21128: multiselect vs details panel resolved Arvados-DCO-1.1-Signed-off-by: Lisa...
authorLisa Knox <lisaknox83@gmail.com>
Wed, 22 Nov 2023 15:43:27 +0000 (10:43 -0500)
committerLisa Knox <lisaknox83@gmail.com>
Wed, 22 Nov 2023 15:43:27 +0000 (10:43 -0500)
src/components/multiselect-toolbar/MultiselectToolbar.tsx
src/store/multiselect/multiselect-actions.tsx
src/store/multiselect/multiselect-reducer.tsx
src/views-components/data-explorer/data-explorer.tsx
src/views-components/details-panel/details-panel.tsx
src/views/all-processes-panel/all-processes-panel.tsx
src/views/favorite-panel/favorite-panel.tsx
src/views/project-panel/project-panel.tsx
src/views/shared-with-me-panel/shared-with-me-panel.tsx
src/views/trash-panel/trash-panel.tsx

index cb884932b30ed707d86457c9865b209616403d34..f2aeb9e92b43e85f75601807dc40a3c57a12b1f4 100644 (file)
@@ -184,7 +184,7 @@ function selectActionsByKind(currentResourceKinds: Array<string>, filterSet: TMu
     });
 }
 
-const isExactlyOneSelected = (checkedList: TCheckedList) => {
+export const isExactlyOneSelected = (checkedList: TCheckedList) => {
     let tally = 0;
     let current = '';
     for (const uuid in checkedList) {
index 6eef131dab65a2198e0b674734f49cf190220cf5..80ff543f2dcdbbe20bacfbb21efece103f0f57c4 100644 (file)
@@ -3,13 +3,15 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import { TCheckedList } from "components/data-table/data-table";
+import { isExactlyOneSelected } from "components/multiselect-toolbar/MultiselectToolbar";
 
 export const multiselectActionContants = {
     TOGGLE_VISIBLITY: "TOGGLE_VISIBLITY",
     SET_CHECKEDLIST: "SET_CHECKEDLIST",
     SELECT_ONE: 'SELECT_ONE',
     DESELECT_ONE: "DESELECT_ONE",
-    TOGGLE_ONE: 'TOGGLE_ONE'
+    TOGGLE_ONE: 'TOGGLE_ONE',
+    SET_SELECTED_UUID: 'SET_SELECTED_UUID'
 };
 
 export const toggleMSToolbar = (isVisible: boolean) => {
@@ -20,6 +22,7 @@ export const toggleMSToolbar = (isVisible: boolean) => {
 
 export const setCheckedListOnStore = (checkedList: TCheckedList) => {
     return dispatch => {
+        dispatch(setSelectedUuid(isExactlyOneSelected(checkedList)))
         dispatch({ type: multiselectActionContants.SET_CHECKEDLIST, payload: checkedList });
     };
 };
@@ -42,9 +45,17 @@ export const toggleOne = (uuid: string) => {
     };
 };
 
+export const setSelectedUuid = (uuid: string | null) => {
+    return dispatch => {
+        dispatch({ type: multiselectActionContants.SET_SELECTED_UUID, payload: uuid });
+    };
+};
+
 export const multiselectActions = {
     toggleMSToolbar,
     setCheckedListOnStore,
     selectOne,
     deselectOne,
+    toggleOne,
+    setSelectedUuid
 };
index 099a1b5bf836c9836ac8f143405edf8f1424112d..27f6b69224d0675646f1032c8f8eeac26771c8e1 100644 (file)
@@ -8,14 +8,16 @@ import { TCheckedList } from "components/data-table/data-table";
 type MultiselectToolbarState = {
     isVisible: boolean;
     checkedList: TCheckedList;
+    selectedUuid: string;
 };
 
 const multiselectToolbarInitialState = {
     isVisible: false,
     checkedList: {},
+    selectedUuid: '',
 };
 
-const { TOGGLE_VISIBLITY, SET_CHECKEDLIST, SELECT_ONE, DESELECT_ONE, TOGGLE_ONE } = multiselectActionContants;
+const { TOGGLE_VISIBLITY, SET_CHECKEDLIST, SELECT_ONE, DESELECT_ONE, TOGGLE_ONE, SET_SELECTED_UUID } = multiselectActionContants;
 
 export const multiselectReducer = (state: MultiselectToolbarState = multiselectToolbarInitialState, action) => {
     switch (action.type) {
@@ -29,6 +31,8 @@ export const multiselectReducer = (state: MultiselectToolbarState = multiselectT
             return { ...state, checkedList: { ...state.checkedList, [action.payload]: false } };
         case TOGGLE_ONE:
             return { ...state, checkedList: { ...state.checkedList, [action.payload]: !state.checkedList[action.payload] } };
+        case SET_SELECTED_UUID:
+            return {...state, selectedUuid: action.payload || ''}
         default:
             return state;
     }
index 55a254aba7f9ab791a44ab749d9a1e5781257667..6c9aeb06006b6c96ff0fc3126ae703bab0147602 100644 (file)
@@ -27,7 +27,8 @@ const mapStateToProps = (state: RootState, { id }: Props) => {
     const dataExplorerState = getDataExplorer(state.dataExplorer, id);
     const currentRoute = state.router.location ? state.router.location.pathname : "";
     const currentRefresh = localStorage.getItem(LAST_REFRESH_TIMESTAMP) || "";
-    const currentItemUuid = currentRoute === "/workflows" ? state.properties.workflowPanelDetailsUuid : state.detailsPanel.resourceUuid;
+    const isDetailsResourceChecked = state.multiselect.checkedList[state.detailsPanel.resourceUuid]
+    const currentItemUuid = currentRoute === "/workflows" ? state.properties.workflowPanelDetailsUuid : isDetailsResourceChecked ? state.detailsPanel.resourceUuid : state.multiselect.selectedUuid;
     const isMSToolbarVisible = state.multiselect.isVisible;
     return {
         ...dataExplorerState,
index e9175f57ba423e5069064db69876ddef15c97e1c..672d678f5b22d6fdf97166c477636813e4b2c75a 100644 (file)
@@ -83,8 +83,11 @@ const getItem = (res: DetailsResource): DetailsData => {
     }
 };
 
-const mapStateToProps = ({ auth, detailsPanel, resources, collectionPanelFiles }: RootState) => {
-    const resource = getResource(detailsPanel.resourceUuid)(resources) as DetailsResource | undefined;
+const mapStateToProps = ({ auth, detailsPanel, resources, collectionPanelFiles, multiselect, router }: RootState) => {
+    const isDetailsResourceChecked = multiselect.checkedList[detailsPanel.resourceUuid]
+    const currentRoute = router.location ? router.location.pathname : "";
+    const currentItemUuid = isDetailsResourceChecked ? detailsPanel.resourceUuid : multiselect.selectedUuid || currentRoute.split('/')[2];
+    const resource = getResource(currentItemUuid)(resources) as DetailsResource | undefined || '';
     const file = resource
         ? undefined
         : getNode(detailsPanel.resourceUuid)(collectionPanelFiles);
index ee53f99c3fe94e39c4fa2da096d8e7175d774223..e63ccae9bab75e2f2c48484a7277a4e9882e9c22 100644 (file)
@@ -31,6 +31,7 @@ import { createTree } from "models/tree";
 import { getInitialProcessStatusFilters, getInitialProcessTypeFilters } from "store/resource-type-filters/resource-type-filters";
 import { getProcess } from "store/processes/process";
 import { ResourcesState } from "store/resources/resources";
+import { selectOne } from "store/multiselect/multiselect-actions";
 
 type CssRules = "toolbar" | "button" | "root";
 
@@ -143,6 +144,7 @@ export const AllProcessesPanel = withStyles(styles)(
             };
 
             handleRowClick = (uuid: string) => {
+                this.props.dispatch<any>(selectOne(uuid))
                 this.props.dispatch<any>(loadDetailsPanel(uuid));
             };
 
index 2392d6fda0380cc2e0108fb8101ae952b18bcf31..16af9c084aa7b53cdd58f2be153af60ef9961f86 100644 (file)
@@ -38,6 +38,7 @@ import { GroupClass, GroupResource } from 'models/group';
 import { getProperty } from 'store/properties/properties';
 import { PROJECT_PANEL_CURRENT_UUID } from 'store/project-panel/project-panel-action';
 import { CollectionResource } from 'models/collection';
+import { selectOne } from 'store/multiselect/multiselect-actions';
 
 type CssRules = "toolbar" | "button" | "root";
 
@@ -171,6 +172,7 @@ export const FavoritePanel = withStyles(styles)(
             }
 
             handleRowClick = (uuid: string) => {
+                this.props.dispatch<any>(selectOne(uuid))
                 this.props.dispatch<any>(loadDetailsPanel(uuid));
             }
 
index 2cc751bffd6e78526b38ea07e8d0a5ca4d0683f2..a85455276f5214c0183d9bb116314df840cab94b 100644 (file)
@@ -52,6 +52,7 @@ import { CollectionResource } from 'models/collection';
 import { resourceIsFrozen } from 'common/frozen-resources';
 import { ProjectResource } from 'models/project';
 import { NotFoundView } from 'views/not-found-panel/not-found-panel';
+import { selectOne } from 'store/multiselect/multiselect-actions';
 
 type CssRules = 'root' | 'button';
 
@@ -323,6 +324,7 @@ export const ProjectPanel = withStyles(styles)(
             };
 
             handleRowClick = (uuid: string) => {
+                this.props.dispatch<any>(selectOne(uuid))
                 this.props.dispatch<any>(loadDetailsPanel(uuid));
             };
         }
index e6cfccd2694c4765570a76268e57cfa2d22d8c90..ece94ee247d9f8507d69c4de4714774663d549d9 100644 (file)
@@ -18,6 +18,7 @@ import {
     resourceUuidToContextMenuKind
 } from 'store/context-menu/context-menu-actions';
 import { GroupContentsResource } from 'services/groups-service/groups-service';
+import { selectOne } from 'store/multiselect/multiselect-actions';
 
 type CssRules = "toolbar" | "button" | "root";
 
@@ -82,6 +83,7 @@ export const SharedWithMePanel = withStyles(styles)(
             }
 
             handleRowClick = (uuid: string) => {
+                this.props.dispatch<any>(selectOne(uuid))
                 this.props.dispatch<any>(loadDetailsPanel(uuid));
             }
         }
index 350207510555ac30870e21dd19916e9399c27534..7b79143423c6d7d83ecb4ec0d6d248a6e5423d7b 100644 (file)
@@ -35,6 +35,7 @@ import {
     getTrashPanelTypeFilters
 } from 'store/resource-type-filters/resource-type-filters';
 import { CollectionResource } from 'models/collection';
+import { selectOne } from 'store/multiselect/multiselect-actions';
 
 type CssRules = "toolbar" | "button" | "root";
 
@@ -178,6 +179,7 @@ export const TrashPanel = withStyles(styles)(
             }
 
             handleRowClick = (uuid: string) => {
+                this.props.dispatch<any>(selectOne(uuid))
                 this.props.dispatch<any>(loadDetailsPanel(uuid));
             }
         }