@genspectrum/dashboard-components 0.8.5 → 0.9.1

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.
Files changed (31) hide show
  1. package/README.md +14 -2
  2. package/custom-elements.json +30 -7
  3. package/dist/{genspectrum-components.d.ts → components.d.ts} +15 -49
  4. package/dist/{dashboard-components.js → components.js} +85 -90
  5. package/dist/components.js.map +1 -0
  6. package/dist/style.css +2 -2
  7. package/dist/util.d.ts +301 -0
  8. package/dist/util.js +6 -0
  9. package/dist/util.js.map +1 -0
  10. package/dist/utilEntrypoint-g4DsyhU7.js +61 -0
  11. package/dist/utilEntrypoint-g4DsyhU7.js.map +1 -0
  12. package/package.json +10 -5
  13. package/src/{index.ts → componentsEntrypoint.ts} +0 -1
  14. package/src/preact/components/no-data-display.tsx +2 -2
  15. package/src/preact/dateRangeSelector/date-range-selector.stories.tsx +101 -44
  16. package/src/preact/dateRangeSelector/date-range-selector.tsx +33 -14
  17. package/src/preact/dateRangeSelector/dateConversion.ts +1 -5
  18. package/src/preact/dateRangeSelector/dateRangeOption.ts +18 -0
  19. package/src/preact/mutationsOverTime/mutations-over-time-grid.tsx +2 -3
  20. package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.stories.tsx +91 -0
  21. package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.tsx +6 -0
  22. package/src/query/queryRelativeGrowthAdvantage.ts +61 -24
  23. package/src/standaloneEntrypoint.ts +2 -0
  24. package/src/utilEntrypoint.ts +6 -0
  25. package/src/web-components/input/gs-date-range-selector.stories.ts +41 -10
  26. package/src/web-components/input/gs-date-range-selector.tsx +16 -2
  27. package/standalone-bundle/assets/mutationOverTimeWorker-MVSt1FVw.js.map +1 -0
  28. package/standalone-bundle/dashboard-components.js +13234 -16877
  29. package/standalone-bundle/dashboard-components.js.map +1 -1
  30. package/standalone-bundle/style.css +1 -0
  31. package/dist/dashboard-components.js.map +0 -1
package/README.md CHANGED
@@ -13,7 +13,7 @@ Usage with a bundler in HTML:
13
13
  ```html
14
14
  <body>
15
15
  <script>
16
- import '@genspectrum/dashboard-components';
16
+ import '@genspectrum/dashboard-components/components';
17
17
  import '@genspectrum/dashboard-components/style.css';
18
18
  </script>
19
19
  <gs-app lapis="https://your.lapis.url"></gs-app>
@@ -42,6 +42,13 @@ We also provide a standalone version of the components that can be used without
42
42
  Internally, the components use [Preact](https://preactjs.com/).
43
43
  We use [Lit](https://lit.dev/) to create web components.
44
44
 
45
+ We have split the package into two parts:
46
+
47
+ - The components, which are web components that can be used in the browser.
48
+ - They can be imported with `import '@genspectrum/dashboard-components/components';`
49
+ - utility functions, which can also be used in a node environment.
50
+ - They can be imported with `import '@genspectrum/dashboard-components/util';`
51
+
45
52
  We primarily provide two kinds of components:
46
53
 
47
54
  - **Visualization components** (charts, tables, etc.)
@@ -130,4 +137,9 @@ We follow this testing concept:
130
137
 
131
138
  #### Mocking
132
139
 
133
- All our tests use mock data. In general, we use `storybook-addon-fetch-mock` for all outgoing requests. This strategy cannot be used for components that use web workers, like gs-mutations-over-time. Therefore, we created custom mock workers that return mocked data. The mock workers are enabled in the package.json using Node.js [subpath imports](https://nodejs.org/api/packages.html#subpath-imports), following the guide from [storybook](https://storybook.js.org/docs/writing-stories/mocking-data-and-modules/mocking-modules). This ensures that when importing the worker in the component, the mock worker is used inside Storybook instead of the real worker.
140
+ All our tests use mock data. In general, we use `storybook-addon-fetch-mock` for all outgoing requests. This strategy
141
+ cannot be used for components that use web workers, like gs-mutations-over-time. Therefore, we created custom mock
142
+ workers that return mocked data. The mock workers are enabled in the package.json using
143
+ Node.js [subpath imports](https://nodejs.org/api/packages.html#subpath-imports), following the guide
144
+ from [storybook](https://storybook.js.org/docs/writing-stories/mocking-data-and-modules/mocking-modules). This ensures
145
+ that when importing the worker in the component, the mock worker is used inside Storybook instead of the real worker.
@@ -274,15 +274,23 @@
274
274
  "type": {
275
275
  "text": "Meta<Required<DateRangeSelectorProps>>"
276
276
  },
277
- "default": "{ title: 'Input/DateRangeSelector', component: 'gs-date-range-selector', parameters: withComponentDocs({ actions: { handles: ['gs-date-range-changed', ...previewHandles], }, fetchMock: {}, componentDocs: { opensShadowDom: true, expectsChildren: false, codeExample, }, }), argTypes: { initialValue: { control: { type: 'select', }, options: [dateRangeOptionPresets.lastMonth.label, dateRangeOptionPresets.allTimes.label, 'CustomDateRange'], }, dateColumn: { control: { type: 'text' } }, dateRangeOptions: { control: { type: 'object', }, }, earliestDate: { control: { type: 'text', }, }, width: { control: { type: 'text', }, }, }, args: { dateRangeOptions: [ dateRangeOptionPresets.lastMonth, dateRangeOptionPresets.last3Months, dateRangeOptionPresets.allTimes, { label: 'CustomDateRange', dateFrom: '2021-01-01', dateTo: '2021-12-31' }, ], earliestDate: '1970-01-01', initialValue: dateRangeOptionPresets.lastMonth.label, dateColumn: 'aDateColumn', width: '100%', initialDateFrom: '', initialDateTo: '', }, tags: ['autodocs'], }"
277
+ "default": "{ title: 'Input/DateRangeSelector', component: 'gs-date-range-selector', parameters: withComponentDocs({ actions: { handles: ['gs-date-range-filter-changed', 'gs-date-range-option-changed', ...previewHandles], }, fetchMock: {}, componentDocs: { opensShadowDom: true, expectsChildren: false, codeExample, }, }), argTypes: { initialValue: { control: { type: 'select', }, options: [dateRangeOptionPresets.lastMonth.label, dateRangeOptionPresets.allTimes.label, 'CustomDateRange'], }, dateColumn: { control: { type: 'text' } }, dateRangeOptions: { control: { type: 'object', }, }, earliestDate: { control: { type: 'text', }, }, width: { control: { type: 'text', }, }, }, args: { dateRangeOptions: [ dateRangeOptionPresets.lastMonth, dateRangeOptionPresets.last3Months, dateRangeOptionPresets.allTimes, customDateRange, ], earliestDate: '1970-01-01', initialValue: dateRangeOptionPresets.lastMonth.label, dateColumn: 'aDateColumn', width: '100%', initialDateFrom: '', initialDateTo: '', }, tags: ['autodocs'], }"
278
278
  },
279
279
  {
280
280
  "kind": "variable",
281
- "name": "DateRangeSelectorStory",
281
+ "name": "Default",
282
+ "type": {
283
+ "text": "StoryObj<Required<DateRangeSelectorProps>>"
284
+ },
285
+ "default": "{ render: (args) => html` <gs-app lapis=\"${LAPIS_URL}\"> <div class=\"max-w-screen-lg\"> <gs-date-range-selector .dateRangeOptions=${args.dateRangeOptions} .earliestDate=${args.earliestDate} .initialValue=${args.initialValue} .initialDateFrom=${args.initialDateFrom} .initialDateTo=${args.initialDateTo} .width=${args.width} .dateColumn=${args.dateColumn} ></gs-date-range-selector> </div> </gs-app>`, }"
286
+ },
287
+ {
288
+ "kind": "variable",
289
+ "name": "FiresEvents",
282
290
  "type": {
283
291
  "text": "StoryObj<Required<DateRangeSelectorProps>>"
284
292
  },
285
- "default": "{ render: (args) => html` <gs-app lapis=\"${LAPIS_URL}\"> <div class=\"max-w-screen-lg\"> <gs-date-range-selector .dateRangeOptions=${args.dateRangeOptions} .earliestDate=${args.earliestDate} .initialValue=${args.initialValue} .initialDateFrom=${args.initialDateFrom} .initialDateTo=${args.initialDateTo} .width=${args.width} .dateColumn=${args.dateColumn} ></gs-date-range-selector> </div> </gs-app>`, play: async ({ canvasElement, step }) => { const canvas = await withinShadowRoot(canvasElement, 'gs-date-range-selector'); const dateTo = () => canvas.getByPlaceholderText('Date to'); await step('Expect last 6 months to be selected', async () => { await expect(canvas.getByRole('combobox')).toHaveValue('Last month'); await waitFor(() => { expect(dateTo()).toHaveValue(toYYYYMMDD(new Date())); }); }); // Due to the limitations of storybook testing which does not fire an event, // when selecting a value from the dropdown we can't test the fired event here. // An e2e test (using playwright) for that can be found in tests/dateRangeSelector.spec.ts }, }"
293
+ "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', async () => { 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(() => { 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, }), ); }); }, }"
286
294
  }
287
295
  ],
288
296
  "exports": [
@@ -296,9 +304,17 @@
296
304
  },
297
305
  {
298
306
  "kind": "js",
299
- "name": "DateRangeSelectorStory",
307
+ "name": "Default",
300
308
  "declaration": {
301
- "name": "DateRangeSelectorStory",
309
+ "name": "Default",
310
+ "module": "src/web-components/input/gs-date-range-selector.stories.ts"
311
+ }
312
+ },
313
+ {
314
+ "kind": "js",
315
+ "name": "FiresEvents",
316
+ "declaration": {
317
+ "name": "FiresEvents",
302
318
  "module": "src/web-components/input/gs-date-range-selector.stories.ts"
303
319
  }
304
320
  }
@@ -389,8 +405,15 @@
389
405
  "type": {
390
406
  "text": "CustomEvent<{ `${dateColumn}From`: string; `${dateColumn}To`: string; }>"
391
407
  },
392
- "description": "Fired when: - The select field is changed, - A date is selected in either of the date pickers, - A date was typed into either of the date input fields, and the input field loses focus (\"on blur\"). Contains the dates in the format `YYYY-MM-DD`. Example: For `dateColumn = yourDate`, an event with `detail` containing ``` { yourDataFrom: \"2021-01-01\", yourDataTo: \"2021-12-31\" } ``` will be fired.",
393
- "name": "gs-date-range-changed"
408
+ "description": "Fired when: - The select field is changed, - A date is selected in either of the date pickers, - A date was typed into either of the date input fields, and the input field loses focus (\"on blur\"). Contains the dates in the format `YYYY-MM-DD`. Example: For `dateColumn = yourDate`, an event with `detail` containing ``` { yourDataFrom: \"2021-01-01\", yourDataTo: \"2021-12-31\" } ``` will be fired. Use this event, when you want to use the filter directly as a LAPIS filter.",
409
+ "name": "gs-date-range-filter-changed"
410
+ },
411
+ {
412
+ "type": {
413
+ "text": "CustomEvent<{ string | {dateFrom: string, dateTo: string}}>"
414
+ },
415
+ "description": "Fired when: - The select field is changed, - A date is selected in either of the date pickers, - A date was typed into either of the date input fields, and the input field loses focus (\"on blur\"). Contains the selected dateRangeOption or when users select custom values it contains the selected dates. Use this event, when you want to control this component in your JS application.",
416
+ "name": "gs-date-range-option-changed"
394
417
  }
395
418
  ],
396
419
  "attributes": [
@@ -99,53 +99,6 @@ export declare class App extends LitElement {
99
99
  createRenderRoot(): this;
100
100
  }
101
101
 
102
- /**
103
- * A date range option that can be used in the `gs-date-range-selector` component.
104
- */
105
- export declare type DateRangeOption = {
106
- /** The label of the date range option that will be shown to the user */
107
- label: string;
108
- /**
109
- * The start date of the date range in the format `YYYY-MM-DD`.
110
- * If not set, the date range selector will default to the `earliestDate` property.
111
- */
112
- dateFrom?: string;
113
- /**
114
- * The end date of the date range in the format `YYYY-MM-DD`.
115
- * If not set, the date range selector will default to the current date.
116
- */
117
- dateTo?: string;
118
- };
119
-
120
- /**
121
- * Presets for the `gs-date-range-selector` component that can be used as `dateRangeOptions`.
122
- */
123
- export declare const dateRangeOptionPresets: {
124
- last2Weeks: {
125
- label: string;
126
- dateFrom: string | undefined;
127
- };
128
- lastMonth: {
129
- label: string;
130
- dateFrom: string | undefined;
131
- };
132
- last2Months: {
133
- label: string;
134
- dateFrom: string | undefined;
135
- };
136
- last3Months: {
137
- label: string;
138
- dateFrom: string | undefined;
139
- };
140
- last6Months: {
141
- label: string;
142
- dateFrom: string | undefined;
143
- };
144
- allTimes: {
145
- label: string;
146
- };
147
- };
148
-
149
102
  /**
150
103
  * ## Context
151
104
  * This component is a group of input fields designed to specify date range filters
@@ -159,7 +112,7 @@ export declare const dateRangeOptionPresets: {
159
112
  * Setting a value in either of the date pickers will set the select field to "custom",
160
113
  * which represents an arbitrary date range.
161
114
  *
162
- * @fires {CustomEvent<{ `${dateColumn}From`: string; `${dateColumn}To`: string; }>} gs-date-range-changed
115
+ * @fires {CustomEvent<{ `${dateColumn}From`: string; `${dateColumn}To`: string; }>} gs-date-range-filter-changed
163
116
  * Fired when:
164
117
  * - The select field is changed,
165
118
  * - A date is selected in either of the date pickers,
@@ -174,6 +127,18 @@ export declare const dateRangeOptionPresets: {
174
127
  * }
175
128
  * ```
176
129
  * will be fired.
130
+ *
131
+ * Use this event, when you want to use the filter directly as a LAPIS filter.
132
+ *
133
+ *
134
+ * @fires {CustomEvent<{ string | {dateFrom: string, dateTo: string}}>} gs-date-range-option-changed
135
+ * Fired when:
136
+ * - The select field is changed,
137
+ * - A date is selected in either of the date pickers,
138
+ * - A date was typed into either of the date input fields, and the input field loses focus ("on blur").
139
+ * Contains the selected dateRangeOption or when users select custom values it contains the selected dates.
140
+ *
141
+ * Use this event, when you want to control this component in your JS application.
177
142
  */
178
143
  export declare class DateRangeSelectorComponent extends PreactLitAdapter {
179
144
  /**
@@ -1145,7 +1110,8 @@ declare global {
1145
1110
  'gs-date-range-selector': DateRangeSelectorComponent;
1146
1111
  }
1147
1112
  interface HTMLElementEventMap {
1148
- 'gs-date-range-changed': CustomEvent<Record<string, string>>;
1113
+ 'gs-date-range-filter-changed': CustomEvent<Record<string, string>>;
1114
+ 'gs-date-range-option-changed': DateRangeOptionChangedEvent;
1149
1115
  }
1150
1116
  }
1151
1117
 
@@ -10,6 +10,7 @@ import { autoUpdate, computePosition, offset, shift, flip } from "@floating-ui/d
10
10
  import { ReactiveElement } from "@lit/reactive-element";
11
11
  import { BarWithErrorBarsController, BarWithErrorBar } from "chartjs-chart-error-bars";
12
12
  import flatpickr from "flatpickr";
13
+ import { t as toYYYYMMDD, D as DateRangeOptionChangedEvent } from "./utilEntrypoint-g4DsyhU7.js";
13
14
  /**
14
15
  * @license
15
16
  * Copyright 2017 Google LLC
@@ -1648,8 +1649,8 @@ const getMutationTypesSelectorLabel = (displayedMutationTypes) => {
1648
1649
  return type.label;
1649
1650
  }).join(", ");
1650
1651
  };
1651
- const NoDataDisplay = () => {
1652
- return /* @__PURE__ */ u$1("div", { className: "h-full w-full rounded-md border-2 border-gray-100 p-2 flex items-center justify-center", children: /* @__PURE__ */ u$1("div", { children: "No data available." }) });
1652
+ const NoDataDisplay = ({ message = "No data available." }) => {
1653
+ return /* @__PURE__ */ u$1("div", { className: "h-full w-full rounded-md border-2 border-gray-100 p-2 flex items-center justify-center", children: /* @__PURE__ */ u$1("div", { children: message }) });
1653
1654
  };
1654
1655
  const MinMaxRangeSlider = ({
1655
1656
  min,
@@ -5128,9 +5129,9 @@ input.tab:checked + .tab-content,
5128
5129
  .peer:hover ~ .peer-hover\\:visible {
5129
5130
  visibility: visible;
5130
5131
  }
5131
- @container (min-width: 30rem) {
5132
+ @container (min-width: 2rem) {
5132
5133
 
5133
- .\\@\\[30rem\\]\\:visible {
5134
+ .\\@\\[2rem\\]\\:visible {
5134
5135
  visibility: visible;
5135
5136
  }
5136
5137
  }
@@ -7759,6 +7760,11 @@ const tooltip = () => {
7759
7760
  }
7760
7761
  };
7761
7762
  };
7763
+ class NotEnoughDataToComputeFitError extends Error {
7764
+ constructor() {
7765
+ super("Not enough data to compute computeFit");
7766
+ }
7767
+ }
7762
7768
  async function queryRelativeGrowthAdvantage(numerator, denominator, generationTime, lapis, lapisDateField, signal) {
7763
7769
  const fetchNumerator = new FetchAggregatedOperator(numerator, [lapisDateField]);
7764
7770
  const fetchDenominator = new FetchAggregatedOperator(denominator, [lapisDateField]);
@@ -7795,27 +7801,7 @@ async function queryRelativeGrowthAdvantage(numerator, denominator, generationTi
7795
7801
  requestData.k.push(numeratorCounts.get(d2.date) ?? 0);
7796
7802
  }
7797
7803
  });
7798
- const requestPayload = {
7799
- config: {
7800
- alpha: 0.95,
7801
- generationTime,
7802
- initialCasesVariant: 1,
7803
- initialCasesWildtype: 1,
7804
- reproductionNumberWildtype: 1,
7805
- tStart: 0,
7806
- tEnd: maxDate.minus(minDate)
7807
- },
7808
- data: requestData
7809
- };
7810
- const response = await fetch("https://cov-spectrum.org/api/v2/computed/model/chen2021Fitness", {
7811
- method: "POST",
7812
- headers: {
7813
- "Content-Type": "application/json"
7814
- },
7815
- body: JSON.stringify(requestPayload),
7816
- signal
7817
- });
7818
- const responseData = await response.json();
7804
+ const responseData = await computeFit(generationTime, maxDate, minDate, requestData, signal);
7819
7805
  const transformed = {
7820
7806
  ...responseData,
7821
7807
  estimatedProportions: {
@@ -7831,6 +7817,40 @@ async function queryRelativeGrowthAdvantage(numerator, denominator, generationTi
7831
7817
  observedProportions
7832
7818
  };
7833
7819
  }
7820
+ async function computeFit(generationTime, maxDate, minDate, requestData, signal) {
7821
+ const requestPayload = {
7822
+ config: {
7823
+ alpha: 0.95,
7824
+ generationTime,
7825
+ initialCasesVariant: 1,
7826
+ initialCasesWildtype: 1,
7827
+ reproductionNumberWildtype: 1,
7828
+ tStart: 0,
7829
+ tEnd: maxDate.minus(minDate)
7830
+ },
7831
+ data: requestData
7832
+ };
7833
+ let response;
7834
+ try {
7835
+ response = await fetch("https://cov-spectrum.org/api/v2/computed/model/chen2021Fitness", {
7836
+ method: "POST",
7837
+ headers: {
7838
+ "Content-Type": "application/json"
7839
+ },
7840
+ body: JSON.stringify(requestPayload),
7841
+ signal
7842
+ });
7843
+ } catch {
7844
+ throw new UserFacingError(
7845
+ "Failed to compute relative growth advantage",
7846
+ "Could not connect to the server that computes the relative growth advantage. Please try again later."
7847
+ );
7848
+ }
7849
+ if (!response.ok) {
7850
+ throw new NotEnoughDataToComputeFitError();
7851
+ }
7852
+ return await response.json();
7853
+ }
7834
7854
  function toYearMonthDay(d2) {
7835
7855
  const temporalCache = TemporalCache.getInstance();
7836
7856
  return {
@@ -7855,6 +7875,9 @@ const RelativeGrowthAdvantageInner = (componentProps) => {
7855
7875
  return /* @__PURE__ */ u$1(LoadingDisplay, {});
7856
7876
  }
7857
7877
  if (error !== null) {
7878
+ if (error instanceof NotEnoughDataToComputeFitError) {
7879
+ return /* @__PURE__ */ u$1(NoDataDisplay, { message: "It was not possible to estimate the relative growth advantage due to insufficient data in the specified filter." });
7880
+ }
7858
7881
  throw error;
7859
7882
  }
7860
7883
  if (data === null) {
@@ -8817,7 +8840,6 @@ const MutationsOverTimeGrid = ({ data, colorScale }) => {
8817
8840
  gridTemplateRows: `repeat(${shownMutations.length}, 24px)`,
8818
8841
  gridTemplateColumns: `${MUTATION_CELL_WIDTH_REM}rem repeat(${dates.length}, minmax(0.05rem, 1fr))`
8819
8842
  },
8820
- className: "@container",
8821
8843
  children: shownMutations.map((mutation, rowIndex) => {
8822
8844
  return /* @__PURE__ */ u$1(Fragment, { children: [
8823
8845
  /* @__PURE__ */ u$1(
@@ -8894,8 +8916,8 @@ const ProportionCell = ({ value, mutation, date, tooltipPosition, colorScale })
8894
8916
  backgroundColor: getColorWithingScale(value.proportion, colorScale),
8895
8917
  color: getTextColorForScale(value.proportion, colorScale)
8896
8918
  },
8897
- className: `w-full h-full text-center hover:font-bold text-xs group`,
8898
- children: /* @__PURE__ */ u$1("span", { className: "invisible @[30rem]:visible", children: formatProportion(value.proportion, 0) })
8919
+ className: `w-full h-full text-center hover:font-bold text-xs group @container`,
8920
+ children: /* @__PURE__ */ u$1("span", { className: "invisible @[2rem]:visible", children: formatProportion(value.proportion, 0) })
8899
8921
  }
8900
8922
  ) }) });
8901
8923
  };
@@ -9189,8 +9211,8 @@ const getSelectableOptions = (dateRangeOptions) => {
9189
9211
  });
9190
9212
  };
9191
9213
  const getDatesForSelectorValue = (initialSelectedDateRange, dateRangeOptions, earliestDate) => {
9192
- const today2 = /* @__PURE__ */ new Date();
9193
- const defaultDates = { dateFrom: new Date(earliestDate), dateTo: today2 };
9214
+ const today = /* @__PURE__ */ new Date();
9215
+ const defaultDates = { dateFrom: new Date(earliestDate), dateTo: today };
9194
9216
  if (initialSelectedDateRange === void 0) {
9195
9217
  return defaultDates;
9196
9218
  }
@@ -9198,7 +9220,7 @@ const getDatesForSelectorValue = (initialSelectedDateRange, dateRangeOptions, ea
9198
9220
  if (dateRangeOption) {
9199
9221
  return {
9200
9222
  dateFrom: new Date(dateRangeOption.dateFrom ?? earliestDate),
9201
- dateTo: new Date(dateRangeOption.dateTo ?? today2)
9223
+ dateTo: new Date(dateRangeOption.dateTo ?? today)
9202
9224
  };
9203
9225
  }
9204
9226
  return defaultDates;
@@ -9247,13 +9269,6 @@ function computeInitialValues(initialValue, initialDateFrom, initialDateTo, earl
9247
9269
  function isUndefinedOrEmpty(value) {
9248
9270
  return value === void 0 || value === "";
9249
9271
  }
9250
- const toYYYYMMDD = (date) => {
9251
- if (!date) {
9252
- return void 0;
9253
- }
9254
- const options2 = { year: "numeric", month: "2-digit", day: "2-digit" };
9255
- return date.toLocaleDateString("en-CA", options2);
9256
- };
9257
9272
  const customOption = "Custom";
9258
9273
  const DateRangeSelector = ({ width, ...innerProps }) => {
9259
9274
  const size = { width, height: "3rem" };
@@ -9323,36 +9338,53 @@ const DateRangeSelectorInner = ({
9323
9338
  dateFrom: dateRange.dateFrom,
9324
9339
  dateTo: dateRange.dateTo
9325
9340
  });
9326
- submit();
9341
+ fireFilterChangedEvent();
9342
+ fireOptionChangedEvent(value);
9327
9343
  };
9328
9344
  const onChangeDateFrom = () => {
9329
9345
  if (selectedDates.dateFrom.toDateString() === (dateFromPicker == null ? void 0 : dateFromPicker.selectedDates[0].toDateString())) {
9330
9346
  return;
9331
9347
  }
9332
- selectedDates.dateFrom = (dateFromPicker == null ? void 0 : dateFromPicker.selectedDates[0]) || /* @__PURE__ */ new Date();
9333
- dateToPicker == null ? void 0 : dateToPicker.set("minDate", dateFromPicker == null ? void 0 : dateFromPicker.selectedDates[0]);
9348
+ const dateTo = dateToPicker == null ? void 0 : dateToPicker.selectedDates[0];
9349
+ const dateFrom = dateFromPicker == null ? void 0 : dateFromPicker.selectedDates[0];
9350
+ selectedDates.dateFrom = dateFrom || /* @__PURE__ */ new Date();
9351
+ dateToPicker == null ? void 0 : dateToPicker.set("minDate", dateFrom);
9334
9352
  setSelectedDateRange(customOption);
9335
- submit();
9353
+ fireFilterChangedEvent();
9354
+ fireOptionChangedEvent({
9355
+ dateFrom: dateFrom !== void 0 ? toYYYYMMDD(dateFrom) : earliestDate,
9356
+ dateTo: toYYYYMMDD(dateTo || /* @__PURE__ */ new Date())
9357
+ });
9336
9358
  };
9337
9359
  const onChangeDateTo = () => {
9338
9360
  if (selectedDates.dateTo.toDateString() === (dateToPicker == null ? void 0 : dateToPicker.selectedDates[0].toDateString())) {
9339
9361
  return;
9340
9362
  }
9341
- selectedDates.dateTo = (dateToPicker == null ? void 0 : dateToPicker.selectedDates[0]) || /* @__PURE__ */ new Date();
9342
- dateFromPicker == null ? void 0 : dateFromPicker.set("maxDate", dateToPicker == null ? void 0 : dateToPicker.selectedDates[0]);
9363
+ const dateTo = dateToPicker == null ? void 0 : dateToPicker.selectedDates[0];
9364
+ const dateFrom = dateFromPicker == null ? void 0 : dateFromPicker.selectedDates[0];
9365
+ selectedDates.dateTo = dateTo || /* @__PURE__ */ new Date();
9366
+ dateFromPicker == null ? void 0 : dateFromPicker.set("maxDate", dateTo);
9343
9367
  setSelectedDateRange(customOption);
9344
- submit();
9368
+ fireFilterChangedEvent();
9369
+ fireOptionChangedEvent({
9370
+ dateFrom: dateFrom !== void 0 ? toYYYYMMDD(dateFrom) : earliestDate,
9371
+ dateTo: toYYYYMMDD(dateTo || /* @__PURE__ */ new Date())
9372
+ });
9373
+ };
9374
+ const fireOptionChangedEvent = (option) => {
9375
+ var _a;
9376
+ (_a = divRef.current) == null ? void 0 : _a.dispatchEvent(new DateRangeOptionChangedEvent(option));
9345
9377
  };
9346
- const submit = () => {
9378
+ const fireFilterChangedEvent = () => {
9347
9379
  var _a;
9348
- const dateFrom = toYYYYMMDD(dateFromPicker == null ? void 0 : dateFromPicker.selectedDates[0]);
9349
- const dateTo = toYYYYMMDD(dateToPicker == null ? void 0 : dateToPicker.selectedDates[0]);
9380
+ const dateFrom = dateFromPicker == null ? void 0 : dateFromPicker.selectedDates[0];
9381
+ const dateTo = dateToPicker == null ? void 0 : dateToPicker.selectedDates[0];
9350
9382
  const detail = {
9351
- ...dateFrom !== void 0 && { [`${dateColumn}From`]: dateFrom },
9352
- ...dateTo !== void 0 && { [`${dateColumn}To`]: dateTo }
9383
+ ...dateFrom !== void 0 && { [`${dateColumn}From`]: toYYYYMMDD(dateFrom) },
9384
+ ...dateTo !== void 0 && { [`${dateColumn}To`]: toYYYYMMDD(dateTo) }
9353
9385
  };
9354
9386
  (_a = divRef.current) == null ? void 0 : _a.dispatchEvent(
9355
- new CustomEvent("gs-date-range-changed", {
9387
+ new CustomEvent("gs-date-range-filter-changed", {
9356
9388
  detail,
9357
9389
  bubbles: true,
9358
9390
  composed: true
@@ -10372,42 +10404,6 @@ __decorateClass([
10372
10404
  LineageFilterComponent = __decorateClass([
10373
10405
  t$2("gs-lineage-filter")
10374
10406
  ], LineageFilterComponent);
10375
- const today = /* @__PURE__ */ new Date();
10376
- const twoWeeksAgo = /* @__PURE__ */ new Date();
10377
- twoWeeksAgo.setDate(today.getDate() - 14);
10378
- const lastMonth = new Date(today);
10379
- lastMonth.setMonth(today.getMonth() - 1);
10380
- const last2Months = new Date(today);
10381
- last2Months.setMonth(today.getMonth() - 2);
10382
- const last3Months = new Date(today);
10383
- last3Months.setMonth(today.getMonth() - 3);
10384
- const last6Months = new Date(today);
10385
- last6Months.setMonth(today.getMonth() - 6);
10386
- const dateRangeOptionPresets = {
10387
- last2Weeks: {
10388
- label: "Last 2 weeks",
10389
- dateFrom: toYYYYMMDD(twoWeeksAgo)
10390
- },
10391
- lastMonth: {
10392
- label: "Last month",
10393
- dateFrom: toYYYYMMDD(lastMonth)
10394
- },
10395
- last2Months: {
10396
- label: "Last 2 months",
10397
- dateFrom: toYYYYMMDD(last2Months)
10398
- },
10399
- last3Months: {
10400
- label: "Last 3 months",
10401
- dateFrom: toYYYYMMDD(last3Months)
10402
- },
10403
- last6Months: {
10404
- label: "Last 6 months",
10405
- dateFrom: toYYYYMMDD(last6Months)
10406
- },
10407
- allTimes: {
10408
- label: "All times"
10409
- }
10410
- };
10411
10407
  export {
10412
10408
  AggregateComponent,
10413
10409
  App,
@@ -10422,7 +10418,6 @@ export {
10422
10418
  PrevalenceOverTimeComponent,
10423
10419
  RelativeGrowthAdvantageComponent,
10424
10420
  TextInputComponent,
10425
- UserFacingError,
10426
- dateRangeOptionPresets
10421
+ UserFacingError
10427
10422
  };
10428
- //# sourceMappingURL=dashboard-components.js.map
10423
+ //# sourceMappingURL=components.js.map