[ARVADOS-WORKBENCH2] updated: 2.1.0-261-g23bafc0a

Git user git at public.arvados.org
Fri Mar 19 22:41:02 UTC 2021


Summary of changes:
 src/plugins/sample-tracker/batchList.tsx  |   2 +-
 src/plugins/sample-tracker/extraction.tsx |  43 +++--------
 src/plugins/sample-tracker/patient.tsx    |   4 +-
 src/plugins/sample-tracker/sampleList.tsx | 124 ++++++++++++++++++++----------
 4 files changed, 96 insertions(+), 77 deletions(-)

       via  23bafc0aac6be3f60812258003dac77a00a4cc18 (commit)
      from  7328f1f28fd792781e32c06232042a58186ea733 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit 23bafc0aac6be3f60812258003dac77a00a4cc18
Author: Peter Amstutz <peter.amstutz at curii.com>
Date:   Fri Mar 19 18:40:53 2021 -0400

    Can edit extractions
    
    Arvados-DCO-1.1-Signed-off-by: Peter Amstutz <peter.amstutz at curii.com>

diff --git a/src/plugins/sample-tracker/batchList.tsx b/src/plugins/sample-tracker/batchList.tsx
index 169583ee..77e7df91 100644
--- a/src/plugins/sample-tracker/batchList.tsx
+++ b/src/plugins/sample-tracker/batchList.tsx
@@ -28,7 +28,7 @@ import { getResource } from "~/store/resources/resources";
 import { Typography } from '@material-ui/core';
 import { initialize } from 'redux-form';
 import { dialogActions } from "~/store/dialog/dialog-actions";
-import { AnalysisState } from './extraction';
+import { AnalysisState } from './sampleList';
 import { StudyPathId } from './patient';
 import { matchPath } from "react-router";
 import { studyRoutePath } from './studyList';
diff --git a/src/plugins/sample-tracker/extraction.tsx b/src/plugins/sample-tracker/extraction.tsx
index 0335a2c1..4329ed83 100644
--- a/src/plugins/sample-tracker/extraction.tsx
+++ b/src/plugins/sample-tracker/extraction.tsx
@@ -8,7 +8,7 @@ import { WithDialogProps } from '~/store/dialog/with-dialog';
 import { FormDialog } from '~/components/form-dialog/form-dialog';
 import { ServiceRepository } from "~/services/services";
 import { compose, Dispatch } from "redux";
-import { reduxForm, WrappedFieldProps, initialize, InjectedFormProps, Field, startSubmit, reset } from 'redux-form';
+import { reduxForm, WrappedFieldProps, InjectedFormProps, Field, startSubmit, reset } from 'redux-form';
 import { RootState } from '~/store/store';
 import { TextField } from "~/components/text-field/text-field";
 import { getResource } from "~/store/resources/resources";
@@ -19,23 +19,13 @@ import { withStyles, WithStyles } from '@material-ui/core/styles';
 import { LinkResource } from "~/models/link";
 import { GroupClass, GroupResource } from "~/models/group";
 import { withDialog } from "~/store/dialog/with-dialog";
-import { sampleTrackerExtractionType } from "./sampleList";
-
-const EXTRACTION_CREATE_FORM_NAME = "extractionCreateFormName";
+import { sampleTrackerExtractionType, EXTRACTION_CREATE_FORM_NAME, AnalysisState } from "./sampleList";
 
 enum ExtractionType {
     DNA = "DNA",
     RNA = "RNA",
 }
 
-export enum AnalysisState {
-    NEW = "NEW",
-    AT_SEQUENCING = "AT_SEQUENCING",
-    SEQUENCED = "SEQUENCED",
-    SEQ_FAILED = "SEQ_FAILED",
-    ANALYSIS_COMPLETE = "ANALYSIS_COMPLETE"
-}
-
 export interface ExtractionCreateFormDialogData {
     sampleUuid: string;
     extractionType: ExtractionType;
@@ -44,9 +34,10 @@ export interface ExtractionCreateFormDialogData {
     sequencingCompleted: string;
     state: AnalysisState;
     batchUuid: string;
+    uuidSelf: string;
 }
 
-type DialogExtractionProps = WithDialogProps<{}> & InjectedFormProps<ExtractionCreateFormDialogData>;
+type DialogExtractionProps = WithDialogProps<{ updating: boolean }> & InjectedFormProps<ExtractionCreateFormDialogData>;
 
 type CssRules = 'selectWidth';
 
@@ -138,9 +129,9 @@ const ExtractionAddFields = () => <span>
 
 const DialogExtractionCreate = (props: DialogExtractionProps) =>
     <FormDialog
-        dialogTitle='Add extraction'
+        dialogTitle={props.data.updating ? 'Edit sample' : 'Add sample'}
         formFields={ExtractionAddFields}
-        submitLabel='Add a extraction'
+        submitLabel={props.data.updating ? 'Update sample' : 'Add sample'}
         {...props}
     />;
 
@@ -185,9 +176,11 @@ const createExtraction = (data: ExtractionCreateFormDialogData) =>
                 "sample_tracker:batch_uuid": "",
             }
         };
-        // const newProject =
-        await services.projectService.create(p);
-
+        if (data.uuidSelf) {
+            await services.projectService.update(data.uuidSelf, p);
+        } else {
+            await services.projectService.create(p);
+        }
         dispatch(dialogActions.CLOSE_DIALOG({ id: EXTRACTION_CREATE_FORM_NAME }));
         dispatch(reset(EXTRACTION_CREATE_FORM_NAME));
     };
@@ -202,17 +195,3 @@ export const CreateExtractionDialog = compose(
         }
     })
 )(DialogExtractionCreate);
-
-
-export const openExtractionCreateDialog = (sampleUuid: string) =>
-    (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
-        dispatch(initialize(EXTRACTION_CREATE_FORM_NAME,
-            {
-                sampleUuid,
-                additionalId: 1,
-                state: AnalysisState.NEW
-            }));
-        dispatch(dialogActions.OPEN_DIALOG({
-            id: EXTRACTION_CREATE_FORM_NAME, data: {}
-        }));
-    };
diff --git a/src/plugins/sample-tracker/patient.tsx b/src/plugins/sample-tracker/patient.tsx
index 4700c734..3525c891 100644
--- a/src/plugins/sample-tracker/patient.tsx
+++ b/src/plugins/sample-tracker/patient.tsx
@@ -13,7 +13,6 @@ import { DataTableDefaultView } from '~/components/data-table-default-view/data-
 import { openContextMenu } from '~/store/context-menu/context-menu-actions';
 import { ResourceKind } from '~/models/resource';
 import { ContextMenuActionSet } from "~/views-components/context-menu/context-menu-action-set";
-import { openExtractionCreateDialog } from "./extraction";
 import { InjectedFormProps, reduxForm, initialize } from 'redux-form';
 import { WithDialogProps } from '~/store/dialog/with-dialog';
 import { ProjectCreateFormDialogData } from '~/store/projects/project-create-actions';
@@ -29,7 +28,8 @@ import { ServiceRepository } from "~/services/services";
 import { PATIENT_PANEL_CURRENT_UUID, sampleTrackerPatientType } from './patientList';
 import {
     SAMPLE_LIST_PANEL_ID, sampleListPanelActions,
-    sampleBaseRoutePath, sampleListPanelColumns
+    sampleBaseRoutePath, sampleListPanelColumns,
+    openExtractionCreateDialog
 } from './sampleList';
 import { studyRoutePath } from './studyList';
 
diff --git a/src/plugins/sample-tracker/sampleList.tsx b/src/plugins/sample-tracker/sampleList.tsx
index a31a0b8d..f4e9991a 100644
--- a/src/plugins/sample-tracker/sampleList.tsx
+++ b/src/plugins/sample-tracker/sampleList.tsx
@@ -9,9 +9,12 @@ import { RootState } from '~/store/store';
 import { DispatchProp, connect } from 'react-redux';
 import { DataColumns } from '~/components/data-table/data-table';
 import { createTree } from '~/models/tree';
-// import { ResourceName } from '~/views-components/data-explorer/renderers';
 import { SortDirection } from '~/components/data-table/data-column';
 import { bindDataExplorerActions } from "~/store/data-explorer/data-explorer-action";
+import { Typography } from '@material-ui/core';
+import { initialize } from 'redux-form';
+import { dialogActions } from "~/store/dialog/dialog-actions";
+import { Resource } from '~/models/resource';
 
 import {
     DataExplorerMiddlewareService,
@@ -38,8 +41,17 @@ export const SAMPLE_PANEL_CURRENT_UUID = "SamplePanelCurrentUUID";
 export const sampleBaseRoutePath = "/SampleTracker/Sample";
 export const sampleRoutePath = sampleBaseRoutePath + "/:uuid";
 
+export const EXTRACTION_CREATE_FORM_NAME = "extractionCreateFormName";
 const PATIENT_PANEL_SAMPLES = "PATIENT_PANEL_SAMPLES";
 
+export enum AnalysisState {
+    NEW = "NEW",
+    AT_SEQUENCING = "AT_SEQUENCING",
+    SEQUENCED = "SEQUENCED",
+    SEQ_FAILED = "SEQ_FAILED",
+    ANALYSIS_COMPLETE = "ANALYSIS_COMPLETE"
+}
+
 enum SamplePanelColumnNames {
     NAME = "Name",
     TIME_POINT = "Time point",
@@ -53,63 +65,95 @@ enum SamplePanelColumnNames {
     BATCH_ID = "Batch",
 }
 
-export const TimePointComponent = connect(
-    (state: RootState, props: { uuid: string }) => {
-        const resource = getResource<LinkResource>(props.uuid)(state.resources);
-        return resource;
-    })((resource: LinkResource & DispatchProp<any>) => <span>{resource.properties["sample_tracker:time_point"]}</span>);
-
-export const CollectionTypeComponent = connect(
-    (state: RootState, props: { uuid: string }) => {
-        const resource = getResource<LinkResource>(props.uuid)(state.resources);
-        return resource;
-    })((resource: LinkResource & DispatchProp<any>) => <span>{resource.properties["sample_tracker:collection_type"]}</span>);
-
-export const SampleTypeComponent = connect(
-    (state: RootState, props: { uuid: string }) => {
-        const resource = getResource<LinkResource>(props.uuid)(state.resources);
-        return resource;
-    })((resource: LinkResource & DispatchProp<any>) => <span>{resource.properties["sample_tracker:sample_type"]}</span>);
-
 export const TimestampComponent = connect(
     (state: RootState, props: { uuid: string, propertyname: string }) => {
         const resource = getResource<LinkResource>(props.uuid)(state.resources);
         return { resource, propertyname: props.propertyname };
     })((props: { resource: LinkResource, propertyname: string } & DispatchProp<any>) => <span>{props.resource.properties[props.propertyname]}</span>);
 
-export const MultiCellComponent = connect(
-    (state: RootState, props: { uuid: string, propertyname: string }) => {
+interface PropertiedResource extends Resource {
+    name: string;
+    properties: any;
+}
+
+export const openExtractionCreateDialog = (sampleUuid: string, editExisting?: PropertiedResource) =>
+    (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+        if (editExisting) {
+            dispatch(initialize(EXTRACTION_CREATE_FORM_NAME,
+                {
+                    sampleUuid,
+                    additionalId: editExisting.properties["sample_tracker:additional_id"],
+                    state: editExisting.properties["sample_tracker:state"],
+                    extractionType: editExisting.properties["sample_tracker:extraction_type"],
+                    batchUuid: editExisting.properties["sample_tracker:batch_uuid"],
+                    uuidSelf: editExisting.uuid,
+                }));
+        } else {
+            dispatch(initialize(EXTRACTION_CREATE_FORM_NAME,
+                {
+                    sampleUuid,
+                    additionalId: 1,
+                    state: AnalysisState.NEW
+                }));
+        }
+        dispatch(dialogActions.OPEN_DIALOG({
+            id: EXTRACTION_CREATE_FORM_NAME, data: { updating: editExisting !== undefined, }
+        }));
+    };
+
+export const ExtractionComponent = connect((state: RootState, props: { resource: PropertiedResource }) => props)(
+    (props: { resource: PropertiedResource } & DispatchProp<any>) =>
+        <Typography color="primary" style={{ width: 'auto', cursor: 'pointer' }}
+            onClick={() => props.dispatch<any>(openExtractionCreateDialog(props.resource.properties["sample_tracker:sample_uuid"], props.resource))}
+        >{props.resource.name}</Typography>);
+
+
+export const PropertyComponent = (props: { resource: PropertiedResource, propertyname: string }) =>
+    <span>{props.resource.properties[props.propertyname]}</span>;
+
+export const ResourceComponent = connect(
+    (state: RootState, props: { uuid: string, render: (item: PropertiedResource) => React.ReactElement<any> }) => {
+        const resource = getResource<PropertiedResource>(props.uuid)(state.resources);
+        return { resource, render: props.render };
+    })((props: { resource: PropertiedResource, render: (item: PropertiedResource) => React.ReactElement<any> } & DispatchProp<any>) => props.render(props.resource));
+
+// {props.resource.properties["sample_tracker:sample_type"]}</span>);
+
+export const MultiResourceComponent = connect(
+    (state: RootState, props: { uuid: string, render: (item: PropertiedResource) => React.ReactElement<any> }) => {
         const reverse = getProperty<{ [key: string]: any[] }>(PATIENT_PANEL_SAMPLES)(state.properties);
         let items = (reverse && reverse[props.uuid]) || [];
         items = items.map(item => {
             const rsc = getResource<GroupResource>(item)(state.resources);
             return rsc || { uuid: "", properties: {} };
         });
-        return { items, propertyname: props.propertyname };
-    })((props: { items: any[], propertyname: string } & DispatchProp<any>) => <>
+        return { items, render: props.render };
+    })((props: { items: any[], render: (item: PropertiedResource) => React.ReactElement<any> } & DispatchProp<any>) => <>
         {props.items.map(item =>
-            <div key={item.uuid} > {item.properties[props.propertyname]}</div>
+            <div key={item.uuid} > {props.render(item)}</div>
         )}
     </>
     );
 
 
 export const sampleListPanelColumns: DataColumns<string> = [
-    /*{
-        name: SamplePanelColumnNames.NAME,
+    {
+        name: SamplePanelColumnNames.SAMPLE_TYPE,
         selected: true,
         configurable: true,
         sortDirection: SortDirection.NONE,
         filters: createTree(),
-        render: uuid => <ResourceName uuid={uuid} />
-    },*/
+        render: uuid => <ResourceComponent uuid={uuid}
+            render={rsc => <PropertyComponent resource={rsc} propertyname="sample_tracker:sample_type" />} />
+    },
     {
         name: SamplePanelColumnNames.TIME_POINT,
         selected: true,
         configurable: true,
         sortDirection: SortDirection.NONE,
         filters: createTree(),
-        render: uuid => <TimePointComponent uuid={uuid} />
+        render: uuid => <ResourceComponent uuid={uuid}
+            render={rsc => <PropertyComponent resource={rsc} propertyname="sample_tracker:time_point" />} />
     },
     {
         name: SamplePanelColumnNames.COLLECTED_AT,
@@ -120,20 +164,13 @@ export const sampleListPanelColumns: DataColumns<string> = [
         render: uuid => <TimestampComponent uuid={uuid} propertyname="sample_tracker:collected_at" />
     },
     {
-        name: SamplePanelColumnNames.COLLECTION_TYPE,
-        selected: true,
-        configurable: true,
-        sortDirection: SortDirection.NONE,
-        filters: createTree(),
-        render: uuid => <CollectionTypeComponent uuid={uuid} />
-    },
-    {
-        name: SamplePanelColumnNames.SAMPLE_TYPE,
+        name: SamplePanelColumnNames.NAME,
         selected: true,
         configurable: true,
         sortDirection: SortDirection.NONE,
         filters: createTree(),
-        render: uuid => <SampleTypeComponent uuid={uuid} />
+        render: uuid => <ResourceComponent uuid={uuid}
+            render={rsc => <span>{rsc.name}</span>} />
     },
     {
         name: SamplePanelColumnNames.FLOW_STARTED_AT,
@@ -157,7 +194,8 @@ export const sampleListPanelColumns: DataColumns<string> = [
         configurable: true,
         sortDirection: SortDirection.NONE,
         filters: createTree(),
-        render: uuid => <MultiCellComponent uuid={uuid.substr(sampleBaseRoutePath.length + 1)} propertyname="sample_tracker:extraction_type" />
+        render: uuid => <MultiResourceComponent uuid={uuid.substr(sampleBaseRoutePath.length + 1)}
+            render={rsc => <ExtractionComponent resource={rsc} />} />
     },
     {
         name: SamplePanelColumnNames.BATCH_ID,
@@ -165,7 +203,8 @@ export const sampleListPanelColumns: DataColumns<string> = [
         configurable: true,
         sortDirection: SortDirection.NONE,
         filters: createTree(),
-        render: uuid => <MultiCellComponent uuid={uuid.substr(sampleBaseRoutePath.length + 1)} propertyname="sample_tracker:batch_uuid" />
+        render: uuid => <MultiResourceComponent uuid={uuid.substr(sampleBaseRoutePath.length + 1)}
+            render={rsc => <PropertyComponent resource={rsc} propertyname="sample_tracker:batch_uuid" />} />
     },
     {
         name: SamplePanelColumnNames.TRACKER_STATE,
@@ -173,7 +212,8 @@ export const sampleListPanelColumns: DataColumns<string> = [
         configurable: true,
         sortDirection: SortDirection.NONE,
         filters: createTree(),
-        render: uuid => <MultiCellComponent uuid={uuid.substr(sampleBaseRoutePath.length + 1)} propertyname="sample_tracker:state" />
+        render: uuid => <MultiResourceComponent uuid={uuid.substr(sampleBaseRoutePath.length + 1)}
+            render={rsc => <PropertyComponent resource={rsc} propertyname="sample_tracker:state" />} />
     }
 ];
 

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list