@marktiderman/genesis-ui 1.2.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AppShell-BJarYZzz.d.ts +198 -0
- package/dist/{chunk-NJMO3VPA.js → chunk-22XB3Q6H.js} +8 -8
- package/dist/chunk-22XB3Q6H.js.map +1 -0
- package/dist/{chunk-2MXMWBDV.js → chunk-27ELYTGE.js} +6 -6
- package/dist/chunk-27ELYTGE.js.map +1 -0
- package/dist/chunk-46TZGMFW.js +159 -0
- package/dist/chunk-46TZGMFW.js.map +1 -0
- package/dist/chunk-4CQHPWJD.js +117 -0
- package/dist/chunk-4CQHPWJD.js.map +1 -0
- package/dist/{chunk-ZDAT5JDH.js → chunk-65SPT7EA.js} +24 -6
- package/dist/chunk-65SPT7EA.js.map +1 -0
- package/dist/chunk-6KHY647C.js +67 -0
- package/dist/chunk-6KHY647C.js.map +1 -0
- package/dist/chunk-6M4NHHKG.js +51 -0
- package/dist/chunk-6M4NHHKG.js.map +1 -0
- package/dist/{chunk-AI6CCNWK.js → chunk-6NPEMLBA.js} +2 -2
- package/dist/chunk-6NPEMLBA.js.map +1 -0
- package/dist/chunk-6Q6CLLJ4.js +9 -0
- package/dist/chunk-6Q6CLLJ4.js.map +1 -0
- package/dist/{chunk-UGHQFQOE.js → chunk-6TVMQH6M.js} +28 -28
- package/dist/chunk-6TVMQH6M.js.map +1 -0
- package/dist/{chunk-UKSBLFEK.js → chunk-6XPMU65K.js} +5 -5
- package/dist/{chunk-UKSBLFEK.js.map → chunk-6XPMU65K.js.map} +1 -1
- package/dist/{chunk-YZEA5TGK.js → chunk-7XMZVISM.js} +16 -16
- package/dist/chunk-7XMZVISM.js.map +1 -0
- package/dist/chunk-A7AHVDG7.js +52 -0
- package/dist/chunk-A7AHVDG7.js.map +1 -0
- package/dist/chunk-AFZ76Q26.js +84 -0
- package/dist/chunk-AFZ76Q26.js.map +1 -0
- package/dist/{chunk-4V4H2ZM7.js → chunk-AL5TMEZQ.js} +31 -31
- package/dist/chunk-AL5TMEZQ.js.map +1 -0
- package/dist/{chunk-O4B5ALO7.js → chunk-AOZGQM6W.js} +3 -3
- package/dist/chunk-AOZGQM6W.js.map +1 -0
- package/dist/chunk-ARJI2JUV.js +122 -0
- package/dist/chunk-ARJI2JUV.js.map +1 -0
- package/dist/chunk-AVFZ4P4B.js +25 -0
- package/dist/chunk-AVFZ4P4B.js.map +1 -0
- package/dist/chunk-B2GIBUQD.js +11 -0
- package/dist/chunk-B2GIBUQD.js.map +1 -0
- package/dist/{chunk-JXI2MYL3.js → chunk-C46ITXE4.js} +5 -5
- package/dist/chunk-C46ITXE4.js.map +1 -0
- package/dist/chunk-CNTWQSUT.js +65 -0
- package/dist/chunk-CNTWQSUT.js.map +1 -0
- package/dist/chunk-D2LIXA2Y.js +65 -0
- package/dist/chunk-D2LIXA2Y.js.map +1 -0
- package/dist/{chunk-FCGFG4RV.js → chunk-D4JTQYP5.js} +3 -3
- package/dist/{chunk-FCGFG4RV.js.map → chunk-D4JTQYP5.js.map} +1 -1
- package/dist/{chunk-T5VX5DYO.js → chunk-F47U5KNW.js} +5 -5
- package/dist/chunk-F47U5KNW.js.map +1 -0
- package/dist/chunk-FEJAZFP3.js +1100 -0
- package/dist/chunk-FEJAZFP3.js.map +1 -0
- package/dist/{chunk-2B3MFHBQ.js → chunk-FK42ZGGV.js} +21 -21
- package/dist/chunk-FK42ZGGV.js.map +1 -0
- package/dist/{chunk-XISSLIMH.js → chunk-FTTNGGLA.js} +2 -2
- package/dist/{chunk-XISSLIMH.js.map → chunk-FTTNGGLA.js.map} +1 -1
- package/dist/chunk-G5YKBPBF.js +74 -0
- package/dist/chunk-G5YKBPBF.js.map +1 -0
- package/dist/chunk-GCQFVMPI.js +56 -0
- package/dist/chunk-GCQFVMPI.js.map +1 -0
- package/dist/{chunk-LDPPIBIJ.js → chunk-IJCT5IJD.js} +3 -3
- package/dist/{chunk-LDPPIBIJ.js.map → chunk-IJCT5IJD.js.map} +1 -1
- package/dist/{chunk-DGRHPJ3M.js → chunk-J6FBA7PH.js} +3 -3
- package/dist/{chunk-DGRHPJ3M.js.map → chunk-J6FBA7PH.js.map} +1 -1
- package/dist/chunk-JAMLFMDS.js +12 -0
- package/dist/chunk-JAMLFMDS.js.map +1 -0
- package/dist/{chunk-C6H7AMO4.js → chunk-LNFF2RBD.js} +9 -9
- package/dist/chunk-LNFF2RBD.js.map +1 -0
- package/dist/{chunk-QBZMY2AF.js → chunk-M62CHO3N.js} +18 -18
- package/dist/chunk-M62CHO3N.js.map +1 -0
- package/dist/{chunk-5Q4FABZQ.js → chunk-NUXW6NPP.js} +8 -8
- package/dist/chunk-NUXW6NPP.js.map +1 -0
- package/dist/{chunk-I6JQHP6D.js → chunk-NWSCYLPT.js} +78 -17
- package/dist/chunk-NWSCYLPT.js.map +1 -0
- package/dist/{chunk-63FW5ZUA.js → chunk-P3ZL6FGR.js} +7 -7
- package/dist/chunk-P3ZL6FGR.js.map +1 -0
- package/dist/chunk-P64MFQXZ.js +191 -0
- package/dist/chunk-P64MFQXZ.js.map +1 -0
- package/dist/chunk-PLIYF6KI.js +52 -0
- package/dist/chunk-PLIYF6KI.js.map +1 -0
- package/dist/chunk-PSR47JRA.js +26 -0
- package/dist/chunk-PSR47JRA.js.map +1 -0
- package/dist/{chunk-QLCDAFS7.js → chunk-Q4I4SFBD.js} +3 -3
- package/dist/chunk-Q4I4SFBD.js.map +1 -0
- package/dist/{chunk-SBJV3K4G.js → chunk-QJ6P2DW6.js} +28 -28
- package/dist/chunk-QJ6P2DW6.js.map +1 -0
- package/dist/{chunk-IP6TMT3D.js → chunk-R7QFP6EL.js} +3 -3
- package/dist/chunk-R7QFP6EL.js.map +1 -0
- package/dist/{chunk-WZWR2ELB.js → chunk-SEBU6JCK.js} +6 -6
- package/dist/chunk-SEBU6JCK.js.map +1 -0
- package/dist/{chunk-7OBL3H5P.js → chunk-SEFK4NZV.js} +3 -3
- package/dist/chunk-SEFK4NZV.js.map +1 -0
- package/dist/chunk-SRIT4NFQ.js +67 -0
- package/dist/chunk-SRIT4NFQ.js.map +1 -0
- package/dist/chunk-SY62XJFA.js +19 -0
- package/dist/chunk-SY62XJFA.js.map +1 -0
- package/dist/{chunk-SVXDWPLO.js → chunk-THD3YOOZ.js} +17 -17
- package/dist/chunk-THD3YOOZ.js.map +1 -0
- package/dist/chunk-VXFYETRK.js +58 -0
- package/dist/chunk-VXFYETRK.js.map +1 -0
- package/dist/chunk-XBX6QMR5.js +58 -0
- package/dist/chunk-XBX6QMR5.js.map +1 -0
- package/dist/{chunk-SCUT2ZCD.js → chunk-XCGZPFT7.js} +17 -17
- package/dist/chunk-XCGZPFT7.js.map +1 -0
- package/dist/chunk-XMK3T4TA.js +73 -0
- package/dist/chunk-XMK3T4TA.js.map +1 -0
- package/dist/chunk-YJ6MPS6U.js +226 -0
- package/dist/chunk-YJ6MPS6U.js.map +1 -0
- package/dist/chunk-YRYQXU3G.js +38 -0
- package/dist/chunk-YRYQXU3G.js.map +1 -0
- package/dist/{chunk-5J7BP5DI.js → chunk-YWFPMND7.js} +10 -10
- package/dist/chunk-YWFPMND7.js.map +1 -0
- package/dist/chunk-YYEGAFUE.js +94 -0
- package/dist/chunk-YYEGAFUE.js.map +1 -0
- package/dist/{chunk-TKA4LOMT.js → chunk-ZZ7H7VVX.js} +8 -8
- package/dist/chunk-ZZ7H7VVX.js.map +1 -0
- package/dist/components/data/index.d.ts +223 -74
- package/dist/components/data/index.js +504 -539
- package/dist/components/data/index.js.map +1 -1
- package/dist/components/layout/dashboard-page.d.ts +4 -0
- package/dist/components/layout/dashboard-page.js +5 -0
- package/dist/components/layout/dashboard-page.js.map +1 -0
- package/dist/components/layout/detail-page.d.ts +91 -0
- package/dist/components/layout/detail-page.js +6 -0
- package/dist/components/layout/detail-page.js.map +1 -0
- package/dist/components/layout/form-page.d.ts +82 -0
- package/dist/components/layout/form-page.js +5 -0
- package/dist/components/layout/form-page.js.map +1 -0
- package/dist/components/layout/index.d.ts +15 -0
- package/dist/components/layout/index.js +21 -0
- package/dist/components/layout/index.js.map +1 -0
- package/dist/components/layout/settings-page.d.ts +114 -0
- package/dist/components/layout/settings-page.js +6 -0
- package/dist/components/layout/settings-page.js.map +1 -0
- package/dist/components/patterns/empty-state.d.ts +74 -0
- package/dist/components/{ui → patterns}/empty-state.js +2 -1
- package/dist/components/{ui → patterns}/form-field.d.ts +2 -2
- package/dist/components/{ui → patterns}/form-field.js +2 -2
- package/dist/components/patterns/index.d.ts +18 -0
- package/dist/components/patterns/index.js +18 -0
- package/dist/components/patterns/index.js.map +1 -0
- package/dist/components/patterns/page-loading.d.ts +25 -0
- package/dist/components/patterns/page-loading.js +5 -0
- package/dist/components/patterns/page-loading.js.map +1 -0
- package/dist/components/patterns/settings-row.d.ts +42 -0
- package/dist/components/patterns/settings-row.js +6 -0
- package/dist/components/patterns/settings-row.js.map +1 -0
- package/dist/components/patterns/status-badge.d.ts +38 -0
- package/dist/components/patterns/status-badge.js +4 -0
- package/dist/components/patterns/status-badge.js.map +1 -0
- package/dist/components/patterns/toggle-row.d.ts +36 -0
- package/dist/components/patterns/toggle-row.js +8 -0
- package/dist/components/patterns/toggle-row.js.map +1 -0
- package/dist/components/patterns/user-avatar.d.ts +34 -0
- package/dist/components/patterns/user-avatar.js +5 -0
- package/dist/components/patterns/user-avatar.js.map +1 -0
- package/dist/components/ui/accessible-icon.d.ts +48 -0
- package/dist/components/ui/accessible-icon.js +3 -0
- package/dist/components/ui/accessible-icon.js.map +1 -0
- package/dist/components/ui/accordion.d.ts +5 -5
- package/dist/components/ui/accordion.js +1 -1
- package/dist/components/ui/alert-dialog.d.ts +10 -10
- package/dist/components/ui/alert-dialog.js +1 -1
- package/dist/components/ui/aspect-ratio.d.ts +2 -2
- package/dist/components/ui/aspect-ratio.js +1 -1
- package/dist/components/ui/avatar.d.ts +4 -4
- package/dist/components/ui/avatar.js +1 -1
- package/dist/components/ui/button.d.ts +75 -8
- package/dist/components/ui/button.js +1 -1
- package/dist/components/ui/calendar.js +2 -2
- package/dist/components/ui/carousel.d.ts +4 -3
- package/dist/components/ui/carousel.js +2 -2
- package/dist/components/ui/checkbox.d.ts +2 -2
- package/dist/components/ui/checkbox.js +1 -1
- package/dist/components/ui/collapsible.d.ts +4 -4
- package/dist/components/ui/collapsible.js +1 -1
- package/dist/components/ui/command-palette.d.ts +30 -0
- package/dist/components/ui/command-palette.js +6 -0
- package/dist/components/ui/command-palette.js.map +1 -0
- package/dist/components/ui/command.d.ts +9 -9
- package/dist/components/ui/command.js +2 -2
- package/dist/components/ui/context-menu.d.ts +15 -15
- package/dist/components/ui/context-menu.js +1 -1
- package/dist/components/ui/date-picker.js +4 -4
- package/dist/components/ui/dialog.d.ts +9 -9
- package/dist/components/ui/dialog.js +1 -1
- package/dist/components/ui/drawer.d.ts +7 -7
- package/dist/components/ui/dropdown-menu.d.ts +15 -15
- package/dist/components/ui/dropdown-menu.js +1 -1
- package/dist/components/ui/hover-card.d.ts +4 -4
- package/dist/components/ui/hover-card.js +1 -1
- package/dist/components/ui/input-otp.d.ts +2 -2
- package/dist/components/ui/label.d.ts +2 -2
- package/dist/components/ui/label.js +1 -1
- package/dist/components/ui/menubar.d.ts +16 -16
- package/dist/components/ui/menubar.js +1 -1
- package/dist/components/ui/navigation-menu.d.ts +9 -9
- package/dist/components/ui/navigation-menu.js +1 -1
- package/dist/components/ui/pagination.js +2 -2
- package/dist/components/ui/password-toggle-field.d.ts +121 -0
- package/dist/components/ui/password-toggle-field.js +4 -0
- package/dist/components/ui/password-toggle-field.js.map +1 -0
- package/dist/components/ui/popover.d.ts +4 -4
- package/dist/components/ui/popover.js +1 -1
- package/dist/components/ui/radio-group.d.ts +3 -3
- package/dist/components/ui/radio-group.js +1 -1
- package/dist/components/ui/resizable.d.ts +1 -1
- package/dist/components/ui/scroll-area.d.ts +60 -3
- package/dist/components/ui/scroll-area.js +1 -1
- package/dist/components/ui/select.d.ts +9 -9
- package/dist/components/ui/select.js +1 -1
- package/dist/components/ui/sheet.d.ts +11 -9
- package/dist/components/ui/sheet.js +1 -1
- package/dist/components/ui/slider.d.ts +2 -2
- package/dist/components/ui/slider.js +1 -1
- package/dist/components/ui/switch.d.ts +2 -2
- package/dist/components/ui/switch.js +1 -1
- package/dist/components/ui/tabs.d.ts +29 -14
- package/dist/components/ui/tabs.js +1 -1
- package/dist/components/ui/toggle-group.d.ts +3 -3
- package/dist/components/ui/toggle-group.js +2 -2
- package/dist/components/ui/toggle.d.ts +2 -2
- package/dist/components/ui/toggle.js +1 -1
- package/dist/components/ui/toolbar.d.ts +104 -0
- package/dist/components/ui/toolbar.js +6 -0
- package/dist/components/ui/toolbar.js.map +1 -0
- package/dist/components/ui/tooltip.d.ts +46 -4
- package/dist/components/ui/tooltip.js +1 -1
- package/dist/components/ui/visually-hidden.d.ts +48 -0
- package/dist/components/ui/visually-hidden.js +4 -0
- package/dist/components/ui/visually-hidden.js.map +1 -0
- package/dist/dashboard-page-C0TihRl5.d.ts +107 -0
- package/dist/hooks/index.d.ts +5 -3
- package/dist/hooks/index.js +10 -5
- package/dist/hooks/use-data-filters.d.ts +1 -1
- package/dist/hooks/use-data-filters.js +2 -2
- package/dist/hooks/use-keyboard-navigation.d.ts +58 -2
- package/dist/hooks/use-keyboard-navigation.js +1 -1
- package/dist/hooks/use-resource-page.d.ts +3 -2
- package/dist/hooks/use-resource-page.js +2 -2
- package/dist/hooks/use-saved-views.d.ts +28 -0
- package/dist/hooks/use-saved-views.js +3 -0
- package/dist/hooks/use-saved-views.js.map +1 -0
- package/dist/hooks/use-view-preference.d.ts +1 -1
- package/dist/hooks/use-view-preference.js +1 -1
- package/dist/index.d.ts +25 -26
- package/dist/index.js +55 -38
- package/dist/{navigation-qI86Ldug.d.ts → navigation-CpOEyUSb.d.ts} +4 -0
- package/dist/spacing-BS6qECD4.d.ts +191 -0
- package/dist/split-Dk9f4Mi0.d.ts +57 -0
- package/dist/{use-resource-page-B-CFcikK.d.ts → use-resource-page-CPs6wjKt.d.ts} +10 -2
- package/dist/view-settings--KXNT_jE.d.ts +12 -0
- package/package.json +77 -32
- package/dist/chunk-2B3MFHBQ.js.map +0 -1
- package/dist/chunk-2MXMWBDV.js.map +0 -1
- package/dist/chunk-4V4H2ZM7.js.map +0 -1
- package/dist/chunk-5J7BP5DI.js.map +0 -1
- package/dist/chunk-5Q4FABZQ.js.map +0 -1
- package/dist/chunk-63FW5ZUA.js.map +0 -1
- package/dist/chunk-7OBL3H5P.js.map +0 -1
- package/dist/chunk-AI6CCNWK.js.map +0 -1
- package/dist/chunk-C6H7AMO4.js.map +0 -1
- package/dist/chunk-EI5EGKHL.js +0 -32
- package/dist/chunk-EI5EGKHL.js.map +0 -1
- package/dist/chunk-I6JQHP6D.js.map +0 -1
- package/dist/chunk-IP6TMT3D.js.map +0 -1
- package/dist/chunk-JJ4NOMMI.js +0 -73
- package/dist/chunk-JJ4NOMMI.js.map +0 -1
- package/dist/chunk-JXI2MYL3.js.map +0 -1
- package/dist/chunk-KBS4BHME.js +0 -11
- package/dist/chunk-KBS4BHME.js.map +0 -1
- package/dist/chunk-LRXDZBV2.js +0 -26
- package/dist/chunk-LRXDZBV2.js.map +0 -1
- package/dist/chunk-NJMO3VPA.js.map +0 -1
- package/dist/chunk-O4B5ALO7.js.map +0 -1
- package/dist/chunk-OCTV3S4I.js +0 -29
- package/dist/chunk-OCTV3S4I.js.map +0 -1
- package/dist/chunk-QBZMY2AF.js.map +0 -1
- package/dist/chunk-QLCDAFS7.js.map +0 -1
- package/dist/chunk-SBJV3K4G.js.map +0 -1
- package/dist/chunk-SCUT2ZCD.js.map +0 -1
- package/dist/chunk-SVXDWPLO.js.map +0 -1
- package/dist/chunk-T465NJRL.js +0 -134
- package/dist/chunk-T465NJRL.js.map +0 -1
- package/dist/chunk-T5VX5DYO.js.map +0 -1
- package/dist/chunk-TKA4LOMT.js.map +0 -1
- package/dist/chunk-UGHQFQOE.js.map +0 -1
- package/dist/chunk-WALXVR6V.js +0 -9
- package/dist/chunk-WALXVR6V.js.map +0 -1
- package/dist/chunk-WZWR2ELB.js.map +0 -1
- package/dist/chunk-YZEA5TGK.js.map +0 -1
- package/dist/chunk-ZDAT5JDH.js.map +0 -1
- package/dist/components/ui/empty-state.d.ts +0 -22
- /package/dist/components/{ui → patterns}/empty-state.js.map +0 -0
- /package/dist/components/{ui → patterns}/form-field.js.map +0 -0
- /package/dist/{ViewToggle-DDe_Luj2.d.ts → view-toggle-DDe_Luj2.d.ts} +0 -0
|
@@ -1,151 +1,55 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { AppShell, PageHeader } from '../../chunk-FEJAZFP3.js';
|
|
3
|
+
export { ViewSettings, ViewToggle } from '../../chunk-46TZGMFW.js';
|
|
4
4
|
import { Table, TableHeader, TableRow, TableHead, TableBody, TableCell } from '../../chunk-N2ZFNOOT.js';
|
|
5
5
|
import { Textarea } from '../../chunk-YETMISCE.js';
|
|
6
|
-
import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from '../../chunk-2B3MFHBQ.js';
|
|
7
6
|
import { Separator } from '../../chunk-SXSCHWZU.js';
|
|
8
|
-
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription } from '../../chunk-
|
|
7
|
+
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription } from '../../chunk-XCGZPFT7.js';
|
|
9
8
|
import { Skeleton } from '../../chunk-QFM4Z2SS.js';
|
|
10
9
|
import { Progress } from '../../chunk-W5Y3LG5K.js';
|
|
11
|
-
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuCheckboxItem, DropdownMenuSeparator, DropdownMenuItem } from '../../chunk-
|
|
12
|
-
import { FormField, FormLabel, FormError, FormDescription } from '../../chunk-IP6TMT3D.js';
|
|
13
|
-
import '../../chunk-T5VX5DYO.js';
|
|
10
|
+
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuCheckboxItem, DropdownMenuSeparator, DropdownMenuItem } from '../../chunk-QJ6P2DW6.js';
|
|
14
11
|
import { Input } from '../../chunk-QSXVL5UB.js';
|
|
15
|
-
import { Checkbox } from '../../chunk-
|
|
16
|
-
import { Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, CommandSeparator } from '../../chunk-7OBL3H5P.js';
|
|
17
|
-
import { Popover, PopoverTrigger, PopoverContent } from '../../chunk-NJMO3VPA.js';
|
|
18
|
-
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogDescription } from '../../chunk-YZEA5TGK.js';
|
|
19
|
-
import { Badge } from '../../chunk-NPNADZHM.js';
|
|
20
|
-
import { Button } from '../../chunk-I6JQHP6D.js';
|
|
12
|
+
import { Checkbox } from '../../chunk-SEBU6JCK.js';
|
|
21
13
|
import { Card, CardContent, CardHeader, CardTitle } from '../../chunk-FN3FZVUR.js';
|
|
14
|
+
import '../../chunk-B2GIBUQD.js';
|
|
15
|
+
import { Badge } from '../../chunk-NPNADZHM.js';
|
|
16
|
+
import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from '../../chunk-FK42ZGGV.js';
|
|
17
|
+
import { Popover, PopoverTrigger, PopoverContent } from '../../chunk-22XB3Q6H.js';
|
|
18
|
+
import { Switch } from '../../chunk-27ELYTGE.js';
|
|
19
|
+
import { EmptyState } from '../../chunk-65SPT7EA.js';
|
|
20
|
+
export { EmptyState } from '../../chunk-65SPT7EA.js';
|
|
21
|
+
import { Button } from '../../chunk-NWSCYLPT.js';
|
|
22
|
+
import { PageLoading } from '../../chunk-YRYQXU3G.js';
|
|
23
|
+
import { Spinner } from '../../chunk-OVU3Z2MT.js';
|
|
24
|
+
import { FormField, FormLabel, FormError, FormDescription } from '../../chunk-R7QFP6EL.js';
|
|
25
|
+
import '../../chunk-F47U5KNW.js';
|
|
26
|
+
import { DetailPage } from '../../chunk-AFZ76Q26.js';
|
|
27
|
+
import '../../chunk-D2LIXA2Y.js';
|
|
28
|
+
import '../../chunk-AVFZ4P4B.js';
|
|
29
|
+
import { titleCase, useResourcePage } from '../../chunk-Q4I4SFBD.js';
|
|
30
|
+
export { useSavedViews } from '../../chunk-GCQFVMPI.js';
|
|
31
|
+
import '../../chunk-FTTNGGLA.js';
|
|
32
|
+
import { useViewSettings } from '../../chunk-OZ7ZAYCS.js';
|
|
33
|
+
export { CommandPalette, useCommandPaletteHotkey } from '../../chunk-CNTWQSUT.js';
|
|
34
|
+
import { Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, CommandSeparator } from '../../chunk-SEFK4NZV.js';
|
|
35
|
+
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogDescription } from '../../chunk-7XMZVISM.js';
|
|
22
36
|
import { cn } from '../../chunk-NZ5WBA4R.js';
|
|
23
|
-
import {
|
|
24
|
-
|
|
25
|
-
import {
|
|
26
|
-
export { DefaultLink, defaultNavigate, isPathActive } from '../../chunk-AI6CCNWK.js';
|
|
37
|
+
import { DefaultLink, defaultNavigate } from '../../chunk-6NPEMLBA.js';
|
|
38
|
+
export { DefaultLink, defaultNavigate, isPathActive } from '../../chunk-6NPEMLBA.js';
|
|
39
|
+
import { useKeyboardNavigation } from '../../chunk-YJ6MPS6U.js';
|
|
27
40
|
import { useIsMobile } from '../../chunk-M7AU5DDM.js';
|
|
28
|
-
import {
|
|
41
|
+
import { AlertTriangle, RefreshCw, ChevronDown, Check, Search, X, ArrowUpDown, Bookmark, Trash2, BookmarkPlus, Loader2, Columns3, ArrowUp, ArrowDown, ChevronLeft, ChevronRight, ExternalLink, Pencil, ChevronsUpDown, ImageIcon, Upload, AlertCircle, FileIcon, Plus } from 'lucide-react';
|
|
29
42
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
30
43
|
import { useState, useRef, useEffect, useCallback, useMemo } from 'react';
|
|
31
44
|
import { formatDistanceToNow, format } from 'date-fns';
|
|
32
45
|
import { useFieldArray, Controller, useWatch } from 'react-hook-form';
|
|
33
|
-
import { useResource, useWizard, useResourceForm, buildArrayItemDefaults } from '@marktiderman/genesis-core/hooks';
|
|
46
|
+
import { useResource, useWizard, useResourceForm, useOne, buildArrayItemDefaults } from '@marktiderman/genesis-core/hooks';
|
|
34
47
|
import { useDataProvider } from '@marktiderman/genesis-core/provider';
|
|
35
48
|
import { useDropzone } from 'react-dropzone';
|
|
36
49
|
|
|
37
|
-
function EmptyState({
|
|
38
|
-
icon: Icon = Search,
|
|
39
|
-
message = "No items found",
|
|
40
|
-
action,
|
|
41
|
-
hasFilters = false,
|
|
42
|
-
onClearFilters
|
|
43
|
-
}) {
|
|
44
|
-
return /* @__PURE__ */ jsxs("div", { className: "text-center py-16 animate-fade-in", children: [
|
|
45
|
-
/* @__PURE__ */ jsx(Icon, { className: "h-10 w-10 text-muted-foreground/30 mx-auto mb-3" }),
|
|
46
|
-
/* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: hasFilters ? "No results match your filters" : message }),
|
|
47
|
-
hasFilters && onClearFilters ? /* @__PURE__ */ jsx(Button, { variant: "link", size: "sm", onClick: onClearFilters, className: "mt-2", children: "Clear all filters" }) : action && /* @__PURE__ */ jsx("div", { className: "mt-4", children: action })
|
|
48
|
-
] });
|
|
49
|
-
}
|
|
50
|
-
function ViewToggle({ viewMode, onViewModeChange }) {
|
|
51
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex items-center border rounded-lg overflow-hidden", children: [
|
|
52
|
-
/* @__PURE__ */ jsx(
|
|
53
|
-
Button,
|
|
54
|
-
{
|
|
55
|
-
variant: viewMode === "grid" ? "default" : "ghost",
|
|
56
|
-
size: "icon",
|
|
57
|
-
className: "h-8 w-8 rounded-none",
|
|
58
|
-
onClick: () => onViewModeChange("grid"),
|
|
59
|
-
title: "Grid view",
|
|
60
|
-
children: /* @__PURE__ */ jsx(LayoutGrid, { className: "h-4 w-4" })
|
|
61
|
-
}
|
|
62
|
-
),
|
|
63
|
-
/* @__PURE__ */ jsx(
|
|
64
|
-
Button,
|
|
65
|
-
{
|
|
66
|
-
variant: viewMode === "table" ? "default" : "ghost",
|
|
67
|
-
size: "icon",
|
|
68
|
-
className: "h-8 w-8 rounded-none",
|
|
69
|
-
onClick: () => onViewModeChange("table"),
|
|
70
|
-
title: "Table view",
|
|
71
|
-
children: /* @__PURE__ */ jsx(Table2, { className: "h-4 w-4" })
|
|
72
|
-
}
|
|
73
|
-
),
|
|
74
|
-
/* @__PURE__ */ jsx(
|
|
75
|
-
Button,
|
|
76
|
-
{
|
|
77
|
-
variant: viewMode === "list" ? "default" : "ghost",
|
|
78
|
-
size: "icon",
|
|
79
|
-
className: "h-8 w-8 rounded-none",
|
|
80
|
-
onClick: () => onViewModeChange("list"),
|
|
81
|
-
title: "List view",
|
|
82
|
-
children: /* @__PURE__ */ jsx(List, { className: "h-4 w-4" })
|
|
83
|
-
}
|
|
84
|
-
)
|
|
85
|
-
] });
|
|
86
|
-
}
|
|
87
|
-
var PAGE_SIZE_OPTIONS = [10, 25, 50, 100];
|
|
88
|
-
var DENSITY_OPTIONS = [
|
|
89
|
-
{ value: "compact", label: "Compact" },
|
|
90
|
-
{ value: "comfortable", label: "Comfortable" },
|
|
91
|
-
{ value: "spacious", label: "Spacious" }
|
|
92
|
-
];
|
|
93
|
-
function ViewSettings({
|
|
94
|
-
pageSize,
|
|
95
|
-
onPageSizeChange,
|
|
96
|
-
density,
|
|
97
|
-
onDensityChange
|
|
98
|
-
}) {
|
|
99
|
-
return /* @__PURE__ */ jsxs(Popover, { children: [
|
|
100
|
-
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
101
|
-
Button,
|
|
102
|
-
{
|
|
103
|
-
variant: "ghost",
|
|
104
|
-
size: "icon",
|
|
105
|
-
className: "h-8 w-8",
|
|
106
|
-
title: "View settings",
|
|
107
|
-
children: /* @__PURE__ */ jsx(Settings2, { className: "h-4 w-4" })
|
|
108
|
-
}
|
|
109
|
-
) }),
|
|
110
|
-
/* @__PURE__ */ jsxs(PopoverContent, { align: "end", className: "w-56 space-y-4", children: [
|
|
111
|
-
/* @__PURE__ */ jsx("h4", { className: "text-sm font-semibold", children: "Display Settings" }),
|
|
112
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
113
|
-
/* @__PURE__ */ jsx("label", { className: "text-xs text-muted-foreground", children: "Page size" }),
|
|
114
|
-
/* @__PURE__ */ jsxs(
|
|
115
|
-
Select,
|
|
116
|
-
{
|
|
117
|
-
value: String(pageSize),
|
|
118
|
-
onValueChange: (v) => onPageSizeChange(Number(v)),
|
|
119
|
-
children: [
|
|
120
|
-
/* @__PURE__ */ jsx(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
121
|
-
/* @__PURE__ */ jsx(SelectContent, { className: "bg-popover z-50", children: PAGE_SIZE_OPTIONS.map((n) => /* @__PURE__ */ jsxs(SelectItem, { value: String(n), children: [
|
|
122
|
-
n,
|
|
123
|
-
" items"
|
|
124
|
-
] }, n)) })
|
|
125
|
-
]
|
|
126
|
-
}
|
|
127
|
-
)
|
|
128
|
-
] }),
|
|
129
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
130
|
-
/* @__PURE__ */ jsx("label", { className: "text-xs text-muted-foreground", children: "Density" }),
|
|
131
|
-
/* @__PURE__ */ jsxs(
|
|
132
|
-
Select,
|
|
133
|
-
{
|
|
134
|
-
value: density,
|
|
135
|
-
onValueChange: (v) => onDensityChange(v),
|
|
136
|
-
children: [
|
|
137
|
-
/* @__PURE__ */ jsx(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
138
|
-
/* @__PURE__ */ jsx(SelectContent, { className: "bg-popover z-50", children: DENSITY_OPTIONS.map((opt) => /* @__PURE__ */ jsx(SelectItem, { value: opt.value, children: opt.label }, opt.value)) })
|
|
139
|
-
]
|
|
140
|
-
}
|
|
141
|
-
)
|
|
142
|
-
] })
|
|
143
|
-
] })
|
|
144
|
-
] });
|
|
145
|
-
}
|
|
146
50
|
function DataPageShell({
|
|
147
51
|
title,
|
|
148
|
-
icon
|
|
52
|
+
icon,
|
|
149
53
|
entityName,
|
|
150
54
|
subtitle,
|
|
151
55
|
createAction,
|
|
@@ -168,44 +72,57 @@ function DataPageShell({
|
|
|
168
72
|
filters,
|
|
169
73
|
hasActiveFilters = false,
|
|
170
74
|
onClearFilters,
|
|
75
|
+
filtersCollapsible = false,
|
|
76
|
+
defaultFiltersOpen = false,
|
|
77
|
+
filtersOpen,
|
|
78
|
+
onFiltersOpenChange,
|
|
79
|
+
filtersLabel,
|
|
80
|
+
filtersHint,
|
|
81
|
+
headerOptions,
|
|
82
|
+
headerOptionsStorageKey,
|
|
171
83
|
children
|
|
172
84
|
}) {
|
|
173
85
|
const entity = entityName || title.toLowerCase();
|
|
174
|
-
const
|
|
175
|
-
const
|
|
176
|
-
|
|
86
|
+
const collapseFilters = filtersCollapsible && filters != null;
|
|
87
|
+
const mergedOptions = {
|
|
88
|
+
defaultDetailsOpen: defaultFiltersOpen,
|
|
89
|
+
detailsLabel: filtersLabel,
|
|
90
|
+
subtitleInDetails: collapseFilters ? true : void 0,
|
|
91
|
+
...headerOptions
|
|
92
|
+
};
|
|
93
|
+
const sharedHeaderProps = {
|
|
94
|
+
title,
|
|
95
|
+
subtitle,
|
|
96
|
+
icon,
|
|
97
|
+
entityName: entity,
|
|
98
|
+
count,
|
|
99
|
+
totalCount,
|
|
100
|
+
countActive: hasActiveFilters,
|
|
101
|
+
viewMode,
|
|
102
|
+
onViewModeChange,
|
|
103
|
+
pageSize,
|
|
104
|
+
onPageSizeChange,
|
|
105
|
+
density,
|
|
106
|
+
onDensityChange,
|
|
107
|
+
createAction,
|
|
108
|
+
optionsStorageKey: headerOptionsStorageKey
|
|
109
|
+
};
|
|
177
110
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
178
|
-
/* @__PURE__ */
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
] }),
|
|
193
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
194
|
-
hasCount && /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "text-xs", children: hasActiveFilters ? `${count} of ${totalCount}` : `${totalCount} ${entity.endsWith("s") ? entity : `${entity}s`}` }),
|
|
195
|
-
hasViewToggle && /* @__PURE__ */ jsx(ViewToggle, { viewMode, onViewModeChange }),
|
|
196
|
-
hasViewSettings && /* @__PURE__ */ jsx(
|
|
197
|
-
ViewSettings,
|
|
198
|
-
{
|
|
199
|
-
pageSize: pageSize ?? 25,
|
|
200
|
-
onPageSizeChange,
|
|
201
|
-
density: density ?? "comfortable",
|
|
202
|
-
onDensityChange
|
|
203
|
-
}
|
|
204
|
-
),
|
|
205
|
-
createAction
|
|
206
|
-
] })
|
|
111
|
+
collapseFilters ? /* @__PURE__ */ jsx(
|
|
112
|
+
PageHeader,
|
|
113
|
+
{
|
|
114
|
+
...sharedHeaderProps,
|
|
115
|
+
details: filters,
|
|
116
|
+
detailsOpen: filtersOpen,
|
|
117
|
+
onDetailsOpenChange: onFiltersOpenChange,
|
|
118
|
+
detailsActive: hasActiveFilters,
|
|
119
|
+
detailsHint: filtersHint,
|
|
120
|
+
options: mergedOptions
|
|
121
|
+
}
|
|
122
|
+
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
123
|
+
/* @__PURE__ */ jsx(PageHeader, { ...sharedHeaderProps, options: headerOptions }),
|
|
124
|
+
filters
|
|
207
125
|
] }),
|
|
208
|
-
filters,
|
|
209
126
|
isLoading ? /* @__PURE__ */ jsx(
|
|
210
127
|
"div",
|
|
211
128
|
{
|
|
@@ -222,17 +139,17 @@ function DataPageShell({
|
|
|
222
139
|
}
|
|
223
140
|
) : hasError ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center py-16 text-center", children: [
|
|
224
141
|
/* @__PURE__ */ jsx(AlertTriangle, { className: "h-10 w-10 text-destructive mb-3" }),
|
|
225
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground
|
|
226
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground
|
|
142
|
+
/* @__PURE__ */ jsx("p", { className: "mb-1 text-sm font-medium text-foreground", children: "Something went wrong" }),
|
|
143
|
+
/* @__PURE__ */ jsx("p", { className: "mb-4 text-sm text-muted-foreground", children: errorMessage || `Failed to load ${entity}s. Please try again.` }),
|
|
227
144
|
onRetry && /* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", onClick: onRetry, children: [
|
|
228
|
-
/* @__PURE__ */ jsx(RefreshCw, { className: "h-4 w-4
|
|
145
|
+
/* @__PURE__ */ jsx(RefreshCw, { className: "mr-1 h-4 w-4" }),
|
|
229
146
|
" Retry"
|
|
230
147
|
] })
|
|
231
148
|
] }) : isEmpty ? /* @__PURE__ */ jsx(
|
|
232
149
|
EmptyState,
|
|
233
150
|
{
|
|
234
151
|
icon: emptyIcon,
|
|
235
|
-
|
|
152
|
+
title: emptyMessage,
|
|
236
153
|
action: emptyAction,
|
|
237
154
|
hasFilters: hasActiveFilters,
|
|
238
155
|
onClearFilters
|
|
@@ -609,14 +526,25 @@ function DataGrid({
|
|
|
609
526
|
}
|
|
610
527
|
if (viewMode === "list" && renderListItem) {
|
|
611
528
|
const keyFnList = getKey || ((item) => item.id);
|
|
612
|
-
return /* @__PURE__ */ jsx(
|
|
529
|
+
return /* @__PURE__ */ jsx(
|
|
613
530
|
"div",
|
|
614
531
|
{
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
532
|
+
ref: keyboardContainerRef,
|
|
533
|
+
className: "divide-y divide-border rounded-lg border",
|
|
534
|
+
children: items.map((item, i) => /* @__PURE__ */ jsx(
|
|
535
|
+
"div",
|
|
536
|
+
{
|
|
537
|
+
"data-nav-item": true,
|
|
538
|
+
className: cn(
|
|
539
|
+
"px-4 py-3 transition-colors hover:bg-accent/50",
|
|
540
|
+
focusedIndex === i && "ring-2 ring-inset ring-primary bg-accent/50"
|
|
541
|
+
),
|
|
542
|
+
children: renderListItem(item, i)
|
|
543
|
+
},
|
|
544
|
+
keyFnList(item)
|
|
545
|
+
))
|
|
546
|
+
}
|
|
547
|
+
);
|
|
620
548
|
}
|
|
621
549
|
const visible = items.slice(0, visibleCount);
|
|
622
550
|
const keyFn = getKey || ((item) => item.id);
|
|
@@ -647,6 +575,16 @@ function DataGrid({
|
|
|
647
575
|
)
|
|
648
576
|
] });
|
|
649
577
|
}
|
|
578
|
+
var DENSITY_CELL = {
|
|
579
|
+
compact: "py-1 h-8",
|
|
580
|
+
comfortable: "py-2",
|
|
581
|
+
spacious: "py-3"
|
|
582
|
+
};
|
|
583
|
+
var DENSITY_HEAD = {
|
|
584
|
+
compact: "h-8 py-1",
|
|
585
|
+
comfortable: "h-10",
|
|
586
|
+
spacious: "h-12 py-3"
|
|
587
|
+
};
|
|
650
588
|
function getCellClasses(col) {
|
|
651
589
|
const hide = col.hideBelow ? col.hideBelow === "sm" ? "hidden sm:table-cell" : col.hideBelow === "md" ? "hidden md:table-cell" : col.hideBelow === "lg" ? "hidden lg:table-cell" : "hidden xl:table-cell" : "";
|
|
652
590
|
return cn(col.width, hide);
|
|
@@ -764,8 +702,11 @@ function DataTable({
|
|
|
764
702
|
pageSizeOptions = [10, 25, 50, 100],
|
|
765
703
|
stickyHeader = true,
|
|
766
704
|
resizeKey,
|
|
767
|
-
stickyFirstColumn
|
|
705
|
+
stickyFirstColumn,
|
|
706
|
+
density = "comfortable"
|
|
768
707
|
}) {
|
|
708
|
+
const cellDensity = DENSITY_CELL[density];
|
|
709
|
+
const headDensity = DENSITY_HEAD[density];
|
|
769
710
|
const [sorts, setSorts] = useState([]);
|
|
770
711
|
const handleSort = useCallback(
|
|
771
712
|
(key, shiftKey) => {
|
|
@@ -788,15 +729,6 @@ function DataTable({
|
|
|
788
729
|
);
|
|
789
730
|
const [visibleCols, setVisibleCols] = useState(
|
|
790
731
|
() => {
|
|
791
|
-
if (columnVisibilityKey) {
|
|
792
|
-
try {
|
|
793
|
-
const saved = localStorage.getItem(
|
|
794
|
-
`dt-vis-${columnVisibilityKey}`
|
|
795
|
-
);
|
|
796
|
-
if (saved) return JSON.parse(saved);
|
|
797
|
-
} catch {
|
|
798
|
-
}
|
|
799
|
-
}
|
|
800
732
|
const initial = {};
|
|
801
733
|
columns.forEach((c) => {
|
|
802
734
|
initial[c.key] = c.defaultVisible !== false;
|
|
@@ -804,14 +736,40 @@ function DataTable({
|
|
|
804
736
|
return initial;
|
|
805
737
|
}
|
|
806
738
|
);
|
|
739
|
+
const [visibilityHydrated, setVisibilityHydrated] = useState(false);
|
|
807
740
|
useEffect(() => {
|
|
808
|
-
if (columnVisibilityKey) {
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
741
|
+
if (!columnVisibilityKey) {
|
|
742
|
+
setVisibilityHydrated(true);
|
|
743
|
+
return;
|
|
744
|
+
}
|
|
745
|
+
try {
|
|
746
|
+
const saved = localStorage.getItem(`dt-vis-${columnVisibilityKey}`);
|
|
747
|
+
if (saved) {
|
|
748
|
+
const parsed = JSON.parse(saved);
|
|
749
|
+
setVisibleCols((prev) => {
|
|
750
|
+
const next = { ...prev };
|
|
751
|
+
for (const [k, v] of Object.entries(parsed)) {
|
|
752
|
+
if (k in next || columns.some((c) => c.key === k)) {
|
|
753
|
+
next[k] = v;
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
columns.forEach((c) => {
|
|
757
|
+
if (!(c.key in next)) next[c.key] = c.defaultVisible !== false;
|
|
758
|
+
});
|
|
759
|
+
return next;
|
|
760
|
+
});
|
|
761
|
+
}
|
|
762
|
+
} catch {
|
|
813
763
|
}
|
|
814
|
-
|
|
764
|
+
setVisibilityHydrated(true);
|
|
765
|
+
}, [columnVisibilityKey]);
|
|
766
|
+
useEffect(() => {
|
|
767
|
+
if (!visibilityHydrated || !columnVisibilityKey) return;
|
|
768
|
+
localStorage.setItem(
|
|
769
|
+
`dt-vis-${columnVisibilityKey}`,
|
|
770
|
+
JSON.stringify(visibleCols)
|
|
771
|
+
);
|
|
772
|
+
}, [visibleCols, columnVisibilityKey, visibilityHydrated]);
|
|
815
773
|
const toggleColumnVisibility = useCallback((key) => {
|
|
816
774
|
setVisibleCols((prev) => ({ ...prev, [key]: !prev[key] }));
|
|
817
775
|
}, []);
|
|
@@ -950,7 +908,7 @@ function DataTable({
|
|
|
950
908
|
{
|
|
951
909
|
className: stickyHeader ? "sticky top-0 z-10 bg-background" : "",
|
|
952
910
|
children: /* @__PURE__ */ jsxs(TableRow, { children: [
|
|
953
|
-
selectable && /* @__PURE__ */ jsx(TableHead, { className: "w-10", children: /* @__PURE__ */ jsx(
|
|
911
|
+
selectable && /* @__PURE__ */ jsx(TableHead, { className: cn("w-10", headDensity), children: /* @__PURE__ */ jsx(
|
|
954
912
|
Checkbox,
|
|
955
913
|
{
|
|
956
914
|
checked: items.length > 0 && selected?.size === items.length,
|
|
@@ -967,6 +925,7 @@ function DataTable({
|
|
|
967
925
|
{
|
|
968
926
|
className: cn(
|
|
969
927
|
getCellClasses(col),
|
|
928
|
+
headDensity,
|
|
970
929
|
col.sortable && "cursor-pointer select-none",
|
|
971
930
|
resizableColumns && "relative",
|
|
972
931
|
isFirstCol && "sticky left-0 bg-background",
|
|
@@ -998,7 +957,7 @@ function DataTable({
|
|
|
998
957
|
col.key
|
|
999
958
|
);
|
|
1000
959
|
}),
|
|
1001
|
-
renderActions && /* @__PURE__ */ jsx(TableHead, { className: "w-10" })
|
|
960
|
+
renderActions && /* @__PURE__ */ jsx(TableHead, { className: cn("w-10", headDensity) })
|
|
1002
961
|
] })
|
|
1003
962
|
}
|
|
1004
963
|
),
|
|
@@ -1018,13 +977,20 @@ function DataTable({
|
|
|
1018
977
|
"data-state": selected?.has(id) ? "selected" : void 0,
|
|
1019
978
|
onClick: onRowClick ? () => onRowClick(item) : void 0,
|
|
1020
979
|
children: [
|
|
1021
|
-
selectable && /* @__PURE__ */ jsx(
|
|
1022
|
-
|
|
980
|
+
selectable && /* @__PURE__ */ jsx(
|
|
981
|
+
TableCell,
|
|
1023
982
|
{
|
|
1024
|
-
|
|
1025
|
-
|
|
983
|
+
className: cellDensity,
|
|
984
|
+
onClick: (e) => e.stopPropagation(),
|
|
985
|
+
children: /* @__PURE__ */ jsx(
|
|
986
|
+
Checkbox,
|
|
987
|
+
{
|
|
988
|
+
checked: selected?.has(id),
|
|
989
|
+
onCheckedChange: () => onToggleSelect?.(id)
|
|
990
|
+
}
|
|
991
|
+
)
|
|
1026
992
|
}
|
|
1027
|
-
)
|
|
993
|
+
),
|
|
1028
994
|
activeColumns.map((col, colIndex) => {
|
|
1029
995
|
const acc = col.accessor || ((it) => it[col.key]);
|
|
1030
996
|
const value = acc(item);
|
|
@@ -1036,6 +1002,7 @@ function DataTable({
|
|
|
1036
1002
|
getCellClasses(
|
|
1037
1003
|
col
|
|
1038
1004
|
),
|
|
1005
|
+
cellDensity,
|
|
1039
1006
|
isFirstCol && "sticky left-0 z-[1] bg-background"
|
|
1040
1007
|
),
|
|
1041
1008
|
children: col.editable ? /* @__PURE__ */ jsx(
|
|
@@ -1050,7 +1017,14 @@ function DataTable({
|
|
|
1050
1017
|
col.key
|
|
1051
1018
|
);
|
|
1052
1019
|
}),
|
|
1053
|
-
renderActions && /* @__PURE__ */ jsx(
|
|
1020
|
+
renderActions && /* @__PURE__ */ jsx(
|
|
1021
|
+
TableCell,
|
|
1022
|
+
{
|
|
1023
|
+
className: cellDensity,
|
|
1024
|
+
onClick: (e) => e.stopPropagation(),
|
|
1025
|
+
children: renderActions(item)
|
|
1026
|
+
}
|
|
1027
|
+
)
|
|
1054
1028
|
]
|
|
1055
1029
|
},
|
|
1056
1030
|
id
|
|
@@ -1347,6 +1321,11 @@ var widthClasses = {
|
|
|
1347
1321
|
md: "w-96",
|
|
1348
1322
|
lg: "w-[480px]"
|
|
1349
1323
|
};
|
|
1324
|
+
var dialogMaxWidthClasses = {
|
|
1325
|
+
sm: "sm:max-w-sm",
|
|
1326
|
+
md: "sm:max-w-lg",
|
|
1327
|
+
lg: "sm:max-w-2xl"
|
|
1328
|
+
};
|
|
1350
1329
|
function keyToLabel(key) {
|
|
1351
1330
|
return key.replace(/_/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
1352
1331
|
}
|
|
@@ -1357,6 +1336,37 @@ function formatValue(value) {
|
|
|
1357
1336
|
if (typeof value === "object") return JSON.stringify(value);
|
|
1358
1337
|
return String(value);
|
|
1359
1338
|
}
|
|
1339
|
+
function renderTitleBlock(layout, title, subtitle) {
|
|
1340
|
+
const titleText = title || "Detail panel";
|
|
1341
|
+
if (layout === "dialog") {
|
|
1342
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1343
|
+
/* @__PURE__ */ jsx(DialogTitle, { className: cn("text-sm font-semibold truncate", !title && "sr-only"), children: titleText }),
|
|
1344
|
+
/* @__PURE__ */ jsx(
|
|
1345
|
+
DialogDescription,
|
|
1346
|
+
{
|
|
1347
|
+
className: cn("text-xs text-muted-foreground truncate", !subtitle && "sr-only"),
|
|
1348
|
+
children: subtitle || titleText
|
|
1349
|
+
}
|
|
1350
|
+
)
|
|
1351
|
+
] });
|
|
1352
|
+
}
|
|
1353
|
+
if (layout === "sheet") {
|
|
1354
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1355
|
+
/* @__PURE__ */ jsx(SheetTitle, { className: cn("text-sm font-semibold truncate", !title && "sr-only"), children: titleText }),
|
|
1356
|
+
/* @__PURE__ */ jsx(
|
|
1357
|
+
SheetDescription,
|
|
1358
|
+
{
|
|
1359
|
+
className: cn("text-xs text-muted-foreground truncate", !subtitle && "sr-only"),
|
|
1360
|
+
children: subtitle || titleText
|
|
1361
|
+
}
|
|
1362
|
+
)
|
|
1363
|
+
] });
|
|
1364
|
+
}
|
|
1365
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1366
|
+
title && /* @__PURE__ */ jsx("h2", { className: "text-sm font-semibold truncate", children: title }),
|
|
1367
|
+
subtitle && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground truncate", children: subtitle })
|
|
1368
|
+
] });
|
|
1369
|
+
}
|
|
1360
1370
|
function DetailPanel({
|
|
1361
1371
|
item,
|
|
1362
1372
|
open,
|
|
@@ -1367,7 +1377,8 @@ function DetailPanel({
|
|
|
1367
1377
|
onDelete,
|
|
1368
1378
|
children,
|
|
1369
1379
|
fields,
|
|
1370
|
-
width = "md"
|
|
1380
|
+
width = "md",
|
|
1381
|
+
layout = "sheet"
|
|
1371
1382
|
}) {
|
|
1372
1383
|
if (!open || !item) return null;
|
|
1373
1384
|
const renderContent = () => {
|
|
@@ -1392,78 +1403,114 @@ function DetailPanel({
|
|
|
1392
1403
|
] })
|
|
1393
1404
|
] }, key)) });
|
|
1394
1405
|
};
|
|
1395
|
-
|
|
1396
|
-
/* @__PURE__ */ jsx(
|
|
1397
|
-
|
|
1406
|
+
const header = /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 border-b border-border px-4 py-3", children: [
|
|
1407
|
+
/* @__PURE__ */ jsx("div", { className: "min-w-0", children: renderTitleBlock(layout, title, subtitle) }),
|
|
1408
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 shrink-0", children: [
|
|
1409
|
+
onEdit && /* @__PURE__ */ jsx(
|
|
1410
|
+
Button,
|
|
1411
|
+
{
|
|
1412
|
+
testID: "detail-panel-edit",
|
|
1413
|
+
variant: "ghost",
|
|
1414
|
+
size: "icon",
|
|
1415
|
+
className: "h-8 w-8",
|
|
1416
|
+
onClick: () => onEdit(item),
|
|
1417
|
+
"aria-label": "Edit",
|
|
1418
|
+
children: /* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4" })
|
|
1419
|
+
}
|
|
1420
|
+
),
|
|
1421
|
+
onDelete && /* @__PURE__ */ jsx(
|
|
1422
|
+
Button,
|
|
1423
|
+
{
|
|
1424
|
+
testID: "detail-panel-delete",
|
|
1425
|
+
variant: "ghost",
|
|
1426
|
+
size: "icon",
|
|
1427
|
+
className: "h-8 w-8 text-destructive hover:text-destructive",
|
|
1428
|
+
onClick: () => onDelete(item),
|
|
1429
|
+
"aria-label": "Delete",
|
|
1430
|
+
children: /* @__PURE__ */ jsx(Trash2, { className: "h-4 w-4" })
|
|
1431
|
+
}
|
|
1432
|
+
),
|
|
1433
|
+
/* @__PURE__ */ jsx(
|
|
1434
|
+
Button,
|
|
1435
|
+
{
|
|
1436
|
+
testID: "detail-panel-close",
|
|
1437
|
+
variant: "ghost",
|
|
1438
|
+
size: "icon",
|
|
1439
|
+
className: "h-8 w-8",
|
|
1440
|
+
onClick: onClose,
|
|
1441
|
+
"aria-label": "Close",
|
|
1442
|
+
children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
|
|
1443
|
+
}
|
|
1444
|
+
)
|
|
1445
|
+
] })
|
|
1446
|
+
] });
|
|
1447
|
+
const content = /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto px-4 py-3", children: renderContent() });
|
|
1448
|
+
if (layout === "dialog") {
|
|
1449
|
+
return /* @__PURE__ */ jsx(
|
|
1450
|
+
Dialog,
|
|
1398
1451
|
{
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1452
|
+
open,
|
|
1453
|
+
onOpenChange: (next) => {
|
|
1454
|
+
if (!next) onClose();
|
|
1455
|
+
},
|
|
1456
|
+
children: /* @__PURE__ */ jsxs(
|
|
1457
|
+
DialogContent,
|
|
1458
|
+
{
|
|
1459
|
+
showCloseButton: false,
|
|
1460
|
+
className: cn(
|
|
1461
|
+
"flex max-h-[85vh] flex-col gap-0 overflow-hidden p-0",
|
|
1462
|
+
dialogMaxWidthClasses[width]
|
|
1463
|
+
),
|
|
1464
|
+
children: [
|
|
1465
|
+
header,
|
|
1466
|
+
content
|
|
1467
|
+
]
|
|
1468
|
+
}
|
|
1469
|
+
)
|
|
1402
1470
|
}
|
|
1403
|
-
)
|
|
1404
|
-
|
|
1405
|
-
|
|
1471
|
+
);
|
|
1472
|
+
}
|
|
1473
|
+
if (layout === "sheet") {
|
|
1474
|
+
return /* @__PURE__ */ jsx(
|
|
1475
|
+
Sheet,
|
|
1406
1476
|
{
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
if (e.key === "Escape") onClose();
|
|
1477
|
+
open,
|
|
1478
|
+
onOpenChange: (next) => {
|
|
1479
|
+
if (!next) onClose();
|
|
1411
1480
|
},
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
onEdit && /* @__PURE__ */ jsx(
|
|
1428
|
-
Button,
|
|
1429
|
-
{
|
|
1430
|
-
variant: "ghost",
|
|
1431
|
-
size: "icon",
|
|
1432
|
-
className: "h-8 w-8",
|
|
1433
|
-
onClick: () => onEdit(item),
|
|
1434
|
-
"aria-label": "Edit",
|
|
1435
|
-
children: /* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4" })
|
|
1436
|
-
}
|
|
1437
|
-
),
|
|
1438
|
-
onDelete && /* @__PURE__ */ jsx(
|
|
1439
|
-
Button,
|
|
1440
|
-
{
|
|
1441
|
-
variant: "ghost",
|
|
1442
|
-
size: "icon",
|
|
1443
|
-
className: "h-8 w-8 text-destructive hover:text-destructive",
|
|
1444
|
-
onClick: () => onDelete(item),
|
|
1445
|
-
"aria-label": "Delete",
|
|
1446
|
-
children: /* @__PURE__ */ jsx(Trash2, { className: "h-4 w-4" })
|
|
1447
|
-
}
|
|
1448
|
-
),
|
|
1449
|
-
/* @__PURE__ */ jsx(
|
|
1450
|
-
Button,
|
|
1451
|
-
{
|
|
1452
|
-
variant: "ghost",
|
|
1453
|
-
size: "icon",
|
|
1454
|
-
className: "h-8 w-8",
|
|
1455
|
-
onClick: onClose,
|
|
1456
|
-
"aria-label": "Close",
|
|
1457
|
-
children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
|
|
1458
|
-
}
|
|
1459
|
-
)
|
|
1460
|
-
] })
|
|
1461
|
-
] }),
|
|
1462
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto px-4 py-3", children: renderContent() })
|
|
1463
|
-
]
|
|
1481
|
+
children: /* @__PURE__ */ jsxs(
|
|
1482
|
+
SheetContent,
|
|
1483
|
+
{
|
|
1484
|
+
side: "right",
|
|
1485
|
+
showCloseButton: false,
|
|
1486
|
+
className: cn(
|
|
1487
|
+
"flex flex-col gap-0 overflow-hidden p-0 max-w-[90vw] sm:max-w-[90vw]",
|
|
1488
|
+
widthClasses[width]
|
|
1489
|
+
),
|
|
1490
|
+
children: [
|
|
1491
|
+
header,
|
|
1492
|
+
content
|
|
1493
|
+
]
|
|
1494
|
+
}
|
|
1495
|
+
)
|
|
1464
1496
|
}
|
|
1465
|
-
)
|
|
1466
|
-
|
|
1497
|
+
);
|
|
1498
|
+
}
|
|
1499
|
+
return /* @__PURE__ */ jsxs(
|
|
1500
|
+
"div",
|
|
1501
|
+
{
|
|
1502
|
+
role: "region",
|
|
1503
|
+
"aria-label": title || "Detail panel",
|
|
1504
|
+
className: cn(
|
|
1505
|
+
"flex flex-col rounded-lg border border-border bg-card",
|
|
1506
|
+
widthClasses[width]
|
|
1507
|
+
),
|
|
1508
|
+
children: [
|
|
1509
|
+
header,
|
|
1510
|
+
content
|
|
1511
|
+
]
|
|
1512
|
+
}
|
|
1513
|
+
);
|
|
1467
1514
|
}
|
|
1468
1515
|
function RelationField({
|
|
1469
1516
|
field,
|
|
@@ -2389,13 +2436,19 @@ function ResourcePage(props) {
|
|
|
2389
2436
|
formSteps,
|
|
2390
2437
|
formLayout: formLayoutProp,
|
|
2391
2438
|
bulkActions,
|
|
2439
|
+
renderCard: renderCardProp,
|
|
2440
|
+
gridCols: gridColsProp,
|
|
2441
|
+
keyboardNavigation = true,
|
|
2392
2442
|
toolbar,
|
|
2393
2443
|
emptyState,
|
|
2394
2444
|
resourceOptions,
|
|
2395
2445
|
defaultView = "table",
|
|
2396
|
-
onNavigate = defaultNavigate
|
|
2446
|
+
onNavigate = defaultNavigate,
|
|
2447
|
+
viewSettingsKey: viewSettingsKeyProp
|
|
2397
2448
|
} = props;
|
|
2398
2449
|
const isClientMode = !!resourceName;
|
|
2450
|
+
const viewSettingsKey = viewSettingsKeyProp ?? resourceName ?? title.toLowerCase().replace(/\s+/g, "-");
|
|
2451
|
+
const { settings, updateSetting } = useViewSettings(viewSettingsKey);
|
|
2399
2452
|
const resourceHook = useResource(
|
|
2400
2453
|
resourceName ?? "__noop__",
|
|
2401
2454
|
isClientMode ? resourceOptions : { enabled: false }
|
|
@@ -2511,6 +2564,35 @@ function ResourcePage(props) {
|
|
|
2511
2564
|
}
|
|
2512
2565
|
page.handleRowClick(item);
|
|
2513
2566
|
};
|
|
2567
|
+
const hasBulkSelect = !!bulkActions && bulkActions.length > 0;
|
|
2568
|
+
const overlayOpen = page.detailOpen || formOpen;
|
|
2569
|
+
const keyboardNav = useKeyboardNavigation({
|
|
2570
|
+
itemCount: page.data.length,
|
|
2571
|
+
enabled: keyboardNavigation && page.viewMode !== "table",
|
|
2572
|
+
overlayOpen,
|
|
2573
|
+
onOpen: (index) => {
|
|
2574
|
+
const item = page.data[index];
|
|
2575
|
+
if (item) handleRowClick(item);
|
|
2576
|
+
},
|
|
2577
|
+
onToggleSelect: hasBulkSelect ? (index) => {
|
|
2578
|
+
const item = page.data[index];
|
|
2579
|
+
if (item) {
|
|
2580
|
+
handleToggleSelect(
|
|
2581
|
+
String(item.id ?? "")
|
|
2582
|
+
);
|
|
2583
|
+
}
|
|
2584
|
+
} : void 0,
|
|
2585
|
+
// Supplied only while there is an open detail to close — the hook
|
|
2586
|
+
// suppresses Backspace's default whenever this is present, so leaving it
|
|
2587
|
+
// wired up permanently would swallow the browser/app's Backspace on
|
|
2588
|
+
// every grid/list page (including detail="none" and detail="route",
|
|
2589
|
+
// which never open one). `detailOpen` is only ever true for the panel
|
|
2590
|
+
// and modal modes, so it is the precise precondition here.
|
|
2591
|
+
onBack: page.detailOpen ? () => {
|
|
2592
|
+
page.setDetailOpen(false);
|
|
2593
|
+
page.setSelectedItem(null);
|
|
2594
|
+
} : void 0
|
|
2595
|
+
});
|
|
2514
2596
|
const showCreateButton = onCreate || useBuiltInCreate;
|
|
2515
2597
|
const createButton = showCreateButton ? /* @__PURE__ */ jsxs(Button, { size: "sm", onClick: handleCreate, children: [
|
|
2516
2598
|
/* @__PURE__ */ jsx(Plus, { className: "h-4 w-4 mr-1" }),
|
|
@@ -2521,15 +2603,83 @@ function ResourcePage(props) {
|
|
|
2521
2603
|
createButton
|
|
2522
2604
|
] }) : void 0;
|
|
2523
2605
|
const isEmpty = !isLoading && !hasError && page.data.length === 0;
|
|
2524
|
-
const
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2606
|
+
const cardActionsFor = (item) => ({
|
|
2607
|
+
...actions,
|
|
2608
|
+
open: () => handleRowClick(item)
|
|
2609
|
+
});
|
|
2610
|
+
const rowActivationProps = (item, label, testId) => ({
|
|
2611
|
+
role: "button",
|
|
2612
|
+
tabIndex: 0,
|
|
2613
|
+
"aria-label": label || void 0,
|
|
2614
|
+
"data-testid": testId,
|
|
2615
|
+
onClick: () => handleRowClick(item),
|
|
2616
|
+
onKeyDown: (e) => {
|
|
2617
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
2618
|
+
e.preventDefault();
|
|
2619
|
+
handleRowClick(item);
|
|
2620
|
+
}
|
|
2621
|
+
}
|
|
2622
|
+
});
|
|
2623
|
+
const renderDefaultCard = (item) => {
|
|
2624
|
+
const cols = page.columns;
|
|
2625
|
+
const titleCol = cols[0];
|
|
2626
|
+
const titleVal = titleCol ? String(item[titleCol.key] ?? "") : "";
|
|
2627
|
+
const badgeCol = cols[1];
|
|
2628
|
+
const badgeVal = badgeCol ? item[badgeCol.key] : null;
|
|
2629
|
+
const priceCol = cols.find(
|
|
2630
|
+
(c, i) => i > 1 && /price|cost|amount|total/i.test(c.key)
|
|
2631
|
+
);
|
|
2632
|
+
const priceVal = priceCol ? item[priceCol.key] : null;
|
|
2633
|
+
const metaCols = cols.filter(
|
|
2634
|
+
(c) => c !== titleCol && c !== badgeCol && c !== priceCol
|
|
2635
|
+
);
|
|
2636
|
+
return /* @__PURE__ */ jsxs(
|
|
2637
|
+
Card,
|
|
2638
|
+
{
|
|
2639
|
+
...rowActivationProps(item, titleVal, "resource-card"),
|
|
2640
|
+
className: "h-full cursor-pointer hover:shadow-md motion-safe:transition-shadow focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
2641
|
+
children: [
|
|
2642
|
+
/* @__PURE__ */ jsx(CardHeader, { className: "pb-2", children: /* @__PURE__ */ jsx(CardTitle, { className: "text-base truncate", children: titleVal }) }),
|
|
2643
|
+
/* @__PURE__ */ jsx(CardContent, { children: /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
2644
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
2645
|
+
badgeCol && /* @__PURE__ */ jsx("span", { children: badgeCol.render ? badgeCol.render(item, badgeVal, actions) : badgeVal != null ? String(badgeVal) : "\u2014" }),
|
|
2646
|
+
priceVal != null && /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: String(priceVal) })
|
|
2647
|
+
] }),
|
|
2648
|
+
metaCols.map((col) => {
|
|
2649
|
+
const val = item[col.key];
|
|
2650
|
+
return /* @__PURE__ */ jsx(
|
|
2651
|
+
"p",
|
|
2652
|
+
{
|
|
2653
|
+
className: "text-xs text-muted-foreground truncate",
|
|
2654
|
+
children: col.render ? col.render(item, val, actions) : val != null ? String(val) : "\u2014"
|
|
2655
|
+
},
|
|
2656
|
+
col.key
|
|
2657
|
+
);
|
|
2658
|
+
})
|
|
2659
|
+
] }) })
|
|
2660
|
+
]
|
|
2661
|
+
}
|
|
2662
|
+
);
|
|
2663
|
+
};
|
|
2664
|
+
const renderDefaultListItem = (item) => {
|
|
2665
|
+
const cols = page.columns;
|
|
2666
|
+
const titleCol = cols[0];
|
|
2667
|
+
const titleVal = titleCol ? String(item[titleCol.key] ?? "") : "";
|
|
2668
|
+
return /* @__PURE__ */ jsxs(
|
|
2669
|
+
"div",
|
|
2670
|
+
{
|
|
2671
|
+
...rowActivationProps(item, titleVal, "resource-list-row"),
|
|
2672
|
+
className: "flex items-center justify-between px-3 py-2 border-b cursor-pointer hover:bg-muted/50 motion-safe:transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring",
|
|
2673
|
+
children: [
|
|
2674
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-sm truncate", children: titleVal }),
|
|
2675
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-3 text-xs text-muted-foreground", children: cols.slice(1, 4).map((col) => {
|
|
2676
|
+
const val = item[col.key];
|
|
2677
|
+
return /* @__PURE__ */ jsx("span", { children: col.render ? col.render(item, val, actions) : val != null ? String(val) : "\u2014" }, col.key);
|
|
2678
|
+
}) })
|
|
2679
|
+
]
|
|
2680
|
+
}
|
|
2681
|
+
);
|
|
2682
|
+
};
|
|
2533
2683
|
return /* @__PURE__ */ jsxs(
|
|
2534
2684
|
DataPageShell,
|
|
2535
2685
|
{
|
|
@@ -2544,6 +2694,10 @@ function ResourcePage(props) {
|
|
|
2544
2694
|
onRetry: isClientMode ? () => resourceHook.list.refetch() : void 0,
|
|
2545
2695
|
viewMode: page.viewMode,
|
|
2546
2696
|
onViewModeChange: page.setViewMode,
|
|
2697
|
+
pageSize: settings.pageSize,
|
|
2698
|
+
onPageSizeChange: (size) => updateSetting("pageSize", size),
|
|
2699
|
+
density: settings.density,
|
|
2700
|
+
onDensityChange: (d) => updateSetting("density", d),
|
|
2547
2701
|
createAction,
|
|
2548
2702
|
hasActiveFilters: page.hasActiveFilters,
|
|
2549
2703
|
onClearFilters: page.clearFilters,
|
|
@@ -2584,7 +2738,10 @@ function ResourcePage(props) {
|
|
|
2584
2738
|
{
|
|
2585
2739
|
items: page.data,
|
|
2586
2740
|
viewMode: page.viewMode,
|
|
2741
|
+
gridCols: gridColsProp,
|
|
2587
2742
|
getKey: (item) => String(item.id ?? ""),
|
|
2743
|
+
focusedIndex: keyboardNav.focusedIndex,
|
|
2744
|
+
keyboardContainerRef: keyboardNav.containerRef,
|
|
2588
2745
|
renderTable: (items) => /* @__PURE__ */ jsx(
|
|
2589
2746
|
DataTable,
|
|
2590
2747
|
{
|
|
@@ -2595,72 +2752,16 @@ function ResourcePage(props) {
|
|
|
2595
2752
|
selectable: !!bulkActions && bulkActions.length > 0,
|
|
2596
2753
|
selected: selectedIds,
|
|
2597
2754
|
onToggleSelect: handleToggleSelect,
|
|
2598
|
-
onToggleAll: handleToggleAll
|
|
2755
|
+
onToggleAll: handleToggleAll,
|
|
2756
|
+
density: settings.density,
|
|
2757
|
+
pageSize: settings.pageSize
|
|
2599
2758
|
}
|
|
2600
2759
|
),
|
|
2601
|
-
renderCard: (item) =>
|
|
2602
|
-
|
|
2603
|
-
const titleCol = cols[0];
|
|
2604
|
-
const titleVal = titleCol ? String(item[titleCol.key] ?? "") : "";
|
|
2605
|
-
const badgeCol = cols[1];
|
|
2606
|
-
const badgeVal = badgeCol ? item[badgeCol.key] : null;
|
|
2607
|
-
const priceCol = cols.find(
|
|
2608
|
-
(c, i) => i > 1 && /price|cost|amount|total/i.test(c.key)
|
|
2609
|
-
);
|
|
2610
|
-
const priceVal = priceCol ? item[priceCol.key] : null;
|
|
2611
|
-
const metaCols = cols.filter(
|
|
2612
|
-
(c) => c !== titleCol && c !== badgeCol && c !== priceCol
|
|
2613
|
-
);
|
|
2614
|
-
return /* @__PURE__ */ jsxs(
|
|
2615
|
-
Card,
|
|
2616
|
-
{
|
|
2617
|
-
className: "h-full cursor-pointer hover:shadow-md transition-shadow",
|
|
2618
|
-
onClick: () => handleRowClick(item),
|
|
2619
|
-
children: [
|
|
2620
|
-
/* @__PURE__ */ jsx(CardHeader, { className: "pb-2", children: /* @__PURE__ */ jsx(CardTitle, { className: "text-base truncate", children: titleVal }) }),
|
|
2621
|
-
/* @__PURE__ */ jsx(CardContent, { children: /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
2622
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
2623
|
-
badgeCol && /* @__PURE__ */ jsx("span", { children: badgeCol.render ? badgeCol.render(item, badgeVal, actions) : badgeVal != null ? String(badgeVal) : "\u2014" }),
|
|
2624
|
-
priceVal != null && /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: String(priceVal) })
|
|
2625
|
-
] }),
|
|
2626
|
-
metaCols.map((col) => {
|
|
2627
|
-
const val = item[col.key];
|
|
2628
|
-
return /* @__PURE__ */ jsx(
|
|
2629
|
-
"p",
|
|
2630
|
-
{
|
|
2631
|
-
className: "text-xs text-muted-foreground truncate",
|
|
2632
|
-
children: col.render ? col.render(item, val, actions) : val != null ? String(val) : "\u2014"
|
|
2633
|
-
},
|
|
2634
|
-
col.key
|
|
2635
|
-
);
|
|
2636
|
-
})
|
|
2637
|
-
] }) })
|
|
2638
|
-
]
|
|
2639
|
-
}
|
|
2640
|
-
);
|
|
2641
|
-
},
|
|
2642
|
-
renderListItem: (item) => {
|
|
2643
|
-
const cols = page.columns;
|
|
2644
|
-
const titleCol = cols[0];
|
|
2645
|
-
const titleVal = titleCol ? String(item[titleCol.key] ?? "") : "";
|
|
2646
|
-
return /* @__PURE__ */ jsxs(
|
|
2647
|
-
"div",
|
|
2648
|
-
{
|
|
2649
|
-
className: "flex items-center justify-between px-3 py-2 border-b cursor-pointer hover:bg-muted/50 transition-colors",
|
|
2650
|
-
onClick: () => handleRowClick(item),
|
|
2651
|
-
children: [
|
|
2652
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium text-sm truncate", children: titleVal }),
|
|
2653
|
-
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-3 text-xs text-muted-foreground", children: cols.slice(1, 4).map((col) => {
|
|
2654
|
-
const val = item[col.key];
|
|
2655
|
-
return /* @__PURE__ */ jsx("span", { children: col.render ? col.render(item, val, actions) : val != null ? String(val) : "\u2014" }, col.key);
|
|
2656
|
-
}) })
|
|
2657
|
-
]
|
|
2658
|
-
}
|
|
2659
|
-
);
|
|
2660
|
-
}
|
|
2760
|
+
renderCard: (item, index) => renderCardProp ? renderCardProp(item, index, cardActionsFor(item)) : renderDefaultCard(item),
|
|
2761
|
+
renderListItem: (item, index) => renderCardProp ? renderCardProp(item, index, cardActionsFor(item)) : renderDefaultListItem(item)
|
|
2661
2762
|
}
|
|
2662
2763
|
),
|
|
2663
|
-
detail === "panel" && /* @__PURE__ */ jsx(
|
|
2764
|
+
(detail === "panel" || detail === "modal") && /* @__PURE__ */ jsx(
|
|
2664
2765
|
DetailPanel,
|
|
2665
2766
|
{
|
|
2666
2767
|
item: page.selectedItem,
|
|
@@ -2675,48 +2776,10 @@ function ResourcePage(props) {
|
|
|
2675
2776
|
onDelete,
|
|
2676
2777
|
fields: detailFields,
|
|
2677
2778
|
width: detailWidth,
|
|
2779
|
+
layout: detail === "modal" ? "dialog" : "sheet",
|
|
2678
2780
|
children: renderDetailProp ? (item) => renderDetailProp(item) : void 0
|
|
2679
2781
|
}
|
|
2680
2782
|
),
|
|
2681
|
-
detail === "modal" && /* @__PURE__ */ jsx(
|
|
2682
|
-
Dialog,
|
|
2683
|
-
{
|
|
2684
|
-
open: page.detailOpen,
|
|
2685
|
-
onOpenChange: (open) => {
|
|
2686
|
-
page.setDetailOpen(open);
|
|
2687
|
-
if (!open) page.setSelectedItem(null);
|
|
2688
|
-
},
|
|
2689
|
-
children: /* @__PURE__ */ jsxs(DialogContent, { children: [
|
|
2690
|
-
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
2691
|
-
/* @__PURE__ */ jsx(DialogTitle, { children: detailTitle }),
|
|
2692
|
-
detailSubtitle && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: detailSubtitle })
|
|
2693
|
-
] }),
|
|
2694
|
-
/* @__PURE__ */ jsxs("div", { className: "py-4", children: [
|
|
2695
|
-
modalDetailContent,
|
|
2696
|
-
(onEdit || useBuiltInEdit || onDelete) && page.selectedItem && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mt-4 pt-4 border-t", children: [
|
|
2697
|
-
(onEdit || useBuiltInEdit) && /* @__PURE__ */ jsx(
|
|
2698
|
-
Button,
|
|
2699
|
-
{
|
|
2700
|
-
variant: "outline",
|
|
2701
|
-
size: "sm",
|
|
2702
|
-
onClick: () => handleEdit(page.selectedItem),
|
|
2703
|
-
children: "Edit"
|
|
2704
|
-
}
|
|
2705
|
-
),
|
|
2706
|
-
onDelete && /* @__PURE__ */ jsx(
|
|
2707
|
-
Button,
|
|
2708
|
-
{
|
|
2709
|
-
variant: "destructive",
|
|
2710
|
-
size: "sm",
|
|
2711
|
-
onClick: () => onDelete(page.selectedItem),
|
|
2712
|
-
children: "Delete"
|
|
2713
|
-
}
|
|
2714
|
-
)
|
|
2715
|
-
] })
|
|
2716
|
-
] })
|
|
2717
|
-
] })
|
|
2718
|
-
}
|
|
2719
|
-
),
|
|
2720
2783
|
(useBuiltInCreate || useBuiltInEdit) && resourceName && /* @__PURE__ */ jsx(
|
|
2721
2784
|
ResourceForm,
|
|
2722
2785
|
{
|
|
@@ -2743,178 +2806,80 @@ function ResourcePage(props) {
|
|
|
2743
2806
|
}
|
|
2744
2807
|
);
|
|
2745
2808
|
}
|
|
2746
|
-
function
|
|
2747
|
-
const [
|
|
2748
|
-
|
|
2749
|
-
const stored = localStorage.getItem("theme");
|
|
2750
|
-
const prefersDark = window.matchMedia(
|
|
2751
|
-
"(prefers-color-scheme: dark)"
|
|
2752
|
-
).matches;
|
|
2753
|
-
const isDark = stored === "dark" || !stored && prefersDark;
|
|
2754
|
-
setDark(isDark);
|
|
2755
|
-
document.documentElement.classList.toggle("dark", isDark);
|
|
2756
|
-
}, []);
|
|
2757
|
-
function toggle() {
|
|
2758
|
-
const next = !dark;
|
|
2759
|
-
setDark(next);
|
|
2760
|
-
document.documentElement.classList.toggle("dark", next);
|
|
2761
|
-
localStorage.setItem("theme", next ? "dark" : "light");
|
|
2762
|
-
}
|
|
2763
|
-
return /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon", onClick: toggle, className: "h-8 w-8", children: dark ? /* @__PURE__ */ jsx(Sun, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(Moon, { className: "h-4 w-4" }) });
|
|
2809
|
+
function pick(record, field) {
|
|
2810
|
+
const value = field ? record[field] : record.name ?? record.title ?? record.id;
|
|
2811
|
+
return value == null ? "" : String(value);
|
|
2764
2812
|
}
|
|
2765
|
-
function
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
}
|
|
2772
|
-
|
|
2773
|
-
const active = isActive(item.to, activePath);
|
|
2774
|
-
return /* @__PURE__ */ jsxs(
|
|
2775
|
-
LinkComp,
|
|
2776
|
-
{
|
|
2777
|
-
href: item.to,
|
|
2778
|
-
onClick: onNavClick,
|
|
2779
|
-
"aria-current": active ? "page" : void 0,
|
|
2780
|
-
className: cn(
|
|
2781
|
-
"flex items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium transition-colors",
|
|
2782
|
-
active ? "bg-sidebar-accent text-sidebar-primary" : "text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground"
|
|
2783
|
-
),
|
|
2784
|
-
children: [
|
|
2785
|
-
/* @__PURE__ */ jsx(item.icon, { className: "h-4 w-4" }),
|
|
2786
|
-
item.label
|
|
2787
|
-
]
|
|
2788
|
-
},
|
|
2789
|
-
item.to
|
|
2790
|
-
);
|
|
2791
|
-
}) });
|
|
2813
|
+
function NotFound() {
|
|
2814
|
+
return /* @__PURE__ */ jsx(
|
|
2815
|
+
EmptyState,
|
|
2816
|
+
{
|
|
2817
|
+
title: "Not found",
|
|
2818
|
+
description: "This record no longer exists, or you don't have access to it."
|
|
2819
|
+
}
|
|
2820
|
+
);
|
|
2792
2821
|
}
|
|
2793
|
-
function
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2798
|
-
appLogo && /* @__PURE__ */ jsx("div", { className: "h-7 w-7 rounded-lg bg-primary flex items-center justify-center", children: /* @__PURE__ */ jsx("span", { className: "text-primary-foreground text-sm font-bold", children: appLogo }) }),
|
|
2799
|
-
/* @__PURE__ */ jsx("span", { className: "font-semibold text-sidebar-foreground", children: appName })
|
|
2800
|
-
] });
|
|
2822
|
+
function isNotFoundError(error) {
|
|
2823
|
+
if (!(error instanceof Error)) return false;
|
|
2824
|
+
if (error.code === "PGRST116") return true;
|
|
2825
|
+
return /\[MockProvider\] Record not found/i.test(error.message) || /switchboard-data-provider: no ".*" row with id/i.test(error.message);
|
|
2801
2826
|
}
|
|
2802
|
-
function
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2827
|
+
function ResourceDetailPage({
|
|
2828
|
+
resource,
|
|
2829
|
+
id,
|
|
2830
|
+
titleField,
|
|
2831
|
+
subtitleField,
|
|
2832
|
+
select,
|
|
2833
|
+
breadcrumb,
|
|
2834
|
+
actions,
|
|
2835
|
+
sidebar,
|
|
2806
2836
|
children,
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
activePath,
|
|
2810
|
-
isActive = isPathActive
|
|
2837
|
+
className,
|
|
2838
|
+
testID
|
|
2811
2839
|
}) {
|
|
2812
|
-
const
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
"div",
|
|
2829
|
-
{
|
|
2830
|
-
className: "fixed inset-0 z-40 bg-black/50 md:hidden",
|
|
2831
|
-
onClick: () => setMobileOpen(false)
|
|
2832
|
-
}
|
|
2833
|
-
),
|
|
2834
|
-
/* @__PURE__ */ jsxs(
|
|
2835
|
-
"aside",
|
|
2840
|
+
const { data, isLoading, isError, error } = useOne(resource, id, {
|
|
2841
|
+
select,
|
|
2842
|
+
// `useOne` defaults to `enabled: !!id`, which is wrong for a numeric
|
|
2843
|
+
// primary key: id `0` is falsy, so the query would never run and the page
|
|
2844
|
+
// would report a record that exists as missing, without ever asking the
|
|
2845
|
+
// provider. `Identifier` is `string | number`, so this is reachable.
|
|
2846
|
+
// Presence is the question, not truthiness.
|
|
2847
|
+
enabled: id != null
|
|
2848
|
+
});
|
|
2849
|
+
if (id == null || isLoading) {
|
|
2850
|
+
return /* @__PURE__ */ jsx(PageLoading, { testID: testID ? `${testID}-loading` : void 0 });
|
|
2851
|
+
}
|
|
2852
|
+
if (isError) {
|
|
2853
|
+
if (isNotFoundError(error)) return /* @__PURE__ */ jsx(NotFound, {});
|
|
2854
|
+
return /* @__PURE__ */ jsx(
|
|
2855
|
+
EmptyState,
|
|
2836
2856
|
{
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
),
|
|
2841
|
-
children: [
|
|
2842
|
-
/* @__PURE__ */ jsxs("div", { className: "flex h-14 items-center justify-between px-4 border-b border-sidebar-border", children: [
|
|
2843
|
-
/* @__PURE__ */ jsx(SidebarLogo, { appName, appLogo }),
|
|
2844
|
-
/* @__PURE__ */ jsx(
|
|
2845
|
-
Button,
|
|
2846
|
-
{
|
|
2847
|
-
variant: "ghost",
|
|
2848
|
-
size: "icon",
|
|
2849
|
-
onClick: () => setMobileOpen(false),
|
|
2850
|
-
children: /* @__PURE__ */ jsx(X, { className: "h-5 w-5" })
|
|
2851
|
-
}
|
|
2852
|
-
)
|
|
2853
|
-
] }),
|
|
2854
|
-
/* @__PURE__ */ jsx(
|
|
2855
|
-
SidebarNav,
|
|
2856
|
-
{
|
|
2857
|
-
navItems,
|
|
2858
|
-
onNavClick: () => setMobileOpen(false),
|
|
2859
|
-
linkComponent,
|
|
2860
|
-
activePath,
|
|
2861
|
-
isActive
|
|
2862
|
-
}
|
|
2863
|
-
)
|
|
2864
|
-
]
|
|
2857
|
+
icon: AlertTriangle,
|
|
2858
|
+
title: "Couldn't load this record",
|
|
2859
|
+
description: error instanceof Error ? error.message : void 0
|
|
2865
2860
|
}
|
|
2866
|
-
)
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
/* @__PURE__ */ jsx("nav", { className: "fixed bottom-0 left-0 right-0 z-30 flex border-t bg-background md:hidden", children: navItems.map((item) => {
|
|
2883
|
-
const LinkComp = linkComponent;
|
|
2884
|
-
const active = isActive(item.to, activePath);
|
|
2885
|
-
return /* @__PURE__ */ jsxs(
|
|
2886
|
-
LinkComp,
|
|
2887
|
-
{
|
|
2888
|
-
href: item.to,
|
|
2889
|
-
"aria-current": active ? "page" : void 0,
|
|
2890
|
-
className: cn(
|
|
2891
|
-
"flex flex-1 flex-col items-center gap-1 py-2 text-xs font-medium transition-colors",
|
|
2892
|
-
active ? "text-primary" : "text-muted-foreground"
|
|
2893
|
-
),
|
|
2894
|
-
children: [
|
|
2895
|
-
/* @__PURE__ */ jsx(item.icon, { className: "h-5 w-5" }),
|
|
2896
|
-
item.label
|
|
2897
|
-
]
|
|
2898
|
-
},
|
|
2899
|
-
item.to
|
|
2900
|
-
);
|
|
2901
|
-
}) })
|
|
2902
|
-
] })
|
|
2903
|
-
] });
|
|
2904
|
-
}
|
|
2905
|
-
function PageHeader({ title, subtitle, icon: Icon, actions }) {
|
|
2906
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between", children: [
|
|
2907
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 min-w-0", children: [
|
|
2908
|
-
Icon && /* @__PURE__ */ jsx("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-primary/10 overflow-hidden", children: /* @__PURE__ */ jsx(Icon, { className: "h-5 w-5 text-primary" }) }),
|
|
2909
|
-
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
2910
|
-
/* @__PURE__ */ jsx("h1", { className: "text-xl sm:text-2xl font-bold font-display tracking-tight truncate", children: title }),
|
|
2911
|
-
subtitle && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground truncate", children: subtitle })
|
|
2912
|
-
] })
|
|
2913
|
-
] }),
|
|
2914
|
-
actions && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2 shrink-0", children: actions })
|
|
2915
|
-
] });
|
|
2861
|
+
);
|
|
2862
|
+
}
|
|
2863
|
+
if (!data) return /* @__PURE__ */ jsx(NotFound, {});
|
|
2864
|
+
return /* @__PURE__ */ jsx(
|
|
2865
|
+
DetailPage,
|
|
2866
|
+
{
|
|
2867
|
+
className,
|
|
2868
|
+
testID,
|
|
2869
|
+
breadcrumb,
|
|
2870
|
+
title: pick(data, titleField),
|
|
2871
|
+
subtitle: subtitleField ? pick(data, subtitleField) : void 0,
|
|
2872
|
+
actions: actions?.(data),
|
|
2873
|
+
sidebar: sidebar?.(data),
|
|
2874
|
+
children: children(data)
|
|
2875
|
+
}
|
|
2876
|
+
);
|
|
2916
2877
|
}
|
|
2917
2878
|
|
|
2918
|
-
|
|
2879
|
+
// src/components/data/index.ts
|
|
2880
|
+
var AppShell2 = AppShell;
|
|
2881
|
+
var PageHeader2 = PageHeader;
|
|
2882
|
+
|
|
2883
|
+
export { AppShell2 as AppShell, BadgeCell, CurrencyCell, DataBulkBar, DataFilters, DataGrid, DataList, DataPageShell, DataTable, DateCell, DetailPanel, FieldArrayRenderer, FileUploadField, FilterCombobox, KanbanBoard, LinkCell, NumberCell, PageHeader2 as PageHeader, RelationField, ResourceDetailPage, ResourceForm, ResourcePage, StatCard, ThumbnailCell, WizardForm };
|
|
2919
2884
|
//# sourceMappingURL=index.js.map
|
|
2920
2885
|
//# sourceMappingURL=index.js.map
|