@genspectrum/dashboard-components 0.12.0 → 0.13.0

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 (37) hide show
  1. package/custom-elements.json +117 -28
  2. package/dist/{LocationChangedEvent-CORvQvXv.js → LineageFilterChangedEvent-GedKNGFI.js} +25 -3
  3. package/dist/LineageFilterChangedEvent-GedKNGFI.js.map +1 -0
  4. package/dist/components.d.ts +86 -52
  5. package/dist/components.js +251 -196
  6. package/dist/components.js.map +1 -1
  7. package/dist/util.d.ts +59 -45
  8. package/dist/util.js +3 -1
  9. package/package.json +1 -1
  10. package/src/preact/components/downshift-combobox.tsx +145 -0
  11. package/src/preact/lineageFilter/LineageFilterChangedEvent.ts +11 -0
  12. package/src/preact/lineageFilter/fetchLineageAutocompleteList.spec.ts +16 -2
  13. package/src/preact/lineageFilter/fetchLineageAutocompleteList.ts +13 -2
  14. package/src/preact/lineageFilter/lineage-filter.stories.tsx +110 -9
  15. package/src/preact/lineageFilter/lineage-filter.tsx +40 -50
  16. package/src/preact/locationFilter/LocationChangedEvent.ts +1 -1
  17. package/src/preact/locationFilter/fetchAutocompletionList.spec.ts +6 -2
  18. package/src/preact/locationFilter/fetchAutocompletionList.ts +16 -6
  19. package/src/preact/locationFilter/location-filter.stories.tsx +33 -30
  20. package/src/preact/locationFilter/location-filter.tsx +47 -144
  21. package/src/preact/map/sequences-by-location-map.tsx +3 -3
  22. package/src/preact/textInput/TextInputChangedEvent.ts +11 -0
  23. package/src/preact/textInput/fetchStringAutocompleteList.ts +20 -0
  24. package/src/preact/textInput/text-input.stories.tsx +34 -14
  25. package/src/preact/textInput/text-input.tsx +47 -45
  26. package/src/types.ts +3 -0
  27. package/src/utilEntrypoint.ts +2 -0
  28. package/src/web-components/input/gs-lineage-filter.stories.ts +120 -31
  29. package/src/web-components/input/gs-lineage-filter.tsx +24 -8
  30. package/src/web-components/input/gs-location-filter.stories.ts +9 -0
  31. package/src/web-components/input/gs-location-filter.tsx +21 -3
  32. package/src/web-components/input/gs-text-input.stories.ts +44 -12
  33. package/src/web-components/input/gs-text-input.tsx +23 -7
  34. package/standalone-bundle/dashboard-components.js +4931 -4863
  35. package/standalone-bundle/dashboard-components.js.map +1 -1
  36. package/dist/LocationChangedEvent-CORvQvXv.js.map +0 -1
  37. package/src/preact/textInput/fetchAutocompleteList.ts +0 -9
@@ -6,11 +6,11 @@ import { options, createContext as createContext$1, Fragment, render, Component,
6
6
  import { Grid } from "gridjs";
7
7
  import { Chart, registerables, Scale, BarController } from "chart.js";
8
8
  import { VennDiagramController, ArcSlice, extractSets } from "chartjs-chart-venn";
9
- import { v as views, n as namedLapisFilterSchema, s as sequenceTypeSchema, l as lapisFilterSchema, t as temporalGranularitySchema, a as dateRangeOptionSchema, b as toYYYYMMDD, D as DateRangeOptionChangedEvent, L as LocationChangedEvent, m as mutationsFilterSchema } from "./LocationChangedEvent-CORvQvXv.js";
9
+ import { v as views, n as namedLapisFilterSchema, s as sequenceTypeSchema, l as lapisFilterSchema, t as temporalGranularitySchema, b as dateRangeOptionSchema, c as toYYYYMMDD, D as DateRangeOptionChangedEvent, e as lapisLocationFilterSchema, L as LocationChangedEvent, T as TextInputChangedEvent, m as mutationsFilterSchema, a as LineageFilterChangedEvent } from "./LineageFilterChangedEvent-GedKNGFI.js";
10
10
  import { autoUpdate, computePosition, offset, shift, flip } from "@floating-ui/dom";
11
11
  import { ReactiveElement } from "@lit/reactive-element";
12
12
  import { BarWithErrorBarsController, BarWithErrorBar } from "chartjs-chart-error-bars";
13
- import Leaflet from "leaflet";
13
+ import { map, geoJson } from "leaflet";
14
14
  import * as topojson from "topojson-client";
15
15
  import flatpickr from "flatpickr";
16
16
  /**
@@ -8617,7 +8617,7 @@ function getDatasets$2(fields, maxNumberOfBars, data) {
8617
8617
  ]
8618
8618
  };
8619
8619
  }
8620
- const map = /* @__PURE__ */ new Map();
8620
+ const map2 = /* @__PURE__ */ new Map();
8621
8621
  const countsOfEachBar = /* @__PURE__ */ new Map();
8622
8622
  for (const row of sortedData) {
8623
8623
  const yValue = row[fields[0]];
@@ -8627,17 +8627,17 @@ function getDatasets$2(fields, maxNumberOfBars, data) {
8627
8627
  }
8628
8628
  const yAxisKey = String(yValue);
8629
8629
  const secondaryKey = String(secondaryValue);
8630
- if (!map.has(secondaryKey)) {
8631
- map.set(secondaryKey, []);
8630
+ if (!map2.has(secondaryKey)) {
8631
+ map2.set(secondaryKey, []);
8632
8632
  }
8633
- (_a = map.get(secondaryKey)) == null ? void 0 : _a.push({
8633
+ (_a = map2.get(secondaryKey)) == null ? void 0 : _a.push({
8634
8634
  y: yAxisKey,
8635
8635
  x: row.count,
8636
8636
  proportion: row.proportion
8637
8637
  });
8638
8638
  countsOfEachBar.set(yAxisKey, (countsOfEachBar.get(yAxisKey) ?? 0) + row.count);
8639
8639
  }
8640
- const datasets2 = Array.from(map.entries()).map(sortAndTruncateYAxisKeys(countsOfEachBar, maxNumberOfBars)).map(([key, value], index) => ({
8640
+ const datasets2 = Array.from(map2.entries()).map(sortAndTruncateYAxisKeys(countsOfEachBar, maxNumberOfBars)).map(([key, value], index) => ({
8641
8641
  borderWidth: 1,
8642
8642
  backgroundColor: singleGraphColorRGBAById(index, 0.3),
8643
8643
  borderColor: singleGraphColorRGBAById(index),
@@ -9259,13 +9259,13 @@ class Map2dBase {
9259
9259
  }
9260
9260
  }
9261
9261
  class Map2dView {
9262
- constructor(map) {
9263
- this.keysFirstAxis = new Map(map.keysFirstAxis);
9264
- this.keysSecondAxis = new Map(map.keysSecondAxis);
9265
- if (map instanceof Map2dView) {
9266
- this.baseMap = map.baseMap;
9262
+ constructor(map2) {
9263
+ this.keysFirstAxis = new Map(map2.keysFirstAxis);
9264
+ this.keysSecondAxis = new Map(map2.keysSecondAxis);
9265
+ if (map2 instanceof Map2dView) {
9266
+ this.baseMap = map2.baseMap;
9267
9267
  }
9268
- this.baseMap = map;
9268
+ this.baseMap = map2;
9269
9269
  }
9270
9270
  serializeFirstAxis(key) {
9271
9271
  return this.baseMap.serializeFirstAxis(key);
@@ -10489,7 +10489,7 @@ const SequencesByLocationMap = ({
10489
10489
  if (!ref.current) {
10490
10490
  return;
10491
10491
  }
10492
- const leafletMap = Leaflet.map(ref.current, {
10492
+ const leafletMap = map(ref.current, {
10493
10493
  scrollWheelZoom: enableMapNavigation,
10494
10494
  zoomControl: enableMapNavigation,
10495
10495
  keyboard: enableMapNavigation,
@@ -10498,7 +10498,7 @@ const SequencesByLocationMap = ({
10498
10498
  zoom,
10499
10499
  center: [offsetY, offsetX]
10500
10500
  });
10501
- Leaflet.geoJson(locations, {
10501
+ geoJson(locations, {
10502
10502
  style: (feature) => {
10503
10503
  var _a;
10504
10504
  return {
@@ -11372,6 +11372,46 @@ __decorateClass$4([
11372
11372
  DateRangeSelectorComponent = __decorateClass$4([
11373
11373
  t$3("gs-date-range-selector")
11374
11374
  ], DateRangeSelectorComponent);
11375
+ async function fetchAutocompletionList({
11376
+ fields,
11377
+ lapis,
11378
+ signal,
11379
+ lapisFilter
11380
+ }) {
11381
+ const toAncestorInHierarchyOverwriteValues = Array(fields.length - 1).fill(0).map((_2, i2) => i2 + 1).map((i2) => fields.slice(i2).reduce((acc, field) => ({ ...acc, [field]: null }), {}));
11382
+ const fetchAggregatedOperator = new FetchAggregatedOperator(
11383
+ lapisFilter ?? {},
11384
+ fields
11385
+ );
11386
+ const data = (await fetchAggregatedOperator.evaluate(lapis, signal)).content;
11387
+ const locationValues = data.map((entry) => fields.reduce((acc, field) => ({ ...acc, [field]: entry[field] }), {})).reduce((setOfAllHierarchies, entry) => {
11388
+ setOfAllHierarchies.add(JSON.stringify(entry));
11389
+ toAncestorInHierarchyOverwriteValues.forEach((overwriteValues) => {
11390
+ setOfAllHierarchies.add(JSON.stringify({ ...entry, ...overwriteValues }));
11391
+ });
11392
+ return setOfAllHierarchies;
11393
+ }, /* @__PURE__ */ new Set());
11394
+ return [...locationValues].map((json) => JSON.parse(json)).sort(compareLocationEntries(fields)).map((entry) => fields.reduce((acc, field) => ({ ...acc, [field]: entry[field] ?? void 0 }), {}));
11395
+ }
11396
+ function compareLocationEntries(fields) {
11397
+ return (a2, b3) => {
11398
+ for (const field of fields) {
11399
+ const valueA = a2[field];
11400
+ const valueB = b3[field];
11401
+ if (valueA === valueB) {
11402
+ continue;
11403
+ }
11404
+ if (valueA === null) {
11405
+ return -1;
11406
+ }
11407
+ if (valueB === null) {
11408
+ return 1;
11409
+ }
11410
+ return valueA < valueB ? -1 : 1;
11411
+ }
11412
+ return 0;
11413
+ };
11414
+ }
11375
11415
  function _objectWithoutPropertiesLoose(r2, e2) {
11376
11416
  if (null == r2) return {};
11377
11417
  var t2 = {};
@@ -14294,80 +14334,20 @@ process.env.NODE_ENV !== "production" ? "__function_remove_selected_item__" : 9;
14294
14334
  process.env.NODE_ENV !== "production" ? "__function_set_selected_items__" : 10;
14295
14335
  process.env.NODE_ENV !== "production" ? "__function_set_active_index__" : 11;
14296
14336
  process.env.NODE_ENV !== "production" ? "__function_reset__" : 12;
14297
- async function fetchAutocompletionList(fields, lapis, signal) {
14298
- const toAncestorInHierarchyOverwriteValues = Array(fields.length - 1).fill(0).map((_2, i2) => i2 + 1).map((i2) => fields.slice(i2).reduce((acc, field) => ({ ...acc, [field]: null }), {}));
14299
- const fetchAggregatedOperator = new FetchAggregatedOperator({}, fields);
14300
- const data = (await fetchAggregatedOperator.evaluate(lapis, signal)).content;
14301
- const locationValues = data.map((entry) => fields.reduce((acc, field) => ({ ...acc, [field]: entry[field] }), {})).reduce((setOfAllHierarchies, entry) => {
14302
- setOfAllHierarchies.add(JSON.stringify(entry));
14303
- toAncestorInHierarchyOverwriteValues.forEach((overwriteValues) => {
14304
- setOfAllHierarchies.add(JSON.stringify({ ...entry, ...overwriteValues }));
14305
- });
14306
- return setOfAllHierarchies;
14307
- }, /* @__PURE__ */ new Set());
14308
- return [...locationValues].map((json) => JSON.parse(json)).sort(compareLocationEntries(fields)).map((entry) => fields.reduce((acc, field) => ({ ...acc, [field]: entry[field] ?? void 0 }), {}));
14309
- }
14310
- function compareLocationEntries(fields) {
14311
- return (a2, b3) => {
14312
- for (const field of fields) {
14313
- const valueA = a2[field];
14314
- const valueB = b3[field];
14315
- if (valueA === valueB) {
14316
- continue;
14317
- }
14318
- if (valueA === null) {
14319
- return -1;
14320
- }
14321
- if (valueB === null) {
14322
- return 1;
14323
- }
14324
- return valueA < valueB ? -1 : 1;
14325
- }
14326
- return 0;
14327
- };
14328
- }
14329
- const lineageFilterInnerPropsSchema$1 = z$2.object({
14330
- value: z$2.record(z$2.string().nullable().optional()).optional(),
14331
- placeholderText: z$2.string().optional(),
14332
- fields: z$2.array(z$2.string()).min(1)
14333
- });
14334
- const lineageFilterPropsSchema$1 = lineageFilterInnerPropsSchema$1.extend({
14335
- width: z$2.string()
14336
- });
14337
- const LocationFilter = (props) => {
14338
- const { width, ...innerProps } = props;
14339
- const size = { width, height: "3rem" };
14340
- return /* @__PURE__ */ u$1(ErrorBoundary, { size, layout: "horizontal", componentProps: props, schema: lineageFilterPropsSchema$1, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(LocationFilterInner, { ...innerProps }) }) });
14341
- };
14342
- const LocationFilterInner = ({ value, fields, placeholderText }) => {
14343
- const lapis = x$1(LapisUrlContext);
14344
- const { data, error, isLoading } = useQuery(() => fetchAutocompletionList(fields, lapis), [fields, lapis]);
14345
- if (isLoading) {
14346
- return /* @__PURE__ */ u$1(LoadingDisplay, {});
14347
- }
14348
- if (error) {
14349
- throw error;
14350
- }
14351
- return /* @__PURE__ */ u$1(LocationSelector, { fields, value, placeholderText, locationData: data });
14352
- };
14353
- const LocationSelector = ({
14354
- fields,
14337
+ function DownshiftCombobox({
14338
+ allItems,
14355
14339
  value,
14340
+ filterItemsByInputValue,
14341
+ createEvent,
14342
+ itemToString: itemToString2,
14356
14343
  placeholderText,
14357
- locationData
14358
- }) => {
14344
+ formatItemInList
14345
+ }) {
14359
14346
  var _a;
14360
- const allItems = T$1(
14361
- () => locationData.map((locationFilter) => {
14362
- return toSelectOption(locationFilter, fields);
14363
- }).filter((item) => item !== void 0),
14364
- [locationData, fields]
14347
+ const initialSelectedItem = value ?? null;
14348
+ const [items, setItems] = h(
14349
+ allItems.filter((item) => filterItemsByInputValue(item, itemToString2(initialSelectedItem)))
14365
14350
  );
14366
- const initialSelectedItem = T$1(
14367
- () => value !== void 0 ? toSelectOption(value, fields) : null,
14368
- [value, fields]
14369
- );
14370
- const [items, setItems] = h(allItems.filter((item) => filterByInputValue(item, initialSelectedItem == null ? void 0 : initialSelectedItem.label)));
14371
14351
  const divRef = A$1(null);
14372
14352
  const shadowRoot = ((_a = divRef.current) == null ? void 0 : _a.shadowRoot) ?? void 0;
14373
14353
  const environment = shadowRoot !== void 0 ? {
@@ -14390,17 +14370,17 @@ const LocationSelector = ({
14390
14370
  closeMenu
14391
14371
  } = useCombobox({
14392
14372
  onInputValueChange({ inputValue: inputValue2 }) {
14393
- setItems(allItems.filter((item) => filterByInputValue(item, inputValue2)));
14373
+ setItems(allItems.filter((item) => filterItemsByInputValue(item, inputValue2)));
14394
14374
  },
14395
14375
  onSelectedItemChange({ selectedItem: selectedItem2 }) {
14396
14376
  var _a2;
14397
14377
  if (selectedItem2 !== null) {
14398
- (_a2 = divRef.current) == null ? void 0 : _a2.dispatchEvent(new LocationChangedEvent(selectedItem2.lapisFilter));
14378
+ (_a2 = divRef.current) == null ? void 0 : _a2.dispatchEvent(createEvent(selectedItem2));
14399
14379
  }
14400
14380
  },
14401
14381
  items,
14402
14382
  itemToString(item) {
14403
- return (item == null ? void 0 : item.label) ?? "";
14383
+ return itemToString2(item);
14404
14384
  },
14405
14385
  initialSelectedItem,
14406
14386
  environment
@@ -14408,15 +14388,15 @@ const LocationSelector = ({
14408
14388
  const onInputBlur = () => {
14409
14389
  var _a2;
14410
14390
  if (inputValue === "") {
14411
- (_a2 = divRef.current) == null ? void 0 : _a2.dispatchEvent(new LocationChangedEvent(emptyLocationFilter(fields)));
14391
+ (_a2 = divRef.current) == null ? void 0 : _a2.dispatchEvent(createEvent(null));
14412
14392
  selectItem(null);
14413
- } else if (inputValue !== (selectedItem == null ? void 0 : selectedItem.label)) {
14414
- setInputValue((selectedItem == null ? void 0 : selectedItem.label) || "");
14393
+ } else if (inputValue !== itemToString2(selectedItem)) {
14394
+ setInputValue(itemToString2(selectedItem) || "");
14415
14395
  }
14416
14396
  };
14417
14397
  const clearInput = () => {
14418
14398
  var _a2;
14419
- (_a2 = divRef.current) == null ? void 0 : _a2.dispatchEvent(new LocationChangedEvent(emptyLocationFilter(fields)));
14399
+ (_a2 = divRef.current) == null ? void 0 : _a2.dispatchEvent(createEvent(null));
14420
14400
  selectItem(null);
14421
14401
  };
14422
14402
  const buttonRef = A$1(null);
@@ -14465,34 +14445,90 @@ const LocationSelector = ({
14465
14445
  ]
14466
14446
  }
14467
14447
  ) }),
14468
- /* @__PURE__ */ u$1(
14448
+ isOpen && /* @__PURE__ */ u$1(
14469
14449
  "ul",
14470
14450
  {
14471
- className: `absolute bg-white mt-1 shadow-md max-h-80 overflow-scroll z-10 w-full min-w-32 ${!(isOpen && items.length > 0) && "hidden"}`,
14451
+ className: "absolute bg-white mt-1 shadow-md max-h-80 overflow-scroll z-10 w-full min-w-32",
14472
14452
  ...getMenuProps(),
14473
- children: isOpen && items.map((item, index) => /* @__PURE__ */ u$1(
14453
+ children: items.length > 0 ? items.map((item, index) => /* @__PURE__ */ u$1(
14474
14454
  "li",
14475
14455
  {
14476
- className: `${highlightedIndex === index && "bg-blue-300"} ${selectedItem !== null && selectedItem.description === item.description && "font-bold"} py-2 px-3 shadow-sm flex flex-col`,
14456
+ className: `${highlightedIndex === index ? "bg-blue-300" : ""} ${selectedItem !== null && itemToString2(selectedItem) === itemToString2(item) ? "font-bold" : ""} py-2 px-3 shadow-sm flex flex-col`,
14477
14457
  ...getItemProps({ item, index }),
14478
- children: [
14479
- /* @__PURE__ */ u$1("span", { children: item.label }),
14480
- /* @__PURE__ */ u$1("span", { className: "text-sm text-gray-500", children: item.description })
14481
- ]
14458
+ children: formatItemInList(item)
14482
14459
  },
14483
- item.description
14484
- ))
14460
+ itemToString2(item)
14461
+ )) : /* @__PURE__ */ u$1("li", { className: "py-2 px-3 shadow-sm flex flex-col", children: "No elements to select." })
14485
14462
  }
14486
14463
  )
14487
14464
  ] });
14465
+ }
14466
+ const locationSelectorPropsSchema = z$2.object({
14467
+ value: lapisLocationFilterSchema.optional(),
14468
+ placeholderText: z$2.string().optional(),
14469
+ fields: z$2.array(z$2.string()).min(1)
14470
+ });
14471
+ const locationFilterInnerPropsSchema = locationSelectorPropsSchema.extend({ lapisFilter: lapisFilterSchema });
14472
+ const locationFilterPropsSchema = locationFilterInnerPropsSchema.extend({
14473
+ width: z$2.string()
14474
+ });
14475
+ const LocationFilter = (props) => {
14476
+ const { width, ...innerProps } = props;
14477
+ const size = { width, height: "3rem" };
14478
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, layout: "horizontal", componentProps: props, schema: locationFilterPropsSchema, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(LocationFilterInner, { ...innerProps }) }) });
14488
14479
  };
14489
- function filterByInputValue(item, inputValue) {
14480
+ const LocationFilterInner = ({ value, fields, placeholderText, lapisFilter }) => {
14481
+ const lapis = x$1(LapisUrlContext);
14482
+ const { data, error, isLoading } = useQuery(
14483
+ () => fetchAutocompletionList({ fields, lapis, lapisFilter }),
14484
+ [fields, lapis, lapisFilter]
14485
+ );
14486
+ if (isLoading) {
14487
+ return /* @__PURE__ */ u$1(LoadingDisplay, {});
14488
+ }
14489
+ if (error) {
14490
+ throw error;
14491
+ }
14492
+ return /* @__PURE__ */ u$1(LocationSelector, { fields, value, placeholderText, locationData: data });
14493
+ };
14494
+ const LocationSelector = ({
14495
+ fields,
14496
+ value,
14497
+ placeholderText,
14498
+ locationData
14499
+ }) => {
14500
+ const allItems = T$1(() => {
14501
+ return locationData.map((location) => toSelectItem(location, fields)).filter((item) => item !== void 0);
14502
+ }, [fields, locationData]);
14503
+ const selectedItem = T$1(() => {
14504
+ return value !== void 0 ? toSelectItem(value, fields) : void 0;
14505
+ }, [fields, value]);
14506
+ return /* @__PURE__ */ u$1(
14507
+ DownshiftCombobox,
14508
+ {
14509
+ allItems,
14510
+ value: selectedItem,
14511
+ filterItemsByInputValue: filterByInputValue$2,
14512
+ createEvent: (item) => new LocationChangedEvent((item == null ? void 0 : item.lapisFilter) ?? emptyLocationFilter(fields)),
14513
+ itemToString: (item) => (item == null ? void 0 : item.label) ?? "",
14514
+ placeholderText,
14515
+ formatItemInList: (item) => {
14516
+ return /* @__PURE__ */ u$1(Fragment, { children: [
14517
+ /* @__PURE__ */ u$1("span", { children: item.label }),
14518
+ /* @__PURE__ */ u$1("span", { className: "text-sm text-gray-500", children: item.description })
14519
+ ] });
14520
+ }
14521
+ }
14522
+ );
14523
+ };
14524
+ function filterByInputValue$2(item, inputValue) {
14525
+ var _a;
14490
14526
  if (inputValue === void 0 || inputValue === null) {
14491
14527
  return true;
14492
14528
  }
14493
- return (item == null ? void 0 : item.label.toLowerCase().includes(inputValue.toLowerCase())) || (item == null ? void 0 : item.description.toLowerCase().includes(inputValue.toLowerCase()));
14529
+ return ((_a = item == null ? void 0 : item.label) == null ? void 0 : _a.toLowerCase().includes(inputValue.toLowerCase())) || (item == null ? void 0 : item.description.toLowerCase().includes(inputValue.toLowerCase()));
14494
14530
  }
14495
- function toSelectOption(locationFilter, fields) {
14531
+ function toSelectItem(locationFilter, fields) {
14496
14532
  const concatenatedLocation = concatenateLocation(locationFilter, fields);
14497
14533
  const lastNonUndefinedField = [...fields].reverse().find((field) => locationFilter[field] !== void 0 && locationFilter[field] !== null);
14498
14534
  if (lastNonUndefinedField === void 0) {
@@ -14528,6 +14564,7 @@ let LocationFilterComponent = class extends PreactLitAdapter {
14528
14564
  super(...arguments);
14529
14565
  this.value = void 0;
14530
14566
  this.fields = [];
14567
+ this.lapisFilter = {};
14531
14568
  this.width = "100%";
14532
14569
  this.placeholderText = void 0;
14533
14570
  }
@@ -14537,6 +14574,7 @@ let LocationFilterComponent = class extends PreactLitAdapter {
14537
14574
  {
14538
14575
  value: this.value,
14539
14576
  fields: this.fields,
14577
+ lapisFilter: this.lapisFilter,
14540
14578
  width: this.width,
14541
14579
  placeholderText: this.placeholderText
14542
14580
  }
@@ -14549,6 +14587,9 @@ __decorateClass$3([
14549
14587
  __decorateClass$3([
14550
14588
  n$1({ type: Array })
14551
14589
  ], LocationFilterComponent.prototype, "fields", 2);
14590
+ __decorateClass$3([
14591
+ n$1({ type: Object })
14592
+ ], LocationFilterComponent.prototype, "lapisFilter", 2);
14552
14593
  __decorateClass$3([
14553
14594
  n$1({ type: String })
14554
14595
  ], LocationFilterComponent.prototype, "width", 2);
@@ -14558,16 +14599,22 @@ __decorateClass$3([
14558
14599
  LocationFilterComponent = __decorateClass$3([
14559
14600
  t$3("gs-location-filter")
14560
14601
  ], LocationFilterComponent);
14561
- async function fetchAutocompleteList(lapis, field, signal) {
14562
- const fetchAggregatedOperator = new FetchAggregatedOperator({}, [field]);
14602
+ async function fetchStringAutocompleteList({
14603
+ lapis,
14604
+ field,
14605
+ lapisFilter,
14606
+ signal
14607
+ }) {
14608
+ const fetchAggregatedOperator = new FetchAggregatedOperator(lapisFilter ?? {}, [field]);
14563
14609
  const data = (await fetchAggregatedOperator.evaluate(lapis, signal)).content;
14564
- return data.map((item) => item[field]);
14610
+ return data.map((item) => item[field]).sort();
14565
14611
  }
14566
- const textInputInnerPropsSchema = z$2.object({
14612
+ const textSelectorPropsSchema = z$2.object({
14567
14613
  lapisField: z$2.string().min(1),
14568
14614
  placeholderText: z$2.string().optional(),
14569
- initialValue: z$2.string().optional()
14615
+ value: z$2.string().optional()
14570
14616
  });
14617
+ const textInputInnerPropsSchema = textSelectorPropsSchema.extend({ lapisFilter: lapisFilterSchema });
14571
14618
  const textInputPropsSchema = textInputInnerPropsSchema.extend({
14572
14619
  width: z$2.string()
14573
14620
  });
@@ -14576,10 +14623,17 @@ const TextInput = (props) => {
14576
14623
  const size = { width, height: "3rem" };
14577
14624
  return /* @__PURE__ */ u$1(ErrorBoundary, { size, layout: "horizontal", componentProps: props, schema: textInputPropsSchema, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(TextInputInner, { ...innerProps }) }) });
14578
14625
  };
14579
- const TextInputInner = ({ lapisField, placeholderText, initialValue }) => {
14626
+ const TextInputInner = ({
14627
+ value,
14628
+ lapisField,
14629
+ placeholderText,
14630
+ lapisFilter
14631
+ }) => {
14580
14632
  const lapis = x$1(LapisUrlContext);
14581
- const inputRef = A$1(null);
14582
- const { data, error, isLoading } = useQuery(() => fetchAutocompleteList(lapis, lapisField), [lapisField, lapis]);
14633
+ const { data, error, isLoading } = useQuery(
14634
+ () => fetchStringAutocompleteList({ lapis, field: lapisField, lapisFilter }),
14635
+ [lapisField, lapis, lapisFilter]
14636
+ );
14583
14637
  if (isLoading) {
14584
14638
  return /* @__PURE__ */ u$1(LoadingDisplay, {});
14585
14639
  }
@@ -14589,41 +14643,35 @@ const TextInputInner = ({ lapisField, placeholderText, initialValue }) => {
14589
14643
  if (data === null) {
14590
14644
  return /* @__PURE__ */ u$1(NoDataDisplay, {});
14591
14645
  }
14592
- const onInput = () => {
14593
- var _a, _b, _c;
14594
- const value = ((_a = inputRef.current) == null ? void 0 : _a.value) === "" ? void 0 : (_b = inputRef.current) == null ? void 0 : _b.value;
14595
- if (isValidValue(value)) {
14596
- (_c = inputRef.current) == null ? void 0 : _c.dispatchEvent(
14597
- new CustomEvent("gs-text-input-changed", {
14598
- detail: { [lapisField]: value },
14599
- bubbles: true,
14600
- composed: true
14601
- })
14602
- );
14603
- }
14604
- };
14605
- const isValidValue = (value) => {
14606
- if (value === void 0) {
14607
- return true;
14608
- }
14609
- return data.includes(value);
14610
- };
14611
- return /* @__PURE__ */ u$1(Fragment, { children: [
14612
- /* @__PURE__ */ u$1(
14613
- "input",
14614
- {
14615
- type: "text",
14616
- class: "input input-bordered w-full",
14617
- placeholder: placeholderText ?? lapisField,
14618
- onInput,
14619
- ref: inputRef,
14620
- list: lapisField,
14621
- value: initialValue
14646
+ return /* @__PURE__ */ u$1(TextSelector, { lapisField, value, placeholderText, data });
14647
+ };
14648
+ const TextSelector = ({
14649
+ lapisField,
14650
+ value,
14651
+ placeholderText,
14652
+ data
14653
+ }) => {
14654
+ return /* @__PURE__ */ u$1(
14655
+ DownshiftCombobox,
14656
+ {
14657
+ allItems: data,
14658
+ value,
14659
+ filterItemsByInputValue: filterByInputValue$1,
14660
+ createEvent: (item) => new TextInputChangedEvent({ [lapisField]: item ?? void 0 }),
14661
+ itemToString: (item) => item ?? "",
14662
+ placeholderText,
14663
+ formatItemInList: (item) => {
14664
+ return /* @__PURE__ */ u$1("span", { children: item });
14622
14665
  }
14623
- ),
14624
- /* @__PURE__ */ u$1("datalist", { id: lapisField, children: data.map((item) => /* @__PURE__ */ u$1("option", { value: item }, item)) })
14625
- ] });
14666
+ }
14667
+ );
14626
14668
  };
14669
+ function filterByInputValue$1(item, inputValue) {
14670
+ if (inputValue === void 0 || inputValue === null || inputValue === "") {
14671
+ return true;
14672
+ }
14673
+ return item == null ? void 0 : item.toLowerCase().includes((inputValue == null ? void 0 : inputValue.toLowerCase()) || "");
14674
+ }
14627
14675
  var __defProp$2 = Object.defineProperty;
14628
14676
  var __getOwnPropDesc$2 = Object.getOwnPropertyDescriptor;
14629
14677
  var __decorateClass$2 = (decorators, target, key, kind) => {
@@ -14637,8 +14685,9 @@ var __decorateClass$2 = (decorators, target, key, kind) => {
14637
14685
  let TextInputComponent = class extends PreactLitAdapter {
14638
14686
  constructor() {
14639
14687
  super(...arguments);
14640
- this.initialValue = void 0;
14688
+ this.value = void 0;
14641
14689
  this.lapisField = "";
14690
+ this.lapisFilter = {};
14642
14691
  this.placeholderText = void 0;
14643
14692
  this.width = "100%";
14644
14693
  }
@@ -14647,8 +14696,9 @@ let TextInputComponent = class extends PreactLitAdapter {
14647
14696
  TextInput,
14648
14697
  {
14649
14698
  lapisField: this.lapisField,
14699
+ lapisFilter: this.lapisFilter,
14650
14700
  placeholderText: this.placeholderText,
14651
- initialValue: this.initialValue,
14701
+ value: this.value,
14652
14702
  width: this.width
14653
14703
  }
14654
14704
  );
@@ -14656,10 +14706,13 @@ let TextInputComponent = class extends PreactLitAdapter {
14656
14706
  };
14657
14707
  __decorateClass$2([
14658
14708
  n$1()
14659
- ], TextInputComponent.prototype, "initialValue", 2);
14709
+ ], TextInputComponent.prototype, "value", 2);
14660
14710
  __decorateClass$2([
14661
14711
  n$1()
14662
14712
  ], TextInputComponent.prototype, "lapisField", 2);
14713
+ __decorateClass$2([
14714
+ n$1({ type: Object })
14715
+ ], TextInputComponent.prototype, "lapisFilter", 2);
14663
14716
  __decorateClass$2([
14664
14717
  n$1()
14665
14718
  ], TextInputComponent.prototype, "placeholderText", 2);
@@ -15295,15 +15348,23 @@ __decorateClass$1([
15295
15348
  MutationFilterComponent = __decorateClass$1([
15296
15349
  t$3("gs-mutation-filter")
15297
15350
  ], MutationFilterComponent);
15298
- async function fetchLineageAutocompleteList(lapis, field, signal) {
15299
- const fetchAggregatedOperator = new FetchAggregatedOperator({}, [field]);
15351
+ async function fetchLineageAutocompleteList({
15352
+ lapis,
15353
+ field,
15354
+ signal,
15355
+ lapisFilter
15356
+ }) {
15357
+ const fetchAggregatedOperator = new FetchAggregatedOperator(lapisFilter ?? {}, [field]);
15300
15358
  const data = (await fetchAggregatedOperator.evaluate(lapis, signal)).content;
15301
15359
  return data.flatMap((item) => [item[field], `${item[field]}*`]).sort();
15302
15360
  }
15303
- const lineageFilterInnerPropsSchema = z$2.object({
15361
+ const lineageSelectorPropsSchema = z$2.object({
15304
15362
  lapisField: z$2.string().min(1),
15305
15363
  placeholderText: z$2.string().optional(),
15306
- initialValue: z$2.string()
15364
+ value: z$2.string()
15365
+ });
15366
+ const lineageFilterInnerPropsSchema = lineageSelectorPropsSchema.extend({
15367
+ lapisFilter: lapisFilterSchema
15307
15368
  });
15308
15369
  const lineageFilterPropsSchema = lineageFilterInnerPropsSchema.extend({
15309
15370
  width: z$2.string()
@@ -15316,13 +15377,13 @@ const LineageFilter = (props) => {
15316
15377
  const LineageFilterInner = ({
15317
15378
  lapisField,
15318
15379
  placeholderText,
15319
- initialValue
15380
+ value,
15381
+ lapisFilter
15320
15382
  }) => {
15321
15383
  const lapis = x$1(LapisUrlContext);
15322
- const inputRef = A$1(null);
15323
15384
  const { data, error, isLoading } = useQuery(
15324
- () => fetchLineageAutocompleteList(lapis, lapisField),
15325
- [lapisField, lapis]
15385
+ () => fetchLineageAutocompleteList({ lapis, field: lapisField, lapisFilter }),
15386
+ [lapisField, lapis, lapisFilter]
15326
15387
  );
15327
15388
  if (isLoading) {
15328
15389
  return /* @__PURE__ */ u$1(LoadingDisplay, {});
@@ -15330,44 +15391,33 @@ const LineageFilterInner = ({
15330
15391
  if (error !== null) {
15331
15392
  throw error;
15332
15393
  }
15333
- if (data === null) {
15334
- return /* @__PURE__ */ u$1(NoDataDisplay, {});
15335
- }
15336
- const onInput = () => {
15337
- var _a, _b, _c;
15338
- const value = ((_a = inputRef.current) == null ? void 0 : _a.value) === "" ? void 0 : (_b = inputRef.current) == null ? void 0 : _b.value;
15339
- if (isValidValue(value)) {
15340
- (_c = inputRef.current) == null ? void 0 : _c.dispatchEvent(
15341
- new CustomEvent("gs-lineage-filter-changed", {
15342
- detail: { [lapisField]: value },
15343
- bubbles: true,
15344
- composed: true
15345
- })
15346
- );
15347
- }
15348
- };
15349
- const isValidValue = (value) => {
15350
- if (value === void 0) {
15351
- return true;
15394
+ return /* @__PURE__ */ u$1(LineageSelector, { lapisField, value, placeholderText, data });
15395
+ };
15396
+ const LineageSelector = ({
15397
+ lapisField,
15398
+ value,
15399
+ placeholderText,
15400
+ data
15401
+ }) => {
15402
+ return /* @__PURE__ */ u$1(
15403
+ DownshiftCombobox,
15404
+ {
15405
+ allItems: data,
15406
+ value,
15407
+ filterItemsByInputValue: filterByInputValue,
15408
+ createEvent: (item) => new LineageFilterChangedEvent({ [lapisField]: item ?? void 0 }),
15409
+ itemToString: (item) => item ?? "",
15410
+ placeholderText,
15411
+ formatItemInList: (item) => item
15352
15412
  }
15353
- return data.includes(value);
15354
- };
15355
- return /* @__PURE__ */ u$1(Fragment, { children: [
15356
- /* @__PURE__ */ u$1(
15357
- "input",
15358
- {
15359
- type: "text",
15360
- class: "input input-bordered w-full",
15361
- placeholder: placeholderText !== void 0 ? placeholderText : lapisField,
15362
- onInput,
15363
- ref: inputRef,
15364
- list: lapisField,
15365
- value: initialValue
15366
- }
15367
- ),
15368
- /* @__PURE__ */ u$1("datalist", { id: lapisField, children: data.map((item) => /* @__PURE__ */ u$1("option", { value: item }, item)) })
15369
- ] });
15413
+ );
15370
15414
  };
15415
+ function filterByInputValue(item, inputValue) {
15416
+ if (inputValue === void 0 || inputValue === null || inputValue === "") {
15417
+ return true;
15418
+ }
15419
+ return item == null ? void 0 : item.toLowerCase().includes((inputValue == null ? void 0 : inputValue.toLowerCase()) || "");
15420
+ }
15371
15421
  var __defProp = Object.defineProperty;
15372
15422
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
15373
15423
  var __decorateClass = (decorators, target, key, kind) => {
@@ -15381,8 +15431,9 @@ var __decorateClass = (decorators, target, key, kind) => {
15381
15431
  let LineageFilterComponent = class extends PreactLitAdapter {
15382
15432
  constructor() {
15383
15433
  super(...arguments);
15384
- this.initialValue = "";
15434
+ this.value = "";
15385
15435
  this.lapisField = "";
15436
+ this.lapisFilter = {};
15386
15437
  this.placeholderText = void 0;
15387
15438
  this.width = "100%";
15388
15439
  }
@@ -15391,8 +15442,9 @@ let LineageFilterComponent = class extends PreactLitAdapter {
15391
15442
  LineageFilter,
15392
15443
  {
15393
15444
  lapisField: this.lapisField,
15445
+ lapisFilter: this.lapisFilter,
15394
15446
  placeholderText: this.placeholderText,
15395
- initialValue: this.initialValue,
15447
+ value: this.value,
15396
15448
  width: this.width
15397
15449
  }
15398
15450
  );
@@ -15400,10 +15452,13 @@ let LineageFilterComponent = class extends PreactLitAdapter {
15400
15452
  };
15401
15453
  __decorateClass([
15402
15454
  n$1()
15403
- ], LineageFilterComponent.prototype, "initialValue", 2);
15455
+ ], LineageFilterComponent.prototype, "value", 2);
15404
15456
  __decorateClass([
15405
15457
  n$1()
15406
15458
  ], LineageFilterComponent.prototype, "lapisField", 2);
15459
+ __decorateClass([
15460
+ n$1({ type: Object })
15461
+ ], LineageFilterComponent.prototype, "lapisFilter", 2);
15407
15462
  __decorateClass([
15408
15463
  n$1()
15409
15464
  ], LineageFilterComponent.prototype, "placeholderText", 2);