Skip to content
Snippets Groups Projects
Commit 1338a0d6 authored by Adrian Orłów's avatar Adrian Orłów
Browse files

feat: merge changes

parents 7088d94a ba85bc5c
No related branches found
No related tags found
2 merge requests!223reset the pin numbers before search results are fetch (so the results will be...,!110feat: add display reaction overlay (MIN-215)
Pipeline #84881 passed
Showing
with 261 additions and 25 deletions
import { useContext } from 'react';
import { Button } from '@/shared/Button';
import { ExportContext } from '../ExportCompound.context';
export const DownloadElements = (): React.ReactNode => {
const { handleDownloadNetwork } = useContext(ExportContext);
return (
<div className="mt-6">
<Button onClick={handleDownloadNetwork}>Download</Button>
</div>
);
};
/* eslint-disable no-magic-numbers */
import { useContext } from 'react';
import { useAppSelector } from '@/redux/hooks/useAppSelector';
import {
compartmentPathwaysDataSelector,
loadingCompartmentPathwaysSelector,
} from '@/redux/compartmentPathways/compartmentPathways.selectors';
import { ZERO } from '@/constants/common';
import { CheckboxFilter } from '../../CheckboxFilter';
import { CollapsibleSection } from '../../CollapsibleSection';
import { getCompartmentPathwaysCheckboxElements } from '../Elements.utils';
import { ExportContext } from '../ExportCompound.context';
import { getCompartmentPathwaysCheckboxElements } from '../utils/getCompartmentPathwaysCheckboxElements';
export const ExcludedCompartmentPathways = (): React.ReactNode => {
const { setExcludedCompartmentPathways } = useContext(ExportContext);
const loadingCompartmentPathways = useAppSelector(loadingCompartmentPathwaysSelector);
const isPending = loadingCompartmentPathways === 'pending';
const compartmentPathways = useAppSelector(compartmentPathwaysDataSelector);
const checkboxElements = getCompartmentPathwaysCheckboxElements(compartmentPathways);
const isCheckboxFilterVisible = !isPending && checkboxElements && checkboxElements.length > 0;
const isCheckboxFilterVisible = !isPending && checkboxElements && checkboxElements.length > ZERO;
return (
<CollapsibleSection title="Select excluded compartment / pathways">
{isPending && <p>Loading...</p>}
{isCheckboxFilterVisible && <CheckboxFilter options={checkboxElements} />}
{isCheckboxFilterVisible && (
<CheckboxFilter
options={checkboxElements}
onCheckedChange={setExcludedCompartmentPathways}
/>
)}
</CollapsibleSection>
);
};
import { ReactNode, useCallback, useMemo, useState } from 'react';
import { useAppSelector } from '@/redux/hooks/useAppSelector';
import { modelsIdsSelector } from '@/redux/models/models.selectors';
import { CheckboxItem } from '../CheckboxFilter/CheckboxFilter.component';
import { Types } from './Types';
import { Columns } from './Columns';
import { Annotations } from './Annotations';
import { ExcludedCompartmentPathways } from './ExcludedCompartmentPathways';
import { IncludedCompartmentPathways } from './IncludedCompartmentPathways ';
import { DownloadElements } from './DownloadElements/DownloadElements';
import { ExportContext } from './ExportCompound.context';
import { getNetworkDownloadBodyRequest } from './utils/getNetworkBodyRequest';
import { getDownloadElementsBodyRequest } from './utils/getDownloadElementsBodyRequest';
type ExportProps = {
children: ReactNode;
};
export const Export = ({ children }: ExportProps): JSX.Element => {
const [types, setTypes] = useState<CheckboxItem[]>([]);
const [columns, setColumns] = useState<CheckboxItem[]>([]);
const [annotations, setAnnotations] = useState<CheckboxItem[]>([]);
const modelIds = useAppSelector(modelsIdsSelector);
const [includedCompartmentPathways, setIncludedCompartmentPathways] = useState<CheckboxItem[]>(
[],
);
const [excludedCompartmentPathways, setExcludedCompartmentPathways] = useState<CheckboxItem[]>(
[],
);
const handleDownloadElements = useCallback(() => {
getDownloadElementsBodyRequest({
types,
columns,
modelIds,
annotations,
includedCompartmentPathways,
excludedCompartmentPathways,
});
}, [
types,
columns,
modelIds,
annotations,
includedCompartmentPathways,
excludedCompartmentPathways,
]);
const handleDownloadNetwork = useCallback(() => {
getNetworkDownloadBodyRequest();
}, []);
const globalContextValue = useMemo(
() => ({
setTypes,
setColumns,
setAnnotations,
setIncludedCompartmentPathways,
setExcludedCompartmentPathways,
handleDownloadElements,
handleDownloadNetwork,
}),
[handleDownloadElements, handleDownloadNetwork],
);
return <ExportContext.Provider value={globalContextValue}>{children}</ExportContext.Provider>;
};
Export.Types = Types;
Export.Columns = Columns;
Export.Annotations = Annotations;
Export.IncludedCompartmentPathways = IncludedCompartmentPathways;
Export.ExcludedCompartmentPathways = ExcludedCompartmentPathways;
Export.DownloadElements = DownloadElements;
import { createContext } from 'react';
import { CheckboxItem } from '../CheckboxFilter/CheckboxFilter.component';
export type ExportContextType = {
setTypes: React.Dispatch<React.SetStateAction<CheckboxItem[]>>;
setColumns: React.Dispatch<React.SetStateAction<CheckboxItem[]>>;
setAnnotations: React.Dispatch<React.SetStateAction<CheckboxItem[]>>;
setIncludedCompartmentPathways: React.Dispatch<React.SetStateAction<CheckboxItem[]>>;
setExcludedCompartmentPathways: React.Dispatch<React.SetStateAction<CheckboxItem[]>>;
handleDownloadElements: () => void;
handleDownloadNetwork: () => void;
};
export const ExportContext = createContext<ExportContextType>({
setTypes: () => {},
setColumns: () => {},
setAnnotations: () => {},
setIncludedCompartmentPathways: () => {},
setExcludedCompartmentPathways: () => {},
handleDownloadElements: () => {},
handleDownloadNetwork: () => {},
});
/* eslint-disable no-magic-numbers */
import { useContext } from 'react';
import {
compartmentPathwaysDataSelector,
loadingCompartmentPathwaysSelector,
} from '@/redux/compartmentPathways/compartmentPathways.selectors';
import { useAppSelector } from '@/redux/hooks/useAppSelector';
import { ZERO } from '@/constants/common';
import { CheckboxFilter } from '../../CheckboxFilter';
import { CollapsibleSection } from '../../CollapsibleSection';
import { getCompartmentPathwaysCheckboxElements } from '../Elements.utils';
import { ExportContext } from '../ExportCompound.context';
import { getCompartmentPathwaysCheckboxElements } from '../utils/getCompartmentPathwaysCheckboxElements';
export const IncludedCompartmentPathways = (): React.ReactNode => {
const { setIncludedCompartmentPathways } = useContext(ExportContext);
const loadingCompartmentPathways = useAppSelector(loadingCompartmentPathwaysSelector);
const isPending = loadingCompartmentPathways === 'pending';
const compartmentPathways = useAppSelector(compartmentPathwaysDataSelector);
......@@ -17,8 +20,11 @@ export const IncludedCompartmentPathways = (): React.ReactNode => {
return (
<CollapsibleSection title="Select included compartment / pathways">
{isPending && <p>Loading...</p>}
{!isPending && checkboxElements && checkboxElements.length > 0 && (
<CheckboxFilter options={checkboxElements} />
{!isPending && checkboxElements && checkboxElements.length > ZERO && (
<CheckboxFilter
options={checkboxElements}
onCheckedChange={setIncludedCompartmentPathways}
/>
)}
</CollapsibleSection>
);
......
import { useContext } from 'react';
import { elementTypesSelector } from '@/redux/configuration/configuration.selectors';
import { useAppSelector } from '@/redux/hooks/useAppSelector';
import { getCheckboxElements } from './Types.utils';
import { CheckboxFilter } from '../../CheckboxFilter';
import { CollapsibleSection } from '../../CollapsibleSection';
import { ExportContext } from '../ExportCompound.context';
export const Types = (): React.ReactNode => {
const { setTypes } = useContext(ExportContext);
const elementTypes = useAppSelector(elementTypesSelector);
const checkboxElements = getCheckboxElements(elementTypes);
return (
<CollapsibleSection title="Select types">
{checkboxElements && <CheckboxFilter options={checkboxElements} isSearchEnabled={false} />}
{checkboxElements && (
<CheckboxFilter
options={checkboxElements}
isSearchEnabled={false}
onCheckedChange={setTypes}
/>
)}
</CollapsibleSection>
);
};
export { Export } from './ExportCompound.component';
/* eslint-disable no-magic-numbers */
import { CompartmentPathwayDetails } from '@/types/models';
import { modelsFixture } from '@/models/fixtures/modelsFixture';
import { getCompartmentPathwaysCheckboxElements, getModelsIds } from './Elements.utils';
import { getCompartmentPathwaysCheckboxElements } from './getCompartmentPathwaysCheckboxElements';
describe('getCompartmentPathwaysCheckboxElements', () => {
it('should return an empty array when given an empty items array', () => {
......@@ -45,17 +44,3 @@ describe('getCompartmentPathwaysCheckboxElements', () => {
]);
});
});
const MODELS_IDS = modelsFixture.map(item => item.idObject);
describe('getModelsIds', () => {
it('should return an empty array if models are not provided', () => {
const result = getModelsIds(undefined);
expect(result).toEqual([]);
});
it('should return an array of model IDs', () => {
const result = getModelsIds(modelsFixture);
expect(result).toEqual(MODELS_IDS);
});
});
/* eslint-disable no-magic-numbers */
import { CompartmentPathwayDetails } from '@/types/models';
type AddedNames = { [key: string]: number };
type CheckboxElement = { id: string; label: string };
type CheckboxElements = CheckboxElement[];
export const getCompartmentPathwaysCheckboxElements = (
items: CompartmentPathwayDetails[],
): CheckboxElements => {
const addedNames: AddedNames = {};
const setNameToIdIfUndefined = (item: CompartmentPathwayDetails): void => {
if (addedNames[item.name] === undefined) {
addedNames[item.name] = item.id;
}
};
items.forEach(setNameToIdIfUndefined);
const parseIdAndLabel = ([name, id]: [name: string, id: number]): CheckboxElement => ({
id: id.toString(),
label: name,
});
const sortByLabel = (a: CheckboxElement, b: CheckboxElement): number => {
if (a.label > b.label) return 1;
return -1;
};
const elements = Object.entries(addedNames).map(parseIdAndLabel).sort(sortByLabel);
return elements;
};
import { getDownloadElementsBodyRequest } from './getDownloadElementsBodyRequest';
describe('getDownloadElementsBodyRequest', () => {
it('should return the correct DownloadBodyRequest object', () => {
const types = [
{ id: '1', label: 'Type 1' },
{ id: '2', label: 'Type 2' },
];
const columns = [
{ id: '1', label: 'Column 1' },
{ id: '2', label: 'Column 2' },
];
// eslint-disable-next-line no-magic-numbers
const modelIds = [1, 2, 3];
const annotations = [
{ id: '1', label: 'Annotation 1' },
{ id: '2', label: 'Annotation 2' },
];
const includedCompartmentPathways = [
{ id: '1', label: 'Compartment 1' },
{ id: '2', label: 'Compartment 2' },
];
const excludedCompartmentPathways = [
{ id: '1', label: 'Compartment 3' },
{ id: '2', label: 'Compartment 4' },
];
const result = getDownloadElementsBodyRequest({
types,
columns,
modelIds,
annotations,
includedCompartmentPathways,
excludedCompartmentPathways,
});
expect(result).toEqual({
types: ['Type 1', 'Type 2'],
columns: ['Column 1', 'Column 2'],
// eslint-disable-next-line no-magic-numbers
submaps: [1, 2, 3],
annotations: ['Annotation 1', 'Annotation 2'],
includedCompartmentIds: ['Compartment 1', 'Compartment 2'],
excludedCompartmentIds: ['Compartment 3', 'Compartment 4'],
});
});
});
import { CheckboxItem } from '../../CheckboxFilter/CheckboxFilter.component';
type DownloadBodyRequest = {
types: string[];
columns: string[];
submaps: number[];
annotations: string[];
includedCompartmentIds: string[];
excludedCompartmentIds: string[];
};
type GetDownloadBodyRequestProps = {
types: CheckboxItem[];
columns: CheckboxItem[];
modelIds: number[];
annotations: CheckboxItem[];
includedCompartmentPathways: CheckboxItem[];
excludedCompartmentPathways: CheckboxItem[];
};
export const getDownloadElementsBodyRequest = ({
types,
columns,
modelIds,
annotations,
includedCompartmentPathways,
excludedCompartmentPathways,
}: GetDownloadBodyRequestProps): DownloadBodyRequest => ({
types: types.map(type => type.label),
columns: columns.map(column => column.label),
submaps: modelIds,
annotations: annotations.map(annotation => annotation.label),
includedCompartmentIds: includedCompartmentPathways.map(compartment => compartment.label),
excludedCompartmentIds: excludedCompartmentPathways.map(compartment => compartment.label),
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment