@questpie/admin 3.5.1 → 3.5.3

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 (94) hide show
  1. package/dist/client/builder/types/collection-types.d.mts +9 -0
  2. package/dist/client/components/actions/action-dialog.mjs +5 -0
  3. package/dist/client/components/fields/rich-text-editor/bubble-menu.mjs +7 -0
  4. package/dist/client/components/fields/rich-text-editor/extensions.mjs +17 -1
  5. package/dist/client/components/fields/rich-text-editor/index.d.mts +2 -1
  6. package/dist/client/components/fields/rich-text-editor/index.mjs +35 -74
  7. package/dist/client/components/fields/rich-text-editor/slash-commands.mjs +30 -7
  8. package/dist/client/components/fields/rich-text-editor/toolbar.mjs +1 -312
  9. package/dist/client/components/fields/rich-text-editor/types.d.mts +4 -0
  10. package/dist/client/components/fields/rich-text-editor/types.mjs +1 -1
  11. package/dist/client/components/fields/rich-text-editor/utils.mjs +6 -12
  12. package/dist/client/components/filter-builder/filter-builder-sheet.mjs +75 -22
  13. package/dist/client/components/ui/dropdown-menu.mjs +1 -34
  14. package/dist/client/hooks/query-access.d.mts +9 -0
  15. package/dist/client/hooks/query-access.mjs +20 -0
  16. package/dist/client/hooks/typed-hooks.d.mts +4 -2
  17. package/dist/client/hooks/typed-hooks.mjs +30 -29
  18. package/dist/client/hooks/use-reactive-fields.d.mts +1 -0
  19. package/dist/client/hooks/use-reactive-fields.mjs +16 -1
  20. package/dist/client/hooks/use-server-actions.mjs +12 -1
  21. package/dist/client/hooks/use-view-state.mjs +15 -7
  22. package/dist/client/lib/view-filter-utils.mjs +30 -0
  23. package/dist/client/preview/block-scope-context.d.mts +2 -2
  24. package/dist/client/preview/preview-banner.d.mts +2 -2
  25. package/dist/client/preview/preview-field.d.mts +4 -4
  26. package/dist/client/scope/picker.d.mts +2 -2
  27. package/dist/client/scope/provider.d.mts +2 -2
  28. package/dist/client/styles/base.css +69 -77
  29. package/dist/client/utils/build-field-definitions-from-schema.mjs +1 -0
  30. package/dist/client/views/collection/auto-form-fields.mjs +3 -2
  31. package/dist/client/views/collection/cells/primitive-cells.mjs +9 -6
  32. package/dist/client/views/collection/columns/build-columns.mjs +3 -1
  33. package/dist/client/views/collection/field-renderer.mjs +11 -3
  34. package/dist/client/views/collection/form-view.mjs +207 -202
  35. package/dist/client/views/collection/list-view.mjs +581 -183
  36. package/dist/client/views/collection/outline.mjs +44 -19
  37. package/dist/client/views/collection/quick-filter-bar.mjs +45 -0
  38. package/dist/client/views/collection/table-view.mjs +60 -16
  39. package/dist/client/views/globals/global-form-view.mjs +12 -9
  40. package/dist/client/views/layout/admin-layout.mjs +1 -1
  41. package/dist/client/views/layout/admin-sidebar.mjs +20 -14
  42. package/dist/client/views/layout/admin-theme.mjs +5 -4
  43. package/dist/client.mjs +1 -1
  44. package/dist/components/rich-text/rich-text-renderer.d.mts +5 -5
  45. package/dist/components/rich-text/rich-text-renderer.mjs +5 -2
  46. package/dist/index.mjs +1 -1
  47. package/dist/modules/admin.d.mts +1 -1
  48. package/dist/server/augmentation/actions.d.mts +4 -3
  49. package/dist/server/augmentation/dashboard.d.mts +11 -11
  50. package/dist/server/augmentation/form-layout.d.mts +11 -6
  51. package/dist/server/augmentation/index.d.mts +7 -0
  52. package/dist/server/augmentation/sidebar.d.mts +8 -8
  53. package/dist/server/codegen/admin-client-template.mjs +55 -38
  54. package/dist/server/fields/index.d.mts +1 -1
  55. package/dist/server/fields/rich-text.d.mts +16 -17
  56. package/dist/server/fields/rich-text.mjs +18 -7
  57. package/dist/server/i18n/messages/cs.mjs +2 -0
  58. package/dist/server/i18n/messages/de.mjs +2 -0
  59. package/dist/server/i18n/messages/en.mjs +4 -0
  60. package/dist/server/i18n/messages/es.mjs +2 -0
  61. package/dist/server/i18n/messages/fr.mjs +2 -0
  62. package/dist/server/i18n/messages/pl.mjs +2 -0
  63. package/dist/server/i18n/messages/pt.mjs +2 -0
  64. package/dist/server/i18n/messages/sk.mjs +2 -0
  65. package/dist/server/modules/admin/block/block-builder.d.mts +0 -8
  66. package/dist/server/modules/admin/block/introspection.d.mts +2 -2
  67. package/dist/server/modules/admin/collections/account.d.mts +53 -52
  68. package/dist/server/modules/admin/collections/admin-locks.d.mts +57 -56
  69. package/dist/server/modules/admin/collections/admin-preferences.d.mts +3 -2
  70. package/dist/server/modules/admin/collections/admin-saved-views.d.mts +50 -49
  71. package/dist/server/modules/admin/collections/apikey.d.mts +72 -71
  72. package/dist/server/modules/admin/collections/assets.d.mts +42 -41
  73. package/dist/server/modules/admin/collections/session.d.mts +46 -45
  74. package/dist/server/modules/admin/collections/user.d.mts +67 -66
  75. package/dist/server/modules/admin/collections/verification.d.mts +39 -38
  76. package/dist/server/modules/admin/index.d.mts +3 -3
  77. package/dist/server/modules/admin/routes/admin-config.d.mts +2 -2
  78. package/dist/server/modules/admin/routes/admin-config.mjs +39 -23
  79. package/dist/server/modules/admin/routes/execute-action.d.mts +9 -9
  80. package/dist/server/modules/admin/routes/execute-action.mjs +28 -8
  81. package/dist/server/modules/admin/routes/locales.d.mts +2 -2
  82. package/dist/server/modules/admin/routes/reactive.mjs +2 -2
  83. package/dist/server/modules/admin/routes/route-helpers.d.mts +11 -7
  84. package/dist/server/modules/admin/routes/translations.d.mts +4 -4
  85. package/dist/server/modules/admin/routes/widget-data.mjs +12 -4
  86. package/dist/server/modules/admin-preferences/collections/saved-views.d.mts +27 -27
  87. package/dist/server/modules/audit/.generated/module.d.mts +6 -6
  88. package/dist/server/modules/audit/collections/audit-log.d.mts +40 -39
  89. package/dist/server/plugin.mjs +3 -3
  90. package/dist/server.d.mts +1 -1
  91. package/dist/shared/types/index.d.mts +1 -0
  92. package/dist/shared/types/saved-views.types.d.mts +14 -7
  93. package/dist/shared.d.mts +3 -2
  94. package/package.json +4 -3
@@ -17,7 +17,9 @@ import { DateTimeInput } from "../../components/primitives/date-input.mjs";
17
17
  import { getDefaultFormActions } from "../../builder/types/action-registry.mjs";
18
18
  import { ConfirmationDialog } from "../../components/actions/confirmation-dialog.mjs";
19
19
  import { ActionButton } from "../../components/actions/action-button.mjs";
20
+ import { adminCollectionKey } from "../../hooks/query-access.mjs";
20
21
  import { useCollectionFields } from "../../hooks/use-collection-fields.mjs";
22
+ import { ReactiveFieldStatesProvider, useReactiveFields } from "../../hooks/use-reactive-fields.mjs";
21
23
  import { AutoFormFields } from "./auto-form-fields.mjs";
22
24
  import { ActionDialog } from "../../components/actions/action-dialog.mjs";
23
25
  import { EmptyState } from "../../components/ui/empty-state.mjs";
@@ -29,7 +31,6 @@ import { usePreferServerValidation } from "../../hooks/use-server-validation.mjs
29
31
  import { useSidebarSearchParam } from "../../hooks/use-sidebar-search-param.mjs";
30
32
  import { useCollectionCreate, useCollectionDelete, useCollectionItem, useCollectionRestore, useCollectionRevertVersion, useCollectionUpdate, useCollectionVersions } from "../../hooks/use-collection.mjs";
31
33
  import { getLockUser, useLock } from "../../hooks/use-locks.mjs";
32
- import { useReactiveFields } from "../../hooks/use-reactive-fields.mjs";
33
34
  import { useServerActions } from "../../hooks/use-server-actions.mjs";
34
35
  import { useTransitionStage } from "../../hooks/use-transition-stage.mjs";
35
36
  import { applyPatchBatchImmutable, cloneSnapshot } from "../../preview/patch.mjs";
@@ -136,22 +137,25 @@ function normalizeInlineEditValue(message) {
136
137
  * Component that manages reactive field states.
137
138
  * Must be rendered inside FormProvider to access form context.
138
139
  */
139
- function ReactiveFieldsManager({ collection, mode = "collection", reactiveConfigs, enabled }) {
140
- useReactiveFields({
140
+ function ReactiveFieldsManager({ collection, mode = "collection", reactiveConfigs, enabled, children }) {
141
+ const { fieldStates } = useReactiveFields({
141
142
  collection,
142
143
  mode,
143
144
  reactiveConfigs,
144
145
  enabled: enabled && Object.keys(reactiveConfigs).length > 0,
145
146
  debounce: 300
146
147
  });
147
- return null;
148
+ return /* @__PURE__ */ jsx(ReactiveFieldStatesProvider, {
149
+ fieldStates,
150
+ children
151
+ });
148
152
  }
149
153
  const FormFieldsContent = React.memo(function FormFieldsContent$1({ collection, config, registry, allCollectionsConfig, resolvedFields, schema }) {
150
154
  return /* @__PURE__ */ jsx(RenderProfiler, {
151
155
  id: `form.fields.${collection}`,
152
156
  minDurationMs: 10,
153
157
  children: /* @__PURE__ */ jsx(AutoFormFields, {
154
- collection,
158
+ collection: adminCollectionKey(collection),
155
159
  config,
156
160
  registry,
157
161
  allCollectionsConfig,
@@ -394,6 +398,7 @@ function FormView({ collection, id, config, viewConfig, navigate, basePath = "/a
394
398
  const { t } = useTranslation();
395
399
  const resolveText = useResolveText();
396
400
  const isEditMode = !!id;
401
+ const collectionKey = adminCollectionKey(collection);
397
402
  const { fields: resolvedFields, schema, isLoading: isFieldsLoading } = useCollectionFields(collection, { fallbackFields: config?.fields });
398
403
  const { data: adminConfig } = useAdminConfig();
399
404
  const resolvedFormConfig = React.useMemo(() => viewConfig ?? (config?.form)?.["~config"] ?? config?.form ?? schema?.admin?.form, [
@@ -442,7 +447,7 @@ function FormView({ collection, id, config, viewConfig, navigate, basePath = "/a
442
447
  fields: resolvedFields,
443
448
  schema
444
449
  }), [resolvedFields, schema]);
445
- const { data: item, isLoading, error: itemError } = useCollectionItem(collection, id ?? "", hasManyToManyRelations(withRelations) ? {
450
+ const { data: item, isLoading, error: itemError } = useCollectionItem(collectionKey, id ?? "", hasManyToManyRelations(withRelations) ? {
446
451
  with: withRelations,
447
452
  localeFallback: false
448
453
  } : { localeFallback: false }, { enabled: isEditMode });
@@ -462,13 +467,13 @@ function FormView({ collection, id, config, viewConfig, navigate, basePath = "/a
462
467
  }
463
468
  return result;
464
469
  }, [item, withRelations]);
465
- const createMutation = useCollectionCreate(collection);
466
- const updateMutation = useCollectionUpdate(collection);
467
- const deleteMutation = useCollectionDelete(collection);
468
- const restoreMutation = useCollectionRestore(collection);
469
- const revertVersionMutation = useCollectionRevertVersion(collection);
470
+ const createMutation = useCollectionCreate(collectionKey);
471
+ const updateMutation = useCollectionUpdate(collectionKey);
472
+ const deleteMutation = useCollectionDelete(collectionKey);
473
+ const restoreMutation = useCollectionRestore(collectionKey);
474
+ const revertVersionMutation = useCollectionRevertVersion(collectionKey);
470
475
  const [pendingRevertVersion, setPendingRevertVersion] = React.useState(null);
471
- const { data: versionsData, isLoading: versionsLoading } = useCollectionVersions(collection, id ?? "", { limit: 50 }, { enabled: isEditMode && !!id && isHistoryOpen && !!schema?.options?.versioning });
476
+ const { data: versionsData, isLoading: versionsLoading } = useCollectionVersions(collectionKey, id ?? "", { limit: 50 }, { enabled: isEditMode && !!id && isHistoryOpen && !!schema?.options?.versioning });
472
477
  const workflowConfig = schema?.options?.workflow;
473
478
  const workflowEnabled = !!workflowConfig?.enabled;
474
479
  /**
@@ -476,7 +481,7 @@ function FormView({ collection, id, config, viewConfig, navigate, basePath = "/a
476
481
  * `versionStage`. Runs whenever workflow is enabled and we have an item id.
477
482
  * The full 50-version query is still lazy-loaded behind the History sidebar.
478
483
  */
479
- const { data: latestVersionData } = useCollectionVersions(collection, id ?? "", { limit: 1 }, { enabled: workflowEnabled && isEditMode && !!id });
484
+ const { data: latestVersionData } = useCollectionVersions(collectionKey, id ?? "", { limit: 1 }, { enabled: workflowEnabled && isEditMode && !!id });
480
485
  const currentStage = latestVersionData?.[0]?.versionStage ?? workflowConfig?.initialStage ?? null;
481
486
  const currentStageConfig = React.useMemo(() => workflowConfig?.stages?.find((s) => s.name === currentStage) ?? null, [workflowConfig?.stages, currentStage]);
482
487
  const currentStageLabel = currentStageConfig?.label ?? currentStage ?? "";
@@ -1238,196 +1243,196 @@ function FormView({ collection, id, config, viewConfig, navigate, basePath = "/a
1238
1243
  /* @__PURE__ */ jsx(ReactiveFieldsManager, {
1239
1244
  collection,
1240
1245
  reactiveConfigs,
1241
- enabled: !isBlocked && !isMutationPending
1242
- }),
1243
- /* @__PURE__ */ jsx(RenderProfiler, {
1244
- id: `form.shell.${collection}`,
1245
- minDurationMs: 12,
1246
- children: /* @__PURE__ */ jsxs("form", {
1247
- ref: formElementRef,
1248
- onSubmit: (e) => {
1249
- e.stopPropagation();
1250
- if (isBlocked) {
1251
- e.preventDefault();
1252
- toast.error(t("lock.cannotSave"));
1253
- return;
1254
- }
1255
- form.handleSubmit(onSubmit, (errors) => {
1256
- console.warn("[FormView] Validation errors:", errors);
1257
- toast.error(t("toast.validationFailed"), { description: t("toast.validationDescription") });
1258
- })(e);
1259
- },
1260
- className: "qa-form-view__form space-y-4",
1261
- children: [
1262
- /* @__PURE__ */ jsx(AdminViewHeader, {
1263
- className: "qa-form-view__header",
1264
- title,
1265
- titleAccessory: /* @__PURE__ */ jsxs(Fragment, { children: [
1266
- localeOptions.length > 0 && /* @__PURE__ */ jsx(LocaleSwitcher, {
1267
- locales: localeOptions,
1268
- value: contentLocale,
1269
- onChange: setContentLocale
1270
- }),
1271
- /* @__PURE__ */ jsx(AutosaveIndicator, {
1272
- control: form.control,
1273
- enabled: autoSaveConfig.enabled,
1274
- indicator: autoSaveConfig.indicator,
1275
- isEditMode,
1276
- isSaving,
1277
- lastSaved,
1278
- formatTimeAgo,
1279
- t
1280
- }),
1281
- workflowEnabled && currentStage && /* @__PURE__ */ jsxs(Badge, {
1282
- variant: "outline",
1283
- className: "gap-1.5",
1284
- children: [/* @__PURE__ */ jsx(Icon, {
1285
- icon: "ph:git-branch",
1286
- className: "size-3"
1287
- }), currentStageLabel]
1288
- })
1289
- ] }),
1290
- meta: showMeta && item ? /* @__PURE__ */ jsxs(Fragment, { children: [
1291
- /* @__PURE__ */ jsxs("span", {
1292
- className: "opacity-60",
1293
- children: [t("form.id"), ":"]
1294
- }),
1295
- /* @__PURE__ */ jsx("button", {
1296
- type: "button",
1297
- className: "hover:text-foreground cursor-pointer transition-colors",
1298
- onClick: () => {
1299
- navigator.clipboard.writeText(String(item.id)).then(() => toast.success(t("toast.idCopied")), () => toast.error(t("toast.copyFailed")));
1300
- },
1301
- title: t("common.copy"),
1302
- children: item.id
1303
- }),
1304
- item.createdAt && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
1305
- className: "opacity-40",
1306
- children: "·"
1307
- }), /* @__PURE__ */ jsxs("span", { children: [/* @__PURE__ */ jsxs("span", {
1308
- className: "opacity-60",
1309
- children: [t("form.created"), " "]
1310
- }), formatDate(item.createdAt)] })] }),
1311
- item.updatedAt && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
1312
- className: "opacity-40",
1313
- children: "·"
1314
- }), /* @__PURE__ */ jsxs("span", { children: [/* @__PURE__ */ jsxs("span", {
1315
- className: "opacity-60",
1316
- children: [t("form.updated"), " "]
1317
- }), formatDate(item.updatedAt)] })] })
1318
- ] }) : void 0,
1319
- actions: /* @__PURE__ */ jsxs(Fragment, { children: [
1320
- headerActions,
1321
- canUseLivePreview && /* @__PURE__ */ jsxs(Button, {
1322
- type: "button",
1323
- variant: "outline",
1324
- size: "icon-sm",
1325
- onClick: () => setIsLivePreviewOpen(true),
1326
- title: t("preview.livePreview"),
1327
- children: [/* @__PURE__ */ jsx(Icon, {
1328
- icon: "ph:eye",
1329
- className: "size-4"
1330
- }), /* @__PURE__ */ jsx("span", {
1331
- className: "sr-only",
1332
- children: t("preview.livePreview")
1333
- })]
1334
- }),
1335
- isEditMode && id && schema?.options?.versioning && /* @__PURE__ */ jsxs(Button, {
1336
- type: "button",
1337
- variant: "outline",
1338
- size: "icon-sm",
1339
- onClick: () => setIsHistoryOpen(true),
1340
- title: t("history.title"),
1341
- children: [/* @__PURE__ */ jsx(Icon, {
1342
- icon: "ph:clock-counter-clockwise",
1343
- className: "size-4"
1344
- }), /* @__PURE__ */ jsx("span", {
1345
- className: "sr-only",
1346
- children: t("history.title")
1347
- })]
1348
- }),
1349
- workflowEnabled && isEditMode && id && allowedTransitions.length > 0 && /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsxs(DropdownMenuTrigger, {
1350
- render: workflowTransitionTriggerRender,
1351
- children: [/* @__PURE__ */ jsx(Icon, {
1352
- icon: "ph:arrows-left-right",
1353
- className: "size-4"
1354
- }), t("workflow.transition")]
1355
- }), /* @__PURE__ */ jsx(DropdownMenuContent, {
1356
- align: "end",
1357
- children: allowedTransitions.map((stage) => /* @__PURE__ */ jsxs(DropdownMenuItem, {
1358
- onClick: () => setTransitionTarget({
1359
- name: stage.name,
1360
- label: stage.label
1361
- }),
1246
+ enabled: !isBlocked && !isMutationPending,
1247
+ children: /* @__PURE__ */ jsx(RenderProfiler, {
1248
+ id: `form.shell.${collection}`,
1249
+ minDurationMs: 12,
1250
+ children: /* @__PURE__ */ jsxs("form", {
1251
+ ref: formElementRef,
1252
+ onSubmit: (e) => {
1253
+ e.stopPropagation();
1254
+ if (isBlocked) {
1255
+ e.preventDefault();
1256
+ toast.error(t("lock.cannotSave"));
1257
+ return;
1258
+ }
1259
+ form.handleSubmit(onSubmit, (errors) => {
1260
+ console.warn("[FormView] Validation errors:", errors);
1261
+ toast.error(t("toast.validationFailed"), { description: t("toast.validationDescription") });
1262
+ })(e);
1263
+ },
1264
+ className: "qa-form-view__form space-y-4",
1265
+ children: [
1266
+ /* @__PURE__ */ jsx(AdminViewHeader, {
1267
+ className: "qa-form-view__header",
1268
+ title,
1269
+ titleAccessory: /* @__PURE__ */ jsxs(Fragment, { children: [
1270
+ localeOptions.length > 0 && /* @__PURE__ */ jsx(LocaleSwitcher, {
1271
+ locales: localeOptions,
1272
+ value: contentLocale,
1273
+ onChange: setContentLocale
1274
+ }),
1275
+ /* @__PURE__ */ jsx(AutosaveIndicator, {
1276
+ control: form.control,
1277
+ enabled: autoSaveConfig.enabled,
1278
+ indicator: autoSaveConfig.indicator,
1279
+ isEditMode,
1280
+ isSaving,
1281
+ lastSaved,
1282
+ formatTimeAgo,
1283
+ t
1284
+ }),
1285
+ workflowEnabled && currentStage && /* @__PURE__ */ jsxs(Badge, {
1286
+ variant: "outline",
1287
+ className: "gap-1.5",
1362
1288
  children: [/* @__PURE__ */ jsx(Icon, {
1363
- icon: "ph:arrow-right",
1364
- className: "mr-2 size-4"
1365
- }), stage.label || stage.name]
1366
- }, stage.name))
1367
- })] }),
1368
- visiblePrimaryActions.map((action) => /* @__PURE__ */ jsx(ActionButton, {
1369
- action,
1370
- collection,
1371
- helpers: actionHelpers,
1372
- size: "sm",
1373
- onOpenDialog: (a) => setDialogAction(a)
1374
- }, action.id)),
1375
- /* @__PURE__ */ jsx(SaveSubmitButton, {
1376
- control: form.control,
1377
- isMutationPending,
1378
- t
1379
- }),
1380
- visibleSecondaryActions.length > 0 && /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsxs(DropdownMenuTrigger, {
1381
- render: secondaryActionsTriggerRender,
1382
- children: [/* @__PURE__ */ jsx(Icon, {
1383
- icon: "ph:dots-three-vertical",
1384
- className: "size-4"
1385
- }), /* @__PURE__ */ jsx("span", {
1386
- className: "sr-only",
1387
- children: t("common.moreActions")
1388
- })]
1389
- }), /* @__PURE__ */ jsxs(DropdownMenuContent, {
1390
- align: "end",
1391
- children: [
1392
- regularSecondary.map((action) => {
1393
- return /* @__PURE__ */ jsxs(DropdownMenuItem, {
1394
- onClick: () => handleActionClick(action),
1395
- disabled: actionLoading,
1396
- children: [resolveIconElement(action.icon, { className: "mr-2 size-4" }), resolveText(action.label)]
1397
- }, action.id);
1398
- }),
1399
- regularSecondary.length > 0 && destructiveSecondary.length > 0 && /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
1400
- destructiveSecondary.map((action) => {
1401
- return /* @__PURE__ */ jsxs(DropdownMenuItem, {
1402
- variant: "destructive",
1403
- onClick: () => handleActionClick(action),
1404
- disabled: actionLoading,
1405
- children: [resolveIconElement(action.icon, { className: "mr-2 size-4" }), resolveText(action.label)]
1406
- }, action.id);
1407
- })
1408
- ]
1409
- })] })
1410
- ] })
1411
- }),
1412
- item?.deletedAt && /* @__PURE__ */ jsxs("div", {
1413
- className: "qa-form-view__deleted-banner border-destructive/30 bg-destructive/5 text-destructive flex items-center gap-2 border px-4 py-3 text-sm",
1414
- children: [/* @__PURE__ */ jsx(Icon, {
1415
- icon: "ph:trash",
1416
- className: "size-4 shrink-0"
1417
- }), /* @__PURE__ */ jsx("span", { children: t("form.deletedBanner", {
1418
- date: formatDate(item.deletedAt),
1419
- defaultValue: `This record was deleted on ${formatDate(item.deletedAt)}. Use the Restore action to make it active again.`
1420
- }) })]
1421
- }),
1422
- /* @__PURE__ */ jsx(FormFieldsContent, {
1423
- collection,
1424
- config: formConfigBridge,
1425
- registry,
1426
- allCollectionsConfig,
1427
- resolvedFields,
1428
- schema
1429
- })
1430
- ]
1289
+ icon: "ph:git-branch",
1290
+ className: "size-3"
1291
+ }), currentStageLabel]
1292
+ })
1293
+ ] }),
1294
+ meta: showMeta && item ? /* @__PURE__ */ jsxs(Fragment, { children: [
1295
+ /* @__PURE__ */ jsxs("span", {
1296
+ className: "opacity-60",
1297
+ children: [t("form.id"), ":"]
1298
+ }),
1299
+ /* @__PURE__ */ jsx("button", {
1300
+ type: "button",
1301
+ className: "hover:text-foreground cursor-pointer transition-colors",
1302
+ onClick: () => {
1303
+ navigator.clipboard.writeText(String(item.id)).then(() => toast.success(t("toast.idCopied")), () => toast.error(t("toast.copyFailed")));
1304
+ },
1305
+ title: t("common.copy"),
1306
+ children: item.id
1307
+ }),
1308
+ item.createdAt && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
1309
+ className: "opacity-40",
1310
+ children: "·"
1311
+ }), /* @__PURE__ */ jsxs("span", { children: [/* @__PURE__ */ jsxs("span", {
1312
+ className: "opacity-60",
1313
+ children: [t("form.created"), " "]
1314
+ }), formatDate(item.createdAt)] })] }),
1315
+ item.updatedAt && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
1316
+ className: "opacity-40",
1317
+ children: "·"
1318
+ }), /* @__PURE__ */ jsxs("span", { children: [/* @__PURE__ */ jsxs("span", {
1319
+ className: "opacity-60",
1320
+ children: [t("form.updated"), " "]
1321
+ }), formatDate(item.updatedAt)] })] })
1322
+ ] }) : void 0,
1323
+ actions: /* @__PURE__ */ jsxs(Fragment, { children: [
1324
+ headerActions,
1325
+ canUseLivePreview && /* @__PURE__ */ jsxs(Button, {
1326
+ type: "button",
1327
+ variant: "outline",
1328
+ size: "icon-sm",
1329
+ onClick: () => setIsLivePreviewOpen(true),
1330
+ title: t("preview.livePreview"),
1331
+ children: [/* @__PURE__ */ jsx(Icon, {
1332
+ icon: "ph:eye",
1333
+ className: "size-4"
1334
+ }), /* @__PURE__ */ jsx("span", {
1335
+ className: "sr-only",
1336
+ children: t("preview.livePreview")
1337
+ })]
1338
+ }),
1339
+ isEditMode && id && schema?.options?.versioning && /* @__PURE__ */ jsxs(Button, {
1340
+ type: "button",
1341
+ variant: "outline",
1342
+ size: "icon-sm",
1343
+ onClick: () => setIsHistoryOpen(true),
1344
+ title: t("history.title"),
1345
+ children: [/* @__PURE__ */ jsx(Icon, {
1346
+ icon: "ph:clock-counter-clockwise",
1347
+ className: "size-4"
1348
+ }), /* @__PURE__ */ jsx("span", {
1349
+ className: "sr-only",
1350
+ children: t("history.title")
1351
+ })]
1352
+ }),
1353
+ workflowEnabled && isEditMode && id && allowedTransitions.length > 0 && /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsxs(DropdownMenuTrigger, {
1354
+ render: workflowTransitionTriggerRender,
1355
+ children: [/* @__PURE__ */ jsx(Icon, {
1356
+ icon: "ph:arrows-left-right",
1357
+ className: "size-4"
1358
+ }), t("workflow.transition")]
1359
+ }), /* @__PURE__ */ jsx(DropdownMenuContent, {
1360
+ align: "end",
1361
+ children: allowedTransitions.map((stage) => /* @__PURE__ */ jsxs(DropdownMenuItem, {
1362
+ onClick: () => setTransitionTarget({
1363
+ name: stage.name,
1364
+ label: stage.label
1365
+ }),
1366
+ children: [/* @__PURE__ */ jsx(Icon, {
1367
+ icon: "ph:arrow-right",
1368
+ className: "mr-2 size-4"
1369
+ }), stage.label || stage.name]
1370
+ }, stage.name))
1371
+ })] }),
1372
+ visiblePrimaryActions.map((action) => /* @__PURE__ */ jsx(ActionButton, {
1373
+ action,
1374
+ collection,
1375
+ helpers: actionHelpers,
1376
+ size: "sm",
1377
+ onOpenDialog: (a) => setDialogAction(a)
1378
+ }, action.id)),
1379
+ /* @__PURE__ */ jsx(SaveSubmitButton, {
1380
+ control: form.control,
1381
+ isMutationPending,
1382
+ t
1383
+ }),
1384
+ visibleSecondaryActions.length > 0 && /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsxs(DropdownMenuTrigger, {
1385
+ render: secondaryActionsTriggerRender,
1386
+ children: [/* @__PURE__ */ jsx(Icon, {
1387
+ icon: "ph:dots-three-vertical",
1388
+ className: "size-4"
1389
+ }), /* @__PURE__ */ jsx("span", {
1390
+ className: "sr-only",
1391
+ children: t("common.moreActions")
1392
+ })]
1393
+ }), /* @__PURE__ */ jsxs(DropdownMenuContent, {
1394
+ align: "end",
1395
+ children: [
1396
+ regularSecondary.map((action) => {
1397
+ return /* @__PURE__ */ jsxs(DropdownMenuItem, {
1398
+ onClick: () => handleActionClick(action),
1399
+ disabled: actionLoading,
1400
+ children: [resolveIconElement(action.icon, { className: "mr-2 size-4" }), resolveText(action.label)]
1401
+ }, action.id);
1402
+ }),
1403
+ regularSecondary.length > 0 && destructiveSecondary.length > 0 && /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
1404
+ destructiveSecondary.map((action) => {
1405
+ return /* @__PURE__ */ jsxs(DropdownMenuItem, {
1406
+ variant: "destructive",
1407
+ onClick: () => handleActionClick(action),
1408
+ disabled: actionLoading,
1409
+ children: [resolveIconElement(action.icon, { className: "mr-2 size-4" }), resolveText(action.label)]
1410
+ }, action.id);
1411
+ })
1412
+ ]
1413
+ })] })
1414
+ ] })
1415
+ }),
1416
+ item?.deletedAt && /* @__PURE__ */ jsxs("div", {
1417
+ className: "qa-form-view__deleted-banner border-destructive/30 bg-destructive/5 text-destructive flex items-center gap-2 border px-4 py-3 text-sm",
1418
+ children: [/* @__PURE__ */ jsx(Icon, {
1419
+ icon: "ph:trash",
1420
+ className: "size-4 shrink-0"
1421
+ }), /* @__PURE__ */ jsx("span", { children: t("form.deletedBanner", {
1422
+ date: formatDate(item.deletedAt),
1423
+ defaultValue: `This record was deleted on ${formatDate(item.deletedAt)}. Use the Restore action to make it active again.`
1424
+ }) })]
1425
+ }),
1426
+ /* @__PURE__ */ jsx(FormFieldsContent, {
1427
+ collection,
1428
+ config: formConfigBridge,
1429
+ registry,
1430
+ allCollectionsConfig,
1431
+ resolvedFields,
1432
+ schema
1433
+ })
1434
+ ]
1435
+ })
1431
1436
  })
1432
1437
  })
1433
1438
  ]