@conduction/nextcloud-vue 2.137.0 → 2.139.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/CnCellRenderer/CnCellRenderer.vue.js +1 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js +6 -4
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js.map +1 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js.map +1 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue.js +1 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailCard/CnDetailCard.vue.js +1 -1
- package/dist/esm/components/CnDetailCard/CnDetailCard.vue2.js +6 -0
- package/dist/esm/components/CnDetailCard/CnDetailCard.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailCard/CnDetailCard.vue3.js +24 -7
- package/dist/esm/components/CnDetailCard/CnDetailCard.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue.js +1 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js +2 -0
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js.map +1 -1
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue.js +1 -1
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue.js +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js +43 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +133 -6
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +25 -17
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue2.js +2 -0
- package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue3.js +13 -2
- package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue3.js.map +1 -1
- package/dist/esm/components/CnMailTab/dashboardRegistration.js +4 -0
- package/dist/esm/components/CnMailTab/dashboardRegistration.js.map +1 -1
- package/dist/esm/components/CnNotificationMatrix/CnNotificationMatrix.vue.js +1 -1
- package/dist/esm/components/CnNotificationMatrix/CnNotificationMatrix.vue2.js.map +1 -1
- package/dist/esm/components/CnNotificationMatrix/CnNotificationMatrix.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue.js +1 -1
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js +1 -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/CnObjectSidebar/CnFilesTab.vue.js +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js +2 -0
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js +2 -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 +6 -0
- package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue2.js.map +1 -1
- package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue3.js +3 -3
- package/dist/esm/components/CnOrderedListField/CnOrderedListField.vue3.js.map +1 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js +1 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js +16 -0
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js +11 -5
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnSavedViewMenuSettings/CnSavedViewMenuSettings.vue.js +1 -1
- package/dist/esm/components/CnSavedViewMenuSettings/CnSavedViewMenuSettings.vue2.js.map +1 -1
- package/dist/esm/components/CnSavedViewMenuSettings/CnSavedViewMenuSettings.vue3.js +1 -0
- package/dist/esm/components/CnSavedViewMenuSettings/CnSavedViewMenuSettings.vue3.js.map +1 -1
- package/dist/esm/components/CnUserSettingsDialog/CnUserSettingsDialog.vue.js +1 -1
- package/dist/esm/components/CnUserSettingsDialog/CnUserSettingsDialog.vue2.js.map +1 -1
- package/dist/esm/components/CnUserSettingsDialog/CnUserSettingsDialog.vue3.js.map +1 -1
- package/dist/esm/composables/indexSources.js +78 -12
- package/dist/esm/composables/indexSources.js.map +1 -1
- package/dist/esm/l10n/en.json.js +12 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +12 -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 +685 -512
- package/dist/esm/utils/resolveFilterTokens.js +9 -0
- package/dist/esm/utils/resolveFilterTokens.js.map +1 -1
- package/dist/esm/utils/sentinelTokens.js +1 -1
- package/dist/esm/utils/sentinelTokens.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +580 -236
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +685 -512
- package/l10n/en.json +12 -1
- package/l10n/nl.json +12 -1
- package/package.json +1 -1
- package/src/components/CnCellRenderer/CnCellRenderer.vue +6 -4
- package/src/components/CnChartWidget/CnChartWidget.vue +4 -0
- package/src/components/CnDetailCard/CnDetailCard.md +1 -0
- package/src/components/CnDetailCard/CnDetailCard.vue +25 -1
- package/src/components/CnDetailWidgetHost/CnDetailWidgetHost.vue +2 -0
- package/src/components/CnFactsWidget/CnFactsWidget.vue +6 -4
- package/src/components/CnFilesBrowser/CnFilesBrowser.vue +54 -1
- package/src/components/CnIndexPage/CnIndexPage.vue +135 -7
- package/src/components/CnIndexSidebar/CnIndexSidebar.vue +10 -2
- package/src/components/CnMailTab/dashboardRegistration.js +4 -0
- package/src/components/CnNotificationMatrix/CnNotificationMatrix.vue +4 -0
- package/src/components/CnObjectListWidget/CnObjectListWidget.vue +1 -1
- package/src/components/CnObjectSidebar/CnFilesTab.vue +3 -0
- package/src/components/CnOrderedListField/CnOrderedListField.vue +11 -1
- package/src/components/CnRecordListWidget/CnRecordListWidget.vue +22 -3
- package/src/components/CnSavedViewMenuSettings/CnSavedViewMenuSettings.vue +1 -0
- package/src/components/CnUserSettingsDialog/CnUserSettingsDialog.vue +3 -0
- package/src/composables/indexSources.js +78 -12
- package/src/css/dialog.css +26 -0
- package/src/css/index-page.css +5 -0
- package/src/css/look-board-detail.css +36 -0
- package/src/css/look-board-index.css +21 -0
- package/src/css/look-board.css +47 -0
- package/src/utils/resolveFilterTokens.js +9 -0
- package/src/utils/sentinelTokens.js +1 -1
package/l10n/en.json
CHANGED
|
@@ -2377,7 +2377,10 @@
|
|
|
2377
2377
|
"Talk to {agent}": "Talk to {agent}",
|
|
2378
2378
|
"Search a person or group": "Search a person or group",
|
|
2379
2379
|
"Now: by {order}.": "Now: by {order}.",
|
|
2380
|
-
"You save the order along with a view.": "You save the order along with a view."
|
|
2380
|
+
"You save the order along with a view.": "You save the order along with a view.",
|
|
2381
|
+
"me": "me",
|
|
2382
|
+
"Open profile": "Open profile",
|
|
2383
|
+
"Link a contact from your address book.": "Link a contact from your address book."
|
|
2381
2384
|
},
|
|
2382
2385
|
"plurals": {
|
|
2383
2386
|
"{count} member": [
|
|
@@ -2578,6 +2581,14 @@
|
|
|
2578
2581
|
"within %n day": [
|
|
2579
2582
|
"within %n day",
|
|
2580
2583
|
"within %n days"
|
|
2584
|
+
],
|
|
2585
|
+
"%n other": [
|
|
2586
|
+
"%n other",
|
|
2587
|
+
"%n others"
|
|
2588
|
+
],
|
|
2589
|
+
"{names} has no location, so it is not on the map.": [
|
|
2590
|
+
"{names} has no location, so it is not on the map.",
|
|
2591
|
+
"{names} have no location, so they are not on the map."
|
|
2581
2592
|
]
|
|
2582
2593
|
}
|
|
2583
2594
|
}
|
package/l10n/nl.json
CHANGED
|
@@ -2627,7 +2627,10 @@
|
|
|
2627
2627
|
"Talk to {agent}": "Praten met {agent}",
|
|
2628
2628
|
"Search a person or group": "Zoek een persoon of groep",
|
|
2629
2629
|
"Now: by {order}.": "Nu: op {order}.",
|
|
2630
|
-
"You save the order along with a view.": "De sortering bewaart u mee in een weergave."
|
|
2630
|
+
"You save the order along with a view.": "De sortering bewaart u mee in een weergave.",
|
|
2631
|
+
"me": "ik",
|
|
2632
|
+
"Open profile": "Profiel openen",
|
|
2633
|
+
"Link a contact from your address book.": "Koppel een contact uit je adresboek."
|
|
2631
2634
|
},
|
|
2632
2635
|
"plurals": {
|
|
2633
2636
|
"{count} member": [
|
|
@@ -2845,6 +2848,14 @@
|
|
|
2845
2848
|
"within %n day": [
|
|
2846
2849
|
"binnen %n dag",
|
|
2847
2850
|
"binnen %n dagen"
|
|
2851
|
+
],
|
|
2852
|
+
"%n other": [
|
|
2853
|
+
"%n andere",
|
|
2854
|
+
"%n andere"
|
|
2855
|
+
],
|
|
2856
|
+
"{names} has no location, so it is not on the map.": [
|
|
2857
|
+
"{names} heeft geen locatie, dus staat niet op de kaart.",
|
|
2858
|
+
"{names} hebben geen locatie, dus staan ze niet op de kaart."
|
|
2848
2859
|
]
|
|
2849
2860
|
}
|
|
2850
2861
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@conduction/nextcloud-vue",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.139.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": {
|
|
@@ -639,7 +639,7 @@ export default {
|
|
|
639
639
|
* type-aware rendering, so a manifest column can opt into currency or a
|
|
640
640
|
* colour swatch without registering a function.
|
|
641
641
|
*
|
|
642
|
-
* @type {{style?: 'currency'|'number'|'percent'|'duration'|'swatch', currency?: string, decimals?: number, unit?: 'milliseconds'|'seconds'|'minutes'|'hours', prefix?: string, suffix?: string, colorField?: string}}
|
|
642
|
+
* @type {{style?: 'currency'|'number'|'decimal'|'percent'|'duration'|'swatch', currency?: string, decimals?: number, unit?: 'milliseconds'|'seconds'|'minutes'|'hours', prefix?: string, suffix?: string, colorField?: string}}
|
|
643
643
|
*/
|
|
644
644
|
format: {
|
|
645
645
|
type: Object,
|
|
@@ -1709,9 +1709,9 @@ export default {
|
|
|
1709
1709
|
return typeof s === 'string' ? s : null
|
|
1710
1710
|
},
|
|
1711
1711
|
|
|
1712
|
-
/** True when a built-in NUMERIC format (currency/number/percent/duration) applies. */
|
|
1712
|
+
/** True when a built-in NUMERIC format (currency/number/decimal/percent/duration) applies. */
|
|
1713
1713
|
hasBuiltinFormat() {
|
|
1714
|
-
return ['currency', 'number', 'percent', 'duration'].includes(this.formatStyle)
|
|
1714
|
+
return ['currency', 'number', 'decimal', 'percent', 'duration'].includes(this.formatStyle)
|
|
1715
1715
|
},
|
|
1716
1716
|
|
|
1717
1717
|
/** True when this cell renders as a colour swatch (`format.style:"swatch"`). */
|
|
@@ -1916,9 +1916,11 @@ export default {
|
|
|
1916
1916
|
if (!Number.isFinite(num)) {
|
|
1917
1917
|
return formatValue(this.value, this.property, { truncate: this.truncate })
|
|
1918
1918
|
}
|
|
1919
|
+
// `decimal` defaults to one fraction digit, as formatMetricValue does.
|
|
1920
|
+
const defaultDecimals = { currency: 2, decimal: 1 }
|
|
1919
1921
|
const decimals = Number.isFinite(fmt.decimals)
|
|
1920
1922
|
? fmt.decimals
|
|
1921
|
-
: (fmt.style
|
|
1923
|
+
: (defaultDecimals[fmt.style] ?? 0)
|
|
1922
1924
|
let body
|
|
1923
1925
|
if (fmt.style === 'currency') {
|
|
1924
1926
|
// `format.currencyField` reads the code from the row's own field.
|
|
@@ -2964,10 +2964,14 @@ export default {
|
|
|
2964
2964
|
display: contents;
|
|
2965
2965
|
}
|
|
2966
2966
|
|
|
2967
|
+
/* A column takes its share of the width (minmax(0, 1fr)), so a long phase
|
|
2968
|
+
name breaks inside its own column instead of running into the next. */
|
|
2967
2969
|
.cn-chart-widget__matrix-head {
|
|
2968
2970
|
--nldesign-color-on-surface: var(--color-text-maxcontrast);
|
|
2969
2971
|
color: var(--color-text-maxcontrast);
|
|
2970
2972
|
padding: 6px;
|
|
2973
|
+
hyphens: auto;
|
|
2974
|
+
overflow-wrap: anywhere;
|
|
2971
2975
|
}
|
|
2972
2976
|
|
|
2973
2977
|
.cn-chart-widget__matrix-label {
|
|
@@ -84,6 +84,7 @@ With footer slot:
|
|
|
84
84
|
| Prop | Type | Default | Description |
|
|
85
85
|
|------|------|---------|-------------|
|
|
86
86
|
| `icon` | Object\|Function | `null` | Optional MDI icon component rendered in the card header |
|
|
87
|
+
| `subtitle` | String | `''` | A muted line under the title, as given (translate before passing). No line when empty. |
|
|
87
88
|
|
|
88
89
|
| Slot | Description |
|
|
89
90
|
|------|-------------|
|
|
@@ -22,7 +22,13 @@
|
|
|
22
22
|
:size="20"
|
|
23
23
|
class="cn-detail-card__icon" />
|
|
24
24
|
</slot>
|
|
25
|
-
<
|
|
25
|
+
<div v-if="subtitle" class="cn-detail-card__heading">
|
|
26
|
+
<h3 class="cn-detail-card__title">
|
|
27
|
+
{{ title }}
|
|
28
|
+
</h3>
|
|
29
|
+
<span class="cn-detail-card__subtitle" data-testid="cn-detail-card-subtitle">{{ subtitle }}</span>
|
|
30
|
+
</div>
|
|
31
|
+
<h3 v-else class="cn-detail-card__title">
|
|
26
32
|
{{ title }}
|
|
27
33
|
</h3>
|
|
28
34
|
</div>
|
|
@@ -125,6 +131,12 @@ export default {
|
|
|
125
131
|
default: '',
|
|
126
132
|
},
|
|
127
133
|
|
|
134
|
+
/** A muted line under the title, as given (translate before passing). */
|
|
135
|
+
subtitle: {
|
|
136
|
+
type: String,
|
|
137
|
+
default: '',
|
|
138
|
+
},
|
|
139
|
+
|
|
128
140
|
/** Optional MDI icon component for the header */
|
|
129
141
|
icon: {
|
|
130
142
|
type: [Object, Function],
|
|
@@ -247,6 +259,18 @@ export default {
|
|
|
247
259
|
flex-shrink: 0;
|
|
248
260
|
}
|
|
249
261
|
|
|
262
|
+
.cn-detail-card__heading {
|
|
263
|
+
display: flex;
|
|
264
|
+
flex-direction: column;
|
|
265
|
+
min-width: 0;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.cn-detail-card__subtitle {
|
|
269
|
+
font-size: 13px;
|
|
270
|
+
line-height: 1.3;
|
|
271
|
+
color: var(--color-text-maxcontrast);
|
|
272
|
+
}
|
|
273
|
+
|
|
250
274
|
.cn-detail-card__title {
|
|
251
275
|
font-weight: 600;
|
|
252
276
|
font-size: 14px;
|
|
@@ -1444,6 +1444,7 @@ export default {
|
|
|
1444
1444
|
objectId: this.objectId,
|
|
1445
1445
|
object: this.object,
|
|
1446
1446
|
config: unwrapAppConfig(this.cnAppConfig),
|
|
1447
|
+
context: (this.cnDetailVisibilityRows && this.cnDetailVisibilityRows.value) || null,
|
|
1447
1448
|
})
|
|
1448
1449
|
},
|
|
1449
1450
|
|
|
@@ -1510,6 +1511,7 @@ export default {
|
|
|
1510
1511
|
// prints its title as given.
|
|
1511
1512
|
title: this.translateLabel(this.widget?.title || ''),
|
|
1512
1513
|
...this.leafTitleLabel,
|
|
1514
|
+
...(this.widgetSubtitle ? { subtitle: this.translateLabel(this.widgetSubtitle) } : {}),
|
|
1513
1515
|
// A provider opting into `bareWidget` is being rendered where the
|
|
1514
1516
|
// tab strip already supplies the card and the title, so tell it to
|
|
1515
1517
|
// drop its own. Without this the panel gets a titled card inside
|
|
@@ -1845,11 +1845,13 @@ export default {
|
|
|
1845
1845
|
display: contents;
|
|
1846
1846
|
}
|
|
1847
1847
|
|
|
1848
|
-
/* Nextcloud core styles `dt` and `dd` (text-align end, 12px padding
|
|
1849
|
-
pushed the label to the right of its column
|
|
1850
|
-
|
|
1851
|
-
|
|
1848
|
+
/* Nextcloud core styles `dt` and `dd` (text-align end, 12px padding, a
|
|
1849
|
+
130px-wide `dt`), which pushed the label to the right of its column, added
|
|
1850
|
+
12px around both and widened the label column to 130px. The class is
|
|
1851
|
+
doubled so these resets outrank that rule, and a dossiq-style `:deep()`
|
|
1852
|
+
override in an app is not needed. */
|
|
1852
1853
|
.cn-facts-widget__label.cn-facts-widget__label {
|
|
1854
|
+
width: auto;
|
|
1853
1855
|
margin: 0;
|
|
1854
1856
|
padding: 0;
|
|
1855
1857
|
text-align: start;
|
|
@@ -1128,6 +1128,21 @@ export default {
|
|
|
1128
1128
|
default: '',
|
|
1129
1129
|
},
|
|
1130
1130
|
|
|
1131
|
+
/**
|
|
1132
|
+
* The second line as a list of fields joined with " · ", a field
|
|
1133
|
+
* without a value left out: the `nameSecondary` tokens without their
|
|
1134
|
+
* braces (`["type", "size", "modified|date"]`, a row-data field such as
|
|
1135
|
+
* `"senderName"`). Or a list of variants `{ when, fields }`: the first
|
|
1136
|
+
* whose `when` is `true`, or that has no `when`, is used (a case type
|
|
1137
|
+
* flag read through `@context`). Takes precedence over `nameSecondary`.
|
|
1138
|
+
*
|
|
1139
|
+
* @spec openspec/changes/files-second-line-fields/specs/files-second-line-fields/spec.md#requirement-a-files-second-line-is-a-list-of-fields
|
|
1140
|
+
*/
|
|
1141
|
+
secondLine: {
|
|
1142
|
+
type: Array,
|
|
1143
|
+
default: null,
|
|
1144
|
+
},
|
|
1145
|
+
|
|
1131
1146
|
/** The line `dropHint` shows. */
|
|
1132
1147
|
dropHintLabel: {
|
|
1133
1148
|
type: String,
|
|
@@ -1526,6 +1541,26 @@ export default {
|
|
|
1526
1541
|
*
|
|
1527
1542
|
* @return {Array<object>} The file nodes.
|
|
1528
1543
|
*/
|
|
1544
|
+
/**
|
|
1545
|
+
* The fields `secondLine` names for this browser: the list itself, or
|
|
1546
|
+
* the fields of its first variant whose `when` is `true` or absent.
|
|
1547
|
+
* Null without `secondLine` or a matching variant.
|
|
1548
|
+
*
|
|
1549
|
+
* @return {Array<string>|null}
|
|
1550
|
+
* @spec openspec/changes/files-second-line-fields/specs/files-second-line-fields/spec.md#requirement-a-files-second-line-is-a-list-of-fields
|
|
1551
|
+
*/
|
|
1552
|
+
secondLineFields() {
|
|
1553
|
+
const list = Array.isArray(this.secondLine) ? this.secondLine : []
|
|
1554
|
+
if (list.length === 0) {
|
|
1555
|
+
return null
|
|
1556
|
+
}
|
|
1557
|
+
if (list.every((item) => typeof item === 'string')) {
|
|
1558
|
+
return list
|
|
1559
|
+
}
|
|
1560
|
+
const variant = list.find((item) => item && typeof item === 'object' && Array.isArray(item.fields) && (!('when' in item) || item.when === true))
|
|
1561
|
+
return variant ? variant.fields.filter((field) => typeof field === 'string') : null
|
|
1562
|
+
},
|
|
1563
|
+
|
|
1529
1564
|
/**
|
|
1530
1565
|
* The bulk bar's count text.
|
|
1531
1566
|
*
|
|
@@ -2079,7 +2114,8 @@ export default {
|
|
|
2079
2114
|
* @return {string}
|
|
2080
2115
|
*/
|
|
2081
2116
|
nameSecondaryOf(node) {
|
|
2082
|
-
|
|
2117
|
+
const fields = this.secondLineFields
|
|
2118
|
+
if ((!this.nameSecondary && fields === null) || this.isFolder(node)) {
|
|
2083
2119
|
return ''
|
|
2084
2120
|
}
|
|
2085
2121
|
const byId = this.resolvedRowData && typeof this.resolvedRowData === 'object' ? this.resolvedRowData : {}
|
|
@@ -2093,6 +2129,12 @@ export default {
|
|
|
2093
2129
|
type: this.typeLabelOf(node),
|
|
2094
2130
|
...(owner ? { owner } : {}),
|
|
2095
2131
|
}
|
|
2132
|
+
if (fields !== null) {
|
|
2133
|
+
return fields
|
|
2134
|
+
.map((field) => fillTemplate(`{${field}}`, object))
|
|
2135
|
+
.filter((text) => text !== '')
|
|
2136
|
+
.join(' · ')
|
|
2137
|
+
}
|
|
2096
2138
|
return fillTemplate(this.cnTranslate(this.nameSecondary), object)
|
|
2097
2139
|
},
|
|
2098
2140
|
|
|
@@ -3236,6 +3278,17 @@ export default {
|
|
|
3236
3278
|
font-size: 14px;
|
|
3237
3279
|
}
|
|
3238
3280
|
|
|
3281
|
+
/* Core's apps.css draws every dt/dd inline-block with a fixed, end-aligned dt.
|
|
3282
|
+
@spec openspec/changes/files-side-facts-core-dl/specs/files-side-facts-core-dl/spec.md#requirement-a-file-side-cards-facts-are-not-drawn-by-cores-dl-rules */
|
|
3283
|
+
.cn-files-browser__side-facts dt,
|
|
3284
|
+
.cn-files-browser__side-facts dd {
|
|
3285
|
+
display: block;
|
|
3286
|
+
width: auto;
|
|
3287
|
+
padding: 0;
|
|
3288
|
+
text-align: start;
|
|
3289
|
+
white-space: normal;
|
|
3290
|
+
}
|
|
3291
|
+
|
|
3239
3292
|
.cn-files-browser__side-facts dt {
|
|
3240
3293
|
color: var(--color-text-maxcontrast);
|
|
3241
3294
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="cn-index-page"
|
|
3
|
-
:class="[lookClass, { 'cn-index-page--with-side-panel': hasSidePanel, 'cn-index-page--quick-filters-toolbar': effectiveQuickFilterPlacement === 'toolbar' }]"
|
|
3
|
+
:class="[lookClass, { 'cn-index-page--with-side-panel': hasSidePanel, 'cn-index-page--sidebar-open': sidebarPanelOpen, 'cn-index-page--quick-filters-toolbar': effectiveQuickFilterPlacement === 'toolbar' }]"
|
|
4
4
|
data-testid="cn-index-page"
|
|
5
5
|
@keydown="onListKeydown">
|
|
6
6
|
<!-- Header — overridable via #header slot. CnPageHeader ALWAYS renders:
|
|
@@ -172,7 +172,7 @@
|
|
|
172
172
|
:maxVisible="quickFilterMaxVisible"
|
|
173
173
|
:fit="false"
|
|
174
174
|
:multiple="quickFilterMultiple"
|
|
175
|
-
:activeIndex="
|
|
175
|
+
:activeIndex="shownQuickFilterIndex"
|
|
176
176
|
:selectedIndices="selectedQuickFilterIndices"
|
|
177
177
|
:counts="effectiveTabCounts"
|
|
178
178
|
@update:activeIndex="onQuickFilterChange"
|
|
@@ -1034,6 +1034,7 @@
|
|
|
1034
1034
|
</ol>
|
|
1035
1035
|
<div v-if="mapList.missing.length > 0" class="cn-index-page__map-missing" data-testid="cn-index-map-missing">
|
|
1036
1036
|
<strong>{{ mapMissingTitle }}</strong>
|
|
1037
|
+
<span v-if="mapMissingNote" class="cn-index-page__map-missing-note" data-testid="cn-index-map-missing-note">{{ mapMissingNote }}</span>
|
|
1037
1038
|
<NcButton variant="tertiary-no-background" data-testid="cn-index-map-missing-table" @click="onViewModeChange('table')">
|
|
1038
1039
|
{{ mapMissingLink }}
|
|
1039
1040
|
</NcButton>
|
|
@@ -1459,6 +1460,7 @@ import { countLine } from '../../utils/countLine.js'
|
|
|
1459
1460
|
import { reportBindingProblems } from '../../utils/diagnostics.js'
|
|
1460
1461
|
import { fetchGroupedCounts } from '../../utils/fetchAggregate.js'
|
|
1461
1462
|
import { fetchFilterCounts, fetchListTotal } from '../../utils/fetchFilterCounts.js'
|
|
1463
|
+
import { fillTemplate } from '../../utils/fillTemplate.js'
|
|
1462
1464
|
import { listText, rangeChipText, rangeEnds, relativeRangeText } from '../../utils/filterRangeLabel.js'
|
|
1463
1465
|
import { unwrapAppConfig } from '../../utils/formatMetric.js'
|
|
1464
1466
|
import { groupDisplayName, loadGroupDisplayName } from '../../utils/groupAutocomplete.js'
|
|
@@ -2238,6 +2240,21 @@ export default {
|
|
|
2238
2240
|
default: '',
|
|
2239
2241
|
},
|
|
2240
2242
|
|
|
2243
|
+
/**
|
|
2244
|
+
* Board look: the count line while a saved view is applied (manifest
|
|
2245
|
+
* `config.savedViewCountText`), a template as `countText` that may name
|
|
2246
|
+
* the view's conditions as `{view}`: its description, else its filters
|
|
2247
|
+
* in words (DqFilterInMenu "3 van 48 lopende zaken · termijn binnen 7
|
|
2248
|
+
* dagen, van mij · gesorteerd op termijn"). A view's own `countText`
|
|
2249
|
+
* override and a scope's come first.
|
|
2250
|
+
*
|
|
2251
|
+
* @spec openspec/changes/applied-view-lights-its-lens/specs/applied-view-lights-its-lens/spec.md
|
|
2252
|
+
*/
|
|
2253
|
+
savedViewCountText: {
|
|
2254
|
+
type: String,
|
|
2255
|
+
default: '',
|
|
2256
|
+
},
|
|
2257
|
+
|
|
2241
2258
|
/**
|
|
2242
2259
|
* Board look: a count line per view (manifest `config.countTextByView`),
|
|
2243
2260
|
* `{ table?, cards?, list?, board?, map? }`, each a template as
|
|
@@ -4578,6 +4595,8 @@ export default {
|
|
|
4578
4595
|
savedViewCounts: null,
|
|
4579
4596
|
// The id (or slug) of the saved view that is applied; its chip shows selected under the board look.
|
|
4580
4597
|
appliedSavedViewId: '',
|
|
4598
|
+
/** Whether the reader picked a lens chip after the applied view (then their chip shows). */
|
|
4599
|
+
lensChosenByHand: false,
|
|
4581
4600
|
// The sort option the applied view's `overrides.sortOption` selected, so leaving the view can undo it.
|
|
4582
4601
|
viewSortOption: '',
|
|
4583
4602
|
// The applied view's filters as one comparable key, so the address keeps naming the view until they change.
|
|
@@ -6417,13 +6436,53 @@ export default {
|
|
|
6417
6436
|
* @spec openspec/changes/working-list-row-actions/specs/index-page/spec.md
|
|
6418
6437
|
*/
|
|
6419
6438
|
/**
|
|
6420
|
-
* The chip
|
|
6421
|
-
*
|
|
6422
|
-
*
|
|
6439
|
+
* The lens chip an applied saved view narrows within: the non-default
|
|
6440
|
+
* tab whose every condition the view's own conditions (its filters
|
|
6441
|
+
* over its locked filters, tokens as written) hold, the most specific
|
|
6442
|
+
* first (DqFilterInMenu: "Termijn deze week" lit for the view of that
|
|
6443
|
+
* name). Null without an applied view or a fitting tab.
|
|
6444
|
+
*
|
|
6445
|
+
* @return {number|null} The tab index.
|
|
6446
|
+
* @spec openspec/changes/applied-view-lights-its-lens/specs/applied-view-lights-its-lens/spec.md
|
|
6447
|
+
*/
|
|
6448
|
+
appliedViewLensIndex() {
|
|
6449
|
+
const view = this.appliedSavedView
|
|
6450
|
+
const tabs = Array.isArray(this.tabStripEntries) ? this.tabStripEntries : []
|
|
6451
|
+
if (!view || tabs.length === 0) {
|
|
6452
|
+
return null
|
|
6453
|
+
}
|
|
6454
|
+
const query = view.query && typeof view.query === 'object' ? view.query : {}
|
|
6455
|
+
const locked = query.overrides && typeof query.overrides.lockedFilters === 'object' ? query.overrides.lockedFilters : {}
|
|
6456
|
+
const conditions = { ...(locked || {}), ...(query.filters || view.filters || {}) }
|
|
6457
|
+
const same = (a, b) => JSON.stringify(Array.isArray(a) ? a.map(String) : String(a)) === JSON.stringify(Array.isArray(b) ? b.map(String) : String(b))
|
|
6458
|
+
let best = null
|
|
6459
|
+
let bestSize = 0
|
|
6460
|
+
tabs.forEach((tab, index) => {
|
|
6461
|
+
const filter = tab && tab.filter && typeof tab.filter === 'object' ? tab.filter : {}
|
|
6462
|
+
const keys = Object.keys(filter)
|
|
6463
|
+
if (tab.default === true || keys.length === 0 || keys.length <= bestSize) {
|
|
6464
|
+
return
|
|
6465
|
+
}
|
|
6466
|
+
if (keys.every((key) => Object.hasOwn(conditions, key) && same(conditions[key], filter[key]))) {
|
|
6467
|
+
best = index
|
|
6468
|
+
bestSize = keys.length
|
|
6469
|
+
}
|
|
6470
|
+
})
|
|
6471
|
+
return best
|
|
6472
|
+
},
|
|
6473
|
+
|
|
6474
|
+
/**
|
|
6475
|
+
* The chip the strip lights: the lens an applied saved view narrows
|
|
6476
|
+
* within (until the reader picks a chip), else the active tab, else
|
|
6477
|
+
* the default tab of tabs that arrived after setup
|
|
6478
|
+
* (`quickFiltersFrom`), which is the one the fetch applies.
|
|
6423
6479
|
*
|
|
6424
6480
|
* @return {number|null} The tab index, or null without tabs.
|
|
6425
6481
|
*/
|
|
6426
6482
|
shownQuickFilterIndex() {
|
|
6483
|
+
if (!this.quickFilterMultiple && !this.lensChosenByHand && this.appliedViewLensIndex !== null) {
|
|
6484
|
+
return this.appliedViewLensIndex
|
|
6485
|
+
}
|
|
6427
6486
|
if (this.activeQuickFilterIndex !== null && this.activeQuickFilterIndex !== undefined) {
|
|
6428
6487
|
return this.activeQuickFilterIndex
|
|
6429
6488
|
}
|
|
@@ -7217,6 +7276,31 @@ export default {
|
|
|
7217
7276
|
return n('nextcloud-vue', '%n without an address', '%n without an address', this.mapList.missing.length)
|
|
7218
7277
|
},
|
|
7219
7278
|
|
|
7279
|
+
/**
|
|
7280
|
+
* The sentence on that card naming the rows without a place by the
|
|
7281
|
+
* list's title template, three at most and the rest counted: "A, B and
|
|
7282
|
+
* C have no location, so they are not on the map." Empty without a
|
|
7283
|
+
* title template.
|
|
7284
|
+
*
|
|
7285
|
+
* @spec openspec/changes/map-missing-card-names-the-cases/specs/map-missing-card-names-the-cases/spec.md#requirement-the-missing-address-card-names-the-cases-it-counts
|
|
7286
|
+
* @return {string} The sentence.
|
|
7287
|
+
*/
|
|
7288
|
+
mapMissingNote() {
|
|
7289
|
+
const list = this.mapConfig && this.mapConfig.list
|
|
7290
|
+
const template = list && typeof list.title === 'string' ? this.cnTranslate(list.title) : ''
|
|
7291
|
+
const missing = this.mapList.missing
|
|
7292
|
+
if (template === '' || missing.length === 0) {
|
|
7293
|
+
return ''
|
|
7294
|
+
}
|
|
7295
|
+
const shown = missing.slice(0, 3).map((row) => fillTemplate(template, row, undefined, this.cnFormatters ? { formatters: this.cnFormatters } : null)).filter((title) => title !== '')
|
|
7296
|
+
if (shown.length === 0) {
|
|
7297
|
+
return ''
|
|
7298
|
+
}
|
|
7299
|
+
const rest = missing.length - shown.length
|
|
7300
|
+
const names = listText(rest > 0 ? [...shown, n('nextcloud-vue', '%n other', '%n others', rest)] : shown, getCanonicalLocale() || undefined)
|
|
7301
|
+
return n('nextcloud-vue', '{names} has no location, so it is not on the map.', '{names} have no location, so they are not on the map.', missing.length, { names })
|
|
7302
|
+
},
|
|
7303
|
+
|
|
7220
7304
|
/** @return {string} The link from that card to the table. */
|
|
7221
7305
|
mapMissingLink() {
|
|
7222
7306
|
return t('nextcloud-vue', 'Show them in the table')
|
|
@@ -8788,6 +8872,11 @@ export default {
|
|
|
8788
8872
|
* @return {string}
|
|
8789
8873
|
*/
|
|
8790
8874
|
presentedCountText() {
|
|
8875
|
+
const viewLine = this.savedViewCountText
|
|
8876
|
+
const view = this.appliedSavedView
|
|
8877
|
+
if (view && typeof viewLine === 'string' && viewLine !== '' && this.activeScopePresentation.countText === undefined && !savedViewOverrides(view)?.countText) {
|
|
8878
|
+
return viewLine
|
|
8879
|
+
}
|
|
8791
8880
|
if (this.activeScopePresentation.countText === undefined) {
|
|
8792
8881
|
const byView = this.countTextByView
|
|
8793
8882
|
const own = byView && typeof byView === 'object' ? byView[this.currentViewMode] : undefined
|
|
@@ -8798,6 +8887,23 @@ export default {
|
|
|
8798
8887
|
return this.presented('countText')
|
|
8799
8888
|
},
|
|
8800
8889
|
|
|
8890
|
+
/**
|
|
8891
|
+
* The applied saved view's conditions for the count line's `{view}`:
|
|
8892
|
+
* its description, else its filters in words, starting lower case.
|
|
8893
|
+
*
|
|
8894
|
+
* @return {string}
|
|
8895
|
+
* @spec openspec/changes/applied-view-lights-its-lens/specs/applied-view-lights-its-lens/spec.md
|
|
8896
|
+
*/
|
|
8897
|
+
appliedViewConditionsText() {
|
|
8898
|
+
const view = this.appliedSavedView
|
|
8899
|
+
if (!view) {
|
|
8900
|
+
return ''
|
|
8901
|
+
}
|
|
8902
|
+
const own = typeof view.description === 'string' ? view.description.trim() : ''
|
|
8903
|
+
const text = own !== '' ? own : String(this.viewFilterSummary(view) || '')
|
|
8904
|
+
return text.charAt(0).toLowerCase() + text.slice(1)
|
|
8905
|
+
},
|
|
8906
|
+
|
|
8801
8907
|
headerDescriptionBase() {
|
|
8802
8908
|
const total = this.effectivePagination?.total
|
|
8803
8909
|
// Board look: the count line is a template over the rows on this page
|
|
@@ -8821,6 +8927,7 @@ export default {
|
|
|
8821
8927
|
.replace('{shown}', String(shown))
|
|
8822
8928
|
.replace('{total}', String(total))
|
|
8823
8929
|
.replace(/\{term\}/g, this.sourceTerm)
|
|
8930
|
+
.replace(/\{view\}/g, this.appliedViewConditionsText)
|
|
8824
8931
|
}
|
|
8825
8932
|
return this.countLine(this.countSubtitle, total, shown)
|
|
8826
8933
|
}
|
|
@@ -8886,6 +8993,17 @@ export default {
|
|
|
8886
8993
|
return !!this.resolvedSidebar.enabled && this.resolvedSidebar.show !== false
|
|
8887
8994
|
},
|
|
8888
8995
|
|
|
8996
|
+
/**
|
|
8997
|
+
* Whether the page's side panel is open now; the board look then lays
|
|
8998
|
+
* the header out narrower (DqZakenSorteren).
|
|
8999
|
+
*
|
|
9000
|
+
* @spec openspec/changes/board-header-buttons-under-title-beside-side-panel/specs/board-header-buttons-under-title-beside-side-panel/spec.md#requirement-the-header-buttons-sit-under-the-title-while-the-side-panel-is-open
|
|
9001
|
+
* @return {boolean}
|
|
9002
|
+
*/
|
|
9003
|
+
sidebarPanelOpen() {
|
|
9004
|
+
return Boolean(this.sidebarOpen && this.hasSidebar)
|
|
9005
|
+
},
|
|
9006
|
+
|
|
8889
9007
|
/**
|
|
8890
9008
|
* Whether the board toolbar draws the Filter button as a menu: the
|
|
8891
9009
|
* board look, `filterMenu` on, something to filter by, and no filter
|
|
@@ -8928,7 +9046,9 @@ export default {
|
|
|
8928
9046
|
|
|
8929
9047
|
/** Search props forwarded to the embedded CnIndexSidebar (defaults applied per CnIndexSidebar). */
|
|
8930
9048
|
sidebarSearchProps() {
|
|
8931
|
-
|
|
9049
|
+
// The page's own search hint, unless `sidebar.search` names one.
|
|
9050
|
+
const own = this.shownSearchPlaceholder ? { searchPlaceholder: this.shownSearchPlaceholder } : {}
|
|
9051
|
+
return { ...own, ...((this.sidebar && this.sidebar.search) || {}) }
|
|
8932
9052
|
},
|
|
8933
9053
|
|
|
8934
9054
|
/**
|
|
@@ -10751,6 +10871,7 @@ export default {
|
|
|
10751
10871
|
// `activeQuickFilterIndex` is a setup-returned ref; the
|
|
10752
10872
|
// Vue 2 ref-unwrap proxy makes plain assignment work.
|
|
10753
10873
|
this.activeQuickFilterIndex = index
|
|
10874
|
+
this.lensChosenByHand = true
|
|
10754
10875
|
this.$emit('quick-filter-change', index)
|
|
10755
10876
|
},
|
|
10756
10877
|
|
|
@@ -11519,10 +11640,16 @@ export default {
|
|
|
11519
11640
|
const bucket = facet && Array.isArray(facet.values)
|
|
11520
11641
|
? facet.values.find((fv) => fv && typeof fv === 'object' && String(fv.value) === id)
|
|
11521
11642
|
: null
|
|
11522
|
-
|
|
11643
|
+
// A facet that only echoes the value names nothing; a group or an
|
|
11644
|
+
// option below may.
|
|
11645
|
+
if (bucket && typeof bucket.label === 'string' && bucket.label !== '' && bucket.label !== id) {
|
|
11523
11646
|
return this.cnTranslate(bucket.label)
|
|
11524
11647
|
}
|
|
11525
11648
|
const prop = this.effectiveSchema?.properties?.[key]
|
|
11649
|
+
// The reader on a user filter is "me" (DqFilterInMenu "Behandelaar: ik").
|
|
11650
|
+
if (prop && prop.referenceType === 'nextcloud-user' && id === (getCurrentUser()?.uid ?? '')) {
|
|
11651
|
+
return t('nextcloud-vue', 'me')
|
|
11652
|
+
}
|
|
11526
11653
|
if (prop && prop.referenceType === 'nextcloud-group') {
|
|
11527
11654
|
const name = groupDisplayName(id)
|
|
11528
11655
|
if (name === null) {
|
|
@@ -13180,6 +13307,7 @@ export default {
|
|
|
13180
13307
|
*/
|
|
13181
13308
|
onApplySavedView(view, { keepSavedViewKey = false } = {}) {
|
|
13182
13309
|
this.appliedSavedViewId = view && (view.id || view.slug) ? String(view.id || view.slug) : ''
|
|
13310
|
+
this.lensChosenByHand = false
|
|
13183
13311
|
const state = extractViewState(view)
|
|
13184
13312
|
// A view's filters may carry tokens (`@me`, `@myTeam`): resolved here,
|
|
13185
13313
|
// and an optional one that answers nothing (no team) is dropped. A
|
|
@@ -32,11 +32,17 @@
|
|
|
32
32
|
</div>
|
|
33
33
|
|
|
34
34
|
<div class="cn-index-sidebar__section">
|
|
35
|
+
<!-- The board look names the field by its hint, as the list's
|
|
36
|
+
own search field, with the magnifier (DqZakenSorteren). -->
|
|
35
37
|
<NcTextField
|
|
36
38
|
:modelValue="searchValue || ''"
|
|
37
39
|
:placeholder="searchPlaceholder"
|
|
38
|
-
:label="searchLabel"
|
|
39
|
-
@update:modelValue="$emit('search', $event)"
|
|
40
|
+
:label="isBoardLook ? searchPlaceholder : searchLabel"
|
|
41
|
+
@update:modelValue="$emit('search', $event)">
|
|
42
|
+
<template v-if="isBoardLook" #icon>
|
|
43
|
+
<Magnify :size="18" />
|
|
44
|
+
</template>
|
|
45
|
+
</NcTextField>
|
|
40
46
|
</div>
|
|
41
47
|
|
|
42
48
|
<!-- Sort (list, card and map views; the table sorts by its headers):
|
|
@@ -355,6 +361,7 @@ import DragVertical from 'vue-material-design-icons/DragVertical.vue'
|
|
|
355
361
|
import FilterOutline from 'vue-material-design-icons/FilterOutline.vue'
|
|
356
362
|
import FilterRemoveOutline from 'vue-material-design-icons/FilterRemoveOutline.vue'
|
|
357
363
|
import InformationOutline from 'vue-material-design-icons/InformationOutline.vue'
|
|
364
|
+
import Magnify from 'vue-material-design-icons/Magnify.vue'
|
|
358
365
|
import Pin from 'vue-material-design-icons/Pin.vue'
|
|
359
366
|
import PinOutline from 'vue-material-design-icons/PinOutline.vue'
|
|
360
367
|
import ViewColumnOutline from 'vue-material-design-icons/ViewColumnOutline.vue'
|
|
@@ -410,6 +417,7 @@ export default {
|
|
|
410
417
|
Pin,
|
|
411
418
|
PinOutline,
|
|
412
419
|
InformationOutline,
|
|
420
|
+
Magnify,
|
|
413
421
|
},
|
|
414
422
|
|
|
415
423
|
inject: {
|
|
@@ -25,4 +25,8 @@ registerDashboardWidget('mail', {
|
|
|
25
25
|
displayName: 'Mail',
|
|
26
26
|
icon: 'EmailOutline',
|
|
27
27
|
surfaces: ['detail-page'],
|
|
28
|
+
// Draws its own title row; on a card surface it stands in an untitled card.
|
|
29
|
+
// @spec openspec/changes/mail-widget-card/specs/mail-widget-card/spec.md#requirement-the-mail-widget-stands-in-a-card-on-a-card-surface
|
|
30
|
+
ownsTitle: true,
|
|
31
|
+
chrome: 'card',
|
|
28
32
|
})
|
|
@@ -1093,12 +1093,16 @@ export default {
|
|
|
1093
1093
|
white-space: nowrap;
|
|
1094
1094
|
}
|
|
1095
1095
|
|
|
1096
|
+
/* A theme that colours every th (thematiq's table header token) leaves
|
|
1097
|
+
the board grid's head white. */
|
|
1096
1098
|
.cn-notification-matrix__table {
|
|
1099
|
+
--nldesign-component-table-header-background-color: transparent;
|
|
1097
1100
|
font-size: 14px;
|
|
1098
1101
|
}
|
|
1099
1102
|
|
|
1100
1103
|
.cn-notification-matrix__table thead th {
|
|
1101
1104
|
padding: 8px 10px 8px 0;
|
|
1105
|
+
line-height: 1.2;
|
|
1102
1106
|
border-block-end: 1px solid var(--color-border);
|
|
1103
1107
|
color: var(--color-text-maxcontrast);
|
|
1104
1108
|
font-size: 13px;
|
|
@@ -860,7 +860,7 @@ export default {
|
|
|
860
860
|
// `secondary` (a second, muted line under the cell) rides
|
|
861
861
|
// along too: the table draws it, and dropping it here took the
|
|
862
862
|
// list rows' second line away (zuiddrecht-pixel-gaps-3).
|
|
863
|
-
for (const k of ['format', 'widget', 'widgetProps', 'formatter', 'align', 'width', 'type', 'enum', 'enumLabels', 'sortable', 'secondary', 'colorMap', 'grow']) {
|
|
863
|
+
for (const k of ['format', 'widget', 'widgetProps', 'formatter', 'align', 'width', 'type', 'enum', 'enumLabels', 'sortable', 'secondary', 'colorMap', 'grow', 'cellClass']) {
|
|
864
864
|
if (c[k] !== undefined) {
|
|
865
865
|
out[k] = c[k]
|
|
866
866
|
}
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
:reviewSummary="reviewSummary"
|
|
25
25
|
:footnote="footnote"
|
|
26
26
|
:nameSecondary="nameSecondary"
|
|
27
|
+
:secondLine="secondLine"
|
|
27
28
|
:linkedItems="linkedItems"
|
|
28
29
|
:columns="columns"
|
|
29
30
|
:rowData="rowDataSource"
|
|
@@ -450,6 +451,8 @@ export default {
|
|
|
450
451
|
footnote: { type: String, default: '' },
|
|
451
452
|
/** Forwarded to CnFilesBrowser: the second line under each file's name. */
|
|
452
453
|
nameSecondary: { type: String, default: '' },
|
|
454
|
+
/** Forwarded to CnFilesBrowser: the second line as a list of fields, or variants. */
|
|
455
|
+
secondLine: { type: Array, default: null },
|
|
453
456
|
/** A dotted path to the list of records in the `rowDataUrl` answer; empty reads the answer itself. */
|
|
454
457
|
rowDataPath: { type: String, default: '' },
|
|
455
458
|
/** The record field that holds the Nextcloud file id. */
|