@burdenoff/microfe-planmagnet 2026.927.2 → 2026.927.3
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.
- package/dist/planmagnet/admin/PlanMagnetAdminRoot.d.ts.map +1 -1
- package/dist/planmagnet/admin/PlanMagnetAdminRoot.js +128 -124
- package/dist/planmagnet/admin/PlanMagnetAdminRoot.js.map +1 -1
- package/dist/planmagnet/controls/ConfirmButton.d.ts +25 -0
- package/dist/planmagnet/controls/ConfirmButton.d.ts.map +1 -0
- package/dist/planmagnet/controls/ConfirmButton.js +30 -0
- package/dist/planmagnet/controls/ConfirmButton.js.map +1 -0
- package/dist/planmagnet/controls/ProjectControls.d.ts +13 -0
- package/dist/planmagnet/controls/ProjectControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/ProjectControls.js +104 -0
- package/dist/planmagnet/controls/ProjectControls.js.map +1 -0
- package/dist/planmagnet/controls/WorkItemControls.d.ts +52 -0
- package/dist/planmagnet/controls/WorkItemControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/WorkItemControls.js +198 -0
- package/dist/planmagnet/controls/WorkItemControls.js.map +1 -0
- package/dist/planmagnet/pages/DocsDocDetailPagePage.js +4 -4
- package/dist/planmagnet/pages/DocsDocDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/DocsDocsPagePage.js +4 -4
- package/dist/planmagnet/pages/ProductsProductDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsProductDetailPagePage.js +97 -90
- package/dist/planmagnet/pages/ProductsProductDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.js +150 -111
- package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProjectsEditProjectPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js +114 -91
- package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js +134 -132
- package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/SprintsStartSprintPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/SprintsStartSprintPagePage.js +6 -5
- package/dist/planmagnet/pages/SprintsStartSprintPagePage.js.map +1 -1
- package/dist/planmagnet/pages/TasksCreateTaskPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/TasksCreateTaskPagePage.js +167 -111
- package/dist/planmagnet/pages/TasksCreateTaskPagePage.js.map +1 -1
- package/dist/planmagnet/pages/TasksTaskDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/TasksTaskDetailPagePage.js +147 -147
- package/dist/planmagnet/pages/TasksTaskDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/TeamTeamPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/TeamTeamPagePage.js +1 -1
- package/dist/planmagnet/pages/TeamTeamPagePage.js.map +1 -1
- package/dist/planmagnet/people/People.js +1 -1
- package/dist/planmagnet/roadmaps/RoadmapControls.d.ts +34 -0
- package/dist/planmagnet/roadmaps/RoadmapControls.d.ts.map +1 -0
- package/dist/planmagnet/roadmaps/RoadmapControls.js +301 -0
- package/dist/planmagnet/roadmaps/RoadmapControls.js.map +1 -0
- package/dist/planmagnet/sprints/SprintControls.d.ts.map +1 -1
- package/dist/planmagnet/sprints/SprintControls.js +194 -215
- package/dist/planmagnet/sprints/SprintControls.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SprintsStartSprintPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/SprintsStartSprintPagePage.tsx"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport { Card, CardContent, CardHeader, CardTitle, Badge } from '@burdenoff/fe-libs/ui';\nimport { Zap, Users } from 'lucide-react';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { detailPath } from '../utils/rowNavigation';\nimport { NewSprintDialog, SprintLifecycleActions } from '../sprints/SprintControls';\nimport { SprintDates, type SprintPlanChange } from '../sprints/SprintDates';\nimport { PersonAvatar } from '../people/People';\n\nconst GET_SPRINTS = gql`\n query GetSprints(\n $workspaceId: ID!\n $filter: PlanmagnetSprintFilter\n $pagination: PlanmagnetPaginationInput\n ) {\n planmagnetSprints(workspaceId: $workspaceId, filter: $filter, pagination: $pagination) {\n items {\n id\n name\n goal\n status\n startDate\n endDate\n startedAt\n completedAt\n baselineStartDate\n baselineEndDate\n planChanges {\n field\n fromValue\n toValue\n sprintStatus\n changedBy\n changedAt\n }\n velocity\n workItems {\n id\n title\n status\n storyPoints\n assigneeId\n }\n }\n totalCount\n }\n }\n`;\n\ninterface SprintWorkItem {\n id: string;\n title: string;\n status: string;\n storyPoints: number | null;\n assigneeId: string | null;\n}\n\ninterface SprintNode {\n id: string;\n name: string;\n goal: string | null;\n status: string;\n startDate: string | null;\n endDate: string | null;\n startedAt: string | null;\n completedAt: string | null;\n baselineStartDate: string | null;\n baselineEndDate: string | null;\n planChanges: SprintPlanChange[];\n velocity: number | null;\n workItems: SprintWorkItem[];\n}\n\ninterface SprintMetrics {\n totalPoints: number;\n completedPoints: number;\n tasksTotal: number;\n tasksCompleted: number;\n teamMemberIds: string[];\n velocity: number;\n}\n\nfunction deriveSprintMetrics(sprint: SprintNode): SprintMetrics {\n const items = sprint.workItems ?? [];\n const totalPoints = items.reduce((sum, w) => sum + (w.storyPoints ?? 0), 0);\n const completedPoints = items\n .filter((w) => w.status === 'DONE')\n .reduce((sum, w) => sum + (w.storyPoints ?? 0), 0);\n const tasksTotal = items.length;\n const tasksCompleted = items.filter((w) => w.status === 'DONE').length;\n const teamMemberIds = Array.from(\n new Set(items.map((w) => w.assigneeId).filter((id): id is string => Boolean(id)))\n );\n const velocity = sprint.velocity ?? completedPoints;\n return { totalPoints, completedPoints, tasksTotal, tasksCompleted, teamMemberIds, velocity };\n}\n\nexport function SprintsStartSprintPagePage() {\n const { workspaceId } = usePlanMagnet();\n\n const {\n data: sprintData,\n loading: sprintsLoading,\n error: sprintsError,\n } = useQuery<{\n planmagnetSprints: { items: SprintNode[]; totalCount: number };\n }>(GET_SPRINTS, {\n variables: { workspaceId, pagination: { first: 50 } },\n skip: !workspaceId,\n });\n\n const sprints = sprintData?.planmagnetSprints?.items ?? [];\n // REVIEW is still in flight (it can be completed or cancelled), so it\n // belongs with the active sprints rather than vanishing from this page.\n const activeSprints = sprints.filter((s) => s.status === 'ACTIVE' || s.status === 'REVIEW');\n const planningSprints = sprints.filter((s) => s.status === 'PLANNING');\n // Finished sprints used to vanish from this page, so \"did we finish on\n // time?\" had nowhere to be answered (BOFF-7918).\n const finishedSprints = sprints.filter(\n (s) => s.status === 'COMPLETED' || s.status === 'CANCELLED'\n );\n\n const navigate = usePlanMagnetNavigate();\n const openSprint = (id: string) => navigate(detailPath('/projects/planning-detail-page', id));\n\n // Only before the first load: a refetch after a sprint action must not blank\n // the page (it unmounted the controls mid-action).\n if (sprintsLoading && !sprintData) {\n return (\n <div className=\"flex items-center justify-center p-12\">\n <div className=\"animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full\" />\n </div>\n );\n }\n\n if (sprintsError) {\n return <div className=\"p-6 text-red-500\">Error: {sprintsError.message}</div>;\n }\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Sprint Management</h1>\n <p className=\"text-sm text-muted-foreground\">\n {sprints.length} sprints total · {activeSprints.length} active\n </p>\n </div>\n <NewSprintDialog onCreated={openSprint} />\n </div>\n\n {activeSprints.length > 0 && (\n <div className=\"space-y-4\">\n <h2 className=\"text-lg font-medium\">Active Sprints</h2>\n {activeSprints.map((sprint) => {\n const metrics = deriveSprintMetrics(sprint);\n const tasksForSprint = sprint.workItems ?? [];\n const pctDone =\n metrics.totalPoints > 0\n ? Math.round((metrics.completedPoints / metrics.totalPoints) * 100)\n : 0;\n return (\n <Card key={sprint.id}>\n <CardHeader className=\"pb-2\">\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-base flex items-center gap-2\">\n <Zap className=\"h-4 w-4 text-primary\" />\n <button\n type=\"button\"\n className=\"hover:underline text-left\"\n onClick={() => openSprint(sprint.id)}\n >\n {sprint.name}\n </button>\n </CardTitle>\n <div className=\"flex items-start gap-2\">\n <Badge>{sprint.status === 'REVIEW' ? 'Review' : 'Active'}</Badge>\n <SprintLifecycleActions\n sprintId={sprint.id}\n sprintName={sprint.name}\n status={sprint.status}\n />\n </div>\n </div>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <p className=\"text-sm text-muted-foreground\">{sprint.goal ?? ''}</p>\n <SprintDates sprint={sprint} />\n <div className=\"flex gap-4 text-xs text-muted-foreground\">\n <span className=\"flex items-center gap-1\">\n <Users className=\"h-3 w-3\" />\n {metrics.teamMemberIds.length} members\n </span>\n </div>\n <div className=\"grid grid-cols-3 gap-4 text-center\">\n <div className=\"p-3 bg-muted rounded-md\">\n <p className=\"text-lg font-bold\">\n {metrics.completedPoints}/{metrics.totalPoints}\n </p>\n <p className=\"text-xs text-muted-foreground\">Points</p>\n </div>\n <div className=\"p-3 bg-muted rounded-md\">\n <p className=\"text-lg font-bold\">\n {metrics.tasksCompleted}/{metrics.tasksTotal}\n </p>\n <p className=\"text-xs text-muted-foreground\">Tasks</p>\n </div>\n <div className=\"p-3 bg-muted rounded-md\">\n <p className=\"text-lg font-bold\">{metrics.velocity}</p>\n <p className=\"text-xs text-muted-foreground\">Velocity</p>\n </div>\n </div>\n <div>\n <div className=\"flex justify-between text-xs mb-1\">\n <span className=\"text-muted-foreground\">Sprint Progress</span>\n <span className=\"font-medium\">{pctDone}%</span>\n </div>\n <div className=\"w-full h-2 rounded-full bg-muted overflow-hidden\">\n <div\n className=\"h-full bg-primary rounded-full\"\n style={{ width: `${pctDone}%` }}\n />\n </div>\n </div>\n {tasksForSprint.length > 0 && (\n <div>\n <p className=\"text-xs font-medium text-muted-foreground mb-2\">\n Sprint Backlog\n </p>\n <div className=\"space-y-1\">\n {tasksForSprint.map((t) => (\n <div\n key={t.id}\n className=\"flex items-center justify-between border rounded p-2 text-sm\"\n >\n <span>{t.title}</span>\n <div className=\"flex gap-1\">\n <Badge variant=\"secondary\" className=\"text-xs capitalize\">\n {t.status.toLowerCase().replace('_', ' ')}\n </Badge>\n <span className=\"text-xs text-muted-foreground\">\n {t.storyPoints ?? 0}pts\n </span>\n </div>\n </div>\n ))}\n </div>\n </div>\n )}\n <div>\n <p className=\"text-xs font-medium text-muted-foreground mb-1\">Team</p>\n <div className=\"flex gap-2\">\n {/* Initials and tooltip from the person's resolved name; these were two characters of the\n user UUID with the full UUID as the tooltip (BOFF-7977). */}\n {metrics.teamMemberIds.map((memberId) => (\n <PersonAvatar\n key={memberId}\n id={memberId}\n className=\"h-7 w-7 rounded-full bg-primary/10 flex items-center justify-center text-[10px] font-medium text-primary\"\n />\n ))}\n </div>\n </div>\n </CardContent>\n </Card>\n );\n })}\n </div>\n )}\n\n {planningSprints.length > 0 && (\n <div className=\"space-y-4\">\n <h2 className=\"text-lg font-medium\">Planning</h2>\n {planningSprints.map((sprint) => {\n const metrics = deriveSprintMetrics(sprint);\n return (\n <Card key={sprint.id}>\n <CardHeader className=\"pb-2\">\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-base\">\n <button\n type=\"button\"\n className=\"hover:underline text-left\"\n onClick={() => openSprint(sprint.id)}\n >\n {sprint.name}\n </button>\n </CardTitle>\n <div className=\"flex items-start gap-2\">\n <Badge variant=\"secondary\">Planning</Badge>\n <SprintLifecycleActions\n sprintId={sprint.id}\n sprintName={sprint.name}\n status={sprint.status}\n />\n </div>\n </div>\n </CardHeader>\n <CardContent className=\"space-y-2\">\n <p className=\"text-sm text-muted-foreground\">{sprint.goal ?? ''}</p>\n <SprintDates sprint={sprint} />\n <div className=\"flex gap-4 text-xs text-muted-foreground\">\n <span>{metrics.totalPoints} points planned</span>\n <span>{metrics.teamMemberIds.length} members</span>\n </div>\n </CardContent>\n </Card>\n );\n })}\n </div>\n )}\n\n {finishedSprints.length > 0 && (\n <div className=\"space-y-4\" data-testid=\"finished-sprints\">\n <h2 className=\"text-lg font-medium\">Finished</h2>\n {finishedSprints.map((sprint) => {\n const metrics = deriveSprintMetrics(sprint);\n return (\n <Card key={sprint.id} data-testid=\"finished-sprint\">\n <CardHeader className=\"pb-2\">\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-base\">\n <button\n type=\"button\"\n className=\"hover:underline text-left\"\n onClick={() => openSprint(sprint.id)}\n >\n {sprint.name}\n </button>\n </CardTitle>\n <Badge variant=\"outline\">\n {sprint.status === 'COMPLETED' ? 'Completed' : 'Cancelled'}\n </Badge>\n </div>\n </CardHeader>\n <CardContent className=\"space-y-2\">\n <SprintDates sprint={sprint} />\n <p className=\"text-xs text-muted-foreground\">\n {metrics.completedPoints}/{metrics.totalPoints} points done\n </p>\n </CardContent>\n </Card>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SprintsStartSprintPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/SprintsStartSprintPagePage.tsx"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport { Card, CardContent, CardHeader, CardTitle, Badge } from '@burdenoff/fe-libs/ui';\nimport { Zap, Users } from 'lucide-react';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { detailPath } from '../utils/rowNavigation';\nimport { NewSprintDialog, SprintLifecycleActions } from '../sprints/SprintControls';\nimport { SprintDates, type SprintPlanChange } from '../sprints/SprintDates';\nimport { PersonAvatar } from '../people/People';\n\nconst GET_SPRINTS = gql`\n query GetSprints(\n $workspaceId: ID!\n $filter: PlanmagnetSprintFilter\n $pagination: PlanmagnetPaginationInput\n ) {\n planmagnetSprints(workspaceId: $workspaceId, filter: $filter, pagination: $pagination) {\n items {\n id\n name\n goal\n status\n startDate\n endDate\n startedAt\n completedAt\n baselineStartDate\n baselineEndDate\n planChanges {\n field\n fromValue\n toValue\n sprintStatus\n changedBy\n changedAt\n }\n velocity\n workItems {\n id\n title\n status\n storyPoints\n assigneeId\n }\n }\n totalCount\n }\n }\n`;\n\ninterface SprintWorkItem {\n id: string;\n title: string;\n status: string;\n storyPoints: number | null;\n assigneeId: string | null;\n}\n\ninterface SprintNode {\n id: string;\n name: string;\n goal: string | null;\n status: string;\n startDate: string | null;\n endDate: string | null;\n startedAt: string | null;\n completedAt: string | null;\n baselineStartDate: string | null;\n baselineEndDate: string | null;\n planChanges: SprintPlanChange[];\n velocity: number | null;\n workItems: SprintWorkItem[];\n}\n\ninterface SprintMetrics {\n totalPoints: number;\n completedPoints: number;\n tasksTotal: number;\n tasksCompleted: number;\n teamMemberIds: string[];\n velocity: number | null;\n}\n\nfunction deriveSprintMetrics(sprint: SprintNode): SprintMetrics {\n const items = sprint.workItems ?? [];\n const totalPoints = items.reduce((sum, w) => sum + (w.storyPoints ?? 0), 0);\n const completedPoints = items\n .filter((w) => w.status === 'DONE')\n .reduce((sum, w) => sum + (w.storyPoints ?? 0), 0);\n const tasksTotal = items.length;\n const tasksCompleted = items.filter((w) => w.status === 'DONE').length;\n const teamMemberIds = Array.from(\n new Set(items.map((w) => w.assigneeId).filter((id): id is string => Boolean(id)))\n );\n // BOFF-7944: velocity is the server's DONE-points-at-completion, set only once the sprint is COMPLETED. It used to\n // fall back to the points done so far — a different number under the same name (the Points tile shows that).\n const velocity = sprint.velocity;\n return { totalPoints, completedPoints, tasksTotal, tasksCompleted, teamMemberIds, velocity };\n}\n\nexport function SprintsStartSprintPagePage() {\n const { workspaceId } = usePlanMagnet();\n\n const {\n data: sprintData,\n loading: sprintsLoading,\n error: sprintsError,\n } = useQuery<{\n planmagnetSprints: { items: SprintNode[]; totalCount: number };\n }>(GET_SPRINTS, {\n variables: { workspaceId, pagination: { first: 50 } },\n skip: !workspaceId,\n });\n\n const sprints = sprintData?.planmagnetSprints?.items ?? [];\n // REVIEW is still in flight (it can be completed or cancelled), so it\n // belongs with the active sprints rather than vanishing from this page.\n const activeSprints = sprints.filter((s) => s.status === 'ACTIVE' || s.status === 'REVIEW');\n const planningSprints = sprints.filter((s) => s.status === 'PLANNING');\n // Finished sprints used to vanish from this page, so \"did we finish on\n // time?\" had nowhere to be answered (BOFF-7918).\n const finishedSprints = sprints.filter(\n (s) => s.status === 'COMPLETED' || s.status === 'CANCELLED'\n );\n\n const navigate = usePlanMagnetNavigate();\n const openSprint = (id: string) => navigate(detailPath('/projects/planning-detail-page', id));\n\n // Only before the first load: a refetch after a sprint action must not blank\n // the page (it unmounted the controls mid-action).\n if (sprintsLoading && !sprintData) {\n return (\n <div className=\"flex items-center justify-center p-12\">\n <div className=\"animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full\" />\n </div>\n );\n }\n\n if (sprintsError) {\n return <div className=\"p-6 text-red-500\">Error: {sprintsError.message}</div>;\n }\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Sprint Management</h1>\n <p className=\"text-sm text-muted-foreground\">\n {sprints.length} sprints total · {activeSprints.length} active\n </p>\n </div>\n <NewSprintDialog onCreated={openSprint} />\n </div>\n\n {activeSprints.length > 0 && (\n <div className=\"space-y-4\">\n <h2 className=\"text-lg font-medium\">Active Sprints</h2>\n {activeSprints.map((sprint) => {\n const metrics = deriveSprintMetrics(sprint);\n const tasksForSprint = sprint.workItems ?? [];\n const pctDone =\n metrics.totalPoints > 0\n ? Math.round((metrics.completedPoints / metrics.totalPoints) * 100)\n : 0;\n return (\n <Card key={sprint.id}>\n <CardHeader className=\"pb-2\">\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-base flex items-center gap-2\">\n <Zap className=\"h-4 w-4 text-primary\" />\n <button\n type=\"button\"\n className=\"hover:underline text-left\"\n onClick={() => openSprint(sprint.id)}\n >\n {sprint.name}\n </button>\n </CardTitle>\n <div className=\"flex items-start gap-2\">\n <Badge>{sprint.status === 'REVIEW' ? 'Review' : 'Active'}</Badge>\n <SprintLifecycleActions\n sprintId={sprint.id}\n sprintName={sprint.name}\n status={sprint.status}\n />\n </div>\n </div>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <p className=\"text-sm text-muted-foreground\">{sprint.goal ?? ''}</p>\n <SprintDates sprint={sprint} />\n <div className=\"flex gap-4 text-xs text-muted-foreground\">\n <span className=\"flex items-center gap-1\">\n <Users className=\"h-3 w-3\" />\n {metrics.teamMemberIds.length} members\n </span>\n </div>\n <div className=\"grid grid-cols-3 gap-4 text-center\">\n <div className=\"p-3 bg-muted rounded-md\">\n <p className=\"text-lg font-bold\">\n {metrics.completedPoints}/{metrics.totalPoints}\n </p>\n <p className=\"text-xs text-muted-foreground\">Points</p>\n </div>\n <div className=\"p-3 bg-muted rounded-md\">\n <p className=\"text-lg font-bold\">\n {metrics.tasksCompleted}/{metrics.tasksTotal}\n </p>\n <p className=\"text-xs text-muted-foreground\">Tasks</p>\n </div>\n <div className=\"p-3 bg-muted rounded-md\">\n <p className=\"text-lg font-bold\">\n {metrics.velocity != null ? metrics.velocity : '—'}\n </p>\n <p\n className=\"text-xs text-muted-foreground\"\n title=\"Story points done when the sprint was completed\"\n >\n Velocity\n </p>\n </div>\n </div>\n <div>\n <div className=\"flex justify-between text-xs mb-1\">\n <span className=\"text-muted-foreground\">Sprint Progress</span>\n <span className=\"font-medium\">{pctDone}%</span>\n </div>\n <div className=\"w-full h-2 rounded-full bg-muted overflow-hidden\">\n <div\n className=\"h-full bg-primary rounded-full\"\n style={{ width: `${pctDone}%` }}\n />\n </div>\n </div>\n {tasksForSprint.length > 0 && (\n <div>\n <p className=\"text-xs font-medium text-muted-foreground mb-2\">\n Sprint Backlog\n </p>\n <div className=\"space-y-1\">\n {tasksForSprint.map((t) => (\n <div\n key={t.id}\n className=\"flex items-center justify-between border rounded p-2 text-sm\"\n >\n <span>{t.title}</span>\n <div className=\"flex gap-1\">\n <Badge variant=\"secondary\" className=\"text-xs capitalize\">\n {t.status.toLowerCase().replace('_', ' ')}\n </Badge>\n <span className=\"text-xs text-muted-foreground\">\n {t.storyPoints ?? 0}pts\n </span>\n </div>\n </div>\n ))}\n </div>\n </div>\n )}\n <div>\n <p className=\"text-xs font-medium text-muted-foreground mb-1\">Team</p>\n <div className=\"flex gap-2\">\n {/* Initials and tooltip from the person's resolved name; these were two characters of the\n user UUID with the full UUID as the tooltip (BOFF-7977). */}\n {metrics.teamMemberIds.map((memberId) => (\n <PersonAvatar\n key={memberId}\n id={memberId}\n className=\"h-7 w-7 rounded-full bg-primary/10 flex items-center justify-center text-[10px] font-medium text-primary\"\n />\n ))}\n </div>\n </div>\n </CardContent>\n </Card>\n );\n })}\n </div>\n )}\n\n {planningSprints.length > 0 && (\n <div className=\"space-y-4\">\n <h2 className=\"text-lg font-medium\">Planning</h2>\n {planningSprints.map((sprint) => {\n const metrics = deriveSprintMetrics(sprint);\n return (\n <Card key={sprint.id}>\n <CardHeader className=\"pb-2\">\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-base\">\n <button\n type=\"button\"\n className=\"hover:underline text-left\"\n onClick={() => openSprint(sprint.id)}\n >\n {sprint.name}\n </button>\n </CardTitle>\n <div className=\"flex items-start gap-2\">\n <Badge variant=\"secondary\">Planning</Badge>\n <SprintLifecycleActions\n sprintId={sprint.id}\n sprintName={sprint.name}\n status={sprint.status}\n />\n </div>\n </div>\n </CardHeader>\n <CardContent className=\"space-y-2\">\n <p className=\"text-sm text-muted-foreground\">{sprint.goal ?? ''}</p>\n <SprintDates sprint={sprint} />\n <div className=\"flex gap-4 text-xs text-muted-foreground\">\n <span>{metrics.totalPoints} points planned</span>\n <span>{metrics.teamMemberIds.length} members</span>\n </div>\n </CardContent>\n </Card>\n );\n })}\n </div>\n )}\n\n {finishedSprints.length > 0 && (\n <div className=\"space-y-4\" data-testid=\"finished-sprints\">\n <h2 className=\"text-lg font-medium\">Finished</h2>\n {finishedSprints.map((sprint) => {\n const metrics = deriveSprintMetrics(sprint);\n return (\n <Card key={sprint.id} data-testid=\"finished-sprint\">\n <CardHeader className=\"pb-2\">\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-base\">\n <button\n type=\"button\"\n className=\"hover:underline text-left\"\n onClick={() => openSprint(sprint.id)}\n >\n {sprint.name}\n </button>\n </CardTitle>\n <Badge variant=\"outline\">\n {sprint.status === 'COMPLETED' ? 'Completed' : 'Cancelled'}\n </Badge>\n </div>\n </CardHeader>\n <CardContent className=\"space-y-2\">\n <SprintDates sprint={sprint} />\n <p className=\"text-xs text-muted-foreground\">\n {metrics.completedPoints}/{metrics.totalPoints} points done\n </p>\n </CardContent>\n </Card>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TasksCreateTaskPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/TasksCreateTaskPagePage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TasksCreateTaskPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/TasksCreateTaskPagePage.tsx"],"names":[],"mappings":"AAsEA,wBAAgB,uBAAuB,4CAqStC"}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { usePlanMagnet as e, usePlanMagnetNavigate as t } from "../providers/PlanMagnetProvider.js";
|
|
2
2
|
import { throwOnError as n } from "../utils/mutationResult.js";
|
|
3
3
|
import { parseIntField as r } from "../utils/formValidation.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
4
|
+
import { AssigneeSelect as i } from "../controls/WorkItemControls.js";
|
|
5
|
+
import { useState as a } from "react";
|
|
6
|
+
import { CheckSquare as o, Save as s, X as c } from "lucide-react";
|
|
7
|
+
import { gql as l } from "@apollo/client";
|
|
8
|
+
import { useMutation as u, useQuery as d } from "@apollo/client/react";
|
|
9
|
+
import { jsx as f, jsxs as p } from "react/jsx-runtime";
|
|
10
|
+
import { Button as m, Card as h, CardContent as g, CardHeader as _, CardTitle as v, Input as y } from "@burdenoff/fe-libs/ui";
|
|
10
11
|
//#region src/planmagnet/pages/TasksCreateTaskPagePage.tsx
|
|
11
|
-
var
|
|
12
|
+
var b = l`
|
|
12
13
|
mutation CreateWorkItem($input: PlanmagnetCreateWorkItemInput!) {
|
|
13
14
|
planmagnetCreateWorkItem(input: $input) {
|
|
14
15
|
id
|
|
@@ -24,7 +25,7 @@ var y = c`
|
|
|
24
25
|
createdAt
|
|
25
26
|
}
|
|
26
27
|
}
|
|
27
|
-
`,
|
|
28
|
+
`, x = l`
|
|
28
29
|
query GetProjectsForTaskCreate($workspaceId: ID!) {
|
|
29
30
|
planmagnetProjects(workspaceId: $workspaceId, pagination: { first: 100 }) {
|
|
30
31
|
items {
|
|
@@ -34,9 +35,27 @@ var y = c`
|
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
`, S = l`
|
|
39
|
+
query GetSprintsForTaskCreate($workspaceId: ID!, $projectId: String) {
|
|
40
|
+
planmagnetSprints(
|
|
41
|
+
workspaceId: $workspaceId
|
|
42
|
+
filter: { projectId: $projectId }
|
|
43
|
+
pagination: { first: 100 }
|
|
44
|
+
) {
|
|
45
|
+
items {
|
|
46
|
+
id
|
|
47
|
+
name
|
|
48
|
+
status
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
`, C = new Set([
|
|
53
|
+
"PLANNING",
|
|
54
|
+
"ACTIVE",
|
|
55
|
+
"REVIEW"
|
|
56
|
+
]);
|
|
57
|
+
function w() {
|
|
58
|
+
let { workspaceId: l } = e(), [w, T] = a({
|
|
40
59
|
title: "",
|
|
41
60
|
description: "",
|
|
42
61
|
projectId: "",
|
|
@@ -45,112 +64,121 @@ function x() {
|
|
|
45
64
|
storyPoints: "5",
|
|
46
65
|
labels: "",
|
|
47
66
|
sprintId: "",
|
|
67
|
+
assigneeId: "",
|
|
48
68
|
dueDate: ""
|
|
49
|
-
}), { data:
|
|
50
|
-
variables: { workspaceId:
|
|
51
|
-
skip: !
|
|
52
|
-
}),
|
|
53
|
-
|
|
69
|
+
}), { data: E, loading: D, error: O, refetch: k } = d(x, {
|
|
70
|
+
variables: { workspaceId: l ?? "default" },
|
|
71
|
+
skip: !l
|
|
72
|
+
}), A = E?.planmagnetProjects?.items ?? [], j = w.projectId || A[0]?.id || "", { data: M, loading: N } = d(S, {
|
|
73
|
+
variables: {
|
|
74
|
+
workspaceId: l ?? "default",
|
|
75
|
+
projectId: j
|
|
76
|
+
},
|
|
77
|
+
skip: !l || !j
|
|
78
|
+
}), P = (M?.planmagnetSprints?.items ?? []).filter((e) => C.has(e.status)), F = t(), [I, { loading: L }] = u(b, { refetchQueries: ["GetWorkItems"] }), [R, z] = a(null), B = r(w.storyPoints, { min: 0 });
|
|
79
|
+
return /* @__PURE__ */ p("div", {
|
|
54
80
|
className: "space-y-6 p-6 max-w-4xl",
|
|
55
81
|
children: [
|
|
56
|
-
/* @__PURE__ */
|
|
82
|
+
/* @__PURE__ */ p("div", {
|
|
57
83
|
className: "flex items-center justify-between",
|
|
58
|
-
children: [/* @__PURE__ */
|
|
84
|
+
children: [/* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("h1", {
|
|
59
85
|
className: "text-2xl font-semibold",
|
|
60
86
|
children: "Create Task"
|
|
61
|
-
}), /* @__PURE__ */
|
|
87
|
+
}), /* @__PURE__ */ f("p", {
|
|
62
88
|
className: "text-sm text-muted-foreground",
|
|
63
89
|
children: "Add a new task to the project backlog."
|
|
64
|
-
})] }), /* @__PURE__ */
|
|
90
|
+
})] }), /* @__PURE__ */ p("div", {
|
|
65
91
|
className: "flex gap-2",
|
|
66
|
-
children: [/* @__PURE__ */
|
|
92
|
+
children: [/* @__PURE__ */ p(m, {
|
|
67
93
|
variant: "outline",
|
|
68
94
|
size: "sm",
|
|
69
|
-
onClick: () =>
|
|
70
|
-
children: [/* @__PURE__ */
|
|
71
|
-
}), /* @__PURE__ */
|
|
95
|
+
onClick: () => F("/tasks/tasks-page"),
|
|
96
|
+
children: [/* @__PURE__ */ f(c, { className: "mr-1 h-4 w-4" }), "Cancel"]
|
|
97
|
+
}), /* @__PURE__ */ p(m, {
|
|
72
98
|
size: "sm",
|
|
73
99
|
onClick: async () => {
|
|
74
|
-
if (!(!
|
|
75
|
-
|
|
100
|
+
if (!(!w.title.trim() || !j || !l || B.invalid)) {
|
|
101
|
+
z(null);
|
|
76
102
|
try {
|
|
77
|
-
let e = (await n(
|
|
78
|
-
projectId:
|
|
79
|
-
title:
|
|
80
|
-
description:
|
|
81
|
-
type:
|
|
82
|
-
priority:
|
|
83
|
-
storyPoints:
|
|
84
|
-
labels:
|
|
85
|
-
sprintId:
|
|
86
|
-
|
|
103
|
+
let e = (await n(I({ variables: { input: {
|
|
104
|
+
projectId: j,
|
|
105
|
+
title: w.title,
|
|
106
|
+
description: w.description || void 0,
|
|
107
|
+
type: w.type,
|
|
108
|
+
priority: w.priority,
|
|
109
|
+
storyPoints: B.value,
|
|
110
|
+
labels: w.labels ? w.labels.split(",").map((e) => e.trim()).filter(Boolean) : void 0,
|
|
111
|
+
sprintId: w.sprintId || void 0,
|
|
112
|
+
assigneeId: w.assigneeId || void 0,
|
|
113
|
+
dueDate: w.dueDate || void 0
|
|
87
114
|
} } }))).data?.planmagnetCreateWorkItem?.id;
|
|
88
|
-
|
|
115
|
+
F(e ? `/tasks/task-detail-page?taskId=${encodeURIComponent(e)}` : "/tasks/tasks-page");
|
|
89
116
|
} catch (e) {
|
|
90
|
-
|
|
117
|
+
z(e instanceof Error ? e.message : "The task could not be created.");
|
|
91
118
|
}
|
|
92
119
|
}
|
|
93
120
|
},
|
|
94
|
-
disabled:
|
|
95
|
-
children: [/* @__PURE__ */
|
|
121
|
+
disabled: L || !w.title.trim() || !j || B.invalid,
|
|
122
|
+
children: [/* @__PURE__ */ f(s, { className: "mr-1 h-4 w-4" }), L ? "Creating..." : "Create Task"]
|
|
96
123
|
})]
|
|
97
124
|
})]
|
|
98
125
|
}),
|
|
99
|
-
|
|
126
|
+
R && /* @__PURE__ */ f("div", {
|
|
100
127
|
role: "alert",
|
|
101
128
|
className: "p-3 bg-destructive/10 text-destructive rounded-md text-sm",
|
|
102
|
-
children:
|
|
129
|
+
children: R
|
|
103
130
|
}),
|
|
104
|
-
/* @__PURE__ */
|
|
131
|
+
/* @__PURE__ */ p(h, { children: [/* @__PURE__ */ f(_, { children: /* @__PURE__ */ p(v, {
|
|
105
132
|
className: "flex items-center gap-2",
|
|
106
|
-
children: [/* @__PURE__ */
|
|
107
|
-
}) }), /* @__PURE__ */
|
|
133
|
+
children: [/* @__PURE__ */ f(o, { className: "h-4 w-4" }), "Task Details"]
|
|
134
|
+
}) }), /* @__PURE__ */ p(g, {
|
|
108
135
|
className: "space-y-4",
|
|
109
136
|
children: [
|
|
110
|
-
/* @__PURE__ */
|
|
137
|
+
/* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
|
|
111
138
|
className: "text-sm font-medium",
|
|
112
139
|
children: "Title"
|
|
113
|
-
}), /* @__PURE__ */
|
|
114
|
-
value:
|
|
115
|
-
onChange: (e) =>
|
|
116
|
-
...
|
|
140
|
+
}), /* @__PURE__ */ f(y, {
|
|
141
|
+
value: w.title,
|
|
142
|
+
onChange: (e) => T({
|
|
143
|
+
...w,
|
|
117
144
|
title: e.target.value
|
|
118
145
|
}),
|
|
119
146
|
className: "mt-1",
|
|
120
147
|
placeholder: "e.g. Implement search query parser"
|
|
121
148
|
})] }),
|
|
122
|
-
/* @__PURE__ */
|
|
149
|
+
/* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
|
|
123
150
|
className: "text-sm font-medium",
|
|
124
151
|
children: "Description"
|
|
125
|
-
}), /* @__PURE__ */
|
|
152
|
+
}), /* @__PURE__ */ f("textarea", {
|
|
126
153
|
className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[100px]",
|
|
127
|
-
value:
|
|
128
|
-
onChange: (e) =>
|
|
129
|
-
...
|
|
154
|
+
value: w.description,
|
|
155
|
+
onChange: (e) => T({
|
|
156
|
+
...w,
|
|
130
157
|
description: e.target.value
|
|
131
158
|
}),
|
|
132
159
|
placeholder: "Describe the task requirements..."
|
|
133
160
|
})] }),
|
|
134
|
-
/* @__PURE__ */
|
|
161
|
+
/* @__PURE__ */ p("div", {
|
|
135
162
|
className: "grid grid-cols-3 gap-4",
|
|
136
163
|
children: [
|
|
137
|
-
/* @__PURE__ */
|
|
138
|
-
/* @__PURE__ */
|
|
164
|
+
/* @__PURE__ */ p("div", { children: [
|
|
165
|
+
/* @__PURE__ */ f("label", {
|
|
139
166
|
className: "text-sm font-medium",
|
|
140
167
|
children: "Project"
|
|
141
168
|
}),
|
|
142
|
-
/* @__PURE__ */
|
|
169
|
+
/* @__PURE__ */ p("select", {
|
|
143
170
|
className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm",
|
|
144
|
-
value:
|
|
145
|
-
onChange: (e) =>
|
|
146
|
-
...
|
|
147
|
-
projectId: e.target.value
|
|
171
|
+
value: j,
|
|
172
|
+
onChange: (e) => T({
|
|
173
|
+
...w,
|
|
174
|
+
projectId: e.target.value,
|
|
175
|
+
sprintId: ""
|
|
148
176
|
}),
|
|
149
|
-
children: [
|
|
177
|
+
children: [A.length === 0 && /* @__PURE__ */ f("option", {
|
|
150
178
|
value: "",
|
|
151
179
|
disabled: !0,
|
|
152
|
-
children:
|
|
153
|
-
}),
|
|
180
|
+
children: D && !E ? "Loading projects…" : O ? "Projects could not be loaded" : "No projects yet"
|
|
181
|
+
}), A.map((e) => /* @__PURE__ */ p("option", {
|
|
154
182
|
value: e.id,
|
|
155
183
|
children: [
|
|
156
184
|
e.key,
|
|
@@ -159,33 +187,33 @@ function x() {
|
|
|
159
187
|
]
|
|
160
188
|
}, e.id))]
|
|
161
189
|
}),
|
|
162
|
-
|
|
190
|
+
O && /* @__PURE__ */ p("p", {
|
|
163
191
|
role: "alert",
|
|
164
192
|
className: "mt-1 flex items-center gap-2 text-xs text-destructive",
|
|
165
|
-
children: [
|
|
193
|
+
children: [O.message, /* @__PURE__ */ f(m, {
|
|
166
194
|
type: "button",
|
|
167
195
|
size: "sm",
|
|
168
196
|
variant: "ghost",
|
|
169
197
|
className: "h-6 px-2 text-xs",
|
|
170
|
-
onClick: () => void
|
|
198
|
+
onClick: () => void k(),
|
|
171
199
|
children: "Retry"
|
|
172
200
|
})]
|
|
173
201
|
}),
|
|
174
|
-
!
|
|
202
|
+
!D && !O && E && A.length === 0 && /* @__PURE__ */ f("button", {
|
|
175
203
|
type: "button",
|
|
176
204
|
className: "mt-1 text-xs text-muted-foreground underline",
|
|
177
|
-
onClick: () =>
|
|
205
|
+
onClick: () => F("/projects/create-project-page"),
|
|
178
206
|
children: "Create a project first"
|
|
179
207
|
})
|
|
180
208
|
] }),
|
|
181
|
-
/* @__PURE__ */
|
|
209
|
+
/* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
|
|
182
210
|
className: "text-sm font-medium",
|
|
183
211
|
children: "Priority"
|
|
184
|
-
}), /* @__PURE__ */
|
|
212
|
+
}), /* @__PURE__ */ f("select", {
|
|
185
213
|
className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm",
|
|
186
|
-
value:
|
|
187
|
-
onChange: (e) =>
|
|
188
|
-
...
|
|
214
|
+
value: w.priority,
|
|
215
|
+
onChange: (e) => T({
|
|
216
|
+
...w,
|
|
189
217
|
priority: e.target.value
|
|
190
218
|
}),
|
|
191
219
|
children: [
|
|
@@ -193,19 +221,19 @@ function x() {
|
|
|
193
221
|
"MEDIUM",
|
|
194
222
|
"HIGH",
|
|
195
223
|
"CRITICAL"
|
|
196
|
-
].map((e) => /* @__PURE__ */
|
|
224
|
+
].map((e) => /* @__PURE__ */ f("option", {
|
|
197
225
|
value: e,
|
|
198
226
|
children: e.toLowerCase()
|
|
199
227
|
}, e))
|
|
200
228
|
})] }),
|
|
201
|
-
/* @__PURE__ */
|
|
229
|
+
/* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
|
|
202
230
|
className: "text-sm font-medium",
|
|
203
231
|
children: "Type"
|
|
204
|
-
}), /* @__PURE__ */
|
|
232
|
+
}), /* @__PURE__ */ f("select", {
|
|
205
233
|
className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm",
|
|
206
|
-
value:
|
|
207
|
-
onChange: (e) =>
|
|
208
|
-
...
|
|
234
|
+
value: w.type,
|
|
235
|
+
onChange: (e) => T({
|
|
236
|
+
...w,
|
|
209
237
|
type: e.target.value
|
|
210
238
|
}),
|
|
211
239
|
children: [
|
|
@@ -214,74 +242,102 @@ function x() {
|
|
|
214
242
|
"TASK",
|
|
215
243
|
"EPIC",
|
|
216
244
|
"SUB_TASK"
|
|
217
|
-
].map((e) => /* @__PURE__ */
|
|
245
|
+
].map((e) => /* @__PURE__ */ f("option", {
|
|
218
246
|
value: e,
|
|
219
247
|
children: e.toLowerCase().replace("_", " ")
|
|
220
248
|
}, e))
|
|
221
249
|
})] })
|
|
222
250
|
]
|
|
223
251
|
}),
|
|
224
|
-
/* @__PURE__ */
|
|
252
|
+
/* @__PURE__ */ p("div", {
|
|
225
253
|
className: "grid grid-cols-3 gap-4",
|
|
226
254
|
children: [
|
|
227
|
-
/* @__PURE__ */
|
|
228
|
-
/* @__PURE__ */
|
|
255
|
+
/* @__PURE__ */ p("div", { children: [
|
|
256
|
+
/* @__PURE__ */ f("label", {
|
|
229
257
|
htmlFor: "task-story-points",
|
|
230
258
|
className: "text-sm font-medium",
|
|
231
259
|
children: "Story Points"
|
|
232
260
|
}),
|
|
233
|
-
/* @__PURE__ */
|
|
261
|
+
/* @__PURE__ */ f(y, {
|
|
234
262
|
id: "task-story-points",
|
|
235
263
|
type: "number",
|
|
236
264
|
min: 0,
|
|
237
265
|
step: 1,
|
|
238
|
-
value:
|
|
239
|
-
onChange: (e) =>
|
|
240
|
-
...
|
|
266
|
+
value: w.storyPoints,
|
|
267
|
+
onChange: (e) => T({
|
|
268
|
+
...w,
|
|
241
269
|
storyPoints: e.target.value
|
|
242
270
|
}),
|
|
243
|
-
"aria-invalid":
|
|
271
|
+
"aria-invalid": B.invalid,
|
|
244
272
|
className: "mt-1"
|
|
245
273
|
}),
|
|
246
|
-
|
|
274
|
+
B.invalid && /* @__PURE__ */ f("p", {
|
|
247
275
|
role: "alert",
|
|
248
276
|
className: "mt-1 text-xs text-destructive",
|
|
249
277
|
children: "Story points must be a whole number, 0 or more."
|
|
250
278
|
})
|
|
251
279
|
] }),
|
|
252
|
-
/* @__PURE__ */
|
|
280
|
+
/* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
|
|
281
|
+
htmlFor: "task-sprint",
|
|
253
282
|
className: "text-sm font-medium",
|
|
254
|
-
children: "Sprint
|
|
255
|
-
}), /* @__PURE__ */
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
283
|
+
children: "Sprint"
|
|
284
|
+
}), /* @__PURE__ */ p("select", {
|
|
285
|
+
id: "task-sprint",
|
|
286
|
+
className: "mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm",
|
|
287
|
+
value: w.sprintId,
|
|
288
|
+
onChange: (e) => T({
|
|
289
|
+
...w,
|
|
259
290
|
sprintId: e.target.value
|
|
260
291
|
}),
|
|
261
|
-
|
|
262
|
-
|
|
292
|
+
children: [/* @__PURE__ */ f("option", {
|
|
293
|
+
value: "",
|
|
294
|
+
children: N && !M ? "Loading sprints…" : "No sprint"
|
|
295
|
+
}), P.map((e) => /* @__PURE__ */ p("option", {
|
|
296
|
+
value: e.id,
|
|
297
|
+
children: [
|
|
298
|
+
e.name,
|
|
299
|
+
" (",
|
|
300
|
+
e.status.toLowerCase(),
|
|
301
|
+
")"
|
|
302
|
+
]
|
|
303
|
+
}, e.id))]
|
|
263
304
|
})] }),
|
|
264
|
-
/* @__PURE__ */
|
|
305
|
+
/* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
|
|
265
306
|
className: "text-sm font-medium",
|
|
266
307
|
children: "Due Date"
|
|
267
|
-
}), /* @__PURE__ */
|
|
308
|
+
}), /* @__PURE__ */ f(y, {
|
|
268
309
|
type: "date",
|
|
269
|
-
value:
|
|
270
|
-
onChange: (e) =>
|
|
271
|
-
...
|
|
310
|
+
value: w.dueDate,
|
|
311
|
+
onChange: (e) => T({
|
|
312
|
+
...w,
|
|
272
313
|
dueDate: e.target.value
|
|
273
314
|
}),
|
|
274
315
|
className: "mt-1"
|
|
275
316
|
})] })
|
|
276
317
|
]
|
|
277
318
|
}),
|
|
278
|
-
/* @__PURE__ */
|
|
319
|
+
/* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
|
|
320
|
+
htmlFor: "task-assignee",
|
|
321
|
+
className: "text-sm font-medium",
|
|
322
|
+
children: "Assignee"
|
|
323
|
+
}), /* @__PURE__ */ f("div", {
|
|
324
|
+
className: "mt-1",
|
|
325
|
+
children: /* @__PURE__ */ f(i, {
|
|
326
|
+
id: "task-assignee",
|
|
327
|
+
value: w.assigneeId,
|
|
328
|
+
onChange: (e) => T({
|
|
329
|
+
...w,
|
|
330
|
+
assigneeId: e
|
|
331
|
+
})
|
|
332
|
+
})
|
|
333
|
+
})] }),
|
|
334
|
+
/* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
|
|
279
335
|
className: "text-sm font-medium",
|
|
280
336
|
children: "Labels (comma-separated)"
|
|
281
|
-
}), /* @__PURE__ */
|
|
282
|
-
value:
|
|
283
|
-
onChange: (e) =>
|
|
284
|
-
...
|
|
337
|
+
}), /* @__PURE__ */ f(y, {
|
|
338
|
+
value: w.labels,
|
|
339
|
+
onChange: (e) => T({
|
|
340
|
+
...w,
|
|
285
341
|
labels: e.target.value
|
|
286
342
|
}),
|
|
287
343
|
className: "mt-1",
|
|
@@ -293,6 +349,6 @@ function x() {
|
|
|
293
349
|
});
|
|
294
350
|
}
|
|
295
351
|
//#endregion
|
|
296
|
-
export {
|
|
352
|
+
export { w as TasksCreateTaskPagePage };
|
|
297
353
|
|
|
298
354
|
//# sourceMappingURL=TasksCreateTaskPagePage.js.map
|