Merge branch '21448-menu-reorder' into 21224-project-details
authorLisa Knox <lisaknox83@gmail.com>
Fri, 19 Apr 2024 18:40:16 +0000 (14:40 -0400)
committerLisa Knox <lisaknox83@gmail.com>
Fri, 19 Apr 2024 18:40:16 +0000 (14:40 -0400)
refs #21448

Arvados-DCO-1.1-Signed-off-by: Lisa Knox <lisa.knox@curii.com>

14 files changed:
1  2 
services/workbench2/cypress/e2e/details-card.spec.js
services/workbench2/src/components/data-explorer/data-explorer.tsx
services/workbench2/src/components/data-table/data-table.tsx
services/workbench2/src/components/multiselect-toolbar/MultiselectToolbar.tsx
services/workbench2/src/components/multiselect-toolbar/ms-toolbar-action-filters.ts
services/workbench2/src/components/multiselect-toolbar/ms-toolbar-overflow-wrapper.tsx
services/workbench2/src/index.tsx
services/workbench2/src/store/project-panel/project-panel-middleware-service.ts
services/workbench2/src/store/projects/project-lock-actions.ts
services/workbench2/src/store/store.ts
services/workbench2/src/views-components/data-explorer/data-explorer.tsx
services/workbench2/src/views-components/data-explorer/renderers.tsx
services/workbench2/src/views-components/multiselect-toolbar/ms-menu-actions.ts
services/workbench2/src/views/project-panel/project-panel.tsx

index 3fbfd97e22c60ae5486cdbd6222a9221bb386fd6,0000000000000000000000000000000000000000..3fbfd97e22c60ae5486cdbd6222a9221bb386fd6
mode 100644,000000..100644
--- /dev/null
index 979fe35c08de20e6b97c018458f06dffdb340f9e,ba710bc783e9ca6368c5355d042a3930e677af8b..4737ed06dc6e124eb9efabd931c1f95603e4f854
@@@ -248,7 -194,7 +204,7 @@@ export const DataExplorer = withStyles(
                                  </Grid>
                              )}
                              {!!progressBar && progressBar}
-                             {this.multiSelectToolbarInTitle && !this.state.msToolbarInDetailsCard && <MultiselectToolbar injectedStyles={classes.msToolbarStyles} />}
 -                            {this.multiSelectToolbarInTitle && <MultiselectToolbar />}
++                            {this.multiSelectToolbarInTitle && <MultiselectToolbar injectedStyles={classes.msToolbarStyles} />}
                              {(!hideColumnSelector || !hideSearchInput || !!actions) && (
                                  <Grid
                                      className={classes.headerMenu}
                                  onFiltersChange={onFiltersChange}
                                  onSortToggle={onSortToggle}
                                  extractKey={extractKey}
-                                 working={this.state.showLoading}
                                  defaultViewIcon={defaultViewIcon}
                                  defaultViewMessages={defaultViewMessages}
 -                                currentItemUuid={currentItemUuid}
                                  currentRoute={paperKey}
                                  toggleMSToolbar={toggleMSToolbar}
                                  setCheckedListOnStore={setCheckedListOnStore}
                                  checkedList={checkedList}
 +                                selectedResourceUuid={selectedResourceUuid}
 +                                setSelectedUuid={this.props.setSelectedUuid}
 +                                currentRouteUuid={this.props.currentRouteUuid}
+                                 working={working}
+                                 isNotFound={this.props.isNotFound}
                              />
                          </Grid>
                          <Grid
index 6e632e071a20b9361f01bd0852c78221226a68ad,7b787994577305ea5725b80fcfd942d42f34f360..e7a358580c77e8802e0b166d5b8bfd376bb9824b
@@@ -29,7 -29,7 +29,8 @@@ import { SvgIconProps } from "@material
  import ArrowDownwardIcon from "@material-ui/icons/ArrowDownward";
  import { createTree } from "models/tree";
  import { DataTableMultiselectOption } from "../data-table-multiselect-popover/data-table-multiselect-popover";
 +import { isExactlyOneSelected } from "store/multiselect/multiselect-actions";
+ import { PendingIcon } from "components/icon/icon";
  
  export type DataColumns<I, R> = Array<DataColumn<I, R>>;
  
@@@ -50,13 -50,12 +51,14 @@@ export interface DataTableDataProps<I> 
      working?: boolean;
      defaultViewIcon?: IconType;
      defaultViewMessages?: string[];
 -    currentItemUuid?: string;
 -    currentRoute?: string;
      toggleMSToolbar: (isVisible: boolean) => void;
      setCheckedListOnStore: (checkedList: TCheckedList) => void;
 +    currentRoute?: string;
 +    currentRouteUuid: string;
      checkedList: TCheckedList;
 +    selectedResourceUuid: string;
 +    setSelectedUuid: (uuid: string | null) => void;
+     isNotFound?: boolean;
  }
  
  type CssRules =
@@@ -175,15 -169,12 +173,21 @@@ export const DataTable = withStyles(sty
              if (prevProps.currentRoute !== this.props.currentRoute) {
                  this.initializeCheckedList([])
              }
 +            if (singleSelected && singleSelected !== isExactlyOneSelected(prevProps.checkedList)) {
 +                this.props.setSelectedUuid(singleSelected);
 +            }
 +            if (!singleSelected && !!currentRouteUuid && !this.isAnySelected()) {
 +                this.props.setSelectedUuid(currentRouteUuid);
 +            }
 +            if (!singleSelected && this.isAnySelected()) {
 +                this.props.setSelectedUuid(null);
 +            }
+             if(prevProps.working === true && this.props.working === false) {
+                 this.setState({ isLoaded: true });
+             }
+             if((this.props.items.length > 0) && !this.state.isLoaded) {
+                 this.setState({ isLoaded: true });
+             }
          }
  
          componentWillUnmount(): void {
index 137506e74354f53811f26fc43239694b31aa25f2,194950b134c9c0cf5d7f233909033b70ae16a01e..0d74b6b38ba40750d847134d55b4d7b252a5f946
@@@ -33,32 -32,22 +32,23 @@@ import { CollectionResource } from "mod
  import { getProcess } from "store/processes/process";
  import { Process } from "store/processes/process";
  import { PublicFavoritesState } from "store/public-favorites/public-favorites-reducer";
 -import { isExactlyOneSelected } from "store/multiselect/multiselect-actions";
 +import { AuthState } from "store/auth/auth-reducer";
  import { IntersectionObserverWrapper } from "./ms-toolbar-overflow-wrapper";
 +import classNames from "classnames";
+ import { ContextMenuKind, sortMenuItems, menuDirection } from 'views-components/context-menu/menu-item-sort';
  
- const WIDTH_TRANSITION = 150
- type CssRules = "root" | "transition" | "button" | "iconContainer" | "icon";
+ type CssRules = "root" | "button" | "iconContainer" | "icon" | "divider";
  
  const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
      root: {
          display: "flex",
          flexDirection: "row",
          width: 0,
 -        height: '2.7rem',
 +        height: '2.5rem',
          padding: 0,
-         transition: `width ${WIDTH_TRANSITION}ms`,
+         margin: "1rem auto auto 0.3rem",
          overflow: 'hidden',
      },
-     transition: {
-         display: "flex",
-         flexDirection: "row",
-         height: '2.5rem',
-         padding: 0,
-         overflow: 'hidden',
-         transition: `width ${WIDTH_TRANSITION}ms`,
-     },
      button: {
          width: "2.5rem",
          height: "2.5rem ",
@@@ -108,38 -86,24 +102,27 @@@ export const MultiselectToolbar = conne
      mapDispatchToProps
  )(
      withStyles(styles)((props: MultiselectToolbarProps & WithStyles<CssRules>) => {
 -        const { classes, checkedList, singleSelectedUuid, iconProps, user, disabledButtons } = props;
 -        const singleResourceKind = singleSelectedUuid ? [resourceToMsResourceKind(singleSelectedUuid, iconProps.resources, user)] : null
 +        const { classes, checkedList, iconProps, user, disabledButtons, location, isSubPanel, injectedStyles } = props;
 +        const selectedResourceUuid = isPathDisallowed(location) ? null : props.selectedResourceUuid;
 +        const singleResourceKind = selectedResourceUuid && !isSubPanel ? [resourceToMsResourceKind(selectedResourceUuid, iconProps.resources, user)] : null
          const currentResourceKinds = singleResourceKind ? singleResourceKind : Array.from(selectedToKindSet(checkedList));
-         const currentPathIsTrash = location.includes("/trash");
-         const [isTransitioning, setIsTransitioning] = useState(false);
-         let transitionTimeout;
-         
-         const handleTransition = () => {
-             setIsTransitioning(true)
-             transitionTimeout = setTimeout(() => {
-                 setIsTransitioning(false)
-             }, WIDTH_TRANSITION);
-         }
-         
-         useEffect(()=>{
-                 handleTransition()
-                 return () => {
-                     if(transitionTimeout) clearTimeout(transitionTimeout)
-                 };
-             // eslint-disable-next-line
-         }, [checkedList])
+         const currentPathIsTrash = window.location.pathname === "/trash";
  
-         const actions =
+         const rawActions =
              currentPathIsTrash && selectedToKindSet(checkedList).size
                  ? [msToggleTrashAction]
                  : selectActionsByKind(currentResourceKinds as string[], multiselectActionsFilters).filter((action) =>
 -                        singleSelectedUuid === null ? action.isForMulti : true
 +                        selectedResourceUuid === null ? action.isForMulti : true
                      );
+                     
+         const actions: ContextMenuAction[] | MultiSelectMenuAction[] = sortMenuItems(
+             singleResourceKind && singleResourceKind.length ? (singleResourceKind[0] as ContextMenuKind) : ContextMenuKind.MULTI,
+             rawActions,
+             menuDirection.HORIZONTAL
+         ); 
  
 +        const targetResources = selectedResourceUuid ? {[selectedResourceUuid]: true} as TCheckedList : checkedList
 +
          return (
              <React.Fragment>
                  <Toolbar
                                  <Tooltip
                                      className={classes.button}
                                      data-targetid={name}
 -                                    title={currentPathIsTrash || (useAlts && useAlts(singleSelectedUuid, iconProps)) ? altName : name}
 +                                    title={currentPathIsTrash || (useAlts && useAlts(selectedResourceUuid, iconProps)) ? altName : name}
                                      key={i}
                                      disableFocusListener
-                                     >
+                                 >
                                      <span className={classes.iconContainer}>
                                          <IconButton
                                              data-cy='multiselect-button'
@@@ -278,19 -251,19 +271,19 @@@ const resourceToMsResourceKind = (uuid
          case ResourceKind.PROCESS:
              return isAdmin && isEditable
                  ? resource && isProcessCancelable(getProcess(resource.uuid)(resources) as Process)
-                     ? msMenuResourceKind.RUNNING_PROCESS_ADMIN
-                     : msMenuResourceKind.PROCESS_ADMIN
+                     ? ContextMenuKind.RUNNING_PROCESS_ADMIN
+                     : ContextMenuKind.PROCESS_ADMIN
                  : readonly
-                 ? msMenuResourceKind.READONLY_PROCESS_RESOURCE
+                 ? ContextMenuKind.READONLY_PROCESS_RESOURCE
                  : resource && isProcessCancelable(getProcess(resource.uuid)(resources) as Process)
-                 ? msMenuResourceKind.RUNNING_PROCESS_RESOURCE
-                 : msMenuResourceKind.PROCESS_RESOURCE;
+                 ? ContextMenuKind.RUNNING_PROCESS_RESOURCE
+                 : ContextMenuKind.PROCESS_RESOURCE;
          case ResourceKind.USER:
-             return isAdmin ? msMenuResourceKind.ROOT_PROJECT_ADMIN : msMenuResourceKind.ROOT_PROJECT;
 -            return ContextMenuKind.ROOT_PROJECT;
++            return isAdmin ? ContextMenuKind.ROOT_PROJECT_ADMIN : ContextMenuKind.ROOT_PROJECT;
          case ResourceKind.LINK:
-             return msMenuResourceKind.LINK;
+             return ContextMenuKind.LINK;
          case ResourceKind.WORKFLOW:
-             return isEditable ? msMenuResourceKind.WORKFLOW : msMenuResourceKind.READONLY_WORKFLOW;
+             return isEditable ? ContextMenuKind.WORKFLOW : ContextMenuKind.READONLY_WORKFLOW;
          default:
              return;
      }
@@@ -362,11 -323,10 +345,11 @@@ function mapDispatchToProps(dispatch: D
      return {
          executeMulti: (selectedAction: ContextMenuAction, checkedList: TCheckedList, resources: ResourcesState): void => {
              const kindGroups = groupByKind(checkedList, resources);
 +            const currentList = selectedToArray(checkedList)
              switch (selectedAction.name) {
-                 case MultiSelectMenuActionNames.MOVE_TO:
-                 case MultiSelectMenuActionNames.REMOVE:
-                     const firstResource = getResource(currentList[0])(resources) as ContainerRequestResource | Resource;
+                 case ContextMenuActionNames.MOVE_TO:
+                 case ContextMenuActionNames.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;
index f7397a5d4edaca716863ee0288ebf0e8366ae815,2b30525e56499c95216b24d9eb0176d560149f6a..9af91daa531ce8ebfbc19b491fafdb78043f3291
@@@ -15,57 -15,8 +15,9 @@@ import 
  } from 'views-components/multiselect-toolbar/ms-project-action-set';
  import { msProcessActionSet, msCommonProcessActionFilter, msAdminProcessActionFilter, msRunningProcessActionFilter } from 'views-components/multiselect-toolbar/ms-process-action-set';
  import { msWorkflowActionSet, msWorkflowActionFilter, msReadOnlyWorkflowActionFilter } from 'views-components/multiselect-toolbar/ms-workflow-action-set';
 +import { UserDetailsActionSet } from 'views-components/multiselect-toolbar/ms-user-details-action-set';
  import { ResourceKind } from 'models/resource';
- export enum msMenuResourceKind {
-     API_CLIENT_AUTHORIZATION = 'ApiClientAuthorization',
-     ROOT_PROJECT = 'RootProject',
-     ROOT_PROJECT_ADMIN = 'RootProjectAdmin',
-     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',
- }
+ import { ContextMenuKind } from 'views-components/context-menu/menu-item-sort';
  
  const {
      COLLECTION,
Simple merge
index 5c356b5b969f52c156e8d2e55921cf595bad4e80,e8d03dfcd76ef6df186a9ab78acc87b692e09178..61c89cd6a78ea76331fbb89aad8aeac9fddf7c47
@@@ -54,9 -55,10 +55,10 @@@ export class ProjectPanelMiddlewareServ
              api.dispatch(projectPanelDataExplorerIsNotSet());
          } else {
              try {
+                 api.dispatch<any>(dataExplorerActions.SET_IS_NOT_FOUND({ id: this.id, isNotFound: false }));
                  if (!background) { api.dispatch(progressIndicatorActions.START_WORKING(this.getId())); }
                  const response = await this.services.groupsService.contents(projectUuid, getParams(dataExplorer, !!isProjectTrashed));
 -                const resourceUuids = response.items.map(item => item.uuid);
 +                const resourceUuids = [...response.items.map(item => item.uuid), projectUuid];
                  api.dispatch<any>(updateFavorites(resourceUuids));
                  api.dispatch<any>(updatePublicFavorites(resourceUuids));
                  api.dispatch(updateResources(response.items));
index d4e633de84860ab6189ed900f549be747f00c3d2,cd72e351964f0d110d95127459e90d8d972a862f..84cea4380954e226be50a8665ce695023fc32c4a
@@@ -7,33 -7,25 +7,33 @@@ import { ServiceRepository } from "serv
  import { projectPanelActions } from "store/project-panel/project-panel-action-bind";
  import { loadResource } from "store/resources/resources-actions";
  import { RootState } from "store/store";
- import { MultiSelectMenuActionNames } from "views-components/multiselect-toolbar/ms-menu-actions";
+ import { ContextMenuActionNames } from "views-components/context-menu/context-menu-action-set"; 
  import { addDisabledButton, removeDisabledButton } from "store/multiselect/multiselect-actions";
 +import { snackbarActions, SnackbarKind } from "store/snackbar/snackbar-actions";
  
  export const freezeProject = (uuid: string) => async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
-     dispatch<any>(addDisabledButton(MultiSelectMenuActionNames.FREEZE_PROJECT))
+     dispatch<any>(addDisabledButton(ContextMenuActionNames.FREEZE_PROJECT))
      const userUUID = getState().auth.user!.uuid;
 -    
 -    const updatedProject = await services.projectService.update(uuid, {
 -        frozenByUuid: userUUID,
 -    });
 -    
 +    let updatedProject;
 +
 +    try {
 +        updatedProject = await services.projectService.update(uuid, {
 +            frozenByUuid: userUUID,
 +        });
 +    } catch (e) {
 +        console.error(e);
 +        dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Could not freeze project', hideDuration: 4000, kind: SnackbarKind.ERROR }));
 +    }
 +
      dispatch(projectPanelActions.REQUEST_ITEMS());
      dispatch<any>(loadResource(uuid, false));
-     dispatch<any>(removeDisabledButton(MultiSelectMenuActionNames.FREEZE_PROJECT))
+     dispatch<any>(removeDisabledButton(ContextMenuActionNames.FREEZE_PROJECT))
      return updatedProject;
  };
  
 +
  export const unfreezeProject = (uuid: string) => async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
-     dispatch<any>(addDisabledButton(MultiSelectMenuActionNames.FREEZE_PROJECT))
+     dispatch<any>(addDisabledButton(ContextMenuActionNames.FREEZE_PROJECT))
      const updatedProject = await services.projectService.update(uuid, {
          frozenByUuid: null,
      });
index 1b62c8dc5d7a70d513ddcd10f7cd488a078f1ce4,643949a20e0545169dac1aa6359705ccc6b86919..034399b124765d9c1af4bb3aa7410a128a699829
@@@ -11,9 -11,7 +11,8 @@@ import { dataExplorerActions } from "st
  import { DataColumn } from "components/data-table/data-column";
  import { DataColumns, TCheckedList } from "components/data-table/data-table";
  import { DataTableFilters } from "components/data-table-filters/data-table-filters-tree";
- import { LAST_REFRESH_TIMESTAMP } from "components/refresh-button/refresh-button";
  import { toggleMSToolbar, setCheckedListOnStore } from "store/multiselect/multiselect-actions";
 +import { setSelectedResourceUuid } from "store/selected-resource/selected-resource-actions";
  
  interface Props {
      id: string;
      onContextMenu?: (event: React.MouseEvent<HTMLElement>, item: any, isAdmin?: boolean) => void;
      onRowDoubleClick: (item: any) => void;
      extractKey?: (item: any) => React.Key;
+     working?: boolean;
  }
  
- const mapStateToProps = ({ progressIndicator, dataExplorer, router, multiselect, properties, selectedResourceUuid}: RootState, { id }: Props) => {
-     const progress = progressIndicator.find(p => p.id === id);
+ const mapStateToProps = ({ progressIndicator, dataExplorer, router, multiselect, detailsPanel, properties}: RootState, { id }: Props) => {
+     const working = !!progressIndicator.some(p => p.id === id && p.working);
      const dataExplorerState = getDataExplorer(dataExplorer, id);
      const currentRoute = router.location ? router.location.pathname : "";
-     const currentRefresh = localStorage.getItem(LAST_REFRESH_TIMESTAMP) || "";
 -    const isDetailsResourceChecked = multiselect.checkedList[detailsPanel.resourceUuid]
 -    const isOnlyOneSelected = Object.values(multiselect.checkedList).filter(x => x === true).length === 1;
 -    const currentItemUuid =
 -        currentRoute === '/workflows' ? properties.workflowPanelDetailsUuid : isDetailsResourceChecked && isOnlyOneSelected ? detailsPanel.resourceUuid : multiselect.selectedUuid;
      const isMSToolbarVisible = multiselect.isVisible;
      return {
          ...dataExplorerState,
-         working: !!progress?.working,
-         currentRefresh: currentRefresh,
          currentRoute: currentRoute,
          paperKey: currentRoute,
 -        currentItemUuid,
 +        currentRouteUuid: properties.currentRouteUuid,
-         selectedResourceUuid: selectedResourceUuid,
          isMSToolbarVisible,
          checkedList: multiselect.checkedList,
+         working,
      };
  };
  
index 45565c4a224a27fb3fc5b78a87a5f431582e5804,91b06c2b2f0a9e22d0d407422d4c2b0fc4636729..bb49b6cf42e5cc25b9a06647d301a8562e92d7dc
@@@ -52,18 -54,7 +53,19 @@@ import { VirtualMachinesResource } fro
  import { CopyToClipboardSnackbar } from "components/copy-to-clipboard-snackbar/copy-to-clipboard-snackbar";
  import { ProjectResource } from "models/project";
  import { ProcessResource } from "models/process";
 +import { ServiceRepository } from "services/services";
 +import { loadUsersPanel } from "store/users/users-actions";
 +
 +export const toggleIsAdmin = (uuid: string) =>
 +    async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
 +        const { resources } = getState();
 +        const data = getResource<UserResource>(uuid)(resources);
 +        const isAdmin = data!.isAdmin;
 +        const newActivity = await services.userService.update(uuid, { isAdmin: !isAdmin });
 +        dispatch<any>(loadUsersPanel());
 +        return newActivity;
 +    };
+ import { InlinePulser } from "components/loading/inline-pulser";
  
  const renderName = (dispatch: Dispatch, item: GroupContentsResource) => {
      const navFunc = "groupClass" in item && item.groupClass === GroupClass.ROLE ? navigateToGroupDetails : navigateTo;
index 85ae063a7917e1d2dae9c809a7465557fb2a5966,2ddfca8178577e8402041bfbb3807968ea7a91af..0425335e4212b5b9942ed8f337ea60b2c7ad5f83
@@@ -51,11 -51,9 +51,10 @@@ import { GroupClass, GroupResource } fr
  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 { deselectAllOthers, toggleOne } from 'store/multiselect/multiselect-actions';
 +import { ProjectDetailsCard } from 'views-components/project-details-card/project-details-card';
  
- type CssRules = 'root' | 'button';
+ type CssRules = 'root' | 'button' ;
  
  const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
      root: {
@@@ -265,27 -262,20 +265,22 @@@ const mapStateToProps = (state: RootSta
  export const ProjectPanel = withStyles(styles)(
      connect(mapStateToProps)(
          class extends React.Component<ProjectPanelProps> {
              render() {
                  const { classes } = this.props;
-                 return this.props.project ?
-                     <div data-cy='project-panel' className={classes.root}>
-                         <ProjectDetailsCard />
-                         <DataExplorer
-                             id={PROJECT_PANEL_ID}
-                             onRowClick={this.handleRowClick}
-                             onRowDoubleClick={this.handleRowDoubleClick}
-                             onContextMenu={this.handleContextMenu}
-                             contextMenuColumn={true}
-                             defaultViewIcon={ProjectIcon}
-                             defaultViewMessages={DEFAULT_VIEW_MESSAGES}
-                         />
-                     </div>
-                     :
-                     <NotFoundView
-                         icon={ProjectIcon}
-                         messages={["Project not found"]}
+                 return <div data-cy='project-panel' className={classes.root}>
++                    <ProjectDetailsCard />
+                     <DataExplorer
+                         id={PROJECT_PANEL_ID}
+                         onRowClick={this.handleRowClick}
+                         onRowDoubleClick={this.handleRowDoubleClick}
+                         onContextMenu={this.handleContextMenu}
+                         contextMenuColumn={true}
+                         defaultViewIcon={ProjectIcon}
+                         defaultViewMessages={DEFAULT_VIEW_MESSAGES}
++                        selectedResourceUuid={this.props.currentItemId}
                      />
+                 </div>
              }
  
              isCurrentItemChild = (resource: Resource) => {