X-Git-Url: https://git.arvados.org/arvados-workbench2.git/blobdiff_plain/4b15593e83bf1a6e1c84c1e18af4b11b9fa1d134..bead3b2896eaaceb9b9a3c805d40e8048c93b218:/src/components/multiselect-toolbar/MultiselectToolbar.tsx diff --git a/src/components/multiselect-toolbar/MultiselectToolbar.tsx b/src/components/multiselect-toolbar/MultiselectToolbar.tsx index b726cfa0..72d375ff 100644 --- a/src/components/multiselect-toolbar/MultiselectToolbar.tsx +++ b/src/components/multiselect-toolbar/MultiselectToolbar.tsx @@ -13,12 +13,14 @@ import { ContextMenuResource } from "store/context-menu/context-menu-actions"; import { Resource, extractUuidKind } from "models/resource"; import { getResource } from "store/resources/resources"; import { ResourcesState } from "store/resources/resources"; -import { ContextMenuAction, ContextMenuActionSet } from "views-components/context-menu/context-menu-action-set"; -import { RestoreFromTrashIcon, TrashIcon } from "components/icon/icon"; -import { multiselectActionsFilters, TMultiselectActionsFilters, contextMenuActionConsts } from "./ms-toolbar-action-filters"; +import { MultiSelectMenuAction, MultiSelectMenuActionSet, MultiSelectMenuActionNames } from "views-components/multiselect-toolbar/ms-menu-action-set"; +import { ContextMenuAction } from "views-components/context-menu/context-menu-action-set"; +import { multiselectActionsFilters, TMultiselectActionsFilters } from "./ms-toolbar-action-filters"; import { kindToActionSet, findActionByName } from "./ms-kind-action-differentiator"; -import { toggleTrashAction } from "views-components/context-menu/action-sets/project-action-set"; +import { msToggleTrashAction } from "views-components/multiselect-toolbar/ms-project-action-set"; import { copyToClipboardAction } from "store/open-in-new-tab/open-in-new-tab.actions"; +import { ContainerRequestResource } from "models/container-request"; +import { FavoritesState } from "store/favorites/favorites-reducer"; type CssRules = "root" | "button"; @@ -29,69 +31,79 @@ const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ width: 0, padding: 0, margin: "1rem auto auto 0.5rem", - overflow: "hidden", + overflowY: 'scroll', transition: "width 150ms", }, button: { - width: "1rem", - margin: "auto 5px", + width: "2.5rem", + height: "2.5rem ", }, }); export type MultiselectToolbarProps = { - isVisible: boolean; checkedList: TCheckedList; - resources: ResourcesState; + selectedUuid: string | null + iconProps: IconProps executeMulti: (action: ContextMenuAction, checkedList: TCheckedList, resources: ResourcesState) => void; }; +type IconProps = { + resources: ResourcesState; + favorites: FavoritesState +} + export const MultiselectToolbar = connect( mapStateToProps, mapDispatchToProps )( withStyles(styles)((props: MultiselectToolbarProps & WithStyles) => { - const { classes, checkedList } = props; + const { classes, checkedList, selectedUuid: singleSelectedUuid, iconProps } = props; const currentResourceKinds = Array.from(selectedToKindSet(checkedList)); const currentPathIsTrash = window.location.pathname === "/trash"; - const buttons = + + const actions = currentPathIsTrash && selectedToKindSet(checkedList).size - ? [toggleTrashAction] - : selectActionsByKind(currentResourceKinds, multiselectActionsFilters); + ? [msToggleTrashAction] + : selectActionsByKind(currentResourceKinds, multiselectActionsFilters) + .filter((action) => (singleSelectedUuid === null ? action.isForMulti : true)); return ( - - {buttons.length ? ( - buttons.map((btn, i) => - btn.name === "ToggleTrashAction" ? ( - - props.executeMulti(btn, checkedList, props.resources)}> - {currentPathIsTrash ? : } - - - ) : ( - - props.executeMulti(btn, checkedList, props.resources)}> - {btn.icon ? btn.icon({}) : <>} - - + + + {actions.length ? ( + actions.map((action, i) => + action.hasAlts ? ( + + props.executeMulti(action, checkedList, iconProps.resources)}> + {currentPathIsTrash || action.useAlts(singleSelectedUuid, iconProps) ? action.altIcon && action.altIcon({}) : action.icon({})} + + + ) : ( + + props.executeMulti(action, checkedList, iconProps.resources)}>{action.icon({})} + + ) ) - ) - ) : ( - <> - )} - - ); + ) : ( + <> + )} + + + ) }) ); @@ -118,21 +130,21 @@ export function selectedToKindSet(checkedList: TCheckedList): Set { function groupByKind(checkedList: TCheckedList, resources: ResourcesState): Record { const result = {}; selectedToArray(checkedList).forEach(uuid => { - const resource = getResource(uuid)(resources) as Resource; + const resource = getResource(uuid)(resources) as ContainerRequestResource | Resource; if (!result[resource.kind]) result[resource.kind] = []; result[resource.kind].push(resource); }); return result; } -function filterActions(actionArray: ContextMenuActionSet, filters: Set): Array { +function filterActions(actionArray: MultiSelectMenuActionSet, filters: Set): Array { return actionArray[0].filter(action => filters.has(action.name as string)); } function selectActionsByKind(currentResourceKinds: Array, filterSet: TMultiselectActionsFilters) { - const rawResult: Set = new Set(); + const rawResult: Set = new Set(); const resultNames = new Set(); - const allFiltersArray: ContextMenuAction[][] = []; + const allFiltersArray: MultiSelectMenuAction[][] = [] currentResourceKinds.forEach(kind => { if (filterSet[kind]) { const actions = filterActions(...filterSet[kind]); @@ -147,14 +159,14 @@ function selectActionsByKind(currentResourceKinds: Array, filterSet: TMu }); const filteredNameSet = allFiltersArray.map(filterArray => { - const resultSet = new Set(); - filterArray.forEach(action => resultSet.add(action.name || "")); + const resultSet = new Set(); + filterArray.forEach(action => resultSet.add(action.name as string || "")); return resultSet; }); const filteredResult = Array.from(rawResult).filter(action => { for (let i = 0; i < filteredNameSet.length; i++) { - if (!filteredNameSet[i].has(action.name)) return false; + if (!filteredNameSet[i].has(action.name as string)) return false; } return true; }); @@ -172,15 +184,29 @@ function selectActionsByKind(currentResourceKinds: Array, filterSet: TMu }); } +export const isExactlyOneSelected = (checkedList: TCheckedList) => { + let tally = 0; + let current = ''; + for (const uuid in checkedList) { + if (checkedList[uuid] === true) { + tally++; + current = uuid; + } + } + return tally === 1 ? current : null +}; + //--------------------------------------------------// -function mapStateToProps(state: RootState) { - const { isVisible, checkedList } = state.multiselect; +function mapStateToProps({multiselect, resources, favorites}: RootState) { return { - isVisible: isVisible, - checkedList: checkedList as TCheckedList, - resources: state.resources, - }; + checkedList: multiselect.checkedList as TCheckedList, + selectedUuid: isExactlyOneSelected(multiselect.checkedList), + iconProps: { + resources, + favorites + } + } } function mapDispatchToProps(dispatch: Dispatch) { @@ -188,20 +214,19 @@ function mapDispatchToProps(dispatch: Dispatch) { executeMulti: (selectedAction: ContextMenuAction, checkedList: TCheckedList, resources: ResourcesState): void => { const kindGroups = groupByKind(checkedList, resources); switch (selectedAction.name) { - case contextMenuActionConsts.MOVE_TO: - case contextMenuActionConsts.REMOVE: - const firstResource = getResource(selectedToArray(checkedList)[0])(resources) as Resource; + case MultiSelectMenuActionNames.MOVE_TO: + case MultiSelectMenuActionNames.REMOVE: + const firstResource = getResource(selectedToArray(checkedList)[0])(resources) as ContainerRequestResource | Resource; const action = findActionByName(selectedAction.name as string, kindToActionSet[firstResource.kind]); if (action) action.execute(dispatch, kindGroups[firstResource.kind]); break; - case contextMenuActionConsts.COPY_TO_CLIPBOARD: + case MultiSelectMenuActionNames.COPY_TO_CLIPBOARD: const selectedResources = selectedToArray(checkedList).map(uuid => getResource(uuid)(resources)); dispatch(copyToClipboardAction(selectedResources)); break; default: for (const kind in kindGroups) { const action = findActionByName(selectedAction.name as string, kindToActionSet[kind]); - console.log(action, kindGroups[kind]); if (action) action.execute(dispatch, kindGroups[kind]); } break;