@genspectrum/dashboard-components 0.14.1 → 0.14.2
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 +11 -11
- package/dist/assets/mutationOverTimeWorker-Dxnxrfe0.js.map +1 -1
- package/dist/components.d.ts +47 -51
- package/dist/components.js +17 -7
- package/dist/components.js.map +1 -1
- package/dist/util.d.ts +46 -46
- package/package.json +2 -2
- package/src/lapisApi/lapisApi.ts +1 -1
- package/src/operator/FillMissingOperator.spec.ts +1 -1
- package/src/operator/GroupByAndSumOperator.spec.ts +1 -1
- package/src/operator/GroupByOperator.spec.ts +2 -2
- package/src/operator/MapOperator.spec.ts +1 -1
- package/src/operator/MockOperator.spec.ts +1 -1
- package/src/operator/MockOperator.ts +6 -4
- package/src/operator/SortOperator.spec.ts +1 -1
- package/src/preact/aggregatedData/aggregate.stories.tsx +1 -1
- package/src/preact/components/csv-download-button.stories.tsx +2 -2
- package/src/preact/components/csv-download-button.tsx +1 -1
- package/src/preact/components/error-boundary.stories.tsx +5 -5
- package/src/preact/components/error-boundary.tsx +14 -3
- package/src/preact/components/error-display.stories.tsx +9 -9
- package/src/preact/components/fullscreen.tsx +3 -3
- package/src/preact/components/info.tsx +1 -1
- package/src/preact/components/mutation-type-selector.stories.tsx +1 -1
- package/src/preact/components/table.stories.tsx +3 -3
- package/src/preact/components/table.tsx +1 -1
- package/src/preact/dateRangeSelector/date-range-selector.stories.tsx +3 -6
- package/src/preact/dateRangeSelector/date-range-selector.tsx +2 -2
- package/src/preact/lineageFilter/lineage-filter.stories.tsx +6 -6
- package/src/preact/locationFilter/fetchAutocompletionList.ts +1 -1
- package/src/preact/locationFilter/location-filter.stories.tsx +6 -6
- package/src/preact/map/sequences-by-location.stories.tsx +1 -1
- package/src/preact/mutationFilter/mutation-filter.stories.tsx +2 -2
- package/src/preact/mutations/getMutationsGridData.ts +1 -1
- package/src/preact/mutationsOverTime/mutations-over-time-grid.tsx +3 -3
- package/src/preact/mutationsOverTime/mutations-over-time.stories.tsx +1 -1
- package/src/preact/mutationsOverTime/mutations-over-time.tsx +1 -0
- package/src/preact/numberSequencesOverTime/number-sequences-over-time.stories.tsx +1 -1
- package/src/preact/prevalenceOverTime/prevalence-over-time-bubble-chart.tsx +4 -4
- package/src/preact/prevalenceOverTime/prevalence-over-time.stories.tsx +1 -1
- package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.stories.tsx +1 -1
- package/src/preact/shared/floating-ui/hooks.ts +1 -1
- package/src/preact/textInput/text-input.stories.tsx +4 -4
- package/src/utils/map2d.ts +1 -0
- package/src/web-components/gs-app.stories.ts +7 -7
- package/src/web-components/input/gs-date-range-selector.stories.ts +6 -6
- package/src/web-components/input/gs-lineage-filter.stories.ts +1 -1
- package/src/web-components/input/gs-location-filter.stories.ts +1 -1
- package/src/web-components/input/gs-mutation-filter.stories.ts +7 -7
- package/src/web-components/input/gs-text-input.stories.ts +3 -3
- package/src/web-components/visualization/gs-aggregate.tsx +2 -2
- package/standalone-bundle/assets/mutationOverTimeWorker-CmSrq4SZ.js.map +1 -1
- package/standalone-bundle/dashboard-components.js +70 -63
- package/standalone-bundle/dashboard-components.js.map +1 -1
package/custom-elements.json
CHANGED
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"type": {
|
|
85
85
|
"text": "StoryObj<{ lapis: string }>"
|
|
86
86
|
},
|
|
87
|
-
"default": "{ ...Template, play: async ({ canvasElement }) => { const canvas = within(canvasElement); await waitFor(() => { expect(canvas.getByText(LAPIS_URL)).toBeVisible(); expect(canvas.getByText('\"name\": \"ORF1a\",', { exact: false })).toBeVisible(); }); }, }"
|
|
87
|
+
"default": "{ ...Template, play: async ({ canvasElement }) => { const canvas = within(canvasElement); await waitFor(async () => { await expect(canvas.getByText(LAPIS_URL)).toBeVisible(); await expect(canvas.getByText('\"name\": \"ORF1a\",', { exact: false })).toBeVisible(); }); }, }"
|
|
88
88
|
},
|
|
89
89
|
{
|
|
90
90
|
"kind": "variable",
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
"type": {
|
|
93
93
|
"text": "StoryObj<{ lapis: string }>"
|
|
94
94
|
},
|
|
95
|
-
"default": "{ ...Default, args: { ...Default.args, lapis: 'notAValidUrl', }, play: async ({ canvasElement }) => { const canvas = within(canvasElement); await waitFor(() => { expect(canvas.getByText(\"Error: Invalid LAPIS URL: 'notAValidUrl'\", { exact: false })).toBeVisible(); }); }, }"
|
|
95
|
+
"default": "{ ...Default, args: { ...Default.args, lapis: 'notAValidUrl', }, play: async ({ canvasElement }) => { const canvas = within(canvasElement); await waitFor(async () => { await expect(canvas.getByText(\"Error: Invalid LAPIS URL: 'notAValidUrl'\", { exact: false })).toBeVisible(); }); }, }"
|
|
96
96
|
},
|
|
97
97
|
{
|
|
98
98
|
"kind": "variable",
|
|
@@ -108,7 +108,7 @@
|
|
|
108
108
|
"type": {
|
|
109
109
|
"text": "StoryObj<{ lapis: string }>"
|
|
110
110
|
},
|
|
111
|
-
"default": "{ ...Template, args: { lapis: 'https://url.to.lapis-definitely-not-a-valid-url', }, play: async ({ canvasElement }) => { const canvas = within(canvasElement); await waitFor(() => { expect(canvas.getByText('Error: Cannot fetch reference genome.', { exact: false })).toBeVisible(); }); }, }"
|
|
111
|
+
"default": "{ ...Template, args: { lapis: 'https://url.to.lapis-definitely-not-a-valid-url', }, play: async ({ canvasElement }) => { const canvas = within(canvasElement); await waitFor(async () => { await expect(canvas.getByText('Error: Cannot fetch reference genome.', { exact: false })).toBeVisible(); }); }, }"
|
|
112
112
|
},
|
|
113
113
|
{
|
|
114
114
|
"kind": "class",
|
|
@@ -314,7 +314,7 @@
|
|
|
314
314
|
"type": {
|
|
315
315
|
"text": "StoryObj<Required<DateRangeSelectorProps>>"
|
|
316
316
|
},
|
|
317
|
-
"default": "{ ...Default, play: async ({ canvasElement, step }) => { const canvas = await withinShadowRoot(canvasElement, 'gs-date-range-selector'); const filterChangedListenerMock = fn(); const optionChangedListenerMock = fn(); await step('Setup event listener mock',
|
|
317
|
+
"default": "{ ...Default, play: async ({ canvasElement, step }) => { const canvas = await withinShadowRoot(canvasElement, 'gs-date-range-selector'); const filterChangedListenerMock = fn(); const optionChangedListenerMock = fn(); await step('Setup event listener mock', () => { canvasElement.addEventListener('gs-date-range-filter-changed', filterChangedListenerMock); canvasElement.addEventListener('gs-date-range-option-changed', optionChangedListenerMock); }); await step('Expect last 6 months to be selected', async () => { await expect(selectField(canvas)).toHaveValue('Last month'); await waitFor(async () => { await expect(dateToPicker(canvas)).toHaveValue(toYYYYMMDD(new Date())); }); }); await step('Expect event to be fired when selecting a different value', async () => { await userEvent.selectOptions(selectField(canvas), 'CustomDateRange'); await expect(dateToPicker(canvas)).toHaveValue(customDateRange.dateTo); await expect(filterChangedListenerMock).toHaveBeenCalledWith( expect.objectContaining({ detail: { aDateColumnFrom: customDateRange.dateFrom, aDateColumnTo: customDateRange.dateTo, }, }), ); await expect(optionChangedListenerMock).toHaveBeenCalledWith( expect.objectContaining({ detail: customDateRange.label, }), ); }); }, }"
|
|
318
318
|
}
|
|
319
319
|
],
|
|
320
320
|
"exports": [
|
|
@@ -536,7 +536,7 @@
|
|
|
536
536
|
"type": {
|
|
537
537
|
"text": "StoryObj<Required<LineageFilterProps>>"
|
|
538
538
|
},
|
|
539
|
-
"default": "{ ...LineageFilter, play: async ({ canvasElement, step }) => { const canvas = await withinShadowRoot(canvasElement, 'gs-lineage-filter'); const inputField = () => canvas.getByPlaceholderText('Enter a lineage'); const listenerMock = fn(); await step('Setup event listener mock',
|
|
539
|
+
"default": "{ ...LineageFilter, play: async ({ canvasElement, step }) => { const canvas = await withinShadowRoot(canvasElement, 'gs-lineage-filter'); const inputField = () => canvas.getByPlaceholderText('Enter a lineage'); const listenerMock = fn(); await step('Setup event listener mock', () => { canvasElement.addEventListener('gs-lineage-filter-changed', listenerMock); }); await step('wait until data is loaded', async () => { await waitFor(() => { return expect(inputField()).toBeEnabled(); }); }); await step('Enters an invalid lineage value', async () => { await userEvent.type(inputField(), 'notInList'); await expect(listenerMock).not.toHaveBeenCalled(); }); await step('Empty input', async () => { await userEvent.type(inputField(), '{backspace>9/}'); await userEvent.click(canvas.getByLabelText('toggle menu')); await waitFor(() => { return expect(listenerMock.mock.calls.at(-1)![0].detail).toStrictEqual({ pangoLineage: undefined, }); }); }); await step('Enter a valid lineage value', async () => { await userEvent.type(inputField(), 'B.1.1.7*'); await userEvent.click(canvas.getByRole('option', { name: 'B.1.1.7*' })); await waitFor(() => { return expect(listenerMock.mock.calls.at(-1)![0].detail).toStrictEqual({ pangoLineage: 'B.1.1.7*', }); }); }); }, args: { ...LineageFilter.args, value: '', }, }"
|
|
540
540
|
}
|
|
541
541
|
],
|
|
542
542
|
"exports": [
|
|
@@ -767,7 +767,7 @@
|
|
|
767
767
|
"type": {
|
|
768
768
|
"text": "StoryObj<LocationFilterProps>"
|
|
769
769
|
},
|
|
770
|
-
"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',
|
|
770
|
+
"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', () => { 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', }); }); }); }, }"
|
|
771
771
|
}
|
|
772
772
|
],
|
|
773
773
|
"exports": [
|
|
@@ -982,7 +982,7 @@
|
|
|
982
982
|
"type": {
|
|
983
983
|
"text": "StoryObj<MutationFilterProps>"
|
|
984
984
|
},
|
|
985
|
-
"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',
|
|
985
|
+
"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', () => { canvasElement.addEventListener('gs-mutation-filter-changed', listenerMock); }); await step('wait until data is loaded', async () => { await waitFor(() => { return expect(inputField()).toBeEnabled(); }); }); await step('Enter a valid mutation', async () => { await userEvent.type(inputField(), 'A123T'); const option = await canvas.findByRole('option'); await userEvent.click(option); await waitFor(() => expect(listenerMock).toHaveBeenCalledWith( expect.objectContaining({ detail: { nucleotideMutations: ['A123T'], aminoAcidMutations: [], nucleotideInsertions: [], aminoAcidInsertions: [], }, }), ), ); }); }, }"
|
|
986
986
|
},
|
|
987
987
|
{
|
|
988
988
|
"kind": "variable",
|
|
@@ -990,7 +990,7 @@
|
|
|
990
990
|
"type": {
|
|
991
991
|
"text": "StoryObj<MutationFilterProps>"
|
|
992
992
|
},
|
|
993
|
-
"default": "{ ...Template, args: { ...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'); const inputField = () => canvas.getByPlaceholderText('Enter a mutation', { exact: false }); await waitFor(() => { const placeholderText = inputField().getAttribute('placeholder'); expect(placeholderText).toEqual( 'Enter a mutation (e.g. seg1:23T, ins_seg1:10462:A, gene1:57Q, ins_gene1:31:N)', ); }); await waitFor(() => { expect(canvas.getByText('seg1:123T')).toBeVisible(); expect(canvas.getByText('gene2:56')).toBeVisible();
|
|
993
|
+
"default": "{ ...Template, args: { ...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'); const inputField = () => canvas.getByPlaceholderText('Enter a mutation', { exact: false }); await waitFor(async () => { const placeholderText = inputField().getAttribute('placeholder'); await expect(placeholderText).toEqual( 'Enter a mutation (e.g. seg1:23T, ins_seg1:10462:A, gene1:57Q, ins_gene1:31:N)', ); }); await waitFor(async () => { await expect(canvas.getByText('seg1:123T')).toBeVisible(); await expect(canvas.getByText('gene2:56')).toBeVisible(); await expect(canvas.getByText('ins_seg2:78:AAA')).toBeVisible(); }); }, }"
|
|
994
994
|
}
|
|
995
995
|
],
|
|
996
996
|
"exports": [
|
|
@@ -1140,7 +1140,7 @@
|
|
|
1140
1140
|
"type": {
|
|
1141
1141
|
"text": "StoryObj<Required<TextInputProps>>"
|
|
1142
1142
|
},
|
|
1143
|
-
"default": "{ ...Default, play: async ({ canvasElement, step }) => { const canvas = await withinShadowRoot(canvasElement, 'gs-text-input'); const inputField = () => canvas.getByPlaceholderText('Enter host name'); const listenerMock = fn(); await step('Setup event listener mock',
|
|
1143
|
+
"default": "{ ...Default, play: async ({ canvasElement, step }) => { const canvas = await withinShadowRoot(canvasElement, 'gs-text-input'); const inputField = () => canvas.getByPlaceholderText('Enter host name'); const listenerMock = fn(); await step('Setup event listener mock', () => { canvasElement.addEventListener('gs-text-input-changed', listenerMock); }); await step('wait until data is loaded', async () => { await waitFor(() => { return expect(inputField()).toBeEnabled(); }); }); await step('Enters an invalid host name', async () => { await userEvent.type(inputField(), 'notInList'); await expect(listenerMock).not.toHaveBeenCalled(); }); await step('Empty input', async () => { await userEvent.type(inputField(), '{backspace>9/}'); }); await step('Enter a valid host name', async () => { await userEvent.type(inputField(), 'Homo s'); const dropdownOption = await canvas.findByText('Homo sapiens'); await userEvent.click(dropdownOption); }); await step('Verify event is fired with correct detail', async () => { await waitFor(async () => { await expect(listenerMock).toHaveBeenCalledWith( expect.objectContaining({ detail: { host: 'Homo sapiens', }, }), ); }); }); await step('Remove initial value', async () => { await fireEvent.click(canvas.getByRole('button', { name: 'clear selection' })); await expect(listenerMock).toHaveBeenCalledWith( expect.objectContaining({ detail: { host: undefined, }, }), ); }); await step('Empty input', async () => { inputField().blur(); await expect(listenerMock.mock.calls.at(-1)![0].detail).toStrictEqual({ host: undefined, }); }); }, args: { ...Default.args, value: '', }, }"
|
|
1144
1144
|
}
|
|
1145
1145
|
],
|
|
1146
1146
|
"exports": [
|
|
@@ -1513,7 +1513,7 @@
|
|
|
1513
1513
|
"kind": "field",
|
|
1514
1514
|
"name": "views",
|
|
1515
1515
|
"type": {
|
|
1516
|
-
"text": "
|
|
1516
|
+
"text": "('table' | 'bar')[]"
|
|
1517
1517
|
},
|
|
1518
1518
|
"default": "['table']",
|
|
1519
1519
|
"description": "A list of tabs with views that this component should provide.",
|
|
@@ -1603,7 +1603,7 @@
|
|
|
1603
1603
|
{
|
|
1604
1604
|
"name": "views",
|
|
1605
1605
|
"type": {
|
|
1606
|
-
"text": "
|
|
1606
|
+
"text": "('table' | 'bar')[]"
|
|
1607
1607
|
},
|
|
1608
1608
|
"default": "['table']",
|
|
1609
1609
|
"description": "A list of tabs with views that this component should provide.",
|