@genspectrum/dashboard-components 0.13.5 → 0.13.6
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.
- package/custom-elements.json +1 -1
- package/dist/components.d.ts +18 -18
- package/dist/components.js +114 -54
- package/dist/components.js.map +1 -1
- package/dist/util.d.ts +18 -18
- package/package.json +1 -1
- package/src/preact/components/downshift-combobox.tsx +2 -2
- package/src/preact/components/mutation-info.tsx +36 -0
- package/src/preact/locationFilter/fetchAutocompletionList.spec.ts +13 -13
- package/src/preact/locationFilter/fetchAutocompletionList.ts +55 -19
- package/src/preact/locationFilter/location-filter.stories.tsx +1 -1
- package/src/preact/locationFilter/location-filter.tsx +18 -12
- package/src/preact/mutationComparison/mutation-comparison.tsx +26 -2
- package/src/preact/mutations/mutations.tsx +5 -23
- package/src/query/queryWastewaterMutationsOverTime.spec.ts +29 -1
- package/src/query/queryWastewaterMutationsOverTime.ts +30 -16
- package/src/web-components/input/gs-location-filter.stories.ts +1 -1
- package/standalone-bundle/dashboard-components.js +3371 -3314
- package/standalone-bundle/dashboard-components.js.map +1 -1
package/custom-elements.json
CHANGED
|
@@ -805,7 +805,7 @@
|
|
|
805
805
|
"type": {
|
|
806
806
|
"text": "StoryObj<LocationFilterProps>"
|
|
807
807
|
},
|
|
808
|
-
"default": "{ ...Template, parameters: { fetchMock: { mocks: [ { matcher: aggregatedEndpointMatcher, response: { status: 200, body: data, }, }, ], }, }, play: async ({ canvasElement, step }) => { const canvas = await withinShadowRoot(canvasElement, 'gs-location-filter'); const inputField = () => canvas.getByRole('combobox'); const listenerMock = fn(); await step('Setup event listener mock', async () => { canvasElement.addEventListener('gs-location-changed', listenerMock); }); await step('wait until data is loaded', async () => { await waitFor(() => { return expect(inputField()).toBeEnabled(); }); }); await step('Input invalid location', async () => { await userEvent.type(inputField(), 'Not / A / Location'); await expect(listenerMock).not.toHaveBeenCalled(); }); await step('Empty input', async () => { await userEvent.type(inputField(), '{backspace>18/}'); await userEvent.click(canvas.getByLabelText('toggle menu')); await waitFor(() => { return expect(listenerMock.mock.calls.at(-1)![0].detail).toStrictEqual({ region: undefined, country: undefined, division: undefined, location: undefined, }); }); }); await step('Select Asia', async () => { await userEvent.type(inputField(), 'Asia'); await userEvent.click(canvas.getByRole('option', { name:
|
|
808
|
+
"default": "{ ...Template, parameters: { fetchMock: { mocks: [ { matcher: aggregatedEndpointMatcher, response: { status: 200, body: data, }, }, ], }, }, play: async ({ canvasElement, step }) => { const canvas = await withinShadowRoot(canvasElement, 'gs-location-filter'); const inputField = () => canvas.getByRole('combobox'); const listenerMock = fn(); await step('Setup event listener mock', async () => { canvasElement.addEventListener('gs-location-changed', listenerMock); }); await step('wait until data is loaded', async () => { await waitFor(() => { return expect(inputField()).toBeEnabled(); }); }); await step('Input invalid location', async () => { await userEvent.type(inputField(), 'Not / A / Location'); await expect(listenerMock).not.toHaveBeenCalled(); }); await step('Empty input', async () => { await userEvent.type(inputField(), '{backspace>18/}'); await userEvent.click(canvas.getByLabelText('toggle menu')); await waitFor(() => { return expect(listenerMock.mock.calls.at(-1)![0].detail).toStrictEqual({ region: undefined, country: undefined, division: undefined, location: undefined, }); }); }); await step('Select Asia', async () => { await userEvent.type(inputField(), 'Asia'); await userEvent.click(canvas.getByRole('option', { name: /^Asia.*Asia$/ })); await waitFor(() => { return expect(listenerMock.mock.calls.at(-1)![0].detail).toStrictEqual({ region: 'Asia', country: undefined, division: undefined, location: undefined, }); }); }); await step('Select Asia / Bangladesh / Rajshahi / Chapainawabgonj', async () => { await userEvent.type(inputField(), ' / Bangladesh / Rajshahi / Chapainawabgonj'); await userEvent.click(canvas.getByText('Asia / Bangladesh / Rajshahi / Chapainawabgonj')); await waitFor(() => { return expect(listenerMock.mock.calls.at(-1)![0].detail).toStrictEqual({ region: 'Asia', country: 'Bangladesh', division: 'Rajshahi', location: 'Chapainawabgonj', }); }); }); }, }"
|
|
809
809
|
}
|
|
810
810
|
],
|
|
811
811
|
"exports": [
|
package/dist/components.d.ts
CHANGED
|
@@ -1434,7 +1434,7 @@ declare global {
|
|
|
1434
1434
|
|
|
1435
1435
|
declare global {
|
|
1436
1436
|
interface HTMLElementTagNameMap {
|
|
1437
|
-
'gs-
|
|
1437
|
+
'gs-mutations-over-time': MutationsOverTimeComponent;
|
|
1438
1438
|
}
|
|
1439
1439
|
}
|
|
1440
1440
|
|
|
@@ -1442,7 +1442,7 @@ declare global {
|
|
|
1442
1442
|
declare global {
|
|
1443
1443
|
namespace JSX {
|
|
1444
1444
|
interface IntrinsicElements {
|
|
1445
|
-
'gs-
|
|
1445
|
+
'gs-mutations-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1446
1446
|
}
|
|
1447
1447
|
}
|
|
1448
1448
|
}
|
|
@@ -1450,7 +1450,7 @@ declare global {
|
|
|
1450
1450
|
|
|
1451
1451
|
declare global {
|
|
1452
1452
|
interface HTMLElementTagNameMap {
|
|
1453
|
-
'gs-
|
|
1453
|
+
'gs-sequences-by-location': SequencesByLocationComponent;
|
|
1454
1454
|
}
|
|
1455
1455
|
}
|
|
1456
1456
|
|
|
@@ -1458,7 +1458,7 @@ declare global {
|
|
|
1458
1458
|
declare global {
|
|
1459
1459
|
namespace JSX {
|
|
1460
1460
|
interface IntrinsicElements {
|
|
1461
|
-
'gs-
|
|
1461
|
+
'gs-sequences-by-location': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1462
1462
|
}
|
|
1463
1463
|
}
|
|
1464
1464
|
}
|
|
@@ -1466,7 +1466,7 @@ declare global {
|
|
|
1466
1466
|
|
|
1467
1467
|
declare global {
|
|
1468
1468
|
interface HTMLElementTagNameMap {
|
|
1469
|
-
'gs-sequences-
|
|
1469
|
+
'gs-number-sequences-over-time': NumberSequencesOverTimeComponent;
|
|
1470
1470
|
}
|
|
1471
1471
|
}
|
|
1472
1472
|
|
|
@@ -1474,7 +1474,7 @@ declare global {
|
|
|
1474
1474
|
declare global {
|
|
1475
1475
|
namespace JSX {
|
|
1476
1476
|
interface IntrinsicElements {
|
|
1477
|
-
'gs-sequences-
|
|
1477
|
+
'gs-number-sequences-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1478
1478
|
}
|
|
1479
1479
|
}
|
|
1480
1480
|
}
|
|
@@ -1534,10 +1534,10 @@ declare global {
|
|
|
1534
1534
|
|
|
1535
1535
|
declare global {
|
|
1536
1536
|
interface HTMLElementTagNameMap {
|
|
1537
|
-
'gs-
|
|
1537
|
+
'gs-location-filter': LocationFilterComponent;
|
|
1538
1538
|
}
|
|
1539
1539
|
interface HTMLElementEventMap {
|
|
1540
|
-
'gs-
|
|
1540
|
+
'gs-location-changed': LocationChangedEvent;
|
|
1541
1541
|
}
|
|
1542
1542
|
}
|
|
1543
1543
|
|
|
@@ -1545,7 +1545,7 @@ declare global {
|
|
|
1545
1545
|
declare global {
|
|
1546
1546
|
namespace JSX {
|
|
1547
1547
|
interface IntrinsicElements {
|
|
1548
|
-
'gs-
|
|
1548
|
+
'gs-location-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1549
1549
|
}
|
|
1550
1550
|
}
|
|
1551
1551
|
}
|
|
@@ -1553,10 +1553,10 @@ declare global {
|
|
|
1553
1553
|
|
|
1554
1554
|
declare global {
|
|
1555
1555
|
interface HTMLElementTagNameMap {
|
|
1556
|
-
'gs-
|
|
1556
|
+
'gs-text-input': TextInputComponent;
|
|
1557
1557
|
}
|
|
1558
1558
|
interface HTMLElementEventMap {
|
|
1559
|
-
'gs-
|
|
1559
|
+
'gs-text-input-changed': TextInputChangedEvent;
|
|
1560
1560
|
}
|
|
1561
1561
|
}
|
|
1562
1562
|
|
|
@@ -1564,7 +1564,7 @@ declare global {
|
|
|
1564
1564
|
declare global {
|
|
1565
1565
|
namespace JSX {
|
|
1566
1566
|
interface IntrinsicElements {
|
|
1567
|
-
'gs-
|
|
1567
|
+
'gs-text-input': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1568
1568
|
}
|
|
1569
1569
|
}
|
|
1570
1570
|
}
|
|
@@ -1572,10 +1572,10 @@ declare global {
|
|
|
1572
1572
|
|
|
1573
1573
|
declare global {
|
|
1574
1574
|
interface HTMLElementTagNameMap {
|
|
1575
|
-
'gs-
|
|
1575
|
+
'gs-lineage-filter': LineageFilterComponent;
|
|
1576
1576
|
}
|
|
1577
1577
|
interface HTMLElementEventMap {
|
|
1578
|
-
'gs-
|
|
1578
|
+
'gs-lineage-filter-changed': LineageFilterChangedEvent;
|
|
1579
1579
|
}
|
|
1580
1580
|
}
|
|
1581
1581
|
|
|
@@ -1583,7 +1583,7 @@ declare global {
|
|
|
1583
1583
|
declare global {
|
|
1584
1584
|
namespace JSX {
|
|
1585
1585
|
interface IntrinsicElements {
|
|
1586
|
-
'gs-
|
|
1586
|
+
'gs-lineage-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1587
1587
|
}
|
|
1588
1588
|
}
|
|
1589
1589
|
}
|
|
@@ -1591,10 +1591,10 @@ declare global {
|
|
|
1591
1591
|
|
|
1592
1592
|
declare global {
|
|
1593
1593
|
interface HTMLElementTagNameMap {
|
|
1594
|
-
'gs-
|
|
1594
|
+
'gs-mutation-filter': MutationFilterComponent;
|
|
1595
1595
|
}
|
|
1596
1596
|
interface HTMLElementEventMap {
|
|
1597
|
-
'gs-
|
|
1597
|
+
'gs-mutation-filter-changed': CustomEvent<MutationsFilter>;
|
|
1598
1598
|
}
|
|
1599
1599
|
}
|
|
1600
1600
|
|
|
@@ -1602,7 +1602,7 @@ declare global {
|
|
|
1602
1602
|
declare global {
|
|
1603
1603
|
namespace JSX {
|
|
1604
1604
|
interface IntrinsicElements {
|
|
1605
|
-
'gs-
|
|
1605
|
+
'gs-mutation-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1606
1606
|
}
|
|
1607
1607
|
}
|
|
1608
1608
|
}
|
package/dist/components.js
CHANGED
|
@@ -1628,6 +1628,25 @@ const LoadingDisplay = () => {
|
|
|
1628
1628
|
}
|
|
1629
1629
|
);
|
|
1630
1630
|
};
|
|
1631
|
+
const SubstitutionsLink = () => /* @__PURE__ */ u$1(InfoLink, { href: "https://www.genome.gov/genetics-glossary/Substitution", children: "substitutions" });
|
|
1632
|
+
const InsertionsLink = () => /* @__PURE__ */ u$1(InfoLink, { href: "https://www.genome.gov/genetics-glossary/Insertion", children: "insertions" });
|
|
1633
|
+
const DeletionsLink = () => /* @__PURE__ */ u$1(InfoLink, { href: "https://www.genome.gov/genetics-glossary/Deletion", children: "deletions" });
|
|
1634
|
+
const ProportionExplanation = () => /* @__PURE__ */ u$1(Fragment, { children: [
|
|
1635
|
+
/* @__PURE__ */ u$1(InfoHeadline2, { children: "Proportion calculation" }),
|
|
1636
|
+
/* @__PURE__ */ u$1(InfoParagraph, { children: "The proportion of a mutation is calculated by dividing the number of sequences with the mutation by the total number of sequences with a non-ambiguous symbol at the position." }),
|
|
1637
|
+
/* @__PURE__ */ u$1(InfoParagraph, { children: [
|
|
1638
|
+
/* @__PURE__ */ u$1("b", { children: "Example:" }),
|
|
1639
|
+
" Assume we look at nucleotide mutations at position 5 where the reference has a T and assume there are 10 sequences in total:",
|
|
1640
|
+
/* @__PURE__ */ u$1("ul", { className: "list-disc list-inside ml-2", children: [
|
|
1641
|
+
/* @__PURE__ */ u$1("li", { children: "3 sequences have a C," }),
|
|
1642
|
+
/* @__PURE__ */ u$1("li", { children: "2 sequences have a T," }),
|
|
1643
|
+
/* @__PURE__ */ u$1("li", { children: "1 sequence has a G," }),
|
|
1644
|
+
/* @__PURE__ */ u$1("li", { children: "3 sequences have an N," }),
|
|
1645
|
+
/* @__PURE__ */ u$1("li", { children: "1 sequence has a Y (which means T or C)," })
|
|
1646
|
+
] }),
|
|
1647
|
+
"then the proportion of the T5C mutation is 50%. The 4 sequences that have an N or Y are excluded from the calculation."
|
|
1648
|
+
] })
|
|
1649
|
+
] });
|
|
1631
1650
|
function useFloatingUi(referenceRef, floatingRef, middleware, placement) {
|
|
1632
1651
|
const cleanupRef = A$1(null);
|
|
1633
1652
|
y(() => {
|
|
@@ -2212,7 +2231,22 @@ const MutationComparisonInfo = ({ originalComponentProps }) => {
|
|
|
2212
2231
|
const lapis = x$1(LapisUrlContext);
|
|
2213
2232
|
return /* @__PURE__ */ u$1(Info, { children: [
|
|
2214
2233
|
/* @__PURE__ */ u$1(InfoHeadline1, { children: "Info for mutation comparison" }),
|
|
2215
|
-
/* @__PURE__ */ u$1(InfoParagraph, { children:
|
|
2234
|
+
/* @__PURE__ */ u$1(InfoParagraph, { children: [
|
|
2235
|
+
"This displays ",
|
|
2236
|
+
/* @__PURE__ */ u$1(SubstitutionsLink, {}),
|
|
2237
|
+
" and ",
|
|
2238
|
+
/* @__PURE__ */ u$1(DeletionsLink, {}),
|
|
2239
|
+
" of several variants. It shows mutations where the proportion for any given variant falls within the range you can select in the component's toolbar."
|
|
2240
|
+
] }),
|
|
2241
|
+
/* @__PURE__ */ u$1(ProportionExplanation, {}),
|
|
2242
|
+
originalComponentProps.views.includes(views.table) && /* @__PURE__ */ u$1(Fragment, { children: [
|
|
2243
|
+
/* @__PURE__ */ u$1(InfoHeadline2, { children: "Table View" }),
|
|
2244
|
+
/* @__PURE__ */ u$1(InfoParagraph, { children: "The table view displays the proportion of mutations that appear in any of the variants." })
|
|
2245
|
+
] }),
|
|
2246
|
+
originalComponentProps.views.includes(views.venn) && /* @__PURE__ */ u$1(Fragment, { children: [
|
|
2247
|
+
/* @__PURE__ */ u$1(InfoHeadline2, { children: "Venn Diagram View" }),
|
|
2248
|
+
/* @__PURE__ */ u$1(InfoParagraph, { children: "The Venn diagram view illustrates which mutations overlap between the variants and which are exclusive to specific variants. Mutations overlap if their proportion falls within the selected range for two variants. If the proportion of a mutation is within the selected range for one variant but not for the other, the mutation is considered exclusive to that variant." })
|
|
2249
|
+
] }),
|
|
2216
2250
|
/* @__PURE__ */ u$1(InfoComponentCode, { componentName: "mutation-comparison", params: originalComponentProps, lapisUrl: lapis })
|
|
2217
2251
|
] });
|
|
2218
2252
|
};
|
|
@@ -6075,31 +6109,16 @@ const MutationsInfo = ({ originalComponentProps }) => {
|
|
|
6075
6109
|
return /* @__PURE__ */ u$1(Info, { children: [
|
|
6076
6110
|
/* @__PURE__ */ u$1(InfoHeadline1, { children: "Mutations" }),
|
|
6077
6111
|
/* @__PURE__ */ u$1(InfoParagraph, { children: [
|
|
6078
|
-
"This shows mutations of a variant. There are three types of mutations:",
|
|
6079
|
-
|
|
6080
|
-
/* @__PURE__ */ u$1(InfoLink, { href: "https://www.genome.gov/genetics-glossary/Substitution", children: "substitutions" }),
|
|
6112
|
+
"This shows mutations of a variant. There are three types of mutations: ",
|
|
6113
|
+
/* @__PURE__ */ u$1(SubstitutionsLink, {}),
|
|
6081
6114
|
",",
|
|
6082
6115
|
" ",
|
|
6083
|
-
/* @__PURE__ */ u$1(
|
|
6084
|
-
" and",
|
|
6085
|
-
|
|
6086
|
-
/* @__PURE__ */ u$1(InfoLink, { href: "https://www.genome.gov/genetics-glossary/Insertion", children: "insertions" }),
|
|
6116
|
+
/* @__PURE__ */ u$1(DeletionsLink, {}),
|
|
6117
|
+
" and ",
|
|
6118
|
+
/* @__PURE__ */ u$1(InsertionsLink, {}),
|
|
6087
6119
|
"."
|
|
6088
6120
|
] }),
|
|
6089
|
-
/* @__PURE__ */ u$1(
|
|
6090
|
-
/* @__PURE__ */ u$1(InfoParagraph, { children: "The proportion of a mutation is calculated by dividing the number of sequences with the mutation by the total number of sequences with a non-ambiguous symbol at the position." }),
|
|
6091
|
-
/* @__PURE__ */ u$1(InfoParagraph, { children: [
|
|
6092
|
-
/* @__PURE__ */ u$1("b", { children: "Example:" }),
|
|
6093
|
-
" Assume we look at nucleotide mutations at position 5 where the reference has a T and assume there are 10 sequences in total:",
|
|
6094
|
-
/* @__PURE__ */ u$1("ul", { className: "list-disc list-inside ml-2", children: [
|
|
6095
|
-
/* @__PURE__ */ u$1("li", { children: "3 sequences have a C," }),
|
|
6096
|
-
/* @__PURE__ */ u$1("li", { children: "2 sequences have a T," }),
|
|
6097
|
-
/* @__PURE__ */ u$1("li", { children: "1 sequence has a G," }),
|
|
6098
|
-
/* @__PURE__ */ u$1("li", { children: "3 sequences have an N," }),
|
|
6099
|
-
/* @__PURE__ */ u$1("li", { children: "1 sequence has a Y (which means T or C)," })
|
|
6100
|
-
] }),
|
|
6101
|
-
"then the proportion of the T5C mutation is 50%. The 4 sequences that have an N or Y are excluded from the calculation."
|
|
6102
|
-
] }),
|
|
6121
|
+
/* @__PURE__ */ u$1(ProportionExplanation, {}),
|
|
6103
6122
|
/* @__PURE__ */ u$1(InfoComponentCode, { componentName: "mutations", params: originalComponentProps, lapisUrl: lapis })
|
|
6104
6123
|
] });
|
|
6105
6124
|
};
|
|
@@ -11140,12 +11159,20 @@ async function queryWastewaterMutationsOverTime(lapis, lapisFilter, signal) {
|
|
|
11140
11159
|
"aminoAcidMutationFrequency"
|
|
11141
11160
|
]);
|
|
11142
11161
|
const data = (await fetchData.evaluate(lapis, signal)).content;
|
|
11143
|
-
return data.map((row) =>
|
|
11144
|
-
|
|
11145
|
-
|
|
11146
|
-
|
|
11147
|
-
|
|
11148
|
-
|
|
11162
|
+
return data.map((row) => {
|
|
11163
|
+
try {
|
|
11164
|
+
return {
|
|
11165
|
+
location: row.location,
|
|
11166
|
+
date: toTemporalClass(parseDateStringToTemporal(row.date, "day")),
|
|
11167
|
+
nucleotideMutationFrequency: row.nucleotideMutationFrequency !== null ? transformMutations(JSON.parse(row.nucleotideMutationFrequency)) : [],
|
|
11168
|
+
aminoAcidMutationFrequency: row.aminoAcidMutationFrequency !== null ? transformMutations(JSON.parse(row.aminoAcidMutationFrequency)) : []
|
|
11169
|
+
};
|
|
11170
|
+
} catch (e2) {
|
|
11171
|
+
throw new Error(
|
|
11172
|
+
`Failed to parse row of wastewater data: ${JSON.stringify(row)}: ${(e2 == null ? void 0 : e2.message) ?? "Unknown error"}`
|
|
11173
|
+
);
|
|
11174
|
+
}
|
|
11175
|
+
});
|
|
11149
11176
|
}
|
|
11150
11177
|
const mutationFrequencySchema = z$2.record(z$2.number().nullable());
|
|
11151
11178
|
function transformMutations(input) {
|
|
@@ -11153,10 +11180,16 @@ function transformMutations(input) {
|
|
|
11153
11180
|
if (!mutationFrequency.success) {
|
|
11154
11181
|
throw new Error(`Failed to parse mutation frequency: ${mutationFrequency.error.message}`);
|
|
11155
11182
|
}
|
|
11156
|
-
return Object.entries(mutationFrequency.data).map(([key, value]) =>
|
|
11157
|
-
mutation
|
|
11158
|
-
|
|
11159
|
-
|
|
11183
|
+
return Object.entries(mutationFrequency.data).map(([key, value]) => {
|
|
11184
|
+
const mutation = SubstitutionClass.parse(key);
|
|
11185
|
+
if (mutation === null) {
|
|
11186
|
+
throw new Error(`Failed to parse mutation: "${key}"`);
|
|
11187
|
+
}
|
|
11188
|
+
return {
|
|
11189
|
+
mutation,
|
|
11190
|
+
proportion: value
|
|
11191
|
+
};
|
|
11192
|
+
});
|
|
11160
11193
|
}
|
|
11161
11194
|
async function computeWastewaterMutationsOverTimeDataPerLocation(lapis, lapisFilter, sequenceType, signal) {
|
|
11162
11195
|
const data = await queryWastewaterMutationsOverTime(lapis, lapisFilter, signal);
|
|
@@ -11640,26 +11673,46 @@ async function fetchAutocompletionList({
|
|
|
11640
11673
|
signal,
|
|
11641
11674
|
lapisFilter
|
|
11642
11675
|
}) {
|
|
11643
|
-
const
|
|
11676
|
+
const helpersThatOverwriteAValueToItsAncestor = fields.map(
|
|
11677
|
+
(_2, i2) => fields.slice(i2 + 1).reduce((acc, field) => ({ ...acc, [field]: null }), {})
|
|
11678
|
+
);
|
|
11644
11679
|
const fetchAggregatedOperator = new FetchAggregatedOperator(
|
|
11645
11680
|
lapisFilter ?? {},
|
|
11646
11681
|
fields
|
|
11647
11682
|
);
|
|
11648
11683
|
const data = (await fetchAggregatedOperator.evaluate(lapis, signal)).content;
|
|
11649
|
-
const locationValues = data.map((entry) =>
|
|
11650
|
-
|
|
11651
|
-
|
|
11652
|
-
|
|
11653
|
-
|
|
11654
|
-
|
|
11655
|
-
|
|
11656
|
-
|
|
11684
|
+
const locationValues = data.map((entry) => ({
|
|
11685
|
+
value: fields.reduce((acc, field) => ({ ...acc, [field]: entry[field] }), {}),
|
|
11686
|
+
count: entry.count
|
|
11687
|
+
})).reduce((mapOfAllHierarchiesAndCounts, entry) => {
|
|
11688
|
+
return addValueAndAllAncestorsToMap(
|
|
11689
|
+
entry,
|
|
11690
|
+
helpersThatOverwriteAValueToItsAncestor,
|
|
11691
|
+
mapOfAllHierarchiesAndCounts
|
|
11692
|
+
);
|
|
11693
|
+
}, /* @__PURE__ */ new Map());
|
|
11694
|
+
return [...locationValues].map(([json, count]) => ({
|
|
11695
|
+
value: JSON.parse(json),
|
|
11696
|
+
count
|
|
11697
|
+
})).sort(compareLocationEntries(fields)).map(({ value, count }) => ({
|
|
11698
|
+
value: fields.reduce((acc, field) => ({ ...acc, [field]: value[field] ?? void 0 }), {}),
|
|
11699
|
+
count
|
|
11700
|
+
}));
|
|
11701
|
+
}
|
|
11702
|
+
function addValueAndAllAncestorsToMap({ value, count }, helpersThatOverwriteAValueToItsAncestor, mapOfAllHierarchiesAndCounts) {
|
|
11703
|
+
const keysOfAllHierarchyLevels = new Set(
|
|
11704
|
+
helpersThatOverwriteAValueToItsAncestor.map((overwriteValues) => ({ ...value, ...overwriteValues })).map((value2) => JSON.stringify(value2))
|
|
11705
|
+
);
|
|
11706
|
+
for (const key of keysOfAllHierarchyLevels) {
|
|
11707
|
+
mapOfAllHierarchiesAndCounts.set(key, (mapOfAllHierarchiesAndCounts.get(key) ?? 0) + count);
|
|
11708
|
+
}
|
|
11709
|
+
return mapOfAllHierarchiesAndCounts;
|
|
11657
11710
|
}
|
|
11658
11711
|
function compareLocationEntries(fields) {
|
|
11659
11712
|
return (a2, b3) => {
|
|
11660
11713
|
for (const field of fields) {
|
|
11661
|
-
const valueA = a2[field];
|
|
11662
|
-
const valueB = b3[field];
|
|
11714
|
+
const valueA = a2.value[field];
|
|
11715
|
+
const valueB = b3.value[field];
|
|
11663
11716
|
if (valueA === valueB) {
|
|
11664
11717
|
continue;
|
|
11665
11718
|
}
|
|
@@ -14715,12 +14768,12 @@ function DownshiftCombobox({
|
|
|
14715
14768
|
children: items.length > 0 ? items.map((item, index) => /* @__PURE__ */ u$1(
|
|
14716
14769
|
"li",
|
|
14717
14770
|
{
|
|
14718
|
-
className: `${highlightedIndex === index ? "bg-blue-300" : ""} ${selectedItem !== null && itemToString2(selectedItem) === itemToString2(item) ? "font-bold" : ""} py-2 px-3 shadow-sm
|
|
14771
|
+
className: `${highlightedIndex === index ? "bg-blue-300" : ""} ${selectedItem !== null && itemToString2(selectedItem) === itemToString2(item) ? "font-bold" : ""} py-2 px-3 shadow-sm`,
|
|
14719
14772
|
...getItemProps({ item, index }),
|
|
14720
14773
|
children: formatItemInList(item)
|
|
14721
14774
|
},
|
|
14722
14775
|
itemToString2(item)
|
|
14723
|
-
)) : /* @__PURE__ */ u$1("li", { className: "py-2 px-3 shadow-sm
|
|
14776
|
+
)) : /* @__PURE__ */ u$1("li", { className: "py-2 px-3 shadow-sm", children: "No elements to select." })
|
|
14724
14777
|
}
|
|
14725
14778
|
)
|
|
14726
14779
|
] });
|
|
@@ -14763,8 +14816,8 @@ const LocationSelector = ({
|
|
|
14763
14816
|
return locationData.map((location) => toSelectItem(location, fields)).filter((item) => item !== void 0);
|
|
14764
14817
|
}, [fields, locationData]);
|
|
14765
14818
|
const selectedItem = T$1(() => {
|
|
14766
|
-
return value !== void 0 ?
|
|
14767
|
-
}, [fields, value]);
|
|
14819
|
+
return value !== void 0 ? allItems.find((item) => item.description == concatenateLocation(value, fields)) : void 0;
|
|
14820
|
+
}, [fields, value, allItems]);
|
|
14768
14821
|
return /* @__PURE__ */ u$1(
|
|
14769
14822
|
DownshiftCombobox,
|
|
14770
14823
|
{
|
|
@@ -14774,12 +14827,17 @@ const LocationSelector = ({
|
|
|
14774
14827
|
createEvent: (item) => new LocationChangedEvent((item == null ? void 0 : item.lapisFilter) ?? emptyLocationFilter(fields)),
|
|
14775
14828
|
itemToString: (item) => (item == null ? void 0 : item.label) ?? "",
|
|
14776
14829
|
placeholderText,
|
|
14777
|
-
formatItemInList: (item) => {
|
|
14778
|
-
|
|
14830
|
+
formatItemInList: (item) => /* @__PURE__ */ u$1(Fragment, { children: [
|
|
14831
|
+
/* @__PURE__ */ u$1("p", { children: [
|
|
14779
14832
|
/* @__PURE__ */ u$1("span", { children: item.label }),
|
|
14780
|
-
/* @__PURE__ */ u$1("span", { className: "
|
|
14781
|
-
|
|
14782
|
-
|
|
14833
|
+
/* @__PURE__ */ u$1("span", { className: "ml-2 text-gray-500", children: [
|
|
14834
|
+
"(",
|
|
14835
|
+
item.count,
|
|
14836
|
+
")"
|
|
14837
|
+
] })
|
|
14838
|
+
] }),
|
|
14839
|
+
/* @__PURE__ */ u$1("span", { className: "text-sm text-gray-500", children: item.description })
|
|
14840
|
+
] })
|
|
14783
14841
|
}
|
|
14784
14842
|
);
|
|
14785
14843
|
};
|
|
@@ -14790,7 +14848,8 @@ function filterByInputValue$2(item, inputValue) {
|
|
|
14790
14848
|
}
|
|
14791
14849
|
return ((_a = item == null ? void 0 : item.label) == null ? void 0 : _a.toLowerCase().includes(inputValue.toLowerCase())) || (item == null ? void 0 : item.description.toLowerCase().includes(inputValue.toLowerCase()));
|
|
14792
14850
|
}
|
|
14793
|
-
function toSelectItem(
|
|
14851
|
+
function toSelectItem(locationEntry, fields) {
|
|
14852
|
+
const locationFilter = locationEntry.value;
|
|
14794
14853
|
const concatenatedLocation = concatenateLocation(locationFilter, fields);
|
|
14795
14854
|
const lastNonUndefinedField = [...fields].reverse().find((field) => locationFilter[field] !== void 0 && locationFilter[field] !== null);
|
|
14796
14855
|
if (lastNonUndefinedField === void 0) {
|
|
@@ -14799,7 +14858,8 @@ function toSelectItem(locationFilter, fields) {
|
|
|
14799
14858
|
return {
|
|
14800
14859
|
lapisFilter: locationFilter,
|
|
14801
14860
|
label: locationFilter[lastNonUndefinedField],
|
|
14802
|
-
description: concatenatedLocation
|
|
14861
|
+
description: concatenatedLocation,
|
|
14862
|
+
count: locationEntry.count
|
|
14803
14863
|
};
|
|
14804
14864
|
}
|
|
14805
14865
|
function concatenateLocation(locationFilter, fields) {
|