@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
|
@@ -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. */
|
|
@@ -258,15 +258,18 @@ function schemaSlug(schema) {
|
|
|
258
258
|
* it: three case indexes share their views, the organisations index does
|
|
259
259
|
* not. `savedViewsScope` on a page overrides that, for pages that should
|
|
260
260
|
* share views although they read different sources, or keep them apart
|
|
261
|
-
* although they read the same one.
|
|
261
|
+
* although they read the same one. A page over a named source
|
|
262
|
+
* (`entitySource`) and no schema shares its views with the pages over that
|
|
263
|
+
* source.
|
|
262
264
|
*
|
|
263
265
|
* @param {object} page The page.
|
|
264
266
|
* @param {string} [page.scope] The explicit `savedViewsScope`, when set.
|
|
265
267
|
* @param {string} [page.register] The page's register.
|
|
266
268
|
* @param {object|string} [page.schema] The page's schema, slug or object.
|
|
269
|
+
* @param {string} [page.source] The page's `entitySource`, when it reads one.
|
|
267
270
|
* @return {string} The scope key, or the empty string for a page with no source.
|
|
268
271
|
*/
|
|
269
|
-
function savedViewScope({ scope, register, schema } = {}) {
|
|
272
|
+
function savedViewScope({ scope, register, schema, source } = {}) {
|
|
270
273
|
if (typeof scope === 'string' && scope !== '') {
|
|
271
274
|
return scope
|
|
272
275
|
}
|
|
@@ -274,9 +277,43 @@ function savedViewScope({ scope, register, schema } = {}) {
|
|
|
274
277
|
if (typeof register === 'string' && register !== '' && slug !== '') {
|
|
275
278
|
return `${register}/${slug}`
|
|
276
279
|
}
|
|
280
|
+
if (typeof source === 'string' && source !== '') {
|
|
281
|
+
return `source:${source}`
|
|
282
|
+
}
|
|
277
283
|
return ''
|
|
278
284
|
}
|
|
279
285
|
|
|
286
|
+
/**
|
|
287
|
+
* Whether an index page offers saved views in its sidebar.
|
|
288
|
+
*
|
|
289
|
+
* `allowSavedViews` decides when it is set. Unset, every index page that has
|
|
290
|
+
* a sidebar and a source a view can be scoped to (a register and schema, a
|
|
291
|
+
* named source, or `savedViewsScope`) offers them, so managing views is
|
|
292
|
+
* there on every list without each page opting in.
|
|
293
|
+
*
|
|
294
|
+
* @param {object} config The page's index config, or CnIndexPage's props.
|
|
295
|
+
* @param {boolean|null} [config.allowSavedViews] The explicit choice, when made.
|
|
296
|
+
* @param {object} [config.sidebar] The sidebar config.
|
|
297
|
+
* @param {string} [config.savedViewsScope] The explicit scope.
|
|
298
|
+
* @param {string} [config.register] The register.
|
|
299
|
+
* @param {object|string} [config.schema] The schema.
|
|
300
|
+
* @param {string} [config.entitySource] The named source.
|
|
301
|
+
* @return {boolean}
|
|
302
|
+
*/
|
|
303
|
+
function pageOffersSavedViews(config) {
|
|
304
|
+
if (!config || typeof config !== 'object') {
|
|
305
|
+
return false
|
|
306
|
+
}
|
|
307
|
+
if (typeof config.allowSavedViews === 'boolean') {
|
|
308
|
+
return config.allowSavedViews
|
|
309
|
+
}
|
|
310
|
+
const sidebar = config.sidebar;
|
|
311
|
+
if (!sidebar || typeof sidebar !== 'object' || sidebar.enabled !== true || sidebar.show === false) {
|
|
312
|
+
return false
|
|
313
|
+
}
|
|
314
|
+
return savedViewScope({ scope: config.savedViewsScope, register: config.register, schema: config.schema, source: config.entitySource }) !== ''
|
|
315
|
+
}
|
|
316
|
+
|
|
280
317
|
/**
|
|
281
318
|
* Whether a saved view belongs on a page.
|
|
282
319
|
*
|
|
@@ -410,5 +447,5 @@ function defaultFilterViews(defaults, page = {}) {
|
|
|
410
447
|
})
|
|
411
448
|
}
|
|
412
449
|
|
|
413
|
-
export { buildRouteQueryFromViewState, buildViewCreatePayload, defaultFilterViews, extractViewState, extractViewStateFromRouteQuery, isOwnView, normalizeSharedWith, savedViewScope, schemaSlug, viewAccess, viewMatchesScope };
|
|
450
|
+
export { buildRouteQueryFromViewState, buildViewCreatePayload, defaultFilterViews, extractViewState, extractViewStateFromRouteQuery, isOwnView, normalizeSharedWith, pageOffersSavedViews, savedViewScope, schemaSlug, viewAccess, viewMatchesScope };
|
|
414
451
|
//# sourceMappingURL=savedViewHelpers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"savedViewHelpers.js","sources":["../../../src/utils/savedViewHelpers.js"],"sourcesContent":["// SPDX-FileCopyrightText: 2026 Conduction B.V.\n// SPDX-License-Identifier: EUPL-1.2\n\n/**\n * Pure helpers for CnIndexPage's saved-views feature (saved-views-ui).\n *\n * OpenRegister ships a saved-search Views backend\n * (`/apps/openregister/api/views`, ViewsController + ViewService); these\n * helpers translate between the three state shapes involved:\n *\n * 1. **Route query** — CnIndexPage's deep-link contract: every `$route.query`\n * key NOT starting with `_` is a fetch filter (see\n * `useSelfFetchList.resolveQueryFilters`); `_`-prefixed keys are reserved\n * list params. Search is `_search` and sort is `_order`, the JSON-encoded\n * ordered array `[{ key, order }, …]` — the one spelling CnIndexPage,\n * listNavigation, CnPageRenderer and OpenRegister's object API all agree\n * on. This module writes NO spelling of its own.\n * 2. **View state** — the normalized internal object\n * `{ filters, search, sortKeys, sortKey, sortOrder }`, where `sortKeys` is\n * the truth and the last two mirror its first entry, exactly as\n * `useListView` holds the same state.\n * 3. **OR View payload** — the `POST/PUT /api/views` body whose opaque\n * `query` field round-trips through OpenRegister unchanged.\n *\n * All functions are pure and defensive: malformed input degrades to the\n * empty/default state, never throws.\n *\n * @module utils/savedViewHelpers\n */\n\nimport { parseSortKeys } from './routeFilters.js'\n\n/** The default (empty) view state. @return {object} A fresh empty state. */\nfunction emptyState() {\n\treturn { filters: {}, search: '', sortKeys: [], sortKey: null, sortOrder: 'asc' }\n}\n\n/**\n * Coerce anything into an ordered sort-key list.\n *\n * The single defensive entry point, and the whole of the stored-shape\n * compatibility: a view saved before sorts could be chained holds `sort` as one\n * `{ key, order }` object, and that must keep opening exactly as it does today.\n *\n * @param {unknown} value An array, a single `{ key, order }`, or anything else.\n * @return {Array<{key: string, order: 'asc'|'desc'}>} The normalized list.\n */\nfunction normalizeSortKeys(value) {\n\tconst list = Array.isArray(value) ? value : [value]\n\tconst seen = new Set()\n\tconst keys = []\n\tfor (const entry of list) {\n\t\tif (!entry || typeof entry !== 'object' || typeof entry.key !== 'string' || entry.key === '') {\n\t\t\tcontinue\n\t\t}\n\t\tif (seen.has(entry.key)) {\n\t\t\tcontinue\n\t\t}\n\t\tseen.add(entry.key)\n\t\tkeys.push({ key: entry.key, order: entry.order === 'desc' ? 'desc' : 'asc' })\n\t}\n\treturn keys\n}\n\n/**\n * Write a sort onto a state, keeping the single-key mirror in step.\n *\n * @param {object} state The state to write onto (mutated and returned).\n * @param {Array<{key: string, order: 'asc'|'desc'}>} keys The normalized sort.\n * @return {object} The same state.\n */\nfunction withSort(state, keys) {\n\tstate.sortKeys = keys\n\tstate.sortKey = keys.length > 0 ? keys[0].key : null\n\tstate.sortOrder = keys.length > 0 ? keys[0].order : 'asc'\n\treturn state\n}\n\n/**\n * The sort a caller handed in, whichever of the two shapes they hold.\n *\n * @param {object} src A view state, possibly carrying only `sortKey`/`sortOrder`.\n * @return {Array<{key: string, order: 'asc'|'desc'}>} The normalized sort.\n */\nfunction sortKeysOf(src) {\n\tif (src.sortKeys !== undefined && src.sortKeys !== null) {\n\t\treturn normalizeSortKeys(src.sortKeys)\n\t}\n\treturn src.sortKey ? normalizeSortKeys({ key: src.sortKey, order: src.sortOrder }) : []\n}\n\n/**\n * Extract the current view state from a `$route.query`-shaped object.\n *\n * Non-underscore-prefixed keys become `filters` entries (values passed\n * through as-is, including arrays from `?status[]=a&status[]=b` deep\n * links). Reserved keys map onto the dedicated state fields: `_search` and\n * `_order`. Other reserved keys (`_page`, `_limit`, …) are ignored —\n * pagination is never part of a saved view.\n *\n * @param {object|null|undefined} query The `$route.query` object.\n * @return {{ filters: object, search: string, sortKeys: Array<{key: string, order: string}>, sortKey: ?string, sortOrder: string }} The normalized view state.\n */\nexport function extractViewStateFromRouteQuery(query) {\n\tconst state = emptyState()\n\tif (!query || typeof query !== 'object' || Array.isArray(query)) {\n\t\treturn state\n\t}\n\tfor (const [key, value] of Object.entries(query)) {\n\t\tif (key.startsWith('_')) {\n\t\t\tcontinue\n\t\t}\n\t\tif (value === undefined || value === null || value === '') {\n\t\t\tcontinue\n\t\t}\n\t\tstate.filters[key] = value\n\t}\n\tif (typeof query._search === 'string' && query._search !== '') {\n\t\tstate.search = query._search\n\t}\n\treturn withSort(state, parseSortKeys(query._order))\n}\n\n/**\n * Build a fresh route-query object that APPLIES a view state.\n *\n * Spreads `state.filters` (skipping null/undefined/empty-string/empty-array\n * values, matching what `CnIndexPage.persistViewStateToRoute` skips — the two\n * write the same query and must agree on what an absent filter looks like),\n * then sets the reserved keys only when meaningful: `_search` for a non-empty\n * search term, `_order` for an active sort. Deliberately omits `_page` —\n * applying a view is a full state replace that implicitly resets pagination.\n *\n * @param {{ filters?: object, search?: string, sortKeys?: Array<{key: string, order: string}>, sortKey?: ?string, sortOrder?: string }} state The view state to serialize.\n * @return {object} A plain object suitable for `$router.replace({ query })`.\n */\nexport function buildRouteQueryFromViewState(state) {\n\tconst query = {}\n\tconst src = (state && typeof state === 'object') ? state : {}\n\tconst filters = (src.filters && typeof src.filters === 'object' && !Array.isArray(src.filters)) ? src.filters : {}\n\tfor (const [key, value] of Object.entries(filters)) {\n\t\tif (value === undefined || value === null || value === '' || (Array.isArray(value) && value.length === 0)) {\n\t\t\tcontinue\n\t\t}\n\t\tquery[key] = value\n\t}\n\tif (typeof src.search === 'string' && src.search !== '') {\n\t\tquery._search = src.search\n\t}\n\tconst keys = sortKeysOf(src)\n\tif (keys.length > 0) {\n\t\tquery._order = JSON.stringify(keys)\n\t}\n\treturn query\n}\n\n/**\n * Build the exact `POST /apps/openregister/api/views` (and PUT) request\n * body for persisting a view. The `query` field is OpenRegister's opaque\n * JSON blob — ViewsController stores `$data['query']` verbatim when it is\n * an array/object, so the shape below round-trips unchanged and\n * {@link extractViewState} is its inverse.\n *\n * @param {object} options Payload options.\n * @param {string} options.name Required view name.\n * @param {string} [options.description] Optional description.\n * @param {boolean} [options.isPublic] Share the view with other users.\n * @param {boolean} [options.isDefault] Mark as the user's default view.\n * @param {{ filters?: object, search?: string, sortKeys?: Array<{key: string, order: string}>, sortKey?: ?string, sortOrder?: string }} options.state The view state to persist.\n * @param {string} [options.scope] The pages this view belongs to, from {@link savedViewScope}; omitted when empty.\n * @param {string} [options.register] The page's register, written as OpenRegister's own `registers` list.\n * @param {object|string} [options.schema] The page's schema (slug or object), written as OpenRegister's own `schemas` list.\n * @param {Array<{group: string, mode: string}>} [options.sharedWith] Groups to share with; omitted from the body when empty.\n * @param {object} [options.presentation] How the view shows (OpenRegister's shape); omitted from the body for a table, which is the default.\n * @return {object} The request body for the OR views API.\n */\nexport function buildViewCreatePayload({ name, description, isPublic, isDefault, state, scope, register, schema, sharedWith, presentation } = {}) {\n\tconst src = (state && typeof state === 'object') ? state : {}\n\tconst keys = sortKeysOf(src)\n\tconst query = {\n\t\tfilters: (src.filters && typeof src.filters === 'object' && !Array.isArray(src.filters)) ? src.filters : {},\n\t\tsearch: (typeof src.search === 'string') ? src.search : '',\n\t\t// `null` rather than `[]` for no sort: every view stored before sorts\n\t\t// could be chained says `null`, and one spelling for \"no sort\" is worth\n\t\t// more than the symmetry.\n\t\tsort: keys.length > 0 ? keys : null,\n\t}\n\tif (typeof scope === 'string' && scope !== '') {\n\t\tquery.scope = scope\n\t}\n\tif (typeof register === 'string' && register !== '') {\n\t\tquery.registers = [register]\n\t}\n\tconst slug = schemaSlug(schema)\n\tif (slug !== '') {\n\t\tquery.schemas = [slug]\n\t}\n\tconst body = {\n\t\tname,\n\t\tdescription: description || '',\n\t\tisPublic: !!isPublic,\n\t\tisDefault: !!isDefault,\n\t\tquery,\n\t}\n\tif (presentation && typeof presentation === 'object' && (presentation.viewType === 'kanban' || presentation.viewType === 'calendar')) {\n\t\tbody.presentation = presentation\n\t}\n\tconst audience = normalizeSharedWith(sharedWith)\n\tif (audience.length > 0) {\n\t\tbody.sharedWith = audience\n\t}\n\treturn body\n}\n\n/**\n * Clean an audience list: keep `{ group, mode }` and `{ user, mode }` entries\n * that name exactly one target, drop repeats, and coerce any mode but `write`\n * to `read`.\n *\n * @param {unknown} sharedWith The audience as given.\n * @return {Array<{group?: string, user?: string, mode: 'read'|'write'}>} The cleaned list.\n * @spec openspec/changes/saved-views-manage-and-defaults/tasks.md#task-5\n */\nexport function normalizeSharedWith(sharedWith) {\n\tconst seen = new Set()\n\tconst out = []\n\tfor (const entry of Array.isArray(sharedWith) ? sharedWith : []) {\n\t\tconst group = entry && typeof entry.group === 'string' ? entry.group : ''\n\t\tconst user = entry && typeof entry.user === 'string' ? entry.user : ''\n\t\tif ((group === '') === (user === '')) {\n\t\t\tcontinue\n\t\t}\n\t\tconst key = user !== '' ? `user:${user}` : `group:${group}`\n\t\tif (seen.has(key)) {\n\t\t\tcontinue\n\t\t}\n\t\tseen.add(key)\n\t\tconst mode = entry.mode === 'write' ? 'write' : 'read'\n\t\tout.push(user !== '' ? { user, mode } : { group, mode })\n\t}\n\treturn out\n}\n\n/**\n * What the current user may do with a view: `owner`, `write` or `read`.\n *\n * The server decides: `@self.access` wins. A view without it (an older\n * OpenRegister) counts as `owner` when its `owner` is the current user and as\n * `read` otherwise.\n *\n * @param {object|null|undefined} view The View API object.\n * @param {string|null|undefined} currentUserId The signed-in NC user id.\n * @return {'owner'|'write'|'read'} The access.\n */\nexport function viewAccess(view, currentUserId) {\n\tconst access = view && view['@self'] && view['@self'].access\n\tif (access === 'owner' || access === 'write' || access === 'read') {\n\t\treturn access\n\t}\n\treturn isOwnView(view, currentUserId) ? 'owner' : 'read'\n}\n\n/**\n * The slug of a schema given as a slug or as a schema object.\n *\n * @param {object|string|null|undefined} schema The page's `schema` prop.\n * @return {string} The slug, or the empty string.\n */\nexport function schemaSlug(schema) {\n\tif (typeof schema === 'string') {\n\t\treturn schema\n\t}\n\tif (schema && typeof schema === 'object' && typeof schema.slug === 'string') {\n\t\treturn schema.slug\n\t}\n\treturn ''\n}\n\n/**\n * The key naming which pages share a view.\n *\n * A view is a set of filters over one schema's fields, so by default every\n * page over the same register and schema shares it and no other page sees\n * it: three case indexes share their views, the organisations index does\n * not. `savedViewsScope` on a page overrides that, for pages that should\n * share views although they read different sources, or keep them apart\n * although they read the same one.\n *\n * @param {object} page The page.\n * @param {string} [page.scope] The explicit `savedViewsScope`, when set.\n * @param {string} [page.register] The page's register.\n * @param {object|string} [page.schema] The page's schema, slug or object.\n * @return {string} The scope key, or the empty string for a page with no source.\n */\nexport function savedViewScope({ scope, register, schema } = {}) {\n\tif (typeof scope === 'string' && scope !== '') {\n\t\treturn scope\n\t}\n\tconst slug = schemaSlug(schema)\n\tif (typeof register === 'string' && register !== '' && slug !== '') {\n\t\treturn `${register}/${slug}`\n\t}\n\treturn ''\n}\n\n/**\n * Whether a saved view belongs on a page.\n *\n * A view saved with a `scope` is shown where the scope matches. A view that\n * names `schemas` (OpenRegister's own search UI writes those) is shown on a\n * page over one of them. A view that says neither, saved before views were\n * scoped, is shown everywhere as it always was: hiding it would lose the\n * view, and nothing can tell which page it was made on.\n *\n * @param {object|null|undefined} view The View API object.\n * @param {object} page The page, as {@link savedViewScope} takes it.\n * @return {boolean} True when the view is shown on this page.\n */\nexport function viewMatchesScope(view, page = {}) {\n\tconst query = view && typeof view === 'object' ? view.query : null\n\tif (!query || typeof query !== 'object' || Array.isArray(query)) {\n\t\treturn true\n\t}\n\tif (typeof query.scope === 'string' && query.scope !== '') {\n\t\treturn query.scope === savedViewScope(page)\n\t}\n\tif (Array.isArray(query.schemas) && query.schemas.length > 0) {\n\t\tconst slug = schemaSlug(page.schema)\n\t\tif (slug === '' || !query.schemas.map(String).includes(slug)) {\n\t\t\treturn false\n\t\t}\n\t\tif (Array.isArray(query.registers) && query.registers.length > 0 && page.register) {\n\t\t\treturn query.registers.map(String).includes(String(page.register))\n\t\t}\n\t\treturn true\n\t}\n\treturn true\n}\n\n/**\n * Normalize a View API object (as returned by `GET /api/views`) back into\n * the internal view state. Accepts either a full view object (reads its\n * `query` property) or a raw query blob directly. Every field degrades\n * defensively: missing/null/malformed `query`, non-object `filters`,\n * malformed `sort` all yield the empty/default state — never throws.\n *\n * @param {object|null|undefined} view The View API object (or its raw `query` blob).\n * @return {{ filters: object, search: string, sortKeys: Array<{key: string, order: string}>, sortKey: ?string, sortOrder: string }} The normalized view state.\n */\nexport function extractViewState(view) {\n\tconst state = emptyState()\n\tif (!view || typeof view !== 'object' || Array.isArray(view)) {\n\t\treturn state\n\t}\n\t// Full view object (has a `query` key) or a raw query blob itself.\n\tconst query = (Object.hasOwn(view, 'query')) ? view.query : view\n\tif (!query || typeof query !== 'object' || Array.isArray(query)) {\n\t\treturn state\n\t}\n\tif (query.filters && typeof query.filters === 'object' && !Array.isArray(query.filters)) {\n\t\tfor (const [key, value] of Object.entries(query.filters)) {\n\t\t\tif (value === undefined || value === null || value === '') {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tstate.filters[key] = value\n\t\t}\n\t}\n\tif (typeof query.search === 'string') {\n\t\tstate.search = query.search\n\t}\n\treturn withSort(state, normalizeSortKeys(query.sort))\n}\n\n/**\n * Whether the given view is owned by the given user. Drives the delete\n * affordance in CnSavedViewsControl — OpenRegister scopes destroy() to the\n * owner server-side (a foreign id 404s), so this only hides the button for\n * views the API would refuse to delete anyway.\n *\n * @param {object|null|undefined} view The View API object.\n * @param {string|null|undefined} currentUserId The signed-in NC user id.\n * @return {boolean} True when the view belongs to the current user.\n */\nexport function isOwnView(view, currentUserId) {\n\treturn !!view && !!currentUserId && view.owner === currentUserId\n}\n\n/**\n * The default views an index page declares (`config.defaultSavedViews`), as\n * read-only views the saved-views control lists. They are never stored: the\n * manifest installs them, so every user has the same set and none can delete\n * one. `seeded: true` puts them in the control's default group; the query\n * keeps its `@`-tokens, which resolve when a default is applied.\n *\n * A default's `overrides` (page config laid over the page while it is\n * active, see `utils/savedViewOverrides.js`) ride in `query.overrides`, so a\n * copy of the default keeps them.\n *\n * @param {Array<object>|null|undefined} defaults The declared entries `{ slug, name, filters, search?, sort?, label?, overrides? }`.\n * @param {{ scope?: string, register?: string, schema?: object|string|null }} [page] The page, as `savedViewScope` takes it.\n * @return {Array<object>} The views, in declaration order; entries without a slug or name are left out.\n * @spec openspec/changes/saved-views-manage-and-defaults/tasks.md#task-4\n */\nexport function defaultFilterViews(defaults, page = {}) {\n\tif (!Array.isArray(defaults)) {\n\t\treturn []\n\t}\n\treturn defaults\n\t\t.filter((entry) => entry && typeof entry.slug === 'string' && entry.slug !== '' && typeof entry.name === 'string' && entry.name !== '')\n\t\t.map((entry) => {\n\t\t\tconst { query } = buildViewCreatePayload({\n\t\t\t\tname: entry.name,\n\t\t\t\tstate: {\n\t\t\t\t\tfilters: (entry.filters && typeof entry.filters === 'object' && !Array.isArray(entry.filters)) ? entry.filters : {},\n\t\t\t\t\tsearch: typeof entry.search === 'string' ? entry.search : '',\n\t\t\t\t\tsortKeys: Array.isArray(entry.sort) ? entry.sort : [],\n\t\t\t\t},\n\t\t\t\tscope: savedViewScope(page),\n\t\t\t\tregister: page.register,\n\t\t\t\tschema: page.schema,\n\t\t\t})\n\t\t\tif (entry.overrides && typeof entry.overrides === 'object' && !Array.isArray(entry.overrides)) {\n\t\t\t\tquery.overrides = entry.overrides\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tid: `default:${entry.slug}`,\n\t\t\t\tslug: entry.slug,\n\t\t\t\tname: entry.name,\n\t\t\t\towner: '',\n\t\t\t\tseeded: true,\n\t\t\t\tisPublic: false,\n\t\t\t\tlabels: typeof entry.label === 'string' && entry.label !== '' ? [entry.label] : [],\n\t\t\t\t'@self': { access: 'read' },\n\t\t\t\tquery,\n\t\t\t}\n\t\t})\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"savedViewHelpers.js","sources":["../../../src/utils/savedViewHelpers.js"],"sourcesContent":["// SPDX-FileCopyrightText: 2026 Conduction B.V.\n// SPDX-License-Identifier: EUPL-1.2\n\n/**\n * Pure helpers for CnIndexPage's saved-views feature (saved-views-ui).\n *\n * OpenRegister ships a saved-search Views backend\n * (`/apps/openregister/api/views`, ViewsController + ViewService); these\n * helpers translate between the three state shapes involved:\n *\n * 1. **Route query** — CnIndexPage's deep-link contract: every `$route.query`\n * key NOT starting with `_` is a fetch filter (see\n * `useSelfFetchList.resolveQueryFilters`); `_`-prefixed keys are reserved\n * list params. Search is `_search` and sort is `_order`, the JSON-encoded\n * ordered array `[{ key, order }, …]` — the one spelling CnIndexPage,\n * listNavigation, CnPageRenderer and OpenRegister's object API all agree\n * on. This module writes NO spelling of its own.\n * 2. **View state** — the normalized internal object\n * `{ filters, search, sortKeys, sortKey, sortOrder }`, where `sortKeys` is\n * the truth and the last two mirror its first entry, exactly as\n * `useListView` holds the same state.\n * 3. **OR View payload** — the `POST/PUT /api/views` body whose opaque\n * `query` field round-trips through OpenRegister unchanged.\n *\n * All functions are pure and defensive: malformed input degrades to the\n * empty/default state, never throws.\n *\n * @module utils/savedViewHelpers\n */\n\nimport { parseSortKeys } from './routeFilters.js'\n\n/** The default (empty) view state. @return {object} A fresh empty state. */\nfunction emptyState() {\n\treturn { filters: {}, search: '', sortKeys: [], sortKey: null, sortOrder: 'asc' }\n}\n\n/**\n * Coerce anything into an ordered sort-key list.\n *\n * The single defensive entry point, and the whole of the stored-shape\n * compatibility: a view saved before sorts could be chained holds `sort` as one\n * `{ key, order }` object, and that must keep opening exactly as it does today.\n *\n * @param {unknown} value An array, a single `{ key, order }`, or anything else.\n * @return {Array<{key: string, order: 'asc'|'desc'}>} The normalized list.\n */\nfunction normalizeSortKeys(value) {\n\tconst list = Array.isArray(value) ? value : [value]\n\tconst seen = new Set()\n\tconst keys = []\n\tfor (const entry of list) {\n\t\tif (!entry || typeof entry !== 'object' || typeof entry.key !== 'string' || entry.key === '') {\n\t\t\tcontinue\n\t\t}\n\t\tif (seen.has(entry.key)) {\n\t\t\tcontinue\n\t\t}\n\t\tseen.add(entry.key)\n\t\tkeys.push({ key: entry.key, order: entry.order === 'desc' ? 'desc' : 'asc' })\n\t}\n\treturn keys\n}\n\n/**\n * Write a sort onto a state, keeping the single-key mirror in step.\n *\n * @param {object} state The state to write onto (mutated and returned).\n * @param {Array<{key: string, order: 'asc'|'desc'}>} keys The normalized sort.\n * @return {object} The same state.\n */\nfunction withSort(state, keys) {\n\tstate.sortKeys = keys\n\tstate.sortKey = keys.length > 0 ? keys[0].key : null\n\tstate.sortOrder = keys.length > 0 ? keys[0].order : 'asc'\n\treturn state\n}\n\n/**\n * The sort a caller handed in, whichever of the two shapes they hold.\n *\n * @param {object} src A view state, possibly carrying only `sortKey`/`sortOrder`.\n * @return {Array<{key: string, order: 'asc'|'desc'}>} The normalized sort.\n */\nfunction sortKeysOf(src) {\n\tif (src.sortKeys !== undefined && src.sortKeys !== null) {\n\t\treturn normalizeSortKeys(src.sortKeys)\n\t}\n\treturn src.sortKey ? normalizeSortKeys({ key: src.sortKey, order: src.sortOrder }) : []\n}\n\n/**\n * Extract the current view state from a `$route.query`-shaped object.\n *\n * Non-underscore-prefixed keys become `filters` entries (values passed\n * through as-is, including arrays from `?status[]=a&status[]=b` deep\n * links). Reserved keys map onto the dedicated state fields: `_search` and\n * `_order`. Other reserved keys (`_page`, `_limit`, …) are ignored —\n * pagination is never part of a saved view.\n *\n * @param {object|null|undefined} query The `$route.query` object.\n * @return {{ filters: object, search: string, sortKeys: Array<{key: string, order: string}>, sortKey: ?string, sortOrder: string }} The normalized view state.\n */\nexport function extractViewStateFromRouteQuery(query) {\n\tconst state = emptyState()\n\tif (!query || typeof query !== 'object' || Array.isArray(query)) {\n\t\treturn state\n\t}\n\tfor (const [key, value] of Object.entries(query)) {\n\t\tif (key.startsWith('_')) {\n\t\t\tcontinue\n\t\t}\n\t\tif (value === undefined || value === null || value === '') {\n\t\t\tcontinue\n\t\t}\n\t\tstate.filters[key] = value\n\t}\n\tif (typeof query._search === 'string' && query._search !== '') {\n\t\tstate.search = query._search\n\t}\n\treturn withSort(state, parseSortKeys(query._order))\n}\n\n/**\n * Build a fresh route-query object that APPLIES a view state.\n *\n * Spreads `state.filters` (skipping null/undefined/empty-string/empty-array\n * values, matching what `CnIndexPage.persistViewStateToRoute` skips — the two\n * write the same query and must agree on what an absent filter looks like),\n * then sets the reserved keys only when meaningful: `_search` for a non-empty\n * search term, `_order` for an active sort. Deliberately omits `_page` —\n * applying a view is a full state replace that implicitly resets pagination.\n *\n * @param {{ filters?: object, search?: string, sortKeys?: Array<{key: string, order: string}>, sortKey?: ?string, sortOrder?: string }} state The view state to serialize.\n * @return {object} A plain object suitable for `$router.replace({ query })`.\n */\nexport function buildRouteQueryFromViewState(state) {\n\tconst query = {}\n\tconst src = (state && typeof state === 'object') ? state : {}\n\tconst filters = (src.filters && typeof src.filters === 'object' && !Array.isArray(src.filters)) ? src.filters : {}\n\tfor (const [key, value] of Object.entries(filters)) {\n\t\tif (value === undefined || value === null || value === '' || (Array.isArray(value) && value.length === 0)) {\n\t\t\tcontinue\n\t\t}\n\t\tquery[key] = value\n\t}\n\tif (typeof src.search === 'string' && src.search !== '') {\n\t\tquery._search = src.search\n\t}\n\tconst keys = sortKeysOf(src)\n\tif (keys.length > 0) {\n\t\tquery._order = JSON.stringify(keys)\n\t}\n\treturn query\n}\n\n/**\n * Build the exact `POST /apps/openregister/api/views` (and PUT) request\n * body for persisting a view. The `query` field is OpenRegister's opaque\n * JSON blob — ViewsController stores `$data['query']` verbatim when it is\n * an array/object, so the shape below round-trips unchanged and\n * {@link extractViewState} is its inverse.\n *\n * @param {object} options Payload options.\n * @param {string} options.name Required view name.\n * @param {string} [options.description] Optional description.\n * @param {boolean} [options.isPublic] Share the view with other users.\n * @param {boolean} [options.isDefault] Mark as the user's default view.\n * @param {{ filters?: object, search?: string, sortKeys?: Array<{key: string, order: string}>, sortKey?: ?string, sortOrder?: string }} options.state The view state to persist.\n * @param {string} [options.scope] The pages this view belongs to, from {@link savedViewScope}; omitted when empty.\n * @param {string} [options.register] The page's register, written as OpenRegister's own `registers` list.\n * @param {object|string} [options.schema] The page's schema (slug or object), written as OpenRegister's own `schemas` list.\n * @param {Array<{group: string, mode: string}>} [options.sharedWith] Groups to share with; omitted from the body when empty.\n * @param {object} [options.presentation] How the view shows (OpenRegister's shape); omitted from the body for a table, which is the default.\n * @return {object} The request body for the OR views API.\n */\nexport function buildViewCreatePayload({ name, description, isPublic, isDefault, state, scope, register, schema, sharedWith, presentation } = {}) {\n\tconst src = (state && typeof state === 'object') ? state : {}\n\tconst keys = sortKeysOf(src)\n\tconst query = {\n\t\tfilters: (src.filters && typeof src.filters === 'object' && !Array.isArray(src.filters)) ? src.filters : {},\n\t\tsearch: (typeof src.search === 'string') ? src.search : '',\n\t\t// `null` rather than `[]` for no sort: every view stored before sorts\n\t\t// could be chained says `null`, and one spelling for \"no sort\" is worth\n\t\t// more than the symmetry.\n\t\tsort: keys.length > 0 ? keys : null,\n\t}\n\tif (typeof scope === 'string' && scope !== '') {\n\t\tquery.scope = scope\n\t}\n\tif (typeof register === 'string' && register !== '') {\n\t\tquery.registers = [register]\n\t}\n\tconst slug = schemaSlug(schema)\n\tif (slug !== '') {\n\t\tquery.schemas = [slug]\n\t}\n\tconst body = {\n\t\tname,\n\t\tdescription: description || '',\n\t\tisPublic: !!isPublic,\n\t\tisDefault: !!isDefault,\n\t\tquery,\n\t}\n\tif (presentation && typeof presentation === 'object' && (presentation.viewType === 'kanban' || presentation.viewType === 'calendar')) {\n\t\tbody.presentation = presentation\n\t}\n\tconst audience = normalizeSharedWith(sharedWith)\n\tif (audience.length > 0) {\n\t\tbody.sharedWith = audience\n\t}\n\treturn body\n}\n\n/**\n * Clean an audience list: keep `{ group, mode }` and `{ user, mode }` entries\n * that name exactly one target, drop repeats, and coerce any mode but `write`\n * to `read`.\n *\n * @param {unknown} sharedWith The audience as given.\n * @return {Array<{group?: string, user?: string, mode: 'read'|'write'}>} The cleaned list.\n * @spec openspec/changes/saved-views-manage-and-defaults/tasks.md#task-5\n */\nexport function normalizeSharedWith(sharedWith) {\n\tconst seen = new Set()\n\tconst out = []\n\tfor (const entry of Array.isArray(sharedWith) ? sharedWith : []) {\n\t\tconst group = entry && typeof entry.group === 'string' ? entry.group : ''\n\t\tconst user = entry && typeof entry.user === 'string' ? entry.user : ''\n\t\tif ((group === '') === (user === '')) {\n\t\t\tcontinue\n\t\t}\n\t\tconst key = user !== '' ? `user:${user}` : `group:${group}`\n\t\tif (seen.has(key)) {\n\t\t\tcontinue\n\t\t}\n\t\tseen.add(key)\n\t\tconst mode = entry.mode === 'write' ? 'write' : 'read'\n\t\tout.push(user !== '' ? { user, mode } : { group, mode })\n\t}\n\treturn out\n}\n\n/**\n * What the current user may do with a view: `owner`, `write` or `read`.\n *\n * The server decides: `@self.access` wins. A view without it (an older\n * OpenRegister) counts as `owner` when its `owner` is the current user and as\n * `read` otherwise.\n *\n * @param {object|null|undefined} view The View API object.\n * @param {string|null|undefined} currentUserId The signed-in NC user id.\n * @return {'owner'|'write'|'read'} The access.\n */\nexport function viewAccess(view, currentUserId) {\n\tconst access = view && view['@self'] && view['@self'].access\n\tif (access === 'owner' || access === 'write' || access === 'read') {\n\t\treturn access\n\t}\n\treturn isOwnView(view, currentUserId) ? 'owner' : 'read'\n}\n\n/**\n * The slug of a schema given as a slug or as a schema object.\n *\n * @param {object|string|null|undefined} schema The page's `schema` prop.\n * @return {string} The slug, or the empty string.\n */\nexport function schemaSlug(schema) {\n\tif (typeof schema === 'string') {\n\t\treturn schema\n\t}\n\tif (schema && typeof schema === 'object' && typeof schema.slug === 'string') {\n\t\treturn schema.slug\n\t}\n\treturn ''\n}\n\n/**\n * The key naming which pages share a view.\n *\n * A view is a set of filters over one schema's fields, so by default every\n * page over the same register and schema shares it and no other page sees\n * it: three case indexes share their views, the organisations index does\n * not. `savedViewsScope` on a page overrides that, for pages that should\n * share views although they read different sources, or keep them apart\n * although they read the same one. A page over a named source\n * (`entitySource`) and no schema shares its views with the pages over that\n * source.\n *\n * @param {object} page The page.\n * @param {string} [page.scope] The explicit `savedViewsScope`, when set.\n * @param {string} [page.register] The page's register.\n * @param {object|string} [page.schema] The page's schema, slug or object.\n * @param {string} [page.source] The page's `entitySource`, when it reads one.\n * @return {string} The scope key, or the empty string for a page with no source.\n */\nexport function savedViewScope({ scope, register, schema, source } = {}) {\n\tif (typeof scope === 'string' && scope !== '') {\n\t\treturn scope\n\t}\n\tconst slug = schemaSlug(schema)\n\tif (typeof register === 'string' && register !== '' && slug !== '') {\n\t\treturn `${register}/${slug}`\n\t}\n\tif (typeof source === 'string' && source !== '') {\n\t\treturn `source:${source}`\n\t}\n\treturn ''\n}\n\n/**\n * Whether an index page offers saved views in its sidebar.\n *\n * `allowSavedViews` decides when it is set. Unset, every index page that has\n * a sidebar and a source a view can be scoped to (a register and schema, a\n * named source, or `savedViewsScope`) offers them, so managing views is\n * there on every list without each page opting in.\n *\n * @param {object} config The page's index config, or CnIndexPage's props.\n * @param {boolean|null} [config.allowSavedViews] The explicit choice, when made.\n * @param {object} [config.sidebar] The sidebar config.\n * @param {string} [config.savedViewsScope] The explicit scope.\n * @param {string} [config.register] The register.\n * @param {object|string} [config.schema] The schema.\n * @param {string} [config.entitySource] The named source.\n * @return {boolean}\n */\nexport function pageOffersSavedViews(config) {\n\tif (!config || typeof config !== 'object') {\n\t\treturn false\n\t}\n\tif (typeof config.allowSavedViews === 'boolean') {\n\t\treturn config.allowSavedViews\n\t}\n\tconst sidebar = config.sidebar\n\tif (!sidebar || typeof sidebar !== 'object' || sidebar.enabled !== true || sidebar.show === false) {\n\t\treturn false\n\t}\n\treturn savedViewScope({ scope: config.savedViewsScope, register: config.register, schema: config.schema, source: config.entitySource }) !== ''\n}\n\n/**\n * Whether a saved view belongs on a page.\n *\n * A view saved with a `scope` is shown where the scope matches. A view that\n * names `schemas` (OpenRegister's own search UI writes those) is shown on a\n * page over one of them. A view that says neither, saved before views were\n * scoped, is shown everywhere as it always was: hiding it would lose the\n * view, and nothing can tell which page it was made on.\n *\n * @param {object|null|undefined} view The View API object.\n * @param {object} page The page, as {@link savedViewScope} takes it.\n * @return {boolean} True when the view is shown on this page.\n */\nexport function viewMatchesScope(view, page = {}) {\n\tconst query = view && typeof view === 'object' ? view.query : null\n\tif (!query || typeof query !== 'object' || Array.isArray(query)) {\n\t\treturn true\n\t}\n\tif (typeof query.scope === 'string' && query.scope !== '') {\n\t\treturn query.scope === savedViewScope(page)\n\t}\n\tif (Array.isArray(query.schemas) && query.schemas.length > 0) {\n\t\tconst slug = schemaSlug(page.schema)\n\t\tif (slug === '' || !query.schemas.map(String).includes(slug)) {\n\t\t\treturn false\n\t\t}\n\t\tif (Array.isArray(query.registers) && query.registers.length > 0 && page.register) {\n\t\t\treturn query.registers.map(String).includes(String(page.register))\n\t\t}\n\t\treturn true\n\t}\n\treturn true\n}\n\n/**\n * Normalize a View API object (as returned by `GET /api/views`) back into\n * the internal view state. Accepts either a full view object (reads its\n * `query` property) or a raw query blob directly. Every field degrades\n * defensively: missing/null/malformed `query`, non-object `filters`,\n * malformed `sort` all yield the empty/default state — never throws.\n *\n * @param {object|null|undefined} view The View API object (or its raw `query` blob).\n * @return {{ filters: object, search: string, sortKeys: Array<{key: string, order: string}>, sortKey: ?string, sortOrder: string }} The normalized view state.\n */\nexport function extractViewState(view) {\n\tconst state = emptyState()\n\tif (!view || typeof view !== 'object' || Array.isArray(view)) {\n\t\treturn state\n\t}\n\t// Full view object (has a `query` key) or a raw query blob itself.\n\tconst query = (Object.hasOwn(view, 'query')) ? view.query : view\n\tif (!query || typeof query !== 'object' || Array.isArray(query)) {\n\t\treturn state\n\t}\n\tif (query.filters && typeof query.filters === 'object' && !Array.isArray(query.filters)) {\n\t\tfor (const [key, value] of Object.entries(query.filters)) {\n\t\t\tif (value === undefined || value === null || value === '') {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tstate.filters[key] = value\n\t\t}\n\t}\n\tif (typeof query.search === 'string') {\n\t\tstate.search = query.search\n\t}\n\treturn withSort(state, normalizeSortKeys(query.sort))\n}\n\n/**\n * Whether the given view is owned by the given user. Drives the delete\n * affordance in CnSavedViewsControl — OpenRegister scopes destroy() to the\n * owner server-side (a foreign id 404s), so this only hides the button for\n * views the API would refuse to delete anyway.\n *\n * @param {object|null|undefined} view The View API object.\n * @param {string|null|undefined} currentUserId The signed-in NC user id.\n * @return {boolean} True when the view belongs to the current user.\n */\nexport function isOwnView(view, currentUserId) {\n\treturn !!view && !!currentUserId && view.owner === currentUserId\n}\n\n/**\n * The default views an index page declares (`config.defaultSavedViews`), as\n * read-only views the saved-views control lists. They are never stored: the\n * manifest installs them, so every user has the same set and none can delete\n * one. `seeded: true` puts them in the control's default group; the query\n * keeps its `@`-tokens, which resolve when a default is applied.\n *\n * A default's `overrides` (page config laid over the page while it is\n * active, see `utils/savedViewOverrides.js`) ride in `query.overrides`, so a\n * copy of the default keeps them.\n *\n * @param {Array<object>|null|undefined} defaults The declared entries `{ slug, name, filters, search?, sort?, label?, overrides? }`.\n * @param {{ scope?: string, register?: string, schema?: object|string|null }} [page] The page, as `savedViewScope` takes it.\n * @return {Array<object>} The views, in declaration order; entries without a slug or name are left out.\n * @spec openspec/changes/saved-views-manage-and-defaults/tasks.md#task-4\n */\nexport function defaultFilterViews(defaults, page = {}) {\n\tif (!Array.isArray(defaults)) {\n\t\treturn []\n\t}\n\treturn defaults\n\t\t.filter((entry) => entry && typeof entry.slug === 'string' && entry.slug !== '' && typeof entry.name === 'string' && entry.name !== '')\n\t\t.map((entry) => {\n\t\t\tconst { query } = buildViewCreatePayload({\n\t\t\t\tname: entry.name,\n\t\t\t\tstate: {\n\t\t\t\t\tfilters: (entry.filters && typeof entry.filters === 'object' && !Array.isArray(entry.filters)) ? entry.filters : {},\n\t\t\t\t\tsearch: typeof entry.search === 'string' ? entry.search : '',\n\t\t\t\t\tsortKeys: Array.isArray(entry.sort) ? entry.sort : [],\n\t\t\t\t},\n\t\t\t\tscope: savedViewScope(page),\n\t\t\t\tregister: page.register,\n\t\t\t\tschema: page.schema,\n\t\t\t})\n\t\t\tif (entry.overrides && typeof entry.overrides === 'object' && !Array.isArray(entry.overrides)) {\n\t\t\t\tquery.overrides = entry.overrides\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tid: `default:${entry.slug}`,\n\t\t\t\tslug: entry.slug,\n\t\t\t\tname: entry.name,\n\t\t\t\towner: '',\n\t\t\t\tseeded: true,\n\t\t\t\tisPublic: false,\n\t\t\t\tlabels: typeof entry.label === 'string' && entry.label !== '' ? [entry.label] : [],\n\t\t\t\t'@self': { access: 'read' },\n\t\t\t\tquery,\n\t\t\t}\n\t\t})\n}\n"],"names":[],"mappings":"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"}
|