--- /dev/null
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import * as React from "react";
+import { InjectedFormProps, Field } from "redux-form";
+import { Dialog, DialogTitle, DialogContent, DialogActions, Button, Typography, DialogContentText, CircularProgress } from "@material-ui/core";
+import { WithDialogProps } from "../../store/dialog/with-dialog";
+import { TextField } from "../text-field/text-field";
+
+export const RenameDialog = (props: WithDialogProps<string> & InjectedFormProps<{ name: string }>) =>
+ <form>
+ <Dialog open={props.open}>
+ <DialogTitle>{`Rename`}</DialogTitle>
+ <DialogContent>
+ <DialogContentText>
+ {`Please, enter a new name for ${props.data}`}
+ </DialogContentText>
+ <Field
+ name='name'
+ component={TextField}
+ />
+ </DialogContent>
+ <DialogActions>
+ <Button
+ variant='flat'
+ color='primary'
+ disabled={props.submitting}
+ onClick={props.closeDialog}>
+ Cancel
+ </Button>
+ <Button
+ variant='contained'
+ color='primary'
+ type='submit'
+ onClick={props.handleSubmit}
+ disabled={props.pristine || props.invalid || props.submitting}>
+ {props.submitting
+ ? <CircularProgress size={20} />
+ : 'Ok'}
+ </Button>
+ </DialogActions>
+ </Dialog>
+ </form>;
--- /dev/null
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import * as React from 'react';
+import { WrappedFieldProps } from 'redux-form';
+import { ArvadosTheme } from '../../common/custom-theme';
+import { TextField as MaterialTextField, StyleRulesCallback, WithStyles, withStyles } from '../../../node_modules/@material-ui/core';
+
+type CssRules = 'textField';
+
+const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
+ textField: {
+ marginBottom: theme.spacing.unit * 3
+ },
+});
+
+export const TextField = withStyles(styles)((props: WrappedFieldProps & WithStyles<CssRules> & { label?: string }) =>
+ <MaterialTextField
+ helperText={props.meta.touched && props.meta.error}
+ className={props.classes.textField}
+ label={props.label}
+ disabled={props.meta.submitting}
+ error={props.meta.touched && !!props.meta.error}
+ autoComplete='off'
+ fullWidth={true}
+ {...props.input}
+ />);
\ No newline at end of file
import { Dispatch } from 'redux';
import { dialogActions } from './dialog-actions';
-export type WithDialog<T> = {
+export type WithDialogStateProps<T> = {
open: boolean;
data?: T;
};
-export type WithDialogActions = {
+export type WithDialogDispatchProps = {
closeDialog: () => void;
};
+export type WithDialogProps<T> = WithDialogStateProps<T> & WithDialogDispatchProps;
+
export const withDialog = (id: string) =>
- <T>(component: React.ComponentType<WithDialog<T> & WithDialogActions>) =>
+ <T, P>(component: React.ComponentType<WithDialogProps<T> & P>) =>
connect(mapStateToProps(id), mapDispatchToProps(id))(component);
-export const mapStateToProps = (id: string) => <T>(state: { dialog: DialogState }): WithDialog<T> => {
+export const mapStateToProps = (id: string) => <T>(state: { dialog: DialogState }): WithDialogStateProps<T> => {
const dialog = state.dialog[id];
return dialog ? dialog : { open: false };
};
-export const mapDispatchToProps = (id: string) => (dispatch: Dispatch): WithDialogActions => ({
+export const mapDispatchToProps = (id: string) => (dispatch: Dispatch): WithDialogDispatchProps => ({
closeDialog: () => {
dispatch(dialogActions.CLOSE_DIALOG({ id }));
}
import { ContextMenuActionSet } from "../context-menu-action-set";
import { RenameIcon, DownloadIcon, RemoveIcon } from "../../../components/icon/icon";
import { openRemoveDialog } from "../../remove-dialog/remove-dialog";
-import { openRenameDialog } from "../../rename-dialog/rename-dialog";
+import { openRenameFileDialog } from "../../rename-file-dialog/rename-file-dialog";
export const collectionFilesItemActionSet: ContextMenuActionSet = [[{
name: "Rename",
icon: RenameIcon,
execute: (dispatch, resource) => {
- dispatch(openRenameDialog('the item'));
+ dispatch(openRenameFileDialog(resource.name));
}
},{
name: "Download",
+++ /dev/null
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-
-import * as React from "react";
-import { Dialog, DialogTitle, DialogContent, DialogActions, Button, TextField, Typography } from "@material-ui/core";
-import { withDialog } from "../../store/dialog/with-dialog";
-import { dialogActions } from "../../store/dialog/dialog-actions";
-
-export const RENAME_DIALOG = 'nameDialog';
-
-export const RenameDialog = withDialog(RENAME_DIALOG)(
- (props) =>
- <Dialog open={props.open}>
- <DialogTitle>{`Rename`}</DialogTitle>
- <DialogContent>
- <Typography variant='body1' gutterBottom>
- {`Please, enter a new name for ${props.data}`}
- </Typography>
- <TextField fullWidth={true} placeholder='New name' />
- </DialogContent>
- <DialogActions>
- <Button
- variant='flat'
- color='primary'
- onClick={props.closeDialog}>
- Cancel
- </Button>
- <Button variant='raised' color='primary'>
- Ok
- </Button>
- </DialogActions>
- </Dialog>
-);
-
-export const openRenameDialog = (originalName: string, ) =>
- dialogActions.OPEN_DIALOG({ id: RENAME_DIALOG, data: originalName });
--- /dev/null
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { reduxForm, startSubmit, stopSubmit } from "redux-form";
+import { withDialog } from "../../store/dialog/with-dialog";
+import { dialogActions } from "../../store/dialog/dialog-actions";
+import { RenameDialog } from "../../components/rename-dialog/rename-dialog";
+
+export const RENAME_FILE_DIALOG = 'renameFileDialog';
+
+export const openRenameFileDialog = (originalName: string, ) =>
+ dialogActions.OPEN_DIALOG({ id: RENAME_FILE_DIALOG, data: originalName });
+
+export const [RenameFileDialog] = [RenameDialog]
+ .map(withDialog(RENAME_FILE_DIALOG))
+ .map(reduxForm({
+ form: RENAME_FILE_DIALOG,
+ onSubmit: (data, dispatch) => {
+ dispatch(startSubmit(RENAME_FILE_DIALOG));
+ // TODO: call collection file renaming action here
+ setTimeout(() => dispatch(stopSubmit(RENAME_FILE_DIALOG, { name: 'Invalid name' })), 2000);
+ }
+ }));
import { loadCollection } 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';
const DRAWER_WITDH = 240;
const APP_BAR_HEIGHT = 100;
<CreateProjectDialog />
<CreateCollectionDialog />
<RemoveDialog />
- <RenameDialog />
+ <RenameFileDialog />
<UpdateCollectionDialog />
<CurrentTokenDialog
currentToken={this.props.currentToken}