@conduction/nextcloud-vue 2.79.0 → 2.81.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/CnActionButtons/CnActionButtons.vue2.js.map +1 -1
- package/dist/esm/components/CnActionButtons/CnActionButtons.vue3.js +3 -1
- package/dist/esm/components/CnActionButtons/CnActionButtons.vue3.js.map +1 -1
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js +32 -3
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue2.js.map +1 -1
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js +13 -11
- package/dist/esm/components/CnActionsBar/CnActionsBar.vue3.js.map +1 -1
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js +80 -4
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js.map +1 -1
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js +95 -91
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js.map +1 -1
- package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue2.js +179 -13
- package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue3.js +52 -16
- package/dist/esm/components/CnBannerWidget/CnBannerWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js +96 -4
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js.map +1 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js +158 -110
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js.map +1 -1
- package/dist/esm/components/CnChipsFieldWidget/CnChipsFieldWidget.vue.js +10 -0
- package/dist/esm/components/CnChipsFieldWidget/CnChipsFieldWidget.vue.js.map +1 -0
- package/dist/esm/components/CnChipsFieldWidget/CnChipsFieldWidget.vue2.js +252 -0
- package/dist/esm/components/CnChipsFieldWidget/CnChipsFieldWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnChipsFieldWidget/CnChipsFieldWidget.vue3.js +140 -0
- package/dist/esm/components/CnChipsFieldWidget/CnChipsFieldWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnChipsFieldWidget/index.js +26 -0
- package/dist/esm/components/CnChipsFieldWidget/index.js.map +1 -0
- package/dist/esm/components/CnChoicePickerWidget/CnChoicePickerWidget.vue.js +10 -0
- package/dist/esm/components/CnChoicePickerWidget/CnChoicePickerWidget.vue.js.map +1 -0
- package/dist/esm/components/CnChoicePickerWidget/CnChoicePickerWidget.vue2.js +354 -0
- package/dist/esm/components/CnChoicePickerWidget/CnChoicePickerWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnChoicePickerWidget/CnChoicePickerWidget.vue3.js +172 -0
- package/dist/esm/components/CnChoicePickerWidget/CnChoicePickerWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnChoicePickerWidget/index.js +27 -0
- package/dist/esm/components/CnChoicePickerWidget/index.js.map +1 -0
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue2.js +1 -1
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnConversationThread/CnConversationWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnDashboardGrid/CnDashboardGrid.vue2.js +2 -2
- package/dist/esm/components/CnDashboardGrid/CnDashboardGrid.vue2.js.map +1 -1
- package/dist/esm/components/CnDashboardGrid/CnDashboardGrid.vue3.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +65 -5
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +2 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +19 -11
- package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +4 -2
- package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +134 -4
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js +21 -4
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js +24 -0
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js +43 -4
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js.map +1 -1
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue2.js +1 -1
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnDocumentReviewList/CnDocumentReviewWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnFacetSidebar/CnFacetSidebar.vue2.js +7 -7
- package/dist/esm/components/CnFacetSidebar/CnFacetSidebar.vue2.js.map +1 -1
- package/dist/esm/components/CnFacetSidebar/CnFacetSidebar.vue3.js.map +1 -1
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue.js +11 -0
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue.js.map +1 -0
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js +867 -0
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue3.js +238 -0
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnFactsWidget/index.js +30 -0
- package/dist/esm/components/CnFactsWidget/index.js.map +1 -0
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue.js +10 -0
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue.js.map +1 -0
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue2.js +626 -0
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue3.js +396 -0
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnFieldListWidget/index.js +29 -0
- package/dist/esm/components/CnFieldListWidget/index.js.map +1 -0
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js +302 -4
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js +417 -244
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/filesBrowser.js +101 -1
- package/dist/esm/components/CnFilesBrowser/filesBrowser.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/filesBrowserColumns.js +141 -1
- package/dist/esm/components/CnFilesBrowser/filesBrowserColumns.js.map +1 -1
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js +65 -17
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js.map +1 -1
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js +4 -4
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js.map +1 -1
- package/dist/esm/components/CnFormPage/CnFormPage.vue2.js +78 -3
- package/dist/esm/components/CnFormPage/CnFormPage.vue2.js.map +1 -1
- package/dist/esm/components/CnFormPage/CnFormPage.vue3.js +74 -49
- package/dist/esm/components/CnFormPage/CnFormPage.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +333 -73
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +79 -17
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue.js +10 -0
- package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue.js.map +1 -0
- package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue2.js +99 -0
- package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue2.js.map +1 -0
- package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue3.js +48 -0
- package/dist/esm/components/CnIndexPage/CnIndexPageWidgets.vue3.js.map +1 -0
- package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue2.js +7 -7
- package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue3.js.map +1 -1
- package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue2.js +1 -1
- package/dist/esm/components/CnNextStepCard/CnNextStepWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js +65 -2
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js +6 -2
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js +63 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js +8 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnNotesTab.vue2.js +14 -0
- package/dist/esm/components/CnObjectSidebar/CnNotesTab.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnNotesTab.vue3.js +5 -1
- package/dist/esm/components/CnObjectSidebar/CnNotesTab.vue3.js.map +1 -1
- package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue2.js +29 -1
- package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue2.js.map +1 -1
- package/dist/esm/components/CnPageRenderer/CnPageRenderer.vue3.js.map +1 -1
- package/dist/esm/components/CnRadioCardsWidget/CnRadioCardsWidget.vue.js +10 -0
- package/dist/esm/components/CnRadioCardsWidget/CnRadioCardsWidget.vue.js.map +1 -0
- package/dist/esm/components/CnRadioCardsWidget/CnRadioCardsWidget.vue2.js +174 -0
- package/dist/esm/components/CnRadioCardsWidget/CnRadioCardsWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnRadioCardsWidget/CnRadioCardsWidget.vue3.js +75 -0
- package/dist/esm/components/CnRadioCardsWidget/CnRadioCardsWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnRadioCardsWidget/index.js +28 -0
- package/dist/esm/components/CnRadioCardsWidget/index.js.map +1 -0
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js +10 -0
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js.map +1 -0
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js +411 -0
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js +178 -0
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnRecordListWidget/index.js +31 -0
- package/dist/esm/components/CnRecordListWidget/index.js.map +1 -0
- package/dist/esm/components/CnSavedViewsWidget/CnSavedViewsWidget.vue.js +10 -0
- package/dist/esm/components/CnSavedViewsWidget/CnSavedViewsWidget.vue.js.map +1 -0
- package/dist/esm/components/CnSavedViewsWidget/CnSavedViewsWidget.vue2.js +222 -0
- package/dist/esm/components/CnSavedViewsWidget/CnSavedViewsWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnSavedViewsWidget/CnSavedViewsWidget.vue3.js +64 -0
- package/dist/esm/components/CnSavedViewsWidget/CnSavedViewsWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnSavedViewsWidget/index.js +30 -0
- package/dist/esm/components/CnSavedViewsWidget/index.js.map +1 -0
- package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue.js +10 -0
- package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue.js.map +1 -0
- package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue2.js +351 -0
- package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue3.js +71 -0
- package/dist/esm/components/CnSectionsWidget/CnSectionsWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnSectionsWidget/index.js +35 -0
- package/dist/esm/components/CnSectionsWidget/index.js.map +1 -0
- package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue2.js.map +1 -1
- package/dist/esm/components/CnSegmentedControl/CnSegmentedControl.vue3.js.map +1 -1
- package/dist/esm/components/CnSettingsFormWidget/CnSettingsFormWidget.vue.js +10 -0
- package/dist/esm/components/CnSettingsFormWidget/CnSettingsFormWidget.vue.js.map +1 -0
- package/dist/esm/components/CnSettingsFormWidget/CnSettingsFormWidget.vue2.js +347 -0
- package/dist/esm/components/CnSettingsFormWidget/CnSettingsFormWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnSettingsFormWidget/CnSettingsFormWidget.vue3.js +184 -0
- package/dist/esm/components/CnSettingsFormWidget/CnSettingsFormWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnSettingsFormWidget/index.js +27 -0
- package/dist/esm/components/CnSettingsFormWidget/index.js.map +1 -0
- package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue2.js +81 -2
- package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue2.js +87 -6
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js +1 -0
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnStatsBlockWidget/CnStatsBlockWidget.vue2.js +84 -1
- package/dist/esm/components/CnStatsBlockWidget/CnStatsBlockWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnStatsBlockWidget/CnStatsBlockWidget.vue3.js +85 -41
- package/dist/esm/components/CnStatsBlockWidget/CnStatsBlockWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnSwitchRowsWidget/CnSwitchRowsWidget.vue.js +10 -0
- package/dist/esm/components/CnSwitchRowsWidget/CnSwitchRowsWidget.vue.js.map +1 -0
- package/dist/esm/components/CnSwitchRowsWidget/CnSwitchRowsWidget.vue2.js +159 -0
- package/dist/esm/components/CnSwitchRowsWidget/CnSwitchRowsWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnSwitchRowsWidget/CnSwitchRowsWidget.vue3.js +60 -0
- package/dist/esm/components/CnSwitchRowsWidget/CnSwitchRowsWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnSwitchRowsWidget/index.js +26 -0
- package/dist/esm/components/CnSwitchRowsWidget/index.js.map +1 -0
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +168 -7
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js +86 -23
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue2.js +80 -1
- package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue3.js +75 -32
- package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnToggleTableWidget/CnToggleTableWidget.vue.js +10 -0
- package/dist/esm/components/CnToggleTableWidget/CnToggleTableWidget.vue.js.map +1 -0
- package/dist/esm/components/CnToggleTableWidget/CnToggleTableWidget.vue2.js +269 -0
- package/dist/esm/components/CnToggleTableWidget/CnToggleTableWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnToggleTableWidget/CnToggleTableWidget.vue3.js +106 -0
- package/dist/esm/components/CnToggleTableWidget/CnToggleTableWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnToggleTableWidget/index.js +27 -0
- package/dist/esm/components/CnToggleTableWidget/index.js.map +1 -0
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +11 -0
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
- package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue2.js +7 -2
- package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue2.js.map +1 -1
- package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue3.js.map +1 -1
- package/dist/esm/components/CnWidgetObjectTable/dashboardRegistration.js +5 -0
- package/dist/esm/components/CnWidgetObjectTable/dashboardRegistration.js.map +1 -1
- package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue2.js +301 -6
- package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue3.js +153 -55
- package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue3.js.map +1 -1
- package/dist/esm/composables/useFormDraft.js +140 -9
- package/dist/esm/composables/useFormDraft.js.map +1 -1
- package/dist/esm/composables/useListView.js +4 -4
- package/dist/esm/composables/useListView.js.map +1 -1
- package/dist/esm/index.js +21 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue2.js +28 -20
- package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue3.js +9 -0
- package/dist/esm/integrations/builtin/field-inspection/CnFieldInspectionCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/field-inspection.js +21 -0
- package/dist/esm/integrations/builtin/field-inspection.js.map +1 -1
- package/dist/esm/integrations/offline/checklistSubmission.js +141 -0
- package/dist/esm/integrations/offline/checklistSubmission.js.map +1 -0
- package/dist/esm/integrations/offline/fieldCollectionHelpers.js +70 -5
- package/dist/esm/integrations/offline/fieldCollectionHelpers.js.map +1 -1
- package/dist/esm/integrations/offline/index.js +2 -1
- package/dist/esm/integrations/offline/index.js.map +1 -1
- package/dist/esm/integrations/offline/offlineDb.js +6 -1
- package/dist/esm/integrations/offline/offlineDb.js.map +1 -1
- package/dist/esm/integrations/offline/syncReplayService.js +8 -2
- package/dist/esm/integrations/offline/syncReplayService.js.map +1 -1
- package/dist/esm/l10n/en.json.js +20 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +70 -2
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/nextcloud-vue.css +2192 -222
- package/dist/esm/utils/contentHeaderLink.js +51 -0
- package/dist/esm/utils/contentHeaderLink.js.map +1 -0
- package/dist/esm/utils/detailActionModel.js +60 -3
- package/dist/esm/utils/detailActionModel.js.map +1 -1
- package/dist/esm/utils/facets.js +75 -3
- package/dist/esm/utils/facets.js.map +1 -1
- package/dist/esm/utils/fetchFilterCounts.js +40 -5
- package/dist/esm/utils/fetchFilterCounts.js.map +1 -1
- package/dist/esm/utils/fillTemplate.js +120 -0
- package/dist/esm/utils/fillTemplate.js.map +1 -0
- package/dist/esm/utils/initials.js +32 -0
- package/dist/esm/utils/initials.js.map +1 -0
- package/dist/esm/utils/libraryWidgetKeys.js +11 -0
- package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
- package/dist/esm/utils/objectWrite.js +59 -0
- package/dist/esm/utils/objectWrite.js.map +1 -0
- package/dist/esm/utils/pageControls.js +81 -0
- package/dist/esm/utils/pageControls.js.map +1 -0
- package/dist/esm/utils/personalLenses.js +40 -3
- package/dist/esm/utils/personalLenses.js.map +1 -1
- package/dist/esm/utils/queryPresets.js +96 -0
- package/dist/esm/utils/queryPresets.js.map +1 -0
- package/dist/esm/utils/resolveFilterTokens.js +12 -1
- package/dist/esm/utils/resolveFilterTokens.js.map +1 -1
- package/dist/esm/utils/resolveManifestTokens.js +2 -0
- package/dist/esm/utils/resolveManifestTokens.js.map +1 -1
- package/dist/esm/utils/schema.js +21 -0
- package/dist/esm/utils/schema.js.map +1 -1
- package/dist/esm/utils/sentinelTokens.js +22 -4
- package/dist/esm/utils/sentinelTokens.js.map +1 -1
- package/dist/esm/utils/userGroupsPeek.js +91 -0
- package/dist/esm/utils/userGroupsPeek.js.map +1 -0
- package/dist/esm/utils/validateManifestV2.compiled.js +3 -3
- package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
- package/dist/esm/utils/visibleWhen.js +57 -5
- package/dist/esm/utils/visibleWhen.js.map +1 -1
- package/dist/esm/utils/widgetDispatch.js +7 -1
- package/dist/esm/utils/widgetDispatch.js.map +1 -1
- package/dist/esm/utils/widgetVisibility.js +4 -57
- package/dist/esm/utils/widgetVisibility.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +19708 -9301
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +2192 -222
- package/l10n/en.json +20 -1
- package/l10n/nl.json +70 -2
- package/package.json +2 -1
- package/scripts/check-docs-mdx.mjs +108 -0
- package/src/components/CnActionButtons/CnActionButtons.vue +2 -0
- package/src/components/CnActionsBar/CnActionsBar.md +4 -0
- package/src/components/CnActionsBar/CnActionsBar.vue +48 -11
- package/src/components/CnAppRoot/CnAppRoot.md +4 -2
- package/src/components/CnAppRoot/CnAppRoot.vue +151 -59
- package/src/components/CnBannerWidget/CnBannerWidget.vue +244 -23
- package/src/components/CnCellRenderer/CnCellRenderer.md +2 -0
- package/src/components/CnCellRenderer/CnCellRenderer.vue +235 -5
- package/src/components/CnChipsFieldWidget/CnChipsFieldWidget.vue +433 -0
- package/src/components/CnChipsFieldWidget/index.js +25 -0
- package/src/components/CnChoicePickerWidget/CnChoicePickerWidget.vue +556 -0
- package/src/components/CnChoicePickerWidget/index.js +26 -0
- package/src/components/CnConversationThread/CnConversationWidget.vue +1 -1
- package/src/components/CnDashboardGrid/CnDashboardGrid.vue +2 -2
- package/src/components/CnDashboardPage/CnDashboardPage.vue +78 -5
- package/src/components/CnDataTable/CnDataTable.vue +22 -12
- package/src/components/CnDetailPage/CnDetailPage.md +1 -1
- package/src/components/CnDetailPage/CnDetailPage.vue +152 -6
- package/src/components/CnDetailWidgetHost/CnDetailWidgetHost.vue +66 -0
- package/src/components/CnDocumentReviewList/CnDocumentReviewWidget.vue +1 -1
- package/src/components/CnFacetSidebar/CnFacetSidebar.vue +7 -7
- package/src/components/CnFactsWidget/CnFactsWidget.vue +1190 -0
- package/src/components/CnFactsWidget/index.js +29 -0
- package/src/components/CnFieldListWidget/CnFieldListWidget.vue +1008 -0
- package/src/components/CnFieldListWidget/index.js +28 -0
- package/src/components/CnFilesBrowser/CnFilesBrowser.vue +588 -117
- package/src/components/CnFilesBrowser/filesBrowser.js +100 -0
- package/src/components/CnFilesBrowser/filesBrowserColumns.js +140 -0
- package/src/components/CnFormDialog/CnFormDialog.md +9 -3
- package/src/components/CnFormDialog/CnFormDialog.vue +69 -21
- package/src/components/CnFormPage/CnFormPage.vue +99 -3
- package/src/components/CnIndexPage/CnIndexPage.vue +309 -9
- package/src/components/CnIndexPage/CnIndexPageWidgets.vue +169 -0
- package/src/components/CnIndexSidebar/CnIndexSidebar.vue +7 -7
- package/src/components/CnNextStepCard/CnNextStepWidget.vue +1 -1
- package/src/components/CnObjectListWidget/CnObjectListWidget.vue +69 -2
- package/src/components/CnObjectSidebar/CnFilesTab.vue +70 -1
- package/src/components/CnObjectSidebar/CnNotesTab.vue +16 -0
- package/src/components/CnPageRenderer/CnPageRenderer.vue +29 -1
- package/src/components/CnRadioCardsWidget/CnRadioCardsWidget.vue +313 -0
- package/src/components/CnRadioCardsWidget/index.js +27 -0
- package/src/components/CnRecordListWidget/CnRecordListWidget.vue +652 -0
- package/src/components/CnRecordListWidget/index.js +30 -0
- package/src/components/CnSavedViewsWidget/CnSavedViewsWidget.vue +296 -0
- package/src/components/CnSavedViewsWidget/index.js +29 -0
- package/src/components/CnSectionsWidget/CnSectionsWidget.vue +489 -0
- package/src/components/CnSectionsWidget/index.js +34 -0
- package/src/components/CnSegmentedControl/CnSegmentedControl.vue +13 -0
- package/src/components/CnSettingsFormWidget/CnSettingsFormWidget.vue +555 -0
- package/src/components/CnSettingsFormWidget/index.js +26 -0
- package/src/components/CnStagesWidget/CnStagesWidget.vue +81 -2
- package/src/components/CnStatWidget/CnStatWidget.vue +88 -7
- package/src/components/CnStatsBlockWidget/CnStatsBlockWidget.vue +180 -3
- package/src/components/CnSwitchRowsWidget/CnSwitchRowsWidget.vue +226 -0
- package/src/components/CnSwitchRowsWidget/index.js +25 -0
- package/src/components/CnTabsWidget/CnTabsWidget.vue +263 -8
- package/src/components/CnTasksWidget/CnTasksWidget.vue +175 -15
- package/src/components/CnToggleTableWidget/CnToggleTableWidget.vue +386 -0
- package/src/components/CnToggleTableWidget/index.js +26 -0
- package/src/components/CnWidgetGrid/registerDashboardWidgets.js +11 -0
- package/src/components/CnWidgetObjectTable/CnWidgetObjectTable.vue +7 -2
- package/src/components/CnWidgetObjectTable/dashboardRegistration.js +5 -0
- package/src/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue +493 -11
- package/src/components/index.js +19 -0
- package/src/composables/__tests__/useFormDraft.spec.js +69 -0
- package/src/composables/useFormDraft.js +139 -8
- package/src/composables/useListView.js +4 -4
- package/src/css/form-field.css +14 -0
- package/src/css/index-page.css +71 -0
- package/src/css/kpi-card.css +32 -0
- package/src/css/look-board-detail.css +113 -2
- package/src/css/look-board-index.css +90 -8
- package/src/css/look-board.css +109 -2
- package/src/css/table.css +19 -0
- package/src/index.js +19 -0
- package/src/integrations/builtin/field-inspection/CnFieldInspectionCard.vue +35 -20
- package/src/integrations/builtin/field-inspection.js +21 -0
- package/src/integrations/offline/checklistSubmission.js +137 -0
- package/src/integrations/offline/fieldCollectionHelpers.js +69 -4
- package/src/integrations/offline/index.js +3 -0
- package/src/integrations/offline/offlineDb.js +6 -1
- package/src/integrations/offline/syncReplayService.js +8 -2
- package/src/schemas/app-manifest-v2.schema.json +196 -13
- package/src/utils/contentHeaderLink.js +48 -0
- package/src/utils/detailActionModel.js +59 -2
- package/src/utils/facets.js +74 -2
- package/src/utils/fetchFilterCounts.js +39 -4
- package/src/utils/fillTemplate.js +116 -0
- package/src/utils/initials.js +29 -0
- package/src/utils/libraryWidgetKeys.js +11 -0
- package/src/utils/objectWrite.js +55 -0
- package/src/utils/pageControls.js +78 -0
- package/src/utils/personalLenses.js +39 -2
- package/src/utils/queryPresets.js +93 -0
- package/src/utils/resolveFilterTokens.js +14 -1
- package/src/utils/resolveManifestTokens.js +2 -0
- package/src/utils/schema.js +21 -0
- package/src/utils/sentinelTokens.js +22 -4
- package/src/utils/userGroupsPeek.js +87 -0
- package/src/utils/validateManifestV2.compiled.js +3 -3
- package/src/utils/visibleWhen.js +56 -4
- package/src/utils/widgetDispatch.js +7 -1
- package/src/utils/widgetVisibility.js +7 -56
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CnChoicePickerWidget.vue2.js","sources":["../../../../src/components/CnChoicePickerWidget/CnChoicePickerWidget.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-choice-picker\" data-testid=\"cn-choice-picker\">\n\t\t<p v-if=\"loading\" class=\"cn-choice-picker__note\" data-testid=\"cn-choice-picker-loading\">\n\t\t\t{{ tr('Loading') }}\n\t\t</p>\n\t\t<p v-else-if=\"options.length === 0\" class=\"cn-choice-picker__note\" data-testid=\"cn-choice-picker-empty\">\n\t\t\t{{ emptyLabel }}\n\t\t</p>\n\t\t<fieldset v-else class=\"cn-choice-picker__cards\">\n\t\t\t<legend class=\"cn-choice-picker__legend\">\n\t\t\t\t{{ legend }}\n\t\t\t</legend>\n\t\t\t<label\n\t\t\t\tv-for=\"option in options\"\n\t\t\t\t:key=\"option.key\"\n\t\t\t\tclass=\"cn-choice-picker__card\"\n\t\t\t\t:class=\"{\n\t\t\t\t\t'cn-choice-picker__card--selected': chosen === option.key,\n\t\t\t\t\t'cn-choice-picker__card--refused': option.refusal !== '',\n\t\t\t\t}\"\n\t\t\t\t:data-testid=\"`cn-choice-picker-option-${option.key}`\">\n\t\t\t\t<input\n\t\t\t\t\tclass=\"cn-choice-picker__input\"\n\t\t\t\t\ttype=\"radio\"\n\t\t\t\t\t:name=\"groupName\"\n\t\t\t\t\t:value=\"option.key\"\n\t\t\t\t\t:checked=\"chosen === option.key\"\n\t\t\t\t\t:disabled=\"option.refusal !== '' || saving\"\n\t\t\t\t\t@change=\"choose(option)\">\n\t\t\t\t<span class=\"cn-choice-picker__swatches\" aria-hidden=\"true\">\n\t\t\t\t\t<span\n\t\t\t\t\t\tv-for=\"(colour, index) in option.swatches\"\n\t\t\t\t\t\t:key=\"index\"\n\t\t\t\t\t\tclass=\"cn-choice-picker__swatch\"\n\t\t\t\t\t\t:style=\"{ background: colour }\" />\n\t\t\t\t</span>\n\t\t\t\t<span class=\"cn-choice-picker__text\">\n\t\t\t\t\t<strong class=\"cn-choice-picker__title\">{{ option.title }}</strong>\n\t\t\t\t\t<span v-if=\"option.refusal\" class=\"cn-choice-picker__refusal\" :data-testid=\"`cn-choice-picker-refusal-${option.key}`\">\n\t\t\t\t\t\t{{ option.refusal }}\n\t\t\t\t\t</span>\n\t\t\t\t</span>\n\t\t\t\t<CnStatusBadge\n\t\t\t\t\tv-if=\"option.pill\"\n\t\t\t\t\t:label=\"option.pill.label\"\n\t\t\t\t\t:variant=\"option.pill.variant\"\n\t\t\t\t\tsize=\"small\" />\n\t\t\t</label>\n\t\t</fieldset>\n\n\t\t<NcNoteCard v-if=\"selected && selected.warning.length > 0\" type=\"warning\" data-testid=\"cn-choice-picker-warning\">\n\t\t\t<p v-if=\"warningIntro\" class=\"cn-choice-picker__warning-intro\">\n\t\t\t\t{{ warningIntro }}\n\t\t\t</p>\n\t\t\t<ul class=\"cn-choice-picker__warning-list\">\n\t\t\t\t<li v-for=\"(line, index) in selected.warning\" :key=\"index\">\n\t\t\t\t\t{{ line }}\n\t\t\t\t</li>\n\t\t\t</ul>\n\t\t</NcNoteCard>\n\n\t\t<NcNoteCard v-if=\"notice\" :type=\"noticeType\" data-testid=\"cn-choice-picker-notice\">\n\t\t\t{{ notice }}\n\t\t</NcNoteCard>\n\n\t\t<div v-if=\"options.length > 0 && !readOnly\" class=\"cn-choice-picker__actions\">\n\t\t\t<NcButton\n\t\t\t\tvariant=\"primary\"\n\t\t\t\t:disabled=\"saving || !canSave\"\n\t\t\t\tdata-testid=\"cn-choice-picker-save\"\n\t\t\t\t@click=\"save(false)\">\n\t\t\t\t{{ saveLabel }}\n\t\t\t</NcButton>\n\t\t\t<NcButton\n\t\t\t\tv-if=\"selected && selected.warning.length > 0\"\n\t\t\t\tvariant=\"secondary\"\n\t\t\t\t:disabled=\"saving\"\n\t\t\t\tdata-testid=\"cn-choice-picker-confirm\"\n\t\t\t\t@click=\"save(true)\">\n\t\t\t\t{{ confirmLabel }}\n\t\t\t</NcButton>\n\t\t</div>\n\t\t<p v-if=\"hint\" class=\"cn-choice-picker__hint\">\n\t\t\t{{ hint }}\n\t\t</p>\n\t</div>\n</template>\n\n<script>\nimport { NcButton, NcNoteCard } from '@nextcloud/vue'\nimport CnStatusBadge from '../CnStatusBadge/CnStatusBadge.vue'\nimport { isBadgeVariant } from '../../utils/badgeVariants.js'\nimport { prefixUrl } from '../../utils/headers.js'\nimport { objectUrlOf } from '../../utils/objectWrite.js'\nimport { readPath } from '../../utils/readPath.js'\nimport { serverErrorMessage } from '../../utils/serverErrorMessage.js'\n\nlet uid = 0\n\n/**\n * CnChoicePickerWidget — the `choice-picker` widget: choice cards read from a\n * source (or a static list), each with a radio, colour swatches read from the\n * item, a title and a state pill (a verdict such as \"Leesbaar\" / \"Slecht\n * leesbaar\"), bound to one field of the CURRENT object.\n *\n * Save is a button. A card that carries a warning (a list of lines read from\n * the item) shows them in a warning band under the cards and adds a second\n * button, the confirm action, so a risky choice is saved only on purpose: the\n * request tells the server which one was pressed (`@confirmed`). A card the\n * source marks as refused is listed with its reason and cannot be chosen.\n *\n * @spec openspec/changes/abstract-choice-picker/specs/choice-picker/spec.md\n */\nexport default {\n\tname: 'CnChoicePickerWidget',\n\n\tcomponents: { CnStatusBadge, NcButton, NcNoteCard },\n\n\tinject: {\n\t\tcnTranslate: { default: () => (key) => key },\n\t},\n\n\tprops: {\n\t\t/**\n\t\t * The widget configuration.\n\t\t *\n\t\t * - `field` (required) — the top-level field of the object holding the chosen key.\n\t\t * - `source` — `{ url, path?, key, label, swatches?, state?, refusal?, warning? }` (tokens `@objectId`, `@object.<field>` in the url), or `items` — the same item shape as a static list.\n\t\t * - `swatches` — path to an array of colours (CSS colour strings).\n\t\t * - `state` — `{ path, map?, variantMap?, empty?, emptyVariant? }`: the pill; `map` turns the value into text, `variantMap` into a badge variant, `empty` is the text when the value is missing.\n\t\t * - `refusal` — path to a string: the card is listed with it and cannot be chosen.\n\t\t * - `warning` — `{ list, item? }`: `list` is a path to an array; `item` a template with `{path}` placeholders for object items (strings are used as they are).\n\t\t * - `legend`, `warningIntro`, `saveLabel`, `confirmLabel`, `emptyText`, `hint`, `readOnly`.\n\t\t * - `save` — `{ method?, url?, payload? }`: a custom request (tokens `@value`, `@confirmed`, `@objectId`, `@object.<field>`); without it the field is PATCHed on the object.\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tcontent: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/** The current detail-page object. */\n\t\tobjectData: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** The current object id. */\n\t\tobjectId: {\n\t\t\ttype: [String, Number],\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** OpenRegister register slug of the surface. */\n\t\tregister: {\n\t\t\ttype: [String, Object],\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** OpenRegister schema slug of the surface. */\n\t\tschema: {\n\t\t\ttype: [String, Object],\n\t\t\tdefault: '',\n\t\t},\n\t},\n\n\temits: ['saved'],\n\n\tdata() {\n\t\tuid += 1\n\t\treturn {\n\t\t\tgroupName: `cn-choice-picker-${uid}`,\n\t\t\tsourced: [],\n\t\t\tloading: false,\n\t\t\tsaved: '',\n\t\t\tchosen: '',\n\t\t\tsaving: false,\n\t\t\tnotice: '',\n\t\t\tnoticeType: 'success',\n\t\t}\n\t},\n\n\tcomputed: {\n\t\tspec() {\n\t\t\treturn this.content.source || {}\n\t\t},\n\n\t\t/** The cards, from the static items then the source. */\n\t\toptions() {\n\t\t\tconst items = [...(Array.isArray(this.content.items) ? this.content.items : []), ...this.sourced]\n\t\t\treturn items\n\t\t\t\t.filter((item) => item && readPath(item, this.spec.key || 'key') !== undefined)\n\t\t\t\t.map((item) => {\n\t\t\t\t\tconst key = String(readPath(item, this.spec.key || 'key'))\n\t\t\t\t\tconst refusal = this.spec.refusal ? readPath(item, this.spec.refusal) : ''\n\t\t\t\t\treturn {\n\t\t\t\t\t\tkey,\n\t\t\t\t\t\ttitle: String(readPath(item, this.spec.label || 'label') ?? key),\n\t\t\t\t\t\tswatches: this.listOf(item, this.spec.swatches).filter((colour) => typeof colour === 'string'),\n\t\t\t\t\t\tpill: this.pillOf(item),\n\t\t\t\t\t\trefusal: typeof refusal === 'string' ? refusal : '',\n\t\t\t\t\t\twarning: this.warningOf(item),\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t},\n\n\t\tselected() {\n\t\t\treturn this.options.find((option) => option.key === this.chosen) || null\n\t\t},\n\n\t\tcanSave() {\n\t\t\treturn this.chosen !== '' && this.chosen !== this.saved && (this.selected ? this.selected.refusal === '' : false)\n\t\t},\n\n\t\tlegend() {\n\t\t\treturn this.tr(this.content.legend || 'Choose one')\n\t\t},\n\n\t\twarningIntro() {\n\t\t\treturn this.tr(this.content.warningIntro || '')\n\t\t},\n\n\t\tsaveLabel() {\n\t\t\treturn this.tr(this.content.saveLabel || 'Save')\n\t\t},\n\n\t\tconfirmLabel() {\n\t\t\treturn this.tr(this.content.confirmLabel || 'Use it anyway')\n\t\t},\n\n\t\temptyLabel() {\n\t\t\treturn this.tr(this.content.emptyText || 'Nothing to choose from')\n\t\t},\n\n\t\thint() {\n\t\t\treturn this.tr(this.content.hint || '')\n\t\t},\n\n\t\treadOnly() {\n\t\t\treturn this.content.readOnly === true\n\t\t},\n\n\t\tobjectUrl() {\n\t\t\treturn objectUrlOf(this.register, this.schema, this.objectId || (this.objectData && this.objectData.id))\n\t\t},\n\t},\n\n\twatch: {\n\t\tobjectData() {\n\t\t\tthis.adopt()\n\t\t\tthis.loadSource()\n\t\t},\n\t},\n\n\tcreated() {\n\t\tthis.adopt()\n\t\tthis.loadSource()\n\t},\n\n\tmethods: {\n\t\ttr(text) {\n\t\t\tif (typeof text !== 'string' || text === '') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn typeof this.cnTranslate === 'function' ? this.cnTranslate(text) : text\n\t\t},\n\n\t\t/** Read the current choice off the object. */\n\t\tadopt() {\n\t\t\tconst stored = readPath(this.objectData || {}, this.content.field)\n\t\t\tthis.saved = stored === undefined || stored === null ? '' : String(stored)\n\t\t\tthis.chosen = this.saved\n\t\t},\n\n\t\t/**\n\t\t * A list off an item.\n\t\t *\n\t\t * @param {object} item The item.\n\t\t * @param {string} path The path, or undefined.\n\t\t * @return {Array}\n\t\t */\n\t\tlistOf(item, path) {\n\t\t\tconst list = path ? readPath(item, path) : []\n\t\t\treturn Array.isArray(list) ? list : []\n\t\t},\n\n\t\t/**\n\t\t * The state pill of an item.\n\t\t *\n\t\t * @param {object} item The item.\n\t\t * @return {{label: string, variant: string}|null}\n\t\t */\n\t\tpillOf(item) {\n\t\t\tconst state = this.spec.state\n\t\t\tif (!state || !state.path) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst raw = readPath(item, state.path)\n\t\t\tconst empty = raw === undefined || raw === null || raw === ''\n\t\t\tif (empty) {\n\t\t\t\treturn state.empty ? { label: this.tr(state.empty), variant: isBadgeVariant(state.emptyVariant) ? state.emptyVariant : 'default' } : null\n\t\t\t}\n\t\t\tconst label = state.map && Object.hasOwn(state.map, String(raw)) ? this.tr(state.map[String(raw)]) : String(raw)\n\t\t\tconst variant = state.variantMap && state.variantMap[String(raw)]\n\t\t\treturn { label, variant: isBadgeVariant(variant) ? variant : 'default' }\n\t\t},\n\n\t\t/**\n\t\t * The warning lines of an item.\n\t\t *\n\t\t * @param {object} item The item.\n\t\t * @return {string[]}\n\t\t */\n\t\twarningOf(item) {\n\t\t\tconst spec = this.spec.warning\n\t\t\tif (!spec || !spec.list) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\treturn this.listOf(item, spec.list)\n\t\t\t\t.map((entry) => {\n\t\t\t\t\tif (typeof entry === 'string') {\n\t\t\t\t\t\treturn entry\n\t\t\t\t\t}\n\t\t\t\t\tif (!entry || typeof entry !== 'object' || !spec.item) {\n\t\t\t\t\t\treturn ''\n\t\t\t\t\t}\n\t\t\t\t\treturn this.tr(spec.item).replace(/\\{([\\w.]+)\\}/g, (m, path) => String(readPath(entry, path) ?? ''))\n\t\t\t\t})\n\t\t\t\t.filter((line) => line !== '')\n\t\t},\n\n\t\t/**\n\t\t * Resolve the tokens in a url or payload.\n\t\t *\n\t\t * @param {unknown} value The value.\n\t\t * @param {object} vars `{ value, confirmed }`.\n\t\t * @return {unknown}\n\t\t */\n\t\tresolve(value, vars) {\n\t\t\tif (Array.isArray(value)) {\n\t\t\t\treturn value.map((v) => this.resolve(v, vars))\n\t\t\t}\n\t\t\tif (value && typeof value === 'object') {\n\t\t\t\treturn Object.fromEntries(Object.entries(value).map(([k, v]) => [k, this.resolve(v, vars)]))\n\t\t\t}\n\t\t\tif (typeof value !== 'string') {\n\t\t\t\treturn value\n\t\t\t}\n\t\t\tconst object = this.objectData || {}\n\t\t\tif (value === '@value') {\n\t\t\t\treturn vars.value\n\t\t\t}\n\t\t\tif (value === '@confirmed') {\n\t\t\t\treturn vars.confirmed\n\t\t\t}\n\t\t\tconst whole = value.match(/^@object\\.([\\w.@]+)$/)\n\t\t\tif (whole) {\n\t\t\t\treturn readPath(object, whole[1])\n\t\t\t}\n\t\t\treturn value\n\t\t\t\t.replace(/@objectId/g, () => encodeURIComponent(String(this.objectId || object.id || '')))\n\t\t\t\t.replace(/@object\\.([\\w.@]+)/g, (m, path) => encodeURIComponent(String(readPath(object, path) ?? '')))\n\t\t\t\t.replace(/@value/g, () => encodeURIComponent(String(vars.value)))\n\t\t},\n\n\t\t/** Read the cards of `source`. */\n\t\tasync loadSource() {\n\t\t\tif (!this.spec.url) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.loading = true\n\t\t\ttry {\n\t\t\t\tconst { default: axios } = await import('@nextcloud/axios')\n\t\t\t\tconst { data } = await axios.get(prefixUrl(String(this.resolve(this.spec.url, { value: '', confirmed: false }))))\n\t\t\t\tconst list = this.spec.path ? readPath(data, this.spec.path) : data\n\t\t\t\tthis.sourced = Array.isArray(list) ? list : []\n\t\t\t} catch (e) {\n\t\t\t\tthis.noticeType = 'error'\n\t\t\t\tthis.notice = serverErrorMessage(e)\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 * Choose a card (nothing is written until Save).\n\t\t *\n\t\t * @param {object} option The card.\n\t\t */\n\t\tchoose(option) {\n\t\t\tthis.chosen = option.key\n\t\t\tthis.notice = ''\n\t\t},\n\n\t\t/**\n\t\t * Save the chosen card: the configured request, else a PATCH of the field.\n\t\t *\n\t\t * @param {boolean} confirmed Whether the confirm action was pressed.\n\t\t * @return {Promise<void>}\n\t\t * @spec openspec/changes/abstract-choice-picker/specs/choice-picker/spec.md#requirement-a-risky-choice-is-saved-only-on-purpose\n\t\t */\n\t\tasync save(confirmed) {\n\t\t\tif (!this.selected) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst request = this.content.save\n\t\t\tif (!request && !this.objectUrl) {\n\t\t\t\tthis.noticeType = 'error'\n\t\t\t\tthis.notice = this.tr('This choice cannot be saved here.')\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.saving = true\n\t\t\tthis.notice = ''\n\t\t\ttry {\n\t\t\t\tconst { default: axios } = await import('@nextcloud/axios')\n\t\t\t\tconst vars = { value: this.selected.key, confirmed }\n\t\t\t\tif (request && request.url) {\n\t\t\t\t\tconst method = String(request.method || 'POST').toLowerCase()\n\t\t\t\t\tawait axios[method](prefixUrl(String(this.resolve(request.url, vars))), this.resolve(request.payload || {}, vars))\n\t\t\t\t} else {\n\t\t\t\t\tawait axios.patch(prefixUrl(this.objectUrl), { [this.content.field]: this.selected.key })\n\t\t\t\t}\n\t\t\t\tthis.saved = this.selected.key\n\t\t\t\tthis.noticeType = 'success'\n\t\t\t\tthis.notice = this.tr(this.content.savedText || 'Saved.')\n\t\t\t\t/**\n\t\t\t\t * @event saved The choice was written.\n\t\t\t\t * @type {{field: string, value: string, confirmed: boolean}}\n\t\t\t\t */\n\t\t\t\tthis.$emit('saved', { field: this.content.field, value: this.saved, confirmed })\n\t\t\t} catch (e) {\n\t\t\t\tthis.noticeType = 'error'\n\t\t\t\tthis.notice = serverErrorMessage(e)\n\t\t\t} finally {\n\t\t\t\tthis.saving = false\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-choice-picker {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 12px;\n\tmin-width: 0;\n}\n\n.cn-choice-picker__cards {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: 10px;\n\tmargin: 0;\n\tpadding: 0;\n\tborder: 0;\n}\n\n.cn-choice-picker__legend {\n\tposition: absolute;\n\twidth: 1px;\n\theight: 1px;\n\toverflow: hidden;\n\tclip-path: inset(50%);\n}\n\n.cn-choice-picker__card {\n\tposition: relative;\n\tdisplay: flex;\n\tflex: 1 1 220px;\n\talign-items: center;\n\tgap: 12px;\n\tpadding: 10px 12px;\n\tborder: 1px solid var(--cn-board-hairline, var(--color-border));\n\tborder-radius: 10px;\n\tbackground: var(--color-main-background);\n\tcursor: pointer;\n}\n\n.cn-choice-picker__card--selected {\n\tpadding: 9px 11px;\n\tborder: 2px solid var(--color-primary-element);\n}\n\n.cn-choice-picker__card--refused {\n\tcursor: not-allowed;\n\topacity: 0.7;\n}\n\n.cn-choice-picker__card:focus-within {\n\toutline: 2px solid var(--color-primary-element);\n\toutline-offset: 2px;\n}\n\n.cn-choice-picker__input {\n\tflex: 0 0 auto;\n\twidth: 18px;\n\theight: 18px;\n\tmargin: 0;\n\taccent-color: var(--color-primary-element);\n}\n\n.cn-choice-picker__swatches {\n\tdisplay: flex;\n\tgap: 4px;\n}\n\n.cn-choice-picker__swatch {\n\twidth: 18px;\n\theight: 18px;\n\tbox-sizing: border-box;\n\tborder: 1px solid var(--color-border);\n\tborder-radius: 4px;\n}\n\n.cn-choice-picker__text {\n\tdisplay: flex;\n\tflex: 1 1 auto;\n\tflex-direction: column;\n\tgap: 2px;\n\tmin-width: 0;\n}\n\n.cn-choice-picker__title {\n\tfont-size: 15px;\n}\n\n.cn-choice-picker__refusal,\n.cn-choice-picker__hint,\n.cn-choice-picker__note {\n\tmargin: 0;\n\tfont-size: 13px;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-choice-picker__warning-intro {\n\tmargin: 0 0 4px;\n}\n\n.cn-choice-picker__warning-list {\n\tmargin: 0;\n\tpadding-inline-start: 18px;\n}\n\n.cn-choice-picker__actions {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: 8px;\n}\n</style>\n"],"names":["CnStatusBadge"],"mappings":"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"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { resolveComponent, openBlock, createElementBlock, toDisplayString, createElementVNode, Fragment, renderList, normalizeClass, normalizeStyle, createCommentVNode, createBlock, withCtx, createTextVNode, createVNode } from 'vue';
|
|
2
|
+
|
|
3
|
+
const _hoisted_1 = {
|
|
4
|
+
class: "cn-choice-picker",
|
|
5
|
+
"data-testid": "cn-choice-picker"
|
|
6
|
+
};
|
|
7
|
+
const _hoisted_2 = {
|
|
8
|
+
key: 0,
|
|
9
|
+
class: "cn-choice-picker__note",
|
|
10
|
+
"data-testid": "cn-choice-picker-loading"
|
|
11
|
+
};
|
|
12
|
+
const _hoisted_3 = {
|
|
13
|
+
key: 1,
|
|
14
|
+
class: "cn-choice-picker__note",
|
|
15
|
+
"data-testid": "cn-choice-picker-empty"
|
|
16
|
+
};
|
|
17
|
+
const _hoisted_4 = {
|
|
18
|
+
key: 2,
|
|
19
|
+
class: "cn-choice-picker__cards"
|
|
20
|
+
};
|
|
21
|
+
const _hoisted_5 = { class: "cn-choice-picker__legend" };
|
|
22
|
+
const _hoisted_6 = ["data-testid"];
|
|
23
|
+
const _hoisted_7 = ["name", "value", "checked", "disabled", "onChange"];
|
|
24
|
+
const _hoisted_8 = {
|
|
25
|
+
class: "cn-choice-picker__swatches",
|
|
26
|
+
"aria-hidden": "true"
|
|
27
|
+
};
|
|
28
|
+
const _hoisted_9 = { class: "cn-choice-picker__text" };
|
|
29
|
+
const _hoisted_10 = { class: "cn-choice-picker__title" };
|
|
30
|
+
const _hoisted_11 = ["data-testid"];
|
|
31
|
+
const _hoisted_12 = {
|
|
32
|
+
key: 0,
|
|
33
|
+
class: "cn-choice-picker__warning-intro"
|
|
34
|
+
};
|
|
35
|
+
const _hoisted_13 = { class: "cn-choice-picker__warning-list" };
|
|
36
|
+
const _hoisted_14 = {
|
|
37
|
+
key: 5,
|
|
38
|
+
class: "cn-choice-picker__actions"
|
|
39
|
+
};
|
|
40
|
+
const _hoisted_15 = {
|
|
41
|
+
key: 6,
|
|
42
|
+
class: "cn-choice-picker__hint"
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
46
|
+
const _component_CnStatusBadge = resolveComponent("CnStatusBadge");
|
|
47
|
+
const _component_NcNoteCard = resolveComponent("NcNoteCard");
|
|
48
|
+
const _component_NcButton = resolveComponent("NcButton");
|
|
49
|
+
|
|
50
|
+
return (openBlock(), createElementBlock("div", _hoisted_1, [
|
|
51
|
+
($data.loading)
|
|
52
|
+
? (openBlock(), createElementBlock("p", _hoisted_2, toDisplayString($options.tr('Loading')), 1 /* TEXT */))
|
|
53
|
+
: ($options.options.length === 0)
|
|
54
|
+
? (openBlock(), createElementBlock("p", _hoisted_3, toDisplayString($options.emptyLabel), 1 /* TEXT */))
|
|
55
|
+
: (openBlock(), createElementBlock("fieldset", _hoisted_4, [
|
|
56
|
+
createElementVNode("legend", _hoisted_5, toDisplayString($options.legend), 1 /* TEXT */),
|
|
57
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList($options.options, (option) => {
|
|
58
|
+
return (openBlock(), createElementBlock("label", {
|
|
59
|
+
key: option.key,
|
|
60
|
+
class: normalizeClass(["cn-choice-picker__card", {
|
|
61
|
+
'cn-choice-picker__card--selected': $data.chosen === option.key,
|
|
62
|
+
'cn-choice-picker__card--refused': option.refusal !== '',
|
|
63
|
+
}]),
|
|
64
|
+
"data-testid": `cn-choice-picker-option-${option.key}`
|
|
65
|
+
}, [
|
|
66
|
+
createElementVNode("input", {
|
|
67
|
+
class: "cn-choice-picker__input",
|
|
68
|
+
type: "radio",
|
|
69
|
+
name: $data.groupName,
|
|
70
|
+
value: option.key,
|
|
71
|
+
checked: $data.chosen === option.key,
|
|
72
|
+
disabled: option.refusal !== '' || $data.saving,
|
|
73
|
+
onChange: $event => ($options.choose(option))
|
|
74
|
+
}, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_7),
|
|
75
|
+
createElementVNode("span", _hoisted_8, [
|
|
76
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(option.swatches, (colour, index) => {
|
|
77
|
+
return (openBlock(), createElementBlock("span", {
|
|
78
|
+
key: index,
|
|
79
|
+
class: "cn-choice-picker__swatch",
|
|
80
|
+
style: normalizeStyle({ background: colour })
|
|
81
|
+
}, null, 4 /* STYLE */))
|
|
82
|
+
}), 128 /* KEYED_FRAGMENT */))
|
|
83
|
+
]),
|
|
84
|
+
createElementVNode("span", _hoisted_9, [
|
|
85
|
+
createElementVNode("strong", _hoisted_10, toDisplayString(option.title), 1 /* TEXT */),
|
|
86
|
+
(option.refusal)
|
|
87
|
+
? (openBlock(), createElementBlock("span", {
|
|
88
|
+
key: 0,
|
|
89
|
+
class: "cn-choice-picker__refusal",
|
|
90
|
+
"data-testid": `cn-choice-picker-refusal-${option.key}`
|
|
91
|
+
}, toDisplayString(option.refusal), 9 /* TEXT, PROPS */, _hoisted_11))
|
|
92
|
+
: createCommentVNode("v-if", true)
|
|
93
|
+
]),
|
|
94
|
+
(option.pill)
|
|
95
|
+
? (openBlock(), createBlock(_component_CnStatusBadge, {
|
|
96
|
+
key: 0,
|
|
97
|
+
label: option.pill.label,
|
|
98
|
+
variant: option.pill.variant,
|
|
99
|
+
size: "small"
|
|
100
|
+
}, null, 8 /* PROPS */, ["label", "variant"]))
|
|
101
|
+
: createCommentVNode("v-if", true)
|
|
102
|
+
], 10 /* CLASS, PROPS */, _hoisted_6))
|
|
103
|
+
}), 128 /* KEYED_FRAGMENT */))
|
|
104
|
+
])),
|
|
105
|
+
($options.selected && $options.selected.warning.length > 0)
|
|
106
|
+
? (openBlock(), createBlock(_component_NcNoteCard, {
|
|
107
|
+
key: 3,
|
|
108
|
+
type: "warning",
|
|
109
|
+
"data-testid": "cn-choice-picker-warning"
|
|
110
|
+
}, {
|
|
111
|
+
default: withCtx(() => [
|
|
112
|
+
($options.warningIntro)
|
|
113
|
+
? (openBlock(), createElementBlock("p", _hoisted_12, toDisplayString($options.warningIntro), 1 /* TEXT */))
|
|
114
|
+
: createCommentVNode("v-if", true),
|
|
115
|
+
createElementVNode("ul", _hoisted_13, [
|
|
116
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList($options.selected.warning, (line, index) => {
|
|
117
|
+
return (openBlock(), createElementBlock("li", { key: index }, toDisplayString(line), 1 /* TEXT */))
|
|
118
|
+
}), 128 /* KEYED_FRAGMENT */))
|
|
119
|
+
])
|
|
120
|
+
]),
|
|
121
|
+
_: 1 /* STABLE */
|
|
122
|
+
}))
|
|
123
|
+
: createCommentVNode("v-if", true),
|
|
124
|
+
($data.notice)
|
|
125
|
+
? (openBlock(), createBlock(_component_NcNoteCard, {
|
|
126
|
+
key: 4,
|
|
127
|
+
type: $data.noticeType,
|
|
128
|
+
"data-testid": "cn-choice-picker-notice"
|
|
129
|
+
}, {
|
|
130
|
+
default: withCtx(() => [
|
|
131
|
+
createTextVNode(toDisplayString($data.notice), 1 /* TEXT */)
|
|
132
|
+
]),
|
|
133
|
+
_: 1 /* STABLE */
|
|
134
|
+
}, 8 /* PROPS */, ["type"]))
|
|
135
|
+
: createCommentVNode("v-if", true),
|
|
136
|
+
($options.options.length > 0 && !$options.readOnly)
|
|
137
|
+
? (openBlock(), createElementBlock("div", _hoisted_14, [
|
|
138
|
+
createVNode(_component_NcButton, {
|
|
139
|
+
variant: "primary",
|
|
140
|
+
disabled: $data.saving || !$options.canSave,
|
|
141
|
+
"data-testid": "cn-choice-picker-save",
|
|
142
|
+
onClick: _cache[0] || (_cache[0] = $event => ($options.save(false)))
|
|
143
|
+
}, {
|
|
144
|
+
default: withCtx(() => [
|
|
145
|
+
createTextVNode(toDisplayString($options.saveLabel), 1 /* TEXT */)
|
|
146
|
+
]),
|
|
147
|
+
_: 1 /* STABLE */
|
|
148
|
+
}, 8 /* PROPS */, ["disabled"]),
|
|
149
|
+
($options.selected && $options.selected.warning.length > 0)
|
|
150
|
+
? (openBlock(), createBlock(_component_NcButton, {
|
|
151
|
+
key: 0,
|
|
152
|
+
variant: "secondary",
|
|
153
|
+
disabled: $data.saving,
|
|
154
|
+
"data-testid": "cn-choice-picker-confirm",
|
|
155
|
+
onClick: _cache[1] || (_cache[1] = $event => ($options.save(true)))
|
|
156
|
+
}, {
|
|
157
|
+
default: withCtx(() => [
|
|
158
|
+
createTextVNode(toDisplayString($options.confirmLabel), 1 /* TEXT */)
|
|
159
|
+
]),
|
|
160
|
+
_: 1 /* STABLE */
|
|
161
|
+
}, 8 /* PROPS */, ["disabled"]))
|
|
162
|
+
: createCommentVNode("v-if", true)
|
|
163
|
+
]))
|
|
164
|
+
: createCommentVNode("v-if", true),
|
|
165
|
+
($options.hint)
|
|
166
|
+
? (openBlock(), createElementBlock("p", _hoisted_15, toDisplayString($options.hint), 1 /* TEXT */))
|
|
167
|
+
: createCommentVNode("v-if", true)
|
|
168
|
+
]))
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export { render };
|
|
172
|
+
//# sourceMappingURL=CnChoicePickerWidget.vue3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CnChoicePickerWidget.vue3.js","sources":["../../../../src/components/CnChoicePickerWidget/CnChoicePickerWidget.vue?vue&type=template&id=7075cbe2&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-choice-picker\" data-testid=\"cn-choice-picker\">\n\t\t<p v-if=\"loading\" class=\"cn-choice-picker__note\" data-testid=\"cn-choice-picker-loading\">\n\t\t\t{{ tr('Loading') }}\n\t\t</p>\n\t\t<p v-else-if=\"options.length === 0\" class=\"cn-choice-picker__note\" data-testid=\"cn-choice-picker-empty\">\n\t\t\t{{ emptyLabel }}\n\t\t</p>\n\t\t<fieldset v-else class=\"cn-choice-picker__cards\">\n\t\t\t<legend class=\"cn-choice-picker__legend\">\n\t\t\t\t{{ legend }}\n\t\t\t</legend>\n\t\t\t<label\n\t\t\t\tv-for=\"option in options\"\n\t\t\t\t:key=\"option.key\"\n\t\t\t\tclass=\"cn-choice-picker__card\"\n\t\t\t\t:class=\"{\n\t\t\t\t\t'cn-choice-picker__card--selected': chosen === option.key,\n\t\t\t\t\t'cn-choice-picker__card--refused': option.refusal !== '',\n\t\t\t\t}\"\n\t\t\t\t:data-testid=\"`cn-choice-picker-option-${option.key}`\">\n\t\t\t\t<input\n\t\t\t\t\tclass=\"cn-choice-picker__input\"\n\t\t\t\t\ttype=\"radio\"\n\t\t\t\t\t:name=\"groupName\"\n\t\t\t\t\t:value=\"option.key\"\n\t\t\t\t\t:checked=\"chosen === option.key\"\n\t\t\t\t\t:disabled=\"option.refusal !== '' || saving\"\n\t\t\t\t\t@change=\"choose(option)\">\n\t\t\t\t<span class=\"cn-choice-picker__swatches\" aria-hidden=\"true\">\n\t\t\t\t\t<span\n\t\t\t\t\t\tv-for=\"(colour, index) in option.swatches\"\n\t\t\t\t\t\t:key=\"index\"\n\t\t\t\t\t\tclass=\"cn-choice-picker__swatch\"\n\t\t\t\t\t\t:style=\"{ background: colour }\" />\n\t\t\t\t</span>\n\t\t\t\t<span class=\"cn-choice-picker__text\">\n\t\t\t\t\t<strong class=\"cn-choice-picker__title\">{{ option.title }}</strong>\n\t\t\t\t\t<span v-if=\"option.refusal\" class=\"cn-choice-picker__refusal\" :data-testid=\"`cn-choice-picker-refusal-${option.key}`\">\n\t\t\t\t\t\t{{ option.refusal }}\n\t\t\t\t\t</span>\n\t\t\t\t</span>\n\t\t\t\t<CnStatusBadge\n\t\t\t\t\tv-if=\"option.pill\"\n\t\t\t\t\t:label=\"option.pill.label\"\n\t\t\t\t\t:variant=\"option.pill.variant\"\n\t\t\t\t\tsize=\"small\" />\n\t\t\t</label>\n\t\t</fieldset>\n\n\t\t<NcNoteCard v-if=\"selected && selected.warning.length > 0\" type=\"warning\" data-testid=\"cn-choice-picker-warning\">\n\t\t\t<p v-if=\"warningIntro\" class=\"cn-choice-picker__warning-intro\">\n\t\t\t\t{{ warningIntro }}\n\t\t\t</p>\n\t\t\t<ul class=\"cn-choice-picker__warning-list\">\n\t\t\t\t<li v-for=\"(line, index) in selected.warning\" :key=\"index\">\n\t\t\t\t\t{{ line }}\n\t\t\t\t</li>\n\t\t\t</ul>\n\t\t</NcNoteCard>\n\n\t\t<NcNoteCard v-if=\"notice\" :type=\"noticeType\" data-testid=\"cn-choice-picker-notice\">\n\t\t\t{{ notice }}\n\t\t</NcNoteCard>\n\n\t\t<div v-if=\"options.length > 0 && !readOnly\" class=\"cn-choice-picker__actions\">\n\t\t\t<NcButton\n\t\t\t\tvariant=\"primary\"\n\t\t\t\t:disabled=\"saving || !canSave\"\n\t\t\t\tdata-testid=\"cn-choice-picker-save\"\n\t\t\t\t@click=\"save(false)\">\n\t\t\t\t{{ saveLabel }}\n\t\t\t</NcButton>\n\t\t\t<NcButton\n\t\t\t\tv-if=\"selected && selected.warning.length > 0\"\n\t\t\t\tvariant=\"secondary\"\n\t\t\t\t:disabled=\"saving\"\n\t\t\t\tdata-testid=\"cn-choice-picker-confirm\"\n\t\t\t\t@click=\"save(true)\">\n\t\t\t\t{{ confirmLabel }}\n\t\t\t</NcButton>\n\t\t</div>\n\t\t<p v-if=\"hint\" class=\"cn-choice-picker__hint\">\n\t\t\t{{ hint }}\n\t\t</p>\n\t</div>\n</template>\n\n<script>\nimport { NcButton, NcNoteCard } from '@nextcloud/vue'\nimport CnStatusBadge from '../CnStatusBadge/CnStatusBadge.vue'\nimport { isBadgeVariant } from '../../utils/badgeVariants.js'\nimport { prefixUrl } from '../../utils/headers.js'\nimport { objectUrlOf } from '../../utils/objectWrite.js'\nimport { readPath } from '../../utils/readPath.js'\nimport { serverErrorMessage } from '../../utils/serverErrorMessage.js'\n\nlet uid = 0\n\n/**\n * CnChoicePickerWidget — the `choice-picker` widget: choice cards read from a\n * source (or a static list), each with a radio, colour swatches read from the\n * item, a title and a state pill (a verdict such as \"Leesbaar\" / \"Slecht\n * leesbaar\"), bound to one field of the CURRENT object.\n *\n * Save is a button. A card that carries a warning (a list of lines read from\n * the item) shows them in a warning band under the cards and adds a second\n * button, the confirm action, so a risky choice is saved only on purpose: the\n * request tells the server which one was pressed (`@confirmed`). A card the\n * source marks as refused is listed with its reason and cannot be chosen.\n *\n * @spec openspec/changes/abstract-choice-picker/specs/choice-picker/spec.md\n */\nexport default {\n\tname: 'CnChoicePickerWidget',\n\n\tcomponents: { CnStatusBadge, NcButton, NcNoteCard },\n\n\tinject: {\n\t\tcnTranslate: { default: () => (key) => key },\n\t},\n\n\tprops: {\n\t\t/**\n\t\t * The widget configuration.\n\t\t *\n\t\t * - `field` (required) — the top-level field of the object holding the chosen key.\n\t\t * - `source` — `{ url, path?, key, label, swatches?, state?, refusal?, warning? }` (tokens `@objectId`, `@object.<field>` in the url), or `items` — the same item shape as a static list.\n\t\t * - `swatches` — path to an array of colours (CSS colour strings).\n\t\t * - `state` — `{ path, map?, variantMap?, empty?, emptyVariant? }`: the pill; `map` turns the value into text, `variantMap` into a badge variant, `empty` is the text when the value is missing.\n\t\t * - `refusal` — path to a string: the card is listed with it and cannot be chosen.\n\t\t * - `warning` — `{ list, item? }`: `list` is a path to an array; `item` a template with `{path}` placeholders for object items (strings are used as they are).\n\t\t * - `legend`, `warningIntro`, `saveLabel`, `confirmLabel`, `emptyText`, `hint`, `readOnly`.\n\t\t * - `save` — `{ method?, url?, payload? }`: a custom request (tokens `@value`, `@confirmed`, `@objectId`, `@object.<field>`); without it the field is PATCHed on the object.\n\t\t *\n\t\t * @type {object}\n\t\t */\n\t\tcontent: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/** The current detail-page object. */\n\t\tobjectData: {\n\t\t\ttype: Object,\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** The current object id. */\n\t\tobjectId: {\n\t\t\ttype: [String, Number],\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** OpenRegister register slug of the surface. */\n\t\tregister: {\n\t\t\ttype: [String, Object],\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** OpenRegister schema slug of the surface. */\n\t\tschema: {\n\t\t\ttype: [String, Object],\n\t\t\tdefault: '',\n\t\t},\n\t},\n\n\temits: ['saved'],\n\n\tdata() {\n\t\tuid += 1\n\t\treturn {\n\t\t\tgroupName: `cn-choice-picker-${uid}`,\n\t\t\tsourced: [],\n\t\t\tloading: false,\n\t\t\tsaved: '',\n\t\t\tchosen: '',\n\t\t\tsaving: false,\n\t\t\tnotice: '',\n\t\t\tnoticeType: 'success',\n\t\t}\n\t},\n\n\tcomputed: {\n\t\tspec() {\n\t\t\treturn this.content.source || {}\n\t\t},\n\n\t\t/** The cards, from the static items then the source. */\n\t\toptions() {\n\t\t\tconst items = [...(Array.isArray(this.content.items) ? this.content.items : []), ...this.sourced]\n\t\t\treturn items\n\t\t\t\t.filter((item) => item && readPath(item, this.spec.key || 'key') !== undefined)\n\t\t\t\t.map((item) => {\n\t\t\t\t\tconst key = String(readPath(item, this.spec.key || 'key'))\n\t\t\t\t\tconst refusal = this.spec.refusal ? readPath(item, this.spec.refusal) : ''\n\t\t\t\t\treturn {\n\t\t\t\t\t\tkey,\n\t\t\t\t\t\ttitle: String(readPath(item, this.spec.label || 'label') ?? key),\n\t\t\t\t\t\tswatches: this.listOf(item, this.spec.swatches).filter((colour) => typeof colour === 'string'),\n\t\t\t\t\t\tpill: this.pillOf(item),\n\t\t\t\t\t\trefusal: typeof refusal === 'string' ? refusal : '',\n\t\t\t\t\t\twarning: this.warningOf(item),\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t},\n\n\t\tselected() {\n\t\t\treturn this.options.find((option) => option.key === this.chosen) || null\n\t\t},\n\n\t\tcanSave() {\n\t\t\treturn this.chosen !== '' && this.chosen !== this.saved && (this.selected ? this.selected.refusal === '' : false)\n\t\t},\n\n\t\tlegend() {\n\t\t\treturn this.tr(this.content.legend || 'Choose one')\n\t\t},\n\n\t\twarningIntro() {\n\t\t\treturn this.tr(this.content.warningIntro || '')\n\t\t},\n\n\t\tsaveLabel() {\n\t\t\treturn this.tr(this.content.saveLabel || 'Save')\n\t\t},\n\n\t\tconfirmLabel() {\n\t\t\treturn this.tr(this.content.confirmLabel || 'Use it anyway')\n\t\t},\n\n\t\temptyLabel() {\n\t\t\treturn this.tr(this.content.emptyText || 'Nothing to choose from')\n\t\t},\n\n\t\thint() {\n\t\t\treturn this.tr(this.content.hint || '')\n\t\t},\n\n\t\treadOnly() {\n\t\t\treturn this.content.readOnly === true\n\t\t},\n\n\t\tobjectUrl() {\n\t\t\treturn objectUrlOf(this.register, this.schema, this.objectId || (this.objectData && this.objectData.id))\n\t\t},\n\t},\n\n\twatch: {\n\t\tobjectData() {\n\t\t\tthis.adopt()\n\t\t\tthis.loadSource()\n\t\t},\n\t},\n\n\tcreated() {\n\t\tthis.adopt()\n\t\tthis.loadSource()\n\t},\n\n\tmethods: {\n\t\ttr(text) {\n\t\t\tif (typeof text !== 'string' || text === '') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn typeof this.cnTranslate === 'function' ? this.cnTranslate(text) : text\n\t\t},\n\n\t\t/** Read the current choice off the object. */\n\t\tadopt() {\n\t\t\tconst stored = readPath(this.objectData || {}, this.content.field)\n\t\t\tthis.saved = stored === undefined || stored === null ? '' : String(stored)\n\t\t\tthis.chosen = this.saved\n\t\t},\n\n\t\t/**\n\t\t * A list off an item.\n\t\t *\n\t\t * @param {object} item The item.\n\t\t * @param {string} path The path, or undefined.\n\t\t * @return {Array}\n\t\t */\n\t\tlistOf(item, path) {\n\t\t\tconst list = path ? readPath(item, path) : []\n\t\t\treturn Array.isArray(list) ? list : []\n\t\t},\n\n\t\t/**\n\t\t * The state pill of an item.\n\t\t *\n\t\t * @param {object} item The item.\n\t\t * @return {{label: string, variant: string}|null}\n\t\t */\n\t\tpillOf(item) {\n\t\t\tconst state = this.spec.state\n\t\t\tif (!state || !state.path) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst raw = readPath(item, state.path)\n\t\t\tconst empty = raw === undefined || raw === null || raw === ''\n\t\t\tif (empty) {\n\t\t\t\treturn state.empty ? { label: this.tr(state.empty), variant: isBadgeVariant(state.emptyVariant) ? state.emptyVariant : 'default' } : null\n\t\t\t}\n\t\t\tconst label = state.map && Object.hasOwn(state.map, String(raw)) ? this.tr(state.map[String(raw)]) : String(raw)\n\t\t\tconst variant = state.variantMap && state.variantMap[String(raw)]\n\t\t\treturn { label, variant: isBadgeVariant(variant) ? variant : 'default' }\n\t\t},\n\n\t\t/**\n\t\t * The warning lines of an item.\n\t\t *\n\t\t * @param {object} item The item.\n\t\t * @return {string[]}\n\t\t */\n\t\twarningOf(item) {\n\t\t\tconst spec = this.spec.warning\n\t\t\tif (!spec || !spec.list) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\treturn this.listOf(item, spec.list)\n\t\t\t\t.map((entry) => {\n\t\t\t\t\tif (typeof entry === 'string') {\n\t\t\t\t\t\treturn entry\n\t\t\t\t\t}\n\t\t\t\t\tif (!entry || typeof entry !== 'object' || !spec.item) {\n\t\t\t\t\t\treturn ''\n\t\t\t\t\t}\n\t\t\t\t\treturn this.tr(spec.item).replace(/\\{([\\w.]+)\\}/g, (m, path) => String(readPath(entry, path) ?? ''))\n\t\t\t\t})\n\t\t\t\t.filter((line) => line !== '')\n\t\t},\n\n\t\t/**\n\t\t * Resolve the tokens in a url or payload.\n\t\t *\n\t\t * @param {unknown} value The value.\n\t\t * @param {object} vars `{ value, confirmed }`.\n\t\t * @return {unknown}\n\t\t */\n\t\tresolve(value, vars) {\n\t\t\tif (Array.isArray(value)) {\n\t\t\t\treturn value.map((v) => this.resolve(v, vars))\n\t\t\t}\n\t\t\tif (value && typeof value === 'object') {\n\t\t\t\treturn Object.fromEntries(Object.entries(value).map(([k, v]) => [k, this.resolve(v, vars)]))\n\t\t\t}\n\t\t\tif (typeof value !== 'string') {\n\t\t\t\treturn value\n\t\t\t}\n\t\t\tconst object = this.objectData || {}\n\t\t\tif (value === '@value') {\n\t\t\t\treturn vars.value\n\t\t\t}\n\t\t\tif (value === '@confirmed') {\n\t\t\t\treturn vars.confirmed\n\t\t\t}\n\t\t\tconst whole = value.match(/^@object\\.([\\w.@]+)$/)\n\t\t\tif (whole) {\n\t\t\t\treturn readPath(object, whole[1])\n\t\t\t}\n\t\t\treturn value\n\t\t\t\t.replace(/@objectId/g, () => encodeURIComponent(String(this.objectId || object.id || '')))\n\t\t\t\t.replace(/@object\\.([\\w.@]+)/g, (m, path) => encodeURIComponent(String(readPath(object, path) ?? '')))\n\t\t\t\t.replace(/@value/g, () => encodeURIComponent(String(vars.value)))\n\t\t},\n\n\t\t/** Read the cards of `source`. */\n\t\tasync loadSource() {\n\t\t\tif (!this.spec.url) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.loading = true\n\t\t\ttry {\n\t\t\t\tconst { default: axios } = await import('@nextcloud/axios')\n\t\t\t\tconst { data } = await axios.get(prefixUrl(String(this.resolve(this.spec.url, { value: '', confirmed: false }))))\n\t\t\t\tconst list = this.spec.path ? readPath(data, this.spec.path) : data\n\t\t\t\tthis.sourced = Array.isArray(list) ? list : []\n\t\t\t} catch (e) {\n\t\t\t\tthis.noticeType = 'error'\n\t\t\t\tthis.notice = serverErrorMessage(e)\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 * Choose a card (nothing is written until Save).\n\t\t *\n\t\t * @param {object} option The card.\n\t\t */\n\t\tchoose(option) {\n\t\t\tthis.chosen = option.key\n\t\t\tthis.notice = ''\n\t\t},\n\n\t\t/**\n\t\t * Save the chosen card: the configured request, else a PATCH of the field.\n\t\t *\n\t\t * @param {boolean} confirmed Whether the confirm action was pressed.\n\t\t * @return {Promise<void>}\n\t\t * @spec openspec/changes/abstract-choice-picker/specs/choice-picker/spec.md#requirement-a-risky-choice-is-saved-only-on-purpose\n\t\t */\n\t\tasync save(confirmed) {\n\t\t\tif (!this.selected) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst request = this.content.save\n\t\t\tif (!request && !this.objectUrl) {\n\t\t\t\tthis.noticeType = 'error'\n\t\t\t\tthis.notice = this.tr('This choice cannot be saved here.')\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.saving = true\n\t\t\tthis.notice = ''\n\t\t\ttry {\n\t\t\t\tconst { default: axios } = await import('@nextcloud/axios')\n\t\t\t\tconst vars = { value: this.selected.key, confirmed }\n\t\t\t\tif (request && request.url) {\n\t\t\t\t\tconst method = String(request.method || 'POST').toLowerCase()\n\t\t\t\t\tawait axios[method](prefixUrl(String(this.resolve(request.url, vars))), this.resolve(request.payload || {}, vars))\n\t\t\t\t} else {\n\t\t\t\t\tawait axios.patch(prefixUrl(this.objectUrl), { [this.content.field]: this.selected.key })\n\t\t\t\t}\n\t\t\t\tthis.saved = this.selected.key\n\t\t\t\tthis.noticeType = 'success'\n\t\t\t\tthis.notice = this.tr(this.content.savedText || 'Saved.')\n\t\t\t\t/**\n\t\t\t\t * @event saved The choice was written.\n\t\t\t\t * @type {{field: string, value: string, confirmed: boolean}}\n\t\t\t\t */\n\t\t\t\tthis.$emit('saved', { field: this.content.field, value: this.saved, confirmed })\n\t\t\t} catch (e) {\n\t\t\t\tthis.noticeType = 'error'\n\t\t\t\tthis.notice = serverErrorMessage(e)\n\t\t\t} finally {\n\t\t\t\tthis.saving = false\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-choice-picker {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 12px;\n\tmin-width: 0;\n}\n\n.cn-choice-picker__cards {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: 10px;\n\tmargin: 0;\n\tpadding: 0;\n\tborder: 0;\n}\n\n.cn-choice-picker__legend {\n\tposition: absolute;\n\twidth: 1px;\n\theight: 1px;\n\toverflow: hidden;\n\tclip-path: inset(50%);\n}\n\n.cn-choice-picker__card {\n\tposition: relative;\n\tdisplay: flex;\n\tflex: 1 1 220px;\n\talign-items: center;\n\tgap: 12px;\n\tpadding: 10px 12px;\n\tborder: 1px solid var(--cn-board-hairline, var(--color-border));\n\tborder-radius: 10px;\n\tbackground: var(--color-main-background);\n\tcursor: pointer;\n}\n\n.cn-choice-picker__card--selected {\n\tpadding: 9px 11px;\n\tborder: 2px solid var(--color-primary-element);\n}\n\n.cn-choice-picker__card--refused {\n\tcursor: not-allowed;\n\topacity: 0.7;\n}\n\n.cn-choice-picker__card:focus-within {\n\toutline: 2px solid var(--color-primary-element);\n\toutline-offset: 2px;\n}\n\n.cn-choice-picker__input {\n\tflex: 0 0 auto;\n\twidth: 18px;\n\theight: 18px;\n\tmargin: 0;\n\taccent-color: var(--color-primary-element);\n}\n\n.cn-choice-picker__swatches {\n\tdisplay: flex;\n\tgap: 4px;\n}\n\n.cn-choice-picker__swatch {\n\twidth: 18px;\n\theight: 18px;\n\tbox-sizing: border-box;\n\tborder: 1px solid var(--color-border);\n\tborder-radius: 4px;\n}\n\n.cn-choice-picker__text {\n\tdisplay: flex;\n\tflex: 1 1 auto;\n\tflex-direction: column;\n\tgap: 2px;\n\tmin-width: 0;\n}\n\n.cn-choice-picker__title {\n\tfont-size: 15px;\n}\n\n.cn-choice-picker__refusal,\n.cn-choice-picker__hint,\n.cn-choice-picker__note {\n\tmargin: 0;\n\tfont-size: 13px;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-choice-picker__warning-intro {\n\tmargin: 0 0 4px;\n}\n\n.cn-choice-picker__warning-list {\n\tmargin: 0;\n\tpadding-inline-start: 18px;\n}\n\n.cn-choice-picker__actions {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: 8px;\n}\n</style>\n"],"names":["_createElementBlock","_toDisplayString","_createElementVNode","_Fragment","_renderList","_openBlock","_createBlock"],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import __sfc_main from './CnChoicePickerWidget.vue.js';
|
|
2
|
+
import { registerDashboardWidget } from '../CnWidgetGrid/dashboardWidgetRegistry.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* SPDX-FileCopyrightText: 2026 Conduction B.V.
|
|
6
|
+
* SPDX-License-Identifier: EUPL-1.2
|
|
7
|
+
*
|
|
8
|
+
* CnChoicePickerWidget — self-registers the `choice-picker` widget type (choice
|
|
9
|
+
* cards with colour swatches and a state pill, and a confirm-with-warning save)
|
|
10
|
+
* into the shared dashboardWidgetRegistry at module load.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
registerDashboardWidget('choice-picker', {
|
|
15
|
+
renderer: __sfc_main,
|
|
16
|
+
form: null,
|
|
17
|
+
defaultContent: {
|
|
18
|
+
field: '',
|
|
19
|
+
items: [],
|
|
20
|
+
},
|
|
21
|
+
displayName: 'Choice picker',
|
|
22
|
+
icon: 'Palette',
|
|
23
|
+
surfaces: ['detail-page'],
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export { __sfc_main as CnChoicePickerWidget, __sfc_main as default };
|
|
27
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/components/CnChoicePickerWidget/index.js"],"sourcesContent":["/**\n * SPDX-FileCopyrightText: 2026 Conduction B.V.\n * SPDX-License-Identifier: EUPL-1.2\n *\n * CnChoicePickerWidget — self-registers the `choice-picker` widget type (choice\n * cards with colour swatches and a state pill, and a confirm-with-warning save)\n * into the shared dashboardWidgetRegistry at module load.\n */\n\nimport CnChoicePickerWidget from './CnChoicePickerWidget.vue'\nimport { registerDashboardWidget } from '../CnWidgetGrid/dashboardWidgetRegistry.js'\n\nregisterDashboardWidget('choice-picker', {\n\trenderer: CnChoicePickerWidget,\n\tform: null,\n\tdefaultContent: {\n\t\tfield: '',\n\t\titems: [],\n\t},\n\tdisplayName: 'Choice picker',\n\ticon: 'Palette',\n\tsurfaces: ['detail-page'],\n})\n\nexport { CnChoicePickerWidget }\nexport default CnChoicePickerWidget\n"],"names":["CnChoicePickerWidget"],"mappings":";;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA,uBAAuB,CAAC,eAAe,EAAE;AACzC,CAAC,QAAQ,EAAEA,UAAoB;AAC/B,CAAC,IAAI,EAAE,IAAI;AACX,CAAC,cAAc,EAAE;AACjB,EAAE,KAAK,EAAE,EAAE;AACX,EAAE,KAAK,EAAE,EAAE;AACX,EAAE;AACF,CAAC,WAAW,EAAE,eAAe;AAC7B,CAAC,IAAI,EAAE,SAAS;AAChB,CAAC,QAAQ,EAAE,CAAC,aAAa,CAAC;AAC1B,CAAC;;;;"}
|
|
@@ -8,7 +8,7 @@ import { readPath } from '../../utils/readPath.js';
|
|
|
8
8
|
* `content: { field, endpoint?, authorField?, timeField?, textField?, sideField?, usValue? }`.
|
|
9
9
|
* `@objectId` in `endpoint` is replaced by the record's id. A reply the
|
|
10
10
|
* endpoint accepts is shown at once, until the record is read again.
|
|
11
|
-
* Resolved by its registry key,
|
|
11
|
+
* Resolved by its registry key, and exported for an app that renders it itself.
|
|
12
12
|
*/
|
|
13
13
|
var script = {
|
|
14
14
|
name: 'CnConversationWidget',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CnConversationWidget.vue2.js","sources":["../../../../src/components/CnConversationThread/CnConversationWidget.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-case-widget-card\">\n\t\t<CnConversationThread\n\t\t\t:messages=\"messages\"\n\t\t\t:title=\"content.title || ''\"\n\t\t\t:allowReply=\"content.allowReply !== false\"\n\t\t\t:replyLabel=\"content.replyLabel || undefined\"\n\t\t\t:placeholder=\"content.placeholder || ''\"\n\t\t\t:sendLabel=\"content.sendLabel || undefined\"\n\t\t\t:endpoint=\"endpoint\"\n\t\t\t:emptyText=\"content.emptyText || undefined\"\n\t\t\t@sent=\"onSent\" />\n\t</div>\n</template>\n\n<script>\nimport CnConversationThread from './CnConversationThread.vue'\nimport { readPath } from '../../utils/readPath.js'\n\n/**\n * CnConversationWidget: the `conversation` detail widget type.\n *\n * Renders CnConversationThread from a list on the bound record:\n * `content: { field, endpoint?, authorField?, timeField?, textField?, sideField?, usValue? }`.\n * `@objectId` in `endpoint` is replaced by the record's id. A reply the\n * endpoint accepts is shown at once, until the record is read again.\n * Resolved by its registry key,
|
|
1
|
+
{"version":3,"file":"CnConversationWidget.vue2.js","sources":["../../../../src/components/CnConversationThread/CnConversationWidget.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-case-widget-card\">\n\t\t<CnConversationThread\n\t\t\t:messages=\"messages\"\n\t\t\t:title=\"content.title || ''\"\n\t\t\t:allowReply=\"content.allowReply !== false\"\n\t\t\t:replyLabel=\"content.replyLabel || undefined\"\n\t\t\t:placeholder=\"content.placeholder || ''\"\n\t\t\t:sendLabel=\"content.sendLabel || undefined\"\n\t\t\t:endpoint=\"endpoint\"\n\t\t\t:emptyText=\"content.emptyText || undefined\"\n\t\t\t@sent=\"onSent\" />\n\t</div>\n</template>\n\n<script>\nimport CnConversationThread from './CnConversationThread.vue'\nimport { readPath } from '../../utils/readPath.js'\n\n/**\n * CnConversationWidget: the `conversation` detail widget type.\n *\n * Renders CnConversationThread from a list on the bound record:\n * `content: { field, endpoint?, authorField?, timeField?, textField?, sideField?, usValue? }`.\n * `@objectId` in `endpoint` is replaced by the record's id. A reply the\n * endpoint accepts is shown at once, until the record is read again.\n * Resolved by its registry key, and exported for an app that renders it itself.\n */\nexport default {\n\tname: 'CnConversationWidget',\n\n\tcomponents: {\n\t\tCnConversationThread,\n\t},\n\n\tprops: {\n\t\t/** The widget's content. `field` is the dot-path to the messages on the record. */\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\n\t\t/** The bound record's id. */\n\t\tobjectId: {\n\t\t\ttype: [String, Number],\n\t\t\tdefault: '',\n\t\t},\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\t/** Replies sent from this widget that the record does not hold yet. */\n\t\t\tsentHere: [],\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The record's messages in the thread's shape, plus the replies sent here.\n\t\t *\n\t\t * @return {Array<object>} The messages.\n\t\t * @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-conversation-thread\n\t\t */\n\t\tmessages() {\n\t\t\tconst c = this.content\n\t\t\tconst value = readPath(this.objectData || {}, c.field || 'messages')\n\t\t\tconst usValue = String(c.usValue === undefined ? 'us' : c.usValue)\n\t\t\tconst stored = (Array.isArray(value) ? value : [])\n\t\t\t\t.filter((message) => message && typeof message === 'object')\n\t\t\t\t.map((message) => ({\n\t\t\t\t\tid: message.id,\n\t\t\t\t\tauthor: readPath(message, c.authorField || 'author'),\n\t\t\t\t\ttime: readPath(message, c.timeField || 'time'),\n\t\t\t\t\ttext: readPath(message, c.textField || 'text'),\n\t\t\t\t\tside: String(readPath(message, c.sideField || 'side')) === usValue ? 'us' : 'them',\n\t\t\t\t}))\n\t\t\treturn [...stored, ...this.sentHere]\n\t\t},\n\n\t\t/**\n\t\t * The endpoint with the record's id filled in.\n\t\t *\n\t\t * @return {string} The URL, or '' when the content names none.\n\t\t * @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-conversation-thread\n\t\t */\n\t\tendpoint() {\n\t\t\tconst url = this.content.endpoint\n\t\t\tif (typeof url !== 'string' || url === '') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn url.replace(/@objectId/g, encodeURIComponent(String(this.objectId ?? '')))\n\t\t},\n\t},\n\n\twatch: {\n\t\t// The record was read again, so it now holds what was sent from here.\n\t\tobjectData() {\n\t\t\tthis.sentHere = []\n\t\t},\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Show an accepted reply at once, without waiting for the record.\n\t\t *\n\t\t * @param {object} data The endpoint's response.\n\t\t * @return {void}\n\t\t * @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-conversation-thread\n\t\t */\n\t\tonSent(data) {\n\t\t\tconst text = data?.message ?? data?.text\n\t\t\tif (typeof text !== 'string' || text === '') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.sentHere.push({\n\t\t\t\tid: `sent-${this.sentHere.length}`,\n\t\t\t\ttime: new Date().toISOString(),\n\t\t\t\ttext,\n\t\t\t\tside: 'us',\n\t\t\t})\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-case-widget-card {\n\tbackground: var(--color-main-background);\n\tborder: 1px solid var(--color-border);\n\tborder-radius: var(--border-radius-large);\n\tpadding: calc(5 * var(--default-grid-baseline));\n}\n</style>\n"],"names":["CnConversationThread"],"mappings":";;;AAwBA;;AAEC;;AAEA;;;AAGA;;AAED,aAAe;CACd,IAAI,EAAE,sBAAsB;;CAE5B,UAAU,EAAE;AACX,wBAAAA,UAAoB;EACpB;;AAED,CAAA,KAAK,EAAE;AACN;AACA,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;;;AAGD,EAAA,QAAQ,EAAE;AACT,GAAA,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;GACtB,OAAO,EAAE,EAAE;GACX;EACD;;AAED,CAAA,IAAI,GAAG;AACN,EAAA,OAAO;;GAEN,QAAQ,EAAE,EAAE;AACb,GAAA;EACA;;AAED,CAAA,QAAQ,EAAE;AACT;;AAEC;AACA;;;EAGD,QAAQ,GAAG;AACV,GAAA,MAAM,CAAA,GAAI,IAAI,CAAC,QAAM;GACrB,MAAM,KAAI,GAAI,QAAQ,CAAC,IAAI,CAAC,UAAW,IAAG,EAAE,EAAE,CAAC,CAAC,KAAM,IAAG,UAAU,EAAA;GACnE,MAAM,OAAQ,GAAE,MAAM,CAAC,CAAC,CAAC,YAAY,SAAU,GAAE,IAAK,GAAE,CAAC,CAAC,OAAO,EAAA;AACjE,GAAA,MAAM,MAAO,GAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAE,GAAE,KAAM,GAAE,EAAE;KAC/C,MAAM,CAAC,CAAC,OAAO,KAAK,OAAM,IAAK,OAAO,OAAQ,KAAI,QAAQ,CAAA;AAC3D,KAAC,GAAG,CAAC,CAAC,OAAO,MAAM;KAClB,EAAE,EAAE,OAAO,CAAC,EAAE;KACd,MAAM,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,eAAe,QAAQ,CAAC;AACpD,KAAA,IAAI,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,SAAU,IAAG,MAAM,CAAC;AAC9C,KAAA,IAAI,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,SAAU,IAAG,MAAM,CAAC;AAC9C,KAAA,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,SAAQ,IAAK,MAAM,CAAC,CAAE,KAAI,OAAM,GAAI,IAAG,GAAI,MAAM;AACnF,KAAC,CAAC,EAAA;AACH,GAAA,OAAO,CAAC,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAA;GACnC;;AAED;AACC;AACA;;;;EAID,QAAQ,GAAG;GACV,MAAM,GAAE,GAAI,IAAI,CAAC,OAAO,CAAC,SAAO;AAChC,GAAA,IAAI,OAAO,GAAE,KAAM,QAAO,IAAK,GAAE,KAAM,EAAE,EAAE;AAC1C,IAAA,OAAO,EAAC;AACT,IAAA;AACA,GAAA,OAAO,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAA;GAChF;EACD;;AAED,CAAA,KAAK,EAAE;;EAEN,UAAU,GAAG;AACZ,GAAA,IAAI,CAAC,QAAO,GAAI,GAAC;GACjB;EACD;;AAED,CAAA,OAAO,EAAE;AACR;;AAEC;AACA;;;;EAID,MAAM,CAAC,IAAI,EAAE;AACZ,GAAA,MAAM,IAAK,GAAE,IAAI,EAAE,OAAM,IAAK,IAAI,EAAE,KAAG;AACvC,GAAA,IAAI,OAAO,IAAG,KAAM,QAAO,IAAK,SAAS,EAAE,EAAE;IAC5C,MAAK;AACN,IAAA;AACA,GAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;AAClB,IAAA,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAClC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;IAC9B,IAAI;AACJ,IAAA,IAAI,EAAE,IAAI;IACV,EAAA;GACD;EACD;AACF;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CnConversationWidget.vue3.js","sources":["../../../../src/components/CnConversationThread/CnConversationWidget.vue?vue&type=template&id=57081189&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-case-widget-card\">\n\t\t<CnConversationThread\n\t\t\t:messages=\"messages\"\n\t\t\t:title=\"content.title || ''\"\n\t\t\t:allowReply=\"content.allowReply !== false\"\n\t\t\t:replyLabel=\"content.replyLabel || undefined\"\n\t\t\t:placeholder=\"content.placeholder || ''\"\n\t\t\t:sendLabel=\"content.sendLabel || undefined\"\n\t\t\t:endpoint=\"endpoint\"\n\t\t\t:emptyText=\"content.emptyText || undefined\"\n\t\t\t@sent=\"onSent\" />\n\t</div>\n</template>\n\n<script>\nimport CnConversationThread from './CnConversationThread.vue'\nimport { readPath } from '../../utils/readPath.js'\n\n/**\n * CnConversationWidget: the `conversation` detail widget type.\n *\n * Renders CnConversationThread from a list on the bound record:\n * `content: { field, endpoint?, authorField?, timeField?, textField?, sideField?, usValue? }`.\n * `@objectId` in `endpoint` is replaced by the record's id. A reply the\n * endpoint accepts is shown at once, until the record is read again.\n * Resolved by its registry key,
|
|
1
|
+
{"version":3,"file":"CnConversationWidget.vue3.js","sources":["../../../../src/components/CnConversationThread/CnConversationWidget.vue?vue&type=template&id=57081189&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-case-widget-card\">\n\t\t<CnConversationThread\n\t\t\t:messages=\"messages\"\n\t\t\t:title=\"content.title || ''\"\n\t\t\t:allowReply=\"content.allowReply !== false\"\n\t\t\t:replyLabel=\"content.replyLabel || undefined\"\n\t\t\t:placeholder=\"content.placeholder || ''\"\n\t\t\t:sendLabel=\"content.sendLabel || undefined\"\n\t\t\t:endpoint=\"endpoint\"\n\t\t\t:emptyText=\"content.emptyText || undefined\"\n\t\t\t@sent=\"onSent\" />\n\t</div>\n</template>\n\n<script>\nimport CnConversationThread from './CnConversationThread.vue'\nimport { readPath } from '../../utils/readPath.js'\n\n/**\n * CnConversationWidget: the `conversation` detail widget type.\n *\n * Renders CnConversationThread from a list on the bound record:\n * `content: { field, endpoint?, authorField?, timeField?, textField?, sideField?, usValue? }`.\n * `@objectId` in `endpoint` is replaced by the record's id. A reply the\n * endpoint accepts is shown at once, until the record is read again.\n * Resolved by its registry key, and exported for an app that renders it itself.\n */\nexport default {\n\tname: 'CnConversationWidget',\n\n\tcomponents: {\n\t\tCnConversationThread,\n\t},\n\n\tprops: {\n\t\t/** The widget's content. `field` is the dot-path to the messages on the record. */\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\n\t\t/** The bound record's id. */\n\t\tobjectId: {\n\t\t\ttype: [String, Number],\n\t\t\tdefault: '',\n\t\t},\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\t/** Replies sent from this widget that the record does not hold yet. */\n\t\t\tsentHere: [],\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The record's messages in the thread's shape, plus the replies sent here.\n\t\t *\n\t\t * @return {Array<object>} The messages.\n\t\t * @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-conversation-thread\n\t\t */\n\t\tmessages() {\n\t\t\tconst c = this.content\n\t\t\tconst value = readPath(this.objectData || {}, c.field || 'messages')\n\t\t\tconst usValue = String(c.usValue === undefined ? 'us' : c.usValue)\n\t\t\tconst stored = (Array.isArray(value) ? value : [])\n\t\t\t\t.filter((message) => message && typeof message === 'object')\n\t\t\t\t.map((message) => ({\n\t\t\t\t\tid: message.id,\n\t\t\t\t\tauthor: readPath(message, c.authorField || 'author'),\n\t\t\t\t\ttime: readPath(message, c.timeField || 'time'),\n\t\t\t\t\ttext: readPath(message, c.textField || 'text'),\n\t\t\t\t\tside: String(readPath(message, c.sideField || 'side')) === usValue ? 'us' : 'them',\n\t\t\t\t}))\n\t\t\treturn [...stored, ...this.sentHere]\n\t\t},\n\n\t\t/**\n\t\t * The endpoint with the record's id filled in.\n\t\t *\n\t\t * @return {string} The URL, or '' when the content names none.\n\t\t * @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-conversation-thread\n\t\t */\n\t\tendpoint() {\n\t\t\tconst url = this.content.endpoint\n\t\t\tif (typeof url !== 'string' || url === '') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn url.replace(/@objectId/g, encodeURIComponent(String(this.objectId ?? '')))\n\t\t},\n\t},\n\n\twatch: {\n\t\t// The record was read again, so it now holds what was sent from here.\n\t\tobjectData() {\n\t\t\tthis.sentHere = []\n\t\t},\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Show an accepted reply at once, without waiting for the record.\n\t\t *\n\t\t * @param {object} data The endpoint's response.\n\t\t * @return {void}\n\t\t * @spec openspec/changes/detail-action-model-and-case-surfaces/specs/detail-action-model/spec.md#requirement-conversation-thread\n\t\t */\n\t\tonSent(data) {\n\t\t\tconst text = data?.message ?? data?.text\n\t\t\tif (typeof text !== 'string' || text === '') {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.sentHere.push({\n\t\t\t\tid: `sent-${this.sentHere.length}`,\n\t\t\t\ttime: new Date().toISOString(),\n\t\t\t\ttext,\n\t\t\t\tside: 'us',\n\t\t\t})\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-case-widget-card {\n\tbackground: var(--color-main-background);\n\tborder: 1px solid var(--color-border);\n\tborder-radius: var(--border-radius-large);\n\tpadding: calc(5 * var(--default-grid-baseline));\n}\n</style>\n"],"names":["_openBlock","_createElementBlock","_createVNode"],"mappings":";;AAWM,MAAA,UAAA,GAAA,EAAA,KAAK,EAAC,qBAAqB,GAAA;;;;;AAA9B,EAAA,QAAAA,SAAA,EAAA,EAAAC,kBAAA,QAAA;IACAC;AACC,MAAA,QAAQ,EAAE,QAAQ,CAAA,QAAA;MAClB,KAAK,EAAE,MAAO,CAAA,OAAA,CAAC,KAAG,IAAA,EAAA;MAClB,UAAU,EAAE,MAAO,CAAA,OAAA,CAAC,UAAU,KAAA,KAAA;AAC9B,MAAA,UAAU,EAAE,MAAA,CAAA,OAAG,CAAA,UAAA,IAAA,SAAA;MACf,WAAE,EAAA,MAAA,CAAA,OAAA,CAAA,WAAA,IAAA,EAAA;;;;;;;;;;;"}
|
|
@@ -354,14 +354,14 @@ var script = {
|
|
|
354
354
|
* anything whose height is whatever it turned out to have.
|
|
355
355
|
*
|
|
356
356
|
* @param {object} item the layout item.
|
|
357
|
-
* @return {string|undefined} `'true'`, a row
|
|
357
|
+
* @return {string|undefined} `'true'`, a row maximum as a string, or undefined.
|
|
358
358
|
*/
|
|
359
359
|
sizeToContentAttr(item) {
|
|
360
360
|
const v = item && item.sizeToContent;
|
|
361
361
|
if (v === true) {
|
|
362
362
|
return 'true'
|
|
363
363
|
}
|
|
364
|
-
// A number is GridStack's "size to content, but never
|
|
364
|
+
// A number is GridStack's "size to content, but never taller than N rows" (a maximum).
|
|
365
365
|
if (Number.isFinite(v) && v > 0) {
|
|
366
366
|
return String(v)
|
|
367
367
|
}
|