@conduction/nextcloud-vue 2.83.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/CnAuditTrailCard/CnAuditTrailCard.vue.js +1 -1
- package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue2.js +1 -1
- package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue2.js.map +1 -1
- package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.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/CnBodySections/CnBodySections.vue.js +1 -1
- package/dist/esm/components/CnBodySections/CnBodySections.vue2.js +22 -1
- package/dist/esm/components/CnBodySections/CnBodySections.vue2.js.map +1 -1
- package/dist/esm/components/CnBodySections/CnBodySections.vue3.js.map +1 -1
- package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue.js +1 -1
- package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue2.js +47 -4
- package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnDashboardGrid/CnDashboardGrid.vue.js +1 -1
- package/dist/esm/components/CnDashboardGrid/CnDashboardGrid.vue2.js +239 -3
- package/dist/esm/components/CnDashboardGrid/CnDashboardGrid.vue2.js.map +1 -1
- package/dist/esm/components/CnDashboardGrid/CnDashboardGrid.vue3.js +5 -5
- 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 +50 -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/CnDeltaWidget/CnDeltaWidget.vue.js +1 -1
- package/dist/esm/components/CnDeltaWidget/CnDeltaWidget.vue2.js +1 -1
- package/dist/esm/components/CnDeltaWidget/CnDeltaWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnDeltaWidget/CnDeltaWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +226 -8
- 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/CnFieldListWidget/CnFieldListWidget.vue.js +1 -1
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue2.js +38 -1
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue3.js +45 -5
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnGaugeWidget/CnGaugeWidget.vue.js +1 -1
- package/dist/esm/components/CnGaugeWidget/CnGaugeWidget.vue2.js +1 -1
- package/dist/esm/components/CnGaugeWidget/CnGaugeWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnGaugeWidget/CnGaugeWidget.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/CnInteractionFormWidget/CnInteractionFormWidget.vue2.js +29 -6
- package/dist/esm/components/CnInteractionFormWidget/CnInteractionFormWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnInteractionFormWidget/CnInteractionFormWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue.js +1 -1
- package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue2.js +126 -2
- 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 +106 -3
- 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/CnReportsPage/CnReportsPage.vue.js +1 -1
- package/dist/esm/components/CnReportsPage/CnReportsPage.vue2.js +135 -2
- package/dist/esm/components/CnReportsPage/CnReportsPage.vue2.js.map +1 -1
- package/dist/esm/components/CnReportsPage/CnReportsPage.vue3.js +95 -43
- package/dist/esm/components/CnReportsPage/CnReportsPage.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/CnStagesWidget/CnStagesWidget.vue.js +1 -1
- package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue2.js +72 -5
- package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue3.js +33 -8
- package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue.js +1 -1
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue2.js +135 -11
- 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/CnStatsBlockWidget/CnStatsBlockWidget.vue.js +1 -1
- package/dist/esm/components/CnStatsBlockWidget/CnStatsBlockWidget.vue2.js +17 -2
- package/dist/esm/components/CnStatsBlockWidget/CnStatsBlockWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnStatsBlockWidget/CnStatsBlockWidget.vue3.js +1 -1
- package/dist/esm/components/CnStatsBlockWidget/CnStatsBlockWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue.js +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +39 -6
- 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/CnWalkthrough/CnWalkthrough.vue.js +1 -1
- package/dist/esm/components/CnWalkthrough/CnWalkthrough.vue2.js +16 -0
- 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.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/dialogs/CnTransitionInputDialog.vue.js +1 -1
- package/dist/esm/dialogs/CnTransitionInputDialog.vue2.js +68 -6
- package/dist/esm/dialogs/CnTransitionInputDialog.vue2.js.map +1 -1
- package/dist/esm/dialogs/CnTransitionInputDialog.vue3.js +133 -105
- package/dist/esm/dialogs/CnTransitionInputDialog.vue3.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 +38 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +78 -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 +1030 -533
- 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 +41 -4
- package/dist/esm/utils/buildManifest.js.map +1 -1
- package/dist/esm/utils/detailWidgetVisibility.js +149 -0
- package/dist/esm/utils/detailWidgetVisibility.js.map +1 -0
- package/dist/esm/utils/formatMetric.js +39 -3
- package/dist/esm/utils/formatMetric.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/resolveManifestTokens.js +1 -0
- package/dist/esm/utils/resolveManifestTokens.js.map +1 -1
- package/dist/esm/utils/sentinelTokens.js +9 -0
- package/dist/esm/utils/sentinelTokens.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 +17159 -13422
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +1030 -533
- package/l10n/en.json +38 -1
- package/l10n/nl.json +78 -1
- package/package.json +1 -1
- package/src/components/CnAdminSettingsShell/CnAdminSettingsShell.vue +160 -8
- package/src/components/CnAuditTrailCard/CnAuditTrailCard.vue +1 -1
- package/src/components/CnBoardView/CnBoardView.vue +262 -6
- package/src/components/CnBodySections/CnBodySections.vue +22 -1
- package/src/components/CnCountdownWidget/CnCountdownWidget.vue +47 -4
- package/src/components/CnDashboardGrid/CnDashboardGrid.vue +244 -8
- package/src/components/CnDashboardPage/CnDashboardPage.vue +62 -2
- package/src/components/CnDeltaWidget/CnDeltaWidget.vue +1 -1
- package/src/components/CnDetailPage/CnDetailPage.md +3 -1
- package/src/components/CnDetailPage/CnDetailPage.vue +226 -8
- package/src/components/CnDetailWidgetHost/CnDetailWidgetHost.vue +3 -1
- package/src/components/CnFactsWidget/CnFactsWidget.vue +18 -5
- package/src/components/CnFieldListWidget/CnFieldListWidget.vue +63 -1
- package/src/components/CnGaugeWidget/CnGaugeWidget.vue +1 -1
- package/src/components/CnIndexPage/CnIndexPage.vue +586 -25
- package/src/components/CnIndexPage/useSelfFetchList.js +10 -1
- package/src/components/CnInteractionFormWidget/CnInteractionFormWidget.vue +29 -6
- package/src/components/CnObjectDataWidget/CnObjectDataWidget.md +1 -1
- package/src/components/CnObjectDataWidget/CnObjectDataWidget.vue +154 -5
- package/src/components/CnRecordListWidget/CnRecordListWidget.vue +106 -3
- package/src/components/CnRegisterMapping/CnRegisterMapping.md +5 -0
- package/src/components/CnRegisterMapping/CnRegisterMapping.vue +231 -96
- package/src/components/CnReportsPage/CnReportsPage.vue +179 -1
- package/src/components/CnSettingsPage/CnSettingsPage.vue +5 -1
- package/src/components/CnStagesWidget/CnStagesWidget.vue +103 -6
- package/src/components/CnStatWidget/CnStatWidget.vue +137 -12
- package/src/components/CnStatsBlockWidget/CnStatsBlockWidget.vue +34 -3
- package/src/components/CnTabsWidget/CnTabsWidget.vue +39 -6
- 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/CnWalkthrough/CnWalkthrough.vue +16 -0
- 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/form-field.css +14 -0
- package/src/css/form-widget.css +11 -0
- package/src/css/index-page.css +49 -0
- package/src/css/kpi-card.css +13 -0
- package/src/css/look-board-reports.css +58 -0
- package/src/css/look-board.css +108 -7
- package/src/dialogs/CnTransitionInputDialog.vue +87 -7
- package/src/index.js +2 -0
- package/src/schemas/app-manifest-v2.schema.json +137 -6
- 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 +40 -3
- package/src/utils/detailWidgetVisibility.js +145 -0
- package/src/utils/formatMetric.js +38 -2
- package/src/utils/gridStack.js +39 -0
- package/src/utils/humaniseKey.js +38 -0
- package/src/utils/notificationRuleLabel.js +5 -23
- package/src/utils/resolveManifestTokens.js +1 -0
- package/src/utils/sentinelTokens.js +9 -0
- package/src/utils/validateManifestV2.compiled.js +3 -3
- package/src/utils/widgetDispatch.js +8 -2
|
@@ -14,7 +14,7 @@ import { resolveObjectOpType } from '../../utils/actionsDispatcher.js';
|
|
|
14
14
|
import { resolveObjectTokenContext } from '../../utils/detailObjectContext.js';
|
|
15
15
|
import { aggFilterParam } from '../../utils/fetchAggregate.js';
|
|
16
16
|
import { needsListEndpoint, fetchListTotal } from '../../utils/fetchFilterCounts.js';
|
|
17
|
-
import { unwrapAppConfig, formatMetricValue } from '../../utils/formatMetric.js';
|
|
17
|
+
import { unwrapAppConfig, formatMetricValue, metricLocale } from '../../utils/formatMetric.js';
|
|
18
18
|
import { dropOptionalUnresolved, resolveFilterTokens } from '../../utils/resolveFilterTokens.js';
|
|
19
19
|
import { STATUS_TEXT_COLORS } from '../../utils/statusColors.js';
|
|
20
20
|
import { readVisibleWhenPath, evaluateVisibleWhenLocal } from '../../utils/visibleWhen.js';
|
|
@@ -63,6 +63,9 @@ const DATE_ONLY = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
|
63
63
|
/** Milliseconds in a day, used only between two UTC-normalised midnights. */
|
|
64
64
|
const DAY_MS = 86400000;
|
|
65
65
|
|
|
66
|
+
/** The smallest size `fitValue` steps a number down to, in px; below it the number wraps. */
|
|
67
|
+
const MIN_FIT_FONT_SIZE = 14;
|
|
68
|
+
|
|
66
69
|
/**
|
|
67
70
|
* The local calendar day a value names, as a UTC midnight timestamp.
|
|
68
71
|
*
|
|
@@ -357,7 +360,7 @@ var script = {
|
|
|
357
360
|
* counted between LOCAL CALENDAR DAYS, not as elapsed milliseconds, so
|
|
358
361
|
* the time of day on a deadline never moves the answer.
|
|
359
362
|
*
|
|
360
|
-
* @type {{label?: string, icon?: string, iconColor?: string, valueColor?: string, caption?: string, route?: (object|string), clickRoute?: (object|string), link?: string, format?: {style?: string, currency?: string, decimals?: number, prefix?: string, suffix?: string}, source?: {kind?: string, register?: string, schema?: string, metric?: string, field?: string, filter?: object, url?: string, path?: string, params?: object}, endpointSource?: {url: string, method?: string, params?: object, responsePath?: string}, valueField?: string, limitField?: string, limit?: number, dateRange?: {presets?: Array<{id: string, label?: string, from?: string, to?: string}>, default?: string}, previousField?: string, deltaField?: string, goodDirection?: ('up'|'down'), variant?: ('default'|'primary'|'success'|'warning'|'error'|'danger'), variantWhen?: Array<{op: string, value: unknown, variant: string, icon?: string}>, objectField?: (string|{field: string, resolve?: {register: string, schema: string, labelField?: string, variantField?: string, variantMap?: {[key: string]: string}}}), display?: ('text'|'badge'|'countdown'), countdown?: {unit?: 'days', warnAt?: number, dangerAt?: number, futureLabel?: string, todayLabel?: string, pastLabel?: string, emptyText?: string}, emptyText?: string, captionVariant?: ('default'|'primary'|'success'|'warning'|'error'|'danger'), captionVariantWhen?: Array<{op: string, value: unknown, variant: string}>, captionSource?: {register?: string, schema?: string, metric?: string, field?: string, filter?: object, via?: string, zeroText?: string}, overrides?: Array<{when: {field: string, op?: string, value?: unknown}, label?: string, variant?: string, icon?: string, caption?: string, captionVariant?: string}>}}
|
|
363
|
+
* @type {{label?: string, icon?: string, iconColor?: string, valueColor?: string, caption?: string, route?: (object|string), clickRoute?: (object|string), link?: string, format?: {style?: string, currency?: string, decimals?: number, prefix?: string, suffix?: string}, source?: {kind?: string, register?: string, schema?: string, metric?: string, field?: string, filter?: object, url?: string, path?: string, params?: object}, endpointSource?: {url: string, method?: string, params?: object, responsePath?: string}, valueField?: string, limitField?: string, limit?: number, dateRange?: {presets?: Array<{id: string, label?: string, from?: string, to?: string}>, default?: string}, previousField?: string, deltaField?: string, goodDirection?: ('up'|'down'), variant?: ('default'|'primary'|'success'|'warning'|'error'|'danger'), variantWhen?: Array<{op: string, value: unknown, variant: string, icon?: string}>, objectField?: (string|{field: string, resolve?: {register: string, schema: string, labelField?: string, variantField?: string, variantMap?: {[key: string]: string}}}), display?: ('text'|'badge'|'countdown'), countdown?: {unit?: 'days', warnAt?: number, dangerAt?: number, futureLabel?: string, todayLabel?: string, pastLabel?: string, emptyText?: string}, emptyText?: string, captionVariant?: ('default'|'primary'|'success'|'warning'|'error'|'danger'), captionVariantWhen?: Array<{op: string, value: unknown, variant: string}>, captionSource?: {kind?: 'ratio', register?: string, schema?: string, metric?: string, field?: string, filter?: object, via?: string, zeroText?: string, numerator?: {metric?: string, field?: string, filter?: object, via?: string}, denominator?: {metric?: string, field?: string, filter?: object, via?: string}, decimals?: number}, overrides?: Array<{when: {field: string, op?: string, value?: unknown}, label?: string, variant?: string, icon?: string, caption?: string, captionVariant?: string}>}}
|
|
361
364
|
*/
|
|
362
365
|
content: {
|
|
363
366
|
type: Object,
|
|
@@ -432,6 +435,9 @@ var script = {
|
|
|
432
435
|
|
|
433
436
|
data() {
|
|
434
437
|
return {
|
|
438
|
+
// The value's font size while the number would not fit its row at
|
|
439
|
+
// its own size; null when it fits.
|
|
440
|
+
fitFontSize: null,
|
|
435
441
|
// Resolved display label for an `objectField` that holds a reference
|
|
436
442
|
// uuid. Null until resolved, and null forever when it cannot be.
|
|
437
443
|
referenceLabel: null,
|
|
@@ -449,6 +455,9 @@ var script = {
|
|
|
449
455
|
value: null,
|
|
450
456
|
// The caption's own count (`content.captionSource`), null until read.
|
|
451
457
|
captionValue: null,
|
|
458
|
+
// The parts of a ratio caption (`captionSource.kind: "ratio"`): the
|
|
459
|
+
// numerator read (null: the tile's own value) and the denominator.
|
|
460
|
+
captionRatioParts: null,
|
|
452
461
|
loading: false,
|
|
453
462
|
error: '',
|
|
454
463
|
}
|
|
@@ -524,8 +533,9 @@ var script = {
|
|
|
524
533
|
// nothing to say while it is not read, and at zero the `zeroText`
|
|
525
534
|
// (or nothing) instead of "0 waiting".
|
|
526
535
|
const counted = this.hasCaptionSource;
|
|
527
|
-
|
|
528
|
-
|
|
536
|
+
const count = this.captionCount;
|
|
537
|
+
if (counted && !(Number(count) > 0)) {
|
|
538
|
+
const zero = count !== null && this.content.captionSource.zeroText;
|
|
529
539
|
return typeof zero === 'string' && zero !== '' ? this.effectiveTranslate(zero) : ''
|
|
530
540
|
}
|
|
531
541
|
const translated = this.effectiveTranslate(caption);
|
|
@@ -534,9 +544,10 @@ var script = {
|
|
|
534
544
|
}
|
|
535
545
|
const payload = this.endpointMode ? this.epData : null;
|
|
536
546
|
return translated.replace(/\{([A-Za-z0-9_.]+)\}/g, (whole, path) => {
|
|
537
|
-
// `{count}` is the caption's own count
|
|
538
|
-
|
|
539
|
-
|
|
547
|
+
// `{count}` is the caption's own count; `{ratio}` the same
|
|
548
|
+
// for a ratio caption, as a percentage.
|
|
549
|
+
if ((path === 'count' || (path === 'ratio' && this.isCaptionRatio)) && counted) {
|
|
550
|
+
return this.isCaptionRatio ? this.formatCaptionRatio(count) : String(count)
|
|
540
551
|
}
|
|
541
552
|
// `{value}` is the tile's own number, so a caption can read
|
|
542
553
|
// "{value} due today" on a register-counted tile that has no
|
|
@@ -549,6 +560,42 @@ var script = {
|
|
|
549
560
|
}).replace(/\s{2,}/g, ' ').trim()
|
|
550
561
|
},
|
|
551
562
|
|
|
563
|
+
/**
|
|
564
|
+
* Whether the caption is a share (`captionSource.kind: "ratio"`).
|
|
565
|
+
*
|
|
566
|
+
* @return {boolean}
|
|
567
|
+
* @spec openspec/changes/stat-caption-ratio/specs/stat-widget/spec.md#requirement-a-stat-tiles-caption-can-show-a-share
|
|
568
|
+
*/
|
|
569
|
+
isCaptionRatio() {
|
|
570
|
+
const own = this.content.captionSource;
|
|
571
|
+
return !!own && typeof own === 'object' && own.kind === 'ratio'
|
|
572
|
+
},
|
|
573
|
+
|
|
574
|
+
/**
|
|
575
|
+
* The caption's own number: its count, or for a ratio caption the
|
|
576
|
+
* numerator (the tile's own value when it names none) over the
|
|
577
|
+
* denominator, times 100. Null while unread, and for a zero or failed
|
|
578
|
+
* denominator.
|
|
579
|
+
*
|
|
580
|
+
* @return {number|null}
|
|
581
|
+
* @spec openspec/changes/stat-caption-ratio/specs/stat-widget/spec.md#requirement-a-stat-tiles-caption-can-show-a-share
|
|
582
|
+
*/
|
|
583
|
+
captionCount() {
|
|
584
|
+
if (!this.isCaptionRatio) {
|
|
585
|
+
return this.captionValue
|
|
586
|
+
}
|
|
587
|
+
const parts = this.captionRatioParts;
|
|
588
|
+
if (!parts) {
|
|
589
|
+
return null
|
|
590
|
+
}
|
|
591
|
+
const num = parts.num === null ? this.displayValue : parts.num;
|
|
592
|
+
const den = Number(parts.den);
|
|
593
|
+
if (num === null || num === undefined || num === '' || !Number.isFinite(Number(num)) || !Number.isFinite(den) || den === 0) {
|
|
594
|
+
return null
|
|
595
|
+
}
|
|
596
|
+
return (Number(num) / den) * 100
|
|
597
|
+
},
|
|
598
|
+
|
|
552
599
|
/**
|
|
553
600
|
* Whether the caption has a count of its own (`content.captionSource`
|
|
554
601
|
* with a register and schema, its own or the tile's).
|
|
@@ -577,7 +624,7 @@ var script = {
|
|
|
577
624
|
return null
|
|
578
625
|
}
|
|
579
626
|
// A caption with its own count is coloured by that count.
|
|
580
|
-
const current = this.hasCaptionSource ? this.
|
|
627
|
+
const current = this.hasCaptionSource ? this.captionCount : this.displayValue;
|
|
581
628
|
if (current === null || current === undefined) {
|
|
582
629
|
return null
|
|
583
630
|
}
|
|
@@ -1287,7 +1334,16 @@ var script = {
|
|
|
1287
1334
|
/** Inline style for the value text (variant rule wins over valueColor). */
|
|
1288
1335
|
valueStyle() {
|
|
1289
1336
|
const color = this.variantColor || this.content.valueColor;
|
|
1290
|
-
|
|
1337
|
+
const style = color ? { color } : {};
|
|
1338
|
+
if (this.fitFontSize !== null) {
|
|
1339
|
+
style.fontSize = `${this.fitFontSize}px`;
|
|
1340
|
+
// At the smallest size a number that still does not fit wraps rather than clips.
|
|
1341
|
+
if (this.fitFontSize <= MIN_FIT_FONT_SIZE) {
|
|
1342
|
+
style.whiteSpace = 'normal';
|
|
1343
|
+
style.overflowWrap = 'anywhere';
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
return style
|
|
1291
1347
|
},
|
|
1292
1348
|
|
|
1293
1349
|
/**
|
|
@@ -1300,7 +1356,7 @@ var script = {
|
|
|
1300
1356
|
* @return {string}
|
|
1301
1357
|
*/
|
|
1302
1358
|
formattedValue() {
|
|
1303
|
-
return formatMetricValue(this.displayValue, this.content.format, this.configCtx, this.objectCtx?.object || null)
|
|
1359
|
+
return formatMetricValue(this.displayValue, this.content.format, this.configCtx, this.objectCtx?.object || null, this.effectiveTranslate)
|
|
1304
1360
|
},
|
|
1305
1361
|
|
|
1306
1362
|
/**
|
|
@@ -1396,6 +1452,10 @@ var script = {
|
|
|
1396
1452
|
this.fetchValue();
|
|
1397
1453
|
},
|
|
1398
1454
|
|
|
1455
|
+
shownValue() {
|
|
1456
|
+
this.$nextTick(() => this.fitValue());
|
|
1457
|
+
},
|
|
1458
|
+
|
|
1399
1459
|
objectFieldRaw: {
|
|
1400
1460
|
immediate: true,
|
|
1401
1461
|
handler() {
|
|
@@ -1416,13 +1476,50 @@ var script = {
|
|
|
1416
1476
|
payload?.waitUntil?.(done);
|
|
1417
1477
|
};
|
|
1418
1478
|
subscribe(PAGE_REFRESH_CHANNEL, this._onPageRefresh);
|
|
1479
|
+
if (typeof ResizeObserver === 'function' && this.$refs.valueRow) {
|
|
1480
|
+
this._fitObserver = new ResizeObserver(() => this.fitValue());
|
|
1481
|
+
this._fitObserver.observe(this.$refs.valueRow);
|
|
1482
|
+
}
|
|
1483
|
+
this.$nextTick(() => this.fitValue());
|
|
1419
1484
|
},
|
|
1420
1485
|
|
|
1421
1486
|
beforeUnmount() {
|
|
1422
1487
|
unsubscribe(PAGE_REFRESH_CHANNEL, this._onPageRefresh);
|
|
1488
|
+
this._fitObserver?.disconnect();
|
|
1423
1489
|
},
|
|
1424
1490
|
|
|
1425
1491
|
methods: {
|
|
1492
|
+
/**
|
|
1493
|
+
* Step the number's font down until it fits its row, instead of the
|
|
1494
|
+
* card clipping it ("€ 1.012.4" in a narrow tile). A value that fits
|
|
1495
|
+
* keeps its own size; text values wrap and clamp on their own.
|
|
1496
|
+
*
|
|
1497
|
+
* @return {void}
|
|
1498
|
+
* @spec openspec/changes/stat-value-fits/specs/stat-tile-board-look/spec.md#requirement-a-stat-value-shrinks-instead-of-clipping
|
|
1499
|
+
*/
|
|
1500
|
+
fitValue() {
|
|
1501
|
+
const row = this.$refs.valueRow;
|
|
1502
|
+
const el = this.$refs.value;
|
|
1503
|
+
if (!row || !el || el.classList.contains('cn-kpi-card__value--text') || typeof getComputedStyle !== 'function') {
|
|
1504
|
+
this.fitFontSize = null;
|
|
1505
|
+
return
|
|
1506
|
+
}
|
|
1507
|
+
const applied = el.style.fontSize;
|
|
1508
|
+
const whiteSpace = el.style.whiteSpace;
|
|
1509
|
+
el.style.fontSize = '';
|
|
1510
|
+
el.style.whiteSpace = '';
|
|
1511
|
+
const natural = parseFloat(getComputedStyle(el).fontSize);
|
|
1512
|
+
const overflow = row.scrollWidth - row.clientWidth;
|
|
1513
|
+
const width = el.offsetWidth;
|
|
1514
|
+
el.style.fontSize = applied;
|
|
1515
|
+
el.style.whiteSpace = whiteSpace;
|
|
1516
|
+
if (!(overflow > 0.5) || !(width > 0) || !(natural > 0)) {
|
|
1517
|
+
this.fitFontSize = null;
|
|
1518
|
+
return
|
|
1519
|
+
}
|
|
1520
|
+
this.fitFontSize = Math.max(MIN_FIT_FONT_SIZE, Math.floor(natural * ((width - overflow) / width) * 10) / 10);
|
|
1521
|
+
},
|
|
1522
|
+
|
|
1426
1523
|
/**
|
|
1427
1524
|
* Resolve an `objectField` that holds a reference uuid to the referenced
|
|
1428
1525
|
* object's label, through the shared object store (per-schema caching and
|
|
@@ -1683,7 +1780,9 @@ var script = {
|
|
|
1683
1780
|
/**
|
|
1684
1781
|
* Read the caption's own count (`content.captionSource`:
|
|
1685
1782
|
* `{ register?, schema?, metric?, field?, filter?, via?, zeroText? }`,
|
|
1686
|
-
* register and schema default to the tile's source).
|
|
1783
|
+
* register and schema default to the tile's source). With `kind:
|
|
1784
|
+
* "ratio"` it reads the `denominator` part, and the `numerator` part
|
|
1785
|
+
* when one is named, as the tile's `ratio` source does. A failed read
|
|
1687
1786
|
* leaves the caption out; it never shows a zero it did not count.
|
|
1688
1787
|
*
|
|
1689
1788
|
* @spec openspec/changes/screens-stat-caption-source/specs/stat-widget/spec.md#requirement-a-stat-tiles-caption-can-carry-its-own-count
|
|
@@ -1692,6 +1791,7 @@ var script = {
|
|
|
1692
1791
|
async fetchCaptionValue() {
|
|
1693
1792
|
if (!this.hasCaptionSource) {
|
|
1694
1793
|
this.captionValue = null;
|
|
1794
|
+
this.captionRatioParts = null;
|
|
1695
1795
|
return
|
|
1696
1796
|
}
|
|
1697
1797
|
const own = this.content.captionSource;
|
|
@@ -1702,13 +1802,37 @@ var script = {
|
|
|
1702
1802
|
import('@nextcloud/axios'),
|
|
1703
1803
|
import('@nextcloud/router'),
|
|
1704
1804
|
]);
|
|
1805
|
+
if (own.kind === 'ratio') {
|
|
1806
|
+
// The parts of the tile's own `ratio` source: each names its
|
|
1807
|
+
// metric, field, filter and `via`.
|
|
1808
|
+
const part = (p) => this.fetchAggregate(axios, generateUrl, source, (p && p.metric) || own.metric, (p && p.field) || own.field, (p && p.filter) || {}, (p && p.via) || own.via);
|
|
1809
|
+
const num = own.numerator ? await part(own.numerator) : null;
|
|
1810
|
+
const den = await part(own.denominator);
|
|
1811
|
+
this.captionRatioParts = { num: num === undefined ? null : num, den };
|
|
1812
|
+
return
|
|
1813
|
+
}
|
|
1705
1814
|
const found = await this.fetchAggregate(axios, generateUrl, source, own.metric, own.field, own.filter || {}, own.via);
|
|
1706
1815
|
this.captionValue = found === null || found === undefined || Number.isNaN(Number(found)) ? null : Number(found);
|
|
1707
1816
|
} catch {
|
|
1708
1817
|
this.captionValue = null;
|
|
1818
|
+
this.captionRatioParts = null;
|
|
1709
1819
|
}
|
|
1710
1820
|
},
|
|
1711
1821
|
|
|
1822
|
+
/**
|
|
1823
|
+
* A ratio caption's share as the reader's number, with
|
|
1824
|
+
* `captionSource.decimals` fraction digits (0 by default).
|
|
1825
|
+
*
|
|
1826
|
+
* @param {number} share The percentage.
|
|
1827
|
+
* @return {string}
|
|
1828
|
+
* @spec openspec/changes/stat-caption-ratio/specs/stat-widget/spec.md#requirement-a-stat-tiles-caption-can-show-a-share
|
|
1829
|
+
*/
|
|
1830
|
+
formatCaptionRatio(share) {
|
|
1831
|
+
const raw = Number(this.content.captionSource && this.content.captionSource.decimals);
|
|
1832
|
+
const digits = Number.isInteger(raw) && raw >= 0 && raw <= 4 ? raw : 0;
|
|
1833
|
+
return new Intl.NumberFormat(metricLocale(), { minimumFractionDigits: digits, maximumFractionDigits: digits }).format(share)
|
|
1834
|
+
},
|
|
1835
|
+
|
|
1712
1836
|
/**
|
|
1713
1837
|
* Resolve the widget's value from its `source`. Supports three source
|
|
1714
1838
|
* kinds (ADR-041): a plain `aggregate` (count/sum/avg/min/max with
|