@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":"TasksCreateTaskPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/TasksCreateTaskPagePage.tsx"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation, useQuery } from '@apollo/client/react';\nimport { Card, CardContent, CardHeader, CardTitle, Button, Input } from '@burdenoff/fe-libs/ui';\nimport { Save, X, CheckSquare } from 'lucide-react';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { throwOnError } from '../utils/mutationResult';\nimport { parseIntField } from '../utils/formValidation';\n\ninterface PlanmagnetProjectOption {\n id: string;\n name: string;\n key: string;\n}\n\nconst CREATE_WORK_ITEM = gql`\n mutation CreateWorkItem($input: PlanmagnetCreateWorkItemInput!) {\n planmagnetCreateWorkItem(input: $input) {\n id\n title\n type\n status\n priority\n key\n storyPoints\n dueDate\n labels\n sprintId\n createdAt\n }\n }\n`;\n\n// BOFF-4442/4443 live-verify fix: a WorkItem must belong to a real project\n// (PlanmagnetCreateWorkItemInput.projectId is non-null); the form needs the\n// caller's actual projects to choose from rather than a free-text name.\nconst GET_PROJECTS = gql`\n query GetProjectsForTaskCreate($workspaceId: ID!) {\n planmagnetProjects(workspaceId: $workspaceId, pagination: { first: 100 }) {\n items {\n id\n name\n key\n }\n }\n }\n`;\n\nexport function TasksCreateTaskPagePage() {\n const { workspaceId } = usePlanMagnet();\n const [form, setForm] = useState({\n title: '',\n description: '',\n projectId: '',\n priority: 'MEDIUM',\n type: 'STORY',\n storyPoints: '5',\n labels: '',\n sprintId: '',\n dueDate: '',\n });\n\n const {\n data: projectsData,\n loading: projectsLoading,\n error: projectsError,\n refetch: refetchProjects,\n } = useQuery<{ planmagnetProjects?: { items: PlanmagnetProjectOption[] } }>(GET_PROJECTS, {\n variables: { workspaceId: workspaceId ?? 'default' },\n skip: !workspaceId,\n });\n const projects: PlanmagnetProjectOption[] = projectsData?.planmagnetProjects?.items ?? [];\n // Fall back to the first loaded project when the user hasn't picked one\n // yet, without stashing derived state in an effect (avoids the extra\n // render cycle and keeps a single source of truth: `projects`).\n const selectedProjectId = form.projectId || projects[0]?.id || '';\n\n const navigate = usePlanMagnetNavigate();\n const [createWorkItem, { loading: saving }] = useMutation(CREATE_WORK_ITEM, {\n refetchQueries: ['GetWorkItems'],\n });\n const [saveError, setSaveError] = useState<string | null>(null);\n // Story points are a whole number, 0 or more (BOFF-7833: prod accepted -3).\n const storyPoints = parseIntField(form.storyPoints, { min: 0 });\n\n const handleCreate = async () => {\n if (!form.title.trim() || !selectedProjectId || !workspaceId || storyPoints.invalid) return;\n setSaveError(null);\n // Success opens the new task; a refusal shows the service's reason (errorPolicy 'all' resolves refused\n // mutations, so the old code showed nothing either way).\n try {\n const result = await throwOnError(\n createWorkItem({\n variables: {\n input: {\n projectId: selectedProjectId,\n title: form.title,\n description: form.description || undefined,\n type: form.type,\n priority: form.priority,\n storyPoints: storyPoints.value,\n labels: form.labels\n ? form.labels\n .split(',')\n .map((l) => l.trim())\n .filter(Boolean)\n : undefined,\n sprintId: form.sprintId || undefined,\n dueDate: form.dueDate || undefined,\n },\n },\n })\n );\n const id = (result.data as { planmagnetCreateWorkItem?: { id: string } } | undefined)\n ?.planmagnetCreateWorkItem?.id;\n navigate(\n id ? `/tasks/task-detail-page?taskId=${encodeURIComponent(id)}` : '/tasks/tasks-page'\n );\n } catch (e) {\n setSaveError(e instanceof Error ? e.message : 'The task could not be created.');\n }\n };\n\n return (\n <div className=\"space-y-6 p-6 max-w-4xl\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Create Task</h1>\n <p className=\"text-sm text-muted-foreground\">Add a new task to the project backlog.</p>\n </div>\n <div className=\"flex gap-2\">\n <Button variant=\"outline\" size=\"sm\" onClick={() => navigate('/tasks/tasks-page')}>\n <X className=\"mr-1 h-4 w-4\" />\n Cancel\n </Button>\n <Button\n size=\"sm\"\n onClick={handleCreate}\n disabled={saving || !form.title.trim() || !selectedProjectId || storyPoints.invalid}\n >\n <Save className=\"mr-1 h-4 w-4\" />\n {saving ? 'Creating...' : 'Create Task'}\n </Button>\n </div>\n </div>\n {saveError && (\n <div role=\"alert\" className=\"p-3 bg-destructive/10 text-destructive rounded-md text-sm\">\n {saveError}\n </div>\n )}\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <CheckSquare className=\"h-4 w-4\" />\n Task Details\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <label className=\"text-sm font-medium\">Title</label>\n <Input\n value={form.title}\n onChange={(e) => setForm({ ...form, title: e.target.value })}\n className=\"mt-1\"\n placeholder=\"e.g. Implement search query parser\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Description</label>\n <textarea\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[100px]\"\n value={form.description}\n onChange={(e) => setForm({ ...form, description: e.target.value })}\n placeholder=\"Describe the task requirements...\"\n />\n </div>\n <div className=\"grid grid-cols-3 gap-4\">\n <div>\n <label className=\"text-sm font-medium\">Project</label>\n <select\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm\"\n value={selectedProjectId}\n onChange={(e) => setForm({ ...form, projectId: e.target.value })}\n >\n {projects.length === 0 && (\n <option value=\"\" disabled>\n {projectsLoading && !projectsData\n ? 'Loading projects…'\n : projectsError\n ? 'Projects could not be loaded'\n : 'No projects yet'}\n </option>\n )}\n {projects.map((p) => (\n <option key={p.id} value={p.id}>\n {p.key} — {p.name}\n </option>\n ))}\n </select>\n {/* C2 (BOFF-7833): loading, failure and \"no projects\" are told apart. */}\n {projectsError && (\n <p role=\"alert\" className=\"mt-1 flex items-center gap-2 text-xs text-destructive\">\n {projectsError.message}\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n className=\"h-6 px-2 text-xs\"\n onClick={() => void refetchProjects()}\n >\n Retry\n </Button>\n </p>\n )}\n {!projectsLoading && !projectsError && projectsData && projects.length === 0 && (\n <button\n type=\"button\"\n className=\"mt-1 text-xs text-muted-foreground underline\"\n onClick={() => navigate('/projects/create-project-page')}\n >\n Create a project first\n </button>\n )}\n </div>\n <div>\n <label className=\"text-sm font-medium\">Priority</label>\n <select\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm\"\n value={form.priority}\n onChange={(e) => setForm({ ...form, priority: e.target.value })}\n >\n {['LOW', 'MEDIUM', 'HIGH', 'CRITICAL'].map((p) => (\n <option key={p} value={p}>\n {p.toLowerCase()}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label className=\"text-sm font-medium\">Type</label>\n <select\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm\"\n value={form.type}\n onChange={(e) => setForm({ ...form, type: e.target.value })}\n >\n {['STORY', 'BUG', 'TASK', 'EPIC', 'SUB_TASK'].map((t) => (\n <option key={t} value={t}>\n {t.toLowerCase().replace('_', ' ')}\n </option>\n ))}\n </select>\n </div>\n </div>\n <div className=\"grid grid-cols-3 gap-4\">\n <div>\n <label htmlFor=\"task-story-points\" className=\"text-sm font-medium\">\n Story Points\n </label>\n <Input\n id=\"task-story-points\"\n type=\"number\"\n min={0}\n step={1}\n value={form.storyPoints}\n onChange={(e) => setForm({ ...form, storyPoints: e.target.value })}\n aria-invalid={storyPoints.invalid}\n className=\"mt-1\"\n />\n {storyPoints.invalid && (\n <p role=\"alert\" className=\"mt-1 text-xs text-destructive\">\n Story points must be a whole number, 0 or more.\n </p>\n )}\n </div>\n <div>\n <label className=\"text-sm font-medium\">Sprint ID</label>\n <Input\n value={form.sprintId}\n onChange={(e) => setForm({ ...form, sprintId: e.target.value })}\n className=\"mt-1\"\n placeholder=\"Sprint ID\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Due Date</label>\n <Input\n type=\"date\"\n value={form.dueDate}\n onChange={(e) => setForm({ ...form, dueDate: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n </div>\n <div>\n <label className=\"text-sm font-medium\">Labels (comma-separated)</label>\n <Input\n value={form.labels}\n onChange={(e) => setForm({ ...form, labels: e.target.value })}\n className=\"mt-1\"\n placeholder=\"backend, search, performance\"\n />\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TasksCreateTaskPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/TasksCreateTaskPagePage.tsx"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation, useQuery } from '@apollo/client/react';\nimport { Card, CardContent, CardHeader, CardTitle, Button, Input } from '@burdenoff/fe-libs/ui';\nimport { Save, X, CheckSquare } from 'lucide-react';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { throwOnError } from '../utils/mutationResult';\nimport { parseIntField } from '../utils/formValidation';\nimport { AssigneeSelect } from '../controls/WorkItemControls';\n\ninterface PlanmagnetProjectOption {\n id: string;\n name: string;\n key: string;\n}\n\nconst CREATE_WORK_ITEM = gql`\n mutation CreateWorkItem($input: PlanmagnetCreateWorkItemInput!) {\n planmagnetCreateWorkItem(input: $input) {\n id\n title\n type\n status\n priority\n key\n storyPoints\n dueDate\n labels\n sprintId\n createdAt\n }\n }\n`;\n\n// BOFF-4442/4443 live-verify fix: a WorkItem must belong to a real project\n// (PlanmagnetCreateWorkItemInput.projectId is non-null); the form needs the\n// caller's actual projects to choose from rather than a free-text name.\nconst GET_PROJECTS = gql`\n query GetProjectsForTaskCreate($workspaceId: ID!) {\n planmagnetProjects(workspaceId: $workspaceId, pagination: { first: 100 }) {\n items {\n id\n name\n key\n }\n }\n }\n`;\n\n// Sprints of the chosen project that can still take work (BOFF-7962: this was a free-text \"Sprint ID\" box — the id\n// was only discoverable from a sprint URL, and a name or another project's id was refused).\nconst GET_SPRINTS = gql`\n query GetSprintsForTaskCreate($workspaceId: ID!, $projectId: String) {\n planmagnetSprints(\n workspaceId: $workspaceId\n filter: { projectId: $projectId }\n pagination: { first: 100 }\n ) {\n items {\n id\n name\n status\n }\n }\n }\n`;\nconst OPEN_SPRINT_STATUSES = new Set(['PLANNING', 'ACTIVE', 'REVIEW']);\n\nexport function TasksCreateTaskPagePage() {\n const { workspaceId } = usePlanMagnet();\n const [form, setForm] = useState({\n title: '',\n description: '',\n projectId: '',\n priority: 'MEDIUM',\n type: 'STORY',\n storyPoints: '5',\n labels: '',\n sprintId: '',\n assigneeId: '',\n dueDate: '',\n });\n\n const {\n data: projectsData,\n loading: projectsLoading,\n error: projectsError,\n refetch: refetchProjects,\n } = useQuery<{ planmagnetProjects?: { items: PlanmagnetProjectOption[] } }>(GET_PROJECTS, {\n variables: { workspaceId: workspaceId ?? 'default' },\n skip: !workspaceId,\n });\n const projects: PlanmagnetProjectOption[] = projectsData?.planmagnetProjects?.items ?? [];\n // Fall back to the first loaded project when the user hasn't picked one\n // yet, without stashing derived state in an effect (avoids the extra\n // render cycle and keeps a single source of truth: `projects`).\n const selectedProjectId = form.projectId || projects[0]?.id || '';\n const { data: sprintsData, loading: sprintsLoading } = useQuery<{\n planmagnetSprints?: { items: { id: string; name: string; status: string }[] };\n }>(GET_SPRINTS, {\n variables: { workspaceId: workspaceId ?? 'default', projectId: selectedProjectId },\n skip: !workspaceId || !selectedProjectId,\n });\n const openSprints = (sprintsData?.planmagnetSprints?.items ?? []).filter((s) =>\n OPEN_SPRINT_STATUSES.has(s.status)\n );\n\n const navigate = usePlanMagnetNavigate();\n const [createWorkItem, { loading: saving }] = useMutation(CREATE_WORK_ITEM, {\n refetchQueries: ['GetWorkItems'],\n });\n const [saveError, setSaveError] = useState<string | null>(null);\n // Story points are a whole number, 0 or more (BOFF-7833: prod accepted -3).\n const storyPoints = parseIntField(form.storyPoints, { min: 0 });\n\n const handleCreate = async () => {\n if (!form.title.trim() || !selectedProjectId || !workspaceId || storyPoints.invalid) return;\n setSaveError(null);\n // Success opens the new task; a refusal shows the service's reason (errorPolicy 'all' resolves refused\n // mutations, so the old code showed nothing either way).\n try {\n const result = await throwOnError(\n createWorkItem({\n variables: {\n input: {\n projectId: selectedProjectId,\n title: form.title,\n description: form.description || undefined,\n type: form.type,\n priority: form.priority,\n storyPoints: storyPoints.value,\n labels: form.labels\n ? form.labels\n .split(',')\n .map((l) => l.trim())\n .filter(Boolean)\n : undefined,\n sprintId: form.sprintId || undefined,\n assigneeId: form.assigneeId || undefined,\n dueDate: form.dueDate || undefined,\n },\n },\n })\n );\n const id = (result.data as { planmagnetCreateWorkItem?: { id: string } } | undefined)\n ?.planmagnetCreateWorkItem?.id;\n navigate(\n id ? `/tasks/task-detail-page?taskId=${encodeURIComponent(id)}` : '/tasks/tasks-page'\n );\n } catch (e) {\n setSaveError(e instanceof Error ? e.message : 'The task could not be created.');\n }\n };\n\n return (\n <div className=\"space-y-6 p-6 max-w-4xl\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Create Task</h1>\n <p className=\"text-sm text-muted-foreground\">Add a new task to the project backlog.</p>\n </div>\n <div className=\"flex gap-2\">\n <Button variant=\"outline\" size=\"sm\" onClick={() => navigate('/tasks/tasks-page')}>\n <X className=\"mr-1 h-4 w-4\" />\n Cancel\n </Button>\n <Button\n size=\"sm\"\n onClick={handleCreate}\n disabled={saving || !form.title.trim() || !selectedProjectId || storyPoints.invalid}\n >\n <Save className=\"mr-1 h-4 w-4\" />\n {saving ? 'Creating...' : 'Create Task'}\n </Button>\n </div>\n </div>\n {saveError && (\n <div role=\"alert\" className=\"p-3 bg-destructive/10 text-destructive rounded-md text-sm\">\n {saveError}\n </div>\n )}\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <CheckSquare className=\"h-4 w-4\" />\n Task Details\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <label className=\"text-sm font-medium\">Title</label>\n <Input\n value={form.title}\n onChange={(e) => setForm({ ...form, title: e.target.value })}\n className=\"mt-1\"\n placeholder=\"e.g. Implement search query parser\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Description</label>\n <textarea\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[100px]\"\n value={form.description}\n onChange={(e) => setForm({ ...form, description: e.target.value })}\n placeholder=\"Describe the task requirements...\"\n />\n </div>\n <div className=\"grid grid-cols-3 gap-4\">\n <div>\n <label className=\"text-sm font-medium\">Project</label>\n <select\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm\"\n value={selectedProjectId}\n // A sprint belongs to one project: changing the project clears the chosen sprint.\n onChange={(e) => setForm({ ...form, projectId: e.target.value, sprintId: '' })}\n >\n {projects.length === 0 && (\n <option value=\"\" disabled>\n {projectsLoading && !projectsData\n ? 'Loading projects…'\n : projectsError\n ? 'Projects could not be loaded'\n : 'No projects yet'}\n </option>\n )}\n {projects.map((p) => (\n <option key={p.id} value={p.id}>\n {p.key} — {p.name}\n </option>\n ))}\n </select>\n {/* C2 (BOFF-7833): loading, failure and \"no projects\" are told apart. */}\n {projectsError && (\n <p role=\"alert\" className=\"mt-1 flex items-center gap-2 text-xs text-destructive\">\n {projectsError.message}\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"ghost\"\n className=\"h-6 px-2 text-xs\"\n onClick={() => void refetchProjects()}\n >\n Retry\n </Button>\n </p>\n )}\n {!projectsLoading && !projectsError && projectsData && projects.length === 0 && (\n <button\n type=\"button\"\n className=\"mt-1 text-xs text-muted-foreground underline\"\n onClick={() => navigate('/projects/create-project-page')}\n >\n Create a project first\n </button>\n )}\n </div>\n <div>\n <label className=\"text-sm font-medium\">Priority</label>\n <select\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm\"\n value={form.priority}\n onChange={(e) => setForm({ ...form, priority: e.target.value })}\n >\n {['LOW', 'MEDIUM', 'HIGH', 'CRITICAL'].map((p) => (\n <option key={p} value={p}>\n {p.toLowerCase()}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label className=\"text-sm font-medium\">Type</label>\n <select\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm\"\n value={form.type}\n onChange={(e) => setForm({ ...form, type: e.target.value })}\n >\n {['STORY', 'BUG', 'TASK', 'EPIC', 'SUB_TASK'].map((t) => (\n <option key={t} value={t}>\n {t.toLowerCase().replace('_', ' ')}\n </option>\n ))}\n </select>\n </div>\n </div>\n <div className=\"grid grid-cols-3 gap-4\">\n <div>\n <label htmlFor=\"task-story-points\" className=\"text-sm font-medium\">\n Story Points\n </label>\n <Input\n id=\"task-story-points\"\n type=\"number\"\n min={0}\n step={1}\n value={form.storyPoints}\n onChange={(e) => setForm({ ...form, storyPoints: e.target.value })}\n aria-invalid={storyPoints.invalid}\n className=\"mt-1\"\n />\n {storyPoints.invalid && (\n <p role=\"alert\" className=\"mt-1 text-xs text-destructive\">\n Story points must be a whole number, 0 or more.\n </p>\n )}\n </div>\n <div>\n <label htmlFor=\"task-sprint\" className=\"text-sm font-medium\">\n Sprint\n </label>\n <select\n id=\"task-sprint\"\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm\"\n value={form.sprintId}\n onChange={(e) => setForm({ ...form, sprintId: e.target.value })}\n >\n <option value=\"\">\n {sprintsLoading && !sprintsData ? 'Loading sprints…' : 'No sprint'}\n </option>\n {openSprints.map((s) => (\n <option key={s.id} value={s.id}>\n {s.name} ({s.status.toLowerCase()})\n </option>\n ))}\n </select>\n </div>\n <div>\n <label className=\"text-sm font-medium\">Due Date</label>\n <Input\n type=\"date\"\n value={form.dueDate}\n onChange={(e) => setForm({ ...form, dueDate: e.target.value })}\n className=\"mt-1\"\n />\n </div>\n </div>\n <div>\n <label htmlFor=\"task-assignee\" className=\"text-sm font-medium\">\n Assignee\n </label>\n <div className=\"mt-1\">\n <AssigneeSelect\n id=\"task-assignee\"\n value={form.assigneeId}\n onChange={(assigneeId) => setForm({ ...form, assigneeId })}\n />\n </div>\n </div>\n <div>\n <label className=\"text-sm font-medium\">Labels (comma-separated)</label>\n <Input\n value={form.labels}\n onChange={(e) => setForm({ ...form, labels: e.target.value })}\n className=\"mt-1\"\n placeholder=\"backend, search, performance\"\n />\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TasksTaskDetailPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/TasksTaskDetailPagePage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TasksTaskDetailPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/TasksTaskDetailPagePage.tsx"],"names":[],"mappings":"AA8RA,wBAAgB,uBAAuB,4CAuItC"}
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { usePlanMagnet as e, usePlanMagnetNavigate as t } from "../providers/PlanMagnetProvider.js";
|
|
2
2
|
import { PersonName as n } from "../people/People.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
3
|
+
import { throwOnError as r } from "../utils/mutationResult.js";
|
|
4
|
+
import { MarkdownEditor as i } from "../../components/MarkdownEditor.js";
|
|
5
|
+
import { WORK_ITEM_PRIORITIES as a, WORK_ITEM_STATUSES as o, WorkItemAssigneeSelect as s, WorkItemEnumSelect as c, WorkItemHeaderActions as l } from "../controls/WorkItemControls.js";
|
|
6
|
+
import { WorkItemComments as u } from "../comments/WorkItemComments.js";
|
|
7
|
+
import { WorkItemActivity as d } from "../comments/WorkItemActivity.js";
|
|
8
|
+
import { useState as f } from "react";
|
|
9
|
+
import { FileText as p, Plus as m, X as h } from "lucide-react";
|
|
10
|
+
import { gql as g } from "@apollo/client";
|
|
11
|
+
import { useMutation as _, useQuery as v } from "@apollo/client/react";
|
|
12
|
+
import { jsx as y, jsxs as b } from "react/jsx-runtime";
|
|
13
|
+
import { Badge as x, Button as S, Card as C, CardContent as w, CardHeader as T, CardTitle as E, Input as D } from "@burdenoff/fe-libs/ui";
|
|
13
14
|
//#region src/planmagnet/pages/TasksTaskDetailPagePage.tsx
|
|
14
|
-
var
|
|
15
|
+
var O = g`
|
|
15
16
|
query GetWorkItemDetail($workItemId: ID!) {
|
|
16
17
|
planmagnetWorkItem(id: $workItemId) {
|
|
17
18
|
id
|
|
@@ -34,7 +35,7 @@ var C = d`
|
|
|
34
35
|
updatedAt
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
|
-
`,
|
|
38
|
+
`, k = g`
|
|
38
39
|
query GetWorkItemDocs($workItemId: ID!) {
|
|
39
40
|
planmagnetWorkItemDocs(workItemId: $workItemId) {
|
|
40
41
|
id
|
|
@@ -44,54 +45,40 @@ var C = d`
|
|
|
44
45
|
updatedAt
|
|
45
46
|
}
|
|
46
47
|
}
|
|
47
|
-
`,
|
|
48
|
+
`, A = g`
|
|
48
49
|
mutation CreateDocForWorkItem($input: PlanmagnetCreateDocInput!) {
|
|
49
50
|
planmagnetCreateDoc(input: $input) {
|
|
50
51
|
id
|
|
51
52
|
}
|
|
52
53
|
}
|
|
53
|
-
`,
|
|
54
|
+
`, j = g`
|
|
54
55
|
mutation LinkDocToWorkItem($docId: ID!, $workItemId: ID!) {
|
|
55
56
|
planmagnetLinkDocToWorkItem(docId: $docId, workItemId: $workItemId) {
|
|
56
57
|
id
|
|
57
58
|
}
|
|
58
59
|
}
|
|
59
|
-
`,
|
|
60
|
+
`, M = g`
|
|
60
61
|
mutation UnlinkDocFromWorkItem($docId: ID!, $workItemId: ID!) {
|
|
61
62
|
planmagnetUnlinkDocFromWorkItem(docId: $docId, workItemId: $workItemId)
|
|
62
63
|
}
|
|
63
|
-
`,
|
|
64
|
-
LOW: "bg-gray-100 text-gray-800",
|
|
65
|
-
MEDIUM: "bg-blue-100 text-blue-800",
|
|
66
|
-
HIGH: "bg-orange-100 text-orange-800",
|
|
67
|
-
CRITICAL: "bg-red-100 text-red-800"
|
|
68
|
-
}, k = {
|
|
69
|
-
BACKLOG: "bg-gray-100 text-gray-800",
|
|
70
|
-
TODO: "bg-blue-100 text-blue-800",
|
|
71
|
-
IN_PROGRESS: "bg-yellow-100 text-yellow-800",
|
|
72
|
-
IN_REVIEW: "bg-purple-100 text-purple-800",
|
|
73
|
-
DONE: "bg-green-100 text-green-800",
|
|
74
|
-
BLOCKED: "bg-red-100 text-red-800",
|
|
75
|
-
TESTING: "bg-teal-100 text-teal-800",
|
|
76
|
-
CANCELLED: "bg-gray-100 text-gray-800"
|
|
77
|
-
}, A = {
|
|
64
|
+
`, N = {
|
|
78
65
|
DRAFT: "bg-gray-100 text-gray-800",
|
|
79
66
|
PUBLISHED: "bg-green-100 text-green-800",
|
|
80
67
|
ARCHIVED: "bg-gray-100 text-gray-500"
|
|
81
68
|
};
|
|
82
|
-
function
|
|
83
|
-
let n = t(), [a, o] =
|
|
69
|
+
function P({ workItemId: e }) {
|
|
70
|
+
let n = t(), [a, o] = f(!1), [s, c] = f(""), [l, u] = f(""), { data: d, loading: g, error: x, refetch: O } = v(k, {
|
|
84
71
|
variables: { workItemId: e },
|
|
85
72
|
skip: !e
|
|
86
|
-
}), [P, { loading: F }] =
|
|
87
|
-
if (!(!
|
|
73
|
+
}), [P, { loading: F }] = _(A), [I] = _(j), [L, { loading: R }] = _(M), [z, B] = f(null), V = d?.planmagnetWorkItemDocs ?? [], H = async () => {
|
|
74
|
+
if (!(!s.trim() || !l.trim())) {
|
|
88
75
|
B(null);
|
|
89
76
|
try {
|
|
90
|
-
let t = (await
|
|
91
|
-
title:
|
|
92
|
-
content:
|
|
77
|
+
let t = (await r(P({ variables: { input: {
|
|
78
|
+
title: s.trim(),
|
|
79
|
+
content: l.trim()
|
|
93
80
|
} } }))).data?.planmagnetCreateDoc?.id;
|
|
94
|
-
t && await
|
|
81
|
+
t && await r(I({ variables: {
|
|
95
82
|
docId: t,
|
|
96
83
|
workItemId: e
|
|
97
84
|
} }));
|
|
@@ -99,12 +86,12 @@ function j({ workItemId: e }) {
|
|
|
99
86
|
B(e instanceof Error ? e.message : "The doc could not be saved.");
|
|
100
87
|
return;
|
|
101
88
|
}
|
|
102
|
-
|
|
89
|
+
c(""), u(""), o(!1), O();
|
|
103
90
|
}
|
|
104
91
|
}, U = async (t) => {
|
|
105
92
|
B(null);
|
|
106
93
|
try {
|
|
107
|
-
await
|
|
94
|
+
await r(L({ variables: {
|
|
108
95
|
docId: t,
|
|
109
96
|
workItemId: e
|
|
110
97
|
} }));
|
|
@@ -112,240 +99,250 @@ function j({ workItemId: e }) {
|
|
|
112
99
|
B(e instanceof Error ? e.message : "The doc could not be unlinked.");
|
|
113
100
|
return;
|
|
114
101
|
}
|
|
115
|
-
|
|
102
|
+
O();
|
|
116
103
|
};
|
|
117
|
-
return /* @__PURE__ */
|
|
104
|
+
return /* @__PURE__ */ b(C, { children: [/* @__PURE__ */ b(T, {
|
|
118
105
|
className: "flex flex-row items-center justify-between space-y-0",
|
|
119
|
-
children: [/* @__PURE__ */
|
|
106
|
+
children: [/* @__PURE__ */ y(E, { children: "Linked Docs" }), !a && /* @__PURE__ */ b(S, {
|
|
120
107
|
size: "sm",
|
|
121
108
|
variant: "outline",
|
|
122
109
|
onClick: () => o(!0),
|
|
123
|
-
children: [/* @__PURE__ */ m
|
|
110
|
+
children: [/* @__PURE__ */ y(m, { className: "h-4 w-4 mr-1" }), "New Doc"]
|
|
124
111
|
})]
|
|
125
|
-
}), /* @__PURE__ */
|
|
112
|
+
}), /* @__PURE__ */ b(w, {
|
|
126
113
|
className: "space-y-4",
|
|
127
114
|
children: [
|
|
128
|
-
a && /* @__PURE__ */
|
|
115
|
+
a && /* @__PURE__ */ b("div", {
|
|
129
116
|
className: "space-y-3 rounded-md border border-input p-3",
|
|
130
117
|
children: [
|
|
131
|
-
/* @__PURE__ */
|
|
118
|
+
/* @__PURE__ */ y(D, {
|
|
132
119
|
placeholder: "Doc title",
|
|
133
|
-
value:
|
|
134
|
-
onChange: (e) =>
|
|
120
|
+
value: s,
|
|
121
|
+
onChange: (e) => c(e.target.value)
|
|
135
122
|
}),
|
|
136
|
-
/* @__PURE__ */
|
|
137
|
-
value:
|
|
138
|
-
onChange:
|
|
123
|
+
/* @__PURE__ */ y(i, {
|
|
124
|
+
value: l,
|
|
125
|
+
onChange: u,
|
|
139
126
|
placeholder: "Write the spec/doc content...",
|
|
140
127
|
minHeight: 140
|
|
141
128
|
}),
|
|
142
|
-
/* @__PURE__ */
|
|
129
|
+
/* @__PURE__ */ b("div", {
|
|
143
130
|
className: "flex gap-2 justify-end",
|
|
144
|
-
children: [/* @__PURE__ */
|
|
131
|
+
children: [/* @__PURE__ */ y(S, {
|
|
145
132
|
size: "sm",
|
|
146
133
|
variant: "ghost",
|
|
147
134
|
onClick: () => {
|
|
148
|
-
o(!1),
|
|
135
|
+
o(!1), c(""), u("");
|
|
149
136
|
},
|
|
150
137
|
children: "Cancel"
|
|
151
|
-
}), /* @__PURE__ */
|
|
138
|
+
}), /* @__PURE__ */ y(S, {
|
|
152
139
|
size: "sm",
|
|
153
|
-
disabled: F || !
|
|
140
|
+
disabled: F || !s.trim() || !l.trim(),
|
|
154
141
|
onClick: H,
|
|
155
142
|
children: F ? "Creating..." : "Create & Link"
|
|
156
143
|
})]
|
|
157
144
|
})
|
|
158
145
|
]
|
|
159
146
|
}),
|
|
160
|
-
|
|
147
|
+
g && /* @__PURE__ */ y("p", {
|
|
161
148
|
className: "text-sm text-muted-foreground",
|
|
162
149
|
children: "Loading docs..."
|
|
163
150
|
}),
|
|
164
|
-
|
|
151
|
+
x && /* @__PURE__ */ b("p", {
|
|
165
152
|
className: "text-sm text-red-500",
|
|
166
|
-
children: ["Error: ",
|
|
153
|
+
children: ["Error: ", x.message]
|
|
167
154
|
}),
|
|
168
|
-
z && /* @__PURE__ */
|
|
155
|
+
z && /* @__PURE__ */ y("p", {
|
|
169
156
|
role: "alert",
|
|
170
157
|
className: "text-sm text-destructive",
|
|
171
158
|
children: z
|
|
172
159
|
}),
|
|
173
|
-
!
|
|
160
|
+
!g && !x && V.length === 0 && !a && /* @__PURE__ */ y("p", {
|
|
174
161
|
className: "text-sm text-muted-foreground",
|
|
175
162
|
children: "No docs linked to this work item yet."
|
|
176
163
|
}),
|
|
177
|
-
V.map((e) => /* @__PURE__ */
|
|
164
|
+
V.map((e) => /* @__PURE__ */ b("div", {
|
|
178
165
|
className: "flex items-center justify-between gap-3 rounded-md border border-input p-3",
|
|
179
|
-
children: [/* @__PURE__ */
|
|
166
|
+
children: [/* @__PURE__ */ b("div", {
|
|
180
167
|
className: "flex items-center gap-2 min-w-0",
|
|
181
|
-
children: [/* @__PURE__ */
|
|
168
|
+
children: [/* @__PURE__ */ y(p, { className: "h-4 w-4 text-muted-foreground shrink-0" }), /* @__PURE__ */ b("div", {
|
|
182
169
|
className: "min-w-0",
|
|
183
|
-
children: [/* @__PURE__ */
|
|
170
|
+
children: [/* @__PURE__ */ y("button", {
|
|
184
171
|
type: "button",
|
|
185
172
|
className: "block max-w-full truncate text-left text-sm font-medium hover:underline",
|
|
186
173
|
onClick: () => n(`/docs/doc-detail-page?docId=${encodeURIComponent(e.id)}`),
|
|
187
174
|
children: e.title
|
|
188
|
-
}), /* @__PURE__ */
|
|
175
|
+
}), /* @__PURE__ */ b("p", {
|
|
189
176
|
className: "text-xs text-muted-foreground",
|
|
190
177
|
children: ["v", e.version]
|
|
191
178
|
})]
|
|
192
179
|
})]
|
|
193
|
-
}), /* @__PURE__ */
|
|
180
|
+
}), /* @__PURE__ */ b("div", {
|
|
194
181
|
className: "flex items-center gap-2 shrink-0",
|
|
195
|
-
children: [/* @__PURE__ */
|
|
196
|
-
className: `text-xs px-2 py-0.5 rounded-full capitalize ${
|
|
182
|
+
children: [/* @__PURE__ */ y("span", {
|
|
183
|
+
className: `text-xs px-2 py-0.5 rounded-full capitalize ${N[e.status] ?? ""}`,
|
|
197
184
|
children: e.status.toLowerCase()
|
|
198
|
-
}), /* @__PURE__ */
|
|
185
|
+
}), /* @__PURE__ */ y(S, {
|
|
199
186
|
size: "icon",
|
|
200
187
|
variant: "ghost",
|
|
201
188
|
disabled: R,
|
|
202
189
|
onClick: () => U(e.id),
|
|
203
190
|
"aria-label": `Unlink ${e.title}`,
|
|
204
|
-
children: /* @__PURE__ */
|
|
191
|
+
children: /* @__PURE__ */ y(h, { className: "h-4 w-4" })
|
|
205
192
|
})]
|
|
206
193
|
})]
|
|
207
194
|
}, e.id))
|
|
208
195
|
]
|
|
209
196
|
})] });
|
|
210
197
|
}
|
|
211
|
-
function
|
|
212
|
-
let { workspaceId: t } = e(), r = new URLSearchParams(window.location.search).get("taskId") ?? "", { data: i, loading:
|
|
198
|
+
function F() {
|
|
199
|
+
let { workspaceId: t } = e(), r = new URLSearchParams(window.location.search).get("taskId") ?? "", { data: i, loading: f, error: p } = v(O, {
|
|
213
200
|
variables: { workItemId: r },
|
|
214
201
|
skip: !t || !r
|
|
215
202
|
});
|
|
216
|
-
if (
|
|
203
|
+
if (f && !i) return /* @__PURE__ */ y("div", {
|
|
217
204
|
className: "flex items-center justify-center p-12",
|
|
218
|
-
children: /* @__PURE__ */
|
|
205
|
+
children: /* @__PURE__ */ y("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
|
|
219
206
|
});
|
|
220
|
-
if (
|
|
207
|
+
if (p) return /* @__PURE__ */ b("div", {
|
|
221
208
|
className: "p-6 text-red-500",
|
|
222
|
-
children: ["Error: ",
|
|
209
|
+
children: ["Error: ", p.message]
|
|
223
210
|
});
|
|
224
|
-
let
|
|
225
|
-
|
|
226
|
-
className: "p-6 text-muted-foreground",
|
|
227
|
-
children: "Task not found."
|
|
228
|
-
});
|
|
229
|
-
let u = l.status.toLowerCase().replace("_", " ");
|
|
230
|
-
return /* @__PURE__ */ h("div", {
|
|
211
|
+
let m = i?.planmagnetWorkItem;
|
|
212
|
+
return m ? /* @__PURE__ */ b("div", {
|
|
231
213
|
className: "space-y-6 p-6",
|
|
232
|
-
children: [/* @__PURE__ */
|
|
233
|
-
className: "
|
|
234
|
-
children:
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
214
|
+
children: [/* @__PURE__ */ b("div", {
|
|
215
|
+
className: "flex items-start justify-between gap-4",
|
|
216
|
+
children: [/* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("h1", {
|
|
217
|
+
className: "text-2xl font-semibold",
|
|
218
|
+
children: m.title
|
|
219
|
+
}), /* @__PURE__ */ b("p", {
|
|
220
|
+
className: "text-sm text-muted-foreground",
|
|
221
|
+
children: [
|
|
222
|
+
m.key,
|
|
223
|
+
" · ",
|
|
224
|
+
m.type.toLowerCase()
|
|
225
|
+
]
|
|
226
|
+
})] }), /* @__PURE__ */ y(l, {
|
|
227
|
+
workItemId: m.id,
|
|
228
|
+
title: m.title
|
|
229
|
+
})]
|
|
230
|
+
}), /* @__PURE__ */ b("div", {
|
|
243
231
|
className: "grid grid-cols-1 lg:grid-cols-3 gap-6",
|
|
244
|
-
children: [/* @__PURE__ */
|
|
232
|
+
children: [/* @__PURE__ */ b("div", {
|
|
245
233
|
className: "lg:col-span-2 space-y-6",
|
|
246
234
|
children: [
|
|
247
|
-
/* @__PURE__ */
|
|
235
|
+
/* @__PURE__ */ b(C, { children: [/* @__PURE__ */ y(T, { children: /* @__PURE__ */ y(E, { children: "Description" }) }), /* @__PURE__ */ y(w, { children: /* @__PURE__ */ y("p", {
|
|
248
236
|
className: "text-sm",
|
|
249
|
-
children:
|
|
237
|
+
children: m.description ?? "No description provided."
|
|
250
238
|
}) })] }),
|
|
251
|
-
/* @__PURE__ */
|
|
252
|
-
/* @__PURE__ */
|
|
253
|
-
/* @__PURE__ */
|
|
239
|
+
/* @__PURE__ */ y(P, { workItemId: m.id }),
|
|
240
|
+
/* @__PURE__ */ y(u, { workItemId: m.id }),
|
|
241
|
+
/* @__PURE__ */ y(d, { workItemId: m.id })
|
|
254
242
|
]
|
|
255
|
-
}), /* @__PURE__ */
|
|
243
|
+
}), /* @__PURE__ */ y("div", {
|
|
256
244
|
className: "space-y-6",
|
|
257
|
-
children: /* @__PURE__ */
|
|
245
|
+
children: /* @__PURE__ */ b(C, { children: [/* @__PURE__ */ y(T, { children: /* @__PURE__ */ y(E, { children: "Details" }) }), /* @__PURE__ */ b(w, {
|
|
258
246
|
className: "space-y-3 text-sm",
|
|
259
247
|
children: [
|
|
260
|
-
/* @__PURE__ */
|
|
261
|
-
className: "flex justify-between",
|
|
262
|
-
children: [/* @__PURE__ */
|
|
248
|
+
/* @__PURE__ */ b("div", {
|
|
249
|
+
className: "flex items-start justify-between gap-2",
|
|
250
|
+
children: [/* @__PURE__ */ y("span", {
|
|
263
251
|
className: "text-muted-foreground",
|
|
264
252
|
children: "Status"
|
|
265
|
-
}), /* @__PURE__ */
|
|
266
|
-
|
|
267
|
-
|
|
253
|
+
}), /* @__PURE__ */ y(c, {
|
|
254
|
+
workItemId: m.id,
|
|
255
|
+
field: "status",
|
|
256
|
+
value: m.status,
|
|
257
|
+
options: o,
|
|
258
|
+
label: "Status"
|
|
268
259
|
})]
|
|
269
260
|
}),
|
|
270
|
-
/* @__PURE__ */
|
|
271
|
-
className: "flex justify-between",
|
|
272
|
-
children: [/* @__PURE__ */
|
|
261
|
+
/* @__PURE__ */ b("div", {
|
|
262
|
+
className: "flex items-start justify-between gap-2",
|
|
263
|
+
children: [/* @__PURE__ */ y("span", {
|
|
273
264
|
className: "text-muted-foreground",
|
|
274
265
|
children: "Priority"
|
|
275
|
-
}), /* @__PURE__ */
|
|
276
|
-
|
|
277
|
-
|
|
266
|
+
}), /* @__PURE__ */ y(c, {
|
|
267
|
+
workItemId: m.id,
|
|
268
|
+
field: "priority",
|
|
269
|
+
value: m.priority,
|
|
270
|
+
options: a,
|
|
271
|
+
label: "Priority"
|
|
278
272
|
})]
|
|
279
273
|
}),
|
|
280
|
-
/* @__PURE__ */
|
|
274
|
+
/* @__PURE__ */ b("div", {
|
|
281
275
|
className: "flex justify-between",
|
|
282
|
-
children: [/* @__PURE__ */
|
|
276
|
+
children: [/* @__PURE__ */ y("span", {
|
|
283
277
|
className: "text-muted-foreground",
|
|
284
278
|
children: "Type"
|
|
285
|
-
}), /* @__PURE__ */
|
|
279
|
+
}), /* @__PURE__ */ y(x, {
|
|
286
280
|
variant: "outline",
|
|
287
281
|
className: "capitalize",
|
|
288
|
-
children:
|
|
282
|
+
children: m.type.toLowerCase()
|
|
289
283
|
})]
|
|
290
284
|
}),
|
|
291
|
-
/* @__PURE__ */
|
|
285
|
+
/* @__PURE__ */ b("div", {
|
|
292
286
|
className: "flex justify-between",
|
|
293
|
-
children: [/* @__PURE__ */
|
|
287
|
+
children: [/* @__PURE__ */ y("span", {
|
|
294
288
|
className: "text-muted-foreground",
|
|
295
289
|
children: "Story Points"
|
|
296
|
-
}), /* @__PURE__ */
|
|
290
|
+
}), /* @__PURE__ */ y("span", {
|
|
297
291
|
className: "font-medium",
|
|
298
|
-
children:
|
|
292
|
+
children: m.storyPoints ?? 0
|
|
299
293
|
})]
|
|
300
294
|
}),
|
|
301
|
-
/* @__PURE__ */
|
|
302
|
-
className: "flex justify-between",
|
|
303
|
-
children: [/* @__PURE__ */
|
|
295
|
+
/* @__PURE__ */ b("div", {
|
|
296
|
+
className: "flex items-start justify-between gap-2",
|
|
297
|
+
children: [/* @__PURE__ */ y("span", {
|
|
304
298
|
className: "text-muted-foreground",
|
|
305
299
|
children: "Assignee"
|
|
306
|
-
}),
|
|
300
|
+
}), /* @__PURE__ */ y(s, {
|
|
301
|
+
workItemId: m.id,
|
|
302
|
+
assigneeId: m.assigneeId
|
|
303
|
+
})]
|
|
307
304
|
}),
|
|
308
|
-
/* @__PURE__ */
|
|
305
|
+
/* @__PURE__ */ b("div", {
|
|
309
306
|
className: "flex justify-between",
|
|
310
|
-
children: [/* @__PURE__ */
|
|
307
|
+
children: [/* @__PURE__ */ y("span", {
|
|
311
308
|
className: "text-muted-foreground",
|
|
312
309
|
children: "Reporter"
|
|
313
|
-
}), /* @__PURE__ */
|
|
310
|
+
}), /* @__PURE__ */ y(n, { id: m.reporterId ?? m.createdBy })]
|
|
314
311
|
}),
|
|
315
|
-
/* @__PURE__ */
|
|
312
|
+
/* @__PURE__ */ b("div", {
|
|
316
313
|
className: "flex justify-between",
|
|
317
|
-
children: [/* @__PURE__ */
|
|
314
|
+
children: [/* @__PURE__ */ y("span", {
|
|
318
315
|
className: "text-muted-foreground",
|
|
319
316
|
children: "Key"
|
|
320
|
-
}), /* @__PURE__ */
|
|
317
|
+
}), /* @__PURE__ */ y("span", { children: m.key })]
|
|
321
318
|
}),
|
|
322
|
-
/* @__PURE__ */
|
|
319
|
+
/* @__PURE__ */ b("div", {
|
|
323
320
|
className: "flex justify-between",
|
|
324
|
-
children: [/* @__PURE__ */
|
|
321
|
+
children: [/* @__PURE__ */ y("span", {
|
|
325
322
|
className: "text-muted-foreground",
|
|
326
323
|
children: "Due Date"
|
|
327
|
-
}), /* @__PURE__ */
|
|
324
|
+
}), /* @__PURE__ */ y("span", { children: m.dueDate ?? "Not set" })]
|
|
328
325
|
}),
|
|
329
|
-
/* @__PURE__ */
|
|
326
|
+
/* @__PURE__ */ b("div", {
|
|
330
327
|
className: "flex justify-between",
|
|
331
|
-
children: [/* @__PURE__ */
|
|
328
|
+
children: [/* @__PURE__ */ y("span", {
|
|
332
329
|
className: "text-muted-foreground",
|
|
333
330
|
children: "Created"
|
|
334
|
-
}), /* @__PURE__ */
|
|
331
|
+
}), /* @__PURE__ */ y("span", { children: m.createdAt })]
|
|
335
332
|
}),
|
|
336
|
-
/* @__PURE__ */
|
|
333
|
+
/* @__PURE__ */ b("div", {
|
|
337
334
|
className: "flex justify-between",
|
|
338
|
-
children: [/* @__PURE__ */
|
|
335
|
+
children: [/* @__PURE__ */ y("span", {
|
|
339
336
|
className: "text-muted-foreground",
|
|
340
337
|
children: "Updated"
|
|
341
|
-
}), /* @__PURE__ */
|
|
338
|
+
}), /* @__PURE__ */ y("span", { children: m.updatedAt })]
|
|
342
339
|
}),
|
|
343
|
-
/* @__PURE__ */
|
|
340
|
+
/* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("span", {
|
|
344
341
|
className: "text-muted-foreground text-xs",
|
|
345
342
|
children: "Labels"
|
|
346
|
-
}), /* @__PURE__ */
|
|
343
|
+
}), /* @__PURE__ */ y("div", {
|
|
347
344
|
className: "flex gap-1 mt-1 flex-wrap",
|
|
348
|
-
children: (
|
|
345
|
+
children: (m.labels ?? []).map((e) => /* @__PURE__ */ y("span", {
|
|
349
346
|
className: "text-xs px-2 py-0.5 rounded bg-muted",
|
|
350
347
|
children: e
|
|
351
348
|
}, e))
|
|
@@ -354,9 +351,12 @@ function M() {
|
|
|
354
351
|
})] })
|
|
355
352
|
})]
|
|
356
353
|
})]
|
|
354
|
+
}) : /* @__PURE__ */ y("div", {
|
|
355
|
+
className: "p-6 text-muted-foreground",
|
|
356
|
+
children: "Task not found."
|
|
357
357
|
});
|
|
358
358
|
}
|
|
359
359
|
//#endregion
|
|
360
|
-
export {
|
|
360
|
+
export { F as TasksTaskDetailPagePage };
|
|
361
361
|
|
|
362
362
|
//# sourceMappingURL=TasksTaskDetailPagePage.js.map
|