@genspectrum/dashboard-components 0.6.14 → 0.6.15

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 (32) hide show
  1. package/custom-elements.json +12 -6
  2. package/dist/dashboard-components.js +97 -53
  3. package/dist/dashboard-components.js.map +1 -1
  4. package/dist/genspectrum-components.d.ts +27 -9
  5. package/dist/style.css +2 -2
  6. package/package.json +3 -3
  7. package/src/index.ts +8 -0
  8. package/src/lapisApi/lapisApi.ts +15 -7
  9. package/src/preact/components/color-scale-selector-dropdown.stories.tsx +1 -1
  10. package/src/preact/components/error-boundary.stories.tsx +21 -4
  11. package/src/preact/components/error-display.stories.tsx +20 -2
  12. package/src/preact/components/error-display.tsx +64 -10
  13. package/src/preact/components/info.stories.tsx +5 -5
  14. package/src/preact/components/info.tsx +1 -3
  15. package/src/preact/dateRangeSelector/date-range-selector.stories.tsx +2 -3
  16. package/src/preact/lineageFilter/lineage-filter.stories.tsx +2 -3
  17. package/src/preact/locationFilter/fetchAutocompletionList.ts +1 -14
  18. package/src/preact/locationFilter/location-filter.stories.tsx +2 -3
  19. package/src/preact/mutationFilter/mutation-filter.stories.tsx +2 -3
  20. package/src/preact/prevalenceOverTime/prevalence-over-time.tsx +1 -1
  21. package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.tsx +1 -1
  22. package/src/preact/shared/floating-ui/hooks.ts +1 -1
  23. package/src/preact/textInput/text-input.stories.tsx +2 -3
  24. package/src/web-components/app.stories.ts +0 -2
  25. package/src/web-components/errorHandling.mdx +8 -0
  26. package/src/web-components/input/gs-date-range-selector.stories.ts +2 -3
  27. package/src/web-components/input/gs-lineage-filter.stories.ts +2 -3
  28. package/src/web-components/input/gs-location-filter.stories.ts +2 -3
  29. package/src/web-components/input/gs-mutation-filter.stories.ts +2 -3
  30. package/src/web-components/input/gs-text-input.stories.ts +2 -3
  31. package/standalone-bundle/dashboard-components.js +1719 -1686
  32. package/standalone-bundle/dashboard-components.js.map +1 -1
@@ -70,7 +70,7 @@
70
70
  "type": {
71
71
  "text": "Meta"
72
72
  },
73
- "default": "{ title: 'Wrapper/App', component: 'gs-app', parameters: withComponentDocs({ fetchMock: {}, componentDocs: { opensShadowDom: false, expectsChildren: true, codeExample, }, }), decorators: [withActions], tags: ['autodocs'], }"
73
+ "default": "{ title: 'Wrapper/App', component: 'gs-app', parameters: withComponentDocs({ fetchMock: {}, componentDocs: { opensShadowDom: false, expectsChildren: true, codeExample, }, }), tags: ['autodocs'], }"
74
74
  },
75
75
  {
76
76
  "kind": "variable",
@@ -227,6 +227,12 @@
227
227
  }
228
228
  ]
229
229
  },
230
+ {
231
+ "kind": "javascript-module",
232
+ "path": "src/web-components/errorHandling.mdx",
233
+ "declarations": [],
234
+ "exports": []
235
+ },
230
236
  {
231
237
  "kind": "javascript-module",
232
238
  "path": "src/web-components/index.ts",
@@ -268,7 +274,7 @@
268
274
  "type": {
269
275
  "text": "Meta<Required<DateRangeSelectorProps<'CustomDateRange'>>>"
270
276
  },
271
- "default": "{ title: 'Input/DateRangeSelector', component: 'gs-date-range-selector', parameters: withComponentDocs({ actions: { handles: ['gs-date-range-changed'], }, fetchMock: {}, componentDocs: { opensShadowDom: true, expectsChildren: false, codeExample, }, }), argTypes: { initialValue: { control: { type: 'select', }, options: [ PRESET_VALUE_CUSTOM, PRESET_VALUE_ALL_TIMES, PRESET_VALUE_LAST_2_WEEKS, PRESET_VALUE_LAST_MONTH, PRESET_VALUE_LAST_2_MONTHS, PRESET_VALUE_LAST_3_MONTHS, PRESET_VALUE_LAST_6_MONTHS, 'CustomDateRange', ], }, dateColumn: { control: { type: 'text' } }, customSelectOptions: { control: { type: 'object', }, }, earliestDate: { control: { type: 'text', }, }, width: { control: { type: 'text', }, }, }, args: { customSelectOptions: [{ label: 'CustomDateRange', dateFrom: '2021-01-01', dateTo: '2021-12-31' }], earliestDate: '1970-01-01', initialValue: PRESET_VALUE_LAST_6_MONTHS, dateColumn: 'aDateColumn', width: '100%', initialDateFrom: '', initialDateTo: '', }, decorators: [withActions], tags: ['autodocs'], }"
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: [ PRESET_VALUE_CUSTOM, PRESET_VALUE_ALL_TIMES, PRESET_VALUE_LAST_2_WEEKS, PRESET_VALUE_LAST_MONTH, PRESET_VALUE_LAST_2_MONTHS, PRESET_VALUE_LAST_3_MONTHS, PRESET_VALUE_LAST_6_MONTHS, 'CustomDateRange', ], }, dateColumn: { control: { type: 'text' } }, customSelectOptions: { control: { type: 'object', }, }, earliestDate: { control: { type: 'text', }, }, width: { control: { type: 'text', }, }, }, args: { customSelectOptions: [{ label: 'CustomDateRange', dateFrom: '2021-01-01', dateTo: '2021-12-31' }], earliestDate: '1970-01-01', initialValue: PRESET_VALUE_LAST_6_MONTHS, dateColumn: 'aDateColumn', width: '100%', initialDateFrom: '', initialDateTo: '', }, tags: ['autodocs'], }"
272
278
  },
273
279
  {
274
280
  "kind": "variable",
@@ -489,7 +495,7 @@
489
495
  "type": {
490
496
  "text": "Meta<Required<LineageFilterProps>>"
491
497
  },
492
- "default": "{ title: 'Input/Lineage filter', component: 'gs-lineage-filter', parameters: withComponentDocs({ actions: { handles: ['gs-lineage-filter-changed'], }, fetchMock: { mocks: [ { matcher: { name: 'pangoLineage', url: AGGREGATED_ENDPOINT, body: { fields: ['pangoLineage'], }, }, response: { status: 200, body: aggregatedData, }, }, ], }, componentDocs: { opensShadowDom: true, expectsChildren: false, codeExample, }, }), decorators: [withActions], tags: ['autodocs'], }"
498
+ "default": "{ title: 'Input/Lineage filter', component: 'gs-lineage-filter', parameters: withComponentDocs({ actions: { handles: ['gs-lineage-filter-changed', ...previewHandles], }, fetchMock: { mocks: [ { matcher: { name: 'pangoLineage', url: AGGREGATED_ENDPOINT, body: { fields: ['pangoLineage'], }, }, response: { status: 200, body: aggregatedData, }, }, ], }, componentDocs: { opensShadowDom: true, expectsChildren: false, codeExample, }, }), tags: ['autodocs'], }"
493
499
  },
494
500
  {
495
501
  "kind": "variable",
@@ -669,7 +675,7 @@
669
675
  "type": {
670
676
  "text": "Meta"
671
677
  },
672
- "default": "{ title: 'Input/Location filter', component: 'gs-location-filter', parameters: withComponentDocs({ actions: { handles: ['gs-location-changed'], }, componentDocs: { opensShadowDom: true, expectsChildren: false, codeExample, }, }), argTypes: { fields: { control: { type: 'object', }, }, initialValue: { control: { type: 'text', }, }, width: { control: { type: 'text', }, }, placeholderText: { control: { type: 'text', }, }, }, decorators: [withActions], tags: ['autodocs'], }"
678
+ "default": "{ title: 'Input/Location filter', component: 'gs-location-filter', parameters: withComponentDocs({ actions: { handles: ['gs-location-changed', ...previewHandles], }, componentDocs: { opensShadowDom: true, expectsChildren: false, codeExample, }, }), argTypes: { fields: { control: { type: 'object', }, }, initialValue: { control: { type: 'text', }, }, width: { control: { type: 'text', }, }, placeholderText: { control: { type: 'text', }, }, }, tags: ['autodocs'], }"
673
679
  },
674
680
  {
675
681
  "kind": "variable",
@@ -881,7 +887,7 @@
881
887
  "type": {
882
888
  "text": "Meta<MutationFilterProps>"
883
889
  },
884
- "default": "{ title: 'Input/Mutation filter', component: 'gs-mutation-filter', parameters: withComponentDocs({ actions: { handles: ['gs-mutation-filter-changed', 'gs-mutation-filter-on-blur'], }, fetchMock: {}, componentDocs: { opensShadowDom: true, expectsChildren: false, codeExample, }, }), argTypes: { initialValue: { control: { type: 'object', }, }, width: { control: 'text' }, }, decorators: [withActions], tags: ['autodocs'], }"
890
+ "default": "{ title: 'Input/Mutation filter', component: 'gs-mutation-filter', parameters: withComponentDocs({ actions: { handles: ['gs-mutation-filter-changed', 'gs-mutation-filter-on-blur', ...previewHandles], }, fetchMock: {}, componentDocs: { opensShadowDom: true, expectsChildren: false, codeExample, }, }), argTypes: { initialValue: { control: { type: 'object', }, }, width: { control: 'text' }, }, tags: ['autodocs'], }"
885
891
  },
886
892
  {
887
893
  "kind": "variable",
@@ -1062,7 +1068,7 @@
1062
1068
  "type": {
1063
1069
  "text": "Meta<Required<TextInputProps>>"
1064
1070
  },
1065
- "default": "{ title: 'Input/Text input', component: 'gs-text-input', parameters: withComponentDocs({ actions: { handles: ['gs-text-input-changed'], }, fetchMock: { mocks: [ { matcher: { name: 'hosts', url: AGGREGATED_ENDPOINT, body: { fields: ['host'], }, }, response: { status: 200, body: data, }, }, ], }, componentDocs: { opensShadowDom: true, expectsChildren: false, codeExample, }, }), argTypes: { lapisField: { control: { type: 'text', }, }, placeholderText: { control: { type: 'text', }, }, initialValue: { control: { type: 'text', }, }, width: { control: { type: 'text', }, }, }, decorators: [withActions], tags: ['autodocs'], }"
1071
+ "default": "{ title: 'Input/Text input', component: 'gs-text-input', parameters: withComponentDocs({ actions: { handles: ['gs-text-input-changed', ...previewHandles], }, fetchMock: { mocks: [ { matcher: { name: 'hosts', url: AGGREGATED_ENDPOINT, body: { fields: ['host'], }, }, response: { status: 200, body: data, }, }, ], }, componentDocs: { opensShadowDom: true, expectsChildren: false, codeExample, }, }), argTypes: { lapisField: { control: { type: 'text', }, }, placeholderText: { control: { type: 'text', }, }, initialValue: { control: { type: 'text', }, }, width: { control: { type: 'text', }, }, }, tags: ['autodocs'], }"
1066
1072
  },
1067
1073
  {
1068
1074
  "kind": "variable",
@@ -397,17 +397,19 @@ const lapisError = z$1.object({
397
397
  error: problemDetail
398
398
  });
399
399
  class UnknownLapisError extends Error {
400
- constructor(message, status) {
400
+ constructor(message, status, requestedData) {
401
401
  super(message);
402
402
  this.status = status;
403
+ this.requestedData = requestedData;
403
404
  this.name = "UnknownLapisError";
404
405
  }
405
406
  }
406
407
  class LapisError extends Error {
407
- constructor(message, status, problemDetail2) {
408
+ constructor(message, status, problemDetail2, requestedData) {
408
409
  super(message);
409
410
  this.status = status;
410
411
  this.problemDetail = problemDetail2;
412
+ this.requestedData = requestedData;
411
413
  this.name = "LapisError";
412
414
  }
413
415
  }
@@ -420,7 +422,7 @@ async function fetchAggregated(lapisUrl, body, signal) {
420
422
  body: JSON.stringify(body),
421
423
  signal
422
424
  });
423
- await handleErrors(response);
425
+ await handleErrors(response, "aggregated data");
424
426
  return aggregatedResponse.parse(await response.json());
425
427
  }
426
428
  async function fetchInsertions(lapisUrl, body, sequenceType, signal) {
@@ -432,7 +434,7 @@ async function fetchInsertions(lapisUrl, body, sequenceType, signal) {
432
434
  body: JSON.stringify(body),
433
435
  signal
434
436
  });
435
- await handleErrors(response);
437
+ await handleErrors(response, `${sequenceType} insertions`);
436
438
  return insertionsResponse.parse(await response.json());
437
439
  }
438
440
  async function fetchSubstitutionsOrDeletions(lapisUrl, body, sequenceType, signal) {
@@ -444,7 +446,7 @@ async function fetchSubstitutionsOrDeletions(lapisUrl, body, sequenceType, signa
444
446
  body: JSON.stringify(body),
445
447
  signal
446
448
  });
447
- await handleErrors(response);
449
+ await handleErrors(response, `${sequenceType} mutations`);
448
450
  return mutationsResponse.parse(await response.json());
449
451
  }
450
452
  async function fetchReferenceGenome(lapisUrl, signal) {
@@ -455,10 +457,10 @@ async function fetchReferenceGenome(lapisUrl, signal) {
455
457
  },
456
458
  signal
457
459
  });
458
- await handleErrors(response);
460
+ await handleErrors(response, "the reference genomes");
459
461
  return referenceGenomeResponse.parse(await response.json());
460
462
  }
461
- const handleErrors = async (response) => {
463
+ const handleErrors = async (response, requestedData) => {
462
464
  if (!response.ok) {
463
465
  if (response.status >= 400 && response.status < 500) {
464
466
  const json = await response.json();
@@ -467,7 +469,8 @@ const handleErrors = async (response) => {
467
469
  throw new LapisError(
468
470
  response.statusText + lapisErrorResult.data.error.detail,
469
471
  response.status,
470
- lapisErrorResult.data.error
472
+ lapisErrorResult.data.error,
473
+ requestedData
471
474
  );
472
475
  }
473
476
  const problemDetailResult = problemDetail.safeParse(json);
@@ -475,12 +478,17 @@ const handleErrors = async (response) => {
475
478
  throw new LapisError(
476
479
  response.statusText + problemDetailResult.data.detail,
477
480
  response.status,
478
- problemDetailResult.data
481
+ problemDetailResult.data,
482
+ requestedData
479
483
  );
480
484
  }
481
- throw new UnknownLapisError(`${response.statusText}: ${JSON.stringify(json)}`, response.status);
485
+ throw new UnknownLapisError(
486
+ `${response.statusText}: ${JSON.stringify(json)}`,
487
+ response.status,
488
+ requestedData
489
+ );
482
490
  }
483
- throw new UnknownLapisError(`${response.statusText}: ${response.status}`, response.status);
491
+ throw new UnknownLapisError(`${response.statusText}: ${response.status}`, response.status, requestedData);
484
492
  }
485
493
  };
486
494
  const aggregatedEndpoint = (lapisUrl) => `${lapisUrl}/sample/aggregated`;
@@ -1200,6 +1208,16 @@ const CsvDownloadButton = ({
1200
1208
  };
1201
1209
  return /* @__PURE__ */ u$1("button", { className, onClick: download, children: label });
1202
1210
  };
1211
+ const GS_ERROR_EVENT_TYPE = "gs-error";
1212
+ class ErrorEvent extends Event {
1213
+ constructor(error) {
1214
+ super(GS_ERROR_EVENT_TYPE, {
1215
+ bubbles: true,
1216
+ composed: true
1217
+ });
1218
+ this.error = error;
1219
+ }
1220
+ }
1203
1221
  class UserFacingError extends Error {
1204
1222
  constructor(headline, message) {
1205
1223
  super(message);
@@ -1209,36 +1227,72 @@ class UserFacingError extends Error {
1209
1227
  }
1210
1228
  const ErrorDisplay = ({ error }) => {
1211
1229
  console.error(error);
1230
+ const containerRef = A(null);
1212
1231
  const ref = A(null);
1213
- return /* @__PURE__ */ u$1("div", { className: "h-full w-full rounded-md border-2 border-gray-100 p-2 flex items-center justify-center flex-col", children: [
1214
- /* @__PURE__ */ u$1("div", { className: "text-red-700 font-bold", children: "Error" }),
1215
- /* @__PURE__ */ u$1("div", { children: [
1216
- "Oops! Something went wrong.",
1217
- error instanceof UserFacingError && /* @__PURE__ */ u$1(Fragment, { children: [
1218
- " ",
1219
- /* @__PURE__ */ u$1(
1220
- "button",
1221
- {
1222
- className: "text-sm text-gray-600 hover:text-gray-300",
1223
- onClick: () => {
1232
+ y(() => {
1233
+ var _a;
1234
+ (_a = containerRef.current) == null ? void 0 : _a.dispatchEvent(new ErrorEvent(error));
1235
+ });
1236
+ const { headline, details } = getDisplayedErrorMessage(error);
1237
+ return /* @__PURE__ */ u$1(
1238
+ "div",
1239
+ {
1240
+ ref: containerRef,
1241
+ className: "h-full w-full rounded-md border-2 border-gray-100 p-2 flex items-center justify-center flex-col",
1242
+ children: [
1243
+ /* @__PURE__ */ u$1("div", { className: "text-red-700 font-bold", children: headline }),
1244
+ /* @__PURE__ */ u$1("div", { children: [
1245
+ "Oops! Something went wrong.",
1246
+ details !== void 0 && /* @__PURE__ */ u$1(Fragment, { children: [
1247
+ " ",
1248
+ /* @__PURE__ */ u$1("button", { className: "underline hover:text-gray-400", onClick: () => {
1224
1249
  var _a;
1225
1250
  return (_a = ref.current) == null ? void 0 : _a.showModal();
1226
- },
1227
- children: "Show details."
1228
- }
1229
- ),
1230
- /* @__PURE__ */ u$1("dialog", { ref, class: "modal", children: [
1231
- /* @__PURE__ */ u$1("div", { class: "modal-box", children: [
1232
- /* @__PURE__ */ u$1("form", { method: "dialog", children: /* @__PURE__ */ u$1("button", { className: "btn btn-sm btn-circle btn-ghost absolute right-2 top-2", children: "✕" }) }),
1233
- /* @__PURE__ */ u$1("h1", { class: "text-lg", children: error.headline }),
1234
- /* @__PURE__ */ u$1("p", { class: "py-4", children: error.message })
1235
- ] }),
1236
- /* @__PURE__ */ u$1("form", { method: "dialog", class: "modal-backdrop", children: /* @__PURE__ */ u$1("button", { children: "close" }) })
1251
+ }, children: "Show details." }),
1252
+ /* @__PURE__ */ u$1("dialog", { ref, class: "modal", children: [
1253
+ /* @__PURE__ */ u$1("div", { class: "modal-box", children: [
1254
+ /* @__PURE__ */ u$1("form", { method: "dialog", children: /* @__PURE__ */ u$1("button", { className: "btn btn-sm btn-circle btn-ghost absolute right-2 top-2", children: "✕" }) }),
1255
+ /* @__PURE__ */ u$1("h1", { class: "text-lg", children: details.headline }),
1256
+ /* @__PURE__ */ u$1("p", { class: "py-4", children: details.message })
1257
+ ] }),
1258
+ /* @__PURE__ */ u$1("form", { method: "dialog", class: "modal-backdrop", children: /* @__PURE__ */ u$1("button", { children: "close" }) })
1259
+ ] })
1260
+ ] })
1237
1261
  ] })
1238
- ] })
1239
- ] })
1240
- ] });
1262
+ ]
1263
+ }
1264
+ );
1241
1265
  };
1266
+ function getDisplayedErrorMessage(error) {
1267
+ if (error instanceof UserFacingError) {
1268
+ return {
1269
+ headline: `Error - ${error.headline}`,
1270
+ details: {
1271
+ headline: error.headline,
1272
+ message: error.message
1273
+ }
1274
+ };
1275
+ }
1276
+ if (error instanceof LapisError) {
1277
+ return {
1278
+ headline: `Error - Failed fetching ${error.requestedData} from LAPIS`,
1279
+ details: {
1280
+ headline: `LAPIS request failed: ${error.requestedData} - ${error.problemDetail.status} ${error.problemDetail.title}`,
1281
+ message: error.problemDetail.detail ?? error.message
1282
+ }
1283
+ };
1284
+ }
1285
+ if (error instanceof UnknownLapisError) {
1286
+ return {
1287
+ headline: `Error - Failed fetching ${error.requestedData} from LAPIS`,
1288
+ details: {
1289
+ headline: `LAPIS request failed: An unexpected error occurred while fetching ${error.requestedData}`,
1290
+ message: error.message
1291
+ }
1292
+ };
1293
+ }
1294
+ return { headline: "Error", details: void 0 };
1295
+ }
1242
1296
  const ResizeContainer = ({ children, size }) => {
1243
1297
  return /* @__PURE__ */ u$1("div", { style: size, className: "bg-white", children });
1244
1298
  };
@@ -5000,9 +5054,9 @@ input.tab:checked + .tab-content,
5000
5054
  --tw-text-opacity: 1;
5001
5055
  color: rgb(30 64 175 / var(--tw-text-opacity));
5002
5056
  }
5003
- .hover\\:text-gray-300:hover {
5057
+ .hover\\:text-gray-400:hover {
5004
5058
  --tw-text-opacity: 1;
5005
- color: rgb(209 213 219 / var(--tw-text-opacity));
5059
+ color: rgb(156 163 175 / var(--tw-text-opacity));
5006
5060
  }
5007
5061
  .hover\\:text-gray-700:hover {
5008
5062
  --tw-text-opacity: 1;
@@ -7250,7 +7304,7 @@ const PrevalenceOverTimeInner = (componentProps) => {
7250
7304
  lapis,
7251
7305
  lapisDateField
7252
7306
  ),
7253
- [lapis, numeratorFilter, denominatorFilter, granularity, smoothingWindow]
7307
+ [lapis, numeratorFilter, denominatorFilter, granularity, smoothingWindow, lapisDateField]
7254
7308
  );
7255
7309
  if (isLoading) {
7256
7310
  return /* @__PURE__ */ u$1(LoadingDisplay, {});
@@ -7704,7 +7758,7 @@ const RelativeGrowthAdvantageInner = ({
7704
7758
  const [yAxisScaleType, setYAxisScaleType] = h("linear");
7705
7759
  const { data, error, isLoading } = useQuery(
7706
7760
  () => queryRelativeGrowthAdvantage(numeratorFilter, denominatorFilter, generationTime, lapis, lapisDateField),
7707
- [lapis, numeratorFilter, denominatorFilter, generationTime, views]
7761
+ [lapis, numeratorFilter, denominatorFilter, generationTime, views, lapisDateField]
7708
7762
  );
7709
7763
  if (isLoading) {
7710
7764
  return /* @__PURE__ */ u$1(LoadingDisplay, {});
@@ -9390,18 +9444,7 @@ DateRangeSelectorComponent = __decorateClass$4([
9390
9444
  async function fetchAutocompletionList(fields, lapis, signal) {
9391
9445
  const toAncestorInHierarchyOverwriteValues = Array(fields.length - 1).fill(0).map((_, i2) => i2 + 1).map((i2) => fields.slice(i2).reduce((acc, field) => ({ ...acc, [field]: null }), {}));
9392
9446
  const fetchAggregatedOperator = new FetchAggregatedOperator({}, fields);
9393
- let data;
9394
- try {
9395
- data = (await fetchAggregatedOperator.evaluate(lapis, signal)).content;
9396
- } catch (error) {
9397
- if (error instanceof LapisError) {
9398
- throw new UserFacingError(
9399
- `Failed to fetch autocomplete list from LAPIS: ${error.problemDetail.status} ${error.problemDetail.title ?? ""}`,
9400
- error.problemDetail.detail ?? error.message
9401
- );
9402
- }
9403
- throw error;
9404
- }
9447
+ const data = (await fetchAggregatedOperator.evaluate(lapis, signal)).content;
9405
9448
  const locationValues = data.map((entry) => fields.reduce((acc, field) => ({ ...acc, [field]: entry[field] }), {})).reduce((setOfAllHierarchies, entry) => {
9406
9449
  setOfAllHierarchies.add(JSON.stringify(entry));
9407
9450
  toAncestorInHierarchyOverwriteValues.forEach((overwriteValues) => {
@@ -10316,6 +10359,7 @@ export {
10316
10359
  NumberSequencesOverTimeComponent,
10317
10360
  PrevalenceOverTimeComponent,
10318
10361
  RelativeGrowthAdvantageComponent,
10319
- TextInputComponent
10362
+ TextInputComponent,
10363
+ UserFacingError
10320
10364
  };
10321
10365
  //# sourceMappingURL=dashboard-components.js.map