From b847cf9409fe488445c8cf9aaddf70a1ad69d5aa Mon Sep 17 00:00:00 2001 From: Moritz Schalk Date: Wed, 27 Mar 2024 18:44:18 +0100 Subject: [PATCH 1/7] Use Groups instead of Layers. --- .../map_planning/components/EditorMap.tsx | 35 ++++++++++--------- .../layers/_frontend_only/grid/GridLayer.tsx | 6 ++-- .../map_planning/layers/base/BaseLayer.tsx | 6 ++-- .../map_planning/layers/plant/PlantsLayer.tsx | 10 +++--- .../components/PlantLayerRelationsOverlay.tsx | 6 ++-- 5 files changed, 33 insertions(+), 30 deletions(-) diff --git a/frontend/src/features/map_planning/components/EditorMap.tsx b/frontend/src/features/map_planning/components/EditorMap.tsx index 0bf09e48c..f31174775 100644 --- a/frontend/src/features/map_planning/components/EditorMap.tsx +++ b/frontend/src/features/map_planning/components/EditorMap.tsx @@ -1,7 +1,8 @@ import i18next from 'i18next'; import Konva from 'konva'; -import { useCallback, useContext, useEffect, useState } from 'react'; +import React, { useCallback, useContext, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; +import { Layer } from 'react-konva'; import { ShepherdTourContext } from 'react-shepherd'; import { toast } from 'react-toastify'; import { GainedBlossomsDto, LayerDto, LayerType } from '@/api_types/definitions'; @@ -321,21 +322,23 @@ export const EditorMap = ({ layers }: MapProps) => { stageClickListeners, }} > - - - + + + + +
{ const viewRect = useMapStore((state) => state.untrackedState.editorViewRect); return ( - + - + ); }; diff --git a/frontend/src/features/map_planning/layers/base/BaseLayer.tsx b/frontend/src/features/map_planning/layers/base/BaseLayer.tsx index 3488e8339..d39b177c6 100644 --- a/frontend/src/features/map_planning/layers/base/BaseLayer.tsx +++ b/frontend/src/features/map_planning/layers/base/BaseLayer.tsx @@ -1,5 +1,5 @@ import { useCallback, useEffect, useState } from 'react'; -import { Circle, Group, Layer, Line } from 'react-konva'; +import { Circle, Group, Line } from 'react-konva'; import { NextcloudKonvaImage } from '@/features/map_planning/components/image/NextcloudKonvaImage'; import { MapGeometryEditor } from '@/features/map_planning/layers/base/components/MapGeometryEditor'; import useMapStore from '@/features/map_planning/store/MapStore'; @@ -62,7 +62,7 @@ const BaseLayer = (props: BaseLayerProps) => { const scale = MAP_PIXELS_PER_METER / pixelsPerMeter; return ( - + {cleanImagePath && ( { /> - + ); }; diff --git a/frontend/src/features/map_planning/layers/plant/PlantsLayer.tsx b/frontend/src/features/map_planning/layers/plant/PlantsLayer.tsx index 4f7fe7240..ebc64e244 100644 --- a/frontend/src/features/map_planning/layers/plant/PlantsLayer.tsx +++ b/frontend/src/features/map_planning/layers/plant/PlantsLayer.tsx @@ -2,7 +2,7 @@ import { t } from 'i18next'; import Konva from 'konva'; import { KonvaEventListener, KonvaEventObject, Node } from 'konva/lib/Node'; import { useCallback, useEffect, useRef } from 'react'; -import { Layer } from 'react-konva'; +import { Group } from 'react-konva'; import * as uuid from 'uuid'; import { LayerType, @@ -339,15 +339,15 @@ function PlantsLayer(props: PlantsLayerProps) { return ( <> - + {plantings.map((planting) => ( ))} - - + + - + ); } diff --git a/frontend/src/features/map_planning/layers/plant/components/PlantLayerRelationsOverlay.tsx b/frontend/src/features/map_planning/layers/plant/components/PlantLayerRelationsOverlay.tsx index 5c61f84e6..4e610c1c2 100644 --- a/frontend/src/features/map_planning/layers/plant/components/PlantLayerRelationsOverlay.tsx +++ b/frontend/src/features/map_planning/layers/plant/components/PlantLayerRelationsOverlay.tsx @@ -1,6 +1,6 @@ import Konva from 'konva'; import { useEffect, useMemo, useState } from 'react'; -import { Layer, Line } from 'react-konva'; +import { Group, Line } from 'react-konva'; import { LayerType, RelationType } from '@/api_types/definitions'; import useMapStore from '@/features/map_planning/store/MapStore'; import { useRelations } from '../hooks/relationsHookApi'; @@ -70,7 +70,7 @@ export function PlantLayerRelationsOverlay() { }, [relations, layers]); return ( - + {!areRelationsLoading && lineEnd && visiblePlantingNodes ? visiblePlantingNodes.map((node) => { const relation = relations?.get(node.attrs.plantId)?.relation; @@ -88,7 +88,7 @@ export function PlantLayerRelationsOverlay() { ); }) : null} - + ); } From c53c09b8fcc1a53fb2dd99a52141d5be401b3224 Mon Sep 17 00:00:00 2001 From: Moritz Schalk Date: Wed, 27 Mar 2024 18:49:47 +0100 Subject: [PATCH 2/7] Update changelog. --- doc/changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/changelog.md b/doc/changelog.md index c3a0d60fb..59548ebbc 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -17,7 +17,7 @@ Syntax: `- short text describing the change _(Your Name)_` - Add notes to plantings in backend #1156 _(Jannis Adamek)_ - Fix seed routes and add naming convention guideline _(Daniel Steinkogler)_ - Enable automatic image scaling in base layer _(Moritz)_ -- _()_ +- Use Konva Groups instead of Layers _(Moritz)_ - Add [guideline](guidelines/frontend-keyhandling.md) and [decisions](decisions/frontend_keyhandling.md) for key handling) _(Daniel Steinkogler)_ - _()_ - Fix ref warning in PlantLabel, center labels as intended _(Paul)_ From ee44faca828b8aaeb9b05d3d3984430a6c86179b Mon Sep 17 00:00:00 2001 From: Moritz Schalk Date: Wed, 27 Mar 2024 18:44:18 +0100 Subject: [PATCH 3/7] Use Groups instead of Layers. --- .../map_planning/components/EditorMap.tsx | 48 +++++++++---------- .../layers/_frontend_only/grid/GridLayer.tsx | 6 +-- .../map_planning/layers/base/BaseLayer.tsx | 6 +-- .../map_planning/layers/plant/PlantsLayer.tsx | 10 ++-- .../components/PlantLayerRelationsOverlay.tsx | 6 +-- 5 files changed, 38 insertions(+), 38 deletions(-) diff --git a/frontend/src/features/map_planning/components/EditorMap.tsx b/frontend/src/features/map_planning/components/EditorMap.tsx index 24c761440..298ee8d32 100644 --- a/frontend/src/features/map_planning/components/EditorMap.tsx +++ b/frontend/src/features/map_planning/components/EditorMap.tsx @@ -1,7 +1,8 @@ import i18next from 'i18next'; import Konva from 'konva'; -import { useCallback, useContext, useEffect, useState } from 'react'; +import React, { useCallback, useContext, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; +import { Layer } from 'react-konva'; import { ShepherdTourContext } from 'react-shepherd'; import { toast } from 'react-toastify'; import { GainedBlossomsDto, LayerDto, LayerType } from '@/api_types/definitions'; @@ -27,9 +28,6 @@ import { gainBlossom } from '../api/gainBlossom'; import { useCompleteTour, useReenableTour } from '../hooks/tourHookApi'; import BaseLayer from '../layers/base/BaseLayer'; import BaseLayerRightToolbar from '../layers/base/components/BaseLayerRightToolbar'; -import DrawingLayer from '../layers/drawing/DrawingLayer'; -import { DrawingLayerLeftToolbar } from '../layers/drawing/DrawingLayerLeftToolbar'; -import DrawingLayerRightToolbar from '../layers/drawing/DrawingLayerRightToolbar'; import PlantsLayer from '../layers/plant/PlantsLayer'; import { PlantLayerLeftToolbar } from '../layers/plant/components/PlantLayerLeftToolbar'; import { PlantLayerRightToolbar } from '../layers/plant/components/PlantLayerRightToolbar'; @@ -331,26 +329,28 @@ export const EditorMap = ({ layers }: MapProps) => { }} selectable={isShapeSelectionEnabled} > - - - - + + + + + +
{ const viewRect = useMapStore((state) => state.untrackedState.editorViewRect); return ( - + - + ); }; diff --git a/frontend/src/features/map_planning/layers/base/BaseLayer.tsx b/frontend/src/features/map_planning/layers/base/BaseLayer.tsx index 3488e8339..d39b177c6 100644 --- a/frontend/src/features/map_planning/layers/base/BaseLayer.tsx +++ b/frontend/src/features/map_planning/layers/base/BaseLayer.tsx @@ -1,5 +1,5 @@ import { useCallback, useEffect, useState } from 'react'; -import { Circle, Group, Layer, Line } from 'react-konva'; +import { Circle, Group, Line } from 'react-konva'; import { NextcloudKonvaImage } from '@/features/map_planning/components/image/NextcloudKonvaImage'; import { MapGeometryEditor } from '@/features/map_planning/layers/base/components/MapGeometryEditor'; import useMapStore from '@/features/map_planning/store/MapStore'; @@ -62,7 +62,7 @@ const BaseLayer = (props: BaseLayerProps) => { const scale = MAP_PIXELS_PER_METER / pixelsPerMeter; return ( - + {cleanImagePath && ( { /> - + ); }; diff --git a/frontend/src/features/map_planning/layers/plant/PlantsLayer.tsx b/frontend/src/features/map_planning/layers/plant/PlantsLayer.tsx index f935a2cb5..9c226b678 100644 --- a/frontend/src/features/map_planning/layers/plant/PlantsLayer.tsx +++ b/frontend/src/features/map_planning/layers/plant/PlantsLayer.tsx @@ -2,7 +2,7 @@ import { t } from 'i18next'; import Konva from 'konva'; import { KonvaEventListener, KonvaEventObject, Node } from 'konva/lib/Node'; import { useCallback, useEffect, useRef } from 'react'; -import { Layer } from 'react-konva'; +import { Group } from 'react-konva'; import * as uuid from 'uuid'; import { LayerType, @@ -339,15 +339,15 @@ function PlantsLayer(props: PlantsLayerProps) { return ( <> - + {plantings.map((planting) => ( ))} - - + + - + ); } diff --git a/frontend/src/features/map_planning/layers/plant/components/PlantLayerRelationsOverlay.tsx b/frontend/src/features/map_planning/layers/plant/components/PlantLayerRelationsOverlay.tsx index 5c61f84e6..4e610c1c2 100644 --- a/frontend/src/features/map_planning/layers/plant/components/PlantLayerRelationsOverlay.tsx +++ b/frontend/src/features/map_planning/layers/plant/components/PlantLayerRelationsOverlay.tsx @@ -1,6 +1,6 @@ import Konva from 'konva'; import { useEffect, useMemo, useState } from 'react'; -import { Layer, Line } from 'react-konva'; +import { Group, Line } from 'react-konva'; import { LayerType, RelationType } from '@/api_types/definitions'; import useMapStore from '@/features/map_planning/store/MapStore'; import { useRelations } from '../hooks/relationsHookApi'; @@ -70,7 +70,7 @@ export function PlantLayerRelationsOverlay() { }, [relations, layers]); return ( - + {!areRelationsLoading && lineEnd && visiblePlantingNodes ? visiblePlantingNodes.map((node) => { const relation = relations?.get(node.attrs.plantId)?.relation; @@ -88,7 +88,7 @@ export function PlantLayerRelationsOverlay() { ); }) : null} - + ); } From 006f9a0a392c38f6606e93dfc50fccda54576330 Mon Sep 17 00:00:00 2001 From: Moritz Schalk Date: Wed, 27 Mar 2024 18:49:47 +0100 Subject: [PATCH 4/7] Update changelog. --- doc/changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/changelog.md b/doc/changelog.md index 3b8c7212b..82efdef58 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -17,7 +17,7 @@ Syntax: `- short text describing the change _(Your Name)_` - Add notes to plantings in backend #1156 _(Jannis Adamek)_ - Fix seed routes and add naming convention guideline _(Daniel Steinkogler)_ - Enable automatic image scaling in base layer _(Moritz)_ -- _()_ +- Use Konva Groups instead of Layers _(Moritz)_ - Add [guideline](guidelines/frontend-keyhandling.md) and [decisions](decisions/frontend_keyhandling.md) for key handling) _(Daniel Steinkogler)_ - _()_ - Fix ref warning in PlantLabel, center labels as intended _(Paul)_ From b5db8a12a719ad88c05be552862add0f07fc95cd Mon Sep 17 00:00:00 2001 From: Moritz Schalk Date: Fri, 29 Mar 2024 14:45:45 +0100 Subject: [PATCH 5/7] Use groups instead of layers in drawing layer. --- frontend/src/features/map_planning/components/EditorMap.tsx | 3 +++ .../features/map_planning/layers/drawing/DrawingLayer.tsx | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/frontend/src/features/map_planning/components/EditorMap.tsx b/frontend/src/features/map_planning/components/EditorMap.tsx index 298ee8d32..4499f3b14 100644 --- a/frontend/src/features/map_planning/components/EditorMap.tsx +++ b/frontend/src/features/map_planning/components/EditorMap.tsx @@ -15,6 +15,9 @@ import { } from '@/config/keybindings'; import { FrontendOnlyLayerType } from '@/features/map_planning/layers/_frontend_only'; import { GridLayer } from '@/features/map_planning/layers/_frontend_only/grid/GridLayer'; +import DrawingLayer from '@/features/map_planning/layers/drawing/DrawingLayer'; +import { DrawingLayerLeftToolbar } from '@/features/map_planning/layers/drawing/DrawingLayerLeftToolbar'; +import DrawingLayerRightToolbar from '@/features/map_planning/layers/drawing/DrawingLayerRightToolbar'; import { CombinedLayerType } from '@/features/map_planning/store/MapStoreTypes'; import { StageListenerRegister } from '@/features/map_planning/types/layer-config'; import { useKeyHandlers } from '@/hooks/useKeyHandlers'; diff --git a/frontend/src/features/map_planning/layers/drawing/DrawingLayer.tsx b/frontend/src/features/map_planning/layers/drawing/DrawingLayer.tsx index 98189fcef..209ebd090 100644 --- a/frontend/src/features/map_planning/layers/drawing/DrawingLayer.tsx +++ b/frontend/src/features/map_planning/layers/drawing/DrawingLayer.tsx @@ -3,7 +3,7 @@ import { LayerConfig } from 'konva/lib/Layer'; import { KonvaEventListener, KonvaEventObject } from 'konva/lib/Node'; import { Vector2d } from 'konva/lib/types'; import { useCallback, useEffect, useRef, useState } from 'react'; -import { Ellipse, Layer, Line, Rect } from 'react-konva'; +import { Ellipse, Group, Line, Rect } from 'react-konva'; import * as uuid from 'uuid'; import { DrawingDto, DrawingShapeType, LayerType } from '@/api_types/definitions'; import { @@ -688,7 +688,7 @@ function DrawingLayer(props: DrawingLayerProps) { return ( <> - + {bezierLines.map((bezierLine, i) => ( )} - + ); } From 178e789c88a81995bfce4a5ff9035647e5d9b1b9 Mon Sep 17 00:00:00 2001 From: Moritz Schalk Date: Wed, 3 Apr 2024 21:48:44 +0200 Subject: [PATCH 6/7] Fix selection rectangle not working. --- .../src/features/map_planning/components/EditorMap.tsx | 2 +- .../src/features/map_planning/utils/ShapesSelection.ts | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/frontend/src/features/map_planning/components/EditorMap.tsx b/frontend/src/features/map_planning/components/EditorMap.tsx index 4499f3b14..ec0494bd6 100644 --- a/frontend/src/features/map_planning/components/EditorMap.tsx +++ b/frontend/src/features/map_planning/components/EditorMap.tsx @@ -332,7 +332,7 @@ export const EditorMap = ({ layers }: MapProps) => { }} selectable={isShapeSelectionEnabled} > - + layer.attrs.listening) .flatMap((layer) => layer.children) + .filter((group) => !!group) + .filter((group) => group?.attrs.listening) + // @ts-expect-error Typescript can't tell that all direct children layer must have children themselves + .filter((group) => group['children'] !== undefined) + // @ts-expect-error Typescript can't tell that all direct children layer must have children themselves + .flatMap((group) => group?.children) .filter((shape) => { // To exclude Konva's transformer, check if node contains children. // 'listening' is explicitly checked for '!== false' because From 1e7eded3d941341564085794aad7023ab1b9f79e Mon Sep 17 00:00:00 2001 From: Moritz Schalk Date: Fri, 5 Apr 2024 13:04:40 +0200 Subject: [PATCH 7/7] Fix PlantLayerRealtionsOverlay. --- .../components/PlantLayerRelationsOverlay.tsx | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/frontend/src/features/map_planning/layers/plant/components/PlantLayerRelationsOverlay.tsx b/frontend/src/features/map_planning/layers/plant/components/PlantLayerRelationsOverlay.tsx index 4e610c1c2..84e6c8e97 100644 --- a/frontend/src/features/map_planning/layers/plant/components/PlantLayerRelationsOverlay.tsx +++ b/frontend/src/features/map_planning/layers/plant/components/PlantLayerRelationsOverlay.tsx @@ -62,11 +62,17 @@ export function PlantLayerRelationsOverlay() { const layers = stage?.children; const visiblePlantingNodes = useMemo(() => { - return layers - ?.filter((l) => l.name() === LayerType.Plants) - .flatMap((l) => l.children ?? []) - .filter((s) => s.attrs.plantId && s.isClientRectOnScreen()) - .filter((s) => relations?.has(s.attrs.plantId)); + return ( + layers + ?.flatMap((l) => l.children ?? []) + .filter((l) => l.name() === LayerType.Plants) + // @ts-expect-error Typescript can't tell that all direct children layer must have children themselves + .filter((group) => group['children'] !== undefined) + // @ts-expect-error Typescript can't tell that all direct children layer must have children themselves + .flatMap((group) => group?.children) + .filter((s) => s.attrs.plantId && s.isClientRectOnScreen()) + .filter((s) => relations?.has(s.attrs.plantId)) + ); }, [relations, layers]); return (