synapse-react-client 4.0.23 → 4.0.25
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/SWC.index.d.ts +1 -0
- package/dist/SWC.index.d.ts.map +1 -1
- package/dist/SWC.index.js +2 -1
- package/dist/SWC.index.js.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/DataAccessRequestAccessorsFilesForm/DataAccessRequestAccessorsFilesForm.js.map +1 -1
- package/dist/components/AclEditor/useUpdateAcl.js.map +1 -1
- package/dist/components/Authentication/TwoFactorBackupCodes.js.map +1 -1
- package/dist/components/Authentication/TwoFactorEnrollmentForm.js.map +1 -1
- package/dist/components/Breadcrumbs/Breadcrumbs.d.ts +3 -0
- package/dist/components/Breadcrumbs/Breadcrumbs.d.ts.map +1 -1
- package/dist/components/Breadcrumbs/Breadcrumbs.js +43 -30
- package/dist/components/Breadcrumbs/Breadcrumbs.js.map +1 -1
- package/dist/components/CannedRejectionDialog/CannedRejectionDialog.js.map +1 -1
- package/dist/components/ChallengeSubmission/SubmissionDirectoryList.js.map +1 -1
- package/dist/components/CopyToClipboardString/CopyToClipboardString.d.ts +7 -1
- package/dist/components/CopyToClipboardString/CopyToClipboardString.d.ts.map +1 -1
- package/dist/components/CopyToClipboardString/CopyToClipboardString.js +22 -16
- package/dist/components/CopyToClipboardString/CopyToClipboardString.js.map +1 -1
- package/dist/components/EntityCitation/EntityCitation.d.ts.map +1 -1
- package/dist/components/EntityCitation/EntityCitation.js +28 -26
- package/dist/components/EntityCitation/EntityCitation.js.map +1 -1
- package/dist/components/EntityFinder/tree/EntityTree.js.map +1 -1
- package/dist/components/EntityFinder/tree/VirtualizedTree.js.map +1 -1
- package/dist/components/EntityIcon.d.ts +1 -0
- package/dist/components/EntityIcon.d.ts.map +1 -1
- package/dist/components/EntityIcon.js +37 -36
- package/dist/components/EntityIcon.js.map +1 -1
- package/dist/components/EntitySidebar/EntitySidebar.css +1 -0
- package/dist/components/EntitySidebar/EntitySidebar.d.ts +7 -0
- package/dist/components/EntitySidebar/EntitySidebar.d.ts.map +1 -0
- package/dist/components/EntitySidebar/EntitySidebar.js +62 -0
- package/dist/components/EntitySidebar/EntitySidebar.js.map +1 -0
- package/dist/components/EntitySidebar/EntitySidebar.module.js +17 -0
- package/dist/components/EntitySidebar/EntitySidebar.module.js.map +1 -0
- package/dist/components/EntitySidebar/EntitySidebar.module.scss +87 -0
- package/dist/components/Evaluation/EvaluationRoundEditorList.js.map +1 -1
- package/dist/components/GenericCard/BioregistryRules.js.map +1 -1
- package/dist/components/IconSvg/IconSvg.d.ts +2 -1
- package/dist/components/IconSvg/IconSvg.d.ts.map +1 -1
- package/dist/components/IconSvg/IconSvg.js +112 -89
- package/dist/components/IconSvg/IconSvg.js.map +1 -1
- package/dist/components/Plot/SynapsePlot.d.ts +4 -0
- package/dist/components/Plot/SynapsePlot.d.ts.map +1 -1
- package/dist/components/Plot/SynapsePlot.js +57 -44
- package/dist/components/Plot/SynapsePlot.js.map +1 -1
- package/dist/components/Plot/UpsetPlot.js.map +1 -1
- package/dist/components/QueryWrapperPlotNav/QueryWrapperSynapsePlot.d.ts.map +1 -1
- package/dist/components/QueryWrapperPlotNav/QueryWrapperSynapsePlot.js +77 -34
- package/dist/components/QueryWrapperPlotNav/QueryWrapperSynapsePlot.js.map +1 -1
- package/dist/components/SchemaDrivenAnnotationEditor/field/AdditionalPropertiesSchemaField.js.map +1 -1
- package/dist/components/SearchQueryWrapperPlotNav/SearchQueryWrapperPlotNav.d.ts.map +1 -1
- package/dist/components/SearchQueryWrapperPlotNav/SearchQueryWrapperPlotNav.js +1 -0
- package/dist/components/SearchQueryWrapperPlotNav/SearchQueryWrapperPlotNav.js.map +1 -1
- package/dist/components/StorybookComponentWrapper.js.map +1 -1
- package/dist/components/SynapseTable/TablePagination.js.map +1 -1
- package/dist/components/SynapseTable/datasets/DatasetItemsEditor.js.map +1 -1
- package/dist/components/TableColumnSchemaEditor/TableColumnSchemaForm.js.map +1 -1
- package/dist/components/TanStackTable/StyledTanStackTable.js.map +1 -1
- package/dist/components/entity/page/action_menu/EntityActionMenu.d.ts +2 -0
- package/dist/components/entity/page/action_menu/EntityActionMenu.d.ts.map +1 -1
- package/dist/components/entity/page/action_menu/EntityActionMenu.js +46 -27
- package/dist/components/entity/page/action_menu/EntityActionMenu.js.map +1 -1
- package/dist/components/entity/page/breadcrumbs/EntityPageBreadcrumbs.d.ts +1 -8
- package/dist/components/entity/page/breadcrumbs/EntityPageBreadcrumbs.d.ts.map +1 -1
- package/dist/components/entity/page/breadcrumbs/EntityPageBreadcrumbs.js +17 -13
- package/dist/components/entity/page/breadcrumbs/EntityPageBreadcrumbs.js.map +1 -1
- package/dist/components/entity/page/title_bar/EntityPageTitleBar.d.ts +1 -0
- package/dist/components/entity/page/title_bar/EntityPageTitleBar.d.ts.map +1 -1
- package/dist/components/entity/page/title_bar/EntityPageTitleBar.js +35 -22
- package/dist/components/entity/page/title_bar/EntityPageTitleBar.js.map +1 -1
- package/dist/components/entity/page/title_bar/EntityTitleBarVersionInfo.d.ts.map +1 -1
- package/dist/components/entity/page/title_bar/EntityTitleBarVersionInfo.js +34 -20
- package/dist/components/entity/page/title_bar/EntityTitleBarVersionInfo.js.map +1 -1
- package/dist/components/entity/page/title_bar/TitleBarProperties.d.ts +0 -1
- package/dist/components/entity/page/title_bar/TitleBarProperties.d.ts.map +1 -1
- package/dist/components/entity/page/title_bar/TitleBarProperties.js +17 -82
- package/dist/components/entity/page/title_bar/TitleBarProperties.js.map +1 -1
- package/dist/components/entity/page/title_bar/useGetEntityTitleBarProperties.d.ts.map +1 -1
- package/dist/components/entity/page/title_bar/useGetEntityTitleBarProperties.js +3 -4
- package/dist/components/entity/page/title_bar/useGetEntityTitleBarProperties.js.map +1 -1
- package/dist/components/favorites/FavoriteButton.d.ts +1 -0
- package/dist/components/favorites/FavoriteButton.d.ts.map +1 -1
- package/dist/components/favorites/FavoriteButton.js +8 -8
- package/dist/components/favorites/FavoriteButton.js.map +1 -1
- package/dist/components/menu/ComplexMenu.d.ts.map +1 -1
- package/dist/components/menu/ComplexMenu.js +5 -3
- package/dist/components/menu/ComplexMenu.js.map +1 -1
- package/dist/components/menu/DropdownMenu.d.ts +1 -0
- package/dist/components/menu/DropdownMenu.d.ts.map +1 -1
- package/dist/components/menu/DropdownMenu.js +24 -24
- package/dist/components/menu/DropdownMenu.js.map +1 -1
- package/dist/components/widgets/facet-nav/FacetNavPanel.d.ts.map +1 -1
- package/dist/components/widgets/facet-nav/FacetNavPanel.js +59 -49
- package/dist/components/widgets/facet-nav/FacetNavPanel.js.map +1 -1
- package/dist/components/widgets/facet-nav/PlotsContainer.d.ts.map +1 -1
- package/dist/components/widgets/facet-nav/PlotsContainer.js +8 -2
- package/dist/components/widgets/facet-nav/PlotsContainer.js.map +1 -1
- package/dist/style/components/facet_nav/_facet-nav-panel.scss +11 -0
- package/dist/style/main.css +1 -1
- package/dist/testutils/ReactQueryMockUtils.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/types/ThemeTypes.d.ts +2 -2
- package/dist/utils/functions/IsEqualTreatUndefinedAsMissing.js.map +1 -1
- package/dist/utils/hooks/useDebouncedEffect.js.map +1 -1
- package/dist/utils/hooks/useDetectSSOCode.js.map +1 -1
- package/dist/utils/hooks/useImmutableTableQuery/useImmutableTableQuery.js.map +1 -1
- package/dist/utils/hooks/useLogin.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlotsContainer.js","names":[],"sources":["../../../../src/components/widgets/facet-nav/PlotsContainer.tsx"],"sourcesContent":["import { UniqueFacetIdentifier } from '@/utils'\nimport { facetObjectMatchesDefinition } from '@/utils/functions/queryUtils'\nimport { Box, Button } from '@mui/material'\nimport type { PlotType as PlotlyPlotType } from 'plotly.js-basic-dist'\nimport { Suspense, useEffect, useMemo, useState } from 'react'\nimport { useQueryVisualizationContext } from '../../QueryVisualizationWrapper'\nimport { useSuspenseGetQueryMetadata } from '../../QueryWrapper/useGetQueryMetadata'\nimport QueryWrapperSynapsePlot, {\n QueryWrapperSynapsePlotProps,\n} from '../../QueryWrapperPlotNav/QueryWrapperSynapsePlot'\nimport FacetNavPanel, {\n FacetNavPanelProps,\n PlotType,\n} from '../facet-nav/FacetNavPanel'\nimport { PlotsContainerSkeleton } from './PlotsContainerSkeleton'\nimport useFacetPlots, { getFacets } from './useFacetPlots'\n\nconst DEFAULT_VISIBLE_PLOTS = 2\ntype ShowMoreState = 'MORE' | 'LESS' | 'NONE'\nexport type PlotsContainerProps = {\n facetsToPlot?: string[]\n customPlots?: QueryWrapperSynapsePlotProps[]\n initialPlotTypeByFacetColumnName?: Record<string, PlotType>\n}\ntype CustomPlotIdentifier = {\n title: string\n __custom: true\n}\nexport type PlotIdentifier = UniqueFacetIdentifier | CustomPlotIdentifier\n\nexport type UiPlotState = {\n plotId: PlotIdentifier\n isHidden: boolean\n plotType: PlotType\n index?: number\n}\nconst plotMatchesDefinition = (\n definition: PlotIdentifier,\n plotId: PlotIdentifier,\n) => {\n if ('__custom' in plotId && '__custom' in definition) {\n return definition.title == plotId.title\n } else if (!('__custom' in plotId) && !('__custom' in definition)) {\n return facetObjectMatchesDefinition(definition, plotId)\n } else {\n return false\n }\n}\n\nfunction convertPlotlyPlotTypeToFacetNavPlotType(\n plotlyPlotType: PlotlyPlotType,\n): PlotType {\n if (plotlyPlotType === 'bar') {\n return 'BAR'\n } else if (plotlyPlotType === 'pie') {\n return 'PIE'\n }\n return 'PIE'\n}\n\nconst generatePlotKey = (plotUiState: UiPlotState) => {\n if ('__custom' in plotUiState.plotId) {\n // For custom plots\n return `custom-${plotUiState.plotId.title}`\n } else {\n // For facet plots\n return `facet-${plotUiState.plotId.columnName}-${plotUiState.plotId.jsonPath}`\n }\n}\n\nconst isPlotInState = (\n plotId: PlotIdentifier,\n plotUiStateArray: UiPlotState[],\n): boolean => {\n return !!plotUiStateArray.find(plot => {\n return plotMatchesDefinition(plot.plotId, plotId)\n })\n}\n\nconst getCustomPlotIdentifier = (\n customPlot: QueryWrapperSynapsePlotProps,\n): PlotIdentifier => {\n return { __custom: true, title: customPlot.title ?? '' }\n}\n\nconst getCombinedNewPlots = (\n customPlots: QueryWrapperSynapsePlotProps[] = [],\n facetNavPanelPropsArray: Pick<\n FacetNavPanelProps,\n 'applyChangesToFacetFilter' | 'applyChangesToGraphSlice' | 'facetToPlot'\n >[] = [],\n initialPlotTypeByFacetColumnName?: Record<string, PlotType>,\n): UiPlotState[] => [\n ...customPlots.map((plotProps, index) => ({\n plotId: getCustomPlotIdentifier(plotProps),\n isHidden: index >= DEFAULT_VISIBLE_PLOTS,\n plotType: convertPlotlyPlotTypeToFacetNavPlotType(plotProps.type),\n })),\n ...facetNavPanelPropsArray.map((facetPlotProps, index) => ({\n plotId: facetPlotProps.facetToPlot,\n isHidden: index + customPlots.length >= DEFAULT_VISIBLE_PLOTS,\n plotType:\n initialPlotTypeByFacetColumnName?.[\n facetPlotProps.facetToPlot.columnName\n ] ?? DEFAULT_PLOT_TYPE,\n })),\n]\n\n// Remove plots that are no longer in props from prevPlots\nconst isPlotStillPresent = (\n prevPlot: UiPlotState,\n customPlots: QueryWrapperSynapsePlotProps[],\n facetNavPanelProps: Pick<\n FacetNavPanelProps,\n 'applyChangesToFacetFilter' | 'applyChangesToGraphSlice' | 'facetToPlot'\n >[],\n): boolean => {\n return (\n customPlots.some(customPlot =>\n plotMatchesDefinition(\n getCustomPlotIdentifier(customPlot),\n prevPlot.plotId,\n ),\n ) ||\n facetNavPanelProps.some(facetPlot =>\n plotMatchesDefinition(facetPlot.facetToPlot, prevPlot.plotId),\n )\n )\n} // fn returns true iff the plot id is in customPlots or facetNavPanelPropsArray\n\nconst DEFAULT_PLOT_TYPE: PlotType = 'PIE'\n\nconst DEFAULT_FACETS_TO_PLOT: string[] = []\nconst DEFAULT_CUSTOM_PLOTS: QueryWrapperSynapsePlotProps[] = []\n\nfunction PlotsContainer(props: PlotsContainerProps) {\n const {\n facetsToPlot = DEFAULT_FACETS_TO_PLOT,\n customPlots = DEFAULT_CUSTOM_PLOTS,\n initialPlotTypeByFacetColumnName,\n } = props\n const { data: queryMetadata } = useSuspenseGetQueryMetadata()\n const { showPlots: showPlotVisualization } = useQueryVisualizationContext()\n const [plotUiStateArray, setPlotUiStateArray] = useState<UiPlotState[]>([])\n const facetNavPanelPropsArray = useFacetPlots(facetsToPlot)\n\n const getPlotType = (plotId: PlotIdentifier): PlotType => {\n const plotType = plotUiStateArray.find(item =>\n plotMatchesDefinition(plotId, item.plotId),\n )?.plotType\n return plotType ?? DEFAULT_PLOT_TYPE\n }\n\n useEffect(() => {\n const combinedNewPlots = getCombinedNewPlots(\n customPlots,\n facetNavPanelPropsArray,\n initialPlotTypeByFacetColumnName,\n )\n\n // Update the state with new plots\n setPlotUiStateArray(prevPlots => {\n // Filter to only include new plots\n const newPlots = combinedNewPlots.filter(plot => {\n const inState = isPlotInState(plot.plotId, prevPlots)\n return !inState\n })\n\n const updatedPlots = prevPlots.filter(prevPlot =>\n isPlotStillPresent(prevPlot, customPlots, facetNavPanelPropsArray),\n )\n\n // Append new plots\n const combinedPlots = [...updatedPlots, ...newPlots]\n return combinedPlots\n })\n }, [customPlots, facetNavPanelPropsArray, initialPlotTypeByFacetColumnName])\n\n // when 'show more/less' is clicked\n const onShowMoreClick = (shouldShowMore: boolean) => {\n setPlotUiStateArray(plotUiStateArray => {\n return plotUiStateArray.map((item, index) => {\n if (shouldShowMore) {\n // show everything\n return { ...item, isHidden: false }\n }\n // otherwise hide everything except the first few items\n return { ...item, isHidden: index >= DEFAULT_VISIBLE_PLOTS }\n })\n })\n }\n\n const isPlotHiddenInGrid = (plotId: PlotIdentifier) => {\n const itemHidden = plotUiStateArray.find(\n item =>\n plotMatchesDefinition(plotId, item.plotId) && item.isHidden === true,\n )\n const result = itemHidden !== undefined\n return result\n }\n\n const showMoreButtonState = useMemo<ShowMoreState>(() => {\n if (\n // if at least one item is hidden\n plotUiStateArray.find(item => item.isHidden === true)\n ) {\n return 'MORE'\n } else if (plotUiStateArray.length <= DEFAULT_VISIBLE_PLOTS) {\n return 'NONE'\n } else {\n return 'LESS'\n }\n }, [plotUiStateArray])\n\n // hides plot graph\n const hidePlotInGrid = (plotId: PlotIdentifier) => {\n setUiPropertyForPlot(plotId, 'isHidden', true)\n }\n\n const setPlotType = (plotId: PlotIdentifier, plotType: PlotType) => {\n setUiPropertyForPlot(plotId, 'plotType', plotType)\n }\n\n const setUiPropertyForPlot = (\n plotId: PlotIdentifier,\n propName: keyof UiPlotState,\n value: boolean | PlotType, // 'the possible values of the above type' (currently can't be specified in TS using symbols)\n ) => {\n setPlotUiStateArray(plotUiStateArray =>\n plotUiStateArray.map(item =>\n plotMatchesDefinition(plotId, item.plotId)\n ? { ...item, [propName]: value }\n : item,\n ),\n )\n }\n\n const colorTracker: { facet: PlotIdentifier; colorIndex: number }[] =\n // TODO: customPlots should use the color index\n // additionally, it is unclear why this object is created\n // We can probably just pass the index from `plotUiStateArray.map)\n getFacets(queryMetadata, facetsToPlot).map((el, index) => {\n return {\n facet: { columnName: el.columnName, jsonPath: el.jsonPath },\n colorIndex: index,\n }\n })\n\n return (\n <>\n {plotUiStateArray.length > 0 && (\n <div\n className={`PlotsContainer ${showPlotVisualization ? '' : 'hidden'} ${\n showMoreButtonState === 'LESS' ? 'less' : ''\n }`}\n >\n <div className=\"PlotsContainer__row\" role=\"list\">\n {plotUiStateArray.map(plotUiState => {\n const isCustomPlot = '__custom' in plotUiState.plotId\n const customPlotProps = customPlots.find(customPlot =>\n plotMatchesDefinition(\n getCustomPlotIdentifier(customPlot),\n plotUiState.plotId,\n ),\n )\n const facetNavPanelProps = facetNavPanelPropsArray.find(props =>\n plotMatchesDefinition(props.facetToPlot, plotUiState.plotId),\n )\n\n return (\n <div\n className={\n plotUiState.plotType === 'BAR'\n ? 'PlotsContainer__row__item--full-width'\n : undefined\n }\n style={{\n minWidth: '435px',\n display: isPlotHiddenInGrid(plotUiState.plotId)\n ? 'none'\n : 'block',\n }}\n key={generatePlotKey(plotUiState)}\n >\n {isCustomPlot && customPlotProps && (\n <QueryWrapperSynapsePlot\n {...customPlotProps}\n onHide={() => hidePlotInGrid(plotUiState.plotId)}\n />\n )}\n {!isCustomPlot && facetNavPanelProps && (\n <FacetNavPanel\n index={\n colorTracker.find(el =>\n plotMatchesDefinition(el.facet, plotUiState.plotId),\n )?.colorIndex!\n }\n onHide={() => hidePlotInGrid(plotUiState.plotId)}\n plotType={getPlotType(plotUiState.plotId)}\n onSetPlotType={(plotType: PlotType) =>\n setPlotType(plotUiState.plotId, plotType)\n }\n isModalView={false}\n {...facetNavPanelProps}\n />\n )}\n </div>\n )\n })}\n </div>\n {showMoreButtonState !== 'NONE' && (\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'center',\n backgroundColor: 'grey.100',\n p: 2,\n mt: 2,\n }}\n >\n <Button\n variant=\"contained\"\n color=\"secondary\"\n onClick={() => onShowMoreClick(showMoreButtonState === 'MORE')}\n sx={{ width: '150px' }}\n >\n {showMoreButtonState === 'LESS'\n ? 'Hide Charts'\n : 'View All Charts'}\n </Button>\n </Box>\n )}\n </div>\n )}\n </>\n )\n}\n\nexport default function PlotsContainerWithSuspense(props: PlotsContainerProps) {\n const { showPlots } = useQueryVisualizationContext()\n return (\n <Suspense fallback={showPlots ? <PlotsContainerSkeleton /> : null}>\n <PlotsContainer {...props} />\n </Suspense>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PlotsContainer.js","names":[],"sources":["../../../../src/components/widgets/facet-nav/PlotsContainer.tsx"],"sourcesContent":["import { UniqueFacetIdentifier } from '@/utils'\nimport { facetObjectMatchesDefinition } from '@/utils/functions/queryUtils'\nimport { Box, Button } from '@mui/material'\nimport type { PlotType as PlotlyPlotType } from 'plotly.js-basic-dist'\nimport { Suspense, useEffect, useMemo, useState } from 'react'\nimport { useQueryVisualizationContext } from '../../QueryVisualizationWrapper'\nimport { useSuspenseGetQueryMetadata } from '../../QueryWrapper/useGetQueryMetadata'\nimport QueryWrapperSynapsePlot, {\n QueryWrapperSynapsePlotProps,\n} from '../../QueryWrapperPlotNav/QueryWrapperSynapsePlot'\nimport FacetNavPanel, {\n FacetNavPanelProps,\n PlotType,\n} from '../facet-nav/FacetNavPanel'\nimport { PlotsContainerSkeleton } from './PlotsContainerSkeleton'\nimport useFacetPlots, { getFacets } from './useFacetPlots'\n\nconst DEFAULT_VISIBLE_PLOTS = 2\ntype ShowMoreState = 'MORE' | 'LESS' | 'NONE'\nexport type PlotsContainerProps = {\n facetsToPlot?: string[]\n customPlots?: QueryWrapperSynapsePlotProps[]\n initialPlotTypeByFacetColumnName?: Record<string, PlotType>\n}\ntype CustomPlotIdentifier = {\n title: string\n __custom: true\n}\nexport type PlotIdentifier = UniqueFacetIdentifier | CustomPlotIdentifier\n\nexport type UiPlotState = {\n plotId: PlotIdentifier\n isHidden: boolean\n plotType: PlotType\n index?: number\n}\nconst plotMatchesDefinition = (\n definition: PlotIdentifier,\n plotId: PlotIdentifier,\n) => {\n if ('__custom' in plotId && '__custom' in definition) {\n return definition.title == plotId.title\n } else if (!('__custom' in plotId) && !('__custom' in definition)) {\n return facetObjectMatchesDefinition(definition, plotId)\n } else {\n return false\n }\n}\n\nfunction convertPlotlyPlotTypeToFacetNavPlotType(\n plotlyPlotType: PlotlyPlotType,\n): PlotType {\n if (plotlyPlotType === 'bar') {\n return 'BAR'\n } else if (plotlyPlotType === 'pie') {\n return 'PIE'\n }\n return 'PIE'\n}\n\nconst generatePlotKey = (plotUiState: UiPlotState) => {\n if ('__custom' in plotUiState.plotId) {\n // For custom plots\n return `custom-${plotUiState.plotId.title}`\n } else {\n // For facet plots\n return `facet-${plotUiState.plotId.columnName}-${plotUiState.plotId.jsonPath}`\n }\n}\n\nconst isPlotInState = (\n plotId: PlotIdentifier,\n plotUiStateArray: UiPlotState[],\n): boolean => {\n return !!plotUiStateArray.find(plot => {\n return plotMatchesDefinition(plot.plotId, plotId)\n })\n}\n\nconst getCustomPlotIdentifier = (\n customPlot: QueryWrapperSynapsePlotProps,\n): PlotIdentifier => {\n return { __custom: true, title: customPlot.title ?? '' }\n}\n\nconst getCombinedNewPlots = (\n customPlots: QueryWrapperSynapsePlotProps[] = [],\n facetNavPanelPropsArray: Pick<\n FacetNavPanelProps,\n 'applyChangesToFacetFilter' | 'applyChangesToGraphSlice' | 'facetToPlot'\n >[] = [],\n initialPlotTypeByFacetColumnName?: Record<string, PlotType>,\n): UiPlotState[] => [\n ...customPlots.map((plotProps, index) => ({\n plotId: getCustomPlotIdentifier(plotProps),\n isHidden: index >= DEFAULT_VISIBLE_PLOTS,\n plotType: convertPlotlyPlotTypeToFacetNavPlotType(plotProps.type),\n })),\n ...facetNavPanelPropsArray.map((facetPlotProps, index) => ({\n plotId: facetPlotProps.facetToPlot,\n isHidden: index + customPlots.length >= DEFAULT_VISIBLE_PLOTS,\n plotType:\n initialPlotTypeByFacetColumnName?.[\n facetPlotProps.facetToPlot.columnName\n ] ?? DEFAULT_PLOT_TYPE,\n })),\n]\n\n// Remove plots that are no longer in props from prevPlots\nconst isPlotStillPresent = (\n prevPlot: UiPlotState,\n customPlots: QueryWrapperSynapsePlotProps[],\n facetNavPanelProps: Pick<\n FacetNavPanelProps,\n 'applyChangesToFacetFilter' | 'applyChangesToGraphSlice' | 'facetToPlot'\n >[],\n): boolean => {\n return (\n customPlots.some(customPlot =>\n plotMatchesDefinition(\n getCustomPlotIdentifier(customPlot),\n prevPlot.plotId,\n ),\n ) ||\n facetNavPanelProps.some(facetPlot =>\n plotMatchesDefinition(facetPlot.facetToPlot, prevPlot.plotId),\n )\n )\n} // fn returns true iff the plot id is in customPlots or facetNavPanelPropsArray\n\nconst DEFAULT_PLOT_TYPE: PlotType = 'PIE'\n\nconst DEFAULT_FACETS_TO_PLOT: string[] = []\nconst DEFAULT_CUSTOM_PLOTS: QueryWrapperSynapsePlotProps[] = []\n\nfunction PlotsContainer(props: PlotsContainerProps) {\n const {\n facetsToPlot = DEFAULT_FACETS_TO_PLOT,\n customPlots = DEFAULT_CUSTOM_PLOTS,\n initialPlotTypeByFacetColumnName,\n } = props\n const { data: queryMetadata } = useSuspenseGetQueryMetadata()\n const { showPlots: showPlotVisualization } = useQueryVisualizationContext()\n const [plotUiStateArray, setPlotUiStateArray] = useState<UiPlotState[]>([])\n const facetNavPanelPropsArray = useFacetPlots(facetsToPlot)\n\n const getPlotType = (plotId: PlotIdentifier): PlotType => {\n const plotType = plotUiStateArray.find(item =>\n plotMatchesDefinition(plotId, item.plotId),\n )?.plotType\n return plotType ?? DEFAULT_PLOT_TYPE\n }\n\n useEffect(() => {\n const combinedNewPlots = getCombinedNewPlots(\n customPlots,\n facetNavPanelPropsArray,\n initialPlotTypeByFacetColumnName,\n )\n\n // Update the state with new plots\n setPlotUiStateArray(prevPlots => {\n // Filter to only include new plots\n const newPlots = combinedNewPlots.filter(plot => {\n const inState = isPlotInState(plot.plotId, prevPlots)\n return !inState\n })\n\n const updatedPlots = prevPlots.filter(prevPlot =>\n isPlotStillPresent(prevPlot, customPlots, facetNavPanelPropsArray),\n )\n\n // Append new plots\n const combinedPlots = [...updatedPlots, ...newPlots]\n return combinedPlots\n })\n }, [customPlots, facetNavPanelPropsArray, initialPlotTypeByFacetColumnName])\n\n // when 'show more/less' is clicked\n const onShowMoreClick = (shouldShowMore: boolean) => {\n setPlotUiStateArray(plotUiStateArray => {\n return plotUiStateArray.map((item, index) => {\n if (shouldShowMore) {\n // show everything\n return { ...item, isHidden: false }\n }\n // otherwise hide everything except the first few items\n return { ...item, isHidden: index >= DEFAULT_VISIBLE_PLOTS }\n })\n })\n }\n\n const isPlotHiddenInGrid = (plotId: PlotIdentifier) => {\n const itemHidden = plotUiStateArray.find(\n item =>\n plotMatchesDefinition(plotId, item.plotId) && item.isHidden === true,\n )\n const result = itemHidden !== undefined\n return result\n }\n\n const showMoreButtonState = useMemo<ShowMoreState>(() => {\n if (\n // if at least one item is hidden\n plotUiStateArray.find(item => item.isHidden === true)\n ) {\n return 'MORE'\n } else if (plotUiStateArray.length <= DEFAULT_VISIBLE_PLOTS) {\n return 'NONE'\n } else {\n return 'LESS'\n }\n }, [plotUiStateArray])\n\n // When all charts become visible (transition to 'LESS'), trigger a resize event so\n // Plotly recalculates dimensions for charts that were previously hidden (display: none).\n useEffect(() => {\n if (showMoreButtonState === 'LESS') {\n requestAnimationFrame(() => {\n window.dispatchEvent(new Event('resize'))\n })\n }\n }, [showMoreButtonState])\n\n // hides plot graph\n const hidePlotInGrid = (plotId: PlotIdentifier) => {\n setUiPropertyForPlot(plotId, 'isHidden', true)\n }\n\n const setPlotType = (plotId: PlotIdentifier, plotType: PlotType) => {\n setUiPropertyForPlot(plotId, 'plotType', plotType)\n }\n\n const setUiPropertyForPlot = (\n plotId: PlotIdentifier,\n propName: keyof UiPlotState,\n value: boolean | PlotType, // 'the possible values of the above type' (currently can't be specified in TS using symbols)\n ) => {\n setPlotUiStateArray(plotUiStateArray =>\n plotUiStateArray.map(item =>\n plotMatchesDefinition(plotId, item.plotId)\n ? { ...item, [propName]: value }\n : item,\n ),\n )\n }\n\n const colorTracker: { facet: PlotIdentifier; colorIndex: number }[] =\n // TODO: customPlots should use the color index\n // additionally, it is unclear why this object is created\n // We can probably just pass the index from `plotUiStateArray.map)\n getFacets(queryMetadata, facetsToPlot).map((el, index) => {\n return {\n facet: { columnName: el.columnName, jsonPath: el.jsonPath },\n colorIndex: index,\n }\n })\n\n return (\n <>\n {plotUiStateArray.length > 0 && (\n <div\n className={`PlotsContainer ${showPlotVisualization ? '' : 'hidden'} ${\n showMoreButtonState === 'LESS' ? 'less' : ''\n }`}\n >\n <div className=\"PlotsContainer__row\" role=\"list\">\n {plotUiStateArray.map(plotUiState => {\n const isCustomPlot = '__custom' in plotUiState.plotId\n const customPlotProps = customPlots.find(customPlot =>\n plotMatchesDefinition(\n getCustomPlotIdentifier(customPlot),\n plotUiState.plotId,\n ),\n )\n const facetNavPanelProps = facetNavPanelPropsArray.find(props =>\n plotMatchesDefinition(props.facetToPlot, plotUiState.plotId),\n )\n\n return (\n <div\n className={\n [\n isCustomPlot\n ? 'PlotsContainer__row__item--custom'\n : undefined,\n isCustomPlot && customPlotProps?.fullWidth\n ? 'PlotsContainer__row__item--full-width'\n : undefined,\n ]\n .filter(Boolean)\n .join(' ') || undefined\n }\n style={{\n minWidth: '435px',\n display: isPlotHiddenInGrid(plotUiState.plotId)\n ? 'none'\n : 'block',\n }}\n key={generatePlotKey(plotUiState)}\n >\n {isCustomPlot && customPlotProps && (\n <QueryWrapperSynapsePlot\n {...customPlotProps}\n onHide={() => hidePlotInGrid(plotUiState.plotId)}\n />\n )}\n {!isCustomPlot && facetNavPanelProps && (\n <FacetNavPanel\n index={\n colorTracker.find(el =>\n plotMatchesDefinition(el.facet, plotUiState.plotId),\n )?.colorIndex!\n }\n onHide={() => hidePlotInGrid(plotUiState.plotId)}\n plotType={getPlotType(plotUiState.plotId)}\n onSetPlotType={(plotType: PlotType) =>\n setPlotType(plotUiState.plotId, plotType)\n }\n isModalView={false}\n {...facetNavPanelProps}\n />\n )}\n </div>\n )\n })}\n </div>\n {showMoreButtonState !== 'NONE' && (\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'center',\n backgroundColor: 'grey.100',\n p: 2,\n mt: 2,\n }}\n >\n <Button\n variant=\"contained\"\n color=\"secondary\"\n onClick={() => onShowMoreClick(showMoreButtonState === 'MORE')}\n sx={{ width: '150px' }}\n >\n {showMoreButtonState === 'LESS'\n ? 'Hide Charts'\n : 'View All Charts'}\n </Button>\n </Box>\n )}\n </div>\n )}\n </>\n )\n}\n\nexport default function PlotsContainerWithSuspense(props: PlotsContainerProps) {\n const { showPlots } = useQueryVisualizationContext()\n return (\n <Suspense fallback={showPlots ? <PlotsContainerSkeleton /> : null}>\n <PlotsContainer {...props} />\n </Suspense>\n )\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
.FacetNavPanel {
|
|
2
2
|
--facetNavPanel-btn-padding: 3px;
|
|
3
3
|
--facetNavPanel-btn-margin: 0 1px;
|
|
4
|
+
height: 100%;
|
|
5
|
+
// Flex column so the body can fill the remaining space after the header
|
|
6
|
+
// using flex:1 (externally determined height, not content-driven). Without
|
|
7
|
+
// this, height:100% on the body creates an infinite growth loop because the
|
|
8
|
+
// chart height feeds back into the panel height.
|
|
9
|
+
display: flex;
|
|
10
|
+
flex-direction: column;
|
|
4
11
|
&--expanded .main-svg,
|
|
5
12
|
.main-svg {
|
|
6
13
|
// https://sagebionetworks.jira.com/browse/PORTALS-1454
|
|
@@ -62,6 +69,10 @@
|
|
|
62
69
|
}
|
|
63
70
|
&__body {
|
|
64
71
|
padding: 20px 0;
|
|
72
|
+
// Fill the remaining height after the header without overflowing. flex:1
|
|
73
|
+
// + min-height:0 are the flex equivalents of "fill remaining space".
|
|
74
|
+
flex: 1;
|
|
75
|
+
min-height: 0;
|
|
65
76
|
}
|
|
66
77
|
|
|
67
78
|
&--expanded {
|