From 5f8c0bc3da2e1ebdf6c36741f0ece9323fdc067b Mon Sep 17 00:00:00 2001 From: Austen Money Date: Tue, 1 Oct 2024 09:27:37 -0400 Subject: [PATCH] Austenem/CAT-883, CAT-914, CAT-870, CAT-868 (#3552) * position button * add changelog * update changelog * update homepage * fix entity header summary view * update changelog --- CHANGELOG-many-minor-bug-fixes.md | 4 +++ .../ProcessedData/ProcessedDataset/hooks.ts | 2 +- .../EntityHeader/EntityHeader.tsx | 30 ++++++++++++++----- .../entityHeader/EntityHeader/hooks.ts | 17 ++++++----- .../static/js/components/home/Hero/const.tsx | 2 +- .../searchPage/MetadataMenu/style.tsx | 1 + .../searchPage/TilesSortDropdown/style.ts | 7 +++-- .../DropdownListbox/DropdownListbox.tsx | 11 +++++-- .../app/static/js/stores/useEntityStore.ts | 4 +++ 9 files changed, 55 insertions(+), 23 deletions(-) create mode 100644 CHANGELOG-many-minor-bug-fixes.md diff --git a/CHANGELOG-many-minor-bug-fixes.md b/CHANGELOG-many-minor-bug-fixes.md new file mode 100644 index 0000000000..3c410e70ea --- /dev/null +++ b/CHANGELOG-many-minor-bug-fixes.md @@ -0,0 +1,4 @@ +- Fix positioning of dropdown order menu on the tile view of the search page. +- Fix tabs moving around in bulk data transfer section on detail pages. +- Update unified datasets link in "What’s New" section on homepage to point to an example dataset detail page. +- Adjust size of "summary" view in entity headers dynamically based on the length of the content. \ No newline at end of file diff --git a/context/app/static/js/components/detailPage/ProcessedData/ProcessedDataset/hooks.ts b/context/app/static/js/components/detailPage/ProcessedData/ProcessedDataset/hooks.ts index 85ca753803..161ec0fde8 100644 --- a/context/app/static/js/components/detailPage/ProcessedData/ProcessedDataset/hooks.ts +++ b/context/app/static/js/components/detailPage/ProcessedData/ProcessedDataset/hooks.ts @@ -97,7 +97,7 @@ export function useProcessedDatasetTabs(): { label: string; uuid: string; icon: // Include dataset status in the label if more than one processed dataset of this type exists. // This allows us to distinguish between published datasets and QA/New/other statuses. - const processedDatasetTabs = searchHits + const processedDatasetTabs = [...searchHits] // Prioritize published datasets .sort((a, b) => { if (a._source.status === 'Published') { diff --git a/context/app/static/js/components/detailPage/entityHeader/EntityHeader/EntityHeader.tsx b/context/app/static/js/components/detailPage/entityHeader/EntityHeader/EntityHeader.tsx index 91b141699e..28089230fd 100644 --- a/context/app/static/js/components/detailPage/entityHeader/EntityHeader/EntityHeader.tsx +++ b/context/app/static/js/components/detailPage/entityHeader/EntityHeader/EntityHeader.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect } from 'react'; +import React, { useCallback, useEffect, useRef } from 'react'; import { animated } from '@react-spring/web'; import Box from '@mui/material/Box'; @@ -19,22 +19,36 @@ const visualizationSelector = (state: VisualizationStore) => ({ }); function Header() { - const { springs, view, setView } = useEntityStore(); + const { springs, view, setView, summaryHeight, setSummaryHeight } = useEntityStore(); const startViewChangeSpring = useStartViewChangeSpring(); const isLargeDesktop = useIsLargeDesktop(); const { vizIsFullscreen } = useVisualizationStore(visualizationSelector); + const { entity } = useFlaskDataContext(); + const uuid = entity?.uuid; + + const summaryBodyRef = useRef(null); + const handleViewChange = useCallback( (v: SummaryViewsType) => { setView(v); - startViewChangeSpring(v); + + // Delay height ref calculation to allow DOM to fully render + setTimeout(() => { + if (summaryBodyRef.current) { + const newHeight = summaryBodyRef.current.offsetHeight; + setSummaryHeight(newHeight); + } + }, 0); }, - [startViewChangeSpring, setView], + [setView, setSummaryHeight], ); - const { entity } = useFlaskDataContext(); - - const uuid = entity?.uuid; + useEffect(() => { + if (summaryHeight !== 0) { + startViewChangeSpring(view); + } + }, [summaryHeight, view, startViewChangeSpring]); useEffect(() => { if (vizIsFullscreen) { @@ -53,7 +67,7 @@ function Header() { {isLargeDesktop && ( - + {view === 'diagram' && uuid && } {view === 'summary' && } diff --git a/context/app/static/js/components/detailPage/entityHeader/EntityHeader/hooks.ts b/context/app/static/js/components/detailPage/entityHeader/EntityHeader/hooks.ts index d4caafa04d..39686b6de0 100644 --- a/context/app/static/js/components/detailPage/entityHeader/EntityHeader/hooks.ts +++ b/context/app/static/js/components/detailPage/entityHeader/EntityHeader/hooks.ts @@ -10,14 +10,15 @@ export const initialHeaderOffset = headerHeight + 16; const expandedHeights = { diagram: 300, - summary: 150, + summary: 'fit-content', narrow: 0, }; function useTotalHeaderOffset() { - const { view } = useEntityStore(); + const { view, summaryHeight } = useEntityStore(); + const contentHeight = view === 'summary' ? summaryHeight : expandedHeights[view]; - return expandedHeights[view] + initialEntityHeaderHeight + headerHeight; + return contentHeight + initialEntityHeaderHeight + headerHeight; } function useEntityHeaderSprings() { @@ -39,25 +40,27 @@ function useEntityHeaderSprings() { } function useStartViewChangeSpring() { - const { springs } = useEntityStore(); + const { springs, summaryHeight } = useEntityStore(); const [, springAPIs] = springs; return useCallback( (view: SummaryViewsType) => { const isExpanded = view !== 'narrow'; + const contentHeight = view === 'summary' ? summaryHeight : expandedHeights[view]; + async function startSprings() { await Promise.all( springAPIs.start((springIndex: number) => { if (springIndex === 0) { return { - height: isExpanded ? expandedHeights[view] + initialEntityHeaderHeight : initialEntityHeaderHeight, + height: isExpanded ? contentHeight + initialEntityHeaderHeight : initialEntityHeaderHeight, }; } if (springIndex === 1) { return { top: isExpanded - ? initialHeaderOffset + expandedHeights[view] + initialEntityHeaderHeight + ? contentHeight + initialEntityHeaderHeight + initialHeaderOffset : initialHeaderOffset + initialEntityHeaderHeight, }; } @@ -68,7 +71,7 @@ function useStartViewChangeSpring() { } startSprings().catch((e) => console.error(e)); }, - [springAPIs], + [springAPIs, summaryHeight], ); } diff --git a/context/app/static/js/components/home/Hero/const.tsx b/context/app/static/js/components/home/Hero/const.tsx index 564fcabad6..139bfb15ab 100644 --- a/context/app/static/js/components/home/Hero/const.tsx +++ b/context/app/static/js/components/home/Hero/const.tsx @@ -15,7 +15,7 @@ const timelineIconProps = { export const HOME_TIMELINE_ITEMS: TimelineData[] = [ { title: 'Raw & Processed Unified Datasets Page', - titleHref: '/search?entity_type[0]=Dataset', + titleHref: '/browse/dataset/8690897fced9931da34d66d669c1d698', description: 'Dataset page design has been updated to display both raw and processed data on the same page, enhancing the understanding of relationships between datasets.', date: 'August 2024', diff --git a/context/app/static/js/components/searchPage/MetadataMenu/style.tsx b/context/app/static/js/components/searchPage/MetadataMenu/style.tsx index d06da3be20..087af7a678 100644 --- a/context/app/static/js/components/searchPage/MetadataMenu/style.tsx +++ b/context/app/static/js/components/searchPage/MetadataMenu/style.tsx @@ -10,6 +10,7 @@ import Stack from '@mui/material/Stack'; const StyledDropdownMenuButton = styled(DropdownMenuButton)(({ theme }) => ({ margin: theme.spacing(0, 1), + height: theme.spacing(5), })); const StyledInfoIcon = styled(InfoIcon)(({ theme }) => ({ diff --git a/context/app/static/js/components/searchPage/TilesSortDropdown/style.ts b/context/app/static/js/components/searchPage/TilesSortDropdown/style.ts index fa5f9d95b3..2b38490a48 100644 --- a/context/app/static/js/components/searchPage/TilesSortDropdown/style.ts +++ b/context/app/static/js/components/searchPage/TilesSortDropdown/style.ts @@ -8,11 +8,12 @@ interface StyledButtonProps { // must use display: none instead of conditional rendering to preserve sort history between views const StyledButton = styled(Button)(({ theme, $searchView }) => ({ - marginLeft: theme.spacing(1), - color: 'white', + margin: theme.spacing(0, 1), height: theme.spacing(5), - marginRight: theme.spacing(1), borderRadius: theme.spacing(0.5), + alignItems: 'center', + justifyContent: 'center', + color: 'white', width: '185px', display: $searchView === 'table' ? 'none' : 'block', })); diff --git a/context/app/static/js/shared-styles/dropdowns/DropdownListbox/DropdownListbox.tsx b/context/app/static/js/shared-styles/dropdowns/DropdownListbox/DropdownListbox.tsx index e58269fe40..6306562726 100644 --- a/context/app/static/js/shared-styles/dropdowns/DropdownListbox/DropdownListbox.tsx +++ b/context/app/static/js/shared-styles/dropdowns/DropdownListbox/DropdownListbox.tsx @@ -3,7 +3,8 @@ import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDownRounded'; import ArrowDropUpIcon from '@mui/icons-material/ArrowDropUpRounded'; import ClickAwayListener from '@mui/material/ClickAwayListener'; import MenuList from '@mui/material/MenuList'; - +import Typography from '@mui/material/Typography'; +import Stack from '@mui/material/Stack'; import { StyledPopper, StyledPaper } from './style'; interface DropdownListboxProps { @@ -47,8 +48,12 @@ function DropdownListbox({ onClick={() => setIsOpen(true)} {...buttonProps} > - {getOptionLabel(options[selectedOptionIndex])} - {isOpen ? : } + + + {getOptionLabel(options[selectedOptionIndex])} + + {isOpen ? : } + diff --git a/context/app/static/js/stores/useEntityStore.ts b/context/app/static/js/stores/useEntityStore.ts index ae52388b02..654ec16691 100644 --- a/context/app/static/js/stores/useEntityStore.ts +++ b/context/app/static/js/stores/useEntityStore.ts @@ -15,6 +15,7 @@ interface EntityStoreState { }; assayMetadata: Partial; shouldDisplaySavedOrEditedAlert: boolean | string; + summaryHeight: number; view: SummaryViewsType; springs: ReturnType; } @@ -23,6 +24,7 @@ interface EntityStoreActions { setSummaryComponentObserver: (inView: boolean, entry: IntersectionObserverEntry) => void; setAssayMetadata: (val: Partial) => void; setShouldDisplaySavedOrEditedAlert: (val: boolean | string) => void; + setSummaryHeight: (val: number) => void; setView: (val: SummaryViewsType) => void; } @@ -41,6 +43,8 @@ export const createEntityStore = ({ springs }: { springs: ReturnType set({ summaryHeight: val }), view: 'narrow' as const, setView: (val) => set({ view: val }), springs,