@conduction/nextcloud-vue 2.78.0 → 2.80.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (259) hide show
  1. package/dist/bundled-packages.json +0 -2
  2. package/dist/esm/bundled-packages.json +0 -2
  3. package/dist/esm/components/CnActionButtons/CnActionButtons.vue2.js.map +1 -1
  4. package/dist/esm/components/CnActionButtons/CnActionButtons.vue3.js +3 -1
  5. package/dist/esm/components/CnActionButtons/CnActionButtons.vue3.js.map +1 -1
  6. package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js +32 -3
  7. package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js.map +1 -1
  8. package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js +115 -104
  9. package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js.map +1 -1
  10. package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js +12 -2
  11. package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js.map +1 -1
  12. package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js.map +1 -1
  13. package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue2.js +39 -3
  14. package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue2.js.map +1 -1
  15. package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue3.js.map +1 -1
  16. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js +158 -0
  17. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js.map +1 -1
  18. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js +157 -96
  19. package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js.map +1 -1
  20. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +139 -1
  21. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
  22. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +140 -92
  23. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
  24. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +77 -0
  25. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
  26. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +5 -2
  27. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
  28. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +62 -4
  29. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
  30. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
  31. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js +85 -1
  32. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js.map +1 -1
  33. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js +43 -4
  34. package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js.map +1 -1
  35. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue.js +11 -0
  36. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue.js.map +1 -0
  37. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js +736 -0
  38. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js.map +1 -0
  39. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue3.js +238 -0
  40. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue3.js.map +1 -0
  41. package/dist/esm/components/CnFactsWidget/index.js +30 -0
  42. package/dist/esm/components/CnFactsWidget/index.js.map +1 -0
  43. package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue.js +10 -0
  44. package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue.js.map +1 -0
  45. package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue2.js +551 -0
  46. package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue2.js.map +1 -0
  47. package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue3.js +183 -0
  48. package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue3.js.map +1 -0
  49. package/dist/esm/components/CnFieldListWidget/index.js +29 -0
  50. package/dist/esm/components/CnFieldListWidget/index.js.map +1 -0
  51. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js +173 -5
  52. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js.map +1 -1
  53. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js +181 -99
  54. package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js.map +1 -1
  55. package/dist/esm/components/CnFilesBrowser/filesBrowser.js +29 -11
  56. package/dist/esm/components/CnFilesBrowser/filesBrowser.js.map +1 -1
  57. package/dist/esm/components/CnFilesBrowser/openRegisterSource.js +252 -0
  58. package/dist/esm/components/CnFilesBrowser/openRegisterSource.js.map +1 -0
  59. package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js +66 -18
  60. package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js.map +1 -1
  61. package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js +4 -4
  62. package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js.map +1 -1
  63. package/dist/esm/components/CnFormPage/CnFormPage.vue2.js +18 -3
  64. package/dist/esm/components/CnFormPage/CnFormPage.vue2.js.map +1 -1
  65. package/dist/esm/components/CnFormPage/CnFormPage.vue3.js.map +1 -1
  66. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +330 -74
  67. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  68. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +34 -15
  69. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  70. package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue.js +10 -0
  71. package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue.js.map +1 -0
  72. package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue2.js +99 -0
  73. package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue2.js.map +1 -0
  74. package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue3.js +48 -0
  75. package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue3.js.map +1 -0
  76. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js +100 -3
  77. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js.map +1 -1
  78. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js +4 -2
  79. package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js.map +1 -1
  80. package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue2.js +29 -1
  81. package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue2.js.map +1 -1
  82. package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue3.js.map +1 -1
  83. package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue2.js +3 -2
  84. package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue2.js.map +1 -1
  85. package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue3.js.map +1 -1
  86. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js +10 -0
  87. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js.map +1 -0
  88. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js +387 -0
  89. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js.map +1 -0
  90. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js +169 -0
  91. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js.map +1 -0
  92. package/dist/esm/components/CnRecordListWidget/index.js +31 -0
  93. package/dist/esm/components/CnRecordListWidget/index.js.map +1 -0
  94. package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue2.js.map +1 -1
  95. package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue3.js +1 -1
  96. package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue3.js.map +1 -1
  97. package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue.js +10 -0
  98. package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue.js.map +1 -0
  99. package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue2.js +351 -0
  100. package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue2.js.map +1 -0
  101. package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue3.js +71 -0
  102. package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue3.js.map +1 -0
  103. package/dist/esm/components/CnSectionsWidget/index.js +35 -0
  104. package/dist/esm/components/CnSectionsWidget/index.js.map +1 -0
  105. package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue2.js +81 -2
  106. package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue2.js.map +1 -1
  107. package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue3.js.map +1 -1
  108. package/dist/esm/components/CnStatWidget/CnStatWidget.vue2.js.map +1 -1
  109. package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js +1 -0
  110. package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js.map +1 -1
  111. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +152 -8
  112. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
  113. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js +84 -23
  114. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js.map +1 -1
  115. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +4 -0
  116. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
  117. package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue2.js +13 -0
  118. package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue2.js.map +1 -1
  119. package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue3.js.map +1 -1
  120. package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue2.js +106 -2
  121. package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue2.js.map +1 -1
  122. package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue3.js +105 -53
  123. package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue3.js.map +1 -1
  124. package/dist/esm/composables/useAppManifest.js +8 -3
  125. package/dist/esm/composables/useAppManifest.js.map +1 -1
  126. package/dist/esm/composables/useFormDraft.js +140 -9
  127. package/dist/esm/composables/useFormDraft.js.map +1 -1
  128. package/dist/esm/index.js +5 -0
  129. package/dist/esm/index.js.map +1 -1
  130. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue2.js +28 -20
  131. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue2.js.map +1 -1
  132. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue3.js +9 -0
  133. package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue3.js.map +1 -1
  134. package/dist/esm/integrations/builtin/field-inspection.js +21 -0
  135. package/dist/esm/integrations/builtin/field-inspection.js.map +1 -1
  136. package/dist/esm/integrations/offline/checklistSubmission.js +141 -0
  137. package/dist/esm/integrations/offline/checklistSubmission.js.map +1 -0
  138. package/dist/esm/integrations/offline/fieldCollectionHelpers.js +70 -5
  139. package/dist/esm/integrations/offline/fieldCollectionHelpers.js.map +1 -1
  140. package/dist/esm/integrations/offline/index.js +2 -1
  141. package/dist/esm/integrations/offline/index.js.map +1 -1
  142. package/dist/esm/integrations/offline/offlineDb.js +6 -1
  143. package/dist/esm/integrations/offline/offlineDb.js.map +1 -1
  144. package/dist/esm/integrations/offline/syncReplayService.js +8 -2
  145. package/dist/esm/integrations/offline/syncReplayService.js.map +1 -1
  146. package/dist/esm/l10n/en.json.js +72 -1
  147. package/dist/esm/l10n/en.json.js.map +1 -1
  148. package/dist/esm/l10n/nl.json.js +120 -2
  149. package/dist/esm/l10n/nl.json.js.map +1 -1
  150. package/dist/esm/nextcloud-vue.css +1314 -74
  151. package/dist/esm/utils/boardDate.js +193 -0
  152. package/dist/esm/utils/boardDate.js.map +1 -0
  153. package/dist/esm/utils/detailActionModel.js +60 -3
  154. package/dist/esm/utils/detailActionModel.js.map +1 -1
  155. package/dist/esm/utils/dynamicProperties.js +5 -1
  156. package/dist/esm/utils/dynamicProperties.js.map +1 -1
  157. package/dist/esm/utils/fillTemplate.js +114 -0
  158. package/dist/esm/utils/fillTemplate.js.map +1 -0
  159. package/dist/esm/utils/libraryWidgetKeys.js +4 -0
  160. package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
  161. package/dist/esm/utils/queryPresets.js +96 -0
  162. package/dist/esm/utils/queryPresets.js.map +1 -0
  163. package/dist/esm/utils/resolveFilterTokens.js +11 -0
  164. package/dist/esm/utils/resolveFilterTokens.js.map +1 -1
  165. package/dist/esm/utils/schema.js +21 -0
  166. package/dist/esm/utils/schema.js.map +1 -1
  167. package/dist/esm/utils/sentinelTokens.js +3 -3
  168. package/dist/esm/utils/sentinelTokens.js.map +1 -1
  169. package/dist/esm/utils/validateManifestV2.compiled.js +57 -6
  170. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  171. package/dist/esm/utils/widgetDispatch.js +7 -1
  172. package/dist/esm/utils/widgetDispatch.js.map +1 -1
  173. package/dist/nextcloud-vue.cjs.js +14278 -8169
  174. package/dist/nextcloud-vue.cjs.js.map +2 -2
  175. package/dist/nextcloud-vue.css +1314 -74
  176. package/l10n/en.json +72 -1
  177. package/l10n/nl.json +120 -2
  178. package/package.json +1 -1
  179. package/scripts/build-validators.js +26 -0
  180. package/src/components/CnActionButtons/CnActionButtons.vue +2 -0
  181. package/src/components/CnActionsBar/CnActionsBar.md +4 -0
  182. package/src/components/CnActionsBar/CnActionsBar.vue +83 -42
  183. package/src/components/CnAppRoot/CnAppRoot.vue +12 -2
  184. package/src/components/CnBannerWidget/CnBannerWidget.vue +39 -3
  185. package/src/components/CnCellRenderer/CnCellRenderer.vue +306 -2
  186. package/src/components/CnDashboardPage/CnDashboardPage.vue +219 -4
  187. package/src/components/CnDataTable/CnDataTable.md +2 -0
  188. package/src/components/CnDataTable/CnDataTable.vue +82 -2
  189. package/src/components/CnDetailPage/CnDetailPage.md +1 -1
  190. package/src/components/CnDetailPage/CnDetailPage.vue +63 -3
  191. package/src/components/CnDetailWidgetHost/CnDetailWidgetHost.vue +127 -1
  192. package/src/components/CnFactsWidget/CnFactsWidget.vue +1050 -0
  193. package/src/components/CnFactsWidget/index.js +29 -0
  194. package/src/components/CnFieldListWidget/CnFieldListWidget.vue +746 -0
  195. package/src/components/CnFieldListWidget/index.js +28 -0
  196. package/src/components/CnFilesBrowser/CnFilesBrowser.vue +232 -11
  197. package/src/components/CnFilesBrowser/filesBrowser.js +43 -2
  198. package/src/components/CnFilesBrowser/index.js +1 -0
  199. package/src/components/CnFilesBrowser/openRegisterSource.js +248 -0
  200. package/src/components/CnFormDialog/CnFormDialog.md +9 -3
  201. package/src/components/CnFormDialog/CnFormDialog.vue +70 -22
  202. package/src/components/CnFormPage/CnFormPage.vue +18 -3
  203. package/src/components/CnIndexPage/CnIndexPage.vue +281 -9
  204. package/src/components/CnIndexPage/CnIndexPageWidgets.vue +169 -0
  205. package/src/components/CnObjectSidebar/CnFilesTab.vue +103 -4
  206. package/src/components/CnPageRenderer/CnPageRenderer.vue +29 -1
  207. package/src/components/CnQuickFilterBar/CnQuickFilterBar.vue +3 -2
  208. package/src/components/CnRecordListWidget/CnRecordListWidget.vue +603 -0
  209. package/src/components/CnRecordListWidget/index.js +30 -0
  210. package/src/components/CnSavedViewsControl/CnSavedViewsControl.vue +1 -1
  211. package/src/components/CnSectionsWidget/CnSectionsWidget.vue +489 -0
  212. package/src/components/CnSectionsWidget/index.js +34 -0
  213. package/src/components/CnStagesWidget/CnStagesWidget.vue +81 -2
  214. package/src/components/CnStatWidget/CnStatWidget.vue +1 -1
  215. package/src/components/CnTabsWidget/CnTabsWidget.vue +214 -9
  216. package/src/components/CnWidgetGrid/registerDashboardWidgets.js +4 -0
  217. package/src/components/CnWidgetObjectTable/CnWidgetObjectTable.vue +13 -0
  218. package/src/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue +188 -4
  219. package/src/components/index.js +5 -1
  220. package/src/composables/__tests__/useFormDraft.spec.js +69 -0
  221. package/src/composables/useAppManifest.js +8 -3
  222. package/src/composables/useFormDraft.js +139 -8
  223. package/src/css/form-field.css +14 -0
  224. package/src/css/index-page.css +71 -0
  225. package/src/css/kpi-card.css +32 -0
  226. package/src/css/look-board-detail.css +87 -0
  227. package/src/css/look-board-index.css +143 -14
  228. package/src/css/look-board.css +114 -2
  229. package/src/css/table.css +56 -0
  230. package/src/index.js +8 -0
  231. package/src/integrations/builtin/field-inspection/CnFieldInspectionCard.vue +35 -20
  232. package/src/integrations/builtin/field-inspection.js +21 -0
  233. package/src/integrations/offline/checklistSubmission.js +137 -0
  234. package/src/integrations/offline/fieldCollectionHelpers.js +69 -4
  235. package/src/integrations/offline/index.js +3 -0
  236. package/src/integrations/offline/offlineDb.js +6 -1
  237. package/src/integrations/offline/syncReplayService.js +8 -2
  238. package/src/schemas/app-manifest-v2.schema.json +149 -5
  239. package/src/utils/boardDate.js +189 -0
  240. package/src/utils/detailActionModel.js +59 -2
  241. package/src/utils/dynamicProperties.js +5 -1
  242. package/src/utils/fillTemplate.js +110 -0
  243. package/src/utils/libraryWidgetKeys.js +4 -0
  244. package/src/utils/queryPresets.js +93 -0
  245. package/src/utils/resolveFilterTokens.js +11 -0
  246. package/src/utils/schema.js +21 -0
  247. package/src/utils/sentinelTokens.js +3 -3
  248. package/src/utils/validateManifestV2.compiled.js +57 -2
  249. package/src/utils/widgetDispatch.js +7 -1
  250. package/dist/esm/_virtual/equal.js +0 -4
  251. package/dist/esm/_virtual/equal.js.map +0 -1
  252. package/dist/esm/_virtual/ucs2length.js +0 -4
  253. package/dist/esm/_virtual/ucs2length.js.map +0 -1
  254. package/dist/esm/node_modules/ajv/dist/runtime/equal.js +0 -9
  255. package/dist/esm/node_modules/ajv/dist/runtime/equal.js.map +0 -1
  256. package/dist/esm/node_modules/ajv/dist/runtime/ucs2length.js +0 -25
  257. package/dist/esm/node_modules/ajv/dist/runtime/ucs2length.js.map +0 -1
  258. package/dist/esm/node_modules/fast-deep-equal/index.js +0 -47
  259. package/dist/esm/node_modules/fast-deep-equal/index.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"offlineDb.js","sources":["../../../../src/integrations/offline/offlineDb.js"],"sourcesContent":["/**\n * SPDX-FileCopyrightText: 2026 Conduction B.V. <info@conduction.nl>\n * SPDX-License-Identifier: EUPL-1.2\n *\n * Generic IndexedDB (Dexie.js) store for the offline data-collection core.\n *\n * Unlike procest's bespoke six-table schema, this store is keyed by\n * `register` + `schema` so ANY consuming app can cache its planned objects and\n * queue mutations through one shared database. Three generic tables:\n *\n * - `objectCache` — cached OpenRegister objects (the planned items plus any\n * reference data, e.g. checklist templates). Each row is a\n * `{ key, register, schema, collection, objectId, object }`\n * envelope so multiple apps/schemas never collide.\n * - `mutationQueue` — the offline sync queue: one row per pending create /\n * update / delete to be replayed against the OR object API.\n * - `meta` — singleton rows (per-collection planning state / expiry).\n *\n * Dexie is imported here only — the pure engine (`syncQueueEngine.js`) and the\n * pure helpers carry the unit-test surface and import nothing from this module,\n * so they stay importable in a Node environment with no IndexedDB. Tests for\n * THIS module inject a fake-indexeddb-backed Dexie via `__setDexie`.\n *\n * Dexie is loaded LAZILY, on the first call that needs the database\n * (`openDb()`), and never at import time. This module is reachable from the\n * package root: `src/index.js` exports `offlineCollection`, which reaches\n * `integrations/builtin/field-inspection`, which reaches here. With a static\n * import every consuming app evaluated Dexie on every page, and Dexie throws\n * \"Two different versions of Dexie loaded in the same app\" at module init\n * when a second copy at another version is already on the page. Nextcloud\n * loads several apps' every-page bundles at once (openregister's\n * integration-global among them), so one app a patch release ahead of\n * another blanked whole apps that never touch the offline core. Loaded on\n * demand, Dexie is evaluated only on a page that actually opens the offline\n * database.\n *\n * Dexie stays a REQUIRED peer dependency. The consumer's bundler still\n * resolves `import('dexie')` at BUILD time (it becomes a separate chunk), so\n * an app without it installed fails its build with \"Module not found\". The\n * dependency is required; loading it is not.\n *\n * @module integrations/offline/offlineDb\n */\n\nimport { resolveConflictChoice } from './syncQueueEngine.js'\n\nconst DB_NAME = 'conduction-offline-collection'\n\nlet dbInstance = null\n// Null until `openDb()` loads Dexie, or a test injects it via `__setDexie`.\nlet DexieCtor = null\n\n/**\n * Build the composite cache key for an object.\n *\n * @param {string} register Register slug or id.\n * @param {string} schema Schema slug or id.\n * @param {string} collection Logical collection name (e.g. 'planning', 'templates').\n * @param {string} objectId The object id.\n *\n * @return {string} A stable composite key.\n */\nexport function cacheKey(register, schema, collection, objectId) {\n\treturn `${register}::${schema}::${collection}::${objectId}`\n}\n\n/**\n * Set the Dexie constructor explicitly (test seam / SSR override).\n *\n * Production code never calls this: `openDb()` lazy-imports `dexie`. Tests pass\n * a fake-indexeddb-backed Dexie so the store can be exercised in Node.\n *\n * @param {new (name: string) => object} ctor The Dexie class.\n *\n * @return {void}\n */\nexport function __setDexie(ctor) {\n\tDexieCtor = ctor\n\tdbInstance = null\n}\n\n/**\n * Load Dexie on first use, then open (and memoise) the database.\n *\n * Every function in the offline core goes through this, so Dexie is only\n * evaluated on a page that actually uses the offline database. A Dexie\n * injected with `__setDexie` is used as is and nothing is imported.\n *\n * @return {Promise<object>} The opened database handle.\n */\nexport async function openDb() {\n\tif (DexieCtor === null) {\n\t\tconst mod = await import('dexie')\n\t\tDexieCtor = mod.default ?? mod.Dexie\n\t}\n\treturn getDb()\n}\n\n/**\n * The memoised database handle, synchronously.\n *\n * Works once Dexie is loaded: after any `openDb()` call, or after a test\n * injected it with `__setDexie`. Call `await openDb()` when neither is\n * certain; that is what every function in this module does.\n *\n * @return {object} The opened database handle.\n *\n * @throws {Error} When Dexie has not been loaded yet.\n */\nexport function getDb() {\n\tif (dbInstance !== null) {\n\t\treturn dbInstance\n\t}\n\tif (DexieCtor === null) {\n\t\tthrow new Error('The offline database is not open yet: call `await openDb()` first. Dexie loads on first use, so a page that never opens the offline database never evaluates it.')\n\t}\n\n\tconst db = new DexieCtor(DB_NAME)\n\tdb.version(1).stores({\n\t\t// Composite key + indexes so a single DB serves every app/schema.\n\t\tobjectCache: 'key, register, schema, collection, objectId',\n\t\tmutationQueue: 'id, deviceId, status, queuedAt, register, schema',\n\t\tmeta: 'key',\n\t})\n\n\tdbInstance = db\n\treturn db\n}\n\n/**\n * Persist a downloaded planning payload into the local cache atomically.\n *\n * Stores the planned items as one collection and any reference data\n * (e.g. checklist templates) as a second collection, plus a per-collection\n * planning meta row recording the offline-ready expiry. Every write happens in\n * one Dexie transaction so a connection drop mid-write never leaves the cache\n * half-populated.\n *\n * @param {object} args Planning storage arguments.\n * @param {string} args.register Register slug or id.\n * @param {string} args.schema Schema slug of the planned items.\n * @param {Array} args.items The planned objects to cache.\n * @param {Array} [args.references] Optional reference objects (templates).\n * @param {string} [args.referenceSchema] Schema slug of the references.\n * @param {string} [args.collection] Planning collection name (default 'planning').\n * @param {object} [args.manifest] Optional download manifest.\n * @param {number} [args.ttlMs] Offline lifetime (default 24h).\n *\n * @return {Promise<void>} Resolves when the planning is stored.\n */\nexport async function storePlanning({\n\tregister,\n\tschema,\n\titems = [],\n\treferences = [],\n\treferenceSchema = null,\n\tcollection = 'planning',\n\tmanifest = null,\n\tttlMs = 24 * 60 * 60 * 1000,\n}) {\n\tconst db = await openDb()\n\tconst planned = Array.isArray(items) ? items : []\n\tconst refs = Array.isArray(references) ? references : []\n\tconst refSchema = referenceSchema || schema\n\tconst expiresAt = new Date(Date.now() + ttlMs).toISOString()\n\n\tconst objectIdOf = (obj) => String(obj?.id ?? obj?.['@self']?.id ?? obj?.uuid ?? '')\n\n\tconst cacheRows = planned\n\t\t.filter((obj) => objectIdOf(obj) !== '')\n\t\t.map((obj) => ({\n\t\t\tkey: cacheKey(register, schema, collection, objectIdOf(obj)),\n\t\t\tregister,\n\t\t\tschema,\n\t\t\tcollection,\n\t\t\tobjectId: objectIdOf(obj),\n\t\t\tobject: obj,\n\t\t}))\n\n\tconst refRows = refs\n\t\t.filter((obj) => objectIdOf(obj) !== '')\n\t\t.map((obj) => ({\n\t\t\tkey: cacheKey(register, refSchema, 'references', objectIdOf(obj)),\n\t\t\tregister,\n\t\t\tschema: refSchema,\n\t\t\tcollection: 'references',\n\t\t\tobjectId: objectIdOf(obj),\n\t\t\tobject: obj,\n\t\t}))\n\n\tawait db.transaction('rw', db.objectCache, db.meta, async () => {\n\t\tawait db.objectCache.bulkPut(cacheRows.concat(refRows))\n\t\tawait db.meta.put({\n\t\t\tkey: `planning::${register}::${schema}::${collection}`,\n\t\t\tregister,\n\t\t\tschema,\n\t\t\tcollection,\n\t\t\tstatus: 'ready_offline',\n\t\t\texpiresAt,\n\t\t\tsyncedAt: new Date().toISOString(),\n\t\t\tcount: cacheRows.length,\n\t\t\tmanifest,\n\t\t})\n\t})\n}\n\n/**\n * Read the cached planned items for a register/schema/collection.\n *\n * @param {string} register Register slug or id.\n * @param {string} schema Schema slug.\n * @param {string} [collection] Collection name (default 'planning').\n *\n * @return {Promise<Array>} The cached objects (unwrapped from the envelope).\n */\nexport async function getPlannedItems(register, schema, collection = 'planning') {\n\tconst db = await openDb()\n\tconst rows = await db.objectCache\n\t\t.where('collection').equals(collection)\n\t\t.and((row) => row.register === register && row.schema === schema)\n\t\t.toArray()\n\treturn rows.map((row) => row.object)\n}\n\n/**\n * Read a single cached object by id.\n *\n * @param {string} register Register slug or id.\n * @param {string} schema Schema slug.\n * @param {string} collection Collection name.\n * @param {string} objectId The object id.\n *\n * @return {Promise<object|null>} The cached object, or null.\n */\nexport async function getCachedObject(register, schema, collection, objectId) {\n\tconst db = await openDb()\n\tconst row = await db.objectCache.get(cacheKey(register, schema, collection, objectId))\n\treturn row ? row.object : null\n}\n\n/**\n * Read the planning meta row (or null when never synced) for a collection.\n *\n * @param {string} register Register slug or id.\n * @param {string} schema Schema slug.\n * @param {string} [collection] Collection name (default 'planning').\n *\n * @return {Promise<object|null>} The planning meta row.\n */\nexport async function getPlanningMeta(register, schema, collection = 'planning') {\n\tconst db = await openDb()\n\treturn (await db.meta.get(`planning::${register}::${schema}::${collection}`)) ?? null\n}\n\n/**\n * Enqueue one offline mutation against the OR object API.\n *\n * @param {object} operation The mutation operation.\n * @param {string} operation.deviceId Owning device id (IDOR scope).\n * @param {string} operation.operationType create / update / delete.\n * @param {string} operation.register Target register slug or id.\n * @param {string} operation.schema Target schema slug or id.\n * @param {string} [operation.targetId] Existing object id (update/delete).\n * @param {object} [operation.payload] The object body (create/update).\n *\n * @return {Promise<string>} The queued operation id.\n */\nexport async function enqueueMutation(operation) {\n\tconst db = await openDb()\n\tconst id = operation.id || `op-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`\n\tawait db.mutationQueue.put({\n\t\tid,\n\t\tdeviceId: operation.deviceId,\n\t\toperationType: operation.operationType,\n\t\tregister: operation.register,\n\t\tschema: operation.schema,\n\t\ttargetId: operation.targetId ?? null,\n\t\tpayload: operation.payload ?? {},\n\t\tqueuedAt: operation.queuedAt || new Date().toISOString(),\n\t\tattemptCount: 0,\n\t\tstatus: 'pending',\n\t})\n\treturn id\n}\n\n/**\n * Count all queue operations not yet synced — drives the pending badge.\n *\n * @param {string} [deviceId] Optional device scope.\n *\n * @return {Promise<number>} The number of pending/conflict/syncing operations.\n */\nexport async function countPending(deviceId) {\n\tconst db = await openDb()\n\tlet collection = db.mutationQueue.where('status').anyOf(['pending', 'conflict', 'syncing'])\n\tif (typeof deviceId === 'string' && deviceId !== '') {\n\t\tcollection = collection.and((op) => op.deviceId === deviceId)\n\t}\n\treturn await collection.count()\n}\n\n/**\n * Every queued operation, in the order they will replay.\n *\n * 🔴 INCLUDING THE FAILED ONES, WHICH IS THE POINT. `countPending()` counts\n * `pending`, `conflict` and `syncing` and leaves `failed` out, so an operation\n * that exhausted its retries or lost its permission drops out of the badge\n * entirely. The row is still on the device; nothing tells anybody. An\n * inspection a citizen stood beside somebody to give is then stranded in one\n * browser's IndexedDB with no reader, which is worse than having refused it at\n * the door.\n *\n * FIFO by `queuedAt`, the same order the replay loop uses, so the list reads\n * as what will happen next rather than as a set.\n *\n * @param {string} [deviceId] Optional device scope.\n *\n * @return {Promise<object[]>} Every operation, oldest first.\n */\nexport async function listQueue(deviceId) {\n\tconst db = await openDb()\n\tlet collection = db.mutationQueue.orderBy('queuedAt')\n\tif (typeof deviceId === 'string' && deviceId !== '') {\n\t\tcollection = collection.and((op) => op.deviceId === deviceId)\n\t}\n\n\treturn await collection.toArray()\n}\n\n/**\n * How many operations will not replay again without somebody acting.\n *\n * Counted apart from `countPending()` rather than folded into it: \"12 waiting\"\n * and \"12 waiting, 1 stuck\" are different sentences, and a surface that adds\n * them together says neither. Nothing is ever dropped to make this number\n * smaller.\n *\n * @param {string} [deviceId] Optional device scope.\n *\n * @return {Promise<number>} The number of failed operations.\n */\nexport async function countStuck(deviceId) {\n\tconst db = await openDb()\n\tlet collection = db.mutationQueue.where('status').equals('failed')\n\tif (typeof deviceId === 'string' && deviceId !== '') {\n\t\tcollection = collection.and((op) => op.deviceId === deviceId)\n\t}\n\n\treturn await collection.count()\n}\n\n/**\n * Put a failed operation back in the queue, by hand.\n *\n * 🔴 BY HAND, AND NEVER AUTOMATICALLY. `failed` is terminal for the replay\n * loop on purpose: an operation the server refused five times will be refused\n * a sixth, and a queue that retries forever is a queue that never drains. But\n * terminal must not mean forgotten, so somebody who has fixed whatever the\n * server was complaining about can ask for it again, and the attempt count\n * starts over.\n *\n * It does NOT reset a `permission_lost` row. The right to write is gone and\n * retrying cannot bring it back; offering the button would be offering a\n * gesture that fails every time.\n *\n * @param {string} operationId The operation to retry.\n *\n * @return {Promise<boolean>} True when it was re-queued.\n */\nexport async function requeueOperation(operationId) {\n\tconst db = await openDb()\n\tconst operation = await db.mutationQueue.get(operationId)\n\tif (!operation || operation.status !== 'failed') {\n\t\treturn false\n\t}\n\n\tif (operation.lastError === 'permission_lost') {\n\t\treturn false\n\t}\n\n\tawait db.mutationQueue.update(operationId, {\n\t\tstatus: 'pending',\n\t\tattemptCount: 0,\n\t\tlastError: null,\n\t})\n\n\treturn true\n}\n\n/**\n * The prefix of a conflict-record operation's id.\n *\n * Derived from the id of the operation that conflicted, so the record is\n * idempotent by construction: a second drain of the same conflicting row\n * computes the same id and finds it already there.\n */\nexport const CONFLICT_RECORD_PREFIX = 'conflict-'\n\n/**\n * Write a classified conflict to the register as an object of its own.\n *\n * A conflict kept only in this browser's IndexedDB is invisible to everyone who\n * could act on it: the colleague whose edit collided, the supervisor who has to\n * decide, the audit that has to show the decision was taken at all. So the\n * conflict becomes an OpenRegister object, carrying both versions and a\n * reference back to the queue row.\n *\n * The write goes through the queue rather than straight to the network, because\n * the moment a conflict is classified is exactly the moment the connection is\n * unreliable. It replays with everything else.\n *\n * It is written ONCE. The record's id is derived from the conflicting\n * operation's id, so a second drain finds it and leaves it alone rather than\n * filing the same collision twice under two ids.\n *\n * With no `conflictSchema` configured nothing is written, and the queue row is\n * marked so the list can say plainly that this conflict is local to this\n * device. Silently keeping it would be the worse half of both options.\n *\n * @param {object} args Recording arguments.\n * @param {object} args.operation The queue row that conflicted.\n * @param {string} args.conflictType concurrent_edit / deleted_remote / permission_lost.\n * @param {object|null} [args.serverObject] The server's version, when it sent one.\n * @param {string} [args.register] Register to write the record to (default: the operation's).\n * @param {string} [args.conflictSchema] Schema holding conflict records.\n *\n * @return {Promise<string|null>} The record operation id, or null when nothing was written.\n */\nexport async function recordConflict({\n\toperation,\n\tconflictType,\n\tserverObject = null,\n\tregister = '',\n\tconflictSchema = '',\n}) {\n\tconst db = await openDb()\n\n\tif (typeof conflictSchema !== 'string' || conflictSchema === '') {\n\t\tawait db.mutationQueue.update(operation.id, { conflictScope: 'local', conflictType })\n\t\treturn null\n\t}\n\n\tconst recordId = `${CONFLICT_RECORD_PREFIX}${operation.id}`\n\tconst existing = await db.mutationQueue.get(recordId)\n\tif (existing !== undefined) {\n\t\treturn recordId\n\t}\n\n\tawait enqueueMutation({\n\t\tid: recordId,\n\t\tdeviceId: operation.deviceId,\n\t\toperationType: 'create',\n\t\tregister: register || operation.register,\n\t\tschema: conflictSchema,\n\t\tpayload: {\n\t\t\tqueueOperationId: operation.id,\n\t\t\tconflictType,\n\t\t\tdeviceId: operation.deviceId,\n\t\t\ttargetRegister: operation.register,\n\t\t\ttargetSchema: operation.schema,\n\t\t\ttargetId: operation.targetId ?? null,\n\t\t\tclientVersion: operation.payload ?? {},\n\t\t\tserverVersion: serverObject ?? null,\n\t\t\tdetectedAt: new Date().toISOString(),\n\t\t},\n\t})\n\n\tawait db.mutationQueue.update(operation.id, {\n\t\tconflictScope: 'register',\n\t\tconflictType,\n\t\tconflictRecordId: recordId,\n\t\tserverVersion: serverObject ?? null,\n\t})\n\n\treturn recordId\n}\n\n/**\n * Write the resolution onto the conflict object, wherever it currently is.\n *\n * Still queued: its payload is amended in place, so it reaches the register\n * already carrying the decision. Already sent: a follow-up `update` is queued\n * against the id the server gave it. Never sent at all (no schema configured):\n * there is nothing to write to, and the queue row keeps the decision.\n *\n * @param {object} db The Dexie handle.\n * @param {object} operation The conflicting queue row.\n * @param {string} resolution The choice made.\n * @param {string} resolvedBy The uid settling it.\n *\n * @return {Promise<void>} Nothing.\n */\nasync function recordResolutionOnConflictObject(db, operation, resolution, resolvedBy) {\n\tconst recordId = operation.conflictRecordId\n\tif (typeof recordId !== 'string' || recordId === '') {\n\t\treturn\n\t}\n\n\tconst record = await db.mutationQueue.get(recordId)\n\tif (record === undefined) {\n\t\treturn\n\t}\n\n\tconst decision = { resolution, resolvedBy, resolvedAt: new Date().toISOString() }\n\n\tif (record.status !== 'synced') {\n\t\tawait db.mutationQueue.update(recordId, { payload: { ...(record.payload ?? {}), ...decision } })\n\t\treturn\n\t}\n\n\tconst serverId = String(record.serverObjectId ?? '')\n\tif (serverId === '') {\n\t\treturn\n\t}\n\n\tawait enqueueMutation({\n\t\tid: `${recordId}-resolution`,\n\t\tdeviceId: record.deviceId,\n\t\toperationType: 'update',\n\t\tregister: record.register,\n\t\tschema: record.schema,\n\t\ttargetId: serverId,\n\t\tpayload: { ...(record.payload ?? {}), ...decision },\n\t})\n}\n\n/**\n * Apply a person's conflict resolution to the queue and to the record.\n *\n * The decision itself is the pure engine's (`resolveConflictChoice`); this puts\n * the result where it has to live. Three things happen, and the third is the\n * one that is easy to forget:\n *\n * 1. The queue row takes the engine's patch, so keep-mine replays and\n * keep-theirs stops.\n * 2. Keep theirs leaves the local cache holding the SERVER's version. Marking\n * the row synced while the device still shows the abandoned local text is\n * how somebody reads their own discarded answer as the current record.\n * 3. The resolution, who made it and when are written onto the conflict\n * object. A conflict record that says a collision happened and not how it\n * was settled cannot answer the only question anybody asks later.\n *\n * @param {object} args Resolution arguments.\n * @param {string} args.operationId The conflicting queue row.\n * @param {string} args.resolution client_wins / server_wins / manual_merge.\n * @param {object} [args.mergedPayload] The merged body, for a manual merge.\n * @param {string} [args.resolvedBy] The uid settling it.\n *\n * @return {Promise<boolean>} True when a conflict was resolved.\n */\nexport async function applyConflictResolution({\n\toperationId,\n\tresolution,\n\tmergedPayload = null,\n\tresolvedBy = '',\n}) {\n\tconst db = await openDb()\n\tconst operation = await db.mutationQueue.get(operationId)\n\n\tif (operation === undefined || operation.status !== 'conflict') {\n\t\treturn false\n\t}\n\n\tconst { patch } = resolveConflictChoice(resolution, mergedPayload)\n\tawait db.mutationQueue.update(operationId, {\n\t\t...patch,\n\t\tresolution,\n\t\tresolvedBy,\n\t\tresolvedAt: new Date().toISOString(),\n\t})\n\n\tif (resolution === 'server_wins' && operation.serverVersion !== null && operation.serverVersion !== undefined) {\n\t\tconst objectId = String(operation.targetId ?? '')\n\t\tif (objectId !== '') {\n\t\t\tawait db.objectCache.put({\n\t\t\t\tkey: cacheKey(operation.register, operation.schema, 'planning', objectId),\n\t\t\t\tregister: operation.register,\n\t\t\t\tschema: operation.schema,\n\t\t\t\tcollection: 'planning',\n\t\t\t\tobjectId,\n\t\t\t\tobject: operation.serverVersion,\n\t\t\t})\n\t\t}\n\t}\n\n\tawait recordResolutionOnConflictObject(db, operation, resolution, resolvedBy)\n\n\treturn true\n}\n\n/**\n * Resolve a stable per-device id, persisted in localStorage.\n *\n * The device id scopes the mutation queue so the server can re-authorize that\n * only the owning device pushes its own queued operations (IDOR is enforced\n * server-side, never client-asserted).\n *\n * @param {object} [storage] localStorage-like object (test seam).\n *\n * @return {string} The device id.\n */\nexport function resolveDeviceId(storage) {\n\tconst store = storage || (typeof window !== 'undefined' ? window.localStorage : null)\n\tconst STORAGE_KEY = 'cn-offline-device-id'\n\tif (store === null || store === undefined) {\n\t\treturn `device-${Math.random().toString(36).slice(2, 10)}`\n\t}\n\tlet id = store.getItem(STORAGE_KEY)\n\tif (!id) {\n\t\tid = `device-${Math.random().toString(36).slice(2, 10)}`\n\t\tstore.setItem(STORAGE_KEY, id)\n\t}\n\treturn id\n}\n\n/**\n * Reset the memoised handle — test/teardown only.\n *\n * @return {void}\n */\nexport function __resetDbForTests() {\n\tdbInstance = null\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"offlineDb.js","sources":["../../../../src/integrations/offline/offlineDb.js"],"sourcesContent":["/**\n * SPDX-FileCopyrightText: 2026 Conduction B.V. <info@conduction.nl>\n * SPDX-License-Identifier: EUPL-1.2\n *\n * Generic IndexedDB (Dexie.js) store for the offline data-collection core.\n *\n * Unlike procest's bespoke six-table schema, this store is keyed by\n * `register` + `schema` so ANY consuming app can cache its planned objects and\n * queue mutations through one shared database. Three generic tables:\n *\n * - `objectCache` — cached OpenRegister objects (the planned items plus any\n * reference data, e.g. checklist templates). Each row is a\n * `{ key, register, schema, collection, objectId, object }`\n * envelope so multiple apps/schemas never collide.\n * - `mutationQueue` — the offline sync queue: one row per pending create /\n * update / delete to be replayed against the OR object API.\n * - `meta` — singleton rows (per-collection planning state / expiry).\n *\n * Dexie is imported here only — the pure engine (`syncQueueEngine.js`) and the\n * pure helpers carry the unit-test surface and import nothing from this module,\n * so they stay importable in a Node environment with no IndexedDB. Tests for\n * THIS module inject a fake-indexeddb-backed Dexie via `__setDexie`.\n *\n * Dexie is loaded LAZILY, on the first call that needs the database\n * (`openDb()`), and never at import time. This module is reachable from the\n * package root: `src/index.js` exports `offlineCollection`, which reaches\n * `integrations/builtin/field-inspection`, which reaches here. With a static\n * import every consuming app evaluated Dexie on every page, and Dexie throws\n * \"Two different versions of Dexie loaded in the same app\" at module init\n * when a second copy at another version is already on the page. Nextcloud\n * loads several apps' every-page bundles at once (openregister's\n * integration-global among them), so one app a patch release ahead of\n * another blanked whole apps that never touch the offline core. Loaded on\n * demand, Dexie is evaluated only on a page that actually opens the offline\n * database.\n *\n * Dexie stays a REQUIRED peer dependency. The consumer's bundler still\n * resolves `import('dexie')` at BUILD time (it becomes a separate chunk), so\n * an app without it installed fails its build with \"Module not found\". The\n * dependency is required; loading it is not.\n *\n * @module integrations/offline/offlineDb\n */\n\nimport { resolveConflictChoice } from './syncQueueEngine.js'\n\nconst DB_NAME = 'conduction-offline-collection'\n\nlet dbInstance = null\n// Null until `openDb()` loads Dexie, or a test injects it via `__setDexie`.\nlet DexieCtor = null\n\n/**\n * Build the composite cache key for an object.\n *\n * @param {string} register Register slug or id.\n * @param {string} schema Schema slug or id.\n * @param {string} collection Logical collection name (e.g. 'planning', 'templates').\n * @param {string} objectId The object id.\n *\n * @return {string} A stable composite key.\n */\nexport function cacheKey(register, schema, collection, objectId) {\n\treturn `${register}::${schema}::${collection}::${objectId}`\n}\n\n/**\n * Set the Dexie constructor explicitly (test seam / SSR override).\n *\n * Production code never calls this: `openDb()` lazy-imports `dexie`. Tests pass\n * a fake-indexeddb-backed Dexie so the store can be exercised in Node.\n *\n * @param {new (name: string) => object} ctor The Dexie class.\n *\n * @return {void}\n */\nexport function __setDexie(ctor) {\n\tDexieCtor = ctor\n\tdbInstance = null\n}\n\n/**\n * Load Dexie on first use, then open (and memoise) the database.\n *\n * Every function in the offline core goes through this, so Dexie is only\n * evaluated on a page that actually uses the offline database. A Dexie\n * injected with `__setDexie` is used as is and nothing is imported.\n *\n * @return {Promise<object>} The opened database handle.\n */\nexport async function openDb() {\n\tif (DexieCtor === null) {\n\t\tconst mod = await import('dexie')\n\t\tDexieCtor = mod.default ?? mod.Dexie\n\t}\n\treturn getDb()\n}\n\n/**\n * The memoised database handle, synchronously.\n *\n * Works once Dexie is loaded: after any `openDb()` call, or after a test\n * injected it with `__setDexie`. Call `await openDb()` when neither is\n * certain; that is what every function in this module does.\n *\n * @return {object} The opened database handle.\n *\n * @throws {Error} When Dexie has not been loaded yet.\n */\nexport function getDb() {\n\tif (dbInstance !== null) {\n\t\treturn dbInstance\n\t}\n\tif (DexieCtor === null) {\n\t\tthrow new Error('The offline database is not open yet: call `await openDb()` first. Dexie loads on first use, so a page that never opens the offline database never evaluates it.')\n\t}\n\n\tconst db = new DexieCtor(DB_NAME)\n\tdb.version(1).stores({\n\t\t// Composite key + indexes so a single DB serves every app/schema.\n\t\tobjectCache: 'key, register, schema, collection, objectId',\n\t\tmutationQueue: 'id, deviceId, status, queuedAt, register, schema',\n\t\tmeta: 'key',\n\t})\n\n\tdbInstance = db\n\treturn db\n}\n\n/**\n * Persist a downloaded planning payload into the local cache atomically.\n *\n * Stores the planned items as one collection and any reference data\n * (e.g. checklist templates) as a second collection, plus a per-collection\n * planning meta row recording the offline-ready expiry. Every write happens in\n * one Dexie transaction so a connection drop mid-write never leaves the cache\n * half-populated.\n *\n * @param {object} args Planning storage arguments.\n * @param {string} args.register Register slug or id.\n * @param {string} args.schema Schema slug of the planned items.\n * @param {Array} args.items The planned objects to cache.\n * @param {Array} [args.references] Optional reference objects (templates).\n * @param {string} [args.referenceSchema] Schema slug of the references.\n * @param {string} [args.collection] Planning collection name (default 'planning').\n * @param {object} [args.manifest] Optional download manifest.\n * @param {number} [args.ttlMs] Offline lifetime (default 24h).\n *\n * @return {Promise<void>} Resolves when the planning is stored.\n */\nexport async function storePlanning({\n\tregister,\n\tschema,\n\titems = [],\n\treferences = [],\n\treferenceSchema = null,\n\tcollection = 'planning',\n\tmanifest = null,\n\tttlMs = 24 * 60 * 60 * 1000,\n}) {\n\tconst db = await openDb()\n\tconst planned = Array.isArray(items) ? items : []\n\tconst refs = Array.isArray(references) ? references : []\n\tconst refSchema = referenceSchema || schema\n\tconst expiresAt = new Date(Date.now() + ttlMs).toISOString()\n\n\tconst objectIdOf = (obj) => String(obj?.id ?? obj?.['@self']?.id ?? obj?.uuid ?? '')\n\n\tconst cacheRows = planned\n\t\t.filter((obj) => objectIdOf(obj) !== '')\n\t\t.map((obj) => ({\n\t\t\tkey: cacheKey(register, schema, collection, objectIdOf(obj)),\n\t\t\tregister,\n\t\t\tschema,\n\t\t\tcollection,\n\t\t\tobjectId: objectIdOf(obj),\n\t\t\tobject: obj,\n\t\t}))\n\n\tconst refRows = refs\n\t\t.filter((obj) => objectIdOf(obj) !== '')\n\t\t.map((obj) => ({\n\t\t\tkey: cacheKey(register, refSchema, 'references', objectIdOf(obj)),\n\t\t\tregister,\n\t\t\tschema: refSchema,\n\t\t\tcollection: 'references',\n\t\t\tobjectId: objectIdOf(obj),\n\t\t\tobject: obj,\n\t\t}))\n\n\tawait db.transaction('rw', db.objectCache, db.meta, async () => {\n\t\tawait db.objectCache.bulkPut(cacheRows.concat(refRows))\n\t\tawait db.meta.put({\n\t\t\tkey: `planning::${register}::${schema}::${collection}`,\n\t\t\tregister,\n\t\t\tschema,\n\t\t\tcollection,\n\t\t\tstatus: 'ready_offline',\n\t\t\texpiresAt,\n\t\t\tsyncedAt: new Date().toISOString(),\n\t\t\tcount: cacheRows.length,\n\t\t\tmanifest,\n\t\t})\n\t})\n}\n\n/**\n * Read the cached planned items for a register/schema/collection.\n *\n * @param {string} register Register slug or id.\n * @param {string} schema Schema slug.\n * @param {string} [collection] Collection name (default 'planning').\n *\n * @return {Promise<Array>} The cached objects (unwrapped from the envelope).\n */\nexport async function getPlannedItems(register, schema, collection = 'planning') {\n\tconst db = await openDb()\n\tconst rows = await db.objectCache\n\t\t.where('collection').equals(collection)\n\t\t.and((row) => row.register === register && row.schema === schema)\n\t\t.toArray()\n\treturn rows.map((row) => row.object)\n}\n\n/**\n * Read a single cached object by id.\n *\n * @param {string} register Register slug or id.\n * @param {string} schema Schema slug.\n * @param {string} collection Collection name.\n * @param {string} objectId The object id.\n *\n * @return {Promise<object|null>} The cached object, or null.\n */\nexport async function getCachedObject(register, schema, collection, objectId) {\n\tconst db = await openDb()\n\tconst row = await db.objectCache.get(cacheKey(register, schema, collection, objectId))\n\treturn row ? row.object : null\n}\n\n/**\n * Read the planning meta row (or null when never synced) for a collection.\n *\n * @param {string} register Register slug or id.\n * @param {string} schema Schema slug.\n * @param {string} [collection] Collection name (default 'planning').\n *\n * @return {Promise<object|null>} The planning meta row.\n */\nexport async function getPlanningMeta(register, schema, collection = 'planning') {\n\tconst db = await openDb()\n\treturn (await db.meta.get(`planning::${register}::${schema}::${collection}`)) ?? null\n}\n\n/**\n * Enqueue one offline mutation against the OR object API.\n *\n * @param {object} operation The mutation operation.\n * @param {string} operation.deviceId Owning device id (IDOR scope).\n * @param {string} operation.operationType create / update / delete / submit.\n * @param {string} operation.register Target register slug or id.\n * @param {string} operation.schema Target schema slug or id.\n * @param {string} [operation.targetId] Existing object id (update/delete).\n * @param {string} [operation.endpoint] Path under the Nextcloud root a\n * `submit` row is POSTed to.\n * @param {object} [operation.payload] The object body (create/update).\n *\n * @return {Promise<string>} The queued operation id.\n */\nexport async function enqueueMutation(operation) {\n\tconst db = await openDb()\n\tconst id = operation.id || `op-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`\n\tawait db.mutationQueue.put({\n\t\tid,\n\t\tdeviceId: operation.deviceId,\n\t\toperationType: operation.operationType,\n\t\tregister: operation.register,\n\t\tschema: operation.schema,\n\t\ttargetId: operation.targetId ?? null,\n\t\t// A `submit` operation replays to an app's own endpoint instead of the\n\t\t// object API (see checklistSubmission.js); every other row has none.\n\t\tendpoint: operation.endpoint ?? null,\n\t\tpayload: operation.payload ?? {},\n\t\tqueuedAt: operation.queuedAt || new Date().toISOString(),\n\t\tattemptCount: 0,\n\t\tstatus: 'pending',\n\t})\n\treturn id\n}\n\n/**\n * Count all queue operations not yet synced — drives the pending badge.\n *\n * @param {string} [deviceId] Optional device scope.\n *\n * @return {Promise<number>} The number of pending/conflict/syncing operations.\n */\nexport async function countPending(deviceId) {\n\tconst db = await openDb()\n\tlet collection = db.mutationQueue.where('status').anyOf(['pending', 'conflict', 'syncing'])\n\tif (typeof deviceId === 'string' && deviceId !== '') {\n\t\tcollection = collection.and((op) => op.deviceId === deviceId)\n\t}\n\treturn await collection.count()\n}\n\n/**\n * Every queued operation, in the order they will replay.\n *\n * 🔴 INCLUDING THE FAILED ONES, WHICH IS THE POINT. `countPending()` counts\n * `pending`, `conflict` and `syncing` and leaves `failed` out, so an operation\n * that exhausted its retries or lost its permission drops out of the badge\n * entirely. The row is still on the device; nothing tells anybody. An\n * inspection a citizen stood beside somebody to give is then stranded in one\n * browser's IndexedDB with no reader, which is worse than having refused it at\n * the door.\n *\n * FIFO by `queuedAt`, the same order the replay loop uses, so the list reads\n * as what will happen next rather than as a set.\n *\n * @param {string} [deviceId] Optional device scope.\n *\n * @return {Promise<object[]>} Every operation, oldest first.\n */\nexport async function listQueue(deviceId) {\n\tconst db = await openDb()\n\tlet collection = db.mutationQueue.orderBy('queuedAt')\n\tif (typeof deviceId === 'string' && deviceId !== '') {\n\t\tcollection = collection.and((op) => op.deviceId === deviceId)\n\t}\n\n\treturn await collection.toArray()\n}\n\n/**\n * How many operations will not replay again without somebody acting.\n *\n * Counted apart from `countPending()` rather than folded into it: \"12 waiting\"\n * and \"12 waiting, 1 stuck\" are different sentences, and a surface that adds\n * them together says neither. Nothing is ever dropped to make this number\n * smaller.\n *\n * @param {string} [deviceId] Optional device scope.\n *\n * @return {Promise<number>} The number of failed operations.\n */\nexport async function countStuck(deviceId) {\n\tconst db = await openDb()\n\tlet collection = db.mutationQueue.where('status').equals('failed')\n\tif (typeof deviceId === 'string' && deviceId !== '') {\n\t\tcollection = collection.and((op) => op.deviceId === deviceId)\n\t}\n\n\treturn await collection.count()\n}\n\n/**\n * Put a failed operation back in the queue, by hand.\n *\n * 🔴 BY HAND, AND NEVER AUTOMATICALLY. `failed` is terminal for the replay\n * loop on purpose: an operation the server refused five times will be refused\n * a sixth, and a queue that retries forever is a queue that never drains. But\n * terminal must not mean forgotten, so somebody who has fixed whatever the\n * server was complaining about can ask for it again, and the attempt count\n * starts over.\n *\n * It does NOT reset a `permission_lost` row. The right to write is gone and\n * retrying cannot bring it back; offering the button would be offering a\n * gesture that fails every time.\n *\n * @param {string} operationId The operation to retry.\n *\n * @return {Promise<boolean>} True when it was re-queued.\n */\nexport async function requeueOperation(operationId) {\n\tconst db = await openDb()\n\tconst operation = await db.mutationQueue.get(operationId)\n\tif (!operation || operation.status !== 'failed') {\n\t\treturn false\n\t}\n\n\tif (operation.lastError === 'permission_lost') {\n\t\treturn false\n\t}\n\n\tawait db.mutationQueue.update(operationId, {\n\t\tstatus: 'pending',\n\t\tattemptCount: 0,\n\t\tlastError: null,\n\t})\n\n\treturn true\n}\n\n/**\n * The prefix of a conflict-record operation's id.\n *\n * Derived from the id of the operation that conflicted, so the record is\n * idempotent by construction: a second drain of the same conflicting row\n * computes the same id and finds it already there.\n */\nexport const CONFLICT_RECORD_PREFIX = 'conflict-'\n\n/**\n * Write a classified conflict to the register as an object of its own.\n *\n * A conflict kept only in this browser's IndexedDB is invisible to everyone who\n * could act on it: the colleague whose edit collided, the supervisor who has to\n * decide, the audit that has to show the decision was taken at all. So the\n * conflict becomes an OpenRegister object, carrying both versions and a\n * reference back to the queue row.\n *\n * The write goes through the queue rather than straight to the network, because\n * the moment a conflict is classified is exactly the moment the connection is\n * unreliable. It replays with everything else.\n *\n * It is written ONCE. The record's id is derived from the conflicting\n * operation's id, so a second drain finds it and leaves it alone rather than\n * filing the same collision twice under two ids.\n *\n * With no `conflictSchema` configured nothing is written, and the queue row is\n * marked so the list can say plainly that this conflict is local to this\n * device. Silently keeping it would be the worse half of both options.\n *\n * @param {object} args Recording arguments.\n * @param {object} args.operation The queue row that conflicted.\n * @param {string} args.conflictType concurrent_edit / deleted_remote / permission_lost.\n * @param {object|null} [args.serverObject] The server's version, when it sent one.\n * @param {string} [args.register] Register to write the record to (default: the operation's).\n * @param {string} [args.conflictSchema] Schema holding conflict records.\n *\n * @return {Promise<string|null>} The record operation id, or null when nothing was written.\n */\nexport async function recordConflict({\n\toperation,\n\tconflictType,\n\tserverObject = null,\n\tregister = '',\n\tconflictSchema = '',\n}) {\n\tconst db = await openDb()\n\n\tif (typeof conflictSchema !== 'string' || conflictSchema === '') {\n\t\tawait db.mutationQueue.update(operation.id, { conflictScope: 'local', conflictType })\n\t\treturn null\n\t}\n\n\tconst recordId = `${CONFLICT_RECORD_PREFIX}${operation.id}`\n\tconst existing = await db.mutationQueue.get(recordId)\n\tif (existing !== undefined) {\n\t\treturn recordId\n\t}\n\n\tawait enqueueMutation({\n\t\tid: recordId,\n\t\tdeviceId: operation.deviceId,\n\t\toperationType: 'create',\n\t\tregister: register || operation.register,\n\t\tschema: conflictSchema,\n\t\tpayload: {\n\t\t\tqueueOperationId: operation.id,\n\t\t\tconflictType,\n\t\t\tdeviceId: operation.deviceId,\n\t\t\ttargetRegister: operation.register,\n\t\t\ttargetSchema: operation.schema,\n\t\t\ttargetId: operation.targetId ?? null,\n\t\t\tclientVersion: operation.payload ?? {},\n\t\t\tserverVersion: serverObject ?? null,\n\t\t\tdetectedAt: new Date().toISOString(),\n\t\t},\n\t})\n\n\tawait db.mutationQueue.update(operation.id, {\n\t\tconflictScope: 'register',\n\t\tconflictType,\n\t\tconflictRecordId: recordId,\n\t\tserverVersion: serverObject ?? null,\n\t})\n\n\treturn recordId\n}\n\n/**\n * Write the resolution onto the conflict object, wherever it currently is.\n *\n * Still queued: its payload is amended in place, so it reaches the register\n * already carrying the decision. Already sent: a follow-up `update` is queued\n * against the id the server gave it. Never sent at all (no schema configured):\n * there is nothing to write to, and the queue row keeps the decision.\n *\n * @param {object} db The Dexie handle.\n * @param {object} operation The conflicting queue row.\n * @param {string} resolution The choice made.\n * @param {string} resolvedBy The uid settling it.\n *\n * @return {Promise<void>} Nothing.\n */\nasync function recordResolutionOnConflictObject(db, operation, resolution, resolvedBy) {\n\tconst recordId = operation.conflictRecordId\n\tif (typeof recordId !== 'string' || recordId === '') {\n\t\treturn\n\t}\n\n\tconst record = await db.mutationQueue.get(recordId)\n\tif (record === undefined) {\n\t\treturn\n\t}\n\n\tconst decision = { resolution, resolvedBy, resolvedAt: new Date().toISOString() }\n\n\tif (record.status !== 'synced') {\n\t\tawait db.mutationQueue.update(recordId, { payload: { ...(record.payload ?? {}), ...decision } })\n\t\treturn\n\t}\n\n\tconst serverId = String(record.serverObjectId ?? '')\n\tif (serverId === '') {\n\t\treturn\n\t}\n\n\tawait enqueueMutation({\n\t\tid: `${recordId}-resolution`,\n\t\tdeviceId: record.deviceId,\n\t\toperationType: 'update',\n\t\tregister: record.register,\n\t\tschema: record.schema,\n\t\ttargetId: serverId,\n\t\tpayload: { ...(record.payload ?? {}), ...decision },\n\t})\n}\n\n/**\n * Apply a person's conflict resolution to the queue and to the record.\n *\n * The decision itself is the pure engine's (`resolveConflictChoice`); this puts\n * the result where it has to live. Three things happen, and the third is the\n * one that is easy to forget:\n *\n * 1. The queue row takes the engine's patch, so keep-mine replays and\n * keep-theirs stops.\n * 2. Keep theirs leaves the local cache holding the SERVER's version. Marking\n * the row synced while the device still shows the abandoned local text is\n * how somebody reads their own discarded answer as the current record.\n * 3. The resolution, who made it and when are written onto the conflict\n * object. A conflict record that says a collision happened and not how it\n * was settled cannot answer the only question anybody asks later.\n *\n * @param {object} args Resolution arguments.\n * @param {string} args.operationId The conflicting queue row.\n * @param {string} args.resolution client_wins / server_wins / manual_merge.\n * @param {object} [args.mergedPayload] The merged body, for a manual merge.\n * @param {string} [args.resolvedBy] The uid settling it.\n *\n * @return {Promise<boolean>} True when a conflict was resolved.\n */\nexport async function applyConflictResolution({\n\toperationId,\n\tresolution,\n\tmergedPayload = null,\n\tresolvedBy = '',\n}) {\n\tconst db = await openDb()\n\tconst operation = await db.mutationQueue.get(operationId)\n\n\tif (operation === undefined || operation.status !== 'conflict') {\n\t\treturn false\n\t}\n\n\tconst { patch } = resolveConflictChoice(resolution, mergedPayload)\n\tawait db.mutationQueue.update(operationId, {\n\t\t...patch,\n\t\tresolution,\n\t\tresolvedBy,\n\t\tresolvedAt: new Date().toISOString(),\n\t})\n\n\tif (resolution === 'server_wins' && operation.serverVersion !== null && operation.serverVersion !== undefined) {\n\t\tconst objectId = String(operation.targetId ?? '')\n\t\tif (objectId !== '') {\n\t\t\tawait db.objectCache.put({\n\t\t\t\tkey: cacheKey(operation.register, operation.schema, 'planning', objectId),\n\t\t\t\tregister: operation.register,\n\t\t\t\tschema: operation.schema,\n\t\t\t\tcollection: 'planning',\n\t\t\t\tobjectId,\n\t\t\t\tobject: operation.serverVersion,\n\t\t\t})\n\t\t}\n\t}\n\n\tawait recordResolutionOnConflictObject(db, operation, resolution, resolvedBy)\n\n\treturn true\n}\n\n/**\n * Resolve a stable per-device id, persisted in localStorage.\n *\n * The device id scopes the mutation queue so the server can re-authorize that\n * only the owning device pushes its own queued operations (IDOR is enforced\n * server-side, never client-asserted).\n *\n * @param {object} [storage] localStorage-like object (test seam).\n *\n * @return {string} The device id.\n */\nexport function resolveDeviceId(storage) {\n\tconst store = storage || (typeof window !== 'undefined' ? window.localStorage : null)\n\tconst STORAGE_KEY = 'cn-offline-device-id'\n\tif (store === null || store === undefined) {\n\t\treturn `device-${Math.random().toString(36).slice(2, 10)}`\n\t}\n\tlet id = store.getItem(STORAGE_KEY)\n\tif (!id) {\n\t\tid = `device-${Math.random().toString(36).slice(2, 10)}`\n\t\tstore.setItem(STORAGE_KEY, id)\n\t}\n\treturn id\n}\n\n/**\n * Reset the memoised handle — test/teardown only.\n *\n * @return {void}\n */\nexport function __resetDbForTests() {\n\tdbInstance = null\n}\n"],"names":[],"mappings":"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"}
@@ -36,7 +36,8 @@ function objectsUrl(register, schema) {
36
36
  }
37
37
 
38
38
  /**
39
- * Replay one queued mutation against the OR object API.
39
+ * Replay one queued mutation against the OR object API, or, for a row that
40
+ * names an `endpoint`, as one POST to that endpoint.
40
41
  *
41
42
  * @param {object} operation The queue operation row.
42
43
  * @param {object} [offlineConfig] The leaf's offline config (`register`,
@@ -55,7 +56,12 @@ async function replayOperation(operation, offlineConfig = {}) {
55
56
 
56
57
  try {
57
58
  let response;
58
- if (operation.operationType === 'create' || operation.operationType === 'upload') {
59
+ if (typeof operation.endpoint === 'string' && operation.endpoint !== '') {
60
+ // A run the app checks and stores itself (a completed task, say):
61
+ // one POST to its endpoint under the Nextcloud root. The endpoint
62
+ // decides access from what it has stored, as the object API does.
63
+ response = await axios__default.post(generateUrl(operation.endpoint), payload);
64
+ } else if (operation.operationType === 'create' || operation.operationType === 'upload') {
59
65
  response = await axios__default.post(base, payload);
60
66
  } else if (operation.operationType === 'update') {
61
67
  response = await axios__default.put(`${base}/${operation.targetId}`, payload);
@@ -1 +1 @@
1
- {"version":3,"file":"syncReplayService.js","sources":["../../../../src/integrations/offline/syncReplayService.js"],"sourcesContent":["/**\n * SPDX-FileCopyrightText: 2026 Conduction B.V. <info@conduction.nl>\n * SPDX-License-Identifier: EUPL-1.2\n *\n * Generic sync-replay glue for the offline data-collection core.\n *\n * Drains the device's queued mutations against the standard OpenRegister\n * object API on reconnect and applies the pure-engine status transition to each\n * queue row. Unlike procest's bespoke service this carries no app-specific\n * outcome callback: re-authorization happens inside OR's own object API (RBAC +\n * multitenancy on `/apps/openregister/api/objects/...`), so any consuming app\n * gets conflict marking, backoff and IDOR-safe replay for free.\n *\n * Browser-only (axios + IndexedDB + navigator.onLine). The decision logic it\n * calls is the pure {@link module:integrations/offline/syncQueueEngine}.\n *\n * @module integrations/offline/syncReplayService\n */\n\nimport axios from '@nextcloud/axios'\nimport { generateUrl } from '@nextcloud/router'\nimport { openDb, recordConflict } from './offlineDb.js'\nimport { nextState, orderForReplay } from './syncQueueEngine.js'\n\n/**\n * Build the OR object-collection URL for a register/schema.\n *\n * @param {string} register Register slug or id.\n * @param {string} schema Schema slug or id.\n *\n * @return {string} The generated collection URL.\n */\nfunction objectsUrl(register, schema) {\n\treturn generateUrl(`/apps/openregister/api/objects/${register}/${schema}`)\n}\n\n/**\n * Replay one queued mutation against the OR object API.\n *\n * @param {object} operation The queue operation row.\n * @param {object} [offlineConfig] The leaf's offline config (`register`,\n * `conflictSchema`).\n *\n * @return {Promise<object>} The applied patch from the engine.\n */\nexport async function replayOperation(operation, offlineConfig = {}) {\n\tconst db = await openDb()\n\tlet statusCode\n\tlet serverObject = null\n\tlet responseBody = null\n\n\tconst base = objectsUrl(operation.register, operation.schema)\n\tconst payload = operation.payload ?? {}\n\n\ttry {\n\t\tlet response\n\t\tif (operation.operationType === 'create' || operation.operationType === 'upload') {\n\t\t\tresponse = await axios.post(base, payload)\n\t\t} else if (operation.operationType === 'update') {\n\t\t\tresponse = await axios.put(`${base}/${operation.targetId}`, payload)\n\t\t} else if (operation.operationType === 'delete') {\n\t\t\tresponse = await axios.delete(`${base}/${operation.targetId}`)\n\t\t} else {\n\t\t\tresponse = await axios.post(base, payload)\n\t\t}\n\t\tstatusCode = response.status\n\t\tresponseBody = response.data ?? null\n\t} catch (error) {\n\t\tstatusCode = error?.response?.status ?? 0\n\t\tserverObject = error?.response?.data ?? null\n\t}\n\n\tconst { patch, conflictType } = nextState(operation, { statusCode, serverObject })\n\n\t// The id the server gave this object, kept so a later write can address it.\n\t// Without it a conflict record is write-once: the resolution somebody makes\n\t// an hour later has nowhere to go, and the register holds a collision with\n\t// no outcome, which answers neither of the questions it was filed for.\n\tconst serverObjectId = idOf(responseBody)\n\tif (patch.status === 'synced' && serverObjectId !== '') {\n\t\tpatch.serverObjectId = serverObjectId\n\t}\n\n\tawait db.mutationQueue.update(operation.id, patch)\n\n\t// A conflict is recorded where other people can see it, not only here.\n\t// `permission_lost` is recorded too: it lands as `failed` rather than\n\t// `conflict`, and it is precisely the case where the person holding the\n\t// capture can do nothing and somebody else must.\n\tif (conflictType !== null) {\n\t\tawait recordConflict({\n\t\t\toperation,\n\t\t\tconflictType,\n\t\t\tserverObject,\n\t\t\tregister: offlineConfig.register ?? '',\n\t\t\tconflictSchema: offlineConfig.conflictSchema ?? '',\n\t\t})\n\t}\n\n\treturn patch\n}\n\n/**\n * The id inside an OpenRegister object response, wherever it is carried.\n *\n * @param {object|null} body The response body.\n *\n * @return {string} The id, or an empty string.\n */\nfunction idOf(body) {\n\tif (body === null || typeof body !== 'object') {\n\t\treturn ''\n\t}\n\treturn String(body.id ?? body['@self']?.id ?? body.uuid ?? '')\n}\n\n/**\n * Drain the device's pending queue in FIFO order.\n *\n * @param {string} deviceId The owning device.\n * @param {object} [offlineConfig] The leaf's offline config; `register` and\n * `conflictSchema` decide where a conflict is\n * filed. Omitted, conflicts stay on the device\n * and the queue row says so.\n *\n * @return {Promise<{ processed: number, synced: number, conflicts: number, failed: number }>}\n */\nexport async function drainQueue(deviceId, offlineConfig = {}) {\n\tif (typeof navigator !== 'undefined' && navigator.onLine === false) {\n\t\treturn { processed: 0, synced: 0, conflicts: 0, failed: 0 }\n\t}\n\n\tconst db = await openDb()\n\tconst rows = await db.mutationQueue.where('deviceId').equals(deviceId).toArray()\n\tconst ordered = orderForReplay(rows)\n\n\tconst tally = { processed: 0, synced: 0, conflicts: 0, failed: 0 }\n\tfor (const operation of ordered) {\n\t\tconst patch = await replayOperation(operation, offlineConfig)\n\t\ttally.processed += 1\n\t\tif (patch.status === 'synced') {\n\t\t\ttally.synced += 1\n\t\t} else if (patch.status === 'conflict') {\n\t\t\ttally.conflicts += 1\n\t\t} else if (patch.status === 'failed') {\n\t\t\ttally.failed += 1\n\t\t}\n\t}\n\n\treturn tally\n}\n"],"names":["axios"],"mappings":"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"}
1
+ {"version":3,"file":"syncReplayService.js","sources":["../../../../src/integrations/offline/syncReplayService.js"],"sourcesContent":["/**\n * SPDX-FileCopyrightText: 2026 Conduction B.V. <info@conduction.nl>\n * SPDX-License-Identifier: EUPL-1.2\n *\n * Generic sync-replay glue for the offline data-collection core.\n *\n * Drains the device's queued mutations against the standard OpenRegister\n * object API on reconnect and applies the pure-engine status transition to each\n * queue row. Unlike procest's bespoke service this carries no app-specific\n * outcome callback: re-authorization happens inside OR's own object API (RBAC +\n * multitenancy on `/apps/openregister/api/objects/...`), so any consuming app\n * gets conflict marking, backoff and IDOR-safe replay for free.\n *\n * Browser-only (axios + IndexedDB + navigator.onLine). The decision logic it\n * calls is the pure {@link module:integrations/offline/syncQueueEngine}.\n *\n * @module integrations/offline/syncReplayService\n */\n\nimport axios from '@nextcloud/axios'\nimport { generateUrl } from '@nextcloud/router'\nimport { openDb, recordConflict } from './offlineDb.js'\nimport { nextState, orderForReplay } from './syncQueueEngine.js'\n\n/**\n * Build the OR object-collection URL for a register/schema.\n *\n * @param {string} register Register slug or id.\n * @param {string} schema Schema slug or id.\n *\n * @return {string} The generated collection URL.\n */\nfunction objectsUrl(register, schema) {\n\treturn generateUrl(`/apps/openregister/api/objects/${register}/${schema}`)\n}\n\n/**\n * Replay one queued mutation against the OR object API, or, for a row that\n * names an `endpoint`, as one POST to that endpoint.\n *\n * @param {object} operation The queue operation row.\n * @param {object} [offlineConfig] The leaf's offline config (`register`,\n * `conflictSchema`).\n *\n * @return {Promise<object>} The applied patch from the engine.\n */\nexport async function replayOperation(operation, offlineConfig = {}) {\n\tconst db = await openDb()\n\tlet statusCode\n\tlet serverObject = null\n\tlet responseBody = null\n\n\tconst base = objectsUrl(operation.register, operation.schema)\n\tconst payload = operation.payload ?? {}\n\n\ttry {\n\t\tlet response\n\t\tif (typeof operation.endpoint === 'string' && operation.endpoint !== '') {\n\t\t\t// A run the app checks and stores itself (a completed task, say):\n\t\t\t// one POST to its endpoint under the Nextcloud root. The endpoint\n\t\t\t// decides access from what it has stored, as the object API does.\n\t\t\tresponse = await axios.post(generateUrl(operation.endpoint), payload)\n\t\t} else if (operation.operationType === 'create' || operation.operationType === 'upload') {\n\t\t\tresponse = await axios.post(base, payload)\n\t\t} else if (operation.operationType === 'update') {\n\t\t\tresponse = await axios.put(`${base}/${operation.targetId}`, payload)\n\t\t} else if (operation.operationType === 'delete') {\n\t\t\tresponse = await axios.delete(`${base}/${operation.targetId}`)\n\t\t} else {\n\t\t\tresponse = await axios.post(base, payload)\n\t\t}\n\t\tstatusCode = response.status\n\t\tresponseBody = response.data ?? null\n\t} catch (error) {\n\t\tstatusCode = error?.response?.status ?? 0\n\t\tserverObject = error?.response?.data ?? null\n\t}\n\n\tconst { patch, conflictType } = nextState(operation, { statusCode, serverObject })\n\n\t// The id the server gave this object, kept so a later write can address it.\n\t// Without it a conflict record is write-once: the resolution somebody makes\n\t// an hour later has nowhere to go, and the register holds a collision with\n\t// no outcome, which answers neither of the questions it was filed for.\n\tconst serverObjectId = idOf(responseBody)\n\tif (patch.status === 'synced' && serverObjectId !== '') {\n\t\tpatch.serverObjectId = serverObjectId\n\t}\n\n\tawait db.mutationQueue.update(operation.id, patch)\n\n\t// A conflict is recorded where other people can see it, not only here.\n\t// `permission_lost` is recorded too: it lands as `failed` rather than\n\t// `conflict`, and it is precisely the case where the person holding the\n\t// capture can do nothing and somebody else must.\n\tif (conflictType !== null) {\n\t\tawait recordConflict({\n\t\t\toperation,\n\t\t\tconflictType,\n\t\t\tserverObject,\n\t\t\tregister: offlineConfig.register ?? '',\n\t\t\tconflictSchema: offlineConfig.conflictSchema ?? '',\n\t\t})\n\t}\n\n\treturn patch\n}\n\n/**\n * The id inside an OpenRegister object response, wherever it is carried.\n *\n * @param {object|null} body The response body.\n *\n * @return {string} The id, or an empty string.\n */\nfunction idOf(body) {\n\tif (body === null || typeof body !== 'object') {\n\t\treturn ''\n\t}\n\treturn String(body.id ?? body['@self']?.id ?? body.uuid ?? '')\n}\n\n/**\n * Drain the device's pending queue in FIFO order.\n *\n * @param {string} deviceId The owning device.\n * @param {object} [offlineConfig] The leaf's offline config; `register` and\n * `conflictSchema` decide where a conflict is\n * filed. Omitted, conflicts stay on the device\n * and the queue row says so.\n *\n * @return {Promise<{ processed: number, synced: number, conflicts: number, failed: number }>}\n */\nexport async function drainQueue(deviceId, offlineConfig = {}) {\n\tif (typeof navigator !== 'undefined' && navigator.onLine === false) {\n\t\treturn { processed: 0, synced: 0, conflicts: 0, failed: 0 }\n\t}\n\n\tconst db = await openDb()\n\tconst rows = await db.mutationQueue.where('deviceId').equals(deviceId).toArray()\n\tconst ordered = orderForReplay(rows)\n\n\tconst tally = { processed: 0, synced: 0, conflicts: 0, failed: 0 }\n\tfor (const operation of ordered) {\n\t\tconst patch = await replayOperation(operation, offlineConfig)\n\t\ttally.processed += 1\n\t\tif (patch.status === 'synced') {\n\t\t\ttally.synced += 1\n\t\t} else if (patch.status === 'conflict') {\n\t\t\ttally.conflicts += 1\n\t\t} else if (patch.status === 'failed') {\n\t\t\ttally.failed += 1\n\t\t}\n\t}\n\n\treturn tally\n}\n"],"names":["axios"],"mappings":"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"}
@@ -1,4 +1,6 @@
1
1
  var translations = {
2
+ "You cannot see these files": "You cannot see these files",
3
+ "Delete {name}? This cannot be undone here.": "Delete {name}? This cannot be undone here.",
2
4
  "Linked items": "Linked items",
3
5
  "Still loading: {sections}": "Still loading: {sections}",
4
6
  "Could not load {section}.": "Could not load {section}.",
@@ -64,6 +66,7 @@ var translations = {
64
66
  "Follow this record to get its updates": "Follow this record to get its updates",
65
67
  "You will see it under Following. This register sends no change notifications.": "You will see it under Following. This register sends no change notifications.",
66
68
  "Since {date}": "Since {date}",
69
+ "since {date}": "since {date}",
67
70
  "Remove {name} as a follower": "Remove {name} as a follower",
68
71
  "Could not change following.": "Could not change following.",
69
72
  "Could not add this colleague.": "Could not add this colleague.",
@@ -223,6 +226,7 @@ var translations = {
223
226
  "Access URL": "Access URL",
224
227
  Action: "Action",
225
228
  Actions: "Actions",
229
+ optional: "optional",
226
230
  Add: "Add",
227
231
  "Add condition": "Add condition",
228
232
  "Add enum value": "Add enum value",
@@ -297,6 +301,9 @@ var translations = {
297
301
  Constant: "Constant",
298
302
  Copy: "Copy",
299
303
  Copied: "Copied",
304
+ Show: "Show",
305
+ "Copy {label}": "Copy {label}",
306
+ "Show {label}": "Show {label}",
300
307
  "Copy item": "Copy item",
301
308
  "Copy items": "Copy items",
302
309
  "Copy of {name}": "Copy of {name}",
@@ -571,6 +578,8 @@ var translations = {
571
578
  Order: "Order",
572
579
  "Owner:": "Owner:",
573
580
  "Page {current} of {total}": "Page {current} of {total}",
581
+ "{shown} of {total}": "{shown} of {total}",
582
+ "{from}–{to} of {total}": "{from}–{to} of {total}",
574
583
  "Parent schemas:": "Parent schemas:",
575
584
  Password: "Password",
576
585
  "Pattern (regex)": "Pattern (regex)",
@@ -770,6 +779,28 @@ var translations = {
770
779
  "Message input": "Message input",
771
780
  "Start new chat": "Start new chat",
772
781
  History: "History",
782
+ "No audit entries yet": "No audit entries yet",
783
+ Meetings: "Meetings",
784
+ "No meetings": "No meetings",
785
+ "Open in Calendar": "Open in Calendar",
786
+ "(no title)": "(no title)",
787
+ "Could not load meetings.": "Could not load meetings.",
788
+ "Could not load meeting.": "Could not load meeting.",
789
+ "Calendar is currently unavailable.": "Calendar is currently unavailable.",
790
+ "Show all {count} fields": "Show all {count} fields",
791
+ "Show less": "Show less",
792
+ "{count} more": "{count} more",
793
+ "Identifier: {identifier}": "Identifier: {identifier}",
794
+ "What happened, who did it and when, newest first": "What happened, who did it and when, newest first",
795
+ "{app} is not installed": "{app} is not installed",
796
+ "Install and enable the {app} app to see this.": "Install and enable the {app} app to see this.",
797
+ "{title} needs the {app} app. Install and enable it to see this.": "{title} needs the {app} app. Install and enable it to see this.",
798
+ "View all ({total})": "View all ({total})",
799
+ "No items": "No items",
800
+ "Nothing here yet": "Nothing here yet",
801
+ "This list could not be loaded.": "This list could not be loaded.",
802
+ "No items match this filter": "No items match this filter",
803
+ "Could not load these records": "Could not load these records",
773
804
  "No conversations yet": "No conversations yet",
774
805
  "Connecting...": "Connecting...",
775
806
  "Loading conversations...": "Loading conversations...",
@@ -1308,9 +1339,41 @@ var translations = {
1308
1339
  "Filter by {column}, active": "Filter by {column}, active",
1309
1340
  "Turn notifications off": "Turn notifications off",
1310
1341
  "Turn notifications on": "Turn notifications on",
1311
- "Could not change notifications.": "Could not change notifications."
1342
+ "Could not change notifications.": "Could not change notifications.",
1343
+ "Actions for the selection": "Actions for the selection",
1344
+ "Active:": "Active:",
1345
+ Filter: "Filter",
1346
+ List: "List",
1347
+ "Map": "Map",
1348
+ "Remove filter: {label}": "Remove filter: {label}",
1349
+ "Search and columns": "Search and columns",
1350
+ "Sort by": "Sort by",
1351
+ "View mode": "View mode",
1352
+ "With the selected {plural}": "With the selected {plural}",
1353
+ items: "items",
1354
+ "{count} active": "{count} active",
1355
+ "Delete \"{name}\"": "Delete \"{name}\"",
1356
+ "No saved views yet": "No saved views yet",
1357
+ "No views with this label": "No views with this label",
1358
+ "Save current view…": "Save current view…",
1359
+ "Save view": "Save view",
1360
+ "Saved views": "Saved views",
1361
+ "Show only views labelled \"{label}\"": "Show only views labelled \"{label}\"",
1362
+ "Stop filtering on \"{label}\"": "Stop filtering on \"{label}\"",
1363
+ "{name}, level {level}": "{name}, level {level}",
1364
+ "{name}. Parts of this view come from one you cannot see.": "{name}. Parts of this view come from one you cannot see.",
1365
+ "More filters": "More filters",
1366
+ "Quick filters": "Quick filters",
1367
+ "{count} filters": "{count} filters",
1368
+ "{count} more filters": "{count} more filters",
1369
+ "{label} — show the other filters": "{label} — show the other filters",
1370
+ "{view}: not available on this list": "{view}: not available on this list"
1312
1371
  };
1313
1372
  var plurals = {
1373
+ "{count} selected": [
1374
+ "{count} selected",
1375
+ "{count} selected"
1376
+ ],
1314
1377
  "%n year": [
1315
1378
  "%n year",
1316
1379
  "%n years"
@@ -1319,6 +1382,10 @@ var plurals = {
1319
1382
  "%n month",
1320
1383
  "%n months"
1321
1384
  ],
1385
+ "%n hour": [
1386
+ "%n hour",
1387
+ "%n hours"
1388
+ ],
1322
1389
  "%n day": [
1323
1390
  "%n day",
1324
1391
  "%n days"
@@ -1374,6 +1441,10 @@ var plurals = {
1374
1441
  "in {count} day": [
1375
1442
  "in {count} day",
1376
1443
  "in {count} days"
1444
+ ],
1445
+ "{count} more filter": [
1446
+ "{count} more filter",
1447
+ "{count} more filters"
1377
1448
  ]
1378
1449
  };
1379
1450
  var en = {
@@ -1 +1 @@
1
- {"version":3,"file":"en.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"en.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,4 +1,6 @@
1
1
  var translations = {
2
+ "You cannot see these files": "Je kunt deze bestanden niet zien",
3
+ "Delete {name}? This cannot be undone here.": "{name} verwijderen? Dit kun je hier niet ongedaan maken.",
2
4
  "Linked items": "Gekoppelde items",
3
5
  "Still loading: {sections}": "Nog aan het laden: {sections}",
4
6
  "Could not load {section}.": "{section} kon niet worden geladen.",
@@ -64,6 +66,7 @@ var translations = {
64
66
  "Follow this record to get its updates": "Volg dit dossier om de wijzigingen te ontvangen",
65
67
  "You will see it under Following. This register sends no change notifications.": "U ziet het onder Volgend. Dit register stuurt geen wijzigingsmeldingen.",
66
68
  "Since {date}": "Sinds {date}",
69
+ "since {date}": "sinds {date}",
67
70
  "Remove {name} as a follower": "{name} als volger verwijderen",
68
71
  "Could not change following.": "Volgen kon niet worden gewijzigd.",
69
72
  "Could not add this colleague.": "Deze collega kon niet worden toegevoegd.",
@@ -222,6 +225,7 @@ var translations = {
222
225
  "Access URL": "Toegangs-URL",
223
226
  Action: "Actie",
224
227
  Actions: "Acties",
228
+ optional: "niet verplicht",
225
229
  Add: "Toevoegen",
226
230
  "Add condition": "Voorwaarde toevoegen",
227
231
  "Add enum value": "Opsommingswaarde toevoegen",
@@ -296,6 +300,9 @@ var translations = {
296
300
  Constant: "Constante",
297
301
  Copy: "Kopiëren",
298
302
  Copied: "Gekopieerd",
303
+ Show: "Tonen",
304
+ "Copy {label}": "{label} kopiëren",
305
+ "Show {label}": "{label} tonen",
299
306
  "Copy item": "Item kopiëren",
300
307
  "Copy items": "Items kopiëren",
301
308
  "Copy of {name}": "Kopie van {name}",
@@ -566,10 +573,16 @@ var translations = {
566
573
  Open: "Openen",
567
574
  "Open access:": "Openbare toegang:",
568
575
  "Open row": "Rij openen",
576
+ "Select all rows": "Alle rijen selecteren",
577
+ "Select row": "Rij selecteren",
578
+ "Scrollable table": "Scrollbare tabel",
579
+ "{title} — scrollable table": "{title}, scrollbare tabel",
569
580
  Operator: "Operator",
570
581
  Order: "Volgorde",
571
582
  "Owner:": "Eigenaar:",
572
583
  "Page {current} of {total}": "Pagina {current} van {total}",
584
+ "{shown} of {total}": "{shown} van {total}",
585
+ "{from}–{to} of {total}": "{from}–{to} van {total}",
573
586
  "Parent schemas:": "Bovenliggende schema's:",
574
587
  Password: "Wachtwoord",
575
588
  "Pattern (regex)": "Patroon (regex)",
@@ -768,7 +781,29 @@ var translations = {
768
781
  "AI assistant": "AI-assistent",
769
782
  "Message input": "Berichtinvoer",
770
783
  "Start new chat": "Nieuwe chat starten",
771
- History: "Geschiedenis",
784
+ History: "Historie",
785
+ "No audit entries yet": "Nog geen wijzigingen vastgelegd",
786
+ Meetings: "Afspraken",
787
+ "No meetings": "Geen afspraken",
788
+ "Open in Calendar": "Openen in Agenda",
789
+ "(no title)": "(geen titel)",
790
+ "Could not load meetings.": "De afspraken konden niet worden geladen.",
791
+ "Could not load meeting.": "De afspraak kon niet worden geladen.",
792
+ "Calendar is currently unavailable.": "De agenda is nu niet beschikbaar.",
793
+ "Show all {count} fields": "Alle {count} velden tonen",
794
+ "Show less": "Minder tonen",
795
+ "{count} more": "Nog {count}",
796
+ "Identifier: {identifier}": "Kenmerk: {identifier}",
797
+ "What happened, who did it and when, newest first": "Wat er gebeurde, door wie en wanneer, nieuwste eerst",
798
+ "{app} is not installed": "{app} is niet geïnstalleerd",
799
+ "Install and enable the {app} app to see this.": "Installeer en activeer de app {app} om dit te zien.",
800
+ "{title} needs the {app} app. Install and enable it to see this.": "{title} heeft de app {app} nodig. Installeer en activeer die om dit te zien.",
801
+ "View all ({total})": "Alles bekijken ({total})",
802
+ "No items": "Geen items",
803
+ "Nothing here yet": "Hier staat nog niets",
804
+ "This list could not be loaded.": "Deze lijst kon niet worden geladen.",
805
+ "No items match this filter": "Geen items voldoen aan dit filter",
806
+ "Could not load these records": "Deze gegevens konden niet worden geladen",
772
807
  "No conversations yet": "Nog geen gesprekken",
773
808
  "Connecting...": "Verbinden...",
774
809
  "Loading conversations...": "Gesprekken laden...",
@@ -1359,9 +1394,84 @@ var translations = {
1359
1394
  "Filter by {column}, active": "Filteren op {column}, actief",
1360
1395
  "Turn notifications off": "Meldingen uitzetten",
1361
1396
  "Turn notifications on": "Meldingen aanzetten",
1362
- "Could not change notifications.": "Meldingen konden niet worden gewijzigd."
1397
+ "Could not change notifications.": "Meldingen konden niet worden gewijzigd.",
1398
+ "Actions for the selection": "Acties voor de selectie",
1399
+ "Active:": "Actief:",
1400
+ Filter: "Filter",
1401
+ List: "Lijst",
1402
+ "Map": "Kaart",
1403
+ "Remove filter: {label}": "Filter verwijderen: {label}",
1404
+ "Search and columns": "Zoeken en kolommen",
1405
+ "Sort by": "Sorteren op",
1406
+ "View mode": "Weergave",
1407
+ "With the selected {plural}": "Met de geselecteerde {plural}",
1408
+ items: "items",
1409
+ "{count} active": "{count} actief",
1410
+ "Delete \"{name}\"": "\"{name}\" verwijderen",
1411
+ "No saved views yet": "Nog geen opgeslagen weergaven",
1412
+ "No views with this label": "Geen weergaven met dit label",
1413
+ "Save current view…": "Huidige weergave opslaan…",
1414
+ "Save view": "Weergave opslaan",
1415
+ "Saved views": "Opgeslagen weergaven",
1416
+ "Show only views labelled \"{label}\"": "Alleen weergaven met label \"{label}\" tonen",
1417
+ "Stop filtering on \"{label}\"": "Niet meer filteren op \"{label}\"",
1418
+ "{name}, level {level}": "{name}, niveau {level}",
1419
+ "{name}. Parts of this view come from one you cannot see.": "{name}. Delen van deze weergave komen uit een weergave die u niet kunt zien.",
1420
+ "More filters": "Meer filters",
1421
+ "Quick filters": "Snelfilters",
1422
+ "{count} filters": "{count} filters",
1423
+ "{count} more filters": "{count} filters meer",
1424
+ "{label} — show the other filters": "{label}, toon de andere filters",
1425
+ "A file or folder with that name is already here": "Hier staat al een bestand of map met die naam",
1426
+ "A file with that name is already here": "Hier staat al een bestand met die naam",
1427
+ "A name cannot contain a slash": "Een naam kan geen schuine streep bevatten",
1428
+ "Actions for {name}": "Acties voor {name}",
1429
+ Download: "Downloaden",
1430
+ "Drop files here, or use New": "Sleep bestanden hierheen, of gebruik Nieuw",
1431
+ "Folder name": "Mapnaam",
1432
+ Modified: "Gewijzigd",
1433
+ New: "Nieuw",
1434
+ "New folder": "Nieuwe map",
1435
+ "New name": "Nieuwe naam",
1436
+ Rename: "Naam wijzigen",
1437
+ "Show in Files": "Tonen in Bestanden",
1438
+ Size: "Grootte",
1439
+ "The folder could not be created": "De map kon niet worden gemaakt",
1440
+ "The folder could not be read": "De map kon niet worden gelezen",
1441
+ "The name could not be changed": "De naam kon niet worden gewijzigd",
1442
+ "The upload failed": "Het uploaden is mislukt",
1443
+ "This folder is empty": "Deze map is leeg",
1444
+ "This folder no longer exists": "Deze map bestaat niet meer",
1445
+ "Try again": "Opnieuw proberen",
1446
+ "Upload files": "Bestanden uploaden",
1447
+ "You cannot see this folder": "Je kunt deze map niet zien",
1448
+ "{action} did not succeed": "{action} is niet gelukt",
1449
+ "Error:": "Fout:",
1450
+ "Copy link": "Link kopiëren",
1451
+ "Details and sharing": "Details en delen",
1452
+ "Link copied": "Link gekopieerd",
1453
+ "Share uploaded files": "Geüploade bestanden delen",
1454
+ "The link could not be copied": "De link kon niet worden gekopieerd",
1455
+ "Invalid JSON: {msg}": "Ongeldige JSON: {msg}",
1456
+ "Loading the fields this choice adds.": "De velden van deze keuze worden geladen.",
1457
+ Restore: "Herstellen",
1458
+ "Save draft": "Concept opslaan",
1459
+ "Saved {title}": "{title} opgeslagen",
1460
+ "Saved, but some rows were not saved: {rows}": "Opgeslagen, maar sommige rijen zijn niet opgeslagen: {rows}",
1461
+ "The list of choices could not be loaded. Enter the value by hand.": "De keuzelijst kon niet worden geladen. Vul de waarde zelf in.",
1462
+ "You have unsaved changes from an earlier visit.": "Je hebt niet-opgeslagen wijzigingen van een eerder bezoek.",
1463
+ "no longer offered": "niet meer beschikbaar",
1464
+ "1 day left": "Nog 1 dag",
1465
+ "{count} days left": "Nog {count} dagen",
1466
+ "1 day overdue": "1 dag te laat",
1467
+ "{count} days overdue": "{count} dagen te laat",
1468
+ "{view}: not available on this list": "{view}: niet beschikbaar in deze lijst"
1363
1469
  };
1364
1470
  var plurals = {
1471
+ "{count} selected": [
1472
+ "{count} geselecteerd",
1473
+ "{count} geselecteerd"
1474
+ ],
1365
1475
  "%n year": [
1366
1476
  "%n jaar",
1367
1477
  "%n jaar"
@@ -1370,6 +1480,10 @@ var plurals = {
1370
1480
  "%n maand",
1371
1481
  "%n maanden"
1372
1482
  ],
1483
+ "%n hour": [
1484
+ "%n uur",
1485
+ "%n uur"
1486
+ ],
1373
1487
  "%n day": [
1374
1488
  "%n dag",
1375
1489
  "%n dagen"
@@ -1425,6 +1539,10 @@ var plurals = {
1425
1539
  "in {count} day": [
1426
1540
  "over {count} dag",
1427
1541
  "over {count} dagen"
1542
+ ],
1543
+ "{count} more filter": [
1544
+ "Nog {count} filter",
1545
+ "Nog {count} filters"
1428
1546
  ]
1429
1547
  };
1430
1548
  var nl = {
@@ -1 +1 @@
1
- {"version":3,"file":"nl.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"nl.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}