@conduction/nextcloud-vue 2.97.0 → 2.99.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 (160) hide show
  1. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue2.js +12 -0
  2. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue2.js.map +1 -1
  3. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue3.js +11 -2
  4. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue3.js.map +1 -1
  5. package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js +17 -0
  6. package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js.map +1 -1
  7. package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js.map +1 -1
  8. package/dist/esm/components/CnBreadcrumbs/CnBreadcrumbs.vue.js +1 -1
  9. package/dist/esm/components/CnBreadcrumbs/CnBreadcrumbs.vue2.js.map +1 -1
  10. package/dist/esm/components/CnBreadcrumbs/CnBreadcrumbs.vue3.js +1 -1
  11. package/dist/esm/components/CnBreadcrumbs/CnBreadcrumbs.vue3.js.map +1 -1
  12. package/dist/esm/components/CnChartWidget/CnChartWidget.vue.js +1 -1
  13. package/dist/esm/components/CnChartWidget/CnChartWidget.vue2.js +106 -2
  14. package/dist/esm/components/CnChartWidget/CnChartWidget.vue2.js.map +1 -1
  15. package/dist/esm/components/CnChartWidget/CnChartWidget.vue3.js.map +1 -1
  16. package/dist/esm/components/CnChecklistRunWidget/CnChecklistRunWidget.vue.js +9 -0
  17. package/dist/esm/components/CnChecklistRunWidget/CnChecklistRunWidget.vue.js.map +1 -0
  18. package/dist/esm/components/CnChecklistRunWidget/CnChecklistRunWidget.vue2.js +964 -0
  19. package/dist/esm/components/CnChecklistRunWidget/CnChecklistRunWidget.vue2.js.map +1 -0
  20. package/dist/esm/components/CnChecklistRunWidget/CnChecklistRunWidget.vue3.js +282 -0
  21. package/dist/esm/components/CnChecklistRunWidget/CnChecklistRunWidget.vue3.js.map +1 -0
  22. package/dist/esm/components/CnChecklistRunWidget/index.js +28 -0
  23. package/dist/esm/components/CnChecklistRunWidget/index.js.map +1 -0
  24. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue.js +1 -1
  25. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +1 -0
  26. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
  27. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
  28. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +26 -8
  29. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
  30. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
  31. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +188 -5
  32. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
  33. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js +2 -1
  34. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
  35. package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue.js +1 -1
  36. package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue2.js +3 -3
  37. package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue2.js.map +1 -1
  38. package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue3.js.map +1 -1
  39. package/dist/esm/components/CnFeaturesBoard/CnFeaturesBoard.vue.js +1 -1
  40. package/dist/esm/components/CnFeaturesBoard/CnFeaturesBoard.vue2.js +27 -0
  41. package/dist/esm/components/CnFeaturesBoard/CnFeaturesBoard.vue2.js.map +1 -1
  42. package/dist/esm/components/CnFeaturesBoard/CnFeaturesBoard.vue3.js +16 -2
  43. package/dist/esm/components/CnFeaturesBoard/CnFeaturesBoard.vue3.js.map +1 -1
  44. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +43 -3
  45. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  46. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  47. package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue.js +9 -0
  48. package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue.js.map +1 -0
  49. package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue2.js +239 -0
  50. package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue2.js.map +1 -0
  51. package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue3.js +182 -0
  52. package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue3.js.map +1 -0
  53. package/dist/esm/components/CnSettingsField/CnSettingsField.vue.js +9 -0
  54. package/dist/esm/components/CnSettingsField/CnSettingsField.vue.js.map +1 -0
  55. package/dist/esm/components/CnSettingsField/CnSettingsField.vue2.js +265 -0
  56. package/dist/esm/components/CnSettingsField/CnSettingsField.vue2.js.map +1 -0
  57. package/dist/esm/components/CnSettingsField/CnSettingsField.vue3.js +191 -0
  58. package/dist/esm/components/CnSettingsField/CnSettingsField.vue3.js.map +1 -0
  59. package/dist/esm/components/CnSettingsFieldsSection/CnSettingsFieldsSection.vue.js +9 -0
  60. package/dist/esm/components/CnSettingsFieldsSection/CnSettingsFieldsSection.vue.js.map +1 -0
  61. package/dist/esm/components/CnSettingsFieldsSection/CnSettingsFieldsSection.vue2.js +508 -0
  62. package/dist/esm/components/CnSettingsFieldsSection/CnSettingsFieldsSection.vue2.js.map +1 -0
  63. package/dist/esm/components/CnSettingsFieldsSection/CnSettingsFieldsSection.vue3.js +99 -0
  64. package/dist/esm/components/CnSettingsFieldsSection/CnSettingsFieldsSection.vue3.js.map +1 -0
  65. package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue.js +1 -1
  66. package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue2.js +18 -70
  67. package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue2.js.map +1 -1
  68. package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue3.js +6 -44
  69. package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue3.js.map +1 -1
  70. package/dist/esm/components/CnUserSettingsDialog/CnUserSettingsDialog.vue.js +1 -1
  71. package/dist/esm/components/CnUserSettingsDialog/CnUserSettingsDialog.vue2.js +83 -9
  72. package/dist/esm/components/CnUserSettingsDialog/CnUserSettingsDialog.vue2.js.map +1 -1
  73. package/dist/esm/components/CnUserSettingsDialog/CnUserSettingsDialog.vue3.js +80 -11
  74. package/dist/esm/components/CnUserSettingsDialog/CnUserSettingsDialog.vue3.js.map +1 -1
  75. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +2 -0
  76. package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
  77. package/dist/esm/components/CnWorkingCalendarWidget/CnWorkingCalendarWidget.vue.js +9 -0
  78. package/dist/esm/components/CnWorkingCalendarWidget/CnWorkingCalendarWidget.vue.js.map +1 -0
  79. package/dist/esm/components/CnWorkingCalendarWidget/CnWorkingCalendarWidget.vue2.js +472 -0
  80. package/dist/esm/components/CnWorkingCalendarWidget/CnWorkingCalendarWidget.vue2.js.map +1 -0
  81. package/dist/esm/components/CnWorkingCalendarWidget/CnWorkingCalendarWidget.vue3.js +231 -0
  82. package/dist/esm/components/CnWorkingCalendarWidget/CnWorkingCalendarWidget.vue3.js.map +1 -0
  83. package/dist/esm/components/CnWorkingCalendarWidget/index.js +27 -0
  84. package/dist/esm/components/CnWorkingCalendarWidget/index.js.map +1 -0
  85. package/dist/esm/composables/indexSources.js +238 -2
  86. package/dist/esm/composables/indexSources.js.map +1 -1
  87. package/dist/esm/composables/useFlowStore.js +2 -1
  88. package/dist/esm/composables/useFlowStore.js.map +1 -1
  89. package/dist/esm/composables/useOrganisationStore.js +115 -0
  90. package/dist/esm/composables/useOrganisationStore.js.map +1 -0
  91. package/dist/esm/index.js +5 -0
  92. package/dist/esm/index.js.map +1 -1
  93. package/dist/esm/l10n/en.json.js +109 -1
  94. package/dist/esm/l10n/en.json.js.map +1 -1
  95. package/dist/esm/l10n/nl.json.js +138 -1
  96. package/dist/esm/l10n/nl.json.js.map +1 -1
  97. package/dist/esm/library-style.js +1 -1
  98. package/dist/esm/nextcloud-vue.css +1071 -274
  99. package/dist/esm/utils/builtInFormatters.js +34 -1
  100. package/dist/esm/utils/builtInFormatters.js.map +1 -1
  101. package/dist/esm/utils/libraryWidgetKeys.js +2 -0
  102. package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
  103. package/dist/esm/utils/matrixCells.js +158 -0
  104. package/dist/esm/utils/matrixCells.js.map +1 -0
  105. package/dist/esm/utils/nextcloudDirectory.js +121 -0
  106. package/dist/esm/utils/nextcloudDirectory.js.map +1 -0
  107. package/dist/esm/utils/validateManifestV2.compiled.js +3 -3
  108. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  109. package/dist/esm/utils/workingCalendarMonth.js +85 -0
  110. package/dist/esm/utils/workingCalendarMonth.js.map +1 -0
  111. package/dist/nextcloud-vue.cjs.js +14888 -10014
  112. package/dist/nextcloud-vue.cjs.js.map +2 -2
  113. package/dist/nextcloud-vue.css +1071 -274
  114. package/l10n/en.json +109 -1
  115. package/l10n/nl.json +138 -1
  116. package/package.json +2 -2
  117. package/scripts/merge-l10n.js +196 -0
  118. package/src/components/CnActionsMenu/CnActionsMenu.vue +14 -1
  119. package/src/components/CnAppRoot/CnAppRoot.md +1 -0
  120. package/src/components/CnAppRoot/CnAppRoot.vue +17 -0
  121. package/src/components/CnBreadcrumbs/CnBreadcrumbs.vue +1 -0
  122. package/src/components/CnChartWidget/CnChartWidget.md +2 -1
  123. package/src/components/CnChartWidget/CnChartWidget.vue +106 -2
  124. package/src/components/CnChecklistRunWidget/CnChecklistRunWidget.vue +1269 -0
  125. package/src/components/CnChecklistRunWidget/index.js +27 -0
  126. package/src/components/CnDashboardPage/CnDashboardPage.vue +1 -0
  127. package/src/components/CnDataTable/CnDataTable.vue +26 -8
  128. package/src/components/CnDetailPage/CnDetailPage.md +48 -0
  129. package/src/components/CnDetailPage/CnDetailPage.vue +189 -5
  130. package/src/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue +3 -3
  131. package/src/components/CnFeaturesBoard/CnFeaturesBoard.vue +38 -2
  132. package/src/components/CnIndexPage/CnIndexPage.md +28 -0
  133. package/src/components/CnIndexPage/CnIndexPage.vue +43 -3
  134. package/src/components/CnOrderedListField/CnOrderedListField.vue +458 -0
  135. package/src/components/CnOrderedListField/index.js +7 -0
  136. package/src/components/CnSettingsField/CnSettingsField.vue +449 -0
  137. package/src/components/CnSettingsField/index.js +4 -0
  138. package/src/components/CnSettingsFieldsSection/CnSettingsFieldsSection.vue +613 -0
  139. package/src/components/CnSettingsFieldsSection/index.js +4 -0
  140. package/src/components/CnSettingsPage/CnSettingsPage.vue +6 -86
  141. package/src/components/CnUserSettingsDialog/CnUserSettingsDialog.vue +139 -10
  142. package/src/components/CnWidgetGrid/registerDashboardWidgets.js +2 -0
  143. package/src/components/CnWorkingCalendarWidget/CnWorkingCalendarWidget.vue +725 -0
  144. package/src/components/CnWorkingCalendarWidget/index.js +26 -0
  145. package/src/components/index.js +5 -0
  146. package/src/composables/indexSources.js +237 -1
  147. package/src/composables/useFlowStore.js +2 -1
  148. package/src/composables/useOrganisationStore.js +111 -0
  149. package/src/css/badge.css +32 -16
  150. package/src/css/look-board-detail.css +80 -8
  151. package/src/css/look-board-index.css +52 -8
  152. package/src/css/look-board.css +219 -1
  153. package/src/index.js +5 -0
  154. package/src/schemas/app-manifest-v2.schema.json +33 -3
  155. package/src/utils/builtInFormatters.js +33 -0
  156. package/src/utils/libraryWidgetKeys.js +2 -0
  157. package/src/utils/matrixCells.js +154 -0
  158. package/src/utils/nextcloudDirectory.js +117 -0
  159. package/src/utils/validateManifestV2.compiled.js +3 -3
  160. package/src/utils/workingCalendarMonth.js +82 -0
@@ -152,6 +152,32 @@
152
152
  margin-top: 16px;
153
153
  }
154
154
 
155
+ /* ---- The stages bars (CnStagesWidget `variant: "bars"`) ---------------- */
156
+ /* DqZaak's "Voortgang": the bars sit flush with the content edge (the
157
+ widget's 4px pad is room for the 32px circles, which the bars variant does
158
+ not draw), the label 8px under its bar and the date 8px under the label at
159
+ the normal line height, open steps muted and the done and current ones in
160
+ the main text. Each hands its ink to --nldesign-color-on-surface, which a
161
+ theme that forces the body ink onto every span (thematiq) reads instead. */
162
+ .cn-look-board .cn-stages-widget:has(> .cn-stages-widget__bars):not(.cn-look-nextcloud *) {
163
+ padding: 0;
164
+ }
165
+
166
+ .cn-look-board .cn-stages-widget__bars .cn-stages-widget__bar-label:not(.cn-look-nextcloud *) {
167
+ --nldesign-color-on-surface: var(--color-text-maxcontrast);
168
+ line-height: normal;
169
+ }
170
+
171
+ .cn-look-board .cn-stages-widget__bars .cn-stages-widget__bar-step--done .cn-stages-widget__bar-label:not(.cn-look-nextcloud *),
172
+ .cn-look-board .cn-stages-widget__bars .cn-stages-widget__bar-step--current .cn-stages-widget__bar-label:not(.cn-look-nextcloud *) {
173
+ --nldesign-color-on-surface: var(--color-main-text);
174
+ }
175
+
176
+ .cn-look-board .cn-stages-widget__bars .cn-stages-widget__bar-date:not(.cn-look-nextcloud *) {
177
+ --nldesign-color-on-surface: var(--color-text-maxcontrast);
178
+ line-height: normal;
179
+ }
180
+
155
181
  /* ---- The body and the side column ------------------------------------- */
156
182
 
157
183
  .cn-look-board.cn-detail-page--with-side {
@@ -185,6 +211,7 @@
185
211
  The open tab overlaps that top border by 1px (the nav's -1px margin) and
186
212
  paints over it, so it flows into the card as a folder tab. */
187
213
  .cn-look-board .cn-tabs--board .cn-tabs__bar {
214
+ align-items: flex-end;
188
215
  border-bottom: none;
189
216
  gap: 4px;
190
217
  position: relative;
@@ -227,6 +254,9 @@
227
254
  row-gap: 4px;
228
255
  }
229
256
 
257
+ /* `margin: 0`: a tab is a <button>, and Nextcloud's core stylesheet gives
258
+ every `button:not(.button-vue)` `margin: 3px 3px 3px 0`, which put the strip
259
+ 3px low and the tabs 7px apart instead of 4 (DqZaak "Zaakonderdelen"). */
230
260
  .cn-look-board .cn-tabs--board .cn-tabs__nav-item {
231
261
  background-color: var(--color-background-dark);
232
262
  border: 1px solid var(--color-border-dark);
@@ -234,6 +264,7 @@
234
264
  border-radius: 8px 8px 0 0;
235
265
  font-size: 14px;
236
266
  font-weight: 400;
267
+ margin: 0;
237
268
  min-height: 34px;
238
269
  padding: 8px 12px;
239
270
  }
@@ -267,9 +298,12 @@
267
298
  padding: 0 6px;
268
299
  }
269
300
 
270
- /* The Actions button at the end of the strip, level with the tabs. */
301
+ /* The Actions button at the end of the strip: at the top, 8px in from the
302
+ end and 8px clear of the card, so the tabs, aligned to the bottom, sit 6px
303
+ lower than the button (DqZaak "Acties"). */
271
304
  .cn-look-board .cn-tabs--board .cn-tabs__nav-end {
272
305
  align-self: flex-start;
306
+ margin: 0 8px 8px 0;
273
307
  }
274
308
 
275
309
  .cn-look-board .cn-tabs--board .cn-tabs__nav-end .button-vue {
@@ -327,21 +361,26 @@
327
361
 
328
362
  /* ---- Body cards and side cards ----------------------------------------- */
329
363
 
364
+ /* A CnDetailCard takes the board card wherever it sits, not only on a detail
365
+ page: a dashboard or a custom page that mounts one drew the Nextcloud card
366
+ (a 12px 16px header over a rule). The doubled class keeps the specificity
367
+ the page-scoped rule had. */
368
+
330
369
  .cn-look-board .cn-detail-page .cn-widget-wrapper,
331
- .cn-look-board .cn-detail-page .cn-detail-card {
370
+ .cn-look-board .cn-detail-card.cn-detail-card:not(.cn-detail-card--chromeless) {
332
371
  background: var(--color-main-background);
333
372
  border: 1px solid var(--color-border);
334
373
  border-radius: var(--cn-board-card-radius);
335
374
  }
336
375
 
337
376
  .cn-look-board .cn-detail-page .cn-widget-wrapper__header,
338
- .cn-look-board .cn-detail-page .cn-detail-card__header {
377
+ .cn-look-board .cn-detail-card .cn-detail-card__header {
339
378
  border-bottom: none;
340
379
  padding: 20px 22px 0;
341
380
  }
342
381
 
343
382
  .cn-look-board .cn-detail-page .cn-widget-wrapper__title,
344
- .cn-look-board .cn-detail-page .cn-detail-card__title {
383
+ .cn-look-board .cn-detail-card .cn-detail-card__title {
345
384
  font-size: var(--cn-board-heading-size);
346
385
  font-weight: 700;
347
386
  line-height: 1.3;
@@ -351,7 +390,7 @@
351
390
  padding: 12px 22px 20px;
352
391
  }
353
392
 
354
- .cn-look-board .cn-detail-page .cn-detail-card__content {
393
+ .cn-look-board .cn-detail-card .cn-detail-card__content {
355
394
  padding: 12px 22px 20px;
356
395
  }
357
396
 
@@ -398,10 +437,12 @@
398
437
  font-weight: 500;
399
438
  }
400
439
 
401
- /* Side cards: the heading is a 15px muted label, not a title. */
440
+ /* Side cards: the heading is a 15px muted label, not a title. The tone
441
+ carries `!important` against a theme that colours every h3 that way
442
+ (thematiq's heading colour). */
402
443
  .cn-look-board .cn-detail-page__side .cn-widget-wrapper__title,
403
444
  .cn-look-board .cn-detail-page__side .cn-detail-card__title {
404
- color: var(--color-text-maxcontrast);
445
+ color: var(--color-text-maxcontrast) !important;
405
446
  font-size: var(--cn-board-side-heading-size);
406
447
  font-weight: 600;
407
448
  }
@@ -456,17 +497,23 @@
456
497
 
457
498
  /* ---- The next-step card ------------------------------------------------- */
458
499
 
500
+ /* The board sets the card at the browser's normal line height: a step row is
501
+ the 20px marker, 28px apart (DqZaak "Wat nu?"). */
459
502
  .cn-look-board .cn-next-step-card--board {
460
503
  border-radius: 12px;
461
504
  gap: 16px 32px;
505
+ line-height: normal;
462
506
  padding: 20px 24px 20px 28px;
463
507
  }
464
508
 
509
+ /* The kicker keeps its tone under a theme that colours every h3 with
510
+ `!important` (thematiq's heading colour); only `!important` beats it. */
465
511
  .cn-look-board .cn-next-step-card--board .cn-next-step-card__title.cn-next-step-card__title {
466
- color: var(--color-primary-element-light-text);
512
+ color: var(--color-primary-element-light-text) !important;
467
513
  font-size: 13px !important;
468
514
  font-weight: 700;
469
515
  letter-spacing: 0.06em;
516
+ line-height: normal;
470
517
  text-transform: uppercase;
471
518
  }
472
519
 
@@ -497,11 +544,36 @@
497
544
  padding: 0 20px;
498
545
  }
499
546
 
547
+ /* The label alone sets the width (DqZaak: 198px for "Verder met beoordelen"):
548
+ NcButton pads its text 4px a side inside the button's own padding, from a
549
+ rule that reaches it through `:has()`, hence the doubled class. */
550
+ .cn-look-board .cn-next-step-card--board .cn-next-step-card__side .button-vue .button-vue__text.button-vue__text {
551
+ margin-inline: 0;
552
+ padding-inline: 0;
553
+ }
554
+
500
555
  .cn-look-board .cn-next-step-card--board .cn-next-step-card__after {
501
556
  color: var(--color-text-maxcontrast);
502
557
  font-size: 13px;
503
558
  }
504
559
 
560
+ /* Done and open steps are muted, the current one in the main text. Each hands
561
+ its ink to --nldesign-color-on-surface, which a theme that forces the body
562
+ ink onto every li and span (thematiq) reads instead. */
563
+ .cn-look-board .cn-next-step-card--board .cn-next-step-card__item,
564
+ .cn-look-board .cn-next-step-card--board .cn-next-step-card__hint,
565
+ .cn-look-board .cn-next-step-card--board .cn-next-step-card__after {
566
+ --nldesign-color-on-surface: var(--color-text-maxcontrast);
567
+ }
568
+
569
+ .cn-look-board .cn-next-step-card--board .cn-next-step-card__item--current {
570
+ --nldesign-color-on-surface: var(--color-main-text);
571
+ }
572
+
573
+ .cn-look-board .cn-next-step-card--board .cn-next-step-card__item--current .cn-next-step-card__hint {
574
+ --nldesign-color-on-surface: var(--color-text-maxcontrast);
575
+ }
576
+
505
577
  /* ---- History: the activity tab ------------------------------------------ */
506
578
 
507
579
  .cn-look-board .cn-activity-tab--board .cn-activity-tab__board-head {
@@ -184,10 +184,15 @@
184
184
  outline-offset: 2px;
185
185
  }
186
186
 
187
+ /* The selected chip is light on dark, so it hands its ink to
188
+ --nldesign-color-on-surface: thematiq forces the body ink onto every span
189
+ with `!important` and reads it from that property, which left the label
190
+ dark on dark. */
187
191
  .cn-look-board .cn-saved-views__chips .cn-saved-views__chip--selected,
188
192
  .cn-look-board .cn-saved-views__chips .cn-saved-views__chip--selected:hover,
189
193
  .cn-look-board .cn-quick-filter-bar .cn-quick-filter-bar__tab--active,
190
194
  .cn-look-board .cn-quick-filter-bar .cn-quick-filter-bar__tab--active:hover {
195
+ --nldesign-color-on-surface: var(--color-main-background);
191
196
  border-color: transparent;
192
197
  background: var(--color-main-text);
193
198
  color: var(--color-main-background);
@@ -208,8 +213,12 @@
208
213
  }
209
214
 
210
215
  .cn-look-board .cn-saved-views__chip--selected .cn-saved-views__chip-count,
216
+ /* On the selected chip the count is a lighter bubble on the dark chip
217
+ (DqZaken: #3d4047 on #1b1c1d); --cn-board-text-soft resolves to the main
218
+ text, the chip's own colour, which hid the bubble. */
211
219
  .cn-look-board .cn-quick-filter-bar .cn-quick-filter-bar__tab--active .cn-quick-filter-bar__count {
212
- background: var(--cn-board-text-soft);
220
+ --nldesign-color-on-surface: var(--color-primary-element-text);
221
+ background: color-mix(in srgb, var(--color-main-background) 15%, var(--color-main-text));
213
222
  color: var(--color-primary-element-text);
214
223
  }
215
224
 
@@ -481,12 +490,16 @@
481
490
  border-radius: 0;
482
491
  }
483
492
 
484
- /* The header row is near-white on the boards (#fafbfc), not the hover grey. */
493
+ /* The header row is near-white on the boards (#fafbfc), not the hover grey,
494
+ its labels 14px muted. The ink also goes to --nldesign-color-on-surface,
495
+ which a theme that forces the body ink onto every span (thematiq) reads. */
485
496
  .cn-look-board .cn-table-container--board .cn-data-table th {
497
+ --nldesign-color-on-surface: var(--color-text-maxcontrast);
486
498
  padding: 12px 16px;
487
499
  border-bottom: 0;
488
500
  background: var(--cn-board-table-head-bg, color-mix(in srgb, var(--color-background-hover) 40%, var(--color-main-background)));
489
501
  color: var(--color-text-maxcontrast);
502
+ font-size: 14px;
490
503
  font-weight: 600;
491
504
  }
492
505
 
@@ -497,6 +510,20 @@
497
510
  font-size: 14px;
498
511
  }
499
512
 
513
+ /* The board sets its table at the normal line height: a row with a title and
514
+ a secondary line is 66px and the header row 50px (DqZaken). Nextcloud's 1.5
515
+ made them 71px and 67px, and the header's sort button kept the 34px
516
+ clickable area. */
517
+ .cn-look-board .cn-table-container--board .cn-data-table {
518
+ line-height: normal;
519
+ }
520
+
521
+ .cn-look-board .cn-table-container--board .cn-data-table th .cn-table-header__sort {
522
+ min-height: 0;
523
+ height: auto;
524
+ line-height: inherit;
525
+ }
526
+
500
527
  .cn-look-board .cn-table-container--board .cn-data-table .cn-table-row {
501
528
  border-bottom: 0;
502
529
  }
@@ -552,7 +579,9 @@
552
579
  margin-inline-start: 4px;
553
580
  }
554
581
 
555
- /* The selection column: 18px checkboxes, 28px of content after 16px of padding.
582
+ /* The selection column: 18px checkboxes, 28px of content between 16px of
583
+ padding either side, 60px in all (DqZaken and 130 other boards; the title
584
+ column starts 77px in).
556
585
  The box model is set with `!important` and the widths include the padding:
557
586
  Nextcloud's server.css sets `box-sizing: border-box` on everything under
558
587
  `#content[class*="app-"]`, an id selector no class rule outranks, so a plain
@@ -560,9 +589,9 @@
560
589
  header's checkbox showed as a stray bracket). */
561
590
  .cn-look-board .cn-table-container--board .cn-data-table .cn-table-col--checkbox {
562
591
  box-sizing: border-box !important;
563
- width: 44px;
564
- min-width: 44px;
565
- padding-inline: 16px 0;
592
+ width: 60px;
593
+ min-width: 60px;
594
+ padding-inline: 16px;
566
595
  text-align: start;
567
596
  }
568
597
 
@@ -570,6 +599,16 @@
570
599
  --icon-size: 18px;
571
600
  }
572
601
 
602
+ /* The checkbox is the 18px box alone, as the board draws it: NcCheckboxRadioSwitch
603
+ wraps it in a 34px clickable area with 4px 7px of padding, a 42px block that
604
+ set every row's height (71px where DqZaken's rows are 66). The cell around it
605
+ stays the click target's room: 44px wide, a full row high. */
606
+ .cn-look-board .cn-table-container--board .cn-data-table .checkbox-radio-switch .checkbox-radio-switch__content {
607
+ min-height: 0;
608
+ height: auto;
609
+ padding: 0;
610
+ }
611
+
573
612
  /* The title column: a 15px weight 600 link, the secondary line under it. */
574
613
  .cn-look-board .cn-table-container--board .cn-data-table td.cn-table-col--title {
575
614
  color: var(--color-main-text);
@@ -580,6 +619,7 @@
580
619
  }
581
620
 
582
621
  .cn-look-board .cn-table-container--board .cn-data-table td.cn-table-col--title .cn-table-cell__secondary {
622
+ --nldesign-color-on-surface: var(--color-text-maxcontrast);
583
623
  color: var(--color-text-maxcontrast);
584
624
  font-size: 14px;
585
625
  font-weight: 400;
@@ -621,10 +661,14 @@
621
661
  gap: 10px;
622
662
  }
623
663
 
664
+ /* The initials sit on the light primary tint in the primary ink, the board's
665
+ person chip (DqZaken's Behandelaar, and most boards' people). */
624
666
  .cn-look-board .cn-table-container--board .cn-data-table .cn-cell-renderer__avatar-initials {
625
- background: var(--color-background-dark);
626
- color: var(--color-main-text);
667
+ --nldesign-color-on-surface: var(--color-primary-element-light-text);
668
+ background: var(--color-primary-element-light);
669
+ color: var(--color-primary-element-light-text);
627
670
  font-size: 12px;
671
+ font-weight: 700;
628
672
  }
629
673
 
630
674
  .cn-look-board .cn-table-container--board .cn-data-table td.cn-table-col--title .cn-cell-renderer__avatar-name {
@@ -141,6 +141,50 @@
141
141
  color: var(--color-primary-element-text);
142
142
  }
143
143
 
144
+ /* ---- Header action buttons (CnActionButtons) ----------------------------- */
145
+ /* The board draws a page's secondary actions as neutral 40px buttons: the
146
+ main background, a grey border, the main text at 600 (DqZaak "Bericht",
147
+ "Document", "Contact vastleggen", "Bewerken"). Nextcloud's secondary button
148
+ is a primary tint. The label hands its ink to --nldesign-color-on-surface,
149
+ which a theme that forces the body ink onto every span (thematiq) reads. */
150
+ .cn-look-board .cn-action-buttons .button-vue--secondary:not(.cn-look-nextcloud *),
151
+ .cn-look-board .cn-action-buttons .button-vue--vue-secondary:not(.cn-look-nextcloud *) {
152
+ --nldesign-color-on-surface: var(--color-main-text);
153
+ height: var(--cn-board-control-height);
154
+ min-height: var(--cn-board-control-height);
155
+ padding: 0 14px;
156
+ border: 1px solid var(--color-border-dark);
157
+ border-radius: var(--cn-board-control-radius);
158
+ background: var(--color-main-background);
159
+ color: var(--color-main-text);
160
+ font-size: 14px;
161
+ font-weight: 600;
162
+ }
163
+
164
+ /* Buttons 10px apart, each icon 16px with 8px to its label (DqZaak's header,
165
+ DqZaken's "Downloaden"); NcButton draws a 20px icon in a 30px slot. */
166
+ .cn-look-board .cn-action-buttons:not(.cn-look-nextcloud *) {
167
+ gap: 10px;
168
+ }
169
+
170
+ .cn-look-board .cn-action-buttons .button-vue .button-vue__icon:not(.cn-look-nextcloud *) {
171
+ width: 16px;
172
+ min-width: 16px;
173
+ height: 16px;
174
+ min-height: 16px;
175
+ margin-inline-end: 8px;
176
+ }
177
+
178
+ .cn-look-board .cn-action-buttons .button-vue .button-vue__icon:not(.cn-look-nextcloud *) svg {
179
+ width: 16px;
180
+ height: 16px;
181
+ }
182
+
183
+ .cn-look-board .cn-action-buttons .button-vue--secondary:not(.cn-look-nextcloud *):hover,
184
+ .cn-look-board .cn-action-buttons .button-vue--vue-secondary:not(.cn-look-nextcloud *):hover {
185
+ background: var(--color-background-hover);
186
+ }
187
+
144
188
  /* ---- The buildiq square ------------------------------------------------ */
145
189
  .cn-look-board .cn-buildiq-edit .cn-buildiq-edit__actions .button-vue {
146
190
  box-sizing: border-box;
@@ -153,6 +197,34 @@
153
197
  border-radius: var(--cn-board-control-radius);
154
198
  }
155
199
 
200
+ /* ---- The Actions menu trigger (CnActionsMenu) ---------------------------- */
201
+ /* A menu asked for as `secondary` ("Meer" in a detail header, "Acties" at the
202
+ end of a tab strip) is the board's neutral control: the main background, a
203
+ grey border, the main text at 600 (DqZaak), not Nextcloud's primary tint.
204
+ NcActions marks a secondary menu `action-item--secondary` on its root and
205
+ keeps a class given to it off, so the rule reads that marker. The label
206
+ hands its ink to --nldesign-color-on-surface for a theme that forces the
207
+ body ink onto every span (thematiq). */
208
+ .cn-look-board .action-item.action-item--secondary .action-item__menutoggle.button-vue--secondary:not(.cn-look-nextcloud *) {
209
+ --nldesign-color-on-surface: var(--color-main-text);
210
+ border: 1px solid var(--color-border-dark);
211
+ border-radius: var(--cn-board-control-radius);
212
+ background: var(--color-main-background);
213
+ color: var(--color-main-text);
214
+ font-size: 14px;
215
+ font-weight: 600;
216
+ }
217
+
218
+ .cn-look-board .action-item.action-item--secondary .action-item__menutoggle.button-vue--secondary:not(.cn-look-nextcloud *):hover {
219
+ background: var(--color-background-hover);
220
+ }
221
+
222
+ /* A trailing chevron ("Meer ⌄") follows the label, 6px after it. */
223
+ .cn-look-board .action-item.action-item--secondary .action-item__menutoggle:has(.chevron-down-icon) .button-vue__wrapper:not(.cn-look-nextcloud *) {
224
+ flex-direction: row-reverse;
225
+ gap: 6px;
226
+ }
227
+
156
228
  /* ---- The navigation ---------------------------------------------------- */
157
229
  .cn-look-board .app-navigation[data-testid="cn-nav"] {
158
230
  --app-navigation-padding: 0px;
@@ -374,6 +446,71 @@
374
446
  font-weight: 600;
375
447
  }
376
448
 
449
+ /* ---- Breadcrumbs (CnBreadcrumbs) ----------------------------------------- */
450
+ /* The board draws a trail as a line of 14px text, 8px apart: the crumbs that
451
+ lead somewhere as underlined links in the primary colour, the current one
452
+ as plain muted text (DqZaak "Alle zaken / 2026-0082"). NcBreadcrumbs draws
453
+ each crumb as a 34px tertiary button. The doubled classes outrank its
454
+ scoped rules; the ink goes through --nldesign-color-on-surface as well, for
455
+ a theme that forces the body ink onto every link and span (thematiq). */
456
+ .cn-look-board .cn-breadcrumbs.cn-breadcrumbs:not(.cn-look-nextcloud *) {
457
+ min-height: 0;
458
+ height: auto;
459
+ color: var(--color-text-maxcontrast);
460
+ font-size: 14px;
461
+ line-height: normal;
462
+ }
463
+
464
+ .cn-look-board .cn-breadcrumbs .breadcrumb__crumbs:not(.cn-look-nextcloud *) {
465
+ gap: 8px;
466
+ min-height: 0;
467
+ margin: 0;
468
+ padding: 0;
469
+ }
470
+
471
+ .cn-look-board .cn-breadcrumbs .vue-crumb.vue-crumb:not(.cn-look-nextcloud *) {
472
+ gap: 8px;
473
+ min-width: 0;
474
+ min-height: 0;
475
+ height: auto;
476
+ }
477
+
478
+ .cn-look-board .cn-breadcrumbs .vue-crumb .button-vue.button-vue:not(.cn-look-nextcloud *) {
479
+ --nldesign-color-on-surface: var(--color-primary-element);
480
+ min-width: 0;
481
+ min-height: 0;
482
+ height: auto;
483
+ padding: 0;
484
+ border: 0;
485
+ background: transparent;
486
+ color: var(--color-primary-element);
487
+ font-size: 14px;
488
+ font-weight: 400;
489
+ line-height: inherit;
490
+ }
491
+
492
+ .cn-look-board .cn-breadcrumbs .vue-crumb .button-vue.button-vue:not(.cn-look-nextcloud *) .button-vue__text {
493
+ padding: 0;
494
+ font-weight: inherit;
495
+ line-height: inherit;
496
+ text-decoration: underline;
497
+ }
498
+
499
+ .cn-look-board .cn-breadcrumbs .vue-crumb .button-vue.button-vue[aria-current='page']:not(.cn-look-nextcloud *) {
500
+ --nldesign-color-on-surface: var(--color-text-maxcontrast);
501
+ color: var(--color-text-maxcontrast);
502
+ cursor: default;
503
+ }
504
+
505
+ .cn-look-board .cn-breadcrumbs .vue-crumb .button-vue.button-vue[aria-current='page']:not(.cn-look-nextcloud *) .button-vue__text {
506
+ text-decoration: none;
507
+ }
508
+
509
+ .cn-look-board .cn-breadcrumbs .vue-crumb__separator:not(.cn-look-nextcloud *) {
510
+ margin: 0;
511
+ color: var(--color-text-maxcontrast);
512
+ }
513
+
377
514
  /* ---- Settings: header, cards in a grid, version card ------------------- */
378
515
  .cn-look-board .cn-admin-settings-shell__header:not(.cn-look-nextcloud *),
379
516
  .cn-look-board .cn-settings-page__header:not(.cn-look-nextcloud *) {
@@ -792,7 +929,26 @@
792
929
  ground ("Verzoek", "Nieuw"); the default look keeps the brighter
793
930
  primary-element text. The other tones already match the board. */
794
931
  .cn-look-board .cn-status-badge--primary:not(.cn-status-badge--solid):not(.cn-look-nextcloud *) {
795
- color: var(--color-primary-element-light-text);
932
+ --cn-status-badge-ink: var(--color-primary-element-light-text);
933
+ color: var(--cn-status-badge-ink);
934
+ }
935
+
936
+ /* Every board pill is 13px at 600 on a 3px 10px pad with a 12px corner
937
+ (DqZaak's header pills, DqZaken's status column). */
938
+ .cn-look-board .cn-status-badge:not(.cn-status-badge--small):not(.cn-look-nextcloud *) {
939
+ padding: 3px 10px;
940
+ border-radius: 12px;
941
+ font-size: 13px;
942
+ font-weight: 600;
943
+ line-height: normal;
944
+ }
945
+
946
+ /* A pill paints its own pairing of ink and fill. A theme that forces the body
947
+ ink onto every span (thematiq's text rule, `!important` at id level) reads
948
+ that ink from --nldesign-color-on-surface when the surface sets it, so the
949
+ pill hands it its own ink: "In behandeling" stays purple on purple. */
950
+ .cn-look-board .cn-status-badge:not(.cn-look-nextcloud *) {
951
+ --nldesign-color-on-surface: var(--cn-status-badge-ink);
796
952
  }
797
953
 
798
954
  /* ---- Date and age cells (screens-cell-date-parity) ---------------------- */
@@ -802,6 +958,68 @@
802
958
  font-weight: 600;
803
959
  }
804
960
 
961
+ /* ---- Label and value pairs (CnDetailGrid) -------------------------------- */
962
+ /* The board draws pairs as plain text, not as grey cards with an accent bar:
963
+ the grid as a 13px muted label over a 15px value at weight 500 with a
964
+ hairline under each pair (DqZaak "Zaakgegevens"), the horizontal layout as
965
+ two columns of 14px text, the label column as wide as its longest label
966
+ (the side cards). Both at the board's line height, 1.2, not Nextcloud's 1.5:
967
+ a pair is 47px tall on the board. The muted label also hands its ink to
968
+ --nldesign-color-on-surface, which a theme that forces the body ink onto
969
+ every div (thematiq) reads. */
970
+ .cn-look-board .cn-detail-grid.cn-detail-grid--grid:not(.cn-look-nextcloud *) {
971
+ gap: 12px 24px;
972
+ font-size: 15px;
973
+ }
974
+
975
+ .cn-look-board .cn-detail-grid.cn-detail-grid--horizontal:not(.cn-look-nextcloud *) {
976
+ display: grid;
977
+ grid-template-columns: max-content 1fr;
978
+ gap: 8px 16px;
979
+ font-size: 14px;
980
+ }
981
+
982
+ .cn-look-board .cn-detail-grid .cn-detail-grid__item:not(.cn-look-nextcloud *) {
983
+ gap: 3px;
984
+ padding: 0;
985
+ border-inline-start: none;
986
+ border-radius: 0;
987
+ background: none;
988
+ }
989
+
990
+ .cn-look-board .cn-detail-grid.cn-detail-grid--grid .cn-detail-grid__item:not(.cn-look-nextcloud *) {
991
+ padding-bottom: 10px;
992
+ border-bottom: 1px solid var(--cn-board-hairline);
993
+ }
994
+
995
+ .cn-look-board .cn-detail-grid.cn-detail-grid--horizontal .cn-detail-grid__item:not(.cn-look-nextcloud *) {
996
+ display: contents;
997
+ }
998
+
999
+ .cn-look-board .cn-detail-grid .cn-detail-grid__label:not(.cn-look-nextcloud *) {
1000
+ --nldesign-color-on-surface: var(--color-text-maxcontrast);
1001
+ min-width: 0;
1002
+ color: var(--color-text-maxcontrast);
1003
+ font-size: 13px;
1004
+ font-weight: 400;
1005
+ line-height: 1.2;
1006
+ }
1007
+
1008
+ .cn-look-board .cn-detail-grid.cn-detail-grid--horizontal .cn-detail-grid__label:not(.cn-look-nextcloud *) {
1009
+ font-size: inherit;
1010
+ }
1011
+
1012
+ .cn-look-board .cn-detail-grid .cn-detail-grid__value:not(.cn-look-nextcloud *) {
1013
+ margin: 0;
1014
+ font-size: inherit;
1015
+ font-weight: 500;
1016
+ line-height: 1.2;
1017
+ }
1018
+
1019
+ .cn-look-board .cn-detail-grid.cn-detail-grid--horizontal .cn-detail-grid__value:not(.cn-look-nextcloud *) {
1020
+ font-weight: 400;
1021
+ }
1022
+
805
1023
  /* ---- Dashboard card titles --------------------------------------------- */
806
1024
  /* A card's title on a dashboard (and on the widgets under a reports page) is
807
1025
  the board's card h2: 17px weight 700 (boards PqMijnWerk, DcRapportages and
package/src/index.js CHANGED
@@ -59,6 +59,7 @@ export {
59
59
  CnChartWidget,
60
60
  CnChartWidgetForm,
61
61
  CnChatPage,
62
+ CnChecklistRunWidget,
62
63
  CnChildRecordsField,
63
64
  CnChipsFieldWidget,
64
65
  CnChoiceCards,
@@ -236,6 +237,7 @@ export {
236
237
  CnObjectRow,
237
238
  CnObjectSidebar,
238
239
  CnOfflineQueue,
240
+ CnOrderedListField,
239
241
  CnPageHeader,
240
242
  CnPageRenderer,
241
243
  CnPagination,
@@ -278,6 +280,8 @@ export {
278
280
  CnSearchPage,
279
281
  CnSectionsWidget,
280
282
  CnSettingsCard,
283
+ CnSettingsField,
284
+ CnSettingsFieldsSection,
281
285
  CnSettingsFormWidget,
282
286
  CnSettingsPage,
283
287
  CnSettingsSection,
@@ -342,6 +346,7 @@ export {
342
346
  CnWidgetVisibilityRulesModal,
343
347
  CnWidgetWrapper,
344
348
  CnWizardDialog,
349
+ CnWorkingCalendarWidget,
345
350
  CnWorkspaceFilterWidget,
346
351
  DEFAULT_DATE_RANGE_PRESETS,
347
352
  defaultPageTypes,
@@ -3,7 +3,7 @@
3
3
  "$id": "https://raw.githubusercontent.com/ConductionNL/nextcloud-vue/main/src/schemas/app-manifest-v2.schema.json",
4
4
  "title": "Conduction App Manifest v2",
5
5
  "description": "v2 schema for the JSON-driven page and navigation manifest consumed by @conduction/nextcloud-vue. Introduces a uniform widgets[] array on every page type with a per-slot grid coordinate system, a typed actions[] discriminator, and the required $schema field for version detection. v1 manifests continue to validate against app-manifest.schema.json (unchanged).",
6
- "version": "2.121.0",
6
+ "version": "2.122.0",
7
7
  "type": "object",
8
8
  "required": ["$schema", "version"],
9
9
  "allOf": [
@@ -1296,6 +1296,7 @@
1296
1296
  "filter": { "type": "object", "additionalProperties": true }
1297
1297
  }
1298
1298
  },
1299
+ "resolve": { "type": "object", "additionalProperties": false, "required": ["register", "schema"], "description": "detail-pill-resolve: the field holds the id of a record of this register and schema; the pill shows that record's `labelField` (else its title or name) and keys `colorMap` by it. The raw value shows while the lookup runs and when it finds nothing.", "properties": { "register": { "type": "string", "minLength": 1 }, "schema": { "type": "string", "minLength": 1 }, "labelField": { "type": "string", "minLength": 1 } } },
1299
1300
  "countLabel": {
1300
1301
  "type": "object",
1301
1302
  "additionalProperties": false,
@@ -2229,6 +2230,35 @@
2229
2230
  "columnKeys": { "type": "array", "items": { "type": ["string", "number"] } }
2230
2231
  }
2231
2232
  },
2233
+ "cellSource": {
2234
+ "type": "object",
2235
+ "additionalProperties": false,
2236
+ "required": ["register", "schema", "rowField", "columnField", "valueField"],
2237
+ "description": "chartKind 'matrix': read the cells from records that each hold one cell. The records are listed from register/schema with `filter` (tokens such as '@object.matrixVersion' resolved; the list waits while one is unresolved), then laid out by rowField / columnField with valueField as the cell. Labels come from rowLabels / columnLabels maps or rowLabelField / columnLabelField; order from rowOrder / columnOrder lists, else rowOrderField / columnOrderField, else natural order. valueLabels maps a stored value to the text shown; colorMap may key on either. With cellsPath the matrix sits inside ONE record: the first record filter finds (else fallbackFilter), its array at cellsPath narrowed by cellFilter (tokens allowed), and the axis order from rowOrderPath / columnOrderPath on that record. Wins over series / categories.",
2238
+ "properties": {
2239
+ "register": { "type": "string" },
2240
+ "schema": { "type": "string" },
2241
+ "filter": { "type": "object", "additionalProperties": true },
2242
+ "rowField": { "type": "string" },
2243
+ "columnField": { "type": "string" },
2244
+ "valueField": { "type": "string" },
2245
+ "rowLabelField": { "type": "string" },
2246
+ "columnLabelField": { "type": "string" },
2247
+ "rowLabels": { "type": "object", "additionalProperties": { "type": "string" } },
2248
+ "columnLabels": { "type": "object", "additionalProperties": { "type": "string" } },
2249
+ "valueLabels": { "type": "object", "additionalProperties": { "type": "string" } },
2250
+ "rowOrder": { "type": "array", "items": { "type": ["string", "number"] } },
2251
+ "columnOrder": { "type": "array", "items": { "type": ["string", "number"] } },
2252
+ "rowOrderField": { "type": "string" },
2253
+ "columnOrderField": { "type": "string" },
2254
+ "limit": { "type": "integer", "minimum": 1 },
2255
+ "cellsPath": { "type": "string", "description": "Path of the cells array inside the one record the source finds." },
2256
+ "cellFilter": { "type": "object", "additionalProperties": true, "description": "Equality filter on the cells of that record, e.g. { actorType: '@object.actorType' }." },
2257
+ "fallbackFilter": { "type": "object", "additionalProperties": true, "description": "Filter used when `filter` finds no record, e.g. { active: true }." },
2258
+ "rowOrderPath": { "type": "string", "description": "Path of an array on that record giving the row order." },
2259
+ "columnOrderPath": { "type": "string", "description": "Path of an array on that record giving the column order." }
2260
+ }
2261
+ },
2232
2262
  "endpointSource": {
2233
2263
  "$ref": "#/$defs/chartEndpointSource",
2234
2264
  "description": "Wave 2 (#91): endpoint-bound series/labels — the shared endpoint transport plus the labelsPath / series[] {name, path} response mapping. Exactly one of dataSource | endpointSource (post-schema check)."
@@ -3702,8 +3732,8 @@
3702
3732
  },
3703
3733
  "entitySource": {
3704
3734
  "type": "string",
3705
- "enum": ["flows", "flowRuns", "tasks", "endpoint", "search", "users"],
3706
- "description": "Name a registered NON-OBJECT entity collection for a type='index' page, instead of register+schema. Deliberately NOT called `source`: that key is already taken on page config and is polymorphic (a URL string in some manifests, an object with `params` in others), so reusing it would give one key two meanings and break six deployed shillinq pages. A flow definition is deliberately not an OpenRegister object, so an index had nothing to bind to and such lists became bespoke type='custom' pages. With a source the index loads the list itself. Takes precedence over register/schema; non-empty `objects` still wins over both. Registered sources live in src/composables/indexSources.js. `tasks` lists the viewer's task inbox from OpenRegister's flow-tasks read (cn-tasks-entity-source)."
3735
+ "enum": ["flows", "flowRuns", "tasks", "endpoint", "search", "users", "organisations"],
3736
+ "description": "Name a registered NON-OBJECT entity collection for a type='index' page, instead of register+schema. Deliberately NOT called `source`: that key is already taken on page config and is polymorphic (a URL string in some manifests, an object with `params` in others), so reusing it would give one key two meanings and break six deployed shillinq pages. A flow definition is deliberately not an OpenRegister object, so an index had nothing to bind to and such lists became bespoke type='custom' pages. With a source the index loads the list itself. Takes precedence over register/schema; non-empty `objects` still wins over both. Registered sources live in src/composables/indexSources.js. `tasks` lists the viewer's task inbox from OpenRegister's flow-tasks read (cn-tasks-entity-source). `organisations` lists the OpenRegister organisations the viewer belongs to. On a type='detail' page a source that reads one record (today `organisations`) loads the record whose id is the route's objectId, instead of register+schema, and feeds the header, pills, widgets and @objectId / @object.* tokens like a fetched object (organisations-entity-source)."
3707
3737
  },
3708
3738
  "sourceConfig": { "type": "object", "additionalProperties": true, "description": "type='index' with `entitySource`: what the named source loads with. `endpoint`: `url` (an app path, required) and `rowsPath` (default `results`); its other keys go along as query parameters. `search`: `kinds` (`{ id, label, register, schema, titleField?, subtitleField?, statusField?, href?, limit? }` or `{ id, label, files: true }`), `term` and `termQuery` (default `q`). `users`: `defaultGroup`, `functionField`, `rolesField`. `flows` / `tasks`: `app`, `scope`. Maps to CnIndexPage `sourceConfig`.", "properties": { "url": { "type": "string", "minLength": 1 }, "rowsPath": { "type": "string", "minLength": 1 }, "kinds": { "type": "array", "items": { "type": "object", "required": ["id"], "additionalProperties": true, "properties": { "id": { "type": "string", "minLength": 1 }, "label": { "type": "string" }, "register": { "type": "string" }, "schema": { "type": "string" }, "files": { "type": "boolean" } } } }, "term": { "type": "string" }, "termQuery": { "type": "string", "minLength": 1 }, "defaultGroup": { "type": "string", "minLength": 1 } } },
3709
3739
  "app": {