@conduction/nextcloud-vue 2.109.0 → 2.111.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 (47) hide show
  1. package/dist/esm/components/CnActionDialog/CnActionDialog.vue.js +1 -1
  2. package/dist/esm/components/CnActionDialog/CnActionDialog.vue2.js +115 -12
  3. package/dist/esm/components/CnActionDialog/CnActionDialog.vue2.js.map +1 -1
  4. package/dist/esm/components/CnActionDialog/CnActionDialog.vue3.js +36 -9
  5. package/dist/esm/components/CnActionDialog/CnActionDialog.vue3.js.map +1 -1
  6. package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js +2 -1
  7. package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js.map +1 -1
  8. package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js.map +1 -1
  9. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +20 -0
  10. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
  11. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js +68 -61
  12. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
  13. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +37 -12
  14. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  15. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  16. package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue2.js.map +1 -1
  17. package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue3.js +1 -1
  18. package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue3.js.map +1 -1
  19. package/dist/esm/components/CnWorkQueue/CnWorkQueue.vue.js +1 -1
  20. package/dist/esm/components/CnWorkQueue/CnWorkQueue.vue2.js +8 -1
  21. package/dist/esm/components/CnWorkQueue/CnWorkQueue.vue2.js.map +1 -1
  22. package/dist/esm/components/CnWorkQueue/CnWorkQueue.vue3.js.map +1 -1
  23. package/dist/esm/library-style.js +1 -1
  24. package/dist/esm/nextcloud-vue.css +131 -64
  25. package/dist/esm/utils/actionsDispatcher.js +5 -2
  26. package/dist/esm/utils/actionsDispatcher.js.map +1 -1
  27. package/dist/esm/utils/savedViewHelpers.js +40 -3
  28. package/dist/esm/utils/savedViewHelpers.js.map +1 -1
  29. package/dist/nextcloud-vue.cjs.js +479 -251
  30. package/dist/nextcloud-vue.cjs.js.map +2 -2
  31. package/dist/nextcloud-vue.css +131 -64
  32. package/package.json +1 -1
  33. package/src/components/CnActionDialog/CnActionDialog.vue +134 -13
  34. package/src/components/CnAppRoot/CnAppRoot.vue +2 -1
  35. package/src/components/CnDetailPage/CnDetailPage.vue +35 -11
  36. package/src/components/CnIndexPage/CnIndexPage.md +1 -1
  37. package/src/components/CnIndexPage/CnIndexPage.vue +37 -12
  38. package/src/components/CnIndexSidebar/CnIndexSidebar.md +1 -1
  39. package/src/components/CnIndexSidebar/CnIndexSidebar.vue +2 -2
  40. package/src/components/CnWorkQueue/CnWorkQueue.vue +8 -1
  41. package/src/css/board.css +5 -2
  42. package/src/css/look-board-detail.css +19 -7
  43. package/src/css/look-board-index.css +14 -10
  44. package/src/css/look-board-reports.css +1 -1
  45. package/src/css/look-board.css +54 -9
  46. package/src/utils/actionsDispatcher.js +4 -1
  47. package/src/utils/savedViewHelpers.js +39 -2
@@ -60,7 +60,7 @@
60
60
  height: var(--cn-board-control-height) !important;
61
61
  min-height: var(--cn-board-control-height) !important;
62
62
  padding: 0 14px !important;
63
- border: 1px solid var(--color-border-dark) !important;
63
+ border: 1px solid var(--cn-board-control-border) !important;
64
64
  border-radius: var(--cn-board-control-radius) !important;
65
65
  background: var(--color-main-background) !important;
66
66
  color: var(--color-main-text) !important;
@@ -184,7 +184,7 @@
184
184
  min-height: 38px;
185
185
  margin: 0;
186
186
  padding: 0 14px;
187
- border: 1px solid var(--color-border-dark);
187
+ border: 1px solid var(--cn-board-control-border);
188
188
  border-radius: 19px;
189
189
  background: var(--color-main-background);
190
190
  color: var(--color-main-text);
@@ -226,20 +226,22 @@
226
226
  padding: 1px 7px;
227
227
  border: 0;
228
228
  border-radius: 10px;
229
+ --nldesign-color-on-surface: var(--cn-board-text-soft);
229
230
  background: var(--color-border);
230
231
  color: var(--cn-board-text-soft);
231
232
  font-size: 12px;
232
233
  font-weight: 600;
233
- line-height: 1.4;
234
+ /* 16px tall on its 1px pad, as the boards draw it (DqTaken, DqWerkbord).
235
+ @spec openspec/changes/board-pill-tones/specs/board-pill-tones/spec.md#requirement-a-board-count-is-16px-tall */
236
+ line-height: 14px;
234
237
  }
235
238
 
236
239
  .cn-look-board .cn-saved-views__chip--selected .cn-saved-views__chip-count,
237
- /* On the selected chip the count is a lighter bubble on the dark chip
238
- (DqZaken: #3d4047 on #1b1c1d); --cn-board-text-soft resolves to the main
239
- text, the chip's own colour, which hid the bubble. */
240
+ /* On the selected chip the count is the soft ink as a lighter bubble on the
241
+ dark chip (DqZaken: #3d4047 on #1b1c1d). */
240
242
  .cn-look-board .cn-quick-filter-bar .cn-quick-filter-bar__tab--active .cn-quick-filter-bar__count {
241
243
  --nldesign-color-on-surface: var(--color-primary-element-text);
242
- background: color-mix(in srgb, var(--color-main-background) 15%, var(--color-main-text));
244
+ background: var(--cn-board-text-soft);
243
245
  color: var(--color-primary-element-text);
244
246
  }
245
247
 
@@ -288,7 +290,7 @@
288
290
  --nldesign-component-button-font-weight: 600;
289
291
  --nldesign-component-button-secondary-action-color: var(--color-main-text);
290
292
  --nldesign-component-button-secondary-action-background-color: var(--color-main-background);
291
- --nldesign-component-button-secondary-action-border-color: var(--color-border-dark);
293
+ --nldesign-component-button-secondary-action-border-color: var(--cn-board-control-border);
292
294
  --nldesign-component-button-secondary-action-hover-background-color: var(--color-background-hover);
293
295
  }
294
296
 
@@ -315,6 +317,8 @@
315
317
  margin-inline-start: 6px;
316
318
  padding: 0 6px;
317
319
  border-radius: 10px;
320
+ /* A theme that forces the body ink onto every span reads it from here. */
321
+ --nldesign-color-on-surface: var(--color-primary-element-text);
318
322
  background: var(--color-primary-element);
319
323
  color: var(--color-primary-element-text);
320
324
  font-size: 12px;
@@ -423,7 +427,7 @@
423
427
  height: 40px;
424
428
  padding-block: 0;
425
429
  padding-inline: 38px 12px !important;
426
- border: 1px solid var(--color-border-dark);
430
+ border: 1px solid var(--cn-board-control-border);
427
431
  border-radius: 8px;
428
432
  font-size: 14px;
429
433
  }
@@ -800,7 +804,7 @@
800
804
  height: 34px !important;
801
805
  min-height: 34px !important;
802
806
  padding: 0 !important;
803
- border: 1px solid var(--color-border-dark) !important;
807
+ border: 1px solid var(--cn-board-control-border) !important;
804
808
  border-radius: 8px !important;
805
809
  color: var(--cn-board-text-soft) !important;
806
810
  }
@@ -150,7 +150,7 @@
150
150
  height: var(--cn-board-control-height) !important;
151
151
  min-height: var(--cn-board-control-height) !important;
152
152
  padding: 0 14px !important;
153
- border: 1px solid var(--color-border-dark) !important;
153
+ border: 1px solid var(--cn-board-control-border) !important;
154
154
  border-radius: var(--cn-board-control-radius) !important;
155
155
  background: var(--color-main-background) !important;
156
156
  color: var(--color-main-text) !important;
@@ -24,14 +24,19 @@
24
24
  /* Buttons and inputs. */
25
25
  --cn-board-control-height: 40px;
26
26
  --cn-board-control-radius: 8px;
27
+ /* A control's edge: 3:1 against every ground a control sits on (WCAG
28
+ 1.4.11). Nextcloud's border-dark is a hairline (#dbdbdb, 1.4:1); its
29
+ max-contrast border is the control step, and a theme sets both. */
30
+ --cn-board-control-border: var(--color-border-maxcontrast);
27
31
  /* Cards. */
28
32
  --cn-board-card-radius: 12px;
29
33
  --cn-board-card-padding: 20px 22px;
30
34
  /* The side inset of a dashboard card: its title and its rows. */
31
35
  --cn-board-dashboard-card-inset: 24px;
32
- /* Hairline inside a card, and the soft secondary text. */
36
+ /* Hairline inside a card, and the soft secondary text: the boards' #3d4047,
37
+ between the main text and the muted text, so it follows a theme's pair. */
33
38
  --cn-board-hairline: var(--color-border);
34
- --cn-board-text-soft: var(--color-main-text);
39
+ --cn-board-text-soft: color-mix(in srgb, var(--color-main-text) 45%, var(--color-text-maxcontrast));
35
40
  }
36
41
 
37
42
  /*
@@ -183,6 +188,37 @@
183
188
  --font-weight-element: 600;
184
189
  }
185
190
 
191
+ /* ---- A button with an icon and a label --------------------------------- */
192
+ /* The boards draw it 14px in at both sides with 14px text and a 16px icon
193
+ 8px from its label (DqZaakEmail "Notitie toevoegen", DqVthInstellingen
194
+ "Regel toevoegen"). NcButton pads its start 4px and its end 12px, and puts
195
+ a 20px icon in a 30px slot. The rules hold the condition in `:where()`, so
196
+ they weigh (0,3,0): enough to outrank NcButton's own (0,2,0), and less than
197
+ any surface rule (header, toolbar, follow pill, Meer chevron, tab strip),
198
+ which keeps its own value. The padding goes through NcButton's
199
+ `--button-padding`, so a surface that sets `padding` is never contested.
200
+ @spec openspec/changes/board-icon-label-button/specs/board-icon-label-button/spec.md#requirement-a-board-button-with-an-icon-and-a-label-is-padded-as-the-boards-draw-it */
201
+ .cn-look-board .button-vue.button-vue:where(:has(> .button-vue__wrapper > .button-vue__icon:not(:empty)):has(> .button-vue__wrapper > .button-vue__text:not(:empty)):not(.cn-look-nextcloud *):not(.vue-crumb *)) {
202
+ --button-padding: 14px;
203
+ font-size: 14px;
204
+ }
205
+
206
+ .cn-look-board :where(.button-vue:has(> .button-vue__wrapper > .button-vue__icon:not(:empty)):has(> .button-vue__wrapper > .button-vue__text:not(:empty)):not(.cn-look-nextcloud *):not(.vue-crumb *)) .button-vue__wrapper.button-vue__wrapper {
207
+ gap: 8px;
208
+ }
209
+
210
+ .cn-look-board :where(.button-vue:has(> .button-vue__wrapper > .button-vue__icon:not(:empty)):has(> .button-vue__wrapper > .button-vue__text:not(:empty)):not(.cn-look-nextcloud *):not(.vue-crumb *)) .button-vue__icon.button-vue__icon {
211
+ width: 16px;
212
+ min-width: 16px;
213
+ height: 16px;
214
+ min-height: 16px;
215
+ }
216
+
217
+ .cn-look-board :where(.button-vue:has(> .button-vue__wrapper > .button-vue__icon:not(:empty)):has(> .button-vue__wrapper > .button-vue__text:not(:empty)):not(.cn-look-nextcloud *):not(.vue-crumb *)) .button-vue__icon svg {
218
+ width: 16px;
219
+ height: 16px;
220
+ }
221
+
186
222
  /* ---- The header button ------------------------------------------------- */
187
223
  .cn-look-board .cn-index-page__header-buttons:not(.cn-look-nextcloud *),
188
224
  .cn-look-board .cn-detail-page__header-actions:not(.cn-look-nextcloud *),
@@ -212,7 +248,7 @@
212
248
  --nldesign-component-button-primary-action-font-weight: 600;
213
249
  --nldesign-component-button-secondary-action-color: var(--color-main-text);
214
250
  --nldesign-component-button-secondary-action-background-color: var(--color-main-background);
215
- --nldesign-component-button-secondary-action-border-color: var(--color-border-dark);
251
+ --nldesign-component-button-secondary-action-border-color: var(--cn-board-control-border);
216
252
  --nldesign-component-button-secondary-action-hover-background-color: var(--color-background-hover);
217
253
  }
218
254
 
@@ -226,7 +262,7 @@
226
262
  min-height: var(--cn-board-control-height);
227
263
  padding: 0 14px;
228
264
  gap: 8px;
229
- border: 1px solid var(--color-border-dark);
265
+ border: 1px solid var(--cn-board-control-border);
230
266
  border-radius: var(--cn-board-control-radius);
231
267
  background: var(--color-main-background);
232
268
  color: var(--color-main-text);
@@ -258,7 +294,7 @@
258
294
  height: var(--cn-board-control-height);
259
295
  min-height: var(--cn-board-control-height);
260
296
  padding: 0 14px;
261
- border: 1px solid var(--color-border-dark);
297
+ border: 1px solid var(--cn-board-control-border);
262
298
  border-radius: var(--cn-board-control-radius);
263
299
  background: var(--color-main-background);
264
300
  color: var(--color-main-text);
@@ -266,8 +302,9 @@
266
302
  font-weight: 600;
267
303
  }
268
304
 
269
- /* Buttons 10px apart, each icon 16px with 8px to its label (DqZaak's header,
270
- DqZaken's "Downloaden"); NcButton draws a 20px icon in a 30px slot. */
305
+ /* Buttons 10px apart, each icon 16px (DqZaak's header, DqZaken's
306
+ "Downloaden"); NcButton draws a 20px icon in a 30px slot. The 8px to the
307
+ label is the board's icon-and-label gap above. */
271
308
  .cn-look-board .cn-action-buttons:not(.cn-look-nextcloud *) {
272
309
  gap: 10px;
273
310
  }
@@ -277,7 +314,6 @@
277
314
  min-width: 16px;
278
315
  height: 16px;
279
316
  min-height: 16px;
280
- margin-inline-end: 8px;
281
317
  }
282
318
 
283
319
  .cn-look-board .cn-action-buttons .button-vue .button-vue__icon:not(.cn-look-nextcloud *) svg {
@@ -312,7 +348,7 @@
312
348
  body ink onto every span (thematiq). */
313
349
  .cn-look-board .action-item.action-item--secondary .action-item__menutoggle.button-vue--secondary:not(.cn-look-nextcloud *) {
314
350
  --nldesign-color-on-surface: var(--color-main-text);
315
- border: 1px solid var(--color-border-dark);
351
+ border: 1px solid var(--cn-board-control-border);
316
352
  border-radius: var(--cn-board-control-radius);
317
353
  background: var(--color-main-background);
318
354
  color: var(--color-main-text);
@@ -1109,6 +1145,15 @@
1109
1145
  line-height: normal;
1110
1146
  }
1111
1147
 
1148
+ /* A neutral board tag ("Normaal", "Uit") is the soft text on the chip ground,
1149
+ not the main text on the darker background a Nextcloud tag takes.
1150
+ @spec openspec/changes/board-pill-tones/specs/board-pill-tones/spec.md#requirement-a-neutral-board-tag-is-soft-text-on-the-chip-ground */
1151
+ .cn-look-board .cn-status-badge--default:not(.cn-status-badge--solid):not(.cn-look-nextcloud *) {
1152
+ --cn-status-badge-ink: var(--cn-board-text-soft);
1153
+ background-color: var(--color-background-hover);
1154
+ color: var(--cn-status-badge-ink);
1155
+ }
1156
+
1112
1157
  /* A pill paints its own pairing of ink and fill. A theme that forces the body
1113
1158
  ink onto every span (thematiq's text rule, `!important` at id level) reads
1114
1159
  that ink from --nldesign-color-on-surface when the surface sets it, so the
@@ -857,7 +857,10 @@ export function dispatchAction(action, context = {}) {
857
857
  return
858
858
  }
859
859
 
860
- context.openModal(target, action.props ?? {})
860
+ // A prop that is exactly a token (`"objectId": "@objectId"`) resolves
861
+ // against the page's object; one the page cannot answer stays as written.
862
+ const props = context.tokenCtx ? resolveDeepTokens(action.props ?? {}, context.tokenCtx) : (action.props ?? {})
863
+ context.openModal(target, props)
861
864
  break
862
865
  }
863
866
 
@@ -284,15 +284,18 @@ export function schemaSlug(schema) {
284
284
  * it: three case indexes share their views, the organisations index does
285
285
  * not. `savedViewsScope` on a page overrides that, for pages that should
286
286
  * share views although they read different sources, or keep them apart
287
- * although they read the same one.
287
+ * although they read the same one. A page over a named source
288
+ * (`entitySource`) and no schema shares its views with the pages over that
289
+ * source.
288
290
  *
289
291
  * @param {object} page The page.
290
292
  * @param {string} [page.scope] The explicit `savedViewsScope`, when set.
291
293
  * @param {string} [page.register] The page's register.
292
294
  * @param {object|string} [page.schema] The page's schema, slug or object.
295
+ * @param {string} [page.source] The page's `entitySource`, when it reads one.
293
296
  * @return {string} The scope key, or the empty string for a page with no source.
294
297
  */
295
- export function savedViewScope({ scope, register, schema } = {}) {
298
+ export function savedViewScope({ scope, register, schema, source } = {}) {
296
299
  if (typeof scope === 'string' && scope !== '') {
297
300
  return scope
298
301
  }
@@ -300,9 +303,43 @@ export function savedViewScope({ scope, register, schema } = {}) {
300
303
  if (typeof register === 'string' && register !== '' && slug !== '') {
301
304
  return `${register}/${slug}`
302
305
  }
306
+ if (typeof source === 'string' && source !== '') {
307
+ return `source:${source}`
308
+ }
303
309
  return ''
304
310
  }
305
311
 
312
+ /**
313
+ * Whether an index page offers saved views in its sidebar.
314
+ *
315
+ * `allowSavedViews` decides when it is set. Unset, every index page that has
316
+ * a sidebar and a source a view can be scoped to (a register and schema, a
317
+ * named source, or `savedViewsScope`) offers them, so managing views is
318
+ * there on every list without each page opting in.
319
+ *
320
+ * @param {object} config The page's index config, or CnIndexPage's props.
321
+ * @param {boolean|null} [config.allowSavedViews] The explicit choice, when made.
322
+ * @param {object} [config.sidebar] The sidebar config.
323
+ * @param {string} [config.savedViewsScope] The explicit scope.
324
+ * @param {string} [config.register] The register.
325
+ * @param {object|string} [config.schema] The schema.
326
+ * @param {string} [config.entitySource] The named source.
327
+ * @return {boolean}
328
+ */
329
+ export function pageOffersSavedViews(config) {
330
+ if (!config || typeof config !== 'object') {
331
+ return false
332
+ }
333
+ if (typeof config.allowSavedViews === 'boolean') {
334
+ return config.allowSavedViews
335
+ }
336
+ const sidebar = config.sidebar
337
+ if (!sidebar || typeof sidebar !== 'object' || sidebar.enabled !== true || sidebar.show === false) {
338
+ return false
339
+ }
340
+ return savedViewScope({ scope: config.savedViewsScope, register: config.register, schema: config.schema, source: config.entitySource }) !== ''
341
+ }
342
+
306
343
  /**
307
344
  * Whether a saved view belongs on a page.
308
345
  *