Merge pull request 'dev' (#324) from dev into dev-deploy

Reviewed-on: #324
This commit is contained in:
ysCha 2025-09-03 10:19:12 +09:00
commit b5fd9e34e7
19 changed files with 364 additions and 177 deletions

View File

@ -13,6 +13,7 @@ export const MENU = {
MOVEMENT_SHAPE_UPDOWN: 'movementShapeUpdown', // 동선이동.형올림내림 MOVEMENT_SHAPE_UPDOWN: 'movementShapeUpdown', // 동선이동.형올림내림
OUTLINE_EDIT_OFFSET: 'outlineEditOffset', // 외벽선 편집 및 오프셋 OUTLINE_EDIT_OFFSET: 'outlineEditOffset', // 외벽선 편집 및 오프셋
ROOF_SHAPE_ALLOC: 'rootShapeAlloc', // 지붕면 항당 ROOF_SHAPE_ALLOC: 'rootShapeAlloc', // 지붕면 항당
ALL_REMOVE: 'allRemove', // 전체 삭제
DEFAULT: 'roofCoveringDefault', // 아무것도 선택 안할 경우 DEFAULT: 'roofCoveringDefault', // 아무것도 선택 안할 경우
}, // 지붕덮개 }, // 지붕덮개
BATCH_CANVAS: { BATCH_CANVAS: {

View File

@ -66,12 +66,17 @@ export default function CanvasFrame() {
canvas?.loadFromJSON(JSON.parse(plan.canvasStatus), function () { canvas?.loadFromJSON(JSON.parse(plan.canvasStatus), function () {
canvasLoadInit() //config canvasLoadInit() //config
canvas?.renderAll() // . canvas?.renderAll() // .
if (canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE).length > 0) { if (canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE).length > 0) {
setTimeout(() => {
setSelectedMenu('module') setSelectedMenu('module')
}, 500)
} else if (canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL).length > 0) { } else if (canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL).length > 0) {
setSelectedMenu('outline') setSelectedMenu('outline')
} else { } else {
setTimeout(() => {
setSelectedMenu('surface') setSelectedMenu('surface')
}, 500)
} }
const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)

View File

@ -8,6 +8,7 @@ import { usePopup } from '@/hooks/usePopup'
import { canvasState } from '@/store/canvasAtom' import { canvasState } from '@/store/canvasAtom'
import { usePolygon } from '@/hooks/usePolygon' import { usePolygon } from '@/hooks/usePolygon'
import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch' import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch'
import { useRoofFn } from '@/hooks/common/useRoofFn'
const FLOW_DIRECTION_TYPE = { const FLOW_DIRECTION_TYPE = {
EIGHT_AZIMUTH: 'eightAzimuth', EIGHT_AZIMUTH: 'eightAzimuth',
@ -19,6 +20,7 @@ export default function FlowDirectionSetting(props) {
const { id, pos = contextPopupPosition, target } = props const { id, pos = contextPopupPosition, target } = props
const canvas = useRecoilValue(canvasState) const canvas = useRecoilValue(canvasState)
const { getMessage } = useMessage() const { getMessage } = useMessage()
const { setSurfaceShapePattern } = useRoofFn()
const { changeSurfaceLineType } = useSurfaceShapeBatch({}) const { changeSurfaceLineType } = useSurfaceShapeBatch({})
@ -79,6 +81,7 @@ export default function FlowDirectionSetting(props) {
surfaceCompass: orientation, surfaceCompass: orientation,
surfaceCompassType: type, surfaceCompassType: type,
}) })
setSurfaceShapePattern(roof, null, null, roof.roofMaterial)
drawDirectionArrow(roof) drawDirectionArrow(roof)
canvas?.renderAll() canvas?.renderAll()
changeSurfaceLineType(roof) changeSurfaceLineType(roof)

View File

@ -66,6 +66,9 @@ export default function useMenu() {
case MENU.ROOF_COVERING.ROOF_SHAPE_ALLOC: case MENU.ROOF_COVERING.ROOF_SHAPE_ALLOC:
addPopup(popupId, 1, <RoofAllocationSetting id={popupId} />) addPopup(popupId, 1, <RoofAllocationSetting id={popupId} />)
break break
case MENU.ROOF_COVERING.ALL_REMOVE:
deleteAllSurfacesAndObjects()
break
} }
} }

View File

@ -6,6 +6,8 @@ import { POLYGON_TYPE } from '@/common/common'
import { useEvent } from '@/hooks/useEvent' import { useEvent } from '@/hooks/useEvent'
import { useLine } from '@/hooks/useLine' import { useLine } from '@/hooks/useLine'
import { outerLinePointsState } from '@/store/outerLineAtom' import { outerLinePointsState } from '@/store/outerLineAtom'
import { usePolygon } from '@/hooks/usePolygon'
import { useText } from '@/hooks/useText'
const ROOF_COLOR = { const ROOF_COLOR = {
0: 'rgb(199,240,213)', 0: 'rgb(199,240,213)',
@ -13,6 +15,7 @@ const ROOF_COLOR = {
2: 'rgb(187,204,255)', 2: 'rgb(187,204,255)',
3: 'rgb(228,202,255)', 3: 'rgb(228,202,255)',
} }
export function useRoofFn() { export function useRoofFn() {
const canvas = useRecoilValue(canvasState) const canvas = useRecoilValue(canvasState)
const selectedRoofMaterial = useRecoilValue(selectedRoofMaterialSelector) const selectedRoofMaterial = useRecoilValue(selectedRoofMaterialSelector)
@ -20,6 +23,8 @@ export function useRoofFn() {
const { addCanvasMouseEventListener, initEvent } = useEvent() const { addCanvasMouseEventListener, initEvent } = useEvent()
const resetPoints = useResetRecoilState(outerLinePointsState) const resetPoints = useResetRecoilState(outerLinePointsState)
const { addPitchText } = useLine() const { addPitchText } = useLine()
const { setPolygonLinesActualSize } = usePolygon()
const { changeCorridorDimensionText } = useText()
//면형상 선택 클릭시 지붕 패턴 입히기 //면형상 선택 클릭시 지붕 패턴 입히기
function setSurfaceShapePattern(polygon, mode = 'onlyBorder', trestleMode = false, roofMaterial, isForceChange = false, isDisplay = false) { function setSurfaceShapePattern(polygon, mode = 'onlyBorder', trestleMode = false, roofMaterial, isForceChange = false, isDisplay = false) {
@ -47,6 +52,7 @@ export function useRoofFn() {
let width = (roofMaterial.width || 226) / 10 let width = (roofMaterial.width || 226) / 10
let height = (roofMaterial.length || 158) / 10 let height = (roofMaterial.length || 158) / 10
const index = roofMaterial.index ?? 0 const index = roofMaterial.index ?? 0
let roofStyle = 2 let roofStyle = 2
const inputPatternSize = { width: width, height: height } //임시 사이즈 const inputPatternSize = { width: width, height: height } //임시 사이즈
@ -172,6 +178,8 @@ export function useRoofFn() {
polygon.set('fill', null) polygon.set('fill', null)
polygon.set('fill', pattern) polygon.set('fill', pattern)
polygon.roofMaterial = roofMaterial polygon.roofMaterial = roofMaterial
setPolygonLinesActualSize(polygon)
changeCorridorDimensionText()
polygon.canvas?.renderAll() polygon.canvas?.renderAll()
} catch (e) { } catch (e) {
console.log(e) console.log(e)
@ -306,7 +314,15 @@ export function useRoofFn() {
} }
function convertAbsolutePoint(area) { function convertAbsolutePoint(area) {
return area.points.map((p) => fabric.util.transformPoint({ x: p.x - area.pathOffset.x, y: p.y - area.pathOffset.y }, area.calcTransformMatrix())) return area.points.map((p) =>
fabric.util.transformPoint(
{
x: p.x - area.pathOffset.x,
y: p.y - area.pathOffset.y,
},
area.calcTransformMatrix(),
),
)
} }
const removeOuterLines = (currentMousePos) => { const removeOuterLines = (currentMousePos) => {

View File

@ -63,6 +63,7 @@ export function useModuleBasicSetting(tabNum) {
const { checkModuleDisjointSurface } = useTurf() const { checkModuleDisjointSurface } = useTurf()
useEffect(() => { useEffect(() => {
initEvent()
return () => { return () => {
//수동 설치시 초기화 //수동 설치시 초기화
removeMouseEvent('mouse:up') removeMouseEvent('mouse:up')
@ -139,7 +140,7 @@ export function useModuleBasicSetting(tabNum) {
roof.lines.forEach((line) => { roof.lines.forEach((line) => {
line.attributes = { line.attributes = {
...line.attributes, ...line.attributes,
offset: getOffset(offsetObjects.addRoof, line, roof.pitch, roof.from), offset: getOffset(offsetObjects.addRoof, line, roof.roofMaterial.pitch),
} }
}) })
//배치면 설치 영역 //배치면 설치 영역
@ -209,9 +210,9 @@ export function useModuleBasicSetting(tabNum) {
const calculateHeightRate = 1 / Math.cos((degree * Math.PI) / 180) const calculateHeightRate = 1 / Math.cos((degree * Math.PI) / 180)
const calculateValue = calculateHeightRate / calculateExpression(degree) const calculateValue = calculateHeightRate / calculateExpression(degree)
const eavesResult = from === 'roofCover' ? (data.eavesMargin * Math.cos((degree * Math.PI) / 180)) / 10 : data.eavesMargin / 10 const eavesResult = +roofSizeSet === 1 ? (data.eavesMargin * Math.cos((degree * Math.PI) / 180)) / 10 : data.eavesMargin / 10
const ridgeResult = from === 'roofCover' ? (data.ridgeMargin * Math.cos((degree * Math.PI) / 180)) / 10 : data.ridgeMargin / 10 const ridgeResult = +roofSizeSet === 1 ? (data.ridgeMargin * Math.cos((degree * Math.PI) / 180)) / 10 : data.ridgeMargin / 10
const kerabaMargin = from === 'roofCover' && isDiagonal ? data.kerabaMargin / calculateValue / 10 : data.kerabaMargin / 10 const kerabaMargin = +roofSizeSet === 1 && isDiagonal ? data.kerabaMargin / calculateValue / 10 : data.kerabaMargin / 10
switch (line.attributes.type) { switch (line.attributes.type) {
case LINE_TYPE.WALLLINE.EAVES: case LINE_TYPE.WALLLINE.EAVES:
@ -556,7 +557,7 @@ export function useModuleBasicSetting(tabNum) {
let tmpHeight = flowDirection === 'south' || flowDirection === 'north' ? moduleHeight : moduleWidth let tmpHeight = flowDirection === 'south' || flowDirection === 'north' ? moduleHeight : moduleWidth
let { width, height } = let { width, height } =
moduleSetupSurface.from === 'roofCover' +roofSizeSet === 1
? calculateVisibleModuleHeight(tmpWidth, tmpHeight, getDegreeByChon(moduleSetupSurfaces[i].roofMaterial.pitch), flowDirection) ? calculateVisibleModuleHeight(tmpWidth, tmpHeight, getDegreeByChon(moduleSetupSurfaces[i].roofMaterial.pitch), flowDirection)
: { width: tmpWidth, height: tmpHeight } : { width: tmpWidth, height: tmpHeight }
@ -1056,11 +1057,11 @@ export function useModuleBasicSetting(tabNum) {
let tmpHeight = flowDirection === 'south' || flowDirection === 'north' ? moduleHeight : moduleWidth let tmpHeight = flowDirection === 'south' || flowDirection === 'north' ? moduleHeight : moduleWidth
width = width =
moduleSetupSurface.from === 'roofCover' +roofSizeSet === 1
? calculateVisibleModuleHeight(tmpWidth, tmpHeight, getDegreeByChon(moduleSetupSurfaces[i].roofMaterial.pitch), flowDirection).width ? calculateVisibleModuleHeight(tmpWidth, tmpHeight, getDegreeByChon(moduleSetupSurfaces[i].roofMaterial.pitch), flowDirection).width
: tmpWidth : tmpWidth
height = height =
moduleSetupSurface.from === 'roofCover' +roofSizeSet === 1
? calculateVisibleModuleHeight(tmpWidth, tmpHeight, getDegreeByChon(moduleSetupSurfaces[i].roofMaterial.pitch), flowDirection).height ? calculateVisibleModuleHeight(tmpWidth, tmpHeight, getDegreeByChon(moduleSetupSurfaces[i].roofMaterial.pitch), flowDirection).height
: tmpHeight : tmpHeight
@ -1386,11 +1387,11 @@ export function useModuleBasicSetting(tabNum) {
//복시도, 실치수에 따른 모듈 높이 조정 //복시도, 실치수에 따른 모듈 높이 조정
width = width =
trestlePolygon.from === 'roofCover' +roofSizeSet === 1
? calculateVisibleModuleHeight(tmpWidth, tmpHeight, getDegreeByChon(trestlePolygon.roofMaterial.pitch), flowDirection).width ? calculateVisibleModuleHeight(tmpWidth, tmpHeight, getDegreeByChon(trestlePolygon.roofMaterial.pitch), flowDirection).width
: tmpWidth : tmpWidth
height = height =
trestlePolygon.from === 'roofCover' +roofSizeSet === 1
? calculateVisibleModuleHeight(tmpWidth, tmpHeight, getDegreeByChon(trestlePolygon.roofMaterial.pitch), flowDirection).height ? calculateVisibleModuleHeight(tmpWidth, tmpHeight, getDegreeByChon(trestlePolygon.roofMaterial.pitch), flowDirection).height
: tmpHeight : tmpHeight
@ -2974,11 +2975,11 @@ export function useModuleBasicSetting(tabNum) {
const pointY2 = top const pointY2 = top
//디버깅 //디버깅
const finalLine = new QLine([pointX1, pointY1, pointX2, pointY2], { // const finalLine = new QLine([pointX1, pointY1, pointX2, pointY2], {
stroke: 'red', // stroke: 'red',
strokeWidth: 1, // strokeWidth: 1,
selectable: true, // selectable: true,
}) // })
// canvas?.add(finalLine) // canvas?.add(finalLine)
// canvas?.renderAll() // canvas?.renderAll()
@ -3106,11 +3107,11 @@ export function useModuleBasicSetting(tabNum) {
const pointY2 = coords[2].y + ((coords[2].x - top) / (coords[2].x - coords[1].x)) * (coords[1].y - coords[2].y) const pointY2 = coords[2].y + ((coords[2].x - top) / (coords[2].x - coords[1].x)) * (coords[1].y - coords[2].y)
//디버깅용 //디버깅용
const finalLine = new QLine([pointX1, pointY1, pointX2, pointY2], { // const finalLine = new QLine([pointX1, pointY1, pointX2, pointY2], {
stroke: 'red', // stroke: 'red',
strokeWidth: 1, // strokeWidth: 1,
selectable: true, // selectable: true,
}) // })
// canvas?.add(finalLine) // canvas?.add(finalLine)
// canvas?.renderAll() // canvas?.renderAll()
@ -3308,7 +3309,7 @@ export function useModuleBasicSetting(tabNum) {
let tmpHeight = flowDirection === 'south' || flowDirection === 'north' ? moduleHeight : moduleWidth let tmpHeight = flowDirection === 'south' || flowDirection === 'north' ? moduleHeight : moduleWidth
let { width, height } = let { width, height } =
moduleSetupSurface.from === 'roofCover' +roofSizeSet === 1
? calculateVisibleModuleHeight(tmpWidth, tmpHeight, getDegreeByChon(moduleSetupSurfaces[i].roofMaterial.pitch), flowDirection) ? calculateVisibleModuleHeight(tmpWidth, tmpHeight, getDegreeByChon(moduleSetupSurfaces[i].roofMaterial.pitch), flowDirection)
: { width: tmpWidth, height: tmpHeight } : { width: tmpWidth, height: tmpHeight }
@ -4027,7 +4028,7 @@ export function useModuleBasicSetting(tabNum) {
10 10
} }
return moduleSetupSurface.from === 'roofCover' return +roofSizeSet === 1
? calculateVisibleModuleHeight(tmpWidth, tmpHeight, getDegreeByChon(moduleSetupSurface.roofMaterial.pitch), moduleSetupSurface.direction) ? calculateVisibleModuleHeight(tmpWidth, tmpHeight, getDegreeByChon(moduleSetupSurface.roofMaterial.pitch), moduleSetupSurface.direction)
: { width: tmpWidth, height: tmpHeight } : { width: tmpWidth, height: tmpHeight }
} }

View File

@ -82,7 +82,6 @@ export const useTrestle = () => {
} }
let rackInfos = [] let rackInfos = []
if (rack) { if (rack) {
rackInfos = Object.keys(rack).map((key) => { rackInfos = Object.keys(rack).map((key) => {
return { key, value: rack[key] } return { key, value: rack[key] }
@ -2484,8 +2483,8 @@ export const useTrestle = () => {
// 각도에 따른 길이 반환 // 각도에 따른 길이 반환
function getTrestleLength(length, degree, surface) { function getTrestleLength(length, degree, surface) {
if (surface.from !== 'roofCover') { if (+roofSizeSet !== 1) {
// 지붕덮개로부터 온게 아니면 그냥 length 리턴 // 복시도 입력이 아닌경우 그냥 길이 return
return length return length
} }
const radians = (degree * Math.PI) / 180 const radians = (degree * Math.PI) / 180

View File

@ -18,7 +18,6 @@ import {
basicSettingState, basicSettingState,
correntObjectNoState, correntObjectNoState,
corridorDimensionSelector, corridorDimensionSelector,
fetchRoofMaterialsState,
roofMaterialsAtom, roofMaterialsAtom,
selectedRoofMaterialSelector, selectedRoofMaterialSelector,
settingModalFirstOptionsState, settingModalFirstOptionsState,
@ -41,6 +40,8 @@ import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupSta
import { v4 as uuidv4 } from 'uuid' import { v4 as uuidv4 } from 'uuid'
import { useEvent } from '@/hooks/useEvent' import { useEvent } from '@/hooks/useEvent'
import { logger } from '@/util/logger' import { logger } from '@/util/logger'
import { useText } from '@/hooks/useText'
import { usePolygon } from '@/hooks/usePolygon'
const defaultDotLineGridSetting = { const defaultDotLineGridSetting = {
INTERVAL: { INTERVAL: {
@ -118,7 +119,6 @@ export function useCanvasSetting(executeEffect = true) {
const { getRoofMaterialList, getModuleTypeItemList } = useMasterController() const { getRoofMaterialList, getModuleTypeItemList } = useMasterController()
const [roofMaterials, setRoofMaterials] = useRecoilState(roofMaterialsAtom) const [roofMaterials, setRoofMaterials] = useRecoilState(roofMaterialsAtom)
const [addedRoofs, setAddedRoofs] = useRecoilState(addedRoofsState) const [addedRoofs, setAddedRoofs] = useRecoilState(addedRoofsState)
const [fetchRoofMaterials, setFetchRoofMaterials] = useRecoilState(fetchRoofMaterialsState)
const setCurrentMenu = useSetRecoilState(currentMenuState) const setCurrentMenu = useSetRecoilState(currentMenuState)
const resetModuleSelectionData = useResetRecoilState(moduleSelectionDataState) /* 다음으로 넘어가는 최종 데이터 */ const resetModuleSelectionData = useResetRecoilState(moduleSelectionDataState) /* 다음으로 넘어가는 최종 데이터 */
@ -133,6 +133,9 @@ export function useCanvasSetting(executeEffect = true) {
const { addPopup } = usePopup() const { addPopup } = usePopup()
const [popupId, setPopupId] = useState(uuidv4()) const [popupId, setPopupId] = useState(uuidv4())
const { changeCorridorDimensionText } = useText()
const { setPolygonLinesActualSize } = usePolygon()
const SelectOptions = [ const SelectOptions = [
{ id: 1, name: getMessage('modal.canvas.setting.grid.dot.line.setting.line.origin'), value: 1 }, { id: 1, name: getMessage('modal.canvas.setting.grid.dot.line.setting.line.origin'), value: 1 },
{ id: 2, name: '1/2', value: 1 / 2 }, { id: 2, name: '1/2', value: 1 / 2 },
@ -197,7 +200,7 @@ export function useCanvasSetting(executeEffect = true) {
} }
}, [addedRoofs]) }, [addedRoofs])
useEffect(() => { /*useEffect(() => {
if (!executeEffect) { if (!executeEffect) {
return return
} }
@ -212,7 +215,7 @@ export function useCanvasSetting(executeEffect = true) {
setAddedRoofs(newAddedRoofs) setAddedRoofs(newAddedRoofs)
} }
setBasicSettings({ ...basicSetting, selectedRoofMaterial: selectedRoofMaterial }) setBasicSettings({ ...basicSetting, selectedRoofMaterial: selectedRoofMaterial })
}, [roofMaterials]) }, [roofMaterials])*/
useEffect(() => { useEffect(() => {
if (!canvas) { if (!canvas) {
@ -221,39 +224,13 @@ export function useCanvasSetting(executeEffect = true) {
if (!executeEffect) { if (!executeEffect) {
return return
} }
const { column } = corridorDimension const roofs = canvasObjects.filter((obj) => obj.name === POLYGON_TYPE.ROOF)
const lengthTexts = canvas.getObjects().filter((obj) => obj.name === 'lengthText') if (roofs.length > 0) {
const group = canvas.getObjects().filter((obj) => obj.type === 'group') roofs.forEach((roof) => {
group.forEach((obj) => { setPolygonLinesActualSize(roof)
obj._objects
.filter((obj2) => obj2.name === 'lengthText')
.forEach((obj3) => {
lengthTexts.push(obj3)
}) })
}) changeCorridorDimensionText()
switch (column) {
case 'corridorDimension':
lengthTexts.forEach((obj) => {
if (obj.planeSize) {
obj.set({ text: obj.planeSize.toString() })
} }
})
break
case 'realDimension':
lengthTexts.forEach((obj) => {
if (obj.actualSize) {
obj.set({ text: obj.actualSize.toString() })
}
})
break
case 'noneDimension':
lengthTexts.forEach((obj) => {
obj.set({ text: '' })
})
break
}
canvas?.renderAll()
}, [corridorDimension]) }, [corridorDimension])
useEffect(() => { useEffect(() => {
@ -448,9 +425,8 @@ export function useCanvasSetting(executeEffect = true) {
} }
if (addRoofs.length > 0) { if (addRoofs.length > 0) {
setAddedRoofs(addRoofs) setBasicSettings((prev) => {
return {
setBasicSettings({
...basicSetting, ...basicSetting,
roofMaterials: addRoofs[0], roofMaterials: addRoofs[0],
planNo: roofsRow[0].planNo, planNo: roofsRow[0].planNo,
@ -458,7 +434,9 @@ export function useCanvasSetting(executeEffect = true) {
roofAngleSet: roofsRow[0].roofAngleSet, roofAngleSet: roofsRow[0].roofAngleSet,
roofsData: roofsArray, roofsData: roofsArray,
selectedRoofMaterial: addRoofs.find((roof) => roof.selected), selectedRoofMaterial: addRoofs.find((roof) => roof.selected),
}
}) })
setAddedRoofs(addRoofs)
setCanvasSetting({ setCanvasSetting({
...basicSetting, ...basicSetting,

View File

@ -28,6 +28,7 @@ import { outerLinePointsState } from '@/store/outerLineAtom'
import { QcastContext } from '@/app/QcastProvider' import { QcastContext } from '@/app/QcastProvider'
import { usePlan } from '@/hooks/usePlan' import { usePlan } from '@/hooks/usePlan'
import { roofsState } from '@/store/roofAtom' import { roofsState } from '@/store/roofAtom'
import { useText } from '@/hooks/useText'
export function useRoofAllocationSetting(id) { export function useRoofAllocationSetting(id) {
const canvas = useRecoilValue(canvasState) const canvas = useRecoilValue(canvasState)
@ -60,6 +61,7 @@ export function useRoofAllocationSetting(id) {
const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState) const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState)
const resetPoints = useResetRecoilState(outerLinePointsState) const resetPoints = useResetRecoilState(outerLinePointsState)
const [corridorDimension, setCorridorDimension] = useRecoilState(corridorDimensionSelector) const [corridorDimension, setCorridorDimension] = useRecoilState(corridorDimensionSelector)
const { changeCorridorDimensionText } = useText()
useEffect(() => { useEffect(() => {
/** 배치면 초기설정에서 선택한 지붕재 배열 설정 */ /** 배치면 초기설정에서 선택한 지붕재 배열 설정 */
@ -188,7 +190,6 @@ export function useRoofAllocationSetting(id) {
}) })
//데이터 동기화 //데이터 동기화
setCurrentRoofList(selectRoofs) setCurrentRoofList(selectRoofs)
}) })
} catch (error) { } catch (error) {
console.error('Data fetching error:', error) console.error('Data fetching error:', error)
@ -459,6 +460,10 @@ export function useRoofAllocationSetting(id) {
/** 모듈 선택 데이터 초기화 */ /** 모듈 선택 데이터 초기화 */
// modifyModuleSelectionData() // modifyModuleSelectionData()
setModuleSelectionData({ ...moduleSelectionData, roofConstructions: newRoofList }) setModuleSelectionData({ ...moduleSelectionData, roofConstructions: newRoofList })
setTimeout(() => {
changeCorridorDimensionText('realDimension')
}, 500)
} }
/** /**

View File

@ -1,9 +1,8 @@
'use client' 'use client'
import { useEffect } from 'react' import { useRecoilValue, useResetRecoilState } from 'recoil'
import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil'
import { canvasSettingState, canvasState, currentCanvasPlanState, globalPitchState } from '@/store/canvasAtom' import { canvasSettingState, canvasState, currentCanvasPlanState, globalPitchState } from '@/store/canvasAtom'
import { MENU, POLYGON_TYPE, LINE_TYPE } from '@/common/common' import { LINE_TYPE, MENU, POLYGON_TYPE } from '@/common/common'
import { getIntersectionPoint, toFixedWithoutRounding } from '@/util/canvas-util' import { getIntersectionPoint, toFixedWithoutRounding } from '@/util/canvas-util'
import { degreesToRadians } from '@turf/turf' import { degreesToRadians } from '@turf/turf'
import { QPolygon } from '@/components/fabric/QPolygon' import { QPolygon } from '@/components/fabric/QPolygon'
@ -20,13 +19,12 @@ import { useRoofFn } from '@/hooks/common/useRoofFn'
import { outerLinePointsState } from '@/store/outerLineAtom' import { outerLinePointsState } from '@/store/outerLineAtom'
import { placementShapeDrawingPointsState } from '@/store/placementShapeDrawingAtom' import { placementShapeDrawingPointsState } from '@/store/placementShapeDrawingAtom'
import { getBackGroundImage } from '@/lib/imageActions' import { getBackGroundImage } from '@/lib/imageActions'
import PlacementSurfaceLineProperty from '@/components/floor-plan/modal/placementShape/PlacementSurfaceLineProperty'
import { v4 as uuidv4 } from 'uuid'
import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' import { useCanvasSetting } from '@/hooks/option/useCanvasSetting'
import { useText } from '@/hooks/useText'
export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
const { getMessage } = useMessage() const { getMessage } = useMessage()
const { drawDirectionArrow, addPolygon } = usePolygon() const { drawDirectionArrow, addPolygon, addLengthText } = usePolygon()
const lengthTextFont = useRecoilValue(fontSelector('lengthText')) const lengthTextFont = useRecoilValue(fontSelector('lengthText'))
const resetOuterLinePoints = useResetRecoilState(outerLinePointsState) const resetOuterLinePoints = useResetRecoilState(outerLinePointsState)
const resetPlacementShapeDrawingPoints = useResetRecoilState(placementShapeDrawingPointsState) const resetPlacementShapeDrawingPoints = useResetRecoilState(placementShapeDrawingPointsState)
@ -40,6 +38,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
// const { addCanvasMouseEventListener, initEvent } = useContext(EventContext) // const { addCanvasMouseEventListener, initEvent } = useContext(EventContext)
const { addPopup, closePopup } = usePopup() const { addPopup, closePopup } = usePopup()
const { setSurfaceShapePattern } = useRoofFn() const { setSurfaceShapePattern } = useRoofFn()
const { changeCorridorDimensionText } = useText()
const currentCanvasPlan = useRecoilValue(currentCanvasPlanState) const currentCanvasPlan = useRecoilValue(currentCanvasPlanState)
const { fetchSettings } = useCanvasSetting(false) const { fetchSettings } = useCanvasSetting(false)
@ -848,7 +847,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
const selection = new fabric.ActiveSelection(selectionArray, { const selection = new fabric.ActiveSelection(selectionArray, {
canvas: canvas, canvas: canvas,
draggable: true, // draggable: true,
lockMovementX: false, // X축 이동 허용 lockMovementX: false, // X축 이동 허용
lockMovementY: false, // Y축 이동 허용 lockMovementY: false, // Y축 이동 허용
originX: 'center', originX: 'center',
@ -858,7 +857,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
canvas.setActiveObject(selection) canvas.setActiveObject(selection)
addCanvasMouseEventListener('mouse:up', (e) => { addCanvasMouseEventListener('mouse:up', (e) => {
canvas.selection = true canvas.selection = false
canvas.discardActiveObject() // 모든 선택 해제 canvas.discardActiveObject() // 모든 선택 해제
canvas.requestRenderAll() // 화면 업데이트 canvas.requestRenderAll() // 화면 업데이트
@ -875,10 +874,13 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
} }
}) })
canvas.renderAll() // roof.fire('polygonMoved')
roof.fire('polygonMoved') roof.fire('modified')
drawDirectionArrow(roof) drawDirectionArrow(roof)
changeCorridorDimensionText()
addLengthText(roof)
initEvent() initEvent()
canvas.renderAll()
}) })
} }
} }

View File

@ -5,6 +5,8 @@ import { canvasSizeState, canvasState, canvasZoomState, currentMenuState, curren
import { QPolygon } from '@/components/fabric/QPolygon' import { QPolygon } from '@/components/fabric/QPolygon'
import { fontSelector } from '@/store/fontAtom' import { fontSelector } from '@/store/fontAtom'
import { MENU, POLYGON_TYPE } from '@/common/common' import { MENU, POLYGON_TYPE } from '@/common/common'
import { useText } from '@/hooks/useText'
import { usePolygon } from '@/hooks/usePolygon'
// 캔버스에 필요한 이벤트 // 캔버스에 필요한 이벤트
export function useCanvasEvent() { export function useCanvasEvent() {
@ -15,6 +17,8 @@ export function useCanvasEvent() {
const [canvasZoom, setCanvasZoom] = useRecoilState(canvasZoomState) const [canvasZoom, setCanvasZoom] = useRecoilState(canvasZoomState)
const lengthTextOption = useRecoilValue(fontSelector('lengthText')) const lengthTextOption = useRecoilValue(fontSelector('lengthText'))
const currentMenu = useRecoilValue(currentMenuState) const currentMenu = useRecoilValue(currentMenuState)
const { changeCorridorDimensionText } = useText()
const { setPolygonLinesActualSize } = usePolygon()
useEffect(() => { useEffect(() => {
canvas?.setZoom(canvasZoom / 100) canvas?.setZoom(canvasZoom / 100)
@ -63,6 +67,13 @@ export function useCanvasEvent() {
textObjs.forEach((obj) => { textObjs.forEach((obj) => {
obj.bringToFront() obj.bringToFront()
}) })
if (target.name === POLYGON_TYPE.ROOF) {
setTimeout(() => {
setPolygonLinesActualSize(target)
changeCorridorDimensionText()
}, 300)
}
} }
if (target.name === 'cell') { if (target.name === 'cell') {
@ -116,48 +127,6 @@ export function useCanvasEvent() {
target.setControlVisible(controlKey, false) target.setControlVisible(controlKey, false)
}) })
}) })
/*target.on('editing:exited', () => {
if (isNaN(target.text.trim())) {
target.set({ text: previousValue })
canvas?.renderAll()
return
}
const updatedValue = parseFloat(target.text.trim())
const targetParent = target.parent
const points = targetParent.getCurrentPoints()
const i = target.idx // Assuming target.index gives the index of the point
const startPoint = points[i]
const endPoint = points[(i + 1) % points.length]
const dx = endPoint.x - startPoint.x
const dy = endPoint.y - startPoint.y
const currentLength = Math.sqrt(dx * dx + dy * dy)
const scaleFactor = updatedValue / currentLength
const newEndPoint = {
x: startPoint.x + dx * scaleFactor,
y: startPoint.y + dy * scaleFactor,
}
const newPoints = [...points]
newPoints[(i + 1) % points.length] = newEndPoint
for (let idx = i + 1; idx < points.length; idx++) {
if (newPoints[idx].x === endPoint.x) {
newPoints[idx].x = newEndPoint.x
} else if (newPoints[idx].y === endPoint.y) {
newPoints[idx].y = newEndPoint.y
}
}
const newPolygon = new QPolygon(newPoints, targetParent.initOptions)
canvas?.add(newPolygon)
canvas?.remove(targetParent)
canvas?.renderAll()
})*/
target.on('moving', (e) => { target.on('moving', (e) => {
target.uuid = uuidv4() target.uuid = uuidv4()

View File

@ -1,15 +1,18 @@
import { useRecoilValue } from 'recoil' import { useRecoilValue } from 'recoil'
import { import {
ANGLE_TYPE,
canvasState, canvasState,
currentAngleTypeSelector, currentAngleTypeSelector,
fontFamilyState, fontFamilyState,
fontSizeState, fontSizeState,
globalPitchState,
pitchTextSelector, pitchTextSelector,
showAngleUnitSelector, showAngleUnitSelector,
} from '@/store/canvasAtom' } from '@/store/canvasAtom'
import { QLine } from '@/components/fabric/QLine' import { QLine } from '@/components/fabric/QLine'
import { getChonByDegree, getDegreeByChon } from '@/util/canvas-util' import { basicSettingState } from '@/store/settingAtom'
import { calcLineActualSize } from '@/util/qpolygon-utils'
import { getDegreeByChon } from '@/util/canvas-util'
import { useText } from '@/hooks/useText'
export const useLine = () => { export const useLine = () => {
const canvas = useRecoilValue(canvasState) const canvas = useRecoilValue(canvasState)
@ -18,6 +21,10 @@ export const useLine = () => {
const currentAngleType = useRecoilValue(currentAngleTypeSelector) const currentAngleType = useRecoilValue(currentAngleTypeSelector)
const pitchText = useRecoilValue(pitchTextSelector) const pitchText = useRecoilValue(pitchTextSelector)
const angleUnit = useRecoilValue(showAngleUnitSelector) const angleUnit = useRecoilValue(showAngleUnitSelector)
const roofSizeSet = useRecoilValue(basicSettingState).roofSizeSet
const globalPitch = useRecoilValue(globalPitchState)
const { changeCorridorDimensionText } = useText()
const addLine = (points = [], options) => { const addLine = (points = [], options) => {
const line = new QLine(points, { const line = new QLine(points, {
@ -151,6 +158,57 @@ export const useLine = () => {
}) })
} }
/**
* 복도치수, 실제치수에 따라 actualSize를 설정한다.
* @param line
* @param direction polygon의 방향
* @param pitch
*/
const setActualSize = (line, direction, pitch = globalPitch) => {
const { x1, y1, x2, y2 } = line
const isHorizontal = y1 === y2
const isVertical = x1 === x2
const isDiagonal = !isHorizontal && !isVertical
const lineLength = line.getLength()
line.attributes = { ...line.attributes, planeSize: line.getLength(), actualSize: line.getLength() }
if (+roofSizeSet === 1) {
if (direction === 'south' || direction === 'north') {
if (isVertical) {
line.attributes = {
...line.attributes,
actualSize: calcLineActualSize(line, getDegreeByChon(pitch)),
}
} else if (isDiagonal) {
const yLength = Math.abs(y2 - y1) * 10
const h = yLength * Math.tan(getDegreeByChon(pitch) * (Math.PI / 180))
const actualSize = Math.sqrt(h ** 2 + lineLength ** 2)
line.attributes = { ...line.attributes, actualSize: actualSize }
}
} else if (direction === 'west' || direction === 'east') {
if (isHorizontal) {
line.attributes = {
...line.attributes,
actualSize: calcLineActualSize(line, getDegreeByChon(pitch)),
}
} else if (isDiagonal) {
const xLength = Math.abs(x2 - x1) * 10
const h = xLength * Math.tan(getDegreeByChon(pitch) * (Math.PI / 180))
const actualSize = Math.sqrt(h ** 2 + lineLength ** 2)
line.attributes = { ...line.attributes, actualSize: actualSize }
}
}
}
line.attributes = { ...line.attributes, actualSize: Number(line.attributes.actualSize.toFixed(0)) }
}
return { return {
addLine, addLine,
removeLine, removeLine,
@ -160,5 +218,6 @@ export const useLine = () => {
removePitchText, removePitchText,
addPitchTextsByOuterLines, addPitchTextsByOuterLines,
getLengthByLine, getLengthByLine,
setActualSize,
} }
} }

View File

@ -4,7 +4,7 @@ import { fabric } from 'fabric'
import { calculateIntersection, findAndRemoveClosestPoint, getDegreeByChon, getDegreeInOrientation, isPointOnLine } from '@/util/canvas-util' import { calculateIntersection, findAndRemoveClosestPoint, getDegreeByChon, getDegreeInOrientation, isPointOnLine } from '@/util/canvas-util'
import { QPolygon } from '@/components/fabric/QPolygon' import { QPolygon } from '@/components/fabric/QPolygon'
import { isSamePoint, removeDuplicatePolygons } from '@/util/qpolygon-utils' import { isSamePoint, removeDuplicatePolygons } from '@/util/qpolygon-utils'
import { flowDisplaySelector } from '@/store/settingAtom' import { basicSettingState, flowDisplaySelector } from '@/store/settingAtom'
import { fontSelector } from '@/store/fontAtom' import { fontSelector } from '@/store/fontAtom'
import { QLine } from '@/components/fabric/QLine' import { QLine } from '@/components/fabric/QLine'
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common' import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
@ -18,6 +18,9 @@ export const usePolygon = () => {
const currentAngleType = useRecoilValue(currentAngleTypeSelector) const currentAngleType = useRecoilValue(currentAngleTypeSelector)
const pitchText = useRecoilValue(pitchTextSelector) const pitchText = useRecoilValue(pitchTextSelector)
const globalPitch = useRecoilValue(globalPitchState) const globalPitch = useRecoilValue(globalPitchState)
const roofSizeSet = useRecoilValue(basicSettingState).roofSizeSet
const { setActualSize } = useLine()
const { getLengthByLine } = useLine() const { getLengthByLine } = useLine()
@ -86,7 +89,9 @@ export const usePolygon = () => {
const maxY = line.top + line.length const maxY = line.top + line.length
const degree = (Math.atan2(y2 - y1, x2 - x1) * 180) / Math.PI const degree = (Math.atan2(y2 - y1, x2 - x1) * 180) / Math.PI
const text = new fabric.Textbox(planeSize ? planeSize.toString() : length.toString(), { const text = new fabric.Textbox(
+roofSizeSet === 1 ? (actualSize ? actualSize.toString() : length.toString()) : planeSize ? planeSize.toString() : length.toString(),
{
left: left, left: left,
top: top, top: top,
fontSize: lengthTextFontOptions.fontSize.value, fontSize: lengthTextFontOptions.fontSize.value,
@ -106,7 +111,8 @@ export const usePolygon = () => {
lockScalingY: true, lockScalingY: true,
parent: polygon, parent: polygon,
name: 'lengthText', name: 'lengthText',
}) },
)
polygon.texts.push(text) polygon.texts.push(text)
canvas.add(text) canvas.add(text)
}) })
@ -927,6 +933,63 @@ export const usePolygon = () => {
canvas.remove(line) canvas.remove(line)
}) })
// innerLines가 합쳐졌을 때 polygonLine과 같은 경우 그 polygonLine의 need를 false로 변경
const mergeOverlappingInnerLines = (lines) => {
const mergedLines = []
const processed = new Set()
lines.forEach((line, index) => {
if (processed.has(index)) return
let currentLine = { ...line }
processed.add(index)
// 현재 라인과 겹치는 다른 라인들을 찾아서 합치기
for (let i = index + 1; i < lines.length; i++) {
if (processed.has(i)) continue
const otherLine = lines[i]
if (checkLineOverlap(currentLine, otherLine)) {
// 두 라인을 합치기 - 가장 긴 범위로 확장
const isVertical = Math.abs(currentLine.x1 - currentLine.x2) < 1
if (isVertical) {
const allYPoints = [currentLine.y1, currentLine.y2, otherLine.y1, otherLine.y2]
currentLine.y1 = Math.min(...allYPoints)
currentLine.y2 = Math.max(...allYPoints)
currentLine.x1 = currentLine.x2 = (currentLine.x1 + otherLine.x1) / 2
} else {
const allXPoints = [currentLine.x1, currentLine.x2, otherLine.x1, otherLine.x2]
currentLine.x1 = Math.min(...allXPoints)
currentLine.x2 = Math.max(...allXPoints)
currentLine.y1 = currentLine.y2 = (currentLine.y1 + otherLine.y1) / 2
}
processed.add(i)
}
}
mergedLines.push(currentLine)
})
return mergedLines
}
const mergedInnerLines = mergeOverlappingInnerLines(innerLines)
// 합쳐진 innerLine과 동일한 polygonLine의 need를 false로 설정
polygonLines.forEach((polygonLine) => {
mergedInnerLines.forEach((mergedInnerLine) => {
const isSameLine =
(isSamePoint(polygonLine.startPoint, mergedInnerLine.startPoint) && isSamePoint(polygonLine.endPoint, mergedInnerLine.endPoint)) ||
(isSamePoint(polygonLine.startPoint, mergedInnerLine.endPoint) && isSamePoint(polygonLine.endPoint, mergedInnerLine.startPoint))
if (isSameLine) {
polygonLine.need = false
}
})
})
canvas.renderAll() canvas.renderAll()
/*polygonLines.forEach((line) => { /*polygonLines.forEach((line) => {
@ -934,6 +997,7 @@ export const usePolygon = () => {
canvas.add(line) canvas.add(line)
}) })
canvas.renderAll()*/ canvas.renderAll()*/
polygonLines = polygonLines.filter((line) => line.need)
polygonLines.forEach((line) => { polygonLines.forEach((line) => {
/*const originStroke = line.stroke /*const originStroke = line.stroke
@ -1589,7 +1653,7 @@ export const usePolygon = () => {
const remainingLines = [...allLines] // 사용 가능한 line들의 복사본 const remainingLines = [...allLines] // 사용 가능한 line들의 복사본
// isStart가 true인 line들만 시작점으로 사용 // isStart가 true인 line들만 시작점으로 사용
const startLines = remainingLines.filter(line => line.attributes?.isStart === true) const startLines = remainingLines.filter((line) => line.attributes?.isStart === true)
startLines.forEach((startLine) => { startLines.forEach((startLine) => {
// 현재 남아있는 line들로 그래프 생성 // 현재 남아있는 line들로 그래프 생성
@ -1621,7 +1685,7 @@ export const usePolygon = () => {
roofs.push(roof) roofs.push(roof)
// 사용된 startLine을 remainingLines에서 제거 // 사용된 startLine을 remainingLines에서 제거
const startLineIndex = remainingLines.findIndex(line => line === startLine) const startLineIndex = remainingLines.findIndex((line) => line === startLine)
if (startLineIndex !== -1) { if (startLineIndex !== -1) {
remainingLines.splice(startLineIndex, 1) remainingLines.splice(startLineIndex, 1)
} }
@ -1675,6 +1739,22 @@ export const usePolygon = () => {
canvas.renderAll() canvas.renderAll()
} }
/**
* 폴리곤의 라인 속성을 복도치수, 실제치수에 따라 actualSize 설정
* @param polygon
*/
const setPolygonLinesActualSize = (polygon) => {
if (!polygon.lines || polygon.lines.length === 0 || !polygon.roofMaterial) {
return
}
polygon.lines.forEach((line) => {
setActualSize(line, polygon.direction, +polygon.roofMaterial?.pitch)
})
addLengthText(polygon)
}
return { return {
addPolygon, addPolygon,
addPolygonByLines, addPolygonByLines,
@ -1683,5 +1763,6 @@ export const usePolygon = () => {
addLengthText, addLengthText,
splitPolygonWithLines, splitPolygonWithLines,
splitPolygonWithSeparate, splitPolygonWithSeparate,
setPolygonLinesActualSize,
} }
} }

51
src/hooks/useText.js Normal file
View File

@ -0,0 +1,51 @@
import { useRecoilValue } from 'recoil'
import { corridorDimensionSelector } from '@/store/settingAtom'
import { canvasState } from '@/store/canvasAtom'
export function useText() {
const canvas = useRecoilValue(canvasState)
const corridorDimension = useRecoilValue(corridorDimensionSelector)
const changeCorridorDimensionText = (columnText) => {
let { column } = corridorDimension
if (columnText) {
column = columnText
}
const lengthTexts = canvas.getObjects().filter((obj) => obj.name === 'lengthText')
const group = canvas.getObjects().filter((obj) => obj.type === 'group')
group.forEach((obj) => {
obj._objects
.filter((obj2) => obj2.name === 'lengthText')
.forEach((obj3) => {
lengthTexts.push(obj3)
})
})
switch (column) {
case 'corridorDimension':
lengthTexts.forEach((obj) => {
if (obj.planeSize) {
obj.set({ text: obj.planeSize.toString() })
}
})
break
case 'realDimension':
lengthTexts.forEach((obj) => {
if (obj.actualSize) {
obj.set({ text: obj.actualSize.toString() })
}
})
break
case 'noneDimension':
lengthTexts.forEach((obj) => {
obj.set({ text: '' })
})
break
}
canvas?.renderAll()
}
return {
changeCorridorDimensionText,
}
}

View File

@ -1,9 +1,12 @@
import {GeoJSONMultipolygon, List} from "./Utils"; // Types
import Vector2d from "./Primitives/Vector2d"; export type { GeoJSONMultipolygon, List } from "./Utils";
import SkeletonBuilder from "./SkeletonBuilder"; export type { Skeleton } from "./Skeleton";
import { Skeleton } from "./Skeleton";
import EdgeResult from "./EdgeResult"; // Values
import Edge from "./Circular/Edge"; export { default as Vector2d } from "./Primitives/Vector2d";
import Vertex from "./Circular/Vertex"; export { default as SkeletonBuilder } from "./SkeletonBuilder";
export { default as EdgeResult } from "./EdgeResult";
export { default as Edge } from "./Circular/Edge";
export { default as Vertex } from "./Circular/Vertex";
export {SkeletonBuilder, List, Vector2d, GeoJSONMultipolygon, Skeleton, EdgeResult, Edge, Vertex};

View File

@ -57,6 +57,7 @@
"modal.movement.flow.line.top.right": "高さ変更:上、右", "modal.movement.flow.line.top.right": "高さ変更:上、右",
"plan.menu.roof.cover.outline.edit.offset": "外壁の編集とオフセット", "plan.menu.roof.cover.outline.edit.offset": "外壁の編集とオフセット",
"plan.menu.roof.cover.roof.surface.alloc": "屋根面の割り当て", "plan.menu.roof.cover.roof.surface.alloc": "屋根面の割り当て",
"plan.menu.roof.cover.roof.surface.all.remove": "伏せ図全削除",
"plan.menu.roof.cover.roof.shape.edit": "屋根形状編集", "plan.menu.roof.cover.roof.shape.edit": "屋根形状編集",
"plan.menu.roof.cover.auxiliary.line.drawing": "補助線の作成", "plan.menu.roof.cover.auxiliary.line.drawing": "補助線の作成",
"modal.cover.outline.drawing": "外壁線の作成", "modal.cover.outline.drawing": "外壁線の作成",

View File

@ -57,6 +57,7 @@
"modal.movement.flow.line.top.right": "높이변경 : 위, 오른쪽", "modal.movement.flow.line.top.right": "높이변경 : 위, 오른쪽",
"plan.menu.roof.cover.outline.edit.offset": "외벽선 편집 및 오프셋", "plan.menu.roof.cover.outline.edit.offset": "외벽선 편집 및 오프셋",
"plan.menu.roof.cover.roof.surface.alloc": "지붕면 할당", "plan.menu.roof.cover.roof.surface.alloc": "지붕면 할당",
"plan.menu.roof.cover.roof.surface.all.remove": "배치면 전체 삭제",
"plan.menu.roof.cover.roof.shape.edit": "지붕형상 편집", "plan.menu.roof.cover.roof.shape.edit": "지붕형상 편집",
"plan.menu.roof.cover.auxiliary.line.drawing": "보조선 작성", "plan.menu.roof.cover.auxiliary.line.drawing": "보조선 작성",
"modal.cover.outline.drawing": "외벽선 작성", "modal.cover.outline.drawing": "외벽선 작성",

View File

@ -23,9 +23,19 @@ export const menusState = atom({
}, },
{ type: 'outline', name: 'plan.menu.roof.cover', icon: 'con02', title: MENU.ROOF_COVERING.DEFAULT }, { type: 'outline', name: 'plan.menu.roof.cover', icon: 'con02', title: MENU.ROOF_COVERING.DEFAULT },
{ type: 'surface', name: 'plan.menu.placement.surface', icon: 'con03', title: MENU.BATCH_CANVAS.DEFAULT }, { type: 'surface', name: 'plan.menu.placement.surface', icon: 'con03', title: MENU.BATCH_CANVAS.DEFAULT },
{ type: 'module', name: 'plan.menu.module.circuit.setting', icon: 'con04', title: MENU.MODULE_CIRCUIT_SETTING.DEFAULT }, {
type: 'module',
name: 'plan.menu.module.circuit.setting',
icon: 'con04',
title: MENU.MODULE_CIRCUIT_SETTING.DEFAULT,
},
{ type: 'estimate', name: 'plan.menu.estimate', icon: 'con06', title: MENU.ESTIMATE.DEFAULT }, { type: 'estimate', name: 'plan.menu.estimate', icon: 'con06', title: MENU.ESTIMATE.DEFAULT },
{ type: 'simulation', name: 'plan.menu.simulation', icon: 'con05', title: MENU.POWER_GENERATION_SIMULATION.DEFAULT }, {
type: 'simulation',
name: 'plan.menu.simulation',
icon: 'con05',
title: MENU.POWER_GENERATION_SIMULATION.DEFAULT,
},
], ],
}) })
@ -37,16 +47,17 @@ export const subMenusState = atom({
// 지붕덮개 // 지붕덮개
{ id: 0, name: 'plan.menu.roof.cover.outline.drawing', menu: MENU.ROOF_COVERING.EXTERIOR_WALL_LINE }, { 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: 1, name: 'plan.menu.roof.cover.roof.shape.setting', menu: MENU.ROOF_COVERING.ROOF_SHAPE_SETTINGS },
// { {
// id: 2, id: 2,
// name: 'plan.menu.roof.cover.roof.shape.passivity.setting', name: 'plan.menu.roof.cover.roof.shape.passivity.setting',
// menu: MENU.ROOF_COVERING.ROOF_SHAPE_PASSIVITY_SETTINGS, menu: MENU.ROOF_COVERING.ROOF_SHAPE_PASSIVITY_SETTINGS,
// }, },
{ id: 3, name: 'plan.menu.roof.cover.auxiliary.line.drawing', menu: MENU.ROOF_COVERING.HELP_LINE_DRAWING }, { id: 3, name: 'plan.menu.roof.cover.auxiliary.line.drawing', menu: MENU.ROOF_COVERING.HELP_LINE_DRAWING },
{ id: 4, name: 'plan.menu.roof.cover.eaves.kerava.edit', menu: MENU.ROOF_COVERING.EAVES_KERAVA_EDIT }, { id: 4, name: 'plan.menu.roof.cover.eaves.kerava.edit', menu: MENU.ROOF_COVERING.EAVES_KERAVA_EDIT },
{ id: 5, name: 'plan.menu.roof.cover.movement.shape.updown', menu: MENU.ROOF_COVERING.MOVEMENT_SHAPE_UPDOWN }, { id: 5, name: 'plan.menu.roof.cover.movement.shape.updown', menu: MENU.ROOF_COVERING.MOVEMENT_SHAPE_UPDOWN },
{ id: 6, name: 'plan.menu.roof.cover.outline.edit.offset', menu: MENU.ROOF_COVERING.OUTLINE_EDIT_OFFSET }, { id: 6, name: 'plan.menu.roof.cover.outline.edit.offset', menu: MENU.ROOF_COVERING.OUTLINE_EDIT_OFFSET },
{ id: 7, name: 'plan.menu.roof.cover.roof.surface.alloc', menu: MENU.ROOF_COVERING.ROOF_SHAPE_ALLOC }, { id: 7, name: 'plan.menu.roof.cover.roof.surface.alloc', menu: MENU.ROOF_COVERING.ROOF_SHAPE_ALLOC },
{ id: 8, name: 'plan.menu.roof.cover.roof.surface.all.remove', menu: MENU.ROOF_COVERING.ALL_REMOVE },
], ],
surface: [ surface: [
// 배치면 // 배치면

View File

@ -14,12 +14,10 @@
"incremental": true, "incremental": true,
"module": "esnext", "module": "esnext",
"esModuleInterop": true, "esModuleInterop": true,
"allowSyntheticDefaultImports": true, // "moduleResolution": "node",
"moduleResolution": "bundler", // : "node" "bundler"
"resolveJsonModule": true, "resolveJsonModule": true,
"isolatedModules": true, "isolatedModules": true,
"jsx": "preserve", "jsx": "preserve",
"baseUrl": ".", //
"plugins": [ "plugins": [
{ {
"name": "next" "name": "next"