diff --git a/packages/base/src/annotations/components/Annotation.tsx b/packages/base/src/annotations/components/Annotation.tsx index f3aa8196d..54989ceb3 100644 --- a/packages/base/src/annotations/components/Annotation.tsx +++ b/packages/base/src/annotations/components/Annotation.tsx @@ -19,37 +19,32 @@ export interface IAnnotationProps { children?: JSX.Element[] | JSX.Element; } -const Annotation: React.FC = ({ - itemId, - annotationModel, - rightPanelModel, - children, -}) => { +const Annotation: React.FC = props => { const [messageContent, setMessageContent] = useState(''); const [jgisModel, setJgisModel] = useState( - rightPanelModel?.jGISModel, + props.rightPanelModel?.jGISModel, ); - const annotation = annotationModel.getAnnotation(itemId); + const annotation = props.annotationModel.getAnnotation(props.itemId); const contents = useMemo(() => annotation?.contents ?? [], [annotation]); /** * Update the model when it changes. */ - rightPanelModel?.documentChanged.connect((_, widget) => { + props.rightPanelModel?.documentChanged.connect((_, widget) => { setJgisModel(widget?.model); }); const handleSubmit = () => { - annotationModel.addContent(itemId, messageContent); + props.annotationModel.addContent(props.itemId, messageContent); setMessageContent(''); }; const handleDelete = async () => { // If the annotation has no content // we remove it right away without prompting - if (!annotationModel.getAnnotation(itemId)?.contents.length) { - return annotationModel.removeAnnotation(itemId); + if (!props.annotationModel.getAnnotation(props.itemId)?.contents.length) { + return props.annotationModel.removeAnnotation(props.itemId); } const result = await showDialog({ @@ -59,24 +54,24 @@ const Annotation: React.FC = ({ }); if (result.button.accept) { - annotationModel.removeAnnotation(itemId); + props.annotationModel.removeAnnotation(props.itemId); } }; const centerOnAnnotation = () => { - jgisModel?.centerOnPosition(itemId); + jgisModel?.centerOnPosition(props.itemId); }; return (
- {children} + {props.children}
{contents.map(content => { return ( ); })} @@ -98,7 +93,7 @@ const Annotation: React.FC = ({ - {rightPanelModel && ( + {props.rightPanelModel && (
); diff --git a/packages/base/src/dialogs/symbology/symbologyDialog.tsx b/packages/base/src/dialogs/symbology/symbologyDialog.tsx index 4a3bee9cf..1d93acd84 100644 --- a/packages/base/src/dialogs/symbology/symbologyDialog.tsx +++ b/packages/base/src/dialogs/symbology/symbologyDialog.tsx @@ -39,12 +39,7 @@ export interface IStopRow { output: number | number[]; } -const SymbologyDialog: React.FC = ({ - model, - state, - okSignalPromise, - cancel, -}) => { +const SymbologyDialog: React.FC = props => { const [selectedLayer, setSelectedLayer] = useState(null); const [componentToRender, setComponentToRender] = useState(null); @@ -52,11 +47,11 @@ const SymbologyDialog: React.FC = ({ useEffect(() => { const handleClientStateChanged = () => { - if (!model.localState?.selected?.value) { + if (!props.model.localState?.selected?.value) { return; } - const currentLayer = Object.keys(model.localState.selected.value)[0]; + const currentLayer = Object.keys(props.model.localState.selected.value)[0]; setSelectedLayer(currentLayer); }; @@ -64,10 +59,10 @@ const SymbologyDialog: React.FC = ({ // Initial state handleClientStateChanged(); - model.clientStateChanged.connect(handleClientStateChanged); + props.model.clientStateChanged.connect(handleClientStateChanged); return () => { - model.clientStateChanged.disconnect(handleClientStateChanged); + props.model.clientStateChanged.disconnect(handleClientStateChanged); }; }, []); @@ -76,7 +71,7 @@ const SymbologyDialog: React.FC = ({ return; } - const layer = model.getLayer(selectedLayer); + const layer = props.model.getLayer(selectedLayer); if (!layer) { return; @@ -89,10 +84,10 @@ const SymbologyDialog: React.FC = ({ case 'HeatmapLayer': LayerSymbology = ( ); @@ -100,10 +95,10 @@ const SymbologyDialog: React.FC = ({ case 'WebGlLayer': LayerSymbology = ( ); diff --git a/packages/base/src/dialogs/symbology/tiff_layer/TiffRendering.tsx b/packages/base/src/dialogs/symbology/tiff_layer/TiffRendering.tsx index 3c9cefd23..fc132d3fc 100644 --- a/packages/base/src/dialogs/symbology/tiff_layer/TiffRendering.tsx +++ b/packages/base/src/dialogs/symbology/tiff_layer/TiffRendering.tsx @@ -4,24 +4,21 @@ import { ISymbologyDialogProps } from '@/src/dialogs/symbology/symbologyDialog'; import MultibandColor from './types/MultibandColor'; import SingleBandPseudoColor from './types/SingleBandPseudoColor'; -const TiffRendering: React.FC = ({ - model, - state, - okSignalPromise, - cancel, - layerId, -}) => { +const TiffRendering: React.FC = props => { const renderTypes = ['Singleband Pseudocolor', 'Multiband Color']; const [selectedRenderType, setSelectedRenderType] = useState(); const [componentToRender, setComponentToRender] = useState(null); let RenderComponent; - if (!layerId) { + if (!props.layerId) { return; } useEffect(() => { - const layer = model.getLayer(layerId); + if (!props.layerId) { + throw new Error('Layer ID is required'); + } + const layer = props.model.getLayer(props.layerId); const renderType = layer?.parameters?.symbologyState?.renderType; setSelectedRenderType(renderType ?? 'Singleband Pseudocolor'); }, []); @@ -35,22 +32,22 @@ const TiffRendering: React.FC = ({ case 'Singleband Pseudocolor': RenderComponent = ( ); break; case 'Multiband Color': RenderComponent = ( ); break; diff --git a/packages/base/src/dialogs/symbology/tiff_layer/components/BandRow.tsx b/packages/base/src/dialogs/symbology/tiff_layer/components/BandRow.tsx index 62036c54b..dc7cd473e 100644 --- a/packages/base/src/dialogs/symbology/tiff_layer/components/BandRow.tsx +++ b/packages/base/src/dialogs/symbology/tiff_layer/components/BandRow.tsx @@ -22,17 +22,9 @@ interface IBandRowProps { * @param setBandRows Function to update band rows in parent * @param isMultibandColor Used to hide min/max input and add 'Unset' option to drop down menu for MultiBand symbology */ -const BandRow: React.FC = ({ - label, - index, - bandRow, - bandRows, - setSelectedBand, - setBandRows, - isMultibandColor, -}) => { - const [minValue, setMinValue] = useState(bandRow?.stats.minimum); - const [maxValue, setMaxValue] = useState(bandRow?.stats.maximum); +const BandRow: React.FC = props => { + const [minValue, setMinValue] = useState(props.bandRow?.stats.minimum); + const [maxValue, setMaxValue] = useState(props.bandRow?.stats.maximum); const handleMinValueChange = (event: { target: { value: string | number }; @@ -49,27 +41,27 @@ const BandRow: React.FC = ({ }; const setNewBands = () => { - const newBandRows = [...bandRows]; - newBandRows[index].stats.minimum = minValue; - newBandRows[index].stats.maximum = maxValue; - setBandRows(newBandRows); + const newBandRows = [...props.bandRows]; + newBandRows[props.index].stats.minimum = minValue; + newBandRows[props.index].stats.maximum = maxValue; + props.setBandRows(newBandRows); }; return ( <>
- +
- {isMultibandColor ? null : ( + {props.isMultibandColor ? null : (
= ({ - model, - okSignalPromise, - cancel, - layerId, -}) => { - if (!layerId) { +const MultibandColor: React.FC = props => { + if (!props.layerId) { return; } - const layer = model.getLayer(layerId); + const layer = props.model.getLayer(props.layerId); if (!layer?.parameters) { return; } - const { bandRows, setBandRows, loading } = useGetBandInfo(model, layer); + const { bandRows, setBandRows, loading } = useGetBandInfo(props.model, layer); const [selectedBands, setSelectedBands] = useState({ red: 1, @@ -50,12 +45,12 @@ const MultibandColor: React.FC = ({ useEffect(() => { populateOptions(); - okSignalPromise.promise.then(okSignal => { + props.okSignalPromise.promise.then(okSignal => { okSignal.connect(handleOk); }); return () => { - okSignalPromise.promise.then(okSignal => { + props.okSignalPromise.promise.then(okSignal => { okSignal.disconnect(handleOk, this); }); }; @@ -88,6 +83,9 @@ const MultibandColor: React.FC = ({ const handleOk = () => { // Update layer + if (!props.layerId) { + throw new Error('layerId is required for MultibandColor component'); + } if (!layer.parameters) { return; } @@ -119,8 +117,8 @@ const MultibandColor: React.FC = ({ layer.parameters.color = colorExpr; layer.type = 'WebGlLayer'; - model.sharedModel.updateLayer(layerId, layer); - cancel(); + props.model.sharedModel.updateLayer(props.layerId, layer); + props.cancel(); }; return ( diff --git a/packages/base/src/dialogs/symbology/tiff_layer/types/SingleBandPseudoColor.tsx b/packages/base/src/dialogs/symbology/tiff_layer/types/SingleBandPseudoColor.tsx index f483ca164..b4ccfbac7 100644 --- a/packages/base/src/dialogs/symbology/tiff_layer/types/SingleBandPseudoColor.tsx +++ b/packages/base/src/dialogs/symbology/tiff_layer/types/SingleBandPseudoColor.tsx @@ -23,16 +23,11 @@ import { GlobalStateDbManager } from '@/src/store'; export type InterpolationType = 'discrete' | 'linear' | 'exact'; -const SingleBandPseudoColor: React.FC = ({ - model, - okSignalPromise, - cancel, - layerId, -}) => { - if (!layerId) { +const SingleBandPseudoColor: React.FC = props => { + if (!props.layerId) { return; } - const layer = model.getLayer(layerId); + const layer = props.model.getLayer(props.layerId); if (!layer?.parameters) { return; } @@ -42,7 +37,7 @@ const SingleBandPseudoColor: React.FC = ({ const stateDb = GlobalStateDbManager.getInstance().getStateDb(); - const { bandRows, setBandRows, loading } = useGetBandInfo(model, layer); + const { bandRows, setBandRows, loading } = useGetBandInfo(props.model, layer); const [layerState, setLayerState] = useState(); const [selectedBand, setSelectedBand] = useState(1); @@ -62,12 +57,12 @@ const SingleBandPseudoColor: React.FC = ({ useEffect(() => { populateOptions(); - okSignalPromise.promise.then(okSignal => { + props.okSignalPromise.promise.then(okSignal => { okSignal.connect(handleOk); }); return () => { - okSignalPromise.promise.then(okSignal => { + props.okSignalPromise.promise.then(okSignal => { okSignal.disconnect(handleOk, this); }); }; @@ -87,7 +82,7 @@ const SingleBandPseudoColor: React.FC = ({ const populateOptions = async () => { const layerState = (await stateDb?.fetch( - `jupytergis:${layerId}`, + `jupytergis:${props.layerId}`, )) as ReadonlyJSONObject; setLayerState(layerState); @@ -158,13 +153,16 @@ const SingleBandPseudoColor: React.FC = ({ }; const handleOk = () => { + if (!props.layerId) { + throw new Error('layerId is required for SingleBandPseudoColor component'); + } // Update source const bandRow = bandRowsRef.current[selectedBand - 1]; if (!bandRow) { return; } const sourceId = layer.parameters?.source; - const source = model.getSource(sourceId); + const source = props.model.getSource(sourceId); if (!source || !source.parameters) { return; @@ -178,7 +176,7 @@ const SingleBandPseudoColor: React.FC = ({ source.parameters.urls[0] = sourceInfo; - model.sharedModel.updateSource(sourceId, source); + props.model.sharedModel.updateSource(sourceId, source); // Update layer if (!layer.parameters) { @@ -260,8 +258,8 @@ const SingleBandPseudoColor: React.FC = ({ layer.parameters.color = colorExpr; layer.type = 'WebGlLayer'; - model.sharedModel.updateLayer(layerId, layer); - cancel(); + props.model.sharedModel.updateLayer(props.layerId, layer); + props.cancel(); }; const addStopRow = () => { @@ -297,7 +295,7 @@ const SingleBandPseudoColor: React.FC = ({ let stops: number[] = []; const currentBand = bandRows[selectedBand - 1]; - const source = model.getSource(layer?.parameters?.source); + const source = props.model.getSource(layer?.parameters?.source); const sourceInfo = source?.parameters?.urls[0]; const nClasses = selectedMode === 'continuous' ? 52 : +numberOfShades; diff --git a/packages/base/src/dialogs/symbology/vector_layer/VectorRendering.tsx b/packages/base/src/dialogs/symbology/vector_layer/VectorRendering.tsx index 666401ec2..480f5eba2 100644 --- a/packages/base/src/dialogs/symbology/vector_layer/VectorRendering.tsx +++ b/packages/base/src/dialogs/symbology/vector_layer/VectorRendering.tsx @@ -101,29 +101,23 @@ const useLayerRenderType = ( setSelectedRenderType(renderType); }, []); -const VectorRendering: React.FC = ({ - model, - state, - okSignalPromise, - cancel, - layerId, -}) => { +const VectorRendering: React.FC = props => { const [selectedRenderType, setSelectedRenderType] = useState< VectorRenderType | undefined >(); const [symbologyTab, setSymbologyTab] = useState('color'); - if (!layerId) { + if (!props.layerId) { return; } - const layer = model.getLayer(layerId); + const layer = props.model.getLayer(props.layerId); if (!layer?.parameters) { return; } const { featureProperties, isLoading: featuresLoading } = useGetProperties({ - layerId, - model: model, + layerId: props.layerId, + model: props.model, }); useLayerRenderType(layer, setSelectedRenderType); @@ -186,11 +180,11 @@ const VectorRendering: React.FC = ({
void; } -const ValueSelect: React.FC = ({ - featureProperties, - selectedValue, - setSelectedValue, -}) => { +const ValueSelect: React.FC = props => { return (
= ({ modeOptions={[]} classifyFunc={buildColorInfoFromClassification} showModeRow={false} - showRampSelector={symbologyTab === 'color'} + showRampSelector={props.symbologyTab === 'color'} /> = ({ - model, - state, - okSignalPromise, - cancel, - layerId, - symbologyTab, - selectableAttributesAndValues, -}) => { +const Graduated: React.FC = props => { const modeOptions = [ 'quantile', 'equal interval', @@ -55,10 +47,10 @@ const Graduated: React.FC = ({ const colorManualStyleRef = useRef(colorManualStyle); const radiusManualStyleRef = useRef(radiusManualStyle); - if (!layerId) { + if (!props.layerId) { return; } - const layer = model.getLayer(layerId); + const layer = props.model.getLayer(props.layerId); if (!layer?.parameters) { return; } @@ -66,12 +58,12 @@ const Graduated: React.FC = ({ useEffect(() => { updateStopRowsBasedOnLayer(); - okSignalPromise.promise.then(okSignal => { + props.okSignalPromise.promise.then(okSignal => { okSignal.connect(handleOk, this); }); return () => { - okSignalPromise.promise.then(okSignal => { + props.okSignalPromise.promise.then(okSignal => { okSignal.disconnect(handleOk, this); }); }; @@ -107,19 +99,19 @@ const Graduated: React.FC = ({ radius: layer.parameters.color['circle-radius'] || 5, }); } - }, [layerId]); + }, [props.layerId]); useEffect(() => { colorStopRowsRef.current = colorStopRows; radiusStopRowsRef.current = radiusStopRows; selectableAttributeRef.current = selectedAttribute; - symbologyTabRef.current = symbologyTab; + symbologyTabRef.current = props.symbologyTab; colorRampOptionsRef.current = colorRampOptions; }, [ colorStopRows, radiusStopRows, selectedAttribute, - symbologyTab, + props.symbologyTab, colorRampOptions, ]); @@ -132,10 +124,10 @@ const Graduated: React.FC = ({ const layerParams = layer.parameters as IVectorLayer; const attribute = layerParams.symbologyState?.value ?? - Object.keys(selectableAttributesAndValues)[0]; + Object.keys(props.selectableAttributesAndValues)[0]; setSelectedAttribute(attribute); - }, [selectableAttributesAndValues]); + }, [props.selectableAttributesAndValues]); const updateStopRowsBasedOnLayer = () => { if (!layer) { @@ -147,6 +139,9 @@ const Graduated: React.FC = ({ }; const handleOk = () => { + if (!props.layerId) { + throw new Error('layerId is required for Graduated component'); + } if (!layer.parameters) { return; } @@ -206,8 +201,8 @@ const Graduated: React.FC = ({ layer.type = 'VectorLayer'; } - model.sharedModel.updateLayer(layerId, layer); - cancel(); + props.model.sharedModel.updateLayer(props.layerId, layer); + props.cancel(); }; const buildColorInfoFromClassification = ( @@ -223,7 +218,7 @@ const Graduated: React.FC = ({ let stops; - const values = Array.from(selectableAttributesAndValues[selectedAttribute]); + const values = Array.from(props.selectableAttributesAndValues[selectedAttribute]); switch (selectedMode) { case 'quantile': @@ -262,11 +257,11 @@ const Graduated: React.FC = ({ } const stopOutputPairs = - symbologyTab === 'radius' + props.symbologyTab === 'radius' ? stops.map(v => ({ stop: v, output: v })) : Utils.getValueColorPairs(stops, selectedRamp, +numberOfShades); - if (symbologyTab === 'radius') { + if (props.symbologyTab === 'radius') { setRadiusStopRows(stopOutputPairs); } else { setColorStopRows(stopOutputPairs); @@ -274,6 +269,9 @@ const Graduated: React.FC = ({ }; const handleReset = (method: string) => { + if (!props.layerId) { + throw new Error('layerId is required for Graduated component'); + } if (!layer?.parameters) { return; } @@ -294,11 +292,11 @@ const Graduated: React.FC = ({ } layer.parameters.color = newStyle; - model.sharedModel.updateLayer(layerId, layer); + props.model.sharedModel.updateLayer(props.layerId, layer); }; const body = (() => { - if (Object.keys(selectableAttributesAndValues)?.length === 0) { + if (Object.keys(props.selectableAttributesAndValues)?.length === 0) { return (

This symbology type is not available; no attributes contain numeric @@ -309,12 +307,12 @@ const Graduated: React.FC = ({ return ( <>

- {symbologyTab === 'color' && ( + {props.symbologyTab === 'color' && ( <>
@@ -361,7 +359,7 @@ const Graduated: React.FC = ({
)} - {symbologyTab === 'radius' && ( + {props.symbologyTab === 'radius' && (
= ({ modeOptions={modeOptions} classifyFunc={buildColorInfoFromClassification} showModeRow={true} - showRampSelector={symbologyTab === 'color'} + showRampSelector={props.symbologyTab === 'color'} /> diff --git a/packages/base/src/dialogs/symbology/vector_layer/types/Heatmap.tsx b/packages/base/src/dialogs/symbology/vector_layer/types/Heatmap.tsx index 6a9f378d9..525358bf3 100644 --- a/packages/base/src/dialogs/symbology/vector_layer/types/Heatmap.tsx +++ b/packages/base/src/dialogs/symbology/vector_layer/types/Heatmap.tsx @@ -4,17 +4,11 @@ import React, { useEffect, useRef, useState } from 'react'; import CanvasSelectComponent from '@/src/dialogs/symbology/components/color_ramp/CanvasSelectComponent'; import { ISymbologyDialogProps } from '@/src/dialogs/symbology/symbologyDialog'; -const Heatmap: React.FC = ({ - model, - state, - okSignalPromise, - cancel, - layerId, -}) => { - if (!layerId) { +const Heatmap: React.FC = props => { + if (!props.layerId) { return; } - const layer = model.getLayer(layerId); + const layer = props.model.getLayer(props.layerId); if (!layer?.parameters) { return; } @@ -32,12 +26,12 @@ const Heatmap: React.FC = ({ useEffect(() => { populateOptions(); - okSignalPromise.promise.then(okSignal => { + props.okSignalPromise.promise.then(okSignal => { okSignal.connect(handleOk, this); }); return () => { - okSignalPromise.promise.then(okSignal => { + props.okSignalPromise.promise.then(okSignal => { okSignal.disconnect(handleOk, this); }); }; @@ -59,6 +53,9 @@ const Heatmap: React.FC = ({ }; const handleOk = () => { + if (!props.layerId) { + throw new Error('Layer ID is required for symbology update'); + } if (!layer.parameters) { return; } @@ -80,9 +77,9 @@ const Heatmap: React.FC = ({ layer.parameters.radius = heatmapOptionsRef.current.radius; layer.type = 'HeatmapLayer'; - model.sharedModel.updateLayer(layerId, layer); + props.model.sharedModel.updateLayer(props.layerId, layer); - cancel(); + props.cancel(); }; return ( diff --git a/packages/base/src/dialogs/symbology/vector_layer/types/SimpleSymbol.tsx b/packages/base/src/dialogs/symbology/vector_layer/types/SimpleSymbol.tsx index 5e6b06ec8..90acf48f8 100644 --- a/packages/base/src/dialogs/symbology/vector_layer/types/SimpleSymbol.tsx +++ b/packages/base/src/dialogs/symbology/vector_layer/types/SimpleSymbol.tsx @@ -4,14 +4,7 @@ import React, { useEffect, useRef, useState } from 'react'; import { ISymbologyTabbedDialogProps } from '@/src/dialogs/symbology/symbologyDialog'; import { IParsedStyle, parseColor } from '@/src/tools'; -const SimpleSymbol: React.FC = ({ - model, - state, - okSignalPromise, - cancel, - layerId, - symbologyTab, -}) => { +const SimpleSymbol: React.FC = props => { const styleRef = useRef(); const [style, setStyle] = useState({ @@ -26,10 +19,10 @@ const SimpleSymbol: React.FC = ({ const joinStyleOptions = ['bevel', 'round', 'miter']; const capStyleOptions = ['butt', 'round', 'square']; - if (!layerId) { + if (!props.layerId) { return; } - const layer = model.getLayer(layerId); + const layer = props.model.getLayer(props.layerId); if (!layer) { return; } @@ -57,12 +50,12 @@ const SimpleSymbol: React.FC = ({ }; initStyle(); - okSignalPromise.promise.then(okSignal => { + props.okSignalPromise.promise.then(okSignal => { okSignal.connect(handleOk, this); }); return () => { - okSignalPromise.promise.then(okSignal => { + props.okSignalPromise.promise.then(okSignal => { okSignal.disconnect(handleOk, this); }); }; @@ -73,6 +66,9 @@ const SimpleSymbol: React.FC = ({ }, [style]); const handleOk = () => { + if (!props.layerId) { + throw new Error('Layer ID is required for symbology update'); + } if (!layer.parameters) { return; } @@ -101,8 +97,8 @@ const SimpleSymbol: React.FC = ({ layer.type = 'VectorLayer'; } - model.sharedModel.updateLayer(layerId, layer); - cancel(); + props.model.sharedModel.updateLayer(props.layerId, layer); + props.cancel(); }; const renderColorTab = () => ( @@ -211,7 +207,7 @@ const SimpleSymbol: React.FC = ({ return (

Color all features the same way.

- {symbologyTab === 'color' ? renderColorTab() : renderRadiusTab()} + {props.symbologyTab === 'color' ? renderColorTab() : renderRadiusTab()}
); }; diff --git a/packages/base/src/mainview/CollaboratorPointers.tsx b/packages/base/src/mainview/CollaboratorPointers.tsx index cd8cec206..1cb5febe8 100644 --- a/packages/base/src/mainview/CollaboratorPointers.tsx +++ b/packages/base/src/mainview/CollaboratorPointers.tsx @@ -18,15 +18,13 @@ export type ClientPointer = { lonLat: { latitude: number; longitude: number }; }; -const CollaboratorPointers: React.FC = ({ - clients, -}) => { +const CollaboratorPointers: React.FC = props => { const [isOpen, setIsOpen] = useState(false); return ( <> - {clients && - Object.values(clients).map(client => ( + {props.clients && + Object.values(props.clients).map(client => (
= ({ - remoteUser, -}) => { - return remoteUser?.display_name ? ( +export const FollowIndicator: React.FC = props => { + return props.remoteUser?.display_name ? (
- {`Following ${remoteUser.display_name}`} + {`Following ${props.remoteUser.display_name}`}
) : null; }; diff --git a/packages/base/src/mainview/TemporalSlider.tsx b/packages/base/src/mainview/TemporalSlider.tsx index 771ad1817..3251e2440 100644 --- a/packages/base/src/mainview/TemporalSlider.tsx +++ b/packages/base/src/mainview/TemporalSlider.tsx @@ -53,10 +53,7 @@ const stepMap = { year: millisecondsInDay * daysInYear, }; -const TemporalSlider: React.FC = ({ - model, - filterStates, -}) => { +const TemporalSlider: React.FC = props => { const [layerId, setLayerId] = useState(''); const [selectedFeature, setSelectedFeature] = useState(''); const [range, setRange] = useState({ start: 0, end: 1 }); // min/max of current range being displayed @@ -71,16 +68,16 @@ const TemporalSlider: React.FC = ({ const layerIdRef = useRef(''); const intervalRef = useRef(null); - const { featureProperties } = useGetProperties({ layerId, model }); + const { featureProperties } = useGetProperties({ layerId, model: props.model }); useEffect(() => { // This is for when the selected layer changes const handleClientStateChanged = () => { - if (!model.localState?.selected?.value) { + if (!props.model.localState?.selected?.value) { return; } - const selectedLayerId = Object.keys(model.localState.selected.value)[0]; + const selectedLayerId = Object.keys(props.model.localState.selected.value)[0]; // reset if (selectedLayerId !== layerIdRef.current) { @@ -112,19 +109,19 @@ const TemporalSlider: React.FC = ({ Object.keys(newValue).length === 0 || newValue.type !== oldValue.type ) { - model.toggleTemporalController(); + props.model.toggleTemporalController(); } }; // Initial state handleClientStateChanged(); - model.clientStateChanged.connect(handleClientStateChanged); - model.sharedLayersChanged.connect(handleLayerChange); + props.model.clientStateChanged.connect(handleClientStateChanged); + props.model.sharedLayersChanged.connect(handleLayerChange); return () => { - model.clientStateChanged.disconnect(handleClientStateChanged); - model.sharedLayersChanged.disconnect(handleLayerChange); + props.model.clientStateChanged.disconnect(handleClientStateChanged); + props.model.sharedLayersChanged.disconnect(handleLayerChange); removeFilter(); if (intervalRef.current) { clearInterval(intervalRef.current); @@ -167,7 +164,7 @@ const TemporalSlider: React.FC = ({ } // if we have state then remove the ms from the converted feature name - const currentState = filterStates[layerId]; + const currentState = props.filterStates[layerId]; const currentFeature = currentState?.feature.slice(0, -2); setValidFeatures(results); setSelectedFeature(currentFeature ?? results[0]); @@ -208,7 +205,7 @@ const TemporalSlider: React.FC = ({ ); //using filter item as a state object to restore prev values - const currentState = filterStates[layerId]; + const currentState = props.filterStates[layerId]; const step = Object.values(filteredSteps).slice(-1)[0] ?? stepMap.millisecond; @@ -220,12 +217,12 @@ const TemporalSlider: React.FC = ({ end: currentState?.betweenMax ?? min + step, }); - model.addFeatureAsMs(layerId, selectedFeature); + props.model.addFeatureAsMs(layerId, selectedFeature); }, [selectedFeature]); // minMax needs to be set before current value so the slider displays correctly useEffect(() => { - const currentState = filterStates[layerId]; + const currentState = props.filterStates[layerId]; setCurrentValue( typeof currentState?.value === 'number' ? currentState.value : minMax.min, @@ -267,7 +264,7 @@ const TemporalSlider: React.FC = ({ betweenMax: value + step, }; - const layer = model.getLayer(layerId); + const layer = props.model.getLayer(layerId); if (!layer) { return; } @@ -293,11 +290,11 @@ const TemporalSlider: React.FC = ({ // Apply the updated filters to the layer layer.filters = { logicalOp, appliedFilters }; - model.triggerLayerUpdate(layerId, layer); + props.model.triggerLayerUpdate(layerId, layer); }; const removeFilter = () => { - const layer = model.getLayer(layerIdRef.current); + const layer = props.model.getLayer(layerIdRef.current); if (!layer) { return; } @@ -318,7 +315,7 @@ const TemporalSlider: React.FC = ({ // Apply the updated filters to the layer layer.filters = { logicalOp, appliedFilters }; - model.triggerLayerUpdate(layerIdRef.current, layer); + props.model.triggerLayerUpdate(layerIdRef.current, layer); }; const playAnimation = () => { diff --git a/packages/base/src/panelview/components/filter-panel/FilterRow.tsx b/packages/base/src/panelview/components/filter-panel/FilterRow.tsx index 0362b0761..a04fb8117 100644 --- a/packages/base/src/panelview/components/filter-panel/FilterRow.tsx +++ b/packages/base/src/panelview/components/filter-panel/FilterRow.tsx @@ -9,38 +9,38 @@ const FilterRow: React.FC<{ filterRows: any; setFilterRows: any; deleteRow: () => void; -}> = ({ index, features, filterRows, setFilterRows, deleteRow }) => { +}> = props => { const operators = ['==', '!=', '>', '<', '>=', '<=']; const [sortedFeatures, setSortedFeatures] = useState<{ [key: string]: any }>( {}, ); const [selectedFeature, setSelectedFeature] = useState( - filterRows[index].feature || Object.keys(features)[0], + props.filterRows[props.index].feature || Object.keys(props.features)[0], ); // Ensure selected feature matches filter rows and proper values are displayed useEffect(() => { - setSelectedFeature(filterRows[index].feature); - }, [filterRows]); + setSelectedFeature(props.filterRows[props.index].feature); + }, [props.filterRows]); useEffect(() => { - const sortedKeys = Object.keys(features).sort(); + const sortedKeys = Object.keys(props.features).sort(); const sortedResult: { [key: string]: any } = {}; for (const key of sortedKeys) { // Convert each Set to a sorted array - const sortedArray = Array.from(features[key]).sort(); + const sortedArray = Array.from(props.features[key]).sort(); sortedResult[key] = sortedArray; } setSortedFeatures(sortedResult); - }, [features]); + }, [props.features]); // Update the value when a new feature is selected useEffect(() => { const valueSelect = document.getElementById( - `jp-gis-value-select-${index}`, + `jp-gis-value-select-${props.index}`, ) as HTMLSelectElement; if (!valueSelect) { @@ -52,26 +52,26 @@ const FilterRow: React.FC<{ }, [selectedFeature]); const onValueChange = (value: string | number) => { - const newFilters = [...filterRows]; + const newFilters = [...props.filterRows]; const isNum = typeof sortedFeatures[selectedFeature][0] === 'number'; - newFilters[index].value = isNum ? +value : value; - setFilterRows(newFilters); + newFilters[props.index].value = isNum ? +value : value; + props.setFilterRows(newFilters); }; const handleKeyChange = (event: React.ChangeEvent) => { - const newFilters = [...filterRows]; - newFilters[index].feature = event.target.value; + const newFilters = [...props.filterRows]; + newFilters[props.index].feature = event.target.value; setSelectedFeature(event.target.value); - setFilterRows(newFilters); + props.setFilterRows(newFilters); }; const handleOperatorChange = ( event: React.ChangeEvent, ) => { - const newFilters = [...filterRows]; - newFilters[index].operator = event.target.value; - setFilterRows(newFilters); + const newFilters = [...props.filterRows]; + newFilters[props.index].operator = event.target.value; + props.setFilterRows(newFilters); }; const handleValueChange = (event: React.ChangeEvent) => { @@ -81,7 +81,7 @@ const FilterRow: React.FC<{ return (
); diff --git a/packages/base/src/panelview/components/identify-panel/IdentifyPanel.tsx b/packages/base/src/panelview/components/identify-panel/IdentifyPanel.tsx index 842f1111f..6750a9f75 100644 --- a/packages/base/src/panelview/components/identify-panel/IdentifyPanel.tsx +++ b/packages/base/src/panelview/components/identify-panel/IdentifyPanel.tsx @@ -50,10 +50,7 @@ interface IIdentifyComponentProps { tracker: IJupyterGISTracker; } -const IdentifyPanelComponent: React.FC = ({ - controlPanelModel, - tracker, -}) => { +const IdentifyPanelComponent: React.FC = props => { const [widgetId, setWidgetId] = useState(''); const [features, setFeatures] = useState>(); const [visibleFeatures, setVisibleFeatures] = useState>({ @@ -61,36 +58,36 @@ const IdentifyPanelComponent: React.FC = ({ }); const [remoteUser, setRemoteUser] = useState(null); const [jgisModel, setJgisModel] = useState( - controlPanelModel?.jGISModel, + props.controlPanelModel?.jGISModel, ); const featuresRef = useRef(features); /** * Update the model when it changes. */ - controlPanelModel?.documentChanged.connect((_, widget) => { + props.controlPanelModel?.documentChanged.connect((_, widget) => { setJgisModel(widget?.model); }); // Reset state values when current widget changes useEffect(() => { const handleCurrentChanged = () => { - if (tracker.currentWidget?.id === widgetId) { + if (props.tracker.currentWidget?.id === widgetId) { return; } - if (tracker.currentWidget) { - setWidgetId(tracker.currentWidget.id); + if (props.tracker.currentWidget) { + setWidgetId(props.tracker.currentWidget.id); } setFeatures({}); setVisibleFeatures({ 0: true }); }; - tracker.currentChanged.connect(handleCurrentChanged); + props.tracker.currentChanged.connect(handleCurrentChanged); return () => { - tracker.currentChanged.disconnect(handleCurrentChanged); + props.tracker.currentChanged.disconnect(handleCurrentChanged); }; - }, []); + }, [props.tracker]); useEffect(() => { featuresRef.current = features; diff --git a/packages/base/src/statusbar/StatusBar.tsx b/packages/base/src/statusbar/StatusBar.tsx index 2563dd49c..d3e5524b0 100644 --- a/packages/base/src/statusbar/StatusBar.tsx +++ b/packages/base/src/statusbar/StatusBar.tsx @@ -16,17 +16,12 @@ interface IStatusBarProps { projection?: { code: string; units: string }; scale: number; } -const StatusBar: React.FC = ({ - jgisModel, - loading, - projection, - scale, -}) => { +const StatusBar: React.FC = props => { const [coords, setCoords] = useState({ x: 0, y: 0 }); useEffect(() => { const handleClientStateChanged = () => { - const pointer = jgisModel?.localState?.pointer?.value; + const pointer = props.jgisModel?.localState?.pointer?.value; if (!pointer) { return; @@ -35,16 +30,16 @@ const StatusBar: React.FC = ({ setCoords({ x: pointer?.coordinates.x, y: pointer?.coordinates.y }); }; - jgisModel.clientStateChanged.connect(handleClientStateChanged); + props.jgisModel.clientStateChanged.connect(handleClientStateChanged); return () => { - jgisModel.clientStateChanged.disconnect(handleClientStateChanged); + props.jgisModel.clientStateChanged.disconnect(handleClientStateChanged); }; - }, [jgisModel]); + }, [props.jgisModel]); return (
- {loading && ( + {props.loading && (
@@ -61,13 +56,13 @@ const StatusBar: React.FC = ({
{' '} - Scale: 1: {Math.trunc(scale)} + Scale: 1: {Math.trunc(props.scale)}
{' '} - {projection?.code ?? null} + {props.projection?.code ?? null}
-
Units: {projection?.units}
+
Units: {props.projection?.units}
); };