From a4e807e72e75824eba935f1088a6625b71056450 Mon Sep 17 00:00:00 2001 From: Nikolay Akhmetov Date: Tue, 8 Oct 2024 10:49:17 -0400 Subject: [PATCH 1/4] NickAkhmetov/CAT-854 Deduplicate pipelines list in processed data section --- .../ProcessedData/ProcessedData.tsx | 9 ++++--- .../detailPage/ProcessedData/hooks.spec.ts | 8 +++++- .../detailPage/ProcessedData/hooks.ts | 25 +++++++++++++++++++ 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/context/app/static/js/components/detailPage/ProcessedData/ProcessedData.tsx b/context/app/static/js/components/detailPage/ProcessedData/ProcessedData.tsx index 7f66fd1ef9..c4851cc524 100644 --- a/context/app/static/js/components/detailPage/ProcessedData/ProcessedData.tsx +++ b/context/app/static/js/components/detailPage/ProcessedData/ProcessedData.tsx @@ -6,15 +6,16 @@ import { sectionIconMap } from 'js/shared-styles/icons/sectionIconMap'; import ProcessedDataset from './ProcessedDataset'; import { SectionDescription } from './ProcessedDataset/SectionDescription'; import HelperPanel from './HelperPanel'; -import { useSortedSearchHits } from './hooks'; +import { usePipelineCountsInfo, useSortedSearchHits } from './hooks'; import CollapsibleDetailPageSection from '../DetailPageSection/CollapsibleDetailPageSection'; function ProcessedDataSection() { const processedDatasets = useProcessedDatasets(); const sortedSearchHits = useSortedSearchHits(processedDatasets.searchHits); - const pipelines = processedDatasets?.searchHits.map((dataset) => dataset._source.pipeline); - const pipelinesText = `Pipelines (${pipelines.length})`; + const { pipelinesText, pipelineCountsText } = usePipelineCountsInfo( + processedDatasets.searchHits.map((dataset) => dataset._source), + ); return ( {pipelines.join(', ')}} + addendum={{pipelineCountsText}} > This section lists analyses generated based on this dataset. These analyses are represented as processed datasets and are either generated by HuBMAP using uniform processing pipelines or by an external processing diff --git a/context/app/static/js/components/detailPage/ProcessedData/hooks.spec.ts b/context/app/static/js/components/detailPage/ProcessedData/hooks.spec.ts index 73044052ed..94be7ce629 100644 --- a/context/app/static/js/components/detailPage/ProcessedData/hooks.spec.ts +++ b/context/app/static/js/components/detailPage/ProcessedData/hooks.spec.ts @@ -1,6 +1,6 @@ import { CreationAction } from 'js/components/types'; import { renderHook } from 'test-utils/functions'; -import { useSortedSearchHits, createdByCentralProcess, datasetIsPublished } from './hooks'; +import { useSortedSearchHits, createdByCentralProcess, datasetIsPublished, usePipelineCountsInfo } from './hooks'; const testDatasets: { _id: string; @@ -93,3 +93,9 @@ it('checks if dataset is published', () => { expect(datasetIsPublished(testDatasets[1]._source)).toBe(true); expect(datasetIsPublished(testDatasets[2]._source)).toBe(true); }); + +it('counts pipelines and their occurrences', () => { + const { pipelinesText, pipelineCountsText } = usePipelineCountsInfo(testDatasets.map((dataset) => dataset._source)); + expect(pipelinesText).toBe('Pipelines (2)'); + expect(pipelineCountsText).toBe('Cytokit + SPRM (2), Segmentation Mask (1)'); +}); diff --git a/context/app/static/js/components/detailPage/ProcessedData/hooks.ts b/context/app/static/js/components/detailPage/ProcessedData/hooks.ts index d22bc6d739..a32cf15261 100644 --- a/context/app/static/js/components/detailPage/ProcessedData/hooks.ts +++ b/context/app/static/js/components/detailPage/ProcessedData/hooks.ts @@ -37,3 +37,28 @@ export function useSortedSearchHits(datasets: ReturnType[]) { + const pipelines = datasets.map((dataset) => dataset.pipeline); + const pipelineCounts = pipelines.reduce( + (acc, pipeline) => { + acc[pipeline] = (acc[pipeline] || 0) + 1; + return acc; + }, + {} as Record, + ); + const pipelinesText = `Pipelines (${Object.keys(pipelineCounts).length})`; + const pipelineCountsText = Object.entries(pipelineCounts) + .map(([pipeline, count]) => `${pipeline} (${count})`) + .join(', '); + + return { + pipelinesText, + pipelineCountsText, + }; +} From c52954bd275326317858a63053fb5c4fb362e390 Mon Sep 17 00:00:00 2001 From: Nikolay Akhmetov Date: Tue, 8 Oct 2024 10:50:57 -0400 Subject: [PATCH 2/4] add changelog --- CHANGELOG-cat-854.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 CHANGELOG-cat-854.md diff --git a/CHANGELOG-cat-854.md b/CHANGELOG-cat-854.md new file mode 100644 index 0000000000..653238e500 --- /dev/null +++ b/CHANGELOG-cat-854.md @@ -0,0 +1 @@ +- Improve readability of pipeline list in processed dataset sections. From c981781ef032fe9dca3749c93dc4a183c565da64 Mon Sep 17 00:00:00 2001 From: Nikolay Akhmetov Date: Tue, 8 Oct 2024 10:53:52 -0400 Subject: [PATCH 3/4] only include counts after pipeline names if there is more than one instance --- .../static/js/components/detailPage/ProcessedData/hooks.spec.ts | 2 +- .../app/static/js/components/detailPage/ProcessedData/hooks.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/context/app/static/js/components/detailPage/ProcessedData/hooks.spec.ts b/context/app/static/js/components/detailPage/ProcessedData/hooks.spec.ts index 94be7ce629..6936a01233 100644 --- a/context/app/static/js/components/detailPage/ProcessedData/hooks.spec.ts +++ b/context/app/static/js/components/detailPage/ProcessedData/hooks.spec.ts @@ -97,5 +97,5 @@ it('checks if dataset is published', () => { it('counts pipelines and their occurrences', () => { const { pipelinesText, pipelineCountsText } = usePipelineCountsInfo(testDatasets.map((dataset) => dataset._source)); expect(pipelinesText).toBe('Pipelines (2)'); - expect(pipelineCountsText).toBe('Cytokit + SPRM (2), Segmentation Mask (1)'); + expect(pipelineCountsText).toBe('Cytokit + SPRM (2), Segmentation Mask'); }); diff --git a/context/app/static/js/components/detailPage/ProcessedData/hooks.ts b/context/app/static/js/components/detailPage/ProcessedData/hooks.ts index a32cf15261..1b9d402a81 100644 --- a/context/app/static/js/components/detailPage/ProcessedData/hooks.ts +++ b/context/app/static/js/components/detailPage/ProcessedData/hooks.ts @@ -54,7 +54,7 @@ export function usePipelineCountsInfo(datasets: Pick `${pipeline} (${count})`) + .map(([pipeline, count]) => (count > 1 ? `${pipeline} (${count})` : pipeline)) .join(', '); return { From 596c998d57fbe69c7f38492d1cafdd5caab04dd6 Mon Sep 17 00:00:00 2001 From: Nikolay Akhmetov Date: Tue, 8 Oct 2024 13:02:44 -0400 Subject: [PATCH 4/4] use `generateCommaList` --- .../js/components/detailPage/ProcessedData/hooks.spec.ts | 2 +- .../static/js/components/detailPage/ProcessedData/hooks.ts | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/context/app/static/js/components/detailPage/ProcessedData/hooks.spec.ts b/context/app/static/js/components/detailPage/ProcessedData/hooks.spec.ts index 6936a01233..d934986388 100644 --- a/context/app/static/js/components/detailPage/ProcessedData/hooks.spec.ts +++ b/context/app/static/js/components/detailPage/ProcessedData/hooks.spec.ts @@ -97,5 +97,5 @@ it('checks if dataset is published', () => { it('counts pipelines and their occurrences', () => { const { pipelinesText, pipelineCountsText } = usePipelineCountsInfo(testDatasets.map((dataset) => dataset._source)); expect(pipelinesText).toBe('Pipelines (2)'); - expect(pipelineCountsText).toBe('Cytokit + SPRM (2), Segmentation Mask'); + expect(pipelineCountsText).toBe('Cytokit + SPRM (2) and Segmentation Mask'); }); diff --git a/context/app/static/js/components/detailPage/ProcessedData/hooks.ts b/context/app/static/js/components/detailPage/ProcessedData/hooks.ts index 1b9d402a81..17a20ac091 100644 --- a/context/app/static/js/components/detailPage/ProcessedData/hooks.ts +++ b/context/app/static/js/components/detailPage/ProcessedData/hooks.ts @@ -1,5 +1,6 @@ import { useMemo } from 'react'; import { ProcessedDatasetInfo, useProcessedDatasets } from 'js/pages/Dataset/hooks'; +import { generateCommaList } from 'js/helpers/functions'; export function createdByCentralProcess(dataset: Pick) { return dataset.creation_action === 'Central Process'; @@ -53,9 +54,9 @@ export function usePipelineCountsInfo(datasets: Pick, ); const pipelinesText = `Pipelines (${Object.keys(pipelineCounts).length})`; - const pipelineCountsText = Object.entries(pipelineCounts) - .map(([pipeline, count]) => (count > 1 ? `${pipeline} (${count})` : pipeline)) - .join(', '); + const pipelineCountsText = generateCommaList( + Object.entries(pipelineCounts).map(([pipeline, count]) => (count > 1 ? `${pipeline} (${count})` : pipeline)), + ); return { pipelinesText,