From: Michal Klobukowski Date: Tue, 7 Aug 2018 12:20:35 +0000 (+0200) Subject: Merge branch 'master' X-Git-Tag: 1.2.0~10^2~1 X-Git-Url: https://git.arvados.org/arvados-workbench2.git/commitdiff_plain/e63198a93d7b537ffbb68b8210c99f76041fd112 Merge branch 'master' Feature #13952 Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski --- e63198a93d7b537ffbb68b8210c99f76041fd112 diff --cc src/views-components/dialog-create/dialog-collection-create.tsx index c599b22d,804aae11..0686904a --- a/src/views-components/dialog-create/dialog-collection-create.tsx +++ b/src/views-components/dialog-create/dialog-collection-create.tsx @@@ -5,11 -5,18 +5,15 @@@ import * as React from 'react'; import { reduxForm, Field } from 'redux-form'; import { compose } from 'redux'; -import TextField from '@material-ui/core/TextField'; -import Dialog from '@material-ui/core/Dialog'; -import DialogActions from '@material-ui/core/DialogActions'; -import DialogContent from '@material-ui/core/DialogContent'; -import DialogTitle from '@material-ui/core/DialogTitle'; +import { TextField } from '../../components/text-field/text-field'; +import { Dialog, DialogActions, DialogContent, DialogTitle } from '@material-ui/core/'; import { Button, StyleRulesCallback, WithStyles, withStyles, CircularProgress } from '@material-ui/core'; - import { COLLECTION_NAME_VALIDATION, COLLECTION_DESCRIPTION_VALIDATION } from '../../validators/create-project/create-project-validator'; + import { COLLECTION_NAME_VALIDATION, COLLECTION_DESCRIPTION_VALIDATION } from '../../validators/create-collection/create-collection-validator'; + import { FileUpload } from "../../components/file-upload/file-upload"; + import { connect, DispatchProp } from "react-redux"; + import { RootState } from "../../store/store"; + import { collectionUploaderActions, UploadFile } from "../../store/collections/uploader/collection-uploader-actions"; type CssRules = "button" | "lastButton" | "formContainer" | "textField" | "createProgress" | "dialogActions"; @@@ -45,54 -53,86 +50,64 @@@ interface DialogCollectionCreateProps submitting: boolean; invalid: boolean; pristine: boolean; + files: UploadFile[]; } -interface TextFieldProps { - label: string; - floatinglabeltext: string; - className?: string; - input?: string; - meta?: any; -} - export const DialogCollectionCreate = compose( + connect((state: RootState) => ({ + files: state.collections.uploader + })), reduxForm({ form: 'collectionCreateDialog' }), withStyles(styles))( - class DialogCollectionCreate extends React.Component> { - class DialogCollectionCreate extends React.Component> { - render() { - const { classes, open, handleClose, handleSubmit, onSubmit, submitting, invalid, pristine, files } = this.props; - const busy = submitting || files.reduce( - (prev, curr) => prev + (curr.loaded > 0 && curr.loaded < curr.total ? 1 : 0), 0 - ) > 0; - return ( - -
onSubmit(data, files))}> - Create a collection - - > { + render() { - const { classes, open, handleClose, handleSubmit, onSubmit, submitting, invalid, pristine } = this.props; - ++ const { classes, open, handleClose, handleSubmit, onSubmit, submitting, invalid, pristine, files } = this.props; ++ const busy = submitting || files.reduce( ++ (prev, curr) => prev + (curr.loaded > 0 && curr.loaded < curr.total ? 1 : 0), 0 ++ ) > 0; + return ( + - onSubmit(data))}> ++ onSubmit(data, files))}> + Create a collection + + - + - this.props.dispatch(collectionUploaderActions.SET_UPLOAD_FILES(files))}/> - - - + disabled={busy}>CANCEL - - {submitting && } - {busy && } - - - - ); ++ {busy && } + + +
+ ); + } } - - renderTextField = ({ input, label, meta: { touched, error }, ...custom }: TextFieldProps) => ( - - ) - } -); + ); diff --cc src/views-components/project-tree-picker/project-tree-picker.tsx index 6effd86d,00000000..1c343a2d mode 100644,000000..100644 --- a/src/views-components/project-tree-picker/project-tree-picker.tsx +++ b/src/views-components/project-tree-picker/project-tree-picker.tsx @@@ -1,75 -1,0 +1,75 @@@ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 + +import * as React from "react"; +import { Dispatch } from "redux"; +import { connect } from "react-redux"; +import { Typography } from "@material-ui/core"; +import { TreePicker } from "../tree-picker/tree-picker"; +import { TreeProps, TreeItem, TreeItemStatus } from "../../components/tree/tree"; +import { ProjectResource } from "../../models/project"; +import { treePickerActions } from "../../store/tree-picker/tree-picker-actions"; +import { ListItemTextIcon } from "../../components/list-item-text-icon/list-item-text-icon"; +import { ProjectIcon } from "../../components/icon/icon"; +import { createTreePickerNode } from "../../store/tree-picker/tree-picker"; +import { RootState } from "../../store/store"; +import { ServiceRepository } from "../../services/services"; +import { FilterBuilder } from "../../common/api/filter-builder"; + +type ProjectTreePickerProps = Pick, 'toggleItemActive' | 'toggleItemOpen'>; + +const mapDispatchToProps = (dispatch: Dispatch, props: {onChange: (projectUuid: string) => void}): ProjectTreePickerProps => ({ + toggleItemActive: id => { + dispatch(treePickerActions.TOGGLE_TREE_PICKER_NODE_SELECT({ id })); + props.onChange(id); + }, + toggleItemOpen: (id, status) => { + status === TreeItemStatus.INITIAL + ? dispatch(loadProjectTreePickerProjects(id)) + : dispatch(treePickerActions.TOGGLE_TREE_PICKER_NODE_COLLAPSE({ id })); + } +}); + +export const ProjectTreePicker = connect(undefined, mapDispatchToProps)((props: ProjectTreePickerProps) => +
+ + Select a project + +
+ +
+
); + +// TODO: move action creator to store directory +export const loadProjectTreePickerProjects = (id: string) => + async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { + dispatch(treePickerActions.LOAD_TREE_PICKER_NODE({ id })); + + const ownerUuid = id.length === 0 ? services.authService.getUuid() || '' : id; + + const filters = FilterBuilder - .create() ++ .create() + .addEqual('ownerUuid', ownerUuid); + + const { items } = await services.projectService.list({ filters }); + + dispatch(receiveProjectTreePickerData(id, items)); + }; + +const renderTreeItem = (item: TreeItem) => + ; + +// TODO: move action creator to store directory +const receiveProjectTreePickerData = (id: string, projects: ProjectResource[]) => + (dispatch: Dispatch) => { + dispatch(treePickerActions.LOAD_TREE_PICKER_NODE_SUCCESS({ + id, + nodes: projects.map(project => createTreePickerNode({ id: project.uuid, value: project })) + })); + dispatch(treePickerActions.TOGGLE_TREE_PICKER_NODE_COLLAPSE({ id })); + }; diff --cc src/views/workbench/workbench.tsx index 147c0a8a,69d80986..a8552eef --- a/src/views/workbench/workbench.tsx +++ b/src/views/workbench/workbench.tsx @@@ -38,14 -38,12 +38,14 @@@ import { Snackbar } from '../../views-c import { favoritePanelActions } from '../../store/favorite-panel/favorite-panel-action'; import { CreateCollectionDialog } from '../../views-components/create-collection-dialog/create-collection-dialog'; import { CollectionPanel } from '../collection-panel/collection-panel'; - import { loadCollection } from '../../store/collection-panel/collection-panel-action'; + import { loadCollection, loadCollectionTags } from '../../store/collection-panel/collection-panel-action'; import { getCollectionUrl } from '../../models/collection'; -import { RemoveDialog } from '../../views-components/remove-dialog/remove-dialog'; -import { RenameDialog } from '../../views-components/rename-dialog/rename-dialog'; import { UpdateCollectionDialog } from '../../views-components/update-collection-dialog/update-collection-dialog.'; import { AuthService } from "../../services/auth-service/auth-service"; +import { RenameFileDialog } from '../../views-components/rename-file-dialog/rename-file-dialog'; +import { FileRemoveDialog } from '../../views-components/file-remove-dialog/file-remove-dialog'; +import { MultipleFilesRemoveDialog } from '../../views-components/file-remove-dialog/multiple-files-remove-dialog'; +import { DialogCollectionCreateWithSelectedFile } from '../../views-components/create-collection-dialog-with-selected/create-collection-dialog-with-selected'; const DRAWER_WITDH = 240; const APP_BAR_HEIGHT = 100;