@burdenoff/planmagnet-fe-sdk 2026.703.2 → 2026.704.1
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/index.d.ts +404 -118
- package/dist/index.js +677 -138
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { createContext, useMemo, useEffect, useContext, useState, useCallback } from 'react';
|
|
2
|
-
import { ApolloProvider, useApolloClient, useMutation
|
|
2
|
+
import { ApolloProvider, useQuery, useApolloClient, useMutation } from '@apollo/client/react';
|
|
3
3
|
import { createHttpLink, ApolloClient, from, InMemoryCache } from '@apollo/client/core';
|
|
4
4
|
import { setContext } from '@apollo/client/link/context';
|
|
5
5
|
import { onError } from '@apollo/client/link/error';
|
|
6
6
|
import { CombinedGraphQLErrors } from '@apollo/client/errors';
|
|
7
7
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
8
8
|
import { gql } from '@apollo/client';
|
|
9
|
-
import { CircleX, CircleCheckBig, CircleDotDashed, CircleDot, Circle, CircleDashed, User, CalendarDays, ChevronUp, ChevronDown, ChevronLeft, ChevronRight, CalendarRange, List, LayoutGrid, Search, Plus } from 'lucide-react';
|
|
9
|
+
import { CircleX, CircleCheckBig, CircleDotDashed, CircleDot, Circle, CircleDashed, User, Link2, CalendarDays, ChevronUp, ChevronDown, ChevronLeft, ChevronRight, Flag, CalendarRange, List, LayoutGrid, Search, Plus, Trash2 } from 'lucide-react';
|
|
10
10
|
import { clsx } from 'clsx';
|
|
11
11
|
import { twMerge } from 'tailwind-merge';
|
|
12
12
|
import { addWeeks, startOfWeek, endOfWeek, eachDayOfInterval, addMonths, startOfMonth, endOfMonth, format, isToday, isSameMonth, startOfDay, parseISO, isValid } from 'date-fns';
|
|
@@ -410,6 +410,108 @@ var MOVE_WORK_ITEM = gql`
|
|
|
410
410
|
}
|
|
411
411
|
${WORK_ITEM_FIELDS}
|
|
412
412
|
`;
|
|
413
|
+
var WORK_ITEM_LINK_FIELDS = gql`
|
|
414
|
+
fragment WorkItemLinkFields on WorkItemLink {
|
|
415
|
+
id
|
|
416
|
+
workspaceId
|
|
417
|
+
workItemId
|
|
418
|
+
sourceProduct
|
|
419
|
+
entityType
|
|
420
|
+
entityId
|
|
421
|
+
relationType
|
|
422
|
+
displayNameSnapshot
|
|
423
|
+
deepLinkSnapshot
|
|
424
|
+
metadata
|
|
425
|
+
createdBy
|
|
426
|
+
onBehalfOf
|
|
427
|
+
createdAt
|
|
428
|
+
updatedAt
|
|
429
|
+
}
|
|
430
|
+
`;
|
|
431
|
+
var LIST_WORK_ITEM_LINKS = gql`
|
|
432
|
+
query ListWorkItemLinks(
|
|
433
|
+
$workspaceId: ID!
|
|
434
|
+
$filter: PlanmagnetWorkItemLinkFilter
|
|
435
|
+
$pagination: PlanmagnetPaginationInput
|
|
436
|
+
) {
|
|
437
|
+
planmagnetWorkItemLinks(
|
|
438
|
+
workspaceId: $workspaceId
|
|
439
|
+
filter: $filter
|
|
440
|
+
pagination: $pagination
|
|
441
|
+
) {
|
|
442
|
+
items {
|
|
443
|
+
...WorkItemLinkFields
|
|
444
|
+
}
|
|
445
|
+
pageInfo {
|
|
446
|
+
hasNextPage
|
|
447
|
+
hasPreviousPage
|
|
448
|
+
startCursor
|
|
449
|
+
endCursor
|
|
450
|
+
totalCount
|
|
451
|
+
}
|
|
452
|
+
totalCount
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
${WORK_ITEM_LINK_FIELDS}
|
|
456
|
+
`;
|
|
457
|
+
var CREATE_WORK_ITEM_LINK = gql`
|
|
458
|
+
mutation CreateWorkItemLink($input: PlanmagnetCreateWorkItemLinkInput!) {
|
|
459
|
+
planmagnetLinkWorkItem(input: $input) {
|
|
460
|
+
...WorkItemLinkFields
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
${WORK_ITEM_LINK_FIELDS}
|
|
464
|
+
`;
|
|
465
|
+
var DELETE_WORK_ITEM_LINK = gql`
|
|
466
|
+
mutation UnlinkWorkItem($id: ID!) {
|
|
467
|
+
planmagnetUnlinkWorkItem(id: $id)
|
|
468
|
+
}
|
|
469
|
+
`;
|
|
470
|
+
var MILESTONE_FIELDS = gql`
|
|
471
|
+
fragment MilestoneFields on Milestone {
|
|
472
|
+
id
|
|
473
|
+
projectId
|
|
474
|
+
name
|
|
475
|
+
description
|
|
476
|
+
status
|
|
477
|
+
dueDate
|
|
478
|
+
completedAt
|
|
479
|
+
ownerId
|
|
480
|
+
createdAt
|
|
481
|
+
updatedAt
|
|
482
|
+
}
|
|
483
|
+
`;
|
|
484
|
+
var LIST_MILESTONES = gql`
|
|
485
|
+
query ListMilestones(
|
|
486
|
+
$workspaceId: ID!
|
|
487
|
+
$filter: PlanmagnetMilestoneFilter
|
|
488
|
+
$pagination: PlanmagnetPaginationInput
|
|
489
|
+
) {
|
|
490
|
+
planmagnetMilestones(
|
|
491
|
+
workspaceId: $workspaceId
|
|
492
|
+
filter: $filter
|
|
493
|
+
pagination: $pagination
|
|
494
|
+
) {
|
|
495
|
+
items {
|
|
496
|
+
...MilestoneFields
|
|
497
|
+
}
|
|
498
|
+
pageInfo {
|
|
499
|
+
hasNextPage
|
|
500
|
+
hasPreviousPage
|
|
501
|
+
startCursor
|
|
502
|
+
endCursor
|
|
503
|
+
totalCount
|
|
504
|
+
}
|
|
505
|
+
totalCount
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
${MILESTONE_FIELDS}
|
|
509
|
+
`;
|
|
510
|
+
var DELETE_WORK_ITEM = gql`
|
|
511
|
+
mutation DeleteWorkItem($id: ID!) {
|
|
512
|
+
planmagnetDeleteWorkItem(id: $id)
|
|
513
|
+
}
|
|
514
|
+
`;
|
|
413
515
|
function cn(...inputs) {
|
|
414
516
|
return twMerge(clsx(inputs));
|
|
415
517
|
}
|
|
@@ -552,6 +654,141 @@ var TASK_STATUSES = [
|
|
|
552
654
|
function enumLabel(value) {
|
|
553
655
|
return value.toLowerCase().replace(/_/g, " ");
|
|
554
656
|
}
|
|
657
|
+
function LinkChip({ link, renderIcon, className }) {
|
|
658
|
+
const label = link.displayNameSnapshot || enumLabel(link.entityType);
|
|
659
|
+
const icon = renderIcon?.(link.entityType) ?? /* @__PURE__ */ jsx(Link2, { className: "h-3 w-3 shrink-0", "aria-hidden": "true" });
|
|
660
|
+
const body = /* @__PURE__ */ jsxs(
|
|
661
|
+
"span",
|
|
662
|
+
{
|
|
663
|
+
className: cn(
|
|
664
|
+
"inline-flex max-w-full items-center gap-1 rounded-full border border-primary/20 bg-primary/5 px-1.5 py-0.5 text-[10px] font-medium text-primary",
|
|
665
|
+
className
|
|
666
|
+
),
|
|
667
|
+
title: `${enumLabel(link.relationType)} \xB7 ${enumLabel(link.entityType)}`,
|
|
668
|
+
children: [
|
|
669
|
+
icon,
|
|
670
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: label })
|
|
671
|
+
]
|
|
672
|
+
}
|
|
673
|
+
);
|
|
674
|
+
if (link.deepLinkSnapshot) {
|
|
675
|
+
return /* @__PURE__ */ jsx(
|
|
676
|
+
"a",
|
|
677
|
+
{
|
|
678
|
+
href: link.deepLinkSnapshot,
|
|
679
|
+
onClick: (e) => e.stopPropagation(),
|
|
680
|
+
className: "inline-flex max-w-full no-underline hover:brightness-95",
|
|
681
|
+
children: body
|
|
682
|
+
}
|
|
683
|
+
);
|
|
684
|
+
}
|
|
685
|
+
return body;
|
|
686
|
+
}
|
|
687
|
+
var DEFAULT_TASK_LABELS = {
|
|
688
|
+
board: "Board",
|
|
689
|
+
list: "List",
|
|
690
|
+
timeline: "Timeline",
|
|
691
|
+
searchPlaceholder: "Search tasks\u2026",
|
|
692
|
+
allPriorities: "All priorities",
|
|
693
|
+
allTypes: "All types",
|
|
694
|
+
newTask: "New task",
|
|
695
|
+
myTasks: "My tasks",
|
|
696
|
+
noTasks: "No tasks",
|
|
697
|
+
noTasksFound: "No tasks found.",
|
|
698
|
+
dropHere: "Drop here",
|
|
699
|
+
unassigned: "Unassigned",
|
|
700
|
+
assigned: "Assigned",
|
|
701
|
+
overdue: "{n} overdue",
|
|
702
|
+
noDueDate: "No due date ({n})",
|
|
703
|
+
milestones: "Milestones",
|
|
704
|
+
today: "Today",
|
|
705
|
+
week: "Week",
|
|
706
|
+
month: "Month",
|
|
707
|
+
tasksSingular: "task",
|
|
708
|
+
tasksPlural: "tasks",
|
|
709
|
+
colTask: "Task",
|
|
710
|
+
colStatus: "Status",
|
|
711
|
+
colPriority: "Priority",
|
|
712
|
+
colAssignee: "Assignee",
|
|
713
|
+
colDueDate: "Due Date",
|
|
714
|
+
colPoints: "Points",
|
|
715
|
+
colLinkedRecord: "Linked Record",
|
|
716
|
+
colType: "Type",
|
|
717
|
+
colKey: "Key",
|
|
718
|
+
colLabels: "Labels",
|
|
719
|
+
newTaskHeading: "New task",
|
|
720
|
+
newTaskSubtitle: "Create a work item in this workspace.",
|
|
721
|
+
title: "Title",
|
|
722
|
+
titlePlaceholder: "What needs doing?",
|
|
723
|
+
description: "Description",
|
|
724
|
+
descriptionPlaceholder: "Add more detail (optional)",
|
|
725
|
+
typeLabel: "Type",
|
|
726
|
+
statusLabel: "Status",
|
|
727
|
+
priorityLabel: "Priority",
|
|
728
|
+
assigneeLabel: "Assignee",
|
|
729
|
+
assigneePlaceholder: "Actor ID (optional)",
|
|
730
|
+
dueDateLabel: "Due date",
|
|
731
|
+
storyPointsLabel: "Story points",
|
|
732
|
+
labelsLabel: "Labels",
|
|
733
|
+
labelsPlaceholder: "comma, separated, labels",
|
|
734
|
+
create: "Create task",
|
|
735
|
+
creating: "Creating\u2026",
|
|
736
|
+
cancel: "Cancel",
|
|
737
|
+
edit: "Edit",
|
|
738
|
+
del: "Delete",
|
|
739
|
+
deletePrompt: "Delete?",
|
|
740
|
+
yes: "Yes",
|
|
741
|
+
no: "No",
|
|
742
|
+
save: "Save changes",
|
|
743
|
+
saving: "Saving\u2026",
|
|
744
|
+
taskNotFound: "Task not found.",
|
|
745
|
+
projectRequired: "A projectId is required to create a task.",
|
|
746
|
+
errorLoading: "Error loading tasks",
|
|
747
|
+
moveFailed: "Couldn't move the task. Please try again.",
|
|
748
|
+
failedToCreate: "Failed to create task",
|
|
749
|
+
failedToSave: "Failed to save",
|
|
750
|
+
failedToDelete: "Failed to delete",
|
|
751
|
+
overdueLabel: "Overdue",
|
|
752
|
+
more: "more",
|
|
753
|
+
status: {
|
|
754
|
+
BACKLOG: "Backlog",
|
|
755
|
+
TODO: "To Do",
|
|
756
|
+
IN_PROGRESS: "In Progress",
|
|
757
|
+
IN_REVIEW: "In Review",
|
|
758
|
+
TESTING: "Testing",
|
|
759
|
+
DONE: "Done",
|
|
760
|
+
CANCELLED: "Cancelled"
|
|
761
|
+
},
|
|
762
|
+
priority: {
|
|
763
|
+
NONE: "None",
|
|
764
|
+
LOW: "Low",
|
|
765
|
+
MEDIUM: "Medium",
|
|
766
|
+
HIGH: "High",
|
|
767
|
+
CRITICAL: "Critical"
|
|
768
|
+
},
|
|
769
|
+
type: {
|
|
770
|
+
TASK: "Task",
|
|
771
|
+
STORY: "Story",
|
|
772
|
+
BUG: "Bug",
|
|
773
|
+
EPIC: "Epic",
|
|
774
|
+
SUB_TASK: "Sub Task"
|
|
775
|
+
}
|
|
776
|
+
};
|
|
777
|
+
var TaskLabelsContext = createContext(DEFAULT_TASK_LABELS);
|
|
778
|
+
var TaskLabelsProvider = TaskLabelsContext.Provider;
|
|
779
|
+
function useTaskLabels() {
|
|
780
|
+
return useContext(TaskLabelsContext);
|
|
781
|
+
}
|
|
782
|
+
function mergeTaskLabels(overrides) {
|
|
783
|
+
if (!overrides) return DEFAULT_TASK_LABELS;
|
|
784
|
+
return {
|
|
785
|
+
...DEFAULT_TASK_LABELS,
|
|
786
|
+
...overrides,
|
|
787
|
+
status: { ...DEFAULT_TASK_LABELS.status, ...overrides.status },
|
|
788
|
+
priority: { ...DEFAULT_TASK_LABELS.priority, ...overrides.priority },
|
|
789
|
+
type: { ...DEFAULT_TASK_LABELS.type, ...overrides.type }
|
|
790
|
+
};
|
|
791
|
+
}
|
|
555
792
|
var STATUS_META = {
|
|
556
793
|
BACKLOG: { icon: CircleDashed, tone: "text-muted-foreground/60" },
|
|
557
794
|
TODO: { icon: Circle, tone: "text-muted-foreground" },
|
|
@@ -573,6 +810,7 @@ function StatusIcon({ status, className }) {
|
|
|
573
810
|
);
|
|
574
811
|
}
|
|
575
812
|
function StatusPill({ status, className }) {
|
|
813
|
+
const L = useTaskLabels();
|
|
576
814
|
return /* @__PURE__ */ jsxs(
|
|
577
815
|
"span",
|
|
578
816
|
{
|
|
@@ -582,7 +820,7 @@ function StatusPill({ status, className }) {
|
|
|
582
820
|
),
|
|
583
821
|
children: [
|
|
584
822
|
/* @__PURE__ */ jsx(StatusIcon, { status }),
|
|
585
|
-
|
|
823
|
+
L.status[status]
|
|
586
824
|
]
|
|
587
825
|
}
|
|
588
826
|
);
|
|
@@ -600,12 +838,13 @@ function PriorityIndicator({
|
|
|
600
838
|
showLabel = false,
|
|
601
839
|
className
|
|
602
840
|
}) {
|
|
841
|
+
const L = useTaskLabels();
|
|
603
842
|
const meta = PRIORITY_META[priority] ?? PRIORITY_META.NONE;
|
|
604
843
|
return /* @__PURE__ */ jsxs(
|
|
605
844
|
"span",
|
|
606
845
|
{
|
|
607
846
|
className: cn("inline-flex items-center gap-1.5", meta.tone, className),
|
|
608
|
-
title:
|
|
847
|
+
title: `${L.priorityLabel}: ${L.priority[priority]}`,
|
|
609
848
|
children: [
|
|
610
849
|
/* @__PURE__ */ jsx("span", { className: "flex items-end gap-0.5", "aria-hidden": "true", children: BAR_HEIGHTS.map((h, i) => /* @__PURE__ */ jsx(
|
|
611
850
|
"span",
|
|
@@ -618,7 +857,7 @@ function PriorityIndicator({
|
|
|
618
857
|
},
|
|
619
858
|
h
|
|
620
859
|
)) }),
|
|
621
|
-
showLabel && /* @__PURE__ */ jsx("span", { className: "text-xs font-medium capitalize", children:
|
|
860
|
+
showLabel && /* @__PURE__ */ jsx("span", { className: "text-xs font-medium capitalize", children: L.priority[priority] })
|
|
622
861
|
]
|
|
623
862
|
}
|
|
624
863
|
);
|
|
@@ -631,7 +870,8 @@ var TYPE_VARIANT = {
|
|
|
631
870
|
SUB_TASK: "muted"
|
|
632
871
|
};
|
|
633
872
|
function TypeBadge({ type, className }) {
|
|
634
|
-
|
|
873
|
+
const L = useTaskLabels();
|
|
874
|
+
return /* @__PURE__ */ jsx(Badge, { variant: TYPE_VARIANT[type], className, children: L.type[type] });
|
|
635
875
|
}
|
|
636
876
|
function OverlayShell({
|
|
637
877
|
open,
|
|
@@ -705,12 +945,16 @@ function TaskCard({
|
|
|
705
945
|
onDragEnd,
|
|
706
946
|
dragging,
|
|
707
947
|
resolveAssignee,
|
|
948
|
+
links,
|
|
949
|
+
renderLinkIcon,
|
|
708
950
|
className
|
|
709
951
|
}) {
|
|
952
|
+
const L = useTaskLabels();
|
|
710
953
|
const overdue = isOverdue(task.dueDate, task.status);
|
|
711
954
|
const due = formatDueDate(task.dueDate);
|
|
712
955
|
const resolved = task.assigneeId ? resolveAssignee?.(task.assigneeId) : null;
|
|
713
956
|
const showTopRow = !hidden.has("key") || !hidden.has("type");
|
|
957
|
+
const showLinks = !hidden.has("links") && (links?.length ?? 0) > 0;
|
|
714
958
|
const showLabels = !hidden.has("labels") && (task.labels?.length ?? 0) > 0;
|
|
715
959
|
const showPriority = !hidden.has("priority");
|
|
716
960
|
const showPoints = !hidden.has("storyPoints") && task.storyPoints != null;
|
|
@@ -749,6 +993,13 @@ function TaskCard({
|
|
|
749
993
|
!hidden.has("type") && /* @__PURE__ */ jsx(TypeBadge, { type: task.type })
|
|
750
994
|
] }),
|
|
751
995
|
/* @__PURE__ */ jsx("p", { className: "line-clamp-2 text-sm font-medium leading-snug text-foreground", children: task.title }),
|
|
996
|
+
showLinks && /* @__PURE__ */ jsxs("div", { className: "mt-1.5 flex flex-wrap gap-1", children: [
|
|
997
|
+
links.slice(0, 3).map((link) => /* @__PURE__ */ jsx(LinkChip, { link, renderIcon: renderLinkIcon }, link.id)),
|
|
998
|
+
links.length > 3 && /* @__PURE__ */ jsxs("span", { className: "text-[10px] text-muted-foreground", children: [
|
|
999
|
+
"+",
|
|
1000
|
+
links.length - 3
|
|
1001
|
+
] })
|
|
1002
|
+
] }),
|
|
752
1003
|
showLabels && /* @__PURE__ */ jsxs("div", { className: "mt-1.5 flex flex-wrap gap-1", children: [
|
|
753
1004
|
task.labels.slice(0, 3).map((l) => /* @__PURE__ */ jsx(
|
|
754
1005
|
"span",
|
|
@@ -769,7 +1020,7 @@ function TaskCard({
|
|
|
769
1020
|
"span",
|
|
770
1021
|
{
|
|
771
1022
|
className: "flex h-5 min-w-5 items-center justify-center rounded-full bg-primary/10 px-1 text-[10px] font-semibold text-primary",
|
|
772
|
-
title: `${task.storyPoints}
|
|
1023
|
+
title: `${task.storyPoints} ${L.storyPointsLabel}`,
|
|
773
1024
|
children: task.storyPoints
|
|
774
1025
|
}
|
|
775
1026
|
)
|
|
@@ -786,7 +1037,7 @@ function TaskCard({
|
|
|
786
1037
|
"flex shrink-0 items-center gap-1 text-[11px]",
|
|
787
1038
|
overdue ? "font-medium text-destructive" : "text-muted-foreground"
|
|
788
1039
|
),
|
|
789
|
-
title: overdue ?
|
|
1040
|
+
title: overdue ? L.overdueLabel : L.dueDateLabel,
|
|
790
1041
|
children: [
|
|
791
1042
|
/* @__PURE__ */ jsx(CalendarDays, { className: "h-3 w-3", "aria-hidden": "true" }),
|
|
792
1043
|
due
|
|
@@ -798,6 +1049,29 @@ function TaskCard({
|
|
|
798
1049
|
}
|
|
799
1050
|
);
|
|
800
1051
|
}
|
|
1052
|
+
function useWorkItemLinks(workspaceId, sourceProduct, limit = 500) {
|
|
1053
|
+
const { data, loading } = useQuery(
|
|
1054
|
+
LIST_WORK_ITEM_LINKS,
|
|
1055
|
+
{
|
|
1056
|
+
variables: {
|
|
1057
|
+
workspaceId,
|
|
1058
|
+
...sourceProduct ? { filter: { sourceProduct } } : {},
|
|
1059
|
+
pagination: { first: limit }
|
|
1060
|
+
},
|
|
1061
|
+
skip: !workspaceId || !sourceProduct
|
|
1062
|
+
}
|
|
1063
|
+
);
|
|
1064
|
+
const linksByItem = useMemo(() => {
|
|
1065
|
+
const map = /* @__PURE__ */ new Map();
|
|
1066
|
+
for (const link of data?.planmagnetWorkItemLinks?.items ?? []) {
|
|
1067
|
+
const arr = map.get(link.workItemId);
|
|
1068
|
+
if (arr) arr.push(link);
|
|
1069
|
+
else map.set(link.workItemId, [link]);
|
|
1070
|
+
}
|
|
1071
|
+
return map;
|
|
1072
|
+
}, [data]);
|
|
1073
|
+
return { linksByItem, loading };
|
|
1074
|
+
}
|
|
801
1075
|
function TaskBoardCore({
|
|
802
1076
|
projectId,
|
|
803
1077
|
columns = DEFAULT_BOARD_COLUMNS,
|
|
@@ -809,6 +1083,8 @@ function TaskBoardCore({
|
|
|
809
1083
|
assigneeId,
|
|
810
1084
|
hiddenFields,
|
|
811
1085
|
resolveAssignee,
|
|
1086
|
+
linkSourceProduct,
|
|
1087
|
+
renderLinkIcon,
|
|
812
1088
|
onTaskClick,
|
|
813
1089
|
className,
|
|
814
1090
|
workspaceId: workspaceIdProp
|
|
@@ -816,7 +1092,9 @@ function TaskBoardCore({
|
|
|
816
1092
|
const ctx = usePlanMagnetContextSafe();
|
|
817
1093
|
const workspaceId = workspaceIdProp ?? ctx?.workspaceId;
|
|
818
1094
|
const client = useApolloClient();
|
|
1095
|
+
const L = useTaskLabels();
|
|
819
1096
|
const hidden = useMemo(() => new Set(hiddenFields ?? []), [hiddenFields]);
|
|
1097
|
+
const { linksByItem } = useWorkItemLinks(workspaceId, linkSourceProduct);
|
|
820
1098
|
const [draggingId, setDraggingId] = useState(null);
|
|
821
1099
|
const [dragOver, setDragOver] = useState(null);
|
|
822
1100
|
const [moveError, setMoveError] = useState(null);
|
|
@@ -844,10 +1122,10 @@ function TaskBoardCore({
|
|
|
844
1122
|
variables: { id: task.id, input: { status: toStatus } }
|
|
845
1123
|
}).catch(() => {
|
|
846
1124
|
client.cache.modify({ id, fields: { status: () => from2 } });
|
|
847
|
-
setMoveError(
|
|
1125
|
+
setMoveError(L.moveFailed);
|
|
848
1126
|
});
|
|
849
1127
|
},
|
|
850
|
-
[client, updateItem]
|
|
1128
|
+
[client, updateItem, L]
|
|
851
1129
|
);
|
|
852
1130
|
if (!workspaceId) {
|
|
853
1131
|
return /* @__PURE__ */ jsx("div", { className: cn("p-6 text-sm text-destructive", className), children: "TaskBoard: no workspaceId provided (prop or PlanMagnetProvider)." });
|
|
@@ -857,7 +1135,8 @@ function TaskBoardCore({
|
|
|
857
1135
|
}
|
|
858
1136
|
if (error && !data) {
|
|
859
1137
|
return /* @__PURE__ */ jsxs("div", { className: cn("p-6 text-sm text-destructive", className), children: [
|
|
860
|
-
|
|
1138
|
+
L.errorLoading,
|
|
1139
|
+
": ",
|
|
861
1140
|
error.message
|
|
862
1141
|
] });
|
|
863
1142
|
}
|
|
@@ -889,11 +1168,11 @@ function TaskBoardCore({
|
|
|
889
1168
|
};
|
|
890
1169
|
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-3", className), children: [
|
|
891
1170
|
!hideHeader && /* @__PURE__ */ jsxs("div", { className: "flex items-baseline justify-between", children: [
|
|
892
|
-
/* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold text-foreground", children:
|
|
1171
|
+
/* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold text-foreground", children: L.board }),
|
|
893
1172
|
/* @__PURE__ */ jsxs("span", { className: "text-sm text-muted-foreground", children: [
|
|
894
1173
|
filtered.length,
|
|
895
1174
|
" ",
|
|
896
|
-
filtered.length === 1 ?
|
|
1175
|
+
filtered.length === 1 ? L.tasksSingular : L.tasksPlural
|
|
897
1176
|
] })
|
|
898
1177
|
] }),
|
|
899
1178
|
moveError && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-destructive/40 bg-destructive/10 px-3 py-1.5 text-xs text-destructive", children: moveError }),
|
|
@@ -914,11 +1193,11 @@ function TaskBoardCore({
|
|
|
914
1193
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 px-3 py-2", children: [
|
|
915
1194
|
/* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2 text-sm font-medium text-foreground", children: [
|
|
916
1195
|
/* @__PURE__ */ jsx(StatusIcon, { status: col.status }),
|
|
917
|
-
col.
|
|
1196
|
+
L.status[col.status]
|
|
918
1197
|
] }),
|
|
919
1198
|
/* @__PURE__ */ jsx("span", { className: "rounded-full bg-muted px-1.5 text-xs font-medium text-muted-foreground", children: colTasks.length })
|
|
920
1199
|
] }),
|
|
921
|
-
/* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2 px-2 pb-2", children: colTasks.length === 0 ? /* @__PURE__ */ jsx("div", { className: "rounded-md border border-dashed border-border/70 px-3 py-6 text-center text-xs text-muted-foreground", children: isOver ?
|
|
1200
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2 px-2 pb-2", children: colTasks.length === 0 ? /* @__PURE__ */ jsx("div", { className: "rounded-md border border-dashed border-border/70 px-3 py-6 text-center text-xs text-muted-foreground", children: isOver ? L.dropHere : L.noTasks }) : colTasks.map((task) => /* @__PURE__ */ jsx(
|
|
922
1201
|
TaskCard,
|
|
923
1202
|
{
|
|
924
1203
|
task,
|
|
@@ -927,6 +1206,8 @@ function TaskBoardCore({
|
|
|
927
1206
|
draggable: canDrag,
|
|
928
1207
|
dragging: draggingId === task.id,
|
|
929
1208
|
resolveAssignee,
|
|
1209
|
+
links: linksByItem.get(task.id),
|
|
1210
|
+
renderLinkIcon,
|
|
930
1211
|
onDragStart: (t, e) => {
|
|
931
1212
|
setDraggingId(t.id);
|
|
932
1213
|
e.dataTransfer.effectAllowed = "move";
|
|
@@ -981,10 +1262,11 @@ var fieldClass = "w-full rounded-md border border-input bg-background px-3 py-2
|
|
|
981
1262
|
var labelClass = "text-sm font-medium text-foreground";
|
|
982
1263
|
function CreateTaskCore({
|
|
983
1264
|
projectId: projectIdProp,
|
|
1265
|
+
assigneeOptions,
|
|
984
1266
|
hiddenFields,
|
|
985
1267
|
defaultValues,
|
|
986
1268
|
hideHeader,
|
|
987
|
-
submitLabel
|
|
1269
|
+
submitLabel,
|
|
988
1270
|
onCreated,
|
|
989
1271
|
onError: onError2,
|
|
990
1272
|
onCancel,
|
|
@@ -994,6 +1276,7 @@ function CreateTaskCore({
|
|
|
994
1276
|
const ctx = usePlanMagnetContextSafe();
|
|
995
1277
|
const workspaceId = workspaceIdProp ?? ctx?.workspaceId;
|
|
996
1278
|
const projectId = projectIdProp ?? defaultValues?.projectId;
|
|
1279
|
+
const L = useTaskLabels();
|
|
997
1280
|
const hidden = useMemo(
|
|
998
1281
|
() => new Set(hiddenFields ?? []),
|
|
999
1282
|
[hiddenFields]
|
|
@@ -1076,12 +1359,12 @@ function CreateTaskCore({
|
|
|
1076
1359
|
}
|
|
1077
1360
|
return /* @__PURE__ */ jsx(Card, { className: cn("shadow-sm", className), children: /* @__PURE__ */ jsx(CardContent, { className: "p-6", children: /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
|
|
1078
1361
|
!hideHeader && /* @__PURE__ */ jsxs("div", { children: [
|
|
1079
|
-
/* @__PURE__ */ jsx("h2", { className: "text-xl font-semibold text-foreground", children:
|
|
1080
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children:
|
|
1362
|
+
/* @__PURE__ */ jsx("h2", { className: "text-xl font-semibold text-foreground", children: L.newTaskHeading }),
|
|
1363
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: L.newTaskSubtitle })
|
|
1081
1364
|
] }),
|
|
1082
|
-
!projectId && /* @__PURE__ */ jsx("p", { className: "rounded-md bg-destructive/10 p-2 text-xs text-destructive", children:
|
|
1365
|
+
!projectId && /* @__PURE__ */ jsx("p", { className: "rounded-md bg-destructive/10 p-2 text-xs text-destructive", children: L.projectRequired }),
|
|
1083
1366
|
/* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
1084
|
-
/* @__PURE__ */ jsx("label", { htmlFor: "pm-title", className: labelClass, children:
|
|
1367
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "pm-title", className: labelClass, children: L.title }),
|
|
1085
1368
|
/* @__PURE__ */ jsx(
|
|
1086
1369
|
"input",
|
|
1087
1370
|
{
|
|
@@ -1089,13 +1372,13 @@ function CreateTaskCore({
|
|
|
1089
1372
|
className: fieldClass,
|
|
1090
1373
|
value: title,
|
|
1091
1374
|
onChange: (e) => setTitle(e.target.value),
|
|
1092
|
-
placeholder:
|
|
1375
|
+
placeholder: L.titlePlaceholder,
|
|
1093
1376
|
required: true
|
|
1094
1377
|
}
|
|
1095
1378
|
)
|
|
1096
1379
|
] }),
|
|
1097
1380
|
!hidden.has("description") && /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
1098
|
-
/* @__PURE__ */ jsx("label", { htmlFor: "pm-description", className: labelClass, children:
|
|
1381
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "pm-description", className: labelClass, children: L.description }),
|
|
1099
1382
|
/* @__PURE__ */ jsx(
|
|
1100
1383
|
"textarea",
|
|
1101
1384
|
{
|
|
@@ -1103,13 +1386,13 @@ function CreateTaskCore({
|
|
|
1103
1386
|
className: cn(fieldClass, "min-h-[80px]"),
|
|
1104
1387
|
value: description,
|
|
1105
1388
|
onChange: (e) => setDescription(e.target.value),
|
|
1106
|
-
placeholder:
|
|
1389
|
+
placeholder: L.descriptionPlaceholder
|
|
1107
1390
|
}
|
|
1108
1391
|
)
|
|
1109
1392
|
] }),
|
|
1110
1393
|
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
|
|
1111
1394
|
!hidden.has("type") && /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
1112
|
-
/* @__PURE__ */ jsx("label", { htmlFor: "pm-type", className: labelClass, children:
|
|
1395
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "pm-type", className: labelClass, children: L.typeLabel }),
|
|
1113
1396
|
/* @__PURE__ */ jsx(
|
|
1114
1397
|
"select",
|
|
1115
1398
|
{
|
|
@@ -1117,12 +1400,12 @@ function CreateTaskCore({
|
|
|
1117
1400
|
className: cn(fieldClass, "capitalize"),
|
|
1118
1401
|
value: type,
|
|
1119
1402
|
onChange: (e) => setType(e.target.value),
|
|
1120
|
-
children: TASK_TYPES.map((t) => /* @__PURE__ */ jsx("option", { value: t, children:
|
|
1403
|
+
children: TASK_TYPES.map((t) => /* @__PURE__ */ jsx("option", { value: t, children: L.type[t] }, t))
|
|
1121
1404
|
}
|
|
1122
1405
|
)
|
|
1123
1406
|
] }),
|
|
1124
1407
|
!hidden.has("status") && /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
1125
|
-
/* @__PURE__ */ jsx("label", { htmlFor: "pm-status", className: labelClass, children:
|
|
1408
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "pm-status", className: labelClass, children: L.statusLabel }),
|
|
1126
1409
|
/* @__PURE__ */ jsx(
|
|
1127
1410
|
"select",
|
|
1128
1411
|
{
|
|
@@ -1130,12 +1413,12 @@ function CreateTaskCore({
|
|
|
1130
1413
|
className: cn(fieldClass, "capitalize"),
|
|
1131
1414
|
value: status,
|
|
1132
1415
|
onChange: (e) => setStatus(e.target.value),
|
|
1133
|
-
children: TASK_STATUSES.map((s) => /* @__PURE__ */ jsx("option", { value: s, children:
|
|
1416
|
+
children: TASK_STATUSES.map((s) => /* @__PURE__ */ jsx("option", { value: s, children: L.status[s] }, s))
|
|
1134
1417
|
}
|
|
1135
1418
|
)
|
|
1136
1419
|
] }),
|
|
1137
1420
|
!hidden.has("priority") && /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
1138
|
-
/* @__PURE__ */ jsx("label", { htmlFor: "pm-priority", className: labelClass, children:
|
|
1421
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "pm-priority", className: labelClass, children: L.priorityLabel }),
|
|
1139
1422
|
/* @__PURE__ */ jsx(
|
|
1140
1423
|
"select",
|
|
1141
1424
|
{
|
|
@@ -1143,25 +1426,37 @@ function CreateTaskCore({
|
|
|
1143
1426
|
className: cn(fieldClass, "capitalize"),
|
|
1144
1427
|
value: priority,
|
|
1145
1428
|
onChange: (e) => setPriority(e.target.value),
|
|
1146
|
-
children: TASK_PRIORITIES.map((p) => /* @__PURE__ */ jsx("option", { value: p, children:
|
|
1429
|
+
children: TASK_PRIORITIES.map((p) => /* @__PURE__ */ jsx("option", { value: p, children: L.priority[p] }, p))
|
|
1147
1430
|
}
|
|
1148
1431
|
)
|
|
1149
1432
|
] }),
|
|
1150
1433
|
!hidden.has("assignee") && /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
1151
|
-
/* @__PURE__ */ jsx("label", { htmlFor: "pm-assignee", className: labelClass, children:
|
|
1152
|
-
/* @__PURE__ */
|
|
1434
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "pm-assignee", className: labelClass, children: L.assigneeLabel }),
|
|
1435
|
+
assigneeOptions && assigneeOptions.length > 0 ? /* @__PURE__ */ jsxs(
|
|
1436
|
+
"select",
|
|
1437
|
+
{
|
|
1438
|
+
id: "pm-assignee",
|
|
1439
|
+
className: fieldClass,
|
|
1440
|
+
value: assigneeId,
|
|
1441
|
+
onChange: (e) => setAssigneeId(e.target.value),
|
|
1442
|
+
children: [
|
|
1443
|
+
/* @__PURE__ */ jsx("option", { value: "", children: L.unassigned }),
|
|
1444
|
+
assigneeOptions.map((o) => /* @__PURE__ */ jsx("option", { value: o.id, children: o.name }, o.id))
|
|
1445
|
+
]
|
|
1446
|
+
}
|
|
1447
|
+
) : /* @__PURE__ */ jsx(
|
|
1153
1448
|
"input",
|
|
1154
1449
|
{
|
|
1155
1450
|
id: "pm-assignee",
|
|
1156
1451
|
className: fieldClass,
|
|
1157
1452
|
value: assigneeId,
|
|
1158
1453
|
onChange: (e) => setAssigneeId(e.target.value),
|
|
1159
|
-
placeholder:
|
|
1454
|
+
placeholder: L.assigneePlaceholder
|
|
1160
1455
|
}
|
|
1161
1456
|
)
|
|
1162
1457
|
] }),
|
|
1163
1458
|
!hidden.has("dueDate") && /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
1164
|
-
/* @__PURE__ */ jsx("label", { htmlFor: "pm-due", className: labelClass, children:
|
|
1459
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "pm-due", className: labelClass, children: L.dueDateLabel }),
|
|
1165
1460
|
/* @__PURE__ */ jsx(
|
|
1166
1461
|
"input",
|
|
1167
1462
|
{
|
|
@@ -1174,7 +1469,7 @@ function CreateTaskCore({
|
|
|
1174
1469
|
)
|
|
1175
1470
|
] }),
|
|
1176
1471
|
!hidden.has("storyPoints") && /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
1177
|
-
/* @__PURE__ */ jsx("label", { htmlFor: "pm-points", className: labelClass, children:
|
|
1472
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "pm-points", className: labelClass, children: L.storyPointsLabel }),
|
|
1178
1473
|
/* @__PURE__ */ jsx(
|
|
1179
1474
|
"input",
|
|
1180
1475
|
{
|
|
@@ -1190,7 +1485,7 @@ function CreateTaskCore({
|
|
|
1190
1485
|
] })
|
|
1191
1486
|
] }),
|
|
1192
1487
|
!hidden.has("labels") && /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
1193
|
-
/* @__PURE__ */ jsx("label", { htmlFor: "pm-labels", className: labelClass, children:
|
|
1488
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "pm-labels", className: labelClass, children: L.labelsLabel }),
|
|
1194
1489
|
/* @__PURE__ */ jsx(
|
|
1195
1490
|
"input",
|
|
1196
1491
|
{
|
|
@@ -1198,12 +1493,13 @@ function CreateTaskCore({
|
|
|
1198
1493
|
className: fieldClass,
|
|
1199
1494
|
value: labels,
|
|
1200
1495
|
onChange: (e) => setLabels(e.target.value),
|
|
1201
|
-
placeholder:
|
|
1496
|
+
placeholder: L.labelsPlaceholder
|
|
1202
1497
|
}
|
|
1203
1498
|
)
|
|
1204
1499
|
] }),
|
|
1205
1500
|
error && /* @__PURE__ */ jsxs("p", { className: "text-sm text-destructive", children: [
|
|
1206
|
-
|
|
1501
|
+
L.failedToCreate,
|
|
1502
|
+
": ",
|
|
1207
1503
|
error.message
|
|
1208
1504
|
] }),
|
|
1209
1505
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-2", children: [
|
|
@@ -1213,7 +1509,7 @@ function CreateTaskCore({
|
|
|
1213
1509
|
type: "button",
|
|
1214
1510
|
onClick: onCancel,
|
|
1215
1511
|
className: "rounded-md bg-muted px-4 py-2 text-sm font-medium text-muted-foreground hover:bg-muted/70",
|
|
1216
|
-
children:
|
|
1512
|
+
children: L.cancel
|
|
1217
1513
|
}
|
|
1218
1514
|
),
|
|
1219
1515
|
/* @__PURE__ */ jsx(
|
|
@@ -1225,7 +1521,7 @@ function CreateTaskCore({
|
|
|
1225
1521
|
"rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground",
|
|
1226
1522
|
(!canSubmit || loading) && "cursor-not-allowed opacity-50"
|
|
1227
1523
|
),
|
|
1228
|
-
children: loading ?
|
|
1524
|
+
children: loading ? L.creating : submitLabel ?? L.create
|
|
1229
1525
|
}
|
|
1230
1526
|
)
|
|
1231
1527
|
] })
|
|
@@ -1283,17 +1579,32 @@ var statusRank = {
|
|
|
1283
1579
|
DONE: 5,
|
|
1284
1580
|
CANCELLED: 6
|
|
1285
1581
|
};
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1582
|
+
function columnLabel(col, L) {
|
|
1583
|
+
switch (col) {
|
|
1584
|
+
case "key":
|
|
1585
|
+
return L.colKey;
|
|
1586
|
+
case "title":
|
|
1587
|
+
return L.colTask;
|
|
1588
|
+
case "type":
|
|
1589
|
+
return L.colType;
|
|
1590
|
+
case "status":
|
|
1591
|
+
return L.colStatus;
|
|
1592
|
+
case "priority":
|
|
1593
|
+
return L.colPriority;
|
|
1594
|
+
case "assignee":
|
|
1595
|
+
return L.colAssignee;
|
|
1596
|
+
case "dueDate":
|
|
1597
|
+
return L.colDueDate;
|
|
1598
|
+
case "storyPoints":
|
|
1599
|
+
return L.colPoints;
|
|
1600
|
+
case "linkedRecord":
|
|
1601
|
+
return L.colLinkedRecord;
|
|
1602
|
+
case "labels":
|
|
1603
|
+
return L.colLabels;
|
|
1604
|
+
default:
|
|
1605
|
+
return col;
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1297
1608
|
var COLUMN_SORT = {
|
|
1298
1609
|
title: "title",
|
|
1299
1610
|
type: "type",
|
|
@@ -1315,12 +1626,16 @@ function TaskListCore({
|
|
|
1315
1626
|
hideHeader,
|
|
1316
1627
|
onSelect,
|
|
1317
1628
|
resolveAssignee,
|
|
1629
|
+
linkSourceProduct,
|
|
1630
|
+
renderLinkIcon,
|
|
1318
1631
|
limit = 200,
|
|
1319
1632
|
className,
|
|
1320
1633
|
workspaceId: workspaceIdProp
|
|
1321
1634
|
}) {
|
|
1322
1635
|
const ctx = usePlanMagnetContextSafe();
|
|
1323
1636
|
const workspaceId = workspaceIdProp ?? ctx?.workspaceId;
|
|
1637
|
+
const { linksByItem } = useWorkItemLinks(workspaceId, linkSourceProduct);
|
|
1638
|
+
const L = useTaskLabels();
|
|
1324
1639
|
const [sort, setSort] = useState({
|
|
1325
1640
|
by: sortBy ?? null,
|
|
1326
1641
|
dir: sortDir
|
|
@@ -1368,17 +1683,18 @@ function TaskListCore({
|
|
|
1368
1683
|
}
|
|
1369
1684
|
if (error && !data) {
|
|
1370
1685
|
return /* @__PURE__ */ jsxs("div", { className: cn("p-6 text-sm text-destructive", className), children: [
|
|
1371
|
-
|
|
1686
|
+
L.errorLoading,
|
|
1687
|
+
": ",
|
|
1372
1688
|
error.message
|
|
1373
1689
|
] });
|
|
1374
1690
|
}
|
|
1375
1691
|
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-3", className), children: [
|
|
1376
1692
|
!hideHeader && /* @__PURE__ */ jsxs("div", { className: "flex items-baseline justify-between", children: [
|
|
1377
|
-
/* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold text-foreground", children:
|
|
1693
|
+
/* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold text-foreground", children: L.list }),
|
|
1378
1694
|
/* @__PURE__ */ jsxs("span", { className: "text-sm text-muted-foreground", children: [
|
|
1379
1695
|
rows.length,
|
|
1380
1696
|
" ",
|
|
1381
|
-
rows.length === 1 ?
|
|
1697
|
+
rows.length === 1 ? L.tasksSingular : L.tasksPlural
|
|
1382
1698
|
] })
|
|
1383
1699
|
] }),
|
|
1384
1700
|
/* @__PURE__ */ jsx("div", { className: "overflow-x-auto rounded-lg border border-border", children: /* @__PURE__ */ jsxs("table", { className: "w-full border-collapse text-sm", children: [
|
|
@@ -1394,7 +1710,7 @@ function TaskListCore({
|
|
|
1394
1710
|
sortable && "cursor-pointer select-none hover:text-foreground"
|
|
1395
1711
|
),
|
|
1396
1712
|
children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
|
|
1397
|
-
|
|
1713
|
+
columnLabel(col, L),
|
|
1398
1714
|
active && (sort.dir === "asc" ? /* @__PURE__ */ jsx(ChevronUp, { className: "h-3 w-3", "aria-hidden": "true" }) : /* @__PURE__ */ jsx(ChevronDown, { className: "h-3 w-3", "aria-hidden": "true" }))
|
|
1399
1715
|
] })
|
|
1400
1716
|
},
|
|
@@ -1407,7 +1723,7 @@ function TaskListCore({
|
|
|
1407
1723
|
{
|
|
1408
1724
|
colSpan: columns.length,
|
|
1409
1725
|
className: "px-3 py-8 text-center text-muted-foreground",
|
|
1410
|
-
children:
|
|
1726
|
+
children: L.noTasksFound
|
|
1411
1727
|
}
|
|
1412
1728
|
) }),
|
|
1413
1729
|
rows.map((task) => /* @__PURE__ */ jsx(
|
|
@@ -1422,7 +1738,12 @@ function TaskListCore({
|
|
|
1422
1738
|
"td",
|
|
1423
1739
|
{
|
|
1424
1740
|
className: "px-3 py-2 align-middle text-foreground",
|
|
1425
|
-
children: renderCell(col, task,
|
|
1741
|
+
children: renderCell(col, task, {
|
|
1742
|
+
resolveAssignee,
|
|
1743
|
+
links: linksByItem.get(task.id),
|
|
1744
|
+
renderLinkIcon,
|
|
1745
|
+
unassigned: L.unassigned
|
|
1746
|
+
})
|
|
1426
1747
|
},
|
|
1427
1748
|
col
|
|
1428
1749
|
))
|
|
@@ -1433,7 +1754,8 @@ function TaskListCore({
|
|
|
1433
1754
|
] }) })
|
|
1434
1755
|
] });
|
|
1435
1756
|
}
|
|
1436
|
-
function renderCell(col, task,
|
|
1757
|
+
function renderCell(col, task, opts) {
|
|
1758
|
+
const { resolveAssignee, links, renderLinkIcon, unassigned } = opts;
|
|
1437
1759
|
switch (col) {
|
|
1438
1760
|
case "key":
|
|
1439
1761
|
return /* @__PURE__ */ jsx("span", { className: "font-mono text-xs text-muted-foreground", children: task.key });
|
|
@@ -1452,7 +1774,7 @@ function renderCell(col, task, resolveAssignee) {
|
|
|
1452
1774
|
const resolved = task.assigneeId ? resolveAssignee?.(task.assigneeId) : null;
|
|
1453
1775
|
return /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5", children: [
|
|
1454
1776
|
/* @__PURE__ */ jsx(Avatar, { id: task.assigneeId, name: resolved?.name, size: "sm" }),
|
|
1455
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: resolved?.name ?? (task.assigneeId ? "" :
|
|
1777
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: resolved?.name ?? (task.assigneeId ? "" : unassigned) })
|
|
1456
1778
|
] });
|
|
1457
1779
|
}
|
|
1458
1780
|
case "dueDate": {
|
|
@@ -1471,6 +1793,17 @@ function renderCell(col, task, resolveAssignee) {
|
|
|
1471
1793
|
}
|
|
1472
1794
|
case "storyPoints":
|
|
1473
1795
|
return task.storyPoints != null ? /* @__PURE__ */ jsx("span", { className: "flex h-5 min-w-5 items-center justify-center rounded-full bg-primary/10 px-1 text-[10px] font-semibold text-primary", children: task.storyPoints }) : /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "\u2014" });
|
|
1796
|
+
case "linkedRecord":
|
|
1797
|
+
if (!links || links.length === 0) {
|
|
1798
|
+
return /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "\u2014" });
|
|
1799
|
+
}
|
|
1800
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-1", children: [
|
|
1801
|
+
links.slice(0, 2).map((link) => /* @__PURE__ */ jsx(LinkChip, { link, renderIcon: renderLinkIcon }, link.id)),
|
|
1802
|
+
links.length > 2 && /* @__PURE__ */ jsxs("span", { className: "text-[10px] text-muted-foreground", children: [
|
|
1803
|
+
"+",
|
|
1804
|
+
links.length - 2
|
|
1805
|
+
] })
|
|
1806
|
+
] });
|
|
1474
1807
|
case "labels":
|
|
1475
1808
|
return /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1", children: (task.labels ?? []).slice(0, 3).map((l) => /* @__PURE__ */ jsx(
|
|
1476
1809
|
"span",
|
|
@@ -1530,6 +1863,35 @@ function TaskList({
|
|
|
1530
1863
|
}
|
|
1531
1864
|
);
|
|
1532
1865
|
}
|
|
1866
|
+
function useMilestones(workspaceId, opts = {}) {
|
|
1867
|
+
const { projectId, enabled = true, limit = 100 } = opts;
|
|
1868
|
+
const { data, loading } = useQuery(LIST_MILESTONES, {
|
|
1869
|
+
variables: {
|
|
1870
|
+
workspaceId,
|
|
1871
|
+
...projectId ? { filter: { projectId } } : {},
|
|
1872
|
+
pagination: { first: limit }
|
|
1873
|
+
},
|
|
1874
|
+
skip: !workspaceId || !enabled,
|
|
1875
|
+
errorPolicy: "all"
|
|
1876
|
+
});
|
|
1877
|
+
const milestones = useMemo(
|
|
1878
|
+
() => data?.planmagnetMilestones?.items ?? [],
|
|
1879
|
+
[data]
|
|
1880
|
+
);
|
|
1881
|
+
const byDay = useMemo(() => {
|
|
1882
|
+
const map = /* @__PURE__ */ new Map();
|
|
1883
|
+
for (const m of milestones) {
|
|
1884
|
+
const d = parseDate(m.dueDate);
|
|
1885
|
+
if (!d) continue;
|
|
1886
|
+
const key = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
|
|
1887
|
+
const arr = map.get(key);
|
|
1888
|
+
if (arr) arr.push(m);
|
|
1889
|
+
else map.set(key, [m]);
|
|
1890
|
+
}
|
|
1891
|
+
return map;
|
|
1892
|
+
}, [milestones]);
|
|
1893
|
+
return { milestones, byDay, loading };
|
|
1894
|
+
}
|
|
1533
1895
|
var WEEK_OPTS = { weekStartsOn: 1 };
|
|
1534
1896
|
function dayKey(d) {
|
|
1535
1897
|
return format(d, "yyyy-MM-dd");
|
|
@@ -1543,11 +1905,17 @@ function TaskTimelineCore({
|
|
|
1543
1905
|
defaultMode = "week",
|
|
1544
1906
|
onSelect,
|
|
1545
1907
|
resolveAssignee,
|
|
1908
|
+
showMilestones = true,
|
|
1546
1909
|
className,
|
|
1547
1910
|
workspaceId: workspaceIdProp
|
|
1548
1911
|
}) {
|
|
1549
1912
|
const ctx = usePlanMagnetContextSafe();
|
|
1550
1913
|
const workspaceId = workspaceIdProp ?? ctx?.workspaceId;
|
|
1914
|
+
const L = useTaskLabels();
|
|
1915
|
+
const { milestones, byDay: milestonesByDay } = useMilestones(workspaceId, {
|
|
1916
|
+
projectId,
|
|
1917
|
+
enabled: showMilestones
|
|
1918
|
+
});
|
|
1551
1919
|
const [mode, setMode] = useState(defaultMode);
|
|
1552
1920
|
const [offset, setOffset] = useState(0);
|
|
1553
1921
|
const { data, loading, error } = useQuery(
|
|
@@ -1627,7 +1995,8 @@ function TaskTimelineCore({
|
|
|
1627
1995
|
}
|
|
1628
1996
|
if (error && !data) {
|
|
1629
1997
|
return /* @__PURE__ */ jsxs("div", { className: cn("p-6 text-sm text-destructive", className), children: [
|
|
1630
|
-
|
|
1998
|
+
L.errorLoading,
|
|
1999
|
+
": ",
|
|
1631
2000
|
error.message
|
|
1632
2001
|
] });
|
|
1633
2002
|
}
|
|
@@ -1651,7 +2020,7 @@ function TaskTimelineCore({
|
|
|
1651
2020
|
type: "button",
|
|
1652
2021
|
onClick: () => setOffset(0),
|
|
1653
2022
|
className: "h-8 rounded-md border border-border px-3 text-xs font-medium text-foreground hover:bg-muted/50",
|
|
1654
|
-
children:
|
|
2023
|
+
children: L.today
|
|
1655
2024
|
}
|
|
1656
2025
|
),
|
|
1657
2026
|
/* @__PURE__ */ jsx(
|
|
@@ -1678,16 +2047,13 @@ function TaskTimelineCore({
|
|
|
1678
2047
|
"rounded px-3 py-1 text-xs font-medium capitalize transition-colors",
|
|
1679
2048
|
mode === m ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:text-foreground"
|
|
1680
2049
|
),
|
|
1681
|
-
children: m
|
|
2050
|
+
children: m === "week" ? L.week : L.month
|
|
1682
2051
|
},
|
|
1683
2052
|
m
|
|
1684
2053
|
)) })
|
|
1685
2054
|
] }),
|
|
1686
2055
|
overdue.length > 0 && /* @__PURE__ */ jsxs("div", { className: "rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2", children: [
|
|
1687
|
-
/* @__PURE__ */
|
|
1688
|
-
overdue.length,
|
|
1689
|
-
" overdue"
|
|
1690
|
-
] }),
|
|
2056
|
+
/* @__PURE__ */ jsx("p", { className: "mb-1 text-xs font-semibold text-destructive", children: L.overdue.replace("{n}", String(overdue.length)) }),
|
|
1691
2057
|
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: overdue.map((t) => /* @__PURE__ */ jsx(
|
|
1692
2058
|
TaskChip,
|
|
1693
2059
|
{
|
|
@@ -1699,8 +2065,16 @@ function TaskTimelineCore({
|
|
|
1699
2065
|
t.id
|
|
1700
2066
|
)) })
|
|
1701
2067
|
] }),
|
|
2068
|
+
milestones.length > 0 && /* @__PURE__ */ jsxs("div", { className: "rounded-md border border-primary/30 bg-primary/5 px-3 py-2", children: [
|
|
2069
|
+
/* @__PURE__ */ jsxs("p", { className: "mb-1 flex items-center gap-1 text-xs font-semibold text-primary", children: [
|
|
2070
|
+
/* @__PURE__ */ jsx(Flag, { className: "h-3.5 w-3.5", "aria-hidden": "true" }),
|
|
2071
|
+
L.milestones
|
|
2072
|
+
] }),
|
|
2073
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: milestones.map((m) => /* @__PURE__ */ jsx(MilestoneFlag, { milestone: m }, m.id)) })
|
|
2074
|
+
] }),
|
|
1702
2075
|
mode === "week" ? /* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 gap-2", children: days.map((day) => {
|
|
1703
2076
|
const items = byDay.get(dayKey(day)) ?? [];
|
|
2077
|
+
const dayMilestones = milestonesByDay.get(dayKey(day)) ?? [];
|
|
1704
2078
|
const today = isToday(day);
|
|
1705
2079
|
return /* @__PURE__ */ jsxs(
|
|
1706
2080
|
"div",
|
|
@@ -1732,15 +2106,18 @@ function TaskTimelineCore({
|
|
|
1732
2106
|
}
|
|
1733
2107
|
)
|
|
1734
2108
|
] }),
|
|
1735
|
-
/* @__PURE__ */
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
2109
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
2110
|
+
dayMilestones.map((m) => /* @__PURE__ */ jsx(MilestoneFlag, { milestone: m, compact: true }, m.id)),
|
|
2111
|
+
items.map((t) => /* @__PURE__ */ jsx(
|
|
2112
|
+
TaskChip,
|
|
2113
|
+
{
|
|
2114
|
+
task: t,
|
|
2115
|
+
onSelect,
|
|
2116
|
+
resolveAssignee
|
|
2117
|
+
},
|
|
2118
|
+
t.id
|
|
2119
|
+
))
|
|
2120
|
+
] })
|
|
1744
2121
|
]
|
|
1745
2122
|
},
|
|
1746
2123
|
dayKey(day)
|
|
@@ -1790,7 +2167,8 @@ function TaskTimelineCore({
|
|
|
1790
2167
|
items.length > 3 && /* @__PURE__ */ jsxs("span", { className: "text-[10px] text-muted-foreground", children: [
|
|
1791
2168
|
"+",
|
|
1792
2169
|
items.length - 3,
|
|
1793
|
-
"
|
|
2170
|
+
" ",
|
|
2171
|
+
L.more
|
|
1794
2172
|
] })
|
|
1795
2173
|
]
|
|
1796
2174
|
},
|
|
@@ -1799,11 +2177,7 @@ function TaskTimelineCore({
|
|
|
1799
2177
|
})
|
|
1800
2178
|
] }),
|
|
1801
2179
|
undated.length > 0 && /* @__PURE__ */ jsxs("div", { className: "rounded-md border border-border bg-muted/20 px-3 py-2", children: [
|
|
1802
|
-
/* @__PURE__ */
|
|
1803
|
-
"No due date (",
|
|
1804
|
-
undated.length,
|
|
1805
|
-
")"
|
|
1806
|
-
] }),
|
|
2180
|
+
/* @__PURE__ */ jsx("p", { className: "mb-1 text-xs font-semibold text-muted-foreground", children: L.noDueDate.replace("{n}", String(undated.length)) }),
|
|
1807
2181
|
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: undated.map((t) => /* @__PURE__ */ jsx(
|
|
1808
2182
|
TaskChip,
|
|
1809
2183
|
{
|
|
@@ -1816,6 +2190,30 @@ function TaskTimelineCore({
|
|
|
1816
2190
|
] })
|
|
1817
2191
|
] });
|
|
1818
2192
|
}
|
|
2193
|
+
function MilestoneFlag({
|
|
2194
|
+
milestone,
|
|
2195
|
+
compact
|
|
2196
|
+
}) {
|
|
2197
|
+
const due = formatDueDate(milestone.dueDate);
|
|
2198
|
+
return /* @__PURE__ */ jsxs(
|
|
2199
|
+
"span",
|
|
2200
|
+
{
|
|
2201
|
+
className: cn(
|
|
2202
|
+
"inline-flex max-w-full items-center gap-1 rounded-md border border-primary/40 bg-primary/10 px-1.5 py-1 text-[11px] font-medium text-primary",
|
|
2203
|
+
compact && "w-full"
|
|
2204
|
+
),
|
|
2205
|
+
title: milestone.name + (due ? ` \xB7 ${due}` : ""),
|
|
2206
|
+
children: [
|
|
2207
|
+
/* @__PURE__ */ jsx(Flag, { className: "h-3 w-3 shrink-0", "aria-hidden": "true" }),
|
|
2208
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: milestone.name }),
|
|
2209
|
+
!compact && due && /* @__PURE__ */ jsxs("span", { className: "shrink-0 text-primary/70", children: [
|
|
2210
|
+
"\xB7 ",
|
|
2211
|
+
due
|
|
2212
|
+
] })
|
|
2213
|
+
]
|
|
2214
|
+
}
|
|
2215
|
+
);
|
|
2216
|
+
}
|
|
1819
2217
|
function TaskChip({
|
|
1820
2218
|
task,
|
|
1821
2219
|
onSelect,
|
|
@@ -1845,10 +2243,10 @@ function TaskChip({
|
|
|
1845
2243
|
}
|
|
1846
2244
|
);
|
|
1847
2245
|
}
|
|
1848
|
-
var
|
|
1849
|
-
board:
|
|
1850
|
-
list:
|
|
1851
|
-
timeline:
|
|
2246
|
+
var VIEW_ICONS = {
|
|
2247
|
+
board: LayoutGrid,
|
|
2248
|
+
list: List,
|
|
2249
|
+
timeline: CalendarRange
|
|
1852
2250
|
};
|
|
1853
2251
|
var SELECT_CLASS = "h-8 rounded-md border border-border bg-background px-2 text-xs font-medium text-foreground capitalize transition-colors hover:bg-muted/50 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring";
|
|
1854
2252
|
function TaskToolbar({
|
|
@@ -1863,8 +2261,16 @@ function TaskToolbar({
|
|
|
1863
2261
|
onTypeChange,
|
|
1864
2262
|
onNewTask,
|
|
1865
2263
|
canCreate,
|
|
2264
|
+
mine,
|
|
2265
|
+
onMineChange,
|
|
1866
2266
|
className
|
|
1867
2267
|
}) {
|
|
2268
|
+
const L = useTaskLabels();
|
|
2269
|
+
const viewLabel = {
|
|
2270
|
+
board: L.board,
|
|
2271
|
+
list: L.list,
|
|
2272
|
+
timeline: L.timeline
|
|
2273
|
+
};
|
|
1868
2274
|
return /* @__PURE__ */ jsxs(
|
|
1869
2275
|
"div",
|
|
1870
2276
|
{
|
|
@@ -1880,8 +2286,7 @@ function TaskToolbar({
|
|
|
1880
2286
|
role: "tablist",
|
|
1881
2287
|
"aria-label": "Task views",
|
|
1882
2288
|
children: views.map((v) => {
|
|
1883
|
-
const
|
|
1884
|
-
const Icon = meta.icon;
|
|
2289
|
+
const Icon = VIEW_ICONS[v];
|
|
1885
2290
|
const active = v === view;
|
|
1886
2291
|
return /* @__PURE__ */ jsxs(
|
|
1887
2292
|
"button",
|
|
@@ -1896,7 +2301,7 @@ function TaskToolbar({
|
|
|
1896
2301
|
),
|
|
1897
2302
|
children: [
|
|
1898
2303
|
/* @__PURE__ */ jsx(Icon, { className: "h-4 w-4", "aria-hidden": "true" }),
|
|
1899
|
-
|
|
2304
|
+
viewLabel[v],
|
|
1900
2305
|
active && /* @__PURE__ */ jsx("span", { className: "absolute inset-x-1 -bottom-[9px] h-0.5 rounded-full bg-primary" })
|
|
1901
2306
|
]
|
|
1902
2307
|
},
|
|
@@ -1920,22 +2325,38 @@ function TaskToolbar({
|
|
|
1920
2325
|
type: "search",
|
|
1921
2326
|
value: search,
|
|
1922
2327
|
onChange: (e) => onSearchChange(e.target.value),
|
|
1923
|
-
placeholder:
|
|
1924
|
-
"aria-label":
|
|
2328
|
+
placeholder: L.searchPlaceholder,
|
|
2329
|
+
"aria-label": L.searchPlaceholder,
|
|
1925
2330
|
className: "h-8 w-40 rounded-md border border-border bg-background pl-7 pr-2 text-xs text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
1926
2331
|
}
|
|
1927
2332
|
)
|
|
1928
2333
|
] }),
|
|
2334
|
+
onMineChange && /* @__PURE__ */ jsxs(
|
|
2335
|
+
"button",
|
|
2336
|
+
{
|
|
2337
|
+
type: "button",
|
|
2338
|
+
onClick: () => onMineChange(!mine),
|
|
2339
|
+
"aria-pressed": mine,
|
|
2340
|
+
className: cn(
|
|
2341
|
+
"flex h-8 items-center gap-1.5 rounded-md border px-2.5 text-xs font-medium transition-colors",
|
|
2342
|
+
mine ? "border-primary bg-primary/10 text-primary" : "border-border bg-background text-muted-foreground hover:bg-muted/50 hover:text-foreground"
|
|
2343
|
+
),
|
|
2344
|
+
children: [
|
|
2345
|
+
/* @__PURE__ */ jsx(User, { className: "h-3.5 w-3.5", "aria-hidden": "true" }),
|
|
2346
|
+
L.myTasks
|
|
2347
|
+
]
|
|
2348
|
+
}
|
|
2349
|
+
),
|
|
1929
2350
|
/* @__PURE__ */ jsxs(
|
|
1930
2351
|
"select",
|
|
1931
2352
|
{
|
|
1932
2353
|
value: priority,
|
|
1933
2354
|
onChange: (e) => onPriorityChange(e.target.value),
|
|
1934
|
-
"aria-label":
|
|
2355
|
+
"aria-label": L.priorityLabel,
|
|
1935
2356
|
className: SELECT_CLASS,
|
|
1936
2357
|
children: [
|
|
1937
|
-
/* @__PURE__ */ jsx("option", { value: "ALL", children:
|
|
1938
|
-
TASK_PRIORITIES.map((p) => /* @__PURE__ */ jsx("option", { value: p, children:
|
|
2358
|
+
/* @__PURE__ */ jsx("option", { value: "ALL", children: L.allPriorities }),
|
|
2359
|
+
TASK_PRIORITIES.map((p) => /* @__PURE__ */ jsx("option", { value: p, children: L.priority[p] }, p))
|
|
1939
2360
|
]
|
|
1940
2361
|
}
|
|
1941
2362
|
),
|
|
@@ -1944,11 +2365,11 @@ function TaskToolbar({
|
|
|
1944
2365
|
{
|
|
1945
2366
|
value: type,
|
|
1946
2367
|
onChange: (e) => onTypeChange(e.target.value),
|
|
1947
|
-
"aria-label":
|
|
2368
|
+
"aria-label": L.typeLabel,
|
|
1948
2369
|
className: SELECT_CLASS,
|
|
1949
2370
|
children: [
|
|
1950
|
-
/* @__PURE__ */ jsx("option", { value: "ALL", children:
|
|
1951
|
-
TASK_TYPES.map((t) => /* @__PURE__ */ jsx("option", { value: t, children:
|
|
2371
|
+
/* @__PURE__ */ jsx("option", { value: "ALL", children: L.allTypes }),
|
|
2372
|
+
TASK_TYPES.map((t) => /* @__PURE__ */ jsx("option", { value: t, children: L.type[t] }, t))
|
|
1952
2373
|
]
|
|
1953
2374
|
}
|
|
1954
2375
|
),
|
|
@@ -1960,7 +2381,7 @@ function TaskToolbar({
|
|
|
1960
2381
|
className: "flex h-8 items-center gap-1.5 rounded-md bg-primary px-3 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90",
|
|
1961
2382
|
children: [
|
|
1962
2383
|
/* @__PURE__ */ jsx(Plus, { className: "h-4 w-4", "aria-hidden": "true" }),
|
|
1963
|
-
|
|
2384
|
+
L.newTask
|
|
1964
2385
|
]
|
|
1965
2386
|
}
|
|
1966
2387
|
)
|
|
@@ -1984,9 +2405,14 @@ function TaskDetailCore({
|
|
|
1984
2405
|
hiddenFields,
|
|
1985
2406
|
hideHeader,
|
|
1986
2407
|
onUpdated,
|
|
2408
|
+
onDeleted,
|
|
1987
2409
|
onError: onError2,
|
|
2410
|
+
resolveAssignee,
|
|
2411
|
+
assigneeOptions,
|
|
1988
2412
|
className
|
|
1989
2413
|
}) {
|
|
2414
|
+
const client = useApolloClient();
|
|
2415
|
+
const L = useTaskLabels();
|
|
1990
2416
|
const hidden = useMemo(
|
|
1991
2417
|
() => new Set(hiddenFields ?? []),
|
|
1992
2418
|
[hiddenFields]
|
|
@@ -1997,6 +2423,7 @@ function TaskDetailCore({
|
|
|
1997
2423
|
});
|
|
1998
2424
|
const item = data?.planmagnetWorkItem ?? null;
|
|
1999
2425
|
const [editing, setEditing] = useState(false);
|
|
2426
|
+
const [confirmingDelete, setConfirmingDelete] = useState(false);
|
|
2000
2427
|
const [title, setTitle] = useState("");
|
|
2001
2428
|
const [description, setDescription] = useState("");
|
|
2002
2429
|
const [type, setType] = useState("TASK");
|
|
@@ -2019,6 +2446,22 @@ function TaskDetailCore({
|
|
|
2019
2446
|
setStoryPoints(item.storyPoints != null ? String(item.storyPoints) : "");
|
|
2020
2447
|
}, [item]);
|
|
2021
2448
|
const [updateWorkItem, { loading: saving, error: saveError }] = useMutation(UPDATE_WORK_ITEM);
|
|
2449
|
+
const [deleteWorkItem, { loading: deleting, error: deleteError }] = useMutation(DELETE_WORK_ITEM);
|
|
2450
|
+
const handleDelete = async () => {
|
|
2451
|
+
if (!item) return;
|
|
2452
|
+
try {
|
|
2453
|
+
await deleteWorkItem({ variables: { id: item.id } });
|
|
2454
|
+
client.cache.evict({
|
|
2455
|
+
id: client.cache.identify({ __typename: "WorkItem", id: item.id })
|
|
2456
|
+
});
|
|
2457
|
+
client.cache.gc();
|
|
2458
|
+
void client.refetchQueries({ include: [LIST_WORK_ITEMS] }).catch(() => {
|
|
2459
|
+
});
|
|
2460
|
+
onDeleted?.(item.id);
|
|
2461
|
+
} catch (err) {
|
|
2462
|
+
onError2?.(err instanceof Error ? err : new Error(String(err)));
|
|
2463
|
+
}
|
|
2464
|
+
};
|
|
2022
2465
|
const handleSave = async (e) => {
|
|
2023
2466
|
e.preventDefault();
|
|
2024
2467
|
if (!item) return;
|
|
@@ -2067,12 +2510,13 @@ function TaskDetailCore({
|
|
|
2067
2510
|
}
|
|
2068
2511
|
if (error && !data) {
|
|
2069
2512
|
return /* @__PURE__ */ jsxs("div", { className: cn("p-6 text-sm text-destructive", className), children: [
|
|
2070
|
-
|
|
2513
|
+
L.errorLoading,
|
|
2514
|
+
": ",
|
|
2071
2515
|
error.message
|
|
2072
2516
|
] });
|
|
2073
2517
|
}
|
|
2074
2518
|
if (!item) {
|
|
2075
|
-
return /* @__PURE__ */ jsx("div", { className: cn("p-6 text-sm text-muted-foreground", className), children:
|
|
2519
|
+
return /* @__PURE__ */ jsx("div", { className: cn("p-6 text-sm text-muted-foreground", className), children: L.taskNotFound });
|
|
2076
2520
|
}
|
|
2077
2521
|
const canEdit = !readonly;
|
|
2078
2522
|
return /* @__PURE__ */ jsx(Card, { className: cn("shadow-sm", className), children: /* @__PURE__ */ jsxs(CardContent, { className: "space-y-4 p-6", children: [
|
|
@@ -2081,29 +2525,78 @@ function TaskDetailCore({
|
|
|
2081
2525
|
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: item.key }),
|
|
2082
2526
|
/* @__PURE__ */ jsx("h2", { className: "text-xl font-semibold text-foreground", children: item.title })
|
|
2083
2527
|
] }),
|
|
2084
|
-
canEdit && !editing && /* @__PURE__ */
|
|
2085
|
-
"
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2528
|
+
canEdit && !editing && /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [
|
|
2529
|
+
onDeleted && (confirmingDelete ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-xs", children: [
|
|
2530
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: L.deletePrompt }),
|
|
2531
|
+
/* @__PURE__ */ jsx(
|
|
2532
|
+
"button",
|
|
2533
|
+
{
|
|
2534
|
+
type: "button",
|
|
2535
|
+
disabled: deleting,
|
|
2536
|
+
onClick: handleDelete,
|
|
2537
|
+
className: "rounded bg-destructive px-2 py-1 font-medium text-destructive-foreground disabled:opacity-50",
|
|
2538
|
+
children: deleting ? "\u2026" : L.yes
|
|
2539
|
+
}
|
|
2540
|
+
),
|
|
2541
|
+
/* @__PURE__ */ jsx(
|
|
2542
|
+
"button",
|
|
2543
|
+
{
|
|
2544
|
+
type: "button",
|
|
2545
|
+
onClick: () => setConfirmingDelete(false),
|
|
2546
|
+
className: "rounded bg-muted px-2 py-1 text-muted-foreground",
|
|
2547
|
+
children: L.no
|
|
2548
|
+
}
|
|
2549
|
+
)
|
|
2550
|
+
] }) : /* @__PURE__ */ jsx(
|
|
2551
|
+
"button",
|
|
2552
|
+
{
|
|
2553
|
+
type: "button",
|
|
2554
|
+
onClick: () => setConfirmingDelete(true),
|
|
2555
|
+
title: L.del,
|
|
2556
|
+
"aria-label": L.del,
|
|
2557
|
+
className: "rounded-md p-1.5 text-destructive hover:bg-destructive/10",
|
|
2558
|
+
children: /* @__PURE__ */ jsx(Trash2, { className: "h-4 w-4" })
|
|
2559
|
+
}
|
|
2560
|
+
)),
|
|
2561
|
+
/* @__PURE__ */ jsx(
|
|
2562
|
+
"button",
|
|
2563
|
+
{
|
|
2564
|
+
type: "button",
|
|
2565
|
+
onClick: () => setEditing(true),
|
|
2566
|
+
className: "rounded-md bg-primary px-3 py-1.5 text-sm font-medium text-primary-foreground",
|
|
2567
|
+
children: L.edit
|
|
2568
|
+
}
|
|
2569
|
+
)
|
|
2570
|
+
] })
|
|
2571
|
+
] }),
|
|
2572
|
+
deleteError && /* @__PURE__ */ jsxs("p", { className: "text-sm text-destructive", children: [
|
|
2573
|
+
L.failedToDelete,
|
|
2574
|
+
": ",
|
|
2575
|
+
deleteError.message
|
|
2093
2576
|
] }),
|
|
2094
2577
|
!editing ? /* @__PURE__ */ jsxs("dl", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
|
|
2095
|
-
!hidden.has("type") && /* @__PURE__ */ jsx(Field, { label:
|
|
2096
|
-
!hidden.has("status") && /* @__PURE__ */ jsx(Field, { label:
|
|
2097
|
-
!hidden.has("priority") && /* @__PURE__ */ jsx(Field, { label:
|
|
2098
|
-
!hidden.has("assignee") && /* @__PURE__ */ jsx(Field, { label:
|
|
2099
|
-
|
|
2100
|
-
|
|
2578
|
+
!hidden.has("type") && /* @__PURE__ */ jsx(Field, { label: L.typeLabel, children: /* @__PURE__ */ jsx(Badge, { variant: "secondary", children: L.type[item.type] }) }),
|
|
2579
|
+
!hidden.has("status") && /* @__PURE__ */ jsx(Field, { label: L.statusLabel, children: /* @__PURE__ */ jsx("span", { className: "capitalize text-foreground", children: L.status[item.status] }) }),
|
|
2580
|
+
!hidden.has("priority") && /* @__PURE__ */ jsx(Field, { label: L.priorityLabel, children: /* @__PURE__ */ jsx(Badge, { variant: priorityVariant[item.priority], children: L.priority[item.priority] }) }),
|
|
2581
|
+
!hidden.has("assignee") && /* @__PURE__ */ jsx(Field, { label: L.assigneeLabel, children: item.assigneeId ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5", children: [
|
|
2582
|
+
/* @__PURE__ */ jsx(
|
|
2583
|
+
Avatar,
|
|
2584
|
+
{
|
|
2585
|
+
id: item.assigneeId,
|
|
2586
|
+
name: resolveAssignee?.(item.assigneeId)?.name,
|
|
2587
|
+
size: "sm"
|
|
2588
|
+
}
|
|
2589
|
+
),
|
|
2590
|
+
/* @__PURE__ */ jsx("span", { className: "text-foreground", children: resolveAssignee?.(item.assigneeId)?.name ?? L.assigned })
|
|
2591
|
+
] }) : /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: L.unassigned }) }),
|
|
2592
|
+
!hidden.has("dueDate") && /* @__PURE__ */ jsx(Field, { label: L.dueDateLabel, children: /* @__PURE__ */ jsx("span", { className: "text-foreground", children: item.dueDate ?? "\u2014" }) }),
|
|
2593
|
+
!hidden.has("storyPoints") && /* @__PURE__ */ jsx(Field, { label: L.storyPointsLabel, children: /* @__PURE__ */ jsx("span", { className: "text-foreground", children: item.storyPoints ?? 0 }) }),
|
|
2101
2594
|
!hidden.has("description") && /* @__PURE__ */ jsxs("div", { className: "sm:col-span-2", children: [
|
|
2102
|
-
/* @__PURE__ */ jsx("dt", { className: labelClass2, children:
|
|
2595
|
+
/* @__PURE__ */ jsx("dt", { className: labelClass2, children: L.description }),
|
|
2103
2596
|
/* @__PURE__ */ jsx("dd", { className: "mt-1 whitespace-pre-wrap text-sm text-foreground", children: item.description || "\u2014" })
|
|
2104
2597
|
] }),
|
|
2105
2598
|
!hidden.has("labels") && /* @__PURE__ */ jsxs("div", { className: "sm:col-span-2", children: [
|
|
2106
|
-
/* @__PURE__ */ jsx("dt", { className: labelClass2, children:
|
|
2599
|
+
/* @__PURE__ */ jsx("dt", { className: labelClass2, children: L.labelsLabel }),
|
|
2107
2600
|
/* @__PURE__ */ jsx("dd", { className: "mt-1 flex flex-wrap gap-1", children: (item.labels ?? []).length === 0 ? /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: "\u2014" }) : item.labels.map((l) => /* @__PURE__ */ jsx(
|
|
2108
2601
|
"span",
|
|
2109
2602
|
{
|
|
@@ -2115,7 +2608,7 @@ function TaskDetailCore({
|
|
|
2115
2608
|
] })
|
|
2116
2609
|
] }) : /* @__PURE__ */ jsxs("form", { onSubmit: handleSave, className: "space-y-4", children: [
|
|
2117
2610
|
/* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
2118
|
-
/* @__PURE__ */ jsx("label", { htmlFor: "pm-detail-title", className: labelClass2, children:
|
|
2611
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "pm-detail-title", className: labelClass2, children: L.title }),
|
|
2119
2612
|
/* @__PURE__ */ jsx(
|
|
2120
2613
|
"input",
|
|
2121
2614
|
{
|
|
@@ -2128,7 +2621,7 @@ function TaskDetailCore({
|
|
|
2128
2621
|
)
|
|
2129
2622
|
] }),
|
|
2130
2623
|
!hidden.has("description") && /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
2131
|
-
/* @__PURE__ */ jsx("label", { htmlFor: "pm-detail-desc", className: labelClass2, children:
|
|
2624
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "pm-detail-desc", className: labelClass2, children: L.description }),
|
|
2132
2625
|
/* @__PURE__ */ jsx(
|
|
2133
2626
|
"textarea",
|
|
2134
2627
|
{
|
|
@@ -2141,7 +2634,7 @@ function TaskDetailCore({
|
|
|
2141
2634
|
] }),
|
|
2142
2635
|
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
|
|
2143
2636
|
!hidden.has("type") && /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
2144
|
-
/* @__PURE__ */ jsx("label", { htmlFor: "pm-detail-type", className: labelClass2, children:
|
|
2637
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "pm-detail-type", className: labelClass2, children: L.typeLabel }),
|
|
2145
2638
|
/* @__PURE__ */ jsx(
|
|
2146
2639
|
"select",
|
|
2147
2640
|
{
|
|
@@ -2149,12 +2642,12 @@ function TaskDetailCore({
|
|
|
2149
2642
|
className: cn(fieldClass2, "capitalize"),
|
|
2150
2643
|
value: type,
|
|
2151
2644
|
onChange: (e) => setType(e.target.value),
|
|
2152
|
-
children: TASK_TYPES.map((t) => /* @__PURE__ */ jsx("option", { value: t, children:
|
|
2645
|
+
children: TASK_TYPES.map((t) => /* @__PURE__ */ jsx("option", { value: t, children: L.type[t] }, t))
|
|
2153
2646
|
}
|
|
2154
2647
|
)
|
|
2155
2648
|
] }),
|
|
2156
2649
|
!hidden.has("status") && /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
2157
|
-
/* @__PURE__ */ jsx("label", { htmlFor: "pm-detail-status", className: labelClass2, children:
|
|
2650
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "pm-detail-status", className: labelClass2, children: L.statusLabel }),
|
|
2158
2651
|
/* @__PURE__ */ jsx(
|
|
2159
2652
|
"select",
|
|
2160
2653
|
{
|
|
@@ -2162,12 +2655,12 @@ function TaskDetailCore({
|
|
|
2162
2655
|
className: cn(fieldClass2, "capitalize"),
|
|
2163
2656
|
value: status,
|
|
2164
2657
|
onChange: (e) => setStatus(e.target.value),
|
|
2165
|
-
children: TASK_STATUSES.map((s) => /* @__PURE__ */ jsx("option", { value: s, children:
|
|
2658
|
+
children: TASK_STATUSES.map((s) => /* @__PURE__ */ jsx("option", { value: s, children: L.status[s] }, s))
|
|
2166
2659
|
}
|
|
2167
2660
|
)
|
|
2168
2661
|
] }),
|
|
2169
2662
|
!hidden.has("priority") && /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
2170
|
-
/* @__PURE__ */ jsx("label", { htmlFor: "pm-detail-priority", className: labelClass2, children:
|
|
2663
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "pm-detail-priority", className: labelClass2, children: L.priorityLabel }),
|
|
2171
2664
|
/* @__PURE__ */ jsx(
|
|
2172
2665
|
"select",
|
|
2173
2666
|
{
|
|
@@ -2175,25 +2668,37 @@ function TaskDetailCore({
|
|
|
2175
2668
|
className: cn(fieldClass2, "capitalize"),
|
|
2176
2669
|
value: priority,
|
|
2177
2670
|
onChange: (e) => setPriority(e.target.value),
|
|
2178
|
-
children: TASK_PRIORITIES.map((p) => /* @__PURE__ */ jsx("option", { value: p, children:
|
|
2671
|
+
children: TASK_PRIORITIES.map((p) => /* @__PURE__ */ jsx("option", { value: p, children: L.priority[p] }, p))
|
|
2179
2672
|
}
|
|
2180
2673
|
)
|
|
2181
2674
|
] }),
|
|
2182
2675
|
!hidden.has("assignee") && /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
2183
|
-
/* @__PURE__ */ jsx("label", { htmlFor: "pm-detail-assignee", className: labelClass2, children:
|
|
2184
|
-
/* @__PURE__ */
|
|
2676
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "pm-detail-assignee", className: labelClass2, children: L.assigneeLabel }),
|
|
2677
|
+
assigneeOptions && assigneeOptions.length > 0 ? /* @__PURE__ */ jsxs(
|
|
2678
|
+
"select",
|
|
2679
|
+
{
|
|
2680
|
+
id: "pm-detail-assignee",
|
|
2681
|
+
className: fieldClass2,
|
|
2682
|
+
value: assigneeId,
|
|
2683
|
+
onChange: (e) => setAssigneeId(e.target.value),
|
|
2684
|
+
children: [
|
|
2685
|
+
/* @__PURE__ */ jsx("option", { value: "", children: L.unassigned }),
|
|
2686
|
+
assigneeOptions.map((o) => /* @__PURE__ */ jsx("option", { value: o.id, children: o.name }, o.id))
|
|
2687
|
+
]
|
|
2688
|
+
}
|
|
2689
|
+
) : /* @__PURE__ */ jsx(
|
|
2185
2690
|
"input",
|
|
2186
2691
|
{
|
|
2187
2692
|
id: "pm-detail-assignee",
|
|
2188
2693
|
className: fieldClass2,
|
|
2189
2694
|
value: assigneeId,
|
|
2190
2695
|
onChange: (e) => setAssigneeId(e.target.value),
|
|
2191
|
-
placeholder:
|
|
2696
|
+
placeholder: L.assigneePlaceholder
|
|
2192
2697
|
}
|
|
2193
2698
|
)
|
|
2194
2699
|
] }),
|
|
2195
2700
|
!hidden.has("dueDate") && /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
2196
|
-
/* @__PURE__ */ jsx("label", { htmlFor: "pm-detail-due", className: labelClass2, children:
|
|
2701
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "pm-detail-due", className: labelClass2, children: L.dueDateLabel }),
|
|
2197
2702
|
/* @__PURE__ */ jsx(
|
|
2198
2703
|
"input",
|
|
2199
2704
|
{
|
|
@@ -2206,7 +2711,7 @@ function TaskDetailCore({
|
|
|
2206
2711
|
)
|
|
2207
2712
|
] }),
|
|
2208
2713
|
!hidden.has("storyPoints") && /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
2209
|
-
/* @__PURE__ */ jsx("label", { htmlFor: "pm-detail-points", className: labelClass2, children:
|
|
2714
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "pm-detail-points", className: labelClass2, children: L.storyPointsLabel }),
|
|
2210
2715
|
/* @__PURE__ */ jsx(
|
|
2211
2716
|
"input",
|
|
2212
2717
|
{
|
|
@@ -2221,7 +2726,7 @@ function TaskDetailCore({
|
|
|
2221
2726
|
] })
|
|
2222
2727
|
] }),
|
|
2223
2728
|
!hidden.has("labels") && /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
2224
|
-
/* @__PURE__ */ jsx("label", { htmlFor: "pm-detail-labels", className: labelClass2, children:
|
|
2729
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "pm-detail-labels", className: labelClass2, children: L.labelsLabel }),
|
|
2225
2730
|
/* @__PURE__ */ jsx(
|
|
2226
2731
|
"input",
|
|
2227
2732
|
{
|
|
@@ -2229,12 +2734,13 @@ function TaskDetailCore({
|
|
|
2229
2734
|
className: fieldClass2,
|
|
2230
2735
|
value: labels,
|
|
2231
2736
|
onChange: (e) => setLabels(e.target.value),
|
|
2232
|
-
placeholder:
|
|
2737
|
+
placeholder: L.labelsPlaceholder
|
|
2233
2738
|
}
|
|
2234
2739
|
)
|
|
2235
2740
|
] }),
|
|
2236
2741
|
saveError && /* @__PURE__ */ jsxs("p", { className: "text-sm text-destructive", children: [
|
|
2237
|
-
|
|
2742
|
+
L.failedToSave,
|
|
2743
|
+
": ",
|
|
2238
2744
|
saveError.message
|
|
2239
2745
|
] }),
|
|
2240
2746
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-2", children: [
|
|
@@ -2244,7 +2750,7 @@ function TaskDetailCore({
|
|
|
2244
2750
|
type: "button",
|
|
2245
2751
|
onClick: () => setEditing(false),
|
|
2246
2752
|
className: "rounded-md bg-muted px-4 py-2 text-sm font-medium text-muted-foreground hover:bg-muted/70",
|
|
2247
|
-
children:
|
|
2753
|
+
children: L.cancel
|
|
2248
2754
|
}
|
|
2249
2755
|
),
|
|
2250
2756
|
/* @__PURE__ */ jsx(
|
|
@@ -2256,7 +2762,7 @@ function TaskDetailCore({
|
|
|
2256
2762
|
"rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground",
|
|
2257
2763
|
(saving || !title.trim()) && "cursor-not-allowed opacity-50"
|
|
2258
2764
|
),
|
|
2259
|
-
children: saving ?
|
|
2765
|
+
children: saving ? L.saving : L.save
|
|
2260
2766
|
}
|
|
2261
2767
|
)
|
|
2262
2768
|
] })
|
|
@@ -2307,6 +2813,11 @@ function TasksPageCore({
|
|
|
2307
2813
|
views,
|
|
2308
2814
|
defaultView = "board",
|
|
2309
2815
|
resolveAssignee,
|
|
2816
|
+
linkSourceProduct,
|
|
2817
|
+
renderLinkIcon,
|
|
2818
|
+
assigneeOptions,
|
|
2819
|
+
currentActorId,
|
|
2820
|
+
labels,
|
|
2310
2821
|
header,
|
|
2311
2822
|
onTaskSaved,
|
|
2312
2823
|
createSurface = "modal",
|
|
@@ -2316,10 +2827,12 @@ function TasksPageCore({
|
|
|
2316
2827
|
const ctx = usePlanMagnetContextSafe();
|
|
2317
2828
|
const workspaceId = workspaceIdProp ?? ctx?.workspaceId;
|
|
2318
2829
|
const client = useApolloClient();
|
|
2830
|
+
const mergedLabels = mergeTaskLabels(labels);
|
|
2319
2831
|
const [view, setView] = useState(defaultView);
|
|
2320
2832
|
const [search, setSearch] = useState("");
|
|
2321
2833
|
const [priority, setPriority] = useState("ALL");
|
|
2322
2834
|
const [type, setType] = useState("ALL");
|
|
2835
|
+
const [mine, setMine] = useState(false);
|
|
2323
2836
|
const [creating, setCreating] = useState(false);
|
|
2324
2837
|
const [selectedId, setSelectedId] = useState(null);
|
|
2325
2838
|
const refetchBoard = useCallback(() => {
|
|
@@ -2341,6 +2854,9 @@ function TasksPageCore({
|
|
|
2341
2854
|
},
|
|
2342
2855
|
[refetchBoard, onTaskSaved]
|
|
2343
2856
|
);
|
|
2857
|
+
const handleDeleted = useCallback(() => {
|
|
2858
|
+
setSelectedId(null);
|
|
2859
|
+
}, []);
|
|
2344
2860
|
const handleTaskClick = useCallback((task) => {
|
|
2345
2861
|
setSelectedId(task.id);
|
|
2346
2862
|
}, []);
|
|
@@ -2356,6 +2872,7 @@ function TasksPageCore({
|
|
|
2356
2872
|
{
|
|
2357
2873
|
workspaceId,
|
|
2358
2874
|
projectId,
|
|
2875
|
+
assigneeOptions,
|
|
2359
2876
|
hiddenFields,
|
|
2360
2877
|
onCreated: handleCreated,
|
|
2361
2878
|
onCancel: () => setCreating(false)
|
|
@@ -2367,12 +2884,24 @@ function TasksPageCore({
|
|
|
2367
2884
|
id: selectedId,
|
|
2368
2885
|
readonly,
|
|
2369
2886
|
hiddenFields,
|
|
2370
|
-
|
|
2887
|
+
resolveAssignee,
|
|
2888
|
+
assigneeOptions,
|
|
2889
|
+
onUpdated: handleUpdated,
|
|
2890
|
+
onDeleted: handleDeleted
|
|
2371
2891
|
}
|
|
2372
2892
|
) : null;
|
|
2373
2893
|
const listPriority = priority === "ALL" ? void 0 : priority;
|
|
2374
2894
|
const listType = type === "ALL" ? void 0 : type;
|
|
2375
|
-
|
|
2895
|
+
const mineAssignee = mine && currentActorId ? currentActorId : void 0;
|
|
2896
|
+
const listColumns = linkSourceProduct ? [
|
|
2897
|
+
"title",
|
|
2898
|
+
"status",
|
|
2899
|
+
"priority",
|
|
2900
|
+
"assignee",
|
|
2901
|
+
"dueDate",
|
|
2902
|
+
"linkedRecord"
|
|
2903
|
+
] : void 0;
|
|
2904
|
+
return /* @__PURE__ */ jsx(TaskLabelsProvider, { value: mergedLabels, children: /* @__PURE__ */ jsxs("div", { className: cn("space-y-4 p-6", className), children: [
|
|
2376
2905
|
header && /* @__PURE__ */ jsx("div", { className: "min-w-0", children: typeof header === "string" ? /* @__PURE__ */ jsx("h1", { className: "truncate text-2xl font-semibold text-foreground", children: header }) : header }),
|
|
2377
2906
|
/* @__PURE__ */ jsx(
|
|
2378
2907
|
TaskToolbar,
|
|
@@ -2387,7 +2916,9 @@ function TasksPageCore({
|
|
|
2387
2916
|
type,
|
|
2388
2917
|
onTypeChange: setType,
|
|
2389
2918
|
onNewTask: () => setCreating(true),
|
|
2390
|
-
canCreate
|
|
2919
|
+
canCreate,
|
|
2920
|
+
mine,
|
|
2921
|
+
onMineChange: currentActorId ? setMine : void 0
|
|
2391
2922
|
}
|
|
2392
2923
|
),
|
|
2393
2924
|
showInlineCreate && /* @__PURE__ */ jsx("div", { children: createForm }),
|
|
@@ -2402,8 +2933,11 @@ function TasksPageCore({
|
|
|
2402
2933
|
priority,
|
|
2403
2934
|
type,
|
|
2404
2935
|
search,
|
|
2936
|
+
assigneeId: mineAssignee,
|
|
2405
2937
|
hiddenFields,
|
|
2406
2938
|
resolveAssignee,
|
|
2939
|
+
linkSourceProduct,
|
|
2940
|
+
renderLinkIcon,
|
|
2407
2941
|
onTaskClick: handleTaskClick
|
|
2408
2942
|
}
|
|
2409
2943
|
),
|
|
@@ -2415,8 +2949,12 @@ function TasksPageCore({
|
|
|
2415
2949
|
priority: listPriority,
|
|
2416
2950
|
type: listType,
|
|
2417
2951
|
search: search || void 0,
|
|
2952
|
+
assigneeId: mineAssignee,
|
|
2418
2953
|
hideHeader: true,
|
|
2419
2954
|
resolveAssignee,
|
|
2955
|
+
linkSourceProduct,
|
|
2956
|
+
renderLinkIcon,
|
|
2957
|
+
columns: listColumns ? [...listColumns] : void 0,
|
|
2420
2958
|
onSelect: handleSelect
|
|
2421
2959
|
}
|
|
2422
2960
|
),
|
|
@@ -2428,6 +2966,7 @@ function TasksPageCore({
|
|
|
2428
2966
|
priority,
|
|
2429
2967
|
type,
|
|
2430
2968
|
search,
|
|
2969
|
+
assigneeId: mineAssignee,
|
|
2431
2970
|
resolveAssignee,
|
|
2432
2971
|
onSelect: handleSelect
|
|
2433
2972
|
}
|
|
@@ -2452,7 +2991,7 @@ function TasksPageCore({
|
|
|
2452
2991
|
children: /* @__PURE__ */ jsx("div", { className: "p-2 pt-8", children: detailView })
|
|
2453
2992
|
}
|
|
2454
2993
|
)
|
|
2455
|
-
] });
|
|
2994
|
+
] }) });
|
|
2456
2995
|
}
|
|
2457
2996
|
function TasksPage({
|
|
2458
2997
|
apiGatewayUrl,
|
|
@@ -2483,6 +3022,6 @@ function TasksPage({
|
|
|
2483
3022
|
);
|
|
2484
3023
|
}
|
|
2485
3024
|
|
|
2486
|
-
export { Avatar, Badge, CREATE_WORK_ITEM, CreateTask, CreateTaskCore, DEFAULT_BOARD_COLUMNS, Drawer, GET_PROJECTS, GET_WORK_ITEM, LIST_WORK_ITEMS, MOVE_WORK_ITEM, Modal, PRIORITY_META, PROJECT_SUMMARY_FIELDS, PlanMagnetProvider, PriorityIndicator, STATUS_META, StatusIcon, StatusPill, TASK_PRIORITIES, TASK_STATUSES, TASK_TYPES, TaskBoard, TaskBoardCore, TaskCard, TaskDetail, TaskDetailCore, TaskList, TaskListCore, TaskTimelineCore, TaskToolbar, TasksPage, TasksPageCore, TypeBadge, UPDATE_WORK_ITEM, WORK_ITEM_FIELDS, WORK_ITEM_SUMMARY_FIELDS, badgeVariants, cn, config, createPlanMagnetClient, enumLabel, getGraphQLEndpoint, getPlanMagnetClient, getPlanMagnetClientSafe, getPlanMagnetConfig, isPlanMagnetClientReady, resetPlanMagnetClient, resetPlanMagnetConfig, setPlanMagnetClient, setPlanMagnetConfig, usePlanMagnetContext, usePlanMagnetContextSafe, validateTrustedOrigin, waitForPlanMagnetClient };
|
|
3025
|
+
export { Avatar, Badge, CREATE_WORK_ITEM, CREATE_WORK_ITEM_LINK, CreateTask, CreateTaskCore, DEFAULT_BOARD_COLUMNS, DEFAULT_TASK_LABELS, DELETE_WORK_ITEM, DELETE_WORK_ITEM_LINK, Drawer, GET_PROJECTS, GET_WORK_ITEM, LIST_MILESTONES, LIST_WORK_ITEMS, LIST_WORK_ITEM_LINKS, LinkChip, MILESTONE_FIELDS, MOVE_WORK_ITEM, Modal, PRIORITY_META, PROJECT_SUMMARY_FIELDS, PlanMagnetProvider, PriorityIndicator, STATUS_META, StatusIcon, StatusPill, TASK_PRIORITIES, TASK_STATUSES, TASK_TYPES, TaskBoard, TaskBoardCore, TaskCard, TaskDetail, TaskDetailCore, TaskLabelsProvider, TaskList, TaskListCore, TaskTimelineCore, TaskToolbar, TasksPage, TasksPageCore, TypeBadge, UPDATE_WORK_ITEM, WORK_ITEM_FIELDS, WORK_ITEM_LINK_FIELDS, WORK_ITEM_SUMMARY_FIELDS, badgeVariants, cn, config, createPlanMagnetClient, enumLabel, getGraphQLEndpoint, getPlanMagnetClient, getPlanMagnetClientSafe, getPlanMagnetConfig, isPlanMagnetClientReady, mergeTaskLabels, resetPlanMagnetClient, resetPlanMagnetConfig, setPlanMagnetClient, setPlanMagnetConfig, useMilestones, usePlanMagnetContext, usePlanMagnetContextSafe, useTaskLabels, useWorkItemLinks, validateTrustedOrigin, waitForPlanMagnetClient };
|
|
2487
3026
|
//# sourceMappingURL=index.js.map
|
|
2488
3027
|
//# sourceMappingURL=index.js.map
|