From 7e4cf7eb047898acdb610933704e879833875690 Mon Sep 17 00:00:00 2001 From: Hanbyul Jo Date: Wed, 30 Oct 2024 11:52:50 -0400 Subject: [PATCH 01/10] Export useAtom, Remove any react router related components --- .../dataset-selector-modal/index.tsx | 22 ++++++++----- .../components/datasets/dataset-list-item.tsx | 5 ++- .../components/datasets/dataset-list.tsx | 5 ++- .../components/layer-info-modal.tsx | 13 +++++--- .../components/parent-dataset-link.tsx | 33 ------------------- .../components/timeline/timeline.tsx | 7 ++-- .../components/exploration/container.tsx | 26 +++++++++++---- .../exploration/data-utils-no-faux-module.ts | 10 ++++++ .../hooks/use-timeline-dataset-atom.tsx | 11 +++++++ app/scripts/components/exploration/index.tsx | 5 ++- app/scripts/index.ts | 2 ++ 11 files changed, 81 insertions(+), 58 deletions(-) delete mode 100644 app/scripts/components/exploration/components/parent-dataset-link.tsx create mode 100644 app/scripts/components/exploration/hooks/use-timeline-dataset-atom.tsx diff --git a/app/scripts/components/exploration/components/dataset-selector-modal/index.tsx b/app/scripts/components/exploration/components/dataset-selector-modal/index.tsx index cc7bf02bd..6ba6cd34b 100644 --- a/app/scripts/components/exploration/components/dataset-selector-modal/index.tsx +++ b/app/scripts/components/exploration/components/dataset-selector-modal/index.tsx @@ -1,6 +1,5 @@ import React, { useCallback, useEffect, useState } from 'react'; import styled from 'styled-components'; -import { useAtom } from 'jotai'; import { Modal, ModalBody, @@ -8,16 +7,18 @@ import { ModalHeader } from '@devseed-ui/modal'; import { glsp, themeVal } from '@devseed-ui/theme-provider'; -import { timelineDatasetsAtom } from '../../atoms/datasets'; import { - reconcileDatasets + reconcileDatasets, + getLayersFromDataset } from '../../data-utils-no-faux-module'; -import { datasetLayers } from '../../data-utils'; +import { TimelineDataset } from '../../types.d.ts'; + import RenderModalHeader from './header'; import ModalFooterRender from './footer'; import CatalogContent from '$components/common/catalog/catalog-content'; import { useFiltersWithURLAtom } from '$components/common/catalog/controls/hooks/use-filters-with-query'; import { FilterActions } from '$components/common/catalog/utils'; + import { DatasetData, LinkProperties, DatasetLayer } from '$types/veda'; const DatasetModal = styled(Modal)` @@ -68,16 +69,20 @@ interface DatasetSelectorModalProps { linkProperties: LinkProperties; datasets: DatasetData[]; datasetPathName: string; + timelineDatasets: TimelineDataset[]; + setTimelineDatasets: (datasets: TimelineDataset[]) => void; } export function DatasetSelectorModal(props: DatasetSelectorModalProps) { - const { revealed, linkProperties, datasets, datasetPathName, close } = props; + const { revealed, linkProperties, datasets, datasetPathName, timelineDatasets, setTimelineDatasets, close } = props; const { LinkElement , pathAttributeKeyName } = linkProperties as { LinkElement: React.ElementType, pathAttributeKeyName: string }; - const [timelineDatasets, setTimelineDatasets] = useAtom(timelineDatasetsAtom); + const datasetLayers = getLayersFromDataset(datasets); + const [selectedIds, setSelectedIds] = useState( timelineDatasets.map((dataset) => dataset.data.id) ); + const enhancedDatasetLayers = datasetLayers.flatMap(e => e); // Use Jotai controlled atoms for query parameter manipulation on new E&A page const {search: searchTerm, taxonomies, onAction } = useFiltersWithURLAtom(); @@ -95,11 +100,12 @@ export function DatasetSelectorModal(props: DatasetSelectorModalProps) { const onConfirm = useCallback(() => { setTimelineDatasets( - reconcileDatasets(selectedIds, datasetLayers, timelineDatasets) + reconcileDatasets(selectedIds, enhancedDatasetLayers, timelineDatasets) ); onAction(FilterActions.CLEAR); close(); - }, [close, selectedIds, timelineDatasets, setTimelineDatasets, onAction]); + }, [close, selectedIds, timelineDatasets, enhancedDatasetLayers, setTimelineDatasets, onAction]); + const linkElementProps = {[pathAttributeKeyName]: datasetPathName}; return ( ; onDragStart?: () => void; onDragEnd?: () => void; + linkProperties: LinkProperties; } export function DatasetListItem(props: DatasetListItemProps) { - const { datasetId, width, xScaled, onDragStart, onDragEnd } = props; + const { datasetId, width, xScaled, linkProperties, onDragStart, onDragEnd } = props; const datasetAtom = useTimelineDatasetAtom(datasetId); const dataset = useAtomValue(datasetAtom); @@ -218,6 +220,7 @@ export function DatasetListItem(props: DatasetListItemProps) { revealed={!!modalLayerInfo} close={() => setModalLayerInfo(undefined)} layerData={modalLayerInfo} + linkProperties={linkProperties} /> )} diff --git a/app/scripts/components/exploration/components/datasets/dataset-list.tsx b/app/scripts/components/exploration/components/datasets/dataset-list.tsx index b0c7b538d..a8e688380 100644 --- a/app/scripts/components/exploration/components/datasets/dataset-list.tsx +++ b/app/scripts/components/exploration/components/datasets/dataset-list.tsx @@ -7,6 +7,7 @@ import { listReset } from '@devseed-ui/theme-provider'; import { DatasetListItem } from './dataset-list-item'; import { timelineDatasetsAtom } from '$components/exploration/atoms/datasets'; +import { LinkProperties } from '$types/veda'; const DatasetListSelf = styled.ul` ${listReset()} @@ -16,10 +17,11 @@ const DatasetListSelf = styled.ul` interface DatasetListProps { width: number; xScaled?: ScaleTime; + linkProperties: LinkProperties; } export function DatasetList(props: DatasetListProps) { - const { width, xScaled } = props; + const { width, xScaled, linkProperties } = props; const [isDragging, setIsDragging] = useState(false); const [datasets, setDatasets] = useAtom(timelineDatasetsAtom); @@ -35,6 +37,7 @@ export function DatasetList(props: DatasetListProps) { {datasets.map((dataset) => ( ` +// override with 'as' as LinkComponent +const ButtonStyleLink = styled.a` &&& { ${({ variation, size }) => createButtonStyles({ variation, size })} } @@ -74,7 +75,8 @@ export interface LayerInfoModalData { interface LayerInfoModalProps { revealed: boolean; close: () => void; - layerData: LayerInfoModalData + layerData: LayerInfoModalData, + linkProperties: LinkProperties; } export function LayerInfoLiner(props: { info: LayerInfo }) { @@ -100,7 +102,8 @@ const LayerInfoLinerModal = styled.div` `; export default function LayerInfoModal(props: LayerInfoModalProps) { - const { revealed, close, layerData } = props; + const { revealed, close, layerData, linkProperties } = props; + const { LinkElement, pathAttributeKeyName } = linkProperties; const { parentData } = layerData; const dataCatalogPage = getDatasetPath(parentData.id); return ( @@ -132,7 +135,7 @@ export default function LayerInfoModal(props: LayerInfoModalProps) {
} footerContent={ - + Open in Data Catalog } diff --git a/app/scripts/components/exploration/components/parent-dataset-link.tsx b/app/scripts/components/exploration/components/parent-dataset-link.tsx deleted file mode 100644 index 0764b7674..000000000 --- a/app/scripts/components/exploration/components/parent-dataset-link.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import React from 'react'; -import styled from 'styled-components'; -import { themeVal } from '@devseed-ui/theme-provider'; -import { Link } from 'react-router-dom'; -import { CollecticonDatasetLayers } from '$components/common/icons/dataset-layers'; -import { ParentDatset } from '$components/exploration/types.d.ts'; -import { getDatasetPath } from '$utils/routes'; - -const DatasetLink = styled(Link)<{size: string}>` - color: ${themeVal('color.link')}; - text-align: left; - text-transform: none; - font-size: ${(props => props.size=='small'? '0.75rem': '1rem')}; - line-height: 0.75rem; - font-weight: normal; - display: flex; - align-items: center; - justify-content: center; - text-decoration: none; - gap: 0.1rem; - > svg { - fill: ${themeVal('color.link')}; - } -`; - -export default function ParentDatasetLink(props: { parentDataset: ParentDatset, size: string}) { - const { parentDataset, size } = props; - const linkTo = getDatasetPath(parentDataset.id); - return ( - - {parentDataset.name} - ); -} \ No newline at end of file diff --git a/app/scripts/components/exploration/components/timeline/timeline.tsx b/app/scripts/components/exploration/components/timeline/timeline.tsx index 8655f34bb..63f8118d2 100644 --- a/app/scripts/components/exploration/components/timeline/timeline.tsx +++ b/app/scripts/components/exploration/components/timeline/timeline.tsx @@ -69,6 +69,7 @@ import { useAnalysisController } from '$components/exploration/hooks/use-analysi import useAois from '$components/common/map/controls/hooks/use-aois'; import Pluralize from '$utils/pluralize'; import { getLowestCommonTimeDensity } from '$components/exploration/data-utils-no-faux-module'; +import { LinkProperties } from '$types/veda'; const TimelineWrapper = styled.div` position: relative; @@ -170,6 +171,7 @@ interface TimelineProps { setSelectedCompareDay: (d: Date | null) => void; onDatasetAddClick?: () => void; panelHeight: number; + linkProperties: LinkProperties; } const getIntervalFromDate = (selectedDay: Date, dataDomain: [Date, Date]) => { @@ -200,7 +202,8 @@ export default function Timeline(props: TimelineProps) { selectedCompareDay, setSelectedCompareDay, onDatasetAddClick, - panelHeight + panelHeight, + linkProperties } = props; // Refs for non react based interactions. @@ -798,7 +801,7 @@ export default function Timeline(props: TimelineProps) { ref={datasetsContainerRef} panelHeight={panelHeight} > - + diff --git a/app/scripts/components/exploration/container.tsx b/app/scripts/components/exploration/container.tsx index b04936029..059d08197 100644 --- a/app/scripts/components/exploration/container.tsx +++ b/app/scripts/components/exploration/container.tsx @@ -3,9 +3,10 @@ import { TourProvider } from '@reactour/tour'; import { DevTools } from 'jotai-devtools'; import { useAtom } from 'jotai'; import { PopoverTourComponent, TourManager } from './tour-manager'; -import { timelineDatasetsAtom } from './atoms/datasets'; + import { DatasetSelectorModal } from './components/dataset-selector-modal'; import { allExploreDatasets } from './data-utils'; +import useTimelineDatasetAtom from './hooks/use-timeline-dataset-atom'; import ExplorationAndAnalysis from '.'; import { urlAtom } from '$utils/params-location-atom/url'; import { DATASETS_PATH, EXPLORATION_PATH } from '$utils/routes'; @@ -14,6 +15,7 @@ import { PageMainContent } from '$styles/page'; import { LayoutProps } from '$components/common/layout-root'; import PageHero from '$components/common/page-hero'; import SmartLink from '$components/common/smart-link'; + /** * @VEDA2-REFACTOR-WORK * @@ -30,15 +32,15 @@ const tourProviderStyles = { }; export default function ExplorationAndAnalysisContainer() { - const [datasets, setDatasets] = useAtom(timelineDatasetsAtom); + 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 [datasetModalRevealed, setDatasetModalRevealed] = useState( - !datasets.length - ); - if(!currentUrl.pathname?.includes(EXPLORATION_PATH)) return null; const openModal = () => setDatasetModalRevealed(true); @@ -59,11 +61,21 @@ export default function ExplorationAndAnalysisContainer() { - + ) => })); }); + export const getLayersFromDataset = (datasets: DatasetData[]) => + Object.values(datasets).map((dataset: DatasetData) => { + return dataset!.layers.map((l) => ({ + ...l, + parentDataset: { + id: dataset!.id, + name: dataset!.name + } + })); + }); /** * Returns an array of metrics based on the given Dataset Layer configuration. * If the layer has metrics defined, it returns only the metrics that match the diff --git a/app/scripts/components/exploration/hooks/use-timeline-dataset-atom.tsx b/app/scripts/components/exploration/hooks/use-timeline-dataset-atom.tsx new file mode 100644 index 000000000..46811c17d --- /dev/null +++ b/app/scripts/components/exploration/hooks/use-timeline-dataset-atom.tsx @@ -0,0 +1,11 @@ +import { useAtom } from 'jotai'; +import { timelineDatasetsAtom } from '../atoms/datasets'; +import { TimelineDataset } from '../types.d.ts'; + +export default function useTimelineDatasetAtom (): [ + TimelineDataset[], + (datasets: TimelineDataset[]) => void +] { + const [datasets, setDatasets] = useAtom(timelineDatasetsAtom); + return [datasets, setDatasets]; +} \ No newline at end of file diff --git a/app/scripts/components/exploration/index.tsx b/app/scripts/components/exploration/index.tsx index 5e4242cba..12636ca85 100644 --- a/app/scripts/components/exploration/index.tsx +++ b/app/scripts/components/exploration/index.tsx @@ -10,6 +10,7 @@ import { useAnalysisController } from './hooks/use-analysis-data-request'; import { TimelineDataset } from './types.d.ts'; import { selectedCompareDateAtom, selectedDateAtom } from './atoms/dates'; import { CLEAR_LOCATION, urlAtom } from '$utils/params-location-atom/url'; +import { LinkProperties } from '$types/veda'; // @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` @@ -59,10 +60,11 @@ interface ExplorationAndAnalysisProps { datasets: TimelineDataset[]; setDatasets: (datasets: TimelineDataset[]) => void; openDatasetsSelectionModal?: () => void; + linkProperties: LinkProperties; } function ExplorationAndAnalysis(props: ExplorationAndAnalysisProps) { - const { datasets, setDatasets, openDatasetsSelectionModal } = props; + const { datasets, setDatasets, linkProperties, openDatasetsSelectionModal } = props; const [selectedDay, setSelectedDay] = useAtom(selectedDateAtom); @@ -111,6 +113,7 @@ function ExplorationAndAnalysis(props: ExplorationAndAnalysisProps) { setSelectedCompareDay={setSelectedCompareDay} onDatasetAddClick={openDatasetsSelectionModal} panelHeight={panelHeight} + linkProperties={linkProperties} /> diff --git a/app/scripts/index.ts b/app/scripts/index.ts index 35fe6cbf5..b377e8025 100644 --- a/app/scripts/index.ts +++ b/app/scripts/index.ts @@ -16,6 +16,7 @@ import { PageMainContent } from '$styles/page'; import PageHero from '$components/common/page-hero'; import { useFiltersWithQS } from '$components/common/catalog/controls/hooks/use-filters-with-query'; import ExplorationAndAnalysis from '$components/exploration'; +import useTimelineDatasetAtom from '$components/exploration/hooks/use-timeline-dataset-atom'; import { timelineDatasetsAtom } from '$components/exploration/atoms/datasets'; import { DatasetSelectorModal } from '$components/exploration/components/dataset-selector-modal'; @@ -41,6 +42,7 @@ export { ExplorationAndAnalysis, DatasetSelectorModal, // HOOKS + useTimelineDatasetAtom, useFiltersWithQS, // STATE timelineDatasetsAtom From 4f69a4ab509ab25eaf18d46fe05ad5902cc69b0f Mon Sep 17 00:00:00 2001 From: Hanbyul Jo Date: Wed, 30 Oct 2024 12:03:17 -0400 Subject: [PATCH 02/10] Use a when opening a tab in a new window --- .../components/datasets/dataset-list-item.tsx | 5 +---- .../exploration/components/datasets/dataset-list.tsx | 5 +---- .../exploration/components/layer-info-modal.tsx | 10 ++++------ .../exploration/components/timeline/timeline.tsx | 7 ++----- app/scripts/components/exploration/container.tsx | 4 ---- app/scripts/components/exploration/index.tsx | 5 +---- 6 files changed, 9 insertions(+), 27 deletions(-) diff --git a/app/scripts/components/exploration/components/datasets/dataset-list-item.tsx b/app/scripts/components/exploration/components/datasets/dataset-list-item.tsx index d6be9e643..18b2a0ea8 100644 --- a/app/scripts/components/exploration/components/datasets/dataset-list-item.tsx +++ b/app/scripts/components/exploration/components/datasets/dataset-list-item.tsx @@ -41,7 +41,6 @@ import { useAnalysisController, useAnalysisDataRequest } from '$components/exploration/hooks/use-analysis-data-request'; -import { LinkProperties } from '$types/veda'; const DatasetItem = styled.article` width: 100%; @@ -94,11 +93,10 @@ interface DatasetListItemProps { xScaled?: ScaleTime; onDragStart?: () => void; onDragEnd?: () => void; - linkProperties: LinkProperties; } export function DatasetListItem(props: DatasetListItemProps) { - const { datasetId, width, xScaled, linkProperties, onDragStart, onDragEnd } = props; + const { datasetId, width, xScaled, onDragStart, onDragEnd } = props; const datasetAtom = useTimelineDatasetAtom(datasetId); const dataset = useAtomValue(datasetAtom); @@ -220,7 +218,6 @@ export function DatasetListItem(props: DatasetListItemProps) { revealed={!!modalLayerInfo} close={() => setModalLayerInfo(undefined)} layerData={modalLayerInfo} - linkProperties={linkProperties} /> )} diff --git a/app/scripts/components/exploration/components/datasets/dataset-list.tsx b/app/scripts/components/exploration/components/datasets/dataset-list.tsx index a8e688380..b0c7b538d 100644 --- a/app/scripts/components/exploration/components/datasets/dataset-list.tsx +++ b/app/scripts/components/exploration/components/datasets/dataset-list.tsx @@ -7,7 +7,6 @@ import { listReset } from '@devseed-ui/theme-provider'; import { DatasetListItem } from './dataset-list-item'; import { timelineDatasetsAtom } from '$components/exploration/atoms/datasets'; -import { LinkProperties } from '$types/veda'; const DatasetListSelf = styled.ul` ${listReset()} @@ -17,11 +16,10 @@ const DatasetListSelf = styled.ul` interface DatasetListProps { width: number; xScaled?: ScaleTime; - linkProperties: LinkProperties; } export function DatasetList(props: DatasetListProps) { - const { width, xScaled, linkProperties } = props; + const { width, xScaled } = props; const [isDragging, setIsDragging] = useState(false); const [datasets, setDatasets] = useAtom(timelineDatasetsAtom); @@ -37,7 +35,6 @@ export function DatasetList(props: DatasetListProps) { {datasets.map((dataset) => ( void; - layerData: LayerInfoModalData, - linkProperties: LinkProperties; + layerData: LayerInfoModalData } export function LayerInfoLiner(props: { info: LayerInfo }) { @@ -102,8 +100,8 @@ const LayerInfoLinerModal = styled.div` `; export default function LayerInfoModal(props: LayerInfoModalProps) { - const { revealed, close, layerData, linkProperties } = props; - const { LinkElement, pathAttributeKeyName } = linkProperties; + const { revealed, close, layerData } = props; + const { parentData } = layerData; const dataCatalogPage = getDatasetPath(parentData.id); return ( @@ -135,7 +133,7 @@ export default function LayerInfoModal(props: LayerInfoModalProps) {
} footerContent={ - + Open in Data Catalog } diff --git a/app/scripts/components/exploration/components/timeline/timeline.tsx b/app/scripts/components/exploration/components/timeline/timeline.tsx index 63f8118d2..8655f34bb 100644 --- a/app/scripts/components/exploration/components/timeline/timeline.tsx +++ b/app/scripts/components/exploration/components/timeline/timeline.tsx @@ -69,7 +69,6 @@ import { useAnalysisController } from '$components/exploration/hooks/use-analysi import useAois from '$components/common/map/controls/hooks/use-aois'; import Pluralize from '$utils/pluralize'; import { getLowestCommonTimeDensity } from '$components/exploration/data-utils-no-faux-module'; -import { LinkProperties } from '$types/veda'; const TimelineWrapper = styled.div` position: relative; @@ -171,7 +170,6 @@ interface TimelineProps { setSelectedCompareDay: (d: Date | null) => void; onDatasetAddClick?: () => void; panelHeight: number; - linkProperties: LinkProperties; } const getIntervalFromDate = (selectedDay: Date, dataDomain: [Date, Date]) => { @@ -202,8 +200,7 @@ export default function Timeline(props: TimelineProps) { selectedCompareDay, setSelectedCompareDay, onDatasetAddClick, - panelHeight, - linkProperties + panelHeight } = props; // Refs for non react based interactions. @@ -801,7 +798,7 @@ export default function Timeline(props: TimelineProps) { ref={datasetsContainerRef} panelHeight={panelHeight} > - + diff --git a/app/scripts/components/exploration/container.tsx b/app/scripts/components/exploration/container.tsx index 059d08197..434dcd457 100644 --- a/app/scripts/components/exploration/container.tsx +++ b/app/scripts/components/exploration/container.tsx @@ -62,10 +62,6 @@ export default function ExplorationAndAnalysisContainer() { void; openDatasetsSelectionModal?: () => void; - linkProperties: LinkProperties; } function ExplorationAndAnalysis(props: ExplorationAndAnalysisProps) { - const { datasets, setDatasets, linkProperties, openDatasetsSelectionModal } = props; + const { datasets, setDatasets, openDatasetsSelectionModal } = props; const [selectedDay, setSelectedDay] = useAtom(selectedDateAtom); @@ -113,7 +111,6 @@ function ExplorationAndAnalysis(props: ExplorationAndAnalysisProps) { setSelectedCompareDay={setSelectedCompareDay} onDatasetAddClick={openDatasetsSelectionModal} panelHeight={panelHeight} - linkProperties={linkProperties} /> From e01d03e2f2e1265faa0d0432f0ff9b7eb35893c2 Mon Sep 17 00:00:00 2001 From: Hanbyul Jo Date: Wed, 30 Oct 2024 14:15:42 -0400 Subject: [PATCH 03/10] Use linkproperties for sources (but is this necessary?) --- app/scripts/components/common/card-sources.tsx | 16 ++++++++-------- .../components/common/catalog/catalog-card.tsx | 2 +- .../common/featured-slider-section.tsx | 9 ++++++--- .../components/stories/hub/hub-content.tsx | 4 ++-- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/app/scripts/components/common/card-sources.tsx b/app/scripts/components/common/card-sources.tsx index d592a1c68..72d47dbd4 100644 --- a/app/scripts/components/common/card-sources.tsx +++ b/app/scripts/components/common/card-sources.tsx @@ -1,8 +1,7 @@ import React from 'react'; import styled from 'styled-components'; -import { Link } from 'react-router-dom'; import { listReset } from '@devseed-ui/theme-provider'; -import { TaxonomyItem } from '$types/veda'; +import { LinkProperties, TaxonomyItem } from '$types/veda'; import { FilterActions } from '$components/common//catalog/utils'; const SourcesUl = styled.ul` @@ -23,11 +22,12 @@ interface SourcesListProps { sources?: TaxonomyItem[]; onSourceClick?: (v: string) => void; rootPath?: string; + linkProperties: LinkProperties; } export function CardSourcesList(props: SourcesListProps) { - const { sources, onSourceClick, rootPath } = props; - + const { sources, onSourceClick, linkProperties, rootPath } = props; + const { LinkElement, pathAttributeKeyName } = linkProperties as { LinkElement: React.ElementType, pathAttributeKeyName: string }; if (!sources?.length) return null; // No link rendering @@ -50,19 +50,19 @@ export function CardSourcesList(props: SourcesListProps) { {sources.map((source) => (
  • - { e.preventDefault(); onSourceClick(source.id); }} > {source.name} - +
  • ))}
    diff --git a/app/scripts/components/common/catalog/catalog-card.tsx b/app/scripts/components/common/catalog/catalog-card.tsx index 439062461..65ef6b20e 100644 --- a/app/scripts/components/common/catalog/catalog-card.tsx +++ b/app/scripts/components/common/catalog/catalog-card.tsx @@ -121,7 +121,7 @@ export const CatalogCard = (props: CatalogCardProps) => { overline={ - + } linkLabel='View dataset' diff --git a/app/scripts/components/common/featured-slider-section.tsx b/app/scripts/components/common/featured-slider-section.tsx index e70a00b15..fb836d054 100644 --- a/app/scripts/components/common/featured-slider-section.tsx +++ b/app/scripts/components/common/featured-slider-section.tsx @@ -93,7 +93,10 @@ function FeaturedSliderSection(props: FeaturedSliderSectionProps) { return sortedFeaturedItems.map((d) => { const date = new Date(d[dateProperty ?? '']); const topics = getTaxonomy(d, TAXONOMY_TOPICS)?.values; - + const linkProperties = { + pathAttributeKeyName: 'to', + LinkElement: SmartLink + }; return ( )} diff --git a/app/scripts/components/stories/hub/hub-content.tsx b/app/scripts/components/stories/hub/hub-content.tsx index bcfa813a7..e78ea28f8 100644 --- a/app/scripts/components/stories/hub/hub-content.tsx +++ b/app/scripts/components/stories/hub/hub-content.tsx @@ -149,6 +149,7 @@ export default function HubContent(props:HubContentProps) { { onAction(FilterActions.TAXONOMY_MULTISELECT, { key: TAXONOMY_SOURCE, @@ -166,9 +167,8 @@ export default function HubContent(props:HubContentProps) { } linkLabel='View more' linkProperties={{ + ...linkProperties, linkTo: `${d.asLink?.url ?? d.path}`, - LinkElement, - pathAttributeKeyName, isLinkExternal: d.isLinkExternal }} title={ From 4a0318f7ab3d43dbbac935dbc48701fe76895b5b Mon Sep 17 00:00:00 2001 From: Hanbyul Jo Date: Wed, 30 Oct 2024 14:20:50 -0400 Subject: [PATCH 04/10] Flag the problem - 1 --- .../map/controls/aoi/custom-aoi-control.tsx | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/app/scripts/components/common/map/controls/aoi/custom-aoi-control.tsx b/app/scripts/components/common/map/controls/aoi/custom-aoi-control.tsx index 34d8b90ec..d3ebff677 100644 --- a/app/scripts/components/common/map/controls/aoi/custom-aoi-control.tsx +++ b/app/scripts/components/common/map/controls/aoi/custom-aoi-control.tsx @@ -86,6 +86,7 @@ function CustomAoI({ // from feature to point. const [, forceUpdate] = useState(0); useEffect(() => { + if(!map.loaded()) return; const mbDraw = map?._drawControl; if (!mbDraw) return; const aoiSelectedFor = selectedForEditing ? SIMPLE_SELECT : STATIC_MODE; @@ -213,6 +214,7 @@ function CustomAoI({ // selected, the trash method doesn't do anything. So, in this case, we // trigger the delete for the whole feature. const selectedFeatures = mbDraw.getSelected()?.features; + if ( mbDraw.getMode() === DIRECT_SELECT && selectedFeatures.length && @@ -241,9 +243,19 @@ function CustomAoI({ mbDraw.trash(); }, [features, aoiDeleteAll, map]); - const isAreaSelected = !!map?._drawControl?.getSelected().features.length; - const isPointSelected = - !!map?._drawControl.getSelectedPoints().features.length; + const isAreaSelected = false; + const isPointSelected = false; + + // try { + // @TODO: the function below gets called boefore the store of mapboxdraw is initialized (before being added to map) + // isAreaSelected = !!map?._drawControl?.getSelected().features.length; + // isPointSelected = + // !!map?._drawControl?.getSelectedPoints()?.features.length; + // } catch(e) { + // console.error(e); + // isAreaSelected = false; + // isPointSelected = false; + // } const hasFeatures = !!features.length; return ( @@ -330,7 +342,6 @@ export default function CustomAoIControl({ // as Mapbox Draw handles this internally when the drawing is completed useEffect(() => { if (!main) return; - const mbDraw = main._drawControl; if (!mbDraw) return; From 0fc1b2b0fa9c920b13a70c2bca6d3d4afffe2ee2 Mon Sep 17 00:00:00 2001 From: Hanbyul Jo Date: Wed, 30 Oct 2024 14:28:52 -0400 Subject: [PATCH 05/10] Edit date atom (workaround) --- app/scripts/components/exploration/atoms/dates.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/scripts/components/exploration/atoms/dates.ts b/app/scripts/components/exploration/atoms/dates.ts index e79e979a1..6cdf70069 100644 --- a/app/scripts/components/exploration/atoms/dates.ts +++ b/app/scripts/components/exploration/atoms/dates.ts @@ -28,8 +28,13 @@ export const selectedDateAtom = atomWithUrlValueStability({ if (!prev || !next) return prev === next; return prev.getTime() === next.getTime(); }, - dehydrate: (date) => { - return date?.toISOString() ?? ''; + dehydrate: (d) => { + // @TODO: temporary to work around + try { + return d?.toISOString() ?? ''; + } catch(e) { + return ''; + } } }); From 889bd47f96a5b4b17a2447feb5ec8b52269c97aa Mon Sep 17 00:00:00 2001 From: Hanbyul Jo Date: Wed, 30 Oct 2024 14:51:02 -0400 Subject: [PATCH 06/10] Make a comment where it uses data faux module datasetLayers --- app/scripts/components/exploration/atoms/datasets.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/app/scripts/components/exploration/atoms/datasets.ts b/app/scripts/components/exploration/atoms/datasets.ts index ed9751f07..f78bbb18d 100644 --- a/app/scripts/components/exploration/atoms/datasets.ts +++ b/app/scripts/components/exploration/atoms/datasets.ts @@ -51,6 +51,7 @@ export const timelineDatasetsAtom = atomWithUrlValueStability< } // Reconcile the dataset with the internal data (from VEDA config files) // and then add the url stored settings. + // @TODO - replace datasetLayers const [reconciled] = reconcileDatasets([enc.id], datasetLayers, []); if (enc.settings) { reconciled.settings = enc.settings; From bafb20e1dca88ca2d845a39ca767f765db9fb09a Mon Sep 17 00:00:00 2001 From: Hanbyul Jo Date: Thu, 31 Oct 2024 16:20:06 -0400 Subject: [PATCH 07/10] Put Try Catch block for drawcontrol function --- .../map/controls/aoi/custom-aoi-control.tsx | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/app/scripts/components/common/map/controls/aoi/custom-aoi-control.tsx b/app/scripts/components/common/map/controls/aoi/custom-aoi-control.tsx index d3ebff677..0b8a1d6b5 100644 --- a/app/scripts/components/common/map/controls/aoi/custom-aoi-control.tsx +++ b/app/scripts/components/common/map/controls/aoi/custom-aoi-control.tsx @@ -243,19 +243,19 @@ function CustomAoI({ mbDraw.trash(); }, [features, aoiDeleteAll, map]); - const isAreaSelected = false; - const isPointSelected = false; - - // try { - // @TODO: the function below gets called boefore the store of mapboxdraw is initialized (before being added to map) - // isAreaSelected = !!map?._drawControl?.getSelected().features.length; - // isPointSelected = - // !!map?._drawControl?.getSelectedPoints()?.features.length; - // } catch(e) { - // console.error(e); - // isAreaSelected = false; - // isPointSelected = false; - // } + let isAreaSelected = false; + let isPointSelected = false; + + // @NOTE: map?._drawControl?.getSelected() needs access to mapboxgl draw context store, + // but the function gets called before mapboxdraw store is initialized (before being added to map) resulting in an error + // Wrapping with try block so the values get subbed even when the store is not available + try { + isAreaSelected = !!(map?._drawControl?.getSelected().features.length); + isPointSelected = !!(map?._drawControl?.getSelectedPoints()?.features.length); + } catch(e) { + isAreaSelected = false; + isPointSelected = false; + } const hasFeatures = !!features.length; return ( From ed269c6aa56e140025d3eb7f34e039bf224b76d5 Mon Sep 17 00:00:00 2001 From: Hanbyul Jo Date: Fri, 1 Nov 2024 08:51:33 -0400 Subject: [PATCH 08/10] Add last array method --- app/scripts/index.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/scripts/index.ts b/app/scripts/index.ts index b377e8025..59c0dde25 100644 --- a/app/scripts/index.ts +++ b/app/scripts/index.ts @@ -20,6 +20,17 @@ import useTimelineDatasetAtom from '$components/exploration/hooks/use-timeline-d import { timelineDatasetsAtom } from '$components/exploration/atoms/datasets'; import { DatasetSelectorModal } from '$components/exploration/components/dataset-selector-modal'; +// Adding .last property to array +/* eslint-disable-next-line fp/no-mutating-methods */ +Object.defineProperty(Array.prototype, 'last', { + enumerable: false, + configurable: true, + get: function () { + return this[this.length - 1]; + }, + set: undefined +}); + export { // COMPONENTS Block, From dc0408a172b4e7c0ebe1c031a5fdc34df3be0f30 Mon Sep 17 00:00:00 2001 From: Hanbyul Jo Date: Fri, 1 Nov 2024 14:52:15 -0400 Subject: [PATCH 09/10] Revert temporary work around --- app/scripts/components/exploration/atoms/dates.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/app/scripts/components/exploration/atoms/dates.ts b/app/scripts/components/exploration/atoms/dates.ts index 6cdf70069..022ebcaeb 100644 --- a/app/scripts/components/exploration/atoms/dates.ts +++ b/app/scripts/components/exploration/atoms/dates.ts @@ -29,12 +29,7 @@ export const selectedDateAtom = atomWithUrlValueStability({ return prev.getTime() === next.getTime(); }, dehydrate: (d) => { - // @TODO: temporary to work around - try { - return d?.toISOString() ?? ''; - } catch(e) { - return ''; - } + return d?.toISOString() ?? ''; } }); From f5bb96cfb0899c7154546de3900e91e771d5c883 Mon Sep 17 00:00:00 2001 From: Hanbyul Jo Date: Wed, 6 Nov 2024 10:15:36 -0500 Subject: [PATCH 10/10] Get rid of the line that is not necessary --- .../components/common/map/controls/aoi/custom-aoi-control.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/app/scripts/components/common/map/controls/aoi/custom-aoi-control.tsx b/app/scripts/components/common/map/controls/aoi/custom-aoi-control.tsx index 0b8a1d6b5..98300ca8f 100644 --- a/app/scripts/components/common/map/controls/aoi/custom-aoi-control.tsx +++ b/app/scripts/components/common/map/controls/aoi/custom-aoi-control.tsx @@ -86,7 +86,6 @@ function CustomAoI({ // from feature to point. const [, forceUpdate] = useState(0); useEffect(() => { - if(!map.loaded()) return; const mbDraw = map?._drawControl; if (!mbDraw) return; const aoiSelectedFor = selectedForEditing ? SIMPLE_SELECT : STATIC_MODE;