@genspectrum/dashboard-components 0.3.0 → 0.3.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.
@@ -483,7 +483,7 @@
483
483
  "type": {
484
484
  "text": "StoryObj<LocationFilterProps>"
485
485
  },
486
- "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 submitButton = () => canvas.getByRole('button', { name: 'Submit' }); 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 userEvent.click(submitButton()); await expect(listenerMock).not.toHaveBeenCalled(); await userEvent.type(inputField(), '{backspace>18/}'); }); await step('Select Asia', async () => { await userEvent.type(inputField(), 'Asia'); await userEvent.click(submitButton()); await expect(listenerMock).toHaveBeenCalledWith( expect.objectContaining({ detail: { region: 'Asia', }, }), ); }); await step('Select Asia / Bangladesh / Rajshahi / Chapainawabgonj', async () => { await userEvent.type(inputField(), ' / Bangladesh / Rajshahi / Chapainawabgonj'); await userEvent.click(submitButton()); await expect(listenerMock).toHaveBeenCalledWith( expect.objectContaining({ detail: { region: 'Asia', country: 'Bangladesh', division: 'Rajshahi', location: 'Chapainawabgonj', }, }), ); }); }, }"
486
+ "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 userEvent.type(inputField(), '{backspace>18/}'); }); await step('Select Asia', async () => { await userEvent.type(inputField(), 'Asia'); await expect(listenerMock).toHaveBeenCalledWith( expect.objectContaining({ detail: { region: 'Asia', }, }), ); }); await step('Select Asia / Bangladesh / Rajshahi / Chapainawabgonj', async () => { await userEvent.type(inputField(), ' / Bangladesh / Rajshahi / Chapainawabgonj'); await expect(listenerMock).toHaveBeenCalledWith( expect.objectContaining({ detail: { region: 'Asia', country: 'Bangladesh', division: 'Rajshahi', location: 'Chapainawabgonj', }, }), ); }); }, }"
487
487
  }
488
488
  ],
489
489
  "exports": [
@@ -574,7 +574,7 @@
574
574
  "type": {
575
575
  "text": "CustomEvent<Record<string, string>>"
576
576
  },
577
- "description": "Fired when the field is submitted with a valid location value. The `details` of this event contain an object with all `fields` as keys and the corresponding values as values, if they are not `undefined`. Example: ``` { continent: \"Asia\", country: \"China\", city: \"Beijing\" } ```",
577
+ "description": "Fired when a value from the datalist is selected or when a valid value is typed into the field. The `details` of this event contain an object with all `fields` as keys and the corresponding values as values, if they are not `undefined`. Example: ``` { continent: \"Asia\", country: \"China\", city: \"Beijing\" } ```",
578
578
  "name": "gs-location-changed"
579
579
  }
580
580
  ],
@@ -1740,7 +1740,7 @@
1740
1740
  "type": {
1741
1741
  "text": "StoryObj<Required<PrevalenceOverTimeProps>>"
1742
1742
  },
1743
- "default": "{ ...Template, args: { numerator: [ { displayName: 'EG', lapisFilter: { country: 'USA', pangoLineage: 'EG*', dateFrom: '2023-01-01' } }, { displayName: 'JN.1', lapisFilter: { country: 'USA', pangoLineage: 'JN.1*', dateFrom: '2023-01-01' } }, ], denominator: { country: 'USA', dateFrom: '2023-01-01' }, granularity: 'month', smoothingWindow: 0, views: ['bar', 'line', 'bubble', 'table'], confidenceIntervalMethods: ['wilson'], width: '100%', height: '700px', headline: 'Prevalence over time', }, parameters: { fetchMock: { mocks: [ { matcher: { name: 'numeratorEG', url: AGGREGATED_ENDPOINT, body: { country: 'USA', pangoLineage: 'EG*', dateFrom: '2023-01-01', fields: ['date'], }, }, response: { status: 200, body: numeratorEG, }, }, { matcher: { name: 'numeratorJN1', url: AGGREGATED_ENDPOINT, body: { country: 'USA', pangoLineage: 'JN.1*', dateFrom: '2023-01-01', fields: ['date'], }, }, response: { status: 200, body: numeratorJN1, }, }, { matcher: { name: 'denominator', url: AGGREGATED_ENDPOINT, body: { country: 'USA', dateFrom: '2023-01-01', fields: ['date'], }, }, response: { status: 200, body: denominator, }, }, ], }, }, }"
1743
+ "default": "{ ...Template, args: { numerator: [ { displayName: 'EG', lapisFilter: { country: 'USA', pangoLineage: 'EG*', dateFrom: '2023-01-01' } }, { displayName: 'JN.1', lapisFilter: { country: 'USA', pangoLineage: 'JN.1*', dateFrom: '2023-01-01' } }, ], denominator: { country: 'USA', dateFrom: '2023-01-01' }, granularity: 'month', smoothingWindow: 0, views: ['bar', 'line', 'bubble', 'table'], confidenceIntervalMethods: ['wilson'], width: '100%', height: '700px', headline: 'Prevalence over time', lapisDateField: 'date', }, parameters: { fetchMock: { mocks: [ { matcher: { name: 'numeratorEG', url: AGGREGATED_ENDPOINT, body: { country: 'USA', pangoLineage: 'EG*', dateFrom: '2023-01-01', fields: ['date'], }, }, response: { status: 200, body: numeratorEG, }, }, { matcher: { name: 'numeratorJN1', url: AGGREGATED_ENDPOINT, body: { country: 'USA', pangoLineage: 'JN.1*', dateFrom: '2023-01-01', fields: ['date'], }, }, response: { status: 200, body: numeratorJN1, }, }, { matcher: { name: 'denominator', url: AGGREGATED_ENDPOINT, body: { country: 'USA', dateFrom: '2023-01-01', fields: ['date'], }, }, response: { status: 200, body: denominator, }, }, ], }, }, }"
1744
1744
  },
1745
1745
  {
1746
1746
  "kind": "variable",
@@ -1748,7 +1748,7 @@
1748
1748
  "type": {
1749
1749
  "text": "StoryObj<Required<PrevalenceOverTimeProps>>"
1750
1750
  },
1751
- "default": "{ ...Template, args: { numerator: { displayName: 'EG', lapisFilter: { country: 'USA', pangoLineage: 'BA.2.86*', dateFrom: '2023-10-01' }, }, denominator: { country: 'USA', dateFrom: '2023-10-01' }, granularity: 'day', smoothingWindow: 7, views: ['bar', 'line', 'bubble', 'table'], confidenceIntervalMethods: ['wilson'], width: '100%', height: '700px', headline: 'Prevalence over time', }, parameters: { fetchMock: { mocks: [ { matcher: { name: 'numeratorOneVariant', url: AGGREGATED_ENDPOINT, body: { country: 'USA', pangoLineage: 'BA.2.86*', dateFrom: '2023-10-01', fields: ['date'], }, }, response: { status: 200, body: numeratorOneVariant, }, }, { matcher: { name: 'denominatorOneVariant', url: AGGREGATED_ENDPOINT, body: { country: 'USA', dateFrom: '2023-10-01', fields: ['date'], }, }, response: { status: 200, body: denominatorOneVariant, }, }, ], }, }, }"
1751
+ "default": "{ ...Template, args: { numerator: { displayName: 'EG', lapisFilter: { country: 'USA', pangoLineage: 'BA.2.86*', dateFrom: '2023-10-01' }, }, denominator: { country: 'USA', dateFrom: '2023-10-01' }, granularity: 'day', smoothingWindow: 7, views: ['bar', 'line', 'bubble', 'table'], confidenceIntervalMethods: ['wilson'], width: '100%', height: '700px', headline: 'Prevalence over time', lapisDateField: 'date', }, parameters: { fetchMock: { mocks: [ { matcher: { name: 'numeratorOneVariant', url: AGGREGATED_ENDPOINT, body: { country: 'USA', pangoLineage: 'BA.2.86*', dateFrom: '2023-10-01', fields: ['date'], }, }, response: { status: 200, body: numeratorOneVariant, }, }, { matcher: { name: 'denominatorOneVariant', url: AGGREGATED_ENDPOINT, body: { country: 'USA', dateFrom: '2023-10-01', fields: ['date'], }, }, response: { status: 200, body: denominatorOneVariant, }, }, ], }, }, }"
1752
1752
  },
1753
1753
  {
1754
1754
  "kind": "variable",
@@ -1924,6 +1924,16 @@
1924
1924
  "default": "'700px'",
1925
1925
  "description": "The height of the component.\n\nVisit https://genspectrum.github.io/dashboards/?path=/docs/components-size-of-components--docs for more information.",
1926
1926
  "attribute": "height"
1927
+ },
1928
+ {
1929
+ "kind": "field",
1930
+ "name": "lapisDateField",
1931
+ "type": {
1932
+ "text": "string"
1933
+ },
1934
+ "default": "'date'",
1935
+ "description": "Required.\n\nThe LAPIS field that the data should be aggregated by.\nThe values will be used on the x-axis of the diagram.\nMust be a field of type `date` in LAPIS.",
1936
+ "attribute": "lapisDateField"
1927
1937
  }
1928
1938
  ],
1929
1939
  "attributes": [
@@ -2007,6 +2017,15 @@
2007
2017
  "default": "'700px'",
2008
2018
  "description": "The height of the component.\n\nVisit https://genspectrum.github.io/dashboards/?path=/docs/components-size-of-components--docs for more information.",
2009
2019
  "fieldName": "height"
2020
+ },
2021
+ {
2022
+ "name": "lapisDateField",
2023
+ "type": {
2024
+ "text": "string"
2025
+ },
2026
+ "default": "'date'",
2027
+ "description": "Required.\n\nThe LAPIS field that the data should be aggregated by.\nThe values will be used on the x-axis of the diagram.\nMust be a field of type `date` in LAPIS.",
2028
+ "fieldName": "lapisDateField"
2010
2029
  }
2011
2030
  ],
2012
2031
  "superclass": {
@@ -2054,7 +2073,7 @@
2054
2073
  "type": {
2055
2074
  "text": "StoryObj<Required<RelativeGrowthAdvantageProps>>"
2056
2075
  },
2057
- "default": "{ ...Template, args: { numerator: { country: 'Switzerland', pangoLineage: 'B.1.1.7', dateFrom: '2020-12-01', dateTo: '2021-03-01' }, denominator: { country: 'Switzerland', dateFrom: '2020-12-01', dateTo: '2021-03-01' }, generationTime: 7, views: ['line'], width: '100%', height: '700px', headline: 'Relative growth advantage', }, parameters: { fetchMock: { mocks: [ { matcher: { name: 'numerator', url: AGGREGATED_ENDPOINT, body: { country: 'Switzerland', pangoLineage: 'B.1.1.7', dateFrom: '2020-12-01', dateTo: '2021-03-01', fields: ['date'], }, }, response: { status: 200, body: numerator, }, }, { matcher: { name: 'denominator', url: AGGREGATED_ENDPOINT, body: { country: 'Switzerland', dateFrom: '2020-12-01', dateTo: '2021-03-01', fields: ['date'], }, }, response: { status: 200, body: denominator, }, }, ], }, }, }"
2076
+ "default": "{ ...Template, args: { numerator: { country: 'Switzerland', pangoLineage: 'B.1.1.7', dateFrom: '2020-12-01', dateTo: '2021-03-01' }, denominator: { country: 'Switzerland', dateFrom: '2020-12-01', dateTo: '2021-03-01' }, generationTime: 7, views: ['line'], width: '100%', height: '700px', headline: 'Relative growth advantage', lapisDateField: 'date', }, parameters: { fetchMock: { mocks: [ { matcher: { name: 'numerator', url: AGGREGATED_ENDPOINT, body: { country: 'Switzerland', pangoLineage: 'B.1.1.7', dateFrom: '2020-12-01', dateTo: '2021-03-01', fields: ['date'], }, }, response: { status: 200, body: numerator, }, }, { matcher: { name: 'denominator', url: AGGREGATED_ENDPOINT, body: { country: 'Switzerland', dateFrom: '2020-12-01', dateTo: '2021-03-01', fields: ['date'], }, }, response: { status: 200, body: denominator, }, }, ], }, }, }"
2058
2077
  }
2059
2078
  ],
2060
2079
  "exports": [
@@ -2154,6 +2173,16 @@
2154
2173
  "default": "'700px'",
2155
2174
  "description": "The height of the component.\n\nVisit https://genspectrum.github.io/dashboards/?path=/docs/components-size-of-components--docs for more information.",
2156
2175
  "attribute": "height"
2176
+ },
2177
+ {
2178
+ "kind": "field",
2179
+ "name": "lapisDateField",
2180
+ "type": {
2181
+ "text": "string"
2182
+ },
2183
+ "default": "'date'",
2184
+ "description": "Required.\n\nThe LAPIS field that the data should be aggregated by.\nThe values will be used on the x-axis of the diagram.\nMust be a field of type `date` in LAPIS.",
2185
+ "attribute": "lapisDateField"
2157
2186
  }
2158
2187
  ],
2159
2188
  "attributes": [
@@ -2219,6 +2248,15 @@
2219
2248
  "default": "'700px'",
2220
2249
  "description": "The height of the component.\n\nVisit https://genspectrum.github.io/dashboards/?path=/docs/components-size-of-components--docs for more information.",
2221
2250
  "fieldName": "height"
2251
+ },
2252
+ {
2253
+ "name": "lapisDateField",
2254
+ "type": {
2255
+ "text": "string"
2256
+ },
2257
+ "default": "'date'",
2258
+ "description": "Required.\n\nThe LAPIS field that the data should be aggregated by.\nThe values will be used on the x-axis of the diagram.\nMust be a field of type `date` in LAPIS.",
2259
+ "fieldName": "lapisDateField"
2222
2260
  }
2223
2261
  ],
2224
2262
  "superclass": {
@@ -2617,19 +2617,6 @@ html {
2617
2617
  }
2618
2618
  }
2619
2619
 
2620
- .btn-outline.btn-primary:hover {
2621
- --tw-text-opacity: 1;
2622
- color: var(--fallback-pc,oklch(var(--pc)/var(--tw-text-opacity)));
2623
- }
2624
-
2625
- @supports (color: color-mix(in oklab, black, black)) {
2626
-
2627
- .btn-outline.btn-primary:hover {
2628
- background-color: color-mix(in oklab, var(--fallback-p,oklch(var(--p)/1)) 90%, black);
2629
- border-color: color-mix(in oklab, var(--fallback-p,oklch(var(--p)/1)) 90%, black);
2630
- }
2631
- }
2632
-
2633
2620
  .btn-disabled:hover,
2634
2621
  .btn[disabled]:hover,
2635
2622
  .btn:disabled:hover {
@@ -3099,34 +3086,12 @@ input.tab:checked + .tab-content,
3099
3086
  background-color: var(--btn-color, var(--fallback-b2));
3100
3087
  border-color: var(--btn-color, var(--fallback-b2));
3101
3088
  }
3102
-
3103
- .btn-primary {
3104
- --btn-color: var(--fallback-p);
3105
- }
3106
- }
3107
- @supports (color: color-mix(in oklab, black, black)) {
3108
-
3109
- .btn-outline.btn-primary.btn-active {
3110
- background-color: color-mix(in oklab, var(--fallback-p,oklch(var(--p)/1)) 90%, black);
3111
- border-color: color-mix(in oklab, var(--fallback-p,oklch(var(--p)/1)) 90%, black);
3112
- }
3113
3089
  }
3114
3090
  .btn:focus-visible {
3115
3091
  outline-style: solid;
3116
3092
  outline-width: 2px;
3117
3093
  outline-offset: 2px;
3118
3094
  }
3119
- .btn-primary {
3120
- --tw-text-opacity: 1;
3121
- color: var(--fallback-pc,oklch(var(--pc)/var(--tw-text-opacity)));
3122
- outline-color: var(--fallback-p,oklch(var(--p)/1));
3123
- }
3124
- @supports (color: oklch(0% 0 0)) {
3125
-
3126
- .btn-primary {
3127
- --btn-color: var(--p);
3128
- }
3129
- }
3130
3095
  .btn.glass {
3131
3096
  --tw-shadow: 0 0 #0000;
3132
3097
  --tw-shadow-colored: 0 0 #0000;
@@ -3151,14 +3116,6 @@ input.tab:checked + .tab-content,
3151
3116
  border-color: transparent;
3152
3117
  background-color: var(--fallback-bc,oklch(var(--bc)/0.2));
3153
3118
  }
3154
- .btn-outline.btn-primary {
3155
- --tw-text-opacity: 1;
3156
- color: var(--fallback-p,oklch(var(--p)/var(--tw-text-opacity)));
3157
- }
3158
- .btn-outline.btn-primary.btn-active {
3159
- --tw-text-opacity: 1;
3160
- color: var(--fallback-pc,oklch(var(--pc)/var(--tw-text-opacity)));
3161
- }
3162
3119
  .btn.btn-disabled,
3163
3120
  .btn[disabled],
3164
3121
  .btn:disabled {
@@ -4309,9 +4266,6 @@ input.tab:checked + .tab-content,
4309
4266
  .me-1 {
4310
4267
  margin-inline-end: 0.25rem;
4311
4268
  }
4312
- .ml-1 {
4313
- margin-left: 0.25rem;
4314
- }
4315
4269
  .ml-2 {
4316
4270
  margin-left: 0.5rem;
4317
4271
  }
@@ -6513,6 +6467,17 @@ class MapOperator {
6513
6467
  };
6514
6468
  }
6515
6469
  }
6470
+ class RenameFieldOperator extends MapOperator {
6471
+ constructor(child, oldFieldName, newFieldName) {
6472
+ super(
6473
+ child,
6474
+ (value) => ({
6475
+ ...value,
6476
+ [newFieldName]: value[oldFieldName]
6477
+ })
6478
+ );
6479
+ }
6480
+ }
6516
6481
  class SlidingOperator {
6517
6482
  constructor(child, windowSize, aggregate) {
6518
6483
  this.child = child;
@@ -6532,12 +6497,12 @@ class SlidingOperator {
6532
6497
  return { content };
6533
6498
  }
6534
6499
  }
6535
- function queryPrevalenceOverTime(numeratorFilter, denominatorFilter, granularity, smoothingWindow, lapis, signal) {
6500
+ function queryPrevalenceOverTime(numeratorFilter, denominatorFilter, granularity, smoothingWindow, lapis, lapisDateField, signal) {
6536
6501
  const numeratorFilters = makeArray(numeratorFilter);
6537
- const denominatorData = fetchAndPrepare(denominatorFilter, granularity, smoothingWindow);
6502
+ const denominatorData = fetchAndPrepare(denominatorFilter, granularity, smoothingWindow, lapisDateField);
6538
6503
  const subQueries = numeratorFilters.map(async (namedLapisFilter) => {
6539
6504
  const { displayName, lapisFilter } = namedLapisFilter;
6540
- const numeratorData = fetchAndPrepare(lapisFilter, granularity, smoothingWindow);
6505
+ const numeratorData = fetchAndPrepare(lapisFilter, granularity, smoothingWindow, lapisDateField);
6541
6506
  const divide = new DivisionOperator(
6542
6507
  numeratorData,
6543
6508
  denominatorData,
@@ -6561,9 +6526,10 @@ function makeArray(arrayOrSingleItem) {
6561
6526
  }
6562
6527
  return [arrayOrSingleItem];
6563
6528
  }
6564
- function fetchAndPrepare(filter, granularity, smoothingWindow) {
6565
- const fetchData = new FetchAggregatedOperator(filter, ["date"]);
6566
- const mapData = new MapOperator(fetchData, (d2) => mapDateToGranularityRange(d2, granularity));
6529
+ function fetchAndPrepare(filter, granularity, smoothingWindow, lapisDateField) {
6530
+ const fetchData = new FetchAggregatedOperator(filter, [lapisDateField]);
6531
+ const dataWithFixedDateKey = new RenameFieldOperator(fetchData, lapisDateField, "date");
6532
+ const mapData = new MapOperator(dataWithFixedDateKey, (d2) => mapDateToGranularityRange(d2, granularity));
6567
6533
  const groupByData = new GroupByAndSumOperator(mapData, "dateRange", "count");
6568
6534
  const fillData = new FillMissingOperator(
6569
6535
  groupByData,
@@ -6683,7 +6649,8 @@ const PrevalenceOverTime = ({
6683
6649
  confidenceIntervalMethods,
6684
6650
  width,
6685
6651
  height,
6686
- headline = "Prevalence over time"
6652
+ headline = "Prevalence over time",
6653
+ lapisDateField
6687
6654
  }) => {
6688
6655
  const size = { height, width };
6689
6656
  return /* @__PURE__ */ u$1(ErrorBoundary, { size, headline, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(
@@ -6694,7 +6661,8 @@ const PrevalenceOverTime = ({
6694
6661
  granularity,
6695
6662
  smoothingWindow,
6696
6663
  views,
6697
- confidenceIntervalMethods
6664
+ confidenceIntervalMethods,
6665
+ lapisDateField
6698
6666
  }
6699
6667
  ) }) }) });
6700
6668
  };
@@ -6704,11 +6672,12 @@ const PrevalenceOverTimeInner = ({
6704
6672
  granularity,
6705
6673
  smoothingWindow,
6706
6674
  views,
6707
- confidenceIntervalMethods
6675
+ confidenceIntervalMethods,
6676
+ lapisDateField
6708
6677
  }) => {
6709
6678
  const lapis = P(LapisUrlContext);
6710
6679
  const { data, error, isLoading } = useQuery(
6711
- () => queryPrevalenceOverTime(numerator, denominator, granularity, smoothingWindow, lapis),
6680
+ () => queryPrevalenceOverTime(numerator, denominator, granularity, smoothingWindow, lapis, lapisDateField),
6712
6681
  [lapis, numerator, denominator, granularity, smoothingWindow]
6713
6682
  );
6714
6683
  if (isLoading) {
@@ -6854,6 +6823,7 @@ let PrevalenceOverTimeComponent = class extends PreactLitAdapterWithGridJsStyles
6854
6823
  this.headline = "Prevalence over time";
6855
6824
  this.width = "100%";
6856
6825
  this.height = "700px";
6826
+ this.lapisDateField = "date";
6857
6827
  }
6858
6828
  render() {
6859
6829
  return /* @__PURE__ */ u$1(
@@ -6867,7 +6837,8 @@ let PrevalenceOverTimeComponent = class extends PreactLitAdapterWithGridJsStyles
6867
6837
  confidenceIntervalMethods: this.confidenceIntervalMethods,
6868
6838
  width: this.width,
6869
6839
  height: this.height,
6870
- headline: this.headline
6840
+ headline: this.headline,
6841
+ lapisDateField: this.lapisDateField
6871
6842
  }
6872
6843
  );
6873
6844
  }
@@ -6899,6 +6870,9 @@ __decorateClass$6([
6899
6870
  __decorateClass$6([
6900
6871
  n2({ type: String })
6901
6872
  ], PrevalenceOverTimeComponent.prototype, "height", 2);
6873
+ __decorateClass$6([
6874
+ n2({ type: String })
6875
+ ], PrevalenceOverTimeComponent.prototype, "lapisDateField", 2);
6902
6876
  PrevalenceOverTimeComponent = __decorateClass$6([
6903
6877
  t$2("gs-prevalence-over-time")
6904
6878
  ], PrevalenceOverTimeComponent);
@@ -7009,11 +6983,13 @@ const tooltip = () => {
7009
6983
  }
7010
6984
  };
7011
6985
  };
7012
- async function queryRelativeGrowthAdvantage(numerator, denominator, generationTime, lapis, signal) {
7013
- const fetchNumerator = new FetchAggregatedOperator(numerator, ["date"]);
7014
- const fetchDenominator = new FetchAggregatedOperator(denominator, ["date"]);
7015
- const mapNumerator = new MapOperator(fetchNumerator, toYearMonthDay);
7016
- const mapDenominator = new MapOperator(fetchDenominator, toYearMonthDay);
6986
+ async function queryRelativeGrowthAdvantage(numerator, denominator, generationTime, lapis, lapisDateField, signal) {
6987
+ const fetchNumerator = new FetchAggregatedOperator(numerator, [lapisDateField]);
6988
+ const fetchDenominator = new FetchAggregatedOperator(denominator, [lapisDateField]);
6989
+ const mapToFixedDateKeyNumerator = new RenameFieldOperator(fetchNumerator, lapisDateField, "date");
6990
+ const mapToFixedDateKeyDenominator = new RenameFieldOperator(fetchDenominator, lapisDateField, "date");
6991
+ const mapNumerator = new MapOperator(mapToFixedDateKeyNumerator, toYearMonthDay);
6992
+ const mapDenominator = new MapOperator(mapToFixedDateKeyDenominator, toYearMonthDay);
7017
6993
  const [numeratorData, denominatorData] = await Promise.all([
7018
6994
  mapNumerator.evaluate(lapis, signal),
7019
6995
  mapDenominator.evaluate(lapis, signal)
@@ -7094,7 +7070,8 @@ const RelativeGrowthAdvantage = ({
7094
7070
  numerator,
7095
7071
  denominator,
7096
7072
  generationTime,
7097
- headline = "Relative growth advantage"
7073
+ headline = "Relative growth advantage",
7074
+ lapisDateField
7098
7075
  }) => {
7099
7076
  const size = { height, width };
7100
7077
  return /* @__PURE__ */ u$1(ErrorBoundary, { size, headline, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(
@@ -7103,7 +7080,8 @@ const RelativeGrowthAdvantage = ({
7103
7080
  views,
7104
7081
  numerator,
7105
7082
  denominator,
7106
- generationTime
7083
+ generationTime,
7084
+ lapisDateField
7107
7085
  }
7108
7086
  ) }) }) });
7109
7087
  };
@@ -7111,12 +7089,13 @@ const RelativeGrowthAdvantageInner = ({
7111
7089
  numerator,
7112
7090
  denominator,
7113
7091
  generationTime,
7114
- views
7092
+ views,
7093
+ lapisDateField
7115
7094
  }) => {
7116
7095
  const lapis = P(LapisUrlContext);
7117
7096
  const [yAxisScaleType, setYAxisScaleType] = p("linear");
7118
7097
  const { data, error, isLoading } = useQuery(
7119
- () => queryRelativeGrowthAdvantage(numerator, denominator, generationTime, lapis),
7098
+ () => queryRelativeGrowthAdvantage(numerator, denominator, generationTime, lapis, lapisDateField),
7120
7099
  [lapis, numerator, denominator, generationTime, views]
7121
7100
  );
7122
7101
  if (isLoading) {
@@ -7228,6 +7207,7 @@ let RelativeGrowthAdvantageComponent = class extends PreactLitAdapter {
7228
7207
  this.headline = "Relative growth advantage";
7229
7208
  this.width = "100%";
7230
7209
  this.height = "700px";
7210
+ this.lapisDateField = "date";
7231
7211
  }
7232
7212
  render() {
7233
7213
  return /* @__PURE__ */ u$1(
@@ -7239,7 +7219,8 @@ let RelativeGrowthAdvantageComponent = class extends PreactLitAdapter {
7239
7219
  views: this.views,
7240
7220
  width: this.width,
7241
7221
  height: this.height,
7242
- headline: this.headline
7222
+ headline: this.headline,
7223
+ lapisDateField: this.lapisDateField
7243
7224
  }
7244
7225
  );
7245
7226
  }
@@ -7265,6 +7246,9 @@ __decorateClass$5([
7265
7246
  __decorateClass$5([
7266
7247
  n2({ type: String })
7267
7248
  ], RelativeGrowthAdvantageComponent.prototype, "height", 2);
7249
+ __decorateClass$5([
7250
+ n2({ type: String })
7251
+ ], RelativeGrowthAdvantageComponent.prototype, "lapisDateField", 2);
7268
7252
  RelativeGrowthAdvantageComponent = __decorateClass$5([
7269
7253
  t$2("gs-relative-growth-advantage")
7270
7254
  ], RelativeGrowthAdvantageComponent);
@@ -7723,7 +7707,7 @@ const LocationFilterInner = ({ initialValue, fields }) => {
7723
7707
  const lapis = P(LapisUrlContext);
7724
7708
  const [value, setValue] = p(initialValue ?? "");
7725
7709
  const [unknownLocation, setUnknownLocation] = p(false);
7726
- const formRef = F(null);
7710
+ const divRef = F(null);
7727
7711
  const { data, error, isLoading } = useQuery(() => fetchAutocompletionList(fields, lapis), [fields, lapis]);
7728
7712
  if (isLoading) {
7729
7713
  return /* @__PURE__ */ u$1(LoadingDisplay, {});
@@ -7732,35 +7716,27 @@ const LocationFilterInner = ({ initialValue, fields }) => {
7732
7716
  return /* @__PURE__ */ u$1(ErrorDisplay, { error });
7733
7717
  }
7734
7718
  const onInput = (event) => {
7735
- if (event.target instanceof HTMLInputElement) {
7736
- const inputValue = event.target.value;
7737
- setValue(inputValue);
7738
- if (unknownLocation) {
7739
- const eventDetail = parseLocation(inputValue, fields);
7740
- if (hasMatchingEntry(data, eventDetail)) {
7741
- setUnknownLocation(false);
7742
- }
7743
- }
7744
- }
7745
- };
7746
- const submit = (event) => {
7747
7719
  var _a;
7748
- event.preventDefault();
7749
- const eventDetail = parseLocation(value, fields);
7720
+ const inputValue = event.currentTarget.value;
7721
+ setValue(inputValue);
7722
+ if (inputValue.trim() === value.trim()) {
7723
+ return;
7724
+ }
7725
+ const eventDetail = parseLocation(inputValue, fields);
7750
7726
  if (hasMatchingEntry(data, eventDetail)) {
7751
- setUnknownLocation(false);
7752
- (_a = formRef.current) == null ? void 0 : _a.dispatchEvent(
7727
+ (_a = divRef.current) == null ? void 0 : _a.dispatchEvent(
7753
7728
  new CustomEvent("gs-location-changed", {
7754
7729
  detail: eventDetail,
7755
7730
  bubbles: true,
7756
7731
  composed: true
7757
7732
  })
7758
7733
  );
7734
+ setUnknownLocation(false);
7759
7735
  } else {
7760
7736
  setUnknownLocation(true);
7761
7737
  }
7762
7738
  };
7763
- return /* @__PURE__ */ u$1("form", { class: "flex w-full", onSubmit: submit, ref: formRef, children: [
7739
+ return /* @__PURE__ */ u$1("div", { class: "flex w-full", ref: divRef, children: [
7764
7740
  /* @__PURE__ */ u$1(
7765
7741
  "input",
7766
7742
  {
@@ -7774,8 +7750,7 @@ const LocationFilterInner = ({ initialValue, fields }) => {
7774
7750
  /* @__PURE__ */ u$1("datalist", { id: "countries", children: data == null ? void 0 : data.map((v2) => {
7775
7751
  const value2 = fields.map((field) => v2[field]).filter((value3) => value3 !== null).join(" / ");
7776
7752
  return /* @__PURE__ */ u$1("option", { value: value2 }, value2);
7777
- }) }),
7778
- /* @__PURE__ */ u$1("button", { class: "btn btn-primary ml-1", type: "submit", children: "Submit" })
7753
+ }) })
7779
7754
  ] });
7780
7755
  };
7781
7756
  const parseLocation = (location, fields) => {