From 767f4cc25264edffa42541260b02a5ce616a1b60 Mon Sep 17 00:00:00 2001 From: Colin Diesh Date: Mon, 27 Jan 2025 21:53:19 -0500 Subject: [PATCH] Make any non-bigWig bigType track open as BigBedAdapter in UCSC connections (#4796) --- .github/workflows/push.yml | 8 +- .github/workflows/release.yml | 14 +- .github/workflows/update-docs.yml | 2 +- docs/generateConfigDocs.ts | 2 +- docs/generateStateModelDocs.ts | 2 +- docs/tsconfig.json | 2 + .../src/UCSCTrackHub/ucscTrackHub.ts | 193 ++++++++---------- tsconfig.json | 1 + website/docs/config/BigBedAdapter.md | 2 +- website/docs/config/VcfAdapter.md | 19 +- website/docs/config/VcfTabixAdapter.md | 14 ++ website/docs/models/AddTrackModel.md | 14 ++ website/docs/models/DotplotView.md | 23 ++- website/docs/models/FacetedModel.md | 15 +- website/docs/models/LinearComparativeView.md | 16 ++ website/docs/models/LinearGenomeView.md | 14 +- website/docs/models/LinearSyntenyView.md | 29 ++- .../docs/models/LinearVariantMatrixDisplay.md | 47 ++++- .../docs/models/MultiLinearVariantDisplay.md | 4 +- 19 files changed, 276 insertions(+), 145 deletions(-) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 16cb812e74..99048bbc01 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -12,7 +12,7 @@ jobs: persist-credentials: false - uses: actions/setup-node@v4 with: - node-version: '20' + node-version: '22' - name: Install website deps (with cache) uses: bahmutov/npm-install@v1 with: @@ -37,7 +37,7 @@ jobs: persist-credentials: false - uses: actions/setup-node@v4 with: - node-version: '20' + node-version: '22' - name: Install deps (with cache) uses: bahmutov/npm-install@v1 - name: Build codebase @@ -69,7 +69,7 @@ jobs: persist-credentials: false - uses: actions/setup-node@v4 with: - node-version: '20' + node-version: '22' - name: Install deps (with cache) uses: bahmutov/npm-install@v1 - name: Build project @@ -153,7 +153,7 @@ jobs: persist-credentials: false - uses: actions/setup-node@v4 with: - node-version: '20' + node-version: '22' - name: Install deps and build (with cache) uses: bahmutov/npm-install@v1 - name: Check codebase format diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c9d2a8de3c..65999f1644 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,10 +23,10 @@ jobs: - uses: actions/checkout@v4 with: persist-credentials: false - - name: Use Node.js 20 + - name: Use Node.js 22 uses: actions/setup-node@v4 with: - node-version: '20' + node-version: '22' - name: Set env run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV - name: Install deps @@ -53,7 +53,7 @@ jobs: name: Build Windows desktop app runs-on: ubuntu-latest container: - image: docker://node:20-bullseye + image: docker://node:22-bullseye steps: - uses: actions/checkout@v4 with: @@ -107,10 +107,10 @@ jobs: with: persist-credentials: false - - name: Use Node.js 20 + - name: Use Node.js 22 uses: actions/setup-node@v4 with: - node-version: '20' + node-version: '22' - name: Install build deps run: | brew install pkg-config cairo pango libpng jpeg giflib librsvg @@ -135,10 +135,10 @@ jobs: with: persist-credentials: false - - name: Use Node.js 20 + - name: Use Node.js 22 uses: actions/setup-node@v4 with: - node-version: '20' + node-version: '22' - name: Install deps (with cache) uses: bahmutov/npm-install@v1 - name: Install build deps diff --git a/.github/workflows/update-docs.yml b/.github/workflows/update-docs.yml index 5bde164c70..dfe777107d 100644 --- a/.github/workflows/update-docs.yml +++ b/.github/workflows/update-docs.yml @@ -14,7 +14,7 @@ jobs: persist-credentials: false - uses: actions/setup-node@v4 with: - node-version: '20' + node-version: '22' - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v4 with: diff --git a/docs/generateConfigDocs.ts b/docs/generateConfigDocs.ts index 9452852e5b..7c185fc9fe 100644 --- a/docs/generateConfigDocs.ts +++ b/docs/generateConfigDocs.ts @@ -8,7 +8,7 @@ import { getAllFiles, removeComments, rm, -} from './util' +} from './util.ts' interface Derives { name: string diff --git a/docs/generateStateModelDocs.ts b/docs/generateStateModelDocs.ts index d49f490663..2739a4ae2e 100644 --- a/docs/generateStateModelDocs.ts +++ b/docs/generateStateModelDocs.ts @@ -8,7 +8,7 @@ import { getAllFiles, removeComments, rm, -} from './util' +} from './util.ts' interface Action { name: string diff --git a/docs/tsconfig.json b/docs/tsconfig.json index ba24224072..09c976facf 100644 --- a/docs/tsconfig.json +++ b/docs/tsconfig.json @@ -10,6 +10,8 @@ "strict": true, "declaration": true, "module": "commonjs", + "noEmit": true, + "allowImportingTsExtensions": true, "moduleResolution": "node" }, "include": ["generateConfigDocs.ts", "generateStateModelDocs.ts", "util.ts"] diff --git a/plugins/data-management/src/UCSCTrackHub/ucscTrackHub.ts b/plugins/data-management/src/UCSCTrackHub/ucscTrackHub.ts index bdb840d26e..247bfd0418 100644 --- a/plugins/data-management/src/UCSCTrackHub/ucscTrackHub.ts +++ b/plugins/data-management/src/UCSCTrackHub/ucscTrackHub.ts @@ -38,25 +38,24 @@ export function generateTracks({ parentTracks.push(trackDb.data[currentTrackName]) } } while (currentTrackName) - parentTracks.reverse() - const categories = parentTracks - .map(p => p?.data.shortLabel) - .filter((f): f is string => !!f) - const res = makeTrackConfig({ + return makeTrackConfig({ track, - categories, trackDbLoc, trackDb, sequenceAdapter, + categories: parentTracks + .reverse() + .map(p => p?.data.shortLabel) + .filter((f): f is string => !!f), }) - return { - ...res, - trackId: `ucsc-trackhub-${objectHash(res)}`, - assemblyNames: [assemblyName], - } } }) .filter(notEmpty) + .map(r => ({ + ...r, + trackId: `ucsc-trackhub-${objectHash(r)}`, + assemblyNames: [assemblyName], + })) } function makeTrackConfig({ @@ -90,98 +89,87 @@ function makeTrackConfig({ ? makeLoc(bigDataUrl, trackDbLoc) : makeLoc2(bigDataUrl) - switch (baseTrackType) { - case 'bam': - return { - type: 'AlignmentsTrack', - name, - description: data.longLabel, - category: categories, - adapter: { - type: 'BamAdapter', - bamLocation: bigDataLocation, - index: { - location: isUri - ? makeLocAlt(bigDataIdx, `${bigDataUrl}.bai`, trackDbLoc) - : makeLoc2(bigDataIdx, `${bigDataUrl}.bai`), - }, + if (baseTrackType === 'bam') { + return { + type: 'AlignmentsTrack', + name, + description: data.longLabel, + category: categories, + adapter: { + type: 'BamAdapter', + bamLocation: bigDataLocation, + index: { + location: isUri + ? makeLocAlt(bigDataIdx, `${bigDataUrl}.bai`, trackDbLoc) + : makeLoc2(bigDataIdx, `${bigDataUrl}.bai`), }, - } - - case 'cram': - return { - type: 'AlignmentsTrack', - name, - description: data.longLabel, - category: categories, - adapter: { - type: 'CramAdapter', - cramLocation: bigDataLocation, - craiLocation: isUri - ? makeLocAlt(bigDataIdx, `${bigDataUrl}.crai`, trackDbLoc) - : makeLoc2(bigDataIdx, `${bigDataUrl}.crai`), - sequenceAdapter, - }, - } - case 'bigBarChart': - case 'bigBed': - case 'bigGenePred': - case 'bigChain': - case 'bigInteract': - case 'bigMaf': - case 'bigNarrowPeak': - case 'bigPsl': - return { - type: 'FeatureTrack', - name, - description: data.longLabel, - category: categories, - adapter: { - type: 'BigBedAdapter', - bigBedLocation: bigDataLocation, - }, - } - case 'bigWig': - return { - type: 'QuantitativeTrack', - name, - description: data.longLabel, - category: categories, - adapter: { - type: 'BigWigAdapter', - bigWigLocation: bigDataLocation, + }, + } + } else if (baseTrackType === 'cram') { + return { + type: 'AlignmentsTrack', + name, + description: data.longLabel, + category: categories, + adapter: { + type: 'CramAdapter', + cramLocation: bigDataLocation, + craiLocation: isUri + ? makeLocAlt(bigDataIdx, `${bigDataUrl}.crai`, trackDbLoc) + : makeLoc2(bigDataIdx, `${bigDataUrl}.crai`), + sequenceAdapter, + }, + } + } else if (baseTrackType === 'bigWig') { + return { + type: 'QuantitativeTrack', + name, + description: data.longLabel, + category: categories, + adapter: { + type: 'BigWigAdapter', + bigWigLocation: bigDataLocation, + }, + } + } else if (baseTrackType.startsWith('big')) { + return { + type: 'FeatureTrack', + name, + description: data.longLabel, + category: categories, + adapter: { + type: 'BigBedAdapter', + bigBedLocation: bigDataLocation, + }, + } + } else if (baseTrackType === 'vcfTabix') { + return { + type: 'VariantTrack', + name, + description: data.longLabel, + category: categories, + adapter: { + type: 'VcfTabixAdapter', + vcfGzLocation: bigDataLocation, + index: { + location: isUri + ? makeLocAlt(bigDataIdx, `${bigDataUrl}.tbi`, trackDbLoc) + : makeLoc2(bigDataIdx, `${bigDataUrl}.tbi`), }, - } - - case 'vcfTabix': - return { - type: 'VariantTrack', - name, - description: data.longLabel, - category: categories, - adapter: { - type: 'VcfTabixAdapter', - vcfGzLocation: bigDataLocation, - index: { - location: isUri - ? makeLocAlt(bigDataIdx, `${bigDataUrl}.tbi`, trackDbLoc) - : makeLoc2(bigDataIdx, `${bigDataUrl}.tbi`), - }, - }, - } - - case 'hic': - return { - type: 'HicTrack', - name, - description: data.longLabel, - category: categories, - adapter: { - type: 'HicAdapter', - hicLocation: bigDataLocation, - }, - } - + }, + } + } else if (baseTrackType === 'hic') { + return { + type: 'HicTrack', + name, + description: data.longLabel, + category: categories, + adapter: { + type: 'HicAdapter', + hicLocation: bigDataLocation, + }, + } + } else { // unsupported types // case 'peptideMapping': // case 'gvf': @@ -196,8 +184,7 @@ function makeTrackConfig({ // case 'bedRnaElements': // case 'broadPeak': // case 'coloredExon': - default: - return generateUnknownTrackConf(name, baseTrackType, categories) + return generateUnknownTrackConf(name, baseTrackType, categories) } } diff --git a/tsconfig.json b/tsconfig.json index 6b1be69954..932535f6e3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -22,6 +22,7 @@ }, "exclude": [ "**/build/", + "**/docs/", "**/dist/", "**/esm/", "**/lib/", diff --git a/website/docs/config/BigBedAdapter.md b/website/docs/config/BigBedAdapter.md index e48d205cb9..28f14c1064 100644 --- a/website/docs/config/BigBedAdapter.md +++ b/website/docs/config/BigBedAdapter.md @@ -45,6 +45,6 @@ scoreColumn: { aggregateField: { type: 'string', description: 'An attribute to aggregate features with', - defaultValue: 'geneName', + defaultValue: 'geneName2', } ``` diff --git a/website/docs/config/VcfAdapter.md b/website/docs/config/VcfAdapter.md index d1eeb6b4d3..8a5be280cd 100644 --- a/website/docs/config/VcfAdapter.md +++ b/website/docs/config/VcfAdapter.md @@ -25,6 +25,23 @@ reference the markdown files in our repo of the checked out git tag ```js vcfLocation: { type: 'fileLocation', - defaultValue: { uri: '/path/to/my.vcf', locationType: 'UriLocation' }, + defaultValue: { + uri: '/path/to/my.vcf', + locationType: 'UriLocation', + }, + } +``` + +#### slot: samplesTsvLocation + +```js +samplesTsvLocation: { + type: 'fileLocation', + defaultValue: { + uri: '/path/to/samples.tsv', + description: + 'tsv with header like name\tpopulation\tetc. where the first column is required, and is the sample names', + locationType: 'UriLocation', + }, } ``` diff --git a/website/docs/config/VcfTabixAdapter.md b/website/docs/config/VcfTabixAdapter.md index 20b298a47e..ce9c19b58c 100644 --- a/website/docs/config/VcfTabixAdapter.md +++ b/website/docs/config/VcfTabixAdapter.md @@ -50,3 +50,17 @@ location: { }, } ``` + +#### slot: samplesTsvLocation + +```js +samplesTsvLocation: { + type: 'fileLocation', + defaultValue: { + uri: '/path/to/samples.tsv', + description: + 'tsv with header like name\tpopulation\tetc. where the first column is required, and is the sample names', + locationType: 'UriLocation', + }, + } +``` diff --git a/website/docs/models/AddTrackModel.md b/website/docs/models/AddTrackModel.md index bb9b4b628f..26fc118599 100644 --- a/website/docs/models/AddTrackModel.md +++ b/website/docs/models/AddTrackModel.md @@ -130,6 +130,13 @@ boolean any ``` +#### getter: trackAdapterType + +```js +// type +any +``` + #### getter: trackType ```js @@ -137,6 +144,13 @@ any string ``` +#### getter: trackConfig + +```js +// type +any +``` + #### getter: warningMessage ```js diff --git a/website/docs/models/DotplotView.md b/website/docs/models/DotplotView.md index bcbc90ac70..ff668d3b24 100644 --- a/website/docs/models/DotplotView.md +++ b/website/docs/models/DotplotView.md @@ -258,11 +258,32 @@ renderProps: () => any ```js // type signature -menuItems: () => ({ label: string; onClick: () => void; icon: OverridableComponent> & { muiName: string; }; } | { label: string; onClick: () => void; icon?: undefined; } | { ...; })[] +menuItems: () => ({ label: string; icon: OverridableComponent> & { muiName: string; }; onClick: () => void; } | { label: string; onClick: () => Widget; icon: (props: SvgIconProps) => Element; })[] ``` ### DotplotView - Actions +#### action: importFormRemoveRow + +```js +// type signature +importFormRemoveRow: (idx: number) => void +``` + +#### action: clearImportFormSyntenyTracks + +```js +// type signature +clearImportFormSyntenyTracks: () => void +``` + +#### action: setImportFormSyntenyTrack + +```js +// type signature +setImportFormSyntenyTrack: (arg: number, val: ImportFormSyntenyTrack) => void +``` + #### action: setShowPanButtons ```js diff --git a/website/docs/models/FacetedModel.md b/website/docs/models/FacetedModel.md index 969b25268c..4c632aa7cd 100644 --- a/website/docs/models/FacetedModel.md +++ b/website/docs/models/FacetedModel.md @@ -38,7 +38,7 @@ filterText: types.optional(types.string, '') IOptionalIType, [undefined]> // code showSparse: types.optional(types.boolean, () => - JSON.parse(localStorageGetItem('facet-showSparse') || 'false'), + localStorageGetBoolean('facet-showSparse', false), ) ``` @@ -49,7 +49,7 @@ showSparse: types.optional(types.boolean, () => IOptionalIType, [undefined]> // code showFilters: types.optional(types.boolean, () => - JSON.parse(localStorageGetItem('facet-showFilters') || 'true'), + localStorageGetBoolean('facet-showFilters', true), ) ``` @@ -60,7 +60,7 @@ showFilters: types.optional(types.boolean, () => IOptionalIType, [undefined]> // code showOptions: types.optional(types.boolean, () => - JSON.parse(localStorageGetItem('facet-showTableOptions') || 'false'), + localStorageGetBoolean('facet-showTableOptions', false), ) ``` @@ -71,7 +71,7 @@ showOptions: types.optional(types.boolean, () => IOptionalIType, [undefined]> // code panelWidth: types.optional(types.number, () => - JSON.parse(localStorageGetItem('facet-panelWidth') || '400'), + localStorageGetNumber('facet-panelWidth', 400), ) ``` @@ -105,6 +105,13 @@ string[] | readonly ["category", "adapter", "description"] any[] ``` +#### getter: filteredMetadataKeys + +```js +// type +any +``` + #### getter: fields ```js diff --git a/website/docs/models/LinearComparativeView.md b/website/docs/models/LinearComparativeView.md index 55e4276e1e..01a6c63a0b 100644 --- a/website/docs/models/LinearComparativeView.md +++ b/website/docs/models/LinearComparativeView.md @@ -62,6 +62,15 @@ true showIntraviewLinks: true ``` +#### property: linkViews + +```js +// type signature +false +// code +linkViews: false +``` + #### property: interactiveOverlay ```js @@ -187,6 +196,13 @@ removeView: (view: { id: string; displayName: string; minimized: boolean; type: setLevelHeight: (newHeight: number, level?: number) => number ``` +#### action: setLinkViews + +```js +// type signature +setLinkViews: (arg: boolean) => void +``` + #### action: activateTrackSelector ```js diff --git a/website/docs/models/LinearGenomeView.md b/website/docs/models/LinearGenomeView.md index 40578fc5a6..cb18efbd15 100644 --- a/website/docs/models/LinearGenomeView.md +++ b/website/docs/models/LinearGenomeView.md @@ -144,9 +144,7 @@ show the "center line" IOptionalIType, [undefined]> // code showCenterLine: types.optional(types.boolean, () => - Boolean( - JSON.parse(localStorageGetItem('lgv-showCenterLine') || 'false'), - ), + localStorageGetBoolean('lgv-showCenterLine', false), ) ``` @@ -159,9 +157,7 @@ show the "cytobands" in the overview scale bar IOptionalIType, [undefined]> // code showCytobandsSetting: types.optional(types.boolean, () => - Boolean( - JSON.parse(localStorageGetItem('lgv-showCytobands') || 'true'), - ), + localStorageGetBoolean('lgv-showCytobands', true), ) ``` @@ -216,7 +212,7 @@ color by CDS IOptionalIType, [undefined]> // code colorByCDS: types.optional(types.boolean, () => - Boolean(JSON.parse(localStorageGetItem('lgv-colorByCDS') || 'false')), + localStorageGetBoolean('lgv-colorByCDS', false), ) ``` @@ -229,9 +225,7 @@ color by CDS IOptionalIType, [undefined]> // code showTrackOutlines: types.optional(types.boolean, () => - Boolean( - JSON.parse(localStorageGetItem('lgv-showTrackOutlines') || 'true'), - ), + localStorageGetBoolean('lgv-showTrackOutlines', true), ) ``` diff --git a/website/docs/models/LinearSyntenyView.md b/website/docs/models/LinearSyntenyView.md index b2dcd10285..6aeaf9d4dc 100644 --- a/website/docs/models/LinearSyntenyView.md +++ b/website/docs/models/LinearSyntenyView.md @@ -74,18 +74,39 @@ menuItems: () => (MenuDivider | MenuSubHeader | NormalMenuItem | CheckboxMenuIte ### LinearSyntenyView - Actions -#### action: toggleCurves +#### action: importFormRemoveRow ```js // type signature -toggleCurves: () => void +importFormRemoveRow: (idx: number) => void ``` -#### action: toggleCIGAR +#### action: clearImportFormSyntenyTracks ```js // type signature -toggleCIGAR: () => void +clearImportFormSyntenyTracks: () => void +``` + +#### action: setImportFormSyntenyTrack + +```js +// type signature +setImportFormSyntenyTrack: (arg: number, val: ImportFormSyntenyTrack) => void +``` + +#### action: setDrawCurves + +```js +// type signature +setDrawCurves: (arg: boolean) => void +``` + +#### action: setDrawCIGAR + +```js +// type signature +setDrawCIGAR: (arg: boolean) => void ``` #### action: showAllRegions diff --git a/website/docs/models/LinearVariantMatrixDisplay.md b/website/docs/models/LinearVariantMatrixDisplay.md index 2b5097456a..f96b918f0a 100644 --- a/website/docs/models/LinearVariantMatrixDisplay.md +++ b/website/docs/models/LinearVariantMatrixDisplay.md @@ -22,7 +22,7 @@ reference the markdown files in our repo of the checked out git tag extends -- [LinearBasicDisplay](../linearbasicdisplay) +- [LinearBareDisplay](../linearbaredisplay) ### LinearVariantMatrixDisplay - Properties @@ -53,13 +53,13 @@ AnyConfigurationSchemaType configuration: ConfigurationReference(configSchema) ``` -#### property: mafFilter +#### property: minorAlleleFrequencyFilter ```js // type signature IOptionalIType, [undefined]> // code -mafFilter: types.optional(types.number, 0.1) +minorAlleleFrequencyFilter: types.optional(types.number, 0.1) ``` #### property: showSidebarLabelsSetting @@ -71,13 +71,29 @@ true showSidebarLabelsSetting: true ``` +#### property: phasedMode + +```js +// type signature +IOptionalIType, [undefined]> +// code +phasedMode: types.optional(types.string, 'none') +``` + ### LinearVariantMatrixDisplay - Getters +#### getter: preSources + +```js +// type +Source[] +``` + #### getter: sources ```js // type -any +any[] ``` #### getter: blockType @@ -121,7 +137,7 @@ adapterProps: () => any ```js // type signature -trackMenuItems: () => (MenuDivider | MenuSubHeader | NormalMenuItem | CheckboxMenuItem | RadioMenuItem | SubMenuItem | { ...; })[] +trackMenuItems: () => (MenuDivider | MenuSubHeader | NormalMenuItem | CheckboxMenuItem | RadioMenuItem | SubMenuItem | { ...; } | { ...; })[] ``` #### method: renderProps @@ -182,6 +198,27 @@ setMafFilter: (arg: number) => void setShowSidebarLabels: (arg: boolean) => void ``` +#### action: setPhasedMode + +```js +// type signature +setPhasedMode: (arg: string) => void +``` + +#### action: setHasPhased + +```js +// type signature +setHasPhased: (arg: boolean) => void +``` + +#### action: setSamplePloidy + +```js +// type signature +setSamplePloidy: (arg: Record) => void +``` + #### action: renderSvg ```js diff --git a/website/docs/models/MultiLinearVariantDisplay.md b/website/docs/models/MultiLinearVariantDisplay.md index aabe9230c4..d769355604 100644 --- a/website/docs/models/MultiLinearVariantDisplay.md +++ b/website/docs/models/MultiLinearVariantDisplay.md @@ -22,7 +22,7 @@ reference the markdown files in our repo of the checked out git tag extends -- [SharedVariantMixin](../sharedvariantmixin) +- [LinearBareDisplay](../linearbaredisplay) ### MultiLinearVariantDisplay - Properties @@ -95,7 +95,7 @@ React.ComponentType ```js // type -{ color: string; baseUri?: string; name: string; group?: string; }[] +{ [x: string]: unknown; baseUri?: string; name: string; label?: string; color?: string; group?: string; HP?: number; }[] ``` #### getter: rowHeight