feat(KAN-20): unify dialogs feedback and protect ticket drafts
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
<script setup>
|
||||
import { Link, useForm } from '@inertiajs/vue3';
|
||||
import { ref } from 'vue';
|
||||
import ProjectTicketController from '@/actions/App/Http/Controllers/ProjectTicketController';
|
||||
import AppearanceTabs from '@/components/AppearanceTabs.vue';
|
||||
import FeedbackState from '@/components/FeedbackState.vue';
|
||||
import FormFeedback from '@/components/FormFeedback.vue';
|
||||
import InputError from '@/components/InputError.vue';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
DialogClose,
|
||||
DialogScrollContent,
|
||||
} from '@/components/ui/dialog';
|
||||
import {
|
||||
Sheet,
|
||||
SheetContent,
|
||||
SheetTitle,
|
||||
SheetDescription,
|
||||
SheetTrigger,
|
||||
} from '@/components/ui/sheet';
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuTrigger,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
} from '@/components/ui/dropdown-menu';
|
||||
import { useFormProtection } from '@/composables/useFormProtection';
|
||||
import { index as projectsIndex } from '@/routes/projects/index';
|
||||
|
||||
const form = useForm('feedback-preview', { title: '' });
|
||||
const protection = useFormProtection(form);
|
||||
const dialogOpen = ref(false);
|
||||
const menuSelection = ref('');
|
||||
const submit = () =>
|
||||
protection.submit(ProjectTicketController.store({ project: 7 }));
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main class="gap-column p-page mx-auto grid max-w-3xl">
|
||||
<div class="gap-stack flex flex-wrap items-center justify-between">
|
||||
<h1 class="text-headline">Dialogs and feedback</h1>
|
||||
<AppearanceTabs />
|
||||
</div>
|
||||
<FeedbackState
|
||||
state="empty"
|
||||
description="New tickets will appear here."
|
||||
/>
|
||||
<FeedbackState state="loading" />
|
||||
<form
|
||||
class="gap-card bg-card p-card grid rounded-md border"
|
||||
@submit.prevent="submit"
|
||||
>
|
||||
<label for="title">Title</label>
|
||||
<Input
|
||||
id="title"
|
||||
v-model="form.title"
|
||||
:invalid="Boolean(form.errors.title)"
|
||||
aria-describedby="title-error"
|
||||
/>
|
||||
<InputError id="title-error" :message="form.errors.title" />
|
||||
<FormFeedback :state="protection.state.value" @retry="submit" />
|
||||
<Button type="submit" :loading="form.processing">Save draft</Button>
|
||||
<Button type="button" variant="outline" @click="form.cancel()"
|
||||
>Cancel request</Button
|
||||
>
|
||||
</form>
|
||||
<Link :href="projectsIndex()">Leave page</Link>
|
||||
<div class="gap-stack flex flex-wrap">
|
||||
<Dialog v-model:open="dialogOpen">
|
||||
<Button id="programmatic-trigger" @click="dialogOpen = true"
|
||||
>Open dialog</Button
|
||||
>
|
||||
<DialogContent>
|
||||
<DialogHeader
|
||||
><DialogTitle>Edit details</DialogTitle
|
||||
><DialogDescription
|
||||
>Keyboard and focus preview.</DialogDescription
|
||||
></DialogHeader
|
||||
>
|
||||
<Input aria-label="Dialog title" />
|
||||
<Dialog>
|
||||
<DialogTrigger as-child
|
||||
><Button>Open nested dialog</Button></DialogTrigger
|
||||
>
|
||||
<DialogContent>
|
||||
<DialogHeader
|
||||
><DialogTitle>Nested details</DialogTitle
|
||||
><DialogDescription
|
||||
>Returns focus to the parent
|
||||
dialog.</DialogDescription
|
||||
></DialogHeader
|
||||
>
|
||||
<DialogClose as-child
|
||||
><Button>Done</Button></DialogClose
|
||||
>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
<DialogClose as-child
|
||||
><Button variant="outline">Cancel</Button></DialogClose
|
||||
>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
<Dialog>
|
||||
<DialogTrigger as-child
|
||||
><Button>Open long dialog</Button></DialogTrigger
|
||||
>
|
||||
<DialogScrollContent>
|
||||
<DialogHeader
|
||||
><DialogTitle>Long details</DialogTitle
|
||||
><DialogDescription
|
||||
>Scrollable content on small
|
||||
screens.</DialogDescription
|
||||
></DialogHeader
|
||||
>
|
||||
<p v-for="item in 30" :key="item">Detail {{ item }}</p>
|
||||
<DialogClose as-child
|
||||
><Button>Finish reading</Button></DialogClose
|
||||
>
|
||||
</DialogScrollContent>
|
||||
</Dialog>
|
||||
<Sheet>
|
||||
<SheetTrigger as-child
|
||||
><Button>Open sheet</Button></SheetTrigger
|
||||
>
|
||||
<SheetContent class="p-page">
|
||||
<SheetTitle>Sheet details</SheetTitle
|
||||
><SheetDescription
|
||||
>Focus returns to the trigger.</SheetDescription
|
||||
>
|
||||
<Input aria-label="Sheet title" />
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger as-child
|
||||
><Button>Open actions</Button></DropdownMenuTrigger
|
||||
>
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuItem disabled>Unavailable</DropdownMenuItem>
|
||||
<DropdownMenuItem @select="menuSelection = 'selected'"
|
||||
>Select action</DropdownMenuItem
|
||||
>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
<span role="status">{{ menuSelection }}</span>
|
||||
</div>
|
||||
</main>
|
||||
</template>
|
||||
Reference in New Issue
Block a user