@questpie/admin 3.2.7 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/README.md +4 -6
  2. package/dist/client/blocks/block-renderer.d.mts +2 -2
  3. package/dist/client/builder/admin-types.d.mts +3 -3
  4. package/dist/client/builder/types/action-types.d.mts +1 -1
  5. package/dist/client/builder/types/collection-types.d.mts +59 -2
  6. package/dist/client/components/blocks/block-editor-provider.mjs +13 -0
  7. package/dist/client/components/fields/array-field.mjs +105 -122
  8. package/dist/client/components/fields/asset-preview-field.mjs +1 -1
  9. package/dist/client/components/fields/blocks-field/blocks-field.mjs +1 -1
  10. package/dist/client/components/fields/boolean-field.mjs +1 -1
  11. package/dist/client/components/fields/date-field.mjs +1 -1
  12. package/dist/client/components/fields/datetime-field.mjs +1 -1
  13. package/dist/client/components/fields/email-field.mjs +1 -1
  14. package/dist/client/components/fields/field-wrapper.mjs +44 -15
  15. package/dist/client/components/fields/number-field.mjs +1 -1
  16. package/dist/client/components/fields/object-array-field.mjs +179 -149
  17. package/dist/client/components/fields/object-field.mjs +96 -87
  18. package/dist/client/components/fields/relation-picker.mjs +1 -1
  19. package/dist/client/components/fields/relation-select.mjs +1 -1
  20. package/dist/client/components/fields/rich-text-editor/index.mjs +1 -1
  21. package/dist/client/components/fields/select-field.mjs +1 -1
  22. package/dist/client/components/fields/text-field.mjs +1 -1
  23. package/dist/client/components/fields/textarea-field.mjs +1 -1
  24. package/dist/client/components/fields/time-field.mjs +1 -1
  25. package/dist/client/components/fields/upload-field.mjs +1 -1
  26. package/dist/client/components/history-sidebar.mjs +10 -4
  27. package/dist/client/components/structured-diff.mjs +367 -0
  28. package/dist/client/components/ui/sidebar.mjs +1 -1
  29. package/dist/client/hooks/use-field-options.mjs +34 -15
  30. package/dist/client/hooks/use-transition-stage.mjs +2 -2
  31. package/dist/client/modules/admin.d.mts +3 -0
  32. package/dist/client/modules/admin.mjs +3 -0
  33. package/dist/client/preview/block-scope-context.d.mts +2 -2
  34. package/dist/client/preview/preview-banner.d.mts +2 -2
  35. package/dist/client/preview/preview-field.d.mts +4 -4
  36. package/dist/client/utils/auto-expand-fields.mjs +1 -1
  37. package/dist/client/views/collection/auto-form-fields.mjs +23 -19
  38. package/dist/client/views/collection/cells/complex-cells.mjs +1 -1
  39. package/dist/client/views/collection/columns/build-columns.mjs +1 -1
  40. package/dist/client/views/collection/columns/column-defaults.mjs +17 -4
  41. package/dist/client/views/collection/field-renderer.mjs +19 -7
  42. package/dist/client/views/collection/form-view.mjs +10 -6
  43. package/dist/client/views/collection/list-view.mjs +830 -0
  44. package/dist/client/views/collection/outline.mjs +363 -0
  45. package/dist/client/views/collection/table-view.mjs +25 -16
  46. package/dist/client/views/globals/global-form-view.mjs +47 -27
  47. package/dist/client/views/layout/admin-layout.d.mts +15 -1
  48. package/dist/client/views/layout/admin-layout.mjs +95 -31
  49. package/dist/client/views/layout/admin-sidebar.mjs +2 -2
  50. package/dist/client.d.mts +6 -6
  51. package/dist/client.mjs +1 -1
  52. package/dist/components/rich-text/rich-text-renderer.d.mts +2 -2
  53. package/dist/factories.d.mts +19 -0
  54. package/dist/factories.mjs +11 -0
  55. package/dist/fields.d.mts +4 -0
  56. package/dist/fields.mjs +5 -0
  57. package/dist/index.d.mts +6 -6
  58. package/dist/index.mjs +1 -1
  59. package/dist/modules/admin.d.mts +10 -0
  60. package/dist/modules/admin.mjs +9 -0
  61. package/dist/modules/audit.d.mts +5 -0
  62. package/dist/modules/audit.mjs +5 -0
  63. package/dist/server/augmentation/form-layout.d.mts +57 -2
  64. package/dist/server/augmentation/index.d.mts +3 -1
  65. package/dist/server/augmentation/shell.d.mts +48 -0
  66. package/dist/server/augmentation.d.mts +2 -1
  67. package/dist/server/codegen/admin-client-template.mjs +11 -4
  68. package/dist/server/fields/blocks.d.mts +9 -2
  69. package/dist/server/fields/blocks.mjs +1 -1
  70. package/dist/server/fields/index.d.mts +2 -2
  71. package/dist/server/fields/index.mjs +2 -2
  72. package/dist/server/fields/rich-text.d.mts +9 -2
  73. package/dist/server/fields/rich-text.mjs +1 -1
  74. package/dist/server/i18n/messages/cs.mjs +8 -0
  75. package/dist/server/i18n/messages/de.mjs +8 -0
  76. package/dist/server/i18n/messages/en.mjs +8 -0
  77. package/dist/server/i18n/messages/es.mjs +8 -0
  78. package/dist/server/i18n/messages/fr.mjs +8 -0
  79. package/dist/server/i18n/messages/pl.mjs +8 -0
  80. package/dist/server/i18n/messages/pt.mjs +8 -0
  81. package/dist/server/i18n/messages/sk.mjs +8 -0
  82. package/dist/server/modules/admin/.generated/module.d.mts +24 -19
  83. package/dist/server/modules/admin/.generated/module.mjs +5 -1
  84. package/dist/server/modules/admin/.generated/registries.d.mts +6 -4
  85. package/dist/server/modules/admin/client/.generated/module.d.mts +70 -70
  86. package/dist/server/modules/admin/client/.generated/module.mjs +3 -1
  87. package/dist/server/modules/admin/client/views/collection-form.d.mts +6 -0
  88. package/dist/server/modules/admin/client/views/collection-table.d.mts +6 -0
  89. package/dist/server/modules/admin/client/views/global-form.d.mts +6 -0
  90. package/dist/server/modules/admin/client/views/list-view.d.mts +6 -0
  91. package/dist/server/modules/admin/client/views/list-view.mjs +10 -0
  92. package/dist/server/modules/admin/collections/account.d.mts +50 -50
  93. package/dist/server/modules/admin/collections/admin-locks.d.mts +54 -54
  94. package/dist/server/modules/admin/collections/admin-preferences.d.mts +39 -39
  95. package/dist/server/modules/admin/collections/admin-saved-views.d.mts +47 -47
  96. package/dist/server/modules/admin/collections/apikey.d.mts +39 -39
  97. package/dist/server/modules/admin/collections/assets.d.mts +39 -39
  98. package/dist/server/modules/admin/collections/session.d.mts +42 -42
  99. package/dist/server/modules/admin/collections/user.d.mts +63 -63
  100. package/dist/server/modules/admin/collections/verification.d.mts +36 -36
  101. package/dist/server/modules/admin/dto/admin-config.dto.mjs +17 -0
  102. package/dist/server/modules/admin/index.d.mts +30 -31
  103. package/dist/server/modules/admin/routes/admin-config.d.mts +2 -17
  104. package/dist/server/modules/admin/routes/admin-config.mjs +21 -5
  105. package/dist/server/modules/admin/routes/execute-action.d.mts +9 -9
  106. package/dist/server/modules/admin/routes/execute-action.mjs +18 -12
  107. package/dist/server/modules/admin/routes/i18n-helpers.d.mts +4 -0
  108. package/dist/server/modules/admin/routes/locales.d.mts +2 -2
  109. package/dist/server/modules/admin/routes/preview.d.mts +24 -19
  110. package/dist/server/modules/admin/routes/preview.mjs +83 -62
  111. package/dist/server/modules/admin/routes/reactive.d.mts +9 -9
  112. package/dist/server/modules/admin/routes/route-helpers.mjs +36 -1
  113. package/dist/server/modules/admin/routes/setup.d.mts +7 -14
  114. package/dist/server/modules/admin/routes/setup.mjs +16 -3
  115. package/dist/server/modules/admin/routes/translations.d.mts +4 -4
  116. package/dist/server/modules/admin/routes/widget-data.d.mts +5 -5
  117. package/dist/server/modules/admin/views/list-view.d.mts +8 -0
  118. package/dist/server/modules/admin/views/list-view.mjs +7 -0
  119. package/dist/server/modules/admin-preferences/collections/saved-views.d.mts +41 -41
  120. package/dist/server/modules/audit/.generated/module.d.mts +6 -6
  121. package/dist/server/modules/audit/collections/audit-log.d.mts +87 -80
  122. package/dist/server/modules/audit/collections/audit-log.mjs +7 -2
  123. package/dist/server/modules/audit/config/localize-title.mjs +67 -0
  124. package/dist/server/modules/audit/index.d.mts +3 -2
  125. package/dist/server/modules/audit/jobs/audit-cleanup.d.mts +2 -2
  126. package/dist/server/modules/audit/log-audit-entry.d.mts +85 -0
  127. package/dist/server/modules/audit/log-audit-entry.mjs +125 -0
  128. package/dist/server/plugin.d.mts +1 -1
  129. package/dist/server/plugin.mjs +31 -31
  130. package/dist/server.d.mts +6 -4
  131. package/dist/server.mjs +9 -8
  132. package/dist/shared/preview-utils.d.mts +4 -4
  133. package/dist/shared/preview-utils.mjs +5 -7
  134. package/package.json +13 -3
  135. package/dist/client/hooks/use-audit-history.mjs +0 -38
@@ -385,20 +385,21 @@ function extractFieldNamesFromFieldItems(fieldItems) {
385
385
  * Supports recursive tabs/sections nesting and auto-generates
386
386
  * field list when no form config is defined.
387
387
  */
388
- function AutoFormFields({ app: _cms, collection, mode = "collection", config, registry, fieldResolver, fieldPrefix, allCollectionsConfig }) {
388
+ function AutoFormFields({ app: _cms, collection, mode = "collection", config, registry, fieldResolver, fieldPrefix, allCollectionsConfig, resolvedFields: providedFields, schema: providedSchema }) {
389
389
  const isActionForm = collection === "__action__";
390
+ const shouldFetchSchema = !providedFields || !providedSchema;
390
391
  const collectionResult = useCollectionFields(mode === "collection" ? collection : "", {
391
392
  fallbackFields: mode === "collection" ? config?.fields : void 0,
392
- schemaQueryOptions: { enabled: mode === "collection" && !isActionForm }
393
+ schemaQueryOptions: { enabled: mode === "collection" && !isActionForm && shouldFetchSchema }
393
394
  });
394
- const globalResult = useGlobalFields(mode === "global" ? collection : "", { schemaQueryOptions: { enabled: mode === "global" } });
395
+ const globalResult = useGlobalFields(mode === "global" ? collection : "", { schemaQueryOptions: { enabled: mode === "global" && shouldFetchSchema } });
395
396
  const { data: collectionMeta } = useCollectionMeta(collection, { enabled: mode === "collection" && !isActionForm });
396
397
  const { data: globalMeta } = useGlobalMeta(collection, { enabled: mode === "global" });
397
398
  const resolvedFields = mode === "global" ? {
398
- ...globalResult.fields,
399
+ ...providedFields ?? globalResult.fields,
399
400
  ...config?.fields
400
- } : collectionResult.fields;
401
- const schema = mode === "global" ? globalResult.schema : collectionResult.schema;
401
+ } : providedFields ?? collectionResult.fields;
402
+ const schema = providedSchema ?? (mode === "global" ? globalResult.schema : collectionResult.schema);
402
403
  const entityMeta = mode === "global" ? globalMeta : collectionMeta;
403
404
  const form = useFormContext();
404
405
  const resolveText = useResolveText();
@@ -476,20 +477,23 @@ function AutoFormFields({ app: _cms, collection, mode = "collection", config, re
476
477
  className: "qa-form-fields__main min-w-0 flex-1",
477
478
  children: mainContent
478
479
  }), /* @__PURE__ */ jsx("aside", {
479
- className: cn("qa-form-fields__sidebar", "w-full @max-2xl:pb-2 @2xl:max-w-[18rem] @2xl:pl-1"),
480
+ className: cn("qa-form-fields__sidebar", "w-full @max-2xl:pb-2 @2xl:sticky @2xl:top-4 @2xl:h-[calc(100svh-7rem)] @2xl:min-h-0 @2xl:max-w-[18rem] @2xl:shrink-0 @2xl:self-start @2xl:pl-1"),
480
481
  children: /* @__PURE__ */ jsx("div", {
481
- className: "bg-surface-low/45 space-y-4 rounded-md px-3 py-3 @2xl:sticky @2xl:top-4 @2xl:h-auto",
482
- children: /* @__PURE__ */ jsx(SidebarRenderer, {
483
- sidebar: formConfig.sidebar,
484
- fields,
485
- collection,
486
- mode,
487
- registry,
488
- fieldPrefix,
489
- allCollectionsConfig,
490
- entityMeta,
491
- formValues,
492
- resolveText
482
+ className: "bg-surface-low/45 flex min-h-0 flex-col rounded-md @2xl:h-full",
483
+ children: /* @__PURE__ */ jsx("div", {
484
+ className: "scrollbar-thin min-h-0 space-y-4 overflow-y-auto px-3 py-3 @2xl:flex-1",
485
+ children: /* @__PURE__ */ jsx(SidebarRenderer, {
486
+ sidebar: formConfig.sidebar,
487
+ fields,
488
+ collection,
489
+ mode,
490
+ registry,
491
+ fieldPrefix,
492
+ allCollectionsConfig,
493
+ entityMeta,
494
+ formValues,
495
+ resolveText
496
+ })
493
497
  })
494
498
  })
495
499
  })]
@@ -1,7 +1,7 @@
1
1
  import { useResolveText, useTranslation } from "../../../i18n/hooks.mjs";
2
2
  import { cn } from "../../../lib/utils.mjs";
3
- import { Badge } from "../../../components/ui/badge.mjs";
4
3
  import { isBlockContent } from "../../../blocks/types.mjs";
4
+ import { Badge } from "../../../components/ui/badge.mjs";
5
5
  import { Tooltip, TooltipContent, TooltipTrigger } from "../../../components/ui/tooltip.mjs";
6
6
  import { useAdminConfig } from "../../../hooks/use-admin-config.mjs";
7
7
  import { formatFieldLabel, formatPrimitiveValue, getFieldLabel, getItemLabel, summarizeValue } from "./shared/cell-helpers.mjs";
@@ -1,8 +1,8 @@
1
1
  import { useResolveText } from "../../../i18n/hooks.mjs";
2
2
  import { useSafeContentLocales } from "../../../runtime/content-locales-provider.mjs";
3
3
  import { useScopedLocale } from "../../../runtime/locale-scope.mjs";
4
- import { DefaultCell, TextCell } from "../cells/primitive-cells.mjs";
5
4
  import { LocaleSwitcher } from "../../../components/locale-switcher.mjs";
5
+ import { DefaultCell, TextCell } from "../cells/primitive-cells.mjs";
6
6
  import { normalizeColumnConfig } from "../../../builder/types/collection-types.mjs";
7
7
  import { computeDefaultColumns, formatHeader } from "./column-defaults.mjs";
8
8
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -12,6 +12,18 @@ const SYSTEM_FIELDS = new Set([
12
12
  "createdBy",
13
13
  "updatedBy"
14
14
  ]);
15
+ const DEFAULT_CONTENT_COLUMN_LIMIT = 4;
16
+ const HEAVY_DEFAULT_FIELD_TYPES = new Set([
17
+ "relation",
18
+ "reverseRelation",
19
+ "upload",
20
+ "uploadMany",
21
+ "blocks",
22
+ "json",
23
+ "object",
24
+ "array",
25
+ "richText"
26
+ ]);
15
27
  /**
16
28
  * Compute sane default visible columns for a collection
17
29
  *
@@ -39,13 +51,14 @@ function computeDefaultColumns(fields, options) {
39
51
  const defaultCols = [titleColumn];
40
52
  if (!fields || Object.keys(fields).length === 0) return defaultCols;
41
53
  const contentFields = [];
42
- const systemFields = [];
43
54
  for (const key of Object.keys(fields)) {
44
55
  if (useTitleField && key === titleFieldName) continue;
45
- if (SYSTEM_FIELDS.has(key)) systemFields.push(key);
46
- else contentFields.push(key);
56
+ if (SYSTEM_FIELDS.has(key)) continue;
57
+ const fieldType = fields[key]?.name ?? "text";
58
+ if (HEAVY_DEFAULT_FIELD_TYPES.has(fieldType)) continue;
59
+ contentFields.push(key);
47
60
  }
48
- defaultCols.push(...contentFields);
61
+ defaultCols.push(...contentFields.slice(0, DEFAULT_CONTENT_COLUMN_LIMIT));
49
62
  if ((options?.meta?.timestamps ?? !!fields.createdAt) && !defaultCols.includes("createdAt")) defaultCols.push("createdAt");
50
63
  return defaultCols;
51
64
  }
@@ -95,6 +95,14 @@ function renderDefinitionComponent({ context, componentProps, blocks }) {
95
95
  });
96
96
  return /* @__PURE__ */ jsx(Component, { ...componentProps });
97
97
  }
98
+ function BlocksDefinitionComponent({ context, componentProps }) {
99
+ const { data: adminConfig } = useAdminConfig();
100
+ return renderDefinitionComponent({
101
+ context,
102
+ componentProps,
103
+ blocks: adminConfig?.blocks
104
+ });
105
+ }
98
106
  /**
99
107
  * Render embedded collection field
100
108
  *
@@ -133,7 +141,6 @@ function FieldRenderer({ fieldName, fieldDef, collection, mode = "collection", r
133
141
  const form = useFormContext();
134
142
  const { locale } = useScopedLocale();
135
143
  const resolveText = useResolveText();
136
- const { data: adminConfig } = useAdminConfig();
137
144
  const fullFieldName = getFullFieldName(fieldName, fieldPrefix);
138
145
  const fieldOptions = React.useMemo(() => getFieldOptions(fieldDef), [fieldDef]);
139
146
  const dynamicDependencyPaths = React.useMemo(() => computeDynamicDependencyPaths({
@@ -222,14 +229,19 @@ function FieldRenderer({ fieldName, fieldDef, collection, mode = "collection", r
222
229
  renderEmbeddedFields
223
230
  });
224
231
  if (!content && componentLoading) content = /* @__PURE__ */ jsx(FieldComponentSkeleton, { type: context.type });
225
- if (!content && resolvedComponent) content = renderDefinitionComponent({
226
- context: {
232
+ if (!content && resolvedComponent) {
233
+ const componentContext = {
227
234
  ...context,
228
235
  component: resolvedComponent
229
- },
230
- componentProps,
231
- blocks: adminConfig?.blocks
232
- });
236
+ };
237
+ content = context.type === "blocks" ? /* @__PURE__ */ jsx(BlocksDefinitionComponent, {
238
+ context: componentContext,
239
+ componentProps
240
+ }) : renderDefinitionComponent({
241
+ context: componentContext,
242
+ componentProps
243
+ });
244
+ }
233
245
  if (!content) content = renderConfigError(`No component registered for field type "${context.type}" (field: "${context.fieldName}").`);
234
246
  if (className) return /* @__PURE__ */ jsx("div", {
235
247
  className,
@@ -4,11 +4,11 @@ import { useSafeContentLocales } from "../../runtime/content-locales-provider.mj
4
4
  import { useScopedLocale } from "../../runtime/locale-scope.mjs";
5
5
  import { resolveIconElement } from "../../components/component-renderer.mjs";
6
6
  import { Button } from "../../components/ui/button.mjs";
7
- import { Badge } from "../../components/ui/badge.mjs";
8
- import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "../../components/ui/dialog.mjs";
9
7
  import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from "../../components/ui/dropdown-menu.mjs";
10
8
  import { LocaleSwitcher } from "../../components/locale-switcher.mjs";
11
9
  import { Label } from "../../components/ui/label.mjs";
10
+ import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "../../components/ui/dialog.mjs";
11
+ import { Badge } from "../../components/ui/badge.mjs";
12
12
  import { RenderProfiler } from "../../lib/render-profiler.mjs";
13
13
  import { scrollFieldIntoView } from "../../contexts/focus-context.mjs";
14
14
  import { Checkbox } from "../../components/ui/checkbox.mjs";
@@ -144,7 +144,7 @@ function ReactiveFieldsManager({ collection, mode = "collection", reactiveConfig
144
144
  });
145
145
  return null;
146
146
  }
147
- const FormFieldsContent = React.memo(function FormFieldsContent$1({ collection, config, registry, allCollectionsConfig }) {
147
+ const FormFieldsContent = React.memo(function FormFieldsContent$1({ collection, config, registry, allCollectionsConfig, resolvedFields, schema }) {
148
148
  return /* @__PURE__ */ jsx(RenderProfiler, {
149
149
  id: `form.fields.${collection}`,
150
150
  minDurationMs: 10,
@@ -152,7 +152,9 @@ const FormFieldsContent = React.memo(function FormFieldsContent$1({ collection,
152
152
  collection,
153
153
  config,
154
154
  registry,
155
- allCollectionsConfig
155
+ allCollectionsConfig,
156
+ resolvedFields,
157
+ schema
156
158
  })
157
159
  });
158
160
  });
@@ -930,7 +932,7 @@ function FormView({ collection, id, config, viewConfig, navigate, basePath = "/a
930
932
  if (handler.body) body = JSON.stringify(handler.body(actionContext));
931
933
  setActionLoading(true);
932
934
  const apiPromise = async () => {
933
- const url = `${storeBasePath}/${collection}/${endpoint}`;
935
+ const url = `${client.getBasePath?.() ?? storeBasePath}/${collection}/${endpoint}`;
934
936
  const response = await fetch(url, {
935
937
  method,
936
938
  headers: { "Content-Type": "application/json" },
@@ -1402,7 +1404,9 @@ function FormView({ collection, id, config, viewConfig, navigate, basePath = "/a
1402
1404
  collection,
1403
1405
  config: formConfigBridge,
1404
1406
  registry,
1405
- allCollectionsConfig
1407
+ allCollectionsConfig,
1408
+ resolvedFields,
1409
+ schema
1406
1410
  })
1407
1411
  ]
1408
1412
  })