@conduction/nextcloud-vue 2.59.0 → 2.60.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/CnActionsMenu/CnActionsMenu.vue2.js +14 -1
- package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue2.js.map +1 -1
- package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue3.js.map +1 -1
- package/dist/esm/components/CnAppNav/CnAppNav.vue2.js +39 -0
- package/dist/esm/components/CnAppNav/CnAppNav.vue2.js.map +1 -1
- package/dist/esm/components/CnAppNav/CnAppNav.vue3.js +46 -4
- package/dist/esm/components/CnAppNav/CnAppNav.vue3.js.map +1 -1
- package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue2.js +224 -9
- package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue3.js +79 -25
- package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnBannerWidgetForm/CnBannerWidgetForm.vue2.js +42 -3
- package/dist/esm/components/CnBannerWidgetForm/CnBannerWidgetForm.vue2.js.map +1 -1
- package/dist/esm/components/CnBannerWidgetForm/CnBannerWidgetForm.vue3.js +39 -6
- package/dist/esm/components/CnBannerWidgetForm/CnBannerWidgetForm.vue3.js.map +1 -1
- package/dist/esm/components/CnBoardView/CnBoardView.vue2.js +46 -0
- package/dist/esm/components/CnBoardView/CnBoardView.vue2.js.map +1 -1
- package/dist/esm/components/CnBoardView/CnBoardView.vue3.js +11 -4
- package/dist/esm/components/CnBoardView/CnBoardView.vue3.js.map +1 -1
- package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue.js +10 -0
- package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue.js.map +1 -0
- package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue2.js +39 -0
- package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue2.js.map +1 -0
- package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue3.js +16 -0
- package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue3.js.map +1 -0
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js +117 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js.map +1 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js +147 -89
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js.map +1 -1
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue.js +10 -0
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue.js.map +1 -0
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue2.js +259 -0
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue2.js.map +1 -0
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue3.js +131 -0
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue3.js.map +1 -0
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue.js +10 -0
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue.js.map +1 -0
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue2.js +116 -0
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue3.js +24 -0
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +503 -28
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js +300 -142
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue.js +10 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue.js.map +1 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue2.js +237 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue2.js.map +1 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue3.js +120 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue3.js.map +1 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue.js +10 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue.js.map +1 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue2.js +77 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue3.js +27 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue2.js +169 -12
- package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue3.js +15 -7
- package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnHeaderWidgetForm/CnHeaderWidgetForm.vue2.js +37 -3
- package/dist/esm/components/CnHeaderWidgetForm/CnHeaderWidgetForm.vue2.js.map +1 -1
- package/dist/esm/components/CnHeaderWidgetForm/CnHeaderWidgetForm.vue3.js +44 -16
- package/dist/esm/components/CnHeaderWidgetForm/CnHeaderWidgetForm.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +132 -3
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +6 -3
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue.js +10 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue.js.map +1 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue2.js +150 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue2.js.map +1 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue3.js +106 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue3.js.map +1 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue.js +9 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue.js.map +1 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue2.js +47 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue3.js +17 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue2.js +49 -0
- package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectDataWidgetForm/CnObjectDataWidgetForm.vue2.js +6 -0
- package/dist/esm/components/CnObjectDataWidgetForm/CnObjectDataWidgetForm.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectDataWidgetForm/CnObjectDataWidgetForm.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectKanban/CnObjectKanban.vue2.js +46 -0
- package/dist/esm/components/CnObjectKanban/CnObjectKanban.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectKanban/CnObjectKanban.vue3.js +15 -3
- package/dist/esm/components/CnObjectKanban/CnObjectKanban.vue3.js.map +1 -1
- package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue2.js +37 -1
- package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue2.js.map +1 -1
- package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue3.js +29 -13
- package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue3.js.map +1 -1
- package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue2.js +50 -3
- package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue2.js.map +1 -1
- package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue3.js.map +1 -1
- package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue.js +10 -0
- package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue.js.map +1 -0
- package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue2.js +186 -0
- package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue2.js.map +1 -0
- package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue3.js +46 -0
- package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue3.js.map +1 -0
- package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue.js +11 -0
- package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue.js.map +1 -0
- package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue2.js +298 -0
- package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue3.js +77 -0
- package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue.js +10 -0
- package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue.js.map +1 -0
- package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue2.js +169 -0
- package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue2.js.map +1 -0
- package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue3.js +48 -0
- package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue3.js.map +1 -0
- package/dist/esm/components/CnTabs/CnTab.vue2.js +35 -0
- package/dist/esm/components/CnTabs/CnTab.vue2.js.map +1 -1
- package/dist/esm/components/CnTabs/CnTab.vue3.js.map +1 -1
- package/dist/esm/components/CnTabs/CnTabs.vue2.js +120 -7
- package/dist/esm/components/CnTabs/CnTabs.vue2.js.map +1 -1
- package/dist/esm/components/CnTabs/CnTabs.vue3.js +57 -5
- package/dist/esm/components/CnTabs/CnTabs.vue3.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +59 -4
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js +6 -2
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue.js +10 -0
- package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue.js.map +1 -0
- package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue2.js +484 -0
- package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue3.js +115 -0
- package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue.js +10 -0
- package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue.js.map +1 -0
- package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue2.js +189 -0
- package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue2.js.map +1 -0
- package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue3.js +74 -0
- package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue3.js.map +1 -0
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +82 -8
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
- package/dist/esm/index.js +10 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/l10n/en.json.js +54 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +54 -1
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/nextcloud-vue.css +931 -4
- package/dist/esm/utils/dateVariant.js +124 -0
- package/dist/esm/utils/dateVariant.js.map +1 -0
- package/dist/esm/utils/detailActionModel.js +260 -0
- package/dist/esm/utils/detailActionModel.js.map +1 -0
- package/dist/esm/utils/dueRule.js +84 -0
- package/dist/esm/utils/dueRule.js.map +1 -0
- package/dist/esm/utils/fetchAggregate.js +37 -1
- package/dist/esm/utils/fetchAggregate.js.map +1 -1
- package/dist/esm/utils/fetchFilterCounts.js +186 -0
- package/dist/esm/utils/fetchFilterCounts.js.map +1 -0
- package/dist/esm/utils/libraryWidgetKeys.js +5 -0
- package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
- package/dist/esm/utils/readPath.js +30 -0
- package/dist/esm/utils/readPath.js.map +1 -0
- package/dist/esm/utils/validateManifestV2.compiled.js +2 -2
- package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +14970 -8991
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +931 -4
- package/l10n/en.json +54 -1
- package/l10n/nl.json +54 -1
- package/package.json +1 -1
- package/scripts/.jsdoc-baselines.json +3 -0
- package/src/components/CnActionsMenu/CnActionsMenu.vue +14 -1
- package/src/components/CnAppNav/CnAppNav.md +26 -0
- package/src/components/CnAppNav/CnAppNav.vue +104 -1
- package/src/components/CnBannerWidget/CnBannerWidget.vue +365 -10
- package/src/components/CnBannerWidgetForm/CnBannerWidgetForm.vue +65 -3
- package/src/components/CnBoardView/CnBoardView.vue +77 -0
- package/src/components/CnBrandStripe/CnBrandStripe.md +22 -0
- package/src/components/CnBrandStripe/CnBrandStripe.vue +100 -0
- package/src/components/CnBrandStripe/index.js +4 -0
- package/src/components/CnCellRenderer/CnCellRenderer.vue +207 -1
- package/src/components/CnConversationThread/CnConversationThread.md +51 -0
- package/src/components/CnConversationThread/CnConversationThread.vue +457 -0
- package/src/components/CnConversationThread/CnConversationWidget.vue +144 -0
- package/src/components/CnConversationThread/index.js +4 -0
- package/src/components/CnDetailPage/CnDetailPage.md +16 -0
- package/src/components/CnDetailPage/CnDetailPage.vue +683 -48
- package/src/components/CnDocumentReviewList/CnDocumentReviewList.md +55 -0
- package/src/components/CnDocumentReviewList/CnDocumentReviewList.vue +384 -0
- package/src/components/CnDocumentReviewList/CnDocumentReviewWidget.vue +108 -0
- package/src/components/CnDocumentReviewList/index.js +4 -0
- package/src/components/CnHeaderWidget/CnHeaderWidget.vue +189 -14
- package/src/components/CnHeaderWidgetForm/CnHeaderWidgetForm.vue +53 -3
- package/src/components/CnIndexPage/CnIndexPage.vue +135 -3
- package/src/components/CnNextStepCard/CnNextStepCard.md +40 -0
- package/src/components/CnNextStepCard/CnNextStepCard.vue +319 -0
- package/src/components/CnNextStepCard/CnNextStepWidget.vue +59 -0
- package/src/components/CnNextStepCard/index.js +4 -0
- package/src/components/CnObjectDataWidget/CnObjectDataWidget.vue +49 -0
- package/src/components/CnObjectDataWidgetForm/CnObjectDataWidgetForm.vue +6 -0
- package/src/components/CnObjectKanban/CnObjectKanban.vue +86 -2
- package/src/components/CnQuickFilterBar/CnQuickFilterBar.md +3 -0
- package/src/components/CnQuickFilterBar/CnQuickFilterBar.vue +60 -1
- package/src/components/CnSavedViewsControl/CnSavedViewsControl.vue +50 -3
- package/src/components/CnSegmentedControl/CnSegmentedControl.md +46 -0
- package/src/components/CnSegmentedControl/CnSegmentedControl.vue +291 -0
- package/src/components/CnSegmentedControl/index.js +4 -0
- package/src/components/CnStackedBarWidget/CnStackedBarWidget.md +15 -0
- package/src/components/CnStackedBarWidget/CnStackedBarWidget.vue +414 -0
- package/src/components/CnStackedBarWidget/index.js +14 -0
- package/src/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue +224 -0
- package/src/components/CnStackedBarWidgetForm/index.js +4 -0
- package/src/components/CnTabs/CnTab.vue +35 -0
- package/src/components/CnTabs/CnTabs.vue +244 -10
- package/src/components/CnTabsWidget/CnTabsWidget.vue +63 -4
- package/src/components/CnWeekStripWidget/CnWeekStripWidget.md +31 -0
- package/src/components/CnWeekStripWidget/CnWeekStripWidget.vue +668 -0
- package/src/components/CnWeekStripWidget/index.js +14 -0
- package/src/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue +265 -0
- package/src/components/CnWeekStripWidgetForm/index.js +4 -0
- package/src/components/CnWidgetGrid/registerDashboardWidgets.js +74 -0
- package/src/components/index.js +11 -0
- package/src/css/detail-page.css +47 -0
- package/src/index.js +9 -0
- package/src/schemas/app-manifest-v2.schema.json +389 -1
- package/src/schemas/app-manifest.schema.json +2 -1
- package/src/utils/dateVariant.js +120 -0
- package/src/utils/detailActionModel.js +256 -0
- package/src/utils/dueRule.js +94 -0
- package/src/utils/fetchAggregate.js +36 -0
- package/src/utils/fetchFilterCounts.js +182 -0
- package/src/utils/index.js +1 -0
- package/src/utils/libraryWidgetKeys.js +5 -0
- package/src/utils/readPath.js +27 -0
- package/src/utils/validateManifestV2.compiled.js +2 -2
|
@@ -0,0 +1,484 @@
|
|
|
1
|
+
import { getCanonicalLocale, translate } from '@nextcloud/l10n';
|
|
2
|
+
import { NcLoadingIcon } from '@nextcloud/vue';
|
|
3
|
+
import { dayKey, daysUntil, parseDateValue } from '../../utils/dateVariant.js';
|
|
4
|
+
import { resolveHref, followLinkClick } from '../../utils/linkNavigation.js';
|
|
5
|
+
import { objectFieldValue, objectDisplayName } from '../../utils/objectName.js';
|
|
6
|
+
import { resolveFilterTokens } from '../../utils/resolveFilterTokens.js';
|
|
7
|
+
import { safeHref } from '../../utils/safeHref.js';
|
|
8
|
+
import { compareVisibleWhen } from '../../utils/visibleWhen.js';
|
|
9
|
+
|
|
10
|
+
const DEFAULT_LIMIT = 100;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* CnWeekStripWidget shows the current week as day columns, with the items
|
|
14
|
+
* that fall on each day listed under it. Use it for deadlines, appointments
|
|
15
|
+
* or anything else that has a date and that somebody should see coming.
|
|
16
|
+
*
|
|
17
|
+
* It renders the five working days by default (`days: 7` adds the weekend),
|
|
18
|
+
* highlights today, marks items that are late, and says so when a day has
|
|
19
|
+
* nothing. On a narrow screen the strip scrolls sideways.
|
|
20
|
+
*
|
|
21
|
+
* Items come from an OpenRegister source (one request for the whole week) or
|
|
22
|
+
* from static `items`. Resolved by its registry type key `week-strip`.
|
|
23
|
+
*
|
|
24
|
+
* ```json
|
|
25
|
+
* {
|
|
26
|
+
* "widgetKey": "week-strip",
|
|
27
|
+
* "props": {
|
|
28
|
+
* "content": {
|
|
29
|
+
* "source": { "register": "dossiq", "schema": "case", "filter": { "assignee": "@me" } },
|
|
30
|
+
* "dateField": "deadline",
|
|
31
|
+
* "titleField": "title",
|
|
32
|
+
* "metaFields": ["identifier", "caseType"],
|
|
33
|
+
* "itemRoute": "CaseDetail",
|
|
34
|
+
* "emptyText": "No deadlines"
|
|
35
|
+
* }
|
|
36
|
+
* }
|
|
37
|
+
* }
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
var script = {
|
|
41
|
+
name: 'CnWeekStripWidget',
|
|
42
|
+
|
|
43
|
+
components: { NcLoadingIcon },
|
|
44
|
+
|
|
45
|
+
inject: {
|
|
46
|
+
/**
|
|
47
|
+
* Host translate function provided by CnAppRoot. The manifest-authored
|
|
48
|
+
* `emptyText` and static item texts run through it. Identity by default.
|
|
49
|
+
*/
|
|
50
|
+
cnTranslate: { default: () => (key) => key },
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
props: {
|
|
54
|
+
/**
|
|
55
|
+
* The widget's configuration. `days` is `5` (working days, the
|
|
56
|
+
* default) or `7`. `source` names the OpenRegister register and schema,
|
|
57
|
+
* with an optional `filter` (the shared @-token grammar) and `limit`.
|
|
58
|
+
* `dateField` is the field the items are bucketed by. `titleField` and
|
|
59
|
+
* `metaFields` pick what each item shows. `itemRoute` is the route name
|
|
60
|
+
* an item links to (with the record id as `params.id`). `lateWhen` is a
|
|
61
|
+
* `{ op, value }` rule on the days until the date (default: before
|
|
62
|
+
* today), `lateField` a boolean field that marks a record late.
|
|
63
|
+
* `items` are static entries `{ title, meta?, date, route?, href?, late? }`.
|
|
64
|
+
* `emptyText` is the text of a day without items. `weekOffset` moves
|
|
65
|
+
* the strip whole weeks from the current one.
|
|
66
|
+
*
|
|
67
|
+
* @type {{days?: (5|7), source?: {register?: string, schema?: string, filter?: object, limit?: number}, dateField?: string, titleField?: string, metaFields?: Array<string>, itemRoute?: string, lateWhen?: {op?: string, value?: number}, lateField?: string, items?: Array<{title: string, meta?: string, date: string, route?: (string|object), href?: string, late?: boolean}>, emptyText?: string, weekOffset?: number}}
|
|
68
|
+
*/
|
|
69
|
+
content: {
|
|
70
|
+
type: Object,
|
|
71
|
+
default: () => ({}),
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Translate function. Falls back to the injected `cnTranslate`. Pass it
|
|
76
|
+
* when mounting the widget outside a CnAppRoot.
|
|
77
|
+
*
|
|
78
|
+
* @type {((key: string) => string)|null}
|
|
79
|
+
*/
|
|
80
|
+
translate: {
|
|
81
|
+
type: Function,
|
|
82
|
+
default: null,
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* The moment the strip treats as "now". Leave empty for the current
|
|
87
|
+
* time; set it to render another week or to test.
|
|
88
|
+
*
|
|
89
|
+
* @type {Date|null}
|
|
90
|
+
*/
|
|
91
|
+
now: {
|
|
92
|
+
type: Date,
|
|
93
|
+
default: null,
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
data() {
|
|
98
|
+
return {
|
|
99
|
+
rows: [],
|
|
100
|
+
loading: false,
|
|
101
|
+
error: '',
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
computed: {
|
|
106
|
+
/**
|
|
107
|
+
* The translate function in use.
|
|
108
|
+
*
|
|
109
|
+
* @return {(key: string) => string}
|
|
110
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget
|
|
111
|
+
*/
|
|
112
|
+
effectiveTranslate() {
|
|
113
|
+
return this.translate ?? this.cnTranslate
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* The reference moment.
|
|
118
|
+
*
|
|
119
|
+
* @return {Date}
|
|
120
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget
|
|
121
|
+
*/
|
|
122
|
+
reference() {
|
|
123
|
+
return this.now instanceof Date ? this.now : new Date()
|
|
124
|
+
},
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* How many day columns render: 7, or 5 for anything else.
|
|
128
|
+
*
|
|
129
|
+
* @return {number}
|
|
130
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget
|
|
131
|
+
*/
|
|
132
|
+
dayCount() {
|
|
133
|
+
return Number(this.content.days) === 7 ? 7 : 5
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* The days of the strip, Monday first.
|
|
138
|
+
*
|
|
139
|
+
* @return {Array<Date>}
|
|
140
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget
|
|
141
|
+
*/
|
|
142
|
+
weekDays() {
|
|
143
|
+
const ref = this.reference;
|
|
144
|
+
const offset = Number.isInteger(this.content.weekOffset) ? this.content.weekOffset : 0;
|
|
145
|
+
const mondayDelta = (ref.getDay() + 6) % 7;
|
|
146
|
+
const days = [];
|
|
147
|
+
for (let i = 0; i < this.dayCount; i++) {
|
|
148
|
+
days.push(new Date(ref.getFullYear(), ref.getMonth(), ref.getDate() - mondayDelta + (offset * 7) + i));
|
|
149
|
+
}
|
|
150
|
+
return days
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* The field the items are bucketed by.
|
|
155
|
+
*
|
|
156
|
+
* @return {string}
|
|
157
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget
|
|
158
|
+
*/
|
|
159
|
+
dateField() {
|
|
160
|
+
return typeof this.content.dateField === 'string' ? this.content.dateField : ''
|
|
161
|
+
},
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Whether the items come from OpenRegister.
|
|
165
|
+
*
|
|
166
|
+
* @return {boolean}
|
|
167
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget
|
|
168
|
+
*/
|
|
169
|
+
hasSource() {
|
|
170
|
+
const s = this.content.source || {};
|
|
171
|
+
return Boolean(s.register && s.schema && this.dateField)
|
|
172
|
+
},
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Every item, from the source rows or the static list, in one shape.
|
|
176
|
+
*
|
|
177
|
+
* @return {Array<{key: string, title: string, meta: string, date: (Date|null), late: boolean, href: string, target: (object|string|null)}>}
|
|
178
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget
|
|
179
|
+
*/
|
|
180
|
+
normalizedItems() {
|
|
181
|
+
if (this.hasSource) {
|
|
182
|
+
return this.rows.map((row, index) => this.itemFromRow(row, index))
|
|
183
|
+
}
|
|
184
|
+
const items = Array.isArray(this.content.items) ? this.content.items : [];
|
|
185
|
+
return items
|
|
186
|
+
.filter((item) => item && typeof item === 'object')
|
|
187
|
+
.map((item, index) => this.itemFromStatic(item, index))
|
|
188
|
+
},
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* The columns: one per day, each with its items.
|
|
192
|
+
*
|
|
193
|
+
* @return {Array<{key: string, label: string, today: boolean, items: Array<object>}>}
|
|
194
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget
|
|
195
|
+
*/
|
|
196
|
+
dayColumns() {
|
|
197
|
+
const todayKey = dayKey(this.reference);
|
|
198
|
+
const buckets = {};
|
|
199
|
+
for (const item of this.normalizedItems) {
|
|
200
|
+
if (item.date === null) {
|
|
201
|
+
continue
|
|
202
|
+
}
|
|
203
|
+
const key = dayKey(item.date)
|
|
204
|
+
;(buckets[key] = buckets[key] || []).push(item);
|
|
205
|
+
}
|
|
206
|
+
const formatter = this.dayFormatter;
|
|
207
|
+
return this.weekDays.map((day) => {
|
|
208
|
+
const key = dayKey(day);
|
|
209
|
+
return {
|
|
210
|
+
key,
|
|
211
|
+
label: formatter.format(day),
|
|
212
|
+
today: key === todayKey,
|
|
213
|
+
items: buckets[key] || [],
|
|
214
|
+
}
|
|
215
|
+
})
|
|
216
|
+
},
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Formats a day as a short weekday and a day number ("Mon 5").
|
|
220
|
+
*
|
|
221
|
+
* @return {Intl.DateTimeFormat}
|
|
222
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget
|
|
223
|
+
*/
|
|
224
|
+
dayFormatter() {
|
|
225
|
+
let locale;
|
|
226
|
+
try {
|
|
227
|
+
locale = getCanonicalLocale();
|
|
228
|
+
} catch {
|
|
229
|
+
locale = undefined;
|
|
230
|
+
}
|
|
231
|
+
try {
|
|
232
|
+
return new Intl.DateTimeFormat(locale || undefined, { weekday: 'short', day: 'numeric' })
|
|
233
|
+
} catch {
|
|
234
|
+
return new Intl.DateTimeFormat(undefined, { weekday: 'short', day: 'numeric' })
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* The text of a day without items.
|
|
240
|
+
*
|
|
241
|
+
* @return {string}
|
|
242
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget
|
|
243
|
+
*/
|
|
244
|
+
emptyLabel() {
|
|
245
|
+
const text = this.content.emptyText;
|
|
246
|
+
return (typeof text === 'string' && text !== '')
|
|
247
|
+
? this.effectiveTranslate(text)
|
|
248
|
+
: translate('nextcloud-vue', 'Nothing planned')
|
|
249
|
+
},
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* @return {string} The badge on today's column.
|
|
253
|
+
*
|
|
254
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget
|
|
255
|
+
*/
|
|
256
|
+
todayLabel() {
|
|
257
|
+
return translate('nextcloud-vue', 'today')
|
|
258
|
+
},
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* @return {string} The marker on a late item.
|
|
262
|
+
*
|
|
263
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget
|
|
264
|
+
*/
|
|
265
|
+
lateLabel() {
|
|
266
|
+
return translate('nextcloud-vue', 'Late')
|
|
267
|
+
},
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* @return {string} The accessible name of the scrolling region.
|
|
271
|
+
*
|
|
272
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget
|
|
273
|
+
*/
|
|
274
|
+
regionLabel() {
|
|
275
|
+
return translate('nextcloud-vue', 'This week, day by day')
|
|
276
|
+
},
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* @return {string} The loading text.
|
|
280
|
+
*
|
|
281
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget
|
|
282
|
+
*/
|
|
283
|
+
loadingLabel() {
|
|
284
|
+
return translate('nextcloud-vue', 'Loading…')
|
|
285
|
+
},
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* @return {string} The text shown when the items could not be loaded.
|
|
289
|
+
*
|
|
290
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget
|
|
291
|
+
*/
|
|
292
|
+
errorLabel() {
|
|
293
|
+
return translate('nextcloud-vue', 'The items for this week could not be loaded.')
|
|
294
|
+
},
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Changes whenever a new fetch is needed.
|
|
298
|
+
*
|
|
299
|
+
* @return {string}
|
|
300
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget
|
|
301
|
+
*/
|
|
302
|
+
sourceKey() {
|
|
303
|
+
return JSON.stringify({
|
|
304
|
+
s: this.content.source || {},
|
|
305
|
+
f: this.dateField,
|
|
306
|
+
d: this.weekDays.length > 0 ? [dayKey(this.weekDays[0]), this.weekDays.length] : [],
|
|
307
|
+
})
|
|
308
|
+
},
|
|
309
|
+
},
|
|
310
|
+
|
|
311
|
+
watch: {
|
|
312
|
+
/** @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget */
|
|
313
|
+
sourceKey() {
|
|
314
|
+
this.fetchItems();
|
|
315
|
+
},
|
|
316
|
+
},
|
|
317
|
+
|
|
318
|
+
mounted() {
|
|
319
|
+
this.fetchItems();
|
|
320
|
+
},
|
|
321
|
+
|
|
322
|
+
methods: {
|
|
323
|
+
/**
|
|
324
|
+
* Whether a date counts as late under `content.lateWhen` (default:
|
|
325
|
+
* before today).
|
|
326
|
+
*
|
|
327
|
+
* @param {Date|null} date The item's date.
|
|
328
|
+
* @return {boolean}
|
|
329
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget
|
|
330
|
+
*/
|
|
331
|
+
isLateDate(date) {
|
|
332
|
+
if (date === null) {
|
|
333
|
+
return false
|
|
334
|
+
}
|
|
335
|
+
const rule = (this.content.lateWhen && typeof this.content.lateWhen === 'object')
|
|
336
|
+
? this.content.lateWhen
|
|
337
|
+
: { op: 'lt', value: 0 };
|
|
338
|
+
return compareVisibleWhen(daysUntil(date, this.reference), rule.op || 'lt', rule.value ?? 0)
|
|
339
|
+
},
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* One OpenRegister record as a strip item.
|
|
343
|
+
*
|
|
344
|
+
* @param {object} row The record.
|
|
345
|
+
* @param {number} index Its position, used as a key of last resort.
|
|
346
|
+
* @return {object} The item.
|
|
347
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget
|
|
348
|
+
*/
|
|
349
|
+
itemFromRow(row, index) {
|
|
350
|
+
const c = this.content;
|
|
351
|
+
const id = row && (row.id || (row['@self'] && row['@self'].id));
|
|
352
|
+
const date = parseDateValue(objectFieldValue(row, this.dateField));
|
|
353
|
+
const titleValue = c.titleField ? objectFieldValue(row, c.titleField) : undefined;
|
|
354
|
+
const title = (titleValue !== undefined && titleValue !== null && titleValue !== '')
|
|
355
|
+
? String(titleValue)
|
|
356
|
+
: objectDisplayName(row);
|
|
357
|
+
const metaFields = Array.isArray(c.metaFields) ? c.metaFields : [];
|
|
358
|
+
const meta = metaFields
|
|
359
|
+
.map((field) => objectFieldValue(row, field))
|
|
360
|
+
.filter((value) => value !== undefined && value !== null && value !== '' && typeof value !== 'object')
|
|
361
|
+
.map(String)
|
|
362
|
+
.join(' · ');
|
|
363
|
+
const flagged = c.lateField ? objectFieldValue(row, c.lateField) === true : false;
|
|
364
|
+
const target = (c.itemRoute && id) ? { name: c.itemRoute, params: { id } } : null;
|
|
365
|
+
return {
|
|
366
|
+
key: String(id || `row-${index}`),
|
|
367
|
+
title,
|
|
368
|
+
meta,
|
|
369
|
+
date,
|
|
370
|
+
late: flagged || this.isLateDate(date),
|
|
371
|
+
target,
|
|
372
|
+
href: target ? resolveHref(target, this.$router) : '',
|
|
373
|
+
}
|
|
374
|
+
},
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* One static manifest entry as a strip item.
|
|
378
|
+
*
|
|
379
|
+
* @param {object} item The entry.
|
|
380
|
+
* @param {number} index Its position.
|
|
381
|
+
* @return {object} The item.
|
|
382
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget
|
|
383
|
+
*/
|
|
384
|
+
itemFromStatic(item, index) {
|
|
385
|
+
const date = parseDateValue(item.date);
|
|
386
|
+
let target = null;
|
|
387
|
+
let href = '';
|
|
388
|
+
if (item.route) {
|
|
389
|
+
target = typeof item.route === 'string' ? { name: item.route } : item.route;
|
|
390
|
+
href = resolveHref(target, this.$router);
|
|
391
|
+
} else if (typeof item.href === 'string' && item.href !== '') {
|
|
392
|
+
const safe = safeHref(item.href);
|
|
393
|
+
href = safe === '#' ? '' : safe;
|
|
394
|
+
}
|
|
395
|
+
return {
|
|
396
|
+
key: `item-${index}`,
|
|
397
|
+
title: typeof item.title === 'string' ? this.effectiveTranslate(item.title) : '',
|
|
398
|
+
meta: typeof item.meta === 'string' ? this.effectiveTranslate(item.meta) : '',
|
|
399
|
+
date,
|
|
400
|
+
late: item.late === true || (item.late !== false && this.isLateDate(date)),
|
|
401
|
+
target,
|
|
402
|
+
href,
|
|
403
|
+
}
|
|
404
|
+
},
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Load the week's records in one request.
|
|
408
|
+
*
|
|
409
|
+
* @return {Promise<void>}
|
|
410
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget
|
|
411
|
+
*/
|
|
412
|
+
async fetchItems() {
|
|
413
|
+
if (!this.hasSource) {
|
|
414
|
+
this.rows = [];
|
|
415
|
+
this.error = '';
|
|
416
|
+
return
|
|
417
|
+
}
|
|
418
|
+
const s = this.content.source;
|
|
419
|
+
const requestKey = this.sourceKey;
|
|
420
|
+
const first = this.weekDays[0];
|
|
421
|
+
const last = this.weekDays[this.weekDays.length - 1];
|
|
422
|
+
const dayAfter = new Date(last.getFullYear(), last.getMonth(), last.getDate() + 1);
|
|
423
|
+
this.loading = true;
|
|
424
|
+
this.error = '';
|
|
425
|
+
try {
|
|
426
|
+
const [{ default: axios }, { generateUrl }] = await Promise.all([
|
|
427
|
+
import('@nextcloud/axios'),
|
|
428
|
+
import('@nextcloud/router'),
|
|
429
|
+
]);
|
|
430
|
+
const url = generateUrl(
|
|
431
|
+
'/apps/openregister/api/objects/{register}/{schema}',
|
|
432
|
+
{ register: s.register, schema: s.schema },
|
|
433
|
+
);
|
|
434
|
+
const params = {
|
|
435
|
+
_limit: Number.isInteger(s.limit) && s.limit > 0 ? s.limit : DEFAULT_LIMIT,
|
|
436
|
+
[`_order[${this.dateField}]`]: 'asc',
|
|
437
|
+
};
|
|
438
|
+
const filter = resolveFilterTokens(s.filter || {}, {});
|
|
439
|
+
for (const [k, v] of Object.entries(filter || {})) {
|
|
440
|
+
if (v && typeof v === 'object') {
|
|
441
|
+
for (const [op, ov] of Object.entries(v)) {
|
|
442
|
+
params[`${k}[${op}]`] = ov;
|
|
443
|
+
}
|
|
444
|
+
} else if (v !== '' && v !== null && v !== undefined) {
|
|
445
|
+
params[k] = v;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
// The week window goes last, so a manifest filter on the date
|
|
449
|
+
// field cannot widen the strip beyond the days it shows.
|
|
450
|
+
params[`${this.dateField}[gte]`] = dayKey(first);
|
|
451
|
+
params[`${this.dateField}[lt]`] = dayKey(dayAfter);
|
|
452
|
+
const res = await axios.get(url, { params });
|
|
453
|
+
if (requestKey !== this.sourceKey) {
|
|
454
|
+
return
|
|
455
|
+
}
|
|
456
|
+
this.rows = (res && res.data && Array.isArray(res.data.results)) ? res.data.results : [];
|
|
457
|
+
} catch (e) {
|
|
458
|
+
// eslint-disable-next-line no-console
|
|
459
|
+
console.warn('[CnWeekStripWidget] failed to load items:', e);
|
|
460
|
+
this.error = (e && e.message) || 'error';
|
|
461
|
+
this.rows = [];
|
|
462
|
+
} finally {
|
|
463
|
+
this.loading = false;
|
|
464
|
+
}
|
|
465
|
+
},
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Route a plain click on an in-app item; the browser handles the rest.
|
|
469
|
+
*
|
|
470
|
+
* @param {MouseEvent} event The click.
|
|
471
|
+
* @param {object} item The clicked item.
|
|
472
|
+
* @return {void}
|
|
473
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget
|
|
474
|
+
*/
|
|
475
|
+
onItemClick(event, item) {
|
|
476
|
+
if (item.target) {
|
|
477
|
+
followLinkClick(event, item.target, this.$router);
|
|
478
|
+
}
|
|
479
|
+
},
|
|
480
|
+
},
|
|
481
|
+
};
|
|
482
|
+
|
|
483
|
+
export { script as default };
|
|
484
|
+
//# sourceMappingURL=CnWeekStripWidget.vue2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CnWeekStripWidget.vue2.js","sources":["../../../../src/components/CnWeekStripWidget/CnWeekStripWidget.vue"],"sourcesContent":["<!--\n SPDX-FileCopyrightText: 2026 Conduction B.V.\n SPDX-License-Identifier: EUPL-1.2\n-->\n<template>\n\t<div class=\"cn-week-strip\" data-testid=\"cn-week-strip\">\n\t\t<div v-if=\"loading\" class=\"cn-week-strip__state\" role=\"status\">\n\t\t\t<NcLoadingIcon :size=\"20\" />\n\t\t\t<span class=\"cn-week-strip__state-text\">{{ loadingLabel }}</span>\n\t\t</div>\n\t\t<p v-else-if=\"error\" class=\"cn-week-strip__state\" role=\"status\">\n\t\t\t{{ errorLabel }}\n\t\t</p>\n\t\t<!-- A scroll container a keyboard user cannot focus cannot be scrolled,\n\t\t so the region is focusable and named. -->\n\t\t<div\n\t\t\tv-else\n\t\t\tclass=\"cn-week-strip__scroll\"\n\t\t\trole=\"region\"\n\t\t\ttabindex=\"0\"\n\t\t\t:aria-label=\"regionLabel\">\n\t\t\t<ol class=\"cn-week-strip__days\" :style=\"{ '--cn-week-strip-columns': dayColumns.length }\">\n\t\t\t\t<li\n\t\t\t\t\tv-for=\"day in dayColumns\"\n\t\t\t\t\t:key=\"day.key\"\n\t\t\t\t\tclass=\"cn-week-strip__day\"\n\t\t\t\t\t:class=\"{ 'cn-week-strip__day--today': day.today }\"\n\t\t\t\t\t:aria-current=\"day.today ? 'date' : null\"\n\t\t\t\t\t:data-day=\"day.key\">\n\t\t\t\t\t<span class=\"cn-week-strip__head\">\n\t\t\t\t\t\t<span class=\"cn-week-strip__label\">{{ day.label }}</span>\n\t\t\t\t\t\t<span v-if=\"day.today\" class=\"cn-week-strip__today\">{{ todayLabel }}</span>\n\t\t\t\t\t</span>\n\t\t\t\t\t<ul v-if=\"day.items.length > 0\" class=\"cn-week-strip__items\">\n\t\t\t\t\t\t<li v-for=\"item in day.items\" :key=\"item.key\" class=\"cn-week-strip__item-row\">\n\t\t\t\t\t\t\t<component\n\t\t\t\t\t\t\t\t:is=\"item.href ? 'a' : 'div'\"\n\t\t\t\t\t\t\t\tclass=\"cn-week-strip__item\"\n\t\t\t\t\t\t\t\t:class=\"{ 'cn-week-strip__item--late': item.late, 'cn-week-strip__item--link': !!item.href }\"\n\t\t\t\t\t\t\t\t:href=\"item.href || null\"\n\t\t\t\t\t\t\t\tdata-testid=\"cn-week-strip-item\"\n\t\t\t\t\t\t\t\t@click=\"onItemClick($event, item)\">\n\t\t\t\t\t\t\t\t<strong class=\"cn-week-strip__title\">{{ item.title }}</strong>\n\t\t\t\t\t\t\t\t<span v-if=\"item.meta\" class=\"cn-week-strip__meta\">{{ item.meta }}</span>\n\t\t\t\t\t\t\t\t<span v-if=\"item.late\" class=\"cn-week-strip__late\">{{ lateLabel }}</span>\n\t\t\t\t\t\t\t</component>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t\t<span v-else class=\"cn-week-strip__empty\">{{ emptyLabel }}</span>\n\t\t\t\t</li>\n\t\t\t</ol>\n\t\t</div>\n\t</div>\n</template>\n\n<script>\nimport { getCanonicalLocale, translate as t } from '@nextcloud/l10n'\nimport { NcLoadingIcon } from '@nextcloud/vue'\nimport { dayKey, daysUntil, parseDateValue } from '../../utils/dateVariant.js'\nimport { followLinkClick, resolveHref } from '../../utils/linkNavigation.js'\nimport { objectDisplayName, objectFieldValue } from '../../utils/objectName.js'\nimport { resolveFilterTokens } from '../../utils/resolveFilterTokens.js'\nimport { safeHref } from '../../utils/safeHref.js'\nimport { compareVisibleWhen } from '../../utils/visibleWhen.js'\n\nconst DEFAULT_LIMIT = 100\n\n/**\n * CnWeekStripWidget shows the current week as day columns, with the items\n * that fall on each day listed under it. Use it for deadlines, appointments\n * or anything else that has a date and that somebody should see coming.\n *\n * It renders the five working days by default (`days: 7` adds the weekend),\n * highlights today, marks items that are late, and says so when a day has\n * nothing. On a narrow screen the strip scrolls sideways.\n *\n * Items come from an OpenRegister source (one request for the whole week) or\n * from static `items`. Resolved by its registry type key `week-strip`.\n *\n * ```json\n * {\n * \"widgetKey\": \"week-strip\",\n * \"props\": {\n * \"content\": {\n * \"source\": { \"register\": \"dossiq\", \"schema\": \"case\", \"filter\": { \"assignee\": \"@me\" } },\n * \"dateField\": \"deadline\",\n * \"titleField\": \"title\",\n * \"metaFields\": [\"identifier\", \"caseType\"],\n * \"itemRoute\": \"CaseDetail\",\n * \"emptyText\": \"No deadlines\"\n * }\n * }\n * }\n * ```\n */\nexport default {\n\tname: 'CnWeekStripWidget',\n\n\tcomponents: { NcLoadingIcon },\n\n\tinject: {\n\t\t/**\n\t\t * Host translate function provided by CnAppRoot. The manifest-authored\n\t\t * `emptyText` and static item texts run through it. Identity by default.\n\t\t */\n\t\tcnTranslate: { default: () => (key) => key },\n\t},\n\n\tprops: {\n\t\t/**\n\t\t * The widget's configuration. `days` is `5` (working days, the\n\t\t * default) or `7`. `source` names the OpenRegister register and schema,\n\t\t * with an optional `filter` (the shared @-token grammar) and `limit`.\n\t\t * `dateField` is the field the items are bucketed by. `titleField` and\n\t\t * `metaFields` pick what each item shows. `itemRoute` is the route name\n\t\t * an item links to (with the record id as `params.id`). `lateWhen` is a\n\t\t * `{ op, value }` rule on the days until the date (default: before\n\t\t * today), `lateField` a boolean field that marks a record late.\n\t\t * `items` are static entries `{ title, meta?, date, route?, href?, late? }`.\n\t\t * `emptyText` is the text of a day without items. `weekOffset` moves\n\t\t * the strip whole weeks from the current one.\n\t\t *\n\t\t * @type {{days?: (5|7), source?: {register?: string, schema?: string, filter?: object, limit?: number}, dateField?: string, titleField?: string, metaFields?: Array<string>, itemRoute?: string, lateWhen?: {op?: string, value?: number}, lateField?: string, items?: Array<{title: string, meta?: string, date: string, route?: (string|object), href?: string, late?: boolean}>, emptyText?: string, weekOffset?: number}}\n\t\t */\n\t\tcontent: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/**\n\t\t * Translate function. Falls back to the injected `cnTranslate`. Pass it\n\t\t * when mounting the widget outside a CnAppRoot.\n\t\t *\n\t\t * @type {((key: string) => string)|null}\n\t\t */\n\t\ttranslate: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * The moment the strip treats as \"now\". Leave empty for the current\n\t\t * time; set it to render another week or to test.\n\t\t *\n\t\t * @type {Date|null}\n\t\t */\n\t\tnow: {\n\t\t\ttype: Date,\n\t\t\tdefault: null,\n\t\t},\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\trows: [],\n\t\t\tloading: false,\n\t\t\terror: '',\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The translate function in use.\n\t\t *\n\t\t * @return {(key: string) => string}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget\n\t\t */\n\t\teffectiveTranslate() {\n\t\t\treturn this.translate ?? this.cnTranslate\n\t\t},\n\n\t\t/**\n\t\t * The reference moment.\n\t\t *\n\t\t * @return {Date}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget\n\t\t */\n\t\treference() {\n\t\t\treturn this.now instanceof Date ? this.now : new Date()\n\t\t},\n\n\t\t/**\n\t\t * How many day columns render: 7, or 5 for anything else.\n\t\t *\n\t\t * @return {number}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget\n\t\t */\n\t\tdayCount() {\n\t\t\treturn Number(this.content.days) === 7 ? 7 : 5\n\t\t},\n\n\t\t/**\n\t\t * The days of the strip, Monday first.\n\t\t *\n\t\t * @return {Array<Date>}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget\n\t\t */\n\t\tweekDays() {\n\t\t\tconst ref = this.reference\n\t\t\tconst offset = Number.isInteger(this.content.weekOffset) ? this.content.weekOffset : 0\n\t\t\tconst mondayDelta = (ref.getDay() + 6) % 7\n\t\t\tconst days = []\n\t\t\tfor (let i = 0; i < this.dayCount; i++) {\n\t\t\t\tdays.push(new Date(ref.getFullYear(), ref.getMonth(), ref.getDate() - mondayDelta + (offset * 7) + i))\n\t\t\t}\n\t\t\treturn days\n\t\t},\n\n\t\t/**\n\t\t * The field the items are bucketed by.\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget\n\t\t */\n\t\tdateField() {\n\t\t\treturn typeof this.content.dateField === 'string' ? this.content.dateField : ''\n\t\t},\n\n\t\t/**\n\t\t * Whether the items come from OpenRegister.\n\t\t *\n\t\t * @return {boolean}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget\n\t\t */\n\t\thasSource() {\n\t\t\tconst s = this.content.source || {}\n\t\t\treturn Boolean(s.register && s.schema && this.dateField)\n\t\t},\n\n\t\t/**\n\t\t * Every item, from the source rows or the static list, in one shape.\n\t\t *\n\t\t * @return {Array<{key: string, title: string, meta: string, date: (Date|null), late: boolean, href: string, target: (object|string|null)}>}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget\n\t\t */\n\t\tnormalizedItems() {\n\t\t\tif (this.hasSource) {\n\t\t\t\treturn this.rows.map((row, index) => this.itemFromRow(row, index))\n\t\t\t}\n\t\t\tconst items = Array.isArray(this.content.items) ? this.content.items : []\n\t\t\treturn items\n\t\t\t\t.filter((item) => item && typeof item === 'object')\n\t\t\t\t.map((item, index) => this.itemFromStatic(item, index))\n\t\t},\n\n\t\t/**\n\t\t * The columns: one per day, each with its items.\n\t\t *\n\t\t * @return {Array<{key: string, label: string, today: boolean, items: Array<object>}>}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget\n\t\t */\n\t\tdayColumns() {\n\t\t\tconst todayKey = dayKey(this.reference)\n\t\t\tconst buckets = {}\n\t\t\tfor (const item of this.normalizedItems) {\n\t\t\t\tif (item.date === null) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst key = dayKey(item.date)\n\t\t\t\t;(buckets[key] = buckets[key] || []).push(item)\n\t\t\t}\n\t\t\tconst formatter = this.dayFormatter\n\t\t\treturn this.weekDays.map((day) => {\n\t\t\t\tconst key = dayKey(day)\n\t\t\t\treturn {\n\t\t\t\t\tkey,\n\t\t\t\t\tlabel: formatter.format(day),\n\t\t\t\t\ttoday: key === todayKey,\n\t\t\t\t\titems: buckets[key] || [],\n\t\t\t\t}\n\t\t\t})\n\t\t},\n\n\t\t/**\n\t\t * Formats a day as a short weekday and a day number (\"Mon 5\").\n\t\t *\n\t\t * @return {Intl.DateTimeFormat}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget\n\t\t */\n\t\tdayFormatter() {\n\t\t\tlet locale\n\t\t\ttry {\n\t\t\t\tlocale = getCanonicalLocale()\n\t\t\t} catch {\n\t\t\t\tlocale = undefined\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn new Intl.DateTimeFormat(locale || undefined, { weekday: 'short', day: 'numeric' })\n\t\t\t} catch {\n\t\t\t\treturn new Intl.DateTimeFormat(undefined, { weekday: 'short', day: 'numeric' })\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * The text of a day without items.\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget\n\t\t */\n\t\temptyLabel() {\n\t\t\tconst text = this.content.emptyText\n\t\t\treturn (typeof text === 'string' && text !== '')\n\t\t\t\t? this.effectiveTranslate(text)\n\t\t\t\t: t('nextcloud-vue', 'Nothing planned')\n\t\t},\n\n\t\t/**\n\t\t * @return {string} The badge on today's column.\n\t\t *\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget\n\t\t */\n\t\ttodayLabel() {\n\t\t\treturn t('nextcloud-vue', 'today')\n\t\t},\n\n\t\t/**\n\t\t * @return {string} The marker on a late item.\n\t\t *\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget\n\t\t */\n\t\tlateLabel() {\n\t\t\treturn t('nextcloud-vue', 'Late')\n\t\t},\n\n\t\t/**\n\t\t * @return {string} The accessible name of the scrolling region.\n\t\t *\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget\n\t\t */\n\t\tregionLabel() {\n\t\t\treturn t('nextcloud-vue', 'This week, day by day')\n\t\t},\n\n\t\t/**\n\t\t * @return {string} The loading text.\n\t\t *\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget\n\t\t */\n\t\tloadingLabel() {\n\t\t\treturn t('nextcloud-vue', 'Loading…')\n\t\t},\n\n\t\t/**\n\t\t * @return {string} The text shown when the items could not be loaded.\n\t\t *\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget\n\t\t */\n\t\terrorLabel() {\n\t\t\treturn t('nextcloud-vue', 'The items for this week could not be loaded.')\n\t\t},\n\n\t\t/**\n\t\t * Changes whenever a new fetch is needed.\n\t\t *\n\t\t * @return {string}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget\n\t\t */\n\t\tsourceKey() {\n\t\t\treturn JSON.stringify({\n\t\t\t\ts: this.content.source || {},\n\t\t\t\tf: this.dateField,\n\t\t\t\td: this.weekDays.length > 0 ? [dayKey(this.weekDays[0]), this.weekDays.length] : [],\n\t\t\t})\n\t\t},\n\t},\n\n\twatch: {\n\t\t/** @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget */\n\t\tsourceKey() {\n\t\t\tthis.fetchItems()\n\t\t},\n\t},\n\n\tmounted() {\n\t\tthis.fetchItems()\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Whether a date counts as late under `content.lateWhen` (default:\n\t\t * before today).\n\t\t *\n\t\t * @param {Date|null} date The item's date.\n\t\t * @return {boolean}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget\n\t\t */\n\t\tisLateDate(date) {\n\t\t\tif (date === null) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tconst rule = (this.content.lateWhen && typeof this.content.lateWhen === 'object')\n\t\t\t\t? this.content.lateWhen\n\t\t\t\t: { op: 'lt', value: 0 }\n\t\t\treturn compareVisibleWhen(daysUntil(date, this.reference), rule.op || 'lt', rule.value ?? 0)\n\t\t},\n\n\t\t/**\n\t\t * One OpenRegister record as a strip item.\n\t\t *\n\t\t * @param {object} row The record.\n\t\t * @param {number} index Its position, used as a key of last resort.\n\t\t * @return {object} The item.\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget\n\t\t */\n\t\titemFromRow(row, index) {\n\t\t\tconst c = this.content\n\t\t\tconst id = row && (row.id || (row['@self'] && row['@self'].id))\n\t\t\tconst date = parseDateValue(objectFieldValue(row, this.dateField))\n\t\t\tconst titleValue = c.titleField ? objectFieldValue(row, c.titleField) : undefined\n\t\t\tconst title = (titleValue !== undefined && titleValue !== null && titleValue !== '')\n\t\t\t\t? String(titleValue)\n\t\t\t\t: objectDisplayName(row)\n\t\t\tconst metaFields = Array.isArray(c.metaFields) ? c.metaFields : []\n\t\t\tconst meta = metaFields\n\t\t\t\t.map((field) => objectFieldValue(row, field))\n\t\t\t\t.filter((value) => value !== undefined && value !== null && value !== '' && typeof value !== 'object')\n\t\t\t\t.map(String)\n\t\t\t\t.join(' · ')\n\t\t\tconst flagged = c.lateField ? objectFieldValue(row, c.lateField) === true : false\n\t\t\tconst target = (c.itemRoute && id) ? { name: c.itemRoute, params: { id } } : null\n\t\t\treturn {\n\t\t\t\tkey: String(id || `row-${index}`),\n\t\t\t\ttitle,\n\t\t\t\tmeta,\n\t\t\t\tdate,\n\t\t\t\tlate: flagged || this.isLateDate(date),\n\t\t\t\ttarget,\n\t\t\t\thref: target ? resolveHref(target, this.$router) : '',\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * One static manifest entry as a strip item.\n\t\t *\n\t\t * @param {object} item The entry.\n\t\t * @param {number} index Its position.\n\t\t * @return {object} The item.\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget\n\t\t */\n\t\titemFromStatic(item, index) {\n\t\t\tconst date = parseDateValue(item.date)\n\t\t\tlet target = null\n\t\t\tlet href = ''\n\t\t\tif (item.route) {\n\t\t\t\ttarget = typeof item.route === 'string' ? { name: item.route } : item.route\n\t\t\t\thref = resolveHref(target, this.$router)\n\t\t\t} else if (typeof item.href === 'string' && item.href !== '') {\n\t\t\t\tconst safe = safeHref(item.href)\n\t\t\t\thref = safe === '#' ? '' : safe\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tkey: `item-${index}`,\n\t\t\t\ttitle: typeof item.title === 'string' ? this.effectiveTranslate(item.title) : '',\n\t\t\t\tmeta: typeof item.meta === 'string' ? this.effectiveTranslate(item.meta) : '',\n\t\t\t\tdate,\n\t\t\t\tlate: item.late === true || (item.late !== false && this.isLateDate(date)),\n\t\t\t\ttarget,\n\t\t\t\thref,\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Load the week's records in one request.\n\t\t *\n\t\t * @return {Promise<void>}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget\n\t\t */\n\t\tasync fetchItems() {\n\t\t\tif (!this.hasSource) {\n\t\t\t\tthis.rows = []\n\t\t\t\tthis.error = ''\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst s = this.content.source\n\t\t\tconst requestKey = this.sourceKey\n\t\t\tconst first = this.weekDays[0]\n\t\t\tconst last = this.weekDays[this.weekDays.length - 1]\n\t\t\tconst dayAfter = new Date(last.getFullYear(), last.getMonth(), last.getDate() + 1)\n\t\t\tthis.loading = true\n\t\t\tthis.error = ''\n\t\t\ttry {\n\t\t\t\tconst [{ default: axios }, { generateUrl }] = await Promise.all([\n\t\t\t\t\timport('@nextcloud/axios'),\n\t\t\t\t\timport('@nextcloud/router'),\n\t\t\t\t])\n\t\t\t\tconst url = generateUrl(\n\t\t\t\t\t'/apps/openregister/api/objects/{register}/{schema}',\n\t\t\t\t\t{ register: s.register, schema: s.schema },\n\t\t\t\t)\n\t\t\t\tconst params = {\n\t\t\t\t\t_limit: Number.isInteger(s.limit) && s.limit > 0 ? s.limit : DEFAULT_LIMIT,\n\t\t\t\t\t[`_order[${this.dateField}]`]: 'asc',\n\t\t\t\t}\n\t\t\t\tconst filter = resolveFilterTokens(s.filter || {}, {})\n\t\t\t\tfor (const [k, v] of Object.entries(filter || {})) {\n\t\t\t\t\tif (v && typeof v === 'object') {\n\t\t\t\t\t\tfor (const [op, ov] of Object.entries(v)) {\n\t\t\t\t\t\t\tparams[`${k}[${op}]`] = ov\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (v !== '' && v !== null && v !== undefined) {\n\t\t\t\t\t\tparams[k] = v\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// The week window goes last, so a manifest filter on the date\n\t\t\t\t// field cannot widen the strip beyond the days it shows.\n\t\t\t\tparams[`${this.dateField}[gte]`] = dayKey(first)\n\t\t\t\tparams[`${this.dateField}[lt]`] = dayKey(dayAfter)\n\t\t\t\tconst res = await axios.get(url, { params })\n\t\t\t\tif (requestKey !== this.sourceKey) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tthis.rows = (res && res.data && Array.isArray(res.data.results)) ? res.data.results : []\n\t\t\t} catch (e) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.warn('[CnWeekStripWidget] failed to load items:', e)\n\t\t\t\tthis.error = (e && e.message) || 'error'\n\t\t\t\tthis.rows = []\n\t\t\t} finally {\n\t\t\t\tthis.loading = false\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Route a plain click on an in-app item; the browser handles the rest.\n\t\t *\n\t\t * @param {MouseEvent} event The click.\n\t\t * @param {object} item The clicked item.\n\t\t * @return {void}\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget\n\t\t */\n\t\tonItemClick(event, item) {\n\t\t\tif (item.target) {\n\t\t\t\tfollowLinkClick(event, item.target, this.$router)\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-week-strip {\n\twidth: 100%;\n}\n\n.cn-week-strip__state {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\tmargin: 0;\n\tpadding: 12px 4px;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-week-strip__scroll {\n\toverflow-x: auto;\n\tborder-radius: var(--border-radius-large, 8px);\n}\n\n.cn-week-strip__scroll:focus-visible {\n\toutline: 2px solid var(--color-primary-element);\n\toutline-offset: 2px;\n}\n\n.cn-week-strip__days {\n\tdisplay: grid;\n\tgrid-template-columns: repeat(var(--cn-week-strip-columns, 5), minmax(128px, 1fr));\n\tgap: 10px;\n\t/* 5 columns of 128px plus gaps: below this the region scrolls sideways. */\n\tmin-width: calc(var(--cn-week-strip-columns, 5) * 136px);\n\tmargin: 0;\n\tpadding: 0;\n\tlist-style: none;\n}\n\n.cn-week-strip__day {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n\tmin-width: 0;\n\tpadding: 10px;\n\tborder: 1px solid var(--color-border);\n\tborder-radius: var(--border-radius-large, 8px);\n\tbackground: var(--color-background-hover);\n}\n\n.cn-week-strip__day--today {\n\tborder-color: var(--color-primary-element);\n\tbackground: var(--color-primary-element-light);\n}\n\n.cn-week-strip__head {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tgap: 6px;\n\tfont-size: 0.85em;\n\tfont-weight: 600;\n\tcolor: var(--color-main-text);\n}\n\n.cn-week-strip__today {\n\tpadding: 1px 8px;\n\tborder-radius: var(--border-radius-pill, 10px);\n\tbackground: var(--color-primary-element);\n\tcolor: var(--color-primary-element-text);\n\tfont-size: 0.85em;\n\tfont-weight: 700;\n}\n\n.cn-week-strip__items {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 6px;\n\tmargin: 0;\n\tpadding: 0;\n\tlist-style: none;\n}\n\n.cn-week-strip__item {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n\tpadding: 10px 12px;\n\tborder: 1px solid var(--color-border);\n\tborder-radius: var(--border-radius-large, 8px);\n\tbackground: var(--color-main-background);\n\tcolor: var(--color-main-text);\n\ttext-decoration: none;\n}\n\n.cn-week-strip__item--link:hover {\n\tborder-color: var(--color-primary-element);\n}\n\n.cn-week-strip__item--link:focus-visible {\n\toutline: 2px solid var(--color-primary-element);\n\toutline-offset: 2px;\n}\n\n/* The edge is drawn inside the box, so a late item is as wide as the others. */\n.cn-week-strip__item--late {\n\tborder-color: var(--color-element-error, var(--color-error));\n\tbox-shadow: inset 3px 0 0 0 var(--color-element-error, var(--color-error));\n}\n\n.cn-week-strip__title {\n\tfont-size: 0.95em;\n\tline-height: 1.3;\n\toverflow-wrap: anywhere;\n}\n\n.cn-week-strip__meta {\n\tfont-size: 0.85em;\n\tcolor: var(--color-text-maxcontrast);\n\toverflow-wrap: anywhere;\n}\n\n.cn-week-strip__late {\n\tfont-size: 0.8em;\n\tfont-weight: 600;\n\tcolor: var(--color-text-error, var(--color-error-text));\n}\n\n.cn-week-strip__empty {\n\tfont-size: 0.9em;\n\tcolor: var(--color-text-maxcontrast);\n}\n</style>\n"],"names":["t"],"mappings":"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"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { resolveComponent, openBlock, createElementBlock, createVNode, createElementVNode, toDisplayString, normalizeStyle, Fragment, renderList, normalizeClass, createCommentVNode, createBlock, resolveDynamicComponent, withCtx } from 'vue';
|
|
2
|
+
|
|
3
|
+
const _hoisted_1 = {
|
|
4
|
+
class: "cn-week-strip",
|
|
5
|
+
"data-testid": "cn-week-strip"
|
|
6
|
+
};
|
|
7
|
+
const _hoisted_2 = {
|
|
8
|
+
key: 0,
|
|
9
|
+
class: "cn-week-strip__state",
|
|
10
|
+
role: "status"
|
|
11
|
+
};
|
|
12
|
+
const _hoisted_3 = { class: "cn-week-strip__state-text" };
|
|
13
|
+
const _hoisted_4 = {
|
|
14
|
+
key: 1,
|
|
15
|
+
class: "cn-week-strip__state",
|
|
16
|
+
role: "status"
|
|
17
|
+
};
|
|
18
|
+
const _hoisted_5 = ["aria-label"];
|
|
19
|
+
const _hoisted_6 = ["aria-current", "data-day"];
|
|
20
|
+
const _hoisted_7 = { class: "cn-week-strip__head" };
|
|
21
|
+
const _hoisted_8 = { class: "cn-week-strip__label" };
|
|
22
|
+
const _hoisted_9 = {
|
|
23
|
+
key: 0,
|
|
24
|
+
class: "cn-week-strip__today"
|
|
25
|
+
};
|
|
26
|
+
const _hoisted_10 = {
|
|
27
|
+
key: 0,
|
|
28
|
+
class: "cn-week-strip__items"
|
|
29
|
+
};
|
|
30
|
+
const _hoisted_11 = { class: "cn-week-strip__title" };
|
|
31
|
+
const _hoisted_12 = {
|
|
32
|
+
key: 0,
|
|
33
|
+
class: "cn-week-strip__meta"
|
|
34
|
+
};
|
|
35
|
+
const _hoisted_13 = {
|
|
36
|
+
key: 1,
|
|
37
|
+
class: "cn-week-strip__late"
|
|
38
|
+
};
|
|
39
|
+
const _hoisted_14 = {
|
|
40
|
+
key: 1,
|
|
41
|
+
class: "cn-week-strip__empty"
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
45
|
+
const _component_NcLoadingIcon = resolveComponent("NcLoadingIcon");
|
|
46
|
+
|
|
47
|
+
return (openBlock(), createElementBlock("div", _hoisted_1, [
|
|
48
|
+
($data.loading)
|
|
49
|
+
? (openBlock(), createElementBlock("div", _hoisted_2, [
|
|
50
|
+
createVNode(_component_NcLoadingIcon, { size: 20 }),
|
|
51
|
+
createElementVNode("span", _hoisted_3, toDisplayString($options.loadingLabel), 1 /* TEXT */)
|
|
52
|
+
]))
|
|
53
|
+
: ($data.error)
|
|
54
|
+
? (openBlock(), createElementBlock("p", _hoisted_4, toDisplayString($options.errorLabel), 1 /* TEXT */))
|
|
55
|
+
: (openBlock(), createElementBlock("div", {
|
|
56
|
+
key: 2,
|
|
57
|
+
class: "cn-week-strip__scroll",
|
|
58
|
+
role: "region",
|
|
59
|
+
tabindex: "0",
|
|
60
|
+
"aria-label": $options.regionLabel
|
|
61
|
+
}, [
|
|
62
|
+
createElementVNode("ol", {
|
|
63
|
+
class: "cn-week-strip__days",
|
|
64
|
+
style: normalizeStyle({ '--cn-week-strip-columns': $options.dayColumns.length })
|
|
65
|
+
}, [
|
|
66
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList($options.dayColumns, (day) => {
|
|
67
|
+
return (openBlock(), createElementBlock("li", {
|
|
68
|
+
key: day.key,
|
|
69
|
+
class: normalizeClass(["cn-week-strip__day", { 'cn-week-strip__day--today': day.today }]),
|
|
70
|
+
"aria-current": day.today ? 'date' : null,
|
|
71
|
+
"data-day": day.key
|
|
72
|
+
}, [
|
|
73
|
+
createElementVNode("span", _hoisted_7, [
|
|
74
|
+
createElementVNode("span", _hoisted_8, toDisplayString(day.label), 1 /* TEXT */),
|
|
75
|
+
(day.today)
|
|
76
|
+
? (openBlock(), createElementBlock("span", _hoisted_9, toDisplayString($options.todayLabel), 1 /* TEXT */))
|
|
77
|
+
: createCommentVNode("v-if", true)
|
|
78
|
+
]),
|
|
79
|
+
(day.items.length > 0)
|
|
80
|
+
? (openBlock(), createElementBlock("ul", _hoisted_10, [
|
|
81
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(day.items, (item) => {
|
|
82
|
+
return (openBlock(), createElementBlock("li", {
|
|
83
|
+
key: item.key,
|
|
84
|
+
class: "cn-week-strip__item-row"
|
|
85
|
+
}, [
|
|
86
|
+
(openBlock(), createBlock(resolveDynamicComponent(item.href ? 'a' : 'div'), {
|
|
87
|
+
class: normalizeClass(["cn-week-strip__item", { 'cn-week-strip__item--late': item.late, 'cn-week-strip__item--link': !!item.href }]),
|
|
88
|
+
href: item.href || null,
|
|
89
|
+
"data-testid": "cn-week-strip-item",
|
|
90
|
+
onClick: $event => ($options.onItemClick($event, item))
|
|
91
|
+
}, {
|
|
92
|
+
default: withCtx(() => [
|
|
93
|
+
createElementVNode("strong", _hoisted_11, toDisplayString(item.title), 1 /* TEXT */),
|
|
94
|
+
(item.meta)
|
|
95
|
+
? (openBlock(), createElementBlock("span", _hoisted_12, toDisplayString(item.meta), 1 /* TEXT */))
|
|
96
|
+
: createCommentVNode("v-if", true),
|
|
97
|
+
(item.late)
|
|
98
|
+
? (openBlock(), createElementBlock("span", _hoisted_13, toDisplayString($options.lateLabel), 1 /* TEXT */))
|
|
99
|
+
: createCommentVNode("v-if", true)
|
|
100
|
+
]),
|
|
101
|
+
_: 2 /* DYNAMIC */
|
|
102
|
+
}, 1032 /* PROPS, DYNAMIC_SLOTS */, ["class", "href", "onClick"]))
|
|
103
|
+
]))
|
|
104
|
+
}), 128 /* KEYED_FRAGMENT */))
|
|
105
|
+
]))
|
|
106
|
+
: (openBlock(), createElementBlock("span", _hoisted_14, toDisplayString($options.emptyLabel), 1 /* TEXT */))
|
|
107
|
+
], 10 /* CLASS, PROPS */, _hoisted_6))
|
|
108
|
+
}), 128 /* KEYED_FRAGMENT */))
|
|
109
|
+
], 4 /* STYLE */)
|
|
110
|
+
], 8 /* PROPS */, _hoisted_5))
|
|
111
|
+
]))
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export { render };
|
|
115
|
+
//# sourceMappingURL=CnWeekStripWidget.vue3.js.map
|