@shapesos/clay 0.11.0 → 0.12.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 +60 -0
- package/dist/artifacts.cjs +858 -132
- package/dist/artifacts.cjs.map +1 -1
- package/dist/artifacts.d.cts +38 -5
- package/dist/artifacts.d.ts +38 -5
- package/dist/artifacts.js +13 -3
- package/dist/blocks.cjs +1185 -467
- package/dist/blocks.cjs.map +1 -1
- package/dist/blocks.css +1 -1
- package/dist/blocks.d.cts +23 -10
- package/dist/blocks.d.ts +23 -10
- package/dist/blocks.js +6 -3
- package/dist/chart.cjs +594 -0
- package/dist/chart.cjs.map +1 -0
- package/dist/chart.d.cts +439 -0
- package/dist/chart.d.ts +439 -0
- package/dist/chart.js +32 -0
- package/dist/chat.cjs +1207 -489
- package/dist/chat.cjs.map +1 -1
- package/dist/chat.d.cts +3 -2
- package/dist/chat.d.ts +3 -2
- package/dist/chat.js +7 -4
- package/dist/{chunk-MXOPG747.js → chunk-36CB624W.js} +7 -7
- package/dist/chunk-36CB624W.js.map +1 -0
- package/dist/{chunk-L35M3OD5.js → chunk-4MZZH3WX.js} +5 -11
- package/dist/chunk-4MZZH3WX.js.map +1 -0
- package/dist/chunk-AQEJRMRN.js +1 -0
- package/dist/chunk-AQEJRMRN.js.map +1 -0
- package/dist/{chunk-OUW6PUEB.js → chunk-FFX3CAOX.js} +7 -7
- package/dist/chunk-P6GUNIAE.js +11 -0
- package/dist/chunk-P6GUNIAE.js.map +1 -0
- package/dist/chunk-QXGYMDIA.js +477 -0
- package/dist/chunk-QXGYMDIA.js.map +1 -0
- package/dist/{chunk-BX5TCEPR.js → chunk-Z5JWF24N.js} +388 -105
- package/dist/chunk-Z5JWF24N.js.map +1 -0
- package/dist/index.cjs +924 -198
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +23 -15
- package/dist/table.js +2 -1
- package/dist/types-B2aYk82c.d.cts +29 -0
- package/dist/types-B2aYk82c.d.ts +29 -0
- package/dist/types-C0BvwliI.d.cts +332 -0
- package/dist/types-C5bFH4v3.d.ts +332 -0
- package/dist/{types-DuuRI4ll.d.cts → types-DCutaXjZ.d.cts} +16 -1
- package/dist/{types-C9XX-Uhk.d.ts → types-uPfn67Dc.d.ts} +16 -1
- package/package.json +13 -1
- package/dist/chunk-BX5TCEPR.js.map +0 -1
- package/dist/chunk-L35M3OD5.js.map +0 -1
- package/dist/chunk-MEJESPTZ.js +0 -1
- package/dist/chunk-MXOPG747.js.map +0 -1
- package/dist/types-3Gzk7cRt.d.cts +0 -121
- package/dist/types-3Gzk7cRt.d.ts +0 -121
- /package/dist/{chunk-MEJESPTZ.js.map → chart.js.map} +0 -0
- /package/dist/{chunk-OUW6PUEB.js.map → chunk-FFX3CAOX.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -16353,8 +16353,11 @@ __export(src_exports, {
|
|
|
16353
16353
|
BlockContext: () => BlockContext,
|
|
16354
16354
|
BlockServices: () => BlockServices,
|
|
16355
16355
|
Button: () => Button2,
|
|
16356
|
+
ChartArtifact: () => ChartArtifact,
|
|
16356
16357
|
ChatContext: () => ChatContext,
|
|
16357
16358
|
ChatMessage: () => ChatMessage,
|
|
16359
|
+
DEFAULT_CHART_ARTIFACT_LABELS: () => DEFAULT_CHART_ARTIFACT_LABELS,
|
|
16360
|
+
DEFAULT_TABLE_ARTIFACT_LABELS: () => DEFAULT_TABLE_ARTIFACT_LABELS,
|
|
16358
16361
|
ICON_POSITION: () => ICON_POSITION,
|
|
16359
16362
|
Icon: () => Icon,
|
|
16360
16363
|
IconButton: () => IconButton,
|
|
@@ -16776,13 +16779,33 @@ var blockTypes = {
|
|
|
16776
16779
|
ARTIFACT_REF: "ARTIFACT_REF"
|
|
16777
16780
|
};
|
|
16778
16781
|
|
|
16779
|
-
// src/components/artifacts/
|
|
16782
|
+
// src/components/artifacts/artifact-base.ts
|
|
16780
16783
|
var artifactTypes = {
|
|
16781
|
-
TABLE: "TABLE"
|
|
16784
|
+
TABLE: "TABLE",
|
|
16785
|
+
CHART: "CHART"
|
|
16782
16786
|
};
|
|
16783
16787
|
|
|
16784
|
-
// src/components/artifacts/
|
|
16785
|
-
var
|
|
16788
|
+
// src/components/artifacts/chart-artifact/types.ts
|
|
16789
|
+
var DEFAULT_CHART_ARTIFACT_LABELS = {
|
|
16790
|
+
download: "Download CSV",
|
|
16791
|
+
unavailable: "Chart data is unavailable.",
|
|
16792
|
+
loadError: "Couldn't load chart data.",
|
|
16793
|
+
loading: "Loading chart\u2026",
|
|
16794
|
+
empty: "No data to chart.",
|
|
16795
|
+
othersCategoryLabels: ["Others", "Other"]
|
|
16796
|
+
};
|
|
16797
|
+
|
|
16798
|
+
// src/components/artifacts/table-artifact/types.ts
|
|
16799
|
+
var DEFAULT_TABLE_ARTIFACT_LABELS = {
|
|
16800
|
+
download: "Download CSV",
|
|
16801
|
+
unavailable: "Table data is unavailable.",
|
|
16802
|
+
loadError: "Couldn't load table data.",
|
|
16803
|
+
loading: "Loading table\u2026",
|
|
16804
|
+
empty: "No rows to display."
|
|
16805
|
+
};
|
|
16806
|
+
|
|
16807
|
+
// src/components/artifacts/chart-artifact/chart-artifact.tsx
|
|
16808
|
+
var import_react9 = require("react");
|
|
16786
16809
|
|
|
16787
16810
|
// src/lib/utils.ts
|
|
16788
16811
|
var import_clsx = require("clsx");
|
|
@@ -17032,7 +17055,12 @@ TooltipContent.displayName = TooltipPrimitive.Content.displayName;
|
|
|
17032
17055
|
|
|
17033
17056
|
// src/components/artifacts/artifact-download-button/artifact-download-button.tsx
|
|
17034
17057
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
17035
|
-
|
|
17058
|
+
var DEFAULT_LABEL = "Download CSV";
|
|
17059
|
+
function ArtifactDownloadButton({
|
|
17060
|
+
href,
|
|
17061
|
+
label = DEFAULT_LABEL,
|
|
17062
|
+
onClick
|
|
17063
|
+
}) {
|
|
17036
17064
|
if (!isSafeDownloadUrl(href)) return null;
|
|
17037
17065
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Tooltip, { children: [
|
|
17038
17066
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
@@ -17042,12 +17070,13 @@ function ArtifactDownloadButton({ href }) {
|
|
|
17042
17070
|
href,
|
|
17043
17071
|
download: true,
|
|
17044
17072
|
rel: "noopener noreferrer",
|
|
17073
|
+
onClick,
|
|
17045
17074
|
icon: IconDownload,
|
|
17046
17075
|
size: "small",
|
|
17047
|
-
"aria-label":
|
|
17076
|
+
"aria-label": label
|
|
17048
17077
|
}
|
|
17049
17078
|
) }),
|
|
17050
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TooltipContent, { children:
|
|
17079
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TooltipContent, { children: label })
|
|
17051
17080
|
] }) });
|
|
17052
17081
|
}
|
|
17053
17082
|
function isSafeDownloadUrl(url) {
|
|
@@ -17059,25 +17088,778 @@ function isSafeDownloadUrl(url) {
|
|
|
17059
17088
|
}
|
|
17060
17089
|
}
|
|
17061
17090
|
|
|
17091
|
+
// src/components/artifacts/status-message.tsx
|
|
17092
|
+
var import_react4 = require("react");
|
|
17093
|
+
function StatusMessage({ $tone, children }) {
|
|
17094
|
+
return (0, import_react4.createElement)(
|
|
17095
|
+
"div",
|
|
17096
|
+
{
|
|
17097
|
+
className: `py-6 px-2 text-center text-sm font-medium leading-5 ${$tone === "error" ? "text-red-600" : "text-brown-70"}`
|
|
17098
|
+
},
|
|
17099
|
+
children
|
|
17100
|
+
);
|
|
17101
|
+
}
|
|
17102
|
+
|
|
17103
|
+
// src/components/chart/bar-chart/bar-chart.tsx
|
|
17104
|
+
var import_react5 = require("react");
|
|
17105
|
+
var import_recharts2 = require("recharts");
|
|
17106
|
+
|
|
17107
|
+
// src/components/chart/chart-container.tsx
|
|
17108
|
+
var import_recharts = require("recharts");
|
|
17109
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
17110
|
+
function ChartContainer({
|
|
17111
|
+
children,
|
|
17112
|
+
height: height2 = 320,
|
|
17113
|
+
width: width2 = "100%",
|
|
17114
|
+
className,
|
|
17115
|
+
style
|
|
17116
|
+
}) {
|
|
17117
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: cn("text-xs text-foreground", className), style: { width: width2, height: height2, ...style }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_recharts.ResponsiveContainer, { width: "100%", height: "100%", children }) });
|
|
17118
|
+
}
|
|
17119
|
+
|
|
17120
|
+
// src/components/chart/chart-legend-content.tsx
|
|
17121
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
17122
|
+
function ChartLegendContent({ payload, className, iconType = "square" }) {
|
|
17123
|
+
if (!payload || payload.length === 0) return null;
|
|
17124
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
17125
|
+
"ul",
|
|
17126
|
+
{
|
|
17127
|
+
className: cn("flex flex-wrap items-center justify-center gap-x-4 gap-y-2 text-xs text-brown-80", className),
|
|
17128
|
+
children: payload.map((entry, i) => {
|
|
17129
|
+
const swatchColor = typeof entry.color === "string" ? entry.color : "transparent";
|
|
17130
|
+
const label = entry.value !== void 0 ? String(entry.value) : "";
|
|
17131
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("li", { className: "flex items-center gap-1.5", children: [
|
|
17132
|
+
iconType === "square" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "inline-block h-2.5 w-2.5 shrink-0 rounded-sm", style: { background: swatchColor } }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "inline-block h-[3px] w-4 shrink-0 rounded-full", style: { background: swatchColor } }),
|
|
17133
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: label })
|
|
17134
|
+
] }, `${label}-${i}`);
|
|
17135
|
+
})
|
|
17136
|
+
}
|
|
17137
|
+
);
|
|
17138
|
+
}
|
|
17139
|
+
|
|
17140
|
+
// src/components/chart/chart-tooltip-content.tsx
|
|
17141
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
17142
|
+
function ChartTooltipContent({
|
|
17143
|
+
active: active2,
|
|
17144
|
+
payload,
|
|
17145
|
+
label,
|
|
17146
|
+
className,
|
|
17147
|
+
showLabel = true,
|
|
17148
|
+
formatValue
|
|
17149
|
+
}) {
|
|
17150
|
+
if (!active2 || !payload || payload.length === 0) return null;
|
|
17151
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
17152
|
+
"div",
|
|
17153
|
+
{
|
|
17154
|
+
className: cn(
|
|
17155
|
+
"rounded-lg border border-brown-40 bg-brown-10 px-3 py-2 text-xs shadow-sm",
|
|
17156
|
+
"min-w-32 text-foreground",
|
|
17157
|
+
className
|
|
17158
|
+
),
|
|
17159
|
+
children: [
|
|
17160
|
+
showLabel && label !== void 0 && label !== null ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "mb-1.5 font-medium text-brown-90", children: String(label) }) : null,
|
|
17161
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("ul", { className: "space-y-1", children: payload.map((entry, i) => {
|
|
17162
|
+
const name2 = entry.name !== void 0 ? String(entry.name) : "";
|
|
17163
|
+
const rawValue = entry.value;
|
|
17164
|
+
const display = formatValue ? formatValue(rawValue, name2) : rawValue === void 0 ? "" : String(rawValue);
|
|
17165
|
+
const swatch = typeof entry.color === "string" ? entry.color : "transparent";
|
|
17166
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("li", { className: "flex items-center gap-2", children: [
|
|
17167
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "inline-block h-2.5 w-2.5 shrink-0 rounded-sm", style: { background: swatch } }),
|
|
17168
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-brown-70", children: name2 }),
|
|
17169
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "ml-auto font-semibold tabular-nums text-brown-90", children: display })
|
|
17170
|
+
] }, `${name2}-${i}`);
|
|
17171
|
+
}) })
|
|
17172
|
+
]
|
|
17173
|
+
}
|
|
17174
|
+
);
|
|
17175
|
+
}
|
|
17176
|
+
|
|
17177
|
+
// src/components/chart/chart-palette.ts
|
|
17178
|
+
var CHART_PALETTE = [
|
|
17179
|
+
colors["blue-600"],
|
|
17180
|
+
// #2563EB — primary
|
|
17181
|
+
colors["blue-400"],
|
|
17182
|
+
// #60A5FA — mid
|
|
17183
|
+
colors["blue-300"],
|
|
17184
|
+
// #93C5FD — light
|
|
17185
|
+
colors["blue-100"],
|
|
17186
|
+
// #DBEAFE — very light
|
|
17187
|
+
colors["indigo-400"],
|
|
17188
|
+
// #818CF8
|
|
17189
|
+
colors["indigo-500"],
|
|
17190
|
+
// #6366F1
|
|
17191
|
+
colors["indigo-600"],
|
|
17192
|
+
// #4F46E5
|
|
17193
|
+
colors["indigo-800"],
|
|
17194
|
+
// #3730A3
|
|
17195
|
+
colors["blue-800"]
|
|
17196
|
+
// #1E40AF — deepest
|
|
17197
|
+
];
|
|
17198
|
+
var OTHERS_SLICE_COLOR = colors["brown-60"];
|
|
17199
|
+
var DEFAULT_OTHERS_CATEGORY_LABELS = ["others", "other"];
|
|
17200
|
+
function isOthersCategory(value2, labels) {
|
|
17201
|
+
if (value2 === null || value2 === void 0) return false;
|
|
17202
|
+
if (labels.length === 0) return false;
|
|
17203
|
+
const normalized = String(value2).trim().toLowerCase();
|
|
17204
|
+
for (const label of labels) {
|
|
17205
|
+
if (normalized === label.toLowerCase()) return true;
|
|
17206
|
+
}
|
|
17207
|
+
return false;
|
|
17208
|
+
}
|
|
17209
|
+
function colorForSeriesIndex(index2, palette = CHART_PALETTE) {
|
|
17210
|
+
return palette[index2 % palette.length] ?? CHART_PALETTE[0];
|
|
17211
|
+
}
|
|
17212
|
+
|
|
17213
|
+
// src/components/chart/chart-styles.ts
|
|
17214
|
+
var GRID_STROKE = colors["brown-40"];
|
|
17215
|
+
var AXIS_STROKE = colors["brown-50"];
|
|
17216
|
+
var AXIS_TICK_STYLE = {
|
|
17217
|
+
fill: colors["brown-70"],
|
|
17218
|
+
fontSize: 12,
|
|
17219
|
+
fontWeight: 500
|
|
17220
|
+
};
|
|
17221
|
+
var CHART_VALUE_LABEL_STYLE = {
|
|
17222
|
+
fill: colors["brown-70"],
|
|
17223
|
+
fontSize: 12,
|
|
17224
|
+
fontWeight: 500
|
|
17225
|
+
};
|
|
17226
|
+
var BAR_TOOLTIP_CURSOR_FILL = colors["brown-alpha-12"];
|
|
17227
|
+
var LINE_ACTIVE_DOT_STROKE = colors["brown-10"];
|
|
17228
|
+
var CHART_MARGIN = { top: 8, right: 16, left: 0, bottom: 4 };
|
|
17229
|
+
var PIE_CHART_MARGIN = { top: 0, right: 24, left: 24, bottom: 4 };
|
|
17230
|
+
var CHART_AXIS_PROPS = {
|
|
17231
|
+
stroke: AXIS_STROKE,
|
|
17232
|
+
tick: AXIS_TICK_STYLE,
|
|
17233
|
+
tickLine: false,
|
|
17234
|
+
axisLine: false
|
|
17235
|
+
};
|
|
17236
|
+
var CHART_GRID_PROPS = {
|
|
17237
|
+
stroke: GRID_STROKE,
|
|
17238
|
+
strokeDasharray: "3 3",
|
|
17239
|
+
vertical: false
|
|
17240
|
+
};
|
|
17241
|
+
|
|
17242
|
+
// src/components/chart/chart-tick-utils.ts
|
|
17243
|
+
function maxTickCharsByCategoryCount(n) {
|
|
17244
|
+
if (n <= 5) return 24;
|
|
17245
|
+
if (n <= 8) return 14;
|
|
17246
|
+
if (n <= 12) return 10;
|
|
17247
|
+
if (n <= 16) return 7;
|
|
17248
|
+
return 5;
|
|
17249
|
+
}
|
|
17250
|
+
function truncateLabel(value2, maxChars) {
|
|
17251
|
+
const s = String(value2 ?? "");
|
|
17252
|
+
if (s.length <= maxChars) return s;
|
|
17253
|
+
return s.slice(0, Math.max(1, maxChars - 1)).trimEnd() + "\u2026";
|
|
17254
|
+
}
|
|
17255
|
+
function evenlyDistributedVisibleIndices(n, target) {
|
|
17256
|
+
if (n <= target) {
|
|
17257
|
+
return new Set(Array.from({ length: n }, (_, i) => i));
|
|
17258
|
+
}
|
|
17259
|
+
const set = /* @__PURE__ */ new Set();
|
|
17260
|
+
const step = (n - 1) / (target - 1);
|
|
17261
|
+
for (let i = 0; i < target; i++) {
|
|
17262
|
+
set.add(Math.round(i * step));
|
|
17263
|
+
}
|
|
17264
|
+
return set;
|
|
17265
|
+
}
|
|
17266
|
+
function defaultBarTickFormatter(categoryCount) {
|
|
17267
|
+
const max = maxTickCharsByCategoryCount(categoryCount);
|
|
17268
|
+
return (value2) => truncateLabel(value2, max);
|
|
17269
|
+
}
|
|
17270
|
+
function defaultLineChartTickFormatter(categoryCount, visibleIndices) {
|
|
17271
|
+
const max = maxTickCharsByCategoryCount(visibleIndices.size || categoryCount);
|
|
17272
|
+
return (value2, index2) => {
|
|
17273
|
+
if (!visibleIndices.has(index2)) return "";
|
|
17274
|
+
return truncateLabel(value2, max);
|
|
17275
|
+
};
|
|
17276
|
+
}
|
|
17277
|
+
|
|
17278
|
+
// src/components/chart/coerce-numeric.ts
|
|
17279
|
+
function coerceNumericColumns(rows, numericKeys) {
|
|
17280
|
+
return rows.map((row) => {
|
|
17281
|
+
const out = { ...row };
|
|
17282
|
+
for (const k of numericKeys) {
|
|
17283
|
+
const v = out[k];
|
|
17284
|
+
if (v == null) continue;
|
|
17285
|
+
const n = Number(v);
|
|
17286
|
+
out[k] = Number.isFinite(n) ? n : NaN;
|
|
17287
|
+
}
|
|
17288
|
+
return out;
|
|
17289
|
+
});
|
|
17290
|
+
}
|
|
17291
|
+
|
|
17292
|
+
// src/components/chart/bar-chart/bar-chart.tsx
|
|
17293
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
17294
|
+
function BarChart({
|
|
17295
|
+
data: data2,
|
|
17296
|
+
xKey,
|
|
17297
|
+
series,
|
|
17298
|
+
stacked = false,
|
|
17299
|
+
height: height2 = 320,
|
|
17300
|
+
width: width2 = "100%",
|
|
17301
|
+
className,
|
|
17302
|
+
palette = CHART_PALETTE,
|
|
17303
|
+
showTooltip = true,
|
|
17304
|
+
showLegend,
|
|
17305
|
+
showGrid = true,
|
|
17306
|
+
showXAxis = true,
|
|
17307
|
+
showYAxis = true,
|
|
17308
|
+
showValueLabels,
|
|
17309
|
+
xAxisInterval = 0,
|
|
17310
|
+
xAxisAngle,
|
|
17311
|
+
xAxisTickFormatter
|
|
17312
|
+
}) {
|
|
17313
|
+
const seriesKeys = (0, import_react5.useMemo)(() => series.map((s) => s.key), [series]);
|
|
17314
|
+
const coercedData = (0, import_react5.useMemo)(
|
|
17315
|
+
() => coerceNumericColumns(data2, seriesKeys),
|
|
17316
|
+
[data2, seriesKeys]
|
|
17317
|
+
);
|
|
17318
|
+
const resolvedShowLegend = showLegend ?? series.length > 1;
|
|
17319
|
+
const resolvedShowValueLabels = showValueLabels ?? (!stacked && series.length === 1);
|
|
17320
|
+
const resolvedAngle = xAxisAngle ?? (coercedData.length >= 8 ? -30 : 0);
|
|
17321
|
+
const resolvedTickFormatter = (0, import_react5.useMemo)(
|
|
17322
|
+
() => xAxisTickFormatter ?? defaultBarTickFormatter(coercedData.length),
|
|
17323
|
+
[xAxisTickFormatter, coercedData.length]
|
|
17324
|
+
);
|
|
17325
|
+
const angledLabelPad = resolvedAngle === 0 ? 0 : Math.min(Math.abs(resolvedAngle) * 0.7, 40);
|
|
17326
|
+
const chartMargin = { ...CHART_MARGIN, bottom: CHART_MARGIN.bottom + angledLabelPad };
|
|
17327
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ChartContainer, { height: height2, width: width2, className, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_recharts2.BarChart, { data: coercedData, margin: chartMargin, barCategoryGap: "22%", children: [
|
|
17328
|
+
showGrid ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_recharts2.CartesianGrid, { ...CHART_GRID_PROPS }) : null,
|
|
17329
|
+
showXAxis ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
17330
|
+
import_recharts2.XAxis,
|
|
17331
|
+
{
|
|
17332
|
+
dataKey: xKey,
|
|
17333
|
+
...CHART_AXIS_PROPS,
|
|
17334
|
+
interval: xAxisInterval,
|
|
17335
|
+
angle: resolvedAngle,
|
|
17336
|
+
textAnchor: resolvedAngle !== 0 ? "end" : "middle",
|
|
17337
|
+
tickMargin: resolvedAngle === 0 ? 8 : 12,
|
|
17338
|
+
height: resolvedAngle !== 0 ? 60 : void 0,
|
|
17339
|
+
tickFormatter: resolvedTickFormatter
|
|
17340
|
+
}
|
|
17341
|
+
) : null,
|
|
17342
|
+
showYAxis ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_recharts2.YAxis, { ...CHART_AXIS_PROPS, width: 40 }) : null,
|
|
17343
|
+
showTooltip ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_recharts2.Tooltip, { cursor: { fill: BAR_TOOLTIP_CURSOR_FILL }, content: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ChartTooltipContent, {}) }) : null,
|
|
17344
|
+
resolvedShowLegend ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
17345
|
+
import_recharts2.Legend,
|
|
17346
|
+
{
|
|
17347
|
+
verticalAlign: "top",
|
|
17348
|
+
align: "center",
|
|
17349
|
+
wrapperStyle: { top: 0 },
|
|
17350
|
+
itemSorter: null,
|
|
17351
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ChartLegendContent, { iconType: "square" })
|
|
17352
|
+
}
|
|
17353
|
+
) : null,
|
|
17354
|
+
series.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
17355
|
+
import_recharts2.Bar,
|
|
17356
|
+
{
|
|
17357
|
+
dataKey: s.key,
|
|
17358
|
+
name: s.label,
|
|
17359
|
+
fill: colorForSeriesIndex(i, palette),
|
|
17360
|
+
stackId: stacked ? "default" : s.key,
|
|
17361
|
+
radius: barRadius(stacked, i, series.length),
|
|
17362
|
+
children: resolvedShowValueLabels ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_recharts2.LabelList, { dataKey: s.key, position: "top", style: CHART_VALUE_LABEL_STYLE }) : null
|
|
17363
|
+
},
|
|
17364
|
+
s.key
|
|
17365
|
+
))
|
|
17366
|
+
] }) });
|
|
17367
|
+
}
|
|
17368
|
+
function barRadius(stacked, seriesIndex, seriesCount) {
|
|
17369
|
+
if (!stacked) return [6, 6, 0, 0];
|
|
17370
|
+
const isTopSegment = seriesIndex === seriesCount - 1;
|
|
17371
|
+
return isTopSegment ? [6, 6, 0, 0] : [0, 0, 0, 0];
|
|
17372
|
+
}
|
|
17373
|
+
|
|
17374
|
+
// src/components/artifacts/chart-artifact/chart-variant-services/constants.ts
|
|
17375
|
+
var VARIANT_CHART_HEIGHT = "100%";
|
|
17376
|
+
|
|
17377
|
+
// src/components/artifacts/chart-artifact/chart-variant-services/bar-chart-variant-component.tsx
|
|
17378
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
17379
|
+
function BarChartVariantComponent({ config, rows }) {
|
|
17380
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
17381
|
+
BarChart,
|
|
17382
|
+
{
|
|
17383
|
+
data: rows,
|
|
17384
|
+
xKey: config.xKey,
|
|
17385
|
+
series: config.series,
|
|
17386
|
+
stacked: config.stacked,
|
|
17387
|
+
height: VARIANT_CHART_HEIGHT
|
|
17388
|
+
}
|
|
17389
|
+
);
|
|
17390
|
+
}
|
|
17391
|
+
|
|
17392
|
+
// src/components/artifacts/chart-artifact/chart-variant-services/shared-column-keys.ts
|
|
17393
|
+
function seriesBasedColumnKeys(config) {
|
|
17394
|
+
return [config.xKey, ...config.series.map((s) => s.key)];
|
|
17395
|
+
}
|
|
17396
|
+
function pieColumnKeys(config) {
|
|
17397
|
+
return [config.categoryKey, config.valueKey];
|
|
17398
|
+
}
|
|
17399
|
+
|
|
17400
|
+
// src/components/artifacts/chart-artifact/chart-variant-services/shared-validators.ts
|
|
17401
|
+
function isValidChartSeries(series) {
|
|
17402
|
+
if (!series || typeof series !== "object") return false;
|
|
17403
|
+
const candidate = series;
|
|
17404
|
+
if (typeof candidate.key !== "string" || candidate.key.length === 0) return false;
|
|
17405
|
+
if (typeof candidate.label !== "string") return false;
|
|
17406
|
+
return true;
|
|
17407
|
+
}
|
|
17408
|
+
|
|
17409
|
+
// src/components/artifacts/chart-artifact/chart-variant-services/bar-chart-variant-service.tsx
|
|
17410
|
+
function isValidBarChartConfig(config) {
|
|
17411
|
+
if (!config || typeof config !== "object") return false;
|
|
17412
|
+
const candidate = config;
|
|
17413
|
+
if (candidate.variant !== "BAR") return false;
|
|
17414
|
+
if (typeof candidate.xKey !== "string" || candidate.xKey.length === 0) return false;
|
|
17415
|
+
if (!Array.isArray(candidate.series) || candidate.series.length === 0) return false;
|
|
17416
|
+
if (!candidate.series.every(isValidChartSeries)) return false;
|
|
17417
|
+
return true;
|
|
17418
|
+
}
|
|
17419
|
+
var BarChartVariantService = {
|
|
17420
|
+
variant: "BAR",
|
|
17421
|
+
isValidConfig: isValidBarChartConfig,
|
|
17422
|
+
columnKeys: seriesBasedColumnKeys,
|
|
17423
|
+
Component: BarChartVariantComponent
|
|
17424
|
+
};
|
|
17425
|
+
|
|
17426
|
+
// src/components/chart/line-chart/line-chart.tsx
|
|
17427
|
+
var import_react6 = require("react");
|
|
17428
|
+
var import_recharts3 = require("recharts");
|
|
17429
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
17430
|
+
var TARGET_VISIBLE_LABELS = 5;
|
|
17431
|
+
function LineChart({
|
|
17432
|
+
data: data2,
|
|
17433
|
+
xKey,
|
|
17434
|
+
series,
|
|
17435
|
+
smooth: smooth2 = true,
|
|
17436
|
+
showDots = true,
|
|
17437
|
+
strokeWidth = 2,
|
|
17438
|
+
height: height2 = 320,
|
|
17439
|
+
width: width2 = "100%",
|
|
17440
|
+
className,
|
|
17441
|
+
palette = CHART_PALETTE,
|
|
17442
|
+
showTooltip = true,
|
|
17443
|
+
showLegend,
|
|
17444
|
+
showGrid = true,
|
|
17445
|
+
showXAxis = true,
|
|
17446
|
+
showYAxis = true,
|
|
17447
|
+
showValueLabels = false,
|
|
17448
|
+
xAxisInterval = 0,
|
|
17449
|
+
xAxisAngle = 0,
|
|
17450
|
+
xAxisTickFormatter
|
|
17451
|
+
}) {
|
|
17452
|
+
const seriesKeys = (0, import_react6.useMemo)(() => series.map((s) => s.key), [series]);
|
|
17453
|
+
const coercedData = (0, import_react6.useMemo)(
|
|
17454
|
+
() => coerceNumericColumns(data2, seriesKeys),
|
|
17455
|
+
[data2, seriesKeys]
|
|
17456
|
+
);
|
|
17457
|
+
const lineType = smooth2 ? "monotone" : "linear";
|
|
17458
|
+
const resolvedShowLegend = showLegend ?? series.length > 1;
|
|
17459
|
+
const resolvedTickFormatter = (0, import_react6.useMemo)(() => {
|
|
17460
|
+
if (xAxisTickFormatter) return xAxisTickFormatter;
|
|
17461
|
+
const visible = evenlyDistributedVisibleIndices(coercedData.length, TARGET_VISIBLE_LABELS);
|
|
17462
|
+
return defaultLineChartTickFormatter(coercedData.length, visible);
|
|
17463
|
+
}, [xAxisTickFormatter, coercedData.length]);
|
|
17464
|
+
const angledLabelPad = xAxisAngle === 0 ? 0 : Math.min(Math.abs(xAxisAngle) * 0.7, 40);
|
|
17465
|
+
const chartMargin = { ...CHART_MARGIN, right: CHART_MARGIN.right + 16, bottom: CHART_MARGIN.bottom + angledLabelPad };
|
|
17466
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ChartContainer, { height: height2, width: width2, className, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_recharts3.LineChart, { data: coercedData, margin: chartMargin, children: [
|
|
17467
|
+
showGrid ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_recharts3.CartesianGrid, { ...CHART_GRID_PROPS }) : null,
|
|
17468
|
+
showXAxis ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
17469
|
+
import_recharts3.XAxis,
|
|
17470
|
+
{
|
|
17471
|
+
dataKey: xKey,
|
|
17472
|
+
...CHART_AXIS_PROPS,
|
|
17473
|
+
interval: xAxisInterval,
|
|
17474
|
+
angle: xAxisAngle,
|
|
17475
|
+
textAnchor: xAxisAngle !== 0 ? "end" : "middle",
|
|
17476
|
+
tickMargin: xAxisAngle === 0 ? 8 : 12,
|
|
17477
|
+
height: xAxisAngle !== 0 ? 60 : void 0,
|
|
17478
|
+
tickFormatter: resolvedTickFormatter
|
|
17479
|
+
}
|
|
17480
|
+
) : null,
|
|
17481
|
+
showYAxis ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_recharts3.YAxis, { ...CHART_AXIS_PROPS, width: 40 }) : null,
|
|
17482
|
+
showTooltip ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_recharts3.Tooltip, { content: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ChartTooltipContent, {}) }) : null,
|
|
17483
|
+
resolvedShowLegend ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
17484
|
+
import_recharts3.Legend,
|
|
17485
|
+
{
|
|
17486
|
+
verticalAlign: "top",
|
|
17487
|
+
align: "center",
|
|
17488
|
+
wrapperStyle: { top: 0 },
|
|
17489
|
+
itemSorter: null,
|
|
17490
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ChartLegendContent, { iconType: "line" })
|
|
17491
|
+
}
|
|
17492
|
+
) : null,
|
|
17493
|
+
series.map((s, i) => {
|
|
17494
|
+
const color = colorForSeriesIndex(i, palette);
|
|
17495
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
17496
|
+
import_recharts3.Line,
|
|
17497
|
+
{
|
|
17498
|
+
type: lineType,
|
|
17499
|
+
dataKey: s.key,
|
|
17500
|
+
name: s.label,
|
|
17501
|
+
stroke: color,
|
|
17502
|
+
strokeWidth,
|
|
17503
|
+
dot: showDots ? { r: 3, fill: color, stroke: color, strokeWidth: 0 } : false,
|
|
17504
|
+
activeDot: { r: 5, fill: color, stroke: LINE_ACTIVE_DOT_STROKE, strokeWidth: 2 },
|
|
17505
|
+
children: showValueLabels ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_recharts3.LabelList, { dataKey: s.key, position: "top", style: CHART_VALUE_LABEL_STYLE }) : null
|
|
17506
|
+
},
|
|
17507
|
+
s.key
|
|
17508
|
+
);
|
|
17509
|
+
})
|
|
17510
|
+
] }) });
|
|
17511
|
+
}
|
|
17512
|
+
|
|
17513
|
+
// src/components/artifacts/chart-artifact/chart-variant-services/line-chart-variant-component.tsx
|
|
17514
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
17515
|
+
function LineChartVariantComponent({ config, rows }) {
|
|
17516
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(LineChart, { data: rows, xKey: config.xKey, series: config.series, height: VARIANT_CHART_HEIGHT });
|
|
17517
|
+
}
|
|
17518
|
+
|
|
17519
|
+
// src/components/artifacts/chart-artifact/chart-variant-services/line-chart-variant-service.tsx
|
|
17520
|
+
function isValidLineChartConfig(config) {
|
|
17521
|
+
if (!config || typeof config !== "object") return false;
|
|
17522
|
+
const candidate = config;
|
|
17523
|
+
if (candidate.variant !== "LINE") return false;
|
|
17524
|
+
if (typeof candidate.xKey !== "string" || candidate.xKey.length === 0) return false;
|
|
17525
|
+
if (!Array.isArray(candidate.series) || candidate.series.length === 0) return false;
|
|
17526
|
+
if (!candidate.series.every(isValidChartSeries)) return false;
|
|
17527
|
+
return true;
|
|
17528
|
+
}
|
|
17529
|
+
var LineChartVariantService = {
|
|
17530
|
+
variant: "LINE",
|
|
17531
|
+
isValidConfig: isValidLineChartConfig,
|
|
17532
|
+
columnKeys: seriesBasedColumnKeys,
|
|
17533
|
+
Component: LineChartVariantComponent
|
|
17534
|
+
};
|
|
17535
|
+
|
|
17536
|
+
// src/components/chart/pie-chart/pie-chart.tsx
|
|
17537
|
+
var import_react7 = require("react");
|
|
17538
|
+
var import_recharts4 = require("recharts");
|
|
17539
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
17540
|
+
function PieChart({
|
|
17541
|
+
data: data2,
|
|
17542
|
+
categoryKey,
|
|
17543
|
+
valueKey,
|
|
17544
|
+
height: height2 = 320,
|
|
17545
|
+
width: width2 = "100%",
|
|
17546
|
+
className,
|
|
17547
|
+
palette = CHART_PALETTE,
|
|
17548
|
+
showLabels = true,
|
|
17549
|
+
showTooltip = true,
|
|
17550
|
+
showLegend = true,
|
|
17551
|
+
innerRadius = 0,
|
|
17552
|
+
outerRadius = "68%",
|
|
17553
|
+
othersCategoryLabels = DEFAULT_OTHERS_CATEGORY_LABELS
|
|
17554
|
+
}) {
|
|
17555
|
+
const { orderedData, sliceColors } = (0, import_react7.useMemo)(() => {
|
|
17556
|
+
const coerced = coerceNumericColumns(data2, [valueKey]);
|
|
17557
|
+
const namedRows = [];
|
|
17558
|
+
const namedColors = [];
|
|
17559
|
+
const othersRows = [];
|
|
17560
|
+
const othersColors = [];
|
|
17561
|
+
for (const row of coerced) {
|
|
17562
|
+
if (isOthersCategory(row[categoryKey], othersCategoryLabels)) {
|
|
17563
|
+
othersRows.push(row);
|
|
17564
|
+
othersColors.push(OTHERS_SLICE_COLOR);
|
|
17565
|
+
} else {
|
|
17566
|
+
namedRows.push(row);
|
|
17567
|
+
namedColors.push(colorForSeriesIndex(namedRows.length - 1, palette));
|
|
17568
|
+
}
|
|
17569
|
+
}
|
|
17570
|
+
return {
|
|
17571
|
+
orderedData: [...namedRows, ...othersRows],
|
|
17572
|
+
sliceColors: [...namedColors, ...othersColors]
|
|
17573
|
+
};
|
|
17574
|
+
}, [data2, valueKey, categoryKey, othersCategoryLabels, palette]);
|
|
17575
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ChartContainer, { height: height2, width: width2, className, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_recharts4.PieChart, { margin: PIE_CHART_MARGIN, children: [
|
|
17576
|
+
showTooltip ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_recharts4.Tooltip, { content: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ChartTooltipContent, {}) }) : null,
|
|
17577
|
+
showLegend ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
17578
|
+
import_recharts4.Legend,
|
|
17579
|
+
{
|
|
17580
|
+
verticalAlign: "top",
|
|
17581
|
+
align: "center",
|
|
17582
|
+
wrapperStyle: { top: 0 },
|
|
17583
|
+
itemSorter: null,
|
|
17584
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ChartLegendContent, { iconType: "square" })
|
|
17585
|
+
}
|
|
17586
|
+
) : null,
|
|
17587
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
17588
|
+
import_recharts4.Pie,
|
|
17589
|
+
{
|
|
17590
|
+
data: orderedData,
|
|
17591
|
+
dataKey: valueKey,
|
|
17592
|
+
nameKey: categoryKey,
|
|
17593
|
+
cx: "50%",
|
|
17594
|
+
cy: "52%",
|
|
17595
|
+
startAngle: 90,
|
|
17596
|
+
endAngle: -270,
|
|
17597
|
+
innerRadius,
|
|
17598
|
+
outerRadius,
|
|
17599
|
+
label: showLabels ? (entry) => {
|
|
17600
|
+
const v = entry.value;
|
|
17601
|
+
if (v === void 0 || v === null) return null;
|
|
17602
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
17603
|
+
"text",
|
|
17604
|
+
{
|
|
17605
|
+
x: entry.x,
|
|
17606
|
+
y: entry.y,
|
|
17607
|
+
fill: CHART_VALUE_LABEL_STYLE.fill,
|
|
17608
|
+
fontSize: CHART_VALUE_LABEL_STYLE.fontSize,
|
|
17609
|
+
fontWeight: CHART_VALUE_LABEL_STYLE.fontWeight,
|
|
17610
|
+
textAnchor: entry.textAnchor,
|
|
17611
|
+
dominantBaseline: "central",
|
|
17612
|
+
children: String(v)
|
|
17613
|
+
}
|
|
17614
|
+
);
|
|
17615
|
+
} : false,
|
|
17616
|
+
labelLine: false,
|
|
17617
|
+
stroke: "none",
|
|
17618
|
+
strokeWidth: 0,
|
|
17619
|
+
children: orderedData.map((_row, i) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_recharts4.Cell, { fill: sliceColors[i] }, i))
|
|
17620
|
+
}
|
|
17621
|
+
)
|
|
17622
|
+
] }) });
|
|
17623
|
+
}
|
|
17624
|
+
|
|
17625
|
+
// src/components/artifacts/chart-artifact/chart-variant-services/pie-chart-variant-component.tsx
|
|
17626
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
17627
|
+
function PieChartVariantComponent({
|
|
17628
|
+
config,
|
|
17629
|
+
rows,
|
|
17630
|
+
labels
|
|
17631
|
+
}) {
|
|
17632
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
17633
|
+
PieChart,
|
|
17634
|
+
{
|
|
17635
|
+
data: rows,
|
|
17636
|
+
categoryKey: config.categoryKey,
|
|
17637
|
+
valueKey: config.valueKey,
|
|
17638
|
+
othersCategoryLabels: labels.othersCategoryLabels,
|
|
17639
|
+
height: VARIANT_CHART_HEIGHT
|
|
17640
|
+
}
|
|
17641
|
+
);
|
|
17642
|
+
}
|
|
17643
|
+
|
|
17644
|
+
// src/components/artifacts/chart-artifact/chart-variant-services/pie-chart-variant-service.tsx
|
|
17645
|
+
function isValidPieChartConfig(config) {
|
|
17646
|
+
if (!config || typeof config !== "object") return false;
|
|
17647
|
+
const candidate = config;
|
|
17648
|
+
if (candidate.variant !== "PIE") return false;
|
|
17649
|
+
if (typeof candidate.categoryKey !== "string" || candidate.categoryKey.length === 0) return false;
|
|
17650
|
+
if (typeof candidate.valueKey !== "string" || candidate.valueKey.length === 0) return false;
|
|
17651
|
+
if (!Array.isArray(candidate.series)) return false;
|
|
17652
|
+
return true;
|
|
17653
|
+
}
|
|
17654
|
+
var PieChartVariantService = {
|
|
17655
|
+
variant: "PIE",
|
|
17656
|
+
isValidConfig: isValidPieChartConfig,
|
|
17657
|
+
columnKeys: pieColumnKeys,
|
|
17658
|
+
Component: PieChartVariantComponent
|
|
17659
|
+
};
|
|
17660
|
+
|
|
17661
|
+
// src/components/artifacts/chart-artifact/chart-variant-services/index.ts
|
|
17662
|
+
var ChartVariantServices = {
|
|
17663
|
+
LINE: LineChartVariantService,
|
|
17664
|
+
BAR: BarChartVariantService,
|
|
17665
|
+
PIE: PieChartVariantService
|
|
17666
|
+
};
|
|
17667
|
+
|
|
17668
|
+
// src/components/artifacts/chart-artifact/chart-artifact-content.tsx
|
|
17669
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
17670
|
+
function ChartArtifactContent({ config, rows, labels }) {
|
|
17671
|
+
const service = ChartVariantServices[config.variant];
|
|
17672
|
+
if (!service) {
|
|
17673
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(StatusMessage, { $tone: "info", children: labels.unavailable });
|
|
17674
|
+
}
|
|
17675
|
+
const Component = service.Component;
|
|
17676
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Component, { config, rows, labels });
|
|
17677
|
+
}
|
|
17678
|
+
|
|
17679
|
+
// src/components/artifacts/parse-csv.ts
|
|
17680
|
+
var import_papaparse = __toESM(require("papaparse"), 1);
|
|
17681
|
+
function parseCsv(text2, columns) {
|
|
17682
|
+
const result = import_papaparse.default.parse(text2, {
|
|
17683
|
+
header: true,
|
|
17684
|
+
skipEmptyLines: true,
|
|
17685
|
+
dynamicTyping: false
|
|
17686
|
+
});
|
|
17687
|
+
const csvHeaders = new Set(result.meta?.fields ?? []);
|
|
17688
|
+
const presentColumns = columns.filter((col) => csvHeaders.has(col.key));
|
|
17689
|
+
if (presentColumns.length === 0) return [];
|
|
17690
|
+
return result.data.map((rawRow) => {
|
|
17691
|
+
const row = {};
|
|
17692
|
+
for (const column of presentColumns) {
|
|
17693
|
+
const value2 = rawRow[column.key];
|
|
17694
|
+
row[column.key] = value2 === void 0 || value2 === "" ? null : value2;
|
|
17695
|
+
}
|
|
17696
|
+
return row;
|
|
17697
|
+
});
|
|
17698
|
+
}
|
|
17699
|
+
|
|
17700
|
+
// src/components/artifacts/use-rows-artifact-data.ts
|
|
17701
|
+
var import_react8 = require("react");
|
|
17702
|
+
var LOADING = { status: "loading", rows: null, error: null };
|
|
17703
|
+
var UNAVAILABLE = { status: "unavailable", rows: null, error: null };
|
|
17704
|
+
var INITIAL_INTERNAL = { cacheKey: null, data: LOADING };
|
|
17705
|
+
function columnsFingerprint(columns) {
|
|
17706
|
+
return columns.map((c) => c.key).join("|");
|
|
17707
|
+
}
|
|
17708
|
+
function scrubUrl(url) {
|
|
17709
|
+
const q = url.indexOf("?");
|
|
17710
|
+
return q === -1 ? url : `${url.slice(0, q)}?<redacted>`;
|
|
17711
|
+
}
|
|
17712
|
+
function useRowsArtifactData(presignedUrl, columns, parse) {
|
|
17713
|
+
const colsKey = (0, import_react8.useMemo)(() => columnsFingerprint(columns), [columns]);
|
|
17714
|
+
const safeUrl = presignedUrl && isSafeDownloadUrl(presignedUrl) ? presignedUrl : null;
|
|
17715
|
+
const cacheKey = safeUrl ? `${safeUrl}::${colsKey}` : null;
|
|
17716
|
+
const [state, setState] = (0, import_react8.useState)(INITIAL_INTERNAL);
|
|
17717
|
+
(0, import_react8.useEffect)(() => {
|
|
17718
|
+
if (!safeUrl) return;
|
|
17719
|
+
const controller = new AbortController();
|
|
17720
|
+
fetch(safeUrl, {
|
|
17721
|
+
signal: controller.signal,
|
|
17722
|
+
headers: { Accept: "text/csv" },
|
|
17723
|
+
// Presigned URLs are cross-origin S3 in production and don't need credentials. Explicit
|
|
17724
|
+
// omit so a same-origin URL (compromised payload, local dev) can't accidentally receive
|
|
17725
|
+
// session cookies or auth headers.
|
|
17726
|
+
credentials: "omit"
|
|
17727
|
+
}).then(async (response) => {
|
|
17728
|
+
if (!response.ok) throw new Error(`Failed to load artifact data (${response.status})`);
|
|
17729
|
+
return response.text();
|
|
17730
|
+
}).then((text2) => {
|
|
17731
|
+
if (controller.signal.aborted) return;
|
|
17732
|
+
try {
|
|
17733
|
+
const rows = parse(text2, columns);
|
|
17734
|
+
setState({ cacheKey: `${safeUrl}::${colsKey}`, data: { status: "ready", rows, error: null } });
|
|
17735
|
+
} catch (parseError) {
|
|
17736
|
+
const err = parseError instanceof Error ? parseError : new Error(String(parseError));
|
|
17737
|
+
console.error("[ArtifactData] CSV parse failed:", err.message);
|
|
17738
|
+
setState({ cacheKey: `${safeUrl}::${colsKey}`, data: { status: "error", rows: null, error: err } });
|
|
17739
|
+
}
|
|
17740
|
+
}).catch((error) => {
|
|
17741
|
+
if (controller.signal.aborted) return;
|
|
17742
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
17743
|
+
console.error(`[ArtifactData] Fetch failed [${scrubUrl(safeUrl)}]:`, err.message);
|
|
17744
|
+
setState({ cacheKey: `${safeUrl}::${colsKey}`, data: { status: "error", rows: null, error: err } });
|
|
17745
|
+
});
|
|
17746
|
+
return () => {
|
|
17747
|
+
controller.abort();
|
|
17748
|
+
};
|
|
17749
|
+
}, [safeUrl, colsKey]);
|
|
17750
|
+
if (!safeUrl) return UNAVAILABLE;
|
|
17751
|
+
if (state.cacheKey !== cacheKey) return LOADING;
|
|
17752
|
+
return state.data;
|
|
17753
|
+
}
|
|
17754
|
+
|
|
17755
|
+
// src/components/artifacts/chart-artifact/use-chart-artifact-data.ts
|
|
17756
|
+
function useChartArtifactData(presignedUrl, config) {
|
|
17757
|
+
const service = ChartVariantServices[config.variant];
|
|
17758
|
+
const keys = service ? service.columnKeys(config) : [];
|
|
17759
|
+
const columns = keys.map((key2) => ({ key: key2 }));
|
|
17760
|
+
return useRowsArtifactData(presignedUrl, columns, parseCsv);
|
|
17761
|
+
}
|
|
17762
|
+
|
|
17763
|
+
// src/components/artifacts/chart-artifact/validate.ts
|
|
17764
|
+
function isValidChartConfig(config) {
|
|
17765
|
+
if (!config || typeof config !== "object") return false;
|
|
17766
|
+
const variant = config.variant;
|
|
17767
|
+
if (typeof variant !== "string") return false;
|
|
17768
|
+
const service = ChartVariantServices[variant];
|
|
17769
|
+
if (!service) return false;
|
|
17770
|
+
return service.isValidConfig(config);
|
|
17771
|
+
}
|
|
17772
|
+
|
|
17773
|
+
// src/components/artifacts/chart-artifact/chart-artifact.tsx
|
|
17774
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
17775
|
+
var TITLE_CLASSES = "text-sm font-semibold text-foreground";
|
|
17776
|
+
var CHART_HEIGHT = 320;
|
|
17777
|
+
function ChartArtifact({ artifact, labels, callbacks }) {
|
|
17778
|
+
const validConfig = isValidChartConfig(artifact.config);
|
|
17779
|
+
(0, import_react9.useEffect)(() => {
|
|
17780
|
+
if (validConfig) return;
|
|
17781
|
+
console.warn("[clay] ChartArtifact: malformed `config` \u2014 skipping render.");
|
|
17782
|
+
}, [validConfig]);
|
|
17783
|
+
const presignedUrl = artifact.protectedAsset?.presignedUrl ?? null;
|
|
17784
|
+
const resolvedLabels = (0, import_react9.useMemo)(
|
|
17785
|
+
() => ({ ...DEFAULT_CHART_ARTIFACT_LABELS, ...labels?.[artifactTypes.CHART] ?? {} }),
|
|
17786
|
+
[labels]
|
|
17787
|
+
);
|
|
17788
|
+
const data2 = useChartArtifactData(
|
|
17789
|
+
validConfig ? presignedUrl : null,
|
|
17790
|
+
validConfig ? artifact.config : { variant: "LINE", series: [], xKey: "x" }
|
|
17791
|
+
);
|
|
17792
|
+
const onDownload = callbacks?.[artifactTypes.CHART]?.onDownload;
|
|
17793
|
+
const handleDownloadClick = onDownload ? () => onDownload(artifact) : void 0;
|
|
17794
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
|
|
17795
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(ArtifactHeader, { className: "bg-background/70", children: [
|
|
17796
|
+
artifact.title ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ArtifactTitle, { className: TITLE_CLASSES, children: artifact.title }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", {}),
|
|
17797
|
+
presignedUrl ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ArtifactActions, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ArtifactDownloadButton, { href: presignedUrl, label: resolvedLabels.download, onClick: handleDownloadClick }) }) : null
|
|
17798
|
+
] }),
|
|
17799
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
17800
|
+
ArtifactContent,
|
|
17801
|
+
{
|
|
17802
|
+
className: "p-4 overflow-visible flex flex-none items-center justify-center",
|
|
17803
|
+
style: { height: CHART_HEIGHT },
|
|
17804
|
+
children: renderBody(validConfig, artifact, data2, resolvedLabels)
|
|
17805
|
+
}
|
|
17806
|
+
)
|
|
17807
|
+
] });
|
|
17808
|
+
}
|
|
17809
|
+
function renderBody(validConfig, artifact, data2, labels) {
|
|
17810
|
+
if (!validConfig) {
|
|
17811
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(StatusMessage, { $tone: "info", children: labels.unavailable });
|
|
17812
|
+
}
|
|
17813
|
+
if (data2.status === "error") {
|
|
17814
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(StatusMessage, { $tone: "error", children: labels.loadError });
|
|
17815
|
+
}
|
|
17816
|
+
if (data2.status === "unavailable") {
|
|
17817
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(StatusMessage, { $tone: "info", children: labels.unavailable });
|
|
17818
|
+
}
|
|
17819
|
+
if (data2.status === "loading") {
|
|
17820
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(StatusMessage, { $tone: "info", children: labels.loading });
|
|
17821
|
+
}
|
|
17822
|
+
if (data2.rows.length === 0) {
|
|
17823
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(StatusMessage, { $tone: "info", children: labels.empty });
|
|
17824
|
+
}
|
|
17825
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ChartArtifactContent, { config: artifact.config, rows: data2.rows, labels });
|
|
17826
|
+
}
|
|
17827
|
+
|
|
17828
|
+
// src/components/artifacts/chart-artifact/to-clipboard-text.ts
|
|
17829
|
+
function chartArtifactToClipboardText(artifact) {
|
|
17830
|
+
const trimmedTitle = artifact.title?.trim();
|
|
17831
|
+
return trimmedTitle || "Chart";
|
|
17832
|
+
}
|
|
17833
|
+
|
|
17834
|
+
// src/components/artifacts/artifact-services/chart-artifact-service.ts
|
|
17835
|
+
var ChartArtifactService = {
|
|
17836
|
+
type: artifactTypes.CHART,
|
|
17837
|
+
Component: ChartArtifact,
|
|
17838
|
+
toClipboardText: chartArtifactToClipboardText
|
|
17839
|
+
};
|
|
17840
|
+
|
|
17841
|
+
// src/components/artifacts/table-artifact/table-artifact.tsx
|
|
17842
|
+
var import_react11 = require("react");
|
|
17843
|
+
|
|
17062
17844
|
// src/components/ui/table.tsx
|
|
17063
17845
|
var React2 = __toESM(require("react"), 1);
|
|
17064
|
-
var
|
|
17065
|
-
var Table = React2.forwardRef(({ className, containerClassName, ...props }, ref) => /* @__PURE__ */ (0,
|
|
17846
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
17847
|
+
var Table = React2.forwardRef(({ className, containerClassName, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: cn("relative w-full overflow-auto", containerClassName), children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("table", { ref, className: cn("w-full caption-bottom text-sm", className), ...props }) }));
|
|
17066
17848
|
Table.displayName = "Table";
|
|
17067
17849
|
var TableHeader = React2.forwardRef(
|
|
17068
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
17850
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("thead", { ref, className: cn("[&_tr]:border-b", className), ...props })
|
|
17069
17851
|
);
|
|
17070
17852
|
TableHeader.displayName = "TableHeader";
|
|
17071
17853
|
var TableBody = React2.forwardRef(
|
|
17072
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
17854
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("tbody", { ref, className: cn("[&_tr:last-child]:border-0", className), ...props })
|
|
17073
17855
|
);
|
|
17074
17856
|
TableBody.displayName = "TableBody";
|
|
17075
17857
|
var TableFooter = React2.forwardRef(
|
|
17076
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
17858
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("tfoot", { ref, className: cn("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0", className), ...props })
|
|
17077
17859
|
);
|
|
17078
17860
|
TableFooter.displayName = "TableFooter";
|
|
17079
17861
|
var TableRow = React2.forwardRef(
|
|
17080
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
17862
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
17081
17863
|
"tr",
|
|
17082
17864
|
{
|
|
17083
17865
|
ref,
|
|
@@ -17088,7 +17870,7 @@ var TableRow = React2.forwardRef(
|
|
|
17088
17870
|
);
|
|
17089
17871
|
TableRow.displayName = "TableRow";
|
|
17090
17872
|
var TableHead = React2.forwardRef(
|
|
17091
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
17873
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
17092
17874
|
"th",
|
|
17093
17875
|
{
|
|
17094
17876
|
ref,
|
|
@@ -17102,20 +17884,20 @@ var TableHead = React2.forwardRef(
|
|
|
17102
17884
|
);
|
|
17103
17885
|
TableHead.displayName = "TableHead";
|
|
17104
17886
|
var TableCell = React2.forwardRef(
|
|
17105
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
17887
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("td", { ref, className: cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className), ...props })
|
|
17106
17888
|
);
|
|
17107
17889
|
TableCell.displayName = "TableCell";
|
|
17108
17890
|
var TableCaption = React2.forwardRef(
|
|
17109
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
17891
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("caption", { ref, className: cn("mt-4 text-sm text-muted-foreground", className), ...props })
|
|
17110
17892
|
);
|
|
17111
17893
|
TableCaption.displayName = "TableCaption";
|
|
17112
17894
|
|
|
17113
17895
|
// src/components/table/use-scroll-shadow.ts
|
|
17114
|
-
var
|
|
17896
|
+
var import_react10 = require("react");
|
|
17115
17897
|
function useScrollShadow() {
|
|
17116
|
-
const targetRef = (0,
|
|
17117
|
-
const [isScrolled, setIsScrolled] = (0,
|
|
17118
|
-
(0,
|
|
17898
|
+
const targetRef = (0, import_react10.useRef)(null);
|
|
17899
|
+
const [isScrolled, setIsScrolled] = (0, import_react10.useState)(false);
|
|
17900
|
+
(0, import_react10.useEffect)(() => {
|
|
17119
17901
|
const target = targetRef.current;
|
|
17120
17902
|
if (!target) return;
|
|
17121
17903
|
let scrollContainer = target;
|
|
@@ -17136,18 +17918,6 @@ function useScrollShadow() {
|
|
|
17136
17918
|
return { targetRef, isScrolled };
|
|
17137
17919
|
}
|
|
17138
17920
|
|
|
17139
|
-
// src/components/artifacts/table-artifact/table-artifact-styles.ts
|
|
17140
|
-
var import_react5 = require("react");
|
|
17141
|
-
function StatusMessage({ $tone, children }) {
|
|
17142
|
-
return (0, import_react5.createElement)(
|
|
17143
|
-
"div",
|
|
17144
|
-
{
|
|
17145
|
-
className: `py-6 px-2 text-center text-sm font-medium leading-5 ${$tone === "error" ? "text-red-600" : "text-brown-70"}`
|
|
17146
|
-
},
|
|
17147
|
-
children
|
|
17148
|
-
);
|
|
17149
|
-
}
|
|
17150
|
-
|
|
17151
17921
|
// src/components/artifacts/table-artifact/table-artifact-content.constants.ts
|
|
17152
17922
|
var TABLE_STATUS = {
|
|
17153
17923
|
LOADING: "loading",
|
|
@@ -17167,125 +17937,58 @@ var DATA_ROW_CLASSES = `${ROW_CLASSES} animate-in fade-in duration-300`;
|
|
|
17167
17937
|
var SCROLL_SHADOW = "0 1px 2px rgb(0 0 0 / 0.01), 0 6px 12px -2px rgb(0 0 0 / 0.03)";
|
|
17168
17938
|
|
|
17169
17939
|
// src/components/artifacts/table-artifact/table-artifact-content.tsx
|
|
17170
|
-
var
|
|
17940
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
17171
17941
|
function TableArtifactContent({
|
|
17172
17942
|
columns,
|
|
17173
17943
|
data: data2,
|
|
17174
17944
|
knownRowCount,
|
|
17175
17945
|
maxShimmerRows,
|
|
17176
17946
|
maxBodyHeight,
|
|
17177
|
-
|
|
17947
|
+
labels
|
|
17178
17948
|
}) {
|
|
17179
17949
|
if (data2.status === TABLE_STATUS.ERROR) {
|
|
17180
|
-
return /* @__PURE__ */ (0,
|
|
17950
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(StatusMessage, { $tone: "error", children: labels.loadError });
|
|
17181
17951
|
}
|
|
17182
17952
|
if (data2.status === TABLE_STATUS.UNAVAILABLE) {
|
|
17183
|
-
return /* @__PURE__ */ (0,
|
|
17953
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(StatusMessage, { $tone: "info", children: labels.unavailable });
|
|
17184
17954
|
}
|
|
17185
17955
|
if (data2.status === TABLE_STATUS.LOADING) {
|
|
17186
17956
|
if (typeof knownRowCount === "number" && knownRowCount > 0) {
|
|
17187
17957
|
const shimmerCount = Math.min(knownRowCount, maxShimmerRows);
|
|
17188
|
-
return /* @__PURE__ */ (0,
|
|
17958
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ArtifactTable, { columns, maxBodyHeight, children: renderShimmerRows(columns, shimmerCount) });
|
|
17189
17959
|
}
|
|
17190
|
-
return /* @__PURE__ */ (0,
|
|
17960
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(StatusMessage, { $tone: "info", children: labels.loading });
|
|
17191
17961
|
}
|
|
17192
|
-
return /* @__PURE__ */ (0,
|
|
17962
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ArtifactTable, { columns, maxBodyHeight, children: data2.rows.length === 0 ? renderEmptyRow(columns.length, labels.empty) : renderDataRows(columns, data2.rows) });
|
|
17193
17963
|
}
|
|
17194
17964
|
function ArtifactTable({ columns, maxBodyHeight, children }) {
|
|
17195
17965
|
const { targetRef, isScrolled } = useScrollShadow();
|
|
17196
|
-
return /* @__PURE__ */ (0,
|
|
17197
|
-
/* @__PURE__ */ (0,
|
|
17966
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { ref: targetRef, className: "overscroll-none", style: { maxHeight: maxBodyHeight, overflowY: "auto" }, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Table, { containerClassName: "overflow-visible", children: [
|
|
17967
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
17198
17968
|
TableHeader,
|
|
17199
17969
|
{
|
|
17200
17970
|
"data-scrolled": isScrolled ? "true" : void 0,
|
|
17201
17971
|
className: "sticky top-0 z-10 bg-background/70 backdrop-blur-lg transition-shadow",
|
|
17202
17972
|
style: isScrolled ? { boxShadow: SCROLL_SHADOW } : void 0,
|
|
17203
|
-
children: /* @__PURE__ */ (0,
|
|
17973
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TableRow, { className: "hover:bg-transparent", children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TableHead, { scope: "col", className: HEAD_CLASS, children: column.label }, column.key)) })
|
|
17204
17974
|
}
|
|
17205
17975
|
),
|
|
17206
|
-
/* @__PURE__ */ (0,
|
|
17976
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TableBody, { children })
|
|
17207
17977
|
] }) });
|
|
17208
17978
|
}
|
|
17209
17979
|
function renderShimmerRows(columns, count) {
|
|
17210
|
-
return Array.from({ length: count }).map((_, index2) => /* @__PURE__ */ (0,
|
|
17980
|
+
return Array.from({ length: count }).map((_, index2) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TableRow, { className: ROW_CLASSES, "aria-hidden": "true", children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TableCell, { className: CELL_CLASS, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "block h-3 w-3/4 animate-pulse rounded bg-muted-foreground/20" }) }, column.key)) }, `shimmer-${index2}`));
|
|
17211
17981
|
}
|
|
17212
17982
|
function renderDataRows(columns, rows) {
|
|
17213
|
-
return rows.map((row, index2) => /* @__PURE__ */ (0,
|
|
17983
|
+
return rows.map((row, index2) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TableRow, { className: DATA_ROW_CLASSES, children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TableCell, { className: CELL_CLASS, children: formatCell(row, column) }, column.key)) }, index2));
|
|
17214
17984
|
}
|
|
17215
|
-
function renderEmptyRow(colSpan) {
|
|
17216
|
-
return /* @__PURE__ */ (0,
|
|
17217
|
-
}
|
|
17218
|
-
|
|
17219
|
-
// src/components/artifacts/table-artifact/use-table-artifact-data.ts
|
|
17220
|
-
var import_react6 = require("react");
|
|
17221
|
-
|
|
17222
|
-
// src/components/artifacts/table-artifact/parse-csv.ts
|
|
17223
|
-
var import_papaparse = __toESM(require("papaparse"), 1);
|
|
17224
|
-
function parseCsv(text2, columns) {
|
|
17225
|
-
const result = import_papaparse.default.parse(text2, {
|
|
17226
|
-
header: true,
|
|
17227
|
-
skipEmptyLines: true,
|
|
17228
|
-
dynamicTyping: false
|
|
17229
|
-
});
|
|
17230
|
-
const csvHeaders = new Set(result.meta?.fields ?? []);
|
|
17231
|
-
const presentColumns = columns.filter((col) => csvHeaders.has(col.key));
|
|
17232
|
-
return result.data.map((rawRow) => {
|
|
17233
|
-
const row = {};
|
|
17234
|
-
for (const column of presentColumns) {
|
|
17235
|
-
const value2 = rawRow[column.key];
|
|
17236
|
-
row[column.key] = value2 === void 0 || value2 === "" ? null : value2;
|
|
17237
|
-
}
|
|
17238
|
-
return row;
|
|
17239
|
-
});
|
|
17985
|
+
function renderEmptyRow(colSpan, emptyMessage) {
|
|
17986
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TableRow, { className: "hover:bg-transparent", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TableCell, { colSpan, className: "py-6 text-center text-sm text-muted-foreground", children: emptyMessage }) });
|
|
17240
17987
|
}
|
|
17241
17988
|
|
|
17242
17989
|
// src/components/artifacts/table-artifact/use-table-artifact-data.ts
|
|
17243
|
-
var LOADING = { status: "loading", rows: null, error: null };
|
|
17244
|
-
var UNAVAILABLE = { status: "unavailable", rows: null, error: null };
|
|
17245
|
-
var INITIAL_INTERNAL = { cacheKey: null, data: LOADING };
|
|
17246
|
-
function columnsFingerprint(columns) {
|
|
17247
|
-
return columns.map((c) => `${c.key}:${c.type ?? "string"}`).join("|");
|
|
17248
|
-
}
|
|
17249
17990
|
function useTableArtifactData(presignedUrl, columns) {
|
|
17250
|
-
|
|
17251
|
-
const cacheKey = presignedUrl ? `${presignedUrl}::${colsKey}` : null;
|
|
17252
|
-
const [state, setState] = (0, import_react6.useState)(INITIAL_INTERNAL);
|
|
17253
|
-
(0, import_react6.useEffect)(() => {
|
|
17254
|
-
if (!presignedUrl) return;
|
|
17255
|
-
const controller = new AbortController();
|
|
17256
|
-
fetch(presignedUrl, {
|
|
17257
|
-
signal: controller.signal,
|
|
17258
|
-
headers: { Accept: "text/csv" },
|
|
17259
|
-
// Presigned URLs are cross-origin S3 in production and don't need credentials. Explicit
|
|
17260
|
-
// omit so a same-origin URL (compromised payload, local dev) can't accidentally receive
|
|
17261
|
-
// session cookies or auth headers.
|
|
17262
|
-
credentials: "omit"
|
|
17263
|
-
}).then(async (response) => {
|
|
17264
|
-
if (!response.ok) throw new Error(`Failed to load table data (${response.status})`);
|
|
17265
|
-
return response.text();
|
|
17266
|
-
}).then((text2) => {
|
|
17267
|
-
if (controller.signal.aborted) return;
|
|
17268
|
-
try {
|
|
17269
|
-
const rows = parseCsv(text2, columns);
|
|
17270
|
-
setState({ cacheKey: `${presignedUrl}::${colsKey}`, data: { status: "ready", rows, error: null } });
|
|
17271
|
-
} catch (parseError) {
|
|
17272
|
-
console.error("[TableArtifact] CSV parse failed", parseError);
|
|
17273
|
-
const err = parseError instanceof Error ? parseError : new Error(String(parseError));
|
|
17274
|
-
setState({ cacheKey: `${presignedUrl}::${colsKey}`, data: { status: "error", rows: null, error: err } });
|
|
17275
|
-
}
|
|
17276
|
-
}).catch((error) => {
|
|
17277
|
-
if (controller.signal.aborted) return;
|
|
17278
|
-
console.error("[TableArtifact] Fetch failed", error);
|
|
17279
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
17280
|
-
setState({ cacheKey: `${presignedUrl}::${colsKey}`, data: { status: "error", rows: null, error: err } });
|
|
17281
|
-
});
|
|
17282
|
-
return () => {
|
|
17283
|
-
controller.abort();
|
|
17284
|
-
};
|
|
17285
|
-
}, [presignedUrl, colsKey]);
|
|
17286
|
-
if (!presignedUrl) return UNAVAILABLE;
|
|
17287
|
-
if (state.cacheKey !== cacheKey) return LOADING;
|
|
17288
|
-
return state.data;
|
|
17991
|
+
return useRowsArtifactData(presignedUrl, columns, parseCsv);
|
|
17289
17992
|
}
|
|
17290
17993
|
|
|
17291
17994
|
// src/components/artifacts/table-artifact/validate.ts
|
|
@@ -17305,42 +18008,61 @@ function isValidTableColumn(column) {
|
|
|
17305
18008
|
}
|
|
17306
18009
|
|
|
17307
18010
|
// src/components/artifacts/table-artifact/table-artifact.tsx
|
|
17308
|
-
var
|
|
17309
|
-
var
|
|
18011
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
18012
|
+
var TITLE_CLASSES2 = "text-sm font-semibold text-foreground";
|
|
17310
18013
|
var TABLE_MAX_BODY_HEIGHT = 480;
|
|
17311
18014
|
var MAX_SHIMMER_ROWS = 10;
|
|
17312
|
-
|
|
17313
|
-
function TableArtifact({ artifact }) {
|
|
18015
|
+
function TableArtifact({ artifact, labels, callbacks }) {
|
|
17314
18016
|
const validConfig = isValidTableConfig(artifact.config);
|
|
17315
18017
|
const validColumns = validConfig ? artifact.config.columns : null;
|
|
17316
|
-
(0,
|
|
18018
|
+
(0, import_react11.useEffect)(() => {
|
|
17317
18019
|
if (validConfig) return;
|
|
17318
18020
|
console.warn("[clay] TableArtifact: malformed `config` \u2014 skipping render.");
|
|
17319
18021
|
}, [validConfig]);
|
|
18022
|
+
const resolvedLabels = (0, import_react11.useMemo)(
|
|
18023
|
+
() => ({ ...DEFAULT_TABLE_ARTIFACT_LABELS, ...labels?.[artifactTypes.TABLE] ?? {} }),
|
|
18024
|
+
[labels]
|
|
18025
|
+
);
|
|
17320
18026
|
const data2 = useTableArtifactData(
|
|
17321
18027
|
validConfig ? artifact.protectedAsset?.presignedUrl ?? null : null,
|
|
17322
18028
|
validColumns ?? []
|
|
17323
18029
|
);
|
|
17324
18030
|
const presignedUrl = artifact.protectedAsset?.presignedUrl ?? null;
|
|
18031
|
+
const onDownload = callbacks?.[artifactTypes.TABLE]?.onDownload;
|
|
18032
|
+
const handleDownloadClick = onDownload ? () => onDownload(artifact) : void 0;
|
|
17325
18033
|
if (!validConfig || !validColumns) {
|
|
17326
|
-
return /* @__PURE__ */ (0,
|
|
17327
|
-
/* @__PURE__ */ (0,
|
|
17328
|
-
artifact.title ? /* @__PURE__ */ (0,
|
|
17329
|
-
presignedUrl ? /* @__PURE__ */ (0,
|
|
18034
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
|
|
18035
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(ArtifactHeader, { className: "bg-background/70", children: [
|
|
18036
|
+
artifact.title ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ArtifactTitle, { className: TITLE_CLASSES2, children: artifact.title }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", {}),
|
|
18037
|
+
presignedUrl ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ArtifactActions, { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
18038
|
+
ArtifactDownloadButton,
|
|
18039
|
+
{
|
|
18040
|
+
href: presignedUrl,
|
|
18041
|
+
label: resolvedLabels.download,
|
|
18042
|
+
onClick: handleDownloadClick
|
|
18043
|
+
}
|
|
18044
|
+
) }) : null
|
|
17330
18045
|
] }),
|
|
17331
|
-
/* @__PURE__ */ (0,
|
|
18046
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ArtifactContent, { className: "p-0 overflow-auto", style: { maxHeight: TABLE_MAX_BODY_HEIGHT }, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(StatusMessage, { $tone: "info", children: resolvedLabels.unavailable }) })
|
|
17332
18047
|
] });
|
|
17333
18048
|
}
|
|
17334
18049
|
return (
|
|
17335
18050
|
// The table body owns its own scroll container (`ArtifactTable` inside `TableArtifactContent`).
|
|
17336
18051
|
// Disable the outer overflow container so only one scroll context exists — this prevents
|
|
17337
18052
|
// double-scroll nesting and lets `useScrollShadow` find the correct scroll ancestor.
|
|
17338
|
-
/* @__PURE__ */ (0,
|
|
17339
|
-
/* @__PURE__ */ (0,
|
|
17340
|
-
artifact.title ? /* @__PURE__ */ (0,
|
|
17341
|
-
/* @__PURE__ */ (0,
|
|
18053
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
|
|
18054
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(ArtifactHeader, { className: "bg-background/70", children: [
|
|
18055
|
+
artifact.title ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ArtifactTitle, { className: TITLE_CLASSES2, children: artifact.title }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", {}),
|
|
18056
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ArtifactActions, { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
18057
|
+
ArtifactDownloadButton,
|
|
18058
|
+
{
|
|
18059
|
+
href: presignedUrl ?? "",
|
|
18060
|
+
label: resolvedLabels.download,
|
|
18061
|
+
onClick: handleDownloadClick
|
|
18062
|
+
}
|
|
18063
|
+
) })
|
|
17342
18064
|
] }),
|
|
17343
|
-
/* @__PURE__ */ (0,
|
|
18065
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ArtifactContent, { className: "p-0 overflow-visible", style: { maxHeight: "none" }, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
17344
18066
|
TableArtifactContent,
|
|
17345
18067
|
{
|
|
17346
18068
|
columns: validColumns,
|
|
@@ -17348,7 +18070,7 @@ function TableArtifact({ artifact }) {
|
|
|
17348
18070
|
knownRowCount: artifact.config.stats?.rowCount,
|
|
17349
18071
|
maxShimmerRows: MAX_SHIMMER_ROWS,
|
|
17350
18072
|
maxBodyHeight: TABLE_MAX_BODY_HEIGHT,
|
|
17351
|
-
|
|
18073
|
+
labels: resolvedLabels
|
|
17352
18074
|
}
|
|
17353
18075
|
) })
|
|
17354
18076
|
] })
|
|
@@ -17370,7 +18092,8 @@ var TableArtifactService = {
|
|
|
17370
18092
|
|
|
17371
18093
|
// src/components/artifacts/artifact-services/index.ts
|
|
17372
18094
|
var ArtifactServices = {
|
|
17373
|
-
[artifactTypes.TABLE]: TableArtifactService
|
|
18095
|
+
[artifactTypes.TABLE]: TableArtifactService,
|
|
18096
|
+
[artifactTypes.CHART]: ChartArtifactService
|
|
17374
18097
|
};
|
|
17375
18098
|
function artifactToClipboardText(artifact) {
|
|
17376
18099
|
const entry = ArtifactServices[artifact.type];
|
|
@@ -17381,13 +18104,13 @@ function artifactToClipboardText(artifact) {
|
|
|
17381
18104
|
}
|
|
17382
18105
|
|
|
17383
18106
|
// src/components/blocks/artifact-ref-block/artifact-ref-block.tsx
|
|
17384
|
-
var
|
|
18107
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
17385
18108
|
function ArtifactRefBlock({ block }) {
|
|
17386
|
-
const { artifact } = block.payload;
|
|
18109
|
+
const { artifact, labels, callbacks } = block.payload;
|
|
17387
18110
|
const entry = ArtifactServices[artifact.type];
|
|
17388
18111
|
if (!entry) return null;
|
|
17389
18112
|
const { Component } = entry;
|
|
17390
|
-
return /* @__PURE__ */ (0,
|
|
18113
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Component, { artifact, labels, callbacks });
|
|
17391
18114
|
}
|
|
17392
18115
|
|
|
17393
18116
|
// src/components/blocks/block-services/artifact-ref-block-service.ts
|
|
@@ -17439,9 +18162,9 @@ var TableScroll = import_styled_components3.default.div`
|
|
|
17439
18162
|
`;
|
|
17440
18163
|
|
|
17441
18164
|
// src/components/blocks/scrollable-table/scrollable-table.tsx
|
|
17442
|
-
var
|
|
18165
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
17443
18166
|
function ScrollableTable({ node: _node, ...props }) {
|
|
17444
|
-
return /* @__PURE__ */ (0,
|
|
18167
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TableContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TableScroll, { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("table", { ...props }) }) });
|
|
17445
18168
|
}
|
|
17446
18169
|
|
|
17447
18170
|
// src/components/blocks/text-block/sanitize.ts
|
|
@@ -17572,12 +18295,12 @@ var TextBlockWrapper = import_styled_components4.default.div`
|
|
|
17572
18295
|
`;
|
|
17573
18296
|
|
|
17574
18297
|
// src/components/blocks/text-block/text-block.tsx
|
|
17575
|
-
var
|
|
18298
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
17576
18299
|
var markdownComponents = {
|
|
17577
|
-
table: ((tableProps) => /* @__PURE__ */ (0,
|
|
18300
|
+
table: ((tableProps) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ScrollableTable, { ...tableProps }))
|
|
17578
18301
|
};
|
|
17579
18302
|
function TextBlock({ block }) {
|
|
17580
|
-
return /* @__PURE__ */ (0,
|
|
18303
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TextBlockWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_markdown.default, { remarkPlugins: [import_remark_gfm.default, import_remark_breaks.default], components: markdownComponents, children: sanitize(block.payload.text) }) });
|
|
17581
18304
|
}
|
|
17582
18305
|
|
|
17583
18306
|
// src/components/blocks/block-services/text-block-service.ts
|
|
@@ -17599,23 +18322,23 @@ var BlockServices = {
|
|
|
17599
18322
|
};
|
|
17600
18323
|
|
|
17601
18324
|
// src/components/blocks/block/block.tsx
|
|
17602
|
-
var
|
|
18325
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
17603
18326
|
function Block({ block }) {
|
|
17604
18327
|
const service = BlockServices[block.type];
|
|
17605
18328
|
if (!service) return null;
|
|
17606
18329
|
const { Component } = service;
|
|
17607
|
-
return /* @__PURE__ */ (0,
|
|
18330
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Component, { block });
|
|
17608
18331
|
}
|
|
17609
18332
|
|
|
17610
18333
|
// src/components/blocks/block-context/block-context.tsx
|
|
17611
|
-
var
|
|
17612
|
-
var BlockContext = (0,
|
|
18334
|
+
var import_react12 = require("react");
|
|
18335
|
+
var BlockContext = (0, import_react12.createContext)(null);
|
|
17613
18336
|
function useBlockContext() {
|
|
17614
|
-
return (0,
|
|
18337
|
+
return (0, import_react12.useContext)(BlockContext) ?? {};
|
|
17615
18338
|
}
|
|
17616
18339
|
|
|
17617
18340
|
// src/components/chat/chat-message/chat-message.tsx
|
|
17618
|
-
var
|
|
18341
|
+
var import_react16 = require("react");
|
|
17619
18342
|
|
|
17620
18343
|
// src/components/chat/hooks/copy-message-text.ts
|
|
17621
18344
|
function copyMessageText(message) {
|
|
@@ -17632,13 +18355,13 @@ function copyMessageText(message) {
|
|
|
17632
18355
|
}
|
|
17633
18356
|
|
|
17634
18357
|
// src/components/chat/chat-message-actions/chat-message-actions.tsx
|
|
17635
|
-
var
|
|
18358
|
+
var import_react15 = require("react");
|
|
17636
18359
|
|
|
17637
18360
|
// src/components/chat/chat-context/chat-context.ts
|
|
17638
|
-
var
|
|
17639
|
-
var ChatContext = (0,
|
|
18361
|
+
var import_react13 = require("react");
|
|
18362
|
+
var ChatContext = (0, import_react13.createContext)(null);
|
|
17640
18363
|
function useChatContext() {
|
|
17641
|
-
const context = (0,
|
|
18364
|
+
const context = (0, import_react13.useContext)(ChatContext);
|
|
17642
18365
|
if (!context) {
|
|
17643
18366
|
throw new Error("useChatContext must be used within a Chat.Root component");
|
|
17644
18367
|
}
|
|
@@ -17646,7 +18369,7 @@ function useChatContext() {
|
|
|
17646
18369
|
}
|
|
17647
18370
|
|
|
17648
18371
|
// src/components/chat/hooks/use-copy-to-clipboard.ts
|
|
17649
|
-
var
|
|
18372
|
+
var import_react14 = require("react");
|
|
17650
18373
|
|
|
17651
18374
|
// src/utils/clipboard.ts
|
|
17652
18375
|
function copyToClipboard(text2, options) {
|
|
@@ -17659,14 +18382,14 @@ function copyToClipboard(text2, options) {
|
|
|
17659
18382
|
// src/components/chat/hooks/use-copy-to-clipboard.ts
|
|
17660
18383
|
var RESET_DELAY_MS = 2e3;
|
|
17661
18384
|
function useCopyToClipboard() {
|
|
17662
|
-
const [isCopied, setIsCopied] = (0,
|
|
17663
|
-
const timeoutRef = (0,
|
|
17664
|
-
(0,
|
|
18385
|
+
const [isCopied, setIsCopied] = (0, import_react14.useState)(false);
|
|
18386
|
+
const timeoutRef = (0, import_react14.useRef)(null);
|
|
18387
|
+
(0, import_react14.useEffect)(() => {
|
|
17665
18388
|
return () => {
|
|
17666
18389
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
17667
18390
|
};
|
|
17668
18391
|
}, []);
|
|
17669
|
-
const copy = (0,
|
|
18392
|
+
const copy = (0, import_react14.useCallback)((text2) => {
|
|
17670
18393
|
copyToClipboard(text2, {
|
|
17671
18394
|
onSuccess: () => {
|
|
17672
18395
|
setIsCopied(true);
|
|
@@ -17706,24 +18429,24 @@ var AnimatedAction = import_styled_components5.default.div`
|
|
|
17706
18429
|
`;
|
|
17707
18430
|
|
|
17708
18431
|
// src/components/chat/chat-message-actions/chat-message-actions.tsx
|
|
17709
|
-
var
|
|
18432
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
17710
18433
|
function ChatMessageActions({ className, messageId, content: content2, role, isHelpful }) {
|
|
17711
18434
|
const { onCopyMessage, onThumbUpClick, onThumbDownClick } = useChatContext();
|
|
17712
18435
|
const { isCopied, copy } = useCopyToClipboard();
|
|
17713
|
-
const handleCopy = (0,
|
|
18436
|
+
const handleCopy = (0, import_react15.useCallback)(() => {
|
|
17714
18437
|
copy(content2);
|
|
17715
18438
|
onCopyMessage?.(messageId);
|
|
17716
18439
|
}, [content2, messageId, copy, onCopyMessage]);
|
|
17717
|
-
const handleThumbUp = (0,
|
|
18440
|
+
const handleThumbUp = (0, import_react15.useCallback)(() => {
|
|
17718
18441
|
onThumbUpClick?.(messageId, isHelpful === true ? null : true);
|
|
17719
18442
|
}, [messageId, isHelpful, onThumbUpClick]);
|
|
17720
|
-
const handleThumbDown = (0,
|
|
18443
|
+
const handleThumbDown = (0, import_react15.useCallback)(() => {
|
|
17721
18444
|
onThumbDownClick?.(messageId, isHelpful === false ? null : false);
|
|
17722
18445
|
}, [messageId, isHelpful, onThumbDownClick]);
|
|
17723
18446
|
const isAssistant = role === MESSAGE_ROLE.ASSISTANT;
|
|
17724
18447
|
const hasFeedback = isAssistant && (onThumbUpClick || onThumbDownClick);
|
|
17725
|
-
return /* @__PURE__ */ (0,
|
|
17726
|
-
/* @__PURE__ */ (0,
|
|
18448
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(ActionsContainer, { $role: role, className, children: [
|
|
18449
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
17727
18450
|
IconButton,
|
|
17728
18451
|
{
|
|
17729
18452
|
icon: isCopied ? IconCheck : IconCopy,
|
|
@@ -17731,7 +18454,7 @@ function ChatMessageActions({ className, messageId, content: content2, role, isH
|
|
|
17731
18454
|
"aria-label": isCopied ? "Copied" : "Copy message"
|
|
17732
18455
|
}
|
|
17733
18456
|
),
|
|
17734
|
-
hasFeedback && /* @__PURE__ */ (0,
|
|
18457
|
+
hasFeedback && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(AnimatedAction, { $visible: isHelpful !== false, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
17735
18458
|
IconButton,
|
|
17736
18459
|
{
|
|
17737
18460
|
icon: IconThumbUp,
|
|
@@ -17740,7 +18463,7 @@ function ChatMessageActions({ className, messageId, content: content2, role, isH
|
|
|
17740
18463
|
"aria-label": "Good response"
|
|
17741
18464
|
}
|
|
17742
18465
|
) }),
|
|
17743
|
-
hasFeedback && /* @__PURE__ */ (0,
|
|
18466
|
+
hasFeedback && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(AnimatedAction, { $visible: isHelpful !== true, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
17744
18467
|
IconButton,
|
|
17745
18468
|
{
|
|
17746
18469
|
icon: IconThumbDown,
|
|
@@ -17790,12 +18513,12 @@ var MessageBubble = import_styled_components6.default.div`
|
|
|
17790
18513
|
`;
|
|
17791
18514
|
|
|
17792
18515
|
// src/components/chat/chat-message/chat-message.tsx
|
|
17793
|
-
var
|
|
18516
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
17794
18517
|
function ChatMessage({ message }) {
|
|
17795
|
-
const clipboardText = (0,
|
|
17796
|
-
return /* @__PURE__ */ (0,
|
|
17797
|
-
/* @__PURE__ */ (0,
|
|
17798
|
-
/* @__PURE__ */ (0,
|
|
18518
|
+
const clipboardText = (0, import_react16.useMemo)(() => copyMessageText(message), [message]);
|
|
18519
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(MessageRow, { $role: message.role, role: "article", "aria-label": `${message.role} message`, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(MessageContainer, { $role: message.role, children: [
|
|
18520
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(MessageBubble, { $role: message.role, "data-testid": "message-bubble", children: message.blocks.map((block, index2) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Block, { block }, index2)) }),
|
|
18521
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
17799
18522
|
ChatMessageActions,
|
|
17800
18523
|
{
|
|
17801
18524
|
messageId: message.id,
|
|
@@ -17844,20 +18567,20 @@ var Key = import_styled_components7.default.kbd`
|
|
|
17844
18567
|
`;
|
|
17845
18568
|
|
|
17846
18569
|
// src/components/keyboard-shortcut/keyboard-shortcut.tsx
|
|
17847
|
-
var
|
|
18570
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
17848
18571
|
function KeyboardShortcut({
|
|
17849
18572
|
keys,
|
|
17850
18573
|
variant = KEYBOARD_SHORTCUT_VARIANTS.OUTLINED,
|
|
17851
18574
|
className
|
|
17852
18575
|
}) {
|
|
17853
|
-
return /* @__PURE__ */ (0,
|
|
18576
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Wrapper, { className, children: keys.map((KeyComponent, index2) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Key, { $variant: variant, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Icon, { icon: KeyComponent, size: 12 }) }, index2)) });
|
|
17854
18577
|
}
|
|
17855
18578
|
|
|
17856
18579
|
// src/components/keyboard-shortcut/icons/icon-ctrl.tsx
|
|
17857
|
-
var
|
|
18580
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
17858
18581
|
function IconCtrl(props) {
|
|
17859
18582
|
const { width: width2 = 24, height: height2 = 24, ...rest } = props;
|
|
17860
|
-
return /* @__PURE__ */ (0,
|
|
18583
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", width: width2, height: height2, fill: "none", ...rest, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
17861
18584
|
"text",
|
|
17862
18585
|
{
|
|
17863
18586
|
x: "50%",
|
|
@@ -17874,7 +18597,7 @@ function IconCtrl(props) {
|
|
|
17874
18597
|
}
|
|
17875
18598
|
|
|
17876
18599
|
// src/components/lottie/lottie.tsx
|
|
17877
|
-
var
|
|
18600
|
+
var import_react18 = require("react");
|
|
17878
18601
|
|
|
17879
18602
|
// src/components/lottie/lottie-styles.ts
|
|
17880
18603
|
var import_styled_components8 = __toESM(require("styled-components"), 1);
|
|
@@ -17890,7 +18613,7 @@ var LottieContainer = import_styled_components8.default.div`
|
|
|
17890
18613
|
`;
|
|
17891
18614
|
|
|
17892
18615
|
// src/components/lottie/use-lottie.ts
|
|
17893
|
-
var
|
|
18616
|
+
var import_react17 = require("react");
|
|
17894
18617
|
var import_lottie_web = __toESM(require_lottie(), 1);
|
|
17895
18618
|
function useLottie({
|
|
17896
18619
|
animationData: animationData2,
|
|
@@ -17905,17 +18628,17 @@ function useLottie({
|
|
|
17905
18628
|
onLoopComplete,
|
|
17906
18629
|
onEnterFrame
|
|
17907
18630
|
}) {
|
|
17908
|
-
const containerRef = (0,
|
|
17909
|
-
const animationRef = (0,
|
|
17910
|
-
const onAnimationLoadedRef = (0,
|
|
17911
|
-
const onCompleteRef = (0,
|
|
17912
|
-
const onLoopCompleteRef = (0,
|
|
17913
|
-
const onEnterFrameRef = (0,
|
|
18631
|
+
const containerRef = (0, import_react17.useRef)(null);
|
|
18632
|
+
const animationRef = (0, import_react17.useRef)(null);
|
|
18633
|
+
const onAnimationLoadedRef = (0, import_react17.useRef)(onAnimationLoaded);
|
|
18634
|
+
const onCompleteRef = (0, import_react17.useRef)(onComplete);
|
|
18635
|
+
const onLoopCompleteRef = (0, import_react17.useRef)(onLoopComplete);
|
|
18636
|
+
const onEnterFrameRef = (0, import_react17.useRef)(onEnterFrame);
|
|
17914
18637
|
onAnimationLoadedRef.current = onAnimationLoaded;
|
|
17915
18638
|
onCompleteRef.current = onComplete;
|
|
17916
18639
|
onLoopCompleteRef.current = onLoopComplete;
|
|
17917
18640
|
onEnterFrameRef.current = onEnterFrame;
|
|
17918
|
-
(0,
|
|
18641
|
+
(0, import_react17.useEffect)(() => {
|
|
17919
18642
|
if (!containerRef.current) return;
|
|
17920
18643
|
const anim = import_lottie_web.default.loadAnimation({
|
|
17921
18644
|
container: containerRef.current,
|
|
@@ -18007,8 +18730,8 @@ function createLottieRef(animationRef) {
|
|
|
18007
18730
|
}
|
|
18008
18731
|
|
|
18009
18732
|
// src/components/lottie/lottie.tsx
|
|
18010
|
-
var
|
|
18011
|
-
var Lottie = (0,
|
|
18733
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
18734
|
+
var Lottie = (0, import_react18.forwardRef)(function Lottie2({
|
|
18012
18735
|
animationData: animationData2,
|
|
18013
18736
|
autoplay,
|
|
18014
18737
|
loop,
|
|
@@ -18038,8 +18761,8 @@ var Lottie = (0, import_react14.forwardRef)(function Lottie2({
|
|
|
18038
18761
|
onLoopComplete,
|
|
18039
18762
|
onEnterFrame
|
|
18040
18763
|
});
|
|
18041
|
-
(0,
|
|
18042
|
-
return /* @__PURE__ */ (0,
|
|
18764
|
+
(0, import_react18.useImperativeHandle)(ref, () => createLottieRef(animationRef), [animationRef]);
|
|
18765
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
18043
18766
|
LottieContainer,
|
|
18044
18767
|
{
|
|
18045
18768
|
ref: containerRef,
|
|
@@ -18053,7 +18776,7 @@ var Lottie = (0, import_react14.forwardRef)(function Lottie2({
|
|
|
18053
18776
|
});
|
|
18054
18777
|
|
|
18055
18778
|
// src/components/text-area/text-area.tsx
|
|
18056
|
-
var
|
|
18779
|
+
var import_react19 = require("react");
|
|
18057
18780
|
|
|
18058
18781
|
// src/utils/merge-refs.ts
|
|
18059
18782
|
function mergeRefs(...refs) {
|
|
@@ -18093,23 +18816,23 @@ var StyledTextArea = import_styled_components9.default.textarea`
|
|
|
18093
18816
|
`;
|
|
18094
18817
|
|
|
18095
18818
|
// src/components/text-area/text-area.tsx
|
|
18096
|
-
var
|
|
18097
|
-
var TextArea = (0,
|
|
18098
|
-
const internalRef = (0,
|
|
18099
|
-
(0,
|
|
18819
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
18820
|
+
var TextArea = (0, import_react19.forwardRef)(function TextArea2({ value: value2, onChange, placeholder, maxHeight, rows = 1, autoFocus, onKeyDown, disabled, className }, externalRef) {
|
|
18821
|
+
const internalRef = (0, import_react19.useRef)(null);
|
|
18822
|
+
(0, import_react19.useLayoutEffect)(() => {
|
|
18100
18823
|
const el = internalRef.current;
|
|
18101
18824
|
if (el) {
|
|
18102
18825
|
el.style.height = "auto";
|
|
18103
18826
|
el.style.height = `${el.scrollHeight}px`;
|
|
18104
18827
|
}
|
|
18105
18828
|
}, [value2]);
|
|
18106
|
-
const handleChange = (0,
|
|
18829
|
+
const handleChange = (0, import_react19.useCallback)(
|
|
18107
18830
|
(e) => {
|
|
18108
18831
|
onChange(e.target.value);
|
|
18109
18832
|
},
|
|
18110
18833
|
[onChange]
|
|
18111
18834
|
);
|
|
18112
|
-
return /* @__PURE__ */ (0,
|
|
18835
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
18113
18836
|
StyledTextArea,
|
|
18114
18837
|
{
|
|
18115
18838
|
ref: mergeRefs(internalRef, externalRef),
|
|
@@ -18198,7 +18921,7 @@ function convertTableToCSV(table) {
|
|
|
18198
18921
|
}
|
|
18199
18922
|
|
|
18200
18923
|
// src/components/button/button.tsx
|
|
18201
|
-
var
|
|
18924
|
+
var import_react20 = require("react");
|
|
18202
18925
|
|
|
18203
18926
|
// src/components/button/button-styles.ts
|
|
18204
18927
|
var import_styled_components10 = __toESM(require("styled-components"), 1);
|
|
@@ -18320,8 +19043,8 @@ var StyledButton = import_styled_components10.default.button`
|
|
|
18320
19043
|
`;
|
|
18321
19044
|
|
|
18322
19045
|
// src/components/button/button.tsx
|
|
18323
|
-
var
|
|
18324
|
-
var Button2 = (0,
|
|
19046
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
19047
|
+
var Button2 = (0, import_react20.forwardRef)(function Button3({
|
|
18325
19048
|
children,
|
|
18326
19049
|
variant = BUTTON_VARIANT.SOLID,
|
|
18327
19050
|
intent = BUTTON_INTENT.PRIMARY,
|
|
@@ -18333,8 +19056,8 @@ var Button2 = (0, import_react16.forwardRef)(function Button3({
|
|
|
18333
19056
|
className,
|
|
18334
19057
|
"aria-label": ariaLabel
|
|
18335
19058
|
}, ref) {
|
|
18336
|
-
const iconElement = icon ? /* @__PURE__ */ (0,
|
|
18337
|
-
return /* @__PURE__ */ (0,
|
|
19059
|
+
const iconElement = icon ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Icon, { icon, size: 16 }) : null;
|
|
19060
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
18338
19061
|
StyledButton,
|
|
18339
19062
|
{
|
|
18340
19063
|
ref,
|
|
@@ -18348,7 +19071,7 @@ var Button2 = (0, import_react16.forwardRef)(function Button3({
|
|
|
18348
19071
|
"aria-label": ariaLabel,
|
|
18349
19072
|
children: [
|
|
18350
19073
|
iconPosition === ICON_POSITION.LEADING && iconElement,
|
|
18351
|
-
/* @__PURE__ */ (0,
|
|
19074
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { children }),
|
|
18352
19075
|
iconPosition === ICON_POSITION.TRAILING && iconElement
|
|
18353
19076
|
]
|
|
18354
19077
|
}
|
|
@@ -18367,8 +19090,11 @@ var Button2 = (0, import_react16.forwardRef)(function Button3({
|
|
|
18367
19090
|
BlockContext,
|
|
18368
19091
|
BlockServices,
|
|
18369
19092
|
Button,
|
|
19093
|
+
ChartArtifact,
|
|
18370
19094
|
ChatContext,
|
|
18371
19095
|
ChatMessage,
|
|
19096
|
+
DEFAULT_CHART_ARTIFACT_LABELS,
|
|
19097
|
+
DEFAULT_TABLE_ARTIFACT_LABELS,
|
|
18372
19098
|
ICON_POSITION,
|
|
18373
19099
|
Icon,
|
|
18374
19100
|
IconButton,
|