Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NickAkhmetov/CAT-776 Dataset Relationships diagram #3481

Merged
merged 20 commits into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
346f987
Implement dataset relationships diagram
NickAkhmetov Jul 24, 2024
1c68d39
add changelog
NickAkhmetov Jul 24, 2024
75df5d4
Merge branch 'unified-datasets' into nickakhmetov/dataset-relationships
NickAkhmetov Jul 24, 2024
c77abea
display pipeline names, make processed/component datasets link to app…
NickAkhmetov Jul 25, 2024
986618a
add tests for prov conversion utils, get storybook examples working a…
NickAkhmetov Jul 25, 2024
ce64168
mswdecorator -> mswloader
NickAkhmetov Jul 25, 2024
077c317
minor statusicon revision to resolve runtime styled-components warning
NickAkhmetov Jul 26, 2024
38f868e
fix duplicate key
NickAkhmetov Jul 26, 2024
2f87c75
fix alignment of nodes by setting consistent height, add tracking to …
NickAkhmetov Jul 26, 2024
cdf3a8b
handle image pyramid/publication supports
NickAkhmetov Jul 26, 2024
a7eb451
fix provData validity check
NickAkhmetov Jul 26, 2024
155932d
add provData safety check to provtabs
NickAkhmetov Jul 26, 2024
276cc5e
update fixtures
NickAkhmetov Jul 26, 2024
8bde8c1
resolve issues with stories running before msw loads in storybook
NickAkhmetov Jul 26, 2024
d78427b
Update CHANGELOG-dataset-relationships.md
NickAkhmetov Jul 26, 2024
ff68b98
merge into a single ternary
NickAkhmetov Jul 29, 2024
6cbb9f3
explanatory comments for forbidden dataset/activity type
NickAkhmetov Jul 29, 2024
97222ae
remove unnecessary width/height
NickAkhmetov Jul 29, 2024
33969b1
use theme
NickAkhmetov Jul 29, 2024
b625598
use fetcher
NickAkhmetov Jul 29, 2024
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
1 change: 1 addition & 0 deletions CHANGELOG-dataset-relationships.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Add dataset relationships diagram.
2 changes: 1 addition & 1 deletion context/.storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const config: StorybookConfig = {
'@chromatic-com/storybook',
'@storybook/addon-webpack5-compiler-swc',
],

staticDirs: ['../app/static/assets', '../app/static/storybook-public'],
webpackFinal: async (config) => {
// exclude svgs from the default file loader
config.module?.rules?.forEach((rule) => {
Expand Down
33 changes: 20 additions & 13 deletions context/.storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
import React from 'react';

import Providers from '../app/static/js/components/Providers';
import { initialize, mswDecorator } from 'msw-storybook-addon';
import { initialize, mswLoader } from 'msw-storybook-addon';
import { enableMapSet } from 'immer';


import '@fontsource-variable/inter/files/inter-latin-standard-normal.woff2';

enableMapSet();

const allowConditions = [(url) => String(url).endsWith('thumbnail.jpg')];
initialize({
onUnhandledRequest: ({ method, url }) => {
if (!allowConditions.some((conditionFn) => conditionFn(url))) {
console.error(`Unhandled ${method} request to ${url}.

This exception has been only logged in the console, however, it's strongly recommended to resolve this error as you don't want unmocked data in Storybook stories.

If you wish to mock an error response, please refer to this guide: https://mswjs.io/docs/recipes/mocking-error-responses
`);
serviceWorker: {
options: {
updateViaCache: 'none'
}
},
}
});
export const loaders = [mswLoader]

export const parameters = {
controls: {
Expand All @@ -29,15 +28,23 @@ export const parameters = {
},
};

export const mockEndpoints = { assetsEndpoint: 'https://assets.hubmapconsortium.org' };
export const mockEndpoints = { assetsEndpoint: 'https://assets.hubmapconsortium.org', softAssayEndpoint: '/soft-assay-endpoint' };
export const mockGroupsToken = '';

export const decorators = [
(Story) => (
<Providers endpoints={mockEndpoints} groupsToken={mockGroupsToken} isAuthenticated={false} userEmail={'undefined'} workspacesToken={'undefined'} isWorkspacesUser={false} isHubmapUser={false} flaskData={undefined}>
<Providers endpoints={mockEndpoints} groupsToken={mockGroupsToken} isAuthenticated={false} userEmail={'undefined'} workspacesToken={'undefined'} isWorkspacesUser={false} isHubmapUser={false} flaskData={{}}>
<Story />
</Providers>
),
mswDecorator,
];
export const tags = ['autodocs'];


const preview = {
parameters,
loaders,
decorators,
}

export default preview
1 change: 1 addition & 0 deletions context/app/static/js/components/Contexts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ interface AppContextType {
assetsEndpoint: string;
entityEndpoint: string;
elasticsearchEndpoint: string;
softAssayEndpoint: string;
groupsToken: string;
workspacesToken: string;
workspacesEndpoint: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
import React, { type ComponentProps } from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { type Edge } from '@xyflow/react';
import { http, HttpResponse } from 'msw';

import { DatasetRelationshipsVisualization } from './DatasetRelationships';
import { NodeWithoutPosition } from './types';
import { nodes, edges } from './prov.fixtures';

const singleAssayNodes: NodeWithoutPosition[] = [
{
id: 'HBM123.ABCD.123',
type: 'primaryDataset',
data: {
status: 'published',
name: 'HBM123.ABCD.456',
datasetType: 'CODEX',
},
},
{
id: 'pipeline-cytokit',
type: 'pipeline',
data: {
name: 'Cytokit + SPRM',
singleAssay: true,
},
},
{
id: 'pipeline-segmentation-mask',
type: 'pipeline',
data: {
name: 'Segmentation Mask Action',
description: 'External',
singleAssay: true,
},
},
{
id: 'HBM123.ABCD.456',
type: 'processedDataset',
data: {
name: 'HBM123.ABCD.456',
status: 'published',
},
},
{
id: 'HBM123.ABCD.789',
type: 'processedDataset',
data: {
name: 'HBM123.ABCD.789',
status: 'error',
},
},
];

const singleAssayEdges: Edge[] = [
{
id: 'HBM123.ABCD.123-pipeline-cytokit',
source: 'HBM123.ABCD.123',
target: 'pipeline-cytokit',
},
{
id: 'pipeline-cytokit-HBM123.ABCD.456',
source: 'pipeline-cytokit',
target: 'HBM123.ABCD.456',
},
{
id: 'HBM123.ABCD.123-pipeline-segmentation-mask',
source: 'HBM123.ABCD.123',
target: 'pipeline-segmentation-mask',
},
{
id: 'pipeline-segmentation-mask-HBM123.ABCD.789',
source: 'pipeline-segmentation-mask',
target: 'HBM123.ABCD.789',
},
];

const multiAssayNodes: NodeWithoutPosition[] = [
{
id: 'HBM123.ABCD.123',
type: 'primaryDataset',
data: {
status: 'published',
name: 'HBM123.ABCD.456',
datasetType: 'CODEX',
},
},
{
id: 'pipeline-split',
type: 'pipeline',
data: {
name: 'Multi Assay Split',
childDatasets: ['HBM123.ABCD.555', 'HBM123.ABCD.666'],
},
},
{
id: 'pipeline-salmon-scanpy',
type: 'pipeline',
data: {
name: 'Salmon + Scanpy',
childDatasets: ['HBM123.ABCD.999'],
singleAssay: true,
},
},
{
id: 'HBM123.ABCD.555',
type: 'componentDataset',
data: {
name: 'HBM123.ABCD.555',
status: 'published',
datasetType: 'Capture bead RNAseq (10x Genomics v3)',
},
},
{
id: 'HBM123.ABCD.666',
type: 'componentDataset',
data: {
name: 'HBM123.ABCD.666',
status: 'published',
datasetType: 'H&E Stained Microscopy',
},
},
{
id: 'HBM123.ABCD.999',
type: 'processedDataset',
data: {
name: 'HBM123.ABCD.999',
status: 'published',
datasetType: 'Salmon + Scanpy',
},
},
];

const multiAssayEdges: Edge[] = [
{
id: 'HBM123.ABCD.123-pipeline-split',
source: 'HBM123.ABCD.123',
target: 'pipeline-split',
},
{
id: 'HBM123.ABCD.123-pipeline-salmon-scanpy',
source: 'HBM123.ABCD.123',
target: 'pipeline-salmon-scanpy',
},
{
id: 'pipeline-split-capture-bead-HBM123.ABCD.555',
source: 'pipeline-split',
target: 'HBM123.ABCD.555',
},
{
id: 'pipeline-split-microscopy-HBM123.ABCD.666',
source: 'pipeline-split',
target: 'HBM123.ABCD.666',
},
{
id: 'pipeline-salmon-scanpy-HBM123.ABCD.999',
source: 'pipeline-salmon-scanpy',
target: 'HBM123.ABCD.999',
},
];

function TemplateComponent(args: ComponentProps<typeof DatasetRelationshipsVisualization>) {
return (
<div style={{ height: 600 }}>
<DatasetRelationshipsVisualization {...args} />
</div>
);
}

const salmonScanpySoftAssayResponse = () =>
HttpResponse.json({
assaytype: 'salmon-scanpy',
'contains-pii': false,
description: 'Salmon + Scanpy',
'pipeline-shorthand': 'Salmon + Scanpy',
primary: false,
'vitessce-hints': [],
});

const codexSPRMresponse = () =>
HttpResponse.json({
assaytype: 'codex_cytokit',
'contains-pii': false,
description: 'CODEX [Cytokit + SPRM]',
'pipeline-shorthand': 'Cytokit + SPRM',
primary: false,
'vitessce-hints': ['sprm', 'anndata', 'is_image', 'is_tiled'],
});

const meta: Meta = {
title: 'DatasetRelationships/DatasetRelationships',
component: TemplateComponent,
args: {
nodes: singleAssayNodes,
edges: singleAssayEdges,
},
parameters: {
msw: {
handlers: [http.get('/soft-assay-endpoint/assaytype/HBM123.ABCD.456', codexSPRMresponse)],
},
},
};

export const SingleAssay: StoryObj<typeof TemplateComponent> = {
args: {
nodes: singleAssayNodes,
edges: singleAssayEdges,
},
parameters: {
msw: {
handlers: [http.get('/soft-assay-endpoint/assaytype/HBM123.ABCD.456', codexSPRMresponse)],
},
},
};

export const MultiAssay: StoryObj<typeof TemplateComponent> = {
args: {
nodes: multiAssayNodes,
edges: multiAssayEdges,
},
parameters: {
msw: {
handlers: [http.get('/soft-assay-endpoint/assaytype/HBM123.ABCD.999', salmonScanpySoftAssayResponse)],
},
},
};

export const RealProv: StoryObj<typeof TemplateComponent> = {
args: {
nodes,
edges,
},
parameters: {
msw: {
handlers: [
http.get<{ id: string }>(`/soft-assay-endpoint/assaytype/d8f851efb54f84d7ee0952e10d4c449e`, codexSPRMresponse),
http.get<{ id: string }>(`/soft-assay-endpoint/assaytype/ff77fcae7f6d9b5b7b8741c282677eef`, codexSPRMresponse),
],
},
},
};

export default meta;
Loading
Loading