@burdenoff/microfe-planmagnet 2026.925.7 → 2026.925.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/dist/planmagnet/board/ProjectBoard.d.ts.map +1 -1
  2. package/dist/planmagnet/board/ProjectBoard.js +159 -158
  3. package/dist/planmagnet/board/ProjectBoard.js.map +1 -1
  4. package/dist/planmagnet/create/CreateDialogs.d.ts.map +1 -1
  5. package/dist/planmagnet/create/CreateDialogs.js +118 -117
  6. package/dist/planmagnet/create/CreateDialogs.js.map +1 -1
  7. package/dist/planmagnet/pages/GoalsCreateObjectivePagePage.d.ts.map +1 -1
  8. package/dist/planmagnet/pages/GoalsCreateObjectivePagePage.js.map +1 -1
  9. package/dist/planmagnet/pages/GoalsObjectiveDetailPagePage.d.ts.map +1 -1
  10. package/dist/planmagnet/pages/GoalsObjectiveDetailPagePage.js +322 -280
  11. package/dist/planmagnet/pages/GoalsObjectiveDetailPagePage.js.map +1 -1
  12. package/dist/planmagnet/pages/TasksCreateTaskPagePage.d.ts.map +1 -1
  13. package/dist/planmagnet/pages/TasksCreateTaskPagePage.js.map +1 -1
  14. package/dist/planmagnet/pages/TasksEditTaskPagePage.d.ts.map +1 -1
  15. package/dist/planmagnet/pages/TasksEditTaskPagePage.js.map +1 -1
  16. package/dist/planmagnet/pages/TasksTaskDetailPagePage.d.ts.map +1 -1
  17. package/dist/planmagnet/pages/TasksTaskDetailPagePage.js +147 -126
  18. package/dist/planmagnet/pages/TasksTaskDetailPagePage.js.map +1 -1
  19. package/dist/planmagnet/sprints/SprintControls.d.ts.map +1 -1
  20. package/dist/planmagnet/sprints/SprintControls.js +202 -201
  21. package/dist/planmagnet/sprints/SprintControls.js.map +1 -1
  22. package/dist/planmagnet/utils/mutationResult.d.ts +16 -0
  23. package/dist/planmagnet/utils/mutationResult.d.ts.map +1 -0
  24. package/dist/planmagnet/utils/mutationResult.js +10 -0
  25. package/dist/planmagnet/utils/mutationResult.js.map +1 -0
  26. package/package.json +3 -2
@@ -1 +1 @@
1
- {"version":3,"file":"ProjectBoard.js","names":[],"sources":["../../../src/planmagnet/board/ProjectBoard.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation, useQuery } from '@apollo/client/react';\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n Button,\n Card,\n CardContent,\n Input,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport { ChevronLeft, ChevronRight, LayoutGrid, Pencil, Plus } from 'lucide-react';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { PersonName } from '../people/People';\n\n/**\n * A project's board (P1.2). The server owns placement: each column's `cards`\n * follow the rule in wspace-planmagnet-svc board.service.ts `columnCardsWhere`\n * (placed column, else the first column mapped to the item's status), and\n * `unplacedCount` says how many items are on no column. Moving a card into a\n * column mapped to a status changes that status on the server, and a column's\n * WIP limit is enforced there too. This component only draws and asks.\n */\n\nconst STATUSES = [\n 'BACKLOG',\n 'TODO',\n 'IN_PROGRESS',\n 'IN_REVIEW',\n 'TESTING',\n 'DONE',\n 'CANCELLED',\n] as const;\nconst statusLabel = (status: string) =>\n status.charAt(0) + status.slice(1).toLowerCase().replace(/_/g, ' ');\n\nconst CARDS_PER_COLUMN = 100;\n\nconst BOARDS = gql`\n query ProjectBoards($workspaceId: ID!, $projectId: String) {\n planmagnetBoards(\n workspaceId: $workspaceId\n filter: { projectId: $projectId }\n pagination: { first: 20 }\n ) {\n items {\n id\n name\n isDefault\n }\n }\n }\n`;\n\nconst BOARD = gql`\n query ProjectBoard($id: ID!) {\n planmagnetBoard(id: $id) {\n id\n name\n unplacedCount\n columns {\n id\n name\n mappedStatus\n wipLimit\n sortOrder\n cards(pagination: { first: 100 }) {\n totalCount\n items {\n id\n key\n title\n status\n priority\n storyPoints\n assigneeId\n }\n }\n }\n }\n }\n`;\n\nconst MOVE_CARD = gql`\n mutation ProjectBoardMoveCard($boardId: ID!, $input: PlanmagnetMoveCardInput!) {\n planmagnetMoveCard(boardId: $boardId, input: $input) {\n id\n }\n }\n`;\nconst CREATE_BOARD = gql`\n mutation ProjectBoardCreate($input: PlanmagnetCreateBoardInput!) {\n planmagnetCreateBoard(input: $input) {\n id\n }\n }\n`;\nconst CREATE_COLUMN = gql`\n mutation ProjectBoardCreateColumn($input: PlanmagnetCreateBoardColumnInput!) {\n planmagnetCreateBoardColumn(input: $input) {\n id\n }\n }\n`;\nconst UPDATE_COLUMN = gql`\n mutation ProjectBoardUpdateColumn($id: ID!, $input: PlanmagnetUpdateBoardColumnInput!) {\n planmagnetUpdateBoardColumn(id: $id, input: $input) {\n id\n }\n }\n`;\nconst DELETE_COLUMN = gql`\n mutation ProjectBoardDeleteColumn($id: ID!) {\n planmagnetDeleteBoardColumn(id: $id)\n }\n`;\nconst REORDER_COLUMNS = gql`\n mutation ProjectBoardReorder($boardId: ID!, $input: PlanmagnetReorderColumnsInput!) {\n planmagnetReorderColumns(boardId: $boardId, input: $input) {\n id\n }\n }\n`;\n\n/** Every query whose numbers a board change can move. */\nconst REFETCH = [\n 'ProjectBoard',\n 'ProjectBoards',\n 'GetWorkItems',\n 'GetWorkItemCounts',\n 'GetDashboardData',\n];\n\ninterface BoardCard {\n id: string;\n key: string;\n title: string;\n status: string;\n priority: string;\n storyPoints: number | null;\n assigneeId: string | null;\n}\n\ninterface BoardColumn {\n id: string;\n name: string;\n mappedStatus: string | null;\n wipLimit: number | null;\n sortOrder: number;\n cards: { totalCount: number; items: BoardCard[] };\n}\n\ninterface BoardData {\n id: string;\n name: string;\n unplacedCount: number;\n columns: BoardColumn[];\n}\n\nconst messageOf = (e: unknown, fallback: string) => (e instanceof Error ? e.message : fallback);\n\nfunction ErrorLine({ message }: { message: string }) {\n return (\n <p role=\"alert\" className=\"text-sm text-destructive\">\n {message}\n </p>\n );\n}\n\nexport function ProjectBoard({\n projectId,\n projectName,\n}: {\n projectId: string;\n projectName: string;\n}) {\n const { workspaceId } = usePlanMagnet();\n const [chosenBoardId, setChosenBoardId] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n const { data: boardsData, loading: boardsLoading } = useQuery<{\n planmagnetBoards: { items: Array<{ id: string; name: string; isDefault: boolean }> };\n }>(BOARDS, { variables: { workspaceId, projectId }, skip: !workspaceId });\n const boards = boardsData?.planmagnetBoards.items ?? [];\n const boardId =\n (chosenBoardId && boards.some((b) => b.id === chosenBoardId) ? chosenBoardId : null) ??\n boards.find((b) => b.isDefault)?.id ??\n boards[0]?.id ??\n null;\n\n const { data, loading } = useQuery<{ planmagnetBoard: BoardData | null }>(BOARD, {\n variables: { id: boardId },\n skip: !boardId,\n });\n const board = data?.planmagnetBoard ?? null;\n\n const [createBoard, createBoardState] = useMutation<{ planmagnetCreateBoard: { id: string } }>(\n CREATE_BOARD,\n { refetchQueries: REFETCH, awaitRefetchQueries: true }\n );\n const [moveCard, moveState] = useMutation(MOVE_CARD, {\n refetchQueries: REFETCH,\n awaitRefetchQueries: true,\n });\n const [reorder] = useMutation(REORDER_COLUMNS, {\n refetchQueries: REFETCH,\n awaitRefetchQueries: true,\n });\n\n const run = async (action: () => Promise<unknown>, fallback: string) => {\n setError(null);\n try {\n await action();\n } catch (e) {\n setError(messageOf(e, fallback));\n }\n };\n\n const move = (workItemId: string, targetColumnId: string) =>\n run(\n () => moveCard({ variables: { boardId, input: { workItemId, targetColumnId } } }),\n 'The card could not be moved.'\n );\n\n const shiftColumn = (index: number, delta: -1 | 1) => {\n if (!board) return;\n const order = board.columns.map((c) => c.id);\n const target = index + delta;\n if (target < 0 || target >= order.length) return;\n [order[index], order[target]] = [order[target], order[index]];\n return run(\n () => reorder({ variables: { boardId, input: { columnIds: order } } }),\n 'The columns could not be reordered.'\n );\n };\n\n if (boardsLoading && !boardsData) {\n return <p className=\"text-sm text-muted-foreground p-4\">Loading board…</p>;\n }\n\n if (!boardId) {\n return (\n <Card>\n <CardContent className=\"p-8 text-center space-y-3\" data-testid=\"board-empty\">\n <LayoutGrid className=\"h-8 w-8 mx-auto text-muted-foreground\" />\n <p className=\"text-sm text-muted-foreground\">{projectName} has no board yet.</p>\n <Button\n size=\"sm\"\n disabled={createBoardState.loading}\n onClick={() =>\n run(\n () =>\n createBoard({\n variables: {\n input: {\n projectId,\n name: `${projectName} board`,\n type: 'KANBAN',\n isDefault: true,\n withDefaultColumns: true,\n },\n },\n }),\n 'The board could not be created.'\n )\n }\n >\n <Plus className=\"mr-1 h-4 w-4\" />\n {createBoardState.loading ? 'Creating…' : 'Create board'}\n </Button>\n <p className=\"text-xs text-muted-foreground\">\n Starts with one column per status: Backlog, To Do, In Progress, In Review, Testing,\n Done.\n </p>\n {error && <ErrorLine message={error} />}\n </CardContent>\n </Card>\n );\n }\n\n return (\n <div className=\"space-y-3\" data-testid=\"project-board\">\n <div className=\"flex flex-wrap items-center gap-3\">\n {boards.length > 1 && (\n <select\n aria-label=\"Board\"\n className=\"rounded-md border border-input bg-background px-2 py-1 text-sm\"\n value={boardId}\n onChange={(e) => setChosenBoardId(e.target.value)}\n >\n {boards.map((b) => (\n <option key={b.id} value={b.id}>\n {b.name}\n </option>\n ))}\n </select>\n )}\n {board && board.unplacedCount > 0 && (\n <p className=\"text-xs text-muted-foreground\" data-testid=\"board-unplaced\">\n {board.unplacedCount} work item{board.unplacedCount === 1 ? ' is' : 's are'} not on this\n board: {board.unplacedCount === 1 ? 'its status has' : 'their status has'} no column.\n </p>\n )}\n {board && (\n <div className=\"ml-auto\">\n <ColumnDialog boardId={board.id} />\n </div>\n )}\n </div>\n {error && <ErrorLine message={error} />}\n {loading && !board ? (\n <p className=\"text-sm text-muted-foreground p-4\">Loading board…</p>\n ) : (\n <div className=\"flex gap-3 overflow-x-auto pb-2\">\n {board?.columns.map((column, index) => (\n <BoardColumnView\n key={column.id}\n boardId={board.id}\n column={column}\n columns={board.columns}\n isFirst={index === 0}\n isLast={index === board.columns.length - 1}\n busy={moveState.loading}\n onMove={move}\n onShift={(delta) => shiftColumn(index, delta)}\n />\n ))}\n {board && board.columns.length === 0 && (\n <p className=\"text-sm text-muted-foreground p-4\">\n This board has no columns. Add one to start placing work.\n </p>\n )}\n </div>\n )}\n </div>\n );\n}\n\nfunction BoardColumnView({\n boardId,\n column,\n columns,\n isFirst,\n isLast,\n busy,\n onMove,\n onShift,\n}: {\n boardId: string;\n column: BoardColumn;\n columns: BoardColumn[];\n isFirst: boolean;\n isLast: boolean;\n busy: boolean;\n onMove: (workItemId: string, targetColumnId: string) => void;\n onShift: (delta: -1 | 1) => void;\n}) {\n const navigate = usePlanMagnetNavigate();\n const [dragOver, setDragOver] = useState(false);\n const count = column.cards.totalCount;\n const atLimit = column.wipLimit != null && column.wipLimit > 0 && count >= column.wipLimit;\n const hidden = count - column.cards.items.length;\n\n return (\n <section\n aria-label={`${column.name} column`}\n data-testid={`board-column-${column.name}`}\n className={`min-w-[240px] w-[240px] shrink-0 rounded-md border bg-muted/30 ${dragOver ? 'ring-2 ring-primary' : ''}`}\n onDragOver={(e) => {\n e.preventDefault();\n setDragOver(true);\n }}\n onDragLeave={() => setDragOver(false)}\n onDrop={(e) => {\n e.preventDefault();\n setDragOver(false);\n const workItemId = e.dataTransfer.getData('text/plain');\n if (workItemId) onMove(workItemId, column.id);\n }}\n >\n <header className=\"p-2 border-b space-y-1\">\n <div className=\"flex items-center justify-between gap-1\">\n <h3 className=\"text-sm font-medium truncate\">{column.name}</h3>\n <span\n data-testid={`board-column-count-${column.name}`}\n className={`text-xs rounded-full px-1.5 ${atLimit ? 'bg-status-warning-subtle text-status-warning' : 'bg-muted'}`}\n title={column.wipLimit ? `WIP limit ${column.wipLimit}` : undefined}\n >\n {column.wipLimit ? `${count} / ${column.wipLimit}` : count}\n </span>\n </div>\n <div className=\"flex items-center justify-between gap-1\">\n <span className=\"text-[11px] text-muted-foreground\">\n {column.mappedStatus ? `Sets status: ${statusLabel(column.mappedStatus)}` : 'No status'}\n </span>\n <span className=\"flex\">\n <Button\n size=\"icon\"\n variant=\"ghost\"\n className=\"h-6 w-6\"\n aria-label={`Move ${column.name} column left`}\n disabled={isFirst}\n onClick={() => onShift(-1)}\n >\n <ChevronLeft className=\"h-3.5 w-3.5\" />\n </Button>\n <Button\n size=\"icon\"\n variant=\"ghost\"\n className=\"h-6 w-6\"\n aria-label={`Move ${column.name} column right`}\n disabled={isLast}\n onClick={() => onShift(1)}\n >\n <ChevronRight className=\"h-3.5 w-3.5\" />\n </Button>\n <ColumnDialog boardId={boardId} column={column} />\n </span>\n </div>\n </header>\n <ul className=\"p-2 space-y-2 min-h-[80px]\">\n {column.cards.items.map((card) => (\n <li\n key={card.id}\n draggable\n onDragStart={(e) => {\n e.dataTransfer.setData('text/plain', card.id);\n e.dataTransfer.effectAllowed = 'move';\n }}\n className=\"rounded-md border bg-background p-2 space-y-1 cursor-grab\"\n data-testid=\"board-card\"\n >\n <button\n type=\"button\"\n className=\"text-left text-sm font-medium leading-tight hover:underline\"\n onClick={() =>\n navigate(`/tasks/task-detail-page?taskId=${encodeURIComponent(card.id)}`)\n }\n >\n {card.title}\n </button>\n <div className=\"flex items-center justify-between text-[11px] text-muted-foreground\">\n <span>{card.key}</span>\n <span>{card.storyPoints ?? 0} pts</span>\n </div>\n <div className=\"flex items-center justify-between gap-1 text-[11px] text-muted-foreground\">\n <span className=\"truncate\">\n {card.assigneeId ? <PersonName id={card.assigneeId} /> : 'Unassigned'}\n </span>\n {/* The same move as drag-and-drop, for keyboard and assistive tech. */}\n <select\n aria-label={`Move ${card.key} to column`}\n className=\"rounded border border-input bg-background px-1 py-0.5 text-[11px]\"\n value=\"\"\n disabled={busy}\n onChange={(e) => e.target.value && onMove(card.id, e.target.value)}\n >\n <option value=\"\">Move…</option>\n {columns\n .filter((c) => c.id !== column.id)\n .map((c) => (\n <option key={c.id} value={c.id}>\n {c.name}\n </option>\n ))}\n </select>\n </div>\n </li>\n ))}\n {count === 0 && <li className=\"text-xs text-muted-foreground text-center py-4\">Empty</li>}\n </ul>\n {hidden > 0 && (\n <p className=\"px-2 pb-2 text-xs text-muted-foreground\">\n +{hidden} more (showing the first {CARDS_PER_COLUMN})\n </p>\n )}\n </section>\n );\n}\n\n/** Add a column (no `column`) or edit one: name, the status it sets, WIP limit; delete. */\nfunction ColumnDialog({ boardId, column }: { boardId: string; column?: BoardColumn }) {\n const editing = column !== undefined;\n const [open, setOpen] = useState(false);\n const [name, setName] = useState(column?.name ?? '');\n const [mappedStatus, setMappedStatus] = useState(column?.mappedStatus ?? '');\n const [wip, setWip] = useState(column?.wipLimit ? String(column.wipLimit) : '');\n const [error, setError] = useState<string | null>(null);\n const options = { refetchQueries: REFETCH, awaitRefetchQueries: true };\n const [create, createState] = useMutation(CREATE_COLUMN, options);\n const [update, updateState] = useMutation(UPDATE_COLUMN, options);\n const [remove, removeState] = useMutation(DELETE_COLUMN, options);\n const busy = createState.loading || updateState.loading || removeState.loading;\n\n const wipValue = wip.trim() === '' ? null : Number(wip);\n const invalidWip = wipValue !== null && (!Number.isInteger(wipValue) || wipValue < 1);\n const canSave = name.trim() !== '' && !invalidWip && !busy;\n\n const reset = () => {\n setName(column?.name ?? '');\n setMappedStatus(column?.mappedStatus ?? '');\n setWip(column?.wipLimit ? String(column.wipLimit) : '');\n setError(null);\n };\n\n const save = async () => {\n setError(null);\n const fields = {\n name: name.trim(),\n mappedStatus: mappedStatus || null,\n wipLimit: wipValue,\n };\n try {\n if (editing) {\n await update({ variables: { id: column.id, input: fields } });\n } else {\n await create({ variables: { input: { boardId, type: 'CUSTOM', ...fields } } });\n }\n setOpen(false);\n } catch (e) {\n setError(messageOf(e, 'The column could not be saved.'));\n }\n };\n\n const idPrefix = editing ? `column-${column.id}` : 'new-column';\n\n return (\n <ResponsiveDialog\n open={open}\n onOpenChange={(next) => {\n setOpen(next);\n if (next) reset();\n }}\n >\n <ResponsiveDialogTrigger asChild>\n {editing ? (\n <Button\n size=\"icon\"\n variant=\"ghost\"\n className=\"h-6 w-6\"\n aria-label={`Edit ${column.name} column`}\n >\n <Pencil className=\"h-3.5 w-3.5\" />\n </Button>\n ) : (\n <Button size=\"sm\" variant=\"outline\">\n <Plus className=\"mr-1 h-4 w-4\" />\n Add column\n </Button>\n )}\n </ResponsiveDialogTrigger>\n <ResponsiveDialogContent className=\"max-w-md\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>\n {editing ? `Edit ${column.name}` : 'Add column'}\n </ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Moving a card into a column that sets a status changes the work item&apos;s status.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div className=\"space-y-3\">\n <div>\n <label htmlFor={`${idPrefix}-name`} className=\"text-sm font-medium\">\n Name\n </label>\n <Input\n id={`${idPrefix}-name`}\n className=\"mt-1\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n />\n </div>\n <div>\n <label htmlFor={`${idPrefix}-status`} className=\"text-sm font-medium\">\n Sets status\n </label>\n <select\n id={`${idPrefix}-status`}\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm\"\n value={mappedStatus}\n onChange={(e) => setMappedStatus(e.target.value)}\n >\n <option value=\"\">No status (cards keep theirs)</option>\n {STATUSES.map((s) => (\n <option key={s} value={s}>\n {statusLabel(s)}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label htmlFor={`${idPrefix}-wip`} className=\"text-sm font-medium\">\n WIP limit (blank for none)\n </label>\n <Input\n id={`${idPrefix}-wip`}\n type=\"number\"\n min={1}\n className=\"mt-1\"\n value={wip}\n onChange={(e) => setWip(e.target.value)}\n />\n {invalidWip && <ErrorLine message=\"The WIP limit must be a whole number, 1 or more.\" />}\n </div>\n </div>\n {error && <ErrorLine message={error} />}\n <ResponsiveDialogFooter className=\"gap-2\">\n {editing && (\n <AlertDialog>\n <AlertDialogTrigger asChild>\n <Button variant=\"outline\" disabled={busy}>\n Delete column\n </Button>\n </AlertDialogTrigger>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Delete {column.name}?</AlertDialogTitle>\n <AlertDialogDescription>\n Its cards are not deleted: each goes back to the column for its status, or off\n the board if no column sets that status.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Keep it</AlertDialogCancel>\n <AlertDialogAction\n className=\"bg-destructive text-destructive-foreground hover:bg-destructive/90\"\n onClick={async () => {\n try {\n await remove({ variables: { id: column.id } });\n setOpen(false);\n } catch (e) {\n setError(messageOf(e, 'The column could not be deleted.'));\n }\n }}\n >\n Delete column\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n )}\n <Button onClick={save} disabled={!canSave} data-testid={`${idPrefix}-save`}>\n {busy ? 'Saving…' : editing ? 'Save' : 'Add column'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ProjectBoard.js","names":[],"sources":["../../../src/planmagnet/board/ProjectBoard.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation, useQuery } from '@apollo/client/react';\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n Button,\n Card,\n CardContent,\n Input,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport { ChevronLeft, ChevronRight, LayoutGrid, Pencil, Plus } from 'lucide-react';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { PersonName } from '../people/People';\nimport { throwOnError } from '../utils/mutationResult';\n\n/**\n * A project's board (P1.2). The server owns placement: each column's `cards`\n * follow the rule in wspace-planmagnet-svc board.service.ts `columnCardsWhere`\n * (placed column, else the first column mapped to the item's status), and\n * `unplacedCount` says how many items are on no column. Moving a card into a\n * column mapped to a status changes that status on the server, and a column's\n * WIP limit is enforced there too. This component only draws and asks.\n */\n\nconst STATUSES = [\n 'BACKLOG',\n 'TODO',\n 'IN_PROGRESS',\n 'IN_REVIEW',\n 'TESTING',\n 'DONE',\n 'CANCELLED',\n] as const;\nconst statusLabel = (status: string) =>\n status.charAt(0) + status.slice(1).toLowerCase().replace(/_/g, ' ');\n\nconst CARDS_PER_COLUMN = 100;\n\nconst BOARDS = gql`\n query ProjectBoards($workspaceId: ID!, $projectId: String) {\n planmagnetBoards(\n workspaceId: $workspaceId\n filter: { projectId: $projectId }\n pagination: { first: 20 }\n ) {\n items {\n id\n name\n isDefault\n }\n }\n }\n`;\n\nconst BOARD = gql`\n query ProjectBoard($id: ID!) {\n planmagnetBoard(id: $id) {\n id\n name\n unplacedCount\n columns {\n id\n name\n mappedStatus\n wipLimit\n sortOrder\n cards(pagination: { first: 100 }) {\n totalCount\n items {\n id\n key\n title\n status\n priority\n storyPoints\n assigneeId\n }\n }\n }\n }\n }\n`;\n\nconst MOVE_CARD = gql`\n mutation ProjectBoardMoveCard($boardId: ID!, $input: PlanmagnetMoveCardInput!) {\n planmagnetMoveCard(boardId: $boardId, input: $input) {\n id\n }\n }\n`;\nconst CREATE_BOARD = gql`\n mutation ProjectBoardCreate($input: PlanmagnetCreateBoardInput!) {\n planmagnetCreateBoard(input: $input) {\n id\n }\n }\n`;\nconst CREATE_COLUMN = gql`\n mutation ProjectBoardCreateColumn($input: PlanmagnetCreateBoardColumnInput!) {\n planmagnetCreateBoardColumn(input: $input) {\n id\n }\n }\n`;\nconst UPDATE_COLUMN = gql`\n mutation ProjectBoardUpdateColumn($id: ID!, $input: PlanmagnetUpdateBoardColumnInput!) {\n planmagnetUpdateBoardColumn(id: $id, input: $input) {\n id\n }\n }\n`;\nconst DELETE_COLUMN = gql`\n mutation ProjectBoardDeleteColumn($id: ID!) {\n planmagnetDeleteBoardColumn(id: $id)\n }\n`;\nconst REORDER_COLUMNS = gql`\n mutation ProjectBoardReorder($boardId: ID!, $input: PlanmagnetReorderColumnsInput!) {\n planmagnetReorderColumns(boardId: $boardId, input: $input) {\n id\n }\n }\n`;\n\n/** Every query whose numbers a board change can move. */\nconst REFETCH = [\n 'ProjectBoard',\n 'ProjectBoards',\n 'GetWorkItems',\n 'GetWorkItemCounts',\n 'GetDashboardData',\n];\n\ninterface BoardCard {\n id: string;\n key: string;\n title: string;\n status: string;\n priority: string;\n storyPoints: number | null;\n assigneeId: string | null;\n}\n\ninterface BoardColumn {\n id: string;\n name: string;\n mappedStatus: string | null;\n wipLimit: number | null;\n sortOrder: number;\n cards: { totalCount: number; items: BoardCard[] };\n}\n\ninterface BoardData {\n id: string;\n name: string;\n unplacedCount: number;\n columns: BoardColumn[];\n}\n\nconst messageOf = (e: unknown, fallback: string) => (e instanceof Error ? e.message : fallback);\n\nfunction ErrorLine({ message }: { message: string }) {\n return (\n <p role=\"alert\" className=\"text-sm text-destructive\">\n {message}\n </p>\n );\n}\n\nexport function ProjectBoard({\n projectId,\n projectName,\n}: {\n projectId: string;\n projectName: string;\n}) {\n const { workspaceId } = usePlanMagnet();\n const [chosenBoardId, setChosenBoardId] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n const { data: boardsData, loading: boardsLoading } = useQuery<{\n planmagnetBoards: { items: Array<{ id: string; name: string; isDefault: boolean }> };\n }>(BOARDS, { variables: { workspaceId, projectId }, skip: !workspaceId });\n const boards = boardsData?.planmagnetBoards.items ?? [];\n const boardId =\n (chosenBoardId && boards.some((b) => b.id === chosenBoardId) ? chosenBoardId : null) ??\n boards.find((b) => b.isDefault)?.id ??\n boards[0]?.id ??\n null;\n\n const { data, loading } = useQuery<{ planmagnetBoard: BoardData | null }>(BOARD, {\n variables: { id: boardId },\n skip: !boardId,\n });\n const board = data?.planmagnetBoard ?? null;\n\n const [createBoard, createBoardState] = useMutation<{ planmagnetCreateBoard: { id: string } }>(\n CREATE_BOARD,\n { refetchQueries: REFETCH, awaitRefetchQueries: true }\n );\n const [moveCard, moveState] = useMutation(MOVE_CARD, {\n refetchQueries: REFETCH,\n awaitRefetchQueries: true,\n });\n const [reorder] = useMutation(REORDER_COLUMNS, {\n refetchQueries: REFETCH,\n awaitRefetchQueries: true,\n });\n\n const run = async (action: () => Promise<{ error?: unknown }>, fallback: string) => {\n setError(null);\n try {\n await throwOnError(action());\n } catch (e) {\n setError(messageOf(e, fallback));\n }\n };\n\n const move = (workItemId: string, targetColumnId: string) =>\n run(\n () => moveCard({ variables: { boardId, input: { workItemId, targetColumnId } } }),\n 'The card could not be moved.'\n );\n\n const shiftColumn = (index: number, delta: -1 | 1) => {\n if (!board) return;\n const order = board.columns.map((c) => c.id);\n const target = index + delta;\n if (target < 0 || target >= order.length) return;\n [order[index], order[target]] = [order[target], order[index]];\n return run(\n () => reorder({ variables: { boardId, input: { columnIds: order } } }),\n 'The columns could not be reordered.'\n );\n };\n\n if (boardsLoading && !boardsData) {\n return <p className=\"text-sm text-muted-foreground p-4\">Loading board…</p>;\n }\n\n if (!boardId) {\n return (\n <Card>\n <CardContent className=\"p-8 text-center space-y-3\" data-testid=\"board-empty\">\n <LayoutGrid className=\"h-8 w-8 mx-auto text-muted-foreground\" />\n <p className=\"text-sm text-muted-foreground\">{projectName} has no board yet.</p>\n <Button\n size=\"sm\"\n disabled={createBoardState.loading}\n onClick={() =>\n run(\n () =>\n createBoard({\n variables: {\n input: {\n projectId,\n name: `${projectName} board`,\n type: 'KANBAN',\n isDefault: true,\n withDefaultColumns: true,\n },\n },\n }),\n 'The board could not be created.'\n )\n }\n >\n <Plus className=\"mr-1 h-4 w-4\" />\n {createBoardState.loading ? 'Creating…' : 'Create board'}\n </Button>\n <p className=\"text-xs text-muted-foreground\">\n Starts with one column per status: Backlog, To Do, In Progress, In Review, Testing,\n Done.\n </p>\n {error && <ErrorLine message={error} />}\n </CardContent>\n </Card>\n );\n }\n\n return (\n <div className=\"space-y-3\" data-testid=\"project-board\">\n <div className=\"flex flex-wrap items-center gap-3\">\n {boards.length > 1 && (\n <select\n aria-label=\"Board\"\n className=\"rounded-md border border-input bg-background px-2 py-1 text-sm\"\n value={boardId}\n onChange={(e) => setChosenBoardId(e.target.value)}\n >\n {boards.map((b) => (\n <option key={b.id} value={b.id}>\n {b.name}\n </option>\n ))}\n </select>\n )}\n {board && board.unplacedCount > 0 && (\n <p className=\"text-xs text-muted-foreground\" data-testid=\"board-unplaced\">\n {board.unplacedCount} work item{board.unplacedCount === 1 ? ' is' : 's are'} not on this\n board: {board.unplacedCount === 1 ? 'its status has' : 'their status has'} no column.\n </p>\n )}\n {board && (\n <div className=\"ml-auto\">\n <ColumnDialog boardId={board.id} />\n </div>\n )}\n </div>\n {error && <ErrorLine message={error} />}\n {loading && !board ? (\n <p className=\"text-sm text-muted-foreground p-4\">Loading board…</p>\n ) : (\n <div className=\"flex gap-3 overflow-x-auto pb-2\">\n {board?.columns.map((column, index) => (\n <BoardColumnView\n key={column.id}\n boardId={board.id}\n column={column}\n columns={board.columns}\n isFirst={index === 0}\n isLast={index === board.columns.length - 1}\n busy={moveState.loading}\n onMove={move}\n onShift={(delta) => shiftColumn(index, delta)}\n />\n ))}\n {board && board.columns.length === 0 && (\n <p className=\"text-sm text-muted-foreground p-4\">\n This board has no columns. Add one to start placing work.\n </p>\n )}\n </div>\n )}\n </div>\n );\n}\n\nfunction BoardColumnView({\n boardId,\n column,\n columns,\n isFirst,\n isLast,\n busy,\n onMove,\n onShift,\n}: {\n boardId: string;\n column: BoardColumn;\n columns: BoardColumn[];\n isFirst: boolean;\n isLast: boolean;\n busy: boolean;\n onMove: (workItemId: string, targetColumnId: string) => void;\n onShift: (delta: -1 | 1) => void;\n}) {\n const navigate = usePlanMagnetNavigate();\n const [dragOver, setDragOver] = useState(false);\n const count = column.cards.totalCount;\n const atLimit = column.wipLimit != null && column.wipLimit > 0 && count >= column.wipLimit;\n const hidden = count - column.cards.items.length;\n\n return (\n <section\n aria-label={`${column.name} column`}\n data-testid={`board-column-${column.name}`}\n className={`min-w-[240px] w-[240px] shrink-0 rounded-md border bg-muted/30 ${dragOver ? 'ring-2 ring-primary' : ''}`}\n onDragOver={(e) => {\n e.preventDefault();\n setDragOver(true);\n }}\n onDragLeave={() => setDragOver(false)}\n onDrop={(e) => {\n e.preventDefault();\n setDragOver(false);\n const workItemId = e.dataTransfer.getData('text/plain');\n if (workItemId) onMove(workItemId, column.id);\n }}\n >\n <header className=\"p-2 border-b space-y-1\">\n <div className=\"flex items-center justify-between gap-1\">\n <h3 className=\"text-sm font-medium truncate\">{column.name}</h3>\n <span\n data-testid={`board-column-count-${column.name}`}\n className={`text-xs rounded-full px-1.5 ${atLimit ? 'bg-status-warning-subtle text-status-warning' : 'bg-muted'}`}\n title={column.wipLimit ? `WIP limit ${column.wipLimit}` : undefined}\n >\n {column.wipLimit ? `${count} / ${column.wipLimit}` : count}\n </span>\n </div>\n <div className=\"flex items-center justify-between gap-1\">\n <span className=\"text-[11px] text-muted-foreground\">\n {column.mappedStatus ? `Sets status: ${statusLabel(column.mappedStatus)}` : 'No status'}\n </span>\n <span className=\"flex\">\n <Button\n size=\"icon\"\n variant=\"ghost\"\n className=\"h-6 w-6\"\n aria-label={`Move ${column.name} column left`}\n disabled={isFirst}\n onClick={() => onShift(-1)}\n >\n <ChevronLeft className=\"h-3.5 w-3.5\" />\n </Button>\n <Button\n size=\"icon\"\n variant=\"ghost\"\n className=\"h-6 w-6\"\n aria-label={`Move ${column.name} column right`}\n disabled={isLast}\n onClick={() => onShift(1)}\n >\n <ChevronRight className=\"h-3.5 w-3.5\" />\n </Button>\n <ColumnDialog boardId={boardId} column={column} />\n </span>\n </div>\n </header>\n <ul className=\"p-2 space-y-2 min-h-[80px]\">\n {column.cards.items.map((card) => (\n <li\n key={card.id}\n draggable\n onDragStart={(e) => {\n e.dataTransfer.setData('text/plain', card.id);\n e.dataTransfer.effectAllowed = 'move';\n }}\n className=\"rounded-md border bg-background p-2 space-y-1 cursor-grab\"\n data-testid=\"board-card\"\n >\n <button\n type=\"button\"\n className=\"text-left text-sm font-medium leading-tight hover:underline\"\n onClick={() =>\n navigate(`/tasks/task-detail-page?taskId=${encodeURIComponent(card.id)}`)\n }\n >\n {card.title}\n </button>\n <div className=\"flex items-center justify-between text-[11px] text-muted-foreground\">\n <span>{card.key}</span>\n <span>{card.storyPoints ?? 0} pts</span>\n </div>\n <div className=\"flex items-center justify-between gap-1 text-[11px] text-muted-foreground\">\n <span className=\"truncate\">\n {card.assigneeId ? <PersonName id={card.assigneeId} /> : 'Unassigned'}\n </span>\n {/* The same move as drag-and-drop, for keyboard and assistive tech. */}\n <select\n aria-label={`Move ${card.key} to column`}\n className=\"rounded border border-input bg-background px-1 py-0.5 text-[11px]\"\n value=\"\"\n disabled={busy}\n onChange={(e) => e.target.value && onMove(card.id, e.target.value)}\n >\n <option value=\"\">Move…</option>\n {columns\n .filter((c) => c.id !== column.id)\n .map((c) => (\n <option key={c.id} value={c.id}>\n {c.name}\n </option>\n ))}\n </select>\n </div>\n </li>\n ))}\n {count === 0 && <li className=\"text-xs text-muted-foreground text-center py-4\">Empty</li>}\n </ul>\n {hidden > 0 && (\n <p className=\"px-2 pb-2 text-xs text-muted-foreground\">\n +{hidden} more (showing the first {CARDS_PER_COLUMN})\n </p>\n )}\n </section>\n );\n}\n\n/** Add a column (no `column`) or edit one: name, the status it sets, WIP limit; delete. */\nfunction ColumnDialog({ boardId, column }: { boardId: string; column?: BoardColumn }) {\n const editing = column !== undefined;\n const [open, setOpen] = useState(false);\n const [name, setName] = useState(column?.name ?? '');\n const [mappedStatus, setMappedStatus] = useState(column?.mappedStatus ?? '');\n const [wip, setWip] = useState(column?.wipLimit ? String(column.wipLimit) : '');\n const [error, setError] = useState<string | null>(null);\n const options = { refetchQueries: REFETCH, awaitRefetchQueries: true };\n const [create, createState] = useMutation(CREATE_COLUMN, options);\n const [update, updateState] = useMutation(UPDATE_COLUMN, options);\n const [remove, removeState] = useMutation(DELETE_COLUMN, options);\n const busy = createState.loading || updateState.loading || removeState.loading;\n\n const wipValue = wip.trim() === '' ? null : Number(wip);\n const invalidWip = wipValue !== null && (!Number.isInteger(wipValue) || wipValue < 1);\n const canSave = name.trim() !== '' && !invalidWip && !busy;\n\n const reset = () => {\n setName(column?.name ?? '');\n setMappedStatus(column?.mappedStatus ?? '');\n setWip(column?.wipLimit ? String(column.wipLimit) : '');\n setError(null);\n };\n\n const save = async () => {\n setError(null);\n const fields = {\n name: name.trim(),\n mappedStatus: mappedStatus || null,\n wipLimit: wipValue,\n };\n try {\n if (editing) {\n await throwOnError(update({ variables: { id: column.id, input: fields } }));\n } else {\n await throwOnError(\n create({ variables: { input: { boardId, type: 'CUSTOM', ...fields } } })\n );\n }\n setOpen(false);\n } catch (e) {\n setError(messageOf(e, 'The column could not be saved.'));\n }\n };\n\n const idPrefix = editing ? `column-${column.id}` : 'new-column';\n\n return (\n <ResponsiveDialog\n open={open}\n onOpenChange={(next) => {\n setOpen(next);\n if (next) reset();\n }}\n >\n <ResponsiveDialogTrigger asChild>\n {editing ? (\n <Button\n size=\"icon\"\n variant=\"ghost\"\n className=\"h-6 w-6\"\n aria-label={`Edit ${column.name} column`}\n >\n <Pencil className=\"h-3.5 w-3.5\" />\n </Button>\n ) : (\n <Button size=\"sm\" variant=\"outline\">\n <Plus className=\"mr-1 h-4 w-4\" />\n Add column\n </Button>\n )}\n </ResponsiveDialogTrigger>\n <ResponsiveDialogContent className=\"max-w-md\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>\n {editing ? `Edit ${column.name}` : 'Add column'}\n </ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Moving a card into a column that sets a status changes the work item&apos;s status.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div className=\"space-y-3\">\n <div>\n <label htmlFor={`${idPrefix}-name`} className=\"text-sm font-medium\">\n Name\n </label>\n <Input\n id={`${idPrefix}-name`}\n className=\"mt-1\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n />\n </div>\n <div>\n <label htmlFor={`${idPrefix}-status`} className=\"text-sm font-medium\">\n Sets status\n </label>\n <select\n id={`${idPrefix}-status`}\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm\"\n value={mappedStatus}\n onChange={(e) => setMappedStatus(e.target.value)}\n >\n <option value=\"\">No status (cards keep theirs)</option>\n {STATUSES.map((s) => (\n <option key={s} value={s}>\n {statusLabel(s)}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label htmlFor={`${idPrefix}-wip`} className=\"text-sm font-medium\">\n WIP limit (blank for none)\n </label>\n <Input\n id={`${idPrefix}-wip`}\n type=\"number\"\n min={1}\n className=\"mt-1\"\n value={wip}\n onChange={(e) => setWip(e.target.value)}\n />\n {invalidWip && <ErrorLine message=\"The WIP limit must be a whole number, 1 or more.\" />}\n </div>\n </div>\n {error && <ErrorLine message={error} />}\n <ResponsiveDialogFooter className=\"gap-2\">\n {editing && (\n <AlertDialog>\n <AlertDialogTrigger asChild>\n <Button variant=\"outline\" disabled={busy}>\n Delete column\n </Button>\n </AlertDialogTrigger>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Delete {column.name}?</AlertDialogTitle>\n <AlertDialogDescription>\n Its cards are not deleted: each goes back to the column for its status, or off\n the board if no column sets that status.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>Keep it</AlertDialogCancel>\n <AlertDialogAction\n className=\"bg-destructive text-destructive-foreground hover:bg-destructive/90\"\n onClick={async () => {\n try {\n await throwOnError(remove({ variables: { id: column.id } }));\n setOpen(false);\n } catch (e) {\n setError(messageOf(e, 'The column could not be deleted.'));\n }\n }}\n >\n Delete column\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n )}\n <Button onClick={save} disabled={!canSave} data-testid={`${idPrefix}-save`}>\n {busy ? 'Saving…' : editing ? 'Save' : 'Add column'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"CreateDialogs.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/create/CreateDialogs.tsx"],"names":[],"mappings":"AAoIA,wBAAgB,gBAAgB,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,2CAoGzF;AAcD,wBAAgB,kBAAkB,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,2CA6F7F"}
1
+ {"version":3,"file":"CreateDialogs.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/create/CreateDialogs.tsx"],"names":[],"mappings":"AAqIA,wBAAgB,gBAAgB,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,2CAsGzF;AAcD,wBAAgB,kBAAkB,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,2CA+F7F"}
@@ -1,12 +1,13 @@
1
1
  import { usePlanMagnet as e } from "../providers/PlanMagnetProvider.js";
2
- import { useState as t } from "react";
3
- import { Plus as n } from "lucide-react";
4
- import { gql as r } from "@apollo/client";
5
- import { useMutation as i, useQuery as a } from "@apollo/client/react";
6
- import { jsx as o, jsxs as s } from "react/jsx-runtime";
7
- import { Button as c, Input as l, ResponsiveDialog as u, ResponsiveDialogContent as d, ResponsiveDialogDescription as f, ResponsiveDialogFooter as p, ResponsiveDialogHeader as m, ResponsiveDialogTitle as h, ResponsiveDialogTrigger as g } from "@burdenoff/fe-libs/ui";
2
+ import { throwOnError as t } from "../utils/mutationResult.js";
3
+ import { useState as n } from "react";
4
+ import { Plus as r } from "lucide-react";
5
+ import { gql as i } from "@apollo/client";
6
+ import { useMutation as a, useQuery as o } from "@apollo/client/react";
7
+ import { jsx as s, jsxs as c } from "react/jsx-runtime";
8
+ import { Button as l, Input as u, ResponsiveDialog as d, ResponsiveDialogContent as f, ResponsiveDialogDescription as p, ResponsiveDialogFooter as m, ResponsiveDialogHeader as h, ResponsiveDialogTitle as g, ResponsiveDialogTrigger as _ } from "@burdenoff/fe-libs/ui";
8
9
  //#region src/planmagnet/create/CreateDialogs.tsx
9
- var _ = r`
10
+ var v = i`
10
11
  query CreateDialogProjects($workspaceId: ID!) {
11
12
  planmagnetProjects(workspaceId: $workspaceId, pagination: { first: 100 }) {
12
13
  items {
@@ -15,16 +16,16 @@ var _ = r`
15
16
  }
16
17
  }
17
18
  }
18
- `, v = "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm";
19
- function y({ message: e }) {
20
- return /* @__PURE__ */ o("p", {
19
+ `, y = "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm";
20
+ function b({ message: e }) {
21
+ return /* @__PURE__ */ s("p", {
21
22
  role: "alert",
22
23
  className: "text-sm text-destructive",
23
24
  children: e
24
25
  });
25
26
  }
26
- function b(t) {
27
- let { workspaceId: n } = e(), { data: r, loading: i } = a(_, {
27
+ function x(t) {
28
+ let { workspaceId: n } = e(), { data: r, loading: i } = o(v, {
28
29
  variables: { workspaceId: n ?? "" },
29
30
  skip: !t || !n
30
31
  });
@@ -33,31 +34,31 @@ function b(t) {
33
34
  loading: i
34
35
  };
35
36
  }
36
- function x({ id: e, value: t, onChange: n, projects: r, loading: i }) {
37
- return /* @__PURE__ */ s("div", { children: [/* @__PURE__ */ o("label", {
37
+ function S({ id: e, value: t, onChange: n, projects: r, loading: i }) {
38
+ return /* @__PURE__ */ c("div", { children: [/* @__PURE__ */ s("label", {
38
39
  htmlFor: e,
39
40
  className: "text-sm font-medium",
40
41
  children: "Project"
41
- }), /* @__PURE__ */ s("select", {
42
+ }), /* @__PURE__ */ c("select", {
42
43
  id: e,
43
- className: v,
44
+ className: y,
44
45
  value: t,
45
46
  onChange: (e) => n(e.target.value),
46
- children: [r.length === 0 && /* @__PURE__ */ o("option", {
47
+ children: [r.length === 0 && /* @__PURE__ */ s("option", {
47
48
  value: "",
48
49
  children: i ? "Loading…" : "No projects"
49
- }), r.map((e) => /* @__PURE__ */ o("option", {
50
+ }), r.map((e) => /* @__PURE__ */ s("option", {
50
51
  value: e.id,
51
52
  children: e.name
52
53
  }, e.id))]
53
54
  })] });
54
55
  }
55
- function S({ id: e, label: t, value: n, onChange: r, type: i = "text", placeholder: a }) {
56
- return /* @__PURE__ */ s("div", { children: [/* @__PURE__ */ o("label", {
56
+ function C({ id: e, label: t, value: n, onChange: r, type: i = "text", placeholder: a }) {
57
+ return /* @__PURE__ */ c("div", { children: [/* @__PURE__ */ s("label", {
57
58
  htmlFor: e,
58
59
  className: "text-sm font-medium",
59
60
  children: t
60
- }), /* @__PURE__ */ o(l, {
61
+ }), /* @__PURE__ */ s(u, {
61
62
  id: e,
62
63
  type: i,
63
64
  className: "mt-1",
@@ -66,217 +67,217 @@ function S({ id: e, label: t, value: n, onChange: r, type: i = "text", placehold
66
67
  onChange: (e) => r(e.target.value)
67
68
  })] });
68
69
  }
69
- var C = (e, t) => e instanceof Error ? e.message : t, w = r`
70
+ var w = (e, t) => e instanceof Error ? e.message : t, T = i`
70
71
  mutation CreateDialogRelease($input: PlanmagnetCreateReleaseInput!) {
71
72
  planmagnetCreateRelease(input: $input) {
72
73
  id
73
74
  }
74
75
  }
75
- `, T = {
76
+ `, E = {
76
77
  name: "",
77
78
  version: "",
78
79
  projectId: "",
79
80
  plannedDate: "",
80
81
  description: ""
81
82
  };
82
- function E({ onCreated: e }) {
83
- let [r, a] = t(!1), [l, _] = t(T), [v, E] = t(null), { projects: D, loading: O } = b(r), k = l.projectId || D[0]?.id || "", [A, { loading: j }] = i(w, {
83
+ function D({ onCreated: e }) {
84
+ let [i, o] = n(!1), [u, v] = n(E), [y, D] = n(null), { projects: O, loading: k } = x(i), A = u.projectId || O[0]?.id || "", [j, { loading: M }] = a(T, {
84
85
  refetchQueries: ["ListReleases"],
85
86
  awaitRefetchQueries: !0
86
- }), M = l.name.trim() !== "" && l.version.trim() !== "" && k !== "" && !j;
87
- return /* @__PURE__ */ s(u, {
88
- open: r,
87
+ }), N = u.name.trim() !== "" && u.version.trim() !== "" && A !== "" && !M;
88
+ return /* @__PURE__ */ c(d, {
89
+ open: i,
89
90
  onOpenChange: (e) => {
90
- a(e), e || E(null);
91
+ o(e), e || D(null);
91
92
  },
92
- children: [/* @__PURE__ */ o(g, {
93
+ children: [/* @__PURE__ */ s(_, {
93
94
  asChild: !0,
94
- children: /* @__PURE__ */ s(c, {
95
+ children: /* @__PURE__ */ c(l, {
95
96
  size: "sm",
96
- children: [/* @__PURE__ */ o(n, { className: "mr-1 h-4 w-4" }), "New Release"]
97
+ children: [/* @__PURE__ */ s(r, { className: "mr-1 h-4 w-4" }), "New Release"]
97
98
  })
98
- }), /* @__PURE__ */ s(d, {
99
+ }), /* @__PURE__ */ c(f, {
99
100
  className: "max-w-lg",
100
101
  children: [
101
- /* @__PURE__ */ s(m, { children: [/* @__PURE__ */ o(h, { children: "New release" }), /* @__PURE__ */ o(f, { children: "The release starts in Planning." })] }),
102
- /* @__PURE__ */ s("div", {
102
+ /* @__PURE__ */ c(h, { children: [/* @__PURE__ */ s(g, { children: "New release" }), /* @__PURE__ */ s(p, { children: "The release starts in Planning." })] }),
103
+ /* @__PURE__ */ c("div", {
103
104
  className: "space-y-3",
104
105
  children: [
105
- /* @__PURE__ */ o(S, {
106
+ /* @__PURE__ */ s(C, {
106
107
  id: "new-release-name",
107
108
  label: "Name",
108
- value: l.name,
109
- onChange: (e) => _({
110
- ...l,
109
+ value: u.name,
110
+ onChange: (e) => v({
111
+ ...u,
111
112
  name: e
112
113
  })
113
114
  }),
114
- /* @__PURE__ */ o(S, {
115
+ /* @__PURE__ */ s(C, {
115
116
  id: "new-release-version",
116
117
  label: "Version",
117
118
  placeholder: "e.g. 1.4.0",
118
- value: l.version,
119
- onChange: (e) => _({
120
- ...l,
119
+ value: u.version,
120
+ onChange: (e) => v({
121
+ ...u,
121
122
  version: e
122
123
  })
123
124
  }),
124
- /* @__PURE__ */ o(x, {
125
+ /* @__PURE__ */ s(S, {
125
126
  id: "new-release-project",
126
- value: k,
127
- onChange: (e) => _({
128
- ...l,
127
+ value: A,
128
+ onChange: (e) => v({
129
+ ...u,
129
130
  projectId: e
130
131
  }),
131
- projects: D,
132
- loading: O
132
+ projects: O,
133
+ loading: k
133
134
  }),
134
- /* @__PURE__ */ o(S, {
135
+ /* @__PURE__ */ s(C, {
135
136
  id: "new-release-date",
136
137
  label: "Planned date",
137
138
  type: "date",
138
- value: l.plannedDate,
139
- onChange: (e) => _({
140
- ...l,
139
+ value: u.plannedDate,
140
+ onChange: (e) => v({
141
+ ...u,
141
142
  plannedDate: e
142
143
  })
143
144
  }),
144
- /* @__PURE__ */ o(S, {
145
+ /* @__PURE__ */ s(C, {
145
146
  id: "new-release-description",
146
147
  label: "Description",
147
- value: l.description,
148
- onChange: (e) => _({
149
- ...l,
148
+ value: u.description,
149
+ onChange: (e) => v({
150
+ ...u,
150
151
  description: e
151
152
  })
152
153
  })
153
154
  ]
154
155
  }),
155
- v && /* @__PURE__ */ o(y, { message: v }),
156
- /* @__PURE__ */ o(p, { children: /* @__PURE__ */ o(c, {
156
+ y && /* @__PURE__ */ s(b, { message: y }),
157
+ /* @__PURE__ */ s(m, { children: /* @__PURE__ */ s(l, {
157
158
  onClick: async () => {
158
- E(null);
159
+ D(null);
159
160
  try {
160
- let t = (await A({ variables: { input: {
161
- name: l.name.trim(),
162
- version: l.version.trim(),
163
- projectId: k,
164
- plannedDate: l.plannedDate || void 0,
165
- description: l.description.trim() || void 0
166
- } } })).data?.planmagnetCreateRelease.id;
167
- _(T), a(!1), t && e(t);
161
+ let n = (await t(j({ variables: { input: {
162
+ name: u.name.trim(),
163
+ version: u.version.trim(),
164
+ projectId: A,
165
+ plannedDate: u.plannedDate || void 0,
166
+ description: u.description.trim() || void 0
167
+ } } }))).data?.planmagnetCreateRelease.id;
168
+ v(E), o(!1), n && e(n);
168
169
  } catch (e) {
169
- E(C(e, "The release could not be created."));
170
+ D(w(e, "The release could not be created."));
170
171
  }
171
172
  },
172
- disabled: !M,
173
+ disabled: !N,
173
174
  "data-testid": "new-release-submit",
174
- children: j ? "Creating…" : "Create release"
175
+ children: M ? "Creating…" : "Create release"
175
176
  }) })
176
177
  ]
177
178
  })]
178
179
  });
179
180
  }
180
- var D = r`
181
+ var O = i`
181
182
  mutation CreateDialogMilestone($input: PlanmagnetCreateMilestoneInput!) {
182
183
  planmagnetCreateMilestone(input: $input) {
183
184
  id
184
185
  }
185
186
  }
186
- `, O = {
187
+ `, k = {
187
188
  name: "",
188
189
  projectId: "",
189
190
  dueDate: "",
190
191
  description: ""
191
192
  };
192
- function k({ onCreated: e }) {
193
- let [r, a] = t(!1), [l, _] = t(O), [v, w] = t(null), { projects: T, loading: E } = b(r), k = l.projectId || T[0]?.id || "", [A, { loading: j }] = i(D, {
193
+ function A({ onCreated: e }) {
194
+ let [i, o] = n(!1), [u, v] = n(k), [y, T] = n(null), { projects: E, loading: D } = x(i), A = u.projectId || E[0]?.id || "", [j, { loading: M }] = a(O, {
194
195
  refetchQueries: ["GetMilestones"],
195
196
  awaitRefetchQueries: !0
196
- }), M = l.name.trim() !== "" && k !== "" && !j;
197
- return /* @__PURE__ */ s(u, {
198
- open: r,
197
+ }), N = u.name.trim() !== "" && A !== "" && !M;
198
+ return /* @__PURE__ */ c(d, {
199
+ open: i,
199
200
  onOpenChange: (e) => {
200
- a(e), e || w(null);
201
+ o(e), e || T(null);
201
202
  },
202
- children: [/* @__PURE__ */ o(g, {
203
+ children: [/* @__PURE__ */ s(_, {
203
204
  asChild: !0,
204
- children: /* @__PURE__ */ s(c, {
205
+ children: /* @__PURE__ */ c(l, {
205
206
  size: "sm",
206
- children: [/* @__PURE__ */ o(n, { className: "mr-1 h-4 w-4" }), "New Milestone"]
207
+ children: [/* @__PURE__ */ s(r, { className: "mr-1 h-4 w-4" }), "New Milestone"]
207
208
  })
208
- }), /* @__PURE__ */ s(d, {
209
+ }), /* @__PURE__ */ c(f, {
209
210
  className: "max-w-lg",
210
211
  children: [
211
- /* @__PURE__ */ s(m, { children: [/* @__PURE__ */ o(h, { children: "New milestone" }), /* @__PURE__ */ o(f, { children: "The milestone starts as Pending." })] }),
212
- /* @__PURE__ */ s("div", {
212
+ /* @__PURE__ */ c(h, { children: [/* @__PURE__ */ s(g, { children: "New milestone" }), /* @__PURE__ */ s(p, { children: "The milestone starts as Pending." })] }),
213
+ /* @__PURE__ */ c("div", {
213
214
  className: "space-y-3",
214
215
  children: [
215
- /* @__PURE__ */ o(S, {
216
+ /* @__PURE__ */ s(C, {
216
217
  id: "new-milestone-name",
217
218
  label: "Name",
218
- value: l.name,
219
- onChange: (e) => _({
220
- ...l,
219
+ value: u.name,
220
+ onChange: (e) => v({
221
+ ...u,
221
222
  name: e
222
223
  })
223
224
  }),
224
- /* @__PURE__ */ o(x, {
225
+ /* @__PURE__ */ s(S, {
225
226
  id: "new-milestone-project",
226
- value: k,
227
- onChange: (e) => _({
228
- ...l,
227
+ value: A,
228
+ onChange: (e) => v({
229
+ ...u,
229
230
  projectId: e
230
231
  }),
231
- projects: T,
232
- loading: E
232
+ projects: E,
233
+ loading: D
233
234
  }),
234
- /* @__PURE__ */ o(S, {
235
+ /* @__PURE__ */ s(C, {
235
236
  id: "new-milestone-due",
236
237
  label: "Due date",
237
238
  type: "date",
238
- value: l.dueDate,
239
- onChange: (e) => _({
240
- ...l,
239
+ value: u.dueDate,
240
+ onChange: (e) => v({
241
+ ...u,
241
242
  dueDate: e
242
243
  })
243
244
  }),
244
- /* @__PURE__ */ o(S, {
245
+ /* @__PURE__ */ s(C, {
245
246
  id: "new-milestone-description",
246
247
  label: "Description",
247
- value: l.description,
248
- onChange: (e) => _({
249
- ...l,
248
+ value: u.description,
249
+ onChange: (e) => v({
250
+ ...u,
250
251
  description: e
251
252
  })
252
253
  })
253
254
  ]
254
255
  }),
255
- v && /* @__PURE__ */ o(y, { message: v }),
256
- /* @__PURE__ */ o(p, { children: /* @__PURE__ */ o(c, {
256
+ y && /* @__PURE__ */ s(b, { message: y }),
257
+ /* @__PURE__ */ s(m, { children: /* @__PURE__ */ s(l, {
257
258
  onClick: async () => {
258
- w(null);
259
+ T(null);
259
260
  try {
260
- let t = (await A({ variables: { input: {
261
- name: l.name.trim(),
262
- projectId: k,
263
- dueDate: l.dueDate || void 0,
264
- description: l.description.trim() || void 0
265
- } } })).data?.planmagnetCreateMilestone.id;
266
- _(O), a(!1), t && e(t);
261
+ let n = (await t(j({ variables: { input: {
262
+ name: u.name.trim(),
263
+ projectId: A,
264
+ dueDate: u.dueDate || void 0,
265
+ description: u.description.trim() || void 0
266
+ } } }))).data?.planmagnetCreateMilestone.id;
267
+ v(k), o(!1), n && e(n);
267
268
  } catch (e) {
268
- w(C(e, "The milestone could not be created."));
269
+ T(w(e, "The milestone could not be created."));
269
270
  }
270
271
  },
271
- disabled: !M,
272
+ disabled: !N,
272
273
  "data-testid": "new-milestone-submit",
273
- children: j ? "Creating…" : "Create milestone"
274
+ children: M ? "Creating…" : "Create milestone"
274
275
  }) })
275
276
  ]
276
277
  })]
277
278
  });
278
279
  }
279
280
  //#endregion
280
- export { k as NewMilestoneDialog, E as NewReleaseDialog };
281
+ export { A as NewMilestoneDialog, D as NewReleaseDialog };
281
282
 
282
283
  //# sourceMappingURL=CreateDialogs.js.map