@schandlergarcia/sf-web-components 1.0.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/.a4drules/skills/building-data-visualization/SKILL.md +72 -0
- package/.a4drules/skills/building-data-visualization/implementation/bar-line-chart.md +316 -0
- package/.a4drules/skills/building-data-visualization/implementation/dashboard-layout.md +189 -0
- package/.a4drules/skills/building-data-visualization/implementation/donut-chart.md +181 -0
- package/.a4drules/skills/building-data-visualization/implementation/stat-card.md +150 -0
- package/.a4drules/skills/building-react-components/SKILL.md +96 -0
- package/.a4drules/skills/building-react-components/implementation/component.md +78 -0
- package/.a4drules/skills/building-react-components/implementation/header-footer.md +132 -0
- package/.a4drules/skills/building-react-components/implementation/page.md +93 -0
- package/.a4drules/skills/configuring-csp-trusted-sites/SKILL.md +90 -0
- package/.a4drules/skills/configuring-csp-trusted-sites/implementation/metadata-format.md +281 -0
- package/.a4drules/skills/configuring-webapp-metadata/SKILL.md +158 -0
- package/.a4drules/skills/creating-webapp/SKILL.md +140 -0
- package/.a4drules/skills/deploying-to-salesforce/SKILL.md +226 -0
- package/.a4drules/skills/implementing-file-upload/SKILL.md +396 -0
- package/.a4drules/skills/installing-webapp-features/SKILL.md +210 -0
- package/.a4drules/skills/managing-agentforce-conversation-client/SKILL.md +186 -0
- package/.a4drules/skills/managing-agentforce-conversation-client/references/constraints.md +134 -0
- package/.a4drules/skills/managing-agentforce-conversation-client/references/examples.md +132 -0
- package/.a4drules/skills/managing-agentforce-conversation-client/references/style-tokens.md +101 -0
- package/.a4drules/skills/managing-agentforce-conversation-client/references/troubleshooting.md +57 -0
- package/.a4drules/skills/using-salesforce-data/SKILL.md +363 -0
- package/.a4drules/skills/using-salesforce-data/graphql-search.sh +139 -0
- package/.a4drules/webapp-data.md +353 -0
- package/.a4drules/webapp-ui.md +16 -0
- package/README.md +124 -0
- package/dist/components/library/cards/ActionList.js +27 -0
- package/dist/components/library/cards/ActionList.js.map +1 -0
- package/dist/components/library/cards/ActivityCard.js +40 -0
- package/dist/components/library/cards/ActivityCard.js.map +1 -0
- package/dist/components/library/cards/BaseCard.js +89 -0
- package/dist/components/library/cards/BaseCard.js.map +1 -0
- package/dist/components/library/cards/CalloutCard.js +28 -0
- package/dist/components/library/cards/CalloutCard.js.map +1 -0
- package/dist/components/library/cards/ChartCard.js +79 -0
- package/dist/components/library/cards/ChartCard.js.map +1 -0
- package/dist/components/library/cards/FeedPanel.js +38 -0
- package/dist/components/library/cards/FeedPanel.js.map +1 -0
- package/dist/components/library/cards/ListCard.js +112 -0
- package/dist/components/library/cards/ListCard.js.map +1 -0
- package/dist/components/library/cards/MetricCard.js +86 -0
- package/dist/components/library/cards/MetricCard.js.map +1 -0
- package/dist/components/library/cards/MetricsStrip.js +60 -0
- package/dist/components/library/cards/MetricsStrip.js.map +1 -0
- package/dist/components/library/cards/SectionCard.js +59 -0
- package/dist/components/library/cards/SectionCard.js.map +1 -0
- package/dist/components/library/cards/StatusCard.js +137 -0
- package/dist/components/library/cards/StatusCard.js.map +1 -0
- package/dist/components/library/cards/TableCard.js +244 -0
- package/dist/components/library/cards/TableCard.js.map +1 -0
- package/dist/components/library/cards/WidgetCard.js +60 -0
- package/dist/components/library/cards/WidgetCard.js.map +1 -0
- package/dist/components/library/charts/D3Chart.js +74 -0
- package/dist/components/library/charts/D3Chart.js.map +1 -0
- package/dist/components/library/charts/D3ChartTemplates.js +44 -0
- package/dist/components/library/charts/D3ChartTemplates.js.map +1 -0
- package/dist/components/library/charts/GeoMap.js +229 -0
- package/dist/components/library/charts/GeoMap.js.map +1 -0
- package/dist/components/library/chat/ChatBar.js +194 -0
- package/dist/components/library/chat/ChatBar.js.map +1 -0
- package/dist/components/library/chat/ChatInput.js +67 -0
- package/dist/components/library/chat/ChatInput.js.map +1 -0
- package/dist/components/library/chat/ChatMessage.js +112 -0
- package/dist/components/library/chat/ChatMessage.js.map +1 -0
- package/dist/components/library/chat/ChatMessageList.js +50 -0
- package/dist/components/library/chat/ChatMessageList.js.map +1 -0
- package/dist/components/library/chat/ChatPanel.js +77 -0
- package/dist/components/library/chat/ChatPanel.js.map +1 -0
- package/dist/components/library/chat/ChatSuggestions.js +22 -0
- package/dist/components/library/chat/ChatSuggestions.js.map +1 -0
- package/dist/components/library/chat/ChatToolCall.js +87 -0
- package/dist/components/library/chat/ChatToolCall.js.map +1 -0
- package/dist/components/library/chat/ChatTypingIndicator.js +20 -0
- package/dist/components/library/chat/ChatTypingIndicator.js.map +1 -0
- package/dist/components/library/chat/ChatWelcome.js +24 -0
- package/dist/components/library/chat/ChatWelcome.js.map +1 -0
- package/dist/components/library/chat/useChatState.js +77 -0
- package/dist/components/library/chat/useChatState.js.map +1 -0
- package/dist/components/library/data/DataModeProvider.js +47 -0
- package/dist/components/library/data/DataModeProvider.js.map +1 -0
- package/dist/components/library/data/DataModeToggle.js +28 -0
- package/dist/components/library/data/DataModeToggle.js.map +1 -0
- package/dist/components/library/data/filterUtils.js +71 -0
- package/dist/components/library/data/filterUtils.js.map +1 -0
- package/dist/components/library/data/useDataSource.js +13 -0
- package/dist/components/library/data/useDataSource.js.map +1 -0
- package/dist/components/library/data/usePageFilters.js +46 -0
- package/dist/components/library/data/usePageFilters.js.map +1 -0
- package/dist/components/library/filters/FilterBar.js +89 -0
- package/dist/components/library/filters/FilterBar.js.map +1 -0
- package/dist/components/library/filters/SearchFilter.js +44 -0
- package/dist/components/library/filters/SearchFilter.js.map +1 -0
- package/dist/components/library/filters/SelectFilter.js +44 -0
- package/dist/components/library/filters/SelectFilter.js.map +1 -0
- package/dist/components/library/filters/ToggleFilter.js +48 -0
- package/dist/components/library/filters/ToggleFilter.js.map +1 -0
- package/dist/components/library/forms/FormField.js +256 -0
- package/dist/components/library/forms/FormField.js.map +1 -0
- package/dist/components/library/forms/FormModal.js +161 -0
- package/dist/components/library/forms/FormModal.js.map +1 -0
- package/dist/components/library/forms/FormRenderer.js +32 -0
- package/dist/components/library/forms/FormRenderer.js.map +1 -0
- package/dist/components/library/forms/FormSection.js +49 -0
- package/dist/components/library/forms/FormSection.js.map +1 -0
- package/dist/components/library/forms/useFormState.js +85 -0
- package/dist/components/library/forms/useFormState.js.map +1 -0
- package/dist/components/library/heroui/Accordion.js +12 -0
- package/dist/components/library/heroui/Accordion.js.map +1 -0
- package/dist/components/library/heroui/Alert.js +12 -0
- package/dist/components/library/heroui/Alert.js.map +1 -0
- package/dist/components/library/heroui/Badge.js +12 -0
- package/dist/components/library/heroui/Badge.js.map +1 -0
- package/dist/components/library/heroui/Breadcrumbs.js +12 -0
- package/dist/components/library/heroui/Breadcrumbs.js.map +1 -0
- package/dist/components/library/heroui/Button.js +18 -0
- package/dist/components/library/heroui/Button.js.map +1 -0
- package/dist/components/library/heroui/Card.js +12 -0
- package/dist/components/library/heroui/Card.js.map +1 -0
- package/dist/components/library/heroui/Drawer.js +12 -0
- package/dist/components/library/heroui/Drawer.js.map +1 -0
- package/dist/components/library/heroui/Dropdown.js +12 -0
- package/dist/components/library/heroui/Dropdown.js.map +1 -0
- package/dist/components/library/heroui/Input.js +10 -0
- package/dist/components/library/heroui/Input.js.map +1 -0
- package/dist/components/library/heroui/Kbd.js +12 -0
- package/dist/components/library/heroui/Kbd.js.map +1 -0
- package/dist/components/library/heroui/Meter.js +12 -0
- package/dist/components/library/heroui/Meter.js.map +1 -0
- package/dist/components/library/heroui/Modal.js +12 -0
- package/dist/components/library/heroui/Modal.js.map +1 -0
- package/dist/components/library/heroui/Pagination.js +12 -0
- package/dist/components/library/heroui/Pagination.js.map +1 -0
- package/dist/components/library/heroui/ProgressBar.js +12 -0
- package/dist/components/library/heroui/ProgressBar.js.map +1 -0
- package/dist/components/library/heroui/ProgressCircle.js +12 -0
- package/dist/components/library/heroui/ProgressCircle.js.map +1 -0
- package/dist/components/library/heroui/ScrollShadow.js +12 -0
- package/dist/components/library/heroui/ScrollShadow.js.map +1 -0
- package/dist/components/library/heroui/Select.js +12 -0
- package/dist/components/library/heroui/Select.js.map +1 -0
- package/dist/components/library/heroui/Separator.js +12 -0
- package/dist/components/library/heroui/Separator.js.map +1 -0
- package/dist/components/library/heroui/Skeleton.js +12 -0
- package/dist/components/library/heroui/Skeleton.js.map +1 -0
- package/dist/components/library/heroui/Tabs.js +12 -0
- package/dist/components/library/heroui/Tabs.js.map +1 -0
- package/dist/components/library/heroui/Toast.js +13 -0
- package/dist/components/library/heroui/Toast.js.map +1 -0
- package/dist/components/library/heroui/Toggle.js +12 -0
- package/dist/components/library/heroui/Toggle.js.map +1 -0
- package/dist/components/library/heroui/Tooltip.js +12 -0
- package/dist/components/library/heroui/Tooltip.js.map +1 -0
- package/dist/components/library/layout/PageContainer.js +9 -0
- package/dist/components/library/layout/PageContainer.js.map +1 -0
- package/dist/components/library/skeletons/CardSkeleton.js +29 -0
- package/dist/components/library/skeletons/CardSkeleton.js.map +1 -0
- package/dist/components/library/theme/AppThemeProvider.js +55 -0
- package/dist/components/library/theme/AppThemeProvider.js.map +1 -0
- package/dist/components/library/theme/tokens.js +55 -0
- package/dist/components/library/theme/tokens.js.map +1 -0
- package/dist/components/library/ui/Avatar.js +33 -0
- package/dist/components/library/ui/Avatar.js.map +1 -0
- package/dist/components/library/ui/Button.js +50 -0
- package/dist/components/library/ui/Button.js.map +1 -0
- package/dist/components/library/ui/Card.js +21 -0
- package/dist/components/library/ui/Card.js.map +1 -0
- package/dist/components/library/ui/Chip.js +31 -0
- package/dist/components/library/ui/Chip.js.map +1 -0
- package/dist/components/library/ui/Container.js +42 -0
- package/dist/components/library/ui/Container.js.map +1 -0
- package/dist/components/library/ui/EmptyState.js +27 -0
- package/dist/components/library/ui/EmptyState.js.map +1 -0
- package/dist/components/library/ui/Input.js +22 -0
- package/dist/components/library/ui/Input.js.map +1 -0
- package/dist/components/library/ui/Spinner.js +64 -0
- package/dist/components/library/ui/Spinner.js.map +1 -0
- package/dist/components/library/ui/Text.js +43 -0
- package/dist/components/library/ui/Text.js.map +1 -0
- package/dist/components/library/ui/Toggle.js +47 -0
- package/dist/components/library/ui/Toggle.js.map +1 -0
- package/dist/components/workspace/ComponentRegistry.js +231 -0
- package/dist/components/workspace/ComponentRegistry.js.map +1 -0
- package/dist/index.js +185 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/utils.js +9 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/node_modules/clsx/dist/clsx.js +17 -0
- package/dist/node_modules/clsx/dist/clsx.js.map +1 -0
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +2925 -0
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -0
- package/package.json +81 -0
- package/scripts/get-graphql-schema.mjs +68 -0
- package/scripts/reset-command-center.sh +358 -0
- package/scripts/rewrite-e2e-assets.mjs +23 -0
- package/scripts/validate-dashboard.sh +290 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { jsx as e, jsxs as l } from "react/jsx-runtime";
|
|
2
|
+
import "react";
|
|
3
|
+
import w from "./BaseCard.js";
|
|
4
|
+
import y from "../ui/Text.js";
|
|
5
|
+
const g = {
|
|
6
|
+
operational: {
|
|
7
|
+
label: "Operational",
|
|
8
|
+
dot: "bg-emerald-500",
|
|
9
|
+
chip: "bg-emerald-100 text-emerald-900 dark:bg-emerald-950/30 dark:text-emerald-200"
|
|
10
|
+
},
|
|
11
|
+
degraded: {
|
|
12
|
+
label: "Degraded",
|
|
13
|
+
dot: "bg-amber-500",
|
|
14
|
+
chip: "bg-amber-100 text-amber-900 dark:bg-amber-950/30 dark:text-amber-200"
|
|
15
|
+
},
|
|
16
|
+
outage: {
|
|
17
|
+
label: "Outage",
|
|
18
|
+
dot: "bg-rose-500",
|
|
19
|
+
chip: "bg-rose-100 text-rose-900 dark:bg-rose-950/30 dark:text-rose-200"
|
|
20
|
+
},
|
|
21
|
+
maintenance: {
|
|
22
|
+
label: "Maintenance",
|
|
23
|
+
dot: "bg-slate-500",
|
|
24
|
+
chip: "bg-slate-100 text-slate-900 dark:bg-slate-800 dark:text-slate-100"
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
function h(t) {
|
|
28
|
+
const a = String(t ?? "operational").toLowerCase();
|
|
29
|
+
return a === "ok" || a === "healthy" || a === "up" ? "operational" : a === "warn" || a === "warning" || a === "partial" ? "degraded" : a === "down" || a === "critical" ? "outage" : g[a] ? a : "operational";
|
|
30
|
+
}
|
|
31
|
+
function I(t) {
|
|
32
|
+
if (!t) return "";
|
|
33
|
+
try {
|
|
34
|
+
const a = t instanceof Date ? t : new Date(t);
|
|
35
|
+
return Number.isNaN(a.getTime()) ? String(t) : a.toLocaleString(void 0, { dateStyle: "medium", timeStyle: "short" });
|
|
36
|
+
} catch {
|
|
37
|
+
return String(t);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function S({ status: t }) {
|
|
41
|
+
const a = h(t), r = g[a];
|
|
42
|
+
return /* @__PURE__ */ l("span", { className: ["inline-flex items-center gap-2 rounded-full px-2.5 py-1 text-xs font-semibold", r.chip].join(" "), children: [
|
|
43
|
+
/* @__PURE__ */ e("span", { className: ["h-2 w-2 rounded-full", r.dot].join(" "), "aria-hidden": "true" }),
|
|
44
|
+
r.label
|
|
45
|
+
] });
|
|
46
|
+
}
|
|
47
|
+
function b({ item: t, showTimestamp: a }) {
|
|
48
|
+
const r = t?.title ?? t?.name ?? "Item", s = t?.description, i = t?.value, o = t?.unit, d = t?.timestamp, c = t?.status;
|
|
49
|
+
return /* @__PURE__ */ l("div", { className: "flex items-start justify-between gap-3 rounded-xl border border-slate-200 bg-white p-3 dark:border-slate-800 dark:bg-slate-900", children: [
|
|
50
|
+
/* @__PURE__ */ l("div", { className: "min-w-0", children: [
|
|
51
|
+
/* @__PURE__ */ l("div", { className: "flex items-center gap-2", children: [
|
|
52
|
+
/* @__PURE__ */ e("div", { className: "truncate text-sm font-semibold text-slate-900 dark:text-slate-50", children: r }),
|
|
53
|
+
c ? /* @__PURE__ */ e(S, { status: c }) : null
|
|
54
|
+
] }),
|
|
55
|
+
s ? /* @__PURE__ */ e("div", { className: "mt-1 text-sm text-slate-600 dark:text-slate-300", children: s }) : null,
|
|
56
|
+
a && d ? /* @__PURE__ */ e("div", { className: "mt-1 text-xs text-slate-500 dark:text-slate-400", children: I(d) }) : null
|
|
57
|
+
] }),
|
|
58
|
+
i != null ? /* @__PURE__ */ e("div", { className: "shrink-0 text-right", children: /* @__PURE__ */ l("div", { className: "text-sm font-semibold text-slate-900 dark:text-slate-50", children: [
|
|
59
|
+
String(i),
|
|
60
|
+
o ? /* @__PURE__ */ e("span", { className: "ml-1 text-xs font-medium text-slate-500 dark:text-slate-400", children: o }) : null
|
|
61
|
+
] }) }) : null
|
|
62
|
+
] });
|
|
63
|
+
}
|
|
64
|
+
function M({ items: t, showTimestamp: a }) {
|
|
65
|
+
return /* @__PURE__ */ l("div", { className: "relative mt-4", children: [
|
|
66
|
+
/* @__PURE__ */ e("div", { className: "absolute left-3 top-0 h-full w-px bg-slate-200 dark:bg-slate-800", "aria-hidden": "true" }),
|
|
67
|
+
/* @__PURE__ */ e("div", { className: "space-y-3", children: t.map((r, s) => {
|
|
68
|
+
const i = r?.id ?? s, o = r?.status, d = g[h(o)];
|
|
69
|
+
return /* @__PURE__ */ l("div", { className: "relative pl-8", children: [
|
|
70
|
+
/* @__PURE__ */ e("div", { className: ["absolute left-[9px] top-3 h-2.5 w-2.5 rounded-full", d.dot].join(" "), "aria-hidden": "true" }),
|
|
71
|
+
/* @__PURE__ */ e(b, { item: r, showTimestamp: a })
|
|
72
|
+
] }, i);
|
|
73
|
+
}) })
|
|
74
|
+
] });
|
|
75
|
+
}
|
|
76
|
+
function E({
|
|
77
|
+
title: t,
|
|
78
|
+
subtitle: a,
|
|
79
|
+
status: r = "operational",
|
|
80
|
+
items: s = [],
|
|
81
|
+
layout: i = "list",
|
|
82
|
+
showProgress: o = !1,
|
|
83
|
+
showTimestamp: d = !0,
|
|
84
|
+
actions: c,
|
|
85
|
+
loading: j = !1,
|
|
86
|
+
error: x,
|
|
87
|
+
emptyMessage: C = "No status items.",
|
|
88
|
+
maxBodyHeight: p,
|
|
89
|
+
...f
|
|
90
|
+
}) {
|
|
91
|
+
const T = h(r), v = /* @__PURE__ */ l("div", { className: "flex items-start justify-between gap-3", children: [
|
|
92
|
+
/* @__PURE__ */ l("div", { className: "min-w-0", children: [
|
|
93
|
+
t ? /* @__PURE__ */ e(y, { as: "div", size: "sm", weight: "medium", children: t }) : null,
|
|
94
|
+
a ? /* @__PURE__ */ e(y, { as: "div", size: "xs", muted: !0, className: "mt-1", children: a }) : null
|
|
95
|
+
] }),
|
|
96
|
+
/* @__PURE__ */ l("div", { className: "flex items-center gap-2", children: [
|
|
97
|
+
/* @__PURE__ */ e(S, { status: T }),
|
|
98
|
+
c ? /* @__PURE__ */ e("div", { className: "ml-1", children: c }) : null
|
|
99
|
+
] })
|
|
100
|
+
] });
|
|
101
|
+
if (x)
|
|
102
|
+
return /* @__PURE__ */ e(
|
|
103
|
+
w,
|
|
104
|
+
{
|
|
105
|
+
variant: "status",
|
|
106
|
+
header: v,
|
|
107
|
+
body: /* @__PURE__ */ e("div", { className: "mt-4 rounded-xl border border-rose-200 bg-rose-50 p-4 text-sm text-rose-900 dark:border-rose-900/40 dark:bg-rose-950/30 dark:text-rose-100", children: String(x) }),
|
|
108
|
+
...f
|
|
109
|
+
}
|
|
110
|
+
);
|
|
111
|
+
const u = s.length, N = s.filter((n) => h(n?.status) === "operational").length, k = u > 0 ? Math.round(N / u * 100) : 100, z = p ? { maxHeight: p, overflowY: "auto" } : {}, A = j ? /* @__PURE__ */ e("div", { className: "space-y-3", children: Array.from({ length: 3 }).map((n, m) => /* @__PURE__ */ l("div", { className: "flex items-center gap-3 rounded-xl border border-slate-200 bg-white p-3 dark:border-slate-800 dark:bg-slate-900", children: [
|
|
112
|
+
/* @__PURE__ */ e("div", { className: "h-4 w-1/4 animate-pulse rounded bg-slate-200 dark:bg-slate-800" }),
|
|
113
|
+
/* @__PURE__ */ e("div", { className: "h-4 w-1/3 animate-pulse rounded bg-slate-200 dark:bg-slate-800" })
|
|
114
|
+
] }, m)) }) : s.length === 0 ? /* @__PURE__ */ e("div", { className: "rounded-xl border border-dashed border-slate-300 bg-slate-50 p-6 text-center text-sm text-slate-600 dark:border-slate-700 dark:bg-slate-950/30 dark:text-slate-300", children: C }) : i === "grid" ? /* @__PURE__ */ e("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2", children: s.map((n, m) => /* @__PURE__ */ e(b, { item: n, showTimestamp: d }, n?.id ?? m)) }) : i === "timeline" ? /* @__PURE__ */ e(M, { items: s, showTimestamp: d }) : /* @__PURE__ */ e("div", { className: "space-y-3", children: s.map((n, m) => /* @__PURE__ */ e(b, { item: n, showTimestamp: d }, n?.id ?? m)) }), D = /* @__PURE__ */ l("div", { className: "mt-4", children: [
|
|
115
|
+
o && u > 0 ? /* @__PURE__ */ l("div", { className: "mb-4", children: [
|
|
116
|
+
/* @__PURE__ */ l("div", { className: "flex items-center justify-between text-xs text-slate-600 dark:text-slate-300", children: [
|
|
117
|
+
/* @__PURE__ */ l("span", { children: [
|
|
118
|
+
N,
|
|
119
|
+
" / ",
|
|
120
|
+
u,
|
|
121
|
+
" operational"
|
|
122
|
+
] }),
|
|
123
|
+
/* @__PURE__ */ l("span", { children: [
|
|
124
|
+
k,
|
|
125
|
+
"%"
|
|
126
|
+
] })
|
|
127
|
+
] }),
|
|
128
|
+
/* @__PURE__ */ e("div", { className: "mt-2 h-2 w-full overflow-hidden rounded-full bg-slate-200 dark:bg-slate-800", children: /* @__PURE__ */ e("div", { className: "h-full bg-emerald-500", style: { width: `${k}%` } }) })
|
|
129
|
+
] }) : null,
|
|
130
|
+
/* @__PURE__ */ e("div", { style: z, children: A })
|
|
131
|
+
] });
|
|
132
|
+
return /* @__PURE__ */ e(w, { variant: "status", header: v, body: D, ...f });
|
|
133
|
+
}
|
|
134
|
+
export {
|
|
135
|
+
E as default
|
|
136
|
+
};
|
|
137
|
+
//# sourceMappingURL=StatusCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatusCard.js","sources":["../../../../src/components/library/cards/StatusCard.jsx"],"sourcesContent":["import React from \"react\";\nimport BaseCard from \"./BaseCard\";\nimport UIText from \"../ui/Text\";\n\nconst STATUS_META = {\n operational: {\n label: \"Operational\",\n dot: \"bg-emerald-500\",\n chip: \"bg-emerald-100 text-emerald-900 dark:bg-emerald-950/30 dark:text-emerald-200\"\n },\n degraded: {\n label: \"Degraded\",\n dot: \"bg-amber-500\",\n chip: \"bg-amber-100 text-amber-900 dark:bg-amber-950/30 dark:text-amber-200\"\n },\n outage: {\n label: \"Outage\",\n dot: \"bg-rose-500\",\n chip: \"bg-rose-100 text-rose-900 dark:bg-rose-950/30 dark:text-rose-200\"\n },\n maintenance: {\n label: \"Maintenance\",\n dot: \"bg-slate-500\",\n chip: \"bg-slate-100 text-slate-900 dark:bg-slate-800 dark:text-slate-100\"\n }\n};\n\nfunction normalizeStatus(status) {\n const s = String(status ?? \"operational\").toLowerCase();\n if (s === \"ok\" || s === \"healthy\" || s === \"up\") return \"operational\";\n if (s === \"warn\" || s === \"warning\" || s === \"partial\") return \"degraded\";\n if (s === \"down\" || s === \"critical\") return \"outage\";\n return STATUS_META[s] ? s : \"operational\";\n}\n\nfunction formatTimestamp(ts) {\n if (!ts) return \"\";\n try {\n const d = ts instanceof Date ? ts : new Date(ts);\n if (Number.isNaN(d.getTime())) return String(ts);\n return d.toLocaleString(undefined, { dateStyle: \"medium\", timeStyle: \"short\" });\n } catch {\n return String(ts);\n }\n}\n\nfunction StatusChip({ status }) {\n const key = normalizeStatus(status);\n const meta = STATUS_META[key];\n return (\n <span className={[\"inline-flex items-center gap-2 rounded-full px-2.5 py-1 text-xs font-semibold\", meta.chip].join(\" \")}>\n <span className={[\"h-2 w-2 rounded-full\", meta.dot].join(\" \")} aria-hidden=\"true\" />\n {meta.label}\n </span>\n );\n}\n\nfunction ItemRow({ item, showTimestamp }) {\n const name = item?.title ?? item?.name ?? \"Item\";\n const desc = item?.description;\n const value = item?.value;\n const unit = item?.unit;\n const ts = item?.timestamp;\n const status = item?.status;\n\n return (\n <div className=\"flex items-start justify-between gap-3 rounded-xl border border-slate-200 bg-white p-3 dark:border-slate-800 dark:bg-slate-900\">\n <div className=\"min-w-0\">\n <div className=\"flex items-center gap-2\">\n <div className=\"truncate text-sm font-semibold text-slate-900 dark:text-slate-50\">{name}</div>\n {status ? <StatusChip status={status} /> : null}\n </div>\n {desc ? (\n <div className=\"mt-1 text-sm text-slate-600 dark:text-slate-300\">{desc}</div>\n ) : null}\n {showTimestamp && ts ? (\n <div className=\"mt-1 text-xs text-slate-500 dark:text-slate-400\">{formatTimestamp(ts)}</div>\n ) : null}\n </div>\n {value != null ? (\n <div className=\"shrink-0 text-right\">\n <div className=\"text-sm font-semibold text-slate-900 dark:text-slate-50\">\n {String(value)}\n {unit ? <span className=\"ml-1 text-xs font-medium text-slate-500 dark:text-slate-400\">{unit}</span> : null}\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction Timeline({ items, showTimestamp }) {\n return (\n <div className=\"relative mt-4\">\n <div className=\"absolute left-3 top-0 h-full w-px bg-slate-200 dark:bg-slate-800\" aria-hidden=\"true\" />\n <div className=\"space-y-3\">\n {items.map((item, idx) => {\n const key = item?.id ?? idx;\n const status = item?.status;\n const meta = STATUS_META[normalizeStatus(status)];\n return (\n <div key={key} className=\"relative pl-8\">\n <div className={[\"absolute left-[9px] top-3 h-2.5 w-2.5 rounded-full\", meta.dot].join(\" \")} aria-hidden=\"true\" />\n <ItemRow item={item} showTimestamp={showTimestamp} />\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\nexport default function StatusCard({\n title,\n subtitle,\n status = \"operational\",\n items = [],\n layout = \"list\",\n showProgress = false,\n showTimestamp = true,\n actions,\n loading = false,\n error,\n emptyMessage = \"No status items.\",\n maxBodyHeight,\n ...cardProps\n}) {\n const overall = normalizeStatus(status);\n const header = (\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n {title ? (\n <UIText as=\"div\" size=\"sm\" weight=\"medium\">\n {title}\n </UIText>\n ) : null}\n {subtitle ? (\n <UIText as=\"div\" size=\"xs\" muted className=\"mt-1\">\n {subtitle}\n </UIText>\n ) : null}\n </div>\n <div className=\"flex items-center gap-2\">\n <StatusChip status={overall} />\n {actions ? <div className=\"ml-1\">{actions}</div> : null}\n </div>\n </div>\n );\n\n if (error) {\n return (\n <BaseCard\n variant=\"status\"\n header={header}\n body={\n <div className=\"mt-4 rounded-xl border border-rose-200 bg-rose-50 p-4 text-sm text-rose-900 dark:border-rose-900/40 dark:bg-rose-950/30 dark:text-rose-100\">\n {String(error)}\n </div>\n }\n {...cardProps}\n />\n );\n }\n\n const total = items.length;\n const okCount = items.filter((it) => normalizeStatus(it?.status) === \"operational\").length;\n const percentOk = total > 0 ? Math.round((okCount / total) * 100) : 100;\n\n const scrollStyle = maxBodyHeight ? { maxHeight: maxBodyHeight, overflowY: \"auto\" } : {};\n\n const itemsContent = loading ? (\n <div className=\"space-y-3\">\n {Array.from({ length: 3 }).map((_, i) => (\n <div key={i} className=\"flex items-center gap-3 rounded-xl border border-slate-200 bg-white p-3 dark:border-slate-800 dark:bg-slate-900\">\n <div className=\"h-4 w-1/4 animate-pulse rounded bg-slate-200 dark:bg-slate-800\" />\n <div className=\"h-4 w-1/3 animate-pulse rounded bg-slate-200 dark:bg-slate-800\" />\n </div>\n ))}\n </div>\n ) : items.length === 0 ? (\n <div className=\"rounded-xl border border-dashed border-slate-300 bg-slate-50 p-6 text-center text-sm text-slate-600 dark:border-slate-700 dark:bg-slate-950/30 dark:text-slate-300\">\n {emptyMessage}\n </div>\n ) : layout === \"grid\" ? (\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n {items.map((it, idx) => (\n <ItemRow key={it?.id ?? idx} item={it} showTimestamp={showTimestamp} />\n ))}\n </div>\n ) : layout === \"timeline\" ? (\n <Timeline items={items} showTimestamp={showTimestamp} />\n ) : (\n <div className=\"space-y-3\">\n {items.map((it, idx) => (\n <ItemRow key={it?.id ?? idx} item={it} showTimestamp={showTimestamp} />\n ))}\n </div>\n );\n\n const body = (\n <div className=\"mt-4\">\n {showProgress && total > 0 ? (\n <div className=\"mb-4\">\n <div className=\"flex items-center justify-between text-xs text-slate-600 dark:text-slate-300\">\n <span>{okCount} / {total} operational</span>\n <span>{percentOk}%</span>\n </div>\n <div className=\"mt-2 h-2 w-full overflow-hidden rounded-full bg-slate-200 dark:bg-slate-800\">\n <div className=\"h-full bg-emerald-500\" style={{ width: `${percentOk}%` }} />\n </div>\n </div>\n ) : null}\n <div style={scrollStyle}>{itemsContent}</div>\n </div>\n );\n\n return <BaseCard variant=\"status\" header={header} body={body} {...cardProps} />;\n}\n\n\n"],"names":["STATUS_META","normalizeStatus","status","s","formatTimestamp","ts","d","StatusChip","key","meta","jsxs","jsx","ItemRow","item","showTimestamp","name","desc","value","unit","Timeline","items","idx","StatusCard","title","subtitle","layout","showProgress","actions","loading","error","emptyMessage","maxBodyHeight","cardProps","overall","header","UIText","BaseCard","total","okCount","it","percentOk","scrollStyle","itemsContent","_","i","body"],"mappings":"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"}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { jsx as t, jsxs as d } from "react/jsx-runtime";
|
|
2
|
+
import i from "react";
|
|
3
|
+
import I from "./BaseCard.js";
|
|
4
|
+
import te from "../ui/Input.js";
|
|
5
|
+
import K from "../ui/Button.js";
|
|
6
|
+
import Q from "../ui/Text.js";
|
|
7
|
+
function re(o, s) {
|
|
8
|
+
if (s == null) return "";
|
|
9
|
+
if (!o) return String(s);
|
|
10
|
+
if (o === "currency") {
|
|
11
|
+
const r = Number(s);
|
|
12
|
+
if (Number.isFinite(r)) return r.toLocaleString(void 0, { style: "currency", currency: "USD" });
|
|
13
|
+
}
|
|
14
|
+
if (o === "percentage") {
|
|
15
|
+
const r = Number(s);
|
|
16
|
+
if (Number.isFinite(r)) return `${r}%`;
|
|
17
|
+
}
|
|
18
|
+
if (o === "number") {
|
|
19
|
+
const r = Number(s);
|
|
20
|
+
if (Number.isFinite(r)) return r.toLocaleString();
|
|
21
|
+
}
|
|
22
|
+
return String(s);
|
|
23
|
+
}
|
|
24
|
+
function se(o, s) {
|
|
25
|
+
return o.map((r, u) => ({ item: r, idx: u })).sort((r, u) => {
|
|
26
|
+
const b = s(r.item, u.item);
|
|
27
|
+
return b !== 0 ? b : r.idx - u.idx;
|
|
28
|
+
}).map((r) => r.item);
|
|
29
|
+
}
|
|
30
|
+
function ce({
|
|
31
|
+
data: o = [],
|
|
32
|
+
columns: s = [],
|
|
33
|
+
title: r,
|
|
34
|
+
subtitle: u,
|
|
35
|
+
searchable: b = !1,
|
|
36
|
+
sortable: j = !1,
|
|
37
|
+
paginated: g = !1,
|
|
38
|
+
selectable: M = !1,
|
|
39
|
+
pageSize: f = 10,
|
|
40
|
+
actions: F,
|
|
41
|
+
rowActions: h,
|
|
42
|
+
onRowSelect: R,
|
|
43
|
+
onSort: _,
|
|
44
|
+
onSearch: G,
|
|
45
|
+
loading: H = !1,
|
|
46
|
+
error: P,
|
|
47
|
+
emptyMessage: J = "No results.",
|
|
48
|
+
simulateInitialLoad: B = !1,
|
|
49
|
+
minInitialDelayMs: L = 350,
|
|
50
|
+
maxInitialDelayMs: U = 900,
|
|
51
|
+
...$
|
|
52
|
+
}) {
|
|
53
|
+
const [N, O] = i.useState(""), [x, V] = i.useState(null), [k, W] = i.useState("asc"), [T, y] = i.useState(1), [X, Y] = i.useState(null), [Z, z] = i.useState(B);
|
|
54
|
+
i.useEffect(() => {
|
|
55
|
+
if (!B) return;
|
|
56
|
+
const e = Math.floor(Math.random() * (U - L + 1)) + L, a = setTimeout(() => z(!1), e);
|
|
57
|
+
return () => clearTimeout(a);
|
|
58
|
+
}, [B, L, U]);
|
|
59
|
+
const q = H || Z, v = i.useMemo(() => {
|
|
60
|
+
if (!b || !N.trim()) return o;
|
|
61
|
+
const e = N.trim().toLowerCase();
|
|
62
|
+
return o.filter(
|
|
63
|
+
(a) => s.some((n) => {
|
|
64
|
+
const p = a?.[n.key];
|
|
65
|
+
return p == null ? !1 : String(p).toLowerCase().includes(e);
|
|
66
|
+
})
|
|
67
|
+
);
|
|
68
|
+
}, [o, s, N, b]), S = i.useMemo(() => {
|
|
69
|
+
if (!j || !x || !s.find((n) => n.key === x)) return v;
|
|
70
|
+
const a = k === "desc" ? -1 : 1;
|
|
71
|
+
return se(v, (n, p) => {
|
|
72
|
+
const l = n?.[x], m = p?.[x];
|
|
73
|
+
return l == null && m == null ? 0 : l == null ? -1 * a : m == null ? 1 * a : typeof l == "number" && typeof m == "number" ? (l - m) * a : String(l).localeCompare(String(m)) * a;
|
|
74
|
+
});
|
|
75
|
+
}, [v, j, x, k, s]), w = S.length, C = g ? Math.max(1, Math.ceil(w / f)) : 1, c = Math.min(T, C), D = i.useMemo(() => {
|
|
76
|
+
if (!g) return S;
|
|
77
|
+
const e = (c - 1) * f;
|
|
78
|
+
return S.slice(e, e + f);
|
|
79
|
+
}, [S, g, c, f]);
|
|
80
|
+
i.useEffect(() => {
|
|
81
|
+
T !== c && y(c);
|
|
82
|
+
}, [T, c]);
|
|
83
|
+
const E = /* @__PURE__ */ d("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between", children: [
|
|
84
|
+
/* @__PURE__ */ d("div", { className: "min-w-0", children: [
|
|
85
|
+
r ? /* @__PURE__ */ t(Q, { as: "div", size: "sm", weight: "medium", children: r }) : null,
|
|
86
|
+
u ? /* @__PURE__ */ t(Q, { as: "div", size: "xs", muted: !0, className: "mt-1", children: u }) : null
|
|
87
|
+
] }),
|
|
88
|
+
/* @__PURE__ */ d("div", { className: "flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-end", children: [
|
|
89
|
+
b ? /* @__PURE__ */ t("div", { className: "w-full sm:w-64", children: /* @__PURE__ */ t(
|
|
90
|
+
te,
|
|
91
|
+
{
|
|
92
|
+
value: N,
|
|
93
|
+
onChange: (e) => {
|
|
94
|
+
O(e.target.value), y(1), G?.(e.target.value);
|
|
95
|
+
},
|
|
96
|
+
placeholder: "Search…",
|
|
97
|
+
"aria-label": "Search table"
|
|
98
|
+
}
|
|
99
|
+
) }) : null,
|
|
100
|
+
F ? /* @__PURE__ */ t("div", { className: "flex items-center gap-2", children: F }) : null
|
|
101
|
+
] })
|
|
102
|
+
] });
|
|
103
|
+
if (P)
|
|
104
|
+
return /* @__PURE__ */ t(
|
|
105
|
+
I,
|
|
106
|
+
{
|
|
107
|
+
header: E,
|
|
108
|
+
body: /* @__PURE__ */ t("div", { className: "mt-4 rounded-xl border border-rose-200 bg-rose-50 p-4 text-sm text-rose-900 dark:border-rose-900/40 dark:bg-rose-950/30 dark:text-rose-100", children: String(P) }),
|
|
109
|
+
...$
|
|
110
|
+
}
|
|
111
|
+
);
|
|
112
|
+
const A = (e) => j && (e.sortable ?? !0);
|
|
113
|
+
return /* @__PURE__ */ t(
|
|
114
|
+
I,
|
|
115
|
+
{
|
|
116
|
+
variant: "table",
|
|
117
|
+
header: E,
|
|
118
|
+
body: /* @__PURE__ */ d("div", { className: "mt-4 overflow-hidden rounded-xl border border-slate-200 dark:border-slate-800", children: [
|
|
119
|
+
/* @__PURE__ */ t("div", { className: "w-full overflow-x-auto", children: /* @__PURE__ */ d("table", { className: "min-w-full border-separate border-spacing-0", children: [
|
|
120
|
+
/* @__PURE__ */ t("thead", { className: "bg-slate-50 dark:bg-slate-950/30", children: /* @__PURE__ */ d("tr", { children: [
|
|
121
|
+
s.map((e) => {
|
|
122
|
+
const a = x === e.key;
|
|
123
|
+
return /* @__PURE__ */ t(
|
|
124
|
+
"th",
|
|
125
|
+
{
|
|
126
|
+
scope: "col",
|
|
127
|
+
className: [
|
|
128
|
+
"whitespace-nowrap border-b border-slate-200 px-4 py-3 text-left text-xs font-semibold text-slate-600 dark:border-slate-800 dark:text-slate-300",
|
|
129
|
+
e.className ?? ""
|
|
130
|
+
].filter(Boolean).join(" "),
|
|
131
|
+
children: A(e) ? /* @__PURE__ */ d(
|
|
132
|
+
"button",
|
|
133
|
+
{
|
|
134
|
+
type: "button",
|
|
135
|
+
className: "inline-flex items-center gap-2 hover:text-slate-900 dark:hover:text-slate-50",
|
|
136
|
+
onClick: () => {
|
|
137
|
+
const n = a && k === "asc" ? "desc" : "asc";
|
|
138
|
+
V(e.key), W(n), _?.({ key: e.key, direction: n });
|
|
139
|
+
},
|
|
140
|
+
children: [
|
|
141
|
+
/* @__PURE__ */ t("span", { children: e.label }),
|
|
142
|
+
/* @__PURE__ */ t("span", { className: "text-[10px] opacity-70", children: a ? k === "asc" ? "▲" : "▼" : "↕" })
|
|
143
|
+
]
|
|
144
|
+
}
|
|
145
|
+
) : e.label
|
|
146
|
+
},
|
|
147
|
+
e.key
|
|
148
|
+
);
|
|
149
|
+
}),
|
|
150
|
+
h ? /* @__PURE__ */ t("th", { className: "border-b border-slate-200 px-4 py-3 text-right text-xs font-semibold text-slate-600 dark:border-slate-800 dark:text-slate-300", children: "Actions" }) : null
|
|
151
|
+
] }) }),
|
|
152
|
+
/* @__PURE__ */ t("tbody", { className: "bg-white dark:bg-slate-900", children: q ? Array.from({ length: Math.min(f, 6) }).map((e, a) => /* @__PURE__ */ d("tr", { children: [
|
|
153
|
+
s.map((n) => /* @__PURE__ */ t(
|
|
154
|
+
"td",
|
|
155
|
+
{
|
|
156
|
+
className: "border-b border-slate-200 px-4 py-3 dark:border-slate-800",
|
|
157
|
+
children: /* @__PURE__ */ t("div", { className: "h-4 w-3/4 animate-pulse rounded bg-slate-200 dark:bg-slate-800" })
|
|
158
|
+
},
|
|
159
|
+
n.key
|
|
160
|
+
)),
|
|
161
|
+
h ? /* @__PURE__ */ t("td", { className: "border-b border-slate-200 px-4 py-3 dark:border-slate-800", children: /* @__PURE__ */ t("div", { className: "h-4 w-10 animate-pulse rounded bg-slate-200 dark:bg-slate-800" }) }) : null
|
|
162
|
+
] }, a)) : D.length === 0 ? /* @__PURE__ */ t("tr", { children: /* @__PURE__ */ t(
|
|
163
|
+
"td",
|
|
164
|
+
{
|
|
165
|
+
colSpan: s.length + (h ? 1 : 0),
|
|
166
|
+
className: "px-4 py-10 text-center text-sm text-slate-600 dark:text-slate-300",
|
|
167
|
+
children: J
|
|
168
|
+
}
|
|
169
|
+
) }) : D.map((e, a) => {
|
|
170
|
+
const n = e?.id ?? a;
|
|
171
|
+
return /* @__PURE__ */ d(
|
|
172
|
+
"tr",
|
|
173
|
+
{
|
|
174
|
+
className: [
|
|
175
|
+
"group",
|
|
176
|
+
M ? "cursor-pointer" : "",
|
|
177
|
+
M && X === n ? "bg-brand-50 dark:bg-brand-950/30" : ""
|
|
178
|
+
].filter(Boolean).join(" "),
|
|
179
|
+
onClick: () => {
|
|
180
|
+
M && (Y(n), R?.(e));
|
|
181
|
+
},
|
|
182
|
+
children: [
|
|
183
|
+
s.map((l) => {
|
|
184
|
+
const m = e?.[l.key], ee = l.render ? l.render(m, e) : re(l.type, m);
|
|
185
|
+
return /* @__PURE__ */ t(
|
|
186
|
+
"td",
|
|
187
|
+
{
|
|
188
|
+
className: [
|
|
189
|
+
"border-b border-slate-200 px-4 py-3 text-sm text-slate-700 dark:border-slate-800 dark:text-slate-200",
|
|
190
|
+
l.mono ? "font-mono text-[13px]" : "",
|
|
191
|
+
l.className ?? ""
|
|
192
|
+
].filter(Boolean).join(" "),
|
|
193
|
+
children: ee
|
|
194
|
+
},
|
|
195
|
+
l.key
|
|
196
|
+
);
|
|
197
|
+
}),
|
|
198
|
+
h ? /* @__PURE__ */ t("td", { className: "border-b border-slate-200 px-4 py-3 text-right text-sm dark:border-slate-800", children: /* @__PURE__ */ t("div", { className: "inline-flex items-center justify-end gap-2 opacity-100 sm:opacity-0 sm:group-hover:opacity-100", children: h(e) }) }) : null
|
|
199
|
+
]
|
|
200
|
+
},
|
|
201
|
+
n
|
|
202
|
+
);
|
|
203
|
+
}) })
|
|
204
|
+
] }) }),
|
|
205
|
+
g && !q ? /* @__PURE__ */ d("div", { className: "flex flex-col gap-2 border-t border-slate-200 bg-slate-50 px-4 py-3 dark:border-slate-800 dark:bg-slate-950/30 sm:flex-row sm:items-center sm:justify-between", children: [
|
|
206
|
+
/* @__PURE__ */ t("div", { className: "text-xs text-slate-600 dark:text-slate-300", children: w === 0 ? "0 results" : `Showing ${(c - 1) * f + 1}-${Math.min(c * f, w)} of ${w}` }),
|
|
207
|
+
/* @__PURE__ */ d("div", { className: "flex items-center gap-2", children: [
|
|
208
|
+
/* @__PURE__ */ t(
|
|
209
|
+
K,
|
|
210
|
+
{
|
|
211
|
+
variant: "outline",
|
|
212
|
+
size: "sm",
|
|
213
|
+
disabled: c <= 1,
|
|
214
|
+
onClick: () => y((e) => Math.max(1, e - 1)),
|
|
215
|
+
children: "Prev"
|
|
216
|
+
}
|
|
217
|
+
),
|
|
218
|
+
/* @__PURE__ */ d("div", { className: "text-xs text-slate-600 dark:text-slate-300", children: [
|
|
219
|
+
"Page ",
|
|
220
|
+
c,
|
|
221
|
+
" / ",
|
|
222
|
+
C
|
|
223
|
+
] }),
|
|
224
|
+
/* @__PURE__ */ t(
|
|
225
|
+
K,
|
|
226
|
+
{
|
|
227
|
+
variant: "outline",
|
|
228
|
+
size: "sm",
|
|
229
|
+
disabled: c >= C,
|
|
230
|
+
onClick: () => y((e) => Math.min(C, e + 1)),
|
|
231
|
+
children: "Next"
|
|
232
|
+
}
|
|
233
|
+
)
|
|
234
|
+
] })
|
|
235
|
+
] }) : null
|
|
236
|
+
] }),
|
|
237
|
+
...$
|
|
238
|
+
}
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
export {
|
|
242
|
+
ce as default
|
|
243
|
+
};
|
|
244
|
+
//# sourceMappingURL=TableCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TableCard.js","sources":["../../../../src/components/library/cards/TableCard.jsx"],"sourcesContent":["import React from \"react\";\nimport BaseCard from \"./BaseCard\";\nimport UIInput from \"../ui/Input\";\nimport UIButton from \"../ui/Button\";\nimport UIText from \"../ui/Text\";\n\nfunction defaultTypeFormat(type, value) {\n if (value == null) return \"\";\n if (!type) return String(value);\n\n if (type === \"currency\") {\n const n = Number(value);\n if (Number.isFinite(n)) return n.toLocaleString(undefined, { style: \"currency\", currency: \"USD\" });\n }\n if (type === \"percentage\") {\n const n = Number(value);\n if (Number.isFinite(n)) return `${n}%`;\n }\n if (type === \"number\") {\n const n = Number(value);\n if (Number.isFinite(n)) return n.toLocaleString();\n }\n return String(value);\n}\n\nfunction stableSort(data, compare) {\n return data\n .map((item, idx) => ({ item, idx }))\n .sort((a, b) => {\n const c = compare(a.item, b.item);\n return c !== 0 ? c : a.idx - b.idx;\n })\n .map((x) => x.item);\n}\n\nexport default function TableCard({\n data = [],\n columns = [],\n title,\n subtitle,\n searchable = false,\n sortable = false,\n paginated = false,\n selectable = false,\n pageSize = 10,\n actions,\n rowActions,\n onRowSelect,\n onSort,\n onSearch,\n loading = false,\n error,\n emptyMessage = \"No results.\",\n simulateInitialLoad = false,\n minInitialDelayMs = 350,\n maxInitialDelayMs = 900,\n ...cardProps\n}) {\n const [query, setQuery] = React.useState(\"\");\n const [sortKey, setSortKey] = React.useState(null);\n const [sortDir, setSortDir] = React.useState(\"asc\");\n const [page, setPage] = React.useState(1);\n const [selectedId, setSelectedId] = React.useState(null);\n const [simLoading, setSimLoading] = React.useState(simulateInitialLoad);\n\n React.useEffect(() => {\n if (!simulateInitialLoad) return;\n const delay =\n Math.floor(Math.random() * (maxInitialDelayMs - minInitialDelayMs + 1)) + minInitialDelayMs;\n const t = setTimeout(() => setSimLoading(false), delay);\n return () => clearTimeout(t);\n }, [simulateInitialLoad, minInitialDelayMs, maxInitialDelayMs]);\n\n const effectiveLoading = loading || simLoading;\n\n const filtered = React.useMemo(() => {\n if (!searchable || !query.trim()) return data;\n const q = query.trim().toLowerCase();\n return data.filter((row) =>\n columns.some((col) => {\n const raw = row?.[col.key];\n if (raw == null) return false;\n return String(raw).toLowerCase().includes(q);\n })\n );\n }, [data, columns, query, searchable]);\n\n const sorted = React.useMemo(() => {\n if (!sortable || !sortKey) return filtered;\n const col = columns.find((c) => c.key === sortKey);\n if (!col) return filtered;\n const dir = sortDir === \"desc\" ? -1 : 1;\n return stableSort(filtered, (a, b) => {\n const av = a?.[sortKey];\n const bv = b?.[sortKey];\n if (av == null && bv == null) return 0;\n if (av == null) return -1 * dir;\n if (bv == null) return 1 * dir;\n if (typeof av === \"number\" && typeof bv === \"number\") return (av - bv) * dir;\n return String(av).localeCompare(String(bv)) * dir;\n });\n }, [filtered, sortable, sortKey, sortDir, columns]);\n\n const total = sorted.length;\n const totalPages = paginated ? Math.max(1, Math.ceil(total / pageSize)) : 1;\n const clampedPage = Math.min(page, totalPages);\n\n const pageData = React.useMemo(() => {\n if (!paginated) return sorted;\n const start = (clampedPage - 1) * pageSize;\n return sorted.slice(start, start + pageSize);\n }, [sorted, paginated, clampedPage, pageSize]);\n\n React.useEffect(() => {\n if (page !== clampedPage) setPage(clampedPage);\n }, [page, clampedPage]);\n\n const header = (\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between\">\n <div className=\"min-w-0\">\n {title ? (\n <UIText as=\"div\" size=\"sm\" weight=\"medium\">\n {title}\n </UIText>\n ) : null}\n {subtitle ? (\n <UIText as=\"div\" size=\"xs\" muted className=\"mt-1\">\n {subtitle}\n </UIText>\n ) : null}\n </div>\n <div className=\"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-end\">\n {searchable ? (\n <div className=\"w-full sm:w-64\">\n <UIInput\n value={query}\n onChange={(e) => {\n setQuery(e.target.value);\n setPage(1);\n onSearch?.(e.target.value);\n }}\n placeholder=\"Search…\"\n aria-label=\"Search table\"\n />\n </div>\n ) : null}\n {actions ? <div className=\"flex items-center gap-2\">{actions}</div> : null}\n </div>\n </div>\n );\n\n if (error) {\n return (\n <BaseCard\n header={header}\n body={\n <div className=\"mt-4 rounded-xl border border-rose-200 bg-rose-50 p-4 text-sm text-rose-900 dark:border-rose-900/40 dark:bg-rose-950/30 dark:text-rose-100\">\n {String(error)}\n </div>\n }\n {...cardProps}\n />\n );\n }\n\n const canSort = (col) => sortable && (col.sortable ?? true);\n\n return (\n <BaseCard\n variant=\"table\"\n header={header}\n body={\n <div className=\"mt-4 overflow-hidden rounded-xl border border-slate-200 dark:border-slate-800\">\n <div className=\"w-full overflow-x-auto\">\n <table className=\"min-w-full border-separate border-spacing-0\">\n <thead className=\"bg-slate-50 dark:bg-slate-950/30\">\n <tr>\n {columns.map((col) => {\n const active = sortKey === col.key;\n return (\n <th\n key={col.key}\n scope=\"col\"\n className={[\n \"whitespace-nowrap border-b border-slate-200 px-4 py-3 text-left text-xs font-semibold text-slate-600 dark:border-slate-800 dark:text-slate-300\",\n col.className ?? \"\"\n ]\n .filter(Boolean)\n .join(\" \")}\n >\n {canSort(col) ? (\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-2 hover:text-slate-900 dark:hover:text-slate-50\"\n onClick={() => {\n const nextDir = active && sortDir === \"asc\" ? \"desc\" : \"asc\";\n setSortKey(col.key);\n setSortDir(nextDir);\n onSort?.({ key: col.key, direction: nextDir });\n }}\n >\n <span>{col.label}</span>\n <span className=\"text-[10px] opacity-70\">\n {active ? (sortDir === \"asc\" ? \"▲\" : \"▼\") : \"↕\"}\n </span>\n </button>\n ) : (\n col.label\n )}\n </th>\n );\n })}\n {rowActions ? (\n <th className=\"border-b border-slate-200 px-4 py-3 text-right text-xs font-semibold text-slate-600 dark:border-slate-800 dark:text-slate-300\">\n Actions\n </th>\n ) : null}\n </tr>\n </thead>\n\n <tbody className=\"bg-white dark:bg-slate-900\">\n {effectiveLoading ? (\n Array.from({ length: Math.min(pageSize, 6) }).map((_, idx) => (\n <tr key={idx}>\n {columns.map((col) => (\n <td\n key={col.key}\n className=\"border-b border-slate-200 px-4 py-3 dark:border-slate-800\"\n >\n <div className=\"h-4 w-3/4 animate-pulse rounded bg-slate-200 dark:bg-slate-800\" />\n </td>\n ))}\n {rowActions ? (\n <td className=\"border-b border-slate-200 px-4 py-3 dark:border-slate-800\">\n <div className=\"h-4 w-10 animate-pulse rounded bg-slate-200 dark:bg-slate-800\" />\n </td>\n ) : null}\n </tr>\n ))\n ) : pageData.length === 0 ? (\n <tr>\n <td\n colSpan={columns.length + (rowActions ? 1 : 0)}\n className=\"px-4 py-10 text-center text-sm text-slate-600 dark:text-slate-300\"\n >\n {emptyMessage}\n </td>\n </tr>\n ) : (\n pageData.map((row, idx) => {\n const rowId = row?.id ?? idx;\n const selected = selectable && selectedId === rowId;\n return (\n <tr\n key={rowId}\n className={[\n \"group\",\n selectable ? \"cursor-pointer\" : \"\",\n selected ? \"bg-brand-50 dark:bg-brand-950/30\" : \"\"\n ]\n .filter(Boolean)\n .join(\" \")}\n onClick={() => {\n if (!selectable) return;\n setSelectedId(rowId);\n onRowSelect?.(row);\n }}\n >\n {columns.map((col) => {\n const raw = row?.[col.key];\n const content = col.render ? col.render(raw, row) : defaultTypeFormat(col.type, raw);\n return (\n <td\n key={col.key}\n className={[\n \"border-b border-slate-200 px-4 py-3 text-sm text-slate-700 dark:border-slate-800 dark:text-slate-200\",\n col.mono ? \"font-mono text-[13px]\" : \"\",\n col.className ?? \"\"\n ]\n .filter(Boolean)\n .join(\" \")}\n >\n {content}\n </td>\n );\n })}\n {rowActions ? (\n <td className=\"border-b border-slate-200 px-4 py-3 text-right text-sm dark:border-slate-800\">\n <div className=\"inline-flex items-center justify-end gap-2 opacity-100 sm:opacity-0 sm:group-hover:opacity-100\">\n {rowActions(row)}\n </div>\n </td>\n ) : null}\n </tr>\n );\n })\n )}\n </tbody>\n </table>\n </div>\n\n {paginated && !effectiveLoading ? (\n <div className=\"flex flex-col gap-2 border-t border-slate-200 bg-slate-50 px-4 py-3 dark:border-slate-800 dark:bg-slate-950/30 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"text-xs text-slate-600 dark:text-slate-300\">\n {total === 0 ? \"0 results\" : `Showing ${(clampedPage - 1) * pageSize + 1}-${Math.min(clampedPage * pageSize, total)} of ${total}`}\n </div>\n <div className=\"flex items-center gap-2\">\n <UIButton\n variant=\"outline\"\n size=\"sm\"\n disabled={clampedPage <= 1}\n onClick={() => setPage((p) => Math.max(1, p - 1))}\n >\n Prev\n </UIButton>\n <div className=\"text-xs text-slate-600 dark:text-slate-300\">\n Page {clampedPage} / {totalPages}\n </div>\n <UIButton\n variant=\"outline\"\n size=\"sm\"\n disabled={clampedPage >= totalPages}\n onClick={() => setPage((p) => Math.min(totalPages, p + 1))}\n >\n Next\n </UIButton>\n </div>\n </div>\n ) : null}\n </div>\n }\n {...cardProps}\n />\n );\n}\n\n\n"],"names":["defaultTypeFormat","type","value","n","stableSort","data","compare","item","idx","a","b","c","x","TableCard","columns","title","subtitle","searchable","sortable","paginated","selectable","pageSize","actions","rowActions","onRowSelect","onSort","onSearch","loading","error","emptyMessage","simulateInitialLoad","minInitialDelayMs","maxInitialDelayMs","cardProps","query","setQuery","React","sortKey","setSortKey","sortDir","setSortDir","page","setPage","selectedId","setSelectedId","simLoading","setSimLoading","delay","t","effectiveLoading","filtered","q","row","col","raw","sorted","dir","av","bv","total","totalPages","clampedPage","pageData","start","header","jsxs","jsx","UIText","UIInput","BaseCard","canSort","active","nextDir","_","rowId","content","UIButton","p"],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { jsxs as s, jsx as e } from "react/jsx-runtime";
|
|
2
|
+
import x from "react";
|
|
3
|
+
import v from "./BaseCard.js";
|
|
4
|
+
import k from "../ui/Text.js";
|
|
5
|
+
function N({ title: d, actions: a, content: r, divided: l }) {
|
|
6
|
+
return /* @__PURE__ */ s("div", { className: l ? "border-t border-slate-200 pt-4 dark:border-slate-800" : "", children: [
|
|
7
|
+
d || a ? /* @__PURE__ */ s("div", { className: "mb-3 flex items-start justify-between gap-3", children: [
|
|
8
|
+
d ? /* @__PURE__ */ e(k, { as: "div", size: "sm", weight: "medium", children: d }) : /* @__PURE__ */ e("div", {}),
|
|
9
|
+
a ? /* @__PURE__ */ e("div", { className: "shrink-0", children: a }) : null
|
|
10
|
+
] }) : null,
|
|
11
|
+
/* @__PURE__ */ e("div", { children: r })
|
|
12
|
+
] });
|
|
13
|
+
}
|
|
14
|
+
function j({
|
|
15
|
+
header: d,
|
|
16
|
+
sections: a = [],
|
|
17
|
+
footer: r,
|
|
18
|
+
divided: l = !1,
|
|
19
|
+
collapsible: o = !1,
|
|
20
|
+
defaultExpanded: c = !0,
|
|
21
|
+
loading: m = !1,
|
|
22
|
+
emptyMessage: b = "No sections.",
|
|
23
|
+
...h
|
|
24
|
+
}) {
|
|
25
|
+
const [i, p] = x.useState(c), u = /* @__PURE__ */ s("div", { className: "flex items-start justify-between gap-3", children: [
|
|
26
|
+
/* @__PURE__ */ e("div", { className: "min-w-0", children: d }),
|
|
27
|
+
o ? /* @__PURE__ */ e(
|
|
28
|
+
"button",
|
|
29
|
+
{
|
|
30
|
+
type: "button",
|
|
31
|
+
className: "rounded-lg border border-slate-200 bg-white px-2 py-1 text-xs font-semibold text-slate-700 shadow-sm hover:bg-slate-50 dark:border-slate-800 dark:bg-slate-900 dark:text-slate-200 dark:hover:bg-slate-800",
|
|
32
|
+
onClick: () => p((t) => !t),
|
|
33
|
+
"aria-expanded": i,
|
|
34
|
+
"aria-label": "Toggle widget",
|
|
35
|
+
children: i ? "Collapse" : "Expand"
|
|
36
|
+
}
|
|
37
|
+
) : null
|
|
38
|
+
] }), g = /* @__PURE__ */ s("div", { className: "mt-4 space-y-4", children: [
|
|
39
|
+
m ? /* @__PURE__ */ s("div", { className: "space-y-3", children: [
|
|
40
|
+
/* @__PURE__ */ e("div", { className: "h-4 w-1/3 animate-pulse rounded bg-slate-200 dark:bg-slate-800" }),
|
|
41
|
+
/* @__PURE__ */ e("div", { className: "h-4 w-2/3 animate-pulse rounded bg-slate-200 dark:bg-slate-800" }),
|
|
42
|
+
/* @__PURE__ */ e("div", { className: "h-4 w-1/2 animate-pulse rounded bg-slate-200 dark:bg-slate-800" })
|
|
43
|
+
] }) : i ? a.length === 0 ? /* @__PURE__ */ e("div", { className: "rounded-xl border border-dashed border-slate-300 bg-slate-50 p-6 text-center text-sm text-slate-600 dark:border-slate-700 dark:bg-slate-950/30 dark:text-slate-300", children: b }) : a.map((t, n) => /* @__PURE__ */ e(
|
|
44
|
+
N,
|
|
45
|
+
{
|
|
46
|
+
title: t?.title,
|
|
47
|
+
actions: t?.actions,
|
|
48
|
+
content: t?.content,
|
|
49
|
+
divided: l && n !== 0
|
|
50
|
+
},
|
|
51
|
+
t?.id ?? n
|
|
52
|
+
)) : /* @__PURE__ */ e("div", { className: "text-sm text-slate-600 dark:text-slate-300", children: "Collapsed." }),
|
|
53
|
+
r ? /* @__PURE__ */ e("div", { className: l ? "border-t border-slate-200 pt-4 dark:border-slate-800" : "", children: r }) : null
|
|
54
|
+
] });
|
|
55
|
+
return /* @__PURE__ */ e(v, { variant: "widget", header: u, body: g, ...h });
|
|
56
|
+
}
|
|
57
|
+
export {
|
|
58
|
+
j as default
|
|
59
|
+
};
|
|
60
|
+
//# sourceMappingURL=WidgetCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WidgetCard.js","sources":["../../../../src/components/library/cards/WidgetCard.jsx"],"sourcesContent":["import React from \"react\";\nimport BaseCard from \"./BaseCard\";\nimport UIText from \"../ui/Text\";\n\nfunction Section({ title, actions, content, divided }) {\n return (\n <div className={divided ? \"border-t border-slate-200 pt-4 dark:border-slate-800\" : \"\"}>\n {(title || actions) ? (\n <div className=\"mb-3 flex items-start justify-between gap-3\">\n {title ? (\n <UIText as=\"div\" size=\"sm\" weight=\"medium\">\n {title}\n </UIText>\n ) : (\n <div />\n )}\n {actions ? <div className=\"shrink-0\">{actions}</div> : null}\n </div>\n ) : null}\n <div>{content}</div>\n </div>\n );\n}\n\nexport default function WidgetCard({\n header,\n sections = [],\n footer,\n divided = false,\n collapsible = false,\n defaultExpanded = true,\n loading = false,\n emptyMessage = \"No sections.\",\n ...cardProps\n}) {\n const [expanded, setExpanded] = React.useState(defaultExpanded);\n\n const hdr = (\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0\">{header}</div>\n {collapsible ? (\n <button\n type=\"button\"\n className=\"rounded-lg border border-slate-200 bg-white px-2 py-1 text-xs font-semibold text-slate-700 shadow-sm hover:bg-slate-50 dark:border-slate-800 dark:bg-slate-900 dark:text-slate-200 dark:hover:bg-slate-800\"\n onClick={() => setExpanded((e) => !e)}\n aria-expanded={expanded}\n aria-label=\"Toggle widget\"\n >\n {expanded ? \"Collapse\" : \"Expand\"}\n </button>\n ) : null}\n </div>\n );\n\n const body = (\n <div className=\"mt-4 space-y-4\">\n {loading ? (\n <div className=\"space-y-3\">\n <div className=\"h-4 w-1/3 animate-pulse rounded bg-slate-200 dark:bg-slate-800\" />\n <div className=\"h-4 w-2/3 animate-pulse rounded bg-slate-200 dark:bg-slate-800\" />\n <div className=\"h-4 w-1/2 animate-pulse rounded bg-slate-200 dark:bg-slate-800\" />\n </div>\n ) : expanded ? (\n sections.length === 0 ? (\n <div className=\"rounded-xl border border-dashed border-slate-300 bg-slate-50 p-6 text-center text-sm text-slate-600 dark:border-slate-700 dark:bg-slate-950/30 dark:text-slate-300\">\n {emptyMessage}\n </div>\n ) : (\n sections.map((s, idx) => (\n <Section\n key={s?.id ?? idx}\n title={s?.title}\n actions={s?.actions}\n content={s?.content}\n divided={divided && idx !== 0}\n />\n ))\n )\n ) : (\n <div className=\"text-sm text-slate-600 dark:text-slate-300\">Collapsed.</div>\n )}\n\n {footer ? <div className={divided ? \"border-t border-slate-200 pt-4 dark:border-slate-800\" : \"\"}>{footer}</div> : null}\n </div>\n );\n\n return <BaseCard variant=\"widget\" header={hdr} body={body} {...cardProps} />;\n}\n\n\n"],"names":["Section","title","actions","content","divided","jsxs","jsx","UIText","WidgetCard","header","sections","footer","collapsible","defaultExpanded","loading","emptyMessage","cardProps","expanded","setExpanded","React","hdr","e","body","s","idx","BaseCard"],"mappings":";;;;AAIA,SAASA,EAAQ,EAAE,OAAAC,GAAO,SAAAC,GAAS,SAAAC,GAAS,SAAAC,KAAW;AACrD,SACE,gBAAAC,EAAC,OAAA,EAAI,WAAWD,IAAU,yDAAyD,IAC/E,UAAA;AAAA,IAAAH,KAASC,IACT,gBAAAG,EAAC,OAAA,EAAI,WAAU,+CACZ,UAAA;AAAA,MAAAJ,IACC,gBAAAK,EAACC,GAAA,EAAO,IAAG,OAAM,MAAK,MAAK,QAAO,UAC/B,UAAAN,EAAA,CACH,IAEA,gBAAAK,EAAC,OAAA,EAAI;AAAA,MAENJ,IAAU,gBAAAI,EAAC,OAAA,EAAI,WAAU,YAAY,aAAQ,IAAS;AAAA,IAAA,EAAA,CACzD,IACE;AAAA,IACJ,gBAAAA,EAAC,SAAK,UAAAH,EAAA,CAAQ;AAAA,EAAA,GAChB;AAEJ;AAEA,SAAwBK,EAAW;AAAA,EACjC,QAAAC;AAAA,EACA,UAAAC,IAAW,CAAA;AAAA,EACX,QAAAC;AAAA,EACA,SAAAP,IAAU;AAAA,EACV,aAAAQ,IAAc;AAAA,EACd,iBAAAC,IAAkB;AAAA,EAClB,SAAAC,IAAU;AAAA,EACV,cAAAC,IAAe;AAAA,EACf,GAAGC;AACL,GAAG;AACD,QAAM,CAACC,GAAUC,CAAW,IAAIC,EAAM,SAASN,CAAe,GAExDO,IACJ,gBAAAf,EAAC,OAAA,EAAI,WAAU,0CACb,UAAA;AAAA,IAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,WAAW,UAAAG,GAAO;AAAA,IAChCG,IACC,gBAAAN;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAS,MAAMY,EAAY,CAACG,MAAM,CAACA,CAAC;AAAA,QACpC,iBAAeJ;AAAA,QACf,cAAW;AAAA,QAEV,cAAW,aAAa;AAAA,MAAA;AAAA,IAAA,IAEzB;AAAA,EAAA,GACN,GAGIK,IACJ,gBAAAjB,EAAC,OAAA,EAAI,WAAU,kBACZ,UAAA;AAAA,IAAAS,IACC,gBAAAT,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,MAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,iEAAA,CAAiE;AAAA,MAChF,gBAAAA,EAAC,OAAA,EAAI,WAAU,iEAAA,CAAiE;AAAA,MAChF,gBAAAA,EAAC,OAAA,EAAI,WAAU,iEAAA,CAAiE;AAAA,IAAA,EAAA,CAClF,IACEW,IACFP,EAAS,WAAW,IAClB,gBAAAJ,EAAC,OAAA,EAAI,WAAU,sKACZ,aACH,IAEAI,EAAS,IAAI,CAACa,GAAGC,MACf,gBAAAlB;AAAA,MAACN;AAAA,MAAA;AAAA,QAEC,OAAOuB,GAAG;AAAA,QACV,SAASA,GAAG;AAAA,QACZ,SAASA,GAAG;AAAA,QACZ,SAASnB,KAAWoB,MAAQ;AAAA,MAAA;AAAA,MAJvBD,GAAG,MAAMC;AAAA,IAAA,CAMjB,IAGH,gBAAAlB,EAAC,OAAA,EAAI,WAAU,8CAA6C,UAAA,cAAU;AAAA,IAGvEK,sBAAU,OAAA,EAAI,WAAWP,IAAU,yDAAyD,IAAK,aAAO,IAAS;AAAA,EAAA,GACpH;AAGF,SAAO,gBAAAE,EAACmB,KAAS,SAAQ,UAAS,QAAQL,GAAK,MAAAE,GAAa,GAAGN,GAAW;AAC5E;"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { jsx as r, jsxs as W } from "react/jsx-runtime";
|
|
2
|
+
import l from "react";
|
|
3
|
+
function F({
|
|
4
|
+
data: h,
|
|
5
|
+
renderChart: f,
|
|
6
|
+
options: g = {},
|
|
7
|
+
width: w,
|
|
8
|
+
height: i = 280,
|
|
9
|
+
responsive: t = !1,
|
|
10
|
+
aspectRatio: s,
|
|
11
|
+
className: k = "",
|
|
12
|
+
style: v,
|
|
13
|
+
containerStyle: x,
|
|
14
|
+
svgStyle: y,
|
|
15
|
+
loading: o = !1,
|
|
16
|
+
error: u,
|
|
17
|
+
ariaLabel: j = "Chart"
|
|
18
|
+
}) {
|
|
19
|
+
const a = l.useRef(null), N = l.useRef(null), [d, E] = l.useState(null);
|
|
20
|
+
l.useEffect(() => {
|
|
21
|
+
if (!t) return;
|
|
22
|
+
const n = a.current;
|
|
23
|
+
if (!n) return;
|
|
24
|
+
const e = new ResizeObserver((R) => {
|
|
25
|
+
const m = R?.[0]?.contentRect?.width;
|
|
26
|
+
typeof m == "number" && Number.isFinite(m) && E(m);
|
|
27
|
+
});
|
|
28
|
+
return e.observe(n), () => e.disconnect();
|
|
29
|
+
}, [t]);
|
|
30
|
+
const c = t ? d : w, b = l.useMemo(() => !t || !d ? i : s && Number.isFinite(s) && s > 0 ? d / s : i, [t, d, i, s]);
|
|
31
|
+
return l.useEffect(() => {
|
|
32
|
+
if (o || u || !f) return;
|
|
33
|
+
const n = N.current;
|
|
34
|
+
if (!n) return;
|
|
35
|
+
const e = {
|
|
36
|
+
width: c ?? 0,
|
|
37
|
+
height: b ?? 0
|
|
38
|
+
};
|
|
39
|
+
t && (!e.width || e.width < 10) || !e.height || e.height < 10 || f(n, h, e, g);
|
|
40
|
+
}, [h, f, g, c, b, t, o, u]), u ? /* @__PURE__ */ r(
|
|
41
|
+
"div",
|
|
42
|
+
{
|
|
43
|
+
ref: a,
|
|
44
|
+
className: ["w-full rounded-xl border border-rose-200 bg-rose-50 p-4 text-sm text-rose-900 dark:border-rose-900/40 dark:bg-rose-950/30 dark:text-rose-100", k].filter(Boolean).join(" "),
|
|
45
|
+
style: x,
|
|
46
|
+
children: String(u)
|
|
47
|
+
}
|
|
48
|
+
) : /* @__PURE__ */ r(
|
|
49
|
+
"div",
|
|
50
|
+
{
|
|
51
|
+
ref: a,
|
|
52
|
+
className: ["w-full", k].filter(Boolean).join(" "),
|
|
53
|
+
style: { ...x, position: "relative" },
|
|
54
|
+
children: o ? /* @__PURE__ */ r("div", { className: "h-full w-full rounded-xl border border-slate-200 bg-white p-5 shadow-sm dark:border-slate-800 dark:bg-slate-900", children: /* @__PURE__ */ W("div", { className: "space-y-3", children: [
|
|
55
|
+
/* @__PURE__ */ r("div", { className: "h-4 w-1/3 animate-pulse rounded bg-slate-200 dark:bg-slate-800" }),
|
|
56
|
+
/* @__PURE__ */ r("div", { className: "h-44 w-full animate-pulse rounded bg-slate-200 dark:bg-slate-800" })
|
|
57
|
+
] }) }) : /* @__PURE__ */ r(
|
|
58
|
+
"svg",
|
|
59
|
+
{
|
|
60
|
+
ref: N,
|
|
61
|
+
role: "img",
|
|
62
|
+
"aria-label": j,
|
|
63
|
+
width: c ?? w ?? "100%",
|
|
64
|
+
height: b,
|
|
65
|
+
style: { ...y, ...v, display: "block" }
|
|
66
|
+
}
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
export {
|
|
72
|
+
F as default
|
|
73
|
+
};
|
|
74
|
+
//# sourceMappingURL=D3Chart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"D3Chart.js","sources":["../../../../src/components/library/charts/D3Chart.jsx"],"sourcesContent":["import React from \"react\";\n\n/**\n * Minimal D3 chart host:\n * - Owns the <svg> element\n * - Computes responsive dimensions from container size\n * - Calls renderChart(svgEl, data, dims, options)\n */\nexport default function D3Chart({\n data,\n renderChart,\n options = {},\n width,\n height = 280,\n responsive = false,\n aspectRatio,\n className = \"\",\n style,\n containerStyle,\n svgStyle,\n loading = false,\n error,\n ariaLabel = \"Chart\"\n}) {\n const containerRef = React.useRef(null);\n const svgRef = React.useRef(null);\n const [containerWidth, setContainerWidth] = React.useState(null);\n\n React.useEffect(() => {\n if (!responsive) return;\n const el = containerRef.current;\n if (!el) return;\n\n const obs = new ResizeObserver((entries) => {\n const w = entries?.[0]?.contentRect?.width;\n if (typeof w === \"number\" && Number.isFinite(w)) setContainerWidth(w);\n });\n obs.observe(el);\n return () => obs.disconnect();\n }, [responsive]);\n\n const computedWidth = responsive ? containerWidth : width;\n const computedHeight = React.useMemo(() => {\n if (!responsive) return height;\n if (!containerWidth) return height;\n if (aspectRatio && Number.isFinite(aspectRatio) && aspectRatio > 0) return containerWidth / aspectRatio;\n return height;\n }, [responsive, containerWidth, height, aspectRatio]);\n\n React.useEffect(() => {\n if (loading || error) return;\n if (!renderChart) return;\n const svgEl = svgRef.current;\n if (!svgEl) return;\n\n const dims = {\n width: computedWidth ?? 0,\n height: computedHeight ?? 0\n };\n\n // Avoid calling renderChart before we have a measurable width in responsive mode\n if (responsive && (!dims.width || dims.width < 10)) return;\n if (!dims.height || dims.height < 10) return;\n\n renderChart(svgEl, data, dims, options);\n }, [data, renderChart, options, computedWidth, computedHeight, responsive, loading, error]);\n\n if (error) {\n return (\n <div\n ref={containerRef}\n className={[\"w-full rounded-xl border border-rose-200 bg-rose-50 p-4 text-sm text-rose-900 dark:border-rose-900/40 dark:bg-rose-950/30 dark:text-rose-100\", className]\n .filter(Boolean)\n .join(\" \")}\n style={containerStyle}\n >\n {String(error)}\n </div>\n );\n }\n\n return (\n <div\n ref={containerRef}\n className={[\"w-full\", className].filter(Boolean).join(\" \")}\n style={{ ...containerStyle, position: \"relative\" }}\n >\n {loading ? (\n <div className=\"h-full w-full rounded-xl border border-slate-200 bg-white p-5 shadow-sm dark:border-slate-800 dark:bg-slate-900\">\n <div className=\"space-y-3\">\n <div className=\"h-4 w-1/3 animate-pulse rounded bg-slate-200 dark:bg-slate-800\" />\n <div className=\"h-44 w-full animate-pulse rounded bg-slate-200 dark:bg-slate-800\" />\n </div>\n </div>\n ) : (\n <svg\n ref={svgRef}\n role=\"img\"\n aria-label={ariaLabel}\n width={computedWidth ?? width ?? \"100%\"}\n height={computedHeight}\n style={{ ...svgStyle, ...style, display: \"block\" }}\n />\n )}\n </div>\n );\n}\n\n\n"],"names":["D3Chart","data","renderChart","options","width","height","responsive","aspectRatio","className","style","containerStyle","svgStyle","loading","error","ariaLabel","containerRef","React","svgRef","containerWidth","setContainerWidth","el","obs","entries","w","computedWidth","computedHeight","svgEl","dims","jsx","jsxs"],"mappings":";;AAQA,SAAwBA,EAAQ;AAAA,EAC9B,MAAAC;AAAA,EACA,aAAAC;AAAA,EACA,SAAAC,IAAU,CAAA;AAAA,EACV,OAAAC;AAAA,EACA,QAAAC,IAAS;AAAA,EACT,YAAAC,IAAa;AAAA,EACb,aAAAC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,OAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,UAAAC;AAAA,EACA,SAAAC,IAAU;AAAA,EACV,OAAAC;AAAA,EACA,WAAAC,IAAY;AACd,GAAG;AACD,QAAMC,IAAeC,EAAM,OAAO,IAAI,GAChCC,IAASD,EAAM,OAAO,IAAI,GAC1B,CAACE,GAAgBC,CAAiB,IAAIH,EAAM,SAAS,IAAI;AAE/D,EAAAA,EAAM,UAAU,MAAM;AACpB,QAAI,CAACV,EAAY;AACjB,UAAMc,IAAKL,EAAa;AACxB,QAAI,CAACK,EAAI;AAET,UAAMC,IAAM,IAAI,eAAe,CAACC,MAAY;AAC1C,YAAMC,IAAID,IAAU,CAAC,GAAG,aAAa;AACrC,MAAI,OAAOC,KAAM,YAAY,OAAO,SAASA,CAAC,OAAqBA,CAAC;AAAA,IACtE,CAAC;AACD,WAAAF,EAAI,QAAQD,CAAE,GACP,MAAMC,EAAI,WAAA;AAAA,EACnB,GAAG,CAACf,CAAU,CAAC;AAEf,QAAMkB,IAAgBlB,IAAaY,IAAiBd,GAC9CqB,IAAiBT,EAAM,QAAQ,MAC/B,CAACV,KACD,CAACY,IAAuBb,IACxBE,KAAe,OAAO,SAASA,CAAW,KAAKA,IAAc,IAAUW,IAAiBX,IACrFF,GACN,CAACC,GAAYY,GAAgBb,GAAQE,CAAW,CAAC;AAoBpD,SAlBAS,EAAM,UAAU,MAAM;AAEpB,QADIJ,KAAWC,KACX,CAACX,EAAa;AAClB,UAAMwB,IAAQT,EAAO;AACrB,QAAI,CAACS,EAAO;AAEZ,UAAMC,IAAO;AAAA,MACX,OAAOH,KAAiB;AAAA,MACxB,QAAQC,KAAkB;AAAA,IAAA;AAI5B,IAAInB,MAAe,CAACqB,EAAK,SAASA,EAAK,QAAQ,OAC3C,CAACA,EAAK,UAAUA,EAAK,SAAS,MAElCzB,EAAYwB,GAAOzB,GAAM0B,GAAMxB,CAAO;AAAA,EACxC,GAAG,CAACF,GAAMC,GAAaC,GAASqB,GAAeC,GAAgBnB,GAAYM,GAASC,CAAK,CAAC,GAEtFA,IAEA,gBAAAe;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAKb;AAAA,MACL,WAAW,CAAC,gJAAgJP,CAAS,EAClK,OAAO,OAAO,EACd,KAAK,GAAG;AAAA,MACX,OAAOE;AAAA,MAEN,iBAAOG,CAAK;AAAA,IAAA;AAAA,EAAA,IAMjB,gBAAAe;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAKb;AAAA,MACL,WAAW,CAAC,UAAUP,CAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,MACzD,OAAO,EAAE,GAAGE,GAAgB,UAAU,WAAA;AAAA,MAErC,UAAAE,sBACE,OAAA,EAAI,WAAU,mHACb,UAAA,gBAAAiB,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,QAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,iEAAA,CAAiE;AAAA,QAChF,gBAAAA,EAAC,OAAA,EAAI,WAAU,mEAAA,CAAmE;AAAA,MAAA,EAAA,CACpF,GACF,IAEA,gBAAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,KAAKX;AAAA,UACL,MAAK;AAAA,UACL,cAAYH;AAAA,UACZ,OAAOU,KAAiBpB,KAAS;AAAA,UACjC,QAAQqB;AAAA,UACR,OAAO,EAAE,GAAGd,GAAU,GAAGF,GAAO,SAAS,QAAA;AAAA,QAAQ;AAAA,MAAA;AAAA,IACnD;AAAA,EAAA;AAIR;"}
|