import blue from '@material-ui/core/colors/blue';
import grey from '@material-ui/core/colors/grey';
import green from '@material-ui/core/colors/green';
+import yellow from '@material-ui/core/colors/yellow';
+import red from '@material-ui/core/colors/red';
interface ArvadosThemeOptions extends ThemeOptions {
customs: any;
customs: any;
}
+// const red =
+const yellow700 = yellow["700"];
const purple800 = purple["800"];
+const grey200 = grey["200"];
+const grey300 = grey["300"];
+const grey500 = grey["500"];
const grey600 = grey["600"];
+const grey700 = grey["700"];
+const grey900 = grey["900"];
+
const themeOptions: ArvadosThemeOptions = {
customs: {
colors: {
}
},
overrides: {
+ MuiTypography: {
+ body1: {
+ fontSize: '0.8125rem'
+ }
+ },
MuiAppBar: {
colorPrimary: {
backgroundColor: purple800
fontWeight: 700,
color: purple800
}
+ },
+ MuiList: {
+ root: {
+ color: grey900
+ }
+ },
+ MuiListItemText: {
+ root: {
+ padding: 0
+ }
+ },
+ MuiListItemIcon: {
+ root: {
+ fontSize: '1.25rem'
+ }
}
},
mixins: {
--- /dev/null
+// 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 { ListItemIcon, ListItemText, Typography } from '@material-ui/core';
+import { IconType } from '../icon/icon';
+import * as classnames from "classnames";
+
+export interface ListItemTextIconDataProps {
+ icon: IconType;
+ name: string;
+ isActive?: boolean;
+ hasMargin?: boolean;
+}
+
+type ListItemTextIconProps = ListItemTextIconDataProps & WithStyles<CssRules>;
+
+class ListItemTextIcon extends React.Component<ListItemTextIconProps, {}> {
+ render() {
+ const { classes, isActive, hasMargin, name, icon: Icon } = this.props;
+ return (
+ <Typography component='span' className={classes.root}>
+ <ListItemIcon className={classnames({
+ [classes.hasMargin]: hasMargin,
+ [classes.active]: isActive
+ })}>
+ <Icon />
+ </ListItemIcon>
+ <ListItemText primary={
+ <Typography variant='body1' className={classnames(classes.listItemText, {
+ [classes.active]: isActive
+ })}>
+ {name}
+ </Typography>
+ } />
+ </Typography>
+ );
+ }
+}
+
+type CssRules = 'root' | 'listItemText' | 'hasMargin' | 'active';
+
+const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
+ root: {
+ display: 'flex',
+ alignItems: 'center'
+ },
+ listItemText: {
+ fontWeight: 700
+ },
+ active: {
+ color: theme.palette.primary.main,
+ },
+ hasMargin: {
+ marginLeft: '18px',
+ },
+});
+
+export default withStyles(styles)(ListItemTextIcon);
\ No newline at end of file
import { List, ListItem, ListItemText, ListItemIcon, Collapse, Typography } 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';
export interface SidePanelItem {
id: string;
class SidePanel extends React.Component<SidePanelProps & WithStyles<CssRules>> {
render(): ReactElement<any> {
const { classes, toggleOpen, toggleActive, sidePanelItems, children } = this.props;
- const { listItemText, leftSidePanelContainer, row, list, icon, projectIconMargin, active, iconArrowContainer } = classes;
+ const { root, row, list, toggableIconContainer } = classes;
return (
- <div className={leftSidePanelContainer}>
+ <div className={root}>
<List>
{sidePanelItems.map(it => (
<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={iconArrowContainer}>
- <SidePanelRightArrowIcon className={this.getIconClassNames(it.open, it.active)} />
+ <i onClick={() => toggleOpen(it.id)} className={toggableIconContainer}>
+ <ListItemIcon className={this.getToggableIconClassNames(it.open, it.active)}>
+ < SidePanelRightArrowIcon />
+ </ListItemIcon>
</i>
) : null}
- <ListItemIcon className={it.active ? active : ''}>
- {<it.icon className={`${icon} ${it.margin ? projectIconMargin : ''}`} />}
- </ListItemIcon>
- <ListItemText className={listItemText}
- primary={renderListItemText(it.name, active, it.active)} />
+ <ListItemTextIcon icon={it.icon} name={it.name} isActive={it.active} hasMargin={it.margin} />
</span>
</ListItem>
{it.openAble ? (
);
}
- getIconClassNames = (itemOpen ?: boolean, itemActive ?: boolean) => {
+ getToggableIconClassNames = (isOpen?: boolean, isActive ?: boolean) => {
const { classes } = this.props;
- return classnames(classes.iconArrow, {
- [classes.iconOpen]: itemOpen,
- [classes.iconClose]: !itemOpen,
- [classes.active]: itemActive
+ return classnames(classes.toggableIcon, {
+ [classes.iconOpen]: isOpen,
+ [classes.iconClose]: !isOpen,
+ [classes.active]: isActive
});
}
}
-const renderListItemText = (itemName: string, active: string, itemActive?: boolean) =>
- <Typography className={itemActive ? active : ''}>{itemName}</Typography>;
-
-type CssRules = 'active' | 'listItemText' | 'row' | 'leftSidePanelContainer' | 'list' | 'icon' |
- 'projectIconMargin' | 'iconClose' | 'iconOpen' | 'iconArrowContainer' | 'iconArrow';
+type CssRules = 'active' | 'row' | 'root' | 'list' | 'iconClose' | 'iconOpen' | 'toggableIconContainer' | 'toggableIcon';
const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
- active: {
- color: theme.palette.primary.main,
+ root: {
+ overflowY: 'auto',
+ minWidth: '240px',
+ whiteSpace: 'nowrap',
+ marginTop: '52px',
+ display: 'flex',
+ flexGrow: 1,
},
- listItemText: {
- padding: '0px',
+ list: {
+ padding: '5px 0px 5px 14px',
+ minWidth: '240px',
},
row: {
display: 'flex',
alignItems: 'center',
},
- iconArrowContainer: {
+ toggableIconContainer: {
color: theme.palette.grey["700"],
height: '14px',
position: 'absolute'
},
- iconArrow: {
+ toggableIcon: {
fontSize: '14px'
},
+ active: {
+ color: theme.palette.primary.main,
+ },
iconClose: {
transition: 'all 0.1s ease',
},
iconOpen: {
transition: 'all 0.1s ease',
transform: 'rotate(90deg)',
- },
- leftSidePanelContainer: {
- overflowY: 'auto',
- minWidth: '240px',
- whiteSpace: 'nowrap',
- marginTop: '52px',
- display: 'flex',
- flexGrow: 1,
- },
- list: {
- padding: '5px 0px 5px 14px',
- minWidth: '240px',
- },
- icon: {
- fontSize: '20px'
- },
- projectIconMargin: {
- marginLeft: '17px',
}
});
import * as React from 'react';
import List from "@material-ui/core/List/List";
import ListItem from "@material-ui/core/ListItem/ListItem";
-import { StyleRulesCallback, Theme, withStyles, WithStyles } from '@material-ui/core/styles';
+import { StyleRulesCallback, withStyles, WithStyles } from '@material-ui/core/styles';
import { ReactElement } from "react";
import Collapse from "@material-ui/core/Collapse/Collapse";
import CircularProgress from '@material-ui/core/CircularProgress';
+import { ArvadosTheme } from '../../common/custom-theme';
export enum TreeItemStatus {
Initial,
</div>)}
</List>;
}
+
renderArrow(status: TreeItemStatus, arrowClass: string, open: boolean, id: string) {
const { arrowTransition, arrowVisibility, arrowRotate } = this.props.classes;
return <i onClick={() => this.props.toggleItemOpen(id, status)}
type CssRules = 'list' | 'activeArrow' | 'inactiveArrow' | 'arrowRotate' | 'arrowTransition' | 'loader' | 'arrowVisibility';
-const styles: StyleRulesCallback<CssRules> = (theme: Theme) => ({
+const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
list: {
paddingBottom: '3px',
paddingTop: '3px',
},
activeArrow: {
- color: '#4285F6',
+ color: theme.palette.primary.main,
position: 'absolute',
},
inactiveArrow: {
+ color: theme.palette.grey["700"],
position: 'absolute',
},
arrowTransition: {
onClick={props.onBreadcrumbClick}
onContextMenu={props.onContextMenu} />
}
- <IconButton color="inherit" onClick={props.onDetailsPanelToggle}>
- { <DetailsIcon /> }
- </IconButton>
+ { props.user && <IconButton color="inherit" onClick={props.onDetailsPanelToggle}>
+ <DetailsIcon />
+ </IconButton>
+ }
</Toolbar>
</AppBar>;
};
<>
<IconButton color="inherit">
<Badge badgeContent={3} color="primary">
- {<NotificationIcon />}
+ <NotificationIcon />
</Badge>
</IconButton>
<DropdownMenu icon={<UserPanelIcon />} id="account-menu">
import * as React from 'react';
import { ReactElement } from 'react';
import { StyleRulesCallback, Theme, WithStyles, withStyles } from '@material-ui/core/styles';
-import ListItemText from "@material-ui/core/ListItemText/ListItemText";
-import ListItemIcon from '@material-ui/core/ListItemIcon';
-import Typography from '@material-ui/core/Typography';
-
import Tree, { TreeItem, TreeItemStatus } from '../../components/tree/tree';
import { ProjectResource } from '../../models/project';
+import { ProjectIcon } from '../../components/icon/icon';
+import { ArvadosTheme } from '../../common/custom-theme';
+import ListItemTextIcon from '../../components/list-item-text-icon/list-item-text-icon';
export interface ProjectTreeProps {
projects: Array<TreeItem<ProjectResource>>;
class ProjectTree<T> extends React.Component<ProjectTreeProps & WithStyles<CssRules>> {
render(): ReactElement<any> {
const { classes, projects, toggleOpen, toggleActive, onContextMenu } = this.props;
- const { active, listItemText, row, treeContainer } = classes;
return (
- <div className={treeContainer}>
+ <div className={classes.root}>
<Tree items={projects}
onContextMenu={onContextMenu}
toggleItemOpen={toggleOpen}
toggleItemActive={toggleActive}
- render={(project: TreeItem<ProjectResource>) =>
- <span className={row}>
- <ListItemIcon className={project.active ? active : ''}>
- <i className="fas fa-folder" />
- </ListItemIcon>
- <ListItemText className={listItemText} primary={
- <Typography className={project.active ? active : ''}>{project.data.name}</Typography>
- } />
- </span>
- } />
+ render={
+ (project: TreeItem<ProjectResource>) =>
+ <ListItemTextIcon icon={ProjectIcon} name={project.data.name} isActive={project.active} hasMargin={true} />
+ }/>
</div>
);
}
}
-type CssRules = 'active' | 'listItemText' | 'row' | 'treeContainer';
+type CssRules = 'root';
-const styles: StyleRulesCallback<CssRules> = (theme: Theme) => ({
- active: {
- color: '#4285F6',
- },
- listItemText: {
- padding: '0px',
- },
- row: {
- display: 'flex',
- alignItems: 'center',
- marginLeft: '20px',
- },
- treeContainer: {
- minWidth: '240px',
- whiteSpace: 'nowrap',
- marginLeft: '13px',
+const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
+ root: {
+ marginLeft: `${theme.spacing.unit * 1.5}px`,
}
});
<Route path="/projects/:id" render={this.renderProjectPanel} />
</Switch>
</div>
- <DetailsPanel />
+ { user && <DetailsPanel /> }
</main>
<ContextMenu />
<CreateProjectDialog />