@alepha/ui 0.18.2 → 0.18.3
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/dist/admin/{AdminApiKeys-BJhIwfD6.js → AdminApiKeys-Dy_k-4Vd.js} +2 -2
- package/dist/admin/{AdminApiKeys-BJhIwfD6.js.map → AdminApiKeys-Dy_k-4Vd.js.map} +1 -1
- package/dist/admin/{AdminAudits-DzD_4cDt.js → AdminAudits-CKiFMSSU.js} +2 -2
- package/dist/admin/{AdminAudits-DzD_4cDt.js.map → AdminAudits-CKiFMSSU.js.map} +1 -1
- package/dist/admin/{AdminDashboard-C92tIc6x.js → AdminDashboard-PhC_dZqo.js} +2 -2
- package/dist/admin/{AdminDashboard-C92tIc6x.js.map → AdminDashboard-PhC_dZqo.js.map} +1 -1
- package/dist/admin/{AdminFiles-DLpfhBkf.js → AdminFiles-DFTjijGp.js} +2 -2
- package/dist/admin/{AdminFiles-DLpfhBkf.js.map → AdminFiles-DFTjijGp.js.map} +1 -1
- package/dist/admin/{AdminJobDashboard-KIOkeMgE.js → AdminJobDashboard-BL8gGPDp.js} +2 -2
- package/dist/admin/{AdminJobDashboard-KIOkeMgE.js.map → AdminJobDashboard-BL8gGPDp.js.map} +1 -1
- package/dist/admin/{AdminJobExecutions-D0Yo_PU0.js → AdminJobExecutions-D9E-CS-U.js} +2 -2
- package/dist/admin/{AdminJobExecutions-D0Yo_PU0.js.map → AdminJobExecutions-D9E-CS-U.js.map} +1 -1
- package/dist/admin/{AdminJobRegistry-PFajqaGK.js → AdminJobRegistry-Ci9ue1zC.js} +2 -2
- package/dist/admin/{AdminJobRegistry-PFajqaGK.js.map → AdminJobRegistry-Ci9ue1zC.js.map} +1 -1
- package/dist/admin/{AdminLayout-B1DXZHDn.js → AdminLayout-I6TlUMPc.js} +2 -2
- package/dist/admin/{AdminLayout-B1DXZHDn.js.map → AdminLayout-I6TlUMPc.js.map} +1 -1
- package/dist/admin/AdminNotifications-ZPHCYrv7.js +542 -0
- package/dist/admin/AdminNotifications-ZPHCYrv7.js.map +1 -0
- package/dist/admin/{AdminParameters-BspPeqp_.js → AdminParameters-CqgvhRsb.js} +120 -105
- package/dist/admin/AdminParameters-CqgvhRsb.js.map +1 -0
- package/dist/admin/{AdminSessions-BnH5CZQl.js → AdminSessions-Bz5NRuoW.js} +2 -2
- package/dist/admin/{AdminSessions-BnH5CZQl.js.map → AdminSessions-Bz5NRuoW.js.map} +1 -1
- package/dist/admin/{AdminUserLayout-DUbC6-BI.js → AdminUserLayout-lXT6I0Qq.js} +14 -8
- package/dist/admin/AdminUserLayout-lXT6I0Qq.js.map +1 -0
- package/dist/admin/{AdminUserProfile-DuTUnjdG.js → AdminUserProfile-vFBLoJ3h.js} +3 -3
- package/dist/admin/{AdminUserProfile-DuTUnjdG.js.map → AdminUserProfile-vFBLoJ3h.js.map} +1 -1
- package/dist/admin/{AdminUserSessions-DvZdAGpL.js → AdminUserSessions-CT_YDim0.js} +2 -2
- package/dist/admin/{AdminUserSessions-DvZdAGpL.js.map → AdminUserSessions-CT_YDim0.js.map} +1 -1
- package/dist/admin/{AdminUsers-CR9z0g_5.js → AdminUsers-D1UfGya9.js} +2 -2
- package/dist/admin/{AdminUsers-CR9z0g_5.js.map → AdminUsers-D1UfGya9.js.map} +1 -1
- package/dist/admin/{AuthLayout-DsUfp9RG.js → AuthLayout-_frhdgOO.js} +2 -2
- package/dist/admin/{AuthLayout-DsUfp9RG.js.map → AuthLayout-_frhdgOO.js.map} +1 -1
- package/dist/admin/Login-xtNmQtGh.js +275 -0
- package/dist/admin/Login-xtNmQtGh.js.map +1 -0
- package/dist/admin/{Profile-B2EcIDB9.js → Profile-_AtPUwAP.js} +31 -27
- package/dist/admin/Profile-_AtPUwAP.js.map +1 -0
- package/dist/admin/{Register-Z3fxRbUF.js → Register-JcCjHUUn.js} +198 -142
- package/dist/admin/Register-JcCjHUUn.js.map +1 -0
- package/dist/admin/{ResetPassword-_Y1qTTKh.js → ResetPassword-CwGBPLJO.js} +7 -7
- package/dist/admin/ResetPassword-CwGBPLJO.js.map +1 -0
- package/dist/admin/{VerifyEmail-Bg22bwcC.js → VerifyEmail-hNxWejWf.js} +23 -8
- package/dist/admin/VerifyEmail-hNxWejWf.js.map +1 -0
- package/dist/admin/{core-BVO_TQxb.js → core-CYaRQ8O-.js} +709 -556
- package/dist/admin/core-CYaRQ8O-.js.map +1 -0
- package/dist/admin/index.d.ts +83 -44
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +58 -39
- package/dist/admin/index.js.map +1 -1
- package/dist/auth/{AuthLayout-C161NeF6.js → AuthLayout-AvLlcLjS.js} +2 -2
- package/dist/auth/{AuthLayout-C161NeF6.js.map → AuthLayout-AvLlcLjS.js.map} +1 -1
- package/dist/auth/Login-BA1E8IZl.js +275 -0
- package/dist/auth/Login-BA1E8IZl.js.map +1 -0
- package/dist/auth/{Profile-BMpXJ0oi.js → Profile-YcWdeuFz.js} +31 -27
- package/dist/auth/Profile-YcWdeuFz.js.map +1 -0
- package/dist/auth/{Register-2gx8qll-.js → Register-CPhEO5MG.js} +198 -142
- package/dist/auth/Register-CPhEO5MG.js.map +1 -0
- package/dist/{demo/ResetPassword-CAPj8MO3.js → auth/ResetPassword-DCtGcneA.js} +7 -7
- package/dist/auth/ResetPassword-DCtGcneA.js.map +1 -0
- package/dist/{demo/VerifyEmail-DFmdCdYs.js → auth/VerifyEmail-DkH7NBfn.js} +23 -8
- package/dist/auth/VerifyEmail-DkH7NBfn.js.map +1 -0
- package/dist/auth/{core-DyfeVr5c.js → core-D5jIAVF2.js} +386 -294
- package/dist/auth/core-D5jIAVF2.js.map +1 -0
- package/dist/auth/index.d.ts +93 -48
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +28 -24
- package/dist/auth/index.js.map +1 -1
- package/dist/core/index.d.ts +116 -61
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +873 -701
- package/dist/core/index.js.map +1 -1
- package/dist/demo/{AuthLayout-DN-ClJQk.js → AuthLayout-Brri4A-L.js} +2 -2
- package/dist/demo/{AuthLayout-DN-ClJQk.js.map → AuthLayout-Brri4A-L.js.map} +1 -1
- package/dist/demo/DemoButton-wiCxZZ_L.js +182 -0
- package/dist/demo/DemoButton-wiCxZZ_L.js.map +1 -0
- package/dist/demo/DemoControlSelect-D7ILObVg.js +305 -0
- package/dist/demo/DemoControlSelect-D7ILObVg.js.map +1 -0
- package/dist/demo/DemoDataTable-DZ5Y8pFX.js +362 -0
- package/dist/demo/DemoDataTable-DZ5Y8pFX.js.map +1 -0
- package/dist/demo/{DemoDialog-DW8QEvD1.js → DemoDialog-CUWdLHim.js} +2 -2
- package/dist/demo/{DemoDialog-DW8QEvD1.js.map → DemoDialog-CUWdLHim.js.map} +1 -1
- package/dist/demo/{DemoFlex-CAhLUanT.js → DemoFlex-a8OhMMvq.js} +3 -3
- package/dist/demo/{DemoFlex-CAhLUanT.js.map → DemoFlex-a8OhMMvq.js.map} +1 -1
- package/dist/demo/{DemoHeading-yIFmNjHB.js → DemoHeading-C13OVDfS.js} +3 -3
- package/dist/demo/{DemoHeading-yIFmNjHB.js.map → DemoHeading-C13OVDfS.js.map} +1 -1
- package/dist/demo/{DemoHome-BSGuBHus.js → DemoHome-D_De3UiT.js} +2 -2
- package/dist/demo/{DemoHome-BSGuBHus.js.map → DemoHome-D_De3UiT.js.map} +1 -1
- package/dist/demo/{DemoJsonViewer-DsA2IpgV.js → DemoJsonViewer-B50s9aGM.js} +3 -3
- package/dist/demo/{DemoJsonViewer-DsA2IpgV.js.map → DemoJsonViewer-B50s9aGM.js.map} +1 -1
- package/dist/demo/{DemoLayout-Cy6xjn6P.js → DemoLayout-CHU8WTwO.js} +14 -5
- package/dist/demo/DemoLayout-CHU8WTwO.js.map +1 -0
- package/dist/demo/{DemoLogin-vqxgTu4P.js → DemoLogin-BBlrWpml.js} +49 -32
- package/dist/demo/DemoLogin-BBlrWpml.js.map +1 -0
- package/dist/demo/{DemoRegister-YHPvPg77.js → DemoRegister-BuNE3_-f.js} +49 -50
- package/dist/demo/DemoRegister-BuNE3_-f.js.map +1 -0
- package/dist/demo/{DemoResetPassword-mOW18Zlm.js → DemoResetPassword-D_IjjjOJ.js} +12 -16
- package/dist/demo/DemoResetPassword-D_IjjjOJ.js.map +1 -0
- package/dist/demo/{DemoSidebar-od7aLjP_.js → DemoSidebar-Giy2HRBD.js} +3 -3
- package/dist/demo/{DemoSidebar-od7aLjP_.js.map → DemoSidebar-Giy2HRBD.js.map} +1 -1
- package/dist/demo/{DemoText-DU3JeRS0.js → DemoText-ubcw-vog.js} +3 -3
- package/dist/demo/{DemoText-DU3JeRS0.js.map → DemoText-ubcw-vog.js.map} +1 -1
- package/dist/demo/{DemoToast-CUJEiPRa.js → DemoToast-9die_dYT.js} +2 -2
- package/dist/demo/{DemoToast-CUJEiPRa.js.map → DemoToast-9die_dYT.js.map} +1 -1
- package/dist/demo/{DemoTypeForm-C1dNkahD.js → DemoTypeForm-D_d6OVKL.js} +8 -4
- package/dist/demo/DemoTypeForm-D_d6OVKL.js.map +1 -0
- package/dist/demo/DemoVerifyEmail-B43KlF4F.js +34 -0
- package/dist/demo/DemoVerifyEmail-B43KlF4F.js.map +1 -0
- package/dist/demo/Login-C12N4oGs.js +275 -0
- package/dist/demo/Login-C12N4oGs.js.map +1 -0
- package/dist/demo/{Profile-BE_Y3co2.js → Profile-DS5q4vOh.js} +31 -27
- package/dist/demo/Profile-DS5q4vOh.js.map +1 -0
- package/dist/demo/{Register-fXHmBpr3.js → Register-B4hLBeEv.js} +198 -142
- package/dist/demo/Register-B4hLBeEv.js.map +1 -0
- package/dist/{auth/ResetPassword-DBxt9hKk.js → demo/ResetPassword-D8g9ha1N.js} +7 -7
- package/dist/demo/ResetPassword-D8g9ha1N.js.map +1 -0
- package/dist/demo/{Showcase-BtEU0pY9.js → Showcase-D6Fxt4X4.js} +64 -65
- package/dist/demo/Showcase-D6Fxt4X4.js.map +1 -0
- package/dist/{auth/VerifyEmail-Z80Ubajk.js → demo/VerifyEmail-BjDo0cZA.js} +23 -8
- package/dist/demo/VerifyEmail-BjDo0cZA.js.map +1 -0
- package/dist/demo/{auth-Djd7SKiw.js → auth-ByVTreDl.js} +8 -8
- package/dist/demo/{auth-Djd7SKiw.js.map → auth-ByVTreDl.js.map} +1 -1
- package/dist/demo/{core-B7LNjM78.js → core-DFgB3yU4.js} +741 -573
- package/dist/demo/core-DFgB3yU4.js.map +1 -0
- package/dist/demo/index.d.ts +1 -0
- package/dist/demo/index.d.ts.map +1 -1
- package/dist/demo/index.js +24 -18
- package/dist/demo/index.js.map +1 -1
- package/package.json +7 -7
- package/src/admin/AdminRouter.tsx +24 -1
- package/src/admin/components/notifications/AdminNotifications.tsx +519 -0
- package/src/admin/components/parameters/ParameterDetails.tsx +12 -270
- package/src/admin/components/parameters/ParameterDetailsConfigForm.tsx +238 -0
- package/src/admin/components/parameters/ParameterDetailsLoading.tsx +24 -0
- package/src/admin/components/parameters/ParameterHistory.tsx +10 -11
- package/src/admin/components/parameters/ParameterTree.tsx +28 -184
- package/src/admin/components/parameters/ParameterTreeNode.tsx +151 -0
- package/src/admin/components/shared/AdminResourceHeader.tsx +2 -25
- package/src/admin/components/shared/AdminResourceHeaderMenuItem.tsx +37 -0
- package/src/admin/components/shared/AdminResourceTabs.tsx +2 -26
- package/src/admin/components/shared/AdminResourceTabsItem.tsx +36 -0
- package/src/auth/components/Login.tsx +188 -121
- package/src/auth/components/Profile.tsx +1 -22
- package/src/auth/components/ProfileField.tsx +39 -0
- package/src/auth/components/Register.tsx +215 -158
- package/src/auth/components/ResetPassword.tsx +7 -11
- package/src/auth/components/VerifyEmail.tsx +35 -10
- package/src/auth/components/buttons/UserButton.tsx +19 -21
- package/src/auth/index.ts +1 -0
- package/src/core/components/Flex.tsx +10 -0
- package/src/core/components/buttons/ActionButton.tsx +104 -78
- package/src/core/components/data/DetailDrawer.tsx +102 -96
- package/src/core/components/data/DetailList.tsx +2 -1
- package/src/core/components/layout/Breadcrumb.tsx +3 -6
- package/src/core/components/layout/DashboardShell.tsx +18 -4
- package/src/core/components/layout/Sidebar.tsx +16 -241
- package/src/core/components/layout/SidebarCollapsedItem.tsx +91 -0
- package/src/core/components/layout/SidebarItem.tsx +146 -0
- package/src/core/components/layout/index.ts +3 -1
- package/src/core/form/components/Control.tsx +31 -29
- package/src/core/form/components/ControlArray.tsx +13 -39
- package/src/core/form/components/ControlDate.tsx +10 -21
- package/src/core/form/components/ControlNumber.tsx +4 -33
- package/src/core/form/components/ControlQueryBuilder.tsx +12 -175
- package/src/core/form/components/ControlQueryBuilderHelp.tsx +165 -0
- package/src/core/form/components/ControlSelect.browser.spec.tsx +343 -0
- package/src/core/form/components/ControlSelect.tsx +294 -92
- package/src/core/form/components/TypeForm.browser.spec.tsx +3 -3
- package/src/core/form/components/TypeForm.tsx +5 -2
- package/src/core/form/index.ts +8 -1
- package/src/core/form/utils/parseInput.ts +7 -3
- package/src/core/index.ts +3 -1
- package/src/core/json/components/JsonViewer.tsx +103 -319
- package/src/core/json/components/JsonViewerCopyButton.tsx +46 -0
- package/src/core/json/components/JsonViewerRowNode.tsx +120 -0
- package/src/core/json/components/JsonViewerShared.ts +76 -0
- package/src/core/styles.css +12 -2
- package/src/core/table/components/ColumnPicker.tsx +3 -3
- package/src/core/table/components/DataTable.tsx +89 -29
- package/src/core/table/components/DataTableFilters.tsx +6 -11
- package/src/core/table/components/DataTablePagination.tsx +9 -3
- package/src/core/table/components/DataTableToolbar.tsx +7 -3
- package/src/core/table/components/FilterPicker.tsx +3 -3
- package/src/core/table/interfaces/types.ts +29 -0
- package/src/core/utils/icons.tsx +2 -2
- package/src/demo/DemoRouter.ts +8 -1
- package/src/demo/components/DemoLayout.tsx +12 -2
- package/src/demo/components/auth/DemoLogin.tsx +35 -28
- package/src/demo/components/auth/DemoRegister.tsx +35 -49
- package/src/demo/components/auth/DemoResetPassword.tsx +5 -9
- package/src/demo/components/auth/DemoVerifyEmail.tsx +7 -6
- package/src/demo/components/core/DemoButton.tsx +123 -103
- package/src/demo/components/core/DemoControlSelect.tsx +325 -0
- package/src/demo/components/core/DemoDataTable.tsx +255 -237
- package/src/demo/components/core/DemoTypeForm.tsx +7 -2
- package/src/demo/components/shared/MacWindow.tsx +5 -11
- package/src/demo/components/shared/Showcase.tsx +28 -42
- package/dist/admin/AdminParameters-BspPeqp_.js.map +0 -1
- package/dist/admin/AdminUserLayout-DUbC6-BI.js.map +0 -1
- package/dist/admin/Login-DHbYJKwg.js +0 -219
- package/dist/admin/Login-DHbYJKwg.js.map +0 -1
- package/dist/admin/Profile-B2EcIDB9.js.map +0 -1
- package/dist/admin/Register-Z3fxRbUF.js.map +0 -1
- package/dist/admin/ResetPassword-_Y1qTTKh.js.map +0 -1
- package/dist/admin/VerifyEmail-Bg22bwcC.js.map +0 -1
- package/dist/admin/core-BVO_TQxb.js.map +0 -1
- package/dist/auth/Login-C7jIqf00.js +0 -219
- package/dist/auth/Login-C7jIqf00.js.map +0 -1
- package/dist/auth/Profile-BMpXJ0oi.js.map +0 -1
- package/dist/auth/Register-2gx8qll-.js.map +0 -1
- package/dist/auth/ResetPassword-DBxt9hKk.js.map +0 -1
- package/dist/auth/VerifyEmail-Z80Ubajk.js.map +0 -1
- package/dist/auth/core-DyfeVr5c.js.map +0 -1
- package/dist/demo/DemoButton-CGUyR9eM.js +0 -178
- package/dist/demo/DemoButton-CGUyR9eM.js.map +0 -1
- package/dist/demo/DemoDataTable-QFG-xXSx.js +0 -358
- package/dist/demo/DemoDataTable-QFG-xXSx.js.map +0 -1
- package/dist/demo/DemoLayout-Cy6xjn6P.js.map +0 -1
- package/dist/demo/DemoLogin-vqxgTu4P.js.map +0 -1
- package/dist/demo/DemoRegister-YHPvPg77.js.map +0 -1
- package/dist/demo/DemoResetPassword-mOW18Zlm.js.map +0 -1
- package/dist/demo/DemoTypeForm-C1dNkahD.js.map +0 -1
- package/dist/demo/DemoVerifyEmail-D9EcXZ38.js +0 -30
- package/dist/demo/DemoVerifyEmail-D9EcXZ38.js.map +0 -1
- package/dist/demo/Login-CoYf_P_F.js +0 -219
- package/dist/demo/Login-CoYf_P_F.js.map +0 -1
- package/dist/demo/Profile-BE_Y3co2.js.map +0 -1
- package/dist/demo/Register-fXHmBpr3.js.map +0 -1
- package/dist/demo/ResetPassword-CAPj8MO3.js.map +0 -1
- package/dist/demo/Showcase-BtEU0pY9.js.map +0 -1
- package/dist/demo/VerifyEmail-DFmdCdYs.js.map +0 -1
- package/dist/demo/core-B7LNjM78.js.map +0 -1
- package/src/demo/styles.css +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { $atom, $context, $inject, $module, Alepha, AlephaError, TypeBoxError, t } from "alepha";
|
|
2
|
-
import { AlephaReactForm, FormValidationError, useForm, useFormState } from "alepha/react/form";
|
|
2
|
+
import { AlephaReactForm, FormValidationError, useFieldValue, useForm, useFormState } from "alepha/react/form";
|
|
3
3
|
import { $head, AlephaReactHead, BrowserHeadProvider } from "alepha/react/head";
|
|
4
4
|
import { AlephaReactI18n, useI18n } from "alepha/react/i18n";
|
|
5
5
|
import { $cookie } from "alepha/server/cookies";
|
|
@@ -1548,41 +1548,10 @@ function isComponentType(param) {
|
|
|
1548
1548
|
|
|
1549
1549
|
//#endregion
|
|
1550
1550
|
//#region ../../src/core/components/buttons/ActionButton.tsx
|
|
1551
|
-
const ActionMenuItem = (props) => {
|
|
1552
|
-
const { item, index } = props;
|
|
1553
|
-
const router = useRouter();
|
|
1554
|
-
const action = useAction({ handler: async (e) => {
|
|
1555
|
-
await item.onClick?.();
|
|
1556
|
-
} }, [item.onClick]);
|
|
1557
|
-
if (item.type === "divider") return /* @__PURE__ */ jsx(Menu.Divider, {}, index);
|
|
1558
|
-
if (item.type === "label") return /* @__PURE__ */ jsx(Menu.Label, { children: item.label }, index);
|
|
1559
|
-
if (item.children && item.children.length > 0) return /* @__PURE__ */ jsxs(Menu, {
|
|
1560
|
-
trigger: "hover",
|
|
1561
|
-
position: "right-start",
|
|
1562
|
-
offset: 2,
|
|
1563
|
-
children: [/* @__PURE__ */ jsx(Menu.Target, { children: /* @__PURE__ */ jsx(Menu.Item, {
|
|
1564
|
-
leftSection: item.icon,
|
|
1565
|
-
rightSection: /* @__PURE__ */ jsx(IconChevronRight, { size: 14 }),
|
|
1566
|
-
children: item.label
|
|
1567
|
-
}) }), /* @__PURE__ */ jsx(Menu.Dropdown, { children: item.children.map((child, childIndex) => /* @__PURE__ */ jsx(ActionMenuItem, {
|
|
1568
|
-
item: child,
|
|
1569
|
-
index: childIndex
|
|
1570
|
-
}, childIndex)) })]
|
|
1571
|
-
}, index);
|
|
1572
|
-
const menuItemProps = {};
|
|
1573
|
-
if (props.item.onClick) menuItemProps.onClick = action.run;
|
|
1574
|
-
else if (props.item.href) Object.assign(menuItemProps, router.anchor(props.item.href));
|
|
1575
|
-
return /* @__PURE__ */ jsx(Menu.Item, {
|
|
1576
|
-
leftSection: item.icon ?? (item.active ? /* @__PURE__ */ jsx(IconCheck, { size: ui.sizes.icon.sm }) : /* @__PURE__ */ jsx(Flex, { w: ui.sizes.icon.sm })),
|
|
1577
|
-
onClick: item.onClick,
|
|
1578
|
-
color: item.color,
|
|
1579
|
-
...menuItemProps,
|
|
1580
|
-
children: item.label
|
|
1581
|
-
}, index);
|
|
1582
|
-
};
|
|
1583
1551
|
const ActionButton = (_props) => {
|
|
1584
1552
|
const theme = useMantineTheme();
|
|
1585
1553
|
const props = { ..._props };
|
|
1554
|
+
if (props.variant === "minimal") {}
|
|
1586
1555
|
const { tooltip, menu, icon, iconSize, ...restProps } = props;
|
|
1587
1556
|
if (props.intent) {
|
|
1588
1557
|
if (props.intent === "primary") restProps.color ??= theme.primaryColor;
|
|
@@ -1627,6 +1596,7 @@ const ActionButton = (_props) => {
|
|
|
1627
1596
|
children: /* @__PURE__ */ jsx(ActionButton, {
|
|
1628
1597
|
px: "xs",
|
|
1629
1598
|
...rest,
|
|
1599
|
+
"aria-label": typeof children === "string" ? children : void 0,
|
|
1630
1600
|
tooltip,
|
|
1631
1601
|
menu,
|
|
1632
1602
|
children: leftSection
|
|
@@ -1783,7 +1753,7 @@ const ActionClickButton = ({ preventDefault, ...props }) => {
|
|
|
1783
1753
|
* Action for navigation with active state support.
|
|
1784
1754
|
*/
|
|
1785
1755
|
const ActionNavigationButton = (props) => {
|
|
1786
|
-
const { active: options, classNameActive, variantActive, propsActive, routerGoOptions, onClick: propsOnClick, anchor, ...buttonProps } = props;
|
|
1756
|
+
const { active: options, classNameActive, variantActive, propsActive, routerGoOptions, onClick: propsOnClick, anchorProps: buttonAnchorProps, anchor, ...buttonProps } = props;
|
|
1787
1757
|
const router = useRouter();
|
|
1788
1758
|
const { isPending, isActive } = useActive(options ? {
|
|
1789
1759
|
href: props.href,
|
|
@@ -1797,11 +1767,11 @@ const ActionNavigationButton = (props) => {
|
|
|
1797
1767
|
};
|
|
1798
1768
|
const className = buttonProps.className || "";
|
|
1799
1769
|
if (isActive && options !== false && classNameActive) buttonProps.className = `${className} ${classNameActive}`.trim();
|
|
1800
|
-
if (
|
|
1770
|
+
if (buttonAnchorProps || anchor) return /* @__PURE__ */ jsx(Anchor, {
|
|
1801
1771
|
component: "a",
|
|
1802
1772
|
...anchorProps,
|
|
1803
1773
|
...buttonProps,
|
|
1804
|
-
...
|
|
1774
|
+
...buttonAnchorProps,
|
|
1805
1775
|
onClick: combinedOnClick,
|
|
1806
1776
|
children: props.children
|
|
1807
1777
|
});
|
|
@@ -1824,6 +1794,38 @@ const ActionHrefButton = (props) => {
|
|
|
1824
1794
|
children: props.children
|
|
1825
1795
|
});
|
|
1826
1796
|
};
|
|
1797
|
+
const ActionMenuItem = (props) => {
|
|
1798
|
+
const { item, index } = props;
|
|
1799
|
+
const router = useRouter();
|
|
1800
|
+
const action = useAction({ handler: async (e) => {
|
|
1801
|
+
await item.onClick?.();
|
|
1802
|
+
} }, [item.onClick]);
|
|
1803
|
+
if (item.type === "divider") return /* @__PURE__ */ jsx(Menu.Divider, {}, index);
|
|
1804
|
+
if (item.type === "label") return /* @__PURE__ */ jsx(Menu.Label, { children: item.label }, index);
|
|
1805
|
+
if (item.children && item.children.length > 0) return /* @__PURE__ */ jsxs(Menu, {
|
|
1806
|
+
trigger: "hover",
|
|
1807
|
+
position: "right-start",
|
|
1808
|
+
offset: 2,
|
|
1809
|
+
children: [/* @__PURE__ */ jsx(Menu.Target, { children: /* @__PURE__ */ jsx(Menu.Item, {
|
|
1810
|
+
leftSection: item.icon,
|
|
1811
|
+
rightSection: /* @__PURE__ */ jsx(IconChevronRight, { size: 14 }),
|
|
1812
|
+
children: item.label
|
|
1813
|
+
}) }), /* @__PURE__ */ jsx(Menu.Dropdown, { children: item.children.map((child, childIndex) => /* @__PURE__ */ jsx(ActionMenuItem, {
|
|
1814
|
+
item: child,
|
|
1815
|
+
index: childIndex
|
|
1816
|
+
}, childIndex)) })]
|
|
1817
|
+
}, index);
|
|
1818
|
+
const menuItemProps = {};
|
|
1819
|
+
if (props.item.onClick) menuItemProps.onClick = action.run;
|
|
1820
|
+
else if (props.item.href) Object.assign(menuItemProps, router.anchor(props.item.href));
|
|
1821
|
+
return /* @__PURE__ */ jsx(Menu.Item, {
|
|
1822
|
+
leftSection: item.icon ?? (item.active ? /* @__PURE__ */ jsx(IconCheck, { size: ui.sizes.icon.sm }) : /* @__PURE__ */ jsx(Flex, { w: ui.sizes.icon.sm })),
|
|
1823
|
+
onClick: item.onClick,
|
|
1824
|
+
color: item.color,
|
|
1825
|
+
...menuItemProps,
|
|
1826
|
+
children: item.label
|
|
1827
|
+
}, index);
|
|
1828
|
+
};
|
|
1827
1829
|
|
|
1828
1830
|
//#endregion
|
|
1829
1831
|
//#region ../../src/core/components/buttons/BurgerButton.tsx
|
|
@@ -2214,7 +2216,7 @@ const ToggleSidebarButton = (props) => {
|
|
|
2214
2216
|
//#endregion
|
|
2215
2217
|
//#region ../../src/core/components/Flex.tsx
|
|
2216
2218
|
const Flex$1 = forwardRef((props, ref) => {
|
|
2217
|
-
const { fill, center, centerX, centerY, col, ground, surface, elevated, rounded, bordered, borderedTop, borderedBottom, shadowed, ...rest } = props;
|
|
2219
|
+
const { fill, center, centerX, centerY, col, ground, surface, elevated, rounded, bordered, borderedTop, borderedBottom, shadowed, overflow, ...rest } = props;
|
|
2218
2220
|
if (fill) rest.flex ??= 1;
|
|
2219
2221
|
if (col) rest.direction ??= "column";
|
|
2220
2222
|
if (center) {
|
|
@@ -2237,6 +2239,7 @@ const Flex$1 = forwardRef((props, ref) => {
|
|
|
2237
2239
|
...rest.style ?? {}
|
|
2238
2240
|
};
|
|
2239
2241
|
if (shadowed) rest.className = `${rest.className ?? ""} shadow-${shadowed === true ? "md" : shadowed}`.trim();
|
|
2242
|
+
if (overflow) rest.className = `${rest.className ?? ""} overflow-auto`.trim();
|
|
2240
2243
|
return /* @__PURE__ */ jsx(Flex, {
|
|
2241
2244
|
ref,
|
|
2242
2245
|
...rest
|
|
@@ -2374,7 +2377,8 @@ const AppBar = (props) => {
|
|
|
2374
2377
|
* Pages should define a `label` in their `$page()` options for best results.
|
|
2375
2378
|
* Falls back to the page name converted to Title Case.
|
|
2376
2379
|
*/
|
|
2377
|
-
const Breadcrumb = (
|
|
2380
|
+
const Breadcrumb = (props) => {
|
|
2381
|
+
const { home = "Home", separator, size = "sm", ...groupProps } = props;
|
|
2378
2382
|
const state = useRouterState();
|
|
2379
2383
|
const router = useRouter();
|
|
2380
2384
|
const crumbs = [];
|
|
@@ -2429,11 +2433,175 @@ const Container$1 = forwardRef((props, ref) => {
|
|
|
2429
2433
|
});
|
|
2430
2434
|
Container$1.displayName = "Container";
|
|
2431
2435
|
|
|
2436
|
+
//#endregion
|
|
2437
|
+
//#region ../../src/core/helpers/renderIcon.tsx
|
|
2438
|
+
const renderIcon = (icon, size) => {
|
|
2439
|
+
if (!icon) return null;
|
|
2440
|
+
if (isValidElement(icon)) return icon;
|
|
2441
|
+
if (isComponentType(icon)) return /* @__PURE__ */ jsx(icon, { size: size ?? ui.sizes.icon.md });
|
|
2442
|
+
return icon;
|
|
2443
|
+
};
|
|
2444
|
+
|
|
2445
|
+
//#endregion
|
|
2446
|
+
//#region ../../src/core/components/Text.tsx
|
|
2447
|
+
const INTENT_COLORS = {
|
|
2448
|
+
primary: "blue",
|
|
2449
|
+
info: "cyan",
|
|
2450
|
+
success: "green",
|
|
2451
|
+
warning: "yellow",
|
|
2452
|
+
danger: "red"
|
|
2453
|
+
};
|
|
2454
|
+
const Text$1 = forwardRef((props, ref) => {
|
|
2455
|
+
const { intent, bold, italic, light, muted, small, uppercase, capitalize, center, monospace, title, ...rest } = props;
|
|
2456
|
+
if (intent) rest.c ??= INTENT_COLORS[intent];
|
|
2457
|
+
if (bold) rest.fw ??= 700;
|
|
2458
|
+
if (light) rest.fw ??= 300;
|
|
2459
|
+
if (italic) rest.fs ??= "italic";
|
|
2460
|
+
if (muted) rest.c ??= "dimmed";
|
|
2461
|
+
if (small) rest.size ??= "xs";
|
|
2462
|
+
if (uppercase) rest.tt ??= "uppercase";
|
|
2463
|
+
if (capitalize) rest.tt ??= "capitalize";
|
|
2464
|
+
if (center) rest.ta ??= "center";
|
|
2465
|
+
if (monospace) rest.ff ??= "monospace";
|
|
2466
|
+
if (title) rest.size ??= "xl";
|
|
2467
|
+
return /* @__PURE__ */ jsx(Text, {
|
|
2468
|
+
ref,
|
|
2469
|
+
...rest
|
|
2470
|
+
});
|
|
2471
|
+
});
|
|
2472
|
+
Text$1.displayName = "Text";
|
|
2473
|
+
|
|
2474
|
+
//#endregion
|
|
2475
|
+
//#region ../../src/core/components/layout/SidebarCollapsedItem.tsx
|
|
2476
|
+
const SidebarCollapsedItem = (props) => {
|
|
2477
|
+
const router = useRouter();
|
|
2478
|
+
const handleItemClick = () => {
|
|
2479
|
+
props.onItemClick?.(props.item);
|
|
2480
|
+
props.item.onClick?.();
|
|
2481
|
+
};
|
|
2482
|
+
const hasChildren = props.item.children && props.item.children.length > 0;
|
|
2483
|
+
const menu = hasChildren ? {
|
|
2484
|
+
on: "hover",
|
|
2485
|
+
position: "right",
|
|
2486
|
+
menuProps: {
|
|
2487
|
+
arrowPosition: "center",
|
|
2488
|
+
arrowSize: 10,
|
|
2489
|
+
withArrow: true
|
|
2490
|
+
},
|
|
2491
|
+
items: [{
|
|
2492
|
+
type: "label",
|
|
2493
|
+
label: props.item.label
|
|
2494
|
+
}, ...props.item.children.filter((child) => !child.can || child.can()).map((child) => ({
|
|
2495
|
+
label: child.label,
|
|
2496
|
+
icon: renderIcon(child.icon, ui.sizes.icon.sm),
|
|
2497
|
+
href: child.href,
|
|
2498
|
+
active: child.href ? router.isActive(child.href, { startWith: child.activeStartsWith }) : void 0
|
|
2499
|
+
}))]
|
|
2500
|
+
} : void 0;
|
|
2501
|
+
return /* @__PURE__ */ jsx(Flex$1, {
|
|
2502
|
+
w: "100%",
|
|
2503
|
+
justify: "center",
|
|
2504
|
+
pos: "relative",
|
|
2505
|
+
children: /* @__PURE__ */ jsx(ActionButton, {
|
|
2506
|
+
size: props.item.theme?.size ?? props.theme.button?.size ?? (props.level === 0 ? "sm" : "xs"),
|
|
2507
|
+
bd: 0,
|
|
2508
|
+
variant: "default",
|
|
2509
|
+
propsActive: { variant: "outline" },
|
|
2510
|
+
tooltip: hasChildren ? void 0 : {
|
|
2511
|
+
label: props.item.label,
|
|
2512
|
+
position: "right"
|
|
2513
|
+
},
|
|
2514
|
+
onClick: hasChildren ? void 0 : handleItemClick,
|
|
2515
|
+
icon: renderIcon(props.item.icon, ui.sizes.icon.sm) ?? /* @__PURE__ */ jsx(IconSquareRounded, { size: ui.sizes.icon.sm }),
|
|
2516
|
+
href: hasChildren ? void 0 : props.item.href,
|
|
2517
|
+
target: hasChildren ? void 0 : props.item.target,
|
|
2518
|
+
menu,
|
|
2519
|
+
...props.item.actionProps
|
|
2520
|
+
})
|
|
2521
|
+
});
|
|
2522
|
+
};
|
|
2523
|
+
|
|
2524
|
+
//#endregion
|
|
2525
|
+
//#region ../../src/core/components/layout/SidebarItem.tsx
|
|
2526
|
+
const SidebarItem = (props) => {
|
|
2527
|
+
const maxLevel = 2;
|
|
2528
|
+
const router = useRouter();
|
|
2529
|
+
const isActive = useCallback((item) => {
|
|
2530
|
+
if (!item.children) return false;
|
|
2531
|
+
for (const child of item.children) {
|
|
2532
|
+
if (child.href) {
|
|
2533
|
+
if (router.isActive(child.href)) return true;
|
|
2534
|
+
}
|
|
2535
|
+
if (isActive(child)) return true;
|
|
2536
|
+
}
|
|
2537
|
+
return false;
|
|
2538
|
+
}, []);
|
|
2539
|
+
const [isOpen, setIsOpen] = useState(isActive(props.item));
|
|
2540
|
+
useEvents({ "react:transition:end": () => {
|
|
2541
|
+
if (isActive(props.item)) setIsOpen(true);
|
|
2542
|
+
} }, []);
|
|
2543
|
+
if (props.level > maxLevel) return null;
|
|
2544
|
+
const handleItemClick = (e) => {
|
|
2545
|
+
if (!props.item.target) e.preventDefault();
|
|
2546
|
+
if (props.item.children && props.item.children.length > 0) setIsOpen(!isOpen);
|
|
2547
|
+
else {
|
|
2548
|
+
props.onItemClick?.(props.item);
|
|
2549
|
+
props.item.onClick?.();
|
|
2550
|
+
}
|
|
2551
|
+
};
|
|
2552
|
+
return /* @__PURE__ */ jsxs(Flex$1, {
|
|
2553
|
+
direction: "column",
|
|
2554
|
+
ps: props.level === 0 ? 0 : 32,
|
|
2555
|
+
pos: "relative",
|
|
2556
|
+
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
2557
|
+
w: "100%",
|
|
2558
|
+
justify: "space-between",
|
|
2559
|
+
href: props.item.href,
|
|
2560
|
+
target: props.item.target,
|
|
2561
|
+
size: props.item.theme?.size ?? props.theme.button?.size ?? (props.level === 0 ? "sm" : "xs"),
|
|
2562
|
+
bd: 0,
|
|
2563
|
+
fw: "normal",
|
|
2564
|
+
variant: "default",
|
|
2565
|
+
propsActive: { variant: "outline" },
|
|
2566
|
+
radius: props.item.theme?.radius ?? props.theme.button?.radius ?? "md",
|
|
2567
|
+
onClick: handleItemClick,
|
|
2568
|
+
leftSection: /* @__PURE__ */ jsxs(Flex$1, {
|
|
2569
|
+
w: "100%",
|
|
2570
|
+
align: "center",
|
|
2571
|
+
gap: "sm",
|
|
2572
|
+
children: [renderIcon(props.item.icon, ui.sizes.icon.sm), /* @__PURE__ */ jsx(Flex$1, {
|
|
2573
|
+
direction: "column",
|
|
2574
|
+
children: /* @__PURE__ */ jsx(Flex$1, { children: props.item.label })
|
|
2575
|
+
})]
|
|
2576
|
+
}),
|
|
2577
|
+
rightSection: props.item.children ? /* @__PURE__ */ jsx(Flex$1, { children: isOpen ? /* @__PURE__ */ jsx(IconChevronDown, { size: 14 }) : /* @__PURE__ */ jsx(IconChevronRight, { size: 14 }) }) : props.item.rightSection,
|
|
2578
|
+
...props.item.actionProps
|
|
2579
|
+
}), props.item.children && isOpen && /* @__PURE__ */ jsxs(Flex$1, {
|
|
2580
|
+
direction: "column",
|
|
2581
|
+
"data-parent-level": props.level,
|
|
2582
|
+
gap: 2,
|
|
2583
|
+
py: 2,
|
|
2584
|
+
children: [/* @__PURE__ */ jsx(Flex$1, { style: {
|
|
2585
|
+
position: "absolute",
|
|
2586
|
+
width: 1,
|
|
2587
|
+
background: "linear-gradient(to bottom, transparent, var(--mantine-color-default-border), transparent)",
|
|
2588
|
+
top: 48,
|
|
2589
|
+
left: 20 + 32 * props.level,
|
|
2590
|
+
bottom: 16
|
|
2591
|
+
} }), props.item.children.filter((child) => !child.can || child.can()).map((child, index) => /* @__PURE__ */ jsx(SidebarItem, {
|
|
2592
|
+
item: child,
|
|
2593
|
+
level: props.level + 1,
|
|
2594
|
+
onItemClick: props.onItemClick,
|
|
2595
|
+
theme: props.theme
|
|
2596
|
+
}, index))]
|
|
2597
|
+
})]
|
|
2598
|
+
});
|
|
2599
|
+
};
|
|
2600
|
+
|
|
2432
2601
|
//#endregion
|
|
2433
2602
|
//#region ../../src/core/components/layout/Sidebar.tsx
|
|
2434
2603
|
const Sidebar = (props) => {
|
|
2435
2604
|
const router = useRouter();
|
|
2436
|
-
const { onItemClick } = props;
|
|
2437
2605
|
const divider = (key, fill, collapsed) => {
|
|
2438
2606
|
return /* @__PURE__ */ jsx(Flex$1, {
|
|
2439
2607
|
h: 1,
|
|
@@ -2484,13 +2652,13 @@ const Sidebar = (props) => {
|
|
|
2484
2652
|
if (collapsed) return /* @__PURE__ */ jsx(SidebarCollapsedItem, {
|
|
2485
2653
|
item,
|
|
2486
2654
|
level: 0,
|
|
2487
|
-
onItemClick,
|
|
2655
|
+
onItemClick: props.onItemClick,
|
|
2488
2656
|
theme: props.theme ?? {}
|
|
2489
2657
|
}, key);
|
|
2490
2658
|
return /* @__PURE__ */ jsx(SidebarItem, {
|
|
2491
2659
|
item,
|
|
2492
2660
|
level: 0,
|
|
2493
|
-
onItemClick,
|
|
2661
|
+
onItemClick: props.onItemClick,
|
|
2494
2662
|
theme: props.theme ?? {}
|
|
2495
2663
|
}, key);
|
|
2496
2664
|
};
|
|
@@ -2553,129 +2721,6 @@ const Sidebar = (props) => {
|
|
|
2553
2721
|
})] });
|
|
2554
2722
|
return renderSidebar(false);
|
|
2555
2723
|
};
|
|
2556
|
-
const SidebarItem = (props) => {
|
|
2557
|
-
const { item, level } = props;
|
|
2558
|
-
const maxLevel = 2;
|
|
2559
|
-
const router = useRouter();
|
|
2560
|
-
const isActive = useCallback((item) => {
|
|
2561
|
-
if (!item.children) return false;
|
|
2562
|
-
for (const child of item.children) {
|
|
2563
|
-
if (child.href) {
|
|
2564
|
-
if (router.isActive(child.href)) return true;
|
|
2565
|
-
}
|
|
2566
|
-
if (isActive(child)) return true;
|
|
2567
|
-
}
|
|
2568
|
-
return false;
|
|
2569
|
-
}, []);
|
|
2570
|
-
const [isOpen, setIsOpen] = useState(isActive(item));
|
|
2571
|
-
useEvents({ "react:transition:end": () => {
|
|
2572
|
-
if (isActive(item)) setIsOpen(true);
|
|
2573
|
-
} }, []);
|
|
2574
|
-
if (level > maxLevel) return null;
|
|
2575
|
-
const handleItemClick = (e) => {
|
|
2576
|
-
if (!props.item.target) e.preventDefault();
|
|
2577
|
-
if (item.children && item.children.length > 0) setIsOpen(!isOpen);
|
|
2578
|
-
else {
|
|
2579
|
-
props.onItemClick?.(item);
|
|
2580
|
-
item.onClick?.();
|
|
2581
|
-
}
|
|
2582
|
-
};
|
|
2583
|
-
return /* @__PURE__ */ jsxs(Flex$1, {
|
|
2584
|
-
direction: "column",
|
|
2585
|
-
ps: level === 0 ? 0 : 32,
|
|
2586
|
-
pos: "relative",
|
|
2587
|
-
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
2588
|
-
w: "100%",
|
|
2589
|
-
justify: "space-between",
|
|
2590
|
-
href: props.item.href,
|
|
2591
|
-
target: props.item.target,
|
|
2592
|
-
size: props.item.theme?.size ?? props.theme.button?.size ?? (level === 0 ? "sm" : "xs"),
|
|
2593
|
-
bd: 0,
|
|
2594
|
-
fw: "normal",
|
|
2595
|
-
variant: "default",
|
|
2596
|
-
propsActive: { variant: "outline" },
|
|
2597
|
-
radius: props.item.theme?.radius ?? props.theme.button?.radius ?? "md",
|
|
2598
|
-
onClick: handleItemClick,
|
|
2599
|
-
leftSection: /* @__PURE__ */ jsxs(Flex$1, {
|
|
2600
|
-
w: "100%",
|
|
2601
|
-
align: "center",
|
|
2602
|
-
gap: "sm",
|
|
2603
|
-
children: [renderIcon(item.icon, ui.sizes.icon.sm), /* @__PURE__ */ jsx(Flex$1, {
|
|
2604
|
-
direction: "column",
|
|
2605
|
-
children: /* @__PURE__ */ jsx(Flex$1, { children: item.label })
|
|
2606
|
-
})]
|
|
2607
|
-
}),
|
|
2608
|
-
rightSection: item.children ? /* @__PURE__ */ jsx(Flex$1, { children: isOpen ? /* @__PURE__ */ jsx(IconChevronDown, { size: 14 }) : /* @__PURE__ */ jsx(IconChevronRight, { size: 14 }) }) : props.item.rightSection,
|
|
2609
|
-
...props.item.actionProps
|
|
2610
|
-
}), item.children && isOpen && /* @__PURE__ */ jsxs(Flex$1, {
|
|
2611
|
-
direction: "column",
|
|
2612
|
-
"data-parent-level": level,
|
|
2613
|
-
gap: 2,
|
|
2614
|
-
py: 2,
|
|
2615
|
-
children: [/* @__PURE__ */ jsx(Flex$1, { style: {
|
|
2616
|
-
position: "absolute",
|
|
2617
|
-
width: 1,
|
|
2618
|
-
background: "linear-gradient(to bottom, transparent, var(--mantine-color-default-border), transparent)",
|
|
2619
|
-
top: 48,
|
|
2620
|
-
left: 20 + 32 * level,
|
|
2621
|
-
bottom: 16
|
|
2622
|
-
} }), item.children.filter((child) => !child.can || child.can()).map((child, index) => /* @__PURE__ */ jsx(SidebarItem, {
|
|
2623
|
-
item: child,
|
|
2624
|
-
level: level + 1,
|
|
2625
|
-
onItemClick: props.onItemClick,
|
|
2626
|
-
theme: props.theme
|
|
2627
|
-
}, index))]
|
|
2628
|
-
})]
|
|
2629
|
-
});
|
|
2630
|
-
};
|
|
2631
|
-
const SidebarCollapsedItem = (props) => {
|
|
2632
|
-
const { item, level } = props;
|
|
2633
|
-
const router = useRouter();
|
|
2634
|
-
const handleItemClick = () => {
|
|
2635
|
-
props.onItemClick?.(item);
|
|
2636
|
-
item.onClick?.();
|
|
2637
|
-
};
|
|
2638
|
-
const hasChildren = item.children && item.children.length > 0;
|
|
2639
|
-
const menu = hasChildren ? {
|
|
2640
|
-
on: "hover",
|
|
2641
|
-
position: "right",
|
|
2642
|
-
menuProps: {
|
|
2643
|
-
arrowPosition: "center",
|
|
2644
|
-
arrowSize: 10,
|
|
2645
|
-
withArrow: true
|
|
2646
|
-
},
|
|
2647
|
-
items: [{
|
|
2648
|
-
type: "label",
|
|
2649
|
-
label: item.label
|
|
2650
|
-
}, ...item.children.filter((child) => !child.can || child.can()).map((child) => ({
|
|
2651
|
-
label: child.label,
|
|
2652
|
-
icon: renderIcon(child.icon, ui.sizes.icon.sm),
|
|
2653
|
-
href: child.href,
|
|
2654
|
-
active: child.href ? router.isActive(child.href, { startWith: child.activeStartsWith }) : void 0
|
|
2655
|
-
}))]
|
|
2656
|
-
} : void 0;
|
|
2657
|
-
return /* @__PURE__ */ jsx(Flex$1, {
|
|
2658
|
-
w: "100%",
|
|
2659
|
-
justify: "center",
|
|
2660
|
-
pos: "relative",
|
|
2661
|
-
children: /* @__PURE__ */ jsx(ActionButton, {
|
|
2662
|
-
size: props.item.theme?.size ?? props.theme.button?.size ?? (level === 0 ? "sm" : "xs"),
|
|
2663
|
-
bd: 0,
|
|
2664
|
-
variant: "default",
|
|
2665
|
-
propsActive: { variant: "outline" },
|
|
2666
|
-
tooltip: hasChildren ? void 0 : {
|
|
2667
|
-
label: item.label,
|
|
2668
|
-
position: "right"
|
|
2669
|
-
},
|
|
2670
|
-
onClick: hasChildren ? void 0 : handleItemClick,
|
|
2671
|
-
icon: renderIcon(item.icon, ui.sizes.icon.sm) ?? /* @__PURE__ */ jsx(IconSquareRounded, { size: ui.sizes.icon.sm }),
|
|
2672
|
-
href: hasChildren ? void 0 : props.item.href,
|
|
2673
|
-
target: hasChildren ? void 0 : props.item.target,
|
|
2674
|
-
menu,
|
|
2675
|
-
...props.item.actionProps
|
|
2676
|
-
})
|
|
2677
|
-
});
|
|
2678
|
-
};
|
|
2679
2724
|
|
|
2680
2725
|
//#endregion
|
|
2681
2726
|
//#region ../../src/core/components/layout/DashboardShell.tsx
|
|
@@ -2716,6 +2761,8 @@ const DashboardShell = (props) => {
|
|
|
2716
2761
|
const fHeight = props.footerHeight ?? 24;
|
|
2717
2762
|
const headerHeight = hasAppBar ? hHeight : 0;
|
|
2718
2763
|
const footerHeight = footerElement ? fHeight : 0;
|
|
2764
|
+
const navbarWidth = collapsed ? collapsedWidth : expandedWidth;
|
|
2765
|
+
const mainContent = props.children ?? /* @__PURE__ */ jsx(NestedView, {});
|
|
2719
2766
|
return /* @__PURE__ */ jsxs(AppShell, {
|
|
2720
2767
|
layout: "alt",
|
|
2721
2768
|
w: "100%",
|
|
@@ -2723,7 +2770,7 @@ const DashboardShell = (props) => {
|
|
|
2723
2770
|
flex: 1,
|
|
2724
2771
|
header: hasAppBar ? { height: hHeight } : void 0,
|
|
2725
2772
|
navbar: hasSidebar ? {
|
|
2726
|
-
width: { base:
|
|
2773
|
+
width: { base: navbarWidth },
|
|
2727
2774
|
breakpoint: "md",
|
|
2728
2775
|
collapsed: { mobile: sidebar.closed }
|
|
2729
2776
|
} : void 0,
|
|
@@ -2760,8 +2807,12 @@ const DashboardShell = (props) => {
|
|
|
2760
2807
|
display: "flex",
|
|
2761
2808
|
bg: "var(--alepha-ground)",
|
|
2762
2809
|
pos: "relative",
|
|
2810
|
+
h: props.fill ? "100%" : "inherit",
|
|
2763
2811
|
...props.appShellMainProps,
|
|
2764
|
-
children: props.
|
|
2812
|
+
children: props.container ? /* @__PURE__ */ jsx(Container$1, {
|
|
2813
|
+
...typeof props.container === "boolean" ? {} : props.container,
|
|
2814
|
+
children: mainContent
|
|
2815
|
+
}) : mainContent
|
|
2765
2816
|
}),
|
|
2766
2817
|
footerElement && /* @__PURE__ */ jsx(AppShell.Footer, {
|
|
2767
2818
|
...props.appShellFooterProps,
|
|
@@ -2771,41 +2822,12 @@ const DashboardShell = (props) => {
|
|
|
2771
2822
|
});
|
|
2772
2823
|
};
|
|
2773
2824
|
|
|
2774
|
-
//#endregion
|
|
2775
|
-
//#region ../../src/core/components/Text.tsx
|
|
2776
|
-
const INTENT_COLORS = {
|
|
2777
|
-
primary: "blue",
|
|
2778
|
-
info: "cyan",
|
|
2779
|
-
success: "green",
|
|
2780
|
-
warning: "yellow",
|
|
2781
|
-
danger: "red"
|
|
2782
|
-
};
|
|
2783
|
-
const Text$1 = forwardRef((props, ref) => {
|
|
2784
|
-
const { intent, bold, italic, light, muted, small, uppercase, capitalize, center, monospace, title, ...rest } = props;
|
|
2785
|
-
if (intent) rest.c ??= INTENT_COLORS[intent];
|
|
2786
|
-
if (bold) rest.fw ??= 700;
|
|
2787
|
-
if (light) rest.fw ??= 300;
|
|
2788
|
-
if (italic) rest.fs ??= "italic";
|
|
2789
|
-
if (muted) rest.c ??= "dimmed";
|
|
2790
|
-
if (small) rest.size ??= "xs";
|
|
2791
|
-
if (uppercase) rest.tt ??= "uppercase";
|
|
2792
|
-
if (capitalize) rest.tt ??= "capitalize";
|
|
2793
|
-
if (center) rest.ta ??= "center";
|
|
2794
|
-
if (monospace) rest.ff ??= "monospace";
|
|
2795
|
-
if (title) rest.size ??= "xl";
|
|
2796
|
-
return /* @__PURE__ */ jsx(Text, {
|
|
2797
|
-
ref,
|
|
2798
|
-
...rest
|
|
2799
|
-
});
|
|
2800
|
-
});
|
|
2801
|
-
Text$1.displayName = "Text";
|
|
2802
|
-
|
|
2803
2825
|
//#endregion
|
|
2804
2826
|
//#region ../../src/core/form/utils/parseInput.ts
|
|
2805
2827
|
const parseInput = (props, form) => {
|
|
2806
2828
|
const disabled = false;
|
|
2807
2829
|
const id = props.input.props.id;
|
|
2808
|
-
const label = props.
|
|
2830
|
+
const label = props.label ?? ("title" in props.input.schema && typeof props.input.schema.title === "string" ? props.input.schema.title : void 0) ?? prettyName(props.input.path);
|
|
2809
2831
|
const description = props.description ?? ("description" in props.input.schema && typeof props.input.schema.description === "string" ? props.input.schema.description : void 0);
|
|
2810
2832
|
const error = form.error && form.error instanceof TypeBoxError ? form.error.value.message : void 0;
|
|
2811
2833
|
const icon = !props.icon ? getDefaultIcon({
|
|
@@ -2813,17 +2835,20 @@ const parseInput = (props, form) => {
|
|
|
2813
2835
|
format: props.input.schema && "format" in props.input.schema && typeof props.input.schema.format === "string" ? props.input.schema.format : void 0,
|
|
2814
2836
|
name: props.input.props.name,
|
|
2815
2837
|
isEnum: props.input.schema && "enum" in props.input.schema && Boolean(props.input.schema.enum),
|
|
2816
|
-
isArray: props.input.schema && "type" in props.input.schema && props.input.schema.type === "array"
|
|
2817
|
-
|
|
2838
|
+
isArray: props.input.schema && "type" in props.input.schema && props.input.schema.type === "array",
|
|
2839
|
+
size: props.size
|
|
2840
|
+
}) : isValidElement(props.icon) ? props.icon : createElement(props.icon, { size: ui.sizes.icon.sm });
|
|
2818
2841
|
const format = props.input.schema && "format" in props.input.schema && typeof props.input.schema.format === "string" ? props.input.schema.format : void 0;
|
|
2819
2842
|
const required = props.input.required;
|
|
2820
2843
|
const schema = props.input.schema;
|
|
2844
|
+
const testId = props.input.props?.["data-testid"];
|
|
2821
2845
|
const inputProps = {
|
|
2822
2846
|
label,
|
|
2823
2847
|
description,
|
|
2824
2848
|
error,
|
|
2825
2849
|
required,
|
|
2826
|
-
disabled
|
|
2850
|
+
disabled,
|
|
2851
|
+
...testId ? { "data-testid": testId } : {}
|
|
2827
2852
|
};
|
|
2828
2853
|
if ("minLength" in schema && typeof schema.minLength === "number") inputProps.minLength = schema.minLength;
|
|
2829
2854
|
if ("maxLength" in schema && typeof schema.maxLength === "number") inputProps.maxLength = schema.maxLength;
|
|
@@ -2848,8 +2873,8 @@ const useArrayItems = (input) => {
|
|
|
2848
2873
|
const alepha = useAlepha();
|
|
2849
2874
|
const keyCounter = useRef(0);
|
|
2850
2875
|
const [items, setItemsState] = useState(() => {
|
|
2851
|
-
const
|
|
2852
|
-
if (Array.isArray(
|
|
2876
|
+
const initial = input?.initialValue;
|
|
2877
|
+
if (Array.isArray(initial)) return initial.map((value) => ({
|
|
2853
2878
|
key: keyCounter.current++,
|
|
2854
2879
|
value
|
|
2855
2880
|
}));
|
|
@@ -2875,22 +2900,9 @@ const useArrayItems = (input) => {
|
|
|
2875
2900
|
if (!input?.form) return;
|
|
2876
2901
|
const formId = input.form.id;
|
|
2877
2902
|
const fieldPath = input.path;
|
|
2878
|
-
|
|
2879
|
-
if (event.id === formId) {
|
|
2880
|
-
const defaultValue = input.props?.defaultValue;
|
|
2881
|
-
keyCounter.current = 0;
|
|
2882
|
-
if (Array.isArray(defaultValue)) setItemsState(defaultValue.map((value) => ({
|
|
2883
|
-
key: keyCounter.current++,
|
|
2884
|
-
value
|
|
2885
|
-
})));
|
|
2886
|
-
else setItemsState([]);
|
|
2887
|
-
}
|
|
2888
|
-
}), alepha.events.on("form:change", (event) => {
|
|
2903
|
+
return alepha.events.on("form:change", (event) => {
|
|
2889
2904
|
if (event.id === formId && event.path === fieldPath) syncFromFormValue(event.value);
|
|
2890
|
-
})
|
|
2891
|
-
return () => {
|
|
2892
|
-
for (const unsub of listeners) unsub();
|
|
2893
|
-
};
|
|
2905
|
+
});
|
|
2894
2906
|
}, [
|
|
2895
2907
|
alepha,
|
|
2896
2908
|
input,
|
|
@@ -2915,10 +2927,10 @@ const createArrayItemInput = (parentInput, itemSchema, index, _itemKey, value, o
|
|
|
2915
2927
|
path: `${parentInput.path}/${index}`,
|
|
2916
2928
|
required: false,
|
|
2917
2929
|
form: parentInput.form,
|
|
2930
|
+
initialValue: value,
|
|
2918
2931
|
props: {
|
|
2919
2932
|
id: `${parentInput.props.id}-${index}`,
|
|
2920
|
-
name: `${parentInput.props.name}[${index}]
|
|
2921
|
-
defaultValue: value
|
|
2933
|
+
name: `${parentInput.props.name}[${index}]`
|
|
2922
2934
|
},
|
|
2923
2935
|
set: onValueChange
|
|
2924
2936
|
};
|
|
@@ -2933,10 +2945,10 @@ const createArrayItemFieldInput = (parentInput, itemSchema, fieldName, index, _i
|
|
|
2933
2945
|
path: `${parentInput.path}/${index}/${fieldName}`,
|
|
2934
2946
|
required: itemSchema.required?.includes(fieldName) ?? false,
|
|
2935
2947
|
form: parentInput.form,
|
|
2948
|
+
initialValue: itemValue?.[fieldName],
|
|
2936
2949
|
props: {
|
|
2937
2950
|
id: `${parentInput.props.id}-${index}-${fieldName}`,
|
|
2938
|
-
name: `${parentInput.props.name}[${index}].${fieldName}
|
|
2939
|
-
defaultValue: itemValue?.[fieldName]
|
|
2951
|
+
name: `${parentInput.props.name}[${index}].${fieldName}`
|
|
2940
2952
|
},
|
|
2941
2953
|
set: (value) => onFieldChange(fieldName, value)
|
|
2942
2954
|
};
|
|
@@ -3154,7 +3166,9 @@ const ControlArray = (props) => {
|
|
|
3154
3166
|
* Automatically detects date formats from schema and renders appropriate picker.
|
|
3155
3167
|
*/
|
|
3156
3168
|
const ControlDate = (props) => {
|
|
3157
|
-
const
|
|
3169
|
+
const form = useFormState(props.input);
|
|
3170
|
+
const [value, setValue] = useFieldValue(props.input);
|
|
3171
|
+
const { inputProps, id, icon, format } = parseInput(props, form);
|
|
3158
3172
|
if (!props.input?.props) return null;
|
|
3159
3173
|
if (props.datetime || format === "date-time") {
|
|
3160
3174
|
const dateTimePickerProps = typeof props.datetime === "object" ? props.datetime : {};
|
|
@@ -3162,10 +3176,8 @@ const ControlDate = (props) => {
|
|
|
3162
3176
|
...inputProps,
|
|
3163
3177
|
id,
|
|
3164
3178
|
leftSection: icon,
|
|
3165
|
-
|
|
3166
|
-
onChange: (
|
|
3167
|
-
props.input.set(value ? new Date(value).toISOString() : void 0);
|
|
3168
|
-
},
|
|
3179
|
+
value: value ? new Date(value) : null,
|
|
3180
|
+
onChange: (val) => setValue(val ? new Date(val).toISOString() : void 0),
|
|
3169
3181
|
...dateTimePickerProps
|
|
3170
3182
|
});
|
|
3171
3183
|
}
|
|
@@ -3175,10 +3187,8 @@ const ControlDate = (props) => {
|
|
|
3175
3187
|
...inputProps,
|
|
3176
3188
|
id,
|
|
3177
3189
|
leftSection: icon,
|
|
3178
|
-
|
|
3179
|
-
onChange: (
|
|
3180
|
-
props.input.set(value ? new Date(value).toISOString().slice(0, 10) : void 0);
|
|
3181
|
-
},
|
|
3190
|
+
value: value ? new Date(value) : null,
|
|
3191
|
+
onChange: (val) => setValue(val ? new Date(val).toISOString().slice(0, 10) : void 0),
|
|
3182
3192
|
...dateInputProps
|
|
3183
3193
|
});
|
|
3184
3194
|
}
|
|
@@ -3188,10 +3198,8 @@ const ControlDate = (props) => {
|
|
|
3188
3198
|
...inputProps,
|
|
3189
3199
|
id,
|
|
3190
3200
|
leftSection: icon,
|
|
3191
|
-
|
|
3192
|
-
onChange: (event) =>
|
|
3193
|
-
props.input.set(event.currentTarget.value);
|
|
3194
|
-
},
|
|
3201
|
+
value: value ?? "",
|
|
3202
|
+
onChange: (event) => setValue(event.currentTarget.value),
|
|
3195
3203
|
...timeInputProps
|
|
3196
3204
|
});
|
|
3197
3205
|
}
|
|
@@ -3204,14 +3212,10 @@ const ControlDate = (props) => {
|
|
|
3204
3212
|
*
|
|
3205
3213
|
*/
|
|
3206
3214
|
const ControlNumber = (props) => {
|
|
3207
|
-
const
|
|
3208
|
-
const
|
|
3209
|
-
const
|
|
3210
|
-
useEvents({ "form:reset": (event) => {
|
|
3211
|
-
if (event.id === props.input?.form.id && ref.current) setValue(props.input.props.defaultValue);
|
|
3212
|
-
} }, [props.input]);
|
|
3215
|
+
const form = useFormState(props.input);
|
|
3216
|
+
const [value, setValue] = useFieldValue(props.input);
|
|
3217
|
+
const { inputProps, id, icon } = parseInput(props, form);
|
|
3213
3218
|
if (!props.input?.props) return null;
|
|
3214
|
-
const { type, ...inputPropsWithoutType } = props.input.props;
|
|
3215
3219
|
if (props.sliderProps) {
|
|
3216
3220
|
const min = props.sliderProps.min ?? inputProps.minimum ?? 0;
|
|
3217
3221
|
const max = props.sliderProps.max ?? inputProps.maximum ?? 100;
|
|
@@ -3224,34 +3228,25 @@ const ControlNumber = (props) => {
|
|
|
3224
3228
|
},
|
|
3225
3229
|
children: /* @__PURE__ */ jsx(Slider, {
|
|
3226
3230
|
...inputProps,
|
|
3227
|
-
ref,
|
|
3228
3231
|
id,
|
|
3229
|
-
...inputPropsWithoutType,
|
|
3230
3232
|
...props.sliderProps,
|
|
3231
|
-
value,
|
|
3233
|
+
value: value ?? 0,
|
|
3232
3234
|
min,
|
|
3233
3235
|
max,
|
|
3234
3236
|
label: () => value,
|
|
3235
|
-
onChange: (val) =>
|
|
3236
|
-
setValue(val);
|
|
3237
|
-
props.input.set(val);
|
|
3238
|
-
}
|
|
3237
|
+
onChange: (val) => setValue(val)
|
|
3239
3238
|
})
|
|
3240
3239
|
})
|
|
3241
3240
|
});
|
|
3242
3241
|
}
|
|
3243
3242
|
return /* @__PURE__ */ jsx(NumberInput, {
|
|
3244
3243
|
...inputProps,
|
|
3245
|
-
ref,
|
|
3246
3244
|
id,
|
|
3247
3245
|
leftSection: icon,
|
|
3248
|
-
...inputPropsWithoutType,
|
|
3249
3246
|
...props.numberInputProps,
|
|
3250
3247
|
value: value ?? "",
|
|
3251
3248
|
onChange: (val) => {
|
|
3252
|
-
|
|
3253
|
-
setValue(newValue);
|
|
3254
|
-
props.input.set(newValue);
|
|
3249
|
+
setValue(val !== null ? Number(val) : void 0);
|
|
3255
3250
|
}
|
|
3256
3251
|
});
|
|
3257
3252
|
};
|
|
@@ -3334,92 +3329,9 @@ const ControlObject = (props) => {
|
|
|
3334
3329
|
};
|
|
3335
3330
|
|
|
3336
3331
|
//#endregion
|
|
3337
|
-
//#region ../../src/core/form/components/
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
* Generates query strings for parseQueryString syntax.
|
|
3341
|
-
*/
|
|
3342
|
-
const ControlQueryBuilder = ({ schema, value = "", onChange, placeholder = "Enter query or click for assistance...", ...textInputProps }) => {
|
|
3343
|
-
const [helpOpened, setHelpOpened] = useState(false);
|
|
3344
|
-
const [textValue, setTextValue] = useState(value);
|
|
3345
|
-
const inputRef = useRef(null);
|
|
3346
|
-
const fields = schema ? extractSchemaFields(schema) : [];
|
|
3347
|
-
const [error, setError] = useState(null);
|
|
3348
|
-
const isValid = (value) => {
|
|
3349
|
-
try {
|
|
3350
|
-
parseQueryString(value.trim());
|
|
3351
|
-
} catch (e) {
|
|
3352
|
-
setError(e.message);
|
|
3353
|
-
return false;
|
|
3354
|
-
}
|
|
3355
|
-
setError(null);
|
|
3356
|
-
return true;
|
|
3357
|
-
};
|
|
3358
|
-
const handleTextChange = (newValue) => {
|
|
3359
|
-
setTextValue(newValue);
|
|
3360
|
-
if (isValid(newValue)) onChange?.(newValue);
|
|
3361
|
-
};
|
|
3362
|
-
const handleClear = () => {
|
|
3363
|
-
setTextValue("");
|
|
3364
|
-
onChange?.("");
|
|
3365
|
-
isValid("");
|
|
3366
|
-
};
|
|
3367
|
-
const handleInsert = (text) => {
|
|
3368
|
-
const newValue = textValue ? `${textValue}${text} ` : `${text} `;
|
|
3369
|
-
setTextValue(newValue);
|
|
3370
|
-
if (isValid(newValue)) onChange?.(newValue);
|
|
3371
|
-
setTimeout(() => {
|
|
3372
|
-
inputRef.current?.focus();
|
|
3373
|
-
const length = inputRef.current?.value.length || 0;
|
|
3374
|
-
inputRef.current?.setSelectionRange(length, length);
|
|
3375
|
-
}, 0);
|
|
3376
|
-
};
|
|
3377
|
-
useEvents({ "form:change": (event) => {
|
|
3378
|
-
if (event.id === inputRef.current?.form?.id) {
|
|
3379
|
-
if (event.path === textInputProps["data-path"]) setTextValue(event.value ?? "");
|
|
3380
|
-
}
|
|
3381
|
-
} }, []);
|
|
3382
|
-
return /* @__PURE__ */ jsxs(Popover, {
|
|
3383
|
-
width: 800,
|
|
3384
|
-
position: "bottom-start",
|
|
3385
|
-
shadow: "md",
|
|
3386
|
-
opened: helpOpened,
|
|
3387
|
-
onChange: setHelpOpened,
|
|
3388
|
-
closeOnClickOutside: true,
|
|
3389
|
-
closeOnEscape: true,
|
|
3390
|
-
transitionProps: {
|
|
3391
|
-
transition: "fade-up",
|
|
3392
|
-
duration: 200,
|
|
3393
|
-
timingFunction: "ease"
|
|
3394
|
-
},
|
|
3395
|
-
children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx(TextInput, {
|
|
3396
|
-
ref: inputRef,
|
|
3397
|
-
placeholder,
|
|
3398
|
-
value: textValue,
|
|
3399
|
-
onChange: (e) => handleTextChange(e.currentTarget.value),
|
|
3400
|
-
onFocus: () => setHelpOpened(true),
|
|
3401
|
-
leftSection: error ? /* @__PURE__ */ jsx(IconInfoTriangle, { size: 16 }) : /* @__PURE__ */ jsx(IconFilter, { size: 16 }),
|
|
3402
|
-
rightSection: textValue && /* @__PURE__ */ jsx(ActionIcon, {
|
|
3403
|
-
size: "sm",
|
|
3404
|
-
variant: "subtle",
|
|
3405
|
-
color: "gray",
|
|
3406
|
-
onClick: handleClear,
|
|
3407
|
-
children: /* @__PURE__ */ jsx(IconX, { size: 14 })
|
|
3408
|
-
}),
|
|
3409
|
-
...textInputProps
|
|
3410
|
-
}) }), /* @__PURE__ */ jsx(Popover.Dropdown, {
|
|
3411
|
-
bg: "transparent",
|
|
3412
|
-
p: "xs",
|
|
3413
|
-
bd: `1px solid ${ui.colors.border}`,
|
|
3414
|
-
style: { backdropFilter: "blur(20px)" },
|
|
3415
|
-
children: /* @__PURE__ */ jsx(QueryHelp, {
|
|
3416
|
-
fields,
|
|
3417
|
-
onInsert: handleInsert
|
|
3418
|
-
})
|
|
3419
|
-
})]
|
|
3420
|
-
});
|
|
3421
|
-
};
|
|
3422
|
-
function QueryHelp({ fields, onInsert }) {
|
|
3332
|
+
//#region ../../src/core/form/components/ControlQueryBuilderHelp.tsx
|
|
3333
|
+
const ControlQueryBuilderHelp = (props) => {
|
|
3334
|
+
const { fields, onInsert } = props;
|
|
3423
3335
|
return /* @__PURE__ */ jsxs(Flex, {
|
|
3424
3336
|
gap: "md",
|
|
3425
3337
|
align: "flex-start",
|
|
@@ -3580,113 +3492,316 @@ function QueryHelp({ fields, onInsert }) {
|
|
|
3580
3492
|
}, field.path))
|
|
3581
3493
|
})]
|
|
3582
3494
|
})
|
|
3583
|
-
]
|
|
3495
|
+
]
|
|
3496
|
+
});
|
|
3497
|
+
};
|
|
3498
|
+
|
|
3499
|
+
//#endregion
|
|
3500
|
+
//#region ../../src/core/form/components/ControlQueryBuilder.tsx
|
|
3501
|
+
/**
|
|
3502
|
+
* Query builder with text input and help popover.
|
|
3503
|
+
* Generates query strings for parseQueryString syntax.
|
|
3504
|
+
*/
|
|
3505
|
+
const ControlQueryBuilder = (props) => {
|
|
3506
|
+
const { schema, value = "", onChange, placeholder = "Enter query or click for assistance...", ...textInputProps } = props;
|
|
3507
|
+
const [helpOpened, setHelpOpened] = useState(false);
|
|
3508
|
+
const [textValue, setTextValue] = useState(value);
|
|
3509
|
+
const inputRef = useRef(null);
|
|
3510
|
+
const fields = schema ? extractSchemaFields(schema) : [];
|
|
3511
|
+
const [error, setError] = useState(null);
|
|
3512
|
+
const isValid = (value) => {
|
|
3513
|
+
try {
|
|
3514
|
+
parseQueryString(value.trim());
|
|
3515
|
+
} catch (e) {
|
|
3516
|
+
setError(e.message);
|
|
3517
|
+
return false;
|
|
3518
|
+
}
|
|
3519
|
+
setError(null);
|
|
3520
|
+
return true;
|
|
3521
|
+
};
|
|
3522
|
+
const handleTextChange = (newValue) => {
|
|
3523
|
+
setTextValue(newValue);
|
|
3524
|
+
if (isValid(newValue)) onChange?.(newValue);
|
|
3525
|
+
};
|
|
3526
|
+
const handleClear = () => {
|
|
3527
|
+
setTextValue("");
|
|
3528
|
+
onChange?.("");
|
|
3529
|
+
isValid("");
|
|
3530
|
+
};
|
|
3531
|
+
const handleInsert = (text) => {
|
|
3532
|
+
const newValue = textValue ? `${textValue}${text} ` : `${text} `;
|
|
3533
|
+
setTextValue(newValue);
|
|
3534
|
+
if (isValid(newValue)) onChange?.(newValue);
|
|
3535
|
+
setTimeout(() => {
|
|
3536
|
+
inputRef.current?.focus();
|
|
3537
|
+
const length = inputRef.current?.value.length || 0;
|
|
3538
|
+
inputRef.current?.setSelectionRange(length, length);
|
|
3539
|
+
}, 0);
|
|
3540
|
+
};
|
|
3541
|
+
useEvents({ "form:change": (event) => {
|
|
3542
|
+
if (event.id === inputRef.current?.form?.id) {
|
|
3543
|
+
if (event.path === textInputProps["data-path"]) setTextValue(event.value ?? "");
|
|
3544
|
+
}
|
|
3545
|
+
} }, []);
|
|
3546
|
+
return /* @__PURE__ */ jsxs(Popover, {
|
|
3547
|
+
width: 800,
|
|
3548
|
+
position: "bottom-start",
|
|
3549
|
+
shadow: "md",
|
|
3550
|
+
opened: helpOpened,
|
|
3551
|
+
onChange: setHelpOpened,
|
|
3552
|
+
closeOnClickOutside: true,
|
|
3553
|
+
closeOnEscape: true,
|
|
3554
|
+
transitionProps: {
|
|
3555
|
+
transition: "fade-up",
|
|
3556
|
+
duration: 200,
|
|
3557
|
+
timingFunction: "ease"
|
|
3558
|
+
},
|
|
3559
|
+
children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx(TextInput, {
|
|
3560
|
+
ref: inputRef,
|
|
3561
|
+
placeholder,
|
|
3562
|
+
value: textValue,
|
|
3563
|
+
onChange: (e) => handleTextChange(e.currentTarget.value),
|
|
3564
|
+
onFocus: () => setHelpOpened(true),
|
|
3565
|
+
leftSection: error ? /* @__PURE__ */ jsx(IconInfoTriangle, { size: 16 }) : /* @__PURE__ */ jsx(IconFilter, { size: 16 }),
|
|
3566
|
+
rightSection: textValue && /* @__PURE__ */ jsx(ActionIcon, {
|
|
3567
|
+
size: "sm",
|
|
3568
|
+
variant: "subtle",
|
|
3569
|
+
color: "gray",
|
|
3570
|
+
onClick: handleClear,
|
|
3571
|
+
children: /* @__PURE__ */ jsx(IconX, { size: 14 })
|
|
3572
|
+
}),
|
|
3573
|
+
...textInputProps
|
|
3574
|
+
}) }), /* @__PURE__ */ jsx(Popover.Dropdown, {
|
|
3575
|
+
bg: "transparent",
|
|
3576
|
+
p: "xs",
|
|
3577
|
+
bd: `1px solid ${ui.colors.border}`,
|
|
3578
|
+
style: { backdropFilter: "blur(20px)" },
|
|
3579
|
+
children: /* @__PURE__ */ jsx(ControlQueryBuilderHelp, {
|
|
3580
|
+
fields,
|
|
3581
|
+
onInsert: handleInsert
|
|
3582
|
+
})
|
|
3583
|
+
})]
|
|
3584
3584
|
});
|
|
3585
|
-
}
|
|
3585
|
+
};
|
|
3586
3586
|
|
|
3587
3587
|
//#endregion
|
|
3588
3588
|
//#region ../../src/core/form/components/ControlSelect.tsx
|
|
3589
3589
|
/**
|
|
3590
|
-
* ControlSelect component for handling Select, MultiSelect, and TagsInput.
|
|
3590
|
+
* ControlSelect component for handling Select, MultiSelect, Autocomplete, and TagsInput.
|
|
3591
3591
|
*
|
|
3592
3592
|
* Features:
|
|
3593
3593
|
* - Basic Select with enum support
|
|
3594
3594
|
* - MultiSelect for array of enums
|
|
3595
|
-
* -
|
|
3596
|
-
* -
|
|
3597
|
-
* -
|
|
3598
|
-
* -
|
|
3595
|
+
* - Autocomplete for creatable single values
|
|
3596
|
+
* - TagsInput for creatable array values
|
|
3597
|
+
* - Async lazy loading with auto short/long mode detection
|
|
3598
|
+
* - Short mode: client-side filtering with cached data
|
|
3599
|
+
* - Long mode: debounced server search
|
|
3599
3600
|
*
|
|
3600
3601
|
* Automatically detects enum values and array types from schema.
|
|
3601
3602
|
*/
|
|
3602
3603
|
const ControlSelect = (props) => {
|
|
3603
|
-
const
|
|
3604
|
+
const form = useFormState(props.input);
|
|
3605
|
+
const [value, setValue] = useFieldValue(props.input);
|
|
3606
|
+
const { inputProps, id, icon } = parseInput(props, form);
|
|
3604
3607
|
const isArray = props.input.schema && "type" in props.input.schema && props.input.schema.type === "array";
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
const items = props.input.schema.items;
|
|
3608
|
-
if ("enum" in items && Array.isArray(items.enum)) itemsEnum = items.enum;
|
|
3609
|
-
}
|
|
3608
|
+
const isNumeric = props.input.schema && "type" in props.input.schema && (props.input.schema.type === "integer" || props.input.schema.type === "number");
|
|
3609
|
+
const isBoolean = props.input.schema && "type" in props.input.schema && props.input.schema.type === "boolean";
|
|
3610
3610
|
const enumValues = props.input.schema && "enum" in props.input.schema && Array.isArray(props.input.schema.enum) ? props.input.schema.enum : [];
|
|
3611
|
-
const
|
|
3611
|
+
const { data: asyncData, loading, mode, search } = useAsyncLoader(props.loader, props.loaderThreshold ?? 100, props.loaderDebounce ?? 300, props.input.initialValue);
|
|
3612
|
+
const [staticData, setStaticData] = useState([]);
|
|
3613
|
+
const enumKey = JSON.stringify(enumValues);
|
|
3612
3614
|
useEffect(() => {
|
|
3613
|
-
if (!props.input?.props) return;
|
|
3614
|
-
if (
|
|
3615
|
-
|
|
3616
|
-
|
|
3615
|
+
if (!props.input?.props || props.loader) return;
|
|
3616
|
+
if (isBoolean && enumValues.length === 0) setStaticData([{
|
|
3617
|
+
value: "true",
|
|
3618
|
+
label: "True"
|
|
3619
|
+
}, {
|
|
3620
|
+
value: "false",
|
|
3621
|
+
label: "False"
|
|
3622
|
+
}]);
|
|
3623
|
+
else setStaticData(enumValues);
|
|
3624
|
+
}, [
|
|
3625
|
+
props.input,
|
|
3626
|
+
props.loader,
|
|
3627
|
+
enumKey,
|
|
3628
|
+
isBoolean
|
|
3629
|
+
]);
|
|
3630
|
+
const data = props.loader ? asyncData : staticData;
|
|
3617
3631
|
if (!props.input?.props) return null;
|
|
3618
|
-
|
|
3619
|
-
|
|
3632
|
+
/**
|
|
3633
|
+
* Coerce value for numeric schemas — Select values are always strings.
|
|
3634
|
+
*/
|
|
3635
|
+
const coerceValue = (val) => {
|
|
3636
|
+
if (val == null) return val;
|
|
3637
|
+
if (isNumeric) return Number(val);
|
|
3638
|
+
if (isBoolean) return val === "true";
|
|
3639
|
+
return val;
|
|
3640
|
+
};
|
|
3641
|
+
if (props.segmentedProps) {
|
|
3642
|
+
const segmentedControlProps = typeof props.segmentedProps === "object" ? props.segmentedProps : {};
|
|
3643
|
+
const segmentedData = segmentedControlProps.data ?? data.slice(0, 10);
|
|
3620
3644
|
return /* @__PURE__ */ jsx(Input.Wrapper, {
|
|
3621
3645
|
...inputProps,
|
|
3622
|
-
children: /* @__PURE__ */ jsx(Flex, {
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3646
|
+
children: /* @__PURE__ */ jsx(Flex, {
|
|
3647
|
+
my: "calc(var(--mantine-spacing-xs) / 2)",
|
|
3648
|
+
children: /* @__PURE__ */ jsx(SegmentedControl, {
|
|
3649
|
+
disabled: inputProps.disabled,
|
|
3650
|
+
value: value != null ? String(value) : "",
|
|
3651
|
+
...segmentedControlProps,
|
|
3652
|
+
onChange: (val) => {
|
|
3653
|
+
setValue(coerceValue(val));
|
|
3654
|
+
},
|
|
3655
|
+
data: segmentedData
|
|
3656
|
+
})
|
|
3657
|
+
})
|
|
3631
3658
|
});
|
|
3632
3659
|
}
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3660
|
+
const sharedProps = {
|
|
3661
|
+
size: props.size,
|
|
3662
|
+
id,
|
|
3663
|
+
leftSection: loading ? /* @__PURE__ */ jsx(Loader, {
|
|
3664
|
+
color: "gray",
|
|
3665
|
+
size: 10
|
|
3666
|
+
}) : icon,
|
|
3667
|
+
data
|
|
3668
|
+
};
|
|
3669
|
+
const selectableProps = {
|
|
3670
|
+
...sharedProps,
|
|
3671
|
+
searchable: true,
|
|
3672
|
+
rightSection: /* @__PURE__ */ jsx("span", {})
|
|
3673
|
+
};
|
|
3674
|
+
const longModeProps = mode === "long" ? {
|
|
3675
|
+
filter: ({ options }) => options,
|
|
3676
|
+
onSearchChange: search.run
|
|
3677
|
+
} : {};
|
|
3678
|
+
if (props.creatable && (isArray || props.tagsInputProps)) {
|
|
3679
|
+
const tagsInputExtraProps = props.tagsInputProps ?? {};
|
|
3680
|
+
return /* @__PURE__ */ jsx(TagsInput, {
|
|
3636
3681
|
...inputProps,
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3682
|
+
...sharedProps,
|
|
3683
|
+
...longModeProps,
|
|
3684
|
+
value: Array.isArray(value) ? value : [],
|
|
3685
|
+
onChange: (val) => {
|
|
3686
|
+
setValue(val);
|
|
3687
|
+
},
|
|
3688
|
+
...tagsInputExtraProps
|
|
3643
3689
|
});
|
|
3644
3690
|
}
|
|
3645
|
-
if (
|
|
3646
|
-
const
|
|
3647
|
-
return /* @__PURE__ */ jsx(
|
|
3691
|
+
if (props.creatable) {
|
|
3692
|
+
const autocompleteExtraProps = props.autocompleteProps ?? {};
|
|
3693
|
+
return /* @__PURE__ */ jsx(Autocomplete, {
|
|
3648
3694
|
...inputProps,
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
props.input.set(value);
|
|
3695
|
+
...sharedProps,
|
|
3696
|
+
...longModeProps,
|
|
3697
|
+
value: value != null ? String(value) : "",
|
|
3698
|
+
onChange: (val) => {
|
|
3699
|
+
setValue(coerceValue(val));
|
|
3655
3700
|
},
|
|
3656
|
-
...
|
|
3701
|
+
...autocompleteExtraProps
|
|
3657
3702
|
});
|
|
3658
3703
|
}
|
|
3659
|
-
if (isArray
|
|
3660
|
-
const
|
|
3661
|
-
value,
|
|
3662
|
-
label: value
|
|
3663
|
-
})) || [];
|
|
3664
|
-
const multiSelectProps = typeof props.multi === "object" ? props.multi : {};
|
|
3704
|
+
if (isArray || props.multiSelectProps) {
|
|
3705
|
+
const multiSelectExtraProps = typeof props.multiSelectProps === "object" ? props.multiSelectProps : {};
|
|
3665
3706
|
return /* @__PURE__ */ jsx(MultiSelect, {
|
|
3666
3707
|
...inputProps,
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
onChange: (value) => {
|
|
3673
|
-
props.input.set(value);
|
|
3708
|
+
...selectableProps,
|
|
3709
|
+
...longModeProps,
|
|
3710
|
+
value: Array.isArray(value) ? value : [],
|
|
3711
|
+
onChange: (val) => {
|
|
3712
|
+
setValue(val);
|
|
3674
3713
|
},
|
|
3675
|
-
...
|
|
3714
|
+
...multiSelectExtraProps
|
|
3676
3715
|
});
|
|
3677
3716
|
}
|
|
3678
|
-
const
|
|
3717
|
+
const selectExtraProps = typeof props.selectProps === "object" ? props.selectProps : {};
|
|
3718
|
+
if (mode === "static") return /* @__PURE__ */ jsx(Select, {
|
|
3719
|
+
...inputProps,
|
|
3720
|
+
...selectableProps,
|
|
3721
|
+
value: value != null ? String(value) : null,
|
|
3722
|
+
onChange: (val) => {
|
|
3723
|
+
setValue(coerceValue(val));
|
|
3724
|
+
},
|
|
3725
|
+
...selectExtraProps
|
|
3726
|
+
});
|
|
3679
3727
|
return /* @__PURE__ */ jsx(Select, {
|
|
3680
3728
|
...inputProps,
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
...
|
|
3729
|
+
...selectableProps,
|
|
3730
|
+
...longModeProps,
|
|
3731
|
+
value: value != null ? String(value) : null,
|
|
3732
|
+
onChange: (val) => {
|
|
3733
|
+
setValue(coerceValue(val));
|
|
3734
|
+
},
|
|
3735
|
+
...selectExtraProps
|
|
3688
3736
|
});
|
|
3689
3737
|
};
|
|
3738
|
+
/**
|
|
3739
|
+
* Hook for async select data loading with auto short/long mode detection.
|
|
3740
|
+
*/
|
|
3741
|
+
const useAsyncLoader = (loader, threshold, debounceMs, defaultValue) => {
|
|
3742
|
+
const [data, setData] = useState([]);
|
|
3743
|
+
const [loading, setLoading] = useState(false);
|
|
3744
|
+
const [mode, setMode] = useState("static");
|
|
3745
|
+
const cache = useRef(/* @__PURE__ */ new Map());
|
|
3746
|
+
useAction({
|
|
3747
|
+
name: "select:loader:init",
|
|
3748
|
+
runOnInit: true,
|
|
3749
|
+
handler: async () => {
|
|
3750
|
+
if (!loader) {
|
|
3751
|
+
setMode("static");
|
|
3752
|
+
return;
|
|
3753
|
+
}
|
|
3754
|
+
setLoading(true);
|
|
3755
|
+
try {
|
|
3756
|
+
const result = await loader("");
|
|
3757
|
+
const isShort = result.length <= threshold;
|
|
3758
|
+
setMode(isShort ? "short" : "long");
|
|
3759
|
+
cache.current.set("", result);
|
|
3760
|
+
setData(result);
|
|
3761
|
+
if (!isShort && defaultValue != null && String(defaultValue) !== "") {
|
|
3762
|
+
const resolved = await loader("", [String(defaultValue)]);
|
|
3763
|
+
if (resolved.length > 0) setData((prev) => {
|
|
3764
|
+
const existing = new Set(prev.map((d) => typeof d === "string" ? d : d.value));
|
|
3765
|
+
const newItems = resolved.filter((r) => {
|
|
3766
|
+
const val = typeof r === "string" ? r : r.value;
|
|
3767
|
+
return !existing.has(val);
|
|
3768
|
+
});
|
|
3769
|
+
return [...prev, ...newItems];
|
|
3770
|
+
});
|
|
3771
|
+
}
|
|
3772
|
+
} finally {
|
|
3773
|
+
setLoading(false);
|
|
3774
|
+
}
|
|
3775
|
+
}
|
|
3776
|
+
}, [loader, threshold]);
|
|
3777
|
+
return {
|
|
3778
|
+
data,
|
|
3779
|
+
loading,
|
|
3780
|
+
mode,
|
|
3781
|
+
search: useAction({
|
|
3782
|
+
debounce: debounceMs,
|
|
3783
|
+
handler: async (text) => {
|
|
3784
|
+
if (!loader || mode !== "long") return;
|
|
3785
|
+
if (cache.current.has(text)) {
|
|
3786
|
+
setData(cache.current.get(text));
|
|
3787
|
+
return;
|
|
3788
|
+
}
|
|
3789
|
+
setLoading(true);
|
|
3790
|
+
try {
|
|
3791
|
+
const result = await loader(text);
|
|
3792
|
+
cache.current.set(text, result);
|
|
3793
|
+
setData(result);
|
|
3794
|
+
} finally {
|
|
3795
|
+
setLoading(false);
|
|
3796
|
+
}
|
|
3797
|
+
}
|
|
3798
|
+
}, [
|
|
3799
|
+
loader,
|
|
3800
|
+
mode,
|
|
3801
|
+
debounceMs
|
|
3802
|
+
])
|
|
3803
|
+
};
|
|
3804
|
+
};
|
|
3690
3805
|
|
|
3691
3806
|
//#endregion
|
|
3692
3807
|
//#region ../../src/core/form/components/Control.tsx
|
|
@@ -3716,6 +3831,7 @@ const ControlSelect = (props) => {
|
|
|
3716
3831
|
*/
|
|
3717
3832
|
const Control = (_props) => {
|
|
3718
3833
|
const form = useFormState(_props.input, ["error"]);
|
|
3834
|
+
const [value, setValue] = useFieldValue(_props.input);
|
|
3719
3835
|
if (!_props.input?.props) return null;
|
|
3720
3836
|
const { inputProps, id, icon, format, schema } = parseInput(_props, form);
|
|
3721
3837
|
const props = {
|
|
@@ -3723,12 +3839,11 @@ const Control = (_props) => {
|
|
|
3723
3839
|
...schema.$control
|
|
3724
3840
|
};
|
|
3725
3841
|
if (props.query) return /* @__PURE__ */ jsx(ControlQueryBuilder, {
|
|
3726
|
-
...props.input.props,
|
|
3727
3842
|
...inputProps,
|
|
3728
3843
|
schema: props.query,
|
|
3729
|
-
value
|
|
3730
|
-
onChange: (
|
|
3731
|
-
|
|
3844
|
+
value,
|
|
3845
|
+
onChange: (val) => {
|
|
3846
|
+
setValue(val);
|
|
3732
3847
|
}
|
|
3733
3848
|
});
|
|
3734
3849
|
if (props.custom) {
|
|
@@ -3739,9 +3854,9 @@ const Control = (_props) => {
|
|
|
3739
3854
|
flex: 1,
|
|
3740
3855
|
mt: "calc(var(--mantine-spacing-xs) / 2)",
|
|
3741
3856
|
children: /* @__PURE__ */ jsx(Custom, {
|
|
3742
|
-
|
|
3743
|
-
onChange: (
|
|
3744
|
-
|
|
3857
|
+
value,
|
|
3858
|
+
onChange: (val) => {
|
|
3859
|
+
setValue(val);
|
|
3745
3860
|
}
|
|
3746
3861
|
})
|
|
3747
3862
|
})
|
|
@@ -3752,7 +3867,7 @@ const Control = (_props) => {
|
|
|
3752
3867
|
const controlObjectProps = typeof props.object === "object" ? props.object : {};
|
|
3753
3868
|
return /* @__PURE__ */ jsx(ControlObject, {
|
|
3754
3869
|
input: props.input,
|
|
3755
|
-
|
|
3870
|
+
label: props.label,
|
|
3756
3871
|
description: props.description,
|
|
3757
3872
|
...controlObjectProps
|
|
3758
3873
|
});
|
|
@@ -3763,18 +3878,18 @@ const Control = (_props) => {
|
|
|
3763
3878
|
const controlArrayProps = typeof props.array === "object" ? props.array : {};
|
|
3764
3879
|
return /* @__PURE__ */ jsx(ControlArray, {
|
|
3765
3880
|
input: props.input,
|
|
3766
|
-
|
|
3881
|
+
label: props.label,
|
|
3767
3882
|
description: props.description,
|
|
3768
3883
|
...controlArrayProps
|
|
3769
3884
|
});
|
|
3770
3885
|
}
|
|
3771
|
-
if (props.number || props.input.schema && "type" in props.input.schema && (props.input.schema.type === "number" || props.input.schema.type === "integer")) {
|
|
3886
|
+
if (props.number || !props.select && props.input.schema && "type" in props.input.schema && (props.input.schema.type === "number" || props.input.schema.type === "integer")) {
|
|
3772
3887
|
const controlNumberProps = typeof props.number === "object" ? props.number : {};
|
|
3773
3888
|
if (props.slider) controlNumberProps.sliderProps ??= {};
|
|
3774
3889
|
return /* @__PURE__ */ jsx(ControlNumber, {
|
|
3775
3890
|
size: props.size,
|
|
3776
3891
|
input: props.input,
|
|
3777
|
-
|
|
3892
|
+
label: props.label,
|
|
3778
3893
|
description: props.description,
|
|
3779
3894
|
icon,
|
|
3780
3895
|
...controlNumberProps
|
|
@@ -3787,9 +3902,7 @@ const Control = (_props) => {
|
|
|
3787
3902
|
size: props.size,
|
|
3788
3903
|
id,
|
|
3789
3904
|
leftSection: icon,
|
|
3790
|
-
onChange: (file) =>
|
|
3791
|
-
props.input.set(file);
|
|
3792
|
-
},
|
|
3905
|
+
onChange: (file) => setValue(file),
|
|
3793
3906
|
...fileInputProps
|
|
3794
3907
|
});
|
|
3795
3908
|
}
|
|
@@ -3800,17 +3913,18 @@ const Control = (_props) => {
|
|
|
3800
3913
|
size: props.size,
|
|
3801
3914
|
id,
|
|
3802
3915
|
leftSection: icon,
|
|
3803
|
-
|
|
3916
|
+
value: value ?? "",
|
|
3917
|
+
onChange: (val) => setValue(val),
|
|
3804
3918
|
...colorInputProps
|
|
3805
3919
|
});
|
|
3806
3920
|
}
|
|
3807
3921
|
if (props.input.schema && "enum" in props.input.schema && props.input.schema.enum || isArray && !isArrayOfObjects || props.select) {
|
|
3808
3922
|
const opts = typeof props.select === "object" ? props.select : {};
|
|
3809
|
-
if (props.segmented) opts.
|
|
3923
|
+
if (props.segmented) opts.segmentedProps ??= {};
|
|
3810
3924
|
return /* @__PURE__ */ jsx(ControlSelect, {
|
|
3811
3925
|
size: props.size,
|
|
3812
3926
|
input: props.input,
|
|
3813
|
-
|
|
3927
|
+
label: props.label,
|
|
3814
3928
|
description: props.description,
|
|
3815
3929
|
icon,
|
|
3816
3930
|
...opts
|
|
@@ -3824,16 +3938,16 @@ const Control = (_props) => {
|
|
|
3824
3938
|
size: props.size,
|
|
3825
3939
|
id,
|
|
3826
3940
|
color: "blue",
|
|
3827
|
-
|
|
3941
|
+
checked: Boolean(value),
|
|
3828
3942
|
onChange: (event) => {
|
|
3829
|
-
|
|
3943
|
+
setValue(event.currentTarget.checked);
|
|
3830
3944
|
},
|
|
3831
3945
|
...switchProps
|
|
3832
3946
|
});
|
|
3833
3947
|
}
|
|
3834
3948
|
const opts = {
|
|
3835
3949
|
input: props.input,
|
|
3836
|
-
|
|
3950
|
+
selectProps: { data: [{
|
|
3837
3951
|
value: "true",
|
|
3838
3952
|
label: "Yes"
|
|
3839
3953
|
}, {
|
|
@@ -3843,7 +3957,7 @@ const Control = (_props) => {
|
|
|
3843
3957
|
};
|
|
3844
3958
|
return /* @__PURE__ */ jsx(ControlSelect, {
|
|
3845
3959
|
size: props.size,
|
|
3846
|
-
|
|
3960
|
+
label: props.label,
|
|
3847
3961
|
description: props.description,
|
|
3848
3962
|
icon,
|
|
3849
3963
|
...opts
|
|
@@ -3856,7 +3970,8 @@ const Control = (_props) => {
|
|
|
3856
3970
|
size: props.size,
|
|
3857
3971
|
id,
|
|
3858
3972
|
leftSection: icon,
|
|
3859
|
-
|
|
3973
|
+
value: value ?? "",
|
|
3974
|
+
onChange: (ev) => setValue(ev.target.value),
|
|
3860
3975
|
...passwordInputProps
|
|
3861
3976
|
});
|
|
3862
3977
|
}
|
|
@@ -3867,14 +3982,15 @@ const Control = (_props) => {
|
|
|
3867
3982
|
size: props.size,
|
|
3868
3983
|
id,
|
|
3869
3984
|
leftSection: icon,
|
|
3870
|
-
|
|
3985
|
+
value: value ?? "",
|
|
3986
|
+
onChange: (ev) => setValue(ev.target.value),
|
|
3871
3987
|
...textAreaProps
|
|
3872
3988
|
});
|
|
3873
3989
|
}
|
|
3874
3990
|
if (props.date || props.datetime || props.time || format === "date" || format === "date-time" || format === "time") return /* @__PURE__ */ jsx(ControlDate, {
|
|
3875
3991
|
size: props.size,
|
|
3876
3992
|
input: props.input,
|
|
3877
|
-
|
|
3993
|
+
label: props.label,
|
|
3878
3994
|
description: props.description,
|
|
3879
3995
|
icon,
|
|
3880
3996
|
date: props.date,
|
|
@@ -3889,7 +4005,7 @@ const Control = (_props) => {
|
|
|
3889
4005
|
case "uri": return "url";
|
|
3890
4006
|
case "tel":
|
|
3891
4007
|
case "phone": return "tel";
|
|
3892
|
-
default: return;
|
|
4008
|
+
default: return props.input.props.type ?? "text";
|
|
3893
4009
|
}
|
|
3894
4010
|
};
|
|
3895
4011
|
return /* @__PURE__ */ jsx(TextInput, {
|
|
@@ -3898,14 +4014,9 @@ const Control = (_props) => {
|
|
|
3898
4014
|
id,
|
|
3899
4015
|
leftSection: icon,
|
|
3900
4016
|
type: getInputType(),
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
"label",
|
|
3905
|
-
"input",
|
|
3906
|
-
"description",
|
|
3907
|
-
"error"
|
|
3908
|
-
]
|
|
4017
|
+
value: value ?? "",
|
|
4018
|
+
onChange: (ev) => setValue(ev.target.value),
|
|
4019
|
+
...textInputProps
|
|
3909
4020
|
});
|
|
3910
4021
|
};
|
|
3911
4022
|
|
|
@@ -3954,6 +4065,7 @@ const Control = (_props) => {
|
|
|
3954
4065
|
*/
|
|
3955
4066
|
const TypeForm = (props) => {
|
|
3956
4067
|
const { form, columns = 3, children, controlProps, fieldControlProps, skipFormElement = false, skipSubmitButton = false, submitButtonProps, fill = true, size } = props;
|
|
4068
|
+
const { dirty } = useFormState(form, ["dirty"]);
|
|
3957
4069
|
const schema = props.schema || form.options.schema;
|
|
3958
4070
|
if (!schema?.properties) return null;
|
|
3959
4071
|
const supportedFields = Object.keys(schema.properties);
|
|
@@ -4016,10 +4128,12 @@ const TypeForm = (props) => {
|
|
|
4016
4128
|
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
4017
4129
|
variant: "subtle",
|
|
4018
4130
|
type: "reset",
|
|
4131
|
+
disabled: !dirty,
|
|
4019
4132
|
children: "Reset"
|
|
4020
4133
|
}), /* @__PURE__ */ jsx(ActionButton, {
|
|
4021
4134
|
intent: "primary",
|
|
4022
4135
|
form,
|
|
4136
|
+
disabled: !dirty,
|
|
4023
4137
|
...submitButtonProps,
|
|
4024
4138
|
children: submitButtonProps?.children ?? "Submit"
|
|
4025
4139
|
})]
|
|
@@ -4039,16 +4153,27 @@ const TypeForm = (props) => {
|
|
|
4039
4153
|
};
|
|
4040
4154
|
|
|
4041
4155
|
//#endregion
|
|
4042
|
-
//#region ../../src/core/
|
|
4043
|
-
const
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4156
|
+
//#region ../../src/core/json/components/JsonViewerCopyButton.tsx
|
|
4157
|
+
const JsonViewerCopyButton = (props) => {
|
|
4158
|
+
const [copied, setCopied] = useState(false);
|
|
4159
|
+
const handleCopy = useCallback((e) => {
|
|
4160
|
+
e.stopPropagation();
|
|
4161
|
+
navigator.clipboard.writeText(props.value);
|
|
4162
|
+
setCopied(true);
|
|
4163
|
+
setTimeout(() => setCopied(false), 1500);
|
|
4164
|
+
}, [props.value]);
|
|
4165
|
+
return /* @__PURE__ */ jsx(ActionIcon, {
|
|
4166
|
+
size: props.iconSize + 4,
|
|
4167
|
+
variant: "transparent",
|
|
4168
|
+
c: copied ? "green" : "dimmed",
|
|
4169
|
+
onClick: handleCopy,
|
|
4170
|
+
className: "alepha-json-viewer-copy",
|
|
4171
|
+
children: copied ? /* @__PURE__ */ jsx(IconCheck, { size: props.iconSize }) : /* @__PURE__ */ jsx(IconCopy, { size: props.iconSize })
|
|
4172
|
+
});
|
|
4048
4173
|
};
|
|
4049
4174
|
|
|
4050
4175
|
//#endregion
|
|
4051
|
-
//#region ../../src/core/json/components/
|
|
4176
|
+
//#region ../../src/core/json/components/JsonViewerShared.ts
|
|
4052
4177
|
const SIZE_CONFIG = {
|
|
4053
4178
|
xs: {
|
|
4054
4179
|
icon: 14,
|
|
@@ -4097,77 +4222,21 @@ const getValueType = (val) => {
|
|
|
4097
4222
|
if (Array.isArray(val)) return "array";
|
|
4098
4223
|
return typeof val;
|
|
4099
4224
|
};
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
label: key ?? "",
|
|
4106
|
-
nodeValue: data,
|
|
4107
|
-
nodeKey: key,
|
|
4108
|
-
path: currentPath,
|
|
4109
|
-
isArrayItem
|
|
4110
|
-
};
|
|
4111
|
-
const type = getValueType(data);
|
|
4112
|
-
if (type === "object" || type === "array") {
|
|
4113
|
-
const children = (type === "array" ? data.map((v, i) => [String(i), v]) : Object.entries(data)).map(([k, v]) => buildTreeNodes(v, currentPath, k, type === "array", maxDepth)).filter((n) => n !== null);
|
|
4114
|
-
return {
|
|
4115
|
-
value: nodeId,
|
|
4116
|
-
label: key ?? "",
|
|
4117
|
-
nodeValue: data,
|
|
4118
|
-
nodeKey: key,
|
|
4119
|
-
path: currentPath,
|
|
4120
|
-
isArrayItem,
|
|
4121
|
-
children: children.length > 0 ? children : void 0
|
|
4122
|
-
};
|
|
4123
|
-
}
|
|
4124
|
-
return {
|
|
4125
|
-
value: nodeId,
|
|
4126
|
-
label: key ?? "",
|
|
4127
|
-
nodeValue: data,
|
|
4128
|
-
nodeKey: key,
|
|
4129
|
-
path: currentPath,
|
|
4130
|
-
isArrayItem
|
|
4131
|
-
};
|
|
4132
|
-
}
|
|
4133
|
-
function getExpandedIds(nodes, targetDepth, currentDepth = 0) {
|
|
4134
|
-
if (currentDepth >= targetDepth) return [];
|
|
4135
|
-
const ids = [];
|
|
4136
|
-
for (const node of nodes) if (node.children) {
|
|
4137
|
-
ids.push(node.value);
|
|
4138
|
-
ids.push(...getExpandedIds(node.children, targetDepth, currentDepth + 1));
|
|
4139
|
-
}
|
|
4140
|
-
return ids;
|
|
4141
|
-
}
|
|
4142
|
-
const CopyButton = ({ value, iconSize }) => {
|
|
4143
|
-
const [copied, setCopied] = useState(false);
|
|
4144
|
-
const handleCopy = useCallback((e) => {
|
|
4145
|
-
e.stopPropagation();
|
|
4146
|
-
navigator.clipboard.writeText(value);
|
|
4147
|
-
setCopied(true);
|
|
4148
|
-
setTimeout(() => setCopied(false), 1500);
|
|
4149
|
-
}, [value]);
|
|
4150
|
-
return /* @__PURE__ */ jsx(ActionIcon, {
|
|
4151
|
-
size: iconSize + 4,
|
|
4152
|
-
variant: "transparent",
|
|
4153
|
-
c: copied ? "green" : "dimmed",
|
|
4154
|
-
onClick: handleCopy,
|
|
4155
|
-
className: "alepha-json-viewer-copy",
|
|
4156
|
-
children: copied ? /* @__PURE__ */ jsx(IconCheck, { size: iconSize }) : /* @__PURE__ */ jsx(IconCopy, { size: iconSize })
|
|
4157
|
-
});
|
|
4158
|
-
};
|
|
4159
|
-
const RowNode = ({ node, expanded, hasChildren, elementProps, size, config, showQuotes, showCopyButton, renderValue }) => {
|
|
4160
|
-
const { nodeValue, nodeKey, path, isArrayItem, isRoot } = node;
|
|
4225
|
+
|
|
4226
|
+
//#endregion
|
|
4227
|
+
//#region ../../src/core/json/components/JsonViewerRowNode.tsx
|
|
4228
|
+
const JsonViewerRowNode = (props) => {
|
|
4229
|
+
const { nodeValue, nodeKey, path, isArrayItem } = props.node;
|
|
4161
4230
|
const type = getValueType(nodeValue);
|
|
4162
4231
|
const isExpandable = type === "object" || type === "array";
|
|
4163
4232
|
const getPreview = () => {
|
|
4164
4233
|
if (!isExpandable) return null;
|
|
4165
4234
|
const count = (type === "array" ? nodeValue : Object.keys(nodeValue)).length;
|
|
4166
4235
|
const label = type === "array" ? "item" : "key";
|
|
4167
|
-
if (!expanded) return /* @__PURE__ */ jsx(Text, {
|
|
4236
|
+
if (!props.expanded) return /* @__PURE__ */ jsx(Text, {
|
|
4168
4237
|
fs: "italic",
|
|
4169
4238
|
component: "span",
|
|
4170
|
-
size,
|
|
4239
|
+
size: props.size,
|
|
4171
4240
|
style: STYLES.preview,
|
|
4172
4241
|
children: count === 0 ? type === "array" ? "[]" : "{}" : type === "array" ? `[ ${count} ${count === 1 ? label : `${label}s`} ]` : `{ ${count} ${count === 1 ? label : `${label}s`} }`
|
|
4173
4242
|
});
|
|
@@ -4177,25 +4246,25 @@ const RowNode = ({ node, expanded, hasChildren, elementProps, size, config, show
|
|
|
4177
4246
|
return /* @__PURE__ */ jsxs(Flex, {
|
|
4178
4247
|
gap: 6,
|
|
4179
4248
|
wrap: "nowrap",
|
|
4180
|
-
...elementProps,
|
|
4181
|
-
className: `alepha-json-viewer-row ${elementProps.className || ""}`,
|
|
4249
|
+
...props.elementProps,
|
|
4250
|
+
className: `alepha-json-viewer-row ${props.elementProps.className || ""}`,
|
|
4182
4251
|
children: [
|
|
4183
|
-
hasChildren ? expanded ? /* @__PURE__ */ jsx(IconChevronDown, {
|
|
4184
|
-
size: config.icon,
|
|
4252
|
+
props.hasChildren ? props.expanded ? /* @__PURE__ */ jsx(IconChevronDown, {
|
|
4253
|
+
size: props.config.icon,
|
|
4185
4254
|
style: STYLES.chevron
|
|
4186
4255
|
}) : /* @__PURE__ */ jsx(IconChevronRight, {
|
|
4187
|
-
size: config.icon,
|
|
4256
|
+
size: props.config.icon,
|
|
4188
4257
|
style: STYLES.chevron
|
|
4189
4258
|
}) : /* @__PURE__ */ jsx("span", { style: {
|
|
4190
|
-
width: config.icon,
|
|
4259
|
+
width: props.config.icon,
|
|
4191
4260
|
flexShrink: 0
|
|
4192
4261
|
} }),
|
|
4193
4262
|
nodeKey !== void 0 && !isArrayItem && /* @__PURE__ */ jsxs(Text, {
|
|
4194
4263
|
component: "span",
|
|
4195
|
-
size,
|
|
4264
|
+
size: props.size,
|
|
4196
4265
|
children: [/* @__PURE__ */ jsx("span", {
|
|
4197
4266
|
style: STYLES.key,
|
|
4198
|
-
children: showQuotes ? `"${nodeKey}"` : nodeKey
|
|
4267
|
+
children: props.showQuotes ? `"${nodeKey}"` : nodeKey
|
|
4199
4268
|
}), /* @__PURE__ */ jsx("span", {
|
|
4200
4269
|
style: STYLES.colon,
|
|
4201
4270
|
children: ":"
|
|
@@ -4203,7 +4272,7 @@ const RowNode = ({ node, expanded, hasChildren, elementProps, size, config, show
|
|
|
4203
4272
|
}),
|
|
4204
4273
|
nodeKey !== void 0 && isArrayItem && /* @__PURE__ */ jsxs(Text, {
|
|
4205
4274
|
component: "span",
|
|
4206
|
-
size,
|
|
4275
|
+
size: props.size,
|
|
4207
4276
|
children: [/* @__PURE__ */ jsx("span", {
|
|
4208
4277
|
style: STYLES.key,
|
|
4209
4278
|
children: nodeKey
|
|
@@ -4212,25 +4281,29 @@ const RowNode = ({ node, expanded, hasChildren, elementProps, size, config, show
|
|
|
4212
4281
|
children: ":"
|
|
4213
4282
|
})]
|
|
4214
4283
|
}),
|
|
4215
|
-
hasChildren ? getPreview() : isExpandable ? type === "array" ? /* @__PURE__ */ jsx(Text, {
|
|
4284
|
+
props.hasChildren ? getPreview() : isExpandable ? type === "array" ? /* @__PURE__ */ jsx(Text, {
|
|
4216
4285
|
component: "span",
|
|
4217
|
-
size,
|
|
4286
|
+
size: props.size,
|
|
4218
4287
|
style: STYLES.preview,
|
|
4219
4288
|
children: "[]"
|
|
4220
4289
|
}) : /* @__PURE__ */ jsx(Text, {
|
|
4221
4290
|
component: "span",
|
|
4222
|
-
size,
|
|
4291
|
+
size: props.size,
|
|
4223
4292
|
style: STYLES.preview,
|
|
4224
4293
|
children: "{}"
|
|
4225
|
-
}) : renderValue(nodeValue, nodeKey, path),
|
|
4226
|
-
showCopyButton && /* @__PURE__ */ jsx(
|
|
4294
|
+
}) : props.renderValue(nodeValue, nodeKey, path),
|
|
4295
|
+
props.showCopyButton && /* @__PURE__ */ jsx(JsonViewerCopyButton, {
|
|
4227
4296
|
value: getCopyValue(),
|
|
4228
|
-
iconSize: config.icon
|
|
4297
|
+
iconSize: props.config.icon
|
|
4229
4298
|
})
|
|
4230
4299
|
]
|
|
4231
4300
|
});
|
|
4232
4301
|
};
|
|
4233
|
-
|
|
4302
|
+
|
|
4303
|
+
//#endregion
|
|
4304
|
+
//#region ../../src/core/json/components/JsonViewer.tsx
|
|
4305
|
+
const JsonViewer = (props) => {
|
|
4306
|
+
const { data, defaultExpandedDepth = 2, maxDepth = 10, size = "sm", showQuotes = false, showCopyButton = true, formatValue } = props;
|
|
4234
4307
|
const config = SIZE_CONFIG[size] || SIZE_CONFIG.sm;
|
|
4235
4308
|
const treeData = useMemo(() => {
|
|
4236
4309
|
const type = getValueType(data);
|
|
@@ -4310,7 +4383,7 @@ const JsonViewer = ({ data, defaultExpandedDepth = 2, maxDepth = 10, size = "sm"
|
|
|
4310
4383
|
size
|
|
4311
4384
|
]);
|
|
4312
4385
|
const renderNode = useCallback(({ node, expanded, hasChildren, elementProps }) => {
|
|
4313
|
-
return /* @__PURE__ */ jsx(
|
|
4386
|
+
return /* @__PURE__ */ jsx(JsonViewerRowNode, {
|
|
4314
4387
|
node,
|
|
4315
4388
|
expanded,
|
|
4316
4389
|
hasChildren,
|
|
@@ -4342,6 +4415,54 @@ const JsonViewer = ({ data, defaultExpandedDepth = 2, maxDepth = 10, size = "sm"
|
|
|
4342
4415
|
styles: { root: STYLES.root }
|
|
4343
4416
|
});
|
|
4344
4417
|
};
|
|
4418
|
+
/**
|
|
4419
|
+
* Convert JSON to tree data structure.
|
|
4420
|
+
*/
|
|
4421
|
+
const buildTreeNodes = (data, path = [], key, isArrayItem = false, maxDepth = 10) => {
|
|
4422
|
+
const currentPath = key !== void 0 ? [...path, key] : path;
|
|
4423
|
+
const nodeId = currentPath.length > 0 ? currentPath.join(".") : "root";
|
|
4424
|
+
if (currentPath.length > maxDepth) return {
|
|
4425
|
+
value: nodeId,
|
|
4426
|
+
label: key ?? "",
|
|
4427
|
+
nodeValue: data,
|
|
4428
|
+
nodeKey: key,
|
|
4429
|
+
path: currentPath,
|
|
4430
|
+
isArrayItem
|
|
4431
|
+
};
|
|
4432
|
+
const type = getValueType(data);
|
|
4433
|
+
if (type === "object" || type === "array") {
|
|
4434
|
+
const children = (type === "array" ? data.map((v, i) => [String(i), v]) : Object.entries(data)).map(([k, v]) => buildTreeNodes(v, currentPath, k, type === "array", maxDepth)).filter((n) => n !== null);
|
|
4435
|
+
return {
|
|
4436
|
+
value: nodeId,
|
|
4437
|
+
label: key ?? "",
|
|
4438
|
+
nodeValue: data,
|
|
4439
|
+
nodeKey: key,
|
|
4440
|
+
path: currentPath,
|
|
4441
|
+
isArrayItem,
|
|
4442
|
+
children: children.length > 0 ? children : void 0
|
|
4443
|
+
};
|
|
4444
|
+
}
|
|
4445
|
+
return {
|
|
4446
|
+
value: nodeId,
|
|
4447
|
+
label: key ?? "",
|
|
4448
|
+
nodeValue: data,
|
|
4449
|
+
nodeKey: key,
|
|
4450
|
+
path: currentPath,
|
|
4451
|
+
isArrayItem
|
|
4452
|
+
};
|
|
4453
|
+
};
|
|
4454
|
+
/**
|
|
4455
|
+
* Get all expandable node IDs up to a certain depth.
|
|
4456
|
+
*/
|
|
4457
|
+
const getExpandedIds = (nodes, targetDepth, currentDepth = 0) => {
|
|
4458
|
+
if (currentDepth >= targetDepth) return [];
|
|
4459
|
+
const ids = [];
|
|
4460
|
+
for (const node of nodes) if (node.children) {
|
|
4461
|
+
ids.push(node.value);
|
|
4462
|
+
ids.push(...getExpandedIds(node.children, targetDepth, currentDepth + 1));
|
|
4463
|
+
}
|
|
4464
|
+
return ids;
|
|
4465
|
+
};
|
|
4345
4466
|
|
|
4346
4467
|
//#endregion
|
|
4347
4468
|
//#region ../../src/core/table/interfaces/types.ts
|
|
@@ -4349,7 +4470,8 @@ const DEFAULT_MAX_VISIBLE_COLUMNS = 8;
|
|
|
4349
4470
|
|
|
4350
4471
|
//#endregion
|
|
4351
4472
|
//#region ../../src/core/table/components/DataTableFilters.tsx
|
|
4352
|
-
const DataTableFilters = (
|
|
4473
|
+
const DataTableFilters = (props) => {
|
|
4474
|
+
const { schema, form, typeFormProps, filterVisibility } = props;
|
|
4353
4475
|
const visibleSchema = useMemo(() => {
|
|
4354
4476
|
const visibleKeys = Object.keys(schema.properties).filter((key) => filterVisibility[key] !== false);
|
|
4355
4477
|
if (visibleKeys.length === 0) return null;
|
|
@@ -4360,14 +4482,14 @@ const DataTableFilters = ({ schema, form, typeFormProps, filterVisibility }) =>
|
|
|
4360
4482
|
return t.object(visibleProps);
|
|
4361
4483
|
}, [schema, filterVisibility]);
|
|
4362
4484
|
if (!visibleSchema) return null;
|
|
4363
|
-
return /* @__PURE__ */ jsx(Flex, {
|
|
4364
|
-
|
|
4485
|
+
return /* @__PURE__ */ jsx(Flex$1, {
|
|
4486
|
+
surface: true,
|
|
4487
|
+
flex: 1,
|
|
4488
|
+
mt: -4,
|
|
4365
4489
|
p: "xs",
|
|
4366
4490
|
m: "xs",
|
|
4367
4491
|
bdrs: "md",
|
|
4368
|
-
bg: ui.colors.surface,
|
|
4369
4492
|
children: /* @__PURE__ */ jsx(TypeForm, {
|
|
4370
|
-
size: "xs",
|
|
4371
4493
|
...typeFormProps,
|
|
4372
4494
|
skipSubmitButton: true,
|
|
4373
4495
|
fill: true,
|
|
@@ -4378,7 +4500,7 @@ const DataTableFilters = ({ schema, form, typeFormProps, filterVisibility }) =>
|
|
|
4378
4500
|
sm: 2,
|
|
4379
4501
|
md: 3,
|
|
4380
4502
|
lg: 4,
|
|
4381
|
-
xl:
|
|
4503
|
+
xl: 5
|
|
4382
4504
|
}
|
|
4383
4505
|
})
|
|
4384
4506
|
});
|
|
@@ -4386,9 +4508,10 @@ const DataTableFilters = ({ schema, form, typeFormProps, filterVisibility }) =>
|
|
|
4386
4508
|
|
|
4387
4509
|
//#endregion
|
|
4388
4510
|
//#region ../../src/core/table/components/DataTablePagination.tsx
|
|
4389
|
-
const DataTablePagination = ({ page, size, totalPages, totalElements, offset, numberOfElements, onPageChange, onSizeChange }) => {
|
|
4511
|
+
const DataTablePagination = ({ page, size, totalPages, totalElements, isFirst, isLast, offset, numberOfElements, onPageChange, onSizeChange }) => {
|
|
4390
4512
|
const from = numberOfElements > 0 ? offset + 1 : 0;
|
|
4391
4513
|
const to = offset + numberOfElements;
|
|
4514
|
+
const hasTotal = totalPages != null;
|
|
4392
4515
|
return /* @__PURE__ */ jsxs(Flex$1, {
|
|
4393
4516
|
align: "center",
|
|
4394
4517
|
justify: "space-between",
|
|
@@ -4436,8 +4559,9 @@ const DataTablePagination = ({ page, size, totalPages, totalElements, offset, nu
|
|
|
4436
4559
|
]
|
|
4437
4560
|
}) }), /* @__PURE__ */ jsx(Flex$1, { children: /* @__PURE__ */ jsx(Pagination, {
|
|
4438
4561
|
size: "sm",
|
|
4439
|
-
withEdges:
|
|
4440
|
-
|
|
4562
|
+
withEdges: hasTotal,
|
|
4563
|
+
withPages: hasTotal,
|
|
4564
|
+
total: hasTotal ? totalPages : isLast !== false ? page : page + 1,
|
|
4441
4565
|
value: page,
|
|
4442
4566
|
onChange: onPageChange
|
|
4443
4567
|
}) })]
|
|
@@ -4488,7 +4612,7 @@ const ColumnPicker = ({ columns, visibility, onVisibilityChange }) => {
|
|
|
4488
4612
|
timingFunction: "ease"
|
|
4489
4613
|
},
|
|
4490
4614
|
children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(ActionButton, {
|
|
4491
|
-
variant: "
|
|
4615
|
+
variant: "minimal",
|
|
4492
4616
|
icon: IconColumns,
|
|
4493
4617
|
onClick: () => setOpened((o) => !o)
|
|
4494
4618
|
}) }) }), /* @__PURE__ */ jsx(Popover.Dropdown, {
|
|
@@ -4518,12 +4642,12 @@ const ColumnPicker = ({ columns, visibility, onVisibilityChange }) => {
|
|
|
4518
4642
|
gap: 4,
|
|
4519
4643
|
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
4520
4644
|
size: "compact-xs",
|
|
4521
|
-
variant: "
|
|
4645
|
+
variant: "minimal",
|
|
4522
4646
|
onClick: handleShowAll,
|
|
4523
4647
|
children: "All"
|
|
4524
4648
|
}), /* @__PURE__ */ jsx(ActionButton, {
|
|
4525
4649
|
size: "compact-xs",
|
|
4526
|
-
variant: "
|
|
4650
|
+
variant: "minimal",
|
|
4527
4651
|
onClick: handleDefault,
|
|
4528
4652
|
children: "Default"
|
|
4529
4653
|
})]
|
|
@@ -4589,7 +4713,7 @@ const FilterPicker = ({ schema, visibility, onVisibilityChange }) => {
|
|
|
4589
4713
|
timingFunction: "ease"
|
|
4590
4714
|
},
|
|
4591
4715
|
children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(ActionButton, {
|
|
4592
|
-
variant: "
|
|
4716
|
+
variant: "minimal",
|
|
4593
4717
|
icon: IconFilter,
|
|
4594
4718
|
onClick: () => setOpened((o) => !o)
|
|
4595
4719
|
}) }) }), /* @__PURE__ */ jsx(Popover.Dropdown, {
|
|
@@ -4619,12 +4743,12 @@ const FilterPicker = ({ schema, visibility, onVisibilityChange }) => {
|
|
|
4619
4743
|
gap: 4,
|
|
4620
4744
|
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
4621
4745
|
size: "compact-xs",
|
|
4622
|
-
variant: "
|
|
4746
|
+
variant: "minimal",
|
|
4623
4747
|
onClick: handleShowAll,
|
|
4624
4748
|
children: "All"
|
|
4625
4749
|
}), /* @__PURE__ */ jsx(ActionButton, {
|
|
4626
4750
|
size: "compact-xs",
|
|
4627
|
-
variant: "
|
|
4751
|
+
variant: "minimal",
|
|
4628
4752
|
onClick: handleHideAll,
|
|
4629
4753
|
children: "None"
|
|
4630
4754
|
})]
|
|
@@ -4718,7 +4842,7 @@ const DataTableToolbar = ({ columns, filters, columnVisibility, filterVisibility
|
|
|
4718
4842
|
onVisibilityChange: onColumnVisibilityChange
|
|
4719
4843
|
}),
|
|
4720
4844
|
withExport && /* @__PURE__ */ jsx(ActionButton, {
|
|
4721
|
-
variant: "
|
|
4845
|
+
variant: "minimal",
|
|
4722
4846
|
icon: IconDownload,
|
|
4723
4847
|
menu: { items: [{
|
|
4724
4848
|
label: "Export as CSV",
|
|
@@ -4741,7 +4865,7 @@ const DataTableToolbar = ({ columns, filters, columnVisibility, filterVisibility
|
|
|
4741
4865
|
children: [selectedItems.length, " selected"]
|
|
4742
4866
|
}),
|
|
4743
4867
|
/* @__PURE__ */ jsx(ActionButton, {
|
|
4744
|
-
variant: "
|
|
4868
|
+
variant: "minimal",
|
|
4745
4869
|
size: "compact-sm",
|
|
4746
4870
|
icon: IconX,
|
|
4747
4871
|
onClick: onClearSelection,
|
|
@@ -4765,7 +4889,7 @@ const DataTableToolbar = ({ columns, filters, columnVisibility, filterVisibility
|
|
|
4765
4889
|
...props,
|
|
4766
4890
|
children: props.label
|
|
4767
4891
|
}, index) : props), /* @__PURE__ */ jsx(ActionButton, {
|
|
4768
|
-
variant: "
|
|
4892
|
+
variant: "minimal",
|
|
4769
4893
|
icon: IconRefresh,
|
|
4770
4894
|
onClick: onRefresh
|
|
4771
4895
|
})]
|
|
@@ -4874,12 +4998,16 @@ const FIT_STYLE = {
|
|
|
4874
4998
|
};
|
|
4875
4999
|
const DataTable = (props) => {
|
|
4876
5000
|
const [items, setItems] = useState(typeof props.items === "function" ? { content: [] } : props.items);
|
|
4877
|
-
const
|
|
5001
|
+
const itemsRef = useRef(items);
|
|
5002
|
+
const [loaded, setLoaded] = useState(typeof props.items !== "function" || !props.submitOnInit);
|
|
5003
|
+
const defaultSize = props.defaultSize || (props.infinityScroll ? 100 : 10);
|
|
4878
5004
|
const [page, setPage] = useState(1);
|
|
4879
5005
|
const [size, setSize] = useState(String(defaultSize));
|
|
4880
5006
|
const [currentPage, setCurrentPage] = useState(0);
|
|
4881
5007
|
const alepha = useInject(Alepha);
|
|
5008
|
+
itemsRef.current = items;
|
|
4882
5009
|
const sentinelRef = useRef(null);
|
|
5010
|
+
const debounceRef = useRef(null);
|
|
4883
5011
|
const [columnVisibility, setColumnVisibility] = useState(() => {
|
|
4884
5012
|
const entries = Object.entries(props.columns);
|
|
4885
5013
|
let visibleCount = 0;
|
|
@@ -4952,13 +5080,14 @@ const DataTable = (props) => {
|
|
|
4952
5080
|
}),
|
|
4953
5081
|
handler: async (values) => {
|
|
4954
5082
|
if (typeof props.items === "function") {
|
|
4955
|
-
const response = await props.items(values, { items:
|
|
5083
|
+
const response = await props.items(values, { items: itemsRef.current.content });
|
|
4956
5084
|
if (props.infinityScroll && values.page > 0) setItems((prev) => ({
|
|
4957
5085
|
...response,
|
|
4958
5086
|
content: [...prev.content, ...response.content]
|
|
4959
5087
|
}));
|
|
4960
5088
|
else setItems(response);
|
|
4961
5089
|
setCurrentPage(values.page);
|
|
5090
|
+
if (!loaded) setLoaded(true);
|
|
4962
5091
|
}
|
|
4963
5092
|
},
|
|
4964
5093
|
onReset: async () => {
|
|
@@ -4978,9 +5107,23 @@ const DataTable = (props) => {
|
|
|
4978
5107
|
return;
|
|
4979
5108
|
}
|
|
4980
5109
|
props.onFilterChange?.(key, value, form);
|
|
5110
|
+
if (props.skipSubmitOnChange) return;
|
|
5111
|
+
form.input.page.set(0);
|
|
5112
|
+
const delay = props.debounce ?? 300;
|
|
5113
|
+
if (delay > 0) {
|
|
5114
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
5115
|
+
debounceRef.current = setTimeout(() => {
|
|
5116
|
+
form.submit();
|
|
5117
|
+
}, delay);
|
|
5118
|
+
} else await form.submit();
|
|
4981
5119
|
}
|
|
4982
|
-
}, [
|
|
5120
|
+
}, []);
|
|
4983
5121
|
const dt = useInject(DateTimeProvider);
|
|
5122
|
+
useEffect(() => {
|
|
5123
|
+
return () => {
|
|
5124
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
5125
|
+
};
|
|
5126
|
+
}, []);
|
|
4984
5127
|
useEffect(() => {
|
|
4985
5128
|
if (props.submitOnInit) form.submit();
|
|
4986
5129
|
if (props.submitEvery) {
|
|
@@ -5045,9 +5188,9 @@ const DataTable = (props) => {
|
|
|
5045
5188
|
}), col.sortable && /* @__PURE__ */ jsxs(Flex$1, {
|
|
5046
5189
|
c: "dimmed",
|
|
5047
5190
|
children: [
|
|
5048
|
-
sortDir === "asc" && /* @__PURE__ */ jsx(IconArrowUp, { size: ui.sizes.icon.
|
|
5049
|
-
sortDir === "desc" && /* @__PURE__ */ jsx(IconArrowDown, { size: ui.sizes.icon.
|
|
5050
|
-
sortDir === null && /* @__PURE__ */ jsx(IconArrowsSort, { size: ui.sizes.icon.
|
|
5191
|
+
sortDir === "asc" && /* @__PURE__ */ jsx(IconArrowUp, { size: ui.sizes.icon.xs }),
|
|
5192
|
+
sortDir === "desc" && /* @__PURE__ */ jsx(IconArrowDown, { size: ui.sizes.icon.xs }),
|
|
5193
|
+
sortDir === null && /* @__PURE__ */ jsx(IconArrowsSort, { size: ui.sizes.icon.xs })
|
|
5051
5194
|
]
|
|
5052
5195
|
})]
|
|
5053
5196
|
})
|
|
@@ -5107,9 +5250,15 @@ const DataTable = (props) => {
|
|
|
5107
5250
|
form,
|
|
5108
5251
|
alepha
|
|
5109
5252
|
};
|
|
5253
|
+
const content = col.value?.(item, ctx);
|
|
5110
5254
|
return /* @__PURE__ */ jsx(Table.Td, {
|
|
5111
5255
|
style: col.fit ? FIT_STYLE : void 0,
|
|
5112
|
-
children: col.
|
|
5256
|
+
children: col.action ? /* @__PURE__ */ jsx(ActionButton, {
|
|
5257
|
+
td: "inherit",
|
|
5258
|
+
unstyled: true,
|
|
5259
|
+
...col.action(item),
|
|
5260
|
+
children: content
|
|
5261
|
+
}) : content
|
|
5113
5262
|
}, key);
|
|
5114
5263
|
}),
|
|
5115
5264
|
props.rowActions && (() => {
|
|
@@ -5126,7 +5275,7 @@ const DataTable = (props) => {
|
|
|
5126
5275
|
style: FIT_STYLE,
|
|
5127
5276
|
onClick: (e) => e.stopPropagation(),
|
|
5128
5277
|
children: /* @__PURE__ */ jsx(ActionButton, {
|
|
5129
|
-
variant: "
|
|
5278
|
+
variant: "minimal",
|
|
5130
5279
|
size: "xs",
|
|
5131
5280
|
icon: IconDotsVertical,
|
|
5132
5281
|
menu: { items: actions.map((action) => {
|
|
@@ -5134,7 +5283,10 @@ const DataTable = (props) => {
|
|
|
5134
5283
|
return {
|
|
5135
5284
|
label: action.label ?? (typeof action.tooltip === "string" ? action.tooltip : void 0),
|
|
5136
5285
|
icon: Icon && isComponentType(Icon) ? /* @__PURE__ */ jsx(Icon, { size: 14 }) : Icon,
|
|
5137
|
-
onClick: action.onClick
|
|
5286
|
+
onClick: action.onClick ? async () => {
|
|
5287
|
+
await action.onClick();
|
|
5288
|
+
if (!action.skipRefresh) await form.submit();
|
|
5289
|
+
} : void 0,
|
|
5138
5290
|
color: action.color
|
|
5139
5291
|
};
|
|
5140
5292
|
}) }
|
|
@@ -5196,19 +5348,26 @@ const DataTable = (props) => {
|
|
|
5196
5348
|
bordered: true,
|
|
5197
5349
|
elevated: true,
|
|
5198
5350
|
shadowed: "xs",
|
|
5351
|
+
flex: 1,
|
|
5352
|
+
style: { minHeight: 0 },
|
|
5199
5353
|
children: [
|
|
5200
5354
|
/* @__PURE__ */ jsx(Flex$1, {
|
|
5201
5355
|
className: "overflow-auto",
|
|
5356
|
+
flex: 1,
|
|
5357
|
+
style: { minHeight: 0 },
|
|
5358
|
+
col: true,
|
|
5202
5359
|
children: /* @__PURE__ */ jsxs(Table, {
|
|
5203
5360
|
"aria-label": "Data table",
|
|
5204
5361
|
withRowBorders: true,
|
|
5205
5362
|
highlightOnHover: true,
|
|
5206
5363
|
...props.tableProps,
|
|
5207
5364
|
children: [/* @__PURE__ */ jsx(Table.Thead, {
|
|
5365
|
+
bdrs: "md",
|
|
5208
5366
|
style: {
|
|
5209
5367
|
position: "sticky",
|
|
5210
5368
|
top: 0,
|
|
5211
|
-
zIndex: 1
|
|
5369
|
+
zIndex: 1,
|
|
5370
|
+
backgroundColor: "var(--alepha-elevated)"
|
|
5212
5371
|
},
|
|
5213
5372
|
children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
|
|
5214
5373
|
panelConfig && /* @__PURE__ */ jsx(Table.Th, { style: { width: 36 } }),
|
|
@@ -5216,30 +5375,39 @@ const DataTable = (props) => {
|
|
|
5216
5375
|
head,
|
|
5217
5376
|
props.rowActions && /* @__PURE__ */ jsx(Table.Th, { style: FIT_STYLE })
|
|
5218
5377
|
] })
|
|
5219
|
-
}), /* @__PURE__ */
|
|
5220
|
-
|
|
5221
|
-
|
|
5222
|
-
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
|
|
5378
|
+
}), /* @__PURE__ */ jsx(Table.Tbody, { children: !loaded || form.submitting ? /* @__PURE__ */ jsx(Table.Tr, { children: /* @__PURE__ */ jsx(Table.Td, {
|
|
5379
|
+
colSpan: totalColumns || 1,
|
|
5380
|
+
py: "sm",
|
|
5381
|
+
children: /* @__PURE__ */ jsx(Flex$1, {
|
|
5382
|
+
justify: "center",
|
|
5383
|
+
p: "md",
|
|
5384
|
+
children: /* @__PURE__ */ jsx(Loader, {
|
|
5385
|
+
size: "sm",
|
|
5386
|
+
type: "dots"
|
|
5387
|
+
})
|
|
5388
|
+
})
|
|
5389
|
+
}) }) : rows.length === 0 ? /* @__PURE__ */ jsx(Table.Tr, { children: /* @__PURE__ */ jsx(Table.Td, {
|
|
5390
|
+
colSpan: totalColumns || 1,
|
|
5391
|
+
py: "xl",
|
|
5392
|
+
children: /* @__PURE__ */ jsx(Flex$1, {
|
|
5393
|
+
justify: "center",
|
|
5228
5394
|
children: /* @__PURE__ */ jsx(Text$1, {
|
|
5229
5395
|
c: "dimmed",
|
|
5230
5396
|
size: "sm",
|
|
5231
|
-
children:
|
|
5397
|
+
children: props.emptyLabel ?? "No results"
|
|
5232
5398
|
})
|
|
5233
|
-
})
|
|
5234
|
-
})]
|
|
5399
|
+
})
|
|
5400
|
+
}) }) : rows })]
|
|
5235
5401
|
})
|
|
5236
5402
|
}),
|
|
5237
5403
|
props.infinityScroll && /* @__PURE__ */ jsx("div", { ref: sentinelRef }),
|
|
5238
5404
|
!props.infinityScroll && /* @__PURE__ */ jsx(DataTablePagination, {
|
|
5239
5405
|
page,
|
|
5240
5406
|
size,
|
|
5241
|
-
totalPages: items.page?.totalPages
|
|
5407
|
+
totalPages: items.page?.totalPages,
|
|
5242
5408
|
totalElements: items.page?.totalElements,
|
|
5409
|
+
isFirst: items.page?.isFirst,
|
|
5410
|
+
isLast: items.page?.isLast,
|
|
5243
5411
|
offset: items.page?.offset ?? 0,
|
|
5244
5412
|
numberOfElements: items.content.length,
|
|
5245
5413
|
onPageChange: (value) => {
|
|
@@ -5357,8 +5525,8 @@ const OPERATOR_INFO = {
|
|
|
5357
5525
|
* Get the default icon for an input based on its type, format, or name.
|
|
5358
5526
|
*/
|
|
5359
5527
|
const getDefaultIcon = (params) => {
|
|
5360
|
-
const { type, format, name, isEnum, isArray, size = "
|
|
5361
|
-
const iconSize = ui.sizes.icon[size];
|
|
5528
|
+
const { type, format, name, isEnum, isArray, size = "xs" } = params;
|
|
5529
|
+
const iconSize = ui.sizes.icon[size] - 4;
|
|
5362
5530
|
if (format) switch (format) {
|
|
5363
5531
|
case "email": return /* @__PURE__ */ jsx(IconMail, { size: iconSize });
|
|
5364
5532
|
case "url":
|
|
@@ -5471,5 +5639,5 @@ const AlephaUI = $module({
|
|
|
5471
5639
|
});
|
|
5472
5640
|
|
|
5473
5641
|
//#endregion
|
|
5474
|
-
export { AlephaMantineProvider as _, TypeForm as a,
|
|
5475
|
-
//# sourceMappingURL=core-
|
|
5642
|
+
export { AlephaMantineProvider as _, TypeForm as a, Sidebar as c, Heading as d, Flex$1 as f, ui as g, ActionButton as h, JsonViewer as i, Text$1 as l, useDialog as m, capitalize as n, Control as o, ToggleSidebarButton as p, DataTable as r, DashboardShell as s, AlephaUI as t, Breadcrumb as u, useToast as v };
|
|
5643
|
+
//# sourceMappingURL=core-DFgB3yU4.js.map
|