Merge branch '13858-process-view-information-card' into 13860-status-for-subprocesses
authorJanicki Artur <artur.janicki@contractors.roche.com>
Wed, 29 Aug 2018 08:34:03 +0000 (10:34 +0200)
committerJanicki Artur <artur.janicki@contractors.roche.com>
Wed, 29 Aug 2018 08:34:03 +0000 (10:34 +0200)
refs #13858
13860

Arvados-DCO-1.1-Signed-off-by: Janicki Artur <artur.janicki@contractors.roche.com>

1  2 
src/components/details-attribute/details-attribute.tsx
src/store/collection-panel/collection-panel-files/collection-panel-files-actions.ts
src/store/collections/collection-partial-copy-actions.ts
src/views-components/dialog-forms/files-upload-collection-dialog.ts
src/views-components/dialog-forms/partial-copy-collection-dialog.ts
src/views/process-panel/process-panel.tsx
src/views/workbench/workbench.tsx

index 96ff17c8cd9f02849d09ec64d12e9c94b6f68752,d509218ecfa2ca8cd0c203780ad8985ae734f85b..413fedfc1c08eccd17fe24f4c22aecd03d5a000e
@@@ -86,65 -86,8 +86,6 @@@ export const openMultipleFilesRemoveDia
          }
      });
  
- 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;
index 0000000000000000000000000000000000000000,f0dd2780d4f5255a0f4ed9c837e06397028490a2..a063abae4107a28438da4e503d2c33d7700a1ca6
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,71 +1,71 @@@
 -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 }));
+                 }
+             }
+         }
+     };
index 0000000000000000000000000000000000000000,38f0333e4d146d071e13ac639324cb03f73d796b..a24490f727fd58d03fe6f40078db73827c88b639
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,20 +1,20 @@@
 -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);
index 0000000000000000000000000000000000000000,9a350f6307ce908f9b503b5b9b21c3ebc45ccc7b..16f8275e8fb57821c8ed2f4b8065c4b8c6c43eb9
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,19 +1,19 @@@
 -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);
index d7a9305261123717f462c93b14507d5ec7cba676,ce98a4880b1ac337a9ef6a2a3a5778d3dc318443..402e5d0e725951040ff5c0008195602417ad0aa7
  // 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));
-             }
-         }
-     )
- );
index a3c4d2faa273dbb5310cce2cd770bbc5e3ae455c,1d53842b422bcbcb4484b6607c355d46fa5d8445..a0619ae346fc7eb715547da07d49373f0bc9b799
@@@ -24,10 -24,8 +24,9 @@@ import { AuthService } from "~/services
  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';
@@@ -36,7 -34,10 +35,9 @@@ import { UpdateCollectionDialog } from 
  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;
  
@@@ -175,12 -176,12 +176,13 @@@ export const Workbench = withStyles(sty
                          <CreateProjectDialog />
                          <CreateCollectionDialog />
                          <RenameFileDialog />
+                         <PartialCopyCollectionDialog />
+                         <FileRemoveDialog />
                          <CopyCollectionDialog />
-                         <CopyCollectionPartialDialog />
 +                        <FileRemoveDialog />
                          <MultipleFilesRemoveDialog />
                          <UpdateCollectionDialog />
--                        <UploadCollectionFilesDialog />
++                        <FilesUploadCollectionDialog />
                          <UpdateProjectDialog />
                          <MoveCollectionDialog />
                          <MoveProjectDialog />