diff --git a/src/components/common/context-menu/QContextMenu.jsx b/src/components/common/context-menu/QContextMenu.jsx index bf8ef23c..9654c514 100644 --- a/src/components/common/context-menu/QContextMenu.jsx +++ b/src/components/common/context-menu/QContextMenu.jsx @@ -12,7 +12,7 @@ export default function QContextMenu(props) { let contextType = '' if (activeObject) { - if (activeObject.initOptions) { + if (activeObject.initOptions && activeObject.initOptions.name) { //이건 바뀔 가능성이 있음 if (activeObject.initOptions?.name?.indexOf('guide') > -1) { contextType = 'surface' //면형상 diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index c916a0fc..71d23481 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -4,20 +4,34 @@ import { useEffect, useState } from 'react' import MenuDepth01 from './MenuDepth01' import QSelectBox from '@/components/common/select/QSelectBox' import { useMessage } from '@/hooks/useMessage' -import { post } from '@/lib/Axios' -import { useRecoilState, useRecoilValue } from 'recoil' +import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' import { settingModalFirstOptionsState, settingModalSecondOptionsState } from '@/store/settingAtom' -import { canvasZoomState, verticalHorizontalModeState } from '@/store/canvasAtom' +import { canvasState, canvasZoomState, currentMenuState, verticalHorizontalModeState } from '@/store/canvasAtom' +import { outerLinePointsState } from '@/store/outerLineAtom' +import { appMessageStore, globalLocaleStore } from '@/store/localeAtom' +import { MENU } from '@/common/common' + +import { useAxios } from '@/hooks/useAxios' +import { toastUp } from '@/hooks/useToast' + +import KO from '@/locales/ko.json' +import JA from '@/locales/ja.json' export default function CanvasMenu(props) { - const [objectNo] = useState('test123240912001') // 이후 삭제 필요 + const [objectNo, setObjectNo] = useState('test123240912001') // 이후 삭제 필요 const { setShowCanvasSettingModal, showOutlineModal, setShowOutlineModal } = props const [menuNumber, setMenuNumber] = useState(null) const [verticalHorizontalMode, setVerticalHorizontalMode] = useRecoilState(verticalHorizontalModeState) - const [vertical, setVertical] = useState(true) const [type, setType] = useState('') const { getMessage } = useMessage() const canvasZoom = useRecoilValue(canvasZoomState) + const canvas = useRecoilValue(canvasState) + const setCurrentMenu = useSetRecoilState(currentMenuState) + const setPoints = useSetRecoilState(outerLinePointsState) + const globalLocale = useRecoilValue(globalLocaleStore) + const [appMessageState, setAppMessageState] = useRecoilState(appMessageStore) + const { post } = useAxios() + const SelectOption = [{ name: '瓦53A' }, { name: '瓦53A' }] const onClickNav = (number) => { setMenuNumber(number) @@ -33,7 +47,13 @@ export default function CanvasMenu(props) { const firstOptions = useRecoilState(settingModalFirstOptionsState) const secondOptions = useRecoilState(settingModalSecondOptionsState) - useEffect(() => {}, [menuNumber, type]) + useEffect(() => { + if (globalLocale === 'ko') { + setAppMessageState(KO) + } else { + setAppMessageState(JA) + } + }, [menuNumber, type, globalLocale]) // 저장버튼(btn08) 클릭 시 호출되는 함수 const handleSaveSettings = async () => { @@ -60,6 +80,7 @@ export default function CanvasMenu(props) { const patternData = { objectNo, + //디스플레이 설정(다중) assignDisplay: dataToSend.firstOption1[0].selected, drawDisplay: dataToSend.firstOption1[1].selected, gridDisplay: dataToSend.firstOption1[2].selected, @@ -71,9 +92,11 @@ export default function CanvasMenu(props) { trestleDisplay: dataToSend.firstOption1[8].selected, coordiDisplay: dataToSend.firstOption1[9].selected, drawConverDisplay: dataToSend.firstOption1[10].selected, + //화면 표시(다중) onlyBorder: dataToSend.firstOption2[0].selected, lineHatch: dataToSend.firstOption2[1].selected, allPainted: dataToSend.firstOption2[2].selected, + //흡착범위 설정(단건) adsorpRangeSmall: dataToSend.secondOption2[0].selected, adsorpRangeSmallSemi: dataToSend.secondOption2[1].selected, adsorpRangeMedium: dataToSend.secondOption2[2].selected, @@ -81,16 +104,19 @@ export default function CanvasMenu(props) { } // HTTP POST 요청 보내기 - await post({ url: `/api/canvas-management/canvas-settings`, data: patternData }) - - // 응답 처리 - alert('설정이 저장되었습니다.') + await post({ url: `/api/canvas-management/canvas-settings`, data: patternData }).then((res) => { + toastUp({ message: res.returnMessage, type: 'success' }) + }) } catch (error) { - console.error('설정을 저장하는 동안 오류가 발생했습니다:', error) - alert('설정을 저장하는 중 오류가 발생했습니다.') + toastUp({ message: res.returnMessage, type: 'error' }) } } + const handleClear = () => { + setPoints([]) + canvas?.clear() + } + return (
@@ -111,6 +137,7 @@ export default function CanvasMenu(props) { className={`canvas-menu-item ${menuNumber === 2 ? 'active' : ''}`} onClick={() => { onClickNav(2) + setCurrentMenu(MENU.ROOF_COVERING.DEFAULT) }} > -
  • onClickNav(3)}> +
  • { + onClickNav(3) + setCurrentMenu(MENU.BATCH_CANVAS.DEFAULT) + }} + >
  • -
  • onClickNav(4)}> +
  • { + onClickNav(4) + setCurrentMenu(MENU.MODULE_CIRCUIT_SETTING.DEFAULT) + }} + >
  • -
  • onClickNav(5)}> +
  • { + onClickNav(5) + setCurrentMenu(MENU.ESTIMATE.DEFAULT) + }} + >
  • -
  • onClickNav(6)}> +
  • { + onClickNav(6) + setCurrentMenu(MENU.POWER_GENERATION_SIMULATION.DEFAULT) + }} + >
  • - +
    diff --git a/src/components/floor-plan/MenuDepth01.jsx b/src/components/floor-plan/MenuDepth01.jsx index cf0ad1e8..ab3c4b5d 100644 --- a/src/components/floor-plan/MenuDepth01.jsx +++ b/src/components/floor-plan/MenuDepth01.jsx @@ -3,14 +3,19 @@ import { ToggleonMouse } from '@/components/header/Header' import { useMessage } from '@/hooks/useMessage' import { useEffect, useState } from 'react' +import { MENU } from '@/common/common' +import { currentMenuState } from '@/store/canvasAtom' +import { useSetRecoilState } from 'recoil' export default function MenuDepth01(props) { const { setShowOutlineModal, type } = props const { getMessage } = useMessage() const [activeMenu, setActiveMenu] = useState() - const onClickMenu = (menuNum) => { - setActiveMenu(menuNum) - setShowOutlineModal(menuNum === 0) + const setCurrentMenu = useSetRecoilState(currentMenuState) + const onClickMenu = ({ id, menu, name }) => { + setActiveMenu(menu) + setShowOutlineModal(menu === MENU.ROOF_COVERING.EXTERIOR_WALL_LINE) + setCurrentMenu(menu) } const menus = [ @@ -26,21 +31,21 @@ export default function MenuDepth01(props) { const menuInfo = { outline: [ // 지붕덮개 - { id: 0, name: 'plan.menu.roof.cover.outline.drawing' }, - { id: 1, name: 'plan.menu.roof.cover.roof.shape.setting' }, - { id: 2, name: 'plan.menu.roof.cover.roof.shape.edit' }, - { id: 3, name: 'plan.menu.roof.cover.auxiliary.line.drawing' }, + { id: 0, name: 'plan.menu.roof.cover.outline.drawing', menu: MENU.ROOF_COVERING.EXTERIOR_WALL_LINE }, + { id: 1, name: 'plan.menu.roof.cover.roof.shape.setting', menu: MENU.ROOF_COVERING.ROOF_SHAPE_SETTINGS }, + { id: 2, name: 'plan.menu.roof.cover.roof.shape.edit', menu: MENU.ROOF_COVERING.ROOF_SHAPE_EDITING }, + { id: 3, name: 'plan.menu.roof.cover.auxiliary.line.drawing', menu: MENU.ROOF_COVERING.HELP_LINE_DRAWING }, ], surface: [ // 배치면 - { id: 0, name: 'plan.menu.placement.surface.drawing' }, - { id: 1, name: 'plan.menu.placement.surface.surface' }, - { id: 2, name: 'plan.menu.placement.surface.object' }, + { id: 0, name: 'plan.menu.placement.surface.drawing', menu: MENU.BATCH_CANVAS.BATCH_DRAWING }, + { id: 1, name: 'plan.menu.placement.surface.surface', menu: MENU.BATCH_CANVAS.SURFACE_SHAPE_BATCH }, + { id: 2, name: 'plan.menu.placement.surface.object', menu: MENU.BATCH_CANVAS.OBJECT_BATCH }, ], module: [ // 모듈, 회로 구성 - { id: 0, name: 'plan.menu.module.circuit.setting.default' }, - { id: 1, name: 'plan.menu.module.circuit.setting.circuit.trestle.setting' }, + { id: 0, name: 'plan.menu.module.circuit.setting.default', menu: MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING }, + { id: 1, name: 'plan.menu.module.circuit.setting.circuit.trestle.setting', menu: MENU.MODULE_CIRCUIT_SETTING.CIRCUIT_TRESTLE_SETTING }, ], } @@ -54,8 +59,8 @@ export default function MenuDepth01(props) {
    + ) : type === OUTER_LINE_TYPE.ANGLE ? ( +
    +
    + + { + const value = e.target.value.replace(/^0+/, '') + setLength1(value.replace(/[^-0-9]/g, '')) + }} + placeholder="3000" + /> +
    +
    + + { + const val = e.target.value + // const pattern = /(^\d+$)|(^\d{1,}.\d{0,2}$)/ + const pattern = /^-?(\d{1,3}([.]\d{0,2})?)?$/ + if (!pattern.test(val)) { + // prev에서 마지막 자리 제거 + setAngle1(val.slice(0, val.length - 1)) + return + } + + setAngle1(val) + }} + className="input-origin block" + /> +
    +
    ) : ( <> )} diff --git a/src/components/floor-plan/modal/setting01/FirstOption.jsx b/src/components/floor-plan/modal/setting01/FirstOption.jsx index 8c292a05..e0c4170d 100644 --- a/src/components/floor-plan/modal/setting01/FirstOption.jsx +++ b/src/components/floor-plan/modal/setting01/FirstOption.jsx @@ -1,28 +1,24 @@ import { useRecoilState } from 'recoil' import { settingModalFirstOptionsState } from '@/store/settingAtom' import { useMessage } from '@/hooks/useMessage' -import React, { useEffect, useState } from 'react' -import { get } from '@/lib/Axios' +import React, { useCallback, useEffect, useState } from 'react' +import { useAxios } from '@/hooks/useAxios' export default function FirstOption() { - const [objectNo] = useState('test123240912001') // 이후 삭제 필요 + const [objectNo, setObjectNo] = useState('test123240912001') // 이후 삭제 필요 const [settingsModalOptions, setSettingModalOptions] = useRecoilState(settingModalFirstOptionsState) const { option1, option2 } = settingsModalOptions const { getMessage } = useMessage() - - const [isFetched, setIsFetched] = useState(false) // 조회 여부 상태 + const { get } = useAxios() // 데이터를 최초 한 번만 조회 useEffect(() => { console.log('FirstOption useEffect 실행') - if (!isFetched) { - // 조회가 안 되었을 때만 fetchSettings 실행 - fetchSettings() - } - }, [isFetched]) // isFetched 상태가 변할 때마다 확인 + fetchSettings() + }, [objectNo]) // Canvas Setting 조회 및 초기화 - const fetchSettings = async () => { + const fetchSettings = useCallback(async () => { try { const res = await get({ url: `/api/canvas-management/canvas-settings/by-object/${objectNo}` }) @@ -49,12 +45,10 @@ export default function FirstOption() { option1, option2, }) - - setIsFetched(true) // 조회가 완료되면 isFetched를 true로 설정 } catch (error) { console.error('Data fetching error:', error) } - } + }, [objectNo]) const onClickOption = (option) => { option.selected = !option.selected @@ -67,23 +61,25 @@ export default function FirstOption() {

    {getMessage('modal.canvas.setting.first.option.info')}

    - {settingsModalOptions?.option1?.map((item) => ( - - ))} + {settingsModalOptions && + settingsModalOptions.option1.map((item) => ( + + ))}

    {getMessage('modal.canvas.setting.first.option.display')}

    - {settingsModalOptions?.option2?.map((item) => ( - - ))} + {settingsModalOptions && + settingsModalOptions.option2.map((item) => ( + + ))}
    diff --git a/src/components/floor-plan/modal/setting01/SecondOption.jsx b/src/components/floor-plan/modal/setting01/SecondOption.jsx index 0a568b67..7b8d8811 100644 --- a/src/components/floor-plan/modal/setting01/SecondOption.jsx +++ b/src/components/floor-plan/modal/setting01/SecondOption.jsx @@ -1,27 +1,24 @@ import { useRecoilState } from 'recoil' import { settingModalSecondOptionsState } from '@/store/settingAtom' import { useMessage } from '@/hooks/useMessage' -import React, { useEffect, useState } from 'react' -import { get } from '@/lib/Axios' +import React, { useCallback, useEffect, useState } from 'react' +import { useAxios } from '@/hooks/useAxios' export default function SecondOption() { - const [objectNo] = useState('test123240912001') // 이후 삭제 필요 + const [objectNo, setObjectNo] = useState('test123240912001') // 이후 삭제 필요 const [settingsModalOptions, setSettingModalOptions] = useRecoilState(settingModalSecondOptionsState) const { option1, option2 } = settingsModalOptions const { getMessage } = useMessage() - - const [isFetched, setIsFetched] = useState(false) // 조회 여부 상태 + const { get } = useAxios() // 데이터를 최초 한 번만 조회 useEffect(() => { console.log('SecondOption useEffect 실행') - if (!isFetched) { - // 조회가 안 되었을 때만 fetchSettings 실행 - fetchSettings() - } - }, [isFetched]) // isFetched 상태가 변할 때마다 확인 + fetchSettings() + }, [objectNo]) - const fetchSettings = async () => { + // Canvas Setting 조회 및 초기화 + const fetchSettings = useCallback(async () => { try { const res = await get({ url: `/api/canvas-management/canvas-settings/by-object/${objectNo}` }) @@ -36,12 +33,10 @@ export default function SecondOption() { option1, option2, }) - - setIsFetched(true) // 조회가 완료되면 isFetched를 true로 설정 } catch (error) { console.error('Data fetching error:', error) } - } + }, [objectNo]) const onClickOption = (option) => { // option2에서 한 개만 선택 가능하도록 처리 @@ -54,22 +49,24 @@ export default function SecondOption() {

    {getMessage('modal.canvas.setting.font.plan.edit')}

    - {settingsModalOptions.option1.map((item, index) => ( - - ))} + {settingsModalOptions && + settingsModalOptions.option1.map((item) => ( + + ))}

    {getMessage('modal.canvas.setting.font.plan.absorption')}

    - {settingsModalOptions.option2.map((item, index) => ( - - ))} + {settingsModalOptions && + settingsModalOptions.option2.map((item) => ( + + ))}