}
});
- export const COLLECTION_PARTIAL_COPY_FORM_NAME = 'collectionPartialCopyFormName';
-
- export interface CollectionPartialCopyFormData {
- name: string;
- description: string;
- projectUuid: string;
- }
-
- export const openCollectionPartialCopyDialog = () =>
- (dispatch: Dispatch, getState: () => RootState) => {
- const currentCollection = getState().collectionPanel.item;
- if (currentCollection) {
- const initialData = {
- name: currentCollection.name,
- description: currentCollection.description,
- projectUuid: ''
- };
- dispatch(initialize(COLLECTION_PARTIAL_COPY_FORM_NAME, initialData));
- dispatch<any>(resetPickerProjectTree());
- dispatch(dialogActions.OPEN_DIALOG({ id: COLLECTION_PARTIAL_COPY_FORM_NAME, data: {} }));
- }
- };
-
--
- export const copyCollectionPartial = ({ name, description, projectUuid }: CollectionPartialCopyFormData) =>
- async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
- dispatch(startSubmit(COLLECTION_PARTIAL_COPY_FORM_NAME));
- const state = getState();
- const currentCollection = state.collectionPanel.item;
- if (currentCollection) {
- try {
- const collection = await services.collectionService.get(currentCollection.uuid);
- const collectionCopy = {
- ...collection,
- name,
- description,
- ownerUuid: projectUuid,
- uuid: undefined
- };
- const newCollection = await services.collectionService.create(collectionCopy);
- const paths = filterCollectionFilesBySelection(state.collectionPanelFiles, false).map(file => file.id);
- await services.collectionService.deleteFiles(newCollection.uuid, paths);
- dispatch(dialogActions.CLOSE_DIALOG({ id: COLLECTION_PARTIAL_COPY_FORM_NAME }));
- dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'New collection created.', hideDuration: 2000 }));
- } catch (e) {
- const error = getCommonResourceServiceError(e);
- if (error === CommonResourceServiceError.UNIQUE_VIOLATION) {
- dispatch(stopSubmit(COLLECTION_PARTIAL_COPY_FORM_NAME, { name: 'Collection with this name already exists.' }));
- } else if (error === CommonResourceServiceError.UNKNOWN) {
- dispatch(dialogActions.CLOSE_DIALOG({ id: COLLECTION_PARTIAL_COPY_FORM_NAME }));
- dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Could not create a copy of collection', hideDuration: 2000 }));
- } else {
- dispatch(dialogActions.CLOSE_DIALOG({ id: COLLECTION_PARTIAL_COPY_FORM_NAME }));
- dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Collection has been copied but may contain incorrect files.', hideDuration: 2000 }));
- }
- }
- }
- };
--
export const RENAME_FILE_DIALOG = 'renameFileDialog';
export interface RenameFileDialogData {
name: string;
--- /dev/null
-export const doCollectionPartialCopy = ({ name, description, projectUuid }: CollectionPartialCopyFormData) =>
+ // Copyright (C) The Arvados Authors. All rights reserved.
+ //
+ // SPDX-License-Identifier: AGPL-3.0
+
+ import { Dispatch } from 'redux';
+ import { RootState } from '~/store/store';
+ import { initialize, startSubmit, stopSubmit } from 'redux-form';
+ import { resetPickerProjectTree } from '~/store/project-tree-picker/project-tree-picker-actions';
+ import { dialogActions } from '~/store/dialog/dialog-actions';
+ import { ServiceRepository } from '~/services/services';
+ import { filterCollectionFilesBySelection } from '../collection-panel/collection-panel-files/collection-panel-files-state';
+ import { snackbarActions } from '~/store/snackbar/snackbar-actions';
+ import { getCommonResourceServiceError, CommonResourceServiceError } from '~/common/api/common-resource-service';
+
+ export const COLLECTION_PARTIAL_COPY_FORM_NAME = 'COLLECTION_PARTIAL_COPY_DIALOG';
+
+ export interface CollectionPartialCopyFormData {
+ name: string;
+ description: string;
+ projectUuid: string;
+ }
+
+ export const openCollectionPartialCopyDialog = () =>
+ (dispatch: Dispatch, getState: () => RootState) => {
+ const currentCollection = getState().collectionPanel.item;
+ if (currentCollection) {
+ const initialData = {
+ name: currentCollection.name,
+ description: currentCollection.description,
+ projectUuid: ''
+ };
+ dispatch(initialize(COLLECTION_PARTIAL_COPY_FORM_NAME, initialData));
+ dispatch<any>(resetPickerProjectTree());
+ dispatch(dialogActions.OPEN_DIALOG({ id: COLLECTION_PARTIAL_COPY_FORM_NAME, data: {} }));
+ }
+ };
+
++export const copyCollectionPartial = ({ name, description, projectUuid }: CollectionPartialCopyFormData) =>
+ async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+ dispatch(startSubmit(COLLECTION_PARTIAL_COPY_FORM_NAME));
+ const state = getState();
+ const currentCollection = state.collectionPanel.item;
+ if (currentCollection) {
+ try {
+ const collection = await services.collectionService.get(currentCollection.uuid);
+ const collectionCopy = {
+ ...collection,
+ name,
+ description,
+ ownerUuid: projectUuid,
+ uuid: undefined
+ };
+ const newCollection = await services.collectionService.create(collectionCopy);
+ const paths = filterCollectionFilesBySelection(state.collectionPanelFiles, false).map(file => file.id);
+ await services.collectionService.deleteFiles(newCollection.uuid, paths);
+ dispatch(dialogActions.CLOSE_DIALOG({ id: COLLECTION_PARTIAL_COPY_FORM_NAME }));
+ dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'New collection created.', hideDuration: 2000 }));
+ } catch (e) {
+ const error = getCommonResourceServiceError(e);
+ if (error === CommonResourceServiceError.UNIQUE_VIOLATION) {
+ dispatch(stopSubmit(COLLECTION_PARTIAL_COPY_FORM_NAME, { name: 'Collection with this name already exists.' }));
+ } else if (error === CommonResourceServiceError.UNKNOWN) {
+ dispatch(dialogActions.CLOSE_DIALOG({ id: COLLECTION_PARTIAL_COPY_FORM_NAME }));
+ dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Could not create a copy of collection', hideDuration: 2000 }));
+ } else {
+ dispatch(dialogActions.CLOSE_DIALOG({ id: COLLECTION_PARTIAL_COPY_FORM_NAME }));
+ dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Collection has been copied but may contain incorrect files.', hideDuration: 2000 }));
+ }
+ }
+ }
+ };
--- /dev/null
-import { DialogCollectionFilesUpload } from '../dialog-upload/dialog-collection-files-upload';
+ // Copyright (C) The Arvados Authors. All rights reserved.
+ //
+ // SPDX-License-Identifier: AGPL-3.0
+
+ import { compose } from "redux";
+ import { reduxForm } from 'redux-form';
+ import { withDialog } from "~/store/dialog/with-dialog";
+ import { CollectionCreateFormDialogData } from '~/store/collections/collection-create-actions';
+ import { COLLECTION_UPLOAD_FILES_DIALOG, submitCollectionFiles } from '~/store/collections/collection-upload-actions';
-export const UploadCollectionFilesDialog = compose(
++import { DialogCollectionFilesUpload } from '~/views-components/dialog-upload/dialog-collection-files-upload';
+
++export const FilesUploadCollectionDialog = compose(
+ withDialog(COLLECTION_UPLOAD_FILES_DIALOG),
+ reduxForm<CollectionCreateFormDialogData>({
+ form: COLLECTION_UPLOAD_FILES_DIALOG,
+ onSubmit: (data, dispatch) => {
+ dispatch(submitCollectionFiles());
+ }
+ })
+ )(DialogCollectionFilesUpload);
--- /dev/null
-import { CollectionPartialCopyFormData, doCollectionPartialCopy, COLLECTION_PARTIAL_COPY_FORM_NAME } from '~/store/collections/collection-partial-copy-actions';
+ // Copyright (C) The Arvados Authors. All rights reserved.
+ //
+ // SPDX-License-Identifier: AGPL-3.0
+
+ import { compose } from "redux";
+ import { reduxForm } from 'redux-form';
+ import { withDialog, } from '~/store/dialog/with-dialog';
- reduxForm({
++import { CollectionPartialCopyFormData, copyCollectionPartial, COLLECTION_PARTIAL_COPY_FORM_NAME } from '~/store/collections/collection-partial-copy-actions';
+ import { DialogCollectionPartialCopy } from "~/views-components/dialog-copy/dialog-collection-partial-copy";
+
+
+ export const PartialCopyCollectionDialog = compose(
+ withDialog(COLLECTION_PARTIAL_COPY_FORM_NAME),
- onSubmit: (data: CollectionPartialCopyFormData, dispatch) => {
- dispatch(doCollectionPartialCopy(data));
++ reduxForm<CollectionPartialCopyFormData>({
+ form: COLLECTION_PARTIAL_COPY_FORM_NAME,
++ onSubmit: (data, dispatch) => {
++ dispatch(copyCollectionPartial(data));
+ }
+ }))(DialogCollectionPartialCopy);
// SPDX-License-Identifier: AGPL-3.0
import * as React from 'react';
- import {
- StyleRulesCallback, WithStyles, withStyles, Card,
- CardHeader, IconButton, CardContent, Grid, Chip
- } from '@material-ui/core';
- import { ArvadosTheme } from '~/common/custom-theme';
- import { ProcessResource } from '~/models/process';
- import { DispatchProp, connect } from 'react-redux';
- import { RouteComponentProps } from 'react-router';
- import { MoreOptionsIcon, ProcessIcon } from '~/components/icon/icon';
- import { DetailsAttribute } from '~/components/details-attribute/details-attribute';
- import { RootState } from '~/store/store';
- import { ContextMenuKind } from '~/views-components/context-menu/context-menu';
- import { openContextMenu } from '~/store/context-menu/context-menu-actions';
-import { ProcessInformationCard } from '~/views/process-panel/information-card';
+ import { Grid } from '@material-ui/core';
++import { ProcessInformationCard } from '~/views/process-panel/information-card';
+import { SubprocessesCard } from '~/views/process-panel/subprocesses-card';
- type CssRules = 'card' | 'iconHeader' | 'label' | 'value' | 'content' | 'chip' | 'headerText' | 'link';
-
- const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
- card: {
- marginBottom: theme.spacing.unit * 2,
- width: '60%'
- },
- iconHeader: {
- fontSize: '1.875rem',
- color: theme.customs.colors.green700
- },
- label: {
- fontSize: '0.875rem',
- },
- value: {
- textTransform: 'none',
- fontSize: '0.875rem'
- },
- content: {
- display: 'flex',
- paddingBottom: '0px ',
- paddingTop: '0px',
- '&:last-child': {
- paddingBottom: '0px ',
- }
- },
- link: {
- fontSize: '0.875rem',
- '&:hover': {
- color: theme.palette.primary.main,
- cursor: 'pointer'
- }
- },
- chip: {
- height: theme.spacing.unit * 2.5,
- width: theme.spacing.unit * 12,
- backgroundColor: theme.customs.colors.green700,
- color: theme.palette.common.white,
- fontSize: '0.875rem',
- borderRadius: theme.spacing.unit * 0.625
- },
- headerText: {
- fontSize: '0.875rem',
- display: 'flex',
- position: 'relative',
- justifyContent: 'flex-start',
- top: -theme.spacing.unit * 4.5,
- left: theme.spacing.unit * 3,
+ export class ProcessPanel extends React.Component {
+ render() {
+ return <div>
- <Grid container>
++ <Grid container spacing={16}>
+ <Grid item xs={7}>
+ <ProcessInformationCard />
+ </Grid>
++ <Grid item xs={5}>
++ <SubprocessesCard />
++ </Grid>
+ </Grid>
+ </div>;
}
- });
-
- interface ProcessPanelDataProps {
- item: ProcessResource;
--}
-
- interface ProcessPanelActionProps {
- onContextMenu: (event: React.MouseEvent<HTMLElement>, item: ProcessResource) => void;
+}
-
- type ProcessPanelProps = ProcessPanelDataProps & ProcessPanelActionProps & DispatchProp & WithStyles<CssRules> & RouteComponentProps<{ id: string }>;
-
- export const ProcessPanel = withStyles(styles)(
- connect((state: RootState) => ({
- item: state.collectionPanel.item,
- tags: state.collectionPanel.tags
- }))(
- class extends React.Component<ProcessPanelProps> {
- render() {
- const { classes } = this.props;
-
- return <div>
- <Card className={classes.card}>
- <CardHeader
- avatar={<ProcessIcon className={classes.iconHeader} />}
- action={
- <IconButton
- aria-label="More options"
- onClick={this.handleContextMenu}>
- <MoreOptionsIcon />
- </IconButton>
- }
- title="Pipeline template that generates a config file from a template" />
- <CardContent className={classes.content}>
- <Grid container direction="column">
- <Grid item xs={8}>
- <DetailsAttribute classLabel={classes.label} classValue={classes.value}
- label='Status' value={<Chip label="Complete" className={classes.chip} />} />
- <DetailsAttribute classLabel={classes.label} classValue={classes.value}
- label='Started at' value="1:25 PM 3/23/2018" />
- <DetailsAttribute classLabel={classes.label} classValue={classes.value}
- label='Finished at' value='1:25 PM 3/23/2018' />
- </Grid>
- </Grid>
- <Grid container direction="column">
- <Grid item xs={8}>
- <DetailsAttribute classLabel={classes.link} classValue={classes.value}
- label='Container output' />
- <DetailsAttribute classLabel={classes.link} classValue={classes.value}
- label='Show inputs' />
- <DetailsAttribute classLabel={classes.link} classValue={classes.value}
- label='Show command' />
- </Grid>
- </Grid>
- </CardContent>
- <span className={classes.headerText}>This container request was created from the workflow FastQC MultiQC</span>
- </Card>
- <SubprocessesCard />
- </div>;
- }
-
- handleContextMenu = (event: React.MouseEvent<any>) => {
- // const { uuid, name, description } = this.props.item;
- const resource = {
- uuid: '',
- name: '',
- description: '',
- kind: ContextMenuKind.PROCESS
- };
- this.props.dispatch<any>(openContextMenu(event, resource));
- }
- }
- )
- );
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 { UploadCollectionFilesDialog } from '~/views-components/upload-collection-files-dialog/upload-collection-files-dialog';
- import { CopyCollectionPartialDialog } from '~/views-components/dialog-forms/copy-collection-partial-dialog';
--import { SidePanel } from '~/views-components/side-panel/side-panel';
import { Routes } from '~/routes/routes';
++import { SidePanel } from '~/views-components/side-panel/side-panel';
++import { ProcessPanel } from '~/views/process-panel/process-panel';
import { Breadcrumbs } from '~/views-components/breadcrumbs/breadcrumbs';
import { CreateProjectDialog } from '~/views-components/dialog-forms/create-project-dialog';
import { CreateCollectionDialog } from '~/views-components/dialog-forms/create-collection-dialog';
import { UpdateProjectDialog } from '~/views-components/dialog-forms/update-project-dialog';
import { MoveProjectDialog } from '~/views-components/dialog-forms/move-project-dialog';
import { MoveCollectionDialog } from '~/views-components/dialog-forms/move-collection-dialog';
--import { ProcessPanel } from '~/views/process-panel/process-panel';
-import { UploadCollectionFilesDialog } from '~/views-components/dialog-forms/upload-collection-files-dialog';
-import { PartialCopyCollectionDialog } from '~/views-components/dialog-forms/partial-copy-collection-dialog';
+
++import { FilesUploadCollectionDialog } from '~/views-components/dialog-forms/files-upload-collection-dialog';
++import { PartialCopyCollectionDialog } from '~/views-components/dialog-forms/partial-copy-collection-dialog';
const APP_BAR_HEIGHT = 100;
<CreateProjectDialog />
<CreateCollectionDialog />
<RenameFileDialog />
+ <PartialCopyCollectionDialog />
+ <FileRemoveDialog />
<CopyCollectionDialog />
- <CopyCollectionPartialDialog />
+ <FileRemoveDialog />
<MultipleFilesRemoveDialog />
<UpdateCollectionDialog />
-- <UploadCollectionFilesDialog />
++ <FilesUploadCollectionDialog />
<UpdateProjectDialog />
<MoveCollectionDialog />
<MoveProjectDialog />