frontend/app/components/preferences/profile/fields.vue

139 lines
3.5 KiB
Vue
Raw Normal View History

<template>
<FormItem>
<FormLabel>
{{ title }}
2025-12-09 22:32:22 +01:00
<Button
type="button"
variant="secondary"
size="icon"
class="ml-auto"
@click="addField()"
:title="m.front_north_eel_gulp()"
>
2026-01-09 21:47:12 +01:00
<Plus />
</Button>
</FormLabel>
<FormControl>
2025-12-09 22:32:22 +01:00
<VueDraggable
class="grid gap-4"
v-model="list"
:animation="200"
handle=".drag-handle"
>
<div
v-for="(field, index) in list"
:key="field.id"
class="grid items-center grid-cols-[auto_repeat(3,minmax(0,1fr))_auto] gap-2"
>
<Button
as="span"
variant="ghost"
size="icon"
class="drag-handle cursor-grab"
>
2026-01-09 21:47:12 +01:00
<GripVertical />
</Button>
2025-12-09 22:32:22 +01:00
<Input
:model-value="field.name"
placeholder="Name"
@update:model-value="
(e) => updateKey(index, String(e))
2025-12-09 22:32:22 +01:00
"
/>
<Input
:model-value="field.value"
placeholder="Value"
class="col-span-2"
@update:model-value="
(e) => updateValue(index, String(e))
2025-12-09 22:32:22 +01:00
"
/>
<Button
type="button"
variant="secondary"
size="icon"
@click="removeField(index)"
>
2026-01-09 21:47:12 +01:00
<Trash />
</Button>
</div>
</VueDraggable>
2026-01-09 21:47:12 +01:00
<FormMessage />
</FormControl>
</FormItem>
</template>
<script lang="ts" setup>
import { GripVertical, Plus, Trash } from "lucide-vue-next";
import { VueDraggable } from "vue-draggable-plus";
import { Button } from "~/components/ui/button";
import {
FormControl,
FormItem,
FormLabel,
FormMessage,
} from "~/components/ui/form";
import { Input } from "~/components/ui/input";
2025-07-16 07:48:39 +02:00
import * as m from "~~/paraglide/messages.js";
const { title } = defineProps<{
title: string;
}>();
const value = defineModel<{ name: string; value: string }[]>("value", {
default: [],
});
const list = ref<
{
id: string;
name: string;
value: string;
}[]
>(
value.value.map((item, index) => ({
id: String(index),
name: item.name,
value: item.value,
})),
);
watch(
list,
(newList) => {
value.value = newList.map((item) => ({
name: item.name,
value: item.value,
}));
},
{
deep: true,
},
);
const updateKey = (index: number, key: string) => {
if (!list.value[index]) {
return;
}
list.value[index].name = key;
};
const updateValue = (index: number, val: string) => {
if (!list.value[index]) {
return;
}
list.value[index].value = val;
};
const removeField = (index: number) => {
list.value.splice(index, 1);
};
const addField = () => {
list.value.push({ name: "", value: "", id: String(list.value.length) });
};
</script>