diff --git a/ui/bedbase-types.d.ts b/ui/bedbase-types.d.ts index 1f790b6..49c16e0 100644 --- a/ui/bedbase-types.d.ts +++ b/ui/bedbase-types.d.ts @@ -329,6 +329,8 @@ export interface components { universe_metadata?: components["schemas"]["UniverseMetadata"] | null; /** Raw Metadata */ raw_metadata?: components["schemas"]["BedPEPHub"] | components["schemas"]["BedPEPHubRestrict"] | null; + /** Bedsets */ + bedsets?: components["schemas"]["BedSetMinimal"][] | null; }; /** BedMetadataBasic */ BedMetadataBasic: { @@ -595,6 +597,15 @@ export interface components { /** Bed Ids */ bed_ids?: string[]; }; + /** BedSetMinimal */ + BedSetMinimal: { + /** Id */ + id: string; + /** Name */ + name?: string | null; + /** Description */ + description?: string | null; + }; /** BedSetPlots */ BedSetPlots: { region_commonality?: components["schemas"]["FileModel"]; diff --git a/ui/package.json b/ui/package.json index 378350d..e54f97a 100644 --- a/ui/package.json +++ b/ui/package.json @@ -8,7 +8,7 @@ "build": "tsc && vite build", "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "preview": "vite preview", - "generate-types": "npx openapi-typescript http://127.0.0.1:8000/openapi.json -o bedbase-types.d.ts" + "generate-types": "npx openapi-typescript https://api-dev.bedbase.org/openapi.json -o bedbase-types.d.ts" }, "dependencies": { "@tanstack/react-query": "^5.28.0", diff --git a/ui/src/components/bed-splash-components/header.tsx b/ui/src/components/bed-splash-components/header.tsx index 59ea7bc..2b72038 100644 --- a/ui/src/components/bed-splash-components/header.tsx +++ b/ui/src/components/bed-splash-components/header.tsx @@ -4,7 +4,7 @@ import { Fragment, useState } from 'react'; import { components } from '../../../bedbase-types'; import { useCopyToClipboard } from '@uidotdev/usehooks'; import { bytesToSize, formatDateTime } from '../../utils'; -import { Dropdown } from 'react-bootstrap'; +import { Dropdown, OverlayTrigger } from 'react-bootstrap'; const API_BASE = import.meta.env.VITE_API_BASE || ''; @@ -45,10 +45,7 @@ export const BedSplashHeader = (props: Props) => { {copiedId ? : } -

- {metadata.name} {' | '} - {metadata.raw_metadata?.global_sample_id || 'No source available'} -

+

{metadata.name}

@@ -148,44 +145,107 @@ export const BedSplashHeader = (props: Props) => {

- -

- + +
+
Genome assembly
+
+ } + > + +
+ + {metadata?.genome_alias || 'No assembly available'} +
+
+

-

- - {metadata?.bed_format || 'No format available'} -
+ +
+
BED file format
+
+ } + > +
+ + {metadata?.bed_format || 'No format available'} +
+

-

- - {metadata?.bed_type || 'No bed type available'} -
+ +
+
BED type
+
+ } + > +
+ + {metadata?.bed_type || 'No bed type available'} +
+

+ {metadata?.is_universe && ( +
+

+ +

+
This BED file is part of the Universe
+
+ } + > +
+ + Universe +
+ +

+
+ )}
- +

Created:{' '} {metadata?.submission_date ? formatDateTime(metadata?.submission_date) : 'No date available'} diff --git a/ui/src/custom.scss b/ui/src/custom.scss index ecf508b..86a5937 100644 --- a/ui/src/custom.scss +++ b/ui/src/custom.scss @@ -113,6 +113,10 @@ a { min-height: 100vh; } +.h-80 { + height: 80%; +} + /* This is for the nav bar */ .hidden { display: none; @@ -148,6 +152,12 @@ a { animation: typing 3.5s steps(40, end), blink-caret 0.75s step-end infinite; } +.truncate { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + /* The typing effect */ @keyframes typing { from { @@ -178,6 +188,10 @@ a { cursor: pointer; } +.cursor-default { + cursor: default; +} + .animate-pulse { animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; } diff --git a/ui/src/pages/bed-splash.tsx b/ui/src/pages/bed-splash.tsx index 6b45737..15ab0e3 100644 --- a/ui/src/pages/bed-splash.tsx +++ b/ui/src/pages/bed-splash.tsx @@ -108,37 +108,75 @@ export const BedSplash = () => { {metadata !== undefined ? : null} -

Overview

- -
- - - - - - - - - {Object.keys(metadata?.raw_metadata || {}).map((k) => { - if (k === 'input_file' || k === 'global_sample_id' || k === 'file_name') { - return null; - // @ts-expect-error wants to get mad because it could be an object and React cant render that (it wont be) - } else if (!metadata?.raw_metadata[k]) { - return null; - } else { - return ( - - - {/* @ts-expect-error wants to get mad because it could be an object and React cant render that (it wont be) */} - - - ); - } - })} - -
KeyValue
{snakeToTitleCase(k)}{metadata?.raw_metadata[k] || 'N/A'}
-
- + + +

Overview

+
+ + + + + + + + + {Object.keys(metadata?.raw_metadata || {}).map((k) => { + if (k === 'input_file' || k === 'file_name' || k === 'sample_name') { + return null; + // @ts-expect-error wants to get mad because it could be an object and React cant render that (it wont be) + } else if (!metadata?.raw_metadata[k]) { + return null; + } else { + return ( + + + + + + ); + } + })} + +
KeyValue
+ {snakeToTitleCase(k)} + + {/* @ts-expect-error wants to get mad because it could be an object and React cant render that (it wont be) */} + {metadata?.raw_metadata[k] || 'N/A'} +
+
+ + +

BED Sets

+
+ + + + + + + + + + + {metadata?.bedsets?.map((bedset) => ( + + + + + + + )) || 'N/A'} + +
BED set IDNameDescriptionView
+ {bedset.id} + + {bedset.name || 'No name'} + {bedset.description || 'No description'} + View +
+
+ +

Statistics

{metadata && ( diff --git a/ui/src/utils.ts b/ui/src/utils.ts index 8546700..fd30eab 100644 --- a/ui/src/utils.ts +++ b/ui/src/utils.ts @@ -2,12 +2,12 @@ type ObjectType = 'bed' | 'bedset'; export const makeHttpDownloadLink = (md5: string) => { const API_BASE = import.meta.env.VITE_API_BASE || ''; - return `${API_BASE}/objects/bed.${md5}.bedfile/access/http`; + return `${API_BASE}/objects/bed.${md5}.bed_file/access/http`; }; export const makeS3DownloadLink = (md5: string) => { const API_BASE = import.meta.env.VITE_BEDHOST_API_URL || ''; - return `${API_BASE}/objects/bed.${md5}.bedfile/access/s3`; + return `${API_BASE}/objects/bed.${md5}.bed_file/access/s3`; }; export const formatNumberWithCommas = (n: number) => {