From: Lisa Knox Date: Thu, 30 Nov 2023 14:27:31 +0000 (-0500) Subject: 21128: single-multi works again Arvados-DCO-1.1-Signed-off-by: Lisa Knox --- diff --git a/src/components/multiselect-toolbar/MultiselectToolbar.tsx b/src/components/multiselect-toolbar/MultiselectToolbar.tsx index f7e75c0e..47157697 100644 --- a/src/components/multiselect-toolbar/MultiselectToolbar.tsx +++ b/src/components/multiselect-toolbar/MultiselectToolbar.tsx @@ -15,7 +15,7 @@ import { getResource } from "store/resources/resources"; import { ResourcesState } from "store/resources/resources"; import { MultiSelectMenuAction, MultiSelectMenuActionSet, MultiSelectMenuActionNames } from "views-components/multiselect-toolbar/ms-menu-actions"; import { ContextMenuAction } from "views-components/context-menu/context-menu-action-set"; -import { multiselectActionsFilters, TMultiselectActionsFilters, msResourceKind } from "./ms-toolbar-action-filters"; +import { multiselectActionsFilters, TMultiselectActionsFilters, msMenuResourceKind } from "./ms-toolbar-action-filters"; import { kindToActionSet, findActionByName } from "./ms-kind-action-differentiator"; import { msToggleTrashAction } from "views-components/multiselect-toolbar/ms-project-action-set"; import { copyToClipboardAction } from "store/open-in-new-tab/open-in-new-tab.actions"; @@ -23,6 +23,15 @@ import { ContainerRequestResource } from "models/container-request"; import { FavoritesState } from "store/favorites/favorites-reducer"; import { resourceIsFrozen } from "common/frozen-resources"; import { ProjectResource } from "models/project"; +import { getResourceWithEditableStatus } from "store/resources/resources"; +import { GroupResource } from "models/group"; +import { EditableResource } from "models/resource"; +import { User } from "models/user"; +import { GroupClass } from "models/group"; +import { isProcessCancelable } from "store/processes/process"; +import { CollectionResource } from "models/collection"; +import { getProcess } from "store/processes/process"; +import { Process } from "store/processes/process"; type CssRules = "root" | "button"; @@ -46,6 +55,7 @@ export type MultiselectToolbarProps = { checkedList: TCheckedList; selectedUuid: string | null iconProps: IconProps + user: User executeMulti: (action: ContextMenuAction, checkedList: TCheckedList, resources: ResourcesState) => void; }; @@ -59,13 +69,11 @@ export const MultiselectToolbar = connect( mapDispatchToProps )( withStyles(styles)((props: MultiselectToolbarProps & WithStyles) => { - const { classes, checkedList, selectedUuid: singleSelectedUuid, iconProps } = props; - const singleProjectKind = singleSelectedUuid ? resourceSubKind(singleSelectedUuid, iconProps.resources) : '' - const currentResourceKinds = singleProjectKind ? singleProjectKind : Array.from(selectedToKindSet(checkedList)); - + const { classes, checkedList, selectedUuid: singleSelectedUuid, iconProps, user } = props; + const singleResourceKind = singleSelectedUuid ? [resourceToMsResourceKind(singleSelectedUuid, iconProps.resources, user)] : null + const currentResourceKinds = singleResourceKind ? singleResourceKind : Array.from(selectedToKindSet(checkedList)); const currentPathIsTrash = window.location.pathname === "/trash"; - const actions = currentPathIsTrash && selectedToKindSet(checkedList).size ? [msToggleTrashAction] @@ -145,19 +153,63 @@ function filterActions(actionArray: MultiSelectMenuActionSet, filters: Set filters.has(action.name as string)); } -const resourceSubKind = (uuid: string, resources: ResourcesState): (msResourceKind | ResourceKind)[] => { - const resource = getResource(uuid)(resources) as ContainerRequestResource | Resource; - switch (resource.kind) { +const resourceToMsResourceKind = (uuid: string, resources: ResourcesState, user: User, readonly = false): (msMenuResourceKind | ResourceKind) | undefined => { + const resource = getResourceWithEditableStatus(uuid, user.uuid)(resources); + const { isAdmin } = user; + const kind = extractUuidKind(uuid); + + const isFrozen = resourceIsFrozen(resource, resources); + const isEditable = (user.isAdmin || (resource || ({} as EditableResource)).isEditable) && !readonly && !isFrozen; + + switch (kind) { case ResourceKind.PROJECT: - if(resourceIsFrozen(resource, resources)) return [msResourceKind.PROJECT_FROZEN] - if((resource as ProjectResource).canWrite === false) return [msResourceKind.PROJECT_READONLY] - if((resource as ProjectResource).groupClass === "filter") return [msResourceKind.PROJECT_FILTER] - return [msResourceKind.PROJECT] + if (isFrozen) { + return isAdmin ? msMenuResourceKind.FROZEN_PROJECT_ADMIN : msMenuResourceKind.FROZEN_PROJECT; + } + + return isAdmin && !readonly + ? resource && resource.groupClass !== GroupClass.FILTER + ? msMenuResourceKind.PROJECT_ADMIN + : msMenuResourceKind.FILTER_GROUP_ADMIN + : isEditable + ? resource && resource.groupClass !== GroupClass.FILTER + ? msMenuResourceKind.PROJECT + : msMenuResourceKind.FILTER_GROUP + : msMenuResourceKind.READONLY_PROJECT; + case ResourceKind.COLLECTION: + const c = getResource(uuid)(resources); + if (c === undefined) { + return; + } + const isOldVersion = c.uuid !== c.currentVersionUuid; + const isTrashed = c.isTrashed; + return isOldVersion + ? msMenuResourceKind.OLD_VERSION_COLLECTION + : isTrashed && isEditable + ? msMenuResourceKind.TRASHED_COLLECTION + : isAdmin && isEditable + ? msMenuResourceKind.COLLECTION_ADMIN + : isEditable + ? msMenuResourceKind.COLLECTION + : msMenuResourceKind.READONLY_COLLECTION; + case ResourceKind.PROCESS: + return isAdmin && isEditable + ? resource && isProcessCancelable(getProcess(resource.uuid)(resources) as Process) + ? msMenuResourceKind.RUNNING_PROCESS_ADMIN + : msMenuResourceKind.PROCESS_ADMIN + : readonly + ? msMenuResourceKind.READONLY_PROCESS_RESOURCE + : resource && isProcessCancelable(getProcess(resource.uuid)(resources) as Process) + ? msMenuResourceKind.RUNNING_PROCESS_RESOURCE + : msMenuResourceKind.PROCESS_RESOURCE; + case ResourceKind.USER: + return msMenuResourceKind.ROOT_PROJECT; + case ResourceKind.LINK: + return msMenuResourceKind.LINK; case ResourceKind.WORKFLOW: - if((resource as ProjectResource).canWrite === false) return [msResourceKind.WORKFLOW_READONLY] - return [msResourceKind.WORKFLOW] + return isEditable ? msMenuResourceKind.WORKFLOW : msMenuResourceKind.READONLY_WORKFLOW; default: - return [resource.kind] + return; } }; @@ -177,7 +229,7 @@ function selectActionsByKind(currentResourceKinds: Array, filterSet: TMu }); } }); - +console.log(currentResourceKinds,allFiltersArray) const filteredNameSet = allFiltersArray.map(filterArray => { const resultSet = new Set(); filterArray.forEach(action => resultSet.add(action.name as string || "")); @@ -218,10 +270,11 @@ export const isExactlyOneSelected = (checkedList: TCheckedList) => { //--------------------------------------------------// -function mapStateToProps({multiselect, resources, favorites}: RootState) { +function mapStateToProps({auth, multiselect, resources, favorites}: RootState) { return { checkedList: multiselect.checkedList as TCheckedList, selectedUuid: isExactlyOneSelected(multiselect.checkedList), + user: auth.user, iconProps: { resources, favorites diff --git a/src/components/multiselect-toolbar/ms-toolbar-action-filters.ts b/src/components/multiselect-toolbar/ms-toolbar-action-filters.ts index 32453fd4..fdea4b96 100644 --- a/src/components/multiselect-toolbar/ms-toolbar-action-filters.ts +++ b/src/components/multiselect-toolbar/ms-toolbar-action-filters.ts @@ -4,56 +4,90 @@ import { MultiSelectMenuActionSet, MultiSelectMenuActionNames } from 'views-components/multiselect-toolbar/ms-menu-actions'; import { msCollectionActionSet } from 'views-components/multiselect-toolbar/ms-collection-action-set'; -import { msProjectActionSet, msProjectActionFilter, msReadOnlyProjectActionFilter, msFilterGroupActionFilter, msFrozenActionFilter } from 'views-components/multiselect-toolbar/ms-project-action-set'; +import { + msProjectActionSet, + msProjectActionFilter, + msReadOnlyProjectActionFilter, + msFilterGroupActionFilter, + msFrozenProjectActionFilter, +} from 'views-components/multiselect-toolbar/ms-project-action-set'; import { msProcessActionSet } from 'views-components/multiselect-toolbar/ms-process-action-set'; import { msWorkflowActionSet, msWorkflowActionFilter, msReadOnlyWorkflowActionFilter } from 'views-components/multiselect-toolbar/ms-workflow-action-set'; +import { ResourceKind } from 'models/resource'; -export type TMultiselectActionsFilters = Record]>; -const { - MOVE_TO, - REMOVE, -} = MultiSelectMenuActionNames; +const { MOVE_TO, REMOVE } = MultiSelectMenuActionNames; const allActionNames = (actionSet: MultiSelectMenuActionSet): Set => new Set(actionSet[0].map((action) => action.name)); -//use allActionNames or filter manually below - const processResourceMSActionsFilter = new Set([MOVE_TO, REMOVE]); -export enum msResourceKind { - API_CLIENT_AUTHORIZATION = "arvados#apiClientAuthorization", - COLLECTION = "arvados#collection", - CONTAINER = "arvados#container", - CONTAINER_REQUEST = "arvados#containerRequest", - GROUP = "arvados#group", - LINK = "arvados#link", - LOG = "arvados#log", - PROCESS = "arvados#containerRequest", - PROJECT = "arvados#group", - PROJECT_FROZEN = "arvados#group_frozen", - PROJECT_READONLY = "arvados#group_readonly", - PROJECT_FILTER = "arvados#group_filter", - REPOSITORY = "arvados#repository", - SSH_KEY = "arvados#authorizedKeys", - KEEP_SERVICE = "arvados#keepService", - USER = "arvados#user", - VIRTUAL_MACHINE = "arvados#virtualMachine", - WORKFLOW = "arvados#workflow", - WORKFLOW_READONLY = "arvados#workflow_readonly", - NONE = "arvados#none" +export enum msMenuResourceKind { + API_CLIENT_AUTHORIZATION = 'ApiClientAuthorization', + ROOT_PROJECT = 'RootProject', + PROJECT = 'Project', + FILTER_GROUP = 'FilterGroup', + READONLY_PROJECT = 'ReadOnlyProject', + FROZEN_PROJECT = 'FrozenProject', + FROZEN_PROJECT_ADMIN = 'FrozenProjectAdmin', + PROJECT_ADMIN = 'ProjectAdmin', + FILTER_GROUP_ADMIN = 'FilterGroupAdmin', + RESOURCE = 'Resource', + FAVORITE = 'Favorite', + TRASH = 'Trash', + COLLECTION_FILES = 'CollectionFiles', + COLLECTION_FILES_MULTIPLE = 'CollectionFilesMultiple', + READONLY_COLLECTION_FILES = 'ReadOnlyCollectionFiles', + READONLY_COLLECTION_FILES_MULTIPLE = 'ReadOnlyCollectionFilesMultiple', + COLLECTION_FILES_NOT_SELECTED = 'CollectionFilesNotSelected', + COLLECTION_FILE_ITEM = 'CollectionFileItem', + COLLECTION_DIRECTORY_ITEM = 'CollectionDirectoryItem', + READONLY_COLLECTION_FILE_ITEM = 'ReadOnlyCollectionFileItem', + READONLY_COLLECTION_DIRECTORY_ITEM = 'ReadOnlyCollectionDirectoryItem', + COLLECTION = 'Collection', + COLLECTION_ADMIN = 'CollectionAdmin', + READONLY_COLLECTION = 'ReadOnlyCollection', + OLD_VERSION_COLLECTION = 'OldVersionCollection', + TRASHED_COLLECTION = 'TrashedCollection', + PROCESS = 'Process', + RUNNING_PROCESS_ADMIN = 'RunningProcessAdmin', + PROCESS_ADMIN = 'ProcessAdmin', + RUNNING_PROCESS_RESOURCE = 'RunningProcessResource', + PROCESS_RESOURCE = 'ProcessResource', + READONLY_PROCESS_RESOURCE = 'ReadOnlyProcessResource', + PROCESS_LOGS = 'ProcessLogs', + REPOSITORY = 'Repository', + SSH_KEY = 'SshKey', + VIRTUAL_MACHINE = 'VirtualMachine', + KEEP_SERVICE = 'KeepService', + USER = 'User', + GROUPS = 'Group', + GROUP_MEMBER = 'GroupMember', + PERMISSION_EDIT = 'PermissionEdit', + LINK = 'Link', + WORKFLOW = 'Workflow', + READONLY_WORKFLOW = 'ReadOnlyWorkflow', + SEARCH_RESULTS = 'SearchResults', } -const { COLLECTION, PROCESS, PROJECT, PROJECT_FROZEN, PROJECT_READONLY, PROJECT_FILTER, WORKFLOW, WORKFLOW_READONLY } = msResourceKind; +const { COLLECTION, COLLECTION_ADMIN, PROCESS, PROCESS_ADMIN, PROJECT, PROJECT_ADMIN, FROZEN_PROJECT, FROZEN_PROJECT_ADMIN, READONLY_PROJECT, FILTER_GROUP, WORKFLOW, READONLY_WORKFLOW } = msMenuResourceKind; + +export type TMultiselectActionsFilters = Record]>; export const multiselectActionsFilters: TMultiselectActionsFilters = { [COLLECTION]: [msCollectionActionSet, allActionNames(msCollectionActionSet)], + [ResourceKind.COLLECTION]: [msCollectionActionSet, allActionNames(msCollectionActionSet)], + [COLLECTION_ADMIN]: [msCollectionActionSet, allActionNames(msCollectionActionSet)], [PROCESS]: [msProcessActionSet, processResourceMSActionsFilter], + [ResourceKind.PROCESS]: [msProcessActionSet, processResourceMSActionsFilter], + [PROCESS_ADMIN]: [msProcessActionSet, processResourceMSActionsFilter], [PROJECT]: [msProjectActionSet, msProjectActionFilter], - [PROJECT_FROZEN]: [msProjectActionSet, msFrozenActionFilter], - [PROJECT_READONLY]: [msProjectActionSet, msReadOnlyProjectActionFilter], - [PROJECT_FILTER]: [msProjectActionSet, msFilterGroupActionFilter], + [ResourceKind.PROJECT]: [msProjectActionSet, msProjectActionFilter], + [PROJECT_ADMIN]: [msProjectActionSet, allActionNames(msProjectActionSet)], + [FROZEN_PROJECT]: [msProjectActionSet, msFrozenProjectActionFilter], + [FROZEN_PROJECT_ADMIN]: [msProjectActionSet, msFrozenProjectActionFilter], + [READONLY_PROJECT]: [msProjectActionSet, msReadOnlyProjectActionFilter], + [FILTER_GROUP]: [msProjectActionSet, msFilterGroupActionFilter], [WORKFLOW]: [msWorkflowActionSet, msWorkflowActionFilter], - [WORKFLOW_READONLY]: [msWorkflowActionSet, msReadOnlyWorkflowActionFilter] + [READONLY_WORKFLOW]: [msWorkflowActionSet, msReadOnlyWorkflowActionFilter], }; - diff --git a/src/views-components/multiselect-toolbar/ms-project-action-set.ts b/src/views-components/multiselect-toolbar/ms-project-action-set.ts index d5076ba7..da20584f 100644 --- a/src/views-components/multiselect-toolbar/ms-project-action-set.ts +++ b/src/views-components/multiselect-toolbar/ms-project-action-set.ts @@ -125,5 +125,5 @@ export const msProjectActionFilter = new Set([ VIEW_DETAILS, ]); export const msReadOnlyProjectActionFilter = new Set([ADD_TO_FAVORITES, OPEN_IN_NEW_TAB, COPY_TO_CLIPBOARD, VIEW_DETAILS, API_DETAILS, OPEN_W_3RD_PARTY_CLIENT]); -export const msFrozenActionFilter = new Set([ADD_TO_FAVORITES, OPEN_IN_NEW_TAB, COPY_TO_CLIPBOARD, VIEW_DETAILS, API_DETAILS, OPEN_W_3RD_PARTY_CLIENT, SHARE, FREEZE_PROJECT]) +export const msFrozenProjectActionFilter = new Set([ADD_TO_FAVORITES, OPEN_IN_NEW_TAB, COPY_TO_CLIPBOARD, VIEW_DETAILS, API_DETAILS, OPEN_W_3RD_PARTY_CLIENT, SHARE, FREEZE_PROJECT]) export const msFilterGroupActionFilter = new Set([ADD_TO_FAVORITES, OPEN_IN_NEW_TAB, COPY_TO_CLIPBOARD, VIEW_DETAILS, API_DETAILS, OPEN_W_3RD_PARTY_CLIENT, EDIT_PPROJECT, SHARE, MOVE_TO, ADD_TO_TRASH])