diff --git a/app/scripts/components/common/card-sources.tsx b/app/scripts/components/common/card-sources.tsx index 72d47dbd4..9d9cf6cca 100644 --- a/app/scripts/components/common/card-sources.tsx +++ b/app/scripts/components/common/card-sources.tsx @@ -22,7 +22,7 @@ interface SourcesListProps { sources?: TaxonomyItem[]; onSourceClick?: (v: string) => void; rootPath?: string; - linkProperties: LinkProperties; + linkProperties?: LinkProperties; } export function CardSourcesList(props: SourcesListProps) { diff --git a/app/scripts/components/common/card/index.tsx b/app/scripts/components/common/card/index.tsx index 4b616d55c..74e705cd1 100644 --- a/app/scripts/components/common/card/index.tsx +++ b/app/scripts/components/common/card/index.tsx @@ -233,7 +233,6 @@ export function ExternalLinkFlag() { export interface LinkWithPathProperties extends LinkProperties { linkTo: string; - isLinkExternal?: boolean; } export interface CardComponentBaseProps { @@ -251,17 +250,17 @@ export interface CardComponentBaseProps { footerContent?: JSX.Element; hideExternalLinkBadge?: boolean; onCardClickCapture?: MouseEventHandler; + onClick?: MouseEventHandler; } -// @TODO: Consolidate these props when the instance adapts the new syntax +// @TODO: Created because GHG uses the card component directly and passes in "linkTo" prop. Consolidate these props when the instance adapts the new syntax // Specifically: https://github.com/US-GHG-Center/veda-config-ghg/blob/develop/custom-pages/news-and-events/component.tsx#L108 export interface CardComponentPropsDeprecated extends CardComponentBaseProps { linkTo: string; - onClick?: MouseEventHandler; - isLinkExternal?: boolean; // @TODO-SANDRA: Why does this overlap with LinkWithPathProperties } + export interface CardComponentProps extends CardComponentBaseProps { - linkProperties: LinkWithPathProperties; + linkProperties?: LinkWithPathProperties; } type CardComponentPropsType = CardComponentProps | CardComponentPropsDeprecated; @@ -288,40 +287,37 @@ function CardComponent(props: CardComponentPropsType) { parentTo, footerContent, hideExternalLinkBadge, - onCardClickCapture + onCardClickCapture, + onClick, } = props; // @TODO: This process is not necessary once all the instances adapt the linkProperties syntax // Consolidate them to use LinkProperties only - let linkProperties: LinkWithPathProperties; + let linkProperties: LinkWithPathProperties | undefined; if (hasLinkProperties(props)) { // Handle new props with linkProperties const { linkProperties: linkPropertiesProps } = props; linkProperties = linkPropertiesProps; } else { - const { linkTo, onClick, isLinkExternal } = props; - linkProperties = { + const { linkTo } = props; + linkProperties = linkTo ? { linkTo, - onClick, pathAttributeKeyName: 'to', LinkElement: SmartLink - }; + } : undefined; } - const isExternalLink = linkProperties.isLinkExternal ?? /^https?:\/\//.test(linkProperties.linkTo); + const isExternalLink = linkProperties ? /^https?:\/\//.test(linkProperties.linkTo) : false; + return ( {cardType !== 'horizontal-info' && ( <> @@ -337,7 +333,7 @@ function CardComponent(props: CardComponentPropsType) { parentTo && tagLabels.map((label) => ( diff --git a/app/scripts/components/common/catalog/catalog-card.tsx b/app/scripts/components/common/catalog/catalog-card.tsx index 13723bcf0..944507108 100644 --- a/app/scripts/components/common/catalog/catalog-card.tsx +++ b/app/scripts/components/common/catalog/catalog-card.tsx @@ -22,7 +22,7 @@ interface CatalogCardProps { selected?: boolean; onDatasetClick?: () => void; pathname?: string; - linkProperties: LinkProperties; + linkProperties?: LinkProperties; } const CardSelectable = styled(Card)<{ @@ -137,6 +137,7 @@ export const CatalogCard = (props: CatalogCardProps) => { } linkLabel='View dataset' + onClick={handleClick} title={ {title} @@ -170,7 +171,7 @@ export const CatalogCard = (props: CatalogCardProps) => { ) : null} } - linkProperties={{...linkProperties, linkTo: linkTo, onClick: handleClick}} + {...(linkProperties ? {linkProperties: {...linkProperties, linkTo: linkTo}} : {})} /> ); }; diff --git a/app/scripts/components/common/catalog/catalog-content.tsx b/app/scripts/components/common/catalog/catalog-content.tsx index 34de58ff7..dcac02395 100644 --- a/app/scripts/components/common/catalog/catalog-content.tsx +++ b/app/scripts/components/common/catalog/catalog-content.tsx @@ -264,7 +264,6 @@ function CatalogContent({ selectable={true} selected={selectedIds.includes(datasetLayer.id)} onDatasetClick={() => onCardSelect(datasetLayer.id, currentDataset)} - linkProperties={linkProperties} pathname={pathname} /> diff --git a/app/scripts/components/common/element-interactive.js b/app/scripts/components/common/element-interactive.js index 497679951..6deebd1f8 100644 --- a/app/scripts/components/common/element-interactive.js +++ b/app/scripts/components/common/element-interactive.js @@ -73,7 +73,13 @@ const InteractiveLink = styled.a` */ export const ElementInteractive = React.forwardRef( function ElementInteractiveFwd(props, ref) { - const { linkProps = {}, linkLabel = 'View', children, ...rest } = props; + const { + linkProps = {}, + linkLabel = 'View', + children, + onClick, + ...rest + } = props; const [isStateOver, setStateOver] = useState(false); const [isStateActive, setStateActive] = useState(false); const [isStateFocus, setStateFocus] = useState(false); @@ -92,6 +98,7 @@ export const ElementInteractive = React.forwardRef( setStateOver(false); setStateActive(false); }, [])} + onClick={onClick} > {children} (false); + const [isPointSelected, setPointSelected] = useState(false); const [selectedForEditing, setSelectedForEditing] = useAtom(selectedForEditingAtom); const { onUpdate, isDrawing, setIsDrawing, features } = useAois(); const aoiDeleteAll = useSetAtom(aoiDeleteAllAtom); - // Needed so that this component re-renders to when the draw selection changes - // from feature to point. - const [, forceUpdate] = useState(0); + // @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 + useEffect(() => { + if (!map) return; + + const mbDraw = map?._drawControl; + setAreaSelected(!!(mbDraw?.getSelected().features.length)); + setPointSelected(!!(mbDraw?.getSelectedPoints()?.features.length)); + }, [map, updated]); + useEffect(() => { const mbDraw = map?._drawControl; if (!mbDraw) return; @@ -249,19 +259,6 @@ function CustomAoI({ mbDraw.trash(); }, [features, aoiDeleteAll, map]); - 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 ( diff --git a/app/scripts/components/common/page-header/index.tsx b/app/scripts/components/common/page-header/index.tsx index 83cf15661..1b603f88a 100644 --- a/app/scripts/components/common/page-header/index.tsx +++ b/app/scripts/components/common/page-header/index.tsx @@ -15,7 +15,6 @@ import { } from '@devseed-ui/collecticons'; import UnscrollableBody from '../unscrollable-body'; -import { LinkProperties } from '../card'; import NavMenuItem from './nav-menu-item'; import { NavItem } from './types'; @@ -23,6 +22,7 @@ import { variableGlsp } from '$styles/variable-utils'; import { PAGE_BODY_ID } from '$components/common/layout-root'; import { useMediaQuery } from '$utils/use-media-query'; import { HEADER_ID } from '$utils/use-sliding-sticky-header'; +import { LinkProperties } from '$types/veda'; const PageHeaderSelf = styled.header` diff --git a/app/scripts/components/common/page-header/logo-container.tsx b/app/scripts/components/common/page-header/logo-container.tsx index 80cc709c0..d0cac7c6d 100644 --- a/app/scripts/components/common/page-header/logo-container.tsx +++ b/app/scripts/components/common/page-header/logo-container.tsx @@ -1,7 +1,8 @@ import React, { ComponentType } from 'react'; import { Tip } from '../tip'; -import { LinkProperties } from '$types/veda'; import { Brand, PageTitleSecLink } from './logo'; +import { LinkProperties } from '$types/veda'; + /** * LogoContainer that is meant to integrate in the default page header without the dependencies of the veda virtual modules * and expects the Logo SVG to be passed in as a prop - this will support the instance for refactor diff --git a/app/scripts/components/common/page-header/logo.tsx b/app/scripts/components/common/page-header/logo.tsx index a4826a83e..383539ed4 100644 --- a/app/scripts/components/common/page-header/logo.tsx +++ b/app/scripts/components/common/page-header/logo.tsx @@ -3,8 +3,8 @@ import styled from 'styled-components'; import { glsp, media, themeVal } from '@devseed-ui/theme-provider'; import NasaLogo from '../nasa-logo'; import { Tip } from '../tip'; -import { LinkProperties } from '../card'; import { ComponentOverride } from '$components/common/page-overrides'; +import { LinkProperties } from '$types/veda'; const appTitle = process.env.APP_TITLE; const appVersion = process.env.APP_VERSION; diff --git a/app/scripts/components/common/page-header/nav-menu-item.tsx b/app/scripts/components/common/page-header/nav-menu-item.tsx index ba4889432..c56249d63 100644 --- a/app/scripts/components/common/page-header/nav-menu-item.tsx +++ b/app/scripts/components/common/page-header/nav-menu-item.tsx @@ -12,10 +12,10 @@ import { DropMenu, DropMenuItem } from '@devseed-ui/dropdown'; import DropdownScrollable from '../dropdown-scrollable'; import GoogleForm from '../google-form'; -import { LinkProperties } from '../card'; import { AlignmentEnum, InternalNavLink, ExternalNavLink, NavLinkItem, DropdownNavLink, ModalNavLink, NavItem, NavItemType } from './types'; import GlobalMenuLinkCSS from '$styles/menu-link'; import { useMediaQuery } from '$utils/use-media-query'; +import { LinkProperties } from '$types/veda'; const rgbaFixed = rgba as any; diff --git a/app/scripts/components/common/smart-link.tsx b/app/scripts/components/common/smart-link.tsx index e6cf6f089..7b0a369b0 100644 --- a/app/scripts/components/common/smart-link.tsx +++ b/app/scripts/components/common/smart-link.tsx @@ -5,8 +5,6 @@ import { getLinkProps } from '$utils/url'; interface SmartLinkProps { to: string; - isLinkExternal?: boolean; - onClick?: ()=> void; children?: ReactNode; } @@ -14,9 +12,9 @@ interface SmartLinkProps { * Switches between a `a` and a `Link` depending on the url. */ export default function SmartLink(props: SmartLinkProps) { - const { to, isLinkExternal, onClick, children, ...rest } = props; - const isExternalLink = isLinkExternal ?? /^https?:\/\//.test(to); - const linkProps = getLinkProps(to, isLinkExternal, undefined, onClick); + const { to, children, ...rest } = props; + const isExternalLink = /^https?:\/\//.test(to); + const linkProps = getLinkProps(to); return isExternalLink ? ( {children} @@ -38,8 +36,9 @@ export function CustomLink(props: CustomLinkProps) { const isExternalLink = /^https?:\/\//.test(href); const linkProps = getLinkProps(href); return isExternalLink ? ( - + // @ts-expect-error linkProps returned from getLinkProps are not being recognized suddenly + ) : ( ); -} +} \ No newline at end of file diff --git a/app/scripts/components/stories/hub/hub-content.tsx b/app/scripts/components/stories/hub/hub-content.tsx index 928f2ed38..b9fff876a 100644 --- a/app/scripts/components/stories/hub/hub-content.tsx +++ b/app/scripts/components/stories/hub/hub-content.tsx @@ -184,7 +184,6 @@ export default function HubContent(props: HubContentProps) { linkProperties={{ ...linkProperties, linkTo: `${d.asLink?.url ?? d.path}`, - isLinkExternal: d.isLinkExternal }} title={ diff --git a/app/scripts/index.ts b/app/scripts/index.ts index 4e350525f..a276bbb4b 100644 --- a/app/scripts/index.ts +++ b/app/scripts/index.ts @@ -60,7 +60,7 @@ export { LogoContainer, ExplorationAndAnalysis, DatasetSelectorModal, - + // HOOKS useTimelineDatasetAtom, useFiltersWithQS, diff --git a/app/scripts/types/veda.ts b/app/scripts/types/veda.ts index a75e99cf6..96d5222c7 100644 --- a/app/scripts/types/veda.ts +++ b/app/scripts/types/veda.ts @@ -1,7 +1,7 @@ import * as dateFns from 'date-fns'; import mapboxgl from 'mapbox-gl'; import { MDXModule } from 'mdx/types'; -import { MouseEventHandler, ComponentType } from 'react'; +import { ComponentType } from 'react'; // /////////////////////////////////////////////////////////////////////////// // Datasets // // /////////////////////////////////////////////////////////////////////////// @@ -287,5 +287,4 @@ export interface DatasetDataWithEnhancedLayers extends DatasetData { export interface LinkProperties { LinkElement: string | ComponentType | undefined; pathAttributeKeyName: string; - onClick?: MouseEventHandler; } \ No newline at end of file diff --git a/app/scripts/utils/url.ts b/app/scripts/utils/url.ts index 926bf23ff..0b6e2626e 100644 --- a/app/scripts/utils/url.ts +++ b/app/scripts/utils/url.ts @@ -1,4 +1,4 @@ -import React, { MouseEventHandler } from 'react'; +import React from 'react'; import { LinkProps } from 'react-router-dom'; export function isExternalLink(link: string): boolean { @@ -9,8 +9,7 @@ export const getLinkProps = ( linkTo: string, as?: React.ForwardRefExoticComponent< LinkProps & React.RefAttributes - >, - onClick?: (() => void) | MouseEventHandler + > ) => { // Open the link in a new tab when link is external const isExternalLink = /^https?:\/\//.test(linkTo); @@ -19,11 +18,9 @@ export const getLinkProps = ( href: linkTo, to: linkTo, ...{ target: '_blank', rel: 'noopener noreferrer' }, - ...(onClick ? { onClick: onClick } : {}) } : { ...(as ? { as: as } : {}), to: linkTo, - ...(onClick ? { onClick: onClick } : {}) }; };