-
Notifications
You must be signed in to change notification settings - Fork 14
fix: 1929 - follow on fixes to pr 1922 #1950
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 13 commits
d5b1c8c
3a6856f
2d87fdb
dbe622d
7996f18
2a55e40
a83e8a0
f1940b4
438ecc2
832109b
97e1a3b
3d42ac6
92091c5
bb2186f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| import { ViewMode } from '$components/exploration/types.d.ts'; | ||
| import { atomWithUrlValueStability } from '$utils/params-location-atom/atom-with-url-value-stability'; | ||
|
|
||
| const initialParams = new URLSearchParams(window.location.search); | ||
|
|
||
| const hydrateViewMode = (serialized: string | null) => { | ||
| if (serialized === 'simple') return serialized; | ||
| return 'default'; | ||
| }; | ||
|
|
||
| const dehydrateViewMode = (value: ViewMode) => { | ||
| return value ?? 'default'; | ||
| }; | ||
|
|
||
| /** | ||
| * Atom that manages the exploration view mode via URL parameter. | ||
| * | ||
| * - 'simple': Minimal view for embedding (no navigation/header) | ||
| * - 'default': Full exploration and analysis interface | ||
| * | ||
| * URL parameter: `?viewMode=simple` (defaults to 'default') | ||
| * | ||
| * @example | ||
| * const [viewMode] = useAtom(viewModeAtom); | ||
| */ | ||
| export const viewModeAtom = atomWithUrlValueStability<ViewMode>({ | ||
| initialValue: hydrateViewMode(initialParams.get('viewMode')), | ||
| urlParam: 'viewMode', | ||
| hydrate: hydrateViewMode, | ||
| dehydrate: dehydrateViewMode, | ||
| areEqual: (prev, next) => prev === next | ||
| }); | ||
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,142 +1,97 @@ | ||
| import React, { useEffect, useState } from 'react'; | ||
| import { Panel, PanelGroup, PanelResizeHandle } from 'react-resizable-panels'; | ||
| import styled from 'styled-components'; | ||
| import { themeVal } from '@devseed-ui/theme-provider'; | ||
| import { TourProvider } from '@reactour/tour'; | ||
|
|
||
| import React, { useState } from 'react'; | ||
| import { Link } from 'react-router-dom'; | ||
| import { DevTools } from 'jotai-devtools'; | ||
| import { useAtom, useSetAtom } from 'jotai'; | ||
| import Timeline from './components/timeline/timeline'; | ||
| import { ExplorationMap } from './components/map'; | ||
| import { useAnalysisController } from './hooks/use-analysis-data-request'; | ||
| import { PopoverTourComponent, TourManager } from './tour-manager'; | ||
| import { TimelineDataset } from './types.d.ts'; | ||
| import { selectedCompareDateAtom, selectedDateAtom } from './atoms/dates'; | ||
| import { CLEAR_LOCATION, urlAtom } from '$utils/params-location-atom/url'; | ||
| import { legacyGlobalStyleCSSBlock } from '$styles/legacy-global-styles'; | ||
|
|
||
| // @TODO: "height: 100%" Added for exploration container to show correctly in NextJs instance but investigate why this is needed and possibly work to remove | ||
| const Container = styled.div` | ||
| display: flex; | ||
| flex-flow: column; | ||
| flex-grow: 1; | ||
| height: 100%; | ||
|
|
||
| .panel-wrapper { | ||
| flex-grow: 1; | ||
| } | ||
|
|
||
| .panel { | ||
| display: flex; | ||
| flex-direction: column; | ||
| position: relative; | ||
| } | ||
| * { | ||
| ${legacyGlobalStyleCSSBlock} | ||
| } | ||
| .panel-timeline { | ||
| box-shadow: 0 -1px 0 0 ${themeVal('color.base-100')}; | ||
| } | ||
|
|
||
| .resize-handle { | ||
| flex: 0; | ||
| position: relative; | ||
| outline: none; | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| width: 5rem; | ||
| margin: 0 auto -1.25rem auto; | ||
| padding: 0rem 0 0.25rem; | ||
| z-index: 1; | ||
|
|
||
| ::before { | ||
| content: ''; | ||
| display: block; | ||
| width: 2rem; | ||
| background: ${themeVal('color.base-200')}; | ||
| height: 0.25rem; | ||
| border-radius: ${themeVal('shape.ellipsoid')}; | ||
| } | ||
| } | ||
| `; | ||
|
|
||
| const tourProviderStyles = { | ||
| popover: (base) => ({ | ||
| ...base, | ||
| padding: '0', | ||
| background: 'none' | ||
| }) | ||
| }; | ||
| import { DatasetSelectorModal } from '$components/exploration/components/dataset-selector-modal'; | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This file is largely the same as the prior container but I updated all the relative path imports. |
||
| import useTimelineDatasetAtom from '$components/exploration/hooks/use-timeline-dataset-atom'; | ||
| import { externalDatasetsAtom } from '$components/exploration/atoms/datasetLayers'; | ||
| import { viewModeAtom } from '$components/exploration/atoms/viewMode'; | ||
| import ExplorationAndAnalysisSimpleView from '$components/exploration/views/simple'; | ||
| import ExplorationAndAnalysisDefaultView from '$components/exploration/views/default'; | ||
| import { allExploreDatasets } from '$data-layer/datasets'; | ||
| import { urlAtom } from '$utils/params-location-atom/url'; | ||
| import { PageMainContent } from '$styles/page'; | ||
| import { LayoutProps } from '$components/common/layout-root'; | ||
| import PageHero from '$components/common/page-hero'; | ||
| import { DATASETS_PATH, EXPLORATION_PATH } from '$utils/routes'; | ||
|
|
||
| interface ExplorationAndAnalysisProps { | ||
| datasets: TimelineDataset[]; | ||
| setDatasets: (datasets: TimelineDataset[]) => void; | ||
| openDatasetsSelectionModal?: () => void; | ||
| } | ||
|
|
||
| export default function ExplorationAndAnalysis( | ||
| props: ExplorationAndAnalysisProps | ||
| ) { | ||
| const { datasets, setDatasets, openDatasetsSelectionModal } = props; | ||
|
|
||
| const [selectedDay, setSelectedDay] = useAtom(selectedDateAtom); | ||
|
|
||
| const [selectedCompareDay, setSelectedCompareDay] = useAtom( | ||
| selectedCompareDateAtom | ||
| /** | ||
| * Container component that manages exploration view routing and data state. | ||
| * | ||
| * Routes between two view modes based on URL parameter: | ||
| * - Simple view (`?viewMode=simple`): Minimal interface for embedding | ||
| * - Default view: Full exploration and analysis interface | ||
| * | ||
| * @LEGACY-SUPPORT | ||
| * | ||
| * @NOTE: This container component serves as a wrapper for the purpose of data management, | ||
| * this is ONLY to support current instances. veda2 instances can just use the direct | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @vgeorge what is current instances vs veda2? is current instances, veda as a submodule? and veda2 is the the next-veda-ui implementation as a library (instead of submodule)? when you say current instances, if I read this in one year, will that still apply?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ifsimicoded my original intent with this change was just to rename the reference component, and I was also confused by the |
||
| * component, 'ExplorationAndAnalysisDefaultView', and manage data directly in their page views | ||
| * | ||
| * @returns {JSX.Element | null} Renders the appropriate view or null if not on exploration path | ||
| */ | ||
| export default function ExplorationAndAnalysisContainer() { | ||
| const setExternalDatasets = useSetAtom(externalDatasetsAtom); | ||
| setExternalDatasets(allExploreDatasets); | ||
| const [timelineDatasets, setTimelineDatasets] = useTimelineDatasetAtom(); | ||
| const [datasetModalRevealed, setDatasetModalRevealed] = useState( | ||
| !timelineDatasets.length | ||
| ); | ||
| // @NOTE: When Exploration page is preloaded (ex. Linked with react-router) | ||
| // atomWithLocation gets initialized outside of Exploration page and returns the previous page's value | ||
| // We check if url Atom actually returns the values for exploration page here. | ||
| const [currentUrl] = useAtom(urlAtom); | ||
| const [viewMode] = useAtom(viewModeAtom); | ||
|
|
||
| // @TECH-DEBT: panelHeight needs to be passed to work around Safari CSS | ||
| const [panelHeight, setPanelHeight] = useState(0); | ||
|
|
||
| const setUrl = useSetAtom(urlAtom); | ||
| const { reset: resetAnalysisController } = useAnalysisController(); | ||
| if (!currentUrl.pathname?.includes(EXPLORATION_PATH)) return null; | ||
|
|
||
| // Reset atoms when leaving the page. | ||
| useEffect(() => { | ||
| return () => { | ||
| resetAnalysisController(); | ||
| setUrl(CLEAR_LOCATION); | ||
| }; | ||
| // eslint-disable-next-line react-hooks/exhaustive-deps | ||
| }, []); | ||
| const openModal = () => setDatasetModalRevealed(true); | ||
| const closeModal = () => setDatasetModalRevealed(false); | ||
|
|
||
| return ( | ||
| <TourProvider | ||
| steps={[]} | ||
| styles={tourProviderStyles} | ||
| ContentComponent={PopoverTourComponent} | ||
| > | ||
| <TourManager /> | ||
| <Container> | ||
| <PanelGroup direction='vertical' className='panel-wrapper'> | ||
| <Panel | ||
| maxSize={75} | ||
| className='panel' | ||
| onResize={(size: number) => { | ||
| setPanelHeight(size); | ||
| }} | ||
| > | ||
| <ExplorationMap | ||
| datasets={datasets} | ||
| setDatasets={setDatasets} | ||
| selectedDay={selectedDay} | ||
| selectedCompareDay={selectedCompareDay} | ||
| <> | ||
| <DevTools /> | ||
| <LayoutProps | ||
| title='Exploration' | ||
| description='Explore and analyze datasets' | ||
| hideFooter | ||
| {...(viewMode === 'simple' && { hideNav: true, hideHeader: true })} | ||
| /> | ||
| <PageMainContent> | ||
| <PageHero title='Exploration' isHidden /> | ||
| {viewMode === 'simple' ? ( | ||
| <ExplorationAndAnalysisSimpleView datasets={timelineDatasets} /> | ||
| ) : ( | ||
| <> | ||
| <ExplorationAndAnalysisDefaultView | ||
| datasets={timelineDatasets} | ||
| setDatasets={setTimelineDatasets} | ||
| openDatasetsSelectionModal={openModal} | ||
| /> | ||
| </Panel> | ||
| <PanelResizeHandle className='resize-handle' /> | ||
| <Panel maxSize={75} className='panel panel-timeline'> | ||
| <Timeline | ||
| datasets={datasets} | ||
| selectedDay={selectedDay} | ||
| setSelectedDay={setSelectedDay} | ||
| selectedCompareDay={selectedCompareDay} | ||
| setSelectedCompareDay={setSelectedCompareDay} | ||
| onDatasetAddClick={openDatasetsSelectionModal} | ||
| panelHeight={panelHeight} | ||
| <DatasetSelectorModal | ||
| revealed={datasetModalRevealed} | ||
| close={closeModal} | ||
| datasets={allExploreDatasets} | ||
| timelineDatasets={timelineDatasets} | ||
| setTimelineDatasets={setTimelineDatasets} | ||
| emptyStateContent={ | ||
| <> | ||
| <p> | ||
| There are no datasets to show with the selected filters. | ||
| </p> | ||
| <p> | ||
| This tool allows the exploration and analysis of time-series | ||
| datasets in raster format. For a comprehensive list of | ||
| available datasets, please visit the{' '} | ||
| <Link to={DATASETS_PATH}>Data Catalog</Link>. | ||
| </p> | ||
| </> | ||
| } | ||
| /> | ||
| </Panel> | ||
| </PanelGroup> | ||
| </Container> | ||
| </TourProvider> | ||
| </> | ||
| )} | ||
| </PageMainContent> | ||
| </> | ||
| ); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file is largely the same as the embed atom, however, we're now managing a view mode (simple or default) vs a boolean. This allows for more view modes in the future