Skip to content
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

Various fixes for E&A #1229

Merged
merged 10 commits into from
Nov 6, 2024
16 changes: 8 additions & 8 deletions app/scripts/components/common/card-sources.tsx
Original file line number Diff line number Diff line change
@@ -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`
Expand All @@ -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
Expand All @@ -50,19 +50,19 @@ export function CardSourcesList(props: SourcesListProps) {
<SourcesUl>
{sources.map((source) => (
<li key={source.id}>
<Link
to={`${rootPath}?${FilterActions.TAXONOMY}=${encodeURIComponent(
<LinkElement
{...{[pathAttributeKeyName]:`${rootPath}?${FilterActions.TAXONOMY}=${encodeURIComponent(
JSON.stringify({
Source: source.id
})
)}`}
)}`}}
onClick={(e) => {
e.preventDefault();
onSourceClick(source.id);
}}
>
{source.name}
</Link>
</LinkElement>
</li>
))}
</SourcesUl>
Expand Down
2 changes: 1 addition & 1 deletion app/scripts/components/common/catalog/catalog-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ export const CatalogCard = (props: CatalogCardProps) => {
overline={
<CardMeta>
<DatasetClassification dataset={dataset} />
<CardSourcesList sources={sources} />
<CardSourcesList sources={sources} linkProperties={linkProperties} />
</CardMeta>
}
linkLabel='View dataset'
Expand Down
9 changes: 6 additions & 3 deletions app/scripts/components/common/featured-slider-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<ContinuumGridItem {...bag} key={d.id}>
<Card
Expand All @@ -108,9 +111,8 @@ function FeaturedSliderSection(props: FeaturedSliderSectionProps) {
cardType='featured'
linkLabel='View more'
linkProperties={{
...linkProperties,
linkTo: `${d.asLink?.url ?? getItemPath(d)}`,
pathAttributeKeyName: 'to',
LinkElement: SmartLink,
isLinkExternal: d.isLinkExternal
}}
title={d.name}
Expand All @@ -120,6 +122,7 @@ function FeaturedSliderSection(props: FeaturedSliderSectionProps) {
<DatasetClassification dataset={d} />
)}
<CardSourcesList
linkProperties={linkProperties}
sources={getTaxonomy(d, TAXONOMY_SOURCE)?.values}
/>
<VerticalDivider variation='light' />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,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 &&
Expand Down Expand Up @@ -241,9 +242,19 @@ function CustomAoI({
mbDraw.trash();
}, [features, aoiDeleteAll, map]);

const isAreaSelected = !!map?._drawControl?.getSelected().features.length;
const isPointSelected =
!!map?._drawControl.getSelectedPoints().features.length;
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 (
Expand Down Expand Up @@ -330,7 +341,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;
Expand Down
1 change: 1 addition & 0 deletions app/scripts/components/exploration/atoms/datasets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions app/scripts/components/exploration/atoms/dates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ export const selectedDateAtom = atomWithUrlValueStability<Date | null>({
if (!prev || !next) return prev === next;
return prev.getTime() === next.getTime();
},
dehydrate: (date) => {
return date?.toISOString() ?? '';
dehydrate: (d) => {
return d?.toISOString() ?? '';
}
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
import React, { useCallback, useEffect, useState } from 'react';
import styled from 'styled-components';
import { useAtom } from 'jotai';
import {
Modal,
ModalBody,
ModalFooter,
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)`
Expand Down Expand Up @@ -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<string[]>(
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();
Expand All @@ -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 (
<DatasetModal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { glsp, themeVal } from '@devseed-ui/theme-provider';
import { createButtonStyles } from '@devseed-ui/button';
import { LayerInfo } from 'veda';

import SmartLink from '$components/common/smart-link';
import { getDatasetPath } from '$utils/routes';
import { CollecticonDatasetLayers } from '$components/common/icons/dataset-layers';
import { ParentDatasetTitle } from '$components/common/catalog/catalog-content';
Expand Down Expand Up @@ -54,7 +53,8 @@ const ParentDatasetHeading = styled.h2`
padding: ${glsp(0.5)} 0;
`;

const ButtonStyleLink = styled(SmartLink)<any>`
// override with 'as' as LinkComponent
const ButtonStyleLink = styled.a<any>`
&&& {
${({ variation, size }) => createButtonStyles({ variation, size })}
}
Expand Down Expand Up @@ -101,6 +101,7 @@ const LayerInfoLinerModal = styled.div`

export default function LayerInfoModal(props: LayerInfoModalProps) {
const { revealed, close, layerData } = props;

const { parentData } = layerData;
const dataCatalogPage = getDatasetPath(parentData.id);
return (
Expand Down Expand Up @@ -132,7 +133,7 @@ export default function LayerInfoModal(props: LayerInfoModalProps) {
<div dangerouslySetInnerHTML={{__html: parentData.infoDescription?? 'Currently, we are unable to display the layer information, but you can find it in the data catalog.' }} />
}
footerContent={
<ButtonStyleLink to={dataCatalogPage} onClick={close} variation='primary-fill' size='medium' target='_blank'>
<ButtonStyleLink href={dataCatalogPage} rel='noopener noreferrer' onClick={close} variation='primary-fill' size='medium' target='_blank'>
Open in Data Catalog
</ButtonStyleLink>
}
Expand Down

This file was deleted.

22 changes: 15 additions & 7 deletions app/scripts/components/exploration/container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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
*
Expand All @@ -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);
Expand All @@ -59,11 +61,17 @@ export default function ExplorationAndAnalysisContainer() {
<TourManager />
<PageMainContent>
<PageHero title='Exploration' isHidden />
<ExplorationAndAnalysis datasets={datasets} setDatasets={setDatasets} openDatasetsSelectionModal={openModal} />
<ExplorationAndAnalysis
datasets={timelineDatasets}
setDatasets={setTimelineDatasets}
openDatasetsSelectionModal={openModal}
/>
<DatasetSelectorModal
revealed={datasetModalRevealed}
close={closeModal}
datasets={allExploreDatasets}
timelineDatasets={timelineDatasets}
setTimelineDatasets={setTimelineDatasets}
datasetPathName={DATASETS_PATH}
linkProperties={{
LinkElement: SmartLink,
Expand Down
10 changes: 10 additions & 0 deletions app/scripts/components/exploration/data-utils-no-faux-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@ export const getDatasetLayers = (datasets: VedaDatum<DatasetData>) =>
}));
});

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
Expand Down
Original file line number Diff line number Diff line change
@@ -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];
}
hanbyul-here marked this conversation as resolved.
Show resolved Hide resolved
4 changes: 2 additions & 2 deletions app/scripts/components/stories/hub/hub-content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ export default function HubContent(props:HubContentProps) {
<CardSourcesList
sources={getTaxonomy(d, TAXONOMY_SOURCE)?.values}
rootPath={pathname}
linkProperties={linkProperties}
onSourceClick={(id) => {
onAction(FilterActions.TAXONOMY_MULTISELECT, {
key: TAXONOMY_SOURCE,
Expand All @@ -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={
Expand Down
Loading
Loading