From 4a9d3eb1e717fcb78bd61cc59f53219b6b77b5b7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mi=C5=82osz=20Grocholewski?= <m.grocholewski@atcomp.pl>
Date: Mon, 17 Feb 2025 12:16:14 +0100
Subject: [PATCH 1/8] feat(layer-text): add transform interaction for layer
 text and delete functionality

---
 ...eObjectEditFactoryModal.component.test.tsx |  38 ++-
 ...rImageObjectEditFactoryModal.component.tsx |  21 +-
 .../LayerDrawerTextItem.component.tsx         |  70 +++-
 .../LayersDrawer/LayersDrawer.component.tsx   |   4 +-
 .../LayersDrawerImageItem.component.tsx       |   4 +-
 .../LayersDrawerObjectsList.component.tsx     | 147 +++++---
 .../Map/MapViewer/MapViewer.component.tsx     |   8 +-
 .../useOlMapAdditionalLayers.ts               |  34 +-
 .../utils/shapes/elements/Glyph/Glyph.ts      |  10 +-
 .../Map/MapViewer/utils/shapes/layer/Layer.ts |  56 ++--
 .../Glyph => layer/elements}/LayerImage.ts    |  33 +-
 .../elements/LayerText.test.ts}               |  28 +-
 .../utils/shapes/layer/elements/LayerText.ts  | 315 ++++++++++++++++++
 ...est.ts => getTransformInteraction.test.ts} |   6 +-
 ...eraction.ts => getTransformInteraction.ts} |  40 +--
 .../utils/updateElement.ts}                   |  12 +-
 .../Map/MapViewer/utils/shapes/text/Text.ts   | 145 --------
 .../utils/shapes/text/getTextCoords.ts        |   9 +-
 .../utils/websocket/processLayerImage.ts      |   4 +-
 .../utils/websocket/processLayerText.ts       |  33 +-
 src/models/layerTextSchema.ts                 |   4 +-
 src/redux/apiPath.ts                          |   4 +
 src/redux/layers/layers.reducers.ts           |  32 ++
 src/redux/layers/layers.slice.ts              |   6 +
 src/redux/layers/layers.thunks.ts             |  86 ++++-
 src/redux/mapEditTools/mapEditTools.mock.ts   |   2 +-
 .../mapEditTools/mapEditTools.reducers.ts     |   6 +-
 .../mapEditTools/mapEditTools.selectors.ts    |   4 +-
 src/redux/mapEditTools/mapEditTools.types.ts  |   4 +-
 29 files changed, 818 insertions(+), 347 deletions(-)
 rename src/components/Map/MapViewer/utils/shapes/{elements/Glyph => layer/elements}/LayerImage.ts (54%)
 rename src/components/Map/MapViewer/utils/shapes/{text/Text.test.ts => layer/elements/LayerText.test.ts} (75%)
 create mode 100644 src/components/Map/MapViewer/utils/shapes/layer/elements/LayerText.ts
 rename src/components/Map/MapViewer/utils/shapes/layer/interaction/{getTransformImageInteraction.test.ts => getTransformInteraction.test.ts} (85%)
 rename src/components/Map/MapViewer/utils/shapes/layer/interaction/{getTransformImageInteraction.ts => getTransformInteraction.ts} (76%)
 rename src/components/Map/MapViewer/utils/shapes/{elements/Glyph/updateGlyph.ts => layer/utils/updateElement.ts} (60%)
 delete mode 100644 src/components/Map/MapViewer/utils/shapes/text/Text.ts

diff --git a/src/components/FunctionalArea/Modal/LayerImageObjectModal/LayerImageObjectEditFactoryModal.component.test.tsx b/src/components/FunctionalArea/Modal/LayerImageObjectModal/LayerImageObjectEditFactoryModal.component.test.tsx
index 0c0973f2..29a26c8b 100644
--- a/src/components/FunctionalArea/Modal/LayerImageObjectModal/LayerImageObjectEditFactoryModal.component.test.tsx
+++ b/src/components/FunctionalArea/Modal/LayerImageObjectModal/LayerImageObjectEditFactoryModal.component.test.tsx
@@ -81,7 +81,13 @@ const renderComponent = (
 
 describe('LayerImageObjectEditFactoryModal - component', () => {
   it('should render LayerImageObjectEditFactoryModal component with initial state', () => {
-    renderComponent();
+    renderComponent({
+      activeAction: null,
+      layerObject: {
+        ...layerImageFixture,
+        glyph: null,
+      },
+    });
 
     expect(screen.getByText(/Glyph:/i)).toBeInTheDocument();
     expect(screen.getByText(/File:/i)).toBeInTheDocument();
@@ -90,7 +96,13 @@ describe('LayerImageObjectEditFactoryModal - component', () => {
   });
 
   it('should display a list of glyphs in the dropdown', async () => {
-    renderComponent();
+    renderComponent({
+      activeAction: null,
+      layerObject: {
+        ...layerImageFixture,
+        glyph: null,
+      },
+    });
 
     const dropdown = screen.getByTestId('autocomplete');
     if (!dropdown.firstChild) {
@@ -102,7 +114,13 @@ describe('LayerImageObjectEditFactoryModal - component', () => {
   });
 
   it('should update the selected glyph on dropdown change', async () => {
-    renderComponent();
+    renderComponent({
+      activeAction: null,
+      layerObject: {
+        ...layerImageFixture,
+        glyph: null,
+      },
+    });
 
     const dropdown = screen.getByTestId('autocomplete');
     if (!dropdown.firstChild) {
@@ -142,13 +160,13 @@ describe('LayerImageObjectEditFactoryModal - component', () => {
     };
     const getGlyphDataMock = jest.fn(() => glyphData);
     jest.spyOn(layerObjectFeature, 'get').mockImplementation(key => {
-      if (key === 'update') return (): void => {};
-      if (key === 'getGlyphData') return getGlyphDataMock;
+      if (key === 'updateElement') return (): void => {};
+      if (key === 'getObjectData') return getGlyphDataMock;
       return undefined;
     });
     renderComponent({
       activeAction: MAP_EDIT_ACTIONS.TRANSFORM_IMAGE,
-      layerImageObject: glyphData,
+      layerObject: glyphData,
     });
 
     const submitButton = screen.getByText(/Submit/i);
@@ -164,7 +182,13 @@ describe('LayerImageObjectEditFactoryModal - component', () => {
   });
 
   it('should display "No Image" when there is no image file', () => {
-    const { store } = renderComponent();
+    const { store } = renderComponent({
+      activeAction: null,
+      layerObject: {
+        ...layerImageFixture,
+        glyph: null,
+      },
+    });
 
     store.dispatch({
       type: 'glyphs/clearGlyphData',
diff --git a/src/components/FunctionalArea/Modal/LayerImageObjectModal/LayerImageObjectEditFactoryModal.component.tsx b/src/components/FunctionalArea/Modal/LayerImageObjectModal/LayerImageObjectEditFactoryModal.component.tsx
index e4dfcdd0..dc280845 100644
--- a/src/components/FunctionalArea/Modal/LayerImageObjectModal/LayerImageObjectEditFactoryModal.component.tsx
+++ b/src/components/FunctionalArea/Modal/LayerImageObjectModal/LayerImageObjectEditFactoryModal.component.tsx
@@ -2,7 +2,7 @@
 import React, { useState } from 'react';
 import { useAppSelector } from '@/redux/hooks/useAppSelector';
 
-import { mapEditToolsLayerImageObjectSelector } from '@/redux/mapEditTools/mapEditTools.selectors';
+import { mapEditToolsLayerObjectSelector } from '@/redux/mapEditTools/mapEditTools.selectors';
 import { LayerImageObjectForm } from '@/components/FunctionalArea/Modal/LayerImageObjectModal/LayerImageObjectForm.component';
 import { currentModelIdSelector } from '@/redux/models/models.selectors';
 import { addGlyph } from '@/redux/glyphs/glyphs.thunks';
@@ -13,24 +13,25 @@ import { showToast } from '@/utils/showToast';
 import { closeModal } from '@/redux/modal/modal.slice';
 import { SerializedError } from '@reduxjs/toolkit';
 import { useMapInstance } from '@/utils/context/mapInstanceContext';
-import updateGlyph from '@/components/Map/MapViewer/utils/shapes/elements/Glyph/updateGlyph';
+import updateElement from '@/components/Map/MapViewer/utils/shapes/layer/utils/updateElement';
 import { mapEditToolsSetLayerObject } from '@/redux/mapEditTools/mapEditTools.slice';
 
 export const LayerImageObjectEditFactoryModal: React.FC = () => {
-  const layerImageObject = useAppSelector(mapEditToolsLayerImageObjectSelector);
+  const layerObject = useAppSelector(mapEditToolsLayerObjectSelector);
   const { mapInstance } = useMapInstance();
 
+  if (!layerObject || !('glyph' in layerObject)) {
+    throw new Error('Invalid layer image object');
+  }
   const currentModelId = useAppSelector(currentModelIdSelector);
   const dispatch = useAppDispatch();
 
-  const [selectedGlyph, setSelectedGlyph] = useState<number | null>(
-    layerImageObject?.glyph || null,
-  );
+  const [selectedGlyph, setSelectedGlyph] = useState<number | null>(layerObject?.glyph || null);
   const [file, setFile] = useState<File | null>(null);
   const [isSending, setIsSending] = useState<boolean>(false);
 
   const handleSubmit = async (): Promise<void> => {
-    if (!layerImageObject) {
+    if (!layerObject) {
       return;
     }
     setIsSending(true);
@@ -47,8 +48,8 @@ export const LayerImageObjectEditFactoryModal: React.FC = () => {
       const layerImage = await dispatch(
         updateLayerImageObject({
           modelId: currentModelId,
-          layerId: layerImageObject.layer,
-          ...layerImageObject,
+          layerId: layerObject.layer,
+          ...layerObject,
           glyph: glyphId,
         }),
       ).unwrap();
@@ -57,7 +58,7 @@ export const LayerImageObjectEditFactoryModal: React.FC = () => {
           layerUpdateImage({ modelId: currentModelId, layerId: layerImage.layer, layerImage }),
         );
         dispatch(mapEditToolsSetLayerObject(layerImage));
-        updateGlyph(mapInstance, layerImage.layer, layerImage);
+        updateElement(mapInstance, layerImage.layer, layerImage);
       }
       showToast({
         type: 'success',
diff --git a/src/components/Map/Drawer/LayersDrawer/LayerDrawerTextItem.component.tsx b/src/components/Map/Drawer/LayersDrawer/LayerDrawerTextItem.component.tsx
index 12a7959c..6f57c762 100644
--- a/src/components/Map/Drawer/LayersDrawer/LayerDrawerTextItem.component.tsx
+++ b/src/components/Map/Drawer/LayersDrawer/LayerDrawerTextItem.component.tsx
@@ -1,18 +1,80 @@
-import { JSX } from 'react';
+import React, { JSX, useMemo } from 'react';
 import { LayerText } from '@/types/models';
 import { Icon } from '@/shared/Icon';
+import { LayersDrawerObjectActions } from '@/components/Map/Drawer/LayersDrawer/LayersDrawerObjectActions.component';
+import { useAppSelector } from '@/redux/hooks/useAppSelector';
+import { mapEditToolsLayerObjectSelector } from '@/redux/mapEditTools/mapEditTools.selectors';
+import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
+import { mapEditToolsSetLayerObject } from '@/redux/mapEditTools/mapEditTools.slice';
+import { hasPrivilegeToWriteProjectSelector } from '@/redux/user/user.selectors';
 
 interface LayersDrawerTextItemProps {
   layerText: LayerText;
+  bringToFront: () => void;
+  bringToBack: () => void;
+  removeObject: () => void;
+  centerObject: () => void;
+  editObject: () => void;
+  isLayerVisible: boolean;
+  isLayerActive: boolean;
 }
 
 export const LayersDrawerTextItem = ({
   layerText,
+  bringToFront,
+  bringToBack,
+  removeObject,
+  centerObject,
+  editObject,
+  isLayerVisible,
+  isLayerActive,
 }: LayersDrawerTextItemProps): JSX.Element | null => {
+  const dispatch = useAppDispatch();
+  const activeLayerObject = useAppSelector(mapEditToolsLayerObjectSelector);
+  const hasPrivilegeToWriteProject = useAppSelector(hasPrivilegeToWriteProjectSelector);
+
+  const showActions = useMemo(() => {
+    return activeLayerObject?.id === layerText.id;
+  }, [activeLayerObject?.id, layerText.id]);
+
+  const canSelectItem = useMemo(() => {
+    return isLayerVisible && isLayerActive && hasPrivilegeToWriteProject;
+  }, [isLayerVisible, isLayerActive, hasPrivilegeToWriteProject]);
+
+  const selectItem = useMemo(() => {
+    return (): void => {
+      if (canSelectItem) {
+        dispatch(mapEditToolsSetLayerObject(layerText));
+      }
+    };
+  }, [canSelectItem, dispatch, layerText]);
+
+  const handleKeyPress = (): void => {};
+
   return (
-    <div className="flex min-h-[24px]  gap-2">
-      <Icon name="text" className="shrink-0" />
-      <span className="truncate">{layerText.notes}</span>
+    <div
+      className="flex min-h-[24px] items-center justify-between gap-2"
+      id={`layer-text-item-${layerText.id}`}
+    >
+      <div
+        className={`flex gap-2 ${canSelectItem ? 'cursor-pointer' : 'cursor-default'}`}
+        onClick={selectItem}
+        tabIndex={0}
+        onKeyDown={handleKeyPress}
+        role="button"
+      >
+        <Icon name="text" className="shrink-0" />
+        <span className="truncate">{layerText.notes}</span>
+      </div>
+      {showActions && (
+        <LayersDrawerObjectActions
+          bringToFront={bringToFront}
+          bringToBack={bringToBack}
+          removeObject={removeObject}
+          centerObject={centerObject}
+          editObject={editObject}
+        />
+      )}
     </div>
   );
 };
diff --git a/src/components/Map/Drawer/LayersDrawer/LayersDrawer.component.tsx b/src/components/Map/Drawer/LayersDrawer/LayersDrawer.component.tsx
index df941aca..12bef081 100644
--- a/src/components/Map/Drawer/LayersDrawer/LayersDrawer.component.tsx
+++ b/src/components/Map/Drawer/LayersDrawer/LayersDrawer.component.tsx
@@ -8,14 +8,14 @@ import { JSX, useEffect, useRef } from 'react';
 import { openLayerFactoryModal } from '@/redux/modal/modal.slice';
 import { hasPrivilegeToWriteProjectSelector } from '@/redux/user/user.selectors';
 import { LayersDrawerLayer } from '@/components/Map/Drawer/LayersDrawer/LayersDrawerLayer.component';
-import { mapEditToolsLayerImageObjectSelector } from '@/redux/mapEditTools/mapEditTools.selectors';
+import { mapEditToolsLayerObjectSelector } from '@/redux/mapEditTools/mapEditTools.selectors';
 
 export const LayersDrawer = (): JSX.Element => {
   const layersForCurrentModel = useAppSelector(layersForCurrentModelSelector);
   const hasPrivilegeToWriteProject = useAppSelector(hasPrivilegeToWriteProjectSelector);
   const dispatch = useAppDispatch();
   const layersDrawerRef = useRef<HTMLDivElement>(null);
-  const mapEditToolsLayerImageObject = useAppSelector(mapEditToolsLayerImageObjectSelector);
+  const mapEditToolsLayerImageObject = useAppSelector(mapEditToolsLayerObjectSelector);
 
   const addNewLayer = (): void => {
     dispatch(openLayerFactoryModal());
diff --git a/src/components/Map/Drawer/LayersDrawer/LayersDrawerImageItem.component.tsx b/src/components/Map/Drawer/LayersDrawer/LayersDrawerImageItem.component.tsx
index d2884a5b..0622f141 100644
--- a/src/components/Map/Drawer/LayersDrawer/LayersDrawerImageItem.component.tsx
+++ b/src/components/Map/Drawer/LayersDrawer/LayersDrawerImageItem.component.tsx
@@ -4,7 +4,7 @@ import { Icon } from '@/shared/Icon';
 import { useAppSelector } from '@/redux/hooks/useAppSelector';
 import { glyphFileNameByIdSelector } from '@/redux/glyphs/glyphs.selectors';
 import { LayersDrawerObjectActions } from '@/components/Map/Drawer/LayersDrawer/LayersDrawerObjectActions.component';
-import { mapEditToolsLayerImageObjectSelector } from '@/redux/mapEditTools/mapEditTools.selectors';
+import { mapEditToolsLayerObjectSelector } from '@/redux/mapEditTools/mapEditTools.selectors';
 import { mapEditToolsSetLayerObject } from '@/redux/mapEditTools/mapEditTools.slice';
 import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
 import { hasPrivilegeToWriteProjectSelector } from '@/redux/user/user.selectors';
@@ -31,7 +31,7 @@ export const LayersDrawerImageItem = ({
   isLayerActive,
 }: LayersDrawerImageItemProps): JSX.Element | null => {
   const dispatch = useAppDispatch();
-  const activeLayerImage = useAppSelector(mapEditToolsLayerImageObjectSelector);
+  const activeLayerImage = useAppSelector(mapEditToolsLayerObjectSelector);
   const fileName = useAppSelector(state => glyphFileNameByIdSelector(state, layerImage.glyph));
   const hasPrivilegeToWriteProject = useAppSelector(hasPrivilegeToWriteProjectSelector);
 
diff --git a/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectsList.component.tsx b/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectsList.component.tsx
index fca7a858..fa98e051 100644
--- a/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectsList.component.tsx
+++ b/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectsList.component.tsx
@@ -9,19 +9,23 @@ import { JSX, useState } from 'react';
 import { LayersDrawerImageItem } from '@/components/Map/Drawer/LayersDrawer/LayersDrawerImageItem.component';
 import { LayersDrawerTextItem } from '@/components/Map/Drawer/LayersDrawer/LayerDrawerTextItem.component';
 import QuestionModal from '@/components/FunctionalArea/Modal/QuestionModal/QustionModal.component';
-import { removeLayerImage, updateLayerImageObject } from '@/redux/layers/layers.thunks';
-import { layerDeleteImage, layerUpdateImage } from '@/redux/layers/layers.slice';
+import {
+  removeLayerImage,
+  removeLayerText,
+  updateLayerImageObject,
+} from '@/redux/layers/layers.thunks';
+import { layerDeleteImage, layerDeleteText, layerUpdateImage } from '@/redux/layers/layers.slice';
 import removeElementFromLayer from '@/components/Map/MapViewer/utils/shapes/elements/removeElementFromLayer';
 import { showToast } from '@/utils/showToast';
 import { SerializedError } from '@reduxjs/toolkit';
-import { LayerImage } from '@/types/models';
+import { LayerImage, LayerText } from '@/types/models';
 import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
 import { useMapInstance } from '@/utils/context/mapInstanceContext';
 import { mapModelIdSelector } from '@/redux/map/map.selectors';
 import { mapEditToolsSetLayerObject } from '@/redux/mapEditTools/mapEditTools.slice';
-import updateGlyph from '@/components/Map/MapViewer/utils/shapes/elements/Glyph/updateGlyph';
+import updateElement from '@/components/Map/MapViewer/utils/shapes/layer/utils/updateElement';
 import { useSetBounds } from '@/utils/map/useSetBounds';
-import { mapEditToolsLayerImageObjectSelector } from '@/redux/mapEditTools/mapEditTools.selectors';
+import { mapEditToolsLayerObjectSelector } from '@/redux/mapEditTools/mapEditTools.selectors';
 import { usePointToProjection } from '@/utils/map/usePointToProjection';
 import { Coordinate } from 'ol/coordinate';
 import { openLayerImageObjectEditFactoryModal } from '@/redux/modal/modal.slice';
@@ -32,6 +36,19 @@ interface LayersDrawerObjectsListProps {
   isLayerActive: boolean;
 }
 
+const removeObjectConfig = {
+  image: {
+    question: 'Are you sure you want to remove the image?',
+    successMessage: 'The layer image has been successfully removed',
+    errorMessage: 'An error occurred while removing the layer text',
+  },
+  text: {
+    question: 'Are you sure you want to remove the text?',
+    successMessage: 'The layer text has been successfully removed',
+    errorMessage: 'An error occurred while removing the layer text',
+  },
+};
+
 export const LayersDrawerObjectsList = ({
   layerId,
   isLayerVisible,
@@ -41,57 +58,81 @@ export const LayersDrawerObjectsList = ({
   const highestZIndex = useAppSelector(highestZIndexSelector);
   const lowestZIndex = useAppSelector(lowestZIndexSelector);
   const layer = useAppSelector(state => layerByIdSelector(state, layerId));
-  const mapEditToolsLayerImageObject = useAppSelector(mapEditToolsLayerImageObjectSelector);
-  const [isImageRemoveModalOpen, setIsImageRemoveModalOpen] = useState(false);
-  const [layerImageToRemove, setLayerImageToRemove] = useState<LayerImage | null>(null);
+  const mapEditToolsLayerImageObject = useAppSelector(mapEditToolsLayerObjectSelector);
+  const [removeModalState, setRemoveModalState] = useState<undefined | 'text' | 'image'>(undefined);
+  const [layerObjectToRemove, setLayerObjectToRemove] = useState<LayerImage | LayerText | null>(
+    null,
+  );
   const dispatch = useAppDispatch();
   const setBounds = useSetBounds();
   const pointToProjection = usePointToProjection();
   const { mapInstance } = useMapInstance();
 
-  const removeImage = (layerImage: LayerImage): void => {
-    setLayerImageToRemove(layerImage);
-    setIsImageRemoveModalOpen(true);
+  const removeObject = (layerObject: LayerImage | LayerText): void => {
+    setLayerObjectToRemove(layerObject);
+    if ('glyph' in layerObject) {
+      setRemoveModalState('image');
+    } else {
+      setRemoveModalState('text');
+    }
   };
 
-  const rejectImageRemove = (): void => {
-    setIsImageRemoveModalOpen(false);
+  const rejectRemove = (): void => {
+    setRemoveModalState(undefined);
   };
 
-  const confirmImageRemove = async (): Promise<void> => {
-    if (!layerImageToRemove) {
+  const confirmRemove = async (): Promise<void> => {
+    if (!layerObjectToRemove || !removeModalState) {
       return;
     }
+
     try {
-      await dispatch(
-        removeLayerImage({
-          modelId: currentModelId,
-          layerId: layerImageToRemove.layer,
-          imageId: layerImageToRemove.id,
-        }),
-      ).unwrap();
-      dispatch(
-        layerDeleteImage({
-          modelId: currentModelId,
-          layerId: layerImageToRemove.layer,
-          imageId: layerImageToRemove.id,
-        }),
-      );
+      if (removeModalState === 'text') {
+        await dispatch(
+          removeLayerText({
+            modelId: currentModelId,
+            layerId: layerObjectToRemove.layer,
+            textId: layerObjectToRemove.id,
+          }),
+        ).unwrap();
+        dispatch(
+          layerDeleteText({
+            modelId: currentModelId,
+            layerId: layerObjectToRemove.layer,
+            textId: layerObjectToRemove.id,
+          }),
+        );
+      } else {
+        await dispatch(
+          removeLayerImage({
+            modelId: currentModelId,
+            layerId: layerObjectToRemove.layer,
+            imageId: layerObjectToRemove.id,
+          }),
+        ).unwrap();
+        dispatch(
+          layerDeleteImage({
+            modelId: currentModelId,
+            layerId: layerObjectToRemove.layer,
+            imageId: layerObjectToRemove.id,
+          }),
+        );
+      }
       removeElementFromLayer({
         mapInstance,
-        layerId: layerImageToRemove.layer,
-        featureId: layerImageToRemove.id,
+        layerId: layerObjectToRemove.layer,
+        featureId: layerObjectToRemove.id,
       });
       showToast({
         type: 'success',
-        message: 'The layer image has been successfully removed',
+        message: removeObjectConfig[removeModalState].successMessage,
       });
-      setIsImageRemoveModalOpen(false);
+      setRemoveModalState(undefined);
     } catch (error) {
       const typedError = error as SerializedError;
       showToast({
         type: 'error',
-        message: typedError.message || 'An error occurred while removing the layer image',
+        message: typedError.message || removeObjectConfig[removeModalState].errorMessage,
       });
     }
   };
@@ -120,7 +161,7 @@ export const LayersDrawerObjectsList = ({
         }),
       );
       dispatch(mapEditToolsSetLayerObject(newLayerImage));
-      updateGlyph(mapInstance, newLayerImage.layer, newLayerImage);
+      updateElement(mapInstance, newLayerImage.layer, newLayerImage);
     }
   };
 
@@ -132,12 +173,12 @@ export const LayersDrawerObjectsList = ({
     await updateImageZIndex({ zIndex: lowestZIndex - 1, layerImage });
   };
 
-  const centerObject = (layerImage: LayerImage): void => {
-    if (mapEditToolsLayerImageObject && mapEditToolsLayerImageObject.id === layerImage.id) {
-      const point1 = pointToProjection({ x: layerImage.x, y: layerImage.y });
+  const centerObject = (layerObject: LayerImage | LayerText): void => {
+    if (mapEditToolsLayerImageObject && mapEditToolsLayerImageObject.id === layerObject.id) {
+      const point1 = pointToProjection({ x: layerObject.x, y: layerObject.y });
       const point2 = pointToProjection({
-        x: layerImage.x + layerImage.width,
-        y: layerImage.y + layerImage.height,
+        x: layerObject.x + layerObject.width,
+        y: layerObject.y + layerObject.height,
       });
       setBounds([point1, point2] as Coordinate[]);
     }
@@ -154,13 +195,27 @@ export const LayersDrawerObjectsList = ({
   return (
     <div className={`${isLayerVisible ? 'opacity-100' : 'opacity-40'} flex flex-col gap-1 ps-3`}>
       <QuestionModal
-        isOpen={isImageRemoveModalOpen}
-        onClose={rejectImageRemove}
-        onConfirm={confirmImageRemove}
-        question="Are you sure you want to remove the image?"
+        isOpen={Boolean(removeModalState)}
+        onClose={rejectRemove}
+        onConfirm={confirmRemove}
+        question={
+          removeModalState
+            ? removeObjectConfig[removeModalState].question
+            : 'Are you sure you want to remove the object'
+        }
       />
       {Object.values(layer.texts).map(layerText => (
-        <LayersDrawerTextItem layerText={layerText} key={layerText.id} />
+        <LayersDrawerTextItem
+          layerText={layerText}
+          key={layerText.id}
+          bringToFront={() => {}}
+          bringToBack={() => {}}
+          removeObject={() => removeObject(layerText)}
+          centerObject={() => centerObject(layerText)}
+          editObject={() => {}}
+          isLayerVisible={isLayerVisible}
+          isLayerActive={isLayerActive}
+        />
       ))}
       {Object.values(layer.images).map(layerImage => (
         <LayersDrawerImageItem
@@ -168,7 +223,7 @@ export const LayersDrawerObjectsList = ({
           key={layerImage.id}
           bringToFront={() => bringImageToFront(layerImage)}
           bringToBack={() => bringImageToBack(layerImage)}
-          removeObject={() => removeImage(layerImage)}
+          removeObject={() => removeObject(layerImage)}
           centerObject={() => centerObject(layerImage)}
           editObject={() => editImage()}
           isLayerVisible={isLayerVisible}
diff --git a/src/components/Map/MapViewer/MapViewer.component.tsx b/src/components/Map/MapViewer/MapViewer.component.tsx
index 0307cf08..faf874c1 100644
--- a/src/components/Map/MapViewer/MapViewer.component.tsx
+++ b/src/components/Map/MapViewer/MapViewer.component.tsx
@@ -1,13 +1,17 @@
 import 'ol/ol.css';
 import { twMerge } from 'tailwind-merge';
 import { useAppSelector } from '@/redux/hooks/useAppSelector';
-import { isMapEditToolsActiveSelector } from '@/redux/mapEditTools/mapEditTools.selectors';
+import {
+  isMapEditToolsActiveSelector,
+  mapEditToolsLayerObjectSelector,
+} from '@/redux/mapEditTools/mapEditTools.selectors';
 import { useOlMap } from './utils/useOlMap';
 import { MAP_VIEWER_ROLE } from './MapViewer.constants';
 
 export const MapViewer = (): JSX.Element => {
   const { mapRef } = useOlMap();
   const isMapEditToolsActive = useAppSelector(isMapEditToolsActiveSelector);
+  const layerObject = useAppSelector(mapEditToolsLayerObjectSelector);
 
   return (
     <div
@@ -15,7 +19,7 @@ export const MapViewer = (): JSX.Element => {
       role={MAP_VIEWER_ROLE}
       className={twMerge(
         'absolute left-[88px] top-[104px] h-[calc(100%-104px)] w-[calc(100%-88px)] bg-white',
-        isMapEditToolsActive ? 'bg-[#e4e2de]' : 'bg-white',
+        isMapEditToolsActive || layerObject ? 'bg-[#e4e2de]' : 'bg-white',
       )}
     />
   );
diff --git a/src/components/Map/MapViewer/utils/config/additionalLayers/useOlMapAdditionalLayers.ts b/src/components/Map/MapViewer/utils/config/additionalLayers/useOlMapAdditionalLayers.ts
index 162d345c..5e378293 100644
--- a/src/components/Map/MapViewer/utils/config/additionalLayers/useOlMapAdditionalLayers.ts
+++ b/src/components/Map/MapViewer/utils/config/additionalLayers/useOlMapAdditionalLayers.ts
@@ -16,7 +16,7 @@ import {
 } from '@/redux/layers/layers.selectors';
 import { usePointToProjection } from '@/utils/map/usePointToProjection';
 import { MapInstance } from '@/types/map';
-import { Geometry, LineString, MultiPolygon, Point } from 'ol/geom';
+import { Geometry, LineString, MultiPolygon } from 'ol/geom';
 import Polygon from 'ol/geom/Polygon';
 import Layer from '@/components/Map/MapViewer/utils/shapes/layer/Layer';
 import { arrowTypesSelector, lineTypesSelector } from '@/redux/shapes/shapes.selectors';
@@ -25,7 +25,7 @@ import { mapDataSizeSelector } from '@/redux/map/map.selectors';
 import { LayerState } from '@/redux/layers/layers.types';
 import {
   mapEditToolsActiveActionSelector,
-  mapEditToolsLayerImageObjectSelector,
+  mapEditToolsLayerObjectSelector,
 } from '@/redux/mapEditTools/mapEditTools.selectors';
 import { MAP_EDIT_ACTIONS } from '@/redux/mapEditTools/mapEditTools.constants';
 import getDrawBoundingBoxInteraction from '@/components/Map/MapViewer/utils/shapes/layer/interaction/getDrawBoundingBoxInteraction';
@@ -38,7 +38,7 @@ import {
   mapEditToolsSetActiveAction,
   mapEditToolsSetLayerObject,
 } from '@/redux/mapEditTools/mapEditTools.slice';
-import getTransformImageInteraction from '@/components/Map/MapViewer/utils/shapes/layer/interaction/getTransformImageInteraction';
+import getTransformInteraction from '@/components/Map/MapViewer/utils/shapes/layer/interaction/getTransformInteraction';
 import { useWebSocketEntityUpdatesContext } from '@/utils/websocket-entity-updates/webSocketEntityUpdatesProvider';
 import processMessage from '@/components/Map/MapViewer/utils/websocket/processMessage';
 import { hasPrivilegeToWriteProjectSelector } from '@/redux/user/user.selectors';
@@ -46,9 +46,7 @@ import { hasPrivilegeToWriteProjectSelector } from '@/redux/user/user.selectors'
 export const useOlMapAdditionalLayers = (
   mapInstance: MapInstance,
 ): Array<
-  VectorLayer<
-    VectorSource<Feature<Point> | Feature<Polygon> | Feature<LineString> | Feature<MultiPolygon>>
-  >
+  VectorLayer<VectorSource<Feature<Polygon> | Feature<LineString> | Feature<MultiPolygon>>>
 > => {
   const activeAction = useAppSelector(mapEditToolsActiveActionSelector);
   const dispatch = useAppDispatch();
@@ -61,7 +59,7 @@ export const useOlMapAdditionalLayers = (
   const activeLayers = useAppSelector(layersActiveLayersSelector);
   const drawLayer = useAppSelector(layersDrawLayerSelector);
   const hasPrivilegeToWriteProject = useAppSelector(hasPrivilegeToWriteProjectSelector);
-  const mapEditToolsLayerImageObject = useAppSelector(mapEditToolsLayerImageObjectSelector);
+  const mapEditToolsLayerObject = useAppSelector(mapEditToolsLayerObjectSelector);
 
   const [layersState, setLayersState] = useState<Array<LayerState>>([]);
   const [layersLoadingState, setLayersLoadingState] = useState(false);
@@ -157,21 +155,23 @@ export const useOlMapAdditionalLayers = (
     if (!dispatch || !currentModelId || !activeLayers.length) {
       return null;
     }
-    const imagesFeatures: Array<Feature<Geometry>> = [];
+    const features: Array<Feature<Geometry>> = [];
     const activeVectorLayers = vectorLayers.filter(layer => activeLayers.includes(layer.get('id')));
     activeVectorLayers.forEach(vectorLayer => {
-      imagesFeatures.push(...vectorLayer.get('imagesFeatures'));
+      features.push(...vectorLayer.get('imagesFeatures'));
+      features.push(...vectorLayer.get('textsFeatures'));
     });
-    const imagesFeaturesCollection = new Collection(imagesFeatures);
-    return getTransformImageInteraction(
+    const featuresCollection = new Collection(features);
+    return getTransformInteraction(
       dispatch,
       mapSize,
       currentModelId,
-      imagesFeaturesCollection,
+      featuresCollection,
       restrictionExtent,
     );
   }, [dispatch, mapSize, currentModelId, restrictionExtent, activeLayers, vectorLayers]);
   const transformRef = useRef(transformInteraction);
+
   useEffect(() => {
     transformRef.current = transformInteraction;
   }, [transformInteraction]);
@@ -202,13 +202,13 @@ export const useOlMapAdditionalLayers = (
     }
     const transformFeatures = transformRef.current.getFeatures();
     if (
-      mapEditToolsLayerImageObject &&
+      mapEditToolsLayerObject &&
       (!transformFeatures.getLength() ||
-        transformFeatures.item(0).getId() !== mapEditToolsLayerImageObject.id)
+        transformFeatures.item(0).getId() !== mapEditToolsLayerObject.id)
     ) {
       const layer = vectorLayers.find(vectorLayer => {
         const layerId = vectorLayer.get('id');
-        return layerId === mapEditToolsLayerImageObject.layer;
+        return layerId === mapEditToolsLayerObject.layer;
       });
       if (!layer) {
         return;
@@ -217,13 +217,13 @@ export const useOlMapAdditionalLayers = (
       if (!source) {
         return;
       }
-      const feature = source.getFeatureById(mapEditToolsLayerImageObject.id);
+      const feature = source.getFeatureById(mapEditToolsLayerObject.id);
       if (!feature) {
         return;
       }
       transformRef.current.setSelection(new Collection<Feature>([feature]));
     }
-  }, [mapEditToolsLayerImageObject, vectorLayers]);
+  }, [mapEditToolsLayerObject, vectorLayers]);
 
   useEffect(() => {
     const activeVectorLayers = vectorLayers.filter(layer => {
diff --git a/src/components/Map/MapViewer/utils/shapes/elements/Glyph/Glyph.ts b/src/components/Map/MapViewer/utils/shapes/elements/Glyph/Glyph.ts
index 0dca36a1..342cdfac 100644
--- a/src/components/Map/MapViewer/utils/shapes/elements/Glyph/Glyph.ts
+++ b/src/components/Map/MapViewer/utils/shapes/elements/Glyph/Glyph.ts
@@ -17,7 +17,6 @@ import { LayerImage } from '@/types/models';
 import getStyle from '@/components/Map/MapViewer/utils/shapes/style/getStyle';
 import getFill from '@/components/Map/MapViewer/utils/shapes/style/getFill';
 import getScaledElementStyle from '@/components/Map/MapViewer/utils/shapes/style/getScaledElementStyle';
-import getBoundingBoxFromExtent from '@/components/Map/MapViewer/utils/shapes/coords/getBoundingBoxFromExtent';
 
 export type GlyphProps = {
   elementId: number;
@@ -154,7 +153,7 @@ export default class Glyph {
 
     this.feature.set('setCoordinates', this.setCoordinates.bind(this));
     this.feature.set('refreshPolygon', this.refreshPolygon.bind(this));
-    this.feature.set('update', this.update.bind(this));
+    this.feature.set('updateElement', this.updateElement.bind(this));
     this.feature.setId(this.elementId);
     this.feature.setStyle(this.getStyle.bind(this));
 
@@ -186,7 +185,7 @@ export default class Glyph {
     this.feature.changed();
   }
 
-  private update(imageObject: LayerImage): void {
+  protected updateElement(imageObject: LayerImage): void {
     this.elementId = imageObject.id;
     this.x = imageObject.x;
     this.y = imageObject.y;
@@ -219,11 +218,6 @@ export default class Glyph {
     const geometry = this.polygonStyle.getGeometry();
     if (geometry && geometry instanceof Polygon) {
       geometry.setCoordinates(coords);
-      const boundingBox = getBoundingBoxFromExtent(geometry.getExtent(), this.mapSize);
-      this.x = boundingBox.x;
-      this.y = boundingBox.y;
-      this.width = boundingBox.width;
-      this.height = boundingBox.height;
     }
   }
 
diff --git a/src/components/Map/MapViewer/utils/shapes/layer/Layer.ts b/src/components/Map/MapViewer/utils/shapes/layer/Layer.ts
index 2149e63b..7f697a72 100644
--- a/src/components/Map/MapViewer/utils/shapes/layer/Layer.ts
+++ b/src/components/Map/MapViewer/utils/shapes/layer/Layer.ts
@@ -4,12 +4,12 @@ import {
   LayerLine,
   LayerOval,
   LayerRect,
-  LayerText,
+  LayerText as LayerTextModel,
 } from '@/types/models';
 import { MapInstance } from '@/types/map';
 import { UsePointToProjectionResult } from '@/utils/map/usePointToProjection';
 import { Feature } from 'ol';
-import { LineString, MultiPolygon, Point } from 'ol/geom';
+import { LineString, MultiPolygon } from 'ol/geom';
 import Polygon from 'ol/geom/Polygon';
 import VectorSource from 'ol/source/Vector';
 import VectorLayer from 'ol/layer/Vector';
@@ -30,11 +30,11 @@ import getArrowFeature from '@/components/Map/MapViewer/utils/shapes/elements/ge
 import getRotation from '@/components/Map/MapViewer/utils/shapes/coords/getRotation';
 import getStyle from '@/components/Map/MapViewer/utils/shapes/style/getStyle';
 import getEllipseCoords from '@/components/Map/MapViewer/utils/shapes/coords/getEllipseCoords';
-import Text from '@/components/Map/MapViewer/utils/shapes/text/Text';
-import LayerImage from '@/components/Map/MapViewer/utils/shapes/elements/Glyph/LayerImage';
+import LayerText from '@/components/Map/MapViewer/utils/shapes/layer/elements/LayerText';
+import LayerImage from '@/components/Map/MapViewer/utils/shapes/layer/elements/LayerImage';
 
 export interface LayerProps {
-  texts: { [key: string]: LayerText };
+  texts: { [key: string]: LayerTextModel };
   rects: Array<LayerRect>;
   ovals: Array<LayerOval>;
   lines: Array<LayerLine>;
@@ -51,7 +51,7 @@ export interface LayerProps {
 export default class Layer {
   layerId: number;
 
-  texts: { [key: string]: LayerText };
+  texts: { [key: string]: LayerTextModel };
 
   rects: Array<LayerRect>;
 
@@ -71,12 +71,10 @@ export default class Layer {
 
   mapSize: MapSize;
 
-  vectorSource: VectorSource<
-    Feature<Point> | Feature<Polygon> | Feature<LineString> | Feature<MultiPolygon>
-  >;
+  vectorSource: VectorSource<Feature<Polygon> | Feature<LineString> | Feature<MultiPolygon>>;
 
   vectorLayer: VectorLayer<
-    VectorSource<Feature<Point> | Feature<Polygon> | Feature<LineString> | Feature<MultiPolygon>>
+    VectorSource<Feature<Polygon> | Feature<LineString> | Feature<MultiPolygon>>
   >;
 
   constructor({
@@ -107,7 +105,9 @@ export default class Layer {
     this.mapSize = mapSize;
     this.layerId = layerId;
 
-    this.vectorSource.addFeatures(this.getTextsFeatures());
+    const textsFeatures = this.getTextsFeatures();
+    this.vectorSource.addFeatures(textsFeatures);
+
     this.vectorSource.addFeatures(this.getRectsFeatures());
     this.vectorSource.addFeatures(this.getOvalsFeatures());
     const imagesFeatures = this.getImagesFeatures();
@@ -127,53 +127,39 @@ export default class Layer {
 
     this.vectorLayer.set('id', layerId);
     this.vectorLayer.set('imagesFeatures', imagesFeatures);
+    this.vectorLayer.set('textsFeatures', textsFeatures);
     this.vectorLayer.set('drawImage', this.drawImage.bind(this));
     this.vectorLayer.set('drawText', this.drawText.bind(this));
   }
 
-  private getTextsFeatures = (): Array<Feature<Point>> => {
-    const textObjects = Object.values(this.texts).map(text => {
-      return new Text({
-        x: text.x,
-        y: text.y,
-        zIndex: text.z,
-        width: text.width,
-        height: text.height,
-        layer: text.layer,
-        fontColor: text.color,
-        borderColor: text.borderColor,
-        fontSize: text.fontSize,
-        text: text.notes,
-        verticalAlign: text.verticalAlign as VerticalAlign,
-        horizontalAlign: text.horizontalAlign as HorizontalAlign,
-        pointToProjection: this.pointToProjection,
-        mapInstance: this.mapInstance,
-      });
-    });
-    return textObjects.map(text => text.feature);
+  private getTextsFeatures = (): Array<Feature<Polygon>> => {
+    return Object.values(this.texts).map(text => this.getTextFeature(text));
   };
 
-  private drawText(text: LayerText): void {
+  private drawText(text: LayerTextModel): void {
     const textFeature = this.getTextFeature(text);
     this.vectorSource.addFeature(textFeature);
   }
 
-  private getTextFeature(text: LayerText): Feature<Point> {
-    const textObject = new Text({
+  private getTextFeature(text: LayerTextModel): Feature<Polygon> {
+    const textObject = new LayerText({
+      elementId: text.id,
       x: text.x,
       y: text.y,
       zIndex: text.z,
       width: text.width,
       height: text.height,
       layer: text.layer,
-      fontColor: text.color,
+      color: text.color,
       borderColor: text.borderColor,
+      backgroundColor: text.backgroundColor,
       fontSize: text.fontSize,
       text: text.notes,
       verticalAlign: text.verticalAlign as VerticalAlign,
       horizontalAlign: text.horizontalAlign as HorizontalAlign,
       pointToProjection: this.pointToProjection,
       mapInstance: this.mapInstance,
+      mapSize: this.mapSize,
     });
     return textObject.feature;
   }
diff --git a/src/components/Map/MapViewer/utils/shapes/elements/Glyph/LayerImage.ts b/src/components/Map/MapViewer/utils/shapes/layer/elements/LayerImage.ts
similarity index 54%
rename from src/components/Map/MapViewer/utils/shapes/elements/Glyph/LayerImage.ts
rename to src/components/Map/MapViewer/utils/shapes/layer/elements/LayerImage.ts
index ff893bdf..b7d306bb 100644
--- a/src/components/Map/MapViewer/utils/shapes/elements/Glyph/LayerImage.ts
+++ b/src/components/Map/MapViewer/utils/shapes/layer/elements/LayerImage.ts
@@ -3,6 +3,11 @@ import { MapInstance } from '@/types/map';
 import { MapSize } from '@/redux/map/map.types';
 import { LayerImage as LayerImageModel } from '@/types/models';
 import Glyph from '@/components/Map/MapViewer/utils/shapes/elements/Glyph/Glyph';
+import { store } from '@/redux/store';
+import { updateLayerImageObject } from '@/redux/layers/layers.thunks';
+import { layerUpdateImage } from '@/redux/layers/layers.slice';
+import { mapEditToolsSetLayerObject } from '@/redux/mapEditTools/mapEditTools.slice';
+import { BoundingBox } from '@/components/Map/MapViewer/MapViewer.types';
 
 export type LayerImageProps = {
   elementId: number;
@@ -47,11 +52,35 @@ export default class LayerImage extends Glyph {
       mapSize,
     });
     this.layer = layer;
-    this.feature.set('getGlyphData', this.getGlyphData.bind(this));
+    this.feature.set('getObjectData', this.getData.bind(this));
+    this.feature.set('save', this.save.bind(this));
     this.feature.set('layer', layer);
   }
 
-  private getGlyphData(): LayerImageModel {
+  private async save({
+    modelId,
+    boundingBox,
+  }: {
+    modelId: number;
+    boundingBox: BoundingBox;
+  }): Promise<void> {
+    const { dispatch } = store;
+    const layerImage = await dispatch(
+      updateLayerImageObject({
+        modelId,
+        layerId: this.layer,
+        ...this.getData(),
+        ...boundingBox,
+      }),
+    ).unwrap();
+    if (layerImage) {
+      dispatch(layerUpdateImage({ modelId, layerId: layerImage.layer, layerImage }));
+      dispatch(mapEditToolsSetLayerObject(layerImage));
+      this.updateElement(layerImage);
+    }
+  }
+
+  private getData(): LayerImageModel {
     return {
       id: this.elementId,
       x: this.x,
diff --git a/src/components/Map/MapViewer/utils/shapes/text/Text.test.ts b/src/components/Map/MapViewer/utils/shapes/layer/elements/LayerText.test.ts
similarity index 75%
rename from src/components/Map/MapViewer/utils/shapes/text/Text.test.ts
rename to src/components/Map/MapViewer/utils/shapes/layer/elements/LayerText.test.ts
index 2f2e145d..7db76f34 100644
--- a/src/components/Map/MapViewer/utils/shapes/text/Text.test.ts
+++ b/src/components/Map/MapViewer/utils/shapes/layer/elements/LayerText.test.ts
@@ -3,17 +3,20 @@ import { Map } from 'ol';
 import { Style } from 'ol/style';
 import View from 'ol/View';
 import { BLACK_COLOR } from '@/components/Map/MapViewer/MapViewer.constants';
-import Text, { TextProps } from '@/components/Map/MapViewer/utils/shapes/text/Text';
+import LayerText, {
+  LayerTextProps,
+} from '@/components/Map/MapViewer/utils/shapes/layer/elements/LayerText';
 import getTextStyle from '@/components/Map/MapViewer/utils/shapes/text/getTextStyle';
 import { rgbToHex } from '@/components/Map/MapViewer/utils/shapes/style/rgbToHex';
 import getTextCoords from '@/components/Map/MapViewer/utils/shapes/text/getTextCoords';
+import { DEFAULT_TILE_SIZE } from '@/constants/map';
 
-jest.mock('./getTextCoords');
-jest.mock('./getTextStyle');
-jest.mock('../style/rgbToHex');
+jest.mock('../../text/getTextCoords');
+jest.mock('../../text/getTextStyle');
+jest.mock('../../style/rgbToHex');
 
 describe('Text', () => {
-  let props: TextProps;
+  let props: LayerTextProps;
 
   beforeEach(() => {
     const dummyElement = document.createElement('div');
@@ -26,6 +29,7 @@ describe('Text', () => {
       }),
     });
     props = {
+      elementId: 1,
       x: 0,
       y: 0,
       width: 100,
@@ -34,12 +38,20 @@ describe('Text', () => {
       layer: 1,
       text: 'Test',
       fontSize: 12,
-      fontColor: BLACK_COLOR,
+      color: BLACK_COLOR,
       borderColor: BLACK_COLOR,
+      backgroundColor: BLACK_COLOR,
       verticalAlign: 'MIDDLE',
       horizontalAlign: 'CENTER',
       pointToProjection: jest.fn(({ x, y }) => [x, y]),
       mapInstance,
+      mapSize: {
+        minZoom: 1,
+        maxZoom: 9,
+        width: 0,
+        height: 0,
+        tileSize: DEFAULT_TILE_SIZE,
+      },
     };
 
     (getTextStyle as jest.Mock).mockReturnValue(new Style());
@@ -48,7 +60,7 @@ describe('Text', () => {
   });
 
   it('should apply correct styles to the feature', () => {
-    const text = new Text(props);
+    const text = new LayerText(props);
     const { feature } = text;
 
     const style = feature.getStyleFunction()?.call(text, feature, 1);
@@ -61,7 +73,7 @@ describe('Text', () => {
   });
 
   it('should hide text when the scaled font size is too small', () => {
-    const text = new Text(props);
+    const text = new LayerText(props);
     const { feature } = text;
 
     const style = feature.getStyleFunction()?.call(text, feature, 20);
diff --git a/src/components/Map/MapViewer/utils/shapes/layer/elements/LayerText.ts b/src/components/Map/MapViewer/utils/shapes/layer/elements/LayerText.ts
new file mode 100644
index 00000000..133034cf
--- /dev/null
+++ b/src/components/Map/MapViewer/utils/shapes/layer/elements/LayerText.ts
@@ -0,0 +1,315 @@
+/* eslint-disable no-magic-numbers */
+import { UsePointToProjectionResult } from '@/utils/map/usePointToProjection';
+import Style from 'ol/style/Style';
+import { Point } from 'ol/geom';
+import { Feature } from 'ol';
+import { FeatureLike } from 'ol/Feature';
+import { MapInstance } from '@/types/map';
+import { LayerText as LayerTextModel, Color } from '@/types/models';
+import { TEXT_CUTOFF_SCALE } from '@/components/Map/MapViewer/MapViewer.constants';
+import {
+  BoundingBox,
+  HorizontalAlign,
+  VerticalAlign,
+} from '@/components/Map/MapViewer/MapViewer.types';
+import getTextCoords from '@/components/Map/MapViewer/utils/shapes/text/getTextCoords';
+import getTextStyle from '@/components/Map/MapViewer/utils/shapes/text/getTextStyle';
+import { rgbToHex } from '@/components/Map/MapViewer/utils/shapes/style/rgbToHex';
+import Polygon from 'ol/geom/Polygon';
+import getStroke from '@/components/Map/MapViewer/utils/shapes/style/getStroke';
+import getStyle from '@/components/Map/MapViewer/utils/shapes/style/getStyle';
+import getScaledElementStyle from '@/components/Map/MapViewer/utils/shapes/style/getScaledElementStyle';
+import { Stroke } from 'ol/style';
+import { MapSize } from '@/redux/map/map.types';
+import getBoundingBoxFromExtent from '@/components/Map/MapViewer/utils/shapes/coords/getBoundingBoxFromExtent';
+import { Coordinate } from 'ol/coordinate';
+import { store } from '@/redux/store';
+import { updateLayerText } from '@/redux/layers/layers.thunks';
+import { layerUpdateText } from '@/redux/layers/layers.slice';
+import { mapEditToolsSetLayerObject } from '@/redux/mapEditTools/mapEditTools.slice';
+
+export interface LayerTextProps {
+  elementId: number;
+  x: number;
+  y: number;
+  width: number;
+  height: number;
+  layer: number;
+  zIndex: number;
+  text: string;
+  fontSize: number;
+  color: Color;
+  borderColor: Color;
+  backgroundColor: Color;
+  verticalAlign: VerticalAlign;
+  horizontalAlign: HorizontalAlign;
+  pointToProjection: UsePointToProjectionResult;
+  mapInstance: MapInstance;
+  mapSize: MapSize;
+}
+
+export default class LayerText {
+  elementId: number;
+
+  x: number;
+
+  y: number;
+
+  zIndex: number;
+
+  width: number;
+
+  height: number;
+
+  layer: number;
+
+  text: string;
+
+  verticalAlign: VerticalAlign;
+
+  horizontalAlign: HorizontalAlign;
+
+  backgroundColor: Color;
+
+  borderColor: Color;
+
+  color: Color;
+
+  fontSize: number;
+
+  style: Style;
+
+  polygonStyle: Style;
+
+  polygon: Polygon = new Polygon([]);
+
+  strokeStyle: Stroke;
+
+  point: Point;
+
+  feature: Feature<Polygon>;
+
+  mapSize: MapSize;
+
+  pointToProjection: UsePointToProjectionResult;
+
+  constructor({
+    elementId,
+    x,
+    y,
+    width,
+    height,
+    layer,
+    zIndex,
+    text,
+    fontSize,
+    color,
+    borderColor,
+    backgroundColor,
+    verticalAlign,
+    horizontalAlign,
+    pointToProjection,
+    mapInstance,
+    mapSize,
+  }: LayerTextProps) {
+    this.text = text;
+    this.fontSize = fontSize;
+    this.elementId = elementId;
+    this.x = x;
+    this.y = y;
+    this.zIndex = zIndex;
+    this.width = width;
+    this.height = height;
+    this.layer = layer;
+    this.text = text;
+    this.verticalAlign = verticalAlign;
+    this.horizontalAlign = horizontalAlign;
+    this.backgroundColor = backgroundColor;
+    this.borderColor = borderColor;
+    this.color = color;
+    this.mapSize = mapSize;
+    this.pointToProjection = pointToProjection;
+
+    const textCoords = getTextCoords({
+      x,
+      y,
+      height,
+      width,
+      fontSize,
+      verticalAlign,
+      horizontalAlign,
+      pointToProjection,
+    });
+    this.drawPolygon();
+    this.strokeStyle = getStroke({
+      color: rgbToHex(borderColor),
+      width: 1,
+    });
+    this.polygonStyle = getStyle({
+      geometry: this.polygon,
+      borderColor,
+      fillColor: { rgb: 0, alpha: 0 },
+      lineWidth: 1,
+      zIndex,
+    });
+
+    const textStyle = getTextStyle({
+      text,
+      fontSize,
+      color: rgbToHex(color),
+      zIndex,
+      horizontalAlign,
+    });
+    this.point = new Point(textCoords);
+    this.style = textStyle;
+    this.style.setGeometry(this.point);
+
+    this.feature = new Feature({
+      geometry: this.polygon,
+      getScale: (resolution: number): number => {
+        const maxZoom = mapInstance?.getView().get('originalMaxZoom');
+        if (maxZoom) {
+          const minResolution = mapInstance?.getView().getResolutionForZoom(maxZoom);
+          if (minResolution) {
+            return Math.round((minResolution / resolution) * 100) / 100;
+          }
+        }
+        return 1;
+      },
+      layer,
+    });
+    this.feature.setId(this.elementId);
+    this.feature.set('getObjectData', this.getData.bind(this));
+    this.feature.set('setCoordinates', this.setCoordinates.bind(this));
+    this.feature.set('refreshPolygon', this.refreshPolygon.bind(this));
+    this.feature.set('save', this.save.bind(this));
+    this.feature.set('updateElement', this.updateElement.bind(this));
+    this.feature.setStyle(this.getStyle.bind(this));
+  }
+
+  private getData(): LayerTextModel {
+    return {
+      id: this.elementId,
+      x: this.x,
+      y: this.y,
+      z: this.zIndex,
+      width: this.width,
+      height: this.height,
+      layer: this.layer,
+      fontSize: this.fontSize,
+      notes: this.text,
+      verticalAlign: this.verticalAlign,
+      horizontalAlign: this.horizontalAlign,
+      backgroundColor: this.backgroundColor,
+      borderColor: this.borderColor,
+      color: this.color,
+    };
+  }
+
+  private drawPolygon(): void {
+    this.polygon = new Polygon([
+      [
+        this.pointToProjection({ x: this.x, y: this.y }),
+        this.pointToProjection({ x: this.x + this.width, y: this.y }),
+        this.pointToProjection({ x: this.x + this.width, y: this.y + this.height }),
+        this.pointToProjection({ x: this.x, y: this.y + this.height }),
+        this.pointToProjection({ x: this.x, y: this.y }),
+      ],
+    ]);
+  }
+
+  private async save({
+    modelId,
+    boundingBox,
+  }: {
+    modelId: number;
+    boundingBox: BoundingBox;
+  }): Promise<void> {
+    const { dispatch } = store;
+    const layerText = await dispatch(
+      updateLayerText({
+        modelId,
+        layerId: this.layer,
+        ...this.getData(),
+        ...boundingBox,
+      }),
+    ).unwrap();
+    if (layerText) {
+      dispatch(layerUpdateText({ modelId, layerId: layerText.layer, layerText }));
+      dispatch(mapEditToolsSetLayerObject(layerText));
+      this.updateElement(layerText);
+    }
+  }
+
+  private refreshPolygon(): void {
+    this.drawPolygon();
+    this.polygonStyle.setGeometry(this.polygon);
+    this.feature.setGeometry(this.polygon);
+    this.feature.changed();
+  }
+
+  private refreshZIndex(): void {
+    this.polygonStyle.setZIndex(this.zIndex);
+    this.style.setZIndex(this.zIndex);
+    this.feature.changed();
+  }
+
+  private updateElement(layerText: LayerTextModel): void {
+    this.elementId = layerText.id;
+    this.x = layerText.x;
+    this.y = layerText.y;
+    this.zIndex = layerText.z;
+    this.width = layerText.width;
+    this.height = layerText.height;
+    this.text = layerText.notes;
+    this.fontSize = layerText.fontSize;
+    this.color = layerText.color;
+    this.borderColor = layerText.borderColor;
+    this.verticalAlign = layerText.verticalAlign;
+    this.horizontalAlign = layerText.horizontalAlign;
+
+    this.refreshPolygon();
+    this.refreshZIndex();
+    this.feature.changed();
+  }
+
+  private setCoordinates(coords: Coordinate[][]): void {
+    const geometry = this.polygonStyle.getGeometry();
+    if (geometry && geometry instanceof Polygon) {
+      geometry.setCoordinates(coords);
+    }
+  }
+
+  protected getStyle(feature: FeatureLike, resolution: number): Style | Array<Style> | void {
+    const getScale = feature.get('getScale');
+    let scale = 1;
+    if (getScale instanceof Function) {
+      scale = getScale(resolution);
+    }
+    const geometry = feature.getGeometry();
+    if (geometry && geometry instanceof Polygon) {
+      const polygonExtent = geometry.getExtent();
+      if (polygonExtent) {
+        const boundingBox = getBoundingBoxFromExtent(polygonExtent, this.mapSize);
+        const textCoords = getTextCoords({
+          x: boundingBox.x,
+          y: boundingBox.y,
+          height: boundingBox.height,
+          width: boundingBox.width,
+          fontSize: this.fontSize,
+          verticalAlign: this.verticalAlign,
+          horizontalAlign: this.horizontalAlign,
+          pointToProjection: this.pointToProjection,
+        });
+        this.point.setCoordinates(textCoords);
+      }
+    }
+    if (scale < TEXT_CUTOFF_SCALE) {
+      return undefined;
+    }
+    return [
+      getScaledElementStyle(this.polygonStyle, this.strokeStyle, scale),
+      getScaledElementStyle(this.style, undefined, scale),
+    ];
+  }
+}
diff --git a/src/components/Map/MapViewer/utils/shapes/layer/interaction/getTransformImageInteraction.test.ts b/src/components/Map/MapViewer/utils/shapes/layer/interaction/getTransformInteraction.test.ts
similarity index 85%
rename from src/components/Map/MapViewer/utils/shapes/layer/interaction/getTransformImageInteraction.test.ts
rename to src/components/Map/MapViewer/utils/shapes/layer/interaction/getTransformInteraction.test.ts
index c2f77a29..1cb1fec9 100644
--- a/src/components/Map/MapViewer/utils/shapes/layer/interaction/getTransformImageInteraction.test.ts
+++ b/src/components/Map/MapViewer/utils/shapes/layer/interaction/getTransformInteraction.test.ts
@@ -10,13 +10,13 @@ import { DEFAULT_TILE_SIZE } from '@/constants/map';
 import { Collection, Feature } from 'ol';
 import Transform from 'ol-ext/interaction/Transform';
 import { Geometry } from 'ol/geom';
-import getTransformImageInteraction from '@/components/Map/MapViewer/utils/shapes/layer/interaction/getTransformImageInteraction';
+import getTransformInteraction from '@/components/Map/MapViewer/utils/shapes/layer/interaction/getTransformInteraction';
 
 jest.mock('../../../../../../../utils/map/latLngToPoint', () => ({
   latLngToPoint: jest.fn(latLng => ({ x: latLng[0], y: latLng[1] })),
 }));
 
-describe('getTransformImageInteraction', () => {
+describe('getTransformInteraction', () => {
   let store = {} as ToolkitStoreWithSingleSlice<ModalState>;
   let modelIdMock: number;
   let featuresCollectionMock: Collection<Feature<Geometry>>;
@@ -39,7 +39,7 @@ describe('getTransformImageInteraction', () => {
   });
 
   it('returns a Transform interaction', () => {
-    const transformInteraction = getTransformImageInteraction(
+    const transformInteraction = getTransformInteraction(
       store.dispatch,
       mapSize,
       modelIdMock,
diff --git a/src/components/Map/MapViewer/utils/shapes/layer/interaction/getTransformImageInteraction.ts b/src/components/Map/MapViewer/utils/shapes/layer/interaction/getTransformInteraction.ts
similarity index 76%
rename from src/components/Map/MapViewer/utils/shapes/layer/interaction/getTransformImageInteraction.ts
rename to src/components/Map/MapViewer/utils/shapes/layer/interaction/getTransformInteraction.ts
index 3a1435fd..c1c8565c 100644
--- a/src/components/Map/MapViewer/utils/shapes/layer/interaction/getTransformImageInteraction.ts
+++ b/src/components/Map/MapViewer/utils/shapes/layer/interaction/getTransformInteraction.ts
@@ -5,15 +5,13 @@ import Transform from 'ol-ext/interaction/Transform';
 import { Geometry } from 'ol/geom';
 import { Collection, Feature } from 'ol';
 import BaseEvent from 'ol/events/Event';
-import { updateLayerImageObject } from '@/redux/layers/layers.thunks';
-import { layerUpdateImage } from '@/redux/layers/layers.slice';
 import getBoundingBoxFromExtent from '@/components/Map/MapViewer/utils/shapes/coords/getBoundingBoxFromExtent';
 import { MapSize } from '@/redux/map/map.types';
 import { Extent } from 'ol/extent';
 import { mapEditToolsSetLayerObject } from '@/redux/mapEditTools/mapEditTools.slice';
 import { openDrawer } from '@/redux/drawer/drawer.slice';
 
-export default function getTransformImageInteraction(
+export default function getTransformInteraction(
   dispatch: AppDispatch,
   mapSize: MapSize,
   modelId: number,
@@ -86,6 +84,11 @@ export default function getTransformImageInteraction(
       newGeometry.scale(1, -1);
       feature.setGeometry(newGeometry);
       transform.setSelection(new Collection([feature]));
+      return;
+    }
+    const setCoordinates = feature.get('setCoordinates');
+    if (geometry instanceof Polygon && setCoordinates instanceof Function) {
+      setCoordinates(geometry.getCoordinates());
     }
   });
 
@@ -96,10 +99,10 @@ export default function getTransformImageInteraction(
       dispatch(mapEditToolsSetLayerObject(null));
       return;
     }
-    const getGlyphData = features.item(0).get('getGlyphData');
-    if (getGlyphData && getGlyphData instanceof Function) {
-      const glyphData = getGlyphData();
-      dispatch(mapEditToolsSetLayerObject(glyphData));
+    const getObjectData = features.item(0).get('getObjectData');
+    if (getObjectData && getObjectData instanceof Function) {
+      const objectData = getObjectData();
+      dispatch(mapEditToolsSetLayerObject(objectData));
       dispatch(openDrawer('layers'));
     }
   });
@@ -107,30 +110,13 @@ export default function getTransformImageInteraction(
   transform.on(['scaleend', 'translateend'], async (event: BaseEvent | Event): Promise<void> => {
     const transformEvent = event as unknown as { feature: Feature };
     const { feature } = transformEvent;
-    const setCoordinates = feature.get('setCoordinates');
-    const getGlyphData = feature.get('getGlyphData');
     const refreshPolygon = feature.get('refreshPolygon');
+    const save = feature.get('save');
     const geometry = feature.getGeometry();
-    if (geometry && getGlyphData instanceof Function) {
-      const glyphData = getGlyphData();
+    if (geometry && save instanceof Function) {
       try {
         const boundingBox = getBoundingBoxFromExtent(geometry.getExtent(), mapSize);
-        const layerImage = await dispatch(
-          updateLayerImageObject({
-            modelId,
-            layerId: glyphData.layer,
-            ...glyphData,
-            ...boundingBox,
-          }),
-        ).unwrap();
-        if (layerImage) {
-          dispatch(layerUpdateImage({ modelId, layerId: layerImage.layer, layerImage }));
-          dispatch(mapEditToolsSetLayerObject(layerImage));
-        }
-        if (geometry instanceof Polygon && setCoordinates instanceof Function) {
-          setCoordinates(geometry.getCoordinates());
-          geometry.changed();
-        }
+        save({ modelId, boundingBox });
       } catch {
         if (refreshPolygon instanceof Function) {
           refreshPolygon();
diff --git a/src/components/Map/MapViewer/utils/shapes/elements/Glyph/updateGlyph.ts b/src/components/Map/MapViewer/utils/shapes/layer/utils/updateElement.ts
similarity index 60%
rename from src/components/Map/MapViewer/utils/shapes/elements/Glyph/updateGlyph.ts
rename to src/components/Map/MapViewer/utils/shapes/layer/utils/updateElement.ts
index 05418973..88f50d44 100644
--- a/src/components/Map/MapViewer/utils/shapes/elements/Glyph/updateGlyph.ts
+++ b/src/components/Map/MapViewer/utils/shapes/layer/utils/updateElement.ts
@@ -1,20 +1,20 @@
 import VectorSource from 'ol/source/Vector';
-import { LayerImage } from '@/types/models';
+import { LayerImage, LayerText } from '@/types/models';
 import { MapInstance } from '@/types/map';
 
-export default function updateGlyph(
+export default function updateElement(
   mapInstance: MapInstance,
   layerId: number,
-  layerImage: LayerImage,
+  layerObject: LayerImage | LayerText,
 ): void {
   mapInstance?.getAllLayers().forEach(layer => {
     if (layer.get('id') === layerId) {
       const source = layer.getSource();
       if (source instanceof VectorSource) {
-        const feature = source.getFeatureById(layerImage.id);
-        const update = feature?.get('update');
+        const feature = source.getFeatureById(layerObject.id);
+        const update = feature?.get('updateElement');
         if (update && update instanceof Function) {
-          update(layerImage);
+          update(layerObject);
           feature.changed();
         }
       }
diff --git a/src/components/Map/MapViewer/utils/shapes/text/Text.ts b/src/components/Map/MapViewer/utils/shapes/text/Text.ts
deleted file mode 100644
index c1bc5799..00000000
--- a/src/components/Map/MapViewer/utils/shapes/text/Text.ts
+++ /dev/null
@@ -1,145 +0,0 @@
-/* eslint-disable no-magic-numbers */
-import { UsePointToProjectionResult } from '@/utils/map/usePointToProjection';
-import Style from 'ol/style/Style';
-import { Point } from 'ol/geom';
-import { Feature } from 'ol';
-import { FeatureLike } from 'ol/Feature';
-import { MapInstance } from '@/types/map';
-import { Color } from '@/types/models';
-import { TEXT_CUTOFF_SCALE } from '@/components/Map/MapViewer/MapViewer.constants';
-import { HorizontalAlign, VerticalAlign } from '@/components/Map/MapViewer/MapViewer.types';
-import getTextCoords from '@/components/Map/MapViewer/utils/shapes/text/getTextCoords';
-import getTextStyle from '@/components/Map/MapViewer/utils/shapes/text/getTextStyle';
-import { rgbToHex } from '@/components/Map/MapViewer/utils/shapes/style/rgbToHex';
-import Polygon from 'ol/geom/Polygon';
-import getStroke from '@/components/Map/MapViewer/utils/shapes/style/getStroke';
-import getStyle from '@/components/Map/MapViewer/utils/shapes/style/getStyle';
-import getScaledElementStyle from '@/components/Map/MapViewer/utils/shapes/style/getScaledElementStyle';
-import { Stroke } from 'ol/style';
-
-export interface TextProps {
-  x: number;
-  y: number;
-  width: number;
-  height: number;
-  layer: number;
-  zIndex: number;
-  text: string;
-  fontSize: number;
-  fontColor: Color;
-  borderColor: Color;
-  verticalAlign: VerticalAlign;
-  horizontalAlign: HorizontalAlign;
-  pointToProjection: UsePointToProjectionResult;
-  mapInstance: MapInstance;
-}
-
-export default class Text {
-  text: string;
-
-  fontSize: number;
-
-  style: Style;
-
-  polygonStyle: Style;
-
-  strokeStyle: Stroke;
-
-  point: Point;
-
-  feature: Feature<Point>;
-
-  constructor({
-    x,
-    y,
-    width,
-    height,
-    layer,
-    zIndex,
-    text,
-    fontSize,
-    fontColor,
-    borderColor,
-    verticalAlign,
-    horizontalAlign,
-    pointToProjection,
-    mapInstance,
-  }: TextProps) {
-    this.text = text;
-    this.fontSize = fontSize;
-
-    const textCoords = getTextCoords({
-      x,
-      y,
-      height,
-      width,
-      fontSize,
-      verticalAlign,
-      horizontalAlign,
-      pointToProjection,
-    });
-    const borderPolygon = new Polygon([
-      [
-        pointToProjection({ x, y }),
-        pointToProjection({ x: x + width, y }),
-        pointToProjection({ x: x + width, y: y + height }),
-        pointToProjection({ x, y: y + height }),
-        pointToProjection({ x, y }),
-      ],
-    ]);
-    this.strokeStyle = getStroke({
-      color: rgbToHex(borderColor),
-      width: 1,
-    });
-    this.polygonStyle = getStyle({
-      geometry: borderPolygon,
-      borderColor,
-      fillColor: { rgb: 0, alpha: 0 },
-      lineWidth: 1,
-      zIndex,
-    });
-
-    const textStyle = getTextStyle({
-      text,
-      fontSize,
-      color: rgbToHex(fontColor),
-      zIndex,
-      horizontalAlign,
-    });
-    this.point = new Point(textCoords);
-    this.style = textStyle;
-    this.style.setGeometry(this.point);
-
-    this.feature = new Feature({
-      geometry: this.point,
-      getScale: (resolution: number): number => {
-        const maxZoom = mapInstance?.getView().get('originalMaxZoom');
-        if (maxZoom) {
-          const minResolution = mapInstance?.getView().getResolutionForZoom(maxZoom);
-          if (minResolution) {
-            return Math.round((minResolution / resolution) * 100) / 100;
-          }
-        }
-        return 1;
-      },
-      layer,
-    });
-
-    this.feature.setStyle(this.getStyle.bind(this));
-  }
-
-  protected getStyle(feature: FeatureLike, resolution: number): Style | Array<Style> | void {
-    const getScale = feature.get('getScale');
-    let scale = 1;
-    if (getScale instanceof Function) {
-      scale = getScale(resolution);
-    }
-    if (scale < TEXT_CUTOFF_SCALE) {
-      return undefined;
-    }
-    return [
-      getScaledElementStyle(this.polygonStyle, this.strokeStyle, scale),
-      getScaledElementStyle(this.style, undefined, scale),
-    ];
-  }
-}
diff --git a/src/components/Map/MapViewer/utils/shapes/text/getTextCoords.ts b/src/components/Map/MapViewer/utils/shapes/text/getTextCoords.ts
index e3224fc9..26acfb6b 100644
--- a/src/components/Map/MapViewer/utils/shapes/text/getTextCoords.ts
+++ b/src/components/Map/MapViewer/utils/shapes/text/getTextCoords.ts
@@ -12,6 +12,7 @@ export default function getTextCoords({
   verticalAlign,
   horizontalAlign,
   pointToProjection,
+  useProjection = true,
 }: {
   x: number;
   y: number;
@@ -20,7 +21,8 @@ export default function getTextCoords({
   fontSize: number;
   verticalAlign: VerticalAlign;
   horizontalAlign: HorizontalAlign;
-  pointToProjection: UsePointToProjectionResult;
+  pointToProjection?: UsePointToProjectionResult;
+  useProjection?: boolean;
 }): Coordinate {
   const minX = x;
   const maxX = x + width;
@@ -41,5 +43,8 @@ export default function getTextCoords({
     textX = maxX;
   }
 
-  return pointToProjection({ x: textX, y: textY });
+  if (useProjection && pointToProjection) {
+    return pointToProjection({ x: textX, y: textY });
+  }
+  return [textX, textY];
 }
diff --git a/src/components/Map/MapViewer/utils/websocket/processLayerImage.ts b/src/components/Map/MapViewer/utils/websocket/processLayerImage.ts
index 84018d80..6fd6ec3a 100644
--- a/src/components/Map/MapViewer/utils/websocket/processLayerImage.ts
+++ b/src/components/Map/MapViewer/utils/websocket/processLayerImage.ts
@@ -2,7 +2,7 @@ import { WebSocketEntityUpdateInterface } from '@/utils/websocket-entity-updates
 import { store } from '@/redux/store';
 import { ENTITY_OPERATION_TYPES } from '@/utils/websocket-entity-updates/webSocketEntityUpdates.constants';
 import { getLayerImage } from '@/redux/layers/layers.thunks';
-import updateGlyph from '@/components/Map/MapViewer/utils/shapes/elements/Glyph/updateGlyph';
+import updateElement from '@/components/Map/MapViewer/utils/shapes/layer/utils/updateElement';
 import { MapInstance } from '@/types/map';
 import drawElementOnLayer from '@/components/Map/MapViewer/utils/shapes/layer/utils/drawElementOnLayer';
 import { layerDeleteImage } from '@/redux/layers/layers.slice';
@@ -38,7 +38,7 @@ export default async function processLayerImage({
         drawFunctionKey: 'drawImage',
       });
     } else {
-      updateGlyph(mapInstance, data.layerId, resultImage);
+      updateElement(mapInstance, data.layerId, resultImage);
     }
   } else if (data.type === ENTITY_OPERATION_TYPES.ENTITY_DELETED) {
     dispatch(
diff --git a/src/components/Map/MapViewer/utils/websocket/processLayerText.ts b/src/components/Map/MapViewer/utils/websocket/processLayerText.ts
index f31697c4..e1740c97 100644
--- a/src/components/Map/MapViewer/utils/websocket/processLayerText.ts
+++ b/src/components/Map/MapViewer/utils/websocket/processLayerText.ts
@@ -4,6 +4,9 @@ import { ENTITY_OPERATION_TYPES } from '@/utils/websocket-entity-updates/webSock
 import { getLayerText } from '@/redux/layers/layers.thunks';
 import { MapInstance } from '@/types/map';
 import drawElementOnLayer from '@/components/Map/MapViewer/utils/shapes/layer/utils/drawElementOnLayer';
+import { layerDeleteText } from '@/redux/layers/layers.slice';
+import removeElementFromLayer from '@/components/Map/MapViewer/utils/shapes/elements/removeElementFromLayer';
+import updateElement from '@/components/Map/MapViewer/utils/shapes/layer/utils/updateElement';
 
 export default async function processLayerText({
   data,
@@ -13,7 +16,10 @@ export default async function processLayerText({
   mapInstance: MapInstance;
 }): Promise<void> {
   const { dispatch } = store;
-  if (data.type === ENTITY_OPERATION_TYPES.ENTITY_CREATED) {
+  if (
+    data.type === ENTITY_OPERATION_TYPES.ENTITY_CREATED ||
+    data.type === ENTITY_OPERATION_TYPES.ENTITY_UPDATED
+  ) {
     const resultText = await dispatch(
       getLayerText({
         modelId: data.mapId,
@@ -24,11 +30,24 @@ export default async function processLayerText({
     if (!resultText) {
       return;
     }
-    drawElementOnLayer({
-      mapInstance,
-      activeLayer: data.layerId,
-      object: resultText,
-      drawFunctionKey: 'drawText',
-    });
+    if (data.type === ENTITY_OPERATION_TYPES.ENTITY_CREATED) {
+      drawElementOnLayer({
+        mapInstance,
+        activeLayer: data.layerId,
+        object: resultText,
+        drawFunctionKey: 'drawText',
+      });
+    } else {
+      updateElement(mapInstance, data.layerId, resultText);
+    }
+  } else if (data.type === ENTITY_OPERATION_TYPES.ENTITY_DELETED) {
+    dispatch(
+      layerDeleteText({
+        modelId: data.mapId,
+        layerId: data.layerId,
+        textId: data.entityId,
+      }),
+    );
+    removeElementFromLayer({ mapInstance, layerId: data.layerId, featureId: data.entityId });
   }
 }
diff --git a/src/models/layerTextSchema.ts b/src/models/layerTextSchema.ts
index 0ec90665..a575b139 100644
--- a/src/models/layerTextSchema.ts
+++ b/src/models/layerTextSchema.ts
@@ -11,8 +11,8 @@ export const layerTextSchema = z.object({
   layer: z.number(),
   fontSize: z.number(),
   notes: z.string(),
-  verticalAlign: z.string(),
-  horizontalAlign: z.string(),
+  verticalAlign: z.enum(['TOP', 'MIDDLE', 'BOTTOM']),
+  horizontalAlign: z.enum(['LEFT', 'RIGHT', 'CENTER', 'END', 'START']),
   backgroundColor: colorSchema,
   borderColor: colorSchema,
   color: colorSchema,
diff --git a/src/redux/apiPath.ts b/src/redux/apiPath.ts
index 9eb33c02..18186d6f 100644
--- a/src/redux/apiPath.ts
+++ b/src/redux/apiPath.ts
@@ -64,6 +64,10 @@ export const apiPath = {
     `projects/${PROJECT_ID}/maps/${modelId}/layers/${layerId}/texts/`,
   getLayerText: (modelId: number, layerId: number, imageId: number | string): string =>
     `projects/${PROJECT_ID}/maps/${modelId}/layers/${layerId}/texts/${imageId}`,
+  updateLayerText: (modelId: number, layerId: number, textId: number | string): string =>
+    `projects/${PROJECT_ID}/maps/${modelId}/layers/${layerId}/texts/${textId}`,
+  removeLayerText: (modelId: number, layerId: number, textId: number | string): string =>
+    `projects/${PROJECT_ID}/maps/${modelId}/layers/${layerId}/texts/${textId}`,
   getLayer: (modelId: number, layerId: number): string =>
     `projects/${PROJECT_ID}/maps/${modelId}/layers/${layerId}`,
   getGlyphImage: (glyphId: number): string =>
diff --git a/src/redux/layers/layers.reducers.ts b/src/redux/layers/layers.reducers.ts
index 0213d714..238a3441 100644
--- a/src/redux/layers/layers.reducers.ts
+++ b/src/redux/layers/layers.reducers.ts
@@ -198,3 +198,35 @@ export const layerAddTextReducer = (
   }
   layer.texts[layerText.id] = layerText;
 };
+
+export const layerUpdateTextReducer = (
+  state: LayersState,
+  action: PayloadAction<{ modelId: number; layerId: number; layerText: LayerText }>,
+): void => {
+  const { modelId, layerId, layerText } = action.payload;
+  const { data } = state[modelId];
+  if (!data) {
+    return;
+  }
+  const layer = data.layers.find(layerState => layerState.details.id === layerId);
+  if (!layer) {
+    return;
+  }
+  layer.texts[layerText.id] = layerText;
+};
+
+export const layerDeleteTextReducer = (
+  state: LayersState,
+  action: PayloadAction<{ modelId: number; layerId: number; textId: number }>,
+): void => {
+  const { modelId, layerId, textId } = action.payload;
+  const { data } = state[modelId];
+  if (!data) {
+    return;
+  }
+  const layer = data.layers.find(layerState => layerState.details.id === layerId);
+  if (!layer) {
+    return;
+  }
+  delete layer.texts[textId];
+};
diff --git a/src/redux/layers/layers.slice.ts b/src/redux/layers/layers.slice.ts
index dcd20ceb..871012fc 100644
--- a/src/redux/layers/layers.slice.ts
+++ b/src/redux/layers/layers.slice.ts
@@ -12,6 +12,8 @@ import {
   setDrawLayerReducer,
   setLayerToInactiveReducer,
   setLayerToActiveReducer,
+  layerDeleteTextReducer,
+  layerUpdateTextReducer,
 } from '@/redux/layers/layers.reducers';
 
 export const layersSlice = createSlice({
@@ -25,6 +27,8 @@ export const layersSlice = createSlice({
     layerUpdateImage: layerUpdateImageReducer,
     layerDeleteImage: layerDeleteImageReducer,
     layerAddText: layerAddTextReducer,
+    layerUpdateText: layerUpdateTextReducer,
+    layerDeleteText: layerDeleteTextReducer,
     setDrawLayer: setDrawLayerReducer,
   },
   extraReducers: builder => {
@@ -42,6 +46,8 @@ export const {
   layerUpdateImage,
   layerDeleteImage,
   layerAddText,
+  layerUpdateText,
+  layerDeleteText,
   setDrawLayer,
 } = layersSlice.actions;
 
diff --git a/src/redux/layers/layers.thunks.ts b/src/redux/layers/layers.thunks.ts
index 847d84d2..66035fd8 100644
--- a/src/redux/layers/layers.thunks.ts
+++ b/src/redux/layers/layers.thunks.ts
@@ -1,7 +1,7 @@
 /* eslint-disable no-magic-numbers */
 import { z as zod } from 'zod';
 import { apiPath } from '@/redux/apiPath';
-import { Layer, LayerImage, Layers, LayerText } from '@/types/models';
+import { Color, Layer, LayerImage, Layers, LayerText } from '@/types/models';
 import { validateDataUsingZodSchema } from '@/utils/validateDataUsingZodSchema';
 import { createAsyncThunk } from '@reduxjs/toolkit';
 import { ThunkConfig } from '@/types/store';
@@ -22,7 +22,11 @@ import { layerLineSchema } from '@/models/layerLineSchema';
 import { layerImageSchema } from '@/models/layerImageSchema';
 import arrayToKeyValue from '@/utils/array/arrayToKeyValue';
 import { LayerTextFactoryForm } from '@/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextFactory.types';
-import { BoundingBox } from '@/components/Map/MapViewer/MapViewer.types';
+import {
+  BoundingBox,
+  HorizontalAlign,
+  VerticalAlign,
+} from '@/components/Map/MapViewer/MapViewer.types';
 
 export const getLayer = createAsyncThunk<
   Layer | null,
@@ -307,3 +311,81 @@ export const getLayerText = createAsyncThunk<
     return Promise.reject(getError({ error }));
   }
 });
+
+export const removeLayerText = createAsyncThunk<
+  null,
+  { modelId: number; layerId: number; textId: number },
+  ThunkConfig
+>('layers/removeLayerText', async ({ modelId, layerId, textId }) => {
+  try {
+    await axiosInstanceNewAPI.delete<void>(apiPath.removeLayerText(modelId, layerId, textId));
+    return null;
+  } catch (error) {
+    return Promise.reject(getError({ error }));
+  }
+});
+
+export const updateLayerText = createAsyncThunk<
+  LayerText | null,
+  {
+    modelId: number;
+    layerId: number;
+    id: number;
+    x: number;
+    y: number;
+    z: number;
+    width: number;
+    height: number;
+    fontSize: number;
+    notes: string;
+    verticalAlign: VerticalAlign;
+    horizontalAlign: HorizontalAlign;
+    color: Color;
+    borderColor: Color;
+  },
+  ThunkConfig
+>(
+  'layers/updateLayerText',
+  async ({
+    modelId,
+    layerId,
+    id,
+    x,
+    y,
+    z,
+    width,
+    height,
+    fontSize,
+    notes,
+    verticalAlign,
+    horizontalAlign,
+    color,
+    borderColor,
+  }) => {
+    try {
+      const { data } = await axiosInstanceNewAPI.put<LayerText>(
+        apiPath.updateLayerText(modelId, layerId, id),
+        {
+          x,
+          y,
+          z,
+          width,
+          height,
+          fontSize,
+          notes,
+          verticalAlign,
+          horizontalAlign,
+          color,
+          borderColor,
+        },
+      );
+      const isDataValid = validateDataUsingZodSchema(data, layerTextSchema);
+      if (isDataValid) {
+        return data;
+      }
+      return null;
+    } catch (error) {
+      return Promise.reject(getError({ error }));
+    }
+  },
+);
diff --git a/src/redux/mapEditTools/mapEditTools.mock.ts b/src/redux/mapEditTools/mapEditTools.mock.ts
index d6fe529c..fbbacec7 100644
--- a/src/redux/mapEditTools/mapEditTools.mock.ts
+++ b/src/redux/mapEditTools/mapEditTools.mock.ts
@@ -2,5 +2,5 @@ import { MapEditToolsState } from '@/redux/mapEditTools/mapEditTools.types';
 
 export const MAP_EDIT_TOOLS_STATE_INITIAL_MOCK: MapEditToolsState = {
   activeAction: null,
-  layerImageObject: null,
+  layerObject: null,
 };
diff --git a/src/redux/mapEditTools/mapEditTools.reducers.ts b/src/redux/mapEditTools/mapEditTools.reducers.ts
index da3f5f7f..d45e719f 100644
--- a/src/redux/mapEditTools/mapEditTools.reducers.ts
+++ b/src/redux/mapEditTools/mapEditTools.reducers.ts
@@ -2,7 +2,7 @@
 import { PayloadAction } from '@reduxjs/toolkit';
 import { MAP_EDIT_ACTIONS } from '@/redux/mapEditTools/mapEditTools.constants';
 import { MapEditToolsState } from '@/redux/mapEditTools/mapEditTools.types';
-import { LayerImage } from '@/types/models';
+import { LayerImage, LayerText } from '@/types/models';
 
 export const mapEditToolsSetActiveActionReducer = (
   state: MapEditToolsState,
@@ -13,7 +13,7 @@ export const mapEditToolsSetActiveActionReducer = (
 
 export const mapEditToolsSetLayerObjectReducer = (
   state: MapEditToolsState,
-  action: PayloadAction<LayerImage | null>,
+  action: PayloadAction<LayerImage | LayerText | null>,
 ): void => {
-  state.layerImageObject = action.payload;
+  state.layerObject = action.payload;
 };
diff --git a/src/redux/mapEditTools/mapEditTools.selectors.ts b/src/redux/mapEditTools/mapEditTools.selectors.ts
index 2b29bd35..d3ea7d12 100644
--- a/src/redux/mapEditTools/mapEditTools.selectors.ts
+++ b/src/redux/mapEditTools/mapEditTools.selectors.ts
@@ -9,9 +9,9 @@ export const mapEditToolsActiveActionSelector = createSelector(
   state => state.activeAction,
 );
 
-export const mapEditToolsLayerImageObjectSelector = createSelector(
+export const mapEditToolsLayerObjectSelector = createSelector(
   mapEditToolsSelector,
-  state => state.layerImageObject,
+  state => state.layerObject,
 );
 
 export const isMapEditToolsActiveSelector = createSelector(mapEditToolsSelector, state =>
diff --git a/src/redux/mapEditTools/mapEditTools.types.ts b/src/redux/mapEditTools/mapEditTools.types.ts
index e141e6b8..4c216c40 100644
--- a/src/redux/mapEditTools/mapEditTools.types.ts
+++ b/src/redux/mapEditTools/mapEditTools.types.ts
@@ -1,7 +1,7 @@
 import { MAP_EDIT_ACTIONS } from '@/redux/mapEditTools/mapEditTools.constants';
-import { LayerImage } from '@/types/models';
+import { LayerImage, LayerText } from '@/types/models';
 
 export type MapEditToolsState = {
   activeAction: keyof typeof MAP_EDIT_ACTIONS | null;
-  layerImageObject: LayerImage | null;
+  layerObject: LayerImage | LayerText | null;
 };
-- 
GitLab


From 09dff5302aad6a606bc317acb391aa0a7b2cc0bf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mi=C5=82osz=20Grocholewski?= <m.grocholewski@atcomp.pl>
Date: Mon, 17 Feb 2025 13:08:07 +0100
Subject: [PATCH 2/8] feat(layer-text): Add editing text notes, font size,
 color alignment etc.

---
 ...rImageObjectEditFactoryModal.component.tsx |   2 +-
 .../LayerTextEditFactoryModal.component.tsx   | 109 ++++++++++++++++++
 .../LayerTextFactory.constants.ts             |  12 +-
 .../LayerTextFactory.types.ts                 |   5 +-
 .../LayerTextForm.component.tsx               |   4 +-
 .../FunctionalArea/Modal/Modal.component.tsx  |   6 +
 .../ModalLayout/ModalLayout.component.tsx     |   3 +-
 .../LayersDrawerObjectsList.component.tsx     |  59 +++++++++-
 .../Map/MapViewer/MapViewer.types.ts          |   2 +-
 .../utils/shapes/elements/Glyph/Glyph.ts      |  52 +++++----
 .../utils/shapes/layer/elements/LayerText.ts  |  56 ++++-----
 src/models/bioEntitySchema.ts                 |   2 +-
 src/models/layerTextSchema.ts                 |   2 +-
 src/models/modelElementModificationSchema.ts  |   2 +-
 src/models/modelElementSchema.ts              |   2 +-
 src/redux/modal/modal.reducers.ts             |   6 +
 src/redux/modal/modal.slice.ts                |   3 +
 src/types/modal.ts                            |   3 +-
 18 files changed, 257 insertions(+), 73 deletions(-)
 create mode 100644 src/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextEditFactoryModal.component.tsx

diff --git a/src/components/FunctionalArea/Modal/LayerImageObjectModal/LayerImageObjectEditFactoryModal.component.tsx b/src/components/FunctionalArea/Modal/LayerImageObjectModal/LayerImageObjectEditFactoryModal.component.tsx
index dc280845..b90d5b25 100644
--- a/src/components/FunctionalArea/Modal/LayerImageObjectModal/LayerImageObjectEditFactoryModal.component.tsx
+++ b/src/components/FunctionalArea/Modal/LayerImageObjectModal/LayerImageObjectEditFactoryModal.component.tsx
@@ -69,7 +69,7 @@ export const LayerImageObjectEditFactoryModal: React.FC = () => {
       const typedError = error as SerializedError;
       showToast({
         type: 'error',
-        message: typedError.message || 'An error occurred while adding a new image',
+        message: typedError.message || 'An error occurred while editing the layer image',
       });
     } finally {
       setIsSending(false);
diff --git a/src/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextEditFactoryModal.component.tsx b/src/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextEditFactoryModal.component.tsx
new file mode 100644
index 00000000..c73e9d93
--- /dev/null
+++ b/src/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextEditFactoryModal.component.tsx
@@ -0,0 +1,109 @@
+/* eslint-disable no-magic-numbers */
+import React, { useState } from 'react';
+import './LayerTextFactoryModal.styles.css';
+import { LayerTextForm } from '@/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextForm.component';
+import { LoadingIndicator } from '@/shared/LoadingIndicator';
+import { Button } from '@/shared/Button';
+import { LayerTextFactoryForm } from '@/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextFactory.types';
+import { Color } from '@/types/models';
+import { useAppSelector } from '@/redux/hooks/useAppSelector';
+import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
+import { currentModelIdSelector } from '@/redux/models/models.selectors';
+import { showToast } from '@/utils/showToast';
+import { closeModal } from '@/redux/modal/modal.slice';
+import { SerializedError } from '@reduxjs/toolkit';
+import { updateLayerText } from '@/redux/layers/layers.thunks';
+import { layerUpdateText } from '@/redux/layers/layers.slice';
+import { useMapInstance } from '@/utils/context/mapInstanceContext';
+import { mapEditToolsSetLayerObject } from '@/redux/mapEditTools/mapEditTools.slice';
+import { mapEditToolsLayerObjectSelector } from '@/redux/mapEditTools/mapEditTools.selectors';
+import updateElement from '@/components/Map/MapViewer/utils/shapes/layer/utils/updateElement';
+
+export const LayerTextEditFactoryModal: React.FC = () => {
+  const layerObject = useAppSelector(mapEditToolsLayerObjectSelector);
+  const currentModelId = useAppSelector(currentModelIdSelector);
+  const dispatch = useAppDispatch();
+  const { mapInstance } = useMapInstance();
+
+  if (!layerObject || !('notes' in layerObject)) {
+    throw new Error('Invalid layer text object');
+  }
+
+  const [isSending, setIsSending] = useState<boolean>(false);
+  const [data, setData] = useState<LayerTextFactoryForm>({
+    notes: layerObject.notes,
+    fontSize: layerObject.fontSize,
+    horizontalAlign: layerObject.horizontalAlign,
+    verticalAlign: layerObject.verticalAlign,
+    color: layerObject.color,
+    borderColor: layerObject.borderColor,
+  });
+
+  const handleSubmit = async (): Promise<void> => {
+    if (!layerObject) {
+      return;
+    }
+    try {
+      const layerText = await dispatch(
+        updateLayerText({
+          modelId: currentModelId,
+          layerId: layerObject.layer,
+          id: layerObject.id,
+          x: layerObject.x,
+          y: layerObject.y,
+          z: layerObject.z,
+          width: layerObject.width,
+          height: layerObject.height,
+          notes: data.notes,
+          fontSize: data.fontSize,
+          horizontalAlign: data.horizontalAlign,
+          verticalAlign: data.verticalAlign,
+          color: data.color,
+          borderColor: data.borderColor,
+        }),
+      ).unwrap();
+
+      if (layerText) {
+        dispatch(layerUpdateText({ modelId: currentModelId, layerId: layerText.layer, layerText }));
+        dispatch(mapEditToolsSetLayerObject(layerText));
+        updateElement(mapInstance, layerText.layer, layerText);
+      }
+      showToast({
+        type: 'success',
+        message: 'The text has been successfully updated',
+      });
+      dispatch(closeModal());
+    } catch (error) {
+      const typedError = error as SerializedError;
+      showToast({
+        type: 'error',
+        message: typedError.message || 'An error occurred while editing the layer text',
+      });
+    } finally {
+      setIsSending(false);
+    }
+  };
+
+  const changeValues = (value: string | number | Color, key: string): void => {
+    setData(prevData => ({ ...prevData, [key]: value }));
+  };
+
+  return (
+    <div className="relative w-[900px] border border-t-[#E1E0E6] bg-white p-[24px]">
+      {isSending && (
+        <div className="c-layer-text-factory-modal-loader">
+          <LoadingIndicator width={44} height={44} />
+        </div>
+      )}
+      <LayerTextForm onChange={changeValues} data={data} />
+      <hr className="py-2" />
+      <Button
+        type="button"
+        onClick={handleSubmit}
+        className="justify-center self-end justify-self-end text-base font-medium"
+      >
+        Submit
+      </Button>
+    </div>
+  );
+};
diff --git a/src/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextFactory.constants.ts b/src/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextFactory.constants.ts
index feddd690..cbee5e1c 100644
--- a/src/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextFactory.constants.ts
+++ b/src/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextFactory.constants.ts
@@ -1,21 +1,21 @@
 /* eslint-disable no-magic-numbers */
 
+import { HorizontalAlign, VerticalAlign } from '@/components/Map/MapViewer/MapViewer.types';
+
 export const TEXT_FONT_SIZES = [8, 9, 10, 11, 12, 14, 16, 18, 24, 30, 36, 48, 60, 72, 96];
 
 export const TEXT_HORIZONTAL_ALIGNMENTS = [
   { id: 'LEFT', name: 'left' },
   { id: 'RIGHT', name: 'right' },
   { id: 'CENTER', name: 'center' },
-  { id: 'END', name: 'end' },
-  { id: 'START', name: 'start' },
-];
+] as const;
 
 export const TEXT_VERTICAL_ALIGNMENTS = [
   { id: 'TOP', name: 'top' },
   { id: 'MIDDLE', name: 'middle' },
   { id: 'BOTTOM', name: 'bottom' },
-];
+] as const;
 
 export const DEFAULT_TEXT_FONT_SIZE = 12;
-export const DEFAULT_HORIZONTAL_ALIGNMENT = TEXT_HORIZONTAL_ALIGNMENTS[0].id;
-export const DEFAULT_VERTICAL_ALIGNMENT = TEXT_VERTICAL_ALIGNMENTS[0].id;
+export const DEFAULT_HORIZONTAL_ALIGNMENT: HorizontalAlign = TEXT_HORIZONTAL_ALIGNMENTS[0].id;
+export const DEFAULT_VERTICAL_ALIGNMENT: VerticalAlign = TEXT_VERTICAL_ALIGNMENTS[0].id;
diff --git a/src/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextFactory.types.ts b/src/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextFactory.types.ts
index bb47feaa..231eb942 100644
--- a/src/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextFactory.types.ts
+++ b/src/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextFactory.types.ts
@@ -1,10 +1,11 @@
 import { Color } from '@/types/models';
+import { HorizontalAlign, VerticalAlign } from '@/components/Map/MapViewer/MapViewer.types';
 
 export type LayerTextFactoryForm = {
   notes: string;
   fontSize: number;
-  horizontalAlign: string;
-  verticalAlign: string;
+  horizontalAlign: HorizontalAlign;
+  verticalAlign: VerticalAlign;
   color: Color;
   borderColor: Color;
 };
diff --git a/src/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextForm.component.tsx b/src/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextForm.component.tsx
index 22bcde3c..2dac649b 100644
--- a/src/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextForm.component.tsx
+++ b/src/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextForm.component.tsx
@@ -41,7 +41,7 @@ export const LayerTextForm = ({ data, onChange }: LayerTextFormProps): React.JSX
         <div>
           <span>Horizontal alignment:</span>
           <Select
-            options={TEXT_HORIZONTAL_ALIGNMENTS}
+            options={[...TEXT_HORIZONTAL_ALIGNMENTS]}
             selectedId={data.horizontalAlign}
             testId="horizontal-alignment-select"
             onChange={value => onChange(value, 'horizontalAlign')}
@@ -50,7 +50,7 @@ export const LayerTextForm = ({ data, onChange }: LayerTextFormProps): React.JSX
         <div>
           <span>Vertical alignment:</span>
           <Select
-            options={TEXT_VERTICAL_ALIGNMENTS}
+            options={[...TEXT_VERTICAL_ALIGNMENTS]}
             selectedId={data.verticalAlign}
             testId="vertical-alignment-select"
             onChange={value => onChange(value, 'verticalAlign')}
diff --git a/src/components/FunctionalArea/Modal/Modal.component.tsx b/src/components/FunctionalArea/Modal/Modal.component.tsx
index 6cc342ee..bbd8c7d5 100644
--- a/src/components/FunctionalArea/Modal/Modal.component.tsx
+++ b/src/components/FunctionalArea/Modal/Modal.component.tsx
@@ -10,6 +10,7 @@ import {
   LayerImageObjectFactoryModal,
 } from '@/components/FunctionalArea/Modal/LayerImageObjectModal';
 import { LayerTextFactoryModal } from '@/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextFactoryModal.component';
+import { LayerTextEditFactoryModal } from '@/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextEditFactoryModal.component';
 import { EditOverlayModal } from './EditOverlayModal';
 import { LoginModal } from './LoginModal';
 import { ErrorReportModal } from './ErrorReportModal';
@@ -105,6 +106,11 @@ export const Modal = (): React.ReactNode => {
           <LayerTextFactoryModal />
         </ModalLayout>
       )}
+      {isOpen && modalName === 'layer-text-edit-factory' && (
+        <ModalLayout>
+          <LayerTextEditFactoryModal />
+        </ModalLayout>
+      )}
     </>
   );
 };
diff --git a/src/components/FunctionalArea/Modal/ModalLayout/ModalLayout.component.tsx b/src/components/FunctionalArea/Modal/ModalLayout/ModalLayout.component.tsx
index 59d85797..e9fd515a 100644
--- a/src/components/FunctionalArea/Modal/ModalLayout/ModalLayout.component.tsx
+++ b/src/components/FunctionalArea/Modal/ModalLayout/ModalLayout.component.tsx
@@ -34,7 +34,8 @@ export const ModalLayout = ({ children }: ModalLayoutProps): JSX.Element => {
             modalName === 'add-comment' && 'h-auto w-[400px]',
             modalName === 'error-report' && 'h-auto w-[800px]',
             modalName === 'layer-factory' && 'h-auto w-[400px]',
-            modalName === 'layer-text-factory' && 'h-auto w-[900px]',
+            ['layer-text-factory', 'layer-text-edit-factory'].includes(modalName) &&
+              'h-auto w-[900px]',
             ['layer-image-object-factory', 'layer-image-object-edit-factory'].includes(modalName) &&
               'h-auto w-[800px]',
             ['edit-overlay', 'logged-in-menu'].includes(modalName) && 'h-auto w-[432px]',
diff --git a/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectsList.component.tsx b/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectsList.component.tsx
index fa98e051..70a6acf5 100644
--- a/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectsList.component.tsx
+++ b/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectsList.component.tsx
@@ -13,8 +13,14 @@ import {
   removeLayerImage,
   removeLayerText,
   updateLayerImageObject,
+  updateLayerText,
 } from '@/redux/layers/layers.thunks';
-import { layerDeleteImage, layerDeleteText, layerUpdateImage } from '@/redux/layers/layers.slice';
+import {
+  layerDeleteImage,
+  layerDeleteText,
+  layerUpdateImage,
+  layerUpdateText,
+} from '@/redux/layers/layers.slice';
 import removeElementFromLayer from '@/components/Map/MapViewer/utils/shapes/elements/removeElementFromLayer';
 import { showToast } from '@/utils/showToast';
 import { SerializedError } from '@reduxjs/toolkit';
@@ -28,7 +34,10 @@ import { useSetBounds } from '@/utils/map/useSetBounds';
 import { mapEditToolsLayerObjectSelector } from '@/redux/mapEditTools/mapEditTools.selectors';
 import { usePointToProjection } from '@/utils/map/usePointToProjection';
 import { Coordinate } from 'ol/coordinate';
-import { openLayerImageObjectEditFactoryModal } from '@/redux/modal/modal.slice';
+import {
+  openLayerImageObjectEditFactoryModal,
+  openLayerTextEditFactoryModal,
+} from '@/redux/modal/modal.slice';
 
 interface LayersDrawerObjectsListProps {
   layerId: number;
@@ -173,6 +182,42 @@ export const LayersDrawerObjectsList = ({
     await updateImageZIndex({ zIndex: lowestZIndex - 1, layerImage });
   };
 
+  const updateTextZIndex = async ({
+    zIndex,
+    layerText,
+  }: {
+    zIndex: number;
+    layerText: LayerText;
+  }): Promise<void> => {
+    const newLayerText = await dispatch(
+      updateLayerText({
+        modelId: currentModelId,
+        layerId: layerText.layer,
+        ...layerText,
+        z: zIndex,
+      }),
+    ).unwrap();
+    if (newLayerText) {
+      dispatch(
+        layerUpdateText({
+          modelId: currentModelId,
+          layerId: newLayerText.layer,
+          layerText: newLayerText,
+        }),
+      );
+      dispatch(mapEditToolsSetLayerObject(newLayerText));
+      updateElement(mapInstance, newLayerText.layer, newLayerText);
+    }
+  };
+
+  const bringTextToFront = async (layerText: LayerText): Promise<void> => {
+    await updateTextZIndex({ zIndex: highestZIndex + 1, layerText });
+  };
+
+  const bringTextToBack = async (layerText: LayerText): Promise<void> => {
+    await updateTextZIndex({ zIndex: lowestZIndex - 1, layerText });
+  };
+
   const centerObject = (layerObject: LayerImage | LayerText): void => {
     if (mapEditToolsLayerImageObject && mapEditToolsLayerImageObject.id === layerObject.id) {
       const point1 = pointToProjection({ x: layerObject.x, y: layerObject.y });
@@ -188,6 +233,10 @@ export const LayersDrawerObjectsList = ({
     dispatch(openLayerImageObjectEditFactoryModal());
   };
 
+  const editText = (): void => {
+    dispatch(openLayerTextEditFactoryModal());
+  };
+
   if (!layer) {
     return null;
   }
@@ -208,11 +257,11 @@ export const LayersDrawerObjectsList = ({
         <LayersDrawerTextItem
           layerText={layerText}
           key={layerText.id}
-          bringToFront={() => {}}
-          bringToBack={() => {}}
+          bringToFront={() => bringTextToFront(layerText)}
+          bringToBack={() => bringTextToBack(layerText)}
           removeObject={() => removeObject(layerText)}
           centerObject={() => centerObject(layerText)}
-          editObject={() => {}}
+          editObject={() => editText()}
           isLayerVisible={isLayerVisible}
           isLayerActive={isLayerActive}
         />
diff --git a/src/components/Map/MapViewer/MapViewer.types.ts b/src/components/Map/MapViewer/MapViewer.types.ts
index f10c9070..4204320f 100644
--- a/src/components/Map/MapViewer/MapViewer.types.ts
+++ b/src/components/Map/MapViewer/MapViewer.types.ts
@@ -8,7 +8,7 @@ export type MapConfig = {
 };
 
 export type VerticalAlign = 'TOP' | 'MIDDLE' | 'BOTTOM';
-export type HorizontalAlign = 'LEFT' | 'RIGHT' | 'CENTER' | 'END' | 'START';
+export type HorizontalAlign = 'LEFT' | 'RIGHT' | 'CENTER';
 
 export type OverlayBioEntityGroupedElementsType = {
   [id: string]: Array<OverlayBioEntityRender & { amount: number }>;
diff --git a/src/components/Map/MapViewer/utils/shapes/elements/Glyph/Glyph.ts b/src/components/Map/MapViewer/utils/shapes/elements/Glyph/Glyph.ts
index 342cdfac..57b36875 100644
--- a/src/components/Map/MapViewer/utils/shapes/elements/Glyph/Glyph.ts
+++ b/src/components/Map/MapViewer/utils/shapes/elements/Glyph/Glyph.ts
@@ -34,13 +34,13 @@ export type GlyphProps = {
 export default class Glyph {
   feature: Feature<Polygon>;
 
-  style: Style = new Style({});
+  style: Style = new Style();
 
-  noGlyphStyle: Style;
+  noGlyphStyle: Style = new Style();
 
   imageScale: number = 1;
 
-  polygonStyle: Style;
+  polygonStyle: Style = new Style();
 
   polygon: Polygon = new Polygon([]);
 
@@ -113,26 +113,7 @@ export default class Glyph {
 
     this.drawPolygon();
 
-    this.polygonStyle = getStyle({
-      geometry: this.polygon,
-      zIndex: this.zIndex,
-      borderColor: { ...WHITE_COLOR, alpha: 0 },
-      fillColor: { ...WHITE_COLOR, alpha: 0 },
-    });
-
-    this.noGlyphStyle = getStyle({
-      geometry: this.polygon,
-      zIndex: this.zIndex,
-      fillColor: '#E7E7E7',
-    });
-    this.noGlyphStyle.setText(
-      new Text({
-        text: 'No image',
-        font: '12pt Arial',
-        fill: getFill({ color: '#000' }),
-        overflow: true,
-      }),
-    );
+    this.setStyles();
 
     this.feature = new Feature({
       geometry: this.polygon,
@@ -172,6 +153,29 @@ export default class Glyph {
     ]);
   }
 
+  private setStyles(): void {
+    this.polygonStyle = getStyle({
+      geometry: this.polygon,
+      zIndex: this.zIndex,
+      borderColor: { ...WHITE_COLOR, alpha: 0 },
+      fillColor: { ...WHITE_COLOR, alpha: 0 },
+    });
+
+    this.noGlyphStyle = getStyle({
+      geometry: this.polygon,
+      zIndex: this.zIndex,
+      fillColor: '#E7E7E7',
+    });
+    this.noGlyphStyle.setText(
+      new Text({
+        text: 'No image',
+        font: '12pt Arial',
+        fill: getFill({ color: '#000' }),
+        overflow: true,
+      }),
+    );
+  }
+
   private refreshPolygon(): void {
     this.drawPolygon();
     this.polygonStyle.setGeometry(this.polygon);
@@ -195,7 +199,7 @@ export default class Glyph {
     this.glyphId = imageObject.glyph;
 
     this.refreshPolygon();
-    this.refreshZIndex();
+    this.setStyles();
     this.drawImage();
     this.feature.changed();
   }
diff --git a/src/components/Map/MapViewer/utils/shapes/layer/elements/LayerText.ts b/src/components/Map/MapViewer/utils/shapes/layer/elements/LayerText.ts
index 133034cf..26565345 100644
--- a/src/components/Map/MapViewer/utils/shapes/layer/elements/LayerText.ts
+++ b/src/components/Map/MapViewer/utils/shapes/layer/elements/LayerText.ts
@@ -5,7 +5,7 @@ import { Point } from 'ol/geom';
 import { Feature } from 'ol';
 import { FeatureLike } from 'ol/Feature';
 import { MapInstance } from '@/types/map';
-import { LayerText as LayerTextModel, Color } from '@/types/models';
+import { Color, LayerText as LayerTextModel } from '@/types/models';
 import { TEXT_CUTOFF_SCALE } from '@/components/Map/MapViewer/MapViewer.constants';
 import {
   BoundingBox,
@@ -77,13 +77,13 @@ export default class LayerText {
 
   fontSize: number;
 
-  style: Style;
+  style: Style = new Style();
 
-  polygonStyle: Style;
+  polygonStyle: Style = new Style();
 
   polygon: Polygon = new Polygon([]);
 
-  strokeStyle: Stroke;
+  strokeStyle: Stroke = new Stroke();
 
   point: Point;
 
@@ -140,29 +140,11 @@ export default class LayerText {
       horizontalAlign,
       pointToProjection,
     });
+    this.point = new Point(textCoords);
+
     this.drawPolygon();
-    this.strokeStyle = getStroke({
-      color: rgbToHex(borderColor),
-      width: 1,
-    });
-    this.polygonStyle = getStyle({
-      geometry: this.polygon,
-      borderColor,
-      fillColor: { rgb: 0, alpha: 0 },
-      lineWidth: 1,
-      zIndex,
-    });
 
-    const textStyle = getTextStyle({
-      text,
-      fontSize,
-      color: rgbToHex(color),
-      zIndex,
-      horizontalAlign,
-    });
-    this.point = new Point(textCoords);
-    this.style = textStyle;
-    this.style.setGeometry(this.point);
+    this.setStyles();
 
     this.feature = new Feature({
       geometry: this.polygon,
@@ -254,6 +236,28 @@ export default class LayerText {
     this.feature.changed();
   }
 
+  private setStyles(): void {
+    this.strokeStyle = getStroke({
+      color: rgbToHex(this.borderColor),
+      width: 1,
+    });
+    this.polygonStyle = getStyle({
+      geometry: this.polygon,
+      borderColor: this.borderColor,
+      fillColor: { rgb: 0, alpha: 0 },
+      lineWidth: 1,
+      zIndex: this.zIndex,
+    });
+    this.style = getTextStyle({
+      text: this.text,
+      fontSize: this.fontSize,
+      color: rgbToHex(this.color),
+      zIndex: this.zIndex,
+      horizontalAlign: this.horizontalAlign,
+    });
+    this.style.setGeometry(this.point);
+  }
+
   private updateElement(layerText: LayerTextModel): void {
     this.elementId = layerText.id;
     this.x = layerText.x;
@@ -269,7 +273,7 @@ export default class LayerText {
     this.horizontalAlign = layerText.horizontalAlign;
 
     this.refreshPolygon();
-    this.refreshZIndex();
+    this.setStyles();
     this.feature.changed();
   }
 
diff --git a/src/models/bioEntitySchema.ts b/src/models/bioEntitySchema.ts
index ec78db95..5c754989 100644
--- a/src/models/bioEntitySchema.ts
+++ b/src/models/bioEntitySchema.ts
@@ -26,7 +26,7 @@ export const bioEntitySchema = z.object({
   nameWidth: z.number(),
   nameHeight: z.number(),
   nameVerticalAlign: z.enum(['TOP', 'MIDDLE', 'BOTTOM']),
-  nameHorizontalAlign: z.enum(['LEFT', 'RIGHT', 'CENTER', 'END', 'START']),
+  nameHorizontalAlign: z.enum(['LEFT', 'RIGHT', 'CENTER']),
   width: z
     .number()
     .optional()
diff --git a/src/models/layerTextSchema.ts b/src/models/layerTextSchema.ts
index a575b139..d0460100 100644
--- a/src/models/layerTextSchema.ts
+++ b/src/models/layerTextSchema.ts
@@ -12,7 +12,7 @@ export const layerTextSchema = z.object({
   fontSize: z.number(),
   notes: z.string(),
   verticalAlign: z.enum(['TOP', 'MIDDLE', 'BOTTOM']),
-  horizontalAlign: z.enum(['LEFT', 'RIGHT', 'CENTER', 'END', 'START']),
+  horizontalAlign: z.enum(['LEFT', 'RIGHT', 'CENTER']),
   backgroundColor: colorSchema,
   borderColor: colorSchema,
   color: colorSchema,
diff --git a/src/models/modelElementModificationSchema.ts b/src/models/modelElementModificationSchema.ts
index 3d7f318e..d69ce89a 100644
--- a/src/models/modelElementModificationSchema.ts
+++ b/src/models/modelElementModificationSchema.ts
@@ -15,7 +15,7 @@ export const modelElementModificationSchema = z.object({
   nameWidth: z.number(),
   nameHeight: z.number(),
   nameVerticalAlign: z.enum(['TOP', 'MIDDLE', 'BOTTOM']),
-  nameHorizontalAlign: z.enum(['LEFT', 'RIGHT', 'CENTER', 'END', 'START']),
+  nameHorizontalAlign: z.enum(['LEFT', 'RIGHT', 'CENTER']),
   species: z.number(),
   borderColor: colorSchema,
   fillColor: colorSchema,
diff --git a/src/models/modelElementSchema.ts b/src/models/modelElementSchema.ts
index 86b82f67..32eae25e 100644
--- a/src/models/modelElementSchema.ts
+++ b/src/models/modelElementSchema.ts
@@ -36,7 +36,7 @@ export const modelElementSchema = z.object({
   nameWidth: z.number(),
   nameHeight: z.number(),
   nameVerticalAlign: z.enum(['TOP', 'MIDDLE', 'BOTTOM']),
-  nameHorizontalAlign: z.enum(['LEFT', 'RIGHT', 'CENTER', 'END', 'START']),
+  nameHorizontalAlign: z.enum(['LEFT', 'RIGHT', 'CENTER']),
   synonyms: z.array(z.string()),
   formerSymbols: z.array(z.string()),
   activity: z.boolean().optional(),
diff --git a/src/redux/modal/modal.reducers.ts b/src/redux/modal/modal.reducers.ts
index 1b903069..923d2858 100644
--- a/src/redux/modal/modal.reducers.ts
+++ b/src/redux/modal/modal.reducers.ts
@@ -165,3 +165,9 @@ export const openLayerTextFactoryModalReducer = (
   state.modalTitle = 'Add text';
   state.isOpen = true;
 };
+
+export const openLayerTextEditFactoryModalReducer = (state: ModalState): void => {
+  state.isOpen = true;
+  state.modalName = 'layer-text-edit-factory';
+  state.modalTitle = 'Edit text';
+};
diff --git a/src/redux/modal/modal.slice.ts b/src/redux/modal/modal.slice.ts
index bf01d86a..ed74baec 100644
--- a/src/redux/modal/modal.slice.ts
+++ b/src/redux/modal/modal.slice.ts
@@ -20,6 +20,7 @@ import {
   openLayerImageObjectFactoryModalReducer,
   openLayerImageObjectEditFactoryModalReducer,
   openLayerTextFactoryModalReducer,
+  openLayerTextEditFactoryModalReducer,
 } from './modal.reducers';
 
 const modalSlice = createSlice({
@@ -45,6 +46,7 @@ const modalSlice = createSlice({
     openLayerImageObjectFactoryModal: openLayerImageObjectFactoryModalReducer,
     openLayerImageObjectEditFactoryModal: openLayerImageObjectEditFactoryModalReducer,
     openLayerTextFactoryModal: openLayerTextFactoryModalReducer,
+    openLayerTextEditFactoryModal: openLayerTextEditFactoryModalReducer,
   },
 });
 
@@ -68,6 +70,7 @@ export const {
   openLayerImageObjectFactoryModal,
   openLayerImageObjectEditFactoryModal,
   openLayerTextFactoryModal,
+  openLayerTextEditFactoryModal,
 } = modalSlice.actions;
 
 export default modalSlice.reducer;
diff --git a/src/types/modal.ts b/src/types/modal.ts
index 8b02e86a..579c8137 100644
--- a/src/types/modal.ts
+++ b/src/types/modal.ts
@@ -15,4 +15,5 @@ export type ModalName =
   | 'layer-factory'
   | 'layer-image-object-factory'
   | 'layer-image-object-edit-factory'
-  | 'layer-text-factory';
+  | 'layer-text-factory'
+  | 'layer-text-edit-factory';
-- 
GitLab


From 7f8d0b665cbd00568e46ba57597c5d22ab28192b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mi=C5=82osz=20Grocholewski?= <m.grocholewski@atcomp.pl>
Date: Tue, 18 Feb 2025 10:10:19 +0100
Subject: [PATCH 3/8] feat(layers): add layers zIndex editing

---
 .../LayerFactoryModal.component.tsx           |   4 +
 ...LayerImageObjectFactoryModal.component.tsx |   9 +-
 .../LayerTextFactoryModal.component.tsx       |   9 +-
 .../LayerDrawerTextItem.component.tsx         |  12 +-
 .../LayersDrawer/LayersDrawer.component.tsx   |  46 ++++--
 .../LayersDrawerImageItem.component.tsx       |  12 +-
 .../LayersDrawerLayer.component.tsx           | 107 +++++++++++---
 .../LayersDrawerLayerActions.component.tsx    |  39 +++++
 .../LayersDrawerObjectActions.component.tsx   |  20 +--
 .../LayersDrawerObjectsList.component.tsx     |  32 ++--
 .../useOlMapAdditionalLayers.ts               |   1 +
 .../commentsLayer/useOlMapCommentsLayer.ts    |   1 +
 .../config/mapCardLayer/useOlMapCardLayer.ts  |   1 +
 .../config/pinsLayer/useOlMapPinsLayer.ts     |   1 +
 .../processLayer/useOlMapProcessLayer.ts      |   1 +
 .../reactionsLayer/useOlMapReactionsLayer.ts  |   1 +
 .../utils/shapes/layer/Layer.test.ts          |   1 +
 .../Map/MapViewer/utils/shapes/layer/Layer.ts |   3 +
 src/models/layerSchema.ts                     |   1 +
 src/redux/layers/layers.reducers.test.ts      |   4 +-
 src/redux/layers/layers.selectors.ts          | 139 +++++++++++++-----
 src/redux/layers/layers.thunks.test.ts        |  18 ++-
 src/redux/layers/layers.thunks.ts             |  28 ++--
 src/redux/layers/layers.types.ts              |   2 +
 src/shared/Icon/Icon.component.tsx            |  12 +-
 src/shared/Icon/Icons/ArrowDoubleDownIcon.tsx |  12 +-
 src/shared/Icon/Icons/ArrowDoubleUpIcon.tsx   |  12 +-
 src/shared/Icon/Icons/LayerArrowDownIcon.tsx  |  18 +++
 src/shared/Icon/Icons/LayerArrowUpIcon.tsx    |  18 +++
 .../{BringBackIcon.tsx => MoveBackIcon.tsx}   |   6 +-
 .../{BringFrontIcon.tsx => MoveFrontIcon.tsx} |   6 +-
 .../IconButton/IconButton.component.tsx       |   8 +-
 src/types/iconTypes.ts                        |   6 +-
 33 files changed, 430 insertions(+), 160 deletions(-)
 create mode 100644 src/shared/Icon/Icons/LayerArrowDownIcon.tsx
 create mode 100644 src/shared/Icon/Icons/LayerArrowUpIcon.tsx
 rename src/shared/Icon/Icons/{BringBackIcon.tsx => MoveBackIcon.tsx} (78%)
 rename src/shared/Icon/Icons/{BringFrontIcon.tsx => MoveFrontIcon.tsx} (77%)

diff --git a/src/components/FunctionalArea/Modal/LayerFactoryModal/LayerFactoryModal.component.tsx b/src/components/FunctionalArea/Modal/LayerFactoryModal/LayerFactoryModal.component.tsx
index 8d925951..b806d2b6 100644
--- a/src/components/FunctionalArea/Modal/LayerFactoryModal/LayerFactoryModal.component.tsx
+++ b/src/components/FunctionalArea/Modal/LayerFactoryModal/LayerFactoryModal.component.tsx
@@ -19,11 +19,13 @@ import { SerializedError } from '@reduxjs/toolkit';
 import { layerFactoryStateSelector } from '@/redux/modal/modal.selector';
 import './LayerFactoryModal.styles.css';
 import { LoadingIndicator } from '@/shared/LoadingIndicator';
+import { maxLayerZIndexAboveDiagramSelector } from '@/redux/layers/layers.selectors';
 
 export const LayerFactoryModal: React.FC = () => {
   const dispatch = useAppDispatch();
   const currentModelId = useAppSelector(currentModelIdSelector);
   const layerFactoryState = useAppSelector(layerFactoryStateSelector);
+  const maxLayerZIndexAboveDiagram = useAppSelector(maxLayerZIndexAboveDiagramSelector);
   const [loaded, setLoaded] = useState<boolean>(false);
 
   const [data, setData] = useState<LayerStoreInterface>({
@@ -31,6 +33,7 @@ export const LayerFactoryModal: React.FC = () => {
     visible: false,
     locked: false,
     modelId: currentModelId,
+    zIndex: maxLayerZIndexAboveDiagram,
   });
 
   const fetchData = useMemo(() => {
@@ -42,6 +45,7 @@ export const LayerFactoryModal: React.FC = () => {
           visible: layer.visible,
           locked: layer.locked,
           modelId: currentModelId,
+          zIndex: layer.z,
         });
       }
       setLoaded(true);
diff --git a/src/components/FunctionalArea/Modal/LayerImageObjectModal/LayerImageObjectFactoryModal.component.tsx b/src/components/FunctionalArea/Modal/LayerImageObjectModal/LayerImageObjectFactoryModal.component.tsx
index 1efb7d88..4d1513e9 100644
--- a/src/components/FunctionalArea/Modal/LayerImageObjectModal/LayerImageObjectFactoryModal.component.tsx
+++ b/src/components/FunctionalArea/Modal/LayerImageObjectModal/LayerImageObjectFactoryModal.component.tsx
@@ -4,7 +4,10 @@ import { useAppSelector } from '@/redux/hooks/useAppSelector';
 import { layerImageObjectFactoryStateSelector } from '@/redux/modal/modal.selector';
 import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
 import { currentModelIdSelector } from '@/redux/models/models.selectors';
-import { highestZIndexSelector, layersDrawLayerSelector } from '@/redux/layers/layers.selectors';
+import {
+  layersDrawLayerSelector,
+  maxObjectZIndexForLayerSelector,
+} from '@/redux/layers/layers.selectors';
 import { addLayerImageObject } from '@/redux/layers/layers.thunks';
 import { addGlyph } from '@/redux/glyphs/glyphs.thunks';
 import { SerializedError } from '@reduxjs/toolkit';
@@ -22,7 +25,7 @@ export const LayerImageObjectFactoryModal: React.FC = () => {
   const drawLayer = useAppSelector(layersDrawLayerSelector);
   const layerImageObjectFactoryState = useAppSelector(layerImageObjectFactoryStateSelector);
   const dispatch = useAppDispatch();
-  const highestZIndex = useAppSelector(highestZIndexSelector);
+  const maxZIndex = useAppSelector(state => maxObjectZIndexForLayerSelector(state, drawLayer));
   const { mapInstance } = useMapInstance();
 
   const [selectedGlyph, setSelectedGlyph] = useState<number | null>(null);
@@ -49,7 +52,7 @@ export const LayerImageObjectFactoryModal: React.FC = () => {
           layerId: drawLayer,
           x: layerImageObjectFactoryState.x,
           y: layerImageObjectFactoryState.y,
-          z: highestZIndex + 1,
+          z: maxZIndex + 1,
           width: layerImageObjectFactoryState.width,
           height: layerImageObjectFactoryState.height,
           glyph: glyphId,
diff --git a/src/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextFactoryModal.component.tsx b/src/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextFactoryModal.component.tsx
index e1ccf612..bfb80aff 100644
--- a/src/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextFactoryModal.component.tsx
+++ b/src/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextFactoryModal.component.tsx
@@ -13,7 +13,10 @@ import { LayerTextFactoryForm } from '@/components/FunctionalArea/Modal/LayerTex
 import { Color } from '@/types/models';
 import { useAppSelector } from '@/redux/hooks/useAppSelector';
 import { layerTextFactoryStateSelector } from '@/redux/modal/modal.selector';
-import { highestZIndexSelector, layersDrawLayerSelector } from '@/redux/layers/layers.selectors';
+import {
+  layersDrawLayerSelector,
+  maxObjectZIndexForLayerSelector,
+} from '@/redux/layers/layers.selectors';
 import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
 import { currentModelIdSelector } from '@/redux/models/models.selectors';
 import { showToast } from '@/utils/showToast';
@@ -31,7 +34,7 @@ export const LayerTextFactoryModal: React.FC = () => {
   const currentModelId = useAppSelector(currentModelIdSelector);
   const layerTextFactoryState = useAppSelector(layerTextFactoryStateSelector);
   const dispatch = useAppDispatch();
-  const highestZIndex = useAppSelector(highestZIndexSelector);
+  const maxZIndex = useAppSelector(state => maxObjectZIndexForLayerSelector(state, drawLayer));
   const { mapInstance } = useMapInstance();
 
   const [isSending, setIsSending] = useState<boolean>(false);
@@ -55,7 +58,7 @@ export const LayerTextFactoryModal: React.FC = () => {
           layerId: drawLayer,
           boundingBox: layerTextFactoryState,
           textData: data,
-          z: highestZIndex + 1,
+          z: maxZIndex + 1,
         }),
       ).unwrap();
       if (!textData) {
diff --git a/src/components/Map/Drawer/LayersDrawer/LayerDrawerTextItem.component.tsx b/src/components/Map/Drawer/LayersDrawer/LayerDrawerTextItem.component.tsx
index 6f57c762..a9c3d3b3 100644
--- a/src/components/Map/Drawer/LayersDrawer/LayerDrawerTextItem.component.tsx
+++ b/src/components/Map/Drawer/LayersDrawer/LayerDrawerTextItem.component.tsx
@@ -10,8 +10,8 @@ import { hasPrivilegeToWriteProjectSelector } from '@/redux/user/user.selectors'
 
 interface LayersDrawerTextItemProps {
   layerText: LayerText;
-  bringToFront: () => void;
-  bringToBack: () => void;
+  moveToFront: () => void;
+  moveToBack: () => void;
   removeObject: () => void;
   centerObject: () => void;
   editObject: () => void;
@@ -21,8 +21,8 @@ interface LayersDrawerTextItemProps {
 
 export const LayersDrawerTextItem = ({
   layerText,
-  bringToFront,
-  bringToBack,
+  moveToFront,
+  moveToBack,
   removeObject,
   centerObject,
   editObject,
@@ -68,8 +68,8 @@ export const LayersDrawerTextItem = ({
       </div>
       {showActions && (
         <LayersDrawerObjectActions
-          bringToFront={bringToFront}
-          bringToBack={bringToBack}
+          moveToFront={moveToFront}
+          moveToBack={moveToBack}
           removeObject={removeObject}
           centerObject={centerObject}
           editObject={editObject}
diff --git a/src/components/Map/Drawer/LayersDrawer/LayersDrawer.component.tsx b/src/components/Map/Drawer/LayersDrawer/LayersDrawer.component.tsx
index 12bef081..33c259f3 100644
--- a/src/components/Map/Drawer/LayersDrawer/LayersDrawer.component.tsx
+++ b/src/components/Map/Drawer/LayersDrawer/LayersDrawer.component.tsx
@@ -4,7 +4,7 @@ import { DrawerHeading } from '@/shared/DrawerHeading';
 import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
 import { layersForCurrentModelSelector } from '@/redux/layers/layers.selectors';
 import { Button } from '@/shared/Button';
-import { JSX, useEffect, useRef } from 'react';
+import { JSX, useEffect, useMemo, useRef } from 'react';
 import { openLayerFactoryModal } from '@/redux/modal/modal.slice';
 import { hasPrivilegeToWriteProjectSelector } from '@/redux/user/user.selectors';
 import { LayersDrawerLayer } from '@/components/Map/Drawer/LayersDrawer/LayersDrawerLayer.component';
@@ -21,6 +21,19 @@ export const LayersDrawer = (): JSX.Element => {
     dispatch(openLayerFactoryModal());
   };
 
+  const sortedLayers = useMemo(() => {
+    return [...layersForCurrentModel].sort((layerA, layerB) => layerB.details.z - layerA.details.z);
+  }, [layersForCurrentModel]);
+
+  const negativeZLayers = useMemo(
+    () => sortedLayers.filter(layer => layer.details.z < 0),
+    [sortedLayers],
+  );
+  const positiveZLayers = useMemo(
+    () => sortedLayers.filter(layer => layer.details.z >= 0),
+    [sortedLayers],
+  );
+
   useEffect(() => {
     if (!mapEditToolsLayerImageObject || !layersDrawerRef.current) {
       return;
@@ -61,20 +74,33 @@ export const LayersDrawer = (): JSX.Element => {
         ref={layersDrawerRef}
       >
         {hasPrivilegeToWriteProject && (
-          <div className="flex justify-start pt-2">
+          <div className="flex justify-start py-2">
             <Button icon="plus" isIcon isFrontIcon onClick={addNewLayer}>
               Add layer
             </Button>
           </div>
         )}
-        <div className="flex flex-col gap-4">
-          {layersForCurrentModel.map(layer => (
-            <LayersDrawerLayer
-              key={layer.details.id}
-              layerId={layer.details.id}
-              layerName={layer.details.name}
-            />
-          ))}
+        <div className="flex flex-col gap-2">
+          {Boolean(positiveZLayers.length) && (
+            <span className="border-b-2 border-dashed border-b-gray-400 text-center text-lg font-semibold">
+              Layers above the diagram
+            </span>
+          )}
+          <div className="flex flex-col gap-5">
+            {positiveZLayers.map(layer => (
+              <LayersDrawerLayer key={layer.details.id} layerDetails={layer.details} />
+            ))}
+          </div>
+          {Boolean(negativeZLayers.length) && (
+            <span className="border-b-2 border-dashed border-b-gray-400 text-center text-lg font-semibold">
+              Layers below the diagram
+            </span>
+          )}
+          <div className="flex flex-col gap-5">
+            {negativeZLayers.map(layer => (
+              <LayersDrawerLayer key={layer.details.id} layerDetails={layer.details} />
+            ))}
+          </div>
         </div>
       </div>
     </div>
diff --git a/src/components/Map/Drawer/LayersDrawer/LayersDrawerImageItem.component.tsx b/src/components/Map/Drawer/LayersDrawer/LayersDrawerImageItem.component.tsx
index 0622f141..e160b807 100644
--- a/src/components/Map/Drawer/LayersDrawer/LayersDrawerImageItem.component.tsx
+++ b/src/components/Map/Drawer/LayersDrawer/LayersDrawerImageItem.component.tsx
@@ -11,8 +11,8 @@ import { hasPrivilegeToWriteProjectSelector } from '@/redux/user/user.selectors'
 
 interface LayersDrawerImageItemProps {
   layerImage: LayerImage;
-  bringToFront: () => void;
-  bringToBack: () => void;
+  moveToFront: () => void;
+  moveToBack: () => void;
   removeObject: () => void;
   centerObject: () => void;
   editObject: () => void;
@@ -22,8 +22,8 @@ interface LayersDrawerImageItemProps {
 
 export const LayersDrawerImageItem = ({
   layerImage,
-  bringToFront,
-  bringToBack,
+  moveToFront,
+  moveToBack,
   removeObject,
   centerObject,
   editObject,
@@ -72,8 +72,8 @@ export const LayersDrawerImageItem = ({
       </div>
       {showActions && (
         <LayersDrawerObjectActions
-          bringToFront={bringToFront}
-          bringToBack={bringToBack}
+          moveToFront={moveToFront}
+          moveToBack={moveToBack}
           removeObject={removeObject}
           centerObject={centerObject}
           editObject={editObject}
diff --git a/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayer.component.tsx b/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayer.component.tsx
index 49b8536f..8b0f9b01 100644
--- a/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayer.component.tsx
+++ b/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayer.component.tsx
@@ -1,14 +1,19 @@
+/* eslint-disable no-magic-numbers */
 import { useAppSelector } from '@/redux/hooks/useAppSelector';
 import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
 import {
   layersActiveLayersSelector,
   layersVisibilityForCurrentModelSelector,
+  maxLayerZIndexAboveDiagramSelector,
+  maxLayerZIndexBelowDiagramSelector,
+  minLayerZIndexAboveDiagramSelector,
+  minLayerZIndexBelowDiagramSelector,
 } from '@/redux/layers/layers.selectors';
 import { currentModelIdSelector } from '@/redux/models/models.selectors';
 import { openLayerFactoryModal } from '@/redux/modal/modal.slice';
 import QuestionModal from '@/components/FunctionalArea/Modal/QuestionModal/QustionModal.component';
 import { useState, JSX, useMemo } from 'react';
-import { getLayersForModel, removeLayer } from '@/redux/layers/layers.thunks';
+import { getLayersForModel, removeLayer, updateLayer } from '@/redux/layers/layers.thunks';
 import { showToast } from '@/utils/showToast';
 import { SerializedError } from '@reduxjs/toolkit';
 import { LayersDrawerLayerActions } from '@/components/Map/Drawer/LayersDrawer/LayersDrawerLayerActions.component';
@@ -21,38 +26,42 @@ import {
 import { LayersDrawerObjectsList } from '@/components/Map/Drawer/LayersDrawer/LayersDrawerObjectsList.component';
 import { mapEditToolsSetActiveAction } from '@/redux/mapEditTools/mapEditTools.slice';
 import { MAP_EDIT_ACTIONS } from '@/redux/mapEditTools/mapEditTools.constants';
+import { Layer } from '@/types/models';
 
 interface LayersDrawerLayerProps {
-  layerId: number;
-  layerName: string;
+  layerDetails: Layer;
 }
 
-export const LayersDrawerLayer = ({ layerId, layerName }: LayersDrawerLayerProps): JSX.Element => {
+export const LayersDrawerLayer = ({ layerDetails }: LayersDrawerLayerProps): JSX.Element => {
   const layersVisibilityForCurrentModel = useAppSelector(layersVisibilityForCurrentModelSelector);
   const activeLayers = useAppSelector(layersActiveLayersSelector);
   const currentModelId = useAppSelector(currentModelIdSelector);
+  const maxLayerZIndexAboveDiagram = useAppSelector(maxLayerZIndexAboveDiagramSelector);
+  const maxLayerZIndexBelowDiagram = useAppSelector(maxLayerZIndexBelowDiagramSelector);
+  const minLayerZIndexAboveDiagram = useAppSelector(minLayerZIndexAboveDiagramSelector);
+  const minLayerZIndexBelowDiagram = useAppSelector(minLayerZIndexBelowDiagramSelector);
   const dispatch = useAppDispatch();
   const [isModalOpen, setIsModalOpen] = useState(false);
 
   const isLayerVisible = useMemo(() => {
-    return layersVisibilityForCurrentModel[layerId];
-  }, [layerId, layersVisibilityForCurrentModel]);
+    return layersVisibilityForCurrentModel[layerDetails.id];
+  }, [layerDetails.id, layersVisibilityForCurrentModel]);
 
   const isLayerActive = useMemo(() => {
-    return activeLayers.includes(layerId);
-  }, [activeLayers, layerId]);
+    return activeLayers.includes(layerDetails.id);
+  }, [activeLayers, layerDetails.id]);
 
   const editLayer = (): void => {
-    dispatch(openLayerFactoryModal(layerId));
+    dispatch(openLayerFactoryModal(layerDetails.id));
   };
 
   const addImage = (): void => {
-    dispatch(setDrawLayer({ modelId: currentModelId, layerId }));
+    dispatch(setDrawLayer({ modelId: currentModelId, layerId: layerDetails.id }));
     dispatch(mapEditToolsSetActiveAction(MAP_EDIT_ACTIONS.DRAW_IMAGE));
   };
 
   const addText = (): void => {
-    dispatch(setDrawLayer({ modelId: currentModelId, layerId }));
+    dispatch(setDrawLayer({ modelId: currentModelId, layerId: layerDetails.id }));
     dispatch(mapEditToolsSetActiveAction(MAP_EDIT_ACTIONS.ADD_TEXT));
   };
 
@@ -61,11 +70,11 @@ export const LayersDrawerLayer = ({ layerId, layerName }: LayersDrawerLayerProps
   };
 
   const confirmRemove = async (): Promise<void> => {
-    if (!layerId) {
+    if (!layerDetails.id) {
       return;
     }
     try {
-      await dispatch(removeLayer({ modelId: currentModelId, layerId })).unwrap();
+      await dispatch(removeLayer({ modelId: currentModelId, layerId: layerDetails.id })).unwrap();
       showToast({
         type: 'success',
         message: 'The layer has been successfully removed',
@@ -87,12 +96,61 @@ export const LayersDrawerLayer = ({ layerId, layerName }: LayersDrawerLayerProps
 
   const toggleActiveLayer = (value: boolean): void => {
     if (value) {
-      dispatch(setLayerToActive({ modelId: currentModelId, layerId }));
+      dispatch(setLayerToActive({ modelId: currentModelId, layerId: layerDetails.id }));
     } else {
-      dispatch(setLayerToInactive({ modelId: currentModelId, layerId }));
+      dispatch(setLayerToInactive({ modelId: currentModelId, layerId: layerDetails.id }));
     }
   };
 
+  const updateLayerZIndex = async (zIndex: number): Promise<void> => {
+    try {
+      dispatch(
+        updateLayer({
+          name: layerDetails.name,
+          visible: layerDetails.visible,
+          locked: layerDetails.locked,
+          modelId: currentModelId,
+          layerId: layerDetails.id,
+          zIndex,
+        }),
+      );
+    } catch (error) {
+      const typedError = error as SerializedError;
+      showToast({
+        type: 'error',
+        message: typedError.message || 'An error occurred while updating the layer',
+      });
+    }
+  };
+
+  const moveToFront = (): void => {
+    if (layerDetails.z > 0) {
+      updateLayerZIndex(maxLayerZIndexAboveDiagram);
+    } else if (layerDetails.z < 0) {
+      const zIndex = Math.min(maxLayerZIndexBelowDiagram, -1);
+      updateLayerZIndex(zIndex);
+    }
+  };
+
+  const moveToBack = (): void => {
+    if (layerDetails.z > 0) {
+      const zIndex = Math.max(minLayerZIndexAboveDiagram, 1);
+      updateLayerZIndex(zIndex);
+    } else if (layerDetails.z < 0) {
+      updateLayerZIndex(minLayerZIndexBelowDiagram);
+    }
+  };
+
+  const moveAboveDiagram = (): void => {
+    const zIndex = Math.max(minLayerZIndexAboveDiagram - 1, 1);
+    updateLayerZIndex(zIndex);
+  };
+
+  const moveBelowDiagram = (): void => {
+    const zIndex = Math.min(minLayerZIndexBelowDiagram + 1, -1);
+    updateLayerZIndex(zIndex);
+  };
+
   return (
     <div>
       <QuestionModal
@@ -101,9 +159,13 @@ export const LayersDrawerLayer = ({ layerId, layerName }: LayersDrawerLayerProps
         onConfirm={confirmRemove}
         question="Are you sure you want to remove the layer?"
       />
-      <div className="flex items-center justify-between py-3">
-        <span className={`font-semibold ${isLayerVisible ? 'opacity-100' : 'opacity-40'}`}>
-          {layerName}
+      <div className="flex items-center justify-between pb-3">
+        <span
+          className={`font-semibold ${
+            isLayerVisible ? 'opacity-100' : 'opacity-40'
+          } min-w-0 flex-1 truncate `}
+        >
+          {layerDetails.name}
         </span>
         <LayersDrawerLayerActions
           toggleVisibility={() =>
@@ -111,7 +173,7 @@ export const LayersDrawerLayer = ({ layerId, layerName }: LayersDrawerLayerProps
               setLayerVisibility({
                 modelId: currentModelId,
                 visible: !isLayerVisible,
-                layerId,
+                layerId: layerDetails.id,
               }),
             )
           }
@@ -120,12 +182,17 @@ export const LayersDrawerLayer = ({ layerId, layerName }: LayersDrawerLayerProps
           removeLayer={onRemoveLayer}
           addImage={addImage}
           addText={addText}
+          moveToFront={moveToFront}
+          moveToBack={moveToBack}
+          moveAboveDiagram={moveAboveDiagram}
+          moveBelowDiagram={moveBelowDiagram}
+          zIndex={layerDetails.z}
           isVisible={isLayerVisible}
           isActive={isLayerActive}
         />
       </div>
       <LayersDrawerObjectsList
-        layerId={layerId}
+        layerId={layerDetails.id}
         isLayerVisible={isLayerVisible}
         isLayerActive={isLayerActive}
       />
diff --git a/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayerActions.component.tsx b/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayerActions.component.tsx
index 18627b13..81435100 100644
--- a/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayerActions.component.tsx
+++ b/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayerActions.component.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable no-magic-numbers */
 import { IconButton } from '@/shared/IconButton';
 import { JSX } from 'react';
 import { LayerDrawerLayerContextMenu } from '@/components/Map/Drawer/LayersDrawer/LayerDrawerLayerContextMenu.component';
@@ -9,10 +10,15 @@ type LayersDrawerLayerActionsProps = {
   removeLayer: () => void;
   isVisible: boolean;
   isActive: boolean;
+  zIndex: number;
   toggleVisibility: () => void;
   toggleActiveLayer: (value: boolean) => void;
   addImage: () => void;
   addText: () => void;
+  moveToFront: () => void;
+  moveToBack: () => void;
+  moveAboveDiagram: () => void;
+  moveBelowDiagram: () => void;
 };
 
 export const LayersDrawerLayerActions = ({
@@ -20,10 +26,15 @@ export const LayersDrawerLayerActions = ({
   removeLayer,
   isVisible,
   isActive,
+  zIndex,
   toggleVisibility,
   toggleActiveLayer,
   addImage,
   addText,
+  moveToFront,
+  moveToBack,
+  moveAboveDiagram,
+  moveBelowDiagram,
 }: LayersDrawerLayerActionsProps): JSX.Element => {
   const hasPrivilegeToWriteProject = useAppSelector(hasPrivilegeToWriteProjectSelector);
 
@@ -43,6 +54,34 @@ export const LayersDrawerLayerActions = ({
             className="h-auto w-auto bg-transparent p-0"
             onClick={() => toggleActiveLayer(!isActive)}
           />
+          <IconButton
+            title="Move to front"
+            icon="move-front"
+            className="h-auto w-auto bg-transparent p-0"
+            onClick={moveToFront}
+          />
+          <IconButton
+            title="Move to back"
+            icon="move-back"
+            className="h-auto w-auto bg-transparent p-0"
+            onClick={moveToBack}
+          />
+          {zIndex < 0 && (
+            <IconButton
+              title="Move above the diagram"
+              icon="layer-arrow-up"
+              className="h-auto w-auto bg-transparent p-0"
+              onClick={moveAboveDiagram}
+            />
+          )}
+          {zIndex > 0 && (
+            <IconButton
+              title="Move below the diagram"
+              icon="layer-arrow-down"
+              className="h-auto w-auto bg-transparent p-0"
+              onClick={moveBelowDiagram}
+            />
+          )}
           <LayerDrawerLayerContextMenu
             removeLayer={removeLayer}
             editLayer={editLayer}
diff --git a/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectActions.component.tsx b/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectActions.component.tsx
index 4cf6871e..a97189ea 100644
--- a/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectActions.component.tsx
+++ b/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectActions.component.tsx
@@ -2,16 +2,16 @@ import { JSX } from 'react';
 import { IconButton } from '@/shared/IconButton';
 
 interface LayersDrawerObjectActionsProps {
-  bringToFront: () => void;
-  bringToBack: () => void;
+  moveToFront: () => void;
+  moveToBack: () => void;
   removeObject: () => void;
   centerObject: () => void;
   editObject: () => void;
 }
 
 export const LayersDrawerObjectActions = ({
-  bringToFront,
-  bringToBack,
+  moveToFront,
+  moveToBack,
   removeObject,
   centerObject,
   editObject,
@@ -31,16 +31,16 @@ export const LayersDrawerObjectActions = ({
         onClick={editObject}
       />
       <IconButton
-        icon="bring-front"
+        icon="move-front"
         className="h-auto w-auto bg-transparent p-0"
-        title="Bring to front"
-        onClick={bringToFront}
+        title="Move to front"
+        onClick={moveToFront}
       />
       <IconButton
-        icon="bring-back"
+        icon="move-back"
         className="h-auto w-auto bg-transparent p-0"
-        title="Bring to back"
-        onClick={bringToBack}
+        title="Move to back"
+        onClick={moveToBack}
       />
       <IconButton
         icon="trash"
diff --git a/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectsList.component.tsx b/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectsList.component.tsx
index 70a6acf5..9ec19fe4 100644
--- a/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectsList.component.tsx
+++ b/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectsList.component.tsx
@@ -1,9 +1,9 @@
 /* eslint-disable no-magic-numbers */
 import { useAppSelector } from '@/redux/hooks/useAppSelector';
 import {
-  highestZIndexSelector,
   layerByIdSelector,
-  lowestZIndexSelector,
+  maxObjectZIndexForLayerSelector,
+  minObjectZIndexForLayerSelector,
 } from '@/redux/layers/layers.selectors';
 import { JSX, useState } from 'react';
 import { LayersDrawerImageItem } from '@/components/Map/Drawer/LayersDrawer/LayersDrawerImageItem.component';
@@ -64,8 +64,8 @@ export const LayersDrawerObjectsList = ({
   isLayerActive,
 }: LayersDrawerObjectsListProps): JSX.Element | null => {
   const currentModelId = useAppSelector(mapModelIdSelector);
-  const highestZIndex = useAppSelector(highestZIndexSelector);
-  const lowestZIndex = useAppSelector(lowestZIndexSelector);
+  const maxZIndex = useAppSelector(state => maxObjectZIndexForLayerSelector(state, layerId));
+  const minZIndex = useAppSelector(state => minObjectZIndexForLayerSelector(state, layerId));
   const layer = useAppSelector(state => layerByIdSelector(state, layerId));
   const mapEditToolsLayerImageObject = useAppSelector(mapEditToolsLayerObjectSelector);
   const [removeModalState, setRemoveModalState] = useState<undefined | 'text' | 'image'>(undefined);
@@ -174,12 +174,12 @@ export const LayersDrawerObjectsList = ({
     }
   };
 
-  const bringImageToFront = async (layerImage: LayerImage): Promise<void> => {
-    await updateImageZIndex({ zIndex: highestZIndex + 1, layerImage });
+  const moveImageToFront = async (layerImage: LayerImage): Promise<void> => {
+    await updateImageZIndex({ zIndex: maxZIndex + 1, layerImage });
   };
 
-  const bringImageToBack = async (layerImage: LayerImage): Promise<void> => {
-    await updateImageZIndex({ zIndex: lowestZIndex - 1, layerImage });
+  const moveImageToBack = async (layerImage: LayerImage): Promise<void> => {
+    await updateImageZIndex({ zIndex: minZIndex - 1, layerImage });
   };
 
   const updateTextZIndex = async ({
@@ -210,12 +210,12 @@ export const LayersDrawerObjectsList = ({
     }
   };
 
-  const bringTextToFront = async (layerText: LayerText): Promise<void> => {
-    await updateTextZIndex({ zIndex: highestZIndex + 1, layerText });
+  const moveTextToFront = async (layerText: LayerText): Promise<void> => {
+    await updateTextZIndex({ zIndex: maxZIndex + 1, layerText });
   };
 
-  const bringTextToBack = async (layerText: LayerText): Promise<void> => {
-    await updateTextZIndex({ zIndex: lowestZIndex - 1, layerText });
+  const moveTextToBack = async (layerText: LayerText): Promise<void> => {
+    await updateTextZIndex({ zIndex: minZIndex - 1, layerText });
   };
 
   const centerObject = (layerObject: LayerImage | LayerText): void => {
@@ -257,8 +257,8 @@ export const LayersDrawerObjectsList = ({
         <LayersDrawerTextItem
           layerText={layerText}
           key={layerText.id}
-          bringToFront={() => bringTextToFront(layerText)}
-          bringToBack={() => bringTextToBack(layerText)}
+          moveToFront={() => moveTextToFront(layerText)}
+          moveToBack={() => moveTextToBack(layerText)}
           removeObject={() => removeObject(layerText)}
           centerObject={() => centerObject(layerText)}
           editObject={() => editText()}
@@ -270,8 +270,8 @@ export const LayersDrawerObjectsList = ({
         <LayersDrawerImageItem
           layerImage={layerImage}
           key={layerImage.id}
-          bringToFront={() => bringImageToFront(layerImage)}
-          bringToBack={() => bringImageToBack(layerImage)}
+          moveToFront={() => moveImageToFront(layerImage)}
+          moveToBack={() => moveImageToBack(layerImage)}
           removeObject={() => removeObject(layerImage)}
           centerObject={() => centerObject(layerImage)}
           editObject={() => editImage()}
diff --git a/src/components/Map/MapViewer/utils/config/additionalLayers/useOlMapAdditionalLayers.ts b/src/components/Map/MapViewer/utils/config/additionalLayers/useOlMapAdditionalLayers.ts
index 5e378293..6d41944f 100644
--- a/src/components/Map/MapViewer/utils/config/additionalLayers/useOlMapAdditionalLayers.ts
+++ b/src/components/Map/MapViewer/utils/config/additionalLayers/useOlMapAdditionalLayers.ts
@@ -125,6 +125,7 @@ export const useOlMapAdditionalLayers = (
   const vectorLayers = useMemo(() => {
     return layersState.map(layer => {
       const additionalLayer = new Layer({
+        zIndex: layer.details.z,
         texts: layer.texts,
         rects: layer.rects,
         ovals: layer.ovals,
diff --git a/src/components/Map/MapViewer/utils/config/commentsLayer/useOlMapCommentsLayer.ts b/src/components/Map/MapViewer/utils/config/commentsLayer/useOlMapCommentsLayer.ts
index 7ac3b73b..a3640020 100644
--- a/src/components/Map/MapViewer/utils/config/commentsLayer/useOlMapCommentsLayer.ts
+++ b/src/components/Map/MapViewer/utils/config/commentsLayer/useOlMapCommentsLayer.ts
@@ -36,6 +36,7 @@ export const useOlMapCommentsLayer = (): VectorLayer<VectorSource<Feature<Geomet
 
   return useMemo(() => {
     const vectorLayer = new VectorLayer({
+      zIndex: Infinity,
       source: vectorSource,
     });
     vectorLayer.set('type', LAYER_TYPE.COMMENTS_LAYER);
diff --git a/src/components/Map/MapViewer/utils/config/mapCardLayer/useOlMapCardLayer.ts b/src/components/Map/MapViewer/utils/config/mapCardLayer/useOlMapCardLayer.ts
index 69cec807..db3dbad4 100644
--- a/src/components/Map/MapViewer/utils/config/mapCardLayer/useOlMapCardLayer.ts
+++ b/src/components/Map/MapViewer/utils/config/mapCardLayer/useOlMapCardLayer.ts
@@ -38,6 +38,7 @@ export const useOlMapCardLayer = (): VectorLayer<VectorSource<Feature<Polygon>>>
 
   return useMemo(() => {
     const vectorLayer = new VectorLayer({
+      zIndex: -Infinity,
       source: vectorSource,
       style: new Style({
         fill: new Fill({
diff --git a/src/components/Map/MapViewer/utils/config/pinsLayer/useOlMapPinsLayer.ts b/src/components/Map/MapViewer/utils/config/pinsLayer/useOlMapPinsLayer.ts
index f7b6001c..4cd5a32b 100644
--- a/src/components/Map/MapViewer/utils/config/pinsLayer/useOlMapPinsLayer.ts
+++ b/src/components/Map/MapViewer/utils/config/pinsLayer/useOlMapPinsLayer.ts
@@ -77,6 +77,7 @@ export const useOlMapPinsLayer = (): VectorLayer<VectorSource<Feature<Geometry>>
 
   return useMemo(() => {
     const vectorLayer = new VectorLayer({
+      zIndex: Infinity,
       source: vectorSource,
     });
     vectorLayer.set('type', LAYER_TYPE.PINS_LAYER);
diff --git a/src/components/Map/MapViewer/utils/config/processLayer/useOlMapProcessLayer.ts b/src/components/Map/MapViewer/utils/config/processLayer/useOlMapProcessLayer.ts
index 2811ec30..98cb6e1e 100644
--- a/src/components/Map/MapViewer/utils/config/processLayer/useOlMapProcessLayer.ts
+++ b/src/components/Map/MapViewer/utils/config/processLayer/useOlMapProcessLayer.ts
@@ -274,6 +274,7 @@ export const useOlMapProcessLayer = ({
 
   return useMemo(() => {
     const vectorLayer = new VectorLayer({
+      zIndex: 0,
       source: vectorSource,
       updateWhileAnimating: true,
       updateWhileInteracting: true,
diff --git a/src/components/Map/MapViewer/utils/config/reactionsLayer/useOlMapReactionsLayer.ts b/src/components/Map/MapViewer/utils/config/reactionsLayer/useOlMapReactionsLayer.ts
index bfb2668e..df526271 100644
--- a/src/components/Map/MapViewer/utils/config/reactionsLayer/useOlMapReactionsLayer.ts
+++ b/src/components/Map/MapViewer/utils/config/reactionsLayer/useOlMapReactionsLayer.ts
@@ -63,6 +63,7 @@ export const useOlMapReactionsLayer = (): VectorLayer<VectorSource<Feature<Geome
 
   return useMemo(() => {
     const vectorLayer = new VectorLayer({
+      zIndex: Infinity,
       source: vectorSource,
       style: new Style({
         fill: new Fill({ color: LINE_COLOR }),
diff --git a/src/components/Map/MapViewer/utils/shapes/layer/Layer.test.ts b/src/components/Map/MapViewer/utils/shapes/layer/Layer.test.ts
index 7b8bb971..10349c6d 100644
--- a/src/components/Map/MapViewer/utils/shapes/layer/Layer.test.ts
+++ b/src/components/Map/MapViewer/utils/shapes/layer/Layer.test.ts
@@ -133,6 +133,7 @@ describe('Layer', () => {
       pointToProjection: jest.fn(point => [point.x, point.y]),
       mapInstance,
       mapSize,
+      zIndex: 1,
       lineTypes: {},
       arrowTypes: {},
     };
diff --git a/src/components/Map/MapViewer/utils/shapes/layer/Layer.ts b/src/components/Map/MapViewer/utils/shapes/layer/Layer.ts
index 7f697a72..14d5f8b5 100644
--- a/src/components/Map/MapViewer/utils/shapes/layer/Layer.ts
+++ b/src/components/Map/MapViewer/utils/shapes/layer/Layer.ts
@@ -34,6 +34,7 @@ import LayerText from '@/components/Map/MapViewer/utils/shapes/layer/elements/La
 import LayerImage from '@/components/Map/MapViewer/utils/shapes/layer/elements/LayerImage';
 
 export interface LayerProps {
+  zIndex: number;
   texts: { [key: string]: LayerTextModel };
   rects: Array<LayerRect>;
   ovals: Array<LayerOval>;
@@ -78,6 +79,7 @@ export default class Layer {
   >;
 
   constructor({
+    zIndex,
     texts,
     rects,
     ovals,
@@ -118,6 +120,7 @@ export default class Layer {
     this.vectorSource.addFeatures(arrowsFeatures);
 
     this.vectorLayer = new VectorLayer({
+      zIndex,
       source: this.vectorSource,
       visible,
       updateWhileAnimating: true,
diff --git a/src/models/layerSchema.ts b/src/models/layerSchema.ts
index 380146a7..11fcd88d 100644
--- a/src/models/layerSchema.ts
+++ b/src/models/layerSchema.ts
@@ -5,4 +5,5 @@ export const layerSchema = z.object({
   name: z.string(),
   visible: z.boolean(),
   locked: z.boolean(),
+  z: z.number(),
 });
diff --git a/src/redux/layers/layers.reducers.test.ts b/src/redux/layers/layers.reducers.test.ts
index 7bcb10ba..d93fb4f8 100644
--- a/src/redux/layers/layers.reducers.test.ts
+++ b/src/redux/layers/layers.reducers.test.ts
@@ -92,7 +92,7 @@ describe('layers reducer', () => {
 
     const { type } = await store.dispatch(getLayersForModel(1));
     const { data, loading, error } = store.getState().layers[1];
-    expect(type).toBe('vectorMap/getLayers/fulfilled');
+    expect(type).toBe('layers/getLayers/fulfilled');
     expect(loading).toEqual('succeeded');
     expect(error).toEqual({ message: '', name: '' });
     expect(data).toEqual({
@@ -120,7 +120,7 @@ describe('layers reducer', () => {
     const action = await store.dispatch(getLayersForModel(1));
     const { data, loading, error } = store.getState().layers[1];
 
-    expect(action.type).toBe('vectorMap/getLayers/rejected');
+    expect(action.type).toBe('layers/getLayers/rejected');
     expect(() => unwrapResult(action)).toThrow(
       "Failed to fetch layers: The page you're looking for doesn't exist. Please verify the URL and try again.",
     );
diff --git a/src/redux/layers/layers.selectors.ts b/src/redux/layers/layers.selectors.ts
index 8f016c8a..8123fa00 100644
--- a/src/redux/layers/layers.selectors.ts
+++ b/src/redux/layers/layers.selectors.ts
@@ -2,6 +2,7 @@
 import { createSelector } from '@reduxjs/toolkit';
 import { rootSelector } from '@/redux/root/root.selectors';
 import { currentModelIdSelector } from '@/redux/models/models.selectors';
+import { LayerState } from '@/redux/layers/layers.types';
 
 export const layersSelector = createSelector(rootSelector, state => state.layers);
 
@@ -18,7 +19,7 @@ export const layersActiveLayersSelector = createSelector(
 
 export const layersDrawLayerSelector = createSelector(
   layersStateForCurrentModelSelector,
-  state => state?.data?.drawLayer,
+  state => state?.data?.drawLayer || null,
 );
 
 export const layerByIdSelector = createSelector(
@@ -41,40 +42,112 @@ export const layersForCurrentModelSelector = createSelector(
   state => state?.data?.layers || [],
 );
 
-export const highestZIndexSelector = createSelector(layersForCurrentModelSelector, layers => {
-  if (!layers || layers.length === 0) return 0;
-
-  const getMaxZFromItems = <T extends { z?: number }>(items: T[] = []): number =>
-    items.length > 0 ? Math.max(...items.map(item => item.z || 0)) : 0;
-
-  return layers.reduce((maxZ, layer) => {
-    const textsMaxZ = getMaxZFromItems(Object.values(layer.texts));
-    const rectsMaxZ = getMaxZFromItems(layer.rects);
-    const ovalsMaxZ = getMaxZFromItems(layer.ovals);
-    const linesMaxZ = getMaxZFromItems(layer.lines);
-    const imagesMaxZ = getMaxZFromItems(Object.values(layer.images));
-
-    const layerMaxZ = Math.max(textsMaxZ, rectsMaxZ, ovalsMaxZ, linesMaxZ, imagesMaxZ);
-
-    return Math.max(maxZ, layerMaxZ);
-  }, 0);
-});
+export const maxLayerZIndexAboveDiagramSelector = createSelector(
+  layersForCurrentModelSelector,
+  layers => {
+    if (!layers || layers.length === 0) {
+      return 1000;
+    }
+    let maxZIndex = -Infinity;
+    layers.forEach((layer: LayerState) => {
+      if (layer.details.z > 0 && layer.details.z > maxZIndex) {
+        maxZIndex = layer.details.z;
+      }
+    });
+    return maxZIndex;
+  },
+);
 
-export const lowestZIndexSelector = createSelector(layersForCurrentModelSelector, layers => {
-  if (!layers || layers.length === 0) return 0;
+export const maxLayerZIndexBelowDiagramSelector = createSelector(
+  layersForCurrentModelSelector,
+  layers => {
+    if (!layers || layers.length === 0) {
+      return -1000;
+    }
+    let maxZIndex = -Infinity;
+    layers.forEach((layer: LayerState) => {
+      if (layer.details.z < 0 && layer.details.z > maxZIndex) {
+        maxZIndex = layer.details.z;
+      }
+    });
+    return maxZIndex;
+  },
+);
 
-  const getMinZFromItems = <T extends { z?: number }>(items: T[] = []): number =>
-    items.length > 0 ? Math.min(...items.map(item => item.z || 0)) : 0;
+export const minLayerZIndexAboveDiagramSelector = createSelector(
+  layersForCurrentModelSelector,
+  layers => {
+    if (!layers || layers.length === 0) {
+      return 1000;
+    }
+    let minZIndex = Infinity;
+    layers.forEach((layer: LayerState) => {
+      if (layer.details.z > 0 && layer.details.z < minZIndex) {
+        minZIndex = layer.details.z;
+      }
+    });
+    return minZIndex;
+  },
+);
 
-  return layers.reduce((minZ, layer) => {
-    const textsMinZ = getMinZFromItems(Object.values(layer.texts));
-    const rectsMinZ = getMinZFromItems(layer.rects);
-    const ovalsMinZ = getMinZFromItems(layer.ovals);
-    const linesMinZ = getMinZFromItems(layer.lines);
-    const imagesMinZ = getMinZFromItems(Object.values(layer.images));
+export const minLayerZIndexBelowDiagramSelector = createSelector(
+  layersForCurrentModelSelector,
+  layers => {
+    if (!layers || layers.length === 0) {
+      return -1000;
+    }
+    let minZIndex = Infinity;
+    layers.forEach((layer: LayerState) => {
+      if (layer.details.z < 0 && layer.details.z < minZIndex) {
+        minZIndex = layer.details.z;
+      }
+    });
+    return minZIndex;
+  },
+);
 
-    const layerMinZ = Math.min(textsMinZ, rectsMinZ, ovalsMinZ, linesMinZ, imagesMinZ);
+export const maxObjectZIndexForLayerSelector = createSelector(
+  [layersForCurrentModelSelector, (_state, layerId: number | null): number | null => layerId],
+  (layers, layerId) => {
+    if (!layers || layers.length === 0 || !layerId) {
+      return 0;
+    }
+    const foundLayer = layers.find(layer => layer.details.id === layerId);
+    if (!foundLayer) {
+      return 0;
+    }
+    const getMaxZFromItems = <T extends { z?: number }>(items: T[] = []): number =>
+      items.length > 0 ? Math.max(...items.map(item => item.z || 0)) : 0;
+
+    const textsMaxZ = getMaxZFromItems(Object.values(foundLayer.texts));
+    const rectsMaxZ = getMaxZFromItems(foundLayer.rects);
+    const ovalsMaxZ = getMaxZFromItems(foundLayer.ovals);
+    const linesMaxZ = getMaxZFromItems(foundLayer.lines);
+    const imagesMaxZ = getMaxZFromItems(Object.values(foundLayer.images));
+
+    return Math.max(textsMaxZ, rectsMaxZ, ovalsMaxZ, linesMaxZ, imagesMaxZ);
+  },
+);
 
-    return Math.min(minZ, layerMinZ);
-  }, 0);
-});
+export const minObjectZIndexForLayerSelector = createSelector(
+  [layersForCurrentModelSelector, (_state, layerId: number | null): number | null => layerId],
+  (layers, layerId) => {
+    if (!layers || layers.length === 0 || !layerId) {
+      return 0;
+    }
+    const foundLayer = layers.find(layer => layer.details.id === layerId);
+    if (!foundLayer) {
+      return 0;
+    }
+    const getMinZFromItems = <T extends { z?: number }>(items: T[] = []): number =>
+      items.length > 0 ? Math.min(...items.map(item => item.z || 0)) : 0;
+
+    const textsMinZ = getMinZFromItems(Object.values(foundLayer.texts));
+    const rectsMinZ = getMinZFromItems(foundLayer.rects);
+    const ovalsMinZ = getMinZFromItems(foundLayer.ovals);
+    const linesMinZ = getMinZFromItems(foundLayer.lines);
+    const imagesMinZ = getMinZFromItems(Object.values(foundLayer.images));
+
+    return Math.min(textsMinZ, rectsMinZ, ovalsMinZ, linesMinZ, imagesMinZ);
+  },
+);
diff --git a/src/redux/layers/layers.thunks.test.ts b/src/redux/layers/layers.thunks.test.ts
index 77e10bdb..09028272 100644
--- a/src/redux/layers/layers.thunks.test.ts
+++ b/src/redux/layers/layers.thunks.test.ts
@@ -111,7 +111,13 @@ describe('layers thunks', () => {
       mockedAxiosClient.onPost(apiPath.storeLayer(1)).reply(HttpStatusCode.Created, layerFixture);
 
       const { payload } = await store.dispatch(
-        addLayerForModel({ name: 'New Layer', visible: true, locked: false, modelId: 1 }),
+        addLayerForModel({
+          name: 'New Layer',
+          visible: true,
+          locked: false,
+          modelId: 1,
+          zIndex: 1,
+        }),
       );
       expect(payload).toEqual(layerFixture);
     });
@@ -122,7 +128,13 @@ describe('layers thunks', () => {
         .reply(HttpStatusCode.Created, { invalid: 'data' });
 
       const { payload } = await store.dispatch(
-        addLayerForModel({ name: 'New Layer', visible: true, locked: false, modelId: 1 }),
+        addLayerForModel({
+          name: 'New Layer',
+          visible: true,
+          locked: false,
+          modelId: 1,
+          zIndex: 1,
+        }),
       );
       expect(payload).toBeNull();
     });
@@ -139,6 +151,7 @@ describe('layers thunks', () => {
           locked: true,
           modelId: 1,
           layerId: 2,
+          zIndex: 1,
         }),
       );
       expect(payload).toEqual(layerFixture);
@@ -156,6 +169,7 @@ describe('layers thunks', () => {
           locked: true,
           modelId: 1,
           layerId: 2,
+          zIndex: 1,
         }),
       );
       expect(payload).toBeNull();
diff --git a/src/redux/layers/layers.thunks.ts b/src/redux/layers/layers.thunks.ts
index 66035fd8..bda72fce 100644
--- a/src/redux/layers/layers.thunks.ts
+++ b/src/redux/layers/layers.thunks.ts
@@ -32,7 +32,7 @@ export const getLayer = createAsyncThunk<
   Layer | null,
   { modelId: number; layerId: number },
   ThunkConfig
->('vectorMap/getLayer', async ({ modelId, layerId }) => {
+>('layers/getLayer', async ({ modelId, layerId }) => {
   try {
     const { data } = await axiosInstanceNewAPI.get<Layer>(apiPath.getLayer(modelId, layerId));
 
@@ -48,7 +48,7 @@ export const getLayersForModel = createAsyncThunk<
   LayersVisibilitiesState | undefined,
   number,
   ThunkConfig
->('vectorMap/getLayers', async (modelId: number) => {
+>('layers/getLayers', async (modelId: number) => {
   try {
     const { data } = await axiosInstanceNewAPI.get<Layers>(apiPath.getLayers(modelId));
     const isDataValid = validateDataUsingZodSchema(data, pageableSchema(layerSchema));
@@ -103,13 +103,14 @@ export const getLayersForModel = createAsyncThunk<
 });
 
 export const addLayerForModel = createAsyncThunk<Layer | null, LayerStoreInterface, ThunkConfig>(
-  'vectorMap/addLayer',
-  async ({ name, visible, locked, modelId }) => {
+  'layers/addLayer',
+  async ({ name, visible, locked, modelId, zIndex }) => {
     try {
       const { data } = await axiosInstanceNewAPI.post<Layer>(apiPath.storeLayer(modelId), {
         name,
         visible,
         locked,
+        z: zIndex,
       });
 
       const isDataValid = validateDataUsingZodSchema(data, layerSchema);
@@ -122,13 +123,14 @@ export const addLayerForModel = createAsyncThunk<Layer | null, LayerStoreInterfa
 );
 
 export const updateLayer = createAsyncThunk<Layer | null, LayerUpdateInterface, ThunkConfig>(
-  'vectorMap/updateLayer',
-  async ({ name, visible, locked, modelId, layerId }) => {
+  'layers/updateLayer',
+  async ({ name, visible, locked, modelId, layerId, zIndex }) => {
     try {
       const { data } = await axiosInstanceNewAPI.put<Layer>(apiPath.updateLayer(modelId, layerId), {
         name,
         visible,
         locked,
+        z: zIndex,
       });
 
       const isDataValid = validateDataUsingZodSchema(data, layerSchema);
@@ -144,7 +146,7 @@ export const removeLayer = createAsyncThunk<
   null,
   { modelId: number; layerId: number },
   ThunkConfig
->('vectorMap/removeLayer', async ({ modelId, layerId }) => {
+>('layers/removeLayer', async ({ modelId, layerId }) => {
   try {
     await axiosInstanceNewAPI.delete<void>(apiPath.removeLayer(modelId, layerId));
     return null;
@@ -161,7 +163,7 @@ export const getLayerImage = createAsyncThunk<
     imageId: number;
   },
   ThunkConfig
->('vectorMap/getLayerImage', async ({ modelId, layerId, imageId }) => {
+>('layers/getLayerImage', async ({ modelId, layerId, imageId }) => {
   try {
     const { data } = await axiosInstanceNewAPI.get<LayerImage>(
       apiPath.getLayerImageObject(modelId, layerId, imageId),
@@ -187,7 +189,7 @@ export const addLayerImageObject = createAsyncThunk<
     glyph: number | null;
   },
   ThunkConfig
->('vectorMap/addLayerImageObject', async ({ modelId, layerId, x, y, z, width, height, glyph }) => {
+>('layers/addLayerImageObject', async ({ modelId, layerId, x, y, z, width, height, glyph }) => {
   try {
     const { data } = await axiosInstanceNewAPI.post<LayerImage>(
       apiPath.addLayerImageObject(modelId, layerId),
@@ -223,7 +225,7 @@ export const updateLayerImageObject = createAsyncThunk<
   },
   ThunkConfig
 >(
-  'vectorMap/updateLayerImageObject',
+  'layers/updateLayerImageObject',
   async ({ modelId, layerId, id, x, y, z, width, height, glyph }) => {
     try {
       const { data } = await axiosInstanceNewAPI.put<LayerImage>(
@@ -252,7 +254,7 @@ export const removeLayerImage = createAsyncThunk<
   null,
   { modelId: number; layerId: number; imageId: number },
   ThunkConfig
->('vectorMap/removeLayerImage', async ({ modelId, layerId, imageId }) => {
+>('layers/removeLayerImage', async ({ modelId, layerId, imageId }) => {
   try {
     await axiosInstanceNewAPI.delete<void>(
       apiPath.removeLayerImageObject(modelId, layerId, imageId),
@@ -273,7 +275,7 @@ export const addLayerText = createAsyncThunk<
     textData: LayerTextFactoryForm;
   },
   ThunkConfig
->('vectorMap/addLayerText', async ({ modelId, layerId, z, boundingBox, textData }) => {
+>('layers/addLayerText', async ({ modelId, layerId, z, boundingBox, textData }) => {
   try {
     const { data } = await axiosInstanceNewAPI.post<LayerText>(
       apiPath.addLayerText(modelId, layerId),
@@ -299,7 +301,7 @@ export const getLayerText = createAsyncThunk<
     textId: number;
   },
   ThunkConfig
->('vectorMap/getLayerText', async ({ modelId, layerId, textId }) => {
+>('layers/getLayerText', async ({ modelId, layerId, textId }) => {
   try {
     const { data } = await axiosInstanceNewAPI.get<LayerText>(
       apiPath.getLayerText(modelId, layerId, textId),
diff --git a/src/redux/layers/layers.types.ts b/src/redux/layers/layers.types.ts
index 60e42717..05b4636e 100644
--- a/src/redux/layers/layers.types.ts
+++ b/src/redux/layers/layers.types.ts
@@ -6,6 +6,7 @@ export interface LayerStoreInterface {
   visible: boolean;
   locked: boolean;
   modelId: number;
+  zIndex: number;
 }
 
 export interface LayerUpdateInterface {
@@ -14,6 +15,7 @@ export interface LayerUpdateInterface {
   visible: boolean;
   locked: boolean;
   modelId: number;
+  zIndex: number;
 }
 
 export type LayerState = {
diff --git a/src/shared/Icon/Icon.component.tsx b/src/shared/Icon/Icon.component.tsx
index 5745b6ec..aed961c3 100644
--- a/src/shared/Icon/Icon.component.tsx
+++ b/src/shared/Icon/Icon.component.tsx
@@ -31,8 +31,10 @@ import { PadlockOpenIcon } from '@/shared/Icon/Icons/PadlockOpenIcon';
 import { PadlockLockedIcon } from '@/shared/Icon/Icons/PadlockLockedIcon';
 import { CrossedEyeIcon } from '@/shared/Icon/Icons/CrossedEyeIcon';
 import { CenterIcon } from '@/shared/Icon/Icons/CenterIcon';
-import { BringFrontIcon } from '@/shared/Icon/Icons/BringFrontIcon';
-import { BringBackIcon } from '@/shared/Icon/Icons/BringBackIcon';
+import { MoveFrontIcon } from '@/shared/Icon/Icons/MoveFrontIcon';
+import { MoveBackIcon } from '@/shared/Icon/Icons/MoveBackIcon';
+import { LayerArrowUpIcon } from '@/shared/Icon/Icons/LayerArrowUpIcon';
+import { LayerArrowDownIcon } from '@/shared/Icon/Icons/LayerArrowDownIcon';
 import { LocationIcon } from './Icons/LocationIcon';
 import { MaginfierZoomInIcon } from './Icons/MagnifierZoomIn';
 import { MaginfierZoomOutIcon } from './Icons/MagnifierZoomOut';
@@ -87,8 +89,10 @@ const icons: Record<IconTypes, IconComponentType> = {
   'padlock-open': PadlockOpenIcon,
   'padlock-locked': PadlockLockedIcon,
   center: CenterIcon,
-  'bring-front': BringFrontIcon,
-  'bring-back': BringBackIcon,
+  'move-front': MoveFrontIcon,
+  'move-back': MoveBackIcon,
+  'layer-arrow-up': LayerArrowUpIcon,
+  'layer-arrow-down': LayerArrowDownIcon,
 } as const;
 
 export const Icon = ({ name, className = '', ...rest }: IconProps): JSX.Element => {
diff --git a/src/shared/Icon/Icons/ArrowDoubleDownIcon.tsx b/src/shared/Icon/Icons/ArrowDoubleDownIcon.tsx
index d7ab4e38..cf5ce5f7 100644
--- a/src/shared/Icon/Icons/ArrowDoubleDownIcon.tsx
+++ b/src/shared/Icon/Icons/ArrowDoubleDownIcon.tsx
@@ -13,26 +13,16 @@ export const ArrowDoubleDownIcon = ({ className }: ArrowDoubleDownIconProps): JS
   >
     <path
       d="M8 8L8 18M8 18L5 15M8 18L11 15"
-      stroke="currentColor"
       strokeWidth="1.5"
       strokeLinecap="round"
       strokeLinejoin="round"
     />
     <path
       d="M16 8L16 18M16 18L13 15M16 18L19 15"
-      stroke="currentColor"
       strokeWidth="1.5"
       strokeLinecap="round"
       strokeLinejoin="round"
     />
-    <line
-      x1="4"
-      y1="6"
-      x2="20"
-      y2="6"
-      stroke="currentColor"
-      strokeWidth="1.5"
-      strokeLinecap="round"
-    />
+    <line x1="4" y1="6" x2="20" y2="6" strokeWidth="1.5" strokeLinecap="round" />
   </svg>
 );
diff --git a/src/shared/Icon/Icons/ArrowDoubleUpIcon.tsx b/src/shared/Icon/Icons/ArrowDoubleUpIcon.tsx
index ed51a602..861773cd 100644
--- a/src/shared/Icon/Icons/ArrowDoubleUpIcon.tsx
+++ b/src/shared/Icon/Icons/ArrowDoubleUpIcon.tsx
@@ -13,26 +13,16 @@ export const ArrowDoubleUpIcon = ({ className }: ArrowDoubleUpIconProps): JSX.El
   >
     <path
       d="M8 16L8 6M8 6L5 9M8 6L11 9"
-      stroke="currentColor"
       strokeWidth="1.5"
       strokeLinecap="round"
       strokeLinejoin="round"
     />
     <path
       d="M16 16L16 6M16 6L13 9M16 6L19 9"
-      stroke="currentColor"
       strokeWidth="1.5"
       strokeLinecap="round"
       strokeLinejoin="round"
     />
-    <line
-      x1="4"
-      y1="18"
-      x2="20"
-      y2="18"
-      stroke="currentColor"
-      strokeWidth="1.5"
-      strokeLinecap="round"
-    />
+    <line x1="4" y1="18" x2="20" y2="18" strokeWidth="1.5" strokeLinecap="round" />
   </svg>
 );
diff --git a/src/shared/Icon/Icons/LayerArrowDownIcon.tsx b/src/shared/Icon/Icons/LayerArrowDownIcon.tsx
new file mode 100644
index 00000000..71223a31
--- /dev/null
+++ b/src/shared/Icon/Icons/LayerArrowDownIcon.tsx
@@ -0,0 +1,18 @@
+interface LayerArrowDownIconProps {
+  className?: string;
+}
+
+export const LayerArrowDownIcon = ({ className }: LayerArrowDownIconProps): JSX.Element => (
+  <svg
+    width="20"
+    height="20"
+    viewBox="2 3 20 17"
+    fill="none"
+    xmlns="http://www.w3.org/2000/svg"
+    className={className}
+  >
+    <path d="M12 21L7 16H10V10H14V16H17L12 21Z" />
+    <rect x="4" y="3" width="16" height="2" />
+    <rect x="4" y="7" width="16" height="2" />
+  </svg>
+);
diff --git a/src/shared/Icon/Icons/LayerArrowUpIcon.tsx b/src/shared/Icon/Icons/LayerArrowUpIcon.tsx
new file mode 100644
index 00000000..bbcf233f
--- /dev/null
+++ b/src/shared/Icon/Icons/LayerArrowUpIcon.tsx
@@ -0,0 +1,18 @@
+interface LayerArrowUpIconProps {
+  className?: string;
+}
+
+export const LayerArrowUpIcon = ({ className }: LayerArrowUpIconProps): JSX.Element => (
+  <svg
+    width="20"
+    height="20"
+    viewBox="2 3 20 19"
+    fill="none"
+    xmlns="http://www.w3.org/2000/svg"
+    className={className}
+  >
+    <path d="M12 3L7 8H10V14H14V8H17L12 3Z" />
+    <rect x="4" y="16" width="16" height="2" />
+    <rect x="4" y="20" width="16" height="2" />
+  </svg>
+);
diff --git a/src/shared/Icon/Icons/BringBackIcon.tsx b/src/shared/Icon/Icons/MoveBackIcon.tsx
similarity index 78%
rename from src/shared/Icon/Icons/BringBackIcon.tsx
rename to src/shared/Icon/Icons/MoveBackIcon.tsx
index d086ac9b..734bd201 100644
--- a/src/shared/Icon/Icons/BringBackIcon.tsx
+++ b/src/shared/Icon/Icons/MoveBackIcon.tsx
@@ -1,8 +1,8 @@
-interface BringBackIconProps {
+interface MoveBackIconProps {
   className?: string;
 }
 
-export const BringBackIcon = ({ className }: BringBackIconProps): JSX.Element => (
+export const MoveBackIcon = ({ className }: MoveBackIconProps): JSX.Element => (
   <svg
     width="20"
     height="20"
@@ -23,6 +23,6 @@ export const BringBackIcon = ({ className }: BringBackIconProps): JSX.Element =>
       stroke="white"
       fill="none"
     />
-    <rect x="4" y="4" width="64" height="64" rx="10" ry="10" strokeWidth="8" fill="black" />
+    <rect x="4" y="4" width="64" height="64" rx="10" ry="10" strokeWidth="8" />
   </svg>
 );
diff --git a/src/shared/Icon/Icons/BringFrontIcon.tsx b/src/shared/Icon/Icons/MoveFrontIcon.tsx
similarity index 77%
rename from src/shared/Icon/Icons/BringFrontIcon.tsx
rename to src/shared/Icon/Icons/MoveFrontIcon.tsx
index e5aa5017..037f5cb3 100644
--- a/src/shared/Icon/Icons/BringFrontIcon.tsx
+++ b/src/shared/Icon/Icons/MoveFrontIcon.tsx
@@ -1,8 +1,8 @@
-interface BringFrontIconProps {
+interface MoveFrontIconProps {
   className?: string;
 }
 
-export const BringFrontIcon = ({ className }: BringFrontIconProps): JSX.Element => (
+export const MoveFrontIcon = ({ className }: MoveFrontIconProps): JSX.Element => (
   <svg
     width="20"
     height="20"
@@ -11,7 +11,7 @@ export const BringFrontIcon = ({ className }: BringFrontIconProps): JSX.Element
     fill="none"
     className={className}
   >
-    <rect x="4" y="4" width="64" height="64" rx="10" ry="10" strokeWidth="8" fill="black" />
+    <rect x="4" y="4" width="64" height="64" rx="10" ry="10" strokeWidth="8" />
     <rect
       x="30"
       y="30"
diff --git a/src/shared/IconButton/IconButton.component.tsx b/src/shared/IconButton/IconButton.component.tsx
index 1330e460..e71c6211 100644
--- a/src/shared/IconButton/IconButton.component.tsx
+++ b/src/shared/IconButton/IconButton.component.tsx
@@ -29,8 +29,8 @@ export const IconButton = ({
 
   const isStrokeIcon = [
     'plugin',
-    'bring-back',
-    'bring-front',
+    'move-back',
+    'move-front',
     'center',
     'eye',
     'crossed-eye',
@@ -38,6 +38,8 @@ export const IconButton = ({
     'padlock-locked',
     'layers',
     'edit',
+    'arrow-double-up',
+    'arrow-double-down',
   ].includes(icon);
 
   return (
@@ -57,6 +59,8 @@ export const IconButton = ({
           isStrokeIcon
             ? 'stroke-font-400 group-hover:stroke-primary-500 group-active:stroke-primary-500'
             : 'fill-font-400 group-hover:fill-primary-500 group-active:fill-primary-500',
+          ['move-back', 'move-front'].includes(icon) &&
+            'fill-font-400 stroke-font-400 group-hover:fill-primary-500 group-hover:stroke-primary-500 group-active:fill-primary-500 group-active:stroke-primary-500',
           isActive && getActiveFillOrStrokeColor(icon),
           classNameIcon,
         )}
diff --git a/src/types/iconTypes.ts b/src/types/iconTypes.ts
index 0d74dd78..0083a622 100644
--- a/src/types/iconTypes.ts
+++ b/src/types/iconTypes.ts
@@ -38,7 +38,9 @@ export type IconTypes =
   | 'padlock-open'
   | 'padlock-locked'
   | 'center'
-  | 'bring-front'
-  | 'bring-back';
+  | 'move-front'
+  | 'move-back'
+  | 'layer-arrow-up'
+  | 'layer-arrow-down';
 
 export type IconComponentType = ({ className }: { className: string }) => JSX.Element;
-- 
GitLab


From f6e504ece2951e59900cec58b70bec18b21b4bde Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mi=C5=82osz=20Grocholewski?= <m.grocholewski@atcomp.pl>
Date: Tue, 18 Feb 2025 10:19:22 +0100
Subject: [PATCH 4/8] Revert "feat(layers): add layers zIndex editing"

This reverts commit 7f8d0b665cbd00568e46ba57597c5d22ab28192b.
---
 .../LayerFactoryModal.component.tsx           |   4 -
 ...LayerImageObjectFactoryModal.component.tsx |   9 +-
 .../LayerTextFactoryModal.component.tsx       |   9 +-
 .../LayerDrawerTextItem.component.tsx         |  12 +-
 .../LayersDrawer/LayersDrawer.component.tsx   |  46 ++----
 .../LayersDrawerImageItem.component.tsx       |  12 +-
 .../LayersDrawerLayer.component.tsx           | 107 +++-----------
 .../LayersDrawerLayerActions.component.tsx    |  39 -----
 .../LayersDrawerObjectActions.component.tsx   |  20 +--
 .../LayersDrawerObjectsList.component.tsx     |  32 ++--
 .../useOlMapAdditionalLayers.ts               |   1 -
 .../commentsLayer/useOlMapCommentsLayer.ts    |   1 -
 .../config/mapCardLayer/useOlMapCardLayer.ts  |   1 -
 .../config/pinsLayer/useOlMapPinsLayer.ts     |   1 -
 .../processLayer/useOlMapProcessLayer.ts      |   1 -
 .../reactionsLayer/useOlMapReactionsLayer.ts  |   1 -
 .../utils/shapes/layer/Layer.test.ts          |   1 -
 .../Map/MapViewer/utils/shapes/layer/Layer.ts |   3 -
 src/models/layerSchema.ts                     |   1 -
 src/redux/layers/layers.reducers.test.ts      |   4 +-
 src/redux/layers/layers.selectors.ts          | 139 +++++-------------
 src/redux/layers/layers.thunks.test.ts        |  18 +--
 src/redux/layers/layers.thunks.ts             |  28 ++--
 src/redux/layers/layers.types.ts              |   2 -
 src/shared/Icon/Icon.component.tsx            |  12 +-
 src/shared/Icon/Icons/ArrowDoubleDownIcon.tsx |  12 +-
 src/shared/Icon/Icons/ArrowDoubleUpIcon.tsx   |  12 +-
 .../{MoveBackIcon.tsx => BringBackIcon.tsx}   |   6 +-
 .../{MoveFrontIcon.tsx => BringFrontIcon.tsx} |   6 +-
 src/shared/Icon/Icons/LayerArrowDownIcon.tsx  |  18 ---
 src/shared/Icon/Icons/LayerArrowUpIcon.tsx    |  18 ---
 .../IconButton/IconButton.component.tsx       |   8 +-
 src/types/iconTypes.ts                        |   6 +-
 33 files changed, 160 insertions(+), 430 deletions(-)
 rename src/shared/Icon/Icons/{MoveBackIcon.tsx => BringBackIcon.tsx} (78%)
 rename src/shared/Icon/Icons/{MoveFrontIcon.tsx => BringFrontIcon.tsx} (77%)
 delete mode 100644 src/shared/Icon/Icons/LayerArrowDownIcon.tsx
 delete mode 100644 src/shared/Icon/Icons/LayerArrowUpIcon.tsx

diff --git a/src/components/FunctionalArea/Modal/LayerFactoryModal/LayerFactoryModal.component.tsx b/src/components/FunctionalArea/Modal/LayerFactoryModal/LayerFactoryModal.component.tsx
index b806d2b6..8d925951 100644
--- a/src/components/FunctionalArea/Modal/LayerFactoryModal/LayerFactoryModal.component.tsx
+++ b/src/components/FunctionalArea/Modal/LayerFactoryModal/LayerFactoryModal.component.tsx
@@ -19,13 +19,11 @@ import { SerializedError } from '@reduxjs/toolkit';
 import { layerFactoryStateSelector } from '@/redux/modal/modal.selector';
 import './LayerFactoryModal.styles.css';
 import { LoadingIndicator } from '@/shared/LoadingIndicator';
-import { maxLayerZIndexAboveDiagramSelector } from '@/redux/layers/layers.selectors';
 
 export const LayerFactoryModal: React.FC = () => {
   const dispatch = useAppDispatch();
   const currentModelId = useAppSelector(currentModelIdSelector);
   const layerFactoryState = useAppSelector(layerFactoryStateSelector);
-  const maxLayerZIndexAboveDiagram = useAppSelector(maxLayerZIndexAboveDiagramSelector);
   const [loaded, setLoaded] = useState<boolean>(false);
 
   const [data, setData] = useState<LayerStoreInterface>({
@@ -33,7 +31,6 @@ export const LayerFactoryModal: React.FC = () => {
     visible: false,
     locked: false,
     modelId: currentModelId,
-    zIndex: maxLayerZIndexAboveDiagram,
   });
 
   const fetchData = useMemo(() => {
@@ -45,7 +42,6 @@ export const LayerFactoryModal: React.FC = () => {
           visible: layer.visible,
           locked: layer.locked,
           modelId: currentModelId,
-          zIndex: layer.z,
         });
       }
       setLoaded(true);
diff --git a/src/components/FunctionalArea/Modal/LayerImageObjectModal/LayerImageObjectFactoryModal.component.tsx b/src/components/FunctionalArea/Modal/LayerImageObjectModal/LayerImageObjectFactoryModal.component.tsx
index 4d1513e9..1efb7d88 100644
--- a/src/components/FunctionalArea/Modal/LayerImageObjectModal/LayerImageObjectFactoryModal.component.tsx
+++ b/src/components/FunctionalArea/Modal/LayerImageObjectModal/LayerImageObjectFactoryModal.component.tsx
@@ -4,10 +4,7 @@ import { useAppSelector } from '@/redux/hooks/useAppSelector';
 import { layerImageObjectFactoryStateSelector } from '@/redux/modal/modal.selector';
 import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
 import { currentModelIdSelector } from '@/redux/models/models.selectors';
-import {
-  layersDrawLayerSelector,
-  maxObjectZIndexForLayerSelector,
-} from '@/redux/layers/layers.selectors';
+import { highestZIndexSelector, layersDrawLayerSelector } from '@/redux/layers/layers.selectors';
 import { addLayerImageObject } from '@/redux/layers/layers.thunks';
 import { addGlyph } from '@/redux/glyphs/glyphs.thunks';
 import { SerializedError } from '@reduxjs/toolkit';
@@ -25,7 +22,7 @@ export const LayerImageObjectFactoryModal: React.FC = () => {
   const drawLayer = useAppSelector(layersDrawLayerSelector);
   const layerImageObjectFactoryState = useAppSelector(layerImageObjectFactoryStateSelector);
   const dispatch = useAppDispatch();
-  const maxZIndex = useAppSelector(state => maxObjectZIndexForLayerSelector(state, drawLayer));
+  const highestZIndex = useAppSelector(highestZIndexSelector);
   const { mapInstance } = useMapInstance();
 
   const [selectedGlyph, setSelectedGlyph] = useState<number | null>(null);
@@ -52,7 +49,7 @@ export const LayerImageObjectFactoryModal: React.FC = () => {
           layerId: drawLayer,
           x: layerImageObjectFactoryState.x,
           y: layerImageObjectFactoryState.y,
-          z: maxZIndex + 1,
+          z: highestZIndex + 1,
           width: layerImageObjectFactoryState.width,
           height: layerImageObjectFactoryState.height,
           glyph: glyphId,
diff --git a/src/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextFactoryModal.component.tsx b/src/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextFactoryModal.component.tsx
index bfb80aff..e1ccf612 100644
--- a/src/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextFactoryModal.component.tsx
+++ b/src/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextFactoryModal.component.tsx
@@ -13,10 +13,7 @@ import { LayerTextFactoryForm } from '@/components/FunctionalArea/Modal/LayerTex
 import { Color } from '@/types/models';
 import { useAppSelector } from '@/redux/hooks/useAppSelector';
 import { layerTextFactoryStateSelector } from '@/redux/modal/modal.selector';
-import {
-  layersDrawLayerSelector,
-  maxObjectZIndexForLayerSelector,
-} from '@/redux/layers/layers.selectors';
+import { highestZIndexSelector, layersDrawLayerSelector } from '@/redux/layers/layers.selectors';
 import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
 import { currentModelIdSelector } from '@/redux/models/models.selectors';
 import { showToast } from '@/utils/showToast';
@@ -34,7 +31,7 @@ export const LayerTextFactoryModal: React.FC = () => {
   const currentModelId = useAppSelector(currentModelIdSelector);
   const layerTextFactoryState = useAppSelector(layerTextFactoryStateSelector);
   const dispatch = useAppDispatch();
-  const maxZIndex = useAppSelector(state => maxObjectZIndexForLayerSelector(state, drawLayer));
+  const highestZIndex = useAppSelector(highestZIndexSelector);
   const { mapInstance } = useMapInstance();
 
   const [isSending, setIsSending] = useState<boolean>(false);
@@ -58,7 +55,7 @@ export const LayerTextFactoryModal: React.FC = () => {
           layerId: drawLayer,
           boundingBox: layerTextFactoryState,
           textData: data,
-          z: maxZIndex + 1,
+          z: highestZIndex + 1,
         }),
       ).unwrap();
       if (!textData) {
diff --git a/src/components/Map/Drawer/LayersDrawer/LayerDrawerTextItem.component.tsx b/src/components/Map/Drawer/LayersDrawer/LayerDrawerTextItem.component.tsx
index a9c3d3b3..6f57c762 100644
--- a/src/components/Map/Drawer/LayersDrawer/LayerDrawerTextItem.component.tsx
+++ b/src/components/Map/Drawer/LayersDrawer/LayerDrawerTextItem.component.tsx
@@ -10,8 +10,8 @@ import { hasPrivilegeToWriteProjectSelector } from '@/redux/user/user.selectors'
 
 interface LayersDrawerTextItemProps {
   layerText: LayerText;
-  moveToFront: () => void;
-  moveToBack: () => void;
+  bringToFront: () => void;
+  bringToBack: () => void;
   removeObject: () => void;
   centerObject: () => void;
   editObject: () => void;
@@ -21,8 +21,8 @@ interface LayersDrawerTextItemProps {
 
 export const LayersDrawerTextItem = ({
   layerText,
-  moveToFront,
-  moveToBack,
+  bringToFront,
+  bringToBack,
   removeObject,
   centerObject,
   editObject,
@@ -68,8 +68,8 @@ export const LayersDrawerTextItem = ({
       </div>
       {showActions && (
         <LayersDrawerObjectActions
-          moveToFront={moveToFront}
-          moveToBack={moveToBack}
+          bringToFront={bringToFront}
+          bringToBack={bringToBack}
           removeObject={removeObject}
           centerObject={centerObject}
           editObject={editObject}
diff --git a/src/components/Map/Drawer/LayersDrawer/LayersDrawer.component.tsx b/src/components/Map/Drawer/LayersDrawer/LayersDrawer.component.tsx
index 33c259f3..12bef081 100644
--- a/src/components/Map/Drawer/LayersDrawer/LayersDrawer.component.tsx
+++ b/src/components/Map/Drawer/LayersDrawer/LayersDrawer.component.tsx
@@ -4,7 +4,7 @@ import { DrawerHeading } from '@/shared/DrawerHeading';
 import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
 import { layersForCurrentModelSelector } from '@/redux/layers/layers.selectors';
 import { Button } from '@/shared/Button';
-import { JSX, useEffect, useMemo, useRef } from 'react';
+import { JSX, useEffect, useRef } from 'react';
 import { openLayerFactoryModal } from '@/redux/modal/modal.slice';
 import { hasPrivilegeToWriteProjectSelector } from '@/redux/user/user.selectors';
 import { LayersDrawerLayer } from '@/components/Map/Drawer/LayersDrawer/LayersDrawerLayer.component';
@@ -21,19 +21,6 @@ export const LayersDrawer = (): JSX.Element => {
     dispatch(openLayerFactoryModal());
   };
 
-  const sortedLayers = useMemo(() => {
-    return [...layersForCurrentModel].sort((layerA, layerB) => layerB.details.z - layerA.details.z);
-  }, [layersForCurrentModel]);
-
-  const negativeZLayers = useMemo(
-    () => sortedLayers.filter(layer => layer.details.z < 0),
-    [sortedLayers],
-  );
-  const positiveZLayers = useMemo(
-    () => sortedLayers.filter(layer => layer.details.z >= 0),
-    [sortedLayers],
-  );
-
   useEffect(() => {
     if (!mapEditToolsLayerImageObject || !layersDrawerRef.current) {
       return;
@@ -74,33 +61,20 @@ export const LayersDrawer = (): JSX.Element => {
         ref={layersDrawerRef}
       >
         {hasPrivilegeToWriteProject && (
-          <div className="flex justify-start py-2">
+          <div className="flex justify-start pt-2">
             <Button icon="plus" isIcon isFrontIcon onClick={addNewLayer}>
               Add layer
             </Button>
           </div>
         )}
-        <div className="flex flex-col gap-2">
-          {Boolean(positiveZLayers.length) && (
-            <span className="border-b-2 border-dashed border-b-gray-400 text-center text-lg font-semibold">
-              Layers above the diagram
-            </span>
-          )}
-          <div className="flex flex-col gap-5">
-            {positiveZLayers.map(layer => (
-              <LayersDrawerLayer key={layer.details.id} layerDetails={layer.details} />
-            ))}
-          </div>
-          {Boolean(negativeZLayers.length) && (
-            <span className="border-b-2 border-dashed border-b-gray-400 text-center text-lg font-semibold">
-              Layers below the diagram
-            </span>
-          )}
-          <div className="flex flex-col gap-5">
-            {negativeZLayers.map(layer => (
-              <LayersDrawerLayer key={layer.details.id} layerDetails={layer.details} />
-            ))}
-          </div>
+        <div className="flex flex-col gap-4">
+          {layersForCurrentModel.map(layer => (
+            <LayersDrawerLayer
+              key={layer.details.id}
+              layerId={layer.details.id}
+              layerName={layer.details.name}
+            />
+          ))}
         </div>
       </div>
     </div>
diff --git a/src/components/Map/Drawer/LayersDrawer/LayersDrawerImageItem.component.tsx b/src/components/Map/Drawer/LayersDrawer/LayersDrawerImageItem.component.tsx
index e160b807..0622f141 100644
--- a/src/components/Map/Drawer/LayersDrawer/LayersDrawerImageItem.component.tsx
+++ b/src/components/Map/Drawer/LayersDrawer/LayersDrawerImageItem.component.tsx
@@ -11,8 +11,8 @@ import { hasPrivilegeToWriteProjectSelector } from '@/redux/user/user.selectors'
 
 interface LayersDrawerImageItemProps {
   layerImage: LayerImage;
-  moveToFront: () => void;
-  moveToBack: () => void;
+  bringToFront: () => void;
+  bringToBack: () => void;
   removeObject: () => void;
   centerObject: () => void;
   editObject: () => void;
@@ -22,8 +22,8 @@ interface LayersDrawerImageItemProps {
 
 export const LayersDrawerImageItem = ({
   layerImage,
-  moveToFront,
-  moveToBack,
+  bringToFront,
+  bringToBack,
   removeObject,
   centerObject,
   editObject,
@@ -72,8 +72,8 @@ export const LayersDrawerImageItem = ({
       </div>
       {showActions && (
         <LayersDrawerObjectActions
-          moveToFront={moveToFront}
-          moveToBack={moveToBack}
+          bringToFront={bringToFront}
+          bringToBack={bringToBack}
           removeObject={removeObject}
           centerObject={centerObject}
           editObject={editObject}
diff --git a/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayer.component.tsx b/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayer.component.tsx
index 8b0f9b01..49b8536f 100644
--- a/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayer.component.tsx
+++ b/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayer.component.tsx
@@ -1,19 +1,14 @@
-/* eslint-disable no-magic-numbers */
 import { useAppSelector } from '@/redux/hooks/useAppSelector';
 import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
 import {
   layersActiveLayersSelector,
   layersVisibilityForCurrentModelSelector,
-  maxLayerZIndexAboveDiagramSelector,
-  maxLayerZIndexBelowDiagramSelector,
-  minLayerZIndexAboveDiagramSelector,
-  minLayerZIndexBelowDiagramSelector,
 } from '@/redux/layers/layers.selectors';
 import { currentModelIdSelector } from '@/redux/models/models.selectors';
 import { openLayerFactoryModal } from '@/redux/modal/modal.slice';
 import QuestionModal from '@/components/FunctionalArea/Modal/QuestionModal/QustionModal.component';
 import { useState, JSX, useMemo } from 'react';
-import { getLayersForModel, removeLayer, updateLayer } from '@/redux/layers/layers.thunks';
+import { getLayersForModel, removeLayer } from '@/redux/layers/layers.thunks';
 import { showToast } from '@/utils/showToast';
 import { SerializedError } from '@reduxjs/toolkit';
 import { LayersDrawerLayerActions } from '@/components/Map/Drawer/LayersDrawer/LayersDrawerLayerActions.component';
@@ -26,42 +21,38 @@ import {
 import { LayersDrawerObjectsList } from '@/components/Map/Drawer/LayersDrawer/LayersDrawerObjectsList.component';
 import { mapEditToolsSetActiveAction } from '@/redux/mapEditTools/mapEditTools.slice';
 import { MAP_EDIT_ACTIONS } from '@/redux/mapEditTools/mapEditTools.constants';
-import { Layer } from '@/types/models';
 
 interface LayersDrawerLayerProps {
-  layerDetails: Layer;
+  layerId: number;
+  layerName: string;
 }
 
-export const LayersDrawerLayer = ({ layerDetails }: LayersDrawerLayerProps): JSX.Element => {
+export const LayersDrawerLayer = ({ layerId, layerName }: LayersDrawerLayerProps): JSX.Element => {
   const layersVisibilityForCurrentModel = useAppSelector(layersVisibilityForCurrentModelSelector);
   const activeLayers = useAppSelector(layersActiveLayersSelector);
   const currentModelId = useAppSelector(currentModelIdSelector);
-  const maxLayerZIndexAboveDiagram = useAppSelector(maxLayerZIndexAboveDiagramSelector);
-  const maxLayerZIndexBelowDiagram = useAppSelector(maxLayerZIndexBelowDiagramSelector);
-  const minLayerZIndexAboveDiagram = useAppSelector(minLayerZIndexAboveDiagramSelector);
-  const minLayerZIndexBelowDiagram = useAppSelector(minLayerZIndexBelowDiagramSelector);
   const dispatch = useAppDispatch();
   const [isModalOpen, setIsModalOpen] = useState(false);
 
   const isLayerVisible = useMemo(() => {
-    return layersVisibilityForCurrentModel[layerDetails.id];
-  }, [layerDetails.id, layersVisibilityForCurrentModel]);
+    return layersVisibilityForCurrentModel[layerId];
+  }, [layerId, layersVisibilityForCurrentModel]);
 
   const isLayerActive = useMemo(() => {
-    return activeLayers.includes(layerDetails.id);
-  }, [activeLayers, layerDetails.id]);
+    return activeLayers.includes(layerId);
+  }, [activeLayers, layerId]);
 
   const editLayer = (): void => {
-    dispatch(openLayerFactoryModal(layerDetails.id));
+    dispatch(openLayerFactoryModal(layerId));
   };
 
   const addImage = (): void => {
-    dispatch(setDrawLayer({ modelId: currentModelId, layerId: layerDetails.id }));
+    dispatch(setDrawLayer({ modelId: currentModelId, layerId }));
     dispatch(mapEditToolsSetActiveAction(MAP_EDIT_ACTIONS.DRAW_IMAGE));
   };
 
   const addText = (): void => {
-    dispatch(setDrawLayer({ modelId: currentModelId, layerId: layerDetails.id }));
+    dispatch(setDrawLayer({ modelId: currentModelId, layerId }));
     dispatch(mapEditToolsSetActiveAction(MAP_EDIT_ACTIONS.ADD_TEXT));
   };
 
@@ -70,11 +61,11 @@ export const LayersDrawerLayer = ({ layerDetails }: LayersDrawerLayerProps): JSX
   };
 
   const confirmRemove = async (): Promise<void> => {
-    if (!layerDetails.id) {
+    if (!layerId) {
       return;
     }
     try {
-      await dispatch(removeLayer({ modelId: currentModelId, layerId: layerDetails.id })).unwrap();
+      await dispatch(removeLayer({ modelId: currentModelId, layerId })).unwrap();
       showToast({
         type: 'success',
         message: 'The layer has been successfully removed',
@@ -96,61 +87,12 @@ export const LayersDrawerLayer = ({ layerDetails }: LayersDrawerLayerProps): JSX
 
   const toggleActiveLayer = (value: boolean): void => {
     if (value) {
-      dispatch(setLayerToActive({ modelId: currentModelId, layerId: layerDetails.id }));
+      dispatch(setLayerToActive({ modelId: currentModelId, layerId }));
     } else {
-      dispatch(setLayerToInactive({ modelId: currentModelId, layerId: layerDetails.id }));
+      dispatch(setLayerToInactive({ modelId: currentModelId, layerId }));
     }
   };
 
-  const updateLayerZIndex = async (zIndex: number): Promise<void> => {
-    try {
-      dispatch(
-        updateLayer({
-          name: layerDetails.name,
-          visible: layerDetails.visible,
-          locked: layerDetails.locked,
-          modelId: currentModelId,
-          layerId: layerDetails.id,
-          zIndex,
-        }),
-      );
-    } catch (error) {
-      const typedError = error as SerializedError;
-      showToast({
-        type: 'error',
-        message: typedError.message || 'An error occurred while updating the layer',
-      });
-    }
-  };
-
-  const moveToFront = (): void => {
-    if (layerDetails.z > 0) {
-      updateLayerZIndex(maxLayerZIndexAboveDiagram);
-    } else if (layerDetails.z < 0) {
-      const zIndex = Math.min(maxLayerZIndexBelowDiagram, -1);
-      updateLayerZIndex(zIndex);
-    }
-  };
-
-  const moveToBack = (): void => {
-    if (layerDetails.z > 0) {
-      const zIndex = Math.max(minLayerZIndexAboveDiagram, 1);
-      updateLayerZIndex(zIndex);
-    } else if (layerDetails.z < 0) {
-      updateLayerZIndex(minLayerZIndexBelowDiagram);
-    }
-  };
-
-  const moveAboveDiagram = (): void => {
-    const zIndex = Math.max(minLayerZIndexAboveDiagram - 1, 1);
-    updateLayerZIndex(zIndex);
-  };
-
-  const moveBelowDiagram = (): void => {
-    const zIndex = Math.min(minLayerZIndexBelowDiagram + 1, -1);
-    updateLayerZIndex(zIndex);
-  };
-
   return (
     <div>
       <QuestionModal
@@ -159,13 +101,9 @@ export const LayersDrawerLayer = ({ layerDetails }: LayersDrawerLayerProps): JSX
         onConfirm={confirmRemove}
         question="Are you sure you want to remove the layer?"
       />
-      <div className="flex items-center justify-between pb-3">
-        <span
-          className={`font-semibold ${
-            isLayerVisible ? 'opacity-100' : 'opacity-40'
-          } min-w-0 flex-1 truncate `}
-        >
-          {layerDetails.name}
+      <div className="flex items-center justify-between py-3">
+        <span className={`font-semibold ${isLayerVisible ? 'opacity-100' : 'opacity-40'}`}>
+          {layerName}
         </span>
         <LayersDrawerLayerActions
           toggleVisibility={() =>
@@ -173,7 +111,7 @@ export const LayersDrawerLayer = ({ layerDetails }: LayersDrawerLayerProps): JSX
               setLayerVisibility({
                 modelId: currentModelId,
                 visible: !isLayerVisible,
-                layerId: layerDetails.id,
+                layerId,
               }),
             )
           }
@@ -182,17 +120,12 @@ export const LayersDrawerLayer = ({ layerDetails }: LayersDrawerLayerProps): JSX
           removeLayer={onRemoveLayer}
           addImage={addImage}
           addText={addText}
-          moveToFront={moveToFront}
-          moveToBack={moveToBack}
-          moveAboveDiagram={moveAboveDiagram}
-          moveBelowDiagram={moveBelowDiagram}
-          zIndex={layerDetails.z}
           isVisible={isLayerVisible}
           isActive={isLayerActive}
         />
       </div>
       <LayersDrawerObjectsList
-        layerId={layerDetails.id}
+        layerId={layerId}
         isLayerVisible={isLayerVisible}
         isLayerActive={isLayerActive}
       />
diff --git a/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayerActions.component.tsx b/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayerActions.component.tsx
index 81435100..18627b13 100644
--- a/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayerActions.component.tsx
+++ b/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayerActions.component.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable no-magic-numbers */
 import { IconButton } from '@/shared/IconButton';
 import { JSX } from 'react';
 import { LayerDrawerLayerContextMenu } from '@/components/Map/Drawer/LayersDrawer/LayerDrawerLayerContextMenu.component';
@@ -10,15 +9,10 @@ type LayersDrawerLayerActionsProps = {
   removeLayer: () => void;
   isVisible: boolean;
   isActive: boolean;
-  zIndex: number;
   toggleVisibility: () => void;
   toggleActiveLayer: (value: boolean) => void;
   addImage: () => void;
   addText: () => void;
-  moveToFront: () => void;
-  moveToBack: () => void;
-  moveAboveDiagram: () => void;
-  moveBelowDiagram: () => void;
 };
 
 export const LayersDrawerLayerActions = ({
@@ -26,15 +20,10 @@ export const LayersDrawerLayerActions = ({
   removeLayer,
   isVisible,
   isActive,
-  zIndex,
   toggleVisibility,
   toggleActiveLayer,
   addImage,
   addText,
-  moveToFront,
-  moveToBack,
-  moveAboveDiagram,
-  moveBelowDiagram,
 }: LayersDrawerLayerActionsProps): JSX.Element => {
   const hasPrivilegeToWriteProject = useAppSelector(hasPrivilegeToWriteProjectSelector);
 
@@ -54,34 +43,6 @@ export const LayersDrawerLayerActions = ({
             className="h-auto w-auto bg-transparent p-0"
             onClick={() => toggleActiveLayer(!isActive)}
           />
-          <IconButton
-            title="Move to front"
-            icon="move-front"
-            className="h-auto w-auto bg-transparent p-0"
-            onClick={moveToFront}
-          />
-          <IconButton
-            title="Move to back"
-            icon="move-back"
-            className="h-auto w-auto bg-transparent p-0"
-            onClick={moveToBack}
-          />
-          {zIndex < 0 && (
-            <IconButton
-              title="Move above the diagram"
-              icon="layer-arrow-up"
-              className="h-auto w-auto bg-transparent p-0"
-              onClick={moveAboveDiagram}
-            />
-          )}
-          {zIndex > 0 && (
-            <IconButton
-              title="Move below the diagram"
-              icon="layer-arrow-down"
-              className="h-auto w-auto bg-transparent p-0"
-              onClick={moveBelowDiagram}
-            />
-          )}
           <LayerDrawerLayerContextMenu
             removeLayer={removeLayer}
             editLayer={editLayer}
diff --git a/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectActions.component.tsx b/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectActions.component.tsx
index a97189ea..4cf6871e 100644
--- a/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectActions.component.tsx
+++ b/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectActions.component.tsx
@@ -2,16 +2,16 @@ import { JSX } from 'react';
 import { IconButton } from '@/shared/IconButton';
 
 interface LayersDrawerObjectActionsProps {
-  moveToFront: () => void;
-  moveToBack: () => void;
+  bringToFront: () => void;
+  bringToBack: () => void;
   removeObject: () => void;
   centerObject: () => void;
   editObject: () => void;
 }
 
 export const LayersDrawerObjectActions = ({
-  moveToFront,
-  moveToBack,
+  bringToFront,
+  bringToBack,
   removeObject,
   centerObject,
   editObject,
@@ -31,16 +31,16 @@ export const LayersDrawerObjectActions = ({
         onClick={editObject}
       />
       <IconButton
-        icon="move-front"
+        icon="bring-front"
         className="h-auto w-auto bg-transparent p-0"
-        title="Move to front"
-        onClick={moveToFront}
+        title="Bring to front"
+        onClick={bringToFront}
       />
       <IconButton
-        icon="move-back"
+        icon="bring-back"
         className="h-auto w-auto bg-transparent p-0"
-        title="Move to back"
-        onClick={moveToBack}
+        title="Bring to back"
+        onClick={bringToBack}
       />
       <IconButton
         icon="trash"
diff --git a/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectsList.component.tsx b/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectsList.component.tsx
index 9ec19fe4..70a6acf5 100644
--- a/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectsList.component.tsx
+++ b/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectsList.component.tsx
@@ -1,9 +1,9 @@
 /* eslint-disable no-magic-numbers */
 import { useAppSelector } from '@/redux/hooks/useAppSelector';
 import {
+  highestZIndexSelector,
   layerByIdSelector,
-  maxObjectZIndexForLayerSelector,
-  minObjectZIndexForLayerSelector,
+  lowestZIndexSelector,
 } from '@/redux/layers/layers.selectors';
 import { JSX, useState } from 'react';
 import { LayersDrawerImageItem } from '@/components/Map/Drawer/LayersDrawer/LayersDrawerImageItem.component';
@@ -64,8 +64,8 @@ export const LayersDrawerObjectsList = ({
   isLayerActive,
 }: LayersDrawerObjectsListProps): JSX.Element | null => {
   const currentModelId = useAppSelector(mapModelIdSelector);
-  const maxZIndex = useAppSelector(state => maxObjectZIndexForLayerSelector(state, layerId));
-  const minZIndex = useAppSelector(state => minObjectZIndexForLayerSelector(state, layerId));
+  const highestZIndex = useAppSelector(highestZIndexSelector);
+  const lowestZIndex = useAppSelector(lowestZIndexSelector);
   const layer = useAppSelector(state => layerByIdSelector(state, layerId));
   const mapEditToolsLayerImageObject = useAppSelector(mapEditToolsLayerObjectSelector);
   const [removeModalState, setRemoveModalState] = useState<undefined | 'text' | 'image'>(undefined);
@@ -174,12 +174,12 @@ export const LayersDrawerObjectsList = ({
     }
   };
 
-  const moveImageToFront = async (layerImage: LayerImage): Promise<void> => {
-    await updateImageZIndex({ zIndex: maxZIndex + 1, layerImage });
+  const bringImageToFront = async (layerImage: LayerImage): Promise<void> => {
+    await updateImageZIndex({ zIndex: highestZIndex + 1, layerImage });
   };
 
-  const moveImageToBack = async (layerImage: LayerImage): Promise<void> => {
-    await updateImageZIndex({ zIndex: minZIndex - 1, layerImage });
+  const bringImageToBack = async (layerImage: LayerImage): Promise<void> => {
+    await updateImageZIndex({ zIndex: lowestZIndex - 1, layerImage });
   };
 
   const updateTextZIndex = async ({
@@ -210,12 +210,12 @@ export const LayersDrawerObjectsList = ({
     }
   };
 
-  const moveTextToFront = async (layerText: LayerText): Promise<void> => {
-    await updateTextZIndex({ zIndex: maxZIndex + 1, layerText });
+  const bringTextToFront = async (layerText: LayerText): Promise<void> => {
+    await updateTextZIndex({ zIndex: highestZIndex + 1, layerText });
   };
 
-  const moveTextToBack = async (layerText: LayerText): Promise<void> => {
-    await updateTextZIndex({ zIndex: minZIndex - 1, layerText });
+  const bringTextToBack = async (layerText: LayerText): Promise<void> => {
+    await updateTextZIndex({ zIndex: lowestZIndex - 1, layerText });
   };
 
   const centerObject = (layerObject: LayerImage | LayerText): void => {
@@ -257,8 +257,8 @@ export const LayersDrawerObjectsList = ({
         <LayersDrawerTextItem
           layerText={layerText}
           key={layerText.id}
-          moveToFront={() => moveTextToFront(layerText)}
-          moveToBack={() => moveTextToBack(layerText)}
+          bringToFront={() => bringTextToFront(layerText)}
+          bringToBack={() => bringTextToBack(layerText)}
           removeObject={() => removeObject(layerText)}
           centerObject={() => centerObject(layerText)}
           editObject={() => editText()}
@@ -270,8 +270,8 @@ export const LayersDrawerObjectsList = ({
         <LayersDrawerImageItem
           layerImage={layerImage}
           key={layerImage.id}
-          moveToFront={() => moveImageToFront(layerImage)}
-          moveToBack={() => moveImageToBack(layerImage)}
+          bringToFront={() => bringImageToFront(layerImage)}
+          bringToBack={() => bringImageToBack(layerImage)}
           removeObject={() => removeObject(layerImage)}
           centerObject={() => centerObject(layerImage)}
           editObject={() => editImage()}
diff --git a/src/components/Map/MapViewer/utils/config/additionalLayers/useOlMapAdditionalLayers.ts b/src/components/Map/MapViewer/utils/config/additionalLayers/useOlMapAdditionalLayers.ts
index 6d41944f..5e378293 100644
--- a/src/components/Map/MapViewer/utils/config/additionalLayers/useOlMapAdditionalLayers.ts
+++ b/src/components/Map/MapViewer/utils/config/additionalLayers/useOlMapAdditionalLayers.ts
@@ -125,7 +125,6 @@ export const useOlMapAdditionalLayers = (
   const vectorLayers = useMemo(() => {
     return layersState.map(layer => {
       const additionalLayer = new Layer({
-        zIndex: layer.details.z,
         texts: layer.texts,
         rects: layer.rects,
         ovals: layer.ovals,
diff --git a/src/components/Map/MapViewer/utils/config/commentsLayer/useOlMapCommentsLayer.ts b/src/components/Map/MapViewer/utils/config/commentsLayer/useOlMapCommentsLayer.ts
index a3640020..7ac3b73b 100644
--- a/src/components/Map/MapViewer/utils/config/commentsLayer/useOlMapCommentsLayer.ts
+++ b/src/components/Map/MapViewer/utils/config/commentsLayer/useOlMapCommentsLayer.ts
@@ -36,7 +36,6 @@ export const useOlMapCommentsLayer = (): VectorLayer<VectorSource<Feature<Geomet
 
   return useMemo(() => {
     const vectorLayer = new VectorLayer({
-      zIndex: Infinity,
       source: vectorSource,
     });
     vectorLayer.set('type', LAYER_TYPE.COMMENTS_LAYER);
diff --git a/src/components/Map/MapViewer/utils/config/mapCardLayer/useOlMapCardLayer.ts b/src/components/Map/MapViewer/utils/config/mapCardLayer/useOlMapCardLayer.ts
index db3dbad4..69cec807 100644
--- a/src/components/Map/MapViewer/utils/config/mapCardLayer/useOlMapCardLayer.ts
+++ b/src/components/Map/MapViewer/utils/config/mapCardLayer/useOlMapCardLayer.ts
@@ -38,7 +38,6 @@ export const useOlMapCardLayer = (): VectorLayer<VectorSource<Feature<Polygon>>>
 
   return useMemo(() => {
     const vectorLayer = new VectorLayer({
-      zIndex: -Infinity,
       source: vectorSource,
       style: new Style({
         fill: new Fill({
diff --git a/src/components/Map/MapViewer/utils/config/pinsLayer/useOlMapPinsLayer.ts b/src/components/Map/MapViewer/utils/config/pinsLayer/useOlMapPinsLayer.ts
index 4cd5a32b..f7b6001c 100644
--- a/src/components/Map/MapViewer/utils/config/pinsLayer/useOlMapPinsLayer.ts
+++ b/src/components/Map/MapViewer/utils/config/pinsLayer/useOlMapPinsLayer.ts
@@ -77,7 +77,6 @@ export const useOlMapPinsLayer = (): VectorLayer<VectorSource<Feature<Geometry>>
 
   return useMemo(() => {
     const vectorLayer = new VectorLayer({
-      zIndex: Infinity,
       source: vectorSource,
     });
     vectorLayer.set('type', LAYER_TYPE.PINS_LAYER);
diff --git a/src/components/Map/MapViewer/utils/config/processLayer/useOlMapProcessLayer.ts b/src/components/Map/MapViewer/utils/config/processLayer/useOlMapProcessLayer.ts
index 98cb6e1e..2811ec30 100644
--- a/src/components/Map/MapViewer/utils/config/processLayer/useOlMapProcessLayer.ts
+++ b/src/components/Map/MapViewer/utils/config/processLayer/useOlMapProcessLayer.ts
@@ -274,7 +274,6 @@ export const useOlMapProcessLayer = ({
 
   return useMemo(() => {
     const vectorLayer = new VectorLayer({
-      zIndex: 0,
       source: vectorSource,
       updateWhileAnimating: true,
       updateWhileInteracting: true,
diff --git a/src/components/Map/MapViewer/utils/config/reactionsLayer/useOlMapReactionsLayer.ts b/src/components/Map/MapViewer/utils/config/reactionsLayer/useOlMapReactionsLayer.ts
index df526271..bfb2668e 100644
--- a/src/components/Map/MapViewer/utils/config/reactionsLayer/useOlMapReactionsLayer.ts
+++ b/src/components/Map/MapViewer/utils/config/reactionsLayer/useOlMapReactionsLayer.ts
@@ -63,7 +63,6 @@ export const useOlMapReactionsLayer = (): VectorLayer<VectorSource<Feature<Geome
 
   return useMemo(() => {
     const vectorLayer = new VectorLayer({
-      zIndex: Infinity,
       source: vectorSource,
       style: new Style({
         fill: new Fill({ color: LINE_COLOR }),
diff --git a/src/components/Map/MapViewer/utils/shapes/layer/Layer.test.ts b/src/components/Map/MapViewer/utils/shapes/layer/Layer.test.ts
index 10349c6d..7b8bb971 100644
--- a/src/components/Map/MapViewer/utils/shapes/layer/Layer.test.ts
+++ b/src/components/Map/MapViewer/utils/shapes/layer/Layer.test.ts
@@ -133,7 +133,6 @@ describe('Layer', () => {
       pointToProjection: jest.fn(point => [point.x, point.y]),
       mapInstance,
       mapSize,
-      zIndex: 1,
       lineTypes: {},
       arrowTypes: {},
     };
diff --git a/src/components/Map/MapViewer/utils/shapes/layer/Layer.ts b/src/components/Map/MapViewer/utils/shapes/layer/Layer.ts
index 14d5f8b5..7f697a72 100644
--- a/src/components/Map/MapViewer/utils/shapes/layer/Layer.ts
+++ b/src/components/Map/MapViewer/utils/shapes/layer/Layer.ts
@@ -34,7 +34,6 @@ import LayerText from '@/components/Map/MapViewer/utils/shapes/layer/elements/La
 import LayerImage from '@/components/Map/MapViewer/utils/shapes/layer/elements/LayerImage';
 
 export interface LayerProps {
-  zIndex: number;
   texts: { [key: string]: LayerTextModel };
   rects: Array<LayerRect>;
   ovals: Array<LayerOval>;
@@ -79,7 +78,6 @@ export default class Layer {
   >;
 
   constructor({
-    zIndex,
     texts,
     rects,
     ovals,
@@ -120,7 +118,6 @@ export default class Layer {
     this.vectorSource.addFeatures(arrowsFeatures);
 
     this.vectorLayer = new VectorLayer({
-      zIndex,
       source: this.vectorSource,
       visible,
       updateWhileAnimating: true,
diff --git a/src/models/layerSchema.ts b/src/models/layerSchema.ts
index 11fcd88d..380146a7 100644
--- a/src/models/layerSchema.ts
+++ b/src/models/layerSchema.ts
@@ -5,5 +5,4 @@ export const layerSchema = z.object({
   name: z.string(),
   visible: z.boolean(),
   locked: z.boolean(),
-  z: z.number(),
 });
diff --git a/src/redux/layers/layers.reducers.test.ts b/src/redux/layers/layers.reducers.test.ts
index d93fb4f8..7bcb10ba 100644
--- a/src/redux/layers/layers.reducers.test.ts
+++ b/src/redux/layers/layers.reducers.test.ts
@@ -92,7 +92,7 @@ describe('layers reducer', () => {
 
     const { type } = await store.dispatch(getLayersForModel(1));
     const { data, loading, error } = store.getState().layers[1];
-    expect(type).toBe('layers/getLayers/fulfilled');
+    expect(type).toBe('vectorMap/getLayers/fulfilled');
     expect(loading).toEqual('succeeded');
     expect(error).toEqual({ message: '', name: '' });
     expect(data).toEqual({
@@ -120,7 +120,7 @@ describe('layers reducer', () => {
     const action = await store.dispatch(getLayersForModel(1));
     const { data, loading, error } = store.getState().layers[1];
 
-    expect(action.type).toBe('layers/getLayers/rejected');
+    expect(action.type).toBe('vectorMap/getLayers/rejected');
     expect(() => unwrapResult(action)).toThrow(
       "Failed to fetch layers: The page you're looking for doesn't exist. Please verify the URL and try again.",
     );
diff --git a/src/redux/layers/layers.selectors.ts b/src/redux/layers/layers.selectors.ts
index 8123fa00..8f016c8a 100644
--- a/src/redux/layers/layers.selectors.ts
+++ b/src/redux/layers/layers.selectors.ts
@@ -2,7 +2,6 @@
 import { createSelector } from '@reduxjs/toolkit';
 import { rootSelector } from '@/redux/root/root.selectors';
 import { currentModelIdSelector } from '@/redux/models/models.selectors';
-import { LayerState } from '@/redux/layers/layers.types';
 
 export const layersSelector = createSelector(rootSelector, state => state.layers);
 
@@ -19,7 +18,7 @@ export const layersActiveLayersSelector = createSelector(
 
 export const layersDrawLayerSelector = createSelector(
   layersStateForCurrentModelSelector,
-  state => state?.data?.drawLayer || null,
+  state => state?.data?.drawLayer,
 );
 
 export const layerByIdSelector = createSelector(
@@ -42,112 +41,40 @@ export const layersForCurrentModelSelector = createSelector(
   state => state?.data?.layers || [],
 );
 
-export const maxLayerZIndexAboveDiagramSelector = createSelector(
-  layersForCurrentModelSelector,
-  layers => {
-    if (!layers || layers.length === 0) {
-      return 1000;
-    }
-    let maxZIndex = -Infinity;
-    layers.forEach((layer: LayerState) => {
-      if (layer.details.z > 0 && layer.details.z > maxZIndex) {
-        maxZIndex = layer.details.z;
-      }
-    });
-    return maxZIndex;
-  },
-);
+export const highestZIndexSelector = createSelector(layersForCurrentModelSelector, layers => {
+  if (!layers || layers.length === 0) return 0;
 
-export const maxLayerZIndexBelowDiagramSelector = createSelector(
-  layersForCurrentModelSelector,
-  layers => {
-    if (!layers || layers.length === 0) {
-      return -1000;
-    }
-    let maxZIndex = -Infinity;
-    layers.forEach((layer: LayerState) => {
-      if (layer.details.z < 0 && layer.details.z > maxZIndex) {
-        maxZIndex = layer.details.z;
-      }
-    });
-    return maxZIndex;
-  },
-);
+  const getMaxZFromItems = <T extends { z?: number }>(items: T[] = []): number =>
+    items.length > 0 ? Math.max(...items.map(item => item.z || 0)) : 0;
 
-export const minLayerZIndexAboveDiagramSelector = createSelector(
-  layersForCurrentModelSelector,
-  layers => {
-    if (!layers || layers.length === 0) {
-      return 1000;
-    }
-    let minZIndex = Infinity;
-    layers.forEach((layer: LayerState) => {
-      if (layer.details.z > 0 && layer.details.z < minZIndex) {
-        minZIndex = layer.details.z;
-      }
-    });
-    return minZIndex;
-  },
-);
+  return layers.reduce((maxZ, layer) => {
+    const textsMaxZ = getMaxZFromItems(Object.values(layer.texts));
+    const rectsMaxZ = getMaxZFromItems(layer.rects);
+    const ovalsMaxZ = getMaxZFromItems(layer.ovals);
+    const linesMaxZ = getMaxZFromItems(layer.lines);
+    const imagesMaxZ = getMaxZFromItems(Object.values(layer.images));
 
-export const minLayerZIndexBelowDiagramSelector = createSelector(
-  layersForCurrentModelSelector,
-  layers => {
-    if (!layers || layers.length === 0) {
-      return -1000;
-    }
-    let minZIndex = Infinity;
-    layers.forEach((layer: LayerState) => {
-      if (layer.details.z < 0 && layer.details.z < minZIndex) {
-        minZIndex = layer.details.z;
-      }
-    });
-    return minZIndex;
-  },
-);
+    const layerMaxZ = Math.max(textsMaxZ, rectsMaxZ, ovalsMaxZ, linesMaxZ, imagesMaxZ);
 
-export const maxObjectZIndexForLayerSelector = createSelector(
-  [layersForCurrentModelSelector, (_state, layerId: number | null): number | null => layerId],
-  (layers, layerId) => {
-    if (!layers || layers.length === 0 || !layerId) {
-      return 0;
-    }
-    const foundLayer = layers.find(layer => layer.details.id === layerId);
-    if (!foundLayer) {
-      return 0;
-    }
-    const getMaxZFromItems = <T extends { z?: number }>(items: T[] = []): number =>
-      items.length > 0 ? Math.max(...items.map(item => item.z || 0)) : 0;
-
-    const textsMaxZ = getMaxZFromItems(Object.values(foundLayer.texts));
-    const rectsMaxZ = getMaxZFromItems(foundLayer.rects);
-    const ovalsMaxZ = getMaxZFromItems(foundLayer.ovals);
-    const linesMaxZ = getMaxZFromItems(foundLayer.lines);
-    const imagesMaxZ = getMaxZFromItems(Object.values(foundLayer.images));
-
-    return Math.max(textsMaxZ, rectsMaxZ, ovalsMaxZ, linesMaxZ, imagesMaxZ);
-  },
-);
+    return Math.max(maxZ, layerMaxZ);
+  }, 0);
+});
 
-export const minObjectZIndexForLayerSelector = createSelector(
-  [layersForCurrentModelSelector, (_state, layerId: number | null): number | null => layerId],
-  (layers, layerId) => {
-    if (!layers || layers.length === 0 || !layerId) {
-      return 0;
-    }
-    const foundLayer = layers.find(layer => layer.details.id === layerId);
-    if (!foundLayer) {
-      return 0;
-    }
-    const getMinZFromItems = <T extends { z?: number }>(items: T[] = []): number =>
-      items.length > 0 ? Math.min(...items.map(item => item.z || 0)) : 0;
-
-    const textsMinZ = getMinZFromItems(Object.values(foundLayer.texts));
-    const rectsMinZ = getMinZFromItems(foundLayer.rects);
-    const ovalsMinZ = getMinZFromItems(foundLayer.ovals);
-    const linesMinZ = getMinZFromItems(foundLayer.lines);
-    const imagesMinZ = getMinZFromItems(Object.values(foundLayer.images));
-
-    return Math.min(textsMinZ, rectsMinZ, ovalsMinZ, linesMinZ, imagesMinZ);
-  },
-);
+export const lowestZIndexSelector = createSelector(layersForCurrentModelSelector, layers => {
+  if (!layers || layers.length === 0) return 0;
+
+  const getMinZFromItems = <T extends { z?: number }>(items: T[] = []): number =>
+    items.length > 0 ? Math.min(...items.map(item => item.z || 0)) : 0;
+
+  return layers.reduce((minZ, layer) => {
+    const textsMinZ = getMinZFromItems(Object.values(layer.texts));
+    const rectsMinZ = getMinZFromItems(layer.rects);
+    const ovalsMinZ = getMinZFromItems(layer.ovals);
+    const linesMinZ = getMinZFromItems(layer.lines);
+    const imagesMinZ = getMinZFromItems(Object.values(layer.images));
+
+    const layerMinZ = Math.min(textsMinZ, rectsMinZ, ovalsMinZ, linesMinZ, imagesMinZ);
+
+    return Math.min(minZ, layerMinZ);
+  }, 0);
+});
diff --git a/src/redux/layers/layers.thunks.test.ts b/src/redux/layers/layers.thunks.test.ts
index 09028272..77e10bdb 100644
--- a/src/redux/layers/layers.thunks.test.ts
+++ b/src/redux/layers/layers.thunks.test.ts
@@ -111,13 +111,7 @@ describe('layers thunks', () => {
       mockedAxiosClient.onPost(apiPath.storeLayer(1)).reply(HttpStatusCode.Created, layerFixture);
 
       const { payload } = await store.dispatch(
-        addLayerForModel({
-          name: 'New Layer',
-          visible: true,
-          locked: false,
-          modelId: 1,
-          zIndex: 1,
-        }),
+        addLayerForModel({ name: 'New Layer', visible: true, locked: false, modelId: 1 }),
       );
       expect(payload).toEqual(layerFixture);
     });
@@ -128,13 +122,7 @@ describe('layers thunks', () => {
         .reply(HttpStatusCode.Created, { invalid: 'data' });
 
       const { payload } = await store.dispatch(
-        addLayerForModel({
-          name: 'New Layer',
-          visible: true,
-          locked: false,
-          modelId: 1,
-          zIndex: 1,
-        }),
+        addLayerForModel({ name: 'New Layer', visible: true, locked: false, modelId: 1 }),
       );
       expect(payload).toBeNull();
     });
@@ -151,7 +139,6 @@ describe('layers thunks', () => {
           locked: true,
           modelId: 1,
           layerId: 2,
-          zIndex: 1,
         }),
       );
       expect(payload).toEqual(layerFixture);
@@ -169,7 +156,6 @@ describe('layers thunks', () => {
           locked: true,
           modelId: 1,
           layerId: 2,
-          zIndex: 1,
         }),
       );
       expect(payload).toBeNull();
diff --git a/src/redux/layers/layers.thunks.ts b/src/redux/layers/layers.thunks.ts
index bda72fce..66035fd8 100644
--- a/src/redux/layers/layers.thunks.ts
+++ b/src/redux/layers/layers.thunks.ts
@@ -32,7 +32,7 @@ export const getLayer = createAsyncThunk<
   Layer | null,
   { modelId: number; layerId: number },
   ThunkConfig
->('layers/getLayer', async ({ modelId, layerId }) => {
+>('vectorMap/getLayer', async ({ modelId, layerId }) => {
   try {
     const { data } = await axiosInstanceNewAPI.get<Layer>(apiPath.getLayer(modelId, layerId));
 
@@ -48,7 +48,7 @@ export const getLayersForModel = createAsyncThunk<
   LayersVisibilitiesState | undefined,
   number,
   ThunkConfig
->('layers/getLayers', async (modelId: number) => {
+>('vectorMap/getLayers', async (modelId: number) => {
   try {
     const { data } = await axiosInstanceNewAPI.get<Layers>(apiPath.getLayers(modelId));
     const isDataValid = validateDataUsingZodSchema(data, pageableSchema(layerSchema));
@@ -103,14 +103,13 @@ export const getLayersForModel = createAsyncThunk<
 });
 
 export const addLayerForModel = createAsyncThunk<Layer | null, LayerStoreInterface, ThunkConfig>(
-  'layers/addLayer',
-  async ({ name, visible, locked, modelId, zIndex }) => {
+  'vectorMap/addLayer',
+  async ({ name, visible, locked, modelId }) => {
     try {
       const { data } = await axiosInstanceNewAPI.post<Layer>(apiPath.storeLayer(modelId), {
         name,
         visible,
         locked,
-        z: zIndex,
       });
 
       const isDataValid = validateDataUsingZodSchema(data, layerSchema);
@@ -123,14 +122,13 @@ export const addLayerForModel = createAsyncThunk<Layer | null, LayerStoreInterfa
 );
 
 export const updateLayer = createAsyncThunk<Layer | null, LayerUpdateInterface, ThunkConfig>(
-  'layers/updateLayer',
-  async ({ name, visible, locked, modelId, layerId, zIndex }) => {
+  'vectorMap/updateLayer',
+  async ({ name, visible, locked, modelId, layerId }) => {
     try {
       const { data } = await axiosInstanceNewAPI.put<Layer>(apiPath.updateLayer(modelId, layerId), {
         name,
         visible,
         locked,
-        z: zIndex,
       });
 
       const isDataValid = validateDataUsingZodSchema(data, layerSchema);
@@ -146,7 +144,7 @@ export const removeLayer = createAsyncThunk<
   null,
   { modelId: number; layerId: number },
   ThunkConfig
->('layers/removeLayer', async ({ modelId, layerId }) => {
+>('vectorMap/removeLayer', async ({ modelId, layerId }) => {
   try {
     await axiosInstanceNewAPI.delete<void>(apiPath.removeLayer(modelId, layerId));
     return null;
@@ -163,7 +161,7 @@ export const getLayerImage = createAsyncThunk<
     imageId: number;
   },
   ThunkConfig
->('layers/getLayerImage', async ({ modelId, layerId, imageId }) => {
+>('vectorMap/getLayerImage', async ({ modelId, layerId, imageId }) => {
   try {
     const { data } = await axiosInstanceNewAPI.get<LayerImage>(
       apiPath.getLayerImageObject(modelId, layerId, imageId),
@@ -189,7 +187,7 @@ export const addLayerImageObject = createAsyncThunk<
     glyph: number | null;
   },
   ThunkConfig
->('layers/addLayerImageObject', async ({ modelId, layerId, x, y, z, width, height, glyph }) => {
+>('vectorMap/addLayerImageObject', async ({ modelId, layerId, x, y, z, width, height, glyph }) => {
   try {
     const { data } = await axiosInstanceNewAPI.post<LayerImage>(
       apiPath.addLayerImageObject(modelId, layerId),
@@ -225,7 +223,7 @@ export const updateLayerImageObject = createAsyncThunk<
   },
   ThunkConfig
 >(
-  'layers/updateLayerImageObject',
+  'vectorMap/updateLayerImageObject',
   async ({ modelId, layerId, id, x, y, z, width, height, glyph }) => {
     try {
       const { data } = await axiosInstanceNewAPI.put<LayerImage>(
@@ -254,7 +252,7 @@ export const removeLayerImage = createAsyncThunk<
   null,
   { modelId: number; layerId: number; imageId: number },
   ThunkConfig
->('layers/removeLayerImage', async ({ modelId, layerId, imageId }) => {
+>('vectorMap/removeLayerImage', async ({ modelId, layerId, imageId }) => {
   try {
     await axiosInstanceNewAPI.delete<void>(
       apiPath.removeLayerImageObject(modelId, layerId, imageId),
@@ -275,7 +273,7 @@ export const addLayerText = createAsyncThunk<
     textData: LayerTextFactoryForm;
   },
   ThunkConfig
->('layers/addLayerText', async ({ modelId, layerId, z, boundingBox, textData }) => {
+>('vectorMap/addLayerText', async ({ modelId, layerId, z, boundingBox, textData }) => {
   try {
     const { data } = await axiosInstanceNewAPI.post<LayerText>(
       apiPath.addLayerText(modelId, layerId),
@@ -301,7 +299,7 @@ export const getLayerText = createAsyncThunk<
     textId: number;
   },
   ThunkConfig
->('layers/getLayerText', async ({ modelId, layerId, textId }) => {
+>('vectorMap/getLayerText', async ({ modelId, layerId, textId }) => {
   try {
     const { data } = await axiosInstanceNewAPI.get<LayerText>(
       apiPath.getLayerText(modelId, layerId, textId),
diff --git a/src/redux/layers/layers.types.ts b/src/redux/layers/layers.types.ts
index 05b4636e..60e42717 100644
--- a/src/redux/layers/layers.types.ts
+++ b/src/redux/layers/layers.types.ts
@@ -6,7 +6,6 @@ export interface LayerStoreInterface {
   visible: boolean;
   locked: boolean;
   modelId: number;
-  zIndex: number;
 }
 
 export interface LayerUpdateInterface {
@@ -15,7 +14,6 @@ export interface LayerUpdateInterface {
   visible: boolean;
   locked: boolean;
   modelId: number;
-  zIndex: number;
 }
 
 export type LayerState = {
diff --git a/src/shared/Icon/Icon.component.tsx b/src/shared/Icon/Icon.component.tsx
index aed961c3..5745b6ec 100644
--- a/src/shared/Icon/Icon.component.tsx
+++ b/src/shared/Icon/Icon.component.tsx
@@ -31,10 +31,8 @@ import { PadlockOpenIcon } from '@/shared/Icon/Icons/PadlockOpenIcon';
 import { PadlockLockedIcon } from '@/shared/Icon/Icons/PadlockLockedIcon';
 import { CrossedEyeIcon } from '@/shared/Icon/Icons/CrossedEyeIcon';
 import { CenterIcon } from '@/shared/Icon/Icons/CenterIcon';
-import { MoveFrontIcon } from '@/shared/Icon/Icons/MoveFrontIcon';
-import { MoveBackIcon } from '@/shared/Icon/Icons/MoveBackIcon';
-import { LayerArrowUpIcon } from '@/shared/Icon/Icons/LayerArrowUpIcon';
-import { LayerArrowDownIcon } from '@/shared/Icon/Icons/LayerArrowDownIcon';
+import { BringFrontIcon } from '@/shared/Icon/Icons/BringFrontIcon';
+import { BringBackIcon } from '@/shared/Icon/Icons/BringBackIcon';
 import { LocationIcon } from './Icons/LocationIcon';
 import { MaginfierZoomInIcon } from './Icons/MagnifierZoomIn';
 import { MaginfierZoomOutIcon } from './Icons/MagnifierZoomOut';
@@ -89,10 +87,8 @@ const icons: Record<IconTypes, IconComponentType> = {
   'padlock-open': PadlockOpenIcon,
   'padlock-locked': PadlockLockedIcon,
   center: CenterIcon,
-  'move-front': MoveFrontIcon,
-  'move-back': MoveBackIcon,
-  'layer-arrow-up': LayerArrowUpIcon,
-  'layer-arrow-down': LayerArrowDownIcon,
+  'bring-front': BringFrontIcon,
+  'bring-back': BringBackIcon,
 } as const;
 
 export const Icon = ({ name, className = '', ...rest }: IconProps): JSX.Element => {
diff --git a/src/shared/Icon/Icons/ArrowDoubleDownIcon.tsx b/src/shared/Icon/Icons/ArrowDoubleDownIcon.tsx
index cf5ce5f7..d7ab4e38 100644
--- a/src/shared/Icon/Icons/ArrowDoubleDownIcon.tsx
+++ b/src/shared/Icon/Icons/ArrowDoubleDownIcon.tsx
@@ -13,16 +13,26 @@ export const ArrowDoubleDownIcon = ({ className }: ArrowDoubleDownIconProps): JS
   >
     <path
       d="M8 8L8 18M8 18L5 15M8 18L11 15"
+      stroke="currentColor"
       strokeWidth="1.5"
       strokeLinecap="round"
       strokeLinejoin="round"
     />
     <path
       d="M16 8L16 18M16 18L13 15M16 18L19 15"
+      stroke="currentColor"
       strokeWidth="1.5"
       strokeLinecap="round"
       strokeLinejoin="round"
     />
-    <line x1="4" y1="6" x2="20" y2="6" strokeWidth="1.5" strokeLinecap="round" />
+    <line
+      x1="4"
+      y1="6"
+      x2="20"
+      y2="6"
+      stroke="currentColor"
+      strokeWidth="1.5"
+      strokeLinecap="round"
+    />
   </svg>
 );
diff --git a/src/shared/Icon/Icons/ArrowDoubleUpIcon.tsx b/src/shared/Icon/Icons/ArrowDoubleUpIcon.tsx
index 861773cd..ed51a602 100644
--- a/src/shared/Icon/Icons/ArrowDoubleUpIcon.tsx
+++ b/src/shared/Icon/Icons/ArrowDoubleUpIcon.tsx
@@ -13,16 +13,26 @@ export const ArrowDoubleUpIcon = ({ className }: ArrowDoubleUpIconProps): JSX.El
   >
     <path
       d="M8 16L8 6M8 6L5 9M8 6L11 9"
+      stroke="currentColor"
       strokeWidth="1.5"
       strokeLinecap="round"
       strokeLinejoin="round"
     />
     <path
       d="M16 16L16 6M16 6L13 9M16 6L19 9"
+      stroke="currentColor"
       strokeWidth="1.5"
       strokeLinecap="round"
       strokeLinejoin="round"
     />
-    <line x1="4" y1="18" x2="20" y2="18" strokeWidth="1.5" strokeLinecap="round" />
+    <line
+      x1="4"
+      y1="18"
+      x2="20"
+      y2="18"
+      stroke="currentColor"
+      strokeWidth="1.5"
+      strokeLinecap="round"
+    />
   </svg>
 );
diff --git a/src/shared/Icon/Icons/MoveBackIcon.tsx b/src/shared/Icon/Icons/BringBackIcon.tsx
similarity index 78%
rename from src/shared/Icon/Icons/MoveBackIcon.tsx
rename to src/shared/Icon/Icons/BringBackIcon.tsx
index 734bd201..d086ac9b 100644
--- a/src/shared/Icon/Icons/MoveBackIcon.tsx
+++ b/src/shared/Icon/Icons/BringBackIcon.tsx
@@ -1,8 +1,8 @@
-interface MoveBackIconProps {
+interface BringBackIconProps {
   className?: string;
 }
 
-export const MoveBackIcon = ({ className }: MoveBackIconProps): JSX.Element => (
+export const BringBackIcon = ({ className }: BringBackIconProps): JSX.Element => (
   <svg
     width="20"
     height="20"
@@ -23,6 +23,6 @@ export const MoveBackIcon = ({ className }: MoveBackIconProps): JSX.Element => (
       stroke="white"
       fill="none"
     />
-    <rect x="4" y="4" width="64" height="64" rx="10" ry="10" strokeWidth="8" />
+    <rect x="4" y="4" width="64" height="64" rx="10" ry="10" strokeWidth="8" fill="black" />
   </svg>
 );
diff --git a/src/shared/Icon/Icons/MoveFrontIcon.tsx b/src/shared/Icon/Icons/BringFrontIcon.tsx
similarity index 77%
rename from src/shared/Icon/Icons/MoveFrontIcon.tsx
rename to src/shared/Icon/Icons/BringFrontIcon.tsx
index 037f5cb3..e5aa5017 100644
--- a/src/shared/Icon/Icons/MoveFrontIcon.tsx
+++ b/src/shared/Icon/Icons/BringFrontIcon.tsx
@@ -1,8 +1,8 @@
-interface MoveFrontIconProps {
+interface BringFrontIconProps {
   className?: string;
 }
 
-export const MoveFrontIcon = ({ className }: MoveFrontIconProps): JSX.Element => (
+export const BringFrontIcon = ({ className }: BringFrontIconProps): JSX.Element => (
   <svg
     width="20"
     height="20"
@@ -11,7 +11,7 @@ export const MoveFrontIcon = ({ className }: MoveFrontIconProps): JSX.Element =>
     fill="none"
     className={className}
   >
-    <rect x="4" y="4" width="64" height="64" rx="10" ry="10" strokeWidth="8" />
+    <rect x="4" y="4" width="64" height="64" rx="10" ry="10" strokeWidth="8" fill="black" />
     <rect
       x="30"
       y="30"
diff --git a/src/shared/Icon/Icons/LayerArrowDownIcon.tsx b/src/shared/Icon/Icons/LayerArrowDownIcon.tsx
deleted file mode 100644
index 71223a31..00000000
--- a/src/shared/Icon/Icons/LayerArrowDownIcon.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-interface LayerArrowDownIconProps {
-  className?: string;
-}
-
-export const LayerArrowDownIcon = ({ className }: LayerArrowDownIconProps): JSX.Element => (
-  <svg
-    width="20"
-    height="20"
-    viewBox="2 3 20 17"
-    fill="none"
-    xmlns="http://www.w3.org/2000/svg"
-    className={className}
-  >
-    <path d="M12 21L7 16H10V10H14V16H17L12 21Z" />
-    <rect x="4" y="3" width="16" height="2" />
-    <rect x="4" y="7" width="16" height="2" />
-  </svg>
-);
diff --git a/src/shared/Icon/Icons/LayerArrowUpIcon.tsx b/src/shared/Icon/Icons/LayerArrowUpIcon.tsx
deleted file mode 100644
index bbcf233f..00000000
--- a/src/shared/Icon/Icons/LayerArrowUpIcon.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-interface LayerArrowUpIconProps {
-  className?: string;
-}
-
-export const LayerArrowUpIcon = ({ className }: LayerArrowUpIconProps): JSX.Element => (
-  <svg
-    width="20"
-    height="20"
-    viewBox="2 3 20 19"
-    fill="none"
-    xmlns="http://www.w3.org/2000/svg"
-    className={className}
-  >
-    <path d="M12 3L7 8H10V14H14V8H17L12 3Z" />
-    <rect x="4" y="16" width="16" height="2" />
-    <rect x="4" y="20" width="16" height="2" />
-  </svg>
-);
diff --git a/src/shared/IconButton/IconButton.component.tsx b/src/shared/IconButton/IconButton.component.tsx
index e71c6211..1330e460 100644
--- a/src/shared/IconButton/IconButton.component.tsx
+++ b/src/shared/IconButton/IconButton.component.tsx
@@ -29,8 +29,8 @@ export const IconButton = ({
 
   const isStrokeIcon = [
     'plugin',
-    'move-back',
-    'move-front',
+    'bring-back',
+    'bring-front',
     'center',
     'eye',
     'crossed-eye',
@@ -38,8 +38,6 @@ export const IconButton = ({
     'padlock-locked',
     'layers',
     'edit',
-    'arrow-double-up',
-    'arrow-double-down',
   ].includes(icon);
 
   return (
@@ -59,8 +57,6 @@ export const IconButton = ({
           isStrokeIcon
             ? 'stroke-font-400 group-hover:stroke-primary-500 group-active:stroke-primary-500'
             : 'fill-font-400 group-hover:fill-primary-500 group-active:fill-primary-500',
-          ['move-back', 'move-front'].includes(icon) &&
-            'fill-font-400 stroke-font-400 group-hover:fill-primary-500 group-hover:stroke-primary-500 group-active:fill-primary-500 group-active:stroke-primary-500',
           isActive && getActiveFillOrStrokeColor(icon),
           classNameIcon,
         )}
diff --git a/src/types/iconTypes.ts b/src/types/iconTypes.ts
index 0083a622..0d74dd78 100644
--- a/src/types/iconTypes.ts
+++ b/src/types/iconTypes.ts
@@ -38,9 +38,7 @@ export type IconTypes =
   | 'padlock-open'
   | 'padlock-locked'
   | 'center'
-  | 'move-front'
-  | 'move-back'
-  | 'layer-arrow-up'
-  | 'layer-arrow-down';
+  | 'bring-front'
+  | 'bring-back';
 
 export type IconComponentType = ({ className }: { className: string }) => JSX.Element;
-- 
GitLab


From 9a22256d5716408896071fe7f94a3eb95ca86932 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mi=C5=82osz=20Grocholewski?= <m.grocholewski@atcomp.pl>
Date: Tue, 18 Feb 2025 10:24:21 +0100
Subject: [PATCH 5/8] feat(layers): add layers zIndex editing

-- 
GitLab


From 3b5fd23cd01eca739523f29616d79577817a2bd3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mi=C5=82osz=20Grocholewski?= <m.grocholewski@atcomp.pl>
Date: Tue, 18 Feb 2025 10:27:03 +0100
Subject: [PATCH 6/8] Revert "Revert "feat(layers): add layers zIndex editing""

This reverts commit f6e504ece2951e59900cec58b70bec18b21b4bde.
---
 .../LayerFactoryModal.component.tsx           |   4 +
 ...LayerImageObjectFactoryModal.component.tsx |   9 +-
 .../LayerTextFactoryModal.component.tsx       |   9 +-
 .../LayerDrawerTextItem.component.tsx         |  12 +-
 .../LayersDrawer/LayersDrawer.component.tsx   |  46 ++++--
 .../LayersDrawerImageItem.component.tsx       |  12 +-
 .../LayersDrawerLayer.component.tsx           | 107 +++++++++++---
 .../LayersDrawerLayerActions.component.tsx    |  39 +++++
 .../LayersDrawerObjectActions.component.tsx   |  20 +--
 .../LayersDrawerObjectsList.component.tsx     |  32 ++--
 .../useOlMapAdditionalLayers.ts               |   1 +
 .../commentsLayer/useOlMapCommentsLayer.ts    |   1 +
 .../config/mapCardLayer/useOlMapCardLayer.ts  |   1 +
 .../config/pinsLayer/useOlMapPinsLayer.ts     |   1 +
 .../processLayer/useOlMapProcessLayer.ts      |   1 +
 .../reactionsLayer/useOlMapReactionsLayer.ts  |   1 +
 .../utils/shapes/layer/Layer.test.ts          |   1 +
 .../Map/MapViewer/utils/shapes/layer/Layer.ts |   3 +
 src/models/layerSchema.ts                     |   1 +
 src/redux/layers/layers.reducers.test.ts      |   4 +-
 src/redux/layers/layers.selectors.ts          | 139 +++++++++++++-----
 src/redux/layers/layers.thunks.test.ts        |  18 ++-
 src/redux/layers/layers.thunks.ts             |  28 ++--
 src/redux/layers/layers.types.ts              |   2 +
 src/shared/Icon/Icon.component.tsx            |  12 +-
 src/shared/Icon/Icons/ArrowDoubleDownIcon.tsx |  12 +-
 src/shared/Icon/Icons/ArrowDoubleUpIcon.tsx   |  12 +-
 src/shared/Icon/Icons/LayerArrowDownIcon.tsx  |  18 +++
 src/shared/Icon/Icons/LayerArrowUpIcon.tsx    |  18 +++
 .../{BringBackIcon.tsx => MoveBackIcon.tsx}   |   6 +-
 .../{BringFrontIcon.tsx => MoveFrontIcon.tsx} |   6 +-
 .../IconButton/IconButton.component.tsx       |   8 +-
 src/types/iconTypes.ts                        |   6 +-
 33 files changed, 430 insertions(+), 160 deletions(-)
 create mode 100644 src/shared/Icon/Icons/LayerArrowDownIcon.tsx
 create mode 100644 src/shared/Icon/Icons/LayerArrowUpIcon.tsx
 rename src/shared/Icon/Icons/{BringBackIcon.tsx => MoveBackIcon.tsx} (78%)
 rename src/shared/Icon/Icons/{BringFrontIcon.tsx => MoveFrontIcon.tsx} (77%)

diff --git a/src/components/FunctionalArea/Modal/LayerFactoryModal/LayerFactoryModal.component.tsx b/src/components/FunctionalArea/Modal/LayerFactoryModal/LayerFactoryModal.component.tsx
index 8d925951..b806d2b6 100644
--- a/src/components/FunctionalArea/Modal/LayerFactoryModal/LayerFactoryModal.component.tsx
+++ b/src/components/FunctionalArea/Modal/LayerFactoryModal/LayerFactoryModal.component.tsx
@@ -19,11 +19,13 @@ import { SerializedError } from '@reduxjs/toolkit';
 import { layerFactoryStateSelector } from '@/redux/modal/modal.selector';
 import './LayerFactoryModal.styles.css';
 import { LoadingIndicator } from '@/shared/LoadingIndicator';
+import { maxLayerZIndexAboveDiagramSelector } from '@/redux/layers/layers.selectors';
 
 export const LayerFactoryModal: React.FC = () => {
   const dispatch = useAppDispatch();
   const currentModelId = useAppSelector(currentModelIdSelector);
   const layerFactoryState = useAppSelector(layerFactoryStateSelector);
+  const maxLayerZIndexAboveDiagram = useAppSelector(maxLayerZIndexAboveDiagramSelector);
   const [loaded, setLoaded] = useState<boolean>(false);
 
   const [data, setData] = useState<LayerStoreInterface>({
@@ -31,6 +33,7 @@ export const LayerFactoryModal: React.FC = () => {
     visible: false,
     locked: false,
     modelId: currentModelId,
+    zIndex: maxLayerZIndexAboveDiagram,
   });
 
   const fetchData = useMemo(() => {
@@ -42,6 +45,7 @@ export const LayerFactoryModal: React.FC = () => {
           visible: layer.visible,
           locked: layer.locked,
           modelId: currentModelId,
+          zIndex: layer.z,
         });
       }
       setLoaded(true);
diff --git a/src/components/FunctionalArea/Modal/LayerImageObjectModal/LayerImageObjectFactoryModal.component.tsx b/src/components/FunctionalArea/Modal/LayerImageObjectModal/LayerImageObjectFactoryModal.component.tsx
index 1efb7d88..4d1513e9 100644
--- a/src/components/FunctionalArea/Modal/LayerImageObjectModal/LayerImageObjectFactoryModal.component.tsx
+++ b/src/components/FunctionalArea/Modal/LayerImageObjectModal/LayerImageObjectFactoryModal.component.tsx
@@ -4,7 +4,10 @@ import { useAppSelector } from '@/redux/hooks/useAppSelector';
 import { layerImageObjectFactoryStateSelector } from '@/redux/modal/modal.selector';
 import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
 import { currentModelIdSelector } from '@/redux/models/models.selectors';
-import { highestZIndexSelector, layersDrawLayerSelector } from '@/redux/layers/layers.selectors';
+import {
+  layersDrawLayerSelector,
+  maxObjectZIndexForLayerSelector,
+} from '@/redux/layers/layers.selectors';
 import { addLayerImageObject } from '@/redux/layers/layers.thunks';
 import { addGlyph } from '@/redux/glyphs/glyphs.thunks';
 import { SerializedError } from '@reduxjs/toolkit';
@@ -22,7 +25,7 @@ export const LayerImageObjectFactoryModal: React.FC = () => {
   const drawLayer = useAppSelector(layersDrawLayerSelector);
   const layerImageObjectFactoryState = useAppSelector(layerImageObjectFactoryStateSelector);
   const dispatch = useAppDispatch();
-  const highestZIndex = useAppSelector(highestZIndexSelector);
+  const maxZIndex = useAppSelector(state => maxObjectZIndexForLayerSelector(state, drawLayer));
   const { mapInstance } = useMapInstance();
 
   const [selectedGlyph, setSelectedGlyph] = useState<number | null>(null);
@@ -49,7 +52,7 @@ export const LayerImageObjectFactoryModal: React.FC = () => {
           layerId: drawLayer,
           x: layerImageObjectFactoryState.x,
           y: layerImageObjectFactoryState.y,
-          z: highestZIndex + 1,
+          z: maxZIndex + 1,
           width: layerImageObjectFactoryState.width,
           height: layerImageObjectFactoryState.height,
           glyph: glyphId,
diff --git a/src/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextFactoryModal.component.tsx b/src/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextFactoryModal.component.tsx
index e1ccf612..bfb80aff 100644
--- a/src/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextFactoryModal.component.tsx
+++ b/src/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextFactoryModal.component.tsx
@@ -13,7 +13,10 @@ import { LayerTextFactoryForm } from '@/components/FunctionalArea/Modal/LayerTex
 import { Color } from '@/types/models';
 import { useAppSelector } from '@/redux/hooks/useAppSelector';
 import { layerTextFactoryStateSelector } from '@/redux/modal/modal.selector';
-import { highestZIndexSelector, layersDrawLayerSelector } from '@/redux/layers/layers.selectors';
+import {
+  layersDrawLayerSelector,
+  maxObjectZIndexForLayerSelector,
+} from '@/redux/layers/layers.selectors';
 import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
 import { currentModelIdSelector } from '@/redux/models/models.selectors';
 import { showToast } from '@/utils/showToast';
@@ -31,7 +34,7 @@ export const LayerTextFactoryModal: React.FC = () => {
   const currentModelId = useAppSelector(currentModelIdSelector);
   const layerTextFactoryState = useAppSelector(layerTextFactoryStateSelector);
   const dispatch = useAppDispatch();
-  const highestZIndex = useAppSelector(highestZIndexSelector);
+  const maxZIndex = useAppSelector(state => maxObjectZIndexForLayerSelector(state, drawLayer));
   const { mapInstance } = useMapInstance();
 
   const [isSending, setIsSending] = useState<boolean>(false);
@@ -55,7 +58,7 @@ export const LayerTextFactoryModal: React.FC = () => {
           layerId: drawLayer,
           boundingBox: layerTextFactoryState,
           textData: data,
-          z: highestZIndex + 1,
+          z: maxZIndex + 1,
         }),
       ).unwrap();
       if (!textData) {
diff --git a/src/components/Map/Drawer/LayersDrawer/LayerDrawerTextItem.component.tsx b/src/components/Map/Drawer/LayersDrawer/LayerDrawerTextItem.component.tsx
index 6f57c762..a9c3d3b3 100644
--- a/src/components/Map/Drawer/LayersDrawer/LayerDrawerTextItem.component.tsx
+++ b/src/components/Map/Drawer/LayersDrawer/LayerDrawerTextItem.component.tsx
@@ -10,8 +10,8 @@ import { hasPrivilegeToWriteProjectSelector } from '@/redux/user/user.selectors'
 
 interface LayersDrawerTextItemProps {
   layerText: LayerText;
-  bringToFront: () => void;
-  bringToBack: () => void;
+  moveToFront: () => void;
+  moveToBack: () => void;
   removeObject: () => void;
   centerObject: () => void;
   editObject: () => void;
@@ -21,8 +21,8 @@ interface LayersDrawerTextItemProps {
 
 export const LayersDrawerTextItem = ({
   layerText,
-  bringToFront,
-  bringToBack,
+  moveToFront,
+  moveToBack,
   removeObject,
   centerObject,
   editObject,
@@ -68,8 +68,8 @@ export const LayersDrawerTextItem = ({
       </div>
       {showActions && (
         <LayersDrawerObjectActions
-          bringToFront={bringToFront}
-          bringToBack={bringToBack}
+          moveToFront={moveToFront}
+          moveToBack={moveToBack}
           removeObject={removeObject}
           centerObject={centerObject}
           editObject={editObject}
diff --git a/src/components/Map/Drawer/LayersDrawer/LayersDrawer.component.tsx b/src/components/Map/Drawer/LayersDrawer/LayersDrawer.component.tsx
index 12bef081..33c259f3 100644
--- a/src/components/Map/Drawer/LayersDrawer/LayersDrawer.component.tsx
+++ b/src/components/Map/Drawer/LayersDrawer/LayersDrawer.component.tsx
@@ -4,7 +4,7 @@ import { DrawerHeading } from '@/shared/DrawerHeading';
 import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
 import { layersForCurrentModelSelector } from '@/redux/layers/layers.selectors';
 import { Button } from '@/shared/Button';
-import { JSX, useEffect, useRef } from 'react';
+import { JSX, useEffect, useMemo, useRef } from 'react';
 import { openLayerFactoryModal } from '@/redux/modal/modal.slice';
 import { hasPrivilegeToWriteProjectSelector } from '@/redux/user/user.selectors';
 import { LayersDrawerLayer } from '@/components/Map/Drawer/LayersDrawer/LayersDrawerLayer.component';
@@ -21,6 +21,19 @@ export const LayersDrawer = (): JSX.Element => {
     dispatch(openLayerFactoryModal());
   };
 
+  const sortedLayers = useMemo(() => {
+    return [...layersForCurrentModel].sort((layerA, layerB) => layerB.details.z - layerA.details.z);
+  }, [layersForCurrentModel]);
+
+  const negativeZLayers = useMemo(
+    () => sortedLayers.filter(layer => layer.details.z < 0),
+    [sortedLayers],
+  );
+  const positiveZLayers = useMemo(
+    () => sortedLayers.filter(layer => layer.details.z >= 0),
+    [sortedLayers],
+  );
+
   useEffect(() => {
     if (!mapEditToolsLayerImageObject || !layersDrawerRef.current) {
       return;
@@ -61,20 +74,33 @@ export const LayersDrawer = (): JSX.Element => {
         ref={layersDrawerRef}
       >
         {hasPrivilegeToWriteProject && (
-          <div className="flex justify-start pt-2">
+          <div className="flex justify-start py-2">
             <Button icon="plus" isIcon isFrontIcon onClick={addNewLayer}>
               Add layer
             </Button>
           </div>
         )}
-        <div className="flex flex-col gap-4">
-          {layersForCurrentModel.map(layer => (
-            <LayersDrawerLayer
-              key={layer.details.id}
-              layerId={layer.details.id}
-              layerName={layer.details.name}
-            />
-          ))}
+        <div className="flex flex-col gap-2">
+          {Boolean(positiveZLayers.length) && (
+            <span className="border-b-2 border-dashed border-b-gray-400 text-center text-lg font-semibold">
+              Layers above the diagram
+            </span>
+          )}
+          <div className="flex flex-col gap-5">
+            {positiveZLayers.map(layer => (
+              <LayersDrawerLayer key={layer.details.id} layerDetails={layer.details} />
+            ))}
+          </div>
+          {Boolean(negativeZLayers.length) && (
+            <span className="border-b-2 border-dashed border-b-gray-400 text-center text-lg font-semibold">
+              Layers below the diagram
+            </span>
+          )}
+          <div className="flex flex-col gap-5">
+            {negativeZLayers.map(layer => (
+              <LayersDrawerLayer key={layer.details.id} layerDetails={layer.details} />
+            ))}
+          </div>
         </div>
       </div>
     </div>
diff --git a/src/components/Map/Drawer/LayersDrawer/LayersDrawerImageItem.component.tsx b/src/components/Map/Drawer/LayersDrawer/LayersDrawerImageItem.component.tsx
index 0622f141..e160b807 100644
--- a/src/components/Map/Drawer/LayersDrawer/LayersDrawerImageItem.component.tsx
+++ b/src/components/Map/Drawer/LayersDrawer/LayersDrawerImageItem.component.tsx
@@ -11,8 +11,8 @@ import { hasPrivilegeToWriteProjectSelector } from '@/redux/user/user.selectors'
 
 interface LayersDrawerImageItemProps {
   layerImage: LayerImage;
-  bringToFront: () => void;
-  bringToBack: () => void;
+  moveToFront: () => void;
+  moveToBack: () => void;
   removeObject: () => void;
   centerObject: () => void;
   editObject: () => void;
@@ -22,8 +22,8 @@ interface LayersDrawerImageItemProps {
 
 export const LayersDrawerImageItem = ({
   layerImage,
-  bringToFront,
-  bringToBack,
+  moveToFront,
+  moveToBack,
   removeObject,
   centerObject,
   editObject,
@@ -72,8 +72,8 @@ export const LayersDrawerImageItem = ({
       </div>
       {showActions && (
         <LayersDrawerObjectActions
-          bringToFront={bringToFront}
-          bringToBack={bringToBack}
+          moveToFront={moveToFront}
+          moveToBack={moveToBack}
           removeObject={removeObject}
           centerObject={centerObject}
           editObject={editObject}
diff --git a/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayer.component.tsx b/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayer.component.tsx
index 49b8536f..8b0f9b01 100644
--- a/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayer.component.tsx
+++ b/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayer.component.tsx
@@ -1,14 +1,19 @@
+/* eslint-disable no-magic-numbers */
 import { useAppSelector } from '@/redux/hooks/useAppSelector';
 import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
 import {
   layersActiveLayersSelector,
   layersVisibilityForCurrentModelSelector,
+  maxLayerZIndexAboveDiagramSelector,
+  maxLayerZIndexBelowDiagramSelector,
+  minLayerZIndexAboveDiagramSelector,
+  minLayerZIndexBelowDiagramSelector,
 } from '@/redux/layers/layers.selectors';
 import { currentModelIdSelector } from '@/redux/models/models.selectors';
 import { openLayerFactoryModal } from '@/redux/modal/modal.slice';
 import QuestionModal from '@/components/FunctionalArea/Modal/QuestionModal/QustionModal.component';
 import { useState, JSX, useMemo } from 'react';
-import { getLayersForModel, removeLayer } from '@/redux/layers/layers.thunks';
+import { getLayersForModel, removeLayer, updateLayer } from '@/redux/layers/layers.thunks';
 import { showToast } from '@/utils/showToast';
 import { SerializedError } from '@reduxjs/toolkit';
 import { LayersDrawerLayerActions } from '@/components/Map/Drawer/LayersDrawer/LayersDrawerLayerActions.component';
@@ -21,38 +26,42 @@ import {
 import { LayersDrawerObjectsList } from '@/components/Map/Drawer/LayersDrawer/LayersDrawerObjectsList.component';
 import { mapEditToolsSetActiveAction } from '@/redux/mapEditTools/mapEditTools.slice';
 import { MAP_EDIT_ACTIONS } from '@/redux/mapEditTools/mapEditTools.constants';
+import { Layer } from '@/types/models';
 
 interface LayersDrawerLayerProps {
-  layerId: number;
-  layerName: string;
+  layerDetails: Layer;
 }
 
-export const LayersDrawerLayer = ({ layerId, layerName }: LayersDrawerLayerProps): JSX.Element => {
+export const LayersDrawerLayer = ({ layerDetails }: LayersDrawerLayerProps): JSX.Element => {
   const layersVisibilityForCurrentModel = useAppSelector(layersVisibilityForCurrentModelSelector);
   const activeLayers = useAppSelector(layersActiveLayersSelector);
   const currentModelId = useAppSelector(currentModelIdSelector);
+  const maxLayerZIndexAboveDiagram = useAppSelector(maxLayerZIndexAboveDiagramSelector);
+  const maxLayerZIndexBelowDiagram = useAppSelector(maxLayerZIndexBelowDiagramSelector);
+  const minLayerZIndexAboveDiagram = useAppSelector(minLayerZIndexAboveDiagramSelector);
+  const minLayerZIndexBelowDiagram = useAppSelector(minLayerZIndexBelowDiagramSelector);
   const dispatch = useAppDispatch();
   const [isModalOpen, setIsModalOpen] = useState(false);
 
   const isLayerVisible = useMemo(() => {
-    return layersVisibilityForCurrentModel[layerId];
-  }, [layerId, layersVisibilityForCurrentModel]);
+    return layersVisibilityForCurrentModel[layerDetails.id];
+  }, [layerDetails.id, layersVisibilityForCurrentModel]);
 
   const isLayerActive = useMemo(() => {
-    return activeLayers.includes(layerId);
-  }, [activeLayers, layerId]);
+    return activeLayers.includes(layerDetails.id);
+  }, [activeLayers, layerDetails.id]);
 
   const editLayer = (): void => {
-    dispatch(openLayerFactoryModal(layerId));
+    dispatch(openLayerFactoryModal(layerDetails.id));
   };
 
   const addImage = (): void => {
-    dispatch(setDrawLayer({ modelId: currentModelId, layerId }));
+    dispatch(setDrawLayer({ modelId: currentModelId, layerId: layerDetails.id }));
     dispatch(mapEditToolsSetActiveAction(MAP_EDIT_ACTIONS.DRAW_IMAGE));
   };
 
   const addText = (): void => {
-    dispatch(setDrawLayer({ modelId: currentModelId, layerId }));
+    dispatch(setDrawLayer({ modelId: currentModelId, layerId: layerDetails.id }));
     dispatch(mapEditToolsSetActiveAction(MAP_EDIT_ACTIONS.ADD_TEXT));
   };
 
@@ -61,11 +70,11 @@ export const LayersDrawerLayer = ({ layerId, layerName }: LayersDrawerLayerProps
   };
 
   const confirmRemove = async (): Promise<void> => {
-    if (!layerId) {
+    if (!layerDetails.id) {
       return;
     }
     try {
-      await dispatch(removeLayer({ modelId: currentModelId, layerId })).unwrap();
+      await dispatch(removeLayer({ modelId: currentModelId, layerId: layerDetails.id })).unwrap();
       showToast({
         type: 'success',
         message: 'The layer has been successfully removed',
@@ -87,12 +96,61 @@ export const LayersDrawerLayer = ({ layerId, layerName }: LayersDrawerLayerProps
 
   const toggleActiveLayer = (value: boolean): void => {
     if (value) {
-      dispatch(setLayerToActive({ modelId: currentModelId, layerId }));
+      dispatch(setLayerToActive({ modelId: currentModelId, layerId: layerDetails.id }));
     } else {
-      dispatch(setLayerToInactive({ modelId: currentModelId, layerId }));
+      dispatch(setLayerToInactive({ modelId: currentModelId, layerId: layerDetails.id }));
     }
   };
 
+  const updateLayerZIndex = async (zIndex: number): Promise<void> => {
+    try {
+      dispatch(
+        updateLayer({
+          name: layerDetails.name,
+          visible: layerDetails.visible,
+          locked: layerDetails.locked,
+          modelId: currentModelId,
+          layerId: layerDetails.id,
+          zIndex,
+        }),
+      );
+    } catch (error) {
+      const typedError = error as SerializedError;
+      showToast({
+        type: 'error',
+        message: typedError.message || 'An error occurred while updating the layer',
+      });
+    }
+  };
+
+  const moveToFront = (): void => {
+    if (layerDetails.z > 0) {
+      updateLayerZIndex(maxLayerZIndexAboveDiagram);
+    } else if (layerDetails.z < 0) {
+      const zIndex = Math.min(maxLayerZIndexBelowDiagram, -1);
+      updateLayerZIndex(zIndex);
+    }
+  };
+
+  const moveToBack = (): void => {
+    if (layerDetails.z > 0) {
+      const zIndex = Math.max(minLayerZIndexAboveDiagram, 1);
+      updateLayerZIndex(zIndex);
+    } else if (layerDetails.z < 0) {
+      updateLayerZIndex(minLayerZIndexBelowDiagram);
+    }
+  };
+
+  const moveAboveDiagram = (): void => {
+    const zIndex = Math.max(minLayerZIndexAboveDiagram - 1, 1);
+    updateLayerZIndex(zIndex);
+  };
+
+  const moveBelowDiagram = (): void => {
+    const zIndex = Math.min(minLayerZIndexBelowDiagram + 1, -1);
+    updateLayerZIndex(zIndex);
+  };
+
   return (
     <div>
       <QuestionModal
@@ -101,9 +159,13 @@ export const LayersDrawerLayer = ({ layerId, layerName }: LayersDrawerLayerProps
         onConfirm={confirmRemove}
         question="Are you sure you want to remove the layer?"
       />
-      <div className="flex items-center justify-between py-3">
-        <span className={`font-semibold ${isLayerVisible ? 'opacity-100' : 'opacity-40'}`}>
-          {layerName}
+      <div className="flex items-center justify-between pb-3">
+        <span
+          className={`font-semibold ${
+            isLayerVisible ? 'opacity-100' : 'opacity-40'
+          } min-w-0 flex-1 truncate `}
+        >
+          {layerDetails.name}
         </span>
         <LayersDrawerLayerActions
           toggleVisibility={() =>
@@ -111,7 +173,7 @@ export const LayersDrawerLayer = ({ layerId, layerName }: LayersDrawerLayerProps
               setLayerVisibility({
                 modelId: currentModelId,
                 visible: !isLayerVisible,
-                layerId,
+                layerId: layerDetails.id,
               }),
             )
           }
@@ -120,12 +182,17 @@ export const LayersDrawerLayer = ({ layerId, layerName }: LayersDrawerLayerProps
           removeLayer={onRemoveLayer}
           addImage={addImage}
           addText={addText}
+          moveToFront={moveToFront}
+          moveToBack={moveToBack}
+          moveAboveDiagram={moveAboveDiagram}
+          moveBelowDiagram={moveBelowDiagram}
+          zIndex={layerDetails.z}
           isVisible={isLayerVisible}
           isActive={isLayerActive}
         />
       </div>
       <LayersDrawerObjectsList
-        layerId={layerId}
+        layerId={layerDetails.id}
         isLayerVisible={isLayerVisible}
         isLayerActive={isLayerActive}
       />
diff --git a/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayerActions.component.tsx b/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayerActions.component.tsx
index 18627b13..81435100 100644
--- a/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayerActions.component.tsx
+++ b/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayerActions.component.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable no-magic-numbers */
 import { IconButton } from '@/shared/IconButton';
 import { JSX } from 'react';
 import { LayerDrawerLayerContextMenu } from '@/components/Map/Drawer/LayersDrawer/LayerDrawerLayerContextMenu.component';
@@ -9,10 +10,15 @@ type LayersDrawerLayerActionsProps = {
   removeLayer: () => void;
   isVisible: boolean;
   isActive: boolean;
+  zIndex: number;
   toggleVisibility: () => void;
   toggleActiveLayer: (value: boolean) => void;
   addImage: () => void;
   addText: () => void;
+  moveToFront: () => void;
+  moveToBack: () => void;
+  moveAboveDiagram: () => void;
+  moveBelowDiagram: () => void;
 };
 
 export const LayersDrawerLayerActions = ({
@@ -20,10 +26,15 @@ export const LayersDrawerLayerActions = ({
   removeLayer,
   isVisible,
   isActive,
+  zIndex,
   toggleVisibility,
   toggleActiveLayer,
   addImage,
   addText,
+  moveToFront,
+  moveToBack,
+  moveAboveDiagram,
+  moveBelowDiagram,
 }: LayersDrawerLayerActionsProps): JSX.Element => {
   const hasPrivilegeToWriteProject = useAppSelector(hasPrivilegeToWriteProjectSelector);
 
@@ -43,6 +54,34 @@ export const LayersDrawerLayerActions = ({
             className="h-auto w-auto bg-transparent p-0"
             onClick={() => toggleActiveLayer(!isActive)}
           />
+          <IconButton
+            title="Move to front"
+            icon="move-front"
+            className="h-auto w-auto bg-transparent p-0"
+            onClick={moveToFront}
+          />
+          <IconButton
+            title="Move to back"
+            icon="move-back"
+            className="h-auto w-auto bg-transparent p-0"
+            onClick={moveToBack}
+          />
+          {zIndex < 0 && (
+            <IconButton
+              title="Move above the diagram"
+              icon="layer-arrow-up"
+              className="h-auto w-auto bg-transparent p-0"
+              onClick={moveAboveDiagram}
+            />
+          )}
+          {zIndex > 0 && (
+            <IconButton
+              title="Move below the diagram"
+              icon="layer-arrow-down"
+              className="h-auto w-auto bg-transparent p-0"
+              onClick={moveBelowDiagram}
+            />
+          )}
           <LayerDrawerLayerContextMenu
             removeLayer={removeLayer}
             editLayer={editLayer}
diff --git a/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectActions.component.tsx b/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectActions.component.tsx
index 4cf6871e..a97189ea 100644
--- a/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectActions.component.tsx
+++ b/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectActions.component.tsx
@@ -2,16 +2,16 @@ import { JSX } from 'react';
 import { IconButton } from '@/shared/IconButton';
 
 interface LayersDrawerObjectActionsProps {
-  bringToFront: () => void;
-  bringToBack: () => void;
+  moveToFront: () => void;
+  moveToBack: () => void;
   removeObject: () => void;
   centerObject: () => void;
   editObject: () => void;
 }
 
 export const LayersDrawerObjectActions = ({
-  bringToFront,
-  bringToBack,
+  moveToFront,
+  moveToBack,
   removeObject,
   centerObject,
   editObject,
@@ -31,16 +31,16 @@ export const LayersDrawerObjectActions = ({
         onClick={editObject}
       />
       <IconButton
-        icon="bring-front"
+        icon="move-front"
         className="h-auto w-auto bg-transparent p-0"
-        title="Bring to front"
-        onClick={bringToFront}
+        title="Move to front"
+        onClick={moveToFront}
       />
       <IconButton
-        icon="bring-back"
+        icon="move-back"
         className="h-auto w-auto bg-transparent p-0"
-        title="Bring to back"
-        onClick={bringToBack}
+        title="Move to back"
+        onClick={moveToBack}
       />
       <IconButton
         icon="trash"
diff --git a/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectsList.component.tsx b/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectsList.component.tsx
index 70a6acf5..9ec19fe4 100644
--- a/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectsList.component.tsx
+++ b/src/components/Map/Drawer/LayersDrawer/LayersDrawerObjectsList.component.tsx
@@ -1,9 +1,9 @@
 /* eslint-disable no-magic-numbers */
 import { useAppSelector } from '@/redux/hooks/useAppSelector';
 import {
-  highestZIndexSelector,
   layerByIdSelector,
-  lowestZIndexSelector,
+  maxObjectZIndexForLayerSelector,
+  minObjectZIndexForLayerSelector,
 } from '@/redux/layers/layers.selectors';
 import { JSX, useState } from 'react';
 import { LayersDrawerImageItem } from '@/components/Map/Drawer/LayersDrawer/LayersDrawerImageItem.component';
@@ -64,8 +64,8 @@ export const LayersDrawerObjectsList = ({
   isLayerActive,
 }: LayersDrawerObjectsListProps): JSX.Element | null => {
   const currentModelId = useAppSelector(mapModelIdSelector);
-  const highestZIndex = useAppSelector(highestZIndexSelector);
-  const lowestZIndex = useAppSelector(lowestZIndexSelector);
+  const maxZIndex = useAppSelector(state => maxObjectZIndexForLayerSelector(state, layerId));
+  const minZIndex = useAppSelector(state => minObjectZIndexForLayerSelector(state, layerId));
   const layer = useAppSelector(state => layerByIdSelector(state, layerId));
   const mapEditToolsLayerImageObject = useAppSelector(mapEditToolsLayerObjectSelector);
   const [removeModalState, setRemoveModalState] = useState<undefined | 'text' | 'image'>(undefined);
@@ -174,12 +174,12 @@ export const LayersDrawerObjectsList = ({
     }
   };
 
-  const bringImageToFront = async (layerImage: LayerImage): Promise<void> => {
-    await updateImageZIndex({ zIndex: highestZIndex + 1, layerImage });
+  const moveImageToFront = async (layerImage: LayerImage): Promise<void> => {
+    await updateImageZIndex({ zIndex: maxZIndex + 1, layerImage });
   };
 
-  const bringImageToBack = async (layerImage: LayerImage): Promise<void> => {
-    await updateImageZIndex({ zIndex: lowestZIndex - 1, layerImage });
+  const moveImageToBack = async (layerImage: LayerImage): Promise<void> => {
+    await updateImageZIndex({ zIndex: minZIndex - 1, layerImage });
   };
 
   const updateTextZIndex = async ({
@@ -210,12 +210,12 @@ export const LayersDrawerObjectsList = ({
     }
   };
 
-  const bringTextToFront = async (layerText: LayerText): Promise<void> => {
-    await updateTextZIndex({ zIndex: highestZIndex + 1, layerText });
+  const moveTextToFront = async (layerText: LayerText): Promise<void> => {
+    await updateTextZIndex({ zIndex: maxZIndex + 1, layerText });
   };
 
-  const bringTextToBack = async (layerText: LayerText): Promise<void> => {
-    await updateTextZIndex({ zIndex: lowestZIndex - 1, layerText });
+  const moveTextToBack = async (layerText: LayerText): Promise<void> => {
+    await updateTextZIndex({ zIndex: minZIndex - 1, layerText });
   };
 
   const centerObject = (layerObject: LayerImage | LayerText): void => {
@@ -257,8 +257,8 @@ export const LayersDrawerObjectsList = ({
         <LayersDrawerTextItem
           layerText={layerText}
           key={layerText.id}
-          bringToFront={() => bringTextToFront(layerText)}
-          bringToBack={() => bringTextToBack(layerText)}
+          moveToFront={() => moveTextToFront(layerText)}
+          moveToBack={() => moveTextToBack(layerText)}
           removeObject={() => removeObject(layerText)}
           centerObject={() => centerObject(layerText)}
           editObject={() => editText()}
@@ -270,8 +270,8 @@ export const LayersDrawerObjectsList = ({
         <LayersDrawerImageItem
           layerImage={layerImage}
           key={layerImage.id}
-          bringToFront={() => bringImageToFront(layerImage)}
-          bringToBack={() => bringImageToBack(layerImage)}
+          moveToFront={() => moveImageToFront(layerImage)}
+          moveToBack={() => moveImageToBack(layerImage)}
           removeObject={() => removeObject(layerImage)}
           centerObject={() => centerObject(layerImage)}
           editObject={() => editImage()}
diff --git a/src/components/Map/MapViewer/utils/config/additionalLayers/useOlMapAdditionalLayers.ts b/src/components/Map/MapViewer/utils/config/additionalLayers/useOlMapAdditionalLayers.ts
index 5e378293..6d41944f 100644
--- a/src/components/Map/MapViewer/utils/config/additionalLayers/useOlMapAdditionalLayers.ts
+++ b/src/components/Map/MapViewer/utils/config/additionalLayers/useOlMapAdditionalLayers.ts
@@ -125,6 +125,7 @@ export const useOlMapAdditionalLayers = (
   const vectorLayers = useMemo(() => {
     return layersState.map(layer => {
       const additionalLayer = new Layer({
+        zIndex: layer.details.z,
         texts: layer.texts,
         rects: layer.rects,
         ovals: layer.ovals,
diff --git a/src/components/Map/MapViewer/utils/config/commentsLayer/useOlMapCommentsLayer.ts b/src/components/Map/MapViewer/utils/config/commentsLayer/useOlMapCommentsLayer.ts
index 7ac3b73b..a3640020 100644
--- a/src/components/Map/MapViewer/utils/config/commentsLayer/useOlMapCommentsLayer.ts
+++ b/src/components/Map/MapViewer/utils/config/commentsLayer/useOlMapCommentsLayer.ts
@@ -36,6 +36,7 @@ export const useOlMapCommentsLayer = (): VectorLayer<VectorSource<Feature<Geomet
 
   return useMemo(() => {
     const vectorLayer = new VectorLayer({
+      zIndex: Infinity,
       source: vectorSource,
     });
     vectorLayer.set('type', LAYER_TYPE.COMMENTS_LAYER);
diff --git a/src/components/Map/MapViewer/utils/config/mapCardLayer/useOlMapCardLayer.ts b/src/components/Map/MapViewer/utils/config/mapCardLayer/useOlMapCardLayer.ts
index 69cec807..db3dbad4 100644
--- a/src/components/Map/MapViewer/utils/config/mapCardLayer/useOlMapCardLayer.ts
+++ b/src/components/Map/MapViewer/utils/config/mapCardLayer/useOlMapCardLayer.ts
@@ -38,6 +38,7 @@ export const useOlMapCardLayer = (): VectorLayer<VectorSource<Feature<Polygon>>>
 
   return useMemo(() => {
     const vectorLayer = new VectorLayer({
+      zIndex: -Infinity,
       source: vectorSource,
       style: new Style({
         fill: new Fill({
diff --git a/src/components/Map/MapViewer/utils/config/pinsLayer/useOlMapPinsLayer.ts b/src/components/Map/MapViewer/utils/config/pinsLayer/useOlMapPinsLayer.ts
index f7b6001c..4cd5a32b 100644
--- a/src/components/Map/MapViewer/utils/config/pinsLayer/useOlMapPinsLayer.ts
+++ b/src/components/Map/MapViewer/utils/config/pinsLayer/useOlMapPinsLayer.ts
@@ -77,6 +77,7 @@ export const useOlMapPinsLayer = (): VectorLayer<VectorSource<Feature<Geometry>>
 
   return useMemo(() => {
     const vectorLayer = new VectorLayer({
+      zIndex: Infinity,
       source: vectorSource,
     });
     vectorLayer.set('type', LAYER_TYPE.PINS_LAYER);
diff --git a/src/components/Map/MapViewer/utils/config/processLayer/useOlMapProcessLayer.ts b/src/components/Map/MapViewer/utils/config/processLayer/useOlMapProcessLayer.ts
index 2811ec30..98cb6e1e 100644
--- a/src/components/Map/MapViewer/utils/config/processLayer/useOlMapProcessLayer.ts
+++ b/src/components/Map/MapViewer/utils/config/processLayer/useOlMapProcessLayer.ts
@@ -274,6 +274,7 @@ export const useOlMapProcessLayer = ({
 
   return useMemo(() => {
     const vectorLayer = new VectorLayer({
+      zIndex: 0,
       source: vectorSource,
       updateWhileAnimating: true,
       updateWhileInteracting: true,
diff --git a/src/components/Map/MapViewer/utils/config/reactionsLayer/useOlMapReactionsLayer.ts b/src/components/Map/MapViewer/utils/config/reactionsLayer/useOlMapReactionsLayer.ts
index bfb2668e..df526271 100644
--- a/src/components/Map/MapViewer/utils/config/reactionsLayer/useOlMapReactionsLayer.ts
+++ b/src/components/Map/MapViewer/utils/config/reactionsLayer/useOlMapReactionsLayer.ts
@@ -63,6 +63,7 @@ export const useOlMapReactionsLayer = (): VectorLayer<VectorSource<Feature<Geome
 
   return useMemo(() => {
     const vectorLayer = new VectorLayer({
+      zIndex: Infinity,
       source: vectorSource,
       style: new Style({
         fill: new Fill({ color: LINE_COLOR }),
diff --git a/src/components/Map/MapViewer/utils/shapes/layer/Layer.test.ts b/src/components/Map/MapViewer/utils/shapes/layer/Layer.test.ts
index 7b8bb971..10349c6d 100644
--- a/src/components/Map/MapViewer/utils/shapes/layer/Layer.test.ts
+++ b/src/components/Map/MapViewer/utils/shapes/layer/Layer.test.ts
@@ -133,6 +133,7 @@ describe('Layer', () => {
       pointToProjection: jest.fn(point => [point.x, point.y]),
       mapInstance,
       mapSize,
+      zIndex: 1,
       lineTypes: {},
       arrowTypes: {},
     };
diff --git a/src/components/Map/MapViewer/utils/shapes/layer/Layer.ts b/src/components/Map/MapViewer/utils/shapes/layer/Layer.ts
index 7f697a72..14d5f8b5 100644
--- a/src/components/Map/MapViewer/utils/shapes/layer/Layer.ts
+++ b/src/components/Map/MapViewer/utils/shapes/layer/Layer.ts
@@ -34,6 +34,7 @@ import LayerText from '@/components/Map/MapViewer/utils/shapes/layer/elements/La
 import LayerImage from '@/components/Map/MapViewer/utils/shapes/layer/elements/LayerImage';
 
 export interface LayerProps {
+  zIndex: number;
   texts: { [key: string]: LayerTextModel };
   rects: Array<LayerRect>;
   ovals: Array<LayerOval>;
@@ -78,6 +79,7 @@ export default class Layer {
   >;
 
   constructor({
+    zIndex,
     texts,
     rects,
     ovals,
@@ -118,6 +120,7 @@ export default class Layer {
     this.vectorSource.addFeatures(arrowsFeatures);
 
     this.vectorLayer = new VectorLayer({
+      zIndex,
       source: this.vectorSource,
       visible,
       updateWhileAnimating: true,
diff --git a/src/models/layerSchema.ts b/src/models/layerSchema.ts
index 380146a7..11fcd88d 100644
--- a/src/models/layerSchema.ts
+++ b/src/models/layerSchema.ts
@@ -5,4 +5,5 @@ export const layerSchema = z.object({
   name: z.string(),
   visible: z.boolean(),
   locked: z.boolean(),
+  z: z.number(),
 });
diff --git a/src/redux/layers/layers.reducers.test.ts b/src/redux/layers/layers.reducers.test.ts
index 7bcb10ba..d93fb4f8 100644
--- a/src/redux/layers/layers.reducers.test.ts
+++ b/src/redux/layers/layers.reducers.test.ts
@@ -92,7 +92,7 @@ describe('layers reducer', () => {
 
     const { type } = await store.dispatch(getLayersForModel(1));
     const { data, loading, error } = store.getState().layers[1];
-    expect(type).toBe('vectorMap/getLayers/fulfilled');
+    expect(type).toBe('layers/getLayers/fulfilled');
     expect(loading).toEqual('succeeded');
     expect(error).toEqual({ message: '', name: '' });
     expect(data).toEqual({
@@ -120,7 +120,7 @@ describe('layers reducer', () => {
     const action = await store.dispatch(getLayersForModel(1));
     const { data, loading, error } = store.getState().layers[1];
 
-    expect(action.type).toBe('vectorMap/getLayers/rejected');
+    expect(action.type).toBe('layers/getLayers/rejected');
     expect(() => unwrapResult(action)).toThrow(
       "Failed to fetch layers: The page you're looking for doesn't exist. Please verify the URL and try again.",
     );
diff --git a/src/redux/layers/layers.selectors.ts b/src/redux/layers/layers.selectors.ts
index 8f016c8a..8123fa00 100644
--- a/src/redux/layers/layers.selectors.ts
+++ b/src/redux/layers/layers.selectors.ts
@@ -2,6 +2,7 @@
 import { createSelector } from '@reduxjs/toolkit';
 import { rootSelector } from '@/redux/root/root.selectors';
 import { currentModelIdSelector } from '@/redux/models/models.selectors';
+import { LayerState } from '@/redux/layers/layers.types';
 
 export const layersSelector = createSelector(rootSelector, state => state.layers);
 
@@ -18,7 +19,7 @@ export const layersActiveLayersSelector = createSelector(
 
 export const layersDrawLayerSelector = createSelector(
   layersStateForCurrentModelSelector,
-  state => state?.data?.drawLayer,
+  state => state?.data?.drawLayer || null,
 );
 
 export const layerByIdSelector = createSelector(
@@ -41,40 +42,112 @@ export const layersForCurrentModelSelector = createSelector(
   state => state?.data?.layers || [],
 );
 
-export const highestZIndexSelector = createSelector(layersForCurrentModelSelector, layers => {
-  if (!layers || layers.length === 0) return 0;
-
-  const getMaxZFromItems = <T extends { z?: number }>(items: T[] = []): number =>
-    items.length > 0 ? Math.max(...items.map(item => item.z || 0)) : 0;
-
-  return layers.reduce((maxZ, layer) => {
-    const textsMaxZ = getMaxZFromItems(Object.values(layer.texts));
-    const rectsMaxZ = getMaxZFromItems(layer.rects);
-    const ovalsMaxZ = getMaxZFromItems(layer.ovals);
-    const linesMaxZ = getMaxZFromItems(layer.lines);
-    const imagesMaxZ = getMaxZFromItems(Object.values(layer.images));
-
-    const layerMaxZ = Math.max(textsMaxZ, rectsMaxZ, ovalsMaxZ, linesMaxZ, imagesMaxZ);
-
-    return Math.max(maxZ, layerMaxZ);
-  }, 0);
-});
+export const maxLayerZIndexAboveDiagramSelector = createSelector(
+  layersForCurrentModelSelector,
+  layers => {
+    if (!layers || layers.length === 0) {
+      return 1000;
+    }
+    let maxZIndex = -Infinity;
+    layers.forEach((layer: LayerState) => {
+      if (layer.details.z > 0 && layer.details.z > maxZIndex) {
+        maxZIndex = layer.details.z;
+      }
+    });
+    return maxZIndex;
+  },
+);
 
-export const lowestZIndexSelector = createSelector(layersForCurrentModelSelector, layers => {
-  if (!layers || layers.length === 0) return 0;
+export const maxLayerZIndexBelowDiagramSelector = createSelector(
+  layersForCurrentModelSelector,
+  layers => {
+    if (!layers || layers.length === 0) {
+      return -1000;
+    }
+    let maxZIndex = -Infinity;
+    layers.forEach((layer: LayerState) => {
+      if (layer.details.z < 0 && layer.details.z > maxZIndex) {
+        maxZIndex = layer.details.z;
+      }
+    });
+    return maxZIndex;
+  },
+);
 
-  const getMinZFromItems = <T extends { z?: number }>(items: T[] = []): number =>
-    items.length > 0 ? Math.min(...items.map(item => item.z || 0)) : 0;
+export const minLayerZIndexAboveDiagramSelector = createSelector(
+  layersForCurrentModelSelector,
+  layers => {
+    if (!layers || layers.length === 0) {
+      return 1000;
+    }
+    let minZIndex = Infinity;
+    layers.forEach((layer: LayerState) => {
+      if (layer.details.z > 0 && layer.details.z < minZIndex) {
+        minZIndex = layer.details.z;
+      }
+    });
+    return minZIndex;
+  },
+);
 
-  return layers.reduce((minZ, layer) => {
-    const textsMinZ = getMinZFromItems(Object.values(layer.texts));
-    const rectsMinZ = getMinZFromItems(layer.rects);
-    const ovalsMinZ = getMinZFromItems(layer.ovals);
-    const linesMinZ = getMinZFromItems(layer.lines);
-    const imagesMinZ = getMinZFromItems(Object.values(layer.images));
+export const minLayerZIndexBelowDiagramSelector = createSelector(
+  layersForCurrentModelSelector,
+  layers => {
+    if (!layers || layers.length === 0) {
+      return -1000;
+    }
+    let minZIndex = Infinity;
+    layers.forEach((layer: LayerState) => {
+      if (layer.details.z < 0 && layer.details.z < minZIndex) {
+        minZIndex = layer.details.z;
+      }
+    });
+    return minZIndex;
+  },
+);
 
-    const layerMinZ = Math.min(textsMinZ, rectsMinZ, ovalsMinZ, linesMinZ, imagesMinZ);
+export const maxObjectZIndexForLayerSelector = createSelector(
+  [layersForCurrentModelSelector, (_state, layerId: number | null): number | null => layerId],
+  (layers, layerId) => {
+    if (!layers || layers.length === 0 || !layerId) {
+      return 0;
+    }
+    const foundLayer = layers.find(layer => layer.details.id === layerId);
+    if (!foundLayer) {
+      return 0;
+    }
+    const getMaxZFromItems = <T extends { z?: number }>(items: T[] = []): number =>
+      items.length > 0 ? Math.max(...items.map(item => item.z || 0)) : 0;
+
+    const textsMaxZ = getMaxZFromItems(Object.values(foundLayer.texts));
+    const rectsMaxZ = getMaxZFromItems(foundLayer.rects);
+    const ovalsMaxZ = getMaxZFromItems(foundLayer.ovals);
+    const linesMaxZ = getMaxZFromItems(foundLayer.lines);
+    const imagesMaxZ = getMaxZFromItems(Object.values(foundLayer.images));
+
+    return Math.max(textsMaxZ, rectsMaxZ, ovalsMaxZ, linesMaxZ, imagesMaxZ);
+  },
+);
 
-    return Math.min(minZ, layerMinZ);
-  }, 0);
-});
+export const minObjectZIndexForLayerSelector = createSelector(
+  [layersForCurrentModelSelector, (_state, layerId: number | null): number | null => layerId],
+  (layers, layerId) => {
+    if (!layers || layers.length === 0 || !layerId) {
+      return 0;
+    }
+    const foundLayer = layers.find(layer => layer.details.id === layerId);
+    if (!foundLayer) {
+      return 0;
+    }
+    const getMinZFromItems = <T extends { z?: number }>(items: T[] = []): number =>
+      items.length > 0 ? Math.min(...items.map(item => item.z || 0)) : 0;
+
+    const textsMinZ = getMinZFromItems(Object.values(foundLayer.texts));
+    const rectsMinZ = getMinZFromItems(foundLayer.rects);
+    const ovalsMinZ = getMinZFromItems(foundLayer.ovals);
+    const linesMinZ = getMinZFromItems(foundLayer.lines);
+    const imagesMinZ = getMinZFromItems(Object.values(foundLayer.images));
+
+    return Math.min(textsMinZ, rectsMinZ, ovalsMinZ, linesMinZ, imagesMinZ);
+  },
+);
diff --git a/src/redux/layers/layers.thunks.test.ts b/src/redux/layers/layers.thunks.test.ts
index 77e10bdb..09028272 100644
--- a/src/redux/layers/layers.thunks.test.ts
+++ b/src/redux/layers/layers.thunks.test.ts
@@ -111,7 +111,13 @@ describe('layers thunks', () => {
       mockedAxiosClient.onPost(apiPath.storeLayer(1)).reply(HttpStatusCode.Created, layerFixture);
 
       const { payload } = await store.dispatch(
-        addLayerForModel({ name: 'New Layer', visible: true, locked: false, modelId: 1 }),
+        addLayerForModel({
+          name: 'New Layer',
+          visible: true,
+          locked: false,
+          modelId: 1,
+          zIndex: 1,
+        }),
       );
       expect(payload).toEqual(layerFixture);
     });
@@ -122,7 +128,13 @@ describe('layers thunks', () => {
         .reply(HttpStatusCode.Created, { invalid: 'data' });
 
       const { payload } = await store.dispatch(
-        addLayerForModel({ name: 'New Layer', visible: true, locked: false, modelId: 1 }),
+        addLayerForModel({
+          name: 'New Layer',
+          visible: true,
+          locked: false,
+          modelId: 1,
+          zIndex: 1,
+        }),
       );
       expect(payload).toBeNull();
     });
@@ -139,6 +151,7 @@ describe('layers thunks', () => {
           locked: true,
           modelId: 1,
           layerId: 2,
+          zIndex: 1,
         }),
       );
       expect(payload).toEqual(layerFixture);
@@ -156,6 +169,7 @@ describe('layers thunks', () => {
           locked: true,
           modelId: 1,
           layerId: 2,
+          zIndex: 1,
         }),
       );
       expect(payload).toBeNull();
diff --git a/src/redux/layers/layers.thunks.ts b/src/redux/layers/layers.thunks.ts
index 66035fd8..bda72fce 100644
--- a/src/redux/layers/layers.thunks.ts
+++ b/src/redux/layers/layers.thunks.ts
@@ -32,7 +32,7 @@ export const getLayer = createAsyncThunk<
   Layer | null,
   { modelId: number; layerId: number },
   ThunkConfig
->('vectorMap/getLayer', async ({ modelId, layerId }) => {
+>('layers/getLayer', async ({ modelId, layerId }) => {
   try {
     const { data } = await axiosInstanceNewAPI.get<Layer>(apiPath.getLayer(modelId, layerId));
 
@@ -48,7 +48,7 @@ export const getLayersForModel = createAsyncThunk<
   LayersVisibilitiesState | undefined,
   number,
   ThunkConfig
->('vectorMap/getLayers', async (modelId: number) => {
+>('layers/getLayers', async (modelId: number) => {
   try {
     const { data } = await axiosInstanceNewAPI.get<Layers>(apiPath.getLayers(modelId));
     const isDataValid = validateDataUsingZodSchema(data, pageableSchema(layerSchema));
@@ -103,13 +103,14 @@ export const getLayersForModel = createAsyncThunk<
 });
 
 export const addLayerForModel = createAsyncThunk<Layer | null, LayerStoreInterface, ThunkConfig>(
-  'vectorMap/addLayer',
-  async ({ name, visible, locked, modelId }) => {
+  'layers/addLayer',
+  async ({ name, visible, locked, modelId, zIndex }) => {
     try {
       const { data } = await axiosInstanceNewAPI.post<Layer>(apiPath.storeLayer(modelId), {
         name,
         visible,
         locked,
+        z: zIndex,
       });
 
       const isDataValid = validateDataUsingZodSchema(data, layerSchema);
@@ -122,13 +123,14 @@ export const addLayerForModel = createAsyncThunk<Layer | null, LayerStoreInterfa
 );
 
 export const updateLayer = createAsyncThunk<Layer | null, LayerUpdateInterface, ThunkConfig>(
-  'vectorMap/updateLayer',
-  async ({ name, visible, locked, modelId, layerId }) => {
+  'layers/updateLayer',
+  async ({ name, visible, locked, modelId, layerId, zIndex }) => {
     try {
       const { data } = await axiosInstanceNewAPI.put<Layer>(apiPath.updateLayer(modelId, layerId), {
         name,
         visible,
         locked,
+        z: zIndex,
       });
 
       const isDataValid = validateDataUsingZodSchema(data, layerSchema);
@@ -144,7 +146,7 @@ export const removeLayer = createAsyncThunk<
   null,
   { modelId: number; layerId: number },
   ThunkConfig
->('vectorMap/removeLayer', async ({ modelId, layerId }) => {
+>('layers/removeLayer', async ({ modelId, layerId }) => {
   try {
     await axiosInstanceNewAPI.delete<void>(apiPath.removeLayer(modelId, layerId));
     return null;
@@ -161,7 +163,7 @@ export const getLayerImage = createAsyncThunk<
     imageId: number;
   },
   ThunkConfig
->('vectorMap/getLayerImage', async ({ modelId, layerId, imageId }) => {
+>('layers/getLayerImage', async ({ modelId, layerId, imageId }) => {
   try {
     const { data } = await axiosInstanceNewAPI.get<LayerImage>(
       apiPath.getLayerImageObject(modelId, layerId, imageId),
@@ -187,7 +189,7 @@ export const addLayerImageObject = createAsyncThunk<
     glyph: number | null;
   },
   ThunkConfig
->('vectorMap/addLayerImageObject', async ({ modelId, layerId, x, y, z, width, height, glyph }) => {
+>('layers/addLayerImageObject', async ({ modelId, layerId, x, y, z, width, height, glyph }) => {
   try {
     const { data } = await axiosInstanceNewAPI.post<LayerImage>(
       apiPath.addLayerImageObject(modelId, layerId),
@@ -223,7 +225,7 @@ export const updateLayerImageObject = createAsyncThunk<
   },
   ThunkConfig
 >(
-  'vectorMap/updateLayerImageObject',
+  'layers/updateLayerImageObject',
   async ({ modelId, layerId, id, x, y, z, width, height, glyph }) => {
     try {
       const { data } = await axiosInstanceNewAPI.put<LayerImage>(
@@ -252,7 +254,7 @@ export const removeLayerImage = createAsyncThunk<
   null,
   { modelId: number; layerId: number; imageId: number },
   ThunkConfig
->('vectorMap/removeLayerImage', async ({ modelId, layerId, imageId }) => {
+>('layers/removeLayerImage', async ({ modelId, layerId, imageId }) => {
   try {
     await axiosInstanceNewAPI.delete<void>(
       apiPath.removeLayerImageObject(modelId, layerId, imageId),
@@ -273,7 +275,7 @@ export const addLayerText = createAsyncThunk<
     textData: LayerTextFactoryForm;
   },
   ThunkConfig
->('vectorMap/addLayerText', async ({ modelId, layerId, z, boundingBox, textData }) => {
+>('layers/addLayerText', async ({ modelId, layerId, z, boundingBox, textData }) => {
   try {
     const { data } = await axiosInstanceNewAPI.post<LayerText>(
       apiPath.addLayerText(modelId, layerId),
@@ -299,7 +301,7 @@ export const getLayerText = createAsyncThunk<
     textId: number;
   },
   ThunkConfig
->('vectorMap/getLayerText', async ({ modelId, layerId, textId }) => {
+>('layers/getLayerText', async ({ modelId, layerId, textId }) => {
   try {
     const { data } = await axiosInstanceNewAPI.get<LayerText>(
       apiPath.getLayerText(modelId, layerId, textId),
diff --git a/src/redux/layers/layers.types.ts b/src/redux/layers/layers.types.ts
index 60e42717..05b4636e 100644
--- a/src/redux/layers/layers.types.ts
+++ b/src/redux/layers/layers.types.ts
@@ -6,6 +6,7 @@ export interface LayerStoreInterface {
   visible: boolean;
   locked: boolean;
   modelId: number;
+  zIndex: number;
 }
 
 export interface LayerUpdateInterface {
@@ -14,6 +15,7 @@ export interface LayerUpdateInterface {
   visible: boolean;
   locked: boolean;
   modelId: number;
+  zIndex: number;
 }
 
 export type LayerState = {
diff --git a/src/shared/Icon/Icon.component.tsx b/src/shared/Icon/Icon.component.tsx
index 5745b6ec..aed961c3 100644
--- a/src/shared/Icon/Icon.component.tsx
+++ b/src/shared/Icon/Icon.component.tsx
@@ -31,8 +31,10 @@ import { PadlockOpenIcon } from '@/shared/Icon/Icons/PadlockOpenIcon';
 import { PadlockLockedIcon } from '@/shared/Icon/Icons/PadlockLockedIcon';
 import { CrossedEyeIcon } from '@/shared/Icon/Icons/CrossedEyeIcon';
 import { CenterIcon } from '@/shared/Icon/Icons/CenterIcon';
-import { BringFrontIcon } from '@/shared/Icon/Icons/BringFrontIcon';
-import { BringBackIcon } from '@/shared/Icon/Icons/BringBackIcon';
+import { MoveFrontIcon } from '@/shared/Icon/Icons/MoveFrontIcon';
+import { MoveBackIcon } from '@/shared/Icon/Icons/MoveBackIcon';
+import { LayerArrowUpIcon } from '@/shared/Icon/Icons/LayerArrowUpIcon';
+import { LayerArrowDownIcon } from '@/shared/Icon/Icons/LayerArrowDownIcon';
 import { LocationIcon } from './Icons/LocationIcon';
 import { MaginfierZoomInIcon } from './Icons/MagnifierZoomIn';
 import { MaginfierZoomOutIcon } from './Icons/MagnifierZoomOut';
@@ -87,8 +89,10 @@ const icons: Record<IconTypes, IconComponentType> = {
   'padlock-open': PadlockOpenIcon,
   'padlock-locked': PadlockLockedIcon,
   center: CenterIcon,
-  'bring-front': BringFrontIcon,
-  'bring-back': BringBackIcon,
+  'move-front': MoveFrontIcon,
+  'move-back': MoveBackIcon,
+  'layer-arrow-up': LayerArrowUpIcon,
+  'layer-arrow-down': LayerArrowDownIcon,
 } as const;
 
 export const Icon = ({ name, className = '', ...rest }: IconProps): JSX.Element => {
diff --git a/src/shared/Icon/Icons/ArrowDoubleDownIcon.tsx b/src/shared/Icon/Icons/ArrowDoubleDownIcon.tsx
index d7ab4e38..cf5ce5f7 100644
--- a/src/shared/Icon/Icons/ArrowDoubleDownIcon.tsx
+++ b/src/shared/Icon/Icons/ArrowDoubleDownIcon.tsx
@@ -13,26 +13,16 @@ export const ArrowDoubleDownIcon = ({ className }: ArrowDoubleDownIconProps): JS
   >
     <path
       d="M8 8L8 18M8 18L5 15M8 18L11 15"
-      stroke="currentColor"
       strokeWidth="1.5"
       strokeLinecap="round"
       strokeLinejoin="round"
     />
     <path
       d="M16 8L16 18M16 18L13 15M16 18L19 15"
-      stroke="currentColor"
       strokeWidth="1.5"
       strokeLinecap="round"
       strokeLinejoin="round"
     />
-    <line
-      x1="4"
-      y1="6"
-      x2="20"
-      y2="6"
-      stroke="currentColor"
-      strokeWidth="1.5"
-      strokeLinecap="round"
-    />
+    <line x1="4" y1="6" x2="20" y2="6" strokeWidth="1.5" strokeLinecap="round" />
   </svg>
 );
diff --git a/src/shared/Icon/Icons/ArrowDoubleUpIcon.tsx b/src/shared/Icon/Icons/ArrowDoubleUpIcon.tsx
index ed51a602..861773cd 100644
--- a/src/shared/Icon/Icons/ArrowDoubleUpIcon.tsx
+++ b/src/shared/Icon/Icons/ArrowDoubleUpIcon.tsx
@@ -13,26 +13,16 @@ export const ArrowDoubleUpIcon = ({ className }: ArrowDoubleUpIconProps): JSX.El
   >
     <path
       d="M8 16L8 6M8 6L5 9M8 6L11 9"
-      stroke="currentColor"
       strokeWidth="1.5"
       strokeLinecap="round"
       strokeLinejoin="round"
     />
     <path
       d="M16 16L16 6M16 6L13 9M16 6L19 9"
-      stroke="currentColor"
       strokeWidth="1.5"
       strokeLinecap="round"
       strokeLinejoin="round"
     />
-    <line
-      x1="4"
-      y1="18"
-      x2="20"
-      y2="18"
-      stroke="currentColor"
-      strokeWidth="1.5"
-      strokeLinecap="round"
-    />
+    <line x1="4" y1="18" x2="20" y2="18" strokeWidth="1.5" strokeLinecap="round" />
   </svg>
 );
diff --git a/src/shared/Icon/Icons/LayerArrowDownIcon.tsx b/src/shared/Icon/Icons/LayerArrowDownIcon.tsx
new file mode 100644
index 00000000..71223a31
--- /dev/null
+++ b/src/shared/Icon/Icons/LayerArrowDownIcon.tsx
@@ -0,0 +1,18 @@
+interface LayerArrowDownIconProps {
+  className?: string;
+}
+
+export const LayerArrowDownIcon = ({ className }: LayerArrowDownIconProps): JSX.Element => (
+  <svg
+    width="20"
+    height="20"
+    viewBox="2 3 20 17"
+    fill="none"
+    xmlns="http://www.w3.org/2000/svg"
+    className={className}
+  >
+    <path d="M12 21L7 16H10V10H14V16H17L12 21Z" />
+    <rect x="4" y="3" width="16" height="2" />
+    <rect x="4" y="7" width="16" height="2" />
+  </svg>
+);
diff --git a/src/shared/Icon/Icons/LayerArrowUpIcon.tsx b/src/shared/Icon/Icons/LayerArrowUpIcon.tsx
new file mode 100644
index 00000000..bbcf233f
--- /dev/null
+++ b/src/shared/Icon/Icons/LayerArrowUpIcon.tsx
@@ -0,0 +1,18 @@
+interface LayerArrowUpIconProps {
+  className?: string;
+}
+
+export const LayerArrowUpIcon = ({ className }: LayerArrowUpIconProps): JSX.Element => (
+  <svg
+    width="20"
+    height="20"
+    viewBox="2 3 20 19"
+    fill="none"
+    xmlns="http://www.w3.org/2000/svg"
+    className={className}
+  >
+    <path d="M12 3L7 8H10V14H14V8H17L12 3Z" />
+    <rect x="4" y="16" width="16" height="2" />
+    <rect x="4" y="20" width="16" height="2" />
+  </svg>
+);
diff --git a/src/shared/Icon/Icons/BringBackIcon.tsx b/src/shared/Icon/Icons/MoveBackIcon.tsx
similarity index 78%
rename from src/shared/Icon/Icons/BringBackIcon.tsx
rename to src/shared/Icon/Icons/MoveBackIcon.tsx
index d086ac9b..734bd201 100644
--- a/src/shared/Icon/Icons/BringBackIcon.tsx
+++ b/src/shared/Icon/Icons/MoveBackIcon.tsx
@@ -1,8 +1,8 @@
-interface BringBackIconProps {
+interface MoveBackIconProps {
   className?: string;
 }
 
-export const BringBackIcon = ({ className }: BringBackIconProps): JSX.Element => (
+export const MoveBackIcon = ({ className }: MoveBackIconProps): JSX.Element => (
   <svg
     width="20"
     height="20"
@@ -23,6 +23,6 @@ export const BringBackIcon = ({ className }: BringBackIconProps): JSX.Element =>
       stroke="white"
       fill="none"
     />
-    <rect x="4" y="4" width="64" height="64" rx="10" ry="10" strokeWidth="8" fill="black" />
+    <rect x="4" y="4" width="64" height="64" rx="10" ry="10" strokeWidth="8" />
   </svg>
 );
diff --git a/src/shared/Icon/Icons/BringFrontIcon.tsx b/src/shared/Icon/Icons/MoveFrontIcon.tsx
similarity index 77%
rename from src/shared/Icon/Icons/BringFrontIcon.tsx
rename to src/shared/Icon/Icons/MoveFrontIcon.tsx
index e5aa5017..037f5cb3 100644
--- a/src/shared/Icon/Icons/BringFrontIcon.tsx
+++ b/src/shared/Icon/Icons/MoveFrontIcon.tsx
@@ -1,8 +1,8 @@
-interface BringFrontIconProps {
+interface MoveFrontIconProps {
   className?: string;
 }
 
-export const BringFrontIcon = ({ className }: BringFrontIconProps): JSX.Element => (
+export const MoveFrontIcon = ({ className }: MoveFrontIconProps): JSX.Element => (
   <svg
     width="20"
     height="20"
@@ -11,7 +11,7 @@ export const BringFrontIcon = ({ className }: BringFrontIconProps): JSX.Element
     fill="none"
     className={className}
   >
-    <rect x="4" y="4" width="64" height="64" rx="10" ry="10" strokeWidth="8" fill="black" />
+    <rect x="4" y="4" width="64" height="64" rx="10" ry="10" strokeWidth="8" />
     <rect
       x="30"
       y="30"
diff --git a/src/shared/IconButton/IconButton.component.tsx b/src/shared/IconButton/IconButton.component.tsx
index 1330e460..e71c6211 100644
--- a/src/shared/IconButton/IconButton.component.tsx
+++ b/src/shared/IconButton/IconButton.component.tsx
@@ -29,8 +29,8 @@ export const IconButton = ({
 
   const isStrokeIcon = [
     'plugin',
-    'bring-back',
-    'bring-front',
+    'move-back',
+    'move-front',
     'center',
     'eye',
     'crossed-eye',
@@ -38,6 +38,8 @@ export const IconButton = ({
     'padlock-locked',
     'layers',
     'edit',
+    'arrow-double-up',
+    'arrow-double-down',
   ].includes(icon);
 
   return (
@@ -57,6 +59,8 @@ export const IconButton = ({
           isStrokeIcon
             ? 'stroke-font-400 group-hover:stroke-primary-500 group-active:stroke-primary-500'
             : 'fill-font-400 group-hover:fill-primary-500 group-active:fill-primary-500',
+          ['move-back', 'move-front'].includes(icon) &&
+            'fill-font-400 stroke-font-400 group-hover:fill-primary-500 group-hover:stroke-primary-500 group-active:fill-primary-500 group-active:stroke-primary-500',
           isActive && getActiveFillOrStrokeColor(icon),
           classNameIcon,
         )}
diff --git a/src/types/iconTypes.ts b/src/types/iconTypes.ts
index 0d74dd78..0083a622 100644
--- a/src/types/iconTypes.ts
+++ b/src/types/iconTypes.ts
@@ -38,7 +38,9 @@ export type IconTypes =
   | 'padlock-open'
   | 'padlock-locked'
   | 'center'
-  | 'bring-front'
-  | 'bring-back';
+  | 'move-front'
+  | 'move-back'
+  | 'layer-arrow-up'
+  | 'layer-arrow-down';
 
 export type IconComponentType = ({ className }: { className: string }) => JSX.Element;
-- 
GitLab


From 55a29206777f4d2a37fea8821a3796f70a25c2d0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mi=C5=82osz=20Grocholewski?= <m.grocholewski@atcomp.pl>
Date: Tue, 18 Feb 2025 10:49:03 +0100
Subject: [PATCH 7/8] feat(layers): fetch layers after updating layer z index

---
 .../Map/Drawer/LayersDrawer/LayersDrawerLayer.component.tsx      | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayer.component.tsx b/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayer.component.tsx
index 8b0f9b01..53dd8d14 100644
--- a/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayer.component.tsx
+++ b/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayer.component.tsx
@@ -114,6 +114,7 @@ export const LayersDrawerLayer = ({ layerDetails }: LayersDrawerLayerProps): JSX
           zIndex,
         }),
       );
+      dispatch(getLayersForModel(currentModelId));
     } catch (error) {
       const typedError = error as SerializedError;
       showToast({
-- 
GitLab


From 70547634bee979c09b32b33d6e222d05da58b4f6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mi=C5=82osz=20Grocholewski?= <m.grocholewski@atcomp.pl>
Date: Wed, 19 Feb 2025 13:58:12 +0100
Subject: [PATCH 8/8] fix(layers): correct min/max zIndex selectors

---
 .../LayersDrawerLayer.component.tsx           | 16 ++++++-------
 src/redux/layers/layers.selectors.ts          | 24 +++++++++++--------
 2 files changed, 22 insertions(+), 18 deletions(-)

diff --git a/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayer.component.tsx b/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayer.component.tsx
index 53dd8d14..93e12281 100644
--- a/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayer.component.tsx
+++ b/src/components/Map/Drawer/LayersDrawer/LayersDrawerLayer.component.tsx
@@ -104,7 +104,7 @@ export const LayersDrawerLayer = ({ layerDetails }: LayersDrawerLayerProps): JSX
 
   const updateLayerZIndex = async (zIndex: number): Promise<void> => {
     try {
-      dispatch(
+      await dispatch(
         updateLayer({
           name: layerDetails.name,
           visible: layerDetails.visible,
@@ -114,7 +114,7 @@ export const LayersDrawerLayer = ({ layerDetails }: LayersDrawerLayerProps): JSX
           zIndex,
         }),
       );
-      dispatch(getLayersForModel(currentModelId));
+      await dispatch(getLayersForModel(currentModelId));
     } catch (error) {
       const typedError = error as SerializedError;
       showToast({
@@ -126,29 +126,29 @@ export const LayersDrawerLayer = ({ layerDetails }: LayersDrawerLayerProps): JSX
 
   const moveToFront = (): void => {
     if (layerDetails.z > 0) {
-      updateLayerZIndex(maxLayerZIndexAboveDiagram);
+      updateLayerZIndex(maxLayerZIndexAboveDiagram + 1);
     } else if (layerDetails.z < 0) {
-      const zIndex = Math.min(maxLayerZIndexBelowDiagram, -1);
+      const zIndex = Math.min(maxLayerZIndexBelowDiagram + 1, -1);
       updateLayerZIndex(zIndex);
     }
   };
 
   const moveToBack = (): void => {
     if (layerDetails.z > 0) {
-      const zIndex = Math.max(minLayerZIndexAboveDiagram, 1);
+      const zIndex = Math.max(minLayerZIndexAboveDiagram - 1, 1);
       updateLayerZIndex(zIndex);
     } else if (layerDetails.z < 0) {
-      updateLayerZIndex(minLayerZIndexBelowDiagram);
+      updateLayerZIndex(minLayerZIndexBelowDiagram - 1);
     }
   };
 
   const moveAboveDiagram = (): void => {
-    const zIndex = Math.max(minLayerZIndexAboveDiagram - 1, 1);
+    const zIndex = Math.max(maxLayerZIndexAboveDiagram + 1, 1);
     updateLayerZIndex(zIndex);
   };
 
   const moveBelowDiagram = (): void => {
-    const zIndex = Math.min(minLayerZIndexBelowDiagram + 1, -1);
+    const zIndex = Math.min(minLayerZIndexBelowDiagram - 1, -1);
     updateLayerZIndex(zIndex);
   };
 
diff --git a/src/redux/layers/layers.selectors.ts b/src/redux/layers/layers.selectors.ts
index 8123fa00..37eee222 100644
--- a/src/redux/layers/layers.selectors.ts
+++ b/src/redux/layers/layers.selectors.ts
@@ -45,11 +45,12 @@ export const layersForCurrentModelSelector = createSelector(
 export const maxLayerZIndexAboveDiagramSelector = createSelector(
   layersForCurrentModelSelector,
   layers => {
-    if (!layers || layers.length === 0) {
-      return 1000;
+    const layersAboveDiagram = layers.filter(layer => layer.details.z > 0);
+    if (layersAboveDiagram.length === 0) {
+      return -1000;
     }
     let maxZIndex = -Infinity;
-    layers.forEach((layer: LayerState) => {
+    layersAboveDiagram.forEach((layer: LayerState) => {
       if (layer.details.z > 0 && layer.details.z > maxZIndex) {
         maxZIndex = layer.details.z;
       }
@@ -61,11 +62,12 @@ export const maxLayerZIndexAboveDiagramSelector = createSelector(
 export const maxLayerZIndexBelowDiagramSelector = createSelector(
   layersForCurrentModelSelector,
   layers => {
-    if (!layers || layers.length === 0) {
+    const layerBelowDiagram = layers.filter(layer => layer.details.z < 0);
+    if (layerBelowDiagram.length === 0) {
       return -1000;
     }
     let maxZIndex = -Infinity;
-    layers.forEach((layer: LayerState) => {
+    layerBelowDiagram.forEach((layer: LayerState) => {
       if (layer.details.z < 0 && layer.details.z > maxZIndex) {
         maxZIndex = layer.details.z;
       }
@@ -77,11 +79,12 @@ export const maxLayerZIndexBelowDiagramSelector = createSelector(
 export const minLayerZIndexAboveDiagramSelector = createSelector(
   layersForCurrentModelSelector,
   layers => {
-    if (!layers || layers.length === 0) {
-      return 1000;
+    const layersAboveDiagram = layers.filter(layer => layer.details.z > 0);
+    if (layersAboveDiagram.length === 0) {
+      return -1000;
     }
     let minZIndex = Infinity;
-    layers.forEach((layer: LayerState) => {
+    layersAboveDiagram.forEach((layer: LayerState) => {
       if (layer.details.z > 0 && layer.details.z < minZIndex) {
         minZIndex = layer.details.z;
       }
@@ -93,11 +96,12 @@ export const minLayerZIndexAboveDiagramSelector = createSelector(
 export const minLayerZIndexBelowDiagramSelector = createSelector(
   layersForCurrentModelSelector,
   layers => {
-    if (!layers || layers.length === 0) {
+    const layerBelowDiagram = layers.filter(layer => layer.details.z < 0);
+    if (layerBelowDiagram.length === 0) {
       return -1000;
     }
     let minZIndex = Infinity;
-    layers.forEach((layer: LayerState) => {
+    layerBelowDiagram.forEach((layer: LayerState) => {
       if (layer.details.z < 0 && layer.details.z < minZIndex) {
         minZIndex = layer.details.z;
       }
-- 
GitLab