@gen3/frontend 0.11.12 → 0.11.14

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 (82) hide show
  1. package/dist/cjs/index.js +344 -239
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/dts/components/DropdownWithIcon/DropdownWithIcon.d.ts +16 -10
  4. package/dist/dts/components/DropdownWithIcon/DropdownWithIcon.d.ts.map +1 -1
  5. package/dist/dts/components/DropdownWithIcon/DropdownWithIcon.js +24 -13
  6. package/dist/dts/components/DropdownWithIcon/DropdownWithIcon.js.map +1 -1
  7. package/dist/dts/components/DropdownWithIcon/DropdownWithIcon.unit.test.js +43 -30
  8. package/dist/dts/components/DropdownWithIcon/DropdownWithIcon.unit.test.js.map +1 -1
  9. package/dist/dts/components/Providers/Gen3Provider.d.ts +141 -4
  10. package/dist/dts/components/Providers/Gen3Provider.d.ts.map +1 -1
  11. package/dist/dts/components/charts/Charts.d.ts.map +1 -1
  12. package/dist/dts/components/charts/Charts.js +27 -31
  13. package/dist/dts/components/charts/Charts.js.map +1 -1
  14. package/dist/dts/components/charts/CollapsableCharts.d.ts +2 -2
  15. package/dist/dts/components/charts/CollapsableCharts.d.ts.map +1 -1
  16. package/dist/dts/components/charts/CollapsableCharts.js +2 -2
  17. package/dist/dts/components/charts/CollapsableCharts.js.map +1 -1
  18. package/dist/dts/components/charts/createChart.d.ts.map +1 -1
  19. package/dist/dts/components/charts/createChart.js +7 -12
  20. package/dist/dts/components/charts/createChart.js.map +1 -1
  21. package/dist/dts/components/charts/echarts/HorizontalBarChart.d.ts.map +1 -1
  22. package/dist/dts/components/charts/echarts/HorizontalBarChart.js +7 -4
  23. package/dist/dts/components/charts/echarts/HorizontalBarChart.js.map +1 -1
  24. package/dist/dts/components/facets/EnumFacet.d.ts +1 -1
  25. package/dist/dts/components/facets/EnumFacet.d.ts.map +1 -1
  26. package/dist/dts/components/facets/EnumFacet.js +6 -6
  27. package/dist/dts/components/facets/EnumFacet.js.map +1 -1
  28. package/dist/dts/components/facets/FacetEnumList.d.ts +2 -0
  29. package/dist/dts/components/facets/FacetEnumList.d.ts.map +1 -1
  30. package/dist/dts/components/facets/FacetEnumList.js +24 -18
  31. package/dist/dts/components/facets/FacetEnumList.js.map +1 -1
  32. package/dist/dts/components/facets/createFacetCard.d.ts.map +1 -1
  33. package/dist/dts/components/facets/createFacetCard.js +4 -4
  34. package/dist/dts/components/facets/createFacetCard.js.map +1 -1
  35. package/dist/dts/components/facets/types.d.ts +4 -0
  36. package/dist/dts/components/facets/types.d.ts.map +1 -1
  37. package/dist/dts/components/facets/types.js.map +1 -1
  38. package/dist/dts/components/facets/utils.d.ts.map +1 -1
  39. package/dist/dts/components/facets/utils.js +18 -0
  40. package/dist/dts/components/facets/utils.js.map +1 -1
  41. package/dist/dts/features/Analysis/AnalysisCard.d.ts.map +1 -1
  42. package/dist/dts/features/Analysis/AnalysisCard.js +1 -1
  43. package/dist/dts/features/Analysis/AnalysisCard.js.map +1 -1
  44. package/dist/dts/features/Analysis/AnalysisCard.stories.d.ts.map +1 -1
  45. package/dist/dts/features/Analysis/AnalysisCardCompact.stories.d.ts +14 -14
  46. package/dist/dts/features/Analysis/AnalysisCardCompact.stories.d.ts.map +1 -1
  47. package/dist/dts/features/Analysis/TextDescription.d.ts.map +1 -1
  48. package/dist/dts/features/Analysis/TextDescription.js +3 -19
  49. package/dist/dts/features/Analysis/TextDescription.js.map +1 -1
  50. package/dist/dts/features/CohortBuilder/CohortBuilder.d.ts.map +1 -1
  51. package/dist/dts/features/CohortBuilder/CohortBuilder.js +3 -13
  52. package/dist/dts/features/CohortBuilder/CohortBuilder.js.map +1 -1
  53. package/dist/dts/features/CohortBuilder/CohortPanel.d.ts.map +1 -1
  54. package/dist/dts/features/CohortBuilder/CohortPanel.js +28 -21
  55. package/dist/dts/features/CohortBuilder/CohortPanel.js.map +1 -1
  56. package/dist/dts/features/CohortDiscovery/registerApp.js +1 -1
  57. package/dist/dts/features/CohortDiscovery/registerApp.js.map +1 -1
  58. package/dist/dts/features/CohortSimilarity/cohortSimilarityApi.d.ts +10 -10
  59. package/dist/dts/features/Discovery/DataLoaders/MDSAllLocal/DataLoader.d.ts.map +1 -1
  60. package/dist/dts/features/Discovery/DataLoaders/MDSAllLocal/DataLoader.js +1 -0
  61. package/dist/dts/features/Discovery/DataLoaders/MDSAllLocal/DataLoader.js.map +1 -1
  62. package/dist/dts/features/Discovery/DiscoveryIndexPanel.d.ts.map +1 -1
  63. package/dist/dts/features/Discovery/DiscoveryIndexPanel.js +1 -1
  64. package/dist/dts/features/Discovery/DiscoveryIndexPanel.js.map +1 -1
  65. package/dist/dts/features/Discovery/DiscoveryTable.d.ts.map +1 -1
  66. package/dist/dts/features/Discovery/DiscoveryTable.js +30 -5
  67. package/dist/dts/features/Discovery/DiscoveryTable.js.map +1 -1
  68. package/dist/dts/features/Discovery/TableRenderers/CellRenderers.d.ts +1 -0
  69. package/dist/dts/features/Discovery/TableRenderers/CellRenderers.d.ts.map +1 -1
  70. package/dist/dts/features/Discovery/TableRenderers/CellRenderers.js +10 -0
  71. package/dist/dts/features/Discovery/TableRenderers/CellRenderers.js.map +1 -1
  72. package/dist/dts/features/Discovery/types.d.ts +7 -0
  73. package/dist/dts/features/Discovery/types.d.ts.map +1 -1
  74. package/dist/dts/features/Discovery/types.js.map +1 -1
  75. package/dist/dts/features/Navigation/NavigationBar.d.ts.map +1 -1
  76. package/dist/dts/features/Navigation/NavigationBar.js +3 -2
  77. package/dist/dts/features/Navigation/NavigationBar.js.map +1 -1
  78. package/dist/esm/index.js +345 -240
  79. package/dist/esm/index.js.map +1 -1
  80. package/dist/index.d.ts +170 -17
  81. package/dist/tsconfig.tsbuildinfo +1 -1
  82. package/package.json +3 -3
package/dist/cjs/index.js CHANGED
@@ -1480,7 +1480,7 @@ function hashCode(str) {
1480
1480
  dangerouslySetInnerHTML: {
1481
1481
  __html: textString
1482
1482
  },
1483
- "aria-label": "HTML content" // Provide context for HTML rendered content
1483
+ "aria-label": "HTML content"
1484
1484
  });
1485
1485
  }
1486
1486
  case "textArray":
@@ -1620,7 +1620,7 @@ function hashCode(str) {
1620
1620
  * @param {string} paramValue - The parameter value
1621
1621
  * @returns {string} - The URL with the added parameter
1622
1622
  */ const appendParameterToUrl = (url, paramName, paramValue)=>{
1623
- if (!url || false) {
1623
+ if (!url || !paramName) {
1624
1624
  return url;
1625
1625
  }
1626
1626
  // Extract hash fragment if present
@@ -1956,8 +1956,7 @@ const saveToFile = (savingStr, filename = 'credentials.json')=>{
1956
1956
  children: [
1957
1957
  credentials.api_key === '' && /*#__PURE__*/ jsxRuntime.jsx(core$1.LoadingOverlay, {
1958
1958
  visible: true
1959
- }) // pragma: allowlist-secret;
1960
- ,
1959
+ }),
1961
1960
  /*#__PURE__*/ jsxRuntime.jsx("p", {
1962
1961
  children: "This key is only shown once. Please copy or save it and store it in a safe place."
1963
1962
  }),
@@ -2514,7 +2513,7 @@ const processChartData$2 = (facetData, valueType = 'count', total, maxBins = 100
2514
2513
  };
2515
2514
  const HorizontalBarChart = ({ data, valueType, total, showLegendInChart = true })=>{
2516
2515
  const chartData = processChartData$2(data, valueType, total);
2517
- const chartDefinition = React.useMemo(()=>{
2516
+ const chartDefinition = useDeepCompare.useDeepCompareMemo(()=>{
2518
2517
  return {
2519
2518
  tooltip: {
2520
2519
  trigger: 'item',
@@ -2556,12 +2555,17 @@ const HorizontalBarChart = ({ data, valueType, total, showLegendInChart = true }
2556
2555
  series: chartData
2557
2556
  };
2558
2557
  }, [
2559
- chartData
2558
+ chartData,
2559
+ showLegendInChart
2560
2560
  ]);
2561
2561
  return /*#__PURE__*/ jsxRuntime.jsx("div", {
2562
2562
  className: "w-full h-64",
2563
2563
  children: /*#__PURE__*/ jsxRuntime.jsx(ReactECharts, {
2564
- option: chartDefinition
2564
+ option: chartDefinition,
2565
+ settings: {
2566
+ notMerge: true,
2567
+ lazyUpdate: false
2568
+ }
2565
2569
  })
2566
2570
  });
2567
2571
  };
@@ -2589,7 +2593,11 @@ const ChartRendererFactory = ()=>{
2589
2593
  // TODO: add default chart chart for missing chart type
2590
2594
  const element = ChartRendererFactory().getRenderer('chart', type);
2591
2595
  return element({
2592
- ...chartProps
2596
+ total: chartProps.total,
2597
+ valueType: chartProps.valueType,
2598
+ label: chartProps.label,
2599
+ data: chartProps.data,
2600
+ showLegendInChart: chartProps.showLegendInChart
2593
2601
  }, parameters);
2594
2602
  };
2595
2603
 
@@ -2607,6 +2615,106 @@ const chartColors = [
2607
2615
  '#9a60b4',
2608
2616
  '#ea7ccc'
2609
2617
  ];
2618
+ const LegendRows = ({ data })=>{
2619
+ const moreThanMaxRows = data.length > MAX_LEGEND_ROWS;
2620
+ const limitedRows = moreThanMaxRows ? data.slice(0, MAX_LEGEND_ROWS) : data;
2621
+ return limitedRows.map((element, elIndex)=>/*#__PURE__*/ jsxRuntime.jsxs(core$1.Table.Tr, {
2622
+ children: [
2623
+ /*#__PURE__*/ jsxRuntime.jsxs(core$1.Table.Td, {
2624
+ children: [
2625
+ /*#__PURE__*/ jsxRuntime.jsx(core$1.ColorSwatch, {
2626
+ className: "inline-block mr-2 align-middle",
2627
+ size: "1em",
2628
+ radius: "xs",
2629
+ color: chartColors?.[elIndex % chartColors.length] || ''
2630
+ }),
2631
+ element.key
2632
+ ]
2633
+ }),
2634
+ /*#__PURE__*/ jsxRuntime.jsx(core$1.Table.Td, {
2635
+ className: "text-right",
2636
+ children: element.count
2637
+ })
2638
+ ]
2639
+ }, elIndex));
2640
+ };
2641
+ const LegendOverflow = ({ chart, data, chartTitle, counts })=>{
2642
+ const [openedMoreRows, { open: openMoreRows, close: closeMoreRows }] = hooks.useDisclosure(false);
2643
+ const theme = core$1.useMantineTheme();
2644
+ return /*#__PURE__*/ jsxRuntime.jsxs(React.Fragment, {
2645
+ children: [
2646
+ /*#__PURE__*/ jsxRuntime.jsx(core$1.Modal, {
2647
+ opened: openedMoreRows,
2648
+ onClose: closeMoreRows,
2649
+ title: chartTitle,
2650
+ size: "xl",
2651
+ children: /*#__PURE__*/ jsxRuntime.jsxs(core$1.Grid, {
2652
+ children: [
2653
+ /*#__PURE__*/ jsxRuntime.jsx(core$1.Grid.Col, {
2654
+ span: 6,
2655
+ children: createChart(chart.chartType, {
2656
+ data: data === undefined ? [] : data,
2657
+ total: counts ?? 1,
2658
+ valueType: chart.valueType ?? 'count',
2659
+ label: chart.label,
2660
+ showLegendInChart: chart.showLegendInChart
2661
+ })
2662
+ }, "modal-col-1"),
2663
+ /*#__PURE__*/ jsxRuntime.jsx(core$1.Grid.Col, {
2664
+ span: 6,
2665
+ children: /*#__PURE__*/ jsxRuntime.jsx("div", {
2666
+ className: "border-solid border-[1px] border-[var(--mantine-color-gray-3)] h-full p-1",
2667
+ children: /*#__PURE__*/ jsxRuntime.jsx(core$1.Table, {
2668
+ withRowBorders: false,
2669
+ classNames: {
2670
+ table: '',
2671
+ td: 'p-1 leading-3'
2672
+ },
2673
+ children: /*#__PURE__*/ jsxRuntime.jsx(core$1.Table.Tbody, {
2674
+ children: data.map((element, elIndex)=>/*#__PURE__*/ jsxRuntime.jsxs(core$1.Table.Tr, {
2675
+ children: [
2676
+ /*#__PURE__*/ jsxRuntime.jsxs(core$1.Table.Td, {
2677
+ children: [
2678
+ /*#__PURE__*/ jsxRuntime.jsx(core$1.ColorSwatch, {
2679
+ className: "inline-block mr-2 align-middle",
2680
+ size: "1em",
2681
+ radius: "xs",
2682
+ color: chartColors?.[elIndex % chartColors.length] || ''
2683
+ }),
2684
+ element.key
2685
+ ]
2686
+ }),
2687
+ /*#__PURE__*/ jsxRuntime.jsx(core$1.Table.Td, {
2688
+ className: "text-right",
2689
+ children: element.count
2690
+ })
2691
+ ]
2692
+ }, elIndex))
2693
+ })
2694
+ })
2695
+ })
2696
+ }, "modal-col-2")
2697
+ ]
2698
+ })
2699
+ }),
2700
+ /*#__PURE__*/ jsxRuntime.jsxs(core$1.Button, {
2701
+ variant: "subtle",
2702
+ onClick: openMoreRows,
2703
+ leftSection: /*#__PURE__*/ jsxRuntime.jsx(react.Icon, {
2704
+ icon: "gen3:open-in-modal",
2705
+ height: 24,
2706
+ width: 24,
2707
+ color: theme.colors.accent[5]
2708
+ }),
2709
+ className: "text-black hover:text-black",
2710
+ children: [
2711
+ data.length - MAX_LEGEND_ROWS,
2712
+ " more"
2713
+ ]
2714
+ })
2715
+ ]
2716
+ });
2717
+ };
2610
2718
  //The Charts component maps the data from ChartsProps into a grid of createChart() ReactNodes
2611
2719
  const Charts = ({ charts, data, counts, isSuccess, numCols = DEFAULT_COLS, style = 'tile', showLegends = false })=>{
2612
2720
  const spans = computeRowSpan(Object.keys(charts).length, numCols);
@@ -2617,109 +2725,10 @@ const Charts = ({ charts, data, counts, isSuccess, numCols = DEFAULT_COLS, style
2617
2725
  message: `${field} not found in data`
2618
2726
  });
2619
2727
  }
2620
- const LegendRows = ({ data })=>{
2621
- const moreThanMaxRows = data.length > MAX_LEGEND_ROWS;
2622
- const limitedRows = moreThanMaxRows ? data.slice(0, MAX_LEGEND_ROWS) : data;
2623
- return limitedRows.map((element, elIndex)=>/*#__PURE__*/ jsxRuntime.jsxs(core$1.Table.Tr, {
2624
- children: [
2625
- /*#__PURE__*/ jsxRuntime.jsxs(core$1.Table.Td, {
2626
- children: [
2627
- /*#__PURE__*/ jsxRuntime.jsx(core$1.ColorSwatch, {
2628
- className: "inline-block mr-2 align-middle",
2629
- size: "1em",
2630
- radius: "xs",
2631
- color: chartColors?.[elIndex % chartColors.length] || ''
2632
- }),
2633
- element.key
2634
- ]
2635
- }),
2636
- /*#__PURE__*/ jsxRuntime.jsx(core$1.Table.Td, {
2637
- className: "text-right",
2638
- children: element.count
2639
- })
2640
- ]
2641
- }, elIndex));
2642
- };
2643
- const LegendOverflow = ({ chart, data, chartTitle })=>{
2644
- const [openedMoreRows, { open: openMoreRows, close: closeMoreRows }] = hooks.useDisclosure(false);
2645
- const theme = core$1.useMantineTheme();
2646
- return /*#__PURE__*/ jsxRuntime.jsxs(React.Fragment, {
2647
- children: [
2648
- /*#__PURE__*/ jsxRuntime.jsx(core$1.Modal, {
2649
- opened: openedMoreRows,
2650
- onClose: closeMoreRows,
2651
- title: chartTitle,
2652
- size: "xl",
2653
- children: /*#__PURE__*/ jsxRuntime.jsxs(core$1.Grid, {
2654
- children: [
2655
- /*#__PURE__*/ jsxRuntime.jsx(core$1.Grid.Col, {
2656
- span: 6,
2657
- children: createChart(chart.chartType, {
2658
- data: data === undefined ? [] : data,
2659
- total: counts ?? 1,
2660
- valueType: chart.valueType ?? 'count',
2661
- label: chart.label,
2662
- showLegendInChart: chart.showLegendInChart
2663
- })
2664
- }, "modal-col-1"),
2665
- /*#__PURE__*/ jsxRuntime.jsx(core$1.Grid.Col, {
2666
- span: 6,
2667
- children: /*#__PURE__*/ jsxRuntime.jsx("div", {
2668
- className: "border-solid border-[1px] border-[var(--mantine-color-gray-3)] h-full p-1",
2669
- children: /*#__PURE__*/ jsxRuntime.jsx(core$1.Table, {
2670
- withRowBorders: false,
2671
- classNames: {
2672
- table: '',
2673
- td: 'p-1 leading-3'
2674
- },
2675
- children: /*#__PURE__*/ jsxRuntime.jsx(core$1.Table.Tbody, {
2676
- children: data.map((element, elIndex)=>/*#__PURE__*/ jsxRuntime.jsxs(core$1.Table.Tr, {
2677
- children: [
2678
- /*#__PURE__*/ jsxRuntime.jsxs(core$1.Table.Td, {
2679
- children: [
2680
- /*#__PURE__*/ jsxRuntime.jsx(core$1.ColorSwatch, {
2681
- className: "inline-block mr-2 align-middle",
2682
- size: "1em",
2683
- radius: "xs",
2684
- color: chartColors?.[elIndex % chartColors.length] || ''
2685
- }),
2686
- element.key
2687
- ]
2688
- }),
2689
- /*#__PURE__*/ jsxRuntime.jsx(core$1.Table.Td, {
2690
- className: "text-right",
2691
- children: element.count
2692
- })
2693
- ]
2694
- }, elIndex))
2695
- })
2696
- })
2697
- })
2698
- }, "modal-col-2")
2699
- ]
2700
- })
2701
- }),
2702
- /*#__PURE__*/ jsxRuntime.jsxs(core$1.Button, {
2703
- variant: "subtle",
2704
- onClick: openMoreRows,
2705
- leftSection: /*#__PURE__*/ jsxRuntime.jsx(react.Icon, {
2706
- icon: "gen3:open-in-modal",
2707
- height: 24,
2708
- width: 24,
2709
- color: theme.colors.accent[5]
2710
- }),
2711
- className: "text-black hover:text-black",
2712
- children: [
2713
- data.length - MAX_LEGEND_ROWS,
2714
- " more"
2715
- ]
2716
- })
2717
- ]
2718
- });
2719
- };
2720
2728
  const dataKeys = field in data && data?.[field].length > 0 ? Object.keys(data[field][0]) : [];
2721
2729
  const chartTitle = charts[field].title ?? core.fieldNameToTitle(field);
2722
- const moreThanMaxRows = data?.[field] && data[field].length > MAX_LEGEND_ROWS;
2730
+ const numberOfDataItems = data?.[field] && data[field].length;
2731
+ const moreThanMaxRows = numberOfDataItems > MAX_LEGEND_ROWS;
2723
2732
  return /*#__PURE__*/ jsxRuntime.jsx(core$1.Grid.Col, {
2724
2733
  span: spans[indexNum],
2725
2734
  children: /*#__PURE__*/ jsxRuntime.jsxs(core$1.Card, {
@@ -2750,7 +2759,7 @@ const Charts = ({ charts, data, counts, isSuccess, numCols = DEFAULT_COLS, style
2750
2759
  label: charts[field].label,
2751
2760
  showLegendInChart: charts[field].showLegendInChart
2752
2761
  }),
2753
- showLegends && /*#__PURE__*/ jsxRuntime.jsx(core$1.Card.Section, {
2762
+ numberOfDataItems > 0 && showLegends && /*#__PURE__*/ jsxRuntime.jsx(core$1.Card.Section, {
2754
2763
  inheritPadding: true,
2755
2764
  py: "xs",
2756
2765
  withBorder: style === 'box',
@@ -2788,7 +2797,8 @@ const Charts = ({ charts, data, counts, isSuccess, numCols = DEFAULT_COLS, style
2788
2797
  children: /*#__PURE__*/ jsxRuntime.jsx(LegendOverflow, {
2789
2798
  chart: charts[field],
2790
2799
  data: data[field],
2791
- chartTitle: chartTitle
2800
+ chartTitle: chartTitle,
2801
+ counts: counts ?? 0
2792
2802
  })
2793
2803
  })
2794
2804
  ]
@@ -2801,7 +2811,7 @@ const Charts = ({ charts, data, counts, isSuccess, numCols = DEFAULT_COLS, style
2801
2811
  });
2802
2812
  };
2803
2813
 
2804
- const CollapsableCharts = ({ config, data })=>{
2814
+ const CollapsableCharts = ({ config, data, isError, isFetching, isSuccess })=>{
2805
2815
  const [showLegends, setShowLegends] = React.useState(config.showLegends?.enabled);
2806
2816
  if (!(config?.charts && Object.keys(config.charts).length > 0)) {
2807
2817
  return /*#__PURE__*/ jsxRuntime.jsx(core$1.Center, {
@@ -2853,7 +2863,7 @@ const CollapsableCharts = ({ config, data })=>{
2853
2863
  charts: config.charts,
2854
2864
  data: data,
2855
2865
  counts: 2,
2856
- isSuccess: true,
2866
+ isSuccess: isSuccess,
2857
2867
  numCols: 4
2858
2868
  })
2859
2869
  })
@@ -3165,6 +3175,8 @@ const classifyFacets = (data, index, fieldMapping = [], facetDefinitionsFromConf
3165
3175
  label: facetDef.label ?? facetName,
3166
3176
  // assumption is that the initial data has the min and max values
3167
3177
  sharedWithIndices: (sharedFieldMapping && fieldKey in sharedFieldMapping && sharedFieldMapping[fieldKey].filter((x)=>x.index !== index)) ?? undefined,
3178
+ moveValuesToBottom: facetDef?.moveValuesToBottom,
3179
+ excludeValues: facetDef?.excludeValues,
3168
3180
  range: facetDef.range ?? type === 'range' ? {
3169
3181
  minimum: Math.floor(Number(value[0].key[0])),
3170
3182
  maximum: Math.ceil(Number(value[0].key[1]))
@@ -3343,6 +3355,22 @@ const convertToStringArray = (inputArray)=>inputArray.map(String);
3343
3355
  * @param {FacetSortType} facetSort - The facet sort type represented as a string in the format "type-direction".
3344
3356
  * @returns {SortType} - The mapped sort type object containing type and direction.
3345
3357
  */ const mapFacetSortToSortType = (facetSort)=>{
3358
+ // Default fallback values
3359
+ const defaultSort = {
3360
+ type: 'value',
3361
+ direction: 'dsc'
3362
+ };
3363
+ // Validate input
3364
+ if (!facetSort) {
3365
+ console.warn(`Invalid facetSort: expected string, got ${typeof facetSort}. Using default.`);
3366
+ return defaultSort;
3367
+ }
3368
+ const parts = facetSort.split('-');
3369
+ // Check if we have exactly 2 parts
3370
+ if (parts.length !== 2) {
3371
+ console.warn(`Invalid facetSort format: expected 'type-direction', got '${facetSort}'. Using default.`);
3372
+ return defaultSort;
3373
+ }
3346
3374
  const [type, direction] = facetSort.split('-');
3347
3375
  return {
3348
3376
  type: type === 'label' ? 'alpha' : 'value',
@@ -3820,7 +3848,7 @@ const OverflowTooltippedLabel = ({ children, label, className = 'flex-grow font-
3820
3848
  });
3821
3849
  };
3822
3850
 
3823
- const FacetEnumList = ({ field, facetName, hooks, valueLabel, isSettings = false, isFacetView = true, isSearching = false, showPercent = false, hideIfEmpty = false, showSorting = true, sort = 'value-dsc' })=>{
3851
+ const FacetEnumList = ({ field, facetName, hooks, valueLabel, isSettings = false, isFacetView = true, isSearching = false, showPercent = false, hideIfEmpty = false, showSorting = true, sort = 'value-dsc', moveValuesToBottom = [], excludeValues = [] })=>{
3824
3852
  const [isGroupExpanded, setIsGroupExpanded] = React.useState(false);
3825
3853
  const cardRef = React.useRef(null);
3826
3854
  const searchInputRef = React.useRef(null);
@@ -3877,7 +3905,7 @@ const FacetEnumList = ({ field, facetName, hooks, valueLabel, isSettings = false
3877
3905
  ];
3878
3906
  updateFacetEnum(field, updated, updateFacetFilters, clearFilters, combineMode);
3879
3907
  } else {
3880
- const updated = selectedEnums?.filter((x)=>x != value);
3908
+ const updated = selectedEnums?.filter((x)=>x !== value);
3881
3909
  updateFacetEnum(field, updated ?? [], updateFacetFilters, clearFilters, combineMode);
3882
3910
  }
3883
3911
  };
@@ -3914,7 +3942,7 @@ const FacetEnumList = ({ field, facetName, hooks, valueLabel, isSettings = false
3914
3942
  useDeepCompare.useDeepCompareEffect(()=>{
3915
3943
  if (isSuccess && data) {
3916
3944
  // get all the data except the missing and empty values
3917
- const tempFilteredData = Object.entries(data).filter((entry)=>entry[0] != '_missing' && entry[0] != '').filter((entry)=>searchTerm === '' ? entry : entry[0].toLowerCase().includes(searchTerm.toLowerCase().trim()));
3945
+ const tempFilteredData = Object.entries(data).filter((entry)=>entry[0] !== '_missing' && entry[0] !== '').filter((entry)=>searchTerm === '' ? entry : entry[0].toLowerCase().includes(searchTerm.toLowerCase().trim()));
3918
3946
  // it is possible that the selected enums are not in the data as their counts are 0
3919
3947
  // therefore we need to add them to the data
3920
3948
  const selectedEnumNotInData = selectedEnums ? selectedEnums.reduce((acc, curr)=>{
@@ -3929,16 +3957,16 @@ const FacetEnumList = ({ field, facetName, hooks, valueLabel, isSettings = false
3929
3957
  const remainingValues = tempFilteredData.length + selectedEnumNotInData.length - maxValuesToDisplay;
3930
3958
  const cardStyle = calcCardStyle(remainingValues);
3931
3959
  const numberOfBarsToDisplay = calcNumberOfBarsToDisplay(tempFilteredData.length + selectedEnumNotInData.length);
3960
+ const allData = [
3961
+ ...tempFilteredData,
3962
+ ...selectedEnumNotInData
3963
+ ];
3964
+ // remove any enum in excludeValues
3965
+ const filteredData = allData.filter((x)=>!excludeValues?.includes(x[0].toString()));
3932
3966
  setFacetChartData((prevFacetChartData)=>({
3933
3967
  ...prevFacetChartData,
3934
- filteredData: [
3935
- ...tempFilteredData,
3936
- ...selectedEnumNotInData
3937
- ],
3938
- filteredDataObj: Object.fromEntries([
3939
- ...tempFilteredData,
3940
- ...selectedEnumNotInData
3941
- ]),
3968
+ filteredData: filteredData,
3969
+ filteredDataObj: Object.fromEntries(filteredData),
3942
3970
  remainingValues,
3943
3971
  numberOfBarsToDisplay,
3944
3972
  isSuccess: true,
@@ -3964,8 +3992,9 @@ const FacetEnumList = ({ field, facetName, hooks, valueLabel, isSettings = false
3964
3992
  useDeepCompare.useDeepCompareEffect(()=>{
3965
3993
  if (facetChartData.filteredData && facetChartData.filteredData.length > 0) {
3966
3994
  const obj = [
3967
- ...facetChartData.filteredData
3968
- ].sort(sortType.type === 'value' ? ([, a], [, b])=>sortType.direction === 'dsc' ? b - a : a - b : ([a], [b])=>sortType.direction === 'dsc' ? compareKeysDescending(a, b) : compareKeysAscending(a, b)).slice(0, !isGroupExpanded ? maxValuesToDisplay : undefined);
3995
+ ...facetChartData.filteredData.filter((x)=>!moveValuesToBottom.includes(x[0].toString())).sort(sortType.type === 'value' ? ([, a], [, b])=>sortType.direction === 'dsc' ? b - a : a - b : ([a], [b])=>sortType.direction === 'dsc' ? compareKeysDescending(a, b) : compareKeysAscending(a, b)),
3996
+ ...facetChartData.filteredData.filter((x)=>moveValuesToBottom.includes(x[0].toString()))
3997
+ ].slice(0, !isGroupExpanded ? maxValuesToDisplay : undefined);
3969
3998
  setSortedData(obj);
3970
3999
  if (updateVisibleValues) updateVisibleValues(obj);
3971
4000
  }
@@ -4178,7 +4207,7 @@ const FacetEnumList = ({ field, facetName, hooks, valueLabel, isSettings = false
4178
4207
  });
4179
4208
  };
4180
4209
 
4181
- const EnumFacet = ({ field, hooks, valueLabel, description, facetName, showPercent = true, hideIfEmpty = true, showSearch = true, showFlip = false, showSettings = false, startShowingData = true, dismissCallback = undefined, width = undefined, sharedWithIndices = undefined, header = {
4210
+ const EnumFacet = ({ field, hooks, valueLabel, description, facetName, showPercent = true, hideIfEmpty = true, showSearch = true, showFlip = false, showSettings = false, startShowingData = true, dismissCallback = undefined, width = undefined, sharedWithIndices = undefined, moveValuesToBottom = [], excludeValues = [], header = {
4182
4211
  Panel: FacetHeader,
4183
4212
  Label: FacetText,
4184
4213
  iconStyle: controlsIconStyle
@@ -4229,7 +4258,9 @@ const EnumFacet = ({ field, hooks, valueLabel, description, facetName, showPerce
4229
4258
  isFacetView: isFacetView,
4230
4259
  isSearching: isSearching,
4231
4260
  hideIfEmpty: hideIfEmpty,
4232
- showPercent: showPercent
4261
+ showPercent: showPercent,
4262
+ moveValuesToBottom: moveValuesToBottom,
4263
+ excludeValues: excludeValues
4233
4264
  })
4234
4265
  })
4235
4266
  ]
@@ -4628,7 +4659,9 @@ const createFacetCard = ({ facetDefinition, valueLabel, hooks: dataFunctions, fa
4628
4659
  width: width,
4629
4660
  hooks: dataFunctions,
4630
4661
  showPercent: showPercent,
4631
- sharedWithIndices: facetDefinition?.sharedWithIndices
4662
+ sharedWithIndices: facetDefinition?.sharedWithIndices,
4663
+ moveValuesToBottom: facetDefinition?.moveValuesToBottom ?? [],
4664
+ excludeValues: facetDefinition?.excludeValues ?? []
4632
4665
  }, `${idPrefix}-enum-${field}`),
4633
4666
  range: /*#__PURE__*/ jsxRuntime.jsx(RangeFacet, {
4634
4667
  valueLabel: valueTypeLabel,
@@ -6168,6 +6201,7 @@ const NavigationLogo = ({ src, title, description, width, height, divider = fals
6168
6201
  root: 'flex bg-base-max border-b-1 border-base-dark',
6169
6202
  navigationPanel: 'font-heading',
6170
6203
  logoAndTitlePanel: 'flex justify-center items-center align-middle',
6204
+ buttons: '',
6171
6205
  login: 'pl-1 mr-6 bg-base-max text-base-contrast opacity-80 hover:opacity-100'
6172
6206
  };
6173
6207
  const mergedClassnames = mergeDefaultTailwindClassnames(classNamesDefaults, classNames);
@@ -6193,11 +6227,11 @@ const NavigationLogo = ({ src, title, description, width, height, divider = fals
6193
6227
  className: "flex flex-grow"
6194
6228
  }),
6195
6229
  /*#__PURE__*/ jsxRuntime.jsx("div", {
6196
- className: `grid grid-cols-${items?.length} ${extractClassName('navigationPanel', mergedClassnames)}`,
6230
+ className: `flex flex-grow nowrap ${extractClassName('navigationPanel', mergedClassnames)}`,
6197
6231
  children: items.map((x, index)=>{
6198
6232
  const selectedStyle = current === x.href ? 'border-accent border-b-4 border-b-accent' : '';
6199
6233
  return /*#__PURE__*/ jsxRuntime.jsx("div", {
6200
- className: `first:border-l-1 border-r-1 border-base-dark ${selectedStyle}`,
6234
+ className: `first:border-l-1 border-r-1 flex-1 border-base-dark ${selectedStyle} ${extractClassName('buttons', mergedClassnames)}`,
6201
6235
  children: /*#__PURE__*/ jsxRuntime.jsx(NavigationBarButton, {
6202
6236
  tooltip: x.tooltip,
6203
6237
  icon: x.icon,
@@ -7536,6 +7570,20 @@ const TableIcons = {
7536
7570
  })
7537
7571
  };
7538
7572
 
7573
+ const CompareFn = (fieldValue, cmpOp, value)=>{
7574
+ switch(cmpOp){
7575
+ case 'alwaysTrue':
7576
+ return true;
7577
+ case 'arrayNotEmpty':
7578
+ return Array.isArray(fieldValue) && fieldValue.length > 0;
7579
+ }
7580
+ };
7581
+ const isSelectable = (row, config)=>{
7582
+ if (!config) return false;
7583
+ if (!Object.hasOwn(row.original, config.field)) return false;
7584
+ const fieldValue = row.original[config.field];
7585
+ return CompareFn(fieldValue, config.comparer, config.value);
7586
+ };
7539
7587
  const extractCellValue = (func)=>({ cell, row })=>func({
7540
7588
  value: cell.getValue(),
7541
7589
  cell,
@@ -7568,6 +7616,13 @@ const DiscoveryTable = ({ data, hits, dataRequestStatus, setSorting, setPaginati
7568
7616
  }, [
7569
7617
  config.studyColumns
7570
7618
  ]);
7619
+ const checkIfRowIsSelectable = (row)=>{
7620
+ if (config.tableConfig?.selectableRows) return true;
7621
+ if (config.tableConfig?.selectableRowConfiguration) {
7622
+ return isSelectable(row, config.tableConfig.selectableRowConfiguration);
7623
+ }
7624
+ return false;
7625
+ };
7571
7626
  const table = mantineReactTable.useMantineReactTable({
7572
7627
  columns: cols,
7573
7628
  data: data ?? [],
@@ -7578,7 +7633,7 @@ const DiscoveryTable = ({ data, hits, dataRequestStatus, setSorting, setPaginati
7578
7633
  onPaginationChange: setPagination,
7579
7634
  onSortingChange: setSorting
7580
7635
  } : {},
7581
- enableRowSelection: config.tableConfig?.selectableRows ?? false,
7636
+ enableRowSelection: checkIfRowIsSelectable,
7582
7637
  rowCount: hits,
7583
7638
  icons: TableIcons,
7584
7639
  enableTopToolbar: false,
@@ -8806,6 +8861,7 @@ const useSearchMetadata = ({ discoveryConfig, searchTerms, mdsData, isSuccess })
8806
8861
  uidField
8807
8862
  ],
8808
8863
  idField: uidField,
8864
+ tokenize: (string, _fieldName)=>string.split(' '),
8809
8865
  extractField: extractValue,
8810
8866
  // processTerm: (term) => suffixes(term, 3),
8811
8867
  searchOptions: {
@@ -9709,7 +9765,8 @@ registerDefaultDiscoveryDataLoaders();
9709
9765
  }) : null,
9710
9766
  discoveryConfig.features?.chartsSection?.enabled && /*#__PURE__*/ jsxRuntime.jsx(CollapsableCharts, {
9711
9767
  config: discoveryConfig.features?.chartsSection,
9712
- data: chartData
9768
+ data: chartData,
9769
+ isSuccess: dataRequestStatus.isSuccess
9713
9770
  }),
9714
9771
  /*#__PURE__*/ jsxRuntime.jsxs("div", {
9715
9772
  className: "flex items-center p-2 mb-4 bg-base-max rounded-lg",
@@ -10139,6 +10196,23 @@ const RenderParagraphsCell = ({ value })=>{
10139
10196
  }, i))
10140
10197
  });
10141
10198
  };
10199
+ const RenderIfArrayHasData = ({ value })=>{
10200
+ const content = value;
10201
+ if (lodash.isArray(content) && content.length > 0) {
10202
+ return /*#__PURE__*/ jsxRuntime.jsx(react.Icon, {
10203
+ icon: "gen3:checked-filled",
10204
+ height: 22,
10205
+ width: 22,
10206
+ className: "text-utility-success"
10207
+ });
10208
+ }
10209
+ return /*#__PURE__*/ jsxRuntime.jsx(react.Icon, {
10210
+ icon: "gen3:cancel-filled",
10211
+ height: 22,
10212
+ width: 22,
10213
+ className: "text-utility-error"
10214
+ });
10215
+ };
10142
10216
  // TODO Fix below
10143
10217
  // eslint-disable-next-line react/prop-types
10144
10218
  const DiscoveryRenderTagsCell = ({ value })=>{
@@ -10169,6 +10243,7 @@ const DiscoveryRenderTagsCell = ({ value })=>{
10169
10243
  const Gen3DiscoveryStandardCellRenderers = {
10170
10244
  array: {
10171
10245
  NegativePositive: RenderArrayCellNegativePositive$1,
10246
+ HasData: RenderIfArrayHasData,
10172
10247
  default: RenderArrayCell$1
10173
10248
  },
10174
10249
  string: {
@@ -12618,10 +12693,22 @@ const EmptyData = {};
12618
12693
  const isXl = hooks.useMediaQuery('(min-width: 1600px)');
12619
12694
  const [accessLevel, setAccessLevel] = React.useState(core.Accessibility.ALL);
12620
12695
  const sharedFiltersMap = core.useCoreSelector((state)=>core.selectSharedFilters(state));
12621
- let numCols = 3;
12622
- if (isSm) numCols = 1;
12623
- if (isMd) numCols = 2;
12624
- if (isXl) numCols = 4;
12696
+ const defaultDropdowns = React.useMemo(()=>dropdowns ?? {}, [
12697
+ dropdowns
12698
+ ]);
12699
+ const defaultButtons = React.useMemo(()=>buttons ?? [], [
12700
+ buttons
12701
+ ]);
12702
+ const numCols = React.useMemo(()=>{
12703
+ if (isSm) return 1;
12704
+ if (isMd) return 2;
12705
+ if (isXl) return 4;
12706
+ return 3;
12707
+ }, [
12708
+ isSm,
12709
+ isMd,
12710
+ isXl
12711
+ ]);
12625
12712
  const index = guppyConfig.dataType;
12626
12713
  const fields = React.useMemo(()=>getAllFieldsFromFilterConfigs(filters?.tabs ?? []), [
12627
12714
  filters?.tabs
@@ -12635,14 +12722,20 @@ const EmptyData = {};
12635
12722
  filters: cohortFilters,
12636
12723
  accessibility: accessLevel
12637
12724
  });
12638
- const { data: chartData, isSuccess: isChartSuccess, isFetching: isChartFetching, isError: isChartError } = core.useGetAggsNoFilterSelfQuery({
12639
- type: index,
12640
- fields: [
12725
+ const chartKeys = useDeepCompare.useDeepCompareMemo(()=>[
12641
12726
  ...Object.keys(chartsSection?.charts ?? {}),
12642
12727
  ...Object.keys(charts)
12643
- ],
12728
+ ], [
12729
+ chartsSection?.charts,
12730
+ charts
12731
+ ]);
12732
+ const { data: chartData, isSuccess: isChartSuccess, isFetching: isChartFetching, isError: isChartError } = core.useGetAggsNoFilterSelfQuery({
12733
+ type: index,
12734
+ fields: chartKeys,
12644
12735
  filters: cohortFilters,
12645
12736
  accessibility: accessLevel
12737
+ }, {
12738
+ skip: chartKeys.length === 0
12646
12739
  });
12647
12740
  const getEnumFacetData = useDeepCompare.useDeepCompareCallback((field)=>{
12648
12741
  let filters = undefined;
@@ -12665,7 +12758,7 @@ const EmptyData = {};
12665
12758
  isSuccess: isSuccess
12666
12759
  };
12667
12760
  }, [
12668
- cohortFilters,
12761
+ cohortFilters.root,
12669
12762
  data,
12670
12763
  isSuccess
12671
12764
  ]);
@@ -12814,8 +12907,8 @@ const EmptyData = {};
12814
12907
  className: "flex justify-between mb-2 ml-2",
12815
12908
  children: [
12816
12909
  /*#__PURE__*/ jsxRuntime.jsx(DownloadsPanel, {
12817
- dropdowns: dropdowns ?? {},
12818
- buttons: buttons ?? [],
12910
+ dropdowns: defaultDropdowns,
12911
+ buttons: defaultButtons,
12819
12912
  loginForDownload: loginForDownload,
12820
12913
  index: index,
12821
12914
  totalCount: counts ?? 0,
@@ -12834,7 +12927,8 @@ const EmptyData = {};
12834
12927
  ...chartsSection,
12835
12928
  charts: summaryCharts
12836
12929
  },
12837
- data: chartData ?? EmptyData
12930
+ data: chartData ?? EmptyData,
12931
+ isSuccess: isChartSuccess
12838
12932
  }) : /*#__PURE__*/ jsxRuntime.jsx(Charts, {
12839
12933
  charts: summaryCharts,
12840
12934
  data: chartData ?? EmptyData,
@@ -12888,6 +12982,9 @@ const TabsLayoutToComponentProp = (tabsLayout)=>{
12888
12982
  const CohortBuilder = ({ explorerConfig, sharedFiltersMap = null, tabsLayout = 'left' })=>{
12889
12983
  const dispatch = core.useCoreDispatch();
12890
12984
  dispatch(core.setSharedFilters(sharedFiltersMap ?? {}));
12985
+ const configuration = useDeepCompare.useDeepCompareMemo(()=>explorerConfig, [
12986
+ explorerConfig
12987
+ ]);
12891
12988
  return /*#__PURE__*/ jsxRuntime.jsx("div", {
12892
12989
  className: "w-full",
12893
12990
  children: /*#__PURE__*/ jsxRuntime.jsxs(core$1.Tabs, {
@@ -12898,17 +12995,24 @@ const CohortBuilder = ({ explorerConfig, sharedFiltersMap = null, tabsLayout = '
12898
12995
  /*#__PURE__*/ jsxRuntime.jsx(core$1.Tabs.List, {
12899
12996
  className: "w-full",
12900
12997
  justify: TabsLayoutToComponentProp(tabsLayout),
12901
- children: explorerConfig.map((panelConfig)=>/*#__PURE__*/ jsxRuntime.jsx(core$1.Tabs.Tab, {
12998
+ children: configuration.map((panelConfig)=>/*#__PURE__*/ jsxRuntime.jsx(core$1.Tabs.Tab, {
12902
12999
  value: panelConfig.tabTitle,
12903
13000
  children: panelConfig.tabTitle
12904
13001
  }, `${panelConfig.tabTitle}-tabList`))
12905
13002
  }),
12906
- explorerConfig.map((panelConfig)=>/*#__PURE__*/ jsxRuntime.jsx(core$1.Tabs.Panel, {
13003
+ configuration.map((panelConfig)=>/*#__PURE__*/ jsxRuntime.jsx(core$1.Tabs.Panel, {
12907
13004
  value: panelConfig.tabTitle,
12908
- children: /*#__PURE__*/ React.createElement(CohortPanel, {
12909
- ...panelConfig,
12910
- key: `${panelConfig.tabTitle}-CohortPanel`
12911
- })
13005
+ children: /*#__PURE__*/ jsxRuntime.jsx(CohortPanel, {
13006
+ guppyConfig: panelConfig.guppyConfig,
13007
+ chartsSection: panelConfig?.chartsSection,
13008
+ filters: panelConfig.filters,
13009
+ tabTitle: panelConfig.tabTitle,
13010
+ table: panelConfig.table,
13011
+ dropdowns: panelConfig.dropdowns,
13012
+ buttons: panelConfig.buttons,
13013
+ loginForDownload: panelConfig.loginForDownload,
13014
+ sharedFiltersMap: panelConfig.sharedFiltersMap
13015
+ }, `${panelConfig.tabTitle}-CohortPanel`)
12912
13016
  }, `${panelConfig.tabTitle}-tabPanel`))
12913
13017
  ]
12914
13018
  })
@@ -14023,47 +14127,25 @@ const Workspace = ({ config })=>{
14023
14127
  };
14024
14128
 
14025
14129
  const TextDescription = ({ description })=>{
14026
- const [extend, setExtend] = React.useState(false);
14027
- const textRef = React.useRef(null);
14028
- const [isClamped, setClamped] = React.useState(false);
14029
- React.useEffect(()=>{
14030
- // Function that should be called on window resize
14031
- function handleResize() {
14032
- if (textRef && textRef.current) {
14033
- setClamped(textRef.current.scrollHeight > textRef.current.clientHeight);
14034
- }
14035
- }
14036
- // Add event listener to window resize
14037
- window.addEventListener('resize', handleResize);
14038
- // Remove event listener on cleanup
14039
- return ()=>window.removeEventListener('resize', handleResize);
14040
- }, []); // Empty array ensures that it would only run on mount
14041
- return /*#__PURE__*/ jsxRuntime.jsxs(jsxRuntime.Fragment, {
14042
- children: [
14043
- !extend ? /*#__PURE__*/ jsxRuntime.jsx(core$1.Text, {
14044
- ref: textRef,
14045
- size: "sm",
14046
- lineClamp: 4,
14047
- children: description
14048
- }) : /*#__PURE__*/ jsxRuntime.jsx(core$1.Text, {
14049
- size: "sm",
14050
- children: description
14051
- }),
14052
- isClamped && /*#__PURE__*/ jsxRuntime.jsx("button", {
14053
- onClick: ()=>setExtend((extend)=>!extend),
14054
- children: /*#__PURE__*/ jsxRuntime.jsxs("div", {
14055
- className: "flex text-xs font-semibold text-base-contrast-light",
14056
- children: [
14057
- !extend ? 'Extend Text' : 'Collapse Text',
14058
- ' ',
14059
- /*#__PURE__*/ jsxRuntime.jsx("div", {
14060
- className: "my-auto",
14061
- children: !extend ? /*#__PURE__*/ jsxRuntime.jsx(md.MdKeyboardArrowDown, {}) : /*#__PURE__*/ jsxRuntime.jsx(md.MdKeyboardArrowUp, {})
14062
- })
14063
- ]
14130
+ return /*#__PURE__*/ jsxRuntime.jsx(core$1.Spoiler, {
14131
+ maxHeight: 80,
14132
+ showLabel: /*#__PURE__*/ jsxRuntime.jsxs("span", {
14133
+ children: [
14134
+ "Extend Text ",
14135
+ /*#__PURE__*/ jsxRuntime.jsx(md.MdKeyboardArrowDown, {
14136
+ className: "inline"
14064
14137
  })
14065
- })
14066
- ]
14138
+ ]
14139
+ }),
14140
+ hideLabel: /*#__PURE__*/ jsxRuntime.jsxs("span", {
14141
+ children: [
14142
+ "Collapse Text ",
14143
+ /*#__PURE__*/ jsxRuntime.jsx(md.MdKeyboardArrowUp, {
14144
+ className: "inline"
14145
+ })
14146
+ ]
14147
+ }),
14148
+ children: description
14067
14149
  });
14068
14150
  };
14069
14151
 
@@ -14071,20 +14153,22 @@ const AnalysisCard = ({ title, description, type, icon, image, hasDemo, loginReq
14071
14153
  return /*#__PURE__*/ jsxRuntime.jsxs(core$1.Stack, {
14072
14154
  align: "stretch",
14073
14155
  justify: "space-between",
14074
- className: "rounded-sm rounded-t-md bg-base-max p-0",
14156
+ className: "rounded-sm rounded-t-md bg-base-max p-0 h-full",
14075
14157
  children: [
14076
14158
  /*#__PURE__*/ jsxRuntime.jsxs("div", {
14077
- className: "h-full",
14159
+ className: "relative",
14078
14160
  children: [
14079
14161
  /*#__PURE__*/ jsxRuntime.jsx("div", {
14080
- className: "p-0 rounded-sm h-1/2 h-max-1/2 flex justify-center items-center overflow-hidden",
14081
- children: /*#__PURE__*/ jsxRuntime.jsx(core$1.Image, {
14082
- component: Image,
14083
- src: `${image}`,
14084
- alt: `${title} image`,
14085
- height: 1000,
14086
- width: 1000,
14087
- radius: "md"
14162
+ className: "p-0 rounded-sm h-[200px] h-max-1/2 flex justify-center items-center relative overflow-hidden",
14163
+ children: /*#__PURE__*/ jsxRuntime.jsx("div", {
14164
+ children: /*#__PURE__*/ jsxRuntime.jsx(core$1.Image, {
14165
+ component: Image,
14166
+ src: `${image}`,
14167
+ alt: "",
14168
+ radius: "md",
14169
+ width: 500,
14170
+ height: 500
14171
+ })
14088
14172
  })
14089
14173
  }),
14090
14174
  /*#__PURE__*/ jsxRuntime.jsxs("div", {
@@ -14095,7 +14179,7 @@ const AnalysisCard = ({ title, description, type, icon, image, hasDemo, loginReq
14095
14179
  children: /*#__PURE__*/ jsxRuntime.jsx(core$1.Image, {
14096
14180
  component: Image,
14097
14181
  src: `${icon}`,
14098
- alt: `${title} logo`,
14182
+ alt: "",
14099
14183
  width: 40,
14100
14184
  height: 40,
14101
14185
  radius: "lg"
@@ -17139,7 +17223,7 @@ const registerCohortDiscoveryApp = ()=>core.createGen3AppWithOwnStore({
17139
17223
  App: CohortDiscovery,
17140
17224
  id: AppId$1,
17141
17225
  name: _APP_NAME$2,
17142
- version: 'v1.0.0',
17226
+ version: _APP_VERSION$1,
17143
17227
  requiredEntityTypes: [],
17144
17228
  store: AppStore,
17145
17229
  context: AppContext
@@ -19331,45 +19415,44 @@ const registerMetadataSchemaApp = ()=>core.createGen3App({
19331
19415
  requiredEntityTypes: []
19332
19416
  });
19333
19417
 
19334
- const DropdownWithIcon = ({ disableTargetWidth, LeftIcon, RightIcon = /*#__PURE__*/ jsxRuntime.jsx(io.IoMdArrowDropdown, {
19335
- size: "1.25em",
19336
- "aria-hidden": "true",
19337
- "data-testid": "dropdown-icon"
19338
- }), TargetButtonChildren, targetButtonDisabled, dropdownElements, menuLabelText, menuLabelCustomClass, customPosition, fullHeight, zIndex = undefined, customDataTestId = undefined, tooltip = undefined, buttonAriaLabel = undefined })=>{
19418
+ const ADDITIONAL_DOWNLOAD_MESSAGE = 'A previous download is being processed. Additional downloads may be started.';
19419
+ const DropdownWithIcon = ({ disableTargetWidth, LeftSection, RightSection = /*#__PURE__*/ jsxRuntime.jsx("div", {
19420
+ className: "border-l pl-1 -mr-2",
19421
+ children: /*#__PURE__*/ jsxRuntime.jsx(io.IoMdArrowDropdown, {
19422
+ size: "1.25em",
19423
+ "aria-hidden": "true",
19424
+ "data-testid": "dropdown-icon"
19425
+ })
19426
+ }), TargetButtonChildren, targetButtonDisabled, dropdownElements, menuLabelText, menuLabelCustomClass, customPosition, fullHeight, zIndex = 900, customTargetButtonDataTestId = undefined, targetButtonTooltip = undefined, buttonAriaLabel = undefined, closeOnItemClick = true })=>{
19427
+ const targetRef = React.useRef(null);
19339
19428
  return /*#__PURE__*/ jsxRuntime.jsxs(core$1.Menu, {
19340
- width: disableTargetWidth ?? 'target',
19429
+ width: !disableTargetWidth ? 'target' : null,
19341
19430
  ...customPosition && {
19342
19431
  position: customPosition
19343
19432
  },
19344
- "data-testid": customDataTestId ?? 'menu-elem',
19345
19433
  zIndex: zIndex,
19434
+ closeOnItemClick: closeOnItemClick,
19346
19435
  children: [
19347
19436
  /*#__PURE__*/ jsxRuntime.jsx(core$1.Menu.Target, {
19348
- children: /*#__PURE__*/ jsxRuntime.jsx(core$1.Button, {
19349
- variant: "outline",
19350
- color: "primary",
19351
- className: `bg-base-max border-primary data-disabled:opacity-50 data-disabled:bg-base-max data-disabled:text-primary ${focusStyles}`,
19352
- ...LeftIcon && {
19353
- leftIcon: LeftIcon
19354
- },
19355
- rightSection: RightIcon,
19356
- disabled: targetButtonDisabled,
19357
- classNames: {
19358
- // rightIcon: 'border-l pl-1 -mr-2',
19359
- root: fullHeight ? 'h-full' : undefined
19360
- },
19361
- "aria-label": buttonAriaLabel,
19362
- children: /*#__PURE__*/ jsxRuntime.jsx("div", {
19363
- children: tooltip?.length && !targetButtonDisabled ? /*#__PURE__*/ jsxRuntime.jsx("div", {
19364
- children: /*#__PURE__*/ jsxRuntime.jsx(core$1.Tooltip, {
19365
- label: tooltip,
19366
- children: /*#__PURE__*/ jsxRuntime.jsx("div", {
19367
- children: TargetButtonChildren
19368
- })
19369
- })
19370
- }) : /*#__PURE__*/ jsxRuntime.jsx("div", {
19371
- children: TargetButtonChildren
19372
- })
19437
+ children: /*#__PURE__*/ jsxRuntime.jsx(core$1.Tooltip, {
19438
+ label: targetButtonTooltip,
19439
+ disabled: !targetButtonTooltip,
19440
+ children: /*#__PURE__*/ jsxRuntime.jsx(core$1.Button, {
19441
+ variant: "outline",
19442
+ color: "primary",
19443
+ className: `flex items-center bg-base-max border-primary data-disabled:opacity-50 data-disabled:bg-base-max data-disabled:text-primary ${focusStyles}`,
19444
+ ...LeftSection && {
19445
+ leftSection: LeftSection
19446
+ },
19447
+ rightSection: RightSection,
19448
+ disabled: targetButtonDisabled,
19449
+ classNames: {
19450
+ root: `${fullHeight ? 'h-full' : undefined}`
19451
+ },
19452
+ ref: targetRef,
19453
+ "aria-label": buttonAriaLabel,
19454
+ "data-testid": customTargetButtonDataTestId ?? 'menu-elem',
19455
+ children: TargetButtonChildren
19373
19456
  })
19374
19457
  })
19375
19458
  }),
@@ -19377,7 +19460,7 @@ const DropdownWithIcon = ({ disableTargetWidth, LeftIcon, RightIcon = /*#__PURE_
19377
19460
  "data-testid": "dropdown-menu-options",
19378
19461
  className: "border-1 border-secondary",
19379
19462
  children: [
19380
- menuLabelText && /*#__PURE__*/ jsxRuntime.jsxs(React.Fragment, {
19463
+ menuLabelText && /*#__PURE__*/ jsxRuntime.jsxs(jsxRuntime.Fragment, {
19381
19464
  children: [
19382
19465
  /*#__PURE__*/ jsxRuntime.jsx(core$1.Menu.Label, {
19383
19466
  className: menuLabelCustomClass ?? 'font-bold',
@@ -19387,15 +19470,37 @@ const DropdownWithIcon = ({ disableTargetWidth, LeftIcon, RightIcon = /*#__PURE_
19387
19470
  /*#__PURE__*/ jsxRuntime.jsx(core$1.Menu.Divider, {})
19388
19471
  ]
19389
19472
  }),
19390
- dropdownElements?.map(({ title, onClick, icon, disabled }, idx)=>/*#__PURE__*/ jsxRuntime.jsx(core$1.Menu.Item, {
19473
+ dropdownElements.map(({ title, onClick, icon, disabled, isLoading, loadingTooltip }, idx)=>{
19474
+ const menuItem = /*#__PURE__*/ jsxRuntime.jsx(core$1.Menu.Item, {
19391
19475
  onClick: ()=>{
19392
- if (onClick) onClick();
19476
+ if (onClick) {
19477
+ onClick();
19478
+ }
19479
+ // This is done inorder to set the last focused element as the menu target element
19480
+ // This is done to return focus to the target element if the modal is closed with ESC
19481
+ if (targetRef?.current) {
19482
+ targetRef?.current?.focus();
19483
+ }
19393
19484
  },
19394
19485
  "data-testid": `${title}-${idx}`,
19395
19486
  leftSection: icon && icon,
19396
19487
  disabled: disabled,
19397
19488
  children: title
19398
- }, `${title}-${idx}`))
19489
+ }, `${title}-${idx}`);
19490
+ if (isLoading) {
19491
+ return /*#__PURE__*/ jsxRuntime.jsx(core$1.Tooltip, {
19492
+ label: loadingTooltip || ADDITIONAL_DOWNLOAD_MESSAGE,
19493
+ position: "right",
19494
+ withArrow: true,
19495
+ multiline: true,
19496
+ w: 400,
19497
+ children: /*#__PURE__*/ jsxRuntime.jsx("div", {
19498
+ children: menuItem
19499
+ })
19500
+ }, `${title}-${idx}`);
19501
+ }
19502
+ return menuItem;
19503
+ })
19399
19504
  ]
19400
19505
  })
19401
19506
  ]