@burdenoff/microfe-bigconsole 2026.805.2 → 2026.805.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/bigconsole/components/builder/inspector/DataBindingSection.js +109 -113
- package/dist/bigconsole/components/builder/inspector/DataBindingSection.js.map +1 -1
- package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js +115 -113
- package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js.map +1 -1
- package/dist/bigconsole/components/dashboard/DashboardCanvas.js +71 -62
- package/dist/bigconsole/components/dashboard/DashboardCanvas.js.map +1 -1
- package/dist/bigconsole/components/dashboard/DashboardToolbar.js +90 -89
- package/dist/bigconsole/components/dashboard/DashboardToolbar.js.map +1 -1
- package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js +56 -54
- package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js.map +1 -1
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js +126 -125
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js.map +1 -1
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js +151 -150
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js.map +1 -1
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js +77 -76
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js.map +1 -1
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js +97 -96
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js.map +1 -1
- package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js +172 -191
- package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js.map +1 -1
- package/dist/bigconsole/components/dashboard/PublishToStoreDialog.js +75 -83
- package/dist/bigconsole/components/dashboard/PublishToStoreDialog.js.map +1 -1
- package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js +151 -154
- package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js.map +1 -1
- package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js +181 -190
- package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js.map +1 -1
- package/dist/bigconsole/components/dashboard/TemplatePicker/TemplatePicker.js +1 -0
- package/dist/bigconsole/components/dashboard/WidgetPalette.js +110 -108
- package/dist/bigconsole/components/dashboard/WidgetPalette.js.map +1 -1
- package/dist/bigconsole/components/datasink/CacheTTLSelector.js +102 -103
- package/dist/bigconsole/components/datasink/CacheTTLSelector.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js +36 -41
- package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js +38 -37
- package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/ImportDataGuideDialog.js +113 -117
- package/dist/bigconsole/components/datasink/ImportDataGuideDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js +182 -197
- package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/RefreshTypeSelector.js +166 -168
- package/dist/bigconsole/components/datasink/RefreshTypeSelector.js.map +1 -1
- package/dist/bigconsole/components/parser/DataSinkSelector.js +87 -86
- package/dist/bigconsole/components/parser/DataSinkSelector.js.map +1 -1
- package/dist/bigconsole/components/parser/ImportParserDialog.js +196 -211
- package/dist/bigconsole/components/parser/ImportParserDialog.js.map +1 -1
- package/dist/bigconsole/components/parser/ParserSelector.js +130 -128
- package/dist/bigconsole/components/parser/ParserSelector.js.map +1 -1
- package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js +66 -63
- package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js.map +1 -1
- package/dist/bigconsole/components/preview/AiPreviewPanel.js +95 -91
- package/dist/bigconsole/components/preview/AiPreviewPanel.js.map +1 -1
- package/dist/bigconsole/components/widgets/ActionConfigDialog.js +222 -215
- package/dist/bigconsole/components/widgets/ActionConfigDialog.js.map +1 -1
- package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js +149 -145
- package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js.map +1 -1
- package/dist/bigconsole/components/widgets/PropertiesPanel.js +504 -470
- package/dist/bigconsole/components/widgets/PropertiesPanel.js.map +1 -1
- package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js +44 -47
- package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/chart/ChartConfig.js +143 -142
- package/dist/bigconsole/components/widgets/chart/ChartConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/comments/WidgetComments.js +101 -88
- package/dist/bigconsole/components/widgets/comments/WidgetComments.js.map +1 -1
- package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js +135 -134
- package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js.map +1 -1
- package/dist/bigconsole/components/widgets/form/FormWidget.js +167 -159
- package/dist/bigconsole/components/widgets/form/FormWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js +69 -68
- package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js +64 -72
- package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js +60 -59
- package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/list/ListConfig.js +57 -56
- package/dist/bigconsole/components/widgets/list/ListConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js +70 -69
- package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js +35 -34
- package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js.map +1 -1
- package/dist/bigconsole/components/widgets/metric-card/TrendIndicator.js +20 -19
- package/dist/bigconsole/components/widgets/metric-card/TrendIndicator.js.map +1 -1
- package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js +178 -177
- package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/progress/ProgressConfig.js +76 -75
- package/dist/bigconsole/components/widgets/progress/ProgressConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/table/TableConfig.js +183 -168
- package/dist/bigconsole/components/widgets/table/TableConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js +187 -180
- package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js.map +1 -1
- package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js +40 -38
- package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js.map +1 -1
- package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js +150 -148
- package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js.map +1 -1
- package/dist/bigconsole/pages/DashboardBuilderPage.js +181 -176
- package/dist/bigconsole/pages/DashboardBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/DashboardViewPage.js +196 -192
- package/dist/bigconsole/pages/DashboardViewPage.js.map +1 -1
- package/dist/bigconsole/pages/DashboardsPage.js +223 -219
- package/dist/bigconsole/pages/DashboardsPage.js.map +1 -1
- package/dist/bigconsole/pages/DataParsersPage.js +167 -170
- package/dist/bigconsole/pages/DataParsersPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSinkBuilderPage.js +204 -189
- package/dist/bigconsole/pages/DataSinkBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSinkViewPage.js +175 -169
- package/dist/bigconsole/pages/DataSinkViewPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSourcesPage.js +8 -7
- package/dist/bigconsole/pages/DataSourcesPage.js.map +1 -1
- package/dist/bigconsole/pages/InsightsPage.js +238 -208
- package/dist/bigconsole/pages/InsightsPage.js.map +1 -1
- package/dist/bigconsole/pages/ParserBuilderPage.js +464 -412
- package/dist/bigconsole/pages/ParserBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/ParserViewPage.js +92 -90
- package/dist/bigconsole/pages/ParserViewPage.js.map +1 -1
- package/dist/bigconsole/pages/PipelineBuilderPage.js +221 -194
- package/dist/bigconsole/pages/PipelineBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/PipelineViewPage.js +181 -184
- package/dist/bigconsole/pages/PipelineViewPage.js.map +1 -1
- package/dist/bigconsole/pages/PipelinesPage.js +128 -127
- package/dist/bigconsole/pages/PipelinesPage.js.map +1 -1
- package/dist/bigconsole/pages/SettingsPage.js +177 -172
- package/dist/bigconsole/pages/SettingsPage.js.map +1 -1
- package/dist/bigconsole/pages/WidgetDemoPage.js +121 -83
- package/dist/bigconsole/pages/WidgetDemoPage.js.map +1 -1
- package/dist/bigconsole/pages/WorkflowViewPage.js +199 -193
- package/dist/bigconsole/pages/WorkflowViewPage.js.map +1 -1
- package/dist/bigconsole/pages/WorkflowsPage.js +129 -128
- package/dist/bigconsole/pages/WorkflowsPage.js.map +1 -1
- package/dist/bigconsole/renderers/adapters/AdaptiveCardRenderer.js +111 -109
- package/dist/bigconsole/renderers/adapters/AdaptiveCardRenderer.js.map +1 -1
- package/dist/bigconsole/renderers/adapters/BlockKitRenderer.js +127 -126
- package/dist/bigconsole/renderers/adapters/BlockKitRenderer.js.map +1 -1
- package/dist/bigconsole/renderers/adapters/CustomRenderer.js +103 -103
- package/dist/bigconsole/renderers/adapters/CustomRenderer.js.map +1 -1
- package/package.json +2 -1
|
@@ -1,200 +1,213 @@
|
|
|
1
1
|
import e from "../../../hooks/useWidgetComments.js";
|
|
2
2
|
import { useCallback as t, useState as n } from "react";
|
|
3
3
|
import { Check as r, CornerDownRight as i, Loader2 as a, MessageSquare as o, RotateCcw as s, Send as c, Trash2 as l, X as u } from "lucide-react";
|
|
4
|
-
import {
|
|
4
|
+
import { useI18n as d } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
5
|
+
import { jsx as f, jsxs as p } from "react/jsx-runtime";
|
|
5
6
|
//#region src/bigconsole/components/widgets/comments/WidgetComments.tsx
|
|
6
|
-
function
|
|
7
|
-
return
|
|
7
|
+
function m(e, t) {
|
|
8
|
+
return e("bigconsole.widget.comments.authorLabel", "User {{id}}", { id: t.slice(0, 6) });
|
|
8
9
|
}
|
|
9
|
-
function
|
|
10
|
+
function h(e) {
|
|
10
11
|
let t = new Date(e);
|
|
11
12
|
return Number.isNaN(t.getTime()) ? "" : new Intl.DateTimeFormat(void 0, {
|
|
12
13
|
dateStyle: "medium",
|
|
13
14
|
timeStyle: "short"
|
|
14
15
|
}).format(t);
|
|
15
16
|
}
|
|
16
|
-
var
|
|
17
|
-
let u = !!e.resolvedAt,
|
|
18
|
-
return /* @__PURE__ */
|
|
17
|
+
var g = ({ comment: e, isReply: t, busy: n, onResolve: a, onDelete: o, onReply: c }) => {
|
|
18
|
+
let { t: u } = d(), g = !!e.resolvedAt, _ = e.content.text ?? e.content.markdown ?? "";
|
|
19
|
+
return /* @__PURE__ */ f("div", {
|
|
19
20
|
className: t ? "pl-6" : "",
|
|
20
|
-
children: /* @__PURE__ */
|
|
21
|
+
children: /* @__PURE__ */ p("div", {
|
|
21
22
|
className: "rounded-md border border-border-default bg-bg-surface p-2.5",
|
|
22
23
|
children: [
|
|
23
|
-
/* @__PURE__ */
|
|
24
|
+
/* @__PURE__ */ p("div", {
|
|
24
25
|
className: "flex items-center justify-between gap-2",
|
|
25
|
-
children: [/* @__PURE__ */
|
|
26
|
+
children: [/* @__PURE__ */ f("span", {
|
|
26
27
|
className: "text-xs font-medium text-text-primary",
|
|
27
|
-
children:
|
|
28
|
-
}), /* @__PURE__ */
|
|
28
|
+
children: m(u, e.authorId)
|
|
29
|
+
}), /* @__PURE__ */ f("span", {
|
|
29
30
|
className: "text-[10px] text-text-tertiary tabular-nums",
|
|
30
|
-
children:
|
|
31
|
+
children: h(e.createdAt)
|
|
31
32
|
})]
|
|
32
33
|
}),
|
|
33
|
-
/* @__PURE__ */
|
|
34
|
+
/* @__PURE__ */ f("p", {
|
|
34
35
|
className: "mt-1 whitespace-pre-wrap break-words text-sm text-text-secondary",
|
|
35
|
-
children:
|
|
36
|
+
children: _
|
|
36
37
|
}),
|
|
37
|
-
/* @__PURE__ */
|
|
38
|
+
/* @__PURE__ */ p("div", {
|
|
38
39
|
className: "mt-1.5 flex items-center gap-2",
|
|
39
40
|
children: [
|
|
40
|
-
|
|
41
|
+
g && /* @__PURE__ */ p("span", {
|
|
41
42
|
className: "inline-flex items-center gap-1 rounded px-1.5 py-0.5 text-[10px] font-medium bg-status-success-bg text-status-success-text",
|
|
42
|
-
children: [
|
|
43
|
+
children: [
|
|
44
|
+
/* @__PURE__ */ f(r, { className: "h-3 w-3" }),
|
|
45
|
+
" ",
|
|
46
|
+
u("bigconsole.widget.comments.resolvedBadge", "Resolved")
|
|
47
|
+
]
|
|
43
48
|
}),
|
|
44
|
-
c && /* @__PURE__ */
|
|
49
|
+
c && /* @__PURE__ */ p("button", {
|
|
45
50
|
type: "button",
|
|
46
51
|
disabled: n,
|
|
47
52
|
onClick: () => c(e.id),
|
|
48
53
|
className: "inline-flex items-center gap-1 text-[11px] text-text-tertiary hover:text-text-primary disabled:opacity-50",
|
|
49
|
-
children: [
|
|
54
|
+
children: [
|
|
55
|
+
/* @__PURE__ */ f(i, { className: "h-3 w-3" }),
|
|
56
|
+
" ",
|
|
57
|
+
u("bigconsole.widget.comments.reply", "Reply")
|
|
58
|
+
]
|
|
50
59
|
}),
|
|
51
|
-
/* @__PURE__ */
|
|
60
|
+
/* @__PURE__ */ p("button", {
|
|
52
61
|
type: "button",
|
|
53
62
|
disabled: n,
|
|
54
|
-
onClick: () => a(e.id, !
|
|
63
|
+
onClick: () => a(e.id, !g),
|
|
55
64
|
className: "inline-flex items-center gap-1 text-[11px] text-text-tertiary hover:text-text-primary disabled:opacity-50",
|
|
56
|
-
children: [
|
|
65
|
+
children: [f(g ? s : r, { className: "h-3 w-3" }), g ? u("bigconsole.widget.comments.reopen", "Reopen") : u("bigconsole.widget.comments.resolve", "Resolve")]
|
|
57
66
|
}),
|
|
58
|
-
/* @__PURE__ */
|
|
67
|
+
/* @__PURE__ */ p("button", {
|
|
59
68
|
type: "button",
|
|
60
69
|
disabled: n,
|
|
61
70
|
onClick: () => o(e.id),
|
|
62
71
|
className: "inline-flex items-center gap-1 text-[11px] text-status-error-text hover:opacity-80 disabled:opacity-50",
|
|
63
|
-
children: [
|
|
72
|
+
children: [
|
|
73
|
+
/* @__PURE__ */ f(l, { className: "h-3 w-3" }),
|
|
74
|
+
" ",
|
|
75
|
+
u("bigconsole.widget.comments.delete", "Delete")
|
|
76
|
+
]
|
|
64
77
|
})
|
|
65
78
|
]
|
|
66
79
|
})
|
|
67
80
|
]
|
|
68
81
|
})
|
|
69
82
|
});
|
|
70
|
-
},
|
|
71
|
-
let
|
|
72
|
-
let e =
|
|
73
|
-
e && await i(e) !== !1 &&
|
|
83
|
+
}, _ = ({ placeholder: e, busy: t, autoFocus: r, onSubmit: i, onCancel: o }) => {
|
|
84
|
+
let { t: s } = d(), [l, m] = n(""), h = async () => {
|
|
85
|
+
let e = l.trim();
|
|
86
|
+
e && await i(e) !== !1 && m("");
|
|
74
87
|
};
|
|
75
|
-
return /* @__PURE__ */
|
|
88
|
+
return /* @__PURE__ */ p("div", {
|
|
76
89
|
className: "flex items-end gap-2",
|
|
77
|
-
children: [/* @__PURE__ */
|
|
90
|
+
children: [/* @__PURE__ */ f("textarea", {
|
|
78
91
|
autoFocus: r,
|
|
79
|
-
value:
|
|
80
|
-
onChange: (e) =>
|
|
92
|
+
value: l,
|
|
93
|
+
onChange: (e) => m(e.target.value),
|
|
81
94
|
onKeyDown: (e) => {
|
|
82
|
-
(e.metaKey || e.ctrlKey) && e.key === "Enter" && (e.preventDefault(),
|
|
95
|
+
(e.metaKey || e.ctrlKey) && e.key === "Enter" && (e.preventDefault(), h());
|
|
83
96
|
},
|
|
84
97
|
rows: 2,
|
|
85
98
|
placeholder: e,
|
|
86
99
|
className: "flex-1 resize-none rounded-md border border-border-default bg-bg-surface px-2.5 py-1.5 text-sm text-text-primary placeholder:text-text-tertiary focus:outline-none focus:ring-2 focus:ring-action-primary-bg"
|
|
87
|
-
}), /* @__PURE__ */
|
|
100
|
+
}), /* @__PURE__ */ p("div", {
|
|
88
101
|
className: "flex flex-col gap-1",
|
|
89
|
-
children: [/* @__PURE__ */
|
|
102
|
+
children: [/* @__PURE__ */ f("button", {
|
|
90
103
|
type: "button",
|
|
91
|
-
disabled: t || !
|
|
92
|
-
onClick: () => void
|
|
93
|
-
title: "Post (⌘/Ctrl + Enter)",
|
|
104
|
+
disabled: t || !l.trim(),
|
|
105
|
+
onClick: () => void h(),
|
|
106
|
+
title: s("bigconsole.widget.comments.postTitle", "Post (⌘/Ctrl + Enter)"),
|
|
94
107
|
className: "inline-flex items-center justify-center rounded-md bg-action-primary-bg p-1.5 text-action-primary-text hover:opacity-90 disabled:opacity-50",
|
|
95
|
-
children: t ? /* @__PURE__ */
|
|
96
|
-
}), o && /* @__PURE__ */
|
|
108
|
+
children: t ? /* @__PURE__ */ f(a, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ f(c, { className: "h-4 w-4" })
|
|
109
|
+
}), o && /* @__PURE__ */ f("button", {
|
|
97
110
|
type: "button",
|
|
98
111
|
onClick: o,
|
|
99
112
|
className: "inline-flex items-center justify-center rounded-md border border-border-default p-1.5 text-text-tertiary hover:text-text-primary",
|
|
100
|
-
title: "Cancel reply",
|
|
101
|
-
children: /* @__PURE__ */
|
|
113
|
+
title: s("bigconsole.widget.comments.cancelReplyTitle", "Cancel reply"),
|
|
114
|
+
children: /* @__PURE__ */ f(u, { className: "h-4 w-4" })
|
|
102
115
|
})]
|
|
103
116
|
})]
|
|
104
117
|
});
|
|
105
|
-
},
|
|
106
|
-
let {
|
|
107
|
-
let n = await
|
|
108
|
-
return n && t &&
|
|
109
|
-
}, [
|
|
110
|
-
return /* @__PURE__ */
|
|
118
|
+
}, v = ({ widgetId: r, onClose: i }) => {
|
|
119
|
+
let { t: s } = d(), { threads: c, count: l, loading: m, error: h, mutating: v, addComment: y, resolveComment: b, deleteComment: x } = e(r), [S, C] = n(null), w = t(async (e, t) => {
|
|
120
|
+
let n = await y(e, t);
|
|
121
|
+
return n && t && C(null), n;
|
|
122
|
+
}, [y]);
|
|
123
|
+
return /* @__PURE__ */ p("div", {
|
|
111
124
|
className: "absolute inset-0 z-40 flex flex-col bg-bg-surface/98 backdrop-blur-sm",
|
|
112
125
|
role: "dialog",
|
|
113
|
-
"aria-label": "Widget comments",
|
|
126
|
+
"aria-label": s("bigconsole.widget.comments.dialogAriaLabel", "Widget comments"),
|
|
114
127
|
tabIndex: -1,
|
|
115
128
|
onClick: (e) => e.stopPropagation(),
|
|
116
129
|
onKeyDown: (e) => {
|
|
117
130
|
e.key === "Escape" && (e.stopPropagation(), i());
|
|
118
131
|
},
|
|
119
132
|
children: [
|
|
120
|
-
/* @__PURE__ */
|
|
133
|
+
/* @__PURE__ */ p("div", {
|
|
121
134
|
className: "flex items-center justify-between border-b border-border-default px-3 py-2",
|
|
122
|
-
children: [/* @__PURE__ */
|
|
135
|
+
children: [/* @__PURE__ */ p("div", {
|
|
123
136
|
className: "flex items-center gap-2 text-sm font-medium text-text-primary",
|
|
124
137
|
children: [
|
|
125
|
-
/* @__PURE__ */
|
|
126
|
-
"Comments",
|
|
127
|
-
/* @__PURE__ */
|
|
138
|
+
/* @__PURE__ */ f(o, { className: "h-4 w-4 text-text-secondary" }),
|
|
139
|
+
s("bigconsole.widget.comments.title", "Comments"),
|
|
140
|
+
/* @__PURE__ */ f("span", {
|
|
128
141
|
className: "rounded-full bg-bg-sunken px-1.5 py-0.5 text-[10px] text-text-secondary tabular-nums",
|
|
129
|
-
children:
|
|
142
|
+
children: l
|
|
130
143
|
})
|
|
131
144
|
]
|
|
132
|
-
}), /* @__PURE__ */
|
|
145
|
+
}), /* @__PURE__ */ f("button", {
|
|
133
146
|
type: "button",
|
|
134
147
|
onClick: i,
|
|
135
|
-
"aria-label": "Close comments",
|
|
148
|
+
"aria-label": s("bigconsole.widget.comments.closeAriaLabel", "Close comments"),
|
|
136
149
|
className: "rounded-md p-1 text-text-tertiary hover:bg-bg-sunken hover:text-text-primary",
|
|
137
|
-
children: /* @__PURE__ */
|
|
150
|
+
children: /* @__PURE__ */ f(u, { className: "h-4 w-4" })
|
|
138
151
|
})]
|
|
139
152
|
}),
|
|
140
|
-
/* @__PURE__ */
|
|
153
|
+
/* @__PURE__ */ p("div", {
|
|
141
154
|
className: "flex-1 space-y-3 overflow-auto p-3",
|
|
142
155
|
children: [
|
|
143
|
-
|
|
156
|
+
m && c.length === 0 && /* @__PURE__ */ f("div", {
|
|
144
157
|
className: "flex items-center justify-center py-8 text-text-tertiary",
|
|
145
|
-
children: /* @__PURE__ */
|
|
158
|
+
children: /* @__PURE__ */ f(a, { className: "h-5 w-5 animate-spin" })
|
|
146
159
|
}),
|
|
147
|
-
|
|
160
|
+
h && !m && /* @__PURE__ */ f("p", {
|
|
148
161
|
className: "rounded-md bg-status-error-bg px-2.5 py-2 text-xs text-status-error-text",
|
|
149
|
-
children: "Couldn’t load comments."
|
|
162
|
+
children: s("bigconsole.widget.comments.loadError", "Couldn’t load comments.")
|
|
150
163
|
}),
|
|
151
|
-
!
|
|
164
|
+
!m && !h && c.length === 0 && /* @__PURE__ */ f("p", {
|
|
152
165
|
className: "py-8 text-center text-sm text-text-tertiary",
|
|
153
|
-
children: "No comments yet. Start the conversation."
|
|
166
|
+
children: s("bigconsole.widget.comments.empty", "No comments yet. Start the conversation.")
|
|
154
167
|
}),
|
|
155
|
-
|
|
168
|
+
c.map(({ comment: e, replies: t }) => /* @__PURE__ */ p("div", {
|
|
156
169
|
className: "space-y-2",
|
|
157
170
|
children: [
|
|
158
|
-
/* @__PURE__ */
|
|
171
|
+
/* @__PURE__ */ f(g, {
|
|
159
172
|
comment: e,
|
|
160
|
-
busy:
|
|
161
|
-
onResolve: (e, t) => void
|
|
162
|
-
onDelete: (e) => void
|
|
163
|
-
onReply: (e) =>
|
|
173
|
+
busy: v,
|
|
174
|
+
onResolve: (e, t) => void b(e, t),
|
|
175
|
+
onDelete: (e) => void x(e),
|
|
176
|
+
onReply: (e) => C((t) => t === e ? null : e)
|
|
164
177
|
}),
|
|
165
|
-
t.map((e) => /* @__PURE__ */
|
|
178
|
+
t.map((e) => /* @__PURE__ */ f(g, {
|
|
166
179
|
comment: e,
|
|
167
180
|
isReply: !0,
|
|
168
|
-
busy:
|
|
169
|
-
onResolve: (e, t) => void
|
|
170
|
-
onDelete: (e) => void
|
|
181
|
+
busy: v,
|
|
182
|
+
onResolve: (e, t) => void b(e, t),
|
|
183
|
+
onDelete: (e) => void x(e)
|
|
171
184
|
}, e.id)),
|
|
172
|
-
|
|
185
|
+
S === e.id && /* @__PURE__ */ f("div", {
|
|
173
186
|
className: "pl-6",
|
|
174
|
-
children: /* @__PURE__ */
|
|
175
|
-
placeholder: "Write a reply…",
|
|
176
|
-
busy:
|
|
187
|
+
children: /* @__PURE__ */ f(_, {
|
|
188
|
+
placeholder: s("bigconsole.widget.comments.replyPlaceholder", "Write a reply…"),
|
|
189
|
+
busy: v,
|
|
177
190
|
autoFocus: !0,
|
|
178
|
-
onSubmit: (t) =>
|
|
179
|
-
onCancel: () =>
|
|
191
|
+
onSubmit: (t) => w(t, e.id),
|
|
192
|
+
onCancel: () => C(null)
|
|
180
193
|
})
|
|
181
194
|
})
|
|
182
195
|
]
|
|
183
196
|
}, e.id))
|
|
184
197
|
]
|
|
185
198
|
}),
|
|
186
|
-
/* @__PURE__ */
|
|
199
|
+
/* @__PURE__ */ f("div", {
|
|
187
200
|
className: "border-t border-border-default p-3",
|
|
188
|
-
children: /* @__PURE__ */
|
|
189
|
-
placeholder: "Add a comment…",
|
|
190
|
-
busy:
|
|
191
|
-
onSubmit: (e) =>
|
|
201
|
+
children: /* @__PURE__ */ f(_, {
|
|
202
|
+
placeholder: s("bigconsole.widget.comments.addPlaceholder", "Add a comment…"),
|
|
203
|
+
busy: v,
|
|
204
|
+
onSubmit: (e) => w(e)
|
|
192
205
|
})
|
|
193
206
|
})
|
|
194
207
|
]
|
|
195
208
|
});
|
|
196
209
|
};
|
|
197
210
|
//#endregion
|
|
198
|
-
export {
|
|
211
|
+
export { v as WidgetComments };
|
|
199
212
|
|
|
200
213
|
//# sourceMappingURL=WidgetComments.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WidgetComments.js","names":[],"sources":["../../../../../src/bigconsole/components/widgets/comments/WidgetComments.tsx"],"sourcesContent":["/**\n * WidgetComments\n *\n * Collaborative comment thread for a single widget, rendered as a slide-over\n * panel inside the widget container. Supports posting top-level comments and\n * threaded replies, resolving/reopening, and (soft) deleting. Data flows through\n * useWidgetComments → the federated EntityComment API.\n */\n\nimport { type FC, useState, useCallback } from 'react';\nimport { MessageSquare, Send, Check, RotateCcw, Trash2, X, CornerDownRight, Loader2 } from 'lucide-react';\nimport { useWidgetComments, type WidgetCommentThread } from '../../../hooks/useWidgetComments';\nimport type { EntityCommentFieldsFragment } from '../../../../generated/wspace-operations';\n\nexport interface WidgetCommentsProps {\n widgetId: string;\n /** Close the panel. */\n onClose: () => void;\n}\n\nfunction authorLabel(authorId: string): string {\n // We only have an opaque actor id here; show a short, stable handle.\n return `User ${authorId.slice(0, 6)}`;\n}\n\nfunction formatWhen(iso: string): string {\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return '';\n return new Intl.DateTimeFormat(undefined, { dateStyle: 'medium', timeStyle: 'short' }).format(d);\n}\n\ninterface CommentItemProps {\n comment: EntityCommentFieldsFragment;\n isReply?: boolean;\n busy: boolean;\n onResolve: (id: string, resolved: boolean) => void;\n onDelete: (id: string) => void;\n onReply?: (id: string) => void;\n}\n\nconst CommentItem: FC<CommentItemProps> = ({ comment, isReply, busy, onResolve, onDelete, onReply }) => {\n const resolved = !!comment.resolvedAt;\n const body = comment.content.text ?? comment.content.markdown ?? '';\n return (\n <div className={isReply ? 'pl-6' : ''}>\n <div className=\"rounded-md border border-border-default bg-bg-surface p-2.5\">\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"text-xs font-medium text-text-primary\">{authorLabel(comment.authorId)}</span>\n <span className=\"text-[10px] text-text-tertiary tabular-nums\">{formatWhen(comment.createdAt)}</span>\n </div>\n <p className=\"mt-1 whitespace-pre-wrap break-words text-sm text-text-secondary\">{body}</p>\n <div className=\"mt-1.5 flex items-center gap-2\">\n {resolved && (\n <span className=\"inline-flex items-center gap-1 rounded px-1.5 py-0.5 text-[10px] font-medium bg-status-success-bg text-status-success-text\">\n <Check className=\"h-3 w-3\" /> Resolved\n </span>\n )}\n {onReply && (\n <button\n type=\"button\"\n disabled={busy}\n onClick={() => onReply(comment.id)}\n className=\"inline-flex items-center gap-1 text-[11px] text-text-tertiary hover:text-text-primary disabled:opacity-50\"\n >\n <CornerDownRight className=\"h-3 w-3\" /> Reply\n </button>\n )}\n <button\n type=\"button\"\n disabled={busy}\n onClick={() => onResolve(comment.id, !resolved)}\n className=\"inline-flex items-center gap-1 text-[11px] text-text-tertiary hover:text-text-primary disabled:opacity-50\"\n >\n {resolved ? <RotateCcw className=\"h-3 w-3\" /> : <Check className=\"h-3 w-3\" />}\n {resolved ? 'Reopen' : 'Resolve'}\n </button>\n <button\n type=\"button\"\n disabled={busy}\n onClick={() => onDelete(comment.id)}\n className=\"inline-flex items-center gap-1 text-[11px] text-status-error-text hover:opacity-80 disabled:opacity-50\"\n >\n <Trash2 className=\"h-3 w-3\" /> Delete\n </button>\n </div>\n </div>\n </div>\n );\n};\n\ninterface ComposerProps {\n placeholder: string;\n busy: boolean;\n autoFocus?: boolean;\n /** Returns false when the post failed — the draft is kept so it isn't lost. */\n onSubmit: (text: string) => boolean | void | Promise<boolean | void>;\n onCancel?: () => void;\n}\n\nconst Composer: FC<ComposerProps> = ({ placeholder, busy, autoFocus, onSubmit, onCancel }) => {\n const [text, setText] = useState('');\n const submit = async () => {\n const v = text.trim();\n if (!v) return;\n // Only clear once the post succeeds; on failure the user keeps their draft.\n const ok = await onSubmit(v);\n if (ok !== false) setText('');\n };\n return (\n <div className=\"flex items-end gap-2\">\n <textarea\n autoFocus={autoFocus}\n value={text}\n onChange={(e) => setText(e.target.value)}\n onKeyDown={(e) => {\n if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') {\n e.preventDefault();\n void submit();\n }\n }}\n rows={2}\n placeholder={placeholder}\n className=\"flex-1 resize-none rounded-md border border-border-default bg-bg-surface px-2.5 py-1.5 text-sm text-text-primary placeholder:text-text-tertiary focus:outline-none focus:ring-2 focus:ring-action-primary-bg\"\n />\n <div className=\"flex flex-col gap-1\">\n <button\n type=\"button\"\n disabled={busy || !text.trim()}\n onClick={() => void submit()}\n title=\"Post (⌘/Ctrl + Enter)\"\n className=\"inline-flex items-center justify-center rounded-md bg-action-primary-bg p-1.5 text-action-primary-text hover:opacity-90 disabled:opacity-50\"\n >\n {busy ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Send className=\"h-4 w-4\" />}\n </button>\n {onCancel && (\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"inline-flex items-center justify-center rounded-md border border-border-default p-1.5 text-text-tertiary hover:text-text-primary\"\n title=\"Cancel reply\"\n >\n <X className=\"h-4 w-4\" />\n </button>\n )}\n </div>\n </div>\n );\n};\n\nexport const WidgetComments: FC<WidgetCommentsProps> = ({ widgetId, onClose }) => {\n const { threads, count, loading, error, mutating, addComment, resolveComment, deleteComment } =\n useWidgetComments(widgetId);\n const [replyTo, setReplyTo] = useState<string | null>(null);\n\n const handleAdd = useCallback(\n async (text: string, parentId?: string): Promise<boolean> => {\n const ok = await addComment(text, parentId);\n if (ok && parentId) setReplyTo(null);\n return ok;\n },\n [addComment]\n );\n\n return (\n <div\n className=\"absolute inset-0 z-40 flex flex-col bg-bg-surface/98 backdrop-blur-sm\"\n role=\"dialog\"\n aria-label=\"Widget comments\"\n tabIndex={-1}\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => {\n if (e.key === 'Escape') {\n e.stopPropagation();\n onClose();\n }\n }}\n >\n {/* Header */}\n <div className=\"flex items-center justify-between border-b border-border-default px-3 py-2\">\n <div className=\"flex items-center gap-2 text-sm font-medium text-text-primary\">\n <MessageSquare className=\"h-4 w-4 text-text-secondary\" />\n Comments\n <span className=\"rounded-full bg-bg-sunken px-1.5 py-0.5 text-[10px] text-text-secondary tabular-nums\">\n {count}\n </span>\n </div>\n <button\n type=\"button\"\n onClick={onClose}\n aria-label=\"Close comments\"\n className=\"rounded-md p-1 text-text-tertiary hover:bg-bg-sunken hover:text-text-primary\"\n >\n <X className=\"h-4 w-4\" />\n </button>\n </div>\n\n {/* Thread list */}\n <div className=\"flex-1 space-y-3 overflow-auto p-3\">\n {loading && threads.length === 0 && (\n <div className=\"flex items-center justify-center py-8 text-text-tertiary\">\n <Loader2 className=\"h-5 w-5 animate-spin\" />\n </div>\n )}\n {error && !loading && (\n <p className=\"rounded-md bg-status-error-bg px-2.5 py-2 text-xs text-status-error-text\">\n Couldn’t load comments.\n </p>\n )}\n {!loading && !error && threads.length === 0 && (\n <p className=\"py-8 text-center text-sm text-text-tertiary\">No comments yet. Start the conversation.</p>\n )}\n {threads.map(({ comment, replies }: WidgetCommentThread) => (\n <div key={comment.id} className=\"space-y-2\">\n <CommentItem\n comment={comment}\n busy={mutating}\n onResolve={(id, r) => void resolveComment(id, r)}\n onDelete={(id) => void deleteComment(id)}\n onReply={(id) => setReplyTo((cur) => (cur === id ? null : id))}\n />\n {replies.map((reply) => (\n <CommentItem\n key={reply.id}\n comment={reply}\n isReply\n busy={mutating}\n onResolve={(id, r) => void resolveComment(id, r)}\n onDelete={(id) => void deleteComment(id)}\n />\n ))}\n {replyTo === comment.id && (\n <div className=\"pl-6\">\n <Composer\n placeholder=\"Write a reply…\"\n busy={mutating}\n autoFocus\n onSubmit={(text) => handleAdd(text, comment.id)}\n onCancel={() => setReplyTo(null)}\n />\n </div>\n )}\n </div>\n ))}\n </div>\n\n {/* New top-level comment */}\n <div className=\"border-t border-border-default p-3\">\n <Composer placeholder=\"Add a comment…\" busy={mutating} onSubmit={(text) => handleAdd(text)} />\n </div>\n </div>\n );\n};\n\nexport default WidgetComments;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"WidgetComments.js","names":[],"sources":["../../../../../src/bigconsole/components/widgets/comments/WidgetComments.tsx"],"sourcesContent":["/**\n * WidgetComments\n *\n * Collaborative comment thread for a single widget, rendered as a slide-over\n * panel inside the widget container. Supports posting top-level comments and\n * threaded replies, resolving/reopening, and (soft) deleting. Data flows through\n * useWidgetComments → the federated EntityComment API.\n */\n\nimport { type FC, useState, useCallback } from 'react';\nimport { MessageSquare, Send, Check, RotateCcw, Trash2, X, CornerDownRight, Loader2 } from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useWidgetComments, type WidgetCommentThread } from '../../../hooks/useWidgetComments';\nimport type { EntityCommentFieldsFragment } from '../../../../generated/wspace-operations';\n\nexport interface WidgetCommentsProps {\n widgetId: string;\n /** Close the panel. */\n onClose: () => void;\n}\n\nfunction authorLabel(\n t: (\n key: string,\n fallbackOrParams?: string | Record<string, string | number>,\n params?: Record<string, string | number>\n ) => string,\n authorId: string\n): string {\n // We only have an opaque actor id here; show a short, stable handle.\n return t('bigconsole.widget.comments.authorLabel', 'User {{id}}', { id: authorId.slice(0, 6) });\n}\n\nfunction formatWhen(iso: string): string {\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return '';\n return new Intl.DateTimeFormat(undefined, { dateStyle: 'medium', timeStyle: 'short' }).format(d);\n}\n\ninterface CommentItemProps {\n comment: EntityCommentFieldsFragment;\n isReply?: boolean;\n busy: boolean;\n onResolve: (id: string, resolved: boolean) => void;\n onDelete: (id: string) => void;\n onReply?: (id: string) => void;\n}\n\nconst CommentItem: FC<CommentItemProps> = ({ comment, isReply, busy, onResolve, onDelete, onReply }) => {\n const { t } = useI18n();\n const resolved = !!comment.resolvedAt;\n const body = comment.content.text ?? comment.content.markdown ?? '';\n return (\n <div className={isReply ? 'pl-6' : ''}>\n <div className=\"rounded-md border border-border-default bg-bg-surface p-2.5\">\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"text-xs font-medium text-text-primary\">{authorLabel(t, comment.authorId)}</span>\n <span className=\"text-[10px] text-text-tertiary tabular-nums\">{formatWhen(comment.createdAt)}</span>\n </div>\n <p className=\"mt-1 whitespace-pre-wrap break-words text-sm text-text-secondary\">{body}</p>\n <div className=\"mt-1.5 flex items-center gap-2\">\n {resolved && (\n <span className=\"inline-flex items-center gap-1 rounded px-1.5 py-0.5 text-[10px] font-medium bg-status-success-bg text-status-success-text\">\n <Check className=\"h-3 w-3\" /> {t('bigconsole.widget.comments.resolvedBadge', 'Resolved')}\n </span>\n )}\n {onReply && (\n <button\n type=\"button\"\n disabled={busy}\n onClick={() => onReply(comment.id)}\n className=\"inline-flex items-center gap-1 text-[11px] text-text-tertiary hover:text-text-primary disabled:opacity-50\"\n >\n <CornerDownRight className=\"h-3 w-3\" /> {t('bigconsole.widget.comments.reply', 'Reply')}\n </button>\n )}\n <button\n type=\"button\"\n disabled={busy}\n onClick={() => onResolve(comment.id, !resolved)}\n className=\"inline-flex items-center gap-1 text-[11px] text-text-tertiary hover:text-text-primary disabled:opacity-50\"\n >\n {resolved ? <RotateCcw className=\"h-3 w-3\" /> : <Check className=\"h-3 w-3\" />}\n {resolved\n ? t('bigconsole.widget.comments.reopen', 'Reopen')\n : t('bigconsole.widget.comments.resolve', 'Resolve')}\n </button>\n <button\n type=\"button\"\n disabled={busy}\n onClick={() => onDelete(comment.id)}\n className=\"inline-flex items-center gap-1 text-[11px] text-status-error-text hover:opacity-80 disabled:opacity-50\"\n >\n <Trash2 className=\"h-3 w-3\" /> {t('bigconsole.widget.comments.delete', 'Delete')}\n </button>\n </div>\n </div>\n </div>\n );\n};\n\ninterface ComposerProps {\n placeholder: string;\n busy: boolean;\n autoFocus?: boolean;\n /** Returns false when the post failed — the draft is kept so it isn't lost. */\n onSubmit: (text: string) => boolean | void | Promise<boolean | void>;\n onCancel?: () => void;\n}\n\nconst Composer: FC<ComposerProps> = ({ placeholder, busy, autoFocus, onSubmit, onCancel }) => {\n const { t } = useI18n();\n const [text, setText] = useState('');\n const submit = async () => {\n const v = text.trim();\n if (!v) return;\n // Only clear once the post succeeds; on failure the user keeps their draft.\n const ok = await onSubmit(v);\n if (ok !== false) setText('');\n };\n return (\n <div className=\"flex items-end gap-2\">\n <textarea\n autoFocus={autoFocus}\n value={text}\n onChange={(e) => setText(e.target.value)}\n onKeyDown={(e) => {\n if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') {\n e.preventDefault();\n void submit();\n }\n }}\n rows={2}\n placeholder={placeholder}\n className=\"flex-1 resize-none rounded-md border border-border-default bg-bg-surface px-2.5 py-1.5 text-sm text-text-primary placeholder:text-text-tertiary focus:outline-none focus:ring-2 focus:ring-action-primary-bg\"\n />\n <div className=\"flex flex-col gap-1\">\n <button\n type=\"button\"\n disabled={busy || !text.trim()}\n onClick={() => void submit()}\n title={t('bigconsole.widget.comments.postTitle', 'Post (⌘/Ctrl + Enter)')}\n className=\"inline-flex items-center justify-center rounded-md bg-action-primary-bg p-1.5 text-action-primary-text hover:opacity-90 disabled:opacity-50\"\n >\n {busy ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Send className=\"h-4 w-4\" />}\n </button>\n {onCancel && (\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"inline-flex items-center justify-center rounded-md border border-border-default p-1.5 text-text-tertiary hover:text-text-primary\"\n title={t('bigconsole.widget.comments.cancelReplyTitle', 'Cancel reply')}\n >\n <X className=\"h-4 w-4\" />\n </button>\n )}\n </div>\n </div>\n );\n};\n\nexport const WidgetComments: FC<WidgetCommentsProps> = ({ widgetId, onClose }) => {\n const { t } = useI18n();\n const { threads, count, loading, error, mutating, addComment, resolveComment, deleteComment } =\n useWidgetComments(widgetId);\n const [replyTo, setReplyTo] = useState<string | null>(null);\n\n const handleAdd = useCallback(\n async (text: string, parentId?: string): Promise<boolean> => {\n const ok = await addComment(text, parentId);\n if (ok && parentId) setReplyTo(null);\n return ok;\n },\n [addComment]\n );\n\n return (\n <div\n className=\"absolute inset-0 z-40 flex flex-col bg-bg-surface/98 backdrop-blur-sm\"\n role=\"dialog\"\n aria-label={t('bigconsole.widget.comments.dialogAriaLabel', 'Widget comments')}\n tabIndex={-1}\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => {\n if (e.key === 'Escape') {\n e.stopPropagation();\n onClose();\n }\n }}\n >\n {/* Header */}\n <div className=\"flex items-center justify-between border-b border-border-default px-3 py-2\">\n <div className=\"flex items-center gap-2 text-sm font-medium text-text-primary\">\n <MessageSquare className=\"h-4 w-4 text-text-secondary\" />\n {t('bigconsole.widget.comments.title', 'Comments')}\n <span className=\"rounded-full bg-bg-sunken px-1.5 py-0.5 text-[10px] text-text-secondary tabular-nums\">\n {count}\n </span>\n </div>\n <button\n type=\"button\"\n onClick={onClose}\n aria-label={t('bigconsole.widget.comments.closeAriaLabel', 'Close comments')}\n className=\"rounded-md p-1 text-text-tertiary hover:bg-bg-sunken hover:text-text-primary\"\n >\n <X className=\"h-4 w-4\" />\n </button>\n </div>\n\n {/* Thread list */}\n <div className=\"flex-1 space-y-3 overflow-auto p-3\">\n {loading && threads.length === 0 && (\n <div className=\"flex items-center justify-center py-8 text-text-tertiary\">\n <Loader2 className=\"h-5 w-5 animate-spin\" />\n </div>\n )}\n {error && !loading && (\n <p className=\"rounded-md bg-status-error-bg px-2.5 py-2 text-xs text-status-error-text\">\n {t('bigconsole.widget.comments.loadError', 'Couldn’t load comments.')}\n </p>\n )}\n {!loading && !error && threads.length === 0 && (\n <p className=\"py-8 text-center text-sm text-text-tertiary\">\n {t('bigconsole.widget.comments.empty', 'No comments yet. Start the conversation.')}\n </p>\n )}\n {threads.map(({ comment, replies }: WidgetCommentThread) => (\n <div key={comment.id} className=\"space-y-2\">\n <CommentItem\n comment={comment}\n busy={mutating}\n onResolve={(id, r) => void resolveComment(id, r)}\n onDelete={(id) => void deleteComment(id)}\n onReply={(id) => setReplyTo((cur) => (cur === id ? null : id))}\n />\n {replies.map((reply) => (\n <CommentItem\n key={reply.id}\n comment={reply}\n isReply\n busy={mutating}\n onResolve={(id, r) => void resolveComment(id, r)}\n onDelete={(id) => void deleteComment(id)}\n />\n ))}\n {replyTo === comment.id && (\n <div className=\"pl-6\">\n <Composer\n placeholder={t('bigconsole.widget.comments.replyPlaceholder', 'Write a reply…')}\n busy={mutating}\n autoFocus\n onSubmit={(text) => handleAdd(text, comment.id)}\n onCancel={() => setReplyTo(null)}\n />\n </div>\n )}\n </div>\n ))}\n </div>\n\n {/* New top-level comment */}\n <div className=\"border-t border-border-default p-3\">\n <Composer\n placeholder={t('bigconsole.widget.comments.addPlaceholder', 'Add a comment…')}\n busy={mutating}\n onSubmit={(text) => handleAdd(text)}\n />\n </div>\n </div>\n );\n};\n\nexport default WidgetComments;\n"],"mappings":"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"}
|