@genspectrum/dashboard-components 0.3.2 → 0.4.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 (27) hide show
  1. package/custom-elements.json +45 -26
  2. package/dist/dashboard-components.js +340 -186
  3. package/dist/dashboard-components.js.map +1 -1
  4. package/dist/genspectrum-components.d.ts +17 -8
  5. package/dist/style.css +58 -50
  6. package/package.json +2 -1
  7. package/src/preact/aggregatedData/aggregate.tsx +1 -1
  8. package/src/preact/components/info.stories.tsx +8 -8
  9. package/src/preact/components/info.tsx +113 -20
  10. package/src/preact/dateRangeSelector/computeInitialValues.spec.ts +99 -0
  11. package/src/preact/dateRangeSelector/computeInitialValues.ts +73 -0
  12. package/src/preact/dateRangeSelector/date-range-selector.stories.tsx +93 -4
  13. package/src/preact/dateRangeSelector/date-range-selector.tsx +27 -88
  14. package/src/preact/dateRangeSelector/selectableOptions.ts +79 -0
  15. package/src/preact/locationFilter/location-filter.tsx +1 -1
  16. package/src/preact/mutationComparison/mutation-comparison.tsx +1 -1
  17. package/src/preact/mutationFilter/mutation-filter.stories.tsx +3 -6
  18. package/src/preact/mutationFilter/mutation-filter.tsx +48 -54
  19. package/src/preact/mutations/mutations.tsx +1 -1
  20. package/src/preact/prevalenceOverTime/prevalence-over-time.tsx +2 -2
  21. package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.tsx +1 -1
  22. package/src/web-components/input/gs-date-range-selector.stories.ts +11 -5
  23. package/src/web-components/input/gs-date-range-selector.tsx +22 -5
  24. package/src/web-components/input/gs-location-filter.stories.ts +6 -7
  25. package/src/web-components/input/gs-location-filter.tsx +3 -2
  26. package/src/web-components/input/gs-mutation-filter.stories.ts +1 -8
  27. package/src/web-components/input/gs-mutation-filter.tsx +1 -9
@@ -6,6 +6,7 @@ import { options, createContext as createContext$1, Fragment, render } from "pre
6
6
  import { Grid } from "gridjs";
7
7
  import { Chart, registerables, Scale } from "chart.js";
8
8
  import { VennDiagramController, ArcSlice, extractSets } from "chartjs-chart-venn";
9
+ import { autoUpdate, computePosition, offset, shift, size } from "@floating-ui/dom";
9
10
  import { ReactiveElement } from "@lit/reactive-element";
10
11
  import { BarWithErrorBarsController, BarWithErrorBar } from "chartjs-chart-error-bars";
11
12
  import flatpickr from "flatpickr";
@@ -1308,8 +1309,8 @@ const ErrorDisplay = ({ error }) => {
1308
1309
  ] })
1309
1310
  ] });
1310
1311
  };
1311
- const ResizeContainer = ({ children, size }) => {
1312
- return /* @__PURE__ */ u$1("div", { style: size, children });
1312
+ const ResizeContainer = ({ children, size: size2 }) => {
1313
+ return /* @__PURE__ */ u$1("div", { style: size2, children });
1313
1314
  };
1314
1315
  const Headline = ({ heading, children }) => {
1315
1316
  if (!heading) {
@@ -1331,33 +1332,107 @@ const ResizingHeadline = ({ heading, children }) => {
1331
1332
  /* @__PURE__ */ u$1("div", { style: { height: `calc(100% - ${h1Height})` }, children })
1332
1333
  ] });
1333
1334
  };
1334
- const ErrorBoundary = ({ size, headline, children }) => {
1335
+ const ErrorBoundary = ({ size: size2, headline, children }) => {
1335
1336
  const [internalError] = b2();
1336
1337
  if (internalError) {
1337
- return /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(ErrorDisplay, { error: internalError }) }) });
1338
+ return /* @__PURE__ */ u$1(ResizeContainer, { size: size2, children: /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(ErrorDisplay, { error: internalError }) }) });
1338
1339
  }
1339
1340
  return /* @__PURE__ */ u$1(Fragment, { children });
1340
1341
  };
1341
- const Info = ({ children, size }) => {
1342
+ const Info = ({ children, height }) => {
1342
1343
  const [showHelp, setShowHelp] = p(false);
1344
+ const referenceRef = F(null);
1345
+ const floatingRef = F(null);
1346
+ useFloatingUi(referenceRef, floatingRef, height, showHelp);
1343
1347
  const toggleHelp = () => {
1344
1348
  setShowHelp(!showHelp);
1345
1349
  };
1346
- return /* @__PURE__ */ u$1("div", { className: "relative", children: [
1347
- /* @__PURE__ */ u$1("button", { className: "btn btn-xs", onClick: toggleHelp, children: "?" }),
1348
- showHelp && /* @__PURE__ */ u$1(
1350
+ useCloseOnEsc(setShowHelp);
1351
+ useCloseOnClickOutside(floatingRef, referenceRef, setShowHelp);
1352
+ return /* @__PURE__ */ u$1("div", { className: "relative z-10", children: [
1353
+ /* @__PURE__ */ u$1("button", { type: "button", className: "btn btn-xs", onClick: toggleHelp, ref: referenceRef, children: "?" }),
1354
+ /* @__PURE__ */ u$1(
1349
1355
  "div",
1350
1356
  {
1351
- className: "absolute top-8 right-6 bg-white p-2 border border-black flex flex-col overflow-auto shadow-lg rounded z-50",
1352
- style: size,
1357
+ ref: floatingRef,
1358
+ className: "bg-white p-2 border border-gray-100 shadow-lg rounded overflow-y-auto opacity-90",
1359
+ style: { position: "absolute", zIndex: 10, display: showHelp ? "" : "none" },
1353
1360
  children: [
1354
1361
  /* @__PURE__ */ u$1("div", { className: "flex flex-col", children }),
1355
- /* @__PURE__ */ u$1("div", { className: "flex justify-end", children: /* @__PURE__ */ u$1("button", { className: "text-sm underline mt-2", onClick: toggleHelp, children: "Close" }) })
1362
+ /* @__PURE__ */ u$1(
1363
+ "button",
1364
+ {
1365
+ onClick: () => setShowHelp(false),
1366
+ className: "float-right underline text-sm hover:text-blue-700 mr-2",
1367
+ children: "Close"
1368
+ }
1369
+ )
1356
1370
  ]
1357
1371
  }
1358
1372
  )
1359
1373
  ] });
1360
1374
  };
1375
+ function useFloatingUi(referenceRef, floatingRef, height, showHelp) {
1376
+ const cleanupRef = F(null);
1377
+ _(() => {
1378
+ if (!referenceRef.current || !floatingRef.current) {
1379
+ return;
1380
+ }
1381
+ const { current: reference } = referenceRef;
1382
+ const { current: floating } = floatingRef;
1383
+ const update = () => {
1384
+ computePosition(reference, floating, {
1385
+ middleware: [
1386
+ offset(10),
1387
+ shift(),
1388
+ size({
1389
+ apply({}) {
1390
+ floating.style.width = "100vw";
1391
+ floating.style.height = height ? height : "50vh";
1392
+ }
1393
+ })
1394
+ ]
1395
+ }).then(({ x, y: y2 }) => {
1396
+ floating.style.left = `${x}px`;
1397
+ floating.style.top = `${y2}px`;
1398
+ });
1399
+ };
1400
+ update();
1401
+ cleanupRef.current = autoUpdate(reference, floating, update);
1402
+ return () => {
1403
+ if (cleanupRef.current) {
1404
+ cleanupRef.current();
1405
+ }
1406
+ };
1407
+ }, [showHelp, height, referenceRef, floatingRef]);
1408
+ }
1409
+ function useCloseOnClickOutside(floatingRef, referenceRef, setShowHelp) {
1410
+ _(() => {
1411
+ const handleClickOutside = (event) => {
1412
+ const path = event.composedPath();
1413
+ if (floatingRef.current && !path.includes(floatingRef.current) && referenceRef.current && !path.includes(referenceRef.current)) {
1414
+ setShowHelp(false);
1415
+ }
1416
+ };
1417
+ document.addEventListener("mousedown", handleClickOutside);
1418
+ return () => {
1419
+ document.removeEventListener("mousedown", handleClickOutside);
1420
+ };
1421
+ }, [floatingRef, referenceRef, setShowHelp]);
1422
+ }
1423
+ function useCloseOnEsc(setShowHelp) {
1424
+ _(() => {
1425
+ const handleKeyDown = (event) => {
1426
+ if (event.key === "Escape") {
1427
+ setShowHelp(false);
1428
+ }
1429
+ };
1430
+ document.addEventListener("keydown", handleKeyDown);
1431
+ return () => {
1432
+ document.removeEventListener("keydown", handleKeyDown);
1433
+ };
1434
+ }, [setShowHelp]);
1435
+ }
1361
1436
  const InfoHeadline1 = ({ children }) => {
1362
1437
  return /* @__PURE__ */ u$1("h1", { className: "text-lg font-bold", children });
1363
1438
  };
@@ -1627,8 +1702,8 @@ const MutationComparison = ({
1627
1702
  height,
1628
1703
  headline = "Mutation comparison"
1629
1704
  }) => {
1630
- const size = { height, width };
1631
- return /* @__PURE__ */ u$1(ErrorBoundary, { size, headline, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(MutationComparisonInner, { variants, sequenceType, views }) }) }) });
1705
+ const size2 = { height, width };
1706
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size: size2, headline, children: /* @__PURE__ */ u$1(ResizeContainer, { size: size2, children: /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(MutationComparisonInner, { variants, sequenceType, views }) }) }) });
1632
1707
  };
1633
1708
  const MutationComparisonInner = ({
1634
1709
  variants,
@@ -1741,7 +1816,7 @@ const Toolbar$3 = ({
1741
1816
  filename: "mutation_comparison.csv"
1742
1817
  }
1743
1818
  ),
1744
- /* @__PURE__ */ u$1(Info, { children: "Info for mutation comparison" })
1819
+ /* @__PURE__ */ u$1(Info, { height: "100px", children: "Info for mutation comparison" })
1745
1820
  ] });
1746
1821
  };
1747
1822
  const gridJsStyle = '.gridjs-head button, .gridjs-footer button {\n cursor: pointer;\n background-color: transparent;\n background-image: none;\n padding: 0;\n margin: 0;\n border: none;\n outline: none;\n}\n\n.gridjs-temp {\n position: relative;\n}\n\n.gridjs-head {\n width: 100%;\n margin-bottom: 5px;\n padding: 5px 1px;\n}\n.gridjs-head::after {\n content: "";\n display: block;\n clear: both;\n}\n.gridjs-head:empty {\n padding: 0;\n border: none;\n}\n\n.gridjs-container {\n overflow: hidden;\n display: inline-block;\n padding: 2px;\n color: #000;\n position: relative;\n z-index: 0;\n}\n\n.gridjs-footer {\n display: block;\n position: relative;\n width: 100%;\n z-index: 5;\n padding: 12px 24px;\n border-top: 1px solid #e5e7eb;\n background-color: #fff;\n box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.26);\n border-radius: 0 0 8px 8px;\n border-bottom-width: 1px;\n border-color: #e5e7eb;\n}\n.gridjs-footer:empty {\n padding: 0;\n border: none;\n}\n\ninput.gridjs-input {\n outline: none;\n background-color: #fff;\n border: 1px solid #d2d6dc;\n border-radius: 5px;\n padding: 10px 13px;\n font-size: 14px;\n line-height: 1.45;\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n}\ninput.gridjs-input:focus {\n box-shadow: 0 0 0 3px rgba(149, 189, 243, 0.5);\n border-color: #9bc2f7;\n}\n\n.gridjs-pagination {\n color: #3d4044;\n}\n.gridjs-pagination::after {\n content: "";\n display: block;\n clear: both;\n}\n.gridjs-pagination .gridjs-summary {\n float: left;\n margin-top: 5px;\n}\n.gridjs-pagination .gridjs-pages {\n float: right;\n}\n.gridjs-pagination .gridjs-pages button {\n padding: 5px 14px;\n border: 1px solid #d2d6dc;\n background-color: #fff;\n border-right: none;\n outline: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none;\n}\n.gridjs-pagination .gridjs-pages button:focus {\n box-shadow: 0 0 0 2px rgba(149, 189, 243, 0.5);\n position: relative;\n margin-right: -1px;\n border-right: 1px solid #d2d6dc;\n}\n.gridjs-pagination .gridjs-pages button:hover {\n background-color: #f7f7f7;\n color: rgb(60, 66, 87);\n outline: none;\n}\n.gridjs-pagination .gridjs-pages button:disabled,\n.gridjs-pagination .gridjs-pages button[disabled],\n.gridjs-pagination .gridjs-pages button:hover:disabled {\n cursor: default;\n background-color: #fff;\n color: #6b7280;\n}\n.gridjs-pagination .gridjs-pages button.gridjs-spread {\n cursor: default;\n box-shadow: none;\n background-color: #fff;\n}\n.gridjs-pagination .gridjs-pages button.gridjs-currentPage {\n background-color: #f7f7f7;\n font-weight: bold;\n}\n.gridjs-pagination .gridjs-pages button:last-child {\n border-bottom-right-radius: 6px;\n border-top-right-radius: 6px;\n border-right: 1px solid #d2d6dc;\n}\n.gridjs-pagination .gridjs-pages button:first-child {\n border-bottom-left-radius: 6px;\n border-top-left-radius: 6px;\n}\n.gridjs-pagination .gridjs-pages button:last-child:focus {\n margin-right: 0;\n}\n\nbutton.gridjs-sort {\n float: right;\n height: 24px;\n width: 13px;\n background-color: transparent;\n background-repeat: no-repeat;\n background-position-x: center;\n cursor: pointer;\n padding: 0;\n margin: 0;\n border: none;\n outline: none;\n background-size: contain;\n}\nbutton.gridjs-sort-neutral {\n opacity: 0.3;\n background-image: url("data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJDYXBhXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHdpZHRoPSI0MDEuOTk4cHgiIGhlaWdodD0iNDAxLjk5OHB4IiB2aWV3Qm94PSIwIDAgNDAxLjk5OCA0MDEuOTk4IiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA0MDEuOTk4IDQwMS45OTg7IgoJIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8Zz4KCTxnPgoJCTxwYXRoIGQ9Ik03My4wOTIsMTY0LjQ1MmgyNTUuODEzYzQuOTQ5LDAsOS4yMzMtMS44MDcsMTIuODQ4LTUuNDI0YzMuNjEzLTMuNjE2LDUuNDI3LTcuODk4LDUuNDI3LTEyLjg0NwoJCQljMC00Ljk0OS0xLjgxMy05LjIyOS01LjQyNy0xMi44NUwyMTMuODQ2LDUuNDI0QzIxMC4yMzIsMS44MTIsMjA1Ljk1MSwwLDIwMC45OTksMHMtOS4yMzMsMS44MTItMTIuODUsNS40MjRMNjAuMjQyLDEzMy4zMzEKCQkJYy0zLjYxNywzLjYxNy01LjQyNCw3LjkwMS01LjQyNCwxMi44NWMwLDQuOTQ4LDEuODA3LDkuMjMxLDUuNDI0LDEyLjg0N0M2My44NjMsMTYyLjY0NSw2OC4xNDQsMTY0LjQ1Miw3My4wOTIsMTY0LjQ1MnoiLz4KCQk8cGF0aCBkPSJNMzI4LjkwNSwyMzcuNTQ5SDczLjA5MmMtNC45NTIsMC05LjIzMywxLjgwOC0xMi44NSw1LjQyMWMtMy42MTcsMy42MTctNS40MjQsNy44OTgtNS40MjQsMTIuODQ3CgkJCWMwLDQuOTQ5LDEuODA3LDkuMjMzLDUuNDI0LDEyLjg0OEwxODguMTQ5LDM5Ni41N2MzLjYyMSwzLjYxNyw3LjkwMiw1LjQyOCwxMi44NSw1LjQyOHM5LjIzMy0xLjgxMSwxMi44NDctNS40MjhsMTI3LjkwNy0xMjcuOTA2CgkJCWMzLjYxMy0zLjYxNCw1LjQyNy03Ljg5OCw1LjQyNy0xMi44NDhjMC00Ljk0OC0xLjgxMy05LjIyOS01LjQyNy0xMi44NDdDMzM4LjEzOSwyMzkuMzUzLDMzMy44NTQsMjM3LjU0OSwzMjguOTA1LDIzNy41NDl6Ii8+Cgk8L2c+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPC9zdmc+");\n background-position-y: center;\n}\nbutton.gridjs-sort-asc {\n background-image: url("data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJDYXBhXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHdpZHRoPSIyOTIuMzYycHgiIGhlaWdodD0iMjkyLjM2MXB4IiB2aWV3Qm94PSIwIDAgMjkyLjM2MiAyOTIuMzYxIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAyOTIuMzYyIDI5Mi4zNjE7IgoJIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8Zz4KCTxwYXRoIGQ9Ik0yODYuOTM1LDE5Ny4yODdMMTU5LjAyOCw2OS4zODFjLTMuNjEzLTMuNjE3LTcuODk1LTUuNDI0LTEyLjg0Ny01LjQyNHMtOS4yMzMsMS44MDctMTIuODUsNS40MjRMNS40MjQsMTk3LjI4NwoJCUMxLjgwNywyMDAuOTA0LDAsMjA1LjE4NiwwLDIxMC4xMzRzMS44MDcsOS4yMzMsNS40MjQsMTIuODQ3YzMuNjIxLDMuNjE3LDcuOTAyLDUuNDI1LDEyLjg1LDUuNDI1aDI1NS44MTMKCQljNC45NDksMCw5LjIzMy0xLjgwOCwxMi44NDgtNS40MjVjMy42MTMtMy42MTMsNS40MjctNy44OTgsNS40MjctMTIuODQ3UzI5MC41NDgsMjAwLjkwNCwyODYuOTM1LDE5Ny4yODd6Ii8+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPC9zdmc+");\n background-position-y: 35%;\n background-size: 10px;\n}\nbutton.gridjs-sort-desc {\n background-image: url("data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJDYXBhXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHdpZHRoPSIyOTIuMzYycHgiIGhlaWdodD0iMjkyLjM2MnB4IiB2aWV3Qm94PSIwIDAgMjkyLjM2MiAyOTIuMzYyIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAyOTIuMzYyIDI5Mi4zNjI7IgoJIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8Zz4KCTxwYXRoIGQ9Ik0yODYuOTM1LDY5LjM3N2MtMy42MTQtMy42MTctNy44OTgtNS40MjQtMTIuODQ4LTUuNDI0SDE4LjI3NGMtNC45NTIsMC05LjIzMywxLjgwNy0xMi44NSw1LjQyNAoJCUMxLjgwNyw3Mi45OTgsMCw3Ny4yNzksMCw4Mi4yMjhjMCw0Ljk0OCwxLjgwNyw5LjIyOSw1LjQyNCwxMi44NDdsMTI3LjkwNywxMjcuOTA3YzMuNjIxLDMuNjE3LDcuOTAyLDUuNDI4LDEyLjg1LDUuNDI4CgkJczkuMjMzLTEuODExLDEyLjg0Ny01LjQyOEwyODYuOTM1LDk1LjA3NGMzLjYxMy0zLjYxNyw1LjQyNy03Ljg5OCw1LjQyNy0xMi44NDdDMjkyLjM2Miw3Ny4yNzksMjkwLjU0OCw3Mi45OTgsMjg2LjkzNSw2OS4zNzd6Ii8+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPGc+CjwvZz4KPC9zdmc+");\n background-position-y: 65%;\n background-size: 10px;\n}\nbutton.gridjs-sort:focus {\n outline: none;\n}\n\ntable.gridjs-table {\n width: 100%;\n max-width: 100%;\n border-collapse: collapse;\n text-align: left;\n display: table;\n margin: 0;\n padding: 0;\n overflow: auto;\n table-layout: fixed;\n}\n\n.gridjs-tbody {\n background-color: #fff;\n}\n\ntd.gridjs-td {\n border: 1px solid #e5e7eb;\n padding: 12px 24px;\n background-color: #fff;\n box-sizing: content-box;\n}\ntd.gridjs-td:first-child {\n border-left: none;\n}\ntd.gridjs-td:last-child {\n border-right: none;\n}\ntd.gridjs-message {\n text-align: center;\n}\n\nth.gridjs-th {\n position: relative;\n color: #6b7280;\n background-color: #f9fafb;\n border: 1px solid #e5e7eb;\n border-top: none;\n padding: 14px 24px;\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none;\n box-sizing: border-box;\n white-space: nowrap;\n outline: none;\n vertical-align: middle;\n}\nth.gridjs-th .gridjs-th-content {\n text-overflow: ellipsis;\n overflow: hidden;\n width: 100%;\n float: left;\n}\nth.gridjs-th-sort {\n cursor: pointer;\n}\nth.gridjs-th-sort .gridjs-th-content {\n width: calc(100% - 15px);\n}\nth.gridjs-th-sort:hover {\n background-color: #e5e7eb;\n}\nth.gridjs-th-sort:focus {\n background-color: #e5e7eb;\n}\nth.gridjs-th-fixed {\n position: sticky;\n box-shadow: 0 1px 0 0 #e5e7eb;\n}\n@supports (-moz-appearance: none) {\n th.gridjs-th-fixed {\n box-shadow: 0 0 0 1px #e5e7eb;\n }\n}\nth.gridjs-th:first-child {\n border-left: none;\n}\nth.gridjs-th:last-child {\n border-right: none;\n}\n\n.gridjs-tr {\n border: none;\n}\n.gridjs-tr-selected td {\n background-color: #ebf5ff;\n}\n.gridjs-tr:last-child td {\n border-bottom: 0;\n}\n\n.gridjs *,\n.gridjs :after,\n.gridjs :before {\n box-sizing: border-box;\n}\n\n.gridjs-wrapper {\n position: relative;\n z-index: 1;\n overflow: auto;\n width: 100%;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.26);\n border-radius: 8px 8px 0 0;\n display: block;\n border-top-width: 1px;\n border-color: #e5e7eb;\n}\n.gridjs-wrapper:nth-last-of-type(2) {\n border-radius: 8px;\n border-bottom-width: 1px;\n}\n\n.gridjs-search {\n float: left;\n}\n.gridjs-search-input {\n width: 250px;\n}\n\n.gridjs-loading-bar {\n z-index: 10;\n position: absolute;\n left: 0;\n right: 0;\n top: 0;\n bottom: 0;\n background-color: #fff;\n opacity: 0.5;\n}\n.gridjs-loading-bar::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n transform: translateX(-100%);\n background-image: linear-gradient(90deg, rgba(204, 204, 204, 0) 0, rgba(204, 204, 204, 0.2) 20%, rgba(204, 204, 204, 0.5) 60%, rgba(204, 204, 204, 0));\n animation: shimmer 2s infinite;\n content: "";\n}\n@keyframes shimmer {\n 100% {\n transform: translateX(100%);\n }\n}\n\n.gridjs-td .gridjs-checkbox {\n display: block;\n margin: auto;\n cursor: pointer;\n}\n\n.gridjs-resizable {\n position: absolute;\n top: 0;\n bottom: 0;\n right: 0;\n width: 5px;\n}\n.gridjs-resizable:hover {\n cursor: ew-resize;\n background-color: #9bc2f7;\n}\n/*# sourceMappingURL=mermaid.css?inline.map */';
@@ -4224,24 +4299,30 @@ input.tab:checked + .tab-content,
4224
4299
  .relative {
4225
4300
  position: relative;
4226
4301
  }
4302
+ .-right-3 {
4303
+ right: -0.75rem;
4304
+ }
4305
+ .-top-3 {
4306
+ top: -0.75rem;
4307
+ }
4227
4308
  .right-2 {
4228
4309
  right: 0.5rem;
4229
4310
  }
4230
- .right-6 {
4231
- right: 1.5rem;
4232
- }
4233
4311
  .top-2 {
4234
4312
  top: 0.5rem;
4235
4313
  }
4236
- .top-8 {
4237
- top: 2rem;
4238
- }
4239
- .z-50 {
4240
- z-index: 50;
4314
+ .z-10 {
4315
+ z-index: 10;
4241
4316
  }
4242
4317
  .z-\\[1\\] {
4243
4318
  z-index: 1;
4244
4319
  }
4320
+ .float-right {
4321
+ float: right;
4322
+ }
4323
+ .m-1 {
4324
+ margin: 0.25rem;
4325
+ }
4245
4326
  .m-2 {
4246
4327
  margin: 0.5rem;
4247
4328
  }
@@ -4257,24 +4338,21 @@ input.tab:checked + .tab-content,
4257
4338
  margin-top: 1rem;
4258
4339
  margin-bottom: 1rem;
4259
4340
  }
4260
- .mb-1 {
4261
- margin-bottom: 0.25rem;
4262
- }
4263
4341
  .mb-2 {
4264
4342
  margin-bottom: 0.5rem;
4265
4343
  }
4266
- .me-1 {
4267
- margin-inline-end: 0.25rem;
4268
- }
4269
4344
  .ml-2 {
4270
4345
  margin-left: 0.5rem;
4271
4346
  }
4272
- .mt-2 {
4273
- margin-top: 0.5rem;
4347
+ .mr-2 {
4348
+ margin-right: 0.5rem;
4274
4349
  }
4275
4350
  .mt-4 {
4276
4351
  margin-top: 1rem;
4277
4352
  }
4353
+ .inline-block {
4354
+ display: inline-block;
4355
+ }
4278
4356
  .inline {
4279
4357
  display: inline;
4280
4358
  }
@@ -4308,13 +4386,6 @@ input.tab:checked + .tab-content,
4308
4386
  .w-full {
4309
4387
  width: 100%;
4310
4388
  }
4311
- .min-w-0 {
4312
- min-width: 0px;
4313
- }
4314
- .min-w-max {
4315
- min-width: -moz-max-content;
4316
- min-width: max-content;
4317
- }
4318
4389
  .max-w-screen-lg {
4319
4390
  max-width: 1024px;
4320
4391
  }
@@ -4333,32 +4404,23 @@ input.tab:checked + .tab-content,
4333
4404
  .flex-wrap {
4334
4405
  flex-wrap: wrap;
4335
4406
  }
4336
- .flex-nowrap {
4337
- flex-wrap: nowrap;
4338
- }
4339
4407
  .items-center {
4340
4408
  align-items: center;
4341
4409
  }
4342
- .justify-end {
4343
- justify-content: flex-end;
4344
- }
4345
4410
  .justify-center {
4346
4411
  justify-content: center;
4347
4412
  }
4348
4413
  .justify-between {
4349
4414
  justify-content: space-between;
4350
4415
  }
4351
- .gap-1 {
4352
- gap: 0.25rem;
4353
- }
4354
4416
  .gap-2 {
4355
4417
  gap: 0.5rem;
4356
4418
  }
4357
4419
  .overflow-auto {
4358
4420
  overflow: auto;
4359
4421
  }
4360
- .overflow-scroll {
4361
- overflow: scroll;
4422
+ .overflow-y-auto {
4423
+ overflow-y: auto;
4362
4424
  }
4363
4425
  .whitespace-nowrap {
4364
4426
  white-space: nowrap;
@@ -4375,8 +4437,8 @@ input.tab:checked + .tab-content,
4375
4437
  .rounded-box {
4376
4438
  border-radius: var(--rounded-box, 1rem);
4377
4439
  }
4378
- .rounded-lg {
4379
- border-radius: 0.5rem;
4440
+ .rounded-full {
4441
+ border-radius: 9999px;
4380
4442
  }
4381
4443
  .rounded-md {
4382
4444
  border-radius: 0.375rem;
@@ -4403,9 +4465,11 @@ input.tab:checked + .tab-content,
4403
4465
  .border-b-2 {
4404
4466
  border-bottom-width: 2px;
4405
4467
  }
4406
- .border-black {
4407
- --tw-border-opacity: 1;
4408
- border-color: rgb(0 0 0 / var(--tw-border-opacity));
4468
+ .border-solid {
4469
+ border-style: solid;
4470
+ }
4471
+ .border-none {
4472
+ border-style: none;
4409
4473
  }
4410
4474
  .border-error {
4411
4475
  --tw-border-opacity: 1;
@@ -4423,6 +4487,10 @@ input.tab:checked + .tab-content,
4423
4487
  --tw-border-opacity: 1;
4424
4488
  border-color: rgb(156 163 175 / var(--tw-border-opacity));
4425
4489
  }
4490
+ .border-red-500 {
4491
+ --tw-border-opacity: 1;
4492
+ border-color: rgb(239 68 68 / var(--tw-border-opacity));
4493
+ }
4426
4494
  .bg-base-100 {
4427
4495
  --tw-bg-opacity: 1;
4428
4496
  background-color: var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity)));
@@ -4435,6 +4503,9 @@ input.tab:checked + .tab-content,
4435
4503
  --tw-bg-opacity: 1;
4436
4504
  background-color: rgb(255 255 255 / var(--tw-bg-opacity));
4437
4505
  }
4506
+ .p-1 {
4507
+ padding: 0.25rem;
4508
+ }
4438
4509
  .p-2 {
4439
4510
  padding: 0.5rem;
4440
4511
  }
@@ -4442,21 +4513,13 @@ input.tab:checked + .tab-content,
4442
4513
  padding-left: 0.5rem;
4443
4514
  padding-right: 0.5rem;
4444
4515
  }
4445
- .px-2\\.5 {
4446
- padding-left: 0.625rem;
4447
- padding-right: 0.625rem;
4448
- }
4449
4516
  .px-4 {
4450
4517
  padding-left: 1rem;
4451
4518
  padding-right: 1rem;
4452
4519
  }
4453
- .py-0 {
4454
- padding-top: 0px;
4455
- padding-bottom: 0px;
4456
- }
4457
- .py-0\\.5 {
4458
- padding-top: 0.125rem;
4459
- padding-bottom: 0.125rem;
4520
+ .py-1 {
4521
+ padding-top: 0.25rem;
4522
+ padding-bottom: 0.25rem;
4460
4523
  }
4461
4524
  .py-16 {
4462
4525
  padding-top: 4rem;
@@ -4517,6 +4580,9 @@ input.tab:checked + .tab-content,
4517
4580
  .underline {
4518
4581
  text-decoration-line: underline;
4519
4582
  }
4583
+ .opacity-90 {
4584
+ opacity: 0.9;
4585
+ }
4520
4586
  .shadow {
4521
4587
  --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
4522
4588
  --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
@@ -4542,10 +4608,18 @@ input.tab:checked + .tab-content,
4542
4608
  .duration-150 {
4543
4609
  transition-duration: 150ms;
4544
4610
  }
4611
+ .focus-within\\:border-gray-400:focus-within {
4612
+ --tw-border-opacity: 1;
4613
+ border-color: rgb(156 163 175 / var(--tw-border-opacity));
4614
+ }
4545
4615
  .hover\\:bg-gray-100:hover {
4546
4616
  --tw-bg-opacity: 1;
4547
4617
  background-color: rgb(243 244 246 / var(--tw-bg-opacity));
4548
4618
  }
4619
+ .hover\\:text-blue-700:hover {
4620
+ --tw-text-opacity: 1;
4621
+ color: rgb(29 78 216 / var(--tw-text-opacity));
4622
+ }
4549
4623
  .hover\\:text-blue-800:hover {
4550
4624
  --tw-text-opacity: 1;
4551
4625
  color: rgb(30 64 175 / var(--tw-text-opacity));
@@ -4557,6 +4631,15 @@ input.tab:checked + .tab-content,
4557
4631
  .hover\\:text-gray-700:hover {
4558
4632
  --tw-text-opacity: 1;
4559
4633
  color: rgb(55 65 81 / var(--tw-text-opacity));
4634
+ }
4635
+ .focus\\:outline-none:focus {
4636
+ outline: 2px solid transparent;
4637
+ outline-offset: 2px;
4638
+ }
4639
+ .focus\\:ring-0:focus {
4640
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
4641
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);
4642
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
4560
4643
  }`;
4561
4644
  var __defProp$9 = Object.defineProperty;
4562
4645
  var __getOwnPropDesc$9 = Object.getOwnPropertyDescriptor;
@@ -4921,8 +5004,8 @@ const Mutations = ({
4921
5004
  height,
4922
5005
  headline = "Mutations"
4923
5006
  }) => {
4924
- const size = { height, width };
4925
- return /* @__PURE__ */ u$1(ErrorBoundary, { size, headline, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(MutationsInner, { variant, sequenceType, views }) }) }) });
5007
+ const size2 = { height, width };
5008
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size: size2, headline, children: /* @__PURE__ */ u$1(ResizeContainer, { size: size2, children: /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(MutationsInner, { variant, sequenceType, views }) }) }) });
4926
5009
  };
4927
5010
  const MutationsInner = ({ variant, sequenceType, views }) => {
4928
5011
  const lapis = P(LapisUrlContext);
@@ -5041,7 +5124,7 @@ const Toolbar$2 = ({
5041
5124
  filename: "insertions.csv"
5042
5125
  }
5043
5126
  ),
5044
- /* @__PURE__ */ u$1(Info, { children: "Info for mutations" })
5127
+ /* @__PURE__ */ u$1(Info, { height: "100px", children: "Info for mutations" })
5045
5128
  ] });
5046
5129
  };
5047
5130
  var __defProp$7 = Object.defineProperty;
@@ -6652,8 +6735,8 @@ const PrevalenceOverTime = ({
6652
6735
  headline = "Prevalence over time",
6653
6736
  lapisDateField
6654
6737
  }) => {
6655
- const size = { height, width };
6656
- return /* @__PURE__ */ u$1(ErrorBoundary, { size, headline, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(
6738
+ const size2 = { height, width };
6739
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size: size2, headline, children: /* @__PURE__ */ u$1(ResizeContainer, { size: size2, children: /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(
6657
6740
  PrevalenceOverTimeInner,
6658
6741
  {
6659
6742
  numerator,
@@ -6794,8 +6877,8 @@ const Toolbar$1 = ({
6794
6877
  /* @__PURE__ */ u$1(PrevalenceOverTimeInfo, {})
6795
6878
  ] });
6796
6879
  };
6797
- const PrevalenceOverTimeInfo = () => {
6798
- return /* @__PURE__ */ u$1(Info, { size: { width: "600px", height: "30vh" }, children: [
6880
+ const PrevalenceOverTimeInfo = ({}) => {
6881
+ return /* @__PURE__ */ u$1(Info, { height: "100px", children: [
6799
6882
  /* @__PURE__ */ u$1(InfoHeadline1, { children: "Prevalence over time" }),
6800
6883
  /* @__PURE__ */ u$1(InfoParagraph, { children: "Prevalence over time info." })
6801
6884
  ] });
@@ -7073,8 +7156,8 @@ const RelativeGrowthAdvantage = ({
7073
7156
  headline = "Relative growth advantage",
7074
7157
  lapisDateField
7075
7158
  }) => {
7076
- const size = { height, width };
7077
- return /* @__PURE__ */ u$1(ErrorBoundary, { size, headline, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(
7159
+ const size2 = { height, width };
7160
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size: size2, headline, children: /* @__PURE__ */ u$1(ResizeContainer, { size: size2, children: /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(
7078
7161
  RelativeGrowthAdvantageInner,
7079
7162
  {
7080
7163
  views,
@@ -7166,7 +7249,7 @@ const RelativeGrowthAdvantageToolbar = ({
7166
7249
  ] });
7167
7250
  };
7168
7251
  const RelativeGrowthAdvantageInfo = ({ generationTime }) => {
7169
- return /* @__PURE__ */ u$1(Info, { size: { width: "600px", height: "30vh" }, children: [
7252
+ return /* @__PURE__ */ u$1(Info, { children: [
7170
7253
  /* @__PURE__ */ u$1(InfoHeadline1, { children: "Relative growth advantage" }),
7171
7254
  /* @__PURE__ */ u$1(InfoParagraph, { children: [
7172
7255
  "If variants spread pre-dominantly by local transmission across demographic groups, this estimate reflects the relative viral intrinsic growth advantage of the focal variant in the selected country and time frame. We report the relative growth advantage per ",
@@ -7291,8 +7374,8 @@ const Aggregate = ({
7291
7374
  filter,
7292
7375
  fields
7293
7376
  }) => {
7294
- const size = { height, width };
7295
- return /* @__PURE__ */ u$1(ErrorBoundary, { size, headline, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(AggregateInner, { fields, filter, views }) }) }) });
7377
+ const size2 = { height, width };
7378
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size: size2, headline, children: /* @__PURE__ */ u$1(ResizeContainer, { size: size2, children: /* @__PURE__ */ u$1(Headline, { heading: headline, children: /* @__PURE__ */ u$1(AggregateInner, { fields, filter, views }) }) }) });
7296
7379
  };
7297
7380
  const AggregateInner = ({ fields, views, filter }) => {
7298
7381
  const lapis = P(LapisUrlContext);
@@ -7326,7 +7409,7 @@ const AggregatedDataTabs = ({ data, views, fields }) => {
7326
7409
  const Toolbar = ({ data }) => {
7327
7410
  return /* @__PURE__ */ u$1("div", { class: "flex flex-row", children: [
7328
7411
  /* @__PURE__ */ u$1(CsvDownloadButton, { className: "mx-1 btn btn-xs", getData: () => data, filename: "aggregate.csv" }),
7329
- /* @__PURE__ */ u$1(Info, { children: "Info for aggregate" })
7412
+ /* @__PURE__ */ u$1(Info, { height: "100px", children: "Info for aggregate" })
7330
7413
  ] });
7331
7414
  };
7332
7415
  var __defProp$4 = Object.defineProperty;
@@ -7385,13 +7468,6 @@ __decorateClass$4([
7385
7468
  AggregateComponent = __decorateClass$4([
7386
7469
  t$2("gs-aggregate")
7387
7470
  ], AggregateComponent);
7388
- const toYYYYMMDD = (date) => {
7389
- if (!date) {
7390
- return void 0;
7391
- }
7392
- const options2 = { year: "numeric", month: "2-digit", day: "2-digit" };
7393
- return date.toLocaleDateString("en-CA", options2);
7394
- };
7395
7471
  const PRESET_VALUE_CUSTOM = "custom";
7396
7472
  const PRESET_VALUE_ALL_TIMES = "allTimes";
7397
7473
  const PRESET_VALUE_LAST_2_WEEKS = "last2Weeks";
@@ -7408,21 +7484,121 @@ const presets = {
7408
7484
  [PRESET_VALUE_LAST_3_MONTHS]: { label: "Last 3 months" },
7409
7485
  [PRESET_VALUE_LAST_6_MONTHS]: { label: "Last 6 months" }
7410
7486
  };
7487
+ const getSelectableOptions = (customSelectOptions) => {
7488
+ const presetOptions = Object.entries(presets).map(([key, value]) => {
7489
+ return { label: value.label, value: key };
7490
+ });
7491
+ const customOptions = customSelectOptions.map((customSelectOption) => {
7492
+ return { label: customSelectOption.label, value: customSelectOption.label };
7493
+ });
7494
+ return [...presetOptions, ...customOptions];
7495
+ };
7496
+ const getDatesForSelectorValue = (selectorValue, customSelectOptions, earliestDate) => {
7497
+ const today = /* @__PURE__ */ new Date();
7498
+ const customSelectOption = customSelectOptions.find((option) => option.label === selectorValue);
7499
+ if (customSelectOption) {
7500
+ return { dateFrom: new Date(customSelectOption.dateFrom), dateTo: new Date(customSelectOption.dateTo) };
7501
+ }
7502
+ switch (selectorValue) {
7503
+ case PRESET_VALUE_LAST_2_WEEKS: {
7504
+ const twoWeeksAgo = new Date(today);
7505
+ twoWeeksAgo.setDate(today.getDate() - 14);
7506
+ return { dateFrom: twoWeeksAgo, dateTo: today };
7507
+ }
7508
+ case PRESET_VALUE_LAST_MONTH: {
7509
+ const lastMonth = new Date(today);
7510
+ lastMonth.setMonth(today.getMonth() - 1);
7511
+ return { dateFrom: lastMonth, dateTo: today };
7512
+ }
7513
+ case PRESET_VALUE_LAST_2_MONTHS: {
7514
+ const twoMonthsAgo = new Date(today);
7515
+ twoMonthsAgo.setMonth(today.getMonth() - 2);
7516
+ return { dateFrom: twoMonthsAgo, dateTo: today };
7517
+ }
7518
+ case PRESET_VALUE_LAST_3_MONTHS: {
7519
+ const threeMonthsAgo = new Date(today);
7520
+ threeMonthsAgo.setMonth(today.getMonth() - 3);
7521
+ return { dateFrom: threeMonthsAgo, dateTo: today };
7522
+ }
7523
+ case PRESET_VALUE_LAST_6_MONTHS: {
7524
+ const sixMonthsAgo = new Date(today);
7525
+ sixMonthsAgo.setMonth(today.getMonth() - 6);
7526
+ return { dateFrom: sixMonthsAgo, dateTo: today };
7527
+ }
7528
+ case PRESET_VALUE_ALL_TIMES: {
7529
+ return { dateFrom: new Date(earliestDate), dateTo: today };
7530
+ }
7531
+ default:
7532
+ return { dateFrom: today, dateTo: today };
7533
+ }
7534
+ };
7535
+ function computeInitialValues(initialValue, initialDateFrom, initialDateTo, earliestDate, customSelectOptions) {
7536
+ if (isUndefinedOrEmpty(initialDateFrom) && isUndefinedOrEmpty(initialDateTo)) {
7537
+ const selectableOptions = getSelectableOptions(customSelectOptions);
7538
+ const initialSelectedDateRange = initialValue !== void 0 && selectableOptions.some((option) => option.value === initialValue) ? initialValue : PRESET_VALUE_LAST_6_MONTHS;
7539
+ const { dateFrom, dateTo } = getDatesForSelectorValue(
7540
+ initialSelectedDateRange,
7541
+ customSelectOptions,
7542
+ earliestDate
7543
+ );
7544
+ return {
7545
+ initialSelectedDateRange,
7546
+ initialSelectedDateFrom: dateFrom,
7547
+ initialSelectedDateTo: dateTo
7548
+ };
7549
+ }
7550
+ const initialSelectedDateFrom = isUndefinedOrEmpty(initialDateFrom) ? new Date(earliestDate) : new Date(initialDateFrom);
7551
+ let initialSelectedDateTo = isUndefinedOrEmpty(initialDateTo) ? /* @__PURE__ */ new Date() : new Date(initialDateTo);
7552
+ if (isNaN(initialSelectedDateFrom.getTime())) {
7553
+ throw new UserFacingError(
7554
+ "Invalid initialDateFrom",
7555
+ `Invalid initialDateFrom "${initialDateFrom}", It must be of the format YYYY-MM-DD`
7556
+ );
7557
+ }
7558
+ if (isNaN(initialSelectedDateTo.getTime())) {
7559
+ throw new UserFacingError(
7560
+ "Invalid initialDateTo",
7561
+ `Invalid initialDateTo "${initialDateTo}", It must be of the format YYYY-MM-DD`
7562
+ );
7563
+ }
7564
+ if (initialSelectedDateFrom > initialSelectedDateTo) {
7565
+ initialSelectedDateTo = initialSelectedDateFrom;
7566
+ }
7567
+ return {
7568
+ initialSelectedDateRange: PRESET_VALUE_CUSTOM,
7569
+ initialSelectedDateFrom,
7570
+ initialSelectedDateTo
7571
+ };
7572
+ }
7573
+ function isUndefinedOrEmpty(value) {
7574
+ return value === void 0 || value === "";
7575
+ }
7576
+ const toYYYYMMDD = (date) => {
7577
+ if (!date) {
7578
+ return void 0;
7579
+ }
7580
+ const options2 = { year: "numeric", month: "2-digit", day: "2-digit" };
7581
+ return date.toLocaleDateString("en-CA", options2);
7582
+ };
7411
7583
  const DateRangeSelector = ({
7412
7584
  customSelectOptions,
7413
7585
  earliestDate = "1900-01-01",
7414
7586
  initialValue,
7415
7587
  width,
7416
- dateColumn
7588
+ dateColumn,
7589
+ initialDateFrom,
7590
+ initialDateTo
7417
7591
  }) => {
7418
- const size = { width, height: "3rem" };
7419
- return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(
7592
+ const size2 = { width, height: "3rem" };
7593
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size: size2, children: /* @__PURE__ */ u$1(ResizeContainer, { size: size2, children: /* @__PURE__ */ u$1(
7420
7594
  DateRangeSelectorInner,
7421
7595
  {
7422
7596
  customSelectOptions,
7423
7597
  earliestDate,
7424
7598
  initialValue,
7425
- dateColumn
7599
+ dateColumn,
7600
+ initialDateFrom,
7601
+ initialDateTo
7426
7602
  }
7427
7603
  ) }) });
7428
7604
  };
@@ -7430,20 +7606,28 @@ const DateRangeSelectorInner = ({
7430
7606
  customSelectOptions,
7431
7607
  earliestDate = "1900-01-01",
7432
7608
  initialValue,
7433
- dateColumn
7609
+ dateColumn,
7610
+ initialDateFrom,
7611
+ initialDateTo
7434
7612
  }) => {
7613
+ const initialValues = computeInitialValues(
7614
+ initialValue,
7615
+ initialDateFrom,
7616
+ initialDateTo,
7617
+ earliestDate,
7618
+ customSelectOptions
7619
+ );
7435
7620
  const fromDatePickerRef = F(null);
7436
7621
  const toDatePickerRef = F(null);
7437
7622
  const divRef = F(null);
7438
7623
  const [dateFromPicker, setDateFromPicker] = p(null);
7439
7624
  const [dateToPicker, setDateToPicker] = p(null);
7440
- const selectableOptions = getSelectableOptions(customSelectOptions);
7441
7625
  const [selectedDateRange, setSelectedDateRange] = p(
7442
- initialValue !== void 0 && selectableOptions.some((option) => option.value === initialValue) ? initialValue : PRESET_VALUE_LAST_6_MONTHS
7626
+ initialValues.initialSelectedDateRange
7443
7627
  );
7444
7628
  const [selectedDates, setSelectedDates] = p({
7445
- dateFrom: getDatesForSelectorValue("last6Months", customSelectOptions, earliestDate).dateFrom,
7446
- dateTo: getDatesForSelectorValue("last6Months", customSelectOptions, earliestDate).dateTo
7629
+ dateFrom: initialValues.initialSelectedDateFrom,
7630
+ dateTo: initialValues.initialSelectedDateTo
7447
7631
  });
7448
7632
  _(() => {
7449
7633
  const commonConfig = {
@@ -7522,7 +7706,7 @@ const DateRangeSelectorInner = ({
7522
7706
  /* @__PURE__ */ u$1(
7523
7707
  Select,
7524
7708
  {
7525
- items: selectableOptions,
7709
+ items: getSelectableOptions(customSelectOptions),
7526
7710
  selected: selectedDateRange,
7527
7711
  selectStyle: "select-bordered rounded-none join-item grow",
7528
7712
  onChange: (event) => {
@@ -7557,54 +7741,6 @@ const DateRangeSelectorInner = ({
7557
7741
  )
7558
7742
  ] });
7559
7743
  };
7560
- const getSelectableOptions = (customSelectOptions) => {
7561
- const presetOptions = Object.entries(presets).map(([key, value]) => {
7562
- return { label: value.label, value: key };
7563
- });
7564
- const customOptions = customSelectOptions.map((customSelectOption) => {
7565
- return { label: customSelectOption.label, value: customSelectOption.label };
7566
- });
7567
- return [...presetOptions, ...customOptions];
7568
- };
7569
- const getDatesForSelectorValue = (selectorValue, customSelectOptions, earliestDate) => {
7570
- const today = /* @__PURE__ */ new Date();
7571
- const customSelectOption = customSelectOptions.find((option) => option.label === selectorValue);
7572
- if (customSelectOption) {
7573
- return { dateFrom: new Date(customSelectOption.dateFrom), dateTo: new Date(customSelectOption.dateTo) };
7574
- }
7575
- switch (selectorValue) {
7576
- case PRESET_VALUE_LAST_2_WEEKS: {
7577
- const twoWeeksAgo = new Date(today);
7578
- twoWeeksAgo.setDate(today.getDate() - 14);
7579
- return { dateFrom: twoWeeksAgo, dateTo: today };
7580
- }
7581
- case PRESET_VALUE_LAST_MONTH: {
7582
- const lastMonth = new Date(today);
7583
- lastMonth.setMonth(today.getMonth() - 1);
7584
- return { dateFrom: lastMonth, dateTo: today };
7585
- }
7586
- case PRESET_VALUE_LAST_2_MONTHS: {
7587
- const twoMonthsAgo = new Date(today);
7588
- twoMonthsAgo.setMonth(today.getMonth() - 2);
7589
- return { dateFrom: twoMonthsAgo, dateTo: today };
7590
- }
7591
- case PRESET_VALUE_LAST_3_MONTHS: {
7592
- const threeMonthsAgo = new Date(today);
7593
- threeMonthsAgo.setMonth(today.getMonth() - 3);
7594
- return { dateFrom: threeMonthsAgo, dateTo: today };
7595
- }
7596
- case PRESET_VALUE_LAST_6_MONTHS: {
7597
- const sixMonthsAgo = new Date(today);
7598
- sixMonthsAgo.setMonth(today.getMonth() - 6);
7599
- return { dateFrom: sixMonthsAgo, dateTo: today };
7600
- }
7601
- case PRESET_VALUE_ALL_TIMES: {
7602
- return { dateFrom: new Date(earliestDate), dateTo: today };
7603
- }
7604
- default:
7605
- return { dateFrom: today, dateTo: today };
7606
- }
7607
- };
7608
7744
  var __defProp$3 = Object.defineProperty;
7609
7745
  var __getOwnPropDesc$3 = Object.getOwnPropertyDescriptor;
7610
7746
  var __decorateClass$3 = (decorators, target, key, kind) => {
@@ -7622,6 +7758,8 @@ let DateRangeSelectorComponent = class extends PreactLitAdapter {
7622
7758
  this.customSelectOptions = [];
7623
7759
  this.earliestDate = "1900-01-01";
7624
7760
  this.initialValue = "last6Months";
7761
+ this.initialDateFrom = "";
7762
+ this.initialDateTo = "";
7625
7763
  this.width = "100%";
7626
7764
  this.dateColumn = "date";
7627
7765
  }
@@ -7632,6 +7770,8 @@ let DateRangeSelectorComponent = class extends PreactLitAdapter {
7632
7770
  customSelectOptions: this.customSelectOptions,
7633
7771
  earliestDate: this.earliestDate,
7634
7772
  initialValue: this.initialValue,
7773
+ initialDateFrom: this.initialDateFrom,
7774
+ initialDateTo: this.initialDateTo,
7635
7775
  dateColumn: this.dateColumn,
7636
7776
  width: this.width
7637
7777
  }
@@ -7647,6 +7787,12 @@ __decorateClass$3([
7647
7787
  __decorateClass$3([
7648
7788
  n2()
7649
7789
  ], DateRangeSelectorComponent.prototype, "initialValue", 2);
7790
+ __decorateClass$3([
7791
+ n2()
7792
+ ], DateRangeSelectorComponent.prototype, "initialDateFrom", 2);
7793
+ __decorateClass$3([
7794
+ n2()
7795
+ ], DateRangeSelectorComponent.prototype, "initialDateTo", 2);
7650
7796
  __decorateClass$3([
7651
7797
  n2({ type: String })
7652
7798
  ], DateRangeSelectorComponent.prototype, "width", 2);
@@ -7700,8 +7846,8 @@ function compareLocationEntries(fields) {
7700
7846
  };
7701
7847
  }
7702
7848
  const LocationFilter = ({ width, initialValue, fields }) => {
7703
- const size = { width, height: "3rem" };
7704
- return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(LocationFilterInner, { initialValue, fields }) }) });
7849
+ const size2 = { width, height: "3rem" };
7850
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size: size2, children: /* @__PURE__ */ u$1(ResizeContainer, { size: size2, children: /* @__PURE__ */ u$1(LocationFilterInner, { initialValue, fields }) }) });
7705
7851
  };
7706
7852
  const LocationFilterInner = ({ initialValue, fields }) => {
7707
7853
  const lapis = P(LapisUrlContext);
@@ -7755,7 +7901,7 @@ const LocationFilterInner = ({ initialValue, fields }) => {
7755
7901
  };
7756
7902
  const parseLocation = (location, fields) => {
7757
7903
  const fieldValues = location.split("/").map((part) => part.trim());
7758
- return fieldValues.reduce((acc, fieldValue, i2) => ({ ...acc, [fields[i2]]: fieldValue }), {});
7904
+ return fields.reduce((acc, field, i2) => ({ ...acc, [field]: fieldValues[i2] }), {});
7759
7905
  };
7760
7906
  const hasMatchingEntry = (data, eventDetail) => {
7761
7907
  if (data === null) {
@@ -7804,8 +7950,8 @@ async function fetchAutocompleteList(lapis, field, signal) {
7804
7950
  return data.map((item) => item[field]);
7805
7951
  }
7806
7952
  const TextInput = ({ width, lapisField, placeholderText, initialValue }) => {
7807
- const size = { width, height: "3rem" };
7808
- return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(TextInputInner, { lapisField, placeholderText, initialValue }) }) });
7953
+ const size2 = { width, height: "3rem" };
7954
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size: size2, children: /* @__PURE__ */ u$1(ResizeContainer, { size: size2, children: /* @__PURE__ */ u$1(TextInputInner, { lapisField, placeholderText, initialValue }) }) });
7809
7955
  };
7810
7956
  const TextInputInner = ({
7811
7957
  lapisField,
@@ -7981,9 +8127,8 @@ const DeleteIcon = () => {
7981
8127
  }
7982
8128
  );
7983
8129
  };
7984
- const MutationFilter = ({ initialValue, width, height }) => {
7985
- const size = { height, width };
7986
- return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(MutationFilterInner, { initialValue }) }) });
8130
+ const MutationFilter = ({ initialValue, width }) => {
8131
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size: { height: "3.375rem", width }, children: /* @__PURE__ */ u$1("div", { style: width, children: /* @__PURE__ */ u$1(MutationFilterInner, { initialValue }) }) });
7987
8132
  };
7988
8133
  const MutationFilterInner = ({ initialValue }) => {
7989
8134
  const referenceGenome = P(ReferenceGenomeContext);
@@ -7995,6 +8140,9 @@ const MutationFilterInner = ({ initialValue }) => {
7995
8140
  const formRef = F(null);
7996
8141
  const handleSubmit = (event) => {
7997
8142
  event.preventDefault();
8143
+ if (inputValue === "") {
8144
+ return;
8145
+ }
7998
8146
  const parsedMutation = parseAndValidateMutation(inputValue, referenceGenome);
7999
8147
  if (parsedMutation === null) {
8000
8148
  setIsError(true);
@@ -8034,8 +8182,9 @@ const MutationFilterInner = ({ initialValue }) => {
8034
8182
  setInputValue(event.target.value);
8035
8183
  setIsError(false);
8036
8184
  };
8037
- return /* @__PURE__ */ u$1("div", { class: `h-full w-full rounded-lg border border-gray-300 bg-white p-2 overflow-scroll`, children: [
8038
- /* @__PURE__ */ u$1("div", { class: "flex justify-between", children: [
8185
+ return /* @__PURE__ */ u$1("form", { className: "w-full border boder-gray-300 rounded-md relative", onSubmit: handleSubmit, ref: formRef, children: [
8186
+ /* @__PURE__ */ u$1("div", { className: "absolute -top-3 -right-3", children: /* @__PURE__ */ u$1(Info, { height: "100px", children: "Info for mutation filter" }) }),
8187
+ /* @__PURE__ */ u$1("div", { className: "w-full flex p-2 flex-wrap items-center", children: [
8039
8188
  /* @__PURE__ */ u$1(
8040
8189
  SelectedMutationDisplay,
8041
8190
  {
@@ -8044,22 +8193,27 @@ const MutationFilterInner = ({ initialValue }) => {
8044
8193
  fireChangeEvent
8045
8194
  }
8046
8195
  ),
8047
- /* @__PURE__ */ u$1(Info, { children: "Info for mutation filter" })
8048
- ] }),
8049
- /* @__PURE__ */ u$1("form", { className: "mt-2 w-full", onSubmit: handleSubmit, ref: formRef, children: /* @__PURE__ */ u$1("label", { className: `input flex items-center gap-2 ${isError ? "input-error" : "input-bordered"}`, children: [
8050
8196
  /* @__PURE__ */ u$1(
8051
- "input",
8197
+ "div",
8052
8198
  {
8053
- className: "grow min-w-0",
8054
- type: "text",
8055
- value: inputValue,
8056
- onInput: handleInputChange,
8057
- placeholder: getPlaceholder(referenceGenome),
8058
- onBlur: handleOnBlur
8199
+ className: `w-full flex border ${isError ? "border-red-500" : "border-gray-300"} border-solid m-2 text-sm focus-within:border-gray-400 `,
8200
+ children: [
8201
+ /* @__PURE__ */ u$1(
8202
+ "input",
8203
+ {
8204
+ className: "grow flex-1 p-1 border-none focus:outline-none focus:ring-0",
8205
+ type: "text",
8206
+ value: inputValue,
8207
+ onInput: handleInputChange,
8208
+ placeholder: getPlaceholder(referenceGenome),
8209
+ onBlur: handleOnBlur
8210
+ }
8211
+ ),
8212
+ /* @__PURE__ */ u$1("button", { type: "submit", className: "btn btn-xs m-1", children: "+" })
8213
+ ]
8059
8214
  }
8060
- ),
8061
- /* @__PURE__ */ u$1("button", { className: "btn btn-sm", children: "+" })
8062
- ] }) })
8215
+ )
8216
+ ] })
8063
8217
  ] });
8064
8218
  };
8065
8219
  function getInitialState(initialValue, referenceGenome) {
@@ -8105,35 +8259,39 @@ const SelectedMutationDisplay = ({ selectedFilters, setSelectedFilters, fireChan
8105
8259
  setSelectedFilters(newSelectedValues);
8106
8260
  fireChangeEvent(newSelectedValues);
8107
8261
  };
8108
- return /* @__PURE__ */ u$1("ul", { class: "flex flex-wrap", children: [
8109
- selectedFilters.nucleotideMutations.map((mutation) => /* @__PURE__ */ u$1("li", { children: /* @__PURE__ */ u$1(
8262
+ return /* @__PURE__ */ u$1(Fragment, { children: [
8263
+ selectedFilters.nucleotideMutations.map((mutation) => /* @__PURE__ */ u$1(
8110
8264
  SelectedNucleotideMutation,
8111
8265
  {
8112
8266
  mutation,
8113
8267
  onDelete: (mutation2) => onSelectedRemoved(mutation2, "nucleotideMutations")
8114
- }
8115
- ) }, mutation.toString())),
8116
- selectedFilters.aminoAcidMutations.map((mutation) => /* @__PURE__ */ u$1("li", { children: /* @__PURE__ */ u$1(
8268
+ },
8269
+ mutation.toString()
8270
+ )),
8271
+ selectedFilters.aminoAcidMutations.map((mutation) => /* @__PURE__ */ u$1(
8117
8272
  SelectedAminoAcidMutation,
8118
8273
  {
8119
8274
  mutation,
8120
8275
  onDelete: (mutation2) => onSelectedRemoved(mutation2, "aminoAcidMutations")
8121
- }
8122
- ) }, mutation.toString())),
8123
- selectedFilters.nucleotideInsertions.map((insertion) => /* @__PURE__ */ u$1("li", { children: /* @__PURE__ */ u$1(
8276
+ },
8277
+ mutation.toString()
8278
+ )),
8279
+ selectedFilters.nucleotideInsertions.map((insertion) => /* @__PURE__ */ u$1(
8124
8280
  SelectedNucleotideInsertion,
8125
8281
  {
8126
8282
  insertion,
8127
8283
  onDelete: (insertion2) => onSelectedRemoved(insertion2, "nucleotideInsertions")
8128
- }
8129
- ) }, insertion.toString())),
8130
- selectedFilters.aminoAcidInsertions.map((insertion) => /* @__PURE__ */ u$1("li", { children: /* @__PURE__ */ u$1(
8284
+ },
8285
+ insertion.toString()
8286
+ )),
8287
+ selectedFilters.aminoAcidInsertions.map((insertion) => /* @__PURE__ */ u$1(
8131
8288
  SelectedAminoAcidInsertion,
8132
8289
  {
8133
8290
  insertion,
8134
8291
  onDelete: (insertion2) => onSelectedRemoved(insertion2, "aminoAcidInsertions")
8135
- }
8136
- ) }, insertion.toString()))
8292
+ },
8293
+ insertion.toString()
8294
+ ))
8137
8295
  ] });
8138
8296
  };
8139
8297
  const SelectedAminoAcidInsertion = ({ insertion, onDelete }) => {
@@ -8195,12 +8353,12 @@ const SelectedFilter = ({
8195
8353
  textColor
8196
8354
  }) => {
8197
8355
  return /* @__PURE__ */ u$1(
8198
- "div",
8356
+ "span",
8199
8357
  {
8200
- class: "flex items-center flex-nowrap gap-1 rounded me-1 px-2.5 py-0.5 font-medium text-xs mb-1 min-w-max",
8358
+ class: "inline-block mx-1 px-2 py-1 font-medium text-xs rounded-full",
8201
8359
  style: { backgroundColor, color: textColor },
8202
8360
  children: [
8203
- /* @__PURE__ */ u$1("div", { className: "whitespace-nowrap min-w-max", children: mutation.toString() }),
8361
+ mutation.toString(),
8204
8362
  /* @__PURE__ */ u$1("button", { type: "button", onClick: () => onDelete(mutation), children: /* @__PURE__ */ u$1(DeleteIcon, {}) })
8205
8363
  ]
8206
8364
  }
@@ -8230,10 +8388,9 @@ let MutationFilterComponent = class extends PreactLitAdapter {
8230
8388
  super(...arguments);
8231
8389
  this.initialValue = void 0;
8232
8390
  this.width = "100%";
8233
- this.height = "6.5rem";
8234
8391
  }
8235
8392
  render() {
8236
- return /* @__PURE__ */ u$1(ReferenceGenomesAwaiter, { children: /* @__PURE__ */ u$1(MutationFilter, { initialValue: this.initialValue, width: this.width, height: this.height }) });
8393
+ return /* @__PURE__ */ u$1(ReferenceGenomesAwaiter, { children: /* @__PURE__ */ u$1(MutationFilter, { initialValue: this.initialValue, width: this.width }) });
8237
8394
  }
8238
8395
  };
8239
8396
  __decorateClass([
@@ -8242,9 +8399,6 @@ __decorateClass([
8242
8399
  __decorateClass([
8243
8400
  n2({ type: String })
8244
8401
  ], MutationFilterComponent.prototype, "width", 2);
8245
- __decorateClass([
8246
- n2({ type: String })
8247
- ], MutationFilterComponent.prototype, "height", 2);
8248
8402
  MutationFilterComponent = __decorateClass([
8249
8403
  t$2("gs-mutation-filter")
8250
8404
  ], MutationFilterComponent);