102 lines
3.7 KiB
Vue
102 lines
3.7 KiB
Vue
<script setup lang="ts">
|
|
import { useForm } from '@inertiajs/vue3';
|
|
import { watch } from 'vue';
|
|
import { update } from '@/actions/App/Http/Controllers/ProjectTicketMetadataSettingsController';
|
|
import FormFeedback from '@/components/FormFeedback.vue';
|
|
import InputError from '@/components/InputError.vue';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Checkbox } from '@/components/ui/checkbox';
|
|
import { Label } from '@/components/ui/label';
|
|
import { useFormProtection } from '@/composables/useFormProtection';
|
|
import { useLocalization } from '@/composables/useLocalization';
|
|
import type { ProjectModel } from '@/types/models/project-model';
|
|
|
|
const props = defineProps<{ project: ProjectModel }>();
|
|
const { t } = useLocalization();
|
|
const form = useForm({
|
|
show_author: props.project.show_author,
|
|
show_story_points: props.project.show_story_points,
|
|
});
|
|
const protection = useFormProtection(form);
|
|
watch(
|
|
() => [props.project.show_author, props.project.show_story_points],
|
|
() => {
|
|
form.defaults({
|
|
show_author: props.project.show_author,
|
|
show_story_points: props.project.show_story_points,
|
|
});
|
|
form.resetAndClearErrors();
|
|
},
|
|
);
|
|
function submit(): void {
|
|
protection.submit(update(props.project.id), {
|
|
preserveScroll: true,
|
|
onSuccess: () => form.defaults(),
|
|
});
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<form
|
|
class="bg-card grid min-w-0 gap-4 rounded-xl border p-4 sm:p-6"
|
|
:aria-busy="form.processing"
|
|
@submit.prevent="submit"
|
|
>
|
|
<h3 class="font-semibold">{{ t('metadata.display') }}</h3>
|
|
<p class="text-muted-foreground text-sm">
|
|
{{ t('metadata.displayDescription') }}
|
|
</p>
|
|
<FormFeedback :state="protection.state.value" @retry="submit" />
|
|
<fieldset :disabled="form.processing" class="grid gap-4">
|
|
<div
|
|
v-for="option in ['show_author', 'show_story_points'] as const"
|
|
:key="option"
|
|
class="grid gap-2"
|
|
>
|
|
<Label
|
|
:for="option"
|
|
class="bg-muted/35 flex min-h-14 cursor-pointer items-start gap-3 rounded-lg border p-4"
|
|
>
|
|
<Checkbox
|
|
:id="option"
|
|
v-model="form[option]"
|
|
:name="option"
|
|
:invalid="!!form.errors[option]"
|
|
:aria-describedby="`${option}-help ${option}-error`"
|
|
/>
|
|
<span class="grid gap-1">
|
|
<span>{{
|
|
t(
|
|
option === 'show_author'
|
|
? 'metadata.author'
|
|
: 'metadata.storyPoints',
|
|
)
|
|
}}</span>
|
|
<span
|
|
:id="`${option}-help`"
|
|
class="text-muted-foreground text-sm font-normal"
|
|
>{{
|
|
t(
|
|
option === 'show_author'
|
|
? 'metadata.authorHelp'
|
|
: 'metadata.storyPointsHelp',
|
|
)
|
|
}}</span
|
|
>
|
|
</span>
|
|
</Label>
|
|
<InputError
|
|
:id="`${option}-error`"
|
|
:message="form.errors[option]"
|
|
/>
|
|
</div>
|
|
</fieldset>
|
|
<Button
|
|
type="submit"
|
|
class="w-full sm:w-fit"
|
|
:loading="form.processing"
|
|
>{{ t('common.save') }}</Button
|
|
>
|
|
</form>
|
|
</template>
|