@conduction/nextcloud-vue 2.84.0 → 2.85.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/CnAdminSettingsShell/CnAdminSettingsShell.vue.js +1 -1
- package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue2.js +131 -3
- package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue2.js.map +1 -1
- package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js +54 -18
- package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js.map +1 -1
- package/dist/esm/components/CnBoardView/CnBoardView.vue.js +1 -1
- package/dist/esm/components/CnBoardView/CnBoardView.vue2.js +232 -4
- package/dist/esm/components/CnBoardView/CnBoardView.vue2.js.map +1 -1
- package/dist/esm/components/CnBoardView/CnBoardView.vue3.js +95 -51
- package/dist/esm/components/CnBoardView/CnBoardView.vue3.js.map +1 -1
- package/dist/esm/components/CnDashboardGrid/CnDashboardGrid.vue.js +1 -1
- package/dist/esm/components/CnDashboardGrid/CnDashboardGrid.vue2.js +114 -0
- package/dist/esm/components/CnDashboardGrid/CnDashboardGrid.vue2.js.map +1 -1
- package/dist/esm/components/CnDashboardGrid/CnDashboardGrid.vue3.js +2 -2
- package/dist/esm/components/CnDashboardGrid/CnDashboardGrid.vue3.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue.js +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +45 -0
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +22 -12
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +23 -4
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue.js +1 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js +3 -1
- 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 +18 -5
- 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/CnIndexPage/CnIndexPage.vue2.js +548 -77
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +191 -82
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/useSelfFetchList.js +11 -2
- package/dist/esm/components/CnIndexPage/useSelfFetchList.js.map +1 -1
- package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue.js +1 -1
- package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue2.js +95 -0
- package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue3.js +24 -2
- package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js +1 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js +70 -2
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnRegisterMapping/CnRegisterMapping.vue.js +1 -1
- package/dist/esm/components/CnRegisterMapping/CnRegisterMapping.vue2.js +67 -5
- package/dist/esm/components/CnRegisterMapping/CnRegisterMapping.vue2.js.map +1 -1
- package/dist/esm/components/CnRegisterMapping/CnRegisterMapping.vue3.js +181 -124
- package/dist/esm/components/CnRegisterMapping/CnRegisterMapping.vue3.js.map +1 -1
- package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue.js +1 -1
- package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue2.js +5 -1
- package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue2.js.map +1 -1
- package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue3.js.map +1 -1
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue.js +1 -1
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue2.js +134 -10
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js +6 -2
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue.js +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +6 -3
- 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/CnToggleTableWidget/CnToggleTableWidget.vue.js +1 -1
- package/dist/esm/components/CnToggleTableWidget/CnToggleTableWidget.vue2.js +140 -7
- package/dist/esm/components/CnToggleTableWidget/CnToggleTableWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnToggleTableWidget/CnToggleTableWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue.js +1 -1
- package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue2.js +37 -9
- package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue2.js.map +1 -1
- package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue3.js +6 -5
- package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue3.js.map +1 -1
- package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue.js +1 -1
- package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue2.js +2 -1
- package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnWidgetCardGrid/CnWidgetCardGrid.vue2.js +53 -1
- package/dist/esm/components/CnWidgetCardGrid/CnWidgetCardGrid.vue2.js.map +1 -1
- package/dist/esm/components/CnWidgetCardGrid/CnWidgetCardGrid.vue3.js +3 -2
- package/dist/esm/components/CnWidgetCardGrid/CnWidgetCardGrid.vue3.js.map +1 -1
- package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue.js +1 -1
- package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue2.js +135 -0
- 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/CnWidgetWrapper/CnWidgetWrapper.vue.js +1 -1
- package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue2.js +19 -0
- package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue2.js.map +1 -1
- package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue3.js +37 -19
- package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue3.js.map +1 -1
- package/dist/esm/composables/useListView.js +21 -0
- package/dist/esm/composables/useListView.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 +23 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +41 -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 +742 -397
- package/dist/esm/store/useObjectStore.js +16 -2
- package/dist/esm/store/useObjectStore.js.map +1 -1
- package/dist/esm/utils/boardColumns.js +8 -1
- package/dist/esm/utils/boardColumns.js.map +1 -1
- package/dist/esm/utils/boardReferenceColumns.js +278 -0
- package/dist/esm/utils/boardReferenceColumns.js.map +1 -0
- package/dist/esm/utils/buildManifest.js +4 -1
- package/dist/esm/utils/buildManifest.js.map +1 -1
- package/dist/esm/utils/gridStack.js +40 -1
- package/dist/esm/utils/gridStack.js.map +1 -1
- package/dist/esm/utils/humaniseKey.js +41 -0
- package/dist/esm/utils/humaniseKey.js.map +1 -0
- package/dist/esm/utils/notificationRuleLabel.js +6 -23
- package/dist/esm/utils/notificationRuleLabel.js.map +1 -1
- package/dist/esm/utils/validateManifestV2.compiled.js +3 -3
- package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
- package/dist/esm/utils/widgetDispatch.js +8 -2
- package/dist/esm/utils/widgetDispatch.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +15075 -12590
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +742 -397
- package/l10n/en.json +23 -1
- package/l10n/nl.json +41 -1
- package/package.json +1 -1
- package/src/components/CnAdminSettingsShell/CnAdminSettingsShell.vue +160 -8
- package/src/components/CnBoardView/CnBoardView.vue +262 -6
- package/src/components/CnDashboardGrid/CnDashboardGrid.vue +116 -2
- package/src/components/CnDashboardPage/CnDashboardPage.vue +57 -2
- package/src/components/CnDetailPage/CnDetailPage.md +1 -1
- package/src/components/CnDetailPage/CnDetailPage.vue +23 -4
- package/src/components/CnDetailWidgetHost/CnDetailWidgetHost.vue +3 -1
- package/src/components/CnFactsWidget/CnFactsWidget.vue +18 -5
- package/src/components/CnIndexPage/CnIndexPage.vue +586 -25
- package/src/components/CnIndexPage/useSelfFetchList.js +10 -1
- package/src/components/CnObjectDataWidget/CnObjectDataWidget.vue +123 -3
- package/src/components/CnRecordListWidget/CnRecordListWidget.vue +70 -2
- package/src/components/CnRegisterMapping/CnRegisterMapping.md +5 -0
- package/src/components/CnRegisterMapping/CnRegisterMapping.vue +231 -96
- package/src/components/CnSettingsPage/CnSettingsPage.vue +5 -1
- package/src/components/CnStatWidget/CnStatWidget.vue +136 -11
- package/src/components/CnTabsWidget/CnTabsWidget.vue +6 -3
- package/src/components/CnToggleTableWidget/CnToggleTableWidget.vue +140 -7
- package/src/components/CnVersionInfoCard/CnVersionInfoCard.md +2 -1
- package/src/components/CnVersionInfoCard/CnVersionInfoCard.vue +42 -13
- package/src/components/CnWeekStripWidget/CnWeekStripWidget.vue +2 -1
- package/src/components/CnWidgetCardGrid/CnWidgetCardGrid.vue +55 -2
- package/src/components/CnWidgetObjectTable/CnWidgetObjectTable.vue +135 -0
- package/src/components/CnWidgetWrapper/CnWidgetWrapper.md +10 -0
- package/src/components/CnWidgetWrapper/CnWidgetWrapper.vue +44 -1
- package/src/composables/useListView.js +21 -0
- package/src/css/board.css +65 -4
- package/src/css/dialog.css +4 -2
- package/src/css/index-page.css +49 -0
- package/src/css/kpi-card.css +13 -0
- package/src/css/look-board.css +96 -7
- package/src/index.js +2 -0
- package/src/schemas/app-manifest-v2.schema.json +115 -5
- package/src/store/useObjectStore.js +16 -2
- package/src/utils/boardColumns.js +8 -1
- package/src/utils/boardReferenceColumns.js +274 -0
- package/src/utils/buildManifest.js +4 -1
- package/src/utils/gridStack.js +39 -0
- package/src/utils/humaniseKey.js +38 -0
- package/src/utils/notificationRuleLabel.js +5 -23
- package/src/utils/validateManifestV2.compiled.js +3 -3
- package/src/utils/widgetDispatch.js +8 -2
|
@@ -395,6 +395,7 @@
|
|
|
395
395
|
<CnStatsBlockWidget
|
|
396
396
|
v-bind="getStatsBlockProps(item)"
|
|
397
397
|
:title="getWidgetTitle(item)"
|
|
398
|
+
:eyebrow="getWidgetEyebrow(item)"
|
|
398
399
|
:data-source="getWidgetDataSource(item)" />
|
|
399
400
|
</CnWidgetWrapper>
|
|
400
401
|
<CnWidgetWrapper
|
|
@@ -420,7 +421,7 @@
|
|
|
420
421
|
:is="registryRenderer(item)"
|
|
421
422
|
:widgetId="item.widgetId"
|
|
422
423
|
:content="registryWidgetBindings(item)"
|
|
423
|
-
v-bind="registryWidgetBindings(item)"
|
|
424
|
+
v-bind="{ ...registryWidgetBindings(item), ...containerBindings(item) }"
|
|
424
425
|
@header="onWidgetHeader(item, $event)" />
|
|
425
426
|
</CnWidgetWrapper>
|
|
426
427
|
<CnWidgetWrapper
|
|
@@ -433,6 +434,7 @@
|
|
|
433
434
|
<CnWidgetWrapper
|
|
434
435
|
v-else
|
|
435
436
|
:title="getWidgetTitle(item)"
|
|
437
|
+
:eyebrow="getWidgetEyebrow(item)"
|
|
436
438
|
:showTitle="false"
|
|
437
439
|
:showRefresh="false">
|
|
438
440
|
<div class="cn-dashboard-page__unknown">
|
|
@@ -494,6 +496,7 @@
|
|
|
494
496
|
<CnWidgetWrapper
|
|
495
497
|
v-if="missingRequiredApp(item)"
|
|
496
498
|
:title="getWidgetTitle(item)"
|
|
499
|
+
:eyebrow="getWidgetEyebrow(item)"
|
|
497
500
|
:showTitle="widgetShowTitle(item)">
|
|
498
501
|
<!-- Compact on purpose: a two-row tile is about 150px, less
|
|
499
502
|
a title row. NcEmptyContent's 64px icon, 20px name,
|
|
@@ -532,6 +535,7 @@
|
|
|
532
535
|
<CnWidgetWrapper
|
|
533
536
|
:widgetId="item.widgetId"
|
|
534
537
|
:title="getWidgetTitle(item)"
|
|
538
|
+
:eyebrow="getWidgetEyebrow(item)"
|
|
535
539
|
:iconUrl="getWidgetIconUrl(item)"
|
|
536
540
|
:iconClass="getWidgetIconClass(item)"
|
|
537
541
|
:showTitle="widgetShowTitle(item)"
|
|
@@ -613,6 +617,7 @@
|
|
|
613
617
|
:widgetId="item.widgetId"
|
|
614
618
|
:class="{ 'cn-dashboard-page__chart-fit': isChartFitted(item) }"
|
|
615
619
|
:title="getWidgetTitle(item)"
|
|
620
|
+
:eyebrow="getWidgetEyebrow(item)"
|
|
616
621
|
:iconUrl="getWidgetIconUrl(item)"
|
|
617
622
|
:iconClass="getWidgetIconClass(item)"
|
|
618
623
|
:showTitle="widgetShowTitle(item)"
|
|
@@ -691,6 +696,7 @@
|
|
|
691
696
|
<CnWidgetWrapper
|
|
692
697
|
:widgetId="item.widgetId"
|
|
693
698
|
:title="getWidgetTitle(item)"
|
|
699
|
+
:eyebrow="getWidgetEyebrow(item)"
|
|
694
700
|
:iconUrl="getWidgetIconUrl(item)"
|
|
695
701
|
:iconClass="getWidgetIconClass(item)"
|
|
696
702
|
:showTitle="widgetShowTitle(item)"
|
|
@@ -718,6 +724,7 @@
|
|
|
718
724
|
<CnWidgetWrapper
|
|
719
725
|
:widgetId="item.widgetId"
|
|
720
726
|
:title="getWidgetTitle(item)"
|
|
727
|
+
:eyebrow="getWidgetEyebrow(item)"
|
|
721
728
|
:iconUrl="getWidgetIconUrl(item)"
|
|
722
729
|
:iconClass="getWidgetIconClass(item)"
|
|
723
730
|
:showTitle="widgetShowTitle(item)"
|
|
@@ -757,6 +764,7 @@
|
|
|
757
764
|
<CnWidgetWrapper
|
|
758
765
|
:widgetId="item.widgetId"
|
|
759
766
|
:title="getWidgetTitle(item)"
|
|
767
|
+
:eyebrow="getWidgetEyebrow(item)"
|
|
760
768
|
:iconUrl="getWidgetIconUrl(item)"
|
|
761
769
|
:iconClass="getWidgetIconClass(item)"
|
|
762
770
|
:showTitle="widgetShowTitle(item)"
|
|
@@ -782,6 +790,7 @@
|
|
|
782
790
|
<CnWidgetWrapper
|
|
783
791
|
:widgetId="item.widgetId"
|
|
784
792
|
:title="getWidgetTitle(item)"
|
|
793
|
+
:eyebrow="getWidgetEyebrow(item)"
|
|
785
794
|
:showTitle="widgetShowTitle(item)"
|
|
786
795
|
:showActions="widgetShowActions(item)"
|
|
787
796
|
:showRefresh="getWidgetShowRefresh(item)"
|
|
@@ -873,7 +882,7 @@
|
|
|
873
882
|
:is="registryRenderer(item)"
|
|
874
883
|
:widgetId="item.widgetId"
|
|
875
884
|
:content="registryWidgetBindings(item)"
|
|
876
|
-
v-bind="registryWidgetBindings(item)"
|
|
885
|
+
v-bind="{ ...registryWidgetBindings(item), ...containerBindings(item) }"
|
|
877
886
|
@header="onWidgetHeader(item, $event)" />
|
|
878
887
|
</CnWidgetWrapper>
|
|
879
888
|
</template>
|
|
@@ -882,6 +891,7 @@
|
|
|
882
891
|
<CnWidgetWrapper
|
|
883
892
|
v-else
|
|
884
893
|
:title="getWidgetTitle(item)"
|
|
894
|
+
:eyebrow="getWidgetEyebrow(item)"
|
|
885
895
|
:showTitle="widgetShowTitle(item)"
|
|
886
896
|
:showRefresh="false">
|
|
887
897
|
<div class="cn-dashboard-page__unknown">
|
|
@@ -2944,6 +2954,7 @@ export default {
|
|
|
2944
2954
|
return {
|
|
2945
2955
|
widgetId: item.widgetId,
|
|
2946
2956
|
title: this.getWidgetTitle(item),
|
|
2957
|
+
eyebrow: this.getWidgetEyebrow(item),
|
|
2947
2958
|
showTitle: this.widgetShowTitle(item),
|
|
2948
2959
|
showActions: this.widgetShowActions(item),
|
|
2949
2960
|
showRefresh: this.getWidgetShowRefresh(item),
|
|
@@ -3630,6 +3641,35 @@ export default {
|
|
|
3630
3641
|
return outcome ? { ...content, conditionOutcome: outcome } : content
|
|
3631
3642
|
},
|
|
3632
3643
|
|
|
3644
|
+
/**
|
|
3645
|
+
* What a container widget (registry `container`, such as `tabs`) needs
|
|
3646
|
+
* beside its content: the page's widget definitions, so its tabs find
|
|
3647
|
+
* the widgets they name, and the consumer registry for custom child
|
|
3648
|
+
* types. Empty for every other widget, so a leaf gets no extra
|
|
3649
|
+
* attributes on its root.
|
|
3650
|
+
*
|
|
3651
|
+
* @param {object} item Layout item.
|
|
3652
|
+
* @return {object} The extra bindings.
|
|
3653
|
+
* @spec openspec/changes/dashboard-tabs-children/specs/dashboard-page/spec.md#requirement-a-tabs-widget-on-a-dashboard-renders-the-widgets-its-tabs-name
|
|
3654
|
+
*/
|
|
3655
|
+
containerBindings(item) {
|
|
3656
|
+
const def = this.getWidgetDef(item.widgetId)
|
|
3657
|
+
if (!def || !def.type) {
|
|
3658
|
+
return {}
|
|
3659
|
+
}
|
|
3660
|
+
const entry = getWidgetTypeEntry(def.type) || getWidgetTypeEntry(canonicalWidgetType(def.type))
|
|
3661
|
+
if (!entry || entry.container !== true) {
|
|
3662
|
+
return {}
|
|
3663
|
+
}
|
|
3664
|
+
const own = Array.isArray(this.widgets) ? this.widgets.filter(Boolean) : []
|
|
3665
|
+
const fromView = this.activeView && Array.isArray(this.activeView.widgets) ? this.activeView.widgets.filter(Boolean) : []
|
|
3666
|
+
return {
|
|
3667
|
+
availableWidgets: [...own, ...fromView],
|
|
3668
|
+
cnRegistry: this.cnRegistry || {},
|
|
3669
|
+
surface: this.surface,
|
|
3670
|
+
}
|
|
3671
|
+
},
|
|
3672
|
+
|
|
3633
3673
|
/**
|
|
3634
3674
|
* A widget's content with the board's quiet collection footer: in the
|
|
3635
3675
|
* board look a dashboard that drops the widget Actions menu
|
|
@@ -4002,6 +4042,21 @@ export default {
|
|
|
4002
4042
|
this.showWidgetConfig = false
|
|
4003
4043
|
},
|
|
4004
4044
|
|
|
4045
|
+
/**
|
|
4046
|
+
* The line above a widget's title (`eyebrow` on the widget
|
|
4047
|
+
* definition: "Saldo per week" above "Prognose 13 weken"), through the
|
|
4048
|
+
* host translate, or '' for none.
|
|
4049
|
+
*
|
|
4050
|
+
* @param {object} item Layout item.
|
|
4051
|
+
* @return {string}
|
|
4052
|
+
* @spec openspec/changes/widget-title-eyebrow/specs/dashboard-page/spec.md#requirement-a-widget-card-can-carry-a-line-above-its-title
|
|
4053
|
+
*/
|
|
4054
|
+
getWidgetEyebrow(item) {
|
|
4055
|
+
const def = this.getWidgetDef(item.widgetId)
|
|
4056
|
+
const eyebrow = def && typeof def.eyebrow === 'string' ? def.eyebrow : ''
|
|
4057
|
+
return eyebrow ? this.effectiveTranslate(eyebrow) : ''
|
|
4058
|
+
},
|
|
4059
|
+
|
|
4005
4060
|
/**
|
|
4006
4061
|
* The widget's title as AUTHORED — the untranslated manifest source
|
|
4007
4062
|
* string — resolved by widget id rather than by item, so a descendant
|
|
@@ -460,4 +460,4 @@ When the schema-driven fetch answers 404 the page shows a not-found state whose
|
|
|
460
460
|
|
|
461
461
|
### The board look
|
|
462
462
|
|
|
463
|
-
`look` (String, default `''`): `nextcloud` or `board`; empty takes the app's look. `headerMeta` (String): the meta line on row 2 of the board header, a field template such as `via {channel}` (manifest `config.headerMeta`). `tabsLabel` (String): the accessible name of the tab list (manifest `config.tabsLabel`). `identifierField` (String): the field named in the last line of the History side card (manifest `config.identifierField`). See `docs/components/cn-detail-page.md`.
|
|
463
|
+
`look` (String, default `''`): `nextcloud` or `board`; empty takes the app's look. `headerMeta` (String): the meta line on row 2 of the board header, a field template such as `via {channel}` (manifest `config.headerMeta`). `tabsLabel` (String): the accessible name of the tab list (manifest `config.tabsLabel`). `identifierField` (String): the field named in the last line of the History side card (manifest `config.identifierField`). `titleField` (String): the record field the header names the record by, such as an invoice number (manifest `config.titleField`); an empty value falls back to the display name. See `docs/components/cn-detail-page.md`.
|
|
@@ -2664,6 +2664,19 @@ export default {
|
|
|
2664
2664
|
type: String,
|
|
2665
2665
|
default: '',
|
|
2666
2666
|
},
|
|
2667
|
+
|
|
2668
|
+
/**
|
|
2669
|
+
* The record field the header names the record by (manifest
|
|
2670
|
+
* `config.titleField`, a dotted path such as `number`), as an invoice
|
|
2671
|
+
* page names the invoice number. An empty value falls back to the
|
|
2672
|
+
* display name. Empty (the default) changes nothing.
|
|
2673
|
+
*
|
|
2674
|
+
* @spec openspec/changes/detail-title-field/specs/detail-page/spec.md#requirement-a-detail-page-can-name-the-record-by-a-field
|
|
2675
|
+
*/
|
|
2676
|
+
titleField: {
|
|
2677
|
+
type: String,
|
|
2678
|
+
default: '',
|
|
2679
|
+
},
|
|
2667
2680
|
},
|
|
2668
2681
|
|
|
2669
2682
|
emits: [
|
|
@@ -4102,10 +4115,10 @@ export default {
|
|
|
4102
4115
|
},
|
|
4103
4116
|
|
|
4104
4117
|
/**
|
|
4105
|
-
* The resolved record's human display name
|
|
4106
|
-
*
|
|
4107
|
-
* `@self.name` → `name` / `title` /
|
|
4108
|
-
* lastName`. Empty string while the object is still loading or when no
|
|
4118
|
+
* The resolved record's human display name: the `titleField` value
|
|
4119
|
+
* when the page names one and it is filled, else the same fallback
|
|
4120
|
+
* chain the relation resolver uses: `@self.name` → `name` / `title` /
|
|
4121
|
+
* `displayName` → `firstName lastName`. Empty string while the object is still loading or when no
|
|
4109
4122
|
* name-like field exists (a raw id is never used as a name — ADR-062).
|
|
4110
4123
|
*
|
|
4111
4124
|
* @return {string}
|
|
@@ -4115,6 +4128,12 @@ export default {
|
|
|
4115
4128
|
if (!obj || typeof obj !== 'object') {
|
|
4116
4129
|
return ''
|
|
4117
4130
|
}
|
|
4131
|
+
if (this.titleField) {
|
|
4132
|
+
const named = stageOf(obj, this.titleField)
|
|
4133
|
+
if (named !== '') {
|
|
4134
|
+
return named
|
|
4135
|
+
}
|
|
4136
|
+
}
|
|
4118
4137
|
const self = obj['@self'] || {}
|
|
4119
4138
|
const id = this.objectId !== null && this.objectId !== undefined ? String(this.objectId) : ''
|
|
4120
4139
|
const candidates = [self.name, self.title, obj.name, obj.title, obj.displayName]
|
|
@@ -725,7 +725,9 @@ export default {
|
|
|
725
725
|
if (this.widget && this.widget.type === 'files' && !(this.cnRegistry && this.cnRegistry.files) && this.register && this.schema) {
|
|
726
726
|
return CnObjectFilesWidget
|
|
727
727
|
}
|
|
728
|
-
|
|
728
|
+
// Inside a dashboard's tabs the dashboard's resolution holds.
|
|
729
|
+
const onDashboard = this.surface === 'app-dashboard' || this.surface === 'user-dashboard'
|
|
730
|
+
return resolveRegistryRenderer(this.widget, this.cnRegistry, { typeAsWritten: onDashboard })
|
|
729
731
|
},
|
|
730
732
|
|
|
731
733
|
/**
|
|
@@ -145,6 +145,7 @@ import { dispatchAction } from '../../utils/actionsDispatcher.js'
|
|
|
145
145
|
import { isBadgeVariant } from '../../utils/badgeVariants.js'
|
|
146
146
|
import { formatBoardDate } from '../../utils/boardDate.js'
|
|
147
147
|
import { parseDateValue } from '../../utils/dateVariant.js'
|
|
148
|
+
import { formatMoney, unwrapAppConfig } from '../../utils/formatMetric.js'
|
|
148
149
|
import { readPath } from '../../utils/readPath.js'
|
|
149
150
|
import { hasUnresolvedDeepTokens, resolveDeepTokens } from '../../utils/resolveFilterTokens.js'
|
|
150
151
|
|
|
@@ -246,6 +247,8 @@ export default {
|
|
|
246
247
|
cnTranslate: { default: () => (key) => key },
|
|
247
248
|
cnObjectContext: { default: null },
|
|
248
249
|
cnWorkspaceContext: { default: null },
|
|
250
|
+
/** The page's app config; its `currency` is the reporting currency a money value falls back to. */
|
|
251
|
+
cnAppConfig: { default: null },
|
|
249
252
|
/** Pre-bound action dispatcher of CnPageRenderer, for `action` / `headerAction`. */
|
|
250
253
|
cnDispatchAction: { default: null },
|
|
251
254
|
},
|
|
@@ -260,7 +263,7 @@ export default {
|
|
|
260
263
|
* A part may be `{ text }`, a constant; a `line` or `text` entry without `path` or `parts` shows its `text`.
|
|
261
264
|
* `resolve: { register, schema, labelField? }` on an entry or a part turns a value that is a reference (an id, or a list of ids) into the label of the referenced object (`labelField`, else `title`, then `name`): the case type or status of a task shows its name, not its uuid. The ids are fetched once per register and schema through the object store and shared by every facts widget on the page; the entry stays empty until its label is known, and when no label can be read. A resolved value works as a pill too: `map` is applied to the resolved label, and `variantMap` / `colorMap` look the tone up by the value of `resolve.toneField` on the referenced object when that is set (a status named by its `name`, coloured by its `state`), then by the resolved label, then by the stored value.
|
|
262
265
|
* - `action` — an action drawn as a button under the facts; `headerAction` — one drawn in the card header (reported through the `header` event).
|
|
263
|
-
* `format` is `text` (default), `date` (board short date), `date-long` (always with the year)
|
|
266
|
+
* `format` is `text` (default), `date` (board short date), `date-long` (always with the year), `list` (an array joined by ", ", each item read at `itemPath`) or `currency` (a money amount in the reader's language, "€ 1.234,50": the code in `currency`, else the record's `currencyField`, else the app's reporting currency, else EUR; `decimals` defaults to 2).
|
|
264
267
|
* `map` turns a raw value into a label (translated). `parts` (on a `line`) lists paths, or `{ path, label?, format? }`, joined by `separator` (default " · "); empty parts are dropped.
|
|
265
268
|
* - `source` — `{ register, schema, id }` or `{ url }`; omitted = the current object.
|
|
266
269
|
* - `link` — `{ label, route? | href? }` at the foot.
|
|
@@ -900,7 +903,7 @@ export default {
|
|
|
900
903
|
*/
|
|
901
904
|
valueOf(record, field) {
|
|
902
905
|
const raw = readPath(record, field.path)
|
|
903
|
-
return this.format(raw, field)
|
|
906
|
+
return this.format(raw, field, record)
|
|
904
907
|
},
|
|
905
908
|
|
|
906
909
|
/**
|
|
@@ -919,7 +922,7 @@ export default {
|
|
|
919
922
|
if (!spec.path && typeof spec.text === 'string') {
|
|
920
923
|
return this.tr(spec.text)
|
|
921
924
|
}
|
|
922
|
-
const value = this.format(readPath(record, spec.path), spec)
|
|
925
|
+
const value = this.format(readPath(record, spec.path), spec, record)
|
|
923
926
|
if (value === '') {
|
|
924
927
|
return ''
|
|
925
928
|
}
|
|
@@ -933,10 +936,12 @@ export default {
|
|
|
933
936
|
* Format a raw value.
|
|
934
937
|
*
|
|
935
938
|
* @param {unknown} raw The value.
|
|
936
|
-
* @param {object} spec `{ format?, map?, itemPath? }`.
|
|
939
|
+
* @param {object} spec `{ format?, map?, itemPath?, currency?, currencyField?, decimals? }`.
|
|
940
|
+
* @param {object|null} [record] The object shown, which `currencyField` reads.
|
|
937
941
|
* @return {string} The text, '' when empty.
|
|
942
|
+
* @spec openspec/changes/facts-currency-format/specs/facts-widget/spec.md#requirement-a-facts-entry-can-show-a-money-amount
|
|
938
943
|
*/
|
|
939
|
-
format(raw, spec) {
|
|
944
|
+
format(raw, spec, record = null) {
|
|
940
945
|
if (raw === null || raw === undefined || raw === '') {
|
|
941
946
|
return ''
|
|
942
947
|
}
|
|
@@ -961,6 +966,14 @@ export default {
|
|
|
961
966
|
? formatBoardDate(date, new Date(date.getFullYear() + 1, 0, 1))
|
|
962
967
|
: formatBoardDate(date)
|
|
963
968
|
}
|
|
969
|
+
if (format === 'currency') {
|
|
970
|
+
const money = formatMoney(raw, { currency: spec.currency, currencyField: spec.currencyField, decimals: spec.decimals }, record, unwrapAppConfig(this.cnAppConfig))
|
|
971
|
+
if (money !== '') {
|
|
972
|
+
return money
|
|
973
|
+
}
|
|
974
|
+
// Not a number: shown as written, never as "[object Object]".
|
|
975
|
+
return typeof raw === 'object' ? '' : String(raw)
|
|
976
|
+
}
|
|
964
977
|
if (typeof raw === 'object') {
|
|
965
978
|
const label = raw.title || raw.name || raw.label || raw.displayName
|
|
966
979
|
return typeof label === 'string' ? label : ''
|