@burdenoff/planmagnet-fe-sdk 2026.703.2 → 2026.703.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/index.d.ts +230 -113
- package/dist/index.js +165 -5
- 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, CalendarRange, List, LayoutGrid, Search, Plus } 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,63 @@ 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
|
+
`;
|
|
413
470
|
function cn(...inputs) {
|
|
414
471
|
return twMerge(clsx(inputs));
|
|
415
472
|
}
|
|
@@ -552,6 +609,36 @@ var TASK_STATUSES = [
|
|
|
552
609
|
function enumLabel(value) {
|
|
553
610
|
return value.toLowerCase().replace(/_/g, " ");
|
|
554
611
|
}
|
|
612
|
+
function LinkChip({ link, renderIcon, className }) {
|
|
613
|
+
const label = link.displayNameSnapshot || enumLabel(link.entityType);
|
|
614
|
+
const icon = renderIcon?.(link.entityType) ?? /* @__PURE__ */ jsx(Link2, { className: "h-3 w-3 shrink-0", "aria-hidden": "true" });
|
|
615
|
+
const body = /* @__PURE__ */ jsxs(
|
|
616
|
+
"span",
|
|
617
|
+
{
|
|
618
|
+
className: cn(
|
|
619
|
+
"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",
|
|
620
|
+
className
|
|
621
|
+
),
|
|
622
|
+
title: `${enumLabel(link.relationType)} \xB7 ${enumLabel(link.entityType)}`,
|
|
623
|
+
children: [
|
|
624
|
+
icon,
|
|
625
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: label })
|
|
626
|
+
]
|
|
627
|
+
}
|
|
628
|
+
);
|
|
629
|
+
if (link.deepLinkSnapshot) {
|
|
630
|
+
return /* @__PURE__ */ jsx(
|
|
631
|
+
"a",
|
|
632
|
+
{
|
|
633
|
+
href: link.deepLinkSnapshot,
|
|
634
|
+
onClick: (e) => e.stopPropagation(),
|
|
635
|
+
className: "inline-flex max-w-full no-underline hover:brightness-95",
|
|
636
|
+
children: body
|
|
637
|
+
}
|
|
638
|
+
);
|
|
639
|
+
}
|
|
640
|
+
return body;
|
|
641
|
+
}
|
|
555
642
|
var STATUS_META = {
|
|
556
643
|
BACKLOG: { icon: CircleDashed, tone: "text-muted-foreground/60" },
|
|
557
644
|
TODO: { icon: Circle, tone: "text-muted-foreground" },
|
|
@@ -705,12 +792,15 @@ function TaskCard({
|
|
|
705
792
|
onDragEnd,
|
|
706
793
|
dragging,
|
|
707
794
|
resolveAssignee,
|
|
795
|
+
links,
|
|
796
|
+
renderLinkIcon,
|
|
708
797
|
className
|
|
709
798
|
}) {
|
|
710
799
|
const overdue = isOverdue(task.dueDate, task.status);
|
|
711
800
|
const due = formatDueDate(task.dueDate);
|
|
712
801
|
const resolved = task.assigneeId ? resolveAssignee?.(task.assigneeId) : null;
|
|
713
802
|
const showTopRow = !hidden.has("key") || !hidden.has("type");
|
|
803
|
+
const showLinks = !hidden.has("links") && (links?.length ?? 0) > 0;
|
|
714
804
|
const showLabels = !hidden.has("labels") && (task.labels?.length ?? 0) > 0;
|
|
715
805
|
const showPriority = !hidden.has("priority");
|
|
716
806
|
const showPoints = !hidden.has("storyPoints") && task.storyPoints != null;
|
|
@@ -749,6 +839,13 @@ function TaskCard({
|
|
|
749
839
|
!hidden.has("type") && /* @__PURE__ */ jsx(TypeBadge, { type: task.type })
|
|
750
840
|
] }),
|
|
751
841
|
/* @__PURE__ */ jsx("p", { className: "line-clamp-2 text-sm font-medium leading-snug text-foreground", children: task.title }),
|
|
842
|
+
showLinks && /* @__PURE__ */ jsxs("div", { className: "mt-1.5 flex flex-wrap gap-1", children: [
|
|
843
|
+
links.slice(0, 3).map((link) => /* @__PURE__ */ jsx(LinkChip, { link, renderIcon: renderLinkIcon }, link.id)),
|
|
844
|
+
links.length > 3 && /* @__PURE__ */ jsxs("span", { className: "text-[10px] text-muted-foreground", children: [
|
|
845
|
+
"+",
|
|
846
|
+
links.length - 3
|
|
847
|
+
] })
|
|
848
|
+
] }),
|
|
752
849
|
showLabels && /* @__PURE__ */ jsxs("div", { className: "mt-1.5 flex flex-wrap gap-1", children: [
|
|
753
850
|
task.labels.slice(0, 3).map((l) => /* @__PURE__ */ jsx(
|
|
754
851
|
"span",
|
|
@@ -798,6 +895,29 @@ function TaskCard({
|
|
|
798
895
|
}
|
|
799
896
|
);
|
|
800
897
|
}
|
|
898
|
+
function useWorkItemLinks(workspaceId, sourceProduct, limit = 500) {
|
|
899
|
+
const { data, loading } = useQuery(
|
|
900
|
+
LIST_WORK_ITEM_LINKS,
|
|
901
|
+
{
|
|
902
|
+
variables: {
|
|
903
|
+
workspaceId,
|
|
904
|
+
...sourceProduct ? { filter: { sourceProduct } } : {},
|
|
905
|
+
pagination: { first: limit }
|
|
906
|
+
},
|
|
907
|
+
skip: !workspaceId || !sourceProduct
|
|
908
|
+
}
|
|
909
|
+
);
|
|
910
|
+
const linksByItem = useMemo(() => {
|
|
911
|
+
const map = /* @__PURE__ */ new Map();
|
|
912
|
+
for (const link of data?.planmagnetWorkItemLinks?.items ?? []) {
|
|
913
|
+
const arr = map.get(link.workItemId);
|
|
914
|
+
if (arr) arr.push(link);
|
|
915
|
+
else map.set(link.workItemId, [link]);
|
|
916
|
+
}
|
|
917
|
+
return map;
|
|
918
|
+
}, [data]);
|
|
919
|
+
return { linksByItem, loading };
|
|
920
|
+
}
|
|
801
921
|
function TaskBoardCore({
|
|
802
922
|
projectId,
|
|
803
923
|
columns = DEFAULT_BOARD_COLUMNS,
|
|
@@ -809,6 +929,8 @@ function TaskBoardCore({
|
|
|
809
929
|
assigneeId,
|
|
810
930
|
hiddenFields,
|
|
811
931
|
resolveAssignee,
|
|
932
|
+
linkSourceProduct,
|
|
933
|
+
renderLinkIcon,
|
|
812
934
|
onTaskClick,
|
|
813
935
|
className,
|
|
814
936
|
workspaceId: workspaceIdProp
|
|
@@ -817,6 +939,7 @@ function TaskBoardCore({
|
|
|
817
939
|
const workspaceId = workspaceIdProp ?? ctx?.workspaceId;
|
|
818
940
|
const client = useApolloClient();
|
|
819
941
|
const hidden = useMemo(() => new Set(hiddenFields ?? []), [hiddenFields]);
|
|
942
|
+
const { linksByItem } = useWorkItemLinks(workspaceId, linkSourceProduct);
|
|
820
943
|
const [draggingId, setDraggingId] = useState(null);
|
|
821
944
|
const [dragOver, setDragOver] = useState(null);
|
|
822
945
|
const [moveError, setMoveError] = useState(null);
|
|
@@ -927,6 +1050,8 @@ function TaskBoardCore({
|
|
|
927
1050
|
draggable: canDrag,
|
|
928
1051
|
dragging: draggingId === task.id,
|
|
929
1052
|
resolveAssignee,
|
|
1053
|
+
links: linksByItem.get(task.id),
|
|
1054
|
+
renderLinkIcon,
|
|
930
1055
|
onDragStart: (t, e) => {
|
|
931
1056
|
setDraggingId(t.id);
|
|
932
1057
|
e.dataTransfer.effectAllowed = "move";
|
|
@@ -1292,6 +1417,7 @@ var COLUMN_LABELS = {
|
|
|
1292
1417
|
assignee: "Assignee",
|
|
1293
1418
|
dueDate: "Due Date",
|
|
1294
1419
|
storyPoints: "Points",
|
|
1420
|
+
linkedRecord: "Linked Record",
|
|
1295
1421
|
labels: "Labels"
|
|
1296
1422
|
};
|
|
1297
1423
|
var COLUMN_SORT = {
|
|
@@ -1315,12 +1441,15 @@ function TaskListCore({
|
|
|
1315
1441
|
hideHeader,
|
|
1316
1442
|
onSelect,
|
|
1317
1443
|
resolveAssignee,
|
|
1444
|
+
linkSourceProduct,
|
|
1445
|
+
renderLinkIcon,
|
|
1318
1446
|
limit = 200,
|
|
1319
1447
|
className,
|
|
1320
1448
|
workspaceId: workspaceIdProp
|
|
1321
1449
|
}) {
|
|
1322
1450
|
const ctx = usePlanMagnetContextSafe();
|
|
1323
1451
|
const workspaceId = workspaceIdProp ?? ctx?.workspaceId;
|
|
1452
|
+
const { linksByItem } = useWorkItemLinks(workspaceId, linkSourceProduct);
|
|
1324
1453
|
const [sort, setSort] = useState({
|
|
1325
1454
|
by: sortBy ?? null,
|
|
1326
1455
|
dir: sortDir
|
|
@@ -1422,7 +1551,11 @@ function TaskListCore({
|
|
|
1422
1551
|
"td",
|
|
1423
1552
|
{
|
|
1424
1553
|
className: "px-3 py-2 align-middle text-foreground",
|
|
1425
|
-
children: renderCell(col, task,
|
|
1554
|
+
children: renderCell(col, task, {
|
|
1555
|
+
resolveAssignee,
|
|
1556
|
+
links: linksByItem.get(task.id),
|
|
1557
|
+
renderLinkIcon
|
|
1558
|
+
})
|
|
1426
1559
|
},
|
|
1427
1560
|
col
|
|
1428
1561
|
))
|
|
@@ -1433,7 +1566,8 @@ function TaskListCore({
|
|
|
1433
1566
|
] }) })
|
|
1434
1567
|
] });
|
|
1435
1568
|
}
|
|
1436
|
-
function renderCell(col, task,
|
|
1569
|
+
function renderCell(col, task, opts) {
|
|
1570
|
+
const { resolveAssignee, links, renderLinkIcon } = opts;
|
|
1437
1571
|
switch (col) {
|
|
1438
1572
|
case "key":
|
|
1439
1573
|
return /* @__PURE__ */ jsx("span", { className: "font-mono text-xs text-muted-foreground", children: task.key });
|
|
@@ -1471,6 +1605,17 @@ function renderCell(col, task, resolveAssignee) {
|
|
|
1471
1605
|
}
|
|
1472
1606
|
case "storyPoints":
|
|
1473
1607
|
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" });
|
|
1608
|
+
case "linkedRecord":
|
|
1609
|
+
if (!links || links.length === 0) {
|
|
1610
|
+
return /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "\u2014" });
|
|
1611
|
+
}
|
|
1612
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-1", children: [
|
|
1613
|
+
links.slice(0, 2).map((link) => /* @__PURE__ */ jsx(LinkChip, { link, renderIcon: renderLinkIcon }, link.id)),
|
|
1614
|
+
links.length > 2 && /* @__PURE__ */ jsxs("span", { className: "text-[10px] text-muted-foreground", children: [
|
|
1615
|
+
"+",
|
|
1616
|
+
links.length - 2
|
|
1617
|
+
] })
|
|
1618
|
+
] });
|
|
1474
1619
|
case "labels":
|
|
1475
1620
|
return /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1", children: (task.labels ?? []).slice(0, 3).map((l) => /* @__PURE__ */ jsx(
|
|
1476
1621
|
"span",
|
|
@@ -2307,6 +2452,8 @@ function TasksPageCore({
|
|
|
2307
2452
|
views,
|
|
2308
2453
|
defaultView = "board",
|
|
2309
2454
|
resolveAssignee,
|
|
2455
|
+
linkSourceProduct,
|
|
2456
|
+
renderLinkIcon,
|
|
2310
2457
|
header,
|
|
2311
2458
|
onTaskSaved,
|
|
2312
2459
|
createSurface = "modal",
|
|
@@ -2372,6 +2519,14 @@ function TasksPageCore({
|
|
|
2372
2519
|
) : null;
|
|
2373
2520
|
const listPriority = priority === "ALL" ? void 0 : priority;
|
|
2374
2521
|
const listType = type === "ALL" ? void 0 : type;
|
|
2522
|
+
const listColumns = linkSourceProduct ? [
|
|
2523
|
+
"title",
|
|
2524
|
+
"status",
|
|
2525
|
+
"priority",
|
|
2526
|
+
"assignee",
|
|
2527
|
+
"dueDate",
|
|
2528
|
+
"linkedRecord"
|
|
2529
|
+
] : void 0;
|
|
2375
2530
|
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-4 p-6", className), children: [
|
|
2376
2531
|
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
2532
|
/* @__PURE__ */ jsx(
|
|
@@ -2404,6 +2559,8 @@ function TasksPageCore({
|
|
|
2404
2559
|
search,
|
|
2405
2560
|
hiddenFields,
|
|
2406
2561
|
resolveAssignee,
|
|
2562
|
+
linkSourceProduct,
|
|
2563
|
+
renderLinkIcon,
|
|
2407
2564
|
onTaskClick: handleTaskClick
|
|
2408
2565
|
}
|
|
2409
2566
|
),
|
|
@@ -2417,6 +2574,9 @@ function TasksPageCore({
|
|
|
2417
2574
|
search: search || void 0,
|
|
2418
2575
|
hideHeader: true,
|
|
2419
2576
|
resolveAssignee,
|
|
2577
|
+
linkSourceProduct,
|
|
2578
|
+
renderLinkIcon,
|
|
2579
|
+
columns: listColumns ? [...listColumns] : void 0,
|
|
2420
2580
|
onSelect: handleSelect
|
|
2421
2581
|
}
|
|
2422
2582
|
),
|
|
@@ -2483,6 +2643,6 @@ function TasksPage({
|
|
|
2483
2643
|
);
|
|
2484
2644
|
}
|
|
2485
2645
|
|
|
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 };
|
|
2646
|
+
export { Avatar, Badge, CREATE_WORK_ITEM, CREATE_WORK_ITEM_LINK, CreateTask, CreateTaskCore, DEFAULT_BOARD_COLUMNS, DELETE_WORK_ITEM_LINK, Drawer, GET_PROJECTS, GET_WORK_ITEM, LIST_WORK_ITEMS, LIST_WORK_ITEM_LINKS, LinkChip, 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_LINK_FIELDS, WORK_ITEM_SUMMARY_FIELDS, badgeVariants, cn, config, createPlanMagnetClient, enumLabel, getGraphQLEndpoint, getPlanMagnetClient, getPlanMagnetClientSafe, getPlanMagnetConfig, isPlanMagnetClientReady, resetPlanMagnetClient, resetPlanMagnetConfig, setPlanMagnetClient, setPlanMagnetConfig, usePlanMagnetContext, usePlanMagnetContextSafe, useWorkItemLinks, validateTrustedOrigin, waitForPlanMagnetClient };
|
|
2487
2647
|
//# sourceMappingURL=index.js.map
|
|
2488
2648
|
//# sourceMappingURL=index.js.map
|