@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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arqel-dev/ui",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.1",
|
|
4
4
|
"description": "Structural React components (AppShell, DataTable, FormRenderer, etc.) for Arqel admin panels.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://arqel.dev",
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
"clsx": "^2.1.1",
|
|
93
93
|
"radix-ui": "^1.4.3",
|
|
94
94
|
"tailwind-merge": "^2.5.5",
|
|
95
|
-
"@arqel-dev/types": "0.15.
|
|
95
|
+
"@arqel-dev/types": "0.15.1"
|
|
96
96
|
},
|
|
97
97
|
"peerDependencies": {
|
|
98
98
|
"@inertiajs/react": "^3.0.0",
|
|
@@ -102,8 +102,8 @@
|
|
|
102
102
|
"react-dom": "^19.2.0",
|
|
103
103
|
"recharts": "^2.15.0",
|
|
104
104
|
"tailwindcss": "^4.0.0",
|
|
105
|
-
"@arqel-dev/hooks": "0.15.
|
|
106
|
-
"@arqel-dev/react": "0.15.
|
|
105
|
+
"@arqel-dev/hooks": "0.15.1",
|
|
106
|
+
"@arqel-dev/react": "0.15.1"
|
|
107
107
|
},
|
|
108
108
|
"devDependencies": {
|
|
109
109
|
"@base-ui-components/react": "^1.0.0-alpha.0",
|
|
@@ -125,8 +125,8 @@
|
|
|
125
125
|
"tsup": "^8.5.0",
|
|
126
126
|
"typescript": "^5.6.3",
|
|
127
127
|
"vitest": "^4.1.0",
|
|
128
|
-
"@arqel-dev/hooks": "0.15.
|
|
129
|
-
"@arqel-dev/react": "0.15.
|
|
128
|
+
"@arqel-dev/hooks": "0.15.1",
|
|
129
|
+
"@arqel-dev/react": "0.15.1"
|
|
130
130
|
},
|
|
131
131
|
"publishConfig": {
|
|
132
132
|
"access": "public"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/widgets/charts/AreaChart.tsx"],"names":["RechartsAreaChart"],"mappings":";;;;AAYO,SAAS,UAAU,EAAE,SAAA,EAAW,MAAA,EAAQ,UAAA,EAAY,UAAS,EAAkB;AACpF,EAAA,MAAM,IAAA,GAAO,WAAW,SAAS,CAAA;AACjC,EAAA,2BACG,KAAA,EAAA,EAAI,aAAA,EAAY,cAAa,KAAA,EAAO,EAAE,OAAO,MAAA,EAAQ,MAAA,IACpD,QAAA,kBAAA,GAAA,CAAC,mBAAA,EAAA,EAAoB,OAAM,MAAA,EAAO,MAAA,EAAO,QACvC,QAAA,kBAAA,IAAA,CAACA,WAAA,EAAA,EAAkB,MAAM,IAAA,EACtB,QAAA,EAAA;AAAA,IAAA,QAAA,mBAAW,GAAA,CAAC,aAAA,EAAA,EAAc,eAAA,EAAgB,KAAA,EAAM,CAAA,GAAK,IAAA;AAAA,oBACtD,GAAA,CAAC,KAAA,EAAA,EAAM,OAAA,EAAQ,MAAA,EAAO,CAAA;AAAA,wBACrB,KAAA,EAAA,EAAM,CAAA;AAAA,wBACN,OAAA,EAAA,EAAQ,CAAA;AAAA,IACR,UAAA,mBAAa,GAAA,CAAC,MAAA,EAAA,EAAO,CAAA,GAAK,IAAA;AAAA,IAC1B,SAAA,CAAU,QAAA,CAAS,GAAA,CAAI,CAAC,IAAI,CAAA,KAAM;AACjC,MAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,EAAA,EAAI,CAAC,CAAA;AAC5B,MAAA,uBACE,GAAA;AAAA,QAAC,IAAA;AAAA,QAAA;AAAA,UAEC,IAAA,EAAK,UAAA;AAAA,UACL,OAAA,EAAS,UAAU,CAAC,CAAA,CAAA;AAAA,UACpB,MAAM,EAAA,CAAG,KAAA;AAAA,UACT,MAAA,EAAQ,KAAA;AAAA,UACR,IAAA,EAAM,KAAA;AAAA,UACN,WAAA,EAAa;AAAA,SAAA;AAAA,QANR,EAAA,CAAG;AAAA,OAOV;AAAA,IAEJ,CAAC;AAAA,GAAA,EACH,GACF,CAAA,EACF,CAAA;AAEJ","file":"AreaChart-NMQ2RQGA.js","sourcesContent":["import {\n Area,\n CartesianGrid,\n Legend,\n AreaChart as RechartsAreaChart,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from 'recharts';\nimport { type ChartSubProps, colorFor, toRowShape } from '../types';\n\nexport function AreaChart({ chartData, height, showLegend, showGrid }: ChartSubProps) {\n const rows = toRowShape(chartData);\n return (\n <div data-testid=\"chart-area\" style={{ width: '100%', height }}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsAreaChart data={rows}>\n {showGrid ? <CartesianGrid strokeDasharray=\"3 3\" /> : null}\n <XAxis dataKey=\"name\" />\n <YAxis />\n <Tooltip />\n {showLegend ? <Legend /> : null}\n {chartData.datasets.map((ds, i) => {\n const color = colorFor(ds, i);\n return (\n <Area\n key={ds.label}\n type=\"monotone\"\n dataKey={`dataset${i}`}\n name={ds.label}\n stroke={color}\n fill={color}\n fillOpacity={0.3}\n />\n );\n })}\n </RechartsAreaChart>\n </ResponsiveContainer>\n </div>\n );\n}\n"]}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export { ArqelCreatePage as default } from './chunk-37FLEB4N.js';
|
|
2
|
-
import './chunk-MXUXMHOK.js';
|
|
3
|
-
import './chunk-MZMYV43C.js';
|
|
4
|
-
import './chunk-ZAM5TUPP.js';
|
|
5
|
-
import './chunk-H23VX3RR.js';
|
|
6
|
-
import './chunk-B7ULUJVO.js';
|
|
7
|
-
//# sourceMappingURL=ArqelCreatePage-MV4JN2MO.js.map
|
|
8
|
-
//# sourceMappingURL=ArqelCreatePage-MV4JN2MO.js.map
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export { ArqelDashboardPage as default } from './chunk-BJER6TOI.js';
|
|
2
|
-
import './chunk-HSDZM4AM.js';
|
|
3
|
-
import './chunk-PSPJA5U6.js';
|
|
4
|
-
import './chunk-B7ULUJVO.js';
|
|
5
|
-
//# sourceMappingURL=ArqelDashboardPage-QK3BYVK3.js.map
|
|
6
|
-
//# sourceMappingURL=ArqelDashboardPage-QK3BYVK3.js.map
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export { ArqelEditPage as default } from './chunk-UXN67E5L.js';
|
|
2
|
-
import './chunk-MXUXMHOK.js';
|
|
3
|
-
import './chunk-MZMYV43C.js';
|
|
4
|
-
import './chunk-ZAM5TUPP.js';
|
|
5
|
-
import './chunk-H23VX3RR.js';
|
|
6
|
-
import './chunk-B7ULUJVO.js';
|
|
7
|
-
//# sourceMappingURL=ArqelEditPage-7J3IS2BR.js.map
|
|
8
|
-
//# sourceMappingURL=ArqelEditPage-7J3IS2BR.js.map
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export { ArqelIndexPage as default } from './chunk-4I5S6MH3.js';
|
|
2
|
-
import './chunk-CVAMCRLL.js';
|
|
3
|
-
import './chunk-AZICSFBA.js';
|
|
4
|
-
import './chunk-RMPOR2YZ.js';
|
|
5
|
-
import './chunk-FP5R6WED.js';
|
|
6
|
-
import './chunk-3HN4ARGG.js';
|
|
7
|
-
import './chunk-MZMYV43C.js';
|
|
8
|
-
import './chunk-ZAM5TUPP.js';
|
|
9
|
-
import './chunk-H23VX3RR.js';
|
|
10
|
-
import './chunk-B7ULUJVO.js';
|
|
11
|
-
//# sourceMappingURL=ArqelIndexPage-R6JL5KOH.js.map
|
|
12
|
-
//# sourceMappingURL=ArqelIndexPage-R6JL5KOH.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/widgets/charts/BarChart.tsx"],"names":["RechartsBarChart"],"mappings":";;;;AAYO,SAAS,SAAS,EAAE,SAAA,EAAW,MAAA,EAAQ,UAAA,EAAY,UAAS,EAAkB;AACnF,EAAA,MAAM,IAAA,GAAO,WAAW,SAAS,CAAA;AACjC,EAAA,2BACG,KAAA,EAAA,EAAI,aAAA,EAAY,aAAY,KAAA,EAAO,EAAE,OAAO,MAAA,EAAQ,MAAA,IACnD,QAAA,kBAAA,GAAA,CAAC,mBAAA,EAAA,EAAoB,OAAM,MAAA,EAAO,MAAA,EAAO,QACvC,QAAA,kBAAA,IAAA,CAACA,UAAA,EAAA,EAAiB,MAAM,IAAA,EACrB,QAAA,EAAA;AAAA,IAAA,QAAA,mBAAW,GAAA,CAAC,aAAA,EAAA,EAAc,eAAA,EAAgB,KAAA,EAAM,CAAA,GAAK,IAAA;AAAA,oBACtD,GAAA,CAAC,KAAA,EAAA,EAAM,OAAA,EAAQ,MAAA,EAAO,CAAA;AAAA,wBACrB,KAAA,EAAA,EAAM,CAAA;AAAA,wBACN,OAAA,EAAA,EAAQ,CAAA;AAAA,IACR,UAAA,mBAAa,GAAA,CAAC,MAAA,EAAA,EAAO,CAAA,GAAK,IAAA;AAAA,IAC1B,SAAA,CAAU,SAAS,GAAA,CAAI,CAAC,IAAI,CAAA,qBAC3B,GAAA,CAAC,GAAA,EAAA,EAAmB,OAAA,EAAS,CAAA,OAAA,EAAU,CAAC,IAAI,IAAA,EAAM,EAAA,CAAG,OAAO,IAAA,EAAM,QAAA,CAAS,IAAI,CAAC,CAAA,EAAA,EAAtE,EAAA,CAAG,KAAsE,CACpF;AAAA,GAAA,EACH,GACF,CAAA,EACF,CAAA;AAEJ","file":"BarChart-KLHKTLO2.js","sourcesContent":["import {\n Bar,\n CartesianGrid,\n Legend,\n BarChart as RechartsBarChart,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from 'recharts';\nimport { type ChartSubProps, colorFor, toRowShape } from '../types';\n\nexport function BarChart({ chartData, height, showLegend, showGrid }: ChartSubProps) {\n const rows = toRowShape(chartData);\n return (\n <div data-testid=\"chart-bar\" style={{ width: '100%', height }}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsBarChart data={rows}>\n {showGrid ? <CartesianGrid strokeDasharray=\"3 3\" /> : null}\n <XAxis dataKey=\"name\" />\n <YAxis />\n <Tooltip />\n {showLegend ? <Legend /> : null}\n {chartData.datasets.map((ds, i) => (\n <Bar key={ds.label} dataKey={`dataset${i}`} name={ds.label} fill={colorFor(ds, i)} />\n ))}\n </RechartsBarChart>\n </ResponsiveContainer>\n </div>\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/widgets/charts/LineChart.tsx"],"names":["RechartsLineChart"],"mappings":";;;;AAYO,SAAS,UAAU,EAAE,SAAA,EAAW,MAAA,EAAQ,UAAA,EAAY,UAAS,EAAkB;AACpF,EAAA,MAAM,IAAA,GAAO,WAAW,SAAS,CAAA;AACjC,EAAA,2BACG,KAAA,EAAA,EAAI,aAAA,EAAY,cAAa,KAAA,EAAO,EAAE,OAAO,MAAA,EAAQ,MAAA,IACpD,QAAA,kBAAA,GAAA,CAAC,mBAAA,EAAA,EAAoB,OAAM,MAAA,EAAO,MAAA,EAAO,QACvC,QAAA,kBAAA,IAAA,CAACA,WAAA,EAAA,EAAkB,MAAM,IAAA,EACtB,QAAA,EAAA;AAAA,IAAA,QAAA,mBAAW,GAAA,CAAC,aAAA,EAAA,EAAc,eAAA,EAAgB,KAAA,EAAM,CAAA,GAAK,IAAA;AAAA,oBACtD,GAAA,CAAC,KAAA,EAAA,EAAM,OAAA,EAAQ,MAAA,EAAO,CAAA;AAAA,wBACrB,KAAA,EAAA,EAAM,CAAA;AAAA,wBACN,OAAA,EAAA,EAAQ,CAAA;AAAA,IACR,UAAA,mBAAa,GAAA,CAAC,MAAA,EAAA,EAAO,CAAA,GAAK,IAAA;AAAA,IAC1B,SAAA,CAAU,QAAA,CAAS,GAAA,CAAI,CAAC,IAAI,CAAA,qBAC3B,GAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QAEC,IAAA,EAAK,UAAA;AAAA,QACL,OAAA,EAAS,UAAU,CAAC,CAAA,CAAA;AAAA,QACpB,MAAM,EAAA,CAAG,KAAA;AAAA,QACT,MAAA,EAAQ,QAAA,CAAS,EAAA,EAAI,CAAC,CAAA;AAAA,QACtB,WAAA,EAAa,CAAA;AAAA,QACb,GAAA,EAAK;AAAA,OAAA;AAAA,MANA,EAAA,CAAG;AAAA,KAQX;AAAA,GAAA,EACH,GACF,CAAA,EACF,CAAA;AAEJ","file":"LineChart-GHMPHFZZ.js","sourcesContent":["import {\n CartesianGrid,\n Legend,\n Line,\n LineChart as RechartsLineChart,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from 'recharts';\nimport { type ChartSubProps, colorFor, toRowShape } from '../types';\n\nexport function LineChart({ chartData, height, showLegend, showGrid }: ChartSubProps) {\n const rows = toRowShape(chartData);\n return (\n <div data-testid=\"chart-line\" style={{ width: '100%', height }}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsLineChart data={rows}>\n {showGrid ? <CartesianGrid strokeDasharray=\"3 3\" /> : null}\n <XAxis dataKey=\"name\" />\n <YAxis />\n <Tooltip />\n {showLegend ? <Legend /> : null}\n {chartData.datasets.map((ds, i) => (\n <Line\n key={ds.label}\n type=\"monotone\"\n dataKey={`dataset${i}`}\n name={ds.label}\n stroke={colorFor(ds, i)}\n strokeWidth={2}\n dot={false}\n />\n ))}\n </RechartsLineChart>\n </ResponsiveContainer>\n </div>\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/widgets/charts/RadarChart.tsx"],"names":["RechartsRadarChart"],"mappings":";;;;AAYO,SAAS,WAAW,EAAE,SAAA,EAAW,MAAA,EAAQ,UAAA,EAAY,UAAS,EAAkB;AACrF,EAAA,MAAM,IAAA,GAAO,WAAW,SAAS,CAAA;AAEjC,EAAA,2BACG,KAAA,EAAA,EAAI,aAAA,EAAY,eAAc,KAAA,EAAO,EAAE,OAAO,MAAA,EAAQ,MAAA,IACrD,QAAA,kBAAA,GAAA,CAAC,mBAAA,EAAA,EAAoB,OAAM,MAAA,EAAO,MAAA,EAAO,QACvC,QAAA,kBAAA,IAAA,CAACA,YAAA,EAAA,EAAmB,MAAM,IAAA,EACvB,QAAA,EAAA;AAAA,IAAA,QAAA,mBAAW,GAAA,CAAC,aAAU,CAAA,GAAK,IAAA;AAAA,oBAC5B,GAAA,CAAC,cAAA,EAAA,EAAe,OAAA,EAAQ,MAAA,EAAO,CAAA;AAAA,wBAC9B,eAAA,EAAA,EAAgB,CAAA;AAAA,IAChB,SAAA,CAAU,QAAA,CAAS,GAAA,CAAI,CAAC,IAAI,CAAA,KAAM;AACjC,MAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,EAAA,EAAI,CAAC,CAAA;AAC5B,MAAA,uBACE,GAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UAEC,OAAA,EAAS,UAAU,CAAC,CAAA,CAAA;AAAA,UACpB,MAAM,EAAA,CAAG,KAAA;AAAA,UACT,MAAA,EAAQ,KAAA;AAAA,UACR,IAAA,EAAM,KAAA;AAAA,UACN,WAAA,EAAa;AAAA,SAAA;AAAA,QALR,EAAA,CAAG;AAAA,OAMV;AAAA,IAEJ,CAAC,CAAA;AAAA,wBACA,OAAA,EAAA,EAAQ,CAAA;AAAA,IACR,UAAA,mBAAa,GAAA,CAAC,MAAA,EAAA,EAAO,CAAA,GAAK;AAAA,GAAA,EAC7B,GACF,CAAA,EACF,CAAA;AAEJ","file":"RadarChart-CSWR5AO7.js","sourcesContent":["import {\n Legend,\n PolarAngleAxis,\n PolarGrid,\n PolarRadiusAxis,\n Radar,\n RadarChart as RechartsRadarChart,\n ResponsiveContainer,\n Tooltip,\n} from 'recharts';\nimport { type ChartSubProps, colorFor, toRowShape } from '../types';\n\nexport function RadarChart({ chartData, height, showLegend, showGrid }: ChartSubProps) {\n const rows = toRowShape(chartData);\n\n return (\n <div data-testid=\"chart-radar\" style={{ width: '100%', height }}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsRadarChart data={rows}>\n {showGrid ? <PolarGrid /> : null}\n <PolarAngleAxis dataKey=\"name\" />\n <PolarRadiusAxis />\n {chartData.datasets.map((ds, i) => {\n const color = colorFor(ds, i);\n return (\n <Radar\n key={ds.label}\n dataKey={`dataset${i}`}\n name={ds.label}\n stroke={color}\n fill={color}\n fillOpacity={0.3}\n />\n );\n })}\n <Tooltip />\n {showLegend ? <Legend /> : null}\n </RechartsRadarChart>\n </ResponsiveContainer>\n </div>\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
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-37FLEB4N.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"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/table/cells.tsx","../src/table/DataTable.tsx","../src/table/TableFilters.tsx","../src/table/TablePagination.tsx","../src/table/TableToolbar.tsx"],"names":["jsx","jsxs","useArqelTranslations"],"mappings":"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","file":"chunk-AZICSFBA.js","sourcesContent":["/**\n * Column cell renderers — one per `ColumnType` discriminant.\n *\n * `<TableCell column={column} value={...} record={...} />` dispatches on\n * `column.type` so DataTable stays free of polymorphic rendering. Cells\n * never reach into the network themselves; everything they need comes\n * from props serialised server-side.\n */\n\nimport type {\n BadgeColumnSchema,\n BooleanColumnSchema,\n ColumnSchema,\n ComputedColumnSchema,\n DateColumnSchema,\n IconColumnSchema,\n ImageColumnSchema,\n NumberColumnSchema,\n RelationshipColumnSchema,\n TextColumnSchema,\n} from '@arqel-dev/types/tables';\nimport { cn } from '../utils/cn.js';\nimport { resolveLucideIcon } from '../utils/icon.js';\n\nexport interface CellProps {\n column: ColumnSchema;\n value: unknown;\n}\n\nexport function TableCell({ column, value }: CellProps) {\n switch (column.type) {\n case 'text':\n return <TextCell column={column} value={value} />;\n case 'badge':\n return <BadgeCell column={column} value={value} />;\n case 'boolean':\n return <BooleanCell column={column} value={value} />;\n case 'date':\n return <DateCell column={column} value={value} />;\n case 'number':\n return <NumberCell column={column} value={value} />;\n case 'icon':\n return <IconCell column={column} />;\n case 'image':\n return <ImageCell column={column} value={value} />;\n case 'relationship':\n return <RelationshipCell column={column} value={value} />;\n case 'computed':\n return <ComputedCell column={column} value={value} />;\n }\n}\n\nfunction asString(value: unknown): string {\n if (value === null || value === undefined) return '';\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n return JSON.stringify(value);\n}\n\nfunction TextCell({ column, value }: { column: TextColumnSchema; value: unknown }) {\n const str = asString(value);\n const truncated =\n column.props.truncate && str.length > column.props.truncate\n ? `${str.slice(0, column.props.truncate)}…`\n : str;\n return (\n <span\n className={cn(\n column.props.weight === 'bold' && 'font-bold',\n column.props.weight === 'medium' && 'font-medium',\n )}\n >\n {truncated}\n </span>\n );\n}\n\n/**\n * Colour token → Tailwind classes for `BadgeColumn::colors()`.\n *\n * Tokens mirror the values the PHP producer emits (e.g. `'green'`,\n * `'yellow'`, `'blue'`). Classes are written out in full so Tailwind's\n * JIT can statically discover them. Unknown tokens fall back to muted.\n */\nconst BADGE_COLOR_CLASS: Record<string, string> = {\n gray: 'bg-muted text-foreground',\n slate: 'bg-slate-100 text-slate-800 dark:bg-slate-800/40 dark:text-slate-200',\n zinc: 'bg-zinc-100 text-zinc-800 dark:bg-zinc-800/40 dark:text-zinc-200',\n red: 'bg-red-100 text-red-800 dark:bg-red-900/40 dark:text-red-200',\n orange: 'bg-orange-100 text-orange-800 dark:bg-orange-900/40 dark:text-orange-200',\n amber: 'bg-amber-100 text-amber-800 dark:bg-amber-900/40 dark:text-amber-200',\n yellow: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900/40 dark:text-yellow-200',\n lime: 'bg-lime-100 text-lime-800 dark:bg-lime-900/40 dark:text-lime-200',\n green: 'bg-green-100 text-green-800 dark:bg-green-900/40 dark:text-green-200',\n emerald: 'bg-emerald-100 text-emerald-800 dark:bg-emerald-900/40 dark:text-emerald-200',\n teal: 'bg-teal-100 text-teal-800 dark:bg-teal-900/40 dark:text-teal-200',\n cyan: 'bg-cyan-100 text-cyan-800 dark:bg-cyan-900/40 dark:text-cyan-200',\n sky: 'bg-sky-100 text-sky-800 dark:bg-sky-900/40 dark:text-sky-200',\n blue: 'bg-blue-100 text-blue-800 dark:bg-blue-900/40 dark:text-blue-200',\n indigo: 'bg-indigo-100 text-indigo-800 dark:bg-indigo-900/40 dark:text-indigo-200',\n violet: 'bg-violet-100 text-violet-800 dark:bg-violet-900/40 dark:text-violet-200',\n purple: 'bg-purple-100 text-purple-800 dark:bg-purple-900/40 dark:text-purple-200',\n fuchsia: 'bg-fuchsia-100 text-fuchsia-800 dark:bg-fuchsia-900/40 dark:text-fuchsia-200',\n pink: 'bg-pink-100 text-pink-800 dark:bg-pink-900/40 dark:text-pink-200',\n rose: 'bg-rose-100 text-rose-800 dark:bg-rose-900/40 dark:text-rose-200',\n};\n\nconst BADGE_MUTED_CLASS = 'bg-muted text-foreground';\n\nfunction BadgeCell({ column, value }: { column: BadgeColumnSchema; value: unknown }) {\n const key = asString(value);\n const option = column.props.options?.find((o) => o.value === value);\n const label = option?.label ?? key;\n\n const colorToken = column.props.colors?.[key];\n const colorClass = (colorToken && BADGE_COLOR_CLASS[colorToken]) || BADGE_MUTED_CLASS;\n\n const iconName = column.props.icons?.[key];\n const Icon = iconName ? resolveLucideIcon(iconName) : undefined;\n\n return (\n <span\n className={cn(\n 'inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium',\n column.props.pill ? 'rounded-full' : 'rounded-sm',\n colorClass,\n )}\n >\n {Icon ? <Icon className=\"size-3 shrink-0\" aria-hidden /> : null}\n {label}\n </span>\n );\n}\n\nfunction BooleanCell({ column, value }: { column: BooleanColumnSchema; value: unknown }) {\n const truthy = Boolean(value);\n return (\n <span role=\"img\" aria-label={truthy ? 'true' : 'false'}>\n {truthy ? (column.props.trueIcon ?? '✓') : (column.props.falseIcon ?? '—')}\n </span>\n );\n}\n\nfunction DateCell({ column, value }: { column: DateColumnSchema; value: unknown }) {\n if (!value) return <span className=\"text-muted-foreground\">—</span>;\n const raw = String(value);\n const date = new Date(raw);\n if (Number.isNaN(date.getTime())) return <span>{raw}</span>;\n if (column.props.mode === 'since') {\n return <time dateTime={date.toISOString()}>{formatRelative(date)}</time>;\n }\n if (column.props.mode === 'datetime') {\n return <time dateTime={date.toISOString()}>{date.toLocaleString()}</time>;\n }\n return <time dateTime={date.toISOString()}>{date.toLocaleDateString()}</time>;\n}\n\nfunction formatRelative(date: Date): string {\n const seconds = Math.round((Date.now() - date.getTime()) / 1000);\n if (seconds < 60) return `${seconds}s ago`;\n const minutes = Math.round(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.round(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.round(hours / 24);\n return `${days}d ago`;\n}\n\nfunction NumberCell({ column, value }: { column: NumberColumnSchema; value: unknown }) {\n if (value === null || value === undefined) return <span>—</span>;\n const num = typeof value === 'number' ? value : Number(value);\n if (Number.isNaN(num)) return <span>{asString(value)}</span>;\n const formatted = num.toFixed(column.props.decimals ?? 0);\n const [whole, dec] = formatted.split('.');\n const safeWhole = whole ?? '0';\n const ts = column.props.thousandsSeparator;\n const finalWhole = ts ? safeWhole.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ts) : safeWhole;\n const ds = column.props.decimalSeparator ?? '.';\n return (\n <span>\n {column.props.prefix ?? ''}\n {finalWhole}\n {dec ? `${ds}${dec}` : ''}\n {column.props.suffix ?? ''}\n </span>\n );\n}\n\nfunction IconCell({ column }: { column: IconColumnSchema }) {\n return (\n <span role=\"img\" aria-label={column.props.icon} title={column.props.icon}>\n {column.props.icon}\n </span>\n );\n}\n\nfunction ImageCell({ column, value }: { column: ImageColumnSchema; value: unknown }) {\n const src = asString(value);\n if (!src) return null;\n const size = column.props.size ?? 32;\n return (\n <img\n src={src}\n alt=\"\"\n style={{ width: size, height: size }}\n className={cn(column.props.shape === 'circular' ? 'rounded-full' : 'rounded')}\n />\n );\n}\n\nfunction RelationshipCell({ column, value }: { column: RelationshipColumnSchema; value: unknown }) {\n if (value === null || value === undefined) return <span>—</span>;\n if (typeof value === 'object') {\n const attr = (value as Record<string, unknown>)[column.props.attribute];\n return <span>{asString(attr)}</span>;\n }\n return <span>{asString(value)}</span>;\n}\n\nfunction ComputedCell({ column, value }: { column: ComputedColumnSchema; value: unknown }) {\n if (value === null || value === undefined) {\n return <span className=\"text-muted-foreground\">{column.props.placeholder ?? '—'}</span>;\n }\n return <span>{asString(value)}</span>;\n}\n","/**\n * `<DataTable>` — generic table built on TanStack Table v8.\n *\n * Columns come from `ColumnSchema[]` (server-emitted). Two structural\n * extras live outside the schema list: a leading selection checkbox\n * (when `enableSelection`) and a trailing actions cell (when\n * `rowActions` resolver is provided).\n *\n * Selection model is controlled — pass `selectedIds` + `onSelectionChange`\n * — so callers (ResourceIndex, custom dashboards) keep ownership. Shift+\n * click on a row checkbox selects the range from the last clicked row,\n * matching the canonical Filament/Linear UX.\n */\n\nimport type { ColumnSchema, SortDirection, TableSort } from '@arqel-dev/types/tables';\nimport {\n type ColumnDef,\n flexRender,\n getCoreRowModel,\n type Row,\n useReactTable,\n} from '@tanstack/react-table';\nimport type { ReactNode } from 'react';\nimport { useCallback, useMemo, useRef } from 'react';\nimport { cn } from '../utils/cn.js';\nimport { TableCell } from './cells.js';\n\ntype RowId = string | number;\n\nexport interface DataTableRecord {\n id: RowId;\n [key: string]: unknown;\n}\n\nexport interface DataTableProps<TRecord extends DataTableRecord> {\n columns: ColumnSchema[];\n records: TRecord[];\n\n enableSelection?: boolean;\n selectedIds?: ReadonlyArray<RowId>;\n onSelectionChange?: ((ids: RowId[]) => void) | undefined;\n\n sort?: TableSort | null;\n onSortChange?: ((column: string, direction: SortDirection) => void) | undefined;\n\n rowActions?: ((record: TRecord) => ReactNode) | undefined;\n\n loading?: boolean;\n emptyState?: ReactNode;\n\n className?: string;\n}\n\nexport function DataTable<TRecord extends DataTableRecord>({\n columns,\n records,\n enableSelection = false,\n selectedIds = [],\n onSelectionChange,\n sort = null,\n onSortChange,\n rowActions,\n loading = false,\n emptyState,\n className,\n}: DataTableProps<TRecord>) {\n const lastClickedIndexRef = useRef<number | null>(null);\n\n const visibleColumns = useMemo(() => columns.filter((col) => !col.hidden), [columns]);\n\n const tableColumns = useMemo<ColumnDef<TRecord>[]>(\n () =>\n visibleColumns.map((col) => ({\n id: col.name,\n accessorFn: (row) => (row as Record<string, unknown>)[col.name],\n header: () => col.label ?? col.name,\n cell: (info) => <TableCell column={col} value={info.getValue()} />,\n enableSorting: col.sortable,\n })),\n [visibleColumns],\n );\n\n const table = useReactTable({\n data: records,\n columns: tableColumns,\n getCoreRowModel: getCoreRowModel(),\n });\n\n const allSelected =\n enableSelection && records.length > 0 && selectedIds.length === records.length;\n const someSelected =\n enableSelection && selectedIds.length > 0 && selectedIds.length < records.length;\n\n const toggleAll = useCallback(() => {\n if (!onSelectionChange) return;\n if (allSelected) onSelectionChange([]);\n else onSelectionChange(records.map((r) => r.id));\n }, [allSelected, records, onSelectionChange]);\n\n const toggleRow = useCallback(\n (id: RowId, index: number, shiftKey: boolean) => {\n if (!onSelectionChange) return;\n // `index` is the row's position in the core row-model, which today equals the\n // `records` prop order (only getCoreRowModel is wired — no client sort/filter\n // row model). The shift-range loop resolves ids from `records[i]`, so this\n // holds only while that ordering parity is true; revisit if a client-side\n // sorted/filtered row model is added.\n const set = new Set<RowId>(selectedIds);\n const lastIndex = lastClickedIndexRef.current;\n\n if (shiftKey && lastIndex !== null) {\n const [from, to] = lastIndex < index ? [lastIndex, index] : [index, lastIndex];\n const shouldSelect = !set.has(id);\n for (let i = from; i <= to; i++) {\n const rowId = records[i]?.id;\n if (rowId === undefined) continue;\n if (shouldSelect) set.add(rowId);\n else set.delete(rowId);\n }\n } else if (set.has(id)) {\n set.delete(id);\n } else {\n set.add(id);\n }\n\n lastClickedIndexRef.current = index;\n onSelectionChange(Array.from(set));\n },\n [records, selectedIds, onSelectionChange],\n );\n\n const headerSortDirection = (columnName: string): SortDirection | null => {\n if (!sort || sort.column !== columnName) return null;\n return sort.direction === 'desc' ? 'desc' : 'asc';\n };\n\n return (\n <>\n <div className={cn('hidden w-full min-w-0 overflow-x-auto md:block', className)}>\n <table className=\"w-full border-collapse text-sm\">\n <thead className=\"sticky top-0 bg-background\">\n {table.getHeaderGroups().map((group) => (\n <tr key={group.id} className=\"border-b border-border\">\n {enableSelection && (\n <th scope=\"col\" className=\"w-10 px-3 py-2 text-left\">\n <input\n type=\"checkbox\"\n aria-label=\"Select all rows\"\n checked={allSelected}\n ref={(el) => {\n if (el) el.indeterminate = someSelected;\n }}\n onChange={toggleAll}\n />\n </th>\n )}\n {group.headers.map((header) => {\n const col = visibleColumns.find((c) => c.name === header.column.id);\n const sortable = col?.sortable && onSortChange;\n const direction = headerSortDirection(header.column.id);\n return (\n <th\n key={header.id}\n scope=\"col\"\n className={cn(\n 'px-3 py-2 text-left font-medium text-muted-foreground',\n col?.align === 'center' && 'text-center',\n col?.align === 'end' && 'text-right',\n col?.hiddenOnMobile && 'hidden md:table-cell',\n )}\n aria-sort={\n direction === 'asc'\n ? 'ascending'\n : direction === 'desc'\n ? 'descending'\n : 'none'\n }\n >\n {sortable ? (\n <button\n type=\"button\"\n className={cn(\n // -mx-3 px-3 stretches the button across the cell's\n // horizontal padding; min-h-11 + w-full give a ≥44px\n // touch target on mobile (WCAG 2.5.5) without changing\n // the header's visual density.\n '-mx-3 inline-flex min-h-11 w-full items-center gap-1 px-3 hover:text-foreground',\n col?.align === 'center' && 'justify-center',\n col?.align === 'end' && 'justify-end',\n )}\n onClick={() =>\n onSortChange(header.column.id, direction === 'asc' ? 'desc' : 'asc')\n }\n >\n {flexRender(header.column.columnDef.header, header.getContext())}\n <span aria-hidden=\"true\">\n {direction === 'asc' ? '▲' : direction === 'desc' ? '▼' : '↕'}\n </span>\n </button>\n ) : (\n flexRender(header.column.columnDef.header, header.getContext())\n )}\n </th>\n );\n })}\n {rowActions && (\n <th scope=\"col\" className=\"w-24 px-3 py-2 text-right\" aria-label=\"Actions\" />\n )}\n </tr>\n ))}\n </thead>\n <tbody>\n {loading && (\n <tr>\n <td\n colSpan={visibleColumns.length + (enableSelection ? 1 : 0) + (rowActions ? 1 : 0)}\n className=\"px-3 py-4 text-center text-muted-foreground\"\n >\n Loading…\n </td>\n </tr>\n )}\n {!loading && records.length === 0 && (\n <tr>\n <td\n colSpan={visibleColumns.length + (enableSelection ? 1 : 0) + (rowActions ? 1 : 0)}\n className=\"px-3 py-8 text-center text-muted-foreground\"\n >\n {emptyState ?? 'No records found.'}\n </td>\n </tr>\n )}\n {!loading &&\n table.getRowModel().rows.map((row, index) => {\n const record = row.original;\n const checked = selectedIds.includes(record.id);\n return (\n <tr\n key={row.id}\n data-selected={checked || undefined}\n className={cn('border-b border-border', checked && 'bg-muted')}\n >\n {enableSelection && (\n <td className=\"w-10 px-3 py-2\">\n <input\n type=\"checkbox\"\n aria-label={`Select row ${record.id}`}\n checked={checked}\n onChange={(event) => {\n const native = event.nativeEvent as MouseEvent;\n toggleRow(record.id, index, native.shiftKey === true);\n }}\n />\n </td>\n )}\n {row.getVisibleCells().map((cell) => {\n const col = visibleColumns.find((c) => c.name === cell.column.id);\n return (\n <td\n key={cell.id}\n className={cn(\n 'px-3 py-2',\n col?.align === 'center' && 'text-center',\n col?.align === 'end' && 'text-right',\n col?.hiddenOnMobile && 'hidden md:table-cell',\n )}\n >\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </td>\n );\n })}\n {rowActions && (\n <td className=\"w-24 px-3 py-2 text-right\">{rowActions(record)}</td>\n )}\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n <DataCards\n columns={visibleColumns}\n rows={table.getRowModel().rows}\n enableSelection={enableSelection}\n selectedIds={selectedIds}\n onToggleRow={toggleRow}\n rowActions={rowActions}\n loading={loading}\n emptyState={emptyState}\n />\n </>\n );\n}\n\ninterface DataCardsProps<TRecord extends DataTableRecord> {\n columns: ColumnSchema[];\n rows: Row<TRecord>[];\n enableSelection: boolean;\n selectedIds: ReadonlyArray<RowId>;\n onToggleRow: (id: RowId, index: number, shiftKey: boolean) => void;\n rowActions?: ((record: TRecord) => ReactNode) | undefined;\n loading: boolean;\n emptyState?: ReactNode;\n}\n\nfunction DataCards<TRecord extends DataTableRecord>({\n columns,\n rows,\n enableSelection,\n selectedIds,\n onToggleRow,\n rowActions,\n loading,\n emptyState,\n}: DataCardsProps<TRecord>) {\n // hiddenOnMobile columns are dropped from the card body (same intent as the\n // table hiding them at < md).\n const cardColumns = columns.filter((col) => !col.hiddenOnMobile);\n\n if (loading) {\n return <div className=\"px-3 py-4 text-center text-muted-foreground md:hidden\">Loading…</div>;\n }\n if (rows.length === 0) {\n return (\n <div className=\"px-3 py-8 text-center text-muted-foreground md:hidden\">\n {emptyState ?? 'No records found.'}\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col gap-3 md:hidden\">\n {rows.map((row, index) => {\n const record = row.original;\n const checked = selectedIds.includes(record.id);\n return (\n <article\n key={row.id}\n data-arqel-data-card=\"\"\n data-selected={checked || undefined}\n className={cn('rounded-lg border border-border p-4 text-sm', checked && 'bg-muted')}\n >\n {(enableSelection || rowActions) && (\n <div className=\"mb-3 flex items-center justify-between gap-2\">\n {enableSelection ? (\n <label className=\"-m-2.5 inline-flex size-11 cursor-pointer items-center justify-center p-2.5\">\n <input\n type=\"checkbox\"\n aria-label={`Select row ${record.id}`}\n className=\"size-5\"\n checked={checked}\n onChange={(event) => {\n const native = event.nativeEvent as MouseEvent;\n onToggleRow(record.id, index, native.shiftKey === true);\n }}\n />\n </label>\n ) : (\n <span />\n )}\n {rowActions ? <div className=\"ml-auto\">{rowActions(record)}</div> : null}\n </div>\n )}\n <dl className=\"grid grid-cols-[minmax(0,auto)_1fr] gap-x-3 gap-y-2\">\n {cardColumns.map((col) => (\n <div key={col.name} className=\"contents\">\n <dt className=\"font-medium text-muted-foreground\">{col.label ?? col.name}</dt>\n <dd\n className={cn(\n 'min-w-0 break-words',\n col.align === 'end' && 'text-right',\n col.align === 'center' && 'text-center',\n )}\n >\n <TableCell column={col} value={(record as Record<string, unknown>)[col.name]} />\n </dd>\n </div>\n ))}\n </dl>\n </article>\n );\n })}\n </div>\n );\n}\n","/**\n * `<TableFilters>` — renders one input per `FilterSchema` and emits\n * a single `onChange(name, value)` callback. Active values render as\n * dismissible chips so users can read state without re-opening menus.\n *\n * Phase 1 covers the four most-used filter types (select, multiSelect,\n * text, ternary). dateRange / scope land alongside FieldRenderer in\n * UI-004, where the date primitives ship.\n */\n\nimport { useArqelTranslations } from '@arqel-dev/react/utils';\nimport type {\n FilterSchema,\n MultiSelectFilterSchema,\n SelectFilterSchema,\n TernaryFilterSchema,\n TextFilterSchema,\n} from '@arqel-dev/types/tables';\nimport { Button } from '../action/Button.js';\nimport { cn } from '../utils/cn.js';\n\nexport interface TableFiltersProps {\n filters: FilterSchema[];\n values: Record<string, unknown>;\n onChange: (name: string, value: unknown) => void;\n onClearAll?: (() => void) | undefined;\n className?: string | undefined;\n}\n\nexport function TableFilters({\n filters,\n values,\n onChange,\n onClearAll,\n className,\n}: TableFiltersProps) {\n const t = useArqelTranslations();\n if (filters.length === 0) return null;\n\n const activeCount = filters.reduce((acc, f) => {\n const v = values[f.name];\n return v !== undefined && v !== null && v !== '' ? acc + 1 : acc;\n }, 0);\n\n return (\n <fieldset className={cn('flex flex-wrap items-end gap-2 border-0 p-0', className)}>\n <legend className=\"sr-only\">Filters</legend>\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 {activeCount > 0 && onClearAll && (\n <Button variant=\"ghost\" size=\"sm\" onClick={onClearAll}>\n {t('table.filters.clear', `Clear filters (${activeCount})`, { count: activeCount })}\n </Button>\n )}\n </fieldset>\n );\n}\n\nfunction FilterControl({\n filter,\n value,\n onChange,\n}: {\n filter: FilterSchema;\n value: unknown;\n onChange: (value: unknown) => void;\n}) {\n switch (filter.type) {\n case 'select':\n return <SelectFilter filter={filter} value={value} onChange={onChange} />;\n case 'multiSelect':\n return <MultiSelectFilter filter={filter} value={value} onChange={onChange} />;\n case 'text':\n return <TextFilter filter={filter} value={value} onChange={onChange} />;\n case 'ternary':\n return <TernaryFilter filter={filter} value={value} onChange={onChange} />;\n case 'dateRange':\n case 'scope':\n return null;\n }\n}\n\nfunction controlClasses() {\n return cn(\n // 44px touch target on mobile (WCAG 2.5.5); dense 36px on >=md.\n 'h-11 rounded-sm border border-[var(--input)] md:h-9',\n 'bg-background px-3 text-sm',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n );\n}\n\nfunction SelectFilter({\n filter,\n value,\n onChange,\n}: {\n filter: SelectFilterSchema;\n value: unknown;\n onChange: (value: unknown) => void;\n}) {\n const t = useArqelTranslations();\n return (\n <label className=\"flex flex-col gap-1 text-xs text-muted-foreground\">\n {filter.label ?? filter.name}\n <select\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 {filter.props.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 MultiSelectFilter({\n filter,\n value,\n onChange,\n}: {\n filter: MultiSelectFilterSchema;\n value: unknown;\n onChange: (value: unknown) => void;\n}) {\n const arr = Array.isArray(value) ? (value as Array<string | number>) : [];\n return (\n <label className=\"flex flex-col gap-1 text-xs text-muted-foreground\">\n {filter.label ?? filter.name}\n <select\n multiple\n className={cn(controlClasses(), 'h-auto min-h-11 py-1 md:min-h-[2.25rem]')}\n value={arr.map(String)}\n onChange={(e) => {\n const next = Array.from(e.target.selectedOptions, (o) => o.value);\n onChange(next.length === 0 ? null : next);\n }}\n >\n {filter.props.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 TextFilter({\n filter,\n value,\n onChange,\n}: {\n filter: TextFilterSchema;\n value: unknown;\n onChange: (value: unknown) => void;\n}) {\n return (\n <label className=\"flex flex-col gap-1 text-xs text-muted-foreground\">\n {filter.label ?? filter.name}\n <input\n type=\"text\"\n className={controlClasses()}\n value={typeof value === 'string' ? value : ''}\n onChange={(e) => onChange(e.target.value === '' ? null : e.target.value)}\n />\n </label>\n );\n}\n\nfunction TernaryFilter({\n filter,\n value,\n onChange,\n}: {\n filter: TernaryFilterSchema;\n value: unknown;\n onChange: (value: unknown) => void;\n}) {\n const t = useArqelTranslations();\n const current = value === undefined || value === null ? 'all' : String(value);\n return (\n <label className=\"flex flex-col gap-1 text-xs text-muted-foreground\">\n {filter.label ?? filter.name}\n <select\n className={controlClasses()}\n value={current}\n onChange={(e) => {\n const v = e.target.value;\n onChange(v === 'all' ? null : v);\n }}\n >\n <option value=\"all\">{filter.props.allLabel ?? t('table.filters.all', 'All')}</option>\n <option value=\"true\">{filter.props.trueLabel ?? 'Yes'}</option>\n <option value=\"false\">{filter.props.falseLabel ?? 'No'}</option>\n </select>\n </label>\n );\n}\n","/**\n * `<TablePagination>` — prev/next + range + per-page picker.\n *\n * Stateless: parent owns `currentPage` / `perPage` and handles transitions\n * (typically via Inertia `router.get` with `preserveState: true`).\n */\n\nimport { useArqelTranslations } from '@arqel-dev/react/utils';\nimport type { PaginationMeta } from '@arqel-dev/types/resources';\nimport { Button } from '../action/Button.js';\nimport { cn } from '../utils/cn.js';\n\nexport interface TablePaginationProps {\n meta: PaginationMeta;\n onPageChange: (page: number) => void;\n onPerPageChange?: ((perPage: number) => void) | undefined;\n perPageOptions?: number[];\n className?: string;\n}\n\nexport function TablePagination({\n meta,\n onPageChange,\n onPerPageChange,\n perPageOptions = [10, 25, 50, 100],\n className,\n}: TablePaginationProps) {\n const t = useArqelTranslations();\n const from = (meta.currentPage - 1) * meta.perPage + 1;\n const to = Math.min(meta.currentPage * meta.perPage, meta.total);\n const isFirst = meta.currentPage <= 1;\n const isLast = meta.currentPage >= meta.lastPage;\n\n return (\n <nav\n className={cn(\n 'flex flex-wrap items-center justify-between gap-2 border-t border-border px-3 py-2 text-sm',\n className,\n )}\n aria-label=\"Pagination\"\n >\n <span className=\"text-muted-foreground\">\n {meta.total === 0 ? t('table.empty', 'No results') : `${from}–${to} of ${meta.total}`}\n </span>\n <div className=\"flex items-center gap-2\">\n {onPerPageChange && (\n <label className=\"flex items-center gap-1 text-xs text-muted-foreground\">\n {t('table.per_page', 'Per page')}\n {/* 44px touch target on mobile (WCAG 2.5.5); dense 32px on >=md. */}\n <select\n className=\"h-11 rounded-sm border border-[var(--input)] bg-background px-2 md:h-8\"\n value={meta.perPage}\n onChange={(e) => onPerPageChange(Number(e.target.value))}\n >\n {perPageOptions.map((n) => (\n <option key={n} value={n}>\n {n}\n </option>\n ))}\n </select>\n </label>\n )}\n {/* Buttons use size=\"sm\" (h-8) for the dense desktop bar; the responsive\n h-11 override lifts them to a 44px touch target below md. */}\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"h-11 md:h-8\"\n disabled={isFirst}\n onClick={() => onPageChange(meta.currentPage - 1)}\n aria-label={t('table.pagination.previous_page', 'Previous page')}\n >\n {t('table.pagination.previous', 'Prev')}\n </Button>\n <span className=\"text-xs text-muted-foreground\">\n {meta.currentPage} / {meta.lastPage}\n </span>\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"h-11 md:h-8\"\n disabled={isLast}\n onClick={() => onPageChange(meta.currentPage + 1)}\n aria-label={t('table.pagination.next_page', 'Next page')}\n >\n {t('table.pagination.next', 'Next')}\n </Button>\n </div>\n </nav>\n );\n}\n","/**\n * `<TableToolbar>` — search input + filters + bulk-action bar slot.\n *\n * The bulk-action bar appears only when `selectedCount > 0`. ResourceIndex\n * passes `bulkActions` rendered as a row of buttons; the toolbar just\n * positions them.\n */\n\nimport { useArqelTranslations } from '@arqel-dev/react/utils';\nimport type { ReactNode } from 'react';\nimport { cn } from '../utils/cn.js';\n\nexport interface TableToolbarProps {\n search?: ReactNode;\n filters?: ReactNode;\n selectedCount?: number;\n bulkActions?: ReactNode;\n onClearSelection?: (() => void) | undefined;\n className?: string;\n}\n\nexport function TableToolbar({\n search,\n filters,\n selectedCount = 0,\n bulkActions,\n onClearSelection,\n className,\n}: TableToolbarProps) {\n const t = useArqelTranslations();\n return (\n <div className={cn('flex flex-col gap-3 px-3 py-3', className)}>\n <div className=\"flex flex-wrap items-end gap-2\">\n {search}\n {filters}\n </div>\n {selectedCount > 0 && (\n <section\n className=\"flex flex-wrap items-center gap-2 rounded-sm border border-border bg-muted px-3 py-2\"\n aria-label=\"Bulk actions\"\n >\n <span className=\"text-sm font-medium\">\n {t('table.bulk.selected', `${selectedCount} selected`, { count: selectedCount })}\n </span>\n <div className=\"ml-auto flex flex-wrap items-center gap-2\">\n {bulkActions}\n {onClearSelection && (\n <button\n type=\"button\"\n className=\"text-sm text-muted-foreground hover:underline\"\n onClick={onClearSelection}\n >\n {t('table.bulk.clear', 'Clear')}\n </button>\n )}\n </div>\n </section>\n )}\n </div>\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/widgets/charts/PieChart.tsx"],"names":["RechartsPieChart"],"mappings":";;;;AAeO,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,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,MAAM,SAAA,CAAU,MAAA,CAAO,CAAC,CAAA,IAAK,CAAA,MAAA,EAAS,IAAI,CAAC,CAAA,CAAA;AAAA,IAC3C;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,EAAK,IAAA;AAAA,QAEJ,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,wBACC,OAAA,EAAA,EAAQ,CAAA;AAAA,IACR,UAAA,mBAAa,GAAA,CAAC,MAAA,EAAA,EAAO,CAAA,GAAK;AAAA,GAAA,EAC7B,GACF,CAAA,EACF,CAAA;AAEJ","file":"chunk-C5H44NSP.js","sourcesContent":["import {\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 first = chartData.datasets[0];\n const slices = (first?.data ?? []).map((value, i) => ({\n name: chartData.labels[i] ?? `Slice ${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\n >\n {slices.map((slice, i) => (\n <Cell key={slice.name} fill={colorFor(first ?? { label: '', data: [] }, i)} />\n ))}\n </Pie>\n <Tooltip />\n {showLegend ? <Legend /> : null}\n </RechartsPieChart>\n </ResponsiveContainer>\n </div>\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/resource/ResourceIndex.tsx"],"names":[],"mappings":"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","file":"chunk-CVAMCRLL.js","sourcesContent":["/**\n * `<ResourceIndex>` — page-level wrapper for index/listing routes.\n *\n * Wires `ResourceIndexProps` (server payload) into the table stack:\n * header (title + toolbar actions + create button)\n * → TableToolbar (search + filters + bulk bar)\n * → DataTable (with selection, sorting, row actions)\n * → TablePagination\n *\n * The component is presentational — selection / sort / page transitions\n * are lifted to props so the same shell can be reused by ResourceIndex\n * (Inertia-driven) and dashboard widgets (memory-driven).\n */\n\nimport { useArqelTranslations } from '@arqel-dev/react/utils';\nimport type { RecordType, ResourceIndexProps as ServerProps } from '@arqel-dev/types/resources';\nimport type { SortDirection, TableSort } from '@arqel-dev/types/tables';\nimport type { ReactNode } from 'react';\nimport { DataTable } from '../table/DataTable.js';\nimport { TableFilters } from '../table/TableFilters.js';\nimport { TablePagination } from '../table/TablePagination.js';\nimport { TableToolbar } from '../table/TableToolbar.js';\nimport { cn } from '../utils/cn.js';\n\ntype RowId = string | number;\n\nexport interface ResourceIndexUIProps<TRecord extends RecordType = RecordType>\n extends ServerProps<TRecord> {\n selectedIds?: ReadonlyArray<RowId>;\n onSelectionChange?: (ids: RowId[]) => void;\n onSortChange?: (column: string, direction: SortDirection) => void;\n onPageChange?: (page: number) => void;\n onPerPageChange?: (perPage: number) => void;\n onSearchChange?: (search: string) => void;\n onFilterChange?: (name: string, value: unknown) => void;\n onClearFilters?: () => void;\n\n filterValues?: Record<string, unknown>;\n\n searchSlot?: ReactNode;\n toolbarActions?: ReactNode;\n rowActions?: (record: TRecord) => ReactNode;\n bulkActions?: ReactNode;\n emptyState?: ReactNode;\n\n loading?: boolean;\n className?: string;\n}\n\nexport function ResourceIndex<TRecord extends RecordType = RecordType>({\n resource,\n records,\n pagination,\n columns,\n filters,\n search,\n sort,\n selectedIds = [],\n filterValues = {},\n onSelectionChange,\n onSortChange,\n onPageChange,\n onPerPageChange,\n onSearchChange,\n onFilterChange,\n onClearFilters,\n searchSlot,\n toolbarActions,\n rowActions,\n bulkActions,\n emptyState,\n loading = false,\n className,\n}: ResourceIndexUIProps<TRecord>) {\n const t = useArqelTranslations();\n const enableSelection = Boolean(onSelectionChange);\n\n const renderSearch = (): ReactNode => {\n if (searchSlot) return searchSlot;\n if (!onSearchChange) return null;\n return (\n <label className=\"flex flex-col gap-1 text-xs text-muted-foreground\">\n {t('table.search.label', 'Search')}\n <input\n type=\"search\"\n placeholder={`Search ${resource.pluralLabel.toLowerCase()}…`}\n // 44px touch target on mobile (WCAG 2.5.5); dense 36px on >=md.\n className=\"h-11 w-64 rounded-sm border border-[var(--input)] bg-background px-3 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring md:h-9\"\n value={search ?? ''}\n onChange={(e) => onSearchChange(e.target.value)}\n />\n </label>\n );\n };\n\n const normalisedSort: TableSort | null = sort?.column\n ? {\n column: sort.column,\n direction: sort.direction === 'desc' ? 'desc' : 'asc',\n }\n : null;\n\n return (\n <section\n className={cn(\n 'flex min-w-0 flex-col rounded-md border border-border bg-background',\n className,\n )}\n aria-label={resource.pluralLabel}\n >\n <header className=\"flex flex-wrap items-center gap-3 border-b border-border px-4 py-3\">\n <h1 className=\"text-lg font-semibold\">{resource.pluralLabel}</h1>\n <div className=\"ml-auto flex flex-wrap items-center gap-2\">{toolbarActions}</div>\n </header>\n\n <TableToolbar\n search={renderSearch()}\n filters={\n filters.length > 0 ? (\n <TableFilters\n filters={filters}\n values={filterValues}\n onChange={(name, value) => onFilterChange?.(name, value)}\n onClearAll={onClearFilters}\n />\n ) : null\n }\n selectedCount={selectedIds.length}\n bulkActions={bulkActions}\n onClearSelection={onSelectionChange ? () => onSelectionChange([]) : undefined}\n />\n\n <DataTable\n columns={columns}\n records={records as unknown as Array<{ id: RowId } & TRecord>}\n enableSelection={enableSelection}\n selectedIds={selectedIds}\n onSelectionChange={onSelectionChange}\n sort={normalisedSort}\n onSortChange={onSortChange}\n rowActions={rowActions ? (record) => rowActions(record as TRecord) : undefined}\n loading={loading}\n emptyState={emptyState}\n />\n\n {pagination && (\n <TablePagination\n meta={pagination}\n onPageChange={(page) => onPageChange?.(page)}\n onPerPageChange={onPerPageChange}\n />\n )}\n </section>\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/flash/FlashToast.tsx","../src/flash/FlashContainer.tsx"],"names":["jsx"],"mappings":";;;;;AAqBA,IAAM,YAAA,GAA0C;AAAA,EAC9C,OAAA,EAAS,mEAAA;AAAA,EACT,KAAA,EAAO,yDAAA;AAAA,EACP,OAAA,EAAS,mEAAA;AAAA,EACT,IAAA,EAAM;AACR,CAAA;AAEA,IAAM,UAAA,GAAwC;AAAA,EAC5C,OAAA,EAAS,QAAA;AAAA,EACT,KAAA,EAAO,QAAA;AAAA,EACP,OAAA,EAAS,GAAA;AAAA,EACT,IAAA,EAAM;AACR,CAAA;AAEO,SAAS,UAAA,CAAW;AAAA,EACzB,IAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA,GAAa,GAAA;AAAA,EACb;AACF,CAAA,EAAoB;AAClB,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,UAAA,IAAc,GAAG,OAAO,MAAA;AAC5B,IAAA,MAAM,EAAA,GAAK,MAAA,CAAO,UAAA,CAAW,SAAA,EAAW,UAAU,CAAA;AAClD,IAAA,OAAO,MAAM,MAAA,CAAO,YAAA,CAAa,EAAE,CAAA;AAAA,EACrC,CAAA,EAAG,CAAC,UAAA,EAAY,SAAS,CAAC,CAAA;AAE1B,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAM,IAAA,KAAS,OAAA,GAAU,OAAA,GAAU,QAAA;AAAA,MACnC,WAAA,EAAW,IAAA,KAAS,OAAA,GAAU,WAAA,GAAc,QAAA;AAAA,MAC5C,SAAA,EAAW,EAAA;AAAA,QACT,kFAAA;AAAA,QACA,gCAAA;AAAA,QACA,aAAa,IAAI,CAAA;AAAA,QACjB;AAAA,OACF;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,UAAK,aAAA,EAAY,MAAA,EAAO,WAAU,qBAAA,EAChC,QAAA,EAAA,UAAA,CAAW,IAAI,CAAA,EAClB,CAAA;AAAA,wBACA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,QAAA,EAAU,QAAA,EAAA,OAAA,EAAQ,CAAA;AAAA,wBAClC,GAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,YAAA,EAAW,SAAA;AAAA,YACX,OAAA,EAAS,SAAA;AAAA,YACT,SAAA,EAAU,6CAAA;AAAA,YACX,QAAA,EAAA;AAAA;AAAA;AAED;AAAA;AAAA,GACF;AAEJ;AC5CA,IAAM,gBAAA,GAAkD;AAAA,EACtD,WAAA,EAAa,yBAAA;AAAA,EACb,UAAA,EAAY,0BAAA;AAAA,EACZ,cAAA,EAAgB,4BAAA;AAAA,EAChB,aAAA,EAAe;AACjB,CAAA;AAEA,IAAI,MAAA,GAAS,CAAA;AAEN,SAAS,cAAA,CAAe;AAAA,EAC7B,QAAA,GAAW,WAAA;AAAA,EACX,UAAA,GAAa,GAAA;AAAA,EACb;AACF,CAAA,EAAwB;AACtB,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,QAAA,CAAuB,EAAE,CAAA;AAErD,EAAA,MAAM,aAAA,GAAgB,WAAA,CAAY,CAAC,IAAA,EAAiB,OAAA,KAAoB;AACtE,IAAA,SAAA,CAAU,CAAC,IAAA,KAAS,CAAC,GAAG,IAAA,EAAM,EAAE,EAAA,EAAI,EAAE,MAAA,EAAQ,IAAA,EAAM,OAAA,EAAS,CAAC,CAAA;AAAA,EAChE,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,QAAA,CAAS,EAAE,SAAA,EAAW,aAAA,EAAe,CAAA;AAErC,EAAA,MAAM,OAAA,GAAU,CAAC,EAAA,KAAe,SAAA,CAAU,CAAC,IAAA,KAAS,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,EAAE,CAAC,CAAA;AAEnF,EAAA,uBACEA,GAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,kBAAA,EAAiB,EAAA;AAAA,MACjB,SAAA,EAAW,EAAA;AAAA,QACT,oDAAA;AAAA,QACA,iBAAiB,QAAQ,CAAA;AAAA,QACzB;AAAA,OACF;AAAA,MAEC,QAAA,EAAA,MAAA,CAAO,GAAA,CAAI,CAAC,KAAA,qBACXA,GAAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UAEC,MAAM,KAAA,CAAM,IAAA;AAAA,UACZ,SAAS,KAAA,CAAM,OAAA;AAAA,UACf,UAAA;AAAA,UACA,SAAA,EAAW,MAAM,OAAA,CAAQ,KAAA,CAAM,EAAE;AAAA,SAAA;AAAA,QAJ5B,KAAA,CAAM;AAAA,OAMd;AAAA;AAAA,GACH;AAEJ","file":"chunk-DSULVRB6.js","sourcesContent":["/**\n * `<FlashToast>` — single auto-dismissing toast.\n *\n * Self-rendered (no `sonner` dep) so apps with strict bundle budgets\n * stay lean. Replaceable via FlashContainer's `renderToast` prop when\n * a richer library is preferred.\n */\n\nimport { useEffect } from 'react';\nimport { cn } from '../utils/cn.js';\n\nexport type FlashKind = 'success' | 'error' | 'info' | 'warning';\n\nexport interface FlashToastProps {\n kind: FlashKind;\n message: string;\n onDismiss: () => void;\n durationMs?: number;\n className?: string;\n}\n\nconst KIND_CLASSES: Record<FlashKind, string> = {\n success: 'border-[var(--chart-2)]/60 bg-[var(--chart-2)]/15 text-foreground',\n error: 'border-destructive/60 bg-destructive/15 text-foreground',\n warning: 'border-[var(--chart-4)]/60 bg-[var(--chart-4)]/15 text-foreground',\n info: 'border-border bg-muted text-foreground',\n};\n\nconst KIND_GLYPH: Record<FlashKind, string> = {\n success: '✓',\n error: '✗',\n warning: '!',\n info: 'i',\n};\n\nexport function FlashToast({\n kind,\n message,\n onDismiss,\n durationMs = 5000,\n className,\n}: FlashToastProps) {\n useEffect(() => {\n if (durationMs <= 0) return undefined;\n const id = window.setTimeout(onDismiss, durationMs);\n return () => window.clearTimeout(id);\n }, [durationMs, onDismiss]);\n\n return (\n <div\n role={kind === 'error' ? 'alert' : 'status'}\n aria-live={kind === 'error' ? 'assertive' : 'polite'}\n className={cn(\n 'pointer-events-auto flex items-start gap-3 rounded-md border px-4 py-3 shadow-md',\n 'min-w-[18rem] max-w-md text-sm',\n KIND_CLASSES[kind],\n className,\n )}\n >\n <span aria-hidden=\"true\" className=\"font-bold leading-5\">\n {KIND_GLYPH[kind]}\n </span>\n <span className=\"flex-1\">{message}</span>\n <button\n type=\"button\"\n aria-label=\"Dismiss\"\n onClick={onDismiss}\n className=\"text-muted-foreground hover:text-foreground\"\n >\n ✕\n </button>\n </div>\n );\n}\n","/**\n * `<FlashContainer>` — bridges `useFlash()` to a stack of toasts.\n *\n * Subscribes to Inertia shared `flash` and pushes a toast each time a\n * new message of any kind arrives. Toast key is the (kind, message)\n * pair; identical repeats inside the same shared-props snapshot don't\n * duplicate. Defaults to fixed-positioning at top-right; pass `position`\n * to relocate.\n */\n\nimport { type FlashKind, useFlash } from '@arqel-dev/hooks';\nimport { useCallback, useState } from 'react';\nimport { cn } from '../utils/cn.js';\nimport { FlashToast } from './FlashToast.js';\n\ninterface ToastEntry {\n id: number;\n kind: FlashKind;\n message: string;\n}\n\nexport type FlashPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';\n\nexport interface FlashContainerProps {\n position?: FlashPosition;\n durationMs?: number;\n className?: string;\n}\n\nconst POSITION_CLASSES: Record<FlashPosition, string> = {\n 'top-right': 'top-4 right-4 items-end',\n 'top-left': 'top-4 left-4 items-start',\n 'bottom-right': 'bottom-4 right-4 items-end',\n 'bottom-left': 'bottom-4 left-4 items-start',\n};\n\nlet nextId = 0;\n\nexport function FlashContainer({\n position = 'top-right',\n durationMs = 5000,\n className,\n}: FlashContainerProps) {\n const [toasts, setToasts] = useState<ToastEntry[]>([]);\n\n const handleMessage = useCallback((kind: FlashKind, message: string) => {\n setToasts((prev) => [...prev, { id: ++nextId, kind, message }]);\n }, []);\n\n useFlash({ onMessage: handleMessage });\n\n const dismiss = (id: number) => setToasts((prev) => prev.filter((t) => t.id !== id));\n\n return (\n <div\n data-arqel-flash=\"\"\n className={cn(\n 'pointer-events-none fixed z-50 flex flex-col gap-2',\n POSITION_CLASSES[position],\n className,\n )}\n >\n {toasts.map((toast) => (\n <FlashToast\n key={toast.id}\n kind={toast.kind}\n message={toast.message}\n durationMs={durationMs}\n onDismiss={() => dismiss(toast.id)}\n />\n ))}\n </div>\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/shadcn/ui/dialog.tsx","../src/action/ActionFormModal.tsx","../src/action/ConfirmDialog.tsx","../src/action/ActionButton.tsx","../src/action/ActionMenu.tsx"],"names":["DialogPrimitive","jsx","jsxs","useState","Fragment"],"mappings":"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","file":"chunk-FP5R6WED.js","sourcesContent":["import * as React from \"react\"\nimport { XIcon } from \"lucide-react\"\nimport { Dialog as DialogPrimitive } from \"radix-ui\"\n\nimport { cn } from \"@/utils/cn\"\nimport { Button } from \"@/shadcn/ui/button\"\n\nfunction Dialog({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Root>) {\n return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />\n}\n\nfunction DialogTrigger({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {\n return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />\n}\n\nfunction DialogPortal({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Portal>) {\n return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />\n}\n\nfunction DialogClose({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Close>) {\n return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />\n}\n\nfunction DialogOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n return (\n <DialogPrimitive.Overlay\n data-slot=\"dialog-overlay\"\n className={cn(\n \"fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DialogContent({\n className,\n children,\n showCloseButton = true,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Content> & {\n showCloseButton?: boolean\n}) {\n return (\n <DialogPortal data-slot=\"dialog-portal\">\n <DialogOverlay />\n <DialogPrimitive.Content\n data-slot=\"dialog-content\"\n className={cn(\n \"fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadow-lg duration-200 outline-none data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 sm:max-w-lg\",\n className\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <DialogPrimitive.Close\n data-slot=\"dialog-close\"\n className=\"absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\"\n >\n <XIcon />\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n )}\n </DialogPrimitive.Content>\n </DialogPortal>\n )\n}\n\nfunction DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-header\"\n className={cn(\"flex flex-col gap-2 text-center sm:text-left\", className)}\n {...props}\n />\n )\n}\n\nfunction DialogFooter({\n className,\n showCloseButton = false,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n showCloseButton?: boolean\n}) {\n return (\n <div\n data-slot=\"dialog-footer\"\n className={cn(\n \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n className\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <DialogPrimitive.Close asChild>\n <Button variant=\"outline\">Close</Button>\n </DialogPrimitive.Close>\n )}\n </div>\n )\n}\n\nfunction DialogTitle({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Title>) {\n return (\n <DialogPrimitive.Title\n data-slot=\"dialog-title\"\n className={cn(\"text-lg leading-none font-semibold\", className)}\n {...props}\n />\n )\n}\n\nfunction DialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Description>) {\n return (\n <DialogPrimitive.Description\n data-slot=\"dialog-description\"\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n}\n","/**\n * `<ActionFormModal>` — modal hosting a `<FormRenderer>` for an Action's\n * companion form (see `arqel-dev/actions` `HasForm`).\n *\n * Action form fields are a flat list — Action FormSchema is built\n * inline from the `ActionFormField[]` since layout components don't\n * apply at this scale. Submit fires `onSubmit(values)`; the parent\n * (typically `useAction`) handles invocation + loading.\n */\n\nimport type { ActionSchema, ModalSize } from '@arqel-dev/types/actions';\nimport type { FieldSchema } from '@arqel-dev/types/fields';\nimport type { FormSchema } from '@arqel-dev/types/forms';\nimport { useMemo, useState } from 'react';\nimport { FormActions } from '../form/FormActions.js';\nimport { FormRenderer } from '../form/FormRenderer.js';\nimport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogHeader,\n DialogTitle,\n} from '../shadcn/ui/dialog.js';\nimport { cn } from '../utils/cn.js';\nimport { Button } from './Button.js';\n\nexport interface ActionFormModalProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n action: ActionSchema;\n fields: FieldSchema[];\n onSubmit: (values: Record<string, unknown>) => void;\n processing?: boolean;\n errors?: Record<string, string[]> | undefined;\n initialValues?: Record<string, unknown>;\n}\n\nconst SIZE_CLASSES: Record<ModalSize, string> = {\n sm: 'sm:max-w-[24rem]',\n md: 'sm:max-w-[32rem]',\n lg: 'sm:max-w-[44rem]',\n xl: 'sm:max-w-[56rem]',\n full: 'sm:max-w-[90vw] h-[90vh]',\n};\n\nexport function ActionFormModal({\n open,\n onOpenChange,\n action,\n fields,\n onSubmit,\n processing = false,\n errors = {},\n initialValues = {},\n}: ActionFormModalProps) {\n const [values, setValues] = useState<Record<string, unknown>>(initialValues);\n const size = action.modalSize ?? 'md';\n\n const schema: FormSchema = useMemo(\n () => ({\n schema: (action.form ?? []).map((entry) => ({\n kind: 'field' as const,\n name: entry.name,\n type: entry.type,\n })),\n columns: 1,\n model: null,\n inline: false,\n disabled: false,\n }),\n [action.form],\n );\n\n return (\n <Dialog open={open} onOpenChange={(next) => onOpenChange(next)}>\n <DialogContent className={cn('overflow-auto', SIZE_CLASSES[size])}>\n <DialogHeader>\n <DialogTitle>{action.label}</DialogTitle>\n </DialogHeader>\n <form\n className=\"flex flex-col gap-4\"\n onSubmit={(e) => {\n e.preventDefault();\n onSubmit(values);\n }}\n >\n <FormRenderer\n schema={schema}\n fields={fields}\n values={values}\n errors={errors}\n onChange={(name, value) => setValues((prev) => ({ ...prev, [name]: value }))}\n disabled={processing}\n />\n <FormActions\n processing={processing}\n submitLabel={action.label}\n extra={\n <DialogClose asChild>\n <Button type=\"button\" variant=\"ghost\" disabled={processing}>\n Cancel\n </Button>\n </DialogClose>\n }\n />\n </form>\n </DialogContent>\n </Dialog>\n );\n}\n","/**\n * `<ConfirmDialog>` — confirmation modal driven by the shadcn (Radix) Dialog.\n *\n * Phase 1 supports the canonical `ConfirmationConfig`:\n * - heading / description\n * - color (destructive | warning | info) — drives submit button variant\n * - submit / cancel labels\n * - \"type to confirm\" via `requiresText` (submit stays disabled until\n * the typed value matches exactly)\n *\n * Keyboard: Escape cancels (Radix built-in dismiss); Enter inside the\n * type-to-confirm input fires confirm when the value matches.\n */\n\nimport { useArqelTranslations } from '@arqel-dev/react/utils';\nimport type { ConfirmationConfig } from '@arqel-dev/types/actions';\nimport { useEffect, useState } from 'react';\nimport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '../shadcn/ui/dialog.js';\nimport { Button, type ButtonProps } from './Button.js';\n\nexport interface ConfirmDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n config?: ConfirmationConfig | undefined;\n onConfirm: () => void;\n processing?: boolean;\n}\n\nconst COLOR_VARIANT: Record<NonNullable<ConfirmationConfig['color']>, ButtonProps['variant']> = {\n destructive: 'destructive',\n warning: 'default',\n info: 'default',\n};\n\nexport function ConfirmDialog({\n open,\n onOpenChange,\n config,\n onConfirm,\n processing = false,\n}: ConfirmDialogProps) {\n const t = useArqelTranslations();\n const [typed, setTyped] = useState('');\n\n useEffect(() => {\n if (!open) setTyped('');\n }, [open]);\n\n const requiresText = config?.requiresText;\n const submitDisabled = processing || (requiresText !== undefined && typed !== requiresText);\n const variant = COLOR_VARIANT[config?.color ?? 'destructive'];\n // Precedence: explicit config > shared translation > English fallback.\n const submitLabel =\n config?.submitLabel ??\n (config?.color === 'info'\n ? t('arqel.actions.confirm', 'Confirm')\n : t('arqel.actions.delete', 'Delete'));\n const cancelLabel = config?.cancelLabel ?? t('arqel.actions.cancel', 'Cancel');\n\n return (\n <Dialog open={open} onOpenChange={(next) => onOpenChange(next)}>\n <DialogContent className=\"sm:max-w-[28rem]\" showCloseButton={false}>\n <DialogHeader>\n <DialogTitle>\n {config?.heading ?? t('arqel.messages.delete_confirm', 'Are you sure?')}\n </DialogTitle>\n {config?.description && <DialogDescription>{config.description}</DialogDescription>}\n </DialogHeader>\n {requiresText !== undefined && (\n <label className=\"flex flex-col gap-1 text-xs text-muted-foreground\">\n <span>\n Type <code className=\"font-mono text-foreground\">{requiresText}</code> to confirm\n </span>\n <input\n type=\"text\"\n ref={(el) => el?.focus()}\n value={typed}\n onChange={(e) => setTyped(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !submitDisabled) {\n e.preventDefault();\n onConfirm();\n }\n }}\n className=\"h-9 rounded-md border border-input bg-background px-3 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n />\n </label>\n )}\n <DialogFooter>\n <DialogClose asChild>\n <Button type=\"button\" variant=\"ghost\" disabled={processing}>\n {cancelLabel}\n </Button>\n </DialogClose>\n <Button type=\"button\" variant={variant} disabled={submitDisabled} onClick={onConfirm}>\n {processing ? t('form.saving', 'Working…') : submitLabel}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n","/**\n * `<ActionButton>` — renders an `ActionSchema` as a button.\n *\n * Behaviour matrix:\n * - `requiresConfirmation` only → opens ConfirmDialog\n * - `form` only → opens ActionFormModal\n * - both → ConfirmDialog first, then form\n * - neither → fires `onInvoke` immediately\n *\n * `onInvoke` receives optional form data so parents (typically using\n * `useAction()` from @arqel-dev/hooks) can dispatch the underlying request.\n */\n\nimport type { ActionColor, ActionSchema, ActionVariant } from '@arqel-dev/types/actions';\nimport type { FieldSchema } from '@arqel-dev/types/fields';\nimport { useState } from 'react';\nimport { ActionFormModal } from './ActionFormModal.js';\nimport { Button, type ButtonProps } from './Button.js';\nimport { ConfirmDialog } from './ConfirmDialog.js';\n\nexport interface ActionButtonProps {\n action: ActionSchema;\n /**\n * Field schemas for the form modal (resolved server-side from\n * `Action::form` via `FieldSchemaSerializer`). Optional override — when\n * omitted the component reads `action.formFields`, the canonical payload\n * shipped by `Action::toArray()` (#213).\n */\n formFields?: FieldSchema[] | undefined;\n onInvoke: (formValues?: Record<string, unknown>) => void;\n processing?: boolean;\n errors?: Record<string, string[]>;\n size?: ButtonProps['size'];\n className?: string;\n}\n\nconst COLOR_TO_VARIANT: Record<ActionColor, ButtonProps['variant']> = {\n primary: 'default',\n secondary: 'outline',\n destructive: 'destructive',\n success: 'default',\n warning: 'default',\n info: 'default',\n};\n\nconst VARIANT_OVERRIDE: Partial<Record<ActionVariant, ButtonProps['variant']>> = {\n default: 'default',\n outline: 'outline',\n ghost: 'ghost',\n destructive: 'destructive',\n};\n\nexport function ActionButton({\n action,\n formFields,\n onInvoke,\n processing = false,\n errors,\n size = 'default',\n className,\n}: ActionButtonProps) {\n const [confirmOpen, setConfirmOpen] = useState(false);\n const [formOpen, setFormOpen] = useState(false);\n\n // Prefer an explicit prop; otherwise read the schema shipped by\n // `Action::toArray()` so the modal renders real inputs (#213).\n const resolvedFormFields = formFields ?? action.formFields ?? [];\n\n const variant: ButtonProps['variant'] =\n VARIANT_OVERRIDE[action.variant] ?? COLOR_TO_VARIANT[action.color];\n\n const handleClick = () => {\n if (action.disabled) return;\n if (action.requiresConfirmation) {\n setConfirmOpen(true);\n } else if (action.form && action.form.length > 0) {\n setFormOpen(true);\n } else {\n onInvoke();\n }\n };\n\n const handleConfirm = () => {\n setConfirmOpen(false);\n if (action.form && action.form.length > 0) {\n setFormOpen(true);\n } else {\n onInvoke();\n }\n };\n\n const handleFormSubmit = (values: Record<string, unknown>) => {\n onInvoke(values);\n setFormOpen(false);\n };\n\n return (\n <>\n <Button\n variant={variant}\n size={size}\n disabled={action.disabled === true || processing}\n title={action.tooltip}\n onClick={handleClick}\n className={className}\n >\n {action.label}\n </Button>\n {action.requiresConfirmation && (\n <ConfirmDialog\n open={confirmOpen}\n onOpenChange={setConfirmOpen}\n config={action.confirmation}\n onConfirm={handleConfirm}\n processing={processing}\n />\n )}\n {action.form && action.form.length > 0 && (\n <ActionFormModal\n open={formOpen}\n onOpenChange={setFormOpen}\n action={action}\n fields={resolvedFormFields}\n onSubmit={handleFormSubmit}\n processing={processing}\n errors={errors}\n />\n )}\n </>\n );\n}\n","/**\n * `<ActionMenu>` — renders a list of actions inline (≤ `inlineThreshold`)\n * or collapses them into a shadcn (Radix) dropdown menu when the list grows.\n *\n * Each menu item delegates to `<ActionButton>` so confirmation /\n * form-modal behaviour is consistent across surfaces. The dropdown\n * trigger is rendered as a ghost icon button by default; callers can\n * supply a custom `trigger` slot.\n */\n\nimport type { ActionSchema } from '@arqel-dev/types/actions';\nimport type { FieldSchema } from '@arqel-dev/types/fields';\nimport { type ReactNode, useState } from 'react';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '../shadcn/ui/dropdown-menu.js';\nimport { Sheet, SheetContent, SheetHeader, SheetTitle } from '../shadcn/ui/sheet.js';\nimport { cn } from '../utils/cn.js';\nimport { ActionButton } from './ActionButton.js';\nimport { ActionFormModal } from './ActionFormModal.js';\nimport { Button } from './Button.js';\nimport { ConfirmDialog } from './ConfirmDialog.js';\n\n/** Does this action need a gate (confirm/form) before invoking? */\nfunction actionHasForm(action: ActionSchema): boolean {\n return Array.isArray(action.form) && action.form.length > 0;\n}\n\nexport interface ActionMenuProps {\n actions: ActionSchema[];\n /**\n * Optional per-action override map keyed by action name. When an action\n * is absent here, `<ActionButton>` falls back to the action's own\n * `formFields` payload shipped by `Action::toArray()` (#213).\n */\n formFieldsByAction?: Record<string, FieldSchema[]>;\n onInvoke: (action: ActionSchema, formValues?: Record<string, unknown>) => void;\n inlineThreshold?: number;\n processing?: boolean;\n trigger?: ReactNode;\n className?: string;\n}\n\nexport function ActionMenu({\n actions,\n formFieldsByAction = {},\n onInvoke,\n inlineThreshold = 3,\n processing = false,\n trigger,\n className,\n}: ActionMenuProps) {\n // Which dropdown action (if any) is currently driving a confirm dialog /\n // form modal. The modals are mounted as siblings of the menu so they\n // survive the menu closing on `onSelect`.\n const [confirmAction, setConfirmAction] = useState<ActionSchema | null>(null);\n const [formAction, setFormAction] = useState<ActionSchema | null>(null);\n // The mobile bottom-sheet is controlled so selecting an item can close it\n // (mirroring the Dropdown's onSelect auto-close).\n const [sheetOpen, setSheetOpen] = useState(false);\n\n if (actions.length === 0) return null;\n\n if (actions.length <= inlineThreshold) {\n return (\n <div className={cn('flex flex-wrap items-center gap-1', className)}>\n {actions.map((action) => (\n <ActionButton\n key={action.name}\n action={action}\n formFields={formFieldsByAction[action.name]}\n onInvoke={(values) => onInvoke(action, values)}\n processing={processing}\n size=\"sm\"\n // 44px touch target on mobile (WCAG 2.5.5); dense 32px on >=md.\n className=\"h-11 md:h-8\"\n />\n ))}\n </div>\n );\n }\n\n const handleSelect = (action: ActionSchema) => {\n if (action.disabled) return;\n // Mirror ActionButton's gating: confirmation first, then form, else\n // invoke directly. The modals open as siblings of the (now closing)\n // menu so destructive/form actions never fire without a gate (#229,\n // #231).\n if (action.requiresConfirmation) {\n setConfirmAction(action);\n } else if (actionHasForm(action)) {\n setFormAction(action);\n } else {\n onInvoke(action);\n }\n };\n\n const handleConfirm = () => {\n const action = confirmAction;\n setConfirmAction(null);\n if (!action) return;\n if (actionHasForm(action)) {\n setFormAction(action);\n } else {\n onInvoke(action);\n }\n };\n\n // One visual trigger shared by both presentation surfaces. The Dropdown\n // wraps it via DropdownMenuTrigger (asChild); the Sheet opens it on click.\n const triggerNode = trigger ?? (\n <Button variant=\"ghost\" size=\"icon-touch\" aria-label=\"Actions\">\n ⋯\n </Button>\n );\n\n return (\n <>\n {/* Desktop (>=md): the Radix dropdown popper, unchanged. */}\n <div data-arqel-action-dropdown=\"\" className=\"hidden md:contents\">\n <DropdownMenu>\n <DropdownMenuTrigger asChild>{triggerNode}</DropdownMenuTrigger>\n <DropdownMenuContent\n align=\"end\"\n sideOffset={6}\n className={cn('min-w-[12rem]', className)}\n >\n {actions.map((action) => (\n <DropdownMenuItem\n key={action.name}\n disabled={action.disabled === true}\n variant={action.color === 'destructive' ? 'destructive' : 'default'}\n onSelect={() => handleSelect(action)}\n >\n {action.label}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n\n {/* Mobile (<md): a full-width bottom sheet with >=44px items. */}\n <div className=\"md:hidden\">\n <Sheet open={sheetOpen} onOpenChange={setSheetOpen}>\n <button\n type=\"button\"\n aria-label=\"Actions\"\n className=\"inline-flex size-11 items-center justify-center rounded-md text-lg hover:bg-accent\"\n onClick={() => setSheetOpen(true)}\n >\n ⋯\n </button>\n <SheetContent\n side=\"bottom\"\n className=\"max-h-[80vh] gap-0 overflow-y-auto pb-[env(safe-area-inset-bottom)]\"\n >\n <SheetHeader className=\"px-4 pt-4 pb-2\">\n <SheetTitle>Actions</SheetTitle>\n </SheetHeader>\n <div className=\"flex flex-col px-2 pb-2\">\n {actions.map((action) => (\n <button\n key={action.name}\n type=\"button\"\n data-arqel-sheet-action=\"\"\n disabled={action.disabled === true}\n className={cn(\n 'flex min-h-11 w-full items-center rounded-md px-3 text-left text-sm hover:bg-accent disabled:pointer-events-none disabled:opacity-50',\n action.color === 'destructive' && 'text-destructive',\n )}\n onClick={() => {\n setSheetOpen(false);\n handleSelect(action);\n }}\n >\n {action.label}\n </button>\n ))}\n </div>\n </SheetContent>\n </Sheet>\n </div>\n\n {confirmAction && (\n <ConfirmDialog\n open\n onOpenChange={(next) => {\n if (!next) setConfirmAction(null);\n }}\n config={confirmAction.confirmation}\n onConfirm={handleConfirm}\n processing={processing}\n />\n )}\n {formAction && (\n <ActionFormModal\n open\n onOpenChange={(next) => {\n if (!next) setFormAction(null);\n }}\n action={formAction}\n fields={formFieldsByAction[formAction.name] ?? formAction.formFields ?? []}\n onSubmit={(values) => {\n const action = formAction;\n setFormAction(null);\n onInvoke(action, values);\n }}\n processing={processing}\n />\n )}\n </>\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/palette/CommandPalette.tsx"],"names":[],"mappings":"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","file":"chunk-FV7RESKL.js","sourcesContent":["/**\n * `<CommandPalette>` — global Cmd+K admin command palette.\n *\n * Wraps the `/admin/commands` endpoint shipped by `arqel-dev/core` (CMDPAL-002)\n * with a native `<dialog>`-based modal. No external dialog/combobox library\n * is used: the surface area is small enough that the platform primitives\n * (HTML dialog + ARIA combobox/listbox roles) cover every requirement.\n *\n * Usage: render once at the top of `<AppShell>` — the global Cmd+K /\n * Ctrl+K listener is mounted on `window` while the component is alive.\n */\n\nimport { type CSSProperties, useCallback, useEffect, useId, useRef, useState } from 'react';\n\nexport interface PaletteCommand {\n id: string;\n label: string;\n url: string;\n description?: string | null;\n category?: string | null;\n icon?: string | null;\n}\n\nexport interface CommandPaletteProps {\n /** Endpoint that returns `{ commands: PaletteCommand[] }`. */\n endpoint?: string;\n}\n\ninterface RecentEntry {\n id: string;\n count: number;\n lastUsed: number;\n command: PaletteCommand;\n}\n\nconst RECENT_KEY = 'arqel:cmdpal:recent';\nconst RECENT_WINDOW_MS = 30 * 24 * 60 * 60 * 1000; // 30 days\nconst RECENT_LIMIT = 5;\nconst DEBOUNCE_MS = 150;\n\nfunction readRecents(): RecentEntry[] {\n try {\n const raw = globalThis.localStorage?.getItem(RECENT_KEY);\n if (!raw) return [];\n const parsed: unknown = JSON.parse(raw);\n if (!Array.isArray(parsed)) return [];\n const now = Date.now();\n return parsed.filter(\n (e): e is RecentEntry =>\n typeof e === 'object' &&\n e !== null &&\n typeof (e as RecentEntry).id === 'string' &&\n typeof (e as RecentEntry).count === 'number' &&\n typeof (e as RecentEntry).lastUsed === 'number' &&\n now - (e as RecentEntry).lastUsed <= RECENT_WINDOW_MS &&\n typeof (e as RecentEntry).command === 'object',\n );\n } catch {\n return [];\n }\n}\n\nfunction writeRecents(entries: RecentEntry[]): void {\n try {\n globalThis.localStorage?.setItem(RECENT_KEY, JSON.stringify(entries));\n } catch {\n // Ignore quota/serialization failures — recents are best-effort.\n }\n}\n\nfunction recordUsage(command: PaletteCommand): void {\n const entries = readRecents();\n const now = Date.now();\n const idx = entries.findIndex((e) => e.id === command.id);\n if (idx >= 0) {\n const existing = entries[idx];\n if (existing) {\n entries[idx] = {\n ...existing,\n count: existing.count + 1,\n lastUsed: now,\n command,\n };\n }\n } else {\n entries.push({ id: command.id, count: 1, lastUsed: now, command });\n }\n // Prune anything older than the recency window.\n const fresh = entries.filter((e) => now - e.lastUsed <= RECENT_WINDOW_MS);\n writeRecents(fresh);\n}\n\nfunction topRecents(): PaletteCommand[] {\n return readRecents()\n .slice()\n .sort((a, b) => (b.count === a.count ? b.lastUsed - a.lastUsed : b.count - a.count))\n .slice(0, RECENT_LIMIT)\n .map((e) => e.command);\n}\n\ninterface Group {\n category: string;\n commands: PaletteCommand[];\n}\n\nfunction groupByCategory(commands: PaletteCommand[]): Group[] {\n const order: string[] = [];\n const buckets = new Map<string, PaletteCommand[]>();\n for (const cmd of commands) {\n const key = cmd.category ?? 'General';\n if (!buckets.has(key)) {\n buckets.set(key, []);\n order.push(key);\n }\n buckets.get(key)?.push(cmd);\n }\n return order.map((category) => ({ category, commands: buckets.get(category) ?? [] }));\n}\n\nfunction flattenGroups(groups: Group[]): PaletteCommand[] {\n return groups.flatMap((g) => g.commands);\n}\n\nconst dialogStyle: CSSProperties = {\n border: 'none',\n borderRadius: '0.75rem',\n padding: 0,\n width: 'min(640px, 92vw)',\n maxHeight: '70vh',\n background: 'var(--background, #fff)',\n color: 'var(--foreground, #111)',\n};\n\nexport function CommandPalette({ endpoint = '/admin/commands' }: CommandPaletteProps) {\n const dialogRef = useRef<HTMLDialogElement | null>(null);\n const inputRef = useRef<HTMLInputElement | null>(null);\n const debounceTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n const [results, setResults] = useState<PaletteCommand[]>([]);\n const [recents, setRecents] = useState<PaletteCommand[]>([]);\n const [highlight, setHighlight] = useState(0);\n\n const titleId = useId();\n const hintId = useId();\n const listId = useId();\n const optBaseId = useId();\n\n const visibleCommands = query.trim().length === 0 ? recents : results;\n const groups =\n query.trim().length === 0 && recents.length > 0\n ? [{ category: 'Recent', commands: recents }]\n : groupByCategory(visibleCommands);\n const flat = flattenGroups(groups);\n\n // Cmd+K / Ctrl+K global toggle.\n useEffect(() => {\n function onKey(event: KeyboardEvent) {\n const isToggle = (event.key === 'k' || event.key === 'K') && (event.metaKey || event.ctrlKey);\n if (!isToggle) return;\n event.preventDefault();\n setOpen((prev) => !prev);\n }\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, []);\n\n // Sync `open` state with the native <dialog>.\n useEffect(() => {\n const dialog = dialogRef.current;\n if (!dialog) return;\n if (open && !dialog.open) {\n try {\n dialog.showModal();\n } catch {\n // jsdom or already-open: ignore.\n }\n setRecents(topRecents());\n setQuery('');\n setResults([]);\n setHighlight(0);\n // Defer focus after the dialog is on-screen.\n queueMicrotask(() => inputRef.current?.focus());\n } else if (!open && dialog.open) {\n dialog.close();\n }\n }, [open]);\n\n // Debounced fetch.\n useEffect(() => {\n if (!open) return;\n if (query.trim().length === 0) {\n setResults([]);\n return;\n }\n if (debounceTimer.current) clearTimeout(debounceTimer.current);\n debounceTimer.current = setTimeout(() => {\n const url = `${endpoint}?q=${encodeURIComponent(query)}`;\n fetch(url, { headers: { Accept: 'application/json' } })\n .then((res) => (res.ok ? res.json() : { commands: [] }))\n .then((data: { commands?: PaletteCommand[] }) => {\n setResults(Array.isArray(data?.commands) ? data.commands : []);\n setHighlight(0);\n })\n .catch(() => {\n setResults([]);\n });\n }, DEBOUNCE_MS);\n return () => {\n if (debounceTimer.current) clearTimeout(debounceTimer.current);\n };\n }, [query, open, endpoint]);\n\n const close = useCallback(() => setOpen(false), []);\n\n const execute = useCallback((command: PaletteCommand) => {\n recordUsage(command);\n setOpen(false);\n window.location.assign(command.url);\n }, []);\n\n const onKeyDown = useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key === 'Escape') {\n event.preventDefault();\n close();\n return;\n }\n if (flat.length === 0) return;\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n setHighlight((h) => (h + 1) % flat.length);\n } else if (event.key === 'ArrowUp') {\n event.preventDefault();\n setHighlight((h) => (h - 1 + flat.length) % flat.length);\n } else if (event.key === 'Enter') {\n event.preventDefault();\n const target = flat[highlight];\n if (target) execute(target);\n }\n },\n [flat, highlight, close, execute],\n );\n\n // Close on backdrop click — dialog click hits the dialog itself, not children.\n const onDialogClick = useCallback(\n (event: React.MouseEvent<HTMLDialogElement>) => {\n if (event.target === dialogRef.current) close();\n },\n [close],\n );\n\n const optionId = (idx: number) => `${optBaseId}-opt-${idx}`;\n const activeOptionId = flat.length > 0 ? optionId(highlight) : undefined;\n\n return (\n // biome-ignore lint/a11y/useKeyWithClickEvents: dialog backdrop click closes; Escape (onCancel) handles keyboard close\n <dialog\n ref={dialogRef}\n aria-labelledby={titleId}\n aria-describedby={hintId}\n onClick={onDialogClick}\n onClose={() => setOpen(false)}\n onCancel={(event) => {\n event.preventDefault();\n close();\n }}\n style={dialogStyle}\n className=\"backdrop:bg-black/40\"\n data-arqel-cmdpal=\"\"\n >\n {/* biome-ignore lint/a11y/noStaticElementInteractions: this wrapper only delegates ArrowUp/Down/Enter/Escape from the combobox input below */}\n <div onKeyDown={onKeyDown} className=\"flex flex-col\">\n <h2 id={titleId} className=\"sr-only\">\n Command palette\n </h2>\n <input\n ref={inputRef}\n type=\"text\"\n role=\"combobox\"\n aria-expanded={open}\n aria-controls={listId}\n aria-autocomplete=\"list\"\n {...(activeOptionId ? { 'aria-activedescendant': activeOptionId } : {})}\n placeholder=\"Type a command…\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n className=\"w-full border-b border-[var(--border,#e5e7eb)] bg-transparent px-4 py-3 text-base outline-none\"\n />\n <div role=\"status\" aria-live=\"polite\" className=\"sr-only\">\n {flat.length} commands\n </div>\n <ul\n id={listId}\n // biome-ignore lint/a11y/noNoninteractiveElementToInteractiveRole: WAI-ARIA combobox/listbox pattern requires <ul role=\"listbox\">\n role=\"listbox\"\n aria-label=\"Commands\"\n className=\"max-h-[50vh] overflow-y-auto py-2\"\n >\n {groups.length === 0 && (\n <li role=\"presentation\" className=\"px-4 py-3 text-sm opacity-60\">\n No commands found\n </li>\n )}\n {groups.map((group) => {\n const startIdx = flat.indexOf(group.commands[0] ?? ({} as PaletteCommand));\n return (\n <li key={group.category} role=\"presentation\">\n <div\n role=\"presentation\"\n className=\"px-4 pt-2 pb-1 text-xs font-semibold uppercase tracking-wide opacity-60\"\n >\n {group.category}\n </div>\n <ul role=\"presentation\" className=\"m-0 list-none p-0\">\n {group.commands.map((cmd, j) => {\n const idx = startIdx + j;\n const isActive = idx === highlight;\n return (\n // biome-ignore lint/a11y/useFocusableInteractive: focus stays on combobox; selection via aria-activedescendant\n // biome-ignore lint/a11y/useKeyWithClickEvents: keyboard nav handled by combobox input ArrowUp/Down/Enter handler\n <li\n key={cmd.id}\n id={optionId(idx)}\n // biome-ignore lint/a11y/noNoninteractiveElementToInteractiveRole: WAI-ARIA combobox/listbox pattern requires <li role=\"option\">\n role=\"option\"\n aria-selected={isActive}\n data-active={isActive ? '' : undefined}\n onMouseEnter={() => setHighlight(idx)}\n onClick={() => execute(cmd)}\n className={\n 'flex cursor-pointer items-center gap-3 px-4 py-2 text-sm ' +\n (isActive ? 'bg-[var(--accent,#f1f5f9)]' : '')\n }\n >\n <span className=\"flex-1\">{cmd.label}</span>\n {cmd.description ? (\n <span className=\"text-xs opacity-60\">{cmd.description}</span>\n ) : null}\n </li>\n );\n })}\n </ul>\n </li>\n );\n })}\n </ul>\n <footer\n id={hintId}\n className=\"flex items-center gap-3 border-t border-[var(--border,#e5e7eb)] px-4 py-2 text-xs opacity-70\"\n >\n <span>↑↓ navigate</span>\n <span>↵ select</span>\n <span>esc close</span>\n </footer>\n </div>\n </dialog>\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
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","jsxs","useState"],"mappings":"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","file":"chunk-HSDZM4AM.js","sourcesContent":["import { 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 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=\"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 { 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 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=\"\">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 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>{filter.label ?? filter.name}</legend>\n <div className=\"flex items-center gap-1\">\n <input\n type=\"date\"\n aria-label={`${filter.label ?? filter.name} from`}\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={`${filter.label ?? filter.name} to`}\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 { 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 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])}\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 See all →\n </a>\n </div>\n )}\n </>\n )}\n </WidgetWrapper>\n );\n}\n\nfunction formatCell(value: unknown): string {\n if (value === null || value === undefined) return '';\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\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 { 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 [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 Widget type {widget.type} not registered\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"]}
|