@automattic/agenttic-client 0.1.0
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/README.md +409 -0
- package/dist/MockSalesGraph-ORPXGMCD.js +7 -0
- package/dist/chunk-LAB4XYXR.js +688 -0
- package/dist/chunk-ZDG7Y2LU.js +39 -0
- package/dist/client/index.d.ts +44 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2137 -0
- package/dist/message-actions/factories.d.ts.map +1 -0
- package/dist/message-actions/index.d.ts.map +1 -0
- package/dist/message-actions/resolver.d.ts.map +1 -0
- package/dist/message-actions/useMessageActions.d.ts.map +1 -0
- package/dist/mocks/index.js +288 -0
- package/dist/react/agentManager.d.ts.map +1 -0
- package/dist/react/useAgentChat.d.ts.map +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1,688 @@
|
|
|
1
|
+
// src/markdown-extensions/charts/BarChart.tsx
|
|
2
|
+
import { BarChart as AutomatticBarChart } from "@automattic/charts";
|
|
3
|
+
|
|
4
|
+
// src/markdown-extensions/charts/BaseChart.tsx
|
|
5
|
+
import {
|
|
6
|
+
defaultTheme,
|
|
7
|
+
ThemeProvider
|
|
8
|
+
} from "@automattic/charts";
|
|
9
|
+
import { useMemo } from "react";
|
|
10
|
+
|
|
11
|
+
// src/utils/theme.ts
|
|
12
|
+
var getCSSVariable = (variableName, fallback = "") => {
|
|
13
|
+
try {
|
|
14
|
+
const value = getComputedStyle(document.documentElement).getPropertyValue(variableName).trim();
|
|
15
|
+
return value || fallback;
|
|
16
|
+
} catch (error) {
|
|
17
|
+
console.warn(`Failed to get CSS variable ${variableName}:`, error);
|
|
18
|
+
return fallback;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// src/markdown-extensions/charts/ChartError.tsx
|
|
23
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
24
|
+
var ChartError = ({ message, details }) => /* @__PURE__ */ jsxs("div", { className: "chart-error", children: [
|
|
25
|
+
/* @__PURE__ */ jsx("strong", { children: "Chart Error:" }),
|
|
26
|
+
" ",
|
|
27
|
+
message,
|
|
28
|
+
details && /* @__PURE__ */ jsxs("details", { children: [
|
|
29
|
+
/* @__PURE__ */ jsx("summary", { children: "Show Details" }),
|
|
30
|
+
/* @__PURE__ */ jsx("pre", { children: details })
|
|
31
|
+
] })
|
|
32
|
+
] });
|
|
33
|
+
|
|
34
|
+
// src/markdown-extensions/charts/BaseChart.tsx
|
|
35
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
36
|
+
var BaseChart = ({
|
|
37
|
+
children,
|
|
38
|
+
error
|
|
39
|
+
}) => {
|
|
40
|
+
const customTheme = useMemo(() => {
|
|
41
|
+
const primaryColor = getCSSVariable("--color-primary", "#4F46E5");
|
|
42
|
+
const colors = [primaryColor, "#f0b849", "#00a32a", "#8c5e94"];
|
|
43
|
+
return {
|
|
44
|
+
...defaultTheme,
|
|
45
|
+
colors,
|
|
46
|
+
legendLabelStyles: {
|
|
47
|
+
fontSize: "11px",
|
|
48
|
+
fontWeight: "400",
|
|
49
|
+
lineHeight: "1.2",
|
|
50
|
+
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif'
|
|
51
|
+
},
|
|
52
|
+
legendItemStyles: {
|
|
53
|
+
padding: "2px 0",
|
|
54
|
+
display: "flex",
|
|
55
|
+
alignItems: "center"
|
|
56
|
+
},
|
|
57
|
+
legendGlyphSize: 12
|
|
58
|
+
};
|
|
59
|
+
}, []);
|
|
60
|
+
if (error) {
|
|
61
|
+
return /* @__PURE__ */ jsx2(ChartError, { message: error.message, details: error.details });
|
|
62
|
+
}
|
|
63
|
+
return /* @__PURE__ */ jsx2("div", { className: "chart-block", children: /* @__PURE__ */ jsx2("div", { className: "chart-container", children: /* @__PURE__ */ jsx2(ThemeProvider, { theme: customTheme, children }) }) });
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// src/markdown-extensions/charts/utils/chartUtils.ts
|
|
67
|
+
var calculateBottomMargin = (minMargin = 80, charWidth = 6, padding = 25, labelLength) => {
|
|
68
|
+
const calculatedLength = labelLength ?? 5;
|
|
69
|
+
return Math.max(minMargin, calculatedLength * charWidth + padding);
|
|
70
|
+
};
|
|
71
|
+
var parseDate = (dateValue) => {
|
|
72
|
+
if (dateValue instanceof Date) {
|
|
73
|
+
return dateValue;
|
|
74
|
+
}
|
|
75
|
+
const dateStr = String(dateValue);
|
|
76
|
+
if (dateStr.includes("T") || dateStr.includes(" ")) {
|
|
77
|
+
return new Date(dateStr);
|
|
78
|
+
}
|
|
79
|
+
const [year, month, day] = dateStr.split("-").map(Number);
|
|
80
|
+
return new Date(year, month - 1, day);
|
|
81
|
+
};
|
|
82
|
+
var getTimeAxisConfig = (data) => {
|
|
83
|
+
const allDataPoints = [];
|
|
84
|
+
data?.forEach((series) => {
|
|
85
|
+
if (series?.data) {
|
|
86
|
+
allDataPoints.push(...series.data);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
if (allDataPoints.length === 0) {
|
|
90
|
+
return {};
|
|
91
|
+
}
|
|
92
|
+
const allDates = allDataPoints.map((point) => {
|
|
93
|
+
if (point && "date" in point && point.date) {
|
|
94
|
+
return parseDate(point.date);
|
|
95
|
+
}
|
|
96
|
+
if (point && "dateString" in point && point.dateString) {
|
|
97
|
+
return parseDate(point.dateString);
|
|
98
|
+
}
|
|
99
|
+
return null;
|
|
100
|
+
}).filter(
|
|
101
|
+
(date) => date !== null && !isNaN(date.getTime())
|
|
102
|
+
).sort((a, b) => a.getTime() - b.getTime());
|
|
103
|
+
const uniqueDates = Array.from(
|
|
104
|
+
new Set(allDates.map((d) => d.getTime()))
|
|
105
|
+
).map((timestamp) => new Date(timestamp));
|
|
106
|
+
if (uniqueDates.length === 0) {
|
|
107
|
+
return {};
|
|
108
|
+
}
|
|
109
|
+
const indices = [
|
|
110
|
+
0,
|
|
111
|
+
Math.floor(uniqueDates.length / 3),
|
|
112
|
+
Math.floor(2 * uniqueDates.length / 3),
|
|
113
|
+
uniqueDates.length - 1
|
|
114
|
+
];
|
|
115
|
+
const tickValues = indices.map((i) => uniqueDates[i]).filter(
|
|
116
|
+
(date) => date !== null && !isNaN(date.getTime())
|
|
117
|
+
);
|
|
118
|
+
return {
|
|
119
|
+
orientation: "bottom",
|
|
120
|
+
tickValues,
|
|
121
|
+
tickFormat: (value) => {
|
|
122
|
+
let date = null;
|
|
123
|
+
if (value instanceof Date) {
|
|
124
|
+
date = value;
|
|
125
|
+
} else if (typeof value === "string") {
|
|
126
|
+
const parsed = new Date(value);
|
|
127
|
+
if (!isNaN(parsed.getTime())) {
|
|
128
|
+
date = parsed;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (date) {
|
|
132
|
+
return `${(date.getMonth() + 1).toString().padStart(2, "0")}/${date.getDate().toString().padStart(2, "0")}`;
|
|
133
|
+
}
|
|
134
|
+
return String(value || "");
|
|
135
|
+
},
|
|
136
|
+
tickLabelProps: () => ({
|
|
137
|
+
fontSize: 11,
|
|
138
|
+
textAnchor: "end",
|
|
139
|
+
angle: -90,
|
|
140
|
+
dx: 0,
|
|
141
|
+
dy: -5
|
|
142
|
+
})
|
|
143
|
+
};
|
|
144
|
+
};
|
|
145
|
+
var getDefaultChartMargins = (customMargin) => {
|
|
146
|
+
const defaultMargin = {
|
|
147
|
+
top: 15,
|
|
148
|
+
right: 20,
|
|
149
|
+
bottom: 100,
|
|
150
|
+
left: 50
|
|
151
|
+
};
|
|
152
|
+
return {
|
|
153
|
+
...defaultMargin,
|
|
154
|
+
...customMargin,
|
|
155
|
+
bottom: calculateBottomMargin(120)
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
// src/markdown-extensions/charts/BarChart.tsx
|
|
160
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
161
|
+
var BarChart = (props) => {
|
|
162
|
+
const {
|
|
163
|
+
data,
|
|
164
|
+
currency,
|
|
165
|
+
showLegend = true,
|
|
166
|
+
withTooltips = true,
|
|
167
|
+
renderTooltip,
|
|
168
|
+
margin: defaultMargin,
|
|
169
|
+
mode = "time-comparison",
|
|
170
|
+
truncateLabels = true,
|
|
171
|
+
maxLabelLength = 15,
|
|
172
|
+
error,
|
|
173
|
+
...restProps
|
|
174
|
+
} = props;
|
|
175
|
+
const truncateText = (text, maxLength) => {
|
|
176
|
+
if (!truncateLabels || text.length <= maxLength) {
|
|
177
|
+
return text;
|
|
178
|
+
}
|
|
179
|
+
return text.substring(0, maxLength - 3) + "...";
|
|
180
|
+
};
|
|
181
|
+
const calculateBarChartBottomMargin = () => {
|
|
182
|
+
if (mode === "item-comparison" && data && data.length > 0) {
|
|
183
|
+
let longestLabel = "";
|
|
184
|
+
data.forEach((series) => {
|
|
185
|
+
if (series?.data) {
|
|
186
|
+
series.data.forEach((item) => {
|
|
187
|
+
const label = item.label || "";
|
|
188
|
+
const truncated = truncateText(label, maxLabelLength);
|
|
189
|
+
if (truncated.length > longestLabel.length) {
|
|
190
|
+
longestLabel = truncated;
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
return calculateBottomMargin(80, 6, 25, longestLabel.length);
|
|
196
|
+
}
|
|
197
|
+
return calculateBottomMargin();
|
|
198
|
+
};
|
|
199
|
+
const margin = {
|
|
200
|
+
...getDefaultChartMargins(defaultMargin),
|
|
201
|
+
bottom: calculateBarChartBottomMargin()
|
|
202
|
+
};
|
|
203
|
+
const getAxisConfig = () => {
|
|
204
|
+
if (mode === "item-comparison") {
|
|
205
|
+
return {
|
|
206
|
+
xScale: {
|
|
207
|
+
type: "band",
|
|
208
|
+
padding: 0.2
|
|
209
|
+
},
|
|
210
|
+
axis: {
|
|
211
|
+
x: {
|
|
212
|
+
orientation: "bottom",
|
|
213
|
+
tickFormat: (value) => truncateText(value, maxLabelLength),
|
|
214
|
+
tickLabelProps: {
|
|
215
|
+
fontSize: 11,
|
|
216
|
+
textAnchor: "end",
|
|
217
|
+
angle: -90,
|
|
218
|
+
dx: 0,
|
|
219
|
+
dy: -5
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
return {
|
|
226
|
+
xScale: { type: "time" },
|
|
227
|
+
axis: {
|
|
228
|
+
x: {
|
|
229
|
+
...getTimeAxisConfig(data),
|
|
230
|
+
dy: -15
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
};
|
|
235
|
+
const axisConfig = getAxisConfig();
|
|
236
|
+
const chartProps = {
|
|
237
|
+
data,
|
|
238
|
+
withTooltips,
|
|
239
|
+
renderTooltip,
|
|
240
|
+
showLegend,
|
|
241
|
+
legendOrientation: "horizontal",
|
|
242
|
+
legendAlignmentHorizontal: "center",
|
|
243
|
+
legendAlignmentVertical: "bottom",
|
|
244
|
+
margin,
|
|
245
|
+
// TODO: Fix this inconsistency that seems to be in @automattic/charts
|
|
246
|
+
// Item-comparison mode requires axis config wrapped in 'options' prop
|
|
247
|
+
// Time-comparison mode requires axis config spread directly
|
|
248
|
+
...mode === "item-comparison" ? { options: axisConfig } : axisConfig,
|
|
249
|
+
...currency && { currency },
|
|
250
|
+
...restProps
|
|
251
|
+
};
|
|
252
|
+
return /* @__PURE__ */ jsx3(BaseChart, { error, children: /* @__PURE__ */ jsx3(AutomatticBarChart, { ...chartProps }) });
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
// src/markdown-extensions/charts/LineChart.tsx
|
|
256
|
+
import { LineChart as AutomatticLineChart } from "@automattic/charts";
|
|
257
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
258
|
+
var LineChart = (props) => {
|
|
259
|
+
const {
|
|
260
|
+
data,
|
|
261
|
+
currency,
|
|
262
|
+
showLegend = true,
|
|
263
|
+
withTooltips = true,
|
|
264
|
+
renderTooltip,
|
|
265
|
+
margin: defaultMargin,
|
|
266
|
+
withGradientFill = true,
|
|
267
|
+
error,
|
|
268
|
+
...restProps
|
|
269
|
+
} = props;
|
|
270
|
+
const margin = {
|
|
271
|
+
...getDefaultChartMargins(),
|
|
272
|
+
bottom: 80
|
|
273
|
+
};
|
|
274
|
+
const chartProps = {
|
|
275
|
+
data,
|
|
276
|
+
withTooltips,
|
|
277
|
+
renderTooltip,
|
|
278
|
+
showLegend,
|
|
279
|
+
withGradientFill,
|
|
280
|
+
withLegendGlyph: false,
|
|
281
|
+
legendOrientation: "horizontal",
|
|
282
|
+
legendAlignmentHorizontal: "center",
|
|
283
|
+
legendAlignmentVertical: "bottom",
|
|
284
|
+
margin,
|
|
285
|
+
options: {
|
|
286
|
+
xScale: {
|
|
287
|
+
type: "time"
|
|
288
|
+
},
|
|
289
|
+
axis: {
|
|
290
|
+
x: {
|
|
291
|
+
...getTimeAxisConfig(data)
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
},
|
|
295
|
+
...currency && { currency },
|
|
296
|
+
...restProps
|
|
297
|
+
};
|
|
298
|
+
return /* @__PURE__ */ jsx4(BaseChart, { error, children: /* @__PURE__ */ jsx4(AutomatticLineChart, { ...chartProps }) });
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
// src/markdown-extensions/charts/ChartBlock.tsx
|
|
302
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
303
|
+
import { __, sprintf } from "@wordpress/i18n";
|
|
304
|
+
|
|
305
|
+
// src/markdown-extensions/charts/ChartErrorBoundary.tsx
|
|
306
|
+
import { Component } from "react";
|
|
307
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
308
|
+
var ChartErrorBoundary = class extends Component {
|
|
309
|
+
constructor(props) {
|
|
310
|
+
super(props);
|
|
311
|
+
this.state = {
|
|
312
|
+
hasError: false,
|
|
313
|
+
error: null,
|
|
314
|
+
errorInfo: null
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
static getDerivedStateFromError(error) {
|
|
318
|
+
return {
|
|
319
|
+
hasError: true,
|
|
320
|
+
error,
|
|
321
|
+
errorInfo: null
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
componentDidCatch(error, errorInfo) {
|
|
325
|
+
console.error("Chart rendering error:", error);
|
|
326
|
+
console.error("Error info:", errorInfo);
|
|
327
|
+
if (this.props.chartData) {
|
|
328
|
+
console.error(
|
|
329
|
+
"Chart data that caused the error:",
|
|
330
|
+
this.props.chartData
|
|
331
|
+
);
|
|
332
|
+
try {
|
|
333
|
+
const parsed = JSON.parse(this.props.chartData);
|
|
334
|
+
console.error("Parsed chart data:", parsed);
|
|
335
|
+
} catch (parseError) {
|
|
336
|
+
console.error("Could not parse chart data as JSON");
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
this.setState({
|
|
340
|
+
errorInfo
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
render() {
|
|
344
|
+
if (this.state.hasError) {
|
|
345
|
+
const errorMessage = this.state.error?.message || "An error occurred while rendering the chart";
|
|
346
|
+
const errorDetails = [
|
|
347
|
+
"The chart could not be rendered due to an error.",
|
|
348
|
+
"The error has been logged to the console."
|
|
349
|
+
];
|
|
350
|
+
return /* @__PURE__ */ jsx5(
|
|
351
|
+
ChartError,
|
|
352
|
+
{
|
|
353
|
+
message: errorMessage,
|
|
354
|
+
details: errorDetails.join("\n")
|
|
355
|
+
}
|
|
356
|
+
);
|
|
357
|
+
}
|
|
358
|
+
return this.props.children;
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
// src/markdown-extensions/charts/ChartBlock.tsx
|
|
363
|
+
import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
364
|
+
var ChartBlock = ({
|
|
365
|
+
data,
|
|
366
|
+
className = "",
|
|
367
|
+
config
|
|
368
|
+
}) => {
|
|
369
|
+
const [error, setError] = useState(null);
|
|
370
|
+
const [chartData, setChartData] = useState(
|
|
371
|
+
null
|
|
372
|
+
);
|
|
373
|
+
const [containerWidth, setContainerWidth] = useState(300);
|
|
374
|
+
const resizeObserverRef = useRef(null);
|
|
375
|
+
const customRenderTooltip = useCallback(
|
|
376
|
+
(params) => {
|
|
377
|
+
const { tooltipData } = params;
|
|
378
|
+
const nearestDatum = tooltipData?.nearestDatum?.datum;
|
|
379
|
+
if (!nearestDatum) {
|
|
380
|
+
return null;
|
|
381
|
+
}
|
|
382
|
+
const formatValue = (value) => {
|
|
383
|
+
if (chartData?.currency) {
|
|
384
|
+
const { symbol, symbolPosition } = chartData.currency;
|
|
385
|
+
let formattedValue;
|
|
386
|
+
if (value >= 1e6) {
|
|
387
|
+
formattedValue = `${(value / 1e6).toFixed(
|
|
388
|
+
1
|
|
389
|
+
)}M`;
|
|
390
|
+
} else if (value >= 1e3) {
|
|
391
|
+
formattedValue = `${(value / 1e3).toFixed(1)}K`;
|
|
392
|
+
} else {
|
|
393
|
+
formattedValue = value.toLocaleString();
|
|
394
|
+
}
|
|
395
|
+
return symbolPosition === "right" ? `${formattedValue}${symbol}` : `${symbol}${formattedValue}`;
|
|
396
|
+
}
|
|
397
|
+
if (value >= 1e6) {
|
|
398
|
+
return `${(value / 1e6).toFixed(1)}M`;
|
|
399
|
+
} else if (value >= 1e3) {
|
|
400
|
+
return `${(value / 1e3).toFixed(1)}K`;
|
|
401
|
+
}
|
|
402
|
+
return value.toLocaleString();
|
|
403
|
+
};
|
|
404
|
+
const formatDate = (date) => {
|
|
405
|
+
const now = /* @__PURE__ */ new Date();
|
|
406
|
+
const diffInDays = Math.floor(
|
|
407
|
+
(now.getTime() - date.getTime()) / (1e3 * 60 * 60 * 24)
|
|
408
|
+
);
|
|
409
|
+
if (diffInDays === 0) {
|
|
410
|
+
return __("Today", "a8c-agenttic");
|
|
411
|
+
} else if (diffInDays === 1) {
|
|
412
|
+
return __("Yesterday", "a8c-agenttic");
|
|
413
|
+
} else if (diffInDays < 7) {
|
|
414
|
+
return sprintf(
|
|
415
|
+
/* translators: %d: number of days */
|
|
416
|
+
__("%d days ago", "a8c-agenttic"),
|
|
417
|
+
diffInDays
|
|
418
|
+
);
|
|
419
|
+
}
|
|
420
|
+
return date.toLocaleDateString("en-US", {
|
|
421
|
+
year: "numeric",
|
|
422
|
+
month: "short",
|
|
423
|
+
day: "numeric"
|
|
424
|
+
});
|
|
425
|
+
};
|
|
426
|
+
const productName = nearestDatum.label;
|
|
427
|
+
const tooltipPoints = Object.entries(
|
|
428
|
+
tooltipData?.datumByKey || {}
|
|
429
|
+
).map(([key, datumInfo]) => {
|
|
430
|
+
const datum = datumInfo.datum;
|
|
431
|
+
return {
|
|
432
|
+
key,
|
|
433
|
+
value: datum.value
|
|
434
|
+
};
|
|
435
|
+
}).sort((a, b) => b.value - a.value);
|
|
436
|
+
return /* @__PURE__ */ jsxs2("div", { children: [
|
|
437
|
+
productName && /* @__PURE__ */ jsx6(
|
|
438
|
+
"div",
|
|
439
|
+
{
|
|
440
|
+
style: {
|
|
441
|
+
fontSize: "12px",
|
|
442
|
+
fontWeight: "bold",
|
|
443
|
+
marginBottom: "4px",
|
|
444
|
+
color: "#1e1e1e",
|
|
445
|
+
borderBottom: "1px solid #eee",
|
|
446
|
+
paddingBottom: "2px"
|
|
447
|
+
},
|
|
448
|
+
children: productName
|
|
449
|
+
}
|
|
450
|
+
),
|
|
451
|
+
nearestDatum.date && /* @__PURE__ */ jsx6(
|
|
452
|
+
"div",
|
|
453
|
+
{
|
|
454
|
+
style: {
|
|
455
|
+
fontSize: "10px",
|
|
456
|
+
opacity: 0.8,
|
|
457
|
+
marginBottom: "4px"
|
|
458
|
+
},
|
|
459
|
+
children: formatDate(nearestDatum.date)
|
|
460
|
+
}
|
|
461
|
+
),
|
|
462
|
+
tooltipPoints.map((point) => /* @__PURE__ */ jsxs2(
|
|
463
|
+
"div",
|
|
464
|
+
{
|
|
465
|
+
style: { marginBottom: "2px" },
|
|
466
|
+
children: [
|
|
467
|
+
/* @__PURE__ */ jsxs2("strong", { children: [
|
|
468
|
+
point.key,
|
|
469
|
+
":"
|
|
470
|
+
] }),
|
|
471
|
+
" ",
|
|
472
|
+
formatValue(point.value)
|
|
473
|
+
]
|
|
474
|
+
},
|
|
475
|
+
point.key
|
|
476
|
+
))
|
|
477
|
+
] });
|
|
478
|
+
},
|
|
479
|
+
[chartData?.currency]
|
|
480
|
+
);
|
|
481
|
+
useEffect(() => {
|
|
482
|
+
setError(null);
|
|
483
|
+
setChartData(null);
|
|
484
|
+
if (!data || typeof data !== "string") {
|
|
485
|
+
setError({
|
|
486
|
+
message: __("Invalid chart data provided", "a8c-agenttic"),
|
|
487
|
+
details: `Input data: ${data}`
|
|
488
|
+
});
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
try {
|
|
492
|
+
const rawData = JSON.parse(data.trim());
|
|
493
|
+
if (!rawData.chartType) {
|
|
494
|
+
setError({
|
|
495
|
+
message: __(
|
|
496
|
+
"Chart data must include chartType",
|
|
497
|
+
"a8c-agenttic"
|
|
498
|
+
),
|
|
499
|
+
details: __("Available types: line, bar", "a8c-agenttic")
|
|
500
|
+
});
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
503
|
+
if (!rawData.data || !Array.isArray(rawData.data)) {
|
|
504
|
+
setError({
|
|
505
|
+
message: __(
|
|
506
|
+
"Chart data must include a data array",
|
|
507
|
+
"a8c-agenttic"
|
|
508
|
+
),
|
|
509
|
+
details: `Input data: ${data}`
|
|
510
|
+
});
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
if (rawData.data.length === 0) {
|
|
514
|
+
setError({
|
|
515
|
+
message: __(
|
|
516
|
+
"No data points found for chart",
|
|
517
|
+
"a8c-agenttic"
|
|
518
|
+
),
|
|
519
|
+
details: `Input data: ${data}`
|
|
520
|
+
});
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
const processedDataSeries = rawData.data.map((series) => ({
|
|
524
|
+
...series,
|
|
525
|
+
data: series.data.map((point) => {
|
|
526
|
+
if (point.date) {
|
|
527
|
+
const parsedDate = new Date(point.date);
|
|
528
|
+
if (isNaN(parsedDate.getTime())) {
|
|
529
|
+
console.warn(
|
|
530
|
+
`Invalid date string: "${point.date}" in series "${series.label}"`
|
|
531
|
+
);
|
|
532
|
+
return {
|
|
533
|
+
label: point.label,
|
|
534
|
+
value: point.value,
|
|
535
|
+
date: void 0
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
return {
|
|
539
|
+
label: point.label,
|
|
540
|
+
value: point.value,
|
|
541
|
+
date: parsedDate
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
return {
|
|
545
|
+
label: point.label,
|
|
546
|
+
value: point.value,
|
|
547
|
+
date: void 0
|
|
548
|
+
};
|
|
549
|
+
})
|
|
550
|
+
}));
|
|
551
|
+
const processedData = {
|
|
552
|
+
chartType: rawData.chartType,
|
|
553
|
+
title: rawData.title,
|
|
554
|
+
data: processedDataSeries,
|
|
555
|
+
currency: rawData.currency,
|
|
556
|
+
mode: rawData.mode || "time-comparison"
|
|
557
|
+
};
|
|
558
|
+
setChartData(processedData);
|
|
559
|
+
} catch (parseError) {
|
|
560
|
+
setError({
|
|
561
|
+
message: __(
|
|
562
|
+
"Failed to parse chart data as JSON",
|
|
563
|
+
"a8c-agenttic"
|
|
564
|
+
),
|
|
565
|
+
details: `Input data: ${data}`
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
}, [data]);
|
|
569
|
+
const setContainerRef = useCallback((node) => {
|
|
570
|
+
if (resizeObserverRef.current) {
|
|
571
|
+
resizeObserverRef.current.disconnect();
|
|
572
|
+
}
|
|
573
|
+
if (node) {
|
|
574
|
+
const { width } = node.getBoundingClientRect();
|
|
575
|
+
const contentWidth = Math.max(280, width - 4);
|
|
576
|
+
setContainerWidth(contentWidth);
|
|
577
|
+
resizeObserverRef.current = new ResizeObserver((entries) => {
|
|
578
|
+
for (const entry of entries) {
|
|
579
|
+
const resizedWidth = entry.contentRect.width;
|
|
580
|
+
const resizedContentWidth = Math.max(
|
|
581
|
+
280,
|
|
582
|
+
resizedWidth - 4
|
|
583
|
+
);
|
|
584
|
+
setContainerWidth(resizedContentWidth);
|
|
585
|
+
}
|
|
586
|
+
});
|
|
587
|
+
resizeObserverRef.current.observe(node);
|
|
588
|
+
}
|
|
589
|
+
}, []);
|
|
590
|
+
useEffect(() => {
|
|
591
|
+
return () => {
|
|
592
|
+
if (resizeObserverRef.current) {
|
|
593
|
+
resizeObserverRef.current.disconnect();
|
|
594
|
+
resizeObserverRef.current = null;
|
|
595
|
+
}
|
|
596
|
+
};
|
|
597
|
+
}, []);
|
|
598
|
+
if (error) {
|
|
599
|
+
return /* @__PURE__ */ jsx6(ChartError, { message: error.message, details: error.details });
|
|
600
|
+
}
|
|
601
|
+
if (!chartData) {
|
|
602
|
+
return /* @__PURE__ */ jsx6(
|
|
603
|
+
ChartError,
|
|
604
|
+
{
|
|
605
|
+
message: __("No chart data available", "a8c-agenttic")
|
|
606
|
+
}
|
|
607
|
+
);
|
|
608
|
+
}
|
|
609
|
+
const hasMultipleSeries = chartData.data.length > 1;
|
|
610
|
+
const shouldShowLegend = hasMultipleSeries;
|
|
611
|
+
const chartWidth = containerWidth;
|
|
612
|
+
const commonProps = {
|
|
613
|
+
data: chartData.data,
|
|
614
|
+
currency: chartData.currency,
|
|
615
|
+
showLegend: shouldShowLegend,
|
|
616
|
+
withTooltips: true,
|
|
617
|
+
renderTooltip: customRenderTooltip,
|
|
618
|
+
error: null,
|
|
619
|
+
maxWidth: chartWidth,
|
|
620
|
+
aspectRatio: 1.2,
|
|
621
|
+
resizeDebounceTime: 300
|
|
622
|
+
};
|
|
623
|
+
const renderChart = () => {
|
|
624
|
+
switch (chartData.chartType) {
|
|
625
|
+
case "line":
|
|
626
|
+
return /* @__PURE__ */ jsx6(LineChart, { ...commonProps });
|
|
627
|
+
case "bar":
|
|
628
|
+
return /* @__PURE__ */ jsx6(
|
|
629
|
+
BarChart,
|
|
630
|
+
{
|
|
631
|
+
...commonProps,
|
|
632
|
+
mode: chartData.mode
|
|
633
|
+
}
|
|
634
|
+
);
|
|
635
|
+
default:
|
|
636
|
+
return /* @__PURE__ */ jsx6(
|
|
637
|
+
ChartError,
|
|
638
|
+
{
|
|
639
|
+
message: sprintf(
|
|
640
|
+
/* translators: %s: chart type name */
|
|
641
|
+
__("Unsupported chart type: %s", "a8c-agenttic"),
|
|
642
|
+
chartData.chartType
|
|
643
|
+
)
|
|
644
|
+
}
|
|
645
|
+
);
|
|
646
|
+
}
|
|
647
|
+
};
|
|
648
|
+
return /* @__PURE__ */ jsx6(ChartErrorBoundary, { chartData: data, children: /* @__PURE__ */ jsxs2(
|
|
649
|
+
"div",
|
|
650
|
+
{
|
|
651
|
+
ref: setContainerRef,
|
|
652
|
+
className: `chart-block ${className}`,
|
|
653
|
+
children: [
|
|
654
|
+
chartData.title && /* @__PURE__ */ jsx6("h3", { className: "chart-block-title", children: chartData.title }),
|
|
655
|
+
/* @__PURE__ */ jsx6("div", { className: "chart-container", children: renderChart() })
|
|
656
|
+
]
|
|
657
|
+
}
|
|
658
|
+
) });
|
|
659
|
+
};
|
|
660
|
+
|
|
661
|
+
// src/markdown-extensions/charts/index.ts
|
|
662
|
+
import React2 from "react";
|
|
663
|
+
function createChartBlock(config) {
|
|
664
|
+
return function ChartCodeBlock(props) {
|
|
665
|
+
const { children, className, ...rest } = props;
|
|
666
|
+
const isChartBlock = className?.includes("language-chart");
|
|
667
|
+
if (!isChartBlock) {
|
|
668
|
+
return React2.createElement(
|
|
669
|
+
"code",
|
|
670
|
+
{ className, ...rest },
|
|
671
|
+
children
|
|
672
|
+
);
|
|
673
|
+
}
|
|
674
|
+
const chartData = typeof children === "string" ? children : "";
|
|
675
|
+
return React2.createElement(ChartBlock, {
|
|
676
|
+
data: chartData,
|
|
677
|
+
className: "markdown-chart",
|
|
678
|
+
config
|
|
679
|
+
});
|
|
680
|
+
};
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
export {
|
|
684
|
+
BarChart,
|
|
685
|
+
LineChart,
|
|
686
|
+
ChartBlock,
|
|
687
|
+
createChartBlock
|
|
688
|
+
};
|