@genspectrum/dashboard-components 0.5.3 → 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -726,6 +726,14 @@
726
726
  "text": "StoryObj<MutationFilterProps>"
727
727
  },
728
728
  "default": "{ ...Template, play: async ({ canvasElement, step }) => { const canvas = await withinShadowRoot(canvasElement, 'gs-mutation-filter'); const inputField = () => canvas.getByPlaceholderText('Enter a mutation', { exact: false }); const listenerMock = fn(); await step('Setup event listener mock', async () => { canvasElement.addEventListener('gs-mutation-filter-on-blur', listenerMock); }); await step('wait until data is loaded', async () => { await waitFor(() => { return expect(inputField()).toBeEnabled(); }); }); await step('Move outside of input', async () => { await userEvent.type(inputField(), 'A123T'); await userEvent.tab(); await expect(listenerMock).toHaveBeenCalled(); }); }, }"
729
+ },
730
+ {
731
+ "kind": "variable",
732
+ "name": "MultiSegmentedReferenceGenomes",
733
+ "type": {
734
+ "text": "StoryObj<MutationFilterProps>"
735
+ },
736
+ "default": "{ ...Template, args: { initialValue: ['seg1:123T', 'gene2:56', 'ins_seg2:78:AAA'], }, parameters: { fetchMock: { mocks: [ { matcher: { name: 'referenceGenome', url: REFERENCE_GENOME_ENDPOINT, }, response: { status: 200, body: { nucleotideSequences: [ { name: 'seg1', sequence: 'dummy', }, { name: 'seg2', sequence: 'dummy', }, ], genes: [ { name: 'gene1', sequence: 'dummy', }, { name: 'gene2', sequence: 'dummy', }, ], }, }, options: { overwriteRoutes: false, }, }, ], }, }, play: async ({ canvasElement }) => { const canvas = await withinShadowRoot(canvasElement, 'gs-mutation-filter'); await waitFor(() => { expect(canvas.getByText('seg1:123T')).toBeVisible(); expect(canvas.getByText('gene2:56')).toBeVisible(); return expect(canvas.getByText('ins_seg2:78:AAA')).toBeVisible(); }); }, }"
729
737
  }
730
738
  ],
731
739
  "exports": [
@@ -760,6 +768,14 @@
760
768
  "name": "FiresFilterOnBlurEvent",
761
769
  "module": "src/web-components/input/gs-mutation-filter.stories.ts"
762
770
  }
771
+ },
772
+ {
773
+ "kind": "js",
774
+ "name": "MultiSegmentedReferenceGenomes",
775
+ "declaration": {
776
+ "name": "MultiSegmentedReferenceGenomes",
777
+ "module": "src/web-components/input/gs-mutation-filter.stories.ts"
778
+ }
763
779
  }
764
780
  ]
765
781
  },
@@ -347,6 +347,7 @@ const getSegmentNames = (referenceGenome, sequenceType) => {
347
347
  }
348
348
  }
349
349
  };
350
+ const isSingleSegmented = (referenceGenome) => referenceGenome.nucleotideSequences.length === 1;
350
351
  const orderByType = z$1.enum(["ascending", "descending"]);
351
352
  const orderBy = z$1.object({
352
353
  field: z$1.string(),
@@ -8266,9 +8267,221 @@ const ReferenceGenomesAwaiter = ({ children }) => {
8266
8267
  function isNotInitialized(referenceGenome) {
8267
8268
  return referenceGenome.nucleotideSequences.length === 0 && referenceGenome.genes.length === 0;
8268
8269
  }
8270
+ const MutationFilterInfo = () => {
8271
+ const referenceGenome = x(ReferenceGenomeContext);
8272
+ const firstGene = referenceGenome.genes[0].name;
8273
+ return /* @__PURE__ */ u$1(Info, { height: "80vh", children: [
8274
+ /* @__PURE__ */ u$1(InfoHeadline1, { children: " Mutation Filter" }),
8275
+ /* @__PURE__ */ u$1(InfoParagraph, { children: "This component allows you to filter for mutations at specific positions." }),
8276
+ /* @__PURE__ */ u$1(InfoHeadline2, { children: " Nucleotide Mutations and Insertions" }),
8277
+ isSingleSegmented(referenceGenome) ? /* @__PURE__ */ u$1(SingleSegmentedNucleotideMutationsInfo, {}) : /* @__PURE__ */ u$1(MultiSegmentedNucleotideMutationsInfo, {}),
8278
+ /* @__PURE__ */ u$1(InfoHeadline2, { children: "Amino Acid Mutations and Insertions" }),
8279
+ /* @__PURE__ */ u$1(InfoParagraph, { children: [
8280
+ "An amino acid mutation has the format ",
8281
+ /* @__PURE__ */ u$1("b", { children: "<gene>:<position><base>" }),
8282
+ " or",
8283
+ /* @__PURE__ */ u$1("b", { children: "<gene>:<base_ref><position><base>" }),
8284
+ ". A ",
8285
+ /* @__PURE__ */ u$1("b", { children: "<base>" }),
8286
+ " can be one of the 20 amino acid codes. It can also be ",
8287
+ /* @__PURE__ */ u$1("b", { children: "-" }),
8288
+ " for deletion and ",
8289
+ /* @__PURE__ */ u$1("b", { children: "X" }),
8290
+ " for unknown. Example:",
8291
+ " ",
8292
+ /* @__PURE__ */ u$1("b", { children: "E:57Q" }),
8293
+ "."
8294
+ ] }),
8295
+ /* @__PURE__ */ u$1(InfoParagraph, { children: [
8296
+ "Insertions can be searched for in the same manner, they just need to have ",
8297
+ /* @__PURE__ */ u$1("b", { children: "ins_" }),
8298
+ " appended to the start of the mutation. Example: ",
8299
+ /* @__PURE__ */ u$1("b", { children: [
8300
+ "ins_",
8301
+ firstGene,
8302
+ ":31:N"
8303
+ ] }),
8304
+ " would filter for sequences with an insertion of N between positions 31 and 32 in the gene ",
8305
+ firstGene,
8306
+ "."
8307
+ ] }),
8308
+ /* @__PURE__ */ u$1(InfoParagraph, { children: [
8309
+ "This organism has the following genes: ",
8310
+ referenceGenome.genes.map((gene) => gene.name).join(", "),
8311
+ "."
8312
+ ] }),
8313
+ /* @__PURE__ */ u$1(InfoHeadline2, { children: "Insertion Wildcards" }),
8314
+ /* @__PURE__ */ u$1(InfoParagraph, { children: [
8315
+ "This component supports insertion queries that contain wildcards ",
8316
+ /* @__PURE__ */ u$1("b", { children: "?" }),
8317
+ ". For example",
8318
+ " ",
8319
+ /* @__PURE__ */ u$1("b", { children: [
8320
+ "ins_",
8321
+ firstGene,
8322
+ ":214:?EP?"
8323
+ ] }),
8324
+ " will match all cases where segment ",
8325
+ /* @__PURE__ */ u$1("b", { children: firstGene }),
8326
+ " has an insertion of ",
8327
+ /* @__PURE__ */ u$1("b", { children: "EP" }),
8328
+ " between the positions ",
8329
+ /* @__PURE__ */ u$1("b", { children: "214" }),
8330
+ " and ",
8331
+ /* @__PURE__ */ u$1("b", { children: "215" }),
8332
+ " but also an insertion of other amino acids which include the ",
8333
+ /* @__PURE__ */ u$1("b", { children: "EP" }),
8334
+ ", e.g. the insertion ",
8335
+ /* @__PURE__ */ u$1("b", { children: "EPE" }),
8336
+ " will be matched."
8337
+ ] }),
8338
+ /* @__PURE__ */ u$1(InfoParagraph, { children: [
8339
+ "You can also use wildcards to match any insertion at a given position. For example",
8340
+ " ",
8341
+ /* @__PURE__ */ u$1("b", { children: [
8342
+ "ins_",
8343
+ firstGene,
8344
+ ":214:?"
8345
+ ] }),
8346
+ " match any (but at least one) insertion between the positions 214 and 215."
8347
+ ] }),
8348
+ /* @__PURE__ */ u$1(InfoHeadline2, { children: "Multiple Mutations" }),
8349
+ /* @__PURE__ */ u$1(InfoParagraph, { children: "Multiple mutation filters can be provided by adding one mutation after the other." }),
8350
+ /* @__PURE__ */ u$1(InfoHeadline2, { children: "Any Mutation" }),
8351
+ /* @__PURE__ */ u$1(InfoParagraph, { children: [
8352
+ "To filter for any mutation at a given position you can omit the ",
8353
+ /* @__PURE__ */ u$1("b", { children: "<base>" }),
8354
+ ". Example:",
8355
+ " ",
8356
+ /* @__PURE__ */ u$1("b", { children: [
8357
+ firstGene,
8358
+ ":20"
8359
+ ] }),
8360
+ "."
8361
+ ] }),
8362
+ /* @__PURE__ */ u$1(InfoHeadline2, { children: "No Mutation" }),
8363
+ /* @__PURE__ */ u$1(InfoParagraph, { children: [
8364
+ "You can write a ",
8365
+ /* @__PURE__ */ u$1("b", { children: "." }),
8366
+ " for the ",
8367
+ /* @__PURE__ */ u$1("b", { children: "<base>" }),
8368
+ " to filter for sequences for which it is confirmed that no mutation occurred, i.e. has the same base as the reference genome at the specified position."
8369
+ ] })
8370
+ ] });
8371
+ };
8372
+ const SingleSegmentedNucleotideMutationsInfo = () => {
8373
+ return /* @__PURE__ */ u$1(Fragment, { children: [
8374
+ /* @__PURE__ */ u$1(InfoParagraph, { children: [
8375
+ "This organism is single-segmented. Thus, nucleotide mutations have the format",
8376
+ " ",
8377
+ /* @__PURE__ */ u$1("b", { children: "<position><base>" }),
8378
+ " or ",
8379
+ /* @__PURE__ */ u$1("b", { children: "<base_ref><position><base>" }),
8380
+ ". The",
8381
+ " ",
8382
+ /* @__PURE__ */ u$1("b", { children: "<base_ref>" }),
8383
+ " is the reference base at the position. It is optional. A ",
8384
+ /* @__PURE__ */ u$1("b", { children: "<base>" }),
8385
+ " can be one of the four nucleotides ",
8386
+ /* @__PURE__ */ u$1("b", { children: "A" }),
8387
+ ", ",
8388
+ /* @__PURE__ */ u$1("b", { children: "T" }),
8389
+ ", ",
8390
+ /* @__PURE__ */ u$1("b", { children: "C" }),
8391
+ ", and ",
8392
+ /* @__PURE__ */ u$1("b", { children: "G" }),
8393
+ ". It can also be ",
8394
+ /* @__PURE__ */ u$1("b", { children: "-" }),
8395
+ " for deletion and ",
8396
+ /* @__PURE__ */ u$1("b", { children: "N" }),
8397
+ " for unknown. For example if the reference sequence is ",
8398
+ /* @__PURE__ */ u$1("b", { children: "A" }),
8399
+ " at position",
8400
+ " ",
8401
+ /* @__PURE__ */ u$1("b", { children: "23" }),
8402
+ " both: ",
8403
+ /* @__PURE__ */ u$1("b", { children: "23T" }),
8404
+ " and ",
8405
+ /* @__PURE__ */ u$1("b", { children: "A23T" }),
8406
+ " will yield the same results."
8407
+ ] }),
8408
+ /* @__PURE__ */ u$1(InfoParagraph, { children: [
8409
+ "Insertions can be searched for in the same manner, they just need to have ",
8410
+ /* @__PURE__ */ u$1("b", { children: "ins_" }),
8411
+ " appended to the start of the mutation. Example: ",
8412
+ /* @__PURE__ */ u$1("b", { children: "ins_1046:A" }),
8413
+ " would filter for sequences with an insertion of A between the positions 1046 and 1047 in the nucleotide sequence."
8414
+ ] })
8415
+ ] });
8416
+ };
8417
+ const MultiSegmentedNucleotideMutationsInfo = () => {
8418
+ const referenceGenome = x(ReferenceGenomeContext);
8419
+ const firstSegment = referenceGenome.nucleotideSequences[0].name;
8420
+ return /* @__PURE__ */ u$1(Fragment, { children: [
8421
+ /* @__PURE__ */ u$1(InfoParagraph, { children: [
8422
+ "This organism is multi-segmented. Thus, nucleotide mutations have the format",
8423
+ " ",
8424
+ /* @__PURE__ */ u$1("b", { children: "<segment>:<position><base>" }),
8425
+ " or",
8426
+ " ",
8427
+ /* @__PURE__ */ u$1("b", { children: "<segment>:<base_ref><position><base>" }),
8428
+ ". ",
8429
+ /* @__PURE__ */ u$1("b", { children: "<base_ref>" }),
8430
+ " is the reference base at the position. It is optional. A ",
8431
+ /* @__PURE__ */ u$1("b", { children: "<base>" }),
8432
+ " can be one of the four nucleotides",
8433
+ " ",
8434
+ /* @__PURE__ */ u$1("b", { children: "A" }),
8435
+ ", ",
8436
+ /* @__PURE__ */ u$1("b", { children: "T" }),
8437
+ ", ",
8438
+ /* @__PURE__ */ u$1("b", { children: "C" }),
8439
+ ", and ",
8440
+ /* @__PURE__ */ u$1("b", { children: "G" }),
8441
+ ". It can also be ",
8442
+ /* @__PURE__ */ u$1("b", { children: "-" }),
8443
+ " for deletion and ",
8444
+ /* @__PURE__ */ u$1("b", { children: "N" }),
8445
+ " for unknown. For example if the reference sequence is ",
8446
+ /* @__PURE__ */ u$1("b", { children: "A" }),
8447
+ " at position ",
8448
+ /* @__PURE__ */ u$1("b", { children: "23" }),
8449
+ " both:",
8450
+ " ",
8451
+ /* @__PURE__ */ u$1("b", { children: [
8452
+ firstSegment,
8453
+ ":23T"
8454
+ ] }),
8455
+ " and ",
8456
+ /* @__PURE__ */ u$1("b", { children: [
8457
+ firstSegment,
8458
+ ":A23T"
8459
+ ] }),
8460
+ " will yield the same results."
8461
+ ] }),
8462
+ /* @__PURE__ */ u$1(InfoParagraph, { children: [
8463
+ "Insertions can be searched for in the same manner, they just need to have ",
8464
+ /* @__PURE__ */ u$1("b", { children: "ins_" }),
8465
+ " appended to the start of the mutation. Example: ",
8466
+ /* @__PURE__ */ u$1("b", { children: [
8467
+ "ins_",
8468
+ firstSegment,
8469
+ ":10462:A"
8470
+ ] }),
8471
+ "."
8472
+ ] }),
8473
+ /* @__PURE__ */ u$1(InfoParagraph, { children: [
8474
+ "This organism has the following segments:",
8475
+ " ",
8476
+ referenceGenome.nucleotideSequences.map((gene) => gene.name).join(", "),
8477
+ "."
8478
+ ] }),
8479
+ " "
8480
+ ] });
8481
+ };
8269
8482
  const sequenceTypeFromSegment = (possibleSegment, referenceGenome) => {
8270
8483
  if (possibleSegment === void 0) {
8271
- return referenceGenome.nucleotideSequences.length === 1 ? "nucleotide" : void 0;
8484
+ return isSingleSegmented(referenceGenome) ? "nucleotide" : void 0;
8272
8485
  }
8273
8486
  if (referenceGenome.nucleotideSequences.some((sequence) => sequence.name === possibleSegment)) {
8274
8487
  return "nucleotide";
@@ -8388,7 +8601,7 @@ const MutationFilterInner = ({ initialValue }) => {
8388
8601
  setIsError(false);
8389
8602
  };
8390
8603
  return /* @__PURE__ */ u$1("form", { className: "w-full border boder-gray-300 rounded-md relative", onSubmit: handleSubmit, ref: formRef, children: [
8391
- /* @__PURE__ */ u$1("div", { className: "absolute -top-3 -right-3", children: /* @__PURE__ */ u$1(Info, { height: "100px", children: "Info for mutation filter" }) }),
8604
+ /* @__PURE__ */ u$1("div", { className: "absolute -top-3 -right-3", children: /* @__PURE__ */ u$1(MutationFilterInfo, {}) }),
8392
8605
  /* @__PURE__ */ u$1("div", { className: "w-full flex p-2 flex-wrap items-center", children: [
8393
8606
  /* @__PURE__ */ u$1(
8394
8607
  SelectedMutationDisplay,