@arqel-dev/ui 0.15.0 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/{AreaChart-NMQ2RQGA.js → AreaChart-JAZ6LUYG.js} +8 -4
- package/dist/AreaChart-JAZ6LUYG.js.map +1 -0
- package/dist/ArqelCreatePage-UZAHV4DK.js +8 -0
- package/dist/{ArqelCreatePage-MV4JN2MO.js.map → ArqelCreatePage-UZAHV4DK.js.map} +1 -1
- package/dist/ArqelDashboardPage-Z5R4XSH4.js +6 -0
- package/dist/{ArqelDashboardPage-QK3BYVK3.js.map → ArqelDashboardPage-Z5R4XSH4.js.map} +1 -1
- package/dist/ArqelEditPage-RRYFYOTC.js +8 -0
- package/dist/{ArqelShowPage-5WWUSYC7.js.map → ArqelEditPage-RRYFYOTC.js.map} +1 -1
- package/dist/ArqelIndexPage-RGZWKKAX.js +12 -0
- package/dist/{ArqelIndexPage-R6JL5KOH.js.map → ArqelIndexPage-RGZWKKAX.js.map} +1 -1
- package/dist/ArqelShowPage-TVCJAV2F.js +6 -0
- package/dist/{ArqelEditPage-7J3IS2BR.js.map → ArqelShowPage-TVCJAV2F.js.map} +1 -1
- package/dist/{BarChart-KLHKTLO2.js → BarChart-E52NJSJE.js} +8 -4
- package/dist/BarChart-E52NJSJE.js.map +1 -0
- package/dist/{DonutChart-L56R4QF2.js → DonutChart-IGSF4LEB.js} +3 -3
- package/dist/{DonutChart-L56R4QF2.js.map → DonutChart-IGSF4LEB.js.map} +1 -1
- package/dist/{FormRenderer-BJBRIkfH.d.ts → FormRenderer-By8fZp4t.d.ts} +2 -0
- package/dist/{LineChart-GHMPHFZZ.js → LineChart-RRPGAZON.js} +8 -4
- package/dist/LineChart-RRPGAZON.js.map +1 -0
- package/dist/PieChart-SGN7V5LQ.js +4 -0
- package/dist/{PieChart-T2VQOFPP.js.map → PieChart-SGN7V5LQ.js.map} +1 -1
- package/dist/{RadarChart-CSWR5AO7.js → RadarChart-3AOM736J.js} +8 -4
- package/dist/RadarChart-3AOM736J.js.map +1 -0
- package/dist/action.js +2 -2
- package/dist/{chunk-FP5R6WED.js → chunk-2JUWLJ3K.js} +21 -13
- package/dist/chunk-2JUWLJ3K.js.map +1 -0
- package/dist/{chunk-BJER6TOI.js → chunk-3VSDQCFO.js} +3 -3
- package/dist/{chunk-BJER6TOI.js.map → chunk-3VSDQCFO.js.map} +1 -1
- package/dist/{chunk-N5U2BB6T.js → chunk-4VWNBMMA.js} +8 -6
- package/dist/chunk-4VWNBMMA.js.map +1 -0
- package/dist/{chunk-ZAM5TUPP.js → chunk-CMNZLA32.js} +60 -25
- package/dist/chunk-CMNZLA32.js.map +1 -0
- package/dist/{chunk-CVAMCRLL.js → chunk-EG2DASKR.js} +8 -4
- package/dist/chunk-EG2DASKR.js.map +1 -0
- package/dist/{chunk-DSULVRB6.js → chunk-GJ2FKAOM.js} +5 -3
- package/dist/chunk-GJ2FKAOM.js.map +1 -0
- package/dist/{chunk-FV7RESKL.js → chunk-HNUUZEOL.js} +28 -16
- package/dist/chunk-HNUUZEOL.js.map +1 -0
- package/dist/{chunk-37FLEB4N.js → chunk-IO6RMVUF.js} +8 -4
- package/dist/chunk-IO6RMVUF.js.map +1 -0
- package/dist/{chunk-4I5S6MH3.js → chunk-LLANMODS.js} +4 -4
- package/dist/{chunk-4I5S6MH3.js.map → chunk-LLANMODS.js.map} +1 -1
- package/dist/{chunk-N6WLCHQE.js → chunk-Q7WGPKUN.js} +6 -4
- package/dist/chunk-Q7WGPKUN.js.map +1 -0
- package/dist/{chunk-AZICSFBA.js → chunk-S5UNPCMQ.js} +112 -38
- package/dist/chunk-S5UNPCMQ.js.map +1 -0
- package/dist/{chunk-MTNFFSVA.js → chunk-SK6H7ARE.js} +5 -3
- package/dist/chunk-SK6H7ARE.js.map +1 -0
- package/dist/{chunk-PSPJA5U6.js → chunk-WMOBLT3Z.js} +10 -5
- package/dist/chunk-WMOBLT3Z.js.map +1 -0
- package/dist/{chunk-C5H44NSP.js → chunk-WZRPGPLH.js} +10 -5
- package/dist/chunk-WZRPGPLH.js.map +1 -0
- package/dist/{chunk-UXN67E5L.js → chunk-YQ6KXR3U.js} +8 -10
- package/dist/chunk-YQ6KXR3U.js.map +1 -0
- package/dist/{chunk-HSDZM4AM.js → chunk-YYQ45W25.js} +37 -24
- package/dist/chunk-YYQ45W25.js.map +1 -0
- package/dist/flash.js +1 -1
- package/dist/form.d.ts +3 -1
- package/dist/form.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +9 -9
- package/dist/pages.js +16 -16
- package/dist/palette.js +1 -1
- package/dist/resource.js +2 -2
- package/dist/shell.js +8 -4
- package/dist/shell.js.map +1 -1
- package/dist/table.js +1 -1
- package/dist/utility.js +1 -1
- package/dist/widgets.js +2 -2
- package/package.json +6 -6
- package/dist/AreaChart-NMQ2RQGA.js.map +0 -1
- package/dist/ArqelCreatePage-MV4JN2MO.js +0 -8
- package/dist/ArqelDashboardPage-QK3BYVK3.js +0 -6
- package/dist/ArqelEditPage-7J3IS2BR.js +0 -8
- package/dist/ArqelIndexPage-R6JL5KOH.js +0 -12
- package/dist/ArqelShowPage-5WWUSYC7.js +0 -6
- package/dist/BarChart-KLHKTLO2.js.map +0 -1
- package/dist/LineChart-GHMPHFZZ.js.map +0 -1
- package/dist/PieChart-T2VQOFPP.js +0 -4
- package/dist/RadarChart-CSWR5AO7.js.map +0 -1
- package/dist/chunk-37FLEB4N.js.map +0 -1
- package/dist/chunk-AZICSFBA.js.map +0 -1
- package/dist/chunk-C5H44NSP.js.map +0 -1
- package/dist/chunk-CVAMCRLL.js.map +0 -1
- package/dist/chunk-DSULVRB6.js.map +0 -1
- package/dist/chunk-FP5R6WED.js.map +0 -1
- package/dist/chunk-FV7RESKL.js.map +0 -1
- package/dist/chunk-HSDZM4AM.js.map +0 -1
- package/dist/chunk-MTNFFSVA.js.map +0 -1
- package/dist/chunk-N5U2BB6T.js.map +0 -1
- package/dist/chunk-N6WLCHQE.js.map +0 -1
- package/dist/chunk-PSPJA5U6.js.map +0 -1
- package/dist/chunk-UXN67E5L.js.map +0 -1
- package/dist/chunk-ZAM5TUPP.js.map +0 -1
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { colorFor } from './chunk-L3JBBN4H.js';
|
|
2
|
+
import { useArqelLocale, useArqelTranslations } from '@arqel-dev/react/utils';
|
|
3
|
+
import { useMemo } from 'react';
|
|
2
4
|
import { ResponsiveContainer, PieChart as PieChart$1, Pie, Cell, Tooltip, Legend } from 'recharts';
|
|
3
5
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
4
6
|
|
|
@@ -9,9 +11,12 @@ function PieChart({
|
|
|
9
11
|
innerRadius = 0,
|
|
10
12
|
testId = "chart-pie"
|
|
11
13
|
}) {
|
|
14
|
+
const locale = useArqelLocale();
|
|
15
|
+
const t = useArqelTranslations();
|
|
16
|
+
const nf = useMemo(() => new Intl.NumberFormat(locale), [locale]);
|
|
12
17
|
const first = chartData.datasets[0];
|
|
13
18
|
const slices = (first?.data ?? []).map((value, i) => ({
|
|
14
|
-
name: chartData.labels[i] ??
|
|
19
|
+
name: chartData.labels[i] ?? t("arqel.chart.slice_fallback", "Slice :number", { number: i + 1 }),
|
|
15
20
|
value
|
|
16
21
|
}));
|
|
17
22
|
return /* @__PURE__ */ jsx("div", { "data-testid": testId, style: { width: "100%", height }, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(PieChart$1, { children: [
|
|
@@ -23,15 +28,15 @@ function PieChart({
|
|
|
23
28
|
nameKey: "name",
|
|
24
29
|
innerRadius,
|
|
25
30
|
outerRadius: "80%",
|
|
26
|
-
label:
|
|
31
|
+
label: (entry) => nf.format(Number(entry.value)),
|
|
27
32
|
children: slices.map((slice, i) => /* @__PURE__ */ jsx(Cell, { fill: colorFor(first ?? { label: "", data: [] }, i) }, slice.name))
|
|
28
33
|
}
|
|
29
34
|
),
|
|
30
|
-
/* @__PURE__ */ jsx(Tooltip, {}),
|
|
35
|
+
/* @__PURE__ */ jsx(Tooltip, { formatter: (v) => nf.format(Number(v)) }),
|
|
31
36
|
showLegend ? /* @__PURE__ */ jsx(Legend, {}) : null
|
|
32
37
|
] }) }) });
|
|
33
38
|
}
|
|
34
39
|
|
|
35
40
|
export { PieChart };
|
|
36
|
-
//# sourceMappingURL=chunk-
|
|
37
|
-
//# sourceMappingURL=chunk-
|
|
41
|
+
//# sourceMappingURL=chunk-WZRPGPLH.js.map
|
|
42
|
+
//# sourceMappingURL=chunk-WZRPGPLH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/widgets/charts/PieChart.tsx"],"names":["RechartsPieChart"],"mappings":";;;;;;AAiBO,SAAS,QAAA,CAAS;AAAA,EACvB,SAAA;AAAA,EACA,MAAA;AAAA,EACA,UAAA;AAAA,EACA,WAAA,GAAc,CAAA;AAAA,EACd,MAAA,GAAS;AACX,CAAA,EAAkB;AAChB,EAAA,MAAM,SAAS,cAAA,EAAe;AAC9B,EAAA,MAAM,IAAI,oBAAA,EAAqB;AAC/B,EAAA,MAAM,EAAA,GAAK,OAAA,CAAQ,MAAM,IAAI,IAAA,CAAK,aAAa,MAAM,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAChE,EAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,QAAA,CAAS,CAAC,CAAA;AAClC,EAAA,MAAM,MAAA,GAAA,CAAU,OAAO,IAAA,IAAQ,IAAI,GAAA,CAAI,CAAC,OAAO,CAAA,MAAO;AAAA,IACpD,IAAA,EACE,SAAA,CAAU,MAAA,CAAO,CAAC,CAAA,IAAK,CAAA,CAAE,4BAAA,EAA8B,eAAA,EAAiB,EAAE,MAAA,EAAQ,CAAA,GAAI,CAAA,EAAG,CAAA;AAAA,IAC3F;AAAA,GACF,CAAE,CAAA;AAEF,EAAA,2BACG,KAAA,EAAA,EAAI,aAAA,EAAa,MAAA,EAAQ,KAAA,EAAO,EAAE,KAAA,EAAO,MAAA,EAAQ,MAAA,EAAO,EACvD,8BAAC,mBAAA,EAAA,EAAoB,KAAA,EAAM,QAAO,MAAA,EAAO,MAAA,EACvC,+BAACA,UAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,GAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAM,MAAA;AAAA,QACN,OAAA,EAAQ,OAAA;AAAA,QACR,OAAA,EAAQ,MAAA;AAAA,QACR,WAAA;AAAA,QACA,WAAA,EAAY,KAAA;AAAA,QACZ,KAAA,EAAO,CAAC,KAAA,KAAU,EAAA,CAAG,OAAO,MAAA,CAAO,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,QAE9C,QAAA,EAAA,MAAA,CAAO,IAAI,CAAC,KAAA,EAAO,sBAClB,GAAA,CAAC,IAAA,EAAA,EAAsB,MAAM,QAAA,CAAS,KAAA,IAAS,EAAE,KAAA,EAAO,EAAA,EAAI,MAAM,EAAC,IAAK,CAAC,CAAA,EAAA,EAA9D,KAAA,CAAM,IAA2D,CAC7E;AAAA;AAAA,KACH;AAAA,oBACA,GAAA,CAAC,OAAA,EAAA,EAAQ,SAAA,EAAW,CAAC,CAAA,KAAM,GAAG,MAAA,CAAO,MAAA,CAAO,CAAC,CAAC,CAAA,EAAG,CAAA;AAAA,IAChD,UAAA,mBAAa,GAAA,CAAC,MAAA,EAAA,EAAO,CAAA,GAAK;AAAA,GAAA,EAC7B,GACF,CAAA,EACF,CAAA;AAEJ","file":"chunk-WZRPGPLH.js","sourcesContent":["import { useArqelLocale, useArqelTranslations } from '@arqel-dev/react/utils';\nimport { useMemo } from 'react';\nimport {\n Cell,\n Legend,\n Pie,\n PieChart as RechartsPieChart,\n ResponsiveContainer,\n Tooltip,\n} from 'recharts';\nimport { type ChartSubProps, colorFor } from '../types';\n\nexport interface PieChartProps extends ChartSubProps {\n innerRadius?: number | undefined;\n testId?: string | undefined;\n}\n\nexport function PieChart({\n chartData,\n height,\n showLegend,\n innerRadius = 0,\n testId = 'chart-pie',\n}: PieChartProps) {\n const locale = useArqelLocale();\n const t = useArqelTranslations();\n const nf = useMemo(() => new Intl.NumberFormat(locale), [locale]);\n const first = chartData.datasets[0];\n const slices = (first?.data ?? []).map((value, i) => ({\n name:\n chartData.labels[i] ?? t('arqel.chart.slice_fallback', 'Slice :number', { number: i + 1 }),\n value,\n }));\n\n return (\n <div data-testid={testId} style={{ width: '100%', height }}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsPieChart>\n <Pie\n data={slices}\n dataKey=\"value\"\n nameKey=\"name\"\n innerRadius={innerRadius}\n outerRadius=\"80%\"\n label={(entry) => nf.format(Number(entry.value))}\n >\n {slices.map((slice, i) => (\n <Cell key={slice.name} fill={colorFor(first ?? { label: '', data: [] }, i)} />\n ))}\n </Pie>\n <Tooltip formatter={(v) => nf.format(Number(v))} />\n {showLegend ? <Legend /> : null}\n </RechartsPieChart>\n </ResponsiveContainer>\n </div>\n );\n}\n"]}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { PageHeader } from './chunk-MXUXMHOK.js';
|
|
2
2
|
import { FormActions } from './chunk-MZMYV43C.js';
|
|
3
|
-
import { FormRenderer } from './chunk-
|
|
3
|
+
import { FormRenderer } from './chunk-CMNZLA32.js';
|
|
4
4
|
import { useArqelForm } from '@arqel-dev/hooks';
|
|
5
|
+
import { useArqelTranslations } from '@arqel-dev/react/utils';
|
|
5
6
|
import { usePage, router } from '@inertiajs/react';
|
|
6
7
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
7
8
|
|
|
@@ -14,6 +15,7 @@ var FALLBACK_SCHEMA = {
|
|
|
14
15
|
};
|
|
15
16
|
function ArqelEditPage() {
|
|
16
17
|
const page = usePage();
|
|
18
|
+
const t = useArqelTranslations();
|
|
17
19
|
const props = page.props;
|
|
18
20
|
const fields = props.fields ?? [];
|
|
19
21
|
const record = props.record;
|
|
@@ -28,14 +30,10 @@ function ArqelEditPage() {
|
|
|
28
30
|
preserveScroll: true
|
|
29
31
|
});
|
|
30
32
|
};
|
|
33
|
+
const label = props.resource?.label ?? t("arqel.pages.fallback", "record");
|
|
34
|
+
const editTitle = props.recordTitle ?? t("arqel.pages.edit", `Edit ${label}`, { label });
|
|
31
35
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
32
|
-
/* @__PURE__ */ jsx(
|
|
33
|
-
PageHeader,
|
|
34
|
-
{
|
|
35
|
-
title: props.recordTitle ?? `Edit ${props.resource?.label ?? "record"}`,
|
|
36
|
-
description: props.recordSubtitle ?? null
|
|
37
|
-
}
|
|
38
|
-
),
|
|
36
|
+
/* @__PURE__ */ jsx(PageHeader, { title: editTitle, description: props.recordSubtitle ?? null }),
|
|
39
37
|
/* @__PURE__ */ jsxs("form", { onSubmit: submit, className: "space-y-6", children: [
|
|
40
38
|
/* @__PURE__ */ jsx(
|
|
41
39
|
FormRenderer,
|
|
@@ -53,5 +51,5 @@ function ArqelEditPage() {
|
|
|
53
51
|
}
|
|
54
52
|
|
|
55
53
|
export { ArqelEditPage };
|
|
56
|
-
//# sourceMappingURL=chunk-
|
|
57
|
-
//# sourceMappingURL=chunk-
|
|
54
|
+
//# sourceMappingURL=chunk-YQ6KXR3U.js.map
|
|
55
|
+
//# sourceMappingURL=chunk-YQ6KXR3U.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/pages/ArqelEditPage.tsx"],"names":[],"mappings":";;;;;;;;AAkBA,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,aAAA,GAAuF;AAC5F,EAAA,MAAM,OAAO,OAAA,EAAQ;AACrB,EAAA,MAAM,IAAI,oBAAA,EAAqB;AAC/B,EAAA,MAAM,QAAQ,IAAA,CAAK,KAAA;AACnB,EAAA,MAAM,MAAA,GAAU,KAAA,CAAM,MAAA,IAAU,EAAC;AACjC,EAAA,MAAM,SAAS,KAAA,CAAM,MAAA;AACrB,EAAA,MAAM,MAAA,GAAU,MAA2C,IAAA,IAAQ,eAAA;AAEnE,EAAA,MAAM,IAAA,GAAO,YAAA,CAAa,EAAE,MAAA,EAAQ,QAAQ,CAAA;AAE5C,EAAA,MAAM,MAAA,GAAS,CAAC,CAAA,KAAuB;AACrC,IAAA,CAAA,CAAE,cAAA,EAAe;AACjB,IAAA,MAAM,EAAA,GAAK,MAAA,CAAQ,MAAA,EAAiD,EAAA,IAAM,EAAE,CAAA;AAC5E,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,GAAA,CAAI,GAAG,QAAQ,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,EAAI,EAAE,CAAA,CAAA,EAAI,IAAA,CAAK,IAAA,EAA+B;AAAA,MAC1E,cAAA,EAAgB;AAAA,KACjB,CAAA;AAAA,EACH,CAAA;AAKA,EAAA,MAAM,QAAQ,KAAA,CAAM,QAAA,EAAU,KAAA,IAAS,CAAA,CAAE,wBAAwB,QAAQ,CAAA;AACzE,EAAA,MAAM,SAAA,GAAY,KAAA,CAAM,WAAA,IAAe,CAAA,CAAE,kBAAA,EAAoB,QAAQ,KAAK,CAAA,CAAA,EAAI,EAAE,KAAA,EAAO,CAAA;AAEvF,EAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,WAAA,EACb,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,cAAW,KAAA,EAAO,SAAA,EAAW,WAAA,EAAa,KAAA,CAAM,kBAAkB,IAAA,EAAM,CAAA;AAAA,oBACzE,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-YQ6KXR3U.js","sourcesContent":["/**\n * Default Inertia page for `arqel::edit`.\n *\n * Same shape as `ArqelCreatePage` but seeds the form with the\n * server-emitted `record`. Submission posts to PUT `/{slug}/{id}`.\n */\n\nimport { useArqelForm } from '@arqel-dev/hooks';\nimport { useArqelTranslations } from '@arqel-dev/react/utils';\nimport type { FieldSchema } from '@arqel-dev/types/fields';\nimport type { FormSchema } from '@arqel-dev/types/forms';\nimport type { RecordType, ResourceEditProps } 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 ArqelEditPage<TRecord extends RecordType = RecordType>(): JSX.Element {\n const page = usePage();\n const t = useArqelTranslations();\n const props = page.props as unknown as ResourceEditProps<TRecord>;\n const fields = (props.fields ?? []) as FieldSchema[];\n const record = props.record;\n const schema = (props as unknown as { form?: FormSchema }).form ?? FALLBACK_SCHEMA;\n\n const form = useArqelForm({ fields, record }) as unknown as ArqelFormShape;\n\n const submit = (e: FormEvent): void => {\n e.preventDefault();\n const id = String((record as { id?: string | number } | undefined)?.id ?? '');\n const slug = props.resource?.slug ?? '';\n const basePath = props.resource?.panelPath ?? '/admin';\n router.put(`${basePath}/${slug}/${id}`, form.data as Record<string, never>, {\n preserveScroll: true,\n });\n };\n\n // Pre-interpolate the label into the English fallback so the title stays\n // correct even when the `arqel.pages.edit` key is absent from the shared\n // dictionary (the hook does not re-interpolate a raw fallback).\n const label = props.resource?.label ?? t('arqel.pages.fallback', 'record');\n const editTitle = props.recordTitle ?? t('arqel.pages.edit', `Edit ${label}`, { label });\n\n return (\n <div className=\"space-y-6\">\n <PageHeader title={editTitle} description={props.recordSubtitle ?? 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"]}
|
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import { WidgetWrapper, StatCard } from './chunk-
|
|
1
|
+
import { WidgetWrapper, StatCard } from './chunk-WMOBLT3Z.js';
|
|
2
2
|
import { cn } from './chunk-B7ULUJVO.js';
|
|
3
|
-
import {
|
|
3
|
+
import { useArqelTranslations, useArqelLocale } from '@arqel-dev/react/utils';
|
|
4
|
+
import { lazy, Suspense, useMemo, useState, useRef, useEffect } from 'react';
|
|
4
5
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
5
6
|
|
|
6
|
-
var LineChart = lazy(() => import('./LineChart-
|
|
7
|
-
var BarChart = lazy(() => import('./BarChart-
|
|
8
|
-
var AreaChart = lazy(() => import('./AreaChart-
|
|
9
|
-
var PieChart = lazy(() => import('./PieChart-
|
|
7
|
+
var LineChart = lazy(() => import('./LineChart-RRPGAZON.js').then((m) => ({ default: m.LineChart })));
|
|
8
|
+
var BarChart = lazy(() => import('./BarChart-E52NJSJE.js').then((m) => ({ default: m.BarChart })));
|
|
9
|
+
var AreaChart = lazy(() => import('./AreaChart-JAZ6LUYG.js').then((m) => ({ default: m.AreaChart })));
|
|
10
|
+
var PieChart = lazy(() => import('./PieChart-SGN7V5LQ.js').then((m) => ({ default: m.PieChart })));
|
|
10
11
|
var DonutChart = lazy(
|
|
11
|
-
() => import('./DonutChart-
|
|
12
|
+
() => import('./DonutChart-IGSF4LEB.js').then((m) => ({ default: m.DonutChart }))
|
|
12
13
|
);
|
|
13
14
|
var RadarChart = lazy(
|
|
14
|
-
() => import('./RadarChart-
|
|
15
|
+
() => import('./RadarChart-3AOM736J.js').then((m) => ({ default: m.RadarChart }))
|
|
15
16
|
);
|
|
16
17
|
var REGISTRY = {
|
|
17
18
|
line: LineChart,
|
|
@@ -22,6 +23,7 @@ var REGISTRY = {
|
|
|
22
23
|
radar: RadarChart
|
|
23
24
|
};
|
|
24
25
|
function ChartCard({ widget }) {
|
|
26
|
+
const t = useArqelTranslations();
|
|
25
27
|
const Chart = REGISTRY[widget.chartType] ?? LineChart;
|
|
26
28
|
return /* @__PURE__ */ jsx(WidgetWrapper, { heading: widget.heading, description: widget.description, children: /* @__PURE__ */ jsx(
|
|
27
29
|
Suspense,
|
|
@@ -30,7 +32,7 @@ function ChartCard({ widget }) {
|
|
|
30
32
|
"div",
|
|
31
33
|
{
|
|
32
34
|
role: "status",
|
|
33
|
-
"aria-label": "Loading chart",
|
|
35
|
+
"aria-label": t("arqel.aria.chart_loading", "Loading chart"),
|
|
34
36
|
"data-testid": "chart-fallback",
|
|
35
37
|
className: "animate-pulse rounded bg-muted",
|
|
36
38
|
style: { height: widget.height }
|
|
@@ -100,6 +102,7 @@ function SelectControl({
|
|
|
100
102
|
value,
|
|
101
103
|
onChange
|
|
102
104
|
}) {
|
|
105
|
+
const t = useArqelTranslations();
|
|
103
106
|
const options = normaliseOptions(filter.options);
|
|
104
107
|
const label = filter.label ?? filter.name;
|
|
105
108
|
if (filter.multiple) {
|
|
@@ -132,7 +135,7 @@ function SelectControl({
|
|
|
132
135
|
value: value === void 0 || value === null ? "" : String(value),
|
|
133
136
|
onChange: (e) => onChange(e.target.value === "" ? null : e.target.value),
|
|
134
137
|
children: [
|
|
135
|
-
/* @__PURE__ */ jsx("option", { value: "", children: "All" }),
|
|
138
|
+
/* @__PURE__ */ jsx("option", { value: "", children: t("table.filters.all", "All") }),
|
|
136
139
|
options.map((opt) => /* @__PURE__ */ jsx("option", { value: opt.value, children: opt.label }, opt.value))
|
|
137
140
|
]
|
|
138
141
|
}
|
|
@@ -144,17 +147,19 @@ function DateRangeControl({
|
|
|
144
147
|
value,
|
|
145
148
|
onChange
|
|
146
149
|
}) {
|
|
150
|
+
const t = useArqelTranslations();
|
|
151
|
+
const label = filter.label ?? filter.name;
|
|
147
152
|
const range = value && typeof value === "object" ? value : {};
|
|
148
153
|
const fromValue = typeof range.from === "string" ? range.from : "";
|
|
149
154
|
const toValue = typeof range.to === "string" ? range.to : "";
|
|
150
155
|
return /* @__PURE__ */ jsxs("fieldset", { className: "flex flex-col gap-1 text-xs text-muted-foreground", children: [
|
|
151
|
-
/* @__PURE__ */ jsx("legend", { children:
|
|
156
|
+
/* @__PURE__ */ jsx("legend", { children: label }),
|
|
152
157
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
153
158
|
/* @__PURE__ */ jsx(
|
|
154
159
|
"input",
|
|
155
160
|
{
|
|
156
161
|
type: "date",
|
|
157
|
-
"aria-label": `${
|
|
162
|
+
"aria-label": t("table.filters.date_from", `${label} from`, { label }),
|
|
158
163
|
className: controlClasses(),
|
|
159
164
|
value: fromValue,
|
|
160
165
|
onChange: (e) => onChange({ from: e.target.value || null, to: range.to ?? null })
|
|
@@ -165,7 +170,7 @@ function DateRangeControl({
|
|
|
165
170
|
"input",
|
|
166
171
|
{
|
|
167
172
|
type: "date",
|
|
168
|
-
"aria-label": `${
|
|
173
|
+
"aria-label": t("table.filters.date_to", `${label} to`, { label }),
|
|
169
174
|
className: controlClasses(),
|
|
170
175
|
value: toValue,
|
|
171
176
|
onChange: (e) => onChange({ from: range.from ?? null, to: e.target.value || null })
|
|
@@ -175,6 +180,9 @@ function DateRangeControl({
|
|
|
175
180
|
] });
|
|
176
181
|
}
|
|
177
182
|
function TableCard({ widget, className }) {
|
|
183
|
+
const t = useArqelTranslations();
|
|
184
|
+
const locale = useArqelLocale();
|
|
185
|
+
const numberFormatter = useMemo(() => new Intl.NumberFormat(locale), [locale]);
|
|
178
186
|
return /* @__PURE__ */ jsx(
|
|
179
187
|
WidgetWrapper,
|
|
180
188
|
{
|
|
@@ -196,19 +204,25 @@ function TableCard({ widget, className }) {
|
|
|
196
204
|
"tr",
|
|
197
205
|
{
|
|
198
206
|
className: "border-b border-border last:border-0",
|
|
199
|
-
children: widget.columns.map((column) => /* @__PURE__ */ jsx("td", { className: "px-2 py-1.5", children: formatCell(record[column.name]) }, column.name))
|
|
207
|
+
children: widget.columns.map((column) => /* @__PURE__ */ jsx("td", { className: "px-2 py-1.5", children: formatCell(record[column.name], numberFormatter, t) }, column.name))
|
|
200
208
|
},
|
|
201
209
|
rowIndex
|
|
202
210
|
)) })
|
|
203
211
|
] }) }),
|
|
204
|
-
widget.seeAllUrl && /* @__PURE__ */ jsx("div", { className: "mt-3 text-right", children: /* @__PURE__ */ jsx("a", { href: widget.seeAllUrl, className: "text-sm text-primary", children: "See all \u2192" }) })
|
|
212
|
+
widget.seeAllUrl && /* @__PURE__ */ jsx("div", { className: "mt-3 text-right", children: /* @__PURE__ */ jsx("a", { href: widget.seeAllUrl, className: "text-sm text-primary", children: t("widgets.table.see_all", "See all \u2192") }) })
|
|
205
213
|
] })
|
|
206
214
|
}
|
|
207
215
|
);
|
|
208
216
|
}
|
|
209
|
-
function formatCell(value) {
|
|
217
|
+
function formatCell(value, numberFormatter, t) {
|
|
210
218
|
if (value === null || value === void 0) return "";
|
|
211
|
-
if (typeof value === "
|
|
219
|
+
if (typeof value === "number") {
|
|
220
|
+
return Number.isFinite(value) ? numberFormatter.format(value) : String(value);
|
|
221
|
+
}
|
|
222
|
+
if (typeof value === "boolean") {
|
|
223
|
+
return value ? t("table.boolean.true_label", "true") : t("table.boolean.false_label", "false");
|
|
224
|
+
}
|
|
225
|
+
if (typeof value === "string") {
|
|
212
226
|
return String(value);
|
|
213
227
|
}
|
|
214
228
|
try {
|
|
@@ -218,6 +232,7 @@ function formatCell(value) {
|
|
|
218
232
|
}
|
|
219
233
|
}
|
|
220
234
|
function WidgetRenderer({ widget, filterValues, fetcher }) {
|
|
235
|
+
const t = useArqelTranslations();
|
|
221
236
|
const [data, setData] = useState(widget.data ?? null);
|
|
222
237
|
const filterRef = useRef(filterValues);
|
|
223
238
|
filterRef.current = filterValues;
|
|
@@ -260,11 +275,9 @@ function WidgetRenderer({ widget, filterValues, fetcher }) {
|
|
|
260
275
|
case "table":
|
|
261
276
|
return /* @__PURE__ */ jsx(TableCard, { widget: merged });
|
|
262
277
|
default:
|
|
263
|
-
return /* @__PURE__ */
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
" not registered"
|
|
267
|
-
] });
|
|
278
|
+
return /* @__PURE__ */ jsx("div", { role: "alert", className: "text-sm text-red-600", children: t("widgets.unknown_type", `Widget type ${widget.type} not registered`, {
|
|
279
|
+
type: widget.type
|
|
280
|
+
}) });
|
|
268
281
|
}
|
|
269
282
|
}
|
|
270
283
|
function withFilters(baseUrl, filters) {
|
|
@@ -366,5 +379,5 @@ function normaliseFilters(raw) {
|
|
|
366
379
|
}
|
|
367
380
|
|
|
368
381
|
export { ChartCard, DashboardFilters, DashboardGrid, TableCard, WidgetRenderer };
|
|
369
|
-
//# sourceMappingURL=chunk-
|
|
370
|
-
//# sourceMappingURL=chunk-
|
|
382
|
+
//# sourceMappingURL=chunk-YYQ45W25.js.map
|
|
383
|
+
//# sourceMappingURL=chunk-YYQ45W25.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/widgets/ChartCard.tsx","../src/widgets/DashboardFilters.tsx","../src/widgets/TableCard.tsx","../src/widgets/WidgetRenderer.tsx","../src/widgets/DashboardGrid.tsx"],"names":["jsx","useArqelTranslations","jsxs","useState"],"mappings":"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","file":"chunk-YYQ45W25.js","sourcesContent":["import { useArqelTranslations } from '@arqel-dev/react/utils';\nimport { type ComponentType, lazy, Suspense } from 'react';\nimport type { ChartSubProps, ChartType, ChartWidgetProps } from './types';\nimport { WidgetWrapper } from './WidgetWrapper';\n\n/**\n * Lazy-loaded chart sub-components. Each `import()` becomes a separate chunk\n * in the build output so the ~60KB Recharts payload (and its sibling chart\n * primitives) stay out of the main `@arqel-dev/ui` bundle. Dashboards that only\n * use StatCard never pay for Recharts.\n */\nconst LineChart = lazy(() => import('./charts/LineChart').then((m) => ({ default: m.LineChart })));\nconst BarChart = lazy(() => import('./charts/BarChart').then((m) => ({ default: m.BarChart })));\nconst AreaChart = lazy(() => import('./charts/AreaChart').then((m) => ({ default: m.AreaChart })));\nconst PieChart = lazy(() => import('./charts/PieChart').then((m) => ({ default: m.PieChart })));\nconst DonutChart = lazy(() =>\n import('./charts/DonutChart').then((m) => ({ default: m.DonutChart })),\n);\nconst RadarChart = lazy(() =>\n import('./charts/RadarChart').then((m) => ({ default: m.RadarChart })),\n);\n\nconst REGISTRY: Record<ChartType, ComponentType<ChartSubProps>> = {\n line: LineChart,\n bar: BarChart,\n area: AreaChart,\n pie: PieChart,\n donut: DonutChart,\n radar: RadarChart,\n};\n\nexport function ChartCard({ widget }: ChartWidgetProps) {\n const t = useArqelTranslations();\n const Chart = REGISTRY[widget.chartType] ?? LineChart;\n\n return (\n <WidgetWrapper heading={widget.heading} description={widget.description}>\n <Suspense\n fallback={\n <div\n role=\"status\"\n aria-label={t('arqel.aria.chart_loading', 'Loading chart')}\n data-testid=\"chart-fallback\"\n className=\"animate-pulse rounded bg-muted\"\n style={{ height: widget.height }}\n />\n }\n >\n <Chart\n chartData={widget.chartData}\n chartOptions={widget.chartOptions}\n height={widget.height}\n showLegend={widget.showLegend}\n showGrid={widget.showGrid}\n />\n </Suspense>\n </WidgetWrapper>\n );\n}\n","/**\n * `<DashboardFilters>` — renders one control per dashboard `Filter`\n * payload (`Arqel\\Widgets\\Filters\\*`). Two filter types are wired in\n * Phase 2 part-3: `select` (single dropdown) and `date_range` (from/to\n * date inputs). Unknown types are dropped silently — extension points\n * land in later slices.\n *\n * Controlled component: callers own `values` and react to `onChange`.\n */\n\nimport { useArqelTranslations } from '@arqel-dev/react/utils';\nimport { cn } from '../utils/cn.js';\n\nexport interface SelectFilterPayload {\n name: string;\n type: 'select';\n label?: string | null;\n options?: Record<string, string> | Array<{ value: string; label: string }>;\n multiple?: boolean;\n}\n\nexport interface DateRangeFilterPayload {\n name: string;\n type: 'date_range';\n label?: string | null;\n}\n\nexport type DashboardFilterPayload =\n | SelectFilterPayload\n | DateRangeFilterPayload\n | { name: string; type: string; label?: string | null; [key: string]: unknown };\n\nexport interface DashboardFiltersProps {\n filters: DashboardFilterPayload[];\n values: Record<string, unknown>;\n onChange: (name: string, value: unknown) => void;\n className?: string | undefined;\n}\n\nexport function DashboardFilters({ filters, values, onChange, className }: DashboardFiltersProps) {\n if (!filters || filters.length === 0) return null;\n\n return (\n <div className={cn('flex flex-wrap gap-2', className)} data-testid=\"dashboard-filters\">\n {filters.map((filter) => (\n <FilterControl\n key={filter.name}\n filter={filter}\n value={values[filter.name]}\n onChange={(v) => onChange(filter.name, v)}\n />\n ))}\n </div>\n );\n}\n\nfunction FilterControl({\n filter,\n value,\n onChange,\n}: {\n filter: DashboardFilterPayload;\n value: unknown;\n onChange: (value: unknown) => void;\n}) {\n if (filter.type === 'select') {\n return (\n <SelectControl filter={filter as SelectFilterPayload} value={value} onChange={onChange} />\n );\n }\n if (filter.type === 'date_range') {\n return (\n <DateRangeControl\n filter={filter as DateRangeFilterPayload}\n value={value}\n onChange={onChange}\n />\n );\n }\n return null;\n}\n\nfunction controlClasses() {\n return cn(\n 'h-9 rounded-sm border border-[var(--input)]',\n 'bg-background px-2 text-sm',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n );\n}\n\nfunction normaliseOptions(\n raw: SelectFilterPayload['options'],\n): Array<{ value: string; label: string }> {\n if (!raw) return [];\n if (Array.isArray(raw)) {\n return raw.map((o) => ({ value: String(o.value), label: String(o.label ?? o.value) }));\n }\n return Object.entries(raw).map(([k, v]) => ({ value: String(k), label: String(v) }));\n}\n\nfunction SelectControl({\n filter,\n value,\n onChange,\n}: {\n filter: SelectFilterPayload;\n value: unknown;\n onChange: (value: unknown) => void;\n}) {\n const t = useArqelTranslations();\n const options = normaliseOptions(filter.options);\n const label = filter.label ?? filter.name;\n\n if (filter.multiple) {\n const selected = Array.isArray(value) ? (value as Array<string | number>).map(String) : [];\n return (\n <label className=\"flex flex-col gap-1 text-xs text-muted-foreground\">\n {label}\n <select\n multiple\n aria-label={label}\n className={cn(controlClasses(), 'h-auto min-h-[2.25rem] py-1')}\n value={selected}\n onChange={(e) => {\n const next = Array.from(e.target.selectedOptions, (o) => o.value);\n onChange(next.length === 0 ? null : next);\n }}\n >\n {options.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n </label>\n );\n }\n\n return (\n <label className=\"flex flex-col gap-1 text-xs text-muted-foreground\">\n {label}\n <select\n aria-label={label}\n className={controlClasses()}\n value={value === undefined || value === null ? '' : String(value)}\n onChange={(e) => onChange(e.target.value === '' ? null : e.target.value)}\n >\n <option value=\"\">{t('table.filters.all', 'All')}</option>\n {options.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n </label>\n );\n}\n\nfunction DateRangeControl({\n filter,\n value,\n onChange,\n}: {\n filter: DateRangeFilterPayload;\n value: unknown;\n onChange: (value: unknown) => void;\n}) {\n const t = useArqelTranslations();\n const label = filter.label ?? filter.name;\n const range = (value && typeof value === 'object' ? (value as Record<string, unknown>) : {}) as {\n from?: unknown;\n to?: unknown;\n };\n const fromValue = typeof range.from === 'string' ? range.from : '';\n const toValue = typeof range.to === 'string' ? range.to : '';\n\n return (\n <fieldset className=\"flex flex-col gap-1 text-xs text-muted-foreground\">\n <legend>{label}</legend>\n <div className=\"flex items-center gap-1\">\n <input\n type=\"date\"\n aria-label={t('table.filters.date_from', `${label} from`, { label })}\n className={controlClasses()}\n value={fromValue}\n onChange={(e) => onChange({ from: e.target.value || null, to: range.to ?? null })}\n />\n <span aria-hidden=\"true\">–</span>\n <input\n type=\"date\"\n aria-label={t('table.filters.date_to', `${label} to`, { label })}\n className={controlClasses()}\n value={toValue}\n onChange={(e) => onChange({ from: range.from ?? null, to: e.target.value || null })}\n />\n </div>\n </fieldset>\n );\n}\n","/**\n * `<TableCard>` — minimal mini-table widget rendered inside a dashboard.\n *\n * Mirrors the payload produced by `Arqel\\Widgets\\TableWidget::data()`:\n * `{ columns, records, limit, seeAllUrl, loadError? }`. The component is\n * intentionally schema-light — each column carries `name` + `label` and\n * cells extract `record[column.name]` verbatim. Renders a `role=\"alert\"`\n * panel when the PHP side surfaced a `loadError` instead of trying to\n * draw an empty table.\n */\n\nimport { useArqelLocale, useArqelTranslations } from '@arqel-dev/react/utils';\nimport { useMemo } from 'react';\nimport { cn } from '../utils/cn.js';\nimport { WidgetWrapper } from './WidgetWrapper.js';\n\nexport interface TableCardColumn {\n name: string;\n label?: string | null;\n}\n\nexport interface TableCardRecord {\n [key: string]: unknown;\n}\n\nexport interface TableCardWidget {\n name: string;\n type: 'table';\n heading?: string | null;\n description?: string | null;\n columns: TableCardColumn[];\n records: TableCardRecord[];\n limit: number;\n seeAllUrl?: string | null;\n loadError?: string | null;\n}\n\nexport interface TableCardProps {\n widget: TableCardWidget;\n className?: string | undefined;\n}\n\nexport function TableCard({ widget, className }: TableCardProps) {\n const t = useArqelTranslations();\n const locale = useArqelLocale();\n const numberFormatter = useMemo(() => new Intl.NumberFormat(locale), [locale]);\n return (\n <WidgetWrapper\n heading={widget.heading ?? undefined}\n description={widget.description ?? undefined}\n className={className}\n >\n {widget.loadError ? (\n <div role=\"alert\" className=\"text-sm text-red-600\">\n {widget.loadError}\n </div>\n ) : (\n <>\n <div className=\"overflow-x-auto\">\n <table className={cn('w-full border-collapse text-sm', 'text-foreground')}>\n <thead>\n <tr className=\"border-b border-border text-left\">\n {widget.columns.map((column) => (\n <th\n key={column.name}\n scope=\"col\"\n className=\"px-2 py-1.5 font-medium text-muted-foreground\"\n >\n {column.label ?? column.name}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {widget.records.map((record, rowIndex) => (\n <tr\n // biome-ignore lint/suspicious/noArrayIndexKey: records may lack a stable id\n key={rowIndex}\n className=\"border-b border-border last:border-0\"\n >\n {widget.columns.map((column) => (\n <td key={column.name} className=\"px-2 py-1.5\">\n {formatCell(record[column.name], numberFormatter, t)}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n {widget.seeAllUrl && (\n <div className=\"mt-3 text-right\">\n <a href={widget.seeAllUrl} className=\"text-sm text-primary\">\n {t('widgets.table.see_all', 'See all →')}\n </a>\n </div>\n )}\n </>\n )}\n </WidgetWrapper>\n );\n}\n\nfunction formatCell(\n value: unknown,\n numberFormatter: Intl.NumberFormat,\n t: (key: string, fallback?: string) => string,\n): string {\n if (value === null || value === undefined) return '';\n // Numbers are grouped/decimal-formatted for the active locale so a cell of\n // `1500000` reads `1.500.000` under pt-BR instead of the raw en-US digits.\n if (typeof value === 'number') {\n return Number.isFinite(value) ? numberFormatter.format(value) : String(value);\n }\n // Booleans render a localized truth label (mirroring cells.tsx) so a pt-BR\n // viewer sees the localized value instead of the literal 'true'/'false'.\n if (typeof value === 'boolean') {\n return value ? t('table.boolean.true_label', 'true') : t('table.boolean.false_label', 'false');\n }\n if (typeof value === 'string') {\n return String(value);\n }\n try {\n return JSON.stringify(value);\n } catch {\n return '';\n }\n}\n","/**\n * `<WidgetRenderer>` — dispatches widget payloads to the right card\n * by `widget.type` (`stat`, `chart`, `table`). Unknown / `custom` types\n * surface a `role=\"alert\"` so a misconfigured registry never silently\n * blanks the dashboard.\n *\n * Two server interactions live here:\n * 1. **Polling** — when `widget.poll > 0`, re-fetch the widget data\n * endpoint every N seconds and replace the inline payload.\n * 2. **Deferred** — when `widget.deferred === true` and `data` is\n * `null`, fetch once on mount.\n *\n * Both call the canonical endpoint\n * `/admin/dashboards/{dashboardId}/widgets/{widgetId}/data`. The\n * controller wraps the payload under `{ data: ... }`, so `doFetch`\n * unwraps that envelope before storing — the resulting shape matches\n * the SSR / Inertia path, which already seeds from `widget.data`. The\n * active `DashboardFilters` selection is forwarded as `filters[k]=v`\n * query params so deferred / poll refetches stay segmented.\n */\n\nimport { useArqelTranslations } from '@arqel-dev/react/utils';\nimport { useEffect, useRef, useState } from 'react';\nimport { ChartCard } from './ChartCard.js';\nimport { StatCard } from './StatCard.js';\nimport { TableCard } from './TableCard.js';\n\nexport interface WidgetPayload {\n id?: string;\n name: string;\n type: string;\n component?: string;\n data?: unknown;\n poll?: number | null;\n deferred?: boolean;\n dashboardId?: string;\n widgetId?: string;\n [key: string]: unknown;\n}\n\nexport interface WidgetRendererProps {\n widget: WidgetPayload;\n filterValues?: Record<string, unknown>;\n fetcher?: ((url: string) => Promise<unknown>) | undefined;\n}\n\nexport function WidgetRenderer({ widget, filterValues, fetcher }: WidgetRendererProps) {\n const t = useArqelTranslations();\n const [data, setData] = useState<unknown>(widget.data ?? null);\n const filterRef = useRef(filterValues);\n filterRef.current = filterValues;\n\n const dashboardId = widget.dashboardId;\n // `Dashboard::findWidget` matches on `id()` (`<type>:<name>`), so the refetch\n // must target that — `Dashboard::resolve` now injects `widgetId`. Fall back to\n // the serialized `id` (also the full `id()`) before the bare `name`.\n const widgetId = widget.widgetId ?? widget.id ?? widget.name;\n const poll = typeof widget.poll === 'number' ? widget.poll : 0;\n const deferred = widget.deferred === true;\n // Capture the initial-payload presence in a ref so the effect doesn't\n // need to take `widget.data` as a dep (we only consult it once on mount).\n const hasInlineDataRef = useRef(widget.data !== null && widget.data !== undefined);\n\n useEffect(() => {\n if (!dashboardId || !widgetId) return undefined;\n\n const baseUrl = `/admin/dashboards/${dashboardId}/widgets/${widgetId}/data`;\n const doFetch = async () => {\n try {\n // Build the URL with the *live* filters so deferred / poll refetches\n // honour the dashboard's `DashboardFilters` selection. The server\n // reads `$request->input('filters')` as an array, so each entry is\n // serialised as `filters[key]=value`.\n const url = withFilters(baseUrl, filterRef.current);\n const body = fetcher\n ? await fetcher(url)\n : await fetch(url, { headers: { Accept: 'application/json' } }).then((r) => r.json());\n // Unwrap the controller envelope (`{ data: ... }`) so the fetch\n // payload shape matches the SSR / Inertia path, which already seeds\n // from the unwrapped `widget.data`. Defensive: accept bare payloads.\n const result =\n body && typeof body === 'object' && 'data' in (body as Record<string, unknown>)\n ? (body as Record<string, unknown>)['data']\n : body;\n setData(result);\n } catch {\n // Swallow — the inline payload (or the previous successful poll) stays.\n }\n };\n\n let interval: ReturnType<typeof setInterval> | undefined;\n\n if (deferred && !hasInlineDataRef.current) {\n void doFetch();\n }\n\n if (poll > 0) {\n interval = setInterval(() => {\n void doFetch();\n }, poll * 1000);\n }\n\n return () => {\n if (interval) clearInterval(interval);\n };\n }, [dashboardId, widgetId, poll, deferred, fetcher]);\n\n const merged = mergeData(widget, data);\n\n switch (widget.type) {\n case 'stat':\n return <StatCard widget={merged as never} />;\n case 'chart':\n return <ChartCard widget={merged as never} />;\n case 'table':\n return <TableCard widget={merged as never} />;\n default:\n return (\n <div role=\"alert\" className=\"text-sm text-red-600\">\n {t('widgets.unknown_type', `Widget type ${widget.type} not registered`, {\n type: widget.type,\n })}\n </div>\n );\n }\n}\n\n/**\n * Append non-empty filter values as query params so the Laravel controller\n * resolves them via `$request->input('filters')` as a nested array. The shape\n * must mirror what the SSR / deep-link path produces (`router.get(path,\n * { filters })`, qs bracket notation) so a deferred / polling widget's lazy\n * refetch agrees with its SSR payload:\n * - **array** → `filters[key][]=el` per element (multi-`SelectControl`, #189)\n * - **plain object** → `filters[key][subKey]=val` per leaf (`DateRangeControl`\n * emits `{from,to}` → `filters[range][from]=..&filters[range][to]=..`)\n * - **scalar** → `filters[key]=value`\n * `null` / `undefined` / empty-string values (and leaves) are skipped to keep\n * the URL clean and match the prior scalar behaviour.\n */\nfunction withFilters(baseUrl: string, filters: Record<string, unknown> | undefined): string {\n if (!filters) return baseUrl;\n\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(filters)) {\n appendFilterValue(params, `filters[${key}]`, value);\n }\n\n const query = params.toString();\n return query ? `${baseUrl}?${query}` : baseUrl;\n}\n\n/**\n * Serialize a single filter value under `prefix`, recursing one level for the\n * array / plain-object shapes the dashboard filters emit (scalar | string[] |\n * `{from,to}`). `Array.isArray` is checked before the plain-object branch since\n * arrays are also objects. Empty leaves are skipped, never appended.\n */\nfunction appendFilterValue(params: URLSearchParams, prefix: string, value: unknown): void {\n if (value === null || value === undefined || value === '') return;\n\n if (Array.isArray(value)) {\n for (const el of value) {\n appendFilterValue(params, `${prefix}[]`, el);\n }\n return;\n }\n\n if (typeof value === 'object') {\n for (const [subKey, subVal] of Object.entries(value as Record<string, unknown>)) {\n appendFilterValue(params, `${prefix}[${subKey}]`, subVal);\n }\n return;\n }\n\n params.append(prefix, String(value));\n}\n\nfunction mergeData(widget: WidgetPayload, data: unknown): Record<string, unknown> {\n if (data && typeof data === 'object' && !Array.isArray(data)) {\n return { ...widget, ...(data as Record<string, unknown>) };\n }\n return { ...widget, data };\n}\n","/**\n * `<DashboardGrid>` — top-level layout for an Arqel dashboard.\n *\n * Renders the dashboard heading + description, the filter bar (when the\n * dashboard declares filters), and a CSS Grid of widgets. Column count\n * accepts either a flat int or a responsive map (`{sm,md,lg,xl,2xl}`)\n * matching `Arqel\\Widgets\\Dashboard::columns()`. Each widget honours\n * `columnSpan` (defaults to 1) via `gridColumn: span N`.\n *\n * Filter values are controlled internally when `onFilterChange` is not\n * provided; supply that prop (and `filterValues`) to lift state out\n * (e.g., to push it to the URL through Inertia).\n */\n\nimport { type CSSProperties, useState } from 'react';\nimport { cn } from '../utils/cn.js';\nimport { type DashboardFilterPayload, DashboardFilters } from './DashboardFilters.js';\nimport { type WidgetPayload, WidgetRenderer } from './WidgetRenderer.js';\n\nexport interface DashboardPayload {\n id: string;\n label: string;\n path?: string | null;\n heading?: string | null;\n description?: string | null;\n widgets: WidgetPayload[];\n filters?: DashboardFilterPayload[] | Record<string, unknown> | null;\n columns: number | Partial<Record<'sm' | 'md' | 'lg' | 'xl' | '2xl', number>>;\n}\n\nexport interface DashboardGridProps {\n dashboard: DashboardPayload;\n filterValues?: Record<string, unknown>;\n onFilterChange?: ((name: string, value: unknown) => void) | undefined;\n className?: string | undefined;\n}\n\nconst BREAKPOINT_PREFIX: Record<string, string> = {\n sm: 'sm:',\n md: 'md:',\n lg: 'lg:',\n xl: 'xl:',\n '2xl': '2xl:',\n};\n\nexport function DashboardGrid({\n dashboard,\n filterValues,\n onFilterChange,\n className,\n}: DashboardGridProps) {\n const [internalValues, setInternalValues] = useState<Record<string, unknown>>(filterValues ?? {});\n const values = filterValues ?? internalValues;\n\n const handleChange = (name: string, value: unknown) => {\n if (onFilterChange) {\n onFilterChange(name, value);\n } else {\n setInternalValues((prev) => ({ ...prev, [name]: value }));\n }\n };\n\n const filterPayload = normaliseFilters(dashboard.filters);\n const heading = dashboard.heading ?? dashboard.label;\n\n return (\n <div className={cn('space-y-4', className)}>\n <header className=\"flex flex-wrap items-start justify-between gap-3\">\n <div className=\"space-y-1\">\n {heading && <h1 className=\"text-xl font-semibold\">{heading}</h1>}\n {dashboard.description && (\n <p className=\"text-sm text-muted-foreground\">{dashboard.description}</p>\n )}\n </div>\n {filterPayload.length > 0 && (\n <DashboardFilters filters={filterPayload} values={values} onChange={handleChange} />\n )}\n </header>\n\n <div\n className={cn('grid gap-4', gridColsClass(dashboard.columns))}\n data-testid=\"dashboard-grid\"\n >\n {dashboard.widgets.map((widget) => {\n const rawSpan = (widget as { columnSpan?: unknown }).columnSpan;\n const span = typeof rawSpan === 'number' ? rawSpan : 1;\n const style: CSSProperties = { gridColumn: `span ${span}` };\n return (\n <div key={widget.name} style={style} data-widget-slot={widget.name}>\n <WidgetRenderer widget={widget} filterValues={values} />\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\nfunction gridColsClass(columns: DashboardPayload['columns']): string {\n if (typeof columns === 'number') {\n return `grid-cols-${Math.max(1, Math.min(12, columns))}`;\n }\n const parts: string[] = [];\n // Base fallback when no `sm` provided.\n parts.push('grid-cols-1');\n for (const bp of ['sm', 'md', 'lg', 'xl', '2xl'] as const) {\n const value = columns[bp];\n if (typeof value === 'number') {\n parts.push(`${BREAKPOINT_PREFIX[bp]}grid-cols-${Math.max(1, Math.min(12, value))}`);\n }\n }\n return parts.join(' ');\n}\n\nfunction normaliseFilters(raw: DashboardPayload['filters']): DashboardFilterPayload[] {\n if (!raw) return [];\n if (Array.isArray(raw)) return raw;\n // Legacy `Record<string, mixed>` passthrough — render as a select-less\n // empty list so we don't crash. The declarative path is preferred.\n return [];\n}\n"]}
|
package/dist/flash.js
CHANGED
package/dist/form.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { F as FieldComponent, a as FieldRenderer, b as FieldRendererProps, c as FormActions, d as FormActionsProps, e as FormRenderer, f as FormRendererProps, g as clearFieldRegistry, h as getFieldComponent, i as getRegisteredFields, r as registerField, u as unregisterField } from './FormRenderer-
|
|
1
|
+
export { F as FieldComponent, a as FieldRenderer, b as FieldRendererProps, c as FormActions, d as FormActionsProps, e as FormRenderer, f as FormRendererProps, g as clearFieldRegistry, h as getFieldComponent, i as getRegisteredFields, r as registerField, u as unregisterField } from './FormRenderer-By8fZp4t.js';
|
|
2
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
3
|
import { FieldsetProps, GridProps, SectionProps, TabsProps } from '@arqel-dev/types/forms';
|
|
4
4
|
import { ReactNode, ReactElement } from 'react';
|
|
@@ -55,6 +55,8 @@ interface NativeProps {
|
|
|
55
55
|
className?: string | undefined;
|
|
56
56
|
inputId?: string | undefined;
|
|
57
57
|
describedBy?: string | undefined;
|
|
58
|
+
/** When true, the control is in an error state — sets `aria-invalid`. */
|
|
59
|
+
invalid?: boolean | undefined;
|
|
58
60
|
}
|
|
59
61
|
declare function NativeFieldInput(props: NativeProps): react_jsx_runtime.JSX.Element;
|
|
60
62
|
|
package/dist/form.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { FormActions } from './chunk-MZMYV43C.js';
|
|
2
|
-
export { FieldRenderer, FormFieldset, FormGrid, FormRenderer, FormSection, FormTabs, NativeFieldInput, clearFieldRegistry, getFieldComponent, getRegisteredFields, registerField, unregisterField } from './chunk-
|
|
2
|
+
export { FieldRenderer, FormFieldset, FormGrid, FormRenderer, FormSection, FormTabs, NativeFieldInput, clearFieldRegistry, getFieldComponent, getRegisteredFields, registerField, unregisterField } from './chunk-CMNZLA32.js';
|
|
3
3
|
import './chunk-H23VX3RR.js';
|
|
4
4
|
import './chunk-B7ULUJVO.js';
|
|
5
5
|
//# sourceMappingURL=form.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { ActionButton, ActionButtonProps, ActionFormModal, ActionFormModalProps, ActionMenu, ActionMenuProps, Button, ButtonProps, ConfirmDialog, ConfirmDialogProps, buttonVariants } from './action.js';
|
|
2
2
|
export { CanAccess, CanAccessProps } from './auth.js';
|
|
3
3
|
export { FlashContainer, FlashContainerProps, FlashKind, FlashPosition, FlashToast, FlashToastProps } from './flash.js';
|
|
4
|
-
export { F as FieldComponent, a as FieldRenderer, b as FieldRendererProps, c as FormActions, d as FormActionsProps, e as FormRenderer, f as FormRendererProps, g as clearFieldRegistry, h as getFieldComponent, r as registerField } from './FormRenderer-
|
|
4
|
+
export { F as FieldComponent, a as FieldRenderer, b as FieldRendererProps, c as FormActions, d as FormActionsProps, e as FormRenderer, f as FormRendererProps, g as clearFieldRegistry, h as getFieldComponent, r as registerField } from './FormRenderer-By8fZp4t.js';
|
|
5
5
|
export { CommandPalette, CommandPaletteProps, PaletteCommand } from './palette.js';
|
|
6
6
|
export { Alert, AlertDescription, AlertTitle, Badge, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, Input, Label, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectSeparator, SelectTrigger, SelectValue, Separator, Skeleton, Textarea, badgeVariants } from './primitives.js';
|
|
7
7
|
export { ResourceIndex, ResourceIndexUIProps } from './resource.js';
|
package/dist/index.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
export { Breadcrumbs, EmptyState, ErrorState, LoadingSkeleton } from './chunk-
|
|
2
|
-
export { StatCard, WidgetWrapper } from './chunk-
|
|
1
|
+
export { Breadcrumbs, EmptyState, ErrorState, LoadingSkeleton } from './chunk-SK6H7ARE.js';
|
|
2
|
+
export { StatCard, WidgetWrapper } from './chunk-WMOBLT3Z.js';
|
|
3
3
|
export { Alert, AlertDescription, AlertTitle, Badge, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, Label, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectSeparator, SelectTrigger, SelectValue, Textarea, badgeVariants } from './chunk-K7QY56XN.js';
|
|
4
4
|
export { PageHeader } from './chunk-MXUXMHOK.js';
|
|
5
|
-
export { AppShell, Footer, MainContent, Sidebar, Topbar } from './chunk-
|
|
6
|
-
export { CommandPalette } from './chunk-
|
|
5
|
+
export { AppShell, Footer, MainContent, Sidebar, Topbar } from './chunk-4VWNBMMA.js';
|
|
6
|
+
export { CommandPalette } from './chunk-HNUUZEOL.js';
|
|
7
7
|
export { Input, Separator, Skeleton } from './chunk-R4BOUU6Y.js';
|
|
8
|
-
export { ResourceIndex } from './chunk-
|
|
9
|
-
export { DataTable, TableFilters, TablePagination, TableToolbar } from './chunk-
|
|
8
|
+
export { ResourceIndex } from './chunk-EG2DASKR.js';
|
|
9
|
+
export { DataTable, TableFilters, TablePagination, TableToolbar } from './chunk-S5UNPCMQ.js';
|
|
10
10
|
import './chunk-RMPOR2YZ.js';
|
|
11
|
-
export { ActionButton, ActionFormModal, ActionMenu, ConfirmDialog } from './chunk-
|
|
11
|
+
export { ActionButton, ActionFormModal, ActionMenu, ConfirmDialog } from './chunk-2JUWLJ3K.js';
|
|
12
12
|
import './chunk-3HN4ARGG.js';
|
|
13
13
|
export { FormActions } from './chunk-MZMYV43C.js';
|
|
14
|
-
export { FieldRenderer, FormRenderer, clearFieldRegistry, getFieldComponent, registerField } from './chunk-
|
|
14
|
+
export { FieldRenderer, FormRenderer, clearFieldRegistry, getFieldComponent, registerField } from './chunk-CMNZLA32.js';
|
|
15
15
|
export { Button, buttonVariants } from './chunk-H23VX3RR.js';
|
|
16
16
|
export { CanAccess } from './chunk-RNAMHQM6.js';
|
|
17
|
-
export { FlashContainer, FlashToast } from './chunk-
|
|
17
|
+
export { FlashContainer, FlashToast } from './chunk-GJ2FKAOM.js';
|
|
18
18
|
export { cn } from './chunk-B7ULUJVO.js';
|
|
19
19
|
//# sourceMappingURL=index.js.map
|
|
20
20
|
//# sourceMappingURL=index.js.map
|
package/dist/pages.js
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
export { ArqelShowPage } from './chunk-
|
|
2
|
-
export { ArqelDashboardPage } from './chunk-
|
|
3
|
-
export { ArqelEditPage } from './chunk-
|
|
4
|
-
export { ArqelIndexPage } from './chunk-
|
|
5
|
-
import './chunk-
|
|
6
|
-
export { ArqelCreatePage } from './chunk-
|
|
7
|
-
import './chunk-
|
|
1
|
+
export { ArqelShowPage } from './chunk-Q7WGPKUN.js';
|
|
2
|
+
export { ArqelDashboardPage } from './chunk-3VSDQCFO.js';
|
|
3
|
+
export { ArqelEditPage } from './chunk-YQ6KXR3U.js';
|
|
4
|
+
export { ArqelIndexPage } from './chunk-LLANMODS.js';
|
|
5
|
+
import './chunk-YYQ45W25.js';
|
|
6
|
+
export { ArqelCreatePage } from './chunk-IO6RMVUF.js';
|
|
7
|
+
import './chunk-WMOBLT3Z.js';
|
|
8
8
|
import './chunk-MXUXMHOK.js';
|
|
9
|
-
import './chunk-
|
|
10
|
-
import './chunk-
|
|
9
|
+
import './chunk-EG2DASKR.js';
|
|
10
|
+
import './chunk-S5UNPCMQ.js';
|
|
11
11
|
import './chunk-RMPOR2YZ.js';
|
|
12
|
-
import './chunk-
|
|
12
|
+
import './chunk-2JUWLJ3K.js';
|
|
13
13
|
import './chunk-3HN4ARGG.js';
|
|
14
14
|
import './chunk-MZMYV43C.js';
|
|
15
|
-
import './chunk-
|
|
15
|
+
import './chunk-CMNZLA32.js';
|
|
16
16
|
import './chunk-H23VX3RR.js';
|
|
17
17
|
import './chunk-B7ULUJVO.js';
|
|
18
18
|
|
|
19
19
|
// src/pages/index.ts
|
|
20
20
|
var arqelPages = {
|
|
21
|
-
"arqel::index": () => import('./ArqelIndexPage-
|
|
22
|
-
"arqel::create": () => import('./ArqelCreatePage-
|
|
23
|
-
"arqel::edit": () => import('./ArqelEditPage-
|
|
24
|
-
"arqel::show": () => import('./ArqelShowPage-
|
|
25
|
-
"arqel::dashboard": () => import('./ArqelDashboardPage-
|
|
21
|
+
"arqel::index": () => import('./ArqelIndexPage-RGZWKKAX.js'),
|
|
22
|
+
"arqel::create": () => import('./ArqelCreatePage-UZAHV4DK.js'),
|
|
23
|
+
"arqel::edit": () => import('./ArqelEditPage-RRYFYOTC.js'),
|
|
24
|
+
"arqel::show": () => import('./ArqelShowPage-TVCJAV2F.js'),
|
|
25
|
+
"arqel::dashboard": () => import('./ArqelDashboardPage-Z5R4XSH4.js')
|
|
26
26
|
};
|
|
27
27
|
|
|
28
28
|
export { arqelPages };
|
package/dist/palette.js
CHANGED
package/dist/resource.js
CHANGED
package/dist/shell.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
export { AppShell, Footer, MainContent, Sidebar, Topbar } from './chunk-
|
|
2
|
-
import './chunk-
|
|
1
|
+
export { AppShell, Footer, MainContent, Sidebar, Topbar } from './chunk-4VWNBMMA.js';
|
|
2
|
+
import './chunk-HNUUZEOL.js';
|
|
3
3
|
import './chunk-R4BOUU6Y.js';
|
|
4
4
|
import './chunk-RMPOR2YZ.js';
|
|
5
5
|
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from './chunk-3HN4ARGG.js';
|
|
6
6
|
import { Button } from './chunk-H23VX3RR.js';
|
|
7
7
|
import './chunk-B7ULUJVO.js';
|
|
8
|
+
import { useArqelTranslations } from '@arqel-dev/react/utils';
|
|
8
9
|
import { router } from '@inertiajs/react';
|
|
9
10
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
10
11
|
|
|
@@ -14,9 +15,10 @@ function TenantSwitcher({
|
|
|
14
15
|
available,
|
|
15
16
|
switchUrl
|
|
16
17
|
}) {
|
|
18
|
+
const t = useArqelTranslations();
|
|
17
19
|
if (!current || available.length <= 1) return null;
|
|
18
20
|
const buildUrl = switchUrl ?? DEFAULT_SWITCH_URL;
|
|
19
|
-
const labelFor = (tenant) => tenant.name?.trim() ? tenant.name : `Tenant ${tenant.id}
|
|
21
|
+
const labelFor = (tenant) => tenant.name?.trim() ? tenant.name : t("arqel.tenant.unnamed", `Tenant ${tenant.id}`, { id: tenant.id });
|
|
20
22
|
const currentLabel = labelFor(current);
|
|
21
23
|
return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
22
24
|
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
@@ -25,7 +27,9 @@ function TenantSwitcher({
|
|
|
25
27
|
variant: "ghost",
|
|
26
28
|
size: "sm",
|
|
27
29
|
"data-testid": "tenant-switcher-trigger",
|
|
28
|
-
"aria-label": `Switch tenant (current: ${currentLabel})`,
|
|
30
|
+
"aria-label": t("arqel.aria.tenant_switch", `Switch tenant (current: ${currentLabel})`, {
|
|
31
|
+
tenant: currentLabel
|
|
32
|
+
}),
|
|
29
33
|
children: currentLabel
|
|
30
34
|
}
|
|
31
35
|
) }),
|
package/dist/shell.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/shell/TenantSwitcher.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/shell/TenantSwitcher.tsx"],"names":[],"mappings":";;;;;;;;;;;AAkCA,IAAM,kBAAA,GAAqB,CAAC,EAAA,KAAgC,CAAA,eAAA,EAAkB,EAAE,CAAA,OAAA,CAAA;AAEzE,SAAS,cAAA,CAAe;AAAA,EAC7B,OAAA;AAAA,EACA,SAAA;AAAA,EACA;AACF,CAAA,EAA4C;AAC1C,EAAA,MAAM,IAAI,oBAAA,EAAqB;AAC/B,EAAA,IAAI,CAAC,OAAA,IAAW,SAAA,CAAU,MAAA,IAAU,GAAG,OAAO,IAAA;AAE9C,EAAA,MAAM,WAAW,SAAA,IAAa,kBAAA;AAC9B,EAAA,MAAM,WAAW,CAAC,MAAA,KAChB,OAAO,IAAA,EAAM,IAAA,KACT,MAAA,CAAO,IAAA,GACP,EAAE,sBAAA,EAAwB,CAAA,OAAA,EAAU,OAAO,EAAE,CAAA,CAAA,EAAI,EAAE,EAAA,EAAI,MAAA,CAAO,IAAI,CAAA;AACxE,EAAA,MAAM,YAAA,GAAe,SAAS,OAAO,CAAA;AAErC,EAAA,4BACG,YAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,mBAAA,EAAA,EAAoB,SAAO,IAAA,EAC1B,QAAA,kBAAA,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,OAAA,EAAQ,OAAA;AAAA,QACR,IAAA,EAAK,IAAA;AAAA,QACL,aAAA,EAAY,yBAAA;AAAA,QACZ,YAAA,EAAY,CAAA,CAAE,0BAAA,EAA4B,CAAA,wBAAA,EAA2B,YAAY,CAAA,CAAA,CAAA,EAAK;AAAA,UACpF,MAAA,EAAQ;AAAA,SACT,CAAA;AAAA,QAEA,QAAA,EAAA;AAAA;AAAA,KACH,EACF,CAAA;AAAA,wBACC,mBAAA,EAAA,EAAoB,KAAA,EAAM,OACxB,QAAA,EAAA,SAAA,CAAU,GAAA,CAAI,CAAC,MAAA,KAAW;AACzB,MAAA,MAAM,SAAA,GAAY,MAAA,CAAO,EAAA,KAAO,OAAA,CAAQ,EAAA;AACxC,MAAA,uBACE,IAAA;AAAA,QAAC,gBAAA;AAAA,QAAA;AAAA,UAEC,aAAA,EAAa,CAAA,uBAAA,EAA0B,MAAA,CAAO,MAAA,CAAO,EAAE,CAAC,CAAA,CAAA;AAAA,UACxD,QAAA,EAAU,SAAA;AAAA,UACV,UAAU,MAAM;AACd,YAAA,MAAA,CAAO,IAAA,CAAK,QAAA,CAAS,MAAA,CAAO,EAAE,CAAA,EAAG,EAAC,EAAG,EAAE,cAAA,EAAgB,IAAA,EAAM,CAAA;AAAA,UAC/D,CAAA;AAAA,UAEC,QAAA,EAAA;AAAA,YAAA,QAAA,CAAS,MAAM,CAAA;AAAA,YACf,YAAY,SAAA,GAAO;AAAA;AAAA,SAAA;AAAA,QARf,MAAA,CAAO,OAAO,EAAE;AAAA,OASvB;AAAA,IAEJ,CAAC,CAAA,EACH;AAAA,GAAA,EACF,CAAA;AAEJ","file":"shell.js","sourcesContent":["/**\n * `<TenantSwitcher>` — dropdown that lists tenants the user can\n * access and dispatches `POST /admin/tenants/{id}/switch` via\n * Inertia router. Renders nothing when there is no current tenant\n * or the user only has access to one tenant.\n *\n * Mounts in the `tenantSwitcher` slot of `<Topbar>`. The current\n * tenant is read from `props.tenant.current` shared by the\n * server-side `HandleArqelInertiaRequests`; available tenants\n * come from the same payload.\n */\n\nimport { useArqelTranslations } from '@arqel-dev/react/utils';\nimport type { TenantSummary } from '@arqel-dev/types/tenant';\nimport { router } from '@inertiajs/react';\nimport type { JSX } from 'react';\nimport { Button } from '../action/Button.js';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '../shadcn/ui/dropdown-menu.js';\n\nexport interface TenantSwitcherProps {\n current: TenantSummary | null;\n available: ReadonlyArray<TenantSummary>;\n /**\n * Path template for switching; defaults to\n * `/admin/tenants/{id}/switch`.\n */\n switchUrl?: (tenantId: string | number) => string;\n}\n\nconst DEFAULT_SWITCH_URL = (id: string | number): string => `/admin/tenants/${id}/switch`;\n\nexport function TenantSwitcher({\n current,\n available,\n switchUrl,\n}: TenantSwitcherProps): JSX.Element | null {\n const t = useArqelTranslations();\n if (!current || available.length <= 1) return null;\n\n const buildUrl = switchUrl ?? DEFAULT_SWITCH_URL;\n const labelFor = (tenant: TenantSummary): string =>\n tenant.name?.trim()\n ? tenant.name\n : t('arqel.tenant.unnamed', `Tenant ${tenant.id}`, { id: tenant.id });\n const currentLabel = labelFor(current);\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n data-testid=\"tenant-switcher-trigger\"\n aria-label={t('arqel.aria.tenant_switch', `Switch tenant (current: ${currentLabel})`, {\n tenant: currentLabel,\n })}\n >\n {currentLabel}\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {available.map((tenant) => {\n const isCurrent = tenant.id === current.id;\n return (\n <DropdownMenuItem\n key={String(tenant.id)}\n data-testid={`tenant-switcher-option-${String(tenant.id)}`}\n disabled={isCurrent}\n onSelect={() => {\n router.post(buildUrl(tenant.id), {}, { preserveScroll: true });\n }}\n >\n {labelFor(tenant)}\n {isCurrent ? ' ✓' : ''}\n </DropdownMenuItem>\n );\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n"]}
|
package/dist/table.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { DataTable, TableCell, TableFilters, TablePagination, TableToolbar } from './chunk-
|
|
1
|
+
export { DataTable, TableCell, TableFilters, TablePagination, TableToolbar } from './chunk-S5UNPCMQ.js';
|
|
2
2
|
import './chunk-RMPOR2YZ.js';
|
|
3
3
|
import './chunk-H23VX3RR.js';
|
|
4
4
|
import './chunk-B7ULUJVO.js';
|
package/dist/utility.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { Breadcrumbs, EmptyState, ErrorState, LoadingSkeleton } from './chunk-
|
|
1
|
+
export { Breadcrumbs, EmptyState, ErrorState, LoadingSkeleton } from './chunk-SK6H7ARE.js';
|
|
2
2
|
export { PageHeader } from './chunk-MXUXMHOK.js';
|
|
3
3
|
import './chunk-B7ULUJVO.js';
|
|
4
4
|
//# sourceMappingURL=utility.js.map
|
package/dist/widgets.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { ChartCard, DashboardFilters, DashboardGrid, TableCard, WidgetRenderer } from './chunk-
|
|
2
|
-
export { StatCard, WidgetWrapper } from './chunk-
|
|
1
|
+
export { ChartCard, DashboardFilters, DashboardGrid, TableCard, WidgetRenderer } from './chunk-YYQ45W25.js';
|
|
2
|
+
export { StatCard, WidgetWrapper } from './chunk-WMOBLT3Z.js';
|
|
3
3
|
import './chunk-B7ULUJVO.js';
|
|
4
4
|
//# sourceMappingURL=widgets.js.map
|
|
5
5
|
//# sourceMappingURL=widgets.js.map
|