useModuleSelection 생성

This commit is contained in:
yjnoh 2025-01-02 15:34:25 +09:00
parent d7e5fd8a87
commit b01fbd1fbd
5 changed files with 383 additions and 206 deletions

View File

@ -10,12 +10,14 @@ export const GlobalDataContext = createContext({
}) })
const GlobalDataProvider = ({ children }) => { const GlobalDataProvider = ({ children }) => {
const [managementState, setManagementState] = useState({}) const [managementState, setManagementState] = useState(null)
// TODO: 임시 조치이며 개발 완료시 삭제 예정 -> 잊지말기... // TODO: 임시 조치이며 개발 완료시 삭제 예정 -> 잊지말기...
const [managementStateLoaded, setManagementStateLoaded] = useLocalStorage('managementStateLoaded', null) const [managementStateLoaded, setManagementStateLoaded] = useLocalStorage('managementStateLoaded', null)
useEffect(() => { useEffect(() => {
setManagementStateLoaded(managementState) if (managementState !== null) {
setManagementStateLoaded(managementState)
}
}, [managementState]) }, [managementState])
return <GlobalDataContext.Provider value={{ managementState, setManagementState, managementStateLoaded }}>{children}</GlobalDataContext.Provider> return <GlobalDataContext.Provider value={{ managementState, setManagementState, managementStateLoaded }}>{children}</GlobalDataContext.Provider>

View File

@ -1,74 +1,39 @@
import QSelectBox from '@/components/common/select/QSelectBox' import { useState } from 'react'
import { useMessage } from '@/hooks/useMessage' import { useRecoilValue } from 'recoil'
import { canvasSettingState, selectedModuleState, checkedModuleState, pitchSelector } from '@/store/canvasAtom'
import { useEffect, useReducer, useState } from 'react'
import { useRecoilValue, useRecoilState } from 'recoil'
import { useMasterController } from '@/hooks/common/useMasterController'
import { useCommonCode } from '@/hooks/common/useCommonCode'
import { addedRoofsState } from '@/store/settingAtom' import { addedRoofsState } from '@/store/settingAtom'
import { canvasSettingState, pitchSelector } from '@/store/canvasAtom'
import { useMessage } from '@/hooks/useMessage'
import QSelectBox from '@/components/common/select/QSelectBox'
import { useModuleSelection } from '@/hooks/module/useModuleSelection'
export default function Module({}) { export default function Module({}) {
const { getMessage } = useMessage()
const canvasSetting = useRecoilValue(canvasSettingState) // const canvasSetting = useRecoilValue(canvasSettingState) //
const addedRoofs = useRecoilValue(addedRoofsState) // const addedRoofs = useRecoilValue(addedRoofsState) //
const [roofTab, setRoofTab] = useState(0) //
const [globalPitch, setGlobalPitch] = useRecoilState(pitchSelector) const globalPitch = useRecoilValue(pitchSelector) //
const [roofTab, setRoofTab] = useState(0)
const [moduleList, setModuleList] = useState([{}])
const [roofMaterial, setRoofMaterial] = useState(addedRoofs[0])
const [raftCodes, setRaftCodes] = useState([])
const { getModuleTypeItemList, getTrestleList } = useMasterController()
const { getMessage } = useMessage()
const { findCommonCode } = useCommonCode()
const [selectedModules, setSelectedModules] = useRecoilState(selectedModuleState) //
const [selectedTrestle, setSelectedTrestle] = useState({}) //
const [selectedConstMthd, setSelectedConstMthd] = useState({}) //
const [selectedRoofBase, setSelectedRoofBase] = useState({}) //
const [selectedOptions, dispatchSelectedOptions] = useReducer(
(prevState, nextState) => {
return { ...prevState, ...nextState }
},
{
module: {},
roofs: [],
},
)
const displayPitch = canvasSetting.roofAngleSet === 'slope' ? '寸' : '度' const displayPitch = canvasSetting.roofAngleSet === 'slope' ? '寸' : '度'
const {
const [trestleList, setTrestleList] = useState([]) roofMaterial,
const [constMthdList, setConstMthdList] = useState([]) selectedModules,
const [roofBaseList, setRoofBaseList] = useState([]) raftCodes,
roughnessCodes,
let optionParams = { windSpeedCodes,
moduleTpCd: '', managementState,
roofMatlCd: '', moduleList,
raftBaseCd: '', trestleList,
trestleMkrCd: '', constMthdList,
constMthdCd: '', roofBaseList,
roofBaseCd: '', selectedOptions,
} handleRoofTab,
handleChangeModule,
useEffect(() => { handleChangeRaftBase,
// handleChangeTrestle,
const raftCodeList = findCommonCode('203800') handleChangeConstMthd,
handleChangeRoofBase,
raftCodeList.forEach((obj) => { } = useModuleSelection({ addedRoofs })
obj.name = obj.clCodeNm
obj.id = obj.clCode
})
setRaftCodes(raftCodeList)
//
const roofsIds = addedRoofs.filter((obj) => obj.roofMatlCd).map((obj) => obj.roofMatlCd)
if (roofsIds.length === 0) {
return
}
getModuleData(roofsIds)
}, [])
const moduleData = { const moduleData = {
header: [ header: [
@ -82,118 +47,6 @@ export default function Module({}) {
], ],
rows: [], rows: [],
} }
const surfaceTypes = [
{ id: 1, name: 'Ⅱ', value: 'Ⅱ' },
{ id: 2, name: 'Ⅲ ∙ Ⅳ', value: 'Ⅲ ∙ Ⅳ' },
]
const fiftingHeights = Array.from({ length: 16 }).map((data, index) => {
return { id: index, name: index + 5, value: index + 5 }
})
const windSpeeds = Array.from({ length: 7 }).map((data, index) => {
return { id: index, name: index * 2 + 30, value: index * 2 + 30 }
})
const handleRoofTab = (tab) => {
setRoofMaterial(addedRoofs[tab])
setRoofTab(tab)
}
const handleChangeModule = (option) => {
setSelectedModules(option) //
optionParams = {
moduleTpCd: option.itemTp,
roofMatlCd: roofMaterial.roofMatlCd,
raftBaseCd: '',
}
getModuleOptionsListData(optionParams, 'trestleList')
dispatchSelectedOptions({
module: option,
})
}
const handleChangeTrestle = (option) => {
setSelectedTrestle(option) //
optionParams = {
moduleTpCd: selectedModules.itemTp,
roofMatlCd: roofMaterial.roofMatlCd,
raftBaseCd: '',
trestleMkrCd: option.trestleMkrCd,
}
getModuleOptionsListData(optionParams, 'constMthdList')
selectedOptions.roofs.map((roof) => {
if (roof.id === tab) {
roof.trestle = option
} else {
roof.trestle = {
id: tab,
trestle: option,
}
}
})
dispatchSelectedOptions({
roofs: selectedOptions.roofs,
})
}
const handleChangeConstMthd = (option) => {
setSelectedConstMthd(option) //
optionParams = {
moduleTpCd: selectedModules.itemTp,
roofMatlCd: roofMaterial.roofMatlCd,
raftBaseCd: '',
trestleMkrCd: selectedTrestle.trestleMkrCd,
constMthdCd: option.constMthdCd,
}
getModuleOptionsListData(optionParams, 'roofBaseList')
}
useEffect(() => {
console.log('roofMaterial', roofMaterial)
}, [roofMaterial])
const getModuleData = async (roofsIds) => {
const list = await getModuleTypeItemList(roofsIds)
//selectbox
list.data.forEach((item) => {
item.name = item.itemNm
})
//
setModuleList(list.data)
setTrestleList([])
setConstMthdList([])
setRoofBaseList([])
}
const getModuleOptionsListData = async (params, optionsName) => {
const optionsList = await getTrestleList(params)
if (optionsName === 'trestleList') {
setTrestleList(optionsList.data)
setConstMthdList([])
setRoofBaseList([])
}
if (optionsName === 'constMthdList') {
setConstMthdList(optionsList.data)
setRoofBaseList([])
}
if (optionsName === 'roofBaseList') {
setRoofBaseList(optionsList.data)
}
}
useEffect(() => {
console.log('selectedOptions', selectedOptions)
}, [selectedOptions])
return ( return (
<> <>
@ -250,7 +103,14 @@ export default function Module({}) {
<div className="eaves-keraba-td"> <div className="eaves-keraba-td">
<div className="outline-form"> <div className="outline-form">
<div className="grid-select" style={{ width: '95.77px', flex: 'none' }}> <div className="grid-select" style={{ width: '95.77px', flex: 'none' }}>
<QSelectBox title={'Ⅲ ∙ Ⅳ'} options={surfaceTypes} /> <QSelectBox
title={'선택하세요'}
options={roughnessCodes}
value={roughnessCodes.clCode}
sourceKey={'clCode'}
targetKey={'clCode'}
showKey={'clCodeNm'}
/>
</div> </div>
</div> </div>
</div> </div>
@ -260,7 +120,12 @@ export default function Module({}) {
<div className="eaves-keraba-td"> <div className="eaves-keraba-td">
<div className="outline-form"> <div className="outline-form">
<div className="grid-select mr10"> <div className="grid-select mr10">
<QSelectBox title={'13'} options={fiftingHeights} /> <input
type="text"
className="input-origin block"
value={managementState?.installHeight}
onChange={(e) => setInstallationHeight(e.target.value)}
/>
</div> </div>
<span className="thin">mm</span> <span className="thin">mm</span>
</div> </div>
@ -271,7 +136,16 @@ export default function Module({}) {
<div className="eaves-keraba-td"> <div className="eaves-keraba-td">
<div className="outline-form"> <div className="outline-form">
<div className="grid-select mr10"> <div className="grid-select mr10">
<QSelectBox title={'32'} options={windSpeeds} /> {windSpeedCodes && managementState && (
<QSelectBox
title={''}
options={windSpeedCodes}
value={managementState}
targetKey={'standardWindSpeedId'}
sourceKey={'clCode'}
showKey={'clCodeNm'}
/>
)}
</div> </div>
<span className="thin">m/s</span> <span className="thin">m/s</span>
</div> </div>
@ -282,7 +156,12 @@ export default function Module({}) {
<div className="eaves-keraba-td"> <div className="eaves-keraba-td">
<div className="outline-form"> <div className="outline-form">
<div className="grid-select mr10"> <div className="grid-select mr10">
<input type="text" className="input-origin block" /> <input
type="text"
className="input-origin block"
value={managementState?.verticalSnowCover}
onChange={(e) => setStandardSnowLoad(e.target.value)}
/>
</div> </div>
<span className="thin">mm</span> <span className="thin">mm</span>
</div> </div>
@ -294,11 +173,16 @@ export default function Module({}) {
</div> </div>
<div className="module-table-box mb10"> <div className="module-table-box mb10">
<div className="module-box-tab"> <div className="module-box-tab">
{addedRoofs.map((roof, index) => ( {addedRoofs &&
<button key={index} className={`module-btn ${roofTab === index ? 'act' : ''}`} onClick={() => (roof ? handleRoofTab(index) : null)}> addedRoofs.map((roof, index) => (
{roof !== undefined ? `屋根材${index + 1}` : '-'} <button
</button> key={index}
))} className={`module-btn ${roofTab === index ? 'act' : ''}`}
onClick={() => setRoofTab(index)(roof ? handleRoofTab(index) : null)}
>
{roof !== undefined ? `屋根材${index + 1}` : '-'}
</button>
))}
{/* <button className={`module-btn ${roofTab === 0 ? 'act' : ''}`} onClick={() => handleRoofTab(0)}> {/* <button className={`module-btn ${roofTab === 0 ? 'act' : ''}`} onClick={() => handleRoofTab(0)}>
{canvasSetting.roofs[0] !== undefined ? '屋根材1' : '-'} {canvasSetting.roofs[0] !== undefined ? '屋根材1' : '-'}
</button> </button>
@ -321,6 +205,25 @@ export default function Module({}) {
</div> </div>
<div className="eaves-keraba-table"> <div className="eaves-keraba-table">
<div className="eaves-keraba-item"> <div className="eaves-keraba-item">
{roofMaterial && ['C'].includes(roofMaterial.lenAuth) && (
<>
<div className="eaves-keraba-th">L</div>
<div className="eaves-keraba-td">
<div className="keraba-flex">
<div className="outline-form">
<div className="grid-select">
<input
type="text"
className="input-origin block"
value={roofMaterial.lenBase}
disabled={roofMaterial.lenAuth === 'R' ? true : false}
/>
</div>
</div>
</div>
</div>
</>
)}
{roofMaterial && ['C', 'R'].includes(roofMaterial.raftAuth) && ( {roofMaterial && ['C', 'R'].includes(roofMaterial.raftAuth) && (
<> <>
<div className="eaves-keraba-th">{getMessage('modal.module.basic.setting.module.rafter.margin')}</div> <div className="eaves-keraba-th">{getMessage('modal.module.basic.setting.module.rafter.margin')}</div>
@ -334,14 +237,29 @@ export default function Module({}) {
value={roofMaterial.raftBaseCd} value={roofMaterial.raftBaseCd}
showKey={'clCodeNm'} showKey={'clCodeNm'}
disabled={roofMaterial.raftAuth === 'R' ? true : false} disabled={roofMaterial.raftAuth === 'R' ? true : false}
onChange={handleChangeRaftBase}
/> />
</> </>
)} )}
</div> </div>
</div>
</div>
</>
)}
{roofMaterial && ['C', 'R'].includes(roofMaterial.roofPchAuth) && (
<>
<div className="eaves-keraba-th">{getMessage('modal.module.basic.setting.module.rafter.margin')}</div>
<div className="eaves-keraba-td">
<div className="keraba-flex">
<div className="outline-form"> <div className="outline-form">
<span>垂木の間隔</span> <span>垂木の間隔</span>
<div className="grid-select"> <div className="grid-select">
<input type="text" className="input-origin block" /> <input
type="text"
className="input-origin block"
value={roofMaterial.hajebichi}
disabled={roofMaterial.roofPchAuth === 'R' ? true : false}
/>
</div> </div>
</div> </div>
</div> </div>
@ -353,13 +271,15 @@ export default function Module({}) {
<div className="eaves-keraba-th">{getMessage('modal.module.basic.setting.module.trestle.maker')}</div> <div className="eaves-keraba-th">{getMessage('modal.module.basic.setting.module.trestle.maker')}</div>
<div className="eaves-keraba-td"> <div className="eaves-keraba-td">
<div className="grid-select"> <div className="grid-select">
<QSelectBox {trestleList && (
title={'선택하세요.'} <QSelectBox
options={trestleList} title={'선택하세요.'}
value={trestleList?.trestleMkrCd} options={trestleList}
showKey={'trestleMkrCdNm'} value={trestleList?.trestleMkrCd}
onChange={handleChangeTrestle} showKey={'trestleMkrCdNm'}
/> onChange={handleChangeTrestle}
/>
)}
</div> </div>
</div> </div>
</div> </div>
@ -367,13 +287,15 @@ export default function Module({}) {
<div className="eaves-keraba-th">{getMessage('modal.module.basic.setting.module.construction.method')}</div> <div className="eaves-keraba-th">{getMessage('modal.module.basic.setting.module.construction.method')}</div>
<div className="eaves-keraba-td"> <div className="eaves-keraba-td">
<div className="grid-select"> <div className="grid-select">
<QSelectBox {constMthdList && (
title={'선택하세요'} <QSelectBox
options={constMthdList} title={'선택하세요'}
value={constMthdList.constMthdCd} options={constMthdList}
showKey={'constMthdCdNm'} value={constMthdList.constMthdCd}
onChange={handleChangeConstMthd} showKey={'constMthdCdNm'}
/> onChange={handleChangeConstMthd}
/>
)}
</div> </div>
</div> </div>
</div> </div>
@ -381,7 +303,15 @@ export default function Module({}) {
<div className="eaves-keraba-th">{getMessage('modal.module.basic.setting.module.under.roof')}</div> <div className="eaves-keraba-th">{getMessage('modal.module.basic.setting.module.under.roof')}</div>
<div className="eaves-keraba-td"> <div className="eaves-keraba-td">
<div className="grid-select"> <div className="grid-select">
<QSelectBox title={'선택하세요'} options={roofBaseList} value={roofBaseList.roofBaseCd} showKey={'roofBaseCdNm'} /> {roofBaseList && (
<QSelectBox
title={'선택하세요'}
options={roofBaseList}
value={roofBaseList.roofBaseCd}
showKey={'roofBaseCdNm'}
onChange={handleChangeRoofBase}
/>
)}
</div> </div>
</div> </div>
</div> </div>

View File

@ -36,7 +36,7 @@ export function useMasterController() {
} }
const paramString = `?${paramArr.map((item) => `arrRoofMatlCd=${item}`).join('&')}` const paramString = `?${paramArr.map((item) => `arrRoofMatlCd=${item}`).join('&')}`
return await get({ url: `/api/v1/master/getModuleTypeItemList${paramString}` }).then((res) => { return await get({ url: `/api/v1/master/getModuleTypeItemList${paramString}` }).then((res) => {
console.log('🚀🚀 ~ getModuleTypeItemList ~ res:', res) // console.log('🚀🚀 ~ getModuleTypeItemList ~ res:', res)
return res return res
}) })
} }

View File

@ -0,0 +1,245 @@
import { useRecoilState, useRecoilValue } from 'recoil'
import { useContext, useEffect, useReducer, useState } from 'react'
import { GlobalDataContext } from '@/app/GlobalDataProvider'
import { useCommonCode } from '../common/useCommonCode'
import { useMasterController } from '../common/useMasterController'
import { selectedModuleState } from '@/store/canvasAtom'
export function useModuleSelection(props) {
const [roofMaterial, setRoofMaterial] = useState(props.addedRoofs[0]) //지붕재
const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext)
const { findCommonCode } = useCommonCode()
const [raftCodes, setRaftCodes] = useState([]) //가대 목록
const [roughnessCodes, setRoughnessCodes] = useState([]) //면조도 목록
const [windSpeedCodes, setWindSpeedCodes] = useState([]) //기준풍속 목록
const [moduleList, setModuleList] = useState([{}]) //모듈 목록
const [trestleList, setTrestleList] = useState([])
const [constMthdList, setConstMthdList] = useState([])
const [roofBaseList, setRoofBaseList] = useState([])
const [selectedModules, setSelectedModules] = useRecoilState(selectedModuleState) //선택된 모듈
const [selectedRaftBase, setSelectedRaftBase] = useState({}) //선택된 가대
const [selectedTrestle, setSelectedTrestle] = useState({}) //선택된 가대
const [selectedConstMthd, setSelectedConstMthd] = useState({}) //선택된 공법
const [selectedRoofBase, setSelectedRoofBase] = useState({}) //선택된 지붕밑바탕
const [selectedOptions, dispatchSelectedOptions] = useReducer(
(prevState, nextState) => {
return { ...prevState, ...nextState }
},
{
module: {},
roofs: [],
},
)
const { getModuleTypeItemList, getTrestleList, getConstructionList } = useMasterController()
let optionParams = {
surfaceType: '', //면조도
installHeight: '', //설치 노 ㅍ이
standardWindSpeedId: '', //기준풍속
verticalSnowCover: '', //수직적설량
moduleTpCd: '',
roofMatlCd: '',
raftBaseCd: '',
trestleMkrCd: '',
constMthdCd: '',
roofBaseCd: '',
}
useEffect(() => {
console.log('managementState', managementState)
}, [managementState])
useEffect(() => {
//새로고침시 데이터 날아가는거 방지
if (!managementState) {
setManagementState(managementStateLoaded)
}
// 202600 경사도
const raftCodeList = findCommonCode('203800')
//서까래 코드
raftCodeList.forEach((obj) => {
obj.name = obj.clCodeNm
obj.id = obj.clCode
})
setRaftCodes(raftCodeList)
// 113700 면조도
const roughnessCodeList = findCommonCode('113700')
roughnessCodeList.forEach((obj) => {
obj.name = obj.clCodeNm
obj.id = obj.clCode
})
setRoughnessCodes(roughnessCodeList)
// 202000 풍속
const windCodeList = findCommonCode('202000')
windCodeList.forEach((obj) => {
obj.name = obj.clCodeNm
obj.id = obj.clCode
})
setWindSpeedCodes(windCodeList)
//지붕재 선택
const roofsIds = props.addedRoofs.filter((obj) => obj.roofMatlCd).map((obj) => obj.roofMatlCd)
if (roofsIds.length === 0) {
return
}
getModuleData(roofsIds)
}, [])
const handleRoofTab = (tab) => {
setRoofMaterial(props.addedRoofs[tab])
}
const getModuleData = async (roofsIds) => {
const list = await getModuleTypeItemList(roofsIds)
//selectbox에 이름을 넣는다
list.data.forEach((item) => {
item.name = item.itemNm
})
//셀렉트박스 데이터 초기화
setModuleList(list.data)
setTrestleList([])
setConstMthdList([])
setRoofBaseList([])
}
const getConstructionListData = async (params) => {
const optionsList = await getConstructionList(params)
console.log('optionsList', optionsList)
// setConstructionList(optionsList.data)
}
const getModuleOptionsListData = async (params, optionsName) => {
const optionsList = await getTrestleList(params)
if (optionsName === 'trestleList') {
setTrestleList(optionsList.data)
setConstMthdList([])
setRoofBaseList([])
}
if (optionsName === 'constMthdList') {
setConstMthdList(optionsList.data)
setRoofBaseList([])
}
if (optionsName === 'roofBaseList') {
setRoofBaseList(optionsList.data)
}
}
const handleChangeModule = (option) => {
setSelectedModules(option) //선택값 저장
optionParams = {
roofMatlCd: roofMaterial.roofMatlCd,
moduleTpCd: option.itemTp,
raftBaseCd: roofMaterial.raftBaseCd,
}
getModuleOptionsListData(optionParams, 'trestleList')
dispatchSelectedOptions({
module: option,
})
}
const handleChangeRaftBase = (option) => {
setSelectedRaftBase(option)
optionParams = {
roofMatlCd: roofMaterial.roofMatlCd,
moduleTpCd: selectedModules.itemTp,
raftBaseCd: option.clCode,
}
getModuleOptionsListData(optionParams, 'trestleList')
}
const handleChangeTrestle = (option) => {
setSelectedTrestle(option) //선택값 저장
optionParams = {
roofMatlCd: roofMaterial.roofMatlCd,
moduleTpCd: selectedModules.itemTp,
raftBaseCd: selectedRaftBase.clCode,
trestleMkrCd: option.trestleMkrCd,
}
getModuleOptionsListData(optionParams, 'constMthdList')
selectedOptions.roofs.map((roof) => {
if (roof.id === tab) {
roof.trestle = option
} else {
roof.trestle = {
id: tab,
trestle: option,
}
}
})
dispatchSelectedOptions({
roofs: selectedOptions.roofs,
})
}
const handleChangeConstMthd = (option) => {
setSelectedConstMthd(option) //선택된값 저장
optionParams = {
roofMatlCd: roofMaterial.roofMatlCd,
moduleTpCd: selectedModules.itemTp,
raftBaseCd: selectedRaftBase.clCode,
trestleMkrCd: selectedTrestle.trestleMkrCd,
constMthdCd: option.constMthdCd,
}
getModuleOptionsListData(optionParams, 'roofBaseList')
}
const handleChangeRoofBase = (option) => {
setSelectedRoofBase(option)
optionParams = {
roofMatlCd: roofMaterial.roofMatlCd,
moduleTpCd: selectedModules.itemTp,
raftBaseCd: selectedRaftBase.clCode,
trestleMkrCd: selectedTrestle.trestleMkrCd,
constMthdCd: selectedConstMthd.constMthdCd,
roofBaseCd: option.roofBaseCd,
}
}
return {
roofMaterial,
selectedModules,
selectedRaftBase,
selectedTrestle,
selectedConstMthd,
selectedRoofBase,
raftCodes,
roughnessCodes,
windSpeedCodes,
managementState,
moduleList,
trestleList,
constMthdList,
roofBaseList,
selectedOptions,
handleRoofTab,
handleChangeModule,
handleChangeRaftBase,
handleChangeTrestle,
handleChangeConstMthd,
handleChangeRoofBase,
}
}

View File

@ -36,10 +36,10 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
}, []) }, [])
const dbClickEvent = () => { const dbClickEvent = () => {
console.log('dbClickEvent 실행') // console.log('dbClickEvent 실행')
const dormerObject = canvas.getObjects().filter((obj) => obj.name === BATCH_TYPE.TRIANGLE_DORMER || obj.name === BATCH_TYPE.PENTAGON_DORMER) const dormerObject = canvas.getObjects().filter((obj) => obj.name === BATCH_TYPE.TRIANGLE_DORMER || obj.name === BATCH_TYPE.PENTAGON_DORMER)
console.log('dormerObject', dormerObject) // console.log('dormerObject', dormerObject)
if (dormerObject) { if (dormerObject) {
canvas.off('mouse:dblclick') canvas.off('mouse:dblclick')