Skip to content

Commit

Permalink
Refactor species stats types and add link to example variant (#1053)
Browse files Browse the repository at this point in the history
- Added link to example variant on the species page
- Refactored types related to species statistics in speciesGeneralHelper.ts — removed the enums
- Simplified speciesApiSlice — moved the step for munging the data required by the Species page
   into the component responsible for displaying the stats accordion
  • Loading branch information
azangru authored Nov 16, 2023
1 parent c1d1a19 commit 9364e1a
Show file tree
Hide file tree
Showing 3 changed files with 295 additions and 403 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,37 @@ import classNames from 'classnames';

import { useAppDispatch, useAppSelector } from 'src/store';
import useSpeciesAnalytics from '../../hooks/useSpeciesAnalytics';

import ViewInAppPopup from 'src/shared/components/view-in-app-popup/ViewInAppPopup';
import SpeciesStats from 'src/content/app/species/components/species-stats/SpeciesStats';
import ExpandableSection from 'src/shared/components/expandable-section/ExpandableSection';
import QuestionButton from 'src/shared/components/question-button/QuestionButton';
import { useUrlParams } from 'src/shared/hooks/useUrlParams';

import {
getActiveGenomeId,
getActiveGenomeUIState
} from 'src/content/app/species/state/general/speciesGeneralSelectors';
import { getCommittedSpeciesById } from 'src/content/app/species-selector/state/species-selector-general-slice/speciesSelectorGeneralSelectors';

import {
getStatsForSection,
sectionGroupsMap,
speciesStatsSectionNames,
type SpeciesStatsSection,
type StatsSection
} from '../../state/general/speciesGeneralHelper';

import { useGetSpeciesStatisticsQuery } from 'src/content/app/species/state/api/speciesApiSlice';
import { setActiveGenomeExpandedSections } from 'src/content/app/species/state/general/speciesGeneralSlice';
import { useExampleObjectsForGenomeQuery } from 'src/shared/state/genome/genomeApiSlice';

import ViewInAppPopup from 'src/shared/components/view-in-app-popup/ViewInAppPopup';
import SpeciesStats from 'src/content/app/species/components/species-stats/SpeciesStats';
import ExpandableSection from 'src/shared/components/expandable-section/ExpandableSection';
import QuestionButton from 'src/shared/components/question-button/QuestionButton';
import { CircleLoader } from 'src/shared/components/loader';

import type { RootState } from 'src/store';
import type { LinksConfig } from 'src/shared/components/view-in-app/ViewInApp';
import type { CommittedItem } from 'src/content/app/species-selector/types/committedItem';
import {
sectionGroupsMap,
SpeciesStatsSection,
type StatsSection
} from '../../state/general/speciesGeneralHelper';
import type { SpeciesStatistics } from 'src/content/app/species/state/api/speciesApiTypes';
import type { ExampleFocusObject } from 'src/shared/state/genome/genomeTypes';

import styles from './SpeciesMainView.scss';

Expand Down Expand Up @@ -170,14 +178,24 @@ const SpeciesMainViewStats = () => {
const dispatch = useAppDispatch();
const activeGenomeId = useAppSelector(getActiveGenomeId);
const genomeUIState = useAppSelector(getActiveGenomeUIState);
const { genomeId: genomeIdForUrl } = useUrlParams<'genomeId'>(
'/species/:genomeId'
) as { genomeId: string };
const species = useAppSelector((state: RootState) =>
getCommittedSpeciesById(state, activeGenomeId)
);

const { currentData: genomeStats } = useGetSpeciesStatisticsQuery(
{
genomeId: activeGenomeId ?? ''
},
const { currentData: statisticsResponse, isFetching: isFetchingStatistics } =
useGetSpeciesStatisticsQuery(
{
genomeId: activeGenomeId ?? ''
},
{
skip: !activeGenomeId
}
);
const { currentData: exampleObjects } = useExampleObjectsForGenomeQuery(
activeGenomeId ?? '',
{
skip: !activeGenomeId
}
Expand All @@ -188,10 +206,25 @@ const SpeciesMainViewStats = () => {

const expandedSections = genomeUIState ? genomeUIState.expandedSections : [];

if (!genomeStats || !species) {
if (isFetchingStatistics) {
return (
<div className={styles.statsWrapper}>
<CircleLoader />
</div>
);
}
if (!statisticsResponse || !species) {
return null;
}

const { genome_stats: rawGenomeStats } = statisticsResponse;

const genomeStats = prepareStatistics({
statistics: rawGenomeStats,
genomeIdForUrl: genomeIdForUrl,
exampleFocusObjects: exampleObjects ?? []
});

const onSectionToggle = (
section: SpeciesStatsSection,
isExpanded: boolean
Expand Down Expand Up @@ -237,4 +270,25 @@ const SpeciesMainViewStats = () => {
);
};

const prepareStatistics = ({
statistics,
genomeIdForUrl,
exampleFocusObjects
}: {
statistics: SpeciesStatistics;
genomeIdForUrl: string;
exampleFocusObjects: ExampleFocusObject[];
}) => {
return speciesStatsSectionNames
.map((section) =>
getStatsForSection({
allStats: statistics,
genomeIdForUrl,
section: section as SpeciesStatsSection,
exampleFocusObjects
})
)
.filter(Boolean) as StatsSection[];
};

export default SpeciesMainViewStats;
70 changes: 7 additions & 63 deletions src/content/app/species/state/api/speciesApiSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,12 @@
*/

import config from 'config';
import type { FetchBaseQueryError } from '@reduxjs/toolkit/query';

import {
getStatsForSection,
SpeciesStatsSection,
speciesStatsSectionNames,
type StatsSection
} from 'src/content/app/species/state/general/speciesGeneralHelper';

import { getGenomeIdForUrl } from 'src/shared/state/genome/genomeSelectors';

import { fetchExampleObjectsForGenome } from 'src/shared/state/genome/genomeApiSlice';
import restApiSlice from 'src/shared/state/api-slices/restSlice';

import type { RootState } from 'src/store';
import type { SpeciesStatistics } from './speciesApiTypes';
import type { ExampleFocusObject } from 'src/shared/state/genome/genomeTypes';
import type { GenomeInfo } from 'src/shared/state/genome/genomeTypes';

export type GenomeStats = StatsSection[];

type SpeciesStatsQueryParams = {
genomeId: string;
};
Expand All @@ -46,54 +31,13 @@ type SpeciesStatsResponse = {

const speciesApiSlice = restApiSlice.injectEndpoints({
endpoints: (builder) => ({
getSpeciesStatistics: builder.query<GenomeStats, SpeciesStatsQueryParams>({
queryFn: async (params, queryApi, _, baseQuery) => {
const { genomeId } = params;
const { dispatch } = queryApi;

const statsResponsePromise = baseQuery({
url: `${config.metadataApiBaseUrl}/genome/${genomeId}/stats`
});
const exampleObjectsResponsePromise = dispatch(
fetchExampleObjectsForGenome.initiate(genomeId)
);

const [statsReponse, exampleObjectsResponse] = await Promise.all([
statsResponsePromise,
exampleObjectsResponsePromise
]);
exampleObjectsResponsePromise.unsubscribe();

if (statsReponse.data && exampleObjectsResponse.data) {
const statsResponseData = statsReponse.data as SpeciesStatsResponse;
const exampleFocusObjects =
exampleObjectsResponse.data as ExampleFocusObject[];

const state = queryApi.getState() as RootState;
const genomeIdForUrl = getGenomeIdForUrl(state, genomeId) ?? genomeId;

const genomeStats = speciesStatsSectionNames
.map((section) =>
getStatsForSection({
allStats: statsResponseData.genome_stats,
genomeIdForUrl,
section: section as SpeciesStatsSection,
exampleFocusObjects
})
)
.filter(Boolean) as GenomeStats;

return {
data: genomeStats
};
} else {
const error = (statsReponse.error ||
exampleObjectsResponse.error) as FetchBaseQueryError;
return {
error
};
}
}
getSpeciesStatistics: builder.query<
SpeciesStatsResponse,
SpeciesStatsQueryParams
>({
query: (params) => ({
url: `${config.metadataApiBaseUrl}/genome/${params.genomeId}/stats`
})
}),
speciesDetails: builder.query<GenomeInfo, string>({
query: (genomeId) => ({
Expand Down
Loading

0 comments on commit 9364e1a

Please sign in to comment.