From a503057258d254700773c26c9f86d6b20ab5ae2d Mon Sep 17 00:00:00 2001 From: j8seangel Date: Tue, 9 Apr 2024 12:59:48 +0200 Subject: [PATCH] show spinner only for each popup category --- apps/fishing-map/features/map/map.slice.ts | 2 +- .../features/map/popups/ActivityLayers.tsx | 14 +- .../features/map/popups/DetectionsLayers.tsx | 16 +- .../features/map/popups/PopupWrapper.tsx | 286 +++++++++--------- 4 files changed, 169 insertions(+), 149 deletions(-) diff --git a/apps/fishing-map/features/map/map.slice.ts b/apps/fishing-map/features/map/map.slice.ts index 1d1b4c7795..1879d301ff 100644 --- a/apps/fishing-map/features/map/map.slice.ts +++ b/apps/fishing-map/features/map/map.slice.ts @@ -493,7 +493,7 @@ const slice = createSlice({ state.currentFishingRequestId = '' if (state?.clicked?.features?.length && action.payload?.vessels?.length) { state.clicked.features = state.clicked.features.map((feature: any) => { - const sublayers = (feature as FourwingsPickingObject).sublayers.map((sublayer) => { + const sublayers = (feature as FourwingsPickingObject).sublayers?.map((sublayer) => { const vessels = action.payload?.vessels.find((v) => v.sublayerId === sublayer.id)?.vessels || [] return { ...sublayer, vessels } diff --git a/apps/fishing-map/features/map/popups/ActivityLayers.tsx b/apps/fishing-map/features/map/popups/ActivityLayers.tsx index 2099086b78..1d0f619c49 100644 --- a/apps/fishing-map/features/map/popups/ActivityLayers.tsx +++ b/apps/fishing-map/features/map/popups/ActivityLayers.tsx @@ -1,20 +1,19 @@ import { Fragment } from 'react' import { useTranslation } from 'react-i18next' -import { Icon } from '@globalfishingwatch/ui-components' -import { FourwingsDeckSublayer } from '@globalfishingwatch/deck-layers' +import { Icon, Spinner } from '@globalfishingwatch/ui-components' import { DataviewCategory } from '@globalfishingwatch/api-types' import I18nNumber from 'features/i18n/i18nNumber' -import { TooltipEventFeature } from 'features/map/map.hooks' import { SliceExtendedFourwingsDeckSublayer } from '../map.slice' import popupStyles from './Popup.module.css' import VesselsTable, { getVesselTableTitle } from './VesselsTable' type ActivityTooltipRowProps = { feature: SliceExtendedFourwingsDeckSublayer & { category: DataviewCategory } + loading?: boolean showFeaturesDetails: boolean } -function ActivityTooltipRow({ feature, showFeaturesDetails }: ActivityTooltipRowProps) { +function ActivityTooltipRow({ feature, showFeaturesDetails, loading }: ActivityTooltipRowProps) { const { t } = useTranslation() const title = getVesselTableTitle(feature) // TODO get the value based on the sublayer @@ -36,8 +35,13 @@ function ActivityTooltipRow({ feature, showFeaturesDetails }: ActivityTooltipRow })} + {loading && ( +
+ +
+ )} {/* // TODO:deck add subcategory info */} - {showFeaturesDetails && ( + {!loading && showFeaturesDetails && ( )} diff --git a/apps/fishing-map/features/map/popups/DetectionsLayers.tsx b/apps/fishing-map/features/map/popups/DetectionsLayers.tsx index 30a7b337b1..8132dcb6cc 100644 --- a/apps/fishing-map/features/map/popups/DetectionsLayers.tsx +++ b/apps/fishing-map/features/map/popups/DetectionsLayers.tsx @@ -1,6 +1,6 @@ import { Fragment } from 'react' import { useTranslation } from 'react-i18next' -import { Icon } from '@globalfishingwatch/ui-components' +import { Icon, Spinner } from '@globalfishingwatch/ui-components' import I18nNumber from 'features/i18n/i18nNumber' import { TooltipEventFeature, TooltipEventFeatureVesselsInfo } from 'features/map/map.hooks' import VesselsTable, { VesselDetectionTimestamps } from 'features/map/popups/VesselsTable' @@ -8,9 +8,14 @@ import styles from './Popup.module.css' type ViirsMatchTooltipRowProps = { feature: TooltipEventFeature + loading?: boolean showFeaturesDetails: boolean } -function ViirsMatchTooltipRow({ feature, showFeaturesDetails }: ViirsMatchTooltipRowProps) { +function ViirsMatchTooltipRow({ + feature, + showFeaturesDetails, + loading, +}: ViirsMatchTooltipRowProps) { const { t } = useTranslation() // Avoid showing not matched detections const matchedVessels: TooltipEventFeatureVesselsInfo['vessels'] = ( @@ -50,7 +55,12 @@ function ViirsMatchTooltipRow({ feature, showFeaturesDetails }: ViirsMatchToolti )} - {showFeaturesDetails && ( + {loading && ( +
+ +
+ )} + {!loading && showFeaturesDetails && ( )} diff --git a/apps/fishing-map/features/map/popups/PopupWrapper.tsx b/apps/fishing-map/features/map/popups/PopupWrapper.tsx index 5c74ce091c..b59f5902e4 100644 --- a/apps/fishing-map/features/map/popups/PopupWrapper.tsx +++ b/apps/fishing-map/features/map/popups/PopupWrapper.tsx @@ -57,12 +57,12 @@ function PopupWrapper({ const timeCompareTimeDescription = useTimeCompareTimeDescription() const mapViewport = useMapViewport() - const fishingInteractionStatus = useSelector(selectFishingInteractionStatus) + const activityInteractionStatus = useSelector(selectFishingInteractionStatus) const apiEventStatus = useSelector(selectApiEventStatus) - const popupNeedsLoading = [fishingInteractionStatus, apiEventStatus].some( - (s) => s === AsyncReducerStatus.Loading - ) + // const popupNeedsLoading = [fishingInteractionStatus, apiEventStatus].some( + // (s) => s === AsyncReducerStatus.Loading + // ) if (!mapViewport || !interaction || !interaction.features) return null @@ -88,105 +88,112 @@ function PopupWrapper({ style={{ position: 'absolute', top, left, maxWidth: '600px' }} className={cx(styles.popup, styles[type], className)} > - {popupNeedsLoading ? ( -
- -
- ) : ( -
- {/*
+
+ {/*
*/} -
- {timeCompareTimeDescription && ( -
{timeCompareTimeDescription}
- )} - {Object.entries(featureByCategory)?.map(([featureCategory, features]) => { - switch (featureCategory) { - // TODO: deck restore this popup - // case DataviewCategory.Comparison: - // return ( - // - // ) - case DataviewCategory.Activity: - return (features as SliceExtendedFourwingsFeature[])?.map((feature, i) => { - return feature.sublayers.map((sublayer, j) => ( - - )) - }) - case DataviewCategory.Detections: - return (features as FourwingsPickingObject[])?.map((feature, i) => { - return feature.sublayers.map((sublayer, j) => ( - - )) - }) - case DataviewCategory.Events: - return ( - + {timeCompareTimeDescription && ( +
{timeCompareTimeDescription}
+ )} + {Object.entries(featureByCategory)?.map(([featureCategory, features]) => { + switch (featureCategory) { + // TODO: deck restore this popup + // case DataviewCategory.Comparison: + // return ( + // + // ) + case DataviewCategory.Activity: { + return (features as SliceExtendedFourwingsFeature[])?.map((feature, i) => { + return feature.sublayers.map((sublayer, j) => ( + - ) - // TODO: deck restore this popup - // case DataviewCategory.Environment: { - // const contextEnvironmentalFeatures = features.filter( - // (feature) => - // feature.type === DataviewType.Context || - // feature.type === DataviewType.UserContext - // ) - // const environmentalFeatures = features.filter( - // (feature) => - // feature.type !== DataviewType.Context && - // feature.type !== DataviewType.UserContext - // ) - // return ( - // - // - // - // - // ) - // } - case DataviewCategory.Context: { - // const defaultContextFeatures = features.filter( - // (feature) => feature.type === DataviewType.Context - // ) - // const workspacePointsFeatures = features.filter( - // (feature) => feature.source === WORKSPACE_GENERATOR_ID - // ) - // const areaBufferFeatures = features.filter( - // (feature) => feature.source === REPORT_BUFFER_GENERATOR_ID - // ) - // const annotationFeatures = features.filter( - // (feature) => feature.type === DataviewType.Annotation - // ) - // const rulersFeatures = features.filter( - // (feature) => feature.type === DataviewType.Rulers - // ) - // const userPointFeatures = features.filter( - // (feature) => feature.type === DataviewType.UserPoints - // ) + )) + }) + } + case DataviewCategory.Detections: { + return (features as FourwingsPickingObject[])?.map((feature, i) => { + return feature.sublayers.map((sublayer, j) => ( + + )) + }) + } + case DataviewCategory.Events: { + if (apiEventStatus === AsyncReducerStatus.Loading) { return ( - - {/* +
+ +
+ ) + } + return ( + + ) + } + // TODO: deck restore this popup + // case DataviewCategory.Environment: { + // const contextEnvironmentalFeatures = features.filter( + // (feature) => + // feature.type === DataviewType.Context || + // feature.type === DataviewType.UserContext + // ) + // const environmentalFeatures = features.filter( + // (feature) => + // feature.type !== DataviewType.Context && + // feature.type !== DataviewType.UserContext + // ) + // return ( + // + // + // + // + // ) + // } + case DataviewCategory.Context: { + // const defaultContextFeatures = features.filter( + // (feature) => feature.type === DataviewType.Context + // ) + // const workspacePointsFeatures = features.filter( + // (feature) => feature.source === WORKSPACE_GENERATOR_ID + // ) + // const areaBufferFeatures = features.filter( + // (feature) => feature.source === REPORT_BUFFER_GENERATOR_ID + // ) + // const annotationFeatures = features.filter( + // (feature) => feature.type === DataviewType.Annotation + // ) + // const rulersFeatures = features.filter( + // (feature) => feature.type === DataviewType.Rulers + // ) + // const userPointFeatures = features.filter( + // (feature) => feature.type === DataviewType.UserPoints + // ) + return ( + + {/* // TODO: deck restore this popup */} - - - ) - } - // TODO: deck restore this popup - // case DataviewCategory.User: { - // const userPointFeatures = features.filter( - // (feature) => feature.type === DataviewType.UserPoints - // ) - // const userContextFeatures = features.filter( - // (feature) => feature.type === DataviewType.UserContext - // ) - // return ( - // - // - // - // - // ) - // } + +
+ ) + } + // TODO: deck restore this popup + // case DataviewCategory.User: { + // const userPointFeatures = features.filter( + // (feature) => feature.type === DataviewType.UserPoints + // ) + // const userContextFeatures = features.filter( + // (feature) => feature.type === DataviewType.UserContext + // ) + // return ( + // + // + // + // + // ) + // } - // case DataviewCategory.Vessels: - // return ( - // - // ) + // case DataviewCategory.Vessels: + // return ( + // + // ) - default: - return null - } - })} -
+ default: + return null + } + })}
- )} +
) }