@conduction/nextcloud-vue 2.56.0-beta.3 → 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 (314) 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/CnAppRoot/CnAppRoot.vue2.js +21 -1
  12. package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js.map +1 -1
  13. package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js +1 -1
  14. package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js.map +1 -1
  15. package/dist/esm/components/CnBoardView/CnBoardView.vue2.js +12 -5
  16. package/dist/esm/components/CnBoardView/CnBoardView.vue2.js.map +1 -1
  17. package/dist/esm/components/CnBoardView/CnBoardView.vue3.js +2 -1
  18. package/dist/esm/components/CnBoardView/CnBoardView.vue3.js.map +1 -1
  19. package/dist/esm/components/CnCardGrid/CnCardGrid.vue2.js +9 -1
  20. package/dist/esm/components/CnCardGrid/CnCardGrid.vue2.js.map +1 -1
  21. package/dist/esm/components/CnCardGrid/CnCardGrid.vue3.js.map +1 -1
  22. package/dist/esm/components/CnContextMenu/CnContextMenu.vue2.js +6 -1
  23. package/dist/esm/components/CnContextMenu/CnContextMenu.vue2.js.map +1 -1
  24. package/dist/esm/components/CnContextMenu/CnContextMenu.vue3.js.map +1 -1
  25. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +116 -15
  26. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
  27. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +27 -14
  28. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
  29. package/dist/esm/components/CnDateAxisView/CnDateAxisView.vue2.js +13 -6
  30. package/dist/esm/components/CnDateAxisView/CnDateAxisView.vue2.js.map +1 -1
  31. package/dist/esm/components/CnDateAxisView/CnDateAxisView.vue3.js +2 -0
  32. package/dist/esm/components/CnDateAxisView/CnDateAxisView.vue3.js.map +1 -1
  33. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +29 -1
  34. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
  35. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
  36. package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue2.js.map +1 -1
  37. package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue3.js +1 -2
  38. package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue3.js.map +1 -1
  39. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js +3 -1
  40. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js.map +1 -1
  41. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js +17 -17
  42. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js.map +1 -1
  43. package/dist/esm/components/CnFilesWidget/CnFilesWidget.vue2.js +4 -21
  44. package/dist/esm/components/CnFilesWidget/CnFilesWidget.vue2.js.map +1 -1
  45. package/dist/esm/components/CnFilesWidget/CnFilesWidget.vue3.js.map +1 -1
  46. package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue2.js +0 -13
  47. package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue2.js.map +1 -1
  48. package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue3.js +8 -8
  49. package/dist/esm/components/CnFlowRunsWidget/CnFlowRunsWidget.vue3.js.map +1 -1
  50. package/dist/esm/components/CnFlowsPage/CnFlowsPage.vue2.js.map +1 -1
  51. package/dist/esm/components/CnFlowsPage/CnFlowsPage.vue3.js +3 -2
  52. package/dist/esm/components/CnFlowsPage/CnFlowsPage.vue3.js.map +1 -1
  53. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +67 -13
  54. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  55. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +15 -8
  56. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  57. package/dist/esm/components/CnIndexPage/manifestActionDispatch.js +31 -11
  58. package/dist/esm/components/CnIndexPage/manifestActionDispatch.js.map +1 -1
  59. package/dist/esm/components/CnIntegrationWidget/CnIntegrationWidgetEmpty.vue2.js.map +1 -1
  60. package/dist/esm/components/CnIntegrationWidget/CnIntegrationWidgetEmpty.vue3.js +1 -2
  61. package/dist/esm/components/CnIntegrationWidget/CnIntegrationWidgetEmpty.vue3.js.map +1 -1
  62. package/dist/esm/components/CnInteractionFormWidget/CnInteractionFormWidget.vue2.js.map +1 -1
  63. package/dist/esm/components/CnInteractionFormWidget/CnInteractionFormWidget.vue3.js +0 -1
  64. package/dist/esm/components/CnInteractionFormWidget/CnInteractionFormWidget.vue3.js.map +1 -1
  65. package/dist/esm/components/CnLinkButtonWidget/CnLinkButtonWidget.vue2.js +2 -17
  66. package/dist/esm/components/CnLinkButtonWidget/CnLinkButtonWidget.vue2.js.map +1 -1
  67. package/dist/esm/components/CnLinkButtonWidget/CnLinkButtonWidget.vue3.js.map +1 -1
  68. package/dist/esm/components/CnLogsPage/CnLogsPage.vue2.js +35 -11
  69. package/dist/esm/components/CnLogsPage/CnLogsPage.vue2.js.map +1 -1
  70. package/dist/esm/components/CnLogsPage/CnLogsPage.vue3.js +3 -2
  71. package/dist/esm/components/CnLogsPage/CnLogsPage.vue3.js.map +1 -1
  72. package/dist/esm/components/CnObjectCard/CnObjectCard.vue2.js +23 -5
  73. package/dist/esm/components/CnObjectCard/CnObjectCard.vue2.js.map +1 -1
  74. package/dist/esm/components/CnObjectCard/CnObjectCard.vue3.js +1 -1
  75. package/dist/esm/components/CnObjectCard/CnObjectCard.vue3.js.map +1 -1
  76. package/dist/esm/components/CnObjectList/CnObjectList.vue2.js +19 -3
  77. package/dist/esm/components/CnObjectList/CnObjectList.vue2.js.map +1 -1
  78. package/dist/esm/components/CnObjectList/CnObjectList.vue3.js.map +1 -1
  79. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js +45 -15
  80. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js.map +1 -1
  81. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js +4 -2
  82. package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js.map +1 -1
  83. package/dist/esm/components/CnObjectRow/CnObjectRow.vue2.js +24 -6
  84. package/dist/esm/components/CnObjectRow/CnObjectRow.vue2.js.map +1 -1
  85. package/dist/esm/components/CnObjectRow/CnObjectRow.vue3.js +1 -1
  86. package/dist/esm/components/CnObjectRow/CnObjectRow.vue3.js.map +1 -1
  87. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js.map +1 -1
  88. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js +0 -1
  89. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js.map +1 -1
  90. package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue2.js.map +1 -1
  91. package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue3.js +4 -2
  92. package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue3.js.map +1 -1
  93. package/dist/esm/components/CnRowActions/CnRowActions.vue2.js +7 -2
  94. package/dist/esm/components/CnRowActions/CnRowActions.vue2.js.map +1 -1
  95. package/dist/esm/components/CnRowActions/CnRowActions.vue3.js.map +1 -1
  96. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js +49 -5
  97. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js.map +1 -1
  98. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js +1 -1
  99. package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js.map +1 -1
  100. package/dist/esm/components/CnSpendAnalyticsWidget/CnSpendAnalyticsWidget.vue2.js +5 -3
  101. package/dist/esm/components/CnSpendAnalyticsWidget/CnSpendAnalyticsWidget.vue2.js.map +1 -1
  102. package/dist/esm/components/CnSpendAnalyticsWidget/CnSpendAnalyticsWidget.vue3.js.map +1 -1
  103. package/dist/esm/components/CnTabs/CnTabs.vue2.js.map +1 -1
  104. package/dist/esm/components/CnTabs/CnTabs.vue3.js.map +1 -1
  105. package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue2.js +3 -1
  106. package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue2.js.map +1 -1
  107. package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue3.js +1 -0
  108. package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue3.js.map +1 -1
  109. package/dist/esm/integrations/builtin/analytics/CnAnalyticsCard.vue2.js +3 -1
  110. package/dist/esm/integrations/builtin/analytics/CnAnalyticsCard.vue2.js.map +1 -1
  111. package/dist/esm/integrations/builtin/analytics/CnAnalyticsCard.vue3.js.map +1 -1
  112. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue2.js +3 -1
  113. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue2.js.map +1 -1
  114. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue3.js +2 -4
  115. package/dist/esm/integrations/builtin/analytics/CnAnalyticsTab.vue3.js.map +1 -1
  116. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksCard.vue2.js +6 -0
  117. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksCard.vue2.js.map +1 -1
  118. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksCard.vue3.js +68 -53
  119. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksCard.vue3.js.map +1 -1
  120. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksTab.vue2.js +17 -0
  121. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksTab.vue2.js.map +1 -1
  122. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksTab.vue3.js +21 -19
  123. package/dist/esm/integrations/builtin/bookmarks/CnBookmarksTab.vue3.js.map +1 -1
  124. package/dist/esm/integrations/builtin/collectives/CnCollectivesCard.vue2.js +3 -1
  125. package/dist/esm/integrations/builtin/collectives/CnCollectivesCard.vue2.js.map +1 -1
  126. package/dist/esm/integrations/builtin/collectives/CnCollectivesCard.vue3.js.map +1 -1
  127. package/dist/esm/integrations/builtin/collectives/CnCollectivesTab.vue2.js +3 -1
  128. package/dist/esm/integrations/builtin/collectives/CnCollectivesTab.vue2.js.map +1 -1
  129. package/dist/esm/integrations/builtin/collectives/CnCollectivesTab.vue3.js +2 -4
  130. package/dist/esm/integrations/builtin/collectives/CnCollectivesTab.vue3.js.map +1 -1
  131. package/dist/esm/integrations/builtin/cospend/CnCospendCard.vue2.js +2 -1
  132. package/dist/esm/integrations/builtin/cospend/CnCospendCard.vue2.js.map +1 -1
  133. package/dist/esm/integrations/builtin/cospend/CnCospendCard.vue3.js.map +1 -1
  134. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue2.js +2 -1
  135. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue2.js.map +1 -1
  136. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue3.js +1 -2
  137. package/dist/esm/integrations/builtin/cospend/CnCospendTab.vue3.js.map +1 -1
  138. package/dist/esm/integrations/builtin/deck/CnDeckCard.vue2.js +2 -1
  139. package/dist/esm/integrations/builtin/deck/CnDeckCard.vue2.js.map +1 -1
  140. package/dist/esm/integrations/builtin/deck/CnDeckCard.vue3.js.map +1 -1
  141. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue2.js +2 -1
  142. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue2.js.map +1 -1
  143. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue3.js +1 -2
  144. package/dist/esm/integrations/builtin/deck/CnDeckTab.vue3.js.map +1 -1
  145. package/dist/esm/integrations/builtin/email/CnEmailCard.vue2.js.map +1 -1
  146. package/dist/esm/integrations/builtin/email/CnEmailCard.vue3.js.map +1 -1
  147. package/dist/esm/integrations/builtin/email/CnEmailTab.vue2.js.map +1 -1
  148. package/dist/esm/integrations/builtin/email/CnEmailTab.vue3.js +1 -2
  149. package/dist/esm/integrations/builtin/email/CnEmailTab.vue3.js.map +1 -1
  150. package/dist/esm/integrations/builtin/flow/CnFlowCard.vue2.js +2 -1
  151. package/dist/esm/integrations/builtin/flow/CnFlowCard.vue2.js.map +1 -1
  152. package/dist/esm/integrations/builtin/flow/CnFlowCard.vue3.js.map +1 -1
  153. package/dist/esm/integrations/builtin/flow/CnFlowTab.vue2.js +2 -1
  154. package/dist/esm/integrations/builtin/flow/CnFlowTab.vue2.js.map +1 -1
  155. package/dist/esm/integrations/builtin/flow/CnFlowTab.vue3.js +1 -2
  156. package/dist/esm/integrations/builtin/flow/CnFlowTab.vue3.js.map +1 -1
  157. package/dist/esm/integrations/builtin/forms/CnFormsCard.vue2.js +3 -1
  158. package/dist/esm/integrations/builtin/forms/CnFormsCard.vue2.js.map +1 -1
  159. package/dist/esm/integrations/builtin/forms/CnFormsCard.vue3.js.map +1 -1
  160. package/dist/esm/integrations/builtin/forms/CnFormsTab.vue2.js +3 -1
  161. package/dist/esm/integrations/builtin/forms/CnFormsTab.vue2.js.map +1 -1
  162. package/dist/esm/integrations/builtin/forms/CnFormsTab.vue3.js +2 -4
  163. package/dist/esm/integrations/builtin/forms/CnFormsTab.vue3.js.map +1 -1
  164. package/dist/esm/integrations/builtin/maps/CnMapsCard.vue2.js +3 -1
  165. package/dist/esm/integrations/builtin/maps/CnMapsCard.vue2.js.map +1 -1
  166. package/dist/esm/integrations/builtin/maps/CnMapsCard.vue3.js.map +1 -1
  167. package/dist/esm/integrations/builtin/maps/CnMapsTab.vue2.js +3 -1
  168. package/dist/esm/integrations/builtin/maps/CnMapsTab.vue2.js.map +1 -1
  169. package/dist/esm/integrations/builtin/maps/CnMapsTab.vue3.js +2 -4
  170. package/dist/esm/integrations/builtin/maps/CnMapsTab.vue3.js.map +1 -1
  171. package/dist/esm/integrations/builtin/openproject/CnOpenprojectCard.vue2.js +3 -1
  172. package/dist/esm/integrations/builtin/openproject/CnOpenprojectCard.vue2.js.map +1 -1
  173. package/dist/esm/integrations/builtin/openproject/CnOpenprojectCard.vue3.js.map +1 -1
  174. package/dist/esm/integrations/builtin/openproject/CnOpenprojectTab.vue2.js +3 -1
  175. package/dist/esm/integrations/builtin/openproject/CnOpenprojectTab.vue2.js.map +1 -1
  176. package/dist/esm/integrations/builtin/openproject/CnOpenprojectTab.vue3.js +2 -4
  177. package/dist/esm/integrations/builtin/openproject/CnOpenprojectTab.vue3.js.map +1 -1
  178. package/dist/esm/integrations/builtin/photos/CnPhotosCard.vue2.js +2 -1
  179. package/dist/esm/integrations/builtin/photos/CnPhotosCard.vue2.js.map +1 -1
  180. package/dist/esm/integrations/builtin/photos/CnPhotosCard.vue3.js.map +1 -1
  181. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue2.js +2 -1
  182. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue2.js.map +1 -1
  183. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue3.js +1 -2
  184. package/dist/esm/integrations/builtin/photos/CnPhotosTab.vue3.js.map +1 -1
  185. package/dist/esm/integrations/builtin/polls/CnPollsCard.vue2.js +2 -1
  186. package/dist/esm/integrations/builtin/polls/CnPollsCard.vue2.js.map +1 -1
  187. package/dist/esm/integrations/builtin/polls/CnPollsCard.vue3.js.map +1 -1
  188. package/dist/esm/integrations/builtin/polls/CnPollsTab.vue2.js +2 -1
  189. package/dist/esm/integrations/builtin/polls/CnPollsTab.vue2.js.map +1 -1
  190. package/dist/esm/integrations/builtin/polls/CnPollsTab.vue3.js +1 -2
  191. package/dist/esm/integrations/builtin/polls/CnPollsTab.vue3.js.map +1 -1
  192. package/dist/esm/integrations/builtin/shares/CnSharesTab.vue2.js.map +1 -1
  193. package/dist/esm/integrations/builtin/shares/CnSharesTab.vue3.js +3 -6
  194. package/dist/esm/integrations/builtin/shares/CnSharesTab.vue3.js.map +1 -1
  195. package/dist/esm/integrations/builtin/talk/CnTalkCard.vue2.js +3 -1
  196. package/dist/esm/integrations/builtin/talk/CnTalkCard.vue2.js.map +1 -1
  197. package/dist/esm/integrations/builtin/talk/CnTalkCard.vue3.js.map +1 -1
  198. package/dist/esm/integrations/builtin/talk/CnTalkTab.vue2.js +3 -1
  199. package/dist/esm/integrations/builtin/talk/CnTalkTab.vue2.js.map +1 -1
  200. package/dist/esm/integrations/builtin/talk/CnTalkTab.vue3.js +2 -4
  201. package/dist/esm/integrations/builtin/talk/CnTalkTab.vue3.js.map +1 -1
  202. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerCard.vue2.js +2 -1
  203. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerCard.vue2.js.map +1 -1
  204. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerCard.vue3.js.map +1 -1
  205. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerTab.vue2.js +2 -1
  206. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerTab.vue2.js.map +1 -1
  207. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerTab.vue3.js +1 -2
  208. package/dist/esm/integrations/builtin/time-tracker/CnTimeTrackerTab.vue3.js.map +1 -1
  209. package/dist/esm/integrations/builtin/xwiki/CnXwikiCard.vue2.js +4 -1
  210. package/dist/esm/integrations/builtin/xwiki/CnXwikiCard.vue2.js.map +1 -1
  211. package/dist/esm/integrations/builtin/xwiki/CnXwikiCard.vue3.js.map +1 -1
  212. package/dist/esm/integrations/builtin/xwiki/CnXwikiTab.vue2.js +6 -3
  213. package/dist/esm/integrations/builtin/xwiki/CnXwikiTab.vue2.js.map +1 -1
  214. package/dist/esm/integrations/builtin/xwiki/CnXwikiTab.vue3.js +2 -4
  215. package/dist/esm/integrations/builtin/xwiki/CnXwikiTab.vue3.js.map +1 -1
  216. package/dist/esm/l10n/en.json.js +2 -0
  217. package/dist/esm/l10n/en.json.js.map +1 -1
  218. package/dist/esm/l10n/nl.json.js +2 -0
  219. package/dist/esm/l10n/nl.json.js.map +1 -1
  220. package/dist/esm/nextcloud-vue.css +78 -7
  221. package/dist/esm/utils/actionLink.js +5 -0
  222. package/dist/esm/utils/actionLink.js.map +1 -1
  223. package/dist/esm/utils/actionsDispatcher.js +16 -1
  224. package/dist/esm/utils/actionsDispatcher.js.map +1 -1
  225. package/dist/esm/utils/linkNavigation.js +6 -3
  226. package/dist/esm/utils/linkNavigation.js.map +1 -1
  227. package/dist/esm/utils/rowAuxClick.js +30 -5
  228. package/dist/esm/utils/rowAuxClick.js.map +1 -1
  229. package/dist/esm/utils/safeHref.js +18 -3
  230. package/dist/esm/utils/safeHref.js.map +1 -1
  231. package/dist/esm/utils/validateManifestV2.compiled.js +2 -2
  232. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  233. package/dist/nextcloud-vue.cjs.js +885 -393
  234. package/dist/nextcloud-vue.cjs.js.map +2 -2
  235. package/dist/nextcloud-vue.css +78 -7
  236. package/l10n/en.json +2 -0
  237. package/l10n/nl.json +2 -0
  238. package/package.json +1 -1
  239. package/src/components/CnActionsBar/CnActionsBar.vue +14 -5
  240. package/src/components/CnActionsMenu/CnActionsMenu.vue +0 -3
  241. package/src/components/CnAdminSettingsShell/CnAdminSettingsShell.vue +1 -2
  242. package/src/components/CnAppRoot/CnAppRoot.vue +31 -2
  243. package/src/components/CnBoardView/CnBoardView.vue +13 -5
  244. package/src/components/CnCardGrid/CnCardGrid.vue +9 -1
  245. package/src/components/CnContextMenu/CnContextMenu.vue +6 -1
  246. package/src/components/CnDataTable/CnDataTable.md +1 -1
  247. package/src/components/CnDataTable/CnDataTable.vue +131 -17
  248. package/src/components/CnDateAxisView/CnDateAxisView.vue +15 -6
  249. package/src/components/CnDetailPage/CnDetailPage.md +1 -1
  250. package/src/components/CnDetailPage/CnDetailPage.vue +29 -1
  251. package/src/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue +1 -2
  252. package/src/components/CnFilesBrowser/CnFilesBrowser.vue +5 -3
  253. package/src/components/CnFilesWidget/CnFilesWidget.vue +4 -21
  254. package/src/components/CnFlowRunsWidget/CnFlowRunsWidget.vue +8 -21
  255. package/src/components/CnFlowsPage/CnFlowsPage.vue +2 -1
  256. package/src/components/CnIndexPage/CnIndexPage.vue +75 -14
  257. package/src/components/CnIndexPage/manifestActionDispatch.js +31 -11
  258. package/src/components/CnIntegrationWidget/CnIntegrationWidgetEmpty.vue +1 -2
  259. package/src/components/CnInteractionFormWidget/CnInteractionFormWidget.vue +0 -1
  260. package/src/components/CnLinkButtonWidget/CnLinkButtonWidget.vue +2 -17
  261. package/src/components/CnLogsPage/CnLogsPage.vue +37 -12
  262. package/src/components/CnObjectCard/CnObjectCard.vue +24 -6
  263. package/src/components/CnObjectList/CnObjectList.vue +19 -3
  264. package/src/components/CnObjectListWidget/CnObjectListWidget.vue +47 -15
  265. package/src/components/CnObjectRow/CnObjectRow.vue +25 -7
  266. package/src/components/CnObjectSidebar/CnFilesTab.vue +0 -1
  267. package/src/components/CnPageRenderer/CnPageRenderer.vue +2 -0
  268. package/src/components/CnRowActions/CnRowActions.vue +7 -2
  269. package/src/components/CnSetupWizard/CnSetupWizard.vue +57 -6
  270. package/src/components/CnSpendAnalyticsWidget/CnSpendAnalyticsWidget.vue +5 -3
  271. package/src/components/CnTabs/CnTabs.vue +7 -3
  272. package/src/components/CnTasksWidget/CnTasksWidget.vue +4 -1
  273. package/src/css/table.css +26 -0
  274. package/src/integrations/builtin/analytics/CnAnalyticsCard.vue +3 -2
  275. package/src/integrations/builtin/analytics/CnAnalyticsTab.vue +5 -6
  276. package/src/integrations/builtin/bookmarks/CnBookmarksCard.vue +12 -1
  277. package/src/integrations/builtin/bookmarks/CnBookmarksTab.vue +23 -6
  278. package/src/integrations/builtin/bookmarks/__tests__/CnBookmarksTab.spec.js +7 -2
  279. package/src/integrations/builtin/collectives/CnCollectivesCard.vue +3 -2
  280. package/src/integrations/builtin/collectives/CnCollectivesTab.vue +5 -6
  281. package/src/integrations/builtin/cospend/CnCospendCard.vue +2 -2
  282. package/src/integrations/builtin/cospend/CnCospendTab.vue +3 -4
  283. package/src/integrations/builtin/deck/CnDeckCard.vue +2 -2
  284. package/src/integrations/builtin/deck/CnDeckTab.vue +3 -4
  285. package/src/integrations/builtin/email/CnEmailCard.vue +6 -2
  286. package/src/integrations/builtin/email/CnEmailTab.vue +7 -4
  287. package/src/integrations/builtin/flow/CnFlowCard.vue +2 -2
  288. package/src/integrations/builtin/flow/CnFlowTab.vue +3 -4
  289. package/src/integrations/builtin/forms/CnFormsCard.vue +3 -2
  290. package/src/integrations/builtin/forms/CnFormsTab.vue +5 -6
  291. package/src/integrations/builtin/maps/CnMapsCard.vue +3 -2
  292. package/src/integrations/builtin/maps/CnMapsTab.vue +5 -6
  293. package/src/integrations/builtin/maps/__tests__/CnMapsTab.spec.js +9 -0
  294. package/src/integrations/builtin/openproject/CnOpenprojectCard.vue +3 -2
  295. package/src/integrations/builtin/openproject/CnOpenprojectTab.vue +5 -6
  296. package/src/integrations/builtin/photos/CnPhotosCard.vue +2 -2
  297. package/src/integrations/builtin/photos/CnPhotosTab.vue +3 -4
  298. package/src/integrations/builtin/polls/CnPollsCard.vue +2 -2
  299. package/src/integrations/builtin/polls/CnPollsTab.vue +3 -4
  300. package/src/integrations/builtin/shares/CnSharesTab.vue +3 -6
  301. package/src/integrations/builtin/talk/CnTalkCard.vue +3 -2
  302. package/src/integrations/builtin/talk/CnTalkTab.vue +5 -6
  303. package/src/integrations/builtin/time-tracker/CnTimeTrackerCard.vue +2 -2
  304. package/src/integrations/builtin/time-tracker/CnTimeTrackerTab.vue +3 -4
  305. package/src/integrations/builtin/xwiki/CnXwikiCard.vue +4 -2
  306. package/src/integrations/builtin/xwiki/CnXwikiTab.vue +7 -7
  307. package/src/integrations/builtin/xwiki/__tests__/CnXwikiTab.spec.js +9 -0
  308. package/src/schemas/app-manifest-v2.schema.json +2 -1
  309. package/src/utils/actionLink.js +5 -0
  310. package/src/utils/actionsDispatcher.js +15 -0
  311. package/src/utils/linkNavigation.js +6 -3
  312. package/src/utils/rowAuxClick.js +29 -4
  313. package/src/utils/safeHref.js +18 -3
  314. package/src/utils/validateManifestV2.compiled.js +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"CnDetailPage.vue2.js","sources":["../../../../src/components/CnDetailPage/CnDetailPage.vue"],"sourcesContent":["<!--\n CnDetailPage — Generic detail/overview page.\n\n The detail page equivalent of CnDashboardPage. Assembles a complete entity detail\n view from card-based sections, matching the dashboard visual style (rounded cards\n with headers). Uses a fixed declarative layout (no drag-and-drop).\n\n Features:\n - Header with back button, title, subtitle, and action buttons\n - Card-based content area (via default slot with CnDetailCard components)\n - Optional 12-column CSS grid layout mode (via layout + widgets props)\n - Optional right sidebar (CnObjectSidebar) for files, notes, tags, tasks, audit trail\n - Loading and error states\n - Edit mode toggle\n\n A simpler alternative to CnIndexPage for detail, stats, and overview pages.\n No multi-object table, no CRUD dialogs — just a clean layout with:\n - Header (title, description, icon, action buttons)\n - Loading / error / empty states\n - Statistics table section\n - Content sections via slots\n-->\n<template>\n\t<div class=\"cn-detail-page\" data-testid=\"cn-detail-page\" :style=\"{ maxWidth: maxWidth }\">\n\t\t<!-- Skip link to the page's primary action. Off screen until it takes\n\t\t focus, so it costs a sighted mouse user nothing and saves a\n\t\t keyboard user every widget on the page. Targets the action the\n\t\t page DECLARES rather than a guessed first button: a skip link\n\t\t that lands somewhere arbitrary is worse than none, because it is\n\t\t the one link a keyboard user is told to trust. -->\n\t\t<a\n\t\t\tv-if=\"primaryActionLabel && !objectNotFound\"\n\t\t\t:href=\"`#${primaryActionAnchorId}`\"\n\t\t\tclass=\"cn-detail-page__skip-link\"\n\t\t\tdata-testid=\"cn-detail-page-skip-link\"\n\t\t\t@click=\"onSkipToPrimaryAction\">\n\t\t\t{{ skipLinkLabel }}\n\t\t</a>\n\n\t\t<!-- Header -->\n\t\t<div v-if=\"!objectNotFound\" class=\"cn-detail-page__header\" data-testid=\"cn-detail-page-header\">\n\t\t\t<!-- Header (left block) — overridable via #header slot. Default\n\t\t\t renders the icon + title + description. The right-hand\n\t\t\t #actions slot remains separate so headerComponent and\n\t\t\t actionsComponent can be replaced independently. -->\n\t\t\t<!--\n\t\t\t\t@slot header\n\t\t\t\t@description Replace the entire left header block (icon + title + description).\n\t\t\t\t@binding {string} title Page title.\n\t\t\t\t@binding {string} description Subtitle / description.\n\t\t\t\t@binding {string} icon MDI icon name resolved by CnIcon.\n\t\t\t\t@binding {number} icon-size Icon size in pixels.\n\t\t\t-->\n\t\t\t<slot\n\t\t\t\tname=\"header\"\n\t\t\t\t:title=\"title\"\n\t\t\t\t:description=\"description\"\n\t\t\t\t:icon=\"icon\"\n\t\t\t\t:iconSize=\"iconSize\">\n\t\t\t\t<div class=\"cn-detail-page__header-left\">\n\t\t\t\t\t<!--\n\t\t\t\t\t\t@slot icon\n\t\t\t\t\t\t@description Replace only the header icon (keeping the lib's title +\n\t\t\t\t\t\tdescription rendering). Default content: a `<CnIcon>` resolved from\n\t\t\t\t\t\tthe `icon` prop.\n\t\t\t\t\t-->\n\t\t\t\t\t<slot name=\"icon\">\n\t\t\t\t\t\t<CnIcon\n\t\t\t\t\t\t\tv-if=\"icon\"\n\t\t\t\t\t\t\t:name=\"icon\"\n\t\t\t\t\t\t\t:size=\"iconSize\"\n\t\t\t\t\t\t\tclass=\"cn-detail-page__icon\" />\n\t\t\t\t\t</slot>\n\t\t\t\t\t<div class=\"cn-detail-page__header-text\">\n\t\t\t\t\t\t<!-- Type name as a small eyebrow above the record name, so\n\t\t\t\t\t\t the header reads \"the record\" not \"the kind of record\"\n\t\t\t\t\t\t (ADR-062). Only shown once the object resolves to a\n\t\t\t\t\t\t display name that differs from the type label. -->\n\t\t\t\t\t\t<p\n\t\t\t\t\t\t\tv-if=\"typeEyebrow\"\n\t\t\t\t\t\t\tclass=\"cn-detail-page__type-eyebrow\"\n\t\t\t\t\t\t\tdata-testid=\"cn-detail-page-type-eyebrow\">\n\t\t\t\t\t\t\t{{ typeEyebrow }}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<h2 v-if=\"displayTitle\" class=\"cn-detail-page__title\">\n\t\t\t\t\t\t\t{{ displayTitle }}\n\t\t\t\t\t\t</h2>\n\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t@slot translation-badge\n\t\t\t\t\t\t\t@description Replace the default `CnTranslatedBadge` rendered when the\n\t\t\t\t\t\t\tresolved object's `_translationMeta.translatedFrom` is set. Receives\n\t\t\t\t\t\t\t`:object=\"resolvedObject\"`. Default renders `<CnTranslatedBadge :object=\"resolvedObject\" />`\n\t\t\t\t\t\t\t(which auto-hides when there's nothing to surface). See\n\t\t\t\t\t\t\t`openspec/changes/cn-detail-translation-aware-surfacing`.\n\t\t\t\t\t\t-->\n\t\t\t\t\t\t<slot name=\"translation-badge\" :object=\"resolvedObject\">\n\t\t\t\t\t\t\t<CnTranslatedBadge v-if=\"resolvedObject\" :object=\"resolvedObject\" />\n\t\t\t\t\t\t</slot>\n\t\t\t\t\t\t<p v-if=\"description\" class=\"cn-detail-page__description\">\n\t\t\t\t\t\t\t{{ resolvedDescription }}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<!-- Declarative cross-schema summary chips (manifest\n\t\t\t\t\t\t `config.summaryAggregates`). Count/sum/avg over a\n\t\t\t\t\t\t related schema scoped to this object via @objectId. -->\n\t\t\t\t\t\t<CnSummaryAggregates\n\t\t\t\t\t\t\tv-if=\"summaryAggregates && summaryAggregates.length > 0\"\n\t\t\t\t\t\t\t:aggregates=\"summaryAggregates\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</slot>\n\t\t\t<div class=\"cn-detail-page__header-actions\">\n\t\t\t\t<!-- Next and previous inside the list this record was opened\n\t\t\t\t from. Rendered only when the address names that list: a\n\t\t\t\t record reached by a bare link offers neither, rather than\n\t\t\t\t stepping through an order nobody chose. Both ends say so\n\t\t\t\t instead of wrapping. -->\n\t\t\t\t<div\n\t\t\t\t\tv-if=\"listNavigation && listNavigation.available\"\n\t\t\t\t\tclass=\"cn-detail-page__list-nav\"\n\t\t\t\t\tdata-testid=\"cn-detail-page-list-nav\">\n\t\t\t\t\t<!-- With previousTo/nextTo the control is a link; a disabled\n\t\t\t\t\t end drops `to` so it renders as a disabled button. -->\n\t\t\t\t\t<NcButton\n\t\t\t\t\t\tvariant=\"tertiary\"\n\t\t\t\t\t\t:disabled=\"listNavigation.isFirst\"\n\t\t\t\t\t\t:to=\"listNavigation.isFirst ? undefined : (previousTo || undefined)\"\n\t\t\t\t\t\t:aria-label=\"previousRecordLabel\"\n\t\t\t\t\t\t:title=\"previousRecordLabel\"\n\t\t\t\t\t\tdata-testid=\"cn-detail-page-previous\"\n\t\t\t\t\t\t@click=\"onListStep('previous-record', previousTo, $event)\">\n\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t<ChevronLeft :size=\"20\" />\n\t\t\t\t\t\t</template>\n\t\t\t\t\t</NcButton>\n\t\t\t\t\t<span class=\"cn-detail-page__list-nav-position\" data-testid=\"cn-detail-page-list-position\">\n\t\t\t\t\t\t{{ listPositionLabel }}\n\t\t\t\t\t</span>\n\t\t\t\t\t<NcButton\n\t\t\t\t\t\tvariant=\"tertiary\"\n\t\t\t\t\t\t:disabled=\"listNavigation.isLast\"\n\t\t\t\t\t\t:to=\"listNavigation.isLast ? undefined : (nextTo || undefined)\"\n\t\t\t\t\t\t:aria-label=\"nextRecordLabel\"\n\t\t\t\t\t\t:title=\"nextRecordLabel\"\n\t\t\t\t\t\tdata-testid=\"cn-detail-page-next\"\n\t\t\t\t\t\t@click=\"onListStep('next-record', nextTo, $event)\">\n\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t<ChevronRight :size=\"20\" />\n\t\t\t\t\t\t</template>\n\t\t\t\t\t</NcButton>\n\t\t\t\t</div>\n\t\t\t\t<!-- The action the page declares as its primary one, and the\n\t\t\t\t target the skip link above lands on. -->\n\t\t\t\t<NcButton\n\t\t\t\t\tv-if=\"primaryActionLabel\"\n\t\t\t\t\t:id=\"primaryActionAnchorId\"\n\t\t\t\t\tref=\"primaryActionButton\"\n\t\t\t\t\tvariant=\"primary\"\n\t\t\t\t\tdata-testid=\"cn-detail-page-primary-action\"\n\t\t\t\t\t@click=\"$emit('primary-action', primaryAction)\">\n\t\t\t\t\t{{ primaryActionLabel }}\n\t\t\t\t</NcButton>\n\t\t\t\t<!-- Declarative lifecycle transitions (manifest\n\t\t\t\t `config.lifecycleActions`). Status-gated; driven by the\n\t\t\t\t object's x-openregister-lifecycle. They land in the Actions\n\t\t\t\t menu below, since a record with several transitions filled\n\t\t\t\t the header with buttons. -->\n\t\t\t\t<CnLifecycleActions\n\t\t\t\t\tv-if=\"showsLifecycleActions\"\n\t\t\t\t\t:objectId=\"objectId\"\n\t\t\t\t\t:object=\"currentObject\"\n\t\t\t\t\t:config=\"lifecycleActions\"\n\t\t\t\t\t:schema=\"currentSchema\"\n\t\t\t\t\tdisplay=\"menu\"\n\t\t\t\t\t@entries=\"lifecycleMenuEntries = $event\"\n\t\t\t\t\t@transitioned=\"onTransitioned\"\n\t\t\t\t\t@reload=\"onLifecycleReload\" />\n\t\t\t\t<!-- Declarative header actions (#91 Wave 3): a manifest\n\t\t\t\t `config.headerActions[]` dispatched with visibleWhen gating —\n\t\t\t\t the object context this page provides drives `@objectId` /\n\t\t\t\t `@object.<field>` tokens + local predicates (the shillinq\n\t\t\t\t PaymentRunDetailActions contract).\n\n\t\t\t\t They render as entries in the Actions menu below, not as a\n\t\t\t\t row of buttons, which is what the manifest schema has always\n\t\t\t\t said they are and what CnIndexPage already does with the same\n\t\t\t\t key. A dossiq case declares twelve, and twelve buttons pushed\n\t\t\t\t the record's own title down to a truncated stub. This\n\t\t\t\t instance draws nothing itself; it owns the dialogs the\n\t\t\t\t actions open and feeds the menu through `entries`. -->\n\t\t\t\t<CnActionButtons\n\t\t\t\t\tv-if=\"effectiveHeaderActions.length > 0\"\n\t\t\t\t\t:actions=\"effectiveHeaderActions\"\n\t\t\t\t\tdisplay=\"menu\"\n\t\t\t\t\tdata-testid=\"cn-detail-page-header-actions\"\n\t\t\t\t\t@entries=\"menuHeaderActions = $event\"\n\t\t\t\t\t@created=\"onLifecycleReload\" />\n\t\t\t\t<!--\n\t\t\t\t\t@slot actions\n\t\t\t\t\t@description Right-hand action surface in the page header (typically NcActions\n\t\t\t\t\tor buttons). Renders alongside (not inside) the `header` slot. Receives the\n\t\t\t\t\tresolved object context so an actionsComponent (resolved by CnPageRenderer)\n\t\t\t\t\tcan act on the current record without re-fetching.\n\t\t\t\t\t@binding {object} object The resolved record.\n\t\t\t\t\t@binding {string} objectId The resolved object id.\n\t\t\t\t\t@binding {object} schema The resolved schema.\n\t\t\t\t\t@binding {string} objectType The resolved object type.\n\t\t\t\t\t@binding {object} store The effective object store.\n\t\t\t\t\t@binding {Function} openEditForm Opens this page's own record edit form. Lets an actions component put Edit inside ITS action cluster instead of leaving the page's button beside it — the page renders no button of its own once `showEditAction` is false, but this still opens the same dialog.\n\t\t\t\t\t@binding {boolean} canEditRecord Whether the page would render its own Edit button (`showEditAction` plus a record and schema to edit).\n\t\t\t\t-->\n\t\t\t\t<slot\n\t\t\t\t\tname=\"actions\"\n\t\t\t\t\t:object=\"resolvedObject\"\n\t\t\t\t\t:objectId=\"objectId\"\n\t\t\t\t\t:schema=\"currentSchema\"\n\t\t\t\t\t:objectType=\"resolvedObjectType\"\n\t\t\t\t\t:store=\"effectiveObjectStore\"\n\t\t\t\t\t:openEditForm=\"openEditForm\"\n\t\t\t\t\t:canEditRecord=\"canEditRecord\" />\n\t\t\t\t<!-- Record edit (ADR-062): the detail page's own way to change the\n\t\t\t\t record it is showing. Without it a `type:\"detail\"` page is\n\t\t\t\t read-only and the ONLY edit surface is the modal launched\n\t\t\t\t from the index table — which is why that modal could not\n\t\t\t\t simply be removed. Opens the same schema-driven CnFormDialog\n\t\t\t\t the index used, scoped to this record. -->\n\t\t\t\t<!-- Standalone unless `inlineActions` is set, in which case Edit\n\t\t\t\t joins the header actions above and lands in the Actions menu\n\t\t\t\t with them. Kept standalone by default so every existing\n\t\t\t\t consumer's header is byte-identical. -->\n\t\t\t\t<NcButton\n\t\t\t\t\tv-if=\"canEditRecord && !foldsEditIntoActions\"\n\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\tdata-testid=\"cn-detail-page-edit\"\n\t\t\t\t\t:aria-label=\"editActionLabel\"\n\t\t\t\t\t@click=\"openEditForm\">\n\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t<Pencil :size=\"20\" />\n\t\t\t\t\t</template>\n\t\t\t\t\t{{ editActionLabel }}\n\t\t\t\t</NcButton>\n\t\t\t\t<!-- NB: no sidebar-toggle here — NcObjectSidebar/NcAppSidebar\n\t\t\t\t renders its own open toggle (`.app-sidebar__toggle`) when\n\t\t\t\t closed and an X (`.app-sidebar__close`) when open, so a custom\n\t\t\t\t button would duplicate it. -->\n\t\t\t\t<!-- In-app edit button (ADR-041): icon-only, self-wires from CnAppRoot. -->\n\t\t\t\t<CnBuildiqEditButton />\n\t\t\t\t<CnActionsMenu\n\t\t\t\t\t:showRefresh=\"effectiveHeaderShowRefresh\"\n\t\t\t\t\t:refreshing=\"effectiveRefreshing\"\n\t\t\t\t\t:showRequestFeature=\"showRequestFeature\"\n\t\t\t\t\t:showReportBug=\"showReportBug\"\n\t\t\t\t\t:showDocumentation=\"showDocumentation\"\n\t\t\t\t\t:documentationUrl=\"documentationUrl\"\n\t\t\t\t\t:docsAnchor=\"resolvedPageId\"\n\t\t\t\t\t:documentationLabel=\"documentationLabel || undefined\"\n\t\t\t\t\t:widgetId=\"resolvedPageId\"\n\t\t\t\t\t:title=\"title\"\n\t\t\t\t\t:surface=\"`detail:${resolvedPageId}`\"\n\t\t\t\t\trefreshChannel=\"cn:page:refresh\"\n\t\t\t\t\ttestidBase=\"cn-detail-page\"\n\t\t\t\t\t@refresh=\"onHeaderRefresh\"\n\t\t\t\t\t@requestFeature=\"onHeaderRequestFeature\">\n\t\t\t\t\t<template v-if=\"headerMenuEntries.length\" #primary-items>\n\t\t\t\t\t\t<template v-for=\"entry in headerMenuEntries\">\n\t\t\t\t\t\t\t<!-- An action that goes to a URL is a LINK. The browser\n\t\t\t\t\t\t\t then supplies middle-click, \"open in new tab\" and the\n\t\t\t\t\t\t\t semantics assistive tech announces, none of which a\n\t\t\t\t\t\t\t click handler can. -->\n\t\t\t\t\t\t\t<NcActionLink\n\t\t\t\t\t\t\t\tv-if=\"entry.href\"\n\t\t\t\t\t\t\t\t:key=\"`${entry.id}-link`\"\n\t\t\t\t\t\t\t\t:href=\"entry.href\"\n\t\t\t\t\t\t\t\t:target=\"entry.linkTarget || undefined\"\n\t\t\t\t\t\t\t\t:data-testid=\"entry.testid\">\n\t\t\t\t\t\t\t\t<template v-if=\"entry.iconName || entry.iconClass\" #icon>\n\t\t\t\t\t\t\t\t\t<CnIcon v-if=\"entry.iconName\" :name=\"entry.iconName\" :size=\"20\" />\n\t\t\t\t\t\t\t\t\t<span v-else :class=\"entry.iconClass\" />\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t{{ entry.label }}\n\t\t\t\t\t\t\t</NcActionLink>\n\t\t\t\t\t\t\t<NcActionButton\n\t\t\t\t\t\t\t\tv-else\n\t\t\t\t\t\t\t\t:key=\"entry.id\"\n\t\t\t\t\t\t\t\t:data-testid=\"entry.testid\"\n\t\t\t\t\t\t\t\t:disabled=\"entry.disabled\"\n\t\t\t\t\t\t\t\t:aria-pressed=\"entry.pressed === null ? null : String(entry.pressed)\"\n\t\t\t\t\t\t\t\t:closeAfterClick=\"true\"\n\t\t\t\t\t\t\t\t@click=\"entry.run()\">\n\t\t\t\t\t\t\t\t<template v-if=\"entry.iconName || entry.iconClass\" #icon>\n\t\t\t\t\t\t\t\t\t<CnIcon v-if=\"entry.iconName\" :name=\"entry.iconName\" :size=\"20\" />\n\t\t\t\t\t\t\t\t\t<span v-else :class=\"entry.iconClass\" />\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t{{ entry.label }}\n\t\t\t\t\t\t\t</NcActionButton>\n\t\t\t\t\t\t</template>\n\t\t\t\t\t\t<NcActionSeparator />\n\t\t\t\t\t</template>\n\t\t\t\t</CnActionsMenu>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<!-- The locked card, under the title, for ANY active lock — not only a\n\t\t remote one. It used to be suppressed when the current user held the\n\t\t lock, which meant the one person who could do something about a\n\t\t stale lock was also the only person the UI never told about it.\n\t\t The card carries the tone: an error for somebody else's lock, a\n\t\t neutral notice plus Unlock for your own. -->\n\t\t<CnLockedBanner\n\t\t\tv-if=\"lockState && lockState.locked.value\"\n\t\t\t:lockedBy=\"lockState.lockedBy.value\"\n\t\t\t:lockedByMe=\"lockState.lockedByMe.value\"\n\t\t\t:expiresAt=\"lockState.expiresAt.value\"\n\t\t\t:unlocking=\"releasingLock\"\n\t\t\t@unlock=\"onReleaseLock\" />\n\n\t\t<!-- The sentence a refused acquire left behind. Shown SEPARATELY from\n\t\t the banner above and not folded into it: a refused acquire does not\n\t\t refresh the cached object, so `@self.locked` is still whatever the\n\t\t last read said and the banner may not have appeared yet. This\n\t\t carries the server's own message, which names the holder. -->\n\t\t<p\n\t\t\tv-if=\"editLockRefusal\"\n\t\t\tclass=\"cn-detail-page__lock-refusal\"\n\t\t\trole=\"alert\"\n\t\t\tdata-testid=\"cn-detail-page-lock-refusal\">\n\t\t\t{{ editLockRefusal }}\n\t\t</p>\n\n\t\t<!-- Not-found state: the record behind the address does not exist. -->\n\t\t<div v-if=\"objectNotFound\" class=\"cn-detail-page__not-found\" data-testid=\"cn-detail-page-not-found\">\n\t\t\t<!--\n\t\t\t\t@slot not-found\n\t\t\t\t@description Replace the default not-found surface, shown instead of the\n\t\t\t\theader and body when the schema-driven fetch answers 404.\n\t\t\t\t@binding {object|string} target Router location of the back button.\n\t\t\t-->\n\t\t\t<slot name=\"not-found\" :target=\"notFoundTarget\">\n\t\t\t\t<NcEmptyContent :name=\"notFoundLabels.name\" :description=\"notFoundLabels.description\">\n\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t<FileQuestionOutline :size=\"48\" />\n\t\t\t\t\t</template>\n\t\t\t\t\t<template v-if=\"$router\" #action>\n\t\t\t\t\t\t<NcButton\n\t\t\t\t\t\t\tvariant=\"primary\"\n\t\t\t\t\t\t\tdata-testid=\"cn-detail-page-not-found-back\"\n\t\t\t\t\t\t\t:to=\"notFoundTarget\">\n\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t<ArrowLeft :size=\"20\" />\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t{{ notFoundButtonLabel }}\n\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t</template>\n\t\t\t\t</NcEmptyContent>\n\t\t\t</slot>\n\t\t</div>\n\n\t\t<!-- Loading state -->\n\t\t<div v-else-if=\"showLoadingState\" class=\"cn-detail-page__loading\">\n\t\t\t<NcLoadingIcon :size=\"32\" />\n\t\t\t<span>{{ loadingLabel }}</span>\n\t\t</div>\n\n\t\t<!-- Error state -->\n\t\t<div v-else-if=\"error\" class=\"cn-detail-page__error\">\n\t\t\t<!--\n\t\t\t\t@slot error\n\t\t\t\t@description Replace the default `<NcEmptyContent>` error surface. Default\n\t\t\t\tcontent uses `errorMessage` + an MDI alert icon + an optional retry button.\n\t\t\t-->\n\t\t\t<slot name=\"error\">\n\t\t\t\t<NcEmptyContent :name=\"errorMessage\">\n\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t<AlertCircleOutline :size=\"48\" />\n\t\t\t\t\t</template>\n\t\t\t\t\t<template #action>\n\t\t\t\t\t\t<NcButton v-if=\"onRetry\" variant=\"primary\" @click=\"onRetry\">\n\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t<Refresh :size=\"20\" />\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t{{ retryLabel }}\n\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t@slot error-actions\n\t\t\t\t\t\t\t@description Extra buttons rendered inside the default error\n\t\t\t\t\t\t\tsurface's action area, after the (optional) Retry button.\n\t\t\t\t\t\t-->\n\t\t\t\t\t\t<slot name=\"error-actions\" />\n\t\t\t\t\t</template>\n\t\t\t\t</NcEmptyContent>\n\t\t\t</slot>\n\t\t</div>\n\n\t\t<!-- Empty state -->\n\t\t<div v-else-if=\"empty\" class=\"cn-detail-page__empty\">\n\t\t\t<!--\n\t\t\t\t@slot empty\n\t\t\t\t@description Replace the default empty-state `<NcEmptyContent>` surface.\n\t\t\t-->\n\t\t\t<slot name=\"empty\">\n\t\t\t\t<NcEmptyContent :name=\"emptyLabel\">\n\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t<InformationOutline :size=\"48\" />\n\t\t\t\t\t</template>\n\t\t\t\t\t<template #action>\n\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t@slot empty-actions\n\t\t\t\t\t\t\t@description Buttons rendered inside the default empty-state\n\t\t\t\t\t\t\taction area.\n\t\t\t\t\t\t-->\n\t\t\t\t\t\t<slot name=\"empty-actions\" />\n\t\t\t\t\t</template>\n\t\t\t\t</NcEmptyContent>\n\t\t\t</slot>\n\t\t</div>\n\n\t\t<!-- Main content -->\n\t\t<div v-else class=\"cn-detail-page__body\">\n\t\t\t<div v-if=\"$slots['before-body'] || $slots['before-body']\" class=\"cn-detail-page__before-body\">\n\t\t\t\t<!--\n\t\t\t\t\t@slot before-body\n\t\t\t\t\t@description Content rendered at the top of the body, above the grid\n\t\t\t\t\tlayout / stats / schema-driven auto-body (Data + Related). Use it to\n\t\t\t\t\tsurface page-level widgets (e.g. a KPI/insights dashboard) in the body\n\t\t\t\t\tbelow the header+actions line without suppressing the auto Data/Related\n\t\t\t\t\tsections (which a `default` slot override would).\n\t\t\t\t\t@binding {object} object The resolved record.\n\t\t\t\t\t@binding {object} schema The resolved schema.\n\t\t\t\t\t@binding {string} objectType The resolved object type.\n\t\t\t\t\t@binding {string} objectId The resolved object id.\n\t\t\t\t\t@binding {object} store The effective object store.\n\t\t\t\t-->\n\t\t\t\t<slot\n\t\t\t\t\tname=\"before-body\"\n\t\t\t\t\t:object=\"resolvedObject\"\n\t\t\t\t\t:schema=\"currentSchema\"\n\t\t\t\t\t:objectType=\"resolvedObjectType\"\n\t\t\t\t\t:objectId=\"objectId\"\n\t\t\t\t\t:store=\"effectiveObjectStore\" />\n\t\t\t</div>\n\n\t\t\t<!-- Declarative in-body sections, `placement: \"before-body\"` —\n\t\t\t above the grid / stats / auto-body. -->\n\t\t\t<CnBodySections\n\t\t\t\tv-if=\"hasBodyWidgets\"\n\t\t\t\t:sections=\"bodyWidgets\"\n\t\t\t\t:context=\"sectionContext\"\n\t\t\t\tplacement=\"before-body\"\n\t\t\t\tdata-testid=\"cn-detail-body-sections-before-body\" />\n\n\t\t\t<!-- Adjustable widget grid (GridStack). The detail body is, at its\n\t\t\t core, a real drag/resize grid: by default it is seeded with the\n\t\t\t schema-driven Data + Related widgets (see `bodyGridLayout`), but in\n\t\t\t Buildiq edit mode widgets can be moved, resized, configured and\n\t\t\t added. Explicit `layout` + `widgets` props (manifest grid pages)\n\t\t\t feed the same engine, so hand-authored grid pages also become\n\t\t\t draggable. -->\n\t\t\t<!-- :key remounts the grid when in-app edit mode flips (ADR-041):\n\t\t\t the manifest is raw (non-reactive) until useManifestEditor\n\t\t\t observes it in place, so a grid mounted pre-edit never\n\t\t\t subscribed to the layout/widgets arrays — in-place pushes\n\t\t\t (Add widget) keep the same array identity and can't re-render\n\t\t\t it. One remount per edit flip re-subscribes it. -->\n\t\t\t<CnDashboardGrid\n\t\t\t\tv-if=\"hasBodyGrid\"\n\t\t\t\t:key=\"`cn-detail-grid-${editingBody ? 'editing' : 'live'}`\"\n\t\t\t\t:layout=\"bodyGridLayout\"\n\t\t\t\t:editable=\"editingBody\"\n\t\t\t\t:columns=\"12\"\n\t\t\t\t:columnOpts=\"columnOpts\"\n\t\t\t\tclass=\"cn-detail-page__grid\"\n\t\t\t\t@layoutChange=\"onBodyLayoutChange\">\n\t\t\t\t<template #widget=\"{ item }\">\n\t\t\t\t\t<div\n\t\t\t\t\t\tclass=\"cn-detail-page__grid-item\"\n\t\t\t\t\t\t:class=\"{ 'cn-detail-page__grid-item--fit': !!item.sizeToContent }\"\n\t\t\t\t\t\t:aria-labelledby=\"showGridTitle(item) ? `widget-title-${item.id}` : undefined\">\n\t\t\t\t\t\t<!-- In-app edit overlay (ADR-041): a configure cog appears on\n\t\t\t\t\t\t EVERY grid widget while the page is in Buildiq edit mode,\n\t\t\t\t\t\t as it does on CnDashboardPage. It was gated on the type\n\t\t\t\t\t\t having a registered config form, which left a `custom`\n\t\t\t\t\t\t widget and an `integration` leaf with no cog at all: they\n\t\t\t\t\t\t could be dragged and resized but never configured or\n\t\t\t\t\t\t removed, because the modal's own Delete affordance is the\n\t\t\t\t\t\t only way off the page. The modal already handles a type\n\t\t\t\t\t\t without a form (title, icon, style, delete), so the gate\n\t\t\t\t\t\t bought nothing. -->\n\t\t\t\t\t\t<div v-if=\"showsCog(item)\" class=\"cn-detail-page__widget-edit\">\n\t\t\t\t\t\t\t<NcButton variant=\"tertiary\" :aria-label=\"t('nextcloud-vue', 'Configure widget')\" @click=\"configureWidget(item)\">\n\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t<Cog :size=\"18\" />\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<!-- Section heading ONLY for consumer-supplied bare-content slots.\n\t\t\t\t\t\t Built-in widgets (data / related / integration / catalog)\n\t\t\t\t\t\t render their own titled card header, so a grid <h3> here would\n\t\t\t\t\t\t duplicate the title above the widget. -->\n\t\t\t\t\t\t<h3\n\t\t\t\t\t\t\tv-if=\"showGridTitle(item)\"\n\t\t\t\t\t\t\t:id=\"`widget-title-${item.id}`\"\n\t\t\t\t\t\t\tclass=\"cn-detail-page__widget-title\">\n\t\t\t\t\t\t\t{{ gridTitle(item) }}\n\t\t\t\t\t\t</h3>\n\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t@slot `widget-${item.widgetId}`\n\t\t\t\t\t\t\t@description Per-widget slot whose name is `widget-<widgetId>`. Use\n\t\t\t\t\t\t\tit to inject custom widget content into a grid slot. Default\n\t\t\t\t\t\t\tfallback renders a registry widget: `type: 'data'` renders the\n\t\t\t\t\t\t\tschema-driven data widget; `type: 'related'` the related-objects\n\t\t\t\t\t\t\twidget; `type: 'integration'` resolves from the integration\n\t\t\t\t\t\t\tregistry; any other content-driven catalog type (stat / chart /\n\t\t\t\t\t\t\tdelta / gauge / object-list / …) renders its registered renderer.\n\n\t\t\t\t\t\t\tThe page's object context is bound alongside the widget\n\t\t\t\t\t\t\tdescriptor because a `type: \"custom\"` widget is not a template —\n\t\t\t\t\t\t\tCnPageRenderer mounts the mapped component as\n\t\t\t\t\t\t\t`<component v-bind=\"slotProps\" />`, so whatever THIS slot binds\n\t\t\t\t\t\t\tIS that widget's entire prop set. Binding only `item`/`widget`\n\t\t\t\t\t\t\ttherefore left every custom widget that declares `objectId`\n\t\t\t\t\t\t\tsitting on its own `default: ''` — and an empty id does not\n\t\t\t\t\t\t\terror, it widens the widget's OpenRegister filter to the whole\n\t\t\t\t\t\t\tcollection (decidiq#968: a voting-round panel filtering on\n\t\t\t\t\t\t\t`relations.motion: ''` listed every round in the instance, so a\n\t\t\t\t\t\t\tvote could be cast against another motion's round). Widgets that\n\t\t\t\t\t\t\tdeclare none of these props are unaffected — this is purely\n\t\t\t\t\t\t\tadditive.\n\n\t\t\t\t\t\t\t`objectId` is bound from the PROP, never read back off the loaded\n\t\t\t\t\t\t\trecord: `currentObject` / `resolvedObject` are themselves keyed by\n\t\t\t\t\t\t\t`objectId`, and the record is null for the first frames of a\n\t\t\t\t\t\t\tdetail page — the same \"the record has not arrived yet\" race\n\t\t\t\t\t\t\t`editFormAwaitingRecord` guards (#850). The route param reaches\n\t\t\t\t\t\t\tthe prop through CnPageRenderer, which maps `params.id` →\n\t\t\t\t\t\t\t`objectId`, so the id is there on the first render while `object`\n\t\t\t\t\t\t\tis not.\n\t\t\t\t\t\t\t@binding {object} item Layout item descriptor.\n\t\t\t\t\t\t\t@binding {object} widget Resolved widget definition.\n\t\t\t\t\t\t\t@binding {string|number} objectId This record's id. Unlike `object`\n\t\t\t\t\t\t\tit is present on the very first render, because it comes from the route.\n\t\t\t\t\t\t\t@binding {object} object The loaded record, or null while it is\n\t\t\t\t\t\t\tstill being fetched.\n\t\t\t\t\t\t\t@binding {object} objectData Alias of `object`, spelled the way widget\n\t\t\t\t\t\t\tcomponents declare the prop (`objectData`).\n\t\t\t\t\t\t\t@binding {string} objectType Resolved object type slug.\n\t\t\t\t\t\t\t@binding {string} register Register slug of this page.\n\t\t\t\t\t\t\t@binding {string} schema Schema slug of this page.\n\t\t\t\t\t\t-->\n\t\t\t\t\t\t<slot\n\t\t\t\t\t\t\t:name=\"`widget-${item.widgetId}`\"\n\t\t\t\t\t\t\t:item=\"item\"\n\t\t\t\t\t\t\t:widget=\"findWidget(item)\"\n\t\t\t\t\t\t\t:objectId=\"objectId\"\n\t\t\t\t\t\t\t:object=\"resolvedObject\"\n\t\t\t\t\t\t\t:objectData=\"resolvedObject\"\n\t\t\t\t\t\t\t:objectType=\"resolvedObjectType\"\n\t\t\t\t\t\t\t:register=\"register\"\n\t\t\t\t\t\t\t:schema=\"schema\">\n\t\t\t\t\t\t\t<CnDetailWidgetHost\n\t\t\t\t\t\t\t\t:widget=\"findWidget(item)\"\n\t\t\t\t\t\t\t\tchrome=\"card\"\n\t\t\t\t\t\t\t\t:showCardTitle=\"showCardTitle(item)\"\n\t\t\t\t\t\t\t\t:objectId=\"objectId\"\n\t\t\t\t\t\t\t\t:object=\"currentObject\"\n\t\t\t\t\t\t\t\t:objectType=\"resolvedObjectType\"\n\t\t\t\t\t\t\t\t:schemaObject=\"currentSchema\"\n\t\t\t\t\t\t\t\t:register=\"register\"\n\t\t\t\t\t\t\t\t:schema=\"schema\"\n\t\t\t\t\t\t\t\t:store=\"effectiveObjectStore\"\n\t\t\t\t\t\t\t\t:surface=\"surface\"\n\t\t\t\t\t\t\t\t:integrationContext=\"effectiveIntegrationContext\"\n\t\t\t\t\t\t\t\t:hideEmpty=\"hideEmpty\"\n\t\t\t\t\t\t\t\t:cnRegistry=\"cnRegistry\"\n\t\t\t\t\t\t\t\t:availableWidgets=\"bodyGridWidgets\"\n\t\t\t\t\t\t\t\t@geoSaved=\"onGeoSaved\"\n\t\t\t\t\t\t\t\t@openIntegration=\"onAutoBodyOpenIntegration\" />\n\t\t\t\t\t\t</slot>\n\t\t\t\t\t</div>\n\t\t\t\t</template>\n\t\t\t</CnDashboardGrid>\n\n\t\t\t<!-- Statistics table -->\n\t\t\t<div v-if=\"hasStats\" class=\"cn-detail-page__stats\">\n\t\t\t\t<!--\n\t\t\t\t\t@slot stats-header\n\t\t\t\t\t@description Replace the heading above the stats table. Default\n\t\t\t\t\tcontent: an `<h3>` showing `statsTitle`.\n\t\t\t\t-->\n\t\t\t\t<slot name=\"stats-header\">\n\t\t\t\t\t<h3 v-if=\"statsTitle\" class=\"cn-detail-page__section-title\">\n\t\t\t\t\t\t{{ resolvedStatsTitle }}\n\t\t\t\t\t</h3>\n\t\t\t\t</slot>\n\t\t\t\t<table class=\"cn-detail-page__stats-table\">\n\t\t\t\t\t<thead v-if=\"statsColumns.length > 0\">\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<th v-for=\"col in statsColumns\"\n\t\t\t\t\t\t\t\t:key=\"col.key\"\n\t\t\t\t\t\t\t\tscope=\"col\"\n\t\t\t\t\t\t\t\t:class=\"col.align ? 'cn-detail-page__stats-cell--' + col.align : ''\">\n\t\t\t\t\t\t\t\t{{ col.label }}\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</thead>\n\t\t\t\t\t<tbody>\n\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t@slot stats-rows\n\t\t\t\t\t\t\t@description Replace the default rendering of the `statsRows`\n\t\t\t\t\t\t\tprop. Use when rows need custom formatting per column.\n\t\t\t\t\t\t-->\n\t\t\t\t\t\t<slot name=\"stats-rows\">\n\t\t\t\t\t\t\t<tr v-for=\"(row, index) in statsRows\" :key=\"index\" :class=\"{ 'cn-detail-page__stats-row--sub': row.indent }\">\n\t\t\t\t\t\t\t\t<td v-for=\"col in statsColumns\" :key=\"col.key\" :class=\"[row.indent ? 'cn-detail-page__stats-cell--indented' : '', col.align ? 'cn-detail-page__stats-cell--' + col.align : '']\">\n\t\t\t\t\t\t\t\t\t{{ row[col.key] !== undefined ? row[col.key] : '-' }}\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t</slot>\n\t\t\t\t\t</tbody>\n\t\t\t\t</table>\n\t\t\t</div>\n\n\t\t\t<!-- Default vertical stacking mode. The schema-driven auto-body (Data +\n\t\t\t Related) is now rendered by the adjustable grid above (seeded by\n\t\t\t `bodyGridLayout`), so this branch only carries hand-authored\n\t\t\t default-slot content when no widget grid is active. -->\n\t\t\t<div v-else class=\"cn-detail-page__content\">\n\t\t\t\t<!-- Default content -->\n\t\t\t\t<div v-if=\"!hasBodyGrid\" class=\"cn-detail-page__content\">\n\t\t\t\t\t<!--\n\t\t\t\t\t\t@slot default\n\t\t\t\t\t\t@description Main body content rendered when no grid layout, no\n\t\t\t\t\t\tstats table, and no schema-driven auto-body apply. Use it to ship\n\t\t\t\t\t\ta hand-authored detail page.\n\t\t\t\t\t-->\n\t\t\t\t\t<slot />\n\t\t\t\t</div>\n\n\t\t\t\t<!-- Sections slot — additional content below stats -->\n\t\t\t\t<div v-if=\"$slots.sections\" class=\"cn-detail-page__sections\">\n\t\t\t\t\t<!--\n\t\t\t\t\t\t@slot sections\n\t\t\t\t\t\t@description Additional vertically-stacked content rendered below\n\t\t\t\t\t\tthe default body / stats table.\n\t\t\t\t\t-->\n\t\t\t\t\t<slot name=\"sections\" />\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- Declarative in-body sections, `placement: \"after-data\"` —\n\t\t\t below the data/auto-body, above the related-object lists. -->\n\t\t\t<CnBodySections\n\t\t\t\tv-if=\"hasBodyWidgets\"\n\t\t\t\t:sections=\"bodyWidgets\"\n\t\t\t\t:context=\"sectionContext\"\n\t\t\t\tplacement=\"after-data\"\n\t\t\t\tdata-testid=\"cn-detail-body-sections-after-data\" />\n\n\t\t\t<!-- Declarative related-object list sections (manifest\n\t\t\t `config.relatedCollections`). Rendered below the detail body;\n\t\t\t each section's filter is scoped to this object via @objectId.\n\t\t\t An optional relation-link button opens CnRelationLinkModal. -->\n\t\t\t<div\n\t\t\t\tv-if=\"(relatedCollections && relatedCollections.length > 0) || (relationLinks && relationLinks.length > 0)\"\n\t\t\t\tclass=\"cn-detail-page__related-collections\">\n\t\t\t\t<div v-if=\"relationLinks && relationLinks.length > 0\" class=\"cn-detail-page__relation-links\">\n\t\t\t\t\t<NcButton\n\t\t\t\t\t\tv-for=\"(link, li) in relationLinks\"\n\t\t\t\t\t\t:key=\"li\"\n\t\t\t\t\t\tclass=\"cn-detail-page__relation-link-button\"\n\t\t\t\t\t\t:data-testid=\"`cn-detail-relation-link-${li}`\"\n\t\t\t\t\t\t@click=\"openRelationLink(link)\">\n\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t<Plus :size=\"18\" />\n\t\t\t\t\t\t</template>\n\t\t\t\t\t\t{{ link.label || t('nextcloud-vue', 'Link related object') }}\n\t\t\t\t\t</NcButton>\n\t\t\t\t</div>\n\t\t\t\t<CnRelatedCollections\n\t\t\t\t\tv-if=\"relatedCollections && relatedCollections.length > 0\"\n\t\t\t\t\t:collections=\"relatedCollections\"\n\t\t\t\t\t@rowClick=\"onRelatedRowClick\" />\n\t\t\t</div>\n\n\t\t\t<!-- Declarative in-body sections, `placement: \"after-related\"` —\n\t\t\t below the related-object lists. -->\n\t\t\t<CnBodySections\n\t\t\t\tv-if=\"hasBodyWidgets\"\n\t\t\t\t:sections=\"bodyWidgets\"\n\t\t\t\t:context=\"sectionContext\"\n\t\t\t\tplacement=\"after-related\"\n\t\t\t\tdata-testid=\"cn-detail-body-sections-after-related\" />\n\n\t\t\t<!-- Declarative in-body sections, `placement: \"end\"` (the default\n\t\t\t placement) — the last body content, above the footer. -->\n\t\t\t<CnBodySections\n\t\t\t\tv-if=\"hasBodyWidgets\"\n\t\t\t\t:sections=\"endPlacementSections\"\n\t\t\t\t:context=\"sectionContext\"\n\t\t\t\t:placement=\"null\"\n\t\t\t\tdata-testid=\"cn-detail-body-sections-end\" />\n\n\t\t\t<!-- Footer -->\n\t\t\t<div v-if=\"$slots.footer\" class=\"cn-detail-page__footer\">\n\t\t\t\t<!--\n\t\t\t\t\t@slot footer\n\t\t\t\t\t@description Footer surface rendered below the detail-page body. Use\n\t\t\t\t\tit for save/cancel button rows or status text.\n\t\t\t\t-->\n\t\t\t\t<slot name=\"footer\" />\n\t\t\t</div>\n\t\t</div>\n\n\t\t<!-- Per-widget style/config editor (ADR-041). Opened by the per-widget\n\t\t configure cog while in Buildiq edit mode; the modal's own Delete\n\t\t button removes the widget from the grid. -->\n\t\t<CnWidgetStyleEditorModal\n\t\t\tv-if=\"showWidgetConfig\"\n\t\t\t:show=\"showWidgetConfig\"\n\t\t\t:widget=\"configWidget\"\n\t\t\t:deletable=\"true\"\n\t\t\t@save=\"onWidgetConfigSave\"\n\t\t\t@delete=\"onWidgetConfigDelete\"\n\t\t\t@close=\"showWidgetConfig = false\" />\n\n\t\t<!-- @slot form-dialog Replace the built-in create/edit form dialog (use CnFormDialog or CnAdvancedFormDialog). Deliberately the SAME slot name and the same scope as CnIndexPage's `form-dialog`, so one replacement component serves both pages and an app author learns one contract, not two. Covers both of this page's built-in dialogs — the create archetype's empty form and the record edit form — which are mutually exclusive, exactly as CnIndexPage's single slot covers create and edit. -->\n\t\t<!-- @binding {boolean} show Whether the form dialog is currently visible. -->\n\t\t<!-- @binding {?object} item The record being edited; in create mode the route-derived prefill, or null when there is nothing to prefill. -->\n\t\t<!-- @binding {object} schema The effective JSON schema driving the form. Transform this — rather than replacing the save path — to splice a runtime vocabulary into an enum. -->\n\t\t<!-- @binding {Function} confirm Persists the form data through the page's own save path and emits `created`/`edited`. Call this instead of saving in the replacement dialog, so a create or edit made there behaves exactly like one made in the built-in dialog. RESOLVES to a `{ success: true, data }` / `{ error }` result, which a replacement rendering its own CnFormDialog must hand back to that dialog's `setResult()`: CnFormDialog sets `loading` on submit and only `setResult` clears it, and `no-close` is bound to `loading`, so a replacement that ignores the result locks its own modal open on both success and failure. -->\n\t\t<!-- @binding {Function} close Closes the form dialog — in create mode this is the \"dismissed without saving\" path, which navigates back so the user is not stranded on an id-less page. -->\n\t\t<!--\n\t\t `show` and `confirm` are bound as PROPS, not left as listeners on\n\t\t the default children. A manifest-declared replacement is mounted by\n\t\t CnPageRenderer as `<component :is=… v-bind=\"slotProps\" />`, which\n\t\t binds props only — so a listener is unreachable from a manifest\n\t\t even in principle, and a replacement dialog could render and close\n\t\t but never save (openconnector#1150, fixed the same way on\n\t\t CnIndexPage).\n\n\t\t The two default children below are UNCHANGED and still wire their\n\t\t own `@confirm` / `@close` directly, so a page that passes no slot\n\t\t renders and behaves exactly as it did before this slot existed.\n\t\t-->\n\t\t<slot\n\t\t\tname=\"form-dialog\"\n\t\t\t:show=\"formDialogVisible\"\n\t\t\t:item=\"formDialogItem\"\n\t\t\t:schema=\"currentSchema\"\n\t\t\t:confirm=\"onFormDialogConfirm\"\n\t\t\t:close=\"onFormDialogClose\">\n\t\t\t<!-- Create archetype (ADR-062): a schema-bound `type:\"detail\"` page with\n\t\t\t no object id renders an empty create form for its schema instead of a\n\t\t\t blank page. Save POSTs the object and navigates to its detail route\n\t\t\t (or back); prefill comes from the route query. -->\n\t\t\t<CnFormDialog\n\t\t\t\tv-if=\"isCreateMode && currentSchema\"\n\t\t\t\tref=\"createFormDialog\"\n\t\t\t\t:schema=\"currentSchema\"\n\t\t\t\t:item=\"createPrefill\"\n\t\t\t\t:register=\"register\"\n\t\t\t\t:dialogTitle=\"title || undefined\"\n\t\t\t\t:excludeFields=\"excludeFields\"\n\t\t\t\t:includeFields=\"includeFields\"\n\t\t\t\t:fieldOverrides=\"fieldOverrides\"\n\t\t\t\t:size=\"formSize\"\n\t\t\t\t:columns=\"formColumns\"\n\t\t\t\t@confirm=\"onCreateFormConfirm\"\n\t\t\t\t@close=\"onCreateFormClose\" />\n\n\t\t\t<!-- Record edit form. Same component and same schema the index table's\n\t\t\t modal used; the difference is that it is reached from the record,\n\t\t\t with the record's own page around it.\n\n\t\t\t Waits for the RECORD as well as the schema. `currentObject` is a\n\t\t\t store read that is null until this page's own fetch lands, and a\n\t\t\t dialog opened before then shows an empty form for a record that\n\t\t\t has values — which the user can type into, and whose Save would\n\t\t\t PUT those blanks over the record. -->\n\t\t\t<CnFormDialog\n\t\t\t\tv-if=\"editFormOpen && currentSchema && !editFormAwaitingRecord\"\n\t\t\t\tref=\"editFormDialog\"\n\t\t\t\t:schema=\"currentSchema\"\n\t\t\t\t:item=\"currentObject\"\n\t\t\t\t:register=\"register\"\n\t\t\t\t:dialogTitle=\"editActionLabel\"\n\t\t\t\t:excludeFields=\"excludeFields\"\n\t\t\t\t:includeFields=\"includeFields\"\n\t\t\t\t:fieldOverrides=\"fieldOverrides\"\n\t\t\t\t:size=\"formSize\"\n\t\t\t\t:columns=\"formColumns\"\n\t\t\t\t@confirm=\"onEditFormConfirm\"\n\t\t\t\t@close=\"closeEditForm\" />\n\t\t</slot>\n\n\t\t<!-- Relation-link modal (manifest `config.relationLinks`): async-search a\n\t\t target schema and patch a FK on the current object. -->\n\t\t<CnRelationLinkModal\n\t\t\tv-if=\"activeRelationLink\"\n\t\t\t:title=\"activeRelationLink.title || undefined\"\n\t\t\t:selectLabel=\"activeRelationLink.selectLabel || undefined\"\n\t\t\t:register=\"activeRelationLink.register\"\n\t\t\t:schema=\"activeRelationLink.schema\"\n\t\t\t:labelField=\"activeRelationLink.labelField || 'name'\"\n\t\t\t:allowCreate=\"activeRelationLink.allowCreate === true\"\n\t\t\t:currentType=\"resolvedObjectType\"\n\t\t\t:currentObject=\"currentObject || {}\"\n\t\t\t:fkField=\"activeRelationLink.fkField\"\n\t\t\t@linked=\"onRelationLinked\"\n\t\t\t@close=\"activeRelationLink = null\" />\n\t</div>\n</template>\n\n<script>\nimport { subscribe, unsubscribe } from '@nextcloud/event-bus'\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcActionButton, NcActionLink, NcActionSeparator, NcButton, NcEmptyContent, NcLoadingIcon } from '@nextcloud/vue'\nimport { provide, ref, watch } from 'vue'\nimport AlertCircleOutline from 'vue-material-design-icons/AlertCircleOutline.vue'\nimport ArrowLeft from 'vue-material-design-icons/ArrowLeft.vue'\nimport ChevronLeft from 'vue-material-design-icons/ChevronLeft.vue'\nimport ChevronRight from 'vue-material-design-icons/ChevronRight.vue'\nimport Cog from 'vue-material-design-icons/Cog.vue'\nimport FileQuestionOutline from 'vue-material-design-icons/FileQuestionOutline.vue'\nimport InformationOutline from 'vue-material-design-icons/InformationOutline.vue'\nimport Pencil from 'vue-material-design-icons/Pencil.vue'\nimport Plus from 'vue-material-design-icons/Plus.vue'\nimport Refresh from 'vue-material-design-icons/Refresh.vue'\nimport CnRelationLinkModal from '../../dialogs/CnRelationLinkModal.vue'\nimport CnWidgetStyleEditorModal from '../../dialogs/CnWidgetStyleEditorModal.vue'\nimport CnActionsMenu from '../CnActionsMenu/CnActionsMenu.vue'\nimport CnBodySections from '../CnBodySections/CnBodySections.vue'\nimport CnBuildiqEditButton from '../CnBuildiqEditButton/CnBuildiqEditButton.vue'\nimport CnDashboardGrid from '../CnDashboardGrid/CnDashboardGrid.vue'\nimport CnDetailWidgetHost from '../CnDetailWidgetHost/CnDetailWidgetHost.vue'\nimport CnFormDialog from '../CnFormDialog/CnFormDialog.vue'\nimport CnLifecycleActions from '../CnLifecycleActions/CnLifecycleActions.vue'\nimport CnLockedBanner from '../CnLockedBanner/CnLockedBanner.vue'\nimport CnRelatedCollections from '../CnRelatedCollections/CnRelatedCollections.vue'\nimport CnSummaryAggregates from '../CnSummaryAggregates/CnSummaryAggregates.vue'\nimport CnTranslatedBadge from '../CnTranslatedBadge/CnTranslatedBadge.vue'\nimport { useIntegrationRegistry } from '../../composables/useIntegrationRegistry.js'\nimport { useObjectLock } from '../../composables/useObjectLock.js'\nimport { useObjectPresence } from '../../composables/useObjectPresence.js'\nimport { useObjectSubscription } from '../../composables/useObjectSubscription.js'\nimport { gridLayout } from '../../mixins/gridLayout.js'\nimport { useObjectStore } from '../../store/index.js'\nimport { isAppInstalled } from '../../utils/appInstalled.js'\nimport { compactLayoutRows } from '../../utils/dashboardPlacement.js'\nimport { defaultDetailGrid } from '../../utils/defaultDetailGrid.js'\nimport { cnGridCellStyle, hasGridRow } from '../../utils/grid.js'\nimport { slotRenders } from '../../utils/slotContent.js'\nimport {\n\tisCardWidgetDef,\n\tisContentOnlyWidgetDef,\n\tisDataWidgetDef,\n\tisGeoWidgetDef,\n\tisRelatedWidgetDef,\n\tresolveRegistryRenderer,\n\twidgetContentOf,\n\twidgetTitleOf,\n} from '../../utils/widgetDispatch.js'\nimport { CnActionButtons } from '../CnActionButtons/index.js'\nimport { CnIcon } from '../CnIcon/index.js'\nimport { getWidgetTypeEntry } from '../CnWidgetGrid/dashboardWidgetRegistry.js'\n\nimport '../CnWidgetGrid/registerDashboardWidgets.js'\n\n/**\n * Responsive column table for a detail body, measured against the GRID element.\n *\n * ONE threshold, and deliberately no steps between. `moveScale` rescales the\n * authored geometry into the new count, so an intermediate width turns a\n * 12-column record into fractional positions nobody placed: a `gridWidth: 3`\n * tile becomes 1 of 4, a `gridWidth: 9` panel becomes 3 of 4, and widgets land\n * left, centre or right depending purely on how the division rounded. That reads\n * as a broken page rather than a narrow one. A record is authored at 12 columns\n * or it is a single stacked column; the sizes in between are not designs.\n *\n * 1000px is where the 12-column geometry stops working rather than merely\n * tightening: it puts a `gridWidth: 3` side panel — Timeline, Flow runs — under\n * 250px, which is below its own title.\n *\n * `breakpointForWindow` is FALSE, unlike `getDashboardColumnOpts()`: a page in a\n * split pane sits in a narrow container on a wide window, so measuring the window\n * is measuring the wrong box and the grid would never reflow.\n *\n * `columnMax` is set EXPLICITLY. Above the top breakpoint GridStack assigns\n * `newColumn = columnOpts.columnMax`, and `column(undefined)` silently no-ops, so\n * a grid that once narrowed would never widen again.\n */\nconst DEFAULT_DETAIL_COLUMN_OPTS = Object.freeze({\n\tcolumnMax: 12,\n\tbreakpoints: [\n\t\t{ w: 1000, c: 1 },\n\t],\n\tlayout: 'moveScale',\n\tbreakpointForWindow: false,\n})\n\n/**\n * Event-bus channel a page-level refresh is announced on. The page's own\n * Actions menu emits it, the manifest `refresh` / `api-call` actions bump it,\n * and an app's own dialog emits it after a successful write.\n */\nconst PAGE_REFRESH_CHANNEL = 'cn:page:refresh'\n\n/** Surfaces understood by the pluggable integration registry (AD-19). */\nconst INTEGRATION_SURFACES = ['user-dashboard', 'app-dashboard', 'detail-page', 'single-entity']\n\n/**\n * CnDetailPage — Generic detail/overview page.\n *\n * Supports two layout modes:\n * 1. **Default (vertical stacking):** Content provided via default slot, cards stack vertically.\n * 2. **Grid layout:** When `layout` and `widgets` props are provided, content renders in a\n * 12-column CSS grid with `#widget-{widgetId}` scoped slots. Same API as CnDashboardPage.\n *\n * Basic usage (vertical stacking)\n *\n * A simpler alternative to CnIndexPage for pages that display detail info,\n * statistics, charts, or card grids — without multi-object tables or CRUD\n * dialogs. Provides a consistent layout with header, loading/error/empty\n * states, a statistics table, and flexible content slots.\n *\n * Basic usage with stats table and content\n * ```vue\n * <CnDetailPage\n * title=\"Register Overview\"\n * description=\"Statistics and schema details\"\n * icon=\"DatabaseOutline\"\n * :stats-title=\"'Register Statistics'\"\n * :stats-columns=\"[\n * { key: 'type', label: 'Type' },\n * { key: 'total', label: 'Total' },\n * { key: 'size', label: 'Size' },\n * ]\"\n * :stats-rows=\"[\n * { type: 'Objects', total: 150, size: '2.4 MB' },\n * { type: 'Files', total: 42, size: '1.1 MB' },\n * ]\"\n * :loading=\"isLoading\">\n * <ChartGrid :data=\"chartData\" />\n * <SchemaCards :schemas=\"schemas\" />\n * </CnDetailPage>\n * ```\n *\n * Grid layout mode\n * ```vue\n * <CnDetailPage\n * title=\"Character Detail\"\n * :layout=\"[\n * { id: 1, widgetId: 'info', gridX: 0, gridY: 0, gridWidth: 8 },\n * { id: 2, widgetId: 'stats', gridX: 8, gridY: 0, gridWidth: 4 },\n * ]\"\n * :widgets=\"[\n * { id: 'info', title: 'Character Info' },\n * { id: 'stats', title: 'Statistics' },\n * ]\">\n * <template #widget-info=\"{ item, widget }\">\n * <CharacterInfoCard :character=\"character\" />\n * </template>\n * <template #widget-stats=\"{ item, widget }\">\n * <StatsCard :stats=\"character.stats\" />\n * </template>\n * ```\n *\n * With header actions and error handling\n * ```vue\n * <CnDetailPage\n * title=\"Schema Details\"\n * :error=\"hasError\"\n * error-message=\"Failed to load schema\"\n * :on-retry=\"loadSchema\">\n * <template #actions>\n * <NcButton @click=\"editSchema\">Edit</NcButton>\n * </template>\n * <DetailContent :schema=\"schema\" />\n * </CnDetailPage>\n * ```\n */\nexport default {\n\tname: 'CnDetailPage',\n\n\tcomponents: {\n\t\tChevronLeft,\n\t\tChevronRight,\n\t\tNcActionButton,\n\t\tNcActionLink,\n\t\tNcActionSeparator,\n\t\tNcButton,\n\t\tNcEmptyContent,\n\t\tNcLoadingIcon,\n\t\tCnIcon,\n\t\tAlertCircleOutline,\n\t\tArrowLeft,\n\t\tFileQuestionOutline,\n\t\tInformationOutline,\n\t\tRefresh,\n\t\tCnActionsMenu,\n\t\tCnBuildiqEditButton,\n\t\tCnLockedBanner,\n\t\tCnDetailWidgetHost,\n\t\tCnFormDialog,\n\t\tCnDashboardGrid,\n\t\tCnLifecycleActions,\n\t\tCnActionButtons,\n\t\tCnSummaryAggregates,\n\t\tCnRelatedCollections,\n\t\tCnBodySections,\n\t\tCnTranslatedBadge,\n\t\tCnWidgetStyleEditorModal,\n\t\tCnRelationLinkModal,\n\t\tCog,\n\t\tPlus,\n\t\tPencil,\n\t},\n\n\tmixins: [gridLayout],\n\n\tinject: {\n\t\t/**\n\t\t * Consumer widget registry provided by CnAppRoot — the SAME injection\n\t\t * CnWidgetGrid reads. A consuming app registers its own components\n\t\t * here (hrmq registers `stat`, `chart`, `actions`,\n\t\t * `lifecycle-actions`, …), and per REQ-MVR-005 a consumer entry\n\t\t * OVERRIDES a built-in of the same name.\n\t\t *\n\t\t * Without this, a detail page could only render library widgets: an\n\t\t * app's own widget resolved on the CnWidgetGrid path and vanished on\n\t\t * this one, which is half of why the two paths disagreed.\n\t\t */\n\t\tcnRegistry: { default: () => ({}) },\n\t\tobjectSidebarState: { default: null },\n\t\t/**\n\t\t * Reactive AI context holder provided by CnAppRoot. This page\n\t\t * component writes pageKind, objectUuid, registerSlug, schemaSlug\n\t\t * in created() and watches for changes. Resets on beforeUnmount().\n\t\t */\n\t\tcnAiContext: { default: null },\n\t\t/**\n\t\t * Buildiq in-app edit state (ADR-041), a ref provided by CnAppRoot /\n\t\t * the edit button. When truthy, configurable grid widgets show a\n\t\t * configure cog. Defaults to null (no edit affordance) for standalone use.\n\t\t */\n\t\tcnEditingBody: { default: null },\n\t\t/**\n\t\t * Host translate function provided by CnAppRoot as\n\t\t * `cnTranslate: this.translate` (bound to the host app's id). The\n\t\t * manifest-authored page/section/widget titles are run through it.\n\t\t * Defaults to an identity function so an untranslated key renders\n\t\t * as itself. Record data (the resolved object's display name) is\n\t\t * NEVER translated — only manifest chrome is.\n\t\t */\n\t\tcnTranslate: { default: () => (key) => key },\n\t},\n\n\tprops: {\n\t\t/** Page title */\n\t\ttitle: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * NcDialog size for this page's create and edit form dialogs.\n\t\t *\n\t\t * CnFormDialog has taken a `size` since it shipped; this page never\n\t\t * passed one, so both its forms were stuck at `normal` however many\n\t\t * properties the schema declared.\n\t\t */\n\t\tformSize: {\n\t\t\ttype: String,\n\t\t\tdefault: 'normal',\n\t\t},\n\n\t\t/**\n\t\t * How many columns the create and edit forms flow their fields into.\n\t\t *\n\t\t * Pair `2` with `formSize: 'large'`, or the two columns are merely two\n\t\t * narrow ones. CnFormDialog collapses back to one column below 700px\n\t\t * on its own, so this is safe on a narrow viewport.\n\t\t */\n\t\tformColumns: {\n\t\t\ttype: Number,\n\t\t\tdefault: 1,\n\t\t\tvalidator: (value) => value === 1 || value === 2,\n\t\t},\n\n\t\t/**\n\t\t * Fields the create and edit forms ask for, in this order. Null asks for\n\t\t * every property the schema declares.\n\t\t *\n\t\t * Same three keys as CnIndexPage, so one manifest describes the record's\n\t\t * form wherever it opens rather than the list page and the detail page\n\t\t * each having their own.\n\t\t */\n\t\tincludeFields: {\n\t\t\ttype: Array,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Fields the create and edit forms never ask for. */\n\t\texcludeFields: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** Per-field widget / label overrides for the create and edit forms. */\n\t\tfieldOverrides: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/** Page description (shown below title) */\n\t\tdescription: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Optional MDI icon name (rendered via CnIcon) */\n\t\ticon: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Icon size in pixels */\n\t\ticonSize: {\n\t\t\ttype: Number,\n\t\t\tdefault: 28,\n\t\t},\n\n\t\t/** Whether the page is in a loading state */\n\t\tloading: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Message shown during loading */\n\t\tloadingLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Loading…'),\n\t\t},\n\n\t\t/**\n\t\t * Sidebar configuration. Accepts EITHER form:\n\t\t *\n\t\t * - **Boolean (legacy, deprecated):** `true` activates the\n\t\t * external sidebar, `false` deactivates. The first time this\n\t\t * form is observed per component instance a one-shot\n\t\t * `console.warn` is logged pointing at the migration path.\n\t\t * Continues to work in v1.x for back-compat.\n\t\t *\n\t\t * - **Object (preferred):** mirrors `CnIndexPage.sidebar` plus\n\t\t * the detail-specific fields previously on `sidebarProps`:\n\t\t * ```ts\n\t\t * {\n\t\t * show?: boolean, // default true; false suppresses sidebar\n\t\t * enabled?: boolean, // default true; false bypasses external sidebar\n\t\t * register?: string,\n\t\t * schema?: string,\n\t\t * hiddenTabs?: string[],\n\t\t * title?: string,\n\t\t * subtitle?: string,\n\t\t * tabs?: Array<TabDef>, // see manifest-abstract-sidebar\n\t\t * }\n\t\t * ```\n\t\t * When BOTH `sidebar` (Object) and `sidebarProps` are set\n\t\t * with overlapping fields, the Object form wins and a\n\t\t * `console.warn` lists the conflicting fields once per\n\t\t * component instance.\n\t\t *\n\t\t * @type {boolean | object}\n\t\t */\n\t\tsidebar: {\n\t\t\ttype: [Boolean, Object],\n\t\t\t// Object default (not Boolean `false`) so apps that omit the\n\t\t\t// prop don't trip the Boolean-form deprecation warning. Equivalent\n\t\t\t// to `false`: resolves to a suppressed/inactive sidebar.\n\t\t\tdefault: () => ({ enabled: false }),\n\t\t},\n\n\t\t/**\n\t\t * Initial open state of the object sidebar when it first activates.\n\t\t * Defaults to closed so the detail content fills the page; the user\n\t\t * opens it on demand via the header sidebar-toggle (and the sidebar's\n\t\t * own X closes it). After the first activation the open state is owned\n\t\t * by the shared `objectSidebarState` channel (toggle / close), so this\n\t\t * prop only seeds the initial value.\n\t\t */\n\t\tsidebarOpen: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** The registered object type slug for the sidebar */\n\t\tobjectType: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** The object ID to display in the sidebar */\n\t\tobjectId: {\n\t\t\ttype: [String, Number],\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Whether a schema-bound page without an object id shows an empty\n\t\t * CnFormDialog for its schema instead of a blank page.\n\t\t *\n\t\t * Set from the manifest as `config.createForm`:\n\t\t * - `'auto'` (default) — heuristic: only when the page is schema-bound,\n\t\t * has no object id, and supplies no body of its own (no default slot,\n\t\t * no grid layout). Existing behaviour.\n\t\t * - `'never'` — never render it. Use when the body owns data entry, e.g.\n\t\t * a page whose CnObjectDataWidget (or a registry component) already\n\t\t * provides the form; this is what stops two form dialogs stacking.\n\t\t * - `'always'` — render it even when the page has a body, for a page\n\t\t * that deliberately pairs custom content with a create form.\n\t\t *\n\t\t * The dialog itself is always the generic, schema-driven CnFormDialog, so\n\t\t * whichever way it is summoned it follows the same OpenRegister/schema\n\t\t * form rules (required, readOnly, enum/$ref, `visibleWhen`).\n\t\t *\n\t\t * @type {'auto'|'never'|'always'}\n\t\t */\n\t\tcreateForm: {\n\t\t\ttype: String,\n\t\t\tdefault: 'auto',\n\t\t\tvalidator: (value) => ['auto', 'never', 'always'].includes(value),\n\t\t},\n\n\t\t/** Subtitle shown in the sidebar header */\n\t\tsubtitle: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Additional sidebar configuration (register, schema, hiddenTabs, title, subtitle) */\n\t\tsidebarProps: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/**\n\t\t * Rendering surface forwarded to integration widgets in the\n\t\t * grid layout (widget defs with `type === 'integration'`).\n\t\t * Drives the AD-19 surface fallback. Defaults to\n\t\t * `'detail-page'` — the surface this page represents.\n\t\t *\n\t\t * @type {'user-dashboard'|'app-dashboard'|'detail-page'|'single-entity'}\n\t\t */\n\t\tsurface: {\n\t\t\ttype: String,\n\t\t\tdefault: 'detail-page',\n\t\t\tvalidator: (value) => INTEGRATION_SURFACES.includes(value),\n\t\t},\n\n\t\t/**\n\t\t * Object context forwarded to integration widgets:\n\t\t * `{ register, schema, objectId }`. When omitted it is derived\n\t\t * from `sidebarProps.register` / `sidebarProps.schema` (or\n\t\t * `objectType`) and `objectId`, so `CnFilesCard` etc. can\n\t\t * fetch the right object's sub-resources without extra wiring.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tintegrationContext: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Whether the page is in an error state */\n\t\terror: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Error message shown in error state */\n\t\terrorMessage: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'An error occurred'),\n\t\t},\n\n\t\t/** Callback for retry button in error state. If null, no retry button is shown. */\n\t\tonRetry: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Label for the retry button */\n\t\tretryLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Retry'),\n\t\t},\n\n\t\t/**\n\t\t * Router location the not-found state's button opens, shown when the\n\t\t * schema-driven fetch answers 404. Usually the record's list; null\n\t\t * sends the user to the app's root (`/`). CnPageRenderer fills it with\n\t\t * the index page the record was opened from.\n\t\t */\n\t\tnotFoundRoute: {\n\t\t\ttype: [Object, String],\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Name of the `notFoundRoute` page, used in the button's \"Back to …\" label. */\n\t\tnotFoundRouteLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Whether the page has no data to show */\n\t\tempty: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Message shown when page is empty */\n\t\temptyLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'No data available'),\n\t\t},\n\n\t\t/** Title shown above the statistics table */\n\t\tstatsTitle: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Column definitions for the statistics table.\n\t\t * Each column: `{ key: string, label: string, align?: 'left'|'center'|'right' }`\n\t\t *\n\t\t * @type {Array<{ key: string, label: string, align: string }>}\n\t\t */\n\t\tstatsColumns: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * Row data for the statistics table. Each row is an object keyed by\n\t\t * column keys. Set `indent: true` on a row for sub-row styling.\n\t\t *\n\t\t * @type {Array<object>}\n\t\t */\n\t\tstatsRows: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** Maximum width of the page content */\n\t\tmaxWidth: {\n\t\t\ttype: String,\n\t\t\tdefault: '1800px',\n\t\t},\n\n\t\t/**\n\t\t * Responsive `columnOpts` for the body grid, measured against the GRID's own\n\t\t * width rather than the window's — so a page rendered in a narrow container\n\t\t * (a split pane beside a list) reflows even though the viewport is wide.\n\t\t * Defaults to a table that stacks to one column at or below 1000px. Pass\n\t\t * `null` for a fixed 12-column grid at every size.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tcolumnOpts: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({ ...DEFAULT_DETAIL_COLUMN_OPTS }),\n\t\t},\n\n\t\t/**\n\t\t * Whether to auto-subscribe to live updates for this object.\n\t\t * Defaults to true. The page calls\n\t\t * `store.subscribe(type, objectId)` on mount and unsubscribes on\n\t\t * unmount, against the explicit `objectStore` prop when passed,\n\t\t * else (schema-driven / manifest mode: `register` + `schema` set)\n\t\t * against the library's default `useObjectStore()`. Set `false`\n\t\t * (manifest: `config.subscribe: false`) for read-only / archive\n\t\t * views.\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\tsubscribe: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Whether the schema-driven auto-body renders the related-objects widget\n\t\t * beneath the data widget. Defaults to true (back-compat). Set false on a\n\t\t * page that surfaces relations elsewhere (e.g. in the sidebar) to drop the\n\t\t * \"Related\" section from the body.\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\tshowRelatedObjects: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Optional explicit Pinia store instance to subscribe / lock\n\t\t * against; always wins when passed. When omitted, a page in\n\t\t * schema-driven mode (`register` + `schema` — the manifest\n\t\t * renderer path) falls back to the library's default\n\t\t * `useObjectStore()` so auto-subscribe still engages; the\n\t\t * resolution is defensive so consumer apps that haven't\n\t\t * activated Pinia yet (e.g. tests) don't crash.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tobjectStore: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * OpenRegister register slug. Pair with `schema` to opt into the\n\t\t * schema-driven mode: the page fuses the two into an internal\n\t\t * `${register}-${schema}` object-type slug, registers it on the\n\t\t * store, fetches the object identified by `objectId`, and auto-\n\t\t * renders `CnObjectDataWidget` + `CnObjectMetadataWidget` when no\n\t\t * default-slot content is supplied. Compatible with the existing\n\t\t * `objectType` prop — `objectType` wins on collision, so legacy\n\t\t * direct mounts are unaffected.\n\t\t *\n\t\t * @type {string}\n\t\t */\n\t\tregister: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * OpenRegister schema slug. See `register` for the schema-driven\n\t\t * contract.\n\t\t *\n\t\t * @type {string}\n\t\t */\n\t\tschema: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Hide valueless fields on the auto-rendered data widget, instead of\n\t\t * showing them with an em dash. See `CnObjectDataWidget`'s `hide-empty`.\n\t\t *\n\t\t * Set this from the manifest (`config.hideEmpty`) for a discriminated\n\t\t * supertype — one schema holding several variants, where each object only\n\t\t * carries the fields its variant uses. A widget that declares its own\n\t\t * `content.hideEmpty` still wins over this page-level default.\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\thideEmpty: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Tab definitions forwarded to the host App's `CnObjectSidebar`\n\t\t * via the injected `objectSidebarState`. Each entry follows the\n\t\t * `CnObjectSidebar` tab shape (see that component for the exact\n\t\t * fields). When empty (default) the sidebar falls back to its\n\t\t * own default tab set. The actual `<CnObjectSidebar>` is rendered\n\t\t * at `NcContent` level by `CnAppRoot` (ADR-017 — external sidebar\n\t\t * pattern); this page only publishes the tabs.\n\t\t *\n\t\t * @type {Array<object>}\n\t\t */\n\t\tsidebarTabs: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * Documentation link surfaced in the page-header Actions menu. When\n\t\t * set, the menu renders a \"Documentation\" entry that opens this URL\n\t\t * in a new tab. The Refresh and Request-a-feature entries render by\n\t\t * default regardless of this value.\n\t\t */\n\t\tdocumentationUrl: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Label for the Documentation entry in the header menu. */\n\t\tdocumentationLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Stable id for the page-header Actions menu — forwarded as the\n\t\t * `widgetId` on the `@refresh` / `cn:page:refresh` payloads and as\n\t\t * the `surface: \"detail:<pageId>\"` on the feature-request modal.\n\t\t * Falls back to a slugified title when empty.\n\t\t */\n\t\tpageId: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Whether the Refresh entry renders in the page-header menu.\n\t\t * Tri-state:\n\t\t * - `true` / `false` — force it on or off.\n\t\t * - `null` (the default) — **auto**: show Refresh only when it will\n\t\t * do something, i.e. a consumer attached an `@refresh` listener OR\n\t\t * the page is in schema-driven mode (`register` + `schema` +\n\t\t * `objectId`) and can self-fetch. Legacy `objectType`-mode detail\n\t\t * pages that never wire `@refresh` therefore show no dead button.\n\t\t *\n\t\t * @type {boolean|null}\n\t\t */\n\t\tshowRefresh: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Show an Edit button in the header that opens the record's schema\n\t\t * form. Needs `register` + `schema` + `objectId` to have something to\n\t\t * edit; without them the button stays hidden however this is set.\n\t\t *\n\t\t * `CnPageRenderer` turns this on for every schema-bound `type:\"detail\"`\n\t\t * page, which is the same set of pages whose index tables stop offering\n\t\t * an edit modal — the two are one rule, and shipping either half alone\n\t\t * would leave records with two edit surfaces or none.\n\t\t */\n\t\tshowEditAction: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Label for the header Edit button. Defaults to a translated \"Edit\". */\n\t\teditLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Whether a header refresh is in flight. Disables the Refresh entry\n\t\t * and swaps its icon for a spinner. Wire this to the same flag the\n\t\t * host toggles around its `@refresh` handler.\n\t\t */\n\t\trefreshing: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Whether the Request-a-feature entry renders in the page-header menu. */\n\t\tshowRequestFeature: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Whether the \"Report a bug\" entry renders in the page-header menu.\n\t\t * On by default — the trio Request a feature / Report a bug /\n\t\t * Documentation is the contract for every Conduction surface.\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\tshowReportBug: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Whether the Documentation entry renders in the page-header menu. On\n\t\t * by default; the shared menu resolves the target itself, so leaving\n\t\t * it on costs the host nothing.\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\tshowDocumentation: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Declarative lifecycle/transition actions (manifest `config.lifecycleActions`).\n\t\t * When set, renders status-gated transition buttons in the page header driven\n\t\t * by the object's `x-openregister-lifecycle`. Shape:\n\t\t * `{ field?: 'status', transitions?: [{ from, to, action, label, confirm?, variant? }], autoFetch?: boolean }`.\n\t\t * With just `{ field: 'status' }` the allowed transitions are fetched live from\n\t\t * OpenRegister's `/available-actions` endpoint (server-authoritative). An\n\t\t * explicit `transitions` array is filtered client-side by the object's current\n\t\t * state. Omit (default `null`) to keep the current behaviour (no transition\n\t\t * buttons). See `CnLifecycleActions`.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tlifecycleActions: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Declarative header actions (manifest `config.headerActions`, #91\n\t\t * Wave 3) rendered as items in the header's Actions menu via\n\t\t * CnActionButtons — `api-call` (POST/PUT + toast + refresh),\n\t\t * `open-form`, `toggle`, `navigate` / `open-modal`, each with an\n\t\t * optional `visibleWhen` predicate. Distinct from `lifecycleActions`\n\t\t * (state-machine transitions): these are free-form record actions\n\t\t * (approve, send, archive). The page's object context drives\n\t\t * `@objectId` / `@object.<field>` token + local-predicate resolution.\n\t\t * Empty (the default) renders nothing.\n\t\t *\n\t\t * The menu, not a row of buttons: that is what the manifest schema has\n\t\t * always said this key is, and what CnIndexPage already does with it.\n\t\t * The two surfaces had drifted, and on a dossiq case — twelve actions —\n\t\t * the button row squeezed the record's own title to a truncated stub.\n\t\t * Edit stays a button because it is the one action a handler reaches\n\t\t * for on nearly every visit.\n\t\t *\n\t\t * @type {Array<object>}\n\t\t */\n\t\theaderActions: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * Set to fold this page's own Edit button in with the header actions,\n\t\t * so it becomes an entry in the Actions menu instead of a button\n\t\t * standing beside it. `null` (the default) keeps Edit standalone, so\n\t\t * every existing consumer's header is unchanged.\n\t\t *\n\t\t * The number itself no longer caps anything HERE: this page draws its\n\t\t * header actions as Actions-menu entries (`display: \"menu\"`), where\n\t\t * there are no buttons to cap. It is still CnActionButtons' `inline`\n\t\t * count for a host that mounts that component in `buttons` mode — see\n\t\t * that component's `inline` prop.\n\t\t *\n\t\t * @type {number|null}\n\t\t */\n\t\tinlineActions: {\n\t\t\ttype: Number,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Declarative related-object list sections (manifest\n\t\t * `config.relatedCollections`). Each entry renders a titled\n\t\t * `CnObjectListWidget` below the detail body, filtered to this object via\n\t\t * `@objectId` / `@object.<field>` tokens. Shape per entry:\n\t\t * `{ title?, register, schema, filter?, columns?, sort?, limit?, rowRoute? }`.\n\t\t * Empty / omitted (default `[]`) renders nothing. See `CnRelatedCollections`.\n\t\t *\n\t\t * @type {Array<object>}\n\t\t */\n\t\trelatedCollections: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * Declarative cross-schema summary chips (manifest\n\t\t * `config.summaryAggregates`). Each entry runs ONE count/sum/avg over a\n\t\t * related schema scoped to this object and shows it as a stat chip in the\n\t\t * header. Shape per entry:\n\t\t * `{ label, register, schema, metric?, field?, filter?, format? }`.\n\t\t * Empty / omitted (default `[]`) renders nothing. See `CnSummaryAggregates`.\n\t\t *\n\t\t * @type {Array<object>}\n\t\t */\n\t\tsummaryAggregates: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * Declarative relation-link actions (manifest `config.relationLinks`).\n\t\t * Each entry renders a button that opens a search-and-link modal which\n\t\t * patches a foreign-key field on THIS object with the chosen object's id.\n\t\t * Shape per entry:\n\t\t * `{ label?, register, schema, fkField, labelField?, allowCreate?, title?, selectLabel? }`.\n\t\t * Empty / omitted (default `[]`) renders nothing.\n\t\t *\n\t\t * @type {Array<object>}\n\t\t */\n\t\trelationLinks: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * Declarative IN-BODY sections (manifest `config.bodyWidgets`). Each\n\t\t * entry renders a REGISTERED host-app component as a titled section in\n\t\t * the page BODY (not the sidebar), with the object/page context injected.\n\t\t * This is the primitive that lets a rich bespoke detail page (BRP panels,\n\t\t * activity timelines, comms history, relationship graphs, bookings, …)\n\t\t * become declarative while keeping its sections in the body. Shape per\n\t\t * entry:\n\t\t * `{ id?, component, title?, props?, placement?, colSpan? }`.\n\t\t * - `component` — registry name resolved from the app's v2 `registry`\n\t\t * (any `kind` exposing a `.component`, e.g. `kind:\"section\"` or\n\t\t * `kind:\"widget\"`) or the legacy `customComponents` map. NO sidebar\n\t\t * tab is required (unlike integration widgets).\n\t\t * - `props` — values are token-resolved: `@objectId` → this object's id,\n\t\t * `@object.<field>` → a field off it, `@workspace.<key>` → page\n\t\t * context; unset `@…?` optional / unresolved tokens are dropped.\n\t\t * - `placement` — `before-body` | `after-data` | `after-related` | `end`\n\t\t * (default `end`). Controls where in the body the section lands.\n\t\t * - `colSpan` — 1–12 grid span when sections share a placement.\n\t\t * The loaded object + objectId are also `provide`d on `cnSectionContext`\n\t\t * so a host component can inject them instead of taking explicit props.\n\t\t * Empty / omitted (default `[]`) renders nothing. See `CnBodySections`.\n\t\t *\n\t\t * @type {Array<{id?: string, component: string, title?: string, props?: object, placement?: string, colSpan?: number}>}\n\t\t */\n\t\tbodyWidgets: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * Vue-router route NAME to navigate to after a create-form save (the\n\t\t * create archetype: a `type:\"detail\"` page whose route carries no `:id`).\n\t\t * The created object's id is passed as the `id` route param. When empty\n\t\t * (the default) the page navigates back in history after a successful\n\t\t * create instead. See `isCreateMode`.\n\t\t *\n\t\t * @type {string}\n\t\t */\n\t\tcreateRoute: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Page-level app config map exposed to declarative widget / section\n\t\t * config via the `@config.<key>` token (e.g. the reporting `currency`\n\t\t * the setup wizard captures). Provided to descendants on `cnAppConfig`,\n\t\t * so a stat widget's `format: { style: 'currency', currency:\n\t\t * '@config.currency' }` formats with the configured value (falling back\n\t\t * to the literal default when unset). A manifest renderer typically seeds\n\t\t * this from `loadState(appId, 'config', {})`. Empty (default) leaves every\n\t\t * `@config.<key>` token to fall back to its literal default.\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tappConfig: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/**\n\t\t * Next and previous within the list this record was opened from, as\n\t\t * returned by `useListNavigation`. Omit it and neither control\n\t\t * renders, which is what a record reached by a bare link must do:\n\t\t * stepping through an order the reader never chose is worse than\n\t\t * offering no step at all.\n\t\t *\n\t\t * @type {{ available: boolean, isFirst: boolean, isLast: boolean, position: number, total: number }}\n\t\t */\n\t\tlistNavigation: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Router location of the previous record, as `useListNavigation`'s\n\t\t * `previousRoute`. When set, the previous control is a real link\n\t\t * (middle-click, open in new tab) and `previous-record` is emitted\n\t\t * with `{ event, to }` after it navigated. Null keeps it a button.\n\t\t *\n\t\t * @type {object|string|null}\n\t\t */\n\t\tpreviousTo: {\n\t\t\ttype: [Object, String],\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Router location of the next record, as `useListNavigation`'s\n\t\t * `nextRoute`. Same behaviour as `previousTo`.\n\t\t *\n\t\t * @type {object|string|null}\n\t\t */\n\t\tnextTo: {\n\t\t\ttype: [Object, String],\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * The page's primary action, as declared on its manifest page. Renders\n\t\t * as the header's primary button and is the target the skip link\n\t\t * lands on. Omit it and neither renders.\n\t\t *\n\t\t * @type {{ id?: string, label: string, icon?: string, route?: string, href?: string }}\n\t\t */\n\t\tprimaryAction: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Puts the active tab in the address as `?_tab=<id>`, so a link points\n\t\t * at a tab of this record rather than at the record. Off by default,\n\t\t * which leaves the address exactly as it is today.\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\ttabInAddress: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t},\n\n\temits: [\n\t\t'create-cancel',\n\t\t'created',\n\t\t'edited',\n\t\t'geo-saved',\n\t\t'layout-change',\n\t\t'open-integration',\n\t\t'refresh',\n\t\t'related-row-click',\n\t\t'relation-linked',\n\t\t'request-feature',\n\t\t'transitioned',\n\t\t'update:layout',\n\t\t'widget-config-change',\n\t\t/**\n\t\t * The reader asked for the next record of the list this one was\n\t\t * opened from. The host steps, because the host owns the router.\n\t\t * With `nextTo` set the link has navigated already and the payload\n\t\t * is `{ event, to }`.\n\t\t */\n\t\t'next-record',\n\t\t/** The reader asked for the previous record of that same list. Payload as `next-record`. */\n\t\t'previous-record',\n\t\t/** The page's declared primary action was pressed. Payload is the declaration. */\n\t\t'primary-action',\n\t\t/**\n\t\t * The active tab changed. Payload is the tab id. Emitted whether or\n\t\t * not `tabInAddress` is set, so a host may mirror it somewhere else.\n\t\t */\n\t\t'tab-change',\n\t],\n\n\tsetup(props) {\n\t\t// Pluggable integration registry — used to resolve `type:\n\t\t// 'integration'` widgets in the grid layout to their Vue\n\t\t// component (AD-19 surface fallback). Always wired; cheap when\n\t\t// no integration widgets are configured.\n\t\tconst { resolveWidget, getById } = useIntegrationRegistry()\n\t\tconst registryExposed = { resolveRegistryWidget: resolveWidget, getRegistryProvider: getById }\n\n\t\t// The host reads presence because only the host can act on it: the grid\n\t\t// reserves the row before the widget renders. See `layoutItemCanDraw`.\n\t\t// A getter, not a one-shot read: a page whose widgets arrive after mount\n\t\t// would otherwise never subscribe, and `layoutItemCanDraw` would drop the\n\t\t// presence row for good instead of until somebody arrives.\n\t\tconst presencePlaced = () => (props.widgets || []).some((w) => w && w.type === 'presence')\n\t\tconst { others: presentOthers } = useObjectPresence(\n\t\t\t() => props.register || '',\n\t\t\t() => props.schema || '',\n\t\t\t() => String(props.objectId || ''),\n\t\t\t{ enabled: presencePlaced },\n\t\t)\n\t\tregistryExposed.presentOthers = presentOthers\n\n\t\t// Object context for detail-page abstract widgets (ADR-041): a reactive\n\t\t// `{ objectId, object, register, schema }` holder kept current by the\n\t\t// Options watcher below. Provided so CnObjectListWidget / CnStatWidget\n\t\t// can resolve `@objectId` / `@object.<field>` filter tokens and scope\n\t\t// their query to the object on this page. Null fields until loaded.\n\t\tconst cnObjectContext = ref({ objectId: props.objectId || null, object: null, register: props.register || '', schema: props.schema || '' })\n\t\tprovide('cnObjectContext', cnObjectContext)\n\t\tregistryExposed.cnObjectContextRef = cnObjectContext\n\n\t\t// Page-level APP CONFIG exposed to declarative widget / section config via\n\t\t// the `@config.<key>` token (e.g. the reporting currency the setup wizard\n\t\t// captures). Provided so CnStatWidget / CnBodySections can format with the\n\t\t// configured value. Kept in sync with the `appConfig` prop.\n\t\tconst cnAppConfig = ref({ ...(props.appConfig || {}) })\n\t\tprovide('cnAppConfig', cnAppConfig)\n\t\tregistryExposed.cnAppConfigRef = cnAppConfig\n\t\twatch(\n\t\t\t() => props.appConfig,\n\t\t\t(next) => {\n\t\t\t\tcnAppConfig.value = { ...(next || {}) }\n\t\t\t},\n\t\t\t{ deep: true },\n\t\t)\n\n\t\t// Auto-subscribe + reactive lock state for the current object.\n\t\t// Both are no-ops when no store resolves (no Pinia active), when\n\t\t// subscribe is false (read-only / archive views), or when\n\t\t// objectType / objectId aren't yet known. Using composables in\n\t\t// setup() keeps the lifecycle bound to the component scope —\n\t\t// `tryOnScopeDispose` releases the subscription on unmount.\n\t\t//\n\t\t// Store resolution (manifest-live-updates): an explicit\n\t\t// `objectStore` prop always wins (existing behaviour, unchanged\n\t\t// for apps that pass their own store). In schema-driven mode —\n\t\t// `register` + `schema` set, the manifest renderer path — fall\n\t\t// back to the library's default store, the same one the\n\t\t// schema-driven fetch (`effectiveObjectStore`) uses, so\n\t\t// manifest-rendered detail pages auto-subscribe with zero\n\t\t// app-side wiring. Legacy `objectType`-only mounts without an\n\t\t// explicit store keep today's behaviour (no subscription).\n\t\tlet subscriptionStore = props.objectStore\n\t\tif (!subscriptionStore && props.subscribe && props.register && props.schema) {\n\t\t\ttry {\n\t\t\t\tsubscriptionStore = useObjectStore()\n\t\t\t} catch {\n\t\t\t\t// Pinia not active (stand-alone test mounts) — no live updates.\n\t\t\t\tsubscriptionStore = null\n\t\t\t}\n\t\t\tif (subscriptionStore) {\n\t\t\t\t// Register the EFFECTIVE type slug synchronously — the same\n\t\t\t\t// slug `resolveType()`/`resolvedObjectType` yields (an explicit\n\t\t\t\t// `objectType` prop wins; note the manifest renderer aliases\n\t\t\t\t// `config.schema` → `objectType`), with the same idempotence\n\t\t\t\t// guard as fetchObjectIfNeeded (which therefore skips its own\n\t\t\t\t// registration). This ensures the subscription's mount-time\n\t\t\t\t// subscribe() never races the mounted() fetch path into a\n\t\t\t\t// \"type not registered\" rejection.\n\t\t\t\tconst effectiveType = props.objectType || `${props.register}-${props.schema}`\n\t\t\t\tif (typeof subscriptionStore.registerObjectType === 'function'\n\t\t\t\t\t&& !subscriptionStore.objectTypeRegistry?.[effectiveType]) {\n\t\t\t\t\tsubscriptionStore.registerObjectType(\n\t\t\t\t\t\teffectiveType,\n\t\t\t\t\t\tprops.schema,\n\t\t\t\t\t\tprops.register,\n\t\t\t\t\t\t{ registerSlug: props.register, schemaSlug: props.schema },\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (!subscriptionStore || !props.subscribe) {\n\t\t\treturn { ...registryExposed, lockState: null }\n\t\t}\n\t\t// Resolve the effective object-type slug the same way `computed.resolvedObjectType`\n\t\t// does — the explicit `objectType` prop wins, else fuse `register` + `schema`.\n\t\t// The composables take getter functions so the resolution stays reactive when\n\t\t// `register` / `schema` / `objectType` change at runtime.\n\t\tconst resolveType = () => props.objectType || (props.register && props.schema ? `${props.register}-${props.schema}` : '')\n\t\tconst subscription = useObjectSubscription(\n\t\t\tsubscriptionStore,\n\t\t\tresolveType,\n\t\t\t() => props.objectId,\n\t\t\t{ enabled: () => Boolean(resolveType() && props.objectId) },\n\t\t)\n\t\tconst sidebarReg = props.sidebarProps?.register || props.resolvedSidebar?.register || props.register || ''\n\t\tconst sidebarSchema = props.sidebarProps?.schema || props.resolvedSidebar?.schema || props.schema || ''\n\t\tconst lock = useObjectLock(\n\t\t\tsubscriptionStore,\n\t\t\t() => sidebarReg,\n\t\t\t() => resolveType() || sidebarSchema,\n\t\t\t() => props.objectId,\n\t\t\t// The third argument is the OBJECT CACHE KEY (`<register>-<schema>`)\n\t\t\t// and the lock URL needs the schema SLUG. They were one string, and\n\t\t\t// the acquire went to `/api/objects/<register>/<register>-<schema>/`,\n\t\t\t// which no register answers.\n\t\t\t{ schemaSlug: () => props.schema || sidebarSchema },\n\t\t)\n\t\treturn {\n\t\t\t...registryExposed,\n\t\t\tsubscriptionStatus: subscription.status,\n\t\t\tlockState: lock,\n\t\t}\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\t/** Whether the record edit form is open. */\n\t\t\teditFormOpen: false,\n\t\t\t/**\n\t\t\t * The sentence a refused lock left behind, shown in place of the\n\t\t\t * form. Empty whenever the form opened.\n\t\t\t */\n\t\t\teditLockRefusal: '',\n\t\t\t/**\n\t\t\t * Whether a lock release is in flight, so the locked card's Unlock\n\t\t\t * button can disable itself for the round trip. Without it a slow\n\t\t\t * release invites a second click, and the second `release()` lands\n\t\t\t * on a lock that is already gone.\n\t\t\t */\n\t\t\treleasingLock: false,\n\t\t\t/**\n\t\t\t * The manifest `headerActions[]` flattened into menu items by the\n\t\t\t * `display: \"menu\"` CnActionButtons instance, which keeps owning\n\t\t\t * their dialogs. Each carries its own pre-bound `run()`, so the\n\t\t\t * menu dispatches without reaching back into that component.\n\t\t\t */\n\t\t\tmenuHeaderActions: [],\n\t\t\t/** Lifecycle transitions CnLifecycleActions hands the Actions menu. */\n\t\t\tlifecycleMenuEntries: [],\n\t\t\t/** Whether the per-widget style/config editor modal is open. */\n\t\t\tshowWidgetConfig: false,\n\t\t\t/** The widgetId currently being configured via the cog. */\n\t\t\tconfigWidgetId: null,\n\t\t\t/**\n\t\t\t * Whether the object sidebar has been seeded with its initial open\n\t\t\t * state for the current activation. Gates the one-shot `sidebarOpen`\n\t\t\t * seed in `syncSidebarState` so user close/toggle is not clobbered.\n\t\t\t */\n\t\t\tsidebarSeeded: false,\n\t\t\t/** The relation-link descriptor whose modal is currently open (or null). */\n\t\t\tactiveRelationLink: null,\n\t\t\t/**\n\t\t\t * Materialized default body grid for the schema-driven auto-body (Data +\n\t\t\t * Related). Lazily built by `materializeAutoBody()` the first time the\n\t\t\t * object resolves so the detail body is a real, mutable GridStack grid\n\t\t\t * (drag / resize / configure) rather than a static stack. `null` until\n\t\t\t * materialized; reset when the schema-driven context changes.\n\t\t\t */\n\t\t\tautoBodyLayout: null,\n\t\t\t/** Widget definitions paired with `autoBodyLayout` (id ↔ widgetId). */\n\t\t\tautoBodyWidgets: null,\n\t\t\t/**\n\t\t\t * True when `materializeAutoBody()` dropped the Data widget only\n\t\t\t * because the schema had not arrived yet — the object won the race\n\t\t\t * against `fetchSchema`. The `currentSchema` watcher re-materializes\n\t\t\t * once on that signal, which is what stops a lost race from\n\t\t\t * permanently hiding every scalar field (shillinq#1073).\n\t\t\t *\n\t\t\t * A flag rather than an \"is the widget missing?\" test, so a body the\n\t\t\t * user has edited is never rewritten underneath them.\n\t\t\t */\n\t\t\tdataWidgetDeferred: false,\n\t\t\t/**\n\t\t\t * Drives the Actions-menu Refresh spinner during a schema-driven\n\t\t\t * self-fetch refresh, where the host has no promise to bind\n\t\t\t * `:refreshing` to. Mirrors CnIndexPage.internalRefreshing.\n\t\t\t */\n\t\t\tinternalRefreshing: false,\n\t\t\t/**\n\t\t\t * Whether a load has completed at least once. Gates the\n\t\t\t * full-page loading state to the FIRST load only: once content\n\t\t\t * has been shown, later loads (refresh, re-fetch) stay in place\n\t\t\t * and surface as the action-button spinner instead of blanking\n\t\t\t * the page. Set true the first time `loading` falls to false.\n\t\t\t */\n\t\t\thasLoadedOnce: false,\n\t\t\t/**\n\t\t\t * Whether the schema-driven object fetch is in flight. Starts true\n\t\t\t * so the immediate sidebar sync at creation already waits for it.\n\t\t\t */\n\t\t\tobjectFetchPending: Boolean(this.register && this.schema && this.objectId),\n\t\t\t/** Whether the schema-driven fetch answered 404 for `objectId`. */\n\t\t\tobjectNotFound: false,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t// ── The record as a place (case-page-and-list-as-a-place) ───────\n\n\t\t/**\n\t\t * The primary action's label, run through the host's translate\n\t\t * function. Empty when the page declares no primary action, which is\n\t\t * what gates both the button and the skip link.\n\t\t *\n\t\t * @return {string} The label, or an empty string.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tprimaryActionLabel() {\n\t\t\tconst label = this.primaryAction?.label\n\t\t\treturn typeof label === 'string' && label !== '' ? this.effectiveTranslate(label) : ''\n\t\t},\n\n\t\t/**\n\t\t * The id the skip link's anchor points at.\n\t\t *\n\t\t * Namespaced by the page so two detail pages in one document, which\n\t\t * the split view makes possible, cannot both answer to `#primary`.\n\t\t *\n\t\t * @return {string} The element id.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tprimaryActionAnchorId() {\n\t\t\tconst scope = this.primaryAction?.id || this.pageId || this.objectId || 'record'\n\t\t\treturn `cn-primary-action-${String(scope).replace(/[^A-Za-z0-9_-]/g, '-')}`\n\t\t},\n\n\t\t/**\n\t\t * What the skip link says.\n\t\t *\n\t\t * It names the action rather than saying \"skip to main content\",\n\t\t * because a keyboard user who cannot see the page needs to know what\n\t\t * they are being offered before they take it.\n\t\t *\n\t\t * @return {string} The link text.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tskipLinkLabel() {\n\t\t\treturn `${this.effectiveTranslate('Skip to')} ${this.primaryActionLabel}`\n\t\t},\n\n\t\t/**\n\t\t * Where this record sits in the list it was opened from, as text.\n\t\t *\n\t\t * @return {string} For example \"4 of 40\".\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tlistPositionLabel() {\n\t\t\tconst nav = this.listNavigation\n\t\t\tif (!nav || !nav.total) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn `${nav.position} ${this.effectiveTranslate('of')} ${nav.total}`\n\t\t},\n\n\t\t/**\n\t\t * Accessible name for the previous control, which says what list it\n\t\t * steps through rather than only which direction it goes.\n\t\t *\n\t\t * @return {string} The label.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tpreviousRecordLabel() {\n\t\t\treturn this.listNavigation?.isFirst\n\t\t\t\t? this.effectiveTranslate('This is the first record in the list')\n\t\t\t\t: this.effectiveTranslate('Previous record in the list')\n\t\t},\n\n\t\t/**\n\t\t * Accessible name for the next control.\n\t\t *\n\t\t * @return {string} The label.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tnextRecordLabel() {\n\t\t\treturn this.listNavigation?.isLast\n\t\t\t\t? this.effectiveTranslate('This is the last record in the list')\n\t\t\t\t: this.effectiveTranslate('Next record in the list')\n\t\t},\n\n\t\t/**\n\t\t * Stable id for the page-header Actions menu. Prefers the explicit\n\t\t * `pageId` prop; falls back to a slugified `title` so the menu still\n\t\t * gets a usable id / surface.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\t/**\n\t\t * Whether the page is in Buildiq edit mode — unwraps the injected\n\t\t * `cnEditingBody` ref (or plain boolean). Drives the per-widget cog.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\teditingBody() {\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 * The widget definition currently being configured, shaped for\n\t\t * `CnWidgetStyleEditorModal` (carries `id`, `type`, `title`, `content`).\n\t\t *\n\t\t * @return {object|null}\n\t\t */\n\t\tconfigWidget() {\n\t\t\tif (!this.configWidgetId) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst def = this.bodyGridWidgets.find((w) => w.id === this.configWidgetId)\n\t\t\treturn def || null\n\t\t},\n\n\t\tresolvedPageId() {\n\t\t\tif (this.pageId) {\n\t\t\t\treturn this.pageId\n\t\t\t}\n\t\t\treturn String(this.title || '').toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '')\n\t\t},\n\n\t\t/**\n\t\t * Whether to show the full-page loading state (spinner that replaces\n\t\t * the page content). Only on the FIRST load — when `loading` is true\n\t\t * and nothing has been shown yet. Once `hasLoadedOnce` is set, a\n\t\t * subsequent `loading` (refresh / re-fetch) keeps the existing\n\t\t * content in place; the action-button spinner signals the refresh\n\t\t * instead (see `effectiveRefreshing`).\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tshowLoadingState() {\n\t\t\treturn (this.loading && !this.hasLoadedOnce) || this.awaitingObject\n\t\t},\n\n\t\t/**\n\t\t * Whether the page is still waiting for its first answer on the record.\n\t\t * The body, lifecycle menu and sidebar stay unmounted meanwhile, because\n\t\t * each of them requests endpoints scoped to the id and a missing record\n\t\t * would turn every one of those into a 404 or 500.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tawaitingObject() {\n\t\t\treturn this.hasSchemaDrivenFetch\n\t\t\t\t&& this.objectFetchPending\n\t\t\t\t&& typeof this.effectiveObjectStore?.fetchObject === 'function'\n\t\t\t\t&& !this.currentObject\n\t\t},\n\n\t\t/**\n\t\t * Where the not-found state's button goes: `notFoundRoute`, or the app's\n\t\t * root when the host names no list to return to.\n\t\t *\n\t\t * @return {object|string}\n\t\t */\n\t\tnotFoundTarget() {\n\t\t\treturn this.notFoundRoute || { path: '/' }\n\t\t},\n\n\t\t/** Heading and description of the not-found state. */\n\t\tnotFoundLabels() {\n\t\t\treturn {\n\t\t\t\tname: t('nextcloud-vue', 'Not found'),\n\t\t\t\tdescription: t('nextcloud-vue', 'This item does not exist or has been deleted.'),\n\t\t\t}\n\t\t},\n\n\t\t/** Label of the not-found state's button, unescaped because `{{ }}` escapes. */\n\t\tnotFoundButtonLabel() {\n\t\t\treturn this.notFoundRoute && this.notFoundRouteLabel\n\t\t\t\t? t('nextcloud-vue', 'Back to {page}', { page: this.notFoundRouteLabel }, undefined, { escape: false })\n\t\t\t\t: t('nextcloud-vue', 'Back to home')\n\t\t},\n\n\t\t/**\n\t\t * Refresh-spinner flag for the page-header Actions menu. True when:\n\t\t * an explicit `refreshing` prop is set; OR a schema-driven self-fetch\n\t\t * is in flight (`internalRefreshing`); OR a background load is running\n\t\t * after the first one completed (`loading && hasLoadedOnce`) — so\n\t\t * legacy `objectType` hosts get the spinner for free just by passing\n\t\t * `:loading`, without wiring `:refreshing` themselves.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\teffectiveRefreshing() {\n\t\t\treturn this.refreshing || this.internalRefreshing || (this.loading && this.hasLoadedOnce)\n\t\t},\n\n\t\t/**\n\t\t * Effective object-type slug, used for subscription, lock, store\n\t\t * registration, fetch, and sidebar state. Explicit `objectType`\n\t\t * prop wins (existing direct-mount call sites stay untouched);\n\t\t * otherwise `${register}-${schema}` fuses the schema-driven props\n\t\t * the manifest renderer passes. Returns `''` when neither path\n\t\t * yields a slug — the schema-driven gates downstream key off that.\n\t\t */\n\t\tresolvedObjectType() {\n\t\t\tif (this.objectType) {\n\t\t\t\treturn this.objectType\n\t\t\t}\n\t\t\tif (this.register && this.schema) {\n\t\t\t\treturn `${this.register}-${this.schema}`\n\t\t\t}\n\t\t\treturn ''\n\t\t},\n\n\t\t/**\n\t\t * True when this mount is wired for the manifest's schema-driven\n\t\t * contract: `register`, `schema`, and `objectId` are all set, so\n\t\t * the page should fetch the object + schema, register the type\n\t\t * on the store, and render the auto-body widgets when no slot\n\t\t * content is supplied. Legacy direct mounts (which pass an\n\t\t * explicit `objectType` instead) return `false` here and skip\n\t\t * the fetch path entirely.\n\t\t */\n\t\thasSchemaDrivenFetch() {\n\t\t\treturn Boolean(this.register && this.schema && this.objectId)\n\t\t},\n\n\t\t/**\n\t\t * Whether the header Edit button renders. Opted in via `showEditAction`,\n\t\t * but gated on there actually being a record and a schema to edit it\n\t\t * with: `isCreateMode` already owns the id-less page, and a button that\n\t\t * opens a form with no schema is a dead button.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\t/** Whether the lifecycle transitions are mounted. */\n\t\tshowsLifecycleActions() {\n\t\t\tif (this.objectNotFound || this.awaitingObject) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\treturn Boolean(this.lifecycleActions && (this.objectId || this.currentObject))\n\t\t},\n\n\t\t/**\n\t\t * Everything the Actions menu lists above its built-in items: the\n\t\t * lifecycle transitions, then the declared header actions.\n\t\t *\n\t\t * @return {Array<object>} Menu-ready entries.\n\t\t */\n\t\theaderMenuEntries() {\n\t\t\tconst lifecycle = this.showsLifecycleActions ? this.lifecycleMenuEntries : []\n\t\t\treturn [...lifecycle, ...this.menuHeaderActions]\n\t\t},\n\n\t\t/**\n\t\t * Whether Edit joins the CnActionButtons cluster instead of standing\n\t\t * on its own. Opted into by `inlineActions`.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tfoldsEditIntoActions() {\n\t\t\treturn typeof this.inlineActions === 'number'\n\t\t},\n\n\t\t/**\n\t\t * The header actions actually handed to CnActionButtons: the declared\n\t\t * ones, plus this page's Edit appended when `inlineActions` folds it\n\t\t * in. Edit goes LAST so it reads after the app's own actions in the\n\t\t * Actions menu — the page's affordance yields to the app's.\n\t\t *\n\t\t * @return {Array<object>} The action descriptors.\n\t\t */\n\t\teffectiveHeaderActions() {\n\t\t\tconst declared = Array.isArray(this.headerActions) ? this.headerActions : []\n\t\t\tif (!(this.foldsEditIntoActions && this.canEditRecord)) {\n\t\t\t\treturn declared\n\t\t\t}\n\t\t\treturn [\n\t\t\t\t...declared,\n\t\t\t\t{\n\t\t\t\t\tid: 'cn-detail-page-edit',\n\t\t\t\t\tlabel: this.editActionLabel,\n\t\t\t\t\ticon: 'Pencil',\n\t\t\t\t\t// A function, not a dispatch type: `open-form` hardcodes\n\t\t\t\t\t// `item: null`, so it creates and cannot edit this record.\n\t\t\t\t\tonSelect: () => this.openEditForm(),\n\t\t\t\t},\n\t\t\t]\n\t\t},\n\n\t\tcanEditRecord() {\n\t\t\treturn this.showEditAction\n\t\t\t\t&& !this.isCreateMode\n\t\t\t\t&& this.hasSchemaDrivenFetch\n\t\t\t\t&& Boolean(this.currentSchema)\n\t\t\t\t&& !this.editLockedByOther\n\t\t},\n\n\t\t/**\n\t\t * Whether somebody else is editing this record right now.\n\t\t *\n\t\t * The banner above already names them, so the button is withdrawn\n\t\t * rather than shown and refused: an Edit that opens a form the write\n\t\t * will reject is a form somebody fills in twice.\n\t\t *\n\t\t * @return {boolean} True when another user holds the lock.\n\t\t */\n\t\teditLockedByOther() {\n\t\t\treturn Boolean(this.lockState\n\t\t\t\t&& this.lockState.locked.value\n\t\t\t\t&& !this.lockState.lockedByMe.value)\n\t\t},\n\n\t\t/**\n\t\t * Label for the header Edit button.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\teditActionLabel() {\n\t\t\treturn this.editLabel || t('nextcloud-vue', 'Edit')\n\t\t},\n\n\t\t/**\n\t\t * The create archetype: a schema-bound page (`register` + `schema`) whose\n\t\t * route carries NO object id, and which has no hand-authored body of its\n\t\t * own. Instead of rendering a blank page (procest `/tasks/new`), the page\n\t\t * shows an empty create form for the schema (ADR-062). Suppressed when a\n\t\t * default slot or an explicit grid `layout` supplies the body.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tisCreateMode() {\n\t\t\t// `createForm` (manifest `config.createForm`) is the explicit switch;\n\t\t\t// 'auto' keeps the original heuristic. A page still needs a schema to\n\t\t\t// build a form from, and one already showing an object is editing,\n\t\t\t// not creating — so those two conditions hold even for 'always'.\n\t\t\tif (this.createForm === 'never') {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tconst schemaBound = Boolean(this.register && this.schema) && !this.objectId\n\t\t\tif (this.createForm === 'always') {\n\t\t\t\treturn schemaBound\n\t\t\t}\n\t\t\treturn schemaBound && !this.hasDefaultSlotContent && !this.hasGridLayout\n\t\t},\n\n\t\t/**\n\t\t * Create-form prefill drawn from the route query, filtered to the\n\t\t * schema's own properties (e.g. `?caseId=x` seeds the `caseId` field so\n\t\t * a child created from a parent is pre-linked). Null when nothing\n\t\t * applies (true empty create).\n\t\t *\n\t\t * @return {object|null}\n\t\t */\n\t\tcreatePrefill() {\n\t\t\tconst q = (this.$route && this.$route.query) || {}\n\t\t\tconst props = (this.currentSchema && this.currentSchema.properties) || {}\n\t\t\tconst out = {}\n\t\t\tfor (const [k, v] of Object.entries(q)) {\n\t\t\t\tif (Object.hasOwn(props, k)) {\n\t\t\t\t\tout[k] = v\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn Object.keys(out).length ? out : null\n\t\t},\n\n\t\t/**\n\t\t * `show` for the `#form-dialog` slot: whether the page's built-in form\n\t\t * dialog is on screen — the create archetype's empty form, or the\n\t\t * record edit form.\n\t\t *\n\t\t * Mirrors the `v-if` on the two default children exactly, so a\n\t\t * replacement opens and closes on the same conditions the built-in\n\t\t * dialog does. That includes the `editFormAwaitingRecord` guard (#850),\n\t\t * which is what stops an edit form opening over a record that has not\n\t\t * loaded yet — a replacement that reimplemented visibility from\n\t\t * `editFormOpen` alone would reintroduce that blank-form-overwrites-\n\t\t * the-record bug in every app that used it.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tformDialogVisible() {\n\t\t\tif (!this.currentSchema) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif (this.isCreateMode) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn this.editFormOpen && !this.editFormAwaitingRecord\n\t\t},\n\n\t\t/**\n\t\t * `item` for the `#form-dialog` slot: the record the built-in dialog is\n\t\t * bound to — the loaded object when editing, the route-derived prefill\n\t\t * when creating (null for a true empty create, matching CnIndexPage,\n\t\t * where a null `item` likewise means \"create\").\n\t\t *\n\t\t * @return {object|null}\n\t\t */\n\t\tformDialogItem() {\n\t\t\treturn this.isCreateMode ? this.createPrefill : this.currentObject\n\t\t},\n\n\t\t/**\n\t\t * Effective Refresh visibility for the page header. An explicit\n\t\t * `showRefresh` prop wins; when unset (`null`), show Refresh only if\n\t\t * it will do something — a consumer attached an `@refresh` listener,\n\t\t * or the page can self-fetch (`hasSchemaDrivenFetch`).\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\teffectiveHeaderShowRefresh() {\n\t\t\tif (this.showRefresh !== null) {\n\t\t\t\treturn this.showRefresh\n\t\t\t}\n\t\t\t// `$.vnode.props`, not `$attrs`: `refresh` is a declared emit, and\n\t\t\t// Vue keeps declared emits out of `$attrs`.\n\t\t\treturn Boolean(this.$.vnode.props?.onRefresh) || this.hasSchemaDrivenFetch\n\t\t},\n\n\t\t/**\n\t\t * Pinia store instance used for the schema-driven fetch.\n\t\t * Mirrors `CnLogsPage.objectStore`: explicit `objectStore` prop\n\t\t * wins; otherwise falls back to the library's default\n\t\t * `useObjectStore()`. The composable is invoked lazily inside a\n\t\t * computed so test mounts that never activate Pinia don't crash.\n\t\t *\n\t\t * @return {object|null} The resolved store, or null when the page\n\t\t * is not in schema-driven mode (no need to touch Pinia at all).\n\t\t */\n\t\teffectiveObjectStore() {\n\t\t\tif (this.objectStore) {\n\t\t\t\treturn this.objectStore\n\t\t\t}\n\t\t\tif (!this.hasSchemaDrivenFetch && !this.isCreateMode) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn useObjectStore()\n\t\t\t} catch (err) {\n\t\t\t\t// Pinia not active in this consumer — fall back to no-op\n\t\t\t\t// and let the page render as if no store-driven content\n\t\t\t\t// were available. Real consumers (CnAppRoot-hosted apps)\n\t\t\t\t// always have Pinia active, so this branch only protects\n\t\t\t\t// stand-alone test mounts.\n\n\t\t\t\t// eslint-disable-next-line no-console -- a deliberate warning to the developer integrating this component\n\t\t\t\tconsole.warn('[CnDetailPage] useObjectStore() unavailable; schema-driven mode disabled.', err)\n\t\t\t\treturn null\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * The fetched OR object for the schema-driven mode. Read straight\n\t\t * from the store's normalised `objects[type][id]` cache so any\n\t\t * other component fetching the same object (sidebar widgets,\n\t\t * locked-banner) shares state with no second request.\n\t\t *\n\t\t * @return {object|null}\n\t\t */\n\t\tcurrentObject() {\n\t\t\tconst store = this.effectiveObjectStore\n\t\t\tif (!store) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst type = this.resolvedObjectType\n\t\t\tif (!type || !this.objectId) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn store.objects?.[type]?.[this.objectId] ?? null\n\t\t},\n\n\t\t/**\n\t\t * Whether the edit form is still waiting for the record it edits.\n\t\t *\n\t\t * True only while a record is actually RESOLVABLE and absent — a host\n\t\t * with no object store has nothing to wait for, and gating on it\n\t\t * there would make the Edit button dead.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\teditFormAwaitingRecord() {\n\t\t\tif (!this.effectiveObjectStore || !this.objectId) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\treturn !this.currentObject\n\t\t},\n\n\t\t/**\n\t\t * The resolved OR object surfaced to the header's translation\n\t\t * badge slot (cn-detail-translation-aware-surfacing). Falls\n\t\t * back to `currentObject` from the schema-driven path AND, when\n\t\t * the schema-driven path is unavailable, attempts to read the\n\t\t * store via `objectType` + `objectId` directly (so legacy direct\n\t\t * mounts that don't pass `register` / `schema` still benefit).\n\t\t * Returns `null` when nothing can be resolved — the badge then\n\t\t * auto-hides.\n\t\t *\n\t\t * @return {object|null}\n\t\t */\n\t\tresolvedObject() {\n\t\t\t// Schema-driven path: reuse what `currentObject` already\n\t\t\t// computed.\n\t\t\tconst fromSchemaDriven = this.currentObject\n\t\t\tif (fromSchemaDriven) {\n\t\t\t\treturn fromSchemaDriven\n\t\t\t}\n\t\t\t// Direct-mount fallback: legacy callers pass `objectType` +\n\t\t\t// `objectId`. Read the same cache shape but keyed off the\n\t\t\t// explicit slug.\n\t\t\tconst store = this.effectiveObjectStore\n\t\t\tif (!store) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tif (!this.objectType || !this.objectId) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn store.objects?.[this.objectType]?.[this.objectId] ?? null\n\t\t},\n\n\t\t/**\n\t\t * The resolved record's human display name, drawn from the loaded\n\t\t * object via the same fallback chain the relation resolver uses:\n\t\t * `@self.name` → `name` / `title` / `displayName` → `firstName\n\t\t * lastName`. Empty string while the object is still loading or when no\n\t\t * name-like field exists (a raw id is never used as a name — ADR-062).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tobjectDisplayName() {\n\t\t\tconst obj = this.resolvedObject\n\t\t\tif (!obj || typeof obj !== 'object') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tconst self = obj['@self'] || {}\n\t\t\tconst id = this.objectId !== null && this.objectId !== undefined ? String(this.objectId) : ''\n\t\t\tconst candidates = [self.name, self.title, obj.name, obj.title, obj.displayName]\n\t\t\tfor (const c of candidates) {\n\t\t\t\tif (c !== null && c !== undefined && c !== '' && String(c) !== id) {\n\t\t\t\t\treturn String(c)\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst composed = ((obj.firstName || '') + ' ' + (obj.lastName || '')).trim()\n\t\t\treturn composed || ''\n\t\t},\n\n\t\t/**\n\t\t * The header `<h2>` text. Prefers the resolved record's display name\n\t\t * so the header names the record (\"ACME Corp\") rather than its type\n\t\t * (\"Case\"); falls back to the `title` prop (the type/label) while the\n\t\t * object is loading or has no name field.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tdisplayTitle() {\n\t\t\treturn this.objectDisplayName || this.resolvedTitle\n\t\t},\n\n\t\t/**\n\t\t * Effective translate function: the injected `cnTranslate` (the host\n\t\t * app's bound `t()`), identity by default.\n\t\t *\n\t\t * @return {(key: string) => string}\n\t\t */\n\t\teffectiveTranslate() {\n\t\t\treturn typeof this.cnTranslate === 'function' ? this.cnTranslate : (key) => key\n\t\t},\n\n\t\t/**\n\t\t * The `title` prop (the manifest-authored type label) run through the\n\t\t * host translate function. Used for the header fallback and the type\n\t\t * eyebrow; the record's own display name is data and stays untouched.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedTitle() {\n\t\t\treturn this.title ? this.effectiveTranslate(this.title) : this.title\n\t\t},\n\n\t\t/**\n\t\t * The page description run through the host translate function.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedDescription() {\n\t\t\treturn this.description ? this.effectiveTranslate(this.description) : this.description\n\t\t},\n\n\t\t/**\n\t\t * The statistics section heading run through the host translate function.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedStatsTitle() {\n\t\t\treturn this.statsTitle ? this.effectiveTranslate(this.statsTitle) : this.statsTitle\n\t\t},\n\n\t\t/**\n\t\t * The small type-label eyebrow shown above the record name. Only\n\t\t * rendered once a record name is resolved AND it differs from the\n\t\t * `title` prop, so the type context (\"Case\", \"Publication\") is kept\n\t\t * without shadowing the record name. Empty while loading (the type\n\t\t * label is then the `<h2>` itself).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\ttypeEyebrow() {\n\t\t\tconst name = this.objectDisplayName\n\t\t\tif (!name || !this.title || name === this.title) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn this.resolvedTitle\n\t\t},\n\n\t\t/**\n\t\t * The fetched JSON Schema for the schema-driven mode. Read from\n\t\t * the store's `schemas[type]` cache populated by `fetchSchema`.\n\t\t * Required to render `CnObjectDataWidget` (which takes a schema\n\t\t * Object, not a slug).\n\t\t *\n\t\t * @return {object|null}\n\t\t */\n\t\tcurrentSchema() {\n\t\t\tconst store = this.effectiveObjectStore\n\t\t\tif (!store) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst type = this.resolvedObjectType\n\t\t\tif (!type) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn store.schemas?.[type] ?? null\n\t\t},\n\n\t\t/**\n\t\t * True when consumer-supplied default slot content IS present.\n\t\t * Treats comment placeholders and whitespace-only text vnodes as\n\t\t * no content so a stray newline in the template doesn't\n\t\t * accidentally suppress the auto-body.\n\t\t *\n\t\t * `$slots.default` is a FUNCTION in Vue 3 — it has to be called to\n\t\t * get the vnodes. Reading `.length` off it yields the function's\n\t\t * arity (always 0 for a compiled slot), which made this read\n\t\t * `false` unconditionally and let the auto-body render on top of\n\t\t * whatever the consumer had put in the slot.\n\t\t */\n\t\thasDefaultSlotContent() {\n\t\t\treturn slotRenders(this.$slots.default)\n\t\t},\n\n\t\t/**\n\t\t * True when the auto-body (CnObjectDataWidget + CnObjectMetadataWidget)\n\t\t * should render. Conditions: schema-driven mount, the object has\n\t\t * loaded, no consumer slot wins, and the grid-layout mode is not\n\t\t * active (grid mode owns the body when present).\n\t\t */\n\t\tshouldRenderAutoBody() {\n\t\t\treturn this.hasSchemaDrivenFetch\n\t\t\t\t&& this.currentObject\n\t\t\t\t&& !this.hasDefaultSlotContent\n\t\t\t\t&& !this.hasGridLayout\n\t\t},\n\n\t\t/**\n\t\t * The object context handed to integration widgets.\n\t\t *\n\t\t * An explicit `integrationContext` prop wins; otherwise it is derived the\n\t\t * way it always was, falling back through the resolved sidebar config and\n\t\t * `sidebarProps` before the page's own register/schema. That fallback\n\t\t * chain is why this is computed HERE and passed down rather than derived\n\t\t * inside CnDetailWidgetHost: `resolvedSidebar` and `sidebarProps` are page\n\t\t * state the host has no view of, and deriving from `register`/`schema`\n\t\t * alone hands the widget two empty strings.\n\t\t *\n\t\t * @return {object} `{ register, schema, objectId }`.\n\t\t */\n\t\teffectiveIntegrationContext() {\n\t\t\tif (this.integrationContext) {\n\t\t\t\treturn this.integrationContext\n\t\t\t}\n\t\t\tconst resolved = this.resolvedSidebar || {}\n\t\t\treturn {\n\t\t\t\tregister: resolved.register || this.sidebarProps?.register || this.register || '',\n\t\t\t\tschema: resolved.schema || this.schema || this.resolvedObjectType || this.sidebarProps?.schema || '',\n\t\t\t\tobjectId: this.objectId ? String(this.objectId) : '',\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Effective layout array driving the body grid. An explicit `layout` prop\n\t\t * (manifest grid page) wins; otherwise the materialized default auto-body\n\t\t * (Data + Related) is used when the schema-driven object has loaded.\n\t\t *\n\t\t * @return {Array} Layout items for CnDashboardGrid.\n\t\t */\n\t\tbodyGridLayout() {\n\t\t\t// Depend on the (always-reactive) edit flag so this re-evaluates\n\t\t\t// when in-app edit mode flips: the manifest arrays are raw until\n\t\t\t// useManifestEditor.enter() observes them in place, so a cache\n\t\t\t// built pre-edit would stay frozen for in-place pushes (Add widget\n\t\t\t// on a detail page / grid ejection). See CnDashboardPage.hasWidgets.\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unused-expressions -- reading the flag IS the effect: the read registers the reactive dependency, and there is nothing to assign it to\n\t\t\tthis.editingBody\n\t\t\tif (this.hasGridLayout) {\n\t\t\t\treturn this.closeDroppedRows(this.layout)\n\t\t\t}\n\t\t\tif (this.shouldRenderAutoBody) {\n\t\t\t\treturn this.closeDroppedRows(this.autoBodyLayout || [])\n\t\t\t}\n\t\t\treturn []\n\t\t},\n\n\t\t/**\n\t\t * Effective widget-definition array paired with `bodyGridLayout`. Used by\n\t\t * the overridden `findWidget` so both the prop-driven and the default\n\t\t * auto-body grids resolve their widget defs from one place.\n\t\t *\n\t\t * @return {Array} Widget definitions.\n\t\t */\n\t\tbodyGridWidgets() {\n\t\t\tif (this.hasGridLayout) {\n\t\t\t\treturn this.widgets\n\t\t\t}\n\t\t\tif (this.shouldRenderAutoBody) {\n\t\t\t\treturn this.autoBodyWidgets || []\n\t\t\t}\n\t\t\treturn []\n\t\t},\n\n\t\t/**\n\t\t * Whether the body renders as an adjustable widget grid (vs. the\n\t\t * hand-authored default slot). True for explicit grid pages and for the\n\t\t * schema-driven default Data + Related body.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\thasBodyGrid() {\n\t\t\treturn this.bodyGridLayout.length > 0\n\t\t},\n\n\t\t/**\n\t\t * Whether the sidebar is rendered externally (via objectSidebarState inject)\n\t\t * rather than inline. When external, CnDetailPage only manages state —\n\t\t * the parent App renders the actual NcAppSidebar.\n\t\t */\n\t\thasExternalSidebar() {\n\t\t\treturn !!this.objectSidebarState\n\t\t},\n\n\t\t/**\n\t\t * Normalised sidebar config object regardless of input shape.\n\t\t *\n\t\t * - Boolean `true` → `{ show: true, enabled: true }`\n\t\t * - Boolean `false` → `{ show: false, enabled: false }`\n\t\t * - Object → fields passed through; `show` and\n\t\t * `enabled` default to `true` when omitted.\n\t\t *\n\t\t * Centralising the normalisation here keeps `syncSidebarState`\n\t\t * and the deprecation/conflict-warning logic single-sourced.\n\t\t */\n\t\tresolvedSidebar() {\n\t\t\tconst cfg = this.sidebar\n\t\t\t// A non-empty manifest `sidebarTabs` prop is itself an opt-in:\n\t\t\t// a `type:\"detail\"` page that declares tabs clearly wants the\n\t\t\t// sidebar. The `sidebar` prop defaults to Boolean `false`, and\n\t\t\t// CnPageRenderer only forwards a `sidebar` config when the\n\t\t\t// manifest page sets one — so a page that declares ONLY\n\t\t\t// `config.sidebarTabs` (procest CaseDetail) would otherwise fall\n\t\t\t// into the Boolean-`false` branch below and never publish its\n\t\t\t// strip. When tabs are present we treat the sidebar as enabled\n\t\t\t// (the explicit Object form below still overrides show/enabled).\n\t\t\tconst hasTabs = Array.isArray(this.sidebarTabs) && this.sidebarTabs.length > 0\n\t\t\tif (typeof cfg === 'boolean') {\n\t\t\t\tif (cfg) {\n\t\t\t\t\treturn { show: true, enabled: true }\n\t\t\t\t}\n\t\t\t\treturn hasTabs ? { show: true, enabled: true } : { show: false, enabled: false }\n\t\t\t}\n\t\t\tif (cfg && typeof cfg === 'object') {\n\t\t\t\treturn {\n\t\t\t\t\tshow: cfg.show !== false,\n\t\t\t\t\tenabled: cfg.enabled !== false,\n\t\t\t\t\t...cfg,\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn hasTabs ? { show: true, enabled: true } : { show: false, enabled: false }\n\t\t},\n\n\t\t/**\n\t\t * True when the sidebar should be wired into the external\n\t\t * `objectSidebarState` channel. Both `show` and `enabled`\n\t\t * must be non-`false` (defaults are `true`); either can\n\t\t * suppress the sidebar declaratively.\n\t\t */\n\t\tsidebarActive() {\n\t\t\tconst r = this.resolvedSidebar\n\t\t\t// An explicit `show: false` always suppresses the sidebar. Otherwise a\n\t\t\t// non-empty `sidebarTabs` opt-in activates it even past the prop's\n\t\t\t// default `{ enabled: false }` — the procest CaseDetail manifest\n\t\t\t// pattern, where a page declares only `config.sidebarTabs`.\n\t\t\tif (r.show === false) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif (r.enabled === false) {\n\t\t\t\treturn Array.isArray(this.sidebarTabs) && this.sidebarTabs.length > 0\n\t\t\t}\n\t\t\treturn true\n\t\t},\n\n\t\thasStats() {\n\t\t\treturn this.statsColumns.length > 0 && (this.statsRows.length > 0 || !!this.$slots['stats-rows'])\n\t\t},\n\n\t\t/** Whether any declarative in-body sections are configured. */\n\t\thasBodyWidgets() {\n\t\t\treturn Array.isArray(this.bodyWidgets) && this.bodyWidgets.length > 0\n\t\t},\n\n\t\t/**\n\t\t * Sections that land at the END placement: those with no `placement`\n\t\t * (the default) or an explicit `placement: \"end\"`. The three named\n\t\t * placement mounts (before-body / after-data / after-related) filter by\n\t\t * exact value; this catches the rest so nothing is silently dropped.\n\t\t *\n\t\t * @return {Array}\n\t\t */\n\t\tendPlacementSections() {\n\t\t\tif (!this.hasBodyWidgets) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\tconst named = ['before-body', 'after-data', 'after-related']\n\t\t\treturn this.bodyWidgets.filter((s) => !s || !s.placement || !named.includes(s.placement))\n\t\t},\n\n\t\t/**\n\t\t * Page/object context forwarded to CnBodySections for token resolution\n\t\t * (`@objectId` / `@object.<field>` / `@workspace.<key>`) AND provided on\n\t\t * `cnSectionContext` for host section components that inject. Mirrors the\n\t\t * `cnObjectContext` ref the abstract list/stat widgets already read.\n\t\t *\n\t\t * @return {{objectId: (string|null), object: (object|null), register: string, schema: string}}\n\t\t */\n\t\tsectionContext() {\n\t\t\tconst resolved = this.resolvedSidebar || {}\n\t\t\treturn {\n\t\t\t\tobjectId: (this.objectId !== undefined && this.objectId !== null) ? String(this.objectId) : null,\n\t\t\t\tobject: this.resolvedObject || null,\n\t\t\t\tregister: resolved.register || this.register || this.sidebarProps?.register || '',\n\t\t\t\tschema: resolved.schema || this.schema || this.resolvedObjectType || this.sidebarProps?.schema || '',\n\t\t\t\tconfig: this.cnAppConfigRef,\n\t\t\t}\n\t\t},\n\t},\n\n\twatch: {\n\t\t// A load just settled (true → false) — remember it so later loads\n\t\t// refresh in place (full-page spinner only on the first load). Not\n\t\t// `immediate`: `loading` starts false before the first fetch begins,\n\t\t// so reacting to that initial false would suppress the first spinner.\n\t\tloading(val) {\n\t\t\tif (!val) {\n\t\t\t\tthis.hasLoadedOnce = true\n\t\t\t\t// Refresh settled — re-assert the sidebar state that\n\t\t\t\t// syncSidebarState skipped while loading was in flight.\n\t\t\t\tthis.syncSidebarState()\n\t\t\t}\n\t\t},\n\n\t\tawaitingObject() {\n\t\t\tthis.syncSidebarState()\n\t\t},\n\n\t\tobjectNotFound() {\n\t\t\tthis.syncSidebarState()\n\t\t},\n\n\t\t// Deep, like `sidebarTabs` / `sidebarProps` below: the manifest editors\n\t\t// mutate `page.config.sidebar` IN PLACE, so the reference CnPageRenderer\n\t\t// forwards never changes. A shallow watcher missed every such edit —\n\t\t// switching the sidebar off in CnEditSidebarModal did nothing until the\n\t\t// page was reloaded. assignSidebarState() only writes keys that actually\n\t\t// changed, so the extra calls cost a comparison.\n\t\tsidebar: {\n\t\t\timmediate: true,\n\t\t\tdeep: true,\n\t\t\thandler() {\n\t\t\t\tthis.syncSidebarState()\n\t\t\t},\n\t\t},\n\n\t\t// Keep the provided object context current so detail-page abstract\n\t\t// widgets (CnObjectListWidget / CnStatWidget) can resolve `@objectId` /\n\t\t// `@object.<field>` tokens against the live object.\n\t\tcurrentObject: {\n\t\t\timmediate: true,\n\t\t\thandler() {\n\t\t\t\tthis.syncObjectContext()\n\t\t\t\t// Re-publish the object into objectSidebarState so the\n\t\t\t\t// hoisted sidebar's data/metadata tab widgets stay current.\n\t\t\t\tthis.syncSidebarState()\n\t\t\t},\n\t\t},\n\n\t\t// Re-publish once the schema Object resolves (fetched async), so the\n\t\t// hoisted sidebar's `data` tab widget gets its `schema` prop.\n\t\tcurrentSchema(schema) {\n\t\t\tthis.syncSidebarState()\n\n\t\t\t// Put the Data widget back if the body materialized before the\n\t\t\t// schema arrived. See materializeAutoBody(): fetchObject and\n\t\t\t// fetchSchema race, `shouldRenderAutoBody` gates on the OBJECT\n\t\t\t// only, and the body materializes once — so losing that race meant\n\t\t\t// the page rendered its title and Related panel with every scalar\n\t\t\t// field permanently missing (shillinq#1073).\n\t\t\t//\n\t\t\t// Guarded by `dataWidgetDeferred` rather than by \"is the data\n\t\t\t// widget absent\", so a body the user has edited is never rewritten\n\t\t\t// underneath them. The flag is cleared by the re-materialize, so\n\t\t\t// this runs at most once per materialized body.\n\t\t\tif (schema && this.dataWidgetDeferred) {\n\t\t\t\tthis.materializeAutoBody()\n\t\t\t}\n\t\t},\n\n\t\t// Materialize the default body grid (Data + Related) the first time the\n\t\t// schema-driven object resolves so the detail body is an adjustable grid.\n\t\tshouldRenderAutoBody: {\n\t\t\timmediate: true,\n\t\t\thandler(active) {\n\t\t\t\tif (active && !this.autoBodyLayout) {\n\t\t\t\t\tthis.materializeAutoBody()\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\n\t\t// A different schema means a fresh default grid — drop the materialized\n\t\t// one so it rebuilds for the new object type.\n\t\tresolvedObjectType() {\n\t\t\tthis.autoBodyLayout = null\n\t\t\tthis.autoBodyWidgets = null\n\t\t\t// Cleared with the body it described. materializeAutoBody() sets it\n\t\t\t// afresh, so this only avoids carrying a stale \"deferred\" across a\n\t\t\t// type change.\n\t\t\tthis.dataWidgetDeferred = false\n\t\t},\n\n\t\ttitle() {\n\t\t\tthis.syncSidebarState()\n\t\t},\n\n\t\tsubtitle() {\n\t\t\tthis.syncSidebarState()\n\t\t},\n\n\t\tobjectType() {\n\t\t\tthis.syncSidebarState()\n\t\t},\n\n\t\t// Schema-driven props feed both the sidebar state (via\n\t\t// resolvedObjectType) and the auto-fetch path. Re-sync + re-fetch\n\t\t// whenever any of the three move so the page stays consistent if\n\t\t// a parent component swaps the active object.\n\t\tregister() {\n\t\t\tthis.syncSidebarState()\n\t\t\tthis.pushAiContext()\n\t\t\tthis.fetchObjectIfNeeded()\n\t\t},\n\n\t\tschema() {\n\t\t\tthis.syncSidebarState()\n\t\t\tthis.pushAiContext()\n\t\t\tthis.fetchObjectIfNeeded()\n\t\t},\n\n\t\tobjectId() {\n\t\t\tthis.syncSidebarState()\n\t\t\tthis.pushAiContext()\n\t\t\tthis.fetchObjectIfNeeded()\n\t\t\tthis.syncObjectContext()\n\t\t},\n\n\t\tsidebarTabs: {\n\t\t\tdeep: true,\n\t\t\thandler() {\n\t\t\t\tthis.syncSidebarState()\n\t\t\t},\n\t\t},\n\n\t\tsidebarProps: {\n\t\t\tdeep: true,\n\t\t\thandler() {\n\t\t\t\tthis.syncSidebarState()\n\t\t\t},\n\t\t},\n\t},\n\n\tcreated() {\n\t\tthis.pushAiContext()\n\t},\n\n\tmounted() {\n\t\t// Kick the schema-driven fetch once the component has mounted —\n\t\t// `effectiveObjectStore` relies on a live Pinia context, which\n\t\t// is guaranteed by mounted() but not by created().\n\t\tthis.fetchObjectIfNeeded()\n\t\tthis.scheduleCellOverflowAudit()\n\n\t\t// `cn:page:refresh` is the channel a successful write announces itself\n\t\t// on — the manifest `refresh` and `api-call` actions bump it, and so do\n\t\t// app dialogs after a save. Until now nothing on a schema-driven detail\n\t\t// page listened: `useEndpointSource` and CnChartWidget answered it, but\n\t\t// every widget reading the page's OBJECT (`type: \"data\"` above all)\n\t\t// reads the copy this component fetched once, so a page kept showing\n\t\t// values the backend had already changed. Measured on a dossiq draft:\n\t\t// publish returned `{\"published\":true,\"version\":1}`, a re-read showed\n\t\t// `isDraft: false`, and the page still said draft.\n\t\t//\n\t\t// The subscription lives HERE rather than in each widget on purpose.\n\t\t// One page carries several object-bound widgets; if each answered the\n\t\t// channel itself, one write would become one read per widget. This\n\t\t// component owns the object, so one write is one read however many\n\t\t// widgets are bound to it.\n\t\tthis._onPageRefresh = (payload) => this.onPageRefreshBus(payload)\n\t\tsubscribe(PAGE_REFRESH_CHANNEL, this._onPageRefresh)\n\t},\n\n\tupdated() {\n\t\tthis.scheduleCellOverflowAudit()\n\t},\n\n\tbeforeUnmount() {\n\t\tif (this._onPageRefresh) {\n\t\t\tunsubscribe(PAGE_REFRESH_CHANNEL, this._onPageRefresh)\n\t\t\tthis._onPageRefresh = null\n\t\t}\n\t\tif (this.hasExternalSidebar) {\n\t\t\tthis.objectSidebarState.active = false\n\t\t\t// Clear manifest-driven tabs so the next mount starts fresh\n\t\t\t// rather than inheriting the previous page's tab strip.\n\t\t\tthis.objectSidebarState.tabs = undefined\n\t\t}\n\t\t// Reset AI context fields so stale detail context doesn't leak\n\t\tif (this.cnAiContext) {\n\t\t\tthis.cnAiContext.pageKind = 'custom'\n\t\t\tthis.cnAiContext.objectUuid = undefined\n\t\t\tthis.cnAiContext.registerSlug = undefined\n\t\t\tthis.cnAiContext.schemaSlug = undefined\n\t\t}\n\t},\n\n\tmethods: {\n\t\t// Expose the shared grid helpers to the template (grid mode + auto-body).\n\t\tcnGridCellStyle,\n\t\thasGridRow,\n\n\t\t/**\n\t\t * Emit a list step. When the control is a link it has navigated\n\t\t * already, so the payload `{ event, to }` tells the host not to push\n\t\t * again (`useListNavigation`'s `goNext`/`goPrevious` honour it).\n\t\t *\n\t\t * @param {string} name `previous-record` or `next-record`.\n\t\t * @param {object|string|null} to The link target, or null.\n\t\t * @param {MouseEvent} event The click event.\n\t\t */\n\t\tonListStep(name, to, event) {\n\t\t\tif (to && this.$router) {\n\t\t\t\tthis.$emit(name, { event, to })\n\t\t\t} else {\n\t\t\t\tthis.$emit(name)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Move focus to the primary action when the skip link is followed.\n\t\t *\n\t\t * The `href` anchor alone moves the DOCUMENT to the element without\n\t\t * moving FOCUS to it in every browser, which is the difference\n\t\t * between a skip link that works and one that scrolls and then hands\n\t\t * the next tab press back to the top of the page.\n\t\t *\n\t\t * @param {Event} event The click event.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tonSkipToPrimaryAction(event) {\n\t\t\tconst target = this.$refs.primaryActionButton?.$el ?? this.$refs.primaryActionButton\n\t\t\tconst focusable = target?.matches?.('button, a') ? target : target?.querySelector?.('button, a')\n\t\t\tif (focusable?.focus) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tfocusable.focus()\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * The active tab changed: tell the host, and put it in the address\n\t\t * when the page declares that its tab is part of its address.\n\t\t *\n\t\t * `replace`, never `push`, for the FIRST tab of a visit: an address\n\t\t * that arrived without a tab is being corrected to its canonical form\n\t\t * (ADR-052), and a correction must not become a history entry the\n\t\t * back button walks into. Later changes push, so back and forward\n\t\t * walk the tabs the reader actually visited.\n\t\t *\n\t\t * @param {string} tabId The tab now active.\n\t\t * @param {boolean} [canonicalising] Whether this is the arrival correction rather than a reader's choice.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tonTabChange(tabId, canonicalising = false) {\n\t\t\tif (typeof tabId !== 'string' || tabId === '') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\t/**\n\t\t\t * @event tab-change Emitted when the active tab changes.\n\t\t\t * @type {string}\n\t\t\t */\n\t\t\tthis.$emit('tab-change', tabId)\n\t\t\tif (!this.tabInAddress || !this.$router || !this.$route) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (this.$route.query?._tab === tabId) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst to = { name: this.$route.name, params: { ...this.$route.params }, query: { ...this.$route.query, _tab: tabId } }\n\t\t\tconst navigate = canonicalising ? this.$router.replace : this.$router.push\n\t\t\tnavigate.call(this.$router, to).catch(() => {})\n\t\t},\n\n\t\t/**\n\t\t * The tab the address asks for, or null.\n\t\t *\n\t\t * @return {string|null} The tab id.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\trequestedTabFromAddress() {\n\t\t\tconst tab = this.$route?.query?._tab\n\t\t\treturn typeof tab === 'string' && tab !== '' ? tab : null\n\t\t},\n\n\t\t/**\n\t\t * The sidebar settled on a tab: put it in the address.\n\t\t *\n\t\t * The sidebar reports the tab it actually shows, not the one that was\n\t\t * asked for, so an address naming a tab this reader may not see is\n\t\t * corrected to the one they can. `canonicalising` is true for that\n\t\t * correction and for the tabless arrival, so neither becomes a\n\t\t * history entry the back button walks into (ADR-052).\n\t\t *\n\t\t * @param {string} tabId The tab now showing.\n\t\t * @param {boolean} [canonicalising] Whether this is a correction rather than a reader's choice.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tonSidebarTabChange(tabId, canonicalising = false) {\n\t\t\tthis.onTabChange(tabId, canonicalising || this.requestedTabFromAddress() === null)\n\t\t},\n\n\t\t/**\n\t\t * Release the lock the current user holds on this record.\n\t\t *\n\t\t * Only reachable from the locked card's Unlock button, which the card\n\t\t * only renders for the viewer's OWN lock — so this never releases\n\t\t * somebody else's. A failure is left to `useObjectLock`, which logs it;\n\t\t * the flag is cleared either way so a failed release does not strand\n\t\t * the button disabled.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync onReleaseLock() {\n\t\t\tif (!this.lockState || this.releasingLock) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.releasingLock = true\n\t\t\ttry {\n\t\t\t\tawait this.lockState.release()\n\t\t\t} finally {\n\t\t\t\tthis.releasingLock = false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Re-emit the page-header menu's Refresh to the host.\n\t\t *\n\t\t * @param {{ widgetId: string, title: string }} payload - Action payload.\n\t\t * @param {object} event - Synthetic event (host may preventDefault).\n\t\t */\n\t\tasync onHeaderRefresh(payload, event) {\n\t\t\t/**\n\t\t\t * @event refresh The page-header Refresh action was clicked.\n\t\t\t * @type {{ widgetId: string, title: string }}\n\t\t\t */\n\t\t\tthis.$emit('refresh', payload, event)\n\t\t\t// Schema-driven (manifest) detail pages self-fetch — without this\n\t\t\t// the Refresh action has no host listener to act on and does\n\t\t\t// nothing. Re-fetch the object + schema and spin the action.\n\t\t\tif (!this.hasSchemaDrivenFetch) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.internalRefreshing = true\n\t\t\tconst done = this.fetchObjectIfNeeded()\n\t\t\tevent?.waitUntil?.(done)\n\t\t\ttry {\n\t\t\t\tawait done\n\t\t\t} finally {\n\t\t\t\tthis.internalRefreshing = false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * A `cn:page:refresh` reached the page — re-read the object so every\n\t\t * object-bound widget re-renders from what the backend now holds.\n\t\t *\n\t\t * Deliberately a no-op while `internalRefreshing` is set. The header's\n\t\t * own Refresh item emits `@refresh` FIRST and only then emits on this\n\t\t * channel (see CnActionsMenu.onRefreshClick), and `onHeaderRefresh`\n\t\t * sets the flag synchronously before awaiting its fetch — so without\n\t\t * this guard one click on Refresh would fetch the object twice.\n\t\t *\n\t\t * @param {{ waitUntil?: (promise: Promise<unknown>) => void }} [payload] Bus payload.\n\t\t * @return {void}\n\t\t */\n\t\tonPageRefreshBus(payload) {\n\t\t\tif (!this.hasSchemaDrivenFetch) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (this.internalRefreshing) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.internalRefreshing = true\n\t\t\tconst done = Promise.resolve(this.fetchObjectIfNeeded()).finally(() => {\n\t\t\t\tthis.internalRefreshing = false\n\t\t\t})\n\t\t\tpayload?.waitUntil?.(done)\n\t\t},\n\n\t\t/**\n\t\t * Re-emit the page-header menu's Request-a-feature to the host.\n\t\t *\n\t\t * @param {{ widgetId: string, title: string }} payload - Action payload.\n\t\t * @param {object} event - Synthetic event (host may preventDefault).\n\t\t */\n\t\tonHeaderRequestFeature(payload, event) {\n\t\t\t/**\n\t\t\t * @event request-feature The page-header Request-a-feature action\n\t\t\t * was clicked.\n\t\t\t * @type {{ widgetId: string, title: string }}\n\t\t\t */\n\t\t\tthis.$emit('request-feature', payload, event)\n\t\t},\n\n\t\t/**\n\t\t * Open the sidebar leaf a \"Linked apps\" row on the auto-body\n\t\t * CnRelatedObjectsWidget points at. Publishes the requested tab and\n\t\t * opens the external sidebar via `objectSidebarState`, and re-emits\n\t\t * `open-integration` so a host can override the routing.\n\t\t *\n\t\t * @param {string} integrationId - The leaf integration id (tab id).\n\t\t */\n\t\tonAutoBodyOpenIntegration(integrationId) {\n\t\t\tif (this.hasExternalSidebar && this.objectSidebarState) {\n\t\t\t\tthis.objectSidebarState.open = true\n\t\t\t\tthis.objectSidebarState.requestedTab = integrationId\n\t\t\t}\n\t\t\t/**\n\t\t\t * @event open-integration A related-objects \"Linked apps\" row\n\t\t\t * was clicked on the auto-body. Payload is the leaf id.\n\t\t\t * @type {string}\n\t\t\t */\n\t\t\tthis.$emit('open-integration', integrationId)\n\t\t},\n\n\t\t/**\n\t\t * Re-fetch the object after the geo widget persists `@self.geo` (so the\n\t\t * rest of the page — metadata, other widgets — reflects the new value),\n\t\t * and re-emit for the host.\n\t\t *\n\t\t * @param {object|null} geo The saved geo value (GeoJSON Point or null).\n\t\t */\n\t\tonGeoSaved(geo) {\n\t\t\tthis.fetchObjectIfNeeded()\n\t\t\t/**\n\t\t\t * @event geo-saved The object's `@self.geo` was saved via the geo\n\t\t\t * widget. Payload is the saved geo value (GeoJSON Point or null).\n\t\t\t * @type {object|null}\n\t\t\t */\n\t\t\tthis.$emit('geo-saved', geo)\n\t\t},\n\n\t\t/**\n\t\t * Re-emit a successful lifecycle transition to the host.\n\t\t *\n\t\t * @param {{ action: string, to: string, object: object }} payload The transition result.\n\t\t */\n\t\tonTransitioned(payload) {\n\t\t\t/**\n\t\t\t * @event transitioned A declarative lifecycle transition succeeded on this\n\t\t\t * page's object. Payload is `{ action, to, object }`.\n\t\t\t * @type {{ action: string, to: string, object: object }}\n\t\t\t */\n\t\t\tthis.$emit('transitioned', payload)\n\t\t},\n\n\t\t/**\n\t\t * Re-fetch the page's object after a lifecycle transition so the new state\n\t\t * (and any other server-side mutations the guard applied) render.\n\t\t */\n\t\tonLifecycleReload() {\n\t\t\tthis.fetchObjectIfNeeded()\n\t\t},\n\n\t\t/**\n\t\t * Open the relation-link modal for a configured `relationLinks` entry.\n\t\t *\n\t\t * @param {object} link The relation-link descriptor.\n\t\t */\n\t\topenRelationLink(link) {\n\t\t\tthis.activeRelationLink = link\n\t\t},\n\n\t\t/**\n\t\t * A relation-link modal saved a patched FK — re-fetch the object and\n\t\t * re-emit so the host can react.\n\t\t *\n\t\t * @param {object} saved The updated object.\n\t\t */\n\t\tonRelationLinked(saved) {\n\t\t\tthis.fetchObjectIfNeeded()\n\t\t\t/**\n\t\t\t * @event relation-linked A relation-link action patched a foreign key on\n\t\t\t * this page's object. Payload is the updated object.\n\t\t\t * @type {object}\n\t\t\t */\n\t\t\tthis.$emit('relation-linked', saved)\n\t\t},\n\n\t\t/**\n\t\t * Re-emit a related-collection row click to the host.\n\t\t *\n\t\t * @param {{ collection: object, row: object, index: number }} payload The click payload.\n\t\t */\n\t\tonRelatedRowClick(payload) {\n\t\t\t/**\n\t\t\t * @event related-row-click A row in a `relatedCollections` section was\n\t\t\t * clicked. Payload is `{ collection, row, index }`.\n\t\t\t * @type {{ collection: object, row: object, index: number }}\n\t\t\t */\n\t\t\tthis.$emit('related-row-click', payload)\n\t\t},\n\n\t\t/**\n\t\t * Schema-driven fetch entry point — no-op outside the\n\t\t * `register`+`schema`+`objectId` mode. Registers the type on\n\t\t * the store with the canonical 4-arg signature (matches what\n\t\t * `CnIndexPage` does), then fetches the object and its schema\n\t\t * in parallel. Errors land on `this._fetchError` (exposed via\n\t\t * the `error` template gate); the loading flag is intentionally\n\t\t * left to the store's own per-type `loading[type]` so it\n\t\t * cooperates with parallel fetches from sibling components.\n\t\t *\n\t\t * Called from `mounted()` and from the `register` / `schema` /\n\t\t * `objectId` watchers — every prop change re-runs in one\n\t\t * place so the request lifecycle stays predictable.\n\t\t */\n\t\tasync fetchObjectIfNeeded() {\n\t\t\t// Create archetype: no object to fetch, but the create form needs\n\t\t\t// the schema — register the type and fetch its schema, then stop.\n\t\t\tif (!this.hasSchemaDrivenFetch) {\n\t\t\t\tthis.objectFetchPending = false\n\t\t\t\tif (this.isCreateMode) {\n\t\t\t\t\tawait this.fetchSchemaForCreate()\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst store = this.effectiveObjectStore\n\t\t\tif (!store) {\n\t\t\t\tthis.objectFetchPending = false\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst type = this.resolvedObjectType\n\t\t\t// (slug, schemaId, registerId, slugs) — same shape as the\n\t\t\t// CnIndexPage / CnLogsPage fix. Passing the slug strings into\n\t\t\t// the positional id slots is intentional (OR's REST accepts\n\t\t\t// either numeric ids or kebab slugs there), and the 4th-arg\n\t\t\t// hints feed the live-updates transport.\n\t\t\t// Register the type ONCE. `registerObjectType` resets the type's\n\t\t\t// cache (`objects[type] = {}`, `schemas[type] = null`), so calling\n\t\t\t// it on every refresh blanks the object + schema until the\n\t\t\t// re-fetch lands — the content visibly disappears mid-refresh.\n\t\t\t// Skip re-registration when the type is already registered so a\n\t\t\t// refresh re-fetches and replaces the data in place.\n\t\t\tif (typeof store.registerObjectType === 'function'\n\t\t\t\t&& !store.objectTypeRegistry?.[type]) {\n\t\t\t\tstore.registerObjectType(\n\t\t\t\t\ttype,\n\t\t\t\t\tthis.schema,\n\t\t\t\t\tthis.register,\n\t\t\t\t\t{ registerSlug: this.register, schemaSlug: this.schema },\n\t\t\t\t)\n\t\t\t}\n\t\t\tconst objectId = this.objectId\n\t\t\tconst fetchesObject = typeof store.fetchObject === 'function'\n\t\t\tthis.objectFetchPending = fetchesObject\n\t\t\tif (fetchesObject) {\n\t\t\t\tthis.objectNotFound = false\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst tasks = []\n\t\t\t\tif (fetchesObject) {\n\t\t\t\t\ttasks.push(store.fetchObject(type, objectId))\n\t\t\t\t}\n\t\t\t\tif (typeof store.fetchSchema === 'function') {\n\t\t\t\t\ttasks.push(store.fetchSchema(type))\n\t\t\t\t}\n\t\t\t\tawait Promise.all(tasks)\n\t\t\t} catch (err) {\n\t\t\t\t// eslint-disable-next-line no-console -- the failure is already handled; the console is the only channel a host app can read the detail on\n\t\t\t\tconsole.error('[CnDetailPage] schema-driven fetch failed:', err)\n\t\t\t} finally {\n\t\t\t\t// A newer fetch for another id owns the flags now.\n\t\t\t\tif (fetchesObject && objectId === this.objectId) {\n\t\t\t\t\tthis.objectNotFound = !store.objects?.[type]?.[objectId]\n\t\t\t\t\t\t&& store.getError?.(type)?.status === 404\n\t\t\t\t\tthis.objectFetchPending = false\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Whether a grid-layout item resolves to an integration-typed\n\t\t * widget — `def.type === 'integration'` with a string\n\t\t * `integrationId`. Used by the grid template to render the\n\t\t * registry widget as the slot fallback.\n\t\t *\n\t\t * @param {object} item Layout item\n\t\t * @return {boolean} true when the matching widget def is an integration widget\n\t\t */\n\t\t/**\n\t\t * Register the type and fetch ONLY its schema, for the create archetype\n\t\t * (no object id to fetch). Populates `currentSchema` so the inline create\n\t\t * form can auto-generate its fields.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync fetchSchemaForCreate() {\n\t\t\tconst store = this.effectiveObjectStore\n\t\t\tif (!store) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst type = this.resolvedObjectType\n\t\t\tif (typeof store.registerObjectType === 'function'\n\t\t\t\t&& !store.objectTypeRegistry?.[type]) {\n\t\t\t\tstore.registerObjectType(\n\t\t\t\t\ttype,\n\t\t\t\t\tthis.schema,\n\t\t\t\t\tthis.register,\n\t\t\t\t\t{ registerSlug: this.register, schemaSlug: this.schema },\n\t\t\t\t)\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tif (typeof store.fetchSchema === 'function') {\n\t\t\t\t\tawait store.fetchSchema(type)\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\t// eslint-disable-next-line no-console -- the failure is already handled; the console is the only channel a host app can read the detail on\n\t\t\t\tconsole.error('[CnDetailPage] create-mode schema fetch failed:', err)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Persist the create form: POST the new object to OpenRegister, then\n\t\t * navigate to the created object's detail route (`createRoute` with its\n\t\t * id) — or back in history when no route is configured.\n\t\t *\n\t\t * Returns the outcome as well as applying it. The built-in dialog reads\n\t\t * the outcome off its own ref (`createFormDialog.setResult`), which a\n\t\t * `#form-dialog` replacement does not have — the returned result is how\n\t\t * a replacement learns whether to unlock its own dialog. Nothing on the\n\t\t * default path consumes the return value.\n\t\t *\n\t\t * @param {object} formData The confirmed form values.\n\t\t * @return {Promise<{success?: boolean, data?: object, error?: string}>}\n\t\t */\n\t\tasync onCreateFormConfirm(formData) {\n\t\t\ttry {\n\t\t\t\tconst [{ default: axios }, { generateUrl }] = await Promise.all([\n\t\t\t\t\timport('@nextcloud/axios'),\n\t\t\t\t\timport('@nextcloud/router'),\n\t\t\t\t])\n\t\t\t\tconst url = generateUrl(\n\t\t\t\t\t'/apps/openregister/api/objects/{register}/{schema}',\n\t\t\t\t\t{ register: this.register, schema: this.schema },\n\t\t\t\t)\n\t\t\t\tconst res = await axios.post(url, formData)\n\t\t\t\tconst created = (res && res.data) ? res.data : {}\n\t\t\t\tconst newId = (created['@self'] && created['@self'].id) || created.id\n\t\t\t\tif (this.$refs.createFormDialog) {\n\t\t\t\t\tthis.$refs.createFormDialog.setResult({ success: true })\n\t\t\t\t}\n\t\t\t\t/**\n\t\t\t\t * @event created Emitted after a successful create-form save.\n\t\t\t\t * @type {object}\n\t\t\t\t */\n\t\t\t\tthis.$emit('created', created)\n\t\t\t\tif (this.createRoute && newId && this.$router) {\n\t\t\t\t\tthis.$router.push({ name: this.createRoute, params: { id: String(newId) } }).catch(() => {})\n\t\t\t\t} else if (this.$router) {\n\t\t\t\t\tthis.$router.back()\n\t\t\t\t}\n\t\t\t\treturn { success: true, data: created }\n\t\t\t} catch (e) {\n\t\t\t\tconst error = (e && e.message) || 'error'\n\t\t\t\tif (this.$refs.createFormDialog) {\n\t\t\t\t\tthis.$refs.createFormDialog.setResult({ error })\n\t\t\t\t}\n\t\t\t\treturn { error }\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * `confirm` for the `#form-dialog` slot: the page's own save path,\n\t\t * handed to a replacement dialog so a create or edit made there behaves\n\t\t * exactly like one made in the built-in dialog — same duplicate-id\n\t\t * refusal, same store-then-axios fallback, same `created` / `edited`\n\t\t * events, same lifecycle reload.\n\t\t *\n\t\t * Bound as a PROP rather than left as an `@confirm` listener, because\n\t\t * CnPageRenderer mounts a manifest-declared replacement with\n\t\t * `v-bind=\"slotProps\"` — props only. A listener is unreachable from a\n\t\t * manifest even in principle, which is what made the same slot on\n\t\t * CnIndexPage decorative until openconnector#1150.\n\t\t *\n\t\t * Dispatches on `isCreateMode`, the same flag that decides which of the\n\t\t * two built-in dialogs renders — they are mutually exclusive, since\n\t\t * create mode is by definition a page with no object id.\n\t\t *\n\t\t * @param {object} formData The submitted form values.\n\t\t * @return {Promise<{success?: boolean, data?: object, error?: string}>} The save outcome, for the replacement's own `setResult`.\n\t\t */\n\t\tonFormDialogConfirm(formData) {\n\t\t\treturn this.isCreateMode\n\t\t\t\t? this.onCreateFormConfirm(formData)\n\t\t\t\t: this.onEditFormConfirm(formData)\n\t\t},\n\n\t\t/**\n\t\t * `close` for the `#form-dialog` slot. Dispatches the same way\n\t\t * `onFormDialogConfirm` does, so a dismissed create still navigates\n\t\t * back rather than stranding the user on an id-less page.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tonFormDialogClose() {\n\t\t\tif (this.isCreateMode) {\n\t\t\t\tthis.onCreateFormClose()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.closeEditForm()\n\t\t},\n\n\t\t/**\n\t\t * Open the record edit form.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\topenEditForm() {\n\t\t\t// 🔴 OPENING TAKES THE LOCK. Two people editing one record is not\n\t\t\t// resolved by whoever presses Save last: the first person's work is\n\t\t\t// gone and neither of them is told. The button is already withdrawn\n\t\t\t// while somebody else holds the lock (`canEditRecord`), so this is\n\t\t\t// the backstop for the seconds between the last read and the click.\n\t\t\t//\n\t\t\t// 🔑 THE FORM OPENS SYNCHRONOUSLY, AND THE ACQUIRE RUNS BESIDE IT.\n\t\t\t// Awaiting the round trip here would make `openEditForm()` async,\n\t\t\t// and every consumer that calls it and then asserts or renders on\n\t\t\t// the next tick would see a form that is not open yet: measured,\n\t\t\t// 10 of the 17 `CnDetailPageFormDialogSlot` tests went red on\n\t\t\t// exactly that. A conflict closes the form again and names the\n\t\t\t// holder, which is the same outcome one tick later.\n\t\t\tthis.editLockRefusal = ''\n\t\t\tthis.editFormOpen = true\n\t\t\tthis.acquireEditLock()\n\t\t},\n\n\t\t/**\n\t\t * Take the lock for the edit that just opened.\n\t\t *\n\t\t * A refusal CLOSES the form and shows the holder, because a form left\n\t\t * open over somebody else's lock is a form that will be filled in and\n\t\t * then refused. Any other failure leaves the form open: the server\n\t\t * re-checks on the write, so a lock that could not be taken costs an\n\t\t * optimistic edit rather than an editor who cannot work at all.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tacquireEditLock() {\n\t\t\tif (!this.lockState) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.lockState.acquire().catch((e) => {\n\t\t\t\tif (e?.name !== 'LockConflictError') {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tthis.editLockRefusal = e.message\n\t\t\t\tthis.editFormOpen = false\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Close the record edit form without saving.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tcloseEditForm() {\n\t\t\tthis.editFormOpen = false\n\t\t\tthis.releaseEditLock()\n\t\t},\n\n\t\t/**\n\t\t * Hand back the lock this page took for an edit.\n\t\t *\n\t\t * Fire and forget and never throws: a release that fails must not stop\n\t\t * a form from closing, and the lock has a server-side TTL behind it.\n\t\t * `release()` is a no-op when the viewer does not hold the lock, so\n\t\t * calling it on a page that opened no form takes nothing from anybody.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\treleaseEditLock() {\n\t\t\tif (!this.lockState || !this.lockState.lockedByMe.value) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.lockState.release().catch(() => {})\n\t\t},\n\n\t\t/**\n\t\t * Persist an edit of the record this page is showing.\n\t\t *\n\t\t * Saves through the object store when one is available so the page's own\n\t\t * subscription re-renders with the new values; the store is also what\n\t\t * every other surface reads from, so a direct HTTP write would leave\n\t\t * them showing the pre-edit record until something else refetched.\n\t\t * Falls back to a PUT for consumers with no Pinia.\n\t\t *\n\t\t * Returns the outcome as well as applying it, for the same reason\n\t\t * `onCreateFormConfirm` does: a `#form-dialog` replacement has no ref\n\t\t * on the built-in dialog and would otherwise never learn whether the\n\t\t * save landed. Nothing on the default path consumes the return value.\n\t\t *\n\t\t * @param {object} formData The submitted form values.\n\t\t * @return {Promise<{success?: boolean, data?: object, error?: string}>}\n\t\t */\n\t\tasync onEditFormConfirm(formData) {\n\t\t\t// `saveObject` picks PUT over POST on the presence of `id`, and an\n\t\t\t// OpenRegister object carries its id in `@self`, not at the top\n\t\t\t// level. Without this the edit would CREATE a duplicate record.\n\t\t\tconst dialog = this.$refs.editFormDialog\n\t\t\tif (!this.objectId) {\n\t\t\t\t// REFUSE rather than save. An empty id does not error — it makes\n\t\t\t\t// saveObject POST, which silently CREATES A DUPLICATE and leaves\n\t\t\t\t// the record the user was editing untouched. That presents as\n\t\t\t\t// \"my change did not save\", with a new orphan row behind it, and\n\t\t\t\t// nothing anywhere says so.\n\t\t\t\tconst error = t('nextcloud-vue', 'Cannot save: this record has no id, so the edit would create a duplicate instead of updating it.')\n\t\t\t\tif (dialog) {\n\t\t\t\t\tdialog.setResult({ error })\n\t\t\t\t}\n\t\t\t\treturn { error }\n\t\t\t}\n\t\t\tconst payload = { ...formData, id: this.objectId }\n\t\t\ttry {\n\t\t\t\tconst store = this.effectiveObjectStore\n\t\t\t\tlet saved = null\n\t\t\t\tif (store && typeof store.saveObject === 'function' && this.resolvedObjectType) {\n\t\t\t\t\tsaved = await store.saveObject(this.resolvedObjectType, payload)\n\t\t\t\t\tif (!saved) {\n\t\t\t\t\t\tconst err = store.getError?.(this.resolvedObjectType)\n\t\t\t\t\t\tconst error = (err && err.message) || t('nextcloud-vue', 'Save failed')\n\t\t\t\t\t\tif (dialog) {\n\t\t\t\t\t\t\tdialog.setResult({ error })\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn { error }\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst [{ default: axios }, { generateUrl }] = await Promise.all([\n\t\t\t\t\t\timport('@nextcloud/axios'),\n\t\t\t\t\t\timport('@nextcloud/router'),\n\t\t\t\t\t])\n\t\t\t\t\tconst url = generateUrl(\n\t\t\t\t\t\t'/apps/openregister/api/objects/{register}/{schema}/{id}',\n\t\t\t\t\t\t{ register: this.register, schema: this.schema, id: this.objectId },\n\t\t\t\t\t)\n\t\t\t\t\tconst res = await axios.put(url, payload)\n\t\t\t\t\tsaved = (res && res.data) ? res.data : payload\n\t\t\t\t}\n\t\t\t\tif (dialog) {\n\t\t\t\t\tdialog.setResult({ success: true })\n\t\t\t\t}\n\t\t\t\tthis.editFormOpen = false\n\t\t\t\tthis.releaseEditLock()\n\t\t\t\t/**\n\t\t\t\t * @event edited Emitted after the record edit form saves successfully.\n\t\t\t\t * @type {object} The saved record.\n\t\t\t\t */\n\t\t\t\tthis.$emit('edited', saved)\n\t\t\t\tthis.onLifecycleReload()\n\t\t\t\treturn { success: true, data: saved }\n\t\t\t} catch (e) {\n\t\t\t\tconst error = (e && e.message) || t('nextcloud-vue', 'Save failed')\n\t\t\t\tif (dialog) {\n\t\t\t\t\tdialog.setResult({ error })\n\t\t\t\t}\n\t\t\t\treturn { error }\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * The create form was dismissed without saving — navigate back so the\n\t\t * user is not stranded on an id-less page.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tonCreateFormClose() {\n\t\t\t/**\n\t\t\t * @event create-cancel Emitted when the create form is dismissed.\n\t\t\t */\n\t\t\tthis.$emit('create-cancel')\n\t\t\tif (this.$router) {\n\t\t\t\tthis.$router.back()\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Whether a grid item is a schema-driven `data` widget — rendered via\n\t\t * CnObjectDataWidget with the page's loaded object + the def's overrides.\n\t\t *\n\t\t * @param {object} item Layout item\n\t\t * @return {boolean} true when the matching widget def is `type: 'data'`.\n\t\t */\n\t\tisDataWidget(item) {\n\t\t\treturn isDataWidgetDef(this.findWidget(item))\n\t\t},\n\n\t\t/**\n\t\t * Whether a grid item is the schema-driven `related` widget — rendered via\n\t\t * CnRelatedObjectsWidget with the page's loaded object. One of the two\n\t\t * default body widgets.\n\t\t *\n\t\t * @param {object} item Layout item\n\t\t * @return {boolean} true when the matching widget def is `type: 'related'`.\n\t\t */\n\t\tisRelatedWidget(item) {\n\t\t\treturn isRelatedWidgetDef(this.findWidget(item))\n\t\t},\n\n\t\t/**\n\t\t * Whether a grid item is the `object-geo` widget — rendered via\n\t\t * CnObjectGeoWidget with the page's loaded object so the user can view /\n\t\t * edit the object's `@self.geo` on a map.\n\t\t *\n\t\t * @param {object} item Layout item\n\t\t * @return {boolean} true when the matching widget def is `type: 'object-geo'`.\n\t\t */\n\t\tisGeoWidget(item) {\n\t\t\treturn isGeoWidgetDef(this.findWidget(item))\n\t\t},\n\n\t\t/**\n\t\t * Whether a grid item is a content-only catalog widget (a bare table\n\t\t * renderer with no chrome of its own). These get the titled\n\t\t * CnWidgetWrapper card in the grid (ADR-062); self-chromed catalog\n\t\t * widgets (stat / chart / gauge / tile / …) render bare.\n\t\t *\n\t\t * @param {object} item Layout item.\n\t\t * @return {boolean} true when the widget def's type is content-only.\n\t\t */\n\t\tisContentOnlyWidget(item) {\n\t\t\treturn isContentOnlyWidgetDef(this.findWidget(item))\n\t\t},\n\n\t\t/**\n\t\t * Whether a grid item is a registry \"card\" widget — a single self-\n\t\t * contained KPI / gauge / delta tile (registry entry `card: true`).\n\t\t * These render bare tile content, so on a detail page they need the\n\t\t * same titled CnWidgetWrapper card chrome the dashboard gives them\n\t\t * (ADR-062: a lone stat must not read as uncarded floating text —\n\t\t * pipelinq contracts / POS).\n\t\t *\n\t\t * @param {object} item Layout item.\n\t\t * @return {boolean} true when the widget def's registry entry is a card.\n\t\t */\n\t\tisCardWidget(item) {\n\t\t\treturn isCardWidgetDef(this.findWidget(item))\n\t\t},\n\n\t\t/**\n\t\t * Debounced dev-mode audit: warn when a grid widget's rendered content\n\t\t * overflows its fixed cell (ADR-062 — the cell is the budget; overflow\n\t\t * is a design bug, never a scroll surface). No-op in production builds.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tscheduleCellOverflowAudit() {\n\t\t\tif (process.env.NODE_ENV === 'production') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tclearTimeout(this._cellAuditTimer)\n\t\t\tthis._cellAuditTimer = setTimeout(() => this.auditCellOverflow(), 800)\n\t\t},\n\n\t\t/**\n\t\t * Measure every grid cell and console.warn the widget ids whose content\n\t\t * is taller than the cell. Dev aid only — called via\n\t\t * `scheduleCellOverflowAudit`.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tauditCellOverflow() {\n\t\t\tif (!this.$el || !this.$el.querySelectorAll) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.$el.querySelectorAll('.grid-stack-item').forEach((cell) => {\n\t\t\t\tconst content = cell.querySelector('.grid-stack-item-content')\n\t\t\t\tif (!content) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif (content.scrollHeight > content.clientHeight + 8) {\n\t\t\t\t\tconst inner = cell.querySelector('.cn-detail-page__grid-item')\n\t\t\t\t\tconst label = (inner && inner.getAttribute('aria-labelledby')) || cell.getAttribute('gs-id') || ''\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.warn(`[CnDetailPage] widget cell ${label || '(unlabelled)'} content overflows its gridHeight `\n\t\t\t\t\t\t+ `(${content.scrollHeight}px in ${content.clientHeight}px) — enlarge the cell or scope the widget's content (ADR-062).`)\n\t\t\t\t}\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Whether to render the grid section `<h3>` title above a widget. Only for\n\t\t * consumer-supplied `#widget-<id>` slots (whose content may be bare) — the\n\t\t * built-in widget renderers (data / related / integration / catalog) draw\n\t\t * their own titled card header, so a grid heading would show the title\n\t\t * twice. Honours `item.showTitle === false` to opt out entirely.\n\t\t *\n\t\t * @param {object} item Layout item.\n\t\t * @return {boolean} true when the grid heading should render.\n\t\t */\n\t\tshowGridTitle(item) {\n\t\t\tif (item.showTitle === false || !this.findWidget(item)) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\treturn Boolean(this.$slots[`widget-${item.widgetId}`] || this.$slots[`widget-${item.widgetId}`])\n\t\t},\n\n\t\t/**\n\t\t * The grid section heading for a consumer slot widget — the widget\n\t\t * definition's manifest `title` run through the host translate\n\t\t * function. Returns the raw value untouched when there is none.\n\t\t *\n\t\t * @param {object} item Layout item.\n\t\t * @return {string|undefined} The heading text.\n\t\t */\n\t\tgridTitle(item) {\n\t\t\tconst title = this.findWidget(item)?.title\n\t\t\treturn title ? this.effectiveTranslate(title) : title\n\t\t},\n\n\t\t/**\n\t\t * Whether a card widget (stat / gauge / delta) shows the wrapper header.\n\t\t *\n\t\t * These renderers draw their own label from `content.label`, so a header\n\t\t * carrying the same manifest title printed it twice. `showTitle: false`\n\t\t * on the layout item switches it off, the same key and the same meaning\n\t\t * as on the grid `<h3>` (`showGridTitle`).\n\t\t *\n\t\t * @param {object} item Layout item.\n\t\t * @return {boolean} true when the wrapper header renders.\n\t\t */\n\t\tshowCardTitle(item) {\n\t\t\tif (item.showTitle === false) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tconst def = this.findWidget(item)\n\t\t\treturn def?.title !== undefined || widgetContentOf(def).title !== undefined\n\t\t},\n\n\t\t/**\n\t\t * Resolve the widget definition for a layout item. Overrides the\n\t\t * gridLayout mixin's `findWidget` (which only reads the `widgets` prop) so\n\t\t * the materialized default auto-body widgets resolve too. Searches the\n\t\t * effective `bodyGridWidgets`.\n\t\t *\n\t\t * @param {{ widgetId: string }} item Layout item.\n\t\t * @return {object|undefined} The matching widget definition.\n\t\t */\n\t\tfindWidget(item) {\n\t\t\treturn this.bodyGridWidgets.find((w) => w.id === item.widgetId)\n\t\t},\n\n\t\t/**\n\t\t * Drop the items that draw nothing, then close the rows they freed —\n\t\t * `float: true` leaves the item below pinned under a gap nobody owns.\n\t\t * Skipped when nothing was dropped, so an authored gap survives.\n\t\t *\n\t\t * @param {Array<object>} items The authored layout items.\n\t\t *\n\t\t * @return {Array<object>} What the grid should render.\n\t\t */\n\t\tcloseDroppedRows(items) {\n\t\t\tconst drawable = items.filter((item) => this.layoutItemCanDraw(item))\n\t\t\tif (drawable.length === items.length) {\n\t\t\t\treturn drawable\n\t\t\t}\n\n\t\t\treturn compactLayoutRows(drawable)\n\t\t},\n\n\t\t/**\n\t\t * Whether a layout item has anything to draw, so a grid cell is worth\n\t\t * spending on it.\n\t\t *\n\t\t * TWO widget types are judged, and no others.\n\t\t *\n\t\t * `integration`, in the case where nothing can ever appear: a leaf from\n\t\t * another app that is not registered, with no `requiredApp` to fall back\n\t\t * on. A cross-app feature is normally optional — humaniq's hours leaf on a\n\t\t * dossiq case — and without this the host still renders its wrapper, so the\n\t\t * absent app costs a bordered, full-height ghost card in the grid. An app\n\t\t * nobody installed should cost nothing.\n\t\t *\n\t\t * A widget that declares `requiredApp` is KEPT: the host answers a missing\n\t\t * app with a set-up state, which is content, and hiding it would turn an\n\t\t * actionable \"install humaniq\" into silence.\n\t\t *\n\t\t * `presence`, whenever nobody else is on the record. A runtime fact that\n\t\t * flips both ways, so the host holds the subscription (see setup) and the\n\t\t * row returns the moment somebody arrives.\n\t\t *\n\t\t * Deliberately NOT generalised to \"anything that resolves to nothing\".\n\t\t * A `custom` widget whose `#widget-<id>` slot is missing also draws an\n\t\t * empty host, but that is a WIRING FAULT rather than an absent optional\n\t\t * feature, and quietly dropping it would hide the bug instead of showing\n\t\t * it — CnPageRenderer's split pane forwards no slots, which is exactly\n\t\t * that fault and wants fixing, not concealing.\n\t\t *\n\t\t * @param {object} item A layout item.\n\t\t * @return {boolean} False only when the item provably draws nothing.\n\t\t */\n\t\tlayoutItemCanDraw(item) {\n\t\t\t// In edit mode nothing is hidden: an author has to see the placement to\n\t\t\t// move or delete it, and a widget that vanished from the editor while\n\t\t\t// staying in the manifest would be unmanageable.\n\t\t\tif (this.editingBody) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tconst widget = this.findWidget(item)\n\t\t\tif (!widget) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\t// Presence is empty almost always, and no attribute can reclaim its\n\t\t\t// row: GridStack floors `sizeToContent` at the item's `gs-min-h`.\n\t\t\tif (widget.type === 'presence') {\n\t\t\t\treturn (this.presentOthers || []).length > 0\n\t\t\t}\n\t\t\tif (widget.type !== 'integration') {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tconst requiredApp = widget.requiredApp || (widget.content || {}).requiredApp || ''\n\t\t\tif (requiredApp !== '' && !isAppInstalled(requiredApp)) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif (typeof this.getRegistryProvider !== 'function') {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn !!this.getRegistryProvider(widget.integrationId)\n\t\t},\n\n\t\t/**\n\t\t * Build the default body grid for the schema-driven auto-body: a full-width\n\t\t * Data widget with the Related-objects widget beneath it. Materialized once\n\t\t * (lazily) so the geometry is a mutable, reactive array the user can drag /\n\t\t * resize in edit mode. Both widgets carry `showTitle: false` because they\n\t\t * render their own card chrome.\n\t\t */\n\t\tmaterializeAutoBody() {\n\t\t\t// One source of truth (shared with the Buildiq edit button's\n\t\t\t// \"eject\" on edit) so the in-memory default and the manifest-ejected\n\t\t\t// default are identical. The data widget's content carries the page's\n\t\t\t// register/schema so its per-property editor can resolve the schema\n\t\t\t// (empty on legacy objectType-only mounts → the editor falls back to\n\t\t\t// the injected `cnObjectContext`).\n\t\t\tconst grid = defaultDetailGrid({\n\t\t\t\tregister: this.register || '',\n\t\t\t\tschema: this.schema || '',\n\t\t\t\tshowRelated: this.showRelatedObjects,\n\t\t\t})\n\t\t\t// Drop the Data widget when there's no schema to render (the helper\n\t\t\t// always includes it; the auto-body only shows it with a schema).\n\t\t\t//\n\t\t\t// This can happen because the schema HAS NOT ARRIVED YET, not\n\t\t\t// because there is none: `schemaDrivenFetch` fires fetchObject and\n\t\t\t// fetchSchema in parallel, and this body materializes as soon as\n\t\t\t// `shouldRenderAutoBody` turns true — which tests `currentObject`\n\t\t\t// and NOT `currentSchema`. When the object wins that race the Data\n\t\t\t// widget is filtered out, and because the body materializes only\n\t\t\t// once (`if (active && !this.autoBodyLayout)`) and resets only when\n\t\t\t// `resolvedObjectType` changes, the schema landing a moment later\n\t\t\t// never puts it back.\n\t\t\t//\n\t\t\t// The symptom is a detail page showing its title and Related panel\n\t\t\t// with EVERY declared scalar field missing, intermittently, on\n\t\t\t// identical code — shillinq#1073, where the object fetch returned\n\t\t\t// 200 carrying the values the page then did not render.\n\t\t\t//\n\t\t\t// `dataWidgetDeferred` records that this filtering was provisional\n\t\t\t// so the watcher below can re-materialize exactly once, when the\n\t\t\t// schema arrives. It is deliberately NOT a plain \"re-materialize if\n\t\t\t// the data widget is absent\": a body the user has edited must not\n\t\t\t// have the widget silently restored underneath them.\n\t\t\tthis.dataWidgetDeferred = !this.currentSchema\n\t\t\tif (!this.currentSchema) {\n\t\t\t\tgrid.widgets = grid.widgets.filter((w) => w.widgetId !== 'data')\n\t\t\t\tgrid.layout = grid.layout.filter((l) => l.widgetId !== 'data')\n\t\t\t}\n\t\t\tthis.autoBodyWidgets = grid.widgets\n\t\t\tthis.autoBodyLayout = grid.layout\n\t\t},\n\n\t\t/**\n\t\t * Persist a drag/resize from the body grid. For the default auto-body the\n\t\t * new geometry is kept locally so the move sticks; for an explicit `layout`\n\t\t * prop the change is emitted upward (`layout-change` + `update:layout`) for\n\t\t * the manifest renderer / host to persist.\n\t\t *\n\t\t * @param {Array} updated The new layout array from CnDashboardGrid.\n\t\t *\n\t\t * @event layout-change Emitted with the updated body-grid layout. The\n\t\t * sibling `update:layout` event is also emitted so `:layout.sync`\n\t\t * consumers stay in sync.\n\t\t */\n\t\tonBodyLayoutChange(updated) {\n\t\t\tif (this.hasGridLayout) {\n\t\t\t\t// Config-backed grid (manifest editor, ADR-041): the `layout` prop is\n\t\t\t\t// the SAME array the working manifest holds (the route-sentinel\n\t\t\t\t// resolver is reference-preserving), so write the new geometry back\n\t\t\t\t// onto its items in place — Save page then persists the resize.\n\t\t\t\tfor (const u of updated) {\n\t\t\t\t\tconst item = this.layout.find((l) => String(l.id) === String(u.id))\n\t\t\t\t\tif (item) {\n\t\t\t\t\t\titem.gridX = u.gridX\n\t\t\t\t\t\titem.gridY = u.gridY\n\t\t\t\t\t\titem.gridWidth = u.gridWidth\n\t\t\t\t\t\titem.gridHeight = u.gridHeight\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// In-memory default grid — keep the new geometry locally so the move\n\t\t\t\t// sticks for the session (un-customised page, nothing to persist).\n\t\t\t\tthis.autoBodyLayout = updated\n\t\t\t}\n\t\t\t/**\n\t\t\t * @event layout-change Emitted when a body-grid widget is dragged or\n\t\t\t * resized. Payload is the updated layout array.\n\t\t\t * @type {Array}\n\t\t\t */\n\t\t\tthis.$emit('layout-change', updated)\n\t\t\t// Description goes ABOVE `@event`, not inline after it:\n\t\t\t// vue-docgen-api's event-name splitter stops at the first `:`, so\n\t\t\t// `@event update:layout <description>` is read as one long event\n\t\t\t// NAME and the generated docs show an empty description.\n\t\t\t/**\n\t\t\t * Sibling of `layout-change` so `v-model:layout` consumers stay in\n\t\t\t * sync.\n\t\t\t *\n\t\t\t * @event update:layout\n\t\t\t * @type {Array}\n\t\t\t */\n\t\t\tthis.$emit('update:layout', updated)\n\t\t},\n\n\t\t/**\n\t\t * The registered config FORM for a grid item's widget type, or null.\n\t\t * Used to gate the per-widget configure cog (only configurable widgets\n\t\t * show one) in Buildiq edit mode.\n\t\t *\n\t\t * @param {object} item Layout item\n\t\t * @return {object|null} The form component, or null.\n\t\t */\n\t\tregistryFormFor(item) {\n\t\t\tconst def = this.findWidget(item)\n\t\t\tif (!def || !def.type) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst entry = getWidgetTypeEntry(def.type)\n\t\t\treturn (entry && entry.form) || null\n\t\t},\n\n\t\t/**\n\t\t * Whether a grid item shows the configure cog: the page is in edit\n\t\t * mode and the item resolves to a widget definition. Not gated on a\n\t\t * registered form: the style editor modal handles a type without one\n\t\t * (title, icon, style, delete), and the delete is what a custom widget\n\t\t * or an integration leaf needs the cog for.\n\t\t *\n\t\t * @param {object} item Layout item.\n\t\t * @return {boolean} true when the cog renders.\n\t\t */\n\t\tshowsCog(item) {\n\t\t\treturn this.editingBody === true && Boolean(this.findWidget(item))\n\t\t},\n\n\t\t/**\n\t\t * The registered RENDERER for a grid item's content-driven catalog\n\t\t * widget type (stat / chart / delta / gauge / object-list / …), or null.\n\t\t * Integration widgets resolve separately; the `data` renderer needs\n\t\t * object context the slot supplies, so it is excluded from this generic\n\t\t * fallback.\n\t\t *\n\t\t * @param {object} item Layout item\n\t\t * @return {object|null} The renderer component, or null.\n\t\t */\n\t\tregistryRendererFor(item) {\n\t\t\treturn resolveRegistryRenderer(this.findWidget(item), this.cnRegistry)\n\t\t},\n\n\t\t/**\n\t\t * The stored content/config blob for a grid item's catalog widget\n\t\t * (passed to its renderer).\n\t\t *\n\t\t * @param {object} item Layout item\n\t\t * @return {object} The widget def's `content`, or an empty object.\n\t\t */\n\t\twidgetContentFor(item) {\n\t\t\treturn widgetContentOf(this.findWidget(item))\n\t\t},\n\n\t\t/**\n\t\t * Resolve the effective title for a grid widget.\n\t\t *\n\t\t * A title-owning widget type (registry `ownsTitle`, e.g. `related`) keeps\n\t\t * its editable title in `content.title` — its config sub-form owns the\n\t\t * title field and the generic chrome title input is hidden. For those,\n\t\t * `content.title` MUST win over the chrome `def.title`, otherwise a\n\t\t * non-empty seed title (e.g. the default detail grid seeds the related\n\t\t * widget with `title: 'Related'`) permanently shadows the user's edit and\n\t\t * the title can never be changed. For every other type the chrome\n\t\t * `def.title` is authoritative, falling back to `content.title`. Empty\n\t\t * resolves to `undefined` so the widget renders its own default label.\n\t\t *\n\t\t * @param {object} item Layout item.\n\t\t * @return {string|undefined} The title to render, or undefined for the default.\n\t\t */\n\t\twidgetDisplayTitle(item) {\n\t\t\treturn widgetTitleOf(this.findWidget(item))\n\t\t},\n\n\t\t/**\n\t\t * Open the per-widget style/config editor for a grid item (cog click).\n\t\t *\n\t\t * @param {object} item Layout item to configure.\n\t\t */\n\t\tconfigureWidget(item) {\n\t\t\tthis.configWidgetId = item.widgetId\n\t\t\tthis.showWidgetConfig = true\n\t\t},\n\n\t\t/**\n\t\t * Persist the editor's changes onto the matching widget definition IN\n\t\t * PLACE (so an injected in-place manifest editor picks them up), close\n\t\t * the modal, and emit `widget-config-change` for consumers that persist\n\t\t * the page config themselves.\n\t\t *\n\t\t * @param {object} edited The widget object mutated by the editor.\n\t\t *\n\t\t * @event widget-config-change Emitted after a widget's config is saved.\n\t\t * @type {object}\n\t\t */\n\t\tonWidgetConfigSave(edited) {\n\t\t\tconst def = this.bodyGridWidgets.find((w) => w.id === this.configWidgetId)\n\t\t\tif (def) {\n\t\t\t\tif (edited.title !== undefined) {\n\t\t\t\t\tdef.title = edited.title\n\t\t\t\t}\n\t\t\t\tif (edited.content !== undefined) {\n\t\t\t\t\tdef.content = edited.content\n\t\t\t\t}\n\t\t\t\tdef.styleConfig = edited.styleConfig || {}\n\t\t\t}\n\t\t\tthis.showWidgetConfig = false\n\t\t\t/**\n\t\t\t * @event widget-config-change Emitted after a grid widget's config is\n\t\t\t * saved via the cog editor, or after the widget is removed (payload\n\t\t\t * null). Consumers persist the updated page/widget config.\n\t\t\t * @type {object|null}\n\t\t\t */\n\t\t\tthis.$emit('widget-config-change', def || null)\n\t\t},\n\n\t\t/**\n\t\t * Delete from inside the editor — drop the widget def + its layout\n\t\t * placement and close.\n\t\t *\n\t\t * @param {object} _w The widget the editor wants deleted (unused; routed\n\t\t * by `configWidgetId`).\n\t\t *\n\t\t * @event widget-config-change Emitted after the widget is removed.\n\t\t * @type {null}\n\t\t */\n\t\tonWidgetConfigDelete(_w) {\n\t\t\tconst id = this.configWidgetId\n\t\t\t// Drop from whichever pair backs the active grid: the explicit\n\t\t\t// `layout`/`widgets` props (manifest grid page) or the materialized\n\t\t\t// default auto-body arrays.\n\t\t\tconst widgetArr = this.hasGridLayout ? this.widgets : this.autoBodyWidgets\n\t\t\tconst layoutArr = this.hasGridLayout ? this.layout : this.autoBodyLayout\n\t\t\tif (Array.isArray(widgetArr)) {\n\t\t\t\tconst wIdx = widgetArr.findIndex((w) => w.id === id)\n\t\t\t\tif (wIdx !== -1) {\n\t\t\t\t\twidgetArr.splice(wIdx, 1)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (Array.isArray(layoutArr)) {\n\t\t\t\tconst lIdx = layoutArr.findIndex((l) => l.widgetId === id)\n\t\t\t\tif (lIdx !== -1) {\n\t\t\t\t\tlayoutArr.splice(lIdx, 1)\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.showWidgetConfig = false\n\t\t\tthis.$emit('widget-config-change', null)\n\t\t},\n\n\t\t/**\n\t\t * Push pageKind + objectUuid + register/schema context into the\n\t\t * reactive cnAiContext holder so the AI Chat Companion knows\n\t\t * what object the user is viewing.\n\t\t */\n\t\tpushAiContext() {\n\t\t\tif (!this.cnAiContext) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst resolved = this.resolvedSidebar || {}\n\t\t\tthis.cnAiContext.pageKind = 'detail'\n\t\t\tthis.cnAiContext.objectUuid = this.objectId ? String(this.objectId) : undefined\n\t\t\tthis.cnAiContext.registerSlug = resolved.register || this.register || this.sidebarProps?.register || undefined\n\t\t\tthis.cnAiContext.schemaSlug = resolved.schema || this.schema || this.resolvedObjectType || this.sidebarProps?.schema || undefined\n\t\t},\n\n\t\t/**\n\t\t * Refresh the provided `cnObjectContext` ref so detail-page abstract\n\t\t * widgets can resolve `@objectId` / `@object.<field>` filter tokens\n\t\t * against the current object. No-op when setup() didn't expose the ref\n\t\t * (standalone / read-only mounts).\n\t\t */\n\t\tsyncObjectContext() {\n\t\t\tif (!this.cnObjectContextRef) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst resolved = this.resolvedSidebar || {}\n\t\t\tthis.cnObjectContextRef.value = {\n\t\t\t\tobjectId: this.objectId !== undefined && this.objectId !== null ? String(this.objectId) : null,\n\t\t\t\tobject: this.currentObject || null,\n\t\t\t\tregister: resolved.register || this.register || this.sidebarProps?.register || '',\n\t\t\t\tschema: resolved.schema || this.schema || this.resolvedObjectType || this.sidebarProps?.schema || '',\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Pushes the resolved sidebar config into the\n\t\t * `objectSidebarState` provide/inject channel for the host\n\t\t * App's mounted `<CnObjectSidebar>` to consume.\n\t\t *\n\t\t * Object form fields take precedence over `sidebarProps` for\n\t\t * any field they declare; `sidebarProps` continues to fill\n\t\t * fields the Object form omits, preserving back-compat.\n\t\t *\n\t\t * Suppression (`show: false` or `enabled: false`) clears\n\t\t * `tabs` so a hidden detail page does not leak prior tab\n\t\t * state to the next mount.\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\tsyncSidebarState() {\n\t\t\tif (!this.hasExternalSidebar) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.warnIfDeprecatedSidebarShape()\n\t\t\t// During a background refresh (content stays in place — see\n\t\t\t// `hasLoadedOnce`), a transient loading-driven `enabled: false`\n\t\t\t// must NOT tear down the sidebar. Hosts commonly bind\n\t\t\t// `:sidebar=\"{ enabled: !loading }\"`, so without this guard every\n\t\t\t// refresh unmounts the host's CnObjectSidebar and re-fetches all\n\t\t\t// its sub-resources (files/notes/tags/tasks/audit). Skip the sync\n\t\t\t// while refreshing; the `loading` watcher re-syncs once it settles.\n\t\t\tif (this.loading && this.hasLoadedOnce) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst r = this.resolvedSidebar\n\t\t\tconst hasRecord = !this.objectNotFound && !this.awaitingObject\n\t\t\tif (this.sidebarActive && hasRecord && this.resolvedObjectType && this.objectId) {\n\t\t\t\tconst merged = this.mergeSidebarSources(r)\n\t\t\t\t// Seed `open` only on the inactive→active edge (first activation\n\t\t\t\t// of this object). Subsequent syncs must NOT clobber it, otherwise\n\t\t\t\t// the user's close/toggle would be undone on the next reactive\n\t\t\t\t// change. The shared channel owns `open` after seeding.\n\t\t\t\t//\n\t\t\t\t// `sidebarSeeded` used to be written here and never read, so\n\t\t\t\t// `open` went into assignSidebarState() on EVERY sync and the\n\t\t\t\t// paragraph above described behaviour the code did not have. A\n\t\t\t\t// detail page emits several syncs while it hydrates (the object\n\t\t\t\t// resolves, then the schema), and each one reset `open` to the\n\t\t\t\t// prop default — reclosing a sidebar the user had just opened.\n\t\t\t\t// Downstream that made openbuild's e2e race the UI: the tab was\n\t\t\t\t// clicked and its panel was hidden again before the assertion\n\t\t\t\t// ran (openbuild#268 — \"resolves 30×, hidden\").\n\t\t\t\tconst seedOpen = (this.sidebarSeeded === false)\n\t\t\t\tif (seedOpen) {\n\t\t\t\t\tthis.sidebarSeeded = true\n\t\t\t\t}\n\t\t\t\t// Manifest-driven open-enum tabs (forwarded to the host\n\t\t\t\t// app's mounted CnObjectSidebar via inject). When the\n\t\t\t\t// top-level `sidebarTabs` prop is non-empty it provides\n\t\t\t\t// the tabs (manifest pattern); otherwise the merged\n\t\t\t\t// `sidebar.tabs` / `sidebarProps.tabs` legacy paths win.\n\t\t\t\t// Falls back to `undefined` so the host's CnObjectSidebar\n\t\t\t\t// renders its built-in tab set.\n\t\t\t\tconst tabs = (this.sidebarTabs && this.sidebarTabs.length > 0)\n\t\t\t\t\t? this.sidebarTabs\n\t\t\t\t\t: merged.tabs\n\t\t\t\tthis.assignSidebarState({\n\t\t\t\t\tactive: true,\n\t\t\t\t\t// Omitted after the seeding sync — assignSidebarState()\n\t\t\t\t\t// only writes the keys it is given, so leaving `open` out\n\t\t\t\t\t// preserves whatever the shared channel currently holds.\n\t\t\t\t\t...(seedOpen ? { open: this.sidebarOpen } : {}),\n\t\t\t\t\tobjectType: this.resolvedObjectType,\n\t\t\t\t\tobjectId: this.objectId,\n\t\t\t\t\t// The loaded object, so coordinate-blind sidebar-tab widgets\n\t\t\t\t\t// (the `data` / `metadata` built-ins) receive it as `objectData`\n\t\t\t\t\t// — the hoisted sidebar is a CnAppRoot sibling, not a\n\t\t\t\t\t// CnDetailPage child, so it can't inject our object context.\n\t\t\t\t\tobject: this.resolvedObject || null,\n\t\t\t\t\t// The resolved schema OBJECT (not the slug), which the `data`\n\t\t\t\t\t// built-in (CnObjectDataWidget) needs alongside `objectData`.\n\t\t\t\t\tschemaObject: this.currentSchema || null,\n\t\t\t\t\ttitle: merged.title || this.title || '',\n\t\t\t\t\tsubtitle: merged.subtitle || this.subtitle || '',\n\t\t\t\t\tregister: merged.register || this.register || '',\n\t\t\t\t\tschema: merged.schema || this.schema || '',\n\t\t\t\t\thiddenTabs: merged.hiddenTabs || [],\n\t\t\t\t\ttabs,\n\t\t\t\t\t// ADR-019. `config.sidebar.useRegistry` reaches\n\t\t\t\t\t// `resolvedSidebar` intact — the Object branch returns\n\t\t\t\t\t// `{show, enabled, ...cfg}` — and survives\n\t\t\t\t\t// mergeSidebarSources(), which spreads `resolved` before\n\t\t\t\t\t// its own field list. It was simply never published here,\n\t\t\t\t\t// so the host's CnObjectSidebar always saw the prop default\n\t\t\t\t\t// `false` and rendered its BACKWARDS-COMPATIBLE branch: the\n\t\t\t\t\t// five hard-coded built-in tabs (files, notes, tags, tasks,\n\t\t\t\t\t// audit-trail) instead of one tab per registered provider.\n\t\t\t\t\t//\n\t\t\t\t\t// The declaration therefore did nothing at all. Measured on\n\t\t\t\t\t// decidiq run 32702211376, whose MeetingIntegrations page\n\t\t\t\t\t// sets `config.sidebar.useRegistry: true`:\n\t\t\t\t\t//\n\t\t\t\t\t// JS registry carries every expected provider passed\n\t\t\t\t\t// every component leaf has a tab + widget passed\n\t\t\t\t\t// OCS caps and JS registry agree passed\n\t\t\t\t\t// providers the server reports available 10\n\t\t\t\t\t// tabs the sidebar rendered 5\n\t\t\t\t\t//\n\t\t\t\t\t// Five, exactly, because that is the fallback branch. Every\n\t\t\t\t\t// app whose manifest opts a page into the registry sidebar\n\t\t\t\t\t// has been getting the built-ins.\n\t\t\t\t\t//\n\t\t\t\t\t// `excludeIntegrations` rides the same channel and was\n\t\t\t\t\t// dropped for the same reason; without it a page cannot\n\t\t\t\t\t// suppress a provider it does not want.\n\t\t\t\t\tuseRegistry: merged.useRegistry === true,\n\t\t\t\t\texcludeIntegrations: merged.excludeIntegrations || [],\n\t\t\t\t\t// The tab the address asks for, and the way back. The\n\t\t\t\t\t// sidebar lives outside this component's tree (the host\n\t\t\t\t\t// mounts it at NcContent level), so the address and the\n\t\t\t\t\t// tab strip can only meet on this shared channel.\n\t\t\t\t\t...(this.tabInAddress\n\t\t\t\t\t\t? { requestedTab: this.requestedTabFromAddress(), onTabChange: this.onSidebarTabChange }\n\t\t\t\t\t\t: {}),\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tthis.assignSidebarState({ active: false, tabs: undefined })\n\t\t\t\t// Re-arm the seed so the next activation re-applies `sidebarOpen`.\n\t\t\t\tthis.sidebarSeeded = false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Apply fields onto the shared `objectSidebarState` only when they\n\t\t * actually change. Writing the same logical value — notably a fresh\n\t\t * `[]` for `hiddenTabs` when none is configured — would otherwise put\n\t\t * a new array reference on the reactive object every call and trigger\n\t\t * a host re-render. That churn fed an infinite render loop: the host\n\t\t * App re-renders on the new `hiddenTabs` ref → its `<router-view>`\n\t\t * re-renders the routed detail page → the page's inline `:sidebar`\n\t\t * prop re-fires this sync → repeat. Arrays are compared shallowly so\n\t\t * an equivalent array is treated as unchanged.\n\t\t *\n\t\t * @param {object} fields Partial `objectSidebarState` to apply.\n\t\t */\n\t\tassignSidebarState(fields) {\n\t\t\tconst state = this.objectSidebarState\n\t\t\tfor (const key of Object.keys(fields)) {\n\t\t\t\tconst next = fields[key]\n\t\t\t\tconst cur = state[key]\n\t\t\t\tif (Array.isArray(next) && Array.isArray(cur)\n\t\t\t\t\t&& next.length === cur.length\n\t\t\t\t\t&& next.every((v, i) => v === cur[i])) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif (cur !== next) {\n\t\t\t\t\tstate[key] = next\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Merge the Object-form `sidebar` fields with the legacy\n\t\t * `sidebarProps` fields. Object form wins on conflict; first\n\t\t * conflict per instance fires a one-shot console.warn naming\n\t\t * the conflicting fields.\n\t\t *\n\t\t * @param {object} resolved Pre-normalised sidebar config object.\n\t\t * @return {object} Merged config — Object form fields override\n\t\t * sidebarProps fields where both are set.\n\t\t */\n\t\tmergeSidebarSources(resolved) {\n\t\t\tconst objectForm = (this.sidebar && typeof this.sidebar === 'object') ? this.sidebar : null\n\t\t\tconst props = this.sidebarProps || {}\n\t\t\tconst merged = {\n\t\t\t\ttitle: objectForm?.title ?? props.title,\n\t\t\t\tsubtitle: objectForm?.subtitle ?? props.subtitle,\n\t\t\t\tregister: objectForm?.register ?? props.register,\n\t\t\t\tschema: objectForm?.schema ?? props.schema,\n\t\t\t\thiddenTabs: objectForm?.hiddenTabs ?? props.hiddenTabs,\n\t\t\t\ttabs: objectForm?.tabs ?? props.tabs,\n\t\t\t}\n\t\t\tif (objectForm && !this.__sidebarConflictWarned) {\n\t\t\t\tconst overlap = ['title', 'subtitle', 'register', 'schema', 'hiddenTabs', 'tabs']\n\t\t\t\t\t.filter((field) => objectForm[field] !== undefined && props[field] !== undefined)\n\t\t\t\tif (overlap.length > 0) {\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(`[CnDetailPage] :sidebar (Object) and :sidebarProps both set ${overlap.join(', ')}; the :sidebar values win. Move all fields to :sidebar to silence this warning.`)\n\t\t\t\t\tthis.__sidebarConflictWarned = true\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Re-anchor `resolved` for the contract — callers expect\n\t\t\t// the returned object to reflect the normalised shape.\n\t\t\treturn { ...resolved, ...merged }\n\t\t},\n\n\t\t/**\n\t\t * Log a one-shot deprecation warning when the legacy Boolean\n\t\t * form of the `sidebar` prop is observed. Tracked via a\n\t\t * non-reactive instance flag so subsequent renders/toggles\n\t\t * don't spam the console.\n\t\t */\n\t\twarnIfDeprecatedSidebarShape() {\n\t\t\tif (typeof this.sidebar !== 'boolean') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (this.__sidebarBooleanWarned) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.__sidebarBooleanWarned = true\n\n\t\t\t// eslint-disable-next-line no-console -- a deliberate warning to the developer integrating this component\n\t\t\tconsole.warn('[CnDetailPage] :sidebar=Boolean is deprecated; pass an Object — see docs/components/cn-detail-page.md for the new shape.')\n\t\t},\n\t},\n}\n</script>\n\n<!-- Styles in css/detail-page.css -->\n"],"names":["CnIcon","CnActionsMenu","CnBuildiqEditButton","CnLockedBanner","CnDetailWidgetHost","CnFormDialog","CnDashboardGrid","CnLifecycleActions","CnActionButtons","CnSummaryAggregates","CnRelatedCollections","CnBodySections","CnTranslatedBadge","CnWidgetStyleEditorModal","CnRelationLinkModal","t"],"mappings":"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"}
1
+ {"version":3,"file":"CnDetailPage.vue2.js","sources":["../../../../src/components/CnDetailPage/CnDetailPage.vue"],"sourcesContent":["<!--\n CnDetailPage — Generic detail/overview page.\n\n The detail page equivalent of CnDashboardPage. Assembles a complete entity detail\n view from card-based sections, matching the dashboard visual style (rounded cards\n with headers). Uses a fixed declarative layout (no drag-and-drop).\n\n Features:\n - Header with back button, title, subtitle, and action buttons\n - Card-based content area (via default slot with CnDetailCard components)\n - Optional 12-column CSS grid layout mode (via layout + widgets props)\n - Optional right sidebar (CnObjectSidebar) for files, notes, tags, tasks, audit trail\n - Loading and error states\n - Edit mode toggle\n\n A simpler alternative to CnIndexPage for detail, stats, and overview pages.\n No multi-object table, no CRUD dialogs — just a clean layout with:\n - Header (title, description, icon, action buttons)\n - Loading / error / empty states\n - Statistics table section\n - Content sections via slots\n-->\n<template>\n\t<div class=\"cn-detail-page\" data-testid=\"cn-detail-page\" :style=\"{ maxWidth: maxWidth }\">\n\t\t<!-- Skip link to the page's primary action. Off screen until it takes\n\t\t focus, so it costs a sighted mouse user nothing and saves a\n\t\t keyboard user every widget on the page. Targets the action the\n\t\t page DECLARES rather than a guessed first button: a skip link\n\t\t that lands somewhere arbitrary is worse than none, because it is\n\t\t the one link a keyboard user is told to trust. -->\n\t\t<a\n\t\t\tv-if=\"primaryActionLabel && !objectNotFound\"\n\t\t\t:href=\"`#${primaryActionAnchorId}`\"\n\t\t\tclass=\"cn-detail-page__skip-link\"\n\t\t\tdata-testid=\"cn-detail-page-skip-link\"\n\t\t\t@click=\"onSkipToPrimaryAction\">\n\t\t\t{{ skipLinkLabel }}\n\t\t</a>\n\n\t\t<!-- Header -->\n\t\t<div v-if=\"!objectNotFound\" class=\"cn-detail-page__header\" data-testid=\"cn-detail-page-header\">\n\t\t\t<!-- Header (left block) — overridable via #header slot. Default\n\t\t\t renders the icon + title + description. The right-hand\n\t\t\t #actions slot remains separate so headerComponent and\n\t\t\t actionsComponent can be replaced independently. -->\n\t\t\t<!--\n\t\t\t\t@slot header\n\t\t\t\t@description Replace the entire left header block (icon + title + description).\n\t\t\t\t@binding {string} title Page title.\n\t\t\t\t@binding {string} description Subtitle / description.\n\t\t\t\t@binding {string} icon MDI icon name resolved by CnIcon.\n\t\t\t\t@binding {number} icon-size Icon size in pixels.\n\t\t\t-->\n\t\t\t<slot\n\t\t\t\tname=\"header\"\n\t\t\t\t:title=\"title\"\n\t\t\t\t:description=\"description\"\n\t\t\t\t:icon=\"icon\"\n\t\t\t\t:iconSize=\"iconSize\">\n\t\t\t\t<div class=\"cn-detail-page__header-left\">\n\t\t\t\t\t<!--\n\t\t\t\t\t\t@slot icon\n\t\t\t\t\t\t@description Replace only the header icon (keeping the lib's title +\n\t\t\t\t\t\tdescription rendering). Default content: a `<CnIcon>` resolved from\n\t\t\t\t\t\tthe `icon` prop.\n\t\t\t\t\t-->\n\t\t\t\t\t<slot name=\"icon\">\n\t\t\t\t\t\t<CnIcon\n\t\t\t\t\t\t\tv-if=\"icon\"\n\t\t\t\t\t\t\t:name=\"icon\"\n\t\t\t\t\t\t\t:size=\"iconSize\"\n\t\t\t\t\t\t\tclass=\"cn-detail-page__icon\" />\n\t\t\t\t\t</slot>\n\t\t\t\t\t<div class=\"cn-detail-page__header-text\">\n\t\t\t\t\t\t<!-- Type name as a small eyebrow above the record name, so\n\t\t\t\t\t\t the header reads \"the record\" not \"the kind of record\"\n\t\t\t\t\t\t (ADR-062). Only shown once the object resolves to a\n\t\t\t\t\t\t display name that differs from the type label. -->\n\t\t\t\t\t\t<p\n\t\t\t\t\t\t\tv-if=\"typeEyebrow\"\n\t\t\t\t\t\t\tclass=\"cn-detail-page__type-eyebrow\"\n\t\t\t\t\t\t\tdata-testid=\"cn-detail-page-type-eyebrow\">\n\t\t\t\t\t\t\t{{ typeEyebrow }}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<h2 v-if=\"displayTitle\" class=\"cn-detail-page__title\">\n\t\t\t\t\t\t\t{{ displayTitle }}\n\t\t\t\t\t\t</h2>\n\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t@slot translation-badge\n\t\t\t\t\t\t\t@description Replace the default `CnTranslatedBadge` rendered when the\n\t\t\t\t\t\t\tresolved object's `_translationMeta.translatedFrom` is set. Receives\n\t\t\t\t\t\t\t`:object=\"resolvedObject\"`. Default renders `<CnTranslatedBadge :object=\"resolvedObject\" />`\n\t\t\t\t\t\t\t(which auto-hides when there's nothing to surface). See\n\t\t\t\t\t\t\t`openspec/changes/cn-detail-translation-aware-surfacing`.\n\t\t\t\t\t\t-->\n\t\t\t\t\t\t<slot name=\"translation-badge\" :object=\"resolvedObject\">\n\t\t\t\t\t\t\t<CnTranslatedBadge v-if=\"resolvedObject\" :object=\"resolvedObject\" />\n\t\t\t\t\t\t</slot>\n\t\t\t\t\t\t<p v-if=\"description\" class=\"cn-detail-page__description\">\n\t\t\t\t\t\t\t{{ resolvedDescription }}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<!-- Declarative cross-schema summary chips (manifest\n\t\t\t\t\t\t `config.summaryAggregates`). Count/sum/avg over a\n\t\t\t\t\t\t related schema scoped to this object via @objectId. -->\n\t\t\t\t\t\t<CnSummaryAggregates\n\t\t\t\t\t\t\tv-if=\"summaryAggregates && summaryAggregates.length > 0\"\n\t\t\t\t\t\t\t:aggregates=\"summaryAggregates\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</slot>\n\t\t\t<div class=\"cn-detail-page__header-actions\">\n\t\t\t\t<!-- Next and previous inside the list this record was opened\n\t\t\t\t from. Rendered only when the address names that list: a\n\t\t\t\t record reached by a bare link offers neither, rather than\n\t\t\t\t stepping through an order nobody chose. Both ends say so\n\t\t\t\t instead of wrapping. -->\n\t\t\t\t<div\n\t\t\t\t\tv-if=\"listNavigation && listNavigation.available\"\n\t\t\t\t\tclass=\"cn-detail-page__list-nav\"\n\t\t\t\t\tdata-testid=\"cn-detail-page-list-nav\">\n\t\t\t\t\t<!-- With previousTo/nextTo the control is a link; a disabled\n\t\t\t\t\t end drops `to` so it renders as a disabled button. -->\n\t\t\t\t\t<NcButton\n\t\t\t\t\t\tvariant=\"tertiary\"\n\t\t\t\t\t\t:disabled=\"listNavigation.isFirst\"\n\t\t\t\t\t\t:to=\"listNavigation.isFirst ? undefined : (previousTo || undefined)\"\n\t\t\t\t\t\t:aria-label=\"previousRecordLabel\"\n\t\t\t\t\t\t:title=\"previousRecordLabel\"\n\t\t\t\t\t\tdata-testid=\"cn-detail-page-previous\"\n\t\t\t\t\t\t@click=\"onListStep('previous-record', previousTo, $event)\">\n\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t<ChevronLeft :size=\"20\" />\n\t\t\t\t\t\t</template>\n\t\t\t\t\t</NcButton>\n\t\t\t\t\t<span class=\"cn-detail-page__list-nav-position\" data-testid=\"cn-detail-page-list-position\">\n\t\t\t\t\t\t{{ listPositionLabel }}\n\t\t\t\t\t</span>\n\t\t\t\t\t<NcButton\n\t\t\t\t\t\tvariant=\"tertiary\"\n\t\t\t\t\t\t:disabled=\"listNavigation.isLast\"\n\t\t\t\t\t\t:to=\"listNavigation.isLast ? undefined : (nextTo || undefined)\"\n\t\t\t\t\t\t:aria-label=\"nextRecordLabel\"\n\t\t\t\t\t\t:title=\"nextRecordLabel\"\n\t\t\t\t\t\tdata-testid=\"cn-detail-page-next\"\n\t\t\t\t\t\t@click=\"onListStep('next-record', nextTo, $event)\">\n\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t<ChevronRight :size=\"20\" />\n\t\t\t\t\t\t</template>\n\t\t\t\t\t</NcButton>\n\t\t\t\t</div>\n\t\t\t\t<!-- The action the page declares as its primary one, and the\n\t\t\t\t target the skip link above lands on. -->\n\t\t\t\t<NcButton\n\t\t\t\t\tv-if=\"primaryActionLabel\"\n\t\t\t\t\t:id=\"primaryActionAnchorId\"\n\t\t\t\t\tref=\"primaryActionButton\"\n\t\t\t\t\tvariant=\"primary\"\n\t\t\t\t\tdata-testid=\"cn-detail-page-primary-action\"\n\t\t\t\t\t@click=\"$emit('primary-action', primaryAction)\">\n\t\t\t\t\t{{ primaryActionLabel }}\n\t\t\t\t</NcButton>\n\t\t\t\t<!-- Declarative lifecycle transitions (manifest\n\t\t\t\t `config.lifecycleActions`). Status-gated; driven by the\n\t\t\t\t object's x-openregister-lifecycle. They land in the Actions\n\t\t\t\t menu below, since a record with several transitions filled\n\t\t\t\t the header with buttons. -->\n\t\t\t\t<CnLifecycleActions\n\t\t\t\t\tv-if=\"showsLifecycleActions\"\n\t\t\t\t\t:objectId=\"objectId\"\n\t\t\t\t\t:object=\"currentObject\"\n\t\t\t\t\t:config=\"lifecycleActions\"\n\t\t\t\t\t:schema=\"currentSchema\"\n\t\t\t\t\tdisplay=\"menu\"\n\t\t\t\t\t@entries=\"lifecycleMenuEntries = $event\"\n\t\t\t\t\t@transitioned=\"onTransitioned\"\n\t\t\t\t\t@reload=\"onLifecycleReload\" />\n\t\t\t\t<!-- Declarative header actions (#91 Wave 3): a manifest\n\t\t\t\t `config.headerActions[]` dispatched with visibleWhen gating —\n\t\t\t\t the object context this page provides drives `@objectId` /\n\t\t\t\t `@object.<field>` tokens + local predicates (the shillinq\n\t\t\t\t PaymentRunDetailActions contract).\n\n\t\t\t\t They render as entries in the Actions menu below, not as a\n\t\t\t\t row of buttons, which is what the manifest schema has always\n\t\t\t\t said they are and what CnIndexPage already does with the same\n\t\t\t\t key. A dossiq case declares twelve, and twelve buttons pushed\n\t\t\t\t the record's own title down to a truncated stub. This\n\t\t\t\t instance draws nothing itself; it owns the dialogs the\n\t\t\t\t actions open and feeds the menu through `entries`. -->\n\t\t\t\t<CnActionButtons\n\t\t\t\t\tv-if=\"effectiveHeaderActions.length > 0\"\n\t\t\t\t\t:actions=\"effectiveHeaderActions\"\n\t\t\t\t\tdisplay=\"menu\"\n\t\t\t\t\tdata-testid=\"cn-detail-page-header-actions\"\n\t\t\t\t\t@entries=\"menuHeaderActions = $event\"\n\t\t\t\t\t@created=\"onLifecycleReload\" />\n\t\t\t\t<!--\n\t\t\t\t\t@slot actions\n\t\t\t\t\t@description Right-hand action surface in the page header (typically NcActions\n\t\t\t\t\tor buttons). Renders alongside (not inside) the `header` slot. Receives the\n\t\t\t\t\tresolved object context so an actionsComponent (resolved by CnPageRenderer)\n\t\t\t\t\tcan act on the current record without re-fetching.\n\t\t\t\t\t@binding {object} object The resolved record.\n\t\t\t\t\t@binding {string} objectId The resolved object id.\n\t\t\t\t\t@binding {object} schema The resolved schema.\n\t\t\t\t\t@binding {string} objectType The resolved object type.\n\t\t\t\t\t@binding {object} store The effective object store.\n\t\t\t\t\t@binding {Function} openEditForm Opens this page's own record edit form. Lets an actions component put Edit inside ITS action cluster instead of leaving the page's button beside it — the page renders no button of its own once `showEditAction` is false, but this still opens the same dialog.\n\t\t\t\t\t@binding {boolean} canEditRecord Whether the page would render its own Edit button (`showEditAction` plus a record and schema to edit).\n\t\t\t\t-->\n\t\t\t\t<slot\n\t\t\t\t\tname=\"actions\"\n\t\t\t\t\t:object=\"resolvedObject\"\n\t\t\t\t\t:objectId=\"objectId\"\n\t\t\t\t\t:schema=\"currentSchema\"\n\t\t\t\t\t:objectType=\"resolvedObjectType\"\n\t\t\t\t\t:store=\"effectiveObjectStore\"\n\t\t\t\t\t:openEditForm=\"openEditForm\"\n\t\t\t\t\t:canEditRecord=\"canEditRecord\" />\n\t\t\t\t<!-- Record edit (ADR-062): the detail page's own way to change the\n\t\t\t\t record it is showing. Without it a `type:\"detail\"` page is\n\t\t\t\t read-only and the ONLY edit surface is the modal launched\n\t\t\t\t from the index table — which is why that modal could not\n\t\t\t\t simply be removed. Opens the same schema-driven CnFormDialog\n\t\t\t\t the index used, scoped to this record. -->\n\t\t\t\t<!-- Standalone unless `inlineActions` is set, in which case Edit\n\t\t\t\t joins the header actions above and lands in the Actions menu\n\t\t\t\t with them. Kept standalone by default so every existing\n\t\t\t\t consumer's header is byte-identical. -->\n\t\t\t\t<NcButton\n\t\t\t\t\tv-if=\"canEditRecord && !foldsEditIntoActions\"\n\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\tdata-testid=\"cn-detail-page-edit\"\n\t\t\t\t\t:aria-label=\"editActionLabel\"\n\t\t\t\t\t@click=\"openEditForm\">\n\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t<Pencil :size=\"20\" />\n\t\t\t\t\t</template>\n\t\t\t\t\t{{ editActionLabel }}\n\t\t\t\t</NcButton>\n\t\t\t\t<!-- NB: no sidebar-toggle here — NcObjectSidebar/NcAppSidebar\n\t\t\t\t renders its own open toggle (`.app-sidebar__toggle`) when\n\t\t\t\t closed and an X (`.app-sidebar__close`) when open, so a custom\n\t\t\t\t button would duplicate it. -->\n\t\t\t\t<!-- In-app edit button (ADR-041): icon-only, self-wires from CnAppRoot. -->\n\t\t\t\t<CnBuildiqEditButton />\n\t\t\t\t<CnActionsMenu\n\t\t\t\t\t:showRefresh=\"effectiveHeaderShowRefresh\"\n\t\t\t\t\t:refreshing=\"effectiveRefreshing\"\n\t\t\t\t\t:showRequestFeature=\"showRequestFeature\"\n\t\t\t\t\t:showReportBug=\"showReportBug\"\n\t\t\t\t\t:showDocumentation=\"showDocumentation\"\n\t\t\t\t\t:documentationUrl=\"documentationUrl\"\n\t\t\t\t\t:docsAnchor=\"resolvedPageId\"\n\t\t\t\t\t:documentationLabel=\"documentationLabel || undefined\"\n\t\t\t\t\t:widgetId=\"resolvedPageId\"\n\t\t\t\t\t:title=\"title\"\n\t\t\t\t\t:surface=\"`detail:${resolvedPageId}`\"\n\t\t\t\t\trefreshChannel=\"cn:page:refresh\"\n\t\t\t\t\ttestidBase=\"cn-detail-page\"\n\t\t\t\t\t@refresh=\"onHeaderRefresh\"\n\t\t\t\t\t@requestFeature=\"onHeaderRequestFeature\">\n\t\t\t\t\t<template v-if=\"headerMenuEntries.length\" #primary-items>\n\t\t\t\t\t\t<template v-for=\"entry in headerMenuEntries\">\n\t\t\t\t\t\t\t<!-- An action that goes to a URL is a LINK. The browser\n\t\t\t\t\t\t\t then supplies middle-click, \"open in new tab\" and the\n\t\t\t\t\t\t\t semantics assistive tech announces, none of which a\n\t\t\t\t\t\t\t click handler can. -->\n\t\t\t\t\t\t\t<NcActionLink\n\t\t\t\t\t\t\t\tv-if=\"entry.href\"\n\t\t\t\t\t\t\t\t:key=\"`${entry.id}-link`\"\n\t\t\t\t\t\t\t\t:href=\"entry.href\"\n\t\t\t\t\t\t\t\t:target=\"entry.linkTarget || undefined\"\n\t\t\t\t\t\t\t\t:data-testid=\"entry.testid\">\n\t\t\t\t\t\t\t\t<template v-if=\"entry.iconName || entry.iconClass\" #icon>\n\t\t\t\t\t\t\t\t\t<CnIcon v-if=\"entry.iconName\" :name=\"entry.iconName\" :size=\"20\" />\n\t\t\t\t\t\t\t\t\t<span v-else :class=\"entry.iconClass\" />\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t{{ entry.label }}\n\t\t\t\t\t\t\t</NcActionLink>\n\t\t\t\t\t\t\t<NcActionButton\n\t\t\t\t\t\t\t\tv-else\n\t\t\t\t\t\t\t\t:key=\"entry.id\"\n\t\t\t\t\t\t\t\t:data-testid=\"entry.testid\"\n\t\t\t\t\t\t\t\t:disabled=\"entry.disabled\"\n\t\t\t\t\t\t\t\t:aria-pressed=\"entry.pressed === null ? null : String(entry.pressed)\"\n\t\t\t\t\t\t\t\t:closeAfterClick=\"true\"\n\t\t\t\t\t\t\t\t@click=\"entry.run()\">\n\t\t\t\t\t\t\t\t<template v-if=\"entry.iconName || entry.iconClass\" #icon>\n\t\t\t\t\t\t\t\t\t<CnIcon v-if=\"entry.iconName\" :name=\"entry.iconName\" :size=\"20\" />\n\t\t\t\t\t\t\t\t\t<span v-else :class=\"entry.iconClass\" />\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t\t{{ entry.label }}\n\t\t\t\t\t\t\t</NcActionButton>\n\t\t\t\t\t\t</template>\n\t\t\t\t\t\t<NcActionSeparator />\n\t\t\t\t\t</template>\n\t\t\t\t</CnActionsMenu>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<!-- The locked card, under the title, for ANY active lock — not only a\n\t\t remote one. It used to be suppressed when the current user held the\n\t\t lock, which meant the one person who could do something about a\n\t\t stale lock was also the only person the UI never told about it.\n\t\t The card carries the tone: an error for somebody else's lock, a\n\t\t neutral notice plus Unlock for your own. -->\n\t\t<CnLockedBanner\n\t\t\tv-if=\"lockState && lockState.locked.value\"\n\t\t\t:lockedBy=\"lockState.lockedBy.value\"\n\t\t\t:lockedByMe=\"lockState.lockedByMe.value\"\n\t\t\t:expiresAt=\"lockState.expiresAt.value\"\n\t\t\t:unlocking=\"releasingLock\"\n\t\t\t@unlock=\"onReleaseLock\" />\n\n\t\t<!-- The sentence a refused acquire left behind. Shown SEPARATELY from\n\t\t the banner above and not folded into it: a refused acquire does not\n\t\t refresh the cached object, so `@self.locked` is still whatever the\n\t\t last read said and the banner may not have appeared yet. This\n\t\t carries the server's own message, which names the holder. -->\n\t\t<p\n\t\t\tv-if=\"editLockRefusal\"\n\t\t\tclass=\"cn-detail-page__lock-refusal\"\n\t\t\trole=\"alert\"\n\t\t\tdata-testid=\"cn-detail-page-lock-refusal\">\n\t\t\t{{ editLockRefusal }}\n\t\t</p>\n\n\t\t<!-- Not-found state: the record behind the address does not exist. -->\n\t\t<div v-if=\"objectNotFound\" class=\"cn-detail-page__not-found\" data-testid=\"cn-detail-page-not-found\">\n\t\t\t<!--\n\t\t\t\t@slot not-found\n\t\t\t\t@description Replace the default not-found surface, shown instead of the\n\t\t\t\theader and body when the schema-driven fetch answers 404.\n\t\t\t\t@binding {object|string} target Router location of the back button.\n\t\t\t-->\n\t\t\t<slot name=\"not-found\" :target=\"notFoundTarget\">\n\t\t\t\t<NcEmptyContent :name=\"notFoundLabels.name\" :description=\"notFoundLabels.description\">\n\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t<FileQuestionOutline :size=\"48\" />\n\t\t\t\t\t</template>\n\t\t\t\t\t<template v-if=\"$router\" #action>\n\t\t\t\t\t\t<NcButton\n\t\t\t\t\t\t\tvariant=\"primary\"\n\t\t\t\t\t\t\tdata-testid=\"cn-detail-page-not-found-back\"\n\t\t\t\t\t\t\t:to=\"notFoundTarget\">\n\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t<ArrowLeft :size=\"20\" />\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t{{ notFoundButtonLabel }}\n\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t</template>\n\t\t\t\t</NcEmptyContent>\n\t\t\t</slot>\n\t\t</div>\n\n\t\t<!-- Loading state -->\n\t\t<div v-else-if=\"showLoadingState\" class=\"cn-detail-page__loading\">\n\t\t\t<NcLoadingIcon :size=\"32\" />\n\t\t\t<span>{{ loadingLabel }}</span>\n\t\t</div>\n\n\t\t<!-- Error state -->\n\t\t<div v-else-if=\"error\" class=\"cn-detail-page__error\">\n\t\t\t<!--\n\t\t\t\t@slot error\n\t\t\t\t@description Replace the default `<NcEmptyContent>` error surface. Default\n\t\t\t\tcontent uses `errorMessage` + an MDI alert icon + an optional retry button.\n\t\t\t-->\n\t\t\t<slot name=\"error\">\n\t\t\t\t<NcEmptyContent :name=\"errorMessage\">\n\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t<AlertCircleOutline :size=\"48\" />\n\t\t\t\t\t</template>\n\t\t\t\t\t<template #action>\n\t\t\t\t\t\t<NcButton v-if=\"onRetry\" variant=\"primary\" @click=\"onRetry\">\n\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t<Refresh :size=\"20\" />\n\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t{{ retryLabel }}\n\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t@slot error-actions\n\t\t\t\t\t\t\t@description Extra buttons rendered inside the default error\n\t\t\t\t\t\t\tsurface's action area, after the (optional) Retry button.\n\t\t\t\t\t\t-->\n\t\t\t\t\t\t<slot name=\"error-actions\" />\n\t\t\t\t\t</template>\n\t\t\t\t</NcEmptyContent>\n\t\t\t</slot>\n\t\t</div>\n\n\t\t<!-- Empty state -->\n\t\t<div v-else-if=\"empty\" class=\"cn-detail-page__empty\">\n\t\t\t<!--\n\t\t\t\t@slot empty\n\t\t\t\t@description Replace the default empty-state `<NcEmptyContent>` surface.\n\t\t\t-->\n\t\t\t<slot name=\"empty\">\n\t\t\t\t<NcEmptyContent :name=\"emptyLabel\">\n\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t<InformationOutline :size=\"48\" />\n\t\t\t\t\t</template>\n\t\t\t\t\t<template #action>\n\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t@slot empty-actions\n\t\t\t\t\t\t\t@description Buttons rendered inside the default empty-state\n\t\t\t\t\t\t\taction area.\n\t\t\t\t\t\t-->\n\t\t\t\t\t\t<slot name=\"empty-actions\" />\n\t\t\t\t\t</template>\n\t\t\t\t</NcEmptyContent>\n\t\t\t</slot>\n\t\t</div>\n\n\t\t<!-- Main content -->\n\t\t<div v-else class=\"cn-detail-page__body\">\n\t\t\t<div v-if=\"$slots['before-body'] || $slots['before-body']\" class=\"cn-detail-page__before-body\">\n\t\t\t\t<!--\n\t\t\t\t\t@slot before-body\n\t\t\t\t\t@description Content rendered at the top of the body, above the grid\n\t\t\t\t\tlayout / stats / schema-driven auto-body (Data + Related). Use it to\n\t\t\t\t\tsurface page-level widgets (e.g. a KPI/insights dashboard) in the body\n\t\t\t\t\tbelow the header+actions line without suppressing the auto Data/Related\n\t\t\t\t\tsections (which a `default` slot override would).\n\t\t\t\t\t@binding {object} object The resolved record.\n\t\t\t\t\t@binding {object} schema The resolved schema.\n\t\t\t\t\t@binding {string} objectType The resolved object type.\n\t\t\t\t\t@binding {string} objectId The resolved object id.\n\t\t\t\t\t@binding {object} store The effective object store.\n\t\t\t\t-->\n\t\t\t\t<slot\n\t\t\t\t\tname=\"before-body\"\n\t\t\t\t\t:object=\"resolvedObject\"\n\t\t\t\t\t:schema=\"currentSchema\"\n\t\t\t\t\t:objectType=\"resolvedObjectType\"\n\t\t\t\t\t:objectId=\"objectId\"\n\t\t\t\t\t:store=\"effectiveObjectStore\" />\n\t\t\t</div>\n\n\t\t\t<!-- Declarative in-body sections, `placement: \"before-body\"` —\n\t\t\t above the grid / stats / auto-body. -->\n\t\t\t<CnBodySections\n\t\t\t\tv-if=\"hasBodyWidgets\"\n\t\t\t\t:sections=\"bodyWidgets\"\n\t\t\t\t:context=\"sectionContext\"\n\t\t\t\tplacement=\"before-body\"\n\t\t\t\tdata-testid=\"cn-detail-body-sections-before-body\" />\n\n\t\t\t<!-- Adjustable widget grid (GridStack). The detail body is, at its\n\t\t\t core, a real drag/resize grid: by default it is seeded with the\n\t\t\t schema-driven Data + Related widgets (see `bodyGridLayout`), but in\n\t\t\t Buildiq edit mode widgets can be moved, resized, configured and\n\t\t\t added. Explicit `layout` + `widgets` props (manifest grid pages)\n\t\t\t feed the same engine, so hand-authored grid pages also become\n\t\t\t draggable. -->\n\t\t\t<!-- :key remounts the grid when in-app edit mode flips (ADR-041):\n\t\t\t the manifest is raw (non-reactive) until useManifestEditor\n\t\t\t observes it in place, so a grid mounted pre-edit never\n\t\t\t subscribed to the layout/widgets arrays — in-place pushes\n\t\t\t (Add widget) keep the same array identity and can't re-render\n\t\t\t it. One remount per edit flip re-subscribes it. -->\n\t\t\t<CnDashboardGrid\n\t\t\t\tv-if=\"hasBodyGrid\"\n\t\t\t\t:key=\"`cn-detail-grid-${editingBody ? 'editing' : 'live'}`\"\n\t\t\t\t:layout=\"bodyGridLayout\"\n\t\t\t\t:editable=\"editingBody\"\n\t\t\t\t:columns=\"12\"\n\t\t\t\t:columnOpts=\"columnOpts\"\n\t\t\t\tclass=\"cn-detail-page__grid\"\n\t\t\t\t@layoutChange=\"onBodyLayoutChange\">\n\t\t\t\t<template #widget=\"{ item }\">\n\t\t\t\t\t<div\n\t\t\t\t\t\tclass=\"cn-detail-page__grid-item\"\n\t\t\t\t\t\t:class=\"{ 'cn-detail-page__grid-item--fit': !!item.sizeToContent }\"\n\t\t\t\t\t\t:aria-labelledby=\"showGridTitle(item) ? `widget-title-${item.id}` : undefined\">\n\t\t\t\t\t\t<!-- In-app edit overlay (ADR-041): a configure cog appears on\n\t\t\t\t\t\t EVERY grid widget while the page is in Buildiq edit mode,\n\t\t\t\t\t\t as it does on CnDashboardPage. It was gated on the type\n\t\t\t\t\t\t having a registered config form, which left a `custom`\n\t\t\t\t\t\t widget and an `integration` leaf with no cog at all: they\n\t\t\t\t\t\t could be dragged and resized but never configured or\n\t\t\t\t\t\t removed, because the modal's own Delete affordance is the\n\t\t\t\t\t\t only way off the page. The modal already handles a type\n\t\t\t\t\t\t without a form (title, icon, style, delete), so the gate\n\t\t\t\t\t\t bought nothing. -->\n\t\t\t\t\t\t<div v-if=\"showsCog(item)\" class=\"cn-detail-page__widget-edit\">\n\t\t\t\t\t\t\t<NcButton variant=\"tertiary\" :aria-label=\"t('nextcloud-vue', 'Configure widget')\" @click=\"configureWidget(item)\">\n\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t<Cog :size=\"18\" />\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<!-- Section heading ONLY for consumer-supplied bare-content slots.\n\t\t\t\t\t\t Built-in widgets (data / related / integration / catalog)\n\t\t\t\t\t\t render their own titled card header, so a grid <h3> here would\n\t\t\t\t\t\t duplicate the title above the widget. -->\n\t\t\t\t\t\t<h3\n\t\t\t\t\t\t\tv-if=\"showGridTitle(item)\"\n\t\t\t\t\t\t\t:id=\"`widget-title-${item.id}`\"\n\t\t\t\t\t\t\tclass=\"cn-detail-page__widget-title\">\n\t\t\t\t\t\t\t{{ gridTitle(item) }}\n\t\t\t\t\t\t</h3>\n\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t@slot `widget-${item.widgetId}`\n\t\t\t\t\t\t\t@description Per-widget slot whose name is `widget-<widgetId>`. Use\n\t\t\t\t\t\t\tit to inject custom widget content into a grid slot. Default\n\t\t\t\t\t\t\tfallback renders a registry widget: `type: 'data'` renders the\n\t\t\t\t\t\t\tschema-driven data widget; `type: 'related'` the related-objects\n\t\t\t\t\t\t\twidget; `type: 'integration'` resolves from the integration\n\t\t\t\t\t\t\tregistry; any other content-driven catalog type (stat / chart /\n\t\t\t\t\t\t\tdelta / gauge / object-list / …) renders its registered renderer.\n\n\t\t\t\t\t\t\tThe page's object context is bound alongside the widget\n\t\t\t\t\t\t\tdescriptor because a `type: \"custom\"` widget is not a template —\n\t\t\t\t\t\t\tCnPageRenderer mounts the mapped component as\n\t\t\t\t\t\t\t`<component v-bind=\"slotProps\" />`, so whatever THIS slot binds\n\t\t\t\t\t\t\tIS that widget's entire prop set. Binding only `item`/`widget`\n\t\t\t\t\t\t\ttherefore left every custom widget that declares `objectId`\n\t\t\t\t\t\t\tsitting on its own `default: ''` — and an empty id does not\n\t\t\t\t\t\t\terror, it widens the widget's OpenRegister filter to the whole\n\t\t\t\t\t\t\tcollection (decidiq#968: a voting-round panel filtering on\n\t\t\t\t\t\t\t`relations.motion: ''` listed every round in the instance, so a\n\t\t\t\t\t\t\tvote could be cast against another motion's round). Widgets that\n\t\t\t\t\t\t\tdeclare none of these props are unaffected — this is purely\n\t\t\t\t\t\t\tadditive.\n\n\t\t\t\t\t\t\t`objectId` is bound from the PROP, never read back off the loaded\n\t\t\t\t\t\t\trecord: `currentObject` / `resolvedObject` are themselves keyed by\n\t\t\t\t\t\t\t`objectId`, and the record is null for the first frames of a\n\t\t\t\t\t\t\tdetail page — the same \"the record has not arrived yet\" race\n\t\t\t\t\t\t\t`editFormAwaitingRecord` guards (#850). The route param reaches\n\t\t\t\t\t\t\tthe prop through CnPageRenderer, which maps `params.id` →\n\t\t\t\t\t\t\t`objectId`, so the id is there on the first render while `object`\n\t\t\t\t\t\t\tis not.\n\t\t\t\t\t\t\t@binding {object} item Layout item descriptor.\n\t\t\t\t\t\t\t@binding {object} widget Resolved widget definition.\n\t\t\t\t\t\t\t@binding {string|number} objectId This record's id. Unlike `object`\n\t\t\t\t\t\t\tit is present on the very first render, because it comes from the route.\n\t\t\t\t\t\t\t@binding {object} object The loaded record, or null while it is\n\t\t\t\t\t\t\tstill being fetched.\n\t\t\t\t\t\t\t@binding {object} objectData Alias of `object`, spelled the way widget\n\t\t\t\t\t\t\tcomponents declare the prop (`objectData`).\n\t\t\t\t\t\t\t@binding {string} objectType Resolved object type slug.\n\t\t\t\t\t\t\t@binding {string} register Register slug of this page.\n\t\t\t\t\t\t\t@binding {string} schema Schema slug of this page.\n\t\t\t\t\t\t-->\n\t\t\t\t\t\t<slot\n\t\t\t\t\t\t\t:name=\"`widget-${item.widgetId}`\"\n\t\t\t\t\t\t\t:item=\"item\"\n\t\t\t\t\t\t\t:widget=\"findWidget(item)\"\n\t\t\t\t\t\t\t:objectId=\"objectId\"\n\t\t\t\t\t\t\t:object=\"resolvedObject\"\n\t\t\t\t\t\t\t:objectData=\"resolvedObject\"\n\t\t\t\t\t\t\t:objectType=\"resolvedObjectType\"\n\t\t\t\t\t\t\t:register=\"register\"\n\t\t\t\t\t\t\t:schema=\"schema\">\n\t\t\t\t\t\t\t<CnDetailWidgetHost\n\t\t\t\t\t\t\t\t:widget=\"findWidget(item)\"\n\t\t\t\t\t\t\t\tchrome=\"card\"\n\t\t\t\t\t\t\t\t:showCardTitle=\"showCardTitle(item)\"\n\t\t\t\t\t\t\t\t:objectId=\"objectId\"\n\t\t\t\t\t\t\t\t:object=\"currentObject\"\n\t\t\t\t\t\t\t\t:objectType=\"resolvedObjectType\"\n\t\t\t\t\t\t\t\t:schemaObject=\"currentSchema\"\n\t\t\t\t\t\t\t\t:register=\"register\"\n\t\t\t\t\t\t\t\t:schema=\"schema\"\n\t\t\t\t\t\t\t\t:store=\"effectiveObjectStore\"\n\t\t\t\t\t\t\t\t:surface=\"surface\"\n\t\t\t\t\t\t\t\t:integrationContext=\"effectiveIntegrationContext\"\n\t\t\t\t\t\t\t\t:hideEmpty=\"hideEmpty\"\n\t\t\t\t\t\t\t\t:cnRegistry=\"cnRegistry\"\n\t\t\t\t\t\t\t\t:availableWidgets=\"bodyGridWidgets\"\n\t\t\t\t\t\t\t\t@geoSaved=\"onGeoSaved\"\n\t\t\t\t\t\t\t\t@openIntegration=\"onAutoBodyOpenIntegration\" />\n\t\t\t\t\t\t</slot>\n\t\t\t\t\t</div>\n\t\t\t\t</template>\n\t\t\t</CnDashboardGrid>\n\n\t\t\t<!-- Statistics table -->\n\t\t\t<div v-if=\"hasStats\" class=\"cn-detail-page__stats\">\n\t\t\t\t<!--\n\t\t\t\t\t@slot stats-header\n\t\t\t\t\t@description Replace the heading above the stats table. Default\n\t\t\t\t\tcontent: an `<h3>` showing `statsTitle`.\n\t\t\t\t-->\n\t\t\t\t<slot name=\"stats-header\">\n\t\t\t\t\t<h3 v-if=\"statsTitle\" class=\"cn-detail-page__section-title\">\n\t\t\t\t\t\t{{ resolvedStatsTitle }}\n\t\t\t\t\t</h3>\n\t\t\t\t</slot>\n\t\t\t\t<table class=\"cn-detail-page__stats-table\">\n\t\t\t\t\t<thead v-if=\"statsColumns.length > 0\">\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<th v-for=\"col in statsColumns\"\n\t\t\t\t\t\t\t\t:key=\"col.key\"\n\t\t\t\t\t\t\t\tscope=\"col\"\n\t\t\t\t\t\t\t\t:class=\"col.align ? 'cn-detail-page__stats-cell--' + col.align : ''\">\n\t\t\t\t\t\t\t\t{{ col.label }}\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</thead>\n\t\t\t\t\t<tbody>\n\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t@slot stats-rows\n\t\t\t\t\t\t\t@description Replace the default rendering of the `statsRows`\n\t\t\t\t\t\t\tprop. Use when rows need custom formatting per column.\n\t\t\t\t\t\t-->\n\t\t\t\t\t\t<slot name=\"stats-rows\">\n\t\t\t\t\t\t\t<tr v-for=\"(row, index) in statsRows\" :key=\"index\" :class=\"{ 'cn-detail-page__stats-row--sub': row.indent }\">\n\t\t\t\t\t\t\t\t<td v-for=\"col in statsColumns\" :key=\"col.key\" :class=\"[row.indent ? 'cn-detail-page__stats-cell--indented' : '', col.align ? 'cn-detail-page__stats-cell--' + col.align : '']\">\n\t\t\t\t\t\t\t\t\t{{ row[col.key] !== undefined ? row[col.key] : '-' }}\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t</slot>\n\t\t\t\t\t</tbody>\n\t\t\t\t</table>\n\t\t\t</div>\n\n\t\t\t<!-- Default vertical stacking mode. The schema-driven auto-body (Data +\n\t\t\t Related) is now rendered by the adjustable grid above (seeded by\n\t\t\t `bodyGridLayout`), so this branch only carries hand-authored\n\t\t\t default-slot content when no widget grid is active. -->\n\t\t\t<div v-else class=\"cn-detail-page__content\">\n\t\t\t\t<!-- Default content -->\n\t\t\t\t<div v-if=\"!hasBodyGrid\" class=\"cn-detail-page__content\">\n\t\t\t\t\t<!--\n\t\t\t\t\t\t@slot default\n\t\t\t\t\t\t@description Main body content rendered when no grid layout, no\n\t\t\t\t\t\tstats table, and no schema-driven auto-body apply. Use it to ship\n\t\t\t\t\t\ta hand-authored detail page.\n\t\t\t\t\t-->\n\t\t\t\t\t<slot />\n\t\t\t\t</div>\n\n\t\t\t\t<!-- Sections slot — additional content below stats -->\n\t\t\t\t<div v-if=\"$slots.sections\" class=\"cn-detail-page__sections\">\n\t\t\t\t\t<!--\n\t\t\t\t\t\t@slot sections\n\t\t\t\t\t\t@description Additional vertically-stacked content rendered below\n\t\t\t\t\t\tthe default body / stats table.\n\t\t\t\t\t-->\n\t\t\t\t\t<slot name=\"sections\" />\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- Declarative in-body sections, `placement: \"after-data\"` —\n\t\t\t below the data/auto-body, above the related-object lists. -->\n\t\t\t<CnBodySections\n\t\t\t\tv-if=\"hasBodyWidgets\"\n\t\t\t\t:sections=\"bodyWidgets\"\n\t\t\t\t:context=\"sectionContext\"\n\t\t\t\tplacement=\"after-data\"\n\t\t\t\tdata-testid=\"cn-detail-body-sections-after-data\" />\n\n\t\t\t<!-- Declarative related-object list sections (manifest\n\t\t\t `config.relatedCollections`). Rendered below the detail body;\n\t\t\t each section's filter is scoped to this object via @objectId.\n\t\t\t An optional relation-link button opens CnRelationLinkModal. -->\n\t\t\t<div\n\t\t\t\tv-if=\"(relatedCollections && relatedCollections.length > 0) || (relationLinks && relationLinks.length > 0)\"\n\t\t\t\tclass=\"cn-detail-page__related-collections\">\n\t\t\t\t<div v-if=\"relationLinks && relationLinks.length > 0\" class=\"cn-detail-page__relation-links\">\n\t\t\t\t\t<NcButton\n\t\t\t\t\t\tv-for=\"(link, li) in relationLinks\"\n\t\t\t\t\t\t:key=\"li\"\n\t\t\t\t\t\tclass=\"cn-detail-page__relation-link-button\"\n\t\t\t\t\t\t:data-testid=\"`cn-detail-relation-link-${li}`\"\n\t\t\t\t\t\t@click=\"openRelationLink(link)\">\n\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t<Plus :size=\"18\" />\n\t\t\t\t\t\t</template>\n\t\t\t\t\t\t{{ link.label || t('nextcloud-vue', 'Link related object') }}\n\t\t\t\t\t</NcButton>\n\t\t\t\t</div>\n\t\t\t\t<CnRelatedCollections\n\t\t\t\t\tv-if=\"relatedCollections && relatedCollections.length > 0\"\n\t\t\t\t\t:collections=\"relatedCollections\"\n\t\t\t\t\t@rowClick=\"onRelatedRowClick\" />\n\t\t\t</div>\n\n\t\t\t<!-- Declarative in-body sections, `placement: \"after-related\"` —\n\t\t\t below the related-object lists. -->\n\t\t\t<CnBodySections\n\t\t\t\tv-if=\"hasBodyWidgets\"\n\t\t\t\t:sections=\"bodyWidgets\"\n\t\t\t\t:context=\"sectionContext\"\n\t\t\t\tplacement=\"after-related\"\n\t\t\t\tdata-testid=\"cn-detail-body-sections-after-related\" />\n\n\t\t\t<!-- Declarative in-body sections, `placement: \"end\"` (the default\n\t\t\t placement) — the last body content, above the footer. -->\n\t\t\t<CnBodySections\n\t\t\t\tv-if=\"hasBodyWidgets\"\n\t\t\t\t:sections=\"endPlacementSections\"\n\t\t\t\t:context=\"sectionContext\"\n\t\t\t\t:placement=\"null\"\n\t\t\t\tdata-testid=\"cn-detail-body-sections-end\" />\n\n\t\t\t<!-- Footer -->\n\t\t\t<div v-if=\"$slots.footer\" class=\"cn-detail-page__footer\">\n\t\t\t\t<!--\n\t\t\t\t\t@slot footer\n\t\t\t\t\t@description Footer surface rendered below the detail-page body. Use\n\t\t\t\t\tit for save/cancel button rows or status text.\n\t\t\t\t-->\n\t\t\t\t<slot name=\"footer\" />\n\t\t\t</div>\n\t\t</div>\n\n\t\t<!-- Per-widget style/config editor (ADR-041). Opened by the per-widget\n\t\t configure cog while in Buildiq edit mode; the modal's own Delete\n\t\t button removes the widget from the grid. -->\n\t\t<CnWidgetStyleEditorModal\n\t\t\tv-if=\"showWidgetConfig\"\n\t\t\t:show=\"showWidgetConfig\"\n\t\t\t:widget=\"configWidget\"\n\t\t\t:deletable=\"true\"\n\t\t\t@save=\"onWidgetConfigSave\"\n\t\t\t@delete=\"onWidgetConfigDelete\"\n\t\t\t@close=\"showWidgetConfig = false\" />\n\n\t\t<!-- @slot form-dialog Replace the built-in create/edit form dialog (use CnFormDialog or CnAdvancedFormDialog). Deliberately the SAME slot name and the same scope as CnIndexPage's `form-dialog`, so one replacement component serves both pages and an app author learns one contract, not two. Covers both of this page's built-in dialogs — the create archetype's empty form and the record edit form — which are mutually exclusive, exactly as CnIndexPage's single slot covers create and edit. -->\n\t\t<!-- @binding {boolean} show Whether the form dialog is currently visible. -->\n\t\t<!-- @binding {?object} item The record being edited; in create mode the route-derived prefill, or null when there is nothing to prefill. -->\n\t\t<!-- @binding {object} schema The effective JSON schema driving the form. Transform this — rather than replacing the save path — to splice a runtime vocabulary into an enum. -->\n\t\t<!-- @binding {Function} confirm Persists the form data through the page's own save path and emits `created`/`edited`. Call this instead of saving in the replacement dialog, so a create or edit made there behaves exactly like one made in the built-in dialog. RESOLVES to a `{ success: true, data }` / `{ error }` result, which a replacement rendering its own CnFormDialog must hand back to that dialog's `setResult()`: CnFormDialog sets `loading` on submit and only `setResult` clears it, and `no-close` is bound to `loading`, so a replacement that ignores the result locks its own modal open on both success and failure. -->\n\t\t<!-- @binding {Function} close Closes the form dialog — in create mode this is the \"dismissed without saving\" path, which navigates back so the user is not stranded on an id-less page. -->\n\t\t<!--\n\t\t `show` and `confirm` are bound as PROPS, not left as listeners on\n\t\t the default children. A manifest-declared replacement is mounted by\n\t\t CnPageRenderer as `<component :is=… v-bind=\"slotProps\" />`, which\n\t\t binds props only — so a listener is unreachable from a manifest\n\t\t even in principle, and a replacement dialog could render and close\n\t\t but never save (openconnector#1150, fixed the same way on\n\t\t CnIndexPage).\n\n\t\t The two default children below are UNCHANGED and still wire their\n\t\t own `@confirm` / `@close` directly, so a page that passes no slot\n\t\t renders and behaves exactly as it did before this slot existed.\n\t\t-->\n\t\t<slot\n\t\t\tname=\"form-dialog\"\n\t\t\t:show=\"formDialogVisible\"\n\t\t\t:item=\"formDialogItem\"\n\t\t\t:schema=\"currentSchema\"\n\t\t\t:confirm=\"onFormDialogConfirm\"\n\t\t\t:close=\"onFormDialogClose\">\n\t\t\t<!-- Create archetype (ADR-062): a schema-bound `type:\"detail\"` page with\n\t\t\t no object id renders an empty create form for its schema instead of a\n\t\t\t blank page. Save POSTs the object and navigates to its detail route\n\t\t\t (or back); prefill comes from the route query. -->\n\t\t\t<CnFormDialog\n\t\t\t\tv-if=\"isCreateMode && currentSchema\"\n\t\t\t\tref=\"createFormDialog\"\n\t\t\t\t:schema=\"currentSchema\"\n\t\t\t\t:item=\"createPrefill\"\n\t\t\t\t:register=\"register\"\n\t\t\t\t:dialogTitle=\"title || undefined\"\n\t\t\t\t:excludeFields=\"excludeFields\"\n\t\t\t\t:includeFields=\"includeFields\"\n\t\t\t\t:fieldOverrides=\"fieldOverrides\"\n\t\t\t\t:size=\"formSize\"\n\t\t\t\t:columns=\"formColumns\"\n\t\t\t\t@confirm=\"onCreateFormConfirm\"\n\t\t\t\t@close=\"onCreateFormClose\" />\n\n\t\t\t<!-- Record edit form. Same component and same schema the index table's\n\t\t\t modal used; the difference is that it is reached from the record,\n\t\t\t with the record's own page around it.\n\n\t\t\t Waits for the RECORD as well as the schema. `currentObject` is a\n\t\t\t store read that is null until this page's own fetch lands, and a\n\t\t\t dialog opened before then shows an empty form for a record that\n\t\t\t has values — which the user can type into, and whose Save would\n\t\t\t PUT those blanks over the record. -->\n\t\t\t<CnFormDialog\n\t\t\t\tv-if=\"editFormOpen && currentSchema && !editFormAwaitingRecord\"\n\t\t\t\tref=\"editFormDialog\"\n\t\t\t\t:schema=\"currentSchema\"\n\t\t\t\t:item=\"currentObject\"\n\t\t\t\t:register=\"register\"\n\t\t\t\t:dialogTitle=\"editActionLabel\"\n\t\t\t\t:excludeFields=\"excludeFields\"\n\t\t\t\t:includeFields=\"includeFields\"\n\t\t\t\t:fieldOverrides=\"fieldOverrides\"\n\t\t\t\t:size=\"formSize\"\n\t\t\t\t:columns=\"formColumns\"\n\t\t\t\t@confirm=\"onEditFormConfirm\"\n\t\t\t\t@close=\"closeEditForm\" />\n\t\t</slot>\n\n\t\t<!-- Relation-link modal (manifest `config.relationLinks`): async-search a\n\t\t target schema and patch a FK on the current object. -->\n\t\t<CnRelationLinkModal\n\t\t\tv-if=\"activeRelationLink\"\n\t\t\t:title=\"activeRelationLink.title || undefined\"\n\t\t\t:selectLabel=\"activeRelationLink.selectLabel || undefined\"\n\t\t\t:register=\"activeRelationLink.register\"\n\t\t\t:schema=\"activeRelationLink.schema\"\n\t\t\t:labelField=\"activeRelationLink.labelField || 'name'\"\n\t\t\t:allowCreate=\"activeRelationLink.allowCreate === true\"\n\t\t\t:currentType=\"resolvedObjectType\"\n\t\t\t:currentObject=\"currentObject || {}\"\n\t\t\t:fkField=\"activeRelationLink.fkField\"\n\t\t\t@linked=\"onRelationLinked\"\n\t\t\t@close=\"activeRelationLink = null\" />\n\t</div>\n</template>\n\n<script>\nimport { subscribe, unsubscribe } from '@nextcloud/event-bus'\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcActionButton, NcActionLink, NcActionSeparator, NcButton, NcEmptyContent, NcLoadingIcon } from '@nextcloud/vue'\nimport { provide, ref, watch } from 'vue'\nimport AlertCircleOutline from 'vue-material-design-icons/AlertCircleOutline.vue'\nimport ArrowLeft from 'vue-material-design-icons/ArrowLeft.vue'\nimport ChevronLeft from 'vue-material-design-icons/ChevronLeft.vue'\nimport ChevronRight from 'vue-material-design-icons/ChevronRight.vue'\nimport Cog from 'vue-material-design-icons/Cog.vue'\nimport FileQuestionOutline from 'vue-material-design-icons/FileQuestionOutline.vue'\nimport InformationOutline from 'vue-material-design-icons/InformationOutline.vue'\nimport Pencil from 'vue-material-design-icons/Pencil.vue'\nimport Plus from 'vue-material-design-icons/Plus.vue'\nimport Refresh from 'vue-material-design-icons/Refresh.vue'\nimport CnRelationLinkModal from '../../dialogs/CnRelationLinkModal.vue'\nimport CnWidgetStyleEditorModal from '../../dialogs/CnWidgetStyleEditorModal.vue'\nimport CnActionsMenu from '../CnActionsMenu/CnActionsMenu.vue'\nimport CnBodySections from '../CnBodySections/CnBodySections.vue'\nimport CnBuildiqEditButton from '../CnBuildiqEditButton/CnBuildiqEditButton.vue'\nimport CnDashboardGrid from '../CnDashboardGrid/CnDashboardGrid.vue'\nimport CnDetailWidgetHost from '../CnDetailWidgetHost/CnDetailWidgetHost.vue'\nimport CnFormDialog from '../CnFormDialog/CnFormDialog.vue'\nimport CnLifecycleActions from '../CnLifecycleActions/CnLifecycleActions.vue'\nimport CnLockedBanner from '../CnLockedBanner/CnLockedBanner.vue'\nimport CnRelatedCollections from '../CnRelatedCollections/CnRelatedCollections.vue'\nimport CnSummaryAggregates from '../CnSummaryAggregates/CnSummaryAggregates.vue'\nimport CnTranslatedBadge from '../CnTranslatedBadge/CnTranslatedBadge.vue'\nimport { useIntegrationRegistry } from '../../composables/useIntegrationRegistry.js'\nimport { useObjectLock } from '../../composables/useObjectLock.js'\nimport { useObjectPresence } from '../../composables/useObjectPresence.js'\nimport { useObjectSubscription } from '../../composables/useObjectSubscription.js'\nimport { gridLayout } from '../../mixins/gridLayout.js'\nimport { useObjectStore } from '../../store/index.js'\nimport { isAppInstalled } from '../../utils/appInstalled.js'\nimport { compactLayoutRows } from '../../utils/dashboardPlacement.js'\nimport { defaultDetailGrid } from '../../utils/defaultDetailGrid.js'\nimport { cnGridCellStyle, hasGridRow } from '../../utils/grid.js'\nimport { slotRenders } from '../../utils/slotContent.js'\nimport {\n\tisCardWidgetDef,\n\tisContentOnlyWidgetDef,\n\tisDataWidgetDef,\n\tisGeoWidgetDef,\n\tisRelatedWidgetDef,\n\tresolveRegistryRenderer,\n\twidgetContentOf,\n\twidgetTitleOf,\n} from '../../utils/widgetDispatch.js'\nimport { CnActionButtons } from '../CnActionButtons/index.js'\nimport { CnIcon } from '../CnIcon/index.js'\nimport { getWidgetTypeEntry } from '../CnWidgetGrid/dashboardWidgetRegistry.js'\n\nimport '../CnWidgetGrid/registerDashboardWidgets.js'\n\n/**\n * Responsive column table for a detail body, measured against the GRID element.\n *\n * ONE threshold, and deliberately no steps between. `moveScale` rescales the\n * authored geometry into the new count, so an intermediate width turns a\n * 12-column record into fractional positions nobody placed: a `gridWidth: 3`\n * tile becomes 1 of 4, a `gridWidth: 9` panel becomes 3 of 4, and widgets land\n * left, centre or right depending purely on how the division rounded. That reads\n * as a broken page rather than a narrow one. A record is authored at 12 columns\n * or it is a single stacked column; the sizes in between are not designs.\n *\n * 1000px is where the 12-column geometry stops working rather than merely\n * tightening: it puts a `gridWidth: 3` side panel — Timeline, Flow runs — under\n * 250px, which is below its own title.\n *\n * `breakpointForWindow` is FALSE, unlike `getDashboardColumnOpts()`: a page in a\n * split pane sits in a narrow container on a wide window, so measuring the window\n * is measuring the wrong box and the grid would never reflow.\n *\n * `columnMax` is set EXPLICITLY. Above the top breakpoint GridStack assigns\n * `newColumn = columnOpts.columnMax`, and `column(undefined)` silently no-ops, so\n * a grid that once narrowed would never widen again.\n */\nconst DEFAULT_DETAIL_COLUMN_OPTS = Object.freeze({\n\tcolumnMax: 12,\n\tbreakpoints: [\n\t\t{ w: 1000, c: 1 },\n\t],\n\tlayout: 'moveScale',\n\tbreakpointForWindow: false,\n})\n\n/**\n * Event-bus channel a page-level refresh is announced on. The page's own\n * Actions menu emits it, the manifest `refresh` / `api-call` actions bump it,\n * and an app's own dialog emits it after a successful write.\n */\nconst PAGE_REFRESH_CHANNEL = 'cn:page:refresh'\n\n/** Surfaces understood by the pluggable integration registry (AD-19). */\nconst INTEGRATION_SURFACES = ['user-dashboard', 'app-dashboard', 'detail-page', 'single-entity']\n\n/**\n * CnDetailPage — Generic detail/overview page.\n *\n * Supports two layout modes:\n * 1. **Default (vertical stacking):** Content provided via default slot, cards stack vertically.\n * 2. **Grid layout:** When `layout` and `widgets` props are provided, content renders in a\n * 12-column CSS grid with `#widget-{widgetId}` scoped slots. Same API as CnDashboardPage.\n *\n * Basic usage (vertical stacking)\n *\n * A simpler alternative to CnIndexPage for pages that display detail info,\n * statistics, charts, or card grids — without multi-object tables or CRUD\n * dialogs. Provides a consistent layout with header, loading/error/empty\n * states, a statistics table, and flexible content slots.\n *\n * Basic usage with stats table and content\n * ```vue\n * <CnDetailPage\n * title=\"Register Overview\"\n * description=\"Statistics and schema details\"\n * icon=\"DatabaseOutline\"\n * :stats-title=\"'Register Statistics'\"\n * :stats-columns=\"[\n * { key: 'type', label: 'Type' },\n * { key: 'total', label: 'Total' },\n * { key: 'size', label: 'Size' },\n * ]\"\n * :stats-rows=\"[\n * { type: 'Objects', total: 150, size: '2.4 MB' },\n * { type: 'Files', total: 42, size: '1.1 MB' },\n * ]\"\n * :loading=\"isLoading\">\n * <ChartGrid :data=\"chartData\" />\n * <SchemaCards :schemas=\"schemas\" />\n * </CnDetailPage>\n * ```\n *\n * Grid layout mode\n * ```vue\n * <CnDetailPage\n * title=\"Character Detail\"\n * :layout=\"[\n * { id: 1, widgetId: 'info', gridX: 0, gridY: 0, gridWidth: 8 },\n * { id: 2, widgetId: 'stats', gridX: 8, gridY: 0, gridWidth: 4 },\n * ]\"\n * :widgets=\"[\n * { id: 'info', title: 'Character Info' },\n * { id: 'stats', title: 'Statistics' },\n * ]\">\n * <template #widget-info=\"{ item, widget }\">\n * <CharacterInfoCard :character=\"character\" />\n * </template>\n * <template #widget-stats=\"{ item, widget }\">\n * <StatsCard :stats=\"character.stats\" />\n * </template>\n * ```\n *\n * With header actions and error handling\n * ```vue\n * <CnDetailPage\n * title=\"Schema Details\"\n * :error=\"hasError\"\n * error-message=\"Failed to load schema\"\n * :on-retry=\"loadSchema\">\n * <template #actions>\n * <NcButton @click=\"editSchema\">Edit</NcButton>\n * </template>\n * <DetailContent :schema=\"schema\" />\n * </CnDetailPage>\n * ```\n */\nexport default {\n\tname: 'CnDetailPage',\n\n\tcomponents: {\n\t\tChevronLeft,\n\t\tChevronRight,\n\t\tNcActionButton,\n\t\tNcActionLink,\n\t\tNcActionSeparator,\n\t\tNcButton,\n\t\tNcEmptyContent,\n\t\tNcLoadingIcon,\n\t\tCnIcon,\n\t\tAlertCircleOutline,\n\t\tArrowLeft,\n\t\tFileQuestionOutline,\n\t\tInformationOutline,\n\t\tRefresh,\n\t\tCnActionsMenu,\n\t\tCnBuildiqEditButton,\n\t\tCnLockedBanner,\n\t\tCnDetailWidgetHost,\n\t\tCnFormDialog,\n\t\tCnDashboardGrid,\n\t\tCnLifecycleActions,\n\t\tCnActionButtons,\n\t\tCnSummaryAggregates,\n\t\tCnRelatedCollections,\n\t\tCnBodySections,\n\t\tCnTranslatedBadge,\n\t\tCnWidgetStyleEditorModal,\n\t\tCnRelationLinkModal,\n\t\tCog,\n\t\tPlus,\n\t\tPencil,\n\t},\n\n\tmixins: [gridLayout],\n\n\tinject: {\n\t\t/**\n\t\t * Consumer widget registry provided by CnAppRoot — the SAME injection\n\t\t * CnWidgetGrid reads. A consuming app registers its own components\n\t\t * here (hrmq registers `stat`, `chart`, `actions`,\n\t\t * `lifecycle-actions`, …), and per REQ-MVR-005 a consumer entry\n\t\t * OVERRIDES a built-in of the same name.\n\t\t *\n\t\t * Without this, a detail page could only render library widgets: an\n\t\t * app's own widget resolved on the CnWidgetGrid path and vanished on\n\t\t * this one, which is half of why the two paths disagreed.\n\t\t */\n\t\tcnRegistry: { default: () => ({}) },\n\t\tobjectSidebarState: { default: null },\n\t\t/**\n\t\t * Reactive AI context holder provided by CnAppRoot. This page\n\t\t * component writes pageKind, objectUuid, registerSlug, schemaSlug\n\t\t * in created() and watches for changes. Resets on beforeUnmount().\n\t\t */\n\t\tcnAiContext: { default: null },\n\t\t/**\n\t\t * Buildiq in-app edit state (ADR-041), a ref provided by CnAppRoot /\n\t\t * the edit button. When truthy, configurable grid widgets show a\n\t\t * configure cog. Defaults to null (no edit affordance) for standalone use.\n\t\t */\n\t\tcnEditingBody: { default: null },\n\t\t/**\n\t\t * Host translate function provided by CnAppRoot as\n\t\t * `cnTranslate: this.translate` (bound to the host app's id). The\n\t\t * manifest-authored page/section/widget titles are run through it.\n\t\t * Defaults to an identity function so an untranslated key renders\n\t\t * as itself. Record data (the resolved object's display name) is\n\t\t * NEVER translated — only manifest chrome is.\n\t\t */\n\t\tcnTranslate: { default: () => (key) => key },\n\t},\n\n\tprops: {\n\t\t/** Page title */\n\t\ttitle: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * NcDialog size for this page's create and edit form dialogs.\n\t\t *\n\t\t * CnFormDialog has taken a `size` since it shipped; this page never\n\t\t * passed one, so both its forms were stuck at `normal` however many\n\t\t * properties the schema declared.\n\t\t */\n\t\tformSize: {\n\t\t\ttype: String,\n\t\t\tdefault: 'normal',\n\t\t},\n\n\t\t/**\n\t\t * How many columns the create and edit forms flow their fields into.\n\t\t *\n\t\t * Pair `2` with `formSize: 'large'`, or the two columns are merely two\n\t\t * narrow ones. CnFormDialog collapses back to one column below 700px\n\t\t * on its own, so this is safe on a narrow viewport.\n\t\t */\n\t\tformColumns: {\n\t\t\ttype: Number,\n\t\t\tdefault: 1,\n\t\t\tvalidator: (value) => value === 1 || value === 2,\n\t\t},\n\n\t\t/**\n\t\t * Fields the create and edit forms ask for, in this order. Null asks for\n\t\t * every property the schema declares.\n\t\t *\n\t\t * Same three keys as CnIndexPage, so one manifest describes the record's\n\t\t * form wherever it opens rather than the list page and the detail page\n\t\t * each having their own.\n\t\t */\n\t\tincludeFields: {\n\t\t\ttype: Array,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Fields the create and edit forms never ask for. */\n\t\texcludeFields: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** Per-field widget / label overrides for the create and edit forms. */\n\t\tfieldOverrides: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/** Page description (shown below title) */\n\t\tdescription: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Optional MDI icon name (rendered via CnIcon) */\n\t\ticon: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Icon size in pixels */\n\t\ticonSize: {\n\t\t\ttype: Number,\n\t\t\tdefault: 28,\n\t\t},\n\n\t\t/** Whether the page is in a loading state */\n\t\tloading: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Message shown during loading */\n\t\tloadingLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Loading…'),\n\t\t},\n\n\t\t/**\n\t\t * Sidebar configuration. Accepts EITHER form:\n\t\t *\n\t\t * - **Boolean (legacy, deprecated):** `true` activates the\n\t\t * external sidebar, `false` deactivates. The first time this\n\t\t * form is observed per component instance a one-shot\n\t\t * `console.warn` is logged pointing at the migration path.\n\t\t * Continues to work in v1.x for back-compat.\n\t\t *\n\t\t * - **Object (preferred):** mirrors `CnIndexPage.sidebar` plus\n\t\t * the detail-specific fields previously on `sidebarProps`:\n\t\t * ```ts\n\t\t * {\n\t\t * show?: boolean, // default true; false suppresses sidebar\n\t\t * enabled?: boolean, // default true; false bypasses external sidebar\n\t\t * register?: string,\n\t\t * schema?: string,\n\t\t * hiddenTabs?: string[],\n\t\t * title?: string,\n\t\t * subtitle?: string,\n\t\t * tabs?: Array<TabDef>, // see manifest-abstract-sidebar\n\t\t * }\n\t\t * ```\n\t\t * When BOTH `sidebar` (Object) and `sidebarProps` are set\n\t\t * with overlapping fields, the Object form wins and a\n\t\t * `console.warn` lists the conflicting fields once per\n\t\t * component instance.\n\t\t *\n\t\t * @type {boolean | object}\n\t\t */\n\t\tsidebar: {\n\t\t\ttype: [Boolean, Object],\n\t\t\t// Object default (not Boolean `false`) so apps that omit the\n\t\t\t// prop don't trip the Boolean-form deprecation warning. Equivalent\n\t\t\t// to `false`: resolves to a suppressed/inactive sidebar.\n\t\t\tdefault: () => ({ enabled: false }),\n\t\t},\n\n\t\t/**\n\t\t * Initial open state of the object sidebar when it first activates.\n\t\t * Defaults to closed so the detail content fills the page; the user\n\t\t * opens it on demand via the header sidebar-toggle (and the sidebar's\n\t\t * own X closes it). After the first activation the open state is owned\n\t\t * by the shared `objectSidebarState` channel (toggle / close), so this\n\t\t * prop only seeds the initial value.\n\t\t */\n\t\tsidebarOpen: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** The registered object type slug for the sidebar */\n\t\tobjectType: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** The object ID to display in the sidebar */\n\t\tobjectId: {\n\t\t\ttype: [String, Number],\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Whether a schema-bound page without an object id shows an empty\n\t\t * CnFormDialog for its schema instead of a blank page.\n\t\t *\n\t\t * Set from the manifest as `config.createForm`:\n\t\t * - `'auto'` (default) — heuristic: only when the page is schema-bound,\n\t\t * has no object id, and supplies no body of its own (no default slot,\n\t\t * no grid layout). Existing behaviour.\n\t\t * - `'never'` — never render it. Use when the body owns data entry, e.g.\n\t\t * a page whose CnObjectDataWidget (or a registry component) already\n\t\t * provides the form; this is what stops two form dialogs stacking.\n\t\t * - `'always'` — render it even when the page has a body, for a page\n\t\t * that deliberately pairs custom content with a create form.\n\t\t *\n\t\t * The dialog itself is always the generic, schema-driven CnFormDialog, so\n\t\t * whichever way it is summoned it follows the same OpenRegister/schema\n\t\t * form rules (required, readOnly, enum/$ref, `visibleWhen`).\n\t\t *\n\t\t * @type {'auto'|'never'|'always'}\n\t\t */\n\t\tcreateForm: {\n\t\t\ttype: String,\n\t\t\tdefault: 'auto',\n\t\t\tvalidator: (value) => ['auto', 'never', 'always'].includes(value),\n\t\t},\n\n\t\t/** Subtitle shown in the sidebar header */\n\t\tsubtitle: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Additional sidebar configuration (register, schema, hiddenTabs, title, subtitle) */\n\t\tsidebarProps: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/**\n\t\t * Rendering surface forwarded to integration widgets in the\n\t\t * grid layout (widget defs with `type === 'integration'`).\n\t\t * Drives the AD-19 surface fallback. Defaults to\n\t\t * `'detail-page'` — the surface this page represents.\n\t\t *\n\t\t * @type {'user-dashboard'|'app-dashboard'|'detail-page'|'single-entity'}\n\t\t */\n\t\tsurface: {\n\t\t\ttype: String,\n\t\t\tdefault: 'detail-page',\n\t\t\tvalidator: (value) => INTEGRATION_SURFACES.includes(value),\n\t\t},\n\n\t\t/**\n\t\t * Object context forwarded to integration widgets:\n\t\t * `{ register, schema, objectId }`. When omitted it is derived\n\t\t * from `sidebarProps.register` / `sidebarProps.schema` (or\n\t\t * `objectType`) and `objectId`, so `CnFilesCard` etc. can\n\t\t * fetch the right object's sub-resources without extra wiring.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tintegrationContext: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Whether the page is in an error state */\n\t\terror: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Error message shown in error state */\n\t\terrorMessage: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'An error occurred'),\n\t\t},\n\n\t\t/** Callback for retry button in error state. If null, no retry button is shown. */\n\t\tonRetry: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Label for the retry button */\n\t\tretryLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Retry'),\n\t\t},\n\n\t\t/**\n\t\t * Router location the not-found state's button opens, shown when the\n\t\t * schema-driven fetch answers 404. Usually the record's list; null\n\t\t * sends the user to the app's root (`/`). CnPageRenderer fills it with\n\t\t * the index page the record was opened from.\n\t\t */\n\t\tnotFoundRoute: {\n\t\t\ttype: [Object, String],\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Name of the `notFoundRoute` page, used in the button's \"Back to …\" label. */\n\t\tnotFoundRouteLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Whether the page has no data to show */\n\t\tempty: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Message shown when page is empty */\n\t\temptyLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'No data available'),\n\t\t},\n\n\t\t/** Title shown above the statistics table */\n\t\tstatsTitle: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Column definitions for the statistics table.\n\t\t * Each column: `{ key: string, label: string, align?: 'left'|'center'|'right' }`\n\t\t *\n\t\t * @type {Array<{ key: string, label: string, align: string }>}\n\t\t */\n\t\tstatsColumns: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * Row data for the statistics table. Each row is an object keyed by\n\t\t * column keys. Set `indent: true` on a row for sub-row styling.\n\t\t *\n\t\t * @type {Array<object>}\n\t\t */\n\t\tstatsRows: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** Maximum width of the page content */\n\t\tmaxWidth: {\n\t\t\ttype: String,\n\t\t\tdefault: '1800px',\n\t\t},\n\n\t\t/**\n\t\t * Responsive `columnOpts` for the body grid, measured against the GRID's own\n\t\t * width rather than the window's — so a page rendered in a narrow container\n\t\t * (a split pane beside a list) reflows even though the viewport is wide.\n\t\t * Defaults to a table that stacks to one column at or below 1000px. Pass\n\t\t * `null` for a fixed 12-column grid at every size.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tcolumnOpts: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({ ...DEFAULT_DETAIL_COLUMN_OPTS }),\n\t\t},\n\n\t\t/**\n\t\t * Whether to auto-subscribe to live updates for this object.\n\t\t * Defaults to true. The page calls\n\t\t * `store.subscribe(type, objectId)` on mount and unsubscribes on\n\t\t * unmount, against the explicit `objectStore` prop when passed,\n\t\t * else (schema-driven / manifest mode: `register` + `schema` set)\n\t\t * against the library's default `useObjectStore()`. Set `false`\n\t\t * (manifest: `config.subscribe: false`) for read-only / archive\n\t\t * views.\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\tsubscribe: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Whether the schema-driven auto-body renders the related-objects widget\n\t\t * beneath the data widget. Defaults to true (back-compat). Set false on a\n\t\t * page that surfaces relations elsewhere (e.g. in the sidebar) to drop the\n\t\t * \"Related\" section from the body.\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\tshowRelatedObjects: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Optional explicit Pinia store instance to subscribe / lock\n\t\t * against; always wins when passed. When omitted, a page in\n\t\t * schema-driven mode (`register` + `schema` — the manifest\n\t\t * renderer path) falls back to the library's default\n\t\t * `useObjectStore()` so auto-subscribe still engages; the\n\t\t * resolution is defensive so consumer apps that haven't\n\t\t * activated Pinia yet (e.g. tests) don't crash.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tobjectStore: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * OpenRegister register slug. Pair with `schema` to opt into the\n\t\t * schema-driven mode: the page fuses the two into an internal\n\t\t * `${register}-${schema}` object-type slug, registers it on the\n\t\t * store, fetches the object identified by `objectId`, and auto-\n\t\t * renders `CnObjectDataWidget` + `CnObjectMetadataWidget` when no\n\t\t * default-slot content is supplied. Compatible with the existing\n\t\t * `objectType` prop — `objectType` wins on collision, so legacy\n\t\t * direct mounts are unaffected.\n\t\t *\n\t\t * @type {string}\n\t\t */\n\t\tregister: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * OpenRegister schema slug. See `register` for the schema-driven\n\t\t * contract.\n\t\t *\n\t\t * @type {string}\n\t\t */\n\t\tschema: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Hide valueless fields on the auto-rendered data widget, instead of\n\t\t * showing them with an em dash. See `CnObjectDataWidget`'s `hide-empty`.\n\t\t *\n\t\t * Set this from the manifest (`config.hideEmpty`) for a discriminated\n\t\t * supertype — one schema holding several variants, where each object only\n\t\t * carries the fields its variant uses. A widget that declares its own\n\t\t * `content.hideEmpty` still wins over this page-level default.\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\thideEmpty: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Tab definitions forwarded to the host App's `CnObjectSidebar`\n\t\t * via the injected `objectSidebarState`. Each entry follows the\n\t\t * `CnObjectSidebar` tab shape (see that component for the exact\n\t\t * fields). When empty (default) the sidebar falls back to its\n\t\t * own default tab set. The actual `<CnObjectSidebar>` is rendered\n\t\t * at `NcContent` level by `CnAppRoot` (ADR-017 — external sidebar\n\t\t * pattern); this page only publishes the tabs.\n\t\t *\n\t\t * @type {Array<object>}\n\t\t */\n\t\tsidebarTabs: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * Documentation link surfaced in the page-header Actions menu. When\n\t\t * set, the menu renders a \"Documentation\" entry that opens this URL\n\t\t * in a new tab. The Refresh and Request-a-feature entries render by\n\t\t * default regardless of this value.\n\t\t */\n\t\tdocumentationUrl: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Label for the Documentation entry in the header menu. */\n\t\tdocumentationLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Stable id for the page-header Actions menu — forwarded as the\n\t\t * `widgetId` on the `@refresh` / `cn:page:refresh` payloads and as\n\t\t * the `surface: \"detail:<pageId>\"` on the feature-request modal.\n\t\t * Falls back to a slugified title when empty.\n\t\t */\n\t\tpageId: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Whether the Refresh entry renders in the page-header menu.\n\t\t * Tri-state:\n\t\t * - `true` / `false` — force it on or off.\n\t\t * - `null` (the default) — **auto**: show Refresh only when it will\n\t\t * do something, i.e. a consumer attached an `@refresh` listener OR\n\t\t * the page is in schema-driven mode (`register` + `schema` +\n\t\t * `objectId`) and can self-fetch. Legacy `objectType`-mode detail\n\t\t * pages that never wire `@refresh` therefore show no dead button.\n\t\t *\n\t\t * @type {boolean|null}\n\t\t */\n\t\tshowRefresh: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Show an Edit button in the header that opens the record's schema\n\t\t * form. Needs `register` + `schema` + `objectId` to have something to\n\t\t * edit; without them the button stays hidden however this is set.\n\t\t *\n\t\t * `CnPageRenderer` turns this on for every schema-bound `type:\"detail\"`\n\t\t * page, which is the same set of pages whose index tables stop offering\n\t\t * an edit modal — the two are one rule, and shipping either half alone\n\t\t * would leave records with two edit surfaces or none.\n\t\t */\n\t\tshowEditAction: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Label for the header Edit button. Defaults to a translated \"Edit\". */\n\t\teditLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Whether a header refresh is in flight. Disables the Refresh entry\n\t\t * and swaps its icon for a spinner. Wire this to the same flag the\n\t\t * host toggles around its `@refresh` handler.\n\t\t */\n\t\trefreshing: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Whether the Request-a-feature entry renders in the page-header menu. */\n\t\tshowRequestFeature: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Whether the \"Report a bug\" entry renders in the page-header menu.\n\t\t * On by default — the trio Request a feature / Report a bug /\n\t\t * Documentation is the contract for every Conduction surface.\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\tshowReportBug: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Whether the Documentation entry renders in the page-header menu. On\n\t\t * by default; the shared menu resolves the target itself, so leaving\n\t\t * it on costs the host nothing.\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\tshowDocumentation: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/**\n\t\t * Declarative lifecycle/transition actions (manifest `config.lifecycleActions`).\n\t\t * When set, renders status-gated transition buttons in the page header driven\n\t\t * by the object's `x-openregister-lifecycle`. Shape:\n\t\t * `{ field?: 'status', transitions?: [{ from, to, action, label, confirm?, variant? }], autoFetch?: boolean }`.\n\t\t * With just `{ field: 'status' }` the allowed transitions are fetched live from\n\t\t * OpenRegister's `/available-actions` endpoint (server-authoritative). An\n\t\t * explicit `transitions` array is filtered client-side by the object's current\n\t\t * state. Omit (default `null`) to keep the current behaviour (no transition\n\t\t * buttons). See `CnLifecycleActions`.\n\t\t *\n\t\t * @type {object|null}\n\t\t */\n\t\tlifecycleActions: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Declarative header actions (manifest `config.headerActions`, #91\n\t\t * Wave 3) rendered as items in the header's Actions menu via\n\t\t * CnActionButtons — `api-call` (POST/PUT + toast + refresh),\n\t\t * `open-form`, `toggle`, `navigate` / `open-modal`, each with an\n\t\t * optional `visibleWhen` predicate. Distinct from `lifecycleActions`\n\t\t * (state-machine transitions): these are free-form record actions\n\t\t * (approve, send, archive). The page's object context drives\n\t\t * `@objectId` / `@object.<field>` token + local-predicate resolution.\n\t\t * Empty (the default) renders nothing.\n\t\t *\n\t\t * The menu, not a row of buttons: that is what the manifest schema has\n\t\t * always said this key is, and what CnIndexPage already does with it.\n\t\t * The two surfaces had drifted, and on a dossiq case — twelve actions —\n\t\t * the button row squeezed the record's own title to a truncated stub.\n\t\t * Edit stays a button because it is the one action a handler reaches\n\t\t * for on nearly every visit.\n\t\t *\n\t\t * @type {Array<object>}\n\t\t */\n\t\theaderActions: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * Set to fold this page's own Edit button in with the header actions,\n\t\t * so it becomes an entry in the Actions menu instead of a button\n\t\t * standing beside it. `null` (the default) keeps Edit standalone, so\n\t\t * every existing consumer's header is unchanged.\n\t\t *\n\t\t * The number itself no longer caps anything HERE: this page draws its\n\t\t * header actions as Actions-menu entries (`display: \"menu\"`), where\n\t\t * there are no buttons to cap. It is still CnActionButtons' `inline`\n\t\t * count for a host that mounts that component in `buttons` mode — see\n\t\t * that component's `inline` prop.\n\t\t *\n\t\t * @type {number|null}\n\t\t */\n\t\tinlineActions: {\n\t\t\ttype: Number,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Declarative related-object list sections (manifest\n\t\t * `config.relatedCollections`). Each entry renders a titled\n\t\t * `CnObjectListWidget` below the detail body, filtered to this object via\n\t\t * `@objectId` / `@object.<field>` tokens. Shape per entry:\n\t\t * `{ title?, register, schema, filter?, columns?, sort?, limit?, rowRoute? }`.\n\t\t * Empty / omitted (default `[]`) renders nothing. See `CnRelatedCollections`.\n\t\t *\n\t\t * @type {Array<object>}\n\t\t */\n\t\trelatedCollections: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * Declarative cross-schema summary chips (manifest\n\t\t * `config.summaryAggregates`). Each entry runs ONE count/sum/avg over a\n\t\t * related schema scoped to this object and shows it as a stat chip in the\n\t\t * header. Shape per entry:\n\t\t * `{ label, register, schema, metric?, field?, filter?, format? }`.\n\t\t * Empty / omitted (default `[]`) renders nothing. See `CnSummaryAggregates`.\n\t\t *\n\t\t * @type {Array<object>}\n\t\t */\n\t\tsummaryAggregates: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * Declarative relation-link actions (manifest `config.relationLinks`).\n\t\t * Each entry renders a button that opens a search-and-link modal which\n\t\t * patches a foreign-key field on THIS object with the chosen object's id.\n\t\t * Shape per entry:\n\t\t * `{ label?, register, schema, fkField, labelField?, allowCreate?, title?, selectLabel? }`.\n\t\t * Empty / omitted (default `[]`) renders nothing.\n\t\t *\n\t\t * @type {Array<object>}\n\t\t */\n\t\trelationLinks: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * Declarative IN-BODY sections (manifest `config.bodyWidgets`). Each\n\t\t * entry renders a REGISTERED host-app component as a titled section in\n\t\t * the page BODY (not the sidebar), with the object/page context injected.\n\t\t * This is the primitive that lets a rich bespoke detail page (BRP panels,\n\t\t * activity timelines, comms history, relationship graphs, bookings, …)\n\t\t * become declarative while keeping its sections in the body. Shape per\n\t\t * entry:\n\t\t * `{ id?, component, title?, props?, placement?, colSpan? }`.\n\t\t * - `component` — registry name resolved from the app's v2 `registry`\n\t\t * (any `kind` exposing a `.component`, e.g. `kind:\"section\"` or\n\t\t * `kind:\"widget\"`) or the legacy `customComponents` map. NO sidebar\n\t\t * tab is required (unlike integration widgets).\n\t\t * - `props` — values are token-resolved: `@objectId` → this object's id,\n\t\t * `@object.<field>` → a field off it, `@workspace.<key>` → page\n\t\t * context; unset `@…?` optional / unresolved tokens are dropped.\n\t\t * - `placement` — `before-body` | `after-data` | `after-related` | `end`\n\t\t * (default `end`). Controls where in the body the section lands.\n\t\t * - `colSpan` — 1–12 grid span when sections share a placement.\n\t\t * The loaded object + objectId are also `provide`d on `cnSectionContext`\n\t\t * so a host component can inject them instead of taking explicit props.\n\t\t * Empty / omitted (default `[]`) renders nothing. See `CnBodySections`.\n\t\t *\n\t\t * @type {Array<{id?: string, component: string, title?: string, props?: object, placement?: string, colSpan?: number}>}\n\t\t */\n\t\tbodyWidgets: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/**\n\t\t * Vue-router route NAME to navigate to after a create-form save (the\n\t\t * create archetype: a `type:\"detail\"` page whose route carries no `:id`).\n\t\t * The created object's id is passed as the `id` route param. When empty\n\t\t * (the default) the page navigates back in history after a successful\n\t\t * create instead. See `isCreateMode`.\n\t\t *\n\t\t * @type {string}\n\t\t */\n\t\tcreateRoute: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Page-level app config map exposed to declarative widget / section\n\t\t * config via the `@config.<key>` token (e.g. the reporting `currency`\n\t\t * the setup wizard captures). Provided to descendants on `cnAppConfig`,\n\t\t * so a stat widget's `format: { style: 'currency', currency:\n\t\t * '@config.currency' }` formats with the configured value (falling back\n\t\t * to the literal default when unset). A manifest renderer typically seeds\n\t\t * this from `loadState(appId, 'config', {})`. Empty (default) leaves every\n\t\t * `@config.<key>` token to fall back to its literal default.\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tappConfig: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/**\n\t\t * Next and previous within the list this record was opened from, as\n\t\t * returned by `useListNavigation`. Omit it and neither control\n\t\t * renders, which is what a record reached by a bare link must do:\n\t\t * stepping through an order the reader never chose is worse than\n\t\t * offering no step at all.\n\t\t *\n\t\t * @type {{ available: boolean, isFirst: boolean, isLast: boolean, position: number, total: number }}\n\t\t */\n\t\tlistNavigation: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Router location of the previous record, as `useListNavigation`'s\n\t\t * `previousRoute`. When set, the previous control is a real link\n\t\t * (middle-click, open in new tab) and `previous-record` is emitted\n\t\t * with `{ event, to }` after it navigated. Null keeps it a button.\n\t\t *\n\t\t * @type {object|string|null}\n\t\t */\n\t\tpreviousTo: {\n\t\t\ttype: [Object, String],\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Router location of the next record, as `useListNavigation`'s\n\t\t * `nextRoute`. Same behaviour as `previousTo`.\n\t\t *\n\t\t * @type {object|string|null}\n\t\t */\n\t\tnextTo: {\n\t\t\ttype: [Object, String],\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * The page's primary action, as declared on its manifest page. Renders\n\t\t * as the header's primary button and is the target the skip link\n\t\t * lands on. Omit it and neither renders.\n\t\t *\n\t\t * @type {{ id?: string, label: string, icon?: string, route?: string, href?: string }}\n\t\t */\n\t\tprimaryAction: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Puts the active tab in the address as `?_tab=<id>`, so a link points\n\t\t * at a tab of this record rather than at the record. Off by default,\n\t\t * which leaves the address exactly as it is today.\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\ttabInAddress: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t},\n\n\temits: [\n\t\t'create-cancel',\n\t\t'created',\n\t\t'edited',\n\t\t'geo-saved',\n\t\t'layout-change',\n\t\t'open-integration',\n\t\t'refresh',\n\t\t'related-row-click',\n\t\t'relation-linked',\n\t\t'request-feature',\n\t\t'transitioned',\n\t\t'update:layout',\n\t\t'widget-config-change',\n\t\t/**\n\t\t * The reader asked for the next record of the list this one was\n\t\t * opened from. The host steps, because the host owns the router.\n\t\t * With `nextTo` set the link has navigated already and the payload\n\t\t * is `{ event, to }`.\n\t\t */\n\t\t'next-record',\n\t\t/** The reader asked for the previous record of that same list. Payload as `next-record`. */\n\t\t'previous-record',\n\t\t/** The page's declared primary action was pressed. Payload is the declaration. */\n\t\t'primary-action',\n\t\t/**\n\t\t * The active tab changed. Payload is the tab id. Emitted whether or\n\t\t * not `tabInAddress` is set, so a host may mirror it somewhere else.\n\t\t */\n\t\t'tab-change',\n\t],\n\n\tsetup(props) {\n\t\t// Pluggable integration registry — used to resolve `type:\n\t\t// 'integration'` widgets in the grid layout to their Vue\n\t\t// component (AD-19 surface fallback). Always wired; cheap when\n\t\t// no integration widgets are configured.\n\t\tconst { resolveWidget, getById } = useIntegrationRegistry()\n\t\tconst registryExposed = { resolveRegistryWidget: resolveWidget, getRegistryProvider: getById }\n\n\t\t// The host reads presence because only the host can act on it: the grid\n\t\t// reserves the row before the widget renders. See `layoutItemCanDraw`.\n\t\t// A getter, not a one-shot read: a page whose widgets arrive after mount\n\t\t// would otherwise never subscribe, and `layoutItemCanDraw` would drop the\n\t\t// presence row for good instead of until somebody arrives.\n\t\tconst presencePlaced = () => (props.widgets || []).some((w) => w && w.type === 'presence')\n\t\tconst { others: presentOthers } = useObjectPresence(\n\t\t\t() => props.register || '',\n\t\t\t() => props.schema || '',\n\t\t\t() => String(props.objectId || ''),\n\t\t\t{ enabled: presencePlaced },\n\t\t)\n\t\tregistryExposed.presentOthers = presentOthers\n\n\t\t// Object context for detail-page abstract widgets (ADR-041): a reactive\n\t\t// `{ objectId, object, register, schema }` holder kept current by the\n\t\t// Options watcher below. Provided so CnObjectListWidget / CnStatWidget\n\t\t// can resolve `@objectId` / `@object.<field>` filter tokens and scope\n\t\t// their query to the object on this page. Null fields until loaded.\n\t\tconst cnObjectContext = ref({ objectId: props.objectId || null, object: null, register: props.register || '', schema: props.schema || '' })\n\t\tprovide('cnObjectContext', cnObjectContext)\n\t\tregistryExposed.cnObjectContextRef = cnObjectContext\n\n\t\t// Page-level APP CONFIG exposed to declarative widget / section config via\n\t\t// the `@config.<key>` token (e.g. the reporting currency the setup wizard\n\t\t// captures). Provided so CnStatWidget / CnBodySections can format with the\n\t\t// configured value. Kept in sync with the `appConfig` prop.\n\t\tconst cnAppConfig = ref({ ...(props.appConfig || {}) })\n\t\tprovide('cnAppConfig', cnAppConfig)\n\t\tregistryExposed.cnAppConfigRef = cnAppConfig\n\t\twatch(\n\t\t\t() => props.appConfig,\n\t\t\t(next) => {\n\t\t\t\tcnAppConfig.value = { ...(next || {}) }\n\t\t\t},\n\t\t\t{ deep: true },\n\t\t)\n\n\t\t// Auto-subscribe + reactive lock state for the current object.\n\t\t// Both are no-ops when no store resolves (no Pinia active), when\n\t\t// subscribe is false (read-only / archive views), or when\n\t\t// objectType / objectId aren't yet known. Using composables in\n\t\t// setup() keeps the lifecycle bound to the component scope —\n\t\t// `tryOnScopeDispose` releases the subscription on unmount.\n\t\t//\n\t\t// Store resolution (manifest-live-updates): an explicit\n\t\t// `objectStore` prop always wins (existing behaviour, unchanged\n\t\t// for apps that pass their own store). In schema-driven mode —\n\t\t// `register` + `schema` set, the manifest renderer path — fall\n\t\t// back to the library's default store, the same one the\n\t\t// schema-driven fetch (`effectiveObjectStore`) uses, so\n\t\t// manifest-rendered detail pages auto-subscribe with zero\n\t\t// app-side wiring. Legacy `objectType`-only mounts without an\n\t\t// explicit store keep today's behaviour (no subscription).\n\t\tlet subscriptionStore = props.objectStore\n\t\tif (!subscriptionStore && props.subscribe && props.register && props.schema) {\n\t\t\ttry {\n\t\t\t\tsubscriptionStore = useObjectStore()\n\t\t\t} catch {\n\t\t\t\t// Pinia not active (stand-alone test mounts) — no live updates.\n\t\t\t\tsubscriptionStore = null\n\t\t\t}\n\t\t\tif (subscriptionStore) {\n\t\t\t\t// Register the EFFECTIVE type slug synchronously — the same\n\t\t\t\t// slug `resolveType()`/`resolvedObjectType` yields (an explicit\n\t\t\t\t// `objectType` prop wins; note the manifest renderer aliases\n\t\t\t\t// `config.schema` → `objectType`), with the same idempotence\n\t\t\t\t// guard as fetchObjectIfNeeded (which therefore skips its own\n\t\t\t\t// registration). This ensures the subscription's mount-time\n\t\t\t\t// subscribe() never races the mounted() fetch path into a\n\t\t\t\t// \"type not registered\" rejection.\n\t\t\t\tconst effectiveType = props.objectType || `${props.register}-${props.schema}`\n\t\t\t\tif (typeof subscriptionStore.registerObjectType === 'function'\n\t\t\t\t\t&& !subscriptionStore.objectTypeRegistry?.[effectiveType]) {\n\t\t\t\t\tsubscriptionStore.registerObjectType(\n\t\t\t\t\t\teffectiveType,\n\t\t\t\t\t\tprops.schema,\n\t\t\t\t\t\tprops.register,\n\t\t\t\t\t\t{ registerSlug: props.register, schemaSlug: props.schema },\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (!subscriptionStore || !props.subscribe) {\n\t\t\treturn { ...registryExposed, lockState: null }\n\t\t}\n\t\t// Resolve the effective object-type slug the same way `computed.resolvedObjectType`\n\t\t// does — the explicit `objectType` prop wins, else fuse `register` + `schema`.\n\t\t// The composables take getter functions so the resolution stays reactive when\n\t\t// `register` / `schema` / `objectType` change at runtime.\n\t\tconst resolveType = () => props.objectType || (props.register && props.schema ? `${props.register}-${props.schema}` : '')\n\t\tconst subscription = useObjectSubscription(\n\t\t\tsubscriptionStore,\n\t\t\tresolveType,\n\t\t\t() => props.objectId,\n\t\t\t{ enabled: () => Boolean(resolveType() && props.objectId) },\n\t\t)\n\t\tconst sidebarReg = props.sidebarProps?.register || props.resolvedSidebar?.register || props.register || ''\n\t\tconst sidebarSchema = props.sidebarProps?.schema || props.resolvedSidebar?.schema || props.schema || ''\n\t\tconst lock = useObjectLock(\n\t\t\tsubscriptionStore,\n\t\t\t() => sidebarReg,\n\t\t\t() => resolveType() || sidebarSchema,\n\t\t\t() => props.objectId,\n\t\t\t// The third argument is the OBJECT CACHE KEY (`<register>-<schema>`)\n\t\t\t// and the lock URL needs the schema SLUG. They were one string, and\n\t\t\t// the acquire went to `/api/objects/<register>/<register>-<schema>/`,\n\t\t\t// which no register answers.\n\t\t\t{ schemaSlug: () => props.schema || sidebarSchema },\n\t\t)\n\t\treturn {\n\t\t\t...registryExposed,\n\t\t\tsubscriptionStatus: subscription.status,\n\t\t\tlockState: lock,\n\t\t}\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\t/** Whether the record edit form is open. */\n\t\t\teditFormOpen: false,\n\t\t\t/**\n\t\t\t * The sentence a refused lock left behind, shown in place of the\n\t\t\t * form. Empty whenever the form opened.\n\t\t\t */\n\t\t\teditLockRefusal: '',\n\t\t\t/**\n\t\t\t * Whether a lock release is in flight, so the locked card's Unlock\n\t\t\t * button can disable itself for the round trip. Without it a slow\n\t\t\t * release invites a second click, and the second `release()` lands\n\t\t\t * on a lock that is already gone.\n\t\t\t */\n\t\t\treleasingLock: false,\n\t\t\t/**\n\t\t\t * The manifest `headerActions[]` flattened into menu items by the\n\t\t\t * `display: \"menu\"` CnActionButtons instance, which keeps owning\n\t\t\t * their dialogs. Each carries its own pre-bound `run()`, so the\n\t\t\t * menu dispatches without reaching back into that component.\n\t\t\t */\n\t\t\tmenuHeaderActions: [],\n\t\t\t/** Lifecycle transitions CnLifecycleActions hands the Actions menu. */\n\t\t\tlifecycleMenuEntries: [],\n\t\t\t/** Whether the per-widget style/config editor modal is open. */\n\t\t\tshowWidgetConfig: false,\n\t\t\t/** The widgetId currently being configured via the cog. */\n\t\t\tconfigWidgetId: null,\n\t\t\t/**\n\t\t\t * Whether the object sidebar has been seeded with its initial open\n\t\t\t * state for the current activation. Gates the one-shot `sidebarOpen`\n\t\t\t * seed in `syncSidebarState` so user close/toggle is not clobbered.\n\t\t\t */\n\t\t\tsidebarSeeded: false,\n\t\t\t/** The relation-link descriptor whose modal is currently open (or null). */\n\t\t\tactiveRelationLink: null,\n\t\t\t/**\n\t\t\t * Materialized default body grid for the schema-driven auto-body (Data +\n\t\t\t * Related). Lazily built by `materializeAutoBody()` the first time the\n\t\t\t * object resolves so the detail body is a real, mutable GridStack grid\n\t\t\t * (drag / resize / configure) rather than a static stack. `null` until\n\t\t\t * materialized; reset when the schema-driven context changes.\n\t\t\t */\n\t\t\tautoBodyLayout: null,\n\t\t\t/** Widget definitions paired with `autoBodyLayout` (id ↔ widgetId). */\n\t\t\tautoBodyWidgets: null,\n\t\t\t/**\n\t\t\t * True when `materializeAutoBody()` dropped the Data widget only\n\t\t\t * because the schema had not arrived yet — the object won the race\n\t\t\t * against `fetchSchema`. The `currentSchema` watcher re-materializes\n\t\t\t * once on that signal, which is what stops a lost race from\n\t\t\t * permanently hiding every scalar field (shillinq#1073).\n\t\t\t *\n\t\t\t * A flag rather than an \"is the widget missing?\" test, so a body the\n\t\t\t * user has edited is never rewritten underneath them.\n\t\t\t */\n\t\t\tdataWidgetDeferred: false,\n\t\t\t/**\n\t\t\t * Drives the Actions-menu Refresh spinner during a schema-driven\n\t\t\t * self-fetch refresh, where the host has no promise to bind\n\t\t\t * `:refreshing` to. Mirrors CnIndexPage.internalRefreshing.\n\t\t\t */\n\t\t\tinternalRefreshing: false,\n\t\t\t/**\n\t\t\t * Whether a load has completed at least once. Gates the\n\t\t\t * full-page loading state to the FIRST load only: once content\n\t\t\t * has been shown, later loads (refresh, re-fetch) stay in place\n\t\t\t * and surface as the action-button spinner instead of blanking\n\t\t\t * the page. Set true the first time `loading` falls to false.\n\t\t\t */\n\t\t\thasLoadedOnce: false,\n\t\t\t/**\n\t\t\t * Whether the schema-driven object fetch is in flight. Starts true\n\t\t\t * so the immediate sidebar sync at creation already waits for it.\n\t\t\t */\n\t\t\tobjectFetchPending: Boolean(this.register && this.schema && this.objectId),\n\t\t\t/** Whether the schema-driven fetch answered 404 for `objectId`. */\n\t\t\tobjectNotFound: false,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t// ── The record as a place (case-page-and-list-as-a-place) ───────\n\n\t\t/**\n\t\t * The primary action's label, run through the host's translate\n\t\t * function. Empty when the page declares no primary action, which is\n\t\t * what gates both the button and the skip link.\n\t\t *\n\t\t * @return {string} The label, or an empty string.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tprimaryActionLabel() {\n\t\t\tconst label = this.primaryAction?.label\n\t\t\treturn typeof label === 'string' && label !== '' ? this.effectiveTranslate(label) : ''\n\t\t},\n\n\t\t/**\n\t\t * The id the skip link's anchor points at.\n\t\t *\n\t\t * Namespaced by the page so two detail pages in one document, which\n\t\t * the split view makes possible, cannot both answer to `#primary`.\n\t\t *\n\t\t * @return {string} The element id.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tprimaryActionAnchorId() {\n\t\t\tconst scope = this.primaryAction?.id || this.pageId || this.objectId || 'record'\n\t\t\treturn `cn-primary-action-${String(scope).replace(/[^A-Za-z0-9_-]/g, '-')}`\n\t\t},\n\n\t\t/**\n\t\t * What the skip link says.\n\t\t *\n\t\t * It names the action rather than saying \"skip to main content\",\n\t\t * because a keyboard user who cannot see the page needs to know what\n\t\t * they are being offered before they take it.\n\t\t *\n\t\t * @return {string} The link text.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tskipLinkLabel() {\n\t\t\treturn `${this.effectiveTranslate('Skip to')} ${this.primaryActionLabel}`\n\t\t},\n\n\t\t/**\n\t\t * Where this record sits in the list it was opened from, as text.\n\t\t *\n\t\t * @return {string} For example \"4 of 40\".\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tlistPositionLabel() {\n\t\t\tconst nav = this.listNavigation\n\t\t\tif (!nav || !nav.total) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn `${nav.position} ${this.effectiveTranslate('of')} ${nav.total}`\n\t\t},\n\n\t\t/**\n\t\t * Accessible name for the previous control, which says what list it\n\t\t * steps through rather than only which direction it goes.\n\t\t *\n\t\t * @return {string} The label.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tpreviousRecordLabel() {\n\t\t\treturn this.listNavigation?.isFirst\n\t\t\t\t? this.effectiveTranslate('This is the first record in the list')\n\t\t\t\t: this.effectiveTranslate('Previous record in the list')\n\t\t},\n\n\t\t/**\n\t\t * Accessible name for the next control.\n\t\t *\n\t\t * @return {string} The label.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tnextRecordLabel() {\n\t\t\treturn this.listNavigation?.isLast\n\t\t\t\t? this.effectiveTranslate('This is the last record in the list')\n\t\t\t\t: this.effectiveTranslate('Next record in the list')\n\t\t},\n\n\t\t/**\n\t\t * Stable id for the page-header Actions menu. Prefers the explicit\n\t\t * `pageId` prop; falls back to a slugified `title` so the menu still\n\t\t * gets a usable id / surface.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\t/**\n\t\t * Whether the page is in Buildiq edit mode — unwraps the injected\n\t\t * `cnEditingBody` ref (or plain boolean). Drives the per-widget cog.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\teditingBody() {\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 * The widget definition currently being configured, shaped for\n\t\t * `CnWidgetStyleEditorModal` (carries `id`, `type`, `title`, `content`).\n\t\t *\n\t\t * @return {object|null}\n\t\t */\n\t\tconfigWidget() {\n\t\t\tif (!this.configWidgetId) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst def = this.bodyGridWidgets.find((w) => w.id === this.configWidgetId)\n\t\t\treturn def || null\n\t\t},\n\n\t\tresolvedPageId() {\n\t\t\tif (this.pageId) {\n\t\t\t\treturn this.pageId\n\t\t\t}\n\t\t\treturn String(this.title || '').toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '')\n\t\t},\n\n\t\t/**\n\t\t * Whether to show the full-page loading state (spinner that replaces\n\t\t * the page content). Only on the FIRST load — when `loading` is true\n\t\t * and nothing has been shown yet. Once `hasLoadedOnce` is set, a\n\t\t * subsequent `loading` (refresh / re-fetch) keeps the existing\n\t\t * content in place; the action-button spinner signals the refresh\n\t\t * instead (see `effectiveRefreshing`).\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tshowLoadingState() {\n\t\t\treturn (this.loading && !this.hasLoadedOnce) || this.awaitingObject\n\t\t},\n\n\t\t/**\n\t\t * Whether the page is still waiting for its first answer on the record.\n\t\t * The body, lifecycle menu and sidebar stay unmounted meanwhile, because\n\t\t * each of them requests endpoints scoped to the id and a missing record\n\t\t * would turn every one of those into a 404 or 500.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tawaitingObject() {\n\t\t\treturn this.hasSchemaDrivenFetch\n\t\t\t\t&& this.objectFetchPending\n\t\t\t\t&& typeof this.effectiveObjectStore?.fetchObject === 'function'\n\t\t\t\t&& !this.currentObject\n\t\t},\n\n\t\t/**\n\t\t * Where the not-found state's button goes: `notFoundRoute`, or the app's\n\t\t * root when the host names no list to return to.\n\t\t *\n\t\t * @return {object|string}\n\t\t */\n\t\tnotFoundTarget() {\n\t\t\treturn this.notFoundRoute || { path: '/' }\n\t\t},\n\n\t\t/** Heading and description of the not-found state. */\n\t\tnotFoundLabels() {\n\t\t\treturn {\n\t\t\t\tname: t('nextcloud-vue', 'Not found'),\n\t\t\t\tdescription: t('nextcloud-vue', 'This item does not exist or has been deleted.'),\n\t\t\t}\n\t\t},\n\n\t\t/** Label of the not-found state's button, unescaped because `{{ }}` escapes. */\n\t\tnotFoundButtonLabel() {\n\t\t\treturn this.notFoundRoute && this.notFoundRouteLabel\n\t\t\t\t? t('nextcloud-vue', 'Back to {page}', { page: this.notFoundRouteLabel }, undefined, { escape: false })\n\t\t\t\t: t('nextcloud-vue', 'Back to home')\n\t\t},\n\n\t\t/**\n\t\t * Refresh-spinner flag for the page-header Actions menu. True when:\n\t\t * an explicit `refreshing` prop is set; OR a schema-driven self-fetch\n\t\t * is in flight (`internalRefreshing`); OR a background load is running\n\t\t * after the first one completed (`loading && hasLoadedOnce`) — so\n\t\t * legacy `objectType` hosts get the spinner for free just by passing\n\t\t * `:loading`, without wiring `:refreshing` themselves.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\teffectiveRefreshing() {\n\t\t\treturn this.refreshing || this.internalRefreshing || (this.loading && this.hasLoadedOnce)\n\t\t},\n\n\t\t/**\n\t\t * Effective object-type slug, used for subscription, lock, store\n\t\t * registration, fetch, and sidebar state. Explicit `objectType`\n\t\t * prop wins (existing direct-mount call sites stay untouched);\n\t\t * otherwise `${register}-${schema}` fuses the schema-driven props\n\t\t * the manifest renderer passes. Returns `''` when neither path\n\t\t * yields a slug — the schema-driven gates downstream key off that.\n\t\t */\n\t\tresolvedObjectType() {\n\t\t\tif (this.objectType) {\n\t\t\t\treturn this.objectType\n\t\t\t}\n\t\t\tif (this.register && this.schema) {\n\t\t\t\treturn `${this.register}-${this.schema}`\n\t\t\t}\n\t\t\treturn ''\n\t\t},\n\n\t\t/**\n\t\t * True when this mount is wired for the manifest's schema-driven\n\t\t * contract: `register`, `schema`, and `objectId` are all set, so\n\t\t * the page should fetch the object + schema, register the type\n\t\t * on the store, and render the auto-body widgets when no slot\n\t\t * content is supplied. Legacy direct mounts (which pass an\n\t\t * explicit `objectType` instead) return `false` here and skip\n\t\t * the fetch path entirely.\n\t\t */\n\t\thasSchemaDrivenFetch() {\n\t\t\treturn Boolean(this.register && this.schema && this.objectId)\n\t\t},\n\n\t\t/**\n\t\t * Whether the header Edit button renders. Opted in via `showEditAction`,\n\t\t * but gated on there actually being a record and a schema to edit it\n\t\t * with: `isCreateMode` already owns the id-less page, and a button that\n\t\t * opens a form with no schema is a dead button.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\t/** Whether the lifecycle transitions are mounted. */\n\t\tshowsLifecycleActions() {\n\t\t\tif (this.objectNotFound || this.awaitingObject) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\treturn Boolean(this.lifecycleActions && (this.objectId || this.currentObject))\n\t\t},\n\n\t\t/**\n\t\t * Everything the Actions menu lists above its built-in items: the\n\t\t * lifecycle transitions, then the declared header actions.\n\t\t *\n\t\t * @return {Array<object>} Menu-ready entries.\n\t\t */\n\t\theaderMenuEntries() {\n\t\t\tconst lifecycle = this.showsLifecycleActions ? this.lifecycleMenuEntries : []\n\t\t\treturn [...lifecycle, ...this.menuHeaderActions]\n\t\t},\n\n\t\t/**\n\t\t * Whether Edit joins the CnActionButtons cluster instead of standing\n\t\t * on its own. Opted into by `inlineActions`.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tfoldsEditIntoActions() {\n\t\t\treturn typeof this.inlineActions === 'number'\n\t\t},\n\n\t\t/**\n\t\t * The header actions actually handed to CnActionButtons: the declared\n\t\t * ones, plus this page's Edit appended when `inlineActions` folds it\n\t\t * in. Edit goes LAST so it reads after the app's own actions in the\n\t\t * Actions menu — the page's affordance yields to the app's.\n\t\t *\n\t\t * @return {Array<object>} The action descriptors.\n\t\t */\n\t\teffectiveHeaderActions() {\n\t\t\tconst declared = Array.isArray(this.headerActions) ? this.headerActions : []\n\t\t\tif (!(this.foldsEditIntoActions && this.canEditRecord)) {\n\t\t\t\treturn declared\n\t\t\t}\n\t\t\treturn [\n\t\t\t\t...declared,\n\t\t\t\t{\n\t\t\t\t\tid: 'cn-detail-page-edit',\n\t\t\t\t\tlabel: this.editActionLabel,\n\t\t\t\t\ticon: 'Pencil',\n\t\t\t\t\t// A function, not a dispatch type: `open-form` hardcodes\n\t\t\t\t\t// `item: null`, so it creates and cannot edit this record.\n\t\t\t\t\tonSelect: () => this.openEditForm(),\n\t\t\t\t},\n\t\t\t]\n\t\t},\n\n\t\tcanEditRecord() {\n\t\t\treturn this.showEditAction\n\t\t\t\t&& !this.isCreateMode\n\t\t\t\t&& this.hasSchemaDrivenFetch\n\t\t\t\t&& Boolean(this.currentSchema)\n\t\t\t\t&& !this.editLockedByOther\n\t\t},\n\n\t\t/**\n\t\t * Whether somebody else is editing this record right now.\n\t\t *\n\t\t * The banner above already names them, so the button is withdrawn\n\t\t * rather than shown and refused: an Edit that opens a form the write\n\t\t * will reject is a form somebody fills in twice.\n\t\t *\n\t\t * @return {boolean} True when another user holds the lock.\n\t\t */\n\t\teditLockedByOther() {\n\t\t\treturn Boolean(this.lockState\n\t\t\t\t&& this.lockState.locked.value\n\t\t\t\t&& !this.lockState.lockedByMe.value)\n\t\t},\n\n\t\t/**\n\t\t * Label for the header Edit button.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\teditActionLabel() {\n\t\t\treturn this.editLabel || t('nextcloud-vue', 'Edit')\n\t\t},\n\n\t\t/**\n\t\t * The create archetype: a schema-bound page (`register` + `schema`) whose\n\t\t * route carries NO object id, and which has no hand-authored body of its\n\t\t * own. Instead of rendering a blank page (procest `/tasks/new`), the page\n\t\t * shows an empty create form for the schema (ADR-062). Suppressed when a\n\t\t * default slot or an explicit grid `layout` supplies the body.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tisCreateMode() {\n\t\t\t// `createForm` (manifest `config.createForm`) is the explicit switch;\n\t\t\t// 'auto' keeps the original heuristic. A page still needs a schema to\n\t\t\t// build a form from, and one already showing an object is editing,\n\t\t\t// not creating — so those two conditions hold even for 'always'.\n\t\t\tif (this.createForm === 'never') {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tconst schemaBound = Boolean(this.register && this.schema) && !this.objectId\n\t\t\tif (this.createForm === 'always') {\n\t\t\t\treturn schemaBound\n\t\t\t}\n\t\t\treturn schemaBound && !this.hasDefaultSlotContent && !this.hasGridLayout\n\t\t},\n\n\t\t/**\n\t\t * Create-form prefill drawn from the route query, filtered to the\n\t\t * schema's own properties (e.g. `?caseId=x` seeds the `caseId` field so\n\t\t * a child created from a parent is pre-linked). Null when nothing\n\t\t * applies (true empty create).\n\t\t *\n\t\t * @return {object|null}\n\t\t */\n\t\tcreatePrefill() {\n\t\t\tconst q = (this.$route && this.$route.query) || {}\n\t\t\tconst props = (this.currentSchema && this.currentSchema.properties) || {}\n\t\t\tconst out = {}\n\t\t\tfor (const [k, v] of Object.entries(q)) {\n\t\t\t\tif (Object.hasOwn(props, k)) {\n\t\t\t\t\tout[k] = v\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn Object.keys(out).length ? out : null\n\t\t},\n\n\t\t/**\n\t\t * `show` for the `#form-dialog` slot: whether the page's built-in form\n\t\t * dialog is on screen — the create archetype's empty form, or the\n\t\t * record edit form.\n\t\t *\n\t\t * Mirrors the `v-if` on the two default children exactly, so a\n\t\t * replacement opens and closes on the same conditions the built-in\n\t\t * dialog does. That includes the `editFormAwaitingRecord` guard (#850),\n\t\t * which is what stops an edit form opening over a record that has not\n\t\t * loaded yet — a replacement that reimplemented visibility from\n\t\t * `editFormOpen` alone would reintroduce that blank-form-overwrites-\n\t\t * the-record bug in every app that used it.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tformDialogVisible() {\n\t\t\tif (!this.currentSchema) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif (this.isCreateMode) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn this.editFormOpen && !this.editFormAwaitingRecord\n\t\t},\n\n\t\t/**\n\t\t * `item` for the `#form-dialog` slot: the record the built-in dialog is\n\t\t * bound to — the loaded object when editing, the route-derived prefill\n\t\t * when creating (null for a true empty create, matching CnIndexPage,\n\t\t * where a null `item` likewise means \"create\").\n\t\t *\n\t\t * @return {object|null}\n\t\t */\n\t\tformDialogItem() {\n\t\t\treturn this.isCreateMode ? this.createPrefill : this.currentObject\n\t\t},\n\n\t\t/**\n\t\t * Effective Refresh visibility for the page header. An explicit\n\t\t * `showRefresh` prop wins; when unset (`null`), show Refresh only if\n\t\t * it will do something — a consumer attached an `@refresh` listener,\n\t\t * or the page can self-fetch (`hasSchemaDrivenFetch`).\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\teffectiveHeaderShowRefresh() {\n\t\t\tif (this.showRefresh !== null) {\n\t\t\t\treturn this.showRefresh\n\t\t\t}\n\t\t\t// `$.vnode.props`, not `$attrs`: `refresh` is a declared emit, and\n\t\t\t// Vue keeps declared emits out of `$attrs`.\n\t\t\treturn Boolean(this.$.vnode.props?.onRefresh) || this.hasSchemaDrivenFetch\n\t\t},\n\n\t\t/**\n\t\t * Pinia store instance used for the schema-driven fetch.\n\t\t * Mirrors `CnLogsPage.objectStore`: explicit `objectStore` prop\n\t\t * wins; otherwise falls back to the library's default\n\t\t * `useObjectStore()`. The composable is invoked lazily inside a\n\t\t * computed so test mounts that never activate Pinia don't crash.\n\t\t *\n\t\t * @return {object|null} The resolved store, or null when the page\n\t\t * is not in schema-driven mode (no need to touch Pinia at all).\n\t\t */\n\t\teffectiveObjectStore() {\n\t\t\tif (this.objectStore) {\n\t\t\t\treturn this.objectStore\n\t\t\t}\n\t\t\tif (!this.hasSchemaDrivenFetch && !this.isCreateMode) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn useObjectStore()\n\t\t\t} catch (err) {\n\t\t\t\t// Pinia not active in this consumer — fall back to no-op\n\t\t\t\t// and let the page render as if no store-driven content\n\t\t\t\t// were available. Real consumers (CnAppRoot-hosted apps)\n\t\t\t\t// always have Pinia active, so this branch only protects\n\t\t\t\t// stand-alone test mounts.\n\n\t\t\t\t// eslint-disable-next-line no-console -- a deliberate warning to the developer integrating this component\n\t\t\t\tconsole.warn('[CnDetailPage] useObjectStore() unavailable; schema-driven mode disabled.', err)\n\t\t\t\treturn null\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * The fetched OR object for the schema-driven mode. Read straight\n\t\t * from the store's normalised `objects[type][id]` cache so any\n\t\t * other component fetching the same object (sidebar widgets,\n\t\t * locked-banner) shares state with no second request.\n\t\t *\n\t\t * @return {object|null}\n\t\t */\n\t\tcurrentObject() {\n\t\t\tconst store = this.effectiveObjectStore\n\t\t\tif (!store) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst type = this.resolvedObjectType\n\t\t\tif (!type || !this.objectId) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn store.objects?.[type]?.[this.objectId] ?? null\n\t\t},\n\n\t\t/**\n\t\t * Whether the edit form is still waiting for the record it edits.\n\t\t *\n\t\t * True only while a record is actually RESOLVABLE and absent — a host\n\t\t * with no object store has nothing to wait for, and gating on it\n\t\t * there would make the Edit button dead.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\teditFormAwaitingRecord() {\n\t\t\tif (!this.effectiveObjectStore || !this.objectId) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\treturn !this.currentObject\n\t\t},\n\n\t\t/**\n\t\t * The resolved OR object surfaced to the header's translation\n\t\t * badge slot (cn-detail-translation-aware-surfacing). Falls\n\t\t * back to `currentObject` from the schema-driven path AND, when\n\t\t * the schema-driven path is unavailable, attempts to read the\n\t\t * store via `objectType` + `objectId` directly (so legacy direct\n\t\t * mounts that don't pass `register` / `schema` still benefit).\n\t\t * Returns `null` when nothing can be resolved — the badge then\n\t\t * auto-hides.\n\t\t *\n\t\t * @return {object|null}\n\t\t */\n\t\tresolvedObject() {\n\t\t\t// Schema-driven path: reuse what `currentObject` already\n\t\t\t// computed.\n\t\t\tconst fromSchemaDriven = this.currentObject\n\t\t\tif (fromSchemaDriven) {\n\t\t\t\treturn fromSchemaDriven\n\t\t\t}\n\t\t\t// Direct-mount fallback: legacy callers pass `objectType` +\n\t\t\t// `objectId`. Read the same cache shape but keyed off the\n\t\t\t// explicit slug.\n\t\t\tconst store = this.effectiveObjectStore\n\t\t\tif (!store) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tif (!this.objectType || !this.objectId) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn store.objects?.[this.objectType]?.[this.objectId] ?? null\n\t\t},\n\n\t\t/**\n\t\t * The resolved record's human display name, drawn from the loaded\n\t\t * object via the same fallback chain the relation resolver uses:\n\t\t * `@self.name` → `name` / `title` / `displayName` → `firstName\n\t\t * lastName`. Empty string while the object is still loading or when no\n\t\t * name-like field exists (a raw id is never used as a name — ADR-062).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tobjectDisplayName() {\n\t\t\tconst obj = this.resolvedObject\n\t\t\tif (!obj || typeof obj !== 'object') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tconst self = obj['@self'] || {}\n\t\t\tconst id = this.objectId !== null && this.objectId !== undefined ? String(this.objectId) : ''\n\t\t\tconst candidates = [self.name, self.title, obj.name, obj.title, obj.displayName]\n\t\t\tfor (const c of candidates) {\n\t\t\t\tif (c !== null && c !== undefined && c !== '' && String(c) !== id) {\n\t\t\t\t\treturn String(c)\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst composed = ((obj.firstName || '') + ' ' + (obj.lastName || '')).trim()\n\t\t\treturn composed || ''\n\t\t},\n\n\t\t/**\n\t\t * The header `<h2>` text. Prefers the resolved record's display name\n\t\t * so the header names the record (\"ACME Corp\") rather than its type\n\t\t * (\"Case\"); falls back to the `title` prop (the type/label) while the\n\t\t * object is loading or has no name field.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tdisplayTitle() {\n\t\t\treturn this.objectDisplayName || this.resolvedTitle\n\t\t},\n\n\t\t/**\n\t\t * Effective translate function: the injected `cnTranslate` (the host\n\t\t * app's bound `t()`), identity by default.\n\t\t *\n\t\t * @return {(key: string) => string}\n\t\t */\n\t\teffectiveTranslate() {\n\t\t\treturn typeof this.cnTranslate === 'function' ? this.cnTranslate : (key) => key\n\t\t},\n\n\t\t/**\n\t\t * The `title` prop (the manifest-authored type label) run through the\n\t\t * host translate function. Used for the header fallback and the type\n\t\t * eyebrow; the record's own display name is data and stays untouched.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedTitle() {\n\t\t\treturn this.title ? this.effectiveTranslate(this.title) : this.title\n\t\t},\n\n\t\t/**\n\t\t * The page description run through the host translate function.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedDescription() {\n\t\t\treturn this.description ? this.effectiveTranslate(this.description) : this.description\n\t\t},\n\n\t\t/**\n\t\t * The statistics section heading run through the host translate function.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedStatsTitle() {\n\t\t\treturn this.statsTitle ? this.effectiveTranslate(this.statsTitle) : this.statsTitle\n\t\t},\n\n\t\t/**\n\t\t * The small type-label eyebrow shown above the record name. Only\n\t\t * rendered once a record name is resolved AND it differs from the\n\t\t * `title` prop, so the type context (\"Case\", \"Publication\") is kept\n\t\t * without shadowing the record name. Empty while loading (the type\n\t\t * label is then the `<h2>` itself).\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\ttypeEyebrow() {\n\t\t\tconst name = this.objectDisplayName\n\t\t\tif (!name || !this.title || name === this.title) {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn this.resolvedTitle\n\t\t},\n\n\t\t/**\n\t\t * The fetched JSON Schema for the schema-driven mode. Read from\n\t\t * the store's `schemas[type]` cache populated by `fetchSchema`.\n\t\t * Required to render `CnObjectDataWidget` (which takes a schema\n\t\t * Object, not a slug).\n\t\t *\n\t\t * @return {object|null}\n\t\t */\n\t\tcurrentSchema() {\n\t\t\tconst store = this.effectiveObjectStore\n\t\t\tif (!store) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst type = this.resolvedObjectType\n\t\t\tif (!type) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn store.schemas?.[type] ?? null\n\t\t},\n\n\t\t/**\n\t\t * True when consumer-supplied default slot content IS present.\n\t\t * Treats comment placeholders and whitespace-only text vnodes as\n\t\t * no content so a stray newline in the template doesn't\n\t\t * accidentally suppress the auto-body.\n\t\t *\n\t\t * `$slots.default` is a FUNCTION in Vue 3 — it has to be called to\n\t\t * get the vnodes. Reading `.length` off it yields the function's\n\t\t * arity (always 0 for a compiled slot), which made this read\n\t\t * `false` unconditionally and let the auto-body render on top of\n\t\t * whatever the consumer had put in the slot.\n\t\t */\n\t\thasDefaultSlotContent() {\n\t\t\treturn slotRenders(this.$slots.default)\n\t\t},\n\n\t\t/**\n\t\t * True when the auto-body (CnObjectDataWidget + CnObjectMetadataWidget)\n\t\t * should render. Conditions: schema-driven mount, the object has\n\t\t * loaded, no consumer slot wins, and the grid-layout mode is not\n\t\t * active (grid mode owns the body when present).\n\t\t */\n\t\tshouldRenderAutoBody() {\n\t\t\treturn this.hasSchemaDrivenFetch\n\t\t\t\t&& this.currentObject\n\t\t\t\t&& !this.hasDefaultSlotContent\n\t\t\t\t&& !this.hasGridLayout\n\t\t},\n\n\t\t/**\n\t\t * The object context handed to integration widgets.\n\t\t *\n\t\t * An explicit `integrationContext` prop wins; otherwise it is derived the\n\t\t * way it always was, falling back through the resolved sidebar config and\n\t\t * `sidebarProps` before the page's own register/schema. That fallback\n\t\t * chain is why this is computed HERE and passed down rather than derived\n\t\t * inside CnDetailWidgetHost: `resolvedSidebar` and `sidebarProps` are page\n\t\t * state the host has no view of, and deriving from `register`/`schema`\n\t\t * alone hands the widget two empty strings.\n\t\t *\n\t\t * @return {object} `{ register, schema, objectId }`.\n\t\t */\n\t\teffectiveIntegrationContext() {\n\t\t\tif (this.integrationContext) {\n\t\t\t\treturn this.integrationContext\n\t\t\t}\n\t\t\tconst resolved = this.resolvedSidebar || {}\n\t\t\treturn {\n\t\t\t\tregister: resolved.register || this.sidebarProps?.register || this.register || '',\n\t\t\t\tschema: resolved.schema || this.schema || this.resolvedObjectType || this.sidebarProps?.schema || '',\n\t\t\t\tobjectId: this.objectId ? String(this.objectId) : '',\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Effective layout array driving the body grid. An explicit `layout` prop\n\t\t * (manifest grid page) wins; otherwise the materialized default auto-body\n\t\t * (Data + Related) is used when the schema-driven object has loaded.\n\t\t *\n\t\t * @return {Array} Layout items for CnDashboardGrid.\n\t\t */\n\t\tbodyGridLayout() {\n\t\t\t// Depend on the (always-reactive) edit flag so this re-evaluates\n\t\t\t// when in-app edit mode flips: the manifest arrays are raw until\n\t\t\t// useManifestEditor.enter() observes them in place, so a cache\n\t\t\t// built pre-edit would stay frozen for in-place pushes (Add widget\n\t\t\t// on a detail page / grid ejection). See CnDashboardPage.hasWidgets.\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unused-expressions -- reading the flag IS the effect: the read registers the reactive dependency, and there is nothing to assign it to\n\t\t\tthis.editingBody\n\t\t\tif (this.hasGridLayout) {\n\t\t\t\treturn this.closeDroppedRows(this.layout)\n\t\t\t}\n\t\t\tif (this.shouldRenderAutoBody) {\n\t\t\t\treturn this.closeDroppedRows(this.autoBodyLayout || [])\n\t\t\t}\n\t\t\treturn []\n\t\t},\n\n\t\t/**\n\t\t * Effective widget-definition array paired with `bodyGridLayout`. Used by\n\t\t * the overridden `findWidget` so both the prop-driven and the default\n\t\t * auto-body grids resolve their widget defs from one place.\n\t\t *\n\t\t * @return {Array} Widget definitions.\n\t\t */\n\t\tbodyGridWidgets() {\n\t\t\tif (this.hasGridLayout) {\n\t\t\t\treturn this.widgets\n\t\t\t}\n\t\t\tif (this.shouldRenderAutoBody) {\n\t\t\t\treturn this.autoBodyWidgets || []\n\t\t\t}\n\t\t\treturn []\n\t\t},\n\n\t\t/**\n\t\t * Whether the body renders as an adjustable widget grid (vs. the\n\t\t * hand-authored default slot). True for explicit grid pages and for the\n\t\t * schema-driven default Data + Related body.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\thasBodyGrid() {\n\t\t\treturn this.bodyGridLayout.length > 0\n\t\t},\n\n\t\t/**\n\t\t * Whether the sidebar is rendered externally (via objectSidebarState inject)\n\t\t * rather than inline. When external, CnDetailPage only manages state —\n\t\t * the parent App renders the actual NcAppSidebar.\n\t\t */\n\t\thasExternalSidebar() {\n\t\t\treturn !!this.objectSidebarState\n\t\t},\n\n\t\t/**\n\t\t * Normalised sidebar config object regardless of input shape.\n\t\t *\n\t\t * - Boolean `true` → `{ show: true, enabled: true }`\n\t\t * - Boolean `false` → `{ show: false, enabled: false }`\n\t\t * - Object → fields passed through; `show` and\n\t\t * `enabled` default to `true` when omitted.\n\t\t *\n\t\t * Centralising the normalisation here keeps `syncSidebarState`\n\t\t * and the deprecation/conflict-warning logic single-sourced.\n\t\t */\n\t\tresolvedSidebar() {\n\t\t\tconst cfg = this.sidebar\n\t\t\t// A non-empty manifest `sidebarTabs` prop is itself an opt-in:\n\t\t\t// a `type:\"detail\"` page that declares tabs clearly wants the\n\t\t\t// sidebar. The `sidebar` prop defaults to Boolean `false`, and\n\t\t\t// CnPageRenderer only forwards a `sidebar` config when the\n\t\t\t// manifest page sets one — so a page that declares ONLY\n\t\t\t// `config.sidebarTabs` (procest CaseDetail) would otherwise fall\n\t\t\t// into the Boolean-`false` branch below and never publish its\n\t\t\t// strip. When tabs are present we treat the sidebar as enabled\n\t\t\t// (the explicit Object form below still overrides show/enabled).\n\t\t\tconst hasTabs = Array.isArray(this.sidebarTabs) && this.sidebarTabs.length > 0\n\t\t\tif (typeof cfg === 'boolean') {\n\t\t\t\tif (cfg) {\n\t\t\t\t\treturn { show: true, enabled: true }\n\t\t\t\t}\n\t\t\t\treturn hasTabs ? { show: true, enabled: true } : { show: false, enabled: false }\n\t\t\t}\n\t\t\tif (cfg && typeof cfg === 'object') {\n\t\t\t\treturn {\n\t\t\t\t\tshow: cfg.show !== false,\n\t\t\t\t\tenabled: cfg.enabled !== false,\n\t\t\t\t\t...cfg,\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn hasTabs ? { show: true, enabled: true } : { show: false, enabled: false }\n\t\t},\n\n\t\t/**\n\t\t * True when the sidebar should be wired into the external\n\t\t * `objectSidebarState` channel. Both `show` and `enabled`\n\t\t * must be non-`false` (defaults are `true`); either can\n\t\t * suppress the sidebar declaratively.\n\t\t */\n\t\tsidebarActive() {\n\t\t\tconst r = this.resolvedSidebar\n\t\t\t// An explicit `show: false` always suppresses the sidebar. Otherwise a\n\t\t\t// non-empty `sidebarTabs` opt-in activates it even past the prop's\n\t\t\t// default `{ enabled: false }` — the procest CaseDetail manifest\n\t\t\t// pattern, where a page declares only `config.sidebarTabs`.\n\t\t\tif (r.show === false) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif (r.enabled === false) {\n\t\t\t\treturn Array.isArray(this.sidebarTabs) && this.sidebarTabs.length > 0\n\t\t\t}\n\t\t\treturn true\n\t\t},\n\n\t\thasStats() {\n\t\t\treturn this.statsColumns.length > 0 && (this.statsRows.length > 0 || !!this.$slots['stats-rows'])\n\t\t},\n\n\t\t/** Whether any declarative in-body sections are configured. */\n\t\thasBodyWidgets() {\n\t\t\treturn Array.isArray(this.bodyWidgets) && this.bodyWidgets.length > 0\n\t\t},\n\n\t\t/**\n\t\t * Sections that land at the END placement: those with no `placement`\n\t\t * (the default) or an explicit `placement: \"end\"`. The three named\n\t\t * placement mounts (before-body / after-data / after-related) filter by\n\t\t * exact value; this catches the rest so nothing is silently dropped.\n\t\t *\n\t\t * @return {Array}\n\t\t */\n\t\tendPlacementSections() {\n\t\t\tif (!this.hasBodyWidgets) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\tconst named = ['before-body', 'after-data', 'after-related']\n\t\t\treturn this.bodyWidgets.filter((s) => !s || !s.placement || !named.includes(s.placement))\n\t\t},\n\n\t\t/**\n\t\t * Page/object context forwarded to CnBodySections for token resolution\n\t\t * (`@objectId` / `@object.<field>` / `@workspace.<key>`) AND provided on\n\t\t * `cnSectionContext` for host section components that inject. Mirrors the\n\t\t * `cnObjectContext` ref the abstract list/stat widgets already read.\n\t\t * `setObject(object)` shows an object a section saved without a re-fetch.\n\t\t *\n\t\t * @return {{objectId: (string|null), object: (object|null), register: string, schema: string, setObject: function(object): void}}\n\t\t */\n\t\tsectionContext() {\n\t\t\tconst resolved = this.resolvedSidebar || {}\n\t\t\treturn {\n\t\t\t\tobjectId: (this.objectId !== undefined && this.objectId !== null) ? String(this.objectId) : null,\n\t\t\t\tobject: this.resolvedObject || null,\n\t\t\t\tregister: resolved.register || this.register || this.sidebarProps?.register || '',\n\t\t\t\tschema: resolved.schema || this.schema || this.resolvedObjectType || this.sidebarProps?.schema || '',\n\t\t\t\tconfig: this.cnAppConfigRef,\n\t\t\t\tsetObject: (object) => this.setCurrentObject(object),\n\t\t\t}\n\t\t},\n\t},\n\n\twatch: {\n\t\t// A load just settled (true → false) — remember it so later loads\n\t\t// refresh in place (full-page spinner only on the first load). Not\n\t\t// `immediate`: `loading` starts false before the first fetch begins,\n\t\t// so reacting to that initial false would suppress the first spinner.\n\t\tloading(val) {\n\t\t\tif (!val) {\n\t\t\t\tthis.hasLoadedOnce = true\n\t\t\t\t// Refresh settled — re-assert the sidebar state that\n\t\t\t\t// syncSidebarState skipped while loading was in flight.\n\t\t\t\tthis.syncSidebarState()\n\t\t\t}\n\t\t},\n\n\t\tawaitingObject() {\n\t\t\tthis.syncSidebarState()\n\t\t},\n\n\t\tobjectNotFound() {\n\t\t\tthis.syncSidebarState()\n\t\t},\n\n\t\t// Deep, like `sidebarTabs` / `sidebarProps` below: the manifest editors\n\t\t// mutate `page.config.sidebar` IN PLACE, so the reference CnPageRenderer\n\t\t// forwards never changes. A shallow watcher missed every such edit —\n\t\t// switching the sidebar off in CnEditSidebarModal did nothing until the\n\t\t// page was reloaded. assignSidebarState() only writes keys that actually\n\t\t// changed, so the extra calls cost a comparison.\n\t\tsidebar: {\n\t\t\timmediate: true,\n\t\t\tdeep: true,\n\t\t\thandler() {\n\t\t\t\tthis.syncSidebarState()\n\t\t\t},\n\t\t},\n\n\t\t// Keep the provided object context current so detail-page abstract\n\t\t// widgets (CnObjectListWidget / CnStatWidget) can resolve `@objectId` /\n\t\t// `@object.<field>` tokens against the live object.\n\t\tcurrentObject: {\n\t\t\timmediate: true,\n\t\t\thandler() {\n\t\t\t\tthis.syncObjectContext()\n\t\t\t\t// Re-publish the object into objectSidebarState so the\n\t\t\t\t// hoisted sidebar's data/metadata tab widgets stay current.\n\t\t\t\tthis.syncSidebarState()\n\t\t\t},\n\t\t},\n\n\t\t// Re-publish once the schema Object resolves (fetched async), so the\n\t\t// hoisted sidebar's `data` tab widget gets its `schema` prop.\n\t\tcurrentSchema(schema) {\n\t\t\tthis.syncSidebarState()\n\n\t\t\t// Put the Data widget back if the body materialized before the\n\t\t\t// schema arrived. See materializeAutoBody(): fetchObject and\n\t\t\t// fetchSchema race, `shouldRenderAutoBody` gates on the OBJECT\n\t\t\t// only, and the body materializes once — so losing that race meant\n\t\t\t// the page rendered its title and Related panel with every scalar\n\t\t\t// field permanently missing (shillinq#1073).\n\t\t\t//\n\t\t\t// Guarded by `dataWidgetDeferred` rather than by \"is the data\n\t\t\t// widget absent\", so a body the user has edited is never rewritten\n\t\t\t// underneath them. The flag is cleared by the re-materialize, so\n\t\t\t// this runs at most once per materialized body.\n\t\t\tif (schema && this.dataWidgetDeferred) {\n\t\t\t\tthis.materializeAutoBody()\n\t\t\t}\n\t\t},\n\n\t\t// Materialize the default body grid (Data + Related) the first time the\n\t\t// schema-driven object resolves so the detail body is an adjustable grid.\n\t\tshouldRenderAutoBody: {\n\t\t\timmediate: true,\n\t\t\thandler(active) {\n\t\t\t\tif (active && !this.autoBodyLayout) {\n\t\t\t\t\tthis.materializeAutoBody()\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\n\t\t// A different schema means a fresh default grid — drop the materialized\n\t\t// one so it rebuilds for the new object type.\n\t\tresolvedObjectType() {\n\t\t\tthis.autoBodyLayout = null\n\t\t\tthis.autoBodyWidgets = null\n\t\t\t// Cleared with the body it described. materializeAutoBody() sets it\n\t\t\t// afresh, so this only avoids carrying a stale \"deferred\" across a\n\t\t\t// type change.\n\t\t\tthis.dataWidgetDeferred = false\n\t\t},\n\n\t\ttitle() {\n\t\t\tthis.syncSidebarState()\n\t\t},\n\n\t\tsubtitle() {\n\t\t\tthis.syncSidebarState()\n\t\t},\n\n\t\tobjectType() {\n\t\t\tthis.syncSidebarState()\n\t\t},\n\n\t\t// Schema-driven props feed both the sidebar state (via\n\t\t// resolvedObjectType) and the auto-fetch path. Re-sync + re-fetch\n\t\t// whenever any of the three move so the page stays consistent if\n\t\t// a parent component swaps the active object.\n\t\tregister() {\n\t\t\tthis.syncSidebarState()\n\t\t\tthis.pushAiContext()\n\t\t\tthis.fetchObjectIfNeeded()\n\t\t},\n\n\t\tschema() {\n\t\t\tthis.syncSidebarState()\n\t\t\tthis.pushAiContext()\n\t\t\tthis.fetchObjectIfNeeded()\n\t\t},\n\n\t\tobjectId() {\n\t\t\tthis.syncSidebarState()\n\t\t\tthis.pushAiContext()\n\t\t\tthis.fetchObjectIfNeeded()\n\t\t\tthis.syncObjectContext()\n\t\t},\n\n\t\tsidebarTabs: {\n\t\t\tdeep: true,\n\t\t\thandler() {\n\t\t\t\tthis.syncSidebarState()\n\t\t\t},\n\t\t},\n\n\t\tsidebarProps: {\n\t\t\tdeep: true,\n\t\t\thandler() {\n\t\t\t\tthis.syncSidebarState()\n\t\t\t},\n\t\t},\n\t},\n\n\tcreated() {\n\t\tthis.pushAiContext()\n\t},\n\n\tmounted() {\n\t\t// Kick the schema-driven fetch once the component has mounted —\n\t\t// `effectiveObjectStore` relies on a live Pinia context, which\n\t\t// is guaranteed by mounted() but not by created().\n\t\tthis.fetchObjectIfNeeded()\n\t\tthis.scheduleCellOverflowAudit()\n\n\t\t// `cn:page:refresh` is the channel a successful write announces itself\n\t\t// on — the manifest `refresh` and `api-call` actions bump it, and so do\n\t\t// app dialogs after a save. Until now nothing on a schema-driven detail\n\t\t// page listened: `useEndpointSource` and CnChartWidget answered it, but\n\t\t// every widget reading the page's OBJECT (`type: \"data\"` above all)\n\t\t// reads the copy this component fetched once, so a page kept showing\n\t\t// values the backend had already changed. Measured on a dossiq draft:\n\t\t// publish returned `{\"published\":true,\"version\":1}`, a re-read showed\n\t\t// `isDraft: false`, and the page still said draft.\n\t\t//\n\t\t// The subscription lives HERE rather than in each widget on purpose.\n\t\t// One page carries several object-bound widgets; if each answered the\n\t\t// channel itself, one write would become one read per widget. This\n\t\t// component owns the object, so one write is one read however many\n\t\t// widgets are bound to it.\n\t\tthis._onPageRefresh = (payload) => this.onPageRefreshBus(payload)\n\t\tsubscribe(PAGE_REFRESH_CHANNEL, this._onPageRefresh)\n\t},\n\n\tupdated() {\n\t\tthis.scheduleCellOverflowAudit()\n\t},\n\n\tbeforeUnmount() {\n\t\tif (this._onPageRefresh) {\n\t\t\tunsubscribe(PAGE_REFRESH_CHANNEL, this._onPageRefresh)\n\t\t\tthis._onPageRefresh = null\n\t\t}\n\t\tif (this.hasExternalSidebar) {\n\t\t\tthis.objectSidebarState.active = false\n\t\t\t// Clear manifest-driven tabs so the next mount starts fresh\n\t\t\t// rather than inheriting the previous page's tab strip.\n\t\t\tthis.objectSidebarState.tabs = undefined\n\t\t}\n\t\t// Reset AI context fields so stale detail context doesn't leak\n\t\tif (this.cnAiContext) {\n\t\t\tthis.cnAiContext.pageKind = 'custom'\n\t\t\tthis.cnAiContext.objectUuid = undefined\n\t\t\tthis.cnAiContext.registerSlug = undefined\n\t\t\tthis.cnAiContext.schemaSlug = undefined\n\t\t}\n\t},\n\n\tmethods: {\n\t\t// Expose the shared grid helpers to the template (grid mode + auto-body).\n\t\tcnGridCellStyle,\n\t\thasGridRow,\n\n\t\t/**\n\t\t * Emit a list step. When the control is a link it has navigated\n\t\t * already, so the payload `{ event, to }` tells the host not to push\n\t\t * again (`useListNavigation`'s `goNext`/`goPrevious` honour it).\n\t\t *\n\t\t * @param {string} name `previous-record` or `next-record`.\n\t\t * @param {object|string|null} to The link target, or null.\n\t\t * @param {MouseEvent} event The click event.\n\t\t */\n\t\tonListStep(name, to, event) {\n\t\t\tif (to && this.$router) {\n\t\t\t\tthis.$emit(name, { event, to })\n\t\t\t} else {\n\t\t\t\tthis.$emit(name)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Move focus to the primary action when the skip link is followed.\n\t\t *\n\t\t * The `href` anchor alone moves the DOCUMENT to the element without\n\t\t * moving FOCUS to it in every browser, which is the difference\n\t\t * between a skip link that works and one that scrolls and then hands\n\t\t * the next tab press back to the top of the page.\n\t\t *\n\t\t * @param {Event} event The click event.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tonSkipToPrimaryAction(event) {\n\t\t\tconst target = this.$refs.primaryActionButton?.$el ?? this.$refs.primaryActionButton\n\t\t\tconst focusable = target?.matches?.('button, a') ? target : target?.querySelector?.('button, a')\n\t\t\tif (focusable?.focus) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tfocusable.focus()\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * The active tab changed: tell the host, and put it in the address\n\t\t * when the page declares that its tab is part of its address.\n\t\t *\n\t\t * `replace`, never `push`, for the FIRST tab of a visit: an address\n\t\t * that arrived without a tab is being corrected to its canonical form\n\t\t * (ADR-052), and a correction must not become a history entry the\n\t\t * back button walks into. Later changes push, so back and forward\n\t\t * walk the tabs the reader actually visited.\n\t\t *\n\t\t * @param {string} tabId The tab now active.\n\t\t * @param {boolean} [canonicalising] Whether this is the arrival correction rather than a reader's choice.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tonTabChange(tabId, canonicalising = false) {\n\t\t\tif (typeof tabId !== 'string' || tabId === '') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\t/**\n\t\t\t * @event tab-change Emitted when the active tab changes.\n\t\t\t * @type {string}\n\t\t\t */\n\t\t\tthis.$emit('tab-change', tabId)\n\t\t\tif (!this.tabInAddress || !this.$router || !this.$route) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (this.$route.query?._tab === tabId) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst to = { name: this.$route.name, params: { ...this.$route.params }, query: { ...this.$route.query, _tab: tabId } }\n\t\t\tconst navigate = canonicalising ? this.$router.replace : this.$router.push\n\t\t\tnavigate.call(this.$router, to).catch(() => {})\n\t\t},\n\n\t\t/**\n\t\t * The tab the address asks for, or null.\n\t\t *\n\t\t * @return {string|null} The tab id.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\trequestedTabFromAddress() {\n\t\t\tconst tab = this.$route?.query?._tab\n\t\t\treturn typeof tab === 'string' && tab !== '' ? tab : null\n\t\t},\n\n\t\t/**\n\t\t * The sidebar settled on a tab: put it in the address.\n\t\t *\n\t\t * The sidebar reports the tab it actually shows, not the one that was\n\t\t * asked for, so an address naming a tab this reader may not see is\n\t\t * corrected to the one they can. `canonicalising` is true for that\n\t\t * correction and for the tabless arrival, so neither becomes a\n\t\t * history entry the back button walks into (ADR-052).\n\t\t *\n\t\t * @param {string} tabId The tab now showing.\n\t\t * @param {boolean} [canonicalising] Whether this is a correction rather than a reader's choice.\n\t\t * @spec openspec/changes/case-page-and-list-as-a-place/specs/index-page/spec.md\n\t\t */\n\t\tonSidebarTabChange(tabId, canonicalising = false) {\n\t\t\tthis.onTabChange(tabId, canonicalising || this.requestedTabFromAddress() === null)\n\t\t},\n\n\t\t/**\n\t\t * Release the lock the current user holds on this record.\n\t\t *\n\t\t * Only reachable from the locked card's Unlock button, which the card\n\t\t * only renders for the viewer's OWN lock — so this never releases\n\t\t * somebody else's. A failure is left to `useObjectLock`, which logs it;\n\t\t * the flag is cleared either way so a failed release does not strand\n\t\t * the button disabled.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync onReleaseLock() {\n\t\t\tif (!this.lockState || this.releasingLock) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.releasingLock = true\n\t\t\ttry {\n\t\t\t\tawait this.lockState.release()\n\t\t\t} finally {\n\t\t\t\tthis.releasingLock = false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Re-emit the page-header menu's Refresh to the host.\n\t\t *\n\t\t * @param {{ widgetId: string, title: string }} payload - Action payload.\n\t\t * @param {object} event - Synthetic event (host may preventDefault).\n\t\t */\n\t\tasync onHeaderRefresh(payload, event) {\n\t\t\t/**\n\t\t\t * @event refresh The page-header Refresh action was clicked.\n\t\t\t * @type {{ widgetId: string, title: string }}\n\t\t\t */\n\t\t\tthis.$emit('refresh', payload, event)\n\t\t\t// Schema-driven (manifest) detail pages self-fetch — without this\n\t\t\t// the Refresh action has no host listener to act on and does\n\t\t\t// nothing. Re-fetch the object + schema and spin the action.\n\t\t\tif (!this.hasSchemaDrivenFetch) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.internalRefreshing = true\n\t\t\tconst done = this.fetchObjectIfNeeded()\n\t\t\tevent?.waitUntil?.(done)\n\t\t\ttry {\n\t\t\t\tawait done\n\t\t\t} finally {\n\t\t\t\tthis.internalRefreshing = false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * A `cn:page:refresh` reached the page — re-read the object so every\n\t\t * object-bound widget re-renders from what the backend now holds.\n\t\t *\n\t\t * Deliberately a no-op while `internalRefreshing` is set. The header's\n\t\t * own Refresh item emits `@refresh` FIRST and only then emits on this\n\t\t * channel (see CnActionsMenu.onRefreshClick), and `onHeaderRefresh`\n\t\t * sets the flag synchronously before awaiting its fetch — so without\n\t\t * this guard one click on Refresh would fetch the object twice.\n\t\t *\n\t\t * @param {{ waitUntil?: (promise: Promise<unknown>) => void }} [payload] Bus payload.\n\t\t * @return {void}\n\t\t */\n\t\tonPageRefreshBus(payload) {\n\t\t\tif (!this.hasSchemaDrivenFetch) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (this.internalRefreshing) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.internalRefreshing = true\n\t\t\tconst done = Promise.resolve(this.fetchObjectIfNeeded()).finally(() => {\n\t\t\t\tthis.internalRefreshing = false\n\t\t\t})\n\t\t\tpayload?.waitUntil?.(done)\n\t\t},\n\n\t\t/**\n\t\t * Re-emit the page-header menu's Request-a-feature to the host.\n\t\t *\n\t\t * @param {{ widgetId: string, title: string }} payload - Action payload.\n\t\t * @param {object} event - Synthetic event (host may preventDefault).\n\t\t */\n\t\tonHeaderRequestFeature(payload, event) {\n\t\t\t/**\n\t\t\t * @event request-feature The page-header Request-a-feature action\n\t\t\t * was clicked.\n\t\t\t * @type {{ widgetId: string, title: string }}\n\t\t\t */\n\t\t\tthis.$emit('request-feature', payload, event)\n\t\t},\n\n\t\t/**\n\t\t * Open the sidebar leaf a \"Linked apps\" row on the auto-body\n\t\t * CnRelatedObjectsWidget points at. Publishes the requested tab and\n\t\t * opens the external sidebar via `objectSidebarState`, and re-emits\n\t\t * `open-integration` so a host can override the routing.\n\t\t *\n\t\t * @param {string} integrationId - The leaf integration id (tab id).\n\t\t */\n\t\tonAutoBodyOpenIntegration(integrationId) {\n\t\t\tif (this.hasExternalSidebar && this.objectSidebarState) {\n\t\t\t\tthis.objectSidebarState.open = true\n\t\t\t\tthis.objectSidebarState.requestedTab = integrationId\n\t\t\t}\n\t\t\t/**\n\t\t\t * @event open-integration A related-objects \"Linked apps\" row\n\t\t\t * was clicked on the auto-body. Payload is the leaf id.\n\t\t\t * @type {string}\n\t\t\t */\n\t\t\tthis.$emit('open-integration', integrationId)\n\t\t},\n\n\t\t/**\n\t\t * Re-fetch the object after the geo widget persists `@self.geo` (so the\n\t\t * rest of the page — metadata, other widgets — reflects the new value),\n\t\t * and re-emit for the host.\n\t\t *\n\t\t * @param {object|null} geo The saved geo value (GeoJSON Point or null).\n\t\t */\n\t\tonGeoSaved(geo) {\n\t\t\tthis.fetchObjectIfNeeded()\n\t\t\t/**\n\t\t\t * @event geo-saved The object's `@self.geo` was saved via the geo\n\t\t\t * widget. Payload is the saved geo value (GeoJSON Point or null).\n\t\t\t * @type {object|null}\n\t\t\t */\n\t\t\tthis.$emit('geo-saved', geo)\n\t\t},\n\n\t\t/**\n\t\t * Re-emit a successful lifecycle transition to the host.\n\t\t *\n\t\t * @param {{ action: string, to: string, object: object }} payload The transition result.\n\t\t */\n\t\tonTransitioned(payload) {\n\t\t\t/**\n\t\t\t * @event transitioned A declarative lifecycle transition succeeded on this\n\t\t\t * page's object. Payload is `{ action, to, object }`.\n\t\t\t * @type {{ action: string, to: string, object: object }}\n\t\t\t */\n\t\t\tthis.$emit('transitioned', payload)\n\t\t},\n\n\t\t/**\n\t\t * Re-fetch the page's object after a lifecycle transition so the new state\n\t\t * (and any other server-side mutations the guard applied) render.\n\t\t */\n\t\tonLifecycleReload() {\n\t\t\tthis.fetchObjectIfNeeded()\n\t\t},\n\n\t\t/**\n\t\t * Open the relation-link modal for a configured `relationLinks` entry.\n\t\t *\n\t\t * @param {object} link The relation-link descriptor.\n\t\t */\n\t\topenRelationLink(link) {\n\t\t\tthis.activeRelationLink = link\n\t\t},\n\n\t\t/**\n\t\t * A relation-link modal saved a patched FK — re-fetch the object and\n\t\t * re-emit so the host can react.\n\t\t *\n\t\t * @param {object} saved The updated object.\n\t\t */\n\t\tonRelationLinked(saved) {\n\t\t\tthis.fetchObjectIfNeeded()\n\t\t\t/**\n\t\t\t * @event relation-linked A relation-link action patched a foreign key on\n\t\t\t * this page's object. Payload is the updated object.\n\t\t\t * @type {object}\n\t\t\t */\n\t\t\tthis.$emit('relation-linked', saved)\n\t\t},\n\n\t\t/**\n\t\t * Re-emit a related-collection row click to the host.\n\t\t *\n\t\t * @param {{ collection: object, row: object, index: number }} payload The click payload.\n\t\t */\n\t\tonRelatedRowClick(payload) {\n\t\t\t/**\n\t\t\t * @event related-row-click A row in a `relatedCollections` section was\n\t\t\t * clicked. Payload is `{ collection, row, index }`.\n\t\t\t * @type {{ collection: object, row: object, index: number }}\n\t\t\t */\n\t\t\tthis.$emit('related-row-click', payload)\n\t\t},\n\n\t\t/**\n\t\t * Replace the page's object in the store cache, for a section that saved\n\t\t * it and holds the saved version. An object with another id is ignored.\n\t\t *\n\t\t * @param {object} object The saved object.\n\t\t */\n\t\tsetCurrentObject(object) {\n\t\t\tconst store = this.effectiveObjectStore\n\t\t\tconst type = this.resolvedObjectType\n\t\t\tif (!store || !type || !this.objectId || !object) {\n\t\t\t\t// eslint-disable-next-line no-console -- tells the integrating section its save is not shown\n\t\t\t\tconsole.warn('[CnDetailPage] setObject ignored: the page has no object store, type or id')\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst id = object.id ?? object['@self']?.id\n\t\t\tif (id !== undefined && id !== null && String(id) !== String(this.objectId)) {\n\t\t\t\t// eslint-disable-next-line no-console -- tells the integrating section its save is not shown\n\t\t\t\tconsole.warn(`[CnDetailPage] setObject ignored: object ${id} is not the page's object ${this.objectId}`)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tstore.objects = {\n\t\t\t\t...store.objects,\n\t\t\t\t[type]: { ...(store.objects?.[type] || {}), [this.objectId]: object },\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Schema-driven fetch entry point — no-op outside the\n\t\t * `register`+`schema`+`objectId` mode. Registers the type on\n\t\t * the store with the canonical 4-arg signature (matches what\n\t\t * `CnIndexPage` does), then fetches the object and its schema\n\t\t * in parallel. Errors land on `this._fetchError` (exposed via\n\t\t * the `error` template gate); the loading flag is intentionally\n\t\t * left to the store's own per-type `loading[type]` so it\n\t\t * cooperates with parallel fetches from sibling components.\n\t\t *\n\t\t * Called from `mounted()` and from the `register` / `schema` /\n\t\t * `objectId` watchers — every prop change re-runs in one\n\t\t * place so the request lifecycle stays predictable.\n\t\t */\n\t\tasync fetchObjectIfNeeded() {\n\t\t\t// Create archetype: no object to fetch, but the create form needs\n\t\t\t// the schema — register the type and fetch its schema, then stop.\n\t\t\tif (!this.hasSchemaDrivenFetch) {\n\t\t\t\tthis.objectFetchPending = false\n\t\t\t\tif (this.isCreateMode) {\n\t\t\t\t\tawait this.fetchSchemaForCreate()\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst store = this.effectiveObjectStore\n\t\t\tif (!store) {\n\t\t\t\tthis.objectFetchPending = false\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst type = this.resolvedObjectType\n\t\t\t// (slug, schemaId, registerId, slugs) — same shape as the\n\t\t\t// CnIndexPage / CnLogsPage fix. Passing the slug strings into\n\t\t\t// the positional id slots is intentional (OR's REST accepts\n\t\t\t// either numeric ids or kebab slugs there), and the 4th-arg\n\t\t\t// hints feed the live-updates transport.\n\t\t\t// Register the type ONCE. `registerObjectType` resets the type's\n\t\t\t// cache (`objects[type] = {}`, `schemas[type] = null`), so calling\n\t\t\t// it on every refresh blanks the object + schema until the\n\t\t\t// re-fetch lands — the content visibly disappears mid-refresh.\n\t\t\t// Skip re-registration when the type is already registered so a\n\t\t\t// refresh re-fetches and replaces the data in place.\n\t\t\tif (typeof store.registerObjectType === 'function'\n\t\t\t\t&& !store.objectTypeRegistry?.[type]) {\n\t\t\t\tstore.registerObjectType(\n\t\t\t\t\ttype,\n\t\t\t\t\tthis.schema,\n\t\t\t\t\tthis.register,\n\t\t\t\t\t{ registerSlug: this.register, schemaSlug: this.schema },\n\t\t\t\t)\n\t\t\t}\n\t\t\tconst objectId = this.objectId\n\t\t\tconst fetchesObject = typeof store.fetchObject === 'function'\n\t\t\tthis.objectFetchPending = fetchesObject\n\t\t\tif (fetchesObject) {\n\t\t\t\tthis.objectNotFound = false\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst tasks = []\n\t\t\t\tif (fetchesObject) {\n\t\t\t\t\ttasks.push(store.fetchObject(type, objectId))\n\t\t\t\t}\n\t\t\t\tif (typeof store.fetchSchema === 'function') {\n\t\t\t\t\ttasks.push(store.fetchSchema(type))\n\t\t\t\t}\n\t\t\t\tawait Promise.all(tasks)\n\t\t\t} catch (err) {\n\t\t\t\t// eslint-disable-next-line no-console -- the failure is already handled; the console is the only channel a host app can read the detail on\n\t\t\t\tconsole.error('[CnDetailPage] schema-driven fetch failed:', err)\n\t\t\t} finally {\n\t\t\t\t// A newer fetch for another id owns the flags now.\n\t\t\t\tif (fetchesObject && objectId === this.objectId) {\n\t\t\t\t\tthis.objectNotFound = !store.objects?.[type]?.[objectId]\n\t\t\t\t\t\t&& store.getError?.(type)?.status === 404\n\t\t\t\t\tthis.objectFetchPending = false\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Whether a grid-layout item resolves to an integration-typed\n\t\t * widget — `def.type === 'integration'` with a string\n\t\t * `integrationId`. Used by the grid template to render the\n\t\t * registry widget as the slot fallback.\n\t\t *\n\t\t * @param {object} item Layout item\n\t\t * @return {boolean} true when the matching widget def is an integration widget\n\t\t */\n\t\t/**\n\t\t * Register the type and fetch ONLY its schema, for the create archetype\n\t\t * (no object id to fetch). Populates `currentSchema` so the inline create\n\t\t * form can auto-generate its fields.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync fetchSchemaForCreate() {\n\t\t\tconst store = this.effectiveObjectStore\n\t\t\tif (!store) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst type = this.resolvedObjectType\n\t\t\tif (typeof store.registerObjectType === 'function'\n\t\t\t\t&& !store.objectTypeRegistry?.[type]) {\n\t\t\t\tstore.registerObjectType(\n\t\t\t\t\ttype,\n\t\t\t\t\tthis.schema,\n\t\t\t\t\tthis.register,\n\t\t\t\t\t{ registerSlug: this.register, schemaSlug: this.schema },\n\t\t\t\t)\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tif (typeof store.fetchSchema === 'function') {\n\t\t\t\t\tawait store.fetchSchema(type)\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\t// eslint-disable-next-line no-console -- the failure is already handled; the console is the only channel a host app can read the detail on\n\t\t\t\tconsole.error('[CnDetailPage] create-mode schema fetch failed:', err)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Persist the create form: POST the new object to OpenRegister, then\n\t\t * navigate to the created object's detail route (`createRoute` with its\n\t\t * id) — or back in history when no route is configured.\n\t\t *\n\t\t * Returns the outcome as well as applying it. The built-in dialog reads\n\t\t * the outcome off its own ref (`createFormDialog.setResult`), which a\n\t\t * `#form-dialog` replacement does not have — the returned result is how\n\t\t * a replacement learns whether to unlock its own dialog. Nothing on the\n\t\t * default path consumes the return value.\n\t\t *\n\t\t * @param {object} formData The confirmed form values.\n\t\t * @return {Promise<{success?: boolean, data?: object, error?: string}>}\n\t\t */\n\t\tasync onCreateFormConfirm(formData) {\n\t\t\ttry {\n\t\t\t\tconst [{ default: axios }, { generateUrl }] = await Promise.all([\n\t\t\t\t\timport('@nextcloud/axios'),\n\t\t\t\t\timport('@nextcloud/router'),\n\t\t\t\t])\n\t\t\t\tconst url = generateUrl(\n\t\t\t\t\t'/apps/openregister/api/objects/{register}/{schema}',\n\t\t\t\t\t{ register: this.register, schema: this.schema },\n\t\t\t\t)\n\t\t\t\tconst res = await axios.post(url, formData)\n\t\t\t\tconst created = (res && res.data) ? res.data : {}\n\t\t\t\tconst newId = (created['@self'] && created['@self'].id) || created.id\n\t\t\t\tif (this.$refs.createFormDialog) {\n\t\t\t\t\tthis.$refs.createFormDialog.setResult({ success: true })\n\t\t\t\t}\n\t\t\t\t/**\n\t\t\t\t * @event created Emitted after a successful create-form save.\n\t\t\t\t * @type {object}\n\t\t\t\t */\n\t\t\t\tthis.$emit('created', created)\n\t\t\t\tif (this.createRoute && newId && this.$router) {\n\t\t\t\t\tthis.$router.push({ name: this.createRoute, params: { id: String(newId) } }).catch(() => {})\n\t\t\t\t} else if (this.$router) {\n\t\t\t\t\tthis.$router.back()\n\t\t\t\t}\n\t\t\t\treturn { success: true, data: created }\n\t\t\t} catch (e) {\n\t\t\t\tconst error = (e && e.message) || 'error'\n\t\t\t\tif (this.$refs.createFormDialog) {\n\t\t\t\t\tthis.$refs.createFormDialog.setResult({ error })\n\t\t\t\t}\n\t\t\t\treturn { error }\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * `confirm` for the `#form-dialog` slot: the page's own save path,\n\t\t * handed to a replacement dialog so a create or edit made there behaves\n\t\t * exactly like one made in the built-in dialog — same duplicate-id\n\t\t * refusal, same store-then-axios fallback, same `created` / `edited`\n\t\t * events, same lifecycle reload.\n\t\t *\n\t\t * Bound as a PROP rather than left as an `@confirm` listener, because\n\t\t * CnPageRenderer mounts a manifest-declared replacement with\n\t\t * `v-bind=\"slotProps\"` — props only. A listener is unreachable from a\n\t\t * manifest even in principle, which is what made the same slot on\n\t\t * CnIndexPage decorative until openconnector#1150.\n\t\t *\n\t\t * Dispatches on `isCreateMode`, the same flag that decides which of the\n\t\t * two built-in dialogs renders — they are mutually exclusive, since\n\t\t * create mode is by definition a page with no object id.\n\t\t *\n\t\t * @param {object} formData The submitted form values.\n\t\t * @return {Promise<{success?: boolean, data?: object, error?: string}>} The save outcome, for the replacement's own `setResult`.\n\t\t */\n\t\tonFormDialogConfirm(formData) {\n\t\t\treturn this.isCreateMode\n\t\t\t\t? this.onCreateFormConfirm(formData)\n\t\t\t\t: this.onEditFormConfirm(formData)\n\t\t},\n\n\t\t/**\n\t\t * `close` for the `#form-dialog` slot. Dispatches the same way\n\t\t * `onFormDialogConfirm` does, so a dismissed create still navigates\n\t\t * back rather than stranding the user on an id-less page.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tonFormDialogClose() {\n\t\t\tif (this.isCreateMode) {\n\t\t\t\tthis.onCreateFormClose()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.closeEditForm()\n\t\t},\n\n\t\t/**\n\t\t * Open the record edit form.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\topenEditForm() {\n\t\t\t// 🔴 OPENING TAKES THE LOCK. Two people editing one record is not\n\t\t\t// resolved by whoever presses Save last: the first person's work is\n\t\t\t// gone and neither of them is told. The button is already withdrawn\n\t\t\t// while somebody else holds the lock (`canEditRecord`), so this is\n\t\t\t// the backstop for the seconds between the last read and the click.\n\t\t\t//\n\t\t\t// 🔑 THE FORM OPENS SYNCHRONOUSLY, AND THE ACQUIRE RUNS BESIDE IT.\n\t\t\t// Awaiting the round trip here would make `openEditForm()` async,\n\t\t\t// and every consumer that calls it and then asserts or renders on\n\t\t\t// the next tick would see a form that is not open yet: measured,\n\t\t\t// 10 of the 17 `CnDetailPageFormDialogSlot` tests went red on\n\t\t\t// exactly that. A conflict closes the form again and names the\n\t\t\t// holder, which is the same outcome one tick later.\n\t\t\tthis.editLockRefusal = ''\n\t\t\tthis.editFormOpen = true\n\t\t\tthis.acquireEditLock()\n\t\t},\n\n\t\t/**\n\t\t * Take the lock for the edit that just opened.\n\t\t *\n\t\t * A refusal CLOSES the form and shows the holder, because a form left\n\t\t * open over somebody else's lock is a form that will be filled in and\n\t\t * then refused. Any other failure leaves the form open: the server\n\t\t * re-checks on the write, so a lock that could not be taken costs an\n\t\t * optimistic edit rather than an editor who cannot work at all.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tacquireEditLock() {\n\t\t\tif (!this.lockState) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.lockState.acquire().catch((e) => {\n\t\t\t\tif (e?.name !== 'LockConflictError') {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tthis.editLockRefusal = e.message\n\t\t\t\tthis.editFormOpen = false\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Close the record edit form without saving.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tcloseEditForm() {\n\t\t\tthis.editFormOpen = false\n\t\t\tthis.releaseEditLock()\n\t\t},\n\n\t\t/**\n\t\t * Hand back the lock this page took for an edit.\n\t\t *\n\t\t * Fire and forget and never throws: a release that fails must not stop\n\t\t * a form from closing, and the lock has a server-side TTL behind it.\n\t\t * `release()` is a no-op when the viewer does not hold the lock, so\n\t\t * calling it on a page that opened no form takes nothing from anybody.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\treleaseEditLock() {\n\t\t\tif (!this.lockState || !this.lockState.lockedByMe.value) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.lockState.release().catch(() => {})\n\t\t},\n\n\t\t/**\n\t\t * Persist an edit of the record this page is showing.\n\t\t *\n\t\t * Saves through the object store when one is available so the page's own\n\t\t * subscription re-renders with the new values; the store is also what\n\t\t * every other surface reads from, so a direct HTTP write would leave\n\t\t * them showing the pre-edit record until something else refetched.\n\t\t * Falls back to a PUT for consumers with no Pinia.\n\t\t *\n\t\t * Returns the outcome as well as applying it, for the same reason\n\t\t * `onCreateFormConfirm` does: a `#form-dialog` replacement has no ref\n\t\t * on the built-in dialog and would otherwise never learn whether the\n\t\t * save landed. Nothing on the default path consumes the return value.\n\t\t *\n\t\t * @param {object} formData The submitted form values.\n\t\t * @return {Promise<{success?: boolean, data?: object, error?: string}>}\n\t\t */\n\t\tasync onEditFormConfirm(formData) {\n\t\t\t// `saveObject` picks PUT over POST on the presence of `id`, and an\n\t\t\t// OpenRegister object carries its id in `@self`, not at the top\n\t\t\t// level. Without this the edit would CREATE a duplicate record.\n\t\t\tconst dialog = this.$refs.editFormDialog\n\t\t\tif (!this.objectId) {\n\t\t\t\t// REFUSE rather than save. An empty id does not error — it makes\n\t\t\t\t// saveObject POST, which silently CREATES A DUPLICATE and leaves\n\t\t\t\t// the record the user was editing untouched. That presents as\n\t\t\t\t// \"my change did not save\", with a new orphan row behind it, and\n\t\t\t\t// nothing anywhere says so.\n\t\t\t\tconst error = t('nextcloud-vue', 'Cannot save: this record has no id, so the edit would create a duplicate instead of updating it.')\n\t\t\t\tif (dialog) {\n\t\t\t\t\tdialog.setResult({ error })\n\t\t\t\t}\n\t\t\t\treturn { error }\n\t\t\t}\n\t\t\tconst payload = { ...formData, id: this.objectId }\n\t\t\ttry {\n\t\t\t\tconst store = this.effectiveObjectStore\n\t\t\t\tlet saved = null\n\t\t\t\tif (store && typeof store.saveObject === 'function' && this.resolvedObjectType) {\n\t\t\t\t\tsaved = await store.saveObject(this.resolvedObjectType, payload)\n\t\t\t\t\tif (!saved) {\n\t\t\t\t\t\tconst err = store.getError?.(this.resolvedObjectType)\n\t\t\t\t\t\tconst error = (err && err.message) || t('nextcloud-vue', 'Save failed')\n\t\t\t\t\t\tif (dialog) {\n\t\t\t\t\t\t\tdialog.setResult({ error })\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn { error }\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst [{ default: axios }, { generateUrl }] = await Promise.all([\n\t\t\t\t\t\timport('@nextcloud/axios'),\n\t\t\t\t\t\timport('@nextcloud/router'),\n\t\t\t\t\t])\n\t\t\t\t\tconst url = generateUrl(\n\t\t\t\t\t\t'/apps/openregister/api/objects/{register}/{schema}/{id}',\n\t\t\t\t\t\t{ register: this.register, schema: this.schema, id: this.objectId },\n\t\t\t\t\t)\n\t\t\t\t\tconst res = await axios.put(url, payload)\n\t\t\t\t\tsaved = (res && res.data) ? res.data : payload\n\t\t\t\t}\n\t\t\t\tif (dialog) {\n\t\t\t\t\tdialog.setResult({ success: true })\n\t\t\t\t}\n\t\t\t\tthis.editFormOpen = false\n\t\t\t\tthis.releaseEditLock()\n\t\t\t\t/**\n\t\t\t\t * @event edited Emitted after the record edit form saves successfully.\n\t\t\t\t * @type {object} The saved record.\n\t\t\t\t */\n\t\t\t\tthis.$emit('edited', saved)\n\t\t\t\tthis.onLifecycleReload()\n\t\t\t\treturn { success: true, data: saved }\n\t\t\t} catch (e) {\n\t\t\t\tconst error = (e && e.message) || t('nextcloud-vue', 'Save failed')\n\t\t\t\tif (dialog) {\n\t\t\t\t\tdialog.setResult({ error })\n\t\t\t\t}\n\t\t\t\treturn { error }\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * The create form was dismissed without saving — navigate back so the\n\t\t * user is not stranded on an id-less page.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tonCreateFormClose() {\n\t\t\t/**\n\t\t\t * @event create-cancel Emitted when the create form is dismissed.\n\t\t\t */\n\t\t\tthis.$emit('create-cancel')\n\t\t\tif (this.$router) {\n\t\t\t\tthis.$router.back()\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Whether a grid item is a schema-driven `data` widget — rendered via\n\t\t * CnObjectDataWidget with the page's loaded object + the def's overrides.\n\t\t *\n\t\t * @param {object} item Layout item\n\t\t * @return {boolean} true when the matching widget def is `type: 'data'`.\n\t\t */\n\t\tisDataWidget(item) {\n\t\t\treturn isDataWidgetDef(this.findWidget(item))\n\t\t},\n\n\t\t/**\n\t\t * Whether a grid item is the schema-driven `related` widget — rendered via\n\t\t * CnRelatedObjectsWidget with the page's loaded object. One of the two\n\t\t * default body widgets.\n\t\t *\n\t\t * @param {object} item Layout item\n\t\t * @return {boolean} true when the matching widget def is `type: 'related'`.\n\t\t */\n\t\tisRelatedWidget(item) {\n\t\t\treturn isRelatedWidgetDef(this.findWidget(item))\n\t\t},\n\n\t\t/**\n\t\t * Whether a grid item is the `object-geo` widget — rendered via\n\t\t * CnObjectGeoWidget with the page's loaded object so the user can view /\n\t\t * edit the object's `@self.geo` on a map.\n\t\t *\n\t\t * @param {object} item Layout item\n\t\t * @return {boolean} true when the matching widget def is `type: 'object-geo'`.\n\t\t */\n\t\tisGeoWidget(item) {\n\t\t\treturn isGeoWidgetDef(this.findWidget(item))\n\t\t},\n\n\t\t/**\n\t\t * Whether a grid item is a content-only catalog widget (a bare table\n\t\t * renderer with no chrome of its own). These get the titled\n\t\t * CnWidgetWrapper card in the grid (ADR-062); self-chromed catalog\n\t\t * widgets (stat / chart / gauge / tile / …) render bare.\n\t\t *\n\t\t * @param {object} item Layout item.\n\t\t * @return {boolean} true when the widget def's type is content-only.\n\t\t */\n\t\tisContentOnlyWidget(item) {\n\t\t\treturn isContentOnlyWidgetDef(this.findWidget(item))\n\t\t},\n\n\t\t/**\n\t\t * Whether a grid item is a registry \"card\" widget — a single self-\n\t\t * contained KPI / gauge / delta tile (registry entry `card: true`).\n\t\t * These render bare tile content, so on a detail page they need the\n\t\t * same titled CnWidgetWrapper card chrome the dashboard gives them\n\t\t * (ADR-062: a lone stat must not read as uncarded floating text —\n\t\t * pipelinq contracts / POS).\n\t\t *\n\t\t * @param {object} item Layout item.\n\t\t * @return {boolean} true when the widget def's registry entry is a card.\n\t\t */\n\t\tisCardWidget(item) {\n\t\t\treturn isCardWidgetDef(this.findWidget(item))\n\t\t},\n\n\t\t/**\n\t\t * Debounced dev-mode audit: warn when a grid widget's rendered content\n\t\t * overflows its fixed cell (ADR-062 — the cell is the budget; overflow\n\t\t * is a design bug, never a scroll surface). No-op in production builds.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tscheduleCellOverflowAudit() {\n\t\t\tif (process.env.NODE_ENV === 'production') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tclearTimeout(this._cellAuditTimer)\n\t\t\tthis._cellAuditTimer = setTimeout(() => this.auditCellOverflow(), 800)\n\t\t},\n\n\t\t/**\n\t\t * Measure every grid cell and console.warn the widget ids whose content\n\t\t * is taller than the cell. Dev aid only — called via\n\t\t * `scheduleCellOverflowAudit`.\n\t\t *\n\t\t * @return {void}\n\t\t */\n\t\tauditCellOverflow() {\n\t\t\tif (!this.$el || !this.$el.querySelectorAll) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.$el.querySelectorAll('.grid-stack-item').forEach((cell) => {\n\t\t\t\tconst content = cell.querySelector('.grid-stack-item-content')\n\t\t\t\tif (!content) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif (content.scrollHeight > content.clientHeight + 8) {\n\t\t\t\t\tconst inner = cell.querySelector('.cn-detail-page__grid-item')\n\t\t\t\t\tconst label = (inner && inner.getAttribute('aria-labelledby')) || cell.getAttribute('gs-id') || ''\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.warn(`[CnDetailPage] widget cell ${label || '(unlabelled)'} content overflows its gridHeight `\n\t\t\t\t\t\t+ `(${content.scrollHeight}px in ${content.clientHeight}px) — enlarge the cell or scope the widget's content (ADR-062).`)\n\t\t\t\t}\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Whether to render the grid section `<h3>` title above a widget. Only for\n\t\t * consumer-supplied `#widget-<id>` slots (whose content may be bare) — the\n\t\t * built-in widget renderers (data / related / integration / catalog) draw\n\t\t * their own titled card header, so a grid heading would show the title\n\t\t * twice. Honours `item.showTitle === false` to opt out entirely.\n\t\t *\n\t\t * @param {object} item Layout item.\n\t\t * @return {boolean} true when the grid heading should render.\n\t\t */\n\t\tshowGridTitle(item) {\n\t\t\tif (item.showTitle === false || !this.findWidget(item)) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\treturn Boolean(this.$slots[`widget-${item.widgetId}`] || this.$slots[`widget-${item.widgetId}`])\n\t\t},\n\n\t\t/**\n\t\t * The grid section heading for a consumer slot widget — the widget\n\t\t * definition's manifest `title` run through the host translate\n\t\t * function. Returns the raw value untouched when there is none.\n\t\t *\n\t\t * @param {object} item Layout item.\n\t\t * @return {string|undefined} The heading text.\n\t\t */\n\t\tgridTitle(item) {\n\t\t\tconst title = this.findWidget(item)?.title\n\t\t\treturn title ? this.effectiveTranslate(title) : title\n\t\t},\n\n\t\t/**\n\t\t * Whether a card widget (stat / gauge / delta) shows the wrapper header.\n\t\t *\n\t\t * These renderers draw their own label from `content.label`, so a header\n\t\t * carrying the same manifest title printed it twice. `showTitle: false`\n\t\t * on the layout item switches it off, the same key and the same meaning\n\t\t * as on the grid `<h3>` (`showGridTitle`).\n\t\t *\n\t\t * @param {object} item Layout item.\n\t\t * @return {boolean} true when the wrapper header renders.\n\t\t */\n\t\tshowCardTitle(item) {\n\t\t\tif (item.showTitle === false) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tconst def = this.findWidget(item)\n\t\t\treturn def?.title !== undefined || widgetContentOf(def).title !== undefined\n\t\t},\n\n\t\t/**\n\t\t * Resolve the widget definition for a layout item. Overrides the\n\t\t * gridLayout mixin's `findWidget` (which only reads the `widgets` prop) so\n\t\t * the materialized default auto-body widgets resolve too. Searches the\n\t\t * effective `bodyGridWidgets`.\n\t\t *\n\t\t * @param {{ widgetId: string }} item Layout item.\n\t\t * @return {object|undefined} The matching widget definition.\n\t\t */\n\t\tfindWidget(item) {\n\t\t\treturn this.bodyGridWidgets.find((w) => w.id === item.widgetId)\n\t\t},\n\n\t\t/**\n\t\t * Drop the items that draw nothing, then close the rows they freed —\n\t\t * `float: true` leaves the item below pinned under a gap nobody owns.\n\t\t * Skipped when nothing was dropped, so an authored gap survives.\n\t\t *\n\t\t * @param {Array<object>} items The authored layout items.\n\t\t *\n\t\t * @return {Array<object>} What the grid should render.\n\t\t */\n\t\tcloseDroppedRows(items) {\n\t\t\tconst drawable = items.filter((item) => this.layoutItemCanDraw(item))\n\t\t\tif (drawable.length === items.length) {\n\t\t\t\treturn drawable\n\t\t\t}\n\n\t\t\treturn compactLayoutRows(drawable)\n\t\t},\n\n\t\t/**\n\t\t * Whether a layout item has anything to draw, so a grid cell is worth\n\t\t * spending on it.\n\t\t *\n\t\t * TWO widget types are judged, and no others.\n\t\t *\n\t\t * `integration`, in the case where nothing can ever appear: a leaf from\n\t\t * another app that is not registered, with no `requiredApp` to fall back\n\t\t * on. A cross-app feature is normally optional — humaniq's hours leaf on a\n\t\t * dossiq case — and without this the host still renders its wrapper, so the\n\t\t * absent app costs a bordered, full-height ghost card in the grid. An app\n\t\t * nobody installed should cost nothing.\n\t\t *\n\t\t * A widget that declares `requiredApp` is KEPT: the host answers a missing\n\t\t * app with a set-up state, which is content, and hiding it would turn an\n\t\t * actionable \"install humaniq\" into silence.\n\t\t *\n\t\t * `presence`, whenever nobody else is on the record. A runtime fact that\n\t\t * flips both ways, so the host holds the subscription (see setup) and the\n\t\t * row returns the moment somebody arrives.\n\t\t *\n\t\t * Deliberately NOT generalised to \"anything that resolves to nothing\".\n\t\t * A `custom` widget whose `#widget-<id>` slot is missing also draws an\n\t\t * empty host, but that is a WIRING FAULT rather than an absent optional\n\t\t * feature, and quietly dropping it would hide the bug instead of showing\n\t\t * it — CnPageRenderer's split pane forwards no slots, which is exactly\n\t\t * that fault and wants fixing, not concealing.\n\t\t *\n\t\t * @param {object} item A layout item.\n\t\t * @return {boolean} False only when the item provably draws nothing.\n\t\t */\n\t\tlayoutItemCanDraw(item) {\n\t\t\t// In edit mode nothing is hidden: an author has to see the placement to\n\t\t\t// move or delete it, and a widget that vanished from the editor while\n\t\t\t// staying in the manifest would be unmanageable.\n\t\t\tif (this.editingBody) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tconst widget = this.findWidget(item)\n\t\t\tif (!widget) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\t// Presence is empty almost always, and no attribute can reclaim its\n\t\t\t// row: GridStack floors `sizeToContent` at the item's `gs-min-h`.\n\t\t\tif (widget.type === 'presence') {\n\t\t\t\treturn (this.presentOthers || []).length > 0\n\t\t\t}\n\t\t\tif (widget.type !== 'integration') {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tconst requiredApp = widget.requiredApp || (widget.content || {}).requiredApp || ''\n\t\t\tif (requiredApp !== '' && !isAppInstalled(requiredApp)) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif (typeof this.getRegistryProvider !== 'function') {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn !!this.getRegistryProvider(widget.integrationId)\n\t\t},\n\n\t\t/**\n\t\t * Build the default body grid for the schema-driven auto-body: a full-width\n\t\t * Data widget with the Related-objects widget beneath it. Materialized once\n\t\t * (lazily) so the geometry is a mutable, reactive array the user can drag /\n\t\t * resize in edit mode. Both widgets carry `showTitle: false` because they\n\t\t * render their own card chrome.\n\t\t */\n\t\tmaterializeAutoBody() {\n\t\t\t// One source of truth (shared with the Buildiq edit button's\n\t\t\t// \"eject\" on edit) so the in-memory default and the manifest-ejected\n\t\t\t// default are identical. The data widget's content carries the page's\n\t\t\t// register/schema so its per-property editor can resolve the schema\n\t\t\t// (empty on legacy objectType-only mounts → the editor falls back to\n\t\t\t// the injected `cnObjectContext`).\n\t\t\tconst grid = defaultDetailGrid({\n\t\t\t\tregister: this.register || '',\n\t\t\t\tschema: this.schema || '',\n\t\t\t\tshowRelated: this.showRelatedObjects,\n\t\t\t})\n\t\t\t// Drop the Data widget when there's no schema to render (the helper\n\t\t\t// always includes it; the auto-body only shows it with a schema).\n\t\t\t//\n\t\t\t// This can happen because the schema HAS NOT ARRIVED YET, not\n\t\t\t// because there is none: `schemaDrivenFetch` fires fetchObject and\n\t\t\t// fetchSchema in parallel, and this body materializes as soon as\n\t\t\t// `shouldRenderAutoBody` turns true — which tests `currentObject`\n\t\t\t// and NOT `currentSchema`. When the object wins that race the Data\n\t\t\t// widget is filtered out, and because the body materializes only\n\t\t\t// once (`if (active && !this.autoBodyLayout)`) and resets only when\n\t\t\t// `resolvedObjectType` changes, the schema landing a moment later\n\t\t\t// never puts it back.\n\t\t\t//\n\t\t\t// The symptom is a detail page showing its title and Related panel\n\t\t\t// with EVERY declared scalar field missing, intermittently, on\n\t\t\t// identical code — shillinq#1073, where the object fetch returned\n\t\t\t// 200 carrying the values the page then did not render.\n\t\t\t//\n\t\t\t// `dataWidgetDeferred` records that this filtering was provisional\n\t\t\t// so the watcher below can re-materialize exactly once, when the\n\t\t\t// schema arrives. It is deliberately NOT a plain \"re-materialize if\n\t\t\t// the data widget is absent\": a body the user has edited must not\n\t\t\t// have the widget silently restored underneath them.\n\t\t\tthis.dataWidgetDeferred = !this.currentSchema\n\t\t\tif (!this.currentSchema) {\n\t\t\t\tgrid.widgets = grid.widgets.filter((w) => w.widgetId !== 'data')\n\t\t\t\tgrid.layout = grid.layout.filter((l) => l.widgetId !== 'data')\n\t\t\t}\n\t\t\tthis.autoBodyWidgets = grid.widgets\n\t\t\tthis.autoBodyLayout = grid.layout\n\t\t},\n\n\t\t/**\n\t\t * Persist a drag/resize from the body grid. For the default auto-body the\n\t\t * new geometry is kept locally so the move sticks; for an explicit `layout`\n\t\t * prop the change is emitted upward (`layout-change` + `update:layout`) for\n\t\t * the manifest renderer / host to persist.\n\t\t *\n\t\t * @param {Array} updated The new layout array from CnDashboardGrid.\n\t\t *\n\t\t * @event layout-change Emitted with the updated body-grid layout. The\n\t\t * sibling `update:layout` event is also emitted so `:layout.sync`\n\t\t * consumers stay in sync.\n\t\t */\n\t\tonBodyLayoutChange(updated) {\n\t\t\tif (this.hasGridLayout) {\n\t\t\t\t// Config-backed grid (manifest editor, ADR-041): the `layout` prop is\n\t\t\t\t// the SAME array the working manifest holds (the route-sentinel\n\t\t\t\t// resolver is reference-preserving), so write the new geometry back\n\t\t\t\t// onto its items in place — Save page then persists the resize.\n\t\t\t\tfor (const u of updated) {\n\t\t\t\t\tconst item = this.layout.find((l) => String(l.id) === String(u.id))\n\t\t\t\t\tif (item) {\n\t\t\t\t\t\titem.gridX = u.gridX\n\t\t\t\t\t\titem.gridY = u.gridY\n\t\t\t\t\t\titem.gridWidth = u.gridWidth\n\t\t\t\t\t\titem.gridHeight = u.gridHeight\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// In-memory default grid — keep the new geometry locally so the move\n\t\t\t\t// sticks for the session (un-customised page, nothing to persist).\n\t\t\t\tthis.autoBodyLayout = updated\n\t\t\t}\n\t\t\t/**\n\t\t\t * @event layout-change Emitted when a body-grid widget is dragged or\n\t\t\t * resized. Payload is the updated layout array.\n\t\t\t * @type {Array}\n\t\t\t */\n\t\t\tthis.$emit('layout-change', updated)\n\t\t\t// Description goes ABOVE `@event`, not inline after it:\n\t\t\t// vue-docgen-api's event-name splitter stops at the first `:`, so\n\t\t\t// `@event update:layout <description>` is read as one long event\n\t\t\t// NAME and the generated docs show an empty description.\n\t\t\t/**\n\t\t\t * Sibling of `layout-change` so `v-model:layout` consumers stay in\n\t\t\t * sync.\n\t\t\t *\n\t\t\t * @event update:layout\n\t\t\t * @type {Array}\n\t\t\t */\n\t\t\tthis.$emit('update:layout', updated)\n\t\t},\n\n\t\t/**\n\t\t * The registered config FORM for a grid item's widget type, or null.\n\t\t * Used to gate the per-widget configure cog (only configurable widgets\n\t\t * show one) in Buildiq edit mode.\n\t\t *\n\t\t * @param {object} item Layout item\n\t\t * @return {object|null} The form component, or null.\n\t\t */\n\t\tregistryFormFor(item) {\n\t\t\tconst def = this.findWidget(item)\n\t\t\tif (!def || !def.type) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst entry = getWidgetTypeEntry(def.type)\n\t\t\treturn (entry && entry.form) || null\n\t\t},\n\n\t\t/**\n\t\t * Whether a grid item shows the configure cog: the page is in edit\n\t\t * mode and the item resolves to a widget definition. Not gated on a\n\t\t * registered form: the style editor modal handles a type without one\n\t\t * (title, icon, style, delete), and the delete is what a custom widget\n\t\t * or an integration leaf needs the cog for.\n\t\t *\n\t\t * @param {object} item Layout item.\n\t\t * @return {boolean} true when the cog renders.\n\t\t */\n\t\tshowsCog(item) {\n\t\t\treturn this.editingBody === true && Boolean(this.findWidget(item))\n\t\t},\n\n\t\t/**\n\t\t * The registered RENDERER for a grid item's content-driven catalog\n\t\t * widget type (stat / chart / delta / gauge / object-list / …), or null.\n\t\t * Integration widgets resolve separately; the `data` renderer needs\n\t\t * object context the slot supplies, so it is excluded from this generic\n\t\t * fallback.\n\t\t *\n\t\t * @param {object} item Layout item\n\t\t * @return {object|null} The renderer component, or null.\n\t\t */\n\t\tregistryRendererFor(item) {\n\t\t\treturn resolveRegistryRenderer(this.findWidget(item), this.cnRegistry)\n\t\t},\n\n\t\t/**\n\t\t * The stored content/config blob for a grid item's catalog widget\n\t\t * (passed to its renderer).\n\t\t *\n\t\t * @param {object} item Layout item\n\t\t * @return {object} The widget def's `content`, or an empty object.\n\t\t */\n\t\twidgetContentFor(item) {\n\t\t\treturn widgetContentOf(this.findWidget(item))\n\t\t},\n\n\t\t/**\n\t\t * Resolve the effective title for a grid widget.\n\t\t *\n\t\t * A title-owning widget type (registry `ownsTitle`, e.g. `related`) keeps\n\t\t * its editable title in `content.title` — its config sub-form owns the\n\t\t * title field and the generic chrome title input is hidden. For those,\n\t\t * `content.title` MUST win over the chrome `def.title`, otherwise a\n\t\t * non-empty seed title (e.g. the default detail grid seeds the related\n\t\t * widget with `title: 'Related'`) permanently shadows the user's edit and\n\t\t * the title can never be changed. For every other type the chrome\n\t\t * `def.title` is authoritative, falling back to `content.title`. Empty\n\t\t * resolves to `undefined` so the widget renders its own default label.\n\t\t *\n\t\t * @param {object} item Layout item.\n\t\t * @return {string|undefined} The title to render, or undefined for the default.\n\t\t */\n\t\twidgetDisplayTitle(item) {\n\t\t\treturn widgetTitleOf(this.findWidget(item))\n\t\t},\n\n\t\t/**\n\t\t * Open the per-widget style/config editor for a grid item (cog click).\n\t\t *\n\t\t * @param {object} item Layout item to configure.\n\t\t */\n\t\tconfigureWidget(item) {\n\t\t\tthis.configWidgetId = item.widgetId\n\t\t\tthis.showWidgetConfig = true\n\t\t},\n\n\t\t/**\n\t\t * Persist the editor's changes onto the matching widget definition IN\n\t\t * PLACE (so an injected in-place manifest editor picks them up), close\n\t\t * the modal, and emit `widget-config-change` for consumers that persist\n\t\t * the page config themselves.\n\t\t *\n\t\t * @param {object} edited The widget object mutated by the editor.\n\t\t *\n\t\t * @event widget-config-change Emitted after a widget's config is saved.\n\t\t * @type {object}\n\t\t */\n\t\tonWidgetConfigSave(edited) {\n\t\t\tconst def = this.bodyGridWidgets.find((w) => w.id === this.configWidgetId)\n\t\t\tif (def) {\n\t\t\t\tif (edited.title !== undefined) {\n\t\t\t\t\tdef.title = edited.title\n\t\t\t\t}\n\t\t\t\tif (edited.content !== undefined) {\n\t\t\t\t\tdef.content = edited.content\n\t\t\t\t}\n\t\t\t\tdef.styleConfig = edited.styleConfig || {}\n\t\t\t}\n\t\t\tthis.showWidgetConfig = false\n\t\t\t/**\n\t\t\t * @event widget-config-change Emitted after a grid widget's config is\n\t\t\t * saved via the cog editor, or after the widget is removed (payload\n\t\t\t * null). Consumers persist the updated page/widget config.\n\t\t\t * @type {object|null}\n\t\t\t */\n\t\t\tthis.$emit('widget-config-change', def || null)\n\t\t},\n\n\t\t/**\n\t\t * Delete from inside the editor — drop the widget def + its layout\n\t\t * placement and close.\n\t\t *\n\t\t * @param {object} _w The widget the editor wants deleted (unused; routed\n\t\t * by `configWidgetId`).\n\t\t *\n\t\t * @event widget-config-change Emitted after the widget is removed.\n\t\t * @type {null}\n\t\t */\n\t\tonWidgetConfigDelete(_w) {\n\t\t\tconst id = this.configWidgetId\n\t\t\t// Drop from whichever pair backs the active grid: the explicit\n\t\t\t// `layout`/`widgets` props (manifest grid page) or the materialized\n\t\t\t// default auto-body arrays.\n\t\t\tconst widgetArr = this.hasGridLayout ? this.widgets : this.autoBodyWidgets\n\t\t\tconst layoutArr = this.hasGridLayout ? this.layout : this.autoBodyLayout\n\t\t\tif (Array.isArray(widgetArr)) {\n\t\t\t\tconst wIdx = widgetArr.findIndex((w) => w.id === id)\n\t\t\t\tif (wIdx !== -1) {\n\t\t\t\t\twidgetArr.splice(wIdx, 1)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (Array.isArray(layoutArr)) {\n\t\t\t\tconst lIdx = layoutArr.findIndex((l) => l.widgetId === id)\n\t\t\t\tif (lIdx !== -1) {\n\t\t\t\t\tlayoutArr.splice(lIdx, 1)\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.showWidgetConfig = false\n\t\t\tthis.$emit('widget-config-change', null)\n\t\t},\n\n\t\t/**\n\t\t * Push pageKind + objectUuid + register/schema context into the\n\t\t * reactive cnAiContext holder so the AI Chat Companion knows\n\t\t * what object the user is viewing.\n\t\t */\n\t\tpushAiContext() {\n\t\t\tif (!this.cnAiContext) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst resolved = this.resolvedSidebar || {}\n\t\t\tthis.cnAiContext.pageKind = 'detail'\n\t\t\tthis.cnAiContext.objectUuid = this.objectId ? String(this.objectId) : undefined\n\t\t\tthis.cnAiContext.registerSlug = resolved.register || this.register || this.sidebarProps?.register || undefined\n\t\t\tthis.cnAiContext.schemaSlug = resolved.schema || this.schema || this.resolvedObjectType || this.sidebarProps?.schema || undefined\n\t\t},\n\n\t\t/**\n\t\t * Refresh the provided `cnObjectContext` ref so detail-page abstract\n\t\t * widgets can resolve `@objectId` / `@object.<field>` filter tokens\n\t\t * against the current object. No-op when setup() didn't expose the ref\n\t\t * (standalone / read-only mounts).\n\t\t */\n\t\tsyncObjectContext() {\n\t\t\tif (!this.cnObjectContextRef) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst resolved = this.resolvedSidebar || {}\n\t\t\tthis.cnObjectContextRef.value = {\n\t\t\t\tobjectId: this.objectId !== undefined && this.objectId !== null ? String(this.objectId) : null,\n\t\t\t\tobject: this.currentObject || null,\n\t\t\t\tregister: resolved.register || this.register || this.sidebarProps?.register || '',\n\t\t\t\tschema: resolved.schema || this.schema || this.resolvedObjectType || this.sidebarProps?.schema || '',\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Pushes the resolved sidebar config into the\n\t\t * `objectSidebarState` provide/inject channel for the host\n\t\t * App's mounted `<CnObjectSidebar>` to consume.\n\t\t *\n\t\t * Object form fields take precedence over `sidebarProps` for\n\t\t * any field they declare; `sidebarProps` continues to fill\n\t\t * fields the Object form omits, preserving back-compat.\n\t\t *\n\t\t * Suppression (`show: false` or `enabled: false`) clears\n\t\t * `tabs` so a hidden detail page does not leak prior tab\n\t\t * state to the next mount.\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\tsyncSidebarState() {\n\t\t\tif (!this.hasExternalSidebar) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.warnIfDeprecatedSidebarShape()\n\t\t\t// During a background refresh (content stays in place — see\n\t\t\t// `hasLoadedOnce`), a transient loading-driven `enabled: false`\n\t\t\t// must NOT tear down the sidebar. Hosts commonly bind\n\t\t\t// `:sidebar=\"{ enabled: !loading }\"`, so without this guard every\n\t\t\t// refresh unmounts the host's CnObjectSidebar and re-fetches all\n\t\t\t// its sub-resources (files/notes/tags/tasks/audit). Skip the sync\n\t\t\t// while refreshing; the `loading` watcher re-syncs once it settles.\n\t\t\tif (this.loading && this.hasLoadedOnce) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst r = this.resolvedSidebar\n\t\t\tconst hasRecord = !this.objectNotFound && !this.awaitingObject\n\t\t\tif (this.sidebarActive && hasRecord && this.resolvedObjectType && this.objectId) {\n\t\t\t\tconst merged = this.mergeSidebarSources(r)\n\t\t\t\t// Seed `open` only on the inactive→active edge (first activation\n\t\t\t\t// of this object). Subsequent syncs must NOT clobber it, otherwise\n\t\t\t\t// the user's close/toggle would be undone on the next reactive\n\t\t\t\t// change. The shared channel owns `open` after seeding.\n\t\t\t\t//\n\t\t\t\t// `sidebarSeeded` used to be written here and never read, so\n\t\t\t\t// `open` went into assignSidebarState() on EVERY sync and the\n\t\t\t\t// paragraph above described behaviour the code did not have. A\n\t\t\t\t// detail page emits several syncs while it hydrates (the object\n\t\t\t\t// resolves, then the schema), and each one reset `open` to the\n\t\t\t\t// prop default — reclosing a sidebar the user had just opened.\n\t\t\t\t// Downstream that made openbuild's e2e race the UI: the tab was\n\t\t\t\t// clicked and its panel was hidden again before the assertion\n\t\t\t\t// ran (openbuild#268 — \"resolves 30×, hidden\").\n\t\t\t\tconst seedOpen = (this.sidebarSeeded === false)\n\t\t\t\tif (seedOpen) {\n\t\t\t\t\tthis.sidebarSeeded = true\n\t\t\t\t}\n\t\t\t\t// Manifest-driven open-enum tabs (forwarded to the host\n\t\t\t\t// app's mounted CnObjectSidebar via inject). When the\n\t\t\t\t// top-level `sidebarTabs` prop is non-empty it provides\n\t\t\t\t// the tabs (manifest pattern); otherwise the merged\n\t\t\t\t// `sidebar.tabs` / `sidebarProps.tabs` legacy paths win.\n\t\t\t\t// Falls back to `undefined` so the host's CnObjectSidebar\n\t\t\t\t// renders its built-in tab set.\n\t\t\t\tconst tabs = (this.sidebarTabs && this.sidebarTabs.length > 0)\n\t\t\t\t\t? this.sidebarTabs\n\t\t\t\t\t: merged.tabs\n\t\t\t\tthis.assignSidebarState({\n\t\t\t\t\tactive: true,\n\t\t\t\t\t// Omitted after the seeding sync — assignSidebarState()\n\t\t\t\t\t// only writes the keys it is given, so leaving `open` out\n\t\t\t\t\t// preserves whatever the shared channel currently holds.\n\t\t\t\t\t...(seedOpen ? { open: this.sidebarOpen } : {}),\n\t\t\t\t\tobjectType: this.resolvedObjectType,\n\t\t\t\t\tobjectId: this.objectId,\n\t\t\t\t\t// The loaded object, so coordinate-blind sidebar-tab widgets\n\t\t\t\t\t// (the `data` / `metadata` built-ins) receive it as `objectData`\n\t\t\t\t\t// — the hoisted sidebar is a CnAppRoot sibling, not a\n\t\t\t\t\t// CnDetailPage child, so it can't inject our object context.\n\t\t\t\t\tobject: this.resolvedObject || null,\n\t\t\t\t\t// The resolved schema OBJECT (not the slug), which the `data`\n\t\t\t\t\t// built-in (CnObjectDataWidget) needs alongside `objectData`.\n\t\t\t\t\tschemaObject: this.currentSchema || null,\n\t\t\t\t\ttitle: merged.title || this.title || '',\n\t\t\t\t\tsubtitle: merged.subtitle || this.subtitle || '',\n\t\t\t\t\tregister: merged.register || this.register || '',\n\t\t\t\t\tschema: merged.schema || this.schema || '',\n\t\t\t\t\thiddenTabs: merged.hiddenTabs || [],\n\t\t\t\t\ttabs,\n\t\t\t\t\t// ADR-019. `config.sidebar.useRegistry` reaches\n\t\t\t\t\t// `resolvedSidebar` intact — the Object branch returns\n\t\t\t\t\t// `{show, enabled, ...cfg}` — and survives\n\t\t\t\t\t// mergeSidebarSources(), which spreads `resolved` before\n\t\t\t\t\t// its own field list. It was simply never published here,\n\t\t\t\t\t// so the host's CnObjectSidebar always saw the prop default\n\t\t\t\t\t// `false` and rendered its BACKWARDS-COMPATIBLE branch: the\n\t\t\t\t\t// five hard-coded built-in tabs (files, notes, tags, tasks,\n\t\t\t\t\t// audit-trail) instead of one tab per registered provider.\n\t\t\t\t\t//\n\t\t\t\t\t// The declaration therefore did nothing at all. Measured on\n\t\t\t\t\t// decidiq run 32702211376, whose MeetingIntegrations page\n\t\t\t\t\t// sets `config.sidebar.useRegistry: true`:\n\t\t\t\t\t//\n\t\t\t\t\t// JS registry carries every expected provider passed\n\t\t\t\t\t// every component leaf has a tab + widget passed\n\t\t\t\t\t// OCS caps and JS registry agree passed\n\t\t\t\t\t// providers the server reports available 10\n\t\t\t\t\t// tabs the sidebar rendered 5\n\t\t\t\t\t//\n\t\t\t\t\t// Five, exactly, because that is the fallback branch. Every\n\t\t\t\t\t// app whose manifest opts a page into the registry sidebar\n\t\t\t\t\t// has been getting the built-ins.\n\t\t\t\t\t//\n\t\t\t\t\t// `excludeIntegrations` rides the same channel and was\n\t\t\t\t\t// dropped for the same reason; without it a page cannot\n\t\t\t\t\t// suppress a provider it does not want.\n\t\t\t\t\tuseRegistry: merged.useRegistry === true,\n\t\t\t\t\texcludeIntegrations: merged.excludeIntegrations || [],\n\t\t\t\t\t// The tab the address asks for, and the way back. The\n\t\t\t\t\t// sidebar lives outside this component's tree (the host\n\t\t\t\t\t// mounts it at NcContent level), so the address and the\n\t\t\t\t\t// tab strip can only meet on this shared channel.\n\t\t\t\t\t...(this.tabInAddress\n\t\t\t\t\t\t? { requestedTab: this.requestedTabFromAddress(), onTabChange: this.onSidebarTabChange }\n\t\t\t\t\t\t: {}),\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tthis.assignSidebarState({ active: false, tabs: undefined })\n\t\t\t\t// Re-arm the seed so the next activation re-applies `sidebarOpen`.\n\t\t\t\tthis.sidebarSeeded = false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Apply fields onto the shared `objectSidebarState` only when they\n\t\t * actually change. Writing the same logical value — notably a fresh\n\t\t * `[]` for `hiddenTabs` when none is configured — would otherwise put\n\t\t * a new array reference on the reactive object every call and trigger\n\t\t * a host re-render. That churn fed an infinite render loop: the host\n\t\t * App re-renders on the new `hiddenTabs` ref → its `<router-view>`\n\t\t * re-renders the routed detail page → the page's inline `:sidebar`\n\t\t * prop re-fires this sync → repeat. Arrays are compared shallowly so\n\t\t * an equivalent array is treated as unchanged.\n\t\t *\n\t\t * @param {object} fields Partial `objectSidebarState` to apply.\n\t\t */\n\t\tassignSidebarState(fields) {\n\t\t\tconst state = this.objectSidebarState\n\t\t\tfor (const key of Object.keys(fields)) {\n\t\t\t\tconst next = fields[key]\n\t\t\t\tconst cur = state[key]\n\t\t\t\tif (Array.isArray(next) && Array.isArray(cur)\n\t\t\t\t\t&& next.length === cur.length\n\t\t\t\t\t&& next.every((v, i) => v === cur[i])) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif (cur !== next) {\n\t\t\t\t\tstate[key] = next\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Merge the Object-form `sidebar` fields with the legacy\n\t\t * `sidebarProps` fields. Object form wins on conflict; first\n\t\t * conflict per instance fires a one-shot console.warn naming\n\t\t * the conflicting fields.\n\t\t *\n\t\t * @param {object} resolved Pre-normalised sidebar config object.\n\t\t * @return {object} Merged config — Object form fields override\n\t\t * sidebarProps fields where both are set.\n\t\t */\n\t\tmergeSidebarSources(resolved) {\n\t\t\tconst objectForm = (this.sidebar && typeof this.sidebar === 'object') ? this.sidebar : null\n\t\t\tconst props = this.sidebarProps || {}\n\t\t\tconst merged = {\n\t\t\t\ttitle: objectForm?.title ?? props.title,\n\t\t\t\tsubtitle: objectForm?.subtitle ?? props.subtitle,\n\t\t\t\tregister: objectForm?.register ?? props.register,\n\t\t\t\tschema: objectForm?.schema ?? props.schema,\n\t\t\t\thiddenTabs: objectForm?.hiddenTabs ?? props.hiddenTabs,\n\t\t\t\ttabs: objectForm?.tabs ?? props.tabs,\n\t\t\t}\n\t\t\tif (objectForm && !this.__sidebarConflictWarned) {\n\t\t\t\tconst overlap = ['title', 'subtitle', 'register', 'schema', 'hiddenTabs', 'tabs']\n\t\t\t\t\t.filter((field) => objectForm[field] !== undefined && props[field] !== undefined)\n\t\t\t\tif (overlap.length > 0) {\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(`[CnDetailPage] :sidebar (Object) and :sidebarProps both set ${overlap.join(', ')}; the :sidebar values win. Move all fields to :sidebar to silence this warning.`)\n\t\t\t\t\tthis.__sidebarConflictWarned = true\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Re-anchor `resolved` for the contract — callers expect\n\t\t\t// the returned object to reflect the normalised shape.\n\t\t\treturn { ...resolved, ...merged }\n\t\t},\n\n\t\t/**\n\t\t * Log a one-shot deprecation warning when the legacy Boolean\n\t\t * form of the `sidebar` prop is observed. Tracked via a\n\t\t * non-reactive instance flag so subsequent renders/toggles\n\t\t * don't spam the console.\n\t\t */\n\t\twarnIfDeprecatedSidebarShape() {\n\t\t\tif (typeof this.sidebar !== 'boolean') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (this.__sidebarBooleanWarned) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.__sidebarBooleanWarned = true\n\n\t\t\t// eslint-disable-next-line no-console -- a deliberate warning to the developer integrating this component\n\t\t\tconsole.warn('[CnDetailPage] :sidebar=Boolean is deprecated; pass an Object — see docs/components/cn-detail-page.md for the new shape.')\n\t\t},\n\t},\n}\n</script>\n\n<!-- Styles in css/detail-page.css -->\n"],"names":["CnIcon","CnActionsMenu","CnBuildiqEditButton","CnLockedBanner","CnDetailWidgetHost","CnFormDialog","CnDashboardGrid","CnLifecycleActions","CnActionButtons","CnSummaryAggregates","CnRelatedCollections","CnBodySections","CnTranslatedBadge","CnWidgetStyleEditorModal","CnRelationLinkModal","t"],"mappings":"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"}