@conduction/nextcloud-vue 2.101.0 → 2.103.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/CnConversationThread/CnConversationThread.vue.js +1 -1
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue2.js +73 -0
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue2.js.map +1 -1
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue3.js +99 -64
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue3.js.map +1 -1
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue.js +1 -1
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue2.js +46 -0
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue3.js +37 -2
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue.js +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +49 -6
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue.js +1 -1
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js +113 -20
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js.map +1 -1
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js +387 -359
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +84 -4
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +8 -6
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/useNamedSource.js +26 -2
- package/dist/esm/components/CnIndexPage/useNamedSource.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 +10 -1
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.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/CnRecordListWidget/CnRecordListWidget.vue.js +1 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js +97 -3
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js +46 -2
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnSearchSelect/CnSearchSelect.vue.js +9 -0
- package/dist/esm/components/CnSearchSelect/CnSearchSelect.vue.js.map +1 -0
- package/dist/esm/components/CnSearchSelect/CnSearchSelect.vue2.js +165 -0
- package/dist/esm/components/CnSearchSelect/CnSearchSelect.vue2.js.map +1 -0
- package/dist/esm/components/CnSearchSelect/CnSearchSelect.vue3.js +85 -0
- package/dist/esm/components/CnSearchSelect/CnSearchSelect.vue3.js.map +1 -0
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue.js +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js +54 -6
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js.map +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js +3 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue.js +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +8 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.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/components/CnWizardDialog/CnWizardDialog.vue.js +1 -1
- package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue2.js +19 -0
- package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue2.js.map +1 -1
- package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue3.js +1 -1
- package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue3.js.map +1 -1
- package/dist/esm/composables/indexSources.js +9 -0
- package/dist/esm/composables/indexSources.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 +5 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +5 -1
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/library-style.js +1 -1
- package/dist/esm/mixins/pageViews.js +8 -1
- package/dist/esm/mixins/pageViews.js.map +1 -1
- package/dist/esm/nextcloud-vue.css +593 -459
- package/dist/esm/utils/builtInFormatters.js +24 -4
- package/dist/esm/utils/builtInFormatters.js.map +1 -1
- 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 +32 -4
- package/dist/esm/utils/visibleWhen.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +10093 -8858
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +593 -459
- package/l10n/en.json +5 -1
- package/l10n/nl.json +5 -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/CnConversationThread/CnConversationThread.md +17 -0
- package/src/components/CnConversationThread/CnConversationThread.vue +113 -8
- package/src/components/CnConversationThread/CnConversationWidget.vue +60 -1
- package/src/components/CnDashboardPage/CnDashboardPage.md +4 -1
- package/src/components/CnDashboardPage/CnDashboardPage.vue +50 -7
- package/src/components/CnDetailPage/CnDetailPage.md +1 -1
- package/src/components/CnFormDialog/CnFormDialog.md +1 -1
- package/src/components/CnFormDialog/CnFormDialog.vue +127 -0
- package/src/components/CnIndexPage/CnIndexPage.md +15 -1
- package/src/components/CnIndexPage/CnIndexPage.vue +92 -9
- package/src/components/CnIndexPage/useNamedSource.js +26 -2
- package/src/components/CnMenuWidget/CnMenuWidget.vue +25 -1
- package/src/components/CnObjectListWidget/CnObjectListWidget.vue +10 -1
- package/src/components/CnQuickFilterBar/CnQuickFilterBar.md +1 -0
- package/src/components/CnQuickFilterBar/CnQuickFilterBar.vue +159 -5
- package/src/components/CnRecordListWidget/CnRecordListWidget.vue +134 -2
- package/src/components/CnSearchSelect/CnSearchSelect.vue +283 -0
- package/src/components/CnSearchSelect/index.js +12 -0
- package/src/components/CnSetupWizard/CnSetupWizard.vue +56 -6
- package/src/components/CnTabsWidget/CnTabsWidget.vue +8 -1
- package/src/components/CnWidgetObjectTable/CnWidgetObjectTable.vue +2 -23
- package/src/components/CnWizardDialog/CnWizardDialog.vue +20 -1
- package/src/components/index.js +1 -0
- package/src/composables/indexSources.js +9 -0
- package/src/css/dialog.css +5 -3
- package/src/css/look-board-index.css +10 -0
- package/src/index.js +1 -0
- package/src/mixins/pageViews.js +8 -1
- package/src/schemas/app-manifest-v2.schema.json +107 -8
- package/src/utils/builtInFormatters.js +24 -4
- package/src/utils/rowClassRules.js +39 -0
- package/src/utils/validateManifestV2.compiled.js +3 -3
- package/src/utils/visibleWhen.js +32 -4
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"$id": "https://raw.githubusercontent.com/ConductionNL/nextcloud-vue/main/src/schemas/app-manifest-v2.schema.json",
|
|
4
4
|
"title": "Conduction App Manifest v2",
|
|
5
5
|
"description": "v2 schema for the JSON-driven page and navigation manifest consumed by @conduction/nextcloud-vue. Introduces a uniform widgets[] array on every page type with a per-slot grid coordinate system, a typed actions[] discriminator, and the required $schema field for version detection. v1 manifests continue to validate against app-manifest.schema.json (unchanged).",
|
|
6
|
-
"version": "2.
|
|
6
|
+
"version": "2.126.0",
|
|
7
7
|
"type": "object",
|
|
8
8
|
"required": ["$schema", "version"],
|
|
9
9
|
"allOf": [
|
|
@@ -115,10 +115,11 @@
|
|
|
115
115
|
}
|
|
116
116
|
},
|
|
117
117
|
"optionsSource": { "type": "string", "description": "choice: where to read the option list from at runtime, instead of declaring it here. Names a key in the app's own GET /api/setup/status document (dots walk into nested objects, e.g. `profiles`). Entries accept `id` for `value` and `name` for `label`, and a numeric `objectCount` becomes the stat a card shows. Use it when the SERVER owns what is on offer, so the manifest cannot drift from it." },
|
|
118
|
-
"display": { "type": "string", "enum": ["select", "cards"], "default": "select", "description": "choice: how the options are rendered. `select` is a dropdown; `cards` is a grid of CnChoiceCards, which shows each option's description and stats. Pick cards when the choice needs explaining." },
|
|
118
|
+
"display": { "type": "string", "enum": ["select", "cards", "rows"], "default": "select", "description": "choice: how the options are rendered. `select` is a dropdown; `cards` is a grid of CnChoiceCards, which shows each option's description and stats; `rows` is CnChoiceCards' rows layout, one radio row per option with its description below the label. Pick cards or rows when the choice needs explaining." },
|
|
119
119
|
"dependsOn": { "type": "string", "description": "choice: the configKey of a previous choice step this one cascades from. Disabled until the parent is set; its option list is taken from optionsByParent[parentValue] (e.g. organisation-type depends on country)." },
|
|
120
120
|
"optionsByParent": { "type": "object", "description": "choice: map of parent-choice value → options[] for a dependent (dependsOn) choice. Same option item shape as `options`.", "additionalProperties": { "type": "array", "items": { "type": "object", "additionalProperties": false, "required": ["value", "label"], "properties": { "value": {}, "label": { "type": "string" } } } } },
|
|
121
121
|
"suggestFrom": { "type": "string", "description": "choice: the configKey of an earlier choice this step pre-fills a suggestion from. When that value is set and the user has not yet picked here, the option matching suggestMap[parentValue] is auto-selected (still user-overridable)." },
|
|
122
|
+
"default": { "description": "choice: the option value chosen when the step opens (an array of values with `multiple`). Not applied to a step the server already completed." },
|
|
122
123
|
"suggestMap": { "type": "object", "description": "choice: map of suggestFrom value → suggested option value. Used to auto-suggest a default (e.g. RGS template suggested from organisation type).", "additionalProperties": { "type": "string" } },
|
|
123
124
|
"multiple": { "type": "boolean", "default": false, "description": "choice: allow multi-select." },
|
|
124
125
|
"loadAction": { "type": "string", "minLength": 1, "description": "choice with display cards: an actionId each option card loads itself with. Every card except the one whose value is `none` gets its own Load button, which POSTs { dataset: <value> } to /api/setup/action/{loadAction}, spins while it runs and shows the result on that card. A successful load also selects the card. With loadAction the separate run-action step that loaded the picked dataset is no longer needed; manifests that keep it still work." },
|
|
@@ -541,6 +542,18 @@
|
|
|
541
542
|
}
|
|
542
543
|
},
|
|
543
544
|
"$defs": {
|
|
545
|
+
"fieldOverride": {
|
|
546
|
+
"type": "object",
|
|
547
|
+
"additionalProperties": true,
|
|
548
|
+
"description": "One field's overrides over its schema-derived descriptor (label, order, hidden, readOnly, widget, enumLabels and more stay free-form). A `widget` that is not one of the form's own widget names mounts the registered component of that name (the v2 registry, then customComponents). 2.126.0 documents the search look of a single select.",
|
|
549
|
+
"properties": {
|
|
550
|
+
"widget": { "type": "string", "minLength": 1 },
|
|
551
|
+
"look": { "type": "string", "enum": ["search"], "description": "`search` draws a single select as CnSearchSelect: a magnifier instead of the chevron, and rows with initials or an icon, the name, a secondary line and a check on the chosen one (DqOverdragen \"Nieuw team\")." },
|
|
552
|
+
"optionSecondary": { "type": "string", "description": "look 'search': the row's secondary line, a template filled from each option (\"{members} leden · {focus}\")." },
|
|
553
|
+
"optionAvatar": { "type": "boolean", "description": "look 'search': draw each option's initials." },
|
|
554
|
+
"optionIcon": { "type": "string", "minLength": 1, "description": "look 'search': one icon for every row." }
|
|
555
|
+
}
|
|
556
|
+
},
|
|
544
557
|
"breadcrumbCrumb": {
|
|
545
558
|
"type": "object",
|
|
546
559
|
"additionalProperties": false,
|
|
@@ -2162,6 +2175,39 @@
|
|
|
2162
2175
|
}
|
|
2163
2176
|
}
|
|
2164
2177
|
},
|
|
2178
|
+
{
|
|
2179
|
+
"description": "record-list built-in widget (CnRecordListWidget): the action under the list, `props.content.footerAction` (2.126.0). Other content keys stay free-form.",
|
|
2180
|
+
"if": {
|
|
2181
|
+
"properties": { "widgetKey": { "const": "record-list" } },
|
|
2182
|
+
"required": ["widgetKey"]
|
|
2183
|
+
},
|
|
2184
|
+
"then": {
|
|
2185
|
+
"properties": {
|
|
2186
|
+
"props": {
|
|
2187
|
+
"type": "object",
|
|
2188
|
+
"properties": {
|
|
2189
|
+
"content": {
|
|
2190
|
+
"type": "object",
|
|
2191
|
+
"properties": {
|
|
2192
|
+
"footerAction": {
|
|
2193
|
+
"type": "object",
|
|
2194
|
+
"additionalProperties": true,
|
|
2195
|
+
"required": ["label"],
|
|
2196
|
+
"description": "One action under the list, also under the empty text (DqBezwaar \"Beroep registreren\"). Its other keys are an action's (`type`, `route`, `form`, ...). While `disabledWhen` holds it is disabled and says `disabledReason` (\"Kan zodra de beslissing is verzonden\"). Label and reason go through the host's translate.",
|
|
2197
|
+
"properties": {
|
|
2198
|
+
"label": { "type": "string", "minLength": 1 },
|
|
2199
|
+
"icon": { "type": "string", "minLength": 1 },
|
|
2200
|
+
"disabledWhen": { "$ref": "#/$defs/visibleWhen" },
|
|
2201
|
+
"disabledReason": { "type": "string" }
|
|
2202
|
+
}
|
|
2203
|
+
}
|
|
2204
|
+
}
|
|
2205
|
+
}
|
|
2206
|
+
}
|
|
2207
|
+
}
|
|
2208
|
+
}
|
|
2209
|
+
}
|
|
2210
|
+
},
|
|
2165
2211
|
{
|
|
2166
2212
|
"description": "audit-trail built-in widget (CnAuditTrailWidget, Wave 1): the object change-log card. All props are optional — register/schema/objectId normally arrive via the detail-page object-context merge; explicit props win.",
|
|
2167
2213
|
"if": {
|
|
@@ -2221,7 +2267,8 @@
|
|
|
2221
2267
|
},
|
|
2222
2268
|
"emptyLabel": { "type": "string", "description": "Empty-state message rendered instead of the chart when the resolved series contain no data points." },
|
|
2223
2269
|
"barMax": { "type": "number", "exclusiveMinimum": 0, "description": "chartKind 'bar-list': the value a full track stands for (100 for percentages). Omitted = the largest value." },
|
|
2224
|
-
"footnote": { "type": "string", "description": "
|
|
2270
|
+
"footnote": { "type": "string", "description": "A line under the chart, through the host's translate: under the rows of a bar-list or matrix, and under the plot of a line, area or bar chart." },
|
|
2271
|
+
"emptyCellLabel": { "type": "string", "description": "chartKind 'matrix': the text of a cell without a value (\"geen\"), through the host's translate. Empty leaves the cell blank. Passed through to CnChartWidget." },
|
|
2225
2272
|
"highlight": {
|
|
2226
2273
|
"type": "object",
|
|
2227
2274
|
"additionalProperties": false,
|
|
@@ -2863,7 +2910,7 @@
|
|
|
2863
2910
|
},
|
|
2864
2911
|
"fieldOverrides": {
|
|
2865
2912
|
"type": "object",
|
|
2866
|
-
"additionalProperties":
|
|
2913
|
+
"additionalProperties": { "$ref": "#/$defs/fieldOverride" },
|
|
2867
2914
|
"description": "open-form: per-field overrides passed to fieldsFromSchema, keyed by field. Recognised keys include label, order, hidden, readOnly and widget."
|
|
2868
2915
|
},
|
|
2869
2916
|
"advanced": {
|
|
@@ -3200,9 +3247,9 @@
|
|
|
3200
3247
|
},
|
|
3201
3248
|
"op": {
|
|
3202
3249
|
"type": "string",
|
|
3203
|
-
"enum": ["eq", "neq", "gt", "gte", "lt", "lte", "empty", "notEmpty", "in"],
|
|
3250
|
+
"enum": ["eq", "neq", "gt", "gte", "lt", "lte", "empty", "notEmpty", "in", "anyOf"],
|
|
3204
3251
|
"default": "eq",
|
|
3205
|
-
"description": "Comparison operator (default eq). eq/neq compare loosely-normalised primitives; ordering operators coerce both sides to Number. `in` holds when the value is one of the listed `value` array (2.87.0). `empty` / `notEmpty` take no `value` and treat undefined, null, '' and an empty array alike — the one question eq cannot ask, because an unset field arrives in a shape that depends on the store and String(null) is the word 'null' rather than blank."
|
|
3252
|
+
"description": "Comparison operator (default eq). eq/neq compare loosely-normalised primitives; ordering operators coerce both sides to Number. `in` holds when the value is one of the listed `value` array (2.87.0). `anyOf` holds when the value, or any entry of a list value, is one of the listed `value` array: a record whose `dataCategories` holds \"health\" among others matches `anyOf [\"health\", \"ethnicity\"]` (2.126.0). `empty` / `notEmpty` take no `value` and treat undefined, null, '' and an empty array alike — the one question eq cannot ask, because an unset field arrives in a shape that depends on the store and String(null) is the word 'null' rather than blank."
|
|
3206
3253
|
},
|
|
3207
3254
|
"value": {
|
|
3208
3255
|
"description": "The right-hand side of the comparison, resolved through the shared @-token grammar so `@me` names the signed-in reader rather than a literal only the server knows. Omitted for `empty` / `notEmpty`."
|
|
@@ -3738,7 +3785,58 @@
|
|
|
3738
3785
|
"enum": ["flows", "flowRuns", "tasks", "endpoint", "search", "users", "organisations"],
|
|
3739
3786
|
"description": "Name a registered NON-OBJECT entity collection for a type='index' page, instead of register+schema. Deliberately NOT called `source`: that key is already taken on page config and is polymorphic (a URL string in some manifests, an object with `params` in others), so reusing it would give one key two meanings and break six deployed shillinq pages. A flow definition is deliberately not an OpenRegister object, so an index had nothing to bind to and such lists became bespoke type='custom' pages. With a source the index loads the list itself. Takes precedence over register/schema; non-empty `objects` still wins over both. Registered sources live in src/composables/indexSources.js. `tasks` lists the viewer's task inbox from OpenRegister's flow-tasks read (cn-tasks-entity-source). `organisations` lists the OpenRegister organisations the viewer belongs to. On a type='detail' page a source that reads one record (today `organisations`) loads the record whose id is the route's objectId, instead of register+schema, and feeds the header, pills, widgets and @objectId / @object.* tokens like a fetched object (organisations-entity-source)."
|
|
3740
3787
|
},
|
|
3741
|
-
"
|
|
3788
|
+
"bulkBandAlways": { "type": "boolean", "default": false, "description": "type='index', board look: draw the bulk band (its actions and hint) before a selection too, its buttons disabled until rows are selected (DqZaken, DqWerkbord). Maps to CnIndexPage `bulkBandAlways`." },
|
|
3789
|
+
"quickFilterPlacement": { "type": "string", "enum": ["", "toolbar"], "default": "", "description": "type='index': where the quick-filter chips sit. `toolbar` keeps them on one row with the Filter button and the view switch beside a side panel, the chips that do not fit behind the overflow chip (DqTeamwachtrij). Maps to CnIndexPage `quickFilterPlacement`." },
|
|
3790
|
+
"rowClass": {
|
|
3791
|
+
"type": "array",
|
|
3792
|
+
"description": "type='index': per-row CSS class rules, compiled into the table's rowClass function as on the object-table widget. Each rule { when: { field, op?, value }, class } adds `class` to a row whose `field` (a dot-path) compares to `value` with `op` (default eq; the visibleWhen operators and tokens such as `@today`, with two dates compared as moments), e.g. an overdue task `{ when: { field: \"dueAt\", op: \"lt\", value: \"@today\" }, class: \"cn-row--overdue\" }`. Maps to CnIndexPage `rowClass`.",
|
|
3793
|
+
"items": {
|
|
3794
|
+
"type": "object",
|
|
3795
|
+
"additionalProperties": false,
|
|
3796
|
+
"required": [
|
|
3797
|
+
"when",
|
|
3798
|
+
"class"
|
|
3799
|
+
],
|
|
3800
|
+
"properties": {
|
|
3801
|
+
"when": {
|
|
3802
|
+
"type": "object",
|
|
3803
|
+
"additionalProperties": false,
|
|
3804
|
+
"required": [
|
|
3805
|
+
"field",
|
|
3806
|
+
"value"
|
|
3807
|
+
],
|
|
3808
|
+
"description": "The predicate evaluated against the row (shared visibleWhen grammar, LOCAL form).",
|
|
3809
|
+
"properties": {
|
|
3810
|
+
"field": {
|
|
3811
|
+
"type": "string",
|
|
3812
|
+
"description": "Dot-path into the row."
|
|
3813
|
+
},
|
|
3814
|
+
"op": {
|
|
3815
|
+
"type": "string",
|
|
3816
|
+
"enum": [
|
|
3817
|
+
"eq",
|
|
3818
|
+
"neq",
|
|
3819
|
+
"gt",
|
|
3820
|
+
"gte",
|
|
3821
|
+
"lt",
|
|
3822
|
+
"lte"
|
|
3823
|
+
],
|
|
3824
|
+
"default": "eq",
|
|
3825
|
+
"description": "Comparison operator (default eq)."
|
|
3826
|
+
},
|
|
3827
|
+
"value": {
|
|
3828
|
+
"description": "Literal right-hand side of the comparison."
|
|
3829
|
+
}
|
|
3830
|
+
}
|
|
3831
|
+
},
|
|
3832
|
+
"class": {
|
|
3833
|
+
"type": "string",
|
|
3834
|
+
"description": "CSS class added to the row when `when` holds."
|
|
3835
|
+
}
|
|
3836
|
+
}
|
|
3837
|
+
}
|
|
3838
|
+
},
|
|
3839
|
+
"sourceConfig": { "type": "object", "additionalProperties": true, "description": "type='index' with `entitySource`: what the named source loads with. `endpoint`: `url` (an app path, required) and `rowsPath` (default `results`); its other keys go along as query parameters. `search`: `kinds` (`{ id, label, register, schema, titleField?, subtitleField?, statusField?, href?, limit? }` or `{ id, label, files: true }`), `term` and `termQuery` (default `q`). `users`: `defaultGroup`, `functionField`, `rolesField`. `flows` / `tasks`: `app`, `scope`. Maps to CnIndexPage `sourceConfig`.", "properties": { "url": { "type": "string", "minLength": 1 }, "rowsPath": { "type": "string", "minLength": 1 }, "kinds": { "type": "array", "items": { "type": "object", "required": ["id"], "additionalProperties": true, "properties": { "id": { "type": "string", "minLength": 1 }, "label": { "type": "string" }, "register": { "type": "string" }, "schema": { "type": "string" }, "files": { "type": "boolean" } } } }, "term": { "type": "string" }, "termQuery": { "type": "string", "minLength": 1 }, "defaultGroup": { "type": "string", "minLength": 1 }, "limit": { "type": "integer", "minimum": 1, "description": "A paging source: rows per page (20 by default); the pager moves through the pages." } } },
|
|
3742
3840
|
"app": {
|
|
3743
3841
|
"type": "string",
|
|
3744
3842
|
"description": "Scopes a named `entitySource` to one app (e.g. entitySource='flows' with app='dossiq' lists that app's flows)."
|
|
@@ -3954,6 +4052,7 @@
|
|
|
3954
4052
|
"additionalProperties": true,
|
|
3955
4053
|
"description": "type='index': the opt-in folder navigation pane (CnFolderSidebar) rendered left of the list. Selecting a folder filters the list by `filterField` (or `field`); \"All\" clears it. Only the per-scope list-layout keys are typed here; the pane's own keys (source, register, schema, idField, nameField, folders, allLabel, title, allowCreate, ...) stay free-form. Maps to CnIndexPage `folderSidebar`.",
|
|
3956
4054
|
"properties": {
|
|
4055
|
+
"pane": { "type": "boolean", "default": true, "description": "false keeps the folder scope (a deep link such as `?caseType=<uuid>` still applies the scope's look and filter) without drawing the pane (dossiq's simple profile, 2.126.0)." },
|
|
3957
4056
|
"folders": {
|
|
3958
4057
|
"type": "array",
|
|
3959
4058
|
"description": "Explicit folder list for source:'custom', and the place a folder declares its own list layout. Every other folder key stays free-form.",
|
|
@@ -4249,7 +4348,7 @@
|
|
|
4249
4348
|
},
|
|
4250
4349
|
"fieldOverrides": {
|
|
4251
4350
|
"type": "object",
|
|
4252
|
-
"additionalProperties":
|
|
4351
|
+
"additionalProperties": { "$ref": "#/$defs/fieldOverride" },
|
|
4253
4352
|
"description": "Per-field overrides merged over the schema-derived field descriptors in the page's built-in Add/Edit form dialog (e.g. `{ \"description\": { \"widget\": \"textarea\" } }`). Which widget a field renders as belongs to the surface, not to the schema. Maps to CnIndexPage / CnDetailPage `fieldOverrides`."
|
|
4254
4353
|
},
|
|
4255
4354
|
"createDefaults": {
|
|
@@ -379,25 +379,45 @@ const CONNECTION_STATUS_LABELS = {
|
|
|
379
379
|
error: 'Error',
|
|
380
380
|
}
|
|
381
381
|
|
|
382
|
+
/**
|
|
383
|
+
* The short labels `formatterOptions.short` draws (board DqInstellingen
|
|
384
|
+
* "Aan / Uit / Fout"): a connection that works in some form is on, one that
|
|
385
|
+
* does not run is off, and a failing one is an error.
|
|
386
|
+
*/
|
|
387
|
+
const CONNECTION_STATUS_SHORT_LABELS = {
|
|
388
|
+
configured: 'On',
|
|
389
|
+
limited: 'On',
|
|
390
|
+
simulated: 'On',
|
|
391
|
+
unconfigured: 'Off',
|
|
392
|
+
disabled: 'Off',
|
|
393
|
+
unavailable: 'Off',
|
|
394
|
+
error: 'Error',
|
|
395
|
+
}
|
|
396
|
+
|
|
382
397
|
/**
|
|
383
398
|
* Connection status formatter (`connectionStatus` registry key) for the
|
|
384
399
|
* fleet connection registry. Renders one of the seven stored status values
|
|
385
400
|
* as its translated label through the library's own slug (`nextcloud-vue`).
|
|
401
|
+
* With `formatterOptions.short` it renders the board's three short labels
|
|
402
|
+
* instead: On (configured, limited, simulated), Off (not configured,
|
|
403
|
+
* switched off, not available) and Error.
|
|
386
404
|
*
|
|
387
405
|
* An unknown value passes through unchanged, so a status added later still
|
|
388
406
|
* shows as its raw value instead of an empty cell. Null and undefined render
|
|
389
407
|
* as `''`. Never throws.
|
|
390
408
|
*
|
|
391
409
|
* @param {unknown} value The stored status value.
|
|
410
|
+
* @param {object} [row] The row (unused).
|
|
411
|
+
* @param {object} [property] The column's property (unused).
|
|
412
|
+
* @param {{short?: boolean}} [options] The column's `formatterOptions`.
|
|
392
413
|
* @return {string} The translated label, or the value itself when it is not one of the seven.
|
|
393
414
|
*/
|
|
394
|
-
export function formatConnectionStatus(value) {
|
|
415
|
+
export function formatConnectionStatus(value, row, property, options) {
|
|
395
416
|
if (value === null || value === undefined) {
|
|
396
417
|
return ''
|
|
397
418
|
}
|
|
398
|
-
const
|
|
399
|
-
|
|
400
|
-
: null
|
|
419
|
+
const labels = options && options.short === true ? CONNECTION_STATUS_SHORT_LABELS : CONNECTION_STATUS_LABELS
|
|
420
|
+
const label = Object.hasOwn(labels, value) ? labels[value] : null
|
|
401
421
|
return label ? t('nextcloud-vue', label) : String(value)
|
|
402
422
|
}
|
|
403
423
|
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SPDX-FileCopyrightText: 2026 Conduction B.V.
|
|
3
|
+
* SPDX-License-Identifier: EUPL-1.2
|
|
4
|
+
*/
|
|
5
|
+
import { compareVisibleWhen, readVisibleWhenPath } from './visibleWhen.js'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Compile a row-class declaration into the `(row) => string` CnDataTable
|
|
9
|
+
* takes. A function passes straight through. An array of rules
|
|
10
|
+
* `[{ when: { field, op?, value }, class }]` adds each rule's `class` to a row
|
|
11
|
+
* whose `field` (a dot-path) compares to `value` with `op` (`eq` by default;
|
|
12
|
+
* the shared `visibleWhen` operators, `@today` and the other tokens included),
|
|
13
|
+
* every matching class space-joined: an overdue row can be marked from the
|
|
14
|
+
* manifest (`{ when: { field: "dueAt", op: "lt", value: "@today" }, class:
|
|
15
|
+
* "cn-row--overdue" }`). Anything else, or an empty list, is null.
|
|
16
|
+
*
|
|
17
|
+
* @param {Function|Array<{when: {field: string, op?: string, value: unknown}, class: string}>|null} rowClass The declaration.
|
|
18
|
+
* @return {?(row: object) => string} The row-class function, or null.
|
|
19
|
+
*/
|
|
20
|
+
export function compileRowClass(rowClass) {
|
|
21
|
+
if (typeof rowClass === 'function') {
|
|
22
|
+
return rowClass
|
|
23
|
+
}
|
|
24
|
+
if (!Array.isArray(rowClass) || rowClass.length === 0) {
|
|
25
|
+
return null
|
|
26
|
+
}
|
|
27
|
+
const rules = rowClass.filter((rule) => rule && typeof rule.class === 'string' && rule.class !== '')
|
|
28
|
+
return (row) => {
|
|
29
|
+
const classes = []
|
|
30
|
+
for (const rule of rules) {
|
|
31
|
+
const when = rule.when || {}
|
|
32
|
+
const actual = readVisibleWhenPath(row, when.field)
|
|
33
|
+
if (compareVisibleWhen(actual, when.op || 'eq', when.value)) {
|
|
34
|
+
classes.push(rule.class)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return classes.join(' ')
|
|
38
|
+
}
|
|
39
|
+
}
|