@burdenoff/microfe-conversations 2026.527.1 → 2026.528.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.
Files changed (29) hide show
  1. package/dist/conversations/ConversationsUserRoutes.js +6 -6
  2. package/dist/conversations/ConversationsUserRoutes.js.map +1 -1
  3. package/dist/conversations/components/ConversationRow.js +176 -0
  4. package/dist/conversations/components/ConversationRow.js.map +1 -0
  5. package/dist/conversations/components/EmptyState.js +10 -21
  6. package/dist/conversations/components/EmptyState.js.map +1 -1
  7. package/dist/conversations/components/InboxLayout.js +185 -0
  8. package/dist/conversations/components/InboxLayout.js.map +1 -0
  9. package/dist/conversations/components/LazyPageBoundary.js.map +1 -1
  10. package/dist/conversations/components/PageLayout.js +16 -34
  11. package/dist/conversations/components/PageLayout.js.map +1 -1
  12. package/dist/conversations/components/PageSection.js +10 -19
  13. package/dist/conversations/components/PageSection.js.map +1 -1
  14. package/dist/conversations/components/lazyRetry.js.map +1 -1
  15. package/dist/conversations/hooks/useConversationQueries.js +48 -34
  16. package/dist/conversations/hooks/useConversationQueries.js.map +1 -1
  17. package/dist/conversations/hooks/useMessageQueries.js.map +1 -1
  18. package/dist/conversations/pages/ConversationAdminPages.js.map +1 -1
  19. package/dist/conversations/pages/ConversationListPage.js +187 -226
  20. package/dist/conversations/pages/ConversationListPage.js.map +1 -1
  21. package/dist/conversations/pages/ConversationsLandingPage.js +93 -103
  22. package/dist/conversations/pages/ConversationsLandingPage.js.map +1 -1
  23. package/dist/conversations/pages/ConversationsSettingsPage.js +201 -182
  24. package/dist/conversations/pages/ConversationsSettingsPage.js.map +1 -1
  25. package/dist/generated/wspace-operations.js +72 -56
  26. package/dist/generated/wspace-operations.js.map +1 -1
  27. package/package.json +2 -2
  28. package/dist/conversations/components/ConversationCard.js +0 -119
  29. package/dist/conversations/components/ConversationCard.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-conversations",
3
- "version": "2026.527.1",
3
+ "version": "2026.528.1",
4
4
  "description": "Burdenoff Conversations Microfrontend - Complete messaging and conversation interface",
5
5
  "type": "module",
6
6
  "files": [
@@ -43,7 +43,7 @@
43
43
  },
44
44
  "dependencies": {
45
45
  "@apollo/client": "^4.0.11",
46
- "@burdenoff/fe-libs": "2026.518.7",
46
+ "@burdenoff/fe-libs": "2026.528.8",
47
47
  "@tanstack/react-query": "^5.90.16",
48
48
  "clsx": "^2.1.1",
49
49
  "graphql": "^16.10.0",
@@ -1,119 +0,0 @@
1
- import { cn as e } from "../utils/cn.js";
2
- import { memo as t } from "react";
3
- import { Bot as n, Hash as r, HeadphonesIcon as i, Megaphone as a, MessageCircle as o, Pin as s, Users as c, VolumeX as l } from "lucide-react";
4
- import { Fragment as u, jsx as d, jsxs as f } from "react/jsx-runtime";
5
- import { useI18n as p } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
6
- //#region src/conversations/components/ConversationCard.tsx
7
- function m({ type: e, size: t = 16 }) {
8
- switch (e) {
9
- case "DIRECT": return /* @__PURE__ */ d(o, { size: t });
10
- case "GROUP": return /* @__PURE__ */ d(c, { size: t });
11
- case "CHANNEL": return /* @__PURE__ */ d(r, { size: t });
12
- case "BROADCAST":
13
- case "ANNOUNCEMENT": return /* @__PURE__ */ d(a, { size: t });
14
- case "BOT": return /* @__PURE__ */ d(n, { size: t });
15
- case "SUPPORT": return /* @__PURE__ */ d(i, { size: t });
16
- default: return /* @__PURE__ */ d(o, { size: t });
17
- }
18
- }
19
- function h(e, t) {
20
- let n = /* @__PURE__ */ new Date(), r = new Date(e), i = n.getTime() - r.getTime(), a = Math.floor(i / 1e3), o = Math.floor(a / 60), s = Math.floor(o / 60), c = Math.floor(s / 24);
21
- return o < 1 ? t.now : o < 60 ? `${o}m` : s < 24 ? `${s}h` : c === 1 ? t.yesterday : c < 7 ? `${c}d` : r.toLocaleDateString(void 0, {
22
- month: "short",
23
- day: "numeric"
24
- });
25
- }
26
- function g(e) {
27
- return e.split(" ").slice(0, 2).map((e) => e[0]).join("").toUpperCase();
28
- }
29
- var _ = t(function({ conversation: t, isActive: n = !1, onClick: r }) {
30
- let { title: i, type: a, lastMessage: o, unreadCount: _, isPinned: v, isMuted: y, memberCount: b, updatedAt: x, sourceContext: S } = t, C = _ > 0, { t: w } = p(), T = (e, t) => {
31
- let n = w(e);
32
- return n === e ? t : n;
33
- }, E = {
34
- now: T("conversations.now", "now"),
35
- yesterday: T("conversations.yesterday", "Yesterday")
36
- };
37
- return /* @__PURE__ */ f("button", {
38
- "data-tour": "conversation-card",
39
- type: "button",
40
- onClick: () => r?.(t),
41
- className: e("w-full flex items-start gap-3 px-4 py-3 text-left rounded-lg", "transition-all duration-150 ease-in-out", "hover:bg-muted/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", n && "bg-primary/5 border-l-2 border-l-primary", !n && "border-l-2 border-l-transparent", C && !n && "bg-muted/20"),
42
- children: [/* @__PURE__ */ d("div", {
43
- className: e("flex-shrink-0 w-10 h-10 rounded-full flex items-center justify-center text-sm font-semibold", a === "DIRECT" ? "bg-status-info-bg-subtle text-status-info-text" : a === "CHANNEL" ? "bg-status-success-bg-subtle text-status-success-text" : a === "GROUP" ? "bg-accent text-accent-foreground" : "bg-muted text-muted-foreground"),
44
- children: t.avatar ? /* @__PURE__ */ d("img", {
45
- src: t.avatar,
46
- alt: i,
47
- className: "w-full h-full rounded-full object-cover"
48
- }) : a === "DIRECT" ? g(i) : /* @__PURE__ */ d(m, {
49
- type: a,
50
- size: 18
51
- })
52
- }), /* @__PURE__ */ f("div", {
53
- className: "flex-1 min-w-0",
54
- children: [
55
- /* @__PURE__ */ f("div", {
56
- className: "flex items-center justify-between gap-2",
57
- children: [/* @__PURE__ */ f("div", {
58
- className: "flex items-center gap-1.5 min-w-0",
59
- children: [
60
- a !== "DIRECT" && /* @__PURE__ */ d(m, {
61
- type: a,
62
- size: 12
63
- }),
64
- /* @__PURE__ */ d("span", {
65
- className: e("text-sm truncate", C ? "font-semibold text-foreground" : "font-medium text-foreground"),
66
- children: i
67
- }),
68
- v && /* @__PURE__ */ d(s, {
69
- size: 12,
70
- className: "flex-shrink-0 text-muted-foreground"
71
- }),
72
- y && /* @__PURE__ */ d(l, {
73
- size: 12,
74
- className: "flex-shrink-0 text-muted-foreground"
75
- })
76
- ]
77
- }), /* @__PURE__ */ d("span", {
78
- className: e("text-xs flex-shrink-0", C ? "text-primary font-medium" : "text-muted-foreground"),
79
- children: h(o ? o.createdAt : x, E)
80
- })]
81
- }),
82
- /* @__PURE__ */ f("div", {
83
- className: "flex items-center justify-between gap-2 mt-0.5",
84
- children: [/* @__PURE__ */ d("p", {
85
- className: e("text-xs truncate", C ? "text-foreground/80" : "text-muted-foreground"),
86
- children: o ? /* @__PURE__ */ f(u, { children: [o.sender.name && /* @__PURE__ */ f("span", {
87
- className: "font-medium",
88
- children: [
89
- o.sender.name,
90
- ":",
91
- " "
92
- ]
93
- }), o.content || T("conversations.sentAttachment", "Sent an attachment")] }) : /* @__PURE__ */ d("span", {
94
- className: "italic",
95
- children: T("conversations.noMessages", "No messages yet")
96
- })
97
- }), /* @__PURE__ */ f("div", {
98
- className: "flex items-center gap-1.5 flex-shrink-0",
99
- children: [a !== "DIRECT" && /* @__PURE__ */ f("span", {
100
- className: "text-[10px] text-muted-foreground flex items-center gap-0.5",
101
- children: [/* @__PURE__ */ d(c, { size: 10 }), b]
102
- }), C && /* @__PURE__ */ d("span", {
103
- className: "inline-flex items-center justify-center min-w-[18px] h-[18px] px-1 text-[10px] font-bold text-primary-foreground bg-primary rounded-full",
104
- children: _ > 99 ? "99+" : _
105
- })]
106
- })]
107
- }),
108
- S?.pagePath ? /* @__PURE__ */ d("p", {
109
- className: "mt-1 truncate text-[11px] text-muted-foreground",
110
- children: S.contextTitle || S.pagePath
111
- }) : null
112
- ]
113
- })]
114
- });
115
- });
116
- //#endregion
117
- export { _ as ConversationCard };
118
-
119
- //# sourceMappingURL=ConversationCard.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ConversationCard.js","names":[],"sources":["../../../src/conversations/components/ConversationCard.tsx"],"sourcesContent":["import { memo } from \"react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n MessageCircle,\n Hash,\n Users,\n Megaphone,\n Bot,\n HeadphonesIcon,\n Pin,\n VolumeX,\n} from \"lucide-react\";\nimport { cn } from \"../utils/cn\";\nimport type { Conversation } from \"../types\";\n\ninterface ConversationCardProps {\n conversation: Conversation;\n isActive?: boolean;\n onClick?: (conversation: Conversation) => void;\n}\n\n/**\n * Conversation type icon mapping\n */\nfunction ConversationTypeIcon({\n type,\n size = 16,\n}: {\n type: Conversation[\"type\"];\n size?: number;\n}) {\n switch (type) {\n case \"DIRECT\":\n return <MessageCircle size={size} />;\n case \"GROUP\":\n return <Users size={size} />;\n case \"CHANNEL\":\n return <Hash size={size} />;\n case \"BROADCAST\":\n case \"ANNOUNCEMENT\":\n return <Megaphone size={size} />;\n case \"BOT\":\n return <Bot size={size} />;\n case \"SUPPORT\":\n return <HeadphonesIcon size={size} />;\n default:\n return <MessageCircle size={size} />;\n }\n}\n\n/**\n * Format a timestamp relative to now (e.g., \"2m ago\", \"3h\", \"Yesterday\")\n */\nfunction formatRelativeTime(\n dateString: string,\n labels: { now: string; yesterday: string },\n): string {\n const now = new Date();\n const date = new Date(dateString);\n const diffMs = now.getTime() - date.getTime();\n const diffSec = Math.floor(diffMs / 1000);\n const diffMin = Math.floor(diffSec / 60);\n const diffHr = Math.floor(diffMin / 60);\n const diffDay = Math.floor(diffHr / 24);\n\n if (diffMin < 1) return labels.now;\n if (diffMin < 60) return `${diffMin}m`;\n if (diffHr < 24) return `${diffHr}h`;\n if (diffDay === 1) return labels.yesterday;\n if (diffDay < 7) return `${diffDay}d`;\n return date.toLocaleDateString(undefined, { month: \"short\", day: \"numeric\" });\n}\n\n/**\n * Generate initials from a conversation title\n */\nfunction getInitials(title: string): string {\n return title\n .split(\" \")\n .slice(0, 2)\n .map((word) => word[0])\n .join(\"\")\n .toUpperCase();\n}\n\n/**\n * ConversationCard - Displays a conversation in the list view.\n * Shows avatar, title, last message preview, unread count, and metadata.\n */\nexport const ConversationCard = memo(function ConversationCard({\n conversation,\n isActive = false,\n onClick,\n}: ConversationCardProps) {\n const {\n title,\n type,\n lastMessage,\n unreadCount,\n isPinned,\n isMuted,\n memberCount,\n updatedAt,\n sourceContext,\n } = conversation;\n\n const hasUnread = unreadCount > 0;\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n const timeLabels = {\n now: tr(\"conversations.now\", \"now\"),\n yesterday: tr(\"conversations.yesterday\", \"Yesterday\"),\n };\n\n return (\n <button\n data-tour=\"conversation-card\"\n type=\"button\"\n onClick={() => onClick?.(conversation)}\n className={cn(\n \"w-full flex items-start gap-3 px-4 py-3 text-left rounded-lg\",\n \"transition-all duration-150 ease-in-out\",\n \"hover:bg-muted/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n isActive && \"bg-primary/5 border-l-2 border-l-primary\",\n !isActive && \"border-l-2 border-l-transparent\",\n hasUnread && !isActive && \"bg-muted/20\",\n )}\n >\n {/* Avatar / Type Icon */}\n <div\n className={cn(\n \"flex-shrink-0 w-10 h-10 rounded-full flex items-center justify-center text-sm font-semibold\",\n type === \"DIRECT\"\n ? \"bg-status-info-bg-subtle text-status-info-text\"\n : type === \"CHANNEL\"\n ? \"bg-status-success-bg-subtle text-status-success-text\"\n : type === \"GROUP\"\n ? \"bg-accent text-accent-foreground\"\n : \"bg-muted text-muted-foreground\",\n )}\n >\n {conversation.avatar ? (\n <img\n src={conversation.avatar}\n alt={title}\n className=\"w-full h-full rounded-full object-cover\"\n />\n ) : type === \"DIRECT\" ? (\n getInitials(title)\n ) : (\n <ConversationTypeIcon type={type} size={18} />\n )}\n </div>\n\n {/* Content */}\n <div className=\"flex-1 min-w-0\">\n {/* Title row */}\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"flex items-center gap-1.5 min-w-0\">\n {type !== \"DIRECT\" && (\n <ConversationTypeIcon type={type} size={12} />\n )}\n <span\n className={cn(\n \"text-sm truncate\",\n hasUnread\n ? \"font-semibold text-foreground\"\n : \"font-medium text-foreground\",\n )}\n >\n {title}\n </span>\n {isPinned && (\n <Pin size={12} className=\"flex-shrink-0 text-muted-foreground\" />\n )}\n {isMuted && (\n <VolumeX\n size={12}\n className=\"flex-shrink-0 text-muted-foreground\"\n />\n )}\n </div>\n\n {/* Timestamp */}\n <span\n className={cn(\n \"text-xs flex-shrink-0\",\n hasUnread ? \"text-primary font-medium\" : \"text-muted-foreground\",\n )}\n >\n {lastMessage\n ? formatRelativeTime(lastMessage.createdAt, timeLabels)\n : formatRelativeTime(updatedAt, timeLabels)}\n </span>\n </div>\n\n {/* Last message preview */}\n <div className=\"flex items-center justify-between gap-2 mt-0.5\">\n <p\n className={cn(\n \"text-xs truncate\",\n hasUnread ? \"text-foreground/80\" : \"text-muted-foreground\",\n )}\n >\n {lastMessage ? (\n <>\n {lastMessage.sender.name && (\n <span className=\"font-medium\">\n {lastMessage.sender.name}:{\" \"}\n </span>\n )}\n {lastMessage.content ||\n tr(\"conversations.sentAttachment\", \"Sent an attachment\")}\n </>\n ) : (\n <span className=\"italic\">\n {tr(\"conversations.noMessages\", \"No messages yet\")}\n </span>\n )}\n </p>\n\n {/* Unread badge + member count */}\n <div className=\"flex items-center gap-1.5 flex-shrink-0\">\n {type !== \"DIRECT\" && (\n <span className=\"text-[10px] text-muted-foreground flex items-center gap-0.5\">\n <Users size={10} />\n {memberCount}\n </span>\n )}\n {hasUnread && (\n <span className=\"inline-flex items-center justify-center min-w-[18px] h-[18px] px-1 text-[10px] font-bold text-primary-foreground bg-primary rounded-full\">\n {unreadCount > 99 ? \"99+\" : unreadCount}\n </span>\n )}\n </div>\n </div>\n\n {sourceContext?.pagePath ? (\n <p className=\"mt-1 truncate text-[11px] text-muted-foreground\">\n {sourceContext.contextTitle || sourceContext.pagePath}\n </p>\n ) : null}\n </div>\n </button>\n );\n});\n"],"mappings":";;;;;;AAwBA,SAAS,EAAqB,EAC5B,SACA,UAAO,MAIN;AACD,SAAQ,GAAR;EACE,KAAK,SACH,QAAO,kBAAC,GAAD,EAAqB,SAAQ,CAAA;EACtC,KAAK,QACH,QAAO,kBAAC,GAAD,EAAa,SAAQ,CAAA;EAC9B,KAAK,UACH,QAAO,kBAAC,GAAD,EAAY,SAAQ,CAAA;EAC7B,KAAK;EACL,KAAK,eACH,QAAO,kBAAC,GAAD,EAAiB,SAAQ,CAAA;EAClC,KAAK,MACH,QAAO,kBAAC,GAAD,EAAW,SAAQ,CAAA;EAC5B,KAAK,UACH,QAAO,kBAAC,GAAD,EAAsB,SAAQ,CAAA;EACvC,QACE,QAAO,kBAAC,GAAD,EAAqB,SAAQ,CAAA;;;AAO1C,SAAS,EACP,GACA,GACQ;CACR,IAAM,oBAAM,IAAI,MAAM,EAChB,IAAO,IAAI,KAAK,EAAW,EAC3B,IAAS,EAAI,SAAS,GAAG,EAAK,SAAS,EACvC,IAAU,KAAK,MAAM,IAAS,IAAK,EACnC,IAAU,KAAK,MAAM,IAAU,GAAG,EAClC,IAAS,KAAK,MAAM,IAAU,GAAG,EACjC,IAAU,KAAK,MAAM,IAAS,GAAG;AAOvC,QALI,IAAU,IAAU,EAAO,MAC3B,IAAU,KAAW,GAAG,EAAQ,KAChC,IAAS,KAAW,GAAG,EAAO,KAC9B,MAAY,IAAU,EAAO,YAC7B,IAAU,IAAU,GAAG,EAAQ,KAC5B,EAAK,mBAAmB,KAAA,GAAW;EAAE,OAAO;EAAS,KAAK;EAAW,CAAC;;AAM/E,SAAS,EAAY,GAAuB;AAC1C,QAAO,EACJ,MAAM,IAAI,CACV,MAAM,GAAG,EAAE,CACX,KAAK,MAAS,EAAK,GAAG,CACtB,KAAK,GAAG,CACR,aAAa;;AAOlB,IAAa,IAAmB,EAAK,SAA0B,EAC7D,iBACA,cAAW,IACX,cACwB;CACxB,IAAM,EACJ,UACA,SACA,gBACA,gBACA,aACA,YACA,gBACA,cACA,qBACE,GAEE,IAAY,IAAc,GAC1B,EAAE,SAAM,GAAS,EACjB,KAAM,GAAa,MAA6B;EACpD,IAAM,IAAQ,EAAE,EAAI;AACpB,SAAO,MAAU,IAAM,IAAW;IAE9B,IAAa;EACjB,KAAK,EAAG,qBAAqB,MAAM;EACnC,WAAW,EAAG,2BAA2B,YAAY;EACtD;AAED,QACE,kBAAC,UAAD;EACE,aAAU;EACV,MAAK;EACL,eAAe,IAAU,EAAa;EACtC,WAAW,EACT,gEACA,2CACA,6FACA,KAAY,4CACZ,CAAC,KAAY,mCACb,KAAa,CAAC,KAAY,cAC3B;YAXH,CAcE,kBAAC,OAAD;GACE,WAAW,EACT,+FACA,MAAS,WACL,mDACA,MAAS,YACP,yDACA,MAAS,UACP,qCACA,iCACT;aAEA,EAAa,SACZ,kBAAC,OAAD;IACE,KAAK,EAAa;IAClB,KAAK;IACL,WAAU;IACV,CAAA,GACA,MAAS,WACX,EAAY,EAAM,GAElB,kBAAC,GAAD;IAA4B;IAAM,MAAM;IAAM,CAAA;GAE5C,CAAA,EAGN,kBAAC,OAAD;GAAK,WAAU;aAAf;IAEE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACG,MAAS,YACR,kBAAC,GAAD;QAA4B;QAAM,MAAM;QAAM,CAAA;OAEhD,kBAAC,QAAD;QACE,WAAW,EACT,oBACA,IACI,kCACA,8BACL;kBAEA;QACI,CAAA;OACN,KACC,kBAAC,GAAD;QAAK,MAAM;QAAI,WAAU;QAAwC,CAAA;OAElE,KACC,kBAAC,GAAD;QACE,MAAM;QACN,WAAU;QACV,CAAA;OAEA;SAGN,kBAAC,QAAD;MACE,WAAW,EACT,yBACA,IAAY,6BAA6B,wBAC1C;gBAGG,EADH,IACsB,EAAY,YACZ,GADuB,EACD;MACxC,CAAA,CACH;;IAGN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,KAAD;MACE,WAAW,EACT,oBACA,IAAY,uBAAuB,wBACpC;gBAEA,IACC,kBAAA,GAAA,EAAA,UAAA,CACG,EAAY,OAAO,QAClB,kBAAC,QAAD;OAAM,WAAU;iBAAhB;QACG,EAAY,OAAO;QAAK;QAAE;QACtB;UAER,EAAY,WACX,EAAG,gCAAgC,qBAAqB,CACzD,EAAA,CAAA,GAEH,kBAAC,QAAD;OAAM,WAAU;iBACb,EAAG,4BAA4B,kBAAkB;OAC7C,CAAA;MAEP,CAAA,EAGJ,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACG,MAAS,YACR,kBAAC,QAAD;OAAM,WAAU;iBAAhB,CACE,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA,EAClB,EACI;UAER,KACC,kBAAC,QAAD;OAAM,WAAU;iBACb,IAAc,KAAK,QAAQ;OACvB,CAAA,CAEL;QACF;;IAEL,GAAe,WACd,kBAAC,KAAD;KAAG,WAAU;eACV,EAAc,gBAAgB,EAAc;KAC3C,CAAA,GACF;IACA;KACC;;EAEX"}