@conduction/nextcloud-vue 2.106.0 → 2.107.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/CnActionDialog/CnActionDialog.vue.js +9 -0
- package/dist/esm/components/CnActionDialog/CnActionDialog.vue.js.map +1 -0
- package/dist/esm/components/CnActionDialog/CnActionDialog.vue2.js +338 -0
- package/dist/esm/components/CnActionDialog/CnActionDialog.vue2.js.map +1 -0
- package/dist/esm/components/CnActionDialog/CnActionDialog.vue3.js +249 -0
- package/dist/esm/components/CnActionDialog/CnActionDialog.vue3.js.map +1 -0
- package/dist/esm/components/CnAdvancedFormDialog/CnPropertiesTab.vue2.js +2 -2
- package/dist/esm/components/CnAdvancedFormDialog/CnPropertiesTab.vue2.js.map +1 -1
- package/dist/esm/components/CnAppNav/CnAppNav.vue2.js.map +1 -1
- package/dist/esm/components/CnAppNav/CnAppNav.vue3.js +145 -138
- package/dist/esm/components/CnAppNav/CnAppNav.vue3.js.map +1 -1
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js +102 -2
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js.map +1 -1
- package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue.js +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +83 -6
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +4 -2
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
- package/dist/esm/components/CnIcon/semanticIcons.js +2 -2
- package/dist/esm/components/CnIcon/semanticIcons.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +389 -20
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +68 -35
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/useSelfFetchList.js +22 -2
- package/dist/esm/components/CnIndexPage/useSelfFetchList.js.map +1 -1
- package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue2.js +69 -5
- package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue3.js +38 -5
- package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue3.js.map +1 -1
- package/dist/esm/components/CnMapWidget/CnMapWidget.vue.js +1 -1
- package/dist/esm/components/CnMapWidget/CnMapWidget.vue2.js +7 -1
- package/dist/esm/components/CnMapWidget/CnMapWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnMapWidget/CnMapWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnPartyPicker/CnPartyPicker.vue.js +8 -0
- package/dist/esm/components/CnPartyPicker/CnPartyPicker.vue.js.map +1 -0
- package/dist/esm/components/CnPartyPicker/CnPartyPicker.vue2.js +297 -0
- package/dist/esm/components/CnPartyPicker/CnPartyPicker.vue2.js.map +1 -0
- package/dist/esm/components/CnPartyPicker/CnPartyPicker.vue3.js +24 -0
- package/dist/esm/components/CnPartyPicker/CnPartyPicker.vue3.js.map +1 -0
- package/dist/esm/components/CnSavedViewEditDialog/CnSavedViewEditDialog.vue.js +9 -0
- package/dist/esm/components/CnSavedViewEditDialog/CnSavedViewEditDialog.vue.js.map +1 -0
- package/dist/esm/components/CnSavedViewEditDialog/CnSavedViewEditDialog.vue2.js +95 -0
- package/dist/esm/components/CnSavedViewEditDialog/CnSavedViewEditDialog.vue2.js.map +1 -0
- package/dist/esm/components/CnSavedViewEditDialog/CnSavedViewEditDialog.vue3.js +123 -0
- package/dist/esm/components/CnSavedViewEditDialog/CnSavedViewEditDialog.vue3.js.map +1 -0
- package/dist/esm/components/CnSavedViewShareDialog/CnSavedViewShareDialog.vue.js +1 -1
- package/dist/esm/components/CnSavedViewShareDialog/CnSavedViewShareDialog.vue2.js +13 -5
- package/dist/esm/components/CnSavedViewShareDialog/CnSavedViewShareDialog.vue2.js.map +1 -1
- package/dist/esm/components/CnSavedViewShareDialog/CnSavedViewShareDialog.vue3.js +3 -1
- package/dist/esm/components/CnSavedViewShareDialog/CnSavedViewShareDialog.vue3.js.map +1 -1
- package/dist/esm/components/CnSavedViewShareFields/CnSavedViewShareFields.vue.js +1 -1
- package/dist/esm/components/CnSavedViewShareFields/CnSavedViewShareFields.vue2.js +49 -23
- package/dist/esm/components/CnSavedViewShareFields/CnSavedViewShareFields.vue2.js.map +1 -1
- package/dist/esm/components/CnSavedViewShareFields/CnSavedViewShareFields.vue3.js +74 -27
- package/dist/esm/components/CnSavedViewShareFields/CnSavedViewShareFields.vue3.js.map +1 -1
- package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue.js +0 -1
- package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue.js.map +1 -1
- package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue2.js +18 -413
- package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue2.js.map +1 -1
- package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue3.js +27 -214
- package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue3.js.map +1 -1
- package/dist/esm/components/CnSavedViewsPanel/CnSavedViewsPanel.vue.js +9 -0
- package/dist/esm/components/CnSavedViewsPanel/CnSavedViewsPanel.vue.js.map +1 -0
- package/dist/esm/components/CnSavedViewsPanel/CnSavedViewsPanel.vue2.js +190 -0
- package/dist/esm/components/CnSavedViewsPanel/CnSavedViewsPanel.vue2.js.map +1 -0
- package/dist/esm/components/CnSavedViewsPanel/CnSavedViewsPanel.vue3.js +270 -0
- package/dist/esm/components/CnSavedViewsPanel/CnSavedViewsPanel.vue3.js.map +1 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/l10n/en.json.js +56 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +56 -1
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/library-style.js +1 -1
- package/dist/esm/mixins/savedViewsList.js +235 -0
- package/dist/esm/mixins/savedViewsList.js.map +1 -0
- package/dist/esm/nextcloud-vue.css +348 -108
- package/dist/esm/utils/actionsDispatcher.js +2 -2
- package/dist/esm/utils/actionsDispatcher.js.map +1 -1
- package/dist/esm/utils/builtInModals.js +39 -0
- package/dist/esm/utils/builtInModals.js.map +1 -0
- package/dist/esm/utils/mapMarkerColor.js +121 -0
- package/dist/esm/utils/mapMarkerColor.js.map +1 -0
- package/dist/esm/utils/mergeManifestDelta.js +4 -0
- package/dist/esm/utils/mergeManifestDelta.js.map +1 -1
- package/dist/esm/utils/savedViewHelpers.js +59 -7
- package/dist/esm/utils/savedViewHelpers.js.map +1 -1
- package/dist/esm/utils/savedViewMenu.js +154 -0
- package/dist/esm/utils/savedViewMenu.js.map +1 -0
- package/dist/esm/utils/searchGroupSharees.js +50 -15
- package/dist/esm/utils/searchGroupSharees.js.map +1 -1
- package/dist/esm/utils/validateManifestV2.compiled.js +3 -3
- package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +13351 -10855
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +348 -108
- package/l10n/en.json +56 -1
- package/l10n/nl.json +56 -1
- package/package.json +1 -1
- package/src/components/CnActionDialog/CnActionDialog.vue +545 -0
- package/src/components/CnActionDialog/index.js +12 -0
- package/src/components/CnAppNav/CnAppNav.vue +17 -0
- package/src/components/CnAppRoot/CnAppRoot.vue +102 -2
- package/src/components/CnDashboardPage/CnDashboardPage.vue +86 -7
- package/src/components/CnIndexPage/CnIndexPage.vue +409 -23
- package/src/components/CnIndexPage/useSelfFetchList.js +21 -1
- package/src/components/CnIndexSidebar/CnIndexSidebar.md +2 -0
- package/src/components/CnIndexSidebar/CnIndexSidebar.vue +91 -1
- package/src/components/CnMapWidget/CnMapWidget.vue +16 -1
- package/src/components/CnPartyPicker/CnPartyPicker.vue +317 -0
- package/src/components/CnPartyPicker/index.js +11 -0
- package/src/components/CnSavedViewEditDialog/CnSavedViewEditDialog.vue +192 -0
- package/src/components/CnSavedViewEditDialog/index.js +11 -0
- package/src/components/CnSavedViewShareDialog/CnSavedViewShareDialog.vue +21 -6
- package/src/components/CnSavedViewShareFields/CnSavedViewShareFields.vue +130 -37
- package/src/components/CnSavedViewsControl/CnSavedViewsControl.vue +36 -599
- package/src/components/CnSavedViewsPanel/CnSavedViewsPanel.vue +459 -0
- package/src/components/CnSavedViewsPanel/index.js +11 -0
- package/src/components/index.js +4 -0
- package/src/css/index-page.css +16 -0
- package/src/css/look-board-index.css +5 -3
- package/src/css/look-board.css +18 -3
- package/src/index.js +4 -0
- package/src/mixins/savedViewsList.js +231 -0
- package/src/schemas/app-manifest-v2.schema.json +98 -3
- package/src/utils/actionsDispatcher.js +2 -2
- package/src/utils/builtInModals.js +35 -0
- package/src/utils/mapMarkerColor.js +117 -0
- package/src/utils/mergeManifestDelta.js +4 -0
- package/src/utils/savedViewHelpers.js +58 -6
- package/src/utils/savedViewMenu.js +150 -0
- package/src/utils/searchGroupSharees.js +49 -14
- package/src/utils/validateManifestV2.compiled.js +3 -3
|
@@ -14,8 +14,8 @@ import ImportIcon from 'vue-material-design-icons/Import.vue';
|
|
|
14
14
|
import TrashCanOutline from 'vue-material-design-icons/TrashCanOutline.vue';
|
|
15
15
|
import Tune from 'vue-material-design-icons/Tune.vue';
|
|
16
16
|
import ViewColumnOutline from 'vue-material-design-icons/ViewColumnOutline.vue';
|
|
17
|
-
import __sfc_main$
|
|
18
|
-
import __sfc_main$
|
|
17
|
+
import __sfc_main$z from '../../dialogs/CnConfirmDialog.vue.js';
|
|
18
|
+
import __sfc_main$A from '../../dialogs/CnQuickEditDialog.vue.js';
|
|
19
19
|
import __sfc_main$2 from '../CnBuildiqEditButton/CnBuildiqEditButton.vue.js';
|
|
20
20
|
import __sfc_main$4 from '../CnEmptyContent/CnEmptyContent.vue.js';
|
|
21
21
|
import __sfc_main$3 from '../CnFollowToggle/CnFollowToggle.vue.js';
|
|
@@ -41,12 +41,13 @@ import { isModifiedClick, openRowTarget } from '../../utils/linkNavigation.js';
|
|
|
41
41
|
import { resolveClaimedTeams, splitViewsIntoTabs, viewAsTab, resolveClaimTokens, viewIdOf } from '../../utils/listLenses.js';
|
|
42
42
|
import { LIST_SHORTCUTS, listPaletteCommands, shortcutFor } from '../../utils/listShortcuts.js';
|
|
43
43
|
import { mapListItems } from '../../utils/mapList.js';
|
|
44
|
+
import { resolveCssColor, markerColorOf, normalizeMarkerColor } from '../../utils/mapMarkerColor.js';
|
|
44
45
|
import { multiKeySort } from '../../utils/multiKeySort.js';
|
|
45
46
|
import { fetchGroups } from '../../utils/nextcloudDirectory.js';
|
|
46
47
|
import { OBJECTS_CHANGED_EVENT } from '../../utils/objectSignals.js';
|
|
47
48
|
import { objectUrlOf, patchObject } from '../../utils/objectWrite.js';
|
|
48
49
|
import { withPersonalLenses } from '../../utils/personalLenses.js';
|
|
49
|
-
import { resolveDeepTokens, resolveFilterValue } from '../../utils/resolveFilterTokens.js';
|
|
50
|
+
import { resolveDeepTokens, resolveFilterValue, resolveFilterTokens } from '../../utils/resolveFilterTokens.js';
|
|
50
51
|
import { resolveRowActions } from '../../utils/resolveRowActions.js';
|
|
51
52
|
import { resolveFilterMap } from '../../utils/routeFilters.js';
|
|
52
53
|
import { DEFAULT_ROW_ACTION_FIELD, withoutViewWhenRowOpensDetail, availableRowActions, refusalReasonFor, undeclaredRowActions } from '../../utils/rowActionAvailability.js';
|
|
@@ -54,7 +55,7 @@ import { isRowActionVisible, rowActionPayload } from '../../utils/rowActionItem.
|
|
|
54
55
|
import { isNewTabClick, preventMiddleClickAutoscroll, isRowMiddleClick, isNewTabHandled, markNewTabHandled } from '../../utils/rowAuxClick.js';
|
|
55
56
|
import { compileRowClass } from '../../utils/rowClassRules.js';
|
|
56
57
|
import { DEFAULT_ROW_INDICATOR_CAP } from '../../utils/rowIndicators.js';
|
|
57
|
-
import { viewMatchesScope, extractViewState, buildRouteQueryFromViewState, extractViewStateFromRouteQuery, buildViewCreatePayload, savedViewScope
|
|
58
|
+
import { defaultFilterViews, viewMatchesScope, normalizeSharedWith, extractViewState, buildRouteQueryFromViewState, extractViewStateFromRouteQuery, buildViewCreatePayload, savedViewScope } from '../../utils/savedViewHelpers.js';
|
|
58
59
|
import { fieldsFromSchema, columnsFromSchema } from '../../utils/schema.js';
|
|
59
60
|
import { resolveScopeLayout, resolveScopePresentation } from '../../utils/scopeListLayout.js';
|
|
60
61
|
import { orderToSortKeys } from '../../utils/sortOrder.js';
|
|
@@ -87,10 +88,11 @@ import __sfc_main$5 from '../CnPageHeader/CnPageHeader.vue.js';
|
|
|
87
88
|
import __sfc_main$i from '../CnPagination/CnPagination.vue.js';
|
|
88
89
|
import __sfc_main$6 from '../CnQuickFilterBar/CnQuickFilterBar.vue.js';
|
|
89
90
|
import __sfc_main$j from '../CnRowActions/CnRowActions.vue.js';
|
|
91
|
+
import __sfc_main$w from '../CnSavedViewEditDialog/CnSavedViewEditDialog.vue.js';
|
|
90
92
|
import __sfc_main$v from '../CnSavedViewPresentationDialog/CnSavedViewPresentationDialog.vue.js';
|
|
91
93
|
import __sfc_main$u from '../CnSavedViewsControl/CnSavedViewsControl.vue.js';
|
|
92
|
-
import __sfc_main$
|
|
93
|
-
import __sfc_main$
|
|
94
|
+
import __sfc_main$x from '../CnSavedViewShareDialog/CnSavedViewShareDialog.vue.js';
|
|
95
|
+
import __sfc_main$y from '../CnSaveViewDialog/CnSaveViewDialog.vue.js';
|
|
94
96
|
import { applyAiContext } from './aiContext.js';
|
|
95
97
|
import { buildDefaultActions } from './defaultActions.js';
|
|
96
98
|
import { dispatchAction } from './manifestActionDispatch.js';
|
|
@@ -99,7 +101,7 @@ import { reconcilePersonalColumns, orderColumns, personalColumnsKey } from './pe
|
|
|
99
101
|
import { createSelfModeActions, resolveRowTarget } from './selfModeActions.js';
|
|
100
102
|
import { applyRowPatches, splitLayoutFor, normalisePaneWidth, rowIdOf } from './splitView.js';
|
|
101
103
|
import { useNamedSource } from './useNamedSource.js';
|
|
102
|
-
import { useSelfFetchList, resolveInitialQuickFilterIndex, BOARD_PAGE_SIZE } from './useSelfFetchList.js';
|
|
104
|
+
import { useSelfFetchList, mapPlotAllLimitOf, resolveInitialQuickFilterIndex, BOARD_PAGE_SIZE } from './useSelfFetchList.js';
|
|
103
105
|
import { useContextMenu } from '../../composables/useContextMenu.js';
|
|
104
106
|
|
|
105
107
|
/** Rows fetched for one month in calendar mode. */
|
|
@@ -382,10 +384,11 @@ var script = {
|
|
|
382
384
|
CnIndexSidebar: __sfc_main$t,
|
|
383
385
|
CnSavedViewsControl: __sfc_main$u,
|
|
384
386
|
CnSavedViewPresentationDialog: __sfc_main$v,
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
387
|
+
CnSavedViewEditDialog: __sfc_main$w,
|
|
388
|
+
CnSavedViewShareDialog: __sfc_main$x,
|
|
389
|
+
CnSaveViewDialog: __sfc_main$y,
|
|
390
|
+
CnConfirmDialog: __sfc_main$z,
|
|
391
|
+
CnQuickEditDialog: __sfc_main$A,
|
|
389
392
|
},
|
|
390
393
|
|
|
391
394
|
/**
|
|
@@ -453,6 +456,12 @@ var script = {
|
|
|
453
456
|
* simply has no held order instead of failing to render.
|
|
454
457
|
*/
|
|
455
458
|
cnUserPreferences: { default: null },
|
|
459
|
+
/**
|
|
460
|
+
* The saved views this user put in the app menu, held by CnAppRoot:
|
|
461
|
+
* `{ entries, toggle(entry) }`. Absent without the shell, and then
|
|
462
|
+
* the sidebar offers no Add to menu.
|
|
463
|
+
*/
|
|
464
|
+
cnSavedViewMenu: { default: null },
|
|
456
465
|
/**
|
|
457
466
|
* Consumer translation function, provided by CnAppRoot as
|
|
458
467
|
* `cnTranslate: this.translate` (bound to the host app's id). Column and
|
|
@@ -1635,6 +1644,17 @@ var script = {
|
|
|
1635
1644
|
default: '',
|
|
1636
1645
|
},
|
|
1637
1646
|
|
|
1647
|
+
/**
|
|
1648
|
+
* Views the app ships for this page (`config.defaultSavedViews`), each
|
|
1649
|
+
* `{ slug, name, filters, search?, sort?, label? }`. Listed read-only
|
|
1650
|
+
* above the user's own saved views, never stored; a user may apply one
|
|
1651
|
+
* or save a copy. `@`-tokens in `filters` resolve when it is applied.
|
|
1652
|
+
*/
|
|
1653
|
+
defaultSavedViews: {
|
|
1654
|
+
type: Array,
|
|
1655
|
+
default: () => [],
|
|
1656
|
+
},
|
|
1657
|
+
|
|
1638
1658
|
/** Property name used to display item names in dialogs */
|
|
1639
1659
|
massActionNameField: {
|
|
1640
1660
|
type: String,
|
|
@@ -2742,6 +2762,10 @@ var script = {
|
|
|
2742
2762
|
headerMetaCountValues: {},
|
|
2743
2763
|
/** The row the pointer is on in the map list, by key; '' for none. */
|
|
2744
2764
|
activeMapKey: '',
|
|
2765
|
+
/** The rows `mapConfig.markerColor.source` points at, or null before they load. */
|
|
2766
|
+
mapColorRefs: null,
|
|
2767
|
+
/** The page size to restore when leaving a map that plots every row. */
|
|
2768
|
+
mapPrevPageSize: this.viewMode === 'map' && mapPlotAllLimitOf(this.mapConfig) > 0 ? ((this.pagination && this.pagination.limit) || 20) : null,
|
|
2745
2769
|
/** The tabs `quickFiltersFrom` produced, or null before they load. */
|
|
2746
2770
|
generatedQuickFilters: null,
|
|
2747
2771
|
/** Count per saved-view id, for the views control; null = none. */
|
|
@@ -2809,6 +2833,8 @@ var script = {
|
|
|
2809
2833
|
// content (table / cards) starts at the top and fills the width;
|
|
2810
2834
|
// opened on demand via the actions-bar toggle.
|
|
2811
2835
|
sidebarOpen: false,
|
|
2836
|
+
/** The sidebar tab to show; follows the user's own tab changes. */
|
|
2837
|
+
sidebarActiveTab: '',
|
|
2812
2838
|
// Saved views (saved-views-ui): the fetched view list, its
|
|
2813
2839
|
// loading flag, the save-dialog toggle, and the view awaiting
|
|
2814
2840
|
// delete confirmation.
|
|
@@ -2818,6 +2844,8 @@ var script = {
|
|
|
2818
2844
|
viewPendingDelete: null,
|
|
2819
2845
|
/** The own view whose audience is being changed (CnSavedViewShareDialog), or null. */
|
|
2820
2846
|
viewPendingShare: null,
|
|
2847
|
+
/** The own view being renamed or re-filtered (CnSavedViewEditDialog), or null. */
|
|
2848
|
+
viewPendingEdit: null,
|
|
2821
2849
|
/** The view whose presentation is being changed (CnSavedViewPresentationDialog), or null. */
|
|
2822
2850
|
viewPendingPresentation: null,
|
|
2823
2851
|
// Split view (case-page-and-list-as-a-place). `splitRowPatches` holds
|
|
@@ -3989,7 +4017,63 @@ var script = {
|
|
|
3989
4017
|
* @return {Array<object>} The views.
|
|
3990
4018
|
*/
|
|
3991
4019
|
viewsForControl() {
|
|
3992
|
-
return this.splitSavedViews.control
|
|
4020
|
+
return [...this.defaultFilterViews, ...this.splitSavedViews.control]
|
|
4021
|
+
},
|
|
4022
|
+
|
|
4023
|
+
/**
|
|
4024
|
+
* What the sidebar's saved-views panel shows, or null when the page
|
|
4025
|
+
* does not offer saved views.
|
|
4026
|
+
*
|
|
4027
|
+
* @return {object|null}
|
|
4028
|
+
* @spec openspec/changes/saved-views-manage-and-defaults/tasks.md#task-6
|
|
4029
|
+
*/
|
|
4030
|
+
savedViewsForSidebar() {
|
|
4031
|
+
if (!this.allowSavedViews) {
|
|
4032
|
+
return null
|
|
4033
|
+
}
|
|
4034
|
+
return {
|
|
4035
|
+
views: this.viewsForControl,
|
|
4036
|
+
loading: this.savedViewsLoading,
|
|
4037
|
+
currentUserId: this.currentSavedViewsUserId,
|
|
4038
|
+
counts: this.savedViewCounts,
|
|
4039
|
+
selectedViewId: this.appliedSavedViewId,
|
|
4040
|
+
menuIds: this.savedViewMenuIds,
|
|
4041
|
+
}
|
|
4042
|
+
},
|
|
4043
|
+
|
|
4044
|
+
/**
|
|
4045
|
+
* The route name this page's menu entries point at.
|
|
4046
|
+
*
|
|
4047
|
+
* @return {string}
|
|
4048
|
+
*/
|
|
4049
|
+
savedViewPage() {
|
|
4050
|
+
return (this.$route && typeof this.$route.name === 'string') ? this.$route.name : ''
|
|
4051
|
+
},
|
|
4052
|
+
|
|
4053
|
+
/**
|
|
4054
|
+
* The ids of this page's views in the app menu, or null when there is
|
|
4055
|
+
* no menu to add to.
|
|
4056
|
+
*
|
|
4057
|
+
* @return {Array<string>|null}
|
|
4058
|
+
* @spec openspec/changes/saved-views-manage-and-defaults/tasks.md#task-7
|
|
4059
|
+
*/
|
|
4060
|
+
savedViewMenuIds() {
|
|
4061
|
+
const menu = this.cnSavedViewMenu;
|
|
4062
|
+
if (!menu || typeof menu.toggle !== 'function' || this.savedViewPage === '') {
|
|
4063
|
+
return null
|
|
4064
|
+
}
|
|
4065
|
+
return (menu.entries || []).filter((e) => e.page === this.savedViewPage).map((e) => String(e.id))
|
|
4066
|
+
},
|
|
4067
|
+
|
|
4068
|
+
/**
|
|
4069
|
+
* The page's `defaultSavedViews` as read-only views.
|
|
4070
|
+
*
|
|
4071
|
+
* @return {Array<object>} The views.
|
|
4072
|
+
* @spec openspec/changes/saved-views-manage-and-defaults/tasks.md#task-4
|
|
4073
|
+
*/
|
|
4074
|
+
defaultFilterViews() {
|
|
4075
|
+
const defaults = (Array.isArray(this.defaultSavedViews) ? this.defaultSavedViews : []).map((entry) => (entry && typeof entry.name === 'string' ? { ...entry, name: this.cnTranslate(entry.name) } : entry));
|
|
4076
|
+
return defaultFilterViews(defaults, this.savedViewsPage)
|
|
3993
4077
|
},
|
|
3994
4078
|
|
|
3995
4079
|
/**
|
|
@@ -4645,11 +4729,13 @@ var script = {
|
|
|
4645
4729
|
if (!geometry) {
|
|
4646
4730
|
continue
|
|
4647
4731
|
}
|
|
4732
|
+
const markerColor = resolveCssColor(markerColorOf(row, this.mapMarkerColor, this.mapColorRefsById));
|
|
4648
4733
|
features.push({
|
|
4649
4734
|
type: 'Feature',
|
|
4650
4735
|
geometry,
|
|
4651
4736
|
properties: {
|
|
4652
4737
|
[this.rowKey]: row[this.rowKey],
|
|
4738
|
+
...(markerColor ? { markerColor } : {}),
|
|
4653
4739
|
...(this.mapConfig.popupField ? { [this.mapConfig.popupField]: row[this.mapConfig.popupField] } : {}),
|
|
4654
4740
|
...(numbers && numbers.has(row) ? { markerNumber: numbers.get(row), markerActive: this.activeMapKey === String(row[this.rowKey]) } : {}),
|
|
4655
4741
|
},
|
|
@@ -4678,6 +4764,80 @@ var script = {
|
|
|
4678
4764
|
return this.mapConfig.clustering !== false
|
|
4679
4765
|
},
|
|
4680
4766
|
|
|
4767
|
+
/**
|
|
4768
|
+
* The marker colour rule (`mapConfig.markerColor`), or null.
|
|
4769
|
+
*
|
|
4770
|
+
* @return {object|null} The normalised rule.
|
|
4771
|
+
* @spec openspec/changes/index-map-parity/specs/index-page/spec.md#requirement-a-marker-can-take-its-colour-from-a-field
|
|
4772
|
+
*/
|
|
4773
|
+
mapMarkerColor() {
|
|
4774
|
+
return normalizeMarkerColor(this.mapConfig && this.mapConfig.markerColor)
|
|
4775
|
+
},
|
|
4776
|
+
|
|
4777
|
+
/** @return {Map<string, object>} The marker colour source rows by id. */
|
|
4778
|
+
mapColorRefsById() {
|
|
4779
|
+
return new Map((this.mapColorRefs || []).map((row) => [refIdOf(row), row]))
|
|
4780
|
+
},
|
|
4781
|
+
|
|
4782
|
+
/** @return {string} Changes when the marker colour source must be read. */
|
|
4783
|
+
mapColorFetchKey() {
|
|
4784
|
+
const source = this.mapMarkerColor && this.mapMarkerColor.source;
|
|
4785
|
+
if (this.currentViewMode !== 'map' || !source) {
|
|
4786
|
+
return ''
|
|
4787
|
+
}
|
|
4788
|
+
return [this.mapMarkerColor.field, source.register || '', source.schema || '', this.effectiveSchema ? 1 : 0].join('|')
|
|
4789
|
+
},
|
|
4790
|
+
|
|
4791
|
+
/**
|
|
4792
|
+
* How many rows the map plots when it plots every matching row
|
|
4793
|
+
* (`mapConfig.plotAll`: `true` for 500, or a
|
|
4794
|
+
* number), 0 when it plots the current page.
|
|
4795
|
+
*
|
|
4796
|
+
* @return {number} The limit.
|
|
4797
|
+
* @spec openspec/changes/index-map-parity/specs/index-page/spec.md#requirement-the-map-can-plot-every-matching-row
|
|
4798
|
+
*/
|
|
4799
|
+
mapPlotAllLimit() {
|
|
4800
|
+
return mapPlotAllLimitOf(this.mapConfig)
|
|
4801
|
+
},
|
|
4802
|
+
|
|
4803
|
+
/** @return {number} The rows that match the filters. */
|
|
4804
|
+
mapMatchTotal() {
|
|
4805
|
+
return Math.max(this.displayObjects.length, Number(this.effectivePagination?.total || 0))
|
|
4806
|
+
},
|
|
4807
|
+
|
|
4808
|
+
/**
|
|
4809
|
+
* The count line under the map (`mapConfig.count`): `true` for "Showing
|
|
4810
|
+
* {located} of {total} located", or a template with `{located}` and
|
|
4811
|
+
* `{total}` through the host's translate. '' when not asked for.
|
|
4812
|
+
*
|
|
4813
|
+
* @return {string} The line.
|
|
4814
|
+
* @spec openspec/changes/index-map-parity/specs/index-page/spec.md#requirement-the-map-can-say-how-many-rows-it-placed
|
|
4815
|
+
*/
|
|
4816
|
+
mapCountLine() {
|
|
4817
|
+
const count = this.mapConfig && this.mapConfig.count;
|
|
4818
|
+
if (this.currentViewMode !== 'map' || !count) {
|
|
4819
|
+
return ''
|
|
4820
|
+
}
|
|
4821
|
+
const vars = { located: this.mapMarkers.features.length, total: this.mapMatchTotal };
|
|
4822
|
+
if (typeof count === 'string' && count !== '') {
|
|
4823
|
+
return this.cnTranslate(count).replace(/\{(located|total)\}/g, (_, key) => String(vars[key]))
|
|
4824
|
+
}
|
|
4825
|
+
return translate('nextcloud-vue', 'Showing {located} of {total} located', vars)
|
|
4826
|
+
},
|
|
4827
|
+
|
|
4828
|
+
/**
|
|
4829
|
+
* The note when a map that plots every row hit its limit.
|
|
4830
|
+
*
|
|
4831
|
+
* @return {string} The note, or ''.
|
|
4832
|
+
*/
|
|
4833
|
+
mapCapNote() {
|
|
4834
|
+
const limit = this.mapPlotAllLimit;
|
|
4835
|
+
if (this.currentViewMode !== 'map' || limit === 0 || this.mapMatchTotal <= this.displayObjects.length) {
|
|
4836
|
+
return ''
|
|
4837
|
+
}
|
|
4838
|
+
return translate('nextcloud-vue', 'The map shows the first {limit} of {total}. Narrow the filters to see the rest.', { limit: this.displayObjects.length, total: this.mapMatchTotal })
|
|
4839
|
+
},
|
|
4840
|
+
|
|
4681
4841
|
/** @return {number|undefined} The map's initial zoom (`mapConfig.zoom`), when a number. */
|
|
4682
4842
|
mapZoom() {
|
|
4683
4843
|
const zoom = this.mapConfig && this.mapConfig.zoom;
|
|
@@ -5029,7 +5189,14 @@ var script = {
|
|
|
5029
5189
|
if (!this.viewPendingDelete) {
|
|
5030
5190
|
return ''
|
|
5031
5191
|
}
|
|
5032
|
-
|
|
5192
|
+
const view = this.viewPendingDelete;
|
|
5193
|
+
const parts = [translate('nextcloud-vue', 'The view "{name}" leaves your list and the menu on the left.', { name: view.name })];
|
|
5194
|
+
const audience = normalizeSharedWith(view.sharedWith).map((e) => e.user || e.group);
|
|
5195
|
+
if (audience.length > 0) {
|
|
5196
|
+
parts.push(translate('nextcloud-vue', 'It is shared with {names}; it leaves their lists too.', { names: audience.join(', ') }));
|
|
5197
|
+
}
|
|
5198
|
+
parts.push(translate('nextcloud-vue', 'The items themselves stay. This cannot be undone.'));
|
|
5199
|
+
return parts.join(' ')
|
|
5033
5200
|
},
|
|
5034
5201
|
|
|
5035
5202
|
/** Sort key / order: list state in self-fetch mode, else the props. */
|
|
@@ -6078,12 +6245,17 @@ var script = {
|
|
|
6078
6245
|
/**
|
|
6079
6246
|
* Effective sidebar configuration. Returns the sidebar config object
|
|
6080
6247
|
* when `sidebar.enabled === true`, otherwise an `{ enabled: false }`
|
|
6081
|
-
* stub so the embedded CnIndexSidebar is not mounted.
|
|
6248
|
+
* stub so the embedded CnIndexSidebar is not mounted. A page that
|
|
6249
|
+
* offers saved views gets the sidebar unless it switched it off
|
|
6250
|
+
* with `enabled: false`: the saved views live in its Search tab.
|
|
6082
6251
|
*/
|
|
6083
6252
|
resolvedSidebar() {
|
|
6084
|
-
if (this.sidebar && this.sidebar.enabled !== false) {
|
|
6253
|
+
if (this.sidebar && this.sidebar.enabled !== false && (this.sidebar.enabled || !this.allowSavedViews)) {
|
|
6085
6254
|
return this.sidebar
|
|
6086
6255
|
}
|
|
6256
|
+
if (this.allowSavedViews && !(this.sidebar && this.sidebar.enabled === false)) {
|
|
6257
|
+
return { ...(this.sidebar || {}), enabled: true }
|
|
6258
|
+
}
|
|
6087
6259
|
return { enabled: false }
|
|
6088
6260
|
},
|
|
6089
6261
|
|
|
@@ -6163,6 +6335,8 @@ var script = {
|
|
|
6163
6335
|
pinnedCount: this.pinnedColumnCount,
|
|
6164
6336
|
sortOptions: this.sidebarSortOptions,
|
|
6165
6337
|
currentSort: this.currentSortKeys,
|
|
6338
|
+
savedViews: this.savedViewsForSidebar,
|
|
6339
|
+
activeTab: this.sidebarActiveTab,
|
|
6166
6340
|
...this.sidebarSearchProps,
|
|
6167
6341
|
}
|
|
6168
6342
|
},
|
|
@@ -6216,12 +6390,25 @@ var script = {
|
|
|
6216
6390
|
this.applyViewModeFromRoute();
|
|
6217
6391
|
},
|
|
6218
6392
|
|
|
6393
|
+
'$route.query.savedView': function() {
|
|
6394
|
+
this.applySavedViewFromRoute();
|
|
6395
|
+
},
|
|
6396
|
+
|
|
6219
6397
|
routeViewModes() {
|
|
6220
6398
|
if (this.routeViewPending) {
|
|
6221
6399
|
this.applyViewModeFromRoute();
|
|
6222
6400
|
}
|
|
6223
6401
|
},
|
|
6224
6402
|
|
|
6403
|
+
mapColorFetchKey: {
|
|
6404
|
+
immediate: true,
|
|
6405
|
+
handler(key) {
|
|
6406
|
+
if (key !== '') {
|
|
6407
|
+
this.loadMapColorSource();
|
|
6408
|
+
}
|
|
6409
|
+
},
|
|
6410
|
+
},
|
|
6411
|
+
|
|
6225
6412
|
boardFetchKey: {
|
|
6226
6413
|
immediate: true,
|
|
6227
6414
|
handler(key) {
|
|
@@ -6342,6 +6529,11 @@ var script = {
|
|
|
6342
6529
|
listSize = this.boardPrevPageSize || 20;
|
|
6343
6530
|
this.boardPrevPageSize = null;
|
|
6344
6531
|
}
|
|
6532
|
+
const leftMapPlotAll = previous === 'map' && this.mapPrevPageSize !== null;
|
|
6533
|
+
if (leftMapPlotAll) {
|
|
6534
|
+
listSize = this.mapPrevPageSize;
|
|
6535
|
+
this.mapPrevPageSize = null;
|
|
6536
|
+
}
|
|
6345
6537
|
let size = null;
|
|
6346
6538
|
if (mode === 'calendar') {
|
|
6347
6539
|
this.calendarPrevPageSize = listSize;
|
|
@@ -6349,7 +6541,10 @@ var script = {
|
|
|
6349
6541
|
} else if (mode === 'board') {
|
|
6350
6542
|
this.boardPrevPageSize = listSize;
|
|
6351
6543
|
size = BOARD_PAGE_SIZE;
|
|
6352
|
-
} else if (
|
|
6544
|
+
} else if (mode === 'map' && this.mapPlotAllLimit > 0 && !this.isNamedSource) {
|
|
6545
|
+
this.mapPrevPageSize = listSize;
|
|
6546
|
+
size = this.mapPlotAllLimit;
|
|
6547
|
+
} else if (previous === 'calendar' || previous === 'board' || leftMapPlotAll) {
|
|
6353
6548
|
size = listSize;
|
|
6354
6549
|
}
|
|
6355
6550
|
if (size !== null && typeof this.list.onPageSizeChange === 'function') {
|
|
@@ -7756,13 +7951,21 @@ var script = {
|
|
|
7756
7951
|
* (same resulting path/query) is swallowed.
|
|
7757
7952
|
*
|
|
7758
7953
|
* @param {{filters?: object, search?: string, sortKey?: ?string, sortOrder?: string, sortKeys?: Array<{key: string, order: string}>}} state Current view state.
|
|
7954
|
+
* @param {{savedView?: string}} [options] The saved view the address keeps naming, or none.
|
|
7759
7955
|
* @return {void}
|
|
7760
7956
|
*/
|
|
7761
|
-
persistViewStateToRoute(state) {
|
|
7957
|
+
persistViewStateToRoute(state, { savedView = '' } = {}) {
|
|
7762
7958
|
if (!this.$router || !this.$route) {
|
|
7763
7959
|
return
|
|
7764
7960
|
}
|
|
7765
7961
|
const query = { ...this.$route.query };
|
|
7962
|
+
// The menu entry of a saved view is active while the address names
|
|
7963
|
+
// it; any other change to the filters is no longer that view.
|
|
7964
|
+
if (savedView !== '') {
|
|
7965
|
+
query.savedView = savedView;
|
|
7966
|
+
} else {
|
|
7967
|
+
delete query.savedView;
|
|
7968
|
+
}
|
|
7766
7969
|
for (const key of this.persistedFilterKeys) {
|
|
7767
7970
|
delete query[key];
|
|
7768
7971
|
}
|
|
@@ -7839,6 +8042,30 @@ var script = {
|
|
|
7839
8042
|
this.$emit('clear-filters');
|
|
7840
8043
|
},
|
|
7841
8044
|
|
|
8045
|
+
/**
|
|
8046
|
+
* Read the rows `mapConfig.markerColor.source` points at, once.
|
|
8047
|
+
*
|
|
8048
|
+
* @return {Promise<void>}
|
|
8049
|
+
*/
|
|
8050
|
+
async loadMapColorSource() {
|
|
8051
|
+
const rule = this.mapMarkerColor;
|
|
8052
|
+
if (!rule || !rule.source || this.mapColorRefs !== null) {
|
|
8053
|
+
return
|
|
8054
|
+
}
|
|
8055
|
+
const property = this.effectiveSchema?.properties?.[rule.field] || null;
|
|
8056
|
+
const target = referenceTargetOf(rule.source, { register: this.register, property });
|
|
8057
|
+
if (!target.register || !target.schema) {
|
|
8058
|
+
return
|
|
8059
|
+
}
|
|
8060
|
+
let rows;
|
|
8061
|
+
try {
|
|
8062
|
+
rows = await fetchReferenceObjects({ ...target, filter: rule.source.filter || {} });
|
|
8063
|
+
} catch {
|
|
8064
|
+
rows = [];
|
|
8065
|
+
}
|
|
8066
|
+
this.mapColorRefs = Array.isArray(rows) ? rows : [];
|
|
8067
|
+
},
|
|
8068
|
+
|
|
7842
8069
|
/**
|
|
7843
8070
|
* Fetch what the board view needs: the rows of a reference column
|
|
7844
8071
|
* field (once per field) and the narrowing select's options.
|
|
@@ -8835,6 +9062,10 @@ var script = {
|
|
|
8835
9062
|
'filter-change': (event) => this.onFilterEvent(event),
|
|
8836
9063
|
'clear-filters': () => this.onClearFilters(),
|
|
8837
9064
|
'sort-change': (keys) => this.onSidebarSortChange(keys),
|
|
9065
|
+
'saved-view': (event) => this.onSavedViewAction(event),
|
|
9066
|
+
'tab-change': (tab) => {
|
|
9067
|
+
this.sidebarActiveTab = tab;
|
|
9068
|
+
},
|
|
8838
9069
|
},
|
|
8839
9070
|
};
|
|
8840
9071
|
},
|
|
@@ -9479,6 +9710,13 @@ var script = {
|
|
|
9479
9710
|
this.savedViewsLoading = true;
|
|
9480
9711
|
try {
|
|
9481
9712
|
this.savedViews = await useSavedViewsApi().fetchViews();
|
|
9713
|
+
// An empty answer is also what a misread response gives, so it
|
|
9714
|
+
// never empties the menu: entries are dropped only against a
|
|
9715
|
+
// list that came back with views in it.
|
|
9716
|
+
if (this.savedViews.length > 0) {
|
|
9717
|
+
this.syncSavedViewMenu();
|
|
9718
|
+
}
|
|
9719
|
+
this.applySavedViewFromRoute();
|
|
9482
9720
|
} catch (error) {
|
|
9483
9721
|
// eslint-disable-next-line no-console
|
|
9484
9722
|
console.error('CnIndexPage: failed to fetch saved views', error);
|
|
@@ -9496,10 +9734,15 @@ var script = {
|
|
|
9496
9734
|
* query implicitly resets `_page` to 1.
|
|
9497
9735
|
*
|
|
9498
9736
|
* @param {object} view The View API object to apply.
|
|
9737
|
+
* @param {{keepSavedViewKey?: boolean}} [options] Keep `?savedView=<id>` in the address, as a menu entry's link does.
|
|
9499
9738
|
*/
|
|
9500
|
-
onApplySavedView(view) {
|
|
9739
|
+
onApplySavedView(view, { keepSavedViewKey = false } = {}) {
|
|
9501
9740
|
this.appliedSavedViewId = view && (view.id || view.slug) ? String(view.id || view.slug) : '';
|
|
9502
9741
|
const state = extractViewState(view);
|
|
9742
|
+
if (view && view.seeded === true) {
|
|
9743
|
+
const ctx = typeof this.selfFetchTokenCtx === 'function' ? this.selfFetchTokenCtx() : {};
|
|
9744
|
+
state.filters = resolveFilterTokens(state.filters, ctx);
|
|
9745
|
+
}
|
|
9503
9746
|
// A view that carries columns wins while it is applied; one without leaves the person's own layout.
|
|
9504
9747
|
const viewColumns = view && view.query && Array.isArray(view.query.columns) ? view.query.columns.map(String) : [];
|
|
9505
9748
|
this.appliedViewColumns = viewColumns.length > 0 ? viewColumns : null;
|
|
@@ -9518,14 +9761,18 @@ var script = {
|
|
|
9518
9761
|
// Through `persistViewStateToRoute` rather than a raw replace,
|
|
9519
9762
|
// because it is what records the keys this view wrote — without
|
|
9520
9763
|
// that, a later "clear all" has nothing to delete them by.
|
|
9521
|
-
this.persistViewStateToRoute(state);
|
|
9764
|
+
this.persistViewStateToRoute(state, { savedView: keepSavedViewKey ? this.appliedSavedViewId : '' });
|
|
9522
9765
|
this.$emit('apply-view', view);
|
|
9523
9766
|
return
|
|
9524
9767
|
}
|
|
9525
9768
|
if (!this.$router) {
|
|
9526
9769
|
return
|
|
9527
9770
|
}
|
|
9528
|
-
const
|
|
9771
|
+
const query = buildRouteQueryFromViewState(state);
|
|
9772
|
+
if (keepSavedViewKey) {
|
|
9773
|
+
query.savedView = this.appliedSavedViewId;
|
|
9774
|
+
}
|
|
9775
|
+
const nav = this.$router.replace({ query });
|
|
9529
9776
|
// Swallow the duplicate-navigation rejection (Vue Router 3)
|
|
9530
9777
|
// when the applied view matches the current query.
|
|
9531
9778
|
if (nav && typeof nav.catch === 'function') {
|
|
@@ -9610,6 +9857,8 @@ var script = {
|
|
|
9610
9857
|
}
|
|
9611
9858
|
this.savedViews = [...this.savedViews, view];
|
|
9612
9859
|
this.showSaveViewDialog = false;
|
|
9860
|
+
this.sidebarActiveTab = 'filters-tab';
|
|
9861
|
+
this.sidebarOpen = true;
|
|
9613
9862
|
this.toastSavedView('success', translate('nextcloud-vue', 'View "{name}" saved', { name }));
|
|
9614
9863
|
} catch (error) {
|
|
9615
9864
|
// eslint-disable-next-line no-console
|
|
@@ -9659,6 +9908,125 @@ var script = {
|
|
|
9659
9908
|
}
|
|
9660
9909
|
},
|
|
9661
9910
|
|
|
9911
|
+
/**
|
|
9912
|
+
* One saved-view intent from the sidebar's Search tab.
|
|
9913
|
+
*
|
|
9914
|
+
* @param {{action: string, view: (object|null)}} event The intent.
|
|
9915
|
+
* @spec openspec/changes/saved-views-manage-and-defaults/tasks.md#task-6
|
|
9916
|
+
*/
|
|
9917
|
+
onSavedViewAction({ action, view } = {}) {
|
|
9918
|
+
const handlers = {
|
|
9919
|
+
apply: () => this.onApplySavedView(view),
|
|
9920
|
+
save: () => { this.showSaveViewDialog = true; },
|
|
9921
|
+
edit: () => this.onEditViewRequest(view),
|
|
9922
|
+
share: () => this.onShareViewRequest(view),
|
|
9923
|
+
presentation: () => this.onPresentationViewRequest(view),
|
|
9924
|
+
update: () => this.onUpdateViewRequest(view),
|
|
9925
|
+
copy: () => this.onCopyViewRequest(view),
|
|
9926
|
+
menu: () => this.onToggleSavedViewInMenu(view),
|
|
9927
|
+
delete: () => this.onDeleteViewRequest(view),
|
|
9928
|
+
};
|
|
9929
|
+
if (handlers[action]) {
|
|
9930
|
+
handlers[action]();
|
|
9931
|
+
}
|
|
9932
|
+
},
|
|
9933
|
+
|
|
9934
|
+
/**
|
|
9935
|
+
* Add a saved view to the app menu, or take it out. Stored per user
|
|
9936
|
+
* by CnAppRoot; the view itself is not touched, so a view shared
|
|
9937
|
+
* with this user can be added as well as an own one.
|
|
9938
|
+
*
|
|
9939
|
+
* @param {object} view The view.
|
|
9940
|
+
* @spec openspec/changes/saved-views-manage-and-defaults/tasks.md#task-7
|
|
9941
|
+
*/
|
|
9942
|
+
onToggleSavedViewInMenu(view) {
|
|
9943
|
+
const menu = this.cnSavedViewMenu;
|
|
9944
|
+
if (!view || !menu || typeof menu.toggle !== 'function' || this.savedViewPage === '') {
|
|
9945
|
+
return
|
|
9946
|
+
}
|
|
9947
|
+
menu.toggle({ id: String(view.id || view.slug), page: this.savedViewPage, name: view.name });
|
|
9948
|
+
},
|
|
9949
|
+
|
|
9950
|
+
/**
|
|
9951
|
+
* Bring this page's menu entries in line with the views it can show:
|
|
9952
|
+
* current names, and none for a view deleted or no longer shared.
|
|
9953
|
+
*
|
|
9954
|
+
* @spec openspec/changes/saved-views-manage-and-defaults/tasks.md#task-7
|
|
9955
|
+
*/
|
|
9956
|
+
syncSavedViewMenu() {
|
|
9957
|
+
const menu = this.cnSavedViewMenu;
|
|
9958
|
+
if (!menu || typeof menu.sync !== 'function' || this.savedViewPage === '') {
|
|
9959
|
+
return
|
|
9960
|
+
}
|
|
9961
|
+
menu.sync(this.savedViewPage, [...this.defaultFilterViews, ...this.visibleSavedViews]);
|
|
9962
|
+
},
|
|
9963
|
+
|
|
9964
|
+
/**
|
|
9965
|
+
* Apply the saved view the address names (`?savedView=<id>`, what a
|
|
9966
|
+
* menu entry links to), once the list holding it has loaded.
|
|
9967
|
+
*
|
|
9968
|
+
* @spec openspec/changes/saved-views-manage-and-defaults/tasks.md#task-7
|
|
9969
|
+
*/
|
|
9970
|
+
applySavedViewFromRoute() {
|
|
9971
|
+
const id = this.$route && this.$route.query ? this.$route.query.savedView : undefined;
|
|
9972
|
+
if (typeof id !== 'string' || id === '' || id === this.appliedSavedViewId) {
|
|
9973
|
+
return
|
|
9974
|
+
}
|
|
9975
|
+
const view = this.viewsForControl.find((v) => String(v.id) === id || String(v.slug) === id);
|
|
9976
|
+
if (view) {
|
|
9977
|
+
this.onApplySavedView(view, { keepSavedViewKey: true });
|
|
9978
|
+
}
|
|
9979
|
+
},
|
|
9980
|
+
|
|
9981
|
+
/**
|
|
9982
|
+
* Open the edit dialog for an own view (CnSavedViewsControl `@edit-request`).
|
|
9983
|
+
*
|
|
9984
|
+
* @param {object} view The View API object.
|
|
9985
|
+
* @spec openspec/changes/saved-views-manage-and-defaults/tasks.md#task-3
|
|
9986
|
+
*/
|
|
9987
|
+
onEditViewRequest(view) {
|
|
9988
|
+
this.viewPendingEdit = view;
|
|
9989
|
+
},
|
|
9990
|
+
|
|
9991
|
+
/**
|
|
9992
|
+
* Save a rename, and the current filters when asked
|
|
9993
|
+
* (CnSavedViewEditDialog `@confirm`). The PATCH carries `name`, plus
|
|
9994
|
+
* `query` only when the criteria are replaced, so nothing else on the
|
|
9995
|
+
* view is rewritten from this tab's copy. A refusal keeps the dialog open.
|
|
9996
|
+
*
|
|
9997
|
+
* @param {{ name: string, replaceCriteria: boolean }} payload The dialog payload.
|
|
9998
|
+
* @spec openspec/changes/saved-views-manage-and-defaults/tasks.md#task-3
|
|
9999
|
+
*/
|
|
10000
|
+
async onEditViewConfirm({ name, replaceCriteria }) {
|
|
10001
|
+
const view = this.viewPendingEdit;
|
|
10002
|
+
if (!view) {
|
|
10003
|
+
return
|
|
10004
|
+
}
|
|
10005
|
+
const body = { name };
|
|
10006
|
+
if (replaceCriteria === true) {
|
|
10007
|
+
const state = this.isSelfFetchMode
|
|
10008
|
+
? this.currentViewState()
|
|
10009
|
+
: extractViewStateFromRouteQuery((this.$route && this.$route.query) || {});
|
|
10010
|
+
body.query = buildViewCreatePayload({
|
|
10011
|
+
name,
|
|
10012
|
+
state,
|
|
10013
|
+
scope: savedViewScope(this.savedViewsPage),
|
|
10014
|
+
register: this.register,
|
|
10015
|
+
schema: this.schema,
|
|
10016
|
+
}).query;
|
|
10017
|
+
}
|
|
10018
|
+
try {
|
|
10019
|
+
const saved = await useSavedViewsApi().patchView(view.id, body);
|
|
10020
|
+
this.savedViews = this.savedViews.map((v) => (v.id === view.id ? { ...v, ...(saved || body) } : v));
|
|
10021
|
+
this.syncSavedViewMenu();
|
|
10022
|
+
this.viewPendingEdit = null;
|
|
10023
|
+
this.toastSavedView('success', translate('nextcloud-vue', 'View "{name}" saved', { name }));
|
|
10024
|
+
} catch (error) {
|
|
10025
|
+
const data = error?.response?.data;
|
|
10026
|
+
this.$refs.editViewDialog?.setError((data && (data.error || data.message)) || error?.message);
|
|
10027
|
+
}
|
|
10028
|
+
},
|
|
10029
|
+
|
|
9662
10030
|
/**
|
|
9663
10031
|
* Open the share dialog for an own view (CnSavedViewsControl `@share-request`).
|
|
9664
10032
|
*
|
|
@@ -9777,6 +10145,7 @@ var script = {
|
|
|
9777
10145
|
try {
|
|
9778
10146
|
await useSavedViewsApi().deleteView(view.id);
|
|
9779
10147
|
this.savedViews = this.savedViews.filter((v) => v.id !== view.id);
|
|
10148
|
+
this.syncSavedViewMenu();
|
|
9780
10149
|
this.$refs.deleteViewConfirmDialog?.setResult({ success: true });
|
|
9781
10150
|
} catch (error) {
|
|
9782
10151
|
// eslint-disable-next-line no-console
|