From 21a265b6745dc28eb7f9d9680f46149ac88363ab Mon Sep 17 00:00:00 2001
From: Quan Nguyen <86090707+qu8n@users.noreply.github.com>
Date: Tue, 19 Mar 2024 17:22:19 -0400
Subject: [PATCH] Add a preliminary version of the Cohorts page (#114)
* Cohort codegen (#109)
* explicit libdir path
* Cohort, CohortComplete schema updates
Signed-off-by: Angelica Ochoa <15623749+ao508@users.noreply.github.com>
---------
Signed-off-by: Angelica Ochoa <15623749+ao508@users.noreply.github.com>
* Add Cohorts view prototype (#111)
* Perform incremental minor cleanups
- Update the favicon from the template favicon to the Smile logo, which
involves moving the logo images to /public to enable index.html to
access them
- Remove the unused template HomePage component
* Create a new route and page for Cohorts view
* Match functional component declaration syntax across all pages
* Generate new types (e.g. Cohort) and define a query for finding cohort samples
* Make the Samples query inside the Samples component generic
* Display cohort sample data on Cohorts view
* Display the TEMPO data columns in Cohorts view
* Rerun codegen to reflect cohort to sample relationship name change
* Add the remaining Tempo event columns and remove Status
* Modify Cohorts view to show cohort-level data
* Modify RecordsList and SamplesList components to handle cohort samples popup
* Make cohort samples popup read-only & show a lock icon for all read-only fields
* Fix popup shows only samples by cohort and fields are searchable
* Add CMO sample label field to the cohort samples popup
* Clean up GraphQL operations file
* Add '# Samples' column to Cohorts view
* Set cohort samples to display the latest tempo events
* Fix cohort samples popup's export
* Pre-PR cleanups
* Clean up and reorganize `RecordsList` and `SamplesList` components (#112)
* Resize RecordsList table to fill the available height
* Remove unneeded props from RecordsList component
* Rename 'ActiveColumns' to 'ActivePatientsListColumns' to standardize colDefs input names
* Combine RecordsList's props sampleQueryParamFieldName and sampleQueryParamValue into one
* Use title case to display field name in heading of samples popups
* Rename cohort/ to cohorts/ to match patients/ and requests/
* Rename RecordsList's prop 'conditionBuilder' to 'queryFilterWhereVariables' for more clarity
* Rename RecordsList's prop 'getRowData' to 'getSampleRowData' for more clarity
* Standardize search-related state variable names for more clarity
* Rename RecordsList's prop 'customFilterUI' to 'customToolbarUI' for more clarity
* Standardize functional component initialization syntax
* Replace table height inputs with CSS classes
* Standardize function input names of search-related state variable names for more clarity
* Standardize and clean up sample where variables and search handlers
* Reorganize RecordsList and SamplesList props order and naming
* Show `CohortComplete` data of each cohort record on Cohorts page (#113)
* Show Cohort Complete data on Cohorts page
* Show latest CohortComplete data on Cohorts page
* Enable searching for CohortComplete fields
---------
Signed-off-by: Angelica Ochoa <15623749+ao508@users.noreply.github.com>
Co-authored-by: ao508 <15623749+ao508@users.noreply.github.com>
---
frontend/{src/imgs => public/img}/logo.png | Bin
.../imgs => public/img}/logo_with_text.png | Bin
frontend/public/index.html | 13 +-
frontend/src/App.tsx | 8 +-
frontend/src/components/RecordsList.tsx | 144 +-
frontend/src/components/SamplesList.tsx | 159 +-
frontend/src/components/records.module.scss | 8 +
frontend/src/generated/graphql.ts | 5256 +-
frontend/src/pages/cohorts/CohortsPage.tsx | 168 +
frontend/src/pages/home/HomePage.tsx | 21 -
frontend/src/pages/patients/PatientsPage.tsx | 146 +-
frontend/src/pages/requests/RequestsPage.tsx | 150 +-
frontend/src/pages/samples/SamplesPage.tsx | 38 +-
frontend/src/shared/components/PageHeader.tsx | 22 +-
.../src/shared/components/SmileNavBar.tsx | 4 +-
frontend/src/shared/helpers.tsx | 407 +-
frontend/src/shared/tableElements.tsx | 30 +-
frontend/src/shared/types.ts | 4 +-
frontend/src/utils/parseSearchQueries.ts | 4 +-
graphql-server/src/generated/graphql.ts | 5494 +-
graphql-server/src/schemas/oracle.ts | 2 +-
graphql.schema.json | 84453 ++++++++++------
graphql/operations.graphql | 98 +-
23 files changed, 65614 insertions(+), 31015 deletions(-)
rename frontend/{src/imgs => public/img}/logo.png (100%)
rename frontend/{src/imgs => public/img}/logo_with_text.png (100%)
create mode 100644 frontend/src/pages/cohorts/CohortsPage.tsx
delete mode 100644 frontend/src/pages/home/HomePage.tsx
diff --git a/frontend/src/imgs/logo.png b/frontend/public/img/logo.png
similarity index 100%
rename from frontend/src/imgs/logo.png
rename to frontend/public/img/logo.png
diff --git a/frontend/src/imgs/logo_with_text.png b/frontend/public/img/logo_with_text.png
similarity index 100%
rename from frontend/src/imgs/logo_with_text.png
rename to frontend/public/img/logo_with_text.png
diff --git a/frontend/public/index.html b/frontend/public/index.html
index 14eb4009..1ee57cf7 100644
--- a/frontend/public/index.html
+++ b/frontend/public/index.html
@@ -2,15 +2,8 @@
-
-
-
-
-
-
-
-
+
@@ -34,10 +27,6 @@
-
SMILE Dashboard
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index 028dffa5..64b428e2 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -3,11 +3,12 @@ import { Routes, Route } from "react-router-dom";
import RequestsPage from "./pages/requests/RequestsPage";
import PatientsPage from "./pages/patients/PatientsPage";
import SamplesPage from "./pages/samples/SamplesPage";
+import CohortsPage from "./pages/cohorts/CohortsPage";
import LoginSuccessPage from "./pages/auth/LoginSuccessPage";
import SmileNavBar from "./shared/components/SmileNavBar";
import { getUserEmail } from "./utils/getUserEmail";
-function App() {
+export default function App() {
const [userEmail, setUserEmail] = useState(null);
useEffect(() => {
@@ -34,11 +35,12 @@ function App() {
} />
+ }>
+
+
} />
>
);
}
-
-export default App;
diff --git a/frontend/src/components/RecordsList.tsx b/frontend/src/components/RecordsList.tsx
index f9448a38..b522a38e 100644
--- a/frontend/src/components/RecordsList.tsx
+++ b/frontend/src/components/RecordsList.tsx
@@ -1,6 +1,6 @@
import AutoSizer from "react-virtualized-auto-sizer";
import { Button, Container, Modal } from "react-bootstrap";
-import { FunctionComponent, useMemo } from "react";
+import { Dispatch, SetStateAction, useMemo } from "react";
import { useNavigate } from "react-router-dom";
import { DownloadModal } from "./DownloadModal";
import { CSVFormulate } from "../utils/CSVExport";
@@ -11,58 +11,66 @@ import "ag-grid-community/styles/ag-grid.css";
import "ag-grid-community/styles/ag-theme-alpine.css";
import "ag-grid-enterprise";
import { ColDef, IServerSideGetRowsParams } from "ag-grid-community";
-import { useHookGeneric } from "../shared/types";
-import { SamplesList } from "./SamplesList";
-import { SampleWhere } from "../generated/graphql";
-import { defaultRecordsColDef } from "../shared/helpers";
+import { DataName, useHookLazyGeneric } from "../shared/types";
+import SamplesList from "./SamplesList";
+import { Sample, SampleWhere } from "../generated/graphql";
+import { defaultReadOnlyColDef } from "../shared/helpers";
import { PatientIdsTriplet } from "../pages/patients/PatientsPage";
import { ErrorMessage, LoadingSpinner, Toolbar } from "../shared/tableElements";
-export interface IRecordsListProps {
- lazyRecordsQuery: typeof useHookGeneric;
- nodeName: string;
- totalCountNodeName: string;
- pageRoute: string;
- searchTerm: string;
+interface IRecordsListProps {
colDefs: ColDef[];
- conditionBuilder: (uniqueQueries: string[]) => Record[];
- sampleQueryParamValue: string | undefined;
- sampleQueryParamFieldName: string;
- searchVariables: SampleWhere;
- customFilterUI?: JSX.Element;
- setCustomFilterVals?: (vals: PatientIdsTriplet[]) => void;
- searchVal: string[];
- setSearchVal: (val: string[]) => void;
+ dataName: DataName;
+ nodeName?: string;
+ lazyRecordsQuery: typeof useHookLazyGeneric;
+ lazyRecordsQueryAddlVariables?: Record;
+ queryFilterWhereVariables: (
+ parsedSearchVals: string[]
+ ) => Record[];
+ userSearchVal: string;
+ setUserSearchVal: Dispatch>;
+ parsedSearchVals: string[];
+ setParsedSearchVals: Dispatch>;
handleSearch: () => void;
- inputVal: string;
- setInputVal: (val: string) => void;
showDownloadModal: boolean;
- setShowDownloadModal: (val: boolean) => void;
+ setShowDownloadModal: Dispatch>;
handleDownload: () => void;
+ samplesQueryParam: string | undefined;
+ samplesDefaultColDef: ColDef;
+ getSamplesRowData: (samples: Sample[]) => any[];
+ samplesColDefs: ColDef[];
+ samplesParentWhereVariables: SampleWhere;
+ samplesRefetchWhereVariables: (
+ samplesParsedSearchVals: string[]
+ ) => SampleWhere;
+ setCustomSearchVals?: Dispatch>;
+ customToolbarUI?: JSX.Element;
}
-const RecordsList: FunctionComponent = ({
- lazyRecordsQuery,
- nodeName,
- totalCountNodeName,
- pageRoute,
- searchTerm,
+export default function RecordsList({
colDefs,
- conditionBuilder,
- sampleQueryParamValue,
- sampleQueryParamFieldName,
- searchVariables,
- customFilterUI,
- setCustomFilterVals,
- searchVal,
- setSearchVal,
+ dataName,
+ nodeName = dataName,
+ lazyRecordsQuery,
+ lazyRecordsQueryAddlVariables,
+ queryFilterWhereVariables,
+ userSearchVal,
+ setUserSearchVal,
+ parsedSearchVals,
+ setParsedSearchVals,
handleSearch,
- inputVal,
- setInputVal,
showDownloadModal,
setShowDownloadModal,
handleDownload,
-}) => {
+ samplesQueryParam,
+ samplesDefaultColDef,
+ getSamplesRowData,
+ samplesColDefs,
+ samplesParentWhereVariables,
+ samplesRefetchWhereVariables,
+ customToolbarUI,
+ setCustomSearchVals,
+}: IRecordsListProps) {
const [showClosingWarning, setShowClosingWarning] = useState(false);
const [unsavedChanges, setUnsavedChanges] = useState(false);
const navigate = useNavigate();
@@ -73,19 +81,22 @@ const RecordsList: FunctionComponent = ({
lazyRecordsQuery({
variables: {
options: { limit: 20, offset: 0 },
+ ...lazyRecordsQueryAddlVariables,
},
});
+ const totalCountNodeName = `${nodeName}Connection`;
+
const datasource = useMemo(() => {
return {
// called by the grid when more rows are required
getRows: (params: IServerSideGetRowsParams) => {
const fetchInput = {
where: {
- OR: conditionBuilder(searchVal),
+ OR: queryFilterWhereVariables(parsedSearchVals),
},
[`${nodeName}ConnectionWhere2`]: {
- OR: conditionBuilder(searchVal),
+ OR: queryFilterWhereVariables(parsedSearchVals),
},
options: {
offset: params.request.startRow,
@@ -114,7 +125,7 @@ const RecordsList: FunctionComponent = ({
},
};
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [searchVal]);
+ }, [parsedSearchVals]);
if (loading) return ;
@@ -126,7 +137,7 @@ const RecordsList: FunctionComponent = ({
if (unsavedChanges) {
setShowClosingWarning(true);
} else {
- navigate(pageRoute);
+ navigate(`/${dataName}`);
}
};
@@ -138,7 +149,7 @@ const RecordsList: FunctionComponent = ({
return fetchMore({
variables: {
where: {
- OR: conditionBuilder(searchVal),
+ OR: queryFilterWhereVariables(parsedSearchVals),
},
options: {
offset: 0,
@@ -183,7 +194,7 @@ const RecordsList: FunctionComponent = ({
onClick={() => {
setShowClosingWarning(false);
setUnsavedChanges(false);
- navigate(pageRoute);
+ navigate(`/${dataName}`);
}}
>
Continue Exiting
@@ -192,22 +203,23 @@ const RecordsList: FunctionComponent = ({
)}
- {sampleQueryParamValue && (
+ {samplesQueryParam && (
{({ height, width }) => (
- {`Viewing ${sampleQueryParamValue}`}
+ {`Viewing ${samplesQueryParam}`}
-
+
@@ -217,26 +229,26 @@ const RecordsList: FunctionComponent
= ({
)}
{
- setCustomFilterVals && setCustomFilterVals([]);
- setSearchVal([]);
+ clearUserSearchVal={() => {
+ setCustomSearchVals && setCustomSearchVals([]);
+ setParsedSearchVals([]);
}}
matchingResultsCount={`${remoteCount?.toLocaleString()} matching ${
- remoteCount > 1 ? searchTerm : searchTerm.slice(0, -1)
+ remoteCount > 1 ? dataName : dataName.slice(0, -1)
}`}
handleDownload={handleDownload}
- customUI={customFilterUI}
+ customUI={customToolbarUI}
/>
{({ width }) => (
= ({
context={{
navigateFunction: navigate,
}}
- defaultColDef={defaultRecordsColDef}
+ defaultColDef={defaultReadOnlyColDef}
onGridReady={(params) => {
params.api.sizeColumnsToFit();
}}
@@ -262,6 +274,4 @@ const RecordsList: FunctionComponent = ({
);
-};
-
-export default RecordsList;
+}
diff --git a/frontend/src/components/SamplesList.tsx b/frontend/src/components/SamplesList.tsx
index 7a300241..a5e24e75 100644
--- a/frontend/src/components/SamplesList.tsx
+++ b/frontend/src/components/SamplesList.tsx
@@ -1,132 +1,86 @@
import {
SortDirection,
Sample,
+ SampleWhere,
useFindSamplesByInputValueQuery,
- SampleMetadataWhere,
} from "../generated/graphql";
import AutoSizer from "react-virtualized-auto-sizer";
import { Button, Col } from "react-bootstrap";
-import { FunctionComponent, useEffect, useRef } from "react";
+import { useEffect, useRef } from "react";
import { DownloadModal } from "./DownloadModal";
import { UpdateModal } from "./UpdateModal";
import { AlertModal } from "./AlertModal";
import { CSVFormulate } from "../utils/CSVExport";
import {
- SampleDetailsColumns,
- defaultSamplesColDef,
SampleChange,
SampleMetadataExtended,
+ handleSearch,
} from "../shared/helpers";
import { AgGridReact } from "ag-grid-react";
import { useState } from "react";
import "ag-grid-community/styles/ag-grid.css";
import "ag-grid-community/styles/ag-theme-alpine.css";
import "ag-grid-enterprise";
-import { CellValueChangedEvent } from "ag-grid-community";
-import { parseSearchQueries } from "../utils/parseSearchQueries";
+import { CellValueChangedEvent, ColDef } from "ag-grid-community";
import { ErrorMessage, LoadingSpinner, Toolbar } from "../shared/tableElements";
+import styles from "./records.module.scss";
const POLLING_INTERVAL = 2000;
const max_rows = 500;
interface ISampleListProps {
- height: number;
- setUnsavedChanges?: (val: boolean) => void;
- searchVariables?: SampleMetadataWhere;
+ columnDefs: ColDef[];
+ defaultColDef: ColDef;
+ getRowData: (samples: Sample[]) => any[];
+ setUnsavedChanges?: (unsavedChanges: boolean) => void;
+ parentWhereVariables?: SampleWhere;
+ refetchWhereVariables: (parsedSearchVals: string[]) => SampleWhere;
exportFileName?: string;
- sampleQueryParamFieldName?: string;
- sampleQueryParamValue?: string;
}
-function sampleFilterWhereVariables(
- uniqueQueries: string[]
-): SampleMetadataWhere[] {
- if (uniqueQueries.length > 1) {
- return [
- { cmoSampleName_IN: uniqueQueries },
- { importDate_IN: uniqueQueries },
- { investigatorSampleId_IN: uniqueQueries },
- { primaryId_IN: uniqueQueries },
- { sampleClass_IN: uniqueQueries },
- { cmoPatientId_IN: uniqueQueries },
- { cmoSampleIdFields_IN: uniqueQueries },
- { sampleName_IN: uniqueQueries },
- { preservation_IN: uniqueQueries },
- { tumorOrNormal_IN: uniqueQueries },
- { oncotreeCode_IN: uniqueQueries },
- { collectionYear_IN: uniqueQueries },
- { sampleOrigin_IN: uniqueQueries },
- { tissueLocation_IN: uniqueQueries },
- { sex_IN: uniqueQueries },
- { libraries_IN: uniqueQueries },
- { sampleType_IN: uniqueQueries },
- { species_IN: uniqueQueries },
- { genePanel_IN: uniqueQueries },
- ];
- } else {
- return [
- { cmoSampleName_CONTAINS: uniqueQueries[0] },
- { importDate_CONTAINS: uniqueQueries[0] },
- { investigatorSampleId_CONTAINS: uniqueQueries[0] },
- { primaryId_CONTAINS: uniqueQueries[0] },
- { sampleClass_CONTAINS: uniqueQueries[0] },
- { cmoPatientId_CONTAINS: uniqueQueries[0] },
- { cmoSampleIdFields_CONTAINS: uniqueQueries[0] },
- { sampleName_CONTAINS: uniqueQueries[0] },
- { preservation_CONTAINS: uniqueQueries[0] },
- { tumorOrNormal_CONTAINS: uniqueQueries[0] },
- { oncotreeCode_CONTAINS: uniqueQueries[0] },
- { collectionYear_CONTAINS: uniqueQueries[0] },
- { sampleOrigin_CONTAINS: uniqueQueries[0] },
- { tissueLocation_CONTAINS: uniqueQueries[0] },
- { sex_CONTAINS: uniqueQueries[0] },
- { libraries_CONTAINS: uniqueQueries[0] },
- { sampleType_CONTAINS: uniqueQueries[0] },
- { species_CONTAINS: uniqueQueries[0] },
- { genePanel_CONTAINS: uniqueQueries[0] },
- ];
- }
-}
-
-function getSampleMetadata(samples: Sample[]) {
- return samples.map((s: any) => {
- return {
- ...s.hasMetadataSampleMetadata[0],
- revisable: s.revisable,
- };
- });
-}
-
-export const SamplesList: FunctionComponent = ({
- searchVariables,
- height,
+export default function SamplesList({
+ columnDefs,
+ defaultColDef,
+ getRowData,
+ parentWhereVariables,
+ refetchWhereVariables,
setUnsavedChanges,
exportFileName,
- sampleQueryParamFieldName,
- sampleQueryParamValue,
-}) => {
+}: ISampleListProps) {
const { loading, error, data, startPolling, stopPolling, refetch } =
useFindSamplesByInputValueQuery({
variables: {
- ...(searchVariables
+ ...(parentWhereVariables
? {
where: {
- ...searchVariables,
+ ...parentWhereVariables,
},
}
: {
first: max_rows,
}),
- options: {
+ sampleMetadataOptions: {
sort: [{ importDate: SortDirection.Desc }],
limit: 1,
},
+ bamCompletesOptions: {
+ sort: [{ date: SortDirection.Desc }],
+ limit: 1,
+ },
+ mafCompletesOptions: {
+ sort: [{ date: SortDirection.Desc }],
+ limit: 1,
+ },
+ qcCompletesOptions: {
+ sort: [{ date: SortDirection.Desc }],
+ limit: 1,
+ },
},
pollInterval: POLLING_INTERVAL,
});
- const [val, setVal] = useState("");
- const [searchVal, setSearchVal] = useState("");
+ const [userSearchVal, setUserSearchVal] = useState("");
+ const [parsedSearchVals, setParsedSearchVals] = useState([]);
const [showDownloadModal, setShowDownloadModal] = useState(false);
const [showAlertModal, setShowAlertModal] = useState(false);
const [showUpdateModal, setShowUpdateModal] = useState(false);
@@ -138,23 +92,14 @@ export const SamplesList: FunctionComponent = ({
gridRef.current?.api?.showLoadingOverlay();
async function refetchSearchVal() {
await refetch({
- where: {
- hasMetadataSampleMetadata_SOME: {
- OR: sampleFilterWhereVariables(parseSearchQueries(searchVal)),
- ...(sampleQueryParamFieldName && sampleQueryParamValue
- ? {
- [sampleQueryParamFieldName]: sampleQueryParamValue,
- }
- : {}),
- },
- },
+ where: refetchWhereVariables(parsedSearchVals),
});
}
refetchSearchVal().then(() => {
gridRef.current?.api?.hideOverlay();
});
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [searchVal]);
+ }, [parsedSearchVals]);
if (loading) return ;
@@ -210,7 +155,7 @@ export const SamplesList: FunctionComponent = ({
{
return Promise.resolve(
- CSVFormulate(getSampleMetadata(samples), SampleDetailsColumns)
+ CSVFormulate(getRowData(samples), columnDefs)
);
}}
onComplete={() => {
@@ -242,14 +187,13 @@ export const SamplesList: FunctionComponent = ({
/>
{
- setSearchVal(val);
- }}
- clearInput={() => {
- setSearchVal("");
+ dataName={"samples"}
+ userSearchVal={userSearchVal}
+ setUserSearchVal={setUserSearchVal}
+ handleSearch={() => handleSearch(userSearchVal, setParsedSearchVals)}
+ clearUserSearchVal={() => {
+ setUserSearchVal("");
+ setParsedSearchVals([]);
}}
matchingResultsCount={
remoteCount === max_rows
@@ -289,8 +233,8 @@ export const SamplesList: FunctionComponent = ({
{({ width }) => (
getRowId={(d) => {
@@ -300,7 +244,6 @@ export const SamplesList: FunctionComponent = ({
unlocked: function (params) {
return params.data?.revisable === true;
},
-
locked: function (params) {
return params.data?.revisable === false;
},
@@ -314,11 +257,11 @@ export const SamplesList: FunctionComponent = ({
);
},
}}
- columnDefs={SampleDetailsColumns}
- rowData={getSampleMetadata(samples)}
+ columnDefs={columnDefs}
+ rowData={getRowData(samples)}
onCellEditRequest={onCellValueChanged}
readOnlyEdit={true}
- defaultColDef={defaultSamplesColDef}
+ defaultColDef={defaultColDef}
ref={gridRef}
context={{
getChanges: () => changes,
@@ -343,4 +286,4 @@ export const SamplesList: FunctionComponent = ({
>
);
-};
+}
diff --git a/frontend/src/components/records.module.scss b/frontend/src/components/records.module.scss
index 09f5f455..787a829a 100644
--- a/frontend/src/components/records.module.scss
+++ b/frontend/src/components/records.module.scss
@@ -9,3 +9,11 @@
align-items: center;
justify-content: center;
}
+
+.tableHeight {
+ height: calc(100vh - 230px);
+}
+
+.popupHeight {
+ height: calc(100vh - 180px);
+}
diff --git a/frontend/src/generated/graphql.ts b/frontend/src/generated/graphql.ts
index cef627ab..fbc0143f 100644
--- a/frontend/src/generated/graphql.ts
+++ b/frontend/src/generated/graphql.ts
@@ -21,679 +21,951 @@ export type Scalars = {
Float: number;
};
-export type CreateInfo = {
- __typename?: "CreateInfo";
- bookmark?: Maybe;
- nodesCreated: Scalars["Int"];
- relationshipsCreated: Scalars["Int"];
+export type BamComplete = {
+ __typename?: "BamComplete";
+ date: Scalars["String"];
+ status: Scalars["String"];
+ temposHasEvent: Array;
+ temposHasEventAggregate?: Maybe;
+ temposHasEventConnection: BamCompleteTemposHasEventConnection;
};
-export type CreatePatientAliasesMutationResponse = {
- __typename?: "CreatePatientAliasesMutationResponse";
- info: CreateInfo;
- patientAliases: Array;
+export type BamCompleteTemposHasEventArgs = {
+ directed?: InputMaybe;
+ options?: InputMaybe;
+ where?: InputMaybe;
};
-export type CreatePatientsMutationResponse = {
- __typename?: "CreatePatientsMutationResponse";
- info: CreateInfo;
- patients: Array;
+export type BamCompleteTemposHasEventAggregateArgs = {
+ directed?: InputMaybe;
+ where?: InputMaybe;
};
-export type CreateProjectsMutationResponse = {
- __typename?: "CreateProjectsMutationResponse";
- info: CreateInfo;
- projects: Array;
+export type BamCompleteTemposHasEventConnectionArgs = {
+ after?: InputMaybe;
+ directed?: InputMaybe;
+ first?: InputMaybe;
+ where?: InputMaybe;
};
-export type CreateRequestMetadataMutationResponse = {
- __typename?: "CreateRequestMetadataMutationResponse";
- info: CreateInfo;
- requestMetadata: Array;
+export type BamCompleteAggregateSelection = {
+ __typename?: "BamCompleteAggregateSelection";
+ count: Scalars["Int"];
+ date: StringAggregateSelectionNonNullable;
+ status: StringAggregateSelectionNonNullable;
};
-export type CreateRequestsMutationResponse = {
- __typename?: "CreateRequestsMutationResponse";
- info: CreateInfo;
- requests: Array;
+export type BamCompleteConnectInput = {
+ temposHasEvent?: InputMaybe<
+ Array
+ >;
};
-export type CreateSampleAliasesMutationResponse = {
- __typename?: "CreateSampleAliasesMutationResponse";
- info: CreateInfo;
- sampleAliases: Array;
+export type BamCompleteConnectWhere = {
+ node: BamCompleteWhere;
};
-export type CreateSampleMetadataMutationResponse = {
- __typename?: "CreateSampleMetadataMutationResponse";
- info: CreateInfo;
- sampleMetadata: Array;
+export type BamCompleteCreateInput = {
+ date: Scalars["String"];
+ status: Scalars["String"];
+ temposHasEvent?: InputMaybe;
};
-export type CreateSamplesMutationResponse = {
- __typename?: "CreateSamplesMutationResponse";
- info: CreateInfo;
- samples: Array;
+export type BamCompleteDeleteInput = {
+ temposHasEvent?: InputMaybe>;
};
-export type CreateStatusesMutationResponse = {
- __typename?: "CreateStatusesMutationResponse";
- info: CreateInfo;
- statuses: Array;
+export type BamCompleteDisconnectInput = {
+ temposHasEvent?: InputMaybe<
+ Array
+ >;
};
-export type DeleteInfo = {
- __typename?: "DeleteInfo";
- bookmark?: Maybe;
- nodesDeleted: Scalars["Int"];
- relationshipsDeleted: Scalars["Int"];
+export type BamCompleteEdge = {
+ __typename?: "BamCompleteEdge";
+ cursor: Scalars["String"];
+ node: BamComplete;
};
-export type Mutation = {
- __typename?: "Mutation";
- createPatientAliases: CreatePatientAliasesMutationResponse;
- createPatients: CreatePatientsMutationResponse;
- createProjects: CreateProjectsMutationResponse;
- createRequestMetadata: CreateRequestMetadataMutationResponse;
- createRequests: CreateRequestsMutationResponse;
- createSampleAliases: CreateSampleAliasesMutationResponse;
- createSampleMetadata: CreateSampleMetadataMutationResponse;
- createSamples: CreateSamplesMutationResponse;
- createStatuses: CreateStatusesMutationResponse;
- deletePatientAliases: DeleteInfo;
- deletePatients: DeleteInfo;
- deleteProjects: DeleteInfo;
- deleteRequestMetadata: DeleteInfo;
- deleteRequests: DeleteInfo;
- deleteSampleAliases: DeleteInfo;
- deleteSampleMetadata: DeleteInfo;
- deleteSamples: DeleteInfo;
- deleteStatuses: DeleteInfo;
- updatePatientAliases: UpdatePatientAliasesMutationResponse;
- updatePatients: UpdatePatientsMutationResponse;
- updateProjects: UpdateProjectsMutationResponse;
- updateRequestMetadata: UpdateRequestMetadataMutationResponse;
- updateRequests: UpdateRequestsMutationResponse;
- updateSampleAliases: UpdateSampleAliasesMutationResponse;
- updateSampleMetadata: UpdateSampleMetadataMutationResponse;
- updateSamples: UpdateSamplesMutationResponse;
- updateStatuses: UpdateStatusesMutationResponse;
+export type BamCompleteOptions = {
+ limit?: InputMaybe;
+ offset?: InputMaybe;
+ /** Specify one or more BamCompleteSort objects to sort BamCompletes by. The sorts will be applied in the order in which they are arranged in the array. */
+ sort?: InputMaybe>;
};
-export type MutationCreatePatientAliasesArgs = {
- input: Array;
+export type BamCompleteRelationInput = {
+ temposHasEvent?: InputMaybe>;
};
-export type MutationCreatePatientsArgs = {
- input: Array;
+/** Fields to sort BamCompletes by. The order in which sorts are applied is not guaranteed when specifying many fields in one BamCompleteSort object. */
+export type BamCompleteSort = {
+ date?: InputMaybe;
+ status?: InputMaybe;
};
-export type MutationCreateProjectsArgs = {
- input: Array;
+export type BamCompleteTempoTemposHasEventAggregationSelection = {
+ __typename?: "BamCompleteTempoTemposHasEventAggregationSelection";
+ count: Scalars["Int"];
};
-export type MutationCreateRequestMetadataArgs = {
- input: Array;
+export type BamCompleteTemposHasEventAggregateInput = {
+ AND?: InputMaybe>;
+ OR?: InputMaybe>;
+ count?: InputMaybe;
+ count_GT?: InputMaybe;
+ count_GTE?: InputMaybe;
+ count_LT?: InputMaybe;
+ count_LTE?: InputMaybe;
};
-export type MutationCreateRequestsArgs = {
- input: Array;
+export type BamCompleteTemposHasEventConnectFieldInput = {
+ connect?: InputMaybe>;
+ where?: InputMaybe;
};
-export type MutationCreateSampleAliasesArgs = {
- input: Array;
+export type BamCompleteTemposHasEventConnection = {
+ __typename?: "BamCompleteTemposHasEventConnection";
+ edges: Array;
+ pageInfo: PageInfo;
+ totalCount: Scalars["Int"];
};
-export type MutationCreateSampleMetadataArgs = {
- input: Array;
+export type BamCompleteTemposHasEventConnectionWhere = {
+ AND?: InputMaybe>;
+ OR?: InputMaybe>;
+ node?: InputMaybe;
+ node_NOT?: InputMaybe;
};
-export type MutationCreateSamplesArgs = {
- input: Array;
+export type BamCompleteTemposHasEventCreateFieldInput = {
+ node: TempoCreateInput;
};
-export type MutationCreateStatusesArgs = {
- input: Array;
+export type BamCompleteTemposHasEventDeleteFieldInput = {
+ delete?: InputMaybe;
+ where?: InputMaybe;
};
-export type MutationDeletePatientAliasesArgs = {
- delete?: InputMaybe;
- where?: InputMaybe;
+export type BamCompleteTemposHasEventDisconnectFieldInput = {
+ disconnect?: InputMaybe;
+ where?: InputMaybe;
};
-export type MutationDeletePatientsArgs = {
- delete?: InputMaybe;
- where?: InputMaybe;
+export type BamCompleteTemposHasEventFieldInput = {
+ connect?: InputMaybe>;
+ create?: InputMaybe>;
};
-export type MutationDeleteProjectsArgs = {
- delete?: InputMaybe;
- where?: InputMaybe;
+export type BamCompleteTemposHasEventRelationship = {
+ __typename?: "BamCompleteTemposHasEventRelationship";
+ cursor: Scalars["String"];
+ node: Tempo;
+};
+
+export type BamCompleteTemposHasEventUpdateConnectionInput = {
+ node?: InputMaybe;
+};
+
+export type BamCompleteTemposHasEventUpdateFieldInput = {
+ connect?: InputMaybe>;
+ create?: InputMaybe>;
+ delete?: InputMaybe>;
+ disconnect?: InputMaybe>;
+ update?: InputMaybe;
+ where?: InputMaybe;
+};
+
+export type BamCompleteUpdateInput = {
+ date?: InputMaybe;
+ status?: InputMaybe;
+ temposHasEvent?: InputMaybe>;
+};
+
+export type BamCompleteWhere = {
+ AND?: InputMaybe>;
+ OR?: InputMaybe>;
+ date?: InputMaybe;
+ date_CONTAINS?: InputMaybe;
+ date_ENDS_WITH?: InputMaybe;
+ date_IN?: InputMaybe>;
+ date_NOT?: InputMaybe;
+ date_NOT_CONTAINS?: InputMaybe;
+ date_NOT_ENDS_WITH?: InputMaybe;
+ date_NOT_IN?: InputMaybe>;
+ date_NOT_STARTS_WITH?: InputMaybe;
+ date_STARTS_WITH?: InputMaybe;
+ status?: InputMaybe;
+ status_CONTAINS?: InputMaybe;
+ status_ENDS_WITH?: InputMaybe;
+ status_IN?: InputMaybe>;
+ status_NOT?: InputMaybe;
+ status_NOT_CONTAINS?: InputMaybe;
+ status_NOT_ENDS_WITH?: InputMaybe;
+ status_NOT_IN?: InputMaybe>;
+ status_NOT_STARTS_WITH?: InputMaybe;
+ status_STARTS_WITH?: InputMaybe;
+ temposHasEventAggregate?: InputMaybe;
+ temposHasEventConnection_ALL?: InputMaybe;
+ temposHasEventConnection_NONE?: InputMaybe;
+ temposHasEventConnection_SINGLE?: InputMaybe;
+ temposHasEventConnection_SOME?: InputMaybe;
+ /** Return BamCompletes where all of the related Tempos match this filter */
+ temposHasEvent_ALL?: InputMaybe;
+ /** Return BamCompletes where none of the related Tempos match this filter */
+ temposHasEvent_NONE?: InputMaybe;
+ /** Return BamCompletes where one of the related Tempos match this filter */
+ temposHasEvent_SINGLE?: InputMaybe;
+ /** Return BamCompletes where some of the related Tempos match this filter */
+ temposHasEvent_SOME?: InputMaybe;
+};
+
+export type BamCompletesConnection = {
+ __typename?: "BamCompletesConnection";
+ edges: Array;
+ pageInfo: PageInfo;
+ totalCount: Scalars["Int"];
};
-export type MutationDeleteRequestMetadataArgs = {
- delete?: InputMaybe;
- where?: InputMaybe;
+export type Cohort = {
+ __typename?: "Cohort";
+ cohortId: Scalars["String"];
+ hasCohortCompleteCohortCompletes: Array;
+ hasCohortCompleteCohortCompletesAggregate?: Maybe;
+ hasCohortCompleteCohortCompletesConnection: CohortHasCohortCompleteCohortCompletesConnection;
+ hasCohortSampleSamples: Array;
+ hasCohortSampleSamplesAggregate?: Maybe;
+ hasCohortSampleSamplesConnection: CohortHasCohortSampleSamplesConnection;
};
-export type MutationDeleteRequestsArgs = {
- delete?: InputMaybe;
- where?: InputMaybe;
+export type CohortHasCohortCompleteCohortCompletesArgs = {
+ directed?: InputMaybe;
+ options?: InputMaybe;
+ where?: InputMaybe;
};
-export type MutationDeleteSampleAliasesArgs = {
- delete?: InputMaybe;
- where?: InputMaybe;
+export type CohortHasCohortCompleteCohortCompletesAggregateArgs = {
+ directed?: InputMaybe;
+ where?: InputMaybe;
};
-export type MutationDeleteSampleMetadataArgs = {
- delete?: InputMaybe;
- where?: InputMaybe;
+export type CohortHasCohortCompleteCohortCompletesConnectionArgs = {
+ after?: InputMaybe;
+ directed?: InputMaybe;
+ first?: InputMaybe;
+ sort?: InputMaybe<
+ Array
+ >;
+ where?: InputMaybe;
};
-export type MutationDeleteSamplesArgs = {
- delete?: InputMaybe;
+export type CohortHasCohortSampleSamplesArgs = {
+ directed?: InputMaybe;
+ options?: InputMaybe;
where?: InputMaybe;
};
-export type MutationDeleteStatusesArgs = {
- delete?: InputMaybe;
- where?: InputMaybe;
+export type CohortHasCohortSampleSamplesAggregateArgs = {
+ directed?: InputMaybe;
+ where?: InputMaybe;
};
-export type MutationUpdatePatientAliasesArgs = {
- connect?: InputMaybe;
- create?: InputMaybe;
- delete?: InputMaybe;
- disconnect?: InputMaybe;
- update?: InputMaybe;
- where?: InputMaybe;
+export type CohortHasCohortSampleSamplesConnectionArgs = {
+ after?: InputMaybe;
+ directed?: InputMaybe;
+ first?: InputMaybe;
+ sort?: InputMaybe>;
+ where?: InputMaybe;
};
-export type MutationUpdatePatientsArgs = {
- connect?: InputMaybe;
- create?: InputMaybe;
- delete?: InputMaybe;
- disconnect?: InputMaybe;
- update?: InputMaybe;
- where?: InputMaybe;
+export type CohortAggregateSelection = {
+ __typename?: "CohortAggregateSelection";
+ cohortId: StringAggregateSelectionNonNullable;
+ count: Scalars["Int"];
};
-export type MutationUpdateProjectsArgs = {
- connect?: InputMaybe;
- create?: InputMaybe;
- delete?: InputMaybe;
- disconnect?: InputMaybe;
- update?: InputMaybe;
- where?: InputMaybe;
+export type CohortCohortCompleteHasCohortCompleteCohortCompletesAggregationSelection =
+ {
+ __typename?: "CohortCohortCompleteHasCohortCompleteCohortCompletesAggregationSelection";
+ count: Scalars["Int"];
+ node?: Maybe;
+ };
+
+export type CohortCohortCompleteHasCohortCompleteCohortCompletesNodeAggregateSelection =
+ {
+ __typename?: "CohortCohortCompleteHasCohortCompleteCohortCompletesNodeAggregateSelection";
+ analyst: StringAggregateSelectionNullable;
+ date: StringAggregateSelectionNonNullable;
+ projectSubtitle: StringAggregateSelectionNullable;
+ projectTitle: StringAggregateSelectionNullable;
+ status: StringAggregateSelectionNonNullable;
+ type: StringAggregateSelectionNonNullable;
+ };
+
+export type CohortComplete = {
+ __typename?: "CohortComplete";
+ analyst?: Maybe;
+ cohortsHasCohortComplete: Array;
+ cohortsHasCohortCompleteAggregate?: Maybe;
+ cohortsHasCohortCompleteConnection: CohortCompleteCohortsHasCohortCompleteConnection;
+ date: Scalars["String"];
+ endUsers?: Maybe>>;
+ pmUsers?: Maybe>>;
+ projectSubtitle?: Maybe;
+ projectTitle?: Maybe;
+ status: Scalars["String"];
+ type: Scalars["String"];
+};
+
+export type CohortCompleteCohortsHasCohortCompleteArgs = {
+ directed?: InputMaybe;
+ options?: InputMaybe;
+ where?: InputMaybe;
};
-export type MutationUpdateRequestMetadataArgs = {
- connect?: InputMaybe;
- create?: InputMaybe;
- delete?: InputMaybe;
- disconnect?: InputMaybe;
- update?: InputMaybe;
- where?: InputMaybe;
+export type CohortCompleteCohortsHasCohortCompleteAggregateArgs = {
+ directed?: InputMaybe;
+ where?: InputMaybe;
};
-export type MutationUpdateRequestsArgs = {
- connect?: InputMaybe;
- create?: InputMaybe;
- delete?: InputMaybe;
- disconnect?: InputMaybe;
- update?: InputMaybe;
- where?: InputMaybe;
+export type CohortCompleteCohortsHasCohortCompleteConnectionArgs = {
+ after?: InputMaybe;
+ directed?: InputMaybe;
+ first?: InputMaybe;
+ sort?: InputMaybe<
+ Array
+ >;
+ where?: InputMaybe;
};
-export type MutationUpdateSampleAliasesArgs = {
- connect?: InputMaybe;
- create?: InputMaybe;
- delete?: InputMaybe;
- disconnect?: InputMaybe;
- update?: InputMaybe;
- where?: InputMaybe;
+export type CohortCompleteAggregateSelection = {
+ __typename?: "CohortCompleteAggregateSelection";
+ analyst: StringAggregateSelectionNullable;
+ count: Scalars["Int"];
+ date: StringAggregateSelectionNonNullable;
+ projectSubtitle: StringAggregateSelectionNullable;
+ projectTitle: StringAggregateSelectionNullable;
+ status: StringAggregateSelectionNonNullable;
+ type: StringAggregateSelectionNonNullable;
};
-export type MutationUpdateSampleMetadataArgs = {
- connect?: InputMaybe;
- create?: InputMaybe;
- delete?: InputMaybe;
- disconnect?: InputMaybe;
- update?: InputMaybe;
- where?: InputMaybe;
+export type CohortCompleteCohortCohortsHasCohortCompleteAggregationSelection = {
+ __typename?: "CohortCompleteCohortCohortsHasCohortCompleteAggregationSelection";
+ count: Scalars["Int"];
+ node?: Maybe;
};
-export type MutationUpdateSamplesArgs = {
- connect?: InputMaybe;
- create?: InputMaybe;
- delete?: InputMaybe;
- disconnect?: InputMaybe;
- update?: InputMaybe;
- where?: InputMaybe;
+export type CohortCompleteCohortCohortsHasCohortCompleteNodeAggregateSelection =
+ {
+ __typename?: "CohortCompleteCohortCohortsHasCohortCompleteNodeAggregateSelection";
+ cohortId: StringAggregateSelectionNonNullable;
+ };
+
+export type CohortCompleteCohortsHasCohortCompleteAggregateInput = {
+ AND?: InputMaybe>;
+ OR?: InputMaybe>;
+ count?: InputMaybe