[ARVADOS-WORKBENCH2] updated: 1.1.4-359-g10ce16c
Git user
git at public.curoverse.com
Mon Jul 23 08:14:26 EDT 2018
Summary of changes:
.env | 1 +
.licenseignore | 2 +
.npmrc | 1 +
.yarnrc | 1 +
Makefile | 3 +-
README.md | 14 +-
etc/arvados/workbench2/workbench2.example.json | 3 +
package.json | 24 +-
src/common/api/common-resource-service.test.ts | 2 +-
src/common/api/common-resource-service.ts | 7 +-
src/common/api/filter-builder.test.ts | 2 +-
src/common/api/filter-builder.ts | 4 +-
src/common/api/order-builder.test.ts | 2 +-
src/common/api/order-builder.ts | 4 +-
src/common/api/server-api.ts | 4 +
src/common/api/url-builder.ts | 36 +-
src/common/config.ts | 23 ++
src/common/custom-theme.ts | 38 +-
src/common/formatters.ts | 4 +-
src/common/url.ts | 6 +
src/components/attribute/attribute.tsx | 65 ----
src/components/breadcrumbs/breadcrumbs.test.tsx | 4 +-
src/components/breadcrumbs/breadcrumbs.tsx | 91 +++--
.../column-selector/column-selector.test.tsx | 2 +-
src/components/column-selector/column-selector.tsx | 37 +-
src/components/context-menu/context-menu.test.tsx | 23 +-
src/components/context-menu/context-menu.tsx | 30 +-
.../data-explorer/data-explorer.test.tsx | 10 +-
src/components/data-explorer/data-explorer.tsx | 141 ++++----
.../data-table-filters/data-table-filters.test.tsx | 12 +-
.../data-table-filters/data-table-filters.tsx | 255 +++++++------
src/components/data-table/data-table.test.tsx | 8 +-
src/components/data-table/data-table.tsx | 156 ++++----
.../details-attribute/details-attribute.tsx | 55 +++
.../details-panel-factory.tsx | 27 --
.../details-panel-factory/items/abstract-item.tsx | 23 --
.../items/collection-item.tsx | 33 --
.../details-panel-factory/items/empty-item.tsx | 21 --
.../details-panel-factory/items/process-item.tsx | 43 ---
.../details-panel-factory/items/project-item.tsx | 31 --
.../dropdown-menu/dropdown-menu.test.tsx | 19 +-
src/components/dropdown-menu/dropdown-menu.tsx | 25 +-
src/components/empty-state/empty-state.tsx | 46 ---
src/components/icon/icon.tsx | 109 +++---
.../list-item-text-icon/list-item-text-icon.tsx | 62 ++++
src/components/popover/helpers.ts | 10 +-
src/components/popover/popover.test.tsx | 6 +-
src/components/popover/popover.tsx | 7 +-
src/components/search-bar/search-bar.test.tsx | 14 +-
src/components/search-bar/search-bar.tsx | 148 ++++----
src/components/search-input/search-input.test.tsx | 12 +-
src/components/search-input/search-input.tsx | 158 ++++----
src/components/side-panel/side-panel.tsx | 187 +++++-----
src/components/tree/tree.test.tsx | 2 +-
src/components/tree/tree.tsx | 133 +++----
src/index.tsx | 83 ++---
src/models/container-request.ts | 3 +-
src/models/details.ts | 10 +
src/models/empty.ts | 4 +-
src/services/auth-service/auth-service.ts | 9 +-
src/services/groups-service/groups-service.test.ts | 2 +-
src/services/groups-service/groups-service.ts | 10 +-
.../project-service/project-service.test.ts | 7 +-
src/services/project-service/project-service.ts | 8 +-
src/services/services.ts | 8 +-
src/store/auth/auth-action.ts | 10 +-
src/store/auth/auth-reducer.test.ts | 16 +-
src/store/auth/auth-reducer.ts | 8 +-
src/store/context-menu/context-menu-actions.ts | 19 +-
src/store/context-menu/context-menu-reducer.ts | 49 +--
src/store/data-explorer/data-explorer-action.ts | 6 +-
.../data-explorer/data-explorer-reducer.test.tsx | 29 +-
src/store/data-explorer/data-explorer-reducer.ts | 8 +-
src/store/details-panel/details-panel-action.ts | 12 +-
src/store/details-panel/details-panel-reducer.ts | 8 +-
src/store/navigation/navigation-action.ts | 4 +-
.../project-panel/project-panel-middleware.ts | 39 +-
src/store/project/project-action.ts | 15 +-
src/store/project/project-reducer.test.ts | 12 +-
src/store/project/project-reducer.ts | 10 +-
src/store/side-panel/side-panel-action.ts | 5 +-
src/store/side-panel/side-panel-reducer.test.ts | 25 +-
src/store/side-panel/side-panel-reducer.ts | 22 +-
src/store/store.ts | 17 +-
src/utils/dialog-validator.tsx | 74 ++++
src/views-components/api-token/api-token.tsx | 40 +--
.../context-menu/action-sets/project-action-set.ts | 19 +
.../action-sets/root-project-action-set.ts | 15 +
.../context-menu/context-menu-action-set.ts | 13 +
src/views-components/context-menu/context-menu.tsx | 60 ++++
.../create-project-dialog.tsx | 10 +-
.../data-explorer/data-explorer.tsx | 20 +-
.../details-panel/collection-details.tsx | 35 ++
.../details-panel/details-data.tsx | 21 ++
.../details-panel/details-panel.tsx | 192 +++++-----
.../details-panel/empty-details.tsx | 53 +++
.../details-panel/process-details.tsx | 45 +++
.../details-panel/project-details.tsx | 33 ++
.../dialog-create/dialog-project-create.tsx | 2 +-
.../main-app-bar/main-app-bar.test.tsx | 12 +-
src/views-components/main-app-bar/main-app-bar.tsx | 27 +-
src/views-components/project-list/project-list.tsx | 61 ----
.../project-tree/project-tree.test.tsx | 14 +-
src/views-components/project-tree/project-tree.tsx | 85 ++---
src/views/project-panel/project-panel.tsx | 278 +++++++-------
src/views/workbench/workbench.test.tsx | 4 +-
src/views/workbench/workbench.tsx | 365 ++++++++-----------
tslint.json | 3 +-
yarn.lock | 399 ++++++++++-----------
109 files changed, 2337 insertions(+), 2187 deletions(-)
create mode 100644 .npmrc
create mode 100644 .yarnrc
create mode 100644 etc/arvados/workbench2/workbench2.example.json
create mode 100644 src/common/config.ts
create mode 100644 src/common/url.ts
delete mode 100644 src/components/attribute/attribute.tsx
create mode 100644 src/components/details-attribute/details-attribute.tsx
delete mode 100644 src/components/details-panel-factory/details-panel-factory.tsx
delete mode 100644 src/components/details-panel-factory/items/abstract-item.tsx
delete mode 100644 src/components/details-panel-factory/items/collection-item.tsx
delete mode 100644 src/components/details-panel-factory/items/empty-item.tsx
delete mode 100644 src/components/details-panel-factory/items/process-item.tsx
delete mode 100644 src/components/details-panel-factory/items/project-item.tsx
delete mode 100644 src/components/empty-state/empty-state.tsx
create mode 100644 src/components/list-item-text-icon/list-item-text-icon.tsx
create mode 100644 src/models/details.ts
create mode 100644 src/utils/dialog-validator.tsx
create mode 100644 src/views-components/context-menu/action-sets/project-action-set.ts
create mode 100644 src/views-components/context-menu/action-sets/root-project-action-set.ts
create mode 100644 src/views-components/context-menu/context-menu-action-set.ts
create mode 100644 src/views-components/context-menu/context-menu.tsx
create mode 100644 src/views-components/details-panel/collection-details.tsx
create mode 100644 src/views-components/details-panel/details-data.tsx
create mode 100644 src/views-components/details-panel/empty-details.tsx
create mode 100644 src/views-components/details-panel/process-details.tsx
create mode 100644 src/views-components/details-panel/project-details.tsx
delete mode 100644 src/views-components/project-list/project-list.tsx
via 10ce16c28de952f6533ca3cc9df909269e3d2a53 (commit)
via 7df4149100f41cc8d4a5438630ba95a1d72409a1 (commit)
via b9da9116feeb510f5dae9da6e4f912ecf4aee298 (commit)
via de8c54604ff856456418f51c150b693845c29f49 (commit)
via 47e0dc87fa82bac593c53518e556ba7c55410288 (commit)
via 37ebbbd4f05f811582546823738619f1fbb97686 (commit)
via b6a5b173cd4e9f325f371d26204dfe156d911c20 (commit)
via ae691a976c8e505afba7cec6f8f316d1c5b175a7 (commit)
via 4229645b39e3edfa288be826fb2cdcfa5fd90d38 (commit)
via 180c2c37b635cbb7a33257d2ee9b4395553ce5e7 (commit)
via 355aa79f1a2abb5e8142062d83f897d780cc8a8e (commit)
via 6a8c680d938820bc497d0a5b0e6aa99c108ede14 (commit)
via b3ed96a047c8db5febae40b6f186a656589167d8 (commit)
via 9230902521944497f96976064c5c7ae824786084 (commit)
via fef17c665b0d6acb4be97c9dcf4a6cb7a92ee6ef (commit)
via 8dda39e1ac1e43d08881b8ac19db92c18d1cb4fe (commit)
via 1a1007b664c6158c905a2fbfa998e7a5737ab7e1 (commit)
via 1411549ab8347b21dc8efc1b208b98b85c186e12 (commit)
via 6577b5404eef1061fc3f2fb1cfdc1775bd752132 (commit)
via 5f5526dc9a8f06f82a4fe5c8f47a26ef6cab707e (commit)
via bc427c3f9f88acefbe12d7b9043d845acf5635a7 (commit)
via 98937529d1e3e8a349fe11ed5cd75c56119990a7 (commit)
via 5219b97601d3aee849081f81536f8edd91d9ad53 (commit)
via 1d9efaa46b5e30f4b69fa8ebca99ea234a5d40c7 (commit)
via 0a80eaa377a404c55660ecae52b495a9ed2e9167 (commit)
via 082c172edc327afa52f9ec716f7702e3f29e58d6 (commit)
via 9157a285ebb05c7ff0ae7a457ec5ffece17c3773 (commit)
via ea8725420ed2b4c3710925ac016ce10f288ab0aa (commit)
via 46a41363f69391d4131180791f912329464d8a65 (commit)
via ea80145c5d632a647cf583cf0ebbf2a866d85549 (commit)
via 9b390921232a4a3d1279d59da96f00dabeba1150 (commit)
via ff25c5d64dd7ba92f121726a31c56f50d4655d2a (commit)
via e6039bec0497aa7e1391958e5c4f84bbaeef653e (commit)
via ab08a8e2200157caaf73828b8459a641fff0d1e9 (commit)
via e3493974f91d07723008cdb8c7466a5ff8407cb5 (commit)
via 7db89c862386851d1f37e12a301aebbe92c5c6f1 (commit)
via 699f7cebc3057ddf22ca3c43c3d3534d605972ec (commit)
via 017dcf25de396de8e382c9a288c62e21717aa600 (commit)
via dd4831ea08257f8891a9822fd29ad9b2dba1be5f (commit)
via 9320734bb358e7148918da13e81ebba59ecf16e8 (commit)
via e046567a3f6fd8bec3113cec513d4a125054caf0 (commit)
via 9ec2e259bd565aea710cdae34d8cba433b09a749 (commit)
via 664fa00705ba7c1ee63d297afe6cdd0238c370e0 (commit)
via 4d124b29e9f45d674c1cb784a4789ec980125bd1 (commit)
via ec802abaf641d5c0d6c0fda6893d0c3126e3cb65 (commit)
via 06a7999b4f97b0ba5e7db1739f5a9531df724b86 (commit)
via 22152102405a1407355d42a32385efd0d83bbc9c (commit)
via e21e064af352066148e4f45c5c4594ae4b05daf3 (commit)
via d44aed1e3141d8e5491b949415c99f594ee79c21 (commit)
via dca911684e2f09e518e976f9e1e3d3c2aec2c86a (commit)
via 090241b266abe8558664a85b7e8e1b93c9ad60d0 (commit)
via 0d71d490e24d2f1dae33360f194259bb597f2799 (commit)
via 913eba4873631814daafa27d2474bb51e2378221 (commit)
via 87dad7df1d3e32afccf7357df1b1d39af5a98154 (commit)
via 8686e6aa3ba0f53b524898f8ef3a7214561cc6a4 (commit)
via a781af5eae4f4e7f6e07a2b205ad4e54e9e8ec7a (commit)
via e7253b56d761c939f1bc890a6b8c4087eab1410d (commit)
via 99d2472afc89ca78a4fef46ac08ce520b3bcf17b (commit)
via b323a94f313671b44a066a2f91dea562e9464d10 (commit)
via 5be1434f78d6dbcf2949918f7f042cab994ab0c5 (commit)
via 2d35cbd012daca122052739564120863fefebfce (commit)
from b0de143e088973715681f7eb6c41f2dccb648c2b (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 10ce16c28de952f6533ca3cc9df909269e3d2a53
Merge: b0de143 7df4149
Author: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>
Date: Mon Jul 23 14:14:16 2018 +0200
merge conflicts
Feature #13781
Arvados-DCO-1.1-Signed-off-by: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>
diff --cc package.json
index a8c5617,0c06a6f..06fa893
--- a/package.json
+++ b/package.json
@@@ -3,12 -3,11 +3,12 @@@
"version": "0.1.0",
"private": true,
"dependencies": {
- "@material-ui/core": "1.2.1",
+ "@material-ui/core": "1.4.0",
"@material-ui/icons": "1.1.0",
- "@types/lodash": "4.14.109",
+ "@types/lodash": "4.14.112",
+ "@types/redux-form": "^7.4.1",
"axios": "0.18.0",
- "classnames": "^2.2.6",
+ "classnames": "2.2.6",
"lodash": "4.17.10",
"react": "16.4.1",
"react-dom": "16.4.1",
@@@ -41,13 -40,11 +41,13 @@@
"@types/react-router-dom": "4.2.7",
"@types/react-router-redux": "5.0.15",
"@types/redux-devtools": "3.0.44",
+ "@types/redux-form": "^7.4.1",
- "axios-mock-adapter": "^1.15.0",
- "enzyme": "^3.3.0",
- "enzyme-adapter-react-16": "^1.1.1",
+ "axios-mock-adapter": "1.15.0",
+ "enzyme": "3.3.0",
+ "enzyme-adapter-react-16": "1.1.1",
"jest-localstorage-mock": "2.2.0",
"redux-devtools": "3.4.1",
+ "redux-form": "^7.4.2",
"typescript": "2.9.2"
},
"moduleNameMapper": {
diff --cc src/common/api/common-resource-service.ts
index 39825c0,2541fea..3956fb7
--- a/src/common/api/common-resource-service.ts
+++ b/src/common/api/common-resource-service.ts
@@@ -3,9 -3,9 +3,9 @@@
// SPDX-License-Identifier: AGPL-3.0
import * as _ from "lodash";
- import FilterBuilder from "./filter-builder";
- import OrderBuilder from "./order-builder";
+ import { FilterBuilder } from "./filter-builder";
+ import { OrderBuilder } from "./order-builder";
-import { AxiosInstance } from "axios";
+import { AxiosInstance, AxiosPromise } from "axios";
import { Resource } from "../../models/resource";
export interface ListArguments {
@@@ -26,12 -26,7 +26,12 @@@ export interface ListResults<T>
itemsAvailable: number;
}
+export interface Errors {
+ errors: string[];
+ errorToken: string;
+}
+
- export default class CommonResourceService<T extends Resource> {
+ export class CommonResourceService<T extends Resource> {
static mapResponseKeys = (response: any): Promise<any> =>
CommonResourceService.mapKeys(_.camelCase)(response.data)
diff --cc src/store/project/project-action.ts
index 3da60f6,2a7a5c1..075e77d
--- a/src/store/project/project-action.ts
+++ b/src/store/project/project-action.ts
@@@ -41,11 -42,11 +41,10 @@@ export const createProject = (project:
(dispatch: Dispatch, getState: () => RootState) => {
const { ownerUuid } = getState().projects.creator;
const projectData = { ownerUuid, ...project };
- dispatch(actions.CREATE_PROJECT(projectData));
+ dispatch(projectActions.CREATE_PROJECT(projectData));
return projectService
.create(projectData)
- .then(project => dispatch(actions.CREATE_PROJECT_SUCCESS(project)));
- .then(project => dispatch(projectActions.CREATE_PROJECT_SUCCESS(project)))
- .catch(() => dispatch(projectActions.CREATE_PROJECT_ERROR("Could not create a project")));
++ .then(project => dispatch(projectActions.CREATE_PROJECT_SUCCESS(project)));
};
- export type ProjectAction = UnionOf<typeof actions>;
- export default actions;
+ export type ProjectAction = UnionOf<typeof projectActions>;
diff --cc src/store/project/project-reducer.ts
index a329e81,40356c0..94a451a
--- a/src/store/project/project-reducer.ts
+++ b/src/store/project/project-reducer.ts
@@@ -112,12 -111,13 +112,12 @@@ const initialState: ProjectState =
};
- const projectsReducer = (state: ProjectState = initialState, action: ProjectAction) => {
- return actions.match(action, {
- OPEN_PROJECT_CREATOR: ({ ownerUuid }) => updateCreator(state, { ownerUuid, opened: true }),
+ export const projectsReducer = (state: ProjectState = initialState, action: ProjectAction) => {
+ return projectActions.match(action, {
+ OPEN_PROJECT_CREATOR: ({ ownerUuid }) => updateCreator(state, { ownerUuid, opened: true, pending: false }),
CLOSE_PROJECT_CREATOR: () => updateCreator(state, { opened: false }),
- CREATE_PROJECT: () => updateCreator(state, { opened: false, pending: true }),
- CREATE_PROJECT_SUCCESS: () => updateCreator(state, { ownerUuid: "", pending: false }),
- CREATE_PROJECT_ERROR: () => updateCreator(state, { ownerUuid: "", pending: false }),
+ CREATE_PROJECT: () => updateCreator(state, { error: undefined }),
+ CREATE_PROJECT_SUCCESS: () => updateCreator(state, { opened: false, ownerUuid: "" }),
REMOVE_PROJECT: () => state,
PROJECTS_REQUEST: itemId => {
const items = _.cloneDeep(state.items);
diff --cc src/store/store.ts
index 956fb46,adb7ddd..01b06b9
--- a/src/store/store.ts
+++ b/src/store/store.ts
@@@ -7,13 -7,13 +7,14 @@@ import { routerMiddleware, routerReduce
import thunkMiddleware from 'redux-thunk';
import { History } from "history";
- import projectsReducer, { ProjectState } from "./project/project-reducer";
- import sidePanelReducer, { SidePanelState } from './side-panel/side-panel-reducer';
- import authReducer, { AuthState } from "./auth/auth-reducer";
- import dataExplorerReducer, { DataExplorerState } from './data-explorer/data-explorer-reducer';
- import { projectPanelMiddleware } from '../store/project-panel/project-panel-middleware';
- import detailsPanelReducer, { DetailsPanelState } from './details-panel/details-panel-reducer';
+ import { projectsReducer, ProjectState } from "./project/project-reducer";
+ import { sidePanelReducer, SidePanelState } from './side-panel/side-panel-reducer';
+ import { authReducer, AuthState } from "./auth/auth-reducer";
+ import { dataExplorerReducer, DataExplorerState } from './data-explorer/data-explorer-reducer';
+ import { projectPanelMiddleware } from './project-panel/project-panel-middleware';
+ import { detailsPanelReducer, DetailsPanelState } from './details-panel/details-panel-reducer';
+ import { contextMenuReducer, ContextMenuState } from './context-menu/context-menu-reducer';
+import { reducer as formReducer } from 'redux-form';
const composeEnhancers =
(process.env.NODE_ENV === 'development' &&
@@@ -36,7 -37,7 +38,8 @@@ const rootReducer = combineReducers(
dataExplorer: dataExplorerReducer,
sidePanel: sidePanelReducer,
detailsPanel: detailsPanelReducer,
- contextMenu: contextMenuReducer
++ contextMenu: contextMenuReducer,
+ form: formReducer
});
diff --cc src/views-components/create-project-dialog/create-project-dialog.tsx
index f75c459,2f3e0b7..43621bf
--- a/src/views-components/create-project-dialog/create-project-dialog.tsx
+++ b/src/views-components/create-project-dialog/create-project-dialog.tsx
@@@ -4,12 -4,10 +4,12 @@@
import { connect } from "react-redux";
import { Dispatch } from "redux";
+import { SubmissionError } from "redux-form";
+
import { RootState } from "../../store/store";
- import DialogProjectCreate from "../dialog-create/dialog-project-create";
- import actions, { createProject, getProjectList } from "../../store/project/project-action";
- import dataExplorerActions from "../../store/data-explorer/data-explorer-action";
-import { DialogProjectCreate as DialogProjectCreateComponent } from "../dialog-create/dialog-project-create";
++import DialogProjectCreate from "../dialog-create/dialog-project-create";
+ import { projectActions, createProject, getProjectList } from "../../store/project/project-action";
+ import { dataExplorerActions } from "../../store/data-explorer/data-explorer-action";
import { PROJECT_PANEL_ID } from "../../views/project-panel/project-panel";
const mapStateToProps = (state: RootState) => ({
@@@ -27,14 -25,11 +27,14 @@@ export const addProject = (data: { name
const mapDispatchToProps = (dispatch: Dispatch) => ({
handleClose: () => {
- dispatch(actions.CLOSE_PROJECT_CREATOR());
+ dispatch(projectActions.CLOSE_PROJECT_CREATOR());
},
onSubmit: (data: { name: string, description: string }) => {
- dispatch<any>(submit(data));
+ return dispatch<any>(addProject(data))
+ .catch((e: any) => {
+ throw new SubmissionError({ name: e.errors.join("").includes("UniqueViolation") ? "Project with this name already exists." : "" });
+ });
}
});
- export default connect(mapStateToProps, mapDispatchToProps)(DialogProjectCreate);
-export const CreateProjectDialog = connect(mapStateToProps, mapDispatchToProps)(DialogProjectCreateComponent);
++export const CreateProjectDialog = connect(mapStateToProps, mapDispatchToProps)(DialogProjectCreate);
diff --cc src/views-components/dialog-create/dialog-project-create.tsx
index 6fb8a69,aefb815..34c655e
--- a/src/views-components/dialog-create/dialog-project-create.tsx
+++ b/src/views-components/dialog-create/dialog-project-create.tsx
@@@ -122,7 -37,106 +122,7 @@@ const styles: StyleRulesCallback<CssRul
}
});
-interface ProjectCreateProps {
- open: boolean;
- handleClose: () => void;
- onSubmit: (data: { name: string, description: string }) => void;
-}
-
-interface DialogState {
- name: string;
- description: string;
- isNameValid: boolean;
- isDescriptionValid: boolean;
-}
-
-export const DialogProjectCreate = withStyles(styles)(
- class extends React.Component<ProjectCreateProps & WithStyles<CssRules>> {
- state: DialogState = {
- name: '',
- description: '',
- isNameValid: false,
- isDescriptionValid: true
- };
-
- render() {
- const { name, description } = this.state;
- const { classes, open, handleClose } = this.props;
-
- return (
- <Dialog
- open={open}
- onClose={handleClose}>
- <div className={classes.dialog}>
- <DialogTitle id="form-dialog-title" className={classes.dialogTitle}>Create a project</DialogTitle>
- <DialogContent className={classes.dialogContent}>
- <Validator
- value={name}
- onChange={e => this.isNameValid(e)}
- isRequired={true}
- render={hasError =>
- <TextField
- margin="dense"
- className={classes.textField}
- id="name"
- onChange={e => this.handleProjectName(e)}
- label="Project name"
- error={hasError}
- fullWidth/>}/>
- <Validator
- value={description}
- onChange={e => this.isDescriptionValid(e)}
- isRequired={false}
- render={hasError =>
- <TextField
- margin="dense"
- className={classes.textField}
- id="description"
- onChange={e => this.handleDescriptionValue(e)}
- label="Description - optional"
- error={hasError}
- fullWidth/>}/>
- </DialogContent>
- <DialogActions>
- <Button onClick={handleClose} className={classes.button} color="primary">CANCEL</Button>
- <Button onClick={this.handleSubmit} className={classes.lastButton} color="primary"
- disabled={!this.state.isNameValid || (!this.state.isDescriptionValid && description.length > 0)}
- variant="raised">CREATE A PROJECT</Button>
- </DialogActions>
- </div>
- </Dialog>
- );
- }
-
- handleSubmit = () => {
- this.props.onSubmit({
- name: this.state.name,
- description: this.state.description
- });
- }
-
- handleProjectName(e: React.ChangeEvent<HTMLInputElement>) {
- this.setState({
- name: e.target.value,
- });
- }
-
- handleDescriptionValue(e: React.ChangeEvent<HTMLInputElement>) {
- this.setState({
- description: e.target.value,
- });
- }
-
- isNameValid(value: boolean | string) {
- this.setState({
- isNameValid: value,
- });
- }
-
- isDescriptionValid(value: boolean | string) {
- this.setState({
- isDescriptionValid: value,
- });
- }
- }
-);
+export default compose(
+ reduxForm({ form: 'projectCreateDialog' }),
+ withStyles(styles)
- )(DialogProjectCreate);
++)(DialogProjectCreate);
diff --cc src/views/workbench/workbench.tsx
index b2bdac8,a62b713..b1e7cd7
--- a/src/views/workbench/workbench.tsx
+++ b/src/views/workbench/workbench.tsx
@@@ -111,207 -104,157 +104,157 @@@ interface WorkbenchState
};
}
-
- class Workbench extends React.Component<WorkbenchProps, WorkbenchState> {
- state = {
- contextMenu: {
- anchorEl: undefined,
- itemUuid: undefined
- },
- isCreationDialogOpen: false,
- anchorEl: null,
- searchText: "",
- breadcrumbs: [],
- 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"))
+ export const Workbench = withStyles(styles)(
+ connect<WorkbenchDataProps>(
+ (state: RootState) => ({
+ projects: state.projects.items,
+ currentProjectId: state.projects.currentItemId,
+ user: state.auth.user,
+ sidePanelItems: state.sidePanel
+ })
+ )(
+ class extends React.Component<WorkbenchProps, WorkbenchState> {
+ state = {
+ isCreationDialogOpen: false,
+ anchorEl: null,
+ searchText: "",
+ breadcrumbs: [],
+ 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())
+ }
+ ]
}
- ],
- anonymousMenu: [
- {
- label: "Sign in",
- action: () => this.props.dispatch(authActions.LOGIN())
- }
- ]
- }
- };
+ };
- mainAppBarActions: MainAppBarActionProps = {
- onBreadcrumbClick: ({ itemId }: NavBreadcrumb) => {
- this.props.dispatch<any>(setProjectItem(itemId, ItemMode.BOTH));
- this.props.dispatch<any>(loadDetails(itemId, ResourceKind.Project));
- },
- onSearch: searchText => {
- this.setState({ searchText });
- this.props.dispatch(push(`/search?q=${searchText}`));
- },
- onMenuItemClick: (menuItem: NavMenuItem) => menuItem.action(),
- onDetailsPanelToggle: () => {
- this.props.dispatch(detailsPanelActions.TOGGLE_DETAILS_PANEL());
- },
- onContextMenu: (event: React.MouseEvent<HTMLElement>, breadcrumb: NavBreadcrumb) => {
- this.openContextMenu(event, breadcrumb.itemId);
- }
- };
+ render() {
+ const path = getTreePath(this.props.projects, this.props.currentProjectId);
+ const breadcrumbs = path.map(item => ({
+ label: item.data.name,
+ itemId: item.data.uuid,
+ status: item.status
+ }));
- toggleSidePanelOpen = (itemId: string) => {
- this.props.dispatch(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_OPEN(itemId));
- }
+ const { classes, user } = this.props;
+ return (
+ <div className={classes.root}>
+ <div className={classes.appBar}>
+ <MainAppBar
+ breadcrumbs={breadcrumbs}
+ searchText={this.state.searchText}
+ user={this.props.user}
+ menuItems={this.state.menuItems}
+ {...this.mainAppBarActions} />
+ </div>
+ {user &&
+ <Drawer
+ variant="permanent"
+ classes={{
+ paper: classes.drawerPaper,
+ }}>
+ <div className={classes.toolbar} />
+ <SidePanel
+ toggleOpen={this.toggleSidePanelOpen}
+ toggleActive={this.toggleSidePanelActive}
+ sidePanelItems={this.props.sidePanelItems}
+ onContextMenu={(event) => this.openContextMenu(event, authService.getUuid() || "", ContextMenuKind.RootProject)}>
+ <ProjectTree
+ projects={this.props.projects}
+ toggleOpen={itemId => this.props.dispatch<any>(setProjectItem(itemId, ItemMode.OPEN))}
+ onContextMenu={(event, item) => this.openContextMenu(event, item.data.uuid, ContextMenuKind.Project)}
+ toggleActive={itemId => {
+ this.props.dispatch<any>(setProjectItem(itemId, ItemMode.ACTIVE));
+ this.props.dispatch<any>(loadDetails(itemId, ResourceKind.Project));
+ this.props.dispatch<any>(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_ACTIVE(SidePanelIdentifiers.Projects));
+ }} />
+ </SidePanel>
+ </Drawer>}
+ <main className={classes.contentWrapper}>
+ <div className={classes.content}>
+ <Switch>
+ <Route path="/projects/:id" render={this.renderProjectPanel} />
+ </Switch>
+ </div>
- { user && <DetailsPanel /> }
++ {user && <DetailsPanel />}
+ </main>
+ <ContextMenu />
+ <CreateProjectDialog />
+ </div>
+ );
+ }
- toggleSidePanelActive = (itemId: string) => {
- this.props.dispatch(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_ACTIVE(itemId));
- this.props.dispatch(projectActions.RESET_PROJECT_TREE_ACTIVITY(itemId));
- this.props.dispatch(push("/"));
- }
+ renderProjectPanel = (props: RouteComponentProps<{ id: string }>) => <ProjectPanel
+ onItemRouteChange={itemId => this.props.dispatch<any>(setProjectItem(itemId, ItemMode.ACTIVE))}
+ onContextMenu={(event, item) => this.openContextMenu(event, item.uuid, ContextMenuKind.Project)}
+ onDialogOpen={this.handleCreationDialogOpen}
+ onItemClick={item => {
+ this.props.dispatch<any>(loadDetails(item.uuid, item.kind as ResourceKind));
+ }}
+ onItemDoubleClick={item => {
+ this.props.dispatch<any>(setProjectItem(item.uuid, ItemMode.ACTIVE));
+ this.props.dispatch<any>(loadDetails(item.uuid, ResourceKind.Project));
+ }}
+ {...props} />
- handleCreationDialogOpen = (itemUuid: string) => {
- this.closeContextMenu();
- this.props.dispatch(projectActions.OPEN_PROJECT_CREATOR({ ownerUuid: itemUuid }));
- }
+ mainAppBarActions: MainAppBarActionProps = {
+ onBreadcrumbClick: ({ itemId }: NavBreadcrumb) => {
+ this.props.dispatch<any>(setProjectItem(itemId, ItemMode.BOTH));
+ this.props.dispatch<any>(loadDetails(itemId, ResourceKind.Project));
+ },
+ onSearch: searchText => {
+ this.setState({ searchText });
+ this.props.dispatch(push(`/search?q=${searchText}`));
+ },
+ onMenuItemClick: (menuItem: NavMenuItem) => menuItem.action(),
+ onDetailsPanelToggle: () => {
+ this.props.dispatch(detailsPanelActions.TOGGLE_DETAILS_PANEL());
+ },
+ onContextMenu: (event: React.MouseEvent<HTMLElement>, breadcrumb: NavBreadcrumb) => {
+ this.openContextMenu(event, breadcrumb.itemId, ContextMenuKind.Project);
+ }
+ };
+ toggleSidePanelOpen = (itemId: string) => {
+ this.props.dispatch(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_OPEN(itemId));
+ }
- openContextMenu = (event: React.MouseEvent<HTMLElement>, itemUuid: string) => {
- event.preventDefault();
- this.setState({
- contextMenu: {
- anchorEl: mockAnchorFromMouseEvent(event),
- itemUuid
+ toggleSidePanelActive = (itemId: string) => {
+ this.props.dispatch(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_ACTIVE(itemId));
+ this.props.dispatch(projectActions.RESET_PROJECT_TREE_ACTIVITY(itemId));
+ this.props.dispatch(push("/"));
}
- });
- }
- closeContextMenu = () => {
- this.setState({ contextMenu: {} });
- }
+ handleCreationDialogOpen = (itemUuid: string) => {
+ this.props.dispatch(projectActions.OPEN_PROJECT_CREATOR({ ownerUuid: itemUuid }));
+ }
- openCreateDialog = (item: ContextMenuAction) => {
- const { itemUuid } = this.state.contextMenu;
- if (item.openCreateDialog && itemUuid) {
- this.handleCreationDialogOpen(itemUuid);
+ openContextMenu = (event: React.MouseEvent<HTMLElement>, itemUuid: string, kind: ContextMenuKind) => {
+ event.preventDefault();
+ this.props.dispatch(
+ contextMenuActions.OPEN_CONTEXT_MENU({
+ position: { x: event.clientX, y: event.clientY },
+ resource: { uuid: itemUuid, kind }
+ })
+ );
+ }
}
- }
-
- render() {
- const path = getTreePath(this.props.projects, this.props.currentProjectId);
- const breadcrumbs = path.map(item => ({
- label: item.data.name,
- itemId: item.data.uuid,
- status: item.status
- }));
-
- const { classes, user } = this.props;
- return (
- <div className={classes.root}>
- <div className={classes.appBar}>
- <MainAppBar
- breadcrumbs={breadcrumbs}
- searchText={this.state.searchText}
- user={this.props.user}
- menuItems={this.state.menuItems}
- {...this.mainAppBarActions} />
- </div>
- {user &&
- <Drawer
- variant="permanent"
- classes={{
- paper: classes.drawerPaper,
- }}>
- <div className={classes.toolbar} />
- <SidePanel
- toggleOpen={this.toggleSidePanelOpen}
- toggleActive={this.toggleSidePanelActive}
- sidePanelItems={this.props.sidePanelItems}
- onContextMenu={(event) => this.openContextMenu(event, authService.getUuid() || "")}>
- <ProjectTree
- projects={this.props.projects}
- toggleOpen={itemId => this.props.dispatch<any>(setProjectItem(itemId, ItemMode.OPEN))}
- onContextMenu={(event, item) => this.openContextMenu(event, item.data.uuid)}
- toggleActive={itemId => {
- this.props.dispatch<any>(setProjectItem(itemId, ItemMode.ACTIVE));
- this.props.dispatch<any>(loadDetails(itemId, ResourceKind.Project));
- this.props.dispatch<any>(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_ACTIVE(SidePanelIdentifiers.Projects));
- }} />
- </SidePanel>
- </Drawer>}
- <main className={classes.contentWrapper}>
- <div className={classes.content}>
- <Switch>
- <Route path="/projects/:id" render={this.renderProjectPanel} />
- </Switch>
- </div>
- <DetailsPanel />
- </main>
- <ContextMenu
- anchorEl={this.state.contextMenu.anchorEl}
- actions={contextMenuActions}
- onActionClick={this.openCreateDialog}
- onClose={this.closeContextMenu} />
- <DialogProjectCreate />
- </div>
- );
- }
-
- renderProjectPanel = (props: RouteComponentProps<{ id: string }>) => <ProjectPanel
- onItemRouteChange={itemId => this.props.dispatch<any>(setProjectItem(itemId, ItemMode.ACTIVE))}
- onContextMenu={(event, item) => this.openContextMenu(event, item.uuid)}
- onDialogOpen={this.handleCreationDialogOpen}
- onItemClick={item => {
- this.props.dispatch<any>(loadDetails(item.uuid, item.kind as ResourceKind));
- }}
- onItemDoubleClick={item => {
- this.props.dispatch<any>(setProjectItem(item.uuid, ItemMode.ACTIVE));
- this.props.dispatch<any>(loadDetails(item.uuid, ResourceKind.Project));
- }}
- {...props} />
- }
-
- const contextMenuActions = [[{
- icon: "fas fa-plus fa-fw",
- name: "New project",
- openCreateDialog: true
- }, {
- icon: "fas fa-users fa-fw",
- name: "Share"
- }, {
- icon: "fas fa-sign-out-alt fa-fw",
- name: "Move to"
- }, {
- icon: "fas fa-star fa-fw",
- name: "Add to favourite"
- }, {
- icon: "fas fa-edit fa-fw",
- name: "Rename"
- }, {
- icon: "fas fa-copy fa-fw",
- name: "Make a copy"
- }, {
- icon: "fas fa-download fa-fw",
- name: "Download"
- }], [{
- icon: "fas fa-trash-alt fa-fw",
- name: "Remove"
- }
- ]];
-
- export default connect<WorkbenchDataProps>(
- (state: RootState) => ({
- projects: state.projects.items,
- currentProjectId: state.projects.currentItemId,
- user: state.auth.user,
- sidePanelItems: state.sidePanel
- })
- )(
- withStyles(styles)(Workbench)
+ )
);
diff --cc yarn.lock
index 0034169,6960aaf..3557ebe
--- a/yarn.lock
+++ b/yarn.lock
@@@ -3347,13 -3334,9 +3345,13 @@@ hmac-drbg@^1.0.0
minimalistic-crypto-utils "^1.0.1"
hoist-non-react-statics@^2.3.1, hoist-non-react-statics@^2.5.0:
- version "2.5.4"
- resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.4.tgz#fc3b1ac05d2ae3abedec84eba846511b0d4fcc4f"
+ version "2.5.5"
+ resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47"
+hoist-non-react-statics@^2.5.4:
+ version "2.5.5"
+ resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47"
+
home-or-tmp@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8"
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list