"@material-ui/icons": "2.0.0",
"@types/lodash": "4.14.116",
"@types/react-copy-to-clipboard": "4.2.5",
+ "@types/react-dropzone": "4.2.1",
"@types/redux-form": "7.4.4",
"axios": "0.18.0",
"classnames": "2.2.6",
"react": "16.4.2",
"react-copy-to-clipboard": "5.0.1",
"react-dom": "16.4.2",
+ "react-dropzone": "4.2.13",
"react-redux": "5.0.7",
"react-router": "4.3.1",
"react-router-dom": "4.3.1",
--- /dev/null
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import * as React from 'react';
+import { Grid, StyleRulesCallback, Typography, WithStyles } from '@material-ui/core';
+import { withStyles } from '@material-ui/core';
+import Dropzone from 'react-dropzone';
+import { CloudUploadIcon } from "../icon/icon";
+
+type CssRules = "root" | "dropzone" | "container" | "uploadIcon";
+
+const styles: StyleRulesCallback<CssRules> = theme => ({
+ root: {
+ },
+ dropzone: {
+ width: "100%",
+ height: "100px",
+ border: "1px dashed black",
+ borderRadius: "5px"
+ },
+ container: {
+ height: "100%"
+ },
+ uploadIcon: {
+ verticalAlign: "middle"
+ }
+});
+
+interface FileUploadProps {
+}
+
+export const FileUpload = withStyles(styles)(
+ ({ classes }: FileUploadProps & WithStyles<CssRules>) =>
+ <Grid container direction={"column"}>
+ <Typography variant={"subheading"}>
+ Upload data
+ </Typography>
+ <Dropzone className={classes.dropzone}>
+ <Grid container justify="center" alignItems="center" className={classes.container}>
+ <Grid item component={"span"}>
+ <Typography variant={"subheading"}>
+ <CloudUploadIcon className={classes.uploadIcon}/> Drag and drop data or <a>browse</a>
+ </Typography>
+ </Grid>
+ </Grid>
+ </Dropzone>
+ </Grid>
+);
import ArrowDropDown from '@material-ui/icons/ArrowDropDown';
import BubbleChart from '@material-ui/icons/BubbleChart';
import Cached from '@material-ui/icons/Cached';
+import CloudUpload from '@material-ui/icons/CloudUpload';
import Code from '@material-ui/icons/Code';
import ChevronLeft from '@material-ui/icons/ChevronLeft';
import ChevronRight from '@material-ui/icons/ChevronRight';
export const CopyIcon: IconType = (props) => <ContentCopy {...props} />;
export const CollectionIcon: IconType = (props) => <LibraryBooks {...props} />;
export const CloseIcon: IconType = (props) => <Close {...props} />;
+export const CloudUploadIcon: IconType = (props) => <CloudUpload {...props} />;
export const DefaultIcon: IconType = (props) => <RateReview {...props} />;
export const DetailsIcon: IconType = (props) => <Info {...props} />;
export const DownloadIcon: IconType = (props) => <GetApp {...props} />;
import { combineReducers } from 'redux';
import * as creator from "./creator/collection-creator-reducer";
-import * as updator from "./updator/collection-updator-reducer";
+import * as updater from "./updater/collection-updater-reducer";
export type CollectionsState = {
creator: creator.CollectionCreatorState;
- updator: updator.CollectionUpdatorState;
+ updater: updater.CollectionUpdaterState;
};
export const collectionsReducer = combineReducers({
- creator: creator.collectionCreationReducer,
- updator: updator.collectionCreationReducer
-});
\ No newline at end of file
+ creator: creator.collectionCreatorReducer,
+ updater: updater.collectionUpdaterReducer
+});
CREATE_COLLECTION: ofType<{}>(),
CREATE_COLLECTION_SUCCESS: ofType<{}>(),
}, {
- tag: 'type',
- value: 'payload'
- });
+ tag: 'type',
+ value: 'payload'
+});
export const createCollection = (collection: Partial<CollectionResource>) =>
(dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
//
// SPDX-License-Identifier: AGPL-3.0
-import { collectionCreationReducer } from "./collection-creator-reducer";
+import { collectionCreatorReducer } from "./collection-creator-reducer";
import { collectionCreateActions } from "./collection-creator-action";
describe('collection-reducer', () => {
const initialState = { opened: false, ownerUuid: "" };
const collection = { opened: true, ownerUuid: "" };
- const state = collectionCreationReducer(initialState, collectionCreateActions.OPEN_COLLECTION_CREATOR(initialState));
+ const state = collectionCreatorReducer(initialState, collectionCreateActions.OPEN_COLLECTION_CREATOR(initialState));
expect(state).toEqual(collection);
});
const initialState = { opened: true, ownerUuid: "" };
const collection = { opened: false, ownerUuid: "" };
- const state = collectionCreationReducer(initialState, collectionCreateActions.CLOSE_COLLECTION_CREATOR());
+ const state = collectionCreatorReducer(initialState, collectionCreateActions.CLOSE_COLLECTION_CREATOR());
expect(state).toEqual(collection);
});
const initialState = { opened: true, ownerUuid: "test" };
const collection = { opened: false, ownerUuid: "" };
- const state = collectionCreationReducer(initialState, collectionCreateActions.CREATE_COLLECTION_SUCCESS());
+ const state = collectionCreatorReducer(initialState, collectionCreateActions.CREATE_COLLECTION_SUCCESS());
expect(state).toEqual(collection);
});
-});
\ No newline at end of file
+});
ownerUuid: ''
};
-export const collectionCreationReducer = (state: CollectionCreatorState = initialState, action: CollectionCreateAction) => {
+export const collectionCreatorReducer = (state: CollectionCreatorState = initialState, action: CollectionCreateAction) => {
return collectionCreateActions.match(action, {
OPEN_COLLECTION_CREATOR: ({ ownerUuid }) => updateCreator(state, { ownerUuid, opened: true }),
CLOSE_COLLECTION_CREATOR: () => updateCreator(state, { opened: false }),
import { initialize } from 'redux-form';
import { collectionPanelActions } from "../../collection-panel/collection-panel-action";
-export const collectionUpdatorActions = unionize({
- OPEN_COLLECTION_UPDATOR: ofType<{ uuid: string }>(),
- CLOSE_COLLECTION_UPDATOR: ofType<{}>(),
+export const collectionUpdaterActions = unionize({
+ OPEN_COLLECTION_UPDATER: ofType<{ uuid: string }>(),
+ CLOSE_COLLECTION_UPDATER: ofType<{}>(),
UPDATE_COLLECTION_SUCCESS: ofType<{}>(),
}, {
- tag: 'type',
- value: 'payload'
- });
+ tag: 'type',
+ value: 'payload'
+});
export const COLLECTION_FORM_NAME = 'collectionEditDialog';
-
-export const openUpdator = (uuid: string) =>
+
+export const openUpdater = (uuid: string) =>
(dispatch: Dispatch, getState: () => RootState) => {
- dispatch(collectionUpdatorActions.OPEN_COLLECTION_UPDATOR({ uuid }));
+ dispatch(collectionUpdaterActions.OPEN_COLLECTION_UPDATER({ uuid }));
const item = getState().collectionPanel.item;
if(item) {
dispatch(initialize(COLLECTION_FORM_NAME, { name: item.name, description: item.description }));
export const updateCollection = (collection: Partial<CollectionResource>) =>
(dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
- const { uuid } = getState().collections.updator;
+ const { uuid } = getState().collections.updater;
return services.collectionService
.update(uuid, collection)
.then(collection => {
dispatch(collectionPanelActions.LOAD_COLLECTION_SUCCESS({ item: collection as CollectionResource }));
- dispatch(collectionUpdatorActions.UPDATE_COLLECTION_SUCCESS());
+ dispatch(collectionUpdaterActions.UPDATE_COLLECTION_SUCCESS());
}
);
};
-export type CollectionUpdatorAction = UnionOf<typeof collectionUpdatorActions>;
\ No newline at end of file
+export type CollectionUpdaterAction = UnionOf<typeof collectionUpdaterActions>;
--- /dev/null
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { collectionUpdaterActions, CollectionUpdaterAction } from './collection-updater-action';
+
+export interface CollectionUpdaterState {
+ opened: boolean;
+ uuid: string;
+}
+
+const updateCollection = (state: CollectionUpdaterState, updater?: Partial<CollectionUpdaterState>) => ({
+ ...state,
+ ...updater
+});
+
+const initialState: CollectionUpdaterState = {
+ opened: false,
+ uuid: ''
+};
+
+export const collectionUpdaterReducer = (state: CollectionUpdaterState = initialState, action: CollectionUpdaterAction) => {
+ return collectionUpdaterActions.match(action, {
+ OPEN_COLLECTION_UPDATER: ({ uuid }) => updateCollection(state, { uuid, opened: true }),
+ CLOSE_COLLECTION_UPDATER: () => updateCollection(state, { opened: false }),
+ UPDATE_COLLECTION_SUCCESS: () => updateCollection(state, { opened: false, uuid: "" }),
+ default: () => state
+ });
+};
+++ /dev/null
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-
-import { collectionUpdatorActions, CollectionUpdatorAction } from './collection-updator-action';
-
-export type CollectionUpdatorState = CollectionUpdator;
-
-interface CollectionUpdator {
- opened: boolean;
- uuid: string;
-}
-
-const updateCollection = (state: CollectionUpdatorState, updator?: Partial<CollectionUpdator>) => ({
- ...state,
- ...updator
-});
-
-const initialState: CollectionUpdatorState = {
- opened: false,
- uuid: ''
-};
-
-export const collectionCreationReducer = (state: CollectionUpdatorState = initialState, action: CollectionUpdatorAction) => {
- return collectionUpdatorActions.match(action, {
- OPEN_COLLECTION_UPDATOR: ({ uuid }) => updateCollection(state, { uuid, opened: true }),
- CLOSE_COLLECTION_UPDATOR: () => updateCollection(state, { opened: false }),
- UPDATE_COLLECTION_SUCCESS: () => updateCollection(state, { opened: false, uuid: "" }),
- default: () => state
- });
-};
import { ToggleFavoriteAction } from "../actions/favorite-action";
import { toggleFavorite } from "../../../store/favorites/favorites-actions";
import { RenameIcon, ShareIcon, MoveToIcon, CopyIcon, DetailsIcon, ProvenanceGraphIcon, AdvancedIcon, RemoveIcon } from "../../../components/icon/icon";
-import { openUpdator } from "../../../store/collections/updator/collection-updator-action";
+import { openUpdater } from "../../../store/collections/updater/collection-updater-action";
import { favoritePanelActions } from "../../../store/favorite-panel/favorite-panel-action";
export const collectionActionSet: ContextMenuActionSet = [[
icon: RenameIcon,
name: "Edit collection",
execute: (dispatch, resource) => {
- dispatch<any>(openUpdator(resource.uuid));
+ dispatch<any>(openUpdater(resource.uuid));
}
},
{
component: ToggleFavoriteAction,
execute: (dispatch, resource) => {
dispatch<any>(toggleFavorite(resource)).then(() => {
- dispatch<any>(favoritePanelActions.REQUEST_ITEMS());
+ dispatch<any>(favoritePanelActions.REQUEST_ITEMS());
});
}
},
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 { FileUpload } from "../../components/file-upload/file-upload";
type CssRules = "button" | "lastButton" | "formContainer" | "textField" | "createProgress" | "dialogActions";
validate={COLLECTION_DESCRIPTION_VALIDATION}
className={classes.textField}
label="Description - optional"/>
+ <FileUpload/>
</DialogContent>
<DialogActions className={classes.dialogActions}>
<Button onClick={handleClose} className={classes.button} color="primary"
import { ArvadosTheme } from '../../common/custom-theme';
import { Dialog, DialogActions, DialogContent, DialogTitle, TextField, StyleRulesCallback, withStyles, WithStyles, Button, CircularProgress } from '../../../node_modules/@material-ui/core';
import { COLLECTION_NAME_VALIDATION, COLLECTION_DESCRIPTION_VALIDATION } from '../../validators/create-project/create-project-validator';
-import { COLLECTION_FORM_NAME } from '../../store/collections/updator/collection-updator-action';
+import { COLLECTION_FORM_NAME } from '../../store/collections/updater/collection-updater-action';
type CssRules = 'content' | 'actions' | 'textField' | 'buttonWrapper' | 'saveButton' | 'circularProgress';
/>
)
}
- );
\ No newline at end of file
+ );
import { SubmissionError } from "redux-form";
import { RootState } from "../../store/store";
import { snackbarActions } from "../../store/snackbar/snackbar-actions";
-import { collectionUpdatorActions, updateCollection } from "../../store/collections/updator/collection-updator-action";
+import { collectionUpdaterActions, updateCollection } from "../../store/collections/updater/collection-updater-action";
import { dataExplorerActions } from "../../store/data-explorer/data-explorer-action";
import { PROJECT_PANEL_ID } from "../../views/project-panel/project-panel";
import { DialogCollectionUpdate } from "../dialog-update/dialog-collection-update";
const mapStateToProps = (state: RootState) => ({
- open: state.collections.updator.opened
+ open: state.collections.updater.opened
});
const mapDispatchToProps = (dispatch: Dispatch) => ({
handleClose: () => {
- dispatch(collectionUpdatorActions.CLOSE_COLLECTION_UPDATOR());
+ dispatch(collectionUpdaterActions.CLOSE_COLLECTION_UPDATER());
},
onSubmit: (data: { name: string, description: string }) => {
return dispatch<any>(editCollection(data))
});
};
-export const UpdateCollectionDialog = connect(mapStateToProps, mapDispatchToProps)(DialogCollectionUpdate);
\ No newline at end of file
+export const UpdateCollectionDialog = connect(mapStateToProps, mapDispatchToProps)(DialogCollectionUpdate);
"@types/node" "*"
"@types/react" "*"
+"@types/react-dropzone@4.2.1":
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/@types/react-dropzone/-/react-dropzone-4.2.1.tgz#4a973b63a8a227e263ff4eece053f643220f28fc"
+ dependencies:
+ "@types/react" "*"
+
"@types/react-redux@6.0.6":
version "6.0.6"
resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-6.0.6.tgz#87f1d0a6ea901b93fcaf95fa57641ff64079d277"
version "2.1.1"
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.1.tgz#ae2d5a729477f289d60dd7f96a6314a22dd6c22a"
+attr-accept@^1.0.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/attr-accept/-/attr-accept-1.1.3.tgz#48230c79f93790ef2775fcec4f0db0f5db41ca52"
+ dependencies:
+ core-js "^2.5.0"
+
autoprefixer@7.1.6:
version "7.1.6"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-7.1.6.tgz#fb933039f74af74a83e71225ce78d9fd58ba84d7"
object-assign "^4.1.1"
prop-types "^15.6.0"
+react-dropzone@4.2.13:
+ version "4.2.13"
+ resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-4.2.13.tgz#31393c079b4e5ddcc176c095cebc3545d1248b9d"
+ dependencies:
+ attr-accept "^1.0.3"
+ prop-types "^15.5.7"
+
react-error-overlay@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-4.0.0.tgz#d198408a85b4070937a98667f500c832f86bd5d4"