[ARVADOS-WORKBENCH2] updated: 8bfcbaea5e9f11543bbc4d721817978e621d2ffa

Git user git at public.curoverse.com
Mon Jun 11 08:03:15 EDT 2018


Summary of changes:
 .../main-app-bar/breadcrumbs/breadcrumbs.tsx       |  31 +++-
 .../main-app-bar/dropdown-menu/dropdown-menu.tsx   |  71 +++++++++
 src/components/main-app-bar/main-app-bar.tsx       | 118 ++++++++++----
 src/views/workbench/workbench.tsx                  | 172 +++++++++++----------
 4 files changed, 277 insertions(+), 115 deletions(-)
 create mode 100644 src/components/main-app-bar/dropdown-menu/dropdown-menu.tsx

       via  8bfcbaea5e9f11543bbc4d721817978e621d2ffa (commit)
       via  8ac033564cfcdc53707cf138c9818328bed78fa4 (commit)
       via  c97df9311cc2fa0142dbc9f234e452b6c28763cc (commit)
       via  6752fb200db07abfd5f98d3838729139fb073dfe (commit)
       via  ca98b15be85d6d8a8f872224ed8a0c2eed7d8f27 (commit)
      from  a9deea73c1982bf90150c6dbc8caca385ad68d04 (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 8bfcbaea5e9f11543bbc4d721817978e621d2ffa
Author: Michal Klobukowski <michal.klobukowski at contractors.roche.com>
Date:   Mon Jun 11 13:46:48 2018 +0200

    Add new main app bar to workbench
    
    Feature #13590
    
    Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski <michal.klobukowski at contractors.roche.com>

diff --git a/src/views/workbench/workbench.tsx b/src/views/workbench/workbench.tsx
index dbf7832..15f6fa5 100644
--- a/src/views/workbench/workbench.tsx
+++ b/src/views/workbench/workbench.tsx
@@ -24,7 +24,9 @@ import { AccountCircle } from "@material-ui/icons";
 import { User } from "../../models/user";
 import Grid from "@material-ui/core/Grid/Grid";
 import { RootState } from "../../store/store";
-import MainAppBar from '../../components/main-app-bar/main-app-bar';
+import MainAppBar, { MainAppBarActionProps, MainAppBarMenuItems, MainAppBarMenuItem } from '../../components/main-app-bar/main-app-bar';
+import { Breadcrumb } from '../../components/main-app-bar/breadcrumbs/breadcrumbs';
+import { push } from 'react-router-redux';
 
 const drawerWidth = 240;
 
@@ -42,7 +44,9 @@ const styles: StyleRulesCallback<CssRules> = (theme: Theme) => ({
     },
     appBar: {
         zIndex: theme.zIndex.drawer + 1,
-        backgroundColor: '#692498'
+        backgroundColor: '#692498',
+        position: "absolute",
+        width: "100%"
     },
     drawerPaper: {
         position: 'relative',
@@ -68,104 +72,104 @@ interface WorkbenchActionProps {
 
 type WorkbenchProps = WorkbenchDataProps & WorkbenchActionProps & DispatchProp & WithStyles<CssRules>;
 
+interface NavBreadcrumb extends Breadcrumb {
+    path: string
+}
+
+interface NavMenuItem extends MainAppBarMenuItem {
+    action: () => void
+}
+
 interface WorkbenchState {
     anchorEl: any;
+    breadcrumbs: NavBreadcrumb[];
+    searchQuery: string;
+    menuItems: {
+        accountMenu: NavMenuItem[],
+        helpMenu: NavMenuItem[],
+        anonymousMenu: NavMenuItem[]
+    };
 }
 
 class Workbench extends React.Component<WorkbenchProps, WorkbenchState> {
-    constructor(props: WorkbenchProps) {
-        super(props);
-        this.state = {
-            anchorEl: null
+    state = {
+        anchorEl: null,
+        searchQuery: "",
+        breadcrumbs: [
+            {
+                label: "Projects",
+                path: "/projects"
+            }, {
+                label: "Project 1",
+                path: "/projects/project-1"
+            }
+        ],
+        menuItems: {
+            accountMenu: [
+                {
+                    label: "Logout",
+                    action: () => this.props.dispatch(authActions.LOGOUT())
+                },
+                {
+                    label: "My account",
+                    action: () => this.props.dispatch(push("/my-account"))
+                }
+            ],
+            helpMenu: [
+                {
+                    label: "Help",
+                    action: () => this.props.dispatch(push("/help"))
+                }
+            ],
+            anonymousMenu: [
+                {
+                    label: "Sign in",
+                    action: () => this.props.dispatch(authActions.LOGIN())
+                }
+            ]
         }
     }
 
-    login = () => {
-        this.props.dispatch(authActions.LOGIN());
-    };
 
-    logout = () => {
-        this.handleClose();
-        this.props.dispatch(authActions.LOGOUT());
-    };
-
-    handleOpenMenu = (event: React.MouseEvent<any>) => {
-        this.setState({
-            anchorEl: event.currentTarget
-        });
-    };
-
-    handleClose = () => {
-        this.setState({
-            anchorEl: null
-        });
-    };
+    mainAppBarActions: MainAppBarActionProps = {
+        actions: {
+            onBreadcrumbClick: (breadcrumb: NavBreadcrumb) => this.props.dispatch(push(breadcrumb.path)),
+            onSearchQueryChange: searchQuery => this.setState({ searchQuery }),
+            onSearchQuerySubmit: () => this.props.dispatch(push(`/search?q=${this.state.searchQuery}`)),
+            onMenuItemClick: (menuItem: NavMenuItem) => menuItem.action()
+        }
+    }
 
     render() {
-        const {classes, user} = this.props;
+        const { classes, user } = this.props;
         return (
             <div className={classes.root}>
-                <AppBar position="absolute" className={classes.appBar}>
-                    <Toolbar>
-                        <Typography variant="title" color="inherit" noWrap style={{flexGrow: 1}}>
-                            <span>Arvados</span><br/><span style={{fontSize: 12}}>Workbench 2</span>
-                        </Typography>
-                        {user ?
-                            <Grid container style={{width: 'auto'}}>
-                                <Grid container style={{width: 'auto'}} alignItems='center'>
-                                    <Typography variant="title" color="inherit" noWrap>
-                                        {user.firstName} {user.lastName}
-                                    </Typography>
-                                </Grid>
-                                <Grid item>
-                                    <IconButton
-                                          aria-owns={this.state.anchorEl ? 'menu-appbar' : undefined}
-                                          aria-haspopup="true"
-                                          onClick={this.handleOpenMenu}
-                                          color="inherit">
-                                      <AccountCircle/>
-                                    </IconButton>
-                                </Grid>
-                                <Menu
-                                  id="menu-appbar"
-                                  anchorEl={this.state.anchorEl}
-                                  anchorOrigin={{
-                                    vertical: 'top',
-                                    horizontal: 'right',
-                                  }}
-                                  transformOrigin={{
-                                    vertical: 'top',
-                                    horizontal: 'right',
-                                  }}
-                                  open={!!this.state.anchorEl}
-                                  onClose={this.handleClose}>
-                                  <MenuItem onClick={this.logout}>Logout</MenuItem>
-                                  <MenuItem onClick={this.handleClose}>My account</MenuItem>
-                                </Menu>
-                            </Grid>
-                            :
-                            <Button color="inherit" onClick={this.login}>Login</Button>
-                        }
-                    </Toolbar>
-                </AppBar>
+                <div className={classes.appBar}>
+                    <MainAppBar
+                        breadcrumbs={this.state.breadcrumbs}
+                        searchQuery={this.state.searchQuery}
+                        user={this.props.user}
+                        menuItems={this.state.menuItems}
+                        actions={this.mainAppBarActions.actions}
+                    />
+                </div>
                 {user &&
-                <Drawer
-                    variant="permanent"
-                    classes={{
-                        paper: classes.drawerPaper,
-                    }}>
-                    <div className={classes.toolbar}/>
-                    <div className={classes.toolbar}/>
-                    <Tree items={this.props.projects} render={(p: Project) =>
-                        <Link to={`/project/${p.name}`}>{p.name}</Link>
-                    }/>
-                </Drawer>}
+                    <Drawer
+                        variant="permanent"
+                        classes={{
+                            paper: classes.drawerPaper,
+                        }}>
+                        <div className={classes.toolbar} />
+                        <div className={classes.toolbar} />
+                        <Tree items={this.props.projects} render={(p: Project) =>
+                            <Link to={`/project/${p.name}`}>{p.name}</Link>
+                        } />
+                    </Drawer>}
                 <main className={classes.content}>
-                    <div className={classes.toolbar}/>
-                    <div className={classes.toolbar}/>
-                    <MainAppBar/>
+                    <div className={classes.toolbar} />
+                    <div className={classes.toolbar} />
                     <Switch>
-                        <Route path="/project/:name" component={ProjectList}/>
+                        <Route path="/project/:name" component={ProjectList} />
                     </Switch>
                 </main>
             </div>

commit 8ac033564cfcdc53707cf138c9818328bed78fa4
Author: Michal Klobukowski <michal.klobukowski at contractors.roche.com>
Date:   Mon Jun 11 13:39:55 2018 +0200

    Add generic app bar menu rendering, extend main app bar props
    
    Feature #13590
    
    Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski <michal.klobukowski at contractors.roche.com>

diff --git a/src/components/main-app-bar/main-app-bar.tsx b/src/components/main-app-bar/main-app-bar.tsx
index 885948f..f5d4cc3 100644
--- a/src/components/main-app-bar/main-app-bar.tsx
+++ b/src/components/main-app-bar/main-app-bar.tsx
@@ -3,26 +3,47 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import * as React from "react";
-import { AppBar, Toolbar, Typography, Grid, IconButton, Badge, Paper, Input, StyleRulesCallback, withStyles, WithStyles } from "@material-ui/core";
+import { AppBar, Toolbar, Typography, Grid, IconButton, Badge, Paper, Input, StyleRulesCallback, withStyles, WithStyles, Button, MenuItem } from "@material-ui/core";
 import NotificationsIcon from "@material-ui/icons/Notifications";
 import PersonIcon from "@material-ui/icons/Person";
 import HelpIcon from "@material-ui/icons/Help";
-import SearchIcon from "@material-ui/icons/Search";
-import { AppBarProps } from "@material-ui/core/AppBar";
 import SearchBar from "./search-bar/search-bar";
-import Breadcrumbs from "./breadcrumbs/breadcrumbs"
+import Breadcrumbs, { Breadcrumb } from "./breadcrumbs/breadcrumbs"
+import DropdownMenu from "./dropdown-menu/dropdown-menu"
+import { User } from "../../models/user";
 
-type CssRules = "appBar"
+export interface MainAppBarMenuItem {
+    label: string
+}
 
-const styles: StyleRulesCallback<CssRules> = theme => ({
-    appBar: {
-        backgroundColor: "#692498"
+export interface MainAppBarMenuItems {
+    accountMenu: MainAppBarMenuItem[];
+    helpMenu: MainAppBarMenuItem[];
+    anonymousMenu: MainAppBarMenuItem[];
+}
+
+interface MainAppBarDataProps {
+    searchQuery: string,
+    breadcrumbs: Breadcrumb[],
+    user?: User,
+    menuItems: MainAppBarMenuItems
+}
+
+export interface MainAppBarActionProps {
+    actions: {
+        onSearchQueryChange: (searchQuery: string) => void,
+        onSearchQuerySubmit: () => void,
+        onBreadcrumbClick: (breadcrumb: Breadcrumb) => void,
+        onMenuItemClick: (menuItem: MainAppBarMenuItem) => void
     }
-})
+}
+
+type MainAppBarProps = MainAppBarDataProps & MainAppBarActionProps & WithStyles<CssRules>;
+
+export class MainAppBar extends React.Component<MainAppBarProps> {
 
-export class MainAppBar extends React.Component<WithStyles<CssRules>> {
     render() {
-        const { classes } = this.props
+        const { classes, searchQuery, breadcrumbs } = this.props
         return <AppBar className={classes.appBar} position="static">
             <Toolbar>
                 <Grid
@@ -35,29 +56,74 @@ export class MainAppBar extends React.Component<WithStyles<CssRules>> {
                         </Typography>
                     </Grid>
                     <Grid item xs={6} container alignItems="center">
-                        <SearchBar value="" onChange={console.log} onSubmit={() => console.log("submit")} />
+                        {
+                            this.props.user && <SearchBar
+                                value={searchQuery}
+                                onChange={this.props.actions.onSearchQueryChange}
+                                onSubmit={this.props.actions.onSearchQuerySubmit}
+                            />
+                        }
                     </Grid>
                     <Grid item xs={3} container alignItems="center" justify="flex-end">
-                        <IconButton color="inherit">
-                            <Badge badgeContent={3} color="primary">
-                                <NotificationsIcon />
-                            </Badge>
-                        </IconButton>
-                        <IconButton color="inherit">
-                            <PersonIcon />
-                        </IconButton>
-                        <IconButton color="inherit">
-                            <HelpIcon />
-                        </IconButton>
+                        {
+                            this.props.user ? this.renderMenuForUser() : this.renderMenuForAnonymous()
+                        }
                     </Grid>
                 </Grid>
             </Toolbar>
-            <Toolbar>
-                <Breadcrumbs items={["Projects", "Project 1"]} />
-            </Toolbar>
+            {
+                this.props.user && <Toolbar>
+                    <Breadcrumbs items={breadcrumbs} onClick={this.props.actions.onBreadcrumbClick} />
+                </Toolbar>
+            }
         </AppBar>
     }
 
+    renderMenuForUser = () => {
+        const { user, actions } = this.props
+        return (
+            <>
+                <IconButton color="inherit">
+                    <Badge badgeContent={3} color="primary">
+                        <NotificationsIcon />
+                    </Badge>
+                </IconButton>
+                <DropdownMenu icon={PersonIcon} id="account-menu">
+                    <MenuItem>{this.getUserFullname()}</MenuItem>
+                    {this.renderMenuItems(this.props.menuItems.accountMenu)}
+                </DropdownMenu>
+                <DropdownMenu icon={HelpIcon} id="help-menu">
+                    {this.renderMenuItems(this.props.menuItems.helpMenu)}
+                </DropdownMenu>
+            </>
+        )
+    }
+
+    renderMenuForAnonymous = () => {
+        return this.props.menuItems.anonymousMenu.map((item, index) => (
+            <Button color="inherit" onClick={() => this.props.actions.onMenuItemClick(item)}>{item.label}</Button>
+        ))
+    }
+
+    renderMenuItems = (menuItems: MainAppBarMenuItem[]) => {
+        return menuItems.map((item, index) => (
+            <MenuItem key={index} onClick={() => this.props.actions.onMenuItemClick(item)}>{item.label}</MenuItem>
+        ))
+    }
+
+    getUserFullname = () => {
+        const { user } = this.props;
+        return user ? `${user.firstName} ${user.lastName}` : "";
+    }
+
 }
 
+type CssRules = "appBar"
+
+const styles: StyleRulesCallback<CssRules> = theme => ({
+    appBar: {
+        backgroundColor: "#692498"
+    }
+})
+
 export default withStyles(styles)(MainAppBar)
\ No newline at end of file

commit c97df9311cc2fa0142dbc9f234e452b6c28763cc
Author: Michal Klobukowski <michal.klobukowski at contractors.roche.com>
Date:   Mon Jun 11 13:01:01 2018 +0200

    Add breadcrumb interface export
    
    Feature #13590
    
    Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski <michal.klobukowski at contractors.roche.com>

diff --git a/src/components/main-app-bar/breadcrumbs/breadcrumbs.tsx b/src/components/main-app-bar/breadcrumbs/breadcrumbs.tsx
index 5521ac2..6c2d1fb 100644
--- a/src/components/main-app-bar/breadcrumbs/breadcrumbs.tsx
+++ b/src/components/main-app-bar/breadcrumbs/breadcrumbs.tsx
@@ -7,7 +7,7 @@ import { Button, Grid, StyleRulesCallback, WithStyles } from '@material-ui/core'
 import ChevronRightIcon from '@material-ui/icons/ChevronRight';
 import { withStyles } from '@material-ui/core';
 
-interface Breadcrumb {
+export interface Breadcrumb {
     label: string
 }
 

commit 6752fb200db07abfd5f98d3838729139fb073dfe
Author: Michal Klobukowski <michal.klobukowski at contractors.roche.com>
Date:   Mon Jun 11 12:04:41 2018 +0200

    Create dropdown menu component
    
    Feature #13590
    
    Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski <michal.klobukowski at contractors.roche.com>

diff --git a/src/components/main-app-bar/dropdown-menu/dropdown-menu.tsx b/src/components/main-app-bar/dropdown-menu/dropdown-menu.tsx
new file mode 100644
index 0000000..533e5a4
--- /dev/null
+++ b/src/components/main-app-bar/dropdown-menu/dropdown-menu.tsx
@@ -0,0 +1,71 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import * as React from 'react';
+import { Button, Grid, StyleRulesCallback, WithStyles, Menu, MenuItem } from '@material-ui/core';
+import ChevronRightIcon from '@material-ui/icons/ChevronRight';
+import { withStyles } from '@material-ui/core';
+import { IconButton } from '@material-ui/core/es';
+import { PopoverOrigin } from '@material-ui/core/Popover';
+
+
+interface DropdownMenuDataProps {
+    id: string,
+    icon: React.ComponentType,
+}
+
+
+type DropdownMenuProps = DropdownMenuDataProps;
+
+class DropdownMenu extends React.Component<DropdownMenuProps> {
+
+    state = {
+        anchorEl: undefined
+    }
+
+    transformOrigin: PopoverOrigin = {
+        vertical: "top",
+        horizontal: "center"
+    }
+
+    render() {
+        const { icon: Icon, id, children } = this.props;
+        const { anchorEl } = this.state;
+        return (
+            <div>
+                <IconButton
+                    aria-owns={anchorEl ? id : undefined}
+                    aria-haspopup="true"
+                    color="inherit"
+                    onClick={this.handleOpen}
+
+                >
+                    <Icon />
+                </IconButton>
+                <Menu
+                    id={id}
+                    anchorEl={anchorEl}
+                    open={Boolean(anchorEl)}
+                    onClose={this.handleClose}
+                    onClick={this.handleClose}
+                    anchorOrigin={this.transformOrigin}
+                    transformOrigin={this.transformOrigin}
+                >
+                    {children}
+                </Menu>
+            </div>
+        )
+    }
+
+    handleClose = () => {
+        this.setState({ anchorEl: undefined })
+    }
+
+    handleOpen = (event: React.MouseEvent<HTMLButtonElement>) => {
+        this.setState({ anchorEl: event.currentTarget })
+    }
+}
+
+
+export default DropdownMenu

commit ca98b15be85d6d8a8f872224ed8a0c2eed7d8f27
Author: Michal Klobukowski <michal.klobukowski at contractors.roche.com>
Date:   Mon Jun 11 09:18:38 2018 +0200

    Add onclick handler to breadcrumbs component
    
    Feature #13590
    
    Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski <michal.klobukowski at contractors.roche.com>

diff --git a/src/components/main-app-bar/breadcrumbs/breadcrumbs.tsx b/src/components/main-app-bar/breadcrumbs/breadcrumbs.tsx
index 9803683..5521ac2 100644
--- a/src/components/main-app-bar/breadcrumbs/breadcrumbs.tsx
+++ b/src/components/main-app-bar/breadcrumbs/breadcrumbs.tsx
@@ -7,28 +7,48 @@ import { Button, Grid, StyleRulesCallback, WithStyles } from '@material-ui/core'
 import ChevronRightIcon from '@material-ui/icons/ChevronRight';
 import { withStyles } from '@material-ui/core';
 
+interface Breadcrumb {
+    label: string
+}
+
 interface BreadcrumbsDataProps {
-    items: string[]
+    items: Breadcrumb[]
 }
 
-type BreadcrumbsProps = BreadcrumbsDataProps & WithStyles<CssRules>;
+interface BreadcrumbsActionProps {
+    onClick: (breadcrumb: Breadcrumb) => any
+}
+
+type BreadcrumbsProps = BreadcrumbsDataProps & BreadcrumbsActionProps & WithStyles<CssRules>;
 
 class Breadcrumbs extends React.Component<BreadcrumbsProps> {
 
     render() {
-        const { classes } = this.props;
+        const { classes, onClick } = this.props;
         return <Grid container alignItems="center">
             {
                 this.getInactiveItems().map((item, index) => (
                     <React.Fragment key={index}>
-                        <Button color="inherit" className={classes.inactiveItem}>{item}</Button>
+                        <Button
+                            color="inherit"
+                            className={classes.inactiveItem}
+                            onClick={() => onClick(item)}
+                        >
+                            {item.label}
+                        </Button>
                         <ChevronRightIcon color="inherit" className={classes.inactiveItem} />
                     </React.Fragment>
                 ))
             }
             {
                 this.getActiveItem().map((item, index) => (
-                    <Button key={index} color="inherit">{item}</Button>
+                    <Button
+                        color="inherit"
+                        key={index}
+                        onClick={() => onClick(item)}
+                    >
+                        {item.label}
+                    </Button>
                 ))
             }
         </Grid>
@@ -41,6 +61,7 @@ class Breadcrumbs extends React.Component<BreadcrumbsProps> {
     getActiveItem = () => {
         return this.props.items.slice(-1)
     }
+
 }
 
 type CssRules = 'inactiveItem'

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


hooks/post-receive
-- 




More information about the arvados-commits mailing list