Skip to content

Commit 0e7b1bf

Browse files
feat: add dataset images
Display dataset images in lists Sibling PR in data: nextstrain/nextclade_data#94
1 parent 9b385f2 commit 0e7b1bf

File tree

5 files changed

+52
-8
lines changed

5 files changed

+52
-8
lines changed

packages_rs/nextclade-cli/src/dataset/dataset_download.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ pub fn dataset_individual_files_load(
234234
rest_attrs: BTreeMap::default(),
235235
other: serde_json::Value::default(),
236236
},
237+
image: None,
237238
files: DatasetFiles {
238239
reference: "".to_owned(),
239240
pathogen_json: "".to_owned(),

packages_rs/nextclade-web/src/components/Main/DatasetInfo.tsx

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { isNil } from 'lodash'
2-
import { darken } from 'polished'
2+
import { darken, transparentize } from 'polished'
33
import React, { useMemo } from 'react'
44
import { Badge } from 'reactstrap'
55
import { useRecoilValue } from 'recoil'
@@ -194,7 +194,7 @@ export interface DatasetInfoCircleProps {
194194
}
195195

196196
function DatasetInfoAutodetectProgressCircle({ dataset, showSuggestions }: DatasetInfoCircleProps) {
197-
const { attributes, path } = dataset
197+
const { attributes, path, image } = dataset
198198
const { name } = attributes
199199

200200
const circleBg = useMemo(() => darken(0.1)(colorHash(path, { saturation: 0.5, reverse: true })), [path])
@@ -219,12 +219,16 @@ function DatasetInfoAutodetectProgressCircle({ dataset, showSuggestions }: Datas
219219
return { circleText: `0%`, percentage: 0, countText: `0 / ${numberAutodetectResults}` }
220220
}, [showSuggestions, records, numberAutodetectResults, name.valueFriendly, name.value])
221221

222+
const circle = useMemo(() => {
223+
if (image?.path) {
224+
return <CircleImage $bg={circleBg} $image={image.path} />
225+
}
226+
return <Circle $bg={circleBg}>{circleText}</Circle>
227+
}, [circleBg, circleText, image?.path])
228+
222229
return (
223230
<>
224-
<CircleBorder $percentage={percentage}>
225-
<Circle $bg={circleBg}>{circleText}</Circle>
226-
</CircleBorder>
227-
231+
<CircleBorder $percentage={percentage}>{circle}</CircleBorder>
228232
<CountText>{countText}</CountText>
229233
</>
230234
)
@@ -257,6 +261,7 @@ const CircleBorder = styled.div.attrs<CircleBorderProps>((props) => ({
257261
border-radius: 50%;
258262
width: 75px;
259263
height: 75px;
264+
z-index: 10 !important;
260265
`
261266

262267
const Circle = styled.div<{ $bg?: string; $fg?: string }>`
@@ -271,3 +276,18 @@ const Circle = styled.div<{ $bg?: string; $fg?: string }>`
271276
height: 60px;
272277
font-size: 1.2rem;
273278
`
279+
280+
const CircleImage = styled.div<{ $bg?: string; $fg?: string; $image?: string }>`
281+
background-image: ${(props) => `url(${props.$image})`};
282+
background-color: ${(props) => props.$bg && transparentize(0.75)(props.$bg)};
283+
background-blend-mode: overlay;
284+
background-size: contain;
285+
display: flex;
286+
margin: auto;
287+
justify-content: center;
288+
align-items: center;
289+
border-radius: 50%;
290+
width: 60px;
291+
height: 60px;
292+
font-size: 1.2rem;
293+
`

packages_rs/nextclade-web/src/io/fetchDatasetsIndex.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { head, mapValues, sortBy, sortedUniq } from 'lodash'
22
import semver from 'semver'
33
import { takeFirstMaybe } from 'src/helpers/takeFirstMaybe'
44
import urljoin from 'url-join'
5+
import copy from 'fast-copy'
56

67
import { Dataset, DatasetFiles, DatasetsIndexJson, DatasetsIndexV2Json, MinimizerIndexVersion } from 'src/types'
78
import { axiosFetch } from 'src/io/axiosFetch'
@@ -27,10 +28,17 @@ export function fileUrlsToAbsolute(datasetServerUrl: string, dataset: Dataset):
2728
const restFilesAbs = mapValues(dataset.files, (file) =>
2829
file ? urljoin(datasetServerUrl, dataset.path, dataset.version?.tag ?? '', file) : undefined,
2930
) as DatasetFiles
31+
3032
const files = {
3133
...restFilesAbs,
3234
}
33-
return { ...dataset, files }
35+
36+
const image = copy(dataset.image)
37+
if (image?.path) {
38+
image.path = urljoin(datasetServerUrl, dataset.path, dataset.version?.tag ?? '', image.path)
39+
}
40+
41+
return { ...dataset, files, image }
3442
}
3543

3644
export function getLatestCompatibleEnabledDatasets(datasetServerUrl: string, datasetsIndexJson: DatasetsIndexV2Json) {

packages_rs/nextclade/src/analyze/virus_properties.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::analyze::pcr_primer_changes::PcrPrimer;
55
use crate::coord::position::AaRefPosition;
66
use crate::coord::range::AaRefRange;
77
use crate::gene::genotype::Genotype;
8-
use crate::io::dataset::{DatasetAttributes, DatasetCompatibility, DatasetFiles, DatasetVersion};
8+
use crate::io::dataset::{DatasetAttributes, DatasetCompatibility, DatasetFiles, DatasetImage, DatasetVersion};
99
use crate::io::fs::read_file_to_string;
1010
use crate::io::json::json_parse;
1111
use crate::io::schema_version::{SchemaVersion, SchemaVersionParams};
@@ -32,6 +32,8 @@ pub struct VirusProperties {
3232

3333
pub attributes: DatasetAttributes,
3434

35+
pub image: Option<DatasetImage>,
36+
3537
pub files: DatasetFiles,
3638

3739
#[serde(default = "bool_false")]

packages_rs/nextclade/src/io/dataset.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ pub struct Dataset {
7070

7171
pub attributes: DatasetAttributes,
7272

73+
pub image: Option<DatasetImage>,
74+
7375
pub files: DatasetFiles,
7476

7577
#[serde(default, skip_serializing_if = "DatasetCapabilities::is_default")]
@@ -302,6 +304,17 @@ impl DatasetAttributeValue {
302304
}
303305
}
304306

307+
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
308+
#[serde(rename_all = "camelCase")]
309+
pub struct DatasetImage {
310+
pub path: Option<String>,
311+
312+
pub source: Option<String>,
313+
314+
#[serde(flatten)]
315+
pub other: serde_json::Value,
316+
}
317+
305318
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
306319
#[serde(rename_all = "camelCase")]
307320
pub struct DatasetAttributes {

0 commit comments

Comments
 (0)