Skip to content

Commit

Permalink
Merge branch 'mvp-2.1.0' of https://github.com/CBIIT/crdc-datahub-ui
Browse files Browse the repository at this point in the history
…into CRDCDH-654
  • Loading branch information
Alejandro-Vega committed Jan 17, 2024
2 parents 3db2408 + 7b5c82e commit e17280d
Show file tree
Hide file tree
Showing 14 changed files with 468 additions and 48 deletions.
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ REACT_APP_NIH_REDIRECT_URL=""
REACT_APP_BACKEND_API=""
REACT_APP_DEV_TIER=""

# Uploader CLI Release
REACT_APP_UPLOADER_CLI=""

# Optional - Specify default port
# PORT=3010

Expand Down
1 change: 1 addition & 0 deletions conf/inject.template.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ window.injectedEnv = {
REACT_APP_BACKEND_PUBLIC_API: '${REACT_APP_BACKEND_PUBLIC_API}',
REACT_APP_AUTH: '${REACT_APP_AUTH}',
REACT_APP_DEV_TIER: '${DEV_TIER}',
REACT_APP_UPLOADER_CLI: '${REACT_APP_UPLOADER_CLI}',
PUBLIC_ACCESS: '${PUBLIC_ACCESS}',
NODE_LEVEL_ACCESS:'${NODE_LEVEL_ACCESS}',
NODE_LABEL: '${NODE_LABEL}'
Expand Down
9 changes: 5 additions & 4 deletions public/injectEnv.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
window.injectedEnv = {
NIH_AUTHORIZE_URL: '',
NIH_CLIENT_ID: '',
NIH_REDIRECT_URL: '',
REACT_APP_DEV_TIER: ''
REACT_APP_NIH_AUTHORIZE_URL: '',
REACT_APP_NIH_CLIENT_ID: '',
REACT_APP_NIH_REDIRECT_URL: '',
REACT_APP_DEV_TIER: '',
REACT_APP_UPLOADER_CLI: '',
};
7 changes: 7 additions & 0 deletions src/components/DataSubmissions/GenericTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ export type FetchListing<T> = {

export type TableMethods = {
refresh: () => void;
setPage: (page: number, forceRefetch?: boolean) => void;
};

type Props<T> = {
Expand Down Expand Up @@ -193,6 +194,12 @@ const GenericTable = <T,>({
useImperativeHandle(ref, () => ({
refresh: () => {
fetchData(true);
},
setPage: (newPage: number, forceRefetch = false) => {
setPage(newPage);
if (forceRefetch) {
fetchData(true);
}
}
}));

Expand Down
122 changes: 122 additions & 0 deletions src/components/Organizations/ConfirmDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { FC } from "react";
import {
Button, Dialog, DialogActions, DialogContent, DialogProps,
IconButton, Typography, styled,
} from "@mui/material";
import { ReactComponent as CloseIconSvg } from "../../assets/icons/close_icon.svg";

const StyledDialog = styled(Dialog)({
"& .MuiDialog-paper": {
maxWidth: "none",
borderRadius: "8px",
width: "755px !important",
padding: "47px 59px 71px 54px",
border: "2px solid #0B7F99",
background: "linear-gradient(0deg, #F2F6FA 0%, #F2F6FA 100%), #2E4D7B",
boxShadow: "0px 4px 45px 0px rgba(0, 0, 0, 0.40)",
},
});

const StyledDialogContent = styled(DialogContent)({
padding: 0,
});

const StyledBodyText = styled(Typography)({
fontFamily: "'Nunito', 'Rubik', sans-serif !important",
fontSize: "16px !important",
fontStyle: "normal",
fontWeight: "400 !important",
lineHeight: "19.6px !important",
marginBottom: "28px !important",
letterSpacing: "unset !important",
});

const StyledDialogActions = styled(DialogActions)({
padding: "0 !important",
justifyContent: "center",
});

const StyledCloseDialogButton = styled(IconButton)(() => ({
position: 'absolute !important' as 'absolute',
right: "21px",
top: "11px",
padding: "10px",
"& svg": {
color: "#44627C"
}
}));

const StyledActionButton = styled(Button)({
minWidth: "128px",
height: "42px",
padding: "12px !important",
borderRadius: "8px !important",
border: "1px solid #000 !important",
color: "#000 !important",
textAlign: "center",
fontFamily: "'Nunito', 'Rubik', sans-serif !important",
fontSize: "16px !important",
fontStyle: "normal",
fontWeight: "700 !important",
lineHeight: "24px !important",
letterSpacing: "0.32px",
textTransform: "none !important" as 'none',
alignSelf: "center",
margin: "0 15px !important",
marginTop: "45px !important",
"&:hover": {
background: "transparent !important",
}
});

type Props = {
onClose?: () => void;
onSubmit?: () => void;
} & Omit<DialogProps, "onClose">;

const ConfirmDialog: FC<Props> = ({
title,
onClose,
onSubmit,
open,
...rest
}) => (
<StyledDialog
open={open}
onClose={() => onClose?.()}
{...rest}
>
<StyledCloseDialogButton
aria-label="close"
onClick={() => onClose?.()}
>
<CloseIconSvg />
</StyledCloseDialogButton>
<StyledDialogContent>
<StyledBodyText id="confirm-dialog-body" variant="h6">
Currently, there are active data submissions for this study within this organization.
{" "}
Are you sure you want to remove this study from the organization?
</StyledBodyText>
</StyledDialogContent>
<StyledDialogActions>
<StyledActionButton
id="uploader-cli-submit-button"
variant="outlined"
sx={{ width: "186px" }}
onClick={onSubmit}
>
Confirm to Remove
</StyledActionButton>
<StyledActionButton
id="uploader-cli-cancel-button"
variant="outlined"
onClick={onClose}
>
Cancel
</StyledActionButton>
</StyledDialogActions>
</StyledDialog>
);

export default ConfirmDialog;
170 changes: 163 additions & 7 deletions src/content/dataSubmissions/QualityControl.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import { useMemo, useRef, useState } from "react";
import { useLazyQuery } from "@apollo/client";
import { FC, useEffect, useMemo, useRef, useState } from "react";
import { useLazyQuery, useQuery } from "@apollo/client";
import { useParams } from "react-router-dom";
import { isEqual } from "lodash";
import { Box, Button, styled } from "@mui/material";
import { SUBMISSION_QC_RESULTS, SubmissionQCResultsResp } from "../../graphql";
import { Box, Button, FormControl, MenuItem, Select, styled } from "@mui/material";
import { Controller, useForm } from 'react-hook-form';
import { LIST_BATCHES, LIST_NODE_TYPES, ListBatchesResp, ListNodeTypesResp, SUBMISSION_QC_RESULTS, SubmissionQCResultsResp } from "../../graphql";
import GenericTable, { Column, FetchListing, TableMethods } from "../../components/DataSubmissions/GenericTable";
import { FormatDate } from "../../utils";
import ErrorDialog from "./ErrorDialog";
import QCResultsContext from "./Contexts/QCResultsContext";

type FilterForm = {
nodeType: string | "All";
batchID: number | "All";
severity: QCResult["severity"] | "All";
};

const StyledErrorDetailsButton = styled(Button)({
display: "inline",
color: "#0D78C5",
Expand Down Expand Up @@ -42,6 +49,58 @@ const StyledBreakAll = styled(Box)({
wordBreak: "break-all"
});

const StyledFilterContainer = styled(Box)({
display: "flex",
alignItems: "center",
justifyContent: "flex-start",
marginBottom: "19px",
paddingLeft: "24px",
});

const StyledFormControl = styled(FormControl)({
margin: "10px",
marginRight: "15px",
minWidth: "250px",
});

const StyledInlineLabel = styled('label')({
padding: "0 10px",
fontWeight: "700"
});

const baseTextFieldStyles = {
borderRadius: "8px",
"& .MuiInputBase-input": {
fontWeight: 400,
fontSize: "16px",
fontFamily: "'Nunito', 'Rubik', sans-serif",
padding: "10px",
height: "20px",
},
"& .MuiOutlinedInput-notchedOutline": {
borderColor: "#6B7294",
},
"&.Mui-focused .MuiOutlinedInput-notchedOutline": {
border: "1px solid #209D7D",
boxShadow: "2px 2px 4px 0px rgba(38, 184, 147, 0.10), -1px -1px 6px 0px rgba(38, 184, 147, 0.20)",
},
"& .Mui-disabled": {
cursor: "not-allowed",
},
"& .MuiList-root": {
padding: "0 !important",
},
"& .MuiMenuItem-root.Mui-selected": {
background: "#3E7E6D !important",
color: "#FFFFFF !important",
},
"& .MuiMenuItem-root:hover": {
background: "#D5EDE5",
},
};

const StyledSelect = styled(Select)(baseTextFieldStyles);

const columns: Column<QCResult>[] = [
{
label: "Type",
Expand Down Expand Up @@ -100,8 +159,9 @@ const columns: Column<QCResult>[] = [
},
];

const QualityControl = () => {
const QualityControl: FC = () => {
const { submissionId } = useParams();
const { watch, control } = useForm<FilterForm>();

const [loading, setLoading] = useState<boolean>(false);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
Expand All @@ -116,7 +176,26 @@ const QualityControl = () => {
const [submissionQCResults] = useLazyQuery<SubmissionQCResultsResp>(SUBMISSION_QC_RESULTS, {
variables: { id: submissionId },
context: { clientName: 'backend' },
fetchPolicy: 'no-cache'
fetchPolicy: 'cache-and-network',
});

const { data: batchData } = useQuery<ListBatchesResp>(LIST_BATCHES, {
variables: {
submissionID: submissionId,
first: -1,
offset: 0,
partial: true,
orderBy: "displayID",
sortDirection: "asc",
},
context: { clientName: 'backend' },
fetchPolicy: 'cache-and-network',
});

const { data: nodeTypes } = useQuery<ListNodeTypesResp>(LIST_NODE_TYPES, {
variables: { _id: submissionId, },
context: { clientName: 'backend' },
fetchPolicy: 'cache-and-network',
});

const handleFetchQCResults = async (fetchListing: FetchListing<QCResult>, force: boolean) => {
Expand All @@ -133,13 +212,19 @@ const QualityControl = () => {

try {
setLoading(true);

const nodeType = watch("nodeType");
const batchID = watch("batchID");
const { data: d, error } = await submissionQCResults({
variables: {
submissionID: submissionId,
first,
offset,
sortDirection,
orderBy
orderBy,
nodeTypes: !nodeType || nodeType === "All" ? undefined : [watch("nodeType")],
batchIDs: !batchID || batchID === "All" ? undefined : [watch("batchID")],
severities: watch("severity") || "All",
},
context: { clientName: 'backend' },
fetchPolicy: 'no-cache'
Expand All @@ -166,8 +251,79 @@ const QualityControl = () => {
handleOpenErrorDialog
}), [handleOpenErrorDialog]);

useEffect(() => {
tableRef.current?.setPage(0, true);
}, [watch("nodeType"), watch("batchID"), watch("severity")]);

return (
<>
<StyledFilterContainer>
<StyledInlineLabel htmlFor="nodeType-filter">Node Type</StyledInlineLabel>
<StyledFormControl>
<Controller
name="nodeType"
control={control}
render={({ field }) => (
<StyledSelect
{...field}
defaultValue="All"
value={field.value || "All"}
MenuProps={{ disablePortal: true }}
inputProps={{ id: "nodeType-filter" }}
>
<MenuItem value="All">All</MenuItem>
{nodeTypes?.listSubmissionNodeTypes?.map((nodeType) => (
<MenuItem key={nodeType} value={nodeType}>{nodeType}</MenuItem>
))}
</StyledSelect>
)}
/>
</StyledFormControl>
<StyledInlineLabel htmlFor="batchID-filter">Batch ID</StyledInlineLabel>
<StyledFormControl>
<Controller
name="batchID"
control={control}
render={({ field }) => (
<StyledSelect
{...field}
defaultValue="All"
value={field.value || "All"}
MenuProps={{ disablePortal: true }}
inputProps={{ id: "batchID-filter" }}
>
<MenuItem value="All">All</MenuItem>
{batchData?.listBatches?.batches?.map((batch) => (
<MenuItem key={batch._id} value={batch._id}>
{batch.displayID}
{` (${FormatDate(batch.createdAt, "MM/DD/YYYY")})`}
</MenuItem>
))}
</StyledSelect>
)}
/>
</StyledFormControl>
<StyledInlineLabel htmlFor="severity-filter">Severity</StyledInlineLabel>
<StyledFormControl>
<Controller
name="severity"
control={control}
render={({ field }) => (
<StyledSelect
{...field}
defaultValue="All"
value={field.value || "All"}
MenuProps={{ disablePortal: true }}
inputProps={{ id: "severity-filter" }}
>
<MenuItem value="All">All</MenuItem>
<MenuItem value="Error">Error</MenuItem>
<MenuItem value="Warning">Warning</MenuItem>
</StyledSelect>
)}
/>
</StyledFormControl>
</StyledFilterContainer>
<QCResultsContext.Provider value={providerValue}>
<GenericTable
ref={tableRef}
Expand Down
Loading

0 comments on commit e17280d

Please sign in to comment.