@arqel-dev/ui 0.11.0 → 0.14.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.
Files changed (112) hide show
  1. package/SKILL.md +5 -2
  2. package/dist/AreaChart-NMQ2RQGA.js +33 -0
  3. package/dist/AreaChart-NMQ2RQGA.js.map +1 -0
  4. package/dist/ArqelCreatePage-O6KNXPAO.js +8 -0
  5. package/dist/ArqelCreatePage-O6KNXPAO.js.map +1 -0
  6. package/dist/ArqelDashboardPage-PX3Y75AA.js +6 -0
  7. package/dist/ArqelDashboardPage-PX3Y75AA.js.map +1 -0
  8. package/dist/ArqelEditPage-NAMWJ5MC.js +8 -0
  9. package/dist/ArqelEditPage-NAMWJ5MC.js.map +1 -0
  10. package/dist/ArqelIndexPage-GC33PNBL.js +12 -0
  11. package/dist/ArqelIndexPage-GC33PNBL.js.map +1 -0
  12. package/dist/ArqelShowPage-LGVTL6UZ.js +6 -0
  13. package/dist/ArqelShowPage-LGVTL6UZ.js.map +1 -0
  14. package/dist/BarChart-KLHKTLO2.js +19 -0
  15. package/dist/BarChart-KLHKTLO2.js.map +1 -0
  16. package/dist/DonutChart-L56R4QF2.js +11 -0
  17. package/dist/DonutChart-L56R4QF2.js.map +1 -0
  18. package/dist/LineChart-GHMPHFZZ.js +30 -0
  19. package/dist/LineChart-GHMPHFZZ.js.map +1 -0
  20. package/dist/PieChart-T2VQOFPP.js +4 -0
  21. package/dist/PieChart-T2VQOFPP.js.map +1 -0
  22. package/dist/RadarChart-CSWR5AO7.js +32 -0
  23. package/dist/RadarChart-CSWR5AO7.js.map +1 -0
  24. package/dist/Topbar-DffcNdcJ.d.ts +50 -0
  25. package/dist/action.d.ts +12 -2
  26. package/dist/action.js +6 -1090
  27. package/dist/action.js.map +1 -1
  28. package/dist/auth.js +1 -10
  29. package/dist/auth.js.map +1 -1
  30. package/dist/chunk-2LTZJ4R7.js +110 -0
  31. package/dist/chunk-2LTZJ4R7.js.map +1 -0
  32. package/dist/chunk-47HD7ALI.js +370 -0
  33. package/dist/chunk-47HD7ALI.js.map +1 -0
  34. package/dist/chunk-4JJS2SVS.js +628 -0
  35. package/dist/chunk-4JJS2SVS.js.map +1 -0
  36. package/dist/chunk-6UJQP7KU.js +737 -0
  37. package/dist/chunk-6UJQP7KU.js.map +1 -0
  38. package/dist/chunk-B7ULUJVO.js +11 -0
  39. package/dist/chunk-B7ULUJVO.js.map +1 -0
  40. package/dist/chunk-C5H44NSP.js +37 -0
  41. package/dist/chunk-C5H44NSP.js.map +1 -0
  42. package/dist/chunk-DSULVRB6.js +101 -0
  43. package/dist/chunk-DSULVRB6.js.map +1 -0
  44. package/dist/chunk-E2ORVQM5.js +50 -0
  45. package/dist/chunk-E2ORVQM5.js.map +1 -0
  46. package/dist/chunk-EYAUPJ6J.js +64 -0
  47. package/dist/chunk-EYAUPJ6J.js.map +1 -0
  48. package/dist/chunk-FHRQ7PWE.js +58 -0
  49. package/dist/chunk-FHRQ7PWE.js.map +1 -0
  50. package/dist/chunk-FV7RESKL.js +285 -0
  51. package/dist/chunk-FV7RESKL.js.map +1 -0
  52. package/dist/chunk-I6MWOIFR.js +204 -0
  53. package/dist/chunk-I6MWOIFR.js.map +1 -0
  54. package/dist/chunk-IKJYLSTK.js +440 -0
  55. package/dist/chunk-IKJYLSTK.js.map +1 -0
  56. package/dist/chunk-K7QY56XN.js +610 -0
  57. package/dist/chunk-K7QY56XN.js.map +1 -0
  58. package/dist/chunk-L3JBBN4H.js +27 -0
  59. package/dist/chunk-L3JBBN4H.js.map +1 -0
  60. package/dist/chunk-M6NI45DQ.js +49 -0
  61. package/dist/chunk-M6NI45DQ.js.map +1 -0
  62. package/dist/chunk-MTNFFSVA.js +92 -0
  63. package/dist/chunk-MTNFFSVA.js.map +1 -0
  64. package/dist/chunk-MTZJDFQ6.js +32 -0
  65. package/dist/chunk-MTZJDFQ6.js.map +1 -0
  66. package/dist/chunk-MXUXMHOK.js +16 -0
  67. package/dist/chunk-MXUXMHOK.js.map +1 -0
  68. package/dist/chunk-PXON56HL.js +35 -0
  69. package/dist/chunk-PXON56HL.js.map +1 -0
  70. package/dist/chunk-PZEVKMZX.js +598 -0
  71. package/dist/chunk-PZEVKMZX.js.map +1 -0
  72. package/dist/chunk-QTUBBZVT.js +57 -0
  73. package/dist/chunk-QTUBBZVT.js.map +1 -0
  74. package/dist/chunk-R4BOUU6Y.js +55 -0
  75. package/dist/chunk-R4BOUU6Y.js.map +1 -0
  76. package/dist/chunk-RMPOR2YZ.js +12 -0
  77. package/dist/chunk-RMPOR2YZ.js.map +1 -0
  78. package/dist/chunk-RNAMHQM6.js +12 -0
  79. package/dist/chunk-RNAMHQM6.js.map +1 -0
  80. package/dist/chunk-WKWV36PG.js +140 -0
  81. package/dist/chunk-WKWV36PG.js.map +1 -0
  82. package/dist/cn-By8XWiSA.d.ts +12 -0
  83. package/dist/flash.js +2 -104
  84. package/dist/flash.js.map +1 -1
  85. package/dist/form.d.ts +1 -1
  86. package/dist/form.js +4 -673
  87. package/dist/form.js.map +1 -1
  88. package/dist/index.d.ts +2 -2
  89. package/dist/index.js +18 -3706
  90. package/dist/index.js.map +1 -1
  91. package/dist/pages.js +23 -3025
  92. package/dist/pages.js.map +1 -1
  93. package/dist/palette.js +1 -283
  94. package/dist/palette.js.map +1 -1
  95. package/dist/primitives.js +3 -658
  96. package/dist/primitives.js.map +1 -1
  97. package/dist/resource.js +5 -720
  98. package/dist/resource.js.map +1 -1
  99. package/dist/shell.d.ts +26 -46
  100. package/dist/shell.js +46 -1039
  101. package/dist/shell.js.map +1 -1
  102. package/dist/table.js +4 -618
  103. package/dist/table.js.map +1 -1
  104. package/dist/utility.js +3 -104
  105. package/dist/utility.js.map +1 -1
  106. package/dist/utils.d.ts +12 -6
  107. package/dist/utils.js +2 -9
  108. package/dist/utils.js.map +1 -1
  109. package/dist/widgets.d.ts +7 -2
  110. package/dist/widgets.js +3 -675
  111. package/dist/widgets.js.map +1 -1
  112. package/package.json +15 -14
@@ -0,0 +1,27 @@
1
+ // src/widgets/types.ts
2
+ function toRowShape(data) {
3
+ return data.labels.map((label, i) => {
4
+ const row = { name: label };
5
+ data.datasets.forEach((ds, j) => {
6
+ row[`dataset${j}`] = ds.data[i] ?? 0;
7
+ });
8
+ return row;
9
+ });
10
+ }
11
+ var PALETTE = [
12
+ "#2563eb",
13
+ "#10b981",
14
+ "#f59e0b",
15
+ "#ef4444",
16
+ "#8b5cf6",
17
+ "#ec4899",
18
+ "#14b8a6",
19
+ "#f97316"
20
+ ];
21
+ function colorFor(dataset, index) {
22
+ return dataset.color ?? PALETTE[index % PALETTE.length] ?? "#2563eb";
23
+ }
24
+
25
+ export { colorFor, toRowShape };
26
+ //# sourceMappingURL=chunk-L3JBBN4H.js.map
27
+ //# sourceMappingURL=chunk-L3JBBN4H.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/widgets/types.ts"],"names":[],"mappings":";AA4CO,SAAS,WAAW,IAAA,EAAyD;AAClF,EAAA,OAAO,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,CAAC,OAAO,CAAA,KAAM;AACnC,IAAA,MAAM,GAAA,GAAuC,EAAE,IAAA,EAAM,KAAA,EAAM;AAC3D,IAAA,IAAA,CAAK,QAAA,CAAS,OAAA,CAAQ,CAAC,EAAA,EAAI,CAAA,KAAM;AAC/B,MAAA,GAAA,CAAI,UAAU,CAAC,CAAA,CAAE,IAAI,EAAA,CAAG,IAAA,CAAK,CAAC,CAAA,IAAK,CAAA;AAAA,IACrC,CAAC,CAAA;AACD,IAAA,OAAO,GAAA;AAAA,EACT,CAAC,CAAA;AACH;AAEA,IAAM,OAAA,GAAU;AAAA,EACd,SAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA;AACF,CAAA;AAEO,SAAS,QAAA,CAAS,SAAuB,KAAA,EAAuB;AACrE,EAAA,OAAO,QAAQ,KAAA,IAAS,OAAA,CAAQ,KAAA,GAAQ,OAAA,CAAQ,MAAM,CAAA,IAAK,SAAA;AAC7D","file":"chunk-L3JBBN4H.js","sourcesContent":["export type ChartType = 'line' | 'bar' | 'area' | 'pie' | 'donut' | 'radar';\n\nexport interface ChartDataset {\n label: string;\n data: number[];\n color?: string;\n}\n\nexport interface ChartData {\n labels: string[];\n datasets: ChartDataset[];\n}\n\nexport interface ChartWidgetProps {\n widget: {\n name: string;\n type: 'chart';\n heading?: string | undefined;\n description?: string | undefined;\n chartType: ChartType;\n chartData: ChartData;\n chartOptions?: Record<string, unknown> | undefined;\n height: number;\n showLegend: boolean;\n showGrid: boolean;\n };\n}\n\nexport interface ChartSubProps {\n chartData: ChartData;\n chartOptions?: Record<string, unknown> | undefined;\n height: number;\n showLegend: boolean;\n showGrid: boolean;\n}\n\n/**\n * Translates the PHP-side `{labels, datasets}` shape into Recharts' expected\n * row shape: `[{ name: label, dataset1: value, dataset2: value, ... }]`.\n *\n * Dataset keys are stable indices (`dataset0`, `dataset1`, ...) so chart\n * components can pair them with their human label/color via the datasets\n * array passed to `<Line dataKey=\"dataset0\" name={datasets[0].label} />`.\n */\nexport function toRowShape(data: ChartData): Array<Record<string, number | string>> {\n return data.labels.map((label, i) => {\n const row: Record<string, number | string> = { name: label };\n data.datasets.forEach((ds, j) => {\n row[`dataset${j}`] = ds.data[i] ?? 0;\n });\n return row;\n });\n}\n\nconst PALETTE = [\n '#2563eb',\n '#10b981',\n '#f59e0b',\n '#ef4444',\n '#8b5cf6',\n '#ec4899',\n '#14b8a6',\n '#f97316',\n];\n\nexport function colorFor(dataset: ChartDataset, index: number): string {\n return dataset.color ?? PALETTE[index % PALETTE.length] ?? '#2563eb';\n}\n"]}
@@ -0,0 +1,49 @@
1
+ import { PageHeader } from './chunk-MXUXMHOK.js';
2
+ import { FormActions } from './chunk-MTZJDFQ6.js';
3
+ import { FormRenderer } from './chunk-4JJS2SVS.js';
4
+ import { useArqelForm } from '@arqel-dev/hooks';
5
+ import { usePage, router } from '@inertiajs/react';
6
+ import { jsxs, jsx } from 'react/jsx-runtime';
7
+
8
+ var FALLBACK_SCHEMA = {
9
+ schema: [],
10
+ columns: 1,
11
+ model: null,
12
+ inline: false,
13
+ disabled: false
14
+ };
15
+ function ArqelCreatePage() {
16
+ const page = usePage();
17
+ const props = page.props;
18
+ const fields = props.fields ?? [];
19
+ const schema = props.form ?? FALLBACK_SCHEMA;
20
+ const form = useArqelForm({ fields });
21
+ const submit = (e) => {
22
+ e.preventDefault();
23
+ const slug = props.resource?.slug ?? "";
24
+ const basePath = props.resource?.panelPath ?? "/admin";
25
+ router.post(`${basePath}/${slug}`, form.data, {
26
+ preserveScroll: true
27
+ });
28
+ };
29
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
30
+ /* @__PURE__ */ jsx(PageHeader, { title: `Create ${props.resource?.label ?? "record"}`, description: null }),
31
+ /* @__PURE__ */ jsxs("form", { onSubmit: submit, className: "space-y-6", children: [
32
+ /* @__PURE__ */ jsx(
33
+ FormRenderer,
34
+ {
35
+ schema,
36
+ fields,
37
+ values: form.data,
38
+ onChange: (name, value) => form.setData(name, value),
39
+ errors: form.errors
40
+ }
41
+ ),
42
+ /* @__PURE__ */ jsx(FormActions, { processing: form.processing, onCancel: () => window.history.back() })
43
+ ] })
44
+ ] });
45
+ }
46
+
47
+ export { ArqelCreatePage };
48
+ //# sourceMappingURL=chunk-M6NI45DQ.js.map
49
+ //# sourceMappingURL=chunk-M6NI45DQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/pages/ArqelCreatePage.tsx"],"names":[],"mappings":";;;;;;;AAmBA,IAAM,eAAA,GAA8B;AAAA,EAClC,QAAQ,EAAC;AAAA,EACT,OAAA,EAAS,CAAA;AAAA,EACT,KAAA,EAAO,IAAA;AAAA,EACP,MAAA,EAAQ,KAAA;AAAA,EACR,QAAA,EAAU;AACZ,CAAA;AASe,SAAR,eAAA,GAAgD;AACrD,EAAA,MAAM,OAAO,OAAA,EAAQ;AACrB,EAAA,MAAM,QAAQ,IAAA,CAAK,KAAA;AACnB,EAAA,MAAM,MAAA,GAAU,KAAA,CAAM,MAAA,IAAU,EAAC;AACjC,EAAA,MAAM,MAAA,GAAU,MAA2C,IAAA,IAAQ,eAAA;AAEnE,EAAA,MAAM,IAAA,GAAO,YAAA,CAAa,EAAE,MAAA,EAAQ,CAAA;AAEpC,EAAA,MAAM,MAAA,GAAS,CAAC,CAAA,KAAuB;AACrC,IAAA,CAAA,CAAE,cAAA,EAAe;AACjB,IAAA,MAAM,IAAA,GAAO,KAAA,CAAM,QAAA,EAAU,IAAA,IAAQ,EAAA;AACrC,IAAA,MAAM,QAAA,GAAW,KAAA,CAAM,QAAA,EAAU,SAAA,IAAa,QAAA;AAC9C,IAAA,MAAA,CAAO,KAAK,CAAA,EAAG,QAAQ,IAAI,IAAI,CAAA,CAAA,EAAI,KAAK,IAAA,EAA+B;AAAA,MACrE,cAAA,EAAgB;AAAA,KACjB,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,WAAA,EACb,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,OAAO,CAAA,OAAA,EAAU,KAAA,CAAM,UAAU,KAAA,IAAS,QAAQ,CAAA,CAAA,EAAI,WAAA,EAAa,IAAA,EAAM,CAAA;AAAA,oBACrF,IAAA,CAAC,MAAA,EAAA,EAAK,QAAA,EAAU,MAAA,EAAQ,WAAU,WAAA,EAChC,QAAA,EAAA;AAAA,sBAAA,GAAA;AAAA,QAAC,YAAA;AAAA,QAAA;AAAA,UACC,MAAA;AAAA,UACA,MAAA;AAAA,UACA,QAAQ,IAAA,CAAK,IAAA;AAAA,UACb,UAAU,CAAC,IAAA,EAAM,UAAU,IAAA,CAAK,OAAA,CAAQ,MAAM,KAAK,CAAA;AAAA,UACnD,QAAQ,IAAA,CAAK;AAAA;AAAA,OACf;AAAA,sBACA,GAAA,CAAC,WAAA,EAAA,EAAY,UAAA,EAAY,IAAA,CAAK,UAAA,EAAY,UAAU,MAAM,MAAA,CAAO,OAAA,CAAQ,IAAA,EAAK,EAAG;AAAA,KAAA,EACnF;AAAA,GAAA,EACF,CAAA;AAEJ","file":"chunk-M6NI45DQ.js","sourcesContent":["/**\n * Default Inertia page for `arqel::create`.\n *\n * Renders a `<FormRenderer>` over the schema/fields the server\n * emits (with `record: null`). Submission goes through Inertia's\n * `useForm` via `useArqelForm` from `@arqel-dev/hooks` — this page is\n * just the layout shell.\n */\n\nimport { useArqelForm } from '@arqel-dev/hooks';\nimport type { FieldSchema } from '@arqel-dev/types/fields';\nimport type { FormSchema } from '@arqel-dev/types/forms';\nimport type { ResourceCreateProps } from '@arqel-dev/types/resources';\nimport { router, usePage } from '@inertiajs/react';\nimport type { FormEvent, JSX } from 'react';\nimport { FormActions } from '../form/FormActions.js';\nimport { FormRenderer } from '../form/FormRenderer.js';\nimport { PageHeader } from '../utility/PageHeader.js';\n\nconst FALLBACK_SCHEMA: FormSchema = {\n schema: [],\n columns: 1,\n model: null,\n inline: false,\n disabled: false,\n};\n\ninterface ArqelFormShape {\n data: Record<string, unknown>;\n setData: (name: string, value: unknown) => void;\n errors: Record<string, string[]>;\n processing: boolean;\n}\n\nexport default function ArqelCreatePage(): JSX.Element {\n const page = usePage();\n const props = page.props as unknown as ResourceCreateProps;\n const fields = (props.fields ?? []) as FieldSchema[];\n const schema = (props as unknown as { form?: FormSchema }).form ?? FALLBACK_SCHEMA;\n\n const form = useArqelForm({ fields }) as unknown as ArqelFormShape;\n\n const submit = (e: FormEvent): void => {\n e.preventDefault();\n const slug = props.resource?.slug ?? '';\n const basePath = props.resource?.panelPath ?? '/admin';\n router.post(`${basePath}/${slug}`, form.data as Record<string, never>, {\n preserveScroll: true,\n });\n };\n\n return (\n <div className=\"space-y-6\">\n <PageHeader title={`Create ${props.resource?.label ?? 'record'}`} description={null} />\n <form onSubmit={submit} className=\"space-y-6\">\n <FormRenderer\n schema={schema}\n fields={fields}\n values={form.data}\n onChange={(name, value) => form.setData(name, value)}\n errors={form.errors}\n />\n <FormActions processing={form.processing} onCancel={() => window.history.back()} />\n </form>\n </div>\n );\n}\n"]}
@@ -0,0 +1,92 @@
1
+ import { cn } from './chunk-B7ULUJVO.js';
2
+ import { usePage } from '@inertiajs/react';
3
+ import { jsx, jsxs } from 'react/jsx-runtime';
4
+
5
+ function Breadcrumbs(props) {
6
+ if (props.items === void 0) {
7
+ return /* @__PURE__ */ jsx(SharedBreadcrumbs, { ...props });
8
+ }
9
+ return /* @__PURE__ */ jsx(BreadcrumbsList, { ...props, items: props.items });
10
+ }
11
+ function SharedBreadcrumbs(props) {
12
+ const page = usePage();
13
+ const items = page.props.panel?.breadcrumbs ?? [];
14
+ return /* @__PURE__ */ jsx(BreadcrumbsList, { ...props, items });
15
+ }
16
+ function BreadcrumbsList({
17
+ items,
18
+ separator = /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "/" }),
19
+ className
20
+ }) {
21
+ if (items.length === 0) return null;
22
+ return /* @__PURE__ */ jsx("nav", { "aria-label": "Breadcrumb", className: cn("text-sm", className), children: /* @__PURE__ */ jsx("ol", { className: "flex flex-wrap items-center gap-2 text-muted-foreground", children: items.map((item, index) => {
23
+ const isLast = index === items.length - 1;
24
+ return /* @__PURE__ */ jsxs("li", { className: "flex items-center gap-2", children: [
25
+ isLast || !item.url ? /* @__PURE__ */ jsx("span", { "aria-current": isLast ? "page" : void 0, className: "text-foreground", children: item.label }) : /* @__PURE__ */ jsx("a", { href: item.url, className: "hover:underline", children: item.label }),
26
+ !isLast && separator
27
+ ] }, `${item.label}-${item.url ?? "leaf"}`);
28
+ }) }) });
29
+ }
30
+ function EmptyState({ title, description, icon, action, className }) {
31
+ return /* @__PURE__ */ jsxs(
32
+ "div",
33
+ {
34
+ className: cn(
35
+ "flex flex-col items-center gap-3 px-4 py-12 text-center text-muted-foreground",
36
+ className
37
+ ),
38
+ children: [
39
+ icon && /* @__PURE__ */ jsx("div", { className: "text-3xl", children: icon }),
40
+ /* @__PURE__ */ jsx("h2", { className: "text-base font-semibold text-foreground", children: title }),
41
+ description && /* @__PURE__ */ jsx("p", { className: "max-w-md text-sm", children: description }),
42
+ action && /* @__PURE__ */ jsx("div", { className: "mt-2", children: action })
43
+ ]
44
+ }
45
+ );
46
+ }
47
+ function ErrorState({ status, title, description, action, className }) {
48
+ return /* @__PURE__ */ jsxs(
49
+ "div",
50
+ {
51
+ role: "alert",
52
+ className: cn("flex flex-col items-center gap-3 px-4 py-16 text-center", className),
53
+ children: [
54
+ status && /* @__PURE__ */ jsx("span", { className: "text-sm font-mono text-muted-foreground", children: status }),
55
+ /* @__PURE__ */ jsx("h1", { className: "text-2xl font-semibold tracking-tight", children: title }),
56
+ description && /* @__PURE__ */ jsx("p", { className: "max-w-md text-sm text-muted-foreground", children: description }),
57
+ action && /* @__PURE__ */ jsx("div", { className: "mt-2", children: action })
58
+ ]
59
+ }
60
+ );
61
+ }
62
+ var VARIANT_CLASSES = {
63
+ line: "h-4 w-full",
64
+ block: "h-24 w-full",
65
+ circle: "h-10 w-10 rounded-full"
66
+ };
67
+ function LoadingSkeleton({
68
+ variant = "line",
69
+ width,
70
+ height,
71
+ count = 1,
72
+ className
73
+ }) {
74
+ const items = Array.from({ length: count }, (_, i) => i);
75
+ return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", "aria-hidden": "true", children: items.map((i) => /* @__PURE__ */ jsx(
76
+ "div",
77
+ {
78
+ style: { width, height },
79
+ className: cn(
80
+ "animate-pulse bg-muted",
81
+ variant !== "circle" && "rounded-sm",
82
+ VARIANT_CLASSES[variant],
83
+ className
84
+ )
85
+ },
86
+ i
87
+ )) });
88
+ }
89
+
90
+ export { Breadcrumbs, EmptyState, ErrorState, LoadingSkeleton };
91
+ //# sourceMappingURL=chunk-MTNFFSVA.js.map
92
+ //# sourceMappingURL=chunk-MTNFFSVA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utility/Breadcrumbs.tsx","../src/utility/EmptyState.tsx","../src/utility/ErrorState.tsx","../src/utility/LoadingSkeleton.tsx"],"names":["jsxs","jsx"],"mappings":";;;;AAgCO,SAAS,YAAY,KAAA,EAAyB;AACnD,EAAA,IAAI,KAAA,CAAM,UAAU,MAAA,EAAW;AAC7B,IAAA,uBAAO,GAAA,CAAC,iBAAA,EAAA,EAAmB,GAAG,KAAA,EAAO,CAAA;AAAA,EACvC;AACA,EAAA,2BAAQ,eAAA,EAAA,EAAiB,GAAG,KAAA,EAAO,KAAA,EAAO,MAAM,KAAA,EAAO,CAAA;AACzD;AAEA,SAAS,kBAAkB,KAAA,EAAyB;AAClD,EAAA,MAAM,OAAO,OAAA,EAAQ;AACrB,EAAA,MAAM,KAAA,GAAS,IAAA,CAAK,KAAA,CAAqC,KAAA,EAAO,eAAe,EAAC;AAChF,EAAA,uBAAO,GAAA,CAAC,eAAA,EAAA,EAAiB,GAAG,KAAA,EAAO,KAAA,EAAc,CAAA;AACnD;AAEA,SAAS,eAAA,CAAgB;AAAA,EACvB,KAAA;AAAA,EACA,SAAA,mBAAY,GAAA,CAAC,MAAA,EAAA,EAAK,aAAA,EAAY,QAAO,QAAA,EAAA,GAAA,EAAC,CAAA;AAAA,EACtC;AACF,CAAA,EAAmD;AACjD,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AAE/B,EAAA,2BACG,KAAA,EAAA,EAAI,YAAA,EAAW,YAAA,EAAa,SAAA,EAAW,GAAG,SAAA,EAAW,SAAS,CAAA,EAC7D,QAAA,kBAAA,GAAA,CAAC,QAAG,SAAA,EAAU,yDAAA,EACX,gBAAM,GAAA,CAAI,CAAC,MAAM,KAAA,KAAU;AAC1B,IAAA,MAAM,MAAA,GAAS,KAAA,KAAU,KAAA,CAAM,MAAA,GAAS,CAAA;AACxC,IAAA,uBACE,IAAA,CAAC,IAAA,EAAA,EAA+C,SAAA,EAAU,yBAAA,EACvD,QAAA,EAAA;AAAA,MAAA,MAAA,IAAU,CAAC,KAAK,GAAA,mBACf,GAAA,CAAC,UAAK,cAAA,EAAc,MAAA,GAAS,MAAA,GAAS,MAAA,EAAW,SAAA,EAAU,iBAAA,EACxD,eAAK,KAAA,EACR,CAAA,uBAEC,GAAA,EAAA,EAAE,IAAA,EAAM,KAAK,GAAA,EAAK,SAAA,EAAU,iBAAA,EAC1B,QAAA,EAAA,IAAA,CAAK,KAAA,EACR,CAAA;AAAA,MAED,CAAC,MAAA,IAAU;AAAA,KAAA,EAAA,EAVL,GAAG,IAAA,CAAK,KAAK,IAAI,IAAA,CAAK,GAAA,IAAO,MAAM,CAAA,CAW5C,CAAA;AAAA,EAEJ,CAAC,GACH,CAAA,EACF,CAAA;AAEJ;ACzDO,SAAS,WAAW,EAAE,KAAA,EAAO,aAAa,IAAA,EAAM,MAAA,EAAQ,WAAU,EAAoB;AAC3F,EAAA,uBACEA,IAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,+EAAA;AAAA,QACA;AAAA,OACF;AAAA,MAEC,QAAA,EAAA;AAAA,QAAA,IAAA,oBAAQC,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,YAAY,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,wBACzCA,GAAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,2CAA2C,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,QAC9D,+BAAeA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,oBAAoB,QAAA,EAAA,WAAA,EAAY,CAAA;AAAA,QAC5D,0BAAUA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,QAAQ,QAAA,EAAA,MAAA,EAAO;AAAA;AAAA;AAAA,GAC3C;AAEJ;ACdO,SAAS,WAAW,EAAE,MAAA,EAAQ,OAAO,WAAA,EAAa,MAAA,EAAQ,WAAU,EAAoB;AAC7F,EAAA,uBACED,IAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,OAAA;AAAA,MACL,SAAA,EAAW,EAAA,CAAG,yDAAA,EAA2D,SAAS,CAAA;AAAA,MAEjF,QAAA,EAAA;AAAA,QAAA,MAAA,oBAAUC,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,2CAA2C,QAAA,EAAA,MAAA,EAAO,CAAA;AAAA,wBAC7EA,GAAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,yCAAyC,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,QAC5D,+BAAeA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,0CAA0C,QAAA,EAAA,WAAA,EAAY,CAAA;AAAA,QAClF,0BAAUA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,QAAQ,QAAA,EAAA,MAAA,EAAO;AAAA;AAAA;AAAA,GAC3C;AAEJ;ACNA,IAAM,eAAA,GAAmD;AAAA,EACvD,IAAA,EAAM,YAAA;AAAA,EACN,KAAA,EAAO,aAAA;AAAA,EACP,MAAA,EAAQ;AACV,CAAA;AAEO,SAAS,eAAA,CAAgB;AAAA,EAC9B,OAAA,GAAU,MAAA;AAAA,EACV,KAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA,GAAQ,CAAA;AAAA,EACR;AACF,CAAA,EAAyB;AACvB,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,IAAA,CAAK,EAAE,MAAA,EAAQ,OAAM,EAAG,CAAC,CAAA,EAAG,CAAA,KAAM,CAAC,CAAA;AACvD,EAAA,uBACEA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qBAAA,EAAsB,aAAA,EAAY,MAAA,EAC9C,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,qBACVA,GAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MAEC,KAAA,EAAO,EAAE,KAAA,EAAO,MAAA,EAAO;AAAA,MACvB,SAAA,EAAW,EAAA;AAAA,QACT,wBAAA;AAAA,QACA,YAAY,QAAA,IAAY,YAAA;AAAA,QACxB,gBAAgB,OAAO,CAAA;AAAA,QACvB;AAAA;AACF,KAAA;AAAA,IAPK;AAAA,GASR,CAAA,EACH,CAAA;AAEJ","file":"chunk-MTNFFSVA.js","sourcesContent":["/**\n * `<Breadcrumbs>` — renders the panel's breadcrumb trail.\n *\n * Items can be passed explicitly, or auto-resolved from Inertia shared\n * props (`panel.breadcrumbs`, populated server-side by\n * `Arqel\\Nav\\BreadcrumbsBuilder`). Each item is a link unless it's the\n * last entry, which is rendered as plain text and marked\n * `aria-current=\"page\"`.\n *\n * `usePage()` is only invoked when `items` is omitted — explicit-items\n * usage works outside Inertia (e.g. dashboard widgets, tests).\n */\n\nimport { usePage } from '@inertiajs/react';\nimport type { ReactNode } from 'react';\nimport { cn } from '../utils/cn.js';\n\nexport interface BreadcrumbItem {\n label: string;\n url?: string | null;\n}\n\nexport interface BreadcrumbsProps {\n items?: BreadcrumbItem[];\n separator?: ReactNode;\n className?: string;\n}\n\ninterface PanelWithCrumbs {\n panel?: { breadcrumbs?: BreadcrumbItem[] } | null;\n}\n\nexport function Breadcrumbs(props: BreadcrumbsProps) {\n if (props.items === undefined) {\n return <SharedBreadcrumbs {...props} />;\n }\n return <BreadcrumbsList {...props} items={props.items} />;\n}\n\nfunction SharedBreadcrumbs(props: BreadcrumbsProps) {\n const page = usePage();\n const items = (page.props as unknown as PanelWithCrumbs).panel?.breadcrumbs ?? [];\n return <BreadcrumbsList {...props} items={items} />;\n}\n\nfunction BreadcrumbsList({\n items,\n separator = <span aria-hidden=\"true\">/</span>,\n className,\n}: BreadcrumbsProps & { items: BreadcrumbItem[] }) {\n if (items.length === 0) return null;\n\n return (\n <nav aria-label=\"Breadcrumb\" className={cn('text-sm', className)}>\n <ol className=\"flex flex-wrap items-center gap-2 text-muted-foreground\">\n {items.map((item, index) => {\n const isLast = index === items.length - 1;\n return (\n <li key={`${item.label}-${item.url ?? 'leaf'}`} className=\"flex items-center gap-2\">\n {isLast || !item.url ? (\n <span aria-current={isLast ? 'page' : undefined} className=\"text-foreground\">\n {item.label}\n </span>\n ) : (\n <a href={item.url} className=\"hover:underline\">\n {item.label}\n </a>\n )}\n {!isLast && separator}\n </li>\n );\n })}\n </ol>\n </nav>\n );\n}\n","/**\n * `<EmptyState>` — standardised empty-state block.\n *\n * Used by DataTable's empty slot and as a stand-alone fallback when\n * a resource collection has zero records.\n */\n\nimport type { ReactNode } from 'react';\nimport { cn } from '../utils/cn.js';\n\nexport interface EmptyStateProps {\n title: ReactNode;\n description?: ReactNode;\n icon?: ReactNode;\n action?: ReactNode;\n className?: string;\n}\n\nexport function EmptyState({ title, description, icon, action, className }: EmptyStateProps) {\n return (\n <div\n className={cn(\n 'flex flex-col items-center gap-3 px-4 py-12 text-center text-muted-foreground',\n className,\n )}\n >\n {icon && <div className=\"text-3xl\">{icon}</div>}\n <h2 className=\"text-base font-semibold text-foreground\">{title}</h2>\n {description && <p className=\"max-w-md text-sm\">{description}</p>}\n {action && <div className=\"mt-2\">{action}</div>}\n </div>\n );\n}\n","/**\n * `<ErrorState>` — generic error block (404 / 403 / 500).\n *\n * Phase 1 ships a plain layout; richer illustrations / Heroicons land\n * with `@arqel-dev/fields` icon registry.\n */\n\nimport type { ReactNode } from 'react';\nimport { cn } from '../utils/cn.js';\n\nexport interface ErrorStateProps {\n status?: number;\n title: ReactNode;\n description?: ReactNode;\n action?: ReactNode;\n className?: string;\n}\n\nexport function ErrorState({ status, title, description, action, className }: ErrorStateProps) {\n return (\n <div\n role=\"alert\"\n className={cn('flex flex-col items-center gap-3 px-4 py-16 text-center', className)}\n >\n {status && <span className=\"text-sm font-mono text-muted-foreground\">{status}</span>}\n <h1 className=\"text-2xl font-semibold tracking-tight\">{title}</h1>\n {description && <p className=\"max-w-md text-sm text-muted-foreground\">{description}</p>}\n {action && <div className=\"mt-2\">{action}</div>}\n </div>\n );\n}\n","/**\n * `<LoadingSkeleton>` — animated placeholder block.\n *\n * Variants:\n * - `line`: single text line (default)\n * - `block`: rectangular block (cards, hero areas)\n * - `circle`: circular (avatars)\n *\n * Heights / widths default to readable values; override via Tailwind\n * classes or explicit `height` / `width` props for bespoke layouts.\n */\n\nimport { cn } from '../utils/cn.js';\n\nexport type SkeletonVariant = 'line' | 'block' | 'circle';\n\nexport interface LoadingSkeletonProps {\n variant?: SkeletonVariant;\n width?: number | string;\n height?: number | string;\n count?: number;\n className?: string;\n}\n\nconst VARIANT_CLASSES: Record<SkeletonVariant, string> = {\n line: 'h-4 w-full',\n block: 'h-24 w-full',\n circle: 'h-10 w-10 rounded-full',\n};\n\nexport function LoadingSkeleton({\n variant = 'line',\n width,\n height,\n count = 1,\n className,\n}: LoadingSkeletonProps) {\n const items = Array.from({ length: count }, (_, i) => i);\n return (\n <div className=\"flex flex-col gap-2\" aria-hidden=\"true\">\n {items.map((i) => (\n <div\n key={i}\n style={{ width, height }}\n className={cn(\n 'animate-pulse bg-muted',\n variant !== 'circle' && 'rounded-sm',\n VARIANT_CLASSES[variant],\n className,\n )}\n />\n ))}\n </div>\n );\n}\n"]}
@@ -0,0 +1,32 @@
1
+ import { Button } from './chunk-FHRQ7PWE.js';
2
+ import { cn } from './chunk-B7ULUJVO.js';
3
+ import { jsxs, jsx } from 'react/jsx-runtime';
4
+
5
+ function FormActions({
6
+ submitLabel = "Save",
7
+ cancelLabel = "Cancel",
8
+ onCancel,
9
+ processing = false,
10
+ disabled = false,
11
+ extra,
12
+ className
13
+ }) {
14
+ return /* @__PURE__ */ jsxs(
15
+ "div",
16
+ {
17
+ className: cn(
18
+ "flex flex-wrap items-center justify-end gap-2 border-t border-border pt-4",
19
+ className
20
+ ),
21
+ children: [
22
+ extra && /* @__PURE__ */ jsx("div", { className: "mr-auto", children: extra }),
23
+ onCancel && /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", onClick: onCancel, disabled: processing, children: cancelLabel }),
24
+ /* @__PURE__ */ jsx(Button, { type: "submit", disabled: processing || disabled, children: processing ? "Saving\u2026" : submitLabel })
25
+ ]
26
+ }
27
+ );
28
+ }
29
+
30
+ export { FormActions };
31
+ //# sourceMappingURL=chunk-MTZJDFQ6.js.map
32
+ //# sourceMappingURL=chunk-MTZJDFQ6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/form/FormActions.tsx"],"names":[],"mappings":";;;;AAsBO,SAAS,WAAA,CAAY;AAAA,EAC1B,WAAA,GAAc,MAAA;AAAA,EACd,WAAA,GAAc,QAAA;AAAA,EACd,QAAA;AAAA,EACA,UAAA,GAAa,KAAA;AAAA,EACb,QAAA,GAAW,KAAA;AAAA,EACX,KAAA;AAAA,EACA;AACF,CAAA,EAAqB;AACnB,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,2EAAA;AAAA,QACA;AAAA,OACF;AAAA,MAEC,QAAA,EAAA;AAAA,QAAA,KAAA,oBAAS,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,SAAA,EAAW,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,QACzC,QAAA,oBACC,GAAA,CAAC,MAAA,EAAA,EAAO,IAAA,EAAK,QAAA,EAAS,OAAA,EAAQ,OAAA,EAAQ,OAAA,EAAS,QAAA,EAAU,QAAA,EAAU,UAAA,EAChE,QAAA,EAAA,WAAA,EACH,CAAA;AAAA,wBAEF,GAAA,CAAC,UAAO,IAAA,EAAK,QAAA,EAAS,UAAU,UAAA,IAAc,QAAA,EAC3C,QAAA,EAAA,UAAA,GAAa,cAAA,GAAY,WAAA,EAC5B;AAAA;AAAA;AAAA,GACF;AAEJ","file":"chunk-MTZJDFQ6.js","sourcesContent":["/**\n * `<FormActions>` — submit + cancel + extra slots.\n *\n * Sits at the bottom of a form. The submit button is `type=\"submit\"`\n * so wrapping a `<form>` around `<FormRenderer>` + `<FormActions>`\n * triggers the form's onSubmit naturally.\n */\n\nimport type { ReactNode } from 'react';\nimport { Button } from '../action/Button.js';\nimport { cn } from '../utils/cn.js';\n\nexport interface FormActionsProps {\n submitLabel?: string;\n cancelLabel?: string;\n onCancel?: () => void;\n processing?: boolean;\n disabled?: boolean;\n extra?: ReactNode;\n className?: string;\n}\n\nexport function FormActions({\n submitLabel = 'Save',\n cancelLabel = 'Cancel',\n onCancel,\n processing = false,\n disabled = false,\n extra,\n className,\n}: FormActionsProps) {\n return (\n <div\n className={cn(\n 'flex flex-wrap items-center justify-end gap-2 border-t border-border pt-4',\n className,\n )}\n >\n {extra && <div className=\"mr-auto\">{extra}</div>}\n {onCancel && (\n <Button type=\"button\" variant=\"ghost\" onClick={onCancel} disabled={processing}>\n {cancelLabel}\n </Button>\n )}\n <Button type=\"submit\" disabled={processing || disabled}>\n {processing ? 'Saving…' : submitLabel}\n </Button>\n </div>\n );\n}\n"]}
@@ -0,0 +1,16 @@
1
+ import { cn } from './chunk-B7ULUJVO.js';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+
4
+ function PageHeader({ title, description, actions, className }) {
5
+ return /* @__PURE__ */ jsxs("header", { className: cn("flex flex-wrap items-start gap-4", className), children: [
6
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
7
+ /* @__PURE__ */ jsx("h1", { className: "text-2xl font-semibold tracking-tight", children: title }),
8
+ description && /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: description })
9
+ ] }),
10
+ actions && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-2", children: actions })
11
+ ] });
12
+ }
13
+
14
+ export { PageHeader };
15
+ //# sourceMappingURL=chunk-MXUXMHOK.js.map
16
+ //# sourceMappingURL=chunk-MXUXMHOK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utility/PageHeader.tsx"],"names":[],"mappings":";;;AAiBO,SAAS,WAAW,EAAE,KAAA,EAAO,WAAA,EAAa,OAAA,EAAS,WAAU,EAAoB;AACtF,EAAA,4BACG,QAAA,EAAA,EAAO,SAAA,EAAW,EAAA,CAAG,kCAAA,EAAoC,SAAS,CAAA,EACjE,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,gBAAA,EACb,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,uCAAA,EAAyC,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,MAC5D,WAAA,oBAAe,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,sCAAsC,QAAA,EAAA,WAAA,EAAY;AAAA,KAAA,EACjF,CAAA;AAAA,IACC,OAAA,oBAAW,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qCAAqC,QAAA,EAAA,OAAA,EAAQ;AAAA,GAAA,EAC1E,CAAA;AAEJ","file":"chunk-MXUXMHOK.js","sourcesContent":["/**\n * `<PageHeader>` — title + optional description + action slot.\n *\n * Used at the top of Resource pages right under `<Breadcrumbs>`. Pass\n * `actions` to render a row of buttons aligned right.\n */\n\nimport type { ReactNode } from 'react';\nimport { cn } from '../utils/cn.js';\n\nexport interface PageHeaderProps {\n title: ReactNode;\n description?: ReactNode;\n actions?: ReactNode;\n className?: string;\n}\n\nexport function PageHeader({ title, description, actions, className }: PageHeaderProps) {\n return (\n <header className={cn('flex flex-wrap items-start gap-4', className)}>\n <div className=\"min-w-0 flex-1\">\n <h1 className=\"text-2xl font-semibold tracking-tight\">{title}</h1>\n {description && <p className=\"mt-1 text-sm text-muted-foreground\">{description}</p>}\n </div>\n {actions && <div className=\"flex flex-wrap items-center gap-2\">{actions}</div>}\n </header>\n );\n}\n"]}
@@ -0,0 +1,35 @@
1
+ import { DashboardGrid } from './chunk-47HD7ALI.js';
2
+ import { usePage, router } from '@inertiajs/react';
3
+ import { jsx } from 'react/jsx-runtime';
4
+
5
+ function ArqelDashboardPage() {
6
+ const { dashboard, filterValues } = usePage().props;
7
+ const handleFilterChange = (name, value) => {
8
+ const current = filterValues ?? {};
9
+ const next = { ...current };
10
+ if (value === void 0 || value === null || value === "") {
11
+ delete next[name];
12
+ } else {
13
+ next[name] = value;
14
+ }
15
+ const path = dashboard.path ?? `/admin/dashboards/${dashboard.id}`;
16
+ const params = Object.keys(next).length > 0 ? { filters: next } : {};
17
+ router.get(path, params, {
18
+ preserveState: true,
19
+ preserveScroll: true,
20
+ replace: true
21
+ });
22
+ };
23
+ return /* @__PURE__ */ jsx(
24
+ DashboardGrid,
25
+ {
26
+ dashboard,
27
+ filterValues: filterValues ?? {},
28
+ onFilterChange: handleFilterChange
29
+ }
30
+ );
31
+ }
32
+
33
+ export { ArqelDashboardPage };
34
+ //# sourceMappingURL=chunk-PXON56HL.js.map
35
+ //# sourceMappingURL=chunk-PXON56HL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/pages/ArqelDashboardPage.tsx"],"names":[],"mappings":";;;;AA0Be,SAAR,kBAAA,GAAmD;AACxD,EAAA,MAAM,EAAE,SAAA,EAAW,YAAA,EAAa,GAAI,SAAiC,CAAE,KAAA;AAEvE,EAAA,MAAM,kBAAA,GAAqB,CAAC,IAAA,EAAc,KAAA,KAAyB;AACjE,IAAA,MAAM,OAAA,GAAU,gBAAgB,EAAC;AACjC,IAAA,MAAM,IAAA,GAAgC,EAAE,GAAG,OAAA,EAAQ;AACnD,IAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA,IAAQ,UAAU,EAAA,EAAI;AACzD,MAAA,OAAO,KAAK,IAAI,CAAA;AAAA,IAClB,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,IAAI,CAAA,GAAI,KAAA;AAAA,IACf;AAEA,IAAA,MAAM,IAAA,GAAO,SAAA,CAAU,IAAA,IAAQ,CAAA,kBAAA,EAAqB,UAAU,EAAE,CAAA,CAAA;AAChE,IAAA,MAAM,MAAA,GAAU,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,CAAE,MAAA,GAAS,CAAA,GAAI,EAAE,OAAA,EAAS,IAAA,EAAK,GAAI,EAAC;AAEpE,IAAA,MAAA,CAAO,GAAA,CAAI,MAAM,MAAA,EAAQ;AAAA,MACvB,aAAA,EAAe,IAAA;AAAA,MACf,cAAA,EAAgB,IAAA;AAAA,MAChB,OAAA,EAAS;AAAA,KACV,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,aAAA;AAAA,IAAA;AAAA,MACC,SAAA;AAAA,MACA,YAAA,EAAc,gBAAgB,EAAC;AAAA,MAC/B,cAAA,EAAgB;AAAA;AAAA,GAClB;AAEJ","file":"chunk-PXON56HL.js","sourcesContent":["/**\n * Default Inertia page for `arqel::dashboard`.\n *\n * Bridges the Inertia payload emitted by\n * `Arqel\\Widgets\\Http\\Controllers\\DashboardController::show` into the\n * existing `<DashboardGrid>` component. The grid already handles the\n * heading/description chrome, the filter bar and the responsive\n * widget grid (column spans, polling, deferred fetch), so this page\n * only owns one piece of glue: lifting filter state up into the URL\n * so deep-link refreshes rehydrate cleanly.\n *\n * Filter changes navigate via `router.get(path, { filters: ... })`,\n * matching `DashboardController::show` which reads\n * `$request->input('filters', [])` and forwards it as `filterValues`.\n */\n\nimport { router, usePage } from '@inertiajs/react';\nimport type { JSX } from 'react';\nimport { DashboardGrid, type DashboardPayload } from '../widgets/index.js';\n\ninterface ArqelDashboardPageProps {\n dashboard: DashboardPayload;\n filterValues?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\nexport default function ArqelDashboardPage(): JSX.Element {\n const { dashboard, filterValues } = usePage<ArqelDashboardPageProps>().props;\n\n const handleFilterChange = (name: string, value: unknown): void => {\n const current = filterValues ?? {};\n const next: Record<string, unknown> = { ...current };\n if (value === undefined || value === null || value === '') {\n delete next[name];\n } else {\n next[name] = value;\n }\n\n const path = dashboard.path ?? `/admin/dashboards/${dashboard.id}`;\n const params = (Object.keys(next).length > 0 ? { filters: next } : {}) as never;\n\n router.get(path, params, {\n preserveState: true,\n preserveScroll: true,\n replace: true,\n });\n };\n\n return (\n <DashboardGrid\n dashboard={dashboard}\n filterValues={filterValues ?? {}}\n onFilterChange={handleFilterChange}\n />\n );\n}\n"]}