@arqel-dev/ui 0.17.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/dist/ArqelCreatePage-SUQTG7LF.js +9 -0
  2. package/dist/{ArqelCreatePage-UZAHV4DK.js.map → ArqelCreatePage-SUQTG7LF.js.map} +1 -1
  3. package/dist/ArqelEditPage-TC6CY66H.js +13 -0
  4. package/dist/{ArqelEditPage-7OFWPULE.js.map → ArqelEditPage-TC6CY66H.js.map} +1 -1
  5. package/dist/ArqelIndexPage-3DPWRK2Q.js +15 -0
  6. package/dist/{ArqelIndexPage-ZAVCCM6V.js.map → ArqelIndexPage-3DPWRK2Q.js.map} +1 -1
  7. package/dist/ArqelNotificationsPage-VCNRIN6A.js +7 -0
  8. package/dist/ArqelNotificationsPage-VCNRIN6A.js.map +1 -0
  9. package/dist/{UserMenu-B5XbC_Gy.d.ts → UserMenu-QlwvvZRU.d.ts} +2 -1
  10. package/dist/action.js +5 -4
  11. package/dist/{chunk-7NGUPQON.js → chunk-4XV35QZA.js} +5 -5
  12. package/dist/{chunk-7NGUPQON.js.map → chunk-4XV35QZA.js.map} +1 -1
  13. package/dist/{chunk-GJ2FKAOM.js → chunk-5ETNGNVM.js} +17 -4
  14. package/dist/chunk-5ETNGNVM.js.map +1 -0
  15. package/dist/chunk-6YGRTXEL.js +87 -0
  16. package/dist/chunk-6YGRTXEL.js.map +1 -0
  17. package/dist/chunk-CZUV5WCY.js +3 -0
  18. package/dist/chunk-CZUV5WCY.js.map +1 -0
  19. package/dist/{chunk-K7QY56XN.js → chunk-D2MUCHFN.js} +5 -119
  20. package/dist/chunk-D2MUCHFN.js.map +1 -0
  21. package/dist/{chunk-DO3PRGVV.js → chunk-FVKM6FDW.js} +3 -3
  22. package/dist/{chunk-DO3PRGVV.js.map → chunk-FVKM6FDW.js.map} +1 -1
  23. package/dist/{chunk-KGAY2AZH.js → chunk-HOJEO5LX.js} +3 -3
  24. package/dist/{chunk-KGAY2AZH.js.map → chunk-HOJEO5LX.js.map} +1 -1
  25. package/dist/chunk-NFP2EB7Y.js +137 -0
  26. package/dist/chunk-NFP2EB7Y.js.map +1 -0
  27. package/dist/{chunk-DOQUHQND.js → chunk-P64TZA7T.js} +4 -4
  28. package/dist/{chunk-DOQUHQND.js.map → chunk-P64TZA7T.js.map} +1 -1
  29. package/dist/{chunk-WKIYS2FQ.js → chunk-RKWHRD75.js} +53 -10
  30. package/dist/chunk-RKWHRD75.js.map +1 -0
  31. package/dist/{chunk-MZMYV43C.js → chunk-SVCWLDZ4.js} +3 -3
  32. package/dist/{chunk-MZMYV43C.js.map → chunk-SVCWLDZ4.js.map} +1 -1
  33. package/dist/{chunk-YEPQWAD6.js → chunk-TBDWW6L5.js} +3 -3
  34. package/dist/{chunk-YEPQWAD6.js.map → chunk-TBDWW6L5.js.map} +1 -1
  35. package/dist/chunk-U4MPY2XT.js +91 -0
  36. package/dist/chunk-U4MPY2XT.js.map +1 -0
  37. package/dist/{chunk-3E66JNQO.js → chunk-VO5KYIHC.js} +3 -30
  38. package/dist/chunk-VO5KYIHC.js.map +1 -0
  39. package/dist/{chunk-IO6RMVUF.js → chunk-WXPBHB7R.js} +3 -3
  40. package/dist/{chunk-IO6RMVUF.js.map → chunk-WXPBHB7R.js.map} +1 -1
  41. package/dist/chunk-XK2P6CSK.js +8 -0
  42. package/dist/chunk-XK2P6CSK.js.map +1 -0
  43. package/dist/{chunk-X2X6YDOX.js → chunk-YDUL7HFU.js} +16 -4
  44. package/dist/chunk-YDUL7HFU.js.map +1 -0
  45. package/dist/{chunk-H23VX3RR.js → chunk-YF2RINPG.js} +2 -2
  46. package/dist/{chunk-H23VX3RR.js.map → chunk-YF2RINPG.js.map} +1 -1
  47. package/dist/{chunk-53J74IYR.js → chunk-ZZKWQO3W.js} +30 -3
  48. package/dist/chunk-ZZKWQO3W.js.map +1 -0
  49. package/dist/flash.d.ts +2 -1
  50. package/dist/flash.js +2 -1
  51. package/dist/form.js +3 -2
  52. package/dist/index.d.ts +1 -1
  53. package/dist/index.js +14 -12
  54. package/dist/pages.d.ts +26 -1
  55. package/dist/pages.js +18 -14
  56. package/dist/pages.js.map +1 -1
  57. package/dist/primitives.js +3 -2
  58. package/dist/resource.js +4 -3
  59. package/dist/shell.d.ts +37 -3
  60. package/dist/shell.js +169 -8
  61. package/dist/shell.js.map +1 -1
  62. package/dist/table.js +3 -2
  63. package/dist/utility.js +2 -2
  64. package/dist/utils.d.ts +16 -1
  65. package/dist/utils.js +1 -0
  66. package/package.json +6 -6
  67. package/dist/ArqelCreatePage-UZAHV4DK.js +0 -8
  68. package/dist/ArqelEditPage-7OFWPULE.js +0 -12
  69. package/dist/ArqelIndexPage-ZAVCCM6V.js +0 -14
  70. package/dist/chunk-3E66JNQO.js.map +0 -1
  71. package/dist/chunk-53J74IYR.js.map +0 -1
  72. package/dist/chunk-GJ2FKAOM.js.map +0 -1
  73. package/dist/chunk-K7QY56XN.js.map +0 -1
  74. package/dist/chunk-R4BOUU6Y.js +0 -55
  75. package/dist/chunk-R4BOUU6Y.js.map +0 -1
  76. package/dist/chunk-WKIYS2FQ.js.map +0 -1
  77. package/dist/chunk-X2X6YDOX.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/shadcn/ui/alert.tsx","../src/shadcn/ui/checkbox.tsx","../src/shadcn/ui/label.tsx","../src/shadcn/ui/field.tsx","../src/shadcn/ui/select.tsx","../src/shadcn/ui/textarea.tsx"],"names":["jsx","CheckboxPrimitive","LabelPrimitive","cva","SelectPrimitive","jsxs","CheckIcon"],"mappings":"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","file":"chunk-D2MUCHFN.js","sourcesContent":["import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/utils/cn\"\n\nconst alertVariants = cva(\n \"relative grid w-full grid-cols-[0_1fr] items-start gap-y-0.5 rounded-lg border px-4 py-3 text-sm has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] has-[>svg]:gap-x-3 [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current\",\n {\n variants: {\n variant: {\n default: \"bg-card text-card-foreground\",\n destructive:\n \"bg-card text-destructive *:data-[slot=alert-description]:text-destructive/90 [&>svg]:text-current\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nfunction Alert({\n className,\n variant,\n ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof alertVariants>) {\n return (\n <div\n data-slot=\"alert\"\n role=\"alert\"\n className={cn(alertVariants({ variant }), className)}\n {...props}\n />\n )\n}\n\nfunction AlertTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-title\"\n className={cn(\n \"col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction AlertDescription({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"alert-description\"\n className={cn(\n \"col-start-2 grid justify-items-start gap-1 text-sm text-muted-foreground [&_p]:leading-relaxed\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Alert, AlertTitle, AlertDescription }\n","import * as React from \"react\"\nimport { CheckIcon } from \"lucide-react\"\nimport { Checkbox as CheckboxPrimitive } from \"radix-ui\"\n\nimport { cn } from \"@/utils/cn\"\n\nfunction Checkbox({\n className,\n ...props\n}: React.ComponentProps<typeof CheckboxPrimitive.Root>) {\n return (\n <CheckboxPrimitive.Root\n data-slot=\"checkbox\"\n className={cn(\n \"peer size-4 shrink-0 rounded-[4px] border border-input shadow-xs transition-shadow outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:bg-input/30 dark:aria-invalid:ring-destructive/40 dark:data-[state=checked]:bg-primary\",\n className\n )}\n {...props}\n >\n <CheckboxPrimitive.Indicator\n data-slot=\"checkbox-indicator\"\n className=\"grid place-content-center text-current transition-none\"\n >\n <CheckIcon className=\"size-3.5\" />\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n )\n}\n\nexport { Checkbox }\n","import * as React from \"react\"\nimport { Label as LabelPrimitive } from \"radix-ui\"\n\nimport { cn } from \"@/utils/cn\"\n\nfunction Label({\n className,\n ...props\n}: React.ComponentProps<typeof LabelPrimitive.Root>) {\n return (\n <LabelPrimitive.Root\n data-slot=\"label\"\n className={cn(\n \"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Label }\n","import { useMemo } from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/utils/cn\"\nimport { Label } from \"@/shadcn/ui/label\"\nimport { Separator } from \"@/shadcn/ui/separator\"\n\nfunction FieldSet({ className, ...props }: React.ComponentProps<\"fieldset\">) {\n return (\n <fieldset\n data-slot=\"field-set\"\n className={cn(\n \"flex flex-col gap-6\",\n \"has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction FieldLegend({\n className,\n variant = \"legend\",\n ...props\n}: React.ComponentProps<\"legend\"> & { variant?: \"legend\" | \"label\" }) {\n return (\n <legend\n data-slot=\"field-legend\"\n data-variant={variant}\n className={cn(\n \"mb-3 font-medium\",\n \"data-[variant=legend]:text-base\",\n \"data-[variant=label]:text-sm\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction FieldGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"field-group\"\n className={cn(\n \"group/field-group @container/field-group flex w-full flex-col gap-7 data-[slot=checkbox-group]:gap-3 [&>[data-slot=field-group]]:gap-4\",\n className\n )}\n {...props}\n />\n )\n}\n\nconst fieldVariants = cva(\n \"group/field flex w-full gap-3 data-[invalid=true]:text-destructive\",\n {\n variants: {\n orientation: {\n vertical: [\"flex-col [&>*]:w-full [&>.sr-only]:w-auto\"],\n horizontal: [\n \"flex-row items-center\",\n \"[&>[data-slot=field-label]]:flex-auto\",\n \"has-[>[data-slot=field-content]]:items-start has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px\",\n ],\n responsive: [\n \"flex-col @md/field-group:flex-row @md/field-group:items-center [&>*]:w-full @md/field-group:[&>*]:w-auto [&>.sr-only]:w-auto\",\n \"@md/field-group:[&>[data-slot=field-label]]:flex-auto\",\n \"@md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px\",\n ],\n },\n },\n defaultVariants: {\n orientation: \"vertical\",\n },\n }\n)\n\nfunction Field({\n className,\n orientation = \"vertical\",\n ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof fieldVariants>) {\n return (\n <div\n role=\"group\"\n data-slot=\"field\"\n data-orientation={orientation}\n className={cn(fieldVariants({ orientation }), className)}\n {...props}\n />\n )\n}\n\nfunction FieldContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"field-content\"\n className={cn(\n \"group/field-content flex flex-1 flex-col gap-1.5 leading-snug\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction FieldLabel({\n className,\n ...props\n}: React.ComponentProps<typeof Label>) {\n return (\n <Label\n data-slot=\"field-label\"\n className={cn(\n \"group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50\",\n \"has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border [&>*]:data-[slot=field]:p-4\",\n \"has-data-[state=checked]:border-primary has-data-[state=checked]:bg-primary/5 dark:has-data-[state=checked]:bg-primary/10\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction FieldTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"field-label\"\n className={cn(\n \"flex w-fit items-center gap-2 text-sm leading-snug font-medium group-data-[disabled=true]/field:opacity-50\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction FieldDescription({ className, ...props }: React.ComponentProps<\"p\">) {\n return (\n <p\n data-slot=\"field-description\"\n className={cn(\n \"text-sm leading-normal font-normal text-muted-foreground group-has-[[data-orientation=horizontal]]/field:text-balance\",\n \"last:mt-0 nth-last-2:-mt-1 [[data-variant=legend]+&]:-mt-1.5\",\n \"[&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction FieldSeparator({\n children,\n className,\n ...props\n}: React.ComponentProps<\"div\"> & {\n children?: React.ReactNode\n}) {\n return (\n <div\n data-slot=\"field-separator\"\n data-content={!!children}\n className={cn(\n \"relative -my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2\",\n className\n )}\n {...props}\n >\n <Separator className=\"absolute inset-0 top-1/2\" />\n {children && (\n <span\n className=\"relative mx-auto block w-fit bg-background px-2 text-muted-foreground\"\n data-slot=\"field-separator-content\"\n >\n {children}\n </span>\n )}\n </div>\n )\n}\n\nfunction FieldError({\n className,\n children,\n errors,\n ...props\n}: React.ComponentProps<\"div\"> & {\n errors?: Array<{ message?: string } | undefined>\n}) {\n const content = useMemo(() => {\n if (children) {\n return children\n }\n\n if (!errors?.length) {\n return null\n }\n\n const uniqueErrors = [\n ...new Map(errors.map((error) => [error?.message, error])).values(),\n ]\n\n if (uniqueErrors?.length == 1) {\n return uniqueErrors[0]?.message\n }\n\n return (\n <ul className=\"ml-4 flex list-disc flex-col gap-1\">\n {uniqueErrors.map(\n (error, index) =>\n error?.message && <li key={index}>{error.message}</li>\n )}\n </ul>\n )\n }, [children, errors])\n\n if (!content) {\n return null\n }\n\n return (\n <div\n role=\"alert\"\n data-slot=\"field-error\"\n className={cn(\"text-sm font-normal text-destructive\", className)}\n {...props}\n >\n {content}\n </div>\n )\n}\n\nexport {\n Field,\n FieldLabel,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLegend,\n FieldSeparator,\n FieldSet,\n FieldContent,\n FieldTitle,\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from \"lucide-react\"\nimport { Select as SelectPrimitive } from \"radix-ui\"\n\nimport { cn } from \"@/utils/cn\"\n\nfunction Select({\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Root>) {\n return <SelectPrimitive.Root data-slot=\"select\" {...props} />\n}\n\nfunction SelectGroup({\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Group>) {\n return <SelectPrimitive.Group data-slot=\"select-group\" {...props} />\n}\n\nfunction SelectValue({\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Value>) {\n return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />\n}\n\nfunction SelectTrigger({\n className,\n size = \"default\",\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {\n size?: \"sm\" | \"default\"\n}) {\n return (\n <SelectPrimitive.Trigger\n data-slot=\"select-trigger\"\n data-size={size}\n className={cn(\n \"flex w-fit items-center justify-between gap-2 rounded-md border border-input bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[placeholder]:text-muted-foreground data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground\",\n className\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDownIcon className=\"size-4 opacity-50\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n )\n}\n\nfunction SelectContent({\n className,\n children,\n position = \"item-aligned\",\n align = \"center\",\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Content>) {\n return (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n data-slot=\"select-content\"\n className={cn(\n \"relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border bg-popover text-popover-foreground shadow-md data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95\",\n position === \"popper\" &&\n \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n className\n )}\n position={position}\n align={align}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.Viewport\n className={cn(\n \"p-1\",\n position === \"popper\" &&\n \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1\"\n )}\n >\n {children}\n </SelectPrimitive.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n )\n}\n\nfunction SelectLabel({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Label>) {\n return (\n <SelectPrimitive.Label\n data-slot=\"select-label\"\n className={cn(\"px-2 py-1.5 text-xs text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nfunction SelectItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Item>) {\n return (\n <SelectPrimitive.Item\n data-slot=\"select-item\"\n className={cn(\n \"relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n className\n )}\n {...props}\n >\n <span\n data-slot=\"select-item-indicator\"\n className=\"absolute right-2 flex size-3.5 items-center justify-center\"\n >\n <SelectPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n )\n}\n\nfunction SelectSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Separator>) {\n return (\n <SelectPrimitive.Separator\n data-slot=\"select-separator\"\n className={cn(\"pointer-events-none -mx-1 my-1 h-px bg-border\", className)}\n {...props}\n />\n )\n}\n\nfunction SelectScrollUpButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n return (\n <SelectPrimitive.ScrollUpButton\n data-slot=\"select-scroll-up-button\"\n className={cn(\n \"flex cursor-default items-center justify-center py-1\",\n className\n )}\n {...props}\n >\n <ChevronUpIcon className=\"size-4\" />\n </SelectPrimitive.ScrollUpButton>\n )\n}\n\nfunction SelectScrollDownButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n return (\n <SelectPrimitive.ScrollDownButton\n data-slot=\"select-scroll-down-button\"\n className={cn(\n \"flex cursor-default items-center justify-center py-1\",\n className\n )}\n {...props}\n >\n <ChevronDownIcon className=\"size-4\" />\n </SelectPrimitive.ScrollDownButton>\n )\n}\n\nexport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectScrollDownButton,\n SelectScrollUpButton,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n}\n","import * as React from \"react\"\n\nimport { cn } from \"@/utils/cn\"\n\nfunction Textarea({ className, ...props }: React.ComponentProps<\"textarea\">) {\n return (\n <textarea\n data-slot=\"textarea\"\n className={cn(\n \"flex field-sizing-content min-h-16 w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:aria-invalid:ring-destructive/40\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Textarea }\n"]}
@@ -1,4 +1,4 @@
1
- import { Button } from './chunk-H23VX3RR.js';
1
+ import { Button } from './chunk-YF2RINPG.js';
2
2
  import { cn } from './chunk-B7ULUJVO.js';
3
3
  import { useArqelTranslations } from '@arqel-dev/react/utils';
4
4
  import { useState, useEffect } from 'react';
@@ -194,5 +194,5 @@ function ConfirmDialog({
194
194
  }
195
195
 
196
196
  export { ConfirmDialog, Dialog, DialogClose, DialogContent, DialogHeader, DialogTitle };
197
- //# sourceMappingURL=chunk-DO3PRGVV.js.map
198
- //# sourceMappingURL=chunk-DO3PRGVV.js.map
197
+ //# sourceMappingURL=chunk-FVKM6FDW.js.map
198
+ //# sourceMappingURL=chunk-FVKM6FDW.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/shadcn/ui/dialog.tsx","../src/action/ConfirmDialog.tsx"],"names":["DialogPrimitive","jsx","jsxs"],"mappings":"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","file":"chunk-DO3PRGVV.js","sourcesContent":["import * as React from \"react\"\nimport { XIcon } from \"lucide-react\"\nimport { Dialog as DialogPrimitive } from \"radix-ui\"\n\nimport { cn } from \"@/utils/cn\"\nimport { Button } from \"@/shadcn/ui/button\"\n\nfunction Dialog({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Root>) {\n return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />\n}\n\nfunction DialogTrigger({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {\n return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />\n}\n\nfunction DialogPortal({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Portal>) {\n return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />\n}\n\nfunction DialogClose({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Close>) {\n return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />\n}\n\nfunction DialogOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n return (\n <DialogPrimitive.Overlay\n data-slot=\"dialog-overlay\"\n className={cn(\n \"fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DialogContent({\n className,\n children,\n showCloseButton = true,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Content> & {\n showCloseButton?: boolean\n}) {\n return (\n <DialogPortal data-slot=\"dialog-portal\">\n <DialogOverlay />\n <DialogPrimitive.Content\n data-slot=\"dialog-content\"\n className={cn(\n \"fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadow-lg duration-200 outline-none data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 sm:max-w-lg\",\n className\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <DialogPrimitive.Close\n data-slot=\"dialog-close\"\n className=\"absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\"\n >\n <XIcon />\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n )}\n </DialogPrimitive.Content>\n </DialogPortal>\n )\n}\n\nfunction DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-header\"\n className={cn(\"flex flex-col gap-2 text-center sm:text-left\", className)}\n {...props}\n />\n )\n}\n\nfunction DialogFooter({\n className,\n showCloseButton = false,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n showCloseButton?: boolean\n}) {\n return (\n <div\n data-slot=\"dialog-footer\"\n className={cn(\n \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n className\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <DialogPrimitive.Close asChild>\n <Button variant=\"outline\">Close</Button>\n </DialogPrimitive.Close>\n )}\n </div>\n )\n}\n\nfunction DialogTitle({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Title>) {\n return (\n <DialogPrimitive.Title\n data-slot=\"dialog-title\"\n className={cn(\"text-lg leading-none font-semibold\", className)}\n {...props}\n />\n )\n}\n\nfunction DialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Description>) {\n return (\n <DialogPrimitive.Description\n data-slot=\"dialog-description\"\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n}\n","/**\n * `<ConfirmDialog>` — confirmation modal driven by the shadcn (Radix) Dialog.\n *\n * Phase 1 supports the canonical `ConfirmationConfig`:\n * - heading / description\n * - color (destructive | warning | info) — drives submit button variant\n * - submit / cancel labels\n * - \"type to confirm\" via `requiresText` (submit stays disabled until\n * the typed value matches exactly)\n *\n * Keyboard: Escape cancels (Radix built-in dismiss); Enter inside the\n * type-to-confirm input fires confirm when the value matches.\n */\n\nimport { useArqelTranslations } from '@arqel-dev/react/utils';\nimport type { ConfirmationConfig } from '@arqel-dev/types/actions';\nimport { useEffect, useState } from 'react';\nimport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '../shadcn/ui/dialog.js';\nimport { Button, type ButtonProps } from './Button.js';\n\nexport interface ConfirmDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n config?: ConfirmationConfig | undefined;\n onConfirm: () => void;\n processing?: boolean;\n}\n\nconst COLOR_VARIANT: Record<NonNullable<ConfirmationConfig['color']>, ButtonProps['variant']> = {\n destructive: 'destructive',\n warning: 'default',\n info: 'default',\n};\n\nexport function ConfirmDialog({\n open,\n onOpenChange,\n config,\n onConfirm,\n processing = false,\n}: ConfirmDialogProps) {\n const t = useArqelTranslations();\n const [typed, setTyped] = useState('');\n\n useEffect(() => {\n if (!open) setTyped('');\n }, [open]);\n\n const requiresText = config?.requiresText;\n const submitDisabled = processing || (requiresText !== undefined && typed !== requiresText);\n const variant = COLOR_VARIANT[config?.color ?? 'destructive'];\n // Precedence: explicit config > shared translation > English fallback.\n const submitLabel =\n config?.submitLabel ??\n (config?.color === 'info'\n ? t('arqel.actions.confirm', 'Confirm')\n : t('arqel.actions.delete', 'Delete'));\n const cancelLabel = config?.cancelLabel ?? t('arqel.actions.cancel', 'Cancel');\n\n return (\n <Dialog open={open} onOpenChange={(next) => onOpenChange(next)}>\n <DialogContent className=\"sm:max-w-[28rem]\" showCloseButton={false}>\n <DialogHeader>\n <DialogTitle>\n {config?.heading ?? t('arqel.messages.delete_confirm', 'Are you sure?')}\n </DialogTitle>\n {config?.description && <DialogDescription>{config.description}</DialogDescription>}\n </DialogHeader>\n {requiresText !== undefined && (\n <label className=\"flex flex-col gap-1 text-xs text-muted-foreground\">\n <span>\n {(() => {\n // Render the required value as inline <code> while keeping the\n // surrounding prompt translatable: split the localized string on\n // its :value placeholder and splice the <code> element in.\n const [before, after] = t(\n 'arqel.messages.type_to_confirm',\n 'Type :value to confirm',\n ).split(':value');\n return (\n <>\n {before}\n <code className=\"font-mono text-foreground\">{requiresText}</code>\n {after}\n </>\n );\n })()}\n </span>\n <input\n type=\"text\"\n ref={(el) => el?.focus()}\n value={typed}\n onChange={(e) => setTyped(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !submitDisabled) {\n e.preventDefault();\n onConfirm();\n }\n }}\n className=\"h-9 rounded-md border border-input bg-background px-3 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n />\n </label>\n )}\n <DialogFooter>\n <DialogClose asChild>\n <Button type=\"button\" variant=\"ghost\" disabled={processing}>\n {cancelLabel}\n </Button>\n </DialogClose>\n <Button type=\"button\" variant={variant} disabled={submitDisabled} onClick={onConfirm}>\n {processing ? t('form.saving', 'Working…') : submitLabel}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/shadcn/ui/dialog.tsx","../src/action/ConfirmDialog.tsx"],"names":["DialogPrimitive","jsx","jsxs"],"mappings":"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","file":"chunk-FVKM6FDW.js","sourcesContent":["import * as React from \"react\"\nimport { XIcon } from \"lucide-react\"\nimport { Dialog as DialogPrimitive } from \"radix-ui\"\n\nimport { cn } from \"@/utils/cn\"\nimport { Button } from \"@/shadcn/ui/button\"\n\nfunction Dialog({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Root>) {\n return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />\n}\n\nfunction DialogTrigger({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {\n return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />\n}\n\nfunction DialogPortal({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Portal>) {\n return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />\n}\n\nfunction DialogClose({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Close>) {\n return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />\n}\n\nfunction DialogOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n return (\n <DialogPrimitive.Overlay\n data-slot=\"dialog-overlay\"\n className={cn(\n \"fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DialogContent({\n className,\n children,\n showCloseButton = true,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Content> & {\n showCloseButton?: boolean\n}) {\n return (\n <DialogPortal data-slot=\"dialog-portal\">\n <DialogOverlay />\n <DialogPrimitive.Content\n data-slot=\"dialog-content\"\n className={cn(\n \"fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadow-lg duration-200 outline-none data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 sm:max-w-lg\",\n className\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <DialogPrimitive.Close\n data-slot=\"dialog-close\"\n className=\"absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\"\n >\n <XIcon />\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n )}\n </DialogPrimitive.Content>\n </DialogPortal>\n )\n}\n\nfunction DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-header\"\n className={cn(\"flex flex-col gap-2 text-center sm:text-left\", className)}\n {...props}\n />\n )\n}\n\nfunction DialogFooter({\n className,\n showCloseButton = false,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n showCloseButton?: boolean\n}) {\n return (\n <div\n data-slot=\"dialog-footer\"\n className={cn(\n \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n className\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <DialogPrimitive.Close asChild>\n <Button variant=\"outline\">Close</Button>\n </DialogPrimitive.Close>\n )}\n </div>\n )\n}\n\nfunction DialogTitle({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Title>) {\n return (\n <DialogPrimitive.Title\n data-slot=\"dialog-title\"\n className={cn(\"text-lg leading-none font-semibold\", className)}\n {...props}\n />\n )\n}\n\nfunction DialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Description>) {\n return (\n <DialogPrimitive.Description\n data-slot=\"dialog-description\"\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n}\n","/**\n * `<ConfirmDialog>` — confirmation modal driven by the shadcn (Radix) Dialog.\n *\n * Phase 1 supports the canonical `ConfirmationConfig`:\n * - heading / description\n * - color (destructive | warning | info) — drives submit button variant\n * - submit / cancel labels\n * - \"type to confirm\" via `requiresText` (submit stays disabled until\n * the typed value matches exactly)\n *\n * Keyboard: Escape cancels (Radix built-in dismiss); Enter inside the\n * type-to-confirm input fires confirm when the value matches.\n */\n\nimport { useArqelTranslations } from '@arqel-dev/react/utils';\nimport type { ConfirmationConfig } from '@arqel-dev/types/actions';\nimport { useEffect, useState } from 'react';\nimport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '../shadcn/ui/dialog.js';\nimport { Button, type ButtonProps } from './Button.js';\n\nexport interface ConfirmDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n config?: ConfirmationConfig | undefined;\n onConfirm: () => void;\n processing?: boolean;\n}\n\nconst COLOR_VARIANT: Record<NonNullable<ConfirmationConfig['color']>, ButtonProps['variant']> = {\n destructive: 'destructive',\n warning: 'default',\n info: 'default',\n};\n\nexport function ConfirmDialog({\n open,\n onOpenChange,\n config,\n onConfirm,\n processing = false,\n}: ConfirmDialogProps) {\n const t = useArqelTranslations();\n const [typed, setTyped] = useState('');\n\n useEffect(() => {\n if (!open) setTyped('');\n }, [open]);\n\n const requiresText = config?.requiresText;\n const submitDisabled = processing || (requiresText !== undefined && typed !== requiresText);\n const variant = COLOR_VARIANT[config?.color ?? 'destructive'];\n // Precedence: explicit config > shared translation > English fallback.\n const submitLabel =\n config?.submitLabel ??\n (config?.color === 'info'\n ? t('arqel.actions.confirm', 'Confirm')\n : t('arqel.actions.delete', 'Delete'));\n const cancelLabel = config?.cancelLabel ?? t('arqel.actions.cancel', 'Cancel');\n\n return (\n <Dialog open={open} onOpenChange={(next) => onOpenChange(next)}>\n <DialogContent className=\"sm:max-w-[28rem]\" showCloseButton={false}>\n <DialogHeader>\n <DialogTitle>\n {config?.heading ?? t('arqel.messages.delete_confirm', 'Are you sure?')}\n </DialogTitle>\n {config?.description && <DialogDescription>{config.description}</DialogDescription>}\n </DialogHeader>\n {requiresText !== undefined && (\n <label className=\"flex flex-col gap-1 text-xs text-muted-foreground\">\n <span>\n {(() => {\n // Render the required value as inline <code> while keeping the\n // surrounding prompt translatable: split the localized string on\n // its :value placeholder and splice the <code> element in.\n const [before, after] = t(\n 'arqel.messages.type_to_confirm',\n 'Type :value to confirm',\n ).split(':value');\n return (\n <>\n {before}\n <code className=\"font-mono text-foreground\">{requiresText}</code>\n {after}\n </>\n );\n })()}\n </span>\n <input\n type=\"text\"\n ref={(el) => el?.focus()}\n value={typed}\n onChange={(e) => setTyped(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !submitDisabled) {\n e.preventDefault();\n onConfirm();\n }\n }}\n className=\"h-9 rounded-md border border-input bg-background px-3 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n />\n </label>\n )}\n <DialogFooter>\n <DialogClose asChild>\n <Button type=\"button\" variant=\"ghost\" disabled={processing}>\n {cancelLabel}\n </Button>\n </DialogClose>\n <Button type=\"button\" variant={variant} disabled={submitDisabled} onClick={onConfirm}>\n {processing ? t('form.saving', 'Working…') : submitLabel}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { TableToolbar, TableFilters, TablePagination } from './chunk-YEPQWAD6.js';
1
+ import { TableToolbar, TableFilters, TablePagination } from './chunk-TBDWW6L5.js';
2
2
  import { DataTable } from './chunk-JKD6SE75.js';
3
3
  import { cn } from './chunk-B7ULUJVO.js';
4
4
  import { useArqelTranslations } from '@arqel-dev/react/utils';
@@ -116,5 +116,5 @@ function ResourceIndex({
116
116
  }
117
117
 
118
118
  export { ResourceIndex };
119
- //# sourceMappingURL=chunk-KGAY2AZH.js.map
120
- //# sourceMappingURL=chunk-KGAY2AZH.js.map
119
+ //# sourceMappingURL=chunk-HOJEO5LX.js.map
120
+ //# sourceMappingURL=chunk-HOJEO5LX.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/resource/ResourceIndex.tsx"],"names":[],"mappings":"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","file":"chunk-KGAY2AZH.js","sourcesContent":["/**\n * `<ResourceIndex>` — page-level wrapper for index/listing routes.\n *\n * Wires `ResourceIndexProps` (server payload) into the table stack:\n * header (title + toolbar actions + create button)\n * → TableToolbar (search + filters + bulk bar)\n * → DataTable (with selection, sorting, row actions)\n * → TablePagination\n *\n * The component is presentational — selection / sort / page transitions\n * are lifted to props so the same shell can be reused by ResourceIndex\n * (Inertia-driven) and dashboard widgets (memory-driven).\n */\n\nimport { useArqelTranslations } from '@arqel-dev/react/utils';\nimport type { RecordType, ResourceIndexProps as ServerProps } from '@arqel-dev/types/resources';\nimport type { SortDirection, TableSort } from '@arqel-dev/types/tables';\nimport type { ReactNode } from 'react';\nimport { DataTable } from '../table/DataTable.js';\nimport { TableFilters } from '../table/TableFilters.js';\nimport { TablePagination } from '../table/TablePagination.js';\nimport { TableToolbar } from '../table/TableToolbar.js';\nimport { cn } from '../utils/cn.js';\n\ntype RowId = string | number;\n\nexport interface ResourceIndexUIProps<TRecord extends RecordType = RecordType>\n extends ServerProps<TRecord> {\n selectedIds?: ReadonlyArray<RowId>;\n onSelectionChange?: (ids: RowId[]) => void;\n onSortChange?: (column: string, direction: SortDirection) => void;\n onPageChange?: (page: number) => void;\n onPerPageChange?: (perPage: number) => void;\n onSearchChange?: (search: string) => void;\n onFilterChange?: (name: string, value: unknown) => void;\n onClearFilters?: () => void;\n\n filterValues?: Record<string, unknown>;\n\n searchSlot?: ReactNode;\n toolbarActions?: ReactNode;\n rowActions?: (record: TRecord) => ReactNode;\n bulkActions?: ReactNode;\n emptyState?: ReactNode;\n\n loading?: boolean;\n className?: string;\n}\n\nexport function ResourceIndex<TRecord extends RecordType = RecordType>({\n resource,\n records,\n pagination,\n columns,\n filters,\n search,\n sort,\n selectedIds = [],\n filterValues = {},\n onSelectionChange,\n onSortChange,\n onPageChange,\n onPerPageChange,\n onSearchChange,\n onFilterChange,\n onClearFilters,\n searchSlot,\n toolbarActions,\n rowActions,\n bulkActions,\n emptyState,\n loading = false,\n className,\n}: ResourceIndexUIProps<TRecord>) {\n const t = useArqelTranslations();\n const enableSelection = Boolean(onSelectionChange);\n\n const renderSearch = (): ReactNode => {\n if (searchSlot) return searchSlot;\n if (!onSearchChange) return null;\n return (\n <label className=\"flex flex-col gap-1 text-xs text-muted-foreground\">\n {t('table.search.label', 'Search')}\n <input\n type=\"search\"\n placeholder={t(\n 'table.search.placeholder_for',\n `Search ${resource.pluralLabel.toLowerCase()}…`,\n { resource: resource.pluralLabel.toLowerCase() },\n )}\n // 44px touch target on mobile (WCAG 2.5.5); dense 36px on >=md.\n className=\"h-11 w-64 rounded-sm border border-[var(--input)] bg-background px-3 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring md:h-9\"\n value={search ?? ''}\n onChange={(e) => onSearchChange(e.target.value)}\n />\n </label>\n );\n };\n\n const normalisedSort: TableSort | null = sort?.column\n ? {\n column: sort.column,\n direction: sort.direction === 'desc' ? 'desc' : 'asc',\n }\n : null;\n\n return (\n <section\n className={cn(\n 'flex min-w-0 flex-col rounded-md border border-border bg-background',\n className,\n )}\n aria-label={resource.pluralLabel}\n >\n <header className=\"flex flex-wrap items-center gap-3 border-b border-border px-4 py-3\">\n <h1 className=\"text-lg font-semibold\">{resource.pluralLabel}</h1>\n <div className=\"ml-auto flex flex-wrap items-center gap-2\">{toolbarActions}</div>\n </header>\n\n <TableToolbar\n search={renderSearch()}\n filters={\n filters.length > 0 ? (\n <TableFilters\n filters={filters}\n values={filterValues}\n onChange={(name, value) => onFilterChange?.(name, value)}\n onClearAll={onClearFilters}\n />\n ) : null\n }\n selectedCount={selectedIds.length}\n bulkActions={bulkActions}\n onClearSelection={onSelectionChange ? () => onSelectionChange([]) : undefined}\n />\n\n <DataTable\n columns={columns}\n records={records as unknown as Array<{ id: RowId } & TRecord>}\n enableSelection={enableSelection}\n selectedIds={selectedIds}\n onSelectionChange={onSelectionChange}\n sort={normalisedSort}\n onSortChange={onSortChange}\n rowActions={rowActions ? (record) => rowActions(record as TRecord) : undefined}\n loading={loading}\n emptyState={emptyState}\n />\n\n {pagination && (\n <TablePagination\n meta={pagination}\n onPageChange={(page) => onPageChange?.(page)}\n onPerPageChange={onPerPageChange}\n />\n )}\n </section>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/resource/ResourceIndex.tsx"],"names":[],"mappings":"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","file":"chunk-HOJEO5LX.js","sourcesContent":["/**\n * `<ResourceIndex>` — page-level wrapper for index/listing routes.\n *\n * Wires `ResourceIndexProps` (server payload) into the table stack:\n * header (title + toolbar actions + create button)\n * → TableToolbar (search + filters + bulk bar)\n * → DataTable (with selection, sorting, row actions)\n * → TablePagination\n *\n * The component is presentational — selection / sort / page transitions\n * are lifted to props so the same shell can be reused by ResourceIndex\n * (Inertia-driven) and dashboard widgets (memory-driven).\n */\n\nimport { useArqelTranslations } from '@arqel-dev/react/utils';\nimport type { RecordType, ResourceIndexProps as ServerProps } from '@arqel-dev/types/resources';\nimport type { SortDirection, TableSort } from '@arqel-dev/types/tables';\nimport type { ReactNode } from 'react';\nimport { DataTable } from '../table/DataTable.js';\nimport { TableFilters } from '../table/TableFilters.js';\nimport { TablePagination } from '../table/TablePagination.js';\nimport { TableToolbar } from '../table/TableToolbar.js';\nimport { cn } from '../utils/cn.js';\n\ntype RowId = string | number;\n\nexport interface ResourceIndexUIProps<TRecord extends RecordType = RecordType>\n extends ServerProps<TRecord> {\n selectedIds?: ReadonlyArray<RowId>;\n onSelectionChange?: (ids: RowId[]) => void;\n onSortChange?: (column: string, direction: SortDirection) => void;\n onPageChange?: (page: number) => void;\n onPerPageChange?: (perPage: number) => void;\n onSearchChange?: (search: string) => void;\n onFilterChange?: (name: string, value: unknown) => void;\n onClearFilters?: () => void;\n\n filterValues?: Record<string, unknown>;\n\n searchSlot?: ReactNode;\n toolbarActions?: ReactNode;\n rowActions?: (record: TRecord) => ReactNode;\n bulkActions?: ReactNode;\n emptyState?: ReactNode;\n\n loading?: boolean;\n className?: string;\n}\n\nexport function ResourceIndex<TRecord extends RecordType = RecordType>({\n resource,\n records,\n pagination,\n columns,\n filters,\n search,\n sort,\n selectedIds = [],\n filterValues = {},\n onSelectionChange,\n onSortChange,\n onPageChange,\n onPerPageChange,\n onSearchChange,\n onFilterChange,\n onClearFilters,\n searchSlot,\n toolbarActions,\n rowActions,\n bulkActions,\n emptyState,\n loading = false,\n className,\n}: ResourceIndexUIProps<TRecord>) {\n const t = useArqelTranslations();\n const enableSelection = Boolean(onSelectionChange);\n\n const renderSearch = (): ReactNode => {\n if (searchSlot) return searchSlot;\n if (!onSearchChange) return null;\n return (\n <label className=\"flex flex-col gap-1 text-xs text-muted-foreground\">\n {t('table.search.label', 'Search')}\n <input\n type=\"search\"\n placeholder={t(\n 'table.search.placeholder_for',\n `Search ${resource.pluralLabel.toLowerCase()}…`,\n { resource: resource.pluralLabel.toLowerCase() },\n )}\n // 44px touch target on mobile (WCAG 2.5.5); dense 36px on >=md.\n className=\"h-11 w-64 rounded-sm border border-[var(--input)] bg-background px-3 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring md:h-9\"\n value={search ?? ''}\n onChange={(e) => onSearchChange(e.target.value)}\n />\n </label>\n );\n };\n\n const normalisedSort: TableSort | null = sort?.column\n ? {\n column: sort.column,\n direction: sort.direction === 'desc' ? 'desc' : 'asc',\n }\n : null;\n\n return (\n <section\n className={cn(\n 'flex min-w-0 flex-col rounded-md border border-border bg-background',\n className,\n )}\n aria-label={resource.pluralLabel}\n >\n <header className=\"flex flex-wrap items-center gap-3 border-b border-border px-4 py-3\">\n <h1 className=\"text-lg font-semibold\">{resource.pluralLabel}</h1>\n <div className=\"ml-auto flex flex-wrap items-center gap-2\">{toolbarActions}</div>\n </header>\n\n <TableToolbar\n search={renderSearch()}\n filters={\n filters.length > 0 ? (\n <TableFilters\n filters={filters}\n values={filterValues}\n onChange={(name, value) => onFilterChange?.(name, value)}\n onClearAll={onClearFilters}\n />\n ) : null\n }\n selectedCount={selectedIds.length}\n bulkActions={bulkActions}\n onClearSelection={onSelectionChange ? () => onSelectionChange([]) : undefined}\n />\n\n <DataTable\n columns={columns}\n records={records as unknown as Array<{ id: RowId } & TRecord>}\n enableSelection={enableSelection}\n selectedIds={selectedIds}\n onSelectionChange={onSelectionChange}\n sort={normalisedSort}\n onSortChange={onSortChange}\n rowActions={rowActions ? (record) => rowActions(record as TRecord) : undefined}\n loading={loading}\n emptyState={emptyState}\n />\n\n {pagination && (\n <TablePagination\n meta={pagination}\n onPageChange={(page) => onPageChange?.(page)}\n onPerPageChange={onPerPageChange}\n />\n )}\n </section>\n );\n}\n"]}
@@ -0,0 +1,137 @@
1
+ import { Card } from './chunk-6YGRTXEL.js';
2
+ import { Button } from './chunk-YF2RINPG.js';
3
+ import { cn } from './chunk-B7ULUJVO.js';
4
+ import { useArqelTranslations } from '@arqel-dev/react/utils';
5
+ import { usePage, Link, router } from '@inertiajs/react';
6
+ import { jsxs, jsx } from 'react/jsx-runtime';
7
+
8
+ function readTitle(item) {
9
+ const title = item.data["title"];
10
+ if (typeof title === "string" && title.trim()) return title;
11
+ return item.type;
12
+ }
13
+ function readBody(item) {
14
+ const body = item.data["body"] ?? item.data["message"];
15
+ return typeof body === "string" && body.trim() ? body : void 0;
16
+ }
17
+ function markRead(id) {
18
+ router.post(
19
+ `/admin/notifications/${id}/read`,
20
+ {},
21
+ { preserveScroll: true, only: ["history", "notifications"] }
22
+ );
23
+ }
24
+ function markAllRead() {
25
+ router.post(
26
+ "/admin/notifications/read-all",
27
+ {},
28
+ { preserveScroll: true, only: ["history", "notifications"] }
29
+ );
30
+ }
31
+ function destroy(id) {
32
+ router.delete(`/admin/notifications/${id}`, { preserveScroll: true });
33
+ }
34
+ function decodePaginationLabel(label) {
35
+ return label.replace(/&laquo;/g, "\xAB").replace(/&raquo;/g, "\xBB");
36
+ }
37
+ function ArqelNotificationsPage() {
38
+ const t = useArqelTranslations();
39
+ const { history, filter } = usePage().props;
40
+ const items = history.data;
41
+ const hasUnread = items.some((item) => item.read_at === null);
42
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 p-4", children: [
43
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [
44
+ /* @__PURE__ */ jsx("h1", { className: "text-lg font-semibold", children: t("arqel.notifications.title", "Notifications") }),
45
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
46
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 text-sm", children: [
47
+ /* @__PURE__ */ jsx(
48
+ Link,
49
+ {
50
+ href: "/admin/notifications?filter=all",
51
+ className: cn(
52
+ "rounded-sm px-2 py-1",
53
+ filter === "all" ? "bg-accent font-medium text-accent-foreground" : "text-muted-foreground hover:text-foreground"
54
+ ),
55
+ children: t("arqel.notifications.filter_all", "All")
56
+ }
57
+ ),
58
+ /* @__PURE__ */ jsx(
59
+ Link,
60
+ {
61
+ href: "/admin/notifications?filter=unread",
62
+ className: cn(
63
+ "rounded-sm px-2 py-1",
64
+ filter === "unread" ? "bg-accent font-medium text-accent-foreground" : "text-muted-foreground hover:text-foreground"
65
+ ),
66
+ children: t("arqel.notifications.filter_unread", "Unread")
67
+ }
68
+ )
69
+ ] }),
70
+ hasUnread && /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", onClick: markAllRead, children: t("arqel.notifications.mark_all_read", "Mark all as read") })
71
+ ] })
72
+ ] }),
73
+ items.length === 0 ? /* @__PURE__ */ jsx(Card, { className: "p-6 text-center text-sm text-muted-foreground", children: t("arqel.notifications.empty", "No notifications") }) : /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: items.map((item) => {
74
+ const title = readTitle(item);
75
+ const body = readBody(item);
76
+ const unread = item.read_at === null;
77
+ return /* @__PURE__ */ jsxs(
78
+ Card,
79
+ {
80
+ className: cn(
81
+ "flex flex-row items-start justify-between gap-4 p-4",
82
+ unread && "bg-accent/50"
83
+ ),
84
+ children: [
85
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 items-start gap-2", children: [
86
+ /* @__PURE__ */ jsx(
87
+ "span",
88
+ {
89
+ "aria-hidden": "true",
90
+ className: cn(
91
+ "mt-1.5 h-1.5 w-1.5 shrink-0 rounded-full",
92
+ unread ? "bg-primary" : "bg-transparent"
93
+ )
94
+ }
95
+ ),
96
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col", children: [
97
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: title }),
98
+ body && /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: body }),
99
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: item.created_at })
100
+ ] })
101
+ ] }),
102
+ /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [
103
+ unread && /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", onClick: () => markRead(item.id), children: t("arqel.notifications.mark_read", "Mark as read") }),
104
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: () => destroy(item.id), children: t("arqel.notifications.delete", "Delete") })
105
+ ] })
106
+ ]
107
+ },
108
+ item.id
109
+ );
110
+ }) }),
111
+ history.links.length > 0 && /* @__PURE__ */ jsx(
112
+ "nav",
113
+ {
114
+ className: "flex flex-wrap items-center gap-1 text-sm",
115
+ "aria-label": t("table.pagination.label", "Pagination"),
116
+ children: history.links.map(
117
+ (link) => link.url ? /* @__PURE__ */ jsx(
118
+ Link,
119
+ {
120
+ href: link.url,
121
+ className: cn(
122
+ "rounded-sm px-2 py-1",
123
+ link.active ? "bg-accent font-medium text-accent-foreground" : "text-muted-foreground hover:text-foreground"
124
+ ),
125
+ children: decodePaginationLabel(link.label)
126
+ },
127
+ link.url
128
+ ) : /* @__PURE__ */ jsx("span", { className: "rounded-sm px-2 py-1 text-muted-foreground/50", children: decodePaginationLabel(link.label) }, link.label)
129
+ )
130
+ }
131
+ )
132
+ ] });
133
+ }
134
+
135
+ export { ArqelNotificationsPage };
136
+ //# sourceMappingURL=chunk-NFP2EB7Y.js.map
137
+ //# sourceMappingURL=chunk-NFP2EB7Y.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/pages/ArqelNotificationsPage.tsx"],"names":[],"mappings":"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","file":"chunk-NFP2EB7Y.js","sourcesContent":["/**\n * Default Inertia page for `arqel::notifications`.\n *\n * Renders the paginated notification history emitted by\n * `Arqel\\Core\\Http\\Controllers\\NotificationController::index`\n * (`{ history: paginator, filter: 'all' | 'unread' }`). The page-prop\n * is named `history` — *not* `notifications` — because `notifications`\n * is already a shared Inertia prop (`{unread_count, recent}`, see\n * `HandleArqelInertiaRequests`) consumed by the `<NotificationBell>`\n * mounted on every page's topbar. Reusing that key here would let this\n * page's paginator silently overwrite the shared prop and break the\n * bell (see branch review, milestone 0.19).\n *\n * The paginator serializes each item as `{id, type, data, read_at,\n * created_at}` — same shape as the `notifications.recent` array the\n * `<NotificationBell>` dropdown consumes, so titles/bodies follow the\n * same `data.title` / `data.body` convention.\n *\n * Per-item actions do scoped Inertia visits (`only: ['history']` for\n * mark-as-read, a plain reload for delete) so the list refreshes\n * without a full page navigation.\n */\n\nimport { useArqelTranslations } from '@arqel-dev/react/utils';\nimport type { NotificationItem } from '@arqel-dev/types/inertia';\nimport { Link, router, usePage } from '@inertiajs/react';\nimport type { JSX } from 'react';\nimport { Button } from '../action/Button.js';\nimport { Card } from '../shadcn/ui/card.js';\nimport { cn } from '../utils/cn.js';\n\ninterface LaravelPaginationLink {\n url: string | null;\n label: string;\n active: boolean;\n}\n\ninterface NotificationsPaginator {\n data: NotificationItem[];\n links: LaravelPaginationLink[];\n meta: Record<string, unknown>;\n}\n\ninterface ArqelNotificationsPageProps {\n history: NotificationsPaginator;\n filter: 'all' | 'unread';\n [key: string]: unknown;\n}\n\nfunction readTitle(item: NotificationItem): string {\n const title = item.data['title'];\n if (typeof title === 'string' && title.trim()) return title;\n return item.type;\n}\n\nfunction readBody(item: NotificationItem): string | undefined {\n const body = item.data['body'] ?? item.data['message'];\n return typeof body === 'string' && body.trim() ? body : undefined;\n}\n\nfunction markRead(id: string): void {\n router.post(\n `/admin/notifications/${id}/read`,\n {},\n { preserveScroll: true, only: ['history', 'notifications'] },\n );\n}\n\nfunction markAllRead(): void {\n router.post(\n '/admin/notifications/read-all',\n {},\n { preserveScroll: true, only: ['history', 'notifications'] },\n );\n}\n\nfunction destroy(id: string): void {\n router.delete(`/admin/notifications/${id}`, { preserveScroll: true });\n}\n\n/**\n * Laravel's paginator emits prev/next labels as HTML entities\n * (`&laquo; Previous`, `Next &raquo;`). Decode the small, known set we\n * expect rather than reaching for `dangerouslySetInnerHTML` — the\n * labels are server-controlled but there is no reason to accept\n * arbitrary markup here.\n */\nfunction decodePaginationLabel(label: string): string {\n return label.replace(/&laquo;/g, '«').replace(/&raquo;/g, '»');\n}\n\nexport default function ArqelNotificationsPage(): JSX.Element {\n const t = useArqelTranslations();\n const { history, filter } = usePage<ArqelNotificationsPageProps>().props;\n\n const items = history.data;\n const hasUnread = items.some((item) => item.read_at === null);\n\n return (\n <div className=\"flex flex-col gap-4 p-4\">\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <h1 className=\"text-lg font-semibold\">{t('arqel.notifications.title', 'Notifications')}</h1>\n <div className=\"flex items-center gap-2\">\n <div className=\"flex items-center gap-1 text-sm\">\n <Link\n href=\"/admin/notifications?filter=all\"\n className={cn(\n 'rounded-sm px-2 py-1',\n filter === 'all'\n ? 'bg-accent font-medium text-accent-foreground'\n : 'text-muted-foreground hover:text-foreground',\n )}\n >\n {t('arqel.notifications.filter_all', 'All')}\n </Link>\n <Link\n href=\"/admin/notifications?filter=unread\"\n className={cn(\n 'rounded-sm px-2 py-1',\n filter === 'unread'\n ? 'bg-accent font-medium text-accent-foreground'\n : 'text-muted-foreground hover:text-foreground',\n )}\n >\n {t('arqel.notifications.filter_unread', 'Unread')}\n </Link>\n </div>\n {hasUnread && (\n <Button variant=\"outline\" size=\"sm\" onClick={markAllRead}>\n {t('arqel.notifications.mark_all_read', 'Mark all as read')}\n </Button>\n )}\n </div>\n </div>\n\n {items.length === 0 ? (\n <Card className=\"p-6 text-center text-sm text-muted-foreground\">\n {t('arqel.notifications.empty', 'No notifications')}\n </Card>\n ) : (\n <div className=\"flex flex-col gap-2\">\n {items.map((item) => {\n const title = readTitle(item);\n const body = readBody(item);\n const unread = item.read_at === null;\n\n return (\n <Card\n key={item.id}\n className={cn(\n 'flex flex-row items-start justify-between gap-4 p-4',\n unread && 'bg-accent/50',\n )}\n >\n <div className=\"flex min-w-0 flex-1 items-start gap-2\">\n <span\n aria-hidden=\"true\"\n className={cn(\n 'mt-1.5 h-1.5 w-1.5 shrink-0 rounded-full',\n unread ? 'bg-primary' : 'bg-transparent',\n )}\n />\n <div className=\"flex min-w-0 flex-col\">\n <span className=\"font-medium\">{title}</span>\n {body && <span className=\"text-sm text-muted-foreground\">{body}</span>}\n <span className=\"text-xs text-muted-foreground\">{item.created_at}</span>\n </div>\n </div>\n <div className=\"flex shrink-0 items-center gap-2\">\n {unread && (\n <Button variant=\"outline\" size=\"sm\" onClick={() => markRead(item.id)}>\n {t('arqel.notifications.mark_read', 'Mark as read')}\n </Button>\n )}\n <Button variant=\"ghost\" size=\"sm\" onClick={() => destroy(item.id)}>\n {t('arqel.notifications.delete', 'Delete')}\n </Button>\n </div>\n </Card>\n );\n })}\n </div>\n )}\n\n {history.links.length > 0 && (\n <nav\n className=\"flex flex-wrap items-center gap-1 text-sm\"\n aria-label={t('table.pagination.label', 'Pagination')}\n >\n {history.links.map((link) =>\n link.url ? (\n <Link\n key={link.url}\n href={link.url}\n className={cn(\n 'rounded-sm px-2 py-1',\n link.active\n ? 'bg-accent font-medium text-accent-foreground'\n : 'text-muted-foreground hover:text-foreground',\n )}\n >\n {decodePaginationLabel(link.label)}\n </Link>\n ) : (\n <span key={link.label} className=\"rounded-sm px-2 py-1 text-muted-foreground/50\">\n {decodePaginationLabel(link.label)}\n </span>\n ),\n )}\n </nav>\n )}\n </div>\n );\n}\n"]}
@@ -1,5 +1,5 @@
1
- import { ResourceIndex } from './chunk-KGAY2AZH.js';
2
- import { ActionButton, ActionMenu } from './chunk-7NGUPQON.js';
1
+ import { ResourceIndex } from './chunk-HOJEO5LX.js';
2
+ import { ActionButton, ActionMenu } from './chunk-4XV35QZA.js';
3
3
  import { usePage, router } from '@inertiajs/react';
4
4
  import { useMemo, useState, useRef, useEffect } from 'react';
5
5
  import { jsx } from 'react/jsx-runtime';
@@ -201,5 +201,5 @@ function ArqelIndexPage() {
201
201
  }
202
202
 
203
203
  export { ArqelIndexPage };
204
- //# sourceMappingURL=chunk-DOQUHQND.js.map
205
- //# sourceMappingURL=chunk-DOQUHQND.js.map
204
+ //# sourceMappingURL=chunk-P64TZA7T.js.map
205
+ //# sourceMappingURL=chunk-P64TZA7T.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/pages/ArqelIndexPage.tsx"],"names":[],"mappings":";;;;;;AAkCA,SAAS,kBAAkB,MAAA,EAAkE;AAC3F,EAAA,MAAM,MAAmC,EAAC;AAC1C,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AAC3C,IAAA,IAAI,CAAA,KAAM,MAAA,IAAa,CAAA,KAAM,IAAA,IAAQ,MAAM,EAAA,EAAI;AAC/C,IAAA,IAAI,MAAM,OAAA,CAAQ,CAAC,CAAA,IAAK,CAAA,CAAE,WAAW,CAAA,EAAG;AACxC,IAAA,GAAA,CAAI,CAAC,CAAA,GAAI,CAAA;AAAA,EACX;AACA,EAAA,OAAO,GAAA;AACT;AAUA,SAAS,YAAA,CACP,MAAA,EACA,MAAA,EACA,UAAA,EACM;AACN,EAAA,MAAM,WAAW,MAAA,EAAQ,EAAA;AAOzB,EAAA,IAAI,CAAC,OAAO,GAAA,EAAK;AACf,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,eAAA,EAAkB,OAAO,IAAI,CAAA,0KAAA;AAAA,KAG/B;AAAA,EACF;AACA,EAAA,MAAM,GAAA,GAAM,OAAO,GAAA,CAAI,OAAA,CAAQ,QAAQ,MAAA,CAAO,QAAA,IAAY,EAAE,CAAC,CAAA;AAC7D,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,MAAA,CAAO,WAAA,EAAY;AACzC,EAAA,MAAM,IAAA,GAAgC,EAAE,GAAI,UAAA,IAAc,EAAC,EAAG;AAC9D,EAAA,IAAI,QAAA,KAAa,MAAA,EAAW,IAAA,CAAK,WAAW,CAAA,GAAI,QAAA;AAEhD,EAAA,MAAA,CAAO,MAAM,GAAA,EAAK;AAAA,IAChB,MAAA;AAAA,IACA,IAAA;AAAA,IACA,cAAA,EAAgB;AAAA,GACjB,CAAA;AACH;AAgBA,SAAS,oBAAA,CACP,cACA,MAAA,EAMgB;AAChB,EAAA,MAAM,YAAA,GAAe,OAAO,KAAA,EAAO,OAAA;AACnC,EAAA,MAAM,SAAA,GAAY,MAAA,CAAO,KAAA,EAAO,eAAA,IAAmB,EAAC;AAEpD,EAAA,OAAO,YAAA,CACJ,MAAA,CAAO,CAAC,MAAA,KAAY,eAAe,YAAA,CAAa,QAAA,CAAS,MAAA,CAAO,IAAI,CAAA,GAAI,IAAK,CAAA,CAC7E,GAAA,CAAI,CAAC,MAAA,KAAW;AACf,IAAA,MAAM,QAAA,GAAW,SAAA,CAAU,MAAA,CAAO,IAAI,CAAA;AACtC,IAAA,IAAI,QAAA,KAAa,QAAW,OAAO,MAAA;AACnC,IAAA,OAAO;AAAA,MACL,GAAG,MAAA;AAAA,MACH,GAAI,SAAS,GAAA,KAAQ,MAAA,GAAY,EAAE,GAAA,EAAK,QAAA,CAAS,GAAA,EAAI,GAAI,EAAC;AAAA,MAC1D,GAAI,SAAS,QAAA,KAAa,IAAA,GAAO,EAAE,QAAA,EAAU,IAAA,KAAkB;AAAC,KAClE;AAAA,EACF,CAAC,CAAA;AACL;AAEA,SAAS,WAAW,MAAA,EAA8C;AAChE,EAAA,MAAM,OAAgC,EAAC;AACvC,EAAA,MAAM,OAAA,GAAU,iBAAA,CAAkB,MAAA,CAAO,OAAO,CAAA;AAChD,EAAA,IAAI,MAAA,CAAO,KAAK,OAAO,CAAA,CAAE,SAAS,CAAA,EAAG,IAAA,CAAK,QAAQ,CAAA,GAAI,OAAA;AACtD,EAAA,IAAI,OAAO,MAAA,KAAW,MAAA,EAAW,IAAA,CAAK,QAAQ,IAAI,MAAA,CAAO,MAAA;AACzD,EAAA,IAAI,MAAA,CAAO,MAAM,MAAA,EAAQ;AACvB,IAAA,IAAA,CAAK,MAAM,CAAA,GAAI,MAAA,CAAO,IAAA,CAAK,MAAA;AAC3B,IAAA,IAAI,OAAO,IAAA,CAAK,SAAA,OAAgB,WAAW,CAAA,GAAI,OAAO,IAAA,CAAK,SAAA;AAAA,EAC7D;AACA,EAAA,IAAI,MAAA,CAAO,QAAQ,MAAA,CAAO,IAAA,GAAO,GAAG,IAAA,CAAK,MAAM,IAAI,MAAA,CAAO,IAAA;AAC1D,EAAA,IAAI,MAAA,CAAO,OAAA,EAAS,IAAA,CAAK,UAAU,IAAI,MAAA,CAAO,OAAA;AAC9C,EAAA,OAAO,IAAA;AACT;AAEe,SAAR,cAAA,GAAwF;AAC7F,EAAA,MAAM,OAAO,OAAA,EAAQ;AACrB,EAAA,MAAM,QAAQ,IAAA,CAAK,KAAA;AAEnB,EAAA,MAAM,cAAA,GAAiB,QAAQ,MAAM;AACnC,IAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,EAAC;AAC3C,IAAA,MAAM,EAAA,GAAK,IAAI,eAAA,CAAgB,MAAA,CAAO,SAAS,MAAM,CAAA;AACrD,IAAA,MAAM,UAAuC,EAAC;AAC9C,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,CAAA,IAAK,EAAA,CAAG,SAAQ,EAAG;AACvC,MAAA,MAAM,CAAA,GAAI,GAAA,CAAI,KAAA,CAAM,sBAAsB,CAAA;AAC1C,MAAA,IAAI,IAAI,CAAC,CAAA,UAAW,CAAA,CAAE,CAAC,CAAC,CAAA,GAAI,KAAA;AAAA,IAC9B;AACA,IAAA,OAAO,OAAA;AAAA,EACT,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,SAAsC,cAAc,CAAA;AAC5F,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,IAAI,QAAA,CAAiB,KAAA,CAAM,UAAU,EAAE,CAAA;AACzE,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,IAAI,QAAA,CAA6B,KAAA,CAAM,YAAY,OAAO,CAAA;AACpF,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,QAAA,CAAyC,EAAE,CAAA;AACjF,EAAA,MAAM,iBAAA,GAAoB,OAA6C,IAAI,CAAA;AAE3E,EAAA,MAAM,KAAA,GAAQ,CAAC,IAAA,KAAwC;AACrD,IAAA,MAAM,GAAA,GAAM,OAAO,MAAA,KAAW,WAAA,GAAc,MAAA,CAAO,QAAA,CAAS,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAA;AAC5F,IAAA,MAAA,CAAO,GAAA,CAAI,GAAA,IAAO,GAAA,EAAK,IAAA,EAA+D;AAAA,MACpF,aAAA,EAAe,IAAA;AAAA,MACf,cAAA,EAAgB,IAAA;AAAA,MAChB,OAAA,EAAS;AAAA,KACV,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,MAAM,WAAA,GAAc,MAAM,IAAA,IAAQ,IAAA;AAElC,EAAA,MAAM,kBAAA,GAAqB,CAAC,IAAA,EAAc,KAAA,KAA6B;AACrE,IAAA,MAAM,WAAA,GAAc,EAAE,GAAG,YAAA,EAAa;AACtC,IAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA,IAAQ,UAAU,EAAA,EAAI;AACzD,MAAA,OAAO,YAAY,IAAI,CAAA;AAAA,IACzB,CAAA,MAAO;AACL,MAAA,WAAA,CAAY,IAAI,CAAA,GAAI,KAAA;AAAA,IACtB;AACA,IAAA,eAAA,CAAgB,WAAW,CAAA;AAC3B,IAAA,KAAA,CAAM,UAAA,CAAW,EAAE,OAAA,EAAS,WAAA,EAAa,MAAA,EAAQ,aAAa,IAAA,EAAM,WAAA,EAAa,OAAA,EAAS,CAAC,CAAA;AAAA,EAC7F,CAAA;AAEA,EAAA,MAAM,qBAAqB,MAAY;AACrC,IAAA,eAAA,CAAgB,EAAE,CAAA;AAClB,IAAA,KAAA,CAAM,UAAA,CAAW,EAAE,OAAA,EAAS,EAAC,EAAG,MAAA,EAAQ,WAAA,EAAa,IAAA,EAAM,WAAA,EAAa,OAAA,EAAS,CAAC,CAAA;AAAA,EACpF,CAAA;AAEA,EAAA,MAAM,kBAAA,GAAqB,CAAC,KAAA,KAAwB;AAClD,IAAA,cAAA,CAAe,KAAK,CAAA;AACpB,IAAA,IAAI,iBAAA,CAAkB,OAAA,EAAS,YAAA,CAAa,iBAAA,CAAkB,OAAO,CAAA;AACrE,IAAA,iBAAA,CAAkB,OAAA,GAAU,WAAW,MAAM;AAC3C,MAAA,KAAA,CAAM,UAAA,CAAW,EAAE,OAAA,EAAS,YAAA,EAAc,MAAA,EAAQ,OAAO,IAAA,EAAM,WAAA,EAAa,OAAA,EAAS,CAAC,CAAA;AAAA,IACxF,GAAG,GAAG,CAAA;AAAA,EACR,CAAA;AAEA,EAAA,SAAA;AAAA,IACE,MAAM,MAAM;AACV,MAAA,IAAI,iBAAA,CAAkB,OAAA,EAAS,YAAA,CAAa,iBAAA,CAAkB,OAAO,CAAA;AAAA,IACvE,CAAA;AAAA,IACA;AAAC,GACH;AAEA,EAAA,MAAM,gBAAA,GAAmB,CAAC,MAAA,EAAgB,SAAA,KAAmC;AAC3E,IAAA,KAAA;AAAA,MACE,UAAA,CAAW;AAAA,QACT,OAAA,EAAS,YAAA;AAAA,QACT,MAAA,EAAQ,WAAA;AAAA,QACR,IAAA,EAAM,EAAE,MAAA,EAAQ,SAAA,EAAU;AAAA,QAC1B;AAAA,OACD;AAAA,KACH;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,gBAAA,GAAmB,CAAC,OAAA,KAA0B;AAClD,IAAA,KAAA;AAAA,MACE,UAAA,CAAW;AAAA,QACT,OAAA,EAAS,YAAA;AAAA,QACT,MAAA,EAAQ,WAAA;AAAA,QACR,IAAA,EAAM,WAAA;AAAA,QACN,IAAA,EAAM,OAAA;AAAA,QACN;AAAA,OACD;AAAA,KACH;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,mBAAA,GAAsB,CAAC,UAAA,KAA6B;AACxD,IAAA,UAAA,CAAW,UAAU,CAAA;AACrB,IAAA,KAAA;AAAA,MACE,UAAA,CAAW;AAAA,QACT,OAAA,EAAS,YAAA;AAAA,QACT,MAAA,EAAQ,WAAA;AAAA,QACR,IAAA,EAAM,WAAA;AAAA,QACN,OAAA,EAAS;AAAA,OACV;AAAA,KACH;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,kBAAA,GAAqB,CAAC,MAAA,KAA+B;AAIzD,IAAA,MAAM,MAAM,MAAA,CAAO,GAAA;AACnB,IAAA,IAAI,QAAQ,MAAA,EAAW;AACrB,MAAA;AAAA,IACF;AACA,IAAA,MAAM,MAAA,GAAS,MAAA,CAAO,MAAA,CAAO,WAAA,EAAY;AACzC,IAAA,MAAA,CAAO,MAAM,GAAA,EAAK;AAAA,MAChB,MAAA;AAAA,MACA,IAAA,EAAM,EAAE,UAAA,EAAY,WAAA,EAA4C;AAAA,MAChE,cAAA,EAAgB,IAAA;AAAA,MAChB,SAAA,EAAW,MAAM,cAAA,CAAe,EAAE;AAAA,KACnC,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,MAAM,eAAA,GAAkB,KAAA,CAAM,OAAA,EAAS,IAAA,IAAQ,EAAC;AAChD,EAAA,MAAM,WAAA,GACJ,eAAA,CAAgB,MAAA,GAAS,CAAA,IAAK,WAAA,CAAY,MAAA,GAAS,CAAA,mBACjD,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yBAAA,EACZ,QAAA,EAAA,eAAA,CAAgB,IAAI,CAAC,MAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAKpB,GAAA;AAAA,MAAC,YAAA;AAAA,MAAA;AAAA,QAEC,MAAA;AAAA,QACA,QAAA,EAAU,MAAM,kBAAA,CAAmB,MAAM,CAAA;AAAA,QACzC,IAAA,EAAK,IAAA;AAAA,QAEL,SAAA,EAAU;AAAA,OAAA;AAAA,MALL,MAAA,CAAO;AAAA;AAMd,GACD,GACH,CAAA,GACE,MAAA;AAEN,EAAA,MAAM,cAAA,GAAiB,KAAA,CAAM,OAAA,EAAS,GAAA,IAAO,EAAC;AAC9C,EAAA,MAAM,UAAA,GACJ,cAAA,CAAe,MAAA,GAAS,CAAA,GACpB,CAAC,MAAA,qBACC,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MAIC,OAAA,EAAS,oBAAA,CAAqB,cAAA,EAAgB,MAAM,CAAA;AAAA,MACpD,UAAU,CAAC,MAAA,EAAQ,eACjB,YAAA,CAAa,MAAA,EAAQ,QAAmC,UAAU;AAAA;AAAA,GAEtE,GAEF,MAAA;AAEN,EAAA,uBACE,GAAA;AAAA,IAAC,aAAA;AAAA,IAAA;AAAA,MACE,GAAG,KAAA;AAAA,MACJ,YAAA;AAAA,MACA,cAAA,EAAgB,kBAAA;AAAA,MAChB,cAAA,EAAgB,kBAAA;AAAA,MAChB,cAAA,EAAgB,kBAAA;AAAA,MAChB,YAAA,EAAc,gBAAA;AAAA,MACd,YAAA,EAAc,gBAAA;AAAA,MACd,eAAA,EAAiB,mBAAA;AAAA,MACjB,MAAA,EAAQ,WAAA;AAAA,MACR,WAAA;AAAA,MACA,iBAAA,EAAmB,CAAC,GAAA,KAAQ,cAAA,CAAe,GAAG,CAAA;AAAA,MAC7C,GAAI,UAAA,GAAa,EAAE,UAAA,KAAe,EAAC;AAAA,MACnC,GAAI,WAAA,GAAc,EAAE,WAAA,KAAgB;AAAC;AAAA,GACxC;AAEJ","file":"chunk-DOQUHQND.js","sourcesContent":["/**\n * Default Inertia page for `arqel::index`.\n *\n * Pulls every prop the server emits via `InertiaDataBuilder::\n * buildIndexData` / `buildTableIndexData` and forwards them to\n * `<ResourceIndex>`. Apps can override per-resource by registering\n * their own page component at `Pages/Arqel/{Slug}/Index.tsx` (the\n * lookup falls through to user pages first inside `createArqelApp`).\n *\n * Wires the standard table interactions — search / filter / sort /\n * pagination — into Inertia partial `router.get` visits so the\n * server can re-run TableQueryBuilder with the new query string.\n *\n * Query-string contract (matches `Arqel\\Table\\TableQueryBuilder`):\n * - `?search=foo` global search\n * - `?sort=column&direction=asc|desc`\n * - `?page=N&per_page=M`\n * - `?filter[name]=value` one entry per filter\n *\n * `search` is debounced (300ms) so typing doesn't hammer the\n * backend; the rest fire immediately.\n */\n\nimport type { ActionSchema } from '@arqel-dev/types/actions';\nimport type { RecordType, ResourceIndexProps } from '@arqel-dev/types/resources';\nimport type { SortDirection } from '@arqel-dev/types/tables';\nimport { router, usePage } from '@inertiajs/react';\nimport { type JSX, useEffect, useMemo, useRef, useState } from 'react';\nimport { ActionButton } from '../action/ActionButton.js';\nimport { ActionMenu } from '../action/ActionMenu.js';\nimport { ResourceIndex } from '../resource/ResourceIndex.js';\n\ntype FilterValue = unknown;\n\nfunction pruneEmptyFilters(values: Record<string, FilterValue>): Record<string, FilterValue> {\n const out: Record<string, FilterValue> = {};\n for (const [k, v] of Object.entries(values)) {\n if (v === undefined || v === null || v === '') continue;\n if (Array.isArray(v) && v.length === 0) continue;\n out[k] = v;\n }\n return out;\n}\n\ninterface VisitParams {\n filters: Record<string, FilterValue>;\n search: string;\n sort?: { column: string | null; direction: string | null } | null;\n page?: number | undefined;\n perPage?: number | undefined;\n}\n\nfunction invokeAction(\n action: ActionSchema,\n record: { id: string | number } | null,\n formValues?: Record<string, unknown>,\n): void {\n const recordId = record?.id;\n // Every dispatchable action ships a server-emitted `url` (stock verbs,\n // bulk, and custom callback actions all resolve through core's authorised\n // routes — see `Action::resolveStockUrl()`, #48/#231). An absent `url`\n // signals a misconfiguration; we must NOT fall back to the dead\n // `/arqel-dev/actions/{name}` route removed in #174. Surface it clearly\n // instead of masking it as a 404.\n if (!action.url) {\n throw new Error(\n `Arqel: action \"${action.name}\" has no url to dispatch to. Declare it on ` +\n `the Resource's actions()/headerActions()/toolbarActions() so the server ` +\n `emits its endpoint URL, or give it an explicit ->url().`,\n );\n }\n const url = action.url.replace('{id}', String(recordId ?? ''));\n const method = action.method.toLowerCase() as 'get' | 'post' | 'put' | 'patch' | 'delete';\n const data: Record<string, unknown> = { ...(formValues ?? {}) };\n if (recordId !== undefined) data['record_id'] = recordId;\n\n router.visit(url, {\n method: method as never,\n data: data as never,\n preserveScroll: true,\n });\n}\n\n/**\n * Resolve the row-action list for a single record (#140).\n *\n * Row actions are defined once at table level (label / icon / color /\n * confirmation / form), but `url(Closure)` and `disabled(Closure)`\n * actions depend on the row. The server emits those resolved values\n * per record under `record.arqel.actionOverrides`; here we merge them\n * onto the shared definitions so each row links to its own URL and\n * carries its own disabled state.\n *\n * When the server also emits `record.arqel.actions` (the visible +\n * executable action names) we filter the list against it so per-row\n * authorization/visibility is honoured.\n */\nfunction resolveRecordActions(\n tableActions: ActionSchema[],\n record: {\n arqel?: {\n actions?: string[];\n actionOverrides?: Record<string, { url?: string; disabled?: true }>;\n };\n },\n): ActionSchema[] {\n const visibleNames = record.arqel?.actions;\n const overrides = record.arqel?.actionOverrides ?? {};\n\n return tableActions\n .filter((action) => (visibleNames ? visibleNames.includes(action.name) : true))\n .map((action) => {\n const override = overrides[action.name];\n if (override === undefined) return action;\n return {\n ...action,\n ...(override.url !== undefined ? { url: override.url } : {}),\n ...(override.disabled === true ? { disabled: true as const } : {}),\n };\n });\n}\n\nfunction buildQuery(params: VisitParams): Record<string, unknown> {\n const data: Record<string, unknown> = {};\n const filters = pruneEmptyFilters(params.filters);\n if (Object.keys(filters).length > 0) data['filter'] = filters;\n if (params.search !== undefined) data['search'] = params.search;\n if (params.sort?.column) {\n data['sort'] = params.sort.column;\n if (params.sort.direction) data['direction'] = params.sort.direction;\n }\n if (params.page && params.page > 1) data['page'] = params.page;\n if (params.perPage) data['per_page'] = params.perPage;\n return data;\n}\n\nexport default function ArqelIndexPage<TRecord extends RecordType = RecordType>(): JSX.Element {\n const page = usePage();\n const props = page.props as unknown as ResourceIndexProps<TRecord>;\n\n const initialFilters = useMemo(() => {\n if (typeof window === 'undefined') return {};\n const sp = new URLSearchParams(window.location.search);\n const fromUrl: Record<string, FilterValue> = {};\n for (const [key, value] of sp.entries()) {\n const m = key.match(/^filter\\[([^\\]]+)\\]$/);\n if (m?.[1]) fromUrl[m[1]] = value;\n }\n return fromUrl;\n }, []);\n\n const [filterValues, setFilterValues] = useState<Record<string, FilterValue>>(initialFilters);\n const [searchValue, setSearchValue] = useState<string>(props.search ?? '');\n const [perPage, setPerPage] = useState<number | undefined>(props.pagination?.perPage);\n const [selectedIds, setSelectedIds] = useState<ReadonlyArray<string | number>>([]);\n const searchDebounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const visit = (data: Record<string, unknown>): void => {\n const url = typeof window !== 'undefined' ? window.location.pathname : page.url.split('?')[0];\n router.get(url ?? '/', data as Record<string, string | number | boolean | undefined>, {\n preserveState: true,\n preserveScroll: true,\n replace: true,\n });\n };\n\n const currentSort = props.sort ?? null;\n\n const handleFilterChange = (name: string, value: FilterValue): void => {\n const nextFilters = { ...filterValues };\n if (value === undefined || value === null || value === '') {\n delete nextFilters[name];\n } else {\n nextFilters[name] = value;\n }\n setFilterValues(nextFilters);\n visit(buildQuery({ filters: nextFilters, search: searchValue, sort: currentSort, perPage }));\n };\n\n const handleClearFilters = (): void => {\n setFilterValues({});\n visit(buildQuery({ filters: {}, search: searchValue, sort: currentSort, perPage }));\n };\n\n const handleSearchChange = (value: string): void => {\n setSearchValue(value);\n if (searchDebounceRef.current) clearTimeout(searchDebounceRef.current);\n searchDebounceRef.current = setTimeout(() => {\n visit(buildQuery({ filters: filterValues, search: value, sort: currentSort, perPage }));\n }, 300);\n };\n\n useEffect(\n () => () => {\n if (searchDebounceRef.current) clearTimeout(searchDebounceRef.current);\n },\n [],\n );\n\n const handleSortChange = (column: string, direction: SortDirection): void => {\n visit(\n buildQuery({\n filters: filterValues,\n search: searchValue,\n sort: { column, direction },\n perPage,\n }),\n );\n };\n\n const handlePageChange = (pageNum: number): void => {\n visit(\n buildQuery({\n filters: filterValues,\n search: searchValue,\n sort: currentSort,\n page: pageNum,\n perPage,\n }),\n );\n };\n\n const handlePerPageChange = (newPerPage: number): void => {\n setPerPage(newPerPage);\n visit(\n buildQuery({\n filters: filterValues,\n search: searchValue,\n sort: currentSort,\n perPage: newPerPage,\n }),\n );\n };\n\n const dispatchBulkAction = (action: ActionSchema): void => {\n // Every bulk action carries a stock url (core resolves\n // /admin/{slug}/bulk/{name} for any bulk action without an\n // explicit url), so there is no client-side fallback route.\n const url = action.url;\n if (url === undefined) {\n return;\n }\n const method = action.method.toLowerCase() as 'get' | 'post' | 'put' | 'patch' | 'delete';\n router.visit(url, {\n method: method as never,\n data: { record_ids: selectedIds as readonly (string | number)[] } as never,\n preserveScroll: true,\n onSuccess: () => setSelectedIds([]),\n });\n };\n\n const bulkActionsList = props.actions?.bulk ?? [];\n const bulkActions =\n bulkActionsList.length > 0 && selectedIds.length > 0 ? (\n <div className=\"flex items-center gap-2\">\n {bulkActionsList.map((action) => (\n // Route through ActionButton so destructive bulk actions that set\n // requiresConfirmation open the ConfirmDialog before dispatching,\n // matching row-action behaviour. Non-confirming actions fire\n // immediately. The visit payload is unchanged.\n <ActionButton\n key={action.name}\n action={action}\n onInvoke={() => dispatchBulkAction(action)}\n size=\"sm\"\n // 44px touch target on mobile (WCAG 2.5.5); dense 32px on >=md.\n className=\"h-11 md:h-8\"\n />\n ))}\n </div>\n ) : undefined;\n\n const rowActionsList = props.actions?.row ?? [];\n const rowActions =\n rowActionsList.length > 0\n ? (record: TRecord) => (\n <ActionMenu\n // Resolve actions against this row so closure-URL /\n // closure-disabled actions get their per-record values\n // (#140) instead of the table-level placeholder.\n actions={resolveRecordActions(rowActionsList, record)}\n onInvoke={(action, formValues) =>\n invokeAction(action, record as { id: string | number }, formValues)\n }\n />\n )\n : undefined;\n\n return (\n <ResourceIndex<TRecord>\n {...props}\n filterValues={filterValues}\n onFilterChange={handleFilterChange}\n onClearFilters={handleClearFilters}\n onSearchChange={handleSearchChange}\n onSortChange={handleSortChange}\n onPageChange={handlePageChange}\n onPerPageChange={handlePerPageChange}\n search={searchValue}\n selectedIds={selectedIds}\n onSelectionChange={(ids) => setSelectedIds(ids)}\n {...(rowActions ? { rowActions } : {})}\n {...(bulkActions ? { bulkActions } : {})}\n />\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/pages/ArqelIndexPage.tsx"],"names":[],"mappings":"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","file":"chunk-P64TZA7T.js","sourcesContent":["/**\n * Default Inertia page for `arqel::index`.\n *\n * Pulls every prop the server emits via `InertiaDataBuilder::\n * buildIndexData` / `buildTableIndexData` and forwards them to\n * `<ResourceIndex>`. Apps can override per-resource by registering\n * their own page component at `Pages/Arqel/{Slug}/Index.tsx` (the\n * lookup falls through to user pages first inside `createArqelApp`).\n *\n * Wires the standard table interactions — search / filter / sort /\n * pagination — into Inertia partial `router.get` visits so the\n * server can re-run TableQueryBuilder with the new query string.\n *\n * Query-string contract (matches `Arqel\\Table\\TableQueryBuilder`):\n * - `?search=foo` global search\n * - `?sort=column&direction=asc|desc`\n * - `?page=N&per_page=M`\n * - `?filter[name]=value` one entry per filter\n *\n * `search` is debounced (300ms) so typing doesn't hammer the\n * backend; the rest fire immediately.\n */\n\nimport type { ActionSchema } from '@arqel-dev/types/actions';\nimport type { RecordType, ResourceIndexProps } from '@arqel-dev/types/resources';\nimport type { SortDirection } from '@arqel-dev/types/tables';\nimport { router, usePage } from '@inertiajs/react';\nimport { type JSX, useEffect, useMemo, useRef, useState } from 'react';\nimport { ActionButton } from '../action/ActionButton.js';\nimport { ActionMenu } from '../action/ActionMenu.js';\nimport { ResourceIndex } from '../resource/ResourceIndex.js';\n\ntype FilterValue = unknown;\n\nfunction pruneEmptyFilters(values: Record<string, FilterValue>): Record<string, FilterValue> {\n const out: Record<string, FilterValue> = {};\n for (const [k, v] of Object.entries(values)) {\n if (v === undefined || v === null || v === '') continue;\n if (Array.isArray(v) && v.length === 0) continue;\n out[k] = v;\n }\n return out;\n}\n\ninterface VisitParams {\n filters: Record<string, FilterValue>;\n search: string;\n sort?: { column: string | null; direction: string | null } | null;\n page?: number | undefined;\n perPage?: number | undefined;\n}\n\nfunction invokeAction(\n action: ActionSchema,\n record: { id: string | number } | null,\n formValues?: Record<string, unknown>,\n): void {\n const recordId = record?.id;\n // Every dispatchable action ships a server-emitted `url` (stock verbs,\n // bulk, and custom callback actions all resolve through core's authorised\n // routes — see `Action::resolveStockUrl()`, #48/#231). An absent `url`\n // signals a misconfiguration; we must NOT fall back to the dead\n // `/arqel-dev/actions/{name}` route removed in #174. Surface it clearly\n // instead of masking it as a 404.\n if (!action.url) {\n throw new Error(\n `Arqel: action \"${action.name}\" has no url to dispatch to. Declare it on ` +\n `the Resource's actions()/headerActions()/toolbarActions() so the server ` +\n `emits its endpoint URL, or give it an explicit ->url().`,\n );\n }\n const url = action.url.replace('{id}', String(recordId ?? ''));\n const method = action.method.toLowerCase() as 'get' | 'post' | 'put' | 'patch' | 'delete';\n const data: Record<string, unknown> = { ...(formValues ?? {}) };\n if (recordId !== undefined) data['record_id'] = recordId;\n\n router.visit(url, {\n method: method as never,\n data: data as never,\n preserveScroll: true,\n });\n}\n\n/**\n * Resolve the row-action list for a single record (#140).\n *\n * Row actions are defined once at table level (label / icon / color /\n * confirmation / form), but `url(Closure)` and `disabled(Closure)`\n * actions depend on the row. The server emits those resolved values\n * per record under `record.arqel.actionOverrides`; here we merge them\n * onto the shared definitions so each row links to its own URL and\n * carries its own disabled state.\n *\n * When the server also emits `record.arqel.actions` (the visible +\n * executable action names) we filter the list against it so per-row\n * authorization/visibility is honoured.\n */\nfunction resolveRecordActions(\n tableActions: ActionSchema[],\n record: {\n arqel?: {\n actions?: string[];\n actionOverrides?: Record<string, { url?: string; disabled?: true }>;\n };\n },\n): ActionSchema[] {\n const visibleNames = record.arqel?.actions;\n const overrides = record.arqel?.actionOverrides ?? {};\n\n return tableActions\n .filter((action) => (visibleNames ? visibleNames.includes(action.name) : true))\n .map((action) => {\n const override = overrides[action.name];\n if (override === undefined) return action;\n return {\n ...action,\n ...(override.url !== undefined ? { url: override.url } : {}),\n ...(override.disabled === true ? { disabled: true as const } : {}),\n };\n });\n}\n\nfunction buildQuery(params: VisitParams): Record<string, unknown> {\n const data: Record<string, unknown> = {};\n const filters = pruneEmptyFilters(params.filters);\n if (Object.keys(filters).length > 0) data['filter'] = filters;\n if (params.search !== undefined) data['search'] = params.search;\n if (params.sort?.column) {\n data['sort'] = params.sort.column;\n if (params.sort.direction) data['direction'] = params.sort.direction;\n }\n if (params.page && params.page > 1) data['page'] = params.page;\n if (params.perPage) data['per_page'] = params.perPage;\n return data;\n}\n\nexport default function ArqelIndexPage<TRecord extends RecordType = RecordType>(): JSX.Element {\n const page = usePage();\n const props = page.props as unknown as ResourceIndexProps<TRecord>;\n\n const initialFilters = useMemo(() => {\n if (typeof window === 'undefined') return {};\n const sp = new URLSearchParams(window.location.search);\n const fromUrl: Record<string, FilterValue> = {};\n for (const [key, value] of sp.entries()) {\n const m = key.match(/^filter\\[([^\\]]+)\\]$/);\n if (m?.[1]) fromUrl[m[1]] = value;\n }\n return fromUrl;\n }, []);\n\n const [filterValues, setFilterValues] = useState<Record<string, FilterValue>>(initialFilters);\n const [searchValue, setSearchValue] = useState<string>(props.search ?? '');\n const [perPage, setPerPage] = useState<number | undefined>(props.pagination?.perPage);\n const [selectedIds, setSelectedIds] = useState<ReadonlyArray<string | number>>([]);\n const searchDebounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const visit = (data: Record<string, unknown>): void => {\n const url = typeof window !== 'undefined' ? window.location.pathname : page.url.split('?')[0];\n router.get(url ?? '/', data as Record<string, string | number | boolean | undefined>, {\n preserveState: true,\n preserveScroll: true,\n replace: true,\n });\n };\n\n const currentSort = props.sort ?? null;\n\n const handleFilterChange = (name: string, value: FilterValue): void => {\n const nextFilters = { ...filterValues };\n if (value === undefined || value === null || value === '') {\n delete nextFilters[name];\n } else {\n nextFilters[name] = value;\n }\n setFilterValues(nextFilters);\n visit(buildQuery({ filters: nextFilters, search: searchValue, sort: currentSort, perPage }));\n };\n\n const handleClearFilters = (): void => {\n setFilterValues({});\n visit(buildQuery({ filters: {}, search: searchValue, sort: currentSort, perPage }));\n };\n\n const handleSearchChange = (value: string): void => {\n setSearchValue(value);\n if (searchDebounceRef.current) clearTimeout(searchDebounceRef.current);\n searchDebounceRef.current = setTimeout(() => {\n visit(buildQuery({ filters: filterValues, search: value, sort: currentSort, perPage }));\n }, 300);\n };\n\n useEffect(\n () => () => {\n if (searchDebounceRef.current) clearTimeout(searchDebounceRef.current);\n },\n [],\n );\n\n const handleSortChange = (column: string, direction: SortDirection): void => {\n visit(\n buildQuery({\n filters: filterValues,\n search: searchValue,\n sort: { column, direction },\n perPage,\n }),\n );\n };\n\n const handlePageChange = (pageNum: number): void => {\n visit(\n buildQuery({\n filters: filterValues,\n search: searchValue,\n sort: currentSort,\n page: pageNum,\n perPage,\n }),\n );\n };\n\n const handlePerPageChange = (newPerPage: number): void => {\n setPerPage(newPerPage);\n visit(\n buildQuery({\n filters: filterValues,\n search: searchValue,\n sort: currentSort,\n perPage: newPerPage,\n }),\n );\n };\n\n const dispatchBulkAction = (action: ActionSchema): void => {\n // Every bulk action carries a stock url (core resolves\n // /admin/{slug}/bulk/{name} for any bulk action without an\n // explicit url), so there is no client-side fallback route.\n const url = action.url;\n if (url === undefined) {\n return;\n }\n const method = action.method.toLowerCase() as 'get' | 'post' | 'put' | 'patch' | 'delete';\n router.visit(url, {\n method: method as never,\n data: { record_ids: selectedIds as readonly (string | number)[] } as never,\n preserveScroll: true,\n onSuccess: () => setSelectedIds([]),\n });\n };\n\n const bulkActionsList = props.actions?.bulk ?? [];\n const bulkActions =\n bulkActionsList.length > 0 && selectedIds.length > 0 ? (\n <div className=\"flex items-center gap-2\">\n {bulkActionsList.map((action) => (\n // Route through ActionButton so destructive bulk actions that set\n // requiresConfirmation open the ConfirmDialog before dispatching,\n // matching row-action behaviour. Non-confirming actions fire\n // immediately. The visit payload is unchanged.\n <ActionButton\n key={action.name}\n action={action}\n onInvoke={() => dispatchBulkAction(action)}\n size=\"sm\"\n // 44px touch target on mobile (WCAG 2.5.5); dense 32px on >=md.\n className=\"h-11 md:h-8\"\n />\n ))}\n </div>\n ) : undefined;\n\n const rowActionsList = props.actions?.row ?? [];\n const rowActions =\n rowActionsList.length > 0\n ? (record: TRecord) => (\n <ActionMenu\n // Resolve actions against this row so closure-URL /\n // closure-disabled actions get their per-record values\n // (#140) instead of the table-level placeholder.\n actions={resolveRecordActions(rowActionsList, record)}\n onInvoke={(action, formValues) =>\n invokeAction(action, record as { id: string | number }, formValues)\n }\n />\n )\n : undefined;\n\n return (\n <ResourceIndex<TRecord>\n {...props}\n filterValues={filterValues}\n onFilterChange={handleFilterChange}\n onClearFilters={handleClearFilters}\n onSearchChange={handleSearchChange}\n onSortChange={handleSortChange}\n onPageChange={handlePageChange}\n onPerPageChange={handlePerPageChange}\n search={searchValue}\n selectedIds={selectedIds}\n onSelectionChange={(ids) => setSelectedIds(ids)}\n {...(rowActions ? { rowActions } : {})}\n {...(bulkActions ? { bulkActions } : {})}\n />\n );\n}\n"]}
@@ -1,10 +1,10 @@
1
- import { ErrorState } from './chunk-53J74IYR.js';
1
+ import { ErrorState, LoadingSkeleton } from './chunk-ZZKWQO3W.js';
2
2
  import { PageHeader } from './chunk-MXUXMHOK.js';
3
3
  import { DataTable } from './chunk-JKD6SE75.js';
4
- import { ConfirmDialog, Dialog, DialogContent, DialogHeader, DialogTitle } from './chunk-DO3PRGVV.js';
5
- import { FormActions } from './chunk-MZMYV43C.js';
4
+ import { ConfirmDialog, Dialog, DialogContent, DialogHeader, DialogTitle } from './chunk-FVKM6FDW.js';
5
+ import { FormActions } from './chunk-SVCWLDZ4.js';
6
6
  import { FormRenderer } from './chunk-CMNZLA32.js';
7
- import { Button } from './chunk-H23VX3RR.js';
7
+ import { Button } from './chunk-YF2RINPG.js';
8
8
  import { cn } from './chunk-B7ULUJVO.js';
9
9
  import { useArqelForm } from '@arqel-dev/hooks';
10
10
  import { useArqelTranslations } from '@arqel-dev/react/utils';
@@ -154,13 +154,47 @@ function RelationFormModal({
154
154
  parentId,
155
155
  basePath = "/admin",
156
156
  recordId,
157
- initialValues = {},
157
+ initialValues,
158
158
  onSuccess
159
159
  }) {
160
160
  const t = useArqelTranslations();
161
- const [values, setValues] = useState(initialValues);
161
+ const [values, setValues] = useState(initialValues ?? {});
162
162
  const [errors, setErrors] = useState({});
163
163
  const [processing, setProcessing] = useState(false);
164
+ const needsFetch = recordId !== void 0 && initialValues === void 0;
165
+ const [loadingRecord, setLoadingRecord] = useState(needsFetch);
166
+ const [loadError, setLoadError] = useState(false);
167
+ const base = `${basePath}/${parentSlug}/${parentId}/relations/${relation.slug}`;
168
+ useEffect(() => {
169
+ if (!open || !needsFetch) return;
170
+ let cancelled = false;
171
+ const editUrl = `${base}/${recordId}/edit`;
172
+ const doFetch = async () => {
173
+ setLoadingRecord(true);
174
+ setLoadError(false);
175
+ try {
176
+ const response = await fetch(editUrl, {
177
+ headers: { Accept: "application/json", "X-Requested-With": "XMLHttpRequest" },
178
+ credentials: "same-origin"
179
+ });
180
+ if (!response.ok) throw new Error(`Request failed with status ${response.status}`);
181
+ const body = await response.json();
182
+ if (!cancelled && body.record) {
183
+ setValues(body.record);
184
+ } else if (!cancelled) {
185
+ throw new Error("Response did not include a record");
186
+ }
187
+ } catch {
188
+ if (!cancelled) setLoadError(true);
189
+ } finally {
190
+ if (!cancelled) setLoadingRecord(false);
191
+ }
192
+ };
193
+ void doFetch();
194
+ return () => {
195
+ cancelled = true;
196
+ };
197
+ }, [open, needsFetch, base, recordId]);
164
198
  const fields = relation.fields;
165
199
  const schema = useMemo(
166
200
  () => ({
@@ -177,10 +211,11 @@ function RelationFormModal({
177
211
  [fields]
178
212
  );
179
213
  if (!open) return null;
180
- const base = `${basePath}/${parentSlug}/${parentId}/relations/${relation.slug}`;
181
214
  const url = recordId ? `${base}/${recordId}` : base;
182
215
  const method = recordId ? "put" : "post";
216
+ const blockedByRecordLoad = needsFetch && (loadingRecord || loadError);
183
217
  const submit = () => {
218
+ if (blockedByRecordLoad) return;
184
219
  setProcessing(true);
185
220
  router[method](url, values, {
186
221
  preserveScroll: true,
@@ -203,11 +238,18 @@ function RelationFormModal({
203
238
  values,
204
239
  errors,
205
240
  onChange: (name, value) => setValues((prev) => ({ ...prev, [name]: value })),
206
- disabled: processing,
241
+ disabled: processing || blockedByRecordLoad,
207
242
  onSubmit: submit
208
243
  };
209
244
  return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: (next) => !next && onClose(), children: /* @__PURE__ */ jsxs(DialogContent, { className: "overflow-auto sm:max-w-[32rem]", children: [
210
245
  /* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsx(DialogTitle, { children: relation.label }) }),
246
+ needsFetch && loadingRecord ? /* @__PURE__ */ jsx(LoadingSkeleton, { variant: "block", count: 3 }) : needsFetch && loadError ? /* @__PURE__ */ jsx(
247
+ ErrorState,
248
+ {
249
+ title: t("relations.form.loadError", "Couldn't load this record"),
250
+ description: t("relations.form.loadErrorDescription", "Please try again.")
251
+ }
252
+ ) : null,
211
253
  /* @__PURE__ */ jsxs(
212
254
  "form",
213
255
  {
@@ -222,6 +264,7 @@ function RelationFormModal({
222
264
  FormActions,
223
265
  {
224
266
  processing,
267
+ disabled: blockedByRecordLoad,
225
268
  submitLabel: t("form.save", "Save"),
226
269
  onCancel: onClose
227
270
  }
@@ -505,5 +548,5 @@ function ArqelEditPage() {
505
548
  }
506
549
 
507
550
  export { ArqelEditPage };
508
- //# sourceMappingURL=chunk-WKIYS2FQ.js.map
509
- //# sourceMappingURL=chunk-WKIYS2FQ.js.map
551
+ //# sourceMappingURL=chunk-RKWHRD75.js.map
552
+ //# sourceMappingURL=chunk-RKWHRD75.js.map