Redesign ticket details with inline editing
This commit is contained in:
+1571
-1165
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import { Head, Link, useForm } from '@inertiajs/vue3';
|
||||
import { computed, ref } from 'vue';
|
||||
import { computed } from 'vue';
|
||||
import ProjectTicketController from '@/actions/App/Http/Controllers/ProjectTicketController';
|
||||
import Heading from '@/components/Heading.vue';
|
||||
import InputError from '@/components/InputError.vue';
|
||||
import AcceptanceCriteriaEditor from '@/components/projects/AcceptanceCriteriaEditor.vue';
|
||||
import ProjectTabs from '@/components/projects/ProjectTabs.vue';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Button } from '@/components/ui/button';
|
||||
@@ -17,10 +18,7 @@ import {
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import AppLayout from '@/layouts/AppLayout.vue';
|
||||
import {
|
||||
buildAcceptanceCriteria,
|
||||
parseChecklistLines,
|
||||
} from '@/lib/acceptance-criteria';
|
||||
import { emptyAcceptanceCriteria } from '@/lib/acceptance-criteria';
|
||||
import { index as backlogIndex } from '@/routes/projects/backlog';
|
||||
import { index as boardIndex } from '@/routes/projects/board';
|
||||
import { index } from '@/routes/projects/index';
|
||||
@@ -63,12 +61,8 @@ const hasTicketMetadata =
|
||||
props.ticketPriorities.length > 0 &&
|
||||
props.ticketStatusOptions.length > 0;
|
||||
|
||||
const acceptanceCriteriaChecklist = ref('');
|
||||
|
||||
const form = useForm({
|
||||
acceptance_criteria: buildAcceptanceCriteria(
|
||||
acceptanceCriteriaChecklist.value,
|
||||
),
|
||||
acceptance_criteria: emptyAcceptanceCriteria(),
|
||||
assignee_user_id: '',
|
||||
description: '',
|
||||
parent_ticket_id: '',
|
||||
@@ -81,10 +75,6 @@ const form = useForm({
|
||||
title: '',
|
||||
});
|
||||
|
||||
const acceptanceCriteriaPreviewItems = computed(() =>
|
||||
parseChecklistLines(acceptanceCriteriaChecklist.value),
|
||||
);
|
||||
|
||||
const acceptanceCriteriaError = computed(() => {
|
||||
return (
|
||||
form.errors.acceptance_criteria ??
|
||||
@@ -96,10 +86,6 @@ const acceptanceCriteriaError = computed(() => {
|
||||
});
|
||||
|
||||
const submit = (): void => {
|
||||
form.acceptance_criteria = buildAcceptanceCriteria(
|
||||
acceptanceCriteriaChecklist.value,
|
||||
);
|
||||
|
||||
form.submit(ProjectTicketController.store({ project: props.project.id }), {
|
||||
preserveScroll: true,
|
||||
});
|
||||
@@ -200,64 +186,14 @@ const ticketStatusLabel = (ticketStatus: TicketStatusModel): string => {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-4">
|
||||
<div class="grid gap-2">
|
||||
<Label
|
||||
for="acceptance_criteria_checklist"
|
||||
>
|
||||
Acceptance criteria checklist
|
||||
</Label>
|
||||
<textarea
|
||||
id="acceptance_criteria_checklist"
|
||||
v-model="
|
||||
acceptanceCriteriaChecklist
|
||||
"
|
||||
rows="6"
|
||||
:disabled="form.processing"
|
||||
class="border-input bg-background shadow-xs focus-visible:border-ring focus-visible:ring-ring/50 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow] focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-60"
|
||||
placeholder="[ ] User can sign in [x] Validation is shown for invalid credentials"
|
||||
/>
|
||||
<p
|
||||
class="text-muted-foreground text-xs"
|
||||
>
|
||||
Use <code>[ ]</code> /
|
||||
<code>[x]</code> for checklist
|
||||
items. Indent with two spaces for
|
||||
nested steps.
|
||||
</p>
|
||||
<InputError
|
||||
:message="acceptanceCriteriaError"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="
|
||||
acceptanceCriteriaPreviewItems.length >
|
||||
0
|
||||
"
|
||||
class="border-border rounded-xl border p-4 text-sm"
|
||||
>
|
||||
<p class="mb-3 font-medium">
|
||||
Checklist preview
|
||||
</p>
|
||||
<ul class="space-y-2">
|
||||
<li
|
||||
v-for="(
|
||||
item, index
|
||||
) in acceptanceCriteriaPreviewItems"
|
||||
:key="index"
|
||||
:style="{
|
||||
marginLeft: `${item.indent * 1.25}rem`,
|
||||
}"
|
||||
class="flex items-start gap-2"
|
||||
>
|
||||
<span class="mt-0.5">{{
|
||||
item.checked ? '☑' : '☐'
|
||||
}}</span>
|
||||
<span>{{ item.text }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="grid gap-2">
|
||||
<Label>Acceptance criteria</Label>
|
||||
<AcceptanceCriteriaEditor
|
||||
v-model="form.acceptance_criteria"
|
||||
editable
|
||||
:disabled="form.processing"
|
||||
:error="acceptanceCriteriaError"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user