@conduction/nextcloud-vue 2.59.0 → 2.60.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue2.js +14 -1
- package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue2.js.map +1 -1
- package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue3.js.map +1 -1
- package/dist/esm/components/CnAppNav/CnAppNav.vue2.js +39 -0
- package/dist/esm/components/CnAppNav/CnAppNav.vue2.js.map +1 -1
- package/dist/esm/components/CnAppNav/CnAppNav.vue3.js +46 -4
- package/dist/esm/components/CnAppNav/CnAppNav.vue3.js.map +1 -1
- package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue2.js +224 -9
- package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue3.js +79 -25
- package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnBannerWidgetForm/CnBannerWidgetForm.vue2.js +42 -3
- package/dist/esm/components/CnBannerWidgetForm/CnBannerWidgetForm.vue2.js.map +1 -1
- package/dist/esm/components/CnBannerWidgetForm/CnBannerWidgetForm.vue3.js +39 -6
- package/dist/esm/components/CnBannerWidgetForm/CnBannerWidgetForm.vue3.js.map +1 -1
- package/dist/esm/components/CnBoardView/CnBoardView.vue2.js +46 -0
- package/dist/esm/components/CnBoardView/CnBoardView.vue2.js.map +1 -1
- package/dist/esm/components/CnBoardView/CnBoardView.vue3.js +11 -4
- package/dist/esm/components/CnBoardView/CnBoardView.vue3.js.map +1 -1
- package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue.js +10 -0
- package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue.js.map +1 -0
- package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue2.js +39 -0
- package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue2.js.map +1 -0
- package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue3.js +16 -0
- package/dist/esm/components/CnBrandStripe/CnBrandStripe.vue3.js.map +1 -0
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js +117 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js.map +1 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js +147 -89
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js.map +1 -1
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue.js +10 -0
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue.js.map +1 -0
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue2.js +259 -0
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue2.js.map +1 -0
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue3.js +131 -0
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue3.js.map +1 -0
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue.js +10 -0
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue.js.map +1 -0
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue2.js +116 -0
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue3.js +24 -0
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +503 -28
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js +300 -142
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue.js +10 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue.js.map +1 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue2.js +237 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue2.js.map +1 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue3.js +120 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewList.vue3.js.map +1 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue.js +10 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue.js.map +1 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue2.js +77 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue3.js +27 -0
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue2.js +169 -12
- package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue3.js +15 -7
- package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnHeaderWidgetForm/CnHeaderWidgetForm.vue2.js +37 -3
- package/dist/esm/components/CnHeaderWidgetForm/CnHeaderWidgetForm.vue2.js.map +1 -1
- package/dist/esm/components/CnHeaderWidgetForm/CnHeaderWidgetForm.vue3.js +44 -16
- package/dist/esm/components/CnHeaderWidgetForm/CnHeaderWidgetForm.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +132 -3
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +6 -3
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue.js +10 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue.js.map +1 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue2.js +150 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue2.js.map +1 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue3.js +106 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepCard.vue3.js.map +1 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue.js +9 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue.js.map +1 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue2.js +47 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue3.js +17 -0
- package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue2.js +49 -0
- package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectDataWidget/CnObjectDataWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectDataWidgetForm/CnObjectDataWidgetForm.vue2.js +6 -0
- package/dist/esm/components/CnObjectDataWidgetForm/CnObjectDataWidgetForm.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectDataWidgetForm/CnObjectDataWidgetForm.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectKanban/CnObjectKanban.vue2.js +46 -0
- package/dist/esm/components/CnObjectKanban/CnObjectKanban.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectKanban/CnObjectKanban.vue3.js +15 -3
- package/dist/esm/components/CnObjectKanban/CnObjectKanban.vue3.js.map +1 -1
- package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue2.js +37 -1
- package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue2.js.map +1 -1
- package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue3.js +29 -13
- package/dist/esm/components/CnQuickFilterBar/CnQuickFilterBar.vue3.js.map +1 -1
- package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue2.js +50 -3
- package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue2.js.map +1 -1
- package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue3.js.map +1 -1
- package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue.js +10 -0
- package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue.js.map +1 -0
- package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue2.js +186 -0
- package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue2.js.map +1 -0
- package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue3.js +46 -0
- package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue3.js.map +1 -0
- package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue.js +11 -0
- package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue.js.map +1 -0
- package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue2.js +298 -0
- package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue3.js +77 -0
- package/dist/esm/components/CnStackedBarWidget/CnStackedBarWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue.js +10 -0
- package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue.js.map +1 -0
- package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue2.js +169 -0
- package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue2.js.map +1 -0
- package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue3.js +48 -0
- package/dist/esm/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue3.js.map +1 -0
- package/dist/esm/components/CnTabs/CnTab.vue2.js +35 -0
- package/dist/esm/components/CnTabs/CnTab.vue2.js.map +1 -1
- package/dist/esm/components/CnTabs/CnTab.vue3.js.map +1 -1
- package/dist/esm/components/CnTabs/CnTabs.vue2.js +120 -7
- package/dist/esm/components/CnTabs/CnTabs.vue2.js.map +1 -1
- package/dist/esm/components/CnTabs/CnTabs.vue3.js +57 -5
- package/dist/esm/components/CnTabs/CnTabs.vue3.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +59 -4
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js +6 -2
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue.js +10 -0
- package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue.js.map +1 -0
- package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue2.js +484 -0
- package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue3.js +115 -0
- package/dist/esm/components/CnWeekStripWidget/CnWeekStripWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue.js +10 -0
- package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue.js.map +1 -0
- package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue2.js +189 -0
- package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue2.js.map +1 -0
- package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue3.js +74 -0
- package/dist/esm/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue3.js.map +1 -0
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +82 -8
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
- package/dist/esm/index.js +10 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/l10n/en.json.js +54 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +54 -1
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/nextcloud-vue.css +931 -4
- package/dist/esm/utils/dateVariant.js +124 -0
- package/dist/esm/utils/dateVariant.js.map +1 -0
- package/dist/esm/utils/detailActionModel.js +260 -0
- package/dist/esm/utils/detailActionModel.js.map +1 -0
- package/dist/esm/utils/dueRule.js +84 -0
- package/dist/esm/utils/dueRule.js.map +1 -0
- package/dist/esm/utils/fetchAggregate.js +37 -1
- package/dist/esm/utils/fetchAggregate.js.map +1 -1
- package/dist/esm/utils/fetchFilterCounts.js +186 -0
- package/dist/esm/utils/fetchFilterCounts.js.map +1 -0
- package/dist/esm/utils/libraryWidgetKeys.js +5 -0
- package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
- package/dist/esm/utils/readPath.js +30 -0
- package/dist/esm/utils/readPath.js.map +1 -0
- package/dist/esm/utils/validateManifestV2.compiled.js +2 -2
- package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +14970 -8991
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +931 -4
- package/l10n/en.json +54 -1
- package/l10n/nl.json +54 -1
- package/package.json +1 -1
- package/scripts/.jsdoc-baselines.json +3 -0
- package/src/components/CnActionsMenu/CnActionsMenu.vue +14 -1
- package/src/components/CnAppNav/CnAppNav.md +26 -0
- package/src/components/CnAppNav/CnAppNav.vue +104 -1
- package/src/components/CnBannerWidget/CnBannerWidget.vue +365 -10
- package/src/components/CnBannerWidgetForm/CnBannerWidgetForm.vue +65 -3
- package/src/components/CnBoardView/CnBoardView.vue +77 -0
- package/src/components/CnBrandStripe/CnBrandStripe.md +22 -0
- package/src/components/CnBrandStripe/CnBrandStripe.vue +100 -0
- package/src/components/CnBrandStripe/index.js +4 -0
- package/src/components/CnCellRenderer/CnCellRenderer.vue +207 -1
- package/src/components/CnConversationThread/CnConversationThread.md +51 -0
- package/src/components/CnConversationThread/CnConversationThread.vue +457 -0
- package/src/components/CnConversationThread/CnConversationWidget.vue +144 -0
- package/src/components/CnConversationThread/index.js +4 -0
- package/src/components/CnDetailPage/CnDetailPage.md +16 -0
- package/src/components/CnDetailPage/CnDetailPage.vue +683 -48
- package/src/components/CnDocumentReviewList/CnDocumentReviewList.md +55 -0
- package/src/components/CnDocumentReviewList/CnDocumentReviewList.vue +384 -0
- package/src/components/CnDocumentReviewList/CnDocumentReviewWidget.vue +108 -0
- package/src/components/CnDocumentReviewList/index.js +4 -0
- package/src/components/CnHeaderWidget/CnHeaderWidget.vue +189 -14
- package/src/components/CnHeaderWidgetForm/CnHeaderWidgetForm.vue +53 -3
- package/src/components/CnIndexPage/CnIndexPage.vue +135 -3
- package/src/components/CnNextStepCard/CnNextStepCard.md +40 -0
- package/src/components/CnNextStepCard/CnNextStepCard.vue +319 -0
- package/src/components/CnNextStepCard/CnNextStepWidget.vue +59 -0
- package/src/components/CnNextStepCard/index.js +4 -0
- package/src/components/CnObjectDataWidget/CnObjectDataWidget.vue +49 -0
- package/src/components/CnObjectDataWidgetForm/CnObjectDataWidgetForm.vue +6 -0
- package/src/components/CnObjectKanban/CnObjectKanban.vue +86 -2
- package/src/components/CnQuickFilterBar/CnQuickFilterBar.md +3 -0
- package/src/components/CnQuickFilterBar/CnQuickFilterBar.vue +60 -1
- package/src/components/CnSavedViewsControl/CnSavedViewsControl.vue +50 -3
- package/src/components/CnSegmentedControl/CnSegmentedControl.md +46 -0
- package/src/components/CnSegmentedControl/CnSegmentedControl.vue +291 -0
- package/src/components/CnSegmentedControl/index.js +4 -0
- package/src/components/CnStackedBarWidget/CnStackedBarWidget.md +15 -0
- package/src/components/CnStackedBarWidget/CnStackedBarWidget.vue +414 -0
- package/src/components/CnStackedBarWidget/index.js +14 -0
- package/src/components/CnStackedBarWidgetForm/CnStackedBarWidgetForm.vue +224 -0
- package/src/components/CnStackedBarWidgetForm/index.js +4 -0
- package/src/components/CnTabs/CnTab.vue +35 -0
- package/src/components/CnTabs/CnTabs.vue +244 -10
- package/src/components/CnTabsWidget/CnTabsWidget.vue +63 -4
- package/src/components/CnWeekStripWidget/CnWeekStripWidget.md +31 -0
- package/src/components/CnWeekStripWidget/CnWeekStripWidget.vue +668 -0
- package/src/components/CnWeekStripWidget/index.js +14 -0
- package/src/components/CnWeekStripWidgetForm/CnWeekStripWidgetForm.vue +265 -0
- package/src/components/CnWeekStripWidgetForm/index.js +4 -0
- package/src/components/CnWidgetGrid/registerDashboardWidgets.js +74 -0
- package/src/components/index.js +11 -0
- package/src/css/detail-page.css +47 -0
- package/src/index.js +9 -0
- package/src/schemas/app-manifest-v2.schema.json +389 -1
- package/src/schemas/app-manifest.schema.json +2 -1
- package/src/utils/dateVariant.js +120 -0
- package/src/utils/detailActionModel.js +256 -0
- package/src/utils/dueRule.js +94 -0
- package/src/utils/fetchAggregate.js +36 -0
- package/src/utils/fetchFilterCounts.js +182 -0
- package/src/utils/index.js +1 -0
- package/src/utils/libraryWidgetKeys.js +5 -0
- package/src/utils/readPath.js +27 -0
- package/src/utils/validateManifestV2.compiled.js +2 -2
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import script from './CnNextStepCard.vue2.js';
|
|
2
|
+
import { render } from './CnNextStepCard.vue3.js';
|
|
3
|
+
|
|
4
|
+
script.render = render;
|
|
5
|
+
script.__scopeId = "data-v-3a9ce962";
|
|
6
|
+
script.__file = "src/components/CnNextStepCard/CnNextStepCard.vue";
|
|
7
|
+
const __sfc_main = script;
|
|
8
|
+
|
|
9
|
+
export { __sfc_main as default };
|
|
10
|
+
//# sourceMappingURL=CnNextStepCard.vue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CnNextStepCard.vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { translate } from '@nextcloud/l10n';
|
|
2
|
+
import { NcButton } from '@nextcloud/vue';
|
|
3
|
+
import Check from 'vue-material-design-icons/Check.vue';
|
|
4
|
+
|
|
5
|
+
let nextStepCardUid = 0;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* CnNextStepCard: what this record needs now, next to the button that does it.
|
|
9
|
+
*
|
|
10
|
+
* A short checklist for the current step and one primary action. It answers
|
|
11
|
+
* "what do I do next?" on a record whose menu would otherwise make the handler
|
|
12
|
+
* guess. Renders nothing when there is no checklist, so a step that needs no
|
|
13
|
+
* explaining shows no empty card.
|
|
14
|
+
*
|
|
15
|
+
* ```vue
|
|
16
|
+
* <CnNextStepCard
|
|
17
|
+
* title="What now? Step 2: handling"
|
|
18
|
+
* :items="[
|
|
19
|
+
* { label: 'Receipt confirmed', done: true },
|
|
20
|
+
* { label: 'Review the open documents', hint: '2 of 5 done' },
|
|
21
|
+
* { label: 'Draft the decision' },
|
|
22
|
+
* ]"
|
|
23
|
+
* action-label="Continue reviewing"
|
|
24
|
+
* after="Then: step 3, decision"
|
|
25
|
+
* @action="onContinue" />
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* CnDetailPage renders this card from its `nextStep` config, and the
|
|
29
|
+
* `next-step` detail widget type renders it inside a grid.
|
|
30
|
+
*/
|
|
31
|
+
var script = {
|
|
32
|
+
name: 'CnNextStepCard',
|
|
33
|
+
|
|
34
|
+
components: {
|
|
35
|
+
Check,
|
|
36
|
+
NcButton,
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
props: {
|
|
40
|
+
/** Heading of the card, for example "What now? Step 2: handling". */
|
|
41
|
+
title: {
|
|
42
|
+
type: String,
|
|
43
|
+
default: '',
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
/** Element the heading renders as. Pick the level that fits the page outline. */
|
|
47
|
+
titleTag: {
|
|
48
|
+
type: String,
|
|
49
|
+
default: 'h3',
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The checklist: `{ label, done?, hint? }` per item. The first item
|
|
54
|
+
* that is not done is emphasised as the one to pick up now.
|
|
55
|
+
*/
|
|
56
|
+
items: {
|
|
57
|
+
type: Array,
|
|
58
|
+
default: () => [],
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
/** Label of the primary button. Empty renders no button. */
|
|
62
|
+
actionLabel: {
|
|
63
|
+
type: String,
|
|
64
|
+
default: '',
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
/** DOM id for the primary button, so a skip link can land on it. */
|
|
68
|
+
actionId: {
|
|
69
|
+
type: String,
|
|
70
|
+
default: '',
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
/** Disable the primary button, for example while its request is in flight. */
|
|
74
|
+
actionDisabled: {
|
|
75
|
+
type: Boolean,
|
|
76
|
+
default: false,
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
/** One line under the button saying what follows, for example "Then: step 3, decision". */
|
|
80
|
+
after: {
|
|
81
|
+
type: String,
|
|
82
|
+
default: '',
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
/** Text state of a done item, read by screen readers. */
|
|
86
|
+
doneLabel: {
|
|
87
|
+
type: String,
|
|
88
|
+
default: () => translate('nextcloud-vue', 'Done'),
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
/** Text state of an open item, read by screen readers. */
|
|
92
|
+
todoLabel: {
|
|
93
|
+
type: String,
|
|
94
|
+
default: () => translate('nextcloud-vue', 'To do'),
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
emits: [
|
|
99
|
+
/** The primary button was pressed. */
|
|
100
|
+
'action',
|
|
101
|
+
],
|
|
102
|
+
|
|
103
|
+
data() {
|
|
104
|
+
nextStepCardUid += 1;
|
|
105
|
+
return {
|
|
106
|
+
titleId: `cn-next-step-title-${nextStepCardUid}`,
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
|
|
110
|
+
computed: {
|
|
111
|
+
/**
|
|
112
|
+
* The items that can render: an object with a label.
|
|
113
|
+
*
|
|
114
|
+
* @return {Array<{label: string, done: boolean, hint: string}>} The checklist.
|
|
115
|
+
* @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-next-step-card
|
|
116
|
+
*/
|
|
117
|
+
normalisedItems() {
|
|
118
|
+
return (Array.isArray(this.items) ? this.items : [])
|
|
119
|
+
.filter((item) => item && typeof item.label === 'string' && item.label !== '')
|
|
120
|
+
.map((item) => ({
|
|
121
|
+
label: item.label,
|
|
122
|
+
done: item.done === true,
|
|
123
|
+
hint: typeof item.hint === 'string' ? item.hint : '',
|
|
124
|
+
}))
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Index of the first open item, the one to pick up now.
|
|
129
|
+
*
|
|
130
|
+
* @return {number} The index, or -1 when everything is done.
|
|
131
|
+
* @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-next-step-card
|
|
132
|
+
*/
|
|
133
|
+
currentIndex() {
|
|
134
|
+
return this.normalisedItems.findIndex((item) => !item.done)
|
|
135
|
+
},
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Accessible name for a card without a title.
|
|
139
|
+
*
|
|
140
|
+
* @return {string} The label.
|
|
141
|
+
* @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-next-step-card
|
|
142
|
+
*/
|
|
143
|
+
fallbackLabel() {
|
|
144
|
+
return translate('nextcloud-vue', 'Next step')
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
export { script as default };
|
|
150
|
+
//# sourceMappingURL=CnNextStepCard.vue2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CnNextStepCard.vue2.js","sources":["../../../../src/components/CnNextStepCard/CnNextStepCard.vue"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n\n<template>\n\t<section\n\t\tv-if=\"normalisedItems.length > 0\"\n\t\tclass=\"cn-next-step-card\"\n\t\tdata-testid=\"cn-next-step-card\"\n\t\t:aria-labelledby=\"title ? titleId : null\"\n\t\t:aria-label=\"title ? null : fallbackLabel\">\n\t\t<div class=\"cn-next-step-card__main\">\n\t\t\t<component\n\t\t\t\t:is=\"titleTag\"\n\t\t\t\tv-if=\"title\"\n\t\t\t\t:id=\"titleId\"\n\t\t\t\tclass=\"cn-next-step-card__title\">\n\t\t\t\t{{ title }}\n\t\t\t</component>\n\t\t\t<ul class=\"cn-next-step-card__list\">\n\t\t\t\t<li\n\t\t\t\t\tv-for=\"(item, index) in normalisedItems\"\n\t\t\t\t\t:key=\"`${index}-${item.label}`\"\n\t\t\t\t\tclass=\"cn-next-step-card__item\"\n\t\t\t\t\t:class=\"{\n\t\t\t\t\t\t'cn-next-step-card__item--done': item.done,\n\t\t\t\t\t\t'cn-next-step-card__item--current': index === currentIndex,\n\t\t\t\t\t}\"\n\t\t\t\t\tdata-testid=\"cn-next-step-item\">\n\t\t\t\t\t<span class=\"cn-next-step-card__marker\" aria-hidden=\"true\">\n\t\t\t\t\t\t<Check v-if=\"item.done\" :size=\"14\" />\n\t\t\t\t\t</span>\n\t\t\t\t\t<span class=\"cn-next-step-card__label\">{{ item.label }}</span>\n\t\t\t\t\t<span v-if=\"item.hint\" class=\"cn-next-step-card__hint\">{{ item.hint }}</span>\n\t\t\t\t\t<!-- The state in words. The marker is a shape and a colour, and\n\t\t\t\t\t neither reaches a screen reader or a reader who cannot tell\n\t\t\t\t\t the two colours apart. -->\n\t\t\t\t\t<span class=\"cn-next-step-card__state\">{{ item.done ? doneLabel : todoLabel }}</span>\n\t\t\t\t</li>\n\t\t\t</ul>\n\t\t</div>\n\t\t<div v-if=\"actionLabel || $slots.action || after\" class=\"cn-next-step-card__side\">\n\t\t\t<!-- @slot action Replace the primary button, for a host that renders its own control. -->\n\t\t\t<slot name=\"action\">\n\t\t\t\t<NcButton\n\t\t\t\t\tv-if=\"actionLabel\"\n\t\t\t\t\t:id=\"actionId || null\"\n\t\t\t\t\tvariant=\"primary\"\n\t\t\t\t\t:disabled=\"actionDisabled\"\n\t\t\t\t\tdata-testid=\"cn-next-step-action\"\n\t\t\t\t\t@click=\"$emit('action')\">\n\t\t\t\t\t{{ actionLabel }}\n\t\t\t\t</NcButton>\n\t\t\t</slot>\n\t\t\t<span v-if=\"after\" class=\"cn-next-step-card__after\">{{ after }}</span>\n\t\t</div>\n\t</section>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcButton } from '@nextcloud/vue'\nimport Check from 'vue-material-design-icons/Check.vue'\n\nlet nextStepCardUid = 0\n\n/**\n * CnNextStepCard: what this record needs now, next to the button that does it.\n *\n * A short checklist for the current step and one primary action. It answers\n * \"what do I do next?\" on a record whose menu would otherwise make the handler\n * guess. Renders nothing when there is no checklist, so a step that needs no\n * explaining shows no empty card.\n *\n * ```vue\n * <CnNextStepCard\n * title=\"What now? Step 2: handling\"\n * :items=\"[\n * { label: 'Receipt confirmed', done: true },\n * { label: 'Review the open documents', hint: '2 of 5 done' },\n * { label: 'Draft the decision' },\n * ]\"\n * action-label=\"Continue reviewing\"\n * after=\"Then: step 3, decision\"\n * @action=\"onContinue\" />\n * ```\n *\n * CnDetailPage renders this card from its `nextStep` config, and the\n * `next-step` detail widget type renders it inside a grid.\n */\nexport default {\n\tname: 'CnNextStepCard',\n\n\tcomponents: {\n\t\tCheck,\n\t\tNcButton,\n\t},\n\n\tprops: {\n\t\t/** Heading of the card, for example \"What now? Step 2: handling\". */\n\t\ttitle: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Element the heading renders as. Pick the level that fits the page outline. */\n\t\ttitleTag: {\n\t\t\ttype: String,\n\t\t\tdefault: 'h3',\n\t\t},\n\n\t\t/**\n\t\t * The checklist: `{ label, done?, hint? }` per item. The first item\n\t\t * that is not done is emphasised as the one to pick up now.\n\t\t */\n\t\titems: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** Label of the primary button. Empty renders no button. */\n\t\tactionLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** DOM id for the primary button, so a skip link can land on it. */\n\t\tactionId: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Disable the primary button, for example while its request is in flight. */\n\t\tactionDisabled: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** One line under the button saying what follows, for example \"Then: step 3, decision\". */\n\t\tafter: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Text state of a done item, read by screen readers. */\n\t\tdoneLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Done'),\n\t\t},\n\n\t\t/** Text state of an open item, read by screen readers. */\n\t\ttodoLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'To do'),\n\t\t},\n\t},\n\n\temits: [\n\t\t/** The primary button was pressed. */\n\t\t'action',\n\t],\n\n\tdata() {\n\t\tnextStepCardUid += 1\n\t\treturn {\n\t\t\ttitleId: `cn-next-step-title-${nextStepCardUid}`,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The items that can render: an object with a label.\n\t\t *\n\t\t * @return {Array<{label: string, done: boolean, hint: string}>} The checklist.\n\t\t * @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-next-step-card\n\t\t */\n\t\tnormalisedItems() {\n\t\t\treturn (Array.isArray(this.items) ? this.items : [])\n\t\t\t\t.filter((item) => item && typeof item.label === 'string' && item.label !== '')\n\t\t\t\t.map((item) => ({\n\t\t\t\t\tlabel: item.label,\n\t\t\t\t\tdone: item.done === true,\n\t\t\t\t\thint: typeof item.hint === 'string' ? item.hint : '',\n\t\t\t\t}))\n\t\t},\n\n\t\t/**\n\t\t * Index of the first open item, the one to pick up now.\n\t\t *\n\t\t * @return {number} The index, or -1 when everything is done.\n\t\t * @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-next-step-card\n\t\t */\n\t\tcurrentIndex() {\n\t\t\treturn this.normalisedItems.findIndex((item) => !item.done)\n\t\t},\n\n\t\t/**\n\t\t * Accessible name for a card without a title.\n\t\t *\n\t\t * @return {string} The label.\n\t\t * @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-next-step-card\n\t\t */\n\t\tfallbackLabel() {\n\t\t\treturn t('nextcloud-vue', 'Next step')\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-next-step-card {\n\talign-items: center;\n\tbackground: var(--color-main-background);\n\tborder: 1px solid var(--color-border);\n\tborder-radius: var(--border-radius-large);\n\t/* The edge says \"this is the thing to act on\". An inset shadow, so it\n\t follows the card's rounded corners instead of squaring them off. */\n\tbox-shadow: inset 4px 0 0 var(--color-primary-element);\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: calc(4 * var(--default-grid-baseline)) calc(8 * var(--default-grid-baseline));\n\tpadding: calc(5 * var(--default-grid-baseline)) calc(6 * var(--default-grid-baseline));\n\tpadding-inline-start: calc(7 * var(--default-grid-baseline));\n}\n\n.cn-next-step-card__main {\n\tdisplay: flex;\n\tflex: 1 1 420px;\n\tflex-direction: column;\n\tgap: calc(2.5 * var(--default-grid-baseline));\n\tmin-width: 0;\n}\n\n.cn-next-step-card__title {\n\tcolor: var(--color-main-text);\n\tfont-size: 0.85em;\n\tfont-weight: 700;\n\tletter-spacing: 0.06em;\n\tmargin: 0;\n\ttext-transform: uppercase;\n}\n\n.cn-next-step-card__list {\n\tdisplay: grid;\n\tgap: calc(2 * var(--default-grid-baseline));\n\tlist-style: none;\n\tmargin: 0;\n\tpadding: 0;\n}\n\n.cn-next-step-card__item {\n\talign-items: center;\n\tcolor: var(--color-text-maxcontrast);\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: calc(2.5 * var(--default-grid-baseline));\n}\n\n.cn-next-step-card__item--current {\n\tcolor: var(--color-main-text);\n}\n\n.cn-next-step-card__item--current .cn-next-step-card__label {\n\tfont-weight: 700;\n}\n\n.cn-next-step-card__marker {\n\talign-items: center;\n\tborder: 2px solid var(--color-border-maxcontrast);\n\tborder-radius: 50%;\n\tbox-sizing: border-box;\n\tdisplay: inline-flex;\n\tflex: none;\n\theight: 20px;\n\tjustify-content: center;\n\twidth: 20px;\n}\n\n.cn-next-step-card__item--current .cn-next-step-card__marker {\n\tborder-color: var(--color-primary-element);\n}\n\n.cn-next-step-card__item--done .cn-next-step-card__marker {\n\tbackground: var(--color-primary-element);\n\tborder-color: var(--color-primary-element);\n\tcolor: var(--color-primary-element-text);\n}\n\n.cn-next-step-card__hint {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-weight: 400;\n}\n\n/* Read, not seen. */\n.cn-next-step-card__state {\n\tborder: 0;\n\tclip-path: inset(50%);\n\theight: 1px;\n\tmargin: -1px;\n\toverflow: hidden;\n\tpadding: 0;\n\tposition: absolute;\n\twhite-space: nowrap;\n\twidth: 1px;\n}\n\n.cn-next-step-card__side {\n\talign-items: flex-start;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: calc(2 * var(--default-grid-baseline));\n}\n\n.cn-next-step-card__after {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 0.9em;\n}\n</style>\n"],"names":["t"],"mappings":";;;;AAiEA,IAAI,kBAAkB,EAAA;;AAEtB;AACC;AACA;;AAEA;;;AAGA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;;;AAGA;AACA;;;;AAID,aAAe;AACd,CAAA,IAAI,EAAE,gBAAgB;;CAEtB,UAAU,EAAE;EACX,KAAK;AACL,EAAA,QAAQ;EACR;;AAED,CAAA,KAAK,EAAE;;AAEN,EAAA,KAAK,EAAE;GACN,IAAI,EAAE,MAAM;GACZ,OAAO,EAAE,EAAE;GACX;;AAED;AACA,EAAA,QAAQ,EAAE;GACT,IAAI,EAAE,MAAM;GACZ,OAAO,EAAE,IAAI;GACb;;AAED;;AAEC;;AAED,EAAA,KAAK,EAAE;GACN,IAAI,EAAE,KAAK;AACX,GAAA,OAAO,EAAE,MAAM,EAAE;GACjB;;;EAGD,WAAW,EAAE;GACZ,IAAI,EAAE,MAAM;GACZ,OAAO,EAAE,EAAE;GACX;;;AAGD,EAAA,QAAQ,EAAE;GACT,IAAI,EAAE,MAAM;GACZ,OAAO,EAAE,EAAE;GACX;;AAED;AACA,EAAA,cAAc,EAAE;GACf,IAAI,EAAE,OAAO;GACb,OAAO,EAAE,KAAK;GACd;;AAED;AACA,EAAA,KAAK,EAAE;GACN,IAAI,EAAE,MAAM;GACZ,OAAO,EAAE,EAAE;GACX;;AAED;EACA,SAAS,EAAE;GACV,IAAI,EAAE,MAAM;AACZ,GAAA,OAAO,EAAE,MAAMA,SAAC,CAAC,eAAe,EAAE,MAAM,CAAC;GACzC;;;EAGD,SAAS,EAAE;GACV,IAAI,EAAE,MAAM;AACZ,GAAA,OAAO,EAAE,MAAMA,SAAC,CAAC,eAAe,EAAE,OAAO,CAAC;GAC1C;EACD;;AAED,CAAA,KAAK,EAAE;AACN;AACA,EAAA,QAAQ;EACR;;AAED,CAAA,IAAI,GAAG;AACN,EAAA,eAAc,IAAK,EAAA;AACnB,EAAA,OAAO;GACN,OAAO,EAAE,CAAC,mBAAmB,EAAE,eAAe,CAAC,CAAC;AACjD,GAAA;EACA;;AAED,CAAA,QAAQ,EAAE;AACT;AACC;AACA;AACA;;;AAGD,EAAA,eAAe,GAAG;GACjB,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAA,GAAI,IAAI,CAAC,KAAM,GAAE,EAAE;AAClD,KAAC,MAAM,CAAC,CAAC,IAAI,KAAK,IAAG,IAAK,OAAO,IAAI,CAAC,KAAM,KAAI,QAAS,IAAG,IAAI,CAAC,KAAM,KAAI,EAAE,CAAA;AAC7E,KAAC,GAAG,CAAC,CAAC,IAAI,MAAM;AACf,KAAA,KAAK,EAAE,IAAI,CAAC,KAAK;AACjB,KAAA,IAAI,EAAE,IAAI,CAAC,SAAS,IAAI;AACxB,KAAA,IAAI,EAAE,OAAO,IAAI,CAAC,SAAS,WAAW,IAAI,CAAC,IAAK,GAAE,EAAE;AACrD,KAAC,CAAC,CAAA;GACH;;AAED;AACC;AACA;;;;AAID,EAAA,YAAY,GAAG;GACd,OAAO,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAA;GAC1D;;AAED;AACC;AACA;;;;AAID,EAAA,aAAa,GAAG;AACf,GAAA,OAAOA,SAAC,CAAC,eAAe,EAAE,WAAW,CAAA;GACrC;EACD;AACF;;;;"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { resolveComponent, openBlock, createElementBlock, createElementVNode, createBlock, resolveDynamicComponent, withCtx, createTextVNode, toDisplayString, createCommentVNode, Fragment, renderList, normalizeClass, renderSlot } from 'vue';
|
|
2
|
+
|
|
3
|
+
const _hoisted_1 = ["aria-labelledby", "aria-label"];
|
|
4
|
+
const _hoisted_2 = { class: "cn-next-step-card__main" };
|
|
5
|
+
const _hoisted_3 = { class: "cn-next-step-card__list" };
|
|
6
|
+
const _hoisted_4 = {
|
|
7
|
+
class: "cn-next-step-card__marker",
|
|
8
|
+
"aria-hidden": "true"
|
|
9
|
+
};
|
|
10
|
+
const _hoisted_5 = { class: "cn-next-step-card__label" };
|
|
11
|
+
const _hoisted_6 = {
|
|
12
|
+
key: 0,
|
|
13
|
+
class: "cn-next-step-card__hint"
|
|
14
|
+
};
|
|
15
|
+
const _hoisted_7 = { class: "cn-next-step-card__state" };
|
|
16
|
+
const _hoisted_8 = {
|
|
17
|
+
key: 0,
|
|
18
|
+
class: "cn-next-step-card__side"
|
|
19
|
+
};
|
|
20
|
+
const _hoisted_9 = {
|
|
21
|
+
key: 0,
|
|
22
|
+
class: "cn-next-step-card__after"
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
26
|
+
const _component_Check = resolveComponent("Check");
|
|
27
|
+
const _component_NcButton = resolveComponent("NcButton");
|
|
28
|
+
|
|
29
|
+
return ($options.normalisedItems.length > 0)
|
|
30
|
+
? (openBlock(), createElementBlock("section", {
|
|
31
|
+
key: 0,
|
|
32
|
+
class: "cn-next-step-card",
|
|
33
|
+
"data-testid": "cn-next-step-card",
|
|
34
|
+
"aria-labelledby": $props.title ? $data.titleId : null,
|
|
35
|
+
"aria-label": $props.title ? null : $options.fallbackLabel
|
|
36
|
+
}, [
|
|
37
|
+
createElementVNode("div", _hoisted_2, [
|
|
38
|
+
($props.title)
|
|
39
|
+
? (openBlock(), createBlock(resolveDynamicComponent($props.titleTag), {
|
|
40
|
+
key: 0,
|
|
41
|
+
id: $data.titleId,
|
|
42
|
+
class: "cn-next-step-card__title"
|
|
43
|
+
}, {
|
|
44
|
+
default: withCtx(() => [
|
|
45
|
+
createTextVNode(toDisplayString($props.title), 1 /* TEXT */)
|
|
46
|
+
]),
|
|
47
|
+
_: 1 /* STABLE */
|
|
48
|
+
}, 8 /* PROPS */, ["id"]))
|
|
49
|
+
: createCommentVNode("v-if", true),
|
|
50
|
+
createElementVNode("ul", _hoisted_3, [
|
|
51
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList($options.normalisedItems, (item, index) => {
|
|
52
|
+
return (openBlock(), createElementBlock("li", {
|
|
53
|
+
key: `${index}-${item.label}`,
|
|
54
|
+
class: normalizeClass(["cn-next-step-card__item", {
|
|
55
|
+
'cn-next-step-card__item--done': item.done,
|
|
56
|
+
'cn-next-step-card__item--current': index === $options.currentIndex,
|
|
57
|
+
}]),
|
|
58
|
+
"data-testid": "cn-next-step-item"
|
|
59
|
+
}, [
|
|
60
|
+
createElementVNode("span", _hoisted_4, [
|
|
61
|
+
(item.done)
|
|
62
|
+
? (openBlock(), createBlock(_component_Check, {
|
|
63
|
+
key: 0,
|
|
64
|
+
size: 14
|
|
65
|
+
}))
|
|
66
|
+
: createCommentVNode("v-if", true)
|
|
67
|
+
]),
|
|
68
|
+
createElementVNode("span", _hoisted_5, toDisplayString(item.label), 1 /* TEXT */),
|
|
69
|
+
(item.hint)
|
|
70
|
+
? (openBlock(), createElementBlock("span", _hoisted_6, toDisplayString(item.hint), 1 /* TEXT */))
|
|
71
|
+
: createCommentVNode("v-if", true),
|
|
72
|
+
createElementVNode("span", _hoisted_7, toDisplayString(item.done ? $props.doneLabel : $props.todoLabel), 1 /* TEXT */)
|
|
73
|
+
], 2 /* CLASS */))
|
|
74
|
+
}), 128 /* KEYED_FRAGMENT */))
|
|
75
|
+
])
|
|
76
|
+
]),
|
|
77
|
+
($props.actionLabel || _ctx.$slots.action || $props.after)
|
|
78
|
+
? (openBlock(), createElementBlock("div", _hoisted_8, [
|
|
79
|
+
renderSlot(_ctx.$slots, "action", {}, () => [
|
|
80
|
+
($props.actionLabel)
|
|
81
|
+
? (openBlock(), createBlock(_component_NcButton, {
|
|
82
|
+
key: 0,
|
|
83
|
+
id: $props.actionId || null,
|
|
84
|
+
variant: "primary",
|
|
85
|
+
disabled: $props.actionDisabled,
|
|
86
|
+
"data-testid": "cn-next-step-action",
|
|
87
|
+
onClick: _cache[0] || (_cache[0] = $event => (_ctx.$emit('action')))
|
|
88
|
+
}, {
|
|
89
|
+
default: withCtx(() => [
|
|
90
|
+
createTextVNode(toDisplayString($props.actionLabel), 1 /* TEXT */)
|
|
91
|
+
]),
|
|
92
|
+
_: 1 /* STABLE */
|
|
93
|
+
}, 8 /* PROPS */, ["id", "disabled"]))
|
|
94
|
+
: createCommentVNode("v-if", true)
|
|
95
|
+
]),
|
|
96
|
+
($props.after)
|
|
97
|
+
? (openBlock(), createElementBlock("span", _hoisted_9, toDisplayString($props.after), 1 /* TEXT */))
|
|
98
|
+
: createCommentVNode("v-if", true)
|
|
99
|
+
]))
|
|
100
|
+
: createCommentVNode("v-if", true)
|
|
101
|
+
], 8 /* PROPS */, _hoisted_1))
|
|
102
|
+
: createCommentVNode("v-if", true)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export { render };
|
|
106
|
+
//# sourceMappingURL=CnNextStepCard.vue3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CnNextStepCard.vue3.js","sources":["../../../../src/components/CnNextStepCard/CnNextStepCard.vue?vue&type=template&id=3a9ce962&lang.js"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n\n<template>\n\t<section\n\t\tv-if=\"normalisedItems.length > 0\"\n\t\tclass=\"cn-next-step-card\"\n\t\tdata-testid=\"cn-next-step-card\"\n\t\t:aria-labelledby=\"title ? titleId : null\"\n\t\t:aria-label=\"title ? null : fallbackLabel\">\n\t\t<div class=\"cn-next-step-card__main\">\n\t\t\t<component\n\t\t\t\t:is=\"titleTag\"\n\t\t\t\tv-if=\"title\"\n\t\t\t\t:id=\"titleId\"\n\t\t\t\tclass=\"cn-next-step-card__title\">\n\t\t\t\t{{ title }}\n\t\t\t</component>\n\t\t\t<ul class=\"cn-next-step-card__list\">\n\t\t\t\t<li\n\t\t\t\t\tv-for=\"(item, index) in normalisedItems\"\n\t\t\t\t\t:key=\"`${index}-${item.label}`\"\n\t\t\t\t\tclass=\"cn-next-step-card__item\"\n\t\t\t\t\t:class=\"{\n\t\t\t\t\t\t'cn-next-step-card__item--done': item.done,\n\t\t\t\t\t\t'cn-next-step-card__item--current': index === currentIndex,\n\t\t\t\t\t}\"\n\t\t\t\t\tdata-testid=\"cn-next-step-item\">\n\t\t\t\t\t<span class=\"cn-next-step-card__marker\" aria-hidden=\"true\">\n\t\t\t\t\t\t<Check v-if=\"item.done\" :size=\"14\" />\n\t\t\t\t\t</span>\n\t\t\t\t\t<span class=\"cn-next-step-card__label\">{{ item.label }}</span>\n\t\t\t\t\t<span v-if=\"item.hint\" class=\"cn-next-step-card__hint\">{{ item.hint }}</span>\n\t\t\t\t\t<!-- The state in words. The marker is a shape and a colour, and\n\t\t\t\t\t neither reaches a screen reader or a reader who cannot tell\n\t\t\t\t\t the two colours apart. -->\n\t\t\t\t\t<span class=\"cn-next-step-card__state\">{{ item.done ? doneLabel : todoLabel }}</span>\n\t\t\t\t</li>\n\t\t\t</ul>\n\t\t</div>\n\t\t<div v-if=\"actionLabel || $slots.action || after\" class=\"cn-next-step-card__side\">\n\t\t\t<!-- @slot action Replace the primary button, for a host that renders its own control. -->\n\t\t\t<slot name=\"action\">\n\t\t\t\t<NcButton\n\t\t\t\t\tv-if=\"actionLabel\"\n\t\t\t\t\t:id=\"actionId || null\"\n\t\t\t\t\tvariant=\"primary\"\n\t\t\t\t\t:disabled=\"actionDisabled\"\n\t\t\t\t\tdata-testid=\"cn-next-step-action\"\n\t\t\t\t\t@click=\"$emit('action')\">\n\t\t\t\t\t{{ actionLabel }}\n\t\t\t\t</NcButton>\n\t\t\t</slot>\n\t\t\t<span v-if=\"after\" class=\"cn-next-step-card__after\">{{ after }}</span>\n\t\t</div>\n\t</section>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcButton } from '@nextcloud/vue'\nimport Check from 'vue-material-design-icons/Check.vue'\n\nlet nextStepCardUid = 0\n\n/**\n * CnNextStepCard: what this record needs now, next to the button that does it.\n *\n * A short checklist for the current step and one primary action. It answers\n * \"what do I do next?\" on a record whose menu would otherwise make the handler\n * guess. Renders nothing when there is no checklist, so a step that needs no\n * explaining shows no empty card.\n *\n * ```vue\n * <CnNextStepCard\n * title=\"What now? Step 2: handling\"\n * :items=\"[\n * { label: 'Receipt confirmed', done: true },\n * { label: 'Review the open documents', hint: '2 of 5 done' },\n * { label: 'Draft the decision' },\n * ]\"\n * action-label=\"Continue reviewing\"\n * after=\"Then: step 3, decision\"\n * @action=\"onContinue\" />\n * ```\n *\n * CnDetailPage renders this card from its `nextStep` config, and the\n * `next-step` detail widget type renders it inside a grid.\n */\nexport default {\n\tname: 'CnNextStepCard',\n\n\tcomponents: {\n\t\tCheck,\n\t\tNcButton,\n\t},\n\n\tprops: {\n\t\t/** Heading of the card, for example \"What now? Step 2: handling\". */\n\t\ttitle: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Element the heading renders as. Pick the level that fits the page outline. */\n\t\ttitleTag: {\n\t\t\ttype: String,\n\t\t\tdefault: 'h3',\n\t\t},\n\n\t\t/**\n\t\t * The checklist: `{ label, done?, hint? }` per item. The first item\n\t\t * that is not done is emphasised as the one to pick up now.\n\t\t */\n\t\titems: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** Label of the primary button. Empty renders no button. */\n\t\tactionLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** DOM id for the primary button, so a skip link can land on it. */\n\t\tactionId: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Disable the primary button, for example while its request is in flight. */\n\t\tactionDisabled: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** One line under the button saying what follows, for example \"Then: step 3, decision\". */\n\t\tafter: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Text state of a done item, read by screen readers. */\n\t\tdoneLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Done'),\n\t\t},\n\n\t\t/** Text state of an open item, read by screen readers. */\n\t\ttodoLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'To do'),\n\t\t},\n\t},\n\n\temits: [\n\t\t/** The primary button was pressed. */\n\t\t'action',\n\t],\n\n\tdata() {\n\t\tnextStepCardUid += 1\n\t\treturn {\n\t\t\ttitleId: `cn-next-step-title-${nextStepCardUid}`,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The items that can render: an object with a label.\n\t\t *\n\t\t * @return {Array<{label: string, done: boolean, hint: string}>} The checklist.\n\t\t * @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-next-step-card\n\t\t */\n\t\tnormalisedItems() {\n\t\t\treturn (Array.isArray(this.items) ? this.items : [])\n\t\t\t\t.filter((item) => item && typeof item.label === 'string' && item.label !== '')\n\t\t\t\t.map((item) => ({\n\t\t\t\t\tlabel: item.label,\n\t\t\t\t\tdone: item.done === true,\n\t\t\t\t\thint: typeof item.hint === 'string' ? item.hint : '',\n\t\t\t\t}))\n\t\t},\n\n\t\t/**\n\t\t * Index of the first open item, the one to pick up now.\n\t\t *\n\t\t * @return {number} The index, or -1 when everything is done.\n\t\t * @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-next-step-card\n\t\t */\n\t\tcurrentIndex() {\n\t\t\treturn this.normalisedItems.findIndex((item) => !item.done)\n\t\t},\n\n\t\t/**\n\t\t * Accessible name for a card without a title.\n\t\t *\n\t\t * @return {string} The label.\n\t\t * @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-next-step-card\n\t\t */\n\t\tfallbackLabel() {\n\t\t\treturn t('nextcloud-vue', 'Next step')\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-next-step-card {\n\talign-items: center;\n\tbackground: var(--color-main-background);\n\tborder: 1px solid var(--color-border);\n\tborder-radius: var(--border-radius-large);\n\t/* The edge says \"this is the thing to act on\". An inset shadow, so it\n\t follows the card's rounded corners instead of squaring them off. */\n\tbox-shadow: inset 4px 0 0 var(--color-primary-element);\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: calc(4 * var(--default-grid-baseline)) calc(8 * var(--default-grid-baseline));\n\tpadding: calc(5 * var(--default-grid-baseline)) calc(6 * var(--default-grid-baseline));\n\tpadding-inline-start: calc(7 * var(--default-grid-baseline));\n}\n\n.cn-next-step-card__main {\n\tdisplay: flex;\n\tflex: 1 1 420px;\n\tflex-direction: column;\n\tgap: calc(2.5 * var(--default-grid-baseline));\n\tmin-width: 0;\n}\n\n.cn-next-step-card__title {\n\tcolor: var(--color-main-text);\n\tfont-size: 0.85em;\n\tfont-weight: 700;\n\tletter-spacing: 0.06em;\n\tmargin: 0;\n\ttext-transform: uppercase;\n}\n\n.cn-next-step-card__list {\n\tdisplay: grid;\n\tgap: calc(2 * var(--default-grid-baseline));\n\tlist-style: none;\n\tmargin: 0;\n\tpadding: 0;\n}\n\n.cn-next-step-card__item {\n\talign-items: center;\n\tcolor: var(--color-text-maxcontrast);\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: calc(2.5 * var(--default-grid-baseline));\n}\n\n.cn-next-step-card__item--current {\n\tcolor: var(--color-main-text);\n}\n\n.cn-next-step-card__item--current .cn-next-step-card__label {\n\tfont-weight: 700;\n}\n\n.cn-next-step-card__marker {\n\talign-items: center;\n\tborder: 2px solid var(--color-border-maxcontrast);\n\tborder-radius: 50%;\n\tbox-sizing: border-box;\n\tdisplay: inline-flex;\n\tflex: none;\n\theight: 20px;\n\tjustify-content: center;\n\twidth: 20px;\n}\n\n.cn-next-step-card__item--current .cn-next-step-card__marker {\n\tborder-color: var(--color-primary-element);\n}\n\n.cn-next-step-card__item--done .cn-next-step-card__marker {\n\tbackground: var(--color-primary-element);\n\tborder-color: var(--color-primary-element);\n\tcolor: var(--color-primary-element-text);\n}\n\n.cn-next-step-card__hint {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-weight: 400;\n}\n\n/* Read, not seen. */\n.cn-next-step-card__state {\n\tborder: 0;\n\tclip-path: inset(50%);\n\theight: 1px;\n\tmargin: -1px;\n\toverflow: hidden;\n\tpadding: 0;\n\tposition: absolute;\n\twhite-space: nowrap;\n\twidth: 1px;\n}\n\n.cn-next-step-card__side {\n\talign-items: flex-start;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: calc(2 * var(--default-grid-baseline));\n}\n\n.cn-next-step-card__after {\n\tcolor: var(--color-text-maxcontrast);\n\tfont-size: 0.9em;\n}\n</style>\n"],"names":["_createElementBlock","_createElementVNode","_openBlock","_createBlock","_resolveDynamicComponent","_Fragment","_renderList","_toDisplayString"],"mappings":";;;AAiBO,MAAA,UAAA,GAAA,EAAA,KAAK,EAAC,yBAAuB,GAAA;AAQ7B,MAAA,UAAA,GAAA,EAAA,KAAK,EAAC,yBAAA,GAAA;;AAUF,EAAA,KAAK,EAAC,2BAA2B;eAAY,EAAA,MAAO;;AAGpD,MAAA,UAAA,GAAA,EAAA,KAAK,EAAC,0BAA0B,GAAA;;;AACnC,EAAA,KAAA,EAAA,yBAAA;;AAIG,MAAA,UAAA,GAAA,EAAA,KAAK,EAAC,0BAA0B,GAAA;;;AAIjB,EAAA,KAAA,EAAA,yBAAA;;;;;;;;;;;AAnClB,EAAA,OAAA,CAAA,QAAA,CAAA,eAAe,CAAC,MAAM,GAAA,CAAA;oBAD5BA;;AAEC,QAAA,KAAI,EAAC,mBAAI;qBACC,EAAC,mBAAG;yBACF,EAAA,MAAA,CAAA,KAAA,GAAA,KAAA,CAAA,OAAA,GAAA,IAAA;oBACF,EAAE,MAAC,CAAA,KAAA,GAAA,IAAA,GAAA,QAAA,CAAA,aAAA;;AACZ,QAAAC,kBAAA,CA6BI,OA7BJ,UA6BI,EAAA;WA1BE,MAAK,CAAA,KAAA;AAFX,eAAAC,SAAA,EAAA,EAAAC,WAAA,CAMWC,wBALN,MAAK,CAAA,QAAA,CAAA,EAAA;;AAET,gBAAA,EAAC,EAAA,KAAA,CAAA,OAAA;AACD,gBAAA,KAAI,EAAC,0BAA0B;;iCAC/B,MAAU;kDAAR,MAAK,CAAA,KAAA,CAAA,EAAA,CAAA,YAAA;;;;;AAEP,UAAAH,kBAAA,CAoBG,MApBH,UAoBG,EAAA;AAnBF,aAAAC,SAAA,CAAA,IAAA,CAAA,EAAAF,kBAAA,CAkBGK,QAjBoB,EAAA,IAAA,EAAAC,UAAA,CAAA,QAAA,CAAA,eAAe,EAA/B,CAAA,IAAI,EAAE,KAAK,KAAA;mCADlBN,kBAkBG,CAAA,IAAA,EAAA;AAhBH,gBAAA,GAAA,EAAA,CAAA,EAAA,KAAA,CAAA,CAAA,EAAA,IAAA,CAAA,KAAA,CAAA,CAAA;AACD,gBAAA,KAAK,kBAAC,yBAAyB,EAAA;AACkB,MAAA,+BAAA,EAAA,IAAI,CAAC,IAAI;AAAA,MAAA,kCAAA,EAAA,KAAA,KAAA,QAAA,CAAA,YAAA;;AAI1D,gBAAA,aAAW,EAAC,mBAAmB;;AAC/B,gBAAAC,kBAAA,CAEO,QAFP,UAEO,EAAA;AADO,kBAAA,CAAA,IAAI,CAAC,IAAI;+CAAe,CAAA,gBAAA,EAAA;;AAAZ,wBAAA,IAAI,EAAE,EAAE;;;;AAElC,gBAAAA,kBAAA,CAA8D,MAA9D,EAAA,UAA8D,EAApBM,eAAA,CAAA,IAAI,CAAC,KAAK,CAAA,EAAA,CAAA,YAAA;AACjD,gBAAA,CAAA,IAAA,CAAA,IAAA;AAAH,qBAAAL,SAAA,EAAA,EAAAF,kBAAA,CAAG,MAAH,EAAA,UAAG,EAAAO,eAAA,CAAA,IAAA,CAAA,IAAA,CAAA,EAAA,CAAA,YAAA;;gBAIHN,kBAAqF,CAAA,MAAA,EAArF,UAAqF,EAA3CM,eAAA,CAAA,IAAI,CAAE,IAAG,GAAI,MAAQ,CAAA,SAAA,GAAG,MAAU,CAAA,SAAA,CAAA,EAAA,CAAA,YAAA;;;;;AAIpE,QAAA,CAAA,MAAA,CAAA,WAAW,IAAE,IAAA,CAAA,MAAA,CAAA,MAAA,IAAA,MAAA,CAAA,KAAA;AAArB,aAAAL,SAAA,EAAA,EAAAF,kBAAA,QAAA;;iBAIM,MAAW,CAAA,WAAA;kCADjBG;;AAEC,sBAAA,EAAE,EAAE,MAAQ,CAAA,QAAA,IAAA,IAAA;AACb,sBAAA,OAAO,EAAC,SAAC;AACR,sBAAA,QAAG,EAAA,MAAA,CAAA,cAAA;AACJ,sBAAA,aAAW,EAAC,qBAAqB;AAChC,sBAAA,OAAC,uCAAA,IAAA,CAAA,KAAA,CAAA,QAAA,CAAA,CAAA,CAAA;;uCACF,MAAK;wDAAF,MAAE,CAAA,WAAA,CAAA,EAAA,CAAA,YAAA;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import script from './CnNextStepWidget.vue2.js';
|
|
2
|
+
import { render } from './CnNextStepWidget.vue3.js';
|
|
3
|
+
|
|
4
|
+
script.render = render;
|
|
5
|
+
script.__file = "src/components/CnNextStepCard/CnNextStepWidget.vue";
|
|
6
|
+
const __sfc_main = script;
|
|
7
|
+
|
|
8
|
+
export { __sfc_main as default };
|
|
9
|
+
//# sourceMappingURL=CnNextStepWidget.vue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CnNextStepWidget.vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import __sfc_main from './CnNextStepCard.vue.js';
|
|
2
|
+
import { resolveNextStep } from '../../utils/detailActionModel.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* CnNextStepWidget: the `next-step` detail widget type.
|
|
6
|
+
*
|
|
7
|
+
* Renders CnNextStepCard for the bound record's stage from
|
|
8
|
+
* `content: { field?, stages: { <stage>: { title?, checklist, after? } } }`.
|
|
9
|
+
* The checklist only: the page's own primary button stays where the page
|
|
10
|
+
* puts it. Resolved by its registry key, not exported.
|
|
11
|
+
*/
|
|
12
|
+
var script = {
|
|
13
|
+
name: 'CnNextStepWidget',
|
|
14
|
+
|
|
15
|
+
components: {
|
|
16
|
+
CnNextStepCard: __sfc_main,
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
props: {
|
|
20
|
+
/** The widget's content: `{ field?, title?, stages }`. */
|
|
21
|
+
content: {
|
|
22
|
+
type: Object,
|
|
23
|
+
default: () => ({}),
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
/** The bound record. */
|
|
27
|
+
objectData: {
|
|
28
|
+
type: Object,
|
|
29
|
+
default: null,
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
computed: {
|
|
34
|
+
/**
|
|
35
|
+
* The card for the record's stage.
|
|
36
|
+
*
|
|
37
|
+
* @return {object|null} The resolved card, or null when the stage declares none.
|
|
38
|
+
* @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-next-step-card
|
|
39
|
+
*/
|
|
40
|
+
step() {
|
|
41
|
+
return resolveNextStep(this.content, this.objectData)
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export { script as default };
|
|
47
|
+
//# sourceMappingURL=CnNextStepWidget.vue2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CnNextStepWidget.vue2.js","sources":["../../../../src/components/CnNextStepCard/CnNextStepWidget.vue"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n\n<template>\n\t<CnNextStepCard\n\t\tv-if=\"step\"\n\t\t:title=\"step.title\"\n\t\t:items=\"step.items\"\n\t\t:after=\"step.after\" />\n</template>\n\n<script>\nimport CnNextStepCard from './CnNextStepCard.vue'\nimport { resolveNextStep } from '../../utils/detailActionModel.js'\n\n/**\n * CnNextStepWidget: the `next-step` detail widget type.\n *\n * Renders CnNextStepCard for the bound record's stage from\n * `content: { field?, stages: { <stage>: { title?, checklist, after? } } }`.\n * The checklist only: the page's own primary button stays where the page\n * puts it. Resolved by its registry key, not exported.\n */\nexport default {\n\tname: 'CnNextStepWidget',\n\n\tcomponents: {\n\t\tCnNextStepCard,\n\t},\n\n\tprops: {\n\t\t/** The widget's content: `{ field?, title?, stages }`. */\n\t\tcontent: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/** The bound record. */\n\t\tobjectData: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The card for the record's stage.\n\t\t *\n\t\t * @return {object|null} The resolved card, or null when the stage declares none.\n\t\t * @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-next-step-card\n\t\t */\n\t\tstep() {\n\t\t\treturn resolveNextStep(this.content, this.objectData)\n\t\t},\n\t},\n}\n</script>\n"],"names":["CnNextStepCard"],"mappings":";;;AAiBA;;AAEC;;AAEA;;AAEA;;AAED,aAAe;CACd,IAAI,EAAE,kBAAkB;;CAExB,UAAU,EAAE;AACX,kBAAAA,UAAc;EACd;;AAED,CAAA,KAAK,EAAE;;AAEN,EAAA,OAAO,EAAE;GACR,IAAI,EAAE,MAAM;AACZ,GAAA,OAAO,EAAE,OAAO,EAAE,CAAC;GACnB;;AAED;EACA,UAAU,EAAE;GACX,IAAI,EAAE,MAAM;GACZ,OAAO,EAAE,IAAI;GACb;EACD;;AAED,CAAA,QAAQ,EAAE;AACT;;AAEC;AACA;;;AAGD,EAAA,IAAI,GAAG;GACN,OAAO,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAA;GACpD;EACD;AACF;;;;"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { resolveComponent, openBlock, createBlock, createCommentVNode } from 'vue';
|
|
2
|
+
|
|
3
|
+
function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
4
|
+
const _component_CnNextStepCard = resolveComponent("CnNextStepCard");
|
|
5
|
+
|
|
6
|
+
return ($options.step)
|
|
7
|
+
? (openBlock(), createBlock(_component_CnNextStepCard, {
|
|
8
|
+
key: 0,
|
|
9
|
+
title: $options.step.title,
|
|
10
|
+
items: $options.step.items,
|
|
11
|
+
after: $options.step.after
|
|
12
|
+
}, null, 8 /* PROPS */, ["title", "items", "after"]))
|
|
13
|
+
: createCommentVNode("v-if", true)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export { render };
|
|
17
|
+
//# sourceMappingURL=CnNextStepWidget.vue3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CnNextStepWidget.vue3.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;"}
|
|
@@ -87,6 +87,13 @@ var script = {
|
|
|
87
87
|
* identity when used standalone (no CnAppRoot ancestor).
|
|
88
88
|
*/
|
|
89
89
|
cnTranslate: { default: () => (key) => key },
|
|
90
|
+
/**
|
|
91
|
+
* Formatter registry, provided by CnAppRoot (`cnFormatters`: the
|
|
92
|
+
* library's built-ins plus the app's `formatters`). A field override
|
|
93
|
+
* `{ formatter: '<id>' }` renders the value through the same function a
|
|
94
|
+
* table column with that `formatter` uses. Empty when used standalone.
|
|
95
|
+
*/
|
|
96
|
+
cnFormatters: { default: () => ({}) },
|
|
90
97
|
/**
|
|
91
98
|
* The host surface's panel-action channel, when this widget is rendered
|
|
92
99
|
* in a tab panel. Null everywhere else, which is every other surface.
|
|
@@ -272,6 +279,11 @@ var script = {
|
|
|
272
279
|
* - `editable` (boolean) — Override editability (default: based on schema readOnly)
|
|
273
280
|
* - `label` (string) — Override the display label
|
|
274
281
|
* - `widget` (string) — Override the widget type for editing
|
|
282
|
+
* - `formatter` (string) — Display the value through the formatter
|
|
283
|
+
* registered under this id on CnAppRoot (`cnFormatters`), called as
|
|
284
|
+
* `(value, object, property)` like a table cell's formatter. An id
|
|
285
|
+
* nobody registered, or a formatter that throws, keeps the default
|
|
286
|
+
* rendering. Editing still writes the stored value.
|
|
275
287
|
*
|
|
276
288
|
* Accepts an Array too: an empty overrides map (`{}`) round-trips through
|
|
277
289
|
* PHP/JSON as an empty Array (`[]`), so a persisted manifest can deliver
|
|
@@ -548,12 +560,46 @@ var script = {
|
|
|
548
560
|
}
|
|
549
561
|
},
|
|
550
562
|
|
|
563
|
+
/**
|
|
564
|
+
* Display values of the fields whose override names a registered
|
|
565
|
+
* formatter, keyed by field key. A field is left out when its formatter
|
|
566
|
+
* id is not registered or the formatter throws, so it falls back to the
|
|
567
|
+
* default rendering.
|
|
568
|
+
*
|
|
569
|
+
* @return {Record<string, string>}
|
|
570
|
+
*/
|
|
571
|
+
formatterDisplayValues() {
|
|
572
|
+
const values = {};
|
|
573
|
+
for (const field of this.resolvedFields) {
|
|
574
|
+
const fn = field.formatter && this.cnFormatters && this.cnFormatters[field.formatter];
|
|
575
|
+
if (typeof fn !== 'function') {
|
|
576
|
+
continue
|
|
577
|
+
}
|
|
578
|
+
const raw = field.key in this.dirtyFields
|
|
579
|
+
? this.dirtyFields[field.key]
|
|
580
|
+
: (this.objectData || {})[field.key];
|
|
581
|
+
const prop = (this.schema.properties && this.schema.properties[field.key]) || {};
|
|
582
|
+
try {
|
|
583
|
+
const formatted = fn(raw, this.objectData || {}, prop);
|
|
584
|
+
values[field.key] = (formatted === null || formatted === undefined || formatted === '') ? '—' : String(formatted);
|
|
585
|
+
} catch (e) {
|
|
586
|
+
// eslint-disable-next-line no-console
|
|
587
|
+
console.warn(`[CnObjectDataWidget] formatter "${field.formatter}" threw; falling back`, e);
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
return values
|
|
591
|
+
},
|
|
592
|
+
|
|
551
593
|
/**
|
|
552
594
|
* Formatted display values for each field.
|
|
553
595
|
*/
|
|
554
596
|
displayValues() {
|
|
555
597
|
const values = {};
|
|
556
598
|
for (const field of this.resolvedFields) {
|
|
599
|
+
if (field.key in this.formatterDisplayValues) {
|
|
600
|
+
values[field.key] = this.formatterDisplayValues[field.key];
|
|
601
|
+
continue
|
|
602
|
+
}
|
|
557
603
|
// Show pending edit value if dirty
|
|
558
604
|
const raw = field.key in this.dirtyFields
|
|
559
605
|
? this.dirtyFields[field.key]
|
|
@@ -822,6 +868,9 @@ var script = {
|
|
|
822
868
|
* @return {'object-array'|'scalar-array'|'object'|'scalar'} The value kind.
|
|
823
869
|
*/
|
|
824
870
|
fieldValueKind(field) {
|
|
871
|
+
if (field.key in this.formatterDisplayValues) {
|
|
872
|
+
return 'scalar'
|
|
873
|
+
}
|
|
825
874
|
const prop = ((this.schema && this.schema.properties) || {})[field.key];
|
|
826
875
|
if (this.isRelationField(prop)) {
|
|
827
876
|
return 'scalar'
|