From: Janicki Artur Date: Thu, 16 Aug 2018 07:04:05 +0000 (+0200) Subject: init edit project feature, refactor forms - add textField component X-Git-Tag: 1.3.0~156^2~2 X-Git-Url: https://git.arvados.org/arvados-workbench2.git/commitdiff_plain/eebf51242e597fd8430f1e92a5e9076b3d623ab5 init edit project feature, refactor forms - add textField component Feature #13833 Arvados-DCO-1.1-Signed-off-by: Janicki Artur --- diff --git a/src/store/project/project-action.ts b/src/store/project/project-action.ts index bef50d11..70800909 100644 --- a/src/store/project/project-action.ts +++ b/src/store/project/project-action.ts @@ -9,12 +9,16 @@ import { FilterBuilder } from "~/common/api/filter-builder"; import { RootState } from "../store"; import { checkPresenceInFavorites } from "../favorites/favorites-actions"; import { ServiceRepository } from "~/services/services"; +import { projectPanelActions } from "~/store/project-panel/project-panel-action"; export const projectActions = unionize({ OPEN_PROJECT_CREATOR: ofType<{ ownerUuid: string }>(), CLOSE_PROJECT_CREATOR: ofType<{}>(), CREATE_PROJECT: ofType>(), CREATE_PROJECT_SUCCESS: ofType(), + OPEN_PROJECT_UPDATER: ofType<{ uuid: string}>(), + CLOSE_PROJECT_UPDATER: ofType<{}>(), + UPDATE_PROJECT_SUCCESS: ofType(), REMOVE_PROJECT: ofType(), PROJECTS_REQUEST: ofType(), PROJECTS_SUCCESS: ofType<{ projects: ProjectResource[], parentItemId?: string }>(), @@ -26,6 +30,8 @@ export const projectActions = unionize({ value: 'payload' }); +export const PROJECT_FORM_NAME = 'projectEditDialog'; + export const getProjectList = (parentUuid: string = '') => (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { dispatch(projectActions.PROJECTS_REQUEST(parentUuid)); @@ -50,4 +56,17 @@ export const createProject = (project: Partial) => .then(project => dispatch(projectActions.CREATE_PROJECT_SUCCESS(project))); }; +export const updateProject = (project: Partial) => + (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { + const { uuid } = getState().projects.updater; + return services.projectService + .update(uuid, project) + .then(project => { + dispatch(projectActions.UPDATE_PROJECT_SUCCESS(project)); + dispatch(projectPanelActions.REQUEST_ITEMS()); + dispatch(getProjectList(project.ownerUuid)); + // ToDo: Update Panel Details + }); + }; + export type ProjectAction = UnionOf; diff --git a/src/store/project/project-reducer.test.ts b/src/store/project/project-reducer.test.ts index cd96afce..d5963f33 100644 --- a/src/store/project/project-reducer.test.ts +++ b/src/store/project/project-reducer.test.ts @@ -35,6 +35,10 @@ describe('project-reducer', () => { creator: { opened: false, ownerUuid: "", + }, + updater: { + opened: false, + uuid: '' } }); }); @@ -50,6 +54,7 @@ describe('project-reducer', () => { }], currentItemId: "1", creator: { opened: false, ownerUuid: "" }, + updater: { opened: false, uuid: '' } }; const project = { items: [{ @@ -61,6 +66,7 @@ describe('project-reducer', () => { }], currentItemId: "", creator: { opened: false, ownerUuid: "" }, + updater: { opened: false, uuid: '' } }; const state = projectsReducer(initialState, projectActions.RESET_PROJECT_TREE_ACTIVITY(initialState.items[0].id)); @@ -77,7 +83,8 @@ describe('project-reducer', () => { status: TreeItemStatus.PENDING }], currentItemId: "1", - creator: { opened: false, ownerUuid: "" } + creator: { opened: false, ownerUuid: "" }, + updater: { opened: false, uuid: '' } }; const project = { items: [{ @@ -89,6 +96,7 @@ describe('project-reducer', () => { }], currentItemId: "1", creator: { opened: false, ownerUuid: "" }, + updater: { opened: false, uuid: '' } }; const state = projectsReducer(initialState, projectActions.TOGGLE_PROJECT_TREE_ITEM_ACTIVE(initialState.items[0].id)); @@ -106,7 +114,8 @@ describe('project-reducer', () => { status: TreeItemStatus.PENDING, }], currentItemId: "1", - creator: { opened: false, ownerUuid: "" } + creator: { opened: false, ownerUuid: "" }, + updater: { opened: false, uuid: '' } }; const project = { items: [{ @@ -118,6 +127,7 @@ describe('project-reducer', () => { }], currentItemId: "1", creator: { opened: false, ownerUuid: "" }, + }; const state = projectsReducer(initialState, projectActions.TOGGLE_PROJECT_TREE_ITEM_OPEN(initialState.items[0].id)); diff --git a/src/store/project/project-reducer.ts b/src/store/project/project-reducer.ts index 42490078..bb074865 100644 --- a/src/store/project/project-reducer.ts +++ b/src/store/project/project-reducer.ts @@ -11,7 +11,8 @@ import { ProjectResource } from "~/models/project"; export type ProjectState = { items: Array>, currentItemId: string, - creator: ProjectCreator + creator: ProjectCreator, + updater: ProjectUpdater }; interface ProjectCreator { @@ -20,6 +21,11 @@ interface ProjectCreator { error?: string; } +interface ProjectUpdater { + opened: boolean; + uuid: string; +} + export function findTreeItem(tree: Array>, itemId: string): TreeItem | undefined { let item; for (const t of tree) { @@ -100,12 +106,24 @@ const updateCreator = (state: ProjectState, creator: Partial) => } }); +const updateProject = (state: ProjectState, updater?: Partial) => ({ + ...state, + updater: { + ...state.updater, + ...updater + } +}); + const initialState: ProjectState = { items: [], currentItemId: "", creator: { opened: false, ownerUuid: "" + }, + updater: { + opened: false, + uuid: '' } }; @@ -116,6 +134,9 @@ export const projectsReducer = (state: ProjectState = initialState, action: Proj CLOSE_PROJECT_CREATOR: () => updateCreator(state, { opened: false }), CREATE_PROJECT: () => updateCreator(state, { error: undefined }), CREATE_PROJECT_SUCCESS: () => updateCreator(state, { opened: false, ownerUuid: "" }), + OPEN_PROJECT_UPDATER: ({ uuid }) => updateProject(state, { uuid, opened: true }), + CLOSE_PROJECT_UPDATER: () => updateProject(state, { opened: false, uuid: "" }), + UPDATE_PROJECT_SUCCESS: () => updateProject(state, { opened: false, uuid: "" }), REMOVE_PROJECT: () => state, PROJECTS_REQUEST: itemId => { const items = _.cloneDeep(state.items); diff --git a/src/validators/create-collection/create-collection-validator.tsx b/src/validators/create-collection/create-collection-validator.tsx deleted file mode 100644 index 2d8e1f50..00000000 --- a/src/validators/create-collection/create-collection-validator.tsx +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -import { require } from '../require'; -import { maxLength } from '../max-length'; - -export const COLLECTION_NAME_VALIDATION = [require, maxLength(255)]; -export const COLLECTION_DESCRIPTION_VALIDATION = [maxLength(255)]; \ No newline at end of file diff --git a/src/validators/create-project/create-project-validator.tsx b/src/validators/create-project/create-project-validator.tsx deleted file mode 100644 index ddea8be9..00000000 --- a/src/validators/create-project/create-project-validator.tsx +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -import { require } from '../require'; -import { maxLength } from '../max-length'; - -export const PROJECT_NAME_VALIDATION = [require, maxLength(255)]; -export const PROJECT_DESCRIPTION_VALIDATION = [maxLength(255)]; -export const COLLECTION_NAME_VALIDATION = [require, maxLength(255)]; -export const COLLECTION_DESCRIPTION_VALIDATION = [maxLength(255)]; -export const COLLECTION_PROJECT_VALIDATION = [require]; diff --git a/src/validators/validators.tsx b/src/validators/validators.tsx index fdeb8fa8..edd07822 100644 --- a/src/validators/validators.tsx +++ b/src/validators/validators.tsx @@ -6,4 +6,11 @@ import { require } from './require'; import { maxLength } from './max-length'; export const TAG_KEY_VALIDATION = [require, maxLength(255)]; -export const TAG_VALUE_VALIDATION = [require, maxLength(255)]; \ No newline at end of file +export const TAG_VALUE_VALIDATION = [require, maxLength(255)]; + +export const PROJECT_NAME_VALIDATION = [require, maxLength(255)]; +export const PROJECT_DESCRIPTION_VALIDATION = [maxLength(255)]; + +export const COLLECTION_NAME_VALIDATION = [require, maxLength(255)]; +export const COLLECTION_DESCRIPTION_VALIDATION = [maxLength(255)]; +export const COLLECTION_PROJECT_VALIDATION = [require]; \ No newline at end of file diff --git a/src/views-components/context-menu/action-sets/project-action-set.ts b/src/views-components/context-menu/action-sets/project-action-set.ts index 89446850..1b000c88 100644 --- a/src/views-components/context-menu/action-sets/project-action-set.ts +++ b/src/views-components/context-menu/action-sets/project-action-set.ts @@ -2,28 +2,39 @@ // // SPDX-License-Identifier: AGPL-3.0 -import { reset } from "redux-form"; +import { reset, initialize } from "redux-form"; import { ContextMenuActionSet } from "../context-menu-action-set"; -import { projectActions } from "~/store/project/project-action"; -import { NewProjectIcon } from "~/components/icon/icon"; +import { projectActions, PROJECT_FORM_NAME } from "~/store/project/project-action"; +import { NewProjectIcon, RenameIcon } from "~/components/icon/icon"; import { ToggleFavoriteAction } from "../actions/favorite-action"; import { toggleFavorite } from "~/store/favorites/favorites-actions"; import { favoritePanelActions } from "~/store/favorite-panel/favorite-panel-action"; import { PROJECT_CREATE_DIALOG } from "../../dialog-create/dialog-project-create"; -export const projectActionSet: ContextMenuActionSet = [[{ - icon: NewProjectIcon, - name: "New project", - execute: (dispatch, resource) => { - dispatch(reset(PROJECT_CREATE_DIALOG)); - dispatch(projectActions.OPEN_PROJECT_CREATOR({ ownerUuid: resource.uuid })); +export const projectActionSet: ContextMenuActionSet = [[ + { + icon: NewProjectIcon, + name: "New project", + execute: (dispatch, resource) => { + dispatch(reset(PROJECT_CREATE_DIALOG)); + dispatch(projectActions.OPEN_PROJECT_CREATOR({ ownerUuid: resource.uuid })); + } + }, + { + icon: RenameIcon, + name: "Edit project", + execute: (dispatch, resource) => { + dispatch(projectActions.OPEN_PROJECT_UPDATER({ uuid: resource.uuid })); + dispatch(initialize(PROJECT_FORM_NAME, { name: resource.name, description: resource.description })); + } + }, + { + component: ToggleFavoriteAction, + execute: (dispatch, resource) => { + dispatch(toggleFavorite(resource)).then(() => { + dispatch(favoritePanelActions.REQUEST_ITEMS()); + }); + } } -}, { - component: ToggleFavoriteAction, - execute: (dispatch, resource) => { - dispatch(toggleFavorite(resource)).then(() => { - dispatch(favoritePanelActions.REQUEST_ITEMS()); - }); - } -}]]; +]]; diff --git a/src/views-components/dialog-create/dialog-collection-create-selected.tsx b/src/views-components/dialog-create/dialog-collection-create-selected.tsx index 0dc590ae..af2536df 100644 --- a/src/views-components/dialog-create/dialog-collection-create-selected.tsx +++ b/src/views-components/dialog-create/dialog-collection-create-selected.tsx @@ -7,7 +7,7 @@ import { InjectedFormProps, Field, WrappedFieldProps } from "redux-form"; import { Dialog, DialogTitle, DialogContent, DialogActions, Button, CircularProgress } from "@material-ui/core"; import { WithDialogProps } from "~/store/dialog/with-dialog"; import { TextField } from "~/components/text-field/text-field"; -import { COLLECTION_NAME_VALIDATION, COLLECTION_DESCRIPTION_VALIDATION, COLLECTION_PROJECT_VALIDATION } from "~/validators/create-project/create-project-validator"; +import { COLLECTION_NAME_VALIDATION, COLLECTION_DESCRIPTION_VALIDATION, COLLECTION_PROJECT_VALIDATION } from "~/validators/validators"; import { ProjectTreePicker } from "../project-tree-picker/project-tree-picker"; export const DialogCollectionCreateWithSelected = (props: WithDialogProps & InjectedFormProps<{ name: string }>) => diff --git a/src/views-components/dialog-create/dialog-collection-create.tsx b/src/views-components/dialog-create/dialog-collection-create.tsx index 7f2e411e..af0e33f1 100644 --- a/src/views-components/dialog-create/dialog-collection-create.tsx +++ b/src/views-components/dialog-create/dialog-collection-create.tsx @@ -9,13 +9,13 @@ 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-collection/create-collection-validator'; +import { COLLECTION_NAME_VALIDATION, COLLECTION_DESCRIPTION_VALIDATION } from '~/validators/validators'; 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"; +type CssRules = "button" | "lastButton" | "formContainer" | "createProgress" | "dialogActions"; const styles: StyleRulesCallback = theme => ({ button: { @@ -29,9 +29,6 @@ const styles: StyleRulesCallback = theme => ({ display: "flex", flexDirection: "column", }, - textField: { - marginBottom: theme.spacing.unit * 3 - }, createProgress: { position: "absolute", minWidth: "20px", @@ -42,10 +39,8 @@ const styles: StyleRulesCallback = theme => ({ } }); -interface DialogCollectionCreateProps { +interface DialogCollectionDataProps { open: boolean; - handleClose: () => void; - onSubmit: (data: { name: string, description: string }, files: UploadFile[]) => void; handleSubmit: any; submitting: boolean; invalid: boolean; @@ -53,6 +48,13 @@ interface DialogCollectionCreateProps { files: UploadFile[]; } +interface DialogCollectionActionProps { + handleClose: () => void; + onSubmit: (data: { name: string, description: string }, files: UploadFile[]) => void; +} + +type DialogCollectionProps = DialogCollectionDataProps & DialogCollectionActionProps & DispatchProp & WithStyles; + export const COLLECTION_CREATE_DIALOG = "collectionCreateDialog"; export const DialogCollectionCreate = compose( @@ -61,7 +63,7 @@ export const DialogCollectionCreate = compose( })), reduxForm({ form: COLLECTION_CREATE_DIALOG }), 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( @@ -82,13 +84,11 @@ export const DialogCollectionCreate = compose( disabled={submitting} component={TextField} validate={COLLECTION_NAME_VALIDATION} - className={classes.textField} label="Collection Name" /> = theme => ({ button: { @@ -29,9 +29,6 @@ const styles: StyleRulesCallback = theme => ({ dialogTitle: { paddingBottom: "0" }, - textField: { - marginTop: "32px", - }, dialog: { minWidth: "600px", minHeight: "320px" @@ -78,12 +75,10 @@ export const DialogProjectCreate = compose( diff --git a/src/views-components/dialog-update/dialog-collection-update.tsx b/src/views-components/dialog-update/dialog-collection-update.tsx index d97ff41b..18c43f2d 100644 --- a/src/views-components/dialog-update/dialog-collection-update.tsx +++ b/src/views-components/dialog-update/dialog-collection-update.tsx @@ -6,11 +6,12 @@ import * as React from 'react'; import { reduxForm, Field } from 'redux-form'; import { compose } from 'redux'; import { ArvadosTheme } from '~/common/custom-theme'; -import { Dialog, DialogActions, DialogContent, DialogTitle, TextField, StyleRulesCallback, withStyles, WithStyles, Button, CircularProgress } from '@material-ui/core'; -import { COLLECTION_NAME_VALIDATION, COLLECTION_DESCRIPTION_VALIDATION } from '~/validators/create-collection/create-collection-validator'; +import { Dialog, DialogActions, DialogContent, DialogTitle, StyleRulesCallback, withStyles, WithStyles, Button, CircularProgress } from '@material-ui/core'; +import { COLLECTION_NAME_VALIDATION, COLLECTION_DESCRIPTION_VALIDATION } from '~/validators/validators'; import { COLLECTION_FORM_NAME } from '~/store/collections/updater/collection-updater-action'; +import { TextField } from '~/components/text-field/text-field'; -type CssRules = 'content' | 'actions' | 'textField' | 'buttonWrapper' | 'saveButton' | 'circularProgress'; +type CssRules = 'content' | 'actions' | 'buttonWrapper' | 'saveButton' | 'circularProgress'; const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ content: { @@ -22,9 +23,6 @@ const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ padding: `${theme.spacing.unit}px ${theme.spacing.unit * 3 - theme.spacing.unit / 2}px ${theme.spacing.unit * 3}px ${theme.spacing.unit * 3}px` }, - textField: { - marginBottom: theme.spacing.unit * 3 - }, buttonWrapper: { position: 'relative' }, @@ -56,14 +54,6 @@ interface DialogCollectionAction { type DialogCollectionProps = DialogCollectionDataProps & DialogCollectionAction & WithStyles; -interface TextFieldProps { - label: string; - floatinglabeltext: string; - className?: string; - input?: string; - meta?: any; -} - export const DialogCollectionUpdate = compose( reduxForm({ form: COLLECTION_FORM_NAME }), withStyles(styles))( @@ -83,19 +73,15 @@ export const DialogCollectionUpdate = compose(
onSubmit(data))}> Edit Collection - - @@ -115,17 +101,5 @@ export const DialogCollectionUpdate = compose( ); } - - renderTextField = ({ input, label, meta: { touched, error }, ...custom }: TextFieldProps) => ( - - ) } ); diff --git a/src/views-components/dialog-update/dialog-project-update.tsx b/src/views-components/dialog-update/dialog-project-update.tsx new file mode 100644 index 00000000..5dde00a6 --- /dev/null +++ b/src/views-components/dialog-update/dialog-project-update.tsx @@ -0,0 +1,101 @@ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 + +import * as React from 'react'; +import { reduxForm, Field } from 'redux-form'; +import { compose } from 'redux'; +import { ArvadosTheme } from '~/common/custom-theme'; +import { StyleRulesCallback, WithStyles, withStyles, Dialog, DialogTitle, DialogContent, DialogActions, CircularProgress, Button } from '../../../node_modules/@material-ui/core'; +import { TextField } from '~/components/text-field/text-field'; +import { PROJECT_FORM_NAME } from '~/store/project/project-action'; +import { PROJECT_NAME_VALIDATION, PROJECT_DESCRIPTION_VALIDATION } from '~/validators/validators'; + +type CssRules = 'content' | 'actions' | 'buttonWrapper' | 'saveButton' | 'circularProgress'; + +const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ + content: { + display: 'flex', + flexDirection: 'column' + }, + actions: { + margin: 0, + padding: `${theme.spacing.unit}px ${theme.spacing.unit * 3 - theme.spacing.unit / 2}px + ${theme.spacing.unit * 3}px ${theme.spacing.unit * 3}px` + }, + buttonWrapper: { + position: 'relative' + }, + saveButton: { + boxShadow: 'none' + }, + circularProgress: { + position: 'absolute', + top: 0, + bottom: 0, + left: 0, + right: 0, + margin: 'auto' + } +}); + +interface DialogProjectDataProps { + open: boolean; + handleSubmit: any; + submitting: boolean; + invalid: boolean; + pristine: boolean; +} + +interface DialogProjectActionProps { + handleClose: () => void; + onSubmit: (data: { name: string, description: string }) => void; +} + +type DialogProjectProps = DialogProjectDataProps & DialogProjectActionProps & WithStyles; + +export const DialogProjectUpdate = compose( + reduxForm({ form: PROJECT_FORM_NAME }), + withStyles(styles))( + + class DialogProjectUpdate extends React.Component { + render() { + const { handleSubmit, handleClose, onSubmit, open, classes, submitting, invalid, pristine } = this.props; + return + onSubmit(data))}> + Edit Collection + + + + + + +
+ + {submitting && } +
+
+ +
; + } + } + ); diff --git a/src/views-components/update-project-dialog/update-project-dialog.tsx b/src/views-components/update-project-dialog/update-project-dialog.tsx new file mode 100644 index 00000000..c4558426 --- /dev/null +++ b/src/views-components/update-project-dialog/update-project-dialog.tsx @@ -0,0 +1,42 @@ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 + +import { connect } from "react-redux"; +import { Dispatch } from "redux"; +import { SubmissionError } from "redux-form"; +import { RootState } from "~/store/store"; +import { snackbarActions } from "~/store/snackbar/snackbar-actions"; +import { DialogProjectUpdate } from "../dialog-update/dialog-project-update"; +import { projectActions, updateProject } from "~/store/project/project-action"; + +const mapStateToProps = (state: RootState) => ({ + open: state.projects.updater.opened +}); + +const mapDispatchToProps = (dispatch: Dispatch) => ({ + handleClose: () => { + dispatch(projectActions.CLOSE_PROJECT_UPDATER()); + }, + onSubmit: (data: { name: string, description: string }) => { + return dispatch(editProject(data)) + .catch((e: any) => { + if (e.errors) { + throw new SubmissionError({ name: e.errors.join("").includes("UniqueViolation") ? "CProject with this name already exists." : "" }); + } + }); + } +}); + +const editProject = (data: { name: string, description: string }) => + (dispatch: Dispatch, getState: () => RootState) => { + const { uuid } = getState().projects.updater; + return dispatch(updateProject(data)).then(() => { + dispatch(snackbarActions.OPEN_SNACKBAR({ + message: "Project has been successfully updated.", + hideDuration: 2000 + })); + }); + }; + +export const UpdateProjectDialog = connect(mapStateToProps, mapDispatchToProps)(DialogProjectUpdate); diff --git a/src/views/collection-panel/collection-tag-form.tsx b/src/views/collection-panel/collection-tag-form.tsx index 8f254041..83ad0ca4 100644 --- a/src/views/collection-panel/collection-tag-form.tsx +++ b/src/views/collection-panel/collection-tag-form.tsx @@ -6,20 +6,15 @@ import * as React from 'react'; import { reduxForm, Field, reset } from 'redux-form'; import { compose, Dispatch } from 'redux'; import { ArvadosTheme } from '~/common/custom-theme'; -import { StyleRulesCallback, withStyles, WithStyles, TextField, Button, CircularProgress } from '@material-ui/core'; +import { StyleRulesCallback, withStyles, WithStyles, Button, CircularProgress, Grid } from '@material-ui/core'; import { TagProperty } from '~/models/tag'; +import { TextField } from '~/components/text-field/text-field'; import { createCollectionTag, COLLECTION_TAG_FORM_NAME } from '~/store/collection-panel/collection-panel-action'; import { TAG_VALUE_VALIDATION, TAG_KEY_VALIDATION } from '~/validators/validators'; -type CssRules = 'form' | 'textField' | 'buttonWrapper' | 'saveButton' | 'circularProgress'; +type CssRules = 'buttonWrapper' | 'saveButton' | 'circularProgress'; const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ - form: { - marginBottom: theme.spacing.unit * 4 - }, - textField: { - marginRight: theme.spacing.unit - }, buttonWrapper: { position: 'relative', display: 'inline-block' @@ -47,14 +42,6 @@ interface CollectionTagFormActionProps { handleSubmit: any; } -interface TextFieldProps { - label: string; - floatinglabeltext: string; - className?: string; - input?: string; - meta?: any; -} - type CollectionTagFormProps = CollectionTagFormDataProps & CollectionTagFormActionProps & WithStyles; export const CollectionTagForm = compose( @@ -67,52 +54,41 @@ export const CollectionTagForm = compose( }), withStyles(styles))( - class CollectionTagForm extends React.Component { + class CollectionTagForm extends React.Component { render() { const { classes, submitting, pristine, invalid, handleSubmit } = this.props; return ( -
- - -
- - {submitting && } -
+ + + + + + + + + + + {submitting && } + + ); } - - renderTextField = ({ input, label, meta: { touched, error }, ...custom }: TextFieldProps) => ( - - ) - } ); diff --git a/src/views/workbench/workbench.tsx b/src/views/workbench/workbench.tsx index a0be3729..a38afb7a 100644 --- a/src/views/workbench/workbench.tsx +++ b/src/views/workbench/workbench.tsx @@ -42,6 +42,7 @@ import { CollectionPanel } from '../collection-panel/collection-panel'; import { loadCollection, loadCollectionTags } from '~/store/collection-panel/collection-panel-action'; import { getCollectionUrl } from '~/models/collection'; import { UpdateCollectionDialog } from '~/views-components/update-collection-dialog/update-collection-dialog.'; +import { UpdateProjectDialog } from '~/views-components/update-project-dialog/update-project-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'; @@ -245,6 +246,7 @@ export const Workbench = withStyles(styles)( +