@gen3/frontend 0.10.47 → 0.10.48
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.
- package/dist/cjs/index.js +2043 -277
- package/dist/cjs/index.js.map +1 -1
- package/dist/dts/components/Login/LoginPanel.d.ts.map +1 -1
- package/dist/dts/components/Login/LoginPanel.js +2 -1
- package/dist/dts/components/Login/LoginPanel.js.map +1 -1
- package/dist/dts/components/charts/Charts.d.ts +1 -2
- package/dist/dts/components/charts/Charts.d.ts.map +1 -1
- package/dist/dts/components/charts/Charts.js +17 -13
- package/dist/dts/components/charts/Charts.js.map +1 -1
- package/dist/dts/components/charts/echarts/ReactECharts.d.ts.map +1 -1
- package/dist/dts/components/charts/echarts/ReactECharts.js +9 -14
- package/dist/dts/components/charts/echarts/ReactECharts.js.map +1 -1
- package/dist/dts/components/charts/tests/utils.unit.test.js +2 -2
- package/dist/dts/components/charts/tests/utils.unit.test.js.map +1 -1
- package/dist/dts/components/charts/types.d.ts +3 -3
- package/dist/dts/components/charts/types.d.ts.map +1 -1
- package/dist/dts/components/charts/utils.d.ts +2 -3
- package/dist/dts/components/charts/utils.d.ts.map +1 -1
- package/dist/dts/components/charts/utils.js +2 -3
- package/dist/dts/components/charts/utils.js.map +1 -1
- package/dist/dts/components/counts/CountsValue.js +1 -1
- package/dist/dts/components/counts/CountsValue.js.map +1 -1
- package/dist/dts/components/facets/EnumFacet.d.ts +3 -3
- package/dist/dts/components/facets/EnumFacet.d.ts.map +1 -1
- package/dist/dts/components/facets/EnumFacet.js +8 -233
- package/dist/dts/components/facets/EnumFacet.js.map +1 -1
- package/dist/dts/components/facets/ExactValueFacet.js +4 -4
- package/dist/dts/components/facets/ExactValueFacet.js.map +1 -1
- package/dist/dts/components/facets/FacetControlsHeader.d.ts +24 -0
- package/dist/dts/components/facets/FacetControlsHeader.d.ts.map +1 -0
- package/dist/dts/components/facets/FacetControlsHeader.js +53 -0
- package/dist/dts/components/facets/FacetControlsHeader.js.map +1 -0
- package/dist/dts/components/facets/FacetEnumList.d.ts +16 -0
- package/dist/dts/components/facets/FacetEnumList.d.ts.map +1 -0
- package/dist/dts/components/facets/FacetEnumList.js +234 -0
- package/dist/dts/components/facets/FacetEnumList.js.map +1 -0
- package/dist/dts/components/facets/FacetExpander.d.ts.map +1 -1
- package/dist/dts/components/facets/FacetExpander.js +2 -2
- package/dist/dts/components/facets/FacetExpander.js.map +1 -1
- package/dist/dts/components/facets/FacetSelector.d.ts +13 -0
- package/dist/dts/components/facets/FacetSelector.d.ts.map +1 -0
- package/dist/dts/components/facets/FacetSelector.js +58 -0
- package/dist/dts/components/facets/FacetSelector.js.map +1 -0
- package/dist/dts/components/facets/MultiSelectValueFacet.js +5 -5
- package/dist/dts/components/facets/MultiSelectValueFacet.js.map +1 -1
- package/dist/dts/components/facets/RangeFacet.d.ts +4 -5
- package/dist/dts/components/facets/RangeFacet.d.ts.map +1 -1
- package/dist/dts/components/facets/RangeFacet.js +4 -4
- package/dist/dts/components/facets/RangeFacet.js.map +1 -1
- package/dist/dts/components/facets/components.d.ts +1 -1
- package/dist/dts/components/facets/components.d.ts.map +1 -1
- package/dist/dts/components/facets/components.js +3 -3
- package/dist/dts/components/facets/components.js.map +1 -1
- package/dist/dts/components/facets/constants.d.ts +1 -0
- package/dist/dts/components/facets/constants.d.ts.map +1 -1
- package/dist/dts/components/facets/constants.js +1 -0
- package/dist/dts/components/facets/constants.js.map +1 -1
- package/dist/dts/components/facets/createFacetCard.js +4 -4
- package/dist/dts/components/facets/createFacetCard.js.map +1 -1
- package/dist/dts/components/facets/index.d.ts +5 -0
- package/dist/dts/components/facets/index.d.ts.map +1 -0
- package/dist/dts/components/facets/index.js +5 -0
- package/dist/dts/components/facets/index.js.map +1 -0
- package/dist/dts/components/facets/types.d.ts +29 -13
- package/dist/dts/components/facets/types.d.ts.map +1 -1
- package/dist/dts/components/facets/types.js.map +1 -1
- package/dist/dts/components/facets/utils.d.ts +2 -2
- package/dist/dts/components/facets/utils.d.ts.map +1 -1
- package/dist/dts/components/facets/utils.js +11 -5
- package/dist/dts/components/facets/utils.js.map +1 -1
- package/dist/dts/features/CohortBuilder/CohortPanel.d.ts.map +1 -1
- package/dist/dts/features/CohortBuilder/CohortPanel.js +4 -2
- package/dist/dts/features/CohortBuilder/CohortPanel.js.map +1 -1
- package/dist/dts/features/CohortBuilder/ExplorerTable/ExploreTableDetails/RowTableDetailsPanel.js.map +1 -1
- package/dist/dts/features/CohortBuilder/QueryExpressionSection.d.ts.map +1 -1
- package/dist/dts/features/CohortBuilder/QueryExpressionSection.js +21 -9
- package/dist/dts/features/CohortBuilder/QueryExpressionSection.js.map +1 -1
- package/dist/dts/features/CohortBuilder/QueryRepresentation.js +2 -2
- package/dist/dts/features/CohortBuilder/QueryRepresentation.js.map +1 -1
- package/dist/dts/features/CohortBuilder/types.d.ts +6 -4
- package/dist/dts/features/CohortBuilder/types.d.ts.map +1 -1
- package/dist/dts/features/CohortBuilder/types.js.map +1 -1
- package/dist/dts/features/CohortDiscovery/ActionButtonGroup.d.ts +3 -0
- package/dist/dts/features/CohortDiscovery/ActionButtonGroup.d.ts.map +1 -0
- package/dist/dts/features/CohortDiscovery/ActionButtonGroup.js +13 -0
- package/dist/dts/features/CohortDiscovery/ActionButtonGroup.js.map +1 -0
- package/dist/dts/features/CohortDiscovery/ChartsAndFacetsPanel.d.ts +16 -0
- package/dist/dts/features/CohortDiscovery/ChartsAndFacetsPanel.d.ts.map +1 -0
- package/dist/dts/features/CohortDiscovery/ChartsAndFacetsPanel.js +70 -0
- package/dist/dts/features/CohortDiscovery/ChartsAndFacetsPanel.js.map +1 -0
- package/dist/dts/features/CohortDiscovery/CohortDiscovery.d.ts +4 -0
- package/dist/dts/features/CohortDiscovery/CohortDiscovery.d.ts.map +1 -0
- package/dist/dts/features/CohortDiscovery/CohortDiscovery.js +17 -0
- package/dist/dts/features/CohortDiscovery/CohortDiscovery.js.map +1 -0
- package/dist/dts/features/CohortDiscovery/FacetSelectionPanel.d.ts +12 -0
- package/dist/dts/features/CohortDiscovery/FacetSelectionPanel.d.ts.map +1 -0
- package/dist/dts/features/CohortDiscovery/FacetSelectionPanel.js +26 -0
- package/dist/dts/features/CohortDiscovery/FacetSelectionPanel.js.map +1 -0
- package/dist/dts/features/CohortDiscovery/FilterExpandSlice.d.ts +11 -0
- package/dist/dts/features/CohortDiscovery/FilterExpandSlice.d.ts.map +1 -0
- package/dist/dts/features/CohortDiscovery/FilterExpandSlice.js +34 -0
- package/dist/dts/features/CohortDiscovery/FilterExpandSlice.js.map +1 -0
- package/dist/dts/features/CohortDiscovery/FilterPanels/EnumFacetPanel.d.ts +16 -0
- package/dist/dts/features/CohortDiscovery/FilterPanels/EnumFacetPanel.d.ts.map +1 -0
- package/dist/dts/features/CohortDiscovery/FilterPanels/EnumFacetPanel.js +22 -0
- package/dist/dts/features/CohortDiscovery/FilterPanels/EnumFacetPanel.js.map +1 -0
- package/dist/dts/features/CohortDiscovery/FilterPanels/FacetPanelDataHeader.d.ts +8 -0
- package/dist/dts/features/CohortDiscovery/FilterPanels/FacetPanelDataHeader.d.ts.map +1 -0
- package/dist/dts/features/CohortDiscovery/FilterPanels/FacetPanelDataHeader.js +8 -0
- package/dist/dts/features/CohortDiscovery/FilterPanels/FacetPanelDataHeader.js.map +1 -0
- package/dist/dts/features/CohortDiscovery/FilterPanels/createFacetPanel.d.ts +5 -0
- package/dist/dts/features/CohortDiscovery/FilterPanels/createFacetPanel.d.ts.map +1 -0
- package/dist/dts/features/CohortDiscovery/FilterPanels/createFacetPanel.js +10 -0
- package/dist/dts/features/CohortDiscovery/FilterPanels/createFacetPanel.js.map +1 -0
- package/dist/dts/features/CohortDiscovery/IndexPanel.d.ts +4 -0
- package/dist/dts/features/CohortDiscovery/IndexPanel.d.ts.map +1 -0
- package/dist/dts/features/CohortDiscovery/IndexPanel.js +96 -0
- package/dist/dts/features/CohortDiscovery/IndexPanel.js.map +1 -0
- package/dist/dts/features/CohortDiscovery/SelectedFacetsSlice.d.ts +14 -0
- package/dist/dts/features/CohortDiscovery/SelectedFacetsSlice.d.ts.map +1 -0
- package/dist/dts/features/CohortDiscovery/SelectedFacetsSlice.js +56 -0
- package/dist/dts/features/CohortDiscovery/SelectedFacetsSlice.js.map +1 -0
- package/dist/dts/features/CohortDiscovery/appApi.d.ts +19 -0
- package/dist/dts/features/CohortDiscovery/appApi.d.ts.map +1 -0
- package/dist/dts/features/CohortDiscovery/appApi.js +27 -0
- package/dist/dts/features/CohortDiscovery/appApi.js.map +1 -0
- package/dist/dts/features/CohortDiscovery/hooks.d.ts +4 -0
- package/dist/dts/features/CohortDiscovery/hooks.d.ts.map +1 -0
- package/dist/dts/features/CohortDiscovery/hooks.js +17 -0
- package/dist/dts/features/CohortDiscovery/hooks.js.map +1 -0
- package/dist/dts/features/CohortDiscovery/registerApp.d.ts +3 -0
- package/dist/dts/features/CohortDiscovery/registerApp.d.ts.map +1 -0
- package/dist/dts/features/CohortDiscovery/registerApp.js +17 -0
- package/dist/dts/features/CohortDiscovery/registerApp.js.map +1 -0
- package/dist/dts/features/CohortDiscovery/types.d.ts +12 -0
- package/dist/dts/features/CohortDiscovery/types.d.ts.map +1 -0
- package/dist/dts/features/CohortDiscovery/types.js +2 -0
- package/dist/dts/features/CohortDiscovery/types.js.map +1 -0
- package/dist/dts/features/CohortDiscovery/utils.d.ts +3 -0
- package/dist/dts/features/CohortDiscovery/utils.d.ts.map +1 -0
- package/dist/dts/features/CohortDiscovery/utils.js +10 -0
- package/dist/dts/features/CohortDiscovery/utils.js.map +1 -0
- package/dist/dts/features/CohortDiversity/CohortDiversityApp.d.ts +4 -0
- package/dist/dts/features/CohortDiversity/CohortDiversityApp.d.ts.map +1 -0
- package/dist/dts/features/CohortDiversity/CohortDiversityApp.js +54 -0
- package/dist/dts/features/CohortDiversity/CohortDiversityApp.js.map +1 -0
- package/dist/dts/features/CohortDiversity/ComnparisonCard.d.ts +15 -0
- package/dist/dts/features/CohortDiversity/ComnparisonCard.d.ts.map +1 -0
- package/dist/dts/features/CohortDiversity/ComnparisonCard.js +32 -0
- package/dist/dts/features/CohortDiversity/ComnparisonCard.js.map +1 -0
- package/dist/dts/features/CohortDiversity/ComparisonCards.d.ts +15 -0
- package/dist/dts/features/CohortDiversity/ComparisonCards.d.ts.map +1 -0
- package/dist/dts/features/CohortDiversity/ComparisonCards.js +14 -0
- package/dist/dts/features/CohortDiversity/ComparisonCards.js.map +1 -0
- package/dist/dts/features/CohortDiversity/appApi.d.ts +8 -0
- package/dist/dts/features/CohortDiversity/appApi.d.ts.map +1 -0
- package/dist/dts/features/CohortDiversity/appApi.js +4 -0
- package/dist/dts/features/CohortDiversity/appApi.js.map +1 -0
- package/dist/dts/features/CohortDiversity/charts/BarComparison.d.ts +5 -0
- package/dist/dts/features/CohortDiversity/charts/BarComparison.d.ts.map +1 -0
- package/dist/dts/features/CohortDiversity/charts/BarComparison.js +70 -0
- package/dist/dts/features/CohortDiversity/charts/BarComparison.js.map +1 -0
- package/dist/dts/features/CohortDiversity/charts/ChartCard.d.ts +16 -0
- package/dist/dts/features/CohortDiversity/charts/ChartCard.d.ts.map +1 -0
- package/dist/dts/features/CohortDiversity/charts/ChartCard.js +45 -0
- package/dist/dts/features/CohortDiversity/charts/ChartCard.js.map +1 -0
- package/dist/dts/features/CohortDiversity/charts/ComparisonCharts.d.ts +13 -0
- package/dist/dts/features/CohortDiversity/charts/ComparisonCharts.d.ts.map +1 -0
- package/dist/dts/features/CohortDiversity/charts/ComparisonCharts.js +18 -0
- package/dist/dts/features/CohortDiversity/charts/ComparisonCharts.js.map +1 -0
- package/dist/dts/features/CohortDiversity/charts/RadarComparison.d.ts +5 -0
- package/dist/dts/features/CohortDiversity/charts/RadarComparison.d.ts.map +1 -0
- package/dist/dts/features/CohortDiversity/charts/RadarComparison.js +90 -0
- package/dist/dts/features/CohortDiversity/charts/RadarComparison.js.map +1 -0
- package/dist/dts/features/CohortDiversity/charts/diversityChartsFactory.d.ts +6 -0
- package/dist/dts/features/CohortDiversity/charts/diversityChartsFactory.d.ts.map +1 -0
- package/dist/dts/features/CohortDiversity/charts/diversityChartsFactory.js +24 -0
- package/dist/dts/features/CohortDiversity/charts/diversityChartsFactory.js.map +1 -0
- package/dist/dts/features/CohortDiversity/charts/types.d.ts +12 -0
- package/dist/dts/features/CohortDiversity/charts/types.d.ts.map +1 -0
- package/dist/dts/features/CohortDiversity/charts/types.js +2 -0
- package/dist/dts/features/CohortDiversity/charts/types.js.map +1 -0
- package/dist/dts/features/CohortDiversity/charts/utils.d.ts +2 -0
- package/dist/dts/features/CohortDiversity/charts/utils.d.ts.map +1 -0
- package/dist/dts/features/CohortDiversity/charts/utils.js +4 -0
- package/dist/dts/features/CohortDiversity/charts/utils.js.map +1 -0
- package/dist/dts/features/CohortDiversity/diversityApi.d.ts +141 -0
- package/dist/dts/features/CohortDiversity/diversityApi.d.ts.map +1 -0
- package/dist/dts/features/CohortDiversity/diversityApi.js +14 -0
- package/dist/dts/features/CohortDiversity/diversityApi.js.map +1 -0
- package/dist/dts/features/CohortDiversity/registerApp.d.ts +3 -0
- package/dist/dts/features/CohortDiversity/registerApp.d.ts.map +1 -0
- package/dist/dts/features/CohortDiversity/registerApp.js +19 -0
- package/dist/dts/features/CohortDiversity/registerApp.js.map +1 -0
- package/dist/dts/features/CohortDiversity/statistics/StatisticsCard.d.ts +9 -0
- package/dist/dts/features/CohortDiversity/statistics/StatisticsCard.d.ts.map +1 -0
- package/dist/dts/features/CohortDiversity/statistics/StatisticsCard.js +68 -0
- package/dist/dts/features/CohortDiversity/statistics/StatisticsCard.js.map +1 -0
- package/dist/dts/features/CohortDiversity/statistics/StatisticsPanel.d.ts +13 -0
- package/dist/dts/features/CohortDiversity/statistics/StatisticsPanel.d.ts.map +1 -0
- package/dist/dts/features/CohortDiversity/statistics/StatisticsPanel.js +16 -0
- package/dist/dts/features/CohortDiversity/statistics/StatisticsPanel.js.map +1 -0
- package/dist/dts/features/CohortDiversity/statistics/data/data.d.ts +2 -0
- package/dist/dts/features/CohortDiversity/statistics/data/data.d.ts.map +1 -0
- package/dist/dts/features/CohortDiversity/statistics/data/data.js +50 -0
- package/dist/dts/features/CohortDiversity/statistics/data/data.js.map +1 -0
- package/dist/dts/features/CohortDiversity/statistics/data/tests/diversityResponse.json +228 -0
- package/dist/dts/features/CohortDiversity/statistics/data/tests/processHistogramResponse.unit.test.d.ts +2 -0
- package/dist/dts/features/CohortDiversity/statistics/data/tests/processHistogramResponse.unit.test.d.ts.map +1 -0
- package/dist/dts/features/CohortDiversity/statistics/data/tests/processHistogramResponse.unit.test.js +365 -0
- package/dist/dts/features/CohortDiversity/statistics/data/tests/processHistogramResponse.unit.test.js.map +1 -0
- package/dist/dts/features/CohortDiversity/statistics/data/utils.d.ts +49 -0
- package/dist/dts/features/CohortDiversity/statistics/data/utils.d.ts.map +1 -0
- package/dist/dts/features/CohortDiversity/statistics/data/utils.js +146 -0
- package/dist/dts/features/CohortDiversity/statistics/data/utils.js.map +1 -0
- package/dist/dts/features/CohortDiversity/statistics/queries.d.ts +6 -0
- package/dist/dts/features/CohortDiversity/statistics/queries.d.ts.map +1 -0
- package/dist/dts/features/CohortDiversity/statistics/queries.js +24 -0
- package/dist/dts/features/CohortDiversity/statistics/queries.js.map +1 -0
- package/dist/dts/features/CohortDiversity/types.d.ts +26 -0
- package/dist/dts/features/CohortDiversity/types.d.ts.map +1 -0
- package/dist/dts/features/CohortDiversity/types.js +2 -0
- package/dist/dts/features/CohortDiversity/types.js.map +1 -0
- package/dist/dts/features/Discovery/Charts/ChartsPanel.d.ts.map +1 -1
- package/dist/dts/features/Discovery/Charts/ChartsPanel.js +44 -33
- package/dist/dts/features/Discovery/Charts/ChartsPanel.js.map +1 -1
- package/dist/dts/features/Discovery/TableRenderers/RowRendererFactory.d.ts.map +1 -1
- package/dist/dts/features/Discovery/TableRenderers/RowRendererFactory.js +1 -1
- package/dist/dts/features/Discovery/TableRenderers/RowRendererFactory.js.map +1 -1
- package/dist/dts/features/Navigation/NavigationBar.d.ts.map +1 -1
- package/dist/dts/features/Navigation/NavigationBar.js +1 -1
- package/dist/dts/features/Navigation/NavigationBar.js.map +1 -1
- package/dist/dts/features/Navigation/TopBar.d.ts.map +1 -1
- package/dist/dts/features/Navigation/TopBar.js +1 -1
- package/dist/dts/features/Navigation/TopBar.js.map +1 -1
- package/dist/dts/index.d.ts +3 -1
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/index.js +3 -1
- package/dist/dts/index.js.map +1 -1
- package/dist/dts/lib/common/staticProps.js +1 -1
- package/dist/dts/lib/common/staticProps.js.map +1 -1
- package/dist/dts/lib/content/types.d.ts +6 -0
- package/dist/dts/lib/content/types.d.ts.map +1 -1
- package/dist/dts/lib/session/session.js.map +1 -1
- package/dist/dts/pages/admin/authz/data.d.ts.map +1 -1
- package/dist/dts/pages/admin/authz/data.js +5 -2
- package/dist/dts/pages/admin/authz/data.js.map +1 -1
- package/dist/dts/types/common.d.ts +5 -0
- package/dist/dts/types/common.d.ts.map +1 -0
- package/dist/dts/types/common.js +2 -0
- package/dist/dts/types/common.js.map +1 -0
- package/dist/dts/types/index.d.ts +1 -0
- package/dist/dts/types/index.d.ts.map +1 -1
- package/dist/dts/types/index.js +1 -0
- package/dist/dts/types/index.js.map +1 -1
- package/dist/dts/utils/isType.d.ts.map +1 -1
- package/dist/dts/utils/strings.d.ts +4 -0
- package/dist/dts/utils/strings.d.ts.map +1 -1
- package/dist/dts/utils/strings.js +15 -3
- package/dist/dts/utils/strings.js.map +1 -1
- package/dist/esm/index.js +2045 -283
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.ts +36 -22
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -3
package/dist/esm/index.js
CHANGED
|
@@ -3,15 +3,15 @@ import * as React from 'react';
|
|
|
3
3
|
import React__default, { useState, useCallback, useEffect, useContext, useRef, createElement, createContext, useMemo, forwardRef, useReducer } from 'react';
|
|
4
4
|
import { twMerge } from 'tailwind-merge';
|
|
5
5
|
import Image from 'next/image';
|
|
6
|
-
import { toString, isArray, get, partial, omit
|
|
6
|
+
import { toString, capitalize as capitalize$1, isArray, get, partial, omit } from 'lodash';
|
|
7
7
|
import Link from 'next/link';
|
|
8
|
-
import { FaExternalLinkAlt, FaQuestion, FaExclamation, FaExclamationTriangle, FaUndo, FaPlus, FaGraduationCap, FaRegQuestionCircle, FaVideo, FaCircle } from 'react-icons/fa';
|
|
8
|
+
import { FaExternalLinkAlt, FaQuestion, FaExclamation, FaExclamationTriangle, FaUndo, FaPlus, FaChartPie, FaGraduationCap, FaRegQuestionCircle, FaVideo, FaCircle } from 'react-icons/fa';
|
|
9
9
|
import { Icon, addCollection } from '@iconify/react';
|
|
10
|
-
import { Tooltip, UnstyledButton, Menu, Text, Button, Box, Badge, Alert, Tabs, Accordion, Stack, Group, Drawer, CopyButton, LoadingOverlay, factory, useProps, useMantineTheme, getStyleObject, Paper, Checkbox, SegmentedControl, Loader, Grid, Card, Table, ColorSwatch, Modal, Switch, Divider, Autocomplete, TextInput, Title, Avatar, Select, Textarea, FileButton, Anchor, ThemeIcon, ActionIcon, NumberInput, RangeSlider, MultiSelect, Center, MantineProvider, createTheme, Highlight, List } from '@mantine/core';
|
|
10
|
+
import { Tooltip, UnstyledButton, Menu, Text, Button, Box, Badge, Alert, Tabs, Accordion, Stack, Group, Drawer, CopyButton, LoadingOverlay, factory, useProps, useMantineTheme, getStyleObject, Paper, Checkbox, SegmentedControl, Loader, Grid, Card, Table, ColorSwatch, Modal, Switch, Divider, Autocomplete, TextInput, Title, Avatar, Select, Textarea, FileButton, Anchor, ThemeIcon, ActionIcon, NumberInput, RangeSlider, MultiSelect, Center, Flex, ScrollArea, rem, MantineProvider, createTheme, Highlight, List } from '@mantine/core';
|
|
11
11
|
import { useRouter } from 'next/router';
|
|
12
12
|
import { usePathname } from 'next/navigation';
|
|
13
|
-
import { MdLogin, MdKeyboardDoubleArrowLeft, MdUndo, MdSearch, MdClose, MdInfo,
|
|
14
|
-
import { useCoreDispatch, useLazyFetchUserDetailsQuery, useCoreSelector, selectUserAuthStatus, GEN3_REDIRECT_URL, showModal, Modals, GEN3_FENCE_API, isAuthenticated, selectUserDetails, useIsUserLoggedIn, fieldNameToTitle, useGetMDSQuery, selectAuthzMappingData, useGetAggMDSQuery, useAskQuestionMutation, useGetIndexAggMDSQuery, useGetTagsQuery, useUserAuth, useGetAuthzMappingsQuery, useGetLoginProvidersQuery, hideModal, useGetCSRFQuery, selectCurrentModal, updateCohortFilter, selectIndexedFilterByName, isOperationWithField, removeCohortFilter, trimFirstFieldNameToTitle, selectCohortFilters, handleOperation, selectCurrentCohortId, clearCohortFilters, selectCurrentCohortName, useGeneralGQLQuery, selectIndexFilters, useGetRawDataAndTotalCountsQuery, Accessibility, downloadFromGuppyToBlob, downloadJSONDataFromGuppy, useGetAggsQuery, extractEnumFilterValue, useGetCountsQuery, selectHeadersWithCSRFToken, GEN3_GUPPY_API, GEN3_COMMONS_NAME, CoreProvider, useGetCredentialsQuery, useRemoveCredentialMutation, useAddNewCredentialMutation, useGetExternalLoginsQuery, useGetDictionaryQuery, useGetProjectsDetailsQuery, useGetSubmissionsQuery, useLazyGetCrosswalkDataQuery } from '@gen3/core';
|
|
13
|
+
import { MdLogin, MdKeyboardDoubleArrowLeft, MdUndo, MdSearch, MdClose, MdInfo, MdExpandLess, MdExpandMore, MdFlip, MdAddCircle, MdRemoveCircle, MdOutlineArrowBack, MdOutlineArrowForward, MdOutlineArrowBackIos, MdOutlineArrowForwardIos, MdKeyboardArrowDown, MdKeyboardArrowUp, MdDownload, MdFormatQuote, MdOutlineSearch, MdOutlineBarChart, MdGroup, MdDelete } from 'react-icons/md';
|
|
14
|
+
import { useCoreDispatch, useLazyFetchUserDetailsQuery, useCoreSelector, selectUserAuthStatus, GEN3_REDIRECT_URL, showModal, Modals, GEN3_FENCE_API, isAuthenticated, selectUserDetails, useIsUserLoggedIn, fieldNameToTitle, useGetMDSQuery, selectAuthzMappingData, useGetAggMDSQuery, useAskQuestionMutation, useGetIndexAggMDSQuery, useGetTagsQuery, useUserAuth, useGetAuthzMappingsQuery, useGetLoginProvidersQuery, hideModal, useGetCSRFQuery, selectCurrentModal, updateCohortFilter, selectIndexedFilterByName, isOperationWithField, removeCohortFilter, trimFirstFieldNameToTitle, selectCohortFilters, handleOperation, selectCurrentCohortId, clearCohortFilters, selectCurrentCohortName, useGeneralGQLQuery, selectIndexFilters, useGetRawDataAndTotalCountsQuery, Accessibility, downloadFromGuppyToBlob, downloadJSONDataFromGuppy, useGetAggsQuery, extractEnumFilterValue, useGetCountsQuery, selectHeadersWithCSRFToken, GEN3_GUPPY_API, GEN3_COMMONS_NAME, createAppStore, createGen3AppWithOwnStore, createAppApiForRTKQ, getGen3AppId, CoreProvider, useGetCredentialsQuery, useRemoveCredentialMutation, useAddNewCredentialMutation, useGetExternalLoginsQuery, useGetDictionaryQuery, useGetProjectsDetailsQuery, useGetSubmissionsQuery, useLazyGetCrosswalkDataQuery } from '@gen3/core';
|
|
15
15
|
import { useDeepCompareEffect, useDeepCompareMemo, useDeepCompareCallback } from 'use-deep-compare';
|
|
16
16
|
import 'swr';
|
|
17
17
|
import { getCookie, deleteCookie, setCookie } from 'cookies-next';
|
|
@@ -25,7 +25,7 @@ import { useMantineReactTable, MantineReactTable } from 'mantine-react-table';
|
|
|
25
25
|
import { JSONPath } from 'jsonpath-plus';
|
|
26
26
|
import { LuClock, LuCircleSlash, LuUnlock, LuLock, LuRefreshCw } from 'react-icons/lu';
|
|
27
27
|
import tinycolor from 'tinycolor2';
|
|
28
|
-
import { useDisclosure, useDidUpdate, mergeRefs, useReducedMotion, useElementSize, useClipboard, useMediaQuery, useLocalStorage, useScrollIntoView } from '@mantine/hooks';
|
|
28
|
+
import { useDisclosure, useDidUpdate, mergeRefs, useReducedMotion, useResizeObserver, useElementSize, useClipboard, useMediaQuery, useLocalStorage, useScrollIntoView } from '@mantine/hooks';
|
|
29
29
|
import { FiDownload, FiMoreVertical } from 'react-icons/fi';
|
|
30
30
|
import { TiArrowUnsorted, TiArrowSortedUp, TiArrowSortedDown } from 'react-icons/ti';
|
|
31
31
|
import { flushSync } from 'react-dom';
|
|
@@ -47,6 +47,11 @@ import { IoMdArrowDropdown, IoMdRefresh, IoMdLogIn } from 'react-icons/io';
|
|
|
47
47
|
import GraphiQL from 'graphiql';
|
|
48
48
|
import fs from 'fs';
|
|
49
49
|
import path from 'path';
|
|
50
|
+
import { PersistGate } from 'redux-persist/integration/react';
|
|
51
|
+
import { persistReducer, persistStore } from 'redux-persist';
|
|
52
|
+
import { combineReducers } from 'redux';
|
|
53
|
+
import storage from 'redux-persist/lib/storage';
|
|
54
|
+
import { createSlice } from '@reduxjs/toolkit';
|
|
50
55
|
import { ModalsProvider } from '@mantine/modals';
|
|
51
56
|
import dynamic from 'next/dynamic';
|
|
52
57
|
import { useForm } from '@mantine/form';
|
|
@@ -647,7 +652,9 @@ const TopBar = ({ items, loginButtonVisibility = LoginButtonVisibility.Hidden, c
|
|
|
647
652
|
return /*#__PURE__*/ jsx("div", {
|
|
648
653
|
children: /*#__PURE__*/ jsx("header", {
|
|
649
654
|
className: extractClassName('root', mergedClassnames),
|
|
650
|
-
children: /*#__PURE__*/ jsxs("
|
|
655
|
+
children: /*#__PURE__*/ jsxs("div", {
|
|
656
|
+
role: "navigation",
|
|
657
|
+
"aria-label": "top most navigation",
|
|
651
658
|
className: "flex items-center align-middle",
|
|
652
659
|
children: [
|
|
653
660
|
processTopBarItems(items, loginButtonVisibility === LoginButtonVisibility.Visible),
|
|
@@ -793,6 +800,8 @@ const NavigationLogo = ({ src, title, description, width, height, divider = fals
|
|
|
793
800
|
router.pathname
|
|
794
801
|
]);
|
|
795
802
|
return /*#__PURE__*/ jsxs("div", {
|
|
803
|
+
role: "navigation",
|
|
804
|
+
"aria-label": "main site navigation",
|
|
796
805
|
className: extractClassName('root', mergedClassnames),
|
|
797
806
|
children: [
|
|
798
807
|
/*#__PURE__*/ jsx("div", {
|
|
@@ -1248,7 +1257,7 @@ class DiscoveryRowRendererFactory {
|
|
|
1248
1257
|
}
|
|
1249
1258
|
static getRowRenderer(type, functionName) {
|
|
1250
1259
|
if (!(type in DiscoveryRowRendererFactory.getInstance().RowRendererCatalog)) {
|
|
1251
|
-
console.
|
|
1260
|
+
console.warn('No row renderer found for type: ', type);
|
|
1252
1261
|
return defaultRowRenderer;
|
|
1253
1262
|
}
|
|
1254
1263
|
return DiscoveryRowRendererFactory.getInstance().RowRendererCatalog[type][functionName] ?? defaultRowRenderer;
|
|
@@ -1468,6 +1477,15 @@ const focusStyles = 'focus-visible:outline-none focus-visible:ring-offset-2 focu
|
|
|
1468
1477
|
const stripTrailingSlash = (str)=>{
|
|
1469
1478
|
return str.endsWith('/') ? str.slice(0, -1) : str;
|
|
1470
1479
|
};
|
|
1480
|
+
const SPECIAL_CASE_FIELDS = {
|
|
1481
|
+
icd_10_code: 'ICD-10 Code'
|
|
1482
|
+
};
|
|
1483
|
+
const toDisplayName = (field)=>{
|
|
1484
|
+
const parsed = field.split('.');
|
|
1485
|
+
const fieldName = parsed.at(-1);
|
|
1486
|
+
if (!fieldName) return 'NotSet';
|
|
1487
|
+
return fieldName.split('_').map((w)=>capitalize$1(w)).join(' ');
|
|
1488
|
+
};
|
|
1471
1489
|
|
|
1472
1490
|
const isArrayOfString = (value)=>{
|
|
1473
1491
|
return Array.isArray(value) && value.every((element)=>typeof element === 'string');
|
|
@@ -3082,18 +3100,18 @@ const defaultStatisticRenderer = ({ value, label, ...props })=>{
|
|
|
3082
3100
|
]
|
|
3083
3101
|
});
|
|
3084
3102
|
};
|
|
3085
|
-
const DefaultRendererCatalog$
|
|
3103
|
+
const DefaultRendererCatalog$2 = {
|
|
3086
3104
|
string: {
|
|
3087
3105
|
default: defaultStatisticRenderer
|
|
3088
3106
|
}
|
|
3089
3107
|
};
|
|
3090
|
-
let instance$
|
|
3108
|
+
let instance$4;
|
|
3091
3109
|
const StatisticRendererFactory = ()=>{
|
|
3092
|
-
if (!instance$
|
|
3093
|
-
instance$
|
|
3094
|
-
instance$
|
|
3110
|
+
if (!instance$4) {
|
|
3111
|
+
instance$4 = new RenderFactoryTypedInstance();
|
|
3112
|
+
instance$4.registerRendererCatalog(DefaultRendererCatalog$2);
|
|
3095
3113
|
}
|
|
3096
|
-
return instance$
|
|
3114
|
+
return instance$4;
|
|
3097
3115
|
};
|
|
3098
3116
|
|
|
3099
3117
|
const BuildSummaryStatisticPanel = (summaries = [])=>{
|
|
@@ -3159,11 +3177,10 @@ const processRangeKeyLabel = (key)=>{
|
|
|
3159
3177
|
/**
|
|
3160
3178
|
* Computes the row span for each item in the charts object.
|
|
3161
3179
|
*
|
|
3162
|
-
* @param {
|
|
3180
|
+
* @param { number } numItems - The charts object containing summary charts.
|
|
3163
3181
|
* @param {number} [numCols=3] - The number of columns per row.
|
|
3164
3182
|
* @returns {number[]} - An array of row spans for each item in the charts object.
|
|
3165
|
-
*/ const computeRowSpan = (
|
|
3166
|
-
const numItems = Object.keys(charts).length;
|
|
3183
|
+
*/ const computeRowSpan = (numItems, numCols = 3)=>{
|
|
3167
3184
|
// compute the row span for the last row
|
|
3168
3185
|
const numLastRow = numItems % numCols;
|
|
3169
3186
|
let spans = new Array(numItems - numLastRow).fill(Math.floor(12 / numCols));
|
|
@@ -3172,24 +3189,15 @@ const processRangeKeyLabel = (key)=>{
|
|
|
3172
3189
|
};
|
|
3173
3190
|
|
|
3174
3191
|
const ReactECharts = ({ option, style, settings, loading, theme })=>{
|
|
3175
|
-
const
|
|
3192
|
+
const [chartRoot, setChartRoot] = useState(undefined);
|
|
3193
|
+
const [chartRef, rect] = useResizeObserver();
|
|
3176
3194
|
useDeepCompareEffect(()=>{
|
|
3177
3195
|
// Initialize chart
|
|
3178
3196
|
let chart;
|
|
3179
3197
|
if (chartRef.current !== null) {
|
|
3180
3198
|
chart = init(chartRef.current, theme);
|
|
3181
3199
|
}
|
|
3182
|
-
|
|
3183
|
-
// ResizeObserver is leading to a bit janky UX
|
|
3184
|
-
function resizeChart(event) {
|
|
3185
|
-
chart?.resize();
|
|
3186
|
-
}
|
|
3187
|
-
window.addEventListener('resize', resizeChart);
|
|
3188
|
-
// Return cleanup function
|
|
3189
|
-
return ()=>{
|
|
3190
|
-
chart?.dispose();
|
|
3191
|
-
window.removeEventListener('resize', resizeChart);
|
|
3192
|
-
};
|
|
3200
|
+
setChartRoot(chart);
|
|
3193
3201
|
}, [
|
|
3194
3202
|
theme
|
|
3195
3203
|
]);
|
|
@@ -3214,7 +3222,14 @@ const ReactECharts = ({ option, style, settings, loading, theme })=>{
|
|
|
3214
3222
|
}, [
|
|
3215
3223
|
loading
|
|
3216
3224
|
]);
|
|
3225
|
+
useDeepCompareEffect(()=>{
|
|
3226
|
+
chartRoot?.resize();
|
|
3227
|
+
}, [
|
|
3228
|
+
rect
|
|
3229
|
+
]);
|
|
3217
3230
|
return /*#__PURE__*/ jsx("div", {
|
|
3231
|
+
role: "figure",
|
|
3232
|
+
"aria-label": "Data Chart",
|
|
3218
3233
|
ref: chartRef,
|
|
3219
3234
|
style: {
|
|
3220
3235
|
width: '100%',
|
|
@@ -3470,13 +3485,13 @@ const DefaultChartCatalog = {
|
|
|
3470
3485
|
donut: DonutChart
|
|
3471
3486
|
}
|
|
3472
3487
|
};
|
|
3473
|
-
let instance$
|
|
3488
|
+
let instance$3 = undefined;
|
|
3474
3489
|
const ChartRendererFactory = ()=>{
|
|
3475
|
-
if (!instance$
|
|
3476
|
-
instance$
|
|
3477
|
-
instance$
|
|
3490
|
+
if (!instance$3) {
|
|
3491
|
+
instance$3 = new RenderFactoryTypedInstance();
|
|
3492
|
+
instance$3.registerRendererCatalog(DefaultChartCatalog);
|
|
3478
3493
|
}
|
|
3479
|
-
return instance$
|
|
3494
|
+
return instance$3;
|
|
3480
3495
|
};
|
|
3481
3496
|
|
|
3482
3497
|
/** createChart selects which type of chart element to create depending on the
|
|
@@ -3504,9 +3519,14 @@ const chartColors = [
|
|
|
3504
3519
|
'#ea7ccc'
|
|
3505
3520
|
];
|
|
3506
3521
|
//The Charts component maps the data from ChartsProps into a grid of createChart() ReactNodes
|
|
3507
|
-
const Charts = ({
|
|
3508
|
-
const spans = computeRowSpan(charts, numCols);
|
|
3522
|
+
const Charts = ({ charts, data, counts, isSuccess, numCols = DEFAULT_COLS, style = 'tile', showLegends = false })=>{
|
|
3523
|
+
const spans = computeRowSpan(Object.keys(charts).length, numCols);
|
|
3509
3524
|
const chartCard = (field, indexNum)=>{
|
|
3525
|
+
if (!(field in data)) {
|
|
3526
|
+
return /*#__PURE__*/ jsx(ErrorCard, {
|
|
3527
|
+
message: `${field} not found in data`
|
|
3528
|
+
});
|
|
3529
|
+
}
|
|
3510
3530
|
const LegendRows = ({ data })=>{
|
|
3511
3531
|
const moreThanMaxRows = data.length > MAX_LEGEND_ROWS;
|
|
3512
3532
|
const limitedRows = moreThanMaxRows ? data.slice(0, MAX_LEGEND_ROWS) : data;
|
|
@@ -3646,7 +3666,7 @@ const Charts = ({ index, charts, data, counts, isSuccess, numCols = DEFAULT_COLS
|
|
|
3646
3666
|
td: 'p-1 leading-3',
|
|
3647
3667
|
th: 'p-1 leading-3 [text-shadow:_1px_0_#000]',
|
|
3648
3668
|
thead: 'border-b',
|
|
3649
|
-
tbody:
|
|
3669
|
+
tbody: "before:content-[''] before:block before:p-1"
|
|
3650
3670
|
},
|
|
3651
3671
|
children: [
|
|
3652
3672
|
/*#__PURE__*/ jsx(Table.Thead, {
|
|
@@ -3679,7 +3699,7 @@ const Charts = ({ index, charts, data, counts, isSuccess, numCols = DEFAULT_COLS
|
|
|
3679
3699
|
})
|
|
3680
3700
|
]
|
|
3681
3701
|
})
|
|
3682
|
-
}, `${
|
|
3702
|
+
}, `${indexNum}-charts-${field}-col`);
|
|
3683
3703
|
};
|
|
3684
3704
|
return /*#__PURE__*/ jsx(Grid, {
|
|
3685
3705
|
className: "w-full",
|
|
@@ -3931,10 +3951,11 @@ const ChartsPanel = ({ config })=>{
|
|
|
3931
3951
|
const chartDataTemp = {};
|
|
3932
3952
|
config?.charts?.forEach((chart, index)=>{
|
|
3933
3953
|
chartDataTemp[`testName${index}`] = {
|
|
3954
|
+
//TODO use from data
|
|
3934
3955
|
title: chart.title,
|
|
3935
3956
|
chartType: chart.chartType,
|
|
3936
3957
|
valueType: chart.valueType,
|
|
3937
|
-
dataLabels: chart.dataLabels
|
|
3958
|
+
dataLabels: chart.dataLabels
|
|
3938
3959
|
};
|
|
3939
3960
|
});
|
|
3940
3961
|
return chartDataTemp;
|
|
@@ -3979,10 +4000,9 @@ const ChartsPanel = ({ config })=>{
|
|
|
3979
4000
|
children: /*#__PURE__*/ jsx(Charts, {
|
|
3980
4001
|
showLegends: showLegends,
|
|
3981
4002
|
style: "box",
|
|
3982
|
-
index: 'subjectsCharts',
|
|
3983
4003
|
charts: chartsProperties(),
|
|
3984
4004
|
data: {
|
|
3985
|
-
|
|
4005
|
+
testName0: [
|
|
3986
4006
|
{
|
|
3987
4007
|
key: 'a',
|
|
3988
4008
|
count: 11
|
|
@@ -4004,7 +4024,7 @@ const ChartsPanel = ({ config })=>{
|
|
|
4004
4024
|
count: 0
|
|
4005
4025
|
}
|
|
4006
4026
|
],
|
|
4007
|
-
|
|
4027
|
+
testName1: [
|
|
4008
4028
|
{
|
|
4009
4029
|
key: 'a',
|
|
4010
4030
|
count: 11
|
|
@@ -4018,7 +4038,7 @@ const ChartsPanel = ({ config })=>{
|
|
|
4018
4038
|
count: 3
|
|
4019
4039
|
}
|
|
4020
4040
|
],
|
|
4021
|
-
|
|
4041
|
+
testName2: [
|
|
4022
4042
|
{
|
|
4023
4043
|
key: 'a',
|
|
4024
4044
|
count: 11
|
|
@@ -4032,7 +4052,7 @@ const ChartsPanel = ({ config })=>{
|
|
|
4032
4052
|
count: 3
|
|
4033
4053
|
}
|
|
4034
4054
|
],
|
|
4035
|
-
|
|
4055
|
+
testName3: [
|
|
4036
4056
|
{
|
|
4037
4057
|
key: 'a',
|
|
4038
4058
|
count: 1
|
|
@@ -5927,7 +5947,7 @@ const LoginPanel = (loginConfig)=>{
|
|
|
5927
5947
|
/*#__PURE__*/ jsx(LoginProvidersPanel, {
|
|
5928
5948
|
handleLoginSelected: handleFenceLoginSelected
|
|
5929
5949
|
}),
|
|
5930
|
-
loginConfig?.showCredentialsLogin && /*#__PURE__*/ jsx(CredentialsLogin, {
|
|
5950
|
+
loginConfig?.showCredentialsLogin && process.env.NODE_ENV === 'development' && /*#__PURE__*/ jsx(CredentialsLogin, {
|
|
5931
5951
|
handleLogin: handleCredentialsLogin
|
|
5932
5952
|
}),
|
|
5933
5953
|
bottomContent?.map((content, index)=>content?.email ? /*#__PURE__*/ createElement(ContactWithEmailContent, {
|
|
@@ -6409,7 +6429,7 @@ const processRangeData = (data)=>{
|
|
|
6409
6429
|
}
|
|
6410
6430
|
};
|
|
6411
6431
|
// Process facets to determine if they are enum, exact, or range
|
|
6412
|
-
const classifyFacets = (data, index, fieldMapping, facetDefinitionsFromConfig)=>{
|
|
6432
|
+
const classifyFacets = (data, index, fieldMapping = [], facetDefinitionsFromConfig = {})=>{
|
|
6413
6433
|
if (typeof data !== 'object' || data === null) return {};
|
|
6414
6434
|
// otherwise enum facet
|
|
6415
6435
|
return Object.entries(data).reduce((acc, [fieldKey, value])=>{
|
|
@@ -6417,7 +6437,7 @@ const classifyFacets = (data, index, fieldMapping, facetDefinitionsFromConfig)=>
|
|
|
6417
6437
|
const dataField = fieldKey.split('.')?.slice(-1)[0] ?? fieldKey;
|
|
6418
6438
|
// check if range facet
|
|
6419
6439
|
const type = value.length === 1 && isArray(value[0].key) ? 'range' : 'enum';
|
|
6420
|
-
const facetName = fieldMapping.find((x)=>x.field === fieldKey)?.name ??
|
|
6440
|
+
const facetName = fieldMapping.find((x)=>x.field === fieldKey)?.name ?? fieldNameToTitle(fieldKey);
|
|
6421
6441
|
const facetDef = facetDefinitionsFromConfig[fieldKey] ?? {};
|
|
6422
6442
|
return {
|
|
6423
6443
|
...acc,
|
|
@@ -6428,7 +6448,7 @@ const classifyFacets = (data, index, fieldMapping, facetDefinitionsFromConfig)=>
|
|
|
6428
6448
|
type: facetDef.type ?? type,
|
|
6429
6449
|
index: index,
|
|
6430
6450
|
description: facetDef.description ?? 'Not Available',
|
|
6431
|
-
label: facetDef.
|
|
6451
|
+
label: facetDef.label ?? facetName,
|
|
6432
6452
|
// assumption is that the initial data has the min and max values
|
|
6433
6453
|
range: facetDef.range ?? type === 'range' ? {
|
|
6434
6454
|
minimum: Math.floor(Number(value[0].key[0])),
|
|
@@ -6470,7 +6490,10 @@ const buildNested = (field, leafOperand)=>{
|
|
|
6470
6490
|
};
|
|
6471
6491
|
};
|
|
6472
6492
|
const useGetFacetFilters = (index, field)=>{
|
|
6473
|
-
return useCoreSelector((state)=>selectIndexedFilterByName(state, index, field)
|
|
6493
|
+
return useCoreSelector((state)=>selectIndexedFilterByName(state, index, field) ?? {
|
|
6494
|
+
operator: 'and',
|
|
6495
|
+
operands: []
|
|
6496
|
+
});
|
|
6474
6497
|
};
|
|
6475
6498
|
/**
|
|
6476
6499
|
* Given an operation, determine if range is open or closed and extract
|
|
@@ -6529,47 +6552,157 @@ inline-flex
|
|
|
6529
6552
|
items-center
|
|
6530
6553
|
hover:text-primary-lightest
|
|
6531
6554
|
`;
|
|
6532
|
-
const controlsIconStyle = 'text-
|
|
6555
|
+
const controlsIconStyle = 'text-secondary-contrast hover:text-secondary-lighter';
|
|
6533
6556
|
const FacetText = tw.div`
|
|
6534
|
-
text-secondary-contrast font-heading font-semibold text-
|
|
6557
|
+
text-secondary-contrast font-heading font-semibold text-sm break-words
|
|
6535
6558
|
`;
|
|
6536
6559
|
const FacetHeader = tw.div`
|
|
6537
|
-
flex items-start justify-between flex-nowrap bg-secondary px-1.5
|
|
6560
|
+
flex items-start justify-between items-center flex-nowrap bg-secondary px-1.5
|
|
6538
6561
|
`;
|
|
6539
6562
|
|
|
6540
|
-
|
|
6541
|
-
|
|
6542
|
-
|
|
6543
|
-
|
|
6544
|
-
|
|
6545
|
-
|
|
6546
|
-
|
|
6547
|
-
|
|
6548
|
-
|
|
6549
|
-
|
|
6550
|
-
|
|
6551
|
-
|
|
6552
|
-
|
|
6553
|
-
|
|
6554
|
-
|
|
6555
|
-
|
|
6556
|
-
|
|
6557
|
-
|
|
6558
|
-
|
|
6559
|
-
|
|
6560
|
-
|
|
6561
|
-
|
|
6562
|
-
|
|
6563
|
-
|
|
6564
|
-
|
|
6565
|
-
|
|
6566
|
-
}
|
|
6563
|
+
/**
|
|
6564
|
+
* Component for the common controls on the header of different type facet cards
|
|
6565
|
+
* @param field - filter this FacetCard manages
|
|
6566
|
+
* @param description - describes information about the facet
|
|
6567
|
+
* @param hooks - object defining the hooks required by this facet component
|
|
6568
|
+
* @param facetName - name of the Facet in human-readable form
|
|
6569
|
+
* @param showSearch - if the search icon show be displayed
|
|
6570
|
+
* @param showFlip - if the flip icon should be displayed
|
|
6571
|
+
* @param showClearSelection - if the clear selection icon should be displayed
|
|
6572
|
+
* @param isFacetView - if the facet selection view (and not the chart view) is displayed
|
|
6573
|
+
* @param toggleFlip - function to switch the facet/chart view
|
|
6574
|
+
* @param toggleSearch - function to switch if the search bart is displayed
|
|
6575
|
+
* @param dismissCallback - if facet can be removed, supply a function which will ensure the "dismiss" control will be visible
|
|
6576
|
+
* @param header - object containing the display components to use for the header
|
|
6577
|
+
*/ const FacetControlsHeader = ({ field, description, hooks, facetName, showSearch = false, showFlip = false, showClearSelection = true, isFacetView = false, toggleFlip = undefined, toggleSearch = undefined, dismissCallback = undefined, header = {
|
|
6578
|
+
Panel: FacetHeader,
|
|
6579
|
+
Label: FacetText,
|
|
6580
|
+
iconStyle: controlsIconStyle
|
|
6581
|
+
} })=>{
|
|
6582
|
+
const clearFilters = hooks.useClearFilter();
|
|
6583
|
+
const isFilterExpanded = hooks?.useFilterExpanded && hooks.useFilterExpanded(field);
|
|
6584
|
+
const toggleExpandFilter = hooks?.useToggleExpandFilter && hooks.useToggleExpandFilter();
|
|
6585
|
+
useEffect(()=>{
|
|
6586
|
+
// Initialize filter as expanded
|
|
6587
|
+
if (isFilterExpanded === undefined && toggleExpandFilter) {
|
|
6588
|
+
toggleExpandFilter(field, true);
|
|
6589
|
+
}
|
|
6590
|
+
}, [
|
|
6591
|
+
field,
|
|
6592
|
+
isFilterExpanded,
|
|
6593
|
+
toggleExpandFilter
|
|
6594
|
+
]);
|
|
6595
|
+
return /*#__PURE__*/ jsxs(header.Panel, {
|
|
6596
|
+
children: [
|
|
6597
|
+
/*#__PURE__*/ jsxs("div", {
|
|
6598
|
+
className: "flex flex-row items-center",
|
|
6599
|
+
children: [
|
|
6600
|
+
toggleExpandFilter && /*#__PURE__*/ jsx(Tooltip, {
|
|
6601
|
+
label: isFilterExpanded ? 'Collapse card' : 'Expand card',
|
|
6602
|
+
children: /*#__PURE__*/ jsx(ActionIcon, {
|
|
6603
|
+
variant: "subtle",
|
|
6604
|
+
onClick: ()=>toggleExpandFilter(field, !isFilterExpanded),
|
|
6605
|
+
className: "mt-0.5 -ml-1.5",
|
|
6606
|
+
"aria-expanded": isFilterExpanded,
|
|
6607
|
+
"aria-label": isFilterExpanded ? 'Collapse card' : 'Expand card',
|
|
6608
|
+
children: isFilterExpanded ? /*#__PURE__*/ jsx(MdExpandLess, {
|
|
6609
|
+
size: "3em",
|
|
6610
|
+
color: "accent.4",
|
|
6611
|
+
"aria-hidden": "true"
|
|
6612
|
+
}) : /*#__PURE__*/ jsx(MdExpandMore, {
|
|
6613
|
+
size: "3em",
|
|
6614
|
+
color: "accent.4",
|
|
6615
|
+
"aria-hidden": "true"
|
|
6616
|
+
})
|
|
6617
|
+
})
|
|
6618
|
+
}),
|
|
6619
|
+
/*#__PURE__*/ jsx(Tooltip, {
|
|
6620
|
+
label: description,
|
|
6621
|
+
position: "bottom-start",
|
|
6622
|
+
multiline: true,
|
|
6623
|
+
w: 220,
|
|
6624
|
+
withArrow: true,
|
|
6625
|
+
transitionProps: {
|
|
6626
|
+
duration: 200,
|
|
6627
|
+
transition: 'fade'
|
|
6628
|
+
},
|
|
6629
|
+
disabled: !description,
|
|
6630
|
+
children: /*#__PURE__*/ jsx(header.Label, {
|
|
6631
|
+
children: facetName ? facetName : fieldNameToTitle(field)
|
|
6632
|
+
})
|
|
6633
|
+
})
|
|
6634
|
+
]
|
|
6635
|
+
}),
|
|
6636
|
+
/*#__PURE__*/ jsxs("div", {
|
|
6637
|
+
className: "flex flex-row",
|
|
6638
|
+
children: [
|
|
6639
|
+
showSearch ? /*#__PURE__*/ jsx(Tooltip, {
|
|
6640
|
+
label: "Search values",
|
|
6641
|
+
children: /*#__PURE__*/ jsx(FacetIconButton, {
|
|
6642
|
+
onClick: ()=>{
|
|
6643
|
+
if (toggleExpandFilter) toggleExpandFilter(field, true);
|
|
6644
|
+
if (toggleSearch) toggleSearch();
|
|
6645
|
+
},
|
|
6646
|
+
"aria-label": "Search",
|
|
6647
|
+
children: /*#__PURE__*/ jsx(MdSearch, {
|
|
6648
|
+
size: "1.45em",
|
|
6649
|
+
className: header.iconStyle,
|
|
6650
|
+
"aria-hidden": "true"
|
|
6651
|
+
})
|
|
6652
|
+
})
|
|
6653
|
+
}) : null,
|
|
6654
|
+
showFlip ? /*#__PURE__*/ jsx(Tooltip, {
|
|
6655
|
+
label: isFacetView ? 'Chart view' : 'Selection view',
|
|
6656
|
+
children: /*#__PURE__*/ jsx(FacetIconButton, {
|
|
6657
|
+
onClick: ()=>{
|
|
6658
|
+
if (toggleExpandFilter) toggleExpandFilter(field, true);
|
|
6659
|
+
if (toggleFlip) toggleFlip();
|
|
6660
|
+
},
|
|
6661
|
+
"aria-pressed": !isFacetView,
|
|
6662
|
+
"aria-label": isFacetView ? 'Chart view' : 'Selection view',
|
|
6663
|
+
children: /*#__PURE__*/ jsx(MdFlip, {
|
|
6664
|
+
size: "1.45em",
|
|
6665
|
+
className: header.iconStyle,
|
|
6666
|
+
"aria-hidden": "true"
|
|
6667
|
+
})
|
|
6668
|
+
})
|
|
6669
|
+
}) : null,
|
|
6670
|
+
showClearSelection && /*#__PURE__*/ jsx(Tooltip, {
|
|
6671
|
+
label: "Clear selection",
|
|
6672
|
+
children: /*#__PURE__*/ jsx(FacetIconButton, {
|
|
6673
|
+
onClick: ()=>clearFilters(field),
|
|
6674
|
+
"aria-label": "clear selection",
|
|
6675
|
+
children: /*#__PURE__*/ jsx(FaUndo, {
|
|
6676
|
+
size: "1.0em",
|
|
6677
|
+
className: header.iconStyle,
|
|
6678
|
+
"aria-hidden": "true"
|
|
6679
|
+
})
|
|
6680
|
+
})
|
|
6681
|
+
}),
|
|
6682
|
+
dismissCallback ? /*#__PURE__*/ jsx(Tooltip, {
|
|
6683
|
+
label: "Remove the facet",
|
|
6684
|
+
children: /*#__PURE__*/ jsx(FacetIconButton, {
|
|
6685
|
+
onClick: ()=>{
|
|
6686
|
+
dismissCallback(field);
|
|
6687
|
+
},
|
|
6688
|
+
"aria-label": "Remove the facet",
|
|
6689
|
+
children: /*#__PURE__*/ jsx(MdClose, {
|
|
6690
|
+
size: "1.25em",
|
|
6691
|
+
className: header.iconStyle,
|
|
6692
|
+
"aria-hidden": "true"
|
|
6693
|
+
})
|
|
6694
|
+
})
|
|
6695
|
+
}) : null
|
|
6696
|
+
]
|
|
6697
|
+
})
|
|
6698
|
+
]
|
|
6567
6699
|
});
|
|
6568
6700
|
};
|
|
6569
6701
|
|
|
6570
6702
|
const DEFAULT_VISIBLE_ITEMS = 6;
|
|
6571
6703
|
const DEFAULT_MINIMUM = 0;
|
|
6572
6704
|
const DEFAULT_MAXIMUM = 100;
|
|
6705
|
+
const BAD_DATA_MESSAGE = 'No data for this field';
|
|
6573
6706
|
|
|
6574
6707
|
const sortTypeToAriaDescription = (sortTypeAndDirection, valueLabel, field)=>{
|
|
6575
6708
|
if (sortTypeAndDirection.type === 'alpha') {
|
|
@@ -6669,13 +6802,43 @@ const sortTypeToAriaDescription = (sortTypeAndDirection, valueLabel, field)=>{
|
|
|
6669
6802
|
});
|
|
6670
6803
|
};
|
|
6671
6804
|
|
|
6805
|
+
const OverflowTooltippedLabel = ({ children, label, className = 'flex-grow font-heading text-md pt-0.5' })=>{
|
|
6806
|
+
const [showTooltip, setShowTooltip] = useState(false);
|
|
6807
|
+
return /*#__PURE__*/ jsx(Tooltip, {
|
|
6808
|
+
label: label,
|
|
6809
|
+
disabled: !showTooltip,
|
|
6810
|
+
position: "top-start",
|
|
6811
|
+
offset: 5,
|
|
6812
|
+
multiline: true,
|
|
6813
|
+
withArrow: true,
|
|
6814
|
+
arrowOffset: 20,
|
|
6815
|
+
classNames: {
|
|
6816
|
+
tooltip: 'bg-base-min bg-opacity-90 text-base-contrast-min shadow-lg font-content font-medium text-xs',
|
|
6817
|
+
arrow: 'bg-base-min bg-opacity-90'
|
|
6818
|
+
},
|
|
6819
|
+
children: /*#__PURE__*/ jsx("div", {
|
|
6820
|
+
className: `${className} truncate ... `,
|
|
6821
|
+
ref: (el)=>{
|
|
6822
|
+
if (el) {
|
|
6823
|
+
if (el.clientWidth < el.scrollWidth) {
|
|
6824
|
+
setShowTooltip(true);
|
|
6825
|
+
} else {
|
|
6826
|
+
setShowTooltip(false);
|
|
6827
|
+
}
|
|
6828
|
+
}
|
|
6829
|
+
},
|
|
6830
|
+
children: children
|
|
6831
|
+
})
|
|
6832
|
+
});
|
|
6833
|
+
};
|
|
6834
|
+
|
|
6672
6835
|
const ExpanderLabel = tw.div`
|
|
6673
6836
|
text-accent-content-darker
|
|
6674
6837
|
p-1
|
|
6675
6838
|
font-bold
|
|
6676
6839
|
cursor-pointer
|
|
6677
6840
|
text-xs
|
|
6678
|
-
font-content
|
|
6841
|
+
font-content
|
|
6679
6842
|
`;
|
|
6680
6843
|
/**
|
|
6681
6844
|
* Component which manages the compact/expanded state of a FacetCard
|
|
@@ -6684,7 +6847,7 @@ font-content-noto
|
|
|
6684
6847
|
* @param onShowChanged - callback to call when the expand/compact button is clicked
|
|
6685
6848
|
*/ const FacetExpander = ({ remainingValues, isGroupExpanded, onShowChanged })=>{
|
|
6686
6849
|
return /*#__PURE__*/ jsx("div", {
|
|
6687
|
-
className:
|
|
6850
|
+
className: `mt-3 flex flex-row justify-end ${remainingValues > 0 && 'border-t-2'} p-1.5`,
|
|
6688
6851
|
children: remainingValues > 0 && !isGroupExpanded ? /*#__PURE__*/ jsx("button", {
|
|
6689
6852
|
onClick: ()=>onShowChanged(!isGroupExpanded),
|
|
6690
6853
|
"data-testid": "plus-icon",
|
|
@@ -6693,7 +6856,7 @@ font-content-noto
|
|
|
6693
6856
|
children: [
|
|
6694
6857
|
/*#__PURE__*/ jsx(MdAddCircle, {
|
|
6695
6858
|
className: "text-accent",
|
|
6696
|
-
size: "
|
|
6859
|
+
size: "1rem",
|
|
6697
6860
|
"aria-hidden": "true"
|
|
6698
6861
|
}, "show-more"),
|
|
6699
6862
|
/*#__PURE__*/ jsxs(ExpanderLabel, {
|
|
@@ -6712,7 +6875,7 @@ font-content-noto
|
|
|
6712
6875
|
children: [
|
|
6713
6876
|
/*#__PURE__*/ jsx(MdRemoveCircle, {
|
|
6714
6877
|
className: "text-accent",
|
|
6715
|
-
size: "
|
|
6878
|
+
size: "1rem",
|
|
6716
6879
|
onClick: ()=>onShowChanged(!isGroupExpanded),
|
|
6717
6880
|
"aria-hidden": "true"
|
|
6718
6881
|
}, "show-less"),
|
|
@@ -6725,35 +6888,32 @@ font-content-noto
|
|
|
6725
6888
|
});
|
|
6726
6889
|
};
|
|
6727
6890
|
|
|
6728
|
-
const
|
|
6729
|
-
Panel: FacetHeader,
|
|
6730
|
-
Label: FacetText,
|
|
6731
|
-
iconStyle: controlsIconStyle
|
|
6732
|
-
} })=>{
|
|
6891
|
+
const FacetEnumList = ({ field, facetName, hooks, valueLabel, isFacetView = true, isSearching = false, showPercent = false, hideIfEmpty = false, showSorting = true })=>{
|
|
6733
6892
|
const [isGroupExpanded, setIsGroupExpanded] = useState(false);
|
|
6734
|
-
const
|
|
6893
|
+
const cardRef = useRef(null);
|
|
6894
|
+
const searchInputRef = useRef(null);
|
|
6735
6895
|
const [searchTerm, setSearchTerm] = useState('');
|
|
6896
|
+
const { data, enumFilters, isSuccess, error } = hooks.useGetFacetData(field);
|
|
6897
|
+
const [selectedEnums, setSelectedEnums] = useState(enumFilters ?? []);
|
|
6898
|
+
const totalCount = hooks?.useTotalCounts ? hooks.useTotalCounts() : 1;
|
|
6899
|
+
const clearFilters = hooks.useClearFilter();
|
|
6900
|
+
const updateFacetFilters = hooks.useUpdateFacetFilters();
|
|
6901
|
+
const isFilterExpanded = hooks?.useFilterExpanded && hooks.useFilterExpanded(field);
|
|
6902
|
+
const showFilters = isFilterExpanded === undefined || isFilterExpanded;
|
|
6736
6903
|
const [sortedData, setSortedData] = useState({});
|
|
6737
6904
|
const [sortType, setSortType] = useState({
|
|
6738
6905
|
type: 'alpha',
|
|
6739
6906
|
direction: 'asc'
|
|
6740
6907
|
});
|
|
6741
|
-
const [isFacetView, setIsFacetView] = useState(startShowingData);
|
|
6742
|
-
const { data, enumFilters, isSuccess } = dataHooks.useGetFacetData(field);
|
|
6743
|
-
const cardRef = useRef(null);
|
|
6744
|
-
const [selectedEnums, setSelectedEnums] = useState(enumFilters ?? []);
|
|
6745
|
-
const searchInputRef = useRef(null);
|
|
6746
|
-
const totalCount = 1000;
|
|
6747
|
-
// TODO Determine if total count is needed
|
|
6748
|
-
// const totalCount = dataHooks.useTotalCounts();
|
|
6749
|
-
const clearFilters = dataHooks.useClearFilter();
|
|
6750
|
-
const updateFacetFilters = dataHooks.useUpdateFacetFilters();
|
|
6751
6908
|
useEffect(()=>{
|
|
6752
6909
|
if (isSearching) {
|
|
6753
6910
|
searchInputRef?.current?.focus();
|
|
6911
|
+
} else if (searchTerm.length > 0) {
|
|
6912
|
+
setSearchTerm('');
|
|
6754
6913
|
}
|
|
6755
6914
|
}, [
|
|
6756
|
-
isSearching
|
|
6915
|
+
isSearching,
|
|
6916
|
+
searchTerm
|
|
6757
6917
|
]);
|
|
6758
6918
|
useDeepCompareEffect(()=>{
|
|
6759
6919
|
setSelectedEnums(enumFilters ?? []);
|
|
@@ -6780,13 +6940,6 @@ const EnumFacet = ({ field, dataHooks, valueLabel, description, facetName, showP
|
|
|
6780
6940
|
updateFacetEnum(field, updated ?? [], updateFacetFilters, clearFilters);
|
|
6781
6941
|
}
|
|
6782
6942
|
};
|
|
6783
|
-
const toggleSearch = ()=>{
|
|
6784
|
-
setIsSearching(!isSearching);
|
|
6785
|
-
setSearchTerm('');
|
|
6786
|
-
};
|
|
6787
|
-
const toggleFlip = ()=>{
|
|
6788
|
-
setIsFacetView(!isFacetView);
|
|
6789
|
-
};
|
|
6790
6943
|
const [facetChartData, setFacetChartData] = useState({
|
|
6791
6944
|
filteredData: [],
|
|
6792
6945
|
filteredDataObj: {},
|
|
@@ -6799,9 +6952,9 @@ const EnumFacet = ({ field, dataHooks, valueLabel, description, facetName, showP
|
|
|
6799
6952
|
const calcCardStyle = useDeepCompareCallback((remainingValues)=>{
|
|
6800
6953
|
if (isGroupExpanded) {
|
|
6801
6954
|
const cardHeight = remainingValues > 16 ? 96 : remainingValues > 0 ? Math.min(96, remainingValues * 5 + 40) : 24;
|
|
6802
|
-
return `flex-none
|
|
6955
|
+
return `flex-none h-${cardHeight} overflow-y-scroll pl-3`;
|
|
6803
6956
|
} else {
|
|
6804
|
-
return 'overflow-hidden h-auto';
|
|
6957
|
+
return 'overflow-hidden h-auto mr-3 pl-3';
|
|
6805
6958
|
}
|
|
6806
6959
|
}, [
|
|
6807
6960
|
isGroupExpanded
|
|
@@ -6897,68 +7050,14 @@ const EnumFacet = ({ field, dataHooks, valueLabel, description, facetName, showP
|
|
|
6897
7050
|
return null; // nothing to render if visibleItems == 0
|
|
6898
7051
|
}
|
|
6899
7052
|
return /*#__PURE__*/ jsxs("div", {
|
|
6900
|
-
className:
|
|
6901
|
-
|
|
7053
|
+
className: showFilters ? 'h-full' : 'h-0 invisible',
|
|
7054
|
+
"aria-hidden": !showFilters,
|
|
6902
7055
|
children: [
|
|
6903
|
-
|
|
6904
|
-
|
|
6905
|
-
|
|
6906
|
-
|
|
6907
|
-
|
|
6908
|
-
position: "bottom-start",
|
|
6909
|
-
multiline: true,
|
|
6910
|
-
w: 220,
|
|
6911
|
-
withArrow: true,
|
|
6912
|
-
disabled: !description,
|
|
6913
|
-
children: /*#__PURE__*/ jsx(header.Label, {
|
|
6914
|
-
children: facetName ? facetName : fieldNameToTitle(field)
|
|
6915
|
-
})
|
|
6916
|
-
}),
|
|
6917
|
-
/*#__PURE__*/ jsxs("div", {
|
|
6918
|
-
className: "flex flex-row",
|
|
6919
|
-
children: [
|
|
6920
|
-
showSearch ? /*#__PURE__*/ jsx(FacetIconButton, {
|
|
6921
|
-
onClick: toggleSearch,
|
|
6922
|
-
"aria-label": "Search",
|
|
6923
|
-
children: /*#__PURE__*/ jsx(MdSearch, {
|
|
6924
|
-
size: "1.45em",
|
|
6925
|
-
className: header.iconStyle
|
|
6926
|
-
})
|
|
6927
|
-
}) : null,
|
|
6928
|
-
showFlip ? /*#__PURE__*/ jsx(FacetIconButton, {
|
|
6929
|
-
onClick: toggleFlip,
|
|
6930
|
-
"aria-label": "Flip between form and chart",
|
|
6931
|
-
children: /*#__PURE__*/ jsx(MdFlip, {
|
|
6932
|
-
size: "1.45em",
|
|
6933
|
-
className: header.iconStyle
|
|
6934
|
-
})
|
|
6935
|
-
}) : null,
|
|
6936
|
-
/*#__PURE__*/ jsx(FacetIconButton, {
|
|
6937
|
-
onClick: ()=>clearFilters(field),
|
|
6938
|
-
"aria-label": "clear selection",
|
|
6939
|
-
children: /*#__PURE__*/ jsx(FaUndo, {
|
|
6940
|
-
size: "1.25em",
|
|
6941
|
-
className: header.iconStyle
|
|
6942
|
-
})
|
|
6943
|
-
}),
|
|
6944
|
-
dismissCallback ? /*#__PURE__*/ jsx(FacetIconButton, {
|
|
6945
|
-
onClick: ()=>{
|
|
6946
|
-
clearFilters(field);
|
|
6947
|
-
dismissCallback(field);
|
|
6948
|
-
},
|
|
6949
|
-
"aria-label": "Remove the facet",
|
|
6950
|
-
children: /*#__PURE__*/ jsx(MdClose, {
|
|
6951
|
-
size: "1.25em",
|
|
6952
|
-
className: header.iconStyle
|
|
6953
|
-
})
|
|
6954
|
-
}) : null
|
|
6955
|
-
]
|
|
6956
|
-
})
|
|
6957
|
-
]
|
|
6958
|
-
})
|
|
6959
|
-
}),
|
|
6960
|
-
/*#__PURE__*/ jsxs("div", {
|
|
6961
|
-
className: "h-full",
|
|
7056
|
+
' ',
|
|
7057
|
+
isSuccess && error ? /*#__PURE__*/ jsx("div", {
|
|
7058
|
+
className: "m-4 font-content pb-2",
|
|
7059
|
+
children: BAD_DATA_MESSAGE
|
|
7060
|
+
}) : /*#__PURE__*/ jsxs(Fragment, {
|
|
6962
7061
|
children: [
|
|
6963
7062
|
isSearching && /*#__PURE__*/ jsx(TextInput, {
|
|
6964
7063
|
value: searchTerm,
|
|
@@ -6984,12 +7083,12 @@ const EnumFacet = ({ field, dataHooks, valueLabel, description, facetName, showP
|
|
|
6984
7083
|
children: [
|
|
6985
7084
|
/*#__PURE__*/ jsxs("div", {
|
|
6986
7085
|
children: [
|
|
6987
|
-
/*#__PURE__*/ jsx(FacetSortPanel, {
|
|
7086
|
+
showSorting ? /*#__PURE__*/ jsx(FacetSortPanel, {
|
|
6988
7087
|
sortType: sortType,
|
|
6989
7088
|
valueLabel: valueLabel,
|
|
6990
7089
|
setSort: setSortType,
|
|
6991
7090
|
field: facetName ? facetName : fieldNameToTitle(field)
|
|
6992
|
-
}),
|
|
7091
|
+
}) : false,
|
|
6993
7092
|
/*#__PURE__*/ jsxs("div", {
|
|
6994
7093
|
className: facetChartData.cardStyle,
|
|
6995
7094
|
role: "group",
|
|
@@ -7000,14 +7099,14 @@ const EnumFacet = ({ field, dataHooks, valueLabel, description, facetName, showP
|
|
|
7000
7099
|
"data-testid": "loading-spinner"
|
|
7001
7100
|
}),
|
|
7002
7101
|
facetChartData.filteredData.length == 0 ? /*#__PURE__*/ jsx("div", {
|
|
7003
|
-
className: "mx-4 font-content",
|
|
7004
|
-
children:
|
|
7102
|
+
className: "mx-4 font-content text-sm",
|
|
7103
|
+
children: BAD_DATA_MESSAGE
|
|
7005
7104
|
}) : isSuccess ? !sortedData || Object.entries(sortedData).length === 0 ? /*#__PURE__*/ jsx("div", {
|
|
7006
7105
|
className: "mx-4",
|
|
7007
7106
|
children: "No results found"
|
|
7008
7107
|
}) : Object.entries(sortedData ?? {}).map(([value, count])=>{
|
|
7009
7108
|
return /*#__PURE__*/ jsxs("div", {
|
|
7010
|
-
className: "flex flex-row items-center gap-x-1
|
|
7109
|
+
className: "flex flex-row items-center gap-x-1",
|
|
7011
7110
|
children: [
|
|
7012
7111
|
/*#__PURE__*/ jsx("div", {
|
|
7013
7112
|
className: "flex-none",
|
|
@@ -7015,11 +7114,12 @@ const EnumFacet = ({ field, dataHooks, valueLabel, description, facetName, showP
|
|
|
7015
7114
|
"data-testid": `checkbox-${value}`,
|
|
7016
7115
|
value: value,
|
|
7017
7116
|
size: "xs",
|
|
7018
|
-
color: "accent",
|
|
7117
|
+
color: "accent.4",
|
|
7019
7118
|
onChange: (e)=>handleChange(e.currentTarget.value, e.currentTarget.checked),
|
|
7020
7119
|
"aria-label": `${value}`,
|
|
7021
7120
|
classNames: {
|
|
7022
|
-
input: '
|
|
7121
|
+
input: 'hover:bg-accent-darker',
|
|
7122
|
+
label: 'text-xs font-normal font-content'
|
|
7023
7123
|
},
|
|
7024
7124
|
checked: selectedEnums && selectedEnums.includes(value)
|
|
7025
7125
|
})
|
|
@@ -7027,16 +7127,16 @@ const EnumFacet = ({ field, dataHooks, valueLabel, description, facetName, showP
|
|
|
7027
7127
|
/*#__PURE__*/ jsx(OverflowTooltippedLabel, {
|
|
7028
7128
|
label: value,
|
|
7029
7129
|
children: /*#__PURE__*/ jsx("span", {
|
|
7030
|
-
className: "font-content",
|
|
7130
|
+
className: "text-xs font-normal font-content",
|
|
7031
7131
|
children: value
|
|
7032
7132
|
})
|
|
7033
7133
|
}),
|
|
7034
7134
|
/*#__PURE__*/ jsx("div", {
|
|
7035
|
-
className: "flex-none text-right w-14 font-content",
|
|
7135
|
+
className: "flex-none text-right w-14 text-xs font-normal font-content",
|
|
7036
7136
|
children: count.toLocaleString()
|
|
7037
7137
|
}),
|
|
7038
7138
|
showPercent ? /*#__PURE__*/ jsxs("div", {
|
|
7039
|
-
className: "flex-none text-right w-18 font-content",
|
|
7139
|
+
className: "flex-none text-right w-18 text-xs font-normal font-content",
|
|
7040
7140
|
children: [
|
|
7041
7141
|
"(",
|
|
7042
7142
|
(count / totalCount * 100).toFixed(2),
|
|
@@ -7055,6 +7155,7 @@ const EnumFacet = ({ field, dataHooks, valueLabel, description, facetName, showP
|
|
|
7055
7155
|
className: "flex-none",
|
|
7056
7156
|
children: /*#__PURE__*/ jsx(Checkbox, {
|
|
7057
7157
|
size: "xs",
|
|
7158
|
+
radius: "xs",
|
|
7058
7159
|
className: "bg-base-lightest text-primary-contrast-lightest hover:bg-base-darkest hover:text-base-contrast-darkest"
|
|
7059
7160
|
})
|
|
7060
7161
|
}),
|
|
@@ -7072,11 +7173,11 @@ const EnumFacet = ({ field, dataHooks, valueLabel, description, facetName, showP
|
|
|
7072
7173
|
})
|
|
7073
7174
|
]
|
|
7074
7175
|
}),
|
|
7075
|
-
/*#__PURE__*/ jsx(FacetExpander, {
|
|
7176
|
+
facetChartData.remainingValues > 0 ? /*#__PURE__*/ jsx(FacetExpander, {
|
|
7076
7177
|
remainingValues: facetChartData.remainingValues,
|
|
7077
7178
|
isGroupExpanded: isGroupExpanded,
|
|
7078
7179
|
onShowChanged: setIsGroupExpanded
|
|
7079
|
-
})
|
|
7180
|
+
}) : null
|
|
7080
7181
|
]
|
|
7081
7182
|
}),
|
|
7082
7183
|
/*#__PURE__*/ jsx("div", {
|
|
@@ -7103,6 +7204,52 @@ const EnumFacet = ({ field, dataHooks, valueLabel, description, facetName, showP
|
|
|
7103
7204
|
});
|
|
7104
7205
|
};
|
|
7105
7206
|
|
|
7207
|
+
const EnumFacet = ({ field, hooks, valueLabel, description, facetName, showPercent = true, hideIfEmpty = true, showSearch = true, showFlip = false, startShowingData = true, dismissCallback = undefined, width = undefined, header = {
|
|
7208
|
+
Panel: FacetHeader,
|
|
7209
|
+
Label: FacetText,
|
|
7210
|
+
iconStyle: controlsIconStyle
|
|
7211
|
+
} })=>{
|
|
7212
|
+
const [isSearching, setIsSearching] = useState(false);
|
|
7213
|
+
const [isFacetView, setIsFacetView] = useState(startShowingData);
|
|
7214
|
+
const toggleSearch = ()=>{
|
|
7215
|
+
setIsSearching(!isSearching);
|
|
7216
|
+
};
|
|
7217
|
+
const toggleFlip = ()=>{
|
|
7218
|
+
setIsFacetView(!isFacetView);
|
|
7219
|
+
};
|
|
7220
|
+
return /*#__PURE__*/ jsxs("div", {
|
|
7221
|
+
className: `flex flex-col ${width ? width : 'mx-1'} bg-base-max relative shadow-lg border-base-lighter border-1 rounded-b-md text-xs transition`,
|
|
7222
|
+
id: field,
|
|
7223
|
+
children: [
|
|
7224
|
+
/*#__PURE__*/ jsx("div", {
|
|
7225
|
+
children: /*#__PURE__*/ jsx(FacetControlsHeader, {
|
|
7226
|
+
field: field,
|
|
7227
|
+
description: description,
|
|
7228
|
+
hooks: hooks,
|
|
7229
|
+
facetName: facetName,
|
|
7230
|
+
showSearch: showSearch,
|
|
7231
|
+
showFlip: showFlip,
|
|
7232
|
+
isFacetView: isFacetView,
|
|
7233
|
+
toggleFlip: toggleFlip,
|
|
7234
|
+
toggleSearch: toggleSearch,
|
|
7235
|
+
dismissCallback: dismissCallback,
|
|
7236
|
+
header: header
|
|
7237
|
+
})
|
|
7238
|
+
}),
|
|
7239
|
+
/*#__PURE__*/ jsx(FacetEnumList, {
|
|
7240
|
+
field: field,
|
|
7241
|
+
facetName: facetName,
|
|
7242
|
+
valueLabel: valueLabel,
|
|
7243
|
+
hooks: hooks,
|
|
7244
|
+
isFacetView: isFacetView,
|
|
7245
|
+
isSearching: isSearching,
|
|
7246
|
+
hideIfEmpty: hideIfEmpty,
|
|
7247
|
+
showPercent: showPercent
|
|
7248
|
+
})
|
|
7249
|
+
]
|
|
7250
|
+
});
|
|
7251
|
+
};
|
|
7252
|
+
|
|
7106
7253
|
const createBucket = (field, lower, upper)=>({
|
|
7107
7254
|
operator: 'and',
|
|
7108
7255
|
operands: [
|
|
@@ -7118,17 +7265,17 @@ const createBucket = (field, lower, upper)=>({
|
|
|
7118
7265
|
}
|
|
7119
7266
|
]
|
|
7120
7267
|
});
|
|
7121
|
-
const RangeFacet = ({ field,
|
|
7268
|
+
const RangeFacet = ({ field, hooks, valueLabel, description, facetName, minimum = DEFAULT_MINIMUM, maximum = DEFAULT_MAXIMUM, showPercent = true, hideIfEmpty = true, showSearch = true, showFlip = true, startShowingData = true, dismissCallback = undefined, width = undefined, header = {
|
|
7122
7269
|
Panel: FacetHeader,
|
|
7123
7270
|
Label: FacetText,
|
|
7124
7271
|
iconStyle: controlsIconStyle
|
|
7125
7272
|
} })=>{
|
|
7126
|
-
const { data, rangeFilters, isSuccess } =
|
|
7273
|
+
const { data, rangeFilters, isSuccess } = hooks.useGetFacetData(field);
|
|
7127
7274
|
const [minMaxValue, setMinMaxValue] = React__default.useState({
|
|
7128
7275
|
from: minimum,
|
|
7129
7276
|
to: maximum
|
|
7130
7277
|
});
|
|
7131
|
-
const clearRangeFilterFromCohort =
|
|
7278
|
+
const clearRangeFilterFromCohort = hooks.useClearFilter();
|
|
7132
7279
|
const clearFilters = useCallback(()=>{
|
|
7133
7280
|
setMinMaxValue({
|
|
7134
7281
|
from: minimum,
|
|
@@ -7141,7 +7288,7 @@ const RangeFacet = ({ field, dataHooks, valueLabel, description, facetName, mini
|
|
|
7141
7288
|
maximum,
|
|
7142
7289
|
minimum
|
|
7143
7290
|
]);
|
|
7144
|
-
const updateRangeFilter =
|
|
7291
|
+
const updateRangeFilter = hooks.useUpdateFacetFilters();
|
|
7145
7292
|
const updateFilters = useCallback((from, to)=>{
|
|
7146
7293
|
updateRangeFilter(field, createBucket(field, from, to));
|
|
7147
7294
|
setMinMaxValue({
|
|
@@ -7275,13 +7422,13 @@ const instanceOfIncludesExcludes$1 = (op)=>[
|
|
|
7275
7422
|
* @param width - width of the facet
|
|
7276
7423
|
* @param hooks - hooks to use for the facet
|
|
7277
7424
|
* @category Facets
|
|
7278
|
-
*/ const MultiSelectValueFacet = ({ field, description, facetName = undefined, dismissCallback = undefined, width = undefined,
|
|
7425
|
+
*/ const MultiSelectValueFacet = ({ field, description, facetName = undefined, dismissCallback = undefined, width = undefined, hooks })=>{
|
|
7279
7426
|
const [selectedValues, setSelectedValues] = useState([]); // Handle the state of the TextInput
|
|
7280
|
-
const clearFilters =
|
|
7281
|
-
const updateFacetFilters =
|
|
7427
|
+
const clearFilters = hooks.useClearFilter();
|
|
7428
|
+
const updateFacetFilters = hooks.useUpdateFacetFilters();
|
|
7282
7429
|
const facetTitle = facetName ? facetName : trimFirstFieldNameToTitle(field, true);
|
|
7283
|
-
const facetValue =
|
|
7284
|
-
const facetDataValues =
|
|
7430
|
+
const facetValue = hooks.useGetFacetFilters(field);
|
|
7431
|
+
const facetDataValues = hooks.useGetFacetData(field);
|
|
7285
7432
|
const dataValues = useMemo(()=>{
|
|
7286
7433
|
if (facetDataValues?.data) {
|
|
7287
7434
|
return Object.keys(facetDataValues.data).map((key)=>{
|
|
@@ -7426,12 +7573,12 @@ const instanceOfIncludesExcludes = (op)=>[
|
|
|
7426
7573
|
* @param width - width of the facet
|
|
7427
7574
|
* @param hooks - hooks to use for the facet
|
|
7428
7575
|
* @category Facets
|
|
7429
|
-
*/ const ExactValueFacet = ({ field, description, facetName = undefined, dismissCallback = undefined, width = undefined,
|
|
7576
|
+
*/ const ExactValueFacet = ({ field, description, facetName = undefined, dismissCallback = undefined, width = undefined, hooks })=>{
|
|
7430
7577
|
const [textValue, setTextValue] = useState(''); // Handle the state of the TextInput
|
|
7431
|
-
const clearFilters =
|
|
7432
|
-
const updateFacetFilters =
|
|
7578
|
+
const clearFilters = hooks.useClearFilter();
|
|
7579
|
+
const updateFacetFilters = hooks.useUpdateFacetFilters();
|
|
7433
7580
|
const facetTitle = facetName ? facetName : trimFirstFieldNameToTitle(field, true);
|
|
7434
|
-
const facetValue =
|
|
7581
|
+
const facetValue = hooks.useGetFacetFilters(field);
|
|
7435
7582
|
const textValues = useMemo(()=>extractValues(facetValue), [
|
|
7436
7583
|
facetValue
|
|
7437
7584
|
]);
|
|
@@ -7582,7 +7729,7 @@ const createFacetCard = (facetDefinition, valueLabel, dataFunctions, idPrefix, d
|
|
|
7582
7729
|
description: description,
|
|
7583
7730
|
hideIfEmpty: hideIfEmpty,
|
|
7584
7731
|
width: width,
|
|
7585
|
-
|
|
7732
|
+
hooks: dataFunctions,
|
|
7586
7733
|
showPercent: false
|
|
7587
7734
|
}, `${idPrefix}-enum-${field}`),
|
|
7588
7735
|
range: /*#__PURE__*/ jsx(RangeFacet, {
|
|
@@ -7592,7 +7739,7 @@ const createFacetCard = (facetDefinition, valueLabel, dataFunctions, idPrefix, d
|
|
|
7592
7739
|
description: description,
|
|
7593
7740
|
hideIfEmpty: hideIfEmpty,
|
|
7594
7741
|
width: width,
|
|
7595
|
-
|
|
7742
|
+
hooks: dataFunctions,
|
|
7596
7743
|
minimum: facetDefinition.range?.minimum,
|
|
7597
7744
|
maximum: facetDefinition.range?.maximum
|
|
7598
7745
|
}, `${idPrefix}-range-${field}`),
|
|
@@ -7602,7 +7749,7 @@ const createFacetCard = (facetDefinition, valueLabel, dataFunctions, idPrefix, d
|
|
|
7602
7749
|
description: description,
|
|
7603
7750
|
hideIfEmpty: hideIfEmpty,
|
|
7604
7751
|
width: width,
|
|
7605
|
-
|
|
7752
|
+
hooks: dataFunctions
|
|
7606
7753
|
}, `${idPrefix}-exact-${field}`),
|
|
7607
7754
|
multiselect: /*#__PURE__*/ jsx(MultiSelectValueFacet, {
|
|
7608
7755
|
field: field,
|
|
@@ -7610,7 +7757,7 @@ const createFacetCard = (facetDefinition, valueLabel, dataFunctions, idPrefix, d
|
|
|
7610
7757
|
description: description,
|
|
7611
7758
|
hideIfEmpty: hideIfEmpty,
|
|
7612
7759
|
width: width,
|
|
7613
|
-
|
|
7760
|
+
hooks: dataFunctions
|
|
7614
7761
|
}, `${idPrefix}-exact-${field}`)
|
|
7615
7762
|
}[type]
|
|
7616
7763
|
}, `${idPrefix}-enum-${field}`);
|
|
@@ -7661,7 +7808,7 @@ const QueryFieldLabel = tw.div`
|
|
|
7661
7808
|
bg-accent-cool-lightest
|
|
7662
7809
|
text-base-darkest
|
|
7663
7810
|
uppercase
|
|
7664
|
-
px-1
|
|
7811
|
+
px-2 pl-1
|
|
7665
7812
|
border-primary-darkest
|
|
7666
7813
|
border-r-[1.5px]
|
|
7667
7814
|
flex
|
|
@@ -7762,7 +7909,7 @@ const IncludeExcludeQueryElement = ({ index, field, path, operator, operands })=
|
|
|
7762
7909
|
color: "accent.5",
|
|
7763
7910
|
size: "md",
|
|
7764
7911
|
pr: 0,
|
|
7765
|
-
className: "normal-case items-center max-w-[162px] cursor-pointer pl-
|
|
7912
|
+
className: "normal-case items-center max-w-[162px] cursor-pointer pl-2 pr-0 hover:bg-accent-darker",
|
|
7766
7913
|
rightSection: /*#__PURE__*/ jsx(RemoveButton, {
|
|
7767
7914
|
value: value
|
|
7768
7915
|
}),
|
|
@@ -8207,7 +8354,7 @@ const QueryExpressionSection = ({ index, filters, currentCohortName, currentCoho
|
|
|
8207
8354
|
setExpandedState
|
|
8208
8355
|
],
|
|
8209
8356
|
children: /*#__PURE__*/ jsxs("div", {
|
|
8210
|
-
className: "flex flex-col w-full bg-primary",
|
|
8357
|
+
className: "flex flex-col w-full bg-primary-lighter",
|
|
8211
8358
|
children: [
|
|
8212
8359
|
/*#__PURE__*/ jsxs("div", {
|
|
8213
8360
|
"data-testid": "text-cohort-filters-top-row",
|
|
@@ -8444,12 +8591,12 @@ const LinkCellFunctionCatalog = {
|
|
|
8444
8591
|
default: RenderLinkCell,
|
|
8445
8592
|
linkWithValueMap: RenderLinkCellUsingValueMap
|
|
8446
8593
|
};
|
|
8447
|
-
let instance$
|
|
8594
|
+
let instance$2;
|
|
8448
8595
|
const ExplorerTableCellRendererFactory = ()=>{
|
|
8449
|
-
if (!instance$
|
|
8450
|
-
instance$
|
|
8596
|
+
if (!instance$2) {
|
|
8597
|
+
instance$2 = new RenderFactoryTypedInstance();
|
|
8451
8598
|
}
|
|
8452
|
-
return instance$
|
|
8599
|
+
return instance$2;
|
|
8453
8600
|
};
|
|
8454
8601
|
// register default cell renderers
|
|
8455
8602
|
const registerExplorerDefaultCellRenderers = ()=>{
|
|
@@ -8603,21 +8750,21 @@ const RowTableDetailsPanel = ({ row })=>{
|
|
|
8603
8750
|
});
|
|
8604
8751
|
};
|
|
8605
8752
|
|
|
8606
|
-
let instance;
|
|
8607
|
-
const DefaultRendererCatalog = {
|
|
8753
|
+
let instance$1;
|
|
8754
|
+
const DefaultRendererCatalog$1 = {
|
|
8608
8755
|
tableDetails: {
|
|
8609
8756
|
default: RowTableDetailsPanel,
|
|
8610
8757
|
queryRowDetails: QueryRowDetailsPanel
|
|
8611
8758
|
}
|
|
8612
8759
|
};
|
|
8613
8760
|
const ExplorerTableDetailsPanelFactory = ()=>{
|
|
8614
|
-
if (!instance) {
|
|
8615
|
-
instance = new RenderFactoryTypedInstance();
|
|
8761
|
+
if (!instance$1) {
|
|
8762
|
+
instance$1 = new RenderFactoryTypedInstance();
|
|
8616
8763
|
}
|
|
8617
|
-
return instance;
|
|
8764
|
+
return instance$1;
|
|
8618
8765
|
};
|
|
8619
8766
|
const registerCohortBuilderDefaultPreviewRenderers = ()=>{
|
|
8620
|
-
ExplorerTableDetailsPanelFactory().registerRendererCatalog(DefaultRendererCatalog);
|
|
8767
|
+
ExplorerTableDetailsPanelFactory().registerRendererCatalog(DefaultRendererCatalog$1);
|
|
8621
8768
|
};
|
|
8622
8769
|
|
|
8623
8770
|
const DEFAULT_PROPS = {
|
|
@@ -8857,7 +9004,7 @@ const CountsValue = ({ label, isSuccess, counts })=>{
|
|
|
8857
9004
|
shadow: "xs",
|
|
8858
9005
|
p: "xs",
|
|
8859
9006
|
withBorder: true,
|
|
8860
|
-
className: "bg-primary font-heading text-md font-semibold",
|
|
9007
|
+
className: "bg-primary text-primary-contrast font-heading text-md font-semibold",
|
|
8861
9008
|
children: `${counts?.toLocaleString() ?? '...'} ${label}`
|
|
8862
9009
|
})
|
|
8863
9010
|
]
|
|
@@ -9595,7 +9742,7 @@ const SinglePanel = ({ filters, tabTitle, facetDefinitions, facetDataHooks })=>{
|
|
|
9595
9742
|
...acc
|
|
9596
9743
|
};
|
|
9597
9744
|
}, {});
|
|
9598
|
-
const facetDefs = classifyFacets(data, index, guppyConfig
|
|
9745
|
+
const facetDefs = classifyFacets(data, index, guppyConfig?.fieldMapping ?? [], configFacetDefs ?? {});
|
|
9599
9746
|
setFacetDefinitions(facetDefs);
|
|
9600
9747
|
// setup summary charts since nested fields can be listed by the split field name
|
|
9601
9748
|
const summaryCharts = Object.keys(charts).reduce((acc, field)=>{
|
|
@@ -9669,14 +9816,13 @@ const SinglePanel = ({ filters, tabTitle, facetDefinitions, facetDataHooks })=>{
|
|
|
9669
9816
|
filter: cohortFilters
|
|
9670
9817
|
}),
|
|
9671
9818
|
/*#__PURE__*/ jsx(CountsValue, {
|
|
9672
|
-
label: guppyConfig
|
|
9819
|
+
label: guppyConfig?.nodeCountTitle || toDisplayName(index),
|
|
9673
9820
|
counts: counts,
|
|
9674
9821
|
isSuccess: isCountSuccess
|
|
9675
9822
|
})
|
|
9676
9823
|
]
|
|
9677
9824
|
}),
|
|
9678
9825
|
/*#__PURE__*/ jsx(Charts, {
|
|
9679
|
-
index: index,
|
|
9680
9826
|
charts: summaryCharts,
|
|
9681
9827
|
data: data ?? EmptyData,
|
|
9682
9828
|
counts: counts,
|
|
@@ -9781,88 +9927,1701 @@ const CohortBuilder = ({ explorerConfig })=>{
|
|
|
9781
9927
|
});
|
|
9782
9928
|
};
|
|
9783
9929
|
|
|
9784
|
-
var GqlQueryEditor$2 = /*#__PURE__*/Object.freeze({
|
|
9785
|
-
__proto__: null,
|
|
9786
|
-
default: GqlQueryEditor$1
|
|
9787
|
-
});
|
|
9930
|
+
var GqlQueryEditor$2 = /*#__PURE__*/Object.freeze({
|
|
9931
|
+
__proto__: null,
|
|
9932
|
+
default: GqlQueryEditor$1
|
|
9933
|
+
});
|
|
9934
|
+
|
|
9935
|
+
const WorkspacesPanel = ()=>{
|
|
9936
|
+
return /*#__PURE__*/ jsx(Center, {
|
|
9937
|
+
className: "m-20 w-full",
|
|
9938
|
+
children: /*#__PURE__*/ jsx(Text, {
|
|
9939
|
+
size: "2rem",
|
|
9940
|
+
children: "Coming soon."
|
|
9941
|
+
})
|
|
9942
|
+
});
|
|
9943
|
+
};
|
|
9944
|
+
|
|
9945
|
+
class FilesystemContent {
|
|
9946
|
+
constructor({ rootPath }){
|
|
9947
|
+
this.rootPath = rootPath || '';
|
|
9948
|
+
}
|
|
9949
|
+
async get(filepath) {
|
|
9950
|
+
try {
|
|
9951
|
+
return await JSON.parse(fs.readFileSync(path.join(this.rootPath, filepath)).toString('utf-8'));
|
|
9952
|
+
} catch (err) {
|
|
9953
|
+
throw new Error(`Cannot process ${filepath}`);
|
|
9954
|
+
}
|
|
9955
|
+
}
|
|
9956
|
+
}
|
|
9957
|
+
|
|
9958
|
+
class ContentDatabase {
|
|
9959
|
+
constructor(config){
|
|
9960
|
+
this.config = config;
|
|
9961
|
+
this.store = config.store;
|
|
9962
|
+
}
|
|
9963
|
+
async get(filepath) {
|
|
9964
|
+
return this.store.get(filepath);
|
|
9965
|
+
}
|
|
9966
|
+
}
|
|
9967
|
+
|
|
9968
|
+
const GEN3_FRONTEND_CONFIGURATION_ROOT = process.env.GEN3_FRONTEND_CONFIGURATION_ROOT || './';
|
|
9969
|
+
|
|
9970
|
+
const ContentRoot = GEN3_FRONTEND_CONFIGURATION_ROOT;
|
|
9971
|
+
const setup = ()=>{
|
|
9972
|
+
const config = {
|
|
9973
|
+
store: new FilesystemContent({
|
|
9974
|
+
rootPath: ContentRoot
|
|
9975
|
+
})
|
|
9976
|
+
};
|
|
9977
|
+
return new ContentDatabase(config);
|
|
9978
|
+
};
|
|
9979
|
+
const ContentSource = setup();
|
|
9980
|
+
|
|
9981
|
+
/**
|
|
9982
|
+
* Retrieves navigation page layout properties from configuration.
|
|
9983
|
+
* Note: GEN3_COMMONS_NAME depends on siteConfig.json value in the data commons package
|
|
9984
|
+
* @returns A Promise resolving to an object containing header and footer props.
|
|
9985
|
+
*/ const getNavPageLayoutPropsFromConfig = async ()=>{
|
|
9986
|
+
const navigationConfigJSON = await ContentSource.get(`config/${GEN3_COMMONS_NAME}/navigation.json`);
|
|
9987
|
+
let bannerConfigJSON = [];
|
|
9988
|
+
try {
|
|
9989
|
+
bannerConfigJSON = await ContentSource.get(`config/${GEN3_COMMONS_NAME}/banner.json`);
|
|
9990
|
+
} catch (e) {
|
|
9991
|
+
console.warn('No banner config found at: ', `config/${GEN3_COMMONS_NAME}/banner.json`);
|
|
9992
|
+
}
|
|
9993
|
+
const { topBar, navigation, type = 'original' } = navigationConfigJSON;
|
|
9994
|
+
const headerProps = {
|
|
9995
|
+
top: topBar,
|
|
9996
|
+
navigation: navigation,
|
|
9997
|
+
banners: bannerConfigJSON,
|
|
9998
|
+
type
|
|
9999
|
+
};
|
|
10000
|
+
const footerProps = await ContentSource.get(`config/${GEN3_COMMONS_NAME}/footer.json`);
|
|
10001
|
+
return {
|
|
10002
|
+
headerProps,
|
|
10003
|
+
footerProps,
|
|
10004
|
+
headerData: {
|
|
10005
|
+
title: 'Gen3 Frontend Framework Page',
|
|
10006
|
+
content: 'Gen3 Frontend Framework Page',
|
|
10007
|
+
key: 'gen3-common-page'
|
|
10008
|
+
}
|
|
10009
|
+
};
|
|
10010
|
+
};
|
|
10011
|
+
|
|
10012
|
+
const FacetSelector = ({ category, facetName, hooks, width = 'w-full', description, fields, selectedFields, updateSelectedField, showSearch = true, header = {
|
|
10013
|
+
Panel: FacetHeader,
|
|
10014
|
+
Label: FacetText,
|
|
10015
|
+
iconStyle: controlsIconStyle
|
|
10016
|
+
} })=>{
|
|
10017
|
+
const [isGroupExpanded, setIsGroupExpanded] = useState(false);
|
|
10018
|
+
const [isSearching, setIsSearching] = useState(false);
|
|
10019
|
+
const [searchTerm, setSearchTerm] = useState('');
|
|
10020
|
+
const cardRef = useRef(null);
|
|
10021
|
+
const isFilterExpanded = hooks.useFilterExpanded && hooks.useFilterExpanded(category);
|
|
10022
|
+
const showFilters = isFilterExpanded === undefined || isFilterExpanded;
|
|
10023
|
+
const searchInputRef = useRef(null);
|
|
10024
|
+
const toggleSearch = ()=>{
|
|
10025
|
+
setIsSearching(!isSearching);
|
|
10026
|
+
setSearchTerm('');
|
|
10027
|
+
};
|
|
10028
|
+
useEffect(()=>{
|
|
10029
|
+
if (isSearching) {
|
|
10030
|
+
searchInputRef?.current?.focus();
|
|
10031
|
+
}
|
|
10032
|
+
}, [
|
|
10033
|
+
isSearching
|
|
10034
|
+
]);
|
|
10035
|
+
const filteredFields = useDeepCompareMemo(()=>{
|
|
10036
|
+
if (!searchTerm) return fields;
|
|
10037
|
+
return fields.filter((f)=>f.description?.toLowerCase().includes(searchTerm.toLowerCase()) || toDisplayName(f?.label ?? f.field).toLowerCase().includes(searchTerm.toLowerCase()));
|
|
10038
|
+
}, [
|
|
10039
|
+
searchTerm,
|
|
10040
|
+
fields
|
|
10041
|
+
]);
|
|
10042
|
+
const remainingValues = filteredFields.length - DEFAULT_VISIBLE_ITEMS;
|
|
10043
|
+
return /*#__PURE__*/ jsxs("div", {
|
|
10044
|
+
className: `flex flex-col ${width ? width : 'mx-1'} bg-base-max relative border-base-light border-1 rounded-b-md transition`,
|
|
10045
|
+
id: category,
|
|
10046
|
+
children: [
|
|
10047
|
+
/*#__PURE__*/ jsx("div", {
|
|
10048
|
+
children: /*#__PURE__*/ jsx(FacetControlsHeader, {
|
|
10049
|
+
field: category,
|
|
10050
|
+
description: description,
|
|
10051
|
+
hooks: hooks,
|
|
10052
|
+
facetName: facetName,
|
|
10053
|
+
showSearch: showSearch,
|
|
10054
|
+
toggleSearch: toggleSearch,
|
|
10055
|
+
header: header
|
|
10056
|
+
})
|
|
10057
|
+
}),
|
|
10058
|
+
/*#__PURE__*/ jsx("div", {
|
|
10059
|
+
className: showFilters ? 'h-full' : 'h-0 invisible',
|
|
10060
|
+
"aria-hidden": !showFilters,
|
|
10061
|
+
children: /*#__PURE__*/ jsxs(Fragment, {
|
|
10062
|
+
children: [
|
|
10063
|
+
isSearching && /*#__PURE__*/ jsx(TextInput, {
|
|
10064
|
+
"data-testid": "textbox-search-values",
|
|
10065
|
+
value: searchTerm,
|
|
10066
|
+
onChange: (e)=>setSearchTerm(e.target.value),
|
|
10067
|
+
"aria-label": `category ${facetName}`,
|
|
10068
|
+
className: 'p-2',
|
|
10069
|
+
placeholder: "Search",
|
|
10070
|
+
ref: searchInputRef,
|
|
10071
|
+
rightSection: searchTerm.length > 0 && /*#__PURE__*/ jsx(ActionIcon, {
|
|
10072
|
+
onClick: ()=>{
|
|
10073
|
+
setSearchTerm('');
|
|
10074
|
+
searchInputRef?.current?.focus();
|
|
10075
|
+
},
|
|
10076
|
+
className: "border-0",
|
|
10077
|
+
children: /*#__PURE__*/ jsx(MdClose, {
|
|
10078
|
+
"aria-label": "clear search"
|
|
10079
|
+
})
|
|
10080
|
+
}),
|
|
10081
|
+
role: "search"
|
|
10082
|
+
}),
|
|
10083
|
+
/*#__PURE__*/ jsxs("div", {
|
|
10084
|
+
className: "flip-card",
|
|
10085
|
+
ref: cardRef,
|
|
10086
|
+
children: [
|
|
10087
|
+
/*#__PURE__*/ jsx("div", {
|
|
10088
|
+
className: "card-face bg-base-max rounded-b-xs flex flex-col gap-y-1 justify-between",
|
|
10089
|
+
children: /*#__PURE__*/ jsx("div", {
|
|
10090
|
+
children: filteredFields.length == 0 ? /*#__PURE__*/ jsx("div", {
|
|
10091
|
+
className: "mx-4 font-content text-sm",
|
|
10092
|
+
children: BAD_DATA_MESSAGE
|
|
10093
|
+
}) : filteredFields.map((facet)=>{
|
|
10094
|
+
const label = fieldNameToTitle(facet.field);
|
|
10095
|
+
return /*#__PURE__*/ jsxs("div", {
|
|
10096
|
+
className: "flex justify-between items-center px-2 my-1",
|
|
10097
|
+
children: [
|
|
10098
|
+
/*#__PURE__*/ jsx(Text, {
|
|
10099
|
+
size: "sm",
|
|
10100
|
+
fw: 400,
|
|
10101
|
+
children: label
|
|
10102
|
+
}),
|
|
10103
|
+
/*#__PURE__*/ jsx(Switch, {
|
|
10104
|
+
"data-testid": `switch-${label}`,
|
|
10105
|
+
"aria-label": `select ${facet.field}`,
|
|
10106
|
+
color: "accent",
|
|
10107
|
+
checked: selectedFields && selectedFields.includes(facet.field),
|
|
10108
|
+
onChange: ()=>updateSelectedField(facet.field)
|
|
10109
|
+
})
|
|
10110
|
+
]
|
|
10111
|
+
}, facet.field);
|
|
10112
|
+
})
|
|
10113
|
+
})
|
|
10114
|
+
}),
|
|
10115
|
+
remainingValues > 0 ? /*#__PURE__*/ jsx(FacetExpander, {
|
|
10116
|
+
remainingValues: remainingValues,
|
|
10117
|
+
isGroupExpanded: isGroupExpanded,
|
|
10118
|
+
onShowChanged: setIsGroupExpanded
|
|
10119
|
+
}) : null
|
|
10120
|
+
]
|
|
10121
|
+
})
|
|
10122
|
+
]
|
|
10123
|
+
})
|
|
10124
|
+
})
|
|
10125
|
+
]
|
|
10126
|
+
});
|
|
10127
|
+
};
|
|
10128
|
+
|
|
10129
|
+
const FacetSelectionPanel = ({ categories, hooks, selectedFields, updateSelectedField })=>{
|
|
10130
|
+
const panels = useDeepCompareMemo(()=>{
|
|
10131
|
+
return categories.map((item)=>{
|
|
10132
|
+
const fields = item.fields.map((f)=>item.fieldsConfig[f]);
|
|
10133
|
+
return /*#__PURE__*/ jsx(FacetSelector, {
|
|
10134
|
+
fields: fields,
|
|
10135
|
+
category: item.title,
|
|
10136
|
+
facetName: item.title,
|
|
10137
|
+
selectedFields: selectedFields,
|
|
10138
|
+
updateSelectedField: updateSelectedField,
|
|
10139
|
+
hooks: {
|
|
10140
|
+
...hooks
|
|
10141
|
+
}
|
|
10142
|
+
}, item.title);
|
|
10143
|
+
});
|
|
10144
|
+
}, [
|
|
10145
|
+
categories,
|
|
10146
|
+
selectedFields,
|
|
10147
|
+
updateSelectedField,
|
|
10148
|
+
hooks
|
|
10149
|
+
]);
|
|
10150
|
+
return /*#__PURE__*/ jsx("div", {
|
|
10151
|
+
className: "w-1/3 flex flex-col p-4 gap-y-6",
|
|
10152
|
+
children: panels
|
|
10153
|
+
});
|
|
10154
|
+
};
|
|
10155
|
+
|
|
10156
|
+
const initialState$1 = {};
|
|
10157
|
+
const expandSlice = createSlice({
|
|
10158
|
+
name: 'CohortDiscovery/filterExpand',
|
|
10159
|
+
initialState: initialState$1,
|
|
10160
|
+
reducers: {
|
|
10161
|
+
toggleCategoryFilter: (state, action)=>{
|
|
10162
|
+
return {
|
|
10163
|
+
...state,
|
|
10164
|
+
[action.payload.field]: action.payload.expanded
|
|
10165
|
+
};
|
|
10166
|
+
},
|
|
10167
|
+
toggleAllFilters: (state, action)=>{
|
|
10168
|
+
return Object.fromEntries(Object.keys(state).map((k)=>[
|
|
10169
|
+
k,
|
|
10170
|
+
action.payload
|
|
10171
|
+
]));
|
|
10172
|
+
}
|
|
10173
|
+
}
|
|
10174
|
+
});
|
|
10175
|
+
const filtersExpandedReducer = expandSlice.reducer;
|
|
10176
|
+
const { toggleCategoryFilter, toggleAllFilters } = expandSlice.actions;
|
|
10177
|
+
const selectFilterExpanded = (state, field)=>state.filtersExpandedState?.[field];
|
|
10178
|
+
|
|
10179
|
+
const initialState = {};
|
|
10180
|
+
const selectIndexFacets = createSlice({
|
|
10181
|
+
name: 'CohortDiscovery/filterExpand',
|
|
10182
|
+
initialState: initialState,
|
|
10183
|
+
reducers: {
|
|
10184
|
+
addFacetSelection: (state, action)=>{
|
|
10185
|
+
if (!(action.payload.index in state)) {
|
|
10186
|
+
return {
|
|
10187
|
+
...state,
|
|
10188
|
+
...{
|
|
10189
|
+
[action.payload.index]: [
|
|
10190
|
+
action.payload.field
|
|
10191
|
+
]
|
|
10192
|
+
}
|
|
10193
|
+
};
|
|
10194
|
+
} else return {
|
|
10195
|
+
...state,
|
|
10196
|
+
[action.payload.index]: [
|
|
10197
|
+
...state[action.payload.index],
|
|
10198
|
+
action.payload.field
|
|
10199
|
+
]
|
|
10200
|
+
};
|
|
10201
|
+
},
|
|
10202
|
+
removeFacetSelection: (state, action)=>{
|
|
10203
|
+
if (!(action.payload.index in state[action.payload.index])) return state;
|
|
10204
|
+
if (action.payload.field in state[action.payload.index]) {
|
|
10205
|
+
return {
|
|
10206
|
+
...state,
|
|
10207
|
+
...{
|
|
10208
|
+
[action.payload.index]: state[action.payload.index].filter((x)=>x !== action.payload.field)
|
|
10209
|
+
}
|
|
10210
|
+
};
|
|
10211
|
+
}
|
|
10212
|
+
}
|
|
10213
|
+
}
|
|
10214
|
+
});
|
|
10215
|
+
const selectedFacetsReducer = selectIndexFacets.reducer;
|
|
10216
|
+
selectIndexFacets.actions;
|
|
10217
|
+
|
|
10218
|
+
const _APP_NAME$2 = 'CohortDiscovery';
|
|
10219
|
+
const persistConfig = {
|
|
10220
|
+
key: _APP_NAME$2,
|
|
10221
|
+
version: 1,
|
|
10222
|
+
storage,
|
|
10223
|
+
whitelist: [
|
|
10224
|
+
'filterExpandState'
|
|
10225
|
+
]
|
|
10226
|
+
};
|
|
10227
|
+
// create the store, context and selector for the ProjectsCenter
|
|
10228
|
+
// Note the project app has a local store and context which isolates
|
|
10229
|
+
// the filters and other store/cache values
|
|
10230
|
+
const reducers = combineReducers({
|
|
10231
|
+
selectedIndexFacets: selectedFacetsReducer,
|
|
10232
|
+
filtersExpandedState: filtersExpandedReducer
|
|
10233
|
+
});
|
|
10234
|
+
const { id, AppStore, AppContext, useAppSelector, useAppDispatch } = createAppStore({
|
|
10235
|
+
reducers: persistReducer(persistConfig, reducers),
|
|
10236
|
+
name: _APP_NAME$2,
|
|
10237
|
+
version: '0.0.1'
|
|
10238
|
+
});
|
|
10239
|
+
|
|
10240
|
+
const useToggleExpandFilter = ()=>{
|
|
10241
|
+
const dispatch = useAppDispatch();
|
|
10242
|
+
return (field, expanded)=>{
|
|
10243
|
+
dispatch(toggleCategoryFilter({
|
|
10244
|
+
field,
|
|
10245
|
+
expanded
|
|
10246
|
+
}));
|
|
10247
|
+
};
|
|
10248
|
+
};
|
|
10249
|
+
const useFilterExpandedState = (field)=>{
|
|
10250
|
+
return useAppSelector((state)=>selectFilterExpanded(state, field));
|
|
10251
|
+
};
|
|
10252
|
+
|
|
10253
|
+
const EnumFacetToHistogramArray = (data)=>{
|
|
10254
|
+
if (!data) return [];
|
|
10255
|
+
return Object.entries(data).reduce((acc, [key, count])=>{
|
|
10256
|
+
acc.push({
|
|
10257
|
+
key,
|
|
10258
|
+
count
|
|
10259
|
+
});
|
|
10260
|
+
return acc;
|
|
10261
|
+
}, []);
|
|
10262
|
+
};
|
|
10263
|
+
|
|
10264
|
+
const FacetPanelDataHeader = ({ label, valueLabel })=>{
|
|
10265
|
+
return /*#__PURE__*/ jsxs(Group, {
|
|
10266
|
+
justify: "space-between",
|
|
10267
|
+
className: "border-1 border-base p-2 px-4",
|
|
10268
|
+
children: [
|
|
10269
|
+
/*#__PURE__*/ jsx("div", {
|
|
10270
|
+
className: "flex",
|
|
10271
|
+
children: /*#__PURE__*/ jsx(Text, {
|
|
10272
|
+
size: "sm",
|
|
10273
|
+
fw: 600,
|
|
10274
|
+
children: label
|
|
10275
|
+
})
|
|
10276
|
+
}),
|
|
10277
|
+
/*#__PURE__*/ jsx(Text, {
|
|
10278
|
+
size: "sm",
|
|
10279
|
+
fw: 600,
|
|
10280
|
+
children: valueLabel
|
|
10281
|
+
})
|
|
10282
|
+
]
|
|
10283
|
+
});
|
|
10284
|
+
};
|
|
10285
|
+
|
|
10286
|
+
const EnumFacetPanel = ({ facet, hooks, valueLabel, showTotals = false, chartType = 'bar' })=>{
|
|
10287
|
+
const { field, label } = facet;
|
|
10288
|
+
const facetName = useMemo(()=>label ?? fieldNameToTitle(field), [
|
|
10289
|
+
label,
|
|
10290
|
+
field
|
|
10291
|
+
]);
|
|
10292
|
+
const { data } = hooks.useGetFacetData(field);
|
|
10293
|
+
const chart = createChart(chartType, {
|
|
10294
|
+
data: EnumFacetToHistogramArray(data),
|
|
10295
|
+
total: 1,
|
|
10296
|
+
valueType: 'count'
|
|
10297
|
+
});
|
|
10298
|
+
return /*#__PURE__*/ jsxs("div", {
|
|
10299
|
+
className: "flex flex-col bg-base-max relative border-base border-1 rounded-b-md transition",
|
|
10300
|
+
children: [
|
|
10301
|
+
/*#__PURE__*/ jsxs("div", {
|
|
10302
|
+
className: "flex justify-between px-4 py-2 bg-base-lightest border-b-1 border-base",
|
|
10303
|
+
children: [
|
|
10304
|
+
/*#__PURE__*/ jsx(Text, {
|
|
10305
|
+
size: "sm",
|
|
10306
|
+
fw: 600,
|
|
10307
|
+
children: facetName
|
|
10308
|
+
}),
|
|
10309
|
+
showTotals ? /*#__PURE__*/ jsx(Text, {
|
|
10310
|
+
children: "Todo"
|
|
10311
|
+
}) : null
|
|
10312
|
+
]
|
|
10313
|
+
}),
|
|
10314
|
+
/*#__PURE__*/ jsx("div", {
|
|
10315
|
+
className: "px-4 pb-4 pt-8",
|
|
10316
|
+
children: chart
|
|
10317
|
+
}),
|
|
10318
|
+
/*#__PURE__*/ jsx(FacetPanelDataHeader, {
|
|
10319
|
+
label: facetName,
|
|
10320
|
+
valueLabel: valueLabel
|
|
10321
|
+
}),
|
|
10322
|
+
/*#__PURE__*/ jsx("div", {
|
|
10323
|
+
className: "p-4 pt-2 pb-2",
|
|
10324
|
+
children: /*#__PURE__*/ jsx(FacetEnumList, {
|
|
10325
|
+
field: field,
|
|
10326
|
+
valueLabel: valueLabel,
|
|
10327
|
+
hooks: hooks,
|
|
10328
|
+
showSorting: false
|
|
10329
|
+
})
|
|
10330
|
+
})
|
|
10331
|
+
]
|
|
10332
|
+
});
|
|
10333
|
+
};
|
|
10334
|
+
|
|
10335
|
+
const createFacetPanel = (facet, chartType, valueLabel, hooks)=>{
|
|
10336
|
+
switch(facet.type){
|
|
10337
|
+
case 'enum':
|
|
10338
|
+
return /*#__PURE__*/ jsx(EnumFacetPanel, {
|
|
10339
|
+
facet: facet,
|
|
10340
|
+
chartType: chartType,
|
|
10341
|
+
valueLabel: valueLabel,
|
|
10342
|
+
hooks: hooks
|
|
10343
|
+
});
|
|
10344
|
+
}
|
|
10345
|
+
return null;
|
|
10346
|
+
};
|
|
10347
|
+
|
|
10348
|
+
/**
|
|
10349
|
+
* CartsAndFacetsPanel component
|
|
10350
|
+
*
|
|
10351
|
+
* @param {string} index - The index type used for querying data.
|
|
10352
|
+
* @param {Array} facets - The list of facets to be rendered.
|
|
10353
|
+
* @returns {JSX.Element} The rendered component showing facets.
|
|
10354
|
+
*/ const ChartsAndFacetsPanel = ({ index, facets })=>{
|
|
10355
|
+
const cohortFilters = useCoreSelector((state)=>selectIndexFilters(state, index));
|
|
10356
|
+
const { data, isSuccess, isError: isAggsQueryError } = useGetAggsQuery({
|
|
10357
|
+
type: index,
|
|
10358
|
+
fields: facets.map((x)=>x.field),
|
|
10359
|
+
filters: cohortFilters
|
|
10360
|
+
});
|
|
10361
|
+
const getEnumFacetData = useDeepCompareCallback((field)=>{
|
|
10362
|
+
return {
|
|
10363
|
+
data: processBucketData(data?.[field]),
|
|
10364
|
+
enumFilters: field in cohortFilters.root ? extractEnumFilterValue(cohortFilters.root[field]) : undefined,
|
|
10365
|
+
isSuccess: isSuccess
|
|
10366
|
+
};
|
|
10367
|
+
}, [
|
|
10368
|
+
cohortFilters,
|
|
10369
|
+
cohortFilters.root,
|
|
10370
|
+
data,
|
|
10371
|
+
isSuccess
|
|
10372
|
+
]);
|
|
10373
|
+
const getRangeFacetData = useDeepCompareCallback((field)=>{
|
|
10374
|
+
return {
|
|
10375
|
+
data: processRangeData(data?.[field]),
|
|
10376
|
+
filters: extractRangeValues(cohortFilters.root[field]),
|
|
10377
|
+
isSuccess: isSuccess
|
|
10378
|
+
};
|
|
10379
|
+
}, [
|
|
10380
|
+
data,
|
|
10381
|
+
cohortFilters.root,
|
|
10382
|
+
isSuccess
|
|
10383
|
+
]);
|
|
10384
|
+
const facetHooks = useDeepCompareMemo(()=>{
|
|
10385
|
+
return {
|
|
10386
|
+
enum: {
|
|
10387
|
+
useGetFacetData: getEnumFacetData,
|
|
10388
|
+
useUpdateFacetFilters: partial(useUpdateFilters, index),
|
|
10389
|
+
useGetFacetFilters: partial(useGetFacetFilters, index),
|
|
10390
|
+
useClearFilter: partial(useClearFilters, index),
|
|
10391
|
+
useTotalCounts: undefined
|
|
10392
|
+
}
|
|
10393
|
+
};
|
|
10394
|
+
}, [
|
|
10395
|
+
getEnumFacetData,
|
|
10396
|
+
getRangeFacetData,
|
|
10397
|
+
index
|
|
10398
|
+
]);
|
|
10399
|
+
const panels = useDeepCompareMemo(()=>{
|
|
10400
|
+
return facets.map((facet)=>createFacetPanel(facet, 'bar', fieldNameToTitle(index), facetHooks.enum));
|
|
10401
|
+
}, [
|
|
10402
|
+
facets,
|
|
10403
|
+
index,
|
|
10404
|
+
facetHooks.enum
|
|
10405
|
+
]);
|
|
10406
|
+
const spans = computeRowSpan(panels.length);
|
|
10407
|
+
return /*#__PURE__*/ jsx(Grid, {
|
|
10408
|
+
className: "w-full mx-2 bg-base-max p-4",
|
|
10409
|
+
children: panels.map((panel, index)=>/*#__PURE__*/ jsx(Grid.Col, {
|
|
10410
|
+
span: spans[index],
|
|
10411
|
+
children: panel
|
|
10412
|
+
}, `${index}-charts-${facets[index].field}-col`))
|
|
10413
|
+
});
|
|
10414
|
+
};
|
|
10415
|
+
|
|
10416
|
+
const ActionButtonGroup = ()=>{
|
|
10417
|
+
return /*#__PURE__*/ jsxs(Group, {
|
|
10418
|
+
gap: "xs",
|
|
10419
|
+
className: "flex pt-4 pl-2",
|
|
10420
|
+
children: [
|
|
10421
|
+
/*#__PURE__*/ jsx(Button, {
|
|
10422
|
+
size: "sm",
|
|
10423
|
+
variant: "outline",
|
|
10424
|
+
color: "secondary.4",
|
|
10425
|
+
classNames: {
|
|
10426
|
+
root: 'bg-base-max'
|
|
10427
|
+
},
|
|
10428
|
+
children: "Save Cohort"
|
|
10429
|
+
}),
|
|
10430
|
+
/*#__PURE__*/ jsx(Button, {
|
|
10431
|
+
size: "sm",
|
|
10432
|
+
variant: "outline",
|
|
10433
|
+
color: "secondary.4",
|
|
10434
|
+
classNames: {
|
|
10435
|
+
root: 'bg-base-max'
|
|
10436
|
+
},
|
|
10437
|
+
children: "Export Cohort"
|
|
10438
|
+
}),
|
|
10439
|
+
/*#__PURE__*/ jsx(Button, {
|
|
10440
|
+
size: "sm",
|
|
10441
|
+
variant: "outline",
|
|
10442
|
+
color: "secondary.4",
|
|
10443
|
+
classNames: {
|
|
10444
|
+
root: 'bg-base-max'
|
|
10445
|
+
},
|
|
10446
|
+
children: "Import Cohort"
|
|
10447
|
+
})
|
|
10448
|
+
]
|
|
10449
|
+
});
|
|
10450
|
+
};
|
|
10451
|
+
|
|
10452
|
+
const IndexPanel = ({ dataConfig, tabs, tabTitle })=>{
|
|
10453
|
+
const [activeFieldDefinitions, setActiveFieldDefinitions] = useState([]);
|
|
10454
|
+
const index = dataConfig.dataType;
|
|
10455
|
+
const fields = useMemo(()=>getAllFieldsFromFilterConfigs(tabs ?? []), [
|
|
10456
|
+
tabs
|
|
10457
|
+
]);
|
|
10458
|
+
const [facetDefinitions, setFacetDefinitions] = useState({});
|
|
10459
|
+
const [categories, setCategories] = useState([]);
|
|
10460
|
+
const cohortFilters = useCoreSelector((state)=>selectIndexFilters(state, index));
|
|
10461
|
+
const queryFields = categories.length === 0 ? fields : activeFieldDefinitions.map((x)=>x.field);
|
|
10462
|
+
const { data, isSuccess, isError: isAggsQueryError } = useGetAggsQuery({
|
|
10463
|
+
type: index,
|
|
10464
|
+
fields: queryFields,
|
|
10465
|
+
filters: cohortFilters
|
|
10466
|
+
}, {
|
|
10467
|
+
skip: queryFields.length === 0
|
|
10468
|
+
});
|
|
10469
|
+
const updateFields = useDeepCompareCallback((field)=>{
|
|
10470
|
+
if (activeFieldDefinitions.some((facetDef)=>facetDef.field === field)) {
|
|
10471
|
+
setActiveFieldDefinitions((prevState)=>{
|
|
10472
|
+
return prevState.filter((f)=>f.field !== field);
|
|
10473
|
+
});
|
|
10474
|
+
} else {
|
|
10475
|
+
setActiveFieldDefinitions((prevState)=>[
|
|
10476
|
+
...prevState,
|
|
10477
|
+
facetDefinitions[field]
|
|
10478
|
+
]);
|
|
10479
|
+
}
|
|
10480
|
+
}, [
|
|
10481
|
+
activeFieldDefinitions,
|
|
10482
|
+
facetDefinitions
|
|
10483
|
+
]);
|
|
10484
|
+
// Set the facet definitions based on the data only the first time the data is loaded
|
|
10485
|
+
useDeepCompareEffect(()=>{
|
|
10486
|
+
if (isSuccess && Object.keys(facetDefinitions).length === 0) {
|
|
10487
|
+
const configFacetDefs = tabs.reduce((acc, tab)=>{
|
|
10488
|
+
return {
|
|
10489
|
+
...tab.fieldsConfig,
|
|
10490
|
+
...acc
|
|
10491
|
+
};
|
|
10492
|
+
}, {});
|
|
10493
|
+
const facetDefs = classifyFacets(data, index, [], configFacetDefs);
|
|
10494
|
+
setFacetDefinitions(facetDefs);
|
|
10495
|
+
// setup categories
|
|
10496
|
+
const categories = tabs.reduce((acc, tab)=>{
|
|
10497
|
+
const updatedTab = tab;
|
|
10498
|
+
if (!updatedTab?.fieldsConfig) {
|
|
10499
|
+
updatedTab.fieldsConfig = {};
|
|
10500
|
+
}
|
|
10501
|
+
updatedTab.fields.forEach((x)=>{
|
|
10502
|
+
tab.fieldsConfig[x] = {
|
|
10503
|
+
...tab.fieldsConfig[x],
|
|
10504
|
+
...x in facetDefs ? facetDefs[x] : {}
|
|
10505
|
+
};
|
|
10506
|
+
});
|
|
10507
|
+
acc.push(updatedTab);
|
|
10508
|
+
return acc;
|
|
10509
|
+
}, []);
|
|
10510
|
+
setCategories(categories);
|
|
10511
|
+
}
|
|
10512
|
+
}, [
|
|
10513
|
+
isSuccess,
|
|
10514
|
+
data,
|
|
10515
|
+
facetDefinitions,
|
|
10516
|
+
index
|
|
10517
|
+
]);
|
|
10518
|
+
if (isAggsQueryError) {
|
|
10519
|
+
return /*#__PURE__*/ jsx(ErrorCard, {
|
|
10520
|
+
message: "Unable to fetch data from server"
|
|
10521
|
+
});
|
|
10522
|
+
}
|
|
10523
|
+
return /*#__PURE__*/ jsxs(Stack, {
|
|
10524
|
+
children: [
|
|
10525
|
+
/*#__PURE__*/ jsx(CohortManager, {
|
|
10526
|
+
index: index
|
|
10527
|
+
}),
|
|
10528
|
+
/*#__PURE__*/ jsxs(Flex, {
|
|
10529
|
+
className: "w-full h-full bg-base-light",
|
|
10530
|
+
children: [
|
|
10531
|
+
/*#__PURE__*/ jsx(FacetSelectionPanel, {
|
|
10532
|
+
categories: categories,
|
|
10533
|
+
selectedFields: activeFieldDefinitions.map((x)=>x.field),
|
|
10534
|
+
updateSelectedField: updateFields,
|
|
10535
|
+
hooks: {
|
|
10536
|
+
useClearFilter: ()=>(field)=>null,
|
|
10537
|
+
useToggleExpandFilter: useToggleExpandFilter,
|
|
10538
|
+
useFilterExpanded: useFilterExpandedState
|
|
10539
|
+
}
|
|
10540
|
+
}),
|
|
10541
|
+
/*#__PURE__*/ jsxs(Stack, {
|
|
10542
|
+
className: "w-full",
|
|
10543
|
+
children: [
|
|
10544
|
+
/*#__PURE__*/ jsx(ActionButtonGroup, {}),
|
|
10545
|
+
/*#__PURE__*/ jsx(ChartsAndFacetsPanel, {
|
|
10546
|
+
index: index,
|
|
10547
|
+
facets: activeFieldDefinitions
|
|
10548
|
+
})
|
|
10549
|
+
]
|
|
10550
|
+
})
|
|
10551
|
+
]
|
|
10552
|
+
})
|
|
10553
|
+
]
|
|
10554
|
+
});
|
|
10555
|
+
};
|
|
10556
|
+
|
|
10557
|
+
const persistor = persistStore(AppStore);
|
|
10558
|
+
const CohortDiscovery = (config)=>{
|
|
10559
|
+
const { isLoading } = useGetCSRFQuery(); // need for Guppy
|
|
10560
|
+
if (isLoading) {
|
|
10561
|
+
return /*#__PURE__*/ jsx(Center, {
|
|
10562
|
+
maw: 400,
|
|
10563
|
+
h: 100,
|
|
10564
|
+
mx: "auto",
|
|
10565
|
+
children: /*#__PURE__*/ jsx(Loader, {
|
|
10566
|
+
variant: "dots"
|
|
10567
|
+
})
|
|
10568
|
+
});
|
|
10569
|
+
}
|
|
10570
|
+
return /*#__PURE__*/ jsx(Fragment, {
|
|
10571
|
+
children: /*#__PURE__*/ jsx(PersistGate, {
|
|
10572
|
+
persistor: persistor,
|
|
10573
|
+
children: /*#__PURE__*/ jsx("div", {
|
|
10574
|
+
className: "w-full h-full",
|
|
10575
|
+
children: /*#__PURE__*/ jsx(IndexPanel, {
|
|
10576
|
+
dataConfig: config.dataIndexes[0].dataConfig,
|
|
10577
|
+
tabTitle: config.dataIndexes[0].tabTitle,
|
|
10578
|
+
tabs: config.dataIndexes[0].tabs
|
|
10579
|
+
})
|
|
10580
|
+
})
|
|
10581
|
+
})
|
|
10582
|
+
});
|
|
10583
|
+
};
|
|
10584
|
+
|
|
10585
|
+
const _APP_NAME$1 = 'CohortDiscovery'; // This wil be the route name of the app
|
|
10586
|
+
const registerCohortDiscoveryApp = ()=>createGen3AppWithOwnStore({
|
|
10587
|
+
App: CohortDiscovery,
|
|
10588
|
+
id: id,
|
|
10589
|
+
name: _APP_NAME$1,
|
|
10590
|
+
version: 'v1.0.0',
|
|
10591
|
+
requiredEntityTypes: [],
|
|
10592
|
+
store: AppStore,
|
|
10593
|
+
context: AppContext
|
|
10594
|
+
});
|
|
10595
|
+
|
|
10596
|
+
const roundTo2AfterDecimal = (number)=>{
|
|
10597
|
+
return Math.round((number + Number.EPSILON) * 100) / 100;
|
|
10598
|
+
};
|
|
10599
|
+
|
|
10600
|
+
const processComparisonData$1 = (baseData, comparisonData)=>{
|
|
10601
|
+
return [
|
|
10602
|
+
{
|
|
10603
|
+
name: baseData.label,
|
|
10604
|
+
type: 'bar',
|
|
10605
|
+
barGap: 0,
|
|
10606
|
+
itemStyle: {
|
|
10607
|
+
color: '#4e79a7'
|
|
10608
|
+
},
|
|
10609
|
+
data: baseData.data.map((item)=>roundTo2AfterDecimal(item.count)),
|
|
10610
|
+
emphasis: {
|
|
10611
|
+
focus: 'series'
|
|
10612
|
+
}
|
|
10613
|
+
},
|
|
10614
|
+
{
|
|
10615
|
+
name: comparisonData.label,
|
|
10616
|
+
type: 'bar',
|
|
10617
|
+
itemStyle: {
|
|
10618
|
+
color: '#f28e2c'
|
|
10619
|
+
},
|
|
10620
|
+
data: comparisonData.data.map((item)=>roundTo2AfterDecimal(item.count)),
|
|
10621
|
+
emphasis: {
|
|
10622
|
+
focus: 'series'
|
|
10623
|
+
}
|
|
10624
|
+
}
|
|
10625
|
+
];
|
|
10626
|
+
};
|
|
10627
|
+
const BarComparison = ({ baseDataset, comparisonDataset, title, yAxisLabel = 'percent' })=>{
|
|
10628
|
+
const categories = baseDataset.data.map((d)=>truncateString(processLabel$1(d.key), 35));
|
|
10629
|
+
const chartDefinition = useMemo(()=>{
|
|
10630
|
+
const series = processComparisonData$1(baseDataset, comparisonDataset);
|
|
10631
|
+
return {
|
|
10632
|
+
aria: {
|
|
10633
|
+
enabled: true
|
|
10634
|
+
},
|
|
10635
|
+
tooltip: {
|
|
10636
|
+
trigger: 'axis',
|
|
10637
|
+
axisPointer: {
|
|
10638
|
+
type: 'shadow'
|
|
10639
|
+
}
|
|
10640
|
+
},
|
|
10641
|
+
title: {
|
|
10642
|
+
text: title,
|
|
10643
|
+
left: 'center'
|
|
10644
|
+
},
|
|
10645
|
+
legend: {
|
|
10646
|
+
data: [
|
|
10647
|
+
baseDataset.label,
|
|
10648
|
+
comparisonDataset.label
|
|
10649
|
+
],
|
|
10650
|
+
bottom: '5%'
|
|
10651
|
+
},
|
|
10652
|
+
xAxis: {
|
|
10653
|
+
type: 'category',
|
|
10654
|
+
data: categories,
|
|
10655
|
+
axisTick: {
|
|
10656
|
+
show: false
|
|
10657
|
+
}
|
|
10658
|
+
},
|
|
10659
|
+
yAxis: {
|
|
10660
|
+
type: 'value',
|
|
10661
|
+
name: yAxisLabel
|
|
10662
|
+
},
|
|
10663
|
+
series: series
|
|
10664
|
+
};
|
|
10665
|
+
}, [
|
|
10666
|
+
baseDataset,
|
|
10667
|
+
categories,
|
|
10668
|
+
comparisonDataset,
|
|
10669
|
+
title,
|
|
10670
|
+
yAxisLabel
|
|
10671
|
+
]);
|
|
10672
|
+
return /*#__PURE__*/ jsx("div", {
|
|
10673
|
+
role: "region",
|
|
10674
|
+
"aria-labelledby": "bar-comparison-title",
|
|
10675
|
+
className: "flex flex-col w-full h-96",
|
|
10676
|
+
children: /*#__PURE__*/ jsx(ReactECharts, {
|
|
10677
|
+
option: chartDefinition,
|
|
10678
|
+
settings: {
|
|
10679
|
+
notMerge: true
|
|
10680
|
+
}
|
|
10681
|
+
})
|
|
10682
|
+
});
|
|
10683
|
+
};
|
|
10684
|
+
|
|
10685
|
+
const processComparisonData = (baseData, comparisonData)=>{
|
|
10686
|
+
const maxB = baseData.data.reduce((acc, curr)=>{
|
|
10687
|
+
return Math.max(curr.count, acc);
|
|
10688
|
+
}, 0);
|
|
10689
|
+
const maxC = comparisonData.data.reduce((acc, curr)=>{
|
|
10690
|
+
return Math.max(curr.count, acc);
|
|
10691
|
+
}, 0);
|
|
10692
|
+
return {
|
|
10693
|
+
data: [
|
|
10694
|
+
{
|
|
10695
|
+
type: 'radar',
|
|
10696
|
+
data: [
|
|
10697
|
+
{
|
|
10698
|
+
value: baseData.data.map((item)=>roundTo2AfterDecimal(item.count)),
|
|
10699
|
+
name: baseData.label,
|
|
10700
|
+
itemStyle: {
|
|
10701
|
+
color: '#4e79a7'
|
|
10702
|
+
},
|
|
10703
|
+
areaStyle: {
|
|
10704
|
+
opacity: 0.3
|
|
10705
|
+
}
|
|
10706
|
+
},
|
|
10707
|
+
{
|
|
10708
|
+
value: comparisonData.data.map((item)=>roundTo2AfterDecimal(item.count)),
|
|
10709
|
+
name: comparisonData.label,
|
|
10710
|
+
itemStyle: {
|
|
10711
|
+
color: '#f28e2c'
|
|
10712
|
+
},
|
|
10713
|
+
areaStyle: {
|
|
10714
|
+
opacity: 0.3
|
|
10715
|
+
}
|
|
10716
|
+
}
|
|
10717
|
+
]
|
|
10718
|
+
}
|
|
10719
|
+
],
|
|
10720
|
+
maxBase: maxB,
|
|
10721
|
+
maxComparison: maxC
|
|
10722
|
+
};
|
|
10723
|
+
};
|
|
10724
|
+
const RadarComparison = ({ baseDataset, comparisonDataset, title, yAxisLabel = 'percent' })=>{
|
|
10725
|
+
const categories = baseDataset.data.map((d)=>truncateString(processLabel$1(d.key), 35));
|
|
10726
|
+
const chartDefinition = useMemo(()=>{
|
|
10727
|
+
const series = processComparisonData(baseDataset, comparisonDataset);
|
|
10728
|
+
const option = {
|
|
10729
|
+
aria: {
|
|
10730
|
+
enabled: true
|
|
10731
|
+
},
|
|
10732
|
+
title: {
|
|
10733
|
+
text: title,
|
|
10734
|
+
left: 'center'
|
|
10735
|
+
},
|
|
10736
|
+
legend: {
|
|
10737
|
+
data: [
|
|
10738
|
+
baseDataset.label,
|
|
10739
|
+
comparisonDataset.label
|
|
10740
|
+
],
|
|
10741
|
+
bottom: '5%'
|
|
10742
|
+
},
|
|
10743
|
+
radar: {
|
|
10744
|
+
indicator: categories.map((group)=>({
|
|
10745
|
+
name: group,
|
|
10746
|
+
max: Math.max(series.maxBase, series.maxComparison)
|
|
10747
|
+
})),
|
|
10748
|
+
axisLine: {
|
|
10749
|
+
lineStyle: {
|
|
10750
|
+
color: '#4e79a7'
|
|
10751
|
+
}
|
|
10752
|
+
},
|
|
10753
|
+
splitLine: {
|
|
10754
|
+
show: true,
|
|
10755
|
+
lineStyle: {
|
|
10756
|
+
color: [
|
|
10757
|
+
'#8c8989',
|
|
10758
|
+
'#8aa0ae'
|
|
10759
|
+
]
|
|
10760
|
+
}
|
|
10761
|
+
},
|
|
10762
|
+
center: [
|
|
10763
|
+
'50%',
|
|
10764
|
+
'50%'
|
|
10765
|
+
],
|
|
10766
|
+
radius: '65%'
|
|
10767
|
+
},
|
|
10768
|
+
series: series.data,
|
|
10769
|
+
tooltip: {
|
|
10770
|
+
trigger: 'item'
|
|
10771
|
+
}
|
|
10772
|
+
};
|
|
10773
|
+
return option;
|
|
10774
|
+
}, [
|
|
10775
|
+
baseDataset,
|
|
10776
|
+
categories,
|
|
10777
|
+
comparisonDataset,
|
|
10778
|
+
title,
|
|
10779
|
+
yAxisLabel
|
|
10780
|
+
]);
|
|
10781
|
+
return /*#__PURE__*/ jsx("div", {
|
|
10782
|
+
role: "region",
|
|
10783
|
+
"aria-labelledby": "radar-comparison-title",
|
|
10784
|
+
className: "flex flex-col w-full h-96",
|
|
10785
|
+
children: /*#__PURE__*/ jsx(ReactECharts, {
|
|
10786
|
+
option: chartDefinition,
|
|
10787
|
+
settings: {
|
|
10788
|
+
notMerge: true
|
|
10789
|
+
}
|
|
10790
|
+
})
|
|
10791
|
+
});
|
|
10792
|
+
};
|
|
10793
|
+
|
|
10794
|
+
let instance = undefined;
|
|
10795
|
+
const DefaultComparisonChart = ()=>{
|
|
10796
|
+
return /*#__PURE__*/ jsx("div", {
|
|
10797
|
+
children: "Chart not configured"
|
|
10798
|
+
});
|
|
10799
|
+
};
|
|
10800
|
+
const DefaultRendererCatalog = {
|
|
10801
|
+
comparison: {
|
|
10802
|
+
default: DefaultComparisonChart,
|
|
10803
|
+
barComparison: BarComparison,
|
|
10804
|
+
radarComparison: RadarComparison
|
|
10805
|
+
}
|
|
10806
|
+
};
|
|
10807
|
+
const DiversityChartsFactory = ()=>{
|
|
10808
|
+
if (!instance) {
|
|
10809
|
+
instance = new RenderFactoryTypedInstance();
|
|
10810
|
+
instance.registerRendererCatalog(DefaultRendererCatalog);
|
|
10811
|
+
}
|
|
10812
|
+
return instance;
|
|
10813
|
+
};
|
|
10814
|
+
|
|
10815
|
+
DiversityChartsFactory();
|
|
10816
|
+
const generateChart = (groundData, groundLabel, comparisonData, comparisonLabel, field, config, showTitle = true)=>{
|
|
10817
|
+
// Check if the field exists in the datasets
|
|
10818
|
+
if (!(field in groundData) || !(field in comparisonData)) {
|
|
10819
|
+
console.error(`Field ${field} does not exist in provided data.`);
|
|
10820
|
+
return /*#__PURE__*/ jsx("span", {
|
|
10821
|
+
children: "Error: Data field missing"
|
|
10822
|
+
});
|
|
10823
|
+
}
|
|
10824
|
+
const chartRenderer = DiversityChartsFactory().getRenderer('comparison', config.chartType);
|
|
10825
|
+
// Check if renderer is the DefaultItemRenderer to log a warning
|
|
10826
|
+
if (chartRenderer === DefaultComparisonChart) {
|
|
10827
|
+
console.warn(`No specific renderer found for ${config.chartType}. Using default renderer.`);
|
|
10828
|
+
}
|
|
10829
|
+
return chartRenderer({
|
|
10830
|
+
baseDataset: {
|
|
10831
|
+
data: groundData[field],
|
|
10832
|
+
label: groundLabel
|
|
10833
|
+
},
|
|
10834
|
+
comparisonDataset: {
|
|
10835
|
+
data: comparisonData[field],
|
|
10836
|
+
label: comparisonLabel
|
|
10837
|
+
},
|
|
10838
|
+
title: showTitle ? fieldNameToTitle(field) : ''
|
|
10839
|
+
});
|
|
10840
|
+
};
|
|
10841
|
+
|
|
10842
|
+
// Compute statistics
|
|
10843
|
+
const computeStatistics = (baseData, comparisonData)=>{
|
|
10844
|
+
const buckets = baseData.map((item)=>typeof item.key !== 'string' ? `${item.key[0]} to ${item.key[1]}` : item.key);
|
|
10845
|
+
const baseValues = baseData.map((item)=>item.count);
|
|
10846
|
+
const cmpValues = comparisonData.map((item)=>item.count);
|
|
10847
|
+
// Mean Absolute Error (MAE)
|
|
10848
|
+
const mae = baseValues.reduce((sum, value, index)=>sum + Math.abs(value - cmpValues[index]), 0) / buckets.length;
|
|
10849
|
+
// Root Mean Square Error (RMSE)
|
|
10850
|
+
const rmse = Math.sqrt(baseValues.reduce((sum, value, index)=>sum + Math.pow(value - cmpValues[index], 2), 0) / buckets.length);
|
|
10851
|
+
// Pearson Correlation Coefficient
|
|
10852
|
+
const baseAve = baseValues.reduce((sum, value)=>sum + value, 0) / buckets.length;
|
|
10853
|
+
const cmpAvg = cmpValues.reduce((sum, value)=>sum + value, 0) / buckets.length;
|
|
10854
|
+
const numerator = baseValues.reduce((sum, value, index)=>sum + (value - baseAve) * (cmpValues[index] - cmpAvg), 0);
|
|
10855
|
+
const denominator = Math.sqrt(baseValues.reduce((sum, value)=>sum + Math.pow(value - baseAve, 2), 0) * cmpValues.reduce((sum, value)=>sum + Math.pow(value - cmpAvg, 2), 0));
|
|
10856
|
+
const correlation = numerator / denominator;
|
|
10857
|
+
const robustChiSquare = baseValues.reduce((sum, expected, index)=>{
|
|
10858
|
+
const observed = cmpValues[index];
|
|
10859
|
+
if (expected === 0 && observed === 0) {
|
|
10860
|
+
return sum; // Both expected and observed are 0, no contribution to chi-square
|
|
10861
|
+
} else if (expected === 0) {
|
|
10862
|
+
return sum + observed; // Add observed value to chi-square when expected is 0
|
|
10863
|
+
} else {
|
|
10864
|
+
return sum + Math.pow(observed - expected, 2) / expected;
|
|
10865
|
+
}
|
|
10866
|
+
}, 0);
|
|
10867
|
+
// Chi-Square Contributions
|
|
10868
|
+
const chiSquareContributions = buckets.map((group, index)=>{
|
|
10869
|
+
const expected = baseValues[index];
|
|
10870
|
+
const observed = cmpValues[index];
|
|
10871
|
+
let contribution = 0;
|
|
10872
|
+
if (expected === 0 && observed === 0) {
|
|
10873
|
+
contribution = 0;
|
|
10874
|
+
} else if (expected === 0) {
|
|
10875
|
+
contribution = observed;
|
|
10876
|
+
} else {
|
|
10877
|
+
contribution = Math.pow(observed - expected, 2) / expected;
|
|
10878
|
+
}
|
|
10879
|
+
return {
|
|
10880
|
+
group,
|
|
10881
|
+
contribution
|
|
10882
|
+
};
|
|
10883
|
+
});
|
|
10884
|
+
return {
|
|
10885
|
+
mae,
|
|
10886
|
+
rmse,
|
|
10887
|
+
correlation,
|
|
10888
|
+
robustChiSquare,
|
|
10889
|
+
chiSquareContributions
|
|
10890
|
+
};
|
|
10891
|
+
};
|
|
10892
|
+
const LabeledValueRow = ({ label, value })=>{
|
|
10893
|
+
return /*#__PURE__*/ jsxs(Group, {
|
|
10894
|
+
justify: "space-between",
|
|
10895
|
+
children: [
|
|
10896
|
+
/*#__PURE__*/ jsx(Text, {
|
|
10897
|
+
fw: 600,
|
|
10898
|
+
size: "sm",
|
|
10899
|
+
className: "uppercase",
|
|
10900
|
+
children: label
|
|
10901
|
+
}),
|
|
10902
|
+
/*#__PURE__*/ jsx(Text, {
|
|
10903
|
+
size: "sm",
|
|
10904
|
+
c: "primary",
|
|
10905
|
+
children: value
|
|
10906
|
+
})
|
|
10907
|
+
]
|
|
10908
|
+
});
|
|
10909
|
+
};
|
|
10910
|
+
const StatisticsCard = ({ baseData, comparisonData })=>{
|
|
10911
|
+
const metrics = computeStatistics(baseData, comparisonData);
|
|
10912
|
+
return /*#__PURE__*/ jsxs(Stack, {
|
|
10913
|
+
gap: "xs",
|
|
10914
|
+
children: [
|
|
10915
|
+
/*#__PURE__*/ jsx(LabeledValueRow, {
|
|
10916
|
+
label: "Mean Absolute Error (MAE)",
|
|
10917
|
+
value: metrics.mae.toFixed(4)
|
|
10918
|
+
}),
|
|
10919
|
+
/*#__PURE__*/ jsx(LabeledValueRow, {
|
|
10920
|
+
label: "Root Mean Square Error (RMSE)",
|
|
10921
|
+
value: metrics.rmse.toFixed(4)
|
|
10922
|
+
}),
|
|
10923
|
+
/*#__PURE__*/ jsx(LabeledValueRow, {
|
|
10924
|
+
label: "Pearson Correlation Coefficient",
|
|
10925
|
+
value: metrics.correlation.toFixed(4)
|
|
10926
|
+
}),
|
|
10927
|
+
/*#__PURE__*/ jsx(LabeledValueRow, {
|
|
10928
|
+
label: "Robust Chi-Square Statistic",
|
|
10929
|
+
value: metrics.robustChiSquare.toFixed(4)
|
|
10930
|
+
}),
|
|
10931
|
+
/*#__PURE__*/ jsx(Text, {
|
|
10932
|
+
fw: 600,
|
|
10933
|
+
size: "sm",
|
|
10934
|
+
className: "uppercase",
|
|
10935
|
+
children: "Chi-Square Contributions by Group"
|
|
10936
|
+
}),
|
|
10937
|
+
/*#__PURE__*/ jsx(ScrollArea, {
|
|
10938
|
+
h: 200,
|
|
10939
|
+
children: /*#__PURE__*/ jsxs(Table, {
|
|
10940
|
+
striped: true,
|
|
10941
|
+
withTableBorder: true,
|
|
10942
|
+
withColumnBorders: true,
|
|
10943
|
+
stickyHeader: true,
|
|
10944
|
+
stickyHeaderOffset: 0,
|
|
10945
|
+
children: [
|
|
10946
|
+
/*#__PURE__*/ jsx(Table.Thead, {
|
|
10947
|
+
children: /*#__PURE__*/ jsxs(Table.Tr, {
|
|
10948
|
+
children: [
|
|
10949
|
+
/*#__PURE__*/ jsx(Table.Th, {
|
|
10950
|
+
children: "Group"
|
|
10951
|
+
}),
|
|
10952
|
+
/*#__PURE__*/ jsx(Table.Th, {
|
|
10953
|
+
children: "Contribution"
|
|
10954
|
+
})
|
|
10955
|
+
]
|
|
10956
|
+
})
|
|
10957
|
+
}),
|
|
10958
|
+
/*#__PURE__*/ jsx(Table.Tbody, {
|
|
10959
|
+
children: metrics.chiSquareContributions.map(({ group, contribution })=>/*#__PURE__*/ jsxs(Table.Tr, {
|
|
10960
|
+
children: [
|
|
10961
|
+
/*#__PURE__*/ jsx(Table.Td, {
|
|
10962
|
+
children: group
|
|
10963
|
+
}),
|
|
10964
|
+
/*#__PURE__*/ jsx(Table.Td, {
|
|
10965
|
+
children: contribution.toFixed(4)
|
|
10966
|
+
})
|
|
10967
|
+
]
|
|
10968
|
+
}, group))
|
|
10969
|
+
})
|
|
10970
|
+
]
|
|
10971
|
+
})
|
|
10972
|
+
})
|
|
10973
|
+
]
|
|
10974
|
+
});
|
|
10975
|
+
};
|
|
10976
|
+
|
|
10977
|
+
const ComparisonChart = ({ config, groundData, groundLabel, comparisonData, comparisonLabel, field, chartType })=>{
|
|
10978
|
+
return generateChart(groundData, groundLabel, comparisonData, comparisonLabel, field, {
|
|
10979
|
+
...config,
|
|
10980
|
+
chartType: chartType
|
|
10981
|
+
}, false);
|
|
10982
|
+
};
|
|
10983
|
+
const ComparisonCard = ({ config, groundData, groundLabel, comparisonData, comparisonLabel, field, style = 'box' })=>{
|
|
10984
|
+
const [viewType, setViewType] = useState(config.chartType);
|
|
10985
|
+
return /*#__PURE__*/ jsxs(Card, {
|
|
10986
|
+
shadow: "xs",
|
|
10987
|
+
withBorder: style === 'box',
|
|
10988
|
+
className: "h-full",
|
|
10989
|
+
children: [
|
|
10990
|
+
/*#__PURE__*/ jsx(Card.Section, {
|
|
10991
|
+
inheritPadding: true,
|
|
10992
|
+
py: "xs",
|
|
10993
|
+
withBorder: style === 'box',
|
|
10994
|
+
children: /*#__PURE__*/ jsxs(Group, {
|
|
10995
|
+
justify: "space-between",
|
|
10996
|
+
children: [
|
|
10997
|
+
/*#__PURE__*/ jsx(Text, {
|
|
10998
|
+
fw: 600,
|
|
10999
|
+
children: fieldNameToTitle(field)
|
|
11000
|
+
}),
|
|
11001
|
+
/*#__PURE__*/ jsx(SegmentedControl, {
|
|
11002
|
+
value: viewType,
|
|
11003
|
+
onChange: setViewType,
|
|
11004
|
+
data: [
|
|
11005
|
+
{
|
|
11006
|
+
label: 'Bar',
|
|
11007
|
+
value: 'barComparison'
|
|
11008
|
+
},
|
|
11009
|
+
{
|
|
11010
|
+
label: 'Radar',
|
|
11011
|
+
value: 'radarComparison'
|
|
11012
|
+
},
|
|
11013
|
+
{
|
|
11014
|
+
label: 'Statistics',
|
|
11015
|
+
value: 'statisticsComparison'
|
|
11016
|
+
}
|
|
11017
|
+
]
|
|
11018
|
+
})
|
|
11019
|
+
]
|
|
11020
|
+
})
|
|
11021
|
+
}),
|
|
11022
|
+
viewType == 'statisticsComparison' ? /*#__PURE__*/ jsx("div", {
|
|
11023
|
+
className: "h-96 m-2",
|
|
11024
|
+
children: /*#__PURE__*/ jsx(StatisticsCard, {
|
|
11025
|
+
baseData: groundData[field],
|
|
11026
|
+
comparisonData: comparisonData[field]
|
|
11027
|
+
})
|
|
11028
|
+
}) : /*#__PURE__*/ jsx(ComparisonChart, {
|
|
11029
|
+
config: config,
|
|
11030
|
+
groundData: groundData,
|
|
11031
|
+
groundLabel: groundLabel,
|
|
11032
|
+
comparisonData: comparisonData,
|
|
11033
|
+
comparisonLabel: comparisonLabel,
|
|
11034
|
+
field: field,
|
|
11035
|
+
chartType: viewType
|
|
11036
|
+
})
|
|
11037
|
+
]
|
|
11038
|
+
});
|
|
11039
|
+
};
|
|
9788
11040
|
|
|
9789
|
-
const
|
|
9790
|
-
|
|
9791
|
-
|
|
9792
|
-
|
|
9793
|
-
|
|
9794
|
-
|
|
11041
|
+
const ComparisonCharts = ({ ground, groundLabel, comparison, comparisonLabel, comparisonChartsConfig, numberOfColumns = 2, style = 'tile' })=>{
|
|
11042
|
+
const spans = computeRowSpan(Object.keys(comparisonChartsConfig).length, numberOfColumns);
|
|
11043
|
+
return /*#__PURE__*/ jsx(Grid, {
|
|
11044
|
+
className: "w-full p-4",
|
|
11045
|
+
children: Object.entries(comparisonChartsConfig).map(([field, config], indexNum)=>{
|
|
11046
|
+
return /*#__PURE__*/ jsx(Grid.Col, {
|
|
11047
|
+
span: spans[indexNum],
|
|
11048
|
+
children: /*#__PURE__*/ jsx(ComparisonCard, {
|
|
11049
|
+
config: config,
|
|
11050
|
+
groundData: ground,
|
|
11051
|
+
groundLabel: groundLabel,
|
|
11052
|
+
comparisonData: comparison,
|
|
11053
|
+
comparisonLabel: comparisonLabel,
|
|
11054
|
+
field: field
|
|
11055
|
+
})
|
|
11056
|
+
}, `${indexNum}-charts-${field}-col`);
|
|
9795
11057
|
})
|
|
9796
11058
|
});
|
|
9797
11059
|
};
|
|
9798
11060
|
|
|
9799
|
-
|
|
9800
|
-
|
|
9801
|
-
|
|
11061
|
+
/**
|
|
11062
|
+
* Converts a deeply nested data structure of numbers into a structured aggregation data format.
|
|
11063
|
+
*
|
|
11064
|
+
* @param {Record<string, Record<string, Record<string, number>>>} data - The input data where the structure
|
|
11065
|
+
* consists of three levels of nested records:
|
|
11066
|
+
* - The outermost level is keyed by source identifiers.
|
|
11067
|
+
* - The middle level is keyed by aggregation identifiers.
|
|
11068
|
+
* - The innermost level is keyed by histogram keys with corresponding numeric counts.
|
|
11069
|
+
*
|
|
11070
|
+
* @return {Record<string, AggregationsData>} - A newly structured data object where:
|
|
11071
|
+
* - The outermost level is the same as the input.
|
|
11072
|
+
* - Each aggregation identifier now maps to an array of histogram objects with key-count pairs.
|
|
11073
|
+
*/ const convertToAggregateData = (data)=>{
|
|
11074
|
+
const result = {};
|
|
11075
|
+
for (const [sourceKey, sourceValue] of Object.entries(data)){
|
|
11076
|
+
const aggData = {};
|
|
11077
|
+
for (const [aggKey, aggValue] of Object.entries(sourceValue)){
|
|
11078
|
+
const histogramDataArray = [];
|
|
11079
|
+
for (const [key, count] of Object.entries(aggValue)){
|
|
11080
|
+
histogramDataArray.push({
|
|
11081
|
+
key,
|
|
11082
|
+
count
|
|
11083
|
+
});
|
|
11084
|
+
}
|
|
11085
|
+
aggData[aggKey] = histogramDataArray;
|
|
11086
|
+
}
|
|
11087
|
+
result[sourceKey] = aggData;
|
|
9802
11088
|
}
|
|
9803
|
-
|
|
9804
|
-
|
|
9805
|
-
|
|
9806
|
-
|
|
9807
|
-
|
|
11089
|
+
return result;
|
|
11090
|
+
};
|
|
11091
|
+
/**
|
|
11092
|
+
* Converts histogram response data into percentages based on the total counts.
|
|
11093
|
+
*
|
|
11094
|
+
* @param {Record<string, any>} data - The input data containing histogram details and total counts.
|
|
11095
|
+
*
|
|
11096
|
+
* @returns {AggregationsData} The processed histogram data where counts are converted to percentages.
|
|
11097
|
+
*/ const processHistogramResponseAsPercentage = (data)=>{
|
|
11098
|
+
const pathData = JSONPath({
|
|
11099
|
+
json: data,
|
|
11100
|
+
path: '$..histogram',
|
|
11101
|
+
resultType: 'all'
|
|
11102
|
+
});
|
|
11103
|
+
const totalData = JSONPath({
|
|
11104
|
+
json: data,
|
|
11105
|
+
path: '$.._totalCount',
|
|
11106
|
+
resultType: 'value'
|
|
11107
|
+
});
|
|
11108
|
+
const total = totalData[0];
|
|
11109
|
+
const results = pathData.reduce((acc, element)=>{
|
|
11110
|
+
const key = element.pointer.split('/').slice(-2, -1)[0];
|
|
11111
|
+
if (isArray(element.value[0].key) && element.value[0].key.length == 2) {
|
|
11112
|
+
if (!(key in acc)) acc[key] = [];
|
|
11113
|
+
return {
|
|
11114
|
+
...acc,
|
|
11115
|
+
[key]: [
|
|
11116
|
+
{
|
|
11117
|
+
key: `${element.value[0].key[0]}-${element.value[0].key[1]}`,
|
|
11118
|
+
count: element.value[0].count / total * 100
|
|
11119
|
+
},
|
|
11120
|
+
...acc[key]
|
|
11121
|
+
]
|
|
11122
|
+
};
|
|
11123
|
+
}
|
|
11124
|
+
return {
|
|
11125
|
+
...acc,
|
|
11126
|
+
[key]: element.value.map((x)=>{
|
|
11127
|
+
return {
|
|
11128
|
+
key: x.key,
|
|
11129
|
+
count: x.count / total * 100
|
|
11130
|
+
};
|
|
11131
|
+
})
|
|
11132
|
+
};
|
|
11133
|
+
}, {});
|
|
11134
|
+
return results;
|
|
11135
|
+
};
|
|
11136
|
+
/**
|
|
11137
|
+
* Takes an object of type AggregationsData and normalizes the
|
|
11138
|
+
* 'age_at_index' property by converting the age keys to a string format.
|
|
11139
|
+
*
|
|
11140
|
+
* This function checks if the 'age_at_index' key exists in the input object.
|
|
11141
|
+
* If it does, it transforms each age entry by appending ' Years' to the age
|
|
11142
|
+
* value and returns the updated object. If the 'age_at_index' key does not exist,
|
|
11143
|
+
* it returns the original data.
|
|
11144
|
+
*
|
|
11145
|
+
* @param {AggregationsData} data - The input data object containing the age aggregations.
|
|
11146
|
+
* @returns {AggregationsData} - The transformed data object with normalized age keys.
|
|
11147
|
+
*/ const normalizeAgeOfIndex = (data)=>{
|
|
11148
|
+
if (!('age_at_index' in data)) return data;
|
|
11149
|
+
const newKeys = data['age_at_index'].map((x)=>{
|
|
11150
|
+
return {
|
|
11151
|
+
key: `${x.key} Years`,
|
|
11152
|
+
count: x.count
|
|
11153
|
+
};
|
|
11154
|
+
});
|
|
11155
|
+
return {
|
|
11156
|
+
...data,
|
|
11157
|
+
age_at_index: newKeys
|
|
11158
|
+
};
|
|
11159
|
+
};
|
|
11160
|
+
/**
|
|
11161
|
+
* Aligns the source data with the target structure by mapping items based on their keys and updating the counts.
|
|
11162
|
+
*
|
|
11163
|
+
* This function takes two sets of aggregation data, aligns them by their categories and individual keys,
|
|
11164
|
+
* and updates the counts from the source data. If a category or its items are missing in the source data,
|
|
11165
|
+
* a count of 0 is assigned to those items in the resulting aligned data structure.
|
|
11166
|
+
*
|
|
11167
|
+
* @param {AggregationsData} sourceData - The source aggregation data containing key-value pairs with the count.
|
|
11168
|
+
* @param {AggregationsData} targetStructure - The target aggregation structure used to align and structure the result.
|
|
11169
|
+
* @return {AggregationsData} The aligned data with updated counts from the source data, maintaining the target structure.
|
|
11170
|
+
*/ const alignData = (sourceData, targetStructure)=>{
|
|
11171
|
+
const result = {};
|
|
11172
|
+
for(const category in targetStructure){
|
|
11173
|
+
if (category in sourceData) {
|
|
11174
|
+
result[category] = targetStructure[category].map((targetItem)=>{
|
|
11175
|
+
const sourceItem = sourceData[category].find((item)=>item.key === targetItem.key);
|
|
11176
|
+
return sourceItem ? {
|
|
11177
|
+
...targetItem,
|
|
11178
|
+
count: sourceItem.count
|
|
11179
|
+
} : {
|
|
11180
|
+
...targetItem,
|
|
11181
|
+
count: 0
|
|
11182
|
+
};
|
|
11183
|
+
});
|
|
9808
11184
|
}
|
|
9809
11185
|
}
|
|
9810
|
-
|
|
11186
|
+
// TODO: report missing?
|
|
11187
|
+
// TODO: make this configurable
|
|
11188
|
+
return result;
|
|
11189
|
+
};
|
|
9811
11190
|
|
|
9812
|
-
|
|
9813
|
-
|
|
9814
|
-
|
|
9815
|
-
|
|
11191
|
+
const getStaticDiversityData = (dataset)=>{
|
|
11192
|
+
return convertToAggregateData({
|
|
11193
|
+
census: {
|
|
11194
|
+
age_at_index: {
|
|
11195
|
+
'0-4 Years': 6,
|
|
11196
|
+
'5-11 Years': 8.7,
|
|
11197
|
+
'12-15 Years': 5.1,
|
|
11198
|
+
'16-17 Years': 2.5,
|
|
11199
|
+
'18-29 Years': 16.4,
|
|
11200
|
+
'30-39 Years': 13.5,
|
|
11201
|
+
'40-49 Years': 12.3,
|
|
11202
|
+
'50-64 Years': 19.2,
|
|
11203
|
+
'65-74 Years': 9.6,
|
|
11204
|
+
'75-84 Years': 4.9,
|
|
11205
|
+
'85-89 Years': 2
|
|
11206
|
+
},
|
|
11207
|
+
race: {
|
|
11208
|
+
White: 61.6315330007,
|
|
11209
|
+
'Black or African American': 12.4013544021,
|
|
11210
|
+
Asian: 5.9997260938,
|
|
11211
|
+
Other: 18.6347237845,
|
|
11212
|
+
'American Indian or Alaska Native': 1.1244963298,
|
|
11213
|
+
'Native Hawaiian or Other Pacific Islander': 0.2081663891,
|
|
11214
|
+
'Not Reported': 0
|
|
11215
|
+
},
|
|
11216
|
+
ethnicity: {
|
|
11217
|
+
'Hispanic or Latino': 18.7298774077,
|
|
11218
|
+
'Not Hispanic or Latino': 81.2701225923,
|
|
11219
|
+
'Not Reported': 0
|
|
11220
|
+
},
|
|
11221
|
+
sex: {
|
|
11222
|
+
Female: 50.75,
|
|
11223
|
+
Male: 49.25,
|
|
11224
|
+
'Not Reported': 0
|
|
11225
|
+
},
|
|
11226
|
+
race_and_ethnicity: {
|
|
11227
|
+
'Hispanic or Latino': 18.45,
|
|
11228
|
+
'American Indian or Alaska Native, Not Hispanic or Latino': 0.74,
|
|
11229
|
+
'Asian, Not Hispanic or Latino': 5.76,
|
|
11230
|
+
'Black, Not Hispanic or Latino': 12.54,
|
|
11231
|
+
'Native Hawaiian or Other Pacific Islander, Not Hispanic or Latino': 0.182,
|
|
11232
|
+
'White, Not Hispanic or Latino': 60.11,
|
|
11233
|
+
'Multiple or Other, Not Hispanic or Latino': 2.22,
|
|
11234
|
+
'Not Reported': 0
|
|
11235
|
+
}
|
|
11236
|
+
}
|
|
11237
|
+
})[dataset];
|
|
11238
|
+
};
|
|
11239
|
+
|
|
11240
|
+
const convertToValidJSON = (inputString)=>{
|
|
11241
|
+
// Remove all newline characters and extra spaces
|
|
11242
|
+
let cleanedString = inputString.replace(/\s+/g, ' ').trim();
|
|
11243
|
+
// Add quotes around property names that aren't already quoted
|
|
11244
|
+
cleanedString = cleanedString.replace(/(\w+):/g, '"$1":');
|
|
11245
|
+
// Replace single quotes with double quotes (if any)
|
|
11246
|
+
cleanedString = cleanedString.replace(/'/g, '"');
|
|
11247
|
+
return cleanedString;
|
|
11248
|
+
};
|
|
11249
|
+
const createDiversityQuery = (fields = {
|
|
11250
|
+
age_at_index: 'age_at_index',
|
|
11251
|
+
sex: 'sex',
|
|
11252
|
+
ethnicity: 'ethnicity',
|
|
11253
|
+
race: 'race'
|
|
11254
|
+
})=>{
|
|
11255
|
+
// TODO refactor to make this usable for all facets
|
|
11256
|
+
return {
|
|
11257
|
+
query: `
|
|
11258
|
+
query ($filter_0_4: JSON, $filter_5_11: JSON, $filter_12_15: JSON, $filter_16_17: JSON, $filter_18_29: JSON, $filter_30_39: JSON, $filter_40_49: JSON, $filter_50_64: JSON, $filter_65_74: JSON, $filter_75_84: JSON, $filter_85_plus: JSON) {
|
|
11259
|
+
_aggregation {
|
|
11260
|
+
case {
|
|
11261
|
+
_totalCount
|
|
11262
|
+
${fields['sex']} {
|
|
11263
|
+
histogram {
|
|
11264
|
+
key
|
|
11265
|
+
count
|
|
11266
|
+
}
|
|
11267
|
+
}
|
|
11268
|
+
${fields['ethnicity']} {
|
|
11269
|
+
histogram {
|
|
11270
|
+
key
|
|
11271
|
+
count
|
|
11272
|
+
}
|
|
11273
|
+
},
|
|
11274
|
+
${fields['race']} {
|
|
11275
|
+
histogram {
|
|
11276
|
+
key
|
|
11277
|
+
count
|
|
11278
|
+
}
|
|
11279
|
+
}
|
|
9816
11280
|
}
|
|
9817
|
-
|
|
9818
|
-
|
|
11281
|
+
case_0_4: case(filter: $filter_0_4, filterSelf: true, accessibility: all) {
|
|
11282
|
+
${fields['age_at_index']} {
|
|
11283
|
+
histogram {
|
|
11284
|
+
key
|
|
11285
|
+
count
|
|
11286
|
+
}
|
|
11287
|
+
}
|
|
9819
11288
|
}
|
|
9820
|
-
|
|
9821
|
-
|
|
9822
|
-
|
|
9823
|
-
|
|
9824
|
-
|
|
9825
|
-
|
|
9826
|
-
|
|
9827
|
-
|
|
9828
|
-
|
|
9829
|
-
|
|
11289
|
+
case_5_11: case(filter: $filter_5_11, filterSelf: true, accessibility: all) {
|
|
11290
|
+
${fields['age_at_index']} {
|
|
11291
|
+
histogram {
|
|
11292
|
+
key
|
|
11293
|
+
count
|
|
11294
|
+
}
|
|
11295
|
+
}
|
|
11296
|
+
}
|
|
11297
|
+
case_12_15: case(filter: $filter_12_15, filterSelf: true, accessibility: all) {
|
|
11298
|
+
${fields['age_at_index']} {
|
|
11299
|
+
histogram {
|
|
11300
|
+
key
|
|
11301
|
+
count
|
|
11302
|
+
}
|
|
11303
|
+
}
|
|
11304
|
+
}
|
|
11305
|
+
case_16_17: case(filter: $filter_16_17, filterSelf: true, accessibility: all) {
|
|
11306
|
+
${fields['age_at_index']} {
|
|
11307
|
+
histogram {
|
|
11308
|
+
key
|
|
11309
|
+
count
|
|
11310
|
+
}
|
|
11311
|
+
}
|
|
11312
|
+
}
|
|
11313
|
+
case_18_29: case(filter: $filter_18_29, filterSelf: true, accessibility: all) {
|
|
11314
|
+
${fields['age_at_index']} {
|
|
11315
|
+
histogram {
|
|
11316
|
+
key
|
|
11317
|
+
count
|
|
11318
|
+
}
|
|
11319
|
+
}
|
|
11320
|
+
}
|
|
11321
|
+
case_30_39: case(filter: $filter_30_39, filterSelf: true, accessibility: all) {
|
|
11322
|
+
${fields['age_at_index']} {
|
|
11323
|
+
histogram {
|
|
11324
|
+
key
|
|
11325
|
+
count
|
|
11326
|
+
}
|
|
11327
|
+
}
|
|
11328
|
+
}
|
|
11329
|
+
case_40_49: case(filter: $filter_40_49, filterSelf: true, accessibility: all) {
|
|
11330
|
+
${fields['age_at_index']} {
|
|
11331
|
+
histogram {
|
|
11332
|
+
key
|
|
11333
|
+
count
|
|
11334
|
+
}
|
|
11335
|
+
}
|
|
11336
|
+
}
|
|
11337
|
+
case_50_64: case(filter: $filter_50_64, filterSelf: true, accessibility: all) {
|
|
11338
|
+
${fields['age_at_index']} {
|
|
11339
|
+
histogram {
|
|
11340
|
+
key
|
|
11341
|
+
count
|
|
11342
|
+
}
|
|
11343
|
+
}
|
|
11344
|
+
}
|
|
11345
|
+
case_65_74: case(filter: $filter_65_74, filterSelf: true, accessibility: all) {
|
|
11346
|
+
${fields['age_at_index']} {
|
|
11347
|
+
histogram {
|
|
11348
|
+
key
|
|
11349
|
+
count
|
|
11350
|
+
}
|
|
11351
|
+
}
|
|
11352
|
+
}
|
|
11353
|
+
case_75_84: case(filter: $filter_75_84, filterSelf: true, accessibility: all) {
|
|
11354
|
+
${fields['age_at_index']} {
|
|
11355
|
+
histogram {
|
|
11356
|
+
key
|
|
11357
|
+
count
|
|
11358
|
+
}
|
|
11359
|
+
}
|
|
11360
|
+
}
|
|
11361
|
+
case_85_plus: case(filter: $filter_85_plus, filterSelf: true, accessibility: all) {
|
|
11362
|
+
${fields['age_at_index']} {
|
|
11363
|
+
histogram {
|
|
11364
|
+
key
|
|
11365
|
+
count
|
|
11366
|
+
}
|
|
11367
|
+
}
|
|
11368
|
+
}
|
|
11369
|
+
}
|
|
11370
|
+
}`,
|
|
11371
|
+
variables: convertToValidJSON(`{ "filter_0_4": {
|
|
11372
|
+
"AND": [
|
|
11373
|
+
{
|
|
11374
|
+
">=": {
|
|
11375
|
+
${fields['age_at_index']}: 0
|
|
11376
|
+
}
|
|
11377
|
+
},
|
|
11378
|
+
{
|
|
11379
|
+
"<=": {
|
|
11380
|
+
${fields['age_at_index']}: 4
|
|
11381
|
+
}
|
|
11382
|
+
}
|
|
11383
|
+
]
|
|
11384
|
+
},
|
|
11385
|
+
"filter_5_11": {
|
|
11386
|
+
"AND": [
|
|
11387
|
+
{
|
|
11388
|
+
">=": {
|
|
11389
|
+
${fields['age_at_index']}: 5
|
|
11390
|
+
}
|
|
11391
|
+
},
|
|
11392
|
+
{
|
|
11393
|
+
"<=": {
|
|
11394
|
+
${fields['age_at_index']}: 11
|
|
11395
|
+
}
|
|
11396
|
+
}
|
|
11397
|
+
]
|
|
11398
|
+
},
|
|
11399
|
+
"filter_12_15": {
|
|
11400
|
+
"AND": [
|
|
11401
|
+
{
|
|
11402
|
+
">=": {
|
|
11403
|
+
${fields['age_at_index']}: 12
|
|
11404
|
+
}
|
|
11405
|
+
},
|
|
11406
|
+
{
|
|
11407
|
+
"<=": {
|
|
11408
|
+
${fields['age_at_index']}: 15
|
|
11409
|
+
}
|
|
11410
|
+
}
|
|
11411
|
+
]
|
|
11412
|
+
},
|
|
11413
|
+
"filter_16_17": {
|
|
11414
|
+
"AND": [
|
|
11415
|
+
{
|
|
11416
|
+
">=": {
|
|
11417
|
+
${fields['age_at_index']}: 16
|
|
11418
|
+
}
|
|
11419
|
+
},
|
|
11420
|
+
{
|
|
11421
|
+
"<=": {
|
|
11422
|
+
${fields['age_at_index']}: 17
|
|
11423
|
+
}
|
|
11424
|
+
}
|
|
11425
|
+
]
|
|
11426
|
+
},
|
|
11427
|
+
"filter_18_29": {
|
|
11428
|
+
"AND": [
|
|
11429
|
+
{
|
|
11430
|
+
">=": {
|
|
11431
|
+
${fields['age_at_index']}: 18
|
|
11432
|
+
}
|
|
11433
|
+
},
|
|
11434
|
+
{
|
|
11435
|
+
"<=": {
|
|
11436
|
+
${fields['age_at_index']}: 29
|
|
11437
|
+
}
|
|
11438
|
+
}
|
|
11439
|
+
]
|
|
11440
|
+
},
|
|
11441
|
+
"filter_30_39": {
|
|
11442
|
+
"AND": [
|
|
11443
|
+
{
|
|
11444
|
+
">=": {
|
|
11445
|
+
${fields['age_at_index']}: 30
|
|
11446
|
+
}
|
|
11447
|
+
},
|
|
11448
|
+
{
|
|
11449
|
+
"<=": {
|
|
11450
|
+
${fields['age_at_index']}: 39
|
|
11451
|
+
}
|
|
11452
|
+
}
|
|
11453
|
+
]
|
|
11454
|
+
},
|
|
11455
|
+
"filter_40_49": {
|
|
11456
|
+
"AND": [
|
|
11457
|
+
{
|
|
11458
|
+
">=": {
|
|
11459
|
+
${fields['age_at_index']}: 40
|
|
11460
|
+
}
|
|
11461
|
+
},
|
|
11462
|
+
{
|
|
11463
|
+
"<=": {
|
|
11464
|
+
${fields['age_at_index']}: 49
|
|
11465
|
+
}
|
|
11466
|
+
}
|
|
11467
|
+
]
|
|
11468
|
+
},
|
|
11469
|
+
"filter_50_64": {
|
|
11470
|
+
"AND": [
|
|
11471
|
+
{
|
|
11472
|
+
">=": {
|
|
11473
|
+
${fields['age_at_index']}: 50
|
|
11474
|
+
}
|
|
11475
|
+
},
|
|
11476
|
+
{
|
|
11477
|
+
"<=": {
|
|
11478
|
+
${fields['age_at_index']}: 64
|
|
11479
|
+
}
|
|
11480
|
+
}
|
|
11481
|
+
]
|
|
11482
|
+
},
|
|
11483
|
+
"filter_65_74": {
|
|
11484
|
+
"AND": [
|
|
11485
|
+
{
|
|
11486
|
+
">=": {
|
|
11487
|
+
${fields['age_at_index']}: 65
|
|
11488
|
+
}
|
|
11489
|
+
},
|
|
11490
|
+
{
|
|
11491
|
+
"<=": {
|
|
11492
|
+
${fields['age_at_index']}: 74
|
|
11493
|
+
}
|
|
11494
|
+
}
|
|
11495
|
+
]
|
|
11496
|
+
},
|
|
11497
|
+
"filter_75_84": {
|
|
11498
|
+
"AND": [
|
|
11499
|
+
{
|
|
11500
|
+
">=": {
|
|
11501
|
+
${fields['age_at_index']}: 75
|
|
11502
|
+
}
|
|
11503
|
+
},
|
|
11504
|
+
{
|
|
11505
|
+
"<=": {
|
|
11506
|
+
${fields['age_at_index']}: 84
|
|
11507
|
+
}
|
|
11508
|
+
}
|
|
11509
|
+
]
|
|
11510
|
+
},
|
|
11511
|
+
"filter_85_plus": {
|
|
11512
|
+
"AND": [
|
|
11513
|
+
{
|
|
11514
|
+
">=": {
|
|
11515
|
+
${fields['age_at_index']}: 85
|
|
11516
|
+
}
|
|
11517
|
+
}
|
|
11518
|
+
]
|
|
11519
|
+
}
|
|
11520
|
+
}`)
|
|
9830
11521
|
};
|
|
9831
|
-
return new ContentDatabase(config);
|
|
9832
11522
|
};
|
|
9833
|
-
const ContentSource = setup();
|
|
9834
11523
|
|
|
9835
|
-
|
|
9836
|
-
|
|
9837
|
-
|
|
9838
|
-
|
|
9839
|
-
|
|
9840
|
-
|
|
9841
|
-
|
|
9842
|
-
|
|
9843
|
-
|
|
9844
|
-
|
|
9845
|
-
|
|
9846
|
-
}
|
|
9847
|
-
const { topBar, navigation, type = 'original' } = navigationConfigJSON;
|
|
9848
|
-
const headerProps = {
|
|
9849
|
-
top: topBar,
|
|
9850
|
-
navigation: navigation,
|
|
9851
|
-
banners: bannerConfigJSON,
|
|
9852
|
-
type
|
|
9853
|
-
};
|
|
9854
|
-
const footerProps = await ContentSource.get(`config/${GEN3_COMMONS_NAME}/footer.json`);
|
|
9855
|
-
return {
|
|
9856
|
-
headerProps,
|
|
9857
|
-
footerProps,
|
|
9858
|
-
headerData: {
|
|
9859
|
-
title: 'Gen3 Frontend Framework Page',
|
|
9860
|
-
content: 'Gen3 Frontend Framework Page',
|
|
9861
|
-
key: 'gen3-common-page'
|
|
11524
|
+
const CohortDiversityApp = (config)=>{
|
|
11525
|
+
const groundDataset = getStaticDiversityData(config.datasets.ground.dataset);
|
|
11526
|
+
const gqlQuery = createDiversityQuery(); // TODO: add field mapping
|
|
11527
|
+
const { data: rawComparisonDataset, isLoading: isComparisonLoading, isError: isComparisonError } = useGeneralGQLQuery({
|
|
11528
|
+
query: gqlQuery.query,
|
|
11529
|
+
variables: JSON.parse(gqlQuery.variables)
|
|
11530
|
+
});
|
|
11531
|
+
const comparisonDataset = useMemo(()=>{
|
|
11532
|
+
if (rawComparisonDataset) {
|
|
11533
|
+
const results = processHistogramResponseAsPercentage(rawComparisonDataset.data);
|
|
11534
|
+
return alignData(normalizeAgeOfIndex(results), groundDataset);
|
|
9862
11535
|
}
|
|
9863
|
-
|
|
11536
|
+
return undefined;
|
|
11537
|
+
}, [
|
|
11538
|
+
groundDataset,
|
|
11539
|
+
rawComparisonDataset
|
|
11540
|
+
]);
|
|
11541
|
+
if (isComparisonError) {
|
|
11542
|
+
return /*#__PURE__*/ jsx(ErrorCard, {
|
|
11543
|
+
message: 'Unable to get data need for Cohort Diversity'
|
|
11544
|
+
});
|
|
11545
|
+
}
|
|
11546
|
+
if (isComparisonLoading) {
|
|
11547
|
+
return /*#__PURE__*/ jsx(LoadingOverlay, {
|
|
11548
|
+
visible: true
|
|
11549
|
+
});
|
|
11550
|
+
}
|
|
11551
|
+
return /*#__PURE__*/ jsxs(Stack, {
|
|
11552
|
+
classNames: {
|
|
11553
|
+
root: 'w-full m-4 mb-2'
|
|
11554
|
+
},
|
|
11555
|
+
"aria-label": "Main Content of Cohort Diversity App",
|
|
11556
|
+
children: [
|
|
11557
|
+
/*#__PURE__*/ jsx(Title, {
|
|
11558
|
+
order: 1,
|
|
11559
|
+
size: "h3",
|
|
11560
|
+
children: "Cohort Diversity Visualization"
|
|
11561
|
+
}),
|
|
11562
|
+
/*#__PURE__*/ jsx(Accordion, {
|
|
11563
|
+
variant: "filled",
|
|
11564
|
+
chevronPosition: "left",
|
|
11565
|
+
children: /*#__PURE__*/ jsxs(Accordion.Item, {
|
|
11566
|
+
value: "summaryCharts",
|
|
11567
|
+
"aria-label": "Summary Charts",
|
|
11568
|
+
children: [
|
|
11569
|
+
/*#__PURE__*/ jsx(Accordion.Control, {
|
|
11570
|
+
children: /*#__PURE__*/ jsxs("div", {
|
|
11571
|
+
className: "flex items-center justify-start space-x-2 text-accent",
|
|
11572
|
+
children: [
|
|
11573
|
+
/*#__PURE__*/ jsx(FaChartPie, {
|
|
11574
|
+
style: {
|
|
11575
|
+
color: 'secondary.4',
|
|
11576
|
+
width: rem(32),
|
|
11577
|
+
height: rem(32)
|
|
11578
|
+
}
|
|
11579
|
+
}),
|
|
11580
|
+
/*#__PURE__*/ jsx(Text, {
|
|
11581
|
+
fw: 600,
|
|
11582
|
+
children: "Summary Charts"
|
|
11583
|
+
})
|
|
11584
|
+
]
|
|
11585
|
+
})
|
|
11586
|
+
}),
|
|
11587
|
+
/*#__PURE__*/ jsx(Accordion.Panel, {
|
|
11588
|
+
children: /*#__PURE__*/ jsx(Charts, {
|
|
11589
|
+
data: groundDataset ?? {},
|
|
11590
|
+
charts: config.charts,
|
|
11591
|
+
isSuccess: true,
|
|
11592
|
+
numCols: 2
|
|
11593
|
+
})
|
|
11594
|
+
})
|
|
11595
|
+
]
|
|
11596
|
+
})
|
|
11597
|
+
}),
|
|
11598
|
+
/*#__PURE__*/ jsx(ComparisonCharts, {
|
|
11599
|
+
ground: groundDataset ?? {},
|
|
11600
|
+
groundLabel: config.datasets.ground.label,
|
|
11601
|
+
comparison: comparisonDataset ?? {},
|
|
11602
|
+
comparisonLabel: config.datasets.comparison[0].label,
|
|
11603
|
+
comparisonChartsConfig: config.comparisonCharts,
|
|
11604
|
+
numberOfColumns: config?.numberOfColumns
|
|
11605
|
+
})
|
|
11606
|
+
]
|
|
11607
|
+
});
|
|
9864
11608
|
};
|
|
9865
11609
|
|
|
11610
|
+
const { appApi: diversityApi, appStore, appContext } = createAppApiForRTKQ('cohortDiversity');
|
|
11611
|
+
|
|
11612
|
+
const _APP_NAME = 'CohortDiversity'; // This wil be the route name of the app
|
|
11613
|
+
const _APP_VERSION = '1.0.0';
|
|
11614
|
+
const AppId = getGen3AppId(_APP_NAME, _APP_VERSION);
|
|
11615
|
+
const registerCohortDiversityApp = ()=>createGen3AppWithOwnStore({
|
|
11616
|
+
App: CohortDiversityApp,
|
|
11617
|
+
name: _APP_NAME,
|
|
11618
|
+
version: 'v1.0.0',
|
|
11619
|
+
id: AppId,
|
|
11620
|
+
requiredEntityTypes: [],
|
|
11621
|
+
store: appStore,
|
|
11622
|
+
context: appContext
|
|
11623
|
+
});
|
|
11624
|
+
|
|
9866
11625
|
// Define theme for mantine v7
|
|
9867
11626
|
const createMantineTheme = (fonts, colors)=>{
|
|
9868
11627
|
const theme = createTheme({
|
|
@@ -13041,7 +14800,10 @@ const AdminAuthZPageGetServerSideProps = async ()=>{
|
|
|
13041
14800
|
try {
|
|
13042
14801
|
const contents = fs.readFileSync(path.join(rootPath, filepath), 'utf8');
|
|
13043
14802
|
data = await YAML.parse(contents);
|
|
13044
|
-
} catch (
|
|
14803
|
+
} catch (error) {
|
|
14804
|
+
if (error instanceof Error) {
|
|
14805
|
+
console.error(error.message);
|
|
14806
|
+
}
|
|
13045
14807
|
throw new Error(`Cannot process ${rootPath}${filepath}`);
|
|
13046
14808
|
}
|
|
13047
14809
|
return {
|
|
@@ -14017,5 +15779,5 @@ async function credentialsLogout(req, res) {
|
|
|
14017
15779
|
res.redirect(307, '/');
|
|
14018
15780
|
}
|
|
14019
15781
|
|
|
14020
|
-
export { AISearchPageGetServerSideProps, AdminAuthZPageGetServerSideProps, AiSearch, AISearchPage as AiSearchPage, AuthzPage, BaseModal, Charts, CohortBuilder, ColorThemePage, ColorThemePageGetServerSideProps, ContentSource, CreateCredentialsAPIKeyModal, CrosswalkPage, CrosswalkPageGetServerSideProps, Custom404Page, DictionaryPage, DictionaryPageGetServerSideProps, DiscoveryCellRendererFactory, DiscoveryProvider as DiscoveryConfigProvider, DiscoveryIndexPanel, DiscoveryPage, DiscoveryPageGetServerSideProps, DiscoveryRowRendererFactory, EnumFacetChart, ErrorCard, ExplorerPage, ExplorerPageGetServerSideProps, ExplorerTableCellRendererFactory, ExplorerTableDetailsPanelFactory, FirstTimeModal, Footer, Gen3Link, Gen3ModalsProvider, Gen3Provider, GqlQueryEditor$1 as GqlQueryEditor, Header, HoverLink, LandingPage, LandingPageGetStaticProps, LoginButton, LoginPage, LoginPageGetServerSideProps, LoginPanel, LoginProvidersPanel, NavPageLayout, NavigationBar, NavigationButton, NoAccessModal, ProfilePage, ProfilePageGetServerSideProps, ProfileProvider, QueryPage, QueryPageGetServerSideProps, ReactECharts, ResourcesFilters, SessionExpiredModal, StudyGroup, SubmissionPage, SubmissionPageGetServerSideProps, TagCloud, TailwindConfig, User, WorkspacesPage, WorkspacesPageGetServerSideProps, WorkspacesPanel, capitalize, computeRowSpan, create10ColorAccessibleContrast, create10ColorPallet, credentialsLogin, credentialsLogout, extractObjectKey, focusStyles, getCurrentUnixTimestamp, getNavPageLayoutPropsFromConfig, getParamsValueAsString, getTagInfo, hasOwnProperty, isArrayOfString, isPropertyKey, isTextTransform$1 as isTextTransform, processLabel$1 as processLabel, processRangeKeyLabel, registerCohortBuilderDefaultPreviewRenderers, registerDefaultDiscoveryDataLoaders, registerDiscoveryDefaultCellRenderers, registerDiscoveryDefaultStudyPreviewRenderers, registerExplorerDefaultCellRenderers, removeKey$1 as removeKey, resourcePathFromProjectID, sessionLogout, sessionToken, stripTrailingSlash, truncateString, unixTimeToString, useDiscoveryContext, userHasMethodForServiceOnResource$1 as userHasMethodForServiceOnResource };
|
|
15782
|
+
export { AISearchPageGetServerSideProps, AdminAuthZPageGetServerSideProps, AiSearch, AISearchPage as AiSearchPage, AuthzPage, BaseModal, Charts, CohortBuilder, ColorThemePage, ColorThemePageGetServerSideProps, ContentSource, CreateCredentialsAPIKeyModal, CrosswalkPage, CrosswalkPageGetServerSideProps, Custom404Page, DictionaryPage, DictionaryPageGetServerSideProps, DiscoveryCellRendererFactory, DiscoveryProvider as DiscoveryConfigProvider, DiscoveryIndexPanel, DiscoveryPage, DiscoveryPageGetServerSideProps, DiscoveryRowRendererFactory, EnumFacetChart, ErrorCard, ExplorerPage, ExplorerPageGetServerSideProps, ExplorerTableCellRendererFactory, ExplorerTableDetailsPanelFactory, FirstTimeModal, Footer, Gen3Link, Gen3ModalsProvider, Gen3Provider, GqlQueryEditor$1 as GqlQueryEditor, Header, HoverLink, LandingPage, LandingPageGetStaticProps, LoginButton, LoginPage, LoginPageGetServerSideProps, LoginPanel, LoginProvidersPanel, NavPageLayout, NavigationBar, NavigationButton, NoAccessModal, ProfilePage, ProfilePageGetServerSideProps, ProfileProvider, QueryPage, QueryPageGetServerSideProps, ReactECharts, ResourcesFilters, SPECIAL_CASE_FIELDS, SessionExpiredModal, StudyGroup, SubmissionPage, SubmissionPageGetServerSideProps, TagCloud, TailwindConfig, User, WorkspacesPage, WorkspacesPageGetServerSideProps, WorkspacesPanel, capitalize, computeRowSpan, create10ColorAccessibleContrast, create10ColorPallet, credentialsLogin, credentialsLogout, extractObjectKey, focusStyles, getCurrentUnixTimestamp, getNavPageLayoutPropsFromConfig, getParamsValueAsString, getTagInfo, hasOwnProperty, isArrayOfString, isPropertyKey, isTextTransform$1 as isTextTransform, processLabel$1 as processLabel, processRangeKeyLabel, registerCohortBuilderDefaultPreviewRenderers, registerCohortDiscoveryApp, registerCohortDiversityApp, registerDefaultDiscoveryDataLoaders, registerDiscoveryDefaultCellRenderers, registerDiscoveryDefaultStudyPreviewRenderers, registerExplorerDefaultCellRenderers, removeKey$1 as removeKey, resourcePathFromProjectID, sessionLogout, sessionToken, stripTrailingSlash, toDisplayName, truncateString, unixTimeToString, useDiscoveryContext, userHasMethodForServiceOnResource$1 as userHasMethodForServiceOnResource };
|
|
14021
15783
|
//# sourceMappingURL=index.js.map
|