[ARVADOS-WORKBENCH2] created: 1.2.0-803-ge27f8f0

Git user git at public.curoverse.com
Thu Nov 1 16:19:52 EDT 2018


        at  e27f8f04d6df30bfb0e8c3ccb99440d2e3c4900d (commit)


commit e27f8f04d6df30bfb0e8c3ccb99440d2e3c4900d
Author: Michal Klobukowski <michal.klobukowski at contractors.roche.com>
Date:   Thu Nov 1 21:19:44 2018 +0100

    Restore navigation from side panel
    
    Feature #14252
    
    Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski <michal.klobukowski at contractors.roche.com>

diff --git a/src/store/side-panel-tree/side-panel-trees-actions.ts b/src/store/side-panel-tree/side-panel-trees-actions.ts
index 214e234..c19b5f5 100644
--- a/src/store/side-panel-tree/side-panel-trees-actions.ts
+++ b/src/store/side-panel-tree/side-panel-trees-actions.ts
@@ -5,6 +5,7 @@
 import { Dispatch } from 'redux';
 import { initSharedProject, initUserProject, receiveTreePickerData } from '../tree-picker/tree-picker-actions';
 import { TreeNodeStatus } from '~/models/tree';
+import { values, includes, __ } from 'lodash/fp';
 
 export enum SidePanelTreeId {
     HOME = 'sidePanelUserTree',
@@ -15,6 +16,8 @@ export enum SidePanelTreeId {
     TRASH = 'sidePanelTrashTree',
 }
 
+export const isSidePanelTreeId = includes(__, values(SidePanelTreeId));
+
 export const initSidePanelTrees = (dispatch: Dispatch<any>) => {
     dispatch(initUserProject(SidePanelTreeId.HOME));
     dispatch(initSharedProject(SidePanelTreeId.SHARED));
@@ -28,7 +31,7 @@ const initSidePanelTree = (pickerId: string, name: string) =>
     receiveTreePickerData({
         id: '',
         pickerId,
-        data: [{ uuid: name, name }],
+        data: [{ uuid: pickerId, name }],
         extractNodeData: value => ({
             id: value.uuid,
             status: TreeNodeStatus.LOADED,
diff --git a/src/store/side-panel/side-panel-action.ts b/src/store/side-panel/side-panel-action.ts
index fd08ee1..d5bbb48 100644
--- a/src/store/side-panel/side-panel-action.ts
+++ b/src/store/side-panel/side-panel-action.ts
@@ -3,13 +3,13 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import { Dispatch } from 'redux';
-import { isSidePanelTreeCategory, SidePanelTreeCategory } from '~/store/side-panel-tree/side-panel-tree-actions';
 import { navigateToFavorites, navigateTo, navigateToTrash, navigateToSharedWithMe, navigateToWorkflows } from '../navigation/navigation-action';
 import { snackbarActions } from '~/store/snackbar/snackbar-actions';
+import { SidePanelTreeId, isSidePanelTreeId } from '~/store/side-panel-tree/side-panel-trees-actions';
 
 export const navigateFromSidePanel = (id: string) =>
     (dispatch: Dispatch) => {
-        if (isSidePanelTreeCategory(id)) {
+        if (isSidePanelTreeId(id)) {
             dispatch<any>(getSidePanelTreeCategoryAction(id));
         } else {
             dispatch<any>(navigateTo(id));
@@ -18,13 +18,13 @@ export const navigateFromSidePanel = (id: string) =>
 
 const getSidePanelTreeCategoryAction = (id: string) => {
     switch (id) {
-        case SidePanelTreeCategory.FAVORITES:
+        case SidePanelTreeId.FAVORITES:
             return navigateToFavorites;
-        case SidePanelTreeCategory.TRASH:
+        case SidePanelTreeId.TRASH:
             return navigateToTrash;
-        case SidePanelTreeCategory.SHARED_WITH_ME:
+        case SidePanelTreeId.SHARED:
             return navigateToSharedWithMe;
-        case SidePanelTreeCategory.WORKFLOWS:
+        case SidePanelTreeId.WORKFLOWS:
             return navigateToWorkflows;
         default:
             return sidePanelTreeCategoryNotAvailable(id);
diff --git a/src/views-components/projects-tree-picker/generic-projects-tree-picker.tsx b/src/views-components/projects-tree-picker/generic-projects-tree-picker.tsx
index d8a5d49..2aafa77 100644
--- a/src/views-components/projects-tree-picker/generic-projects-tree-picker.tsx
+++ b/src/views-components/projects-tree-picker/generic-projects-tree-picker.tsx
@@ -29,6 +29,7 @@ export interface ProjectsTreePickerDataProps {
     includeFiles?: boolean;
     rootItemIcon: IconType;
     showSelection?: boolean;
+    openOnActivation?: boolean;
     relatedTreePickers?: string[];
     loadRootItem: (item: TreeItem<ProjectsTreePickerRootItem>, pickerId: string, includeCollections?: boolean, inlcudeFiles?: boolean) => void;
 }
@@ -40,39 +41,66 @@ const mapStateToProps = (_: any, { rootItemIcon, showSelection }: ProjectsTreePi
     showSelection: isSelectionVisible(showSelection),
 });
 
-const mapDispatchToProps = (dispatch: Dispatch, { loadRootItem, includeCollections, includeFiles, relatedTreePickers, ...props }: ProjectsTreePickerProps): PickedTreePickerProps => ({
-    onContextMenu: () => { return; },
-    toggleItemActive: (event, item, pickerId) => {
-        dispatch(treePickerActions.ACTIVATE_TREE_PICKER_NODE({ id: item.id, pickerId, relatedTreePickers }));
-        if (props.toggleItemActive) {
-            props.toggleItemActive(event, item, pickerId);
-        }
-    },
-    toggleItemOpen: (_, item, pickerId) => {
-        const { id, data, status } = item;
-        if (status === TreeItemStatus.INITIAL) {
-            if ('kind' in data) {
-                dispatch<any>(
-                    data.kind === ResourceKind.COLLECTION
-                        ? loadCollection(id, pickerId)
-                        : loadProject({ id, pickerId, includeCollections, includeFiles })
-                );
-            } else if (!('type' in data) && loadRootItem) {
-                loadRootItem(item as TreeItem<ProjectsTreePickerRootItem>, pickerId, includeCollections, includeFiles);
+const mapDispatchToProps = (dispatch: Dispatch, {
+    loadRootItem,
+    includeCollections,
+    includeFiles,
+    relatedTreePickers,
+    ...props }: ProjectsTreePickerProps): PickedTreePickerProps => ({
+        onContextMenu: () => { return; },
+        toggleItemActive: (event, item, pickerId) => {
+            dispatch(treePickerActions.ACTIVATE_TREE_PICKER_NODE({ id: item.id, pickerId, relatedTreePickers }));
+            if (props.toggleItemActive) {
+                props.toggleItemActive(event, item, pickerId);
             }
-        } else if (status === TreeItemStatus.LOADED) {
-            dispatch(treePickerActions.TOGGLE_TREE_PICKER_NODE_COLLAPSE({ id, pickerId }));
-        }
-    },
-    toggleItemSelection: (event, item, pickerId) => {
-        dispatch<any>(treePickerActions.TOGGLE_TREE_PICKER_NODE_SELECTION({ id: item.id, pickerId }));
-        if (props.toggleItemSelection) {
-            props.toggleItemSelection(event, item, pickerId);
+        },
+        toggleItemOpen: (_, item, pickerId) => {
+            const { id, data, status } = item;
+            if (status === TreeItemStatus.INITIAL) {
+                if ('kind' in data) {
+                    dispatch<any>(
+                        data.kind === ResourceKind.COLLECTION
+                            ? loadCollection(id, pickerId)
+                            : loadProject({ id, pickerId, includeCollections, includeFiles })
+                    );
+                } else if (!('type' in data) && loadRootItem) {
+                    loadRootItem(item as TreeItem<ProjectsTreePickerRootItem>, pickerId, includeCollections, includeFiles);
+                }
+            } else if (status === TreeItemStatus.LOADED) {
+                dispatch(treePickerActions.TOGGLE_TREE_PICKER_NODE_COLLAPSE({ id, pickerId }));
+            }
+        },
+        toggleItemSelection: (event, item, pickerId) => {
+            dispatch<any>(treePickerActions.TOGGLE_TREE_PICKER_NODE_SELECTION({ id: item.id, pickerId }));
+            if (props.toggleItemSelection) {
+                props.toggleItemSelection(event, item, pickerId);
+            }
+        },
+    });
+
+const mergeProps = (
+    stateProps: ReturnType<typeof mapStateToProps>,
+    dispatchProps: ReturnType<typeof mapDispatchToProps>,
+    ownProps: ProjectsTreePickerProps) => ({
+        ...stateProps,
+        ...dispatchProps,
+        ...ownProps,
+        ...mergeToggleItemActive(dispatchProps, ownProps),
+    });
+
+const mergeToggleItemActive = (
+    dispatchProps: ReturnType<typeof mapDispatchToProps>,
+    ownProps: ProjectsTreePickerProps
+): Partial<PickedTreePickerProps> => ({
+    toggleItemActive: (event, item, pickerId) => {
+        if (ownProps.openOnActivation) {
+            dispatchProps.toggleItemOpen(event, item, pickerId);
         }
-    },
+        dispatchProps.toggleItemActive(event, item, pickerId);
+    }
 });
 
-export const ProjectsTreePicker = connect(mapStateToProps, mapDispatchToProps)(TreePicker);
+export const ProjectsTreePicker = connect(mapStateToProps, mapDispatchToProps, mergeProps)(TreePicker);
 
 const getProjectPickerIcon = ({ data }: TreeItem<ProjectsTreePickerItem>, rootIcon: IconType): IconType => {
     if ('kind' in data) {
diff --git a/src/views-components/side-panel-tree/side-panel-tree.tsx b/src/views-components/side-panel-tree/side-panel-tree.tsx
index 743a39d..e2465d2 100644
--- a/src/views-components/side-panel-tree/side-panel-tree.tsx
+++ b/src/views-components/side-panel-tree/side-panel-tree.tsx
@@ -3,91 +3,29 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import * as React from "react";
-import { Dispatch } from "redux";
 import { connect } from "react-redux";
-import { TreePicker, TreePickerProps } from "../tree-picker/tree-picker";
-import { TreeItem } from "~/components/tree/tree";
-import { ProjectResource } from "~/models/project";
-import { ListItemTextIcon } from "~/components/list-item-text-icon/list-item-text-icon";
-import { ProjectIcon, FavoriteIcon, ProjectsIcon, ShareMeIcon, TrashIcon } from '~/components/icon/icon';
-import { RecentIcon, WorkflowIcon } from '~/components/icon/icon';
-import { activateSidePanelTreeItem, toggleSidePanelTreeItemCollapse, SIDE_PANEL_TREE, SidePanelTreeCategory } from '~/store/side-panel-tree/side-panel-tree-actions';
-import { openSidePanelContextMenu } from '~/store/context-menu/context-menu-actions';
 import { noop } from 'lodash';
-
-import { HomeTreePicker } from "../projects-tree-picker/home-tree-picker";
-import { SharedTreePicker } from "../projects-tree-picker/shared-tree-picker";
-import { SidePanelTreeId } from "~/store/side-panel-tree/side-panel-trees-actions";
-import { ProjectsTreePicker } from '~/views-components/projects-tree-picker/generic-projects-tree-picker';
-import { IconType } from '../../components/icon/icon';
 import { values } from 'lodash/fp';
-
-export interface SidePanelTreeProps {
-    onItemActivation: (id: string) => void;
-    sidePanelProgress?: boolean;
-}
-
-type SidePanelTreeActionProps = Pick<TreePickerProps<ProjectResource | string>, 'onContextMenu' | 'toggleItemActive' | 'toggleItemOpen' | 'toggleItemSelection'>;
-
-const mapDispatchToProps = (dispatch: Dispatch, props: SidePanelTreeProps): SidePanelTreeActionProps => ({
-    onContextMenu: (event, { id }) => {
-        dispatch<any>(openSidePanelContextMenu(event, id));
-    },
-    toggleItemActive: (_, { id }) => {
-        dispatch<any>(activateSidePanelTreeItem(id));
-        props.onItemActivation(id);
-    },
-    toggleItemOpen: (_, { id }) => {
-        dispatch<any>(toggleSidePanelTreeItemCollapse(id));
-    },
-    toggleItemSelection: noop,
-});
-
-export const SidePanelTree = connect(undefined, mapDispatchToProps)(
-    (props: SidePanelTreeActionProps) =>
-        <TreePicker {...props} render={renderSidePanelItem} pickerId={SIDE_PANEL_TREE} />);
-
-const renderSidePanelItem = (item: TreeItem<ProjectResource>) =>
-    <ListItemTextIcon
-        icon={getProjectPickerIcon(item)}
-        name={typeof item.data === 'string' ? item.data : item.data.name}
-        isActive={item.active}
-        hasMargin={true} />;
-
-const getProjectPickerIcon = (item: TreeItem<ProjectResource | string>) =>
-    typeof item.data === 'string'
-        ? getSidePanelIcon(item.data)
-        : ProjectIcon;
-
-const getSidePanelIcon = (category: string) => {
-    switch (category) {
-        case SidePanelTreeCategory.FAVORITES:
-            return FavoriteIcon;
-        case SidePanelTreeCategory.PROJECTS:
-            return ProjectsIcon;
-        case SidePanelTreeCategory.RECENT_OPEN:
-            return RecentIcon;
-        case SidePanelTreeCategory.SHARED_WITH_ME:
-            return ShareMeIcon;
-        case SidePanelTreeCategory.TRASH:
-            return TrashIcon;
-        case SidePanelTreeCategory.WORKFLOWS:
-            return WorkflowIcon;
-        default:
-            return ProjectIcon;
-    }
-};
+import {  FavoriteIcon, TrashIcon } from '~/components/icon/icon';
+import { RecentIcon, WorkflowIcon } from '~/components/icon/icon';
+import { HomeTreePicker } from "~/views-components/projects-tree-picker/home-tree-picker";
+import { SharedTreePicker } from "~/views-components/projects-tree-picker/shared-tree-picker";
+import { SidePanelTreeId } from "~/store/side-panel-tree/side-panel-trees-actions";
+import { ProjectsTreePicker, ProjectsTreePickerProps } from '~/views-components/projects-tree-picker/generic-projects-tree-picker';
+import { IconType } from '~/components/icon/icon';
 
 const relatedTreePickers = values(SidePanelTreeId);
 
-export const SidePanelTrees = () =>
+export type SidePanelTreesProps = Pick<ProjectsTreePickerProps, 'toggleItemActive'>;
+
+export const SidePanelTrees = (props: SidePanelTreesProps) =>
     <div>
-        <HomeTreePicker pickerId={SidePanelTreeId.HOME} {...{relatedTreePickers}} />
-        <SharedTreePicker pickerId={SidePanelTreeId.SHARED} {...{relatedTreePickers}} />
-        <WorkflowsTreePicker pickerId={SidePanelTreeId.WORKFLOWS} {...{relatedTreePickers}} />
-        <RecentTreePicker pickerId={SidePanelTreeId.RECENT} {...{relatedTreePickers}} />
-        <FavoritesTreePicker pickerId={SidePanelTreeId.FAVORITES} {...{relatedTreePickers}} />
-        <TrashTreePicker pickerId={SidePanelTreeId.TRASH} {...{relatedTreePickers}} />
+        <HomeTreePicker pickerId={SidePanelTreeId.HOME} openOnActivation {...{ relatedTreePickers }} {...props} />
+        <SharedTreePicker pickerId={SidePanelTreeId.SHARED} openOnActivation {...{ relatedTreePickers }} {...props} />
+        <WorkflowsTreePicker pickerId={SidePanelTreeId.WORKFLOWS} {...{ relatedTreePickers }} {...props} />
+        <RecentTreePicker pickerId={SidePanelTreeId.RECENT} {...{ relatedTreePickers }} {...props} />
+        <FavoritesTreePicker pickerId={SidePanelTreeId.FAVORITES} {...{ relatedTreePickers }} {...props} />
+        <TrashTreePicker pickerId={SidePanelTreeId.TRASH} {...{ relatedTreePickers }} {...props} />
     </div>;
 
 const createPicker = (icon: IconType) =>
diff --git a/src/views-components/side-panel/side-panel.tsx b/src/views-components/side-panel/side-panel.tsx
index bc8c803..80916e5 100644
--- a/src/views-components/side-panel/side-panel.tsx
+++ b/src/views-components/side-panel/side-panel.tsx
@@ -3,44 +3,23 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import * as React from 'react';
-import { StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core/styles';
-import { ArvadosTheme } from '~/common/custom-theme';
-import { SidePanelTrees, SidePanelTreeProps } from '~/views-components/side-panel-tree/side-panel-tree';
-import { Dispatch } from 'redux';
 import { connect } from 'react-redux';
-import { navigateFromSidePanel } from '../../store/side-panel/side-panel-action';
+import { SidePanelTrees as SidePanelTreesComponent, SidePanelTreesProps } from '~/views-components/side-panel-tree/side-panel-tree';
+import { navigateFromSidePanel } from '~/store/side-panel/side-panel-action';
 import { Grid } from '@material-ui/core';
 import { SidePanelButton } from '~/views-components/side-panel-button/side-panel-button';
-import { RootState } from '~/store/store';
 
-const DRAWER_WITDH = 240;
+export const SidePanel = () =>
+    <Grid item xs>
+        <SidePanelButton />
+        <SidePanelTrees />
+    </Grid>;
 
-type CssRules = 'root';
+const dispatchProps: SidePanelTreesProps = {
+    toggleItemActive: (_, { id }) => navigateFromSidePanel(id),
+};
 
-const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
-    root: {
-        background: theme.palette.background.paper,
-        borderRight: `1px solid ${theme.palette.divider}`,
-        height: '100%',
-        overflowX: 'auto',
-        width: DRAWER_WITDH,
-    }
-});
-
-const mapDispatchToProps = (dispatch: Dispatch): SidePanelTreeProps => ({
-    onItemActivation: id => {
-        dispatch<any>(navigateFromSidePanel(id));
-    }
-});
-
-const mapStateToProps = (state: RootState) => ({
-});
-
-export const SidePanel = withStyles(styles)(
-    connect(mapStateToProps, mapDispatchToProps)(
-        ({ classes, ...props }: WithStyles<CssRules> & SidePanelTreeProps) =>
-            <Grid item xs>
-                <SidePanelButton />
-                <SidePanelTrees />
-            </Grid>
-    ));
+const SidePanelTrees = connect(
+    null,
+    dispatchProps
+)(SidePanelTreesComponent);

commit eec250ad6f4582674e0abc57214a2da6a3b68897
Author: Michal Klobukowski <michal.klobukowski at contractors.roche.com>
Date:   Thu Nov 1 19:06:48 2018 +0100

    Handle deactivation of related tree pickers
    
    Feature #14252
    
    Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski <michal.klobukowski at contractors.roche.com>

diff --git a/src/store/side-panel-tree/side-panel-trees-actions.ts b/src/store/side-panel-tree/side-panel-trees-actions.ts
index 53e4eab..214e234 100644
--- a/src/store/side-panel-tree/side-panel-trees-actions.ts
+++ b/src/store/side-panel-tree/side-panel-trees-actions.ts
@@ -34,4 +34,4 @@ const initSidePanelTree = (pickerId: string, name: string) =>
             status: TreeNodeStatus.LOADED,
             value,
         }),
-    });
\ No newline at end of file
+    });
diff --git a/src/store/tree-picker/tree-picker-actions.ts b/src/store/tree-picker/tree-picker-actions.ts
index a988e89..0e8118f 100644
--- a/src/store/tree-picker/tree-picker-actions.ts
+++ b/src/store/tree-picker/tree-picker-actions.ts
@@ -19,7 +19,7 @@ export const treePickerActions = unionize({
     LOAD_TREE_PICKER_NODE: ofType<{ id: string, pickerId: string }>(),
     LOAD_TREE_PICKER_NODE_SUCCESS: ofType<{ id: string, nodes: Array<TreeNode<any>>, pickerId: string }>(),
     TOGGLE_TREE_PICKER_NODE_COLLAPSE: ofType<{ id: string, pickerId: string }>(),
-    ACTIVATE_TREE_PICKER_NODE: ofType<{ id: string, pickerId: string }>(),
+    ACTIVATE_TREE_PICKER_NODE: ofType<{ id: string, pickerId: string, relatedTreePickers?: string[] }>(),
     DEACTIVATE_TREE_PICKER_NODE: ofType<{ pickerId: string }>(),
     TOGGLE_TREE_PICKER_NODE_SELECTION: ofType<{ id: string, pickerId: string }>(),
     SELECT_TREE_PICKER_NODE: ofType<{ id: string | string[], pickerId: string }>(),
diff --git a/src/store/tree-picker/tree-picker-reducer.ts b/src/store/tree-picker/tree-picker-reducer.ts
index 846e445..341df7b 100644
--- a/src/store/tree-picker/tree-picker-reducer.ts
+++ b/src/store/tree-picker/tree-picker-reducer.ts
@@ -7,29 +7,46 @@ import { TreePicker } from "./tree-picker";
 import { treePickerActions, TreePickerAction } from "./tree-picker-actions";
 import { compose } from "redux";
 import { activateNode, getNode, toggleNodeCollapse, toggleNodeSelection } from '~/models/tree';
+import { pipe } from 'lodash/fp';
 
 export const treePickerReducer = (state: TreePicker = {}, action: TreePickerAction) =>
     treePickerActions.match(action, {
         LOAD_TREE_PICKER_NODE: ({ id, pickerId }) =>
             updateOrCreatePicker(state, pickerId, setNodeStatus(id)(TreeNodeStatus.PENDING)),
+
         LOAD_TREE_PICKER_NODE_SUCCESS: ({ id, nodes, pickerId }) =>
             updateOrCreatePicker(state, pickerId, compose(receiveNodes(nodes)(id), setNodeStatus(id)(TreeNodeStatus.LOADED))),
+
         TOGGLE_TREE_PICKER_NODE_COLLAPSE: ({ id, pickerId }) =>
             updateOrCreatePicker(state, pickerId, toggleNodeCollapse(id)),
-        ACTIVATE_TREE_PICKER_NODE: ({ id, pickerId }) =>
-            updateOrCreatePicker(state, pickerId, activateNode(id)),
+
+        ACTIVATE_TREE_PICKER_NODE: ({ id, pickerId, relatedTreePickers = [] }) =>
+            pipe(
+                () => relatedTreePickers.reduce(
+                    (state, relatedPickerId) => updateOrCreatePicker(state, relatedPickerId, deactivateNode),
+                    state
+                ),
+                state => updateOrCreatePicker(state, pickerId, activateNode(id))
+            )(),
+
         DEACTIVATE_TREE_PICKER_NODE: ({ pickerId }) =>
             updateOrCreatePicker(state, pickerId, deactivateNode),
+
         TOGGLE_TREE_PICKER_NODE_SELECTION: ({ id, pickerId }) =>
             updateOrCreatePicker(state, pickerId, toggleNodeSelection(id)),
+
         SELECT_TREE_PICKER_NODE: ({ id, pickerId }) =>
             updateOrCreatePicker(state, pickerId, selectNodes(id)),
+
         DESELECT_TREE_PICKER_NODE: ({ id, pickerId }) =>
             updateOrCreatePicker(state, pickerId, deselectNodes(id)),
+
         RESET_TREE_PICKER: ({ pickerId }) =>
             updateOrCreatePicker(state, pickerId, createTree),
+
         EXPAND_TREE_PICKER_NODES: ({ pickerId, ids }) =>
             updateOrCreatePicker(state, pickerId, expandNode(...ids)),
+
         default: () => state
     });
 
diff --git a/src/views-components/projects-tree-picker/generic-projects-tree-picker.tsx b/src/views-components/projects-tree-picker/generic-projects-tree-picker.tsx
index 77f831f..d8a5d49 100644
--- a/src/views-components/projects-tree-picker/generic-projects-tree-picker.tsx
+++ b/src/views-components/projects-tree-picker/generic-projects-tree-picker.tsx
@@ -29,6 +29,7 @@ export interface ProjectsTreePickerDataProps {
     includeFiles?: boolean;
     rootItemIcon: IconType;
     showSelection?: boolean;
+    relatedTreePickers?: string[];
     loadRootItem: (item: TreeItem<ProjectsTreePickerRootItem>, pickerId: string, includeCollections?: boolean, inlcudeFiles?: boolean) => void;
 }
 
@@ -39,10 +40,10 @@ const mapStateToProps = (_: any, { rootItemIcon, showSelection }: ProjectsTreePi
     showSelection: isSelectionVisible(showSelection),
 });
 
-const mapDispatchToProps = (dispatch: Dispatch, { loadRootItem, includeCollections, includeFiles, ...props }: ProjectsTreePickerProps): PickedTreePickerProps => ({
+const mapDispatchToProps = (dispatch: Dispatch, { loadRootItem, includeCollections, includeFiles, relatedTreePickers, ...props }: ProjectsTreePickerProps): PickedTreePickerProps => ({
     onContextMenu: () => { return; },
     toggleItemActive: (event, item, pickerId) => {
-        dispatch(treePickerActions.ACTIVATE_TREE_PICKER_NODE({ id: item.id, pickerId }));
+        dispatch(treePickerActions.ACTIVATE_TREE_PICKER_NODE({ id: item.id, pickerId, relatedTreePickers }));
         if (props.toggleItemActive) {
             props.toggleItemActive(event, item, pickerId);
         }
@@ -65,7 +66,7 @@ const mapDispatchToProps = (dispatch: Dispatch, { loadRootItem, includeCollectio
     },
     toggleItemSelection: (event, item, pickerId) => {
         dispatch<any>(treePickerActions.TOGGLE_TREE_PICKER_NODE_SELECTION({ id: item.id, pickerId }));
-        if(props.toggleItemSelection){
+        if (props.toggleItemSelection) {
             props.toggleItemSelection(event, item, pickerId);
         }
     },
diff --git a/src/views-components/side-panel-tree/side-panel-tree.tsx b/src/views-components/side-panel-tree/side-panel-tree.tsx
index 6567ffd..743a39d 100644
--- a/src/views-components/side-panel-tree/side-panel-tree.tsx
+++ b/src/views-components/side-panel-tree/side-panel-tree.tsx
@@ -20,6 +20,7 @@ import { SharedTreePicker } from "../projects-tree-picker/shared-tree-picker";
 import { SidePanelTreeId } from "~/store/side-panel-tree/side-panel-trees-actions";
 import { ProjectsTreePicker } from '~/views-components/projects-tree-picker/generic-projects-tree-picker';
 import { IconType } from '../../components/icon/icon';
+import { values } from 'lodash/fp';
 
 export interface SidePanelTreeProps {
     onItemActivation: (id: string) => void;
@@ -77,14 +78,16 @@ const getSidePanelIcon = (category: string) => {
     }
 };
 
+const relatedTreePickers = values(SidePanelTreeId);
+
 export const SidePanelTrees = () =>
     <div>
-        <HomeTreePicker pickerId={SidePanelTreeId.HOME} />
-        <SharedTreePicker pickerId={SidePanelTreeId.SHARED} />
-        <WorkflowsTreePicker pickerId={SidePanelTreeId.WORKFLOWS} />
-        <RecentTreePicker pickerId={SidePanelTreeId.RECENT} />
-        <FavoritesTreePicker pickerId={SidePanelTreeId.FAVORITES} />
-        <TrashTreePicker pickerId={SidePanelTreeId.TRASH} />
+        <HomeTreePicker pickerId={SidePanelTreeId.HOME} {...{relatedTreePickers}} />
+        <SharedTreePicker pickerId={SidePanelTreeId.SHARED} {...{relatedTreePickers}} />
+        <WorkflowsTreePicker pickerId={SidePanelTreeId.WORKFLOWS} {...{relatedTreePickers}} />
+        <RecentTreePicker pickerId={SidePanelTreeId.RECENT} {...{relatedTreePickers}} />
+        <FavoritesTreePicker pickerId={SidePanelTreeId.FAVORITES} {...{relatedTreePickers}} />
+        <TrashTreePicker pickerId={SidePanelTreeId.TRASH} {...{relatedTreePickers}} />
     </div>;
 
 const createPicker = (icon: IconType) =>

commit b717649cc20466b2e8c47f47c685aa59d0780def
Merge: dca90ab c7bc8de
Author: Michal Klobukowski <michal.klobukowski at contractors.roche.com>
Date:   Thu Nov 1 17:38:13 2018 +0100

    Merge branch 'master'
    
    Feature #14252
    
    Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski <michal.klobukowski at contractors.roche.com>


commit dca90abb6f6d6d9609bf1a8634915598f9afa5ad
Author: Michal Klobukowski <michal.klobukowski at contractors.roche.com>
Date:   Mon Oct 22 16:46:37 2018 +0200

    Recreate side panel menu from new tree pickers
    
    Feature #14252
    
    Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski <michal.klobukowski at contractors.roche.com>

diff --git a/src/store/side-panel-tree/side-panel-trees-actions.ts b/src/store/side-panel-tree/side-panel-trees-actions.ts
new file mode 100644
index 0000000..53e4eab
--- /dev/null
+++ b/src/store/side-panel-tree/side-panel-trees-actions.ts
@@ -0,0 +1,37 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { Dispatch } from 'redux';
+import { initSharedProject, initUserProject, receiveTreePickerData } from '../tree-picker/tree-picker-actions';
+import { TreeNodeStatus } from '~/models/tree';
+
+export enum SidePanelTreeId {
+    HOME = 'sidePanelUserTree',
+    SHARED = 'sidePanelSharedTree',
+    WORKFLOWS = 'sidePanelWorkflowsTree',
+    RECENT = 'sidePanelRecentTree',
+    FAVORITES = 'sidePanelFavoritesTree',
+    TRASH = 'sidePanelTrashTree',
+}
+
+export const initSidePanelTrees = (dispatch: Dispatch<any>) => {
+    dispatch(initUserProject(SidePanelTreeId.HOME));
+    dispatch(initSharedProject(SidePanelTreeId.SHARED));
+    dispatch(initSidePanelTree(SidePanelTreeId.WORKFLOWS, 'Workflows'));
+    dispatch(initSidePanelTree(SidePanelTreeId.RECENT, 'Recently open'));
+    dispatch(initSidePanelTree(SidePanelTreeId.FAVORITES, 'Favorites'));
+    dispatch(initSidePanelTree(SidePanelTreeId.TRASH, 'Trash'));
+};
+
+const initSidePanelTree = (pickerId: string, name: string) =>
+    receiveTreePickerData({
+        id: '',
+        pickerId,
+        data: [{ uuid: name, name }],
+        extractNodeData: value => ({
+            id: value.uuid,
+            status: TreeNodeStatus.LOADED,
+            value,
+        }),
+    });
\ No newline at end of file
diff --git a/src/store/workbench/workbench-actions.ts b/src/store/workbench/workbench-actions.ts
index 1f31656..80e8d8f 100644
--- a/src/store/workbench/workbench-actions.ts
+++ b/src/store/workbench/workbench-actions.ts
@@ -53,6 +53,7 @@ import { collectionPanelActions } from "~/store/collection-panel/collection-pane
 import { CollectionResource } from "~/models/collection";
 import { searchResultsPanelActions, loadSearchResultsPanel } from '~/store/search-results-panel/search-results-panel-actions';
 import { searchResultsPanelColumns } from '~/views/search-results-panel/search-results-panel-view';
+import { initSidePanelTrees } from '../side-panel-tree/side-panel-trees-actions';
 
 export const WORKBENCH_LOADING_SCREEN = 'workbenchLoadingScreen';
 
@@ -88,6 +89,7 @@ export const loadWorkbench = () =>
                 dispatch(workflowPanelActions.SET_COLUMNS({ columns: workflowPanelColumns }));
                 dispatch(searchResultsPanelActions.SET_COLUMNS({ columns: searchResultsPanelColumns }));
                 dispatch<any>(initSidePanelTree());
+                dispatch<any>(initSidePanelTrees);
                 if (router.location) {
                     const match = matchRootRoute(router.location.pathname);
                     if (match) {
diff --git a/src/views-components/side-panel-tree/side-panel-tree.tsx b/src/views-components/side-panel-tree/side-panel-tree.tsx
index 0e34d3a..6567ffd 100644
--- a/src/views-components/side-panel-tree/side-panel-tree.tsx
+++ b/src/views-components/side-panel-tree/side-panel-tree.tsx
@@ -14,6 +14,13 @@ import { RecentIcon, WorkflowIcon } from '~/components/icon/icon';
 import { activateSidePanelTreeItem, toggleSidePanelTreeItemCollapse, SIDE_PANEL_TREE, SidePanelTreeCategory } from '~/store/side-panel-tree/side-panel-tree-actions';
 import { openSidePanelContextMenu } from '~/store/context-menu/context-menu-actions';
 import { noop } from 'lodash';
+
+import { HomeTreePicker } from "../projects-tree-picker/home-tree-picker";
+import { SharedTreePicker } from "../projects-tree-picker/shared-tree-picker";
+import { SidePanelTreeId } from "~/store/side-panel-tree/side-panel-trees-actions";
+import { ProjectsTreePicker } from '~/views-components/projects-tree-picker/generic-projects-tree-picker';
+import { IconType } from '../../components/icon/icon';
+
 export interface SidePanelTreeProps {
     onItemActivation: (id: string) => void;
     sidePanelProgress?: boolean;
@@ -69,3 +76,26 @@ const getSidePanelIcon = (category: string) => {
             return ProjectIcon;
     }
 };
+
+export const SidePanelTrees = () =>
+    <div>
+        <HomeTreePicker pickerId={SidePanelTreeId.HOME} />
+        <SharedTreePicker pickerId={SidePanelTreeId.SHARED} />
+        <WorkflowsTreePicker pickerId={SidePanelTreeId.WORKFLOWS} />
+        <RecentTreePicker pickerId={SidePanelTreeId.RECENT} />
+        <FavoritesTreePicker pickerId={SidePanelTreeId.FAVORITES} />
+        <TrashTreePicker pickerId={SidePanelTreeId.TRASH} />
+    </div>;
+
+const createPicker = (icon: IconType) =>
+    connect(() => ({
+        rootItemIcon: icon,
+    }), { loadRootItem: noop, })(ProjectsTreePicker);
+
+export const WorkflowsTreePicker = createPicker(WorkflowIcon);
+
+export const RecentTreePicker = createPicker(RecentIcon);
+
+export const FavoritesTreePicker = createPicker(FavoriteIcon);
+
+export const TrashTreePicker = createPicker(TrashIcon);
diff --git a/src/views-components/side-panel/side-panel.tsx b/src/views-components/side-panel/side-panel.tsx
index 12e82df..bc8c803 100644
--- a/src/views-components/side-panel/side-panel.tsx
+++ b/src/views-components/side-panel/side-panel.tsx
@@ -5,8 +5,8 @@
 import * as React from 'react';
 import { StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core/styles';
 import { ArvadosTheme } from '~/common/custom-theme';
-import { SidePanelTree, SidePanelTreeProps } from '~/views-components/side-panel-tree/side-panel-tree';
-import { compose, Dispatch } from 'redux';
+import { SidePanelTrees, SidePanelTreeProps } from '~/views-components/side-panel-tree/side-panel-tree';
+import { Dispatch } from 'redux';
 import { connect } from 'react-redux';
 import { navigateFromSidePanel } from '../../store/side-panel/side-panel-action';
 import { Grid } from '@material-ui/core';
@@ -38,9 +38,9 @@ const mapStateToProps = (state: RootState) => ({
 
 export const SidePanel = withStyles(styles)(
     connect(mapStateToProps, mapDispatchToProps)(
-    ({ classes, ...props }: WithStyles<CssRules> & SidePanelTreeProps) =>
-    <Grid item xs>
-        <SidePanelButton />
-        <SidePanelTree {...props} />
-    </Grid>
-));
+        ({ classes, ...props }: WithStyles<CssRules> & SidePanelTreeProps) =>
+            <Grid item xs>
+                <SidePanelButton />
+                <SidePanelTrees />
+            </Grid>
+    ));

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list