@conduction/nextcloud-vue 2.100.0 → 2.101.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/CnChoiceCards/CnChoiceCards.vue.js +1 -1
- package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue2.js +22 -1
- package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue2.js.map +1 -1
- package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue3.js +26 -16
- package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue3.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue.js +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +51 -7
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +104 -73
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
- package/dist/esm/components/CnExportsWidget/CnExportsWidget.vue.js +9 -0
- package/dist/esm/components/CnExportsWidget/CnExportsWidget.vue.js.map +1 -0
- package/dist/esm/components/CnExportsWidget/CnExportsWidget.vue2.js +139 -0
- package/dist/esm/components/CnExportsWidget/CnExportsWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnExportsWidget/CnExportsWidget.vue3.js +76 -0
- package/dist/esm/components/CnExportsWidget/CnExportsWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue.js +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js +160 -2
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js +206 -94
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/filesReview.js +61 -0
- package/dist/esm/components/CnFilesBrowser/filesReview.js.map +1 -0
- package/dist/esm/components/CnGroupedCardsWidget/CnGroupedCardsWidget.vue.js +9 -0
- package/dist/esm/components/CnGroupedCardsWidget/CnGroupedCardsWidget.vue.js.map +1 -0
- package/dist/esm/components/CnGroupedCardsWidget/CnGroupedCardsWidget.vue2.js +279 -0
- package/dist/esm/components/CnGroupedCardsWidget/CnGroupedCardsWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnGroupedCardsWidget/CnGroupedCardsWidget.vue3.js +122 -0
- package/dist/esm/components/CnGroupedCardsWidget/CnGroupedCardsWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnGroupedCardsWidget/index.js +29 -0
- package/dist/esm/components/CnGroupedCardsWidget/index.js.map +1 -0
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +251 -71
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +317 -209
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/useNamedSource.js +4 -1
- package/dist/esm/components/CnIndexPage/useNamedSource.js.map +1 -1
- package/dist/esm/components/CnMapWidget/CnMapWidget.vue.js +1 -1
- package/dist/esm/components/CnMapWidget/CnMapWidget.vue2.js +15 -0
- package/dist/esm/components/CnMapWidget/CnMapWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnMapWidget/CnMapWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue.js +1 -1
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js +14 -1
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js +14 -6
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue.js +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js +10 -0
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js +6 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js.map +1 -1
- package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue.js +1 -1
- package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue2.js +91 -4
- package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue2.js.map +1 -1
- package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue3.js +63 -38
- package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue3.js.map +1 -1
- package/dist/esm/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue.js +9 -0
- package/dist/esm/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue.js.map +1 -0
- package/dist/esm/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue2.js +175 -0
- package/dist/esm/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue3.js +77 -0
- package/dist/esm/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue.js +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js +35 -2
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js.map +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js.map +1 -1
- package/dist/esm/components/CnWidgetGrid/builtInWidgets.js +4 -0
- package/dist/esm/components/CnWidgetGrid/builtInWidgets.js.map +1 -1
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +1 -0
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
- package/dist/esm/composables/indexSources.js +167 -20
- package/dist/esm/composables/indexSources.js.map +1 -1
- package/dist/esm/composables/useEndpointSource.js +28 -6
- package/dist/esm/composables/useEndpointSource.js.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/l10n/en.json.js +37 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +35 -1
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/library-style.js +1 -1
- package/dist/esm/nextcloud-vue.css +769 -251
- package/dist/esm/utils/languageMapText.js +50 -0
- package/dist/esm/utils/languageMapText.js.map +1 -0
- package/dist/esm/utils/libraryWidgetKeys.js +3 -0
- package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
- package/dist/esm/utils/mapList.js +71 -0
- package/dist/esm/utils/mapList.js.map +1 -0
- package/dist/esm/utils/validateManifestV2.compiled.js +3 -3
- package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +8977 -6843
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +769 -251
- package/l10n/en.json +37 -1
- package/l10n/nl.json +35 -1
- package/package.json +1 -1
- package/src/components/CnChoiceCards/CnChoiceCards.md +39 -0
- package/src/components/CnChoiceCards/CnChoiceCards.vue +93 -16
- package/src/components/CnDashboardPage/CnDashboardPage.vue +89 -20
- package/src/components/CnExportsWidget/CnExportsWidget.vue +233 -0
- package/src/components/CnExportsWidget/index.js +7 -0
- package/src/components/CnFilesBrowser/CnFilesBrowser.vue +324 -0
- package/src/components/CnFilesBrowser/filesReview.js +57 -0
- package/src/components/CnGroupedCardsWidget/CnGroupedCardsWidget.vue +433 -0
- package/src/components/CnGroupedCardsWidget/index.js +28 -0
- package/src/components/CnIndexPage/CnIndexPage.vue +240 -4
- package/src/components/CnIndexPage/useNamedSource.js +4 -1
- package/src/components/CnMapWidget/CnMapWidget.vue +37 -0
- package/src/components/CnObjectListWidget/CnObjectListWidget.vue +29 -1
- package/src/components/CnObjectSidebar/CnFilesTab.vue +15 -0
- package/src/components/CnOrderedListField/CnOrderedListField.vue +151 -5
- package/src/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue +272 -0
- package/src/components/CnSavedViewAlertWidget/index.js +7 -0
- package/src/components/CnSetupWizard/CnSetupWizard.vue +35 -2
- package/src/components/CnWidgetGrid/builtInWidgets.js +4 -0
- package/src/components/CnWidgetGrid/registerDashboardWidgets.js +1 -0
- package/src/components/index.js +3 -0
- package/src/composables/indexSources.js +166 -19
- package/src/composables/useEndpointSource.js +28 -6
- package/src/css/index-page.css +117 -0
- package/src/css/look-board.css +44 -0
- package/src/index.js +1 -0
- package/src/schemas/app-manifest-v2.schema.json +31 -1
- package/src/utils/languageMapText.js +46 -0
- package/src/utils/libraryWidgetKeys.js +3 -0
- package/src/utils/mapList.js +67 -0
- package/src/utils/validateManifestV2.compiled.js +3 -3
package/l10n/en.json
CHANGED
|
@@ -1700,7 +1700,27 @@
|
|
|
1700
1700
|
"Run test": "Run test",
|
|
1701
1701
|
"Test with a record": "Test with a record",
|
|
1702
1702
|
"admin": "admin",
|
|
1703
|
-
"Wizard": "Wizard"
|
|
1703
|
+
"Wizard": "Wizard",
|
|
1704
|
+
"{done} of {total} reviewed": "{done} of {total} reviewed",
|
|
1705
|
+
"{open} still to review": "{open} still to review",
|
|
1706
|
+
"{action}: {name}": "{action}: {name}",
|
|
1707
|
+
"On the map": "On the map",
|
|
1708
|
+
"Show them in the table": "Show them in the table",
|
|
1709
|
+
"Linked": "Linked",
|
|
1710
|
+
"Now": "Now",
|
|
1711
|
+
"Tell me above a number": "Tell me above a number",
|
|
1712
|
+
"Threshold": "Threshold",
|
|
1713
|
+
"A message to you when there are {threshold} or more": "A message to you when there are {threshold} or more",
|
|
1714
|
+
"Save this search or open a saved one to set an alert on it.": "Save this search or open a saved one to set an alert on it.",
|
|
1715
|
+
"The alert could not be saved.": "The alert could not be saved.",
|
|
1716
|
+
"Your exports could not be loaded.": "Your exports could not be loaded.",
|
|
1717
|
+
"You have no exports here.": "You have no exports here.",
|
|
1718
|
+
"Expires today": "Expires today",
|
|
1719
|
+
"Download": "Download",
|
|
1720
|
+
"Made {date}": "Made {date}",
|
|
1721
|
+
"expires {date}": "expires {date}",
|
|
1722
|
+
"Loading …": "Loading …",
|
|
1723
|
+
"Reorder {item}: drag, or press the up and down arrow keys": "Reorder {item}: drag, or press the up and down arrow keys"
|
|
1704
1724
|
},
|
|
1705
1725
|
"plurals": {
|
|
1706
1726
|
"{count} selected": [
|
|
@@ -1798,6 +1818,22 @@
|
|
|
1798
1818
|
"Showing %n flow": [
|
|
1799
1819
|
"Showing %n flow",
|
|
1800
1820
|
"Showing %n flows"
|
|
1821
|
+
],
|
|
1822
|
+
"%n without an address": [
|
|
1823
|
+
"%n without an address",
|
|
1824
|
+
"%n without an address"
|
|
1825
|
+
],
|
|
1826
|
+
"%n with an address on the map": [
|
|
1827
|
+
"%n with an address on the map",
|
|
1828
|
+
"%n with an address on the map"
|
|
1829
|
+
],
|
|
1830
|
+
"%n result": [
|
|
1831
|
+
"%n result",
|
|
1832
|
+
"%n results"
|
|
1833
|
+
],
|
|
1834
|
+
"downloaded %n time": [
|
|
1835
|
+
"downloaded %n time",
|
|
1836
|
+
"downloaded %n times"
|
|
1801
1837
|
]
|
|
1802
1838
|
}
|
|
1803
1839
|
}
|
package/l10n/nl.json
CHANGED
|
@@ -1915,7 +1915,25 @@
|
|
|
1915
1915
|
"Run test": "Test uitvoeren",
|
|
1916
1916
|
"Test with a record": "Testen met een record",
|
|
1917
1917
|
"admin": "beheerder",
|
|
1918
|
-
"Wizard": "Assistent"
|
|
1918
|
+
"Wizard": "Assistent",
|
|
1919
|
+
"{done} of {total} reviewed": "{done} van {total} beoordeeld",
|
|
1920
|
+
"{open} still to review": "Nog {open} te beoordelen",
|
|
1921
|
+
"{action}: {name}": "{action}: {name}",
|
|
1922
|
+
"On the map": "Op de kaart",
|
|
1923
|
+
"Show them in the table": "Toon ze in de tabel",
|
|
1924
|
+
"Linked": "Gekoppeld",
|
|
1925
|
+
"Now": "Nu",
|
|
1926
|
+
"Tell me above a number": "Melden boven een aantal",
|
|
1927
|
+
"Threshold": "Grens",
|
|
1928
|
+
"A message to you when there are {threshold} or more": "Bericht aan u als het er {threshold} of meer zijn",
|
|
1929
|
+
"Save this search or open a saved one to set an alert on it.": "Sla deze zoekopdracht op of open een opgeslagen zoekopdracht om er een melding op te zetten.",
|
|
1930
|
+
"The alert could not be saved.": "De melding kon niet worden opgeslagen.",
|
|
1931
|
+
"Your exports could not be loaded.": "Uw exports konden niet worden geladen.",
|
|
1932
|
+
"You have no exports here.": "U heeft hier geen exports.",
|
|
1933
|
+
"Expires today": "Verloopt vandaag",
|
|
1934
|
+
"Made {date}": "Gemaakt {date}",
|
|
1935
|
+
"expires {date}": "verloopt {date}",
|
|
1936
|
+
"Reorder {item}: drag, or press the up and down arrow keys": "{item} verplaatsen: slepen, of de pijltoetsen omhoog en omlaag"
|
|
1919
1937
|
},
|
|
1920
1938
|
"plurals": {
|
|
1921
1939
|
"{count} selected": [
|
|
@@ -2013,6 +2031,22 @@
|
|
|
2013
2031
|
"Showing %n flow": [
|
|
2014
2032
|
"%n flow",
|
|
2015
2033
|
"%n flows"
|
|
2034
|
+
],
|
|
2035
|
+
"%n without an address": [
|
|
2036
|
+
"%n zonder adres",
|
|
2037
|
+
"%n zonder adres"
|
|
2038
|
+
],
|
|
2039
|
+
"%n with an address on the map": [
|
|
2040
|
+
"%n met een adres op de kaart",
|
|
2041
|
+
"%n met een adres op de kaart"
|
|
2042
|
+
],
|
|
2043
|
+
"%n result": [
|
|
2044
|
+
"%n resultaat",
|
|
2045
|
+
"%n resultaten"
|
|
2046
|
+
],
|
|
2047
|
+
"downloaded %n time": [
|
|
2048
|
+
"%n keer gedownload",
|
|
2049
|
+
"%n keer gedownload"
|
|
2016
2050
|
]
|
|
2017
2051
|
}
|
|
2018
2052
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@conduction/nextcloud-vue",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.101.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": {
|
|
@@ -87,4 +87,43 @@ under it through the `option-actions` slot (scope `{ option, selected }`):
|
|
|
87
87
|
</div>
|
|
88
88
|
```
|
|
89
89
|
|
|
90
|
+
The chosen option's own fields can also sit inside its frame, under its text,
|
|
91
|
+
through the `option-details` slot (scope `{ option }`): rendered only for the
|
|
92
|
+
selected option, and outside the radio's label.
|
|
93
|
+
|
|
94
|
+
```vue
|
|
95
|
+
<div style="max-width: 560px;">
|
|
96
|
+
<CnChoiceCards
|
|
97
|
+
label="Next step"
|
|
98
|
+
layout="rows"
|
|
99
|
+
:model-value="'suspend'"
|
|
100
|
+
:options="[
|
|
101
|
+
{ value: 'suspend', label: 'Suspend', description: 'The term stops until the answer is in.' },
|
|
102
|
+
{ value: 'abort', label: 'Abort' },
|
|
103
|
+
]">
|
|
104
|
+
<template #option-details="{ option }">
|
|
105
|
+
<p v-if="option.value === 'suspend'" style="margin: 0;">Reason and return date go here.</p>
|
|
106
|
+
</template>
|
|
107
|
+
</CnChoiceCards>
|
|
108
|
+
</div>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
A recorded choice shown back with `readonly`: every option at full contrast, the
|
|
112
|
+
chosen one marked, nothing pickable. `disabled` greys the options out instead.
|
|
113
|
+
|
|
114
|
+
```vue
|
|
115
|
+
<div style="max-width: 560px;">
|
|
116
|
+
<CnChoiceCards
|
|
117
|
+
label="Outcome"
|
|
118
|
+
layout="rows"
|
|
119
|
+
:readonly="true"
|
|
120
|
+
:model-value="'partial'"
|
|
121
|
+
:options="[
|
|
122
|
+
{ value: 'public', label: 'Made public' },
|
|
123
|
+
{ value: 'partial', label: 'Partly made public' },
|
|
124
|
+
{ value: 'none', label: 'Not made public' },
|
|
125
|
+
]" />
|
|
126
|
+
</div>
|
|
127
|
+
```
|
|
128
|
+
|
|
90
129
|
`columns` fixes the card grid's column count; `:columns="1"` stacks the cards in one column.
|
|
@@ -20,17 +20,18 @@
|
|
|
20
20
|
<div
|
|
21
21
|
v-for="option in normalizedOptions"
|
|
22
22
|
:key="String(option.value)"
|
|
23
|
-
class="cn-choice-cards__cell"
|
|
23
|
+
class="cn-choice-cards__cell"
|
|
24
|
+
:class="{ 'cn-choice-cards__cell--with-details': hasDetails(option) }">
|
|
24
25
|
<label
|
|
25
26
|
class="cn-choice-cards__row"
|
|
26
|
-
:class="{ 'cn-choice-cards__row--selected': isSelected(option), 'cn-choice-cards__row--disabled': isDisabled(option) }">
|
|
27
|
+
:class="{ 'cn-choice-cards__row--selected': isSelected(option), 'cn-choice-cards__row--disabled': isDisabled(option), 'cn-choice-cards__row--readonly': readonly }">
|
|
27
28
|
<input
|
|
28
29
|
class="cn-choice-cards__row-input"
|
|
29
30
|
:type="multiple ? 'checkbox' : 'radio'"
|
|
30
31
|
:name="groupName"
|
|
31
32
|
:value="String(option.value)"
|
|
32
33
|
:checked="isSelected(option)"
|
|
33
|
-
:disabled="isDisabled(option)"
|
|
34
|
+
:disabled="isDisabled(option) || readonly"
|
|
34
35
|
:aria-describedby="option.disabled && option.disabledReason ? reasonId(option) : null"
|
|
35
36
|
@change="onToggle(option)">
|
|
36
37
|
<CnIcon v-if="option.icon"
|
|
@@ -47,6 +48,16 @@
|
|
|
47
48
|
data-testid="cn-choice-cards-reason">{{ option.disabledReason }}</span>
|
|
48
49
|
</span>
|
|
49
50
|
</label>
|
|
51
|
+
<div v-if="hasDetails(option)"
|
|
52
|
+
class="cn-choice-cards__details"
|
|
53
|
+
:data-testid="`cn-choice-cards-details-${option.value}`">
|
|
54
|
+
<!-- @slot option-details The chosen option's own fields, drawn
|
|
55
|
+
inside the selected row's frame under its text (DqVolgendeStap:
|
|
56
|
+
Opschorten's reason, days and return date). Rendered only for a
|
|
57
|
+
selected option, outside the label so a field is not part of
|
|
58
|
+
the radio's label. Scope: `{ option }`. -->
|
|
59
|
+
<slot name="option-details" :option="option" />
|
|
60
|
+
</div>
|
|
50
61
|
<div v-if="$slots['option-actions']" class="cn-choice-cards__actions">
|
|
51
62
|
<slot name="option-actions" :option="option" :selected="isSelected(option)" />
|
|
52
63
|
</div>
|
|
@@ -64,7 +75,7 @@
|
|
|
64
75
|
class="cn-choice-cards__cell">
|
|
65
76
|
<label
|
|
66
77
|
class="cn-choice-cards__option"
|
|
67
|
-
:class="{ 'cn-choice-cards__option--selected': isSelected(option) }">
|
|
78
|
+
:class="{ 'cn-choice-cards__option--selected': isSelected(option), 'cn-choice-cards__option--disabled': isDisabled(option) }">
|
|
68
79
|
<!-- A REAL, VISIBLE input, not a styled div with a click handler.
|
|
69
80
|
It carries the checked state to assistive technology and to
|
|
70
81
|
Windows high-contrast mode for free, and it keeps the
|
|
@@ -76,7 +87,7 @@
|
|
|
76
87
|
:name="groupName"
|
|
77
88
|
:value="String(option.value)"
|
|
78
89
|
:checked="isSelected(option)"
|
|
79
|
-
:disabled="isDisabled(option)"
|
|
90
|
+
:disabled="isDisabled(option) || readonly"
|
|
80
91
|
:aria-describedby="option.disabled && option.disabledReason ? reasonId(option) : null"
|
|
81
92
|
@change="onToggle(option)">
|
|
82
93
|
<CnCard
|
|
@@ -191,6 +202,16 @@ export default {
|
|
|
191
202
|
default: false,
|
|
192
203
|
},
|
|
193
204
|
|
|
205
|
+
/**
|
|
206
|
+
* Show the choice without letting it change: every option at full
|
|
207
|
+
* contrast, the selected one marked, nothing pickable (DqBesluit's
|
|
208
|
+
* recorded outcome). `disabled` greys the options out instead.
|
|
209
|
+
*/
|
|
210
|
+
readonly: {
|
|
211
|
+
type: Boolean,
|
|
212
|
+
default: false,
|
|
213
|
+
},
|
|
214
|
+
|
|
194
215
|
/** Show a spinner instead of the grid while options are being fetched. */
|
|
195
216
|
loading: {
|
|
196
217
|
type: Boolean,
|
|
@@ -311,6 +332,17 @@ export default {
|
|
|
311
332
|
* @param {object} option The normalised option.
|
|
312
333
|
* @return {boolean} True when selected.
|
|
313
334
|
*/
|
|
335
|
+
/**
|
|
336
|
+
* Whether a rows option draws the `option-details` slot in its frame:
|
|
337
|
+
* the slot is given and the option is the chosen one.
|
|
338
|
+
*
|
|
339
|
+
* @param {object} option The option.
|
|
340
|
+
* @return {boolean}
|
|
341
|
+
*/
|
|
342
|
+
hasDetails(option) {
|
|
343
|
+
return Boolean(this.$slots['option-details']) && this.isSelected(option)
|
|
344
|
+
},
|
|
345
|
+
|
|
314
346
|
/**
|
|
315
347
|
* Whether an option cannot be picked: the whole group is disabled, or the option is.
|
|
316
348
|
*
|
|
@@ -342,7 +374,7 @@ export default {
|
|
|
342
374
|
* @return {void}
|
|
343
375
|
*/
|
|
344
376
|
onToggle(option) {
|
|
345
|
-
if (this.isDisabled(option)) {
|
|
377
|
+
if (this.readonly || this.isDisabled(option)) {
|
|
346
378
|
return
|
|
347
379
|
}
|
|
348
380
|
if (!this.multiple) {
|
|
@@ -452,7 +484,7 @@ export default {
|
|
|
452
484
|
cursor: default;
|
|
453
485
|
}
|
|
454
486
|
|
|
455
|
-
.cn-choice-
|
|
487
|
+
.cn-choice-cards__option--disabled .cn-choice-cards__input + :deep(.cn-card) {
|
|
456
488
|
opacity: 0.6;
|
|
457
489
|
}
|
|
458
490
|
|
|
@@ -462,11 +494,12 @@ export default {
|
|
|
462
494
|
gap: 8px;
|
|
463
495
|
}
|
|
464
496
|
|
|
497
|
+
/* 12px 14px, as the boards draw an option row (DqVolgendeStap, DqBesluit). */
|
|
465
498
|
.cn-choice-cards__row {
|
|
466
499
|
display: flex;
|
|
467
500
|
align-items: flex-start;
|
|
468
501
|
gap: 12px;
|
|
469
|
-
padding: 14px
|
|
502
|
+
padding: 12px 14px;
|
|
470
503
|
border: 1px solid var(--color-border);
|
|
471
504
|
border-radius: var(--border-radius-large, 8px);
|
|
472
505
|
background: var(--color-main-background);
|
|
@@ -485,9 +518,54 @@ export default {
|
|
|
485
518
|
background: var(--color-primary-element-light);
|
|
486
519
|
}
|
|
487
520
|
|
|
488
|
-
|
|
521
|
+
/* An option this record does not allow: the grey ground and the muted ink,
|
|
522
|
+
still legible (DqVolgendeStap), not faded. */
|
|
523
|
+
.cn-choice-cards__row--disabled,
|
|
524
|
+
.cn-choice-cards__row--disabled:hover {
|
|
525
|
+
--nldesign-color-on-surface: var(--color-text-maxcontrast);
|
|
526
|
+
border-color: var(--color-border);
|
|
527
|
+
background: var(--color-background-hover);
|
|
528
|
+
color: var(--color-text-maxcontrast);
|
|
489
529
|
cursor: default;
|
|
490
|
-
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/* The title takes the muted ink itself: a theme that colours every label
|
|
533
|
+
with `!important` (thematiq) would otherwise hand it the label colour. */
|
|
534
|
+
.cn-choice-cards__row--disabled .cn-choice-cards__row-title {
|
|
535
|
+
--nldesign-color-on-surface: var(--color-text-maxcontrast);
|
|
536
|
+
color: var(--color-text-maxcontrast);
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/* The chosen option's fields share the selected row's frame: the cell draws
|
|
540
|
+
the 2px primary border and the ground, the row inside it draws none, and
|
|
541
|
+
the fields sit under the text, indented to it (DqVolgendeStap). */
|
|
542
|
+
.cn-choice-cards__cell--with-details {
|
|
543
|
+
border: 1px solid var(--color-primary-element);
|
|
544
|
+
border-radius: var(--border-radius-large, 8px);
|
|
545
|
+
box-shadow: inset 0 0 0 1px var(--color-primary-element);
|
|
546
|
+
background: var(--color-primary-element-light);
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
.cn-choice-cards__cell--with-details .cn-choice-cards__row,
|
|
550
|
+
.cn-choice-cards__cell--with-details .cn-choice-cards__row:hover {
|
|
551
|
+
border-color: transparent;
|
|
552
|
+
box-shadow: none;
|
|
553
|
+
background: transparent;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
.cn-choice-cards__details {
|
|
557
|
+
display: flex;
|
|
558
|
+
flex-direction: column;
|
|
559
|
+
gap: 14px;
|
|
560
|
+
padding: 0 14px 14px 44px;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
.cn-choice-cards__row--readonly {
|
|
564
|
+
cursor: default;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
.cn-choice-cards__row--readonly:not(.cn-choice-cards__row--selected):hover {
|
|
568
|
+
border-color: var(--color-border);
|
|
491
569
|
}
|
|
492
570
|
|
|
493
571
|
.cn-choice-cards__row:has(.cn-choice-cards__row-input:focus-visible) {
|
|
@@ -518,15 +596,14 @@ export default {
|
|
|
518
596
|
font-weight: 600;
|
|
519
597
|
}
|
|
520
598
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
}
|
|
525
|
-
|
|
599
|
+
/* Regular weight on the span itself: a theme that sets every label bold
|
|
600
|
+
with `!important` (thematiq) reaches a span that only inherits. */
|
|
601
|
+
.cn-choice-cards__row-description,
|
|
526
602
|
.cn-choice-cards__reason {
|
|
603
|
+
--nldesign-color-on-surface: var(--color-text-maxcontrast);
|
|
527
604
|
font-size: 13px;
|
|
605
|
+
font-weight: 400;
|
|
528
606
|
color: var(--color-text-maxcontrast);
|
|
529
|
-
font-style: italic;
|
|
530
607
|
}
|
|
531
608
|
|
|
532
609
|
.cn-choice-cards__reason--card {
|
|
@@ -42,12 +42,13 @@
|
|
|
42
42
|
group ends the description line ("Week 41 · alle teams ·
|
|
43
43
|
[Deze week | Dit kwartaal | Dit jaar]"). -->
|
|
44
44
|
<div
|
|
45
|
-
v-if="datePeriodInDescription"
|
|
45
|
+
v-if="datePeriodInDescription || descriptionPageFilters.length > 0"
|
|
46
46
|
class="cn-dashboard-page__description cn-dashboard-page__description--with-period"
|
|
47
47
|
data-testid="cn-dashboard-page-subtitle">
|
|
48
48
|
<span v-if="subtitleText">{{ subtitleText }}</span>
|
|
49
49
|
<span v-if="subtitleText" aria-hidden="true">·</span>
|
|
50
50
|
<CnSegmentedControl
|
|
51
|
+
v-if="datePeriodInDescription"
|
|
51
52
|
size="compact"
|
|
52
53
|
mode="toggle"
|
|
53
54
|
:options="segmentedOptions"
|
|
@@ -55,6 +56,20 @@
|
|
|
55
56
|
:ariaLabel="datePeriodLabel"
|
|
56
57
|
data-testid="cn-dashboard-page-date-segmented"
|
|
57
58
|
@update:modelValue="onSegmentPick" />
|
|
59
|
+
<!-- A page filter with `control: "segmented"` and
|
|
60
|
+
`placement: "description"` (DqProcesanalyse
|
|
61
|
+
"Gemiddeld | Mediaan"): a segmented group on the
|
|
62
|
+
description line that writes the workspace context. -->
|
|
63
|
+
<CnSegmentedControl
|
|
64
|
+
v-for="pf in descriptionPageFilters"
|
|
65
|
+
:key="pf.key"
|
|
66
|
+
size="compact"
|
|
67
|
+
mode="toggle"
|
|
68
|
+
:options="pageFilterSegments(pf)"
|
|
69
|
+
:modelValue="workspaceContext[pf.key]"
|
|
70
|
+
:ariaLabel="pf.label ? effectiveTranslate(pf.label) : pf.key"
|
|
71
|
+
:data-testid="'cn-page-filter-' + pf.key"
|
|
72
|
+
@update:modelValue="onPageFilterChange(pf, $event)" />
|
|
58
73
|
</div>
|
|
59
74
|
<p v-else-if="subtitleText" class="cn-dashboard-page__description" data-testid="cn-dashboard-page-subtitle">
|
|
60
75
|
{{ subtitleText }}
|
|
@@ -316,23 +331,33 @@
|
|
|
316
331
|
`@page.<key>` / `@workspace.<key>` token (e.g. an endpoint KPI's URL
|
|
317
332
|
interpolating a chosen period). -->
|
|
318
333
|
<div
|
|
319
|
-
v-if="
|
|
334
|
+
v-if="rowPageFilters.length > 0"
|
|
320
335
|
class="cn-dashboard-page__page-filters"
|
|
321
336
|
data-testid="cn-dashboard-page-page-filters">
|
|
322
|
-
<
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
:modelValue="
|
|
329
|
-
:
|
|
330
|
-
:clearable="false"
|
|
331
|
-
:inputLabel="pf.label || pf.key"
|
|
332
|
-
label="label"
|
|
337
|
+
<template v-for="pf in rowPageFilters" :key="pf.key">
|
|
338
|
+
<CnSegmentedControl
|
|
339
|
+
v-if="pf.control === 'segmented'"
|
|
340
|
+
size="compact"
|
|
341
|
+
mode="toggle"
|
|
342
|
+
:options="pageFilterSegments(pf)"
|
|
343
|
+
:modelValue="workspaceContext[pf.key]"
|
|
344
|
+
:ariaLabel="pf.label ? effectiveTranslate(pf.label) : pf.key"
|
|
333
345
|
:data-testid="'cn-page-filter-' + pf.key"
|
|
334
346
|
@update:modelValue="onPageFilterChange(pf, $event)" />
|
|
335
|
-
|
|
347
|
+
<label
|
|
348
|
+
v-else
|
|
349
|
+
class="cn-dashboard-page__page-filter">
|
|
350
|
+
<span v-if="pf.label" class="cn-dashboard-page__page-filter-label">{{ pf.label }}</span>
|
|
351
|
+
<NcSelect
|
|
352
|
+
:modelValue="selectedPageFilterOption(pf)"
|
|
353
|
+
:options="pf.options || []"
|
|
354
|
+
:clearable="false"
|
|
355
|
+
:inputLabel="pf.label || pf.key"
|
|
356
|
+
label="label"
|
|
357
|
+
:data-testid="'cn-page-filter-' + pf.key"
|
|
358
|
+
@update:modelValue="onPageFilterChange(pf, $event)" />
|
|
359
|
+
</label>
|
|
360
|
+
</template>
|
|
336
361
|
</div>
|
|
337
362
|
|
|
338
363
|
<!-- Declarative in-body sections, `placement: "before-grid"` — host-app
|
|
@@ -1678,13 +1703,18 @@ export default {
|
|
|
1678
1703
|
* read it via a `@page.<key>` / `@workspace.<key>` token — e.g. a period
|
|
1679
1704
|
* selector that every endpoint-bound KPI's URL interpolates.
|
|
1680
1705
|
*
|
|
1681
|
-
* Each entry: `{ key, label?, type?: 'select',
|
|
1682
|
-
* default? }`. `key` is the workspace-context
|
|
1683
|
-
* `default` (or the first option) seeds it on
|
|
1684
|
-
*
|
|
1685
|
-
*
|
|
1706
|
+
* Each entry: `{ key, label?, type?: 'select', control?, placement?,
|
|
1707
|
+
* options: [{ value, label }], default? }`. `key` is the workspace-context
|
|
1708
|
+
* key written on change; `default` (or the first option) seeds it on
|
|
1709
|
+
* mount. The control is a select, or with `control: 'segmented'` a
|
|
1710
|
+
* compact segmented group; `placement: 'description'` puts a segmented
|
|
1711
|
+
* group on the header's description line, after the period group
|
|
1712
|
+
* (DqProcesanalyse "Gemiddeld | Mediaan"). An endpoint widget can read
|
|
1713
|
+
* the value in its `responsePath` too (`phaseDays.@workspace.measure`).
|
|
1714
|
+
* Empty (the default) renders no controls and leaves the context
|
|
1715
|
+
* untouched.
|
|
1686
1716
|
*
|
|
1687
|
-
* @type {Array<{key: string, label?: string, type?: string, options: Array<{value: (string|number), label: string}>, default?: (string|number)}>}
|
|
1717
|
+
* @type {Array<{key: string, label?: string, type?: string, control?: ('select'|'segmented'), placement?: ('row'|'description'), options: Array<{value: (string|number), label: string}>, default?: (string|number)}>}
|
|
1688
1718
|
*/
|
|
1689
1719
|
pageFilters: {
|
|
1690
1720
|
type: Array,
|
|
@@ -2343,6 +2373,33 @@ export default {
|
|
|
2343
2373
|
&& this.dateRange.placement === 'description' && !this.hasCustomPreset
|
|
2344
2374
|
},
|
|
2345
2375
|
|
|
2376
|
+
/**
|
|
2377
|
+
* The page filters drawn as a segmented group on the description
|
|
2378
|
+
* line (`control: "segmented"`, `placement: "description"`).
|
|
2379
|
+
* Without a header row they fall back to the filter row.
|
|
2380
|
+
*
|
|
2381
|
+
* @spec openspec/changes/dashboard-board-termijnen/specs/dashboard-page/spec.md#requirement-a-page-filter-as-a-segmented-group-on-the-description-line
|
|
2382
|
+
* @return {Array<object>}
|
|
2383
|
+
*/
|
|
2384
|
+
descriptionPageFilters() {
|
|
2385
|
+
if (!this.showHeader) {
|
|
2386
|
+
return []
|
|
2387
|
+
}
|
|
2388
|
+
return (this.pageFilters || []).filter((pf) => pf && pf.key && pf.control === 'segmented' && pf.placement === 'description')
|
|
2389
|
+
},
|
|
2390
|
+
|
|
2391
|
+
/**
|
|
2392
|
+
* The page filters drawn in the filter row under the header: every
|
|
2393
|
+
* filter the description line does not draw.
|
|
2394
|
+
*
|
|
2395
|
+
* @spec openspec/changes/dashboard-board-termijnen/specs/dashboard-page/spec.md#requirement-a-page-filter-as-a-segmented-group-on-the-description-line
|
|
2396
|
+
* @return {Array<object>}
|
|
2397
|
+
*/
|
|
2398
|
+
rowPageFilters() {
|
|
2399
|
+
const inDescription = this.descriptionPageFilters
|
|
2400
|
+
return (this.pageFilters || []).filter((pf) => pf && pf.key && !inDescription.includes(pf))
|
|
2401
|
+
},
|
|
2402
|
+
|
|
2346
2403
|
/**
|
|
2347
2404
|
* The preset list passed to the picker. Falls back to the
|
|
2348
2405
|
* `DEFAULT_DATE_RANGE_PRESETS` constant when the consumer
|
|
@@ -2795,6 +2852,18 @@ export default {
|
|
|
2795
2852
|
return (pf.options || []).find((o) => o.value === current) || null
|
|
2796
2853
|
},
|
|
2797
2854
|
|
|
2855
|
+
/**
|
|
2856
|
+
* A page filter's options as segments, labels through the host
|
|
2857
|
+
* translate.
|
|
2858
|
+
*
|
|
2859
|
+
* @spec openspec/changes/dashboard-board-termijnen/specs/dashboard-page/spec.md#requirement-a-page-filter-as-a-segmented-group-on-the-description-line
|
|
2860
|
+
* @param {object} pf The page-filter descriptor.
|
|
2861
|
+
* @return {Array<{value: (string|number), label: string}>}
|
|
2862
|
+
*/
|
|
2863
|
+
pageFilterSegments(pf) {
|
|
2864
|
+
return (pf.options || []).map((o) => ({ value: o.value, label: o.label ? this.effectiveTranslate(o.label) : String(o.value) }))
|
|
2865
|
+
},
|
|
2866
|
+
|
|
2798
2867
|
/**
|
|
2799
2868
|
* Write a page filter's new selection into the reactive workspace
|
|
2800
2869
|
* context so every `@page.<key>` / `@workspace.<key>` token re-resolves.
|