@conduction/nextcloud-vue 2.76.0 → 2.78.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/CnAiCompanion/CnAiCompanion.vue2.js +23 -0
- package/dist/esm/components/CnAiCompanion/CnAiCompanion.vue2.js.map +1 -1
- package/dist/esm/components/CnAiCompanion/CnAiCompanion.vue3.js.map +1 -1
- package/dist/esm/components/CnAppNav/CnAppNav.vue2.js +18 -3
- package/dist/esm/components/CnAppNav/CnAppNav.vue2.js.map +1 -1
- package/dist/esm/components/CnAppNav/CnAppNav.vue3.js +49 -3
- package/dist/esm/components/CnAppNav/CnAppNav.vue3.js.map +1 -1
- package/dist/esm/components/CnBoardView/CnBoardView.vue2.js +2 -1
- package/dist/esm/components/CnBoardView/CnBoardView.vue2.js.map +1 -1
- package/dist/esm/components/CnBoardView/CnBoardView.vue3.js.map +1 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js +79 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js.map +1 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js +229 -203
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js.map +1 -1
- package/dist/esm/components/CnCellRenderer/CnGroupNameCell.vue.js +9 -0
- package/dist/esm/components/CnCellRenderer/CnGroupNameCell.vue.js.map +1 -0
- package/dist/esm/components/CnCellRenderer/CnGroupNameCell.vue2.js +50 -0
- package/dist/esm/components/CnCellRenderer/CnGroupNameCell.vue2.js.map +1 -0
- package/dist/esm/components/CnCellRenderer/CnGroupNameCell.vue3.js +13 -0
- package/dist/esm/components/CnCellRenderer/CnGroupNameCell.vue3.js.map +1 -0
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue2.js +37 -0
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue3.js +2 -2
- package/dist/esm/components/CnChartWidget/CnChartWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +29 -4
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +48 -6
- package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +90 -51
- package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
- package/dist/esm/components/CnDateRangePicker/CnDateRangePicker.vue.js +1 -1
- package/dist/esm/components/CnDateRangePicker/CnDateRangePicker.vue2.js +45 -2
- package/dist/esm/components/CnDateRangePicker/CnDateRangePicker.vue2.js.map +1 -1
- package/dist/esm/components/CnDateRangePicker/CnDateRangePicker.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +16 -28
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js +12 -24
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
- package/dist/esm/components/CnFavouriteToggle/CnFavouriteToggle.vue2.js +7 -2
- package/dist/esm/components/CnFavouriteToggle/CnFavouriteToggle.vue2.js.map +1 -1
- package/dist/esm/components/CnFavouriteToggle/CnFavouriteToggle.vue3.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js +114 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js +115 -62
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js.map +1 -1
- package/dist/esm/components/CnFollowToggle/CnFollowToggle.vue2.js +89 -7
- package/dist/esm/components/CnFollowToggle/CnFollowToggle.vue2.js.map +1 -1
- package/dist/esm/components/CnFollowToggle/CnFollowToggle.vue3.js +62 -30
- package/dist/esm/components/CnFollowToggle/CnFollowToggle.vue3.js.map +1 -1
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js +7 -1
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js.map +1 -1
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js.map +1 -1
- package/dist/esm/components/CnFormPage/CnFormPage.vue2.js +4 -1
- package/dist/esm/components/CnFormPage/CnFormPage.vue2.js.map +1 -1
- package/dist/esm/components/CnFormPage/CnFormPage.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +104 -13
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +13 -9
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue2.js +199 -7
- package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue3.js +155 -119
- package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js +6 -0
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js +4 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js.map +1 -1
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue2.js +36 -0
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js +35 -23
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnStatusBadge/CnStatusBadge.vue2.js +6 -2
- package/dist/esm/components/CnStatusBadge/CnStatusBadge.vue2.js.map +1 -1
- package/dist/esm/components/CnStatusBadge/CnStatusBadge.vue3.js.map +1 -1
- package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue2.js +13 -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/composables/useFormDraft.js +11 -1
- package/dist/esm/composables/useFormDraft.js.map +1 -1
- package/dist/esm/composables/useListView.js +4 -0
- package/dist/esm/composables/useListView.js.map +1 -1
- package/dist/esm/composables/useObjectPresence.js +15 -4
- package/dist/esm/composables/useObjectPresence.js.map +1 -1
- package/dist/esm/index.js +2 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/l10n/en.json.js +32 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +32 -1
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/nextcloud-vue.css +500 -75
- package/dist/esm/store/plugins/interactions.js +20 -10
- package/dist/esm/store/plugins/interactions.js.map +1 -1
- package/dist/esm/store/useObjectStore.js +17 -0
- package/dist/esm/store/useObjectStore.js.map +1 -1
- package/dist/esm/utils/badgeVariants.js +32 -0
- package/dist/esm/utils/badgeVariants.js.map +1 -0
- package/dist/esm/utils/builtInFormatters.js +15 -7
- package/dist/esm/utils/builtInFormatters.js.map +1 -1
- package/dist/esm/utils/groupAutocomplete.js +63 -1
- package/dist/esm/utils/groupAutocomplete.js.map +1 -1
- package/dist/esm/utils/lensAvailability.js +90 -0
- package/dist/esm/utils/lensAvailability.js.map +1 -0
- package/dist/esm/utils/personalLenses.js +13 -6
- package/dist/esm/utils/personalLenses.js.map +1 -1
- package/dist/esm/utils/recordInteractions.js +31 -13
- package/dist/esm/utils/recordInteractions.js.map +1 -1
- package/dist/esm/utils/resolveFilterTokens.js +46 -3
- package/dist/esm/utils/resolveFilterTokens.js.map +1 -1
- package/dist/esm/utils/schema.js +1 -1
- package/dist/esm/utils/schema.js.map +1 -1
- package/dist/esm/utils/sentinelTokens.js +4 -4
- package/dist/esm/utils/sentinelTokens.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/esm/utils/widgetVisibility.js +46 -1
- package/dist/esm/utils/widgetVisibility.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +4389 -2890
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +500 -75
- package/l10n/en.json +32 -1
- package/l10n/nl.json +32 -1
- package/package.json +1 -1
- package/src/components/CnAiCompanion/CnAiCompanion.vue +23 -0
- package/src/components/CnAppNav/CnAppNav.vue +44 -5
- package/src/components/CnBoardView/CnBoardView.vue +2 -1
- package/src/components/CnCellRenderer/CnCellRenderer.md +1 -0
- package/src/components/CnCellRenderer/CnCellRenderer.vue +106 -9
- package/src/components/CnCellRenderer/CnGroupNameCell.vue +61 -0
- package/src/components/CnChartWidget/CnChartWidget.vue +39 -2
- package/src/components/CnDashboardPage/CnDashboardPage.vue +29 -4
- package/src/components/CnDataTable/CnDataTable.md +9 -0
- package/src/components/CnDataTable/CnDataTable.vue +87 -22
- package/src/components/CnDateRangePicker/CnDateRangePicker.vue +44 -1
- package/src/components/CnDetailPage/CnDetailPage.vue +10 -27
- package/src/components/CnFavouriteToggle/CnFavouriteToggle.vue +7 -2
- package/src/components/CnFilesBrowser/CnFilesBrowser.vue +204 -5
- package/src/components/CnFollowToggle/CnFollowToggle.vue +118 -13
- package/src/components/CnFormDialog/CnFormDialog.vue +7 -1
- package/src/components/CnFormPage/CnFormPage.vue +4 -1
- package/src/components/CnIndexPage/CnIndexPage.md +36 -0
- package/src/components/CnIndexPage/CnIndexPage.vue +112 -19
- package/src/components/CnObjectDataWidget/CnObjectDataWidget.vue +226 -2
- package/src/components/CnObjectSidebar/CnFilesTab.vue +9 -0
- package/src/components/CnStatWidget/CnStatWidget.vue +52 -2
- package/src/components/CnStatusBadge/CnStatusBadge.vue +6 -2
- package/src/components/CnWidgetObjectTable/CnWidgetObjectTable.vue +13 -0
- package/src/composables/__tests__/useObjectPresence.spec.js +24 -0
- package/src/composables/useFormDraft.js +11 -1
- package/src/composables/useListView.js +4 -0
- package/src/composables/useObjectPresence.js +15 -4
- package/src/css/badge.css +31 -0
- package/src/css/kpi-card.css +51 -0
- package/src/css/look-board-detail.css +40 -2
- package/src/css/look-board-index.css +36 -0
- package/src/css/look-board.css +8 -0
- package/src/css/table.css +82 -17
- package/src/index.js +2 -1
- package/src/schemas/app-manifest-v2.schema.json +15 -11
- package/src/store/plugins/interactions.js +20 -10
- package/src/store/useObjectStore.js +17 -0
- package/src/utils/badgeVariants.js +29 -0
- package/src/utils/builtInFormatters.js +15 -7
- package/src/utils/groupAutocomplete.js +75 -0
- package/src/utils/index.js +1 -1
- package/src/utils/lensAvailability.js +86 -0
- package/src/utils/personalLenses.js +13 -6
- package/src/utils/recordInteractions.js +31 -13
- package/src/utils/resolveFilterTokens.js +45 -2
- package/src/utils/schema.js +1 -1
- package/src/utils/sentinelTokens.js +4 -4
- package/src/utils/validateManifestV2.compiled.js +2 -2
- package/src/utils/widgetVisibility.js +45 -0
package/l10n/en.json
CHANGED
|
@@ -114,6 +114,7 @@
|
|
|
114
114
|
"Saved just now": "Saved just now",
|
|
115
115
|
"Saved {time}": "Saved {time}",
|
|
116
116
|
"Saved": "Saved",
|
|
117
|
+
"Draft kept on this device": "Draft kept on this device",
|
|
117
118
|
"Publish": "Publish",
|
|
118
119
|
"Edit {title} (draft)": "Edit {title} (draft)",
|
|
119
120
|
"Also search inside files": "Also search inside files",
|
|
@@ -453,6 +454,12 @@
|
|
|
453
454
|
"NC Activity is currently unavailable.": "NC Activity is currently unavailable.",
|
|
454
455
|
"Could not load activity.": "Could not load activity.",
|
|
455
456
|
"Today": "Today",
|
|
457
|
+
"Last 8 hours": "Last 8 hours",
|
|
458
|
+
"Last 24 hours": "Last 24 hours",
|
|
459
|
+
"Last 7 days": "Last 7 days",
|
|
460
|
+
"Last 30 days": "Last 30 days",
|
|
461
|
+
"Last 90 days": "Last 90 days",
|
|
462
|
+
"Custom range": "Custom range",
|
|
456
463
|
"Yesterday": "Yesterday",
|
|
457
464
|
"Earlier": "Earlier",
|
|
458
465
|
"System": "System",
|
|
@@ -1290,7 +1297,19 @@
|
|
|
1290
1297
|
"Test environment": "Test environment",
|
|
1291
1298
|
"Acceptance environment": "Acceptance environment",
|
|
1292
1299
|
"About {label}": "About {label}",
|
|
1293
|
-
"Could not load the form for this item.": "Could not load the form for this item."
|
|
1300
|
+
"Could not load the form for this item.": "Could not load the form for this item.",
|
|
1301
|
+
"Drop to add": "Drop to add",
|
|
1302
|
+
"Or drag files onto this list.": "Or drag files onto this list.",
|
|
1303
|
+
"This server does not keep track of what you open.": "This server does not keep track of what you open.",
|
|
1304
|
+
"Log in to see what you opened recently.": "Log in to see what you opened recently.",
|
|
1305
|
+
"Your recent items are not available right now.": "Your recent items are not available right now.",
|
|
1306
|
+
"yesterday": "yesterday",
|
|
1307
|
+
"tomorrow": "tomorrow",
|
|
1308
|
+
"Filter by {column}": "Filter by {column}",
|
|
1309
|
+
"Filter by {column}, active": "Filter by {column}, active",
|
|
1310
|
+
"Turn notifications off": "Turn notifications off",
|
|
1311
|
+
"Turn notifications on": "Turn notifications on",
|
|
1312
|
+
"Could not change notifications.": "Could not change notifications."
|
|
1294
1313
|
},
|
|
1295
1314
|
"plurals": {
|
|
1296
1315
|
"%n year": [
|
|
@@ -1344,6 +1363,18 @@
|
|
|
1344
1363
|
"You see {count} capability of {total}.": [
|
|
1345
1364
|
"You see {count} capability of {total}.",
|
|
1346
1365
|
"You see {count} capabilities of {total}."
|
|
1366
|
+
],
|
|
1367
|
+
"%n file added": [
|
|
1368
|
+
"%n file added",
|
|
1369
|
+
"%n files added"
|
|
1370
|
+
],
|
|
1371
|
+
"{count} day ago": [
|
|
1372
|
+
"{count} day ago",
|
|
1373
|
+
"{count} days ago"
|
|
1374
|
+
],
|
|
1375
|
+
"in {count} day": [
|
|
1376
|
+
"in {count} day",
|
|
1377
|
+
"in {count} days"
|
|
1347
1378
|
]
|
|
1348
1379
|
}
|
|
1349
1380
|
}
|
package/l10n/nl.json
CHANGED
|
@@ -114,6 +114,7 @@
|
|
|
114
114
|
"Saved just now": "Zojuist opgeslagen",
|
|
115
115
|
"Saved {time}": "Opgeslagen {time}",
|
|
116
116
|
"Saved": "Opgeslagen",
|
|
117
|
+
"Draft kept on this device": "Concept bewaard op dit apparaat",
|
|
117
118
|
"Edit {title} (draft)": "{title} bewerken (concept)",
|
|
118
119
|
"Also search inside files": "Zoek ook in bestanden",
|
|
119
120
|
"File matches are limited to the best 50.": "Bestandstreffers zijn beperkt tot de beste 50.",
|
|
@@ -452,6 +453,12 @@
|
|
|
452
453
|
"NC Activity is currently unavailable.": "NC Activiteit is momenteel niet beschikbaar.",
|
|
453
454
|
"Could not load activity.": "Kon activiteit niet laden.",
|
|
454
455
|
"Today": "Vandaag",
|
|
456
|
+
"Last 8 hours": "Laatste 8 uur",
|
|
457
|
+
"Last 24 hours": "Laatste 24 uur",
|
|
458
|
+
"Last 7 days": "Laatste 7 dagen",
|
|
459
|
+
"Last 30 days": "Laatste 30 dagen",
|
|
460
|
+
"Last 90 days": "Laatste 90 dagen",
|
|
461
|
+
"Custom range": "Aangepaste periode",
|
|
455
462
|
"Yesterday": "Gisteren",
|
|
456
463
|
"Earlier": "Eerder",
|
|
457
464
|
"System": "Systeem",
|
|
@@ -1341,7 +1348,19 @@
|
|
|
1341
1348
|
"Test environment": "Testomgeving",
|
|
1342
1349
|
"Acceptance environment": "Acceptatieomgeving",
|
|
1343
1350
|
"About {label}": "Over {label}",
|
|
1344
|
-
"Could not load the form for this item.": "Kon het formulier voor dit item niet laden."
|
|
1351
|
+
"Could not load the form for this item.": "Kon het formulier voor dit item niet laden.",
|
|
1352
|
+
"Drop to add": "Laat los om toe te voegen",
|
|
1353
|
+
"Or drag files onto this list.": "Of sleep bestanden op deze lijst.",
|
|
1354
|
+
"This server does not keep track of what you open.": "Deze server houdt niet bij welke items je opent.",
|
|
1355
|
+
"Log in to see what you opened recently.": "Log in om te zien wat je onlangs opende.",
|
|
1356
|
+
"Your recent items are not available right now.": "Je recente items zijn nu niet beschikbaar.",
|
|
1357
|
+
"yesterday": "gisteren",
|
|
1358
|
+
"tomorrow": "morgen",
|
|
1359
|
+
"Filter by {column}": "Filteren op {column}",
|
|
1360
|
+
"Filter by {column}, active": "Filteren op {column}, actief",
|
|
1361
|
+
"Turn notifications off": "Meldingen uitzetten",
|
|
1362
|
+
"Turn notifications on": "Meldingen aanzetten",
|
|
1363
|
+
"Could not change notifications.": "Meldingen konden niet worden gewijzigd."
|
|
1345
1364
|
},
|
|
1346
1365
|
"plurals": {
|
|
1347
1366
|
"%n year": [
|
|
@@ -1395,6 +1414,18 @@
|
|
|
1395
1414
|
"You see {count} capability of {total}.": [
|
|
1396
1415
|
"Je ziet {count} functionaliteit van {total}.",
|
|
1397
1416
|
"Je ziet {count} functionaliteiten van {total}."
|
|
1417
|
+
],
|
|
1418
|
+
"%n file added": [
|
|
1419
|
+
"%n bestand toegevoegd",
|
|
1420
|
+
"%n bestanden toegevoegd"
|
|
1421
|
+
],
|
|
1422
|
+
"{count} day ago": [
|
|
1423
|
+
"{count} dag geleden",
|
|
1424
|
+
"{count} dagen geleden"
|
|
1425
|
+
],
|
|
1426
|
+
"in {count} day": [
|
|
1427
|
+
"over {count} dag",
|
|
1428
|
+
"over {count} dagen"
|
|
1398
1429
|
]
|
|
1399
1430
|
}
|
|
1400
1431
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@conduction/nextcloud-vue",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.78.0",
|
|
4
4
|
"description": "Shared Vue component library for Conduction Nextcloud apps — complements @nextcloud/vue with higher-level components, OpenRegister integration, and NL Design System support",
|
|
5
5
|
"homepage": "https://github.com/ConductionNL/nextcloud-vue#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -66,6 +66,7 @@ import CnAiChatPanel from './CnAiChatPanel.vue'
|
|
|
66
66
|
import CnAiFloatingButton from './CnAiFloatingButton.vue'
|
|
67
67
|
import { chatHealthUrl, DEFAULT_CHAT_APP_ID } from '../../composables/aiChatConfig.js'
|
|
68
68
|
import { useAiChatStream } from '../../composables/useAiChatStream.js'
|
|
69
|
+
import { isAppInstalled } from '../../utils/appInstalled.js'
|
|
69
70
|
|
|
70
71
|
const HEALTH_TIMEOUT = 5000
|
|
71
72
|
|
|
@@ -340,6 +341,15 @@ export default {
|
|
|
340
341
|
}
|
|
341
342
|
},
|
|
342
343
|
|
|
344
|
+
/**
|
|
345
|
+
* Ask the chat backend whether it can answer, and render only if so.
|
|
346
|
+
*
|
|
347
|
+
* Skipped without a request when the backend app is not installed for
|
|
348
|
+
* this user.
|
|
349
|
+
*
|
|
350
|
+
* @return {Promise<void>}
|
|
351
|
+
* @spec openspec/changes/no-calls-to-missing-apps-and-presence-beacon/specs/ai-companion/spec.md#requirement-the-companion-does-not-probe-a-backend-that-is-not-installed
|
|
352
|
+
*/
|
|
343
353
|
async runHealthProbe() {
|
|
344
354
|
// RETRY before hiding. A single probe makes the whole companion
|
|
345
355
|
// disappear on one slow response, and "slow" is normal: measured on a
|
|
@@ -351,6 +361,19 @@ export default {
|
|
|
351
361
|
//
|
|
352
362
|
// A backend that is genuinely down fails all attempts and is still
|
|
353
363
|
// reported; this only stops one unlucky request from deciding.
|
|
364
|
+
//
|
|
365
|
+
// 🔴 NO PROBE AT AN APP THAT IS NOT THERE. Nextcloud already tells
|
|
366
|
+
// the page which apps the user has (`OC.appswebroots`), so asking a
|
|
367
|
+
// missing backend for its health is a guaranteed 404, three times
|
|
368
|
+
// per page, in every console. Measured on cloud.conduction.nl
|
|
369
|
+
// (round-5 check): hermiq not installed, three
|
|
370
|
+
// `/apps/hermiq/api/chat/health` 404s on every pipelinq and dossiq
|
|
371
|
+
// page. Hidden either way; now hidden without the requests.
|
|
372
|
+
if (!isAppInstalled(this.chatAppId || DEFAULT_CHAT_APP_ID)) {
|
|
373
|
+
this.probeSucceeded = false
|
|
374
|
+
return
|
|
375
|
+
}
|
|
376
|
+
|
|
354
377
|
for (let attempt = 1; attempt <= HEALTH_PROBE_ATTEMPTS; attempt++) {
|
|
355
378
|
try {
|
|
356
379
|
const response = await axios.get(chatHealthUrl(this.chatAppId), {
|
|
@@ -183,7 +183,19 @@
|
|
|
183
183
|
v-if="isCaption(item)"
|
|
184
184
|
:key="item.id"
|
|
185
185
|
:name="resolveLabel(item)"
|
|
186
|
-
:data-testid="`cn-nav-caption-${item.id}`"
|
|
186
|
+
:data-testid="`cn-nav-caption-${item.id}`">
|
|
187
|
+
<template v-if="item.href" #actions>
|
|
188
|
+
<NcActionLink
|
|
189
|
+
:href="item.href"
|
|
190
|
+
:aria-label="captionEditLabel(item)"
|
|
191
|
+
:data-testid="`cn-nav-caption-edit-${item.id}`">
|
|
192
|
+
<template #icon>
|
|
193
|
+
<Pencil :size="20" />
|
|
194
|
+
</template>
|
|
195
|
+
{{ captionEditLabel(item) }}
|
|
196
|
+
</NcActionLink>
|
|
197
|
+
</template>
|
|
198
|
+
</NcAppNavigationCaption>
|
|
187
199
|
<NcAppNavigationItem
|
|
188
200
|
v-else
|
|
189
201
|
:key="item.id"
|
|
@@ -424,7 +436,19 @@
|
|
|
424
436
|
v-if="isCaption(item)"
|
|
425
437
|
:key="item.id"
|
|
426
438
|
:name="resolveLabel(item)"
|
|
427
|
-
:data-testid="`cn-nav-caption-${item.id}`"
|
|
439
|
+
:data-testid="`cn-nav-caption-${item.id}`">
|
|
440
|
+
<template v-if="item.href" #actions>
|
|
441
|
+
<NcActionLink
|
|
442
|
+
:href="item.href"
|
|
443
|
+
:aria-label="captionEditLabel(item)"
|
|
444
|
+
:data-testid="`cn-nav-caption-edit-${item.id}`">
|
|
445
|
+
<template #icon>
|
|
446
|
+
<Pencil :size="20" />
|
|
447
|
+
</template>
|
|
448
|
+
{{ captionEditLabel(item) }}
|
|
449
|
+
</NcActionLink>
|
|
450
|
+
</template>
|
|
451
|
+
</NcAppNavigationCaption>
|
|
428
452
|
<NcAppNavigationItem
|
|
429
453
|
v-else
|
|
430
454
|
:key="item.id"
|
|
@@ -466,7 +490,7 @@
|
|
|
466
490
|
<script>
|
|
467
491
|
import { translate as t } from '@nextcloud/l10n'
|
|
468
492
|
import { generateUrl } from '@nextcloud/router'
|
|
469
|
-
import { NcAppNavigation, NcAppNavigationCaption, NcAppNavigationItem, NcAppNavigationList, NcAppNavigationNew, NcAppNavigationSettings, NcButton, NcCounterBubble } from '@nextcloud/vue'
|
|
493
|
+
import { NcActionLink, NcAppNavigation, NcAppNavigationCaption, NcAppNavigationItem, NcAppNavigationList, NcAppNavigationNew, NcAppNavigationSettings, NcButton, NcCounterBubble } from '@nextcloud/vue'
|
|
470
494
|
import { toRaw } from 'vue'
|
|
471
495
|
import BookOpenVariant from 'vue-material-design-icons/BookOpenVariant.vue'
|
|
472
496
|
import Cog from 'vue-material-design-icons/Cog.vue'
|
|
@@ -474,6 +498,7 @@ import Cog from 'vue-material-design-icons/Cog.vue'
|
|
|
474
498
|
import HelpCircleOutline from 'vue-material-design-icons/HelpCircleOutline.vue'
|
|
475
499
|
import MapMarkerPath from 'vue-material-design-icons/MapMarkerPath.vue'
|
|
476
500
|
import OpenInNew from 'vue-material-design-icons/OpenInNew.vue'
|
|
501
|
+
import Pencil from 'vue-material-design-icons/Pencil.vue'
|
|
477
502
|
import Plus from 'vue-material-design-icons/Plus.vue'
|
|
478
503
|
import ShieldAccountOutline from 'vue-material-design-icons/ShieldAccountOutline.vue'
|
|
479
504
|
import { ICON_MAP } from '../CnIcon/CnIcon.vue'
|
|
@@ -560,6 +585,8 @@ export default {
|
|
|
560
585
|
name: 'CnAppNav',
|
|
561
586
|
|
|
562
587
|
components: {
|
|
588
|
+
NcActionLink,
|
|
589
|
+
Pencil,
|
|
563
590
|
NcAppNavigation,
|
|
564
591
|
NcAppNavigationCaption,
|
|
565
592
|
NcAppNavigationItem,
|
|
@@ -1921,8 +1948,10 @@ export default {
|
|
|
1921
1948
|
/**
|
|
1922
1949
|
* Whether a menu entry renders as a `NcAppNavigationCaption`
|
|
1923
1950
|
* (`type: "caption"`) rather than a clickable
|
|
1924
|
-
* `NcAppNavigationItem`. Caption entries ignore `route`, `
|
|
1925
|
-
* `
|
|
1951
|
+
* `NcAppNavigationItem`. Caption entries ignore `route`, `action`,
|
|
1952
|
+
* `icon`, `count`, `children`, and `pinned`. A caption's `href` is
|
|
1953
|
+
* drawn as a pencil link beside the heading: the place where what
|
|
1954
|
+
* stands under it is changed (a user's own choice of entries, say).
|
|
1926
1955
|
*
|
|
1927
1956
|
* @param {{ type?: string }} item Menu entry descriptor.
|
|
1928
1957
|
* @return {boolean}
|
|
@@ -1931,6 +1960,16 @@ export default {
|
|
|
1931
1960
|
return item?.type === 'caption'
|
|
1932
1961
|
},
|
|
1933
1962
|
|
|
1963
|
+
/**
|
|
1964
|
+
* The accessible name of a caption's pencil link.
|
|
1965
|
+
*
|
|
1966
|
+
* @param {object} item The caption entry.
|
|
1967
|
+
* @return {string} "Change {caption}", translated.
|
|
1968
|
+
*/
|
|
1969
|
+
captionEditLabel(item) {
|
|
1970
|
+
return t('nextcloud-vue', 'Change {name}', { name: this.resolveLabel(item) })
|
|
1971
|
+
},
|
|
1972
|
+
|
|
1934
1973
|
/**
|
|
1935
1974
|
* Whether the host has registered a scoped slot named
|
|
1936
1975
|
* `item-${id}-actions` for this menu item. Used to gate template
|
|
@@ -308,6 +308,7 @@
|
|
|
308
308
|
import { translate as t } from '@nextcloud/l10n'
|
|
309
309
|
import CnStatusBadge from '../CnStatusBadge/CnStatusBadge.vue'
|
|
310
310
|
import { normalizeLook } from '../../composables/useLook.js'
|
|
311
|
+
import { isBadgeVariant } from '../../utils/badgeVariants.js'
|
|
311
312
|
import { buildBoardColumns, resolveStageColor } from '../../utils/boardColumns.js'
|
|
312
313
|
import { buildSwimlanes } from '../../utils/boardSwimlanes.js'
|
|
313
314
|
import { DROP_OUTCOMES, runBoardDrop } from '../../utils/boardTransition.js'
|
|
@@ -688,7 +689,7 @@ export default {
|
|
|
688
689
|
pillVariant(card) {
|
|
689
690
|
const raw = this.textOf(readPath(card, this.roles.pill))
|
|
690
691
|
const variant = this.roles.pillColors[raw] ?? this.roles.pillColors[raw.toLowerCase()]
|
|
691
|
-
return
|
|
692
|
+
return isBadgeVariant(variant) ? variant : 'default'
|
|
692
693
|
},
|
|
693
694
|
|
|
694
695
|
/**
|
|
@@ -89,6 +89,7 @@ fall back to the normal rendering. See `docs/migrating-to-manifest.md` →
|
|
|
89
89
|
Column widget — `widget="badge"`, `widget="fkResolve"` (uuid → related object label via the shared object store with per-schema caching; config `widgetProps { register, schema, labelField }`), and `widget="link"` are built-in; any other id resolves against the app's `cellWidgets` registry (`CnAppRoot`'s `cellWidgets` prop → `cnCellWidgets`), and that component receives `{ value, row, property, formatted, ...widgetProps }`. `widget` takes precedence over `formatter`; when both are set the widget gets the formatter-shaped value as `formatted`. See `docs/migrating-to-manifest.md` → "Column widgets" + "Built-in cell formatters / widgets".
|
|
90
90
|
|
|
91
91
|
- `widget="badge"` — `CnStatusBadge` pill; `widgetProps.variant` picks the colour.
|
|
92
|
+
An enum value shows its `x-enum-labels` label, translated, as the plain enum cell does; a column `formatter` still wins. `widgetProps.colorMap` is looked up by the stored value when it has an entry for it, else by the label. The `link` widget and the `swatch` format show the same label.
|
|
92
93
|
- `widget="link"` — `<router-link>` when `widgetProps.route` is a manifest page id, or when `widgetProps.routeMap` maps the row's `widgetProps.routeField` value to one (a value the map does not hold falls back to `route`, then to text); `<a target="_blank">` when `widgetProps.href` is set (with `{key}` placeholders substituted from the row); plain text + once-per-session `console.warn` when neither resolves (silence with `widgetProps.fallback:"silent"`). For non-`id` route params: `widgetProps.params: { routeParam: "rowField" }`. Default param map is `{ id: row[rowKey] }` — see the `row-key` prop below.
|
|
93
94
|
|
|
94
95
|
```vue
|
|
@@ -10,12 +10,29 @@
|
|
|
10
10
|
:formatted="formattedValue"
|
|
11
11
|
v-bind="widgetProps" />
|
|
12
12
|
|
|
13
|
-
<!-- Built-in "
|
|
13
|
+
<!-- Built-in "group" widget: a Nextcloud group id (or a list of them)
|
|
14
|
+
shown as the group's display name, cached per id. Used on its own
|
|
15
|
+
for a property marked `referenceType: nextcloud-group` /
|
|
16
|
+
`format: nc-group` unless the column has a formatter. -->
|
|
17
|
+
<template v-else-if="isGroupCell">
|
|
18
|
+
<span v-if="!groupIds.length" class="cn-cell-renderer__dash">—</span>
|
|
19
|
+
<span v-else class="cn-cell-renderer__groups">
|
|
20
|
+
<template v-for="(gid, i) in groupIds" :key="gid">
|
|
21
|
+
<span v-if="i > 0">, </span>
|
|
22
|
+
<CnGroupNameCell :gid="gid" />
|
|
23
|
+
</template>
|
|
24
|
+
</span>
|
|
25
|
+
</template>
|
|
26
|
+
|
|
27
|
+
<!-- Built-in "badge" widget: renders the value as a status pill. An enum
|
|
28
|
+
value shows its label (x-enum-labels, translated) unless a formatter
|
|
29
|
+
shapes it; the colour stays keyed on the raw value. -->
|
|
14
30
|
<template v-else-if="widget === 'badge'">
|
|
15
31
|
<CnStatusBadge v-if="hasValue"
|
|
16
|
-
:label="
|
|
32
|
+
:label="labelledValue"
|
|
17
33
|
:variant="badgeVariant"
|
|
18
|
-
:colorMap="badgeColorMap"
|
|
34
|
+
:colorMap="badgeColorMap"
|
|
35
|
+
:colorKey="badgeColorKey" />
|
|
19
36
|
<span v-else class="cn-cell-renderer__dash">—</span>
|
|
20
37
|
</template>
|
|
21
38
|
|
|
@@ -64,7 +81,7 @@
|
|
|
64
81
|
v-if="linkRoute"
|
|
65
82
|
:to="linkRoute"
|
|
66
83
|
class="cn-cell-renderer__link">
|
|
67
|
-
{{
|
|
84
|
+
{{ labelledValue }}
|
|
68
85
|
</router-link>
|
|
69
86
|
<a
|
|
70
87
|
v-else-if="linkHref"
|
|
@@ -72,9 +89,9 @@
|
|
|
72
89
|
target="_blank"
|
|
73
90
|
rel="noopener"
|
|
74
91
|
class="cn-cell-renderer__link">
|
|
75
|
-
{{
|
|
92
|
+
{{ labelledValue }}
|
|
76
93
|
</a>
|
|
77
|
-
<span v-else :title="rawTitle">{{
|
|
94
|
+
<span v-else :title="rawTitle">{{ labelledValue }}</span>
|
|
78
95
|
</template>
|
|
79
96
|
|
|
80
97
|
<!-- Built-in "avatar" widget: a person as an avatar with the name beside
|
|
@@ -127,7 +144,7 @@
|
|
|
127
144
|
class="cn-cell-renderer__swatch-dot"
|
|
128
145
|
:style="{ backgroundColor: swatchColor }"
|
|
129
146
|
aria-hidden="true" />
|
|
130
|
-
<span v-if="hasValue" :title="rawTitle">{{
|
|
147
|
+
<span v-if="hasValue" :title="rawTitle">{{ labelledValue }}</span>
|
|
131
148
|
<span v-else class="cn-cell-renderer__dash">—</span>
|
|
132
149
|
</span>
|
|
133
150
|
</template>
|
|
@@ -192,11 +209,12 @@ import { getCanonicalLocale } from '@nextcloud/l10n'
|
|
|
192
209
|
import { NcAvatar, NcDateTime } from '@nextcloud/vue'
|
|
193
210
|
import CheckBold from 'vue-material-design-icons/CheckBold.vue'
|
|
194
211
|
import CnFkResolveCell from '../CnFkResolveCell/CnFkResolveCell.vue'
|
|
212
|
+
import CnGroupNameCell from './CnGroupNameCell.vue'
|
|
195
213
|
import { parseDateValue, resolveDateVariant } from '../../utils/dateVariant.js'
|
|
196
214
|
import { safeCurrencyCode } from '../../utils/formatMetric.js'
|
|
197
215
|
import { objectFieldValue } from '../../utils/objectName.js'
|
|
198
216
|
import { safeHref } from '../../utils/safeHref.js'
|
|
199
|
-
import { formatValue } from '../../utils/schema.js'
|
|
217
|
+
import { formatValue, isGroupProp } from '../../utils/schema.js'
|
|
200
218
|
import { CnStatusBadge } from '../CnStatusBadge/index.js'
|
|
201
219
|
|
|
202
220
|
/** A uuid in any version, the shape OpenRegister ids take. */
|
|
@@ -226,6 +244,7 @@ export default {
|
|
|
226
244
|
components: {
|
|
227
245
|
CnStatusBadge,
|
|
228
246
|
CnFkResolveCell,
|
|
247
|
+
CnGroupNameCell,
|
|
229
248
|
CheckBold,
|
|
230
249
|
NcAvatar,
|
|
231
250
|
NcDateTime,
|
|
@@ -307,6 +326,9 @@ export default {
|
|
|
307
326
|
* a date whose colour follows `widgetProps.variantWhen`, rules on the
|
|
308
327
|
* number of days until the date (`[{ op: "lt", value: 0, variant:
|
|
309
328
|
* "error" }, { op: "lte", value: 5, variant: "warning" }]`).
|
|
329
|
+
* The built-in id `"group"` shows a Nextcloud group id (or a list of
|
|
330
|
+
* them) as the group's display name; a column whose property is
|
|
331
|
+
* marked `referenceType: "nextcloud-group"` gets it without asking.
|
|
310
332
|
* Takes precedence over `formatter`/the type-aware rendering, but the
|
|
311
333
|
* value handed to the widget is the formatter-shaped `formatted` when
|
|
312
334
|
* `formatter` is also set.
|
|
@@ -577,6 +599,79 @@ export default {
|
|
|
577
599
|
return c || null
|
|
578
600
|
},
|
|
579
601
|
|
|
602
|
+
/**
|
|
603
|
+
* Whether this cell shows Nextcloud group names: the column asks for
|
|
604
|
+
* `widget: "group"`, or it names no widget and no formatter and its
|
|
605
|
+
* property is a group (or a list of groups).
|
|
606
|
+
*
|
|
607
|
+
* @spec openspec/changes/nextcloud-group-surfaces/specs/data-display/spec.md#requirement-a-group-cell-shows-the-groups-display-name
|
|
608
|
+
* @return {boolean}
|
|
609
|
+
*/
|
|
610
|
+
isGroupCell() {
|
|
611
|
+
if (this.widget === 'group') {
|
|
612
|
+
return true
|
|
613
|
+
}
|
|
614
|
+
if (this.widget || this.hasFormatter) {
|
|
615
|
+
return false
|
|
616
|
+
}
|
|
617
|
+
const p = this.property
|
|
618
|
+
if (!p || typeof p !== 'object') {
|
|
619
|
+
return false
|
|
620
|
+
}
|
|
621
|
+
return isGroupProp(p) || (p.type === 'array' && isGroupProp(p.items))
|
|
622
|
+
},
|
|
623
|
+
|
|
624
|
+
/**
|
|
625
|
+
* The group ids in this cell, empty ones dropped.
|
|
626
|
+
*
|
|
627
|
+
* @spec openspec/changes/nextcloud-group-surfaces/specs/data-display/spec.md#requirement-a-group-cell-shows-the-groups-display-name
|
|
628
|
+
* @return {string[]}
|
|
629
|
+
*/
|
|
630
|
+
groupIds() {
|
|
631
|
+
const raw = this.value
|
|
632
|
+
const list = Array.isArray(raw) ? raw : [raw]
|
|
633
|
+
return list
|
|
634
|
+
.filter((gid) => (typeof gid === 'string' && gid !== '') || typeof gid === 'number')
|
|
635
|
+
.map((gid) => String(gid))
|
|
636
|
+
},
|
|
637
|
+
|
|
638
|
+
/**
|
|
639
|
+
* The text a built-in widget (`badge`, `link`) or a swatch shows. An
|
|
640
|
+
* enum value reads its label the way the plain enum cell does
|
|
641
|
+
* (`enumLabel`: `x-enum-labels`, translated), so a list says "Active"
|
|
642
|
+
* where the detail page does, not the stored "active". A column
|
|
643
|
+
* formatter still wins: an app that shapes the value itself gets
|
|
644
|
+
* exactly what its formatter returns.
|
|
645
|
+
*
|
|
646
|
+
* @return {string}
|
|
647
|
+
* @spec openspec/changes/cell-labels-and-draft-indicator/specs/cell-labels-and-draft-indicator/spec.md#requirement-a-built-in-cell-widget-shows-an-enum-value-by-its-label
|
|
648
|
+
*/
|
|
649
|
+
labelledValue() {
|
|
650
|
+
if (!this.hasFormatter && this.isEnum && this.hasValue && typeof this.value !== 'object') {
|
|
651
|
+
return this.enumLabel
|
|
652
|
+
}
|
|
653
|
+
return String(this.formattedValue)
|
|
654
|
+
},
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
* The key the built-in `badge` looks its colour up by: the raw value
|
|
658
|
+
* when `widgetProps.colorMap` has an entry for it (case-insensitive),
|
|
659
|
+
* so a translated label keeps the colour the manifest keyed on the
|
|
660
|
+
* stored code. Otherwise '' and the badge looks up its label, as before,
|
|
661
|
+
* which keeps a map keyed on a formatter's output working.
|
|
662
|
+
*
|
|
663
|
+
* @return {string}
|
|
664
|
+
* @spec openspec/changes/cell-labels-and-draft-indicator/specs/cell-labels-and-draft-indicator/spec.md#requirement-a-built-in-cell-widget-shows-an-enum-value-by-its-label
|
|
665
|
+
*/
|
|
666
|
+
badgeColorKey() {
|
|
667
|
+
const map = this.badgeColorMap
|
|
668
|
+
if (!map || !this.hasValue || typeof this.value === 'object') {
|
|
669
|
+
return ''
|
|
670
|
+
}
|
|
671
|
+
const raw = String(this.value).toLowerCase()
|
|
672
|
+
return Object.keys(map).some((key) => key.toLowerCase() === raw) ? String(this.value) : ''
|
|
673
|
+
},
|
|
674
|
+
|
|
580
675
|
/** Variant for the built-in `badge` widget — `widgetProps.variant` or `'default'`. */
|
|
581
676
|
badgeVariant() {
|
|
582
677
|
return (this.widgetProps && this.widgetProps.variant) || 'default'
|
|
@@ -1048,8 +1143,10 @@ export default {
|
|
|
1048
1143
|
color: var(--color-text-error, var(--color-error-text));
|
|
1049
1144
|
}
|
|
1050
1145
|
|
|
1146
|
+
/* The text variant, not the fill: from Nextcloud 32 `--color-success` is a
|
|
1147
|
+
background colour and too pale for a 16px glyph on a light theme. */
|
|
1051
1148
|
.cn-cell-renderer__icon--success {
|
|
1052
|
-
color: var(--color-success);
|
|
1149
|
+
color: var(--color-text-success, var(--color-success-text, var(--color-success)));
|
|
1053
1150
|
}
|
|
1054
1151
|
|
|
1055
1152
|
.cn-cell-renderer__swatch-wrap {
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
SPDX-FileCopyrightText: 2026 Conduction B.V.
|
|
3
|
+
SPDX-License-Identifier: EUPL-1.2
|
|
4
|
+
|
|
5
|
+
CnGroupNameCell: one Nextcloud group id shown as the group's display name.
|
|
6
|
+
The name is looked up once per page (utils/groupAutocomplete.js); until it
|
|
7
|
+
arrives, and when it cannot be found, the cell shows the id.
|
|
8
|
+
-->
|
|
9
|
+
<template>
|
|
10
|
+
<span class="cn-group-name-cell" :title="gid">{{ label }}</span>
|
|
11
|
+
</template>
|
|
12
|
+
|
|
13
|
+
<script>
|
|
14
|
+
import { groupDisplayName, loadGroupDisplayName } from '../../utils/groupAutocomplete.js'
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* CnGroupNameCell renders a Nextcloud group id as its display name.
|
|
18
|
+
*
|
|
19
|
+
* ```vue
|
|
20
|
+
* <CnGroupNameCell gid="toezicht" />
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @spec openspec/changes/nextcloud-group-surfaces/specs/data-display/spec.md#requirement-a-group-cell-shows-the-groups-display-name
|
|
24
|
+
*/
|
|
25
|
+
export default {
|
|
26
|
+
name: 'CnGroupNameCell',
|
|
27
|
+
|
|
28
|
+
props: {
|
|
29
|
+
/** The group id to show. */
|
|
30
|
+
gid: {
|
|
31
|
+
type: String,
|
|
32
|
+
required: true,
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
computed: {
|
|
37
|
+
/**
|
|
38
|
+
* The cached display name, or the id while it loads or when unknown.
|
|
39
|
+
*
|
|
40
|
+
* @return {string}
|
|
41
|
+
*/
|
|
42
|
+
label() {
|
|
43
|
+
return groupDisplayName(this.gid) || this.gid
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
watch: {
|
|
48
|
+
gid: {
|
|
49
|
+
immediate: true,
|
|
50
|
+
/**
|
|
51
|
+
* Ask for the name of a new id (cached, so once per id per page).
|
|
52
|
+
*
|
|
53
|
+
* @param {string} gid The group id.
|
|
54
|
+
*/
|
|
55
|
+
handler(gid) {
|
|
56
|
+
loadGroupDisplayName(gid)
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
}
|
|
61
|
+
</script>
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
:aria-pressed="String(Boolean(activeView && activeView.key === view.key))"
|
|
30
30
|
:data-testid="`cn-chart-widget-view-${view.key}`"
|
|
31
31
|
@click="activeViewKey = view.key">
|
|
32
|
-
{{ view.label
|
|
32
|
+
{{ view.label ? hostTranslate(view.label) : view.key }}
|
|
33
33
|
</button>
|
|
34
34
|
</div>
|
|
35
35
|
<div v-if="showEmptyState" class="cn-chart-widget__empty" data-testid="cn-chart-widget-empty">
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
:height="computedHeight"
|
|
54
54
|
:width="computedWidth"
|
|
55
55
|
:options="mergedOptions"
|
|
56
|
-
:series="
|
|
56
|
+
:series="plottedSeries" />
|
|
57
57
|
</div>
|
|
58
58
|
<div v-else class="cn-chart-widget__fallback">
|
|
59
59
|
<!-- @slot Rendered when the ApexCharts peer dependency is not available (defaults to the unavailableLabel text). -->
|
|
@@ -213,6 +213,11 @@ export default {
|
|
|
213
213
|
* always a ref to inject, even outside a dashboard.
|
|
214
214
|
*/
|
|
215
215
|
cnDashboardDateRange: { default: () => ref(null) },
|
|
216
|
+
/**
|
|
217
|
+
* Host translate function provided by CnAppRoot: manifest-authored
|
|
218
|
+
* view labels and series names are i18n keys (screens-dashboard-i18n).
|
|
219
|
+
*/
|
|
220
|
+
cnTranslate: { default: () => (key) => key },
|
|
216
221
|
},
|
|
217
222
|
|
|
218
223
|
props: {
|
|
@@ -918,6 +923,25 @@ export default {
|
|
|
918
923
|
*
|
|
919
924
|
* @return {Array} The displayed series.
|
|
920
925
|
*/
|
|
926
|
+
/**
|
|
927
|
+
* The displayed series with each series name through the host
|
|
928
|
+
* translate function, so a manifest series named "Revenue" reads in
|
|
929
|
+
* the user's language in the legend and the tooltip. Views still
|
|
930
|
+
* filter on the name as written (`displayedSeries`).
|
|
931
|
+
*
|
|
932
|
+
* @spec openspec/changes/screens-dashboard-i18n/specs/dashboard-page/spec.md#requirement-chart-view-labels-and-series-names-are-translated
|
|
933
|
+
* @return {Array} The series handed to ApexCharts.
|
|
934
|
+
*/
|
|
935
|
+
plottedSeries() {
|
|
936
|
+
const series = this.displayedSeries
|
|
937
|
+
if (!Array.isArray(series)) {
|
|
938
|
+
return series
|
|
939
|
+
}
|
|
940
|
+
return series.map((entry) => (entry && typeof entry === 'object' && typeof entry.name === 'string' && entry.name !== '')
|
|
941
|
+
? { ...entry, name: this.hostTranslate(entry.name) }
|
|
942
|
+
: entry)
|
|
943
|
+
},
|
|
944
|
+
|
|
921
945
|
displayedSeries() {
|
|
922
946
|
const series = this.resolvedSeries
|
|
923
947
|
const view = this.activeView
|
|
@@ -1417,6 +1441,19 @@ export default {
|
|
|
1417
1441
|
},
|
|
1418
1442
|
|
|
1419
1443
|
methods: {
|
|
1444
|
+
/**
|
|
1445
|
+
* A manifest-authored label through the host translate function.
|
|
1446
|
+
*
|
|
1447
|
+
* @spec openspec/changes/screens-dashboard-i18n/specs/dashboard-page/spec.md#requirement-chart-view-labels-and-series-names-are-translated
|
|
1448
|
+
* @param {string} key The label.
|
|
1449
|
+
* @return {string} The translated label.
|
|
1450
|
+
*/
|
|
1451
|
+
hostTranslate(key) {
|
|
1452
|
+
const translate = typeof this.cnTranslate === 'function' ? this.cnTranslate : null
|
|
1453
|
+
const out = translate ? translate(key) : key
|
|
1454
|
+
return (typeof out === 'string' && out !== '') ? out : key
|
|
1455
|
+
},
|
|
1456
|
+
|
|
1420
1457
|
/**
|
|
1421
1458
|
* Re-query the chart's dataSource / endpointSource. Exposed as a
|
|
1422
1459
|
* ref-callable method (B3 canonical refresh mode) AND invoked by the
|