Files
warren/frontend/components/admin/EditWarrenDialog.vue
2025-07-22 22:01:43 +02:00

159 lines
5.0 KiB
Vue

<script setup lang="ts">
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from '@/components/ui/alert-dialog';
import { useForm } from 'vee-validate';
import { toTypedSchema } from '@vee-validate/yup';
import { editWarrenSchema } from '~/lib/schemas/admin';
import { editWarren } from '~/lib/api/admin/editWarren';
import type { AdminWarrenData } from '~/shared/types/warrens';
const adminStore = useAdminStore();
const isValid = computed(() => Object.keys(form.errors.value).length < 1);
// We'll only update this value if there is a warren to prevent layout shifts on close
const warren = ref<AdminWarrenData>();
const editing = ref(false);
const isChanged = computed(() => {
if (warren.value == null) {
return false;
}
try {
const values = editWarrenSchema.validateSync(
form.controlledValues.value
);
return (
values.name !== warren.value.name ||
values.path !== warren.value.path
);
} catch {
return true;
}
});
function close() {
adminStore.closeEditWarrenDialog();
}
const form = useForm({
validationSchema: toTypedSchema(editWarrenSchema),
});
adminStore.$subscribe((_mutation, state) => {
if (state.editWarrenDialog != null && !editing.value) {
warren.value = Object.values(state.resources.warrens).find(
(w) => w.id === state.editWarrenDialog?.warren.id
);
if (warren.value != null) {
form.setValues(warren.value);
}
}
});
const onSubmit = form.handleSubmit(async (values) => {
if (warren.value == null || !isChanged.value || editing.value) {
return;
}
editing.value = true;
const result = await editWarren(warren.value.id, values.name, values.path);
if (result.success) {
const newWarren: AdminWarrenData = {
id: result.warren.id,
name: result.warren.name,
path: result.warren.path,
};
adminStore.openEditWarrenDialog(newWarren);
}
editing.value = false;
});
</script>
<template>
<AlertDialog :open="adminStore.editWarrenDialog != null">
<AlertDialogTrigger><slot /></AlertDialogTrigger>
<AlertDialogContent
v-if="warren != null"
class="flex max-h-[95vh] flex-col"
@escape-key-down="close"
>
<AlertDialogHeader class="shrink">
<AlertDialogTitle>Edit warren</AlertDialogTitle>
<AlertDialogDescription>
Modify the warren's name and path
</AlertDialogDescription>
</AlertDialogHeader>
<form
id="edit-warren-form"
class="flex flex-col gap-2"
@submit.prevent="onSubmit"
>
<input type="hidden" name="id" :value="warren.id" />
<FormField v-slot="{ componentField }" name="name">
<FormItem>
<FormLabel>Name</FormLabel>
<FormControl>
<Input
v-bind="componentField"
id="name"
type="text"
placeholder="my-warren"
autocomplete="off"
data-1p-ignore
data-protonpass-ignore
data-bwignore
/>
</FormControl>
<FormMessage />
</FormItem>
</FormField>
<FormField v-slot="{ componentField }" name="path">
<FormItem>
<FormLabel>Path</FormLabel>
<FormControl>
<Input
v-bind="componentField"
id="path"
type="text"
placeholder="/mywarren"
autocomplete="off"
data-1p-ignore
data-protonpass-ignore
data-bwignore
/>
</FormControl>
<FormMessage />
</FormItem>
</FormField>
</form>
<AlertDialogFooter class="gap-y-0">
<AlertDialogCancel @click="close">Close</AlertDialogCancel>
<AlertDialogAction
type="submit"
form="edit-warren-form"
:disabled="!isChanged || !isValid"
>Save</AlertDialogAction
>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</template>