@burdenoff/planmagnet-fe-sdk 2026.705.2 → 2026.706.2
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 +12 -6
- package/dist/index.js +227 -62
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -881,22 +881,25 @@ interface TaskCommentsCoreProps {
|
|
|
881
881
|
entityId: string;
|
|
882
882
|
/** The current actor — enables "You" + delete on own comments. */
|
|
883
883
|
currentActorId?: string;
|
|
884
|
-
/** Resolve an author id → display name (reuse the member directory). */
|
|
884
|
+
/** Resolve an author/mention id → display name (reuse the member directory). */
|
|
885
885
|
resolveAssignee?: ResolveAssignee;
|
|
886
|
+
/** Member directory for @-mention autocomplete. Omit to disable mentions. */
|
|
887
|
+
members?: AssigneeOption[];
|
|
886
888
|
/** Hide the composer + delete affordances (pure read-only). */
|
|
887
889
|
readonly?: boolean;
|
|
888
890
|
/** Extra classes on the root container. */
|
|
889
891
|
className?: string;
|
|
890
892
|
}
|
|
891
893
|
/**
|
|
892
|
-
* TaskCommentsCore — a comment thread on a work item, backed by the
|
|
893
|
-
* wspace-conversations-svc `EntityComment` (the platform's canonical
|
|
894
|
-
* owner) rather than a per-product comment table.
|
|
894
|
+
* TaskCommentsCore — a threaded comment thread on a work item, backed by the
|
|
895
|
+
* SHARED wspace-conversations-svc `EntityComment` (the platform's canonical
|
|
896
|
+
* comment owner) rather than a per-product comment table. Supports 1-level
|
|
897
|
+
* replies (grouped by thread root) and @-mentions. BYO-Apollo, semantic-token
|
|
895
898
|
* only, farm-free. RBAC is enforced server-side (create/read are editor-level,
|
|
896
899
|
* a workspace Member gets editor on `entity-comment`); the composer fails open
|
|
897
|
-
* and
|
|
900
|
+
* and surfaces a graceful error if the server denies it.
|
|
898
901
|
*/
|
|
899
|
-
declare function TaskCommentsCore({ entityType, entityId, currentActorId, resolveAssignee, readonly, className, }: TaskCommentsCoreProps): react.JSX.Element;
|
|
902
|
+
declare function TaskCommentsCore({ entityType, entityId, currentActorId, resolveAssignee, members, readonly, className, }: TaskCommentsCoreProps): react.JSX.Element;
|
|
900
903
|
|
|
901
904
|
/**
|
|
902
905
|
* TaskLabels — every user-facing string the SDK renders, so a host (e.g.
|
|
@@ -969,6 +972,9 @@ interface TaskLabels {
|
|
|
969
972
|
editedTag: string;
|
|
970
973
|
failedToComment: string;
|
|
971
974
|
failedToDeleteComment: string;
|
|
975
|
+
reply: string;
|
|
976
|
+
replyPlaceholder: string;
|
|
977
|
+
repliesCount: string;
|
|
972
978
|
create: string;
|
|
973
979
|
creating: string;
|
|
974
980
|
cancel: string;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createContext, useMemo, useEffect, useContext, useState, useCallback } from 'react';
|
|
1
|
+
import { createContext, useMemo, useEffect, useContext, useState, useCallback, useRef } from 'react';
|
|
2
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';
|
|
@@ -524,6 +524,12 @@ var ENTITY_COMMENT_FIELDS = gql`
|
|
|
524
524
|
edited
|
|
525
525
|
editedAt
|
|
526
526
|
status
|
|
527
|
+
parentCommentId
|
|
528
|
+
threadRootId
|
|
529
|
+
threadLevel
|
|
530
|
+
mentions {
|
|
531
|
+
mentionedUserId
|
|
532
|
+
}
|
|
527
533
|
}
|
|
528
534
|
`;
|
|
529
535
|
var GET_ENTITY_COMMENTS = gql`
|
|
@@ -798,6 +804,9 @@ var DEFAULT_TASK_LABELS = {
|
|
|
798
804
|
editedTag: "(edited)",
|
|
799
805
|
failedToComment: "Failed to post comment",
|
|
800
806
|
failedToDeleteComment: "Failed to delete comment",
|
|
807
|
+
reply: "Reply",
|
|
808
|
+
replyPlaceholder: "Write a reply\u2026",
|
|
809
|
+
repliesCount: "{n} replies",
|
|
801
810
|
create: "Create task",
|
|
802
811
|
creating: "Creating\u2026",
|
|
803
812
|
cancel: "Cancel",
|
|
@@ -2501,22 +2510,131 @@ function TaskToolbar({
|
|
|
2501
2510
|
}
|
|
2502
2511
|
);
|
|
2503
2512
|
}
|
|
2504
|
-
var labelClass2 = "text-xs font-medium uppercase tracking-wide text-muted-foreground";
|
|
2505
2513
|
var fieldClass2 = "w-full rounded-md border border-input bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring";
|
|
2514
|
+
function CommentComposer({
|
|
2515
|
+
placeholder,
|
|
2516
|
+
submitLabel,
|
|
2517
|
+
pendingLabel,
|
|
2518
|
+
members,
|
|
2519
|
+
autoFocus,
|
|
2520
|
+
onSubmit
|
|
2521
|
+
}) {
|
|
2522
|
+
const [text, setText] = useState("");
|
|
2523
|
+
const [pending, setPending] = useState(false);
|
|
2524
|
+
const [mentioned, setMentioned] = useState([]);
|
|
2525
|
+
const [query, setQuery] = useState(null);
|
|
2526
|
+
const taRef = useRef(null);
|
|
2527
|
+
const suggestions = useMemo(() => {
|
|
2528
|
+
if (query == null || !members || members.length === 0) return [];
|
|
2529
|
+
const q = query.toLowerCase();
|
|
2530
|
+
return members.filter((m) => m.name.toLowerCase().includes(q)).slice(0, 6);
|
|
2531
|
+
}, [query, members]);
|
|
2532
|
+
const detectMention = (value) => {
|
|
2533
|
+
const caret = taRef.current?.selectionStart ?? value.length;
|
|
2534
|
+
const m = /(?:^|\s)@([\p{L}\p{N} ._-]*)$/u.exec(value.slice(0, caret));
|
|
2535
|
+
setQuery(m ? m[1] : null);
|
|
2536
|
+
};
|
|
2537
|
+
const onChange = (value) => {
|
|
2538
|
+
setText(value);
|
|
2539
|
+
detectMention(value);
|
|
2540
|
+
};
|
|
2541
|
+
const pickMention = (member) => {
|
|
2542
|
+
const el = taRef.current;
|
|
2543
|
+
const caret = el?.selectionStart ?? text.length;
|
|
2544
|
+
const before = text.slice(0, caret);
|
|
2545
|
+
const after = text.slice(caret);
|
|
2546
|
+
const replaced = before.replace(
|
|
2547
|
+
/@([\p{L}\p{N} ._-]*)$/u,
|
|
2548
|
+
`@${member.name} `
|
|
2549
|
+
);
|
|
2550
|
+
setText(replaced + after);
|
|
2551
|
+
setQuery(null);
|
|
2552
|
+
setMentioned(
|
|
2553
|
+
(prev) => prev.some((p) => p.id === member.id) ? prev : [...prev, member]
|
|
2554
|
+
);
|
|
2555
|
+
requestAnimationFrame(() => el?.focus());
|
|
2556
|
+
};
|
|
2557
|
+
const submit = async (e) => {
|
|
2558
|
+
e.preventDefault();
|
|
2559
|
+
const body = text.trim();
|
|
2560
|
+
if (!body || pending) return;
|
|
2561
|
+
const ids = mentioned.filter((m) => body.includes(`@${m.name}`)).map((m) => m.id);
|
|
2562
|
+
setPending(true);
|
|
2563
|
+
try {
|
|
2564
|
+
await onSubmit({ text: body, mentionUserIds: ids });
|
|
2565
|
+
setText("");
|
|
2566
|
+
setMentioned([]);
|
|
2567
|
+
setQuery(null);
|
|
2568
|
+
} finally {
|
|
2569
|
+
setPending(false);
|
|
2570
|
+
}
|
|
2571
|
+
};
|
|
2572
|
+
return /* @__PURE__ */ jsxs("form", { onSubmit: submit, className: "relative space-y-2", children: [
|
|
2573
|
+
/* @__PURE__ */ jsx(
|
|
2574
|
+
"textarea",
|
|
2575
|
+
{
|
|
2576
|
+
ref: taRef,
|
|
2577
|
+
className: cn(fieldClass2, "min-h-[60px]"),
|
|
2578
|
+
rows: 2,
|
|
2579
|
+
value: text,
|
|
2580
|
+
autoFocus,
|
|
2581
|
+
onChange: (e) => onChange(e.target.value),
|
|
2582
|
+
onKeyUp: (e) => detectMention(e.target.value),
|
|
2583
|
+
onClick: (e) => detectMention(e.target.value),
|
|
2584
|
+
placeholder,
|
|
2585
|
+
"aria-label": placeholder
|
|
2586
|
+
}
|
|
2587
|
+
),
|
|
2588
|
+
suggestions.length > 0 && /* @__PURE__ */ jsx("ul", { className: "absolute left-0 top-full z-20 mt-1 max-h-48 w-56 overflow-auto rounded-md border border-border bg-popover p-1 shadow-md", children: suggestions.map((m) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
|
|
2589
|
+
"button",
|
|
2590
|
+
{
|
|
2591
|
+
type: "button",
|
|
2592
|
+
onMouseDown: (e) => {
|
|
2593
|
+
e.preventDefault();
|
|
2594
|
+
pickMention(m);
|
|
2595
|
+
},
|
|
2596
|
+
className: "flex w-full items-center rounded px-2 py-1 text-left text-sm text-foreground hover:bg-muted",
|
|
2597
|
+
children: [
|
|
2598
|
+
"@",
|
|
2599
|
+
m.name
|
|
2600
|
+
]
|
|
2601
|
+
}
|
|
2602
|
+
) }, m.id)) }),
|
|
2603
|
+
/* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx(
|
|
2604
|
+
"button",
|
|
2605
|
+
{
|
|
2606
|
+
type: "submit",
|
|
2607
|
+
disabled: pending || !text.trim(),
|
|
2608
|
+
className: cn(
|
|
2609
|
+
"rounded-md bg-primary px-3 py-1.5 text-sm font-medium text-primary-foreground",
|
|
2610
|
+
(pending || !text.trim()) && "cursor-not-allowed opacity-50"
|
|
2611
|
+
),
|
|
2612
|
+
children: pending ? pendingLabel : submitLabel
|
|
2613
|
+
}
|
|
2614
|
+
) })
|
|
2615
|
+
] });
|
|
2616
|
+
}
|
|
2617
|
+
var labelClass2 = "text-xs font-medium uppercase tracking-wide text-muted-foreground";
|
|
2618
|
+
var escapeRe = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2506
2619
|
function TaskCommentsCore({
|
|
2507
2620
|
entityType,
|
|
2508
2621
|
entityId,
|
|
2509
2622
|
currentActorId,
|
|
2510
2623
|
resolveAssignee,
|
|
2624
|
+
members,
|
|
2511
2625
|
readonly,
|
|
2512
2626
|
className
|
|
2513
2627
|
}) {
|
|
2514
2628
|
const L = useTaskLabels();
|
|
2515
|
-
const [text, setText] = useState("");
|
|
2516
2629
|
const [error, setError] = useState(null);
|
|
2630
|
+
const [replyingTo, setReplyingTo] = useState(null);
|
|
2517
2631
|
const { data, loading, refetch } = useQuery(
|
|
2518
2632
|
GET_ENTITY_COMMENTS,
|
|
2519
2633
|
{
|
|
2634
|
+
// No parentCommentId → the service returns EVERY comment (all levels)
|
|
2635
|
+
// flat; we build the thread tree client-side via threadRootId. `take` is
|
|
2636
|
+
// capped at 100 by the conversations service (a higher value is rejected
|
|
2637
|
+
// with a validation error), which is ample for a single work item.
|
|
2520
2638
|
variables: {
|
|
2521
2639
|
input: {
|
|
2522
2640
|
entityType,
|
|
@@ -2530,16 +2648,30 @@ function TaskCommentsCore({
|
|
|
2530
2648
|
errorPolicy: "all"
|
|
2531
2649
|
}
|
|
2532
2650
|
);
|
|
2533
|
-
const
|
|
2534
|
-
const
|
|
2651
|
+
const all = data?.getEntityComments?.items ?? [];
|
|
2652
|
+
const { topLevel, repliesByRoot } = useMemo(() => {
|
|
2653
|
+
const top = [];
|
|
2654
|
+
const map = /* @__PURE__ */ new Map();
|
|
2655
|
+
for (const c of all) {
|
|
2656
|
+
if (!c.parentCommentId) {
|
|
2657
|
+
top.push(c);
|
|
2658
|
+
} else {
|
|
2659
|
+
const root = c.threadRootId ?? c.parentCommentId;
|
|
2660
|
+
const arr = map.get(root);
|
|
2661
|
+
if (arr) arr.push(c);
|
|
2662
|
+
else map.set(root, [c]);
|
|
2663
|
+
}
|
|
2664
|
+
}
|
|
2665
|
+
return { topLevel: top, repliesByRoot: map };
|
|
2666
|
+
}, [all]);
|
|
2667
|
+
const [createComment] = useMutation(
|
|
2668
|
+
CREATE_ENTITY_COMMENT
|
|
2669
|
+
);
|
|
2535
2670
|
const [deleteComment] = useMutation(
|
|
2536
2671
|
DELETE_ENTITY_COMMENT
|
|
2537
2672
|
);
|
|
2538
2673
|
const authorName = (id) => id === currentActorId ? L.you : resolveAssignee?.(id)?.name ?? void 0;
|
|
2539
|
-
const
|
|
2540
|
-
e.preventDefault();
|
|
2541
|
-
const body = text.trim();
|
|
2542
|
-
if (!body) return;
|
|
2674
|
+
const post = async ({ text, mentionUserIds }, parentCommentId) => {
|
|
2543
2675
|
setError(null);
|
|
2544
2676
|
try {
|
|
2545
2677
|
await createComment({
|
|
@@ -2547,15 +2679,18 @@ function TaskCommentsCore({
|
|
|
2547
2679
|
input: {
|
|
2548
2680
|
entityType,
|
|
2549
2681
|
entityId,
|
|
2550
|
-
content: { text
|
|
2551
|
-
contentType: "TEXT"
|
|
2682
|
+
content: { text },
|
|
2683
|
+
contentType: "TEXT",
|
|
2684
|
+
...parentCommentId ? { parentCommentId } : {},
|
|
2685
|
+
...mentionUserIds.length ? { mentionUserIds } : {}
|
|
2552
2686
|
}
|
|
2553
2687
|
}
|
|
2554
2688
|
});
|
|
2555
|
-
setText("");
|
|
2556
2689
|
await refetch();
|
|
2557
|
-
|
|
2690
|
+
setReplyingTo(null);
|
|
2691
|
+
} catch (err) {
|
|
2558
2692
|
setError(L.failedToComment);
|
|
2693
|
+
throw err;
|
|
2559
2694
|
}
|
|
2560
2695
|
};
|
|
2561
2696
|
const handleDelete = async (id) => {
|
|
@@ -2567,60 +2702,89 @@ function TaskCommentsCore({
|
|
|
2567
2702
|
setError(L.failedToDeleteComment);
|
|
2568
2703
|
}
|
|
2569
2704
|
};
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-foreground", children: authorName(c.authorId) ?? c.authorId.slice(0, 8) }),
|
|
2580
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: formatDateFull(c.createdAt) }),
|
|
2581
|
-
c.edited && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: L.editedTag }),
|
|
2582
|
-
!readonly && c.authorId === currentActorId && /* @__PURE__ */ jsx(
|
|
2583
|
-
"button",
|
|
2584
|
-
{
|
|
2585
|
-
type: "button",
|
|
2586
|
-
onClick: () => handleDelete(c.id),
|
|
2587
|
-
"aria-label": L.del,
|
|
2588
|
-
title: L.del,
|
|
2589
|
-
className: "ml-auto rounded p-1 text-muted-foreground hover:text-destructive",
|
|
2590
|
-
children: /* @__PURE__ */ jsx(Trash2, { className: "h-3.5 w-3.5" })
|
|
2591
|
-
}
|
|
2592
|
-
)
|
|
2593
|
-
] }),
|
|
2594
|
-
/* @__PURE__ */ jsx("p", { className: "whitespace-pre-wrap break-words text-sm text-foreground", children: c.content?.text })
|
|
2595
|
-
] })
|
|
2596
|
-
] }, c.id)) }),
|
|
2597
|
-
error && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: error }),
|
|
2598
|
-
!readonly && /* @__PURE__ */ jsxs("form", { onSubmit: handlePost, className: "space-y-2", children: [
|
|
2599
|
-
/* @__PURE__ */ jsx(
|
|
2600
|
-
"textarea",
|
|
2705
|
+
const renderBody = (c) => {
|
|
2706
|
+
const text = c.content?.text ?? "";
|
|
2707
|
+
const names = (c.mentions ?? []).map((m) => resolveAssignee?.(m.mentionedUserId)?.name).filter((n) => Boolean(n));
|
|
2708
|
+
if (names.length === 0) return text;
|
|
2709
|
+
const tokens = new Set(names.map((n) => `@${n}`));
|
|
2710
|
+
const re = new RegExp(`(@(?:${names.map(escapeRe).join("|")}))`, "g");
|
|
2711
|
+
return text.split(re).map(
|
|
2712
|
+
(part, i) => tokens.has(part) ? /* @__PURE__ */ jsx(
|
|
2713
|
+
"span",
|
|
2601
2714
|
{
|
|
2602
|
-
className:
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2715
|
+
className: "rounded bg-primary/10 px-0.5 font-medium text-primary",
|
|
2716
|
+
children: part
|
|
2717
|
+
},
|
|
2718
|
+
i
|
|
2719
|
+
) : /* @__PURE__ */ jsx("span", { children: part }, i)
|
|
2720
|
+
);
|
|
2721
|
+
};
|
|
2722
|
+
const commentBlock = (c, isReply) => /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
2723
|
+
/* @__PURE__ */ jsx(Avatar, { id: c.authorId, name: authorName(c.authorId), size: "sm" }),
|
|
2724
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
2725
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2726
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-foreground", children: authorName(c.authorId) ?? c.authorId.slice(0, 8) }),
|
|
2727
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: formatDateFull(c.createdAt) }),
|
|
2728
|
+
c.edited && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: L.editedTag }),
|
|
2729
|
+
!readonly && c.authorId === currentActorId && /* @__PURE__ */ jsx(
|
|
2730
|
+
"button",
|
|
2731
|
+
{
|
|
2732
|
+
type: "button",
|
|
2733
|
+
onClick: () => handleDelete(c.id),
|
|
2734
|
+
"aria-label": L.del,
|
|
2735
|
+
title: L.del,
|
|
2736
|
+
className: "ml-auto rounded p-1 text-muted-foreground hover:text-destructive",
|
|
2737
|
+
children: /* @__PURE__ */ jsx(Trash2, { className: "h-3.5 w-3.5" })
|
|
2738
|
+
}
|
|
2739
|
+
)
|
|
2740
|
+
] }),
|
|
2741
|
+
/* @__PURE__ */ jsx("p", { className: "whitespace-pre-wrap break-words text-sm text-foreground", children: renderBody(c) }),
|
|
2742
|
+
!isReply && !readonly && /* @__PURE__ */ jsx(
|
|
2611
2743
|
"button",
|
|
2612
2744
|
{
|
|
2613
|
-
type: "
|
|
2614
|
-
|
|
2615
|
-
className:
|
|
2616
|
-
|
|
2617
|
-
(posting || !text.trim()) && "cursor-not-allowed opacity-50"
|
|
2618
|
-
),
|
|
2619
|
-
children: posting ? L.posting : L.postComment
|
|
2745
|
+
type: "button",
|
|
2746
|
+
onClick: () => setReplyingTo((prev) => prev === c.id ? null : c.id),
|
|
2747
|
+
className: "mt-1 text-xs font-medium text-muted-foreground hover:text-foreground",
|
|
2748
|
+
children: L.reply
|
|
2620
2749
|
}
|
|
2621
|
-
)
|
|
2750
|
+
)
|
|
2622
2751
|
] })
|
|
2623
2752
|
] });
|
|
2753
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-4", className), children: [
|
|
2754
|
+
/* @__PURE__ */ jsxs("div", { className: labelClass2, children: [
|
|
2755
|
+
L.commentsLabel,
|
|
2756
|
+
all.length > 0 ? ` (${all.length})` : ""
|
|
2757
|
+
] }),
|
|
2758
|
+
/* @__PURE__ */ jsx("ul", { className: "space-y-4", children: topLevel.length === 0 && !loading ? /* @__PURE__ */ jsx("li", { className: "text-sm text-muted-foreground", children: L.noComments }) : topLevel.map((c) => {
|
|
2759
|
+
const replies = repliesByRoot.get(c.id) ?? [];
|
|
2760
|
+
return /* @__PURE__ */ jsxs("li", { className: "space-y-2", children: [
|
|
2761
|
+
commentBlock(c, false),
|
|
2762
|
+
replies.length > 0 && /* @__PURE__ */ jsx("ul", { className: "ml-8 space-y-2 border-l border-border pl-3", children: replies.map((r) => /* @__PURE__ */ jsx("li", { children: commentBlock(r, true) }, r.id)) }),
|
|
2763
|
+
!readonly && replyingTo === c.id && /* @__PURE__ */ jsx("div", { className: "ml-8", children: /* @__PURE__ */ jsx(
|
|
2764
|
+
CommentComposer,
|
|
2765
|
+
{
|
|
2766
|
+
placeholder: L.replyPlaceholder,
|
|
2767
|
+
submitLabel: L.reply,
|
|
2768
|
+
pendingLabel: L.posting,
|
|
2769
|
+
members,
|
|
2770
|
+
autoFocus: true,
|
|
2771
|
+
onSubmit: (p) => post(p, c.id)
|
|
2772
|
+
}
|
|
2773
|
+
) })
|
|
2774
|
+
] }, c.id);
|
|
2775
|
+
}) }),
|
|
2776
|
+
error && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: error }),
|
|
2777
|
+
!readonly && /* @__PURE__ */ jsx(
|
|
2778
|
+
CommentComposer,
|
|
2779
|
+
{
|
|
2780
|
+
placeholder: L.commentPlaceholder,
|
|
2781
|
+
submitLabel: L.postComment,
|
|
2782
|
+
pendingLabel: L.posting,
|
|
2783
|
+
members,
|
|
2784
|
+
onSubmit: (p) => post(p)
|
|
2785
|
+
}
|
|
2786
|
+
)
|
|
2787
|
+
] });
|
|
2624
2788
|
}
|
|
2625
2789
|
var fieldClass3 = "w-full rounded-md border border-input bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring";
|
|
2626
2790
|
var labelClass3 = "text-xs font-medium uppercase tracking-wide text-muted-foreground";
|
|
@@ -2947,7 +3111,8 @@ function TaskDetailCore({
|
|
|
2947
3111
|
entityType: commentsEntityType,
|
|
2948
3112
|
entityId: item.id,
|
|
2949
3113
|
currentActorId,
|
|
2950
|
-
resolveAssignee
|
|
3114
|
+
resolveAssignee,
|
|
3115
|
+
members: assigneeOptions
|
|
2951
3116
|
}
|
|
2952
3117
|
) })
|
|
2953
3118
|
] }) : /* @__PURE__ */ jsxs("form", { onSubmit: handleSave, className: "space-y-4", children: [
|