[ARVADOS-WORKBENCH2] updated: 1.1.4-66-g799ab57

Git user git at public.curoverse.com
Thu Jun 14 08:54:34 EDT 2018


Summary of changes:
 .../columns-configurator/columns-configurator.tsx  |  84 ++++------
 src/components/data-explorer/data-explorer.tsx     |   4 +-
 src/components/popover/popover.tsx                 |  53 +++++++
 .../project-explorer/project-explorer.tsx          | 171 ++++++++++++++++++---
 src/views/project-explorer/project-explorer.tsx    |  26 +++-
 5 files changed, 253 insertions(+), 85 deletions(-)
 create mode 100644 src/components/popover/popover.tsx

       via  799ab572df62562e8634e0e76683c3973c8337c4 (commit)
       via  6d53fc76c84291e57f33d55cb1f211bfb63b9f19 (commit)
       via  5361dea818f3f5c2b71ba4ce7ecb97e601c0403a (commit)
       via  a3620f307448f7854be04a12bce741385cc27ddd (commit)
      from  6471df421940db8b44adc93171a27659f7e3bdf1 (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 799ab572df62562e8634e0e76683c3973c8337c4
Author: Michal Klobukowski <michal.klobukowski at contractors.roche.com>
Date:   Thu Jun 14 14:54:20 2018 +0200

    Mock project explorer item actions
    
    Feature #13601
    
    Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski <michal.klobukowski at contractors.roche.com>

diff --git a/src/components/project-explorer/project-explorer.tsx b/src/components/project-explorer/project-explorer.tsx
index a764843..73d232b 100644
--- a/src/components/project-explorer/project-explorer.tsx
+++ b/src/components/project-explorer/project-explorer.tsx
@@ -4,7 +4,7 @@
 
 import * as React from 'react';
 import DataExplorer, { DataExplorerProps } from "../../components/data-explorer/data-explorer";
-import { Typography, Grid, ListItem, Divider, List } from '@material-ui/core';
+import { Typography, Grid, ListItem, Divider, List, ListItemIcon, ListItemText } from '@material-ui/core';
 import { Column } from '../../components/data-explorer/column';
 import IconButton, { IconButtonProps } from '@material-ui/core/IconButton';
 import MoreVertIcon from "@material-ui/icons/MoreVert";
@@ -92,10 +92,37 @@ class ProjectExplorer extends React.Component<ProjectExplorerProps, ProjectExplo
                 selected: true,
                 render: item => (
                     <Popover triggerComponent={ItemActionsTrigger}>
-                        <List>
-                            <ListItem>Share</ListItem>
-                            <Divider />
-                            <ListItem>Remove</ListItem>
+                        <List dense>
+                            {[
+                                {
+                                    icon: "fas fa-users",
+                                    label: "Share"
+                                },
+                                {
+                                    icon: "fas fa-sign-out-alt",
+                                    label: "Move to"
+                                },
+                                {
+                                    icon: "fas fa-star",
+                                    label: "Add to favourite"
+                                },
+                                {
+                                    icon: "fas fa-edit",
+                                    label: "Rename"
+                                },
+                                {
+                                    icon: "fas fa-copy",
+                                    label: "Make a copy"
+                                },
+                                {
+                                    icon: "fas fa-download",
+                                    label: "Download"
+                                }].map(renderAction)
+                            }
+                            < Divider />
+                            {
+                                renderAction({ icon: "fas fa-trash-alt", label: "Remove" })
+                            }
                         </List>
                     </Popover>
                 )
@@ -152,6 +179,17 @@ const renderIcon = (projectItem: ProjectItem) => {
     }
 };
 
+const renderAction = (action: { label: string, icon: string }, index?: number) => (
+    <ListItem button key={index}>
+        <ListItemIcon>
+            <i className={action.icon} />
+        </ListItemIcon>
+        <ListItemText>
+            {action.label}
+        </ListItemText>
+    </ListItem>
+);
+
 const ItemActionsTrigger: React.SFC<IconButtonProps> = (props) => (
     <IconButton {...props}>
         <MoreVertIcon />

commit 6d53fc76c84291e57f33d55cb1f211bfb63b9f19
Author: Michal Klobukowski <michal.klobukowski at contractors.roche.com>
Date:   Thu Jun 14 14:23:31 2018 +0200

    Make data-explorer onItemClick prop optional
    
    Feature #13601
    
    Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski <michal.klobukowski at contractors.roche.com>

diff --git a/src/components/data-explorer/data-explorer.tsx b/src/components/data-explorer/data-explorer.tsx
index 9090bff..f24d344 100644
--- a/src/components/data-explorer/data-explorer.tsx
+++ b/src/components/data-explorer/data-explorer.tsx
@@ -11,7 +11,7 @@ export interface DataExplorerProps<T> {
     items: T[];
     columns: Array<Column<T>>;
     onColumnToggle: (column: Column<T>) => void;
-    onItemClick: (item: T) => void;
+    onItemClick?: (item: T) => void;
 }
 
 class DataExplorer<T> extends React.Component<DataExplorerProps<T> & WithStyles<CssRules>> {
@@ -38,7 +38,7 @@ class DataExplorer<T> extends React.Component<DataExplorerProps<T> & WithStyles<
                                 <TableBody className={classes.tableBody}>
                                     {
                                         items.map((item, index) => (
-                                            <TableRow key={index} hover onClick={() => onItemClick(item)}>
+                                            <TableRow key={index} hover onClick={() => onItemClick && onItemClick(item)}>
                                                 {
                                                     columns.filter(column => column.selected).map((column, index) => (
                                                         <TableCell key={index}>

commit 5361dea818f3f5c2b71ba4ce7ecb97e601c0403a
Author: Michal Klobukowski <michal.klobukowski at contractors.roche.com>
Date:   Thu Jun 14 14:23:08 2018 +0200

    Create ProjectItem interface, update project explorer columns
    
    Feature #13601
    
    Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski <michal.klobukowski at contractors.roche.com>

diff --git a/src/components/project-explorer/project-explorer.tsx b/src/components/project-explorer/project-explorer.tsx
index 490e46f..a764843 100644
--- a/src/components/project-explorer/project-explorer.tsx
+++ b/src/components/project-explorer/project-explorer.tsx
@@ -4,33 +4,102 @@
 
 import * as React from 'react';
 import DataExplorer, { DataExplorerProps } from "../../components/data-explorer/data-explorer";
-import { RouteComponentProps } from 'react-router';
-import { Project } from '../../models/project';
-import { ProjectState, findTreeItem } from '../../store/project/project-reducer';
-import { RootState } from '../../store/store';
-import { connect, DispatchProp } from 'react-redux';
-import { push } from 'react-router-redux';
-import projectActions from "../../store/project/project-action";
-import { Typography } from '@material-ui/core';
+import { Typography, Grid, ListItem, Divider, List } from '@material-ui/core';
 import { Column } from '../../components/data-explorer/column';
+import IconButton, { IconButtonProps } from '@material-ui/core/IconButton';
+import MoreVertIcon from "@material-ui/icons/MoreVert";
+import Popover from '../popover/popover';
+
+export interface ProjectItem {
+    name: string;
+    type: string;
+    owner: string;
+    lastModified: string;
+    fileSize?: number;
+    status?: string;
+}
 
 interface ProjectExplorerProps {
-    projects: Project[];
-    onProjectClick: (project: Project) => void;
+    items: ProjectItem[];
+    onItemClick: (item: ProjectItem) => void;
 }
 
-type ProjectExplorerState = Pick<DataExplorerProps<Project>, "columns">;
+type ProjectExplorerState = Pick<DataExplorerProps<ProjectItem>, "columns">;
 
 class ProjectExplorer extends React.Component<ProjectExplorerProps, ProjectExplorerState> {
 
     state: ProjectExplorerState = {
         columns: [
-            { header: "Name", selected: true, render: item => <Typography noWrap>{renderIcon(item.kind)} {item.name}</Typography> },
-            { header: "Created at", selected: true, render: item => <Typography noWrap>{formatDate(item.createdAt)}</Typography> },
-            { header: "Modified at", selected: true, render: item => <Typography noWrap>{formatDate(item.modifiedAt)}</Typography> },
-            { header: "UUID", selected: true, render: item => <Typography noWrap>{item.uuid}</Typography> },
-            { header: "Owner UUID", selected: true, render: item => <Typography noWrap>{item.ownerUuid}</Typography> },
-            { header: "URL", selected: true, render: item => <Typography noWrap>{item.href}</Typography> }
+            {
+                header: "Name",
+                selected: true,
+                render: item => (
+                    <Grid container onClick={() => this.props.onItemClick(item)}>
+                        {renderIcon(item)}
+                        <Typography style={{ marginLeft: 8 }}>
+                            {item.name}
+                        </Typography>
+                    </Grid>
+                )
+            },
+            {
+                header: "Status",
+                selected: true,
+                render: item => (
+                    <Typography noWrap align="center">
+                        {item.status || "-"}
+                    </Typography>
+                )
+            },
+            {
+                header: "Type",
+                selected: true,
+                render: item => (
+                    <Typography noWrap>
+                        {item.type}
+                    </Typography>
+                )
+            },
+            {
+                header: "Owner",
+                selected: true,
+                render: item => (
+                    <Typography noWrap>
+                        {item.owner}
+                    </Typography>
+                )
+            },
+            {
+                header: "File size",
+                selected: true,
+                render: ({ fileSize }) => (
+                    <Typography noWrap>
+                        {typeof fileSize === "number" ? formatFileSize(fileSize) : "-"}
+                    </Typography>
+                )
+            },
+            {
+                header: "Last modified",
+                selected: true,
+                render: item => (
+                    <Typography noWrap>
+                        {formatDate(item.lastModified)}
+                    </Typography>
+                )
+            },
+            {
+                header: "Actions",
+                selected: true,
+                render: item => (
+                    <Popover triggerComponent={ItemActionsTrigger}>
+                        <List>
+                            <ListItem>Share</ListItem>
+                            <Divider />
+                            <ListItem>Remove</ListItem>
+                        </List>
+                    </Popover>
+                )
+            }
         ]
     };
 
@@ -38,14 +107,13 @@ class ProjectExplorer extends React.Component<ProjectExplorerProps, ProjectExplo
         return (
             <DataExplorer
                 columns={this.state.columns}
-                items={this.props.projects}
-                onItemClick={this.props.onProjectClick}
+                items={this.props.items}
                 onColumnToggle={this.toggleColumn}
             />
         );
     }
 
-    toggleColumn = (column: Column<Project>) => {
+    toggleColumn = (column: Column<ProjectItem>) => {
         const index = this.state.columns.indexOf(column);
         const columns = this.state.columns.slice(0);
         columns.splice(index, 1, { ...column, selected: !column.selected });
@@ -58,8 +126,23 @@ const formatDate = (isoDate: string) => {
     return date.toLocaleString();
 };
 
-const renderIcon = (kind: string) => {
-    switch (kind) {
+const formatFileSize = (size: number) => {
+    switch (true) {
+        case size > 1000000000000:
+            return `${size / 1000000000000} TB`;
+        case size > 1000000000:
+            return `${size / 1000000000} GB`;
+        case size > 1000000:
+            return `${size / 1000000} MB`;
+        case size > 1000:
+            return `${size / 1000} KB`;
+        default:
+            return `${size} B`;
+    }
+};
+
+const renderIcon = (projectItem: ProjectItem) => {
+    switch (projectItem.type) {
         case "arvados#group":
             return <i className="fas fa-folder" />;
         case "arvados#groupList":
@@ -69,4 +152,10 @@ const renderIcon = (kind: string) => {
     }
 };
 
+const ItemActionsTrigger: React.SFC<IconButtonProps> = (props) => (
+    <IconButton {...props}>
+        <MoreVertIcon />
+    </IconButton>
+);
+
 export default ProjectExplorer;
diff --git a/src/views/project-explorer/project-explorer.tsx b/src/views/project-explorer/project-explorer.tsx
index de91c0b..ec08b02 100644
--- a/src/views/project-explorer/project-explorer.tsx
+++ b/src/views/project-explorer/project-explorer.tsx
@@ -3,7 +3,7 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import * as React from 'react';
-import DataExplorer, { DataExplorerProps } from "../../components/data-explorer/data-explorer";
+import { DataExplorerProps } from "../../components/data-explorer/data-explorer";
 import { RouteComponentProps } from 'react-router';
 import { Project } from '../../models/project';
 import { ProjectState, findTreeItem } from '../../store/project/project-reducer';
@@ -11,9 +11,8 @@ import { RootState } from '../../store/store';
 import { connect, DispatchProp } from 'react-redux';
 import { push } from 'react-router-redux';
 import projectActions from "../../store/project/project-action";
-import { Typography } from '@material-ui/core';
-import { Column } from '../../components/data-explorer/column';
-import ProjectExplorer from '../../components/project-explorer/project-explorer';
+import ProjectExplorer, { ProjectItem } from '../../components/project-explorer/project-explorer';
+import { TreeItem } from '../../components/tree/tree';
 
 interface ProjectExplorerViewDataProps {
     projects: ProjectState;
@@ -23,6 +22,10 @@ type ProjectExplorerViewProps = ProjectExplorerViewDataProps & RouteComponentPro
 
 type ProjectExplorerViewState = Pick<DataExplorerProps<Project>, "columns">;
 
+interface MappedProjectItem extends ProjectItem {
+    uuid: string;
+}
+
 class ProjectExplorerView extends React.Component<ProjectExplorerViewProps, ProjectExplorerViewState> {
 
     render() {
@@ -30,19 +33,28 @@ class ProjectExplorerView extends React.Component<ProjectExplorerViewProps, Proj
         const projectItems = project && project.items || [];
         return (
             <ProjectExplorer
-                projects={projectItems.map(item => item.data)}
-                onProjectClick={this.goToProject}
+                items={projectItems.map(mapTreeItem)}
+                onItemClick={this.goToProject}
             />
         );
     }
 
-    goToProject = (project: Project) => {
+    goToProject = (project: MappedProjectItem) => {
         this.props.dispatch(push(`/project/${project.uuid}`));
         this.props.dispatch(projectActions.TOGGLE_PROJECT_TREE_ITEM(project.uuid));
     }
 
 }
 
+const mapTreeItem = (item: TreeItem<Project>): MappedProjectItem => ({
+    name: item.data.name,
+    type: item.data.kind,
+    owner: item.data.ownerUuid,
+    lastModified: item.data.modifiedAt,
+    uuid: item.data.uuid
+});
+
+
 export default connect(
     (state: RootState) => ({
         projects: state.projects

commit a3620f307448f7854be04a12bce741385cc27ddd
Author: Michal Klobukowski <michal.klobukowski at contractors.roche.com>
Date:   Thu Jun 14 13:24:30 2018 +0200

    Create popover component, replace popover in columns configurator
    
    Feature #13601
    
    Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski <michal.klobukowski at contractors.roche.com>

diff --git a/src/components/data-explorer/columns-configurator/columns-configurator.tsx b/src/components/data-explorer/columns-configurator/columns-configurator.tsx
index 5a3fb01..a46d224 100644
--- a/src/components/data-explorer/columns-configurator/columns-configurator.tsx
+++ b/src/components/data-explorer/columns-configurator/columns-configurator.tsx
@@ -3,70 +3,46 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import * as React from 'react';
-import { WithStyles, StyleRulesCallback, Theme, withStyles, IconButton, Popover, Paper, List, Checkbox, ListItemText, ListItem, Typography, ListSubheader } from '@material-ui/core';
+import { WithStyles, StyleRulesCallback, Theme, withStyles, IconButton, Paper, List, Checkbox, ListItemText, ListItem, Typography, ListSubheader } from '@material-ui/core';
 import MenuIcon from "@material-ui/icons/Menu";
 import { Column } from '../column';
 import { PopoverOrigin } from '@material-ui/core/Popover';
+import Popover from "../../popover/popover";
+import { IconButtonProps } from '@material-ui/core/IconButton';
 
 export interface ColumnsConfiguratorProps {
     columns: Array<Column<any>>;
     onColumnToggle: (column: Column<any>) => void;
 }
 
-
-class ColumnsConfigurator extends React.Component<ColumnsConfiguratorProps & WithStyles<CssRules>> {
-
-    state = {
-        anchorEl: undefined
-    };
-
-    transformOrigin: PopoverOrigin = {
-        vertical: "top",
-        horizontal: "right",
-    };
-
-    render() {
-        const { columns, onColumnToggle, classes } = this.props;
-        return (
-            <>
-                <IconButton onClick={this.handleClick}><MenuIcon /></IconButton>
-                <Popover
-                    anchorEl={this.state.anchorEl}
-                    open={Boolean(this.state.anchorEl)}
-                    onClose={this.handleClose}
-                    transformOrigin={this.transformOrigin}
-                    anchorOrigin={this.transformOrigin}
-                >
-                    <Paper>
-                        <List dense>
-                            <ListSubheader>
-                                Configure table columns
+const ColumnsConfigurator: React.SFC<ColumnsConfiguratorProps & WithStyles<CssRules>> = ({ columns, onColumnToggle, classes }) => {
+    return (
+        <Popover triggerComponent={ColumnsConfiguratorTrigger}>
+            <Paper>
+                <List dense>
+                    <ListSubheader>
+                        Configure table columns
                             </ListSubheader>
-                            {
-                                columns.map((column, index) => (
-                                    <ListItem key={index} button onClick={() => onColumnToggle(column)}>
-                                        <Checkbox disableRipple color="primary" checked={column.selected} className={classes.checkbox} />
-                                        <ListItemText>{column.header}</ListItemText>
-                                    </ListItem>
-
-                                ))
-                            }
-                        </List>
-                    </Paper>
-                </Popover>
-            </>
-        );
-    }
-
-    handleClose = () => {
-        this.setState({ anchorEl: undefined });
-    }
-
-    handleClick = (event: React.MouseEvent<HTMLElement>) => {
-        this.setState({ anchorEl: event.currentTarget });
-    }
-
-}
+                    {
+                        columns.map((column, index) => (
+                            <ListItem key={index} button onClick={() => onColumnToggle(column)}>
+                                <Checkbox disableRipple color="primary" checked={column.selected} className={classes.checkbox} />
+                                <ListItemText>{column.header}</ListItemText>
+                            </ListItem>
+
+                        ))
+                    }
+                </List>
+            </Paper>
+        </Popover>
+    );
+};
+
+const ColumnsConfiguratorTrigger: React.SFC<IconButtonProps> = (props) => (
+    <IconButton {...props}>
+        <MenuIcon />
+    </IconButton>
+);
 
 type CssRules = "root" | "checkbox";
 
diff --git a/src/components/popover/popover.tsx b/src/components/popover/popover.tsx
new file mode 100644
index 0000000..b7e082b
--- /dev/null
+++ b/src/components/popover/popover.tsx
@@ -0,0 +1,53 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import * as React from 'react';
+import { Popover as MaterialPopover } from '@material-ui/core';
+
+import { PopoverOrigin } from '@material-ui/core/Popover';
+
+export interface PopoverProps {
+    triggerComponent: React.ComponentType<{ onClick: (event: React.MouseEvent<any>) => void }>;
+}
+
+
+class Popover extends React.Component<PopoverProps> {
+
+    state = {
+        anchorEl: undefined
+    };
+
+    transformOrigin: PopoverOrigin = {
+        vertical: "top",
+        horizontal: "right",
+    };
+
+    render() {
+        return (
+            <>
+                <this.props.triggerComponent onClick={this.handleClick} />
+                <MaterialPopover
+                    anchorEl={this.state.anchorEl}
+                    open={Boolean(this.state.anchorEl)}
+                    onClose={this.handleClose}
+                    transformOrigin={this.transformOrigin}
+                    anchorOrigin={this.transformOrigin}
+                >
+                    {this.props.children}
+                </MaterialPopover>
+            </>
+        );
+    }
+
+    handleClose = () => {
+        this.setState({ anchorEl: undefined });
+    }
+
+    handleClick = (event: React.MouseEvent<any>) => {
+        this.setState({ anchorEl: event.currentTarget });
+    }
+
+}
+
+export default Popover;

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


hooks/post-receive
-- 




More information about the arvados-commits mailing list