diff --git a/packages_rs/nextclade-web/package.json b/packages_rs/nextclade-web/package.json index 0f93187d9..7c5b95673 100644 --- a/packages_rs/nextclade-web/package.json +++ b/packages_rs/nextclade-web/package.json @@ -117,6 +117,7 @@ "luxon": "2.3.2", "marked": "4.0.14", "memoize-one": "6.0.0", + "nanoid": "3.3.6", "next": "12.1.6", "next-compose-plugins": "2.2.1", "numbro": "2.3.6", @@ -239,13 +240,13 @@ "allow-methods": "3.1.0", "babel-plugin-parameter-decorator": "1.0.16", "babel-plugin-transform-typescript-metadata": "0.3.2", + "commander": "10.0.1", "compression-webpack-plugin": "9.2.0", "connect-history-api-fallback": "1.6.0", "conventional-changelog-cli": "2.2.2", "copy-webpack-plugin": "10.2.4", "cross-env": "7.0.3", "css-loader": "6.7.1", - "commander": "10.0.1", "dotenv": "16.0.0", "eslint": "8.14.0", "eslint-config-airbnb": "19.0.4", diff --git a/packages_rs/nextclade-web/src/components/FilePicker/FilePicker.tsx b/packages_rs/nextclade-web/src/components/FilePicker/FilePicker.tsx index 5e55a0109..87aaf3d68 100644 --- a/packages_rs/nextclade-web/src/components/FilePicker/FilePicker.tsx +++ b/packages_rs/nextclade-web/src/components/FilePicker/FilePicker.tsx @@ -111,12 +111,12 @@ export function FilePicker({ const onPaste = useCallback( (content: string) => { if (multiple) { - onInputs?.([new AlgorithmInputString(content)]) + onInputs?.([new AlgorithmInputString(content, t('Pasted sequences'))]) } else { - onInput?.(new AlgorithmInputString(content)) + onInput?.(new AlgorithmInputString(content, t('Pasted sequences'))) } }, - [multiple, onInput, onInputs], + [multiple, onInput, onInputs, t], ) // eslint-disable-next-line no-void diff --git a/packages_rs/nextclade-web/src/components/Main/QuerySequenceList.tsx b/packages_rs/nextclade-web/src/components/Main/QuerySequenceList.tsx index cb7802f94..61b0f91eb 100644 --- a/packages_rs/nextclade-web/src/components/Main/QuerySequenceList.tsx +++ b/packages_rs/nextclade-web/src/components/Main/QuerySequenceList.tsx @@ -14,7 +14,7 @@ export function QuerySequenceList() { const listItems = useMemo(() => { return qryInputs.map((input, index) => ( -
  • +
  • )) diff --git a/packages_rs/nextclade-web/src/helpers/uniqueId.ts b/packages_rs/nextclade-web/src/helpers/uniqueId.ts new file mode 100644 index 000000000..e1525d609 --- /dev/null +++ b/packages_rs/nextclade-web/src/helpers/uniqueId.ts @@ -0,0 +1,5 @@ +import { nanoid } from 'nanoid' + +export function uniqueId(): string { + return nanoid() +} diff --git a/packages_rs/nextclade-web/src/io/AlgorithmInput.ts b/packages_rs/nextclade-web/src/io/AlgorithmInput.ts index 248d9c304..5e3d398ad 100644 --- a/packages_rs/nextclade-web/src/io/AlgorithmInput.ts +++ b/packages_rs/nextclade-web/src/io/AlgorithmInput.ts @@ -1,6 +1,6 @@ +import { uniqueId } from 'src/helpers/uniqueId' import { AlgorithmInput, AlgorithmInputType, Dataset } from 'src/types' import { axiosFetchRaw } from 'src/io/axiosFetch' - import { readFile } from 'src/helpers/readFile' import { numbro } from 'src/i18n/i18n' @@ -16,12 +16,20 @@ function formatBytes(bytes: number) { } export class AlgorithmInputFile implements AlgorithmInput { + public readonly uid = uniqueId() + public readonly path: string public readonly type: AlgorithmInputType = AlgorithmInputType.File as const - private readonly file: File constructor(file: File) { this.file = file + + // eslint-disable-next-line unicorn/prefer-ternary + if (this.file.webkitRelativePath.trim().length > 0) { + this.path = this.file.webkitRelativePath ?? `${this.uid}-${this.file}` + } else { + this.path = `${this.uid}-${this.file.name}` + } } public get name(): string { @@ -38,12 +46,14 @@ export class AlgorithmInputFile implements AlgorithmInput { } export class AlgorithmInputUrl implements AlgorithmInput { + public readonly uid = uniqueId() + public readonly path: string public readonly type: AlgorithmInputType = AlgorithmInputType.Url as const - private readonly url: string constructor(url: string) { this.url = url + this.path = this.url } public get name(): string { @@ -60,12 +70,14 @@ export class AlgorithmInputUrl implements AlgorithmInput { } export class AlgorithmInputString implements AlgorithmInput { + public readonly uid = uniqueId() + public readonly path: string public readonly type: AlgorithmInputType = AlgorithmInputType.String as const - private readonly content: string private readonly contentName: string constructor(content: string, contentName?: string) { + this.path = `pasted-${this.uid}.fasta` this.content = content this.contentName = contentName ?? 'Pasted sequences' } @@ -84,21 +96,22 @@ export class AlgorithmInputString implements AlgorithmInput { } export class AlgorithmInputDefault implements AlgorithmInput { + public readonly uid = uniqueId() + public readonly path: string public readonly type: AlgorithmInputType = AlgorithmInputType.Default as const - public dataset: Dataset constructor(dataset: Dataset) { this.dataset = dataset + this.path = `${this.dataset.path}/${this.dataset.files.examples ?? 'unknown.fasta'}` } public get name(): string { - const { value, valueFriendly } = this.dataset.attributes.name - return `${valueFriendly ?? value} example sequences` + return this.path } public get description(): string { - return `${this.name}` + return this.name } public async getContent(): Promise { diff --git a/packages_rs/nextclade-web/src/types.ts b/packages_rs/nextclade-web/src/types.ts index 6cabb3df4..03fc0a055 100644 --- a/packages_rs/nextclade-web/src/types.ts +++ b/packages_rs/nextclade-web/src/types.ts @@ -127,6 +127,8 @@ export enum AlgorithmInputType { } export interface AlgorithmInput { + uid: string + path: string type: AlgorithmInputType name: string description: string diff --git a/packages_rs/nextclade-web/yarn.lock b/packages_rs/nextclade-web/yarn.lock index 2499a6d2d..df7774898 100644 --- a/packages_rs/nextclade-web/yarn.lock +++ b/packages_rs/nextclade-web/yarn.lock @@ -11515,6 +11515,11 @@ nano-time@1.0.0: dependencies: big-integer "^1.6.16" +nanoid@3.3.6: + version "3.3.6" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" + integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== + nanoid@^3.1.30, nanoid@^3.3.1: version "3.3.3" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25"