@conduction/nextcloud-vue 2.110.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.
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js +2 -1
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js.map +1 -1
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +20 -0
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js +68 -61
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +37 -12
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue3.js +1 -1
- package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue3.js.map +1 -1
- package/dist/esm/library-style.js +1 -1
- package/dist/esm/nextcloud-vue.css +98 -31
- package/dist/esm/utils/savedViewHelpers.js +40 -3
- package/dist/esm/utils/savedViewHelpers.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +198 -109
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +98 -31
- package/package.json +1 -1
- package/src/components/CnAppRoot/CnAppRoot.vue +2 -1
- package/src/components/CnDetailPage/CnDetailPage.vue +35 -11
- package/src/components/CnIndexPage/CnIndexPage.md +1 -1
- package/src/components/CnIndexPage/CnIndexPage.vue +37 -12
- package/src/components/CnIndexSidebar/CnIndexSidebar.md +1 -1
- package/src/components/CnIndexSidebar/CnIndexSidebar.vue +2 -2
- package/src/css/board.css +5 -2
- package/src/css/look-board-detail.css +19 -7
- package/src/css/look-board-index.css +14 -10
- package/src/css/look-board-reports.css +1 -1
- package/src/css/look-board.css +54 -9
- package/src/utils/savedViewHelpers.js +39 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
[diffend] Oversized file quarantined before diffing.
|
|
2
2
|
name: package/dist/nextcloud-vue.cjs.js.map
|
|
3
|
-
size:
|
|
4
|
-
sha256:
|
|
3
|
+
size: 44711106 bytes
|
|
4
|
+
sha256: adc90af5daccb75c11701d4aa396b6d4d702bbbe7162340774724cc78395fa24
|
package/dist/nextcloud-vue.css
CHANGED
|
@@ -91,14 +91,19 @@
|
|
|
91
91
|
/* Buttons and inputs. */
|
|
92
92
|
--cn-board-control-height: 40px;
|
|
93
93
|
--cn-board-control-radius: 8px;
|
|
94
|
+
/* A control's edge: 3:1 against every ground a control sits on (WCAG
|
|
95
|
+
1.4.11). Nextcloud's border-dark is a hairline (#dbdbdb, 1.4:1); its
|
|
96
|
+
max-contrast border is the control step, and a theme sets both. */
|
|
97
|
+
--cn-board-control-border: var(--color-border-maxcontrast);
|
|
94
98
|
/* Cards. */
|
|
95
99
|
--cn-board-card-radius: 12px;
|
|
96
100
|
--cn-board-card-padding: 20px 22px;
|
|
97
101
|
/* The side inset of a dashboard card: its title and its rows. */
|
|
98
102
|
--cn-board-dashboard-card-inset: 24px;
|
|
99
|
-
/* Hairline inside a card, and the soft secondary text
|
|
103
|
+
/* Hairline inside a card, and the soft secondary text: the boards' #3d4047,
|
|
104
|
+
between the main text and the muted text, so it follows a theme's pair. */
|
|
100
105
|
--cn-board-hairline: var(--color-border);
|
|
101
|
-
--cn-board-text-soft: var(--color-main-text);
|
|
106
|
+
--cn-board-text-soft: color-mix(in srgb, var(--color-main-text) 45%, var(--color-text-maxcontrast));
|
|
102
107
|
}
|
|
103
108
|
|
|
104
109
|
/*
|
|
@@ -250,6 +255,37 @@
|
|
|
250
255
|
--font-weight-element: 600;
|
|
251
256
|
}
|
|
252
257
|
|
|
258
|
+
/* ---- A button with an icon and a label --------------------------------- */
|
|
259
|
+
/* The boards draw it 14px in at both sides with 14px text and a 16px icon
|
|
260
|
+
8px from its label (DqZaakEmail "Notitie toevoegen", DqVthInstellingen
|
|
261
|
+
"Regel toevoegen"). NcButton pads its start 4px and its end 12px, and puts
|
|
262
|
+
a 20px icon in a 30px slot. The rules hold the condition in `:where()`, so
|
|
263
|
+
they weigh (0,3,0): enough to outrank NcButton's own (0,2,0), and less than
|
|
264
|
+
any surface rule (header, toolbar, follow pill, Meer chevron, tab strip),
|
|
265
|
+
which keeps its own value. The padding goes through NcButton's
|
|
266
|
+
`--button-padding`, so a surface that sets `padding` is never contested.
|
|
267
|
+
@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 */
|
|
268
|
+
.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 *)) {
|
|
269
|
+
--button-padding: 14px;
|
|
270
|
+
font-size: 14px;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
.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 {
|
|
274
|
+
gap: 8px;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.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 {
|
|
278
|
+
width: 16px;
|
|
279
|
+
min-width: 16px;
|
|
280
|
+
height: 16px;
|
|
281
|
+
min-height: 16px;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
.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 {
|
|
285
|
+
width: 16px;
|
|
286
|
+
height: 16px;
|
|
287
|
+
}
|
|
288
|
+
|
|
253
289
|
/* ---- The header button ------------------------------------------------- */
|
|
254
290
|
.cn-look-board .cn-index-page__header-buttons:not(.cn-look-nextcloud *),
|
|
255
291
|
.cn-look-board .cn-detail-page__header-actions:not(.cn-look-nextcloud *),
|
|
@@ -279,7 +315,7 @@
|
|
|
279
315
|
--nldesign-component-button-primary-action-font-weight: 600;
|
|
280
316
|
--nldesign-component-button-secondary-action-color: var(--color-main-text);
|
|
281
317
|
--nldesign-component-button-secondary-action-background-color: var(--color-main-background);
|
|
282
|
-
--nldesign-component-button-secondary-action-border-color: var(--
|
|
318
|
+
--nldesign-component-button-secondary-action-border-color: var(--cn-board-control-border);
|
|
283
319
|
--nldesign-component-button-secondary-action-hover-background-color: var(--color-background-hover);
|
|
284
320
|
}
|
|
285
321
|
|
|
@@ -293,7 +329,7 @@
|
|
|
293
329
|
min-height: var(--cn-board-control-height);
|
|
294
330
|
padding: 0 14px;
|
|
295
331
|
gap: 8px;
|
|
296
|
-
border: 1px solid var(--
|
|
332
|
+
border: 1px solid var(--cn-board-control-border);
|
|
297
333
|
border-radius: var(--cn-board-control-radius);
|
|
298
334
|
background: var(--color-main-background);
|
|
299
335
|
color: var(--color-main-text);
|
|
@@ -325,7 +361,7 @@
|
|
|
325
361
|
height: var(--cn-board-control-height);
|
|
326
362
|
min-height: var(--cn-board-control-height);
|
|
327
363
|
padding: 0 14px;
|
|
328
|
-
border: 1px solid var(--
|
|
364
|
+
border: 1px solid var(--cn-board-control-border);
|
|
329
365
|
border-radius: var(--cn-board-control-radius);
|
|
330
366
|
background: var(--color-main-background);
|
|
331
367
|
color: var(--color-main-text);
|
|
@@ -333,8 +369,9 @@
|
|
|
333
369
|
font-weight: 600;
|
|
334
370
|
}
|
|
335
371
|
|
|
336
|
-
/* Buttons 10px apart, each icon 16px
|
|
337
|
-
|
|
372
|
+
/* Buttons 10px apart, each icon 16px (DqZaak's header, DqZaken's
|
|
373
|
+
"Downloaden"); NcButton draws a 20px icon in a 30px slot. The 8px to the
|
|
374
|
+
label is the board's icon-and-label gap above. */
|
|
338
375
|
.cn-look-board .cn-action-buttons:not(.cn-look-nextcloud *) {
|
|
339
376
|
gap: 10px;
|
|
340
377
|
}
|
|
@@ -344,7 +381,6 @@
|
|
|
344
381
|
min-width: 16px;
|
|
345
382
|
height: 16px;
|
|
346
383
|
min-height: 16px;
|
|
347
|
-
margin-inline-end: 8px;
|
|
348
384
|
}
|
|
349
385
|
|
|
350
386
|
.cn-look-board .cn-action-buttons .button-vue .button-vue__icon:not(.cn-look-nextcloud *) svg {
|
|
@@ -379,7 +415,7 @@
|
|
|
379
415
|
body ink onto every span (thematiq). */
|
|
380
416
|
.cn-look-board .action-item.action-item--secondary .action-item__menutoggle.button-vue--secondary:not(.cn-look-nextcloud *) {
|
|
381
417
|
--nldesign-color-on-surface: var(--color-main-text);
|
|
382
|
-
border: 1px solid var(--
|
|
418
|
+
border: 1px solid var(--cn-board-control-border);
|
|
383
419
|
border-radius: var(--cn-board-control-radius);
|
|
384
420
|
background: var(--color-main-background);
|
|
385
421
|
color: var(--color-main-text);
|
|
@@ -1176,6 +1212,15 @@
|
|
|
1176
1212
|
line-height: normal;
|
|
1177
1213
|
}
|
|
1178
1214
|
|
|
1215
|
+
/* A neutral board tag ("Normaal", "Uit") is the soft text on the chip ground,
|
|
1216
|
+
not the main text on the darker background a Nextcloud tag takes.
|
|
1217
|
+
@spec openspec/changes/board-pill-tones/specs/board-pill-tones/spec.md#requirement-a-neutral-board-tag-is-soft-text-on-the-chip-ground */
|
|
1218
|
+
.cn-look-board .cn-status-badge--default:not(.cn-status-badge--solid):not(.cn-look-nextcloud *) {
|
|
1219
|
+
--cn-status-badge-ink: var(--cn-board-text-soft);
|
|
1220
|
+
background-color: var(--color-background-hover);
|
|
1221
|
+
color: var(--cn-status-badge-ink);
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1179
1224
|
/* A pill paints its own pairing of ink and fill. A theme that forces the body
|
|
1180
1225
|
ink onto every span (thematiq's text rule, `!important` at id level) reads
|
|
1181
1226
|
that ink from --nldesign-color-on-surface when the surface sets it, so the
|
|
@@ -2099,10 +2144,13 @@
|
|
|
2099
2144
|
margin-inline-start: auto;
|
|
2100
2145
|
padding: 1px 8px;
|
|
2101
2146
|
border-radius: 10px;
|
|
2147
|
+
--nldesign-color-on-surface: var(--cn-board-text-soft, var(--color-main-text));
|
|
2102
2148
|
background-color: var(--color-main-background);
|
|
2103
|
-
color: var(--color-main-text);
|
|
2149
|
+
color: var(--cn-board-text-soft, var(--color-main-text));
|
|
2104
2150
|
font-size: 12px;
|
|
2105
|
-
font-weight:
|
|
2151
|
+
font-weight: 700;
|
|
2152
|
+
/* 16px tall on its 1px pad (DqWerkbord's column counts). */
|
|
2153
|
+
line-height: 14px;
|
|
2106
2154
|
}
|
|
2107
2155
|
|
|
2108
2156
|
/* A column at its limit: the count in the error colour; "full" is said in words too. */
|
|
@@ -2474,7 +2522,7 @@
|
|
|
2474
2522
|
height: var(--cn-board-control-height) !important;
|
|
2475
2523
|
min-height: var(--cn-board-control-height) !important;
|
|
2476
2524
|
padding: 0 14px !important;
|
|
2477
|
-
border: 1px solid var(--
|
|
2525
|
+
border: 1px solid var(--cn-board-control-border) !important;
|
|
2478
2526
|
border-radius: var(--cn-board-control-radius) !important;
|
|
2479
2527
|
background: var(--color-main-background) !important;
|
|
2480
2528
|
color: var(--color-main-text) !important;
|
|
@@ -2598,7 +2646,7 @@
|
|
|
2598
2646
|
min-height: 38px;
|
|
2599
2647
|
margin: 0;
|
|
2600
2648
|
padding: 0 14px;
|
|
2601
|
-
border: 1px solid var(--
|
|
2649
|
+
border: 1px solid var(--cn-board-control-border);
|
|
2602
2650
|
border-radius: 19px;
|
|
2603
2651
|
background: var(--color-main-background);
|
|
2604
2652
|
color: var(--color-main-text);
|
|
@@ -2640,20 +2688,22 @@
|
|
|
2640
2688
|
padding: 1px 7px;
|
|
2641
2689
|
border: 0;
|
|
2642
2690
|
border-radius: 10px;
|
|
2691
|
+
--nldesign-color-on-surface: var(--cn-board-text-soft);
|
|
2643
2692
|
background: var(--color-border);
|
|
2644
2693
|
color: var(--cn-board-text-soft);
|
|
2645
2694
|
font-size: 12px;
|
|
2646
2695
|
font-weight: 600;
|
|
2647
|
-
|
|
2696
|
+
/* 16px tall on its 1px pad, as the boards draw it (DqTaken, DqWerkbord).
|
|
2697
|
+
@spec openspec/changes/board-pill-tones/specs/board-pill-tones/spec.md#requirement-a-board-count-is-16px-tall */
|
|
2698
|
+
line-height: 14px;
|
|
2648
2699
|
}
|
|
2649
2700
|
|
|
2650
2701
|
.cn-look-board .cn-saved-views__chip--selected .cn-saved-views__chip-count,
|
|
2651
|
-
/* On the selected chip the count is a lighter bubble on the
|
|
2652
|
-
(DqZaken: #3d4047 on #1b1c1d)
|
|
2653
|
-
text, the chip's own colour, which hid the bubble. */
|
|
2702
|
+
/* On the selected chip the count is the soft ink as a lighter bubble on the
|
|
2703
|
+
dark chip (DqZaken: #3d4047 on #1b1c1d). */
|
|
2654
2704
|
.cn-look-board .cn-quick-filter-bar .cn-quick-filter-bar__tab--active .cn-quick-filter-bar__count {
|
|
2655
2705
|
--nldesign-color-on-surface: var(--color-primary-element-text);
|
|
2656
|
-
background:
|
|
2706
|
+
background: var(--cn-board-text-soft);
|
|
2657
2707
|
color: var(--color-primary-element-text);
|
|
2658
2708
|
}
|
|
2659
2709
|
|
|
@@ -2702,7 +2752,7 @@
|
|
|
2702
2752
|
--nldesign-component-button-font-weight: 600;
|
|
2703
2753
|
--nldesign-component-button-secondary-action-color: var(--color-main-text);
|
|
2704
2754
|
--nldesign-component-button-secondary-action-background-color: var(--color-main-background);
|
|
2705
|
-
--nldesign-component-button-secondary-action-border-color: var(--
|
|
2755
|
+
--nldesign-component-button-secondary-action-border-color: var(--cn-board-control-border);
|
|
2706
2756
|
--nldesign-component-button-secondary-action-hover-background-color: var(--color-background-hover);
|
|
2707
2757
|
}
|
|
2708
2758
|
|
|
@@ -2729,6 +2779,8 @@
|
|
|
2729
2779
|
margin-inline-start: 6px;
|
|
2730
2780
|
padding: 0 6px;
|
|
2731
2781
|
border-radius: 10px;
|
|
2782
|
+
/* A theme that forces the body ink onto every span reads it from here. */
|
|
2783
|
+
--nldesign-color-on-surface: var(--color-primary-element-text);
|
|
2732
2784
|
background: var(--color-primary-element);
|
|
2733
2785
|
color: var(--color-primary-element-text);
|
|
2734
2786
|
font-size: 12px;
|
|
@@ -2837,7 +2889,7 @@
|
|
|
2837
2889
|
height: 40px;
|
|
2838
2890
|
padding-block: 0;
|
|
2839
2891
|
padding-inline: 38px 12px !important;
|
|
2840
|
-
border: 1px solid var(--
|
|
2892
|
+
border: 1px solid var(--cn-board-control-border);
|
|
2841
2893
|
border-radius: 8px;
|
|
2842
2894
|
font-size: 14px;
|
|
2843
2895
|
}
|
|
@@ -3214,7 +3266,7 @@
|
|
|
3214
3266
|
height: 34px !important;
|
|
3215
3267
|
min-height: 34px !important;
|
|
3216
3268
|
padding: 0 !important;
|
|
3217
|
-
border: 1px solid var(--
|
|
3269
|
+
border: 1px solid var(--cn-board-control-border) !important;
|
|
3218
3270
|
border-radius: 8px !important;
|
|
3219
3271
|
color: var(--cn-board-text-soft) !important;
|
|
3220
3272
|
}
|
|
@@ -8000,7 +8052,7 @@ a.cn-kpi-card--board * {
|
|
|
8000
8052
|
height: var(--cn-board-control-height) !important;
|
|
8001
8053
|
min-height: var(--cn-board-control-height) !important;
|
|
8002
8054
|
padding: 0 14px !important;
|
|
8003
|
-
border: 1px solid var(--
|
|
8055
|
+
border: 1px solid var(--cn-board-control-border) !important;
|
|
8004
8056
|
border-radius: var(--cn-board-control-radius) !important;
|
|
8005
8057
|
background: var(--color-main-background) !important;
|
|
8006
8058
|
color: var(--color-main-text) !important;
|
|
@@ -8013,13 +8065,13 @@ a.cn-kpi-card--board * {
|
|
|
8013
8065
|
background: var(--color-background-hover) !important;
|
|
8014
8066
|
}
|
|
8015
8067
|
|
|
8016
|
-
/* Each header icon is 16px
|
|
8068
|
+
/* Each header icon is 16px; NcButton draws 20px in a 30px slot. The 8px to
|
|
8069
|
+
the label is the board's icon-and-label gap (look-board.css). */
|
|
8017
8070
|
.cn-look-board .cn-detail-page .cn-detail-page__header-actions > .button-vue--secondary .button-vue__icon {
|
|
8018
8071
|
width: 16px;
|
|
8019
8072
|
min-width: 16px;
|
|
8020
8073
|
height: 16px;
|
|
8021
8074
|
min-height: 16px;
|
|
8022
|
-
margin-inline-end: 8px;
|
|
8023
8075
|
}
|
|
8024
8076
|
|
|
8025
8077
|
.cn-look-board .cn-detail-page .cn-detail-page__header-actions > .button-vue--secondary .button-vue__icon svg {
|
|
@@ -8027,6 +8079,17 @@ a.cn-kpi-card--board * {
|
|
|
8027
8079
|
height: 16px;
|
|
8028
8080
|
}
|
|
8029
8081
|
|
|
8082
|
+
/* Row 3: the Follow control under the breadcrumb, on the full width.
|
|
8083
|
+
@spec openspec/changes/board-follow-row/specs/board-follow-row/spec.md#requirement-the-board-follow-control-sits-under-the-breadcrumb */
|
|
8084
|
+
.cn-look-board .cn-detail-page__header-row3 {
|
|
8085
|
+
align-items: center;
|
|
8086
|
+
display: flex;
|
|
8087
|
+
flex: 1 0 100%;
|
|
8088
|
+
flex-wrap: wrap;
|
|
8089
|
+
gap: 8px;
|
|
8090
|
+
min-width: 0;
|
|
8091
|
+
}
|
|
8092
|
+
|
|
8030
8093
|
/* Row 2: pills, breadcrumb, dot, meta, chips. */
|
|
8031
8094
|
.cn-look-board .cn-detail-page__header-row2 {
|
|
8032
8095
|
align-items: center;
|
|
@@ -8184,14 +8247,14 @@ a.cn-kpi-card--board * {
|
|
|
8184
8247
|
--nldesign-component-button-border-radius: 14px;
|
|
8185
8248
|
--nldesign-component-button-secondary-action-color: var(--color-main-text);
|
|
8186
8249
|
--nldesign-component-button-secondary-action-background-color: var(--color-main-background);
|
|
8187
|
-
--nldesign-component-button-secondary-action-border-color: var(--
|
|
8250
|
+
--nldesign-component-button-secondary-action-border-color: var(--cn-board-control-border);
|
|
8188
8251
|
--nldesign-component-button-secondary-action-hover-background-color: var(--color-background-hover);
|
|
8189
8252
|
box-sizing: border-box;
|
|
8190
8253
|
height: 28px;
|
|
8191
8254
|
min-height: 28px;
|
|
8192
8255
|
min-width: 0;
|
|
8193
8256
|
padding: 0 10px;
|
|
8194
|
-
border: 1px solid var(--
|
|
8257
|
+
border: 1px solid var(--cn-board-control-border);
|
|
8195
8258
|
border-radius: 14px;
|
|
8196
8259
|
background: var(--color-main-background);
|
|
8197
8260
|
color: var(--color-main-text);
|
|
@@ -8329,13 +8392,14 @@ a.cn-kpi-card--board * {
|
|
|
8329
8392
|
|
|
8330
8393
|
/* The Actions button at the end of the strip: at the top, 8px in from the
|
|
8331
8394
|
end and 8px clear of the card, so the tabs, aligned to the bottom, sit 6px
|
|
8332
|
-
lower than the button (DqZaak "Acties"). */
|
|
8395
|
+
lower than the button, 12px in at both sides (DqZaak "Acties"). */
|
|
8333
8396
|
.cn-look-board .cn-tabs--board .cn-tabs__nav-end {
|
|
8334
8397
|
align-self: flex-start;
|
|
8335
8398
|
margin: 0 8px 8px 0;
|
|
8336
8399
|
}
|
|
8337
8400
|
|
|
8338
8401
|
.cn-look-board .cn-tabs--board .cn-tabs__nav-end .button-vue {
|
|
8402
|
+
--button-padding: 12px;
|
|
8339
8403
|
min-height: 34px;
|
|
8340
8404
|
block-size: 34px;
|
|
8341
8405
|
}
|
|
@@ -8659,7 +8723,7 @@ a.cn-kpi-card--board * {
|
|
|
8659
8723
|
.cn-look-board .cn-activity-tab--board .cn-activity-tab__kind {
|
|
8660
8724
|
align-items: center;
|
|
8661
8725
|
background: var(--color-main-background);
|
|
8662
|
-
border: 1px solid var(--
|
|
8726
|
+
border: 1px solid var(--cn-board-control-border);
|
|
8663
8727
|
border-radius: 18px;
|
|
8664
8728
|
color: var(--color-main-text);
|
|
8665
8729
|
cursor: pointer;
|
|
@@ -8934,7 +8998,7 @@ a.cn-kpi-card--board * {
|
|
|
8934
8998
|
height: var(--cn-board-control-height) !important;
|
|
8935
8999
|
min-height: var(--cn-board-control-height) !important;
|
|
8936
9000
|
padding: 0 14px !important;
|
|
8937
|
-
border: 1px solid var(--
|
|
9001
|
+
border: 1px solid var(--cn-board-control-border) !important;
|
|
8938
9002
|
border-radius: var(--cn-board-control-radius) !important;
|
|
8939
9003
|
background: var(--color-main-background) !important;
|
|
8940
9004
|
color: var(--color-main-text) !important;
|
|
@@ -39027,10 +39091,13 @@ to {
|
|
|
39027
39091
|
margin-inline-start: auto;
|
|
39028
39092
|
padding: 1px 8px;
|
|
39029
39093
|
border-radius: 10px;
|
|
39094
|
+
--nldesign-color-on-surface: var(--cn-board-text-soft, var(--color-main-text));
|
|
39030
39095
|
background-color: var(--color-main-background);
|
|
39031
|
-
color: var(--color-main-text);
|
|
39096
|
+
color: var(--cn-board-text-soft, var(--color-main-text));
|
|
39032
39097
|
font-size: 12px;
|
|
39033
|
-
font-weight:
|
|
39098
|
+
font-weight: 700;
|
|
39099
|
+
/* 16px tall on its 1px pad (DqWerkbord's column counts). */
|
|
39100
|
+
line-height: 14px;
|
|
39034
39101
|
}
|
|
39035
39102
|
|
|
39036
39103
|
/* A column at its limit: the count in the error colour; "full" is said in words too. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@conduction/nextcloud-vue",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.111.0",
|
|
4
4
|
"description": "Shared Vue component library for Conduction Nextcloud apps — complements @nextcloud/vue with higher-level components, OpenRegister integration, and NL Design System support",
|
|
5
5
|
"homepage": "https://github.com/ConductionNL/nextcloud-vue#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -758,6 +758,7 @@ import { installModalStack, uninstallModalStack } from '../../utils/modalStack.j
|
|
|
758
758
|
import { OBJECTS_CHANGED_EVENT } from '../../utils/objectSignals.js'
|
|
759
759
|
import { resolveBrand } from '../../utils/resolveBrand.js'
|
|
760
760
|
import { resolveFilterTokens } from '../../utils/resolveFilterTokens.js'
|
|
761
|
+
import { pageOffersSavedViews } from '../../utils/savedViewHelpers.js'
|
|
761
762
|
import { normalizeSavedViewMenu, SAVED_VIEW_MENU_KEY, SAVED_VIEW_MENU_PREFIX, syncSavedViewMenu, toggleSavedViewMenuEntry, withSavedViewMenu } from '../../utils/savedViewMenu.js'
|
|
762
763
|
import { passesContextPredicates } from '../../utils/visibleIfContext.js'
|
|
763
764
|
|
|
@@ -2400,7 +2401,7 @@ export default {
|
|
|
2400
2401
|
*/
|
|
2401
2402
|
offersSavedViews() {
|
|
2402
2403
|
const pages = this.manifest && Array.isArray(this.manifest.pages) ? this.manifest.pages : []
|
|
2403
|
-
return pages.some((page) => page && page.
|
|
2404
|
+
return pages.some((page) => page && page.type === 'index' && pageOffersSavedViews(page.config))
|
|
2404
2405
|
},
|
|
2405
2406
|
|
|
2406
2407
|
/**
|
|
@@ -126,20 +126,13 @@
|
|
|
126
126
|
</component>
|
|
127
127
|
<!-- The one Follow control beside the title (manifest `config.follow`):
|
|
128
128
|
shown when the object carries `@self.watching`. There is no star:
|
|
129
|
-
a favourite is a follow with notifications off.
|
|
129
|
+
a favourite is a follow with notifications off. The board look
|
|
130
|
+
draws it on a row of its own under the breadcrumb. -->
|
|
130
131
|
<span
|
|
131
|
-
v-if="showFollowToggle"
|
|
132
|
+
v-if="showFollowToggle && !isBoard"
|
|
132
133
|
class="cn-detail-page__interactions"
|
|
133
134
|
data-testid="cn-detail-page-interactions">
|
|
134
|
-
<CnFollowToggle
|
|
135
|
-
:register="register"
|
|
136
|
-
:schema="schema"
|
|
137
|
-
:objectId="String(objectId)"
|
|
138
|
-
:watching="resolvedSelf.watching === true"
|
|
139
|
-
:notify="typeof resolvedSelf.watchNotify === 'boolean' ? resolvedSelf.watchNotify : null"
|
|
140
|
-
:watcherCount="typeof resolvedSelf.watcherCount === 'number' ? resolvedSelf.watcherCount : null"
|
|
141
|
-
:canManage="!!(resolvedSelf.can && resolvedSelf.can.manage === true)"
|
|
142
|
-
:notifies="followNotifies" />
|
|
135
|
+
<CnFollowToggle v-bind="followToggleProps" />
|
|
143
136
|
</span>
|
|
144
137
|
</div>
|
|
145
138
|
<!--
|
|
@@ -517,6 +510,17 @@
|
|
|
517
510
|
:schema="currentSchema"
|
|
518
511
|
:register="register" />
|
|
519
512
|
</div>
|
|
513
|
+
<!-- Row 3 of the board look's header: the Follow control under the
|
|
514
|
+
breadcrumb, clear of the title row and its actions (DqZaak
|
|
515
|
+
"Volgen"). -->
|
|
516
|
+
<div
|
|
517
|
+
v-if="isBoard && showFollowToggle"
|
|
518
|
+
class="cn-detail-page__header-row3"
|
|
519
|
+
data-testid="cn-detail-page-header-row3">
|
|
520
|
+
<span class="cn-detail-page__interactions" data-testid="cn-detail-page-interactions">
|
|
521
|
+
<CnFollowToggle v-bind="followToggleProps" />
|
|
522
|
+
</span>
|
|
523
|
+
</div>
|
|
520
524
|
<!-- A widget inside the header (manifest `config.headerWidget`), on
|
|
521
525
|
a row of its own under the title and the actions: the stages
|
|
522
526
|
bars of the board's case card. Drawn without a card of its own,
|
|
@@ -4319,6 +4323,26 @@ export default {
|
|
|
4319
4323
|
&& this.register !== '' && this.schema !== '' && this.objectId !== ''
|
|
4320
4324
|
},
|
|
4321
4325
|
|
|
4326
|
+
/**
|
|
4327
|
+
* The props of the Follow control, wherever the header draws it.
|
|
4328
|
+
*
|
|
4329
|
+
* @return {object} The CnFollowToggle props.
|
|
4330
|
+
* @spec openspec/changes/board-follow-row/specs/board-follow-row/spec.md#requirement-the-board-follow-control-sits-under-the-breadcrumb
|
|
4331
|
+
*/
|
|
4332
|
+
followToggleProps() {
|
|
4333
|
+
const self = this.resolvedSelf
|
|
4334
|
+
return {
|
|
4335
|
+
register: this.register,
|
|
4336
|
+
schema: this.schema,
|
|
4337
|
+
objectId: String(this.objectId),
|
|
4338
|
+
watching: self.watching === true,
|
|
4339
|
+
notify: typeof self.watchNotify === 'boolean' ? self.watchNotify : null,
|
|
4340
|
+
watcherCount: typeof self.watcherCount === 'number' ? self.watcherCount : null,
|
|
4341
|
+
canManage: !!(self.can && self.can.manage === true),
|
|
4342
|
+
notifies: this.followNotifies,
|
|
4343
|
+
}
|
|
4344
|
+
},
|
|
4345
|
+
|
|
4322
4346
|
/**
|
|
4323
4347
|
* The `_extend[]` values of the object read: the page's own, plus
|
|
4324
4348
|
* `@self.can` while the Follow toggle can render (OpenRegister returns
|
|
@@ -368,7 +368,7 @@ export default {
|
|
|
368
368
|
| `showMassImport` | Boolean | `true` | Whether to show the mass Import action |
|
|
369
369
|
| `showMassCopy` | Boolean | `true` | Whether to show the mass Copy action |
|
|
370
370
|
| `allowExport` | Boolean | `false` | Opt-in flag for the native Export menu (CSV/Excel) next to the Add button. Renders only when `true` AND the resolved schema is flagged `exportable: true`; navigates to OpenRegister's export leaf (`GET /apps/openregister/api/objects/{register}/{schema}/export`), passing `$route.query` through as filters. Distinct from `showMassExport`, which exports the fetched/selected rows via a blob download. |
|
|
371
|
-
| `allowSavedViews` | Boolean |
|
|
371
|
+
| `allowSavedViews` | Boolean | unset | Saved views (saved-views-ui). Unset, the sidebar's Views tab (save, apply, edit, share, add to menu, copy a default, delete) is on for every page with a sidebar and a source a view can be scoped to: register and schema, `entitySource` or `savedViewsScope`. `false` turns it off. `true` also forces the sidebar and adds the toolbar control: a Views dropdown listing the user's OpenRegister saved-search views (`GET /apps/openregister/api/views`). Applying one writes its stored filters/search/sort into the route query (`_search` and `_order` reserved keys + plain filter keys); "Save current view…" persists the current route-query state via POST and toasts either way, naming the view (a failure also keeps the dialog open with the reason); own views can be deleted after confirmation. Emits `apply-view`. |
|
|
372
372
|
| `savedViewsScope` | String | `''` | Which pages share this page's saved views. By default a view is shared by every page over the same `register` and `schema` and shown on no other page, since a view is filters over one schema's fields. Set a name to share views across pages over different sources, or to keep two pages over one source apart. Written into the saved view's `query.scope` on save; views saved before scoping existed carry no scope and stay visible everywhere. |
|
|
373
373
|
| `massActionNameField` | String | `'title'` | Property name used to display item names in dialogs |
|
|
374
374
|
| `nameFormatter` | Function | `null` | Custom formatter for item names in dialogs; overrides `massActionNameField` |
|
|
@@ -1379,7 +1379,7 @@ import { isRowActionVisible, rowActionPayload } from '../../utils/rowActionItem.
|
|
|
1379
1379
|
import { isNewTabClick, isNewTabHandled, isRowMiddleClick, markNewTabHandled, preventMiddleClickAutoscroll } from '../../utils/rowAuxClick.js'
|
|
1380
1380
|
import { compileRowClass } from '../../utils/rowClassRules.js'
|
|
1381
1381
|
import { DEFAULT_ROW_INDICATOR_CAP } from '../../utils/rowIndicators.js'
|
|
1382
|
-
import { buildRouteQueryFromViewState, buildViewCreatePayload, defaultFilterViews, extractViewState, extractViewStateFromRouteQuery, normalizeSharedWith, savedViewScope, schemaSlug, viewMatchesScope } from '../../utils/savedViewHelpers.js'
|
|
1382
|
+
import { buildRouteQueryFromViewState, buildViewCreatePayload, defaultFilterViews, extractViewState, extractViewStateFromRouteQuery, normalizeSharedWith, pageOffersSavedViews, savedViewScope, schemaSlug, viewMatchesScope } from '../../utils/savedViewHelpers.js'
|
|
1383
1383
|
import { savedViewBadge, savedViewOverrides } from '../../utils/savedViewOverrides.js'
|
|
1384
1384
|
import { columnsFromSchema, fieldsFromSchema } from '../../utils/schema.js'
|
|
1385
1385
|
import { resolveScopeLayout, resolveScopePresentation } from '../../utils/scopeListLayout.js'
|
|
@@ -1500,11 +1500,22 @@ function declaredFilterFields(props) {
|
|
|
1500
1500
|
* @return {object} The `{ fieldKey: values }` map, empty when the link carries none.
|
|
1501
1501
|
*/
|
|
1502
1502
|
function namedFiltersFromRoute(instance, props) {
|
|
1503
|
+
const route = instance && instance.proxy && instance.proxy.$route
|
|
1504
|
+
return namedFiltersFromQuery((route && route.query) || {}, props)
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
/**
|
|
1508
|
+
* The named-source filters a query carries, as `namedFiltersFromRoute` reads them.
|
|
1509
|
+
*
|
|
1510
|
+
* @param {object} query The route query.
|
|
1511
|
+
* @param {object} props The CnIndexPage props.
|
|
1512
|
+
*
|
|
1513
|
+
* @return {object} The `{ fieldKey: values }` map.
|
|
1514
|
+
*/
|
|
1515
|
+
function namedFiltersFromQuery(query, props) {
|
|
1503
1516
|
if (!props.entitySource) {
|
|
1504
1517
|
return {}
|
|
1505
1518
|
}
|
|
1506
|
-
const route = instance && instance.proxy && instance.proxy.$route
|
|
1507
|
-
const query = (route && route.query) || {}
|
|
1508
1519
|
const properties = declaredFilterFields(props)
|
|
1509
1520
|
const out = {}
|
|
1510
1521
|
|
|
@@ -2947,9 +2958,11 @@ export default {
|
|
|
2947
2958
|
},
|
|
2948
2959
|
|
|
2949
2960
|
/**
|
|
2950
|
-
*
|
|
2951
|
-
*
|
|
2952
|
-
*
|
|
2961
|
+
* Saved views (saved-views-ui). Unset, the sidebar's Views tab is on
|
|
2962
|
+
* for every page with a sidebar and a source a view can be scoped to
|
|
2963
|
+
* (register and schema, `entitySource` or `savedViewsScope`); `false`
|
|
2964
|
+
* turns it off. `true` also forces the sidebar and adds the toolbar
|
|
2965
|
+
* control, where a Views dropdown lists the
|
|
2953
2966
|
* current user's OpenRegister saved-search views
|
|
2954
2967
|
* (`GET /apps/openregister/api/views`); applying one writes its
|
|
2955
2968
|
* stored filters/search/sort into the route query (reusing the
|
|
@@ -2961,7 +2974,7 @@ export default {
|
|
|
2961
2974
|
*/
|
|
2962
2975
|
allowSavedViews: {
|
|
2963
2976
|
type: Boolean,
|
|
2964
|
-
default:
|
|
2977
|
+
default: null,
|
|
2965
2978
|
},
|
|
2966
2979
|
|
|
2967
2980
|
/**
|
|
@@ -5523,7 +5536,7 @@ export default {
|
|
|
5523
5536
|
* @spec openspec/changes/saved-views-manage-and-defaults/tasks.md#task-6
|
|
5524
5537
|
*/
|
|
5525
5538
|
savedViewsForSidebar() {
|
|
5526
|
-
if (!this.
|
|
5539
|
+
if (!this.savedViewsOffered) {
|
|
5527
5540
|
return null
|
|
5528
5541
|
}
|
|
5529
5542
|
return {
|
|
@@ -6664,7 +6677,16 @@ export default {
|
|
|
6664
6677
|
* @return {{ scope: string, register: string, schema: object|string|null }} The page's source.
|
|
6665
6678
|
*/
|
|
6666
6679
|
savedViewsPage() {
|
|
6667
|
-
return { scope: this.savedViewsScope, register: this.register, schema: this.schema }
|
|
6680
|
+
return { scope: this.savedViewsScope, register: this.register, schema: this.schema, source: this.entitySource }
|
|
6681
|
+
},
|
|
6682
|
+
|
|
6683
|
+
/**
|
|
6684
|
+
* Whether this page offers saved views in its sidebar.
|
|
6685
|
+
*
|
|
6686
|
+
* @return {boolean}
|
|
6687
|
+
*/
|
|
6688
|
+
savedViewsOffered() {
|
|
6689
|
+
return pageOffersSavedViews(this)
|
|
6668
6690
|
},
|
|
6669
6691
|
|
|
6670
6692
|
/**
|
|
@@ -8237,7 +8259,7 @@ export default {
|
|
|
8237
8259
|
created() {
|
|
8238
8260
|
this.applyViewModeFromRoute()
|
|
8239
8261
|
this.pushAiContext()
|
|
8240
|
-
if (this.
|
|
8262
|
+
if (this.savedViewsOffered) {
|
|
8241
8263
|
this.fetchSavedViews()
|
|
8242
8264
|
}
|
|
8243
8265
|
this.selfActions = createSelfModeActions({
|
|
@@ -11345,8 +11367,8 @@ export default {
|
|
|
11345
11367
|
|
|
11346
11368
|
/**
|
|
11347
11369
|
* Fetch the current user's saved views (own + public) from
|
|
11348
|
-
* OpenRegister's views API. Called from created() when
|
|
11349
|
-
*
|
|
11370
|
+
* OpenRegister's views API. Called from created() when the page
|
|
11371
|
+
* offers saved views.
|
|
11350
11372
|
*/
|
|
11351
11373
|
async fetchSavedViews() {
|
|
11352
11374
|
this.savedViewsLoading = true
|
|
@@ -11416,6 +11438,9 @@ export default {
|
|
|
11416
11438
|
query.savedView = this.appliedSavedViewId
|
|
11417
11439
|
}
|
|
11418
11440
|
const nav = this.$router.replace({ query })
|
|
11441
|
+
if (this.isNamedSource) {
|
|
11442
|
+
this.namedActiveFilters = namedFiltersFromQuery(query, this)
|
|
11443
|
+
}
|
|
11419
11444
|
// Swallow the duplicate-navigation rejection (Vue Router 3)
|
|
11420
11445
|
// when the applied view matches the current query.
|
|
11421
11446
|
if (nav && typeof nav.catch === 'function') {
|
|
@@ -216,7 +216,7 @@ With admin-only filter control:
|
|
|
216
216
|
| `propertiesGroupLabel` | String | `''` | Override label for the schema properties group. Falls back to `schema.title` |
|
|
217
217
|
| `defaultTab` | String | `'search-tab'` | Tab id that is active when the sidebar opens. Built-in ids: `'search-tab'`, `'columns-tab'` |
|
|
218
218
|
| `activeTab` | String | `''` | Switch to a tab while mounted, e.g. `'filters-tab'` |
|
|
219
|
-
| `savedViews` | Object | `null` | The page's saved views, shown in a third tab,
|
|
219
|
+
| `savedViews` | Object | `null` | The page's saved views, shown in a third tab, Views (`filters-tab`, CnSavedViewsPanel); every intent comes back as one `saved-view` event `{ action, view }` |
|
|
220
220
|
| `userIsAdmin` | Boolean | `true` | When `false`, schema properties with `adminOnly: true` are hidden from filters |
|
|
221
221
|
| `filterFields` | Object | `null` | Filter declarations for a page with no schema of its own. Wins over `schema`, and feeds the Search tab only |
|
|
222
222
|
|
|
@@ -287,11 +287,11 @@
|
|
|
287
287
|
</div>
|
|
288
288
|
</NcAppSidebarTab>
|
|
289
289
|
|
|
290
|
-
<!--
|
|
290
|
+
<!-- Views tab (id filters-tab): the page's saved views (save, list, manage, add to menu). -->
|
|
291
291
|
<NcAppSidebarTab
|
|
292
292
|
v-if="savedViews"
|
|
293
293
|
id="filters-tab"
|
|
294
|
-
:name="t('nextcloud-vue', '
|
|
294
|
+
:name="t('nextcloud-vue', 'Views')"
|
|
295
295
|
:order="3">
|
|
296
296
|
<template #icon>
|
|
297
297
|
<BookmarkOutline :size="20" />
|
package/src/css/board.css
CHANGED
|
@@ -55,10 +55,13 @@
|
|
|
55
55
|
margin-inline-start: auto;
|
|
56
56
|
padding: 1px 8px;
|
|
57
57
|
border-radius: 10px;
|
|
58
|
+
--nldesign-color-on-surface: var(--cn-board-text-soft, var(--color-main-text));
|
|
58
59
|
background-color: var(--color-main-background);
|
|
59
|
-
color: var(--color-main-text);
|
|
60
|
+
color: var(--cn-board-text-soft, var(--color-main-text));
|
|
60
61
|
font-size: 12px;
|
|
61
|
-
font-weight:
|
|
62
|
+
font-weight: 700;
|
|
63
|
+
/* 16px tall on its 1px pad (DqWerkbord's column counts). */
|
|
64
|
+
line-height: 14px;
|
|
62
65
|
}
|
|
63
66
|
|
|
64
67
|
/* A column at its limit: the count in the error colour; "full" is said in words too. */
|