@questpie/admin 3.5.2 → 3.5.4

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 (195) hide show
  1. package/README.md +8 -0
  2. package/dist/client/blocks/block-renderer.d.mts +2 -2
  3. package/dist/client/builder/index.d.mts +1 -1
  4. package/dist/client/builder/types/collection-types.d.mts +89 -5
  5. package/dist/client/builder/types/common.d.mts +5 -0
  6. package/dist/client/builder/types/field-types.d.mts +41 -1
  7. package/dist/client/builder/view/view.d.mts +3 -2
  8. package/dist/client/components/actions/action-dialog.mjs +5 -0
  9. package/dist/client/components/admin-link.d.mts +2 -2
  10. package/dist/client/components/fields/boolean-field.mjs +2 -1
  11. package/dist/client/components/fields/date-field.mjs +2 -1
  12. package/dist/client/components/fields/datetime-field.mjs +2 -1
  13. package/dist/client/components/fields/email-field.mjs +2 -1
  14. package/dist/client/components/fields/field-utils.d.mts +11 -0
  15. package/dist/client/components/fields/field-utils.mjs +3 -1
  16. package/dist/client/components/fields/field-wrapper.mjs +3 -3
  17. package/dist/client/components/fields/number-field.mjs +2 -1
  18. package/dist/client/components/fields/object-field.mjs +2 -1
  19. package/dist/client/components/fields/relation/displays/types.mjs +3 -3
  20. package/dist/client/components/fields/rich-text-editor/bubble-menu.mjs +7 -0
  21. package/dist/client/components/fields/rich-text-editor/extensions.mjs +19 -2
  22. package/dist/client/components/fields/rich-text-editor/image-popover.mjs +6 -2
  23. package/dist/client/components/fields/rich-text-editor/image-upload.mjs +2 -1
  24. package/dist/client/components/fields/rich-text-editor/index.d.mts +5 -3
  25. package/dist/client/components/fields/rich-text-editor/index.mjs +38 -76
  26. package/dist/client/components/fields/rich-text-editor/slash-commands.mjs +30 -7
  27. package/dist/client/components/fields/rich-text-editor/toolbar.mjs +1 -312
  28. package/dist/client/components/fields/rich-text-editor/types.d.mts +4 -0
  29. package/dist/client/components/fields/rich-text-editor/types.mjs +1 -1
  30. package/dist/client/components/fields/rich-text-editor/utils.mjs +6 -12
  31. package/dist/client/components/fields/select-field.mjs +2 -1
  32. package/dist/client/components/fields/text-field.mjs +2 -1
  33. package/dist/client/components/fields/textarea-field.mjs +2 -1
  34. package/dist/client/components/fields/time-field.mjs +2 -1
  35. package/dist/client/components/filter-builder/filter-builder-sheet.mjs +75 -22
  36. package/dist/client/components/layout/field-layout-renderer.mjs +4 -4
  37. package/dist/client/components/media/media-grid.mjs +2 -1
  38. package/dist/client/components/primitives/asset-preview.mjs +4 -2
  39. package/dist/client/components/primitives/dropzone.d.mts +100 -0
  40. package/dist/client/components/primitives/field-select-control.mjs +2 -1
  41. package/dist/client/components/ui/button.d.mts +23 -0
  42. package/dist/client/components/ui/button.mjs +2 -2
  43. package/dist/client/components/ui/dropdown-menu.d.mts +49 -0
  44. package/dist/client/components/ui/dropdown-menu.mjs +7 -19
  45. package/dist/client/components/ui/popover.mjs +1 -1
  46. package/dist/client/components/ui/search-input.d.mts +56 -0
  47. package/dist/client/components/ui/select.mjs +2 -2
  48. package/dist/client/components/ui/sheet.d.mts +40 -0
  49. package/dist/client/components/ui/table.d.mts +49 -0
  50. package/dist/client/components/ui/table.mjs +15 -1
  51. package/dist/client/components/ui/tooltip.d.mts +21 -0
  52. package/dist/client/contexts/focus-context.d.mts +2 -2
  53. package/dist/client/hooks/query-access.d.mts +9 -0
  54. package/dist/client/hooks/query-access.mjs +20 -0
  55. package/dist/client/hooks/typed-hooks.d.mts +4 -2
  56. package/dist/client/hooks/typed-hooks.mjs +30 -29
  57. package/dist/client/hooks/use-admin-config.mjs +20 -1
  58. package/dist/client/hooks/use-autosave.mjs +91 -0
  59. package/dist/client/hooks/use-collection.mjs +65 -23
  60. package/dist/client/hooks/use-reactive-fields.d.mts +1 -0
  61. package/dist/client/hooks/use-reactive-fields.mjs +16 -1
  62. package/dist/client/hooks/use-server-actions.mjs +12 -1
  63. package/dist/client/hooks/use-upload.d.mts +40 -0
  64. package/dist/client/hooks/use-upload.mjs +4 -2
  65. package/dist/client/hooks/use-view-state.mjs +15 -7
  66. package/dist/client/i18n/hooks.d.mts +20 -0
  67. package/dist/client/lib/utils.d.mts +6 -0
  68. package/dist/client/lib/view-filter-utils.mjs +30 -0
  69. package/dist/client/preview/block-scope-context.d.mts +2 -2
  70. package/dist/client/preview/preview-banner.d.mts +2 -2
  71. package/dist/client/preview/preview-field.d.mts +4 -4
  72. package/dist/client/runtime/provider.mjs +22 -3
  73. package/dist/client/scope/picker.d.mts +2 -2
  74. package/dist/client/scope/provider.d.mts +2 -2
  75. package/dist/client/styles/base.css +75 -79
  76. package/dist/client/utils/asset-url.mjs +27 -0
  77. package/dist/client/utils/build-field-definitions-from-schema.mjs +1 -0
  78. package/dist/client/views/auth/accept-invite-form.d.mts +2 -2
  79. package/dist/client/views/auth/auth-layout.d.mts +3 -3
  80. package/dist/client/views/auth/forgot-password-form.d.mts +2 -2
  81. package/dist/client/views/auth/login-form.d.mts +2 -2
  82. package/dist/client/views/auth/reset-password-form.d.mts +2 -2
  83. package/dist/client/views/auth/setup-form.d.mts +2 -2
  84. package/dist/client/views/collection/auto-form-fields.mjs +7 -6
  85. package/dist/client/views/collection/cells/primitive-cells.mjs +9 -6
  86. package/dist/client/views/collection/cells/shared/asset-thumbnail.d.mts +7 -0
  87. package/dist/client/views/collection/cells/shared/asset-thumbnail.mjs +3 -2
  88. package/dist/client/views/collection/cells/shared/cell-helpers.mjs +3 -2
  89. package/dist/client/views/collection/cells/upload-cells.mjs +2 -1
  90. package/dist/client/views/collection/columns/build-columns.mjs +3 -1
  91. package/dist/client/views/collection/document-view.d.mts +30 -0
  92. package/dist/client/views/collection/document-view.mjs +377 -0
  93. package/dist/client/views/collection/field-context.mjs +3 -2
  94. package/dist/client/views/collection/field-renderer.mjs +13 -5
  95. package/dist/client/views/collection/form-view.mjs +221 -282
  96. package/dist/client/views/collection/list-view.mjs +592 -190
  97. package/dist/client/views/collection/outline.mjs +44 -19
  98. package/dist/client/views/collection/quick-filter-bar.mjs +45 -0
  99. package/dist/client/views/collection/table-view.mjs +61 -17
  100. package/dist/client/views/globals/global-form-view.mjs +12 -9
  101. package/dist/client/views/layout/admin-layout-provider.mjs +4 -3
  102. package/dist/client/views/layout/admin-layout.mjs +108 -21
  103. package/dist/client/views/layout/admin-router.mjs +19 -3
  104. package/dist/client/views/layout/admin-sidebar.mjs +70 -20
  105. package/dist/client/views/layout/admin-theme.mjs +5 -4
  106. package/dist/client/views/layout/admin-view-layout.d.mts +36 -0
  107. package/dist/client/views/pages/accept-invite-page.d.mts +2 -2
  108. package/dist/client/views/pages/dashboard-page.d.mts +2 -2
  109. package/dist/client/views/pages/forgot-password-page.d.mts +2 -2
  110. package/dist/client/views/pages/invite-page.d.mts +2 -2
  111. package/dist/client/views/pages/login-page.d.mts +2 -2
  112. package/dist/client/views/pages/reset-password-page.d.mts +2 -2
  113. package/dist/client/views/pages/setup-page.d.mts +2 -2
  114. package/dist/client.d.mts +17 -2
  115. package/dist/client.mjs +17 -2
  116. package/dist/components/rich-text/rich-text-renderer.d.mts +5 -5
  117. package/dist/components/rich-text/rich-text-renderer.mjs +5 -2
  118. package/dist/factories.d.mts +4 -2
  119. package/dist/factories.mjs +2 -2
  120. package/dist/index.d.mts +17 -3
  121. package/dist/index.mjs +17 -2
  122. package/dist/modules/admin.d.mts +1 -1
  123. package/dist/server/adapters/index.d.mts +2 -0
  124. package/dist/server/adapters/nextjs.d.mts +1 -0
  125. package/dist/server/augmentation/actions.d.mts +9 -3
  126. package/dist/server/augmentation/dashboard.d.mts +11 -11
  127. package/dist/server/augmentation/form-layout.d.mts +16 -6
  128. package/dist/server/augmentation/index.d.mts +7 -0
  129. package/dist/server/augmentation/sidebar.d.mts +8 -8
  130. package/dist/server/augmentation/views.d.mts +4 -1
  131. package/dist/server/auth-helpers.d.mts +1 -0
  132. package/dist/server/codegen/admin-client-template.mjs +7 -6
  133. package/dist/server/fields/blocks.mjs +4 -1
  134. package/dist/server/fields/index.d.mts +1 -1
  135. package/dist/server/fields/reactive-runtime.mjs +3 -0
  136. package/dist/server/fields/rich-text.d.mts +16 -17
  137. package/dist/server/fields/rich-text.mjs +18 -7
  138. package/dist/server/i18n/messages/cs.mjs +2 -0
  139. package/dist/server/i18n/messages/de.mjs +2 -0
  140. package/dist/server/i18n/messages/en.mjs +4 -0
  141. package/dist/server/i18n/messages/es.mjs +2 -0
  142. package/dist/server/i18n/messages/fr.mjs +2 -0
  143. package/dist/server/i18n/messages/pl.mjs +2 -0
  144. package/dist/server/i18n/messages/pt.mjs +2 -0
  145. package/dist/server/i18n/messages/sk.mjs +2 -0
  146. package/dist/server/modules/admin/.generated/module.d.mts +1 -1
  147. package/dist/server/modules/admin/auth-helpers.mjs +7 -1
  148. package/dist/server/modules/admin/block/block-builder.d.mts +0 -8
  149. package/dist/server/modules/admin/block/introspection.d.mts +2 -2
  150. package/dist/server/modules/admin/block/introspection.mjs +28 -4
  151. package/dist/server/modules/admin/block/prefetch.d.mts +11 -0
  152. package/dist/server/modules/admin/block/prefetch.mjs +108 -27
  153. package/dist/server/modules/admin/client/.generated/module.d.mts +68 -67
  154. package/dist/server/modules/admin/client/.generated/module.mjs +2 -0
  155. package/dist/server/modules/admin/client/views/collection-document.d.mts +6 -0
  156. package/dist/server/modules/admin/client/views/collection-document.mjs +10 -0
  157. package/dist/server/modules/admin/collections/account.d.mts +53 -52
  158. package/dist/server/modules/admin/collections/admin-locks.d.mts +57 -56
  159. package/dist/server/modules/admin/collections/admin-preferences.d.mts +38 -37
  160. package/dist/server/modules/admin/collections/admin-saved-views.d.mts +50 -49
  161. package/dist/server/modules/admin/collections/apikey.d.mts +76 -67
  162. package/dist/server/modules/admin/collections/assets.d.mts +37 -36
  163. package/dist/server/modules/admin/collections/session.d.mts +42 -41
  164. package/dist/server/modules/admin/collections/user.d.mts +57 -56
  165. package/dist/server/modules/admin/collections/verification.d.mts +34 -33
  166. package/dist/server/modules/admin/dto/admin-config.dto.mjs +34 -4
  167. package/dist/server/modules/admin/factories.mjs +4 -34
  168. package/dist/server/modules/admin/index.d.mts +3 -3
  169. package/dist/server/modules/admin/routes/admin-config.d.mts +4 -2
  170. package/dist/server/modules/admin/routes/admin-config.mjs +56 -24
  171. package/dist/server/modules/admin/routes/execute-action.d.mts +9 -9
  172. package/dist/server/modules/admin/routes/execute-action.mjs +35 -9
  173. package/dist/server/modules/admin/routes/locales.mjs +1 -1
  174. package/dist/server/modules/admin/routes/preview.d.mts +11 -11
  175. package/dist/server/modules/admin/routes/preview.mjs +6 -5
  176. package/dist/server/modules/admin/routes/reactive.d.mts +9 -9
  177. package/dist/server/modules/admin/routes/reactive.mjs +2 -2
  178. package/dist/server/modules/admin/routes/route-helpers.d.mts +11 -7
  179. package/dist/server/modules/admin/routes/route-helpers.mjs +1 -1
  180. package/dist/server/modules/admin/routes/setup.d.mts +7 -7
  181. package/dist/server/modules/admin/routes/translations.d.mts +4 -4
  182. package/dist/server/modules/admin/routes/widget-data.d.mts +5 -5
  183. package/dist/server/modules/admin/routes/widget-data.mjs +12 -4
  184. package/dist/server/modules/admin-preferences/collections/saved-views.d.mts +45 -45
  185. package/dist/server/modules/audit/.generated/module.d.mts +6 -6
  186. package/dist/server/modules/audit/collections/audit-log.d.mts +81 -80
  187. package/dist/server/modules/audit/jobs/audit-cleanup.d.mts +2 -2
  188. package/dist/server/plugin.mjs +10 -5
  189. package/dist/server/proxy-factories.d.mts +8 -1
  190. package/dist/server/proxy-factories.mjs +33 -1
  191. package/dist/server.d.mts +3 -1
  192. package/dist/shared/types/index.d.mts +1 -0
  193. package/dist/shared/types/saved-views.types.d.mts +14 -7
  194. package/dist/shared.d.mts +3 -2
  195. package/package.json +5 -4
@@ -4,6 +4,8 @@
4
4
  @import "@fontsource-variable/geist";
5
5
  @import "@fontsource-variable/jetbrains-mono";
6
6
 
7
+ @source "../**/*.{js,jsx,ts,tsx}";
8
+
7
9
  /* ================================================================
8
10
  QUESTPIE ADMIN THEME — Base
9
11
  ================================================================
@@ -361,46 +363,19 @@
361
363
  }
362
364
 
363
365
  /* =============================================================================
364
- Rich Text Editor Styles
366
+ Rich Text Editor Styles — Notion-like document editor
365
367
  ============================================================================= */
366
368
 
367
369
  .qp-rich-text-editor {
368
370
  position: relative;
369
- border-color: var(--border-subtle);
370
- background: var(--surface-low);
371
- transition-property: background-color, border-color, box-shadow;
372
- transition-duration: var(--motion-duration-base);
373
- transition-timing-function: var(--motion-ease-standard);
374
- }
375
-
376
- .qp-rich-text-editor:focus-within {
377
- border-color: var(--border-strong);
378
- box-shadow: 0 0 0 3px color-mix(in srgb, var(--ring) 18%, transparent);
379
- }
380
-
381
- .qp-rich-text-editor [data-rich-text-toolbar-button] {
382
- flex: 0 0 auto;
383
- }
384
-
385
- .qp-rich-text-editor__toolbar {
386
- scrollbar-width: none;
387
- -webkit-overflow-scrolling: touch;
388
- }
389
-
390
- .qp-rich-text-editor__toolbar::-webkit-scrollbar {
391
- display: none;
392
- }
393
-
394
- .qp-rich-text-editor__toolbar > [role="group"] {
395
- flex: 0 0 auto;
396
371
  }
397
372
 
398
373
  .qp-rich-text-editor__bubble {
399
374
  display: flex;
400
375
  align-items: center;
401
- gap: 0.25rem;
402
- padding: 0.25rem;
403
- border-radius: calc(var(--control-radius-inner) + 0.25rem);
376
+ gap: 0.375rem;
377
+ padding: 0.375rem;
378
+ border-radius: var(--floating-radius);
404
379
  }
405
380
 
406
381
  .qp-rich-text-editor__bubble-block {
@@ -411,7 +386,8 @@
411
386
 
412
387
  .qp-rich-text-editor__bubble-separator {
413
388
  width: 1px;
414
- height: 1.5rem;
389
+ height: 1.25rem;
390
+ margin: 0 0.125rem;
415
391
  background: var(--border-subtle);
416
392
  }
417
393
 
@@ -419,8 +395,8 @@
419
395
  display: grid;
420
396
  grid-template-columns: auto minmax(12rem, 18rem) auto auto;
421
397
  align-items: center;
422
- gap: 0.375rem;
423
- padding: 0.125rem;
398
+ gap: 0.5rem;
399
+ padding: 0.25rem;
424
400
  }
425
401
 
426
402
  .qp-rich-text-editor__link-input {
@@ -446,13 +422,14 @@
446
422
  font-size: 0.75rem;
447
423
  }
448
424
 
425
+ /* Content area — document editor feel */
449
426
  .qp-rich-text-editor__content {
450
427
  min-height: 240px;
451
- padding: 1rem 1.25rem 1.25rem;
428
+ padding: 1.25rem 1.5rem 1.5rem;
452
429
  outline: none;
453
430
  color: var(--foreground);
454
- font-size: 0.9375rem;
455
- line-height: 1.65;
431
+ font-size: 1rem;
432
+ line-height: 1.7;
456
433
  text-wrap: pretty;
457
434
  caret-color: var(--foreground);
458
435
  }
@@ -478,30 +455,30 @@
478
455
  }
479
456
 
480
457
  .qp-rich-text-editor__content p {
481
- margin: 0 0 0.8rem;
458
+ margin: 0 0 0.5em;
482
459
  }
483
460
 
484
461
  .qp-rich-text-editor__content h1 {
485
- margin: 1.5rem 0 0.85rem;
486
- font-size: 1.625rem;
487
- font-weight: 650;
488
- letter-spacing: 0;
462
+ margin: 1.75em 0 0.4em;
463
+ font-size: 1.875rem;
464
+ font-weight: 700;
465
+ letter-spacing: -0.02em;
489
466
  line-height: 1.2;
490
467
  text-wrap: balance;
491
468
  }
492
469
 
493
470
  .qp-rich-text-editor__content h2 {
494
- margin: 1.35rem 0 0.75rem;
495
- font-size: 1.375rem;
471
+ margin: 1.5em 0 0.35em;
472
+ font-size: 1.5rem;
496
473
  font-weight: 650;
497
- letter-spacing: 0;
474
+ letter-spacing: -0.01em;
498
475
  line-height: 1.25;
499
476
  text-wrap: balance;
500
477
  }
501
478
 
502
479
  .qp-rich-text-editor__content h3 {
503
- margin: 1.15rem 0 0.65rem;
504
- font-size: 1.125rem;
480
+ margin: 1.25em 0 0.3em;
481
+ font-size: 1.25rem;
505
482
  font-weight: 650;
506
483
  letter-spacing: 0;
507
484
  line-height: 1.3;
@@ -511,36 +488,40 @@
511
488
  .qp-rich-text-editor__content h4,
512
489
  .qp-rich-text-editor__content h5,
513
490
  .qp-rich-text-editor__content h6 {
514
- margin: 1rem 0 0.5rem;
491
+ margin: 1.15em 0 0.25em;
515
492
  font-size: 1rem;
516
493
  font-weight: 650;
517
494
  letter-spacing: 0;
518
- line-height: 1.35;
495
+ line-height: 1.4;
519
496
  text-wrap: balance;
520
497
  }
521
498
 
522
499
  .qp-rich-text-editor__content ul,
523
500
  .qp-rich-text-editor__content ol {
524
- margin: 0.75rem 0;
525
- padding-left: 1.35rem;
501
+ margin: 0.75em 0;
502
+ padding-left: 1.5rem;
526
503
  }
527
504
 
528
505
  .qp-rich-text-editor__content li {
529
- margin: 0.25rem 0;
530
- padding-left: 0.15rem;
506
+ margin: 0.35em 0;
507
+ padding-left: 0.25rem;
508
+ }
509
+
510
+ .qp-rich-text-editor__content li p {
511
+ margin: 0;
531
512
  }
532
513
 
533
514
  .qp-rich-text-editor__content blockquote {
534
- margin: 1rem 0;
515
+ margin: 1.25em 0;
535
516
  border-left: 3px solid var(--border-strong);
536
- padding: 0.15rem 0 0.15rem 0.85rem;
517
+ padding: 0.25em 0 0.25em 1rem;
537
518
  color: var(--muted-foreground);
538
519
  }
539
520
 
540
521
  .qp-rich-text-editor__content code {
541
522
  background: var(--muted);
542
523
  border-radius: var(--radius-xs);
543
- padding: 0.1rem 0.3rem;
524
+ padding: 0.15em 0.35em;
544
525
  font-size: 0.875em;
545
526
  font-family: var(--font-mono);
546
527
  }
@@ -548,11 +529,11 @@
548
529
  .qp-rich-text-editor__content pre {
549
530
  background: var(--muted);
550
531
  border-radius: var(--control-radius-inner);
551
- margin: 1rem 0;
552
- padding: 0.875rem 1rem;
532
+ margin: 1.25em 0;
533
+ padding: 1rem 1.25rem;
553
534
  font-family: var(--font-mono);
554
535
  font-size: 0.8125rem;
555
- line-height: 1.6;
536
+ line-height: 1.65;
556
537
  overflow-x: auto;
557
538
  }
558
539
 
@@ -565,14 +546,14 @@
565
546
  .qp-rich-text-editor__content hr {
566
547
  border: none;
567
548
  border-top: 1px solid var(--border-subtle);
568
- margin: 1.25rem 0;
549
+ margin: 1.75em 0;
569
550
  }
570
551
 
571
552
  .qp-rich-text-editor__content img {
572
553
  display: block;
573
554
  max-width: 100%;
574
555
  height: auto;
575
- margin: 1rem 0;
556
+ margin: 1.25em 0;
576
557
  border-radius: var(--control-radius-inner);
577
558
  outline: 1px solid rgba(255, 255, 255, 0.1);
578
559
  outline-offset: -1px;
@@ -585,7 +566,7 @@
585
566
 
586
567
  .qp-rich-text-editor__content table {
587
568
  border-collapse: collapse;
588
- margin: 1rem 0;
569
+ margin: 1.25em 0;
589
570
  width: 100%;
590
571
  font-size: 0.875rem;
591
572
  }
@@ -593,7 +574,7 @@
593
574
  .qp-rich-text-editor__content th,
594
575
  .qp-rich-text-editor__content td {
595
576
  border: 1px solid var(--border-subtle);
596
- padding: 0.5rem 0.625rem;
577
+ padding: 0.5rem 0.75rem;
597
578
  text-align: left;
598
579
  vertical-align: top;
599
580
  }
@@ -615,25 +596,28 @@
615
596
  padding: 0;
616
597
  }
617
598
 
599
+ /* Slash command menu — compact command density */
618
600
  .qp-rich-text-editor__slash {
619
601
  display: flex;
620
602
  flex-direction: column;
621
- gap: 0.25rem;
603
+ gap: 0.125rem;
622
604
  min-width: 280px;
623
- max-width: min(360px, calc(100vw - 2rem));
624
- padding: 0.35rem;
605
+ max-width: min(340px, calc(100vw - 2rem));
606
+ max-height: min(19rem, calc(100vh - 4rem));
607
+ overflow-y: auto;
608
+ padding: 0.375rem;
625
609
  }
626
610
 
627
611
  .qp-rich-text-editor__slash-item {
628
612
  display: flex;
629
613
  width: 100%;
630
- min-height: 3rem;
614
+ min-height: 2.25rem;
631
615
  align-items: center;
632
- gap: 0.625rem;
616
+ gap: 0.5rem;
633
617
  border: 1px solid transparent;
634
- border-radius: var(--control-radius-inner);
618
+ border-radius: var(--radius-sm);
635
619
  background: transparent;
636
- padding: 0.45rem 0.55rem;
620
+ padding: 0.3125rem 0.5rem;
637
621
  color: var(--foreground);
638
622
  font-size: 0.8125rem;
639
623
  line-height: 1.2;
@@ -653,14 +637,15 @@
653
637
 
654
638
  .qp-rich-text-editor__slash-icon {
655
639
  display: inline-flex;
656
- width: 2rem;
657
- height: 2rem;
640
+ width: 1.5rem;
641
+ height: 1.5rem;
658
642
  flex: 0 0 auto;
659
643
  align-items: center;
660
644
  justify-content: center;
661
- border-radius: var(--radius-xs);
645
+ border-radius: var(--radius-sm);
662
646
  background: var(--surface-mid);
663
647
  color: var(--muted-foreground);
648
+ font-size: 1.125rem;
664
649
  }
665
650
 
666
651
  .qp-rich-text-editor__slash-copy {
@@ -668,29 +653,40 @@
668
653
  min-width: 0;
669
654
  flex: 1;
670
655
  flex-direction: column;
671
- gap: 0.125rem;
656
+ gap: 0.0625rem;
672
657
  }
673
658
 
674
659
  .qp-rich-text-editor__slash-title {
675
660
  font-family: var(--font-chrome);
676
- font-weight: 600;
661
+ font-weight: 500;
677
662
  }
678
663
 
679
664
  .qp-rich-text-editor__slash-description {
680
665
  color: var(--muted-foreground);
666
+ font-size: 0.6875rem;
667
+ line-height: 1.25;
681
668
  overflow: hidden;
682
669
  text-overflow: ellipsis;
683
670
  white-space: nowrap;
684
671
  }
685
672
 
673
+ .qp-rich-text-editor__slash-group {
674
+ padding: 0.3125rem 0.5rem 0.125rem;
675
+ font-family: var(--font-chrome);
676
+ font-size: 0.625rem;
677
+ font-weight: 600;
678
+ letter-spacing: 0.04em;
679
+ text-transform: uppercase;
680
+ color: var(--muted-foreground);
681
+ }
682
+
686
683
  .qp-rich-text-editor__slash-empty {
687
- padding: 0.5rem;
688
- font-size: 0.75rem;
684
+ padding: 0.625rem;
685
+ font-size: 0.8125rem;
689
686
  color: var(--muted-foreground);
690
687
  }
691
688
 
692
689
  @media (prefers-reduced-motion: reduce) {
693
- .qp-rich-text-editor,
694
690
  .qp-rich-text-editor__bubble,
695
691
  .qp-rich-text-editor__slash-item {
696
692
  transition: none;
@@ -700,7 +696,7 @@
700
696
  @media (max-width: 640px) {
701
697
  .qp-rich-text-editor__content {
702
698
  min-height: 200px;
703
- padding: 0.875rem 1rem 1rem;
699
+ padding: 1rem 1rem 1.25rem;
704
700
  }
705
701
 
706
702
  .qp-rich-text-editor__bubble {
@@ -0,0 +1,27 @@
1
+ //#region src/client/utils/asset-url.ts
2
+ const STORAGE_FILE_PATH_PATTERN = /^\/api\/[^/]+\/files(?:\/|$)/;
3
+ function isStorageFilePath(pathname) {
4
+ return STORAGE_FILE_PATH_PATTERN.test(pathname);
5
+ }
6
+ function currentOrigin() {
7
+ if (typeof window === "undefined" || !window.location?.origin) return null;
8
+ return window.location.origin;
9
+ }
10
+ function resolveAssetUrl(url) {
11
+ if (typeof url !== "string") return void 0;
12
+ const trimmed = url.trim();
13
+ if (!trimmed) return void 0;
14
+ if (trimmed.startsWith("/")) return trimmed;
15
+ const origin = currentOrigin();
16
+ if (!origin) return trimmed;
17
+ try {
18
+ const parsed = new URL(trimmed);
19
+ if (isStorageFilePath(parsed.pathname) && parsed.origin === origin) return `${parsed.pathname}${parsed.search}${parsed.hash}`;
20
+ } catch {
21
+ return trimmed;
22
+ }
23
+ return trimmed;
24
+ }
25
+
26
+ //#endregion
27
+ export { resolveAssetUrl };
@@ -205,6 +205,7 @@ function applyRichTextConfig(config, metadata) {
205
205
  if (metadata.placeholder !== void 0) config.placeholder = metadata.placeholder;
206
206
  if (metadata.allowImages !== void 0) config.enableImages = metadata.allowImages;
207
207
  if (metadata.imageCollection !== void 0) config.imageCollection = metadata.imageCollection;
208
+ if (metadata.outputMode !== void 0) config.outputMode = metadata.outputMode;
208
209
  }
209
210
  function buildNestedFieldDefinitions(nestedFields, relations, registry) {
210
211
  const result = {};
@@ -1,4 +1,4 @@
1
- import * as react_jsx_runtime2 from "react/jsx-runtime";
1
+ import * as react_jsx_runtime36 from "react/jsx-runtime";
2
2
 
3
3
  //#region src/client/views/auth/accept-invite-form.d.ts
4
4
  /**
@@ -67,6 +67,6 @@ declare function AcceptInviteForm({
67
67
  className,
68
68
  error,
69
69
  minPasswordLength
70
- }: AcceptInviteFormProps): react_jsx_runtime2.JSX.Element;
70
+ }: AcceptInviteFormProps): react_jsx_runtime36.JSX.Element;
71
71
  //#endregion
72
72
  export { AcceptInviteForm };
@@ -1,5 +1,5 @@
1
1
  import * as React from "react";
2
- import * as react_jsx_runtime0 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime34 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/client/views/auth/auth-layout.d.ts
5
5
 
@@ -26,7 +26,7 @@ declare function AuthDefaultLogo({
26
26
  brandName
27
27
  }: {
28
28
  brandName: string;
29
- }): react_jsx_runtime0.JSX.Element;
29
+ }): react_jsx_runtime34.JSX.Element;
30
30
  /**
31
31
  * Minimal split layout for authentication pages (login, register, forgot password, etc.)
32
32
  *
@@ -50,6 +50,6 @@ declare function AuthDefaultLogo({
50
50
  * </AuthLayout>
51
51
  * ```
52
52
  */
53
- declare function AuthLayout(props: AuthLayoutProps): react_jsx_runtime0.JSX.Element;
53
+ declare function AuthLayout(props: AuthLayoutProps): react_jsx_runtime34.JSX.Element;
54
54
  //#endregion
55
55
  export { AuthDefaultLogo, AuthLayout, AuthLayoutProps };
@@ -1,4 +1,4 @@
1
- import * as react_jsx_runtime3 from "react/jsx-runtime";
1
+ import * as react_jsx_runtime37 from "react/jsx-runtime";
2
2
 
3
3
  //#region src/client/views/auth/forgot-password-form.d.ts
4
4
  /**
@@ -53,6 +53,6 @@ declare function ForgotPasswordForm({
53
53
  defaultValues,
54
54
  className,
55
55
  error
56
- }: ForgotPasswordFormProps): react_jsx_runtime3.JSX.Element;
56
+ }: ForgotPasswordFormProps): react_jsx_runtime37.JSX.Element;
57
57
  //#endregion
58
58
  export { ForgotPasswordForm };
@@ -1,4 +1,4 @@
1
- import * as react_jsx_runtime5 from "react/jsx-runtime";
1
+ import * as react_jsx_runtime38 from "react/jsx-runtime";
2
2
 
3
3
  //#region src/client/views/auth/login-form.d.ts
4
4
  /**
@@ -70,6 +70,6 @@ declare function LoginForm({
70
70
  className,
71
71
  error,
72
72
  minPasswordLength
73
- }: LoginFormProps): react_jsx_runtime5.JSX.Element;
73
+ }: LoginFormProps): react_jsx_runtime38.JSX.Element;
74
74
  //#endregion
75
75
  export { LoginForm };
@@ -1,4 +1,4 @@
1
- import * as react_jsx_runtime4 from "react/jsx-runtime";
1
+ import * as react_jsx_runtime40 from "react/jsx-runtime";
2
2
 
3
3
  //#region src/client/views/auth/reset-password-form.d.ts
4
4
  /**
@@ -60,6 +60,6 @@ declare function ResetPasswordForm({
60
60
  minPasswordLength,
61
61
  className,
62
62
  error
63
- }: ResetPasswordFormProps): react_jsx_runtime4.JSX.Element;
63
+ }: ResetPasswordFormProps): react_jsx_runtime40.JSX.Element;
64
64
  //#endregion
65
65
  export { ResetPasswordForm };
@@ -1,4 +1,4 @@
1
- import * as react_jsx_runtime6 from "react/jsx-runtime";
1
+ import * as react_jsx_runtime39 from "react/jsx-runtime";
2
2
 
3
3
  //#region src/client/views/auth/setup-form.d.ts
4
4
  /**
@@ -55,6 +55,6 @@ declare function SetupForm({
55
55
  className,
56
56
  error,
57
57
  minPasswordLength
58
- }: SetupFormProps): react_jsx_runtime6.JSX.Element;
58
+ }: SetupFormProps): react_jsx_runtime39.JSX.Element;
59
59
  //#endregion
60
60
  export { SetupForm, SetupFormValues };
@@ -5,6 +5,7 @@ import { getGridColumnsClass } from "../../components/fields/field-utils.mjs";
5
5
  import { getFieldName, isFieldReference } from "../../builder/types/field-types.mjs";
6
6
  import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "../../components/ui/accordion.mjs";
7
7
  import { Tabs, TabsContent, TabsList, TabsTrigger } from "../../components/ui/tabs.mjs";
8
+ import { adminCollectionKey } from "../../hooks/query-access.mjs";
8
9
  import { useCollectionFields } from "../../hooks/use-collection-fields.mjs";
9
10
  import { useCollectionMeta } from "../../hooks/use-collection-meta.mjs";
10
11
  import { useGlobalFields } from "../../hooks/use-global-fields.mjs";
@@ -273,18 +274,18 @@ function SectionLayoutRenderer({ section, index, fields, collection, mode = "col
273
274
  const value = `section-${index}`;
274
275
  return /* @__PURE__ */ jsx(Accordion, {
275
276
  defaultValue: section.defaultCollapsed !== true ? [value] : [],
276
- className: "w-full",
277
+ className: "qa-form-fields__section qa-form-fields__section--collapsible panel-surface bg-card overflow-hidden",
277
278
  children: /* @__PURE__ */ jsxs(AccordionItem, {
278
279
  value,
279
- className: "border-transparent px-4",
280
+ className: "border-none px-0 data-open:bg-transparent",
280
281
  children: [/* @__PURE__ */ jsx(AccordionTrigger, {
281
- className: "hover:no-underline",
282
+ className: "hover:bg-surface-low aria-expanded:bg-surface-low min-h-12 px-4 py-3 hover:no-underline",
282
283
  children: /* @__PURE__ */ jsx("span", {
283
284
  className: "font-semibold",
284
285
  children: resolveText(section.label, "Section", formValues)
285
286
  })
286
287
  }), /* @__PURE__ */ jsxs(AccordionContent, {
287
- className: "pt-2 pb-4",
288
+ className: "border-border-subtle border-t px-4 pt-3 pb-4",
288
289
  children: [section.description && /* @__PURE__ */ jsx("p", {
289
290
  className: "text-muted-foreground mb-4 text-sm text-pretty",
290
291
  children: resolveText(section.description, "", formValues)
@@ -393,8 +394,8 @@ function AutoFormFields({ app: _cms, collection, mode = "collection", config, re
393
394
  schemaQueryOptions: { enabled: mode === "collection" && !isActionForm && shouldFetchSchema }
394
395
  });
395
396
  const globalResult = useGlobalFields(mode === "global" ? collection : "", { schemaQueryOptions: { enabled: mode === "global" && shouldFetchSchema } });
396
- const { data: collectionMeta } = useCollectionMeta(collection, { enabled: mode === "collection" && !isActionForm });
397
- const { data: globalMeta } = useGlobalMeta(collection, { enabled: mode === "global" });
397
+ const { data: collectionMeta } = useCollectionMeta(adminCollectionKey(collection), { enabled: mode === "collection" && !isActionForm });
398
+ const { data: globalMeta } = useGlobalMeta(adminCollectionKey(collection), { enabled: mode === "global" });
398
399
  const resolvedFields = mode === "global" ? {
399
400
  ...providedFields ?? globalResult.fields,
400
401
  ...config?.fields
@@ -104,6 +104,13 @@ function DateCell({ value }) {
104
104
  children: date.toLocaleDateString()
105
105
  });
106
106
  }
107
+ function formatShortDate(date) {
108
+ const now = /* @__PURE__ */ new Date();
109
+ const sameYear = date.getFullYear() === now.getFullYear();
110
+ const month = date.toLocaleDateString(void 0, { month: "short" });
111
+ const day = date.getDate();
112
+ return sameYear ? `${month} ${day}` : `${month} ${day}, ${date.getFullYear()}`;
113
+ }
107
114
  /**
108
115
  * DateTime cell - formatted date and time display
109
116
  */
@@ -117,13 +124,9 @@ function DateTimeCell({ value }) {
117
124
  className: "text-muted-foreground",
118
125
  children: String(value)
119
126
  });
120
- return /* @__PURE__ */ jsxs("span", {
127
+ return /* @__PURE__ */ jsx("span", {
121
128
  className: "tabular-nums",
122
- children: [
123
- date.toLocaleDateString(),
124
- " ",
125
- date.toLocaleTimeString()
126
- ]
129
+ children: formatShortDate(date)
127
130
  });
128
131
  }
129
132
  /**
@@ -0,0 +1,7 @@
1
+ import "react/jsx-runtime";
2
+
3
+ //#region src/client/views/collection/cells/shared/asset-thumbnail.d.ts
4
+
5
+ declare function getFileIcon(mimeType?: string): string;
6
+ //#endregion
7
+ export { getFileIcon };
@@ -1,5 +1,6 @@
1
1
  import { cn } from "../../../../lib/utils.mjs";
2
2
  import { Button } from "../../../../components/ui/button.mjs";
3
+ import { resolveAssetUrl } from "../../../../utils/asset-url.mjs";
3
4
  import { Icon } from "@iconify/react";
4
5
  import { jsx, jsxs } from "react/jsx-runtime";
5
6
 
@@ -51,7 +52,7 @@ function AssetThumbnail({ asset, size = "sm", showFilename = false, showControls
51
52
  })
52
53
  });
53
54
  const assetObj = asset;
54
- const url = assetObj.url;
55
+ const url = resolveAssetUrl(assetObj.url);
55
56
  const filename = assetObj.filename;
56
57
  const mimeType = assetObj.mimeType;
57
58
  const alt = assetObj.alt;
@@ -223,4 +224,4 @@ function AssetThumbnail({ asset, size = "sm", showFilename = false, showControls
223
224
  }
224
225
 
225
226
  //#endregion
226
- export { AssetThumbnail };
227
+ export { AssetThumbnail, getFileIcon };
@@ -1,4 +1,5 @@
1
1
  import { formatLabel } from "../../../../lib/utils.mjs";
2
+ import { resolveAssetUrl } from "../../../../utils/asset-url.mjs";
2
3
 
3
4
  //#region src/client/views/collection/cells/shared/cell-helpers.ts
4
5
  function getNestedValue(item, path) {
@@ -15,9 +16,9 @@ function toImageUrl(value) {
15
16
  if (!value || typeof value !== "object") return null;
16
17
  const obj = value;
17
18
  const url = obj.url;
18
- if (typeof url === "string" && url.length > 0) return url;
19
+ if (typeof url === "string" && url.length > 0) return resolveAssetUrl(url) ?? null;
19
20
  const src = obj.src;
20
- if (typeof src === "string" && src.length > 0) return src;
21
+ if (typeof src === "string" && src.length > 0) return resolveAssetUrl(src) ?? null;
21
22
  return null;
22
23
  }
23
24
  /**
@@ -1,5 +1,6 @@
1
1
  import { useTranslation } from "../../../i18n/hooks.mjs";
2
2
  import { Badge } from "../../../components/ui/badge.mjs";
3
+ import { resolveAssetUrl } from "../../../utils/asset-url.mjs";
3
4
  import { AssetThumbnail } from "./shared/asset-thumbnail.mjs";
4
5
  import { useCollectionItem } from "../../../hooks/use-collection.mjs";
5
6
  import "react";
@@ -81,7 +82,7 @@ function UploadManyCell({ value }) {
81
82
  children: [/* @__PURE__ */ jsx("div", {
82
83
  className: "flex",
83
84
  children: imageAssets.map((asset, index) => /* @__PURE__ */ jsx("img", {
84
- src: asset.url,
85
+ src: resolveAssetUrl(asset.url) ?? "",
85
86
  alt: asset.filename || "Asset",
86
87
  className: `image-outline bg-background size-6 rounded object-cover${index > 0 ? " -ms-2" : ""}`
87
88
  }, asset.id || index))
@@ -2,7 +2,7 @@ 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
4
  import { LocaleSwitcher } from "../../../components/locale-switcher.mjs";
5
- import { DefaultCell, TextCell } from "../cells/primitive-cells.mjs";
5
+ import { DateCell, DateTimeCell, 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";
@@ -133,6 +133,8 @@ function buildColumns(options) {
133
133
  let CellComponent;
134
134
  if (normalized.cell) CellComponent = normalized.cell;
135
135
  else if (fieldDef?.cell) CellComponent = fieldDef.cell;
136
+ else if (fieldType === "datetime") CellComponent = DateTimeCell;
137
+ else if (fieldType === "date") CellComponent = DateCell;
136
138
  else CellComponent = DefaultCell;
137
139
  const needsFieldDef = FIELD_TYPES_NEEDING_FIELD_DEF.has(fieldType);
138
140
  const accessorKey = (fieldType === "relation" || fieldType === "upload" || fieldType === "uploadMany") && fieldOptions.relationName ? fieldOptions.relationName : fieldName;
@@ -0,0 +1,30 @@
1
+ import { ComponentRegistry, DocumentViewConfig } from "../../builder/types/field-types.mjs";
2
+ import { CollectionBuilderState } from "../../builder/types/collection-types.mjs";
3
+ import * as React from "react";
4
+
5
+ //#region src/client/views/collection/document-view.d.ts
6
+
7
+ interface DocumentViewProps {
8
+ collection: string;
9
+ id?: string;
10
+ config?: Partial<CollectionBuilderState> | Record<string, any>;
11
+ viewConfig?: DocumentViewConfig & Record<string, any>;
12
+ navigate: (path: string) => void;
13
+ basePath?: string;
14
+ defaultValues?: Record<string, any>;
15
+ registry?: ComponentRegistry;
16
+ allCollectionsConfig?: Record<string, any>;
17
+ title?: string;
18
+ }
19
+ declare function DocumentView({
20
+ collection,
21
+ id,
22
+ config,
23
+ viewConfig,
24
+ defaultValues: defaultValuesProp,
25
+ registry,
26
+ allCollectionsConfig,
27
+ title: titleProp
28
+ }: DocumentViewProps): React.ReactElement;
29
+ //#endregion
30
+ export { DocumentView };