@conduction/nextcloud-vue 2.93.0 → 2.95.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 (162) hide show
  1. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue2.js +1 -1
  2. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue2.js.map +1 -1
  3. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue3.js +2 -1
  4. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue3.js.map +1 -1
  5. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue.js +1 -1
  6. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue2.js +28 -8
  7. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue2.js.map +1 -1
  8. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js +37 -2
  9. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js.map +1 -1
  10. package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js +46 -28
  11. package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js.map +1 -1
  12. package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js +17 -10
  13. package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js.map +1 -1
  14. package/dist/esm/components/CnBrandBar/CnBrandBar.vue2.js.map +1 -1
  15. package/dist/esm/components/CnBrandBar/CnBrandBar.vue3.js.map +1 -1
  16. package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue.js +1 -1
  17. package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue2.js +139 -3
  18. package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue2.js.map +1 -1
  19. package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue3.js +60 -12
  20. package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue3.js.map +1 -1
  21. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue.js +1 -1
  22. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +91 -36
  23. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
  24. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +115 -72
  25. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
  26. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +32 -3
  27. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
  28. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +7 -7
  29. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
  30. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +56 -16
  31. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
  32. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
  33. package/dist/esm/components/CnDeviceFramesWidget/CnDeviceFramesWidget.vue.js +9 -0
  34. package/dist/esm/components/CnDeviceFramesWidget/CnDeviceFramesWidget.vue.js.map +1 -0
  35. package/dist/esm/components/CnDeviceFramesWidget/CnDeviceFramesWidget.vue2.js +240 -0
  36. package/dist/esm/components/CnDeviceFramesWidget/CnDeviceFramesWidget.vue2.js.map +1 -0
  37. package/dist/esm/components/CnDeviceFramesWidget/CnDeviceFramesWidget.vue3.js +65 -0
  38. package/dist/esm/components/CnDeviceFramesWidget/CnDeviceFramesWidget.vue3.js.map +1 -0
  39. package/dist/esm/components/CnDeviceFramesWidget/index.js +30 -0
  40. package/dist/esm/components/CnDeviceFramesWidget/index.js.map +1 -0
  41. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue.js +1 -1
  42. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js +17 -1
  43. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js.map +1 -1
  44. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue3.js +30 -31
  45. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue3.js.map +1 -1
  46. package/dist/esm/components/CnHeaderSearchLabel/CnHeaderSearchLabel.vue.js +6 -0
  47. package/dist/esm/components/CnHeaderSearchLabel/CnHeaderSearchLabel.vue.js.map +1 -0
  48. package/dist/esm/components/CnHeaderSearchLabel/CnHeaderSearchLabel.vue2.js +90 -0
  49. package/dist/esm/components/CnHeaderSearchLabel/CnHeaderSearchLabel.vue2.js.map +1 -0
  50. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +141 -7
  51. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  52. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +5 -2
  53. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  54. package/dist/esm/components/CnPageHeader/CnHeaderTrail.vue.js +8 -0
  55. package/dist/esm/components/CnPageHeader/CnHeaderTrail.vue.js.map +1 -0
  56. package/dist/esm/components/CnPageHeader/CnHeaderTrail.vue2.js +114 -0
  57. package/dist/esm/components/CnPageHeader/CnHeaderTrail.vue2.js.map +1 -0
  58. package/dist/esm/components/CnPageHeader/CnHeaderTrail.vue3.js +45 -0
  59. package/dist/esm/components/CnPageHeader/CnHeaderTrail.vue3.js.map +1 -0
  60. package/dist/esm/components/CnPageHeader/CnPageHeader.vue2.js +38 -2
  61. package/dist/esm/components/CnPageHeader/CnPageHeader.vue2.js.map +1 -1
  62. package/dist/esm/components/CnPageHeader/CnPageHeader.vue3.js +12 -2
  63. package/dist/esm/components/CnPageHeader/CnPageHeader.vue3.js.map +1 -1
  64. package/dist/esm/components/CnPagination/CnPagination.vue2.js.map +1 -1
  65. package/dist/esm/components/CnPagination/CnPagination.vue3.js +56 -51
  66. package/dist/esm/components/CnPagination/CnPagination.vue3.js.map +1 -1
  67. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js +1 -1
  68. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js +51 -4
  69. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js.map +1 -1
  70. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js +20 -2
  71. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js.map +1 -1
  72. package/dist/esm/components/CnRegisterMapping/CnRegisterMapping.vue.js +1 -1
  73. package/dist/esm/components/CnRegisterMapping/CnRegisterMapping.vue2.js +230 -25
  74. package/dist/esm/components/CnRegisterMapping/CnRegisterMapping.vue2.js.map +1 -1
  75. package/dist/esm/components/CnRegisterMapping/CnRegisterMapping.vue3.js +447 -221
  76. package/dist/esm/components/CnRegisterMapping/CnRegisterMapping.vue3.js.map +1 -1
  77. package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue.js +1 -1
  78. package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue2.js +24 -0
  79. package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue2.js.map +1 -1
  80. package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue3.js +3 -1
  81. package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue3.js.map +1 -1
  82. package/dist/esm/components/CnTabs/CnTabs.vue.js +1 -1
  83. package/dist/esm/components/CnTabs/CnTabs.vue2.js +39 -2
  84. package/dist/esm/components/CnTabs/CnTabs.vue2.js.map +1 -1
  85. package/dist/esm/components/CnTabs/CnTabs.vue3.js.map +1 -1
  86. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue.js +1 -1
  87. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +85 -8
  88. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
  89. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js +37 -9
  90. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js.map +1 -1
  91. package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue.js +1 -1
  92. package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue2.js.map +1 -1
  93. package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue3.js +4 -3
  94. package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue3.js.map +1 -1
  95. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +1 -0
  96. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
  97. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue.js +1 -1
  98. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue2.js +20 -0
  99. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue2.js.map +1 -1
  100. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue3.js +31 -20
  101. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue3.js.map +1 -1
  102. package/dist/esm/composables/indexSources.js +9 -0
  103. package/dist/esm/composables/indexSources.js.map +1 -1
  104. package/dist/esm/index.js +1 -0
  105. package/dist/esm/index.js.map +1 -1
  106. package/dist/esm/l10n/en.json.js +18 -1
  107. package/dist/esm/l10n/en.json.js.map +1 -1
  108. package/dist/esm/l10n/nl.json.js +18 -1
  109. package/dist/esm/l10n/nl.json.js.map +1 -1
  110. package/dist/esm/library-style.js +1 -1
  111. package/dist/esm/nextcloud-vue.css +712 -330
  112. package/dist/esm/utils/dueText.js +49 -8
  113. package/dist/esm/utils/dueText.js.map +1 -1
  114. package/dist/esm/utils/libraryWidgetKeys.js +1 -0
  115. package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
  116. package/dist/esm/utils/validateManifestV2.compiled.js +3 -3
  117. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  118. package/dist/nextcloud-vue.cjs.js +8275 -6302
  119. package/dist/nextcloud-vue.cjs.js.map +2 -2
  120. package/dist/nextcloud-vue.css +712 -330
  121. package/l10n/en.json +18 -1
  122. package/l10n/nl.json +18 -1
  123. package/package.json +1 -1
  124. package/src/components/CnActionsMenu/CnActionsMenu.vue +3 -1
  125. package/src/components/CnAdminSettingsShell/CnAdminSettingsShell.vue +39 -1
  126. package/src/components/CnAppRoot/CnAppRoot.vue +20 -0
  127. package/src/components/CnBrandBar/CnBrandBar.vue +5 -4
  128. package/src/components/CnCountdownWidget/CnCountdownWidget.vue +222 -6
  129. package/src/components/CnDashboardPage/CnDashboardPage.vue +96 -2
  130. package/src/components/CnDataTable/CnDataTable.md +1 -0
  131. package/src/components/CnDataTable/CnDataTable.vue +39 -10
  132. package/src/components/CnDetailPage/CnDetailPage.vue +55 -15
  133. package/src/components/CnDeviceFramesWidget/CnDeviceFramesWidget.vue +360 -0
  134. package/src/components/CnDeviceFramesWidget/index.js +29 -0
  135. package/src/components/CnFactsWidget/CnFactsWidget.vue +46 -2
  136. package/src/components/CnHeaderSearchLabel/CnHeaderSearchLabel.vue +107 -0
  137. package/src/components/CnIndexPage/CnIndexPage.vue +144 -7
  138. package/src/components/CnPageHeader/CnHeaderTrail.vue +140 -0
  139. package/src/components/CnPageHeader/CnPageHeader.md +11 -0
  140. package/src/components/CnPageHeader/CnPageHeader.vue +42 -0
  141. package/src/components/CnPagination/CnPagination.vue +10 -2
  142. package/src/components/CnRecordListWidget/CnRecordListWidget.vue +84 -4
  143. package/src/components/CnRegisterMapping/CnRegisterMapping.md +10 -0
  144. package/src/components/CnRegisterMapping/CnRegisterMapping.vue +511 -28
  145. package/src/components/CnSettingsPage/CnSettingsPage.vue +26 -0
  146. package/src/components/CnTabs/CnTabs.vue +39 -2
  147. package/src/components/CnTabsWidget/CnTabsWidget.vue +106 -13
  148. package/src/components/CnVersionInfoCard/CnVersionInfoCard.vue +4 -3
  149. package/src/components/CnWidgetGrid/registerDashboardWidgets.js +1 -0
  150. package/src/components/CnWidgetWrapper/CnWidgetWrapper.md +8 -0
  151. package/src/components/CnWidgetWrapper/CnWidgetWrapper.vue +31 -2
  152. package/src/components/index.js +1 -0
  153. package/src/composables/indexSources.js +9 -0
  154. package/src/css/dialog.css +14 -0
  155. package/src/css/look-board-index.css +27 -1
  156. package/src/css/look-board.css +27 -0
  157. package/src/css/page-header.css +16 -0
  158. package/src/index.js +1 -0
  159. package/src/schemas/app-manifest-v2.schema.json +27 -15
  160. package/src/utils/dueText.js +49 -8
  161. package/src/utils/libraryWidgetKeys.js +1 -0
  162. package/src/utils/validateManifestV2.compiled.js +3 -3
@@ -1,11 +1,15 @@
1
- import { translate } from '@nextcloud/l10n';
1
+ import { translate, translatePlural } from '@nextcloud/l10n';
2
2
  import { NcButton, NcLoadingIcon, NcNoteCard, NcSelect } from '@nextcloud/vue';
3
+ import CheckCircle from 'vue-material-design-icons/CheckCircle.vue';
3
4
  import ChevronDown from 'vue-material-design-icons/ChevronDown.vue';
5
+ import ChevronRight from 'vue-material-design-icons/ChevronRight.vue';
4
6
  import ChevronUp from 'vue-material-design-icons/ChevronUp.vue';
5
7
  import ContentSave from 'vue-material-design-icons/ContentSave.vue';
6
8
  import Refresh from 'vue-material-design-icons/Refresh.vue';
9
+ import { normalizeLook } from '../../composables/useLook.js';
7
10
  import { prefixUrl, buildHeaders } from '../../utils/headers.js';
8
11
  import __sfc_main from '../CnSettingsSection/CnSettingsSection.vue.js';
12
+ import __sfc_main$1 from '../CnStatusBadge/CnStatusBadge.vue.js';
9
13
 
10
14
  let mappingCount = 0;
11
15
 
@@ -17,6 +21,13 @@ let mappingCount = 0;
17
21
  * Supports multiple register groups (stacked sections) with expandable
18
22
  * type rows for manual schema override.
19
23
  *
24
+ * Only the registers the configuration maps have their schemas fetched; the
25
+ * register select lists every register without its schemas.
26
+ *
27
+ * In the board look one group is open as a type/schema table under a status
28
+ * chip, the other groups are rows with their type count and status, and the
29
+ * save button closes the section.
30
+ *
20
31
  * Single register (Pipelinq)
21
32
  * ```vue
22
33
  * <CnRegisterMapping
@@ -50,16 +61,24 @@ var script = {
50
61
 
51
62
  components: {
52
63
  CnSettingsSection: __sfc_main,
64
+ CnStatusBadge: __sfc_main$1,
53
65
  NcButton,
54
66
  NcLoadingIcon,
55
67
  NcNoteCard,
56
68
  NcSelect,
57
69
  ContentSave,
58
70
  Refresh,
71
+ CheckCircle,
59
72
  ChevronDown,
73
+ ChevronRight,
60
74
  ChevronUp,
61
75
  },
62
76
 
77
+ inject: {
78
+ /** The look CnAppRoot or CnAdminSettingsShell provides. */
79
+ cnLook: { default: 'nextcloud' },
80
+ },
81
+
63
82
  props: {
64
83
  /** Section title */
65
84
  name: {
@@ -147,6 +166,28 @@ var script = {
147
166
  default: null,
148
167
  },
149
168
 
169
+ /**
170
+ * The look the mapping is drawn in: `board` or `nextcloud`. Empty
171
+ * follows the provided `cnLook`.
172
+ *
173
+ * @spec openspec/changes/register-mapping-board-look/specs/register-mapping/spec.md#requirement-the-board-look-draws-one-open-group-and-compact-rows
174
+ */
175
+ look: {
176
+ type: String,
177
+ default: '',
178
+ },
179
+
180
+ /**
181
+ * Board look: how many types the open group lists before a "show all"
182
+ * line. 0 lists every type.
183
+ *
184
+ * @spec openspec/changes/register-mapping-board-look/specs/register-mapping/spec.md#requirement-the-board-look-draws-one-open-group-and-compact-rows
185
+ */
186
+ boardRowLimit: {
187
+ type: Number,
188
+ default: 4,
189
+ },
190
+
150
191
  /** Auto-match schema titles to type slugs on register change */
151
192
  autoMatch: {
152
193
  type: Boolean,
@@ -184,6 +225,12 @@ var script = {
184
225
  expandedRows: {},
185
226
  // The groups opened by the reader, by index.
186
227
  openGroups: {},
228
+ // Board look: the group drawn open, and whether it lists every type.
229
+ activeGroupIdx: 0,
230
+ // Schema requests by register id, so a register is fetched once.
231
+ schemaRequests: {},
232
+ registersLoaded: false,
233
+ showAllTypes: false,
187
234
  uid: ++mappingCount,
188
235
  }
189
236
  },
@@ -207,6 +254,79 @@ var script = {
207
254
  return this.collapseGroups === null ? this.groups.length > 1 : this.collapseGroups
208
255
  },
209
256
 
257
+ /**
258
+ * Whether the board look applies.
259
+ *
260
+ * @return {boolean}
261
+ */
262
+ isBoardLook() {
263
+ return normalizeLook(this.look || this.cnLook) === 'board'
264
+ },
265
+
266
+ /**
267
+ * The group the board look draws open.
268
+ *
269
+ * @return {object}
270
+ */
271
+ activeGroup() {
272
+ return this.groups[this.activeGroupIdx] || this.groups[0]
273
+ },
274
+
275
+ /**
276
+ * The open group's types the board table lists.
277
+ *
278
+ * @return {Array<object>}
279
+ */
280
+ boardVisibleTypes() {
281
+ const types = this.activeGroup.types;
282
+ if (this.showAllTypes || this.boardRowLimit <= 0) {
283
+ return types
284
+ }
285
+ return types.slice(0, this.boardRowLimit)
286
+ },
287
+
288
+ /**
289
+ * The open group's types below the row limit.
290
+ *
291
+ * @return {Array<object>}
292
+ */
293
+ boardHiddenTypes() {
294
+ return this.activeGroup.types.slice(this.boardVisibleTypes.length)
295
+ },
296
+
297
+ /**
298
+ * The line under the board table that counts the types not listed.
299
+ *
300
+ * @return {string}
301
+ */
302
+ boardHiddenSummary() {
303
+ const count = this.boardHiddenTypes.length;
304
+ const allSet = this.boardHiddenTypes.every((type) => !!this.schemaValue(this.activeGroupIdx, type));
305
+ return allSet
306
+ ? translatePlural('nextcloud-vue', 'And %n more type in this group, set up.', 'And %n more types in this group, all set up.', count)
307
+ : translatePlural('nextcloud-vue', 'And %n more type in this group.', 'And %n more types in this group.', count)
308
+ },
309
+
310
+ /**
311
+ * The groups the board look draws as compact rows, with their index.
312
+ *
313
+ * @return {Array<{group: object, idx: number}>}
314
+ */
315
+ boardOtherGroups() {
316
+ return this.groups
317
+ .map((group, idx) => ({ group, idx }))
318
+ .filter((item) => item.idx !== this.activeGroupIdx)
319
+ },
320
+
321
+ /**
322
+ * Whether the section header draws buttons; the board look saves at the end.
323
+ *
324
+ * @return {boolean}
325
+ */
326
+ hasHeaderActions() {
327
+ return (this.showSaveButton && !this.isBoardLook) || this.showReimportButton || !!this.$slots.actions
328
+ },
329
+
210
330
  /** Whether local config differs from prop */
211
331
  hasChanges() {
212
332
  return JSON.stringify(this.localConfig) !== JSON.stringify(this.configuration)
@@ -217,11 +337,20 @@ var script = {
217
337
  configuration: {
218
338
  handler(newVal) {
219
339
  this.localConfig = { ...newVal };
340
+ if (this.registersLoaded) {
341
+ this.mappedRegisterIds().forEach((id) => this.loadSchemasForRegister(id));
342
+ }
220
343
  },
221
344
 
222
345
  immediate: true,
223
346
  deep: true,
224
347
  },
348
+
349
+ groups() {
350
+ if (this.activeGroupIdx >= this.groups.length) {
351
+ this.activeGroupIdx = 0;
352
+ }
353
+ },
225
354
  },
226
355
 
227
356
  async mounted() {
@@ -230,6 +359,65 @@ var script = {
230
359
 
231
360
  methods: {
232
361
  t: translate,
362
+ n: translatePlural,
363
+
364
+ /**
365
+ * The status chip text of a group: every type set up, none, or how many.
366
+ *
367
+ * @param {number} groupIdx Group index
368
+ * @param {boolean} open Whether the group is the open one, which says "All types set up"
369
+ * @return {string}
370
+ * @spec openspec/changes/register-mapping-board-look/specs/register-mapping/spec.md#requirement-the-board-look-draws-one-open-group-and-compact-rows
371
+ */
372
+ groupStatusLabel(groupIdx, open) {
373
+ const configured = this.configuredCount(groupIdx);
374
+ const total = this.groups[groupIdx].types.length;
375
+ if (configured === total) {
376
+ return open ? translate('nextcloud-vue', 'All types set up') : translate('nextcloud-vue', 'Set up')
377
+ }
378
+ if (configured === 0) {
379
+ return translate('nextcloud-vue', 'Not set')
380
+ }
381
+ return translate('nextcloud-vue', '{configured} of {total} set up', { configured, total })
382
+ },
383
+
384
+ /**
385
+ * The status chip variant of a group.
386
+ *
387
+ * @param {number} groupIdx Group index
388
+ * @return {'success'|'warning'|'default'}
389
+ */
390
+ groupStatusVariant(groupIdx) {
391
+ const configured = this.configuredCount(groupIdx);
392
+ if (configured === this.groups[groupIdx].types.length) {
393
+ return 'success'
394
+ }
395
+ return configured === 0 ? 'default' : 'warning'
396
+ },
397
+
398
+ /**
399
+ * Board look: draw another group open.
400
+ *
401
+ * @param {number} groupIdx Group index
402
+ * @return {void}
403
+ * @spec openspec/changes/register-mapping-board-look/specs/register-mapping/spec.md#requirement-the-board-look-draws-one-open-group-and-compact-rows
404
+ */
405
+ openBoardGroup(groupIdx) {
406
+ this.activeGroupIdx = groupIdx;
407
+ this.showAllTypes = false;
408
+ },
409
+
410
+ /**
411
+ * The register ids the configuration maps, one per distinct value.
412
+ *
413
+ * @return {string[]}
414
+ */
415
+ mappedRegisterIds() {
416
+ const ids = this.groups
417
+ .map((group, idx) => String(this.localConfig[this.registerConfigKey(idx)] || ''))
418
+ .filter(Boolean);
419
+ return [...new Set(ids)]
420
+ },
233
421
 
234
422
  /**
235
423
  * Whether a group's body shows.
@@ -487,17 +675,24 @@ var script = {
487
675
  },
488
676
 
489
677
  /**
490
- * Fetch all registers from OpenRegister API.
678
+ * Fetch the registers for the select, without their schemas, and the
679
+ * schemas of the registers the configuration maps. Expanding the schemas
680
+ * of every register costs megabytes on a busy instance.
681
+ *
682
+ * @spec openspec/changes/register-mapping-board-look/specs/register-mapping/spec.md#requirement-only-mapped-registers-have-their-schemas-fetched
491
683
  */
492
684
  async loadRegisters() {
493
685
  this.registersLoading = true;
494
686
  this.registersError = null;
495
687
 
496
688
  try {
497
- const response = await fetch(prefixUrl('/apps/openregister/api/registers?_extend[]=schemas'), {
498
- method: 'GET',
499
- headers: buildHeaders(),
500
- });
689
+ const [response] = await Promise.all([
690
+ fetch(prefixUrl('/apps/openregister/api/registers'), {
691
+ method: 'GET',
692
+ headers: buildHeaders(),
693
+ }),
694
+ ...this.mappedRegisterIds().map((id) => this.loadSchemasForRegister(id)),
695
+ ]);
501
696
 
502
697
  if (!response.ok) {
503
698
  this.registersError = translate('nextcloud-vue', 'The registers could not be loaded: {reason}', { reason: response.statusText || response.status });
@@ -507,19 +702,7 @@ var script = {
507
702
  const data = await response.json();
508
703
  const results = data.results || data;
509
704
  this.registers = Array.isArray(results) ? results : [];
510
-
511
- // Cache expanded schemas
512
- for (const reg of this.registers) {
513
- if (Array.isArray(reg.schemas) && reg.schemas.length > 0) {
514
- const schemas = reg.schemas.filter((s) => s && typeof s === 'object' && s.id);
515
- if (schemas.length > 0) {
516
- this.schemasByRegister = {
517
- ...this.schemasByRegister,
518
- [String(reg.id)]: schemas,
519
- };
520
- }
521
- }
522
- }
705
+ this.registersLoaded = true;
523
706
  } catch (error) {
524
707
  this.registersError = error.message || translate('nextcloud-vue', 'The registers could not be loaded: {reason}', { reason: translate('nextcloud-vue', 'no connection') });
525
708
  } finally {
@@ -528,32 +711,54 @@ var script = {
528
711
  },
529
712
 
530
713
  /**
531
- * Fetch schemas for a specific register.
714
+ * Fetch the schemas of one register, through `registers/{id}/schemas`,
715
+ * or the register with its schemas expanded where that route is missing.
532
716
  *
533
717
  * @param {string} registerId Register ID
718
+ * @spec openspec/changes/register-mapping-board-look/specs/register-mapping/spec.md#requirement-only-mapped-registers-have-their-schemas-fetched
534
719
  */
535
720
  async loadSchemasForRegister(registerId) {
536
721
  const id = String(registerId);
537
722
 
538
- // Return cached
539
723
  if (this.schemasByRegister[id]?.length > 0) {
540
724
  return
541
725
  }
726
+ if (!this.schemaRequests[id]) {
727
+ this.schemaRequests[id] = this.fetchSchemas(id).finally(() => {
728
+ delete this.schemaRequests[id];
729
+ });
730
+ }
731
+ await this.schemaRequests[id];
732
+ },
542
733
 
734
+ /**
735
+ * One schema request for a register; fills `schemasByRegister`.
736
+ *
737
+ * @param {string} id Register ID
738
+ * @return {Promise<void>}
739
+ */
740
+ async fetchSchemas(id) {
543
741
  try {
544
- const response = await fetch(
545
- prefixUrl(`/apps/openregister/api/registers/${encodeURIComponent(id)}?_extend[]=schemas`),
742
+ let response = await fetch(
743
+ prefixUrl(`/apps/openregister/api/registers/${encodeURIComponent(id)}/schemas`),
546
744
  { method: 'GET', headers: buildHeaders() },
547
745
  );
746
+ if (response.status === 404) {
747
+ response = await fetch(
748
+ prefixUrl(`/apps/openregister/api/registers/${encodeURIComponent(id)}?_extend[]=schemas`),
749
+ { method: 'GET', headers: buildHeaders() },
750
+ );
751
+ }
548
752
  if (!response.ok) {
549
753
  return
550
754
  }
551
755
 
552
756
  const data = await response.json();
553
- const schemas = (data.schemas || []).filter((s) => s && typeof s === 'object' && s.id);
757
+ const list = data.results || data.schemas || [];
758
+ const schemas = (Array.isArray(list) ? list : []).filter((s) => s && typeof s === 'object' && s.id);
554
759
  this.schemasByRegister = { ...this.schemasByRegister, [id]: schemas };
555
760
  } catch {
556
- // Silently fail — register already selected, schemas just won't populate
761
+ // The register stays selected; its schema select stays empty.
557
762
  }
558
763
  },
559
764
  },
@@ -1 +1 @@
1
- {"version":3,"file":"CnRegisterMapping.vue2.js","sources":["../../../../src/components/CnRegisterMapping/CnRegisterMapping.vue"],"sourcesContent":["<template>\n\t<CnSettingsSection\n\t\t:name=\"name\"\n\t\t:description=\"description\"\n\t\t:docUrl=\"docUrl\"\n\t\t:loading=\"registersLoading\"\n\t\t:loadingMessage=\"t('nextcloud-vue', 'Loading registers…')\"\n\t\t:error=\"!!registersError\"\n\t\t:errorMessage=\"registersError || ''\"\n\t\t:onRetry=\"loadRegisters\">\n\t\t<!-- Action buttons -->\n\t\t<template #actions>\n\t\t\t<NcButton\n\t\t\t\tv-if=\"showSaveButton\"\n\t\t\t\tvariant=\"primary\"\n\t\t\t\t:disabled=\"saving || !hasChanges\"\n\t\t\t\t@click=\"handleSave\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<NcLoadingIcon v-if=\"saving\" :size=\"20\" />\n\t\t\t\t\t<ContentSave v-else :size=\"20\" />\n\t\t\t\t</template>\n\t\t\t\t{{ saving ? t('nextcloud-vue', 'Saving…') : saveButtonText }}\n\t\t\t</NcButton>\n\t\t\t<NcButton\n\t\t\t\tv-if=\"showReimportButton\"\n\t\t\t\tvariant=\"secondary\"\n\t\t\t\t:disabled=\"reimporting\"\n\t\t\t\t@click=\"$emit('reimport')\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<NcLoadingIcon v-if=\"reimporting\" :size=\"20\" />\n\t\t\t\t\t<Refresh v-else :size=\"20\" />\n\t\t\t\t</template>\n\t\t\t\t{{ reimporting ? t('nextcloud-vue', 'Importing…') : reimportButtonText }}\n\t\t\t</NcButton>\n\t\t\t<slot name=\"actions\" />\n\t\t</template>\n\n\t\t<!-- Group sections -->\n\t\t<div v-if=\"!registersLoading && !registersError\" class=\"cn-register-mapping\">\n\t\t\t<div\n\t\t\t\tv-for=\"(group, groupIdx) in groups\"\n\t\t\t\t:key=\"groupIdx\"\n\t\t\t\tclass=\"cn-register-mapping__group\"\n\t\t\t\t:class=\"{ 'cn-register-mapping__group--collapsed': !isGroupOpen(groupIdx) }\"\n\t\t\t\tdata-testid=\"cn-register-mapping-group\">\n\t\t\t\t<!-- Group header. With collapsible groups a heading holds the button\n\t\t\t\t that opens and closes the group (the WAI-ARIA accordion); the\n\t\t\t\t count stays visible while it is closed. -->\n\t\t\t\t<h4 v-if=\"groupsCollapsible\" class=\"cn-register-mapping__group-heading\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"cn-register-mapping__group-toggle\"\n\t\t\t\t\t\t:aria-expanded=\"String(isGroupOpen(groupIdx))\"\n\t\t\t\t\t\t:aria-controls=\"groupBodyId(groupIdx)\"\n\t\t\t\t\t\tdata-testid=\"cn-register-mapping-group-toggle\"\n\t\t\t\t\t\t@click=\"toggleGroup(groupIdx)\">\n\t\t\t\t\t\t<span class=\"cn-register-mapping__group-chevron\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t<ChevronUp v-if=\"isGroupOpen(groupIdx)\" :size=\"20\" />\n\t\t\t\t\t\t\t<ChevronDown v-else :size=\"20\" />\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<slot name=\"group-header\"\n\t\t\t\t\t\t\t:group=\"group\"\n\t\t\t\t\t\t\t:configuredCount=\"configuredCount(groupIdx)\"\n\t\t\t\t\t\t\t:totalCount=\"group.types.length\">\n\t\t\t\t\t\t\t<span class=\"cn-register-mapping__group-header\">\n\t\t\t\t\t\t\t\t<span class=\"cn-register-mapping__group-title\">{{ group.name }}</span>\n\t\t\t\t\t\t\t\t<span class=\"cn-register-mapping__group-status\" data-testid=\"cn-register-mapping-group-count\">\n\t\t\t\t\t\t\t\t\t{{ configuredCount(groupIdx) }}/{{ group.types.length }} {{ labels.partiallyConfigured }}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</slot>\n\t\t\t\t\t</button>\n\t\t\t\t</h4>\n\t\t\t\t<slot v-else\n\t\t\t\t\tname=\"group-header\"\n\t\t\t\t\t:group=\"group\"\n\t\t\t\t\t:configuredCount=\"configuredCount(groupIdx)\"\n\t\t\t\t\t:totalCount=\"group.types.length\">\n\t\t\t\t\t<div class=\"cn-register-mapping__group-header\">\n\t\t\t\t\t\t<h4 class=\"cn-register-mapping__group-title\">\n\t\t\t\t\t\t\t{{ group.name }}\n\t\t\t\t\t\t</h4>\n\t\t\t\t\t\t<span class=\"cn-register-mapping__group-status\">\n\t\t\t\t\t\t\t{{ configuredCount(groupIdx) }}/{{ group.types.length }} {{ labels.partiallyConfigured }}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</div>\n\t\t\t\t</slot>\n\n\t\t\t\t<div\n\t\t\t\t\tv-show=\"isGroupOpen(groupIdx)\"\n\t\t\t\t\t:id=\"groupBodyId(groupIdx)\"\n\t\t\t\t\tclass=\"cn-register-mapping__group-body\"\n\t\t\t\t\tdata-testid=\"cn-register-mapping-group-body\">\n\t\t\t\t\t<!-- Group description -->\n\t\t\t\t\t<p v-if=\"group.description\" class=\"cn-register-mapping__group-description\">\n\t\t\t\t\t\t{{ group.description }}\n\t\t\t\t\t</p>\n\n\t\t\t\t\t<!-- Register selector -->\n\t\t\t\t\t<div class=\"cn-register-mapping__register-select\">\n\t\t\t\t\t\t<NcSelect\n\t\t\t\t\t\t\t:modelValue=\"selectedRegister(groupIdx)\"\n\t\t\t\t\t\t\t:options=\"registerSelectOptions\"\n\t\t\t\t\t\t\t:placeholder=\"labels.selectRegister\"\n\t\t\t\t\t\t\t:inputLabel=\"labels.register\"\n\t\t\t\t\t\t\t:loading=\"registersLoading\"\n\t\t\t\t\t\t\tlabel=\"label\"\n\t\t\t\t\t\t\ttrackBy=\"value\"\n\t\t\t\t\t\t\t@update:modelValue=\"handleRegisterChange(groupIdx, $event)\" />\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<!-- Type list -->\n\t\t\t\t\t<div v-if=\"selectedRegister(groupIdx)\" class=\"cn-register-mapping__type-list\">\n\t\t\t\t\t\t<!-- Header row -->\n\t\t\t\t\t\t<div class=\"cn-register-mapping__type-list-header\">\n\t\t\t\t\t\t\t<span>{{ t('nextcloud-vue', 'Object type') }}</span>\n\t\t\t\t\t\t\t<span>{{ labels.schema }}</span>\n\t\t\t\t\t\t\t<span />\n\t\t\t\t\t\t\t<span />\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<!-- Type rows -->\n\t\t\t\t\t\t<template v-for=\"type in group.types\" :key=\"type.slug + '-row'\">\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclass=\"cn-register-mapping__type-row\"\n\t\t\t\t\t\t\t\t:class=\"{ 'cn-register-mapping__type-row--expanded': isExpanded(groupIdx, type.slug) }\"\n\t\t\t\t\t\t\t\t@click=\"toggleExpand(groupIdx, type.slug)\">\n\t\t\t\t\t\t\t\t<span class=\"cn-register-mapping__type-name\">{{ type.label }}</span>\n\t\t\t\t\t\t\t\t<span class=\"cn-register-mapping__type-schema\">\n\t\t\t\t\t\t\t\t\t{{ schemaLabel(groupIdx, type) || labels.notConfigured }}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<span class=\"cn-register-mapping__type-status\">\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"cn-register-mapping__status-dot\"\n\t\t\t\t\t\t\t\t\t\t:class=\"schemaValue(groupIdx, type)\n\t\t\t\t\t\t\t\t\t\t\t? 'cn-register-mapping__status-dot--configured'\n\t\t\t\t\t\t\t\t\t\t\t: 'cn-register-mapping__status-dot--unconfigured'\" />\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<span class=\"cn-register-mapping__type-chevron\">\n\t\t\t\t\t\t\t\t\t<ChevronUp v-if=\"isExpanded(groupIdx, type.slug)\" :size=\"20\" />\n\t\t\t\t\t\t\t\t\t<ChevronDown v-else :size=\"20\" />\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t<!-- Expanded detail -->\n\t\t\t\t\t\t\t<transition name=\"slide\">\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\tv-if=\"isExpanded(groupIdx, type.slug)\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-register-mapping__type-detail\">\n\t\t\t\t\t\t\t\t\t<p v-if=\"type.description\" class=\"cn-register-mapping__type-description\">\n\t\t\t\t\t\t\t\t\t\t{{ type.description }}\n\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t\t<NcSelect\n\t\t\t\t\t\t\t\t\t\t:modelValue=\"selectedSchema(groupIdx, type)\"\n\t\t\t\t\t\t\t\t\t\t:options=\"schemaSelectOptions(groupIdx)\"\n\t\t\t\t\t\t\t\t\t\t:placeholder=\"labels.selectSchema\"\n\t\t\t\t\t\t\t\t\t\t:inputLabel=\"labels.schema\"\n\t\t\t\t\t\t\t\t\t\tlabel=\"label\"\n\t\t\t\t\t\t\t\t\t\ttrackBy=\"value\"\n\t\t\t\t\t\t\t\t\t\t@update:modelValue=\"handleSchemaChange(groupIdx, type, $event)\" />\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</transition>\n\t\t\t\t\t\t</template>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<!-- No register selected -->\n\t\t\t\t\t<NcNoteCard v-else-if=\"!registersLoading\" type=\"info\">\n\t\t\t\t\t\t{{ labels.selectRegister }}\n\t\t\t\t\t</NcNoteCard>\n\n\t\t\t\t\t<!-- No schemas available -->\n\t\t\t\t\t<NcNoteCard\n\t\t\t\t\t\tv-if=\"selectedRegister(groupIdx) && schemaSelectOptions(groupIdx).length === 0 && !registersLoading\"\n\t\t\t\t\t\tvariant=\"warning\">\n\t\t\t\t\t\t{{ labels.noSchemas }}\n\t\t\t\t\t</NcNoteCard>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<!-- Footer -->\n\t\t<template v-if=\"$slots.footer\" #footer>\n\t\t\t<slot name=\"footer\" />\n\t\t</template>\n\t</CnSettingsSection>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcButton, NcLoadingIcon, NcNoteCard, NcSelect } from '@nextcloud/vue'\nimport ChevronDown from 'vue-material-design-icons/ChevronDown.vue'\nimport ChevronUp from 'vue-material-design-icons/ChevronUp.vue'\nimport ContentSave from 'vue-material-design-icons/ContentSave.vue'\nimport Refresh from 'vue-material-design-icons/Refresh.vue'\nimport { buildHeaders, prefixUrl } from '../../utils/headers.js'\nimport { CnSettingsSection } from '../CnSettingsSection/index.js'\n\nlet mappingCount = 0\n\n/**\n * CnRegisterMapping - OpenRegister register/schema configuration component.\n *\n * Displays and manages register-to-schema mappings for app object types.\n * Self-fetches available registers and schemas from the OpenRegister API.\n * Supports multiple register groups (stacked sections) with expandable\n * type rows for manual schema override.\n *\n * Single register (Pipelinq)\n * ```vue\n * <CnRegisterMapping\n * name=\"Register Configuration\"\n * :groups=\"[{\n * name: 'Core Objects',\n * types: [\n * { slug: 'client', label: 'Client' },\n * { slug: 'contact', label: 'Contact' },\n * ],\n * }]\"\n * :configuration=\"config\"\n * :show-reimport-button=\"true\"\n * @save=\"saveConfig\"\n * @reimport=\"reimport\" />\n * ```\n *\n * Multi-register (Stackiq)\n * ```vue\n * <CnRegisterMapping\n * :groups=\"[\n * { name: 'Voorzieningen', registerConfigKey: 'voorzieningen_register', types: [...] },\n * { name: 'AMEF', registerConfigKey: 'amef_register', types: [...] },\n * ]\"\n * :configuration=\"config\"\n * @save=\"saveConfig\" />\n * ```\n */\nexport default {\n\tname: 'CnRegisterMapping',\n\n\tcomponents: {\n\t\tCnSettingsSection,\n\t\tNcButton,\n\t\tNcLoadingIcon,\n\t\tNcNoteCard,\n\t\tNcSelect,\n\t\tContentSave,\n\t\tRefresh,\n\t\tChevronDown,\n\t\tChevronUp,\n\t},\n\n\tprops: {\n\t\t/** Section title */\n\t\tname: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Register configuration'),\n\t\t},\n\n\t\t/** Section description */\n\t\tdescription: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Configure OpenRegister schema mappings for your object types'),\n\t\t},\n\n\t\t/** Documentation URL */\n\t\tdocUrl: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Groups of object types that share a register.\n\t\t *\n\t\t * @type {Array<{ name: string, description: string, registerConfigKey: string, types: Array<{ slug: string, label: string, description: string, configKey: string }> }>}\n\t\t */\n\t\tgroups: {\n\t\t\ttype: Array,\n\t\t\trequired: true,\n\t\t\tvalidator: (groups) => groups.length > 0\n\t\t\t\t&& groups.every((g) => g.name && Array.isArray(g.types) && g.types.length > 0),\n\t\t},\n\n\t\t/** Current configuration values: { register: '5', client_schema: '28', ... } */\n\t\tconfiguration: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/** Show save button */\n\t\tshowSaveButton: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/** Whether save is in progress */\n\t\tsaving: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Show reimport button */\n\t\tshowReimportButton: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Whether reimport is in progress */\n\t\treimporting: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Save button text */\n\t\tsaveButtonText: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Save configuration'),\n\t\t},\n\n\t\t/** Reimport button text */\n\t\treimportButtonText: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Re-import configuration'),\n\t\t},\n\n\t\t/**\n\t\t * Draw each group as a header that opens and closes it, showing its\n\t\t * configured count while closed. The groups start closed. `null` (the\n\t\t * default) collapses them when there is more than one group, so a page\n\t\t * with several registers is not one long card.\n\t\t *\n\t\t * @type {boolean|null}\n\t\t * @spec openspec/changes/register-mapping-collapsed-groups/specs/register-mapping/spec.md#requirement-register-groups-start-closed-with-their-count\n\t\t */\n\t\tcollapseGroups: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** Auto-match schema titles to type slugs on register change */\n\t\tautoMatch: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/** UI labels (i18n) */\n\t\tlabels: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({\n\t\t\t\tregister: t('nextcloud-vue', 'Register'),\n\t\t\t\tschema: t('nextcloud-vue', 'Schema'),\n\t\t\t\tconfigured: t('nextcloud-vue', 'Configured'),\n\t\t\t\tnotConfigured: t('nextcloud-vue', 'Not configured'),\n\t\t\t\tnoSchemas: t('nextcloud-vue', 'No schemas available in this register'),\n\t\t\t\tselectRegister: t('nextcloud-vue', 'Select a register'),\n\t\t\t\tselectSchema: t('nextcloud-vue', 'Select a schema'),\n\t\t\t\tallConfigured: t('nextcloud-vue', 'All types configured'),\n\t\t\t\tpartiallyConfigured: t('nextcloud-vue', 'configured'),\n\t\t\t}),\n\t\t},\n\t},\n\n\temits: ['update:configuration', 'save', 'reimport'],\n\n\tdata() {\n\t\treturn {\n\t\t\t// Fetched data\n\t\t\tregisters: [],\n\t\t\tschemasByRegister: {},\n\t\t\tregistersLoading: false,\n\t\t\tregistersError: null,\n\t\t\t// Local state\n\t\t\tlocalConfig: {},\n\t\t\texpandedRows: {},\n\t\t\t// The groups opened by the reader, by index.\n\t\t\topenGroups: {},\n\t\t\tuid: ++mappingCount,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/** Register options for NcSelect */\n\t\tregisterSelectOptions() {\n\t\t\treturn this.registers.map((r) => ({\n\t\t\t\tlabel: r.title || r.slug || t('nextcloud-vue', 'Register {id}', { id: r.id }),\n\t\t\t\tvalue: String(r.id),\n\t\t\t}))\n\t\t},\n\n\t\t/**\n\t\t * Whether the groups open and close.\n\t\t *\n\t\t * @return {boolean}\n\t\t * @spec openspec/changes/register-mapping-collapsed-groups/specs/register-mapping/spec.md#requirement-register-groups-start-closed-with-their-count\n\t\t */\n\t\tgroupsCollapsible() {\n\t\t\treturn this.collapseGroups === null ? this.groups.length > 1 : this.collapseGroups\n\t\t},\n\n\t\t/** Whether local config differs from prop */\n\t\thasChanges() {\n\t\t\treturn JSON.stringify(this.localConfig) !== JSON.stringify(this.configuration)\n\t\t},\n\t},\n\n\twatch: {\n\t\tconfiguration: {\n\t\t\thandler(newVal) {\n\t\t\t\tthis.localConfig = { ...newVal }\n\t\t\t},\n\n\t\t\timmediate: true,\n\t\t\tdeep: true,\n\t\t},\n\t},\n\n\tasync mounted() {\n\t\tawait this.loadRegisters()\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\t/**\n\t\t * Whether a group's body shows.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @return {boolean}\n\t\t */\n\t\tisGroupOpen(groupIdx) {\n\t\t\treturn !this.groupsCollapsible || this.openGroups[groupIdx] === true\n\t\t},\n\n\t\t/**\n\t\t * Open a closed group, or close an open one.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @return {void}\n\t\t * @spec openspec/changes/register-mapping-collapsed-groups/specs/register-mapping/spec.md#requirement-register-groups-start-closed-with-their-count\n\t\t */\n\t\ttoggleGroup(groupIdx) {\n\t\t\tthis.openGroups = { ...this.openGroups, [groupIdx]: !this.isGroupOpen(groupIdx) }\n\t\t},\n\n\t\t/**\n\t\t * The id of a group's body, for the header's `aria-controls`.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @return {string}\n\t\t */\n\t\tgroupBodyId(groupIdx) {\n\t\t\treturn `cn-register-mapping-${this.uid}-group-${groupIdx}`\n\t\t},\n\n\t\t/**\n\t\t * Get the config key for a group's register.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @return {string} Config key\n\t\t */\n\t\tregisterConfigKey(groupIdx) {\n\t\t\tconst group = this.groups[groupIdx]\n\t\t\tif (group.registerConfigKey) {\n\t\t\t\treturn group.registerConfigKey\n\t\t\t}\n\t\t\tif (this.groups.length === 1) {\n\t\t\t\treturn 'register'\n\t\t\t}\n\t\t\treturn group.name.toLowerCase().replace(/[^a-z0-9]+/g, '_') + '_register'\n\t\t},\n\n\t\t/**\n\t\t * Get the config key for a type's schema.\n\t\t *\n\t\t * @param {object} type Type definition\n\t\t * @return {string} Config key\n\t\t */\n\t\tschemaConfigKey(type) {\n\t\t\treturn type.configKey || type.slug + '_schema'\n\t\t},\n\n\t\t/**\n\t\t * Get the selected register option for a group.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @return {object|null} NcSelect option\n\t\t */\n\t\tselectedRegister(groupIdx) {\n\t\t\tconst key = this.registerConfigKey(groupIdx)\n\t\t\tconst value = String(this.localConfig[key] || '')\n\t\t\tif (!value) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn this.registerSelectOptions.find((o) => o.value === value) || null\n\t\t},\n\n\t\t/**\n\t\t * Get the selected schema option for a type.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @param {object} type Type definition\n\t\t * @return {object|null} NcSelect option\n\t\t */\n\t\tselectedSchema(groupIdx, type) {\n\t\t\tconst key = this.schemaConfigKey(type)\n\t\t\tconst value = String(this.localConfig[key] || '')\n\t\t\tif (!value) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst options = this.schemaSelectOptions(groupIdx)\n\t\t\treturn options.find((o) => o.value === value) || null\n\t\t},\n\n\t\t/**\n\t\t * Get the schema value (ID) for a type.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @param {object} type Type definition\n\t\t * @return {string} Schema ID or empty string\n\t\t */\n\t\tschemaValue(groupIdx, type) {\n\t\t\tconst key = this.schemaConfigKey(type)\n\t\t\treturn this.localConfig[key] || ''\n\t\t},\n\n\t\t/**\n\t\t * Get the display label for a type's current schema.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @param {object} type Type definition\n\t\t * @return {string} Schema label or empty string\n\t\t */\n\t\tschemaLabel(groupIdx, type) {\n\t\t\tconst selected = this.selectedSchema(groupIdx, type)\n\t\t\tif (selected) {\n\t\t\t\treturn selected.label\n\t\t\t}\n\t\t\tconst value = this.schemaValue(groupIdx, type)\n\t\t\treturn value ? t('nextcloud-vue', 'Schema {id}', { id: value }) : ''\n\t\t},\n\n\t\t/**\n\t\t * Get schema options for a group's selected register.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @return {Array<{label: string, value: string}>} NcSelect options\n\t\t */\n\t\tschemaSelectOptions(groupIdx) {\n\t\t\tconst reg = this.selectedRegister(groupIdx)\n\t\t\tif (!reg) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\tconst schemas = this.schemasByRegister[reg.value] || []\n\t\t\treturn schemas.map((s) => ({\n\t\t\t\tlabel: s.title || s.slug || t('nextcloud-vue', 'Schema {id}', { id: s.id }),\n\t\t\t\tvalue: String(s.id),\n\t\t\t}))\n\t\t},\n\n\t\t/**\n\t\t * Count configured types in a group.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @return {number} Count\n\t\t */\n\t\tconfiguredCount(groupIdx) {\n\t\t\tconst group = this.groups[groupIdx]\n\t\t\treturn group.types.filter((type) => !!this.schemaValue(groupIdx, type)).length\n\t\t},\n\n\t\t/**\n\t\t * Check if a type row is expanded.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @param {string} slug Type slug\n\t\t * @return {boolean}\n\t\t */\n\t\tisExpanded(groupIdx, slug) {\n\t\t\treturn !!this.expandedRows[groupIdx + '-' + slug]\n\t\t},\n\n\t\t/**\n\t\t * Toggle a type row expansion.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @param {string} slug Type slug\n\t\t */\n\t\ttoggleExpand(groupIdx, slug) {\n\t\t\tconst key = groupIdx + '-' + slug\n\t\t\tthis.expandedRows = {\n\t\t\t\t...this.expandedRows,\n\t\t\t\t[key]: !this.expandedRows[key],\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Handle register selection change for a group.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @param {object|null} option NcSelect option\n\t\t */\n\t\tasync handleRegisterChange(groupIdx, option) {\n\t\t\tconst key = this.registerConfigKey(groupIdx)\n\t\t\tconst value = option?.value || ''\n\n\t\t\tthis.localConfig = { ...this.localConfig, [key]: value }\n\n\t\t\t// Clear schema selections for this group\n\t\t\tconst group = this.groups[groupIdx]\n\t\t\tfor (const type of group.types) {\n\t\t\t\tconst schemaKey = this.schemaConfigKey(type)\n\t\t\t\tthis.localConfig = { ...this.localConfig, [schemaKey]: '' }\n\t\t\t}\n\n\t\t\t// Fetch schemas for the new register\n\t\t\tif (value) {\n\t\t\t\tawait this.loadSchemasForRegister(value)\n\n\t\t\t\t// Auto-match schemas\n\t\t\t\tif (this.autoMatch) {\n\t\t\t\t\tthis.autoMatchSchemas(groupIdx)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.$emit('update:configuration', { ...this.localConfig })\n\t\t},\n\n\t\t/**\n\t\t * Handle schema selection change for a type.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @param {object} type Type definition\n\t\t * @param {object|null} option NcSelect option\n\t\t */\n\t\thandleSchemaChange(groupIdx, type, option) {\n\t\t\tconst key = this.schemaConfigKey(type)\n\t\t\tconst value = option?.value || ''\n\n\t\t\tthis.localConfig = { ...this.localConfig, [key]: value }\n\t\t\tthis.$emit('update:configuration', { ...this.localConfig })\n\t\t},\n\n\t\t/**\n\t\t * Auto-match schema titles to type slugs/labels (case-insensitive).\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t */\n\t\tautoMatchSchemas(groupIdx) {\n\t\t\tconst group = this.groups[groupIdx]\n\t\t\tconst options = this.schemaSelectOptions(groupIdx)\n\n\t\t\tfor (const type of group.types) {\n\t\t\t\tconst schemaKey = this.schemaConfigKey(type)\n\t\t\t\t// Skip if already has a value\n\t\t\t\tif (this.localConfig[schemaKey]) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tconst slug = type.slug.toLowerCase()\n\t\t\t\tconst label = type.label.toLowerCase()\n\n\t\t\t\tconst match = options.find((o) => {\n\t\t\t\t\tconst optLabel = o.label.toLowerCase()\n\t\t\t\t\treturn optLabel === slug || optLabel === label\n\t\t\t\t\t\t|| optLabel.includes(slug) || slug.includes(optLabel)\n\t\t\t\t})\n\n\t\t\t\tif (match) {\n\t\t\t\t\tthis.localConfig = { ...this.localConfig, [schemaKey]: match.value }\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/** Emit save event with current config */\n\t\thandleSave() {\n\t\t\tthis.$emit('save', { ...this.localConfig })\n\t\t},\n\n\t\t/**\n\t\t * Fetch all registers from OpenRegister API.\n\t\t */\n\t\tasync loadRegisters() {\n\t\t\tthis.registersLoading = true\n\t\t\tthis.registersError = null\n\n\t\t\ttry {\n\t\t\t\tconst response = await fetch(prefixUrl('/apps/openregister/api/registers?_extend[]=schemas'), {\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t\theaders: buildHeaders(),\n\t\t\t\t})\n\n\t\t\t\tif (!response.ok) {\n\t\t\t\t\tthis.registersError = t('nextcloud-vue', 'The registers could not be loaded: {reason}', { reason: response.statusText || response.status })\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst data = await response.json()\n\t\t\t\tconst results = data.results || data\n\t\t\t\tthis.registers = Array.isArray(results) ? results : []\n\n\t\t\t\t// Cache expanded schemas\n\t\t\t\tfor (const reg of this.registers) {\n\t\t\t\t\tif (Array.isArray(reg.schemas) && reg.schemas.length > 0) {\n\t\t\t\t\t\tconst schemas = reg.schemas.filter((s) => s && typeof s === 'object' && s.id)\n\t\t\t\t\t\tif (schemas.length > 0) {\n\t\t\t\t\t\t\tthis.schemasByRegister = {\n\t\t\t\t\t\t\t\t...this.schemasByRegister,\n\t\t\t\t\t\t\t\t[String(reg.id)]: schemas,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tthis.registersError = error.message || t('nextcloud-vue', 'The registers could not be loaded: {reason}', { reason: t('nextcloud-vue', 'no connection') })\n\t\t\t} finally {\n\t\t\t\tthis.registersLoading = false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Fetch schemas for a specific register.\n\t\t *\n\t\t * @param {string} registerId Register ID\n\t\t */\n\t\tasync loadSchemasForRegister(registerId) {\n\t\t\tconst id = String(registerId)\n\n\t\t\t// Return cached\n\t\t\tif (this.schemasByRegister[id]?.length > 0) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst response = await fetch(\n\t\t\t\t\tprefixUrl(`/apps/openregister/api/registers/${encodeURIComponent(id)}?_extend[]=schemas`),\n\t\t\t\t\t{ method: 'GET', headers: buildHeaders() },\n\t\t\t\t)\n\t\t\t\tif (!response.ok) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst data = await response.json()\n\t\t\t\tconst schemas = (data.schemas || []).filter((s) => s && typeof s === 'object' && s.id)\n\t\t\t\tthis.schemasByRegister = { ...this.schemasByRegister, [id]: schemas }\n\t\t\t} catch {\n\t\t\t\t// Silently fail — register already selected, schemas just won't populate\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-register-mapping__group {\n\tmargin-bottom: 24px;\n\tborder: 1px solid var(--color-border);\n\tborder-radius: var(--border-radius-large);\n\tpadding: 20px;\n\tbackground: var(--color-background-hover);\n}\n\n.cn-register-mapping__group:last-child {\n\tmargin-bottom: 0;\n}\n\n.cn-register-mapping__group-header {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tmargin-bottom: 12px;\n}\n\n.cn-register-mapping__group-heading {\n\tmargin: 0 0 12px;\n\tfont: inherit;\n}\n\n.cn-register-mapping__group--collapsed .cn-register-mapping__group-heading {\n\tmargin-bottom: 0;\n}\n\n.cn-register-mapping__group-toggle {\n\tbox-sizing: border-box;\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\twidth: 100%;\n\tmin-height: 44px;\n\tmargin: 0;\n\tpadding: 0;\n\tborder: 0;\n\tbackground: transparent;\n\tcolor: inherit;\n\tfont: inherit;\n\ttext-align: start;\n\tcursor: pointer;\n}\n\n.cn-register-mapping__group-toggle:focus-visible {\n\toutline: 2px solid var(--color-primary-element);\n\toutline-offset: 2px;\n\tborder-radius: var(--border-radius);\n}\n\n.cn-register-mapping__group-chevron {\n\tdisplay: inline-flex;\n\tflex: none;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-register-mapping__group-toggle .cn-register-mapping__group-header {\n\tflex: 1 1 auto;\n\tflex-wrap: wrap;\n\tgap: 4px 12px;\n\tmin-width: 0;\n\tmargin-bottom: 0;\n}\n\n.cn-register-mapping__group-title {\n\tfont-size: 16px;\n\tfont-weight: 600;\n\tmargin: 0;\n\tcolor: var(--color-main-text);\n}\n\n.cn-register-mapping__group-status {\n\tfont-size: 13px;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-register-mapping__group-description {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 13px;\n\tmargin: 0 0 12px 0;\n}\n\n.cn-register-mapping__register-select {\n\tmargin-bottom: 16px;\n\tmax-width: 400px;\n}\n\n.cn-register-mapping__type-list {\n\tborder: 1px solid var(--color-border);\n\tborder-radius: var(--border-radius);\n\toverflow: hidden;\n\tbackground: var(--color-main-background);\n}\n\n.cn-register-mapping__type-list-header {\n\tdisplay: grid;\n\tgrid-template-columns: 1fr 1fr 40px 32px;\n\talign-items: center;\n\tpadding: 8px 16px;\n\tfont-size: 12px;\n\tfont-weight: 600;\n\tcolor: var(--color-text-maxcontrast);\n\ttext-transform: uppercase;\n\tletter-spacing: 0.5px;\n\tborder-bottom: 1px solid var(--color-border);\n\tbackground: var(--color-background-hover);\n}\n\n.cn-register-mapping__type-row {\n\tdisplay: grid;\n\tgrid-template-columns: 1fr 1fr 40px 32px;\n\talign-items: center;\n\tpadding: 10px 16px;\n\tborder-bottom: 1px solid var(--color-border);\n\tcursor: pointer;\n\ttransition: background-color 0.15s ease;\n}\n\n.cn-register-mapping__type-row:hover {\n\tbackground: var(--color-background-hover);\n}\n\n.cn-register-mapping__type-row--expanded {\n\tbackground: var(--color-background-hover);\n}\n\n.cn-register-mapping__type-name {\n\tfont-weight: 500;\n\tcolor: var(--color-main-text);\n}\n\n.cn-register-mapping__type-schema {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 13px;\n}\n\n.cn-register-mapping__type-status {\n\tdisplay: flex;\n\tjustify-content: center;\n}\n\n.cn-register-mapping__type-chevron {\n\tdisplay: flex;\n\tjustify-content: center;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-register-mapping__status-dot {\n\tdisplay: inline-block;\n\twidth: 10px;\n\theight: 10px;\n\tborder-radius: 50%;\n}\n\n.cn-register-mapping__status-dot--configured {\n\tbackground-color: var(--color-success);\n}\n\n.cn-register-mapping__status-dot--unconfigured {\n\tbackground-color: var(--color-warning);\n}\n\n.cn-register-mapping__type-detail {\n\tpadding: 12px 16px 16px;\n\tborder-bottom: 1px solid var(--color-border);\n\tbackground: var(--color-main-background);\n}\n\n.cn-register-mapping__type-description {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 13px;\n\tmargin: 0 0 8px 0;\n}\n\n/* Slide transition */\n.slide-enter-active,\n.slide-leave-active {\n\ttransition: all 0.2s ease;\n\tmax-height: 200px;\n\toverflow: hidden;\n}\n\n.slide-enter,\n.slide-leave-to {\n\tmax-height: 0;\n\tpadding-top: 0;\n\tpadding-bottom: 0;\n\topacity: 0;\n}\n\n/* Last row in list should not have bottom border */\n.cn-register-mapping__type-list > :last-child {\n\tborder-bottom: none;\n}\n\n@media (max-width: 768px) {\n\t.cn-register-mapping__type-list-header {\n\t\tdisplay: none;\n\t}\n\n\t.cn-register-mapping__type-row {\n\t\tgrid-template-columns: 1fr auto 32px;\n\t}\n\n\t.cn-register-mapping__type-schema {\n\t\tdisplay: none;\n\t}\n\n\t.cn-register-mapping__register-select {\n\t\tmax-width: none;\n\t}\n}\n</style>\n"],"names":["CnSettingsSection","t"],"mappings":"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"}
1
+ {"version":3,"file":"CnRegisterMapping.vue2.js","sources":["../../../../src/components/CnRegisterMapping/CnRegisterMapping.vue"],"sourcesContent":["<template>\n\t<CnSettingsSection\n\t\t:name=\"name\"\n\t\t:description=\"description\"\n\t\t:docUrl=\"docUrl\"\n\t\t:loading=\"registersLoading\"\n\t\t:loadingMessage=\"t('nextcloud-vue', 'Loading registers…')\"\n\t\t:error=\"!!registersError\"\n\t\t:errorMessage=\"registersError || ''\"\n\t\t:onRetry=\"loadRegisters\">\n\t\t<!-- Action buttons -->\n\t\t<template v-if=\"hasHeaderActions\" #actions>\n\t\t\t<NcButton\n\t\t\t\tv-if=\"showSaveButton && !isBoardLook\"\n\t\t\t\tvariant=\"primary\"\n\t\t\t\t:disabled=\"saving || !hasChanges\"\n\t\t\t\t@click=\"handleSave\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<NcLoadingIcon v-if=\"saving\" :size=\"20\" />\n\t\t\t\t\t<ContentSave v-else :size=\"20\" />\n\t\t\t\t</template>\n\t\t\t\t{{ saving ? t('nextcloud-vue', 'Saving…') : saveButtonText }}\n\t\t\t</NcButton>\n\t\t\t<NcButton\n\t\t\t\tv-if=\"showReimportButton\"\n\t\t\t\tvariant=\"secondary\"\n\t\t\t\t:disabled=\"reimporting\"\n\t\t\t\t@click=\"$emit('reimport')\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<NcLoadingIcon v-if=\"reimporting\" :size=\"20\" />\n\t\t\t\t\t<Refresh v-else :size=\"20\" />\n\t\t\t\t</template>\n\t\t\t\t{{ reimporting ? t('nextcloud-vue', 'Importing…') : reimportButtonText }}\n\t\t\t</NcButton>\n\t\t\t<slot name=\"actions\" />\n\t\t</template>\n\n\t\t<!-- Group sections -->\n\t\t<div\n\t\t\tv-if=\"isBoardLook && !registersLoading && !registersError\"\n\t\t\tclass=\"cn-register-mapping cn-register-mapping--board\"\n\t\t\tdata-testid=\"cn-register-mapping-board\">\n\t\t\t<div class=\"cn-register-mapping__board-group\" data-testid=\"cn-register-mapping-board-group\">\n\t\t\t\t<div class=\"cn-register-mapping__board-head\">\n\t\t\t\t\t<h3 class=\"cn-register-mapping__board-title\">\n\t\t\t\t\t\t{{ activeGroup.name }}\n\t\t\t\t\t</h3>\n\t\t\t\t\t<CnStatusBadge\n\t\t\t\t\t\t:label=\"groupStatusLabel(activeGroupIdx, true)\"\n\t\t\t\t\t\t:variant=\"groupStatusVariant(activeGroupIdx)\"\n\t\t\t\t\t\tdata-testid=\"cn-register-mapping-board-status\" />\n\t\t\t\t</div>\n\t\t\t\t<p v-if=\"activeGroup.description\" class=\"cn-register-mapping__group-description\">\n\t\t\t\t\t{{ activeGroup.description }}\n\t\t\t\t</p>\n\t\t\t\t<div class=\"cn-register-mapping__register-select cn-register-mapping__board-select\">\n\t\t\t\t\t<NcSelect\n\t\t\t\t\t\t:modelValue=\"selectedRegister(activeGroupIdx)\"\n\t\t\t\t\t\t:options=\"registerSelectOptions\"\n\t\t\t\t\t\t:placeholder=\"labels.selectRegister\"\n\t\t\t\t\t\t:inputLabel=\"labels.register\"\n\t\t\t\t\t\tlabel=\"label\"\n\t\t\t\t\t\ttrackBy=\"value\"\n\t\t\t\t\t\t@update:modelValue=\"handleRegisterChange(activeGroupIdx, $event)\" />\n\t\t\t\t</div>\n\t\t\t\t<table v-if=\"selectedRegister(activeGroupIdx)\" class=\"cn-register-mapping__board-table\">\n\t\t\t\t\t<thead>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<th scope=\"col\">\n\t\t\t\t\t\t\t\t{{ t('nextcloud-vue', 'Object type') }}\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t<th scope=\"col\">\n\t\t\t\t\t\t\t\t{{ labels.schema }}\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</thead>\n\t\t\t\t\t<tbody>\n\t\t\t\t\t\t<template v-for=\"type in boardVisibleTypes\" :key=\"type.slug + '-board'\">\n\t\t\t\t\t\t\t<tr data-testid=\"cn-register-mapping-board-row\">\n\t\t\t\t\t\t\t\t<td>{{ type.label }}</td>\n\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclass=\"cn-register-mapping__board-schema\"\n\t\t\t\t\t\t\t\t\t\t:aria-expanded=\"String(isExpanded(activeGroupIdx, type.slug))\"\n\t\t\t\t\t\t\t\t\t\t:aria-label=\"t('nextcloud-vue', 'Change the schema for {type}', { type: type.label })\"\n\t\t\t\t\t\t\t\t\t\t@click=\"toggleExpand(activeGroupIdx, type.slug)\">\n\t\t\t\t\t\t\t\t\t\t<CheckCircle\n\t\t\t\t\t\t\t\t\t\t\tv-if=\"schemaValue(activeGroupIdx, type)\"\n\t\t\t\t\t\t\t\t\t\t\tclass=\"cn-register-mapping__board-check\"\n\t\t\t\t\t\t\t\t\t\t\t:size=\"16\" />\n\t\t\t\t\t\t\t\t\t\t{{ schemaLabel(activeGroupIdx, type) || t('nextcloud-vue', 'Not set') }}\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t<tr v-if=\"isExpanded(activeGroupIdx, type.slug)\" class=\"cn-register-mapping__board-detail\">\n\t\t\t\t\t\t\t\t<td colspan=\"2\">\n\t\t\t\t\t\t\t\t\t<p v-if=\"type.description\" class=\"cn-register-mapping__type-description\">\n\t\t\t\t\t\t\t\t\t\t{{ type.description }}\n\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t\t<NcSelect\n\t\t\t\t\t\t\t\t\t\t:modelValue=\"selectedSchema(activeGroupIdx, type)\"\n\t\t\t\t\t\t\t\t\t\t:options=\"schemaSelectOptions(activeGroupIdx)\"\n\t\t\t\t\t\t\t\t\t\t:placeholder=\"labels.selectSchema\"\n\t\t\t\t\t\t\t\t\t\t:inputLabel=\"labels.schema\"\n\t\t\t\t\t\t\t\t\t\tlabel=\"label\"\n\t\t\t\t\t\t\t\t\t\ttrackBy=\"value\"\n\t\t\t\t\t\t\t\t\t\t@update:modelValue=\"handleSchemaChange(activeGroupIdx, type, $event)\" />\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t</template>\n\t\t\t\t\t</tbody>\n\t\t\t\t</table>\n\t\t\t\t<p\n\t\t\t\t\tv-if=\"selectedRegister(activeGroupIdx) && boardHiddenTypes.length > 0\"\n\t\t\t\t\tclass=\"cn-register-mapping__board-more\"\n\t\t\t\t\tdata-testid=\"cn-register-mapping-board-more\">\n\t\t\t\t\t{{ boardHiddenSummary }}\n\t\t\t\t\t<button type=\"button\" class=\"cn-register-mapping__board-link\" @click=\"showAllTypes = true\">\n\t\t\t\t\t\t{{ t('nextcloud-vue', 'Show all types') }}\n\t\t\t\t\t</button>\n\t\t\t\t</p>\n\t\t\t\t<NcNoteCard v-if=\"!selectedRegister(activeGroupIdx)\" type=\"info\">\n\t\t\t\t\t{{ labels.selectRegister }}\n\t\t\t\t</NcNoteCard>\n\t\t\t\t<NcNoteCard\n\t\t\t\t\tv-if=\"selectedRegister(activeGroupIdx) && schemaSelectOptions(activeGroupIdx).length === 0\"\n\t\t\t\t\ttype=\"warning\">\n\t\t\t\t\t{{ labels.noSchemas }}\n\t\t\t\t</NcNoteCard>\n\t\t\t</div>\n\t\t\t<ul v-if=\"boardOtherGroups.length > 0\" class=\"cn-register-mapping__board-groups\">\n\t\t\t\t<li v-for=\"item in boardOtherGroups\" :key=\"item.idx\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"cn-register-mapping__board-group-row\"\n\t\t\t\t\t\tdata-testid=\"cn-register-mapping-board-group-row\"\n\t\t\t\t\t\t@click=\"openBoardGroup(item.idx)\">\n\t\t\t\t\t\t<ChevronRight :size=\"18\" class=\"cn-register-mapping__board-chevron\" />\n\t\t\t\t\t\t<strong class=\"cn-register-mapping__board-group-name\">{{ item.group.name }}</strong>\n\t\t\t\t\t\t<span class=\"cn-register-mapping__board-group-count\">\n\t\t\t\t\t\t\t{{ n('nextcloud-vue', '%n type', '%n types', item.group.types.length) }}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<CnStatusBadge\n\t\t\t\t\t\t\t:label=\"groupStatusLabel(item.idx, false)\"\n\t\t\t\t\t\t\t:variant=\"groupStatusVariant(item.idx)\" />\n\t\t\t\t\t</button>\n\t\t\t\t</li>\n\t\t\t</ul>\n\t\t\t<div v-if=\"showSaveButton\" class=\"cn-register-mapping__board-save\">\n\t\t\t\t<NcButton\n\t\t\t\t\tvariant=\"primary\"\n\t\t\t\t\t:disabled=\"saving || !hasChanges\"\n\t\t\t\t\tdata-testid=\"cn-register-mapping-board-save\"\n\t\t\t\t\t@click=\"handleSave\">\n\t\t\t\t\t<template v-if=\"saving\" #icon>\n\t\t\t\t\t\t<NcLoadingIcon :size=\"20\" />\n\t\t\t\t\t</template>\n\t\t\t\t\t{{ saving ? t('nextcloud-vue', 'Saving…') : saveButtonText }}\n\t\t\t\t</NcButton>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<div v-else-if=\"!registersLoading && !registersError\" class=\"cn-register-mapping\">\n\t\t\t<div\n\t\t\t\tv-for=\"(group, groupIdx) in groups\"\n\t\t\t\t:key=\"groupIdx\"\n\t\t\t\tclass=\"cn-register-mapping__group\"\n\t\t\t\t:class=\"{ 'cn-register-mapping__group--collapsed': !isGroupOpen(groupIdx) }\"\n\t\t\t\tdata-testid=\"cn-register-mapping-group\">\n\t\t\t\t<!-- Group header. With collapsible groups a heading holds the button\n\t\t\t\t that opens and closes the group (the WAI-ARIA accordion); the\n\t\t\t\t count stays visible while it is closed. -->\n\t\t\t\t<h4 v-if=\"groupsCollapsible\" class=\"cn-register-mapping__group-heading\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"cn-register-mapping__group-toggle\"\n\t\t\t\t\t\t:aria-expanded=\"String(isGroupOpen(groupIdx))\"\n\t\t\t\t\t\t:aria-controls=\"groupBodyId(groupIdx)\"\n\t\t\t\t\t\tdata-testid=\"cn-register-mapping-group-toggle\"\n\t\t\t\t\t\t@click=\"toggleGroup(groupIdx)\">\n\t\t\t\t\t\t<span class=\"cn-register-mapping__group-chevron\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t<ChevronUp v-if=\"isGroupOpen(groupIdx)\" :size=\"20\" />\n\t\t\t\t\t\t\t<ChevronDown v-else :size=\"20\" />\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<slot name=\"group-header\"\n\t\t\t\t\t\t\t:group=\"group\"\n\t\t\t\t\t\t\t:configuredCount=\"configuredCount(groupIdx)\"\n\t\t\t\t\t\t\t:totalCount=\"group.types.length\">\n\t\t\t\t\t\t\t<span class=\"cn-register-mapping__group-header\">\n\t\t\t\t\t\t\t\t<span class=\"cn-register-mapping__group-title\">{{ group.name }}</span>\n\t\t\t\t\t\t\t\t<span class=\"cn-register-mapping__group-status\" data-testid=\"cn-register-mapping-group-count\">\n\t\t\t\t\t\t\t\t\t{{ configuredCount(groupIdx) }}/{{ group.types.length }} {{ labels.partiallyConfigured }}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</slot>\n\t\t\t\t\t</button>\n\t\t\t\t</h4>\n\t\t\t\t<slot v-else\n\t\t\t\t\tname=\"group-header\"\n\t\t\t\t\t:group=\"group\"\n\t\t\t\t\t:configuredCount=\"configuredCount(groupIdx)\"\n\t\t\t\t\t:totalCount=\"group.types.length\">\n\t\t\t\t\t<div class=\"cn-register-mapping__group-header\">\n\t\t\t\t\t\t<h4 class=\"cn-register-mapping__group-title\">\n\t\t\t\t\t\t\t{{ group.name }}\n\t\t\t\t\t\t</h4>\n\t\t\t\t\t\t<span class=\"cn-register-mapping__group-status\">\n\t\t\t\t\t\t\t{{ configuredCount(groupIdx) }}/{{ group.types.length }} {{ labels.partiallyConfigured }}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</div>\n\t\t\t\t</slot>\n\n\t\t\t\t<div\n\t\t\t\t\tv-show=\"isGroupOpen(groupIdx)\"\n\t\t\t\t\t:id=\"groupBodyId(groupIdx)\"\n\t\t\t\t\tclass=\"cn-register-mapping__group-body\"\n\t\t\t\t\tdata-testid=\"cn-register-mapping-group-body\">\n\t\t\t\t\t<!-- Group description -->\n\t\t\t\t\t<p v-if=\"group.description\" class=\"cn-register-mapping__group-description\">\n\t\t\t\t\t\t{{ group.description }}\n\t\t\t\t\t</p>\n\n\t\t\t\t\t<!-- Register selector -->\n\t\t\t\t\t<div class=\"cn-register-mapping__register-select\">\n\t\t\t\t\t\t<NcSelect\n\t\t\t\t\t\t\t:modelValue=\"selectedRegister(groupIdx)\"\n\t\t\t\t\t\t\t:options=\"registerSelectOptions\"\n\t\t\t\t\t\t\t:placeholder=\"labels.selectRegister\"\n\t\t\t\t\t\t\t:inputLabel=\"labels.register\"\n\t\t\t\t\t\t\t:loading=\"registersLoading\"\n\t\t\t\t\t\t\tlabel=\"label\"\n\t\t\t\t\t\t\ttrackBy=\"value\"\n\t\t\t\t\t\t\t@update:modelValue=\"handleRegisterChange(groupIdx, $event)\" />\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<!-- Type list -->\n\t\t\t\t\t<div v-if=\"selectedRegister(groupIdx)\" class=\"cn-register-mapping__type-list\">\n\t\t\t\t\t\t<!-- Header row -->\n\t\t\t\t\t\t<div class=\"cn-register-mapping__type-list-header\">\n\t\t\t\t\t\t\t<span>{{ t('nextcloud-vue', 'Object type') }}</span>\n\t\t\t\t\t\t\t<span>{{ labels.schema }}</span>\n\t\t\t\t\t\t\t<span />\n\t\t\t\t\t\t\t<span />\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<!-- Type rows -->\n\t\t\t\t\t\t<template v-for=\"type in group.types\" :key=\"type.slug + '-row'\">\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclass=\"cn-register-mapping__type-row\"\n\t\t\t\t\t\t\t\t:class=\"{ 'cn-register-mapping__type-row--expanded': isExpanded(groupIdx, type.slug) }\"\n\t\t\t\t\t\t\t\t@click=\"toggleExpand(groupIdx, type.slug)\">\n\t\t\t\t\t\t\t\t<span class=\"cn-register-mapping__type-name\">{{ type.label }}</span>\n\t\t\t\t\t\t\t\t<span class=\"cn-register-mapping__type-schema\">\n\t\t\t\t\t\t\t\t\t{{ schemaLabel(groupIdx, type) || labels.notConfigured }}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<span class=\"cn-register-mapping__type-status\">\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"cn-register-mapping__status-dot\"\n\t\t\t\t\t\t\t\t\t\t:class=\"schemaValue(groupIdx, type)\n\t\t\t\t\t\t\t\t\t\t\t? 'cn-register-mapping__status-dot--configured'\n\t\t\t\t\t\t\t\t\t\t\t: 'cn-register-mapping__status-dot--unconfigured'\" />\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<span class=\"cn-register-mapping__type-chevron\">\n\t\t\t\t\t\t\t\t\t<ChevronUp v-if=\"isExpanded(groupIdx, type.slug)\" :size=\"20\" />\n\t\t\t\t\t\t\t\t\t<ChevronDown v-else :size=\"20\" />\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t<!-- Expanded detail -->\n\t\t\t\t\t\t\t<transition name=\"slide\">\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\tv-if=\"isExpanded(groupIdx, type.slug)\"\n\t\t\t\t\t\t\t\t\tclass=\"cn-register-mapping__type-detail\">\n\t\t\t\t\t\t\t\t\t<p v-if=\"type.description\" class=\"cn-register-mapping__type-description\">\n\t\t\t\t\t\t\t\t\t\t{{ type.description }}\n\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t\t<NcSelect\n\t\t\t\t\t\t\t\t\t\t:modelValue=\"selectedSchema(groupIdx, type)\"\n\t\t\t\t\t\t\t\t\t\t:options=\"schemaSelectOptions(groupIdx)\"\n\t\t\t\t\t\t\t\t\t\t:placeholder=\"labels.selectSchema\"\n\t\t\t\t\t\t\t\t\t\t:inputLabel=\"labels.schema\"\n\t\t\t\t\t\t\t\t\t\tlabel=\"label\"\n\t\t\t\t\t\t\t\t\t\ttrackBy=\"value\"\n\t\t\t\t\t\t\t\t\t\t@update:modelValue=\"handleSchemaChange(groupIdx, type, $event)\" />\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</transition>\n\t\t\t\t\t\t</template>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<!-- No register selected -->\n\t\t\t\t\t<NcNoteCard v-else-if=\"!registersLoading\" type=\"info\">\n\t\t\t\t\t\t{{ labels.selectRegister }}\n\t\t\t\t\t</NcNoteCard>\n\n\t\t\t\t\t<!-- No schemas available -->\n\t\t\t\t\t<NcNoteCard\n\t\t\t\t\t\tv-if=\"selectedRegister(groupIdx) && schemaSelectOptions(groupIdx).length === 0 && !registersLoading\"\n\t\t\t\t\t\tvariant=\"warning\">\n\t\t\t\t\t\t{{ labels.noSchemas }}\n\t\t\t\t\t</NcNoteCard>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<!-- Footer -->\n\t\t<template v-if=\"$slots.footer\" #footer>\n\t\t\t<slot name=\"footer\" />\n\t\t</template>\n\t</CnSettingsSection>\n</template>\n\n<script>\nimport { translatePlural as n, translate as t } from '@nextcloud/l10n'\nimport { NcButton, NcLoadingIcon, NcNoteCard, NcSelect } from '@nextcloud/vue'\nimport CheckCircle from 'vue-material-design-icons/CheckCircle.vue'\nimport ChevronDown from 'vue-material-design-icons/ChevronDown.vue'\nimport ChevronRight from 'vue-material-design-icons/ChevronRight.vue'\nimport ChevronUp from 'vue-material-design-icons/ChevronUp.vue'\nimport ContentSave from 'vue-material-design-icons/ContentSave.vue'\nimport Refresh from 'vue-material-design-icons/Refresh.vue'\nimport { normalizeLook } from '../../composables/useLook.js'\nimport { buildHeaders, prefixUrl } from '../../utils/headers.js'\nimport { CnSettingsSection } from '../CnSettingsSection/index.js'\nimport { CnStatusBadge } from '../CnStatusBadge/index.js'\n\nlet mappingCount = 0\n\n/**\n * CnRegisterMapping - OpenRegister register/schema configuration component.\n *\n * Displays and manages register-to-schema mappings for app object types.\n * Self-fetches available registers and schemas from the OpenRegister API.\n * Supports multiple register groups (stacked sections) with expandable\n * type rows for manual schema override.\n *\n * Only the registers the configuration maps have their schemas fetched; the\n * register select lists every register without its schemas.\n *\n * In the board look one group is open as a type/schema table under a status\n * chip, the other groups are rows with their type count and status, and the\n * save button closes the section.\n *\n * Single register (Pipelinq)\n * ```vue\n * <CnRegisterMapping\n * name=\"Register Configuration\"\n * :groups=\"[{\n * name: 'Core Objects',\n * types: [\n * { slug: 'client', label: 'Client' },\n * { slug: 'contact', label: 'Contact' },\n * ],\n * }]\"\n * :configuration=\"config\"\n * :show-reimport-button=\"true\"\n * @save=\"saveConfig\"\n * @reimport=\"reimport\" />\n * ```\n *\n * Multi-register (Stackiq)\n * ```vue\n * <CnRegisterMapping\n * :groups=\"[\n * { name: 'Voorzieningen', registerConfigKey: 'voorzieningen_register', types: [...] },\n * { name: 'AMEF', registerConfigKey: 'amef_register', types: [...] },\n * ]\"\n * :configuration=\"config\"\n * @save=\"saveConfig\" />\n * ```\n */\nexport default {\n\tname: 'CnRegisterMapping',\n\n\tcomponents: {\n\t\tCnSettingsSection,\n\t\tCnStatusBadge,\n\t\tNcButton,\n\t\tNcLoadingIcon,\n\t\tNcNoteCard,\n\t\tNcSelect,\n\t\tContentSave,\n\t\tRefresh,\n\t\tCheckCircle,\n\t\tChevronDown,\n\t\tChevronRight,\n\t\tChevronUp,\n\t},\n\n\tinject: {\n\t\t/** The look CnAppRoot or CnAdminSettingsShell provides. */\n\t\tcnLook: { default: 'nextcloud' },\n\t},\n\n\tprops: {\n\t\t/** Section title */\n\t\tname: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Register configuration'),\n\t\t},\n\n\t\t/** Section description */\n\t\tdescription: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Configure OpenRegister schema mappings for your object types'),\n\t\t},\n\n\t\t/** Documentation URL */\n\t\tdocUrl: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Groups of object types that share a register.\n\t\t *\n\t\t * @type {Array<{ name: string, description: string, registerConfigKey: string, types: Array<{ slug: string, label: string, description: string, configKey: string }> }>}\n\t\t */\n\t\tgroups: {\n\t\t\ttype: Array,\n\t\t\trequired: true,\n\t\t\tvalidator: (groups) => groups.length > 0\n\t\t\t\t&& groups.every((g) => g.name && Array.isArray(g.types) && g.types.length > 0),\n\t\t},\n\n\t\t/** Current configuration values: { register: '5', client_schema: '28', ... } */\n\t\tconfiguration: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/** Show save button */\n\t\tshowSaveButton: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/** Whether save is in progress */\n\t\tsaving: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Show reimport button */\n\t\tshowReimportButton: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Whether reimport is in progress */\n\t\treimporting: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Save button text */\n\t\tsaveButtonText: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Save configuration'),\n\t\t},\n\n\t\t/** Reimport button text */\n\t\treimportButtonText: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Re-import configuration'),\n\t\t},\n\n\t\t/**\n\t\t * Draw each group as a header that opens and closes it, showing its\n\t\t * configured count while closed. The groups start closed. `null` (the\n\t\t * default) collapses them when there is more than one group, so a page\n\t\t * with several registers is not one long card.\n\t\t *\n\t\t * @type {boolean|null}\n\t\t * @spec openspec/changes/register-mapping-collapsed-groups/specs/register-mapping/spec.md#requirement-register-groups-start-closed-with-their-count\n\t\t */\n\t\tcollapseGroups: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * The look the mapping is drawn in: `board` or `nextcloud`. Empty\n\t\t * follows the provided `cnLook`.\n\t\t *\n\t\t * @spec openspec/changes/register-mapping-board-look/specs/register-mapping/spec.md#requirement-the-board-look-draws-one-open-group-and-compact-rows\n\t\t */\n\t\tlook: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Board look: how many types the open group lists before a \"show all\"\n\t\t * line. 0 lists every type.\n\t\t *\n\t\t * @spec openspec/changes/register-mapping-board-look/specs/register-mapping/spec.md#requirement-the-board-look-draws-one-open-group-and-compact-rows\n\t\t */\n\t\tboardRowLimit: {\n\t\t\ttype: Number,\n\t\t\tdefault: 4,\n\t\t},\n\n\t\t/** Auto-match schema titles to type slugs on register change */\n\t\tautoMatch: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/** UI labels (i18n) */\n\t\tlabels: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({\n\t\t\t\tregister: t('nextcloud-vue', 'Register'),\n\t\t\t\tschema: t('nextcloud-vue', 'Schema'),\n\t\t\t\tconfigured: t('nextcloud-vue', 'Configured'),\n\t\t\t\tnotConfigured: t('nextcloud-vue', 'Not configured'),\n\t\t\t\tnoSchemas: t('nextcloud-vue', 'No schemas available in this register'),\n\t\t\t\tselectRegister: t('nextcloud-vue', 'Select a register'),\n\t\t\t\tselectSchema: t('nextcloud-vue', 'Select a schema'),\n\t\t\t\tallConfigured: t('nextcloud-vue', 'All types configured'),\n\t\t\t\tpartiallyConfigured: t('nextcloud-vue', 'configured'),\n\t\t\t}),\n\t\t},\n\t},\n\n\temits: ['update:configuration', 'save', 'reimport'],\n\n\tdata() {\n\t\treturn {\n\t\t\t// Fetched data\n\t\t\tregisters: [],\n\t\t\tschemasByRegister: {},\n\t\t\tregistersLoading: false,\n\t\t\tregistersError: null,\n\t\t\t// Local state\n\t\t\tlocalConfig: {},\n\t\t\texpandedRows: {},\n\t\t\t// The groups opened by the reader, by index.\n\t\t\topenGroups: {},\n\t\t\t// Board look: the group drawn open, and whether it lists every type.\n\t\t\tactiveGroupIdx: 0,\n\t\t\t// Schema requests by register id, so a register is fetched once.\n\t\t\tschemaRequests: {},\n\t\t\tregistersLoaded: false,\n\t\t\tshowAllTypes: false,\n\t\t\tuid: ++mappingCount,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/** Register options for NcSelect */\n\t\tregisterSelectOptions() {\n\t\t\treturn this.registers.map((r) => ({\n\t\t\t\tlabel: r.title || r.slug || t('nextcloud-vue', 'Register {id}', { id: r.id }),\n\t\t\t\tvalue: String(r.id),\n\t\t\t}))\n\t\t},\n\n\t\t/**\n\t\t * Whether the groups open and close.\n\t\t *\n\t\t * @return {boolean}\n\t\t * @spec openspec/changes/register-mapping-collapsed-groups/specs/register-mapping/spec.md#requirement-register-groups-start-closed-with-their-count\n\t\t */\n\t\tgroupsCollapsible() {\n\t\t\treturn this.collapseGroups === null ? this.groups.length > 1 : this.collapseGroups\n\t\t},\n\n\t\t/**\n\t\t * Whether the board look applies.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tisBoardLook() {\n\t\t\treturn normalizeLook(this.look || this.cnLook) === 'board'\n\t\t},\n\n\t\t/**\n\t\t * The group the board look draws open.\n\t\t *\n\t\t * @return {object}\n\t\t */\n\t\tactiveGroup() {\n\t\t\treturn this.groups[this.activeGroupIdx] || this.groups[0]\n\t\t},\n\n\t\t/**\n\t\t * The open group's types the board table lists.\n\t\t *\n\t\t * @return {Array<object>}\n\t\t */\n\t\tboardVisibleTypes() {\n\t\t\tconst types = this.activeGroup.types\n\t\t\tif (this.showAllTypes || this.boardRowLimit <= 0) {\n\t\t\t\treturn types\n\t\t\t}\n\t\t\treturn types.slice(0, this.boardRowLimit)\n\t\t},\n\n\t\t/**\n\t\t * The open group's types below the row limit.\n\t\t *\n\t\t * @return {Array<object>}\n\t\t */\n\t\tboardHiddenTypes() {\n\t\t\treturn this.activeGroup.types.slice(this.boardVisibleTypes.length)\n\t\t},\n\n\t\t/**\n\t\t * The line under the board table that counts the types not listed.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tboardHiddenSummary() {\n\t\t\tconst count = this.boardHiddenTypes.length\n\t\t\tconst allSet = this.boardHiddenTypes.every((type) => !!this.schemaValue(this.activeGroupIdx, type))\n\t\t\treturn allSet\n\t\t\t\t? n('nextcloud-vue', 'And %n more type in this group, set up.', 'And %n more types in this group, all set up.', count)\n\t\t\t\t: n('nextcloud-vue', 'And %n more type in this group.', 'And %n more types in this group.', count)\n\t\t},\n\n\t\t/**\n\t\t * The groups the board look draws as compact rows, with their index.\n\t\t *\n\t\t * @return {Array<{group: object, idx: number}>}\n\t\t */\n\t\tboardOtherGroups() {\n\t\t\treturn this.groups\n\t\t\t\t.map((group, idx) => ({ group, idx }))\n\t\t\t\t.filter((item) => item.idx !== this.activeGroupIdx)\n\t\t},\n\n\t\t/**\n\t\t * Whether the section header draws buttons; the board look saves at the end.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\thasHeaderActions() {\n\t\t\treturn (this.showSaveButton && !this.isBoardLook) || this.showReimportButton || !!this.$slots.actions\n\t\t},\n\n\t\t/** Whether local config differs from prop */\n\t\thasChanges() {\n\t\t\treturn JSON.stringify(this.localConfig) !== JSON.stringify(this.configuration)\n\t\t},\n\t},\n\n\twatch: {\n\t\tconfiguration: {\n\t\t\thandler(newVal) {\n\t\t\t\tthis.localConfig = { ...newVal }\n\t\t\t\tif (this.registersLoaded) {\n\t\t\t\t\tthis.mappedRegisterIds().forEach((id) => this.loadSchemasForRegister(id))\n\t\t\t\t}\n\t\t\t},\n\n\t\t\timmediate: true,\n\t\t\tdeep: true,\n\t\t},\n\n\t\tgroups() {\n\t\t\tif (this.activeGroupIdx >= this.groups.length) {\n\t\t\t\tthis.activeGroupIdx = 0\n\t\t\t}\n\t\t},\n\t},\n\n\tasync mounted() {\n\t\tawait this.loadRegisters()\n\t},\n\n\tmethods: {\n\t\tt,\n\t\tn,\n\n\t\t/**\n\t\t * The status chip text of a group: every type set up, none, or how many.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @param {boolean} open Whether the group is the open one, which says \"All types set up\"\n\t\t * @return {string}\n\t\t * @spec openspec/changes/register-mapping-board-look/specs/register-mapping/spec.md#requirement-the-board-look-draws-one-open-group-and-compact-rows\n\t\t */\n\t\tgroupStatusLabel(groupIdx, open) {\n\t\t\tconst configured = this.configuredCount(groupIdx)\n\t\t\tconst total = this.groups[groupIdx].types.length\n\t\t\tif (configured === total) {\n\t\t\t\treturn open ? t('nextcloud-vue', 'All types set up') : t('nextcloud-vue', 'Set up')\n\t\t\t}\n\t\t\tif (configured === 0) {\n\t\t\t\treturn t('nextcloud-vue', 'Not set')\n\t\t\t}\n\t\t\treturn t('nextcloud-vue', '{configured} of {total} set up', { configured, total })\n\t\t},\n\n\t\t/**\n\t\t * The status chip variant of a group.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @return {'success'|'warning'|'default'}\n\t\t */\n\t\tgroupStatusVariant(groupIdx) {\n\t\t\tconst configured = this.configuredCount(groupIdx)\n\t\t\tif (configured === this.groups[groupIdx].types.length) {\n\t\t\t\treturn 'success'\n\t\t\t}\n\t\t\treturn configured === 0 ? 'default' : 'warning'\n\t\t},\n\n\t\t/**\n\t\t * Board look: draw another group open.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @return {void}\n\t\t * @spec openspec/changes/register-mapping-board-look/specs/register-mapping/spec.md#requirement-the-board-look-draws-one-open-group-and-compact-rows\n\t\t */\n\t\topenBoardGroup(groupIdx) {\n\t\t\tthis.activeGroupIdx = groupIdx\n\t\t\tthis.showAllTypes = false\n\t\t},\n\n\t\t/**\n\t\t * The register ids the configuration maps, one per distinct value.\n\t\t *\n\t\t * @return {string[]}\n\t\t */\n\t\tmappedRegisterIds() {\n\t\t\tconst ids = this.groups\n\t\t\t\t.map((group, idx) => String(this.localConfig[this.registerConfigKey(idx)] || ''))\n\t\t\t\t.filter(Boolean)\n\t\t\treturn [...new Set(ids)]\n\t\t},\n\n\t\t/**\n\t\t * Whether a group's body shows.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @return {boolean}\n\t\t */\n\t\tisGroupOpen(groupIdx) {\n\t\t\treturn !this.groupsCollapsible || this.openGroups[groupIdx] === true\n\t\t},\n\n\t\t/**\n\t\t * Open a closed group, or close an open one.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @return {void}\n\t\t * @spec openspec/changes/register-mapping-collapsed-groups/specs/register-mapping/spec.md#requirement-register-groups-start-closed-with-their-count\n\t\t */\n\t\ttoggleGroup(groupIdx) {\n\t\t\tthis.openGroups = { ...this.openGroups, [groupIdx]: !this.isGroupOpen(groupIdx) }\n\t\t},\n\n\t\t/**\n\t\t * The id of a group's body, for the header's `aria-controls`.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @return {string}\n\t\t */\n\t\tgroupBodyId(groupIdx) {\n\t\t\treturn `cn-register-mapping-${this.uid}-group-${groupIdx}`\n\t\t},\n\n\t\t/**\n\t\t * Get the config key for a group's register.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @return {string} Config key\n\t\t */\n\t\tregisterConfigKey(groupIdx) {\n\t\t\tconst group = this.groups[groupIdx]\n\t\t\tif (group.registerConfigKey) {\n\t\t\t\treturn group.registerConfigKey\n\t\t\t}\n\t\t\tif (this.groups.length === 1) {\n\t\t\t\treturn 'register'\n\t\t\t}\n\t\t\treturn group.name.toLowerCase().replace(/[^a-z0-9]+/g, '_') + '_register'\n\t\t},\n\n\t\t/**\n\t\t * Get the config key for a type's schema.\n\t\t *\n\t\t * @param {object} type Type definition\n\t\t * @return {string} Config key\n\t\t */\n\t\tschemaConfigKey(type) {\n\t\t\treturn type.configKey || type.slug + '_schema'\n\t\t},\n\n\t\t/**\n\t\t * Get the selected register option for a group.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @return {object|null} NcSelect option\n\t\t */\n\t\tselectedRegister(groupIdx) {\n\t\t\tconst key = this.registerConfigKey(groupIdx)\n\t\t\tconst value = String(this.localConfig[key] || '')\n\t\t\tif (!value) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\treturn this.registerSelectOptions.find((o) => o.value === value) || null\n\t\t},\n\n\t\t/**\n\t\t * Get the selected schema option for a type.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @param {object} type Type definition\n\t\t * @return {object|null} NcSelect option\n\t\t */\n\t\tselectedSchema(groupIdx, type) {\n\t\t\tconst key = this.schemaConfigKey(type)\n\t\t\tconst value = String(this.localConfig[key] || '')\n\t\t\tif (!value) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst options = this.schemaSelectOptions(groupIdx)\n\t\t\treturn options.find((o) => o.value === value) || null\n\t\t},\n\n\t\t/**\n\t\t * Get the schema value (ID) for a type.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @param {object} type Type definition\n\t\t * @return {string} Schema ID or empty string\n\t\t */\n\t\tschemaValue(groupIdx, type) {\n\t\t\tconst key = this.schemaConfigKey(type)\n\t\t\treturn this.localConfig[key] || ''\n\t\t},\n\n\t\t/**\n\t\t * Get the display label for a type's current schema.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @param {object} type Type definition\n\t\t * @return {string} Schema label or empty string\n\t\t */\n\t\tschemaLabel(groupIdx, type) {\n\t\t\tconst selected = this.selectedSchema(groupIdx, type)\n\t\t\tif (selected) {\n\t\t\t\treturn selected.label\n\t\t\t}\n\t\t\tconst value = this.schemaValue(groupIdx, type)\n\t\t\treturn value ? t('nextcloud-vue', 'Schema {id}', { id: value }) : ''\n\t\t},\n\n\t\t/**\n\t\t * Get schema options for a group's selected register.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @return {Array<{label: string, value: string}>} NcSelect options\n\t\t */\n\t\tschemaSelectOptions(groupIdx) {\n\t\t\tconst reg = this.selectedRegister(groupIdx)\n\t\t\tif (!reg) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\tconst schemas = this.schemasByRegister[reg.value] || []\n\t\t\treturn schemas.map((s) => ({\n\t\t\t\tlabel: s.title || s.slug || t('nextcloud-vue', 'Schema {id}', { id: s.id }),\n\t\t\t\tvalue: String(s.id),\n\t\t\t}))\n\t\t},\n\n\t\t/**\n\t\t * Count configured types in a group.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @return {number} Count\n\t\t */\n\t\tconfiguredCount(groupIdx) {\n\t\t\tconst group = this.groups[groupIdx]\n\t\t\treturn group.types.filter((type) => !!this.schemaValue(groupIdx, type)).length\n\t\t},\n\n\t\t/**\n\t\t * Check if a type row is expanded.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @param {string} slug Type slug\n\t\t * @return {boolean}\n\t\t */\n\t\tisExpanded(groupIdx, slug) {\n\t\t\treturn !!this.expandedRows[groupIdx + '-' + slug]\n\t\t},\n\n\t\t/**\n\t\t * Toggle a type row expansion.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @param {string} slug Type slug\n\t\t */\n\t\ttoggleExpand(groupIdx, slug) {\n\t\t\tconst key = groupIdx + '-' + slug\n\t\t\tthis.expandedRows = {\n\t\t\t\t...this.expandedRows,\n\t\t\t\t[key]: !this.expandedRows[key],\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Handle register selection change for a group.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @param {object|null} option NcSelect option\n\t\t */\n\t\tasync handleRegisterChange(groupIdx, option) {\n\t\t\tconst key = this.registerConfigKey(groupIdx)\n\t\t\tconst value = option?.value || ''\n\n\t\t\tthis.localConfig = { ...this.localConfig, [key]: value }\n\n\t\t\t// Clear schema selections for this group\n\t\t\tconst group = this.groups[groupIdx]\n\t\t\tfor (const type of group.types) {\n\t\t\t\tconst schemaKey = this.schemaConfigKey(type)\n\t\t\t\tthis.localConfig = { ...this.localConfig, [schemaKey]: '' }\n\t\t\t}\n\n\t\t\t// Fetch schemas for the new register\n\t\t\tif (value) {\n\t\t\t\tawait this.loadSchemasForRegister(value)\n\n\t\t\t\t// Auto-match schemas\n\t\t\t\tif (this.autoMatch) {\n\t\t\t\t\tthis.autoMatchSchemas(groupIdx)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.$emit('update:configuration', { ...this.localConfig })\n\t\t},\n\n\t\t/**\n\t\t * Handle schema selection change for a type.\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t * @param {object} type Type definition\n\t\t * @param {object|null} option NcSelect option\n\t\t */\n\t\thandleSchemaChange(groupIdx, type, option) {\n\t\t\tconst key = this.schemaConfigKey(type)\n\t\t\tconst value = option?.value || ''\n\n\t\t\tthis.localConfig = { ...this.localConfig, [key]: value }\n\t\t\tthis.$emit('update:configuration', { ...this.localConfig })\n\t\t},\n\n\t\t/**\n\t\t * Auto-match schema titles to type slugs/labels (case-insensitive).\n\t\t *\n\t\t * @param {number} groupIdx Group index\n\t\t */\n\t\tautoMatchSchemas(groupIdx) {\n\t\t\tconst group = this.groups[groupIdx]\n\t\t\tconst options = this.schemaSelectOptions(groupIdx)\n\n\t\t\tfor (const type of group.types) {\n\t\t\t\tconst schemaKey = this.schemaConfigKey(type)\n\t\t\t\t// Skip if already has a value\n\t\t\t\tif (this.localConfig[schemaKey]) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tconst slug = type.slug.toLowerCase()\n\t\t\t\tconst label = type.label.toLowerCase()\n\n\t\t\t\tconst match = options.find((o) => {\n\t\t\t\t\tconst optLabel = o.label.toLowerCase()\n\t\t\t\t\treturn optLabel === slug || optLabel === label\n\t\t\t\t\t\t|| optLabel.includes(slug) || slug.includes(optLabel)\n\t\t\t\t})\n\n\t\t\t\tif (match) {\n\t\t\t\t\tthis.localConfig = { ...this.localConfig, [schemaKey]: match.value }\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/** Emit save event with current config */\n\t\thandleSave() {\n\t\t\tthis.$emit('save', { ...this.localConfig })\n\t\t},\n\n\t\t/**\n\t\t * Fetch the registers for the select, without their schemas, and the\n\t\t * schemas of the registers the configuration maps. Expanding the schemas\n\t\t * of every register costs megabytes on a busy instance.\n\t\t *\n\t\t * @spec openspec/changes/register-mapping-board-look/specs/register-mapping/spec.md#requirement-only-mapped-registers-have-their-schemas-fetched\n\t\t */\n\t\tasync loadRegisters() {\n\t\t\tthis.registersLoading = true\n\t\t\tthis.registersError = null\n\n\t\t\ttry {\n\t\t\t\tconst [response] = await Promise.all([\n\t\t\t\t\tfetch(prefixUrl('/apps/openregister/api/registers'), {\n\t\t\t\t\t\tmethod: 'GET',\n\t\t\t\t\t\theaders: buildHeaders(),\n\t\t\t\t\t}),\n\t\t\t\t\t...this.mappedRegisterIds().map((id) => this.loadSchemasForRegister(id)),\n\t\t\t\t])\n\n\t\t\t\tif (!response.ok) {\n\t\t\t\t\tthis.registersError = t('nextcloud-vue', 'The registers could not be loaded: {reason}', { reason: response.statusText || response.status })\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst data = await response.json()\n\t\t\t\tconst results = data.results || data\n\t\t\t\tthis.registers = Array.isArray(results) ? results : []\n\t\t\t\tthis.registersLoaded = true\n\t\t\t} catch (error) {\n\t\t\t\tthis.registersError = error.message || t('nextcloud-vue', 'The registers could not be loaded: {reason}', { reason: t('nextcloud-vue', 'no connection') })\n\t\t\t} finally {\n\t\t\t\tthis.registersLoading = false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Fetch the schemas of one register, through `registers/{id}/schemas`,\n\t\t * or the register with its schemas expanded where that route is missing.\n\t\t *\n\t\t * @param {string} registerId Register ID\n\t\t * @spec openspec/changes/register-mapping-board-look/specs/register-mapping/spec.md#requirement-only-mapped-registers-have-their-schemas-fetched\n\t\t */\n\t\tasync loadSchemasForRegister(registerId) {\n\t\t\tconst id = String(registerId)\n\n\t\t\tif (this.schemasByRegister[id]?.length > 0) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (!this.schemaRequests[id]) {\n\t\t\t\tthis.schemaRequests[id] = this.fetchSchemas(id).finally(() => {\n\t\t\t\t\tdelete this.schemaRequests[id]\n\t\t\t\t})\n\t\t\t}\n\t\t\tawait this.schemaRequests[id]\n\t\t},\n\n\t\t/**\n\t\t * One schema request for a register; fills `schemasByRegister`.\n\t\t *\n\t\t * @param {string} id Register ID\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync fetchSchemas(id) {\n\t\t\ttry {\n\t\t\t\tlet response = await fetch(\n\t\t\t\t\tprefixUrl(`/apps/openregister/api/registers/${encodeURIComponent(id)}/schemas`),\n\t\t\t\t\t{ method: 'GET', headers: buildHeaders() },\n\t\t\t\t)\n\t\t\t\tif (response.status === 404) {\n\t\t\t\t\tresponse = await fetch(\n\t\t\t\t\t\tprefixUrl(`/apps/openregister/api/registers/${encodeURIComponent(id)}?_extend[]=schemas`),\n\t\t\t\t\t\t{ method: 'GET', headers: buildHeaders() },\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tif (!response.ok) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst data = await response.json()\n\t\t\t\tconst list = data.results || data.schemas || []\n\t\t\t\tconst schemas = (Array.isArray(list) ? list : []).filter((s) => s && typeof s === 'object' && s.id)\n\t\t\t\tthis.schemasByRegister = { ...this.schemasByRegister, [id]: schemas }\n\t\t\t} catch {\n\t\t\t\t// The register stays selected; its schema select stays empty.\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-register-mapping__group {\n\tmargin-bottom: 24px;\n\tborder: 1px solid var(--color-border);\n\tborder-radius: var(--border-radius-large);\n\tpadding: 20px;\n\tbackground: var(--color-background-hover);\n}\n\n.cn-register-mapping__group:last-child {\n\tmargin-bottom: 0;\n}\n\n.cn-register-mapping__group-header {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tmargin-bottom: 12px;\n}\n\n.cn-register-mapping__group-heading {\n\tmargin: 0 0 12px;\n\tfont: inherit;\n}\n\n.cn-register-mapping__group--collapsed .cn-register-mapping__group-heading {\n\tmargin-bottom: 0;\n}\n\n.cn-register-mapping__group-toggle {\n\tbox-sizing: border-box;\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\twidth: 100%;\n\tmin-height: 44px;\n\tmargin: 0;\n\tpadding: 0;\n\tborder: 0;\n\tbackground: transparent;\n\tcolor: inherit;\n\tfont: inherit;\n\ttext-align: start;\n\tcursor: pointer;\n}\n\n.cn-register-mapping__group-toggle:focus-visible {\n\toutline: 2px solid var(--color-primary-element);\n\toutline-offset: 2px;\n\tborder-radius: var(--border-radius);\n}\n\n.cn-register-mapping__group-chevron {\n\tdisplay: inline-flex;\n\tflex: none;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-register-mapping__group-toggle .cn-register-mapping__group-header {\n\tflex: 1 1 auto;\n\tflex-wrap: wrap;\n\tgap: 4px 12px;\n\tmin-width: 0;\n\tmargin-bottom: 0;\n}\n\n.cn-register-mapping__group-title {\n\tfont-size: 16px;\n\tfont-weight: 600;\n\tmargin: 0;\n\tcolor: var(--color-main-text);\n}\n\n.cn-register-mapping__group-status {\n\tfont-size: 13px;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-register-mapping__group-description {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 13px;\n\tmargin: 0 0 12px 0;\n}\n\n.cn-register-mapping__register-select {\n\tmargin-bottom: 16px;\n\tmax-width: 400px;\n}\n\n.cn-register-mapping__type-list {\n\tborder: 1px solid var(--color-border);\n\tborder-radius: var(--border-radius);\n\toverflow: hidden;\n\tbackground: var(--color-main-background);\n}\n\n.cn-register-mapping__type-list-header {\n\tdisplay: grid;\n\tgrid-template-columns: 1fr 1fr 40px 32px;\n\talign-items: center;\n\tpadding: 8px 16px;\n\tfont-size: 12px;\n\tfont-weight: 600;\n\tcolor: var(--color-text-maxcontrast);\n\ttext-transform: uppercase;\n\tletter-spacing: 0.5px;\n\tborder-bottom: 1px solid var(--color-border);\n\tbackground: var(--color-background-hover);\n}\n\n.cn-register-mapping__type-row {\n\tdisplay: grid;\n\tgrid-template-columns: 1fr 1fr 40px 32px;\n\talign-items: center;\n\tpadding: 10px 16px;\n\tborder-bottom: 1px solid var(--color-border);\n\tcursor: pointer;\n\ttransition: background-color 0.15s ease;\n}\n\n.cn-register-mapping__type-row:hover {\n\tbackground: var(--color-background-hover);\n}\n\n.cn-register-mapping__type-row--expanded {\n\tbackground: var(--color-background-hover);\n}\n\n.cn-register-mapping__type-name {\n\tfont-weight: 500;\n\tcolor: var(--color-main-text);\n}\n\n.cn-register-mapping__type-schema {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 13px;\n}\n\n.cn-register-mapping__type-status {\n\tdisplay: flex;\n\tjustify-content: center;\n}\n\n.cn-register-mapping__type-chevron {\n\tdisplay: flex;\n\tjustify-content: center;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-register-mapping__status-dot {\n\tdisplay: inline-block;\n\twidth: 10px;\n\theight: 10px;\n\tborder-radius: 50%;\n}\n\n.cn-register-mapping__status-dot--configured {\n\tbackground-color: var(--color-success);\n}\n\n.cn-register-mapping__status-dot--unconfigured {\n\tbackground-color: var(--color-warning);\n}\n\n.cn-register-mapping__type-detail {\n\tpadding: 12px 16px 16px;\n\tborder-bottom: 1px solid var(--color-border);\n\tbackground: var(--color-main-background);\n}\n\n.cn-register-mapping__type-description {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 13px;\n\tmargin: 0 0 8px 0;\n}\n\n/* Board look (PqBeheer): one open group, compact rows for the others. */\n.cn-register-mapping--board {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 14px;\n}\n\n.cn-register-mapping__board-group {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 10px;\n\tpadding: 14px;\n\tborder: 1px solid var(--color-border);\n\tborder-radius: var(--border-radius-large);\n}\n\n.cn-register-mapping__board-head {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\talign-items: flex-start;\n\tjustify-content: space-between;\n\tgap: 10px 16px;\n}\n\n.cn-register-mapping__board-title {\n\tmargin: 0;\n\tfont-size: 15px;\n\tfont-weight: 700;\n}\n\n.cn-register-mapping__board-select {\n\tmax-width: 400px;\n\tmargin-bottom: 0;\n}\n\n.cn-register-mapping__board-table {\n\twidth: 100%;\n\tborder-collapse: collapse;\n}\n\n.cn-register-mapping__board-table th {\n\tpadding: 8px 12px 8px 0;\n\tborder-bottom: 1px solid var(--color-border);\n\tfont-size: 13px;\n\tfont-weight: 600;\n\tcolor: var(--color-text-maxcontrast);\n\ttext-align: start;\n\twhite-space: nowrap;\n}\n\n.cn-register-mapping__board-table td {\n\tpadding: 10px 12px 10px 0;\n\tborder-bottom: 1px solid var(--color-border);\n\tfont-size: 14px;\n\tvertical-align: middle;\n}\n\n.cn-register-mapping__board-schema {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: 6px;\n\tmin-height: 32px;\n\tmargin: 0;\n\tpadding: 0;\n\tborder: 0;\n\tbackground: transparent;\n\tcolor: inherit;\n\tfont: inherit;\n\ttext-align: start;\n\tcursor: pointer;\n}\n\n.cn-register-mapping__board-schema:hover {\n\ttext-decoration: underline;\n}\n\n.cn-register-mapping__board-schema:focus-visible,\n.cn-register-mapping__board-link:focus-visible,\n.cn-register-mapping__board-group-row:focus-visible {\n\toutline: 2px solid var(--color-primary-element);\n\toutline-offset: 2px;\n\tborder-radius: var(--border-radius);\n}\n\n.cn-register-mapping__board-check {\n\tcolor: var(--color-success-text, var(--color-success));\n}\n\n.cn-register-mapping__board-more {\n\tmargin: 0;\n\tfont-size: 13px;\n\tline-height: 1.4;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-register-mapping__board-link {\n\tmargin: 0;\n\tpadding: 0;\n\tborder: 0;\n\tbackground: transparent;\n\tcolor: var(--color-primary-element);\n\tfont: inherit;\n\ttext-decoration: underline;\n\tcursor: pointer;\n}\n\n.cn-register-mapping__board-groups {\n\tdisplay: flex;\n\tflex-direction: column;\n\tmargin: 0;\n\tpadding: 0;\n\tlist-style: none;\n}\n\n.cn-register-mapping__board-group-row {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 10px;\n\twidth: 100%;\n\tmin-height: 44px;\n\tmargin: 0;\n\tpadding: 10px 2px;\n\tborder: 0;\n\tborder-bottom: 1px solid var(--color-border);\n\tbackground: transparent;\n\tcolor: inherit;\n\tfont: inherit;\n\tfont-size: 14px;\n\ttext-align: start;\n\tcursor: pointer;\n}\n\n.cn-register-mapping__board-group-row:hover {\n\tbackground: var(--color-background-hover);\n}\n\n.cn-register-mapping__board-chevron,\n.cn-register-mapping__board-group-count {\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-register-mapping__board-group-name {\n\tflex: 1;\n}\n\n.cn-register-mapping__board-save {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\talign-items: center;\n\tjustify-content: flex-end;\n\tgap: 10px;\n}\n\n/* Slide transition */\n.slide-enter-active,\n.slide-leave-active {\n\ttransition: all 0.2s ease;\n\tmax-height: 200px;\n\toverflow: hidden;\n}\n\n.slide-enter,\n.slide-leave-to {\n\tmax-height: 0;\n\tpadding-top: 0;\n\tpadding-bottom: 0;\n\topacity: 0;\n}\n\n/* Last row in list should not have bottom border */\n.cn-register-mapping__type-list > :last-child {\n\tborder-bottom: none;\n}\n\n@media (max-width: 768px) {\n\t.cn-register-mapping__type-list-header {\n\t\tdisplay: none;\n\t}\n\n\t.cn-register-mapping__type-row {\n\t\tgrid-template-columns: 1fr auto 32px;\n\t}\n\n\t.cn-register-mapping__type-schema {\n\t\tdisplay: none;\n\t}\n\n\t.cn-register-mapping__register-select {\n\t\tmax-width: none;\n\t}\n}\n</style>\n"],"names":["CnSettingsSection","CnStatusBadge","t","n"],"mappings":"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"}