@burdenoff/planmagnet-fe-sdk 2026.705.2 → 2026.706.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 +12 -6
- package/dist/index.js +226 -63
- 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,27 +2510,134 @@ 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.
|
|
2520
2636
|
variables: {
|
|
2521
2637
|
input: {
|
|
2522
2638
|
entityType,
|
|
2523
2639
|
entityId,
|
|
2524
|
-
take:
|
|
2640
|
+
take: 200,
|
|
2525
2641
|
sortBy: "createdAt",
|
|
2526
2642
|
sortOrder: "asc"
|
|
2527
2643
|
}
|
|
@@ -2530,16 +2646,30 @@ function TaskCommentsCore({
|
|
|
2530
2646
|
errorPolicy: "all"
|
|
2531
2647
|
}
|
|
2532
2648
|
);
|
|
2533
|
-
const
|
|
2534
|
-
const
|
|
2649
|
+
const all = data?.getEntityComments?.items ?? [];
|
|
2650
|
+
const { topLevel, repliesByRoot } = useMemo(() => {
|
|
2651
|
+
const top = [];
|
|
2652
|
+
const map = /* @__PURE__ */ new Map();
|
|
2653
|
+
for (const c of all) {
|
|
2654
|
+
if (!c.parentCommentId) {
|
|
2655
|
+
top.push(c);
|
|
2656
|
+
} else {
|
|
2657
|
+
const root = c.threadRootId ?? c.parentCommentId;
|
|
2658
|
+
const arr = map.get(root);
|
|
2659
|
+
if (arr) arr.push(c);
|
|
2660
|
+
else map.set(root, [c]);
|
|
2661
|
+
}
|
|
2662
|
+
}
|
|
2663
|
+
return { topLevel: top, repliesByRoot: map };
|
|
2664
|
+
}, [all]);
|
|
2665
|
+
const [createComment] = useMutation(
|
|
2666
|
+
CREATE_ENTITY_COMMENT
|
|
2667
|
+
);
|
|
2535
2668
|
const [deleteComment] = useMutation(
|
|
2536
2669
|
DELETE_ENTITY_COMMENT
|
|
2537
2670
|
);
|
|
2538
2671
|
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;
|
|
2672
|
+
const post = async ({ text, mentionUserIds }, parentCommentId) => {
|
|
2543
2673
|
setError(null);
|
|
2544
2674
|
try {
|
|
2545
2675
|
await createComment({
|
|
@@ -2547,15 +2677,18 @@ function TaskCommentsCore({
|
|
|
2547
2677
|
input: {
|
|
2548
2678
|
entityType,
|
|
2549
2679
|
entityId,
|
|
2550
|
-
content: { text
|
|
2551
|
-
contentType: "TEXT"
|
|
2680
|
+
content: { text },
|
|
2681
|
+
contentType: "TEXT",
|
|
2682
|
+
...parentCommentId ? { parentCommentId } : {},
|
|
2683
|
+
...mentionUserIds.length ? { mentionUserIds } : {}
|
|
2552
2684
|
}
|
|
2553
2685
|
}
|
|
2554
2686
|
});
|
|
2555
|
-
setText("");
|
|
2556
2687
|
await refetch();
|
|
2557
|
-
|
|
2688
|
+
setReplyingTo(null);
|
|
2689
|
+
} catch (err) {
|
|
2558
2690
|
setError(L.failedToComment);
|
|
2691
|
+
throw err;
|
|
2559
2692
|
}
|
|
2560
2693
|
};
|
|
2561
2694
|
const handleDelete = async (id) => {
|
|
@@ -2567,60 +2700,89 @@ function TaskCommentsCore({
|
|
|
2567
2700
|
setError(L.failedToDeleteComment);
|
|
2568
2701
|
}
|
|
2569
2702
|
};
|
|
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",
|
|
2703
|
+
const renderBody = (c) => {
|
|
2704
|
+
const text = c.content?.text ?? "";
|
|
2705
|
+
const names = (c.mentions ?? []).map((m) => resolveAssignee?.(m.mentionedUserId)?.name).filter((n) => Boolean(n));
|
|
2706
|
+
if (names.length === 0) return text;
|
|
2707
|
+
const tokens = new Set(names.map((n) => `@${n}`));
|
|
2708
|
+
const re = new RegExp(`(@(?:${names.map(escapeRe).join("|")}))`, "g");
|
|
2709
|
+
return text.split(re).map(
|
|
2710
|
+
(part, i) => tokens.has(part) ? /* @__PURE__ */ jsx(
|
|
2711
|
+
"span",
|
|
2601
2712
|
{
|
|
2602
|
-
className:
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2713
|
+
className: "rounded bg-primary/10 px-0.5 font-medium text-primary",
|
|
2714
|
+
children: part
|
|
2715
|
+
},
|
|
2716
|
+
i
|
|
2717
|
+
) : /* @__PURE__ */ jsx("span", { children: part }, i)
|
|
2718
|
+
);
|
|
2719
|
+
};
|
|
2720
|
+
const commentBlock = (c, isReply) => /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
2721
|
+
/* @__PURE__ */ jsx(Avatar, { id: c.authorId, name: authorName(c.authorId), size: "sm" }),
|
|
2722
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
2723
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2724
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-foreground", children: authorName(c.authorId) ?? c.authorId.slice(0, 8) }),
|
|
2725
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: formatDateFull(c.createdAt) }),
|
|
2726
|
+
c.edited && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: L.editedTag }),
|
|
2727
|
+
!readonly && c.authorId === currentActorId && /* @__PURE__ */ jsx(
|
|
2728
|
+
"button",
|
|
2729
|
+
{
|
|
2730
|
+
type: "button",
|
|
2731
|
+
onClick: () => handleDelete(c.id),
|
|
2732
|
+
"aria-label": L.del,
|
|
2733
|
+
title: L.del,
|
|
2734
|
+
className: "ml-auto rounded p-1 text-muted-foreground hover:text-destructive",
|
|
2735
|
+
children: /* @__PURE__ */ jsx(Trash2, { className: "h-3.5 w-3.5" })
|
|
2736
|
+
}
|
|
2737
|
+
)
|
|
2738
|
+
] }),
|
|
2739
|
+
/* @__PURE__ */ jsx("p", { className: "whitespace-pre-wrap break-words text-sm text-foreground", children: renderBody(c) }),
|
|
2740
|
+
!isReply && !readonly && /* @__PURE__ */ jsx(
|
|
2611
2741
|
"button",
|
|
2612
2742
|
{
|
|
2613
|
-
type: "
|
|
2614
|
-
|
|
2615
|
-
className:
|
|
2616
|
-
|
|
2617
|
-
(posting || !text.trim()) && "cursor-not-allowed opacity-50"
|
|
2618
|
-
),
|
|
2619
|
-
children: posting ? L.posting : L.postComment
|
|
2743
|
+
type: "button",
|
|
2744
|
+
onClick: () => setReplyingTo((prev) => prev === c.id ? null : c.id),
|
|
2745
|
+
className: "mt-1 text-xs font-medium text-muted-foreground hover:text-foreground",
|
|
2746
|
+
children: L.reply
|
|
2620
2747
|
}
|
|
2621
|
-
)
|
|
2748
|
+
)
|
|
2622
2749
|
] })
|
|
2623
2750
|
] });
|
|
2751
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-4", className), children: [
|
|
2752
|
+
/* @__PURE__ */ jsxs("div", { className: labelClass2, children: [
|
|
2753
|
+
L.commentsLabel,
|
|
2754
|
+
all.length > 0 ? ` (${all.length})` : ""
|
|
2755
|
+
] }),
|
|
2756
|
+
/* @__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) => {
|
|
2757
|
+
const replies = repliesByRoot.get(c.id) ?? [];
|
|
2758
|
+
return /* @__PURE__ */ jsxs("li", { className: "space-y-2", children: [
|
|
2759
|
+
commentBlock(c, false),
|
|
2760
|
+
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)) }),
|
|
2761
|
+
!readonly && replyingTo === c.id && /* @__PURE__ */ jsx("div", { className: "ml-8", children: /* @__PURE__ */ jsx(
|
|
2762
|
+
CommentComposer,
|
|
2763
|
+
{
|
|
2764
|
+
placeholder: L.replyPlaceholder,
|
|
2765
|
+
submitLabel: L.reply,
|
|
2766
|
+
pendingLabel: L.posting,
|
|
2767
|
+
members,
|
|
2768
|
+
autoFocus: true,
|
|
2769
|
+
onSubmit: (p) => post(p, c.id)
|
|
2770
|
+
}
|
|
2771
|
+
) })
|
|
2772
|
+
] }, c.id);
|
|
2773
|
+
}) }),
|
|
2774
|
+
error && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: error }),
|
|
2775
|
+
!readonly && /* @__PURE__ */ jsx(
|
|
2776
|
+
CommentComposer,
|
|
2777
|
+
{
|
|
2778
|
+
placeholder: L.commentPlaceholder,
|
|
2779
|
+
submitLabel: L.postComment,
|
|
2780
|
+
pendingLabel: L.posting,
|
|
2781
|
+
members,
|
|
2782
|
+
onSubmit: (p) => post(p)
|
|
2783
|
+
}
|
|
2784
|
+
)
|
|
2785
|
+
] });
|
|
2624
2786
|
}
|
|
2625
2787
|
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
2788
|
var labelClass3 = "text-xs font-medium uppercase tracking-wide text-muted-foreground";
|
|
@@ -2947,7 +3109,8 @@ function TaskDetailCore({
|
|
|
2947
3109
|
entityType: commentsEntityType,
|
|
2948
3110
|
entityId: item.id,
|
|
2949
3111
|
currentActorId,
|
|
2950
|
-
resolveAssignee
|
|
3112
|
+
resolveAssignee,
|
|
3113
|
+
members: assigneeOptions
|
|
2951
3114
|
}
|
|
2952
3115
|
) })
|
|
2953
3116
|
] }) : /* @__PURE__ */ jsxs("form", { onSubmit: handleSave, className: "space-y-4", children: [
|