@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
@@ -36,6 +36,10 @@ export function InlineRecipientInput<Required extends boolean = false>({
36
36
  permission,
37
37
  updateStrategy,
38
38
  isRequired,
39
+ parser: {
40
+ decode: (value) => value,
41
+ encode: (value) => value,
42
+ },
39
43
  });
40
44
 
41
45
  return (
@@ -31,6 +31,10 @@ export function InlineStringInputToggle<Required extends boolean>({
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
  function handleToggle() {
@@ -33,6 +33,10 @@ export function InlineStringInput<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 (
@@ -75,6 +79,10 @@ export function InlineNumberInput<Required extends boolean = false>({
75
79
  permission,
76
80
  updateStrategy,
77
81
  isRequired,
82
+ parser: {
83
+ decode: (value) => value,
84
+ encode: (value) => value,
85
+ },
78
86
  });
79
87
 
80
88
  return (
@@ -114,6 +122,10 @@ export function InlineDecimalInput({
114
122
  permission,
115
123
  updateStrategy,
116
124
  isRequired,
125
+ parser: {
126
+ decode: (value) => value,
127
+ encode: (value) => value,
128
+ },
117
129
  });
118
130
 
119
131
  return (
@@ -34,6 +34,10 @@ export function InlineSelect<Required extends boolean = false>({
34
34
  permission,
35
35
  updateStrategy,
36
36
  isRequired,
37
+ parser: {
38
+ decode: (value) => value,
39
+ encode: (value) => value,
40
+ },
37
41
  });
38
42
 
39
43
  return (
@@ -19,6 +19,10 @@ export function InlineSwitch<Required extends boolean = false>({
19
19
  permission,
20
20
  updateStrategy,
21
21
  isRequired,
22
+ parser: {
23
+ decode: (value) => value,
24
+ encode: (value) => value,
25
+ },
22
26
  });
23
27
 
24
28
  return (
@@ -24,6 +24,10 @@ export function InlineToggle<Required extends boolean = false>({
24
24
  permission,
25
25
  updateStrategy,
26
26
  isRequired,
27
+ parser: {
28
+ decode: (value) => value,
29
+ encode: (value) => value,
30
+ },
27
31
  });
28
32
 
29
33
  return (
@@ -28,15 +28,15 @@ type MaybeValue<TValue, Required extends boolean> = Required extends true ? TVal
28
28
  /**
29
29
  * Use the inline edit hook options.
30
30
  */
31
- export type useInlineEditOptions<TValue, Required extends boolean = false> = {
31
+ export type useInlineEditOptions<TResult, Required extends boolean = false> = {
32
32
  /**
33
33
  * Initial value
34
34
  */
35
- initialValue?: MaybeValue<TValue, Required>;
35
+ initialValue?: MaybeValue<TResult, Required>;
36
36
  /**
37
37
  * Action to execute on update
38
38
  */
39
- action: (value: { id: string; value: MaybeValue<TValue, Required> }) => Promise<unknown>;
39
+ action: (value: { id: string; value: MaybeValue<TResult, Required> }) => Promise<unknown>;
40
40
  /**
41
41
  * Permission required to edit
42
42
  */
@@ -55,18 +55,40 @@ export type useInlineEditOptions<TValue, Required extends boolean = false> = {
55
55
  isRequired?: Required;
56
56
  };
57
57
 
58
+ /**
59
+ * Inline edit hook props
60
+ */
61
+ export type UseInlineEditProps<
62
+ TValue extends string | number | Date | boolean | JSON | EditorJSONContent,
63
+ TResult extends string | number | Date | boolean | JSON | EditorJSONContent,
64
+ Required extends boolean = false,
65
+ > = useInlineEditOptions<TResult, Required> & {
66
+ parser: {
67
+ /**
68
+ * Transform the value from the result type to the value type
69
+ */
70
+ decode: (value: TResult) => TValue;
71
+ /**
72
+ * Transform the value from the value type to the result type
73
+ */
74
+ encode: (value: TValue) => TResult;
75
+ };
76
+ };
77
+
58
78
  /**
59
79
  * Use the inline edit hook.
60
80
  */
61
81
  export function useInlineEdit<
62
82
  TValue extends string | number | Date | boolean | JSON | EditorJSONContent,
83
+ TResult extends string | number | Date | boolean | JSON | EditorJSONContent = TValue,
63
84
  Required extends boolean = false,
64
- >(props: useInlineEditOptions<TValue, Required>) {
85
+ >(props: UseInlineEditProps<TValue, TResult, Required>) {
65
86
  /**
66
87
  * The update strategy.
67
88
  */
68
89
  const strategy = props.updateStrategy ?? defaultUpdateStrategy;
69
90
  const delay = strategy.mode === "change" ? (strategy.delay ?? 0) : 0;
91
+ const initialValue = props.parser.decode(props.initialValue as TResult) ?? undefined;
70
92
 
71
93
  /**
72
94
  * The inline edit context.
@@ -76,7 +98,7 @@ export function useInlineEdit<
76
98
  /**
77
99
  * The current value of the inline edit.
78
100
  */
79
- const [value, setValue] = useState<MaybeValue<TValue, Required> | undefined>(props.initialValue);
101
+ const [value, setValue] = useState<MaybeValue<TValue, Required> | undefined>(initialValue);
80
102
 
81
103
  /**
82
104
  * The indicator status.
@@ -101,7 +123,7 @@ export function useInlineEdit<
101
123
  setStatus("success");
102
124
  },
103
125
  onError: (error) => {
104
- setValue(props.initialValue);
126
+ setValue(initialValue);
105
127
  toast.error("Er is iets misgegaan", {
106
128
  description: error instanceof Error ? error.message : undefined,
107
129
  });
@@ -112,7 +134,7 @@ export function useInlineEdit<
112
134
  * Handle instant mutate
113
135
  */
114
136
  const handleMutateInstant = useCallback(
115
- (value: MaybeValue<TValue, Required>) => {
137
+ (input: TValue) => {
116
138
  // Permission guard
117
139
  if (!isAllowed) {
118
140
  toast.error("Je hebt geen toestemming om dit te bewerken");
@@ -120,12 +142,14 @@ export function useInlineEdit<
120
142
  }
121
143
 
122
144
  // If the value is the same as the initial value, do nothing
123
- if (value === props.initialValue) return;
145
+ if (input === initialValue) return;
146
+
147
+ const value = props.parser.encode(input as TValue);
124
148
 
125
149
  // Update the value
126
150
  return mutation.mutate({ id: context.id, value });
127
151
  },
128
- [isAllowed, props.initialValue, mutation, context.id],
152
+ [isAllowed, initialValue, mutation, context.id, props.parser],
129
153
  );
130
154
 
131
155
  /**
@@ -145,14 +169,14 @@ export function useInlineEdit<
145
169
 
146
170
  // If it is required and the value is null or empty, reset to initial value
147
171
  if (props.isRequired && next === null) {
148
- setValue(props.initialValue ?? undefined);
172
+ setValue(initialValue ?? undefined);
149
173
  setStatus("error");
150
174
  toast.error("Dit veld is verplicht");
151
175
  return;
152
176
  }
153
177
 
154
178
  // If the strategy is change, update the value after the delay
155
- handleMutateDebounced(next as MaybeValue<TValue, Required>);
179
+ handleMutateDebounced(next as TValue);
156
180
  }
157
181
 
158
182
  /**
@@ -167,14 +191,14 @@ export function useInlineEdit<
167
191
 
168
192
  // If it is required and the value is null or empty, reset to initial value
169
193
  if (props.isRequired && next === null) {
170
- setValue(props.initialValue ?? undefined);
194
+ setValue(initialValue ?? undefined);
171
195
  setStatus("error");
172
196
  toast.error("Dit veld is verplicht");
173
197
  return;
174
198
  }
175
199
 
176
200
  // If the strategy is blur, update the value
177
- handleMutateInstant(next as MaybeValue<TValue, Required>);
201
+ handleMutateInstant(next as TValue);
178
202
  }
179
203
 
180
204
  return { value, setValue, handleChange, handleBlur, status, isAllowed };
@@ -0,0 +1,9 @@
1
+ // export function defaultParser<
2
+ // TValue extends string | number | Date | boolean | JSON | EditorJSONContent,
3
+ // TResult extends string | number | Date | boolean | JSON | EditorJSONContent,
4
+ // >() {
5
+ // return {
6
+ // decode: <>(value: TResult) => value as unknown as TValue,
7
+ // encode: (value: TValue) => value as unknown as TResult,
8
+ // };
9
+ // }
@@ -17,6 +17,7 @@ export type UploadZoneContextValue = {
17
17
  invalidate?: () => Promise<void> | void;
18
18
  cancel?: () => Promise<void> | void;
19
19
  };
20
+ disabled?: boolean;
20
21
  // updateData: (newValue: FileNode[] | ((oldValue: FileNode[]) => FileNode[])) => Promise<void>;
21
22
  // invalidateQuery: () => Promise<void> | void;
22
23
  };
@@ -10,7 +10,7 @@ import type { FileNode, Node, UploadFileSchema } from "../lib/validators";
10
10
  import { UploadZoneContext, type UploadZoneContextValue } from "./upload-zone-context.client";
11
11
 
12
12
  export type UploadZoneProps = ComponentProps<"div"> &
13
- Pick<UploadZoneContextValue, "optimistic" | "uploadClient"> & {
13
+ Pick<UploadZoneContextValue, "optimistic" | "uploadClient" | "disabled"> & {
14
14
  variables: Pick<UploadFileSchema, "namespace" | "parentId" | "mode" | "hidden" | "readonly">;
15
15
  uploadHooks?: UploadHooks;
16
16
 
@@ -25,6 +25,7 @@ export function UploadZone({
25
25
  uploadHooks,
26
26
  onUploadCompleted,
27
27
  onUploadFailed,
28
+ disabled = false,
28
29
  children,
29
30
  className,
30
31
  ...props
@@ -106,7 +107,11 @@ export function UploadZone({
106
107
  [onUpload],
107
108
  );
108
109
 
109
- const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop, noClick: true });
110
+ const { getRootProps, getInputProps, isDragActive } = useDropzone({
111
+ onDrop,
112
+ noClick: true,
113
+ disabled,
114
+ });
110
115
 
111
116
  return (
112
117
  <div {...props} {...getRootProps()} className={cn("relative z-0", className)}>
@@ -123,6 +128,7 @@ export function UploadZone({
123
128
  onUpload,
124
129
  onRemove: deleteMutation.mutateAsync,
125
130
  optimistic,
131
+ disabled,
126
132
  }}
127
133
  >
128
134
  {children}
@@ -1 +0,0 @@
1
- {"version":3,"file":"data-table-menu.client.mjs","names":[],"sources":["../../../../src/modules/commands/menus/data-table-menu.client.tsx"],"sourcesContent":["\"use client\";\n\nimport type { Table } from \"@tanstack/react-table\";\nimport { useRef } from \"react\";\nimport type { TableMeta } from \"@/modules/data-tables/lib/types\";\nimport { RenderCommand } from \"../components/render-command\";\nimport { CommandContextProvider } from \"../hooks/context.client\";\nimport { useBulkCommandMenu } from \"../hooks/use-command-menu.client\";\n\nexport function TableCommandMenu<TData extends { id: string }>({ table }: { table: Table<TData> }) {\n const meta = table.options.meta as TableMeta<TData>;\n\n const hasCommands = useRef(true);\n\n const onSuccess = () => table.resetRowSelection();\n\n const [validCommands, renderCommand] = useBulkCommandMenu({\n data: meta.selectedData ?? [],\n commands: meta.commands ?? [],\n meta: meta as never,\n });\n\n return (\n <div\n data-state={meta.selectedData?.length ? \"open\" : \"closed\"}\n className=\"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\"\n >\n <CommandContextProvider value={{ menu: \"table\", onSuccess }}>\n <div\n className=\"flex gap-2\"\n ref={(ref) => {\n if (ref?.childNodes.length === 0) hasCommands.current = false;\n }}\n >\n {validCommands.map((command) => (\n <RenderCommand key={command.name} command={command} render={renderCommand} />\n ))}\n </div>\n\n {!hasCommands.current && (\n <span className=\"text-sm font-medium\">Geen acties beschikbaar</span>\n )}\n </CommandContextProvider>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;AASA,SAAgB,iBAA+C,EAAE,SAAkC;CACjG,MAAM,OAAO,MAAM,QAAQ;CAE3B,MAAM,cAAc,OAAO,KAAK;CAEhC,MAAM,kBAAkB,MAAM,mBAAmB;CAEjD,MAAM,CAAC,eAAe,iBAAiB,mBAAmB;EACxD,MAAM,KAAK,gBAAgB,EAAE;EAC7B,UAAU,KAAK,YAAY,EAAE;EACvB;EACP,CAAC;AAEF,QACE,oBAAC;EACC,cAAY,KAAK,cAAc,SAAS,SAAS;EACjD,WAAU;YAEV,qBAAC;GAAuB,OAAO;IAAE,MAAM;IAAS;IAAW;cACzD,oBAAC;IACC,WAAU;IACV,MAAM,QAAQ;AACZ,SAAI,KAAK,WAAW,WAAW,EAAG,aAAY,UAAU;;cAGzD,cAAc,KAAK,YAClB,oBAAC;KAA0C;KAAS,QAAQ;OAAxC,QAAQ,KAAiD,CAC7E;KACE,EAEL,CAAC,YAAY,WACZ,oBAAC;IAAK,WAAU;cAAsB;KAA8B;IAE/C;GACrB"}
@@ -1,46 +0,0 @@
1
- "use client";
2
-
3
- import type { Table } from "@tanstack/react-table";
4
- import { useRef } from "react";
5
- import type { TableMeta } from "@/modules/data-tables/lib/types";
6
- import { RenderCommand } from "../components/render-command";
7
- import { CommandContextProvider } from "../hooks/context.client";
8
- import { useBulkCommandMenu } from "../hooks/use-command-menu.client";
9
-
10
- export function TableCommandMenu<TData extends { id: string }>({ table }: { table: Table<TData> }) {
11
- const meta = table.options.meta as TableMeta<TData>;
12
-
13
- const hasCommands = useRef(true);
14
-
15
- const onSuccess = () => table.resetRowSelection();
16
-
17
- const [validCommands, renderCommand] = useBulkCommandMenu({
18
- data: meta.selectedData ?? [],
19
- commands: meta.commands ?? [],
20
- meta: meta as never,
21
- });
22
-
23
- return (
24
- <div
25
- data-state={meta.selectedData?.length ? "open" : "closed"}
26
- className="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"
27
- >
28
- <CommandContextProvider value={{ menu: "table", onSuccess }}>
29
- <div
30
- className="flex gap-2"
31
- ref={(ref) => {
32
- if (ref?.childNodes.length === 0) hasCommands.current = false;
33
- }}
34
- >
35
- {validCommands.map((command) => (
36
- <RenderCommand key={command.name} command={command} render={renderCommand} />
37
- ))}
38
- </div>
39
-
40
- {!hasCommands.current && (
41
- <span className="text-sm font-medium">Geen acties beschikbaar</span>
42
- )}
43
- </CommandContextProvider>
44
- </div>
45
- );
46
- }