Merge branch 'master' into 13764-icons-colors-unification-refactoring
authorJanicki Artur <artur.janicki@contractors.roche.com>
Wed, 11 Jul 2018 13:15:49 +0000 (15:15 +0200)
committerJanicki Artur <artur.janicki@contractors.roche.com>
Tue, 17 Jul 2018 11:03:18 +0000 (13:03 +0200)
refs #13764

Arvados-DCO-1.1-Signed-off-by: Janicki Artur <artur.janicki@contractors.roche.com>

16 files changed:
src/common/custom-theme.ts
src/components/attribute/attribute.tsx
src/components/details-panel-factory/items/abstract-item.tsx
src/components/details-panel-factory/items/collection-item.tsx
src/components/details-panel-factory/items/empty-item.tsx
src/components/details-panel-factory/items/process-item.tsx
src/components/details-panel-factory/items/project-item.tsx
src/components/dropdown-menu/dropdown-menu.test.tsx
src/components/dropdown-menu/dropdown-menu.tsx
src/components/empty-state/empty-state.tsx
src/components/icon/icon.tsx
src/components/side-panel/side-panel.tsx
src/store/side-panel/side-panel-reducer.test.ts
src/store/side-panel/side-panel-reducer.ts
src/views-components/details-panel/details-panel.tsx
src/views-components/main-app-bar/main-app-bar.tsx

index 0850f8815a7c6bb712b4c8f935f3f0da7f38c9bf..e81473aea1c2c3b19c8c21732072f557051f3d7d 100644 (file)
@@ -17,7 +17,7 @@ export interface ArvadosTheme extends Theme {
     customs: any;
 }
 
-const purple900 = purple["900"];
+const purple800 = purple["800"];
 const grey600 = grey["600"];
 const themeOptions: ArvadosThemeOptions = {
     customs: {
@@ -28,7 +28,7 @@ const themeOptions: ArvadosThemeOptions = {
     overrides: {
         MuiAppBar: {
             colorPrimary: {
-                backgroundColor: purple900
+                backgroundColor: purple800
             }
         },
         MuiTabs: {
@@ -36,13 +36,13 @@ const themeOptions: ArvadosThemeOptions = {
                 color: grey600
             },
             indicator: {
-                backgroundColor: purple900
+                backgroundColor: purple800
             }
         },
         MuiTab: {
             selected: {
                 fontWeight: 700,
-                color: purple900
+                color: purple800
             }
         }
     },
index c0874f7d5469818123ecb266c9096ee365ce97dc..4fb1d110ed1507ebb0863aa295a121b3713cb3a9 100644 (file)
@@ -57,8 +57,10 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
         textTransform: 'capitalize'
     },
     link: {
+        width: '60%',
         color: theme.palette.primary.main,
-        textDecoration: 'none'
+        textDecoration: 'none',
+        overflowWrap: 'break-word'
     }
 });
 
index a50c867be1493ed29d5695afb2f71a0927eeeaa6..d4038703096a5e3ce8a781578f4060651b000170 100644 (file)
@@ -3,8 +3,8 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import * as React from 'react';
-import { IconTypes } from '../../icon/icon';
 import { DetailsPanelResource } from '../../../views-components/details-panel/details-panel';
+import { IconType } from '../../icon/icon';
 
 export default abstract class AbstractItem<T extends DetailsPanelResource = DetailsPanelResource> {
 
@@ -14,7 +14,7 @@ export default abstract class AbstractItem<T extends DetailsPanelResource = Deta
         return this.item.name;
     }
   
-    abstract getIcon(): IconTypes;
+    abstract getIcon(className?: string): React.ReactElement<any>;
     abstract buildDetails(): React.ReactElement<any>;
     
     buildActivity(): React.ReactElement<any> {
index 1fa2891932ed4acc44d709074b463ed13c12f71b..dab8101a0d9e1b769fea3d1e6c9eeabd02332c4d 100644 (file)
@@ -3,21 +3,23 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import * as React from 'react';
-import { IconTypes } from '../../icon/icon';
+import { CollectionIcon } from '../../icon/icon';
 import Attribute from '../../attribute/attribute';
 import AbstractItem from './abstract-item';
 import { CollectionResource } from '../../../models/collection';
 import { formatDate } from '../../../common/formatters';
+import { resourceLabel } from '../../../common/labels';
+import { ResourceKind } from '../../../models/resource';
 
 export default class CollectionItem extends AbstractItem<CollectionResource> {
 
-    getIcon(): IconTypes {
-        return IconTypes.COLLECTION;
+    getIcon(className?: string) {
+        return <CollectionIcon className={className} />;
     }
 
-    buildDetails(): React.ReactElement<any> {
+    buildDetails() {
         return <div>
-           <Attribute label='Type' value='Data Collection' />
+            <Attribute label='Type' value={resourceLabel(ResourceKind.Collection)} />
             <Attribute label='Size' value='---' />
             <Attribute label='Owner' value={this.item.ownerUuid} />
             <Attribute label='Last modified' value={formatDate(this.item.modifiedAt)} />
index 16394c89538623b44e7cd2b7c41ad00b1cfdd844..0edfe84f5bfe3f3cfb0b04c8c956c1f0cdeaa38f 100644 (file)
@@ -3,19 +3,19 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import * as React from 'react';
-import { IconTypes } from '../../icon/icon';
+import { DefaultIcon, ProjectsIcon } from '../../icon/icon';
 import AbstractItem from './abstract-item';
 import EmptyState from '../../empty-state/empty-state';
 import { EmptyResource } from '../../../models/empty';
 
 export default class EmptyItem extends AbstractItem<EmptyResource> {
     
-    getIcon(): IconTypes {
-        return IconTypes.FOLDER;
+    getIcon(className?: string) {
+        return <ProjectsIcon className={className} />;
     }
 
-    buildDetails(): React.ReactElement<any> {
-        return <EmptyState icon={IconTypes.ANNOUNCEMENT}
+    buildDetails() {
+        return <EmptyState icon={DefaultIcon}
             message='Select a file or folder to view its details.' />;
     }
 }
\ No newline at end of file
index 1ea34deef3dade992bbbfa008c4d235603c29afd..215c5312d20a636523d661f92029a742db195972 100644 (file)
@@ -3,21 +3,23 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import * as React from 'react';
-import IconBase, { IconTypes } from '../../icon/icon';
+import { ProcessIcon } from '../../icon/icon';
 import Attribute from '../../attribute/attribute';
 import AbstractItem from './abstract-item';
 import { ProcessResource } from '../../../models/process';
 import { formatDate } from '../../../common/formatters';
+import { ResourceKind } from '../../../models/resource';
+import { resourceLabel } from '../../../common/labels';
 
 export default class ProcessItem extends AbstractItem<ProcessResource> {
 
-    getIcon(): IconTypes {
-        return IconTypes.PROCESS;
+    getIcon(className?: string){
+        return <ProcessIcon className={className} />;
     }
 
-    buildDetails(): React.ReactElement<any> {
+    buildDetails() {
         return <div>
-            <Attribute label='Type' value='Process' />
+            <Attribute label='Type' value={resourceLabel(ResourceKind.Process)} />
             <Attribute label='Size' value='---' />
             <Attribute label='Owner' value={this.item.ownerUuid} />
 
index 559816e12fc36e288c226bfe5bd01f55036b6e8c..ae694e5c4d355396bce29a3f38cbfbf55c7ccff2 100644 (file)
@@ -3,21 +3,23 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import * as React from 'react';
-import { IconTypes } from '../../icon/icon';
+import { ProjectIcon } from '../../icon/icon';
 import Attribute from '../../attribute/attribute';
 import AbstractItem from './abstract-item';
 import { ProjectResource } from '../../../models/project';
 import { formatDate } from '../../../common/formatters';
+import { ResourceKind } from '../../../models/resource';
+import { resourceLabel } from '../../../common/labels';
 
 export default class ProjectItem extends AbstractItem<ProjectResource> {
 
-    getIcon(): IconTypes {
-        return IconTypes.FOLDER;
+    getIcon(className?: string) {
+        return <ProjectIcon className={className} />;
     }
 
-    buildDetails(): React.ReactElement<any> {
+    buildDetails() {
         return <div>
-            <Attribute label='Type' value={this.item.groupClass} />
+            <Attribute label='Type' value={resourceLabel(ResourceKind.Project)} />
             {/* Missing attr */}
             <Attribute label='Size' value='---' />
             <Attribute label='Owner' value={this.item.ownerUuid} />
index 19924ad76c70496477329b139f47db1bcc7a5bbe..33964692493b336e9baae40ad69ad480008a17fe 100644 (file)
@@ -5,22 +5,21 @@
 import * as React from "react";
 import { shallow, configure } from "enzyme";
 import DropdownMenu from "./dropdown-menu";
-import ChevronRightIcon from '@material-ui/icons/ChevronRight';
-
 import * as Adapter from 'enzyme-adapter-react-16';
 import { MenuItem, IconButton, Menu } from "@material-ui/core";
+import { PaginationRightArrowIcon } from "../icon/icon";
 
 configure({ adapter: new Adapter() });
 
 describe("<DropdownMenu />", () => {
     it("renders menu icon", () => {
-        const dropdownMenu = shallow(<DropdownMenu id="test-menu" icon={ChevronRightIcon} />);
-        expect(dropdownMenu.find(ChevronRightIcon)).toHaveLength(1);
+        const dropdownMenu = shallow(<DropdownMenu id="test-menu" icon={<PaginationRightArrowIcon />} />);
+        expect(dropdownMenu.find(PaginationRightArrowIcon)).toHaveLength(1);
     });
 
     it("render menu items", () => {
         const dropdownMenu = shallow(
-            <DropdownMenu id="test-menu" icon={ChevronRightIcon}>
+            <DropdownMenu id="test-menu" icon={<PaginationRightArrowIcon />}>
                 <MenuItem>Item 1</MenuItem>
                 <MenuItem>Item 2</MenuItem>
             </DropdownMenu>
@@ -29,13 +28,13 @@ describe("<DropdownMenu />", () => {
     });
 
     it("opens on menu icon click", () => {
-        const dropdownMenu = shallow(<DropdownMenu id="test-menu" icon={ChevronRightIcon} />);
+        const dropdownMenu = shallow(<DropdownMenu id="test-menu" icon={<PaginationRightArrowIcon />} />);
         dropdownMenu.find(IconButton).simulate("click", {currentTarget: {}});
         expect(dropdownMenu.state().anchorEl).toBeDefined();
     });
     
     it("closes on menu click", () => {
-        const dropdownMenu = shallow(<DropdownMenu id="test-menu" icon={ChevronRightIcon} />);
+        const dropdownMenu = shallow(<DropdownMenu id="test-menu" icon={<PaginationRightArrowIcon />} />);
         dropdownMenu.find(Menu).simulate("click", {currentTarget: {}});
         expect(dropdownMenu.state().anchorEl).toBeUndefined();
     });
index 4f2b83af6591e6ab9d72d1e0d83914ff55bd4414..98c29c6416af047554c103bfba0ef8eb3f61a7d1 100644 (file)
@@ -3,13 +3,13 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import * as React from 'react';
-import { Menu, IconButton } from '@material-ui/core';
+import Menu from '@material-ui/core/Menu';
+import IconButton from '@material-ui/core/IconButton';
 import { PopoverOrigin } from '@material-ui/core/Popover';
 
-
 interface DropdownMenuProps {
     id: string;
-    icon: React.ComponentType;
+    icon: React.ReactElement<any>;
 }
 
 class DropdownMenu extends React.Component<DropdownMenuProps> {
@@ -24,7 +24,7 @@ class DropdownMenu extends React.Component<DropdownMenuProps> {
     };
 
     render() {
-        const { icon: Icon, id, children } = this.props;
+        const { icon, id, children } = this.props;
         const { anchorEl } = this.state;
         return (
             <div>
@@ -32,10 +32,8 @@ class DropdownMenu extends React.Component<DropdownMenuProps> {
                     aria-owns={anchorEl ? id : undefined}
                     aria-haspopup="true"
                     color="inherit"
-                    onClick={this.handleOpen}
-
-                >
-                    <Icon />
+                    onClick={this.handleOpen}>
+                    {icon}
                 </IconButton>
                 <Menu
                     id={id}
@@ -44,8 +42,7 @@ class DropdownMenu extends React.Component<DropdownMenuProps> {
                     onClose={this.handleClose}
                     onClick={this.handleClose}
                     anchorOrigin={this.transformOrigin}
-                    transformOrigin={this.transformOrigin}
-                >
+                    transformOrigin={this.transformOrigin}>
                     {children}
                 </Menu>
             </div>
index 9ab306359e28b2eeba3feec5a3ee4754f883c3ca..8a36213e4f4e2fc17cbd4c0fdd34718633bfec13 100644 (file)
@@ -5,12 +5,12 @@
 import * as React from 'react';
 import Typography from '@material-ui/core/Typography';
 import { WithStyles, withStyles, StyleRulesCallback } from '@material-ui/core/styles';
-import { ArvadosTheme } from '../../common/custom-theme';
-import IconBase, { IconTypes } from '../icon/icon';
+import { ArvadosTheme } from 'src/common/custom-theme';
+import { IconType } from '../icon/icon';
 
 export interface EmptyStateDataProps {
     message: string;
-    icon: IconTypes;
+    icon: IconType;
     details?: string;
 }
 
@@ -19,10 +19,10 @@ type EmptyStateProps = EmptyStateDataProps & WithStyles<CssRules>;
 class EmptyState extends React.Component<EmptyStateProps, {}> {
 
     render() {
-        const { classes, message, details, icon, children } = this.props;
+        const { classes, message, details, icon: Icon, children } = this.props;
         return (
             <Typography className={classes.container} component="div">
-                <IconBase icon={icon} className={classes.icon} />
+                <Icon className={classes.icon} />
                 <Typography variant="body1" gutterBottom>{message}</Typography>
                 { details && <Typography gutterBottom>{details}</Typography> }
                 { children && <Typography gutterBottom>{children}</Typography> }
index c420a19c8d46397caa1934908528e5127e149b32..e80fee8e97db18107cc186cf2819c6dfc9f0ed9c 100644 (file)
@@ -3,48 +3,71 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import * as React from 'react';
-import * as classnames from "classnames";
-import CloseAnnouncement from '@material-ui/icons/Announcement';
-import CloseIcon from '@material-ui/icons/Close';
-import FolderIcon from '@material-ui/icons/Folder';
+import AccessTime from '@material-ui/icons/AccessTime';
+import ArrowDropDown from '@material-ui/icons/ArrowDropDown';
+import BubbleChart from '@material-ui/icons/BubbleChart';
+import Cached from '@material-ui/icons/Cached';
+import Code from '@material-ui/icons/Code';
+import ChevronLeft from '@material-ui/icons/ChevronLeft';
+import ChevronRight from '@material-ui/icons/ChevronRight';
+import Close from '@material-ui/icons/Close';
+import ContentCopy from '@material-ui/icons/ContentCopy';
+import CreateNewFolder from '@material-ui/icons/CreateNewFolder';
+import Delete from '@material-ui/icons/Delete';
+import Edit from '@material-ui/icons/Edit';
+import Folder from '@material-ui/icons/Folder';
+import GetApp from '@material-ui/icons/GetApp';
+import Help from '@material-ui/icons/Help';
+import Inbox from '@material-ui/icons/Inbox';
+import Info from '@material-ui/icons/Info';
+import Input from '@material-ui/icons/Input';
+import Menu from '@material-ui/icons/Menu';
+import MoreVert from '@material-ui/icons/MoreVert';
+import Notifications from '@material-ui/icons/Notifications';
+import People from '@material-ui/icons/People';
+import Person from '@material-ui/icons/Person';
+import PersonAdd from '@material-ui/icons/PersonAdd';
+import PlayArrow from '@material-ui/icons/PlayArrow';
+import RateReview from '@material-ui/icons/RateReview';
+import Search from '@material-ui/icons/Search';
+import Star from '@material-ui/icons/Star';
+import StarBorder from '@material-ui/icons/StarBorder';
 
-export enum IconTypes {
-    ANNOUNCEMENT = 'announcement',
-    FOLDER = 'folder',
-    CLOSE = 'close',
-    PROJECT  = 'project',
-    COLLECTION = 'collection',
-    PROCESS = 'process'
-}
+export type IconType = React.SFC<{ className?: string }>;
 
-interface IconBaseDataProps {
-    icon: IconTypes;
-    className?: string;
-}
-
-type IconBaseProps = IconBaseDataProps;
-
-interface IconBaseState {
-    icon: IconTypes;
-}
-
-const getSpecificIcon = (props: any) => ({
-    announcement: <CloseAnnouncement className={props.className} />,
-    folder: <FolderIcon className={props.className} />,
-    close: <CloseIcon className={props.className} />,
-    project: <i className={classnames([props.className, 'fas fa-folder fa-lg'])} />,
-    collection: <i className={classnames([props.className, 'fas fa-archive fa-lg'])} />,
-    process: <i className={classnames([props.className, 'fas fa-cogs fa-lg'])} />
-});
-
-class IconBase extends React.Component<IconBaseProps, IconBaseState> {
-    state = {
-        icon: IconTypes.FOLDER,
-    };
-
-    render() {
-        return getSpecificIcon(this.props)[this.props.icon];
-    }
-}
-
-export default IconBase;
\ No newline at end of file
+export const AddFavoriteIcon: IconType = (props) => <StarBorder {...props} />;
+export const AdvancedIcon: IconType = (props) => <Folder {...props} />;
+export const CustomizeTableIcon: IconType = (props) => <Menu {...props} />;
+export const CopyIcon: IconType = (props) => <ContentCopy {...props} />;
+export const CollectionIcon: IconType = (props) => <Folder {...props} />;
+export const CloseIcon: IconType = (props) => <Close {...props} />;
+export const DefaultIcon: IconType = (props) => <RateReview {...props} />;
+export const DetailsIcon: IconType = (props) => <Info {...props} />;
+export const DownloadIcon: IconType = (props) => <GetApp {...props} />;
+export const FavoriteIcon: IconType = (props) => <Star {...props} />;
+export const HelpIcon: IconType = (props) => <Help {...props} />;
+export const LogIcon: IconType = (props) => <Folder {...props} />;
+export const MoreOptionsIcon: IconType = (props) => <MoreVert {...props} />;
+export const MoveToIcon: IconType = (props) => <Input {...props} />;
+export const NewProjectIcon: IconType = (props) => <CreateNewFolder {...props} />;
+export const NotificationIcon: IconType = (props) => <Notifications {...props} />;
+export const PaginationDownIcon: IconType = (props) => <ArrowDropDown {...props} />;
+export const PaginationLeftArrowIcon: IconType = (props) => <ChevronLeft {...props} />;
+export const PaginationRightArrowIcon: IconType = (props) => <ChevronRight {...props} />;
+export const ProcessIcon: IconType = (props) => <BubbleChart {...props} />;
+export const ProjectIcon: IconType = (props) => <Folder {...props} />;
+export const ProjectsIcon: IconType = (props) => <Inbox {...props} />;
+export const ProvenanceGraphIcon: IconType = (props) => <Folder {...props} />;
+export const RecentIcon: IconType = (props) => <AccessTime {...props} />;
+export const RemoveIcon: IconType = (props) => <Delete {...props} />;
+export const RemoveFavoriteIcon: IconType = (props) => <Star {...props} />;
+export const RenameIcon: IconType = (props) => <Edit {...props} />;
+export const ReRunProcessIcon: IconType = (props) => <Cached {...props} />;
+export const SearchIcon: IconType = (props) => <Search {...props} />;
+export const ShareIcon: IconType = (props) => <PersonAdd {...props} />;
+export const ShareMeIcon: IconType = (props) => <People {...props} />;
+export const SidePanelRightArrowIcon: IconType = (props) => <PlayArrow {...props} />;
+export const TrashIcon: IconType = (props) => <Delete {...props} />;
+export const UserPanelIcon: IconType = (props) => <Person {...props} />;
+export const UsedByIcon: IconType = (props) => <Folder {...props} />;
+export const WorkflowIcon: IconType = (props) => <Code {...props} />;
\ No newline at end of file
index a7783fb256c611f99fac80803b781c9884b74f8c..eedc499f55143bc640e5d799aef30d83ef792989 100644 (file)
@@ -4,19 +4,16 @@
 
 import * as React from 'react';
 import { ReactElement } from 'react';
-import { StyleRulesCallback, Theme, WithStyles, withStyles } from '@material-ui/core/styles';
-import List from "@material-ui/core/List/List";
-import ListItem from "@material-ui/core/ListItem/ListItem";
-import ListItemText from "@material-ui/core/ListItemText/ListItemText";
-import ListItemIcon from '@material-ui/core/ListItemIcon';
-import Collapse from "@material-ui/core/Collapse/Collapse";
-
-import { Typography } from '@material-ui/core';
+import { StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core/styles';
+import { ArvadosTheme } from '../../common/custom-theme';
+import { List, ListItem, ListItemText, ListItemIcon, Collapse, Typography } from "@material-ui/core";
+import { SidePanelRightArrowIcon, IconType } from '../icon/icon';
+import * as classnames from "classnames";
 
 export interface SidePanelItem {
     id: string;
     name: string;
-    icon: string;
+    icon: IconType;
     active?: boolean;
     open?: boolean;
     margin?: boolean;
@@ -33,7 +30,7 @@ interface SidePanelProps {
 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, activeArrow, inactiveArrow, arrowTransition, arrowRotate } = classes;
+        const { listItemText, leftSidePanelContainer, row, list, icon, projectIconMargin, active, iconArrowContainer } = classes;
         return (
             <div className={leftSidePanelContainer}>
                 <List>
@@ -41,18 +38,23 @@ class SidePanel extends React.Component<SidePanelProps & WithStyles<CssRules>> {
                         <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={`${it.active ? activeArrow : inactiveArrow} 
-                                        ${it.open ? `fas fa-caret-down ${arrowTransition}` : `fas fa-caret-down ${arrowRotate}`}`} /> : null}
+                                    {it.openAble ? (
+                                        <i onClick={() => toggleOpen(it.id)} className={iconArrowContainer}>
+                                            <SidePanelRightArrowIcon className={this.getIconClassNames(it.open, it.active)} />
+                                        </i>
+                                    ) : null}
                                     <ListItemIcon className={it.active ? active : ''}>
-                                        <i className={`${it.icon} ${icon} ${it.margin ? projectIconMargin : ''}`} />
+                                        {<it.icon className={`${icon} ${it.margin ? projectIconMargin : ''}`} />}
                                     </ListItemIcon>
-                                    <ListItemText className={listItemText} primary={<Typography className={it.active ? active : ''}>{it.name}</Typography>} />
+                                    <ListItemText className={listItemText} 
+                                        primary={renderListItemText(it.name, active, it.active)} />
                                 </span>
                             </ListItem>
                             {it.openAble ? (
                                 <Collapse in={it.open} timeout="auto" unmountOnExit>
                                     {children}
-                                </Collapse>) : null}
+                                </Collapse>
+                            ) : null}
                         </span>
                     ))}
                 </List>
@@ -60,18 +62,30 @@ class SidePanel extends React.Component<SidePanelProps & WithStyles<CssRules>> {
         );
     }
 
+    getIconClassNames = (itemOpen ?: boolean, itemActive ?: boolean) => {
+        const { classes } = this.props;
+        return classnames(classes.iconArrow, {
+            [classes.iconOpen]: itemOpen,
+            [classes.iconClose]: !itemOpen,
+            [classes.active]: itemActive
+        });
+    }
+
     handleRowContextMenu = (item: SidePanelItem) =>
         (event: React.MouseEvent<HTMLElement>) =>
             item.openAble ? this.props.onContextMenu(event, item) : null
 
 }
 
-type CssRules = 'active' | 'listItemText' | 'row' | 'leftSidePanelContainer' | 'list' | 'icon' | 'projectIconMargin' |
-    'activeArrow' | 'inactiveArrow' | 'arrowRotate' | 'arrowTransition';
+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';
 
-const styles: StyleRulesCallback<CssRules> = (theme: Theme) => ({
+const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
     active: {
-        color: '#4285F6',
+        color: theme.palette.primary.main,
     },
     listItemText: {
         padding: '0px',
@@ -80,19 +94,20 @@ const styles: StyleRulesCallback<CssRules> = (theme: Theme) => ({
         display: 'flex',
         alignItems: 'center',
     },
-    activeArrow: {
-        color: '#4285F6',
-        position: 'absolute',
+    iconArrowContainer: {
+        color: theme.palette.grey["700"],
+        height: '14px',
+        position: 'absolute'
     },
-    inactiveArrow: {
-        position: 'absolute',
+    iconArrow: {
+        fontSize: '14px'
     },
-    arrowTransition: {
+    iconClose: {
         transition: 'all 0.1s ease',
     },
-    arrowRotate: {
+    iconOpen: {
         transition: 'all 0.1s ease',
-        transform: 'rotate(-90deg)',
+        transform: 'rotate(90deg)',
     },
     leftSidePanelContainer: {
         overflowY: 'auto',
@@ -103,13 +118,11 @@ const styles: StyleRulesCallback<CssRules> = (theme: Theme) => ({
         flexGrow: 1,
     },
     list: {
-        paddingBottom: '5px',
-        paddingTop: '5px',
-        paddingLeft: '14px',
+        padding: '5px 0px 5px 14px',
         minWidth: '240px',
     },
     icon: {
-        minWidth: '20px',
+        fontSize: '20px'
     },
     projectIconMargin: {
         marginLeft: '17px',
index 942c16ebdcc7d1588f156c25345f6eda9a5617db..5edd9021648dca18dbd0996e41efe8012d06b1f9 100644 (file)
@@ -4,6 +4,7 @@
 
 import sidePanelReducer from "./side-panel-reducer";
 import actions from "./side-panel-action";
+import { ProjectsIcon } from "../../components/icon/icon";
 
 describe('side-panel-reducer', () => {
 
@@ -12,7 +13,7 @@ describe('side-panel-reducer', () => {
             {
                 id: "1",
                 name: "Projects",
-                icon: "fas fa-th fa-fw",
+                icon: ProjectsIcon,
                 open: false,
                 active: false,
             }
@@ -21,7 +22,7 @@ describe('side-panel-reducer', () => {
             {
                 id: "1",
                 name: "Projects",
-                icon: "fas fa-th fa-fw",
+                icon: ProjectsIcon,
                 open: false,
                 active: true,
             }
@@ -36,7 +37,7 @@ describe('side-panel-reducer', () => {
             {
                 id: "1",
                 name: "Projects",
-                icon: "fas fa-th fa-fw",
+                icon: ProjectsIcon,
                 open: false,
                 active: false,
             }
@@ -45,7 +46,7 @@ describe('side-panel-reducer', () => {
             {
                 id: "1",
                 name: "Projects",
-                icon: "fas fa-th fa-fw",
+                icon: ProjectsIcon,
                 open: true,
                 active: false,
             }
@@ -60,7 +61,7 @@ describe('side-panel-reducer', () => {
             {
                 id: "1",
                 name: "Projects",
-                icon: "fas fa-th fa-fw",
+                icon: ProjectsIcon,
                 open: false,
                 active: true,
             }
@@ -69,7 +70,7 @@ describe('side-panel-reducer', () => {
             {
                 id: "1",
                 name: "Projects",
-                icon: "fas fa-th fa-fw",
+                icon: ProjectsIcon,
                 open: false,
                 active: false,
             }
index ca26eeb6435b619af28faf2e3a98d68190a83461..a0da7db9bb3cc63e89592c39d2827221aa3702de 100644 (file)
@@ -3,9 +3,9 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import * as _ from "lodash";
-
 import actions, { SidePanelAction } from './side-panel-action';
 import { SidePanelItem } from '../../components/side-panel/side-panel';
+import { ProjectsIcon, ShareMeIcon, WorkflowIcon, RecentIcon, FavoriteIcon, TrashIcon } from "../../components/icon/icon";
 
 export type SidePanelState = SidePanelItem[];
 
@@ -48,7 +48,7 @@ export const sidePanelData = [
     {
         id: SidePanelIdentifiers.Projects,
         name: "Projects",
-        icon: "fas fa-th fa-fw",
+        icon: ProjectsIcon,
         open: false,
         active: false,
         margin: true,
@@ -57,31 +57,31 @@ export const sidePanelData = [
     {
         id: SidePanelIdentifiers.SharedWithMe,
         name: "Shared with me",
-        icon: "fas fa-users fa-fw",
+        icon: ShareMeIcon,
         active: false,
     },
     {
         id: SidePanelIdentifiers.Workflows,
         name: "Workflows",
-        icon: "fas fa-cogs fa-fw",
+        icon: WorkflowIcon,
         active: false,
     },
     {
         id: SidePanelIdentifiers.RecentOpen,
         name: "Recent open",
-        icon: "icon-time fa-fw",
+        icon: RecentIcon,
         active: false,
     },
     {
         id: SidePanelIdentifiers.Favourites,
         name: "Favorites",
-        icon: "fas fa-star fa-fw",
+        icon: FavoriteIcon,
         active: false,
     },
     {
         id: SidePanelIdentifiers.Trash,
         name: "Trash",
-        icon: "fas fa-trash-alt fa-fw",
+        icon: TrashIcon,
         active: false,
     }
 ];
index 341957849ede81e94c98627f9eb4180553e446b4..f2212fc528e430c55e77c3792b6db89cf06ddf59 100644 (file)
@@ -3,21 +3,16 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import * as React from 'react';
-import Drawer from '@material-ui/core/Drawer';
-import IconButton from "@material-ui/core/IconButton";
+import { Drawer, IconButton, Tabs, Tab, Typography, Grid } from '@material-ui/core';
 import { StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core/styles';
 import { ArvadosTheme } from '../../common/custom-theme';
-import Tabs from '@material-ui/core/Tabs';
-import Tab from '@material-ui/core/Tab';
-import Typography from '@material-ui/core/Typography';
-import Grid from '@material-ui/core/Grid';
 import * as classnames from "classnames";
 import { connect, Dispatch } from 'react-redux';
 import { RootState } from '../../store/store';
 import actions from "../../store/details-panel/details-panel-action";
 import { ProjectResource } from '../../models/project';
 import { CollectionResource } from '../../models/collection';
-import IconBase, { IconTypes } from '../../components/icon/icon';
+import { CloseIcon } from '../../components/icon/icon';
 import { ProcessResource } from '../../models/process';
 import DetailsPanelFactory from '../../components/details-panel-factory/details-panel-factory';
 import AbstractItem from '../../components/details-panel-factory/items/abstract-item';
@@ -54,7 +49,7 @@ class DetailsPanel extends React.Component<DetailsPanelProps, {}> {
                     <Typography component="div" className={classes.headerContainer}>
                         <Grid container alignItems='center' justify='space-around'>
                             <Grid item xs={2}>
-                                <IconBase className={classes.headerIcon} icon={item.getIcon()} />
+                                {item.getIcon(classes.headerIcon)}
                             </Grid>
                             <Grid item xs={8}>
                                 <Typography variant="title">
@@ -63,7 +58,7 @@ class DetailsPanel extends React.Component<DetailsPanelProps, {}> {
                             </Grid>
                             <Grid item>
                                 <IconButton color="inherit" onClick={onCloseDrawer}>
-                                    <IconBase icon={IconTypes.CLOSE} />
+                                    {<CloseIcon />}
                                 </IconButton>
                             </Grid>
                         </Grid>
index d2082395125e740e1cff707293d4e7f8d081740b..30eee0d2d5530b48319f5abb811571619c103ae3 100644 (file)
@@ -4,14 +4,11 @@
 
 import * as React from "react";
 import { AppBar, Toolbar, Typography, Grid, IconButton, Badge, 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 InfoIcon from '@material-ui/icons/Info';
+import { User, getUserFullname } from "../../models/user";
 import SearchBar from "../../components/search-bar/search-bar";
 import Breadcrumbs, { Breadcrumb } from "../../components/breadcrumbs/breadcrumbs";
 import DropdownMenu from "../../components/dropdown-menu/dropdown-menu";
-import { User, getUserFullname } from "../../models/user";
+import { DetailsIcon, NotificationIcon, UserPanelIcon, HelpIcon } from "../../components/icon/icon";
 
 export interface MainAppBarMenuItem {
     label: string;
@@ -77,7 +74,7 @@ export const MainAppBar: React.SFC<MainAppBarProps> = (props) => {
                     onContextMenu={props.onContextMenu} />
             }
             <IconButton color="inherit" onClick={props.onDetailsPanelToggle}>
-                <InfoIcon />
+                { <DetailsIcon /> }
             </IconButton>
         </Toolbar>
     </AppBar>;
@@ -89,16 +86,16 @@ const renderMenuForUser = ({ user, menuItems, onMenuItemClick }: MainAppBarProps
         <>
             <IconButton color="inherit">
                 <Badge badgeContent={3} color="primary">
-                    <NotificationsIcon />
+                    {<NotificationIcon />}
                 </Badge>
             </IconButton>
-            <DropdownMenu icon={PersonIcon} id="account-menu">
+            <DropdownMenu icon={<UserPanelIcon />} id="account-menu">
                 <MenuItem>
                     {getUserFullname(user)}
                 </MenuItem>
                 {renderMenuItems(menuItems.accountMenu, onMenuItemClick)}
             </DropdownMenu>
-            <DropdownMenu icon={HelpIcon} id="help-menu">
+            <DropdownMenu icon={<HelpIcon />} id="help-menu">
                 {renderMenuItems(menuItems.helpMenu, onMenuItemClick)}
             </DropdownMenu>
         </>