-
Piotr Gawron authoredPiotr Gawron authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
bioEntity.selectors.ts 11.49 KiB
import { ONE, SIZE_OF_EMPTY_ARRAY, ZERO } from '@/constants/common';
import {
allCommentsSelectorOfCurrentMap,
commentElementSelector,
} from '@/redux/comment/comment.selectors';
import { currentDrawerReactionSelector } from '@/redux/reactions/reactions.selector';
import { rootSelector } from '@/redux/root/root.selectors';
import { BioEntityWithPinType } from '@/types/bioEntity';
import { ElementIdTabObj } from '@/types/elements';
import { MultiSearchData } from '@/types/fetchDataState';
import { BioEntity, BioEntityContent, Comment, MapModel } from '@/types/models';
import { createSelector } from '@reduxjs/toolkit';
import {
allChemicalsBioEntitesOfAllMapsSelector,
allChemicalsBioEntitesOfCurrentMapSelector,
allChemicalsIdTabSelectorOfCurrentMap,
chemicalsBioEntitiesForSelectedSearchElementSelector,
searchedChemicalsBioEntitesOfCurrentMapSelector,
} from '../chemicals/chemicals.selectors';
import { currentSelectedBioEntityIdSelector } from '../contextMenu/contextMenu.selector';
import {
currentSearchedBioEntityId,
currentSelectedSearchElement,
} from '../drawer/drawer.selectors';
import {
allDrugsBioEntitesOfAllMapsSelector,
allDrugsBioEntitesOfCurrentMapSelector,
allDrugsIdTabSelectorOfCurrentMap,
drugsBioEntitiesForSelectedSearchElementSelector,
searchedDrugsBioEntitesOfCurrentMapSelector,
} from '../drugs/drugs.selectors';
import { currentModelIdSelector, modelsDataSelector } from '../models/models.selectors';
export const bioEntitySelector = createSelector(rootSelector, state => state.bioEntity);
export const bioEntityDataSelector = createSelector(bioEntitySelector, bioEntity => bioEntity.data);
export const bioEntityIsContentTabOpenedSelector = createSelector(
bioEntitySelector,
bioEntity => bioEntity.isContentTabOpened,
);
export const bioEntityLoadingSelector = createSelector(
bioEntitySelector,
bioEntity => bioEntity.loading,
);
export const bioEntityDataListSelector = createSelector(bioEntityDataSelector, bioEntityData =>
bioEntityData.map(b => b.data || []).flat(),
);
export const allSubmapConnectionsBioEntitySelector = createSelector(
bioEntitySelector,
(bioEntityData): BioEntity[] => bioEntityData?.submapConnections?.data || [],
);
export const allSubmapConnectionsBioEntityOfCurrentSubmapSelector = createSelector(
allSubmapConnectionsBioEntitySelector,
currentModelIdSelector,
(submapConnectionsBioEntity, currentModel): BioEntity[] =>
submapConnectionsBioEntity.filter(({ model }) => model === currentModel),
);
export const bioEntitiesForSelectedSearchElement = createSelector(
bioEntitySelector,
currentSelectedSearchElement,
(bioEntitiesState, currentSearchElement): MultiSearchData<BioEntityContent[]> | undefined =>
bioEntitiesState.data.find(
({ searchQueryElement }) => searchQueryElement === currentSearchElement,
),
);
export const searchedFromMapBioEntityElement = createSelector(
bioEntitiesForSelectedSearchElement,
currentSearchedBioEntityId,
(bioEntitiesState, currentBioEntityId): BioEntity | undefined =>
bioEntitiesState &&
bioEntitiesState.data?.find(({ bioEntity }) => bioEntity.id === currentBioEntityId)?.bioEntity,
);
export const searchedBioEntityElementForContextMapSelector = createSelector(
bioEntitySelector,
currentSelectedBioEntityIdSelector,
(bioEntitiesState, currentBioEntityId): BioEntity | undefined => {
return bioEntitiesState.data
.find(({ searchQueryElement }) => searchQueryElement === currentBioEntityId.toString())
?.data?.find(({ bioEntity }) => bioEntity.id === currentBioEntityId)?.bioEntity;
},
);
export const searchedBioEntityElementUniProtIdSelector = createSelector(
searchedBioEntityElementForContextMapSelector,
(bioEntitiesState): string | undefined => {
return bioEntitiesState?.references.find(({ type }) => type === 'UNIPROT')?.resource;
},
);
export const searchedFromMapBioEntityElementRelatedSubmapSelector = createSelector(
searchedFromMapBioEntityElement,
modelsDataSelector,
(bioEntity, models): MapModel | undefined =>
models.find(({ idObject }) => idObject === bioEntity?.submodel?.mapId),
);
export const loadingBioEntityStatusSelector = createSelector(
bioEntitiesForSelectedSearchElement,
state => state?.loading,
);
export const searchedBioEntitesSelectorOfCurrentMap = createSelector(
bioEntitySelector,
currentSelectedSearchElement,
currentModelIdSelector,
(bioEntities, currentSearchElement, currentModelId): BioEntity[] => {
if (!bioEntities) {
return [];
}
return (bioEntities?.data || [])
.filter(({ searchQueryElement }) =>
currentSearchElement ? searchQueryElement === currentSearchElement : true,
)
.map(({ data }) => data || [])
.flat()
.filter(({ bioEntity }) => bioEntity.model === currentModelId)
.map(({ bioEntity }) => bioEntity);
},
);
export const allBioEntitesSelectorOfCurrentMap = createSelector(
bioEntitySelector,
currentModelIdSelector,
(bioEntities, currentModelId): BioEntity[] => {
if (!bioEntities) {
return [];
}
return (bioEntities?.data || [])
.map(({ data }) => data || [])
.flat()
.filter(({ bioEntity }) => bioEntity.model === currentModelId)
.map(({ bioEntity }) => bioEntity);
},
);
export const allBioEntitesIdTabSelectorOfCurrentMap = createSelector(
bioEntitySelector,
currentModelIdSelector,
(bioEntities, currentModelId): ElementIdTabObj => {
if (!bioEntities) {
return {};
}
return Object.fromEntries(
(bioEntities?.data || [])
.map(({ data, searchQueryElement }): [typeof data, string] => [data, searchQueryElement])
.map(([data, tab]) =>
(data || [])
.flat()
.filter(({ bioEntity }) => bioEntity.model === currentModelId)
.map(d => [d.bioEntity.id, tab]),
)
.flat(),
);
},
);
export const numberOfBioEntitiesSelector = createSelector(
bioEntitiesForSelectedSearchElement,
state => (state?.data ? state.data.length : SIZE_OF_EMPTY_ARRAY),
);
export const bioEntitiesPerModelSelector = createSelector(
bioEntitiesForSelectedSearchElement,
modelsDataSelector,
(bioEntities, models) => {
const bioEntitiesPerModelPerSearchElement = (models || []).map(model => {
const bioEntitiesInGivenModel = (bioEntities?.data || []).filter(
entity => model.idObject === entity.bioEntity.model,
);
return {
modelName: model.name,
modelId: model.idObject,
numberOfEntities: bioEntitiesInGivenModel.length,
bioEntities: bioEntitiesInGivenModel,
};
});
return bioEntitiesPerModelPerSearchElement.filter(
model => model.numberOfEntities !== SIZE_OF_EMPTY_ARRAY,
);
},
);
export const allVisibleBioEntitiesSelector = createSelector(
searchedBioEntitesSelectorOfCurrentMap,
searchedChemicalsBioEntitesOfCurrentMapSelector,
searchedDrugsBioEntitesOfCurrentMapSelector,
(content, chemicals, drugs): BioEntity[] => {
return [content, chemicals, drugs].flat();
},
);
export const allElementsForSearchElementSelector = createSelector(
bioEntitiesForSelectedSearchElement,
chemicalsBioEntitiesForSelectedSearchElementSelector,
drugsBioEntitiesForSelectedSearchElementSelector,
(content, chemicals, drugs): BioEntity[] => {
const contentBioEntities = (content?.data || []).map(({ bioEntity }) => bioEntity);
return [contentBioEntities, chemicals || [], drugs || []].flat();
},
);
export const allElementsForSearchElementNumberByModelId = createSelector(
allElementsForSearchElementSelector,
(elements): Record<number, number> => {
return elements.reduce(
(acc, { model }) => ({
...acc,
[model]: (acc?.[model] || ZERO) + ONE,
}),
{} as Record<number, number>,
);
},
);
export const allContentBioEntitesSelectorOfAllMaps = createSelector(
bioEntitySelector,
(bioEntities): BioEntity[] => {
if (!bioEntities) {
return [];
}
return (bioEntities?.data || [])
.map(({ data }) => data || [])
.flat()
.map(({ bioEntity }) => bioEntity);
},
);
export const allBioEntitiesSelector = createSelector(
allContentBioEntitesSelectorOfAllMaps,
allChemicalsBioEntitesOfAllMapsSelector,
allDrugsBioEntitesOfAllMapsSelector,
allSubmapConnectionsBioEntitySelector,
(content, chemicals, drugs, submapConnections): BioEntity[] => {
return [content, chemicals, drugs, submapConnections].flat();
},
);
export const allBioEntitiesElementsIdsSelector = createSelector(
allBioEntitesIdTabSelectorOfCurrentMap,
allChemicalsIdTabSelectorOfCurrentMap,
allDrugsIdTabSelectorOfCurrentMap,
(content, chemicals, drugs): ElementIdTabObj => {
return {
...content,
...chemicals,
...drugs,
};
},
);
export const currentDrawerBioEntitySelector = createSelector(
allBioEntitiesSelector,
commentElementSelector,
currentSearchedBioEntityId,
(bioEntities, commentElement, currentBioEntityId): BioEntity | undefined => {
if (commentElement && commentElement.id === currentBioEntityId) {
return commentElement;
}
return bioEntities.find(({ id }) => id === currentBioEntityId);
},
);
export const currentDrawerBioEntityRelatedSubmapSelector = createSelector(
currentDrawerBioEntitySelector,
modelsDataSelector,
(bioEntity, models): MapModel | undefined =>
models.find(({ idObject }) => idObject === bioEntity?.submodel?.mapId),
);
export const allSubmapConnectionsBioEntityOfCurrentSubmapWithRealConnectionsSelector =
createSelector(
allSubmapConnectionsBioEntityOfCurrentSubmapSelector,
allElementsForSearchElementNumberByModelId,
(submapConnectionsBioEntity, modelElementsNumber): BioEntity[] => {
return submapConnectionsBioEntity.filter(
({ submodel }) => submodel && modelElementsNumber?.[submodel.mapId] > ZERO,
);
},
);
export const allBioEntitiesWithTypeOfCurrentMapSelector = createSelector(
allBioEntitesSelectorOfCurrentMap,
allChemicalsBioEntitesOfCurrentMapSelector,
allDrugsBioEntitesOfCurrentMapSelector,
allSubmapConnectionsBioEntityOfCurrentSubmapWithRealConnectionsSelector,
(content, chemicals, drugs, submapConnections): BioEntityWithPinType[] => {
return [
content.map(v => ({ ...v, type: 'bioEntity' as const })),
chemicals.map(v => ({ ...v, type: 'chemicals' as const })),
drugs.map(v => ({ ...v, type: 'drugs' as const })),
submapConnections.map(v => ({ ...v, type: 'bioEntity' as const })),
].flat();
},
);
export const allVisibleBioEntitiesIdsSelector = createSelector(
allVisibleBioEntitiesSelector,
allSubmapConnectionsBioEntityOfCurrentSubmapWithRealConnectionsSelector,
(elements, submapConnections): (string | number)[] => {
return [...elements, ...submapConnections].map(e => e.id);
},
);
export const currentDrawerElementCommentsSelector = createSelector(
currentDrawerBioEntitySelector,
allCommentsSelectorOfCurrentMap,
(element, comments): Comment[] => {
if (element) {
return comments.filter(
comment =>
comment.type === 'ALIAS' &&
comment.modelId === element.model &&
Number(comment.elementId) === element.id,
);
}
return [];
},
);
export const currentDrawerReactionCommentsSelector = createSelector(
currentDrawerReactionSelector,
allCommentsSelectorOfCurrentMap,
(reaction, comments): Comment[] => {
if (reaction) {
return comments.filter(
comment =>
comment.type === 'REACTION' &&
comment.modelId === reaction.modelId &&
Number(comment.elementId) === reaction.id,
);
}
return [];
},
);