@conduction/nextcloud-vue 2.69.0 → 2.71.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 +25 -0
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js.map +1 -1
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js +155 -152
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js.map +1 -1
- package/dist/esm/components/CnAppNav/CnAppNav.vue2.js +77 -0
- package/dist/esm/components/CnAppNav/CnAppNav.vue2.js.map +1 -1
- package/dist/esm/components/CnAppNav/CnAppNav.vue3.js +8 -8
- package/dist/esm/components/CnAppNav/CnAppNav.vue3.js.map +1 -1
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js +151 -13
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js.map +1 -1
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js +3 -1
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js.map +1 -1
- package/dist/esm/components/CnBreadcrumbs/CnBreadcrumbs.vue.js +1 -0
- package/dist/esm/components/CnBreadcrumbs/CnBreadcrumbs.vue.js.map +1 -1
- package/dist/esm/components/CnBreadcrumbs/CnBreadcrumbs.vue2.js +28 -0
- package/dist/esm/components/CnBreadcrumbs/CnBreadcrumbs.vue2.js.map +1 -1
- package/dist/esm/components/CnBreadcrumbs/CnBreadcrumbs.vue3.js +4 -2
- package/dist/esm/components/CnBreadcrumbs/CnBreadcrumbs.vue3.js.map +1 -1
- package/dist/esm/components/CnCalendarWidget/CnCalendarWidget.vue2.js +25 -1
- package/dist/esm/components/CnCalendarWidget/CnCalendarWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnCalendarWidget/CnCalendarWidget.vue3.js +32 -17
- package/dist/esm/components/CnCalendarWidget/CnCalendarWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnCapabilityTable/CnCapabilityTable.vue2.js +14 -1
- package/dist/esm/components/CnCapabilityTable/CnCapabilityTable.vue2.js.map +1 -1
- package/dist/esm/components/CnCapabilityTable/CnCapabilityTable.vue3.js.map +1 -1
- package/dist/esm/components/CnDashboardGrid/CnDashboardGrid.vue2.js +43 -2
- package/dist/esm/components/CnDashboardGrid/CnDashboardGrid.vue2.js.map +1 -1
- package/dist/esm/components/CnDashboardGrid/CnDashboardGrid.vue3.js +3 -3
- package/dist/esm/components/CnDashboardGrid/CnDashboardGrid.vue3.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +25 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +40 -43
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +35 -1
- package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +54 -3
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js +6 -3
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js +28 -0
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js +3 -2
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js.map +1 -1
- package/dist/esm/components/CnFeaturesAndRoadmapPage/CnFeaturesAndRoadmapPage.vue2.js +12 -0
- package/dist/esm/components/CnFeaturesAndRoadmapPage/CnFeaturesAndRoadmapPage.vue2.js.map +1 -1
- package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue2.js +9 -0
- package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue2.js.map +1 -1
- package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue3.js.map +1 -1
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js +29 -2
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js.map +1 -1
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js +71 -34
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js.map +1 -1
- package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue2.js +54 -7
- package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue3.js +26 -8
- package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +165 -0
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +69 -26
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue2.js.map +1 -1
- package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js +4 -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/CnNotesTab.vue2.js +1 -1
- package/dist/esm/components/CnObjectSidebar/CnNotesTab.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnNotesTab.vue3.js.map +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js.map +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js +46 -32
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js.map +1 -1
- package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue2.js +17 -3
- package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue3.js +25 -24
- package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue2.js +27 -0
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js +7 -0
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnStatsBlock/CnStatsBlock.vue2.js +24 -1
- package/dist/esm/components/CnStatsBlock/CnStatsBlock.vue2.js.map +1 -1
- package/dist/esm/components/CnStatsBlock/CnStatsBlock.vue3.js +1 -1
- package/dist/esm/components/CnStatsBlock/CnStatsBlock.vue3.js.map +1 -1
- package/dist/esm/components/CnStatsBlockWidget/CnStatsBlockWidget.vue2.js +11 -0
- package/dist/esm/components/CnStatsBlockWidget/CnStatsBlockWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnStatsBlockWidget/CnStatsBlockWidget.vue3.js +4 -2
- package/dist/esm/components/CnStatsBlockWidget/CnStatsBlockWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnWalkthrough/CnWalkthrough.vue2.js +30 -9
- package/dist/esm/components/CnWalkthrough/CnWalkthrough.vue2.js.map +1 -1
- package/dist/esm/components/CnWalkthrough/CnWalkthrough.vue3.js.map +1 -1
- package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue2.js +15 -2
- package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue3.js +31 -32
- package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue3.js.map +1 -1
- package/dist/esm/composables/useWalkthrough.js +11 -3
- package/dist/esm/composables/useWalkthrough.js.map +1 -1
- package/dist/esm/nextcloud-vue.css +198 -0
- package/dist/esm/utils/capabilityComparison.js +29 -1
- package/dist/esm/utils/capabilityComparison.js.map +1 -1
- package/dist/esm/utils/columnFilters.js +54 -4
- package/dist/esm/utils/columnFilters.js.map +1 -1
- package/dist/esm/utils/userAutocomplete.js +69 -3
- package/dist/esm/utils/userAutocomplete.js.map +1 -1
- package/dist/esm/utils/validateManifestV2.compiled.js +2 -2
- package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +2778 -1630
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +198 -0
- package/package.json +1 -1
- package/src/components/CnActionsBar/CnActionsBar.md +2 -0
- package/src/components/CnActionsBar/CnActionsBar.vue +28 -2
- package/src/components/CnAppNav/CnAppNav.vue +85 -8
- package/src/components/CnAppRoot/CnAppRoot.vue +153 -13
- package/src/components/CnBreadcrumbs/CnBreadcrumbs.vue +45 -0
- package/src/components/CnCalendarWidget/CnCalendarWidget.vue +32 -4
- package/src/components/CnCapabilityTable/CnCapabilityTable.vue +14 -0
- package/src/components/CnDashboardGrid/CnDashboardGrid.md +2 -0
- package/src/components/CnDashboardGrid/CnDashboardGrid.vue +54 -2
- package/src/components/CnDashboardPage/CnDashboardPage.vue +46 -19
- package/src/components/CnDataTable/CnDataTable.vue +35 -1
- package/src/components/CnDetailPage/CnDetailPage.md +2 -0
- package/src/components/CnDetailPage/CnDetailPage.vue +57 -3
- package/src/components/CnDetailWidgetHost/CnDetailWidgetHost.vue +30 -1
- package/src/components/CnFeaturesAndRoadmapPage/CnFeaturesAndRoadmapPage.vue +12 -0
- package/src/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue +9 -0
- package/src/components/CnFormDialog/CnFormDialog.vue +62 -2
- package/src/components/CnHeaderWidget/CnHeaderWidget.vue +95 -8
- package/src/components/CnIndexPage/CnIndexPage.vue +194 -7
- package/src/components/CnNextStepCard/CnNextStepCard.vue +11 -0
- package/src/components/CnObjectListWidget/CnObjectListWidget.vue +4 -1
- package/src/components/CnObjectSidebar/CnNotesTab.vue +1 -1
- package/src/components/CnSetupWizard/CnSetupWizard.vue +7 -0
- package/src/components/CnStackedBarWidget/CnStackedBarWidget.vue +34 -7
- package/src/components/CnStagesWidget/CnStagesWidget.vue +19 -0
- package/src/components/CnStatWidget/CnStatWidget.vue +36 -0
- package/src/components/CnStatsBlock/CnStatsBlock.md +2 -0
- package/src/components/CnStatsBlock/CnStatsBlock.vue +25 -2
- package/src/components/CnStatsBlockWidget/CnStatsBlockWidget.vue +13 -0
- package/src/components/CnWalkthrough/CnWalkthrough.vue +30 -9
- package/src/components/CnWeekStripWidget/CnWeekStripWidget.vue +24 -3
- package/src/composables/useWalkthrough.js +11 -3
- package/src/css/dashboard.css +44 -0
- package/src/css/detail-page.css +10 -0
- package/src/css/index-page.css +12 -0
- package/src/css/kpi-card.css +15 -0
- package/src/schemas/app-manifest-v2.schema.json +47 -5
- package/src/utils/capabilityComparison.js +28 -0
- package/src/utils/columnFilters.js +54 -4
- package/src/utils/userAutocomplete.js +68 -2
- package/src/utils/validateManifestV2.compiled.js +2 -2
|
@@ -444,3 +444,5 @@ When the schema-driven fetch answers 404 the page shows a not-found state whose
|
|
|
444
444
|
### Header card and header widget
|
|
445
445
|
|
|
446
446
|
`headerCard` (default `false`) draws the header as a bordered card. `headerWidget` (default `''`) names a widget in `widgets` to render inside the header under the title, without a card of its own and out of the body grid: the stages bars of the board's case card.
|
|
447
|
+
|
|
448
|
+
`showWidgetActions` (Boolean, default `true`): `false` (manifest `config.showWidgetActions: false`) drops the overflow Actions menu from the cards of the body grid and the side column, unless a widget definition sets `showActions: true`.
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
class="cn-detail-page__breadcrumbs"
|
|
49
49
|
:crumbs="breadcrumbCrumbs"
|
|
50
50
|
:rootText="breadcrumbCrumbs[0].icon === undefined"
|
|
51
|
+
:separator="breadcrumbSeparator"
|
|
51
52
|
data-testid="cn-detail-page-breadcrumbs" />
|
|
52
53
|
<!-- Header -->
|
|
53
54
|
<div
|
|
@@ -749,6 +750,7 @@
|
|
|
749
750
|
:widget="findWidget(item)"
|
|
750
751
|
chrome="card"
|
|
751
752
|
:showCardTitle="showCardTitle(item)"
|
|
753
|
+
:showActions="showWidgetActions"
|
|
752
754
|
:objectId="objectId"
|
|
753
755
|
:object="currentObject"
|
|
754
756
|
:objectType="resolvedObjectType"
|
|
@@ -959,6 +961,7 @@
|
|
|
959
961
|
:widget="widget"
|
|
960
962
|
chrome="card"
|
|
961
963
|
:showCardTitle="true"
|
|
964
|
+
:showActions="showWidgetActions"
|
|
962
965
|
:objectId="objectId"
|
|
963
966
|
:object="currentObject"
|
|
964
967
|
:objectType="resolvedObjectType"
|
|
@@ -2235,18 +2238,38 @@ export default {
|
|
|
2235
2238
|
* belongs to; the record's display name follows as the current
|
|
2236
2239
|
* crumb. `label` goes through the host translate function and shows
|
|
2237
2240
|
* as text; `icon` (an MDI name, e.g. `Home`) draws that icon instead,
|
|
2238
|
-
* with the label as its accessible name.
|
|
2241
|
+
* with the label as its accessible name. `currentField` names a field
|
|
2242
|
+
* of the record (a dotted path, e.g. `identifier`) whose value is the
|
|
2243
|
+
* current crumb instead of the display name; an empty value falls back
|
|
2244
|
+
* to the display name. `separator` draws that text (e.g. `/`) between
|
|
2245
|
+
* the crumbs instead of the chevron. Null (the default) draws no
|
|
2239
2246
|
* trail.
|
|
2240
2247
|
*
|
|
2241
2248
|
* @spec openspec/changes/zuiddrecht-pixel-gaps/specs/zuiddrecht-pixel-gaps/spec.md#requirement-a-detail-page-drops-its-eyebrow-and-shows-a-breadcrumb
|
|
2242
2249
|
* @spec openspec/changes/zuiddrecht-pixel-gaps-2/specs/zuiddrecht-pixel-gaps-2/spec.md#requirement-a-declared-breadcrumb-label-shows-as-text
|
|
2243
|
-
* @
|
|
2250
|
+
* @spec openspec/changes/zuiddrecht-pixel-gaps-3/specs/zuiddrecht-pixel-gaps-3/spec.md#requirement-a-breadcrumb-can-name-the-record-by-a-field-and-use-a-text-separator
|
|
2251
|
+
* @type {{label: string, route?: string, params?: object, href?: string, icon?: string, currentField?: string, separator?: string}|null}
|
|
2244
2252
|
*/
|
|
2245
2253
|
breadcrumb: {
|
|
2246
2254
|
type: Object,
|
|
2247
2255
|
default: null,
|
|
2248
2256
|
},
|
|
2249
2257
|
|
|
2258
|
+
/**
|
|
2259
|
+
* Whether the record's widget cards (the body grid and the side
|
|
2260
|
+
* column) keep their overflow Actions menu when their definition does
|
|
2261
|
+
* not say (`showActions`). `false` (manifest
|
|
2262
|
+
* `config.showWidgetActions: false`) drops it, as on a dashboard; a
|
|
2263
|
+
* widget with `showActions: true` keeps its menu. A card that offers
|
|
2264
|
+
* an Add action keeps the menu that holds it. True by default.
|
|
2265
|
+
*
|
|
2266
|
+
* @spec openspec/changes/zuiddrecht-pixel-gaps-3/specs/zuiddrecht-pixel-gaps-3/spec.md#requirement-a-detail-page-can-drop-the-widget-actions-menu
|
|
2267
|
+
*/
|
|
2268
|
+
showWidgetActions: {
|
|
2269
|
+
type: Boolean,
|
|
2270
|
+
default: true,
|
|
2271
|
+
},
|
|
2272
|
+
|
|
2250
2273
|
/**
|
|
2251
2274
|
* A column of cards beside the body (manifest `config.sideColumn`),
|
|
2252
2275
|
* for the record's facts: deadline, requester, handler, links. Each
|
|
@@ -3438,7 +3461,38 @@ export default {
|
|
|
3438
3461
|
} else if (crumb.href) {
|
|
3439
3462
|
first.href = crumb.href
|
|
3440
3463
|
}
|
|
3441
|
-
return [first, { label: this.
|
|
3464
|
+
return [first, { label: this.breadcrumbCurrentLabel }]
|
|
3465
|
+
},
|
|
3466
|
+
|
|
3467
|
+
/**
|
|
3468
|
+
* The current crumb: the record's `breadcrumb.currentField` value
|
|
3469
|
+
* (the case number on a case page) when declared and filled, else the
|
|
3470
|
+
* display name.
|
|
3471
|
+
*
|
|
3472
|
+
* @spec openspec/changes/zuiddrecht-pixel-gaps-3/specs/zuiddrecht-pixel-gaps-3/spec.md#requirement-a-breadcrumb-can-name-the-record-by-a-field-and-use-a-text-separator
|
|
3473
|
+
* @return {string}
|
|
3474
|
+
*/
|
|
3475
|
+
breadcrumbCurrentLabel() {
|
|
3476
|
+
const field = this.breadcrumb && this.breadcrumb.currentField
|
|
3477
|
+
if (typeof field === 'string' && field !== '') {
|
|
3478
|
+
const value = stageOf(this.resolvedObject, field)
|
|
3479
|
+
if (value !== '') {
|
|
3480
|
+
return value
|
|
3481
|
+
}
|
|
3482
|
+
}
|
|
3483
|
+
return this.displayTitle
|
|
3484
|
+
},
|
|
3485
|
+
|
|
3486
|
+
/**
|
|
3487
|
+
* The text drawn between the crumbs (`breadcrumb.separator`), or ''
|
|
3488
|
+
* for the chevron.
|
|
3489
|
+
*
|
|
3490
|
+
* @spec openspec/changes/zuiddrecht-pixel-gaps-3/specs/zuiddrecht-pixel-gaps-3/spec.md#requirement-a-breadcrumb-can-name-the-record-by-a-field-and-use-a-text-separator
|
|
3491
|
+
* @return {string}
|
|
3492
|
+
*/
|
|
3493
|
+
breadcrumbSeparator() {
|
|
3494
|
+
const separator = this.breadcrumb && this.breadcrumb.separator
|
|
3495
|
+
return typeof separator === 'string' ? separator : ''
|
|
3442
3496
|
},
|
|
3443
3497
|
|
|
3444
3498
|
/**
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
v-else-if="isData && schemaObject"
|
|
86
86
|
:title="resolvedTitle"
|
|
87
87
|
:chromeless="isBare"
|
|
88
|
-
:showActions="!isBare"
|
|
88
|
+
:showActions="!isBare && actionsShown"
|
|
89
89
|
:icon="widget.icon || null"
|
|
90
90
|
:schema="schemaObject"
|
|
91
91
|
:objectData="object"
|
|
@@ -165,6 +165,7 @@
|
|
|
165
165
|
v-else-if="renderer && isContentOnly && !isBare"
|
|
166
166
|
:title="widget.title || ''"
|
|
167
167
|
titleIconPosition="left"
|
|
168
|
+
:showActions="actionsShown || catalogAddEnabled"
|
|
168
169
|
:showRefresh="false"
|
|
169
170
|
:showRequestFeature="false"
|
|
170
171
|
class="cn-detail-page__catalog-card">
|
|
@@ -473,6 +474,21 @@ export default {
|
|
|
473
474
|
default: null,
|
|
474
475
|
},
|
|
475
476
|
|
|
477
|
+
/**
|
|
478
|
+
* Whether a widget on a card keeps its overflow Actions menu when its
|
|
479
|
+
* definition does not say (`showActions`). `false` (CnDetailPage
|
|
480
|
+
* `showWidgetActions: false`) drops it from the record's data cards; a
|
|
481
|
+
* definition with `showActions: true` keeps it, one with
|
|
482
|
+
* `showActions: false` drops it whatever this says. True by default,
|
|
483
|
+
* which is the menu every card had.
|
|
484
|
+
*
|
|
485
|
+
* @spec openspec/changes/zuiddrecht-pixel-gaps-3/specs/zuiddrecht-pixel-gaps-3/spec.md#requirement-a-detail-page-can-drop-the-widget-actions-menu
|
|
486
|
+
*/
|
|
487
|
+
showActions: {
|
|
488
|
+
type: Boolean,
|
|
489
|
+
default: true,
|
|
490
|
+
},
|
|
491
|
+
|
|
476
492
|
/**
|
|
477
493
|
* The consumer's component registry, consulted before the built-in
|
|
478
494
|
* catalog so a custom widget type overrides a built-in (REQ-MVR-005).
|
|
@@ -839,6 +855,19 @@ export default {
|
|
|
839
855
|
return this.content.allowCreate !== false
|
|
840
856
|
},
|
|
841
857
|
|
|
858
|
+
/**
|
|
859
|
+
* Whether the widget's overflow Actions menu renders: the definition's
|
|
860
|
+
* own `showActions` when it is a boolean, else the surface's
|
|
861
|
+
* `showActions`.
|
|
862
|
+
*
|
|
863
|
+
* @spec openspec/changes/zuiddrecht-pixel-gaps-3/specs/zuiddrecht-pixel-gaps-3/spec.md#requirement-a-detail-page-can-drop-the-widget-actions-menu
|
|
864
|
+
* @return {boolean} true when the menu renders.
|
|
865
|
+
*/
|
|
866
|
+
actionsShown() {
|
|
867
|
+
const own = this.widget && this.widget.showActions
|
|
868
|
+
return typeof own === 'boolean' ? own : this.showActions
|
|
869
|
+
},
|
|
870
|
+
|
|
842
871
|
/**
|
|
843
872
|
* The card header rule, with the surface's layout-driven answer winning
|
|
844
873
|
* when it supplied one.
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
// unconditionally.
|
|
41
41
|
import { loadState } from '@nextcloud/initial-state'
|
|
42
42
|
import CnFeaturesAndRoadmapView from '../CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue'
|
|
43
|
+
import { warnCapabilityComparisonDeprecated } from '../../utils/capabilityComparison.js'
|
|
43
44
|
import { DEFAULT_FORGE } from '../../utils/forge.js'
|
|
44
45
|
|
|
45
46
|
/**
|
|
@@ -175,6 +176,11 @@ export default {
|
|
|
175
176
|
* Manifest config > initialState (`features_roadmap_capabilities`) >
|
|
176
177
|
* null. When null the view renders its two stops as it always has.
|
|
177
178
|
*
|
|
179
|
+
* Deprecated: publish the comparison on the app's docs site and link to it (as dossiq #3312 and pipelinq #2195 did). Still rendered; removal waits for a major version. The same goes for the `features_roadmap_capabilities` initial
|
|
180
|
+
* state key. A development build warns once when either is set.
|
|
181
|
+
*
|
|
182
|
+
* @deprecated since 2.66.0, publish the comparison on the app's docs site and link to it.
|
|
183
|
+
* @spec openspec/changes/zuiddrecht-pixel-gaps-3/specs/zuiddrecht-pixel-gaps-3/spec.md#requirement-the-in-app-capability-comparison-is-deprecated
|
|
178
184
|
* @type {object|null}
|
|
179
185
|
*/
|
|
180
186
|
capabilityComparison: {
|
|
@@ -298,5 +304,11 @@ export default {
|
|
|
298
304
|
return readInitialState(this.effectiveAppId, 'features_roadmap_capabilities', null)
|
|
299
305
|
},
|
|
300
306
|
},
|
|
307
|
+
|
|
308
|
+
mounted() {
|
|
309
|
+
if (this.resolvedCapabilityComparison) {
|
|
310
|
+
warnCapabilityComparisonDeprecated('CnFeaturesAndRoadmapPage `capabilityComparison` / the `features_roadmap_capabilities` initial state')
|
|
311
|
+
}
|
|
312
|
+
},
|
|
301
313
|
}
|
|
302
314
|
</script>
|
|
@@ -114,6 +114,7 @@ import CnFeaturesAndRoadmapSidebar from '../CnFeaturesAndRoadmapSidebar/CnFeatur
|
|
|
114
114
|
import CnFeaturesTab from '../CnFeaturesTab/CnFeaturesTab.vue'
|
|
115
115
|
import CnRoadmapTab from '../CnRoadmapTab/CnRoadmapTab.vue'
|
|
116
116
|
import CnSupportDialog from '../CnSupportDialog/CnSupportDialog.vue'
|
|
117
|
+
import { warnCapabilityComparisonDeprecated } from '../../utils/capabilityComparison.js'
|
|
117
118
|
import { buildFeatureRequestUrl, DEFAULT_FORGE } from '../../utils/forge.js'
|
|
118
119
|
|
|
119
120
|
const DEFAULT_OPENBUILT_PATH = '/apps/openbuilt'
|
|
@@ -214,6 +215,11 @@ export default {
|
|
|
214
215
|
* When null (default) the toggle keeps its two stops and the view
|
|
215
216
|
* renders exactly as it does for every app that passes nothing.
|
|
216
217
|
*
|
|
218
|
+
* Deprecated: publish the comparison on the app's docs site and link to it (as dossiq #3312 and pipelinq #2195 did). Still rendered; removal waits for a major version.
|
|
219
|
+
* A development build warns once when it is set.
|
|
220
|
+
*
|
|
221
|
+
* @deprecated since 2.66.0, publish the comparison on the app's docs site and link to it.
|
|
222
|
+
* @spec openspec/changes/zuiddrecht-pixel-gaps-3/specs/zuiddrecht-pixel-gaps-3/spec.md#requirement-the-in-app-capability-comparison-is-deprecated
|
|
217
223
|
* @type {object|null}
|
|
218
224
|
*/
|
|
219
225
|
capabilityComparison: {
|
|
@@ -527,6 +533,9 @@ export default {
|
|
|
527
533
|
|
|
528
534
|
mounted() {
|
|
529
535
|
this.publishHoistedSidebar()
|
|
536
|
+
if (this.capabilityComparison) {
|
|
537
|
+
warnCapabilityComparisonDeprecated('CnFeaturesAndRoadmapView `capabilityComparison`')
|
|
538
|
+
}
|
|
530
539
|
},
|
|
531
540
|
|
|
532
541
|
beforeUnmount() {
|
|
@@ -250,6 +250,17 @@
|
|
|
250
250
|
<!-- @binding {object} option The option being rendered (`{ id, label }`). -->
|
|
251
251
|
<slot :name="'field-' + field.key + '-option'" v-bind="optionProps" />
|
|
252
252
|
</template>
|
|
253
|
+
<!-- NcSelect's own option splits a label in two spans
|
|
254
|
+
(NcEllipsisedOption, keeping its last characters
|
|
255
|
+
visible), and in a narrow dropdown the halves broke
|
|
256
|
+
onto two lines mid-word: "Agricu lture". A plain
|
|
257
|
+
label wraps at spaces only. NcSelectUsers keeps its
|
|
258
|
+
avatar rendering. -->
|
|
259
|
+
<template
|
|
260
|
+
v-else-if="!isUserField(field)"
|
|
261
|
+
#option="optionProps">
|
|
262
|
+
<span class="cn-form-dialog__option">{{ optionText(optionProps) }}</span>
|
|
263
|
+
</template>
|
|
253
264
|
<template
|
|
254
265
|
v-if="$slots['field-' + field.key + '-selected-option']"
|
|
255
266
|
#selected-option="optionProps">
|
|
@@ -284,11 +295,17 @@
|
|
|
284
295
|
#option="optionProps">
|
|
285
296
|
<slot :name="'field-' + field.key + '-option'" v-bind="optionProps" />
|
|
286
297
|
</template>
|
|
298
|
+
<template v-else #option="optionProps">
|
|
299
|
+
<span class="cn-form-dialog__option">{{ optionText(optionProps) }}</span>
|
|
300
|
+
</template>
|
|
287
301
|
<template
|
|
288
302
|
v-if="$slots['field-' + field.key + '-selected-option']"
|
|
289
303
|
#selected-option="optionProps">
|
|
290
304
|
<slot :name="'field-' + field.key + '-selected-option'" v-bind="optionProps" />
|
|
291
305
|
</template>
|
|
306
|
+
<template v-else #selected-option="optionProps">
|
|
307
|
+
<span class="cn-form-dialog__option">{{ optionText(optionProps) }}</span>
|
|
308
|
+
</template>
|
|
292
309
|
</NcSelect>
|
|
293
310
|
<CnFieldHelper
|
|
294
311
|
:text="field.description"
|
|
@@ -318,11 +335,17 @@
|
|
|
318
335
|
#option="optionProps">
|
|
319
336
|
<slot :name="'field-' + field.key + '-option'" v-bind="optionProps" />
|
|
320
337
|
</template>
|
|
338
|
+
<template v-else #option="optionProps">
|
|
339
|
+
<span class="cn-form-dialog__option">{{ optionText(optionProps) }}</span>
|
|
340
|
+
</template>
|
|
321
341
|
<template
|
|
322
342
|
v-if="$slots['field-' + field.key + '-selected-option']"
|
|
323
343
|
#selected-option="optionProps">
|
|
324
344
|
<slot :name="'field-' + field.key + '-selected-option'" v-bind="optionProps" />
|
|
325
345
|
</template>
|
|
346
|
+
<template v-else #selected-option="optionProps">
|
|
347
|
+
<span class="cn-form-dialog__option">{{ optionText(optionProps) }}</span>
|
|
348
|
+
</template>
|
|
326
349
|
</NcSelect>
|
|
327
350
|
<CnFieldHelper
|
|
328
351
|
:text="field.description"
|
|
@@ -2452,6 +2475,26 @@ export default {
|
|
|
2452
2475
|
* @param {object} field The field definition
|
|
2453
2476
|
* @return {boolean}
|
|
2454
2477
|
*/
|
|
2478
|
+
/**
|
|
2479
|
+
* The text a select option shows: its label, else a display name, a
|
|
2480
|
+
* name or the id. A plain string option (a tag) is its own text.
|
|
2481
|
+
*
|
|
2482
|
+
* @spec openspec/changes/audit-round-lib-fixes/specs/schema-utilities/spec.md
|
|
2483
|
+
* @param {object|string} option The option (slot props).
|
|
2484
|
+
* @return {string} The text.
|
|
2485
|
+
*/
|
|
2486
|
+
optionText(option) {
|
|
2487
|
+
if (option === null || option === undefined) {
|
|
2488
|
+
return ''
|
|
2489
|
+
}
|
|
2490
|
+
if (typeof option !== 'object') {
|
|
2491
|
+
return String(option)
|
|
2492
|
+
}
|
|
2493
|
+
const text = [option.label, option.displayName, option.name, option.id]
|
|
2494
|
+
.find((v) => v !== undefined && v !== null && v !== '')
|
|
2495
|
+
return text === undefined ? '' : String(text)
|
|
2496
|
+
},
|
|
2497
|
+
|
|
2455
2498
|
isUserField(field) {
|
|
2456
2499
|
return !!(field && field.userPicker && !field.userPicker.multiple)
|
|
2457
2500
|
},
|
|
@@ -3519,8 +3562,15 @@ export default {
|
|
|
3519
3562
|
if (this.isIdPickerField(field)) {
|
|
3520
3563
|
// Reference / user fields store the chosen id (UUID / UID),
|
|
3521
3564
|
// not the full option. Cache its label so the selection displays.
|
|
3565
|
+
// A user option can carry only `displayName` (NcSelectUsers' own
|
|
3566
|
+
// shape), and without that fallback the chip showed the uid.
|
|
3522
3567
|
if (option && option.id) {
|
|
3523
|
-
|
|
3568
|
+
const name = option.label || option.displayName || this.referenceLabels[option.id]
|
|
3569
|
+
if (name) {
|
|
3570
|
+
this.referenceLabels = { ...this.referenceLabels, [option.id]: name }
|
|
3571
|
+
} else if (this.isUserField(field)) {
|
|
3572
|
+
this.resolveUserLabel(option.id)
|
|
3573
|
+
}
|
|
3524
3574
|
}
|
|
3525
3575
|
this.updateField(field.key, option ? option.id : null)
|
|
3526
3576
|
// Reference options are label-only ({id,label}) — pass the id so
|
|
@@ -3587,7 +3637,7 @@ export default {
|
|
|
3587
3637
|
const labels = {}
|
|
3588
3638
|
for (const o of list) {
|
|
3589
3639
|
if (o && o.id) {
|
|
3590
|
-
labels[o.id] = o.label || String(o.id)
|
|
3640
|
+
labels[o.id] = o.label || o.displayName || this.referenceLabels[o.id] || String(o.id)
|
|
3591
3641
|
}
|
|
3592
3642
|
}
|
|
3593
3643
|
if (Object.keys(labels).length > 0) {
|
|
@@ -3861,6 +3911,16 @@ export default {
|
|
|
3861
3911
|
</script>
|
|
3862
3912
|
|
|
3863
3913
|
<style scoped>
|
|
3914
|
+
/* A select option breaks between words only, never inside one. */
|
|
3915
|
+
.cn-form-dialog__option {
|
|
3916
|
+
display: block;
|
|
3917
|
+
min-width: 0;
|
|
3918
|
+
white-space: normal;
|
|
3919
|
+
overflow-wrap: normal;
|
|
3920
|
+
word-break: normal;
|
|
3921
|
+
hyphens: manual;
|
|
3922
|
+
}
|
|
3923
|
+
|
|
3864
3924
|
.cn-form-dialog__draft-actions {
|
|
3865
3925
|
display: flex;
|
|
3866
3926
|
gap: 8px;
|
|
@@ -4,12 +4,25 @@
|
|
|
4
4
|
-->
|
|
5
5
|
|
|
6
6
|
<template>
|
|
7
|
-
<div class="cn-header-widget" :class="{ 'cn-header-widget--plain': isPlain, 'cn-header-widget--ground': isGround, 'cn-header-widget--with-views': viewOptions.length > 0 }" :style="wrapperStyle">
|
|
7
|
+
<div class="cn-header-widget" :class="{ 'cn-header-widget--plain': isPlain, 'cn-header-widget--ground': isGround, 'cn-header-widget--with-views': viewOptions.length > 0, 'cn-header-widget--with-emblem': emblem !== null }" :style="wrapperStyle">
|
|
8
8
|
<div
|
|
9
9
|
v-if="hasOverlay"
|
|
10
10
|
class="cn-header-widget__overlay"
|
|
11
11
|
:style="overlayStyle"
|
|
12
12
|
aria-hidden="true" />
|
|
13
|
+
<!-- The emblem beside the greeting (`content.emblem`): a URL, or
|
|
14
|
+
`true` for the theme's emblem (--nldesign-emblem-url). Decoration. -->
|
|
15
|
+
<img
|
|
16
|
+
v-if="emblem && emblem !== true"
|
|
17
|
+
class="cn-header-widget__emblem"
|
|
18
|
+
:src="emblem"
|
|
19
|
+
alt=""
|
|
20
|
+
data-testid="cn-header-widget-emblem">
|
|
21
|
+
<span
|
|
22
|
+
v-else-if="emblem === true"
|
|
23
|
+
class="cn-header-widget__emblem cn-header-widget__emblem--theme"
|
|
24
|
+
aria-hidden="true"
|
|
25
|
+
data-testid="cn-header-widget-emblem" />
|
|
13
26
|
<div class="cn-header-widget__content" :style="contentStyle">
|
|
14
27
|
<p
|
|
15
28
|
v-if="dateLine"
|
|
@@ -140,7 +153,7 @@ export default {
|
|
|
140
153
|
* Persisted widget content: `{title, subtitle, backgroundImageUrl,
|
|
141
154
|
* backgroundImageFileId, backgroundColor, overlayMode, overlayColor,
|
|
142
155
|
* overlayOpacity, textColor, textAlign, verticalAlign, height, cta,
|
|
143
|
-
* greeting, showDate, plain, ground, views}`. All fields are optional except
|
|
156
|
+
* greeting, showDate, kicker, emblem, plain, ground, views}`. All fields are optional except
|
|
144
157
|
* `title` (or `greeting`); unknown enum values collapse to documented
|
|
145
158
|
* defaults and the renderer never throws. `views` is
|
|
146
159
|
* `{ ariaLabel?, options: [{ label, route, params? } | { label, view }] }`:
|
|
@@ -151,7 +164,12 @@ export default {
|
|
|
151
164
|
* own. `ground: true`
|
|
152
165
|
* draws the greeting on the page ground: the plain look with no
|
|
153
166
|
* padding, a 32px heading and the date line 6px above it (a dashboard
|
|
154
|
-
* also drops the widget's card for it).
|
|
167
|
+
* also drops the widget's card for it). A ground greeting takes its
|
|
168
|
+
* own height rather than its grid cell's, so a view switch sits on
|
|
169
|
+
* the heading's line. `kicker` (an i18n key) prefixes the date line, as
|
|
170
|
+
* "Customer contact · Tuesday 6 October". `emblem` (a URL, or `true`
|
|
171
|
+
* for the theme's `--nldesign-emblem-url`) draws the emblem beside the
|
|
172
|
+
* date line and heading, 52px high (`--cn-header-emblem-size`).
|
|
155
173
|
*
|
|
156
174
|
* @type {object}
|
|
157
175
|
*/
|
|
@@ -396,13 +414,30 @@ export default {
|
|
|
396
414
|
},
|
|
397
415
|
|
|
398
416
|
/**
|
|
399
|
-
*
|
|
400
|
-
*
|
|
417
|
+
* The kicker line above the heading: `content.kicker` (through the
|
|
418
|
+
* host translate function, e.g. "Customer contact") and today's date
|
|
419
|
+
* written out ("Monday 5 October 2026") when `showDate` is on, joined
|
|
420
|
+
* by " · ". '' when neither is set. Without `kicker` this is the date
|
|
421
|
+
* line as before.
|
|
401
422
|
*
|
|
402
423
|
* @return {string}
|
|
403
424
|
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-greeting-header
|
|
404
425
|
*/
|
|
405
426
|
dateLine() {
|
|
427
|
+
const kicker = this.content && typeof this.content.kicker === 'string' && this.content.kicker !== ''
|
|
428
|
+
? this.effectiveTranslate(this.content.kicker)
|
|
429
|
+
: ''
|
|
430
|
+
const date = this.dateText
|
|
431
|
+
return [kicker, date].filter((part) => part !== '').join(' · ')
|
|
432
|
+
},
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* Today's date written out, or '' when `showDate` is off.
|
|
436
|
+
*
|
|
437
|
+
* @spec openspec/changes/zuiddrecht-pixel-gaps-3/specs/zuiddrecht-pixel-gaps-3/spec.md#requirement-a-greeting-kicker-can-carry-a-prefix
|
|
438
|
+
* @return {string}
|
|
439
|
+
*/
|
|
440
|
+
dateText() {
|
|
406
441
|
if (!this.content || this.content.showDate !== true) {
|
|
407
442
|
return ''
|
|
408
443
|
}
|
|
@@ -434,6 +469,21 @@ export default {
|
|
|
434
469
|
}
|
|
435
470
|
},
|
|
436
471
|
|
|
472
|
+
/**
|
|
473
|
+
* The emblem beside the greeting: the URL `content.emblem` names,
|
|
474
|
+
* `true` for the theme's emblem, or null without the key.
|
|
475
|
+
*
|
|
476
|
+
* @spec openspec/changes/zuiddrecht-pixel-gaps-3/specs/zuiddrecht-pixel-gaps-3/spec.md#requirement-a-greeting-can-carry-the-emblem
|
|
477
|
+
* @return {string|true|null}
|
|
478
|
+
*/
|
|
479
|
+
emblem() {
|
|
480
|
+
const value = this.content && this.content.emblem
|
|
481
|
+
if (value === true) {
|
|
482
|
+
return true
|
|
483
|
+
}
|
|
484
|
+
return typeof value === 'string' && value !== '' ? resolveImageUrl(value) : null
|
|
485
|
+
},
|
|
486
|
+
|
|
437
487
|
/** Whether a non-empty subtitle is set. */
|
|
438
488
|
hasSubtitle() {
|
|
439
489
|
return this.subtitle !== ''
|
|
@@ -574,7 +624,12 @@ export default {
|
|
|
574
624
|
return this.isLightColor(this.backgroundColor) ? '#000000' : '#ffffff'
|
|
575
625
|
},
|
|
576
626
|
|
|
577
|
-
/**
|
|
627
|
+
/**
|
|
628
|
+
* Inline style for the banner wrapper.
|
|
629
|
+
*
|
|
630
|
+
* @spec openspec/changes/zuiddrecht-pixel-gaps-3/specs/zuiddrecht-pixel-gaps-3/spec.md#requirement-a-ground-greeting-lines-its-switch-up-with-the-heading
|
|
631
|
+
* @return {object}
|
|
632
|
+
*/
|
|
578
633
|
wrapperStyle() {
|
|
579
634
|
const style = {
|
|
580
635
|
position: 'relative',
|
|
@@ -583,7 +638,11 @@ export default {
|
|
|
583
638
|
// widget. A fixed pixel height ignored the cell, which made the
|
|
584
639
|
// banner un-resizable and made it overflow/scroll inside a
|
|
585
640
|
// smaller cell. The grid controls the size now.
|
|
586
|
-
|
|
641
|
+
// On the page ground there is no banner to fill the cell with:
|
|
642
|
+
// the greeting takes its own height, so the view switch lines
|
|
643
|
+
// up with the heading instead of the bottom of a taller cell,
|
|
644
|
+
// and a size-to-content cell can shrink to it.
|
|
645
|
+
height: this.isGround ? 'auto' : '100%',
|
|
587
646
|
overflow: 'hidden',
|
|
588
647
|
'background-color': this.backgroundColor,
|
|
589
648
|
}
|
|
@@ -619,6 +678,7 @@ export default {
|
|
|
619
678
|
* Inline style for the content flex container.
|
|
620
679
|
*
|
|
621
680
|
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-greeting-header
|
|
681
|
+
* @spec openspec/changes/zuiddrecht-pixel-gaps-3/specs/zuiddrecht-pixel-gaps-3/spec.md#requirement-a-ground-greeting-lines-its-switch-up-with-the-heading
|
|
622
682
|
*/
|
|
623
683
|
contentStyle() {
|
|
624
684
|
return {
|
|
@@ -627,7 +687,7 @@ export default {
|
|
|
627
687
|
// Beside a view switch the content shares the row instead of
|
|
628
688
|
// taking the whole width (see .cn-header-widget--with-views).
|
|
629
689
|
width: this.viewOptions.length > 0 ? 'auto' : '100%',
|
|
630
|
-
height: '100%',
|
|
690
|
+
height: this.isGround ? 'auto' : '100%',
|
|
631
691
|
display: 'flex',
|
|
632
692
|
'flex-direction': 'column',
|
|
633
693
|
'align-items': this.flexAlignFromTextAlign,
|
|
@@ -834,6 +894,33 @@ export default {
|
|
|
834
894
|
width: auto;
|
|
835
895
|
}
|
|
836
896
|
|
|
897
|
+
/* The emblem beside the greeting (`content.emblem`): on one row with the
|
|
898
|
+
date line and heading, centred on them, as LpStart draws it. */
|
|
899
|
+
.cn-header-widget--with-emblem {
|
|
900
|
+
display: flex;
|
|
901
|
+
column-gap: var(--cn-header-emblem-gap, 16px);
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
.cn-header-widget--with-emblem .cn-header-widget__content {
|
|
905
|
+
flex: 1 1 auto;
|
|
906
|
+
width: auto;
|
|
907
|
+
min-width: 0;
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
.cn-header-widget__emblem {
|
|
911
|
+
position: relative;
|
|
912
|
+
z-index: 1;
|
|
913
|
+
flex: none;
|
|
914
|
+
align-self: center;
|
|
915
|
+
height: var(--cn-header-emblem-size, 52px);
|
|
916
|
+
width: auto;
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
.cn-header-widget__emblem--theme {
|
|
920
|
+
width: var(--cn-header-emblem-size, 52px);
|
|
921
|
+
background: var(--nldesign-emblem-url) center / contain no-repeat;
|
|
922
|
+
}
|
|
923
|
+
|
|
837
924
|
.cn-header-widget__views {
|
|
838
925
|
position: relative;
|
|
839
926
|
z-index: 1;
|