@conduction/nextcloud-vue 2.100.0 → 2.102.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/CnActionsBar/CnActionsBar.vue2.js +22 -0
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js.map +1 -1
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js +8 -6
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js.map +1 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue.js +1 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue2.js +29 -4
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue3.js +9 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue3.js.map +1 -1
- 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 +70 -6
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +105 -74
- 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 +320 -74
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +323 -213
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/useNamedSource.js +30 -3
- 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/CnMenuWidget/CnMenuWidget.vue.js +1 -1
- package/dist/esm/components/CnMenuWidget/CnMenuWidget.vue2.js +25 -1
- package/dist/esm/components/CnMenuWidget/CnMenuWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnMenuWidget/CnMenuWidget.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/CnQuickFilterBar/CnQuickFilterBar.vue.js +1 -1
- package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue2.js +106 -4
- package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue2.js.map +1 -1
- package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue3.js +70 -25
- package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.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/components/CnWidgetObjectTable/CnWidgetObjectTable.vue.js +1 -1
- package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue2.js +2 -23
- package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue2.js.map +1 -1
- package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue3.js.map +1 -1
- package/dist/esm/composables/indexSources.js +176 -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 +41 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +39 -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 +939 -376
- package/dist/esm/utils/builtInFormatters.js +24 -4
- package/dist/esm/utils/builtInFormatters.js.map +1 -1
- 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/rowClassRules.js +43 -0
- package/dist/esm/utils/rowClassRules.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/esm/utils/visibleWhen.js +19 -2
- package/dist/esm/utils/visibleWhen.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +9681 -7136
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +939 -376
- package/l10n/en.json +41 -1
- package/l10n/nl.json +39 -1
- package/package.json +1 -1
- package/src/components/CnActionsBar/CnActionsBar.md +1 -0
- package/src/components/CnActionsBar/CnActionsBar.vue +31 -4
- package/src/components/CnChartWidget/CnChartWidget.md +3 -2
- package/src/components/CnChartWidget/CnChartWidget.vue +42 -4
- package/src/components/CnChoiceCards/CnChoiceCards.md +39 -0
- package/src/components/CnChoiceCards/CnChoiceCards.vue +93 -16
- package/src/components/CnDashboardPage/CnDashboardPage.vue +110 -21
- 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.md +5 -1
- package/src/components/CnIndexPage/CnIndexPage.vue +313 -9
- package/src/components/CnIndexPage/useNamedSource.js +30 -3
- package/src/components/CnMapWidget/CnMapWidget.vue +37 -0
- package/src/components/CnMenuWidget/CnMenuWidget.vue +25 -1
- 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/CnQuickFilterBar/CnQuickFilterBar.md +1 -0
- package/src/components/CnQuickFilterBar/CnQuickFilterBar.vue +159 -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/CnWidgetObjectTable/CnWidgetObjectTable.vue +2 -23
- package/src/components/index.js +3 -0
- package/src/composables/indexSources.js +175 -19
- package/src/composables/useEndpointSource.js +28 -6
- package/src/css/index-page.css +117 -0
- package/src/css/look-board-index.css +10 -0
- package/src/css/look-board.css +44 -0
- package/src/index.js +1 -0
- package/src/schemas/app-manifest-v2.schema.json +85 -3
- package/src/utils/builtInFormatters.js +24 -4
- package/src/utils/languageMapText.js +46 -0
- package/src/utils/libraryWidgetKeys.js +3 -0
- package/src/utils/mapList.js +67 -0
- package/src/utils/rowClassRules.js +39 -0
- package/src/utils/validateManifestV2.compiled.js +3 -3
- package/src/utils/visibleWhen.js +19 -2
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import script from './CnSavedViewAlertWidget.vue2.js';
|
|
2
|
+
import { render } from './CnSavedViewAlertWidget.vue3.js';
|
|
3
|
+
|
|
4
|
+
script.render = render;
|
|
5
|
+
script.__scopeId = "data-v-4439a3f3";
|
|
6
|
+
const __sfc_main = script;
|
|
7
|
+
|
|
8
|
+
export { __sfc_main as default };
|
|
9
|
+
//# sourceMappingURL=CnSavedViewAlertWidget.vue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CnSavedViewAlertWidget.vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { getCurrentUser } from '@nextcloud/auth';
|
|
2
|
+
import { translatePlural, translate } from '@nextcloud/l10n';
|
|
3
|
+
import { NcCheckboxRadioSwitch, NcTextField } from '@nextcloud/vue';
|
|
4
|
+
import { useSavedViewsApi } from '../../composables/useSavedViewsApi.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* CnSavedViewAlertWidget — the saved view an index page has applied, with its
|
|
8
|
+
* count alert (DqZoekresultaten "Opgeslagen zoekopdracht"): its name, how many
|
|
9
|
+
* rows it holds now, and a switch that asks OpenRegister to tell the reader
|
|
10
|
+
* when the count reaches a threshold.
|
|
11
|
+
*
|
|
12
|
+
* The alert is the view's own `alert` (`{ operator: 'gte', threshold,
|
|
13
|
+
* recipients }`), saved with a PATCH on the view; OpenRegister evaluates it on
|
|
14
|
+
* its sweep and fires on the crossing, not on the state. Switching it off
|
|
15
|
+
* clears it. The widget reads the page through the `cnIndexList` CnIndexPage
|
|
16
|
+
* provides, so it belongs in an index page's `sidePanel`
|
|
17
|
+
* (`type: "saved-view-alert"`).
|
|
18
|
+
*
|
|
19
|
+
* Example (manifest):
|
|
20
|
+
* ```json
|
|
21
|
+
* { "id": "alert", "type": "saved-view-alert", "title": "Saved search", "content": { "noun": { "one": "case", "other": "cases" } } }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
var script = {
|
|
25
|
+
name: 'CnSavedViewAlertWidget',
|
|
26
|
+
|
|
27
|
+
components: { NcCheckboxRadioSwitch, NcTextField },
|
|
28
|
+
|
|
29
|
+
inject: {
|
|
30
|
+
/** The index page's list: its applied saved view and its total. */
|
|
31
|
+
cnIndexList: { default: null },
|
|
32
|
+
/** Host translate function provided by CnAppRoot. */
|
|
33
|
+
cnTranslate: { default: () => (key) => key },
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
props: {
|
|
37
|
+
/**
|
|
38
|
+
* The widget content: `{ noun?: { one, other }, emptyText? }`. `noun`
|
|
39
|
+
* names what is counted ("9 zaken"); `emptyText` shows while no saved
|
|
40
|
+
* view is applied. Both are translated with the app's catalogue.
|
|
41
|
+
*/
|
|
42
|
+
content: {
|
|
43
|
+
type: Object,
|
|
44
|
+
default: () => ({}),
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
data() {
|
|
49
|
+
return { saving: false, error: '', draft: null }
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
computed: {
|
|
53
|
+
/** @return {object|null} The applied saved view, or null. */
|
|
54
|
+
view() {
|
|
55
|
+
return (this.cnIndexList && this.cnIndexList.appliedView) || null
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
/** @return {boolean} Whether the view carries an alert. */
|
|
59
|
+
enabled() {
|
|
60
|
+
const alert = this.view && this.view.alert;
|
|
61
|
+
return Boolean(alert && typeof alert === 'object' && Number.isFinite(Number(alert.threshold)))
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
/** @return {number} The threshold being edited, else the view's, else 10. */
|
|
65
|
+
threshold() {
|
|
66
|
+
if (this.draft !== null) {
|
|
67
|
+
return this.draft
|
|
68
|
+
}
|
|
69
|
+
const value = this.enabled ? Number(this.view.alert.threshold) : 10;
|
|
70
|
+
return Number.isFinite(value) ? value : 10
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
/** @return {boolean} Whether the reader may change the view: its owner, or when the view says nothing. */
|
|
74
|
+
canEdit() {
|
|
75
|
+
const owner = this.view && this.view.owner;
|
|
76
|
+
if (!owner) {
|
|
77
|
+
return true
|
|
78
|
+
}
|
|
79
|
+
const user = getCurrentUser();
|
|
80
|
+
return Boolean(user && user.uid === owner)
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
/** @return {string} "9 zaken", or '' while the total is unknown. */
|
|
84
|
+
countText() {
|
|
85
|
+
const total = this.cnIndexList ? this.cnIndexList.total : undefined;
|
|
86
|
+
if (typeof total !== 'number') {
|
|
87
|
+
return ''
|
|
88
|
+
}
|
|
89
|
+
const noun = this.content && this.content.noun;
|
|
90
|
+
if (noun && typeof noun === 'object' && noun.one && noun.other) {
|
|
91
|
+
return `${total} ${this.cnTranslate(total === 1 ? noun.one : noun.other)}`
|
|
92
|
+
}
|
|
93
|
+
return translatePlural('nextcloud-vue', '%n result', '%n results', total)
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
/** @return {string} The line under the switch. */
|
|
97
|
+
hintText() {
|
|
98
|
+
return translate('nextcloud-vue', 'A message to you when there are {threshold} or more', { threshold: this.threshold })
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
/** @return {string} What shows while no saved view is applied. */
|
|
102
|
+
emptyText() {
|
|
103
|
+
const own = this.content && this.content.emptyText;
|
|
104
|
+
return own ? this.cnTranslate(own) : translate('nextcloud-vue', 'Save this search or open a saved one to set an alert on it.')
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
methods: {
|
|
109
|
+
t: translate,
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Switch the alert on (at the shown threshold) or off.
|
|
113
|
+
*
|
|
114
|
+
* @param {boolean} on The new state.
|
|
115
|
+
* @return {Promise<void>}
|
|
116
|
+
*/
|
|
117
|
+
async onToggle(on) {
|
|
118
|
+
await this.save(on ? this.alertFor(this.threshold) : null);
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Save a new threshold, when the alert is on.
|
|
123
|
+
*
|
|
124
|
+
* @param {string} value The typed value.
|
|
125
|
+
* @return {Promise<void>}
|
|
126
|
+
*/
|
|
127
|
+
async onThreshold(value) {
|
|
128
|
+
const number = Math.max(0, Math.floor(Number(value)));
|
|
129
|
+
if (!Number.isFinite(number)) {
|
|
130
|
+
return
|
|
131
|
+
}
|
|
132
|
+
this.draft = number;
|
|
133
|
+
await this.save(this.alertFor(number));
|
|
134
|
+
this.draft = null;
|
|
135
|
+
},
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* The alert the view stores: reaching the threshold tells the reader.
|
|
139
|
+
*
|
|
140
|
+
* @param {number} threshold The threshold.
|
|
141
|
+
* @return {{operator: string, threshold: number, recipients: Array<string>}}
|
|
142
|
+
*/
|
|
143
|
+
alertFor(threshold) {
|
|
144
|
+
const user = getCurrentUser();
|
|
145
|
+
return { operator: 'gte', threshold, recipients: user && user.uid ? [user.uid] : [] }
|
|
146
|
+
},
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* PATCH the view's alert and hand the saved view back to the page.
|
|
150
|
+
*
|
|
151
|
+
* @param {object|null} alert The alert, or null to clear it.
|
|
152
|
+
* @return {Promise<void>}
|
|
153
|
+
*/
|
|
154
|
+
async save(alert) {
|
|
155
|
+
if (!this.view) {
|
|
156
|
+
return
|
|
157
|
+
}
|
|
158
|
+
this.saving = true;
|
|
159
|
+
this.error = '';
|
|
160
|
+
try {
|
|
161
|
+
const saved = await useSavedViewsApi().patchView(this.view.uuid || this.view.id, { alert });
|
|
162
|
+
if (saved && this.cnIndexList && typeof this.cnIndexList.replaceSavedView === 'function') {
|
|
163
|
+
this.cnIndexList.replaceSavedView(saved);
|
|
164
|
+
}
|
|
165
|
+
} catch (error) {
|
|
166
|
+
this.error = (error && error.response && error.response.data && error.response.data.error) || translate('nextcloud-vue', 'The alert could not be saved.');
|
|
167
|
+
} finally {
|
|
168
|
+
this.saving = false;
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
export { script as default };
|
|
175
|
+
//# sourceMappingURL=CnSavedViewAlertWidget.vue2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CnSavedViewAlertWidget.vue2.js","sources":["../../../../src/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n<template>\n\t<div class=\"cn-saved-view-alert\" data-testid=\"cn-saved-view-alert\">\n\t\t<p v-if=\"!view\" class=\"cn-saved-view-alert__empty\" data-testid=\"cn-saved-view-alert-empty\">\n\t\t\t{{ emptyText }}\n\t\t</p>\n\t\t<template v-else>\n\t\t\t<dl class=\"cn-saved-view-alert__facts\">\n\t\t\t\t<dt>{{ t('nextcloud-vue', 'Name') }}</dt>\n\t\t\t\t<dd data-testid=\"cn-saved-view-alert-name\">\n\t\t\t\t\t{{ view.name }}\n\t\t\t\t</dd>\n\t\t\t\t<template v-if=\"countText\">\n\t\t\t\t\t<dt>{{ t('nextcloud-vue', 'Now') }}</dt>\n\t\t\t\t\t<dd data-testid=\"cn-saved-view-alert-count\">\n\t\t\t\t\t\t{{ countText }}\n\t\t\t\t\t</dd>\n\t\t\t\t</template>\n\t\t\t</dl>\n\t\t\t<NcCheckboxRadioSwitch\n\t\t\t\ttype=\"switch\"\n\t\t\t\t:modelValue=\"enabled\"\n\t\t\t\t:disabled=\"saving || !canEdit\"\n\t\t\t\tdata-testid=\"cn-saved-view-alert-switch\"\n\t\t\t\t@update:modelValue=\"onToggle\">\n\t\t\t\t<span class=\"cn-saved-view-alert__switch-text\">\n\t\t\t\t\t<span>{{ t('nextcloud-vue', 'Tell me above a number') }}</span>\n\t\t\t\t\t<span class=\"cn-saved-view-alert__hint\">{{ hintText }}</span>\n\t\t\t\t</span>\n\t\t\t</NcCheckboxRadioSwitch>\n\t\t\t<NcTextField v-if=\"enabled\"\n\t\t\t\t:modelValue=\"String(threshold)\"\n\t\t\t\ttype=\"number\"\n\t\t\t\tmin=\"0\"\n\t\t\t\t:label=\"t('nextcloud-vue', 'Threshold')\"\n\t\t\t\t:disabled=\"saving || !canEdit\"\n\t\t\t\tdata-testid=\"cn-saved-view-alert-threshold\"\n\t\t\t\t@update:modelValue=\"onThreshold\" />\n\t\t\t<p v-if=\"error\"\n\t\t\t\tclass=\"cn-saved-view-alert__error\"\n\t\t\t\trole=\"alert\"\n\t\t\t\tdata-testid=\"cn-saved-view-alert-error\">\n\t\t\t\t{{ error }}\n\t\t\t</p>\n\t\t</template>\n\t</div>\n</template>\n\n<script>\nimport { getCurrentUser } from '@nextcloud/auth'\nimport { translatePlural as n, translate as t } from '@nextcloud/l10n'\nimport { NcCheckboxRadioSwitch, NcTextField } from '@nextcloud/vue'\nimport { useSavedViewsApi } from '../../composables/useSavedViewsApi.js'\n\n/**\n * CnSavedViewAlertWidget — the saved view an index page has applied, with its\n * count alert (DqZoekresultaten \"Opgeslagen zoekopdracht\"): its name, how many\n * rows it holds now, and a switch that asks OpenRegister to tell the reader\n * when the count reaches a threshold.\n *\n * The alert is the view's own `alert` (`{ operator: 'gte', threshold,\n * recipients }`), saved with a PATCH on the view; OpenRegister evaluates it on\n * its sweep and fires on the crossing, not on the state. Switching it off\n * clears it. The widget reads the page through the `cnIndexList` CnIndexPage\n * provides, so it belongs in an index page's `sidePanel`\n * (`type: \"saved-view-alert\"`).\n *\n * Example (manifest):\n * ```json\n * { \"id\": \"alert\", \"type\": \"saved-view-alert\", \"title\": \"Saved search\", \"content\": { \"noun\": { \"one\": \"case\", \"other\": \"cases\" } } }\n * ```\n */\nexport default {\n\tname: 'CnSavedViewAlertWidget',\n\n\tcomponents: { NcCheckboxRadioSwitch, NcTextField },\n\n\tinject: {\n\t\t/** The index page's list: its applied saved view and its total. */\n\t\tcnIndexList: { default: null },\n\t\t/** Host translate function provided by CnAppRoot. */\n\t\tcnTranslate: { default: () => (key) => key },\n\t},\n\n\tprops: {\n\t\t/**\n\t\t * The widget content: `{ noun?: { one, other }, emptyText? }`. `noun`\n\t\t * names what is counted (\"9 zaken\"); `emptyText` shows while no saved\n\t\t * view is applied. Both are translated with the app's catalogue.\n\t\t */\n\t\tcontent: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\t},\n\n\tdata() {\n\t\treturn { saving: false, error: '', draft: null }\n\t},\n\n\tcomputed: {\n\t\t/** @return {object|null} The applied saved view, or null. */\n\t\tview() {\n\t\t\treturn (this.cnIndexList && this.cnIndexList.appliedView) || null\n\t\t},\n\n\t\t/** @return {boolean} Whether the view carries an alert. */\n\t\tenabled() {\n\t\t\tconst alert = this.view && this.view.alert\n\t\t\treturn Boolean(alert && typeof alert === 'object' && Number.isFinite(Number(alert.threshold)))\n\t\t},\n\n\t\t/** @return {number} The threshold being edited, else the view's, else 10. */\n\t\tthreshold() {\n\t\t\tif (this.draft !== null) {\n\t\t\t\treturn this.draft\n\t\t\t}\n\t\t\tconst value = this.enabled ? Number(this.view.alert.threshold) : 10\n\t\t\treturn Number.isFinite(value) ? value : 10\n\t\t},\n\n\t\t/** @return {boolean} Whether the reader may change the view: its owner, or when the view says nothing. */\n\t\tcanEdit() {\n\t\t\tconst owner = this.view && this.view.owner\n\t\t\tif (!owner) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tconst user = getCurrentUser()\n\t\t\treturn Boolean(user && user.uid === owner)\n\t\t},\n\n\t\t/** @return {string} \"9 zaken\", or '' while the total is unknown. */\n\t\tcountText() {\n\t\t\tconst total = this.cnIndexList ? this.cnIndexList.total : undefined\n\t\t\tif (typeof total !== 'number') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tconst noun = this.content && this.content.noun\n\t\t\tif (noun && typeof noun === 'object' && noun.one && noun.other) {\n\t\t\t\treturn `${total} ${this.cnTranslate(total === 1 ? noun.one : noun.other)}`\n\t\t\t}\n\t\t\treturn n('nextcloud-vue', '%n result', '%n results', total)\n\t\t},\n\n\t\t/** @return {string} The line under the switch. */\n\t\thintText() {\n\t\t\treturn t('nextcloud-vue', 'A message to you when there are {threshold} or more', { threshold: this.threshold })\n\t\t},\n\n\t\t/** @return {string} What shows while no saved view is applied. */\n\t\temptyText() {\n\t\t\tconst own = this.content && this.content.emptyText\n\t\t\treturn own ? this.cnTranslate(own) : t('nextcloud-vue', 'Save this search or open a saved one to set an alert on it.')\n\t\t},\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\t/**\n\t\t * Switch the alert on (at the shown threshold) or off.\n\t\t *\n\t\t * @param {boolean} on The new state.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync onToggle(on) {\n\t\t\tawait this.save(on ? this.alertFor(this.threshold) : null)\n\t\t},\n\n\t\t/**\n\t\t * Save a new threshold, when the alert is on.\n\t\t *\n\t\t * @param {string} value The typed value.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync onThreshold(value) {\n\t\t\tconst number = Math.max(0, Math.floor(Number(value)))\n\t\t\tif (!Number.isFinite(number)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.draft = number\n\t\t\tawait this.save(this.alertFor(number))\n\t\t\tthis.draft = null\n\t\t},\n\n\t\t/**\n\t\t * The alert the view stores: reaching the threshold tells the reader.\n\t\t *\n\t\t * @param {number} threshold The threshold.\n\t\t * @return {{operator: string, threshold: number, recipients: Array<string>}}\n\t\t */\n\t\talertFor(threshold) {\n\t\t\tconst user = getCurrentUser()\n\t\t\treturn { operator: 'gte', threshold, recipients: user && user.uid ? [user.uid] : [] }\n\t\t},\n\n\t\t/**\n\t\t * PATCH the view's alert and hand the saved view back to the page.\n\t\t *\n\t\t * @param {object|null} alert The alert, or null to clear it.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync save(alert) {\n\t\t\tif (!this.view) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.saving = true\n\t\t\tthis.error = ''\n\t\t\ttry {\n\t\t\t\tconst saved = await useSavedViewsApi().patchView(this.view.uuid || this.view.id, { alert })\n\t\t\t\tif (saved && this.cnIndexList && typeof this.cnIndexList.replaceSavedView === 'function') {\n\t\t\t\t\tthis.cnIndexList.replaceSavedView(saved)\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tthis.error = (error && error.response && error.response.data && error.response.data.error) || t('nextcloud-vue', 'The alert could not be saved.')\n\t\t\t} finally {\n\t\t\t\tthis.saving = false\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-saved-view-alert {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 12px;\n\tfont-size: 14px;\n}\n\n.cn-saved-view-alert__facts {\n\tdisplay: grid;\n\tgrid-template-columns: max-content 1fr;\n\tgap: 6px 16px;\n\tmargin: 0;\n}\n\n.cn-saved-view-alert__facts dt {\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-saved-view-alert__facts dd {\n\tmargin: 0;\n\tfont-weight: 500;\n}\n\n.cn-saved-view-alert__switch-text {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 2px;\n}\n\n.cn-saved-view-alert__hint,\n.cn-saved-view-alert__empty {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 13px;\n}\n\n.cn-saved-view-alert__empty,\n.cn-saved-view-alert__error {\n\tmargin: 0;\n}\n\n.cn-saved-view-alert__error {\n\tcolor: var(--color-error-text, var(--color-error));\n\tfont-size: 13px;\n}\n</style>\n"],"names":["n","t"],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { resolveComponent, openBlock, createElementBlock, toDisplayString, Fragment, createElementVNode, createCommentVNode, createVNode, withCtx, createBlock } from 'vue';
|
|
2
|
+
|
|
3
|
+
const _hoisted_1 = {
|
|
4
|
+
class: "cn-saved-view-alert",
|
|
5
|
+
"data-testid": "cn-saved-view-alert"
|
|
6
|
+
};
|
|
7
|
+
const _hoisted_2 = {
|
|
8
|
+
key: 0,
|
|
9
|
+
class: "cn-saved-view-alert__empty",
|
|
10
|
+
"data-testid": "cn-saved-view-alert-empty"
|
|
11
|
+
};
|
|
12
|
+
const _hoisted_3 = { class: "cn-saved-view-alert__facts" };
|
|
13
|
+
const _hoisted_4 = { "data-testid": "cn-saved-view-alert-name" };
|
|
14
|
+
const _hoisted_5 = { "data-testid": "cn-saved-view-alert-count" };
|
|
15
|
+
const _hoisted_6 = { class: "cn-saved-view-alert__switch-text" };
|
|
16
|
+
const _hoisted_7 = { class: "cn-saved-view-alert__hint" };
|
|
17
|
+
const _hoisted_8 = {
|
|
18
|
+
key: 1,
|
|
19
|
+
class: "cn-saved-view-alert__error",
|
|
20
|
+
role: "alert",
|
|
21
|
+
"data-testid": "cn-saved-view-alert-error"
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
25
|
+
const _component_NcCheckboxRadioSwitch = resolveComponent("NcCheckboxRadioSwitch");
|
|
26
|
+
const _component_NcTextField = resolveComponent("NcTextField");
|
|
27
|
+
|
|
28
|
+
return (openBlock(), createElementBlock("div", _hoisted_1, [
|
|
29
|
+
(!$options.view)
|
|
30
|
+
? (openBlock(), createElementBlock("p", _hoisted_2, toDisplayString($options.emptyText), 1 /* TEXT */))
|
|
31
|
+
: (openBlock(), createElementBlock(Fragment, { key: 1 }, [
|
|
32
|
+
createElementVNode("dl", _hoisted_3, [
|
|
33
|
+
createElementVNode("dt", null, toDisplayString($options.t('nextcloud-vue', 'Name')), 1 /* TEXT */),
|
|
34
|
+
createElementVNode("dd", _hoisted_4, toDisplayString($options.view.name), 1 /* TEXT */),
|
|
35
|
+
($options.countText)
|
|
36
|
+
? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
|
|
37
|
+
createElementVNode("dt", null, toDisplayString($options.t('nextcloud-vue', 'Now')), 1 /* TEXT */),
|
|
38
|
+
createElementVNode("dd", _hoisted_5, toDisplayString($options.countText), 1 /* TEXT */)
|
|
39
|
+
], 64 /* STABLE_FRAGMENT */))
|
|
40
|
+
: createCommentVNode("v-if", true)
|
|
41
|
+
]),
|
|
42
|
+
createVNode(_component_NcCheckboxRadioSwitch, {
|
|
43
|
+
type: "switch",
|
|
44
|
+
modelValue: $options.enabled,
|
|
45
|
+
disabled: $data.saving || !$options.canEdit,
|
|
46
|
+
"data-testid": "cn-saved-view-alert-switch",
|
|
47
|
+
"onUpdate:modelValue": $options.onToggle
|
|
48
|
+
}, {
|
|
49
|
+
default: withCtx(() => [
|
|
50
|
+
createElementVNode("span", _hoisted_6, [
|
|
51
|
+
createElementVNode("span", null, toDisplayString($options.t('nextcloud-vue', 'Tell me above a number')), 1 /* TEXT */),
|
|
52
|
+
createElementVNode("span", _hoisted_7, toDisplayString($options.hintText), 1 /* TEXT */)
|
|
53
|
+
])
|
|
54
|
+
]),
|
|
55
|
+
_: 1 /* STABLE */
|
|
56
|
+
}, 8 /* PROPS */, ["modelValue", "disabled", "onUpdate:modelValue"]),
|
|
57
|
+
($options.enabled)
|
|
58
|
+
? (openBlock(), createBlock(_component_NcTextField, {
|
|
59
|
+
key: 0,
|
|
60
|
+
modelValue: String($options.threshold),
|
|
61
|
+
type: "number",
|
|
62
|
+
min: "0",
|
|
63
|
+
label: $options.t('nextcloud-vue', 'Threshold'),
|
|
64
|
+
disabled: $data.saving || !$options.canEdit,
|
|
65
|
+
"data-testid": "cn-saved-view-alert-threshold",
|
|
66
|
+
"onUpdate:modelValue": $options.onThreshold
|
|
67
|
+
}, null, 8 /* PROPS */, ["modelValue", "label", "disabled", "onUpdate:modelValue"]))
|
|
68
|
+
: createCommentVNode("v-if", true),
|
|
69
|
+
($data.error)
|
|
70
|
+
? (openBlock(), createElementBlock("p", _hoisted_8, toDisplayString($data.error), 1 /* TEXT */))
|
|
71
|
+
: createCommentVNode("v-if", true)
|
|
72
|
+
], 64 /* STABLE_FRAGMENT */))
|
|
73
|
+
]))
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export { render };
|
|
77
|
+
//# sourceMappingURL=CnSavedViewAlertWidget.vue3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CnSavedViewAlertWidget.vue3.js","sources":["../../../../src/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue?vue&type=template&id=4439a3f3&lang.js"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n<template>\n\t<div class=\"cn-saved-view-alert\" data-testid=\"cn-saved-view-alert\">\n\t\t<p v-if=\"!view\" class=\"cn-saved-view-alert__empty\" data-testid=\"cn-saved-view-alert-empty\">\n\t\t\t{{ emptyText }}\n\t\t</p>\n\t\t<template v-else>\n\t\t\t<dl class=\"cn-saved-view-alert__facts\">\n\t\t\t\t<dt>{{ t('nextcloud-vue', 'Name') }}</dt>\n\t\t\t\t<dd data-testid=\"cn-saved-view-alert-name\">\n\t\t\t\t\t{{ view.name }}\n\t\t\t\t</dd>\n\t\t\t\t<template v-if=\"countText\">\n\t\t\t\t\t<dt>{{ t('nextcloud-vue', 'Now') }}</dt>\n\t\t\t\t\t<dd data-testid=\"cn-saved-view-alert-count\">\n\t\t\t\t\t\t{{ countText }}\n\t\t\t\t\t</dd>\n\t\t\t\t</template>\n\t\t\t</dl>\n\t\t\t<NcCheckboxRadioSwitch\n\t\t\t\ttype=\"switch\"\n\t\t\t\t:modelValue=\"enabled\"\n\t\t\t\t:disabled=\"saving || !canEdit\"\n\t\t\t\tdata-testid=\"cn-saved-view-alert-switch\"\n\t\t\t\t@update:modelValue=\"onToggle\">\n\t\t\t\t<span class=\"cn-saved-view-alert__switch-text\">\n\t\t\t\t\t<span>{{ t('nextcloud-vue', 'Tell me above a number') }}</span>\n\t\t\t\t\t<span class=\"cn-saved-view-alert__hint\">{{ hintText }}</span>\n\t\t\t\t</span>\n\t\t\t</NcCheckboxRadioSwitch>\n\t\t\t<NcTextField v-if=\"enabled\"\n\t\t\t\t:modelValue=\"String(threshold)\"\n\t\t\t\ttype=\"number\"\n\t\t\t\tmin=\"0\"\n\t\t\t\t:label=\"t('nextcloud-vue', 'Threshold')\"\n\t\t\t\t:disabled=\"saving || !canEdit\"\n\t\t\t\tdata-testid=\"cn-saved-view-alert-threshold\"\n\t\t\t\t@update:modelValue=\"onThreshold\" />\n\t\t\t<p v-if=\"error\"\n\t\t\t\tclass=\"cn-saved-view-alert__error\"\n\t\t\t\trole=\"alert\"\n\t\t\t\tdata-testid=\"cn-saved-view-alert-error\">\n\t\t\t\t{{ error }}\n\t\t\t</p>\n\t\t</template>\n\t</div>\n</template>\n\n<script>\nimport { getCurrentUser } from '@nextcloud/auth'\nimport { translatePlural as n, translate as t } from '@nextcloud/l10n'\nimport { NcCheckboxRadioSwitch, NcTextField } from '@nextcloud/vue'\nimport { useSavedViewsApi } from '../../composables/useSavedViewsApi.js'\n\n/**\n * CnSavedViewAlertWidget — the saved view an index page has applied, with its\n * count alert (DqZoekresultaten \"Opgeslagen zoekopdracht\"): its name, how many\n * rows it holds now, and a switch that asks OpenRegister to tell the reader\n * when the count reaches a threshold.\n *\n * The alert is the view's own `alert` (`{ operator: 'gte', threshold,\n * recipients }`), saved with a PATCH on the view; OpenRegister evaluates it on\n * its sweep and fires on the crossing, not on the state. Switching it off\n * clears it. The widget reads the page through the `cnIndexList` CnIndexPage\n * provides, so it belongs in an index page's `sidePanel`\n * (`type: \"saved-view-alert\"`).\n *\n * Example (manifest):\n * ```json\n * { \"id\": \"alert\", \"type\": \"saved-view-alert\", \"title\": \"Saved search\", \"content\": { \"noun\": { \"one\": \"case\", \"other\": \"cases\" } } }\n * ```\n */\nexport default {\n\tname: 'CnSavedViewAlertWidget',\n\n\tcomponents: { NcCheckboxRadioSwitch, NcTextField },\n\n\tinject: {\n\t\t/** The index page's list: its applied saved view and its total. */\n\t\tcnIndexList: { default: null },\n\t\t/** Host translate function provided by CnAppRoot. */\n\t\tcnTranslate: { default: () => (key) => key },\n\t},\n\n\tprops: {\n\t\t/**\n\t\t * The widget content: `{ noun?: { one, other }, emptyText? }`. `noun`\n\t\t * names what is counted (\"9 zaken\"); `emptyText` shows while no saved\n\t\t * view is applied. Both are translated with the app's catalogue.\n\t\t */\n\t\tcontent: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\t},\n\n\tdata() {\n\t\treturn { saving: false, error: '', draft: null }\n\t},\n\n\tcomputed: {\n\t\t/** @return {object|null} The applied saved view, or null. */\n\t\tview() {\n\t\t\treturn (this.cnIndexList && this.cnIndexList.appliedView) || null\n\t\t},\n\n\t\t/** @return {boolean} Whether the view carries an alert. */\n\t\tenabled() {\n\t\t\tconst alert = this.view && this.view.alert\n\t\t\treturn Boolean(alert && typeof alert === 'object' && Number.isFinite(Number(alert.threshold)))\n\t\t},\n\n\t\t/** @return {number} The threshold being edited, else the view's, else 10. */\n\t\tthreshold() {\n\t\t\tif (this.draft !== null) {\n\t\t\t\treturn this.draft\n\t\t\t}\n\t\t\tconst value = this.enabled ? Number(this.view.alert.threshold) : 10\n\t\t\treturn Number.isFinite(value) ? value : 10\n\t\t},\n\n\t\t/** @return {boolean} Whether the reader may change the view: its owner, or when the view says nothing. */\n\t\tcanEdit() {\n\t\t\tconst owner = this.view && this.view.owner\n\t\t\tif (!owner) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tconst user = getCurrentUser()\n\t\t\treturn Boolean(user && user.uid === owner)\n\t\t},\n\n\t\t/** @return {string} \"9 zaken\", or '' while the total is unknown. */\n\t\tcountText() {\n\t\t\tconst total = this.cnIndexList ? this.cnIndexList.total : undefined\n\t\t\tif (typeof total !== 'number') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\tconst noun = this.content && this.content.noun\n\t\t\tif (noun && typeof noun === 'object' && noun.one && noun.other) {\n\t\t\t\treturn `${total} ${this.cnTranslate(total === 1 ? noun.one : noun.other)}`\n\t\t\t}\n\t\t\treturn n('nextcloud-vue', '%n result', '%n results', total)\n\t\t},\n\n\t\t/** @return {string} The line under the switch. */\n\t\thintText() {\n\t\t\treturn t('nextcloud-vue', 'A message to you when there are {threshold} or more', { threshold: this.threshold })\n\t\t},\n\n\t\t/** @return {string} What shows while no saved view is applied. */\n\t\temptyText() {\n\t\t\tconst own = this.content && this.content.emptyText\n\t\t\treturn own ? this.cnTranslate(own) : t('nextcloud-vue', 'Save this search or open a saved one to set an alert on it.')\n\t\t},\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\t/**\n\t\t * Switch the alert on (at the shown threshold) or off.\n\t\t *\n\t\t * @param {boolean} on The new state.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync onToggle(on) {\n\t\t\tawait this.save(on ? this.alertFor(this.threshold) : null)\n\t\t},\n\n\t\t/**\n\t\t * Save a new threshold, when the alert is on.\n\t\t *\n\t\t * @param {string} value The typed value.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync onThreshold(value) {\n\t\t\tconst number = Math.max(0, Math.floor(Number(value)))\n\t\t\tif (!Number.isFinite(number)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.draft = number\n\t\t\tawait this.save(this.alertFor(number))\n\t\t\tthis.draft = null\n\t\t},\n\n\t\t/**\n\t\t * The alert the view stores: reaching the threshold tells the reader.\n\t\t *\n\t\t * @param {number} threshold The threshold.\n\t\t * @return {{operator: string, threshold: number, recipients: Array<string>}}\n\t\t */\n\t\talertFor(threshold) {\n\t\t\tconst user = getCurrentUser()\n\t\t\treturn { operator: 'gte', threshold, recipients: user && user.uid ? [user.uid] : [] }\n\t\t},\n\n\t\t/**\n\t\t * PATCH the view's alert and hand the saved view back to the page.\n\t\t *\n\t\t * @param {object|null} alert The alert, or null to clear it.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync save(alert) {\n\t\t\tif (!this.view) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.saving = true\n\t\t\tthis.error = ''\n\t\t\ttry {\n\t\t\t\tconst saved = await useSavedViewsApi().patchView(this.view.uuid || this.view.id, { alert })\n\t\t\t\tif (saved && this.cnIndexList && typeof this.cnIndexList.replaceSavedView === 'function') {\n\t\t\t\t\tthis.cnIndexList.replaceSavedView(saved)\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tthis.error = (error && error.response && error.response.data && error.response.data.error) || t('nextcloud-vue', 'The alert could not be saved.')\n\t\t\t} finally {\n\t\t\t\tthis.saving = false\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-saved-view-alert {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 12px;\n\tfont-size: 14px;\n}\n\n.cn-saved-view-alert__facts {\n\tdisplay: grid;\n\tgrid-template-columns: max-content 1fr;\n\tgap: 6px 16px;\n\tmargin: 0;\n}\n\n.cn-saved-view-alert__facts dt {\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-saved-view-alert__facts dd {\n\tmargin: 0;\n\tfont-weight: 500;\n}\n\n.cn-saved-view-alert__switch-text {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 2px;\n}\n\n.cn-saved-view-alert__hint,\n.cn-saved-view-alert__empty {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 13px;\n}\n\n.cn-saved-view-alert__empty,\n.cn-saved-view-alert__error {\n\tmargin: 0;\n}\n\n.cn-saved-view-alert__error {\n\tcolor: var(--color-error-text, var(--color-error));\n\tfont-size: 13px;\n}\n</style>\n"],"names":["_openBlock","_createElementBlock","_toDisplayString","_createElementVNode","_Fragment","_createVNode","_createBlock"],"mappings":";;;AASM,EAAA,KAAI,EAAE,qBAAM;AAAA,EAAA,aAAA,EAAA,qBAAA;;;;AACA,EAAA,KAAK,EAAC,4BAAiB;AAAA,EAAA,aAAA,EAAA,2BAAA;;AAIlC,MAAA,UAAA,GAAA,EAAA,KAAC,EAAA,4BAAA,GAAA;AAEA,MAAA,UAAA,GAAA,EAAA,aAAW,EAAC,0BAAwB,GAAA;AAKrC,MAAA,UAAA,GAAA,EAAA,aAAA,EAAA,2BAAA,GAAA;AAWG,MAAA,UAAA,GAAA,EAAA,KAAK,EAAC,kCAAU,GAAA;AAEf,MAAA,UAAA,GAAA,EAAA,KAAK,EAAC,2BAAiB,GAAA;;;AAY9B,EAAA,KAAE,EAAA,4BAAA;AACF,EAAA,IAAI,EAAC,OAAG;AACR,EAAA,aAAE,EAAA,2BAAA;;;;;;;AAvCJ,EAAA,QAAAA,SAAA,EAAA,EAAAC,kBAAA,QAAA;MACU,QAAI,CAAA,IAAA;sBAAbA,kBAEG,CAAA,GAAA,EAFH,UAEG,EAAAC,eAAA,CADA,QAAS,CAAA,SAAA,CAAA,EAAA,CAAA,YAAA;;6BAcP,gBAAA,EAAA;AAVJ,YAAAC,kBAAA,CAA0B,4BAAnB,QAAC,CAAA,CAAA,CAAA,eAAA,EAAA,MAAA,CAAA,CAAA,EAAA,CAAA,YAAA;AACP,YAAAA,kBAAA,CAEI,IAFJ,EAAA,UAEI,EADAD,eAAA,CAAA,QAAA,CAAA,IAAG,CAAC,IAAI,CAAA,EAAA,CAAA,YAAA;aAER,QAAA,CAAA,SAAA;gDAKM,CAAAE,QAAA,EAAA,EAAA,GAAA,EAAA,CAAA,EAAA,EAAA;AAJV,kBAAAD,kBAAA,CAAS,4BAAF,QAAC,CAAA,CAAA,CAAA,eAAA,EAAA,KAAA,CAAA,CAAA,EAAA,CAAA,YAAA;kBACRA,kBAEK,CAAA,IAAA,EAFL,UAEK,EAAAD,eAAA,CADD,QAAS,CAAA,SAAA,CAAA,EAAA,CAAA,YAAA;;;;UAIdG,WAUM,CAAA,gCAAA,EAAA;AATN,YAAA,IAAI,EAAC,QAAQ;AACZ,YAAA,UAAU,EAAE,QAAO,CAAA,OAAA;YACnB,QAAS,EAAC,KAAM,CAAA,MAAA,IAAA,CAAK,QAAO,CAAA,OAAA;yBAClB,EAAC,4BAA4B;AACvC,YAAA,qBAAK,EAAA,QAAA,CAAA,QAAA;;6BACN,MAGO;AAHP,cAAAF,kBAAA,CAGO,QAHP,UAGO,EAAA;AAFN,gBAAAA,kBAAA,CAAwB,8BAAf,QAAA,CAAA,CAAA,CAAA,eAAA,EAAA,wBAAA,CAAA,CAAA,EAAA,CAAA,YAAA;gBACTA,kBAA6B,CAAA,MAAA,EAA7B,UAA6B,EAAAD,eAAA,CAAA,QAAA,CAAA,QAAA,CAAA,EAAA,CAAA,YAAA;;;;;WAGZ,QAAO,CAAA,OAAA;4BAAzBI,WAOmC,CAAA,sBAAA,EAAA;;gBANlC,UAAU,EAAE,MAAM,CAAE,QAAQ,CAAA,SAAA,CAAA;AAC7B,gBAAA,IAAI,EAAC,QAAQ;AACb,gBAAA,GAAG,EAAC,GAAG;AACP,gBAAA,KAAM,EAAE,QAAC,CAAA,CAAA,CAAA,eAAA,EAAA,WAAA,CAAA;gBACR,QAAQ,EAAE,KAAM,CAAA,MAAA,IAAA,CAAK,QAAO,CAAA,OAAA;AAC7B,gBAAA,aAAW,EAAA,+BAAA;AACV,gBAAA,qBAAiB,EAAE,QAAW,CAAA,WAAA;;;gBACrB,CAAA,KAAA;4BAAVL,wBAAA;;;;;;;;"}
|
|
@@ -2,7 +2,7 @@ import script from './CnSetupWizard.vue2.js';
|
|
|
2
2
|
import { render } from './CnSetupWizard.vue3.js';
|
|
3
3
|
|
|
4
4
|
script.render = render;
|
|
5
|
-
script.__scopeId = "data-v-
|
|
5
|
+
script.__scopeId = "data-v-44988d3d";
|
|
6
6
|
const __sfc_main = script;
|
|
7
7
|
|
|
8
8
|
export { __sfc_main as default };
|
|
@@ -223,7 +223,7 @@ var script = {
|
|
|
223
223
|
*/
|
|
224
224
|
setup(props) {
|
|
225
225
|
const { isBoard } = useLook();
|
|
226
|
-
const wantsSource = (props.steps || []).some((s) => s && s.optionsSource);
|
|
226
|
+
const wantsSource = (props.steps || []).some((s) => s && (s.optionsSource || s.visibleWhen));
|
|
227
227
|
if (!wantsSource) {
|
|
228
228
|
return { isBoard }
|
|
229
229
|
}
|
|
@@ -291,7 +291,7 @@ var script = {
|
|
|
291
291
|
|
|
292
292
|
setupSteps() {
|
|
293
293
|
const skipped = new Set(this.skippedSteps.map((entry) => entry.step.id));
|
|
294
|
-
return this.declaredSteps.filter((s) => !skipped.has(s.id))
|
|
294
|
+
return this.declaredSteps.filter((s) => !skipped.has(s.id) && this.stepConditionHolds(s))
|
|
295
295
|
},
|
|
296
296
|
|
|
297
297
|
/**
|
|
@@ -654,6 +654,39 @@ var script = {
|
|
|
654
654
|
})
|
|
655
655
|
},
|
|
656
656
|
|
|
657
|
+
/**
|
|
658
|
+
* Whether a step's `visibleWhen` holds: the value at that path in the
|
|
659
|
+
* setup status (`"flags.hasPayouts"`, dots walk into objects) is truthy,
|
|
660
|
+
* or equals `equals` when the step gives `{ path, equals }`. A step
|
|
661
|
+
* without `visibleWhen` always shows; one with it stays hidden until the
|
|
662
|
+
* status says so, also while the status loads (DqInstellen: the dwangsom
|
|
663
|
+
* step only when the app pays penalties).
|
|
664
|
+
*
|
|
665
|
+
* @param {object} step The step declaration.
|
|
666
|
+
* @return {boolean}
|
|
667
|
+
*/
|
|
668
|
+
stepConditionHolds(step) {
|
|
669
|
+
const when = step && step.visibleWhen;
|
|
670
|
+
if (when === undefined || when === null || when === '') {
|
|
671
|
+
return true
|
|
672
|
+
}
|
|
673
|
+
const path = typeof when === 'string' ? when : when.path;
|
|
674
|
+
if (typeof path !== 'string' || path === '') {
|
|
675
|
+
return true
|
|
676
|
+
}
|
|
677
|
+
let node = this.setupStatus;
|
|
678
|
+
for (const key of path.split('.')) {
|
|
679
|
+
if (node === null || node === undefined || typeof node !== 'object') {
|
|
680
|
+
return false
|
|
681
|
+
}
|
|
682
|
+
node = node[key];
|
|
683
|
+
}
|
|
684
|
+
if (typeof when === 'object' && Object.hasOwn(when, 'equals')) {
|
|
685
|
+
return node === when.equals
|
|
686
|
+
}
|
|
687
|
+
return Boolean(node)
|
|
688
|
+
},
|
|
689
|
+
|
|
657
690
|
/**
|
|
658
691
|
* The option list a `choice` step declares `optionsSource` for, read
|
|
659
692
|
* from the setup status document the app already serves.
|