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] 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