@conduction/nextcloud-vue 2.56.0-beta.6 → 2.56.0-beta.8
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 +80 -1
- 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 +232 -10
- 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/CnDashboardPage/CnDashboardPage.vue2.js +10 -2
- 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/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 +303 -144
- 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 +171 -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/CnLinkCardsPage/CnLinkCardsPage.vue.js +10 -0
- package/dist/esm/components/CnLinkCardsPage/CnLinkCardsPage.vue.js.map +1 -0
- package/dist/esm/components/CnLinkCardsPage/CnLinkCardsPage.vue2.js +316 -0
- package/dist/esm/components/CnLinkCardsPage/CnLinkCardsPage.vue2.js.map +1 -0
- package/dist/esm/components/CnLinkCardsPage/CnLinkCardsPage.vue3.js +105 -0
- package/dist/esm/components/CnLinkCardsPage/CnLinkCardsPage.vue3.js.map +1 -0
- 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/CnPageRenderer/pageTypes.js +1 -0
- package/dist/esm/components/CnPageRenderer/pageTypes.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 +16 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/l10n/en.json.js +55 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +55 -1
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/nextcloud-vue.css +1036 -19
- 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/headers.js +28 -2
- package/dist/esm/utils/headers.js.map +1 -1
- 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 +16019 -9528
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +1036 -19
- package/l10n/en.json +55 -1
- package/l10n/nl.json +55 -1
- package/package.json +1 -1
- package/scripts/.jsdoc-baselines.json +4 -0
- package/src/components/CnActionsMenu/CnActionsMenu.vue +14 -1
- package/src/components/CnAppNav/CnAppNav.md +26 -0
- package/src/components/CnAppNav/CnAppNav.vue +145 -2
- package/src/components/CnBannerWidget/CnBannerWidget.vue +373 -11
- 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/CnDashboardPage/CnDashboardPage.vue +10 -2
- package/src/components/CnDetailPage/CnDetailPage.md +16 -0
- package/src/components/CnDetailPage/CnDetailPage.vue +687 -49
- 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 +191 -14
- package/src/components/CnHeaderWidgetForm/CnHeaderWidgetForm.vue +53 -3
- package/src/components/CnIndexPage/CnIndexPage.vue +135 -3
- package/src/components/CnLinkCardsPage/CnLinkCardsPage.vue +484 -0
- package/src/components/CnLinkCardsPage/index.js +4 -0
- 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/CnPageRenderer/pageTypes.js +1 -0
- 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 +12 -0
- package/src/css/detail-page.css +57 -2
- package/src/index.js +16 -0
- package/src/schemas/app-manifest-v2.schema.json +433 -3
- package/src/schemas/app-manifest.schema.json +2 -1
- package/src/types/manifest.d.ts +1 -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/headers.js +28 -2
- 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 @@
|
|
|
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":";;;;;;;;;AAiEA,MAAM,aAAc,GAAE,IAAE;;AAExB;;;;AAIC;;;;AAIA;AACA;;AAEA;AACA;;;AAGA;;AAEA;;AAEA;AACA;;;;;;AAMA;;AAED,aAAe;CACd,IAAI,EAAE,mBAAmB;;CAEzB,UAAU,EAAE,EAAE,aAAY,EAAG;;AAE7B,CAAA,MAAM,EAAE;AACP;;;;AAIA,EAAA,WAAW,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,KAAK,KAAK;EAC5C;;AAED,CAAA,KAAK,EAAE;AACN;;;;;;;;;AASC;;AAEA;AACA;AACA;;AAED,EAAA,OAAO,EAAE;GACR,IAAI,EAAE,MAAM;AACZ,GAAA,OAAO,EAAE,OAAO,EAAE,CAAC;GACnB;;AAED;;AAEC;AACA;AACA;;EAED,SAAS,EAAE;GACV,IAAI,EAAE,QAAQ;GACd,OAAO,EAAE,IAAI;GACb;;AAED;;AAEC;AACA;AACA;;EAED,GAAG,EAAE;AACJ,GAAA,IAAI,EAAE,IAAI;GACV,OAAO,EAAE,IAAI;GACb;EACD;;AAED,CAAA,IAAI,GAAG;AACN,EAAA,OAAO;AACN,GAAA,IAAI,EAAE,EAAE;GACR,OAAO,EAAE,KAAK;AACd,GAAA,KAAK,EAAE,EAAE;AACV,GAAA;EACA;;AAED,CAAA,QAAQ,EAAE;AACT;;AAEC;;AAEA;;AAED,EAAA,kBAAkB,GAAG;AACpB,GAAA,OAAO,IAAI,CAAC,SAAQ,IAAK,IAAI,CAAC,WAAU;GACxC;;AAED;AACC;AACA;;AAEA;;EAED,SAAS,GAAG;GACX,OAAO,IAAI,CAAC,GAAE,YAAa,IAAK,GAAE,IAAI,CAAC,GAAI,GAAE,IAAI,IAAI,EAAC;GACtD;;AAED;AACC;AACA;AACA;AACA;;EAED,QAAQ,GAAG;AACV,GAAA,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAA,KAAM,CAAE,GAAE,IAAI,CAAA;GAC7C;;AAED;AACC;AACA;AACA;AACA;;EAED,QAAQ,GAAG;GACV,MAAM,GAAE,GAAI,IAAI,CAAC,UAAQ;AACzB,GAAA,MAAM,MAAK,GAAI,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAE,GAAE,IAAI,CAAC,OAAO,CAAC,aAAa,EAAA;AACrF,GAAA,MAAM,WAAY,GAAE,CAAC,GAAG,CAAC,MAAM,EAAC,GAAI,CAAC,IAAI,EAAA;GACzC,MAAM,IAAK,GAAE,GAAC;AACd,GAAA,KAAK,IAAI,CAAE,GAAE,CAAC,EAAE,CAAE,GAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE;AACvC,IAAA,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,GAAG,CAAC,QAAQ,EAAE,EAAE,GAAG,CAAC,OAAO,EAAG,GAAE,WAAU,IAAK,MAAO,GAAE,CAAC,CAAE,GAAE,CAAC,CAAC,EAAA;AACtG,IAAA;AACA,GAAA,OAAO,IAAG;GACV;;AAED;AACC;AACA;AACA;AACA;;EAED,SAAS,GAAG;AACX,GAAA,OAAO,OAAO,IAAI,CAAC,OAAO,CAAC,SAAU,KAAI,QAAS,GAAE,IAAI,CAAC,OAAO,CAAC,SAAQ,GAAI,EAAC;GAC9E;;AAED;AACC;AACA;AACA;AACA;;EAED,SAAS,GAAG;GACX,MAAM,CAAA,GAAI,IAAI,CAAC,OAAO,CAAC,MAAK,IAAK,GAAC;GAClC,OAAO,OAAO,CAAC,CAAC,CAAC,QAAS,IAAG,CAAC,CAAC,MAAK,IAAK,IAAI,CAAC,SAAS,CAAA;GACvD;;AAED;;AAEC;;AAEA;;AAED,EAAA,eAAe,GAAG;AACjB,GAAA,IAAI,IAAI,CAAC,SAAS,EAAE;IACnB,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;AAClE,IAAA;AACA,GAAA,MAAM,KAAM,GAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAA,GAAI,IAAI,CAAC,OAAO,CAAC,KAAI,GAAI,GAAC;GACxE,OAAO,KAAI;AACV,KAAC,MAAM,CAAC,CAAC,IAAI,KAAK,IAAK,IAAG,OAAO,IAAG,KAAM,QAAQ,CAAA;KACjD,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;GACvD;;AAED;AACC;AACA;AACA;AACA;;EAED,UAAU,GAAG;AACZ,GAAA,MAAM,QAAS,GAAE,MAAM,CAAC,IAAI,CAAC,SAAS,EAAA;AACtC,GAAA,MAAM,OAAQ,GAAE,GAAC;AACjB,GAAA,KAAK,MAAM,IAAG,IAAK,IAAI,CAAC,eAAe,EAAE;AACxC,IAAA,IAAI,IAAI,CAAC,IAAG,KAAM,IAAI,EAAE;AACvB,KAAA,QAAO;AACR,KAAA;IACA,MAAM,GAAE,GAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAA;AAC5B,KAAC,CAAC,OAAO,CAAC,GAAG,CAAE,GAAE,OAAO,CAAC,GAAG,KAAK,EAAE,EAAE,IAAI,CAAC,IAAI,EAAA;AAC/C,IAAA;AACA,GAAA,MAAM,SAAU,GAAE,IAAI,CAAC,aAAW;AAClC,GAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK;AACjC,IAAA,MAAM,GAAI,GAAE,MAAM,CAAC,GAAG,EAAA;AACtB,IAAA,OAAO;AACN,KAAA,GAAG;KACH,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC;AAC5B,KAAA,KAAK,EAAE,GAAI,KAAI,QAAQ;KACvB,KAAK,EAAE,OAAO,CAAC,GAAG,KAAK,EAAE;AAC1B,KAAA;IACA,CAAA;GACD;;AAED;;AAEC;;AAEA;;AAED,EAAA,YAAY,GAAG;AACd,GAAA,IAAI,OAAK;AACT,GAAA,IAAI;IACH,MAAK,GAAI,kBAAkB,GAAC;AAC7B,IAAA,CAAE,MAAM;AACP,IAAA,MAAO,GAAE,UAAQ;AAClB,IAAA;AACA,GAAA,IAAI;AACH,IAAA,OAAO,IAAI,IAAI,CAAC,cAAc,CAAC,MAAO,IAAG,SAAS,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,CAAA;AACzF,IAAA,CAAE,MAAM;AACP,IAAA,OAAO,IAAI,IAAI,CAAC,cAAc,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,CAAA;AAC/E,IAAA;GACA;;AAED;;AAEC;AACA;AACA;;EAED,UAAU,GAAG;AACZ,GAAA,MAAM,IAAG,GAAI,IAAI,CAAC,OAAO,CAAC,UAAQ;AAClC,GAAA,OAAO,CAAC,OAAO,SAAS,QAAS,IAAG,IAAG,KAAM,EAAE;MAC5C,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAA;AAC9B,MAAEA,SAAC,CAAC,eAAe,EAAE,iBAAiB,CAAA;GACvC;;AAED;AACC;AACA;AACA;;EAED,UAAU,GAAG;AACZ,GAAA,OAAOA,SAAC,CAAC,eAAe,EAAE,OAAO,CAAA;GACjC;;AAED;AACC;AACA;AACA;;EAED,SAAS,GAAG;AACX,GAAA,OAAOA,SAAC,CAAC,eAAe,EAAE,MAAM,CAAA;GAChC;;AAED;;AAEC;AACA;;EAED,WAAW,GAAG;AACb,GAAA,OAAOA,SAAC,CAAC,eAAe,EAAE,uBAAuB,CAAA;GACjD;;AAED;AACC;AACA;AACA;;AAED,EAAA,YAAY,GAAG;AACd,GAAA,OAAOA,SAAC,CAAC,eAAe,EAAE,UAAU,CAAA;GACpC;;AAED;;AAEC;AACA;;EAED,UAAU,GAAG;AACZ,GAAA,OAAOA,SAAC,CAAC,eAAe,EAAE,8CAA8C,CAAA;GACxE;;AAED;AACC;AACA;AACA;AACA;;EAED,SAAS,GAAG;AACX,GAAA,OAAO,IAAI,CAAC,SAAS,CAAC;IACrB,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,MAAO,IAAG,EAAE;AAC5B,IAAA,CAAC,EAAE,IAAI,CAAC,SAAS;AACjB,IAAA,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAK,GAAI,CAAA,GAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAE,GAAE,EAAE;IACnF,CAAA;GACD;EACD;;AAED,CAAA,KAAK,EAAE;AACN;EACA,SAAS,GAAG;AACX,GAAA,IAAI,CAAC,UAAU,GAAC;GAChB;EACD;;AAED,CAAA,OAAO,GAAG;AACT,EAAA,IAAI,CAAC,UAAU,GAAC;EAChB;;AAED,CAAA,OAAO,EAAE;AACR;;;AAGC;AACA;AACA;AACA;;AAED,EAAA,UAAU,CAAC,IAAI,EAAE;AAChB,GAAA,IAAI,IAAG,KAAM,IAAI,EAAE;IAClB,OAAO,KAAI;AACZ,IAAA;AACA,GAAA,MAAM,IAAK,GAAE,CAAC,IAAI,CAAC,OAAO,CAAC,QAAS,IAAG,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,QAAQ;AAC/E,MAAE,IAAI,CAAC,OAAO,CAAC,QAAO;AACtB,MAAE,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAE,GAAA;AACxB,GAAA,OAAO,kBAAkB,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,EAAG,IAAG,IAAI,EAAE,IAAI,CAAC,KAAM,IAAG,CAAC,CAAA;GAC3F;;AAED;AACC;AACA;;;;AAIA;;EAED,WAAW,CAAC,GAAG,EAAE,KAAK,EAAE;AACvB,GAAA,MAAM,CAAA,GAAI,IAAI,CAAC,QAAM;GACrB,MAAM,EAAG,GAAE,GAAI,KAAI,GAAG,CAAC,OAAO,GAAG,CAAC,OAAO,CAAE,IAAG,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAA;GAC9D,MAAM,IAAK,GAAE,cAAc,CAAC,gBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,EAAA;AACjE,GAAA,MAAM,aAAa,CAAC,CAAC,UAAS,GAAI,gBAAgB,CAAC,GAAG,EAAE,CAAC,CAAC,UAAU,CAAA,GAAI,UAAQ;AAChF,GAAA,MAAM,KAAI,GAAI,CAAC,UAAW,KAAI,SAAU,IAAG,UAAS,KAAM,IAAG,IAAK,UAAW,KAAI,EAAE;AAClF,MAAE,MAAM,CAAC,UAAU,CAAA;MACjB,iBAAiB,CAAC,GAAG,EAAA;GACxB,MAAM,aAAa,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAE,GAAE,CAAC,CAAC,UAAW,GAAE,GAAC;AACjE,GAAA,MAAM,IAAG,GAAI,UAAS;AACrB,KAAC,GAAG,CAAC,CAAC,KAAK,KAAK,gBAAgB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;AAC5C,KAAC,MAAM,CAAC,CAAC,KAAK,KAAK,KAAI,KAAM,aAAa,KAAM,KAAI,IAAK,IAAG,UAAU,EAAC,IAAK,OAAO,KAAM,KAAI,QAAQ,CAAA;KACpG,GAAG,CAAC,MAAM,CAAA;AACX,KAAC,IAAI,CAAC,KAAK,EAAA;AACZ,GAAA,MAAM,OAAM,GAAI,CAAC,CAAC,YAAY,gBAAgB,CAAC,GAAG,EAAE,CAAC,CAAC,SAAS,CAAE,KAAI,IAAK,GAAE,MAAI;AAChF,GAAA,MAAM,MAAK,GAAI,CAAC,CAAC,CAAC,SAAU,IAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAC,EAAI,EAAA,GAAI,KAAG;AAChF,GAAA,OAAO;AACN,IAAA,GAAG,EAAE,MAAM,CAAC,EAAC,IAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;IACjC,KAAK;IACL,IAAI;IACJ,IAAI;AACJ,IAAA,IAAI,EAAE,OAAM,IAAK,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;AACtC,IAAA,MAAM;IACN,IAAI,EAAE,MAAK,GAAI,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAA,GAAI,EAAE;AACtD,IAAA;GACA;;AAED;AACC;AACA;;AAEA;;AAEA;;EAED,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE;AAC3B,GAAA,MAAM,IAAK,GAAE,cAAc,CAAC,IAAI,CAAC,IAAI,EAAA;GACrC,IAAI,MAAO,GAAE,KAAG;AAChB,GAAA,IAAI,IAAG,GAAI,GAAC;AACZ,GAAA,IAAI,IAAI,CAAC,KAAK,EAAE;AACf,IAAA,MAAO,GAAE,OAAO,IAAI,CAAC,KAAI,KAAM,QAAS,GAAE,EAAE,IAAI,EAAE,IAAI,CAAC,KAAI,EAAI,GAAE,IAAI,CAAC,MAAI;AAC1E,IAAA,IAAK,GAAE,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAA;IACtC,MAAK,IAAI,OAAO,IAAI,CAAC,IAAG,KAAM,QAAO,IAAK,IAAI,CAAC,IAAG,KAAM,EAAE,EAAE;IAC7D,MAAM,IAAK,GAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAA;IAC/B,IAAK,GAAE,SAAS,MAAM,KAAK,KAAG;AAC/B,IAAA;AACA,GAAA,OAAO;AACN,IAAA,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AACpB,IAAA,KAAK,EAAE,OAAO,IAAI,CAAC,KAAM,KAAI,QAAO,GAAI,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAE,GAAE,EAAE;AAChF,IAAA,IAAI,EAAE,OAAO,IAAI,CAAC,IAAG,KAAM,QAAO,GAAI,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAE,GAAE,EAAE;IAC7E,IAAI;AACJ,IAAA,IAAI,EAAE,IAAI,CAAC,IAAK,KAAI,IAAG,KAAM,IAAI,CAAC,IAAK,KAAI,KAAM,IAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AAC1E,IAAA,MAAM;IACN,IAAI;AACL,IAAA;GACA;;AAED;AACC;AACA;;AAEA;;AAED,EAAA,MAAM,UAAU,GAAG;AAClB,GAAA,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;IACpB,IAAI,CAAC,IAAK,GAAE,GAAC;IACb,IAAI,CAAC,KAAM,GAAE,GAAC;IACd,MAAK;AACN,IAAA;GACA,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,OAAK;GAC5B,MAAM,UAAW,GAAE,IAAI,CAAC,UAAQ;GAChC,MAAM,KAAM,GAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAA;GAC7B,MAAM,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAK,GAAI,CAAC,EAAA;AACnD,GAAA,MAAM,QAAS,GAAE,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,OAAO,EAAC,GAAI,CAAC,EAAA;AACjF,GAAA,IAAI,CAAC,OAAM,GAAI,KAAG;GAClB,IAAI,CAAC,KAAM,GAAE,GAAC;AACd,GAAA,IAAI;IACH,MAAM,CAAC,EAAE,OAAO,EAAE,KAAI,EAAG,EAAE,EAAE,WAAU,EAAG,CAAE,GAAE,MAAM,OAAO,CAAC,GAAG,CAAC;KAC/D,OAAO,kBAAkB,CAAC;KAC1B,OAAO,mBAAmB,CAAC;KAC3B,EAAA;AACD,IAAA,MAAM,MAAM,WAAW;KACtB,oDAAoD;AACpD,KAAA,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,QAAQ;AAC3C,MAAA;IACA,MAAM,MAAK,GAAI;AACd,KAAA,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAA,IAAK,CAAC,CAAC,KAAM,GAAE,CAAE,GAAE,CAAC,CAAC,KAAI,GAAI,aAAa;AAC1E,KAAA,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,KAAK;AACrC,MAAA;IACA,MAAM,MAAK,GAAI,mBAAmB,CAAC,CAAC,CAAC,MAAO,IAAG,EAAE,EAAE,EAAE,EAAA;AACrD,IAAA,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAE,IAAG,MAAM,CAAC,OAAO,CAAC,MAAO,IAAG,EAAE,CAAC,EAAE;KAClD,IAAI,CAAE,IAAG,OAAO,MAAM,QAAQ,EAAE;AAC/B,MAAA,KAAK,MAAM,CAAC,EAAE,EAAE,EAAE,KAAK,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;OACzC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAE,GAAE,GAAC;AAC1B,OAAA;AACD,MAAA,MAAO,IAAI,CAAA,KAAM,EAAC,IAAK,CAAA,KAAM,IAAK,IAAG,CAAA,KAAM,SAAS,EAAE;MACrD,MAAM,CAAC,CAAC,IAAI,EAAA;AACb,MAAA;AACD,KAAA;;;AAGA,IAAA,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,EAAA;IAC/C,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAE,GAAE,MAAM,CAAC,QAAQ,EAAA;AACjD,IAAA,MAAM,GAAE,GAAI,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAA;AAC3C,IAAA,IAAI,UAAS,KAAM,IAAI,CAAC,SAAS,EAAE;KAClC,MAAK;AACN,KAAA;AACA,IAAA,IAAI,CAAC,IAAK,GAAE,CAAC,GAAI,IAAG,GAAG,CAAC,IAAK,IAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,OAAM,GAAI,GAAC;AACxF,IAAA,CAAE,OAAO,CAAC,EAAE;AACX;IACA,OAAO,CAAC,IAAI,CAAC,2CAA2C,EAAE,CAAC,EAAA;AAC3D,IAAA,IAAI,CAAC,KAAM,GAAE,CAAC,CAAA,IAAK,CAAC,CAAC,OAAO,KAAK,QAAM;IACvC,IAAI,CAAC,IAAK,GAAE,GAAC;AACd,IAAA,SAAU;AACT,IAAA,IAAI,CAAC,OAAQ,GAAE,MAAI;AACpB,IAAA;GACA;;AAED;;AAEC;AACA;AACA;;AAEA;;EAED,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE;AACxB,GAAA,IAAI,IAAI,CAAC,MAAM,EAAE;IAChB,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAA;AACjD,IAAA;GACA;EACD;AACF;;;;"}
|
|
@@ -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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CnWeekStripWidget.vue3.js","sources":["../../../../src/components/CnWeekStripWidget/CnWeekStripWidget.vue?vue&type=template&id=153dd4cb&lang.js"],"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":["_openBlock","_createElementBlock","_createVNode","_createElementVNode","_toDisplayString","_normalizeStyle","_normalizeClass","_Fragment","_renderList","_resolveDynamicComponent"],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import script from './CnWeekStripWidgetForm.vue2.js';
|
|
2
|
+
import { render } from './CnWeekStripWidgetForm.vue3.js';
|
|
3
|
+
|
|
4
|
+
script.render = render;
|
|
5
|
+
script.__scopeId = "data-v-4a9dc393";
|
|
6
|
+
script.__file = "src/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue";
|
|
7
|
+
const __sfc_main = script;
|
|
8
|
+
|
|
9
|
+
export { __sfc_main as default };
|
|
10
|
+
//# sourceMappingURL=CnWeekStripWidgetForm.vue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CnWeekStripWidgetForm.vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { translate } from '@nextcloud/l10n';
|
|
2
|
+
import { NcSelect, NcTextField } from '@nextcloud/vue';
|
|
3
|
+
import __sfc_main from '../CnFieldPicker/CnFieldPicker.vue.js';
|
|
4
|
+
import __sfc_main$1 from '../CnFilterRowsEditor/CnFilterRowsEditor.vue.js';
|
|
5
|
+
import __sfc_main$2 from '../CnRegisterSchemaSelect/CnRegisterSchemaSelect.vue.js';
|
|
6
|
+
import { fetchSchemaProperties } from '../../utils/fetchSchemaProperties.js';
|
|
7
|
+
import { filterToRows, rowsToFilter } from '../CnFilterRowsEditor/filterRows.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* CnWeekStripWidgetForm is the settings form of a `week-strip` widget. It
|
|
11
|
+
* edits the source (register, schema, filter), the date field the items are
|
|
12
|
+
* bucketed by, what each item shows, how many days render and the text of an
|
|
13
|
+
* empty day. Static `items` and the `lateWhen` rule are written in the
|
|
14
|
+
* manifest and pass through untouched. Emits `update:content` on every
|
|
15
|
+
* change; `validate()` asks for a register, a schema and a date field unless
|
|
16
|
+
* the widget has static items.
|
|
17
|
+
*/
|
|
18
|
+
var script = {
|
|
19
|
+
name: 'CnWeekStripWidgetForm',
|
|
20
|
+
|
|
21
|
+
components: { NcSelect, NcTextField, CnFieldPicker: __sfc_main, CnFilterRowsEditor: __sfc_main$1, CnRegisterSchemaSelect: __sfc_main$2 },
|
|
22
|
+
|
|
23
|
+
props: {
|
|
24
|
+
/**
|
|
25
|
+
* The placement being edited (pre-fills from `editingWidget.content`), or null.
|
|
26
|
+
*
|
|
27
|
+
* @type {{content: object}|null}
|
|
28
|
+
*/
|
|
29
|
+
editingWidget: { type: Object, default: null },
|
|
30
|
+
/**
|
|
31
|
+
* Initial content values when not editing (registry defaults).
|
|
32
|
+
*
|
|
33
|
+
* @type {object}
|
|
34
|
+
*/
|
|
35
|
+
value: { type: Object, default: () => ({}) },
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
emits: [
|
|
39
|
+
/**
|
|
40
|
+
* Emitted with the assembled content blob on every field change.
|
|
41
|
+
*
|
|
42
|
+
* @event update:content
|
|
43
|
+
* @type {object}
|
|
44
|
+
*/
|
|
45
|
+
'update:content',
|
|
46
|
+
],
|
|
47
|
+
|
|
48
|
+
data() {
|
|
49
|
+
const initial = this.editingWidget?.content || this.value || {};
|
|
50
|
+
const src = initial.source || {};
|
|
51
|
+
return {
|
|
52
|
+
initial,
|
|
53
|
+
source: { register: src.register ?? '', schema: src.schema ?? '' },
|
|
54
|
+
limit: src.limit,
|
|
55
|
+
filterRows: filterToRows(src.filter || {}),
|
|
56
|
+
dateField: initial.dateField ?? '',
|
|
57
|
+
titleField: initial.titleField ?? '',
|
|
58
|
+
metaFieldsText: Array.isArray(initial.metaFields) ? initial.metaFields.join(', ') : '',
|
|
59
|
+
days: Number(initial.days) === 7 ? 7 : 5,
|
|
60
|
+
itemRoute: initial.itemRoute ?? '',
|
|
61
|
+
emptyText: initial.emptyText ?? '',
|
|
62
|
+
availableFields: [],
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
computed: {
|
|
67
|
+
/**
|
|
68
|
+
* The day counts on offer: working days or the whole week.
|
|
69
|
+
*
|
|
70
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget
|
|
71
|
+
*/
|
|
72
|
+
dayOptions() {
|
|
73
|
+
return [5, 7]
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* The assembled content blob. Keys the form does not edit (static
|
|
78
|
+
* items, the late rule) are carried over from the initial content.
|
|
79
|
+
*
|
|
80
|
+
* @return {object}
|
|
81
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget
|
|
82
|
+
*/
|
|
83
|
+
assembledContent() {
|
|
84
|
+
const source = {
|
|
85
|
+
register: this.source.register,
|
|
86
|
+
schema: this.source.schema,
|
|
87
|
+
filter: rowsToFilter(this.filterRows),
|
|
88
|
+
};
|
|
89
|
+
if (this.limit !== undefined) {
|
|
90
|
+
source.limit = this.limit;
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
...this.initial,
|
|
94
|
+
source,
|
|
95
|
+
dateField: this.dateField,
|
|
96
|
+
titleField: this.titleField,
|
|
97
|
+
metaFields: this.metaFieldsText.split(',').map((field) => field.trim()).filter((field) => field !== ''),
|
|
98
|
+
days: this.days,
|
|
99
|
+
itemRoute: this.itemRoute,
|
|
100
|
+
emptyText: this.emptyText,
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
watch: {
|
|
106
|
+
'source.register': 'loadFields',
|
|
107
|
+
'source.schema': 'loadFields',
|
|
108
|
+
},
|
|
109
|
+
|
|
110
|
+
mounted() {
|
|
111
|
+
this.loadFields();
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
methods: {
|
|
115
|
+
t: translate,
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Load the schema's field names for the pickers.
|
|
119
|
+
*
|
|
120
|
+
* @return {Promise<void>}
|
|
121
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget
|
|
122
|
+
*/
|
|
123
|
+
async loadFields() {
|
|
124
|
+
this.availableFields = await fetchSchemaProperties(this.source.register, this.source.schema);
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Set one field and emit the assembled content.
|
|
129
|
+
*
|
|
130
|
+
* @param {string} field The data key to write.
|
|
131
|
+
* @param {string|number} value The new value.
|
|
132
|
+
* @return {void}
|
|
133
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget
|
|
134
|
+
*/
|
|
135
|
+
updateField(field, value) {
|
|
136
|
+
this[field] = value;
|
|
137
|
+
this.$emit('update:content', this.assembledContent);
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Set the register or the schema and emit.
|
|
142
|
+
*
|
|
143
|
+
* @param {'register'|'schema'} field The source key to write.
|
|
144
|
+
* @param {string} value The chosen slug.
|
|
145
|
+
* @return {void}
|
|
146
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget
|
|
147
|
+
*/
|
|
148
|
+
updateSource(field, value) {
|
|
149
|
+
this.source[field] = value;
|
|
150
|
+
this.$emit('update:content', this.assembledContent);
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Take the filter editor's rows and emit.
|
|
155
|
+
*
|
|
156
|
+
* @param {Array<{key: string, op: string, value: string}>} rows The rows.
|
|
157
|
+
* @return {void}
|
|
158
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget
|
|
159
|
+
*/
|
|
160
|
+
onFilterRows(rows) {
|
|
161
|
+
this.filterRows = rows;
|
|
162
|
+
this.$emit('update:content', this.assembledContent);
|
|
163
|
+
},
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Validate the form; an empty array means valid.
|
|
167
|
+
*
|
|
168
|
+
* @return {string[]} The validation errors.
|
|
169
|
+
* @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget
|
|
170
|
+
*/
|
|
171
|
+
validate() {
|
|
172
|
+
const hasStaticItems = Array.isArray(this.initial.items) && this.initial.items.length > 0;
|
|
173
|
+
if (hasStaticItems && !this.source.register && !this.source.schema) {
|
|
174
|
+
return []
|
|
175
|
+
}
|
|
176
|
+
const errors = [];
|
|
177
|
+
if (!this.source.register || !this.source.schema) {
|
|
178
|
+
errors.push(translate('nextcloud-vue', 'A register and schema are required'));
|
|
179
|
+
}
|
|
180
|
+
if (!this.dateField) {
|
|
181
|
+
errors.push(translate('nextcloud-vue', 'A date field is required'));
|
|
182
|
+
}
|
|
183
|
+
return errors
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
export { script as default };
|
|
189
|
+
//# sourceMappingURL=CnWeekStripWidgetForm.vue2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CnWeekStripWidgetForm.vue2.js","sources":["../../../../src/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n\n<template>\n\t<div class=\"cn-week-strip-form\">\n\t\t<div class=\"cn-week-strip-form__row2\">\n\t\t\t<CnRegisterSchemaSelect\n\t\t\t\t:register=\"source.register\"\n\t\t\t\t:schema=\"source.schema\"\n\t\t\t\t@update:register=\"updateSource('register', $event)\"\n\t\t\t\t@update:schema=\"updateSource('schema', $event)\" />\n\t\t</div>\n\n\t\t<div class=\"cn-week-strip-form__row2\">\n\t\t\t<CnFieldPicker\n\t\t\t\t:value=\"dateField\"\n\t\t\t\t:label=\"t('nextcloud-vue', 'Date field')\"\n\t\t\t\t:options=\"availableFields\"\n\t\t\t\tplaceholder=\"deadline\"\n\t\t\t\t@update=\"updateField('dateField', $event)\" />\n\t\t\t<CnFieldPicker\n\t\t\t\t:value=\"titleField\"\n\t\t\t\t:label=\"t('nextcloud-vue', 'Title field')\"\n\t\t\t\t:options=\"availableFields\"\n\t\t\t\tplaceholder=\"title\"\n\t\t\t\t@update=\"updateField('titleField', $event)\" />\n\t\t</div>\n\n\t\t<NcTextField\n\t\t\t:modelValue=\"metaFieldsText\"\n\t\t\t:label=\"t('nextcloud-vue', 'Extra fields under the title (comma separated)')\"\n\t\t\tplaceholder=\"identifier, type\"\n\t\t\t@update:modelValue=\"updateField('metaFieldsText', $event)\" />\n\n\t\t<CnFilterRowsEditor :value=\"filterRows\" :fields=\"availableFields\" @input=\"onFilterRows\" />\n\n\t\t<div class=\"cn-week-strip-form__row2\">\n\t\t\t<NcSelect\n\t\t\t\t:modelValue=\"days\"\n\t\t\t\t:options=\"dayOptions\"\n\t\t\t\t:inputLabel=\"t('nextcloud-vue', 'Days shown')\"\n\t\t\t\t:clearable=\"false\"\n\t\t\t\t@update:modelValue=\"updateField('days', $event)\" />\n\t\t\t<NcTextField\n\t\t\t\t:modelValue=\"itemRoute\"\n\t\t\t\t:label=\"t('nextcloud-vue', 'Page an item opens (page id, optional)')\"\n\t\t\t\t@update:modelValue=\"updateField('itemRoute', $event)\" />\n\t\t</div>\n\n\t\t<NcTextField\n\t\t\t:modelValue=\"emptyText\"\n\t\t\t:label=\"t('nextcloud-vue', 'Text for a day without items')\"\n\t\t\t@update:modelValue=\"updateField('emptyText', $event)\" />\n\t</div>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcSelect, NcTextField } from '@nextcloud/vue'\nimport CnFieldPicker from '../CnFieldPicker/CnFieldPicker.vue'\nimport CnFilterRowsEditor from '../CnFilterRowsEditor/CnFilterRowsEditor.vue'\nimport CnRegisterSchemaSelect from '../CnRegisterSchemaSelect/CnRegisterSchemaSelect.vue'\nimport { fetchSchemaProperties } from '../../utils/fetchSchemaProperties.js'\nimport { filterToRows, rowsToFilter } from '../CnFilterRowsEditor/filterRows.js'\n\n/**\n * CnWeekStripWidgetForm is the settings form of a `week-strip` widget. It\n * edits the source (register, schema, filter), the date field the items are\n * bucketed by, what each item shows, how many days render and the text of an\n * empty day. Static `items` and the `lateWhen` rule are written in the\n * manifest and pass through untouched. Emits `update:content` on every\n * change; `validate()` asks for a register, a schema and a date field unless\n * the widget has static items.\n */\nexport default {\n\tname: 'CnWeekStripWidgetForm',\n\n\tcomponents: { NcSelect, NcTextField, CnFieldPicker, CnFilterRowsEditor, CnRegisterSchemaSelect },\n\n\tprops: {\n\t\t/**\n\t\t * The placement being edited (pre-fills from `editingWidget.content`), or null.\n\t\t *\n\t\t * @type {{content: object}|null}\n\t\t */\n\t\teditingWidget: { type: Object, default: null },\n\t\t/**\n\t\t * Initial content values when not editing (registry defaults).\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tvalue: { type: Object, default: () => ({}) },\n\t},\n\n\temits: [\n\t\t/**\n\t\t * Emitted with the assembled content blob on every field change.\n\t\t *\n\t\t * @event update:content\n\t\t * @type {object}\n\t\t */\n\t\t'update:content',\n\t],\n\n\tdata() {\n\t\tconst initial = this.editingWidget?.content || this.value || {}\n\t\tconst src = initial.source || {}\n\t\treturn {\n\t\t\tinitial,\n\t\t\tsource: { register: src.register ?? '', schema: src.schema ?? '' },\n\t\t\tlimit: src.limit,\n\t\t\tfilterRows: filterToRows(src.filter || {}),\n\t\t\tdateField: initial.dateField ?? '',\n\t\t\ttitleField: initial.titleField ?? '',\n\t\t\tmetaFieldsText: Array.isArray(initial.metaFields) ? initial.metaFields.join(', ') : '',\n\t\t\tdays: Number(initial.days) === 7 ? 7 : 5,\n\t\t\titemRoute: initial.itemRoute ?? '',\n\t\t\temptyText: initial.emptyText ?? '',\n\t\t\tavailableFields: [],\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The day counts on offer: working days or the whole week.\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\tdayOptions() {\n\t\t\treturn [5, 7]\n\t\t},\n\n\t\t/**\n\t\t * The assembled content blob. Keys the form does not edit (static\n\t\t * items, the late rule) are carried over from the initial content.\n\t\t *\n\t\t * @return {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\tassembledContent() {\n\t\t\tconst source = {\n\t\t\t\tregister: this.source.register,\n\t\t\t\tschema: this.source.schema,\n\t\t\t\tfilter: rowsToFilter(this.filterRows),\n\t\t\t}\n\t\t\tif (this.limit !== undefined) {\n\t\t\t\tsource.limit = this.limit\n\t\t\t}\n\t\t\treturn {\n\t\t\t\t...this.initial,\n\t\t\t\tsource,\n\t\t\t\tdateField: this.dateField,\n\t\t\t\ttitleField: this.titleField,\n\t\t\t\tmetaFields: this.metaFieldsText.split(',').map((field) => field.trim()).filter((field) => field !== ''),\n\t\t\t\tdays: this.days,\n\t\t\t\titemRoute: this.itemRoute,\n\t\t\t\temptyText: this.emptyText,\n\t\t\t}\n\t\t},\n\t},\n\n\twatch: {\n\t\t'source.register': 'loadFields',\n\t\t'source.schema': 'loadFields',\n\t},\n\n\tmounted() {\n\t\tthis.loadFields()\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\t/**\n\t\t * Load the schema's field names for the pickers.\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 loadFields() {\n\t\t\tthis.availableFields = await fetchSchemaProperties(this.source.register, this.source.schema)\n\t\t},\n\n\t\t/**\n\t\t * Set one field and emit the assembled content.\n\t\t *\n\t\t * @param {string} field The data key to write.\n\t\t * @param {string|number} value The new value.\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\tupdateField(field, value) {\n\t\t\tthis[field] = value\n\t\t\tthis.$emit('update:content', this.assembledContent)\n\t\t},\n\n\t\t/**\n\t\t * Set the register or the schema and emit.\n\t\t *\n\t\t * @param {'register'|'schema'} field The source key to write.\n\t\t * @param {string} value The chosen slug.\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\tupdateSource(field, value) {\n\t\t\tthis.source[field] = value\n\t\t\tthis.$emit('update:content', this.assembledContent)\n\t\t},\n\n\t\t/**\n\t\t * Take the filter editor's rows and emit.\n\t\t *\n\t\t * @param {Array<{key: string, op: string, value: string}>} rows The rows.\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\tonFilterRows(rows) {\n\t\t\tthis.filterRows = rows\n\t\t\tthis.$emit('update:content', this.assembledContent)\n\t\t},\n\n\t\t/**\n\t\t * Validate the form; an empty array means valid.\n\t\t *\n\t\t * @return {string[]} The validation errors.\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget\n\t\t */\n\t\tvalidate() {\n\t\t\tconst hasStaticItems = Array.isArray(this.initial.items) && this.initial.items.length > 0\n\t\t\tif (hasStaticItems && !this.source.register && !this.source.schema) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\tconst errors = []\n\t\t\tif (!this.source.register || !this.source.schema) {\n\t\t\t\terrors.push(t('nextcloud-vue', 'A register and schema are required'))\n\t\t\t}\n\t\t\tif (!this.dateField) {\n\t\t\t\terrors.push(t('nextcloud-vue', 'A date field is required'))\n\t\t\t}\n\t\t\treturn errors\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-week-strip-form {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 12px;\n}\n\n.cn-week-strip-form__row2 {\n\tdisplay: flex;\n\tgap: 12px;\n\talign-items: flex-end;\n}\n\n.cn-week-strip-form__row2 > * {\n\tflex: 1;\n\tmin-width: 0;\n}\n</style>\n"],"names":["CnFieldPicker","CnFilterRowsEditor","CnRegisterSchemaSelect","t"],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { resolveComponent, openBlock, createElementBlock, createElementVNode, createVNode } from 'vue';
|
|
2
|
+
|
|
3
|
+
const _hoisted_1 = { class: "cn-week-strip-form" };
|
|
4
|
+
const _hoisted_2 = { class: "cn-week-strip-form__row2" };
|
|
5
|
+
const _hoisted_3 = { class: "cn-week-strip-form__row2" };
|
|
6
|
+
const _hoisted_4 = { class: "cn-week-strip-form__row2" };
|
|
7
|
+
|
|
8
|
+
function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
9
|
+
const _component_CnRegisterSchemaSelect = resolveComponent("CnRegisterSchemaSelect");
|
|
10
|
+
const _component_CnFieldPicker = resolveComponent("CnFieldPicker");
|
|
11
|
+
const _component_NcTextField = resolveComponent("NcTextField");
|
|
12
|
+
const _component_CnFilterRowsEditor = resolveComponent("CnFilterRowsEditor");
|
|
13
|
+
const _component_NcSelect = resolveComponent("NcSelect");
|
|
14
|
+
|
|
15
|
+
return (openBlock(), createElementBlock("div", _hoisted_1, [
|
|
16
|
+
createElementVNode("div", _hoisted_2, [
|
|
17
|
+
createVNode(_component_CnRegisterSchemaSelect, {
|
|
18
|
+
register: $data.source.register,
|
|
19
|
+
schema: $data.source.schema,
|
|
20
|
+
"onUpdate:register": _cache[0] || (_cache[0] = $event => ($options.updateSource('register', $event))),
|
|
21
|
+
"onUpdate:schema": _cache[1] || (_cache[1] = $event => ($options.updateSource('schema', $event)))
|
|
22
|
+
}, null, 8 /* PROPS */, ["register", "schema"])
|
|
23
|
+
]),
|
|
24
|
+
createElementVNode("div", _hoisted_3, [
|
|
25
|
+
createVNode(_component_CnFieldPicker, {
|
|
26
|
+
value: $data.dateField,
|
|
27
|
+
label: $options.t('nextcloud-vue', 'Date field'),
|
|
28
|
+
options: $data.availableFields,
|
|
29
|
+
placeholder: "deadline",
|
|
30
|
+
onUpdate: _cache[2] || (_cache[2] = $event => ($options.updateField('dateField', $event)))
|
|
31
|
+
}, null, 8 /* PROPS */, ["value", "label", "options"]),
|
|
32
|
+
createVNode(_component_CnFieldPicker, {
|
|
33
|
+
value: $data.titleField,
|
|
34
|
+
label: $options.t('nextcloud-vue', 'Title field'),
|
|
35
|
+
options: $data.availableFields,
|
|
36
|
+
placeholder: "title",
|
|
37
|
+
onUpdate: _cache[3] || (_cache[3] = $event => ($options.updateField('titleField', $event)))
|
|
38
|
+
}, null, 8 /* PROPS */, ["value", "label", "options"])
|
|
39
|
+
]),
|
|
40
|
+
createVNode(_component_NcTextField, {
|
|
41
|
+
modelValue: $data.metaFieldsText,
|
|
42
|
+
label: $options.t('nextcloud-vue', 'Extra fields under the title (comma separated)'),
|
|
43
|
+
placeholder: "identifier, type",
|
|
44
|
+
"onUpdate:modelValue": _cache[4] || (_cache[4] = $event => ($options.updateField('metaFieldsText', $event)))
|
|
45
|
+
}, null, 8 /* PROPS */, ["modelValue", "label"]),
|
|
46
|
+
createVNode(_component_CnFilterRowsEditor, {
|
|
47
|
+
value: $data.filterRows,
|
|
48
|
+
fields: $data.availableFields,
|
|
49
|
+
onInput: $options.onFilterRows
|
|
50
|
+
}, null, 8 /* PROPS */, ["value", "fields", "onInput"]),
|
|
51
|
+
createElementVNode("div", _hoisted_4, [
|
|
52
|
+
createVNode(_component_NcSelect, {
|
|
53
|
+
modelValue: $data.days,
|
|
54
|
+
options: $options.dayOptions,
|
|
55
|
+
inputLabel: $options.t('nextcloud-vue', 'Days shown'),
|
|
56
|
+
clearable: false,
|
|
57
|
+
"onUpdate:modelValue": _cache[5] || (_cache[5] = $event => ($options.updateField('days', $event)))
|
|
58
|
+
}, null, 8 /* PROPS */, ["modelValue", "options", "inputLabel"]),
|
|
59
|
+
createVNode(_component_NcTextField, {
|
|
60
|
+
modelValue: $data.itemRoute,
|
|
61
|
+
label: $options.t('nextcloud-vue', 'Page an item opens (page id, optional)'),
|
|
62
|
+
"onUpdate:modelValue": _cache[6] || (_cache[6] = $event => ($options.updateField('itemRoute', $event)))
|
|
63
|
+
}, null, 8 /* PROPS */, ["modelValue", "label"])
|
|
64
|
+
]),
|
|
65
|
+
createVNode(_component_NcTextField, {
|
|
66
|
+
modelValue: $data.emptyText,
|
|
67
|
+
label: $options.t('nextcloud-vue', 'Text for a day without items'),
|
|
68
|
+
"onUpdate:modelValue": _cache[7] || (_cache[7] = $event => ($options.updateField('emptyText', $event)))
|
|
69
|
+
}, null, 8 /* PROPS */, ["modelValue", "label"])
|
|
70
|
+
]))
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export { render };
|
|
74
|
+
//# sourceMappingURL=CnWeekStripWidgetForm.vue3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CnWeekStripWidgetForm.vue3.js","sources":["../../../../src/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue?vue&type=template&id=4a9dc393&lang.js"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n\n<template>\n\t<div class=\"cn-week-strip-form\">\n\t\t<div class=\"cn-week-strip-form__row2\">\n\t\t\t<CnRegisterSchemaSelect\n\t\t\t\t:register=\"source.register\"\n\t\t\t\t:schema=\"source.schema\"\n\t\t\t\t@update:register=\"updateSource('register', $event)\"\n\t\t\t\t@update:schema=\"updateSource('schema', $event)\" />\n\t\t</div>\n\n\t\t<div class=\"cn-week-strip-form__row2\">\n\t\t\t<CnFieldPicker\n\t\t\t\t:value=\"dateField\"\n\t\t\t\t:label=\"t('nextcloud-vue', 'Date field')\"\n\t\t\t\t:options=\"availableFields\"\n\t\t\t\tplaceholder=\"deadline\"\n\t\t\t\t@update=\"updateField('dateField', $event)\" />\n\t\t\t<CnFieldPicker\n\t\t\t\t:value=\"titleField\"\n\t\t\t\t:label=\"t('nextcloud-vue', 'Title field')\"\n\t\t\t\t:options=\"availableFields\"\n\t\t\t\tplaceholder=\"title\"\n\t\t\t\t@update=\"updateField('titleField', $event)\" />\n\t\t</div>\n\n\t\t<NcTextField\n\t\t\t:modelValue=\"metaFieldsText\"\n\t\t\t:label=\"t('nextcloud-vue', 'Extra fields under the title (comma separated)')\"\n\t\t\tplaceholder=\"identifier, type\"\n\t\t\t@update:modelValue=\"updateField('metaFieldsText', $event)\" />\n\n\t\t<CnFilterRowsEditor :value=\"filterRows\" :fields=\"availableFields\" @input=\"onFilterRows\" />\n\n\t\t<div class=\"cn-week-strip-form__row2\">\n\t\t\t<NcSelect\n\t\t\t\t:modelValue=\"days\"\n\t\t\t\t:options=\"dayOptions\"\n\t\t\t\t:inputLabel=\"t('nextcloud-vue', 'Days shown')\"\n\t\t\t\t:clearable=\"false\"\n\t\t\t\t@update:modelValue=\"updateField('days', $event)\" />\n\t\t\t<NcTextField\n\t\t\t\t:modelValue=\"itemRoute\"\n\t\t\t\t:label=\"t('nextcloud-vue', 'Page an item opens (page id, optional)')\"\n\t\t\t\t@update:modelValue=\"updateField('itemRoute', $event)\" />\n\t\t</div>\n\n\t\t<NcTextField\n\t\t\t:modelValue=\"emptyText\"\n\t\t\t:label=\"t('nextcloud-vue', 'Text for a day without items')\"\n\t\t\t@update:modelValue=\"updateField('emptyText', $event)\" />\n\t</div>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcSelect, NcTextField } from '@nextcloud/vue'\nimport CnFieldPicker from '../CnFieldPicker/CnFieldPicker.vue'\nimport CnFilterRowsEditor from '../CnFilterRowsEditor/CnFilterRowsEditor.vue'\nimport CnRegisterSchemaSelect from '../CnRegisterSchemaSelect/CnRegisterSchemaSelect.vue'\nimport { fetchSchemaProperties } from '../../utils/fetchSchemaProperties.js'\nimport { filterToRows, rowsToFilter } from '../CnFilterRowsEditor/filterRows.js'\n\n/**\n * CnWeekStripWidgetForm is the settings form of a `week-strip` widget. It\n * edits the source (register, schema, filter), the date field the items are\n * bucketed by, what each item shows, how many days render and the text of an\n * empty day. Static `items` and the `lateWhen` rule are written in the\n * manifest and pass through untouched. Emits `update:content` on every\n * change; `validate()` asks for a register, a schema and a date field unless\n * the widget has static items.\n */\nexport default {\n\tname: 'CnWeekStripWidgetForm',\n\n\tcomponents: { NcSelect, NcTextField, CnFieldPicker, CnFilterRowsEditor, CnRegisterSchemaSelect },\n\n\tprops: {\n\t\t/**\n\t\t * The placement being edited (pre-fills from `editingWidget.content`), or null.\n\t\t *\n\t\t * @type {{content: object}|null}\n\t\t */\n\t\teditingWidget: { type: Object, default: null },\n\t\t/**\n\t\t * Initial content values when not editing (registry defaults).\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tvalue: { type: Object, default: () => ({}) },\n\t},\n\n\temits: [\n\t\t/**\n\t\t * Emitted with the assembled content blob on every field change.\n\t\t *\n\t\t * @event update:content\n\t\t * @type {object}\n\t\t */\n\t\t'update:content',\n\t],\n\n\tdata() {\n\t\tconst initial = this.editingWidget?.content || this.value || {}\n\t\tconst src = initial.source || {}\n\t\treturn {\n\t\t\tinitial,\n\t\t\tsource: { register: src.register ?? '', schema: src.schema ?? '' },\n\t\t\tlimit: src.limit,\n\t\t\tfilterRows: filterToRows(src.filter || {}),\n\t\t\tdateField: initial.dateField ?? '',\n\t\t\ttitleField: initial.titleField ?? '',\n\t\t\tmetaFieldsText: Array.isArray(initial.metaFields) ? initial.metaFields.join(', ') : '',\n\t\t\tdays: Number(initial.days) === 7 ? 7 : 5,\n\t\t\titemRoute: initial.itemRoute ?? '',\n\t\t\temptyText: initial.emptyText ?? '',\n\t\t\tavailableFields: [],\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The day counts on offer: working days or the whole week.\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\tdayOptions() {\n\t\t\treturn [5, 7]\n\t\t},\n\n\t\t/**\n\t\t * The assembled content blob. Keys the form does not edit (static\n\t\t * items, the late rule) are carried over from the initial content.\n\t\t *\n\t\t * @return {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\tassembledContent() {\n\t\t\tconst source = {\n\t\t\t\tregister: this.source.register,\n\t\t\t\tschema: this.source.schema,\n\t\t\t\tfilter: rowsToFilter(this.filterRows),\n\t\t\t}\n\t\t\tif (this.limit !== undefined) {\n\t\t\t\tsource.limit = this.limit\n\t\t\t}\n\t\t\treturn {\n\t\t\t\t...this.initial,\n\t\t\t\tsource,\n\t\t\t\tdateField: this.dateField,\n\t\t\t\ttitleField: this.titleField,\n\t\t\t\tmetaFields: this.metaFieldsText.split(',').map((field) => field.trim()).filter((field) => field !== ''),\n\t\t\t\tdays: this.days,\n\t\t\t\titemRoute: this.itemRoute,\n\t\t\t\temptyText: this.emptyText,\n\t\t\t}\n\t\t},\n\t},\n\n\twatch: {\n\t\t'source.register': 'loadFields',\n\t\t'source.schema': 'loadFields',\n\t},\n\n\tmounted() {\n\t\tthis.loadFields()\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\t/**\n\t\t * Load the schema's field names for the pickers.\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 loadFields() {\n\t\t\tthis.availableFields = await fetchSchemaProperties(this.source.register, this.source.schema)\n\t\t},\n\n\t\t/**\n\t\t * Set one field and emit the assembled content.\n\t\t *\n\t\t * @param {string} field The data key to write.\n\t\t * @param {string|number} value The new value.\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\tupdateField(field, value) {\n\t\t\tthis[field] = value\n\t\t\tthis.$emit('update:content', this.assembledContent)\n\t\t},\n\n\t\t/**\n\t\t * Set the register or the schema and emit.\n\t\t *\n\t\t * @param {'register'|'schema'} field The source key to write.\n\t\t * @param {string} value The chosen slug.\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\tupdateSource(field, value) {\n\t\t\tthis.source[field] = value\n\t\t\tthis.$emit('update:content', this.assembledContent)\n\t\t},\n\n\t\t/**\n\t\t * Take the filter editor's rows and emit.\n\t\t *\n\t\t * @param {Array<{key: string, op: string, value: string}>} rows The rows.\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\tonFilterRows(rows) {\n\t\t\tthis.filterRows = rows\n\t\t\tthis.$emit('update:content', this.assembledContent)\n\t\t},\n\n\t\t/**\n\t\t * Validate the form; an empty array means valid.\n\t\t *\n\t\t * @return {string[]} The validation errors.\n\t\t * @spec openspec/changes/workplace-dashboard-primitives/specs/workplace-dashboard-primitives/spec.md#requirement-week-strip-widget\n\t\t */\n\t\tvalidate() {\n\t\t\tconst hasStaticItems = Array.isArray(this.initial.items) && this.initial.items.length > 0\n\t\t\tif (hasStaticItems && !this.source.register && !this.source.schema) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\tconst errors = []\n\t\t\tif (!this.source.register || !this.source.schema) {\n\t\t\t\terrors.push(t('nextcloud-vue', 'A register and schema are required'))\n\t\t\t}\n\t\t\tif (!this.dateField) {\n\t\t\t\terrors.push(t('nextcloud-vue', 'A date field is required'))\n\t\t\t}\n\t\t\treturn errors\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-week-strip-form {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 12px;\n}\n\n.cn-week-strip-form__row2 {\n\tdisplay: flex;\n\tgap: 12px;\n\talign-items: flex-end;\n}\n\n.cn-week-strip-form__row2 > * {\n\tflex: 1;\n\tmin-width: 0;\n}\n</style>\n"],"names":["_createVNode","_createElementVNode"],"mappings":"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"}
|