feat(sprint-dialogs): conform aan dialog-pattern + entity-profile
Story 5 van PBI "Alle dialogen conform docs/patterns/dialog.md". - lib/schemas/sprint.ts — gedeelde zod-schemas (create/dates/goal) - actions/sprints.ts — code+fieldErrors voor 422; code: 403 voor auth/demo errors - StartSprintButton dialog: useDirtyCloseGuard, useDialogSubmitShortcut, entityDialog* layout-classes; DemoTooltip op trigger; veld-niveau errors via fieldErrors - SprintHeader's date- en complete-dialogen: zelfde behandeling; date- dialog krijgt dirty-guard, complete-dialog krijgt DemoTooltip op bevestigen - docs/specs/dialogs/sprint.md — entity-profile dat alle drie de modes documenteert; consolidatie naar één SprintDialog component bewust uitgesteld - Sprint-dates tests aangepast aan nieuwe action-shape Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
01e77fc560
commit
784791d8f9
7 changed files with 320 additions and 125 deletions
38
lib/schemas/sprint.ts
Normal file
38
lib/schemas/sprint.ts
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
import { z } from 'zod'
|
||||
|
||||
const dateField = z.string().optional().nullable().transform(v => (v && v.trim() !== '' ? new Date(v) : null))
|
||||
|
||||
export function validateDateOrder(
|
||||
data: { start_date: Date | null; end_date: Date | null },
|
||||
ctx: z.RefinementCtx,
|
||||
) {
|
||||
if (data.start_date && data.end_date && data.end_date < data.start_date) {
|
||||
ctx.addIssue({ code: z.ZodIssueCode.custom, path: ['end_date'], message: 'Einddatum moet na startdatum liggen' })
|
||||
}
|
||||
}
|
||||
|
||||
export const createSprintSchema = z
|
||||
.object({
|
||||
productId: z.string(),
|
||||
sprint_goal: z.string().min(1, 'Sprint Goal is verplicht').max(500),
|
||||
start_date: dateField,
|
||||
end_date: dateField,
|
||||
})
|
||||
.superRefine(validateDateOrder)
|
||||
|
||||
export const updateSprintDatesSchema = z
|
||||
.object({
|
||||
id: z.string(),
|
||||
start_date: dateField,
|
||||
end_date: dateField,
|
||||
})
|
||||
.superRefine(validateDateOrder)
|
||||
|
||||
export const updateSprintGoalSchema = z.object({
|
||||
id: z.string(),
|
||||
sprint_goal: z.string().min(1, 'Sprint Goal is verplicht').max(500),
|
||||
})
|
||||
|
||||
export type CreateSprintInput = z.infer<typeof createSprintSchema>
|
||||
export type UpdateSprintDatesInput = z.infer<typeof updateSprintDatesSchema>
|
||||
export type UpdateSprintGoalInput = z.infer<typeof updateSprintGoalSchema>
|
||||
Loading…
Add table
Add a link
Reference in a new issue