Teren-app/resources/js/Pages/Admin/DocumentSettings/Edit.vue
2026-01-05 18:27:35 +01:00

243 lines
8.4 KiB
Vue

<script setup>
import AdminLayout from "@/Layouts/AdminLayout.vue";
import { useForm } from "@inertiajs/vue3";
import { ref, watch } from "vue";
import {
Settings2Icon,
SaveIcon,
CheckCircle2Icon,
AlertCircleIcon,
} from "lucide-vue-next";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/Components/ui/card";
import { Button } from "@/Components/ui/button";
import { Input } from "@/Components/ui/input";
import { Label } from "@/Components/ui/label";
import { Textarea } from "@/Components/ui/textarea";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/Components/ui/select";
import { Switch } from "@/Components/ui/switch";
import { Alert, AlertDescription } from "@/Components/ui/alert";
const props = defineProps({ settings: Object, defaults: Object });
const form = useForm({
file_name_pattern: props.settings.file_name_pattern || props.defaults.file_name_pattern,
date_format: props.settings.date_format || props.defaults.date_format,
unresolved_policy: props.settings.unresolved_policy || props.defaults.unresolved_policy,
preview_enabled: props.settings.preview_enabled ? 1 : 0,
whitelist: JSON.stringify(props.settings.whitelist || {}, null, 2),
date_formats: JSON.stringify(props.settings.date_formats || {}, null, 2),
});
const whitelistError = ref(null);
const dateFormatsError = ref(null);
function validateJson(source, targetError, expectations = "object") {
try {
const parsed = JSON.parse(source.value);
if (
expectations === "object" &&
(parsed === null || Array.isArray(parsed) || typeof parsed !== "object")
) {
targetError.value = "Mora biti JSON objekt";
} else {
targetError.value = null;
}
} catch (e) {
targetError.value = "Neveljaven JSON";
}
}
watch(
() => form.whitelist,
() => validateJson({ value: form.whitelist }, whitelistError)
);
watch(
() => form.date_formats,
() => validateJson({ value: form.date_formats }, dateFormatsError)
);
function submit() {
if (whitelistError.value || dateFormatsError.value) {
return;
}
let wl = null;
try {
wl = JSON.parse(form.whitelist);
} catch (e) {
wl = null;
}
let df = null;
try {
df = JSON.parse(form.date_formats);
} catch (e) {
df = null;
}
form
.transform((d) => ({
...d,
preview_enabled: !!d.preview_enabled,
whitelist: wl,
date_formats: df,
}))
.put(route("admin.document-settings.update"));
}
</script>
<template>
<AdminLayout title="Nastavitve dokumentov">
<div class="max-w-4xl mx-auto">
<Card>
<CardHeader>
<div class="flex items-start gap-3">
<div
class="inline-flex items-center justify-center h-10 w-10 rounded-lg bg-primary/10 text-primary"
>
<Settings2Icon class="h-5 w-5" />
</div>
<div>
<CardTitle>Nastavitve dokumentov</CardTitle>
<CardDescription>
Konfiguracija generiranja dokumentov, vzorcev imen in formatiranja
</CardDescription>
</div>
</div>
</CardHeader>
<CardContent>
<form @submit.prevent="submit" class="space-y-6">
<!-- Basic Settings -->
<div class="space-y-4">
<h3 class="text-sm font-semibold">Osnovne nastavitve</h3>
<div class="grid md:grid-cols-2 gap-4">
<div class="space-y-2">
<Label for="file_name_pattern">Vzorec imena datoteke</Label>
<Input
id="file_name_pattern"
v-model="form.file_name_pattern"
class="font-mono text-sm"
/>
<p class="text-xs text-muted-foreground">
Podprti placeholderji: {slug} {version} {generation.date}
{generation.timestamp}
</p>
<p
v-if="form.errors.file_name_pattern"
class="text-sm text-destructive"
>
{{ form.errors.file_name_pattern }}
</p>
</div>
<div class="space-y-2">
<Label for="date_format">Privzeti datum format</Label>
<Input
id="date_format"
v-model="form.date_format"
placeholder="Y-m-d"
class="font-mono text-sm"
/>
<p class="text-xs text-muted-foreground">npr. Y-m-d ali d.m.Y</p>
<p v-if="form.errors.date_format" class="text-sm text-destructive">
{{ form.errors.date_format }}
</p>
</div>
<div class="space-y-2">
<Label for="unresolved_policy">Politika nerešenih spremenljivk</Label>
<Select v-model="form.unresolved_policy">
<SelectTrigger id="unresolved_policy">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="fail">Fail (napaka)</SelectItem>
<SelectItem value="blank">Blank (prazno)</SelectItem>
<SelectItem value="keep">Keep (obdrži)</SelectItem>
</SelectContent>
</Select>
<p
v-if="form.errors.unresolved_policy"
class="text-sm text-destructive"
>
{{ form.errors.unresolved_policy }}
</p>
</div>
<div class="flex items-center gap-2 pt-8">
<Switch id="preview_enabled" v-model="form.preview_enabled" />
<Label for="preview_enabled" class="cursor-pointer">
Omogoči predoglede dokumentov
</Label>
</div>
</div>
</div>
<!-- JSON Configuration -->
<div class="space-y-4">
<h3 class="text-sm font-semibold">Napišrana konfiguracija (JSON)</h3>
<div class="grid md:grid-cols-2 gap-4">
<div class="space-y-2">
<Label for="whitelist">Whitelist (dovoljeni tokeni)</Label>
<Textarea
id="whitelist"
v-model="form.whitelist"
rows="10"
class="font-mono text-xs"
placeholder='{"entity": ["column1", "column2"]}'
/>
<Alert v-if="whitelistError" variant="destructive" class="py-2">
<AlertCircleIcon class="h-4 w-4" />
<AlertDescription>{{ whitelistError }}</AlertDescription>
</Alert>
<p v-else-if="form.errors.whitelist" class="text-sm text-destructive">
{{ form.errors.whitelist }}
</p>
</div>
<div class="space-y-2">
<Label for="date_formats">Date formats override (JSON)</Label>
<Textarea
id="date_formats"
v-model="form.date_formats"
rows="10"
class="font-mono text-xs"
placeholder='{"contract.start_date": "d.m.Y"}'
/>
<p class="text-xs text-muted-foreground">
Primer: {"contract.start_date":"d.m.Y"}
</p>
<Alert v-if="dateFormatsError" variant="destructive" class="py-2">
<AlertCircleIcon class="h-4 w-4" />
<AlertDescription>{{ dateFormatsError }}</AlertDescription>
</Alert>
</div>
</div>
</div>
<!-- Actions -->
<div class="flex items-center gap-3 pt-4">
<Button :disabled="form.processing" type="submit">
<SaveIcon class="h-4 w-4 mr-2" />
{{ form.processing ? "Shranjevanje..." : "Shrani nastavitve" }}
</Button>
<Alert v-if="form.wasSuccessful" class="py-2 px-3 w-auto">
<CheckCircle2Icon class="h-4 w-4 text-green-600" />
<AlertDescription class="text-green-600">Shranjeno</AlertDescription>
</Alert>
</div>
</form>
</CardContent>
</Card>
</div>
</AdminLayout>
</template>