@genspectrum/dashboard-components 0.1.2 → 0.1.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.
- package/README.md +1 -1
- package/custom-elements.json +453 -67
- package/dist/dashboard-components.js +778 -488
- package/dist/dashboard-components.js.map +1 -1
- package/dist/genspectrum-components.d.ts +277 -50
- package/dist/style.css +132 -139
- package/package.json +9 -5
- package/src/lapisApi/lapisApi.ts +1 -1
- package/src/preact/aggregatedData/__mockData__/aggregated.json +585 -0
- package/src/preact/aggregatedData/aggregate-table.tsx +32 -0
- package/src/preact/aggregatedData/aggregate.stories.tsx +53 -0
- package/src/preact/aggregatedData/aggregate.tsx +102 -0
- package/src/preact/components/ReferenceGenomesAwaiter.tsx +25 -0
- package/src/preact/components/csv-download-button.tsx +8 -2
- package/src/preact/components/headline.tsx +16 -4
- package/src/preact/components/min-max-range-slider.tsx +4 -4
- package/src/preact/components/percent-intput.tsx +2 -3
- package/src/preact/components/resize-container.tsx +23 -0
- package/src/preact/components/table.tsx +1 -0
- package/src/preact/components/tabs.stories.tsx +2 -2
- package/src/preact/components/tabs.tsx +47 -24
- package/src/preact/dateRangeSelector/date-range-selector.stories.tsx +36 -4
- package/src/preact/dateRangeSelector/date-range-selector.tsx +57 -43
- package/src/preact/locationFilter/location-filter.tsx +2 -2
- package/src/preact/mutationComparison/getMutationComparisonTableData.spec.ts +5 -5
- package/src/preact/mutationComparison/getMutationComparisonTableData.ts +45 -10
- package/src/preact/mutationComparison/mutation-comparison-table.tsx +20 -22
- package/src/preact/mutationComparison/mutation-comparison-venn.tsx +6 -3
- package/src/preact/mutationComparison/mutation-comparison.stories.tsx +8 -1
- package/src/preact/mutationComparison/mutation-comparison.tsx +13 -4
- package/src/preact/mutationFilter/mutation-filter.stories.tsx +70 -31
- package/src/preact/mutationFilter/mutation-filter.tsx +62 -14
- package/src/preact/mutations/getInsertionsTableData.spec.ts +6 -4
- package/src/preact/mutations/getInsertionsTableData.ts +1 -1
- package/src/preact/mutations/getMutationsTableData.spec.ts +9 -19
- package/src/preact/mutations/getMutationsTableData.ts +1 -1
- package/src/preact/mutations/mutations-insertions-table.tsx +3 -1
- package/src/preact/mutations/mutations-table.tsx +3 -1
- package/src/preact/mutations/mutations.stories.tsx +8 -1
- package/src/preact/mutations/mutations.tsx +16 -5
- package/src/preact/prevalenceOverTime/prevalence-over-time-bar-chart.tsx +1 -0
- package/src/preact/prevalenceOverTime/prevalence-over-time-bubble-chart.tsx +1 -0
- package/src/preact/prevalenceOverTime/prevalence-over-time-line-chart.tsx +1 -0
- package/src/preact/prevalenceOverTime/prevalence-over-time.stories.tsx +4 -0
- package/src/preact/prevalenceOverTime/prevalence-over-time.tsx +17 -9
- package/src/preact/relativeGrowthAdvantage/relative-growth-advantage-chart.tsx +8 -5
- package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.stories.tsx +12 -0
- package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.tsx +13 -8
- package/src/preact/shared/sort/sortInsertions.spec.ts +11 -10
- package/src/preact/shared/sort/sortInsertions.ts +10 -17
- package/src/preact/shared/sort/sortSubstitutionsAndDeletions.spec.ts +19 -10
- package/src/preact/shared/sort/sortSubstitutionsAndDeletions.ts +45 -12
- package/src/preact/textInput/text-input.stories.tsx +22 -1
- package/src/preact/textInput/text-input.tsx +3 -1
- package/src/query/queryAggregateData.spec.ts +32 -0
- package/src/query/queryAggregateData.ts +25 -0
- package/src/utils/typeAssertions.spec.ts +31 -0
- package/src/utils/typeAssertions.ts +16 -0
- package/src/web-components/PreactLitAdapter.tsx +0 -1
- package/src/web-components/app.stories.ts +129 -0
- package/src/web-components/app.ts +27 -6
- package/src/web-components/display/aggregate-component.stories.ts +73 -0
- package/src/web-components/display/aggregate-component.tsx +58 -0
- package/src/web-components/display/index.ts +1 -0
- package/src/web-components/display/mutation-comparison-component.stories.ts +29 -11
- package/src/web-components/display/mutation-comparison-component.tsx +72 -4
- package/src/web-components/display/mutations-component.stories.ts +14 -13
- package/src/web-components/display/mutations-component.tsx +14 -1
- package/src/web-components/display/prevalence-over-time-component.stories.ts +20 -18
- package/src/web-components/display/prevalence-over-time-component.tsx +12 -0
- package/src/web-components/display/relative-growth-advantage-component.stories.ts +11 -10
- package/src/web-components/display/relative-growth-advantage-component.tsx +12 -0
- package/src/web-components/input/date-range-selector-component.stories.ts +35 -8
- package/src/web-components/input/date-range-selector-component.tsx +18 -5
- package/src/web-components/input/location-filter-component.stories.ts +17 -8
- package/src/web-components/input/location-filter-component.tsx +2 -6
- package/src/web-components/input/mutation-filter-component.stories.ts +20 -9
- package/src/web-components/input/mutation-filter-component.tsx +10 -2
- package/src/web-components/input/text-input-component.stories.ts +13 -4
- package/src/web-components/input/text-input-component.tsx +11 -2
- package/src/web-components/input/location-filter.mdx +0 -25
|
@@ -15,8 +15,21 @@ export class MutationsComponent extends PreactLitAdapterWithGridJsStyles {
|
|
|
15
15
|
@property({ type: Array })
|
|
16
16
|
views: View[] = ['table', 'grid'];
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* The size of the component.
|
|
20
|
+
*
|
|
21
|
+
* If not set, the component will take the full width of its container with height 700px.
|
|
22
|
+
*
|
|
23
|
+
* The width and height should be a string with a unit in css style, e.g. '100%', '500px' or '50vh'.
|
|
24
|
+
* If the unit is %, the size will be relative to the container of the component.
|
|
25
|
+
*/
|
|
26
|
+
@property({ type: Object })
|
|
27
|
+
size: { width?: string; height?: string } | undefined = undefined;
|
|
28
|
+
|
|
18
29
|
override render() {
|
|
19
|
-
return
|
|
30
|
+
return (
|
|
31
|
+
<Mutations variant={this.variant} sequenceType={this.sequenceType} views={this.views} size={this.size} />
|
|
32
|
+
);
|
|
20
33
|
}
|
|
21
34
|
}
|
|
22
35
|
|
|
@@ -32,6 +32,7 @@ const meta: Meta<PrevalenceOverTimeProps> = {
|
|
|
32
32
|
options: ['wilson'],
|
|
33
33
|
control: { type: 'check' },
|
|
34
34
|
},
|
|
35
|
+
size: [{ control: 'object' }],
|
|
35
36
|
},
|
|
36
37
|
};
|
|
37
38
|
|
|
@@ -39,18 +40,17 @@ export default meta;
|
|
|
39
40
|
|
|
40
41
|
const Template: StoryObj<PrevalenceOverTimeProps> = {
|
|
41
42
|
render: (args) => html`
|
|
42
|
-
<
|
|
43
|
-
<gs-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
</div>
|
|
43
|
+
<gs-app lapis="${LAPIS_URL}">
|
|
44
|
+
<gs-prevalence-over-time
|
|
45
|
+
.numerator=${args.numerator}
|
|
46
|
+
.denominator=${args.denominator}
|
|
47
|
+
.granularity=${args.granularity}
|
|
48
|
+
.smoothingWindow=${args.smoothingWindow}
|
|
49
|
+
.views=${args.views}
|
|
50
|
+
.confidenceIntervalMethods=${args.confidenceIntervalMethods}
|
|
51
|
+
.size=${args.size}
|
|
52
|
+
></gs-prevalence-over-time>
|
|
53
|
+
</gs-app>
|
|
54
54
|
`,
|
|
55
55
|
};
|
|
56
56
|
|
|
@@ -66,6 +66,7 @@ export const TwoVariants: StoryObj<PrevalenceOverTimeProps> = {
|
|
|
66
66
|
smoothingWindow: 0,
|
|
67
67
|
views: ['bar', 'line', 'bubble', 'table'],
|
|
68
68
|
confidenceIntervalMethods: ['wilson'],
|
|
69
|
+
size: { width: '100%', height: '700px' },
|
|
69
70
|
},
|
|
70
71
|
parameters: {
|
|
71
72
|
fetchMock: {
|
|
@@ -131,6 +132,7 @@ export const OneVariant: StoryObj<PrevalenceOverTimeProps> = {
|
|
|
131
132
|
smoothingWindow: 7,
|
|
132
133
|
views: ['bar', 'line', 'bubble', 'table'],
|
|
133
134
|
confidenceIntervalMethods: ['wilson'],
|
|
135
|
+
size: { width: '100%', height: '700px' },
|
|
134
136
|
},
|
|
135
137
|
parameters: {
|
|
136
138
|
fetchMock: {
|
|
@@ -176,9 +178,9 @@ export const OneVariantOnLineTab: StoryObj<PrevalenceOverTimeProps> = {
|
|
|
176
178
|
play: async ({ canvasElement }) => {
|
|
177
179
|
const canvas = await withinShadowRoot(canvasElement, 'gs-prevalence-over-time');
|
|
178
180
|
|
|
179
|
-
await waitFor(() => expect(canvas.
|
|
181
|
+
await waitFor(() => expect(canvas.getByRole('button', { name: 'Line' })).toBeInTheDocument());
|
|
180
182
|
|
|
181
|
-
await fireEvent.click(canvas.
|
|
183
|
+
await fireEvent.click(canvas.getByRole('button', { name: 'Line' }));
|
|
182
184
|
},
|
|
183
185
|
};
|
|
184
186
|
|
|
@@ -187,9 +189,9 @@ export const OneVariantOnBubbleTab: StoryObj<PrevalenceOverTimeProps> = {
|
|
|
187
189
|
play: async ({ canvasElement }) => {
|
|
188
190
|
const canvas = await withinShadowRoot(canvasElement, 'gs-prevalence-over-time');
|
|
189
191
|
|
|
190
|
-
await waitFor(() => expect(canvas.
|
|
192
|
+
await waitFor(() => expect(canvas.getByRole('button', { name: 'Bubble' })).toBeInTheDocument());
|
|
191
193
|
|
|
192
|
-
await fireEvent.click(canvas.
|
|
194
|
+
await fireEvent.click(canvas.getByRole('button', { name: 'Bubble' }));
|
|
193
195
|
},
|
|
194
196
|
};
|
|
195
197
|
|
|
@@ -198,8 +200,8 @@ export const OneVariantOnTableTab: StoryObj<PrevalenceOverTimeProps> = {
|
|
|
198
200
|
play: async ({ canvasElement }) => {
|
|
199
201
|
const canvas = await withinShadowRoot(canvasElement, 'gs-prevalence-over-time');
|
|
200
202
|
|
|
201
|
-
await waitFor(() => expect(canvas.
|
|
203
|
+
await waitFor(() => expect(canvas.getByRole('button', { name: 'Table' })).toBeInTheDocument());
|
|
202
204
|
|
|
203
|
-
await fireEvent.click(canvas.
|
|
205
|
+
await fireEvent.click(canvas.getByRole('button', { name: 'Table' }));
|
|
204
206
|
},
|
|
205
207
|
};
|
|
@@ -25,6 +25,17 @@ export class PrevalenceOverTimeComponent extends PreactLitAdapterWithGridJsStyle
|
|
|
25
25
|
@property({ type: Array })
|
|
26
26
|
confidenceIntervalMethods: ConfidenceIntervalMethod[] = ['wilson'];
|
|
27
27
|
|
|
28
|
+
/**
|
|
29
|
+
* The size of the component.
|
|
30
|
+
*
|
|
31
|
+
* If not set, the component will take the full width of its container with height 700px.
|
|
32
|
+
*
|
|
33
|
+
* The width and height should be a string with a unit in css style, e.g. '100%', '500px' or '50vh'.
|
|
34
|
+
* If the unit is %, the size will be relative to the container of the component.
|
|
35
|
+
*/
|
|
36
|
+
@property({ type: Object })
|
|
37
|
+
size: { width?: string; height?: string } | undefined = undefined;
|
|
38
|
+
|
|
28
39
|
override render() {
|
|
29
40
|
return (
|
|
30
41
|
<PrevalenceOverTime
|
|
@@ -34,6 +45,7 @@ export class PrevalenceOverTimeComponent extends PreactLitAdapterWithGridJsStyle
|
|
|
34
45
|
smoothingWindow={this.smoothingWindow}
|
|
35
46
|
views={this.views}
|
|
36
47
|
confidenceIntervalMethods={this.confidenceIntervalMethods}
|
|
48
|
+
size={this.size}
|
|
37
49
|
/>
|
|
38
50
|
);
|
|
39
51
|
}
|
|
@@ -19,6 +19,7 @@ const meta: Meta<RelativeGrowthAdvantageProps> = {
|
|
|
19
19
|
options: ['line'],
|
|
20
20
|
control: { type: 'check' },
|
|
21
21
|
},
|
|
22
|
+
size: [{ control: 'object' }],
|
|
22
23
|
},
|
|
23
24
|
};
|
|
24
25
|
|
|
@@ -26,16 +27,15 @@ export default meta;
|
|
|
26
27
|
|
|
27
28
|
const Template: StoryObj<RelativeGrowthAdvantageProps> = {
|
|
28
29
|
render: (args) => html`
|
|
29
|
-
<
|
|
30
|
-
<gs-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
</div>
|
|
30
|
+
<gs-app lapis="${LAPIS_URL}">
|
|
31
|
+
<gs-relative-growth-advantage
|
|
32
|
+
.numerator=${args.numerator}
|
|
33
|
+
.denominator=${args.denominator}
|
|
34
|
+
.generationTime=${args.generationTime}
|
|
35
|
+
.views=${args.views}
|
|
36
|
+
.size=${args.size}
|
|
37
|
+
></gs-relative-growth-advantage>
|
|
38
|
+
</gs-app>
|
|
39
39
|
`,
|
|
40
40
|
};
|
|
41
41
|
|
|
@@ -46,6 +46,7 @@ export const Default: StoryObj<RelativeGrowthAdvantageProps> = {
|
|
|
46
46
|
denominator: { country: 'Switzerland', dateFrom: '2020-12-01', dateTo: '2021-03-01' },
|
|
47
47
|
generationTime: 7,
|
|
48
48
|
views: ['line'],
|
|
49
|
+
size: { width: '100%', height: '700px' },
|
|
49
50
|
},
|
|
50
51
|
parameters: {
|
|
51
52
|
fetchMock: {
|
|
@@ -18,6 +18,17 @@ export class RelativeGrowthAdvantageComponent extends PreactLitAdapter {
|
|
|
18
18
|
@property({ type: Array })
|
|
19
19
|
views: View[] = ['line'];
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* The size of the component.
|
|
23
|
+
*
|
|
24
|
+
* If not set, the component will take the full width of its container with height 700px.
|
|
25
|
+
*
|
|
26
|
+
* The width and height should be a string with a unit in css style, e.g. '100%', '500px' or '50vh'.
|
|
27
|
+
* If the unit is %, the size will be relative to the container of the component.
|
|
28
|
+
*/
|
|
29
|
+
@property({ type: Object })
|
|
30
|
+
size: { width?: string; height?: string } | undefined = undefined;
|
|
31
|
+
|
|
21
32
|
override render() {
|
|
22
33
|
return (
|
|
23
34
|
<RelativeGrowthAdvantage
|
|
@@ -25,6 +36,7 @@ export class RelativeGrowthAdvantageComponent extends PreactLitAdapter {
|
|
|
25
36
|
denominator={this.denominator}
|
|
26
37
|
generationTime={this.generationTime}
|
|
27
38
|
views={this.views}
|
|
39
|
+
size={this.size}
|
|
28
40
|
/>
|
|
29
41
|
);
|
|
30
42
|
}
|
|
@@ -4,13 +4,22 @@ import type { Meta, StoryObj } from '@storybook/web-components';
|
|
|
4
4
|
import { html } from 'lit';
|
|
5
5
|
|
|
6
6
|
import { LAPIS_URL } from '../../constants';
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
type DateRangeSelectorProps,
|
|
9
|
+
PRESET_VALUE_ALL_TIMES,
|
|
10
|
+
PRESET_VALUE_CUSTOM,
|
|
11
|
+
PRESET_VALUE_LAST_2_MONTHS,
|
|
12
|
+
PRESET_VALUE_LAST_2_WEEKS,
|
|
13
|
+
PRESET_VALUE_LAST_3_MONTHS,
|
|
14
|
+
PRESET_VALUE_LAST_6_MONTHS,
|
|
15
|
+
PRESET_VALUE_LAST_MONTH,
|
|
16
|
+
} from '../../preact/dateRangeSelector/date-range-selector';
|
|
8
17
|
import './date-range-selector-component';
|
|
9
18
|
import '../app';
|
|
10
19
|
import { toYYYYMMDD } from '../../preact/dateRangeSelector/dateConversion';
|
|
11
20
|
import { withinShadowRoot } from '../withinShadowRoot.story';
|
|
12
21
|
|
|
13
|
-
const meta: Meta<DateRangeSelectorProps
|
|
22
|
+
const meta: Meta<DateRangeSelectorProps<'CustomDateRange'>> = {
|
|
14
23
|
title: 'Input/DateRangeSelector',
|
|
15
24
|
component: 'gs-date-range-selector',
|
|
16
25
|
parameters: {
|
|
@@ -19,22 +28,44 @@ const meta: Meta<DateRangeSelectorProps> = {
|
|
|
19
28
|
},
|
|
20
29
|
fetchMock: {},
|
|
21
30
|
},
|
|
31
|
+
argTypes: {
|
|
32
|
+
initialValue: {
|
|
33
|
+
control: {
|
|
34
|
+
type: 'select',
|
|
35
|
+
},
|
|
36
|
+
options: [
|
|
37
|
+
PRESET_VALUE_CUSTOM,
|
|
38
|
+
PRESET_VALUE_ALL_TIMES,
|
|
39
|
+
PRESET_VALUE_LAST_2_WEEKS,
|
|
40
|
+
PRESET_VALUE_LAST_MONTH,
|
|
41
|
+
PRESET_VALUE_LAST_2_MONTHS,
|
|
42
|
+
PRESET_VALUE_LAST_3_MONTHS,
|
|
43
|
+
PRESET_VALUE_LAST_6_MONTHS,
|
|
44
|
+
'CustomDateRange',
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
args: {
|
|
49
|
+
customSelectOptions: [{ label: 'CustomDateRange', dateFrom: '2021-01-01', dateTo: '2021-12-31' }],
|
|
50
|
+
earliestDate: '1970-01-01',
|
|
51
|
+
initialValue: PRESET_VALUE_LAST_6_MONTHS,
|
|
52
|
+
},
|
|
22
53
|
decorators: [withActions],
|
|
23
54
|
};
|
|
24
55
|
|
|
25
56
|
export default meta;
|
|
26
57
|
|
|
27
|
-
export const DateRangeSelectorStory: StoryObj<DateRangeSelectorProps
|
|
58
|
+
export const DateRangeSelectorStory: StoryObj<DateRangeSelectorProps<'CustomDateRange'>> = {
|
|
28
59
|
render: (args) =>
|
|
29
60
|
html` <gs-app lapis="${LAPIS_URL}">
|
|
30
61
|
<div class="max-w-screen-lg">
|
|
31
62
|
<gs-date-range-selector
|
|
32
63
|
.customSelectOptions=${args.customSelectOptions}
|
|
33
64
|
.earliestDate=${args.earliestDate}
|
|
65
|
+
.initialValue=${args.initialValue}
|
|
34
66
|
></gs-date-range-selector>
|
|
35
67
|
</div>
|
|
36
68
|
</gs-app>`,
|
|
37
|
-
|
|
38
69
|
play: async ({ canvasElement, step }) => {
|
|
39
70
|
const canvas = await withinShadowRoot(canvasElement, 'gs-date-range-selector');
|
|
40
71
|
const dateTo = () => canvas.getByPlaceholderText('Date to');
|
|
@@ -46,8 +77,4 @@ export const DateRangeSelectorStory: StoryObj<DateRangeSelectorProps> = {
|
|
|
46
77
|
});
|
|
47
78
|
});
|
|
48
79
|
},
|
|
49
|
-
args: {
|
|
50
|
-
customSelectOptions: [{ label: 'CustomDateRange', dateFrom: '2021-01-01', dateTo: '2021-12-31' }],
|
|
51
|
-
earliestDate: '1970-01-01',
|
|
52
|
-
},
|
|
53
80
|
};
|
|
@@ -1,27 +1,40 @@
|
|
|
1
1
|
import { customElement, property } from 'lit/decorators.js';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
type CustomSelectOption,
|
|
5
|
+
DateRangeSelector,
|
|
6
|
+
type PresetOptionValues,
|
|
7
|
+
} from '../../preact/dateRangeSelector/date-range-selector';
|
|
4
8
|
import { PreactLitAdapter } from '../PreactLitAdapter';
|
|
5
9
|
|
|
6
10
|
/**
|
|
7
11
|
* @fires {CustomEvent<{ dateFrom: string; dateTo: string; }>} gs-date-range-changed - When the date range has changed
|
|
8
12
|
*/
|
|
9
13
|
@customElement('gs-date-range-selector')
|
|
10
|
-
export class DateRangeSelectorComponent extends PreactLitAdapter {
|
|
14
|
+
export class DateRangeSelectorComponent<CustomLabel extends string> extends PreactLitAdapter {
|
|
11
15
|
@property({ type: Array })
|
|
12
|
-
customSelectOptions: CustomSelectOption[] = [];
|
|
16
|
+
customSelectOptions: CustomSelectOption<CustomLabel>[] = [];
|
|
13
17
|
|
|
14
18
|
@property({ type: String })
|
|
15
19
|
earliestDate: string | undefined = '1900-01-01';
|
|
16
20
|
|
|
21
|
+
@property()
|
|
22
|
+
initialValue: PresetOptionValues | CustomLabel | string | undefined = '';
|
|
23
|
+
|
|
17
24
|
override render() {
|
|
18
|
-
return
|
|
25
|
+
return (
|
|
26
|
+
<DateRangeSelector
|
|
27
|
+
customSelectOptions={this.customSelectOptions}
|
|
28
|
+
earliestDate={this.earliestDate}
|
|
29
|
+
initialValue={this.initialValue}
|
|
30
|
+
/>
|
|
31
|
+
);
|
|
19
32
|
}
|
|
20
33
|
}
|
|
21
34
|
|
|
22
35
|
declare global {
|
|
23
36
|
interface HTMLElementTagNameMap {
|
|
24
|
-
'gs-date-range-selector': DateRangeSelectorComponent
|
|
37
|
+
'gs-date-range-selector': DateRangeSelectorComponent<string>;
|
|
25
38
|
}
|
|
26
39
|
|
|
27
40
|
interface HTMLElementEventMap {
|
|
@@ -4,6 +4,7 @@ import type { Meta, StoryObj } from '@storybook/web-components';
|
|
|
4
4
|
import { html } from 'lit';
|
|
5
5
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
6
6
|
|
|
7
|
+
import { withComponentDocs } from '../../../.storybook/ComponentDocsBlock';
|
|
7
8
|
import { AGGREGATED_ENDPOINT, LAPIS_URL } from '../../constants';
|
|
8
9
|
import '../app';
|
|
9
10
|
import './location-filter-component';
|
|
@@ -14,12 +15,19 @@ import { withinShadowRoot } from '../withinShadowRoot.story';
|
|
|
14
15
|
const meta: Meta = {
|
|
15
16
|
title: 'Input/Location filter',
|
|
16
17
|
component: 'gs-location-filter',
|
|
17
|
-
parameters: {
|
|
18
|
+
parameters: withComponentDocs({
|
|
18
19
|
actions: {
|
|
19
20
|
handles: ['gs-location-changed'],
|
|
20
21
|
},
|
|
21
|
-
|
|
22
|
+
componentDocs: {
|
|
23
|
+
tag: 'gs-location-filter',
|
|
24
|
+
opensShadowDom: true,
|
|
25
|
+
expectsChildren: false,
|
|
26
|
+
codeExample: `<gs-location-filter fields="['continent', 'country']" value='Europe / Switzerland'></gs-location-filter>`,
|
|
27
|
+
},
|
|
28
|
+
}),
|
|
22
29
|
decorators: [withActions],
|
|
30
|
+
tags: ['autodocs'],
|
|
23
31
|
};
|
|
24
32
|
|
|
25
33
|
export default meta;
|
|
@@ -28,13 +36,16 @@ const Template: StoryObj<LocationFilterProps> = {
|
|
|
28
36
|
render: (args) => {
|
|
29
37
|
return html` <gs-app lapis="${LAPIS_URL}">
|
|
30
38
|
<div class="max-w-screen-lg">
|
|
31
|
-
<gs-location-filter
|
|
39
|
+
<gs-location-filter
|
|
40
|
+
.fields=${args.fields}
|
|
41
|
+
initialValue=${ifDefined(args.initialValue)}
|
|
42
|
+
></gs-location-filter>
|
|
32
43
|
</div>
|
|
33
44
|
</gs-app>`;
|
|
34
45
|
},
|
|
35
46
|
args: {
|
|
36
47
|
fields: ['region', 'country', 'division', 'location'],
|
|
37
|
-
|
|
48
|
+
initialValue: '',
|
|
38
49
|
},
|
|
39
50
|
};
|
|
40
51
|
|
|
@@ -97,7 +108,7 @@ export const FetchingLocationsFails: StoryObj<LocationFilterProps> = {
|
|
|
97
108
|
{
|
|
98
109
|
matcher: aggregatedEndpointMatcher,
|
|
99
110
|
response: {
|
|
100
|
-
status:
|
|
111
|
+
status: 400,
|
|
101
112
|
body: { error: 'no data' },
|
|
102
113
|
},
|
|
103
114
|
},
|
|
@@ -108,9 +119,7 @@ export const FetchingLocationsFails: StoryObj<LocationFilterProps> = {
|
|
|
108
119
|
const canvas = await withinShadowRoot(canvasElement, 'gs-location-filter');
|
|
109
120
|
|
|
110
121
|
await waitFor(() =>
|
|
111
|
-
expect(
|
|
112
|
-
canvas.getByText('Internal Server Error: {"error":"no data"} ', { exact: false }),
|
|
113
|
-
).toBeInTheDocument(),
|
|
122
|
+
expect(canvas.getByText('Bad Request: {"error":"no data"} ', { exact: false })).toBeInTheDocument(),
|
|
114
123
|
);
|
|
115
124
|
},
|
|
116
125
|
};
|
|
@@ -4,10 +4,6 @@ import { LocationFilter } from '../../preact/locationFilter/location-filter';
|
|
|
4
4
|
import { PreactLitAdapter } from '../PreactLitAdapter';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* ## Tag
|
|
8
|
-
*
|
|
9
|
-
* `gs-location-filter`
|
|
10
|
-
*
|
|
11
7
|
* ## Context
|
|
12
8
|
*
|
|
13
9
|
* This component provides an input field to specify filters for locations.
|
|
@@ -41,7 +37,7 @@ export class LocationFilterComponent extends PreactLitAdapter {
|
|
|
41
37
|
* Must be of the form `valueForField1 / valueForField2 / ... / valueForFieldN`.
|
|
42
38
|
*/
|
|
43
39
|
@property()
|
|
44
|
-
|
|
40
|
+
initialValue = '';
|
|
45
41
|
|
|
46
42
|
/**
|
|
47
43
|
* The fields to display in the location filter, in hierarchical order.
|
|
@@ -53,7 +49,7 @@ export class LocationFilterComponent extends PreactLitAdapter {
|
|
|
53
49
|
fields: string[] = [];
|
|
54
50
|
|
|
55
51
|
override render() {
|
|
56
|
-
return <LocationFilter
|
|
52
|
+
return <LocationFilter initialValue={this.initialValue} fields={this.fields} />;
|
|
57
53
|
}
|
|
58
54
|
}
|
|
59
55
|
|
|
@@ -5,6 +5,7 @@ import { html } from 'lit';
|
|
|
5
5
|
|
|
6
6
|
import { LAPIS_URL } from '../../constants';
|
|
7
7
|
import '../app';
|
|
8
|
+
import { type MutationFilterProps } from '../../preact/mutationFilter/mutation-filter';
|
|
8
9
|
import { withinShadowRoot } from '../withinShadowRoot.story';
|
|
9
10
|
import './mutation-filter-component';
|
|
10
11
|
|
|
@@ -22,22 +23,32 @@ const meta: Meta = {
|
|
|
22
23
|
|
|
23
24
|
export default meta;
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
render: () => {
|
|
26
|
+
const Template: StoryObj<MutationFilterProps> = {
|
|
27
|
+
render: (args) => {
|
|
27
28
|
return html` <gs-app lapis="${LAPIS_URL}">
|
|
28
29
|
<div class="max-w-screen-lg">
|
|
29
|
-
<gs-mutation-filter></gs-mutation-filter>
|
|
30
|
+
<gs-mutation-filter .initialValue=${args.initialValue}></gs-mutation-filter>
|
|
30
31
|
</div>
|
|
31
32
|
</gs-app>`;
|
|
32
33
|
},
|
|
34
|
+
args: {
|
|
35
|
+
initialValue: [],
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const Default: StoryObj<MutationFilterProps> = {
|
|
40
|
+
...Template,
|
|
41
|
+
args: {
|
|
42
|
+
initialValue: ['A123T'],
|
|
43
|
+
},
|
|
33
44
|
};
|
|
34
45
|
|
|
35
|
-
export const FiresFilterChangedEvent: StoryObj<
|
|
36
|
-
...
|
|
46
|
+
export const FiresFilterChangedEvent: StoryObj<MutationFilterProps> = {
|
|
47
|
+
...Template,
|
|
37
48
|
play: async ({ canvasElement, step }) => {
|
|
38
49
|
const canvas = await withinShadowRoot(canvasElement, 'gs-mutation-filter');
|
|
39
50
|
|
|
40
|
-
const inputField = () => canvas.getByPlaceholderText('Enter a mutation');
|
|
51
|
+
const inputField = () => canvas.getByPlaceholderText('Enter a mutation', { exact: false });
|
|
41
52
|
const submitButton = () => canvas.getByRole('button', { name: '+' });
|
|
42
53
|
const listenerMock = fn();
|
|
43
54
|
await step('Setup event listener mock', async () => {
|
|
@@ -70,12 +81,12 @@ export const FiresFilterChangedEvent: StoryObj<{ lapisField: string; placeholder
|
|
|
70
81
|
},
|
|
71
82
|
};
|
|
72
83
|
|
|
73
|
-
export const FiresFilterOnBlurEvent: StoryObj<
|
|
74
|
-
...
|
|
84
|
+
export const FiresFilterOnBlurEvent: StoryObj<MutationFilterProps> = {
|
|
85
|
+
...Template,
|
|
75
86
|
play: async ({ canvasElement, step }) => {
|
|
76
87
|
const canvas = await withinShadowRoot(canvasElement, 'gs-mutation-filter');
|
|
77
88
|
|
|
78
|
-
const inputField = () => canvas.getByPlaceholderText('Enter a mutation');
|
|
89
|
+
const inputField = () => canvas.getByPlaceholderText('Enter a mutation', { exact: false });
|
|
79
90
|
const listenerMock = fn();
|
|
80
91
|
await step('Setup event listener mock', async () => {
|
|
81
92
|
canvasElement.addEventListener('gs-mutation-filter-on-blur', listenerMock);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { customElement } from 'lit/decorators.js';
|
|
1
|
+
import { customElement, property } from 'lit/decorators.js';
|
|
2
2
|
|
|
3
3
|
import { type TextInputComponent } from './text-input-component';
|
|
4
|
+
import { ReferenceGenomesAwaiter } from '../../preact/components/ReferenceGenomesAwaiter';
|
|
4
5
|
import { MutationFilter, type SelectedMutationFilterStrings } from '../../preact/mutationFilter/mutation-filter';
|
|
5
6
|
import { PreactLitAdapter } from '../PreactLitAdapter';
|
|
6
7
|
|
|
@@ -10,8 +11,15 @@ import { PreactLitAdapter } from '../PreactLitAdapter';
|
|
|
10
11
|
*/
|
|
11
12
|
@customElement('gs-mutation-filter')
|
|
12
13
|
export class MutationFilterComponent extends PreactLitAdapter {
|
|
14
|
+
@property()
|
|
15
|
+
initialValue: SelectedMutationFilterStrings | string[] | undefined = undefined;
|
|
16
|
+
|
|
13
17
|
override render() {
|
|
14
|
-
return
|
|
18
|
+
return (
|
|
19
|
+
<ReferenceGenomesAwaiter>
|
|
20
|
+
<MutationFilter initialValue={this.initialValue} />
|
|
21
|
+
</ReferenceGenomesAwaiter>
|
|
22
|
+
);
|
|
15
23
|
}
|
|
16
24
|
}
|
|
17
25
|
|
|
@@ -7,6 +7,7 @@ import { AGGREGATED_ENDPOINT, LAPIS_URL } from '../../constants';
|
|
|
7
7
|
import '../app';
|
|
8
8
|
import './text-input-component';
|
|
9
9
|
import data from '../../preact/textInput/__mockData__/aggregated_hosts.json';
|
|
10
|
+
import type { TextInputProps } from '../../preact/textInput/text-input';
|
|
10
11
|
import { withinShadowRoot } from '../withinShadowRoot.story';
|
|
11
12
|
|
|
12
13
|
const meta: Meta = {
|
|
@@ -35,26 +36,30 @@ const meta: Meta = {
|
|
|
35
36
|
},
|
|
36
37
|
},
|
|
37
38
|
decorators: [withActions],
|
|
38
|
-
tags: ['autodocs'],
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
export default meta;
|
|
42
42
|
|
|
43
|
-
export const Default: StoryObj<
|
|
43
|
+
export const Default: StoryObj<TextInputProps> = {
|
|
44
44
|
render: (args) => {
|
|
45
45
|
return html` <gs-app lapis="${LAPIS_URL}">
|
|
46
46
|
<div class="max-w-screen-lg">
|
|
47
|
-
<gs-text-input
|
|
47
|
+
<gs-text-input
|
|
48
|
+
.lapisField=${args.lapisField}
|
|
49
|
+
.placeholderText=${args.placeholderText}
|
|
50
|
+
.initialValue=${args.initialValue}
|
|
51
|
+
></gs-text-input>
|
|
48
52
|
</div>
|
|
49
53
|
</gs-app>`;
|
|
50
54
|
},
|
|
51
55
|
args: {
|
|
52
56
|
lapisField: 'host',
|
|
53
57
|
placeholderText: 'Enter host name',
|
|
58
|
+
initialValue: 'Homo sapiens',
|
|
54
59
|
},
|
|
55
60
|
};
|
|
56
61
|
|
|
57
|
-
export const FiresEvent: StoryObj<
|
|
62
|
+
export const FiresEvent: StoryObj<TextInputProps> = {
|
|
58
63
|
...Default,
|
|
59
64
|
play: async ({ canvasElement, step }) => {
|
|
60
65
|
const canvas = await withinShadowRoot(canvasElement, 'gs-text-input');
|
|
@@ -89,4 +94,8 @@ export const FiresEvent: StoryObj<{ lapisField: string; placeholderText: string
|
|
|
89
94
|
);
|
|
90
95
|
});
|
|
91
96
|
},
|
|
97
|
+
args: {
|
|
98
|
+
...Default.args,
|
|
99
|
+
initialValue: '',
|
|
100
|
+
},
|
|
92
101
|
};
|
|
@@ -8,14 +8,23 @@ import { PreactLitAdapter } from '../PreactLitAdapter';
|
|
|
8
8
|
*/
|
|
9
9
|
@customElement('gs-text-input')
|
|
10
10
|
export class TextInputComponent extends PreactLitAdapter {
|
|
11
|
+
@property()
|
|
12
|
+
initialValue: string | undefined = '';
|
|
13
|
+
|
|
11
14
|
@property()
|
|
12
15
|
lapisField = '';
|
|
13
16
|
|
|
14
17
|
@property()
|
|
15
|
-
placeholderText = '';
|
|
18
|
+
placeholderText: string | undefined = '';
|
|
16
19
|
|
|
17
20
|
override render() {
|
|
18
|
-
return
|
|
21
|
+
return (
|
|
22
|
+
<TextInput
|
|
23
|
+
lapisField={this.lapisField}
|
|
24
|
+
placeholderText={this.placeholderText}
|
|
25
|
+
initialValue={this.initialValue}
|
|
26
|
+
/>
|
|
27
|
+
);
|
|
19
28
|
}
|
|
20
29
|
}
|
|
21
30
|
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { ArgTypes, Description, Meta, Story, Title, Source } from '@storybook/blocks';
|
|
2
|
-
|
|
3
|
-
import * as LocationFilterStories from './location-filter-component.stories.ts';
|
|
4
|
-
|
|
5
|
-
<Meta of={LocationFilterStories} name='Docs' />
|
|
6
|
-
|
|
7
|
-
<Title of={LocationFilterStories} />
|
|
8
|
-
|
|
9
|
-
<Description of={LocationFilterStories} />
|
|
10
|
-
|
|
11
|
-
## Specification
|
|
12
|
-
|
|
13
|
-
<ArgTypes of={LocationFilterStories} />
|
|
14
|
-
|
|
15
|
-
## Example
|
|
16
|
-
|
|
17
|
-
<Source
|
|
18
|
-
code={`<gs-location-filter fields="['continent', 'country']" value='Europe / Switzerland'></gs-location-filter>`}
|
|
19
|
-
/>
|
|
20
|
-
|
|
21
|
-
### Live Example
|
|
22
|
-
|
|
23
|
-
[See here](?path=/story/input-location-filter--location-filter)
|
|
24
|
-
|
|
25
|
-
<Story of={LocationFilterStories.LocationFilter} />
|