@xleddyl/nuxt-cms 0.9.4 → 0.10.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 (431) hide show
  1. package/README.md +1 -1
  2. package/dist/module.d.mts +20 -1
  3. package/dist/module.json +1 -1
  4. package/dist/module.mjs +1037 -148
  5. package/dist/runtime/app/blocks/CmsBlocks.d.vue.ts +1 -1
  6. package/dist/runtime/app/blocks/CmsBlocks.vue +57 -9
  7. package/dist/runtime/app/blocks/CmsBlocks.vue.d.ts +1 -1
  8. package/dist/runtime/app/blocks/CmsField.d.ts +24 -0
  9. package/dist/runtime/app/blocks/CmsField.js +16 -0
  10. package/dist/runtime/app/blocks/node.d.ts +37 -0
  11. package/dist/runtime/app/blocks/node.js +17 -0
  12. package/dist/runtime/app/blocks/resolve.d.ts +18 -0
  13. package/dist/runtime/app/blocks/resolve.js +34 -0
  14. package/dist/runtime/app/components/cms/BlockPicker.d.vue.ts +22 -0
  15. package/dist/runtime/app/components/cms/BlockPicker.vue +87 -0
  16. package/dist/runtime/app/components/cms/BlockPicker.vue.d.ts +22 -0
  17. package/dist/runtime/app/components/cms/BlockPickerPopover.d.vue.ts +38 -0
  18. package/dist/runtime/app/components/cms/BlockPickerPopover.vue +44 -0
  19. package/dist/runtime/app/components/cms/BlockPickerPopover.vue.d.ts +38 -0
  20. package/dist/runtime/app/components/cms/BlockTree.d.vue.ts +29 -0
  21. package/dist/runtime/app/components/cms/BlockTree.vue +322 -0
  22. package/dist/runtime/app/components/cms/BlockTree.vue.d.ts +29 -0
  23. package/dist/runtime/app/components/cms/BlocksField.vue +569 -218
  24. package/dist/runtime/app/components/cms/BrandMark.vue +7 -13
  25. package/dist/runtime/app/components/cms/ConfirmGroups.vue +15 -13
  26. package/dist/runtime/app/components/cms/{BlockPalette.vue.d.ts → EditorHistory.d.vue.ts} +6 -5
  27. package/dist/runtime/app/components/cms/EditorHistory.vue +34 -0
  28. package/dist/runtime/app/components/cms/{BlockPalette.d.vue.ts → EditorHistory.vue.d.ts} +6 -5
  29. package/dist/runtime/app/components/cms/EntryDrawer.d.vue.ts +11 -5
  30. package/dist/runtime/app/components/cms/EntryDrawer.vue +183 -152
  31. package/dist/runtime/app/components/cms/EntryDrawer.vue.d.ts +11 -5
  32. package/dist/runtime/app/components/cms/EntryForm.d.vue.ts +16 -4
  33. package/dist/runtime/app/components/cms/EntryForm.vue +106 -146
  34. package/dist/runtime/app/components/cms/EntryForm.vue.d.ts +16 -4
  35. package/dist/runtime/app/components/cms/FieldInput.vue +10 -2
  36. package/dist/runtime/app/components/cms/FormSections.d.vue.ts +22 -0
  37. package/dist/runtime/app/components/cms/FormSections.vue +71 -0
  38. package/dist/runtime/app/components/cms/FormSections.vue.d.ts +22 -0
  39. package/dist/runtime/app/components/cms/ImportModal.vue +46 -58
  40. package/dist/runtime/app/components/cms/LinkField.d.vue.ts +16 -0
  41. package/dist/runtime/app/components/cms/LinkField.vue +250 -0
  42. package/dist/runtime/app/components/cms/LinkField.vue.d.ts +16 -0
  43. package/dist/runtime/app/components/cms/ListFilters.vue +10 -12
  44. package/dist/runtime/app/components/cms/LocaleSwitch.d.vue.ts +2 -1
  45. package/dist/runtime/app/components/cms/LocaleSwitch.vue +29 -5
  46. package/dist/runtime/app/components/cms/LocaleSwitch.vue.d.ts +2 -1
  47. package/dist/runtime/app/components/cms/MediaDetail.d.vue.ts +2 -0
  48. package/dist/runtime/app/components/cms/MediaDetail.vue +112 -83
  49. package/dist/runtime/app/components/cms/MediaDetail.vue.d.ts +2 -0
  50. package/dist/runtime/app/components/cms/MediaField.vue +35 -25
  51. package/dist/runtime/app/components/cms/MediaFolderPicker.vue +26 -71
  52. package/dist/runtime/app/components/cms/MediaGallery.d.vue.ts +1 -0
  53. package/dist/runtime/app/components/cms/MediaGallery.vue +442 -419
  54. package/dist/runtime/app/components/cms/MediaGallery.vue.d.ts +1 -0
  55. package/dist/runtime/app/components/cms/MediaThumb.vue +9 -25
  56. package/dist/runtime/app/components/cms/MediaUpload.vue +1 -1
  57. package/dist/runtime/app/components/cms/{BlockOutline.d.vue.ts → NestedBlockList.d.vue.ts} +5 -5
  58. package/dist/runtime/app/components/cms/NestedBlockList.vue +87 -0
  59. package/dist/runtime/app/components/cms/{BlockOutline.vue.d.ts → NestedBlockList.vue.d.ts} +5 -5
  60. package/dist/runtime/app/components/cms/PoweredBy.vue +12 -5
  61. package/dist/runtime/app/components/cms/PresetModal.d.vue.ts +18 -0
  62. package/dist/runtime/app/components/cms/PresetModal.vue +70 -0
  63. package/dist/runtime/app/components/cms/PresetModal.vue.d.ts +18 -0
  64. package/dist/runtime/app/components/cms/RelationField.vue +2 -8
  65. package/dist/runtime/app/components/cms/SettingsAccount.vue +60 -71
  66. package/dist/runtime/app/components/cms/SettingsColumns.vue +47 -69
  67. package/dist/runtime/app/components/cms/SettingsEmptyAdd.d.vue.ts +13 -0
  68. package/dist/runtime/app/components/cms/SettingsEmptyAdd.vue +21 -0
  69. package/dist/runtime/app/components/cms/SettingsEmptyAdd.vue.d.ts +13 -0
  70. package/dist/runtime/app/components/cms/SettingsEntries.d.vue.ts +13 -0
  71. package/dist/runtime/app/components/cms/SettingsEntries.vue +50 -0
  72. package/dist/runtime/app/components/cms/SettingsEntries.vue.d.ts +13 -0
  73. package/dist/runtime/app/components/cms/SettingsEntry.d.vue.ts +1 -10
  74. package/dist/runtime/app/components/cms/SettingsEntry.vue +11 -95
  75. package/dist/runtime/app/components/cms/SettingsEntry.vue.d.ts +1 -10
  76. package/dist/runtime/app/components/cms/SettingsEntryActions.d.vue.ts +7 -0
  77. package/dist/runtime/app/components/cms/SettingsEntryActions.vue +42 -0
  78. package/dist/runtime/app/components/cms/SettingsEntryActions.vue.d.ts +7 -0
  79. package/dist/runtime/app/components/cms/SettingsEntryTabs.d.vue.ts +7 -0
  80. package/dist/runtime/app/components/cms/SettingsEntryTabs.vue +21 -0
  81. package/dist/runtime/app/components/cms/SettingsEntryTabs.vue.d.ts +7 -0
  82. package/dist/runtime/app/components/cms/SettingsFormAction.d.vue.ts +3 -0
  83. package/dist/runtime/app/components/cms/SettingsFormAction.vue +17 -0
  84. package/dist/runtime/app/components/cms/SettingsFormAction.vue.d.ts +3 -0
  85. package/dist/runtime/app/components/cms/SettingsLayout.vue +18 -14
  86. package/dist/runtime/app/components/cms/SettingsPresetForm.d.vue.ts +11 -0
  87. package/dist/runtime/app/components/cms/SettingsPresetForm.vue +60 -0
  88. package/dist/runtime/app/components/cms/SettingsPresetForm.vue.d.ts +11 -0
  89. package/dist/runtime/app/components/cms/SettingsPresets.d.vue.ts +13 -0
  90. package/dist/runtime/app/components/cms/SettingsPresets.vue +65 -0
  91. package/dist/runtime/app/components/cms/SettingsPresets.vue.d.ts +13 -0
  92. package/dist/runtime/app/components/cms/SettingsRecordActions.d.vue.ts +32 -0
  93. package/dist/runtime/app/components/cms/SettingsRecordActions.vue +45 -0
  94. package/dist/runtime/app/components/cms/SettingsRecordActions.vue.d.ts +32 -0
  95. package/dist/runtime/app/components/cms/SettingsRedirectActions.d.vue.ts +3 -0
  96. package/dist/runtime/app/components/cms/SettingsRedirectActions.vue +59 -0
  97. package/dist/runtime/app/components/cms/SettingsRedirectActions.vue.d.ts +3 -0
  98. package/dist/runtime/app/components/cms/SettingsRedirectForm.d.vue.ts +11 -0
  99. package/dist/runtime/app/components/cms/SettingsRedirectForm.vue +77 -0
  100. package/dist/runtime/app/components/cms/SettingsRedirectForm.vue.d.ts +11 -0
  101. package/dist/runtime/app/components/cms/SettingsRedirects.d.vue.ts +13 -0
  102. package/dist/runtime/app/components/cms/SettingsRedirects.vue +117 -0
  103. package/dist/runtime/app/components/cms/SettingsRedirects.vue.d.ts +13 -0
  104. package/dist/runtime/app/components/cms/SettingsSecretCard.d.vue.ts +17 -0
  105. package/dist/runtime/app/components/cms/SettingsSecretCard.vue +43 -0
  106. package/dist/runtime/app/components/cms/SettingsSecretCard.vue.d.ts +17 -0
  107. package/dist/runtime/app/components/cms/SettingsSite.d.vue.ts +3 -0
  108. package/dist/runtime/app/components/cms/SettingsSite.vue +140 -0
  109. package/dist/runtime/app/components/cms/SettingsSite.vue.d.ts +3 -0
  110. package/dist/runtime/app/components/cms/SettingsUserCreate.d.vue.ts +8 -0
  111. package/dist/runtime/app/components/cms/SettingsUserCreate.vue +82 -0
  112. package/dist/runtime/app/components/cms/SettingsUserCreate.vue.d.ts +8 -0
  113. package/dist/runtime/app/components/cms/SettingsUserDetail.d.vue.ts +11 -0
  114. package/dist/runtime/app/components/cms/SettingsUserDetail.vue +179 -0
  115. package/dist/runtime/app/components/cms/SettingsUserDetail.vue.d.ts +11 -0
  116. package/dist/runtime/app/components/cms/SettingsUsers.d.vue.ts +9 -6
  117. package/dist/runtime/app/components/cms/SettingsUsers.vue +88 -234
  118. package/dist/runtime/app/components/cms/SettingsUsers.vue.d.ts +9 -6
  119. package/dist/runtime/app/components/cms/SharePreview.d.vue.ts +18 -0
  120. package/dist/runtime/app/components/cms/SharePreview.vue +219 -0
  121. package/dist/runtime/app/components/cms/SharePreview.vue.d.ts +18 -0
  122. package/dist/runtime/app/components/cms/SlugField.vue +5 -3
  123. package/dist/runtime/app/components/cms/StatusBadge.vue +9 -8
  124. package/dist/runtime/app/components/cms/TranslationBadges.d.vue.ts +7 -0
  125. package/dist/runtime/app/components/cms/TranslationBadges.vue +45 -0
  126. package/dist/runtime/app/components/cms/TranslationBadges.vue.d.ts +7 -0
  127. package/dist/runtime/app/components/cms/TranslationMenu.d.vue.ts +17 -0
  128. package/dist/runtime/app/components/cms/TranslationMenu.vue +28 -0
  129. package/dist/runtime/app/components/cms/TranslationMenu.vue.d.ts +17 -0
  130. package/dist/runtime/app/components/cms/VisualEditor.d.vue.ts +22 -4
  131. package/dist/runtime/app/components/cms/VisualEditor.vue +1152 -335
  132. package/dist/runtime/app/components/cms/VisualEditor.vue.d.ts +22 -4
  133. package/dist/runtime/app/components/cms/WelcomeModal.vue +32 -50
  134. package/dist/runtime/app/composables/cms-clipboard.d.ts +8 -0
  135. package/dist/runtime/app/composables/cms-clipboard.js +38 -0
  136. package/dist/runtime/app/composables/cms-confirm.d.ts +6 -8
  137. package/dist/runtime/app/composables/cms-confirm.js +5 -7
  138. package/dist/runtime/app/composables/cms-entry-disabled.d.ts +5 -1
  139. package/dist/runtime/app/composables/cms-entry-disabled.js +7 -0
  140. package/dist/runtime/app/composables/cms-entry-form.d.ts +15 -0
  141. package/dist/runtime/app/composables/cms-entry-form.js +40 -0
  142. package/dist/runtime/app/composables/cms-entry-settings.d.ts +30 -0
  143. package/dist/runtime/app/composables/cms-entry-settings.js +122 -0
  144. package/dist/runtime/app/composables/cms-entry.d.ts +5 -1
  145. package/dist/runtime/app/composables/cms-entry.js +36 -11
  146. package/dist/runtime/app/composables/cms-history.d.ts +10 -0
  147. package/dist/runtime/app/composables/cms-history.js +24 -0
  148. package/dist/runtime/app/composables/cms-link-targets.d.ts +10 -0
  149. package/dist/runtime/app/composables/cms-link-targets.js +40 -0
  150. package/dist/runtime/app/composables/cms-link-usage.d.ts +1 -0
  151. package/dist/runtime/app/composables/cms-link-usage.js +45 -0
  152. package/dist/runtime/app/composables/cms-media-library.d.ts +19 -9
  153. package/dist/runtime/app/composables/cms-media-library.js +31 -13
  154. package/dist/runtime/app/composables/cms-media-uploader.js +6 -20
  155. package/dist/runtime/app/composables/cms-permissions.d.ts +18 -0
  156. package/dist/runtime/app/composables/cms-permissions.js +54 -0
  157. package/dist/runtime/app/composables/cms-presets.d.ts +11 -0
  158. package/dist/runtime/app/composables/cms-presets.js +40 -0
  159. package/dist/runtime/app/composables/cms-preview-mode.d.ts +4 -0
  160. package/dist/runtime/app/composables/cms-preview-mode.js +8 -0
  161. package/dist/runtime/app/composables/cms-query.d.ts +3 -0
  162. package/dist/runtime/app/composables/cms-query.js +45 -20
  163. package/dist/runtime/app/composables/cms-record-list.d.ts +31 -0
  164. package/dist/runtime/app/composables/cms-record-list.js +75 -0
  165. package/dist/runtime/app/composables/cms-route.d.ts +6 -0
  166. package/dist/runtime/app/composables/cms-route.js +36 -0
  167. package/dist/runtime/app/composables/cms-runtime.d.ts +1 -0
  168. package/dist/runtime/app/composables/cms-save-handoff.d.ts +4 -0
  169. package/dist/runtime/app/composables/cms-save-handoff.js +19 -0
  170. package/dist/runtime/app/composables/cms-seo.d.ts +12 -0
  171. package/dist/runtime/app/composables/cms-seo.js +69 -0
  172. package/dist/runtime/app/composables/cms-settings-form.d.ts +13 -0
  173. package/dist/runtime/app/composables/cms-settings-form.js +29 -0
  174. package/dist/runtime/app/composables/cms-settings-sections.d.ts +26 -0
  175. package/dist/runtime/app/composables/cms-settings-sections.js +181 -0
  176. package/dist/runtime/app/composables/cms-settings-stores.d.ts +52 -0
  177. package/dist/runtime/app/composables/cms-settings-stores.js +156 -0
  178. package/dist/runtime/app/composables/cms-settings.d.ts +3 -3
  179. package/dist/runtime/app/composables/cms-settings.js +14 -8
  180. package/dist/runtime/app/composables/cms-site-disabled.d.ts +7 -0
  181. package/dist/runtime/app/composables/cms-site-disabled.js +8 -0
  182. package/dist/runtime/app/composables/cms-site.d.ts +7 -0
  183. package/dist/runtime/app/composables/cms-site.js +22 -0
  184. package/dist/runtime/app/composables/cms-toast.d.ts +2 -8
  185. package/dist/runtime/app/composables/cms-toast.js +3 -9
  186. package/dist/runtime/app/composables/cms-translation-actions.d.ts +15 -0
  187. package/dist/runtime/app/composables/cms-translation-actions.js +108 -0
  188. package/dist/runtime/app/css-url.d.ts +4 -0
  189. package/dist/runtime/app/image/CmsImage.d.vue.ts +89 -0
  190. package/dist/runtime/app/image/CmsImage.vue +91 -0
  191. package/dist/runtime/app/image/CmsImage.vue.d.ts +89 -0
  192. package/dist/runtime/app/layouts/cms-admin.d.vue.ts +2 -2
  193. package/dist/runtime/app/layouts/cms-admin.vue +98 -76
  194. package/dist/runtime/app/layouts/cms-admin.vue.d.ts +2 -2
  195. package/dist/runtime/app/layouts/cms-editor.vue +7 -2
  196. package/dist/runtime/app/links/CmsLink.d.vue.ts +18 -0
  197. package/dist/runtime/app/links/CmsLink.vue +18 -0
  198. package/dist/runtime/app/links/CmsLink.vue.d.ts +18 -0
  199. package/dist/runtime/app/middleware/cms-auth.js +13 -1
  200. package/dist/runtime/app/pages/admin-collection.vue +473 -297
  201. package/dist/runtime/app/pages/admin-content.vue +190 -53
  202. package/dist/runtime/app/pages/admin-entry.vue +79 -75
  203. package/dist/runtime/app/pages/admin-index.vue +18 -5
  204. package/dist/runtime/app/pages/admin-login.vue +1 -1
  205. package/dist/runtime/app/pages/admin-logout.vue +1 -1
  206. package/dist/runtime/app/pages/admin-media.vue +3 -3
  207. package/dist/runtime/app/pages/admin-preview.vue +112 -24
  208. package/dist/runtime/app/plugins/cms-field.d.ts +2 -0
  209. package/dist/runtime/app/plugins/cms-field.js +8 -0
  210. package/dist/runtime/app/plugins/cms-preview-banner.client.d.ts +2 -0
  211. package/dist/runtime/app/plugins/cms-preview-banner.client.js +19 -0
  212. package/dist/runtime/app/plugins/cms-preview.d.ts +2 -0
  213. package/dist/runtime/app/plugins/cms-preview.js +27 -0
  214. package/dist/runtime/app/preview/CmsPreviewBanner.d.vue.ts +7 -0
  215. package/dist/runtime/app/preview/CmsPreviewBanner.vue +63 -0
  216. package/dist/runtime/app/preview/CmsPreviewBanner.vue.d.ts +7 -0
  217. package/dist/runtime/app/preview/PreviewOverlay.d.vue.ts +17 -3
  218. package/dist/runtime/app/preview/PreviewOverlay.vue +629 -166
  219. package/dist/runtime/app/preview/PreviewOverlay.vue.d.ts +17 -3
  220. package/dist/runtime/app/preview/field-marker.d.ts +12 -0
  221. package/dist/runtime/app/preview/field-marker.js +20 -0
  222. package/dist/runtime/app/preview/inline-text.d.ts +15 -0
  223. package/dist/runtime/app/preview/inline-text.js +158 -0
  224. package/dist/runtime/app/utils/block-editor.d.ts +22 -0
  225. package/dist/runtime/app/utils/block-editor.js +12 -0
  226. package/dist/runtime/app/utils/keyboard.d.ts +6 -0
  227. package/dist/runtime/app/utils/keyboard.js +52 -0
  228. package/dist/runtime/app/utils/redirects.d.ts +6 -0
  229. package/dist/runtime/app/utils/redirects.js +7 -0
  230. package/dist/runtime/app/utils/ui.d.ts +8 -0
  231. package/dist/runtime/app/utils/ui.js +15 -1
  232. package/dist/runtime/app/utils/users.d.ts +15 -0
  233. package/dist/runtime/app/utils/users.js +14 -0
  234. package/dist/runtime/assets/cms.css +1 -1
  235. package/dist/runtime/generate.js +16 -2
  236. package/dist/runtime/server/api/collection-export.get.js +3 -2
  237. package/dist/runtime/server/api/collection-import.post.js +39 -11
  238. package/dist/runtime/server/api/collection.get.js +27 -9
  239. package/dist/runtime/server/api/collection.post.js +28 -11
  240. package/dist/runtime/server/api/collection.put.js +35 -13
  241. package/dist/runtime/server/api/item.delete.js +19 -7
  242. package/dist/runtime/server/api/item.get.js +3 -2
  243. package/dist/runtime/server/api/item.put.js +52 -18
  244. package/dist/runtime/server/api/link-usage.post.d.ts +5 -0
  245. package/dist/runtime/server/api/link-usage.post.js +21 -0
  246. package/dist/runtime/server/api/media-delete.post.js +4 -2
  247. package/dist/runtime/server/api/media-download.get.js +2 -2
  248. package/dist/runtime/server/api/media-folder.delete.js +8 -2
  249. package/dist/runtime/server/api/media-folder.patch.js +10 -2
  250. package/dist/runtime/server/api/media-folder.post.js +4 -2
  251. package/dist/runtime/server/api/media-move.post.js +7 -4
  252. package/dist/runtime/server/api/media-presign.post.js +2 -2
  253. package/dist/runtime/server/api/media-upload.put.js +2 -2
  254. package/dist/runtime/server/api/media-usage.post.d.ts +2 -4
  255. package/dist/runtime/server/api/media-usage.post.js +13 -9
  256. package/dist/runtime/server/api/media.delete.js +4 -2
  257. package/dist/runtime/server/api/media.get.js +22 -7
  258. package/dist/runtime/server/api/media.post.js +4 -2
  259. package/dist/runtime/server/api/media.put.js +33 -16
  260. package/dist/runtime/server/api/preset.delete.d.ts +4 -0
  261. package/dist/runtime/server/api/preset.delete.js +9 -0
  262. package/dist/runtime/server/api/preset.put.d.ts +3 -0
  263. package/dist/runtime/server/api/preset.put.js +23 -0
  264. package/dist/runtime/server/api/presets-field.get.d.ts +3 -0
  265. package/dist/runtime/server/api/presets-field.get.js +13 -0
  266. package/dist/runtime/server/api/presets-field.post.d.ts +3 -0
  267. package/dist/runtime/server/api/presets-field.post.js +36 -0
  268. package/dist/runtime/server/api/presets.get.d.ts +3 -0
  269. package/dist/runtime/server/api/presets.get.js +7 -0
  270. package/dist/runtime/server/api/preview-link.delete.d.ts +4 -0
  271. package/dist/runtime/server/api/preview-link.delete.js +15 -0
  272. package/dist/runtime/server/api/preview-links.get.d.ts +3 -0
  273. package/dist/runtime/server/api/preview-links.get.js +10 -0
  274. package/dist/runtime/server/api/preview-links.post.d.ts +3 -0
  275. package/dist/runtime/server/api/preview-links.post.js +17 -0
  276. package/dist/runtime/server/api/preview.get.d.ts +3 -0
  277. package/dist/runtime/server/api/preview.get.js +7 -0
  278. package/dist/runtime/server/api/redirect.delete.d.ts +4 -0
  279. package/dist/runtime/server/api/redirect.delete.js +10 -0
  280. package/dist/runtime/server/api/redirect.put.d.ts +3 -0
  281. package/dist/runtime/server/api/redirect.put.js +8 -0
  282. package/dist/runtime/server/api/redirects-import.post.d.ts +3 -0
  283. package/dist/runtime/server/api/redirects-import.post.js +13 -0
  284. package/dist/runtime/server/api/redirects.get.d.ts +3 -0
  285. package/dist/runtime/server/api/redirects.get.js +7 -0
  286. package/dist/runtime/server/api/redirects.post.d.ts +3 -0
  287. package/dist/runtime/server/api/redirects.post.js +7 -0
  288. package/dist/runtime/server/api/search.get.js +8 -3
  289. package/dist/runtime/server/api/settings.delete.js +2 -2
  290. package/dist/runtime/server/api/settings.get.js +4 -2
  291. package/dist/runtime/server/api/settings.put.js +2 -2
  292. package/dist/runtime/server/api/site.get.d.ts +3 -0
  293. package/dist/runtime/server/api/site.get.js +7 -0
  294. package/dist/runtime/server/api/site.put.d.ts +3 -0
  295. package/dist/runtime/server/api/site.put.js +16 -0
  296. package/dist/runtime/server/api/tags.get.js +3 -2
  297. package/dist/runtime/server/api/user.delete.js +8 -2
  298. package/dist/runtime/server/api/user.put.js +14 -4
  299. package/dist/runtime/server/api/users.get.js +2 -2
  300. package/dist/runtime/server/api/users.post.js +8 -4
  301. package/dist/runtime/server/middleware/hidden-site.d.ts +2 -0
  302. package/dist/runtime/server/middleware/hidden-site.js +8 -0
  303. package/dist/runtime/server/middleware/preview-links.d.ts +2 -0
  304. package/dist/runtime/server/middleware/preview-links.js +6 -0
  305. package/dist/runtime/server/middleware/redirects.d.ts +2 -0
  306. package/dist/runtime/server/middleware/redirects.js +18 -0
  307. package/dist/runtime/server/plugins/session-validate.js +4 -1
  308. package/dist/runtime/server/plugins/webhooks.d.ts +3 -0
  309. package/dist/runtime/server/plugins/webhooks.js +27 -0
  310. package/dist/runtime/server/routes/graphql.js +5 -3
  311. package/dist/runtime/server/routes/robots.d.ts +2 -0
  312. package/dist/runtime/server/routes/robots.js +16 -0
  313. package/dist/runtime/server/routes/sitemap.d.ts +2 -0
  314. package/dist/runtime/server/routes/sitemap.js +67 -0
  315. package/dist/runtime/server/utils/cached-value.d.ts +5 -0
  316. package/dist/runtime/server/utils/cached-value.js +24 -0
  317. package/dist/runtime/server/utils/content-routes.d.ts +5 -0
  318. package/dist/runtime/server/utils/content-routes.js +29 -0
  319. package/dist/runtime/server/utils/field-rules.d.ts +19 -0
  320. package/dist/runtime/server/utils/field-rules.js +72 -0
  321. package/dist/runtime/server/utils/graphql.d.ts +3 -1
  322. package/dist/runtime/server/utils/graphql.js +143 -28
  323. package/dist/runtime/server/utils/hooks.d.ts +14 -0
  324. package/dist/runtime/server/utils/hooks.js +71 -0
  325. package/dist/runtime/server/utils/import.d.ts +7 -2
  326. package/dist/runtime/server/utils/import.js +108 -14
  327. package/dist/runtime/server/utils/link-usage.d.ts +4 -0
  328. package/dist/runtime/server/utils/link-usage.js +28 -0
  329. package/dist/runtime/server/utils/media-references.d.ts +6 -1
  330. package/dist/runtime/server/utils/media-references.js +49 -20
  331. package/dist/runtime/server/utils/media-usage.d.ts +2 -0
  332. package/dist/runtime/server/utils/media-usage.js +5 -3
  333. package/dist/runtime/server/utils/page-rows.d.ts +2 -0
  334. package/dist/runtime/server/utils/page-rows.js +42 -29
  335. package/dist/runtime/server/utils/permissions.d.ts +14 -0
  336. package/dist/runtime/server/utils/permissions.js +43 -0
  337. package/dist/runtime/server/utils/presets.d.ts +18 -0
  338. package/dist/runtime/server/utils/presets.js +68 -0
  339. package/dist/runtime/server/utils/preview-links.d.ts +207 -0
  340. package/dist/runtime/server/utils/preview-links.js +161 -0
  341. package/dist/runtime/server/utils/redirects.d.ts +31 -0
  342. package/dist/runtime/server/utils/redirects.js +240 -0
  343. package/dist/runtime/server/utils/registry.js +4 -1
  344. package/dist/runtime/server/utils/relations.d.ts +8 -0
  345. package/dist/runtime/server/utils/relations.js +25 -6
  346. package/dist/runtime/server/utils/require-admin.d.ts +0 -1
  347. package/dist/runtime/server/utils/require-admin.js +4 -8
  348. package/dist/runtime/server/utils/search.d.ts +1 -0
  349. package/dist/runtime/server/utils/search.js +44 -19
  350. package/dist/runtime/server/utils/site.d.ts +23 -0
  351. package/dist/runtime/server/utils/site.js +79 -0
  352. package/dist/runtime/server/utils/sitemap.d.ts +12 -0
  353. package/dist/runtime/server/utils/sitemap.js +109 -0
  354. package/dist/runtime/server/utils/user-management.d.ts +4 -0
  355. package/dist/runtime/server/utils/user-management.js +20 -0
  356. package/dist/runtime/server/utils/users.d.ts +1 -1
  357. package/dist/runtime/server/utils/users.js +1 -1
  358. package/dist/runtime/server/utils/visibility.d.ts +1 -0
  359. package/dist/runtime/server/utils/visibility.js +6 -1
  360. package/dist/runtime/server/utils/webhooks.d.ts +24 -0
  361. package/dist/runtime/server/utils/webhooks.js +90 -0
  362. package/dist/runtime/shared/block-paths.d.ts +66 -0
  363. package/dist/runtime/shared/block-paths.js +310 -0
  364. package/dist/runtime/shared/block-picker.d.ts +18 -0
  365. package/dist/runtime/shared/block-picker.js +31 -0
  366. package/dist/runtime/shared/block-signature.d.ts +4 -0
  367. package/dist/runtime/shared/block-signature.js +46 -0
  368. package/dist/runtime/shared/clipboard.d.ts +31 -0
  369. package/dist/runtime/shared/clipboard.js +206 -0
  370. package/dist/runtime/shared/conditions.d.ts +36 -0
  371. package/dist/runtime/shared/conditions.js +100 -0
  372. package/dist/runtime/shared/content-routes.d.ts +42 -0
  373. package/dist/runtime/shared/content-routes.js +237 -0
  374. package/dist/runtime/shared/duplicate.js +2 -1
  375. package/dist/runtime/shared/editor-layout.d.ts +18 -0
  376. package/dist/runtime/shared/editor-layout.js +9 -0
  377. package/dist/runtime/shared/field-options.d.ts +21 -0
  378. package/dist/runtime/shared/field-options.js +90 -0
  379. package/dist/runtime/shared/graphql-sdl.d.ts +1 -0
  380. package/dist/runtime/shared/graphql-sdl.js +50 -26
  381. package/dist/runtime/shared/history.d.ts +27 -0
  382. package/dist/runtime/shared/history.js +123 -0
  383. package/dist/runtime/shared/hooks.d.ts +45 -0
  384. package/dist/runtime/shared/hooks.js +28 -0
  385. package/dist/runtime/shared/index.d.ts +90 -21
  386. package/dist/runtime/shared/index.js +121 -37
  387. package/dist/runtime/shared/inline-text.d.ts +38 -0
  388. package/dist/runtime/shared/inline-text.js +85 -0
  389. package/dist/runtime/shared/layout.d.ts +2 -1
  390. package/dist/runtime/shared/layout.js +3 -0
  391. package/dist/runtime/shared/links.d.ts +48 -0
  392. package/dist/runtime/shared/links.js +155 -0
  393. package/dist/runtime/shared/list-filters.d.ts +2 -0
  394. package/dist/runtime/shared/list-filters.js +2 -0
  395. package/dist/runtime/shared/media-focal.d.ts +30 -0
  396. package/dist/runtime/shared/media-focal.js +52 -0
  397. package/dist/runtime/shared/migrations-dir.d.ts +14 -0
  398. package/dist/runtime/shared/migrations-dir.js +48 -2
  399. package/dist/runtime/shared/presets.d.ts +67 -0
  400. package/dist/runtime/shared/presets.js +127 -0
  401. package/dist/runtime/shared/preview-links.d.ts +64 -0
  402. package/dist/runtime/shared/preview-links.js +54 -0
  403. package/dist/runtime/shared/preview.d.ts +124 -21
  404. package/dist/runtime/shared/preview.js +419 -81
  405. package/dist/runtime/shared/redirects.d.ts +75 -0
  406. package/dist/runtime/shared/redirects.js +230 -0
  407. package/dist/runtime/shared/roles.d.ts +57 -0
  408. package/dist/runtime/shared/roles.js +293 -0
  409. package/dist/runtime/shared/save-state.d.ts +8 -0
  410. package/dist/runtime/shared/save-state.js +15 -0
  411. package/dist/runtime/shared/search.d.ts +16 -1
  412. package/dist/runtime/shared/search.js +41 -7
  413. package/dist/runtime/shared/seo.d.ts +167 -0
  414. package/dist/runtime/shared/seo.js +335 -0
  415. package/dist/runtime/shared/transfer.js +2 -1
  416. package/dist/runtime/shared/translations.d.ts +29 -0
  417. package/dist/runtime/shared/translations.js +123 -0
  418. package/dist/runtime/shared/users.d.ts +1 -1
  419. package/dist/runtime/shared/validation.d.ts +23 -1
  420. package/dist/runtime/shared/validation.js +214 -64
  421. package/dist/runtime/webhooks.d.ts +33 -0
  422. package/dist/runtime/webhooks.js +57 -0
  423. package/dist/types.d.mts +5 -1
  424. package/package.json +6 -2
  425. package/dist/runtime/app/components/cms/BlockOutline.vue +0 -88
  426. package/dist/runtime/app/components/cms/BlockPalette.vue +0 -31
  427. package/dist/runtime/app/components/cms/SettingsModal.d.vue.ts +0 -12
  428. package/dist/runtime/app/components/cms/SettingsModal.vue +0 -126
  429. package/dist/runtime/app/components/cms/SettingsModal.vue.d.ts +0 -12
  430. package/dist/runtime/app/composables/cms-field-focus.d.ts +0 -4
  431. package/dist/runtime/app/composables/cms-field-focus.js +0 -20
@@ -4,29 +4,23 @@
4
4
  :subtitle="subtitle"
5
5
  :size="size"
6
6
  :logo="logo"
7
+ :icon="CMS_BRAND_ICON"
7
8
  :hide-text="hideText"
8
9
  show-name
9
- >
10
- <template #mark>
11
- <svg class="cms-brand-glyph" viewBox="0 0 16 16" fill="none">
12
- <path
13
- d="M4.5 5.5h7M4.5 8h7M4.5 10.5h4"
14
- stroke="currentColor"
15
- stroke-width="1.5"
16
- stroke-linecap="round"
17
- />
18
- </svg>
19
- </template>
20
- </KBrand>
10
+ />
21
11
  </template>
22
12
 
23
13
  <script setup>
24
- import { Brand as KBrand } from "@xleddyl/443-components-vue";
14
+ import { Brand as KBrand, provideIcons } from "@xleddyl/443-components-vue";
25
15
  import { cmsBrand } from "#cms-brand";
26
16
  defineProps({
27
17
  size: { type: String, required: false, default: "md" },
28
18
  subtitle: { type: String, required: false },
29
19
  hideText: { type: Boolean, required: false }
30
20
  });
21
+ const CMS_BRAND_ICON = "cms-brand";
22
+ provideIcons({
23
+ [CMS_BRAND_ICON]: '<svg viewBox="0 0 16 16" fill="none"><path d="M4.5 5.5h7M4.5 8h7M4.5 10.5h4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>'
24
+ });
31
25
  const logo = cmsBrand.logo.kind === "svg" ? cmsBrand.logo.markup : cmsBrand.logo.kind === "image" ? cmsBrand.logo.src : void 0;
32
26
  </script>
@@ -1,20 +1,22 @@
1
1
  <template>
2
- <div class="cms-confirm-groups">
3
- <section v-for="group in groups" :key="group.title" class="cms-confirm-group">
4
- <h3 class="cms-confirm-group-title" :title="group.title">{{ group.title }}</h3>
5
- <ul class="cms-confirm-list">
6
- <li v-for="link in group.links" :key="link.to + link.meta">
7
- <NuxtLink :to="link.to" class="cms-confirm-link" @click="emit('close')">
8
- <span class="cms-confirm-link-title">{{ link.title }}</span>
9
- <span class="cms-confirm-link-meta">{{ link.meta }}</span>
10
- </NuxtLink>
11
- </li>
12
- </ul>
13
- </section>
14
- </div>
2
+ <KStack gap="md">
3
+ <KStack v-for="group in groups" :key="group.title" as="section" gap="xs">
4
+ <KTooltip :text="group.title">
5
+ <h3 class="cms-confirm-group-title k-mono">{{ group.title }}</h3>
6
+ </KTooltip>
7
+ <KRecordList :items="group.items" :label="group.title" @row-click="emit('close')" />
8
+ <KFieldMessage v-if="group.note" tone="neutral" :icon="false" :message="group.note" />
9
+ </KStack>
10
+ </KStack>
15
11
  </template>
16
12
 
17
13
  <script setup>
14
+ import {
15
+ FieldMessage as KFieldMessage,
16
+ RecordList as KRecordList,
17
+ Stack as KStack,
18
+ Tooltip as KTooltip
19
+ } from "@xleddyl/443-components-vue";
18
20
  defineProps({
19
21
  groups: { type: Array, required: true }
20
22
  });
@@ -1,12 +1,13 @@
1
- import type { BlockConfig } from '#nuxt-cms';
2
1
  type __VLS_Props = {
3
- blocks: Record<string, BlockConfig>;
4
- label?: string;
2
+ canUndo: boolean;
3
+ canRedo: boolean;
5
4
  };
6
5
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
7
- pick: (type: string) => any;
6
+ undo: () => any;
7
+ redo: () => any;
8
8
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
9
- onPick?: ((type: string) => any) | undefined;
9
+ onUndo?: (() => any) | undefined;
10
+ onRedo?: (() => any) | undefined;
10
11
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
11
12
  declare const _default: typeof __VLS_export;
12
13
  export default _default;
@@ -0,0 +1,34 @@
1
+ <template>
2
+ <KTooltip text="Undo" shortcut="mod+z">
3
+ <KButton
4
+ :icon="cmsIcon('arrow-uturn-left')"
5
+ size="sm"
6
+ variant="ghost"
7
+ tone="neutral"
8
+ aria-label="Undo"
9
+ :disabled="!canUndo"
10
+ @click="emit('undo')"
11
+ />
12
+ </KTooltip>
13
+ <KTooltip text="Redo" shortcut="mod+shift+z">
14
+ <KButton
15
+ :icon="cmsIcon('arrow-uturn-right')"
16
+ size="sm"
17
+ variant="ghost"
18
+ tone="neutral"
19
+ aria-label="Redo"
20
+ :disabled="!canRedo"
21
+ @click="emit('redo')"
22
+ />
23
+ </KTooltip>
24
+ </template>
25
+
26
+ <script setup>
27
+ import { Button as KButton, Tooltip as KTooltip } from "@xleddyl/443-components-vue";
28
+ import { cmsIcon } from "../../utils/ui";
29
+ defineProps({
30
+ canUndo: { type: Boolean, required: true },
31
+ canRedo: { type: Boolean, required: true }
32
+ });
33
+ const emit = defineEmits(["undo", "redo"]);
34
+ </script>
@@ -1,12 +1,13 @@
1
- import type { BlockConfig } from '#nuxt-cms';
2
1
  type __VLS_Props = {
3
- blocks: Record<string, BlockConfig>;
4
- label?: string;
2
+ canUndo: boolean;
3
+ canRedo: boolean;
5
4
  };
6
5
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
7
- pick: (type: string) => any;
6
+ undo: () => any;
7
+ redo: () => any;
8
8
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
9
- onPick?: ((type: string) => any) | undefined;
9
+ onUndo?: (() => any) | undefined;
10
+ onRedo?: (() => any) | undefined;
10
11
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
11
12
  declare const _default: typeof __VLS_export;
12
13
  export default _default;
@@ -1,24 +1,30 @@
1
1
  import type { CmsEntry } from '#nuxt-cms';
2
+ import type { CmsSearchFocus } from '../../../shared/search.js';
2
3
  type __VLS_Props = {
3
4
  collection: string;
4
5
  config: CmsEntry;
5
6
  entryId: string | null;
6
- initial?: Record<string, unknown> | null;
7
+ duplicateId?: string | null;
8
+ focus?: CmsSearchFocus | null;
7
9
  };
8
10
  type __VLS_ModelProps = {
9
11
  'open'?: boolean;
10
12
  };
11
13
  type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
12
14
  declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
15
+ duplicate: (id: string) => any;
16
+ created: (id: string) => any;
17
+ missing: () => any;
18
+ saved: (id: string) => any;
13
19
  "update:open": (value: boolean) => any;
14
- saved: () => any;
15
20
  deleted: () => any;
16
- duplicate: (values: Record<string, unknown>) => any;
17
21
  }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
22
+ onDuplicate?: ((id: string) => any) | undefined;
23
+ onCreated?: ((id: string) => any) | undefined;
24
+ onMissing?: (() => any) | undefined;
25
+ onSaved?: ((id: string) => any) | undefined;
18
26
  "onUpdate:open"?: ((value: boolean) => any) | undefined;
19
- onSaved?: (() => any) | undefined;
20
27
  onDeleted?: (() => any) | undefined;
21
- onDuplicate?: ((values: Record<string, unknown>) => any) | undefined;
22
28
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
23
29
  declare const _default: typeof __VLS_export;
24
30
  export default _default;
@@ -1,115 +1,138 @@
1
1
  <template>
2
- <KDrawer v-model:open="open" :title="title" size="lg" :before-close="confirmClose">
2
+ <KFormDrawer
3
+ v-model:open="open"
4
+ size="lg"
5
+ :title="title"
6
+ :tabs="drawerTabs"
7
+ :tab-route="CMS_ENTRY_TAB_ROUTE_KEY"
8
+ :form="form"
9
+ :loading="loading"
10
+ :creating="isNew"
11
+ :readonly="!!lock"
12
+ :deletable="!isNew && canDelete"
13
+ @delete="remove"
14
+ >
3
15
  <template v-if="drafts && !loading" #title-trailing>
4
- <KBadge
5
- dot
6
- :tone="published ? 'success' : 'neutral'"
7
- :variant="published ? 'soft' : 'outline'"
8
- :label="published ? 'Published' : 'Draft'"
9
- />
16
+ <CmsStatusBadge :published="savedStatus === 'published'" />
10
17
  </template>
11
18
 
12
- <KStack v-if="loading" align="center" justify="center" class="cms-drawer-loading">
13
- <KSpinner size="lg" label="Loading" />
14
- </KStack>
15
-
16
- <CmsEntryForm
17
- v-else
18
- v-model="formState"
19
- :fields="config.fields"
20
- :tabs="config.tabs"
21
- :entry-name="collection"
22
- :drafts="drafts"
23
- :form-id="FORM_ID"
24
- :loading="saving"
25
- :footer="false"
26
- @submit="save"
27
- @error="revertStatus"
28
- />
19
+ <template v-if="!loading" #actions>
20
+ <CmsTranslationMenu
21
+ v-model="formState"
22
+ :fields="config.fields"
23
+ :disabled="!!lock"
24
+ size="sm"
25
+ />
26
+ <KButton
27
+ v-if="!isNew && canCreate"
28
+ variant="soft"
29
+ tone="neutral"
30
+ size="sm"
31
+ :icon="cmsIcon('document-duplicate')"
32
+ :disabled="form.dirty.value"
33
+ disabled-reason="Save the changes first"
34
+ @click="emit('duplicate', String(entryId))"
35
+ >
36
+ Duplicate
37
+ </KButton>
38
+ <KButton
39
+ v-if="drafts && !lock && canPublish"
40
+ variant="soft"
41
+ tone="neutral"
42
+ size="sm"
43
+ :icon="cmsIcon(published ? 'pencil-square' : 'check-circle')"
44
+ :loading="form.submitting.value"
45
+ @click="togglePublished"
46
+ >
47
+ {{ published ? "Make draft" : "Publish" }}
48
+ </KButton>
49
+ </template>
29
50
 
30
- <template #footer>
31
- <KStack direction="row" justify="between" gap="sm" wrap class="cms-drawer-actions">
32
- <KStack v-if="!isNew" direction="row" gap="sm">
33
- <KButton
34
- label="Delete"
35
- icon="trash"
36
- variant="ghost"
37
- tone="danger"
38
- :disabled="saving || loading"
39
- @click="remove"
40
- />
41
- <KButton
42
- label="Duplicate"
43
- :icon="cmsIcon('document-duplicate')"
44
- variant="ghost"
45
- tone="neutral"
46
- :disabled="saving || loading"
47
- @click="duplicate"
48
- />
49
- </KStack>
50
- <span v-else />
51
- <KStack direction="row" gap="sm">
52
- <KButton
53
- v-if="drafts"
54
- type="submit"
55
- :form="FORM_ID"
56
- :label="published ? 'Make draft' : 'Publish'"
57
- variant="soft"
58
- :loading="saving"
59
- :disabled="loading"
60
- @click="togglePublished"
61
- />
62
- <KButton
63
- type="submit"
64
- :form="FORM_ID"
65
- label="Save"
66
- :loading="saving"
67
- :disabled="loading"
68
- />
69
- </KStack>
70
- </KStack>
51
+ <template #default="{ tab }">
52
+ <CmsEntryForm
53
+ ref="formRef"
54
+ v-model="formState"
55
+ :form="form"
56
+ :tab="tab === void 0 ? void 0 : String(tab)"
57
+ :fields="config.fields"
58
+ :tabs="config.tabs"
59
+ :entry-name="collection"
60
+ :lock="lock"
61
+ :locked="locked"
62
+ :focus="focus"
63
+ @update:tab="selectTab"
64
+ />
71
65
  </template>
72
- </KDrawer>
66
+ </KFormDrawer>
73
67
  </template>
74
68
 
75
69
  <script setup>
76
- import { isTranslatableField, selectDisplayValue } from "#nuxt-cms";
70
+ import { fieldTab, isTranslatableField, selectDisplayValue } from "#nuxt-cms";
77
71
  import {
78
- Badge as KBadge,
79
72
  Button as KButton,
80
- Drawer as KDrawer,
81
- Spinner as KSpinner,
82
- Stack as KStack
73
+ FormDrawer as KFormDrawer,
74
+ toast,
75
+ useConfirm,
76
+ useRouteState
83
77
  } from "@xleddyl/443-components-vue";
84
- import { computed, ref, watch } from "#imports";
78
+ import { computed, nextTick, ref, watch } from "#imports";
85
79
  import { duplicateEntryValues } from "../../../shared/duplicate";
86
- import { useCmsConfirm } from "../../composables/cms-confirm";
80
+ import { entryDefaults, lockedFieldKeys } from "../../../shared/field-options";
81
+ import { cloneState, mergeSavedState } from "../../../shared/save-state";
82
+ import { CMS_ENTRY_TAB_ROUTE_KEY } from "../../../shared/search";
83
+ import { useCmsEntryForm } from "../../composables/cms-entry-form";
84
+ import { useCmsPermissions } from "../../composables/cms-permissions";
87
85
  import { useCmsRuntime } from "../../composables/cms-runtime";
88
- import { useCmsToast } from "../../composables/cms-toast";
89
86
  import { cmsApi } from "../../utils/api";
90
87
  import { cmsIcon, errorMessage } from "../../utils/ui";
91
- const FORM_ID = "cms-entry-drawer-form";
92
88
  const props = defineProps({
93
89
  collection: { type: String, required: true },
94
90
  config: { type: Object, required: true },
95
91
  entryId: { type: [String, null], required: true },
96
- initial: { type: [Object, null], required: false }
92
+ duplicateId: { type: [String, null], required: false, default: null },
93
+ focus: { type: [Object, null], required: false, default: null }
97
94
  });
98
95
  const open = defineModel("open", { type: Boolean, ...{ default: false } });
99
- const emit = defineEmits(["saved", "deleted", "duplicate"]);
100
- const toast = useCmsToast();
101
- const confirmAction = useCmsConfirm();
96
+ const emit = defineEmits(["saved", "created", "deleted", "duplicate", "missing"]);
97
+ const confirm = useConfirm();
98
+ const routeTab = useRouteState(CMS_ENTRY_TAB_ROUTE_KEY, { location: "hash", history: "replace" });
102
99
  const endpoint = computed(() => `/api/cms/admin/${props.collection}`);
103
100
  const isNew = computed(() => props.entryId === null);
104
101
  const drafts = computed(() => !!props.config.drafts);
105
102
  const formKeys = computed(
106
103
  () => drafts.value ? [...Object.keys(props.config.fields), "status"] : Object.keys(props.config.fields)
107
104
  );
108
- const { i18n: contentI18n } = useCmsRuntime();
105
+ const { i18n } = useCmsRuntime();
109
106
  const loading = ref(false);
110
- const saving = ref(false);
111
107
  const formState = ref({});
112
- const snapshot = ref("");
108
+ const savedState = ref({});
109
+ const loadedId = ref(null);
110
+ const formRef = ref(null);
111
+ const savedStatus = computed(() => savedState.value.status);
112
+ function emptyState() {
113
+ return Object.fromEntries(formKeys.value.map((key) => [key, null]));
114
+ }
115
+ function newState() {
116
+ return { ...emptyState(), ...entryDefaults(props.config.fields, i18n, { local: true }) };
117
+ }
118
+ function pickFields(row) {
119
+ return Object.fromEntries(formKeys.value.map((key) => [key, row[key] ?? null]));
120
+ }
121
+ const { can, entryLock } = useCmsPermissions();
122
+ const canPublish = computed(() => can(`${props.collection}.publish`));
123
+ const canCreate = computed(() => can(`${props.collection}.create`));
124
+ const canDelete = computed(
125
+ () => can(`${props.collection}.delete`) && (!drafts.value || canPublish.value || savedStatus.value !== "published")
126
+ );
127
+ const lock = computed(
128
+ () => loading.value ? null : entryLock(props.collection, props.config, {
129
+ isNew: isNew.value,
130
+ status: savedStatus.value
131
+ })
132
+ );
133
+ const locked = computed(
134
+ () => isNew.value ? [] : lockedFieldKeys(props.config.fields, savedState.value)
135
+ );
113
136
  const entryName = computed(() => {
114
137
  const key = props.config.titleField;
115
138
  const field = key ? props.config.fields[key] : void 0;
@@ -117,121 +140,129 @@ const entryName = computed(() => {
117
140
  if (!field || value == null || value === "") return "";
118
141
  if (isTranslatableField(field)) {
119
142
  const record = value;
120
- return record[contentI18n.defaultLocale] ?? Object.values(record)[0] ?? "";
143
+ return record[i18n.defaultLocale] ?? Object.values(record)[0] ?? "";
121
144
  }
122
145
  if (field.type === "select") return selectDisplayValue(field, value);
123
146
  return String(value);
124
147
  });
125
148
  const title = computed(() => {
126
- if (isNew.value) return props.initial ? "Duplicate entry" : "Add entry";
149
+ if (isNew.value) return props.duplicateId ? "Duplicate entry" : "Add entry";
127
150
  return entryName.value || "Untitled";
128
151
  });
129
- function emptyState() {
130
- return Object.fromEntries(formKeys.value.map((key) => [key, null]));
131
- }
132
- function pickFields(row) {
133
- return Object.fromEntries(formKeys.value.map((key) => [key, row[key] ?? null]));
152
+ const drawerTabs = computed(() => {
153
+ const tabs = props.config.tabs ?? [];
154
+ if (tabs.length < 2) return void 0;
155
+ return tabs.map((tab) => ({
156
+ value: tab.id,
157
+ label: tab.label,
158
+ fields: Object.entries(props.config.fields).filter(([, field]) => fieldTab(field, tabs) === tab.id).map(([key]) => key)
159
+ }));
160
+ });
161
+ function selectTab(value) {
162
+ routeTab.value = value === drawerTabs.value?.[0]?.value ? void 0 : value;
134
163
  }
135
- function setState(state) {
136
- formState.value = state;
137
- snapshot.value = JSON.stringify(state);
164
+ const published = computed(() => formState.value.status === "published");
165
+ function revertStatus() {
166
+ if (drafts.value) formState.value.status = savedState.value.status ?? null;
138
167
  }
139
- const dirty = computed(() => JSON.stringify(formState.value) !== snapshot.value);
140
- const published = computed({
141
- get: () => formState.value.status === "published",
142
- set: (value) => {
143
- formState.value.status = value ? "published" : "draft";
168
+ const form = useCmsEntryForm({
169
+ state: formState,
170
+ fields: () => props.config.fields,
171
+ entryName: () => props.collection,
172
+ drafts,
173
+ onSubmit: save,
174
+ onInvalid: (errors) => {
175
+ revertStatus();
176
+ formRef.value?.revealErrors(errors);
144
177
  }
145
178
  });
146
179
  function togglePublished() {
147
- published.value = !published.value;
180
+ formState.value.status = published.value ? "draft" : "published";
181
+ void form.submit();
148
182
  }
149
- function revertStatus() {
150
- if (!drafts.value) return;
151
- formState.value.status = JSON.parse(snapshot.value).status ?? null;
183
+ function applyState(saved, current = saved) {
184
+ savedState.value = saved;
185
+ form.reset(saved);
186
+ if (current !== saved) formState.value = current;
152
187
  }
153
188
  let loadRequest = 0;
154
189
  async function load() {
155
190
  const request = ++loadRequest;
156
191
  const id = props.entryId;
157
- if (id === null) {
192
+ const source = id === null ? props.duplicateId : id;
193
+ const isStale = () => request !== loadRequest || props.entryId !== id || !open.value;
194
+ loadedId.value = id;
195
+ if (!source) {
158
196
  loading.value = false;
159
- setState(emptyState());
160
- if (props.initial) formState.value = { ...emptyState(), ...pickFields(props.initial) };
197
+ applyState(newState());
161
198
  return;
162
199
  }
163
- const isStale = () => request !== loadRequest || props.entryId !== id || !open.value;
164
200
  loading.value = true;
165
201
  try {
166
- const entry = await cmsApi(`${endpoint.value}/${id}`);
202
+ const entry = await cmsApi(`${endpoint.value}/${source}`);
167
203
  if (isStale()) return;
168
- setState(pickFields(entry));
204
+ if (id === null) {
205
+ applyState(newState(), {
206
+ ...emptyState(),
207
+ ...pickFields(duplicateEntryValues(props.config, entry))
208
+ });
209
+ } else {
210
+ applyState(pickFields(entry));
211
+ }
169
212
  } catch (error) {
170
213
  if (isStale()) return;
171
- toast.add({
172
- title: "Could not load entry",
173
- description: errorMessage(error),
174
- color: "error"
175
- });
176
- open.value = false;
214
+ toast.error("Could not load entry", { description: errorMessage(error) });
215
+ emit("missing");
177
216
  } finally {
178
217
  if (request === loadRequest) loading.value = false;
179
218
  }
180
219
  }
181
220
  watch(
182
- () => [open.value, props.entryId, props.initial],
183
- ([isOpen]) => {
184
- if (isOpen) load();
221
+ () => [open.value, props.entryId, props.duplicateId],
222
+ ([isOpen], previous) => {
223
+ if (!isOpen) return;
224
+ if (previous?.[0] && props.entryId !== null && loadedId.value === props.entryId) return;
225
+ void load();
185
226
  },
186
227
  { immediate: true }
187
228
  );
188
- function confirmClose() {
189
- return !dirty.value || confirmAction("You have unsaved changes. Close anyway?");
190
- }
191
- async function save() {
192
- if (saving.value) return;
193
- saving.value = true;
229
+ async function save(values) {
230
+ const submitted = cloneState(values);
194
231
  try {
195
- await (isNew.value ? cmsApi(endpoint.value, { method: "POST", body: formState.value }) : cmsApi(`${endpoint.value}/${props.entryId}`, {
196
- method: "PUT",
197
- body: formState.value
198
- }));
199
- snapshot.value = JSON.stringify(formState.value);
200
- toast.add({ title: "Saved", color: "success" });
201
- emit("saved");
202
- open.value = false;
232
+ const row = await (isNew.value ? cmsApi(endpoint.value, { method: "POST", body: submitted }) : cmsApi(`${endpoint.value}/${props.entryId}`, { method: "PUT", body: submitted }));
233
+ const saved = pickFields(row ?? submitted);
234
+ const merged = mergeSavedState(submitted, formState.value, saved);
235
+ const id = row?.id != null ? String(row.id) : props.entryId;
236
+ applyState(saved, merged.state);
237
+ loadedId.value = id;
238
+ if (merged.clean) {
239
+ toast.success("Saved");
240
+ if (id) emit("saved", id);
241
+ open.value = false;
242
+ return;
243
+ }
244
+ toast.success("Saved", { description: "Changes made while saving are not saved yet." });
245
+ if (id && isNew.value) emit("created", id);
246
+ else if (id) emit("saved", id);
203
247
  } catch (error) {
204
248
  revertStatus();
205
- toast.add({
206
- title: "Save failed",
207
- description: errorMessage(error),
208
- color: "error"
209
- });
210
- } finally {
211
- saving.value = false;
249
+ throw error;
212
250
  }
213
251
  }
214
- async function duplicate() {
215
- if (dirty.value && !await confirmAction("You have unsaved changes. Duplicate the saved entry anyway?"))
216
- return;
217
- emit("duplicate", duplicateEntryValues(props.config, JSON.parse(snapshot.value)));
218
- }
219
252
  async function remove() {
220
- if (!await confirmAction("Delete this row?")) return;
221
- saving.value = true;
253
+ if (!await confirm.delete("Delete this entry?", {
254
+ description: entryName.value ? `"${entryName.value}" is deleted for good.` : "The entry is deleted for good."
255
+ }))
256
+ return;
222
257
  try {
223
258
  await cmsApi(`${endpoint.value}/${props.entryId}`, { method: "DELETE" });
224
- snapshot.value = JSON.stringify(formState.value);
259
+ form.markClean();
260
+ toast.success("Entry deleted");
225
261
  emit("deleted");
262
+ await nextTick();
226
263
  open.value = false;
227
264
  } catch (error) {
228
- toast.add({
229
- title: "Delete failed",
230
- description: errorMessage(error),
231
- color: "error"
232
- });
233
- } finally {
234
- saving.value = false;
265
+ toast.error("Delete failed", { description: errorMessage(error) });
235
266
  }
236
267
  }
237
268
  </script>
@@ -1,24 +1,30 @@
1
1
  import type { CmsEntry } from '#nuxt-cms';
2
+ import type { CmsSearchFocus } from '../../../shared/search.js';
2
3
  type __VLS_Props = {
3
4
  collection: string;
4
5
  config: CmsEntry;
5
6
  entryId: string | null;
6
- initial?: Record<string, unknown> | null;
7
+ duplicateId?: string | null;
8
+ focus?: CmsSearchFocus | null;
7
9
  };
8
10
  type __VLS_ModelProps = {
9
11
  'open'?: boolean;
10
12
  };
11
13
  type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
12
14
  declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
15
+ duplicate: (id: string) => any;
16
+ created: (id: string) => any;
17
+ missing: () => any;
18
+ saved: (id: string) => any;
13
19
  "update:open": (value: boolean) => any;
14
- saved: () => any;
15
20
  deleted: () => any;
16
- duplicate: (values: Record<string, unknown>) => any;
17
21
  }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
22
+ onDuplicate?: ((id: string) => any) | undefined;
23
+ onCreated?: ((id: string) => any) | undefined;
24
+ onMissing?: (() => any) | undefined;
25
+ onSaved?: ((id: string) => any) | undefined;
18
26
  "onUpdate:open"?: ((value: boolean) => any) | undefined;
19
- onSaved?: (() => any) | undefined;
20
27
  onDeleted?: (() => any) | undefined;
21
- onDuplicate?: ((values: Record<string, unknown>) => any) | undefined;
22
28
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
23
29
  declare const _default: typeof __VLS_export;
24
30
  export default _default;