@burdenoff/fe-libs 2026.527.3 → 2026.527.4

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.
Files changed (94) hide show
  1. package/dist/chrome/ContextSwitcher.js +90 -339
  2. package/dist/chrome/GlobalSearch.js +72 -456
  3. package/dist/chrome/NotificationCenter.js +69 -703
  4. package/dist/chrome/SideNavigation.js +73 -241
  5. package/dist/chrome/contextSwitcher/EmptyState.js +32 -0
  6. package/dist/chrome/contextSwitcher/OrganizationList.js +34 -0
  7. package/dist/chrome/contextSwitcher/ProjectList.js +34 -0
  8. package/dist/chrome/contextSwitcher/SearchInput.js +50 -0
  9. package/dist/chrome/contextSwitcher/TabButton.js +9 -0
  10. package/dist/chrome/contextSwitcher/TriggerButton.js +38 -0
  11. package/dist/chrome/contextSwitcher/WorkspaceList.js +34 -0
  12. package/dist/chrome/contextSwitcher/icons.js +58 -0
  13. package/dist/chrome/contextSwitcher/useIsMobile.js +11 -0
  14. package/dist/chrome/globalSearch/AdvancedFiltersPanel.js +253 -0
  15. package/dist/chrome/globalSearch/CategoryTabs.js +28 -0
  16. package/dist/chrome/globalSearch/ResultsList.js +58 -0
  17. package/dist/chrome/globalSearch/SearchInput.js +28 -0
  18. package/dist/chrome/globalSearch/SearchModeBar.js +36 -0
  19. package/dist/chrome/globalSearch/useAdvancedFilters.js +78 -0
  20. package/dist/chrome/globalSearch/utils.js +22 -0
  21. package/dist/chrome/notificationCenter/BellButton.js +27 -0
  22. package/dist/chrome/notificationCenter/NotificationCardItem.js +129 -0
  23. package/dist/chrome/notificationCenter/NotificationFilters.js +67 -0
  24. package/dist/chrome/notificationCenter/NotificationFooter.js +23 -0
  25. package/dist/chrome/notificationCenter/NotificationHeader.js +75 -0
  26. package/dist/chrome/notificationCenter/NotificationList.js +75 -0
  27. package/dist/chrome/notificationCenter/NotificationPanel.js +19 -0
  28. package/dist/chrome/notificationCenter/SkeletonCard.js +18 -0
  29. package/dist/chrome/notificationCenter/constants.js +93 -0
  30. package/dist/chrome/notificationCenter/gql.js +58 -0
  31. package/dist/chrome/notificationCenter/useNotificationCenter.js +149 -0
  32. package/dist/chrome/notificationCenter/usePanelChrome.js +36 -0
  33. package/dist/chrome/sideNavigation/CollapseToggle.js +29 -0
  34. package/dist/chrome/sideNavigation/MobileActionsBar.js +25 -0
  35. package/dist/chrome/sideNavigation/NavItemRenderer.js +79 -0
  36. package/dist/chrome/sideNavigation/SidebarHeader.js +29 -0
  37. package/dist/chrome/sideNavigation/helpers.js +19 -0
  38. package/dist/chrome/sideNavigation/useSideNavigationState.js +45 -0
  39. package/dist/shared/components/ContextConversationWidget.js +173 -767
  40. package/dist/shared/components/contextConversationWidget/Composer.js +66 -0
  41. package/dist/shared/components/contextConversationWidget/MessageItem.js +124 -0
  42. package/dist/shared/components/contextConversationWidget/MessageList.js +32 -0
  43. package/dist/shared/components/contextConversationWidget/NoWorkspaceCard.js +19 -0
  44. package/dist/shared/components/contextConversationWidget/PendingAttachmentsBar.js +28 -0
  45. package/dist/shared/components/contextConversationWidget/ReplyBanner.js +32 -0
  46. package/dist/shared/components/contextConversationWidget/WidgetHeader.js +70 -0
  47. package/dist/shared/components/contextConversationWidget/queries.js +197 -0
  48. package/dist/shared/components/contextConversationWidget/types.js +10 -0
  49. package/dist/shared/components/contextConversationWidget/useAttachmentUpload.js +57 -0
  50. package/dist/shared/components/contextConversationWidget/useConversationSubscriptions.js +26 -0
  51. package/dist/shared/components/contextConversationWidget/useMessageActions.js +34 -0
  52. package/dist/shared/components/contextConversationWidget/useSendMessage.js +45 -0
  53. package/dist/shared/components/contextConversationWidget/useWidgetMessages.js +44 -0
  54. package/dist/shared/components/contextConversationWidget/utils.js +56 -0
  55. package/dist/shared/pages/SearchPage.js +293 -1076
  56. package/dist/shared/pages/searchPage/ActiveFilterChips.js +176 -0
  57. package/dist/shared/pages/searchPage/FiltersPanel.js +329 -0
  58. package/dist/shared/pages/searchPage/ResultsList.js +119 -0
  59. package/dist/shared/pages/searchPage/ResultsStatus.js +32 -0
  60. package/dist/shared/pages/searchPage/SearchInput.js +31 -0
  61. package/dist/shared/pages/searchPage/SearchPagination.js +37 -0
  62. package/dist/shared/pages/searchPage/SearchToolbar.js +58 -0
  63. package/dist/shared/pages/searchPage/constants.js +155 -0
  64. package/dist/shared/pages/searchPage/utils.js +24 -0
  65. package/dist/shared/providers/shell/AuthProvider.js +130 -384
  66. package/dist/shared/providers/shell/authProvider/bridgeStateSync.js +34 -0
  67. package/dist/shared/providers/shell/authProvider/jwt.js +13 -0
  68. package/dist/shared/providers/shell/authProvider/ssoRelay.js +38 -0
  69. package/dist/shared/providers/shell/authProvider/useAuthActions.js +170 -0
  70. package/dist/shared/providers/shell/authProvider/useBridgeInitialization.js +86 -0
  71. package/dist/shared/providers/shell/authProvider/useRemoteSLO.js +32 -0
  72. package/dist/shared/providers/shell/authProvider/useStorageSync.js +35 -0
  73. package/dist/shared/providers/shell/authProvider/useTokenExpiryTimer.js +37 -0
  74. package/dist/shared/tours/TourTrigger.js +86 -262
  75. package/dist/shared/tours/ToursContext.js +108 -398
  76. package/dist/shared/tours/tourTrigger/DesktopTourDropdown.js +48 -0
  77. package/dist/shared/tours/tourTrigger/MobileTourSheet.js +68 -0
  78. package/dist/shared/tours/tourTrigger/TourListItemDesktop.js +36 -0
  79. package/dist/shared/tours/tourTrigger/TourListItemMobile.js +47 -0
  80. package/dist/shared/tours/tourTrigger/TourStatusChip.js +30 -0
  81. package/dist/shared/tours/tourTrigger/TourTriggerButton.js +22 -0
  82. package/dist/shared/tours/toursContext/errors.js +18 -0
  83. package/dist/shared/tours/toursContext/gql.js +152 -0
  84. package/dist/shared/tours/toursContext/route.js +20 -0
  85. package/dist/shared/tours/toursContext/session.js +19 -0
  86. package/dist/shared/tours/toursContext/useIdleReady.js +18 -0
  87. package/dist/shared/tours/toursContext/useTourMutations.js +118 -0
  88. package/dist/tag/TagsWidget.js +81 -226
  89. package/dist/tag/tagsWidget/AddTagTrigger.js +14 -0
  90. package/dist/tag/tagsWidget/TagBadgeList.js +17 -0
  91. package/dist/tag/tagsWidget/TagSearchPopover.js +80 -0
  92. package/dist/tag/tagsWidget/operations.js +64 -0
  93. package/dist/tag/tagsWidget/useVocabResolver.js +30 -0
  94. package/package.json +1 -1
@@ -0,0 +1,66 @@
1
+ import { Button as e } from "../../../ui/button.js";
2
+ import { Badge as t } from "../../../ui/badge.js";
3
+ import { Textarea as n } from "../../../ui/textarea.js";
4
+ import "../../../ui.js";
5
+ import { Loader2 as r, Paperclip as i, SendHorizontal as a, SmilePlus as o } from "lucide-react";
6
+ import { jsx as s, jsxs as c } from "react/jsx-runtime";
7
+ //#region src/shared/components/contextConversationWidget/Composer.tsx
8
+ function l({ composerValue: l, onComposerChange: u, fileInputRef: d, onFilesSelected: f, onAttachClick: p, onSend: m, uploading: h, isSendingMessage: g, featureFlags: _, mentionSuggestions: v, onSelectMention: y, tr: b }) {
9
+ return /* @__PURE__ */ c("div", {
10
+ "data-tour": "page-discussion-composer",
11
+ className: "space-y-3 rounded-lg border border-border bg-background/80 p-3",
12
+ children: [
13
+ /* @__PURE__ */ s(n, {
14
+ value: l,
15
+ onChange: (e) => u(e.target.value),
16
+ rows: 3,
17
+ placeholder: b("conversationWidget.placeholder", "Discuss this page in context…"),
18
+ className: "border-0 bg-transparent px-0 shadow-none focus-visible:ring-0"
19
+ }),
20
+ _.mentions && v.length > 0 ? /* @__PURE__ */ c("div", {
21
+ className: "flex flex-wrap gap-2 rounded-md border border-border bg-muted/20 p-2",
22
+ children: [/* @__PURE__ */ s(o, { className: "mt-0.5 size-4 text-muted-foreground" }), v.map((t) => /* @__PURE__ */ c(e, {
23
+ type: "button",
24
+ variant: "outline",
25
+ size: "sm",
26
+ onClick: () => y(t),
27
+ children: ["@", t.label]
28
+ }, t.id))]
29
+ }) : null,
30
+ /* @__PURE__ */ c("div", {
31
+ className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between",
32
+ children: [/* @__PURE__ */ c("div", {
33
+ className: "flex flex-wrap items-center gap-2",
34
+ children: [
35
+ /* @__PURE__ */ s("input", {
36
+ ref: d,
37
+ type: "file",
38
+ multiple: !0,
39
+ className: "hidden",
40
+ onChange: (e) => f(e.target.files)
41
+ }),
42
+ /* @__PURE__ */ c(e, {
43
+ type: "button",
44
+ variant: "outline",
45
+ size: "sm",
46
+ onClick: p,
47
+ disabled: h,
48
+ children: [h ? /* @__PURE__ */ s(r, { className: "mr-2 size-4 animate-spin" }) : /* @__PURE__ */ s(i, { className: "mr-2 size-4" }), b("conversationWidget.attach", "Attach files")]
49
+ }),
50
+ _.mentions ? /* @__PURE__ */ s(t, {
51
+ variant: "outline",
52
+ children: b("conversationWidget.mentionsHint", "Type @ to mention participants")
53
+ }) : null
54
+ ]
55
+ }), /* @__PURE__ */ c(e, {
56
+ type: "button",
57
+ onClick: m,
58
+ disabled: g || h || !l.trim(),
59
+ children: [g ? /* @__PURE__ */ s(r, { className: "mr-2 size-4 animate-spin" }) : /* @__PURE__ */ s(a, { className: "mr-2 size-4" }), b("conversationWidget.send", "Send")]
60
+ })]
61
+ })
62
+ ]
63
+ });
64
+ }
65
+ //#endregion
66
+ export { l as Composer };
@@ -0,0 +1,124 @@
1
+ import { Button as e } from "../../../ui/button.js";
2
+ import { Textarea as t } from "../../../ui/textarea.js";
3
+ import "../../../ui.js";
4
+ import { QUICK_REACTIONS as n } from "./types.js";
5
+ import { formatFileSize as r, formatTimestamp as i } from "./utils.js";
6
+ import { Pencil as a, Pin as o, PinOff as s, Reply as c, Trash2 as l } from "lucide-react";
7
+ import { Fragment as u, jsx as d, jsxs as f } from "react/jsx-runtime";
8
+ //#region src/shared/components/contextConversationWidget/MessageItem.tsx
9
+ function p({ message: p, currentUserId: m, featureFlags: h, editingMessageId: g, editingValue: _, onEditValueChange: v, onStartEdit: y, onCancelEdit: b, onSaveEdit: x, onSetReplyTarget: S, onToggleReaction: C, onDelete: w, onTogglePin: T, tr: E }) {
10
+ let D = p.authorId === m, O = g === p.id;
11
+ return /* @__PURE__ */ d("div", {
12
+ className: `flex ${D ? "justify-end" : "justify-start"}`,
13
+ children: /* @__PURE__ */ f("div", {
14
+ className: `w-full max-w-full rounded-xl border px-3 py-2 text-sm shadow-sm sm:max-w-[92%] ${D ? "border-primary/20 bg-primary/5" : "border-border bg-background"}`,
15
+ children: [
16
+ /* @__PURE__ */ f("div", {
17
+ className: "mb-1 flex items-center justify-between gap-2",
18
+ children: [/* @__PURE__ */ f("div", {
19
+ className: "flex items-center gap-2 text-xs text-muted-foreground",
20
+ children: [
21
+ /* @__PURE__ */ d("span", {
22
+ className: "font-medium text-foreground",
23
+ children: D ? E("conversationWidget.you", "You") : p.authorId
24
+ }),
25
+ /* @__PURE__ */ d("span", { children: i(p.createdAt) }),
26
+ p.isEdited ? /* @__PURE__ */ d("span", { children: E("conversationWidget.edited", "edited") }) : null,
27
+ p.isPinned ? /* @__PURE__ */ d(o, { className: "size-3" }) : null
28
+ ]
29
+ }), /* @__PURE__ */ d("div", {
30
+ className: "flex items-center gap-1",
31
+ children: h.reactions && p.permissions.canReact ? n.map((e) => {
32
+ let t = p.reactions.filter((t) => t.emoji === e).length;
33
+ return /* @__PURE__ */ f("button", {
34
+ type: "button",
35
+ className: `min-h-9 rounded-full px-2.5 py-1 text-xs transition-colors ${p.reactions.some((t) => t.emoji === e && t.userId === m) ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground hover:bg-muted/80"}`,
36
+ onClick: () => C(p, e),
37
+ children: [e, t > 0 ? ` ${t}` : ""]
38
+ }, `${p.id}-${e}`);
39
+ }) : null
40
+ })]
41
+ }),
42
+ O ? /* @__PURE__ */ f("div", {
43
+ className: "space-y-2",
44
+ children: [/* @__PURE__ */ d(t, {
45
+ value: _,
46
+ onChange: (e) => v(e.target.value),
47
+ rows: 3
48
+ }), /* @__PURE__ */ f("div", {
49
+ className: "flex flex-wrap items-center justify-end gap-2",
50
+ children: [/* @__PURE__ */ d(e, {
51
+ type: "button",
52
+ variant: "outline",
53
+ size: "sm",
54
+ onClick: b,
55
+ children: E("conversationWidget.cancel", "Cancel")
56
+ }), /* @__PURE__ */ d(e, {
57
+ type: "button",
58
+ size: "sm",
59
+ onClick: x,
60
+ children: E("conversationWidget.save", "Save")
61
+ })]
62
+ })]
63
+ }) : /* @__PURE__ */ f(u, { children: [p.parentMessageId ? /* @__PURE__ */ d("p", {
64
+ className: "mb-1 text-xs text-muted-foreground",
65
+ children: E("conversationWidget.replyingInThread", "Reply in thread")
66
+ }) : null, /* @__PURE__ */ d("p", {
67
+ className: "whitespace-pre-wrap break-words text-sm text-foreground",
68
+ children: p.content
69
+ })] }),
70
+ p.attachments.length > 0 ? /* @__PURE__ */ d("div", {
71
+ className: "mt-3 flex flex-col gap-2",
72
+ children: p.attachments.map((e) => /* @__PURE__ */ f("a", {
73
+ href: e.downloadUrl ?? "#",
74
+ target: e.downloadUrl ? "_blank" : void 0,
75
+ rel: e.downloadUrl ? "noreferrer" : void 0,
76
+ className: "flex items-center justify-between gap-2 rounded-md border border-border bg-muted/40 px-3 py-2 text-xs",
77
+ children: [/* @__PURE__ */ d("span", {
78
+ className: "truncate",
79
+ children: e.fileName
80
+ }), /* @__PURE__ */ d("span", {
81
+ className: "text-muted-foreground",
82
+ children: r(e.fileSize)
83
+ })]
84
+ }, e.id))
85
+ }) : null,
86
+ /* @__PURE__ */ f("div", {
87
+ className: "mt-3 flex flex-wrap items-center gap-2 text-xs",
88
+ children: [
89
+ h.threads && p.permissions.canReply ? /* @__PURE__ */ f(e, {
90
+ type: "button",
91
+ variant: "ghost",
92
+ size: "sm",
93
+ onClick: () => S(p),
94
+ children: [/* @__PURE__ */ d(c, { className: "mr-2 size-3" }), E("conversationWidget.reply", "Reply")]
95
+ }) : null,
96
+ p.permissions.canEdit && !O ? /* @__PURE__ */ f(e, {
97
+ type: "button",
98
+ variant: "ghost",
99
+ size: "sm",
100
+ onClick: () => y(p),
101
+ children: [/* @__PURE__ */ d(a, { className: "mr-2 size-3" }), E("conversationWidget.edit", "Edit")]
102
+ }) : null,
103
+ p.permissions.canDelete ? /* @__PURE__ */ f(e, {
104
+ type: "button",
105
+ variant: "ghost",
106
+ size: "sm",
107
+ onClick: () => w(p),
108
+ children: [/* @__PURE__ */ d(l, { className: "mr-2 size-3" }), E("conversationWidget.delete", "Delete")]
109
+ }) : null,
110
+ p.permissions.canPin ? /* @__PURE__ */ f(e, {
111
+ type: "button",
112
+ variant: "ghost",
113
+ size: "sm",
114
+ onClick: () => T(p),
115
+ children: [p.isPinned ? /* @__PURE__ */ d(s, { className: "mr-2 size-3" }) : /* @__PURE__ */ d(o, { className: "mr-2 size-3" }), p.isPinned ? E("conversationWidget.unpin", "Unpin") : E("conversationWidget.pin", "Pin")]
116
+ }) : null
117
+ ]
118
+ })
119
+ ]
120
+ })
121
+ });
122
+ }
123
+ //#endregion
124
+ export { p as MessageItem };
@@ -0,0 +1,32 @@
1
+ import { MessageItem as e } from "./MessageItem.js";
2
+ import { jsx as t, jsxs as n } from "react/jsx-runtime";
3
+ //#region src/shared/components/contextConversationWidget/MessageList.tsx
4
+ function r({ messages: r, currentUserId: i, featureFlags: a, editingMessageId: o, editingValue: s, messageEndRef: c, onEditValueChange: l, onStartEdit: u, onCancelEdit: d, onSaveEdit: f, onSetReplyTarget: p, onToggleReaction: m, onDelete: h, onTogglePin: g, tr: _ }) {
5
+ return /* @__PURE__ */ t("div", {
6
+ className: "max-h-[24rem] overflow-y-auto rounded-lg border border-border bg-muted/20",
7
+ children: /* @__PURE__ */ n("div", {
8
+ className: "space-y-3 p-4",
9
+ children: [r.length === 0 ? /* @__PURE__ */ t("div", {
10
+ className: "rounded-lg border border-dashed border-border bg-background/70 px-4 py-5 text-sm text-muted-foreground",
11
+ children: _("conversationWidget.empty", "No messages yet. Start the conversation in context.")
12
+ }) : r.map((n) => /* @__PURE__ */ t(e, {
13
+ message: n,
14
+ currentUserId: i,
15
+ featureFlags: a,
16
+ editingMessageId: o,
17
+ editingValue: s,
18
+ onEditValueChange: l,
19
+ onStartEdit: u,
20
+ onCancelEdit: d,
21
+ onSaveEdit: f,
22
+ onSetReplyTarget: p,
23
+ onToggleReaction: m,
24
+ onDelete: h,
25
+ onTogglePin: g,
26
+ tr: _
27
+ }, n.id)), /* @__PURE__ */ t("div", { ref: c })]
28
+ })
29
+ });
30
+ }
31
+ //#endregion
32
+ export { r as MessageList };
@@ -0,0 +1,19 @@
1
+ import { Card as e, CardContent as t, CardHeader as n, CardTitle as r } from "../../../ui/card.js";
2
+ import "../../../ui.js";
3
+ import { MessageCircle as i } from "lucide-react";
4
+ import { jsx as a, jsxs as o } from "react/jsx-runtime";
5
+ //#region src/shared/components/contextConversationWidget/NoWorkspaceCard.tsx
6
+ function s({ className: s, tr: c }) {
7
+ return /* @__PURE__ */ o(e, {
8
+ className: s,
9
+ children: [/* @__PURE__ */ a(n, { children: /* @__PURE__ */ o(r, {
10
+ className: "flex items-center gap-2 text-base",
11
+ children: [/* @__PURE__ */ a(i, { className: "size-4" }), c("conversationWidget.title", "Page conversation")]
12
+ }) }), /* @__PURE__ */ a(t, { children: /* @__PURE__ */ a("p", {
13
+ className: "text-sm text-muted-foreground",
14
+ children: c("conversationWidget.noWorkspace", "Select a workspace to enable contextual conversations on this page.")
15
+ }) })]
16
+ });
17
+ }
18
+ //#endregion
19
+ export { s as NoWorkspaceCard };
@@ -0,0 +1,28 @@
1
+ import { Badge as e } from "../../../ui/badge.js";
2
+ import "../../../ui.js";
3
+ import { Paperclip as t, X as n } from "lucide-react";
4
+ import { jsx as r, jsxs as i } from "react/jsx-runtime";
5
+ //#region src/shared/components/contextConversationWidget/PendingAttachmentsBar.tsx
6
+ function a({ attachments: a, onRemove: o }) {
7
+ return /* @__PURE__ */ r("div", {
8
+ className: "flex flex-wrap gap-2",
9
+ children: a.map((a) => /* @__PURE__ */ i(e, {
10
+ variant: "secondary",
11
+ className: "gap-2 py-1.5",
12
+ children: [
13
+ /* @__PURE__ */ r(t, { className: "size-3" }),
14
+ /* @__PURE__ */ r("span", {
15
+ className: "max-w-[14rem] truncate",
16
+ children: a.fileName
17
+ }),
18
+ /* @__PURE__ */ r("button", {
19
+ type: "button",
20
+ onClick: () => o(a.fileId),
21
+ children: /* @__PURE__ */ r(n, { className: "size-3" })
22
+ })
23
+ ]
24
+ }, a.fileId))
25
+ });
26
+ }
27
+ //#endregion
28
+ export { a as PendingAttachmentsBar };
@@ -0,0 +1,32 @@
1
+ import { Button as e } from "../../../ui/button.js";
2
+ import "../../../ui.js";
3
+ import { X as t } from "lucide-react";
4
+ import { jsx as n, jsxs as r } from "react/jsx-runtime";
5
+ //#region src/shared/components/contextConversationWidget/ReplyBanner.tsx
6
+ function i({ replyTarget: i, onClear: a, tr: o }) {
7
+ return /* @__PURE__ */ r("div", {
8
+ className: "flex items-center justify-between gap-2 rounded-md border border-border bg-muted/40 px-3 py-2 text-sm",
9
+ children: [/* @__PURE__ */ r("div", {
10
+ className: "min-w-0",
11
+ children: [/* @__PURE__ */ r("p", {
12
+ className: "text-xs text-muted-foreground",
13
+ children: [
14
+ o("conversationWidget.replyingTo", "Replying to"),
15
+ " ",
16
+ i.authorId
17
+ ]
18
+ }), /* @__PURE__ */ n("p", {
19
+ className: "truncate",
20
+ children: i.content
21
+ })]
22
+ }), /* @__PURE__ */ n(e, {
23
+ type: "button",
24
+ variant: "ghost",
25
+ size: "icon",
26
+ onClick: a,
27
+ children: /* @__PURE__ */ n(t, { className: "size-4" })
28
+ })]
29
+ });
30
+ }
31
+ //#endregion
32
+ export { i as ReplyBanner };
@@ -0,0 +1,70 @@
1
+ import { Button as e } from "../../../ui/button.js";
2
+ import { Badge as t } from "../../../ui/badge.js";
3
+ import { CardHeader as n, CardTitle as r } from "../../../ui/card.js";
4
+ import "../../../ui.js";
5
+ import { ChevronDown as i, ChevronUp as a, ExternalLink as o, MessageCircle as s } from "lucide-react";
6
+ import { jsx as c, jsxs as l } from "react/jsx-runtime";
7
+ //#region src/shared/components/contextConversationWidget/WidgetHeader.tsx
8
+ function u({ conversationTitle: u, pageContext: d, resolvedContext: f, unreadCount: p, conversationId: m, collapsed: h, onToggleCollapsed: g, onOpenContext: _, onOpenInbox: v, tr: y }) {
9
+ let b = d.entityType && d.entityId ? `${d.entityType} · ${d.entityId}` : d.pagePath;
10
+ return /* @__PURE__ */ l(n, {
11
+ className: "space-y-3",
12
+ children: [/* @__PURE__ */ l("div", {
13
+ className: "flex flex-col gap-3 md:flex-row md:items-start md:justify-between",
14
+ children: [/* @__PURE__ */ l("div", {
15
+ className: "space-y-1",
16
+ children: [/* @__PURE__ */ l(r, {
17
+ className: "flex items-center gap-2 text-base",
18
+ children: [/* @__PURE__ */ c(s, { className: "size-4" }), u || d.contextTitle || y("conversationWidget.title", "Page conversation")]
19
+ }), /* @__PURE__ */ c("p", {
20
+ className: "text-sm text-muted-foreground truncate whitespace-nowrap overflow-hidden max-w-full",
21
+ title: b,
22
+ children: b
23
+ })]
24
+ }), /* @__PURE__ */ l("div", {
25
+ className: "flex flex-wrap items-center gap-2 md:justify-end",
26
+ children: [
27
+ /* @__PURE__ */ l(e, {
28
+ type: "button",
29
+ variant: "outline",
30
+ size: "sm",
31
+ onClick: _,
32
+ children: [/* @__PURE__ */ c(o, { className: "mr-2 size-4" }), y("conversationWidget.openContext", "Open context")]
33
+ }),
34
+ /* @__PURE__ */ c(e, {
35
+ type: "button",
36
+ "data-tour": "page-discussion-open-full",
37
+ variant: "outline",
38
+ size: "sm",
39
+ onClick: v,
40
+ disabled: !m,
41
+ children: y("conversationWidget.openInbox", "Open in conversations")
42
+ }),
43
+ /* @__PURE__ */ c(e, {
44
+ type: "button",
45
+ variant: "ghost",
46
+ size: "icon",
47
+ onClick: g,
48
+ "aria-label": h ? y("conversationWidget.expand", "Expand page conversation") : y("conversationWidget.collapse", "Collapse page conversation"),
49
+ children: c(h ? i : a, { className: "size-4" })
50
+ })
51
+ ]
52
+ })]
53
+ }), /* @__PURE__ */ l("div", {
54
+ className: "flex flex-wrap items-center gap-2",
55
+ children: [
56
+ /* @__PURE__ */ c(t, {
57
+ variant: "secondary",
58
+ children: f.widgetKey
59
+ }),
60
+ f.activeTab ? /* @__PURE__ */ c(t, {
61
+ variant: "outline",
62
+ children: f.activeTab
63
+ }) : null,
64
+ p ? /* @__PURE__ */ l(t, { children: [p, " unread"] }) : null
65
+ ]
66
+ })]
67
+ });
68
+ }
69
+ //#endregion
70
+ export { u as WidgetHeader };
@@ -0,0 +1,197 @@
1
+ import { gql as e } from "@apollo/client";
2
+ //#region src/shared/components/contextConversationWidget/queries.ts
3
+ var t = e`
4
+ mutation ContextConversationWidget_SendContextMessage(
5
+ $input: SendContextConversationMessageInput!
6
+ ) {
7
+ sendContextMessage(input: $input) {
8
+ success
9
+ message {
10
+ id
11
+ conversationId
12
+ }
13
+ }
14
+ }
15
+ `, n = e`
16
+ query ContextConversationWidget_GetConversation($id: ID!) {
17
+ conversation(id: $id) {
18
+ id
19
+ title
20
+ description
21
+ settings
22
+ updatedAt
23
+ features {
24
+ threads
25
+ reactions
26
+ mentions
27
+ }
28
+ currentUserMembership {
29
+ unreadCount
30
+ }
31
+ }
32
+ }
33
+ `, r = e`
34
+ query ContextConversationWidget_GetContextConversations($first: Int) {
35
+ conversations(first: $first) {
36
+ edges {
37
+ node {
38
+ id
39
+ settings
40
+ }
41
+ }
42
+ }
43
+ }
44
+ `, i = e`
45
+ query ContextConversationWidget_GetMessages($conversationId: ID!, $first: Int) {
46
+ messages(conversationId: $conversationId, first: $first) {
47
+ edges {
48
+ node {
49
+ id
50
+ conversationId
51
+ type
52
+ status
53
+ content
54
+ authorId
55
+ authorType
56
+ parentMessageId
57
+ threadRootId
58
+ threadLevel
59
+ isEdited
60
+ editedAt
61
+ isPinned
62
+ createdAt
63
+ updatedAt
64
+ replyCount
65
+ permissions {
66
+ canEdit
67
+ canDelete
68
+ canReact
69
+ canReply
70
+ canPin
71
+ }
72
+ reactions {
73
+ id
74
+ emoji
75
+ userId
76
+ createdAt
77
+ }
78
+ attachments {
79
+ id
80
+ fileId
81
+ fileName
82
+ fileSize
83
+ mimeType
84
+ downloadUrl
85
+ thumbnail
86
+ width
87
+ height
88
+ duration
89
+ }
90
+ }
91
+ }
92
+ }
93
+ }
94
+ `, a = e`
95
+ subscription ContextConversationWidget_MessageAdded($conversationId: ID!) {
96
+ messageAdded(conversationId: $conversationId) {
97
+ id
98
+ conversationId
99
+ type
100
+ status
101
+ content
102
+ authorId
103
+ authorType
104
+ parentMessageId
105
+ threadRootId
106
+ threadLevel
107
+ isEdited
108
+ editedAt
109
+ isPinned
110
+ createdAt
111
+ updatedAt
112
+ replyCount
113
+ }
114
+ }
115
+ `, o = e`
116
+ subscription ContextConversationWidget_MessageUpdated($conversationId: ID!) {
117
+ messageUpdated(conversationId: $conversationId) {
118
+ id
119
+ conversationId
120
+ content
121
+ isEdited
122
+ editedAt
123
+ updatedAt
124
+ }
125
+ }
126
+ `, s = e`
127
+ subscription ContextConversationWidget_MessageDeleted($conversationId: ID!) {
128
+ messageDeleted(conversationId: $conversationId) {
129
+ messageId
130
+ conversationId
131
+ }
132
+ }
133
+ `, c = e`
134
+ mutation ContextConversationWidget_EditMessage($input: EditMessageInput!) {
135
+ editMessage(input: $input) {
136
+ id
137
+ content
138
+ isEdited
139
+ editedAt
140
+ updatedAt
141
+ }
142
+ }
143
+ `, l = e`
144
+ mutation ContextConversationWidget_DeleteMessage($id: ID!, $hard: Boolean) {
145
+ deleteMessage(id: $id, hard: $hard) {
146
+ success
147
+ }
148
+ }
149
+ `, u = e`
150
+ mutation ContextConversationWidget_AddReaction($messageId: ID!, $emoji: String!) {
151
+ addReaction(messageId: $messageId, emoji: $emoji) {
152
+ id
153
+ }
154
+ }
155
+ `, d = e`
156
+ mutation ContextConversationWidget_RemoveReaction($messageId: ID!, $emoji: String!) {
157
+ removeReaction(messageId: $messageId, emoji: $emoji) {
158
+ success
159
+ }
160
+ }
161
+ `, f = e`
162
+ mutation ContextConversationWidget_PinMessage($messageId: ID!) {
163
+ pinMessage(messageId: $messageId) {
164
+ id
165
+ }
166
+ }
167
+ `, p = e`
168
+ mutation ContextConversationWidget_UnpinMessage($messageId: ID!) {
169
+ unpinMessage(messageId: $messageId) {
170
+ id
171
+ }
172
+ }
173
+ `, m = e`
174
+ mutation ContextConversationWidget_InitiateUpload($input: InitiateUploadInput!) {
175
+ initiateUpload(input: $input) {
176
+ uploadUrl
177
+ session {
178
+ id
179
+ }
180
+ }
181
+ }
182
+ `, h = e`
183
+ mutation ContextConversationWidget_CompleteUpload($input: CompleteUploadInput!) {
184
+ completeUpload(input: $input) {
185
+ fileId
186
+ file {
187
+ id
188
+ name
189
+ mimeType
190
+ size
191
+ downloadUrl
192
+ }
193
+ }
194
+ }
195
+ `;
196
+ //#endregion
197
+ export { u as ADD_REACTION, h as COMPLETE_UPLOAD, l as DELETE_MESSAGE, c as EDIT_MESSAGE, r as GET_CONTEXT_CONVERSATIONS, n as GET_WIDGET_CONVERSATION, i as GET_WIDGET_MESSAGES, m as INITIATE_UPLOAD, a as MESSAGE_ADDED_SUBSCRIPTION, s as MESSAGE_DELETED_SUBSCRIPTION, o as MESSAGE_UPDATED_SUBSCRIPTION, f as PIN_MESSAGE, d as REMOVE_REACTION, t as SEND_CONTEXT_MESSAGE, p as UNPIN_MESSAGE };
@@ -0,0 +1,10 @@
1
+ //#region src/shared/components/contextConversationWidget/types.ts
2
+ var e = [
3
+ "👍",
4
+ "❤️",
5
+ "🎉",
6
+ "👀",
7
+ "✅"
8
+ ], t = 5 * 1024 * 1024;
9
+ //#endregion
10
+ export { t as MAX_DIRECT_UPLOAD_BYTES, e as QUICK_REACTIONS };
@@ -0,0 +1,57 @@
1
+ import "./types.js";
2
+ import { COMPLETE_UPLOAD as e, INITIATE_UPLOAD as t } from "./queries.js";
3
+ import { useRef as n, useState as r } from "react";
4
+ import { useMutation as i } from "@apollo/client/react";
5
+ //#region src/shared/components/contextConversationWidget/useAttachmentUpload.ts
6
+ function a({ workspaceClient: a, onError: o }) {
7
+ let [s, c] = r(!1), [l, u] = r([]), d = n(null), [f] = i(t, { client: a }), [p] = i(e, { client: a });
8
+ return {
9
+ uploading: s,
10
+ pendingAttachments: l,
11
+ fileInputRef: d,
12
+ handleUploadFiles: async (e) => {
13
+ if (!(!e || e.length === 0)) {
14
+ c(!0);
15
+ try {
16
+ let t = [];
17
+ for (let n of Array.from(e)) {
18
+ if (n.size > 5242880) throw Error(`${n.name} exceeds the 5 MB widget upload limit.`);
19
+ let e = n.name.includes(".") ? n.name.split(".").pop() ?? "bin" : "bin", r = await f({ variables: { input: {
20
+ fileName: n.name,
21
+ fileSize: n.size,
22
+ mimeType: n.type || "application/octet-stream",
23
+ extension: e,
24
+ visibility: "PRIVATE"
25
+ } } }), i = r.data?.initiateUpload?.uploadUrl, a = r.data?.initiateUpload?.session?.id;
26
+ if (!i || !a) throw Error(`Unable to create an upload session for ${n.name}`);
27
+ if (!(await fetch(i, {
28
+ method: "PUT",
29
+ body: n,
30
+ headers: { "Content-Type": n.type || "application/octet-stream" }
31
+ })).ok) throw Error(`Upload failed for ${n.name}`);
32
+ let o = (await p({ variables: { input: { sessionId: a } } })).data?.completeUpload;
33
+ if (!o?.fileId) throw Error(`Failed to finalize ${n.name}`);
34
+ t.push({
35
+ fileId: o.fileId,
36
+ fileName: o.file?.name ?? n.name,
37
+ fileSize: Number(o.file?.size ?? n.size),
38
+ mimeType: o.file?.mimeType ?? n.type,
39
+ downloadUrl: o.file?.downloadUrl ?? null
40
+ });
41
+ }
42
+ u((e) => [...e, ...t]);
43
+ } catch (e) {
44
+ o(e instanceof Error ? e.message : "File upload failed");
45
+ } finally {
46
+ c(!1), d.current && (d.current.value = "");
47
+ }
48
+ }
49
+ },
50
+ removePendingAttachment: (e) => {
51
+ u((t) => t.filter((t) => t.fileId !== e));
52
+ },
53
+ clearPendingAttachments: () => u([])
54
+ };
55
+ }
56
+ //#endregion
57
+ export { a as useAttachmentUpload };
@@ -0,0 +1,26 @@
1
+ import { GET_WIDGET_MESSAGES as e, MESSAGE_ADDED_SUBSCRIPTION as t, MESSAGE_DELETED_SUBSCRIPTION as n, MESSAGE_UPDATED_SUBSCRIPTION as r } from "./queries.js";
2
+ import { useSubscription as i } from "@apollo/client/react";
3
+ //#region src/shared/components/contextConversationWidget/useConversationSubscriptions.ts
4
+ function a(a, o) {
5
+ i(t, {
6
+ client: a,
7
+ variables: { conversationId: o || "" },
8
+ skip: !o,
9
+ onData: ({ data: t, client: n }) => {
10
+ t.data?.messageAdded && n.refetchQueries({ include: [e] });
11
+ }
12
+ }), i(r, {
13
+ client: a,
14
+ variables: { conversationId: o || "" },
15
+ skip: !o
16
+ }), i(n, {
17
+ client: a,
18
+ variables: { conversationId: o || "" },
19
+ skip: !o,
20
+ onData: ({ client: t }) => {
21
+ t.refetchQueries({ include: [e] });
22
+ }
23
+ });
24
+ }
25
+ //#endregion
26
+ export { a as useConversationSubscriptions };