@questpie/admin 0.0.1 → 1.0.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 (250) hide show
  1. package/README.md +439 -424
  2. package/dist/auth-layout-M8K8_q5R.mjs +181 -0
  3. package/dist/auth-layout-M8K8_q5R.mjs.map +1 -0
  4. package/dist/bulk-upload-dialog-D7w7W1Hl.mjs +273 -0
  5. package/dist/bulk-upload-dialog-D7w7W1Hl.mjs.map +1 -0
  6. package/dist/{components/ui/card.mjs → card-BKHjBQfw.mjs} +8 -8
  7. package/dist/card-BKHjBQfw.mjs.map +1 -0
  8. package/dist/client/styles/index.css +434 -0
  9. package/dist/client-DbpZKSgH.d.mts +13585 -0
  10. package/dist/client-DbpZKSgH.d.mts.map +1 -0
  11. package/dist/client-njX1rZmi.mjs +22612 -0
  12. package/dist/client-njX1rZmi.mjs.map +1 -0
  13. package/dist/client.d.mts +3 -0
  14. package/dist/client.mjs +13 -0
  15. package/dist/content-locales-provider-BXvuIgfg.mjs +1650 -0
  16. package/dist/content-locales-provider-BXvuIgfg.mjs.map +1 -0
  17. package/dist/dashboard-page-B4PGEdc2.mjs +2500 -0
  18. package/dist/dashboard-page-B4PGEdc2.mjs.map +1 -0
  19. package/dist/dashboard-page-mCY0pgZv.mjs +3 -0
  20. package/dist/dropzone-Do3awXKd.mjs +634 -0
  21. package/dist/dropzone-Do3awXKd.mjs.map +1 -0
  22. package/dist/{views/auth/forgot-password-form.mjs → forgot-password-page-Bcp-An4Y.mjs} +87 -14
  23. package/dist/forgot-password-page-Bcp-An4Y.mjs.map +1 -0
  24. package/dist/forgot-password-page-CEwsdLwn.mjs +3 -0
  25. package/dist/index-B9Xwk4hi.d.mts +2753 -0
  26. package/dist/index-B9Xwk4hi.d.mts.map +1 -0
  27. package/dist/index.d.mts +3 -0
  28. package/dist/index.mjs +13 -0
  29. package/dist/login-page-BUnpCbCa.mjs +3 -0
  30. package/dist/login-page-CP4gA-dl.mjs +298 -0
  31. package/dist/login-page-CP4gA-dl.mjs.map +1 -0
  32. package/dist/preview-utils-BKQ9-TMa.mjs +65 -0
  33. package/dist/preview-utils-BKQ9-TMa.mjs.map +1 -0
  34. package/dist/{views/auth/reset-password-form.mjs → reset-password-page-BqfDmLxA.mjs} +111 -14
  35. package/dist/reset-password-page-BqfDmLxA.mjs.map +1 -0
  36. package/dist/reset-password-page-CufHz3h3.mjs +3 -0
  37. package/dist/runtime-6VZM878K.mjs +69 -0
  38. package/dist/runtime-6VZM878K.mjs.map +1 -0
  39. package/dist/saved-views.types-BMsz5mCy.d.mts +42 -0
  40. package/dist/saved-views.types-BMsz5mCy.d.mts.map +1 -0
  41. package/dist/server.d.mts +250 -0
  42. package/dist/server.d.mts.map +1 -0
  43. package/dist/server.mjs +832 -0
  44. package/dist/server.mjs.map +1 -0
  45. package/dist/setup-page-BNNzt_Z6.mjs +3 -0
  46. package/dist/setup-page-YAP_fzqh.mjs +264 -0
  47. package/dist/setup-page-YAP_fzqh.mjs.map +1 -0
  48. package/dist/shared.d.mts +57 -0
  49. package/dist/shared.d.mts.map +1 -0
  50. package/dist/shared.mjs +3 -0
  51. package/dist/{hooks/use-auth.mjs → use-auth-BoLmWtmU.mjs} +42 -30
  52. package/dist/use-auth-BoLmWtmU.mjs.map +1 -0
  53. package/package.json +48 -198
  54. package/.turbo/turbo-build.log +0 -108
  55. package/CHANGELOG.md +0 -10
  56. package/STATUS.md +0 -917
  57. package/VALIDATION.md +0 -602
  58. package/components.json +0 -24
  59. package/dist/__tests__/setup.mjs +0 -38
  60. package/dist/__tests__/test-utils.mjs +0 -45
  61. package/dist/__tests__/vitest.d.mjs +0 -3
  62. package/dist/components/admin-app.mjs +0 -69
  63. package/dist/components/fields/array-field.mjs +0 -190
  64. package/dist/components/fields/checkbox-field.mjs +0 -34
  65. package/dist/components/fields/custom-field.mjs +0 -32
  66. package/dist/components/fields/date-field.mjs +0 -41
  67. package/dist/components/fields/datetime-field.mjs +0 -42
  68. package/dist/components/fields/email-field.mjs +0 -37
  69. package/dist/components/fields/embedded-collection.mjs +0 -253
  70. package/dist/components/fields/field-types.mjs +0 -1
  71. package/dist/components/fields/field-utils.mjs +0 -10
  72. package/dist/components/fields/field-wrapper.mjs +0 -34
  73. package/dist/components/fields/index.mjs +0 -23
  74. package/dist/components/fields/json-field.mjs +0 -243
  75. package/dist/components/fields/locale-badge.mjs +0 -16
  76. package/dist/components/fields/number-field.mjs +0 -39
  77. package/dist/components/fields/password-field.mjs +0 -37
  78. package/dist/components/fields/relation-field.mjs +0 -104
  79. package/dist/components/fields/relation-picker.mjs +0 -229
  80. package/dist/components/fields/relation-select.mjs +0 -188
  81. package/dist/components/fields/rich-text-editor/index.mjs +0 -897
  82. package/dist/components/fields/select-field.mjs +0 -41
  83. package/dist/components/fields/switch-field.mjs +0 -34
  84. package/dist/components/fields/text-field.mjs +0 -38
  85. package/dist/components/fields/textarea-field.mjs +0 -38
  86. package/dist/components/index.mjs +0 -59
  87. package/dist/components/primitives/checkbox-input.mjs +0 -127
  88. package/dist/components/primitives/date-input.mjs +0 -303
  89. package/dist/components/primitives/index.mjs +0 -12
  90. package/dist/components/primitives/number-input.mjs +0 -104
  91. package/dist/components/primitives/select-input.mjs +0 -177
  92. package/dist/components/primitives/tag-input.mjs +0 -135
  93. package/dist/components/primitives/text-input.mjs +0 -39
  94. package/dist/components/primitives/textarea-input.mjs +0 -37
  95. package/dist/components/primitives/toggle-input.mjs +0 -31
  96. package/dist/components/primitives/types.mjs +0 -12
  97. package/dist/components/ui/accordion.mjs +0 -55
  98. package/dist/components/ui/avatar.mjs +0 -54
  99. package/dist/components/ui/badge.mjs +0 -34
  100. package/dist/components/ui/button.mjs +0 -48
  101. package/dist/components/ui/checkbox.mjs +0 -21
  102. package/dist/components/ui/combobox.mjs +0 -163
  103. package/dist/components/ui/dialog.mjs +0 -95
  104. package/dist/components/ui/dropdown-menu.mjs +0 -138
  105. package/dist/components/ui/field.mjs +0 -113
  106. package/dist/components/ui/input-group.mjs +0 -82
  107. package/dist/components/ui/input.mjs +0 -17
  108. package/dist/components/ui/label.mjs +0 -15
  109. package/dist/components/ui/popover.mjs +0 -56
  110. package/dist/components/ui/scroll-area.mjs +0 -38
  111. package/dist/components/ui/select.mjs +0 -100
  112. package/dist/components/ui/separator.mjs +0 -16
  113. package/dist/components/ui/sheet.mjs +0 -90
  114. package/dist/components/ui/sidebar.mjs +0 -387
  115. package/dist/components/ui/skeleton.mjs +0 -14
  116. package/dist/components/ui/spinner.mjs +0 -16
  117. package/dist/components/ui/switch.mjs +0 -22
  118. package/dist/components/ui/table.mjs +0 -68
  119. package/dist/components/ui/tabs.mjs +0 -48
  120. package/dist/components/ui/textarea.mjs +0 -15
  121. package/dist/components/ui/tooltip.mjs +0 -44
  122. package/dist/config/component-registry.mjs +0 -38
  123. package/dist/config/index.mjs +0 -129
  124. package/dist/hooks/admin-provider.mjs +0 -70
  125. package/dist/hooks/index.mjs +0 -7
  126. package/dist/hooks/store.mjs +0 -178
  127. package/dist/hooks/use-collection-db.mjs +0 -146
  128. package/dist/hooks/use-collection.mjs +0 -112
  129. package/dist/hooks/use-global.mjs +0 -46
  130. package/dist/hooks/use-mobile.mjs +0 -20
  131. package/dist/lib/utils.mjs +0 -10
  132. package/dist/styles/index.css +0 -336
  133. package/dist/styles/index.mjs +0 -1
  134. package/dist/utils/index.mjs +0 -9
  135. package/dist/views/auth/auth-layout.mjs +0 -52
  136. package/dist/views/auth/index.mjs +0 -6
  137. package/dist/views/auth/login-form.mjs +0 -156
  138. package/dist/views/collection/auto-form-fields.mjs +0 -525
  139. package/dist/views/collection/collection-form.mjs +0 -91
  140. package/dist/views/collection/collection-list.mjs +0 -76
  141. package/dist/views/collection/form-field.mjs +0 -42
  142. package/dist/views/collection/index.mjs +0 -6
  143. package/dist/views/common/index.mjs +0 -4
  144. package/dist/views/common/locale-switcher.mjs +0 -39
  145. package/dist/views/common/version-history.mjs +0 -272
  146. package/dist/views/index.mjs +0 -9
  147. package/dist/views/layout/admin-layout.mjs +0 -40
  148. package/dist/views/layout/admin-router.mjs +0 -95
  149. package/dist/views/layout/admin-sidebar.mjs +0 -63
  150. package/dist/views/layout/index.mjs +0 -5
  151. package/src/__tests__/setup.ts +0 -44
  152. package/src/__tests__/test-utils.tsx +0 -49
  153. package/src/__tests__/vitest.d.ts +0 -9
  154. package/src/components/admin-app.tsx +0 -221
  155. package/src/components/fields/array-field.tsx +0 -237
  156. package/src/components/fields/checkbox-field.tsx +0 -47
  157. package/src/components/fields/custom-field.tsx +0 -50
  158. package/src/components/fields/date-field.tsx +0 -65
  159. package/src/components/fields/datetime-field.tsx +0 -67
  160. package/src/components/fields/email-field.tsx +0 -51
  161. package/src/components/fields/embedded-collection.tsx +0 -315
  162. package/src/components/fields/field-types.ts +0 -162
  163. package/src/components/fields/field-utils.ts +0 -6
  164. package/src/components/fields/field-wrapper.tsx +0 -52
  165. package/src/components/fields/index.ts +0 -66
  166. package/src/components/fields/json-field.tsx +0 -440
  167. package/src/components/fields/locale-badge.tsx +0 -15
  168. package/src/components/fields/number-field.tsx +0 -57
  169. package/src/components/fields/password-field.tsx +0 -51
  170. package/src/components/fields/relation-field.tsx +0 -243
  171. package/src/components/fields/relation-picker.tsx +0 -402
  172. package/src/components/fields/relation-select.tsx +0 -327
  173. package/src/components/fields/rich-text-editor/index.tsx +0 -1337
  174. package/src/components/fields/select-field.tsx +0 -61
  175. package/src/components/fields/switch-field.tsx +0 -47
  176. package/src/components/fields/text-field.tsx +0 -55
  177. package/src/components/fields/textarea-field.tsx +0 -55
  178. package/src/components/index.ts +0 -40
  179. package/src/components/primitives/checkbox-input.tsx +0 -193
  180. package/src/components/primitives/date-input.tsx +0 -401
  181. package/src/components/primitives/index.ts +0 -24
  182. package/src/components/primitives/number-input.tsx +0 -132
  183. package/src/components/primitives/select-input.tsx +0 -296
  184. package/src/components/primitives/tag-input.tsx +0 -200
  185. package/src/components/primitives/text-input.tsx +0 -49
  186. package/src/components/primitives/textarea-input.tsx +0 -46
  187. package/src/components/primitives/toggle-input.tsx +0 -36
  188. package/src/components/primitives/types.ts +0 -235
  189. package/src/components/ui/accordion.tsx +0 -72
  190. package/src/components/ui/avatar.tsx +0 -106
  191. package/src/components/ui/badge.tsx +0 -48
  192. package/src/components/ui/button.tsx +0 -53
  193. package/src/components/ui/card.tsx +0 -94
  194. package/src/components/ui/checkbox.tsx +0 -27
  195. package/src/components/ui/combobox.tsx +0 -290
  196. package/src/components/ui/dialog.tsx +0 -151
  197. package/src/components/ui/dropdown-menu.tsx +0 -254
  198. package/src/components/ui/field.tsx +0 -227
  199. package/src/components/ui/input-group.tsx +0 -149
  200. package/src/components/ui/input.tsx +0 -20
  201. package/src/components/ui/label.tsx +0 -18
  202. package/src/components/ui/popover.tsx +0 -88
  203. package/src/components/ui/scroll-area.tsx +0 -53
  204. package/src/components/ui/select.tsx +0 -192
  205. package/src/components/ui/separator.tsx +0 -23
  206. package/src/components/ui/sheet.tsx +0 -127
  207. package/src/components/ui/sidebar.tsx +0 -723
  208. package/src/components/ui/skeleton.tsx +0 -13
  209. package/src/components/ui/spinner.tsx +0 -10
  210. package/src/components/ui/switch.tsx +0 -32
  211. package/src/components/ui/table.tsx +0 -99
  212. package/src/components/ui/tabs.tsx +0 -82
  213. package/src/components/ui/textarea.tsx +0 -18
  214. package/src/components/ui/tooltip.tsx +0 -70
  215. package/src/config/component-registry.ts +0 -190
  216. package/src/config/index.ts +0 -1099
  217. package/src/hooks/README.md +0 -269
  218. package/src/hooks/admin-provider.tsx +0 -110
  219. package/src/hooks/index.ts +0 -41
  220. package/src/hooks/store.ts +0 -248
  221. package/src/hooks/use-auth.ts +0 -168
  222. package/src/hooks/use-collection-db.ts +0 -209
  223. package/src/hooks/use-collection.ts +0 -156
  224. package/src/hooks/use-global.ts +0 -69
  225. package/src/hooks/use-mobile.ts +0 -21
  226. package/src/lib/utils.ts +0 -6
  227. package/src/styles/index.css +0 -340
  228. package/src/utils/index.ts +0 -6
  229. package/src/views/auth/auth-layout.tsx +0 -77
  230. package/src/views/auth/forgot-password-form.tsx +0 -192
  231. package/src/views/auth/index.ts +0 -21
  232. package/src/views/auth/login-form.tsx +0 -229
  233. package/src/views/auth/reset-password-form.tsx +0 -232
  234. package/src/views/collection/auto-form-fields.tsx +0 -982
  235. package/src/views/collection/collection-form.tsx +0 -186
  236. package/src/views/collection/collection-list.tsx +0 -223
  237. package/src/views/collection/form-field.tsx +0 -52
  238. package/src/views/collection/index.ts +0 -15
  239. package/src/views/common/index.ts +0 -8
  240. package/src/views/common/locale-switcher.tsx +0 -45
  241. package/src/views/common/version-history.tsx +0 -406
  242. package/src/views/index.ts +0 -25
  243. package/src/views/layout/admin-layout.tsx +0 -117
  244. package/src/views/layout/admin-router.tsx +0 -206
  245. package/src/views/layout/admin-sidebar.tsx +0 -185
  246. package/src/views/layout/index.ts +0 -12
  247. package/tsconfig.json +0 -13
  248. package/tsconfig.tsbuildinfo +0 -1
  249. package/tsdown.config.ts +0 -13
  250. package/vitest.config.ts +0 -29
@@ -1,104 +0,0 @@
1
- import "react";
2
- import { jsx, jsxs } from "react/jsx-runtime";
3
- import { Controller, useFormContext } from "react-hook-form";
4
- import { RelationSelect } from "./relation-select";
5
- import { RelationPicker } from "./relation-picker";
6
-
7
- //#region src/components/fields/relation-field.tsx
8
- /**
9
- * Unified relation field component that integrates with react-hook-form.
10
- *
11
- * Automatically chooses between RelationSelect (single) and RelationPicker (multiple)
12
- * based on the `type` prop.
13
- *
14
- * @example
15
- * ```tsx
16
- * // Single relation (one-to-one)
17
- * <RelationField
18
- * name="author"
19
- * targetCollection="users"
20
- * type="single"
21
- * label="Author"
22
- * required
23
- * />
24
- *
25
- * // Multiple relations (many-to-many)
26
- * <RelationField
27
- * name="tags"
28
- * targetCollection="tags"
29
- * type="multiple"
30
- * label="Tags"
31
- * maxItems={5}
32
- * orderable
33
- * />
34
- * ```
35
- */
36
- function RelationField({ name, targetCollection, type, label, description, localized, locale, filter, required, disabled, readOnly, placeholder, orderable, maxItems, renderOption, renderValue, renderItem, renderFormFields, control: controlProp }) {
37
- const formContext = useFormContext();
38
- const control = controlProp ?? formContext?.control;
39
- if (!control) {
40
- console.warn("RelationField: No form control found. Make sure to use within FormProvider or pass control prop.");
41
- return null;
42
- }
43
- return /* @__PURE__ */ jsx(Controller, {
44
- name,
45
- control,
46
- rules: { required: required ? `${label || name} is required` : void 0 },
47
- render: ({ field, fieldState }) => {
48
- const error = fieldState.error?.message;
49
- if (type === "single") return /* @__PURE__ */ jsxs("div", {
50
- className: "space-y-1",
51
- children: [/* @__PURE__ */ jsx(RelationSelect, {
52
- name,
53
- value: field.value,
54
- onChange: field.onChange,
55
- targetCollection,
56
- label,
57
- localized,
58
- locale,
59
- filter,
60
- required,
61
- disabled,
62
- readOnly,
63
- placeholder,
64
- error,
65
- renderOption,
66
- renderValue,
67
- renderFormFields
68
- }), description && !error && /* @__PURE__ */ jsx("p", {
69
- className: "text-muted-foreground text-xs",
70
- children: description
71
- })]
72
- });
73
- return /* @__PURE__ */ jsxs("div", {
74
- className: "space-y-1",
75
- children: [/* @__PURE__ */ jsx(RelationPicker, {
76
- name,
77
- value: field.value,
78
- onChange: field.onChange,
79
- targetCollection,
80
- label,
81
- localized,
82
- locale,
83
- filter,
84
- required,
85
- disabled,
86
- readOnly,
87
- placeholder,
88
- error,
89
- orderable,
90
- maxItems,
91
- renderOption,
92
- renderItem,
93
- renderFormFields
94
- }), description && !error && /* @__PURE__ */ jsx("p", {
95
- className: "text-muted-foreground text-xs",
96
- children: description
97
- })]
98
- });
99
- }
100
- });
101
- }
102
-
103
- //#endregion
104
- export { RelationField };
@@ -1,229 +0,0 @@
1
- import * as React$1 from "react";
2
- import { useQuery } from "@tanstack/react-query";
3
- import { jsx, jsxs } from "react/jsx-runtime";
4
- import { useAdminContext } from "../../hooks/admin-provider";
5
- import { Button } from "../ui/button";
6
- import { Combobox, ComboboxContent, ComboboxEmpty, ComboboxInput, ComboboxItem, ComboboxList } from "../ui/combobox";
7
- import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from "../ui/sheet";
8
- import { DotsSixVertical, Pencil, Plus, X } from "@phosphor-icons/react";
9
- import { LocaleBadge } from "./locale-badge";
10
-
11
- //#region src/components/fields/relation-picker.tsx
12
- /**
13
- * RelationPicker Component
14
- *
15
- * Multiple relation field (one-to-many, many-to-many) with:
16
- * - Multi-select picker to choose existing items
17
- * - Plus button to create new related item (opens side sheet)
18
- * - Edit button on each selected item (opens side sheet)
19
- * - Remove button on each selected item
20
- * - Optional drag-and-drop reordering
21
- */
22
- function RelationPicker({ name, value = [], onChange, targetCollection, label, filter, required, disabled, readOnly, placeholder, error, localized, locale: localeProp, orderable = false, maxItems, renderItem, renderOption, renderFormFields }) {
23
- const { client, locale: contextLocale } = useAdminContext();
24
- const locale = localeProp ?? contextLocale;
25
- const localeKey = locale ?? "default";
26
- const [isSheetOpen, setIsSheetOpen] = React$1.useState(false);
27
- const [sheetMode, setSheetMode] = React$1.useState("create");
28
- const [editingItemId, setEditingItemId] = React$1.useState();
29
- const selectedIds = value || [];
30
- const { data: allOptions, isLoading } = useQuery({
31
- queryKey: [
32
- "relation",
33
- targetCollection,
34
- localeKey,
35
- filter
36
- ],
37
- queryFn: async () => {
38
- const api = client.collections?.[targetCollection];
39
- if (!api?.list) return [];
40
- return (await api.list({ ...filter ? filter({}) : {} })).data || [];
41
- }
42
- });
43
- const { data: selectedItems } = useQuery({
44
- queryKey: [
45
- "relation",
46
- targetCollection,
47
- localeKey,
48
- "selected",
49
- selectedIds
50
- ],
51
- queryFn: async () => {
52
- if (!selectedIds.length) return [];
53
- const api = client.collections?.[targetCollection];
54
- if (!api?.get) return [];
55
- return await Promise.all(selectedIds.map((id) => api.get(id)));
56
- },
57
- enabled: selectedIds.length > 0
58
- });
59
- const handleAdd = (itemId) => {
60
- if (selectedIds.includes(itemId)) return;
61
- if (maxItems && selectedIds.length >= maxItems) return;
62
- onChange([...selectedIds, itemId]);
63
- };
64
- const handleRemove = (itemId) => {
65
- onChange(selectedIds.filter((id) => id !== itemId));
66
- };
67
- const handleOpenCreate = () => {
68
- setSheetMode("create");
69
- setEditingItemId(void 0);
70
- setIsSheetOpen(true);
71
- };
72
- const handleOpenEdit = (itemId) => {
73
- setSheetMode("edit");
74
- setEditingItemId(itemId);
75
- setIsSheetOpen(true);
76
- };
77
- const getDisplayValue = (item) => {
78
- return item?._title || item?.id || "";
79
- };
80
- const getOptionDisplay = (item) => {
81
- if (renderOption) return renderOption(item);
82
- return item?._title || item?.id || "";
83
- };
84
- const availableOptions = allOptions?.filter((opt) => !selectedIds.includes(opt.id)) || [];
85
- const canAddMore = !maxItems || selectedIds.length < maxItems;
86
- return /* @__PURE__ */ jsxs("div", {
87
- className: "space-y-2",
88
- children: [
89
- label && /* @__PURE__ */ jsxs("div", {
90
- className: "flex items-center gap-2",
91
- children: [/* @__PURE__ */ jsxs("label", {
92
- htmlFor: name,
93
- className: "text-sm font-medium",
94
- children: [
95
- label,
96
- required && /* @__PURE__ */ jsx("span", {
97
- className: "text-destructive",
98
- children: "*"
99
- }),
100
- maxItems && /* @__PURE__ */ jsxs("span", {
101
- className: "ml-2 text-xs text-muted-foreground",
102
- children: [
103
- "(",
104
- selectedIds.length,
105
- "/",
106
- maxItems,
107
- ")"
108
- ]
109
- })
110
- ]
111
- }), localized && /* @__PURE__ */ jsx(LocaleBadge, { locale: locale || "i18n" })]
112
- }),
113
- selectedItems && selectedItems.length > 0 && /* @__PURE__ */ jsx("div", {
114
- className: "space-y-2 rounded-lg border p-3",
115
- children: selectedItems.map((item, index) => /* @__PURE__ */ jsxs("div", {
116
- className: "flex items-center gap-2 rounded-md border bg-card p-2",
117
- children: [
118
- orderable && !readOnly && /* @__PURE__ */ jsx("button", {
119
- type: "button",
120
- className: "cursor-grab text-muted-foreground hover:text-foreground",
121
- disabled,
122
- children: /* @__PURE__ */ jsx(DotsSixVertical, { className: "h-4 w-4" })
123
- }),
124
- /* @__PURE__ */ jsx("div", {
125
- className: "flex-1",
126
- children: renderItem ? renderItem(item, index) : /* @__PURE__ */ jsx("span", {
127
- className: "text-sm",
128
- children: getDisplayValue(item)
129
- })
130
- }),
131
- !readOnly && /* @__PURE__ */ jsx(Button, {
132
- type: "button",
133
- variant: "ghost",
134
- size: "icon",
135
- className: "h-7 w-7",
136
- onClick: () => handleOpenEdit(item.id),
137
- disabled,
138
- title: "Edit",
139
- children: /* @__PURE__ */ jsx(Pencil, { className: "h-3 w-3" })
140
- }),
141
- !readOnly && (!required || selectedIds.length > 1) && /* @__PURE__ */ jsx(Button, {
142
- type: "button",
143
- variant: "ghost",
144
- size: "icon",
145
- className: "h-7 w-7",
146
- onClick: () => handleRemove(item.id),
147
- disabled,
148
- title: "Remove",
149
- children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" })
150
- })
151
- ]
152
- }, item.id))
153
- }),
154
- !readOnly && canAddMore && /* @__PURE__ */ jsxs("div", {
155
- className: "flex gap-2",
156
- children: [/* @__PURE__ */ jsx("div", {
157
- className: "flex-1",
158
- children: /* @__PURE__ */ jsxs(Combobox, {
159
- value: "",
160
- onValueChange: (value$1) => {
161
- if (value$1) handleAdd(value$1);
162
- },
163
- disabled: disabled || isLoading,
164
- children: [/* @__PURE__ */ jsx(ComboboxInput, {
165
- placeholder: placeholder || `Add ${label || targetCollection}...`,
166
- disabled: disabled || isLoading
167
- }), /* @__PURE__ */ jsxs(ComboboxContent, { children: [/* @__PURE__ */ jsx(ComboboxList, { children: availableOptions.map((opt) => /* @__PURE__ */ jsx(ComboboxItem, {
168
- value: opt.id,
169
- children: getOptionDisplay(opt)
170
- }, opt.id)) }), /* @__PURE__ */ jsx(ComboboxEmpty, { children: isLoading ? "Loading..." : "No more options available" })] })]
171
- })
172
- }), /* @__PURE__ */ jsx(Button, {
173
- type: "button",
174
- variant: "outline",
175
- size: "icon",
176
- onClick: handleOpenCreate,
177
- disabled,
178
- title: `Create new ${label || targetCollection}`,
179
- children: /* @__PURE__ */ jsx(Plus, { className: "h-4 w-4" })
180
- })]
181
- }),
182
- selectedIds.length === 0 && /* @__PURE__ */ jsx("div", {
183
- className: "rounded-lg border border-dashed p-4 text-center",
184
- children: /* @__PURE__ */ jsx("p", {
185
- className: "text-sm text-muted-foreground",
186
- children: placeholder || `No ${label || targetCollection} selected`
187
- })
188
- }),
189
- error && /* @__PURE__ */ jsx("p", {
190
- className: "text-sm text-destructive",
191
- children: error
192
- }),
193
- /* @__PURE__ */ jsx(Sheet, {
194
- open: isSheetOpen,
195
- onOpenChange: setIsSheetOpen,
196
- children: /* @__PURE__ */ jsxs(SheetContent, {
197
- side: "right",
198
- className: "w-full sm:max-w-lg overflow-y-auto",
199
- children: [/* @__PURE__ */ jsxs(SheetHeader, { children: [/* @__PURE__ */ jsxs(SheetTitle, { children: [
200
- sheetMode === "create" ? "Create" : "Edit",
201
- " ",
202
- label || targetCollection
203
- ] }), /* @__PURE__ */ jsx(SheetDescription, { children: sheetMode === "create" ? `Fill in the details to create a new ${label || targetCollection}` : `Update the details of this ${label || targetCollection}` })] }), /* @__PURE__ */ jsx("div", {
204
- className: "mt-6",
205
- children: renderFormFields ? renderFormFields(targetCollection, editingItemId) : /* @__PURE__ */ jsx("div", {
206
- className: "rounded-lg border border-dashed p-8 text-center",
207
- children: /* @__PURE__ */ jsxs("p", {
208
- className: "text-sm text-muted-foreground",
209
- children: [
210
- "Form fields not configured.",
211
- /* @__PURE__ */ jsx("br", {}),
212
- "Pass ",
213
- /* @__PURE__ */ jsx("code", {
214
- className: "text-xs",
215
- children: "renderFormFields"
216
- }),
217
- " prop to enable create/edit."
218
- ]
219
- })
220
- })
221
- })]
222
- })
223
- })
224
- ]
225
- });
226
- }
227
-
228
- //#endregion
229
- export { RelationPicker };
@@ -1,188 +0,0 @@
1
- import * as React$1 from "react";
2
- import { useQuery } from "@tanstack/react-query";
3
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
- import { useAdminContext } from "../../hooks/admin-provider";
5
- import { Button } from "../ui/button";
6
- import { Select, SelectContent, SelectItem, SelectTrigger } from "../ui/select";
7
- import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from "../ui/sheet";
8
- import { Spinner } from "../ui/spinner";
9
- import { Pencil, Plus, X } from "@phosphor-icons/react";
10
- import { LocaleBadge } from "./locale-badge";
11
-
12
- //#region src/components/fields/relation-select.tsx
13
- /**
14
- * RelationSelect Component
15
- *
16
- * Single relation field (one-to-one) with:
17
- * - Select dropdown to choose existing item
18
- * - Plus button to create new related item (opens side sheet)
19
- * - Edit button to modify selected item (opens side sheet)
20
- */
21
- function RelationSelect({ name, value, onChange, targetCollection, label, filter, required, disabled, readOnly, placeholder, error, localized, locale: localeProp, renderOption, renderValue, renderFormFields }) {
22
- const { client, locale: contextLocale } = useAdminContext();
23
- const locale = localeProp ?? contextLocale;
24
- const localeKey = locale ?? "default";
25
- const [isSheetOpen, setIsSheetOpen] = React$1.useState(false);
26
- const [sheetMode, setSheetMode] = React$1.useState("create");
27
- const { data: options, isLoading } = useQuery({
28
- queryKey: [
29
- "relation",
30
- targetCollection,
31
- localeKey,
32
- filter
33
- ],
34
- queryFn: async () => {
35
- const api = client.collections?.[targetCollection];
36
- if (!api?.list) return [];
37
- return (await api.list({ ...filter ? filter({}) : {} })).data || [];
38
- }
39
- });
40
- const { data: selectedItem } = useQuery({
41
- queryKey: [
42
- "relation",
43
- targetCollection,
44
- localeKey,
45
- value
46
- ],
47
- queryFn: async () => {
48
- if (!value) return null;
49
- const api = client.collections?.[targetCollection];
50
- if (!api?.get) return null;
51
- return await api.get(value);
52
- },
53
- enabled: !!value
54
- });
55
- const handleOpenCreate = () => {
56
- setSheetMode("create");
57
- setIsSheetOpen(true);
58
- };
59
- const handleOpenEdit = () => {
60
- if (!value) return;
61
- setSheetMode("edit");
62
- setIsSheetOpen(true);
63
- };
64
- const handleClear = () => {
65
- onChange(null);
66
- };
67
- const handleValueChange = (newValue) => {
68
- if (newValue) onChange(newValue);
69
- };
70
- const getDisplayValue = (item) => {
71
- if (renderValue) return renderValue(item);
72
- return item?._title || item?.id || "";
73
- };
74
- const getOptionDisplay = (item) => {
75
- if (renderOption) return renderOption(item);
76
- return item?._title || item?.id || "";
77
- };
78
- return /* @__PURE__ */ jsxs("div", {
79
- className: "space-y-2",
80
- children: [
81
- label && /* @__PURE__ */ jsxs("div", {
82
- className: "flex items-center gap-2",
83
- children: [/* @__PURE__ */ jsxs("label", {
84
- htmlFor: name,
85
- className: "text-sm font-medium",
86
- children: [label, required && /* @__PURE__ */ jsx("span", {
87
- className: "text-destructive",
88
- children: "*"
89
- })]
90
- }), localized && /* @__PURE__ */ jsx(LocaleBadge, { locale: locale || "i18n" })]
91
- }),
92
- /* @__PURE__ */ jsxs("div", {
93
- className: "flex gap-2",
94
- children: [/* @__PURE__ */ jsx("div", {
95
- className: "flex-1",
96
- children: /* @__PURE__ */ jsxs(Select, {
97
- value: value || void 0,
98
- onValueChange: handleValueChange,
99
- disabled: disabled || readOnly || isLoading,
100
- children: [/* @__PURE__ */ jsx(SelectTrigger, {
101
- id: name,
102
- className: error ? "border-destructive" : "",
103
- children: /* @__PURE__ */ jsx("span", {
104
- className: "truncate",
105
- children: selectedItem ? getDisplayValue(selectedItem) : placeholder || `Select ${label || targetCollection}...`
106
- })
107
- }), /* @__PURE__ */ jsx(SelectContent, { children: isLoading ? /* @__PURE__ */ jsx("div", {
108
- className: "flex items-center justify-center p-4",
109
- children: /* @__PURE__ */ jsx(Spinner, { className: "h-4 w-4" })
110
- }) : options && options.length > 0 ? options.map((option) => /* @__PURE__ */ jsx(SelectItem, {
111
- value: option.id,
112
- children: getOptionDisplay(option)
113
- }, option.id)) : /* @__PURE__ */ jsx("div", {
114
- className: "p-4 text-center text-sm text-muted-foreground",
115
- children: "No options available"
116
- }) })]
117
- })
118
- }), !readOnly && /* @__PURE__ */ jsxs(Fragment, { children: [
119
- value && !required && /* @__PURE__ */ jsx(Button, {
120
- type: "button",
121
- variant: "outline",
122
- size: "icon",
123
- onClick: handleClear,
124
- disabled,
125
- title: "Clear selection",
126
- children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
127
- }),
128
- value && /* @__PURE__ */ jsx(Button, {
129
- type: "button",
130
- variant: "outline",
131
- size: "icon",
132
- onClick: handleOpenEdit,
133
- disabled,
134
- title: `Edit ${label || targetCollection}`,
135
- children: /* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4" })
136
- }),
137
- /* @__PURE__ */ jsx(Button, {
138
- type: "button",
139
- variant: "outline",
140
- size: "icon",
141
- onClick: handleOpenCreate,
142
- disabled,
143
- title: `Create new ${label || targetCollection}`,
144
- children: /* @__PURE__ */ jsx(Plus, { className: "h-4 w-4" })
145
- })
146
- ] })]
147
- }),
148
- error && /* @__PURE__ */ jsx("p", {
149
- className: "text-sm text-destructive",
150
- children: error
151
- }),
152
- /* @__PURE__ */ jsx(Sheet, {
153
- open: isSheetOpen,
154
- onOpenChange: setIsSheetOpen,
155
- children: /* @__PURE__ */ jsxs(SheetContent, {
156
- side: "right",
157
- className: "w-full sm:max-w-lg overflow-y-auto",
158
- children: [/* @__PURE__ */ jsxs(SheetHeader, { children: [/* @__PURE__ */ jsxs(SheetTitle, { children: [
159
- sheetMode === "create" ? "Create" : "Edit",
160
- " ",
161
- label || targetCollection
162
- ] }), /* @__PURE__ */ jsx(SheetDescription, { children: sheetMode === "create" ? `Fill in the details to create a new ${label || targetCollection}` : `Update the details of this ${label || targetCollection}` })] }), /* @__PURE__ */ jsx("div", {
163
- className: "mt-6",
164
- children: renderFormFields ? renderFormFields(targetCollection, sheetMode === "edit" ? value || void 0 : void 0) : /* @__PURE__ */ jsx("div", {
165
- className: "rounded-lg border border-dashed p-8 text-center",
166
- children: /* @__PURE__ */ jsxs("p", {
167
- className: "text-sm text-muted-foreground",
168
- children: [
169
- "Form fields not configured.",
170
- /* @__PURE__ */ jsx("br", {}),
171
- "Pass ",
172
- /* @__PURE__ */ jsx("code", {
173
- className: "text-xs",
174
- children: "renderFormFields"
175
- }),
176
- " prop to enable create/edit."
177
- ]
178
- })
179
- })
180
- })]
181
- })
182
- })
183
- ]
184
- });
185
- }
186
-
187
- //#endregion
188
- export { RelationSelect };