@burdenoff/planmagnet-fe-sdk 2026.704.4 → 2026.705.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 +11 -1
- package/dist/index.js +102 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -810,6 +810,13 @@ interface TaskDetailCoreProps {
|
|
|
810
810
|
linkSourceProduct?: string;
|
|
811
811
|
/** Optional host hook to render an icon per linked-entity type. */
|
|
812
812
|
renderLinkIcon?: RenderLinkIcon;
|
|
813
|
+
/** Open another work item's detail (parent link / sub-task row click). */
|
|
814
|
+
onOpenItem?: (id: string) => void;
|
|
815
|
+
/** Start creating a sub-task under this item (the "Add sub-task" affordance). */
|
|
816
|
+
onAddSubtask?: (parent: {
|
|
817
|
+
id: string;
|
|
818
|
+
projectId: string;
|
|
819
|
+
}) => void;
|
|
813
820
|
/** Extra classes on the root container. */
|
|
814
821
|
className?: string;
|
|
815
822
|
}
|
|
@@ -818,7 +825,7 @@ interface TaskDetailCoreProps {
|
|
|
818
825
|
* edit. Fetches via `planmagnetWorkItem(id)`, saves via
|
|
819
826
|
* `planmagnetUpdateWorkItem`. BYO-Apollo, semantic-token only, farm-free.
|
|
820
827
|
*/
|
|
821
|
-
declare function TaskDetailCore({ id, readonly, hiddenFields, hideHeader, onUpdated, onDeleted, onError, resolveAssignee, assigneeOptions, linkSourceProduct, renderLinkIcon, className, }: TaskDetailCoreProps): react.JSX.Element;
|
|
828
|
+
declare function TaskDetailCore({ id, readonly, hiddenFields, hideHeader, onUpdated, onDeleted, onError, resolveAssignee, assigneeOptions, linkSourceProduct, renderLinkIcon, onOpenItem, onAddSubtask, className, }: TaskDetailCoreProps): react.JSX.Element;
|
|
822
829
|
|
|
823
830
|
interface TaskDetailProps extends TaskDetailCoreProps {
|
|
824
831
|
/** Workspace API gateway URL (URL mode). */
|
|
@@ -918,6 +925,9 @@ interface TaskLabels {
|
|
|
918
925
|
linkedRecordsLabel: string;
|
|
919
926
|
createdLabel: string;
|
|
920
927
|
updatedLabel: string;
|
|
928
|
+
parentLabel: string;
|
|
929
|
+
subtasksLabel: string;
|
|
930
|
+
addSubtask: string;
|
|
921
931
|
create: string;
|
|
922
932
|
creating: string;
|
|
923
933
|
cancel: string;
|
package/dist/index.js
CHANGED
|
@@ -748,6 +748,9 @@ var DEFAULT_TASK_LABELS = {
|
|
|
748
748
|
linkedRecordsLabel: "Linked records",
|
|
749
749
|
createdLabel: "Created",
|
|
750
750
|
updatedLabel: "Updated",
|
|
751
|
+
parentLabel: "Parent",
|
|
752
|
+
subtasksLabel: "Sub-tasks",
|
|
753
|
+
addSubtask: "Add sub-task",
|
|
751
754
|
create: "Create task",
|
|
752
755
|
creating: "Creating\u2026",
|
|
753
756
|
cancel: "Cancel",
|
|
@@ -1370,6 +1373,10 @@ function CreateTaskCore({
|
|
|
1370
1373
|
projectId,
|
|
1371
1374
|
title: title.trim(),
|
|
1372
1375
|
type,
|
|
1376
|
+
// Sub-task linkage: parentId is not an editable form field — it rides
|
|
1377
|
+
// through from defaultValues (the "Add sub-task" flow) so a created work
|
|
1378
|
+
// item nests under its parent.
|
|
1379
|
+
...defaultValues?.parentId ? { parentId: defaultValues.parentId } : {},
|
|
1373
1380
|
...hidden.has("status") ? {} : { status },
|
|
1374
1381
|
...hidden.has("priority") ? {} : { priority },
|
|
1375
1382
|
...hidden.has("description") || !description.trim() ? {} : { description: description.trim() },
|
|
@@ -2468,6 +2475,8 @@ function TaskDetailCore({
|
|
|
2468
2475
|
assigneeOptions,
|
|
2469
2476
|
linkSourceProduct,
|
|
2470
2477
|
renderLinkIcon,
|
|
2478
|
+
onOpenItem,
|
|
2479
|
+
onAddSubtask,
|
|
2471
2480
|
className
|
|
2472
2481
|
}) {
|
|
2473
2482
|
const client = useApolloClient();
|
|
@@ -2486,6 +2495,20 @@ function TaskDetailCore({
|
|
|
2486
2495
|
linkSourceProduct
|
|
2487
2496
|
);
|
|
2488
2497
|
const links = item ? linksByItem.get(item.id) ?? [] : [];
|
|
2498
|
+
const { data: parentData } = useQuery(GET_WORK_ITEM, {
|
|
2499
|
+
variables: { id: item?.parentId },
|
|
2500
|
+
skip: !item?.parentId
|
|
2501
|
+
});
|
|
2502
|
+
const parent = parentData?.planmagnetWorkItem ?? null;
|
|
2503
|
+
const { data: childData } = useQuery(LIST_WORK_ITEMS, {
|
|
2504
|
+
variables: {
|
|
2505
|
+
workspaceId: item?.workspaceId,
|
|
2506
|
+
filter: { parentId: item?.id },
|
|
2507
|
+
pagination: { first: 100 }
|
|
2508
|
+
},
|
|
2509
|
+
skip: !item?.id || !item?.workspaceId
|
|
2510
|
+
});
|
|
2511
|
+
const children = childData?.planmagnetWorkItems?.items ?? [];
|
|
2489
2512
|
const [editing, setEditing] = useState(false);
|
|
2490
2513
|
const [confirmingDelete, setConfirmingDelete] = useState(false);
|
|
2491
2514
|
const [title, setTitle] = useState("");
|
|
@@ -2681,6 +2704,56 @@ function TaskDetailCore({
|
|
|
2681
2704
|
link.id
|
|
2682
2705
|
)) })
|
|
2683
2706
|
] }),
|
|
2707
|
+
parent && /* @__PURE__ */ jsxs("div", { className: "sm:col-span-2", children: [
|
|
2708
|
+
/* @__PURE__ */ jsx("dt", { className: labelClass2, children: L.parentLabel }),
|
|
2709
|
+
/* @__PURE__ */ jsx("dd", { className: "mt-1", children: /* @__PURE__ */ jsxs(
|
|
2710
|
+
"button",
|
|
2711
|
+
{
|
|
2712
|
+
type: "button",
|
|
2713
|
+
onClick: () => onOpenItem?.(parent.id),
|
|
2714
|
+
className: "inline-flex max-w-full items-center gap-1.5 rounded-md border border-border bg-muted/40 px-2 py-1 text-sm text-foreground hover:bg-muted",
|
|
2715
|
+
children: [
|
|
2716
|
+
/* @__PURE__ */ jsx(StatusIcon, { status: parent.status }),
|
|
2717
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: parent.key }),
|
|
2718
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: parent.title })
|
|
2719
|
+
]
|
|
2720
|
+
}
|
|
2721
|
+
) })
|
|
2722
|
+
] }),
|
|
2723
|
+
(children.length > 0 || onAddSubtask && canEdit) && /* @__PURE__ */ jsxs("div", { className: "sm:col-span-2", children: [
|
|
2724
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
2725
|
+
/* @__PURE__ */ jsxs("dt", { className: labelClass2, children: [
|
|
2726
|
+
L.subtasksLabel,
|
|
2727
|
+
children.length > 0 ? ` (${children.length})` : ""
|
|
2728
|
+
] }),
|
|
2729
|
+
onAddSubtask && canEdit && /* @__PURE__ */ jsxs(
|
|
2730
|
+
"button",
|
|
2731
|
+
{
|
|
2732
|
+
type: "button",
|
|
2733
|
+
onClick: () => onAddSubtask({ id: item.id, projectId: item.projectId }),
|
|
2734
|
+
className: "text-xs font-medium text-primary hover:underline",
|
|
2735
|
+
children: [
|
|
2736
|
+
"+ ",
|
|
2737
|
+
L.addSubtask
|
|
2738
|
+
]
|
|
2739
|
+
}
|
|
2740
|
+
)
|
|
2741
|
+
] }),
|
|
2742
|
+
/* @__PURE__ */ jsx("dd", { className: "mt-1 space-y-1", children: children.length === 0 ? /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: "\u2014" }) : children.map((c) => /* @__PURE__ */ jsxs(
|
|
2743
|
+
"button",
|
|
2744
|
+
{
|
|
2745
|
+
type: "button",
|
|
2746
|
+
onClick: () => onOpenItem?.(c.id),
|
|
2747
|
+
className: "flex w-full items-center gap-2 rounded-md px-2 py-1 text-left text-sm hover:bg-muted",
|
|
2748
|
+
children: [
|
|
2749
|
+
/* @__PURE__ */ jsx(StatusIcon, { status: c.status }),
|
|
2750
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: c.key }),
|
|
2751
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 truncate text-foreground", children: c.title })
|
|
2752
|
+
]
|
|
2753
|
+
},
|
|
2754
|
+
c.id
|
|
2755
|
+
)) })
|
|
2756
|
+
] }),
|
|
2684
2757
|
(item.createdAt || item.updatedAt) && /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-x-6 gap-y-1 border-t border-border pt-3 text-xs text-muted-foreground sm:col-span-2", children: [
|
|
2685
2758
|
item.createdAt && /* @__PURE__ */ jsxs("span", { children: [
|
|
2686
2759
|
L.createdLabel,
|
|
@@ -2924,6 +2997,7 @@ function TasksPageCore({
|
|
|
2924
2997
|
const [mine, setMine] = useState(false);
|
|
2925
2998
|
const [creating, setCreating] = useState(false);
|
|
2926
2999
|
const [selectedId, setSelectedId] = useState(null);
|
|
3000
|
+
const [createDefaults, setCreateDefaults] = useState(null);
|
|
2927
3001
|
useEffect(() => {
|
|
2928
3002
|
if (openItemId) setSelectedId(openItemId);
|
|
2929
3003
|
}, [openItemId]);
|
|
@@ -2935,10 +3009,31 @@ function TasksPageCore({
|
|
|
2935
3009
|
(workItem) => {
|
|
2936
3010
|
refetchBoard();
|
|
2937
3011
|
setCreating(false);
|
|
3012
|
+
setCreateDefaults(null);
|
|
2938
3013
|
onTaskSaved?.({ workItem, operation: "created" });
|
|
2939
3014
|
},
|
|
2940
3015
|
[refetchBoard, onTaskSaved]
|
|
2941
3016
|
);
|
|
3017
|
+
const handleAddSubtask = useCallback(
|
|
3018
|
+
(parent) => {
|
|
3019
|
+
setSelectedId(null);
|
|
3020
|
+
setCreateDefaults({
|
|
3021
|
+
parentId: parent.id,
|
|
3022
|
+
projectId: parent.projectId,
|
|
3023
|
+
type: "SUB_TASK"
|
|
3024
|
+
});
|
|
3025
|
+
setCreating(true);
|
|
3026
|
+
},
|
|
3027
|
+
[]
|
|
3028
|
+
);
|
|
3029
|
+
const startCreate = useCallback(() => {
|
|
3030
|
+
setCreateDefaults(null);
|
|
3031
|
+
setCreating(true);
|
|
3032
|
+
}, []);
|
|
3033
|
+
const cancelCreate = useCallback(() => {
|
|
3034
|
+
setCreating(false);
|
|
3035
|
+
setCreateDefaults(null);
|
|
3036
|
+
}, []);
|
|
2942
3037
|
const handleUpdated = useCallback(
|
|
2943
3038
|
(workItem) => {
|
|
2944
3039
|
refetchBoard();
|
|
@@ -2966,8 +3061,9 @@ function TasksPageCore({
|
|
|
2966
3061
|
projectId,
|
|
2967
3062
|
assigneeOptions,
|
|
2968
3063
|
hiddenFields,
|
|
3064
|
+
defaultValues: createDefaults ?? void 0,
|
|
2969
3065
|
onCreated: handleCreated,
|
|
2970
|
-
onCancel:
|
|
3066
|
+
onCancel: cancelCreate
|
|
2971
3067
|
}
|
|
2972
3068
|
);
|
|
2973
3069
|
const detailView = selectedId != null ? /* @__PURE__ */ jsx(
|
|
@@ -2981,7 +3077,9 @@ function TasksPageCore({
|
|
|
2981
3077
|
linkSourceProduct,
|
|
2982
3078
|
renderLinkIcon,
|
|
2983
3079
|
onUpdated: handleUpdated,
|
|
2984
|
-
onDeleted: handleDeleted
|
|
3080
|
+
onDeleted: handleDeleted,
|
|
3081
|
+
onOpenItem: handleSelect,
|
|
3082
|
+
onAddSubtask: handleAddSubtask
|
|
2985
3083
|
}
|
|
2986
3084
|
) : null;
|
|
2987
3085
|
const listPriority = priority === "ALL" ? void 0 : priority;
|
|
@@ -3009,7 +3107,7 @@ function TasksPageCore({
|
|
|
3009
3107
|
onPriorityChange: setPriority,
|
|
3010
3108
|
type,
|
|
3011
3109
|
onTypeChange: setType,
|
|
3012
|
-
onNewTask:
|
|
3110
|
+
onNewTask: startCreate,
|
|
3013
3111
|
canCreate,
|
|
3014
3112
|
mine,
|
|
3015
3113
|
onMineChange: currentActorId ? setMine : void 0
|
|
@@ -3071,7 +3169,7 @@ function TasksPageCore({
|
|
|
3071
3169
|
Modal,
|
|
3072
3170
|
{
|
|
3073
3171
|
open: creating,
|
|
3074
|
-
onClose:
|
|
3172
|
+
onClose: cancelCreate,
|
|
3075
3173
|
ariaLabel: "Create task",
|
|
3076
3174
|
className: "max-w-xl",
|
|
3077
3175
|
children: /* @__PURE__ */ jsx("div", { className: "p-2 pt-8", children: createForm })
|