@conduction/nextcloud-vue 2.62.0 → 2.64.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/CnAdminActionCard/CnAdminActionCard.vue.js +10 -0
- package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue.js.map +1 -0
- package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue2.js +189 -0
- package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue2.js.map +1 -0
- package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue3.js +72 -0
- package/dist/esm/components/CnAdminActionCard/CnAdminActionCard.vue3.js.map +1 -0
- package/dist/esm/components/CnAppNav/CnAppNav.vue2.js +425 -39
- package/dist/esm/components/CnAppNav/CnAppNav.vue2.js.map +1 -1
- package/dist/esm/components/CnAppNav/CnAppNav.vue3.js +119 -42
- package/dist/esm/components/CnAppNav/CnAppNav.vue3.js.map +1 -1
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js +186 -9
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js.map +1 -1
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js +65 -42
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js.map +1 -1
- package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue2.js +61 -16
- package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue2.js.map +1 -1
- package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue3.js.map +1 -1
- package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue2.js +20 -0
- package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue3.js +3 -2
- package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js +33 -2
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js.map +1 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js.map +1 -1
- package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue2.js.map +1 -1
- package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue3.js +53 -37
- package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue3.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +29 -0
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +152 -135
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue.js +10 -0
- package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue.js.map +1 -0
- package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue2.js +293 -0
- package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue2.js.map +1 -0
- package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue3.js +189 -0
- package/dist/esm/components/CnDataTable/CnColumnFilterPopover.vue3.js.map +1 -0
- package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +253 -9
- package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +126 -50
- package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +66 -14
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js +23 -14
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js +2 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js.map +1 -1
- package/dist/esm/components/CnFieldHelper/CnFieldHelper.vue2.js +3 -1
- package/dist/esm/components/CnFieldHelper/CnFieldHelper.vue2.js.map +1 -1
- package/dist/esm/components/CnFieldHelper/CnFieldHelper.vue3.js +1 -1
- package/dist/esm/components/CnFieldHelper/CnFieldHelper.vue3.js.map +1 -1
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js +234 -9
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js.map +1 -1
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js +96 -57
- package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js.map +1 -1
- package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue2.js +81 -4
- package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue3.js +22 -5
- package/dist/esm/components/CnHeaderWidget/CnHeaderWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +81 -2
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +7 -3
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/selfModeActions.js +3 -3
- package/dist/esm/components/CnIndexPage/selfModeActions.js.map +1 -1
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js +41 -2
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js +8 -3
- package/dist/esm/components/CnObjectListWidget/CnObjectListWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnResourceSelect/CnResourceSelect.vue2.js +121 -12
- package/dist/esm/components/CnResourceSelect/CnResourceSelect.vue2.js.map +1 -1
- package/dist/esm/components/CnResourceSelect/CnResourceSelect.vue3.js +3 -1
- package/dist/esm/components/CnResourceSelect/CnResourceSelect.vue3.js.map +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js +326 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue2.js.map +1 -1
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js +112 -26
- package/dist/esm/components/CnSetupWizard/CnSetupWizard.vue3.js.map +1 -1
- package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue2.js +63 -2
- package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue3.js +96 -37
- package/dist/esm/components/CnStagesWidget/CnStagesWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnStagesWidget/stagesModel.js +5 -2
- package/dist/esm/components/CnStagesWidget/stagesModel.js.map +1 -1
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue2.js +52 -2
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js +6 -6
- package/dist/esm/components/CnStatWidget/CnStatWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +14 -2
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js +2 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue.js +10 -0
- package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue.js.map +1 -0
- package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue2.js +337 -0
- package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue2.js.map +1 -0
- package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue3.js +102 -0
- package/dist/esm/components/CnTimelineWidget/CnTimelineWidget.vue3.js.map +1 -0
- package/dist/esm/components/CnTimelineWidget/dashboardRegistration.js +34 -0
- package/dist/esm/components/CnTimelineWidget/dashboardRegistration.js.map +1 -0
- package/dist/esm/components/CnWalkthrough/CnWalkthrough.vue2.js +131 -8
- package/dist/esm/components/CnWalkthrough/CnWalkthrough.vue2.js.map +1 -1
- package/dist/esm/components/CnWalkthrough/CnWalkthrough.vue3.js +40 -38
- package/dist/esm/components/CnWalkthrough/CnWalkthrough.vue3.js.map +1 -1
- package/dist/esm/components/CnWidgetGrid/builtInWidgets.js +8 -6
- package/dist/esm/components/CnWidgetGrid/builtInWidgets.js.map +1 -1
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js +1 -0
- package/dist/esm/components/CnWidgetGrid/registerDashboardWidgets.js.map +1 -1
- package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue2.js +73 -1
- package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue2.js.map +1 -1
- package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue3.js +14 -2
- package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue3.js.map +1 -1
- package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue2.js +19 -0
- package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue2.js.map +1 -1
- package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue3.js +1 -1
- package/dist/esm/components/CnWizardDialog/CnWizardDialog.vue3.js.map +1 -1
- package/dist/esm/composables/useDependencyCheck.js +65 -0
- package/dist/esm/composables/useDependencyCheck.js.map +1 -0
- package/dist/esm/composables/useWalkthrough.js +218 -6
- package/dist/esm/composables/useWalkthrough.js.map +1 -1
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/l10n/en.json.js +45 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +45 -1
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/nextcloud-vue.css +780 -81
- package/dist/esm/store/useObjectStore.js +8 -0
- package/dist/esm/store/useObjectStore.js.map +1 -1
- package/dist/esm/utils/columnFilters.js +311 -0
- package/dist/esm/utils/columnFilters.js.map +1 -0
- package/dist/esm/utils/groupAutocomplete.js +123 -0
- package/dist/esm/utils/groupAutocomplete.js.map +1 -0
- package/dist/esm/utils/libraryWidgetKeys.js +2 -0
- package/dist/esm/utils/libraryWidgetKeys.js.map +1 -1
- package/dist/esm/utils/pickerOptions.js +198 -0
- package/dist/esm/utils/pickerOptions.js.map +1 -0
- package/dist/esm/utils/schema.js +83 -7
- package/dist/esm/utils/schema.js.map +1 -1
- package/dist/esm/utils/schemaRefSlug.js +19 -3
- package/dist/esm/utils/schemaRefSlug.js.map +1 -1
- package/dist/esm/utils/timelineEvents.js +174 -0
- package/dist/esm/utils/timelineEvents.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/esm/utils/walkthroughSignals.js +88 -0
- package/dist/esm/utils/walkthroughSignals.js.map +1 -0
- package/dist/nextcloud-vue.cjs.js +13088 -7937
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +780 -81
- package/l10n/en.json +45 -0
- package/l10n/nl.json +45 -0
- package/package.json +1 -1
- package/src/components/CnAdminActionCard/CnAdminActionCard.vue +234 -0
- package/src/components/CnAdminActionCard/index.js +4 -0
- package/src/components/CnAppNav/CnAppNav.vue +568 -43
- package/src/components/CnAppRoot/CnAppRoot.md +4 -0
- package/src/components/CnAppRoot/CnAppRoot.vue +223 -16
- package/src/components/CnAuditTrailCard/CnAuditTrailCard.vue +61 -16
- package/src/components/CnAuditTrailWidget/CnAuditTrailWidget.vue +22 -1
- package/src/components/CnCellRenderer/CnCellRenderer.vue +33 -2
- package/src/components/CnChoiceCards/CnChoiceCards.vue +56 -31
- package/src/components/CnDashboardPage/CnDashboardPage.vue +45 -4
- package/src/components/CnDataTable/CnColumnFilterPopover.vue +524 -0
- package/src/components/CnDataTable/CnDataTable.md +3 -0
- package/src/components/CnDataTable/CnDataTable.vue +305 -5
- package/src/components/CnDetailPage/CnDetailPage.md +4 -0
- package/src/components/CnDetailPage/CnDetailPage.vue +60 -1
- package/src/components/CnDetailWidgetHost/CnDetailWidgetHost.vue +2 -2
- package/src/components/CnFieldHelper/CnFieldHelper.vue +4 -2
- package/src/components/CnFormDialog/CnFormDialog.vue +290 -31
- package/src/components/CnHeaderWidget/CnHeaderWidget.vue +116 -6
- package/src/components/CnIndexPage/CnIndexPage.vue +87 -4
- package/src/components/CnIndexPage/selfModeActions.js +3 -3
- package/src/components/CnObjectListWidget/CnObjectListWidget.vue +46 -2
- package/src/components/CnResourceSelect/CnResourceSelect.vue +123 -12
- package/src/components/CnSetupWizard/CnSetupWizard.vue +392 -3
- package/src/components/CnStagesWidget/CnStagesWidget.vue +180 -2
- package/src/components/CnStagesWidget/stagesModel.js +5 -2
- package/src/components/CnStatWidget/CnStatWidget.vue +57 -3
- package/src/components/CnTabsWidget/CnTabsWidget.vue +15 -2
- package/src/components/CnTimelineWidget/CnTimelineWidget.vue +477 -0
- package/src/components/CnTimelineWidget/dashboardRegistration.js +32 -0
- package/src/components/CnTimelineWidget/index.js +4 -0
- package/src/components/CnWalkthrough/CnWalkthrough.vue +143 -10
- package/src/components/CnWidgetGrid/builtInWidgets.js +2 -0
- package/src/components/CnWidgetGrid/registerDashboardWidgets.js +1 -0
- package/src/components/CnWidgetWrapper/CnWidgetWrapper.md +4 -0
- package/src/components/CnWidgetWrapper/CnWidgetWrapper.vue +107 -1
- package/src/components/CnWizardDialog/CnWizardDialog.vue +20 -1
- package/src/components/index.js +2 -0
- package/src/composables/useDependencyCheck.js +61 -0
- package/src/composables/useWalkthrough.js +217 -5
- package/src/css/dashboard.css +49 -0
- package/src/css/detail-page.css +29 -4
- package/src/css/kpi-card.css +24 -1
- package/src/css/table.css +99 -6
- package/src/index.js +2 -0
- package/src/schemas/app-manifest-v2.schema.json +135 -3
- package/src/store/useObjectStore.js +8 -0
- package/src/utils/columnFilters.js +324 -0
- package/src/utils/groupAutocomplete.js +119 -0
- package/src/utils/libraryWidgetKeys.js +2 -0
- package/src/utils/pickerOptions.js +194 -0
- package/src/utils/schema.js +83 -7
- package/src/utils/schemaRefSlug.js +19 -3
- package/src/utils/timelineEvents.js +171 -0
- package/src/utils/validateManifestV2.compiled.js +2 -2
- package/src/utils/walkthroughSignals.js +94 -0
|
@@ -13,12 +13,12 @@
|
|
|
13
13
|
<slot
|
|
14
14
|
name="header"
|
|
15
15
|
:title="title"
|
|
16
|
-
:description="
|
|
16
|
+
:description="headerDescription"
|
|
17
17
|
:icon="resolvedIcon"
|
|
18
18
|
:showTitle="showTitle">
|
|
19
19
|
<CnPageHeader
|
|
20
20
|
:title="title"
|
|
21
|
-
:description="
|
|
21
|
+
:description="headerDescription"
|
|
22
22
|
:icon="resolvedIcon"
|
|
23
23
|
:visuallyHidden="!showTitle" />
|
|
24
24
|
</slot>
|
|
@@ -450,6 +450,10 @@
|
|
|
450
450
|
:includeColumns="includeColumns"
|
|
451
451
|
:columnOverrides="columnOverrides"
|
|
452
452
|
:rowClass="rowClass"
|
|
453
|
+
:filterable="headerFilters && !!effectiveSchema"
|
|
454
|
+
:activeFilters="effectiveActiveFilters"
|
|
455
|
+
:filterRegister="typeof register === 'string' ? register : ''"
|
|
456
|
+
@columnFilter="onColumnFilterEvent"
|
|
453
457
|
@sort="onSortEvent"
|
|
454
458
|
@select="onSelect"
|
|
455
459
|
@rowClick="onRowClick"
|
|
@@ -798,6 +802,7 @@ import { DEFAULT_ROW_INDICATOR_CAP } from '../../utils/rowIndicators.js'
|
|
|
798
802
|
import { buildRouteQueryFromViewState, buildViewCreatePayload, extractViewState, extractViewStateFromRouteQuery, savedViewScope, viewMatchesScope } from '../../utils/savedViewHelpers.js'
|
|
799
803
|
import { columnsFromSchema } from '../../utils/schema.js'
|
|
800
804
|
import { resolveScopeLayout } from '../../utils/scopeListLayout.js'
|
|
805
|
+
import { dispatchObjectCreated } from '../../utils/walkthroughSignals.js'
|
|
801
806
|
import { CnActionsBar } from '../CnActionsBar/index.js'
|
|
802
807
|
import { CnAdvancedFormDialog } from '../CnAdvancedFormDialog/index.js'
|
|
803
808
|
import { CnBoardView } from '../CnBoardView/index.js'
|
|
@@ -1172,6 +1177,21 @@ export default {
|
|
|
1172
1177
|
default: '',
|
|
1173
1178
|
},
|
|
1174
1179
|
|
|
1180
|
+
/**
|
|
1181
|
+
* A description that carries the collection's total: `{total}` in
|
|
1182
|
+
* the text is replaced by the current pagination total ("{total}
|
|
1183
|
+
* open cases" reads "48 open cases"). Rendered in place of
|
|
1184
|
+
* `description` once a total is known; before that, `description`
|
|
1185
|
+
* shows. Manifest key `config.countSubtitle`. Goes through the host
|
|
1186
|
+
* translate function.
|
|
1187
|
+
*
|
|
1188
|
+
* @spec openspec/changes/zuiddrecht-pixel-gaps/specs/zuiddrecht-pixel-gaps/spec.md#requirement-an-index-page-title-is-a-manifest-key
|
|
1189
|
+
*/
|
|
1190
|
+
countSubtitle: {
|
|
1191
|
+
type: String,
|
|
1192
|
+
default: '',
|
|
1193
|
+
},
|
|
1194
|
+
|
|
1175
1195
|
/**
|
|
1176
1196
|
* Whether to show the page header (icon, title, description) inline.
|
|
1177
1197
|
* When false (default), only the sidebar header shows the title
|
|
@@ -2285,6 +2305,22 @@ export default {
|
|
|
2285
2305
|
default: false,
|
|
2286
2306
|
},
|
|
2287
2307
|
|
|
2308
|
+
/**
|
|
2309
|
+
* Per-column filters in the table header: a filter button on every
|
|
2310
|
+
* column that can filter, opening a small panel that fits the column
|
|
2311
|
+
* (checkboxes, yes/no/any, from and to, a searchable reference list).
|
|
2312
|
+
* On by default; a column opts out with `filterable: false`, a page
|
|
2313
|
+
* with `pages[].config.headerFilters: false`. Filters write into the
|
|
2314
|
+
* same active-filter map as the facet sidebar, so they persist in the
|
|
2315
|
+
* route query and reach the same OpenRegister query parameters.
|
|
2316
|
+
*
|
|
2317
|
+
* @spec openspec/changes/table-header-sort-and-filter/specs/cn-data-table/spec.md#requirement-every-backed-column-filters-from-its-header
|
|
2318
|
+
*/
|
|
2319
|
+
headerFilters: {
|
|
2320
|
+
type: Boolean,
|
|
2321
|
+
default: true,
|
|
2322
|
+
},
|
|
2323
|
+
|
|
2288
2324
|
/**
|
|
2289
2325
|
* Show a filter menu (funnel button) in the table header, above the
|
|
2290
2326
|
* row-actions column. Its menu lists every enum/badge column's values as
|
|
@@ -4210,6 +4246,21 @@ export default {
|
|
|
4210
4246
|
return resolveDeepTokens(seed, {})
|
|
4211
4247
|
},
|
|
4212
4248
|
|
|
4249
|
+
/**
|
|
4250
|
+
* The header's description line: `countSubtitle` with the total
|
|
4251
|
+
* filled in when one is known, else `description`.
|
|
4252
|
+
*
|
|
4253
|
+
* @spec openspec/changes/zuiddrecht-pixel-gaps/specs/zuiddrecht-pixel-gaps/spec.md#requirement-an-index-page-title-is-a-manifest-key
|
|
4254
|
+
* @return {string}
|
|
4255
|
+
*/
|
|
4256
|
+
headerDescription() {
|
|
4257
|
+
const total = this.effectivePagination?.total
|
|
4258
|
+
if (this.countSubtitle && typeof total === 'number' && total >= 0) {
|
|
4259
|
+
return this.cnTranslate(this.countSubtitle).replace('{total}', String(total))
|
|
4260
|
+
}
|
|
4261
|
+
return this.description
|
|
4262
|
+
},
|
|
4263
|
+
|
|
4213
4264
|
/** Add button label — derived from schema.title if not explicitly set */
|
|
4214
4265
|
resolvedAddLabel() {
|
|
4215
4266
|
if (this.addLabel) {
|
|
@@ -5225,6 +5276,39 @@ export default {
|
|
|
5225
5276
|
this.$emit('filter-change', payload)
|
|
5226
5277
|
},
|
|
5227
5278
|
|
|
5279
|
+
/**
|
|
5280
|
+
* A header filter was applied or cleared. One column can own several
|
|
5281
|
+
* query parameters (a range is `key[gte]` and `key[lte]`), so they are
|
|
5282
|
+
* applied together: one fetch, one route update.
|
|
5283
|
+
*
|
|
5284
|
+
* @param {{key: string, params: object}} payload From CnDataTable's `column-filter`.
|
|
5285
|
+
* @return {void}
|
|
5286
|
+
* @spec openspec/changes/table-header-sort-and-filter/specs/cn-data-table/spec.md#requirement-a-header-filter-speaks-the-sidebars-query-language
|
|
5287
|
+
*/
|
|
5288
|
+
onColumnFilterEvent(payload) {
|
|
5289
|
+
const params = (payload && payload.params) || {}
|
|
5290
|
+
const entries = Object.entries(params).map(([key, values]) => [key, Array.isArray(values) ? values : []])
|
|
5291
|
+
if (this.isSelfFetchMode) {
|
|
5292
|
+
const next = { ...this.list.activeFilters.value }
|
|
5293
|
+
for (const [key, values] of entries) {
|
|
5294
|
+
if (values.length === 0) {
|
|
5295
|
+
delete next[key]
|
|
5296
|
+
} else {
|
|
5297
|
+
next[key] = values
|
|
5298
|
+
}
|
|
5299
|
+
}
|
|
5300
|
+
this.list.activeFilters.value = next
|
|
5301
|
+
this.list.refresh(1)
|
|
5302
|
+
this.persistViewStateToRoute(this.currentViewState())
|
|
5303
|
+
}
|
|
5304
|
+
for (const [key, values] of entries) {
|
|
5305
|
+
if (this.isNamedSource) {
|
|
5306
|
+
this.setNamedFilter(key, values)
|
|
5307
|
+
}
|
|
5308
|
+
this.$emit('filter-change', { key, values })
|
|
5309
|
+
}
|
|
5310
|
+
},
|
|
5311
|
+
|
|
5228
5312
|
/**
|
|
5229
5313
|
* Record one sidebar choice on a named-source page and mirror it into
|
|
5230
5314
|
* the URL.
|
|
@@ -6460,8 +6544,7 @@ export default {
|
|
|
6460
6544
|
if (typeof window === 'undefined' || !created) {
|
|
6461
6545
|
return
|
|
6462
6546
|
}
|
|
6463
|
-
|
|
6464
|
-
window.dispatchEvent(new CustomEvent('cn-walkthrough:object-created', { detail }))
|
|
6547
|
+
dispatchObjectCreated({ register: this.register, schema: this.exportSchemaSlug, object: created })
|
|
6465
6548
|
},
|
|
6466
6549
|
|
|
6467
6550
|
/**
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { dispatchObjectCreated } from '../../utils/walkthroughSignals.js'
|
|
1
2
|
import {
|
|
2
3
|
cloneObjectForCopy,
|
|
3
4
|
runSelfExportRequest,
|
|
@@ -196,9 +197,8 @@ export function createSelfModeActions(ctx) {
|
|
|
196
197
|
// @self.register/@self.schema are numeric DB ids, not slugs, so
|
|
197
198
|
// override with this page's own slug props (self-fetch mode
|
|
198
199
|
// guarantees ctx.schema() is already a string).
|
|
199
|
-
if (isCreate
|
|
200
|
-
|
|
201
|
-
window.dispatchEvent(new CustomEvent('cn-walkthrough:object-created', { detail }))
|
|
200
|
+
if (isCreate) {
|
|
201
|
+
dispatchObjectCreated({ register: ctx.register(), schema: ctx.schema(), object: saved })
|
|
202
202
|
}
|
|
203
203
|
refreshList(ctx)
|
|
204
204
|
if (isCreate && typeof ctx.afterCreateSuccess === 'function') {
|
|
@@ -151,6 +151,7 @@
|
|
|
151
151
|
:sortKey="localSort.field || null"
|
|
152
152
|
:sortOrder="localSort.dir || 'asc'"
|
|
153
153
|
borderless
|
|
154
|
+
:hideHeader="content.hideHeader === true"
|
|
154
155
|
@rowClick="onRowClick"
|
|
155
156
|
@rowAuxClick="onRowAuxClick"
|
|
156
157
|
@select="onSelect"
|
|
@@ -172,6 +173,7 @@
|
|
|
172
173
|
:sortKey="localSort.field || null"
|
|
173
174
|
:sortOrder="localSort.dir || 'asc'"
|
|
174
175
|
borderless
|
|
176
|
+
:hideHeader="content.hideHeader === true"
|
|
175
177
|
@rowClick="onRowClick"
|
|
176
178
|
@rowAuxClick="onRowAuxClick"
|
|
177
179
|
@select="onSelect"
|
|
@@ -268,6 +270,9 @@
|
|
|
268
270
|
ref="createDialog"
|
|
269
271
|
:schema="createSchema"
|
|
270
272
|
:item="null"
|
|
273
|
+
:register="content.register || ''"
|
|
274
|
+
:initialData="createInitialData"
|
|
275
|
+
:lockedFields="createLockedFields"
|
|
271
276
|
:size="formSize"
|
|
272
277
|
:columns="formColumns"
|
|
273
278
|
:includeFields="formIncludeFields"
|
|
@@ -293,6 +298,7 @@ import { followLinkClick, openRowTarget, resolveHref } from '../../utils/linkNav
|
|
|
293
298
|
import { objectFieldValue } from '../../utils/objectName.js'
|
|
294
299
|
import { dropOptionalUnresolved, hasUnresolvedTokens, resolveFilterTokens } from '../../utils/resolveFilterTokens.js'
|
|
295
300
|
import { markNewTabHandled } from '../../utils/rowAuxClick.js'
|
|
301
|
+
import { dispatchObjectCreated } from '../../utils/walkthroughSignals.js'
|
|
296
302
|
import { CnRowActions } from '../CnRowActions/index.js'
|
|
297
303
|
|
|
298
304
|
/**
|
|
@@ -415,7 +421,11 @@ export default {
|
|
|
415
421
|
* those carrying a selected value. Client-side over the fetched page,
|
|
416
422
|
* like the rest of this widget's row set.
|
|
417
423
|
*
|
|
418
|
-
*
|
|
424
|
+
* `hideHeader: true` drops the table's column header row (CnDataTable's
|
|
425
|
+
* `hideHeader`), for a short list that reads as rows, not as a table.
|
|
426
|
+
*
|
|
427
|
+
* @spec openspec/changes/zuiddrecht-pixel-gaps/specs/zuiddrecht-pixel-gaps/spec.md#requirement-small-opt-ins-from-the-decidiq-and-learniq-lanes
|
|
428
|
+
* @type {{register?: string, schema?: string, filter?: object, sort?: {field?: string, dir?: string}, limit?: number, extend?: Array<string>, columns?: Array, rowActions?: Array<object>, dropZone?: object, upload?: boolean, groupBy?: string, groupLabel?: string, groupLabelResolve?: {register: string, schema: string, labelField?: string}, selectable?: boolean, bulkActions?: Array<object>, sortable?: boolean, facet?: {field: string, label?: string}, rowRoute?: string, prompt?: string, emptyText?: string, viewAllRoute?: string, viewAllQuery?: object, hideHeader?: boolean}}
|
|
419
429
|
*/
|
|
420
430
|
content: {
|
|
421
431
|
type: Object,
|
|
@@ -1010,6 +1020,39 @@ export default {
|
|
|
1010
1020
|
return Array.isArray(c.formExcludeFields) ? c.formExcludeFields : []
|
|
1011
1021
|
},
|
|
1012
1022
|
|
|
1023
|
+
/**
|
|
1024
|
+
* Create-form seed values: the list's scalar filter values (the parent
|
|
1025
|
+
* this list is scoped to, e.g. `{ lead: '<uuid>' }`), limited to keys
|
|
1026
|
+
* the schema declares, so the new row shows its parent already chosen.
|
|
1027
|
+
*
|
|
1028
|
+
* @spec openspec/changes/form-pickers-from-schema/specs/schema-utilities/spec.md
|
|
1029
|
+
* @return {object}
|
|
1030
|
+
*/
|
|
1031
|
+
createInitialData() {
|
|
1032
|
+
const props = (this.createSchema && this.createSchema.properties) || {}
|
|
1033
|
+
const out = {}
|
|
1034
|
+
for (const [key, value] of Object.entries(this.resolvedFilter || {})) {
|
|
1035
|
+
if (!(key in props) || value === null || value === undefined || value === '' || typeof value === 'object') {
|
|
1036
|
+
continue
|
|
1037
|
+
}
|
|
1038
|
+
if (typeof value === 'string' && value.charAt(0) === '@') {
|
|
1039
|
+
continue
|
|
1040
|
+
}
|
|
1041
|
+
out[key] = value
|
|
1042
|
+
}
|
|
1043
|
+
return out
|
|
1044
|
+
},
|
|
1045
|
+
|
|
1046
|
+
/**
|
|
1047
|
+
* The seeded parent keys are locked: a row added to this list belongs
|
|
1048
|
+
* to the record the list is scoped to.
|
|
1049
|
+
*
|
|
1050
|
+
* @return {string[]}
|
|
1051
|
+
*/
|
|
1052
|
+
createLockedFields() {
|
|
1053
|
+
return Object.keys(this.createInitialData)
|
|
1054
|
+
},
|
|
1055
|
+
|
|
1013
1056
|
/** Per-field overrides for the create dialog (`content.formFieldOverrides`). */
|
|
1014
1057
|
formFieldOverrides() {
|
|
1015
1058
|
const c = this.content || {}
|
|
@@ -1358,7 +1401,8 @@ export default {
|
|
|
1358
1401
|
}
|
|
1359
1402
|
}
|
|
1360
1403
|
const url = generateUrl('/apps/openregister/api/objects/{register}/{schema}', { register: c.register, schema: c.schema })
|
|
1361
|
-
await axios.post(url, payload)
|
|
1404
|
+
const response = await axios.post(url, payload)
|
|
1405
|
+
dispatchObjectCreated({ register: c.register, schema: c.schema, object: (response && response.data) || payload })
|
|
1362
1406
|
if (this.$refs.createDialog) {
|
|
1363
1407
|
this.$refs.createDialog.setResult({ success: true })
|
|
1364
1408
|
}
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
:disabled="disabled"
|
|
14
14
|
:placeholder="placeholder"
|
|
15
15
|
:filterable="false"
|
|
16
|
+
:multiple="multiple"
|
|
17
|
+
:keepOpen="multiple"
|
|
16
18
|
label="label"
|
|
17
19
|
@search="onSearch"
|
|
18
20
|
@update:modelValue="onInput">
|
|
@@ -93,12 +95,21 @@ export default {
|
|
|
93
95
|
required: true,
|
|
94
96
|
},
|
|
95
97
|
|
|
96
|
-
/** Currently-selected object id (v-model)
|
|
98
|
+
/** Currently-selected object id (v-model), or an array of ids when `multiple`. */
|
|
97
99
|
modelValue: {
|
|
98
|
-
type: [String, Number],
|
|
100
|
+
type: [String, Number, Array],
|
|
99
101
|
default: '',
|
|
100
102
|
},
|
|
101
103
|
|
|
104
|
+
/**
|
|
105
|
+
* Pick several objects. `modelValue` is then an array of ids, and a
|
|
106
|
+
* create adds the new object to the selection.
|
|
107
|
+
*/
|
|
108
|
+
multiple: {
|
|
109
|
+
type: Boolean,
|
|
110
|
+
default: false,
|
|
111
|
+
},
|
|
112
|
+
|
|
102
113
|
/** Object field used as the option label AND written on create. */
|
|
103
114
|
labelField: {
|
|
104
115
|
type: String,
|
|
@@ -219,6 +230,9 @@ export default {
|
|
|
219
230
|
// The selected option object kept locally so the label shows even
|
|
220
231
|
// before/without a matching search result (e.g. a pre-set modelValue).
|
|
221
232
|
localSelected: null,
|
|
233
|
+
// Options seen so far, keyed by value, so a multiple selection
|
|
234
|
+
// keeps its labels when the search results move on.
|
|
235
|
+
known: {},
|
|
222
236
|
}
|
|
223
237
|
},
|
|
224
238
|
|
|
@@ -232,6 +246,19 @@ export default {
|
|
|
232
246
|
}
|
|
233
247
|
},
|
|
234
248
|
|
|
249
|
+
/**
|
|
250
|
+
* The selected ids as strings (multiple mode).
|
|
251
|
+
*
|
|
252
|
+
* @return {string[]}
|
|
253
|
+
*/
|
|
254
|
+
selectedIds() {
|
|
255
|
+
const value = this.modelValue
|
|
256
|
+
if (Array.isArray(value)) {
|
|
257
|
+
return value.filter((v) => v !== null && v !== undefined && v !== '').map((v) => String(v))
|
|
258
|
+
}
|
|
259
|
+
return value ? [String(value)] : []
|
|
260
|
+
},
|
|
261
|
+
|
|
235
262
|
/** The `${register}-${schema}` object-type slug used by the store. */
|
|
236
263
|
typeSlug() {
|
|
237
264
|
return `${this.register}-${this.schema}`
|
|
@@ -239,6 +266,11 @@ export default {
|
|
|
239
266
|
|
|
240
267
|
/** The currently-selected option, for NcSelect's model-value. */
|
|
241
268
|
selectedOption() {
|
|
269
|
+
if (this.multiple) {
|
|
270
|
+
return this.selectedIds.map((id) => this.known[id]
|
|
271
|
+
|| this.options.find((o) => o.value === id)
|
|
272
|
+
|| { value: id, label: id })
|
|
273
|
+
}
|
|
242
274
|
if (this.localSelected && this.localSelected.value === this.modelValue) {
|
|
243
275
|
return this.localSelected
|
|
244
276
|
}
|
|
@@ -310,9 +342,9 @@ export default {
|
|
|
310
342
|
// The scope moved, so anything already selected may no longer be
|
|
311
343
|
// in it. Drop the stale options + selection, then re-seed.
|
|
312
344
|
this.options = []
|
|
313
|
-
if (this.
|
|
345
|
+
if (this.selectedIds.length > 0) {
|
|
314
346
|
this.localSelected = null
|
|
315
|
-
this.$emit('update:modelValue', '')
|
|
347
|
+
this.$emit('update:modelValue', this.multiple ? [] : '')
|
|
316
348
|
}
|
|
317
349
|
if (this.search.trim().length >= this.minChars) {
|
|
318
350
|
this.onSearch(this.search)
|
|
@@ -347,7 +379,7 @@ export default {
|
|
|
347
379
|
const items = Array.isArray(collection)
|
|
348
380
|
? collection
|
|
349
381
|
: (this.objectStore.collections[this.typeSlug] || [])
|
|
350
|
-
this.options = items.map((o) => this.toOption(o))
|
|
382
|
+
this.options = this.remember(items.map((o) => this.toOption(o)))
|
|
351
383
|
} catch {
|
|
352
384
|
this.options = []
|
|
353
385
|
} finally {
|
|
@@ -392,7 +424,7 @@ export default {
|
|
|
392
424
|
const items = Array.isArray(collection)
|
|
393
425
|
? collection
|
|
394
426
|
: (this.objectStore.collections[this.typeSlug] || [])
|
|
395
|
-
this.options = items.map((o) => this.toOption(o))
|
|
427
|
+
this.options = this.remember(items.map((o) => this.toOption(o)))
|
|
396
428
|
} catch {
|
|
397
429
|
this.options = []
|
|
398
430
|
} finally {
|
|
@@ -408,6 +440,10 @@ export default {
|
|
|
408
440
|
* @return {Promise<void>}
|
|
409
441
|
*/
|
|
410
442
|
async onInput(option) {
|
|
443
|
+
if (this.multiple) {
|
|
444
|
+
await this.onMultipleInput(Array.isArray(option) ? option : (option ? [option] : []))
|
|
445
|
+
return
|
|
446
|
+
}
|
|
411
447
|
if (!option) {
|
|
412
448
|
this.localSelected = null
|
|
413
449
|
/**
|
|
@@ -425,19 +461,58 @@ export default {
|
|
|
425
461
|
this.$emit('update:modelValue', option.value)
|
|
426
462
|
},
|
|
427
463
|
|
|
464
|
+
/**
|
|
465
|
+
* Handle a change of a multiple selection. A synthetic create option
|
|
466
|
+
* creates the object and adds it; the rest emit their ids.
|
|
467
|
+
*
|
|
468
|
+
* @param {Array<object>} chosen The selected options.
|
|
469
|
+
* @return {Promise<void>}
|
|
470
|
+
*/
|
|
471
|
+
async onMultipleInput(chosen) {
|
|
472
|
+
const createOption = chosen.find((o) => o && o.__create)
|
|
473
|
+
const ids = chosen.filter((o) => o && !o.__create).map((o) => String(o.value))
|
|
474
|
+
this.remember(chosen.filter((o) => o && !o.__create))
|
|
475
|
+
if (!createOption) {
|
|
476
|
+
this.$emit('update:modelValue', ids)
|
|
477
|
+
return
|
|
478
|
+
}
|
|
479
|
+
const created = await this.createFromTerm(createOption.label, ids)
|
|
480
|
+
if (!created) {
|
|
481
|
+
this.$emit('update:modelValue', ids)
|
|
482
|
+
}
|
|
483
|
+
},
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Cache options by value so their labels survive a new search.
|
|
487
|
+
*
|
|
488
|
+
* @param {Array<object>} options Options to remember.
|
|
489
|
+
* @return {Array<object>} The same options.
|
|
490
|
+
*/
|
|
491
|
+
remember(options) {
|
|
492
|
+
const next = { ...this.known }
|
|
493
|
+
for (const o of options) {
|
|
494
|
+
if (o && o.value) {
|
|
495
|
+
next[o.value] = o
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
this.known = next
|
|
499
|
+
return options
|
|
500
|
+
},
|
|
501
|
+
|
|
428
502
|
/**
|
|
429
503
|
* Create a new object from the typed term and select it.
|
|
430
504
|
*
|
|
431
505
|
* @param {string} term The term to write to `labelField`.
|
|
432
|
-
* @
|
|
506
|
+
* @param {string[]} [keep] Multiple mode: the ids already selected, which the new id joins.
|
|
507
|
+
* @return {Promise<object|null>} The created object, or null.
|
|
433
508
|
*/
|
|
434
|
-
async createFromTerm(term) {
|
|
509
|
+
async createFromTerm(term, keep = []) {
|
|
435
510
|
if (!this.objectStore && !this.createHandler) {
|
|
436
|
-
return
|
|
511
|
+
return null
|
|
437
512
|
}
|
|
438
513
|
const name = (term || '').trim()
|
|
439
514
|
if (!name) {
|
|
440
|
-
return
|
|
515
|
+
return null
|
|
441
516
|
}
|
|
442
517
|
this.loading = true
|
|
443
518
|
try {
|
|
@@ -456,20 +531,26 @@ export default {
|
|
|
456
531
|
created = await this.objectStore.saveObject(this.typeSlug, payload)
|
|
457
532
|
}
|
|
458
533
|
if (!created) {
|
|
459
|
-
return
|
|
534
|
+
return null
|
|
460
535
|
}
|
|
461
536
|
const option = this.toOption(created)
|
|
537
|
+
this.remember([option])
|
|
462
538
|
this.options = [option, ...this.options.filter((o) => o.value !== option.value)]
|
|
463
539
|
this.localSelected = option
|
|
464
|
-
this
|
|
540
|
+
this.search = ''
|
|
541
|
+
this.$emit('update:modelValue', this.multiple
|
|
542
|
+
? [...keep.filter((id) => id !== option.value), option.value]
|
|
543
|
+
: option.value)
|
|
465
544
|
/**
|
|
466
545
|
* @event create A new object was created from the search term.
|
|
467
546
|
* @type {object} The created OpenRegister object.
|
|
468
547
|
*/
|
|
469
548
|
this.$emit('create', created)
|
|
549
|
+
return created
|
|
470
550
|
} catch (e) {
|
|
471
551
|
// eslint-disable-next-line no-console
|
|
472
552
|
console.warn('[CnResourceSelect] create failed', e)
|
|
553
|
+
return null
|
|
473
554
|
} finally {
|
|
474
555
|
this.loading = false
|
|
475
556
|
}
|
|
@@ -508,6 +589,10 @@ export default {
|
|
|
508
589
|
* @return {Promise<void>}
|
|
509
590
|
*/
|
|
510
591
|
async ensureSelectedLoaded() {
|
|
592
|
+
if (this.multiple) {
|
|
593
|
+
await this.ensureManyLoaded()
|
|
594
|
+
return
|
|
595
|
+
}
|
|
511
596
|
if (!this.modelValue || this.selectedOption || !this.objectStore) {
|
|
512
597
|
return
|
|
513
598
|
}
|
|
@@ -524,6 +609,32 @@ export default {
|
|
|
524
609
|
// Leave the id un-labelled rather than crash.
|
|
525
610
|
}
|
|
526
611
|
},
|
|
612
|
+
|
|
613
|
+
/**
|
|
614
|
+
* Multiple mode: fetch each selected id whose label is not known yet.
|
|
615
|
+
*
|
|
616
|
+
* @return {Promise<void>}
|
|
617
|
+
*/
|
|
618
|
+
async ensureManyLoaded() {
|
|
619
|
+
if (!this.objectStore || typeof this.objectStore.fetchObject !== 'function') {
|
|
620
|
+
return
|
|
621
|
+
}
|
|
622
|
+
const missing = this.selectedIds.filter((id) => !this.known[id] && !this.options.some((o) => o.value === id))
|
|
623
|
+
if (missing.length === 0) {
|
|
624
|
+
return
|
|
625
|
+
}
|
|
626
|
+
this.ensureRegistered()
|
|
627
|
+
for (const id of missing) {
|
|
628
|
+
try {
|
|
629
|
+
const obj = await this.objectStore.fetchObject(this.typeSlug, id)
|
|
630
|
+
if (obj) {
|
|
631
|
+
this.remember([this.toOption(obj)])
|
|
632
|
+
}
|
|
633
|
+
} catch {
|
|
634
|
+
// Leave the id un-labelled rather than crash.
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
},
|
|
527
638
|
},
|
|
528
639
|
}
|
|
529
640
|
</script>
|