From f7acfec80e0cc13e75f3bb33d39410e0a3314f72 Mon Sep 17 00:00:00 2001 From: popovspiridon99 Date: Tue, 23 Dec 2025 16:06:55 +0900 Subject: [PATCH] map undo redo --- client/src/components/map/MapComponent.tsx | 31 +++++++- client/src/components/map/MapMode.tsx | 61 ++++++++++++++- .../components/map/MapToolbar/MapToolbar.tsx | 44 ++++++++++- client/src/components/map/mapUtils.ts | 50 +++++++++--- client/src/store/map.ts | 77 +++++++++++++++++-- 5 files changed, 241 insertions(+), 22 deletions(-) diff --git a/client/src/components/map/MapComponent.tsx b/client/src/components/map/MapComponent.tsx index e3e47c9..1fd1803 100644 --- a/client/src/components/map/MapComponent.tsx +++ b/client/src/components/map/MapComponent.tsx @@ -17,7 +17,7 @@ import { IconBoxPadding, IconChevronLeft, } from '@tabler/icons-react' import axios from 'axios' import MapToolbar from './MapToolbar/MapToolbar' import MapStatusbar from './MapStatusbar/MapStatusbar' -import { setAlignMode, setTypeRoles, useMapStore, setMapLabel, } from '../../store/map' +import { setAlignMode, setTypeRoles, useMapStore, setMapLabel, getChanges, } from '../../store/map' import ObjectTree from '../Tree/ObjectTree' import { setSelectedDistrict, setSelectedRegion, setSelectedYear, useObjectsStore } from '../../store/objects' import ObjectParameters from './ObjectParameters/ObjectParameters' @@ -53,6 +53,7 @@ const MapComponent = ({ // Store const { selectedYear, currentObjectId, selectedRegion, selectedDistrict } = useObjectsStore().id[id] const { + changes, currentChange, mode, map, currentTool, alignMode, satMapsProvider, selectedObjectType, measureDraw, draw, snap, translate, drawingLayerSource, @@ -478,6 +479,34 @@ const MapComponent = ({ } }, [selectedYear]) + useEffect(() => { + if (changes) { + console.log(changes) + } + }, [changes]) + + useEffect(() => { + if (currentChange) { + const figures = figuresLayer.getSource()?.getFeatures() + const lines = linesLayer.getSource()?.getFeatures() + + const changes = getChanges(id).get(currentChange) + + if (figures && lines) { + changes.map((f: { object_id: string, year: number, type: 'figure' | 'line', feature: Feature }) => { + const geometry = new GeoJSON() + + const feature = geometry.readFeature(f.feature) as Feature + + if (f.type === 'figure') { + figures.find(fig => fig.getProperties()['object_id'] === f.object_id && fig.getProperties()['year'] === f.year)?.setGeometry(feature.getGeometry()) + } else if (f.type === 'line') { + lines.find(l => l.getProperties()['object_id'] === f.object_id && l.getProperties()['year'] === f.year)?.setGeometry(feature.getGeometry()) + } + }) + } + } + }, [currentChange]) return (
diff --git a/client/src/components/map/MapMode.tsx b/client/src/components/map/MapMode.tsx index 59b3e6a..31653a7 100644 --- a/client/src/components/map/MapMode.tsx +++ b/client/src/components/map/MapMode.tsx @@ -1,13 +1,14 @@ -import { Mode, setMode, useMapStore } from '../../store/map' +import { cleanChanges, getChanges, Mode, setMode, useMapStore } from '../../store/map' import { IconCropLandscape, IconCropPortrait, IconEdit, IconEye, IconPrinter } from '@tabler/icons-react' import { useEffect, useState } from 'react' import { PrintOrientation, setPrintOrientation, usePrintStore } from '../../store/print' import { Button, Menu, MenuItemRadio, MenuList, MenuPopover, MenuProps, MenuTrigger, SplitButton } from '@fluentui/react-components' +import axiosInstance from '../../http/axiosInstanceNest' const MapMode = ({ map_id }: { map_id: string }) => { - const { mode } = useMapStore().id[map_id] + const { mode, changes, currentChange } = useMapStore().id[map_id] const { printOrientation } = usePrintStore() @@ -85,6 +86,62 @@ const MapMode = ({ + + {changes && currentChange && mode === 'edit' && }
) } diff --git a/client/src/components/map/MapToolbar/MapToolbar.tsx b/client/src/components/map/MapToolbar/MapToolbar.tsx index 10064f6..52f91c4 100644 --- a/client/src/components/map/MapToolbar/MapToolbar.tsx +++ b/client/src/components/map/MapToolbar/MapToolbar.tsx @@ -1,5 +1,5 @@ -import { IconArrowBackUp, IconArrowsMove, IconCircle, IconExclamationCircle, IconLine, IconPoint, IconPolygon } from '@tabler/icons-react' -import { getDraw, setCurrentTool, useMapStore } from '../../../store/map'; +import { IconArrowBackUp, IconArrowForwardUp, IconArrowsMove, IconCircle, IconExclamationCircle, IconLine, IconPoint, IconPolygon } from '@tabler/icons-react' +import { getChanges, getCurrentChange, setCurrentChange, setCurrentTool, useMapStore } from '../../../store/map'; import { saveFeatures } from '../mapUtils'; import { Button, Tooltip } from '@fluentui/react-components'; import { useAppStore } from '../../../store/app'; @@ -13,6 +13,24 @@ const MapToolbar = ({ const { selectedRegion, selectedDistrict, selectedYear } = useObjectsStore().id[map_id] const { colorScheme } = useAppStore(); + const getEntries = () => { + const entries = Array.from(getChanges(map_id).entries()) + const currentIndex = entries.findIndex(([key]) => key === getCurrentChange(map_id)) + + let prevEntry = undefined + let currentEntry = undefined + let nextEntry = undefined + + if (currentIndex !== -1) { + prevEntry = currentIndex > 0 ? entries[currentIndex - 1] : undefined; + nextEntry = currentIndex < entries.length - 1 ? entries[currentIndex + 1] : undefined; + + currentEntry = entries[currentIndex] + } + + return { prevEntry: prevEntry, currentEntry: currentEntry, nextEntry: nextEntry } + } + return (
@@ -21,7 +39,27 @@ const MapToolbar = ({