[ARVADOS-WORKBENCH2] updated: 1.2.0-139-g4157d0e

Git user git at public.curoverse.com
Mon Aug 27 07:19:14 EDT 2018


Summary of changes:
 src/components/side-panel/side-panel.tsx           | 128 ---------------------
 src/components/tree/tree.tsx                       |   7 +-
 src/store/navigation/navigation-action.ts          |  20 +---
 .../side-panel-tree/side-panel-tree-actions.ts     |  36 ++++--
 src/store/side-panel/side-panel-action.ts          |   4 -
 src/store/tree-picker/tree-picker-actions.ts       |   1 +
 src/store/tree-picker/tree-picker-reducer.ts       |   9 +-
 7 files changed, 44 insertions(+), 161 deletions(-)
 delete mode 100644 src/components/side-panel/side-panel.tsx

       via  4157d0e93444cd1d2a631e7826f8cd831863b58a (commit)
      from  c3bec339e0f247f7cbc8698120b8ecf43629d3e7 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit 4157d0e93444cd1d2a631e7826f8cd831863b58a
Author: Michal Klobukowski <michal.klobukowski at contractors.roche.com>
Date:   Mon Aug 27 13:18:59 2018 +0200

    Remove unused file, update side panel tree actions
    
    Feature #14102
    
    Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski <michal.klobukowski at contractors.roche.com>

diff --git a/src/components/side-panel/side-panel.tsx b/src/components/side-panel/side-panel.tsx
deleted file mode 100644
index 84e5c54..0000000
--- a/src/components/side-panel/side-panel.tsx
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// 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 { List, ListItem, ListItemIcon, Collapse } from "@material-ui/core";
-import { SidePanelRightArrowIcon, IconType } from '../icon/icon';
-import * as classnames from "classnames";
-import { ListItemTextIcon } from '../list-item-text-icon/list-item-text-icon';
-import { Dispatch } from "redux";
-import { RouteComponentProps, withRouter } from "react-router";
-
-type CssRules = 'active' | 'row' | 'root' | 'list' | 'iconClose' | 'iconOpen' | 'toggableIconContainer' | 'toggableIcon';
-
-const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
-    root: {
-        overflowY: 'auto',
-        minWidth: '240px',
-        whiteSpace: 'nowrap',
-        marginTop: '52px',
-        display: 'flex',
-        flexGrow: 1,
-    },
-    list: {
-        padding: '5px 0px 5px 14px',
-        minWidth: '240px',
-    },
-    row: {
-        display: 'flex',
-        alignItems: 'center',
-    },
-    toggableIconContainer: {
-        color: theme.palette.grey["700"],
-        height: '14px',
-        width: '14px'
-    },
-    toggableIcon: {
-        fontSize: '14px'
-    },
-    active: {
-        color: theme.palette.primary.main,
-    },
-    iconClose: {
-        transition: 'all 0.1s ease',
-    },
-    iconOpen: {
-        transition: 'all 0.1s ease',
-        transform: 'rotate(90deg)',
-    }
-});
-
-export interface SidePanelItem {
-    id: string;
-    name: string;
-    url: string;
-    icon: IconType;
-    open?: boolean;
-    margin?: boolean;
-    openAble?: boolean;
-    activeAction?: (dispatch: Dispatch, uuid?: string) => void;
-}
-
-interface SidePanelDataProps {
-    toggleOpen: (id: string) => void;
-    toggleActive: (id: string) => void;
-    sidePanelItems: SidePanelItem[];
-    onContextMenu: (event: React.MouseEvent<HTMLElement>, item: SidePanelItem) => void;
-}
-
-type SidePanelProps = RouteComponentProps<{}> & SidePanelDataProps & WithStyles<CssRules>;
-
-export const SidePanel = withStyles(styles)(withRouter(
-    class extends React.Component<SidePanelProps> {
-        render() {
-            const { classes, toggleOpen, toggleActive, sidePanelItems, children } = this.props;
-            const { root, row, list, toggableIconContainer } = classes;
-
-            const path = this.props.location.pathname.split('/');
-            const activeUrl = path.length > 1 ? "/" + path[1] : "/";
-            return (
-                <div className={root}>
-                    <List>
-                        {sidePanelItems.map(it => {
-                            const active = it.url === activeUrl;
-                            return <span key={it.name}>
-                                <ListItem button className={list} onClick={() => toggleActive(it.id)}
-                                          onContextMenu={this.handleRowContextMenu(it)}>
-                                    <span className={row}>
-                                        {it.openAble ? (
-                                            <i onClick={() => toggleOpen(it.id)} className={toggableIconContainer}>
-                                                <ListItemIcon
-                                                    className={this.getToggableIconClassNames(it.open, active)}>
-                                                    < SidePanelRightArrowIcon/>
-                                                </ListItemIcon>
-                                            </i>
-                                        ) : null}
-                                        <ListItemTextIcon icon={it.icon} name={it.name} isActive={active}
-                                                          hasMargin={it.margin}/>
-                                    </span>
-                                </ListItem>
-                                {it.openAble ? (
-                                    <Collapse in={it.open} timeout="auto" unmountOnExit>
-                                        {children}
-                                    </Collapse>
-                                ) : null}
-                            </span>;
-                        })}
-                    </List>
-                </div>
-            );
-        }
-
-        getToggableIconClassNames = (isOpen?: boolean, isActive ?: boolean) => {
-            const { iconOpen, iconClose, active, toggableIcon } = this.props.classes;
-            return classnames(toggableIcon, {
-                [iconOpen]: isOpen,
-                [iconClose]: !isOpen,
-                [active]: isActive
-            });
-        }
-
-        handleRowContextMenu = (item: SidePanelItem) =>
-            (event: React.MouseEvent<HTMLElement>) =>
-                item.openAble ? this.props.onContextMenu(event, item) : null
-    }
-));
diff --git a/src/components/tree/tree.tsx b/src/components/tree/tree.tsx
index 8d657f8..c892d7d 100644
--- a/src/components/tree/tree.tsx
+++ b/src/components/tree/tree.tsx
@@ -107,7 +107,7 @@ export const Tree = withStyles(styles)(
                             onContextMenu={this.handleRowContextMenu(it)}>
                             {it.status === TreeItemStatus.PENDING ?
                                 <CircularProgress size={10} className={loader} /> : null}
-                            <i onClick={() => this.props.toggleItemOpen(it.id, it.status)}
+                            <i onClick={this.handleToggleItemOpen(it.id, it.status)}
                                 className={toggableIconContainer}>
                                 <ListItemIcon className={this.getToggableIconClassNames(it.open, it.active)}>
                                     {this.getProperArrowAnimation(it.status, it.items!)}
@@ -171,5 +171,10 @@ export const Tree = withStyles(styles)(
                 }
                 : undefined;
         }
+
+        handleToggleItemOpen = (id: string, status: TreeItemStatus) => (event: React.MouseEvent<HTMLElement>) => {
+            event.stopPropagation();
+            this.props.toggleItemOpen(id, status);
+        }
     }
 );
diff --git a/src/store/navigation/navigation-action.ts b/src/store/navigation/navigation-action.ts
index b5dc5e9..3256846 100644
--- a/src/store/navigation/navigation-action.ts
+++ b/src/store/navigation/navigation-action.ts
@@ -8,7 +8,6 @@ import { RootState } from "../store";
 import { ResourceKind, Resource, extractUuidKind } from '~/models/resource';
 import { getCollectionUrl } from "~/models/collection";
 import { getProjectUrl } from "~/models/project";
-import { getResource } from '~/store/resources/resources';
 import { loadDetailsPanel } from '~/store/details-panel/details-panel-action';
 import { loadCollectionPanel } from '~/store/collection-panel/collection-panel-action';
 import { snackbarActions } from '../snackbar/snackbar-actions';
@@ -18,7 +17,6 @@ import { openProjectPanel, projectPanelActions } from '~/store/project-panel/pro
 import { activateSidePanelTreeItem, initSidePanelTree, SidePanelTreeCategory } from '../side-panel-tree/side-panel-tree-actions';
 import { Routes } from '~/routes/routes';
 import { loadResource } from '../resources/resources-actions';
-import { ServiceRepository } from '~/services/services';
 import { favoritePanelActions } from '~/store/favorite-panel/favorite-panel-action';
 import { projectPanelColumns } from '~/views/project-panel/project-panel';
 import { favoritePanelColumns } from '~/views/favorite-panel/favorite-panel';
@@ -26,7 +24,7 @@ import { matchRootRoute } from '~/routes/routes';
 import { setCollectionBreadcrumbs, setProjectBreadcrumbs, setSidePanelBreadcrumbs } from '../breadcrumbs/breadcrumbs-actions';
 
 export const navigateTo = (uuid: string) =>
-    async (dispatch: Dispatch, getState: () => RootState) => {
+    async (dispatch: Dispatch) => {
         const kind = extractUuidKind(uuid);
         if (kind === ResourceKind.PROJECT || kind === ResourceKind.USER) {
             dispatch<any>(navigateToProject(uuid));
@@ -38,20 +36,8 @@ export const navigateTo = (uuid: string) =>
         }
     };
 
-const getResourceNavigationAction = (resource: Resource) => {
-    switch (resource.kind) {
-        case ResourceKind.COLLECTION:
-            return navigateToCollection(resource.uuid);
-        case ResourceKind.PROJECT:
-        case ResourceKind.USER:
-            return navigateToProject(resource.uuid);
-        default:
-            return cannotNavigateToResource(resource);
-    }
-};
-
 export const loadWorkbench = () =>
-    async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+    async (dispatch: Dispatch, getState: () => RootState) => {
         const { auth, router } = getState();
         const { user } = auth;
         if (user) {
@@ -77,7 +63,7 @@ export const loadWorkbench = () =>
 export const navigateToFavorites = push(Routes.FAVORITES);
 
 export const loadFavorites = () =>
-    async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+    (dispatch: Dispatch) => {
         dispatch<any>(activateSidePanelTreeItem(SidePanelTreeCategory.FAVORITES));
         dispatch<any>(loadFavoritePanel());
         dispatch<any>(setSidePanelBreadcrumbs(SidePanelTreeCategory.FAVORITES));
diff --git a/src/store/side-panel-tree/side-panel-tree-actions.ts b/src/store/side-panel-tree/side-panel-tree-actions.ts
index 377f420..574bda9 100644
--- a/src/store/side-panel-tree/side-panel-tree-actions.ts
+++ b/src/store/side-panel-tree/side-panel-tree-actions.ts
@@ -11,7 +11,7 @@ import { FilterBuilder } from '~/common/api/filter-builder';
 import { resourcesActions } from '../resources/resources-actions';
 import { getTreePicker, TreePicker } from '../tree-picker/tree-picker';
 import { TreeItemStatus } from "~/components/tree/tree";
-import { getNodeAncestors, getNodeValue } from '~/models/tree';
+import { getNodeAncestors, getNodeValue, getNodeAncestorsIds } from '~/models/tree';
 import { ProjectResource } from '~/models/project';
 
 export enum SidePanelTreeCategory {
@@ -88,7 +88,7 @@ export const loadSidePanelTreeProjects = (projectUuid: string) =>
 
 export const activateSidePanelTreeItem = (nodeId: string) =>
     async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
-        const node = getSidePanelTreeNode(nodeId)(getState());
+        const node = getSidePanelTreeNode(nodeId)(getState().treePicker);
         if (node && !node.selected) {
             dispatch(treePickerActions.TOGGLE_TREE_PICKER_NODE_SELECT({ nodeId, pickerId: SIDE_PANEL_TREE }));
         }
@@ -99,13 +99,18 @@ export const activateSidePanelTreeItem = (nodeId: string) =>
 
 export const activateSidePanelTreeProject = (nodeId: string) =>
     async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
-        const node = getSidePanelTreeNode(nodeId)(getState());
+        const { treePicker } = getState();
+        const node = getSidePanelTreeNode(nodeId)(treePicker);
         if (node && node.status !== TreeItemStatus.LOADED) {
             await dispatch<any>(loadSidePanelTreeProjects(nodeId));
-            dispatch<any>(expandSidePanelTreeItem(nodeId));
         } else if (node === undefined) {
             await dispatch<any>(activateSidePanelTreeBranch(nodeId));
         }
+        dispatch(treePickerActions.EXPAND_TREE_PICKER_NODES({
+            nodeIds: getSidePanelTreeNodeAncestorsIds(nodeId)(treePicker),
+            pickerId: SIDE_PANEL_TREE
+        }));
+        dispatch<any>(expandSidePanelTreeItem(nodeId));
     };
 
 export const activateSidePanelTreeBranch = (nodeId: string) =>
@@ -114,29 +119,40 @@ export const activateSidePanelTreeBranch = (nodeId: string) =>
         for (const ancestor of ancestors) {
             await dispatch<any>(loadSidePanelTreeProjects(ancestor.uuid));
         }
-        for (const ancestor of ancestors) {
-            dispatch<any>(expandSidePanelTreeItem(ancestor.uuid));
-        }
+        dispatch(treePickerActions.EXPAND_TREE_PICKER_NODES({
+            nodeIds: ancestors.map(ancestor => ancestor.uuid),
+            pickerId: SIDE_PANEL_TREE
+        }));
         dispatch(treePickerActions.TOGGLE_TREE_PICKER_NODE_SELECT({ nodeId, pickerId: SIDE_PANEL_TREE }));
     };
 
 export const toggleSidePanelTreeItemCollapse = (nodeId: string) =>
     async (dispatch: Dispatch, getState: () => RootState) => {
+        const node = getSidePanelTreeNode(nodeId)(getState().treePicker);
+        if (node && node.status === TreeItemStatus.INITIAL) {
+            await dispatch<any>(loadSidePanelTreeProjects(node.nodeId));
+        }
         dispatch(treePickerActions.TOGGLE_TREE_PICKER_NODE_COLLAPSE({ nodeId, pickerId: SIDE_PANEL_TREE }));
     };
 
 export const expandSidePanelTreeItem = (nodeId: string) =>
     async (dispatch: Dispatch, getState: () => RootState) => {
-        const node = getSidePanelTreeNode(nodeId)(getState());
+        const node = getSidePanelTreeNode(nodeId)(getState().treePicker);
         if (node && node.collapsed) {
             dispatch(treePickerActions.TOGGLE_TREE_PICKER_NODE_COLLAPSE({ nodeId, pickerId: SIDE_PANEL_TREE }));
         }
     };
 
-const getSidePanelTreeNode = (nodeId: string) => (state: RootState) => {
-    const sidePanelTree = getTreePicker(SIDE_PANEL_TREE)(state.treePicker);
+const getSidePanelTreeNode = (nodeId: string) => (treePicker: TreePicker) => {
+    const sidePanelTree = getTreePicker(SIDE_PANEL_TREE)(treePicker);
     return sidePanelTree
         ? getNodeValue(nodeId)(sidePanelTree)
         : undefined;
 };
 
+const getSidePanelTreeNodeAncestorsIds = (nodeId: string) => (treePicker: TreePicker) => {
+    const sidePanelTree = getTreePicker(SIDE_PANEL_TREE)(treePicker);
+    return sidePanelTree
+        ? getNodeAncestorsIds(nodeId)(sidePanelTree)
+        : [];
+};
diff --git a/src/store/side-panel/side-panel-action.ts b/src/store/side-panel/side-panel-action.ts
index d0fde0e..8c7ef4a 100644
--- a/src/store/side-panel/side-panel-action.ts
+++ b/src/store/side-panel/side-panel-action.ts
@@ -6,10 +6,6 @@ import { Dispatch } from 'redux';
 import { isSidePanelTreeCategory, SidePanelTreeCategory } from '~/store/side-panel-tree/side-panel-tree-actions';
 import { navigateToFavorites, navigateTo } from '../navigation/navigation-action';
 import { snackbarActions } from '~/store/snackbar/snackbar-actions';
-import { RootState } from '~/store/store';
-import { extractUuidKind, ResourceKind } from '~/models/resource';
-import { openProjectContextMenu } from '~/store/context-menu/context-menu-actions';
-import { openRootProjectContextMenu } from '../context-menu/context-menu-actions';
 
 export const navigateFromSidePanel = (id: string) =>
     (dispatch: Dispatch) => {
diff --git a/src/store/tree-picker/tree-picker-actions.ts b/src/store/tree-picker/tree-picker-actions.ts
index 97f72d6..5b04389 100644
--- a/src/store/tree-picker/tree-picker-actions.ts
+++ b/src/store/tree-picker/tree-picker-actions.ts
@@ -11,6 +11,7 @@ export const treePickerActions = unionize({
     LOAD_TREE_PICKER_NODE_SUCCESS: ofType<{ nodeId: string, nodes: Array<TreePickerNode>, pickerId: string }>(),
     TOGGLE_TREE_PICKER_NODE_COLLAPSE: ofType<{ nodeId: string, pickerId: string }>(),
     TOGGLE_TREE_PICKER_NODE_SELECT: ofType<{ nodeId: string, pickerId: string }>(),
+    EXPAND_TREE_PICKER_NODES: ofType<{ nodeIds: string[], pickerId: string }>(),
     RESET_TREE_PICKER: ofType<{ pickerId: string }>()
 });
 
diff --git a/src/store/tree-picker/tree-picker-reducer.ts b/src/store/tree-picker/tree-picker-reducer.ts
index e7173d2..8eaada6 100644
--- a/src/store/tree-picker/tree-picker-reducer.ts
+++ b/src/store/tree-picker/tree-picker-reducer.ts
@@ -18,8 +18,10 @@ export const treePickerReducer = (state: TreePicker = {}, action: TreePickerActi
             updateOrCreatePicker(state, pickerId, setNodeValueWith(toggleCollapse)(nodeId)),
         TOGGLE_TREE_PICKER_NODE_SELECT: ({ nodeId, pickerId }) =>
             updateOrCreatePicker(state, pickerId, mapTreeValues(toggleSelect(nodeId))),
-        RESET_TREE_PICKER: ({ pickerId }) => 
+        RESET_TREE_PICKER: ({ pickerId }) =>
             updateOrCreatePicker(state, pickerId, createTree),
+        EXPAND_TREE_PICKER_NODES: ({ pickerId, nodeIds }) =>
+            updateOrCreatePicker(state, pickerId, mapTreeValues(expand(nodeIds))),
         default: () => state
     });
 
@@ -29,6 +31,11 @@ const updateOrCreatePicker = (state: TreePicker, pickerId: string, func: (value:
     return { ...state, [pickerId]: updatedPicker };
 };
 
+const expand = (ids: string[]) => (node: TreePickerNode): TreePickerNode =>
+    ids.some(id => id === node.nodeId)
+        ? { ...node, collapsed: false }
+        : node;
+
 const setPending = (value: TreePickerNode): TreePickerNode =>
     ({ ...value, status: TreeItemStatus.PENDING });
 

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


hooks/post-receive
-- 




More information about the arvados-commits mailing list