Skip to content

Commit

Permalink
Merge pull request #1432 from amir-azma/1376-details-store
Browse files Browse the repository at this point in the history
fix(layer-selection) Pre select the previously selected layer in left panel (#1432)
  • Loading branch information
jolevesq authored Oct 24, 2023
2 parents 51010d6 + e7647a8 commit 3c23569
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 9 deletions.
14 changes: 10 additions & 4 deletions packages/geoview-core/src/core/components/details/details.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React, { useEffect, useState } from 'react';
import React, { useEffect } from 'react';
import { useStore } from 'zustand';
import { TypeArrayOfFeatureInfoEntries } from '@/api/events/payloads';
import { LayersListFooter } from './layers-list-footer';
import { getGeoViewStore } from '@/core/stores/stores-managers';

export interface TypeDetailsProps {
arrayOfLayerData: TypeArrayOfLayerData;
Expand All @@ -20,11 +22,15 @@ export type TypeArrayOfLayerData = TypeLayerData[];
* @returns {JSX.Element} returns the Details component
*/
export function DetailsFooter({ arrayOfLayerData, mapId }: TypeDetailsProps): JSX.Element | null {
const [details, setDetails] = useState<TypeArrayOfLayerData>([]);
const store = getGeoViewStore(mapId);
const layerDataArray = useStore(store, (state) => state.detailsState.layerDataArray);

useEffect(() => {
setDetails(arrayOfLayerData);
store.setState({
detailsState: { ...store.getState().detailsState, layerDataArray: arrayOfLayerData },
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [arrayOfLayerData]);

return <LayersListFooter arrayOfLayerData={details} mapId={mapId} />;
return <LayersListFooter arrayOfLayerData={layerDataArray} mapId={mapId} />;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable react/require-default-props */
import React, { useEffect, useState, useRef, useCallback } from 'react';
import { useStore } from 'zustand';
import { useTheme } from '@mui/material/styles';
import { useTranslation } from 'react-i18next';
import { getUid } from 'ol/util';
Expand Down Expand Up @@ -35,6 +36,7 @@ import {
TypeGeometry,
} from '@/api/events/payloads';
import { getSxClasses } from './details-style';
import { getGeoViewStore } from '@/core/stores/stores-managers';

interface TypeLayersListProps {
arrayOfLayerData: TypeArrayOfLayerData;
Expand All @@ -52,13 +54,22 @@ export function LayersListFooter(props: TypeLayersListProps): JSX.Element {
const { t } = useTranslation<string>();
const theme = useTheme();
const selectedFeatures = useRef<string[]>([]);

const store = getGeoViewStore(mapId);
const selectedLayerPath = useStore(store, (state) => state.detailsState.selectedLayerPath);

const [layerDataInfo, setLayerDataInfo] = useState<TypeLayerData | null>(null);
const [currentFeatureIndex, setCurrentFeatureIndex] = useState<number>(0);
const [isClearAllCheckboxes, setIsClearAllCheckboxes] = useState<boolean>(false);
const [disableClearAllBtn, setDisableClearAllBtn] = useState<boolean>(false);

const sxClasses = getSxClasses(theme);

// Returns the index of matching layer based on the found layer path
const findLayerPathIndex = (layerDataArray: TypeArrayOfLayerData, layerPathSearch: string): number => {
return layerDataArray.findIndex((item) => item.layerPath === layerPathSearch);
};

const highlightCallbackFunction = (payload: PayloadBaseClass) => {
if (payloadIsAFeatureHighlight(payload)) {
selectedFeatures.current.push(getUid(payload.feature.geometry));
Expand Down Expand Up @@ -133,11 +144,20 @@ export function LayersListFooter(props: TypeLayersListProps): JSX.Element {

useEffect(() => {
if (arrayOfLayerData.length > 0) {
// load the first layer we clicked with its feature info in right panel
// if there are multiple layers, we load the first one on the list with its feature info
setLayerDataInfo(arrayOfLayerData[0]);
// Check if have the previous selected layer path in incoming arrayOfLayerData
// if so, get the index of the found layer, we need to pass to setLayerDataInfo to load layer in left panel
const commonLayerPathIndex = findLayerPathIndex(arrayOfLayerData, selectedLayerPath);
setLayerDataInfo(arrayOfLayerData[commonLayerPathIndex > -1 ? commonLayerPathIndex : 0]);
store.setState({
detailsState: {
...store.getState().detailsState,
selectedLayerPath: arrayOfLayerData[commonLayerPathIndex > -1 ? commonLayerPathIndex : 0].layerPath,
},
});

setCurrentFeatureIndex(0);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [arrayOfLayerData]);

const renderLayerList = useCallback(() => {
Expand All @@ -164,6 +184,9 @@ export function LayersListFooter(props: TypeLayersListProps): JSX.Element {
onClick={() => {
setLayerDataInfo(layerData);
setCurrentFeatureIndex(0);
store.setState({
detailsState: { ...store.getState().detailsState, selectedLayerPath: layerData.layerPath },
});
}}
sx={{ height: '67px' }}
>
Expand Down Expand Up @@ -232,7 +255,7 @@ export function LayersListFooter(props: TypeLayersListProps): JSX.Element {
aria-label="backward"
tooltip="details.previousFeatureBtn"
tooltipPlacement="top"
onClick={() => setCurrentFeatureIndex((prevValue) => prevValue - 1)}
onClick={() => setCurrentFeatureIndex(currentFeatureIndex - 1)}
disabled={currentFeatureIndex === 0}
>
<ArrowBackIosOutlinedIcon />
Expand All @@ -242,7 +265,7 @@ export function LayersListFooter(props: TypeLayersListProps): JSX.Element {
aria-label="forward"
tooltip="details.nextFeatureBtn"
tooltipPlacement="top"
onClick={() => setCurrentFeatureIndex((prevValue) => prevValue + 1)}
onClick={() => setCurrentFeatureIndex(currentFeatureIndex + 1)}
// eslint-disable-next-line no-unsafe-optional-chaining
disabled={currentFeatureIndex === layerDataInfo?.features.length - 1}
>
Expand Down
11 changes: 11 additions & 0 deletions packages/geoview-core/src/core/stores/geoview-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { toLonLat } from 'ol/proj';

import { TypeMapFeaturesConfig, TypeValidMapProjectionCodes } from '@/core/types/global-types';
import { TypeLegendItemProps } from '../components/legend-2/types';
import { TypeArrayOfLayerData } from '../components/details/details';

import { TypeMapMouseInfo } from '@/api/events/payloads';
import { TypeDisplayLanguage, TypeInteraction } from '@/geo/map/map-schema-types';
Expand Down Expand Up @@ -88,6 +89,11 @@ export interface IMapDataTableState {
setToolbarRowSelectedMessage: (message: string) => void;
}

export interface IDetailsState {
layerDataArray: TypeArrayOfLayerData;
selectedLayerPath: string;
}

export interface IGeoViewState {
displayLanguage: TypeDisplayLanguage;
isCrosshairsActive: boolean;
Expand All @@ -100,6 +106,7 @@ export interface IGeoViewState {
legendState: ILegendState;
mapState: IMapState;
notificationState: INotificationsState;
detailsState: IDetailsState;
dataTableState: IMapDataTableState;
setMapConfig: (config: TypeMapFeaturesConfig) => void;
onMapLoaded: (mapElem: OLMap) => void;
Expand Down Expand Up @@ -189,6 +196,10 @@ export const geoViewStoreDefinition = (
selectedIsVisible: true,
selectedLayers: {},
},
detailsState: {
layerDataArray: [],
selectedLayerPath: '',
},
notificationState: {
notifications: [],
},
Expand Down

0 comments on commit 3c23569

Please sign in to comment.