@tulip-systems/core 0.6.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/dist/commands/client.d.mts +2 -1
  2. package/dist/commands/client.mjs +2 -1
  3. package/dist/components/editor/components/menu-nodes.client.mjs +2 -2
  4. package/dist/components/editor/components/menu-nodes.client.mjs.map +1 -1
  5. package/dist/components/ui/input-date-time.d.mts +4 -4
  6. package/dist/components/ui/input-date-time.d.mts.map +1 -1
  7. package/dist/components/ui/input-date-time.mjs +4 -6
  8. package/dist/components/ui/input-date-time.mjs.map +1 -1
  9. package/dist/inline-edit/client.d.mts +2 -2
  10. package/dist/lib/hooks/use-indicator.d.mts.map +1 -1
  11. package/dist/lib/hooks/use-indicator.mjs +11 -8
  12. package/dist/lib/hooks/use-indicator.mjs.map +1 -1
  13. package/dist/modules/auth/components/auth-layout.server.mjs +1 -1
  14. package/dist/modules/auth/components/auth-layout.server.mjs.map +1 -1
  15. package/dist/modules/commands/hooks/use-command-menu.client.d.mts +8 -1
  16. package/dist/modules/commands/hooks/use-command-menu.client.d.mts.map +1 -1
  17. package/dist/modules/commands/hooks/use-command-menu.client.mjs.map +1 -1
  18. package/dist/modules/commands/menus/floating-menu.client.d.mts +19 -0
  19. package/dist/modules/commands/menus/floating-menu.client.d.mts.map +1 -0
  20. package/dist/modules/commands/menus/{data-table-menu.client.mjs → floating-menu.client.mjs} +10 -10
  21. package/dist/modules/commands/menus/floating-menu.client.mjs.map +1 -0
  22. package/dist/modules/data-tables/tables/data-table/components/table.mjs +8 -2
  23. package/dist/modules/data-tables/tables/data-table/components/table.mjs.map +1 -1
  24. package/dist/modules/data-tables/tables/inline-table/components/table.mjs +8 -2
  25. package/dist/modules/data-tables/tables/inline-table/components/table.mjs.map +1 -1
  26. package/dist/modules/inline-edit/components/combobox-dropdown.client.mjs +5 -1
  27. package/dist/modules/inline-edit/components/combobox-dropdown.client.mjs.map +1 -1
  28. package/dist/modules/inline-edit/components/combobox.client.mjs +5 -1
  29. package/dist/modules/inline-edit/components/combobox.client.mjs.map +1 -1
  30. package/dist/modules/inline-edit/components/date-input.client.mjs +5 -1
  31. package/dist/modules/inline-edit/components/date-input.client.mjs.map +1 -1
  32. package/dist/modules/inline-edit/components/date-picker.client.mjs +5 -1
  33. package/dist/modules/inline-edit/components/date-picker.client.mjs.map +1 -1
  34. package/dist/modules/inline-edit/components/date-time.client.d.mts.map +1 -1
  35. package/dist/modules/inline-edit/components/date-time.client.mjs +6 -1
  36. package/dist/modules/inline-edit/components/date-time.client.mjs.map +1 -1
  37. package/dist/modules/inline-edit/components/editor.client.mjs +5 -1
  38. package/dist/modules/inline-edit/components/editor.client.mjs.map +1 -1
  39. package/dist/modules/inline-edit/components/input-recipient.client.mjs +5 -1
  40. package/dist/modules/inline-edit/components/input-recipient.client.mjs.map +1 -1
  41. package/dist/modules/inline-edit/components/input-toggle.client.mjs +5 -1
  42. package/dist/modules/inline-edit/components/input-toggle.client.mjs.map +1 -1
  43. package/dist/modules/inline-edit/components/input.client.d.mts.map +1 -1
  44. package/dist/modules/inline-edit/components/input.client.mjs +15 -3
  45. package/dist/modules/inline-edit/components/input.client.mjs.map +1 -1
  46. package/dist/modules/inline-edit/components/select.client.d.mts.map +1 -1
  47. package/dist/modules/inline-edit/components/select.client.mjs +5 -1
  48. package/dist/modules/inline-edit/components/select.client.mjs.map +1 -1
  49. package/dist/modules/inline-edit/components/switch.client.mjs +5 -1
  50. package/dist/modules/inline-edit/components/switch.client.mjs.map +1 -1
  51. package/dist/modules/inline-edit/components/toggle.client.mjs +5 -1
  52. package/dist/modules/inline-edit/components/toggle.client.mjs.map +1 -1
  53. package/dist/modules/inline-edit/hooks/use-inline.client.d.mts +20 -5
  54. package/dist/modules/inline-edit/hooks/use-inline.client.d.mts.map +1 -1
  55. package/dist/modules/inline-edit/hooks/use-inline.client.mjs +11 -8
  56. package/dist/modules/inline-edit/hooks/use-inline.client.mjs.map +1 -1
  57. package/dist/modules/inline-edit/lib/variants.d.mts +1 -1
  58. package/dist/modules/storage/components/dropzone.client.d.mts +2 -2
  59. package/dist/modules/storage/components/dropzone.client.d.mts.map +1 -1
  60. package/dist/modules/storage/components/upload-zone-context.client.d.mts +1 -0
  61. package/dist/modules/storage/components/upload-zone-context.client.d.mts.map +1 -1
  62. package/dist/modules/storage/components/upload-zone-context.client.mjs.map +1 -1
  63. package/dist/modules/storage/components/upload-zone.client.d.mts +2 -1
  64. package/dist/modules/storage/components/upload-zone.client.d.mts.map +1 -1
  65. package/dist/modules/storage/components/upload-zone.client.mjs +5 -3
  66. package/dist/modules/storage/components/upload-zone.client.mjs.map +1 -1
  67. package/dist/modules/storage/lib/router.server.d.mts +11 -11
  68. package/dist/modules/storage/lib/service.server.d.mts +9 -9
  69. package/dist/modules/storage/lib/validators.d.mts +7 -7
  70. package/package.json +1 -1
  71. package/src/components/editor/components/menu-nodes.client.tsx +2 -2
  72. package/src/components/navigation/admin-sidebar.client.tsx +1 -0
  73. package/src/components/ui/input-date-time.tsx +12 -10
  74. package/src/lib/hooks/use-indicator.tsx +17 -8
  75. package/src/modules/auth/components/auth-layout.server.tsx +1 -1
  76. package/src/modules/commands/entry.client.ts +16 -0
  77. package/src/modules/commands/hooks/use-command-menu.client.tsx +2 -0
  78. package/src/modules/commands/menus/floating-menu.client.tsx +54 -0
  79. package/src/modules/data-tables/tables/data-table/components/table.tsx +11 -2
  80. package/src/modules/data-tables/tables/inline-table/components/table.tsx +11 -2
  81. package/src/modules/inline-edit/components/combobox-dropdown.client.tsx +4 -0
  82. package/src/modules/inline-edit/components/combobox.client.tsx +4 -0
  83. package/src/modules/inline-edit/components/date-input.client.tsx +4 -0
  84. package/src/modules/inline-edit/components/date-picker.client.tsx +4 -0
  85. package/src/modules/inline-edit/components/date-time.client.tsx +15 -1
  86. package/src/modules/inline-edit/components/editor.client.tsx +4 -0
  87. package/src/modules/inline-edit/components/input-recipient.client.tsx +4 -0
  88. package/src/modules/inline-edit/components/input-toggle.client.tsx +4 -0
  89. package/src/modules/inline-edit/components/input.client.tsx +12 -0
  90. package/src/modules/inline-edit/components/select.client.tsx +4 -0
  91. package/src/modules/inline-edit/components/switch.client.tsx +4 -0
  92. package/src/modules/inline-edit/components/toggle.client.tsx +4 -0
  93. package/src/modules/inline-edit/hooks/use-inline.client.tsx +37 -13
  94. package/src/modules/inline-edit/lib/parsers.ts +9 -0
  95. package/src/modules/storage/components/upload-zone-context.client.tsx +1 -0
  96. package/src/modules/storage/components/upload-zone.client.tsx +8 -2
  97. package/dist/modules/commands/menus/data-table-menu.client.mjs.map +0 -1
  98. package/src/modules/commands/menus/data-table-menu.client.tsx +0 -46
@@ -9,7 +9,7 @@ import { useCallback } from "react";
9
9
  import { useDropzone } from "react-dropzone";
10
10
 
11
11
  //#region src/modules/storage/components/upload-zone.client.tsx
12
- function UploadZone({ variables, optimistic, uploadClient, uploadHooks, onUploadCompleted, onUploadFailed, children, className, ...props }) {
12
+ function UploadZone({ variables, optimistic, uploadClient, uploadHooks, onUploadCompleted, onUploadFailed, disabled = false, children, className, ...props }) {
13
13
  /**
14
14
  * Delete mutation
15
15
  */
@@ -76,7 +76,8 @@ function UploadZone({ variables, optimistic, uploadClient, uploadHooks, onUpload
76
76
  if (acceptedFiles.length === 0) return;
77
77
  await Promise.allSettled(acceptedFiles.map(onUpload));
78
78
  }, [onUpload]),
79
- noClick: true
79
+ noClick: true,
80
+ disabled
80
81
  });
81
82
  return /* @__PURE__ */ jsxs("div", {
82
83
  ...props,
@@ -90,7 +91,8 @@ function UploadZone({ variables, optimistic, uploadClient, uploadHooks, onUpload
90
91
  uploadClient,
91
92
  onUpload,
92
93
  onRemove: deleteMutation.mutateAsync,
93
- optimistic
94
+ optimistic,
95
+ disabled
94
96
  },
95
97
  children
96
98
  })
@@ -1 +1 @@
1
- {"version":3,"file":"upload-zone.client.mjs","names":[],"sources":["../../../../src/modules/storage/components/upload-zone.client.tsx"],"sourcesContent":["\"use client\";\n\nimport { type ComponentProps, useCallback } from \"react\";\nimport { useDropzone } from \"react-dropzone\";\nimport { toast } from \"@/components/ui/sonner.client\";\nimport { useAction } from \"@/lib/hooks/use-action\";\nimport { cn } from \"@/lib/utils/cn\";\nimport type { UploadFileRequest, UploadHooks } from \"../lib/create-upload.client\";\nimport type { FileNode, Node, UploadFileSchema } from \"../lib/validators\";\nimport { UploadZoneContext, type UploadZoneContextValue } from \"./upload-zone-context.client\";\n\nexport type UploadZoneProps = ComponentProps<\"div\"> &\n Pick<UploadZoneContextValue, \"optimistic\" | \"uploadClient\"> & {\n variables: Pick<UploadFileSchema, \"namespace\" | \"parentId\" | \"mode\" | \"hidden\" | \"readonly\">;\n uploadHooks?: UploadHooks;\n\n onUploadCompleted?: (node: Node) => Promise<void> | void;\n onUploadFailed?: (error: unknown) => Promise<void> | void;\n };\n\nexport function UploadZone({\n variables,\n optimistic,\n uploadClient,\n uploadHooks,\n onUploadCompleted,\n onUploadFailed,\n children,\n className,\n ...props\n}: UploadZoneProps) {\n /**\n * Delete mutation\n */\n const deleteMutation = useAction({\n mutationFn: async (ids: string[]) => uploadClient.deleteFiles(ids),\n onMutate: async (ids) => {\n await optimistic?.cancel?.();\n await optimistic?.remove?.(ids);\n },\n onError: async (error) => {\n console.error(\"Delete failed upload error: \", error);\n await onUploadFailed?.(error);\n },\n onSettled: () => {\n optimistic?.invalidate?.();\n },\n });\n\n /**\n * Upload mutation\n */\n const uploadMutation = useAction({\n mutationFn: async (params: UploadFileRequest) => uploadClient.upload(params, uploadHooks),\n onMutate: async (variables) => {\n // Generate a new node\n const newNode = {\n ...variables,\n type: \"file\",\n isPending: true,\n } as FileNode;\n\n await optimistic?.cancel?.();\n await optimistic?.add?.(newNode);\n },\n onSuccess: async (data) => {\n await onUploadCompleted?.(data);\n toast.success(`Succesvol geupload: ${data.name}`);\n },\n onError: async (error, variables) => {\n await onUploadFailed?.(error);\n\n console.error(\"Upload error: \", error);\n toast.error(\"Bestand uploaden mislukt\", {\n description: error instanceof Error ? error.message : undefined,\n });\n\n console.info(\"Deleting failed upload\");\n await deleteMutation.mutateAsync([variables.id]);\n },\n onSettled: () => {\n optimistic?.invalidate?.();\n },\n });\n\n /**\n * Upload file handler\n */\n const onUpload = useCallback(\n async (file: File) => {\n console.info(\"Uploading file\", file);\n const req = uploadClient.prepareUpload({ ...variables, file });\n return await uploadMutation.mutateAsync(req);\n },\n [uploadClient, variables, uploadMutation],\n );\n\n /**\n * Drop handler\n */\n const onDrop = useCallback(\n async (acceptedFiles: File[]) => {\n if (acceptedFiles.length === 0) return;\n await Promise.allSettled(acceptedFiles.map(onUpload));\n },\n [onUpload],\n );\n\n const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop, noClick: true });\n\n return (\n <div {...props} {...getRootProps()} className={cn(\"relative z-0\", className)}>\n <input {...getInputProps()} />\n\n {/* Show drag overlay when drag is active */}\n {isDragActive && (\n <div className=\"bg-primary/20 absolute inset-0 z-10 rounded-md opacity-70 backdrop-blur-3xl\" />\n )}\n\n <UploadZoneContext\n value={{\n uploadClient,\n onUpload,\n onRemove: deleteMutation.mutateAsync,\n optimistic,\n }}\n >\n {children}\n </UploadZoneContext>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;AAoBA,SAAgB,WAAW,EACzB,WACA,YACA,cACA,aACA,mBACA,gBACA,UACA,WACA,GAAG,SACe;;;;CAIlB,MAAM,iBAAiB,UAAU;EAC/B,YAAY,OAAO,QAAkB,aAAa,YAAY,IAAI;EAClE,UAAU,OAAO,QAAQ;AACvB,SAAM,YAAY,UAAU;AAC5B,SAAM,YAAY,SAAS,IAAI;;EAEjC,SAAS,OAAO,UAAU;AACxB,WAAQ,MAAM,gCAAgC,MAAM;AACpD,SAAM,iBAAiB,MAAM;;EAE/B,iBAAiB;AACf,eAAY,cAAc;;EAE7B,CAAC;;;;CAKF,MAAM,iBAAiB,UAAU;EAC/B,YAAY,OAAO,WAA8B,aAAa,OAAO,QAAQ,YAAY;EACzF,UAAU,OAAO,cAAc;GAE7B,MAAM,UAAU;IACd,GAAG;IACH,MAAM;IACN,WAAW;IACZ;AAED,SAAM,YAAY,UAAU;AAC5B,SAAM,YAAY,MAAM,QAAQ;;EAElC,WAAW,OAAO,SAAS;AACzB,SAAM,oBAAoB,KAAK;AAC/B,SAAM,QAAQ,uBAAuB,KAAK,OAAO;;EAEnD,SAAS,OAAO,OAAO,cAAc;AACnC,SAAM,iBAAiB,MAAM;AAE7B,WAAQ,MAAM,kBAAkB,MAAM;AACtC,SAAM,MAAM,4BAA4B,EACtC,aAAa,iBAAiB,QAAQ,MAAM,UAAU,QACvD,CAAC;AAEF,WAAQ,KAAK,yBAAyB;AACtC,SAAM,eAAe,YAAY,CAAC,UAAU,GAAG,CAAC;;EAElD,iBAAiB;AACf,eAAY,cAAc;;EAE7B,CAAC;;;;CAKF,MAAM,WAAW,YACf,OAAO,SAAe;AACpB,UAAQ,KAAK,kBAAkB,KAAK;EACpC,MAAM,MAAM,aAAa,cAAc;GAAE,GAAG;GAAW;GAAM,CAAC;AAC9D,SAAO,MAAM,eAAe,YAAY,IAAI;IAE9C;EAAC;EAAc;EAAW;EAAe,CAC1C;CAaD,MAAM,EAAE,cAAc,eAAe,iBAAiB,YAAY;EAAE,QARrD,YACb,OAAO,kBAA0B;AAC/B,OAAI,cAAc,WAAW,EAAG;AAChC,SAAM,QAAQ,WAAW,cAAc,IAAI,SAAS,CAAC;KAEvD,CAAC,SAAS,CACX;EAE2E,SAAS;EAAM,CAAC;AAE5F,QACE,qBAAC;EAAI,GAAI;EAAO,GAAI,cAAc;EAAE,WAAW,GAAG,gBAAgB,UAAU;;GAC1E,oBAAC,WAAM,GAAI,eAAe,GAAI;GAG7B,gBACC,oBAAC,SAAI,WAAU,gFAAgF;GAGjG,oBAAC;IACC,OAAO;KACL;KACA;KACA,UAAU,eAAe;KACzB;KACD;IAEA;KACiB;;GAChB"}
1
+ {"version":3,"file":"upload-zone.client.mjs","names":[],"sources":["../../../../src/modules/storage/components/upload-zone.client.tsx"],"sourcesContent":["\"use client\";\n\nimport { type ComponentProps, useCallback } from \"react\";\nimport { useDropzone } from \"react-dropzone\";\nimport { toast } from \"@/components/ui/sonner.client\";\nimport { useAction } from \"@/lib/hooks/use-action\";\nimport { cn } from \"@/lib/utils/cn\";\nimport type { UploadFileRequest, UploadHooks } from \"../lib/create-upload.client\";\nimport type { FileNode, Node, UploadFileSchema } from \"../lib/validators\";\nimport { UploadZoneContext, type UploadZoneContextValue } from \"./upload-zone-context.client\";\n\nexport type UploadZoneProps = ComponentProps<\"div\"> &\n Pick<UploadZoneContextValue, \"optimistic\" | \"uploadClient\" | \"disabled\"> & {\n variables: Pick<UploadFileSchema, \"namespace\" | \"parentId\" | \"mode\" | \"hidden\" | \"readonly\">;\n uploadHooks?: UploadHooks;\n\n onUploadCompleted?: (node: Node) => Promise<void> | void;\n onUploadFailed?: (error: unknown) => Promise<void> | void;\n };\n\nexport function UploadZone({\n variables,\n optimistic,\n uploadClient,\n uploadHooks,\n onUploadCompleted,\n onUploadFailed,\n disabled = false,\n children,\n className,\n ...props\n}: UploadZoneProps) {\n /**\n * Delete mutation\n */\n const deleteMutation = useAction({\n mutationFn: async (ids: string[]) => uploadClient.deleteFiles(ids),\n onMutate: async (ids) => {\n await optimistic?.cancel?.();\n await optimistic?.remove?.(ids);\n },\n onError: async (error) => {\n console.error(\"Delete failed upload error: \", error);\n await onUploadFailed?.(error);\n },\n onSettled: () => {\n optimistic?.invalidate?.();\n },\n });\n\n /**\n * Upload mutation\n */\n const uploadMutation = useAction({\n mutationFn: async (params: UploadFileRequest) => uploadClient.upload(params, uploadHooks),\n onMutate: async (variables) => {\n // Generate a new node\n const newNode = {\n ...variables,\n type: \"file\",\n isPending: true,\n } as FileNode;\n\n await optimistic?.cancel?.();\n await optimistic?.add?.(newNode);\n },\n onSuccess: async (data) => {\n await onUploadCompleted?.(data);\n toast.success(`Succesvol geupload: ${data.name}`);\n },\n onError: async (error, variables) => {\n await onUploadFailed?.(error);\n\n console.error(\"Upload error: \", error);\n toast.error(\"Bestand uploaden mislukt\", {\n description: error instanceof Error ? error.message : undefined,\n });\n\n console.info(\"Deleting failed upload\");\n await deleteMutation.mutateAsync([variables.id]);\n },\n onSettled: () => {\n optimistic?.invalidate?.();\n },\n });\n\n /**\n * Upload file handler\n */\n const onUpload = useCallback(\n async (file: File) => {\n console.info(\"Uploading file\", file);\n const req = uploadClient.prepareUpload({ ...variables, file });\n return await uploadMutation.mutateAsync(req);\n },\n [uploadClient, variables, uploadMutation],\n );\n\n /**\n * Drop handler\n */\n const onDrop = useCallback(\n async (acceptedFiles: File[]) => {\n if (acceptedFiles.length === 0) return;\n await Promise.allSettled(acceptedFiles.map(onUpload));\n },\n [onUpload],\n );\n\n const { getRootProps, getInputProps, isDragActive } = useDropzone({\n onDrop,\n noClick: true,\n disabled,\n });\n\n return (\n <div {...props} {...getRootProps()} className={cn(\"relative z-0\", className)}>\n <input {...getInputProps()} />\n\n {/* Show drag overlay when drag is active */}\n {isDragActive && (\n <div className=\"bg-primary/20 absolute inset-0 z-10 rounded-md opacity-70 backdrop-blur-3xl\" />\n )}\n\n <UploadZoneContext\n value={{\n uploadClient,\n onUpload,\n onRemove: deleteMutation.mutateAsync,\n optimistic,\n disabled,\n }}\n >\n {children}\n </UploadZoneContext>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;AAoBA,SAAgB,WAAW,EACzB,WACA,YACA,cACA,aACA,mBACA,gBACA,WAAW,OACX,UACA,WACA,GAAG,SACe;;;;CAIlB,MAAM,iBAAiB,UAAU;EAC/B,YAAY,OAAO,QAAkB,aAAa,YAAY,IAAI;EAClE,UAAU,OAAO,QAAQ;AACvB,SAAM,YAAY,UAAU;AAC5B,SAAM,YAAY,SAAS,IAAI;;EAEjC,SAAS,OAAO,UAAU;AACxB,WAAQ,MAAM,gCAAgC,MAAM;AACpD,SAAM,iBAAiB,MAAM;;EAE/B,iBAAiB;AACf,eAAY,cAAc;;EAE7B,CAAC;;;;CAKF,MAAM,iBAAiB,UAAU;EAC/B,YAAY,OAAO,WAA8B,aAAa,OAAO,QAAQ,YAAY;EACzF,UAAU,OAAO,cAAc;GAE7B,MAAM,UAAU;IACd,GAAG;IACH,MAAM;IACN,WAAW;IACZ;AAED,SAAM,YAAY,UAAU;AAC5B,SAAM,YAAY,MAAM,QAAQ;;EAElC,WAAW,OAAO,SAAS;AACzB,SAAM,oBAAoB,KAAK;AAC/B,SAAM,QAAQ,uBAAuB,KAAK,OAAO;;EAEnD,SAAS,OAAO,OAAO,cAAc;AACnC,SAAM,iBAAiB,MAAM;AAE7B,WAAQ,MAAM,kBAAkB,MAAM;AACtC,SAAM,MAAM,4BAA4B,EACtC,aAAa,iBAAiB,QAAQ,MAAM,UAAU,QACvD,CAAC;AAEF,WAAQ,KAAK,yBAAyB;AACtC,SAAM,eAAe,YAAY,CAAC,UAAU,GAAG,CAAC;;EAElD,iBAAiB;AACf,eAAY,cAAc;;EAE7B,CAAC;;;;CAKF,MAAM,WAAW,YACf,OAAO,SAAe;AACpB,UAAQ,KAAK,kBAAkB,KAAK;EACpC,MAAM,MAAM,aAAa,cAAc;GAAE,GAAG;GAAW;GAAM,CAAC;AAC9D,SAAO,MAAM,eAAe,YAAY,IAAI;IAE9C;EAAC;EAAc;EAAW;EAAe,CAC1C;CAaD,MAAM,EAAE,cAAc,eAAe,iBAAiB,YAAY;EAChE,QATa,YACb,OAAO,kBAA0B;AAC/B,OAAI,cAAc,WAAW,EAAG;AAChC,SAAM,QAAQ,WAAW,cAAc,IAAI,SAAS,CAAC;KAEvD,CAAC,SAAS,CACX;EAIC,SAAS;EACT;EACD,CAAC;AAEF,QACE,qBAAC;EAAI,GAAI;EAAO,GAAI,cAAc;EAAE,WAAW,GAAG,gBAAgB,UAAU;;GAC1E,oBAAC,WAAM,GAAI,eAAe,GAAI;GAG7B,gBACC,oBAAC,SAAI,WAAU,gFAAgF;GAGjG,oBAAC;IACC,OAAO;KACL;KACA;KACA,UAAU,eAAe;KACzB;KACA;KACD;IAEA;KACiB;;GAChB"}
@@ -6151,8 +6151,8 @@ declare function createDriveBaseProcedures(): {
6151
6151
  node: drizzle_orm0.One<"nodes", true>;
6152
6152
  }>;
6153
6153
  }>>, z$1.ZodObject<{
6154
- sort: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodString>>;
6155
6154
  search: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodString>>;
6155
+ sort: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodString>>;
6156
6156
  order: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodEnum<{
6157
6157
  asc: "asc";
6158
6158
  desc: "desc";
@@ -9386,14 +9386,14 @@ declare function createDriveBaseProcedures(): {
9386
9386
  id: z$1.ZodNullable<z$1.ZodString>;
9387
9387
  namespace: z$1.ZodString;
9388
9388
  }, z$1.core.$strip>, _orpc_contract0.Schema<(Pick<{
9389
+ isPending: boolean;
9389
9390
  id: string;
9390
- readonly: boolean | null;
9391
- type: "file" | "folder" | null;
9392
9391
  createdAt: Date;
9393
9392
  updatedAt: Date;
9394
9393
  name: string;
9394
+ type: "file" | "folder" | null;
9395
+ readonly: boolean | null;
9395
9396
  mode: "private" | "public" | null;
9396
- isPending: boolean;
9397
9397
  namespace: string;
9398
9398
  subtype: "image" | "document" | "spreadsheet" | "video" | "audio" | "archive" | "other";
9399
9399
  size: number | null;
@@ -9406,14 +9406,14 @@ declare function createDriveBaseProcedures(): {
9406
9406
  }, "id" | "name" | "parentId"> & {
9407
9407
  depth: number;
9408
9408
  })[], (Pick<{
9409
+ isPending: boolean;
9409
9410
  id: string;
9410
- readonly: boolean | null;
9411
- type: "file" | "folder" | null;
9412
9411
  createdAt: Date;
9413
9412
  updatedAt: Date;
9414
9413
  name: string;
9414
+ type: "file" | "folder" | null;
9415
+ readonly: boolean | null;
9415
9416
  mode: "private" | "public" | null;
9416
- isPending: boolean;
9417
9417
  namespace: string;
9418
9418
  subtype: "image" | "document" | "spreadsheet" | "video" | "audio" | "archive" | "other";
9419
9419
  size: number | null;
@@ -15244,15 +15244,15 @@ declare function createDriveBaseProcedures(): {
15244
15244
  node: drizzle_orm0.One<"nodes", true>;
15245
15245
  }>;
15246
15246
  }>>, z$1.ZodObject<{
15247
- readonly: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodBoolean>>;
15247
+ isPending: z$1.ZodOptional<z$1.ZodBoolean>;
15248
15248
  createdAt: z$1.ZodOptional<z$1.ZodDate>;
15249
15249
  updatedAt: z$1.ZodOptional<z$1.ZodDate>;
15250
15250
  name: z$1.ZodString;
15251
+ readonly: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodBoolean>>;
15251
15252
  mode: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodEnum<{
15252
15253
  private: "private";
15253
15254
  public: "public";
15254
15255
  }>>>;
15255
- isPending: z$1.ZodOptional<z$1.ZodBoolean>;
15256
15256
  namespace: z$1.ZodString;
15257
15257
  subtype: z$1.ZodOptional<z$1.ZodEnum<{
15258
15258
  image: "image";
@@ -21380,16 +21380,16 @@ declare function createDriveBaseProcedures(): {
21380
21380
  node: drizzle_orm0.One<"nodes", true>;
21381
21381
  }>;
21382
21382
  }>>, z$1.ZodObject<{
21383
+ isPending: z$1.ZodOptional<z$1.ZodBoolean>;
21383
21384
  id: z$1.ZodOptional<z$1.ZodUUID>;
21384
- readonly: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodBoolean>>;
21385
21385
  createdAt: z$1.ZodOptional<z$1.ZodDate>;
21386
21386
  updatedAt: z$1.ZodOptional<z$1.ZodDate>;
21387
21387
  name: z$1.ZodString;
21388
+ readonly: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodBoolean>>;
21388
21389
  mode: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodEnum<{
21389
21390
  private: "private";
21390
21391
  public: "public";
21391
21392
  }>>>;
21392
- isPending: z$1.ZodOptional<z$1.ZodBoolean>;
21393
21393
  namespace: z$1.ZodString;
21394
21394
  hidden: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodBoolean>>;
21395
21395
  createdBy: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodUUID>>;
@@ -91,14 +91,14 @@ declare class StorageService<TSchema extends TDatabaseSchema> {
91
91
  * Upload file to S3 and add it to the database
92
92
  **/
93
93
  uploadFile(input: UploadFileSchema & Pick<PutObjectInput, "body">): Promise<{
94
+ isPending: boolean;
94
95
  id: string;
95
- readonly: boolean | null;
96
- type: "file" | "folder" | null;
97
96
  createdAt: Date;
98
97
  updatedAt: Date;
99
98
  name: string;
99
+ type: "file" | "folder" | null;
100
+ readonly: boolean | null;
100
101
  mode: "private" | "public" | null;
101
- isPending: boolean;
102
102
  namespace: string;
103
103
  subtype: "image" | "document" | "spreadsheet" | "video" | "audio" | "archive" | "other";
104
104
  size: number | null;
@@ -116,14 +116,14 @@ declare class StorageService<TSchema extends TDatabaseSchema> {
116
116
  id: string;
117
117
  presignedUrl: string;
118
118
  node: {
119
+ isPending: boolean;
119
120
  id: string;
120
- readonly: boolean | null;
121
- type: "file" | "folder" | null;
122
121
  createdAt: Date;
123
122
  updatedAt: Date;
124
123
  name: string;
124
+ type: "file" | "folder" | null;
125
+ readonly: boolean | null;
125
126
  mode: "private" | "public" | null;
126
- isPending: boolean;
127
127
  namespace: string;
128
128
  subtype: "image" | "document" | "spreadsheet" | "video" | "audio" | "archive" | "other";
129
129
  size: number | null;
@@ -151,14 +151,14 @@ declare class StorageService<TSchema extends TDatabaseSchema> {
151
151
  * Create a new folder
152
152
  */
153
153
  createFolder(input: CreateFolderNodeSchema): Promise<{
154
+ isPending: boolean;
154
155
  id: string;
155
- readonly: boolean | null;
156
- type: "file" | "folder" | null;
157
156
  createdAt: Date;
158
157
  updatedAt: Date;
159
158
  name: string;
159
+ type: "file" | "folder" | null;
160
+ readonly: boolean | null;
160
161
  mode: "private" | "public" | null;
161
- isPending: boolean;
162
162
  namespace: string;
163
163
  subtype: "image" | "document" | "spreadsheet" | "video" | "audio" | "archive" | "other";
164
164
  size: number | null;
@@ -1285,16 +1285,16 @@ type NodesTableFilters = z$1.input<typeof nodesTableFiltersSchema>;
1285
1285
  * Create folder node
1286
1286
  */
1287
1287
  declare const createFolderNodeSchema: z$1.ZodObject<{
1288
+ isPending: z$1.ZodOptional<z$1.ZodBoolean>;
1288
1289
  id: z$1.ZodOptional<z$1.ZodUUID>;
1289
- readonly: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodBoolean>>;
1290
1290
  createdAt: z$1.ZodOptional<z$1.ZodDate>;
1291
1291
  updatedAt: z$1.ZodOptional<z$1.ZodDate>;
1292
1292
  name: z$1.ZodString;
1293
+ readonly: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodBoolean>>;
1293
1294
  mode: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodEnum<{
1294
1295
  private: "private";
1295
1296
  public: "public";
1296
1297
  }>>>;
1297
- isPending: z$1.ZodOptional<z$1.ZodBoolean>;
1298
1298
  namespace: z$1.ZodString;
1299
1299
  hidden: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodBoolean>>;
1300
1300
  createdBy: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodUUID>>;
@@ -1310,16 +1310,16 @@ type CreateFolderNodeSchema = z$1.infer<typeof createFolderNodeSchema>;
1310
1310
  * Upload file schema
1311
1311
  */
1312
1312
  declare const uploadFileSchema: z$1.ZodObject<{
1313
+ isPending: z$1.ZodOptional<z$1.ZodBoolean>;
1313
1314
  id: z$1.ZodOptional<z$1.ZodUUID>;
1314
- readonly: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodBoolean>>;
1315
1315
  createdAt: z$1.ZodOptional<z$1.ZodDate>;
1316
1316
  updatedAt: z$1.ZodOptional<z$1.ZodDate>;
1317
1317
  name: z$1.ZodString;
1318
+ readonly: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodBoolean>>;
1318
1319
  mode: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodEnum<{
1319
1320
  private: "private";
1320
1321
  public: "public";
1321
1322
  }>>>;
1322
- isPending: z$1.ZodOptional<z$1.ZodBoolean>;
1323
1323
  namespace: z$1.ZodString;
1324
1324
  subtype: z$1.ZodOptional<z$1.ZodEnum<{
1325
1325
  image: "image";
@@ -1346,15 +1346,15 @@ type UploadFileSchema = z$1.infer<typeof uploadFileSchema>;
1346
1346
  * Presign file schema
1347
1347
  */
1348
1348
  declare const presignFileSchema: z$1.ZodObject<{
1349
- readonly: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodBoolean>>;
1349
+ isPending: z$1.ZodOptional<z$1.ZodBoolean>;
1350
1350
  createdAt: z$1.ZodOptional<z$1.ZodDate>;
1351
1351
  updatedAt: z$1.ZodOptional<z$1.ZodDate>;
1352
1352
  name: z$1.ZodString;
1353
+ readonly: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodBoolean>>;
1353
1354
  mode: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodEnum<{
1354
1355
  private: "private";
1355
1356
  public: "public";
1356
1357
  }>>>;
1357
- isPending: z$1.ZodOptional<z$1.ZodBoolean>;
1358
1358
  namespace: z$1.ZodString;
1359
1359
  subtype: z$1.ZodOptional<z$1.ZodEnum<{
1360
1360
  image: "image";
@@ -1401,8 +1401,8 @@ type GetFileURLSchema = z$1.infer<typeof getFileURLSchema>;
1401
1401
  * Get by parent id input
1402
1402
  */
1403
1403
  declare const getNodesByParentIdSchema: z$1.ZodObject<{
1404
- sort: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodString>>;
1405
1404
  search: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodString>>;
1405
+ sort: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodString>>;
1406
1406
  order: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodEnum<{
1407
1407
  asc: "asc";
1408
1408
  desc: "desc";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tulip-systems/core",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "license": "MIT",
@@ -104,9 +104,9 @@ export function EditorMenuNodes() {
104
104
  </DropdownMenuTrigger>
105
105
 
106
106
  <DropdownMenuContent>
107
- {filteredBlocks.map(({ label, icon: Icon, handler }, index) => (
107
+ {filteredBlocks.map(({ label, icon: Icon, handler }) => (
108
108
  <DropdownMenuItem
109
- key={index}
109
+ key={label}
110
110
  onClick={() => handler(editor)}
111
111
  className="flex items-center gap-2"
112
112
  >
@@ -29,6 +29,7 @@ import {
29
29
 
30
30
  /**
31
31
  * AdminSidebar
32
+ * @deprecated
32
33
  */
33
34
  export function AdminSidebar({
34
35
  paths,
@@ -6,10 +6,10 @@ import { Input } from "./input";
6
6
  * DateTimeInput
7
7
  */
8
8
  type DateTimeInputProps = Omit<React.ComponentProps<"input">, "type" | "value" | "defaultValue"> & {
9
- defaultValue?: Date;
10
- value?: Date;
11
- onValueChange?: (date: Date | undefined) => void;
12
- onValueBlur?: (date: Date | undefined) => void;
9
+ defaultValue?: Date | string;
10
+ value?: Date | string;
11
+ onValueChange?: (date: string | undefined) => void;
12
+ onValueBlur?: (date: string | undefined) => void;
13
13
  };
14
14
 
15
15
  export function DateTimeInput({
@@ -26,12 +26,16 @@ export function DateTimeInput({
26
26
  const defaultValue =
27
27
  props.defaultValue instanceof Date
28
28
  ? format(props.defaultValue, "yyyy-MM-dd'T'HH:mm")
29
- : undefined;
29
+ : typeof props.defaultValue === "string"
30
+ ? props.defaultValue
31
+ : undefined;
30
32
 
31
33
  const value =
32
34
  props.value && props.value instanceof Date
33
35
  ? format(props.value, "yyyy-MM-dd'T'HH:mm")
34
- : undefined;
36
+ : typeof props.value === "string"
37
+ ? props.value
38
+ : undefined;
35
39
 
36
40
  return (
37
41
  <Input
@@ -40,13 +44,11 @@ export function DateTimeInput({
40
44
  defaultValue={defaultValue}
41
45
  value={value}
42
46
  onChange={(e) => {
43
- const date = new Date(e.target.value);
44
- onValueChange?.(date ?? undefined);
47
+ onValueChange?.(e.target.value ?? undefined);
45
48
  onChange?.(e);
46
49
  }}
47
50
  onBlur={(e) => {
48
- const date = new Date(e.target.value);
49
- onValueBlur?.(date ?? undefined);
51
+ onValueBlur?.(e.target.value ?? undefined);
50
52
  onBlur?.(e);
51
53
  }}
52
54
  className={cn(
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
 
3
3
  import type React from "react";
4
- import { createContext, useContext, useEffect, useState, useTransition } from "react";
4
+ import { createContext, useCallback, useContext, useEffect, useState, useTransition } from "react";
5
5
 
6
6
  /**
7
7
  * Indicator status
@@ -15,7 +15,7 @@ export function useLocalIndicator() {
15
15
  /**
16
16
  * Start transition
17
17
  */
18
- const [isPending, startTransition] = useTransition();
18
+ const [, startTransitionBase] = useTransition();
19
19
 
20
20
  /**
21
21
  * Status of the inline edit indicator
@@ -25,19 +25,28 @@ export function useLocalIndicator() {
25
25
  /**
26
26
  * Set status to pending when isPending is true
27
27
  */
28
- useEffect(() => {
29
- if (isPending) setStatus("pending");
30
- }, [isPending]);
28
+ const startTransition = useCallback<React.TransitionStartFunction>(
29
+ (callback) => {
30
+ setStatus("pending");
31
+ startTransitionBase(callback);
32
+ },
33
+ [],
34
+ );
31
35
 
32
36
  /**
33
37
  * Set status back to idle after 1.5 seconds when status is succes
34
38
  * Set status back to idle after 3 seconds when status is error
35
39
  */
36
- useEffect(() => {
37
- if (status === "success") setTimeout(() => setStatus("idle"), 1000);
38
- if (status === "error") setTimeout(() => setStatus("idle"), 2000);
40
+ const resetAfterDelay = useCallback(() => {
41
+ if (status !== "success" && status !== "error") return undefined;
42
+
43
+ const timeout = setTimeout(() => setStatus("idle"), status === "success" ? 1000 : 2000);
44
+
45
+ return () => clearTimeout(timeout);
39
46
  }, [status]);
40
47
 
48
+ useEffect(() => resetAfterDelay(), [resetAfterDelay]);
49
+
41
50
  return { status, setStatus, startTransition };
42
51
  }
43
52
 
@@ -4,7 +4,7 @@ import type { PropsWithChildren } from "react";
4
4
 
5
5
  export async function AuthLayout(props: PropsWithChildren<{ name: string }>) {
6
6
  return (
7
- <div className="container relative mx-auto grid h-[100dvh] flex-col items-center justify-center lg:max-w-none lg:grid-cols-2 lg:px-0">
7
+ <div className="container relative mx-auto grid h-dvh flex-col items-center justify-center lg:max-w-none lg:grid-cols-2 lg:px-0">
8
8
  <div className="bg-muted relative hidden h-full flex-col p-10 text-white lg:flex dark:border-r">
9
9
  <Image src="/images/auth-background.jpeg" alt="Background" className="object-cover" fill />
10
10
 
@@ -1,3 +1,6 @@
1
+ /**
2
+ * Components
3
+ */
1
4
  export * from "./components/alert-dialog-command.client";
2
5
  export * from "./components/click-command.client";
3
6
  export * from "./components/command-trigger.client";
@@ -5,11 +8,24 @@ export * from "./components/dialog-command.client";
5
8
  export * from "./components/dropdown-command.client";
6
9
  export * from "./components/empty-command.client";
7
10
  export * from "./components/form-dialog-command.client";
11
+
12
+ /**
13
+ * Hooks
14
+ */
8
15
  export * from "./hooks/use-command-mutation.client";
16
+
17
+ /**
18
+ * Menus
19
+ */
9
20
  export * from "./menus/context-menu.client";
10
21
  export * from "./menus/dropdown-menu.client";
22
+ export * from "./menus/floating-menu.client";
11
23
  export * from "./menus/inline-menu.client";
12
24
  export * from "./menus/responsive-menu.client";
25
+
26
+ /**
27
+ * Utils
28
+ */
13
29
  export * from "./utils/archive-command.client";
14
30
  export * from "./utils/delete-command.client";
15
31
  export * from "./utils/send-mail-command.client";
@@ -13,12 +13,14 @@ export type SingleCommandMenuProps<TData, TMeta> = {
13
13
  data: TData;
14
14
  commands: CommandDef<TData, TMeta>[];
15
15
  meta?: TMeta;
16
+ onSuccess?: () => void;
16
17
  };
17
18
 
18
19
  export type BulkCommandMenuProps<TData, TMeta> = {
19
20
  data: TData[];
20
21
  commands: CommandDef<TData, TMeta>[];
21
22
  meta?: TMeta;
23
+ onSuccess?: () => void;
22
24
  };
23
25
 
24
26
  /**
@@ -0,0 +1,54 @@
1
+ "use client";
2
+
3
+ import { useRef } from "react";
4
+ import { cn } from "@/lib/utils/cn";
5
+ import { RenderCommand } from "../components/render-command";
6
+ import { CommandContextProvider } from "../hooks/context.client";
7
+ import { type BulkCommandMenuProps, useBulkCommandMenu } from "../hooks/use-command-menu.client";
8
+
9
+ type FloatingCommandMenuProps<TData, TMeta> = BulkCommandMenuProps<TData, TMeta> &
10
+ React.HTMLAttributes<HTMLElement> & {
11
+ state: "open" | "closed";
12
+ };
13
+
14
+ export function FloatingCommandMenu<TData, TMeta>({
15
+ data,
16
+ commands,
17
+ meta,
18
+ state,
19
+ onSuccess,
20
+ className,
21
+ ...props
22
+ }: FloatingCommandMenuProps<TData, TMeta>) {
23
+ const hasCommands = useRef(true);
24
+
25
+ const [validCommands, renderCommand] = useBulkCommandMenu({ data, commands, meta });
26
+
27
+ return (
28
+ <div
29
+ {...props}
30
+ data-state={state}
31
+ className={cn(
32
+ "bg-muted/80 fixed bottom-12 left-0 right-0 z-50 mx-auto flex w-fit items-center rounded-xl border px-3 py-2 shadow-xl backdrop-blur-2xl data-[state=open]:flex data-[state=closed]:hidden",
33
+ className,
34
+ )}
35
+ >
36
+ <CommandContextProvider value={{ menu: "table", onSuccess }}>
37
+ <div
38
+ className="flex gap-2"
39
+ ref={(ref) => {
40
+ if (ref?.childNodes.length === 0) hasCommands.current = false;
41
+ }}
42
+ >
43
+ {validCommands.map((command) => (
44
+ <RenderCommand key={command.name} command={command} render={renderCommand} />
45
+ ))}
46
+ </div>
47
+
48
+ {!hasCommands.current && (
49
+ <span className="text-sm font-medium">Geen acties beschikbaar</span>
50
+ )}
51
+ </CommandContextProvider>
52
+ </div>
53
+ );
54
+ }
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
 
3
3
  import type { ComponentProps } from "react";
4
- import { TableCommandMenu } from "@/modules/commands/menus/data-table-menu.client";
4
+ import { FloatingCommandMenu } from "@/modules/commands/menus/floating-menu.client";
5
5
  import { TableBottombar, TableFooter } from "@/modules/data-tables/components/footer";
6
6
  import { Table } from "@/modules/data-tables/components/table";
7
7
  import type { TableMeta } from "@/modules/data-tables/entry";
@@ -24,7 +24,16 @@ export function DataTable<TData extends { id: string }>(props: ComponentProps<ty
24
24
  </div>
25
25
 
26
26
  <TableBottombar table={table} />
27
- {meta.commands && <TableCommandMenu table={table} />}
27
+
28
+ {meta.commands && (
29
+ <FloatingCommandMenu
30
+ data={meta.selectedData}
31
+ commands={meta.commands}
32
+ meta={meta}
33
+ state={meta.selectedData?.length ? "open" : "closed"}
34
+ onSuccess={() => table.resetRowSelection()}
35
+ />
36
+ )}
28
37
  </div>
29
38
  );
30
39
  }
@@ -2,7 +2,7 @@
2
2
 
3
3
  import type { ComponentProps } from "react";
4
4
  import { HotkeysProvider } from "react-hotkeys-hook";
5
- import { TableCommandMenu } from "@/modules/commands/menus/data-table-menu.client";
5
+ import { FloatingCommandMenu } from "@/modules/commands/menus/floating-menu.client";
6
6
  import { TableBottombar, TableFooter } from "@/modules/data-tables/components/footer";
7
7
  import { Table } from "@/modules/data-tables/components/table";
8
8
  import type { TableMeta } from "@/modules/data-tables/entry";
@@ -35,7 +35,16 @@ export function InlineTable<TData extends { id: string }>({
35
35
  </div>
36
36
 
37
37
  <TableBottombar table={table} />
38
- {meta.commands && <TableCommandMenu table={table} />}
38
+
39
+ {meta.commands && (
40
+ <FloatingCommandMenu
41
+ data={meta.selectedData}
42
+ commands={meta.commands}
43
+ meta={meta}
44
+ state={meta.selectedData?.length ? "open" : "closed"}
45
+ onSuccess={() => table.resetRowSelection()}
46
+ />
47
+ )}
39
48
  </div>
40
49
  </InlineTableProvider>
41
50
  );
@@ -40,6 +40,10 @@ export function InlineComboboxDropdown<
40
40
  permission,
41
41
  updateStrategy,
42
42
  isRequired,
43
+ parser: {
44
+ decode: (value) => value,
45
+ encode: (value) => value,
46
+ },
43
47
  });
44
48
 
45
49
  const initialSelectedItem = props.items.find((item) => item.id === initialValue);
@@ -26,6 +26,10 @@ export function InlineCombobox<TValue, Required extends boolean>({
26
26
  permission,
27
27
  updateStrategy,
28
28
  isRequired,
29
+ parser: {
30
+ decode: (value) => value,
31
+ encode: (value) => value,
32
+ },
29
33
  });
30
34
 
31
35
  return (
@@ -33,6 +33,10 @@ export function InlineDateInput<Required extends boolean = false>({
33
33
  permission,
34
34
  updateStrategy,
35
35
  isRequired,
36
+ parser: {
37
+ decode: (value) => value,
38
+ encode: (value) => value,
39
+ },
36
40
  });
37
41
 
38
42
  const [stringDate, setStringDate] = React.useState<string>(
@@ -33,6 +33,10 @@ export function InlineDatePicker<Required extends boolean = false>({
33
33
  permission,
34
34
  updateStrategy,
35
35
  isRequired,
36
+ parser: {
37
+ decode: (value) => value,
38
+ encode: (value) => value,
39
+ },
36
40
  });
37
41
 
38
42
  return (
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
 
3
+ import { format } from "date-fns";
3
4
  import type { ComponentProps } from "react";
4
5
  import { DateTimeInput } from "@/components/ui/input-date-time";
5
6
  import { cn } from "@/lib/utils/cn";
@@ -19,12 +20,25 @@ export function InlineDateTimeInput<Required extends boolean = false>({
19
20
  }: ComponentProps<typeof DateTimeInput> &
20
21
  useInlineEditOptions<Date, Required> &
21
22
  InlineEditVariantsProps) {
22
- const { value, handleChange, handleBlur, status, isAllowed } = useInlineEdit({
23
+ const { value, handleChange, handleBlur, status, isAllowed } = useInlineEdit<
24
+ string,
25
+ Date,
26
+ Required
27
+ >({
23
28
  initialValue,
24
29
  action,
25
30
  permission,
26
31
  updateStrategy,
27
32
  isRequired,
33
+ parser: {
34
+ decode: (value) =>
35
+ (value instanceof Date
36
+ ? format(value, "yyyy-MM-dd'T'HH:mm")
37
+ : typeof value === "string"
38
+ ? value
39
+ : undefined) as string,
40
+ encode: (value) => (value ? new Date(value) : null) as Date,
41
+ },
28
42
  });
29
43
 
30
44
  return (
@@ -31,6 +31,10 @@ export function InlineEditor<Required extends boolean = false>({
31
31
  permission,
32
32
  updateStrategy,
33
33
  isRequired,
34
+ parser: {
35
+ decode: (value) => value,
36
+ encode: (value) => value,
37
+ },
34
38
  });
35
39
 
36
40
  return (