Simplify acceptance criteria checklist model
This commit is contained in:
@@ -7,24 +7,15 @@ const MAX_INDENT_LEVEL = 8;
|
||||
|
||||
export type AcceptanceCriteriaEditorState = {
|
||||
checklist: string;
|
||||
summary: string;
|
||||
};
|
||||
|
||||
export const emptyAcceptanceCriteria = (): AcceptanceCriteriaModel => ({
|
||||
summary: null,
|
||||
items: [],
|
||||
});
|
||||
export const emptyAcceptanceCriteria = (): AcceptanceCriteriaModel => [];
|
||||
|
||||
export const normalizeAcceptanceCriteria = (
|
||||
value: AcceptanceCriteriaModel | null | undefined,
|
||||
): AcceptanceCriteriaModel => {
|
||||
if (value === null || value === undefined) {
|
||||
return emptyAcceptanceCriteria();
|
||||
}
|
||||
|
||||
const summary = value.summary?.trim() ?? null;
|
||||
const items = Array.isArray(value.items)
|
||||
? value.items
|
||||
const items = Array.isArray(value)
|
||||
? value
|
||||
.map((item) => ({
|
||||
checked: item.checked === true,
|
||||
indent: clampIndent(item.indent),
|
||||
@@ -33,10 +24,7 @@ export const normalizeAcceptanceCriteria = (
|
||||
.filter((item) => item.text !== '')
|
||||
: [];
|
||||
|
||||
return {
|
||||
summary: summary === '' ? null : summary,
|
||||
items,
|
||||
};
|
||||
return items;
|
||||
};
|
||||
|
||||
export const parseChecklistLines = (
|
||||
@@ -69,15 +57,9 @@ export const formatChecklistLines = (
|
||||
};
|
||||
|
||||
export const buildAcceptanceCriteria = (
|
||||
summaryInput: string,
|
||||
checklistInput: string,
|
||||
): AcceptanceCriteriaModel => {
|
||||
const summary = summaryInput.trim();
|
||||
|
||||
return normalizeAcceptanceCriteria({
|
||||
summary: summary === '' ? null : summary,
|
||||
items: parseChecklistLines(checklistInput),
|
||||
});
|
||||
return normalizeAcceptanceCriteria(parseChecklistLines(checklistInput));
|
||||
};
|
||||
|
||||
export const acceptanceCriteriaToEditorState = (
|
||||
@@ -86,8 +68,7 @@ export const acceptanceCriteriaToEditorState = (
|
||||
const normalized = normalizeAcceptanceCriteria(value);
|
||||
|
||||
return {
|
||||
checklist: formatChecklistLines(normalized.items),
|
||||
summary: normalized.summary ?? '',
|
||||
checklist: formatChecklistLines(normalized),
|
||||
};
|
||||
};
|
||||
|
||||
@@ -123,6 +104,8 @@ const parseChecklistLine = (
|
||||
|
||||
if (bulletMatch?.groups !== undefined) {
|
||||
content = bulletMatch.groups.text.trim();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -111,14 +111,10 @@ const breadcrumbs: BreadcrumbItem[] = [
|
||||
const acceptanceCriteriaEditorState = acceptanceCriteriaToEditorState(
|
||||
props.ticket.acceptance_criteria,
|
||||
);
|
||||
const acceptanceCriteriaSummary = ref(acceptanceCriteriaEditorState.summary);
|
||||
const acceptanceCriteriaChecklist = ref(acceptanceCriteriaEditorState.checklist);
|
||||
|
||||
const form = useForm({
|
||||
acceptance_criteria: buildAcceptanceCriteria(
|
||||
acceptanceCriteriaSummary.value,
|
||||
acceptanceCriteriaChecklist.value,
|
||||
),
|
||||
acceptance_criteria: buildAcceptanceCriteria(acceptanceCriteriaChecklist.value),
|
||||
assignee_user_id: props.ticket.assignee_user_id ?? '',
|
||||
author_user_id: props.ticket.author_user_id ?? '',
|
||||
blocked_comment: props.ticket.blocked_comment ?? '',
|
||||
@@ -151,10 +147,8 @@ const acceptanceCriteriaPreviewItems = computed(() =>
|
||||
const acceptanceCriteriaError = computed(() => {
|
||||
return (
|
||||
form.errors.acceptance_criteria ??
|
||||
form.errors['acceptance_criteria.summary'] ??
|
||||
form.errors['acceptance_criteria.items'] ??
|
||||
Object.entries(form.errors).find(([key]) =>
|
||||
key.startsWith('acceptance_criteria.items.'),
|
||||
key.startsWith('acceptance_criteria.'),
|
||||
)?.[1] ??
|
||||
''
|
||||
);
|
||||
@@ -348,10 +342,7 @@ const submit = (): void => {
|
||||
return;
|
||||
}
|
||||
|
||||
form.acceptance_criteria = buildAcceptanceCriteria(
|
||||
acceptanceCriteriaSummary.value,
|
||||
acceptanceCriteriaChecklist.value,
|
||||
);
|
||||
form.acceptance_criteria = buildAcceptanceCriteria(acceptanceCriteriaChecklist.value);
|
||||
|
||||
form.submit(
|
||||
ProjectTicketController.update({
|
||||
@@ -625,20 +616,6 @@ const formatDateTime = (value: string): string => {
|
||||
</div>
|
||||
|
||||
<div class="grid gap-4">
|
||||
<div class="grid gap-2">
|
||||
<Label for="acceptance_criteria_summary">
|
||||
Acceptance criteria summary
|
||||
</Label>
|
||||
<Input
|
||||
id="acceptance_criteria_summary"
|
||||
v-model="acceptanceCriteriaSummary"
|
||||
:disabled="
|
||||
!canEditTicket || form.processing
|
||||
"
|
||||
placeholder="What should be true when this ticket is done?"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-2">
|
||||
<Label for="acceptance_criteria_checklist">
|
||||
Acceptance criteria checklist
|
||||
|
||||
@@ -61,14 +61,10 @@ const hasTicketMetadata =
|
||||
props.ticketPriorities.length > 0 &&
|
||||
props.ticketStatusOptions.length > 0;
|
||||
|
||||
const acceptanceCriteriaSummary = ref('');
|
||||
const acceptanceCriteriaChecklist = ref('');
|
||||
|
||||
const form = useForm({
|
||||
acceptance_criteria: buildAcceptanceCriteria(
|
||||
acceptanceCriteriaSummary.value,
|
||||
acceptanceCriteriaChecklist.value,
|
||||
),
|
||||
acceptance_criteria: buildAcceptanceCriteria(acceptanceCriteriaChecklist.value),
|
||||
assignee_user_id: '',
|
||||
description: '',
|
||||
story_points: '',
|
||||
@@ -87,20 +83,15 @@ const acceptanceCriteriaPreviewItems = computed(() =>
|
||||
const acceptanceCriteriaError = computed(() => {
|
||||
return (
|
||||
form.errors.acceptance_criteria ??
|
||||
form.errors['acceptance_criteria.summary'] ??
|
||||
form.errors['acceptance_criteria.items'] ??
|
||||
Object.entries(form.errors).find(([key]) =>
|
||||
key.startsWith('acceptance_criteria.items.'),
|
||||
key.startsWith('acceptance_criteria.'),
|
||||
)?.[1] ??
|
||||
''
|
||||
);
|
||||
});
|
||||
|
||||
const submit = (): void => {
|
||||
form.acceptance_criteria = buildAcceptanceCriteria(
|
||||
acceptanceCriteriaSummary.value,
|
||||
acceptanceCriteriaChecklist.value,
|
||||
);
|
||||
form.acceptance_criteria = buildAcceptanceCriteria(acceptanceCriteriaChecklist.value);
|
||||
|
||||
form.submit(ProjectTicketController.store({ project: props.project.id }), {
|
||||
preserveScroll: true,
|
||||
@@ -197,18 +188,6 @@ const ticketStatusLabel = (ticketStatus: TicketStatusModel): string => {
|
||||
</div>
|
||||
|
||||
<div class="grid gap-4">
|
||||
<div class="grid gap-2">
|
||||
<Label for="acceptance_criteria_summary">
|
||||
Acceptance criteria summary
|
||||
</Label>
|
||||
<Input
|
||||
id="acceptance_criteria_summary"
|
||||
v-model="acceptanceCriteriaSummary"
|
||||
:disabled="form.processing"
|
||||
placeholder="What should be true when this ticket is done?"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-2">
|
||||
<Label for="acceptance_criteria_checklist">
|
||||
Acceptance criteria checklist
|
||||
|
||||
@@ -4,7 +4,4 @@ export type AcceptanceCriteriaItemModel = {
|
||||
text: string;
|
||||
};
|
||||
|
||||
export type AcceptanceCriteriaModel = {
|
||||
summary: string | null;
|
||||
items: AcceptanceCriteriaItemModel[];
|
||||
};
|
||||
export type AcceptanceCriteriaModel = AcceptanceCriteriaItemModel[];
|
||||
|
||||
@@ -9,7 +9,6 @@ import type { UserModel } from '@/types/models/user-model';
|
||||
export type TicketModel = {
|
||||
id: number;
|
||||
acceptance_criteria: AcceptanceCriteriaModel;
|
||||
acceptance_criteria_text: string | null;
|
||||
assignee: UserModel | null;
|
||||
assignee_user_id: number | null;
|
||||
author: UserModel | null;
|
||||
|
||||
Reference in New Issue
Block a user