@conduction/nextcloud-vue 2.56.0-beta.4 → 2.56.0-beta.5

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 (300) hide show
  1. package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js +12 -2
  2. package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js.map +1 -1
  3. package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js +1 -2
  4. package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js.map +1 -1
  5. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue2.js.map +1 -1
  6. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue3.js +0 -3
  7. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue3.js.map +1 -1
  8. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue2.js.map +1 -1
  9. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js +1 -2
  10. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js.map +1 -1
  11. package/dist/esm/components/CnBoardView/CnBoardView.vue2.js +12 -5
  12. package/dist/esm/components/CnBoardView/CnBoardView.vue2.js.map +1 -1
  13. package/dist/esm/components/CnBoardView/CnBoardView.vue3.js +2 -1
  14. package/dist/esm/components/CnBoardView/CnBoardView.vue3.js.map +1 -1
  15. package/dist/esm/components/CnCardGrid/CnCardGrid.vue2.js +9 -1
  16. package/dist/esm/components/CnCardGrid/CnCardGrid.vue2.js.map +1 -1
  17. package/dist/esm/components/CnCardGrid/CnCardGrid.vue3.js.map +1 -1
  18. package/dist/esm/components/CnContextMenu/CnContextMenu.vue2.js +6 -1
  19. package/dist/esm/components/CnContextMenu/CnContextMenu.vue2.js.map +1 -1
  20. package/dist/esm/components/CnContextMenu/CnContextMenu.vue3.js.map +1 -1
  21. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +116 -15
  22. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
  23. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +27 -14
  24. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
  25. package/dist/esm/components/CnDateAxisView/CnDateAxisView.vue2.js +13 -6
  26. package/dist/esm/components/CnDateAxisView/CnDateAxisView.vue2.js.map +1 -1
  27. package/dist/esm/components/CnDateAxisView/CnDateAxisView.vue3.js +2 -0
  28. package/dist/esm/components/CnDateAxisView/CnDateAxisView.vue3.js.map +1 -1
  29. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +29 -1
  30. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
  31. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
  32. package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue2.js.map +1 -1
  33. package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue3.js +1 -2
  34. package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue3.js.map +1 -1
  35. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js +3 -1
  36. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js.map +1 -1
  37. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js +17 -17
  38. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js.map +1 -1
  39. package/dist/esm/components/CnFilesWidget/CnFilesWidget.vue2.js +4 -21
  40. package/dist/esm/components/CnFilesWidget/CnFilesWidget.vue2.js.map +1 -1
  41. package/dist/esm/components/CnFilesWidget/CnFilesWidget.vue3.js.map +1 -1
  42. package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue2.js +0 -13
  43. package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue2.js.map +1 -1
  44. package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue3.js +8 -8
  45. package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue3.js.map +1 -1
  46. package/dist/esm/components/CnFlowsPage/CnFlowsPage.vue2.js.map +1 -1
  47. package/dist/esm/components/CnFlowsPage/CnFlowsPage.vue3.js +3 -2
  48. package/dist/esm/components/CnFlowsPage/CnFlowsPage.vue3.js.map +1 -1
  49. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +67 -13
  50. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  51. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +15 -8
  52. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  53. package/dist/esm/components/CnIndexPage/manifestActionDispatch.js +31 -11
  54. package/dist/esm/components/CnIndexPage/manifestActionDispatch.js.map +1 -1
  55. package/dist/esm/components/CnIntegrationWidget/CnIntegrationWidgetEmpty.vue2.js.map +1 -1
  56. package/dist/esm/components/CnIntegrationWidget/CnIntegrationWidgetEmpty.vue3.js +1 -2
  57. package/dist/esm/components/CnIntegrationWidget/CnIntegrationWidgetEmpty.vue3.js.map +1 -1
  58. package/dist/esm/components/CnInteractionFormWidget/CnInteractionFormWidget.vue2.js.map +1 -1
  59. package/dist/esm/components/CnInteractionFormWidget/CnInteractionFormWidget.vue3.js +0 -1
  60. package/dist/esm/components/CnInteractionFormWidget/CnInteractionFormWidget.vue3.js.map +1 -1
  61. package/dist/esm/components/CnLinkButtonWidget/CnLinkButtonWidget.vue2.js +2 -17
  62. package/dist/esm/components/CnLinkButtonWidget/CnLinkButtonWidget.vue2.js.map +1 -1
  63. package/dist/esm/components/CnLinkButtonWidget/CnLinkButtonWidget.vue3.js.map +1 -1
  64. package/dist/esm/components/CnLogsPage/CnLogsPage.vue2.js +35 -11
  65. package/dist/esm/components/CnLogsPage/CnLogsPage.vue2.js.map +1 -1
  66. package/dist/esm/components/CnLogsPage/CnLogsPage.vue3.js +3 -2
  67. package/dist/esm/components/CnLogsPage/CnLogsPage.vue3.js.map +1 -1
  68. package/dist/esm/components/CnObjectCard/CnObjectCard.vue2.js +23 -5
  69. package/dist/esm/components/CnObjectCard/CnObjectCard.vue2.js.map +1 -1
  70. package/dist/esm/components/CnObjectCard/CnObjectCard.vue3.js +1 -1
  71. package/dist/esm/components/CnObjectCard/CnObjectCard.vue3.js.map +1 -1
  72. package/dist/esm/components/CnObjectList/CnObjectList.vue2.js +19 -3
  73. package/dist/esm/components/CnObjectList/CnObjectList.vue2.js.map +1 -1
  74. package/dist/esm/components/CnObjectList/CnObjectList.vue3.js.map +1 -1
  75. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js +45 -15
  76. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js.map +1 -1
  77. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js +4 -2
  78. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js.map +1 -1
  79. package/dist/esm/components/CnObjectRow/CnObjectRow.vue2.js +24 -6
  80. package/dist/esm/components/CnObjectRow/CnObjectRow.vue2.js.map +1 -1
  81. package/dist/esm/components/CnObjectRow/CnObjectRow.vue3.js +1 -1
  82. package/dist/esm/components/CnObjectRow/CnObjectRow.vue3.js.map +1 -1
  83. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js.map +1 -1
  84. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js +0 -1
  85. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js.map +1 -1
  86. package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue2.js.map +1 -1
  87. package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue3.js +4 -2
  88. package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue3.js.map +1 -1
  89. package/dist/esm/components/CnRowActions/CnRowActions.vue2.js +7 -2
  90. package/dist/esm/components/CnRowActions/CnRowActions.vue2.js.map +1 -1
  91. package/dist/esm/components/CnRowActions/CnRowActions.vue3.js.map +1 -1
  92. package/dist/esm/components/CnSpendAnalyticsWidget/CnSpendAnalyticsWidget.vue2.js +5 -3
  93. package/dist/esm/components/CnSpendAnalyticsWidget/CnSpendAnalyticsWidget.vue2.js.map +1 -1
  94. package/dist/esm/components/CnSpendAnalyticsWidget/CnSpendAnalyticsWidget.vue3.js.map +1 -1
  95. package/dist/esm/components/CnTabs/CnTabs.vue2.js.map +1 -1
  96. package/dist/esm/components/CnTabs/CnTabs.vue3.js.map +1 -1
  97. package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue2.js +3 -1
  98. package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue2.js.map +1 -1
  99. package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue3.js +1 -0
  100. package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue3.js.map +1 -1
  101. package/dist/esm/integrations/builtin/analytics/CnAnalyticsCard.vue2.js +3 -1
  102. package/dist/esm/integrations/builtin/analytics/CnAnalyticsCard.vue2.js.map +1 -1
  103. package/dist/esm/integrations/builtin/analytics/CnAnalyticsCard.vue3.js.map +1 -1
  104. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue2.js +3 -1
  105. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue2.js.map +1 -1
  106. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue3.js +2 -4
  107. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue3.js.map +1 -1
  108. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksCard.vue2.js +6 -0
  109. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksCard.vue2.js.map +1 -1
  110. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksCard.vue3.js +68 -53
  111. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksCard.vue3.js.map +1 -1
  112. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksTab.vue2.js +17 -0
  113. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksTab.vue2.js.map +1 -1
  114. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksTab.vue3.js +21 -19
  115. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksTab.vue3.js.map +1 -1
  116. package/dist/esm/integrations/builtin/collectives/CnCollectivesCard.vue2.js +3 -1
  117. package/dist/esm/integrations/builtin/collectives/CnCollectivesCard.vue2.js.map +1 -1
  118. package/dist/esm/integrations/builtin/collectives/CnCollectivesCard.vue3.js.map +1 -1
  119. package/dist/esm/integrations/builtin/collectives/CnCollectivesTab.vue2.js +3 -1
  120. package/dist/esm/integrations/builtin/collectives/CnCollectivesTab.vue2.js.map +1 -1
  121. package/dist/esm/integrations/builtin/collectives/CnCollectivesTab.vue3.js +2 -4
  122. package/dist/esm/integrations/builtin/collectives/CnCollectivesTab.vue3.js.map +1 -1
  123. package/dist/esm/integrations/builtin/cospend/CnCospendCard.vue2.js +2 -1
  124. package/dist/esm/integrations/builtin/cospend/CnCospendCard.vue2.js.map +1 -1
  125. package/dist/esm/integrations/builtin/cospend/CnCospendCard.vue3.js.map +1 -1
  126. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue2.js +2 -1
  127. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue2.js.map +1 -1
  128. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue3.js +1 -2
  129. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue3.js.map +1 -1
  130. package/dist/esm/integrations/builtin/deck/CnDeckCard.vue2.js +2 -1
  131. package/dist/esm/integrations/builtin/deck/CnDeckCard.vue2.js.map +1 -1
  132. package/dist/esm/integrations/builtin/deck/CnDeckCard.vue3.js.map +1 -1
  133. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue2.js +2 -1
  134. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue2.js.map +1 -1
  135. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue3.js +1 -2
  136. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue3.js.map +1 -1
  137. package/dist/esm/integrations/builtin/email/CnEmailCard.vue2.js.map +1 -1
  138. package/dist/esm/integrations/builtin/email/CnEmailCard.vue3.js.map +1 -1
  139. package/dist/esm/integrations/builtin/email/CnEmailTab.vue2.js.map +1 -1
  140. package/dist/esm/integrations/builtin/email/CnEmailTab.vue3.js +1 -2
  141. package/dist/esm/integrations/builtin/email/CnEmailTab.vue3.js.map +1 -1
  142. package/dist/esm/integrations/builtin/flow/CnFlowCard.vue2.js +2 -1
  143. package/dist/esm/integrations/builtin/flow/CnFlowCard.vue2.js.map +1 -1
  144. package/dist/esm/integrations/builtin/flow/CnFlowCard.vue3.js.map +1 -1
  145. package/dist/esm/integrations/builtin/flow/CnFlowTab.vue2.js +2 -1
  146. package/dist/esm/integrations/builtin/flow/CnFlowTab.vue2.js.map +1 -1
  147. package/dist/esm/integrations/builtin/flow/CnFlowTab.vue3.js +1 -2
  148. package/dist/esm/integrations/builtin/flow/CnFlowTab.vue3.js.map +1 -1
  149. package/dist/esm/integrations/builtin/forms/CnFormsCard.vue2.js +3 -1
  150. package/dist/esm/integrations/builtin/forms/CnFormsCard.vue2.js.map +1 -1
  151. package/dist/esm/integrations/builtin/forms/CnFormsCard.vue3.js.map +1 -1
  152. package/dist/esm/integrations/builtin/forms/CnFormsTab.vue2.js +3 -1
  153. package/dist/esm/integrations/builtin/forms/CnFormsTab.vue2.js.map +1 -1
  154. package/dist/esm/integrations/builtin/forms/CnFormsTab.vue3.js +2 -4
  155. package/dist/esm/integrations/builtin/forms/CnFormsTab.vue3.js.map +1 -1
  156. package/dist/esm/integrations/builtin/maps/CnMapsCard.vue2.js +3 -1
  157. package/dist/esm/integrations/builtin/maps/CnMapsCard.vue2.js.map +1 -1
  158. package/dist/esm/integrations/builtin/maps/CnMapsCard.vue3.js.map +1 -1
  159. package/dist/esm/integrations/builtin/maps/CnMapsTab.vue2.js +3 -1
  160. package/dist/esm/integrations/builtin/maps/CnMapsTab.vue2.js.map +1 -1
  161. package/dist/esm/integrations/builtin/maps/CnMapsTab.vue3.js +2 -4
  162. package/dist/esm/integrations/builtin/maps/CnMapsTab.vue3.js.map +1 -1
  163. package/dist/esm/integrations/builtin/openproject/CnOpenprojectCard.vue2.js +3 -1
  164. package/dist/esm/integrations/builtin/openproject/CnOpenprojectCard.vue2.js.map +1 -1
  165. package/dist/esm/integrations/builtin/openproject/CnOpenprojectCard.vue3.js.map +1 -1
  166. package/dist/esm/integrations/builtin/openproject/CnOpenprojectTab.vue2.js +3 -1
  167. package/dist/esm/integrations/builtin/openproject/CnOpenprojectTab.vue2.js.map +1 -1
  168. package/dist/esm/integrations/builtin/openproject/CnOpenprojectTab.vue3.js +2 -4
  169. package/dist/esm/integrations/builtin/openproject/CnOpenprojectTab.vue3.js.map +1 -1
  170. package/dist/esm/integrations/builtin/photos/CnPhotosCard.vue2.js +2 -1
  171. package/dist/esm/integrations/builtin/photos/CnPhotosCard.vue2.js.map +1 -1
  172. package/dist/esm/integrations/builtin/photos/CnPhotosCard.vue3.js.map +1 -1
  173. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue2.js +2 -1
  174. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue2.js.map +1 -1
  175. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue3.js +1 -2
  176. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue3.js.map +1 -1
  177. package/dist/esm/integrations/builtin/polls/CnPollsCard.vue2.js +2 -1
  178. package/dist/esm/integrations/builtin/polls/CnPollsCard.vue2.js.map +1 -1
  179. package/dist/esm/integrations/builtin/polls/CnPollsCard.vue3.js.map +1 -1
  180. package/dist/esm/integrations/builtin/polls/CnPollsTab.vue2.js +2 -1
  181. package/dist/esm/integrations/builtin/polls/CnPollsTab.vue2.js.map +1 -1
  182. package/dist/esm/integrations/builtin/polls/CnPollsTab.vue3.js +1 -2
  183. package/dist/esm/integrations/builtin/polls/CnPollsTab.vue3.js.map +1 -1
  184. package/dist/esm/integrations/builtin/shares/CnSharesTab.vue2.js.map +1 -1
  185. package/dist/esm/integrations/builtin/shares/CnSharesTab.vue3.js +3 -6
  186. package/dist/esm/integrations/builtin/shares/CnSharesTab.vue3.js.map +1 -1
  187. package/dist/esm/integrations/builtin/talk/CnTalkCard.vue2.js +3 -1
  188. package/dist/esm/integrations/builtin/talk/CnTalkCard.vue2.js.map +1 -1
  189. package/dist/esm/integrations/builtin/talk/CnTalkCard.vue3.js.map +1 -1
  190. package/dist/esm/integrations/builtin/talk/CnTalkTab.vue2.js +3 -1
  191. package/dist/esm/integrations/builtin/talk/CnTalkTab.vue2.js.map +1 -1
  192. package/dist/esm/integrations/builtin/talk/CnTalkTab.vue3.js +2 -4
  193. package/dist/esm/integrations/builtin/talk/CnTalkTab.vue3.js.map +1 -1
  194. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerCard.vue2.js +2 -1
  195. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerCard.vue2.js.map +1 -1
  196. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerCard.vue3.js.map +1 -1
  197. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerTab.vue2.js +2 -1
  198. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerTab.vue2.js.map +1 -1
  199. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerTab.vue3.js +1 -2
  200. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerTab.vue3.js.map +1 -1
  201. package/dist/esm/integrations/builtin/xwiki/CnXwikiCard.vue2.js +4 -1
  202. package/dist/esm/integrations/builtin/xwiki/CnXwikiCard.vue2.js.map +1 -1
  203. package/dist/esm/integrations/builtin/xwiki/CnXwikiCard.vue3.js.map +1 -1
  204. package/dist/esm/integrations/builtin/xwiki/CnXwikiTab.vue2.js +6 -3
  205. package/dist/esm/integrations/builtin/xwiki/CnXwikiTab.vue2.js.map +1 -1
  206. package/dist/esm/integrations/builtin/xwiki/CnXwikiTab.vue3.js +2 -4
  207. package/dist/esm/integrations/builtin/xwiki/CnXwikiTab.vue3.js.map +1 -1
  208. package/dist/esm/l10n/en.json.js +1 -0
  209. package/dist/esm/l10n/en.json.js.map +1 -1
  210. package/dist/esm/l10n/nl.json.js +1 -0
  211. package/dist/esm/l10n/nl.json.js.map +1 -1
  212. package/dist/esm/nextcloud-vue.css +71 -7
  213. package/dist/esm/utils/actionLink.js +5 -0
  214. package/dist/esm/utils/actionLink.js.map +1 -1
  215. package/dist/esm/utils/actionsDispatcher.js +16 -1
  216. package/dist/esm/utils/actionsDispatcher.js.map +1 -1
  217. package/dist/esm/utils/linkNavigation.js +6 -3
  218. package/dist/esm/utils/linkNavigation.js.map +1 -1
  219. package/dist/esm/utils/rowAuxClick.js +30 -5
  220. package/dist/esm/utils/rowAuxClick.js.map +1 -1
  221. package/dist/esm/utils/safeHref.js +18 -3
  222. package/dist/esm/utils/safeHref.js.map +1 -1
  223. package/dist/nextcloud-vue.cjs.js +809 -383
  224. package/dist/nextcloud-vue.cjs.js.map +2 -2
  225. package/dist/nextcloud-vue.css +71 -7
  226. package/l10n/en.json +1 -0
  227. package/l10n/nl.json +1 -0
  228. package/package.json +1 -1
  229. package/src/components/CnActionsBar/CnActionsBar.vue +14 -5
  230. package/src/components/CnActionsMenu/CnActionsMenu.vue +0 -3
  231. package/src/components/CnAdminSettingsShell/CnAdminSettingsShell.vue +1 -2
  232. package/src/components/CnBoardView/CnBoardView.vue +13 -5
  233. package/src/components/CnCardGrid/CnCardGrid.vue +9 -1
  234. package/src/components/CnContextMenu/CnContextMenu.vue +6 -1
  235. package/src/components/CnDataTable/CnDataTable.md +1 -1
  236. package/src/components/CnDataTable/CnDataTable.vue +131 -17
  237. package/src/components/CnDateAxisView/CnDateAxisView.vue +15 -6
  238. package/src/components/CnDetailPage/CnDetailPage.md +1 -1
  239. package/src/components/CnDetailPage/CnDetailPage.vue +29 -1
  240. package/src/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue +1 -2
  241. package/src/components/CnFilesBrowser/CnFilesBrowser.vue +5 -3
  242. package/src/components/CnFilesWidget/CnFilesWidget.vue +4 -21
  243. package/src/components/CnFlowRunsWidget/CnFlowRunsWidget.vue +8 -21
  244. package/src/components/CnFlowsPage/CnFlowsPage.vue +2 -1
  245. package/src/components/CnIndexPage/CnIndexPage.vue +75 -14
  246. package/src/components/CnIndexPage/manifestActionDispatch.js +31 -11
  247. package/src/components/CnIntegrationWidget/CnIntegrationWidgetEmpty.vue +1 -2
  248. package/src/components/CnInteractionFormWidget/CnInteractionFormWidget.vue +0 -1
  249. package/src/components/CnLinkButtonWidget/CnLinkButtonWidget.vue +2 -17
  250. package/src/components/CnLogsPage/CnLogsPage.vue +37 -12
  251. package/src/components/CnObjectCard/CnObjectCard.vue +24 -6
  252. package/src/components/CnObjectList/CnObjectList.vue +19 -3
  253. package/src/components/CnObjectListWidget/CnObjectListWidget.vue +47 -15
  254. package/src/components/CnObjectRow/CnObjectRow.vue +25 -7
  255. package/src/components/CnObjectSidebar/CnFilesTab.vue +0 -1
  256. package/src/components/CnPageRenderer/CnPageRenderer.vue +2 -0
  257. package/src/components/CnRowActions/CnRowActions.vue +7 -2
  258. package/src/components/CnSpendAnalyticsWidget/CnSpendAnalyticsWidget.vue +5 -3
  259. package/src/components/CnTabs/CnTabs.vue +7 -3
  260. package/src/components/CnTasksWidget/CnTasksWidget.vue +4 -1
  261. package/src/css/table.css +26 -0
  262. package/src/integrations/builtin/analytics/CnAnalyticsCard.vue +3 -2
  263. package/src/integrations/builtin/analytics/CnAnalyticsTab.vue +5 -6
  264. package/src/integrations/builtin/bookmarks/CnBookmarksCard.vue +12 -1
  265. package/src/integrations/builtin/bookmarks/CnBookmarksTab.vue +23 -6
  266. package/src/integrations/builtin/bookmarks/__tests__/CnBookmarksTab.spec.js +7 -2
  267. package/src/integrations/builtin/collectives/CnCollectivesCard.vue +3 -2
  268. package/src/integrations/builtin/collectives/CnCollectivesTab.vue +5 -6
  269. package/src/integrations/builtin/cospend/CnCospendCard.vue +2 -2
  270. package/src/integrations/builtin/cospend/CnCospendTab.vue +3 -4
  271. package/src/integrations/builtin/deck/CnDeckCard.vue +2 -2
  272. package/src/integrations/builtin/deck/CnDeckTab.vue +3 -4
  273. package/src/integrations/builtin/email/CnEmailCard.vue +6 -2
  274. package/src/integrations/builtin/email/CnEmailTab.vue +7 -4
  275. package/src/integrations/builtin/flow/CnFlowCard.vue +2 -2
  276. package/src/integrations/builtin/flow/CnFlowTab.vue +3 -4
  277. package/src/integrations/builtin/forms/CnFormsCard.vue +3 -2
  278. package/src/integrations/builtin/forms/CnFormsTab.vue +5 -6
  279. package/src/integrations/builtin/maps/CnMapsCard.vue +3 -2
  280. package/src/integrations/builtin/maps/CnMapsTab.vue +5 -6
  281. package/src/integrations/builtin/maps/__tests__/CnMapsTab.spec.js +9 -0
  282. package/src/integrations/builtin/openproject/CnOpenprojectCard.vue +3 -2
  283. package/src/integrations/builtin/openproject/CnOpenprojectTab.vue +5 -6
  284. package/src/integrations/builtin/photos/CnPhotosCard.vue +2 -2
  285. package/src/integrations/builtin/photos/CnPhotosTab.vue +3 -4
  286. package/src/integrations/builtin/polls/CnPollsCard.vue +2 -2
  287. package/src/integrations/builtin/polls/CnPollsTab.vue +3 -4
  288. package/src/integrations/builtin/shares/CnSharesTab.vue +3 -6
  289. package/src/integrations/builtin/talk/CnTalkCard.vue +3 -2
  290. package/src/integrations/builtin/talk/CnTalkTab.vue +5 -6
  291. package/src/integrations/builtin/time-tracker/CnTimeTrackerCard.vue +2 -2
  292. package/src/integrations/builtin/time-tracker/CnTimeTrackerTab.vue +3 -4
  293. package/src/integrations/builtin/xwiki/CnXwikiCard.vue +4 -2
  294. package/src/integrations/builtin/xwiki/CnXwikiTab.vue +7 -7
  295. package/src/integrations/builtin/xwiki/__tests__/CnXwikiTab.spec.js +9 -0
  296. package/src/utils/actionLink.js +5 -0
  297. package/src/utils/actionsDispatcher.js +15 -0
  298. package/src/utils/linkNavigation.js +6 -3
  299. package/src/utils/rowAuxClick.js +29 -4
  300. package/src/utils/safeHref.js +18 -3
@@ -1 +1 @@
1
- {"version":3,"file":"CnPageRenderer.vue2.js","sources":["../../../../src/components/CnPageRenderer/CnPageRenderer.vue"],"sourcesContent":["<!--\n CnPageRenderer — JSON-driven page dispatcher.\n\n Mounted inside <router-view>, CnPageRenderer reads the manifest, finds\n the page definition whose `id` matches the current route name, and\n renders the appropriate page component by dispatching on `type`.\n\n Page types are resolved via the `pageTypes` registry. The library\n ships a built-in registry (`defaultPageTypes` — index, detail,\n dashboard) and consumers can extend it by passing a merged map to\n CnAppRoot or CnPageRenderer. The `custom` type is special: it\n resolves `page.component` against the customComponents registry\n rather than the page-types map. Adding a new built-in page type to\n the library is one line in `pageTypes.js` — no change here.\n\n Each entry in `pageTypes` is wrapped in `defineAsyncComponent` so\n apps using only a subset of types do not pay the bundle cost for\n others (notably the GridStack-backed dashboard).\n\n Manifest, customComponents, pageTypes, and translate are injected\n from CnAppRoot by default; each can also be passed as props for\n standalone use without CnAppRoot. Props always take precedence\n over inject.\n\n See REQ-JMR-005 of the json-manifest-renderer specification.\n-->\n<template>\n\t<div\n\t\tv-if=\"currentPage\"\n\t\t:data-page-id=\"currentPage.id\"\n\t\tdata-testid=\"cn-page\"\n\t\t:data-testid-page-id=\"currentPage.id\"\n\t\tclass=\"cn-page-renderer\"\n\t\t:class=\"[{ 'cn-page-renderer--no-sidebar': !pageSidebarVisibleValue }]\">\n\t\t<!--\n\t\t A page whose `requiresApp` is not installed renders the missing-\n\t\t dependency screen INSTEAD of its body.\n\n\t\t This is for the deep link, not the menu. An entry gated by\n\t\t `visibleIf.appInstalled` is already hidden from navigation, so the\n\t\t only ways here are a bookmark, a shared URL, a redirect or an e2e\n\t\t spec — and every one of those otherwise lands on a page that renders\n\t\t an empty list with nothing saying why. \"Not installed\" then looks\n\t\t identical to \"no data\" and to \"no permission\".\n\n\t\t It is deliberately NOT the deprecated soft-dependency notice\n\t\t (REQ-DIA-6, off by default since 2.1.0). Those stacked one banner per\n\t\t optional app above EVERY page on EVERY load; this renders on the one\n\t\t page that actually needs the app, only when someone navigates to it.\n\n\t\t Widget-level gating stays with `visibleIf.appInstalled`: a detail page\n\t\t may carry many widgets where only one needs the app, and that widget\n\t\t hides while the page renders normally. Use `requiresApp` only when the\n\t\t WHOLE page is meaningless without it.\n\t\t-->\n\t\t<!--\n\t\t A page whose declared `permission` the user does not hold renders a\n\t\t refusal INSTEAD of its body, and BEFORE the dependency check, because\n\t\t \"you may not see this\" outranks \"the app it needs is missing\".\n\n\t\t Same reasoning as `requiresApp` above: this is for the deep link, not\n\t\t the menu. CnAppNav already drops the entry, so the only ways here are\n\t\t a bookmark, a shared URL, a redirect or a typed address — and until\n\t\t now every one of those rendered the page in full.\n\t\t-->\n\t\t<NcEmptyContent v-if=\"forbiddenPagePermission\"\n\t\t\t:name=\"tr('You do not have access to this page')\"\n\t\t\t:description=\"tr('Ask an administrator if you need it.')\"\n\t\t\tdata-testid=\"cn-page-forbidden\">\n\t\t\t<template #icon>\n\t\t\t\t<LockOutline :size=\"20\" />\n\t\t\t</template>\n\t\t</NcEmptyContent>\n\n\t\t<CnDependencyMissing\n\t\t\tv-else-if=\"missingPageDependency\"\n\t\t\t:dependencies=\"[missingPageDependency]\"\n\t\t\t:heading=\"missingDependencyHeading\"\n\t\t\t:intro=\"missingDependencyIntro\"\n\t\t\tdata-testid=\"cn-page-dependency-missing\" />\n\n\t\t<!-- V2 render path: slot dispatcher via CnWidgetGrid.\n\t\t Body falls back to the typed-primitive dispatch when no\n\t\t widgets[] entries target the `body` slot — apps that just\n\t\t declare `type:\"index\"` (or any other registered type) with\n\t\t a `config` payload still get the default page component\n\t\t (CnIndexPage, CnDetailPage, etc.) mounted, without having\n\t\t to hand-author a widget entry. An explicit body widget\n\t\t (e.g. an `object-table` widget in `body`) still wins over\n\t\t the default. -->\n\t\t<template v-else-if=\"isV2Manifest\">\n\t\t\t<!-- body slot — widgets first, default typed component otherwise.\n\t\t\t KNOWN GAP (ConductionNL/hrmq#112 follow-up): a body widget\n\t\t\t short-circuits the typed component, so a `type: \"detail\"` page\n\t\t\t that adopts ADR-036's page-level `widgets[]` never mounts\n\t\t\t CnDetailPage and loses its header, padding, sidebar and grid\n\t\t\t discipline. The same applies to `type: \"dashboard\"` pages and\n\t\t\t CnDashboardPage.\n\n\t\t\t NOTE the direction of the tension: the v2 schema DOCUMENTS\n\t\t\t page-level `widgets[]` as preferred and calls `config.widgets`\n\t\t\t legacy, yet only `config.widgets` reaches the typed component.\n\t\t\t An app following the documented advice gets the worse result.\n\n\t\t\t hrmq was the only app with `widgets[]` on detail pages and has\n\t\t\t since moved its 47 pages onto `config.widgets` (hrmq#115), so\n\t\t\t nothing in the fleet is currently mis-rendering — but the trap\n\t\t\t is still armed for the next app that follows the schema's own\n\t\t\t recommendation.\n\n\t\t\t Hosting the grid in the typed component's default slot was tried\n\t\t\t and REVERTED: the unit suite went green while the live page got\n\t\t\t worse — the body rendered empty (CnDetailPage gates its default\n\t\t\t slot against its own auto-body) and its sidebar fired ~20\n\t\t\t integration endpoints that 404 on an instance without them. The\n\t\t\t real fix is either to make the typed components accept a body\n\t\t\t grid as a first-class input, or to settle the schema on one\n\t\t\t spelling and translate the other here. -->\n\t\t\t<CnWidgetGrid\n\t\t\t\tv-if=\"widgetsBySlot.has('body')\"\n\t\t\t\t:widgets=\"widgetsBySlot.get('body')\"\n\t\t\t\t:editable=\"bodyEditable\"\n\t\t\t\tslotName=\"body\" />\n\t\t\t<component\n\t\t\t\t:is=\"resolvedComponent\"\n\t\t\t\tv-else-if=\"resolvedComponent\"\n\t\t\t\t:key=\"pageRenderKey\"\n\t\t\t\tv-bind=\"{ ...$attrs, ...resolvedProps }\"\n\t\t\t\t@view=\"onRowOpen\"\n\t\t\t\t@rowClick=\"onRowOpen\"\n\t\t\t\t@editOpen=\"onRowOpen\"\n\t\t\t\t@configure=\"showConfigModal = true\">\n\t\t\t\t<!-- This `<template v-for>` defines dynamic SLOTS, not a\n\t\t\t\t rendered list, so the rule's advice is inverted here:\n\t\t\t\t `@vue/compiler-sfc` DISCARDS a `:key` on a slot-defining\n\t\t\t\t `<template>` (verified — the generated `createSlots` entry\n\t\t\t\t carries only `name`) and honours it only on the child.\n\t\t\t\t Moving the key up would throw it away. -->\n\t\t\t\t<!-- eslint-disable vue/no-v-for-template-key-on-child -->\n\t\t\t\t<template\n\t\t\t\t\tv-for=\"entry in resolvedSlotEntries\"\n\t\t\t\t\t#[entry.name]=\"slotProps\">\n\t\t\t\t\t<component\n\t\t\t\t\t\t:is=\"entry.component\"\n\t\t\t\t\t\t:key=\"entry.name\"\n\t\t\t\t\t\tv-bind=\"slotProps\" />\n\t\t\t\t</template>\n\t\t\t\t<!-- The open record, beside the list. The host never writes\n\t\t\t\t this slot: the renderer already knows which detail page\n\t\t\t\t the index opens into, so it mounts that one. `$attrs` too:\n\t\t\t\t the host passes the page its `objectStore` as an attribute,\n\t\t\t\t not through the manifest. -->\n\t\t\t\t<template v-if=\"splitPaneComponent\" #split-pane=\"splitScope\">\n\t\t\t\t\t<component\n\t\t\t\t\t\t:is=\"splitPaneComponent\"\n\t\t\t\t\t\tv-bind=\"{ ...$attrs, ...splitPaneProps }\"\n\t\t\t\t\t\t@edited=\"splitScope.saved\"\n\t\t\t\t\t\t@created=\"splitScope.saved\">\n\t\t\t\t\t\t<template\n\t\t\t\t\t\t\tv-for=\"entry in splitPaneSlotEntries\"\n\t\t\t\t\t\t\t#[entry.name]=\"paneSlotProps\">\n\t\t\t\t\t\t\t<component\n\t\t\t\t\t\t\t\t:is=\"entry.component\"\n\t\t\t\t\t\t\t\t:key=\"entry.name\"\n\t\t\t\t\t\t\t\tv-bind=\"paneSlotProps\" />\n\t\t\t\t\t\t</template>\n\t\t\t\t\t</component>\n\t\t\t\t</template>\n\t\t\t\t<!-- eslint-enable vue/no-v-for-template-key-on-child -->\n\t\t\t</component>\n\t\t\t<!-- header-actions slot -->\n\t\t\t<CnWidgetGrid\n\t\t\t\tv-if=\"widgetsBySlot.has('header-actions')\"\n\t\t\t\t:widgets=\"widgetsBySlot.get('header-actions')\"\n\t\t\t\tslotName=\"header-actions\" />\n\t\t\t<!-- footer slot -->\n\t\t\t<CnWidgetGrid\n\t\t\t\tv-if=\"widgetsBySlot.has('footer')\"\n\t\t\t\t:widgets=\"widgetsBySlot.get('footer')\"\n\t\t\t\tslotName=\"footer\" />\n\t\t\t<!-- modal slot -->\n\t\t\t<CnWidgetGrid\n\t\t\t\tv-if=\"widgetsBySlot.has('modal')\"\n\t\t\t\t:widgets=\"widgetsBySlot.get('modal')\"\n\t\t\t\tslotName=\"modal\" />\n\t\t\t<!-- sidebar slot (gated by cnPageSidebarVisible) -->\n\t\t\t<CnWidgetGrid\n\t\t\t\tv-if=\"widgetsBySlot.has('sidebar') && pageSidebarVisibleValue\"\n\t\t\t\t:widgets=\"widgetsBySlot.get('sidebar')\"\n\t\t\t\tslotName=\"sidebar\" />\n\t\t\t<!-- dynamic tab:* and section:* slots -->\n\t\t\t<template v-for=\"dynamicSlot in dynamicSlotKeys\" :key=\"dynamicSlot\">\n\t\t\t\t<CnWidgetGrid\n\t\t\t\t\t:widgets=\"widgetsBySlot.get(dynamicSlot)\"\n\t\t\t\t\t:slotName=\"dynamicSlot\" />\n\t\t\t</template>\n\t\t</template>\n\n\t\t<component\n\t\t\t:is=\"resolvedComponent\"\n\t\t\tv-else-if=\"resolvedComponent\"\n\t\t\t:key=\"pageRenderKey\"\n\t\t\tv-bind=\"{ ...$attrs, ...resolvedProps }\"\n\t\t\t@view=\"onRowOpen\"\n\t\t\t@rowClick=\"onRowOpen\"\n\t\t\t@editOpen=\"onRowOpen\"\n\t\t\t@configure=\"showConfigModal = true\">\n\t\t\t<!-- Dynamic slot definition, not a rendered list — see the note on\n\t\t\t the identical block above. -->\n\t\t\t<!-- eslint-disable vue/no-v-for-template-key-on-child -->\n\t\t\t<template\n\t\t\t\tv-for=\"entry in resolvedSlotEntries\"\n\t\t\t\t#[entry.name]=\"slotProps\">\n\t\t\t\t<component\n\t\t\t\t\t:is=\"entry.component\"\n\t\t\t\t\t:key=\"entry.name\"\n\t\t\t\t\tv-bind=\"slotProps\" />\n\t\t\t</template>\n\t\t\t<!-- The open record, beside the list. The host never writes\n\t\t\t this slot: the renderer already knows which detail page\n\t\t\t the index opens into, so it mounts that one. -->\n\t\t\t<template v-if=\"splitPaneComponent\" #split-pane=\"splitScope\">\n\t\t\t\t<component\n\t\t\t\t\t:is=\"splitPaneComponent\"\n\t\t\t\t\tv-bind=\"{ ...$attrs, ...splitPaneProps }\"\n\t\t\t\t\t@edited=\"splitScope.saved\"\n\t\t\t\t\t@created=\"splitScope.saved\">\n\t\t\t\t\t<template\n\t\t\t\t\t\tv-for=\"entry in splitPaneSlotEntries\"\n\t\t\t\t\t\t#[entry.name]=\"paneSlotProps\">\n\t\t\t\t\t\t<component\n\t\t\t\t\t\t\t:is=\"entry.component\"\n\t\t\t\t\t\t\t:key=\"entry.name\"\n\t\t\t\t\t\t\tv-bind=\"paneSlotProps\" />\n\t\t\t\t\t</template>\n\t\t\t\t</component>\n\t\t\t</template>\n\t\t\t<!-- eslint-enable vue/no-v-for-template-key-on-child -->\n\t\t</component>\n\n\t\t<!-- Builder empty-state. A page with no renderable body — e.g. a\n\t\t freshly-created custom page that has no `component` / body widgets\n\t\t yet — would otherwise render nothing at all, leaving no\n\t\t \"Edit with Buildiq\" affordance to start adding content. Render the\n\t\t edit button (it self-gates to builder mode via CnAppRoot's\n\t\t `cnOpenBuildAvailable`) plus a neutral prompt, so a new page is\n\t\t always editable. ADR-041. -->\n\t\t<div v-if=\"!hasRenderableBody\" class=\"cn-page-renderer__empty\">\n\t\t\t<div class=\"cn-page-renderer__empty-actions\">\n\t\t\t\t<CnBuildiqEditButton />\n\t\t\t</div>\n\t\t\t<NcEmptyContent :name=\"tr('This page is empty')\"\n\t\t\t\t:description=\"tr('Open the Buildiq editor to start adding content to this page.')\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<ShapeOutline :size=\"20\" />\n\t\t\t\t</template>\n\t\t\t</NcEmptyContent>\n\t\t</div>\n\n\t\t<!-- Per-page config editor, opened by an index page's edit-mode cog. -->\n\t\t<CnPageConfigModal v-if=\"showConfigModal && currentPage\"\n\t\t\t:page=\"currentPage\"\n\t\t\t@close=\"showConfigModal = false\" />\n\n\t\t<!-- Shared export launcher, opened by a `type:\"export\"` manifest\n\t\t action (Wave 1, nextcloud-vue#91). Configured from the action's\n\t\t entities[] / formats[] / description; the confirm payload routes\n\t\t to the action's optional `handler` (manifest actions map). -->\n\t\t<CnMassExportDialog\n\t\t\tv-if=\"exportAction\"\n\t\t\tref=\"exportDialog\"\n\t\t\t:entities=\"exportDialogEntities\"\n\t\t\t:formats=\"exportDialogFormats\"\n\t\t\t:description=\"exportAction.description || ''\"\n\t\t\t@confirm=\"onExportConfirm\"\n\t\t\t@close=\"exportAction = null\" />\n\t</div>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcEmptyContent } from '@nextcloud/vue'\nimport { ref } from 'vue'\nimport LockOutline from 'vue-material-design-icons/LockOutline.vue'\nimport ShapeOutline from 'vue-material-design-icons/ShapeOutline.vue'\nimport CnPageConfigModal from '../../dialogs/CnPageConfigModal.vue'\nimport CnBuildiqEditButton from '../CnBuildiqEditButton/CnBuildiqEditButton.vue'\nimport CnDependencyMissing from '../CnDependencyMissing/CnDependencyMissing.vue'\nimport CnWidgetGrid from '../CnWidgetGrid/CnWidgetGrid.vue'\nimport { useObjectSubscription } from '../../composables/useObjectSubscription.js'\nimport { useObjectStore } from '../../store/index.js'\nimport { dispatchAction, resolveCreateOverrideHandler } from '../../utils/actionsDispatcher.js'\nimport { isAppInstalled } from '../../utils/appInstalled.js'\nimport { pageHasSplitView, pageIdForRoute, splitIdForRoute, splitRouteName } from '../../utils/buildManifestRoutes.js'\nimport { openRowTarget } from '../../utils/linkNavigation.js'\nimport { listContextFromRoute, listContextToQuery } from '../../utils/listNavigation.js'\nimport { resolveRouteSentinels } from '../../utils/resolveRouteSentinels.js'\nimport { parseSortKeys } from '../../utils/routeFilters.js'\nimport { buildRouteParams, routePathFor } from '../../utils/routeParams.js'\nimport { isNewTabHandled } from '../../utils/rowAuxClick.js'\nimport { CnMassExportDialog } from '../CnMassExportDialog/index.js'\nimport { defaultPageTypes } from './pageTypes.js'\n\n/** Recognised fixed slot names for v2 manifests. */\nconst KNOWN_SLOTS = new Set(['body', 'sidebar', 'header-actions', 'footer', 'modal'])\n\n/**\n * Test whether a slot name is a recognised v2 slot pattern.\n *\n * @param {string} slotName The slot name to test (e.g. `body`, `tab:overview`).\n * @return {boolean}\n */\nfunction isKnownSlot(slotName) {\n\tif (!slotName) {\n\t\treturn false\n\t}\n\tif (KNOWN_SLOTS.has(slotName)) {\n\t\treturn true\n\t}\n\tif (/^tab:[^\\s]+$/.test(slotName)) {\n\t\treturn true\n\t}\n\tif (/^section:[^\\s]+$/.test(slotName)) {\n\t\treturn true\n\t}\n\treturn false\n}\n\n/**\n * Read-only defaults applied when a type='index' page declares\n * `config.readOnly: true` (REQ-MIPFU-4 of manifest-index-page-followups).\n * Merged UNDER the explicit `config.*` props by `resolvedProps`, so\n * any explicit prop the manifest sets still wins.\n */\nconst READ_ONLY_DEFAULTS = Object.freeze({\n\tselectable: false,\n\tshowAdd: false,\n\tshowFormDialog: false,\n\tshowEditAction: false,\n\tshowCopyAction: false,\n\tshowDeleteAction: false,\n\tshowMassImport: false,\n\tshowMassCopy: false,\n\tshowMassDelete: false,\n})\n\nexport default {\n\tname: 'CnPageRenderer',\n\n\tcomponents: {\n\t\tCnDependencyMissing,\n\t\tCnWidgetGrid,\n\t\tCnPageConfigModal,\n\t\tCnBuildiqEditButton,\n\t\tCnMassExportDialog,\n\t\tNcEmptyContent,\n\t\tShapeOutline,\n\t\tLockOutline,\n\t},\n\n\tinject: {\n\t\tcnManifest: { default: null },\n\t\t/**\n\t\t * The same manifest as `cnManifest`, but provided as a REF.\n\t\t *\n\t\t * Options-API `inject` resolves a plain provided value exactly once, at\n\t\t * this component's creation, and `cnManifest` is a getter on CnAppRoot's\n\t\t * provide object — so what arrives is a snapshot. A renderer created\n\t\t * before edit mode keeps the pre-edit manifest object and never\n\t\t * re-derives its page props from an in-app edit. `inject` unwraps a ref\n\t\t * into a reactive getter instead, which is what makes those edits render\n\t\t * (ADR-041).\n\t\t */\n\t\tcnManifestSource: { default: null },\n\t\tcnCustomComponents: { default: () => ({}) },\n\t\tcnTranslate: { default: () => (key) => key },\n\t\tcnPageTypes: { default: null },\n\t\tcnRegistry: { default: () => ({}) },\n\t\t/** Permission strings the current user holds, provided by CnAppRoot. */\n\t\tcnPermissions: { default: () => [] },\n\t\tcnOpenModal: { default: null },\n\t\t/** ADR-041: true while the in-app editor is editing — makes the body grid draggable. */\n\t\tcnEditingBody: { default: false },\n\t},\n\n\t/**\n\t * Expose the current page's sidebar-visibility state and\n\t * sidebar-component override to descendants (notably\n\t * `CnAppRoot` which gates its `#sidebar` slot on\n\t * `cnPageSidebarVisible.value` and renders\n\t * `cnPageSidebarComponent.value` as the slot's default content).\n\t * Each provider is a reactive holder so consumers can `inject`\n\t * once and read `.value` whenever they render — Vue 2 reactivity\n\t * tracks the mutation site (the watchers below in `data()`).\n\t *\n\t * `cnPageSidebarVisible` default holder value is `true`, so when\n\t * `pages[].sidebar.show` is unset / `true`, behaviour matches\n\t * today (slot renders).\n\t *\n\t * `cnPageSidebarComponent` default holder value is `null`, so\n\t * when `pages[].sidebarComponent` is unset, the host App's\n\t * `#sidebar` slot renders its consumer-supplied content (or\n\t * nothing) — no behaviour change for apps that don't adopt the\n\t * field.\n\t */\n\tprovide() {\n\t\t// `self` is load-bearing: `cnSlotColumns` below is a GETTER, and inside\n\t\t// a getter on that object literal `this` is the literal — not the\n\t\t// component. The getter is what keeps the provide tracking the active\n\t\t// page, and a getter cannot be an arrow function.\n\t\t// eslint-disable-next-line @typescript-eslint/no-this-alias\n\t\tconst self = this\n\t\treturn {\n\t\t\t// Per-page slot→columns override (page.config.slotColumns), read by\n\t\t\t// CnWidgetGrid. A getter so it tracks the active page reactively\n\t\t\t// despite provide() running once.\n\t\t\tget cnSlotColumns() {\n\t\t\t\treturn self.currentPage?.config?.slotColumns ?? null\n\t\t\t},\n\n\t\t\tcnPageSidebarVisible: this.pageSidebarVisible,\n\t\t\tcnPageSidebarComponent: this.pageSidebarComponent,\n\t\t\t// Loaded object for a type:\"detail\" page (reactive holder). See\n\t\t\t// data().detailObjectContext. Descendant CnWidgetGrid reads this\n\t\t\t// to feed `objectData` / `schema` / `objectType` to detail widgets.\n\t\t\tcnDetailObjectContext: this.detailObjectContext,\n\t\t\t/**\n\t\t\t * Bound dispatchAction for the v2 render path. Child widget\n\t\t\t * components inject `cnDispatchAction` to dispatch manifest\n\t\t\t * actions. Context is pre-bound with this component's\n\t\t\t * $router and the injected cnRegistry; a caller may merge\n\t\t\t * extra context (e.g. CnWidgetObjectTable passes\n\t\t\t * `{ objectStore, source, row }` for `object-op` actions).\n\t\t\t * The dispatch result is returned so async `object-op`\n\t\t\t * dispatches can be awaited.\n\t\t\t *\n\t\t\t * @param {object} action The action to dispatch.\n\t\t\t * @param {object} [extraContext] Extra context merged over the pre-bound one.\n\t\t\t * @return {unknown} The dispatchAction return value (a promise for object-op).\n\t\t\t */\n\t\t\tcnDispatchAction: (action, extraContext = {}) => {\n\t\t\t\treturn dispatchAction(action, {\n\t\t\t\t\trouter: this.$router ?? null,\n\t\t\t\t\tregistry: this.cnRegistry,\n\t\t\t\t\thandlers: this.effectiveManifest?.actions ?? {},\n\t\t\t\t\topenModal: this._cnOpenModal,\n\t\t\t\t\t// `type:\"export\"` opens the shared CnMassExportDialog this\n\t\t\t\t\t// component mounts (Wave 1, nextcloud-vue#91).\n\t\t\t\t\topenExport: (exportAction) => {\n\t\t\t\t\t\tthis.exportAction = exportAction\n\t\t\t\t\t},\n\t\t\t\t\t// The host translate function, so an api-call/agent action's\n\t\t\t\t\t// manifest-authored success/error toast localises exactly\n\t\t\t\t\t// like the rest of the page chrome. Identity by default.\n\t\t\t\t\ttranslate: (key) => this.tr(key),\n\t\t\t\t\t...extraContext,\n\t\t\t\t})\n\t\t\t},\n\t\t}\n\t},\n\n\t/**\n\t * Forward listeners + attrs to the dispatched page component (B1).\n\t *\n\t * `inheritAttrs: false` opts the wrapping `.cn-page-renderer` <div>\n\t * out of Vue's default non-prop-attribute fallthrough, so attributes\n\t * the host passed to CnPageRenderer land on the dispatched page via\n\t * `v-bind=\"{ ...$attrs, ...resolvedProps }\"` instead. `v-on=\"$listeners\"`\n\t * does the same for events. Without this, built-in page components\n\t * that emit (CnDashboardPage `@widget-refresh` / `@widget-request-feature`,\n\t * CnIndexPage `@create` / `@edit` / `@delete`) cannot reach the host App.\n\t *\n\t * Resolved props win over `$attrs` on key collisions because the\n\t * spread order is `{ ...$attrs, ...resolvedProps }`.\n\t */\n\tinheritAttrs: false,\n\n\tprops: {\n\t\t/**\n\t\t * Manifest object. When omitted, falls back to the injected\n\t\t * `cnManifest` from a CnAppRoot ancestor. Provide explicitly when\n\t\t * mounting CnPageRenderer outside of CnAppRoot.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tmanifest: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Custom-component registry. Keys are the names referenced by\n\t\t * `page.component` (for `type: \"custom\"` pages). When omitted,\n\t\t * falls back to the injected `cnCustomComponents`.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tcustomComponents: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Translate function. When omitted, falls back to the injected\n\t\t * `cnTranslate`. Currently not used directly by the renderer\n\t\t * itself — exposed as a prop for symmetry and so future page\n\t\t * components rendered by the renderer can `inject('cnTranslate')`\n\t\t * via the consumer's setup.\n\t\t *\n\t\t * @type {((text: string, placeholders?: object) => string)|null}\n\t\t */\n\t\ttranslate: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Page-type registry. Map of `pages[].type` value → Vue\n\t\t * component to mount. Consumers extend the library defaults by\n\t\t * spreading them: `{ ...defaultPageTypes, report: MyReportPage }`.\n\t\t *\n\t\t * Falls back to the injected `cnPageTypes` and finally to the\n\t\t * library's `defaultPageTypes`. The special `custom` type is\n\t\t * NOT looked up here — it resolves through the customComponents\n\t\t * registry instead.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tpageTypes: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\t},\n\n\t/**\n\t * Live updates for the v2 widget-grid detail path (#222). A\n\t * `type:\"detail\"` page rendered through CnWidgetGrid gets its object\n\t * from the `cnDetailObjectContext` holder (see `loadDetailObject`),\n\t * NOT from a page component with its own subscription — so the\n\t * renderer itself subscribes to `or-object-{id}` for the loaded\n\t * object. The plugin's event-driven refetch then lands in\n\t * `store.objects[slug][id]`, which the holder reads through\n\t * reactively.\n\t *\n\t * The refs returned here are DRIVEN by `loadDetailObject`:\n\t * - `liveSubType` / `liveSubId` re-scope the subscription on route\n\t * or object change (the composable's epoch guard swaps handles).\n\t * - `liveSubEnabled` gates on (a) a v2 manifest page that actually\n\t * renders widget grids — the typed CnDetailPage dispatch path\n\t * manages its own subscription — and (b) the same\n\t * `config.subscribe: false` opt-out CnIndexPage / CnDetailPage\n\t * honour (manifest-live-updates).\n\t *\n\t * Laziness: `enabled` starts `false`, so mounting the renderer on\n\t * any non-detail page causes zero transport activity (resolving the\n\t * default store is inert per the plugin's laziness guarantee).\n\t * Unmount and route changes release via the composable's own\n\t * lifecycle; the polling fallback is the transport's concern.\n\t *\n\t * @return {object} Refs exposed on `this` for `loadDetailObject`.\n\t */\n\tsetup() {\n\t\tconst liveSubType = ref('')\n\t\tconst liveSubId = ref('')\n\t\tconst liveSubEnabled = ref(false)\n\t\tlet liveStore\n\t\ttry {\n\t\t\tliveStore = useObjectStore()\n\t\t} catch {\n\t\t\t// Pinia not installed (stand-alone / unit-test mounts) — no\n\t\t\t// live updates; loadDetailObject degrades the same way.\n\t\t\tliveStore = null\n\t\t}\n\t\tif (liveStore) {\n\t\t\tuseObjectSubscription(\n\t\t\t\tliveStore,\n\t\t\t\tliveSubType,\n\t\t\t\tliveSubId,\n\t\t\t\t{ enabled: () => Boolean(liveSubEnabled.value && liveSubType.value && liveSubId.value) },\n\t\t\t)\n\t\t}\n\t\treturn { liveSubType, liveSubId, liveSubEnabled }\n\t},\n\n\tdata() {\n\t\t// Reactive holders for the per-page sidebar visibility flag and\n\t\t// sidebar-component override. Both live on data() so Vue 2\n\t\t// reactivity tracks `.value` mutations in the watchers below;\n\t\t// `provide()` returns the same references so descendant injects\n\t\t// observe each update.\n\t\treturn {\n\t\t\tpageSidebarVisible: { value: true },\n\t\t\tpageSidebarComponent: { value: null },\n\t\t\t// Whether the per-page config modal (edit-mode cog) is open.\n\t\t\tshowConfigModal: false,\n\t\t\t// Reactive holder for the loaded object of a `type:\"detail\"`\n\t\t\t// page. `null` until the async load resolves (and on non-detail\n\t\t\t// pages). Shape when populated:\n\t\t\t// `{ objectData, schema, objectType, objectId, register, store }`.\n\t\t\t// Published via provide() as `cnDetailObjectContext` and read by\n\t\t\t// descendant CnWidgetGrid instances, which merge it into each\n\t\t\t// body/sidebar widget's props so `data` / `metadata` /\n\t\t\t// `file-manager` widgets receive the object with no per-widget\n\t\t\t// manifest props.\n\t\t\tdetailObjectContext: { value: null },\n\t\t\t// The `type:\"export\"` action currently shown in the shared\n\t\t\t// CnMassExportDialog export launcher (null = dialog closed). Set\n\t\t\t// by the `openExport` bound into the cnDispatchAction context.\n\t\t\texportAction: null,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * Whether the body slot should be editable (ADR-041). Unwraps the\n\t\t * injected `cnEditingBody`, which CnAppRoot provides as a raw ref.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tbodyEditable() {\n\t\t\tconst e = this.cnEditingBody\n\t\t\treturn Boolean(e && typeof e === 'object' && 'value' in e ? e.value : e)\n\t\t},\n\n\t\t/**\n\t\t * Convenience accessor on the reactive holder so the template\n\t\t * `v-bind:class` reads a primitive boolean. Vue 2 templates\n\t\t * unwrap `data` references but not arbitrary `{value}`\n\t\t * holders, so this stays explicit.\n\t\t */\n\t\tpageSidebarVisibleValue() {\n\t\t\treturn this.pageSidebarVisible.value !== false\n\t\t},\n\n\t\t/**\n\t\t * Entity options for the export launcher, from the active export\n\t\t * action's `entities[]` (empty hides the picker).\n\t\t *\n\t\t * @return {Array<{id: string, label: string}>}\n\t\t */\n\t\texportDialogEntities() {\n\t\t\tconst entities = this.exportAction && this.exportAction.entities\n\t\t\tif (!Array.isArray(entities)) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\treturn entities\n\t\t\t\t.map((e) => (typeof e === 'string' ? { id: e, label: e } : e))\n\t\t\t\t.filter((e) => e && e.id)\n\t\t},\n\n\t\t/**\n\t\t * Format options for the export launcher, from the active export\n\t\t * action's `formats[]` (bare ids are lifted to `{id, label}`).\n\t\t * `undefined` when the action declares none, so the dialog's\n\t\t * built-in Excel/CSV defaults apply.\n\t\t *\n\t\t * @return {Array<{id: string, label: string}>|undefined}\n\t\t */\n\t\texportDialogFormats() {\n\t\t\tconst formats = this.exportAction && this.exportAction.formats\n\t\t\tif (!Array.isArray(formats) || formats.length === 0) {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t\treturn formats\n\t\t\t\t.map((f) => (typeof f === 'string' ? { id: f, label: f.toUpperCase() } : f))\n\t\t\t\t.filter((f) => f && f.id)\n\t\t},\n\n\t\t/**\n\t\t * Effective manifest: explicit prop wins, then the reactive injected\n\t\t * source, then the one-shot `cnManifest` snapshot for hosts that\n\t\t * provide only that.\n\t\t */\n\t\teffectiveManifest() {\n\t\t\treturn this.manifest ?? this.cnManifestSource ?? this.cnManifest\n\t\t},\n\n\t\t/**\n\t\t * True when the effective manifest is a v2 manifest.\n\t\t * Detected by `manifest.$schema` containing `app-manifest-v2`.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tisV2Manifest() {\n\t\t\tconst schema = this.effectiveManifest?.$schema\n\t\t\treturn typeof schema === 'string' && schema.includes('app-manifest-v2')\n\t\t},\n\n\t\t/**\n\t\t * Groups the current page's `widgets[]` by slot value into a\n\t\t * `Map<string, WidgetEntry[]>`. Entries with unrecognised slot\n\t\t * patterns emit `console.warn` and are excluded.\n\t\t *\n\t\t * @return {Map<string, Array>}\n\t\t */\n\t\twidgetsBySlot() {\n\t\t\tconst page = this.currentPage\n\t\t\tconst map = new Map()\n\t\t\tif (!page || !Array.isArray(page.widgets)) {\n\t\t\t\treturn map\n\t\t\t}\n\n\t\t\tfor (const widget of page.widgets) {\n\t\t\t\tconst slot = widget?.slot\n\t\t\t\tif (!slot || !isKnownSlot(slot)) {\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.warn(`[CnPageRenderer] Widget \"${widget?.widgetKey}\" in page \"${page.id}\" has unrecognised slot \"${slot}\". Skipping.`)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif (!map.has(slot)) {\n\t\t\t\t\tmap.set(slot, [])\n\t\t\t\t}\n\t\t\t\tmap.get(slot).push(widget)\n\t\t\t}\n\n\t\t\treturn map\n\t\t},\n\n\t\t/**\n\t\t * Dynamic slot keys from widgetsBySlot that are not fixed known\n\t\t * slot names (i.e. `tab:*` and `section:*` patterns).\n\t\t *\n\t\t * @return {string[]}\n\t\t */\n\t\tdynamicSlotKeys() {\n\t\t\tconst FIXED_SLOTS = ['body', 'sidebar', 'header-actions', 'footer', 'modal']\n\t\t\tconst result = []\n\t\t\tfor (const key of this.widgetsBySlot.keys()) {\n\t\t\t\tif (!FIXED_SLOTS.includes(key)) {\n\t\t\t\t\tresult.push(key)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result\n\t\t},\n\n\t\t/**\n\t\t * Proxy for the cnOpenModal inject so the provide() closure can\n\t\t * reference `this._cnOpenModal` without binding issues.\n\t\t *\n\t\t * @return {?(key: string, props?: object) => void} The injected opener, or null.\n\t\t */\n\t\t_cnOpenModal() {\n\t\t\treturn typeof this.cnOpenModal === 'function' ? this.cnOpenModal : null\n\t\t},\n\n\t\t/** Effective custom-component registry. */\n\t\teffectiveCustomComponents() {\n\t\t\treturn this.customComponents ?? this.cnCustomComponents ?? {}\n\t\t},\n\n\t\t/**\n\t\t * Effective v2 component registry. Provided by CnAppRoot via the\n\t\t * `registry` prop (kind-tagged entries: `widget`, `modal`, `page`,\n\t\t * `form-field`, `cell-renderer`). Empty when consumers haven't\n\t\t * migrated off the legacy `customComponents` prop yet. ADR-036.\n\t\t *\n\t\t * @return {object}\n\t\t */\n\t\teffectiveRegistry() {\n\t\t\treturn this.cnRegistry ?? {}\n\t\t},\n\n\t\t/**\n\t\t * Effective page-type registry. Prop wins over inject; both\n\t\t * fall back to the library's `defaultPageTypes`. Apps that want\n\t\t * the library defaults plus extras typically construct the prop\n\t\t * value as `{ ...defaultPageTypes, ...myExtras }`.\n\t\t */\n\t\teffectivePageTypes() {\n\t\t\treturn this.pageTypes ?? this.cnPageTypes ?? defaultPageTypes\n\t\t},\n\n\t\t/**\n\t\t * The app this page needs but that is not installed, or null.\n\t\t *\n\t\t * Reads the page's `requiresApp` and answers with a dependency entry\n\t\t * shaped the way CnDependencyMissing expects, so the same screen the\n\t\t * app-level check uses is reused rather than a second one written.\n\t\t *\n\t\t * `isAppInstalled` is the SAME resolver `visibleIf.appInstalled` uses.\n\t\t * Deliberately so: a menu entry hidden by one predicate and a page\n\t\t * gated by a different one would drift, and the pair would disagree\n\t\t * about whether the app is there.\n\t\t *\n\t\t * @return {{id: string, name: string}|null} The missing app, or null.\n\t\t */\n\t\t/**\n\t\t * The permission this page declares and the user does not hold, or null.\n\t\t *\n\t\t * The schema has carried `pages[].permission` as SCHEMA-ONLY since it\n\t\t * was added: \"CnPageRenderer / CnAppRoot do NOT currently gate the page\n\t\t * on it; consumers that want enforcement filter the manifest themselves\".\n\t\t * No consumer did. So a page declaring it was hidden from the MENU by\n\t\t * CnAppNav and served to anyone who typed its URL, which is the worst of\n\t\t * the two: it reads as protected to whoever declared it.\n\t\t *\n\t\t * Measured on dossiq: a non-admin opening `/settings/integrations`\n\t\t * directly got the page with seven links into admin settings, while the\n\t\t * same account correctly saw no entry for it in the navigation.\n\t\t *\n\t\t * 🔑 THE SEMANTICS ARE CnAppNav's, DELIBERATELY, so the route and the\n\t\t * menu agree. An empty list still means \"the app did not say\" and\n\t\t * allows, exactly as the menu filter does. Refusing on an empty list\n\t\t * would hide every declared page in an app that passes no `permissions`\n\t\t * — which is the shape that once rendered an Admin-settings entry for\n\t\t * nobody — and that is a separate decision from closing this hole.\n\t\t *\n\t\t * @return {string|null} The missing permission, or null when allowed.\n\t\t */\n\t\tforbiddenPagePermission() {\n\t\t\tconst required = this.currentPage?.permission\n\t\t\tif (!required) {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\tconst held = Array.isArray(this.cnPermissions) ? this.cnPermissions : []\n\t\t\tif (held.length === 0) {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\treturn held.includes(required) ? null : required\n\t\t},\n\n\t\tmissingPageDependency() {\n\t\t\tconst required = this.currentPage?.requiresApp\n\t\t\tif (!required) {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\tconst id = (typeof required === 'string' ? required : required.id)\n\t\t\tif (!id || isAppInstalled(id)) {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tid,\n\t\t\t\tname: (typeof required === 'object' && required.name) || id,\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Heading for the page-level missing-dependency screen.\n\t\t *\n\t\t * Overridden away from CnDependencyMissing's default (\"Required apps\n\t\t * are missing\"), which is written for the app-level check where\n\t\t * NOTHING works. Here the app is fine and one feature is not, and\n\t\t * saying otherwise would send the reader looking for a broken install.\n\t\t *\n\t\t * @return {string} The heading.\n\t\t */\n\t\tmissingDependencyHeading() {\n\t\t\treturn this.tr('This feature needs another app')\n\t\t},\n\n\t\t/**\n\t\t * Intro for the page-level missing-dependency screen.\n\t\t *\n\t\t * @return {string} The intro line.\n\t\t */\n\t\tmissingDependencyIntro() {\n\t\t\tconst title = (this.currentPage?.title || '')\n\t\t\tif (title) {\n\t\t\t\treturn this.tr('\"{page}\" needs the following app to be installed and enabled.').replace('{page}', title)\n\t\t\t}\n\n\t\t\treturn this.tr('This page needs the following app to be installed and enabled.')\n\t\t},\n\n\t\t/**\n\t\t * Page definition matching the current route name, or null.\n\t\t *\n\t\t * @return {object|null} The manifest page entry.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tcurrentPage() {\n\t\t\t// `meta.cnPageId` first, the route name second. The split route\n\t\t\t// `/<page>/split/:id` is registered under `<pageId>__split`, so\n\t\t\t// matching on the name alone would resolve it to no page at all\n\t\t\t// and render a blank screen at a perfectly valid address.\n\t\t\t// `buildManifestRoutes()` stamps the meta; a hand-written router\n\t\t\t// has none, and there the route name IS the page id.\n\t\t\tconst pageId = pageIdForRoute(this.$route)\n\t\t\tif (!pageId) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn this.pageById.get(pageId) ?? null\n\t\t},\n\n\t\t/**\n\t\t * The record the split pane is showing, or null when this is not a\n\t\t * split route.\n\t\t *\n\t\t * @return {string|null} The record id.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tcurrentSplitId() {\n\t\t\treturn splitIdForRoute(this.$route)\n\t\t},\n\n\t\t/**\n\t\t * `Map<pageId, page>` built once per manifest identity (Vue caches this\n\t\t * computed until `effectiveManifest` changes), replacing per-recompute\n\t\t * linear `pages.find()` — O(n) per navigation on large manifests\n\t\t * (shillinq ships 223 pages). 2026-07-06 audit item 10.\n\t\t */\n\t\tpageById() {\n\t\t\tconst pages = this.effectiveManifest?.pages\n\t\t\tconst index = new Map()\n\t\t\tif (Array.isArray(pages)) {\n\t\t\t\tfor (const page of pages) {\n\t\t\t\t\tif (page && typeof page.id === 'string' && !index.has(page.id)) {\n\t\t\t\t\t\tindex.set(page.id, page)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn index\n\t\t},\n\n\t\t/**\n\t\t * `Map<\"register schema\", detailPage>` — the first detail page bound to\n\t\t * each register+schema pair. Backs the index→detail row-click wiring\n\t\t * without re-scanning all pages per index page and per row click.\n\t\t * Memoized on `effectiveManifest`.\n\t\t */\n\t\tdetailPageByRegisterSchema() {\n\t\t\tconst pages = this.effectiveManifest?.pages\n\t\t\tconst index = new Map()\n\t\t\tif (Array.isArray(pages)) {\n\t\t\t\tfor (const page of pages) {\n\t\t\t\t\tif (!page || page.type !== 'detail') {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tconst cfg = page.config || {}\n\t\t\t\t\tconst key = `${cfg.register} ${cfg.schema}`\n\t\t\t\t\tif (!index.has(key)) {\n\t\t\t\t\t\tindex.set(key, page)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn index\n\t\t},\n\n\t\t/**\n\t\t * Remount key for the dispatched page component. Includes the data source\n\t\t * (register + schema) so changing it in the page-config modal remounts the\n\t\t * page: the self-fetch composable binds its object type + schema once at\n\t\t * setup, so without a remount a data-source change would leave the old\n\t\t * columns, create/edit form, and \"Add\" label in place.\n\t\t *\n\t\t * @return {string} A key of `id:register:schema`.\n\t\t */\n\t\tpageRenderKey() {\n\t\t\tconst page = this.currentPage\n\t\t\tif (!page) {\n\t\t\t\treturn 'none'\n\t\t\t}\n\t\t\tconst cfg = (page.config && typeof page.config === 'object' && !Array.isArray(page.config)) ? page.config : {}\n\t\t\treturn [page.id, cfg.register || '', cfg.schema || ''].join(':')\n\t\t},\n\n\t\t/**\n\t\t * Component to render for the current page. Looked up in\n\t\t * `effectivePageTypes` for built-in / library / consumer-extended\n\t\t * types; resolved against `effectiveCustomComponents` for\n\t\t * `type: \"custom\"` pages.\n\t\t *\n\t\t * Async loading is the responsibility of whoever populated the\n\t\t * `pageTypes` map (the library wraps each entry in\n\t\t * `defineAsyncComponent`); the renderer treats any value in the\n\t\t * map as a Vue component.\n\t\t */\n\t\t/**\n\t\t * Whether the current page renders any body content — a dispatched page\n\t\t * component (index/detail/dashboard/custom-with-component) or a v2 `body`\n\t\t * widget slot. False for a freshly-created custom page with no component\n\t\t * and no widgets, which drives the builder empty-state (ADR-041) so the\n\t\t * page still exposes the \"Edit with Buildiq\" affordance.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\thasRenderableBody() {\n\t\t\tif (this.resolvedComponent) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif (this.isV2Manifest && this.widgetsBySlot && this.widgetsBySlot.has('body')) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn false\n\t\t},\n\n\t\t/**\n\t\t * The detail page a split pane mounts, resolved the same way the full\n\t\t * route resolves it.\n\t\t *\n\t\t * The SAME component, deliberately. A second detail implementation\n\t\t * for the pane would drift from the full page within a month, and the\n\t\t * first thing to drift is always the thing only one of them has.\n\t\t *\n\t\t * @return {object|null} The manifest page entry, or null when the index has no detail page.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tsplitDetailPage() {\n\t\t\tconst page = this.currentPage\n\t\t\tif (!pageHasSplitView(page)) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst cfg = page.config || {}\n\t\t\tconst named = typeof cfg.rowRoute === 'string' && cfg.rowRoute !== ''\n\t\t\t\t? this.pageById.get(cfg.rowRoute)\n\t\t\t\t: null\n\t\t\treturn named ?? this.detailPageByRegisterSchema.get(`${cfg.register} ${cfg.schema}`) ?? null\n\t\t},\n\n\t\t/**\n\t\t * The component the split pane renders.\n\t\t *\n\t\t * @return {object|null} The page component, or null.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tsplitPaneComponent() {\n\t\t\tconst detail = this.splitDetailPage\n\t\t\tif (!detail) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tif (detail.type === 'custom') {\n\t\t\t\treturn this.resolveCustomComponent(detail.component || detail.slots?.main, 'page') || null\n\t\t\t}\n\t\t\treturn this.effectivePageTypes[detail.type] || null\n\t\t},\n\n\t\t/**\n\t\t * The props the split pane's detail component is mounted with.\n\t\t *\n\t\t * Built from the detail page's own declaration, so the pane shows\n\t\t * what the full route would show, plus the id the split address\n\t\t * names.\n\t\t *\n\t\t * @return {object} The prop bag.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tsplitPaneProps() {\n\t\t\tconst detail = this.splitDetailPage\n\t\t\tconst id = this.currentSplitId\n\t\t\tif (!detail || !id) {\n\t\t\t\treturn {}\n\t\t\t}\n\t\t\tconst config = detail.config || {}\n\t\t\t// `objectId` only, never a bare `id`. CnDetailPage declares no\n\t\t\t// `id` prop, so a bare one falls through onto the pane's root\n\t\t\t// element as a plain HTML attribute, and the page then answers to\n\t\t\t// `#case-1` alongside the skip link's own anchor.\n\t\t\tconst props = { ...config, objectId: id }\n\t\t\tif (props.objectType === undefined && typeof config.schema === 'string' && config.schema !== '') {\n\t\t\t\tprops.objectType = config.schema\n\t\t\t}\n\t\t\tfor (const key of ['title', 'description', 'icon']) {\n\t\t\t\tif (detail[key] !== undefined) {\n\t\t\t\t\tprops[key] = detail[key]\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (detail.tabInAddress === true) {\n\t\t\t\tprops.tabInAddress = true\n\t\t\t}\n\t\t\tif (detail.primaryAction) {\n\t\t\t\tprops.primaryAction = detail.primaryAction\n\t\t\t}\n\t\t\treturn props\n\t\t},\n\n\t\tresolvedComponent() {\n\t\t\tconst page = this.currentPage\n\t\t\tif (!page) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tif (page.type === 'custom') {\n\t\t\t\t// Two authoring styles for a custom page body:\n\t\t\t\t// 1. `page.component` — a single registry component name.\n\t\t\t\t// 2. `page.slots.main` — the body component referenced via\n\t\t\t\t// the generic slot map (same field used for header /\n\t\t\t\t// actions / sidebar overrides). When `component` is\n\t\t\t\t// absent we treat the `main` slot entry as the page body\n\t\t\t\t// so a custom page authored purely with `slots` still\n\t\t\t\t// renders. The remaining slot entries continue to mount\n\t\t\t\t// as named slots inside it via `resolvedSlotEntries`.\n\t\t\t\tconst name = page.component || page.slots?.main\n\t\t\t\tconst resolved = this.resolveCustomComponent(name, 'page')\n\t\t\t\tif (!resolved) {\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.warn(`[CnPageRenderer] Custom component \"${name}\" not found in registry for page id \"${page.id}\".`)\n\t\t\t\t\treturn null\n\t\t\t\t}\n\t\t\t\treturn resolved\n\t\t\t}\n\t\t\tconst component = this.effectivePageTypes[page.type]\n\t\t\tif (!component) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.warn(`[CnPageRenderer] Unknown page type \"${page.type}\" for page id \"${page.id}\". Add it to the pageTypes registry (e.g. via the pageTypes prop on CnAppRoot or CnPageRenderer).`)\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn component\n\t\t},\n\n\t\t/**\n\t\t * Props forwarded to the dispatched page component. Merges:\n\t\t *\n\t\t * 1. The page's static `config` object — manifest-authored data\n\t\t * shared across every visit to this route.\n\t\t * 2. The router's `$route.params` — dynamic placeholders captured\n\t\t * from the URL (e.g. `/meetings/:id/live` → `{ id: '...' }`).\n\t\t * Without this merge, children that declare a route-derived\n\t\t * prop (`props: { id: { type: String, required: true } }`)\n\t\t * receive `undefined` even when the URL clearly contains the\n\t\t * value, because the generated route definition's `props: true`\n\t\t * only binds params to `CnPageRenderer` itself, not the\n\t\t * dispatched child component. Params take precedence over\n\t\t * `config` collisions so URL truth wins; config keeps acting\n\t\t * as a default-overrides layer.\n\t\t *\n\t\t * Per-type prop validation lives on the target components.\n\t\t *\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tresolvedProps() {\n\t\t\tconst page = this.currentPage\n\t\t\t// Normalise to a plain object: an empty `config: {}` round-trips\n\t\t\t// through PHP/JSON as `[]`, and spreading an array would silently\n\t\t\t// contribute no config keys (register/schema/columns) to the page.\n\t\t\tconst rawConfig = (page?.config && typeof page.config === 'object' && !Array.isArray(page.config)) ? page.config : {}\n\t\t\t// Clone params — `resolvedProps` MAY add normalised aliases\n\t\t\t// (e.g. `objectId` for type='detail') and we must not mutate\n\t\t\t// the live `$route.params` object.\n\t\t\tconst params = { ...(this.$route?.params ?? {}) }\n\t\t\t// `manifest-route-param-sentinel`: substitute every\n\t\t\t// `@route.<param>` string in the config subtree with the\n\t\t\t// matching `$route.params.<param>` value before any other\n\t\t\t// merge. Unresolved sentinels become null (with a one-shot\n\t\t\t// console.warn per pageId+sentinel).\n\t\t\tconst pageId = page?.id ?? '<unknown>'\n\t\t\tlet config = resolveRouteSentinels(rawConfig, params, pageId)\n\t\t\t// Schema v2 lifts a uniform set of page-level fields out of\n\t\t\t// `config` so every page type can declare them without\n\t\t\t// per-type schema branches. Forward those to the dispatched\n\t\t\t// component so they reach typed props (e.g.\n\t\t\t// CnDetailPage.title, CnDetailPage.widgets). Listed\n\t\t\t// explicitly to keep the prop surface minimal — schema\n\t\t\t// fields not in this list stay private to the renderer.\n\t\t\tconst topLevel = {}\n\t\t\tfor (const key of ['title', 'description', 'icon', 'widgets', 'actions', 'sidebar']) {\n\t\t\t\tif (page && page[key] !== undefined) {\n\t\t\t\t\ttopLevel[key] = page[key]\n\t\t\t\t}\n\t\t\t}\n\t\t\t// type:\"custom\" dispatches an app-authored component that usually\n\t\t\t// declares NONE of the lifted fields as props. Vue's attribute\n\t\t\t// fallthrough would then paint them onto the component's root\n\t\t\t// element as plain HTML attributes — `title=\"Vault\"` becomes a\n\t\t\t// browser tooltip hovering over the ENTIRE page, and icon/widgets\n\t\t\t// turn into junk markup. Forward a lifted field to a custom\n\t\t\t// component only when its definition actually declares the prop.\n\t\t\tif (page?.type === 'custom') {\n\t\t\t\t// A defineAsyncComponent wrapper exposes no `props` until its\n\t\t\t\t// loader resolves — unwrap the resolved definition when\n\t\t\t\t// available so a lazily-registered custom page still receives\n\t\t\t\t// its declared lifted fields. Before resolution the fields\n\t\t\t\t// are withheld, which is the safe default here: withheld\n\t\t\t\t// means no stray root attributes, and the async component\n\t\t\t\t// renders nothing yet anyway.\n\t\t\t\tconst resolved = this.resolvedComponent\n\t\t\t\tconst declared = (resolved?.__asyncResolved ?? resolved)?.props\n\t\t\t\tconst declares = (key) => (Array.isArray(declared)\n\t\t\t\t\t? declared.includes(key)\n\t\t\t\t\t: Boolean(declared && key in declared))\n\t\t\t\tfor (const key of Object.keys(topLevel)) {\n\t\t\t\t\tif (!declares(key)) {\n\t\t\t\t\t\tdelete topLevel[key]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// NOTE on ADR-036 page-level `widgets[]`: it is NOT translated into\n\t\t\t// the typed component's `widgets` + `layout` props here.\n\t\t\t//\n\t\t\t// An earlier cut of this fix did exactly that, and the suite caught\n\t\t\t// why it is wrong: body widgets on the widget-grid path are fed\n\t\t\t// their object context by the live-context HOLDER\n\t\t\t// (`detailObjectContext`, #222) — subscription, re-render on store\n\t\t\t// cache updates, re-scoping when the route object changes. Handing\n\t\t\t// the widgets to the typed component instead silently dropped all\n\t\t\t// of that; `CnPageRendererV2DetailLiveContext` went red on the\n\t\t\t// widget rendering \"none\" where the holder had been supplying the\n\t\t\t// object.\n\t\t\t//\n\t\t\t// So the widgets keep being rendered by CnWidgetGrid, with the\n\t\t\t// holder intact. The typed component supplies only what was\n\t\t\t// actually missing — its chrome — by hosting the grid in its\n\t\t\t// default slot (see the template).\n\t\t\t// `config.actionToggles` is a typed object sugaring the nine\n\t\t\t// show*/selectable toggles on type='index' pages. Flatten\n\t\t\t// each key into the top-level config namespace UNDER any\n\t\t\t// explicit config.<key> (so explicit wins). Strip the\n\t\t\t// container before forwarding — CnIndexPage has no\n\t\t\t// `actionToggles` prop.\n\t\t\tconst isIndex = page?.type === 'index'\n\t\t\t// When an index page has somewhere to open a row, make a row click\n\t\t\t// go there: set `rowClickToView` so the row body emits `row-click`\n\t\t\t// (→ onRowOpen navigates) even though the page is selectable.\n\t\t\t// Selection stays available via the checkbox. An explicit\n\t\t\t// `config.rowClickToView` still wins (merged below).\n\t\t\t//\n\t\t\t// Two ways to have somewhere to open:\n\t\t\t// 1. `config.rowRoute` — an explicit route/page NAME. Needed\n\t\t\t// whenever the row's detail surface is NOT a `type:\"detail\"`\n\t\t\t// page: a `type:\"custom\"` authoring canvas, a form page, a\n\t\t\t// page in another register. Without this the key parsed,\n\t\t\t// validated and did nothing, so a manifest that authored it\n\t\t\t// shipped an index whose rows were simply dead on click\n\t\t\t// (observed on hermiq GraphIndex → GraphDetail).\n\t\t\t// 2. A matching `type:\"detail\"` page (same register + schema).\n\t\t\tif (isIndex && pageHasSplitView(page)) {\n\t\t\t\t// The split view and the record it is showing. `splitId` comes\n\t\t\t\t// from the route rather than from config, because the address\n\t\t\t\t// is the source of truth for which record is open: that is\n\t\t\t\t// what makes the split view a place you can link to.\n\t\t\t\ttopLevel.splitView = page.splitView\n\t\t\t\ttopLevel.splitId = this.currentSplitId || ''\n\t\t\t\ttopLevel.splitCloseRoute = page.id\n\t\t\t}\n\t\t\tif (isIndex && page?.manualOrder === true) {\n\t\t\t\ttopLevel.manualOrder = true\n\t\t\t\ttopLevel.manualOrderId = page.id\n\t\t\t}\n\t\t\tif (isIndex) {\n\t\t\t\tconst hasRowRoute = typeof config.rowRoute === 'string' && config.rowRoute !== ''\n\t\t\t\tconst hasDetail = this.detailPageByRegisterSchema.has(`${config.register} ${config.schema}`)\n\t\t\t\tif (hasRowRoute || hasDetail || pageHasSplitView(page)) {\n\t\t\t\t\ttopLevel.rowClickToView = true\n\t\t\t\t\t// The View row action links to where a row click opens.\n\t\t\t\t\ttopLevel.viewTo = (row) => this.rowOpenTarget(row)\n\t\t\t\t} else if (config.rowClickToView === true) {\n\t\t\t\t\t// Nowhere to open a row, so the click selects instead of doing nothing.\n\t\t\t\t\tconfig = { ...config, rowClickToView: false }\n\t\t\t\t}\n\t\t\t\t// `editOpensDetail` is NOT derived from that signal. It used to be,\n\t\t\t\t// on the reasoning that a record with a detail page is better edited\n\t\t\t\t// there than in a modal of flat scalars. But `@editOpen` is bound to\n\t\t\t\t// the same `onRowOpen` as `@rowClick`, so the result was an Edit that\n\t\t\t\t// did precisely what clicking the row does — the pane on a split\n\t\t\t\t// view, the detail page otherwise — and no way left to reach the\n\t\t\t\t// form. Opening a record and editing it are different acts and get\n\t\t\t\t// different affordances. A page that does want the old routing asks\n\t\t\t\t// for it with `config.editOpensDetail: true`.\n\t\t\t}\n\t\t\tlet normalizedConfig = config\n\t\t\tif (isIndex && config.actionToggles && typeof config.actionToggles === 'object' && !Array.isArray(config.actionToggles)) {\n\t\t\t\tconst { actionToggles, ...rest } = config\n\t\t\t\tnormalizedConfig = { ...actionToggles, ...rest }\n\t\t\t}\n\t\t\t// Type='detail' object-context mapping. The manifest declares\n\t\t\t// `config.schema` and `:id` route param; CnDetailPage's\n\t\t\t// sidebar gating needs `objectType` + `objectId` props (see\n\t\t\t// CnDetailPage.syncSidebarState — `objectSidebarState.active`\n\t\t\t// stays false without them, so the host's mounted\n\t\t\t// CnObjectSidebar never renders). Bridge the names here so\n\t\t\t// every consumer doesn't have to duplicate the alias in its\n\t\t\t// own customComponents wrapper. Only fills when the typed\n\t\t\t// prop is unset, so `config.objectType` or\n\t\t\t// `params.objectId` still wins.\n\t\t\tconst isDetail = page?.type === 'detail'\n\t\t\tif (isDetail && page.tabInAddress === true) {\n\t\t\t\ttopLevel.tabInAddress = true\n\t\t\t}\n\t\t\tif (isDetail && page.primaryAction) {\n\t\t\t\ttopLevel.primaryAction = page.primaryAction\n\t\t\t}\n\t\t\tif (isDetail) {\n\t\t\t\t// The other half of the index rule above: a schema-bound detail\n\t\t\t\t// page gets its own Edit affordance. Set unconditionally for\n\t\t\t\t// schema-bound detail pages — the index stops offering the modal\n\t\t\t\t// for exactly this set of pages, so a detail page that did not\n\t\t\t\t// gain the button would leave its records with no edit surface at\n\t\t\t\t// all. `config.showEditAction` still wins (merged below).\n\t\t\t\tif (typeof normalizedConfig.schema === 'string' && normalizedConfig.schema.length > 0) {\n\t\t\t\t\ttopLevel.showEditAction = true\n\t\t\t\t}\n\t\t\t\tif (normalizedConfig.objectType === undefined && typeof normalizedConfig.schema === 'string' && normalizedConfig.schema.length > 0) {\n\t\t\t\t\tnormalizedConfig = { ...normalizedConfig, objectType: normalizedConfig.schema }\n\t\t\t\t}\n\t\t\t\tif (params.objectId === undefined && typeof params.id === 'string' && params.id.length > 0) {\n\t\t\t\t\tparams.objectId = params.id\n\t\t\t\t}\n\t\t\t\tconst listPage = this.listPageForDetail(normalizedConfig)\n\t\t\t\tif (listPage) {\n\t\t\t\t\ttopLevel.notFoundRoute = { name: listPage.id }\n\t\t\t\t\ttopLevel.notFoundRouteLabel = this.tr(listPage.title || listPage.id)\n\t\t\t\t}\n\t\t\t}\n\t\t\t// `config.readOnly:true` shorthand on type='index' (REQ-MIPFU-4):\n\t\t\t// expand to the nine read-only flags MERGED UNDER `config.*`\n\t\t\t// so explicit `config.showAdd:true` still wins. Strip the\n\t\t\t// `readOnly` key before forwarding — CnIndexPage has no\n\t\t\t// `readOnly` prop.\n\t\t\tif (isIndex && normalizedConfig.readOnly === true) {\n\t\t\t\tconst { readOnly, ...rest } = normalizedConfig\n\t\t\t\treturn { ...topLevel, ...READ_ONLY_DEFAULTS, ...rest, ...params }\n\t\t\t}\n\t\t\t// `config.createOverride` can be declared in the JSON manifest as a\n\t\t\t// STRING naming an async create handler the consumer registered in\n\t\t\t// its customComponents registry (functions are valid registry\n\t\t\t// values). Resolve it to the function so CnIndexPage's per-schema\n\t\t\t// create-override hook fires from a purely declarative page. A\n\t\t\t// non-string value (an actual function passed programmatically) is\n\t\t\t// left untouched. Unresolved names are dropped with a one-shot warn.\n\t\t\tif (isIndex && typeof normalizedConfig.createOverride === 'string') {\n\t\t\t\tconst name = normalizedConfig.createOverride\n\t\t\t\tconst fn = this.resolveCreateOverride(name)\n\t\t\t\tconst { createOverride, ...rest } = normalizedConfig\n\t\t\t\tif (typeof fn === 'function') {\n\t\t\t\t\tnormalizedConfig = { ...rest, createOverride: fn }\n\t\t\t\t} else {\n\t\t\t\t\t// eslint-disable-next-line no-console -- a deliberate warning to the developer integrating this component\n\t\t\t\t\tconsole.warn(`[CnPageRenderer] config.createOverride \"${name}\" did not resolve to a registered function; dropping it.`)\n\t\t\t\t\tnormalizedConfig = rest\n\t\t\t\t}\n\t\t\t}\n\t\t\t// A named entity source loads with the `sourceConfig` PROP, and the\n\t\t\t// renderer never set it: config keys spread as individual props, so\n\t\t\t// `config.app` (flows) or `config.scope` (tasks) reached the page as\n\t\t\t// inert attributes and the loader received `{}`. Hand the resolved\n\t\t\t// config through as the default `sourceConfig` — the loader picks\n\t\t\t// the keys it knows and ignores the rest. An explicit\n\t\t\t// `config.sourceConfig` block still wins unchanged.\n\t\t\tif (isIndex\n\t\t\t\t&& typeof normalizedConfig.entitySource === 'string'\n\t\t\t\t&& normalizedConfig.entitySource.length > 0\n\t\t\t\t&& normalizedConfig.sourceConfig === undefined) {\n\t\t\t\tnormalizedConfig = { ...normalizedConfig, sourceConfig: { ...normalizedConfig } }\n\t\t\t}\n\t\t\t// Precedence (highest wins): route params > config > top-level\n\t\t\t// page fields. URL truth trumps everything; config trumps\n\t\t\t// top-level so per-route config still beats the page default.\n\t\t\treturn { ...topLevel, ...normalizedConfig, ...params }\n\t\t},\n\n\t\t/**\n\t\t * Resolved `{ register, schema, objectId, slug }` for a\n\t\t * `type:\"detail\"` page, or `null` for any other page (or when the\n\t\t * triple is incomplete). `objectId` comes from the resolved\n\t\t * `config.idParam` (a `@route.*` sentinel like `\"@route.id\"`),\n\t\t * falling back to `config.objectId`, the `:objectId` route param,\n\t\t * then the `:id` route param. `slug` is the `${register}-${schema}`\n\t\t * object-type key registered in the store (matches the convention\n\t\t * used by `autoRegisterCustomTypes` and CnIndexPage self-fetch).\n\t\t *\n\t\t * Drives `loadDetailObject` (watched below). Kept separate from\n\t\t * `resolvedProps` so the (potentially async) object load only runs\n\t\t * for detail pages and only re-runs when the triple changes.\n\t\t *\n\t\t * @return {{register: string, schema: string, objectId: string, slug: string}|null}\n\t\t */\n\t\tdetailLoadContext() {\n\t\t\t// A split address resolves to the INDEX page, so the pane's record\n\t\t\t// needs the detail page the pane mounts. Without it the pane got no\n\t\t\t// object context at all and every `@object.<field>` token in it\n\t\t\t// resolved against nothing.\n\t\t\tconst onDetailRoute = this.currentPage?.type === 'detail'\n\t\t\tconst splitId = this.currentSplitId\n\t\t\tconst page = onDetailRoute\n\t\t\t\t? this.currentPage\n\t\t\t\t: (splitId ? this.splitDetailPage : null)\n\t\t\tif (!page || page.type !== 'detail') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst params = { ...(this.$route?.params ?? {}) }\n\t\t\tconst config = resolveRouteSentinels(page.config ?? {}, params, page.id ?? '<unknown>')\n\t\t\tconst register = config.register\n\t\t\tconst schema = config.schema\n\t\t\t// The split address names the record, not the detail page's idParam.\n\t\t\tconst objectId = onDetailRoute\n\t\t\t\t? (config.idParam || config.objectId || params.objectId || params.id)\n\t\t\t\t: splitId\n\t\t\tif (typeof register !== 'string' || register.length === 0\n\t\t\t\t|| typeof schema !== 'string' || schema.length === 0\n\t\t\t\t|| typeof objectId !== 'string' || objectId.length === 0) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn { register, schema, objectId, slug: `${register}-${schema}` }\n\t\t},\n\n\t\t/**\n\t\t * Combined slot-override map for the dispatched page component.\n\t\t * Sources:\n\t\t * 1. `page.slots` — generic { slotName: registryName } map.\n\t\t * 2. `page.headerComponent` — sugar for `slots.header`.\n\t\t * 3. `page.actionsComponent` — sugar for `slots.actions`.\n\t\t *\n\t\t * Sugar fields take precedence when both are set so that the\n\t\t * legacy fields remain meaningful in mixed manifests. Returned\n\t\t * as an array of `{ name, component }` entries to make the\n\t\t * `<template v-for>` + dynamic-slot-name pattern work in Vue 2.\n\t\t */\n\t\t/**\n\t\t * The DETAIL page's own slot components, for the record mounted in the\n\t\t * split pane.\n\t\t *\n\t\t * `resolvedSlotEntries` belongs to the index page and cannot serve here:\n\t\t * the pane mounts a different manifest page, and a `type: \"custom\"` widget\n\t\t * resolves through its host page's `slots` map and nothing else. Without\n\t\t * this the pane drew an empty grid cell wherever the detail page declared\n\t\t * one — the same widget renders correctly on its own route, so the record\n\t\t * silently lost content by being opened beside the list instead of from it.\n\t\t *\n\t\t * @return {Array<{name: string, component: object}>}\n\t\t */\n\t\tsplitPaneSlotEntries() {\n\t\t\tconst page = this.splitDetailPage\n\t\t\tif (!page) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\t// Same two sugar keys `resolvedSlotEntries` maps for the full route,\n\t\t\t// or the pane silently drops the page's actions component.\n\t\t\tconst map = { ...(page.slots ?? {}) }\n\t\t\tif (page.headerComponent) {\n\t\t\t\tmap.header = page.headerComponent\n\t\t\t}\n\t\t\tif (page.actionsComponent) {\n\t\t\t\tmap.actions = page.actionsComponent\n\t\t\t}\n\t\t\tconst entries = []\n\t\t\tfor (const [name, registryName] of Object.entries(map)) {\n\t\t\t\tconst component = this.resolveRegistryName(registryName, name)\n\t\t\t\tif (component) {\n\t\t\t\t\tentries.push({ name, component })\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn entries\n\t\t},\n\n\t\tresolvedSlotEntries() {\n\t\t\tconst page = this.currentPage\n\t\t\tif (!page) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\tconst map = { ...(page.slots ?? {}) }\n\t\t\t// For a custom page that has no explicit `component`, `slots.main`\n\t\t\t// is promoted to the page BODY by `resolvedComponent`, so drop it\n\t\t\t// here — otherwise it would also try to mount as a (non-existent)\n\t\t\t// `main` named slot inside itself.\n\t\t\tif (page.type === 'custom' && !page.component && map.main) {\n\t\t\t\tdelete map.main\n\t\t\t}\n\t\t\tif (page.headerComponent) {\n\t\t\t\tmap.header = page.headerComponent\n\t\t\t}\n\t\t\tif (page.actionsComponent) {\n\t\t\t\tmap.actions = page.actionsComponent\n\t\t\t}\n\t\t\tconst entries = []\n\t\t\tfor (const [name, registryName] of Object.entries(map)) {\n\t\t\t\tconst component = this.resolveRegistryName(registryName, name)\n\t\t\t\tif (component) {\n\t\t\t\t\tentries.push({ name, component })\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn entries\n\t\t},\n\n\t\t/**\n\t\t * Per-page sidebar visibility flag derived from the page\n\t\t * entry's top-level `sidebar.show` field (sibling of `config`).\n\t\t * Defaults to `true` when unset. Watched below to push the\n\t\t * value into the reactive `pageSidebarVisible` holder shared\n\t\t * via provide/inject with `CnAppRoot`.\n\t\t */\n\t\tcurrentPageSidebarVisible() {\n\t\t\tconst page = this.currentPage\n\t\t\tif (!page || !page.sidebar || typeof page.sidebar !== 'object') {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn page.sidebar.show !== false\n\t\t},\n\n\t\t/**\n\t\t * Per-page sidebar component derived from the page entry's\n\t\t * top-level `sidebarComponent` field (sibling of `config`).\n\t\t * The string is resolved against the effective\n\t\t * `customComponents` registry — same registry as\n\t\t * `headerComponent`, `actionsComponent`, `cardComponent`, and\n\t\t * `slots.*`. Returns `null` when the field is unset, the\n\t\t * registry name is missing, or resolution fails (a\n\t\t * `console.warn` is logged in the missing-name case so\n\t\t * manifest authors notice misconfiguration). Watched below to\n\t\t * push the value into the reactive `pageSidebarComponent`\n\t\t * holder shared via provide/inject with `CnAppRoot`.\n\t\t *\n\t\t * @return {object|null} The resolved Vue component, or null.\n\t\t */\n\t\tcurrentPageSidebarComponent() {\n\t\t\tconst page = this.currentPage\n\t\t\tif (!page || typeof page.sidebarComponent !== 'string' || page.sidebarComponent.length === 0) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst name = page.sidebarComponent\n\t\t\tconst resolved = this.resolveCustomComponent(name, 'page')\n\t\t\tif (!resolved) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.warn(`[CnPageRenderer] Sidebar component \"${name}\" referenced by page id \"${page.id}\" not found in registry or customComponents.`)\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn resolved\n\t\t},\n\n\t\t/**\n\t\t * @deprecated Use `resolvedSlotEntries` for general slot\n\t\t * resolution. Retained for compatibility with code that read the\n\t\t * computed directly.\n\t\t */\n\t\theaderOverride() {\n\t\t\treturn this.resolvedSlotEntries.find((e) => e.name === 'header')?.component ?? null\n\t\t},\n\n\t\t/**\n\t\t * @deprecated See `headerOverride`.\n\t\t */\n\t\tactionsOverride() {\n\t\t\treturn this.resolvedSlotEntries.find((e) => e.name === 'actions')?.component ?? null\n\t\t},\n\t},\n\n\twatch: {\n\t\t/**\n\t\t * Auto-register object types for `type:\"custom\"` pages whose\n\t\t * manifest config declares `register` + `schema` (single type)\n\t\t * and/or `types: [{ name, register, schema }, ...]` (multi-type).\n\t\t *\n\t\t * For `type:\"index\"` and `type:\"detail\"` pages, the underlying\n\t\t * CnIndexPage / CnDetailPage components self-register when\n\t\t * mounted with `register` + `schema` props — so the renderer\n\t\t * does nothing extra for those. Custom components have no such\n\t\t * guarantee: they are bespoke per-app Vue components and would\n\t\t * each have to remember to call `registerObjectType` in their\n\t\t * own `mounted()` hook. Mirroring index/detail's zero-config\n\t\t * behaviour for the manifest-driven custom case (declared\n\t\t * `register` + `schema`) keeps the manifest the single source\n\t\t * of truth and removes a per-component landmine.\n\t\t *\n\t\t * Runs `immediate: true` so first mount registers before the\n\t\t * custom component's mounted() hook fires; re-runs on route\n\t\t * change in case the same CnPageRenderer instance is reused\n\t\t * for a different `type:\"custom\"` page.\n\t\t *\n\t\t * Defensive: every step is wrapped — a Pinia-not-installed\n\t\t * test harness, a missing store method, or a thrown error\n\t\t * inside `registerObjectType` all degrade to a single\n\t\t * `console.warn` so the page still mounts.\n\t\t *\n\t\t * See issue ConductionNL/nextcloud-vue#341.\n\t\t */\n\t\tcurrentPage: {\n\t\t\timmediate: true,\n\t\t\thandler() {\n\t\t\t\tthis.autoRegisterCustomTypes()\n\t\t\t},\n\t\t},\n\n\t\tcurrentPageSidebarVisible: {\n\t\t\timmediate: true,\n\t\t\thandler(visible) {\n\t\t\t\t// Mutate the shared holder's `.value` so descendant\n\t\t\t\t// injects (notably CnAppRoot) re-render the slot gate.\n\t\t\t\tthis.pageSidebarVisible.value = visible\n\t\t\t\t// When BOTH visibility is off AND a sidebar component\n\t\t\t\t// was declared, the sidebarComponent is dead config.\n\t\t\t\t// Log once at watcher flush time so manifest authors\n\t\t\t\t// notice the misconfiguration. Visibility wins — the\n\t\t\t\t// component holder still carries the resolved value\n\t\t\t\t// for downstream consumers that inspect it directly.\n\t\t\t\tif (visible === false && this.currentPage?.sidebarComponent) {\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.warn(`[CnPageRenderer] Page id \"${this.currentPage.id}\" declares both sidebar.show: false and sidebarComponent \"${this.currentPage.sidebarComponent}\". Visibility wins; the sidebarComponent will not render.`)\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\n\t\tcurrentPageSidebarComponent: {\n\t\t\timmediate: true,\n\t\t\thandler(component) {\n\t\t\t\t// Mutate the shared holder's `.value` so descendant\n\t\t\t\t// injects (notably CnAppRoot) re-render the slot\n\t\t\t\t// default content with the resolved component.\n\t\t\t\tthis.pageSidebarComponent.value = component\n\t\t\t},\n\t\t},\n\n\t\t/**\n\t\t * Load (and reload on change) the object backing a `type:\"detail\"`\n\t\t * page so its body/sidebar widgets can render it. Runs\n\t\t * `immediate: true` so the first paint kicks the fetch; re-runs\n\t\t * whenever the register/schema/objectId triple changes (e.g.\n\t\t * navigating between two detail routes on the same renderer).\n\t\t * Clears the context on non-detail pages.\n\t\t */\n\t\tdetailLoadContext: {\n\t\t\timmediate: true,\n\t\t\tdeep: true,\n\t\t\thandler() {\n\t\t\t\tthis.loadDetailObject()\n\t\t\t},\n\t\t},\n\t},\n\n\tcreated() {\n\t\t// Surface the page id in Vue devtools and stack traces. The base\n\t\t// component name `CnPageRenderer` becomes `CnPageRenderer:<id>`\n\t\t// for the lifetime of this instance.\n\t\tif (this.currentPage) {\n\t\t\tthis.$options.name = `CnPageRenderer:${this.currentPage.id}`\n\t\t} else if (this.$route) {\n\t\t\t// Router is present but no page matches — warn so developers notice misconfigured routes.\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.warn(`[CnPageRenderer] No page found for $route.name = \"${this.$route.name}\". The renderer will mount nothing.`)\n\t\t}\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Resolve a UI string through the consumer's translate function\n\t\t * (`translate` prop, else injected `cnTranslate`), falling back to the\n\t\t * English source key. Used for the builder empty-state copy.\n\t\t *\n\t\t * @param {string} key The English source string.\n\t\t * @return {string} The translated (or source) string.\n\t\t */\n\t\ttr(key) {\n\t\t\tconst fn = this.translate || this.cnTranslate\n\t\t\treturn typeof fn === 'function' ? fn(key) : key\n\t\t},\n\n\t\t/**\n\t\t * The index page a detail page returns to: the list named in the\n\t\t * address (`_from`), else the first index page on the same register and\n\t\t * schema.\n\t\t *\n\t\t * @param {object} config The detail page's normalized config.\n\t\t * @return {object|null} The manifest page, or null when there is none.\n\t\t */\n\t\tlistPageForDetail(config) {\n\t\t\tconst fromId = listContextFromRoute(this.$route)?.pageId\n\t\t\tconst from = fromId ? this.pageById.get(fromId) : null\n\t\t\tif (from?.type === 'index') {\n\t\t\t\treturn from\n\t\t\t}\n\t\t\tconst pages = this.effectiveManifest?.pages\n\t\t\tif (!Array.isArray(pages) || !config.schema) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn pages.find((p) => p?.type === 'index'\n\t\t\t\t&& p.config?.register === config.register\n\t\t\t\t&& p.config?.schema === config.schema) ?? null\n\t\t},\n\n\t\t/**\n\t\t * Route the export launcher's confirm payload (`{ format, entity? }`)\n\t\t * to the export action's `handler` (resolved against the manifest\n\t\t * actions map — the same registry `type:\"handler\"` actions use). The\n\t\t * handler does the actual download (e.g. an app's ExportService) and\n\t\t * its resolved/rejected promise drives the dialog's result phase. A\n\t\t * missing handler surfaces as a dialog error (never a silent success).\n\t\t *\n\t\t * @param {{format: string, entity?: string}} payload The dialog's confirm payload.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync onExportConfirm(payload) {\n\t\t\tconst action = this.exportAction\n\t\t\tconst dialog = this.$refs.exportDialog\n\t\t\tconst setResult = (result) => {\n\t\t\t\tif (dialog && typeof dialog.setResult === 'function') {\n\t\t\t\t\tdialog.setResult(result)\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst handlers = this.effectiveManifest?.actions ?? {}\n\t\t\tconst fn = action && action.handler && handlers[action.handler]\n\t\t\tif (typeof fn !== 'function') {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.warn(`[CnPageRenderer] export action \"${action && action.id}\" has no resolvable handler \"${action && action.handler}\" in the manifest actions map.`)\n\t\t\t\tsetResult({ error: t('nextcloud-vue', 'No export handler is configured') })\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait fn(payload, action)\n\t\t\t\tsetResult({ success: true })\n\t\t\t} catch (e) {\n\t\t\t\tsetResult({ error: (e && e.message) || t('nextcloud-vue', 'Export failed') })\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Open a row's detail page. Bound to an index page's `@view` (the\n\t\t * built-in eye action) and `@row-click`, this is what makes \"View\"\n\t\t * navigate for manifest-driven index pages — `CnIndexPage` only emits\n\t\t * the event, so without this the action is a no-op. Resolves the\n\t\t * matching `type: 'detail'` page (same `register` + `schema` as the\n\t\t * current index page) and pushes to it with the row's id in whichever\n\t\t * param that page's route declares — `:id`, `:objectId`, anything.\n\t\t * No-ops when there is no detail page, no router, or no resolvable id.\n\t\t * A ctrl/cmd/shift or middle click opens the same address in a new tab.\n\t\t *\n\t\t * @param {object} row The clicked / viewed row object.\n\t\t * @param {MouseEvent} [event] The originating click/auxclick event, when there is one.\n\t\t * @return {void}\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tonRowOpen(row, event) {\n\t\t\t// Only a native event can ask for a new tab.\n\t\t\tconst nativeEvent = (typeof Event !== 'undefined' && event instanceof Event) ? event : undefined\n\t\t\t// The index page already opened this row in a new tab.\n\t\t\tif (isNewTabHandled(nativeEvent)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst target = this.rowOpenTarget(row, true)\n\t\t\tif (target) {\n\t\t\t\topenRowTarget(nativeEvent, target, this.$router)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Where an index row opens: the split view beside the list, else\n\t\t * `config.rowRoute` or the matching detail page. Also the target of the\n\t\t * View row action's link.\n\t\t *\n\t\t * @param {object} row The row.\n\t\t * @param {boolean} [warn] Log a misconfigured route (on a click, not per render).\n\t\t * @return {object|null} The router location, or null when the row opens nowhere.\n\t\t */\n\t\trowOpenTarget(row, warn = false) {\n\t\t\tconst page = this.currentPage\n\t\t\tconst router = this.$router\n\t\t\tif (!page || page.type !== 'index' || !router || !row || typeof row !== 'object') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst cfg = page.config || {}\n\t\t\tconst self0 = row['@self'] || {}\n\t\t\tconst rowId = row.id ?? self0.id ?? self0.uuid ?? row.uuid\n\t\t\t// A page declaring a split view opens the row BESIDE the list, at\n\t\t\t// its own address, rather than navigating away from it. This\n\t\t\t// branch comes first and is deliberately unconditional on\n\t\t\t// `config.rowRoute`: the split view is the page saying where its\n\t\t\t// rows open, and it is a stronger statement than a route name,\n\t\t\t// because it also says the list must not unmount.\n\t\t\tif (pageHasSplitView(page) && rowId !== undefined && rowId !== null && rowId !== '') {\n\t\t\t\tconst splitName = splitRouteName(page.id)\n\t\t\t\tif (this.routeNameIsKnown(splitName) === false) {\n\t\t\t\t\tif (warn) {\n\t\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\t\tconsole.warn(`[CnPageRenderer] Index page \"${page.id}\" declares splitView, but the router has no \"${splitName}\" route. Build the routes with buildManifestRoutes() or the split view cannot open.`)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst splitPath = routePathFor(router, splitName)\n\t\t\t\t\treturn {\n\t\t\t\t\t\tname: splitName,\n\t\t\t\t\t\tparams: buildRouteParams(splitPath, rowId, this.$route?.params),\n\t\t\t\t\t\tquery: this.$route?.query || {},\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// `config.rowRoute` names the target explicitly and WINS: it is the\n\t\t\t// only way to reach a detail surface that is not a `type:\"detail\"`\n\t\t\t// page (an authoring canvas, a form page), and an author who named\n\t\t\t// a route meant that route.\n\t\t\tconst rowRoute = (typeof cfg.rowRoute === 'string' && cfg.rowRoute !== '') ? cfg.rowRoute : null\n\t\t\tconst detail = this.detailPageByRegisterSchema.get(`${cfg.register} ${cfg.schema}`)\n\t\t\tconst target = rowRoute ?? detail?.id ?? null\n\t\t\tif (!target) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst self = row['@self'] || {}\n\t\t\tconst id = row.id ?? self.id ?? self.uuid ?? row.uuid\n\t\t\tif (id === undefined || id === null || id === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\t// A name the router does not have makes every row click a no-op that\n\t\t\t// looks exactly like a broken table, so name the mistake instead of\n\t\t\t// letting push() reject into a silent catch. Feature-detected: only\n\t\t\t// some router versions can be asked.\n\t\t\tif (this.routeNameIsKnown(target) === false) {\n\t\t\t\tif (warn) {\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.warn(`[CnPageRenderer] Index page \"${page.id}\" opens rows on route \"${target}\", which the router does not have. Row clicks will do nothing.`)\n\t\t\t\t}\n\t\t\t\treturn null\n\t\t\t}\n\t\t\t// The param name comes from the TARGET'S OWN path, never a\n\t\t\t// hardcoded `id`: a manifest is free to write\n\t\t\t// `/applications/:objectId`, and vue-router answers a mismatch by\n\t\t\t// discarding the param and throwing `Missing required param`.\n\t\t\t// Manifest first, router second — a `rowRoute` may name a route\n\t\t\t// registered outside the manifest.\n\t\t\tconst path = this.pageById.get(target)?.route ?? routePathFor(router, target)\n\t\t\tconst params = buildRouteParams(path, id, this.$route?.params)\n\t\t\t// The record carries the list it came from, so its detail page can\n\t\t\t// offer next and previous within THAT list, in the filter and the\n\t\t\t// sort the handler was looking at. Without this the detail page\n\t\t\t// has an id and nothing else, and \"next\" could only ever mean\n\t\t\t// next in some order nobody chose.\n\t\t\treturn { name: target, params, query: this.rowOpenQuery() }\n\t\t},\n\n\t\t/**\n\t\t * The query a record's address carries so it can step through the list\n\t\t * it was opened from.\n\t\t *\n\t\t * Read off the CURRENT route, which is the list's own address and\n\t\t * already holds its search, its sort and its filters.\n\t\t *\n\t\t * @return {object} The query for the record's route.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\trowOpenQuery() {\n\t\t\tconst page = this.currentPage\n\t\t\tconst route = this.$route\n\t\t\tif (!page || page.type !== 'index' || !route) {\n\t\t\t\treturn {}\n\t\t\t}\n\t\t\tconst query = route.query || {}\n\t\t\treturn listContextToQuery({\n\t\t\t\tpageId: page.id,\n\t\t\t\tsearch: typeof query._search === 'string' ? query._search : '',\n\t\t\t\tsortKeys: parseSortKeys(query._order),\n\t\t\t\tfilters: query,\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Whether the router has a route by this name.\n\t\t *\n\t\t * Returns `true` when the router cannot be asked (an older router, or a\n\t\t * test double), so an unanswerable question never blocks navigation.\n\t\t *\n\t\t * @param {string} name The route name.\n\t\t * @return {boolean} False only when the router positively lacks it.\n\t\t */\n\t\trouteNameIsKnown(name) {\n\t\t\tconst router = this.$router\n\t\t\tif (!router) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif (typeof router.hasRoute === 'function') {\n\t\t\t\treturn router.hasRoute(name)\n\t\t\t}\n\t\t\tif (typeof router.getRoutes === 'function') {\n\t\t\t\tconst routes = router.getRoutes() || []\n\t\t\t\treturn routes.some((route) => route && route.name === name)\n\t\t\t}\n\t\t\treturn true\n\t\t},\n\n\t\t/**\n\t\t * Resolve a custom-component reference (page.component,\n\t\t * page.headerComponent, page.actionsComponent, page.sidebarComponent,\n\t\t * slot overrides, etc.) by name. Source precedence (ADR-036):\n\t\t *\n\t\t * 1. The v2 `registry` prop. When `requireKind` is set, only entries\n\t\t * with a matching `kind` field are considered; otherwise any\n\t\t * entry whose `component` is set wins. Each entry's `component`\n\t\t * field is the Vue component to render.\n\t\t * 2. Legacy `customComponents` map (`{ name: Component }`). Used\n\t\t * until consumers complete the registry migration.\n\t\t *\n\t\t * Returns `null` when neither source has the name.\n\t\t *\n\t\t * @param {string} name The component name referenced by the manifest.\n\t\t * @param {string|null} [requireKind] Optional kind discriminator —\n\t\t * `'page'` for page dispatch (page.component, page.sidebarComponent).\n\t\t * Omit for slot/actions/section/header lookups where any kind with\n\t\t * a `component` field is acceptable (widget, modal, form-field,\n\t\t * cell-renderer, custom kinds…).\n\t\t *\n\t\t * @return {object|null} The resolved Vue component, or null.\n\t\t */\n\t\tresolveCustomComponent(name, requireKind = null) {\n\t\t\tif (typeof name !== 'string' || name === '') {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\tconst registryEntry = this.effectiveRegistry[name]\n\t\t\tif (registryEntry !== undefined\n\t\t\t\t&& registryEntry !== null\n\t\t\t\t&& registryEntry.component\n\t\t\t\t&& (requireKind === null || registryEntry.kind === requireKind)) {\n\t\t\t\treturn registryEntry.component\n\t\t\t}\n\n\t\t\tconst legacy = this.effectiveCustomComponents[name]\n\t\t\tif (legacy) {\n\t\t\t\treturn legacy\n\t\t\t}\n\n\t\t\treturn null\n\t\t},\n\n\t\t/**\n\t\t * Resolve a named create-override handler for CnIndexPage's\n\t\t * `createOverride` prop (see `resolvedProps`). Unlike components, a\n\t\t * create-override is a plain async function, so it is looked up across\n\t\t * both registries by value shape:\n\t\t * 1. v2 registry (`cnRegistry`) — a `kind:'create-override'` entry\n\t\t * exposing the function as `.handler` (or `.fn`), or a directly\n\t\t * function-valued entry.\n\t\t * 2. legacy customComponents — a function-valued entry.\n\t\t *\n\t\t * @param {string} name The registered handler name from `config.createOverride`.\n\t\t * @return {?(formData: object, ctx: object) => Promise<object>} The async create handler, or null if unresolved.\n\t\t */\n\t\tresolveCreateOverride(name) {\n\t\t\treturn resolveCreateOverrideHandler(name, this.effectiveRegistry, this.effectiveCustomComponents)\n\t\t},\n\n\t\t/**\n\t\t * Load the object + schema backing a `type:\"detail\"` page and\n\t\t * publish them on the reactive `detailObjectContext` holder so\n\t\t * descendant CnWidgetGrid instances can feed `objectData` /\n\t\t * `schema` / `objectType` to the body/sidebar widgets.\n\t\t *\n\t\t * Steps (all defensive — a Pinia-less test harness, a missing\n\t\t * store method, or a failed fetch each degrade to leaving the\n\t\t * context null, so the page still mounts):\n\t\t * 1. Resolve `detailLoadContext` (null → clear + return).\n\t\t * 2. Register the `${register}-${schema}` object type (idempotent).\n\t\t * 3. Publish `{ objectData, schema, objectType, objectId,\n\t\t * register, store }` — with `objectData` / `schema` as\n\t\t * READ-THROUGH getters over the store cache (see below).\n\t\t * 4. Re-scope the live `or-object-{id}` subscription (see setup()).\n\t\t * 5. Fetch schema + object in parallel to warm the cache.\n\t\t *\n\t\t * Read-through holder (#222): `objectData` and `schema` are\n\t\t * accessors over `store.objects[slug][id]` / `store.schemas[slug]`\n\t\t * rather than stashed copies, so when the live-updates plugin's\n\t\t * event-driven refetch replaces the cache entry, every consumer\n\t\t * reading the holder during render (CnWidgetGrid's\n\t\t * `detailContextProps`, `resolveObjectTokenContext` callers)\n\t\t * re-renders with the fresh object — the holder never freezes a\n\t\t * snapshot. The external contract is unchanged: same keys, same\n\t\t * `{ value }` holder shape. Vue's observer preserves the accessors\n\t\t * and makes top-level writes to `objectData` / `schema` silent\n\t\t * no-ops (accessor without setter), so a consumer cannot clobber\n\t\t * the live view; all shipped widgets copy before mutating.\n\t\t *\n\t\t * The holder is published before the fetches so widgets that only\n\t\t * need objectId / register (e.g. file-manager) render without\n\t\t * waiting for the object body; the getters go non-null the moment\n\t\t * the fetches populate the cache — no re-publish needed.\n\t\t */\n\t\tasync loadDetailObject() {\n\t\t\tconst ctx = this.detailLoadContext\n\t\t\tif (!ctx) {\n\t\t\t\t// Not a detail page (or incomplete triple): clear the holder\n\t\t\t\t// and close the live-subscription gate — the composable in\n\t\t\t\t// setup() releases any held subscription when it sees the\n\t\t\t\t// scope go invalid (the renderer persists across routes).\n\t\t\t\tthis.liveSubEnabled = false\n\t\t\t\tthis.liveSubType = ''\n\t\t\t\tthis.liveSubId = ''\n\t\t\t\tthis.detailObjectContext.value = null\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tlet store = null\n\t\t\ttry {\n\t\t\t\tstore = useObjectStore()\n\t\t\t} catch {\n\t\t\t\t// Pinia not installed (unit tests). Publish the ids so\n\t\t\t\t// id-only widgets still work; skip the object fetch and\n\t\t\t\t// leave the live subscription disabled.\n\t\t\t\tthis.liveSubEnabled = false\n\t\t\t\tthis.detailObjectContext.value = {\n\t\t\t\t\tobjectData: null,\n\t\t\t\t\tschema: null,\n\t\t\t\t\tobjectType: ctx.slug,\n\t\t\t\t\tobjectId: ctx.objectId,\n\t\t\t\t\tregister: ctx.register,\n\t\t\t\t\tstore: null,\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Must precede the subscription re-scope below: subscribe() rejects\n\t\t\t// unregistered types. Once only — registerObjectType also blanks\n\t\t\t// `objects[slug]` and `schemas[slug]`, so re-running it empties the\n\t\t\t// content until the re-fetch lands.\n\t\t\ttry {\n\t\t\t\tif (typeof store.registerObjectType === 'function'\n\t\t\t\t\t&& !store.objectTypeRegistry?.[ctx.slug]) {\n\t\t\t\t\tstore.registerObjectType(ctx.slug, ctx.schema, ctx.register)\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.warn(`[CnPageRenderer] Failed to register object type \"${ctx.slug}\" for detail page \"${this.currentPage?.id}\":`, err)\n\t\t\t}\n\n\t\t\t// Publish the read-through holder (see method docblock). The ids\n\t\t\t// are available immediately; the getters resolve once the cache\n\t\t\t// fills.\n\t\t\tthis.detailObjectContext.value = {\n\t\t\t\tget objectData() {\n\t\t\t\t\treturn store.getObject?.(ctx.slug, ctx.objectId) ?? null\n\t\t\t\t},\n\n\t\t\t\t// Explicit no-op setters keep a consumer's stray write harmless.\n\t\t\t\t// Under Vue 2 the getter-only accessor was enough: `defineReactive`\n\t\t\t\t// replaced each property with its own get/set pair that delegated\n\t\t\t\t// reads to the original getter, so an assignment was swallowed.\n\t\t\t\t// Vue 3 leaves the accessor on the target and its `set` trap\n\t\t\t\t// forwards to `Reflect.set`, which returns false for a\n\t\t\t\t// setter-less accessor — and a `set` trap returning false throws\n\t\t\t\t// `TypeError: 'set' on proxy: trap returned falsish` in strict\n\t\t\t\t// mode. That would turn a benign mistake in a consumer app into a\n\t\t\t\t// crash, so the swallow is now written out rather than implied.\n\t\t\t\tset objectData(_ignored) {},\n\t\t\t\tget schema() {\n\t\t\t\t\treturn store.getSchema?.(ctx.slug) ?? null\n\t\t\t\t},\n\n\t\t\t\tset schema(_ignored) {},\n\t\t\t\tobjectType: ctx.slug,\n\t\t\t\tobjectId: ctx.objectId,\n\t\t\t\tregister: ctx.register,\n\t\t\t\tstore,\n\t\t\t}\n\n\t\t\t// Re-scope the live subscription (see setup()). Gated to the v2\n\t\t\t// widget-grid path — CnWidgetGrid (the holder's only render-time\n\t\t\t// consumer surface) mounts only for v2 manifests with widget\n\t\t\t// entries; the typed CnDetailPage dispatch path manages its own\n\t\t\t// subscription. `config.subscribe: false` opts out, mirroring\n\t\t\t// CnIndexPage / CnDetailPage (manifest-live-updates).\n\t\t\tconst subscribeOptOut = this.currentPage?.config?.subscribe === false\n\t\t\tconst rendersWidgetGrids = this.isV2Manifest && this.widgetsBySlot.size > 0\n\t\t\tthis.liveSubType = ctx.slug\n\t\t\tthis.liveSubId = ctx.objectId\n\t\t\tthis.liveSubEnabled = !subscribeOptOut && rendersWidgetGrids\n\n\t\t\t// Warm the cache: fetch schema + object, tolerating either\n\t\t\t// failing. No re-publish afterwards — the holder's getters read\n\t\t\t// the cache these fetches populate, so there is nothing to\n\t\t\t// clobber if the user navigated away mid-fetch either.\n\t\t\tconst tasks = []\n\t\t\tif (typeof store.fetchSchema === 'function') {\n\t\t\t\ttasks.push(store.fetchSchema(ctx.slug).catch(() => null))\n\t\t\t} else {\n\t\t\t\ttasks.push(Promise.resolve(null))\n\t\t\t}\n\t\t\tif (typeof store.fetchObject === 'function') {\n\t\t\t\ttasks.push(store.fetchObject(ctx.slug, ctx.objectId).catch(() => null))\n\t\t\t} else {\n\t\t\t\ttasks.push(Promise.resolve(null))\n\t\t\t}\n\t\t\tawait Promise.all(tasks)\n\t\t},\n\n\t\t/**\n\t\t * Auto-register object types declared on the current\n\t\t * `type:\"custom\"` page's `config`. No-op for any other page\n\t\t * type (index/detail self-register inside the page component\n\t\t * itself; dashboard/form/map have no such concept).\n\t\t *\n\t\t * Recognised config shapes:\n\t\t *\n\t\t * 1. Single type — `config.register` + `config.schema` are\n\t\t * both non-empty strings. Registered under slug\n\t\t * `${register}-${schema}` to match the convention used by\n\t\t * CnIndexPage.setup (self-fetch mode) and CnLogsPage.\n\t\t *\n\t\t * 2. Multi-type — `config.types: [{ name, register, schema }]`.\n\t\t * Each entry is registered under its own `name` slug so a\n\t\t * single custom page (e.g. a Kanban board with multiple\n\t\t * object kinds) can hydrate several object types in one\n\t\t * manifest declaration.\n\t\t *\n\t\t * Both shapes may co-exist; the single-type pair is registered\n\t\t * first, then each `types[]` entry. Entries with missing /\n\t\t * non-string `name` / `register` / `schema` are skipped with a\n\t\t * single warning. All work is wrapped in try/catch so a broken\n\t\t * Pinia setup or a thrown `registerObjectType` never blocks\n\t\t * the page from mounting.\n\t\t */\n\t\tautoRegisterCustomTypes() {\n\t\t\tconst page = this.currentPage\n\t\t\tif (!page || page.type !== 'custom') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst config = page.config\n\t\t\tif (!config || typeof config !== 'object') {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tlet store\n\t\t\ttry {\n\t\t\t\tstore = useObjectStore()\n\t\t\t} catch {\n\t\t\t\t// Pinia not installed (common in unit tests). Silently\n\t\t\t\t// skip — the custom component can still register itself\n\t\t\t\t// at mount time if/when it has its own store.\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (!store || typeof store.registerObjectType !== 'function') {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Single-type shape: config.register + config.schema.\n\t\t\tconst reg = config.register\n\t\t\tconst schema = config.schema\n\t\t\tconst hasSingle = typeof reg === 'string' && reg.length > 0\n\t\t\t\t&& typeof schema === 'string' && schema.length > 0\n\t\t\tif (hasSingle) {\n\t\t\t\tconst slug = `${reg}-${schema}`\n\t\t\t\ttry {\n\t\t\t\t\tstore.registerObjectType(slug, schema, reg)\n\t\t\t\t} catch (err) {\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t`[CnPageRenderer] Failed to auto-register object type \"${slug}\" for custom page id \"${page.id}\":`,\n\t\t\t\t\t\terr,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t} else if (\n\t\t\t\t(typeof reg === 'string' && reg.length > 0)\n\t\t\t\t|| (typeof schema === 'string' && schema.length > 0)\n\t\t\t) {\n\t\t\t\t// One half of the pair is set but not the other —\n\t\t\t\t// likely a manifest typo. Warn but keep going so\n\t\t\t\t// types[] (below) still gets a chance.\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.warn(`[CnPageRenderer] Custom page id \"${page.id}\" declares only one of config.register / config.schema; auto-registration skipped. Set both (or use config.types[]) to opt in.`)\n\t\t\t}\n\n\t\t\t// Multi-type shape: config.types: [{ name, register, schema }, ...].\n\t\t\tconst types = config.types\n\t\t\tif (Array.isArray(types)) {\n\t\t\t\tfor (const entry of types) {\n\t\t\t\t\tif (!entry || typeof entry !== 'object') {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tconst name = entry.name\n\t\t\t\t\tconst r = entry.register\n\t\t\t\t\tconst s = entry.schema\n\t\t\t\t\tif (\n\t\t\t\t\t\ttypeof name !== 'string' || name.length === 0\n\t\t\t\t\t\t|| typeof r !== 'string' || r.length === 0\n\t\t\t\t\t\t|| typeof s !== 'string' || s.length === 0\n\t\t\t\t\t) {\n\t\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\t\tconsole.warn(`[CnPageRenderer] Skipping invalid entry in config.types on custom page id \"${page.id}\" — each entry needs non-empty name, register, and schema.`)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\ttry {\n\t\t\t\t\t\tstore.registerObjectType(name, s, r)\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t`[CnPageRenderer] Failed to auto-register object type \"${name}\" for custom page id \"${page.id}\":`,\n\t\t\t\t\t\t\terr,\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Resolve a registry component name. Logs a single console.warn\n\t\t * naming the slot if the name is not in the registry.\n\t\t *\n\t\t * @param {string} registryName Name of the component to look up\n\t\t * in `effectiveCustomComponents`.\n\t\t * @param {string} slotName Slot the component would have filled\n\t\t * (used only for the warning message).\n\t\t * @return {object|null}\n\t\t */\n\t\tresolveRegistryName(registryName, slotName) {\n\t\t\tconst resolved = this.resolveCustomComponent(registryName)\n\t\t\tif (!resolved) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.warn(`[CnPageRenderer] Slot-override component \"${registryName}\" referenced by page id \"${this.currentPage.id}\" (slot \"${slotName}\") not found in registry.`)\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn resolved\n\t\t},\n\t},\n}\n</script>\n\n<style>\n.cn-page-renderer {\n\tdisplay: contents;\n}\n\n/*\n * Toggle-clearance padding lives PER-COMPONENT on each page's HEADER\n * element (CnPageHeader, CnDashboardPage, CnDetailPage,\n * CnFeaturesAndRoadmapView, etc.). Earlier attempts at an abstract\n * fix here — first via `.cn-page-renderer > *` (PR #355, lost to\n * scoped-style specificity + shorthand overrides), then via a\n * `.cn-page-renderer__viewport` wrapper (PR #359, narrowed body\n * content unintentionally) — were rejected in favour of per-header\n * rules so body content keeps its full width.\n *\n * Custom pages MUST add `padding-inline-start: 56px` to their HEADER\n * element to clear the navigation toggle. See `docs/getting-started.md`.\n */\n\n/*\n * Hook class applied when the current page's manifest entry has\n * `sidebar.show: false`. The library does not ship visual rules\n * here — consumer apps with style-driven sidebar layouts (e.g. CSS\n * grid where the host shell sibling sidebar is a grid track) can\n * target this class to collapse / hide the sibling element.\n *\n * The programmatic counterpart is the `cnPageSidebarVisible`\n * inject — `CnAppRoot` reads it to gate `<slot name=\"sidebar\" />`.\n */\n.cn-page-renderer--no-sidebar {\n\t/* intentionally empty — consumer-styled */\n}\n\n/* Builder empty-state: keep the edit button top-right (mirrors a page\n header's actions area) above a centred empty prompt. */\n.cn-page-renderer__empty {\n\tpadding-inline-start: 56px;\n}\n\n.cn-page-renderer__empty-actions {\n\tdisplay: flex;\n\tjustify-content: flex-end;\n\tpadding: 8px 8px 0;\n}\n</style>\n"],"names":["CnDependencyMissing","CnWidgetGrid","CnPageConfigModal","CnBuildiqEditButton","CnMassExportDialog","t"],"mappings":"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"}
1
+ {"version":3,"file":"CnPageRenderer.vue2.js","sources":["../../../../src/components/CnPageRenderer/CnPageRenderer.vue"],"sourcesContent":["<!--\n CnPageRenderer — JSON-driven page dispatcher.\n\n Mounted inside <router-view>, CnPageRenderer reads the manifest, finds\n the page definition whose `id` matches the current route name, and\n renders the appropriate page component by dispatching on `type`.\n\n Page types are resolved via the `pageTypes` registry. The library\n ships a built-in registry (`defaultPageTypes` — index, detail,\n dashboard) and consumers can extend it by passing a merged map to\n CnAppRoot or CnPageRenderer. The `custom` type is special: it\n resolves `page.component` against the customComponents registry\n rather than the page-types map. Adding a new built-in page type to\n the library is one line in `pageTypes.js` — no change here.\n\n Each entry in `pageTypes` is wrapped in `defineAsyncComponent` so\n apps using only a subset of types do not pay the bundle cost for\n others (notably the GridStack-backed dashboard).\n\n Manifest, customComponents, pageTypes, and translate are injected\n from CnAppRoot by default; each can also be passed as props for\n standalone use without CnAppRoot. Props always take precedence\n over inject.\n\n See REQ-JMR-005 of the json-manifest-renderer specification.\n-->\n<template>\n\t<div\n\t\tv-if=\"currentPage\"\n\t\t:data-page-id=\"currentPage.id\"\n\t\tdata-testid=\"cn-page\"\n\t\t:data-testid-page-id=\"currentPage.id\"\n\t\tclass=\"cn-page-renderer\"\n\t\t:class=\"[{ 'cn-page-renderer--no-sidebar': !pageSidebarVisibleValue }]\">\n\t\t<!--\n\t\t A page whose `requiresApp` is not installed renders the missing-\n\t\t dependency screen INSTEAD of its body.\n\n\t\t This is for the deep link, not the menu. An entry gated by\n\t\t `visibleIf.appInstalled` is already hidden from navigation, so the\n\t\t only ways here are a bookmark, a shared URL, a redirect or an e2e\n\t\t spec — and every one of those otherwise lands on a page that renders\n\t\t an empty list with nothing saying why. \"Not installed\" then looks\n\t\t identical to \"no data\" and to \"no permission\".\n\n\t\t It is deliberately NOT the deprecated soft-dependency notice\n\t\t (REQ-DIA-6, off by default since 2.1.0). Those stacked one banner per\n\t\t optional app above EVERY page on EVERY load; this renders on the one\n\t\t page that actually needs the app, only when someone navigates to it.\n\n\t\t Widget-level gating stays with `visibleIf.appInstalled`: a detail page\n\t\t may carry many widgets where only one needs the app, and that widget\n\t\t hides while the page renders normally. Use `requiresApp` only when the\n\t\t WHOLE page is meaningless without it.\n\t\t-->\n\t\t<!--\n\t\t A page whose declared `permission` the user does not hold renders a\n\t\t refusal INSTEAD of its body, and BEFORE the dependency check, because\n\t\t \"you may not see this\" outranks \"the app it needs is missing\".\n\n\t\t Same reasoning as `requiresApp` above: this is for the deep link, not\n\t\t the menu. CnAppNav already drops the entry, so the only ways here are\n\t\t a bookmark, a shared URL, a redirect or a typed address — and until\n\t\t now every one of those rendered the page in full.\n\t\t-->\n\t\t<NcEmptyContent v-if=\"forbiddenPagePermission\"\n\t\t\t:name=\"tr('You do not have access to this page')\"\n\t\t\t:description=\"tr('Ask an administrator if you need it.')\"\n\t\t\tdata-testid=\"cn-page-forbidden\">\n\t\t\t<template #icon>\n\t\t\t\t<LockOutline :size=\"20\" />\n\t\t\t</template>\n\t\t</NcEmptyContent>\n\n\t\t<CnDependencyMissing\n\t\t\tv-else-if=\"missingPageDependency\"\n\t\t\t:dependencies=\"[missingPageDependency]\"\n\t\t\t:heading=\"missingDependencyHeading\"\n\t\t\t:intro=\"missingDependencyIntro\"\n\t\t\tdata-testid=\"cn-page-dependency-missing\" />\n\n\t\t<!-- V2 render path: slot dispatcher via CnWidgetGrid.\n\t\t Body falls back to the typed-primitive dispatch when no\n\t\t widgets[] entries target the `body` slot — apps that just\n\t\t declare `type:\"index\"` (or any other registered type) with\n\t\t a `config` payload still get the default page component\n\t\t (CnIndexPage, CnDetailPage, etc.) mounted, without having\n\t\t to hand-author a widget entry. An explicit body widget\n\t\t (e.g. an `object-table` widget in `body`) still wins over\n\t\t the default. -->\n\t\t<template v-else-if=\"isV2Manifest\">\n\t\t\t<!-- body slot — widgets first, default typed component otherwise.\n\t\t\t KNOWN GAP (ConductionNL/hrmq#112 follow-up): a body widget\n\t\t\t short-circuits the typed component, so a `type: \"detail\"` page\n\t\t\t that adopts ADR-036's page-level `widgets[]` never mounts\n\t\t\t CnDetailPage and loses its header, padding, sidebar and grid\n\t\t\t discipline. The same applies to `type: \"dashboard\"` pages and\n\t\t\t CnDashboardPage.\n\n\t\t\t NOTE the direction of the tension: the v2 schema DOCUMENTS\n\t\t\t page-level `widgets[]` as preferred and calls `config.widgets`\n\t\t\t legacy, yet only `config.widgets` reaches the typed component.\n\t\t\t An app following the documented advice gets the worse result.\n\n\t\t\t hrmq was the only app with `widgets[]` on detail pages and has\n\t\t\t since moved its 47 pages onto `config.widgets` (hrmq#115), so\n\t\t\t nothing in the fleet is currently mis-rendering — but the trap\n\t\t\t is still armed for the next app that follows the schema's own\n\t\t\t recommendation.\n\n\t\t\t Hosting the grid in the typed component's default slot was tried\n\t\t\t and REVERTED: the unit suite went green while the live page got\n\t\t\t worse — the body rendered empty (CnDetailPage gates its default\n\t\t\t slot against its own auto-body) and its sidebar fired ~20\n\t\t\t integration endpoints that 404 on an instance without them. The\n\t\t\t real fix is either to make the typed components accept a body\n\t\t\t grid as a first-class input, or to settle the schema on one\n\t\t\t spelling and translate the other here. -->\n\t\t\t<CnWidgetGrid\n\t\t\t\tv-if=\"widgetsBySlot.has('body')\"\n\t\t\t\t:widgets=\"widgetsBySlot.get('body')\"\n\t\t\t\t:editable=\"bodyEditable\"\n\t\t\t\tslotName=\"body\" />\n\t\t\t<component\n\t\t\t\t:is=\"resolvedComponent\"\n\t\t\t\tv-else-if=\"resolvedComponent\"\n\t\t\t\t:key=\"pageRenderKey\"\n\t\t\t\tv-bind=\"{ ...$attrs, ...resolvedProps }\"\n\t\t\t\t@view=\"onRowOpen\"\n\t\t\t\t@rowClick=\"onRowOpen\"\n\t\t\t\t@rowAuxClick=\"onRowOpen\"\n\t\t\t\t@editOpen=\"onRowOpen\"\n\t\t\t\t@configure=\"showConfigModal = true\">\n\t\t\t\t<!-- This `<template v-for>` defines dynamic SLOTS, not a\n\t\t\t\t rendered list, so the rule's advice is inverted here:\n\t\t\t\t `@vue/compiler-sfc` DISCARDS a `:key` on a slot-defining\n\t\t\t\t `<template>` (verified — the generated `createSlots` entry\n\t\t\t\t carries only `name`) and honours it only on the child.\n\t\t\t\t Moving the key up would throw it away. -->\n\t\t\t\t<!-- eslint-disable vue/no-v-for-template-key-on-child -->\n\t\t\t\t<template\n\t\t\t\t\tv-for=\"entry in resolvedSlotEntries\"\n\t\t\t\t\t#[entry.name]=\"slotProps\">\n\t\t\t\t\t<component\n\t\t\t\t\t\t:is=\"entry.component\"\n\t\t\t\t\t\t:key=\"entry.name\"\n\t\t\t\t\t\tv-bind=\"slotProps\" />\n\t\t\t\t</template>\n\t\t\t\t<!-- The open record, beside the list. The host never writes\n\t\t\t\t this slot: the renderer already knows which detail page\n\t\t\t\t the index opens into, so it mounts that one. `$attrs` too:\n\t\t\t\t the host passes the page its `objectStore` as an attribute,\n\t\t\t\t not through the manifest. -->\n\t\t\t\t<template v-if=\"splitPaneComponent\" #split-pane=\"splitScope\">\n\t\t\t\t\t<component\n\t\t\t\t\t\t:is=\"splitPaneComponent\"\n\t\t\t\t\t\tv-bind=\"{ ...$attrs, ...splitPaneProps }\"\n\t\t\t\t\t\t@edited=\"splitScope.saved\"\n\t\t\t\t\t\t@created=\"splitScope.saved\">\n\t\t\t\t\t\t<template\n\t\t\t\t\t\t\tv-for=\"entry in splitPaneSlotEntries\"\n\t\t\t\t\t\t\t#[entry.name]=\"paneSlotProps\">\n\t\t\t\t\t\t\t<component\n\t\t\t\t\t\t\t\t:is=\"entry.component\"\n\t\t\t\t\t\t\t\t:key=\"entry.name\"\n\t\t\t\t\t\t\t\tv-bind=\"paneSlotProps\" />\n\t\t\t\t\t\t</template>\n\t\t\t\t\t</component>\n\t\t\t\t</template>\n\t\t\t\t<!-- eslint-enable vue/no-v-for-template-key-on-child -->\n\t\t\t</component>\n\t\t\t<!-- header-actions slot -->\n\t\t\t<CnWidgetGrid\n\t\t\t\tv-if=\"widgetsBySlot.has('header-actions')\"\n\t\t\t\t:widgets=\"widgetsBySlot.get('header-actions')\"\n\t\t\t\tslotName=\"header-actions\" />\n\t\t\t<!-- footer slot -->\n\t\t\t<CnWidgetGrid\n\t\t\t\tv-if=\"widgetsBySlot.has('footer')\"\n\t\t\t\t:widgets=\"widgetsBySlot.get('footer')\"\n\t\t\t\tslotName=\"footer\" />\n\t\t\t<!-- modal slot -->\n\t\t\t<CnWidgetGrid\n\t\t\t\tv-if=\"widgetsBySlot.has('modal')\"\n\t\t\t\t:widgets=\"widgetsBySlot.get('modal')\"\n\t\t\t\tslotName=\"modal\" />\n\t\t\t<!-- sidebar slot (gated by cnPageSidebarVisible) -->\n\t\t\t<CnWidgetGrid\n\t\t\t\tv-if=\"widgetsBySlot.has('sidebar') && pageSidebarVisibleValue\"\n\t\t\t\t:widgets=\"widgetsBySlot.get('sidebar')\"\n\t\t\t\tslotName=\"sidebar\" />\n\t\t\t<!-- dynamic tab:* and section:* slots -->\n\t\t\t<template v-for=\"dynamicSlot in dynamicSlotKeys\" :key=\"dynamicSlot\">\n\t\t\t\t<CnWidgetGrid\n\t\t\t\t\t:widgets=\"widgetsBySlot.get(dynamicSlot)\"\n\t\t\t\t\t:slotName=\"dynamicSlot\" />\n\t\t\t</template>\n\t\t</template>\n\n\t\t<component\n\t\t\t:is=\"resolvedComponent\"\n\t\t\tv-else-if=\"resolvedComponent\"\n\t\t\t:key=\"pageRenderKey\"\n\t\t\tv-bind=\"{ ...$attrs, ...resolvedProps }\"\n\t\t\t@view=\"onRowOpen\"\n\t\t\t@rowClick=\"onRowOpen\"\n\t\t\t@rowAuxClick=\"onRowOpen\"\n\t\t\t@editOpen=\"onRowOpen\"\n\t\t\t@configure=\"showConfigModal = true\">\n\t\t\t<!-- Dynamic slot definition, not a rendered list — see the note on\n\t\t\t the identical block above. -->\n\t\t\t<!-- eslint-disable vue/no-v-for-template-key-on-child -->\n\t\t\t<template\n\t\t\t\tv-for=\"entry in resolvedSlotEntries\"\n\t\t\t\t#[entry.name]=\"slotProps\">\n\t\t\t\t<component\n\t\t\t\t\t:is=\"entry.component\"\n\t\t\t\t\t:key=\"entry.name\"\n\t\t\t\t\tv-bind=\"slotProps\" />\n\t\t\t</template>\n\t\t\t<!-- The open record, beside the list. The host never writes\n\t\t\t this slot: the renderer already knows which detail page\n\t\t\t the index opens into, so it mounts that one. -->\n\t\t\t<template v-if=\"splitPaneComponent\" #split-pane=\"splitScope\">\n\t\t\t\t<component\n\t\t\t\t\t:is=\"splitPaneComponent\"\n\t\t\t\t\tv-bind=\"{ ...$attrs, ...splitPaneProps }\"\n\t\t\t\t\t@edited=\"splitScope.saved\"\n\t\t\t\t\t@created=\"splitScope.saved\">\n\t\t\t\t\t<template\n\t\t\t\t\t\tv-for=\"entry in splitPaneSlotEntries\"\n\t\t\t\t\t\t#[entry.name]=\"paneSlotProps\">\n\t\t\t\t\t\t<component\n\t\t\t\t\t\t\t:is=\"entry.component\"\n\t\t\t\t\t\t\t:key=\"entry.name\"\n\t\t\t\t\t\t\tv-bind=\"paneSlotProps\" />\n\t\t\t\t\t</template>\n\t\t\t\t</component>\n\t\t\t</template>\n\t\t\t<!-- eslint-enable vue/no-v-for-template-key-on-child -->\n\t\t</component>\n\n\t\t<!-- Builder empty-state. A page with no renderable body — e.g. a\n\t\t freshly-created custom page that has no `component` / body widgets\n\t\t yet — would otherwise render nothing at all, leaving no\n\t\t \"Edit with Buildiq\" affordance to start adding content. Render the\n\t\t edit button (it self-gates to builder mode via CnAppRoot's\n\t\t `cnOpenBuildAvailable`) plus a neutral prompt, so a new page is\n\t\t always editable. ADR-041. -->\n\t\t<div v-if=\"!hasRenderableBody\" class=\"cn-page-renderer__empty\">\n\t\t\t<div class=\"cn-page-renderer__empty-actions\">\n\t\t\t\t<CnBuildiqEditButton />\n\t\t\t</div>\n\t\t\t<NcEmptyContent :name=\"tr('This page is empty')\"\n\t\t\t\t:description=\"tr('Open the Buildiq editor to start adding content to this page.')\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<ShapeOutline :size=\"20\" />\n\t\t\t\t</template>\n\t\t\t</NcEmptyContent>\n\t\t</div>\n\n\t\t<!-- Per-page config editor, opened by an index page's edit-mode cog. -->\n\t\t<CnPageConfigModal v-if=\"showConfigModal && currentPage\"\n\t\t\t:page=\"currentPage\"\n\t\t\t@close=\"showConfigModal = false\" />\n\n\t\t<!-- Shared export launcher, opened by a `type:\"export\"` manifest\n\t\t action (Wave 1, nextcloud-vue#91). Configured from the action's\n\t\t entities[] / formats[] / description; the confirm payload routes\n\t\t to the action's optional `handler` (manifest actions map). -->\n\t\t<CnMassExportDialog\n\t\t\tv-if=\"exportAction\"\n\t\t\tref=\"exportDialog\"\n\t\t\t:entities=\"exportDialogEntities\"\n\t\t\t:formats=\"exportDialogFormats\"\n\t\t\t:description=\"exportAction.description || ''\"\n\t\t\t@confirm=\"onExportConfirm\"\n\t\t\t@close=\"exportAction = null\" />\n\t</div>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcEmptyContent } from '@nextcloud/vue'\nimport { ref } from 'vue'\nimport LockOutline from 'vue-material-design-icons/LockOutline.vue'\nimport ShapeOutline from 'vue-material-design-icons/ShapeOutline.vue'\nimport CnPageConfigModal from '../../dialogs/CnPageConfigModal.vue'\nimport CnBuildiqEditButton from '../CnBuildiqEditButton/CnBuildiqEditButton.vue'\nimport CnDependencyMissing from '../CnDependencyMissing/CnDependencyMissing.vue'\nimport CnWidgetGrid from '../CnWidgetGrid/CnWidgetGrid.vue'\nimport { useObjectSubscription } from '../../composables/useObjectSubscription.js'\nimport { useObjectStore } from '../../store/index.js'\nimport { dispatchAction, resolveCreateOverrideHandler } from '../../utils/actionsDispatcher.js'\nimport { isAppInstalled } from '../../utils/appInstalled.js'\nimport { pageHasSplitView, pageIdForRoute, splitIdForRoute, splitRouteName } from '../../utils/buildManifestRoutes.js'\nimport { openRowTarget } from '../../utils/linkNavigation.js'\nimport { listContextFromRoute, listContextToQuery } from '../../utils/listNavigation.js'\nimport { resolveRouteSentinels } from '../../utils/resolveRouteSentinels.js'\nimport { parseSortKeys } from '../../utils/routeFilters.js'\nimport { buildRouteParams, routePathFor } from '../../utils/routeParams.js'\nimport { isNewTabHandled } from '../../utils/rowAuxClick.js'\nimport { CnMassExportDialog } from '../CnMassExportDialog/index.js'\nimport { defaultPageTypes } from './pageTypes.js'\n\n/** Recognised fixed slot names for v2 manifests. */\nconst KNOWN_SLOTS = new Set(['body', 'sidebar', 'header-actions', 'footer', 'modal'])\n\n/**\n * Test whether a slot name is a recognised v2 slot pattern.\n *\n * @param {string} slotName The slot name to test (e.g. `body`, `tab:overview`).\n * @return {boolean}\n */\nfunction isKnownSlot(slotName) {\n\tif (!slotName) {\n\t\treturn false\n\t}\n\tif (KNOWN_SLOTS.has(slotName)) {\n\t\treturn true\n\t}\n\tif (/^tab:[^\\s]+$/.test(slotName)) {\n\t\treturn true\n\t}\n\tif (/^section:[^\\s]+$/.test(slotName)) {\n\t\treturn true\n\t}\n\treturn false\n}\n\n/**\n * Read-only defaults applied when a type='index' page declares\n * `config.readOnly: true` (REQ-MIPFU-4 of manifest-index-page-followups).\n * Merged UNDER the explicit `config.*` props by `resolvedProps`, so\n * any explicit prop the manifest sets still wins.\n */\nconst READ_ONLY_DEFAULTS = Object.freeze({\n\tselectable: false,\n\tshowAdd: false,\n\tshowFormDialog: false,\n\tshowEditAction: false,\n\tshowCopyAction: false,\n\tshowDeleteAction: false,\n\tshowMassImport: false,\n\tshowMassCopy: false,\n\tshowMassDelete: false,\n})\n\nexport default {\n\tname: 'CnPageRenderer',\n\n\tcomponents: {\n\t\tCnDependencyMissing,\n\t\tCnWidgetGrid,\n\t\tCnPageConfigModal,\n\t\tCnBuildiqEditButton,\n\t\tCnMassExportDialog,\n\t\tNcEmptyContent,\n\t\tShapeOutline,\n\t\tLockOutline,\n\t},\n\n\tinject: {\n\t\tcnManifest: { default: null },\n\t\t/**\n\t\t * The same manifest as `cnManifest`, but provided as a REF.\n\t\t *\n\t\t * Options-API `inject` resolves a plain provided value exactly once, at\n\t\t * this component's creation, and `cnManifest` is a getter on CnAppRoot's\n\t\t * provide object — so what arrives is a snapshot. A renderer created\n\t\t * before edit mode keeps the pre-edit manifest object and never\n\t\t * re-derives its page props from an in-app edit. `inject` unwraps a ref\n\t\t * into a reactive getter instead, which is what makes those edits render\n\t\t * (ADR-041).\n\t\t */\n\t\tcnManifestSource: { default: null },\n\t\tcnCustomComponents: { default: () => ({}) },\n\t\tcnTranslate: { default: () => (key) => key },\n\t\tcnPageTypes: { default: null },\n\t\tcnRegistry: { default: () => ({}) },\n\t\t/** Permission strings the current user holds, provided by CnAppRoot. */\n\t\tcnPermissions: { default: () => [] },\n\t\tcnOpenModal: { default: null },\n\t\t/** ADR-041: true while the in-app editor is editing — makes the body grid draggable. */\n\t\tcnEditingBody: { default: false },\n\t},\n\n\t/**\n\t * Expose the current page's sidebar-visibility state and\n\t * sidebar-component override to descendants (notably\n\t * `CnAppRoot` which gates its `#sidebar` slot on\n\t * `cnPageSidebarVisible.value` and renders\n\t * `cnPageSidebarComponent.value` as the slot's default content).\n\t * Each provider is a reactive holder so consumers can `inject`\n\t * once and read `.value` whenever they render — Vue 2 reactivity\n\t * tracks the mutation site (the watchers below in `data()`).\n\t *\n\t * `cnPageSidebarVisible` default holder value is `true`, so when\n\t * `pages[].sidebar.show` is unset / `true`, behaviour matches\n\t * today (slot renders).\n\t *\n\t * `cnPageSidebarComponent` default holder value is `null`, so\n\t * when `pages[].sidebarComponent` is unset, the host App's\n\t * `#sidebar` slot renders its consumer-supplied content (or\n\t * nothing) — no behaviour change for apps that don't adopt the\n\t * field.\n\t */\n\tprovide() {\n\t\t// `self` is load-bearing: `cnSlotColumns` below is a GETTER, and inside\n\t\t// a getter on that object literal `this` is the literal — not the\n\t\t// component. The getter is what keeps the provide tracking the active\n\t\t// page, and a getter cannot be an arrow function.\n\t\t// eslint-disable-next-line @typescript-eslint/no-this-alias\n\t\tconst self = this\n\t\treturn {\n\t\t\t// Per-page slot→columns override (page.config.slotColumns), read by\n\t\t\t// CnWidgetGrid. A getter so it tracks the active page reactively\n\t\t\t// despite provide() running once.\n\t\t\tget cnSlotColumns() {\n\t\t\t\treturn self.currentPage?.config?.slotColumns ?? null\n\t\t\t},\n\n\t\t\tcnPageSidebarVisible: this.pageSidebarVisible,\n\t\t\tcnPageSidebarComponent: this.pageSidebarComponent,\n\t\t\t// Loaded object for a type:\"detail\" page (reactive holder). See\n\t\t\t// data().detailObjectContext. Descendant CnWidgetGrid reads this\n\t\t\t// to feed `objectData` / `schema` / `objectType` to detail widgets.\n\t\t\tcnDetailObjectContext: this.detailObjectContext,\n\t\t\t/**\n\t\t\t * Bound dispatchAction for the v2 render path. Child widget\n\t\t\t * components inject `cnDispatchAction` to dispatch manifest\n\t\t\t * actions. Context is pre-bound with this component's\n\t\t\t * $router and the injected cnRegistry; a caller may merge\n\t\t\t * extra context (e.g. CnWidgetObjectTable passes\n\t\t\t * `{ objectStore, source, row }` for `object-op` actions).\n\t\t\t * The dispatch result is returned so async `object-op`\n\t\t\t * dispatches can be awaited.\n\t\t\t *\n\t\t\t * @param {object} action The action to dispatch.\n\t\t\t * @param {object} [extraContext] Extra context merged over the pre-bound one.\n\t\t\t * @return {unknown} The dispatchAction return value (a promise for object-op).\n\t\t\t */\n\t\t\tcnDispatchAction: (action, extraContext = {}) => {\n\t\t\t\treturn dispatchAction(action, {\n\t\t\t\t\trouter: this.$router ?? null,\n\t\t\t\t\tregistry: this.cnRegistry,\n\t\t\t\t\thandlers: this.effectiveManifest?.actions ?? {},\n\t\t\t\t\topenModal: this._cnOpenModal,\n\t\t\t\t\t// `type:\"export\"` opens the shared CnMassExportDialog this\n\t\t\t\t\t// component mounts (Wave 1, nextcloud-vue#91).\n\t\t\t\t\topenExport: (exportAction) => {\n\t\t\t\t\t\tthis.exportAction = exportAction\n\t\t\t\t\t},\n\t\t\t\t\t// The host translate function, so an api-call/agent action's\n\t\t\t\t\t// manifest-authored success/error toast localises exactly\n\t\t\t\t\t// like the rest of the page chrome. Identity by default.\n\t\t\t\t\ttranslate: (key) => this.tr(key),\n\t\t\t\t\t...extraContext,\n\t\t\t\t})\n\t\t\t},\n\t\t}\n\t},\n\n\t/**\n\t * Forward listeners + attrs to the dispatched page component (B1).\n\t *\n\t * `inheritAttrs: false` opts the wrapping `.cn-page-renderer` <div>\n\t * out of Vue's default non-prop-attribute fallthrough, so attributes\n\t * the host passed to CnPageRenderer land on the dispatched page via\n\t * `v-bind=\"{ ...$attrs, ...resolvedProps }\"` instead. `v-on=\"$listeners\"`\n\t * does the same for events. Without this, built-in page components\n\t * that emit (CnDashboardPage `@widget-refresh` / `@widget-request-feature`,\n\t * CnIndexPage `@create` / `@edit` / `@delete`) cannot reach the host App.\n\t *\n\t * Resolved props win over `$attrs` on key collisions because the\n\t * spread order is `{ ...$attrs, ...resolvedProps }`.\n\t */\n\tinheritAttrs: false,\n\n\tprops: {\n\t\t/**\n\t\t * Manifest object. When omitted, falls back to the injected\n\t\t * `cnManifest` from a CnAppRoot ancestor. Provide explicitly when\n\t\t * mounting CnPageRenderer outside of CnAppRoot.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tmanifest: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Custom-component registry. Keys are the names referenced by\n\t\t * `page.component` (for `type: \"custom\"` pages). When omitted,\n\t\t * falls back to the injected `cnCustomComponents`.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tcustomComponents: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Translate function. When omitted, falls back to the injected\n\t\t * `cnTranslate`. Currently not used directly by the renderer\n\t\t * itself — exposed as a prop for symmetry and so future page\n\t\t * components rendered by the renderer can `inject('cnTranslate')`\n\t\t * via the consumer's setup.\n\t\t *\n\t\t * @type {((text: string, placeholders?: object) => string)|null}\n\t\t */\n\t\ttranslate: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Page-type registry. Map of `pages[].type` value → Vue\n\t\t * component to mount. Consumers extend the library defaults by\n\t\t * spreading them: `{ ...defaultPageTypes, report: MyReportPage }`.\n\t\t *\n\t\t * Falls back to the injected `cnPageTypes` and finally to the\n\t\t * library's `defaultPageTypes`. The special `custom` type is\n\t\t * NOT looked up here — it resolves through the customComponents\n\t\t * registry instead.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tpageTypes: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\t},\n\n\t/**\n\t * Live updates for the v2 widget-grid detail path (#222). A\n\t * `type:\"detail\"` page rendered through CnWidgetGrid gets its object\n\t * from the `cnDetailObjectContext` holder (see `loadDetailObject`),\n\t * NOT from a page component with its own subscription — so the\n\t * renderer itself subscribes to `or-object-{id}` for the loaded\n\t * object. The plugin's event-driven refetch then lands in\n\t * `store.objects[slug][id]`, which the holder reads through\n\t * reactively.\n\t *\n\t * The refs returned here are DRIVEN by `loadDetailObject`:\n\t * - `liveSubType` / `liveSubId` re-scope the subscription on route\n\t * or object change (the composable's epoch guard swaps handles).\n\t * - `liveSubEnabled` gates on (a) a v2 manifest page that actually\n\t * renders widget grids — the typed CnDetailPage dispatch path\n\t * manages its own subscription — and (b) the same\n\t * `config.subscribe: false` opt-out CnIndexPage / CnDetailPage\n\t * honour (manifest-live-updates).\n\t *\n\t * Laziness: `enabled` starts `false`, so mounting the renderer on\n\t * any non-detail page causes zero transport activity (resolving the\n\t * default store is inert per the plugin's laziness guarantee).\n\t * Unmount and route changes release via the composable's own\n\t * lifecycle; the polling fallback is the transport's concern.\n\t *\n\t * @return {object} Refs exposed on `this` for `loadDetailObject`.\n\t */\n\tsetup() {\n\t\tconst liveSubType = ref('')\n\t\tconst liveSubId = ref('')\n\t\tconst liveSubEnabled = ref(false)\n\t\tlet liveStore\n\t\ttry {\n\t\t\tliveStore = useObjectStore()\n\t\t} catch {\n\t\t\t// Pinia not installed (stand-alone / unit-test mounts) — no\n\t\t\t// live updates; loadDetailObject degrades the same way.\n\t\t\tliveStore = null\n\t\t}\n\t\tif (liveStore) {\n\t\t\tuseObjectSubscription(\n\t\t\t\tliveStore,\n\t\t\t\tliveSubType,\n\t\t\t\tliveSubId,\n\t\t\t\t{ enabled: () => Boolean(liveSubEnabled.value && liveSubType.value && liveSubId.value) },\n\t\t\t)\n\t\t}\n\t\treturn { liveSubType, liveSubId, liveSubEnabled }\n\t},\n\n\tdata() {\n\t\t// Reactive holders for the per-page sidebar visibility flag and\n\t\t// sidebar-component override. Both live on data() so Vue 2\n\t\t// reactivity tracks `.value` mutations in the watchers below;\n\t\t// `provide()` returns the same references so descendant injects\n\t\t// observe each update.\n\t\treturn {\n\t\t\tpageSidebarVisible: { value: true },\n\t\t\tpageSidebarComponent: { value: null },\n\t\t\t// Whether the per-page config modal (edit-mode cog) is open.\n\t\t\tshowConfigModal: false,\n\t\t\t// Reactive holder for the loaded object of a `type:\"detail\"`\n\t\t\t// page. `null` until the async load resolves (and on non-detail\n\t\t\t// pages). Shape when populated:\n\t\t\t// `{ objectData, schema, objectType, objectId, register, store }`.\n\t\t\t// Published via provide() as `cnDetailObjectContext` and read by\n\t\t\t// descendant CnWidgetGrid instances, which merge it into each\n\t\t\t// body/sidebar widget's props so `data` / `metadata` /\n\t\t\t// `file-manager` widgets receive the object with no per-widget\n\t\t\t// manifest props.\n\t\t\tdetailObjectContext: { value: null },\n\t\t\t// The `type:\"export\"` action currently shown in the shared\n\t\t\t// CnMassExportDialog export launcher (null = dialog closed). Set\n\t\t\t// by the `openExport` bound into the cnDispatchAction context.\n\t\t\texportAction: null,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * Whether the body slot should be editable (ADR-041). Unwraps the\n\t\t * injected `cnEditingBody`, which CnAppRoot provides as a raw ref.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tbodyEditable() {\n\t\t\tconst e = this.cnEditingBody\n\t\t\treturn Boolean(e && typeof e === 'object' && 'value' in e ? e.value : e)\n\t\t},\n\n\t\t/**\n\t\t * Convenience accessor on the reactive holder so the template\n\t\t * `v-bind:class` reads a primitive boolean. Vue 2 templates\n\t\t * unwrap `data` references but not arbitrary `{value}`\n\t\t * holders, so this stays explicit.\n\t\t */\n\t\tpageSidebarVisibleValue() {\n\t\t\treturn this.pageSidebarVisible.value !== false\n\t\t},\n\n\t\t/**\n\t\t * Entity options for the export launcher, from the active export\n\t\t * action's `entities[]` (empty hides the picker).\n\t\t *\n\t\t * @return {Array<{id: string, label: string}>}\n\t\t */\n\t\texportDialogEntities() {\n\t\t\tconst entities = this.exportAction && this.exportAction.entities\n\t\t\tif (!Array.isArray(entities)) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\treturn entities\n\t\t\t\t.map((e) => (typeof e === 'string' ? { id: e, label: e } : e))\n\t\t\t\t.filter((e) => e && e.id)\n\t\t},\n\n\t\t/**\n\t\t * Format options for the export launcher, from the active export\n\t\t * action's `formats[]` (bare ids are lifted to `{id, label}`).\n\t\t * `undefined` when the action declares none, so the dialog's\n\t\t * built-in Excel/CSV defaults apply.\n\t\t *\n\t\t * @return {Array<{id: string, label: string}>|undefined}\n\t\t */\n\t\texportDialogFormats() {\n\t\t\tconst formats = this.exportAction && this.exportAction.formats\n\t\t\tif (!Array.isArray(formats) || formats.length === 0) {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t\treturn formats\n\t\t\t\t.map((f) => (typeof f === 'string' ? { id: f, label: f.toUpperCase() } : f))\n\t\t\t\t.filter((f) => f && f.id)\n\t\t},\n\n\t\t/**\n\t\t * Effective manifest: explicit prop wins, then the reactive injected\n\t\t * source, then the one-shot `cnManifest` snapshot for hosts that\n\t\t * provide only that.\n\t\t */\n\t\teffectiveManifest() {\n\t\t\treturn this.manifest ?? this.cnManifestSource ?? this.cnManifest\n\t\t},\n\n\t\t/**\n\t\t * True when the effective manifest is a v2 manifest.\n\t\t * Detected by `manifest.$schema` containing `app-manifest-v2`.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tisV2Manifest() {\n\t\t\tconst schema = this.effectiveManifest?.$schema\n\t\t\treturn typeof schema === 'string' && schema.includes('app-manifest-v2')\n\t\t},\n\n\t\t/**\n\t\t * Groups the current page's `widgets[]` by slot value into a\n\t\t * `Map<string, WidgetEntry[]>`. Entries with unrecognised slot\n\t\t * patterns emit `console.warn` and are excluded.\n\t\t *\n\t\t * @return {Map<string, Array>}\n\t\t */\n\t\twidgetsBySlot() {\n\t\t\tconst page = this.currentPage\n\t\t\tconst map = new Map()\n\t\t\tif (!page || !Array.isArray(page.widgets)) {\n\t\t\t\treturn map\n\t\t\t}\n\n\t\t\tfor (const widget of page.widgets) {\n\t\t\t\tconst slot = widget?.slot\n\t\t\t\tif (!slot || !isKnownSlot(slot)) {\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.warn(`[CnPageRenderer] Widget \"${widget?.widgetKey}\" in page \"${page.id}\" has unrecognised slot \"${slot}\". Skipping.`)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif (!map.has(slot)) {\n\t\t\t\t\tmap.set(slot, [])\n\t\t\t\t}\n\t\t\t\tmap.get(slot).push(widget)\n\t\t\t}\n\n\t\t\treturn map\n\t\t},\n\n\t\t/**\n\t\t * Dynamic slot keys from widgetsBySlot that are not fixed known\n\t\t * slot names (i.e. `tab:*` and `section:*` patterns).\n\t\t *\n\t\t * @return {string[]}\n\t\t */\n\t\tdynamicSlotKeys() {\n\t\t\tconst FIXED_SLOTS = ['body', 'sidebar', 'header-actions', 'footer', 'modal']\n\t\t\tconst result = []\n\t\t\tfor (const key of this.widgetsBySlot.keys()) {\n\t\t\t\tif (!FIXED_SLOTS.includes(key)) {\n\t\t\t\t\tresult.push(key)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn result\n\t\t},\n\n\t\t/**\n\t\t * Proxy for the cnOpenModal inject so the provide() closure can\n\t\t * reference `this._cnOpenModal` without binding issues.\n\t\t *\n\t\t * @return {?(key: string, props?: object) => void} The injected opener, or null.\n\t\t */\n\t\t_cnOpenModal() {\n\t\t\treturn typeof this.cnOpenModal === 'function' ? this.cnOpenModal : null\n\t\t},\n\n\t\t/** Effective custom-component registry. */\n\t\teffectiveCustomComponents() {\n\t\t\treturn this.customComponents ?? this.cnCustomComponents ?? {}\n\t\t},\n\n\t\t/**\n\t\t * Effective v2 component registry. Provided by CnAppRoot via the\n\t\t * `registry` prop (kind-tagged entries: `widget`, `modal`, `page`,\n\t\t * `form-field`, `cell-renderer`). Empty when consumers haven't\n\t\t * migrated off the legacy `customComponents` prop yet. ADR-036.\n\t\t *\n\t\t * @return {object}\n\t\t */\n\t\teffectiveRegistry() {\n\t\t\treturn this.cnRegistry ?? {}\n\t\t},\n\n\t\t/**\n\t\t * Effective page-type registry. Prop wins over inject; both\n\t\t * fall back to the library's `defaultPageTypes`. Apps that want\n\t\t * the library defaults plus extras typically construct the prop\n\t\t * value as `{ ...defaultPageTypes, ...myExtras }`.\n\t\t */\n\t\teffectivePageTypes() {\n\t\t\treturn this.pageTypes ?? this.cnPageTypes ?? defaultPageTypes\n\t\t},\n\n\t\t/**\n\t\t * The app this page needs but that is not installed, or null.\n\t\t *\n\t\t * Reads the page's `requiresApp` and answers with a dependency entry\n\t\t * shaped the way CnDependencyMissing expects, so the same screen the\n\t\t * app-level check uses is reused rather than a second one written.\n\t\t *\n\t\t * `isAppInstalled` is the SAME resolver `visibleIf.appInstalled` uses.\n\t\t * Deliberately so: a menu entry hidden by one predicate and a page\n\t\t * gated by a different one would drift, and the pair would disagree\n\t\t * about whether the app is there.\n\t\t *\n\t\t * @return {{id: string, name: string}|null} The missing app, or null.\n\t\t */\n\t\t/**\n\t\t * The permission this page declares and the user does not hold, or null.\n\t\t *\n\t\t * The schema has carried `pages[].permission` as SCHEMA-ONLY since it\n\t\t * was added: \"CnPageRenderer / CnAppRoot do NOT currently gate the page\n\t\t * on it; consumers that want enforcement filter the manifest themselves\".\n\t\t * No consumer did. So a page declaring it was hidden from the MENU by\n\t\t * CnAppNav and served to anyone who typed its URL, which is the worst of\n\t\t * the two: it reads as protected to whoever declared it.\n\t\t *\n\t\t * Measured on dossiq: a non-admin opening `/settings/integrations`\n\t\t * directly got the page with seven links into admin settings, while the\n\t\t * same account correctly saw no entry for it in the navigation.\n\t\t *\n\t\t * 🔑 THE SEMANTICS ARE CnAppNav's, DELIBERATELY, so the route and the\n\t\t * menu agree. An empty list still means \"the app did not say\" and\n\t\t * allows, exactly as the menu filter does. Refusing on an empty list\n\t\t * would hide every declared page in an app that passes no `permissions`\n\t\t * — which is the shape that once rendered an Admin-settings entry for\n\t\t * nobody — and that is a separate decision from closing this hole.\n\t\t *\n\t\t * @return {string|null} The missing permission, or null when allowed.\n\t\t */\n\t\tforbiddenPagePermission() {\n\t\t\tconst required = this.currentPage?.permission\n\t\t\tif (!required) {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\tconst held = Array.isArray(this.cnPermissions) ? this.cnPermissions : []\n\t\t\tif (held.length === 0) {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\treturn held.includes(required) ? null : required\n\t\t},\n\n\t\tmissingPageDependency() {\n\t\t\tconst required = this.currentPage?.requiresApp\n\t\t\tif (!required) {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\tconst id = (typeof required === 'string' ? required : required.id)\n\t\t\tif (!id || isAppInstalled(id)) {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tid,\n\t\t\t\tname: (typeof required === 'object' && required.name) || id,\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Heading for the page-level missing-dependency screen.\n\t\t *\n\t\t * Overridden away from CnDependencyMissing's default (\"Required apps\n\t\t * are missing\"), which is written for the app-level check where\n\t\t * NOTHING works. Here the app is fine and one feature is not, and\n\t\t * saying otherwise would send the reader looking for a broken install.\n\t\t *\n\t\t * @return {string} The heading.\n\t\t */\n\t\tmissingDependencyHeading() {\n\t\t\treturn this.tr('This feature needs another app')\n\t\t},\n\n\t\t/**\n\t\t * Intro for the page-level missing-dependency screen.\n\t\t *\n\t\t * @return {string} The intro line.\n\t\t */\n\t\tmissingDependencyIntro() {\n\t\t\tconst title = (this.currentPage?.title || '')\n\t\t\tif (title) {\n\t\t\t\treturn this.tr('\"{page}\" needs the following app to be installed and enabled.').replace('{page}', title)\n\t\t\t}\n\n\t\t\treturn this.tr('This page needs the following app to be installed and enabled.')\n\t\t},\n\n\t\t/**\n\t\t * Page definition matching the current route name, or null.\n\t\t *\n\t\t * @return {object|null} The manifest page entry.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tcurrentPage() {\n\t\t\t// `meta.cnPageId` first, the route name second. The split route\n\t\t\t// `/<page>/split/:id` is registered under `<pageId>__split`, so\n\t\t\t// matching on the name alone would resolve it to no page at all\n\t\t\t// and render a blank screen at a perfectly valid address.\n\t\t\t// `buildManifestRoutes()` stamps the meta; a hand-written router\n\t\t\t// has none, and there the route name IS the page id.\n\t\t\tconst pageId = pageIdForRoute(this.$route)\n\t\t\tif (!pageId) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn this.pageById.get(pageId) ?? null\n\t\t},\n\n\t\t/**\n\t\t * The record the split pane is showing, or null when this is not a\n\t\t * split route.\n\t\t *\n\t\t * @return {string|null} The record id.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tcurrentSplitId() {\n\t\t\treturn splitIdForRoute(this.$route)\n\t\t},\n\n\t\t/**\n\t\t * `Map<pageId, page>` built once per manifest identity (Vue caches this\n\t\t * computed until `effectiveManifest` changes), replacing per-recompute\n\t\t * linear `pages.find()` — O(n) per navigation on large manifests\n\t\t * (shillinq ships 223 pages). 2026-07-06 audit item 10.\n\t\t */\n\t\tpageById() {\n\t\t\tconst pages = this.effectiveManifest?.pages\n\t\t\tconst index = new Map()\n\t\t\tif (Array.isArray(pages)) {\n\t\t\t\tfor (const page of pages) {\n\t\t\t\t\tif (page && typeof page.id === 'string' && !index.has(page.id)) {\n\t\t\t\t\t\tindex.set(page.id, page)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn index\n\t\t},\n\n\t\t/**\n\t\t * `Map<\"register schema\", detailPage>` — the first detail page bound to\n\t\t * each register+schema pair. Backs the index→detail row-click wiring\n\t\t * without re-scanning all pages per index page and per row click.\n\t\t * Memoized on `effectiveManifest`.\n\t\t */\n\t\tdetailPageByRegisterSchema() {\n\t\t\tconst pages = this.effectiveManifest?.pages\n\t\t\tconst index = new Map()\n\t\t\tif (Array.isArray(pages)) {\n\t\t\t\tfor (const page of pages) {\n\t\t\t\t\tif (!page || page.type !== 'detail') {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tconst cfg = page.config || {}\n\t\t\t\t\tconst key = `${cfg.register} ${cfg.schema}`\n\t\t\t\t\tif (!index.has(key)) {\n\t\t\t\t\t\tindex.set(key, page)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn index\n\t\t},\n\n\t\t/**\n\t\t * Remount key for the dispatched page component. Includes the data source\n\t\t * (register + schema) so changing it in the page-config modal remounts the\n\t\t * page: the self-fetch composable binds its object type + schema once at\n\t\t * setup, so without a remount a data-source change would leave the old\n\t\t * columns, create/edit form, and \"Add\" label in place.\n\t\t *\n\t\t * @return {string} A key of `id:register:schema`.\n\t\t */\n\t\tpageRenderKey() {\n\t\t\tconst page = this.currentPage\n\t\t\tif (!page) {\n\t\t\t\treturn 'none'\n\t\t\t}\n\t\t\tconst cfg = (page.config && typeof page.config === 'object' && !Array.isArray(page.config)) ? page.config : {}\n\t\t\treturn [page.id, cfg.register || '', cfg.schema || ''].join(':')\n\t\t},\n\n\t\t/**\n\t\t * Component to render for the current page. Looked up in\n\t\t * `effectivePageTypes` for built-in / library / consumer-extended\n\t\t * types; resolved against `effectiveCustomComponents` for\n\t\t * `type: \"custom\"` pages.\n\t\t *\n\t\t * Async loading is the responsibility of whoever populated the\n\t\t * `pageTypes` map (the library wraps each entry in\n\t\t * `defineAsyncComponent`); the renderer treats any value in the\n\t\t * map as a Vue component.\n\t\t */\n\t\t/**\n\t\t * Whether the current page renders any body content — a dispatched page\n\t\t * component (index/detail/dashboard/custom-with-component) or a v2 `body`\n\t\t * widget slot. False for a freshly-created custom page with no component\n\t\t * and no widgets, which drives the builder empty-state (ADR-041) so the\n\t\t * page still exposes the \"Edit with Buildiq\" affordance.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\thasRenderableBody() {\n\t\t\tif (this.resolvedComponent) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif (this.isV2Manifest && this.widgetsBySlot && this.widgetsBySlot.has('body')) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn false\n\t\t},\n\n\t\t/**\n\t\t * The detail page a split pane mounts, resolved the same way the full\n\t\t * route resolves it.\n\t\t *\n\t\t * The SAME component, deliberately. A second detail implementation\n\t\t * for the pane would drift from the full page within a month, and the\n\t\t * first thing to drift is always the thing only one of them has.\n\t\t *\n\t\t * @return {object|null} The manifest page entry, or null when the index has no detail page.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tsplitDetailPage() {\n\t\t\tconst page = this.currentPage\n\t\t\tif (!pageHasSplitView(page)) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst cfg = page.config || {}\n\t\t\tconst named = typeof cfg.rowRoute === 'string' && cfg.rowRoute !== ''\n\t\t\t\t? this.pageById.get(cfg.rowRoute)\n\t\t\t\t: null\n\t\t\treturn named ?? this.detailPageByRegisterSchema.get(`${cfg.register} ${cfg.schema}`) ?? null\n\t\t},\n\n\t\t/**\n\t\t * The component the split pane renders.\n\t\t *\n\t\t * @return {object|null} The page component, or null.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tsplitPaneComponent() {\n\t\t\tconst detail = this.splitDetailPage\n\t\t\tif (!detail) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tif (detail.type === 'custom') {\n\t\t\t\treturn this.resolveCustomComponent(detail.component || detail.slots?.main, 'page') || null\n\t\t\t}\n\t\t\treturn this.effectivePageTypes[detail.type] || null\n\t\t},\n\n\t\t/**\n\t\t * The props the split pane's detail component is mounted with.\n\t\t *\n\t\t * Built from the detail page's own declaration, so the pane shows\n\t\t * what the full route would show, plus the id the split address\n\t\t * names.\n\t\t *\n\t\t * @return {object} The prop bag.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tsplitPaneProps() {\n\t\t\tconst detail = this.splitDetailPage\n\t\t\tconst id = this.currentSplitId\n\t\t\tif (!detail || !id) {\n\t\t\t\treturn {}\n\t\t\t}\n\t\t\tconst config = detail.config || {}\n\t\t\t// `objectId` only, never a bare `id`. CnDetailPage declares no\n\t\t\t// `id` prop, so a bare one falls through onto the pane's root\n\t\t\t// element as a plain HTML attribute, and the page then answers to\n\t\t\t// `#case-1` alongside the skip link's own anchor.\n\t\t\tconst props = { ...config, objectId: id }\n\t\t\tif (props.objectType === undefined && typeof config.schema === 'string' && config.schema !== '') {\n\t\t\t\tprops.objectType = config.schema\n\t\t\t}\n\t\t\tfor (const key of ['title', 'description', 'icon']) {\n\t\t\t\tif (detail[key] !== undefined) {\n\t\t\t\t\tprops[key] = detail[key]\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (detail.tabInAddress === true) {\n\t\t\t\tprops.tabInAddress = true\n\t\t\t}\n\t\t\tif (detail.primaryAction) {\n\t\t\t\tprops.primaryAction = detail.primaryAction\n\t\t\t}\n\t\t\treturn props\n\t\t},\n\n\t\tresolvedComponent() {\n\t\t\tconst page = this.currentPage\n\t\t\tif (!page) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tif (page.type === 'custom') {\n\t\t\t\t// Two authoring styles for a custom page body:\n\t\t\t\t// 1. `page.component` — a single registry component name.\n\t\t\t\t// 2. `page.slots.main` — the body component referenced via\n\t\t\t\t// the generic slot map (same field used for header /\n\t\t\t\t// actions / sidebar overrides). When `component` is\n\t\t\t\t// absent we treat the `main` slot entry as the page body\n\t\t\t\t// so a custom page authored purely with `slots` still\n\t\t\t\t// renders. The remaining slot entries continue to mount\n\t\t\t\t// as named slots inside it via `resolvedSlotEntries`.\n\t\t\t\tconst name = page.component || page.slots?.main\n\t\t\t\tconst resolved = this.resolveCustomComponent(name, 'page')\n\t\t\t\tif (!resolved) {\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.warn(`[CnPageRenderer] Custom component \"${name}\" not found in registry for page id \"${page.id}\".`)\n\t\t\t\t\treturn null\n\t\t\t\t}\n\t\t\t\treturn resolved\n\t\t\t}\n\t\t\tconst component = this.effectivePageTypes[page.type]\n\t\t\tif (!component) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.warn(`[CnPageRenderer] Unknown page type \"${page.type}\" for page id \"${page.id}\". Add it to the pageTypes registry (e.g. via the pageTypes prop on CnAppRoot or CnPageRenderer).`)\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn component\n\t\t},\n\n\t\t/**\n\t\t * Props forwarded to the dispatched page component. Merges:\n\t\t *\n\t\t * 1. The page's static `config` object — manifest-authored data\n\t\t * shared across every visit to this route.\n\t\t * 2. The router's `$route.params` — dynamic placeholders captured\n\t\t * from the URL (e.g. `/meetings/:id/live` → `{ id: '...' }`).\n\t\t * Without this merge, children that declare a route-derived\n\t\t * prop (`props: { id: { type: String, required: true } }`)\n\t\t * receive `undefined` even when the URL clearly contains the\n\t\t * value, because the generated route definition's `props: true`\n\t\t * only binds params to `CnPageRenderer` itself, not the\n\t\t * dispatched child component. Params take precedence over\n\t\t * `config` collisions so URL truth wins; config keeps acting\n\t\t * as a default-overrides layer.\n\t\t *\n\t\t * Per-type prop validation lives on the target components.\n\t\t *\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tresolvedProps() {\n\t\t\tconst page = this.currentPage\n\t\t\t// Normalise to a plain object: an empty `config: {}` round-trips\n\t\t\t// through PHP/JSON as `[]`, and spreading an array would silently\n\t\t\t// contribute no config keys (register/schema/columns) to the page.\n\t\t\tconst rawConfig = (page?.config && typeof page.config === 'object' && !Array.isArray(page.config)) ? page.config : {}\n\t\t\t// Clone params — `resolvedProps` MAY add normalised aliases\n\t\t\t// (e.g. `objectId` for type='detail') and we must not mutate\n\t\t\t// the live `$route.params` object.\n\t\t\tconst params = { ...(this.$route?.params ?? {}) }\n\t\t\t// `manifest-route-param-sentinel`: substitute every\n\t\t\t// `@route.<param>` string in the config subtree with the\n\t\t\t// matching `$route.params.<param>` value before any other\n\t\t\t// merge. Unresolved sentinels become null (with a one-shot\n\t\t\t// console.warn per pageId+sentinel).\n\t\t\tconst pageId = page?.id ?? '<unknown>'\n\t\t\tlet config = resolveRouteSentinels(rawConfig, params, pageId)\n\t\t\t// Schema v2 lifts a uniform set of page-level fields out of\n\t\t\t// `config` so every page type can declare them without\n\t\t\t// per-type schema branches. Forward those to the dispatched\n\t\t\t// component so they reach typed props (e.g.\n\t\t\t// CnDetailPage.title, CnDetailPage.widgets). Listed\n\t\t\t// explicitly to keep the prop surface minimal — schema\n\t\t\t// fields not in this list stay private to the renderer.\n\t\t\tconst topLevel = {}\n\t\t\tfor (const key of ['title', 'description', 'icon', 'widgets', 'actions', 'sidebar']) {\n\t\t\t\tif (page && page[key] !== undefined) {\n\t\t\t\t\ttopLevel[key] = page[key]\n\t\t\t\t}\n\t\t\t}\n\t\t\t// type:\"custom\" dispatches an app-authored component that usually\n\t\t\t// declares NONE of the lifted fields as props. Vue's attribute\n\t\t\t// fallthrough would then paint them onto the component's root\n\t\t\t// element as plain HTML attributes — `title=\"Vault\"` becomes a\n\t\t\t// browser tooltip hovering over the ENTIRE page, and icon/widgets\n\t\t\t// turn into junk markup. Forward a lifted field to a custom\n\t\t\t// component only when its definition actually declares the prop.\n\t\t\tif (page?.type === 'custom') {\n\t\t\t\t// A defineAsyncComponent wrapper exposes no `props` until its\n\t\t\t\t// loader resolves — unwrap the resolved definition when\n\t\t\t\t// available so a lazily-registered custom page still receives\n\t\t\t\t// its declared lifted fields. Before resolution the fields\n\t\t\t\t// are withheld, which is the safe default here: withheld\n\t\t\t\t// means no stray root attributes, and the async component\n\t\t\t\t// renders nothing yet anyway.\n\t\t\t\tconst resolved = this.resolvedComponent\n\t\t\t\tconst declared = (resolved?.__asyncResolved ?? resolved)?.props\n\t\t\t\tconst declares = (key) => (Array.isArray(declared)\n\t\t\t\t\t? declared.includes(key)\n\t\t\t\t\t: Boolean(declared && key in declared))\n\t\t\t\tfor (const key of Object.keys(topLevel)) {\n\t\t\t\t\tif (!declares(key)) {\n\t\t\t\t\t\tdelete topLevel[key]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// NOTE on ADR-036 page-level `widgets[]`: it is NOT translated into\n\t\t\t// the typed component's `widgets` + `layout` props here.\n\t\t\t//\n\t\t\t// An earlier cut of this fix did exactly that, and the suite caught\n\t\t\t// why it is wrong: body widgets on the widget-grid path are fed\n\t\t\t// their object context by the live-context HOLDER\n\t\t\t// (`detailObjectContext`, #222) — subscription, re-render on store\n\t\t\t// cache updates, re-scoping when the route object changes. Handing\n\t\t\t// the widgets to the typed component instead silently dropped all\n\t\t\t// of that; `CnPageRendererV2DetailLiveContext` went red on the\n\t\t\t// widget rendering \"none\" where the holder had been supplying the\n\t\t\t// object.\n\t\t\t//\n\t\t\t// So the widgets keep being rendered by CnWidgetGrid, with the\n\t\t\t// holder intact. The typed component supplies only what was\n\t\t\t// actually missing — its chrome — by hosting the grid in its\n\t\t\t// default slot (see the template).\n\t\t\t// `config.actionToggles` is a typed object sugaring the nine\n\t\t\t// show*/selectable toggles on type='index' pages. Flatten\n\t\t\t// each key into the top-level config namespace UNDER any\n\t\t\t// explicit config.<key> (so explicit wins). Strip the\n\t\t\t// container before forwarding — CnIndexPage has no\n\t\t\t// `actionToggles` prop.\n\t\t\tconst isIndex = page?.type === 'index'\n\t\t\t// When an index page has somewhere to open a row, make a row click\n\t\t\t// go there: set `rowClickToView` so the row body emits `row-click`\n\t\t\t// (→ onRowOpen navigates) even though the page is selectable.\n\t\t\t// Selection stays available via the checkbox. An explicit\n\t\t\t// `config.rowClickToView` still wins (merged below).\n\t\t\t//\n\t\t\t// Two ways to have somewhere to open:\n\t\t\t// 1. `config.rowRoute` — an explicit route/page NAME. Needed\n\t\t\t// whenever the row's detail surface is NOT a `type:\"detail\"`\n\t\t\t// page: a `type:\"custom\"` authoring canvas, a form page, a\n\t\t\t// page in another register. Without this the key parsed,\n\t\t\t// validated and did nothing, so a manifest that authored it\n\t\t\t// shipped an index whose rows were simply dead on click\n\t\t\t// (observed on hermiq GraphIndex → GraphDetail).\n\t\t\t// 2. A matching `type:\"detail\"` page (same register + schema).\n\t\t\tif (isIndex && pageHasSplitView(page)) {\n\t\t\t\t// The split view and the record it is showing. `splitId` comes\n\t\t\t\t// from the route rather than from config, because the address\n\t\t\t\t// is the source of truth for which record is open: that is\n\t\t\t\t// what makes the split view a place you can link to.\n\t\t\t\ttopLevel.splitView = page.splitView\n\t\t\t\ttopLevel.splitId = this.currentSplitId || ''\n\t\t\t\ttopLevel.splitCloseRoute = page.id\n\t\t\t}\n\t\t\tif (isIndex && page?.manualOrder === true) {\n\t\t\t\ttopLevel.manualOrder = true\n\t\t\t\ttopLevel.manualOrderId = page.id\n\t\t\t}\n\t\t\tif (isIndex) {\n\t\t\t\tconst hasRowRoute = typeof config.rowRoute === 'string' && config.rowRoute !== ''\n\t\t\t\tconst hasDetail = this.detailPageByRegisterSchema.has(`${config.register} ${config.schema}`)\n\t\t\t\tif (hasRowRoute || hasDetail || pageHasSplitView(page)) {\n\t\t\t\t\ttopLevel.rowClickToView = true\n\t\t\t\t\t// The View row action links to where a row click opens.\n\t\t\t\t\ttopLevel.viewTo = (row) => this.rowOpenTarget(row)\n\t\t\t\t} else if (config.rowClickToView === true) {\n\t\t\t\t\t// Nowhere to open a row, so the click selects instead of doing nothing.\n\t\t\t\t\tconfig = { ...config, rowClickToView: false }\n\t\t\t\t}\n\t\t\t\t// `editOpensDetail` is NOT derived from that signal. It used to be,\n\t\t\t\t// on the reasoning that a record with a detail page is better edited\n\t\t\t\t// there than in a modal of flat scalars. But `@editOpen` is bound to\n\t\t\t\t// the same `onRowOpen` as `@rowClick`, so the result was an Edit that\n\t\t\t\t// did precisely what clicking the row does — the pane on a split\n\t\t\t\t// view, the detail page otherwise — and no way left to reach the\n\t\t\t\t// form. Opening a record and editing it are different acts and get\n\t\t\t\t// different affordances. A page that does want the old routing asks\n\t\t\t\t// for it with `config.editOpensDetail: true`.\n\t\t\t}\n\t\t\tlet normalizedConfig = config\n\t\t\tif (isIndex && config.actionToggles && typeof config.actionToggles === 'object' && !Array.isArray(config.actionToggles)) {\n\t\t\t\tconst { actionToggles, ...rest } = config\n\t\t\t\tnormalizedConfig = { ...actionToggles, ...rest }\n\t\t\t}\n\t\t\t// Type='detail' object-context mapping. The manifest declares\n\t\t\t// `config.schema` and `:id` route param; CnDetailPage's\n\t\t\t// sidebar gating needs `objectType` + `objectId` props (see\n\t\t\t// CnDetailPage.syncSidebarState — `objectSidebarState.active`\n\t\t\t// stays false without them, so the host's mounted\n\t\t\t// CnObjectSidebar never renders). Bridge the names here so\n\t\t\t// every consumer doesn't have to duplicate the alias in its\n\t\t\t// own customComponents wrapper. Only fills when the typed\n\t\t\t// prop is unset, so `config.objectType` or\n\t\t\t// `params.objectId` still wins.\n\t\t\tconst isDetail = page?.type === 'detail'\n\t\t\tif (isDetail && page.tabInAddress === true) {\n\t\t\t\ttopLevel.tabInAddress = true\n\t\t\t}\n\t\t\tif (isDetail && page.primaryAction) {\n\t\t\t\ttopLevel.primaryAction = page.primaryAction\n\t\t\t}\n\t\t\tif (isDetail) {\n\t\t\t\t// The other half of the index rule above: a schema-bound detail\n\t\t\t\t// page gets its own Edit affordance. Set unconditionally for\n\t\t\t\t// schema-bound detail pages — the index stops offering the modal\n\t\t\t\t// for exactly this set of pages, so a detail page that did not\n\t\t\t\t// gain the button would leave its records with no edit surface at\n\t\t\t\t// all. `config.showEditAction` still wins (merged below).\n\t\t\t\tif (typeof normalizedConfig.schema === 'string' && normalizedConfig.schema.length > 0) {\n\t\t\t\t\ttopLevel.showEditAction = true\n\t\t\t\t}\n\t\t\t\tif (normalizedConfig.objectType === undefined && typeof normalizedConfig.schema === 'string' && normalizedConfig.schema.length > 0) {\n\t\t\t\t\tnormalizedConfig = { ...normalizedConfig, objectType: normalizedConfig.schema }\n\t\t\t\t}\n\t\t\t\tif (params.objectId === undefined && typeof params.id === 'string' && params.id.length > 0) {\n\t\t\t\t\tparams.objectId = params.id\n\t\t\t\t}\n\t\t\t\tconst listPage = this.listPageForDetail(normalizedConfig)\n\t\t\t\tif (listPage) {\n\t\t\t\t\ttopLevel.notFoundRoute = { name: listPage.id }\n\t\t\t\t\ttopLevel.notFoundRouteLabel = this.tr(listPage.title || listPage.id)\n\t\t\t\t}\n\t\t\t}\n\t\t\t// `config.readOnly:true` shorthand on type='index' (REQ-MIPFU-4):\n\t\t\t// expand to the nine read-only flags MERGED UNDER `config.*`\n\t\t\t// so explicit `config.showAdd:true` still wins. Strip the\n\t\t\t// `readOnly` key before forwarding — CnIndexPage has no\n\t\t\t// `readOnly` prop.\n\t\t\tif (isIndex && normalizedConfig.readOnly === true) {\n\t\t\t\tconst { readOnly, ...rest } = normalizedConfig\n\t\t\t\treturn { ...topLevel, ...READ_ONLY_DEFAULTS, ...rest, ...params }\n\t\t\t}\n\t\t\t// `config.createOverride` can be declared in the JSON manifest as a\n\t\t\t// STRING naming an async create handler the consumer registered in\n\t\t\t// its customComponents registry (functions are valid registry\n\t\t\t// values). Resolve it to the function so CnIndexPage's per-schema\n\t\t\t// create-override hook fires from a purely declarative page. A\n\t\t\t// non-string value (an actual function passed programmatically) is\n\t\t\t// left untouched. Unresolved names are dropped with a one-shot warn.\n\t\t\tif (isIndex && typeof normalizedConfig.createOverride === 'string') {\n\t\t\t\tconst name = normalizedConfig.createOverride\n\t\t\t\tconst fn = this.resolveCreateOverride(name)\n\t\t\t\tconst { createOverride, ...rest } = normalizedConfig\n\t\t\t\tif (typeof fn === 'function') {\n\t\t\t\t\tnormalizedConfig = { ...rest, createOverride: fn }\n\t\t\t\t} else {\n\t\t\t\t\t// eslint-disable-next-line no-console -- a deliberate warning to the developer integrating this component\n\t\t\t\t\tconsole.warn(`[CnPageRenderer] config.createOverride \"${name}\" did not resolve to a registered function; dropping it.`)\n\t\t\t\t\tnormalizedConfig = rest\n\t\t\t\t}\n\t\t\t}\n\t\t\t// A named entity source loads with the `sourceConfig` PROP, and the\n\t\t\t// renderer never set it: config keys spread as individual props, so\n\t\t\t// `config.app` (flows) or `config.scope` (tasks) reached the page as\n\t\t\t// inert attributes and the loader received `{}`. Hand the resolved\n\t\t\t// config through as the default `sourceConfig` — the loader picks\n\t\t\t// the keys it knows and ignores the rest. An explicit\n\t\t\t// `config.sourceConfig` block still wins unchanged.\n\t\t\tif (isIndex\n\t\t\t\t&& typeof normalizedConfig.entitySource === 'string'\n\t\t\t\t&& normalizedConfig.entitySource.length > 0\n\t\t\t\t&& normalizedConfig.sourceConfig === undefined) {\n\t\t\t\tnormalizedConfig = { ...normalizedConfig, sourceConfig: { ...normalizedConfig } }\n\t\t\t}\n\t\t\t// Precedence (highest wins): route params > config > top-level\n\t\t\t// page fields. URL truth trumps everything; config trumps\n\t\t\t// top-level so per-route config still beats the page default.\n\t\t\treturn { ...topLevel, ...normalizedConfig, ...params }\n\t\t},\n\n\t\t/**\n\t\t * Resolved `{ register, schema, objectId, slug }` for a\n\t\t * `type:\"detail\"` page, or `null` for any other page (or when the\n\t\t * triple is incomplete). `objectId` comes from the resolved\n\t\t * `config.idParam` (a `@route.*` sentinel like `\"@route.id\"`),\n\t\t * falling back to `config.objectId`, the `:objectId` route param,\n\t\t * then the `:id` route param. `slug` is the `${register}-${schema}`\n\t\t * object-type key registered in the store (matches the convention\n\t\t * used by `autoRegisterCustomTypes` and CnIndexPage self-fetch).\n\t\t *\n\t\t * Drives `loadDetailObject` (watched below). Kept separate from\n\t\t * `resolvedProps` so the (potentially async) object load only runs\n\t\t * for detail pages and only re-runs when the triple changes.\n\t\t *\n\t\t * @return {{register: string, schema: string, objectId: string, slug: string}|null}\n\t\t */\n\t\tdetailLoadContext() {\n\t\t\t// A split address resolves to the INDEX page, so the pane's record\n\t\t\t// needs the detail page the pane mounts. Without it the pane got no\n\t\t\t// object context at all and every `@object.<field>` token in it\n\t\t\t// resolved against nothing.\n\t\t\tconst onDetailRoute = this.currentPage?.type === 'detail'\n\t\t\tconst splitId = this.currentSplitId\n\t\t\tconst page = onDetailRoute\n\t\t\t\t? this.currentPage\n\t\t\t\t: (splitId ? this.splitDetailPage : null)\n\t\t\tif (!page || page.type !== 'detail') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst params = { ...(this.$route?.params ?? {}) }\n\t\t\tconst config = resolveRouteSentinels(page.config ?? {}, params, page.id ?? '<unknown>')\n\t\t\tconst register = config.register\n\t\t\tconst schema = config.schema\n\t\t\t// The split address names the record, not the detail page's idParam.\n\t\t\tconst objectId = onDetailRoute\n\t\t\t\t? (config.idParam || config.objectId || params.objectId || params.id)\n\t\t\t\t: splitId\n\t\t\tif (typeof register !== 'string' || register.length === 0\n\t\t\t\t|| typeof schema !== 'string' || schema.length === 0\n\t\t\t\t|| typeof objectId !== 'string' || objectId.length === 0) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn { register, schema, objectId, slug: `${register}-${schema}` }\n\t\t},\n\n\t\t/**\n\t\t * Combined slot-override map for the dispatched page component.\n\t\t * Sources:\n\t\t * 1. `page.slots` — generic { slotName: registryName } map.\n\t\t * 2. `page.headerComponent` — sugar for `slots.header`.\n\t\t * 3. `page.actionsComponent` — sugar for `slots.actions`.\n\t\t *\n\t\t * Sugar fields take precedence when both are set so that the\n\t\t * legacy fields remain meaningful in mixed manifests. Returned\n\t\t * as an array of `{ name, component }` entries to make the\n\t\t * `<template v-for>` + dynamic-slot-name pattern work in Vue 2.\n\t\t */\n\t\t/**\n\t\t * The DETAIL page's own slot components, for the record mounted in the\n\t\t * split pane.\n\t\t *\n\t\t * `resolvedSlotEntries` belongs to the index page and cannot serve here:\n\t\t * the pane mounts a different manifest page, and a `type: \"custom\"` widget\n\t\t * resolves through its host page's `slots` map and nothing else. Without\n\t\t * this the pane drew an empty grid cell wherever the detail page declared\n\t\t * one — the same widget renders correctly on its own route, so the record\n\t\t * silently lost content by being opened beside the list instead of from it.\n\t\t *\n\t\t * @return {Array<{name: string, component: object}>}\n\t\t */\n\t\tsplitPaneSlotEntries() {\n\t\t\tconst page = this.splitDetailPage\n\t\t\tif (!page) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\t// Same two sugar keys `resolvedSlotEntries` maps for the full route,\n\t\t\t// or the pane silently drops the page's actions component.\n\t\t\tconst map = { ...(page.slots ?? {}) }\n\t\t\tif (page.headerComponent) {\n\t\t\t\tmap.header = page.headerComponent\n\t\t\t}\n\t\t\tif (page.actionsComponent) {\n\t\t\t\tmap.actions = page.actionsComponent\n\t\t\t}\n\t\t\tconst entries = []\n\t\t\tfor (const [name, registryName] of Object.entries(map)) {\n\t\t\t\tconst component = this.resolveRegistryName(registryName, name)\n\t\t\t\tif (component) {\n\t\t\t\t\tentries.push({ name, component })\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn entries\n\t\t},\n\n\t\tresolvedSlotEntries() {\n\t\t\tconst page = this.currentPage\n\t\t\tif (!page) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\tconst map = { ...(page.slots ?? {}) }\n\t\t\t// For a custom page that has no explicit `component`, `slots.main`\n\t\t\t// is promoted to the page BODY by `resolvedComponent`, so drop it\n\t\t\t// here — otherwise it would also try to mount as a (non-existent)\n\t\t\t// `main` named slot inside itself.\n\t\t\tif (page.type === 'custom' && !page.component && map.main) {\n\t\t\t\tdelete map.main\n\t\t\t}\n\t\t\tif (page.headerComponent) {\n\t\t\t\tmap.header = page.headerComponent\n\t\t\t}\n\t\t\tif (page.actionsComponent) {\n\t\t\t\tmap.actions = page.actionsComponent\n\t\t\t}\n\t\t\tconst entries = []\n\t\t\tfor (const [name, registryName] of Object.entries(map)) {\n\t\t\t\tconst component = this.resolveRegistryName(registryName, name)\n\t\t\t\tif (component) {\n\t\t\t\t\tentries.push({ name, component })\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn entries\n\t\t},\n\n\t\t/**\n\t\t * Per-page sidebar visibility flag derived from the page\n\t\t * entry's top-level `sidebar.show` field (sibling of `config`).\n\t\t * Defaults to `true` when unset. Watched below to push the\n\t\t * value into the reactive `pageSidebarVisible` holder shared\n\t\t * via provide/inject with `CnAppRoot`.\n\t\t */\n\t\tcurrentPageSidebarVisible() {\n\t\t\tconst page = this.currentPage\n\t\t\tif (!page || !page.sidebar || typeof page.sidebar !== 'object') {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn page.sidebar.show !== false\n\t\t},\n\n\t\t/**\n\t\t * Per-page sidebar component derived from the page entry's\n\t\t * top-level `sidebarComponent` field (sibling of `config`).\n\t\t * The string is resolved against the effective\n\t\t * `customComponents` registry — same registry as\n\t\t * `headerComponent`, `actionsComponent`, `cardComponent`, and\n\t\t * `slots.*`. Returns `null` when the field is unset, the\n\t\t * registry name is missing, or resolution fails (a\n\t\t * `console.warn` is logged in the missing-name case so\n\t\t * manifest authors notice misconfiguration). Watched below to\n\t\t * push the value into the reactive `pageSidebarComponent`\n\t\t * holder shared via provide/inject with `CnAppRoot`.\n\t\t *\n\t\t * @return {object|null} The resolved Vue component, or null.\n\t\t */\n\t\tcurrentPageSidebarComponent() {\n\t\t\tconst page = this.currentPage\n\t\t\tif (!page || typeof page.sidebarComponent !== 'string' || page.sidebarComponent.length === 0) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst name = page.sidebarComponent\n\t\t\tconst resolved = this.resolveCustomComponent(name, 'page')\n\t\t\tif (!resolved) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.warn(`[CnPageRenderer] Sidebar component \"${name}\" referenced by page id \"${page.id}\" not found in registry or customComponents.`)\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn resolved\n\t\t},\n\n\t\t/**\n\t\t * @deprecated Use `resolvedSlotEntries` for general slot\n\t\t * resolution. Retained for compatibility with code that read the\n\t\t * computed directly.\n\t\t */\n\t\theaderOverride() {\n\t\t\treturn this.resolvedSlotEntries.find((e) => e.name === 'header')?.component ?? null\n\t\t},\n\n\t\t/**\n\t\t * @deprecated See `headerOverride`.\n\t\t */\n\t\tactionsOverride() {\n\t\t\treturn this.resolvedSlotEntries.find((e) => e.name === 'actions')?.component ?? null\n\t\t},\n\t},\n\n\twatch: {\n\t\t/**\n\t\t * Auto-register object types for `type:\"custom\"` pages whose\n\t\t * manifest config declares `register` + `schema` (single type)\n\t\t * and/or `types: [{ name, register, schema }, ...]` (multi-type).\n\t\t *\n\t\t * For `type:\"index\"` and `type:\"detail\"` pages, the underlying\n\t\t * CnIndexPage / CnDetailPage components self-register when\n\t\t * mounted with `register` + `schema` props — so the renderer\n\t\t * does nothing extra for those. Custom components have no such\n\t\t * guarantee: they are bespoke per-app Vue components and would\n\t\t * each have to remember to call `registerObjectType` in their\n\t\t * own `mounted()` hook. Mirroring index/detail's zero-config\n\t\t * behaviour for the manifest-driven custom case (declared\n\t\t * `register` + `schema`) keeps the manifest the single source\n\t\t * of truth and removes a per-component landmine.\n\t\t *\n\t\t * Runs `immediate: true` so first mount registers before the\n\t\t * custom component's mounted() hook fires; re-runs on route\n\t\t * change in case the same CnPageRenderer instance is reused\n\t\t * for a different `type:\"custom\"` page.\n\t\t *\n\t\t * Defensive: every step is wrapped — a Pinia-not-installed\n\t\t * test harness, a missing store method, or a thrown error\n\t\t * inside `registerObjectType` all degrade to a single\n\t\t * `console.warn` so the page still mounts.\n\t\t *\n\t\t * See issue ConductionNL/nextcloud-vue#341.\n\t\t */\n\t\tcurrentPage: {\n\t\t\timmediate: true,\n\t\t\thandler() {\n\t\t\t\tthis.autoRegisterCustomTypes()\n\t\t\t},\n\t\t},\n\n\t\tcurrentPageSidebarVisible: {\n\t\t\timmediate: true,\n\t\t\thandler(visible) {\n\t\t\t\t// Mutate the shared holder's `.value` so descendant\n\t\t\t\t// injects (notably CnAppRoot) re-render the slot gate.\n\t\t\t\tthis.pageSidebarVisible.value = visible\n\t\t\t\t// When BOTH visibility is off AND a sidebar component\n\t\t\t\t// was declared, the sidebarComponent is dead config.\n\t\t\t\t// Log once at watcher flush time so manifest authors\n\t\t\t\t// notice the misconfiguration. Visibility wins — the\n\t\t\t\t// component holder still carries the resolved value\n\t\t\t\t// for downstream consumers that inspect it directly.\n\t\t\t\tif (visible === false && this.currentPage?.sidebarComponent) {\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.warn(`[CnPageRenderer] Page id \"${this.currentPage.id}\" declares both sidebar.show: false and sidebarComponent \"${this.currentPage.sidebarComponent}\". Visibility wins; the sidebarComponent will not render.`)\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\n\t\tcurrentPageSidebarComponent: {\n\t\t\timmediate: true,\n\t\t\thandler(component) {\n\t\t\t\t// Mutate the shared holder's `.value` so descendant\n\t\t\t\t// injects (notably CnAppRoot) re-render the slot\n\t\t\t\t// default content with the resolved component.\n\t\t\t\tthis.pageSidebarComponent.value = component\n\t\t\t},\n\t\t},\n\n\t\t/**\n\t\t * Load (and reload on change) the object backing a `type:\"detail\"`\n\t\t * page so its body/sidebar widgets can render it. Runs\n\t\t * `immediate: true` so the first paint kicks the fetch; re-runs\n\t\t * whenever the register/schema/objectId triple changes (e.g.\n\t\t * navigating between two detail routes on the same renderer).\n\t\t * Clears the context on non-detail pages.\n\t\t */\n\t\tdetailLoadContext: {\n\t\t\timmediate: true,\n\t\t\tdeep: true,\n\t\t\thandler() {\n\t\t\t\tthis.loadDetailObject()\n\t\t\t},\n\t\t},\n\t},\n\n\tcreated() {\n\t\t// Surface the page id in Vue devtools and stack traces. The base\n\t\t// component name `CnPageRenderer` becomes `CnPageRenderer:<id>`\n\t\t// for the lifetime of this instance.\n\t\tif (this.currentPage) {\n\t\t\tthis.$options.name = `CnPageRenderer:${this.currentPage.id}`\n\t\t} else if (this.$route) {\n\t\t\t// Router is present but no page matches — warn so developers notice misconfigured routes.\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.warn(`[CnPageRenderer] No page found for $route.name = \"${this.$route.name}\". The renderer will mount nothing.`)\n\t\t}\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Resolve a UI string through the consumer's translate function\n\t\t * (`translate` prop, else injected `cnTranslate`), falling back to the\n\t\t * English source key. Used for the builder empty-state copy.\n\t\t *\n\t\t * @param {string} key The English source string.\n\t\t * @return {string} The translated (or source) string.\n\t\t */\n\t\ttr(key) {\n\t\t\tconst fn = this.translate || this.cnTranslate\n\t\t\treturn typeof fn === 'function' ? fn(key) : key\n\t\t},\n\n\t\t/**\n\t\t * The index page a detail page returns to: the list named in the\n\t\t * address (`_from`), else the first index page on the same register and\n\t\t * schema.\n\t\t *\n\t\t * @param {object} config The detail page's normalized config.\n\t\t * @return {object|null} The manifest page, or null when there is none.\n\t\t */\n\t\tlistPageForDetail(config) {\n\t\t\tconst fromId = listContextFromRoute(this.$route)?.pageId\n\t\t\tconst from = fromId ? this.pageById.get(fromId) : null\n\t\t\tif (from?.type === 'index') {\n\t\t\t\treturn from\n\t\t\t}\n\t\t\tconst pages = this.effectiveManifest?.pages\n\t\t\tif (!Array.isArray(pages) || !config.schema) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn pages.find((p) => p?.type === 'index'\n\t\t\t\t&& p.config?.register === config.register\n\t\t\t\t&& p.config?.schema === config.schema) ?? null\n\t\t},\n\n\t\t/**\n\t\t * Route the export launcher's confirm payload (`{ format, entity? }`)\n\t\t * to the export action's `handler` (resolved against the manifest\n\t\t * actions map — the same registry `type:\"handler\"` actions use). The\n\t\t * handler does the actual download (e.g. an app's ExportService) and\n\t\t * its resolved/rejected promise drives the dialog's result phase. A\n\t\t * missing handler surfaces as a dialog error (never a silent success).\n\t\t *\n\t\t * @param {{format: string, entity?: string}} payload The dialog's confirm payload.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync onExportConfirm(payload) {\n\t\t\tconst action = this.exportAction\n\t\t\tconst dialog = this.$refs.exportDialog\n\t\t\tconst setResult = (result) => {\n\t\t\t\tif (dialog && typeof dialog.setResult === 'function') {\n\t\t\t\t\tdialog.setResult(result)\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst handlers = this.effectiveManifest?.actions ?? {}\n\t\t\tconst fn = action && action.handler && handlers[action.handler]\n\t\t\tif (typeof fn !== 'function') {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.warn(`[CnPageRenderer] export action \"${action && action.id}\" has no resolvable handler \"${action && action.handler}\" in the manifest actions map.`)\n\t\t\t\tsetResult({ error: t('nextcloud-vue', 'No export handler is configured') })\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait fn(payload, action)\n\t\t\t\tsetResult({ success: true })\n\t\t\t} catch (e) {\n\t\t\t\tsetResult({ error: (e && e.message) || t('nextcloud-vue', 'Export failed') })\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Open a row's detail page. Bound to an index page's `@view` (the\n\t\t * built-in eye action) and `@row-click`, this is what makes \"View\"\n\t\t * navigate for manifest-driven index pages — `CnIndexPage` only emits\n\t\t * the event, so without this the action is a no-op. Resolves the\n\t\t * matching `type: 'detail'` page (same `register` + `schema` as the\n\t\t * current index page) and pushes to it with the row's id in whichever\n\t\t * param that page's route declares — `:id`, `:objectId`, anything.\n\t\t * No-ops when there is no detail page, no router, or no resolvable id.\n\t\t * A ctrl/cmd/shift or middle click opens the same address in a new tab.\n\t\t *\n\t\t * @param {object} row The clicked / viewed row object.\n\t\t * @param {MouseEvent} [event] The originating click/auxclick event, when there is one.\n\t\t * @return {void}\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tonRowOpen(row, event) {\n\t\t\t// Only a native event can ask for a new tab.\n\t\t\tconst nativeEvent = (typeof Event !== 'undefined' && event instanceof Event) ? event : undefined\n\t\t\t// The index page already opened this row in a new tab.\n\t\t\tif (isNewTabHandled(nativeEvent)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst target = this.rowOpenTarget(row, true)\n\t\t\tif (target) {\n\t\t\t\topenRowTarget(nativeEvent, target, this.$router)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Where an index row opens: the split view beside the list, else\n\t\t * `config.rowRoute` or the matching detail page. Also the target of the\n\t\t * View row action's link.\n\t\t *\n\t\t * @param {object} row The row.\n\t\t * @param {boolean} [warn] Log a misconfigured route (on a click, not per render).\n\t\t * @return {object|null} The router location, or null when the row opens nowhere.\n\t\t */\n\t\trowOpenTarget(row, warn = false) {\n\t\t\tconst page = this.currentPage\n\t\t\tconst router = this.$router\n\t\t\tif (!page || page.type !== 'index' || !router || !row || typeof row !== 'object') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst cfg = page.config || {}\n\t\t\tconst self0 = row['@self'] || {}\n\t\t\tconst rowId = row.id ?? self0.id ?? self0.uuid ?? row.uuid\n\t\t\t// A page declaring a split view opens the row BESIDE the list, at\n\t\t\t// its own address, rather than navigating away from it. This\n\t\t\t// branch comes first and is deliberately unconditional on\n\t\t\t// `config.rowRoute`: the split view is the page saying where its\n\t\t\t// rows open, and it is a stronger statement than a route name,\n\t\t\t// because it also says the list must not unmount.\n\t\t\tif (pageHasSplitView(page) && rowId !== undefined && rowId !== null && rowId !== '') {\n\t\t\t\tconst splitName = splitRouteName(page.id)\n\t\t\t\tif (this.routeNameIsKnown(splitName) === false) {\n\t\t\t\t\tif (warn) {\n\t\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\t\tconsole.warn(`[CnPageRenderer] Index page \"${page.id}\" declares splitView, but the router has no \"${splitName}\" route. Build the routes with buildManifestRoutes() or the split view cannot open.`)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst splitPath = routePathFor(router, splitName)\n\t\t\t\t\treturn {\n\t\t\t\t\t\tname: splitName,\n\t\t\t\t\t\tparams: buildRouteParams(splitPath, rowId, this.$route?.params),\n\t\t\t\t\t\tquery: this.$route?.query || {},\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// `config.rowRoute` names the target explicitly and WINS: it is the\n\t\t\t// only way to reach a detail surface that is not a `type:\"detail\"`\n\t\t\t// page (an authoring canvas, a form page), and an author who named\n\t\t\t// a route meant that route.\n\t\t\tconst rowRoute = (typeof cfg.rowRoute === 'string' && cfg.rowRoute !== '') ? cfg.rowRoute : null\n\t\t\tconst detail = this.detailPageByRegisterSchema.get(`${cfg.register} ${cfg.schema}`)\n\t\t\tconst target = rowRoute ?? detail?.id ?? null\n\t\t\tif (!target) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst self = row['@self'] || {}\n\t\t\tconst id = row.id ?? self.id ?? self.uuid ?? row.uuid\n\t\t\tif (id === undefined || id === null || id === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\t// A name the router does not have makes every row click a no-op that\n\t\t\t// looks exactly like a broken table, so name the mistake instead of\n\t\t\t// letting push() reject into a silent catch. Feature-detected: only\n\t\t\t// some router versions can be asked.\n\t\t\tif (this.routeNameIsKnown(target) === false) {\n\t\t\t\tif (warn) {\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.warn(`[CnPageRenderer] Index page \"${page.id}\" opens rows on route \"${target}\", which the router does not have. Row clicks will do nothing.`)\n\t\t\t\t}\n\t\t\t\treturn null\n\t\t\t}\n\t\t\t// The param name comes from the TARGET'S OWN path, never a\n\t\t\t// hardcoded `id`: a manifest is free to write\n\t\t\t// `/applications/:objectId`, and vue-router answers a mismatch by\n\t\t\t// discarding the param and throwing `Missing required param`.\n\t\t\t// Manifest first, router second — a `rowRoute` may name a route\n\t\t\t// registered outside the manifest.\n\t\t\tconst path = this.pageById.get(target)?.route ?? routePathFor(router, target)\n\t\t\tconst params = buildRouteParams(path, id, this.$route?.params)\n\t\t\t// The record carries the list it came from, so its detail page can\n\t\t\t// offer next and previous within THAT list, in the filter and the\n\t\t\t// sort the handler was looking at. Without this the detail page\n\t\t\t// has an id and nothing else, and \"next\" could only ever mean\n\t\t\t// next in some order nobody chose.\n\t\t\treturn { name: target, params, query: this.rowOpenQuery() }\n\t\t},\n\n\t\t/**\n\t\t * The query a record's address carries so it can step through the list\n\t\t * it was opened from.\n\t\t *\n\t\t * Read off the CURRENT route, which is the list's own address and\n\t\t * already holds its search, its sort and its filters.\n\t\t *\n\t\t * @return {object} The query for the record's route.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\trowOpenQuery() {\n\t\t\tconst page = this.currentPage\n\t\t\tconst route = this.$route\n\t\t\tif (!page || page.type !== 'index' || !route) {\n\t\t\t\treturn {}\n\t\t\t}\n\t\t\tconst query = route.query || {}\n\t\t\treturn listContextToQuery({\n\t\t\t\tpageId: page.id,\n\t\t\t\tsearch: typeof query._search === 'string' ? query._search : '',\n\t\t\t\tsortKeys: parseSortKeys(query._order),\n\t\t\t\tfilters: query,\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Whether the router has a route by this name.\n\t\t *\n\t\t * Returns `true` when the router cannot be asked (an older router, or a\n\t\t * test double), so an unanswerable question never blocks navigation.\n\t\t *\n\t\t * @param {string} name The route name.\n\t\t * @return {boolean} False only when the router positively lacks it.\n\t\t */\n\t\trouteNameIsKnown(name) {\n\t\t\tconst router = this.$router\n\t\t\tif (!router) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif (typeof router.hasRoute === 'function') {\n\t\t\t\treturn router.hasRoute(name)\n\t\t\t}\n\t\t\tif (typeof router.getRoutes === 'function') {\n\t\t\t\tconst routes = router.getRoutes() || []\n\t\t\t\treturn routes.some((route) => route && route.name === name)\n\t\t\t}\n\t\t\treturn true\n\t\t},\n\n\t\t/**\n\t\t * Resolve a custom-component reference (page.component,\n\t\t * page.headerComponent, page.actionsComponent, page.sidebarComponent,\n\t\t * slot overrides, etc.) by name. Source precedence (ADR-036):\n\t\t *\n\t\t * 1. The v2 `registry` prop. When `requireKind` is set, only entries\n\t\t * with a matching `kind` field are considered; otherwise any\n\t\t * entry whose `component` is set wins. Each entry's `component`\n\t\t * field is the Vue component to render.\n\t\t * 2. Legacy `customComponents` map (`{ name: Component }`). Used\n\t\t * until consumers complete the registry migration.\n\t\t *\n\t\t * Returns `null` when neither source has the name.\n\t\t *\n\t\t * @param {string} name The component name referenced by the manifest.\n\t\t * @param {string|null} [requireKind] Optional kind discriminator —\n\t\t * `'page'` for page dispatch (page.component, page.sidebarComponent).\n\t\t * Omit for slot/actions/section/header lookups where any kind with\n\t\t * a `component` field is acceptable (widget, modal, form-field,\n\t\t * cell-renderer, custom kinds…).\n\t\t *\n\t\t * @return {object|null} The resolved Vue component, or null.\n\t\t */\n\t\tresolveCustomComponent(name, requireKind = null) {\n\t\t\tif (typeof name !== 'string' || name === '') {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\tconst registryEntry = this.effectiveRegistry[name]\n\t\t\tif (registryEntry !== undefined\n\t\t\t\t&& registryEntry !== null\n\t\t\t\t&& registryEntry.component\n\t\t\t\t&& (requireKind === null || registryEntry.kind === requireKind)) {\n\t\t\t\treturn registryEntry.component\n\t\t\t}\n\n\t\t\tconst legacy = this.effectiveCustomComponents[name]\n\t\t\tif (legacy) {\n\t\t\t\treturn legacy\n\t\t\t}\n\n\t\t\treturn null\n\t\t},\n\n\t\t/**\n\t\t * Resolve a named create-override handler for CnIndexPage's\n\t\t * `createOverride` prop (see `resolvedProps`). Unlike components, a\n\t\t * create-override is a plain async function, so it is looked up across\n\t\t * both registries by value shape:\n\t\t * 1. v2 registry (`cnRegistry`) — a `kind:'create-override'` entry\n\t\t * exposing the function as `.handler` (or `.fn`), or a directly\n\t\t * function-valued entry.\n\t\t * 2. legacy customComponents — a function-valued entry.\n\t\t *\n\t\t * @param {string} name The registered handler name from `config.createOverride`.\n\t\t * @return {?(formData: object, ctx: object) => Promise<object>} The async create handler, or null if unresolved.\n\t\t */\n\t\tresolveCreateOverride(name) {\n\t\t\treturn resolveCreateOverrideHandler(name, this.effectiveRegistry, this.effectiveCustomComponents)\n\t\t},\n\n\t\t/**\n\t\t * Load the object + schema backing a `type:\"detail\"` page and\n\t\t * publish them on the reactive `detailObjectContext` holder so\n\t\t * descendant CnWidgetGrid instances can feed `objectData` /\n\t\t * `schema` / `objectType` to the body/sidebar widgets.\n\t\t *\n\t\t * Steps (all defensive — a Pinia-less test harness, a missing\n\t\t * store method, or a failed fetch each degrade to leaving the\n\t\t * context null, so the page still mounts):\n\t\t * 1. Resolve `detailLoadContext` (null → clear + return).\n\t\t * 2. Register the `${register}-${schema}` object type (idempotent).\n\t\t * 3. Publish `{ objectData, schema, objectType, objectId,\n\t\t * register, store }` — with `objectData` / `schema` as\n\t\t * READ-THROUGH getters over the store cache (see below).\n\t\t * 4. Re-scope the live `or-object-{id}` subscription (see setup()).\n\t\t * 5. Fetch schema + object in parallel to warm the cache.\n\t\t *\n\t\t * Read-through holder (#222): `objectData` and `schema` are\n\t\t * accessors over `store.objects[slug][id]` / `store.schemas[slug]`\n\t\t * rather than stashed copies, so when the live-updates plugin's\n\t\t * event-driven refetch replaces the cache entry, every consumer\n\t\t * reading the holder during render (CnWidgetGrid's\n\t\t * `detailContextProps`, `resolveObjectTokenContext` callers)\n\t\t * re-renders with the fresh object — the holder never freezes a\n\t\t * snapshot. The external contract is unchanged: same keys, same\n\t\t * `{ value }` holder shape. Vue's observer preserves the accessors\n\t\t * and makes top-level writes to `objectData` / `schema` silent\n\t\t * no-ops (accessor without setter), so a consumer cannot clobber\n\t\t * the live view; all shipped widgets copy before mutating.\n\t\t *\n\t\t * The holder is published before the fetches so widgets that only\n\t\t * need objectId / register (e.g. file-manager) render without\n\t\t * waiting for the object body; the getters go non-null the moment\n\t\t * the fetches populate the cache — no re-publish needed.\n\t\t */\n\t\tasync loadDetailObject() {\n\t\t\tconst ctx = this.detailLoadContext\n\t\t\tif (!ctx) {\n\t\t\t\t// Not a detail page (or incomplete triple): clear the holder\n\t\t\t\t// and close the live-subscription gate — the composable in\n\t\t\t\t// setup() releases any held subscription when it sees the\n\t\t\t\t// scope go invalid (the renderer persists across routes).\n\t\t\t\tthis.liveSubEnabled = false\n\t\t\t\tthis.liveSubType = ''\n\t\t\t\tthis.liveSubId = ''\n\t\t\t\tthis.detailObjectContext.value = null\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tlet store = null\n\t\t\ttry {\n\t\t\t\tstore = useObjectStore()\n\t\t\t} catch {\n\t\t\t\t// Pinia not installed (unit tests). Publish the ids so\n\t\t\t\t// id-only widgets still work; skip the object fetch and\n\t\t\t\t// leave the live subscription disabled.\n\t\t\t\tthis.liveSubEnabled = false\n\t\t\t\tthis.detailObjectContext.value = {\n\t\t\t\t\tobjectData: null,\n\t\t\t\t\tschema: null,\n\t\t\t\t\tobjectType: ctx.slug,\n\t\t\t\t\tobjectId: ctx.objectId,\n\t\t\t\t\tregister: ctx.register,\n\t\t\t\t\tstore: null,\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Must precede the subscription re-scope below: subscribe() rejects\n\t\t\t// unregistered types. Once only — registerObjectType also blanks\n\t\t\t// `objects[slug]` and `schemas[slug]`, so re-running it empties the\n\t\t\t// content until the re-fetch lands.\n\t\t\ttry {\n\t\t\t\tif (typeof store.registerObjectType === 'function'\n\t\t\t\t\t&& !store.objectTypeRegistry?.[ctx.slug]) {\n\t\t\t\t\tstore.registerObjectType(ctx.slug, ctx.schema, ctx.register)\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.warn(`[CnPageRenderer] Failed to register object type \"${ctx.slug}\" for detail page \"${this.currentPage?.id}\":`, err)\n\t\t\t}\n\n\t\t\t// Publish the read-through holder (see method docblock). The ids\n\t\t\t// are available immediately; the getters resolve once the cache\n\t\t\t// fills.\n\t\t\tthis.detailObjectContext.value = {\n\t\t\t\tget objectData() {\n\t\t\t\t\treturn store.getObject?.(ctx.slug, ctx.objectId) ?? null\n\t\t\t\t},\n\n\t\t\t\t// Explicit no-op setters keep a consumer's stray write harmless.\n\t\t\t\t// Under Vue 2 the getter-only accessor was enough: `defineReactive`\n\t\t\t\t// replaced each property with its own get/set pair that delegated\n\t\t\t\t// reads to the original getter, so an assignment was swallowed.\n\t\t\t\t// Vue 3 leaves the accessor on the target and its `set` trap\n\t\t\t\t// forwards to `Reflect.set`, which returns false for a\n\t\t\t\t// setter-less accessor — and a `set` trap returning false throws\n\t\t\t\t// `TypeError: 'set' on proxy: trap returned falsish` in strict\n\t\t\t\t// mode. That would turn a benign mistake in a consumer app into a\n\t\t\t\t// crash, so the swallow is now written out rather than implied.\n\t\t\t\tset objectData(_ignored) {},\n\t\t\t\tget schema() {\n\t\t\t\t\treturn store.getSchema?.(ctx.slug) ?? null\n\t\t\t\t},\n\n\t\t\t\tset schema(_ignored) {},\n\t\t\t\tobjectType: ctx.slug,\n\t\t\t\tobjectId: ctx.objectId,\n\t\t\t\tregister: ctx.register,\n\t\t\t\tstore,\n\t\t\t}\n\n\t\t\t// Re-scope the live subscription (see setup()). Gated to the v2\n\t\t\t// widget-grid path — CnWidgetGrid (the holder's only render-time\n\t\t\t// consumer surface) mounts only for v2 manifests with widget\n\t\t\t// entries; the typed CnDetailPage dispatch path manages its own\n\t\t\t// subscription. `config.subscribe: false` opts out, mirroring\n\t\t\t// CnIndexPage / CnDetailPage (manifest-live-updates).\n\t\t\tconst subscribeOptOut = this.currentPage?.config?.subscribe === false\n\t\t\tconst rendersWidgetGrids = this.isV2Manifest && this.widgetsBySlot.size > 0\n\t\t\tthis.liveSubType = ctx.slug\n\t\t\tthis.liveSubId = ctx.objectId\n\t\t\tthis.liveSubEnabled = !subscribeOptOut && rendersWidgetGrids\n\n\t\t\t// Warm the cache: fetch schema + object, tolerating either\n\t\t\t// failing. No re-publish afterwards — the holder's getters read\n\t\t\t// the cache these fetches populate, so there is nothing to\n\t\t\t// clobber if the user navigated away mid-fetch either.\n\t\t\tconst tasks = []\n\t\t\tif (typeof store.fetchSchema === 'function') {\n\t\t\t\ttasks.push(store.fetchSchema(ctx.slug).catch(() => null))\n\t\t\t} else {\n\t\t\t\ttasks.push(Promise.resolve(null))\n\t\t\t}\n\t\t\tif (typeof store.fetchObject === 'function') {\n\t\t\t\ttasks.push(store.fetchObject(ctx.slug, ctx.objectId).catch(() => null))\n\t\t\t} else {\n\t\t\t\ttasks.push(Promise.resolve(null))\n\t\t\t}\n\t\t\tawait Promise.all(tasks)\n\t\t},\n\n\t\t/**\n\t\t * Auto-register object types declared on the current\n\t\t * `type:\"custom\"` page's `config`. No-op for any other page\n\t\t * type (index/detail self-register inside the page component\n\t\t * itself; dashboard/form/map have no such concept).\n\t\t *\n\t\t * Recognised config shapes:\n\t\t *\n\t\t * 1. Single type — `config.register` + `config.schema` are\n\t\t * both non-empty strings. Registered under slug\n\t\t * `${register}-${schema}` to match the convention used by\n\t\t * CnIndexPage.setup (self-fetch mode) and CnLogsPage.\n\t\t *\n\t\t * 2. Multi-type — `config.types: [{ name, register, schema }]`.\n\t\t * Each entry is registered under its own `name` slug so a\n\t\t * single custom page (e.g. a Kanban board with multiple\n\t\t * object kinds) can hydrate several object types in one\n\t\t * manifest declaration.\n\t\t *\n\t\t * Both shapes may co-exist; the single-type pair is registered\n\t\t * first, then each `types[]` entry. Entries with missing /\n\t\t * non-string `name` / `register` / `schema` are skipped with a\n\t\t * single warning. All work is wrapped in try/catch so a broken\n\t\t * Pinia setup or a thrown `registerObjectType` never blocks\n\t\t * the page from mounting.\n\t\t */\n\t\tautoRegisterCustomTypes() {\n\t\t\tconst page = this.currentPage\n\t\t\tif (!page || page.type !== 'custom') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst config = page.config\n\t\t\tif (!config || typeof config !== 'object') {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tlet store\n\t\t\ttry {\n\t\t\t\tstore = useObjectStore()\n\t\t\t} catch {\n\t\t\t\t// Pinia not installed (common in unit tests). Silently\n\t\t\t\t// skip — the custom component can still register itself\n\t\t\t\t// at mount time if/when it has its own store.\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (!store || typeof store.registerObjectType !== 'function') {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Single-type shape: config.register + config.schema.\n\t\t\tconst reg = config.register\n\t\t\tconst schema = config.schema\n\t\t\tconst hasSingle = typeof reg === 'string' && reg.length > 0\n\t\t\t\t&& typeof schema === 'string' && schema.length > 0\n\t\t\tif (hasSingle) {\n\t\t\t\tconst slug = `${reg}-${schema}`\n\t\t\t\ttry {\n\t\t\t\t\tstore.registerObjectType(slug, schema, reg)\n\t\t\t\t} catch (err) {\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t`[CnPageRenderer] Failed to auto-register object type \"${slug}\" for custom page id \"${page.id}\":`,\n\t\t\t\t\t\terr,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t} else if (\n\t\t\t\t(typeof reg === 'string' && reg.length > 0)\n\t\t\t\t|| (typeof schema === 'string' && schema.length > 0)\n\t\t\t) {\n\t\t\t\t// One half of the pair is set but not the other —\n\t\t\t\t// likely a manifest typo. Warn but keep going so\n\t\t\t\t// types[] (below) still gets a chance.\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.warn(`[CnPageRenderer] Custom page id \"${page.id}\" declares only one of config.register / config.schema; auto-registration skipped. Set both (or use config.types[]) to opt in.`)\n\t\t\t}\n\n\t\t\t// Multi-type shape: config.types: [{ name, register, schema }, ...].\n\t\t\tconst types = config.types\n\t\t\tif (Array.isArray(types)) {\n\t\t\t\tfor (const entry of types) {\n\t\t\t\t\tif (!entry || typeof entry !== 'object') {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tconst name = entry.name\n\t\t\t\t\tconst r = entry.register\n\t\t\t\t\tconst s = entry.schema\n\t\t\t\t\tif (\n\t\t\t\t\t\ttypeof name !== 'string' || name.length === 0\n\t\t\t\t\t\t|| typeof r !== 'string' || r.length === 0\n\t\t\t\t\t\t|| typeof s !== 'string' || s.length === 0\n\t\t\t\t\t) {\n\t\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\t\tconsole.warn(`[CnPageRenderer] Skipping invalid entry in config.types on custom page id \"${page.id}\" — each entry needs non-empty name, register, and schema.`)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\ttry {\n\t\t\t\t\t\tstore.registerObjectType(name, s, r)\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t`[CnPageRenderer] Failed to auto-register object type \"${name}\" for custom page id \"${page.id}\":`,\n\t\t\t\t\t\t\terr,\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Resolve a registry component name. Logs a single console.warn\n\t\t * naming the slot if the name is not in the registry.\n\t\t *\n\t\t * @param {string} registryName Name of the component to look up\n\t\t * in `effectiveCustomComponents`.\n\t\t * @param {string} slotName Slot the component would have filled\n\t\t * (used only for the warning message).\n\t\t * @return {object|null}\n\t\t */\n\t\tresolveRegistryName(registryName, slotName) {\n\t\t\tconst resolved = this.resolveCustomComponent(registryName)\n\t\t\tif (!resolved) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.warn(`[CnPageRenderer] Slot-override component \"${registryName}\" referenced by page id \"${this.currentPage.id}\" (slot \"${slotName}\") not found in registry.`)\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn resolved\n\t\t},\n\t},\n}\n</script>\n\n<style>\n.cn-page-renderer {\n\tdisplay: contents;\n}\n\n/*\n * Toggle-clearance padding lives PER-COMPONENT on each page's HEADER\n * element (CnPageHeader, CnDashboardPage, CnDetailPage,\n * CnFeaturesAndRoadmapView, etc.). Earlier attempts at an abstract\n * fix here — first via `.cn-page-renderer > *` (PR #355, lost to\n * scoped-style specificity + shorthand overrides), then via a\n * `.cn-page-renderer__viewport` wrapper (PR #359, narrowed body\n * content unintentionally) — were rejected in favour of per-header\n * rules so body content keeps its full width.\n *\n * Custom pages MUST add `padding-inline-start: 56px` to their HEADER\n * element to clear the navigation toggle. See `docs/getting-started.md`.\n */\n\n/*\n * Hook class applied when the current page's manifest entry has\n * `sidebar.show: false`. The library does not ship visual rules\n * here — consumer apps with style-driven sidebar layouts (e.g. CSS\n * grid where the host shell sibling sidebar is a grid track) can\n * target this class to collapse / hide the sibling element.\n *\n * The programmatic counterpart is the `cnPageSidebarVisible`\n * inject — `CnAppRoot` reads it to gate `<slot name=\"sidebar\" />`.\n */\n.cn-page-renderer--no-sidebar {\n\t/* intentionally empty — consumer-styled */\n}\n\n/* Builder empty-state: keep the edit button top-right (mirrors a page\n header's actions area) above a centred empty prompt. */\n.cn-page-renderer__empty {\n\tpadding-inline-start: 56px;\n}\n\n.cn-page-renderer__empty-actions {\n\tdisplay: flex;\n\tjustify-content: flex-end;\n\tpadding: 8px 8px 0;\n}\n</style>\n"],"names":["CnDependencyMissing","CnWidgetGrid","CnPageConfigModal","CnBuildiqEditButton","CnMassExportDialog","t"],"mappings":"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"}