@genspectrum/dashboard-components 0.12.1 → 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 (36) hide show
  1. package/custom-elements.json +114 -25
  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 +55 -21
  5. package/dist/components.js +229 -286
  6. package/dist/components.js.map +1 -1
  7. package/dist/util.d.ts +28 -14
  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/textInput/TextInputChangedEvent.ts +1 -1
  22. package/src/preact/textInput/fetchStringAutocompleteList.ts +20 -0
  23. package/src/preact/textInput/text-input.stories.tsx +14 -11
  24. package/src/preact/textInput/text-input.tsx +39 -140
  25. package/src/types.ts +3 -0
  26. package/src/utilEntrypoint.ts +2 -0
  27. package/src/web-components/input/gs-lineage-filter.stories.ts +120 -31
  28. package/src/web-components/input/gs-lineage-filter.tsx +24 -8
  29. package/src/web-components/input/gs-location-filter.stories.ts +9 -0
  30. package/src/web-components/input/gs-location-filter.tsx +21 -3
  31. package/src/web-components/input/gs-text-input.stories.ts +14 -5
  32. package/src/web-components/input/gs-text-input.tsx +23 -7
  33. package/standalone-bundle/dashboard-components.js +5574 -5605
  34. package/standalone-bundle/dashboard-components.js.map +1 -1
  35. package/dist/LocationChangedEvent-CORvQvXv.js.map +0 -1
  36. package/src/preact/textInput/fetchAutocompleteList.ts +0 -9
@@ -6,7 +6,7 @@ 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";
@@ -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]
14365
- );
14366
- const initialSelectedItem = T$1(
14367
- () => value !== void 0 ? toSelectOption(value, fields) : null,
14368
- [value, fields]
14347
+ const initialSelectedItem = value ?? null;
14348
+ const [items, setItems] = h(
14349
+ allItems.filter((item) => filterItemsByInputValue(item, itemToString2(initialSelectedItem)))
14369
14350
  );
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,25 +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
14610
  return data.map((item) => item[field]).sort();
14565
14611
  }
14566
- class TextInputChangedEvent extends CustomEvent {
14567
- constructor(detail) {
14568
- super("gs-text-input-changed", {
14569
- detail,
14570
- bubbles: true,
14571
- composed: true
14572
- });
14573
- }
14574
- }
14575
- const textInputInnerPropsSchema = z$2.object({
14612
+ const textSelectorPropsSchema = z$2.object({
14576
14613
  lapisField: z$2.string().min(1),
14577
14614
  placeholderText: z$2.string().optional(),
14578
- initialValue: z$2.string().optional()
14615
+ value: z$2.string().optional()
14579
14616
  });
14617
+ const textInputInnerPropsSchema = textSelectorPropsSchema.extend({ lapisFilter: lapisFilterSchema });
14580
14618
  const textInputPropsSchema = textInputInnerPropsSchema.extend({
14581
14619
  width: z$2.string()
14582
14620
  });
@@ -14585,9 +14623,17 @@ const TextInput = (props) => {
14585
14623
  const size = { width, height: "3rem" };
14586
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 }) }) });
14587
14625
  };
14588
- const TextInputInner = ({ initialValue, lapisField, placeholderText }) => {
14626
+ const TextInputInner = ({
14627
+ value,
14628
+ lapisField,
14629
+ placeholderText,
14630
+ lapisFilter
14631
+ }) => {
14589
14632
  const lapis = x$1(LapisUrlContext);
14590
- 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
+ );
14591
14637
  if (isLoading) {
14592
14638
  return /* @__PURE__ */ u$1(LoadingDisplay, {});
14593
14639
  }
@@ -14597,145 +14643,35 @@ const TextInputInner = ({ initialValue, lapisField, placeholderText }) => {
14597
14643
  if (data === null) {
14598
14644
  return /* @__PURE__ */ u$1(NoDataDisplay, {});
14599
14645
  }
14600
- return /* @__PURE__ */ u$1(
14601
- TextSelector,
14602
- {
14603
- lapisField,
14604
- initialValue,
14605
- placeholderText,
14606
- data
14607
- }
14608
- );
14646
+ return /* @__PURE__ */ u$1(TextSelector, { lapisField, value, placeholderText, data });
14609
14647
  };
14610
14648
  const TextSelector = ({
14611
14649
  lapisField,
14612
- initialValue,
14650
+ value,
14613
14651
  placeholderText,
14614
14652
  data
14615
14653
  }) => {
14616
- var _a;
14617
- const [items, setItems] = h(data.filter((item) => filterByInputValue2(item, initialValue)));
14618
- const divRef = A$1(null);
14619
- const shadowRoot = ((_a = divRef.current) == null ? void 0 : _a.shadowRoot) ?? void 0;
14620
- const environment = shadowRoot !== void 0 ? {
14621
- addEventListener: window.addEventListener.bind(window),
14622
- removeEventListener: window.removeEventListener.bind(window),
14623
- document: shadowRoot.ownerDocument,
14624
- Node: window.Node
14625
- } : void 0;
14626
- function filterByInputValue2(item, inputValue2) {
14627
- if (inputValue2 === void 0 || inputValue2 === null || inputValue2 === "") {
14628
- return true;
14629
- }
14630
- return item == null ? void 0 : item.toLowerCase().includes((inputValue2 == null ? void 0 : inputValue2.toLowerCase()) || "");
14631
- }
14632
- const {
14633
- isOpen,
14634
- getToggleButtonProps,
14635
- getMenuProps,
14636
- getInputProps,
14637
- highlightedIndex,
14638
- getItemProps,
14639
- selectedItem,
14640
- inputValue,
14641
- selectItem,
14642
- setInputValue,
14643
- closeMenu
14644
- } = useCombobox({
14645
- onInputValueChange({ inputValue: inputValue2 }) {
14646
- setItems(data.filter((item) => filterByInputValue2(item, inputValue2)));
14647
- },
14648
- onSelectedItemChange({ selectedItem: selectedItem2 }) {
14649
- var _a2;
14650
- if (selectedItem2 !== null) {
14651
- (_a2 = divRef.current) == null ? void 0 : _a2.dispatchEvent(new TextInputChangedEvent({ [lapisField]: selectedItem2 }));
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 });
14652
14665
  }
14653
- },
14654
- items,
14655
- itemToString(item) {
14656
- return item ?? "";
14657
- },
14658
- initialSelectedItem: initialValue,
14659
- environment
14660
- });
14661
- const onInputBlur = () => {
14662
- var _a2;
14663
- if (inputValue === "") {
14664
- (_a2 = divRef.current) == null ? void 0 : _a2.dispatchEvent(new TextInputChangedEvent({ [lapisField]: void 0 }));
14665
- selectItem(null);
14666
- } else if (inputValue !== selectedItem) {
14667
- setInputValue(selectedItem ?? "");
14668
14666
  }
14669
- };
14670
- const clearInput = () => {
14671
- var _a2;
14672
- (_a2 = divRef.current) == null ? void 0 : _a2.dispatchEvent(new TextInputChangedEvent({ [lapisField]: void 0 }));
14673
- selectItem(null);
14674
- };
14675
- const buttonRef = A$1(null);
14676
- return /* @__PURE__ */ u$1("div", { ref: divRef, className: "relative w-full", children: [
14677
- /* @__PURE__ */ u$1("div", { className: "w-full flex flex-col gap-1", children: /* @__PURE__ */ u$1(
14678
- "div",
14679
- {
14680
- className: "flex gap-0.5 input input-bordered min-w-32",
14681
- onBlur: (event) => {
14682
- if (event.relatedTarget != buttonRef.current) {
14683
- closeMenu();
14684
- }
14685
- },
14686
- children: [
14687
- /* @__PURE__ */ u$1(
14688
- "input",
14689
- {
14690
- placeholder: placeholderText,
14691
- className: "w-full p-1.5",
14692
- ...getInputProps(),
14693
- onBlur: onInputBlur
14694
- }
14695
- ),
14696
- /* @__PURE__ */ u$1(
14697
- "button",
14698
- {
14699
- "aria-label": "clear selection",
14700
- className: `px-2 ${inputValue === "" && "hidden"}`,
14701
- type: "button",
14702
- onClick: clearInput,
14703
- tabIndex: -1,
14704
- children: "×"
14705
- }
14706
- ),
14707
- /* @__PURE__ */ u$1(
14708
- "button",
14709
- {
14710
- "aria-label": "toggle menu",
14711
- className: "px-2",
14712
- type: "button",
14713
- ...getToggleButtonProps(),
14714
- ref: buttonRef,
14715
- children: isOpen ? /* @__PURE__ */ u$1(Fragment, { children: "↑" }) : /* @__PURE__ */ u$1(Fragment, { children: "↓" })
14716
- }
14717
- )
14718
- ]
14719
- }
14720
- ) }),
14721
- /* @__PURE__ */ u$1(
14722
- "ul",
14723
- {
14724
- 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"}`,
14725
- ...getMenuProps(),
14726
- children: isOpen && items.map((item, index) => /* @__PURE__ */ u$1(
14727
- "li",
14728
- {
14729
- className: `${highlightedIndex === index && "bg-blue-300"} ${selectedItem !== null} py-2 px-3 shadow-sm flex flex-col`,
14730
- ...getItemProps({ item, index }),
14731
- children: /* @__PURE__ */ u$1("span", { children: item })
14732
- },
14733
- item
14734
- ))
14735
- }
14736
- )
14737
- ] });
14667
+ );
14738
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
+ }
14739
14675
  var __defProp$2 = Object.defineProperty;
14740
14676
  var __getOwnPropDesc$2 = Object.getOwnPropertyDescriptor;
14741
14677
  var __decorateClass$2 = (decorators, target, key, kind) => {
@@ -14749,8 +14685,9 @@ var __decorateClass$2 = (decorators, target, key, kind) => {
14749
14685
  let TextInputComponent = class extends PreactLitAdapter {
14750
14686
  constructor() {
14751
14687
  super(...arguments);
14752
- this.initialValue = void 0;
14688
+ this.value = void 0;
14753
14689
  this.lapisField = "";
14690
+ this.lapisFilter = {};
14754
14691
  this.placeholderText = void 0;
14755
14692
  this.width = "100%";
14756
14693
  }
@@ -14759,8 +14696,9 @@ let TextInputComponent = class extends PreactLitAdapter {
14759
14696
  TextInput,
14760
14697
  {
14761
14698
  lapisField: this.lapisField,
14699
+ lapisFilter: this.lapisFilter,
14762
14700
  placeholderText: this.placeholderText,
14763
- initialValue: this.initialValue,
14701
+ value: this.value,
14764
14702
  width: this.width
14765
14703
  }
14766
14704
  );
@@ -14768,10 +14706,13 @@ let TextInputComponent = class extends PreactLitAdapter {
14768
14706
  };
14769
14707
  __decorateClass$2([
14770
14708
  n$1()
14771
- ], TextInputComponent.prototype, "initialValue", 2);
14709
+ ], TextInputComponent.prototype, "value", 2);
14772
14710
  __decorateClass$2([
14773
14711
  n$1()
14774
14712
  ], TextInputComponent.prototype, "lapisField", 2);
14713
+ __decorateClass$2([
14714
+ n$1({ type: Object })
14715
+ ], TextInputComponent.prototype, "lapisFilter", 2);
14775
14716
  __decorateClass$2([
14776
14717
  n$1()
14777
14718
  ], TextInputComponent.prototype, "placeholderText", 2);
@@ -15407,15 +15348,23 @@ __decorateClass$1([
15407
15348
  MutationFilterComponent = __decorateClass$1([
15408
15349
  t$3("gs-mutation-filter")
15409
15350
  ], MutationFilterComponent);
15410
- async function fetchLineageAutocompleteList(lapis, field, signal) {
15411
- 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]);
15412
15358
  const data = (await fetchAggregatedOperator.evaluate(lapis, signal)).content;
15413
15359
  return data.flatMap((item) => [item[field], `${item[field]}*`]).sort();
15414
15360
  }
15415
- const lineageFilterInnerPropsSchema = z$2.object({
15361
+ const lineageSelectorPropsSchema = z$2.object({
15416
15362
  lapisField: z$2.string().min(1),
15417
15363
  placeholderText: z$2.string().optional(),
15418
- initialValue: z$2.string()
15364
+ value: z$2.string()
15365
+ });
15366
+ const lineageFilterInnerPropsSchema = lineageSelectorPropsSchema.extend({
15367
+ lapisFilter: lapisFilterSchema
15419
15368
  });
15420
15369
  const lineageFilterPropsSchema = lineageFilterInnerPropsSchema.extend({
15421
15370
  width: z$2.string()
@@ -15428,13 +15377,13 @@ const LineageFilter = (props) => {
15428
15377
  const LineageFilterInner = ({
15429
15378
  lapisField,
15430
15379
  placeholderText,
15431
- initialValue
15380
+ value,
15381
+ lapisFilter
15432
15382
  }) => {
15433
15383
  const lapis = x$1(LapisUrlContext);
15434
- const inputRef = A$1(null);
15435
15384
  const { data, error, isLoading } = useQuery(
15436
- () => fetchLineageAutocompleteList(lapis, lapisField),
15437
- [lapisField, lapis]
15385
+ () => fetchLineageAutocompleteList({ lapis, field: lapisField, lapisFilter }),
15386
+ [lapisField, lapis, lapisFilter]
15438
15387
  );
15439
15388
  if (isLoading) {
15440
15389
  return /* @__PURE__ */ u$1(LoadingDisplay, {});
@@ -15442,44 +15391,33 @@ const LineageFilterInner = ({
15442
15391
  if (error !== null) {
15443
15392
  throw error;
15444
15393
  }
15445
- if (data === null) {
15446
- return /* @__PURE__ */ u$1(NoDataDisplay, {});
15447
- }
15448
- const onInput = () => {
15449
- var _a, _b, _c;
15450
- const value = ((_a = inputRef.current) == null ? void 0 : _a.value) === "" ? void 0 : (_b = inputRef.current) == null ? void 0 : _b.value;
15451
- if (isValidValue(value)) {
15452
- (_c = inputRef.current) == null ? void 0 : _c.dispatchEvent(
15453
- new CustomEvent("gs-lineage-filter-changed", {
15454
- detail: { [lapisField]: value },
15455
- bubbles: true,
15456
- composed: true
15457
- })
15458
- );
15459
- }
15460
- };
15461
- const isValidValue = (value) => {
15462
- if (value === void 0) {
15463
- 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
15464
15412
  }
15465
- return data.includes(value);
15466
- };
15467
- return /* @__PURE__ */ u$1(Fragment, { children: [
15468
- /* @__PURE__ */ u$1(
15469
- "input",
15470
- {
15471
- type: "text",
15472
- class: "input input-bordered w-full",
15473
- placeholder: placeholderText !== void 0 ? placeholderText : lapisField,
15474
- onInput,
15475
- ref: inputRef,
15476
- list: lapisField,
15477
- value: initialValue
15478
- }
15479
- ),
15480
- /* @__PURE__ */ u$1("datalist", { id: lapisField, children: data.map((item) => /* @__PURE__ */ u$1("option", { value: item }, item)) })
15481
- ] });
15413
+ );
15482
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
+ }
15483
15421
  var __defProp = Object.defineProperty;
15484
15422
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
15485
15423
  var __decorateClass = (decorators, target, key, kind) => {
@@ -15493,8 +15431,9 @@ var __decorateClass = (decorators, target, key, kind) => {
15493
15431
  let LineageFilterComponent = class extends PreactLitAdapter {
15494
15432
  constructor() {
15495
15433
  super(...arguments);
15496
- this.initialValue = "";
15434
+ this.value = "";
15497
15435
  this.lapisField = "";
15436
+ this.lapisFilter = {};
15498
15437
  this.placeholderText = void 0;
15499
15438
  this.width = "100%";
15500
15439
  }
@@ -15503,8 +15442,9 @@ let LineageFilterComponent = class extends PreactLitAdapter {
15503
15442
  LineageFilter,
15504
15443
  {
15505
15444
  lapisField: this.lapisField,
15445
+ lapisFilter: this.lapisFilter,
15506
15446
  placeholderText: this.placeholderText,
15507
- initialValue: this.initialValue,
15447
+ value: this.value,
15508
15448
  width: this.width
15509
15449
  }
15510
15450
  );
@@ -15512,10 +15452,13 @@ let LineageFilterComponent = class extends PreactLitAdapter {
15512
15452
  };
15513
15453
  __decorateClass([
15514
15454
  n$1()
15515
- ], LineageFilterComponent.prototype, "initialValue", 2);
15455
+ ], LineageFilterComponent.prototype, "value", 2);
15516
15456
  __decorateClass([
15517
15457
  n$1()
15518
15458
  ], LineageFilterComponent.prototype, "lapisField", 2);
15459
+ __decorateClass([
15460
+ n$1({ type: Object })
15461
+ ], LineageFilterComponent.prototype, "lapisFilter", 2);
15519
15462
  __decorateClass([
15520
15463
  n$1()
15521
15464
  ], LineageFilterComponent.prototype, "placeholderText", 2);