Skip to content

Commit

Permalink
Progress
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex-NRCan committed Feb 7, 2025
1 parent 1fd6031 commit e1a7e79
Show file tree
Hide file tree
Showing 21 changed files with 330 additions and 235 deletions.
4 changes: 3 additions & 1 deletion packages/geoview-core/public/templates/add-layers.html
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,9 @@ <h4>Add Layer Examples</h4>
<div>GeoCore UUID Layer</div>
<div style="margin-top: 10px; margin-left: 20px">
<input id="selectGeoCore" list="geocoreids" style="width: 300px" />
<datalist id="geocoreids">
<datalist id="geocoreids" value="fd4369a4-21fe-4070-914a-067474da0fd6">
<option value="fd4369a4-21fe-4070-914a-067474da0fd6"></option>
<option value="9d96e8c9-22fe-4ad2-b5e8-94a6991b744b"></option>
<option value="21b821cf-0f1c-40ee-8925-eab12d357668"></option>
<option value="ccc75c12-5acc-4a6a-959f-ef6f621147b9"></option>
<option value="0fca08b5-e9d0-414b-a3c4-092ff9c5e326"></option>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -556,8 +556,12 @@ export class MapEventProcessor extends AbstractEventProcessor {
* @param {string} layerPath - The path of the layer to get.
* @returns {TypeOrderedLayerInfo | undefined} The ordered layer info.
*/
static getMapOrderedLayerInfoForLayer(mapId: string, layerPath: string): TypeOrderedLayerInfo | undefined {
return this.getMapStateProtected(mapId).orderedLayerInfo.find((orderedLayerInfo) => orderedLayerInfo.layerPath === layerPath);
static findMapLayerFromOrderedInfo(
mapId: string,
layerPath: string,
orderedLayerInfo: TypeOrderedLayerInfo[] = this.getMapStateProtected(mapId).orderedLayerInfo
): TypeOrderedLayerInfo | undefined {
return orderedLayerInfo.find((layer) => layer.layerPath === layerPath);
}

/**
Expand All @@ -567,14 +571,12 @@ export class MapEventProcessor extends AbstractEventProcessor {
* @param {TypeOrderedLayerInfo[]} orderedLayerInfo - The array of ordered layer info to search, default is current ordered layer info.
* @returns {TypeOrderedLayerInfo[] | undefined} The ordered layer info of the layer and its children.
*/
static getMapLayerAndChildrenOrderedInfo(
static findMapLayerAndChildrenFromOrderedInfo(
mapId: string,
layerPath: string,
orderedLayerInfo: TypeOrderedLayerInfo[] = this.getMapStateProtected(mapId).orderedLayerInfo
): TypeOrderedLayerInfo[] {
return orderedLayerInfo.filter(
(info: TypeOrderedLayerInfo) => info.layerPath.startsWith(`${layerPath}/`) || info.layerPath === layerPath
);
return orderedLayerInfo.filter((layer) => layer.layerPath.startsWith(`${layerPath}/`) || layer.layerPath === layerPath);
}

static getMapIndexFromOrderedLayerInfo(mapId: string, layerPath: string): number {
Expand Down Expand Up @@ -770,7 +772,7 @@ export class MapEventProcessor extends AbstractEventProcessor {
: (geoviewLayerConfig as TypeLayerEntryConfig).layerPath;
const pathToSearch = layerPathToReplace || layerPath;
const index = this.getMapIndexFromOrderedLayerInfo(mapId, pathToSearch);
const replacedLayers = this.getMapLayerAndChildrenOrderedInfo(mapId, pathToSearch);
const replacedLayers = this.findMapLayerAndChildrenFromOrderedInfo(mapId, pathToSearch);
const newOrderedLayerInfo = LayerApi.generateArrayOfLayerOrderInfo(geoviewLayerConfig);
orderedLayerInfo.splice(index, replacedLayers.length, ...newOrderedLayerInfo);

Expand Down Expand Up @@ -1137,7 +1139,7 @@ export class MapEventProcessor extends AbstractEventProcessor {
): TypeLayerEntryConfig {
// Get needed info
const layerEntryConfig = MapEventProcessor.getMapViewerLayerAPI(mapId).getLayerEntryConfig(layerPath);
const orderedLayerInfo = MapEventProcessor.getMapOrderedLayerInfoForLayer(mapId, layerPath);
const orderedLayerInfo = MapEventProcessor.findMapLayerFromOrderedInfo(mapId, layerPath);
const legendLayerInfo = LegendEventProcessor.getLegendLayerInfo(mapId, layerPath);

// Get original layerEntryConfig from map config
Expand Down Expand Up @@ -1220,7 +1222,7 @@ export class MapEventProcessor extends AbstractEventProcessor {
const layerEntryConfig = MapEventProcessor.getMapViewerLayerAPI(mapId).getLayerEntryConfig(layerPath)!;

const { geoviewLayerConfig } = layerEntryConfig;
const orderedLayerInfo = MapEventProcessor.getMapOrderedLayerInfoForLayer(mapId, layerPath);
const orderedLayerInfo = MapEventProcessor.findMapLayerFromOrderedInfo(mapId, layerPath);
const legendLayerInfo = LegendEventProcessor.getLegendLayerInfo(mapId, layerPath);

// Check if the layer is a geocore layers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export const Attribution = memo(function Attribution(): JSX.Element {
};

// Memoize values
const attributionContent = useMemo(
const memoAttributionContent = useMemo(
() => mapAttribution.map((attribution) => <Typography key={attribution}>{attribution}</Typography>),
[mapAttribution]
);
Expand Down Expand Up @@ -96,7 +96,7 @@ export const Attribution = memo(function Attribution(): JSX.Element {
}}
onClose={handleClosePopover}
>
<Box sx={BOX_STYLES}>{attributionContent}</Box>
<Box sx={BOX_STYLES}>{memoAttributionContent}</Box>
</Popover>
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { LayerListEntry } from '.';
export interface TypeIconStackProps {
layerPath: string;
onIconClick?: () => void;
onStackIconClick?: (e: React.KeyboardEvent<HTMLElement>) => void;
onStackIconClick?: (event: React.KeyboardEvent<HTMLElement>) => void;
}

interface LayerIconProps {
Expand Down
10 changes: 7 additions & 3 deletions packages/geoview-core/src/core/components/common/layer-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Box, List, ListItem, ListItemButton, Paper, Tooltip, Typography } from
import { TypeFeatureInfoEntry, TypeQueryStatus, TypeLayerStatus } from '@/geo/map/map-schema-types';
import { getSxClasses } from './layer-list-style';
import { LayerIcon } from './layer-icon';
import { logger } from '@/core/utils/logger';

export interface LayerListEntry {
content?: string | ReactNode;
Expand Down Expand Up @@ -87,12 +88,15 @@ export const LayerListItem = memo(function LayerListItem({ id, isSelected, layer
* Handle layer click when mouse enter is pressed.
*/
const handleLayerKeyDown = useCallback(
(e: React.KeyboardEvent, selectedLayer: LayerListEntry): void => {
if (e.key === 'Enter' && !isDisabled) {
(event: React.KeyboardEvent, selectedLayer: LayerListEntry): void => {
// Log
logger.logTraceUseCallback('LAYER-LIST - handleLayerKeyDown');

if (event.key === 'Enter' && !isDisabled) {
onListItemClick(selectedLayer);
// NOTE: did this, bcz when enter is clicked, tab component `handleClick` function is fired,
// to avoid this we have do prevent default so that it doesn't probagate to the parent elements.
e.preventDefault();
event.preventDefault();
}
},
[isDisabled, onListItemClick]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ export const FeatureItem = memo(function FeatureItem({
src={item}
tabIndex={0}
onClick={() => onInitLightBox(featureInfoItem.value as string, featureInfoItem.alias, index)}
onKeyDown={(e: React.KeyboardEvent) => {
if (e.key === 'Enter') {
onKeyDown={(event: React.KeyboardEvent) => {
if (event.key === 'Enter') {
onInitLightBox(featureInfoItem.value as string, `${index}_${featureInfoItem.alias}`, index);
}
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ interface FeatureHeaderProps {
name: string;
hasGeometry: boolean;
checked: boolean;
onCheckChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
onZoomIn: (e: React.MouseEvent<HTMLButtonElement>) => void;
onCheckChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
onZoomIn: (event: React.MouseEvent<HTMLButtonElement>) => void;
}

// Constants outside component to prevent recreating every render
Expand Down Expand Up @@ -128,8 +128,8 @@ export function FeatureInfo({ feature }: FeatureInfoProps): JSX.Element | null {

// Event Handlers
const handleFeatureSelectedChange = useCallback(
(e: React.ChangeEvent<HTMLInputElement>): void => {
e.stopPropagation();
(event: React.ChangeEvent<HTMLInputElement>): void => {
event.stopPropagation();
if (!feature) return;

if (!checked) {
Expand All @@ -142,8 +142,8 @@ export function FeatureInfo({ feature }: FeatureInfoProps): JSX.Element | null {
);

const handleZoomIn = useCallback(
(e: React.MouseEvent<HTMLButtonElement>): void => {
e.stopPropagation();
(event: React.MouseEvent<HTMLButtonElement>): void => {
event.stopPropagation();
if (!featureData?.extent) return;

const center = getCenter(featureData.extent);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { ResponsiveGridLayout, ResponsiveGridLayoutExposedMethods } from '@/core
import { Typography } from '@/ui/typography/typography';
import { TypeContainerBox } from '@/core/types/global-types';
import { useUIStoreActions } from '@/core/stores/store-interface-and-intial-values/ui-state';
import { TypeLegendLayer } from './types';

interface TypeLayersPanel {
containerType?: TypeContainerBox;
Expand All @@ -30,11 +29,11 @@ export function LayersPanel({ containerType }: TypeLayersPanel): JSX.Element {

const responsiveLayoutRef = useRef<ResponsiveGridLayoutExposedMethods>(null);

const showLayerDetailsPanel = (layer: TypeLegendLayer): void => {
const showLayerDetailsPanel = (layerId: string): void => {
responsiveLayoutRef.current?.setIsRightPanelVisible(true);
responsiveLayoutRef.current?.setRightPanelFocus();
// set the focus item when layer item clicked.
setSelectedFooterLayerListItemId(`${layer.layerId}`);
setSelectedFooterLayerListItemId(`${layerId}`);
};

const leftPanel = (): JSX.Element => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { useEffect, useState, KeyboardEvent } from 'react';
import { Box, CircularProgressBase, DeleteOutlineIcon, IconButton, UndoIcon } from '@/ui';
import { TypeLegendLayer } from '@/core/components/layers/types';
import { useLayerStoreActions } from '@/core/stores/store-interface-and-intial-values/layer-state';
import { useMapStoreActions } from '@/core/stores/store-interface-and-intial-values/map-state';
import { logger } from '@/core/utils/logger';
import { useMapStoreActions, useSelectorLayerVisibility } from '@/core/stores/store-interface-and-intial-values/map-state';
import { useUIStoreActions } from '@/core/stores/store-interface-and-intial-values/ui-state';
import { useGeoViewMapId } from '@/core/stores/geoview-store';
import { logger } from '@/core/utils/logger';

interface DeleteUndoButtonProps {
layer: TypeLegendLayer;
layerPath: string;
layerId: string;
layerRemovable: boolean;
}

interface UndoButtonProps {
Expand Down Expand Up @@ -48,24 +50,26 @@ export function DeleteUndoButton(props: DeleteUndoButtonProps): JSX.Element {
// Log
logger.logTraceRender('components/layers/left-panel/delete-undo-button/DeleteUndoButton');

const { layer } = props;
const { layerPath, layerId, layerRemovable } = props;

const [progress, setProgress] = useState(10);
const [inUndoState, setInUndoState] = useState(false);

// get store actions
const mapId = useGeoViewMapId();
const { deleteLayer, setLayerDeleteInProgress, getLayerDeleteInProgress } = useLayerStoreActions();
const { getVisibilityFromOrderedLayerInfo, setOrToggleLayerVisibility } = useMapStoreActions();
const { setOrToggleLayerVisibility } = useMapStoreActions();
const { setSelectedFooterLayerListItemId } = useUIStoreActions();
const isVisible = useSelectorLayerVisibility(mapId, layerPath);

const handleDeleteClick = (): void => {
if (getVisibilityFromOrderedLayerInfo(layer.layerPath)) setOrToggleLayerVisibility(layer.layerPath);
if (isVisible) setOrToggleLayerVisibility(layerPath);
setInUndoState(true);
setLayerDeleteInProgress(true);
};

const handleUndoClick = (): void => {
setOrToggleLayerVisibility(layer.layerPath);
setOrToggleLayerVisibility(layerPath);
setInUndoState(false);
setLayerDeleteInProgress(false);
};
Expand All @@ -74,7 +78,7 @@ export function DeleteUndoButton(props: DeleteUndoButtonProps): JSX.Element {
if (e.key === 'Enter') {
e.preventDefault();
handleDeleteClick();
setSelectedFooterLayerListItemId(layer.layerId);
setSelectedFooterLayerListItemId(layerId);
}
};

Expand All @@ -98,7 +102,7 @@ export function DeleteUndoButton(props: DeleteUndoButtonProps): JSX.Element {

useEffect(() => {
if (progress === 100) {
deleteLayer(layer.layerPath);
deleteLayer(layerPath);
setInUndoState(false);
}
return undefined;
Expand All @@ -119,7 +123,7 @@ export function DeleteUndoButton(props: DeleteUndoButtonProps): JSX.Element {
}, [inUndoState]);

// Never hide the remove icon, so user can remove forever loading/processing layers.
if (!inUndoState && layer.controls?.remove !== false && !getLayerDeleteInProgress()) {
if (!inUndoState && layerRemovable && !getLayerDeleteInProgress()) {
return (
<IconButton onClick={handleDeleteClick} edge="end" size="small" onKeyDown={(e) => handleDeleteKeyDown(e)}>
<DeleteOutlineIcon color="error" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ import { useTheme } from '@mui/material/styles';
import { SingleLayer } from './single-layer';
import { getSxClasses } from './left-panel-styles';
import { Box } from '@/ui';
import { useGeoViewMapId, useLayerStoreActions, useMapStoreActions } from '@/core/stores';
import { useGeoViewMapId, useLayerStoreActions, useSelectorLayerPathOrder } from '@/core/stores';
import { logger } from '@/core/utils/logger';
import { TypeLegendLayer } from '@/core/components/layers/types';
import { TABS } from '@/core/utils/constant';

interface LayerListProps {
depth: number;
layersList: TypeLegendLayer[];
showLayerDetailsPanel: (layer: TypeLegendLayer) => void;
showLayerDetailsPanel: (layerId: string) => void;
isLayoutEnlarged: boolean;
}

Expand All @@ -23,12 +23,15 @@ export function LayersList({ layersList, showLayerDetailsPanel, isLayoutEnlarged
const sxClasses = useMemo(() => getSxClasses(theme), [theme]);

const mapId = useGeoViewMapId();
const { getIndexFromOrderedLayerInfo } = useMapStoreActions();
const layerPathOrder = useSelectorLayerPathOrder();
const { sortLegendLayersChildren } = useLayerStoreActions();

const sortedLayers = layersList.sort((a, b) =>
getIndexFromOrderedLayerInfo(a.layerPath) > getIndexFromOrderedLayerInfo(b.layerPath) ? 1 : -1
);
const sortedLayers = layersList.sort((a, b) => {
return layerPathOrder.indexOf(a.layerPath) - layerPathOrder.indexOf(b.layerPath);
});

// TODO: Check - This sort should likely happen elsewhere than in a rendering component
// TO.DOCONT: (the fact that the rendering component exists or not in the ui shouldn't have to do with the order state from store)
sortLegendLayersChildren(sortedLayers);

const textToSlug = (text: string): string => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ import { useDebounceLayerLegendLayers } from '@/core/components/legend/hooks/use
import { LayersList } from './layers-list';
import { AddNewLayer } from './add-new-layer/add-new-layer';
import { logger } from '@/core/utils/logger';
import { TypeLegendLayer } from '@/core/components/layers/types';

interface LeftPanelProps {
showLayerDetailsPanel: (layer: TypeLegendLayer) => void;
showLayerDetailsPanel: (layerId: string) => void;
isLayoutEnlarged: boolean;
}

Expand Down
Loading

0 comments on commit e1a7e79

Please sign in to comment.