22199: removed actions column and forceMultiselectMode
[arvados.git] / services / workbench2 / src / views-components / context-menu / menu-item-sort.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { ContextMenuAction } from './context-menu-action-set';
6 import { ContextMenuActionNames } from 'views-components/context-menu/context-menu-action-set';
7 import { sortByProperty } from 'common/array-utils';
8 import { horizontalMenuDivider, verticalMenuDivider } from './actions/context-menu-divider';
9 import { MultiSelectMenuAction } from 'views-components/multiselect-toolbar/ms-menu-actions';
10
11 export enum ContextMenuKind {
12     API_CLIENT_AUTHORIZATION = "ApiClientAuthorization",
13     COLLECTION = "Collection",
14     COLLECTION_ADMIN = "CollectionAdmin",
15     COLLECTION_DIRECTORY_ITEM = "CollectionDirectoryItem",
16     COLLECTION_FILE_ITEM = "CollectionFileItem",
17     COLLECTION_FILES = "CollectionFiles",
18     COLLECTION_FILES_MULTIPLE = "CollectionFilesMultiple",
19     COLLECTION_FILES_NOT_SELECTED = "CollectionFilesNotSelected",
20     FAVORITE = "Favorite",
21     FILTER_GROUP = "FilterGroup",
22     FILTER_GROUP_ADMIN = "FilterGroupAdmin",
23     FROZEN_MANAGEABLE_PROJECT = "FrozenManageableProject",
24     FROZEN_PROJECT = "FrozenProject",
25     FROZEN_PROJECT_ADMIN = "FrozenProjectAdmin",
26     GROUPS = "Group",
27     GROUP_MEMBER = "GroupMember",
28     KEEP_SERVICE = "KeepService",
29     LINK = "Link",
30     MANAGEABLE_PROJECT = "ManageableProject",
31     MULTI = "Multi",
32     OLD_VERSION_COLLECTION = "OldVersionCollection",
33     PERMISSION_EDIT = "PermissionEdit",
34     PROCESS = "Process",
35     PROCESS_ADMIN = "ProcessAdmin",
36     PROCESS_LOGS = "ProcessLogs",
37     PROCESS_RESOURCE = "ProcessResource",
38     PROJECT = "Project",
39     PROJECT_ADMIN = "ProjectAdmin",
40     READONLY_COLLECTION = "ReadOnlyCollection",
41     READONLY_COLLECTION_DIRECTORY_ITEM = "ReadOnlyCollectionDirectoryItem",
42     READONLY_COLLECTION_FILE_ITEM = "ReadOnlyCollectionFileItem",
43     READONLY_COLLECTION_FILES = "ReadOnlyCollectionFiles",
44     READONLY_COLLECTION_FILES_MULTIPLE = "ReadOnlyCollectionFilesMultiple",
45     READONLY_PROCESS_RESOURCE = "ReadOnlyProcessResource",
46     READONLY_PROJECT = "ReadOnlyProject",
47     READONLY_WORKFLOW = "ReadOnlyWorkflow",
48     REPOSITORY = "Repository",
49     RESOURCE = "Resource",
50     ROOT_PROJECT = "RootProject",
51     ROOT_PROJECT_ADMIN = "RootProjectAdmin",
52     RUNNING_PROCESS_ADMIN = "RunningProcessAdmin",
53     RUNNING_PROCESS_RESOURCE = "RunningProcessResource",
54     SEARCH_RESULTS = "SearchResults",
55     SSH_KEY = "SshKey",
56     TRASH = "Trash",
57     TRASHED_COLLECTION = "TrashedCollection",
58     USER = "User",
59     USER_DETAILS = "UserDetails",
60     VIRTUAL_MACHINE = "VirtualMachine",
61     WORKFLOW = "Workflow",
62     WRITEABLE_COLLECTION = "WriteableCollection",
63     WRITEABLE_PROJECT = "WriteableProject",
64 }
65
66 const processOrder = [
67     ContextMenuActionNames.VIEW_DETAILS,
68     ContextMenuActionNames.OPEN_IN_NEW_TAB,
69     ContextMenuActionNames.COPY_UUID,
70     ContextMenuActionNames.COPY_AND_RERUN_PROCESS,
71     ContextMenuActionNames.CANCEL,
72     ContextMenuActionNames.EDIT_PROCESS,
73     ContextMenuActionNames.REMOVE,
74     ContextMenuActionNames.DIVIDER,
75     ContextMenuActionNames.OUTPUTS,
76     ContextMenuActionNames.ADD_TO_FAVORITES,
77     ContextMenuActionNames.ADD_TO_PUBLIC_FAVORITES,
78     ContextMenuActionNames.DIVIDER,
79     ContextMenuActionNames.COPY_LINK_TO_CLIPBOARD,
80     ContextMenuActionNames.API_DETAILS,
81 ];
82
83 const projectOrder = [
84     ContextMenuActionNames.VIEW_DETAILS,
85     ContextMenuActionNames.OPEN_IN_NEW_TAB,
86     ContextMenuActionNames.COPY_UUID,
87     ContextMenuActionNames.SHARE,
88     ContextMenuActionNames.EDIT_PROJECT,
89     ContextMenuActionNames.MOVE_TO_TRASH,
90     ContextMenuActionNames.DIVIDER,
91     ContextMenuActionNames.NEW_PROJECT,
92     ContextMenuActionNames.MOVE_TO,
93     ContextMenuActionNames.FREEZE_PROJECT,
94     ContextMenuActionNames.ADD_TO_FAVORITES,
95     ContextMenuActionNames.ADD_TO_PUBLIC_FAVORITES,
96     ContextMenuActionNames.DIVIDER,
97     ContextMenuActionNames.COPY_LINK_TO_CLIPBOARD,
98     ContextMenuActionNames.OPEN_WITH_3RD_PARTY_CLIENT,
99     ContextMenuActionNames.API_DETAILS,
100 ];
101
102 const collectionOrder = [
103     ContextMenuActionNames.VIEW_DETAILS,
104     ContextMenuActionNames.OPEN_IN_NEW_TAB,
105     ContextMenuActionNames.COPY_UUID,
106     ContextMenuActionNames.SHARE,
107     ContextMenuActionNames.EDIT_COLLECTION,
108     ContextMenuActionNames.MOVE_TO_TRASH,
109     ContextMenuActionNames.DIVIDER,
110     ContextMenuActionNames.MAKE_A_COPY,
111     ContextMenuActionNames.MOVE_TO,
112     ContextMenuActionNames.ADD_TO_FAVORITES,
113     ContextMenuActionNames.ADD_TO_PUBLIC_FAVORITES,
114     ContextMenuActionNames.DIVIDER,
115     ContextMenuActionNames.COPY_LINK_TO_CLIPBOARD,
116     ContextMenuActionNames.OPEN_WITH_3RD_PARTY_CLIENT,
117     ContextMenuActionNames.API_DETAILS,
118 ];
119
120 const workflowOrder = [
121     ContextMenuActionNames.VIEW_DETAILS,
122     ContextMenuActionNames.OPEN_IN_NEW_TAB,
123     ContextMenuActionNames.COPY_UUID,
124     ContextMenuActionNames.RUN_WORKFLOW,
125     ContextMenuActionNames.DELETE_WORKFLOW,
126     ContextMenuActionNames.DIVIDER,
127     ContextMenuActionNames.COPY_LINK_TO_CLIPBOARD,
128     ContextMenuActionNames.API_DETAILS,
129 ]
130
131 const rootProjectOrder = [
132     ContextMenuActionNames.VIEW_DETAILS,
133     ContextMenuActionNames.USER_ACCOUNT,
134     ContextMenuActionNames.API_DETAILS,
135 ];
136
137 const defaultMultiOrder = [
138     ContextMenuActionNames.MOVE_TO,
139     ContextMenuActionNames.MAKE_A_COPY,
140     ContextMenuActionNames.MOVE_TO_TRASH,
141 ];
142
143 const kindToOrder: Record<string, ContextMenuActionNames[]> = {
144     [ContextMenuKind.MULTI]: defaultMultiOrder,
145
146     [ContextMenuKind.PROCESS]: processOrder,
147     [ContextMenuKind.PROCESS_ADMIN]: processOrder,
148     [ContextMenuKind.PROCESS_RESOURCE]: processOrder,
149     [ContextMenuKind.RUNNING_PROCESS_ADMIN]: processOrder,
150     [ContextMenuKind.RUNNING_PROCESS_RESOURCE]: processOrder,
151     [ContextMenuKind.READONLY_PROCESS_RESOURCE]: processOrder,
152
153     [ContextMenuKind.PROJECT]: projectOrder,
154     [ContextMenuKind.PROJECT_ADMIN]: projectOrder,
155     [ContextMenuKind.READONLY_PROJECT]: projectOrder,
156     [ContextMenuKind.FROZEN_PROJECT]: projectOrder,
157     [ContextMenuKind.FROZEN_PROJECT_ADMIN]: projectOrder,
158     [ContextMenuKind.WRITEABLE_PROJECT]: projectOrder,
159     [ContextMenuKind.MANAGEABLE_PROJECT]: projectOrder,
160     [ContextMenuKind.FROZEN_MANAGEABLE_PROJECT]: projectOrder,
161
162     [ContextMenuKind.COLLECTION]: collectionOrder,
163     [ContextMenuKind.COLLECTION_ADMIN]: collectionOrder,
164     [ContextMenuKind.READONLY_COLLECTION]: collectionOrder,
165     [ContextMenuKind.WRITEABLE_COLLECTION]: collectionOrder,
166     [ContextMenuKind.OLD_VERSION_COLLECTION]: collectionOrder,
167
168     [ContextMenuKind.WORKFLOW]: workflowOrder,
169     [ContextMenuKind.READONLY_WORKFLOW]: workflowOrder,
170
171     [ContextMenuKind.GROUPS]: projectOrder,
172
173     [ContextMenuKind.FILTER_GROUP]: projectOrder,
174     [ContextMenuKind.FILTER_GROUP_ADMIN]: projectOrder,
175
176     [ContextMenuKind.ROOT_PROJECT]: rootProjectOrder,
177     [ContextMenuKind.ROOT_PROJECT_ADMIN]: rootProjectOrder,
178 };
179
180 export const menuDirection = {
181     VERTICAL: 'vertical',
182     HORIZONTAL: 'horizontal'
183 }
184
185 export const sortMenuItems = (menuKind: ContextMenuKind, menuItems: ContextMenuAction[], orthagonality: string): ContextMenuAction[] | MultiSelectMenuAction[] => {
186     const preferredOrder = kindToOrder[menuKind];
187     //if no specified order, sort by name
188     if (!preferredOrder) return menuItems.sort(sortByProperty("name"));
189
190     const bucketMap = new Map();
191     const leftovers: ContextMenuAction[] = [];
192
193     // if we have multiple dividers, we need each of them to have a different "name" property
194     let count = 0;
195
196     preferredOrder.forEach((name) => {
197         if (name === ContextMenuActionNames.DIVIDER) {
198             count++;
199             bucketMap.set(`${name}-${count}`, orthagonality === menuDirection.VERTICAL ? verticalMenuDivider : horizontalMenuDivider)
200         } else {
201             bucketMap.set(name, null)
202         }
203     });
204     [...menuItems].forEach((item) => {
205         if (bucketMap.has(item.name)) bucketMap.set(item.name, item);
206         else leftovers.push(item);
207     });
208
209     const result =  Array.from(bucketMap.values()).concat(leftovers).filter((item) => item !== null).reduce((acc, val)=>{
210         return acc.at(-1)?.name === "Divider" && val.name === "Divider" ? acc : acc.concat(val)
211     }, []);
212
213     console.log('>>>SORT', menuKind);
214
215     return result.at(-1)?.name === "Divider" ? result.slice(0, -1) : result;
216 };