"dependencies": {
"@material-ui/core": "1.2.0",
"@material-ui/icons": "^1.1.0",
+ "lodash": "4.17.10",
"axios": "0.18.0",
"react": "16.4.0",
"react-dom": "16.4.0",
"lint": "tslint src/** -t verbose"
},
"devDependencies": {
+ "@types/enzyme": "^3.1.10",
+ "@types/enzyme-adapter-react-16": "^1.0.2",
"@types/jest": "23.0.0",
"@types/node": "10.3.0",
"@types/react": "16.3.16",
"@types/react-router-dom": "4.2.7",
"@types/react-router-redux": "5.0.15",
"@types/redux-devtools": "3.0.44",
+ "enzyme": "^3.3.0",
+ "enzyme-adapter-react-16": "^1.1.1",
"jest-localstorage-mock": "2.2.0",
"redux-devtools": "3.4.1",
"typescript": "2.9.1"
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
+ <link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>Arvados Workbench 2</title>
+ <script>FontAwesomeConfig = { autoReplaceSvg: 'nest' }</script>
+ <script defer src="https://use.fontawesome.com/releases/v5.0.13/js/all.js" integrity="sha384-xymdQtn1n3lH2wcu0qhcdaOpQwyoarkgLVxC/wZ5q7h9gHtxICrpcaSUfygqZGOe" crossorigin="anonymous"></script>
</head>
<body>
<noscript>
import * as React from 'react';
import { Theme } from "@material-ui/core";
-import { StyleRulesCallback, WithStyles } from "@material-ui/core/styles";
+import { StyleRulesCallback, WithStyles, withStyles } from "@material-ui/core/styles";
import Paper from "@material-ui/core/Paper/Paper";
-import withStyles from "@material-ui/core/es/styles/withStyles";
import Table from "@material-ui/core/Table/Table";
import TableHead from "@material-ui/core/TableHead/TableHead";
import TableRow from "@material-ui/core/TableRow/TableRow";
--- /dev/null
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import * as React from 'react';
+import * as ReactDOM from 'react-dom';
+import { shallow, mount, render } from 'enzyme';
+import * as Enzyme from 'enzyme';
+import * as Adapter from 'enzyme-adapter-react-16';
+import ListItemIcon from '@material-ui/core/ListItemIcon';
+import { Collapse } from '@material-ui/core';
+
+import ProjectTree from './project-tree';
+import { TreeItem } from '../tree/tree';
+import { Project } from '../../models/project';
+Enzyme.configure({ adapter: new Adapter() });
+
+describe("ProjectTree component", () => {
+
+ it("checks is there ListItemIcon in the ProjectTree component", () => {
+ const project: TreeItem<Project> = {
+ data: {
+ name: "sample name",
+ createdAt: "2018-06-12",
+ icon: <i className="fas fa-th" />
+ },
+ id: "3",
+ open: true,
+ active: true
+ }
+ const wrapper = mount(<ProjectTree projects={[project]} toggleProjectTreeItem={() => { }} />);
+
+ expect(wrapper.find(ListItemIcon).length).toEqual(1);
+ });
+
+ it("checks are there two ListItemIcon's in the ProjectTree component", () => {
+ const project: Array<TreeItem<Project>> = [
+ {
+ data: {
+ name: "sample name",
+ createdAt: "2018-06-12",
+ icon: <i className="fas fa-th" />
+ },
+ id: "3",
+ open: false,
+ active: true
+ },
+ {
+ data: {
+ name: "sample name",
+ createdAt: "2018-06-12",
+ icon: <i className="fas fa-th" />
+ },
+ id: "3",
+ open: false,
+ active: true
+ }
+ ]
+ const wrapper = mount(<ProjectTree projects={project} toggleProjectTreeItem={() => { }} />);
+
+ expect(wrapper.find(ListItemIcon).length).toEqual(2);
+ });
+
+ it("check ProjectTree, when open is changed", () => {
+ const project: TreeItem<Project> = {
+ data: {
+ name: "sample name",
+ createdAt: "2018-06-12",
+ icon: <i className="fas fa-th" />
+ },
+ id: "3",
+ open: true,
+ active: true,
+ items: [
+ {
+ data: {
+ name: "sample name",
+ createdAt: "2018-06-12",
+ icon: <i className="fas fa-th" />
+ },
+ id: "4",
+ open: false,
+ active: true
+ }
+ ]
+ }
+ const wrapper = mount(<ProjectTree projects={[project]} toggleProjectTreeItem={() => { }} />);
+ wrapper.setState({open: true });
+
+ expect(wrapper.find(Collapse).length).toEqual(1);
+ });
+});
--- /dev/null
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+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 } from '../tree/tree';
+import { Project } from '../../models/project';
+
+type CssRules = 'active' | 'listItemText' | 'row' | 'treeContainer';
+
+const styles: StyleRulesCallback<CssRules> = (theme: Theme) => ({
+ active: {
+ color: '#4285F6',
+ },
+ listItemText: {
+ padding: '0px',
+ },
+ row: {
+ display: 'flex',
+ alignItems: 'center',
+ marginLeft: '20px',
+ },
+ treeContainer: {
+ position: 'absolute',
+ overflowX: 'visible',
+ marginTop: '80px',
+ minWidth: '240px',
+ whiteSpace: 'nowrap',
+ }
+});
+
+export interface WorkbenchProps {
+ projects: Array<TreeItem<Project>>;
+ toggleProjectTreeItem: (id: string) => any;
+}
+
+class ProjectTree<T> extends React.Component<WorkbenchProps & WithStyles<CssRules>> {
+ render(): ReactElement<any> {
+ const {classes, projects} = this.props;
+ const {active, listItemText, row, treeContainer} = classes;
+ return (
+ <div className={treeContainer}>
+ <Tree items={projects}
+ toggleItem={this.props.toggleProjectTreeItem}
+ render={(project: TreeItem<Project>) => <span className={row}>
+ <ListItemIcon className={project.active ? active : ''}>{project.data.icon}</ListItemIcon>
+ <ListItemText className={listItemText} primary={<Typography className={project.active ? active : ''}>{project.data.name}</Typography>} />
+ </span>} />
+ </div>
+ );
+ }
+}
+
+export default withStyles(styles)(ProjectTree)
\ No newline at end of file
--- /dev/null
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
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 { ReactElement } from "react";
+import Collapse from "@material-ui/core/Collapse/Collapse";
+
+type CssRules = 'list' | 'activeArrow' | 'arrow' | 'arrowRotate';
+
+const styles: StyleRulesCallback<CssRules> = (theme: Theme) => ({
+ list: {
+ paddingBottom: '3px',
+ paddingTop: '3px',
+ },
+ activeArrow: {
+ color: '#4285F6',
+ position: 'absolute',
+ },
+ arrow: {
+ position: 'absolute',
+ },
+ arrowRotate: {
+ transform: 'rotate(-90deg)',
+ }
+});
+
+export interface TreeItem<T> {
+ data: T;
+ id: string;
+ open: boolean;
+ active: boolean;
+ items?: Array<TreeItem<T>>;
+}
interface TreeProps<T> {
- items: T[],
- render: (item: T) => ReactElement<{}>
+ items?: Array<TreeItem<T>>;
+ render: (item: TreeItem<T>) => ReactElement<{}>;
+ toggleItem: (id: string) => any;
+ level?: number;
}
-class Tree<T> extends React.Component<TreeProps<T>, {}> {
- render() {
- return <List>
- {this.props.items && this.props.items.map((it: T, idx: number) =>
- <ListItem key={`item/${idx}`} button>
- {this.props.render(it)}
+class Tree<T> extends React.Component<TreeProps<T> & WithStyles<CssRules>, {}> {
+ renderArrow (items: Array<TreeItem<T>> | undefined, arrowClass: string, isOpen: boolean){
+ return items && items.length > 0 ? <i className={`${arrowClass} ${isOpen ? "fas fa-caret-down" : `fas fa-caret-down ${this.props.classes.arrowRotate}`}`} /> : ''
+ }
+ render(): ReactElement<any> {
+ const level = this.props.level ? this.props.level : 0;
+ const {classes, render, toggleItem, items} = this.props;
+ const {list, arrow, activeArrow, arrowRotate} = classes;
+ return <List component="div" className={list}>
+ {items && items.map((it: TreeItem<T>, idx: number) =>
+ <div key={`item/${level}/${idx}`}>
+ <ListItem button onClick={() => toggleItem(it.id)} className={list} style={{paddingLeft: (level + 1) * 20}}>
+ {it.active ? this.renderArrow(it.items, activeArrow, it.open) : this.renderArrow(it.items, arrow, it.open)}
+ {render(it)}
</ListItem>
- )}
+ {it.items && it.items.length > 0 &&
+ <Collapse in={it.open} timeout="auto" unmountOnExit>
+ <StyledTree
+ items={it.items}
+ render={render}
+ toggleItem={toggleItem}
+ level={level + 1}/>
+ </Collapse>}
+ </div>)}
</List>
}
}
-export default Tree;
+const StyledTree = withStyles(styles)(Tree);
+export default StyledTree
import ApiToken from "./components/api-token/api-token";
import authActions from "./store/auth/auth-action";
import { projectService } from "./services/services";
+import { TreeItem } from "./components/tree/tree";
+import { Project } from "./models/project";
+function buildProjectTree(tree: any[], level = 0): Array<TreeItem<Project>> {
+ const projects = tree.map((t, idx) => ({
+ id: `l${level}i${idx}${t[0]}`,
+ open: false,
+ active: false,
+ data: {
+ name: t[0],
+ icon: level === 0 ? <i className="fas fa-th"/> : <i className="fas fa-folder"/>,
+ createdAt: '2018-05-05',
+ },
+ items: t.length > 1 ? buildProjectTree(t[1], level + 1) : []
+ }));
+ return projects;
+}
const history = createBrowserHistory();
+const projects = buildProjectTree(sampleProjects);
+
const store = configureStore({
projects: [
],
store.dispatch(authActions.INIT());
store.dispatch<any>(projectService.getProjectList());
+
const App = () =>
<Provider store={store}>
<ConnectedRouter history={history}>
modifiedAt: string;
uuid: string;
ownerUuid: string;
- href: string
+ href: string;
+ icon?: any;
}
--- /dev/null
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { ActionType, createStandardAction } from "typesafe-actions";
+import { Project } from "../models/project";
+
+export const actions = {
+ createProject: createStandardAction('@@project/create')<Project>(),
+ removeProject: createStandardAction('@@project/remove')<string>(),
+ toggleProjectTreeItem: createStandardAction('@@project/toggleTreeItem')<string>()
+};
+
+export type ProjectAction = ActionType<typeof actions>;
--- /dev/null
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { getType } from "typesafe-actions";
+import { Project } from "../models/project";
+import { actions, ProjectAction } from "./project-action";
+import { TreeItem } from "../components/tree/tree";
+import * as _ from 'lodash';
+
+type ProjectState = Array<TreeItem<Project>>;
+
+function findTreeItem<T>(tree: Array<TreeItem<T>>, itemId: string): TreeItem<T> | undefined {
+ let item;
+ for (const t of tree) {
+ item = t.id === itemId
+ ? t
+ : findTreeItem(t.items ? t.items : [], itemId);
+ if (item) {
+ break;
+ }
+ }
+ return item;
+}
+
+function resetTreeActivity<T>(tree: Array<TreeItem<T>>): boolean | undefined {
+ let item;
+ for (const leaf of tree) {
+ item = leaf.active === true
+ ? leaf.active = false
+ : resetTreeActivity(leaf.items ? leaf.items : []);
+ }
+ return item;
+}
+
+const projectsReducer = (state: ProjectState = [], action: ProjectAction) => {
+ switch (action.type) {
+ case getType(actions.createProject): {
+ return [...state, action.payload];
+ }
+ case getType(actions.toggleProjectTreeItem): {
+ const tree = _.cloneDeep(state);
+ const itemId = action.payload;
+ resetTreeActivity(tree);
+ const item = findTreeItem(tree, itemId);
+ if (item) {
+ item.open = !item.open;
+ item.active = true;
+ }
+ return tree;
+ }
+ default:
+ return state;
+ }
+};
+
+export default projectsReducer;
CREATE_PROJECT: ofType<Project>(),
REMOVE_PROJECT: ofType<string>(),
PROJECTS_REQUEST: {},
- PROJECTS_SUCCESS: ofType<Project[]>()
+ PROJECTS_SUCCESS: ofType<Project[]>(),
+ TOGGLE_PROJECT_TREE_ITEM: ofType<string>()
}, {
tag: 'type',
value: 'payload'
import { Project } from "../../models/project";
import actions, { ProjectAction } from "./project-action";
+import { TreeItem } from "../../components/tree/tree";
+import * as _ from "lodash";
-export type ProjectState = Project[];
+export type ProjectState = Array<TreeItem<Project>>;
+
+function findTreeItem<T>(tree: Array<TreeItem<T>>, itemId: string): TreeItem<T> | undefined {
+ let item;
+ for (const t of tree) {
+ item = t.id === itemId
+ ? t
+ : findTreeItem(t.items ? t.items : [], itemId);
+ if (item) {
+ break;
+ }
+ }
+ return item;
+}
+
+function resetTreeActivity<T>(tree: Array<TreeItem<T>>): boolean | undefined {
+ let item;
+ for (const leaf of tree) {
+ item = leaf.active === true
+ ? leaf.active = false
+ : resetTreeActivity(leaf.items ? leaf.items : []);
+ }
+ return item;
+}
const projectsReducer = (state: ProjectState = [], action: ProjectAction) => {
return actions.match(action, {
PROJECTS_SUCCESS: projects => {
return projects;
},
+ TOGGLE_PROJECT_TREE_ITEM: itemId => {
+ const tree = _.cloneDeep(state);
+ resetTreeActivity(tree);
+ const item = findTreeItem(tree, itemId);
+ if (item) {
+ item.open = !item.open;
+ item.active = true;
+ }
+ return tree;
+ },
default: () => state
});
};
import { Provider } from "react-redux";
import configureStore from "../../store/store";
import createBrowserHistory from "history/createBrowserHistory";
+import { ConnectedRouter } from "react-router-redux";
+
+const history = createBrowserHistory();
it('renders without crashing', () => {
const div = document.createElement('div');
const store = configureStore({ projects: [], router: { location: null }, auth: {} }, createBrowserHistory());
- ReactDOM.render(<Provider store={store}><Workbench/></Provider>, div);
+ ReactDOM.render(
+ <Provider store={store}>
+ <ConnectedRouter history={history}>
+ <Workbench/>
+ </ConnectedRouter>
+ </Provider>,
+ div);
ReactDOM.unmountComponentAtNode(div);
});
import Grid from "@material-ui/core/Grid/Grid";
import { RootState } from "../../store/store";
+import { actions as projectActions } from "../../store/project-action";
+import ProjectTree, { WorkbenchProps } from '../../components/project-tree/project-tree';
+
const drawerWidth = 240;
type CssRules = 'root' | 'appBar' | 'drawerPaper' | 'content' | 'toolbar';
paper: classes.drawerPaper,
}}>
<div className={classes.toolbar}/>
- <Tree items={this.props.projects} render={(p: Project) =>
- <Link to={`/project/${p.name}`}>{p.name}</Link>
- }/>
+ <ProjectTree
+ projects={this.props.projects}
+ toggleProjectTreeItem={this.props.toggleProjectTreeItem}/>
</Drawer>}
<main className={classes.content}>
<div className={classes.toolbar}/>
(state: RootState) => ({
projects: state.projects,
user: state.auth.user
- })
+ }){
+ toggleProjectTreeItem: (id: string) => projectActions.toggleProjectTreeItem(id)
+ }
)(
withStyles(styles)(Workbench)
);
"acceptance-tests",
"webpack",
"jest",
- "src/setupTests.ts"
+ "src/setupTests.ts",
+ "**/*.test.tsx"
]
}
"compilerOptions": {
"module": "commonjs"
}
-}
\ No newline at end of file
+}
"jsx-boolean-value": false,
"jsx-no-lambda": false,
"no-debugger": false,
- "no-console": false
+ "no-console": false,
+ "no-shadowed-variable": false
},
"linterOptions": {
"exclude": [
dependencies:
recompose "^0.26.0 || ^0.27.0"
+"@types/cheerio@*":
+ version "0.22.7"
+ resolved "https://registry.yarnpkg.com/@types/cheerio/-/cheerio-0.22.7.tgz#4a92eafedfb2b9f4437d3a4410006d81114c66ce"
+
+"@types/enzyme-adapter-react-16@^1.0.2":
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/@types/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.0.2.tgz#15ae37c64d6221a6f4b3a4aacc357cf773859de4"
+ dependencies:
+ "@types/enzyme" "*"
+
+"@types/enzyme@*", "@types/enzyme@^3.1.10":
+ version "3.1.10"
+ resolved "https://registry.yarnpkg.com/@types/enzyme/-/enzyme-3.1.10.tgz#28108a9864e65699751469551a803a35d2e26160"
+ dependencies:
+ "@types/cheerio" "*"
+ "@types/react" "*"
+
"@types/history@*":
version "4.6.2"
resolved "https://registry.yarnpkg.com/@types/history/-/history-4.6.2.tgz#12cfaba693ba20f114ed5765467ff25fdf67ddb0"
csstype "^2.0.0"
indefinite-observable "^1.0.1"
+"@types/lodash@4.14.109":
+ version "4.14.109"
+ resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.109.tgz#b1c4442239730bf35cabaf493c772b18c045886d"
+
"@types/node@*", "@types/node@10.3.0":
version "10.3.0"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.3.0.tgz#078516315a84d56216b5d4fed8f75d59d3b16cac"
version "0.4.2"
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2"
+cheerio@^1.0.0-rc.2:
+ version "1.0.0-rc.2"
+ resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.2.tgz#4b9f53a81b27e4d5dac31c0ffd0cfa03cc6830db"
+ dependencies:
+ css-select "~1.2.0"
+ dom-serializer "~0.1.0"
+ entities "~1.1.1"
+ htmlparser2 "^3.9.1"
+ lodash "^4.15.0"
+ parse5 "^3.0.1"
+
chokidar@^1.6.0, chokidar@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468"
css-color-names "0.0.4"
has "^1.0.1"
+colors@0.5.x:
+ version "0.5.1"
+ resolved "https://registry.yarnpkg.com/colors/-/colors-0.5.1.tgz#7d0023eaeb154e8ee9fce75dcb923d0ed1667774"
+
colors@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
postcss-value-parser "^3.3.0"
source-list-map "^2.0.0"
-css-select@^1.1.0:
+css-select@^1.1.0, css-select@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858"
dependencies:
miller-rabin "^4.0.0"
randombytes "^2.0.0"
+discontinuous-range@1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a"
+
dns-equal@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d"
version "3.3.1"
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.3.1.tgz#fc1a4e15ffdf60ddde03a480a9c0fece821dd4a6"
-dom-serializer@0:
+dom-serializer@0, dom-serializer@~0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82"
dependencies:
version "1.2.0"
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
-domelementtype@1:
+domelementtype@1, domelementtype@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2"
dependencies:
domelementtype "1"
+domhandler@^2.3.0:
+ version "2.4.2"
+ resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803"
+ dependencies:
+ domelementtype "1"
+
domutils@1.1:
version "1.1.6"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.1.6.tgz#bddc3de099b9a2efacc51c623f28f416ecc57485"
dom-serializer "0"
domelementtype "1"
+domutils@^1.5.1:
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a"
+ dependencies:
+ dom-serializer "0"
+ domelementtype "1"
+
dot-prop@^4.1.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57"
object-assign "^4.0.1"
tapable "^0.2.7"
-entities@~1.1.1:
+entities@^1.1.1, entities@~1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
+enzyme-adapter-react-16@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.1.1.tgz#a8f4278b47e082fbca14f5bfb1ee50ee650717b4"
+ dependencies:
+ enzyme-adapter-utils "^1.3.0"
+ lodash "^4.17.4"
+ object.assign "^4.0.4"
+ object.values "^1.0.4"
+ prop-types "^15.6.0"
+ react-reconciler "^0.7.0"
+ react-test-renderer "^16.0.0-0"
+
+enzyme-adapter-utils@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.3.0.tgz#d6c85756826c257a8544d362cc7a67e97ea698c7"
+ dependencies:
+ lodash "^4.17.4"
+ object.assign "^4.0.4"
+ prop-types "^15.6.0"
+
+enzyme@^3.3.0:
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-3.3.0.tgz#0971abd167f2d4bf3f5bd508229e1c4b6dc50479"
+ dependencies:
+ cheerio "^1.0.0-rc.2"
+ function.prototype.name "^1.0.3"
+ has "^1.0.1"
+ is-boolean-object "^1.0.0"
+ is-callable "^1.1.3"
+ is-number-object "^1.0.3"
+ is-string "^1.0.4"
+ is-subset "^0.1.1"
+ lodash "^4.17.4"
+ object-inspect "^1.5.0"
+ object-is "^1.0.1"
+ object.assign "^4.1.0"
+ object.entries "^1.0.4"
+ object.values "^1.0.4"
+ raf "^3.4.0"
+ rst-selector-parser "^2.2.3"
+
errno@^0.1.3, errno@~0.1.7:
version "0.1.7"
resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618"
version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
+function.prototype.name@^1.0.3:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.0.tgz#8bd763cc0af860a859cc5d49384d74b932cd2327"
+ dependencies:
+ define-properties "^1.1.2"
+ function-bind "^1.1.1"
+ is-callable "^1.1.3"
+
gauge@~2.7.3:
version "2.7.4"
resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"
version "3.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
+has-symbols@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44"
+
has-unicode@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
pretty-error "^2.0.2"
toposort "^1.0.0"
+htmlparser2@^3.9.1:
+ version "3.9.2"
+ resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.9.2.tgz#1bdf87acca0f3f9e53fa4fcceb0f4b4cbb00b338"
+ dependencies:
+ domelementtype "^1.3.0"
+ domhandler "^2.3.0"
+ domutils "^1.5.1"
+ entities "^1.1.1"
+ inherits "^2.0.1"
+ readable-stream "^2.0.2"
+
htmlparser2@~3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.3.0.tgz#cc70d05a59f6542e43f0e685c982e14c924a9efe"
dependencies:
binary-extensions "^1.0.0"
+is-boolean-object@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.0.tgz#98f8b28030684219a95f375cfbd88ce3405dff93"
+
is-buffer@^1.1.5:
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4"
+is-number-object@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.3.tgz#f265ab89a9f445034ef6aff15a8f00b00f551799"
+
is-number@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f"
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
+is-string@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.4.tgz#cc3a9b69857d621e963725a24caeec873b826e64"
+
+is-subset@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6"
+
is-svg@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-2.1.0.tgz#cf61090da0d9efbcab8722deba6f032208dbb0e9"
version "4.2.1"
resolved "https://registry.yarnpkg.com/lodash.endswith/-/lodash.endswith-4.2.1.tgz#fed59ac1738ed3e236edd7064ec456448b37bc09"
+lodash.flattendeep@^4.4.0:
+ version "4.4.0"
+ resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2"
+
lodash.isfunction@^3.0.8:
version "3.0.9"
resolved "https://registry.yarnpkg.com/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz#06de25df4db327ac931981d1bdb067e5af68d051"
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
-"lodash@>=3.5 <5", lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.2, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0:
+lodash@4.17.10, "lodash@>=3.5 <5", lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.2, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0:
version "4.17.10"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"
version "1.4.0"
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
+nearley@^2.7.10:
+ version "2.13.0"
+ resolved "https://registry.yarnpkg.com/nearley/-/nearley-2.13.0.tgz#6e7b0f4e68bfc3e74c99eaef2eda39e513143439"
+ dependencies:
+ nomnom "~1.6.2"
+ railroad-diagrams "^1.0.0"
+ randexp "0.4.6"
+ semver "^5.4.1"
+
needle@^2.2.0:
version "2.2.1"
resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.1.tgz#b5e325bd3aae8c2678902fa296f729455d1d3a7d"
semver "^5.3.0"
tar "^4"
+nomnom@~1.6.2:
+ version "1.6.2"
+ resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.6.2.tgz#84a66a260174408fc5b77a18f888eccc44fb6971"
+ dependencies:
+ colors "0.5.x"
+ underscore "~1.4.4"
+
nopt@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d"
define-property "^0.2.5"
kind-of "^3.0.3"
-object-keys@^1.0.8:
+object-inspect@^1.5.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b"
+
+object-is@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.1.tgz#0aa60ec9989a0b3ed795cf4d06f62cf1ad6539b6"
+
+object-keys@^1.0.11, object-keys@^1.0.8:
version "1.0.11"
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d"
dependencies:
isobject "^3.0.0"
+object.assign@^4.0.4, object.assign@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da"
+ dependencies:
+ define-properties "^1.1.2"
+ function-bind "^1.1.1"
+ has-symbols "^1.0.0"
+ object-keys "^1.0.11"
+
+object.entries@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.0.4.tgz#1bf9a4dd2288f5b33f3a993d257661f05d161a5f"
+ dependencies:
+ define-properties "^1.1.2"
+ es-abstract "^1.6.1"
+ function-bind "^1.1.0"
+ has "^1.0.1"
+
object.getownpropertydescriptors@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16"
dependencies:
isobject "^3.0.1"
+object.values@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.0.4.tgz#e524da09b4f66ff05df457546ec72ac99f13069a"
+ dependencies:
+ define-properties "^1.1.2"
+ es-abstract "^1.6.1"
+ function-bind "^1.1.0"
+ has "^1.0.1"
+
obuf@^1.0.0, obuf@^1.1.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e"
version "4.0.0"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608"
+parse5@^3.0.1:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c"
+ dependencies:
+ "@types/node" "*"
+
parseurl@~1.3.2:
version "1.3.2"
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3"
version "2.0.0"
resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.0.0.tgz#fa3ed6e68eb15159457c89b37bc6472833195755"
-raf@3.4.0:
+raf@3.4.0, raf@^3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.0.tgz#a28876881b4bc2ca9117d4138163ddb80f781575"
dependencies:
dependencies:
global "~4.3.0"
+railroad-diagrams@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz#eb7e6267548ddedfb899c1b90e57374559cddb7e"
+
+randexp@0.4.6:
+ version "0.4.6"
+ resolved "https://registry.yarnpkg.com/randexp/-/randexp-0.4.6.tgz#e986ad5e5e31dae13ddd6f7b3019aa7c87f60ca3"
+ dependencies:
+ discontinuous-range "1.0.0"
+ ret "~0.1.10"
+
randomatic@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.0.0.tgz#d35490030eb4f7578de292ce6dfb04a91a128923"
prop-types "^15.6.0"
warning "^3.0.0"
+react-is@^16.4.0:
+ version "16.4.0"
+ resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.4.0.tgz#cc9fdc855ac34d2e7d9d2eb7059bbc240d35ffcf"
+
react-jss@^8.1.0:
version "8.4.0"
resolved "https://registry.yarnpkg.com/react-jss/-/react-jss-8.4.0.tgz#7cb43d85dea56afafc8f0fd072ae27fcc0518950"
popper.js "^1.14.1"
prop-types "^15.6.1"
+react-reconciler@^0.7.0:
+ version "0.7.0"
+ resolved "https://registry.yarnpkg.com/react-reconciler/-/react-reconciler-0.7.0.tgz#9614894103e5f138deeeb5eabaf3ee80eb1d026d"
+ dependencies:
+ fbjs "^0.8.16"
+ loose-envify "^1.1.0"
+ object-assign "^4.1.1"
+ prop-types "^15.6.0"
+
react-redux@5.0.7:
version "5.0.7"
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.7.tgz#0dc1076d9afb4670f993ffaef44b8f8c1155a4c8"
optionalDependencies:
fsevents "^1.1.3"
+react-scrollbar-size@^2.0.2:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/react-scrollbar-size/-/react-scrollbar-size-2.1.0.tgz#105e797135cab92b1f9e16f00071db7f29f80754"
+ dependencies:
+ babel-runtime "^6.26.0"
+ prop-types "^15.6.0"
+ react-event-listener "^0.5.1"
+ stifle "^1.0.2"
+
+react-test-renderer@^16.0.0-0:
+ version "16.4.0"
+ resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.4.0.tgz#0dbe0e24263e94e1830c7afb1f403707fad313a3"
+ dependencies:
+ fbjs "^0.8.16"
+ object-assign "^4.1.1"
+ prop-types "^15.6.0"
+ react-is "^16.4.0"
+
react-transition-group@^2.2.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.3.1.tgz#31d611b33e143a5e0f2d94c348e026a0f3b474b6"
hash-base "^3.0.0"
inherits "^2.0.1"
+rst-selector-parser@^2.2.3:
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz#81b230ea2fcc6066c89e3472de794285d9b03d91"
+ dependencies:
+ lodash.flattendeep "^4.4.0"
+ nearley "^2.7.10"
+
rsvp@^3.3.3:
version "3.6.2"
resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a"
webpack-sources "^1.1.0"
worker-farm "^1.5.2"
+underscore@~1.4.4:
+ version "1.4.4"
+ resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.4.4.tgz#61a6a32010622afa07963bf325203cf12239d604"
+
union-value@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4"