Skip to content

Commit

Permalink
Refactor RecordsList and SamplesList (#103)
Browse files Browse the repository at this point in the history
* Create a set of shared components for RecordsList and SamplesList

* Replace duplicate elements in RecordsList with newly created shared components

* Replace duplicate elements in SamplesList with newly created shared components
  • Loading branch information
qu8n authored Dec 1, 2023
1 parent a7f0d5c commit 86b3810
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 189 deletions.
100 changes: 19 additions & 81 deletions frontend/src/components/RecordsList.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import AutoSizer from "react-virtualized-auto-sizer";
import { Button, Col, Container, Form, Row, Modal } from "react-bootstrap";
import { Button, Container, Modal } from "react-bootstrap";
import { FunctionComponent, useMemo } from "react";
import { useNavigate } from "react-router-dom";
import classNames from "classnames";
import { DownloadModal } from "./DownloadModal";
import Spinner from "react-spinkit";
import { CSVFormulate } from "../lib/CSVExport";
import { AgGridReact } from "ag-grid-react";
import { useState } from "react";
Expand All @@ -17,9 +15,8 @@ import { useHookGeneric } from "../shared/types";
import { SamplesList } from "./SamplesList";
import { SampleWhere } from "../generated/graphql";
import { defaultRecordsColDef } from "../shared/helpers";
import InfoIcon from "@material-ui/icons/InfoOutlined";
import { Tooltip } from "@material-ui/core";
import { PatientIdsTriplet } from "../pages/patients/PatientsPage";
import { ErrorMessage, LoadingSpinner, Toolbar } from "../shared/tableElements";

export interface IRecordsListProps {
lazyRecordsQuery: typeof useHookGeneric;
Expand Down Expand Up @@ -119,14 +116,9 @@ const RecordsList: FunctionComponent<IRecordsListProps> = ({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [searchVal]);

if (loading)
return (
<div className={"centralSpinner"}>
<Spinner fadeIn={"none"} color={"lightblue"} name="ball-grid-pulse" />
</div>
);
if (loading) return <LoadingSpinner />;

if (error) return <p>Error :(</p>;
if (error) return <ErrorMessage error={error} />;

const remoteCount = data?.[totalCountNodeName]?.totalCount;

Expand Down Expand Up @@ -224,76 +216,22 @@ const RecordsList: FunctionComponent<IRecordsListProps> = ({
</AutoSizer>
)}

<Row
className={classNames(
"d-flex justify-content-between align-items-center",
"tableControlsRow"
)}
>
<Col></Col>

<Col md="auto">
<Form.Control
className={"d-inline-block"}
style={{ width: "300px" }}
type="search"
placeholder={"Search " + searchTerm}
aria-label="Search"
defaultValue={inputVal}
onKeyDown={(event) => {
if (event.key === "Enter") {
handleSearch();
}
}}
onInput={(event) => {
const newVal = event.currentTarget.value;
if (newVal === "") {
setCustomFilterVals && setCustomFilterVals([]);
setSearchVal([]);
}
setInputVal(newVal);
}}
/>
</Col>

<Col md="auto" style={{ marginLeft: -15 }}>
<Tooltip
title={
<span style={{ fontSize: 12 }}>
After inputting your search query, click on &quot;Search&quot;
or press &quot;Enter&quot; to get your results. To bulk search,
input a list of values separated by spaces or commas (e.g.
&quot;value1 value2 value3&quot;)
</span>
}
>
<InfoIcon style={{ fontSize: 18, color: "grey" }} />
</Tooltip>
</Col>

<Col md="auto" style={{ marginLeft: -15 }}>
<Button
onClick={handleSearch}
className={"btn btn-secondary"}
size={"sm"}
>
Search
</Button>
</Col>

<Col md="auto">
{remoteCount?.toLocaleString()} matching{" "}
{remoteCount > 1 ? searchTerm : searchTerm.slice(0, -1)}
</Col>

{customFilterUI}
<Toolbar
searchTerm={searchTerm}
input={inputVal}
setInput={setInputVal}
handleSearch={handleSearch}
clearInput={() => {
setCustomFilterVals && setCustomFilterVals([]);
setSearchVal([]);
}}
matchingResultsCount={`${remoteCount?.toLocaleString()} matching ${
remoteCount > 1 ? searchTerm : searchTerm.slice(0, -1)
}`}
handleDownload={handleDownload}
customUI={customFilterUI}
/>

<Col className={"text-end"}>
<Button onClick={handleDownload} size={"sm"}>
Generate Report
</Button>
</Col>
</Row>
<AutoSizer>
{({ width }) => (
<div
Expand Down
154 changes: 46 additions & 108 deletions frontend/src/components/SamplesList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import {
SampleMetadataWhere,
} from "../generated/graphql";
import AutoSizer from "react-virtualized-auto-sizer";
import { Button, Col, Form, Row } from "react-bootstrap";
import classNames from "classnames";
import { Button, Col } from "react-bootstrap";
import { FunctionComponent, useEffect, useRef } from "react";
import { DownloadModal } from "./DownloadModal";
import { UpdateModal } from "./UpdateModal";
Expand All @@ -18,16 +17,14 @@ import {
SampleChange,
SampleMetadataExtended,
} from "../shared/helpers";
import Spinner from "react-spinkit";
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 { Tooltip } from "@material-ui/core";
import InfoIcon from "@material-ui/icons/InfoOutlined";
import { parseSearchQueries } from "../lib/parseSearchQueries";
import { ErrorMessage, LoadingSpinner, Toolbar } from "../shared/tableElements";

const POLLING_INTERVAL = 2000;
const max_rows = 500;
Expand Down Expand Up @@ -159,14 +156,9 @@ export const SamplesList: FunctionComponent<ISampleListProps> = ({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [searchVal]);

if (loading)
return (
<div className={"centralSpinner"}>
<Spinner fadeIn={"none"} color={"lightblue"} name="ball-grid-pulse" />
</div>
);
if (loading) return <LoadingSpinner />;

if (error) return <Row>Error loading request details / request samples</Row>;
if (error) return <ErrorMessage error={error} />;

const samples = data!.samplesConnection.edges.map((e) => e.node) as Sample[];

Expand Down Expand Up @@ -249,104 +241,50 @@ export const SamplesList: FunctionComponent<ISampleListProps> = ({
}
/>

<Row
className={classNames(
"d-flex justify-content-between align-items-center tableControlsRow"
)}
>
<Col></Col>
<Col className={"text-end"}>
<Form.Control
className={"d-inline-block"}
style={{ width: "300px" }}
type="search"
placeholder="Search samples"
aria-label="Search"
value={val}
onKeyDown={(event) => {
if (event.key === "Enter") {
setSearchVal(val);
}
}}
onInput={(event) => {
const newVal = event.currentTarget.value;
if (newVal === "") {
setSearchVal("");
}
setVal(newVal);
}}
/>
</Col>

<Col md="auto" style={{ marginLeft: -15 }}>
<Tooltip
title={
<span style={{ fontSize: 12 }}>
After inputting your search query, click on &quot;Search&quot;
or press &quot;Enter&quot; to get your results. To bulk search,
input a list of values separated by spaces or commas (e.g.
&quot;value1 value2 value3&quot;)
</span>
}
>
<InfoIcon style={{ fontSize: 18, color: "grey" }} />
</Tooltip>
</Col>

<Col md="auto" style={{ marginLeft: -15 }}>
<Button
onClick={() => {
setSearchVal(val);
}}
className={"btn btn-secondary"}
size={"sm"}
>
Search
</Button>
</Col>

<Col className={"text-start"}>
{remoteCount === max_rows
<Toolbar
searchTerm={"samples"}
input={val}
setInput={setVal}
handleSearch={() => {
setSearchVal(val);
}}
clearInput={() => {
setSearchVal("");
}}
matchingResultsCount={
remoteCount === max_rows
? `${max_rows}+ matching samples`
: `${remoteCount} matching samples`}
</Col>

{changes.length > 0 && (
<>
<Col className={"text-end"}>
<Button
className={"btn btn-secondary"}
onClick={handleDiscardChanges}
size={"sm"}
>
Discard Changes
</Button>
</Col>
<Col className={"text-start"}>
<Button
className={"btn btn-success"}
onClick={() => {
setShowUpdateModal(true);
}}
size={"sm"}
>
Submit Updates
</Button>
</Col>
</>
)}
: `${remoteCount} matching samples`
}
handleDownload={() => setShowDownloadModal(true)}
customUI={
changes.length > 0 ? (
<>
<Col className={"text-end"}>
<Button
className={"btn btn-secondary"}
onClick={handleDiscardChanges}
size={"sm"}
>
Discard Changes
</Button>
</Col>

<Col className={"text-end"}>
<Button
onClick={() => {
setShowDownloadModal(true);
}}
size={"sm"}
>
Generate Report
</Button>
</Col>
</Row>
<Col className={"text-start"}>
<Button
className={"btn btn-success"}
onClick={() => {
setShowUpdateModal(true);
}}
size={"sm"}
>
Submit Updates
</Button>
</Col>
</>
) : undefined
}
/>

<AutoSizer>
{({ width }) => (
Expand Down
Loading

0 comments on commit 86b3810

Please sign in to comment.