Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const AccessionSelector = ({
onRequestData,
open,
status,
table,
}: Props): JSX.Element => {
return (
<StyledDialog
Expand All @@ -36,6 +37,7 @@ export const AccessionSelector = ({
onSubmit: (event: FormEvent<HTMLFormElement>) =>
onRequestData(event, {
onSuccess: () => {
table.resetColumnFilters(); // Clear column filters from previous query.
onContinue();
onClose();
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { OnRequestData, Status } from "../../hooks/UseENA/types";
import { OnRequestData, Status } from "../../hooks/UseENADataByAccession/types";
import { Table } from "@tanstack/react-table";
import { ReadRun } from "../../types";

export interface Props {
clearErrors: () => void;
Expand All @@ -7,4 +9,5 @@ export interface Props {
onRequestData: OnRequestData;
open: boolean;
status: Status;
table: Table<ReadRun>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Table } from "./components/Table/table";
import { RowSelectionState } from "@tanstack/table-core";
import { buildEnaSequencingReads } from "../../utils";
import { ColumnFilters } from "./components/ColumnFilters/columnFilters";
import { preSelectColumnFilters } from "./utils";

export const CollectionSelector = ({
onClose,
Expand All @@ -20,7 +21,12 @@ export const CollectionSelector = ({
const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
return (
<StyledDialog
onTransitionEnter={() => setRowSelection(table.getState().rowSelection)}
onTransitionEnter={() => {
setRowSelection(table.getState().rowSelection);
if (selectedCount > 0) return;
preSelectColumnFilters(table, stepKey);
}}
onClose={onClose}
open={open}
>
<DialogTitle onClose={onClose} title="Select Sequencing Runs" />
Expand All @@ -46,10 +52,19 @@ export const CollectionSelector = ({
onClose();
}}
>
Add {selectedCount ? selectedCount : ""} Sequencing Run
{selectedCount > 1 ? "s" : ""}
{renderButtonText(selectedCount)}
</Button>
</DialogActions>
</StyledDialog>
);
};

/**
* Renders the button text based on the selected count.
* @param selectedCount - The number of selected rows.
* @returns The button text.
*/
function renderButtonText(selectedCount: number): string {
if (selectedCount === 1) return "Add 1 Sequencing Run";
return `Add ${selectedCount} Sequencing Runs`;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { SEQUENCING_DATA_TYPE } from "../../../../types";
import { CATEGORY_CONFIGS } from "./hooks/UseTable/categoryConfigs";

export const PRESELECTED_COLUMN_FILTERS: Record<
SEQUENCING_DATA_TYPE,
Record<string, string[]>
> = {
[SEQUENCING_DATA_TYPE.READ_RUNS_PAIRED]: {
[CATEGORY_CONFIGS.LIBRARY_LAYOUT.key]: ["PAIRED"],
[CATEGORY_CONFIGS.LIBRARY_STRATEGY.key]: ["WGS"],
},
[SEQUENCING_DATA_TYPE.READ_RUNS_SINGLE]: {
[CATEGORY_CONFIGS.LIBRARY_LAYOUT.key]: ["SINGLE"],
[CATEGORY_CONFIGS.LIBRARY_STRATEGY.key]: ["WGS"],
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export const CATEGORY_CONFIGS: Record<string, CategoryConfig> = {
label: "Experiment Accession",
},
FASTQ_FTP: { key: "fastq_ftp", label: "Fastq FTP" },
FIRST_PUBLIC: { key: "first_public", label: "First Public" },
INSTRUMENT_MODEL: { key: "instrument_model", label: "Instrument Model" },
INSTRUMENT_PLATFORM: {
key: "instrument_platform",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ const FASTQ_FTP: ColumnDef<ReadRun> = {
meta: { width: { max: "1.8fr", min: "200px" } },
};

const FIRST_PUBLIC: ColumnDef<ReadRun> = {
accessorKey: CATEGORY_CONFIGS.FIRST_PUBLIC.key,
enableColumnFilter: false,
header: CATEGORY_CONFIGS.FIRST_PUBLIC.label,
meta: META,
};

const INSTRUMENT_MODEL: ColumnDef<ReadRun> = {
accessorKey: CATEGORY_CONFIGS.INSTRUMENT_MODEL.key,
filterFn: SELECT_FILTER_FN,
Expand Down Expand Up @@ -102,6 +109,7 @@ const STUDY_ACCESSION: ColumnDef<ReadRun> = {
export const columns: ColumnDef<ReadRun>[] = [
COLUMN_DEF.ROW_SELECTION as ColumnDef<ReadRun>,
RUN_ACCESSION,
FIRST_PUBLIC,
FASTQ_FTP,
EXPERIMENT_ACCESSION,
SAMPLE_ACCESSION,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {
functionalUpdate,
getCoreRowModel,
getFacetedRowModel,
getFilteredRowModel,
Expand All @@ -14,22 +13,42 @@ import { useCallback, useMemo, useState } from "react";
import { getFacetedUniqueValuesWithArrayValues } from "@databiosphere/findable-ui/lib/components/Table/common/utils";
import { arrIncludesSome } from "@databiosphere/findable-ui/lib/components/Table/columnDef/columnFilters/filterFn";
import { ColumnFiltersState, Updater } from "@tanstack/react-table";
import { UseENADataByAccession } from "../../../../hooks/UseENADataByAccession/types";
import { UseENADataByTaxonomyId } from "../../../../hooks/UseENADataByTaxonomyId/types";
import { ENA_QUERY_METHOD } from "../../../../../../types";
import { updateColumnFilters } from "./utils";

export const useTable = (
readRuns: ReadRun[] | undefined = []
enaQueryMethod: ENA_QUERY_METHOD,
enaAccession: UseENADataByAccession<ReadRun>,
enaTaxonomyId: UseENADataByTaxonomyId<ReadRun>
): Table<ReadRun> => {
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
const [columnFiltersByMethod, setColumnFiltersByMethod] = useState<
Record<ENA_QUERY_METHOD, ColumnFiltersState>
>({
[ENA_QUERY_METHOD.ACCESSION]: [],
[ENA_QUERY_METHOD.TAXONOMY_ID]: [],
});

const onColumnFiltersChange = useCallback(
(updaterOrValue: Updater<ColumnFiltersState>): void => {
setColumnFilters((old) => functionalUpdate(updaterOrValue, old));
},
[setColumnFilters]
(updaterOrValue: Updater<ColumnFiltersState>): void =>
setColumnFiltersByMethod(
updateColumnFilters(enaQueryMethod, updaterOrValue)
),
[enaQueryMethod]
);

const data = useMemo(() => readRuns, [readRuns]);
// Get the data for the ENA query method (by accession or by taxonomy ID).
const { data: readRuns } =
enaQueryMethod === ENA_QUERY_METHOD.ACCESSION
? enaAccession
: enaTaxonomyId;

const data = useMemo(() => readRuns || [], [readRuns]);

const meta = { enaQueryMethod };

const state = { columnFilters };
const state = { columnFilters: columnFiltersByMethod[enaQueryMethod] };

return useReactTable<ReadRun>({
_features: [ROW_POSITION, ROW_PREVIEW],
Expand All @@ -44,6 +63,7 @@ export const useTable = (
getFacetedUniqueValues: getFacetedUniqueValuesWithArrayValues(),
getFilteredRowModel: getFilteredRowModel(),
getRowId: (row) => row.run_accession,
meta,
onColumnFiltersChange,
state,
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {
ColumnFiltersState,
Updater,
functionalUpdate,
} from "@tanstack/react-table";
import { ENA_QUERY_METHOD } from "../../../../../../types";

/**
* Updates the column filters for the specified ENA query method.
* @param enaQueryMethod - ENA query method.
* @param updaterOrValue - Updater or value.
* @returns Updated column filter state for the specified ENA query method.
*/
export function updateColumnFilters(
enaQueryMethod: ENA_QUERY_METHOD,
updaterOrValue: Updater<ColumnFiltersState>
): (
old: Record<ENA_QUERY_METHOD, ColumnFiltersState>
) => Record<ENA_QUERY_METHOD, ColumnFiltersState> {
return (old: Record<ENA_QUERY_METHOD, ColumnFiltersState>) => {
return {
...old,
[enaQueryMethod]: functionalUpdate(updaterOrValue, old[enaQueryMethod]),
};
};
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { ReadRun } from "../../types";
import { OnConfigure } from "../../../../../../../../../../../../../../../views/WorkflowInputsView/hooks/UseConfigureInputs/types";
import { Table } from "@tanstack/react-table";
import { SEQUENCING_DATA_TYPE } from "../../../../types";

export interface Props {
onClose: () => void;
onConfigure: OnConfigure;
open: boolean;
selectedCount: number;
stepKey: "readRunsSingle" | "readRunsPaired";
stepKey: SEQUENCING_DATA_TYPE;
table: Table<ReadRun>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { ENA_QUERY_METHOD, SEQUENCING_DATA_TYPE } from "../../../../types";
import { ColumnFiltersState, Table } from "@tanstack/react-table";
import { ReadRun } from "../../types";
import { PRESELECTED_COLUMN_FILTERS } from "./constants";

/**
* Returns true if the table is using data from ENA query method by taxonomy ID.
* @param table - The table.
* @returns True if the table is using data from ENA query method by taxonomy ID.
*/
function isENAQueryMethodByTaxonomyId(table: Table<ReadRun>): boolean {
if (!table.options.meta) return false;
if (!("enaQueryMethod" in table.options.meta)) return false;

return table.options.meta.enaQueryMethod === ENA_QUERY_METHOD.TAXONOMY_ID;
}

/**
* Pre-selects column filters based on the given step key for ENA query method by taxonomy ID.
* @param table - Table instance.
* @param stepKey - Step key.
*/
export function preSelectColumnFilters(
table: Table<ReadRun>,
stepKey: SEQUENCING_DATA_TYPE
): void {
if (isENAQueryMethodByTaxonomyId(table)) {
const preselectedFilters = PRESELECTED_COLUMN_FILTERS[stepKey];
const columnFiltersState = buildValidatedColumnFilters(
table,
preselectedFilters
);
table.setColumnFilters(columnFiltersState);
}
}

/**
* Builds validated column filters from preselected filter values.
* Filters out columns that don't exist in the table and values that aren't available
* in the column's faceted unique values.
* @param table - Table instance.
* @param preselectedFilters - Record of column IDs to arrays of desired filter values.
* @returns Column filters state.
*/
function buildValidatedColumnFilters(
table: Table<ReadRun>,
preselectedFilters: Record<string, string[]>
): ColumnFiltersState {
const columnFiltersState: ColumnFiltersState = [];

for (const [columnId, desiredValues] of Object.entries(preselectedFilters)) {
const column = table.getColumn(columnId);
if (!column) continue;

const availableValues = column.getFacetedUniqueValues();
const validValues: string[] = [];

// Only include values that exist in the column's faceted data.
for (const value of desiredValues) {
if (!availableValues.has(value)) continue;
validValues.push(value);
}

if (validValues.length === 0) continue;

columnFiltersState.push({ id: columnId, value: validValues });
}

return columnFiltersState;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { PaperProps } from "@mui/material";
import { GridProps, PaperProps } from "@mui/material";

export const MAX_READ_RUNS_FOR_BROWSE_ALL = 200;
export const GRID_PROPS: GridProps = {
alignItems: "center",
container: true,
gap: 4,
};

export const PAPER_PROPS: PaperProps = {
elevation: 0,
Expand Down
Loading
Loading