Merge branch 'dev' into dev-yj
This commit is contained in:
commit
d2da3cae4f
1
.gitignore
vendored
1
.gitignore
vendored
@ -41,4 +41,5 @@ next-env.d.ts
|
|||||||
#lock files
|
#lock files
|
||||||
yarn.lock
|
yarn.lock
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
pnpm-lock.yaml
|
||||||
certificates
|
certificates
|
||||||
1
MainLayout.codediagram
Normal file
1
MainLayout.codediagram
Normal file
File diff suppressed because one or more lines are too long
@ -1,6 +1,6 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { createContext, useEffect, useState } from 'react'
|
import { createContext, useState } from 'react'
|
||||||
import { ErrorBoundary } from 'next/dist/client/components/error-boundary'
|
import { ErrorBoundary } from 'next/dist/client/components/error-boundary'
|
||||||
import { useCommonCode } from '@/hooks/common/useCommonCode'
|
import { useCommonCode } from '@/hooks/common/useCommonCode'
|
||||||
import ServerError from './error'
|
import ServerError from './error'
|
||||||
|
|||||||
@ -25,6 +25,7 @@ import QPagination from './common/pagination/QPagination'
|
|||||||
|
|
||||||
import { trestleRequestModels, constructionRequestModels, trestleDetailRequestModels } from '@/models/apiModels'
|
import { trestleRequestModels, constructionRequestModels, trestleDetailRequestModels } from '@/models/apiModels'
|
||||||
import QSelectBox from './common/select/QSelectBox'
|
import QSelectBox from './common/select/QSelectBox'
|
||||||
|
import SampleReducer from './sample/SampleReducer'
|
||||||
|
|
||||||
export default function Playground() {
|
export default function Playground() {
|
||||||
const [useCadFile, setUseCadFile] = useRecoilState(useCadFileState)
|
const [useCadFile, setUseCadFile] = useRecoilState(useCadFileState)
|
||||||
@ -504,6 +505,9 @@ export default function Playground() {
|
|||||||
<div className="my-2">
|
<div className="my-2">
|
||||||
<Button onClick={handleChangeMyData}>QSelectBox value change!!</Button>
|
<Button onClick={handleChangeMyData}>QSelectBox value change!!</Button>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="my-2">
|
||||||
|
<SampleReducer />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,32 +1,28 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useContext, useEffect, useRef } from 'react'
|
import { useEffect, useRef } from 'react'
|
||||||
|
|
||||||
import { useRecoilValue } from 'recoil'
|
import { useRecoilValue } from 'recoil'
|
||||||
|
|
||||||
|
import QContextMenu from '@/components/common/context-menu/QContextMenu'
|
||||||
|
import PanelBatchStatistics from '@/components/floor-plan/modal/panelBatch/PanelBatchStatistics'
|
||||||
|
import ImgLoad from '@/components/floor-plan/modal/ImgLoad'
|
||||||
import { useCanvas } from '@/hooks/useCanvas'
|
import { useCanvas } from '@/hooks/useCanvas'
|
||||||
import { useEvent } from '@/hooks/useEvent'
|
|
||||||
import { usePlan } from '@/hooks/usePlan'
|
import { usePlan } from '@/hooks/usePlan'
|
||||||
import { useContextMenu } from '@/hooks/useContextMenu'
|
import { useContextMenu } from '@/hooks/useContextMenu'
|
||||||
import { currentMenuState } from '@/store/canvasAtom'
|
|
||||||
import QContextMenu from '@/components/common/context-menu/QContextMenu'
|
|
||||||
import { useCanvasConfigInitialize } from '@/hooks/common/useCanvasConfigInitialize'
|
import { useCanvasConfigInitialize } from '@/hooks/common/useCanvasConfigInitialize'
|
||||||
import { MENU } from '@/common/common'
|
import { currentMenuState } from '@/store/canvasAtom'
|
||||||
import PanelBatchStatistics from '@/components/floor-plan/modal/panelBatch/PanelBatchStatistics'
|
|
||||||
import { totalDisplaySelector } from '@/store/settingAtom'
|
import { totalDisplaySelector } from '@/store/settingAtom'
|
||||||
import ImgLoad from '@/components/floor-plan/modal/ImgLoad'
|
import { MENU } from '@/common/common'
|
||||||
|
|
||||||
export default function CanvasFrame() {
|
export default function CanvasFrame() {
|
||||||
const canvasRef = useRef(null)
|
const canvasRef = useRef(null)
|
||||||
const { canvas, handleBackImageLoadToCanvas } = useCanvas('canvas')
|
const { canvas } = useCanvas('canvas')
|
||||||
const { canvasLoadInit, gridInit } = useCanvasConfigInitialize()
|
const { canvasLoadInit, gridInit } = useCanvasConfigInitialize()
|
||||||
const currentMenu = useRecoilValue(currentMenuState)
|
const currentMenu = useRecoilValue(currentMenuState)
|
||||||
const { contextMenu, handleClick } = useContextMenu()
|
const { contextMenu, handleClick } = useContextMenu()
|
||||||
const { selectedPlan, currentCanvasPlan } = usePlan()
|
const { selectedPlan } = usePlan()
|
||||||
const totalDisplay = useRecoilValue(totalDisplaySelector) // 집계표 표시 여부
|
const totalDisplay = useRecoilValue(totalDisplaySelector) // 집계표 표시 여부
|
||||||
// useEvent()
|
|
||||||
// const { initEvent } = useContext(EventContext)
|
|
||||||
// initEvent()
|
|
||||||
|
|
||||||
const loadCanvas = () => {
|
const loadCanvas = () => {
|
||||||
if (canvas) {
|
if (canvas) {
|
||||||
|
|||||||
@ -3,12 +3,12 @@
|
|||||||
import { useContext, useEffect } from 'react'
|
import { useContext, useEffect } from 'react'
|
||||||
import { useRecoilValue } from 'recoil'
|
import { useRecoilValue } from 'recoil'
|
||||||
import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
|
import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
|
||||||
|
import { SessionContext } from '@/app/SessionProvider'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
import { usePlan } from '@/hooks/usePlan'
|
import { usePlan } from '@/hooks/usePlan'
|
||||||
import { globalLocaleStore } from '@/store/localeAtom'
|
|
||||||
import { SessionContext } from '@/app/SessionProvider'
|
|
||||||
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
|
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
|
||||||
|
import { globalLocaleStore } from '@/store/localeAtom'
|
||||||
|
|
||||||
export default function CanvasLayout({ children }) {
|
export default function CanvasLayout({ children }) {
|
||||||
// const { menuNumber } = props
|
// const { menuNumber } = props
|
||||||
|
|||||||
@ -2,54 +2,47 @@
|
|||||||
|
|
||||||
import { useContext, useEffect, useState } from 'react'
|
import { useContext, useEffect, useState } from 'react'
|
||||||
|
|
||||||
|
import { usePathname, useRouter } from 'next/navigation'
|
||||||
|
|
||||||
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
|
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
|
||||||
|
|
||||||
import { usePathname, useRouter } from 'next/navigation'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
|
|
||||||
import MenuDepth01 from './MenuDepth01'
|
import MenuDepth01 from './MenuDepth01'
|
||||||
import QSelectBox from '@/components/common/select/QSelectBox'
|
import QSelectBox from '@/components/common/select/QSelectBox'
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
import SettingModal01 from '@/components/floor-plan/modal/setting01/SettingModal01'
|
||||||
|
import PlacementShapeSetting from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting'
|
||||||
|
import EstimateCopyPop from '../estimate/popup/EstimateCopyPop'
|
||||||
|
import DocDownOptionPop from '../estimate/popup/DocDownOptionPop'
|
||||||
|
import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { usePlan } from '@/hooks/usePlan'
|
import { usePlan } from '@/hooks/usePlan'
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
import { useEvent } from '@/hooks/useEvent'
|
import { useEvent } from '@/hooks/useEvent'
|
||||||
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
|
import { useCanvasEvent } from '@/hooks/useCanvasEvent'
|
||||||
|
import { useCommonUtils } from '@/hooks/common/useCommonUtils'
|
||||||
|
import useMenu from '@/hooks/common/useMenu'
|
||||||
|
import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController'
|
||||||
|
import { useAxios } from '@/hooks/useAxios'
|
||||||
|
import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting'
|
||||||
import { canvasSettingState, canvasState, canvasZoomState, currentMenuState, verticalHorizontalModeState } from '@/store/canvasAtom'
|
import { canvasSettingState, canvasState, canvasZoomState, currentMenuState, verticalHorizontalModeState } from '@/store/canvasAtom'
|
||||||
import { sessionStore } from '@/store/commonAtom'
|
import { sessionStore } from '@/store/commonAtom'
|
||||||
import { outerLinePointsState } from '@/store/outerLineAtom'
|
import { outerLinePointsState } from '@/store/outerLineAtom'
|
||||||
import { appMessageStore, globalLocaleStore } from '@/store/localeAtom'
|
import { appMessageStore, globalLocaleStore } from '@/store/localeAtom'
|
||||||
import {
|
import { addedRoofsState, basicSettingState, selectedRoofMaterialSelector, settingModalFirstOptionsState } from '@/store/settingAtom'
|
||||||
addedRoofsSelector,
|
import { placementShapeDrawingPointsState } from '@/store/placementShapeDrawingAtom'
|
||||||
addedRoofsState,
|
import { commonUtilsState } from '@/store/commonUtilsAtom'
|
||||||
basicSettingState,
|
import { menusState, menuTypeState } from '@/store/menuAtom'
|
||||||
roofMaterialsSelector,
|
import { estimateState, floorPlanObjectState } from '@/store/floorPlanObjectAtom'
|
||||||
selectedRoofMaterialSelector,
|
import { pwrGnrSimTypeState } from '@/store/simulatorAtom'
|
||||||
settingModalFirstOptionsState,
|
import { isObjectNotEmpty } from '@/util/common-utils'
|
||||||
} from '@/store/settingAtom'
|
|
||||||
|
|
||||||
import KO from '@/locales/ko.json'
|
import KO from '@/locales/ko.json'
|
||||||
import JA from '@/locales/ja.json'
|
import JA from '@/locales/ja.json'
|
||||||
import { useCanvasEvent } from '@/hooks/useCanvasEvent'
|
|
||||||
import SettingModal01 from '@/components/floor-plan/modal/setting01/SettingModal01'
|
|
||||||
import { usePopup } from '@/hooks/usePopup'
|
|
||||||
import { placementShapeDrawingPointsState } from '@/store/placementShapeDrawingAtom'
|
|
||||||
import PlacementShapeSetting from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting'
|
|
||||||
import { useCommonUtils } from '@/hooks/common/useCommonUtils'
|
|
||||||
|
|
||||||
import { commonUtilsState } from '@/store/commonUtilsAtom'
|
|
||||||
import { menusState, menuTypeState } from '@/store/menuAtom'
|
|
||||||
import useMenu from '@/hooks/common/useMenu'
|
|
||||||
import { MENU } from '@/common/common'
|
import { MENU } from '@/common/common'
|
||||||
|
|
||||||
import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController'
|
|
||||||
import { estimateState, floorPlanObjectState } from '@/store/floorPlanObjectAtom'
|
|
||||||
import DocDownOptionPop from '../estimate/popup/DocDownOptionPop'
|
|
||||||
import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
|
|
||||||
import EstimateCopyPop from '../estimate/popup/EstimateCopyPop'
|
|
||||||
import { pwrGnrSimTypeState } from '@/store/simulatorAtom'
|
|
||||||
import { useAxios } from '@/hooks/useAxios'
|
|
||||||
|
|
||||||
import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting'
|
|
||||||
import { isObjectNotEmpty } from '@/util/common-utils'
|
|
||||||
|
|
||||||
export default function CanvasMenu(props) {
|
export default function CanvasMenu(props) {
|
||||||
const { menuNumber, setMenuNumber } = props
|
const { menuNumber, setMenuNumber } = props
|
||||||
const pathname = usePathname()
|
const pathname = usePathname()
|
||||||
@ -58,8 +51,8 @@ export default function CanvasMenu(props) {
|
|||||||
const canvasMenus = useRecoilValue(menusState)
|
const canvasMenus = useRecoilValue(menusState)
|
||||||
const [type, setType] = useRecoilState(menuTypeState)
|
const [type, setType] = useRecoilState(menuTypeState)
|
||||||
const [verticalHorizontalMode, setVerticalHorizontalMode] = useRecoilState(verticalHorizontalModeState)
|
const [verticalHorizontalMode, setVerticalHorizontalMode] = useRecoilState(verticalHorizontalModeState)
|
||||||
const [appMessageState, setAppMessageState] = useRecoilState(appMessageStore)
|
const setAppMessageState = useSetRecoilState(appMessageStore)
|
||||||
const [currentMenu, setCurrentMenu] = useRecoilState(currentMenuState)
|
const setCurrentMenu = useSetRecoilState(currentMenuState)
|
||||||
const setOuterLinePoints = useSetRecoilState(outerLinePointsState)
|
const setOuterLinePoints = useSetRecoilState(outerLinePointsState)
|
||||||
const setPlacementPoints = useSetRecoilState(placementShapeDrawingPointsState)
|
const setPlacementPoints = useSetRecoilState(placementShapeDrawingPointsState)
|
||||||
const canvasSetting = useRecoilValue(canvasSettingState)
|
const canvasSetting = useRecoilValue(canvasSettingState)
|
||||||
@ -86,7 +79,7 @@ export default function CanvasMenu(props) {
|
|||||||
const { floorPlanState, setFloorPlanState } = useContext(FloorPlanContext)
|
const { floorPlanState, setFloorPlanState } = useContext(FloorPlanContext)
|
||||||
const { restoreModuleInstArea } = useModuleBasicSetting()
|
const { restoreModuleInstArea } = useModuleBasicSetting()
|
||||||
|
|
||||||
const addedRoofs = useRecoilValue(addedRoofsState)
|
const [addedRoofs, setAddedRoofsState] = useRecoilState(addedRoofsState)
|
||||||
const [basicSetting, setBasicSetting] = useRecoilState(basicSettingState)
|
const [basicSetting, setBasicSetting] = useRecoilState(basicSettingState)
|
||||||
const selectedRoofMaterial = useRecoilValue(selectedRoofMaterialSelector)
|
const selectedRoofMaterial = useRecoilValue(selectedRoofMaterialSelector)
|
||||||
|
|
||||||
@ -123,15 +116,18 @@ export default function CanvasMenu(props) {
|
|||||||
if (pathname !== '/floor-plan') router.push('/floor-plan')
|
if (pathname !== '/floor-plan') router.push('/floor-plan')
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
console.log('addedRoofs', addedRoofs)
|
|
||||||
}, [addedRoofs])
|
|
||||||
useEffect(() => {
|
|
||||||
console.log('selectedRoofMaterial', selectedRoofMaterial)
|
|
||||||
}, [selectedRoofMaterial])
|
|
||||||
|
|
||||||
const changeSelectedRoofMaterial = (e) => {
|
const changeSelectedRoofMaterial = (e) => {
|
||||||
setBasicSetting({ ...basicSetting, selectedRoofMaterial: e })
|
setBasicSetting({ ...basicSetting, selectedRoofMaterial: e })
|
||||||
|
|
||||||
|
const newAddedRoofs = addedRoofs.map((roof) => {
|
||||||
|
if (roof.index === e.index) {
|
||||||
|
return { ...roof, selected: true }
|
||||||
|
} else {
|
||||||
|
return { ...roof, selected: false }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
setAddedRoofsState(newAddedRoofs)
|
||||||
}
|
}
|
||||||
|
|
||||||
const settingsModalOptions = useRecoilState(settingModalFirstOptionsState)
|
const settingsModalOptions = useRecoilState(settingModalFirstOptionsState)
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useContext, useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
//import { useRecoilState } from 'recoil'
|
//import { useRecoilState } from 'recoil'
|
||||||
import CanvasMenu from '@/components/floor-plan/CanvasMenu'
|
import CanvasMenu from '@/components/floor-plan/CanvasMenu'
|
||||||
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
|
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
|
import { useEffect } from 'react'
|
||||||
|
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import useMenu from '@/hooks/common/useMenu'
|
||||||
import { canvasState, currentMenuState } from '@/store/canvasAtom'
|
import { canvasState, currentMenuState } from '@/store/canvasAtom'
|
||||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||||
import { menuTypeState, subMenusState } from '@/store/menuAtom'
|
import { menuTypeState, subMenusState } from '@/store/menuAtom'
|
||||||
import useMenu from '@/hooks/common/useMenu'
|
|
||||||
import { useEffect } from 'react'
|
|
||||||
|
|
||||||
export default function MenuDepth01() {
|
export default function MenuDepth01() {
|
||||||
const type = useRecoilValue(menuTypeState)
|
const type = useRecoilValue(menuTypeState)
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
|
||||||
import { useRecoilState, useSetRecoilState } from 'recoil'
|
import { useRecoilState, useSetRecoilState } from 'recoil'
|
||||||
import { currentMenuState } from '@/store/canvasAtom'
|
|
||||||
import { MENU } from '@/common/common'
|
import { MENU } from '@/common/common'
|
||||||
import { modalState } from '@/store/modalAtom'
|
|
||||||
import { ToggleonMouse } from '@/components/header/Header'
|
import { ToggleonMouse } from '@/components/header/Header'
|
||||||
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import { currentMenuState } from '@/store/canvasAtom'
|
||||||
|
import { modalState } from '@/store/modalAtom'
|
||||||
|
|
||||||
export default function RoofCoveringMenu() {
|
export default function RoofCoveringMenu() {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
|
|||||||
@ -9,15 +9,27 @@ import { deepCopyArray } from '@/util/common-utils'
|
|||||||
import { canvasState } from '@/store/canvasAtom'
|
import { canvasState } from '@/store/canvasAtom'
|
||||||
import * as turf from '@turf/turf'
|
import * as turf from '@turf/turf'
|
||||||
import { POLYGON_TYPE } from '@/common/common'
|
import { POLYGON_TYPE } from '@/common/common'
|
||||||
|
import { useModal } from '@nextui-org/react'
|
||||||
|
import { useModule } from '@/hooks/module/useModule'
|
||||||
|
|
||||||
|
export const PANEL_EDIT_TYPE = {
|
||||||
|
MOVE: 'move',
|
||||||
|
COPY: 'copy',
|
||||||
|
COLUMN_MOVE: 'columnMove',
|
||||||
|
COLUMN_COPY: 'columnCopy',
|
||||||
|
ROW_MOVE: 'rowMove',
|
||||||
|
ROW_COPY: 'rowCopy',
|
||||||
|
}
|
||||||
|
|
||||||
export default function PanelEdit(props) {
|
export default function PanelEdit(props) {
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
const { id, pos = contextPopupPosition, type = 'move', apply } = props
|
const { id, pos = contextPopupPosition, type = PANEL_EDIT_TYPE.MOVE, apply } = props
|
||||||
const { closePopup } = usePopup()
|
const { closePopup } = usePopup()
|
||||||
const [length, setLength] = useState(0)
|
const [length, setLength] = useState(0)
|
||||||
const [direction, setDirection] = useState('up')
|
const [direction, setDirection] = useState('up')
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
const canvas = useRecoilValue(canvasState)
|
const canvas = useRecoilValue(canvasState)
|
||||||
|
const { moduleMove, moduleCopy, moduleMultiMove, moduleMultiCopy } = useModule()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (canvas) {
|
if (canvas) {
|
||||||
@ -28,7 +40,20 @@ export default function PanelEdit(props) {
|
|||||||
|
|
||||||
//모듈 이동 적용
|
//모듈 이동 적용
|
||||||
const handleApply = () => {
|
const handleApply = () => {
|
||||||
contextModuleMove(length, direction)
|
// const activeModuleIds = canvas.getActiveObjects().map((obj) => obj.id)
|
||||||
|
if (type === PANEL_EDIT_TYPE.MOVE) {
|
||||||
|
moduleMove(length, direction)
|
||||||
|
} else if (type === PANEL_EDIT_TYPE.COPY) {
|
||||||
|
moduleCopy(length, direction)
|
||||||
|
} else if (type === PANEL_EDIT_TYPE.COLUMN_MOVE) {
|
||||||
|
moduleMultiMove('column', length, direction)
|
||||||
|
} else if (type === PANEL_EDIT_TYPE.COLUMN_COPY) {
|
||||||
|
moduleMultiCopy('column', length, direction)
|
||||||
|
} else if (type === PANEL_EDIT_TYPE.ROW_MOVE) {
|
||||||
|
moduleMultiMove('row', length, direction)
|
||||||
|
} else if (type === PANEL_EDIT_TYPE.ROW_COPY) {
|
||||||
|
moduleMultiCopy('row', length, direction)
|
||||||
|
}
|
||||||
closePopup(id)
|
closePopup(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,20 +5,22 @@ import { usePopup } from '@/hooks/usePopup'
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import Image from 'next/image'
|
import Image from 'next/image'
|
||||||
|
import { MODULE_INSERT_TYPE, useModule } from '@/hooks/module/useModule'
|
||||||
|
|
||||||
export default function ColumnInsert(props) {
|
export default function ColumnInsert(props) {
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
const { id, pos = contextPopupPosition, apply } = props
|
const { id, pos = contextPopupPosition, apply } = props
|
||||||
const { closePopup } = usePopup()
|
const { closePopup } = usePopup()
|
||||||
const [selectedType, setSelectedType] = useState(1)
|
const [selectedType, setSelectedType] = useState(MODULE_INSERT_TYPE.LEFT)
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
|
const { moduleColumnInsert } = useModule()
|
||||||
const handleApply = () => {
|
const handleApply = () => {
|
||||||
if (apply) apply()
|
moduleColumnInsert(selectedType)
|
||||||
closePopup(id)
|
closePopup(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
const HandleRadioChange = (e) => {
|
const handleRadioChange = (e) => {
|
||||||
setSelectedType(Number(e.target.value))
|
setSelectedType(e.target.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -36,16 +38,30 @@ export default function ColumnInsert(props) {
|
|||||||
<div className="additional-wrap">
|
<div className="additional-wrap">
|
||||||
<div className="additional-radio-wrap">
|
<div className="additional-radio-wrap">
|
||||||
<div className="d-check-radio pop">
|
<div className="d-check-radio pop">
|
||||||
<input type="radio" name="radio01" id="ra01" onChange={HandleRadioChange} value={1} checked={selectedType === 1} />
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="radio01"
|
||||||
|
id="ra01"
|
||||||
|
onChange={handleRadioChange}
|
||||||
|
value={MODULE_INSERT_TYPE.LEFT}
|
||||||
|
checked={selectedType === MODULE_INSERT_TYPE.LEFT}
|
||||||
|
/>
|
||||||
<label htmlFor="ra01">{getMessage('modal.panel.column.insert.type.left')}</label>
|
<label htmlFor="ra01">{getMessage('modal.panel.column.insert.type.left')}</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="d-check-radio pop">
|
<div className="d-check-radio pop">
|
||||||
<input type="radio" name="radio01" id="ra02" onChange={HandleRadioChange} value={2} checked={selectedType === 2} />
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="radio01"
|
||||||
|
id="ra02"
|
||||||
|
onChange={handleRadioChange}
|
||||||
|
value={MODULE_INSERT_TYPE.RIGHT}
|
||||||
|
checked={selectedType === MODULE_INSERT_TYPE.RIGHT}
|
||||||
|
/>
|
||||||
<label htmlFor="ra02">{getMessage('modal.panel.column.insert.type.right')}</label>
|
<label htmlFor="ra02">{getMessage('modal.panel.column.insert.type.right')}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="additional-img-wrap">
|
<div className="additional-img-wrap">
|
||||||
{selectedType === 1 && (
|
{selectedType === MODULE_INSERT_TYPE.LEFT && (
|
||||||
<Image
|
<Image
|
||||||
src="/static/images/canvas/additional-edit01.svg"
|
src="/static/images/canvas/additional-edit01.svg"
|
||||||
alt="react"
|
alt="react"
|
||||||
@ -54,7 +70,7 @@ export default function ColumnInsert(props) {
|
|||||||
style={{ width: 'auto', height: 'auto' }}
|
style={{ width: 'auto', height: 'auto' }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{selectedType === 2 && (
|
{selectedType === MODULE_INSERT_TYPE.RIGHT && (
|
||||||
<Image
|
<Image
|
||||||
src="/static/images/canvas/additional-edit02.svg"
|
src="/static/images/canvas/additional-edit02.svg"
|
||||||
alt="react"
|
alt="react"
|
||||||
|
|||||||
@ -5,21 +5,24 @@ import { usePopup } from '@/hooks/usePopup'
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import Image from 'next/image'
|
import Image from 'next/image'
|
||||||
|
import { MODULE_REMOVE_TYPE, useModule } from '@/hooks/module/useModule'
|
||||||
|
|
||||||
export default function ColumnRemove(props) {
|
export default function ColumnRemove(props) {
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
const { id, pos = contextPopupPosition, apply } = props
|
const { id, pos = contextPopupPosition, apply } = props
|
||||||
const { closePopup } = usePopup()
|
const { closePopup } = usePopup()
|
||||||
const [selectedType, setSelectedType] = useState(1)
|
const [selectedType, setSelectedType] = useState(MODULE_REMOVE_TYPE.LEFT)
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
|
const { moduleColumnRemove } = useModule()
|
||||||
const types = [
|
const types = [
|
||||||
{ name: getMessage('modal.panel.column.remove.type.left'), value: 1 },
|
{ name: getMessage('modal.panel.column.remove.type.left'), value: MODULE_REMOVE_TYPE.LEFT },
|
||||||
{ name: getMessage('modal.panel.column.remove.type.right'), value: 2 },
|
{ name: getMessage('modal.panel.column.remove.type.right'), value: MODULE_REMOVE_TYPE.RIGHT },
|
||||||
{ name: getMessage('modal.panel.column.remove.type.side'), value: 3 },
|
{ name: getMessage('modal.panel.column.remove.type.side'), value: MODULE_REMOVE_TYPE.HORIZONTAL_SIDE },
|
||||||
{ name: getMessage('modal.panel.column.remove.type.none'), value: 4 },
|
{ name: getMessage('modal.panel.column.remove.type.none'), value: MODULE_REMOVE_TYPE.NONE },
|
||||||
]
|
]
|
||||||
const handleApply = () => {
|
const handleApply = () => {
|
||||||
if (apply) apply()
|
// if (apply) apply()
|
||||||
|
moduleColumnRemove(selectedType)
|
||||||
closePopup(id)
|
closePopup(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,12 +42,12 @@ export default function ColumnRemove(props) {
|
|||||||
<div className="additional-radio-wrap">
|
<div className="additional-radio-wrap">
|
||||||
{types.map((type, index) => {
|
{types.map((type, index) => {
|
||||||
return (
|
return (
|
||||||
<div className="d-check-radio pop">
|
<div className="d-check-radio pop" key={index}>
|
||||||
<input
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
name="radio01"
|
name="radio01"
|
||||||
id={`ra0${index + 1}`}
|
id={`ra0${index + 1}`}
|
||||||
onClick={(e) => setSelectedType(Number(e.target.value))}
|
onClick={(e) => setSelectedType(e.target.value)}
|
||||||
value={type.value}
|
value={type.value}
|
||||||
checked={selectedType === type.value}
|
checked={selectedType === type.value}
|
||||||
/>
|
/>
|
||||||
@ -54,7 +57,7 @@ export default function ColumnRemove(props) {
|
|||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
<div className="additional-img-wrap">
|
<div className="additional-img-wrap">
|
||||||
{selectedType === 1 && (
|
{selectedType === MODULE_REMOVE_TYPE.LEFT && (
|
||||||
<Image
|
<Image
|
||||||
src="/static/images/canvas/additional_del01.svg"
|
src="/static/images/canvas/additional_del01.svg"
|
||||||
alt="react"
|
alt="react"
|
||||||
@ -63,7 +66,7 @@ export default function ColumnRemove(props) {
|
|||||||
style={{ width: 'auto', height: 'auto' }}
|
style={{ width: 'auto', height: 'auto' }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{selectedType === 2 && (
|
{selectedType === MODULE_REMOVE_TYPE.RIGHT && (
|
||||||
<Image
|
<Image
|
||||||
src="/static/images/canvas/additional_del02.svg"
|
src="/static/images/canvas/additional_del02.svg"
|
||||||
alt="react"
|
alt="react"
|
||||||
@ -72,7 +75,7 @@ export default function ColumnRemove(props) {
|
|||||||
style={{ width: 'auto', height: 'auto' }}
|
style={{ width: 'auto', height: 'auto' }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{selectedType === 3 && (
|
{selectedType === MODULE_REMOVE_TYPE.HORIZONTAL_SIDE && (
|
||||||
<Image
|
<Image
|
||||||
src="/static/images/canvas/additional_del03.svg"
|
src="/static/images/canvas/additional_del03.svg"
|
||||||
alt="react"
|
alt="react"
|
||||||
@ -81,7 +84,7 @@ export default function ColumnRemove(props) {
|
|||||||
style={{ width: 'auto', height: 'auto' }}
|
style={{ width: 'auto', height: 'auto' }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{selectedType === 4 && (
|
{selectedType === MODULE_REMOVE_TYPE.NONE && (
|
||||||
<Image
|
<Image
|
||||||
src="/static/images/canvas/additional_del04.svg"
|
src="/static/images/canvas/additional_del04.svg"
|
||||||
alt="react"
|
alt="react"
|
||||||
|
|||||||
@ -5,20 +5,22 @@ import { useRecoilValue } from 'recoil'
|
|||||||
import { contextPopupPositionState } from '@/store/popupAtom'
|
import { contextPopupPositionState } from '@/store/popupAtom'
|
||||||
import { usePopup } from '@/hooks/usePopup'
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import { MODULE_INSERT_TYPE, useModule } from '@/hooks/module/useModule'
|
||||||
|
|
||||||
export default function RowInsert(props) {
|
export default function RowInsert(props) {
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
const { id, pos = contextPopupPosition, apply } = props
|
const { id, pos = contextPopupPosition, apply } = props
|
||||||
const { closePopup } = usePopup()
|
const { closePopup } = usePopup()
|
||||||
const [selectedType, setSelectedType] = useState(1)
|
const [selectedType, setSelectedType] = useState(MODULE_INSERT_TYPE.TOP)
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
|
const { muduleRowInsert } = useModule()
|
||||||
const handleApply = () => {
|
const handleApply = () => {
|
||||||
if (apply) apply()
|
muduleRowInsert(selectedType)
|
||||||
closePopup(id)
|
closePopup(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
const HandleRadioChange = (e) => {
|
const HandleRadioChange = (e) => {
|
||||||
setSelectedType(Number(e.target.value))
|
setSelectedType(e.target.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -36,16 +38,30 @@ export default function RowInsert(props) {
|
|||||||
<div className="additional-wrap">
|
<div className="additional-wrap">
|
||||||
<div className="additional-radio-wrap">
|
<div className="additional-radio-wrap">
|
||||||
<div className="d-check-radio pop">
|
<div className="d-check-radio pop">
|
||||||
<input type="radio" name="radio01" id="ra01" onChange={HandleRadioChange} value={1} checked={selectedType === 1} />
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="radio01"
|
||||||
|
id="ra01"
|
||||||
|
onChange={HandleRadioChange}
|
||||||
|
value={MODULE_INSERT_TYPE.TOP}
|
||||||
|
checked={selectedType === MODULE_INSERT_TYPE.TOP}
|
||||||
|
/>
|
||||||
<label htmlFor="ra01">{getMessage('modal.row.insert.type.up')}</label>
|
<label htmlFor="ra01">{getMessage('modal.row.insert.type.up')}</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="d-check-radio pop">
|
<div className="d-check-radio pop">
|
||||||
<input type="radio" name="radio01" id="ra02" onChange={HandleRadioChange} value={2} checked={selectedType === 2} />
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="radio01"
|
||||||
|
id="ra02"
|
||||||
|
onChange={HandleRadioChange}
|
||||||
|
value={MODULE_INSERT_TYPE.BOTTOM}
|
||||||
|
checked={selectedType === MODULE_INSERT_TYPE.BOTTOM}
|
||||||
|
/>
|
||||||
<label htmlFor="ra02">{getMessage('modal.row.insert.type.down')}</label>
|
<label htmlFor="ra02">{getMessage('modal.row.insert.type.down')}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="additional-img-wrap">
|
<div className="additional-img-wrap">
|
||||||
{selectedType === 1 && (
|
{selectedType === MODULE_INSERT_TYPE.TOP && (
|
||||||
<Image
|
<Image
|
||||||
src="/static/images/canvas/additional_bundle-edit01.svg"
|
src="/static/images/canvas/additional_bundle-edit01.svg"
|
||||||
alt="react"
|
alt="react"
|
||||||
@ -54,7 +70,7 @@ export default function RowInsert(props) {
|
|||||||
style={{ width: 'auto', height: 'auto' }}
|
style={{ width: 'auto', height: 'auto' }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{selectedType === 2 && (
|
{selectedType === MODULE_INSERT_TYPE.BOTTOM && (
|
||||||
<Image
|
<Image
|
||||||
src="/static/images/canvas/additional_bundle-edit02.svg"
|
src="/static/images/canvas/additional_bundle-edit02.svg"
|
||||||
alt="react"
|
alt="react"
|
||||||
|
|||||||
@ -5,21 +5,24 @@ import { useRecoilValue } from 'recoil'
|
|||||||
import { contextPopupPositionState } from '@/store/popupAtom'
|
import { contextPopupPositionState } from '@/store/popupAtom'
|
||||||
import { usePopup } from '@/hooks/usePopup'
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import { MODULE_REMOVE_TYPE, useModule } from '@/hooks/module/useModule'
|
||||||
|
|
||||||
export default function RowRemove(props) {
|
export default function RowRemove(props) {
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
const { id, pos = contextPopupPosition, apply } = props
|
const { id, pos = contextPopupPosition, apply } = props
|
||||||
const { closePopup } = usePopup()
|
const { closePopup } = usePopup()
|
||||||
const [selectedType, setSelectedType] = useState(1)
|
const [selectedType, setSelectedType] = useState(MODULE_REMOVE_TYPE.TOP)
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
|
const { moduleRowRemove } = useModule()
|
||||||
const types = [
|
const types = [
|
||||||
{ name: getMessage('modal.row.remove.type.up'), value: 1 },
|
{ name: getMessage('modal.row.remove.type.up'), value: MODULE_REMOVE_TYPE.TOP },
|
||||||
{ name: getMessage('modal.row.remove.type.down'), value: 2 },
|
{ name: getMessage('modal.row.remove.type.down'), value: MODULE_REMOVE_TYPE.BOTTOM },
|
||||||
{ name: getMessage('modal.row.remove.type.side'), value: 3 },
|
{ name: getMessage('modal.row.remove.type.side'), value: MODULE_REMOVE_TYPE.VERTICAL_SIDE },
|
||||||
{ name: getMessage('modal.row.remove.type.none'), value: 4 },
|
{ name: getMessage('modal.row.remove.type.none'), value: MODULE_REMOVE_TYPE.NONE },
|
||||||
]
|
]
|
||||||
const handleApply = () => {
|
const handleApply = () => {
|
||||||
if (apply) apply()
|
// if (apply) apply()
|
||||||
|
moduleRowRemove(selectedType)
|
||||||
closePopup(id)
|
closePopup(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,22 +42,22 @@ export default function RowRemove(props) {
|
|||||||
<div className="additional-radio-wrap">
|
<div className="additional-radio-wrap">
|
||||||
{types.map((type, index) => {
|
{types.map((type, index) => {
|
||||||
return (
|
return (
|
||||||
<div className="d-check-radio pop">
|
<div className="d-check-radio pop" key={index}>
|
||||||
<input
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
name="radio01"
|
name="radio01"
|
||||||
id={`ra0${index + 1}`}
|
id={`ra0${index + 1}`}
|
||||||
onClick={() => setSelectedType(Number(e.target.value))}
|
onClick={(e) => setSelectedType(e.target.value)}
|
||||||
value={type.value}
|
value={type.value}
|
||||||
checked={selectedType === type.value}
|
checked={selectedType === type.value}
|
||||||
/>
|
/>
|
||||||
<label htmlFor="ra01">{getMessage(type.name)}</label>
|
<label htmlFor={`ra0${index + 1}`}>{type.name}</label>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
<div className="additional-img-wrap">
|
<div className="additional-img-wrap">
|
||||||
{selectedType === 1 && (
|
{selectedType === MODULE_REMOVE_TYPE.TOP && (
|
||||||
<Image
|
<Image
|
||||||
src="/static/images/canvas/additional_bundle-del01.svg"
|
src="/static/images/canvas/additional_bundle-del01.svg"
|
||||||
alt="react"
|
alt="react"
|
||||||
@ -63,7 +66,7 @@ export default function RowRemove(props) {
|
|||||||
style={{ width: 'auto', height: 'auto' }}
|
style={{ width: 'auto', height: 'auto' }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{selectedType === 2 && (
|
{selectedType === MODULE_REMOVE_TYPE.BOTTOM && (
|
||||||
<Image
|
<Image
|
||||||
src="/static/images/canvas/additional_bundle-del02.svg"
|
src="/static/images/canvas/additional_bundle-del02.svg"
|
||||||
alt="react"
|
alt="react"
|
||||||
@ -72,7 +75,7 @@ export default function RowRemove(props) {
|
|||||||
style={{ width: 'auto', height: 'auto' }}
|
style={{ width: 'auto', height: 'auto' }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{selectedType === 3 && (
|
{selectedType === MODULE_REMOVE_TYPE.VERTICAL_SIDE && (
|
||||||
<Image
|
<Image
|
||||||
src="/static/images/canvas/additional_bundle-del03.svg"
|
src="/static/images/canvas/additional_bundle-del03.svg"
|
||||||
alt="react"
|
alt="react"
|
||||||
@ -81,7 +84,7 @@ export default function RowRemove(props) {
|
|||||||
style={{ width: 'auto', height: 'auto' }}
|
style={{ width: 'auto', height: 'auto' }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{selectedType === 4 && (
|
{selectedType === MODULE_REMOVE_TYPE.NONE && (
|
||||||
<Image
|
<Image
|
||||||
src="/static/images/canvas/additional_bundle-del04.svg"
|
src="/static/images/canvas/additional_bundle-del04.svg"
|
||||||
alt="react"
|
alt="react"
|
||||||
|
|||||||
@ -247,6 +247,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set
|
|||||||
sourceKey="id"
|
sourceKey="id"
|
||||||
targetKey="id"
|
targetKey="id"
|
||||||
showKey="name"
|
showKey="name"
|
||||||
|
disabled={basicSetting.roofSizeSet === '3'}
|
||||||
/>
|
/>
|
||||||
{/* <select
|
{/* <select
|
||||||
className="select-light dark"
|
className="select-light dark"
|
||||||
@ -324,6 +325,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set
|
|||||||
sourceKey="clCode"
|
sourceKey="clCode"
|
||||||
targetKey={currentRoofMaterial.raft ? 'raft' : 'raftBaseCd'}
|
targetKey={currentRoofMaterial.raft ? 'raft' : 'raftBaseCd'}
|
||||||
showKey="clCodeNm"
|
showKey="clCodeNm"
|
||||||
|
disabled={basicSetting.roofSizeSet === '3'}
|
||||||
/>
|
/>
|
||||||
{/* <select className="select-light dark" name="roofGap" ref={roofRef.rafter}>
|
{/* <select className="select-light dark" name="roofGap" ref={roofRef.rafter}>
|
||||||
{raftCodes.map((raft, index) => {
|
{raftCodes.map((raft, index) => {
|
||||||
|
|||||||
@ -28,6 +28,7 @@ export default function ContextRoofAllocationSetting(props) {
|
|||||||
handleChangeRaft,
|
handleChangeRaft,
|
||||||
handleChangeLayout,
|
handleChangeLayout,
|
||||||
handleSaveContext,
|
handleSaveContext,
|
||||||
|
currentRoofList,
|
||||||
} = useRoofAllocationSetting(id)
|
} = useRoofAllocationSetting(id)
|
||||||
|
|
||||||
const { findCommonCode } = useCommonCode()
|
const { findCommonCode } = useCommonCode()
|
||||||
@ -39,7 +40,7 @@ export default function ContextRoofAllocationSetting(props) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<WithDraggable isShow={true} pos={pos}>
|
<WithDraggable isShow={true} pos={pos}>
|
||||||
<div className={`modal-pop-wrap ml mount`}>
|
<div className={`modal-pop-wrap lr mount`}>
|
||||||
<div className="modal-head">
|
<div className="modal-head">
|
||||||
<h1 className="title">{getMessage('plan.menu.estimate.roof.alloc')}</h1>
|
<h1 className="title">{getMessage('plan.menu.estimate.roof.alloc')}</h1>
|
||||||
<button className="modal-close" onClick={() => closePopup(id)}>
|
<button className="modal-close" onClick={() => closePopup(id)}>
|
||||||
@ -53,10 +54,14 @@ export default function ContextRoofAllocationSetting(props) {
|
|||||||
<div className="grid-select">
|
<div className="grid-select">
|
||||||
<QSelectBox
|
<QSelectBox
|
||||||
options={roofMaterials}
|
options={roofMaterials}
|
||||||
|
value={roofMaterials[0]}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const selected = roofMaterials.find((roofMaterial) => roofMaterial.roofMatlCd === e.id)
|
// const selected = roofMaterials.find((roofMaterial) => roofMaterial.roofMatlCd === e.id)
|
||||||
setCurrentRoofMaterial(selected)
|
setCurrentRoofMaterial(e)
|
||||||
}}
|
}}
|
||||||
|
showKey={'roofMatlNm'}
|
||||||
|
sourceKey={'roofMatlCd'}
|
||||||
|
targetKey={'roofMatlCd'}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
@ -70,7 +75,7 @@ export default function ContextRoofAllocationSetting(props) {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid-option-wrap">
|
<div className="grid-option-wrap">
|
||||||
{roofList.map((roof, index) => {
|
{currentRoofList.map((roof, index) => {
|
||||||
return (
|
return (
|
||||||
<div className="grid-option-box" key={index}>
|
<div className="grid-option-box" key={index}>
|
||||||
<div className="d-check-radio pop no-text">
|
<div className="d-check-radio pop no-text">
|
||||||
@ -88,78 +93,74 @@ export default function ContextRoofAllocationSetting(props) {
|
|||||||
<div className="grid-select" style={{ width: '248px' }}>
|
<div className="grid-select" style={{ width: '248px' }}>
|
||||||
<QSelectBox
|
<QSelectBox
|
||||||
options={roofMaterials}
|
options={roofMaterials}
|
||||||
value={roofMaterials.find((r) => r.id === roof.id)}
|
value={roof}
|
||||||
|
showKey={'roofMatlNm'}
|
||||||
|
sourceKey={'roofMatlCd'}
|
||||||
|
targetKey={'roofMatlCd'}
|
||||||
onChange={(e) => handleChangeRoofMaterial(e, index)}
|
onChange={(e) => handleChangeRoofMaterial(e, index)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{index === 0 && <span className="dec">基本屋根材</span>}
|
{index === 0 && <span className="dec">{getMessage('modal.roof.alloc.default.roof.material')}</span>}
|
||||||
{index !== 0 && <button className="delete" onClick={() => onDeleteRoofMaterial(index)}></button>}
|
{index !== 0 && <button className="delete" onClick={() => onDeleteRoofMaterial(index)}></button>}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="block-box">
|
{(roof.widAuth || roof.lenAuth) && (
|
||||||
{roof.widAuth && (
|
<div className="block-box">
|
||||||
<div className="flex-ment">
|
{roof.widAuth && (
|
||||||
<span>W</span>
|
<div className="flex-ment">
|
||||||
<div className="input-grid" style={{ width: '100px' }}>
|
<span>W</span>
|
||||||
<input type="text" className="input-origin block" defaultValue={roof.width} readOnly />
|
<div className="input-grid" style={{ width: '100px' }}>
|
||||||
|
<input type="text" className="input-origin block" defaultValue={roof.width} readOnly={roof.widAuth === 'R'} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* <div className="select-wrap" style={{ width: '84px' }}>
|
)}
|
||||||
<select className="select-light dark" name="" id="">
|
{roof.lenAuth && (
|
||||||
<option>265</option>
|
<div className="flex-ment">
|
||||||
</select>
|
<span>L</span>
|
||||||
</div> */}
|
<div className="input-grid" style={{ width: '100px' }}>
|
||||||
</div>
|
<input type="text" className="input-origin block" defaultValue={roof.length} readOnly={roof.lenAuth === 'R'} />
|
||||||
)}
|
</div>
|
||||||
{roof.lenAuth && (
|
|
||||||
<div className="flex-ment">
|
|
||||||
<span>L</span>
|
|
||||||
<div className="input-grid" style={{ width: '100px' }}>
|
|
||||||
<input type="text" className="input-origin block" defaultValue={roof.length} readOnly />
|
|
||||||
</div>
|
</div>
|
||||||
{/* <div className="select-wrap" style={{ width: '84px' }}>
|
)}
|
||||||
<select className="select-light dark" name="" id="">
|
</div>
|
||||||
<option>235</option>
|
)}
|
||||||
</select>
|
{(roof.raftAuth || roof.roofPchAuth) && (
|
||||||
</div> */}
|
<div className="block-box">
|
||||||
</div>
|
{roof.raftAuth && (
|
||||||
)}
|
<div className="block-box">
|
||||||
{roof.raftAuth && (
|
<div className="flex-ment">
|
||||||
<div className="flex-ment">
|
<span>{getMessage('modal.placement.initial.setting.rafter')}</span>
|
||||||
<span>{getMessage('modal.placement.initial.setting.rafter')}</span>
|
{raftCodes.length > 0 && (
|
||||||
<div className="grid-select" style={{ width: '84px' }}>
|
<div className="grid-select" style={{ width: '160px' }}>
|
||||||
{raftCodes.length > 0 && (
|
<QSelectBox
|
||||||
<QSelectBox
|
options={raftCodes}
|
||||||
options={raftCodes.map((raft) => ({ name: raft.clCodeNm, value: raft.clCode }))}
|
value={roof}
|
||||||
onChange={(e) => handleChangeRaft(e, index)}
|
showKey={'clCodeNm'}
|
||||||
value={raftCodes.find((r) => r.value === roof.raft)}
|
sourceKey={'clCode'}
|
||||||
/>
|
targetKey={roof.raft ? 'raft' : 'raftBaseCd'}
|
||||||
)}
|
/>
|
||||||
{/* <select className="select-light dark" name="roofGap" ref={roofRef.rafter}>
|
</div>
|
||||||
{raftCodes.map((raft, index) => {
|
)}
|
||||||
return (
|
</div>
|
||||||
<option key={index} value={raft.clCode}>
|
|
||||||
{raft.clCodeNm}
|
|
||||||
</option>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</select> */}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)}
|
||||||
)}
|
{roof.roofPchAuth && (
|
||||||
{roof.roofPchAuth && (
|
<div className="block-box">
|
||||||
<div className="flex-ment">
|
<div className="flex-ment">
|
||||||
<span>{getMessage('hajebichi')}</span>
|
<span>{getMessage('hajebichi')}</span>
|
||||||
<div className="input-grid" style={{ width: '84px' }}>
|
<div className="input-grid" style={{ width: '84px' }}>
|
||||||
<input type="text" className="input-origin block" value={parseInt(roof.hajebichi)} readOnly={roof.roofPchAuth === 'R'} />
|
<input
|
||||||
|
type="text"
|
||||||
|
className="input-origin block"
|
||||||
|
value={parseInt(roof.hajebichi)}
|
||||||
|
readOnly={roof.roofPchAuth === 'R'}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* <div className="grid-select no-flx" style={{ width: '84px' }}>
|
)}
|
||||||
<select className="select-light dark" name="" id="">
|
</div>
|
||||||
<option>265</option>
|
)}
|
||||||
</select>
|
|
||||||
</div> */}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div className="block-box">
|
<div className="block-box">
|
||||||
<div className="icon-btn-wrap">
|
<div className="icon-btn-wrap">
|
||||||
<button
|
<button
|
||||||
|
|||||||
@ -27,6 +27,7 @@ export default function RoofAllocationSetting(props) {
|
|||||||
handleChangeRoofMaterial,
|
handleChangeRoofMaterial,
|
||||||
handleChangeRaft,
|
handleChangeRaft,
|
||||||
handleChangeLayout,
|
handleChangeLayout,
|
||||||
|
currentRoofList,
|
||||||
} = useRoofAllocationSetting(id)
|
} = useRoofAllocationSetting(id)
|
||||||
const { findCommonCode } = useCommonCode()
|
const { findCommonCode } = useCommonCode()
|
||||||
const [raftCodes, setRaftCodes] = useState([])
|
const [raftCodes, setRaftCodes] = useState([])
|
||||||
@ -73,7 +74,7 @@ export default function RoofAllocationSetting(props) {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid-option-wrap">
|
<div className="grid-option-wrap">
|
||||||
{roofList.map((roof, index) => {
|
{currentRoofList.map((roof, index) => {
|
||||||
return (
|
return (
|
||||||
<div className="grid-option-box" key={index}>
|
<div className="grid-option-box" key={index}>
|
||||||
<div className="d-check-radio pop no-text">
|
<div className="d-check-radio pop no-text">
|
||||||
@ -136,6 +137,7 @@ export default function RoofAllocationSetting(props) {
|
|||||||
showKey={'clCodeNm'}
|
showKey={'clCodeNm'}
|
||||||
sourceKey={'clCode'}
|
sourceKey={'clCode'}
|
||||||
targetKey={roof.raft ? 'raft' : 'raftBaseCd'}
|
targetKey={roof.raft ? 'raft' : 'raftBaseCd'}
|
||||||
|
onChange={(e) => handleChangeRaft(e, index)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
115
src/components/sample/SampleReducer.jsx
Normal file
115
src/components/sample/SampleReducer.jsx
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
import { Card, CardBody, Input, Tab, Tabs } from '@nextui-org/react'
|
||||||
|
import { useEffect, useReducer } from 'react'
|
||||||
|
|
||||||
|
const reducer = (prevState, nextState) => {
|
||||||
|
return { ...prevState, ...nextState }
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultData = {
|
||||||
|
commonData: 'common',
|
||||||
|
tabs: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: 'tab1',
|
||||||
|
range: 10,
|
||||||
|
maker: 'maker1',
|
||||||
|
law: 'law1',
|
||||||
|
basis: 'basis1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: 'tab2',
|
||||||
|
range: 20,
|
||||||
|
maker: 'maker2',
|
||||||
|
law: 'law2',
|
||||||
|
basis: 'basis2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: 'tab3',
|
||||||
|
range: 30,
|
||||||
|
maker: 'maker3',
|
||||||
|
law: 'law3',
|
||||||
|
basis: 'basis3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
name: 'tab4',
|
||||||
|
range: 40,
|
||||||
|
maker: 'maker4',
|
||||||
|
law: 'law4',
|
||||||
|
basis: 'basis4',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function SampleReducer() {
|
||||||
|
const [sampleState, setSampleState] = useReducer(reducer, defaultData)
|
||||||
|
|
||||||
|
const handleChangeTabsData = (newTab) => {
|
||||||
|
const newTabs = sampleState.tabs.map((t) => {
|
||||||
|
if (t.id === newTab.id) {
|
||||||
|
return newTab
|
||||||
|
} else {
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
})
|
||||||
|
setSampleState({ ...sampleState, tabs: newTabs })
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log('🚀 ~ SampleReducer ~ sampleState:', sampleState)
|
||||||
|
}, [sampleState])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div>공통: {sampleState.commonData}</div>
|
||||||
|
<div className="flex w-full flex-col">
|
||||||
|
<Tabs aria-label="Options">
|
||||||
|
{sampleState.tabs.map((s) => (
|
||||||
|
<Tab key={s.id} title={s.name}>
|
||||||
|
<Card>
|
||||||
|
<CardBody>
|
||||||
|
<div className="flex w-full flex-wrap md:flex-nowrap gap-4">
|
||||||
|
<Input
|
||||||
|
label="range"
|
||||||
|
type="text"
|
||||||
|
value={s.range}
|
||||||
|
onChange={(e) => {
|
||||||
|
handleChangeTabsData({ ...s, range: e.target.value })
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
label="maker"
|
||||||
|
type="text"
|
||||||
|
value={s.maker}
|
||||||
|
onChange={(e) => {
|
||||||
|
handleChangeTabsData({ ...s, maker: e.target.value })
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
label="law"
|
||||||
|
type="text"
|
||||||
|
value={s.law}
|
||||||
|
onChange={(e) => {
|
||||||
|
handleChangeTabsData({ ...s, law: e.target.value })
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
label="basis"
|
||||||
|
type="text"
|
||||||
|
value={s.basis}
|
||||||
|
onChange={(e) => {
|
||||||
|
handleChangeTabsData({ ...s, basis: e.target.value })
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
</Tab>
|
||||||
|
))}
|
||||||
|
</Tabs>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -1,11 +1,13 @@
|
|||||||
import { useRecoilValue } from 'recoil'
|
import { useRecoilValue } from 'recoil'
|
||||||
import { canvasState } from '@/store/canvasAtom'
|
import { canvasState, currentObjectState } from '@/store/canvasAtom'
|
||||||
import { selectedRoofMaterialSelector } from '@/store/settingAtom'
|
import { selectedRoofMaterialSelector } from '@/store/settingAtom'
|
||||||
import { ROOF_MATERIAL_LAYOUT } from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting'
|
import { ROOF_MATERIAL_LAYOUT } from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting'
|
||||||
|
import { POLYGON_TYPE } from '@/common/common'
|
||||||
|
|
||||||
export function useRoofFn() {
|
export function useRoofFn() {
|
||||||
const canvas = useRecoilValue(canvasState)
|
const canvas = useRecoilValue(canvasState)
|
||||||
const selectedRoofMaterial = useRecoilValue(selectedRoofMaterialSelector)
|
const selectedRoofMaterial = useRecoilValue(selectedRoofMaterialSelector)
|
||||||
|
const currentObject = useRecoilValue(currentObjectState)
|
||||||
|
|
||||||
//면형상 선택 클릭시 지붕 패턴 입히기
|
//면형상 선택 클릭시 지붕 패턴 입히기
|
||||||
function setSurfaceShapePattern(polygon, mode = 'onlyBorder', trestleMode = false, roofMaterial = selectedRoofMaterial) {
|
function setSurfaceShapePattern(polygon, mode = 'onlyBorder', trestleMode = false, roofMaterial = selectedRoofMaterial) {
|
||||||
@ -141,5 +143,22 @@ export function useRoofFn() {
|
|||||||
polygon.roofMaterial = roofMaterial
|
polygon.roofMaterial = roofMaterial
|
||||||
polygon.canvas?.renderAll()
|
polygon.canvas?.renderAll()
|
||||||
}
|
}
|
||||||
return { setSurfaceShapePattern }
|
|
||||||
|
function removeRoofMaterial(roof = currentObject) {
|
||||||
|
if (roof === null || roof.name !== POLYGON_TYPE.ROOF) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
roof.set('fill', null)
|
||||||
|
roof.roofMaterial = null
|
||||||
|
canvas?.renderAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeAllRoofMaterial() {
|
||||||
|
const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
||||||
|
roofBases.forEach((roofBase) => {
|
||||||
|
removeRoofMaterial(roofBase)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return { setSurfaceShapePattern, removeRoofMaterial, removeAllRoofMaterial }
|
||||||
}
|
}
|
||||||
|
|||||||
833
src/hooks/module/useModule.js
Normal file
833
src/hooks/module/useModule.js
Normal file
@ -0,0 +1,833 @@
|
|||||||
|
import { BATCH_TYPE, POLYGON_TYPE } from '@/common/common'
|
||||||
|
import { canvasState } from '@/store/canvasAtom'
|
||||||
|
import { isOverlap, polygonToTurfPolygon, rectToPolygon } from '@/util/canvas-util'
|
||||||
|
import { useRecoilValue } from 'recoil'
|
||||||
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
|
import * as turf from '@turf/turf'
|
||||||
|
import { useSwal } from '../useSwal'
|
||||||
|
import { QPolygon } from '@/components/fabric/QPolygon'
|
||||||
|
import { useModuleBasicSetting } from './useModuleBasicSetting'
|
||||||
|
|
||||||
|
export const MODULE_REMOVE_TYPE = {
|
||||||
|
LEFT: 'left',
|
||||||
|
RIGHT: 'right',
|
||||||
|
HORIZONTAL_SIDE: 'horizontalSide',
|
||||||
|
TOP: 'top',
|
||||||
|
BOTTOM: 'bottom',
|
||||||
|
VERTICAL_SIDE: 'verticalSide',
|
||||||
|
NONE: 'none',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const MODULE_INSERT_TYPE = {
|
||||||
|
LEFT: 'left',
|
||||||
|
RIGHT: 'right',
|
||||||
|
TOP: 'up',
|
||||||
|
BOTTOM: 'down',
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useModule() {
|
||||||
|
const canvas = useRecoilValue(canvasState)
|
||||||
|
const { swalFire } = useSwal()
|
||||||
|
const { checkModuleDisjointObjects } = useModuleBasicSetting()
|
||||||
|
|
||||||
|
const moduleMove = (length, direction) => {
|
||||||
|
const checkModuleDisjointSurface = (squarePolygon, turfModuleSetupSurface) => {
|
||||||
|
return turf.booleanContains(turfModuleSetupSurface, squarePolygon) || turf.booleanWithin(squarePolygon, turfModuleSetupSurface)
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectedObj = canvas.getActiveObjects() //선택된 객체들을 가져옴
|
||||||
|
const selectedIds = selectedObj.map((obj) => obj.id) // selectedObj의 ID 추출
|
||||||
|
|
||||||
|
canvas.discardActiveObject() //선택해제
|
||||||
|
|
||||||
|
const isSetupModules = canvas.getObjects().filter((obj) => obj.name === 'module' && !selectedIds.includes(obj.id)) // selectedObj에 없는 객체만 필터링
|
||||||
|
const selectedModules = canvas.getObjects().filter((obj) => selectedIds.includes(obj.id) && obj.name === 'module') //선택했던 객체들만 가져옴
|
||||||
|
const setupSurface = canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === selectedModules[0].surfaceId)[0]
|
||||||
|
const isOverlapArray = []
|
||||||
|
const isInSurfaceArray = []
|
||||||
|
const isOverlapObjects = []
|
||||||
|
const objects = getObjects()
|
||||||
|
|
||||||
|
if (selectedModules) {
|
||||||
|
canvas.remove(...selectedModules)
|
||||||
|
selectedModules.forEach((module) => {
|
||||||
|
module.set({
|
||||||
|
originCoords: {
|
||||||
|
left: module.left,
|
||||||
|
top: module.top,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if (direction === 'up') {
|
||||||
|
module.set({ ...module, top: module.top - Number(length) })
|
||||||
|
} else if (direction === 'down') {
|
||||||
|
module.set({ ...module, top: module.top + Number(length) })
|
||||||
|
} else if (direction === 'left') {
|
||||||
|
module.set({ ...module, left: module.left - Number(length) })
|
||||||
|
} else if (direction === 'right') {
|
||||||
|
module.set({ ...module, left: module.left + Number(length) })
|
||||||
|
}
|
||||||
|
module.setCoords()
|
||||||
|
canvas.renderAll()
|
||||||
|
|
||||||
|
//다른 모듈과 겹치는지 확인하는 로직
|
||||||
|
const isOverlap = isSetupModules.some((isSetupModule) =>
|
||||||
|
turf.booleanOverlap(polygonToTurfPolygon(module, true), polygonToTurfPolygon(isSetupModule, true)),
|
||||||
|
)
|
||||||
|
isOverlapArray.push(isOverlap)
|
||||||
|
|
||||||
|
const turfModuleSetupSurface = polygonToTurfPolygon(setupSurface, true)
|
||||||
|
const turfModule = polygonToTurfPolygon(module, true)
|
||||||
|
|
||||||
|
//나갔는지 확인하는 로직
|
||||||
|
const isInSurface = turf.booleanContains(turfModuleSetupSurface, turfModule) || turf.booleanWithin(turfModule, turfModuleSetupSurface)
|
||||||
|
isInSurfaceArray.push(isInSurface)
|
||||||
|
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
||||||
|
})
|
||||||
|
|
||||||
|
const isNotOverlap = isOverlapArray.some((isOverlap) => isOverlap) // true면 겹침
|
||||||
|
const isNotOutSurface = isInSurfaceArray.every((isOutSurface) => isOutSurface) //false면 밖으로 나감
|
||||||
|
|
||||||
|
//안겹치고 안나갔으면 이동시킨다 아니면 원래 위치로 돌려놓는다
|
||||||
|
if (isNotOverlap || !isNotOutSurface || isOverlapObjects.some((isOverlap) => isOverlap)) {
|
||||||
|
swalFire({
|
||||||
|
title: isNotOverlap
|
||||||
|
? '겹치는 모듈이 있습니다.'
|
||||||
|
: isOverlapObjects.some((isOverlap) => isOverlap)
|
||||||
|
? '모듈이 오브젝트와 겹칩니다.'
|
||||||
|
: '영역 밖',
|
||||||
|
icon: 'error',
|
||||||
|
type: 'confirm',
|
||||||
|
confirmFn: () => {
|
||||||
|
selectedModules.forEach((module) => {
|
||||||
|
module.set({ ...module, left: module.originCoords.left, top: module.originCoords.top })
|
||||||
|
module.setCoords()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas.add(...selectedModules)
|
||||||
|
canvas.renderAll()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const moduleCopy = (length, direction) => {
|
||||||
|
if (canvas.getActiveObjects().length === 0) return
|
||||||
|
const activeModuleIds = canvas.getActiveObjects().map((obj) => obj.id)
|
||||||
|
const modules = canvas.getObjects().filter((obj) => activeModuleIds.includes(obj.id))
|
||||||
|
const objects = getObjects()
|
||||||
|
const otherModules = canvas.getObjects().filter((obj) => obj.surfaceId === modules[0].surfaceId && obj.name === POLYGON_TYPE.MODULE)
|
||||||
|
const moduleSetupSurface = canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === modules[0].surfaceId)[0]
|
||||||
|
let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
|
||||||
|
canvas.discardActiveObject() //선택해제
|
||||||
|
modules.forEach((module) => {
|
||||||
|
const { top, left } = getPosotion(module, direction, length, true)
|
||||||
|
const moduleOptions = { ...module, left, top, id: uuidv4() }
|
||||||
|
const rect = new QPolygon(module.points, moduleOptions)
|
||||||
|
canvas.add(rect)
|
||||||
|
rect.setCoords()
|
||||||
|
canvas.renderAll()
|
||||||
|
|
||||||
|
isOverlapOtherModules.push(
|
||||||
|
otherModules.some(
|
||||||
|
(otherModule) =>
|
||||||
|
turf.booleanOverlap(polygonToTurfPolygon(rect, true), polygonToTurfPolygon(otherModule, true)) ||
|
||||||
|
turf.booleanWithin(polygonToTurfPolygon(rect, true), polygonToTurfPolygon(otherModule, true)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(rect, true), objects))
|
||||||
|
|
||||||
|
isOutsideSurface.push(
|
||||||
|
!turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(rect, true)) ||
|
||||||
|
!turf.booleanWithin(polygonToTurfPolygon(rect, true), polygonToTurfPolygon(moduleSetupSurface, true)),
|
||||||
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
isOverlapOtherModules.some((isOverlap) => isOverlap) ||
|
||||||
|
isOutsideSurface.some((isOutside) => isOutside) ||
|
||||||
|
isOverlapObjects.some((isOverlap) => isOverlap)
|
||||||
|
) {
|
||||||
|
swalFire({
|
||||||
|
title: isOverlapOtherModules ? '겹치는 모듈이 있습니다.' : isOutsideSurface ? '모듈이 오브젝트와 겹칩니다.' : '영역 밖',
|
||||||
|
icon: 'error',
|
||||||
|
type: 'confirm',
|
||||||
|
confirmFn: () => {
|
||||||
|
canvas.remove(rect)
|
||||||
|
canvas.renderAll()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const moduleMultiMove = (type, length, direction) => {
|
||||||
|
if (canvas.getActiveObjects().length === 0) return
|
||||||
|
if (canvas.getActiveObjects().length > 1) {
|
||||||
|
swalFire({
|
||||||
|
title: '여러 개의 모듈을 선택할 수 없습니다.',
|
||||||
|
icon: 'error',
|
||||||
|
type: 'alert',
|
||||||
|
})
|
||||||
|
canvas.discardActiveObject()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
|
||||||
|
const modules = type === 'row' ? getRowModules(activeModule) : getColumnModules(activeModule)
|
||||||
|
const otherModules = getOtherModules(modules)
|
||||||
|
const objects = getObjects()
|
||||||
|
console.log('🚀 ~ moduleMultiMove ~ objects:', objects)
|
||||||
|
|
||||||
|
const moduleSetupSurface = canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
|
||||||
|
let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
|
||||||
|
|
||||||
|
modules.forEach((module) => {
|
||||||
|
const { top, left } = getPosotion(module, direction, length, false)
|
||||||
|
module.originPos = {
|
||||||
|
top: module.top,
|
||||||
|
left: module.left,
|
||||||
|
}
|
||||||
|
|
||||||
|
module.set({ top, left })
|
||||||
|
module.setCoords()
|
||||||
|
canvas.renderAll()
|
||||||
|
|
||||||
|
if (otherModules.length > 0) {
|
||||||
|
isOverlapOtherModules.push(
|
||||||
|
otherModules.some(
|
||||||
|
(otherModule) =>
|
||||||
|
turf.booleanOverlap(polygonToTurfPolygon(module, true), polygonToTurfPolygon(otherModule, true)) ||
|
||||||
|
turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(otherModule, true)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (objects.length > 0) {
|
||||||
|
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
||||||
|
}
|
||||||
|
|
||||||
|
isOutsideSurface.push(
|
||||||
|
!turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(module, true)) ||
|
||||||
|
!turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(moduleSetupSurface, true)),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (
|
||||||
|
isOverlapOtherModules.some((isOverlap) => isOverlap) ||
|
||||||
|
isOverlapObjects.some((isOverlap) => isOverlap) ||
|
||||||
|
isOutsideSurface.some((isOutside) => isOutside)
|
||||||
|
) {
|
||||||
|
swalFire({
|
||||||
|
title: isOverlapOtherModules.some((isOverlap) => isOverlap)
|
||||||
|
? '겹치는 모듈이 있습니다.'
|
||||||
|
: isOverlapObjects.some((isOverlap) => isOverlap)
|
||||||
|
? '모듈이 오브젝트와 겹칩니다.'
|
||||||
|
: '영역 밖',
|
||||||
|
icon: 'error',
|
||||||
|
type: 'confirm',
|
||||||
|
confirmFn: () => {
|
||||||
|
modules.forEach((module) => {
|
||||||
|
module.set({ top: module.originPos.top, left: module.originPos.left })
|
||||||
|
module.setCoords()
|
||||||
|
})
|
||||||
|
canvas.renderAll()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const moduleMultiCopy = (type, length, direction) => {
|
||||||
|
if (canvas.getActiveObjects().length === 0) return
|
||||||
|
if (canvas.getActiveObjects().length > 1) {
|
||||||
|
swalFire({
|
||||||
|
title: '여러 개의 모듈을 선택할 수 없습니다.',
|
||||||
|
icon: 'error',
|
||||||
|
type: 'alert',
|
||||||
|
})
|
||||||
|
canvas.discardActiveObject()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
|
||||||
|
const modules = type === 'row' ? getRowModules(activeModule) : getColumnModules(activeModule)
|
||||||
|
const otherModules = canvas.getObjects().filter((obj) => obj.surfaceId === modules[0].surfaceId && obj.name === POLYGON_TYPE.MODULE)
|
||||||
|
const objects = getObjects()
|
||||||
|
const copyRects = []
|
||||||
|
const moduleSetupSurface = canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === modules[0].surfaceId)[0]
|
||||||
|
let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
|
||||||
|
let moduleLength = 0
|
||||||
|
if (['up', 'down'].includes(direction)) {
|
||||||
|
moduleLength = Number(modules[modules.length - 1].top) + Number(modules[modules.length - 1].height) - Number(modules[0].top)
|
||||||
|
} else if (['left', 'right'].includes(direction)) {
|
||||||
|
moduleLength = Number(modules[modules.length - 1].left) + Number(modules[modules.length - 1].width) - Number(modules[0].left)
|
||||||
|
}
|
||||||
|
|
||||||
|
modules.forEach((module) => {
|
||||||
|
const { top, left } = getPosotion(module, direction, Number(length) + Number(moduleLength), false)
|
||||||
|
const moduleOptions = { ...module, left, top, id: uuidv4() }
|
||||||
|
const rect = new QPolygon(module.getCurrentPoints(), moduleOptions)
|
||||||
|
canvas.add(rect)
|
||||||
|
copyRects.push(rect)
|
||||||
|
module.setCoords()
|
||||||
|
|
||||||
|
if (otherModules.length > 0) {
|
||||||
|
isOverlapOtherModules.push(
|
||||||
|
otherModules.some(
|
||||||
|
(otherModule) =>
|
||||||
|
turf.booleanOverlap(polygonToTurfPolygon(rect, true), polygonToTurfPolygon(otherModule, true)) ||
|
||||||
|
turf.booleanWithin(polygonToTurfPolygon(rect, true), polygonToTurfPolygon(otherModule, true)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (objects.length > 0) {
|
||||||
|
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
||||||
|
}
|
||||||
|
|
||||||
|
isOutsideSurface.push(
|
||||||
|
!turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(rect, true)) ||
|
||||||
|
!turf.booleanWithin(polygonToTurfPolygon(rect, true), polygonToTurfPolygon(moduleSetupSurface, true)),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (
|
||||||
|
isOverlapOtherModules.some((isOverlap) => isOverlap) ||
|
||||||
|
isOverlapObjects.some((isOverlap) => isOverlap) ||
|
||||||
|
isOutsideSurface.some((isOutside) => isOutside)
|
||||||
|
) {
|
||||||
|
swalFire({
|
||||||
|
title: isOverlapOtherModules.some((isOverlap) => isOverlap)
|
||||||
|
? '겹치는 모듈이 있습니다.'
|
||||||
|
: isOverlapObjects.some((isOverlap) => isOverlap)
|
||||||
|
? '모듈이 오브젝트와 겹칩니다.'
|
||||||
|
: '영역 밖',
|
||||||
|
icon: 'error',
|
||||||
|
type: 'confirm',
|
||||||
|
confirmFn: () => {
|
||||||
|
canvas.remove(...copyRects)
|
||||||
|
canvas.renderAll()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
canvas.renderAll()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const moduleColumnRemove = (type) => {
|
||||||
|
const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
|
||||||
|
const columnModules = getColumnModules(activeModule)
|
||||||
|
const otherModules = getOtherModules(columnModules)
|
||||||
|
const objects = getObjects()
|
||||||
|
let targetModules = []
|
||||||
|
const rightModules = otherModules.filter((module) => activeModule.left < module.left).sort((a, b) => a.left - b.left)
|
||||||
|
const leftModules = otherModules.filter((module) => activeModule.left > module.left).sort((a, b) => b.left - a.left)
|
||||||
|
let width = -1
|
||||||
|
const moduleSetupSurface = canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
|
||||||
|
let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
|
||||||
|
canvas.discardActiveObject()
|
||||||
|
canvas.remove(...columnModules)
|
||||||
|
canvas.renderAll()
|
||||||
|
|
||||||
|
if (type === MODULE_REMOVE_TYPE.LEFT) {
|
||||||
|
rightModules.forEach((module) => {
|
||||||
|
module.originPos = {
|
||||||
|
left: module.left,
|
||||||
|
top: module.top,
|
||||||
|
}
|
||||||
|
if (width === -1) width = module.left - activeModule.left
|
||||||
|
module.set({ left: module.left - width })
|
||||||
|
module.setCoords()
|
||||||
|
canvas.renderAll()
|
||||||
|
isOverlapOtherModules.push(getIsOverlapOtherModules(module, leftModules))
|
||||||
|
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
||||||
|
isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
|
||||||
|
})
|
||||||
|
targetModules = rightModules
|
||||||
|
} else if (type === MODULE_REMOVE_TYPE.RIGHT) {
|
||||||
|
leftModules.forEach((module) => {
|
||||||
|
module.originPos = {
|
||||||
|
left: module.left,
|
||||||
|
top: module.top,
|
||||||
|
}
|
||||||
|
if (width === -1) width = activeModule.left - module.left
|
||||||
|
module.set({ left: module.left + width })
|
||||||
|
module.setCoords()
|
||||||
|
canvas.renderAll()
|
||||||
|
isOverlapOtherModules.push(getIsOverlapOtherModules(module, rightModules))
|
||||||
|
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
||||||
|
isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
|
||||||
|
})
|
||||||
|
targetModules = leftModules
|
||||||
|
} else if (type === MODULE_REMOVE_TYPE.HORIZONTAL_SIDE) {
|
||||||
|
const sideModules = [...leftModules, ...rightModules]
|
||||||
|
leftModules.forEach((module) => {
|
||||||
|
module.originPos = {
|
||||||
|
left: module.left,
|
||||||
|
top: module.top,
|
||||||
|
}
|
||||||
|
if (width === -1) width = activeModule.left - module.left
|
||||||
|
module.set({ left: module.left + width / 2 })
|
||||||
|
module.setCoords()
|
||||||
|
canvas.renderAll()
|
||||||
|
})
|
||||||
|
|
||||||
|
rightModules.forEach((module) => {
|
||||||
|
module.originPos = {
|
||||||
|
left: module.left,
|
||||||
|
top: module.top,
|
||||||
|
}
|
||||||
|
if (width === -1) width = module.left - activeModule.left
|
||||||
|
module.set({ left: module.left - width / 2 })
|
||||||
|
module.setCoords()
|
||||||
|
canvas.renderAll()
|
||||||
|
})
|
||||||
|
canvas.renderAll()
|
||||||
|
sideModules.forEach((module) => {
|
||||||
|
isOverlapOtherModules.push(
|
||||||
|
getIsOverlapOtherModules(
|
||||||
|
module,
|
||||||
|
sideModules.filter((m) => m.id !== module.id),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
||||||
|
isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
|
||||||
|
})
|
||||||
|
|
||||||
|
targetModules = sideModules
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
(isOverlapOtherModules.some((isOverlap) => isOverlap) ||
|
||||||
|
isOverlapObjects.some((isOverlap) => isOverlap) ||
|
||||||
|
isOutsideSurface.some((isOutside) => isOutside)) &&
|
||||||
|
type !== MODULE_REMOVE_TYPE.NONE
|
||||||
|
) {
|
||||||
|
swalFire({
|
||||||
|
title: isOverlapOtherModules.some((isOverlap) => isOverlap)
|
||||||
|
? '겹치는 모듈이 있습니다.'
|
||||||
|
: isOverlapObjects.some((isOverlap) => isOverlap)
|
||||||
|
? '모듈이 오브젝트와 겹칩니다.'
|
||||||
|
: '영역 밖',
|
||||||
|
icon: 'error',
|
||||||
|
type: 'confirm',
|
||||||
|
confirmFn: () => {
|
||||||
|
canvas.add(...columnModules)
|
||||||
|
targetModules.forEach((module) => {
|
||||||
|
module.set({ top: module.originPos.top, left: module.originPos.left })
|
||||||
|
module.setCoords()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
canvas.renderAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
const moduleRowRemove = (type) => {
|
||||||
|
const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
|
||||||
|
const rowModules = getRowModules(activeModule)
|
||||||
|
const otherModules = getOtherModules(rowModules)
|
||||||
|
const objects = getObjects()
|
||||||
|
let targetModules = []
|
||||||
|
const topModules = otherModules.filter((module) => activeModule.top > module.top).sort((a, b) => b.top - a.top)
|
||||||
|
const bottomModules = otherModules.filter((module) => activeModule.top < module.top).sort((a, b) => a.top - b.top)
|
||||||
|
let height = -1
|
||||||
|
const moduleSetupSurface = canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
|
||||||
|
let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
|
||||||
|
|
||||||
|
canvas.discardActiveObject()
|
||||||
|
canvas.remove(...rowModules)
|
||||||
|
canvas.renderAll()
|
||||||
|
|
||||||
|
if (type === MODULE_REMOVE_TYPE.TOP) {
|
||||||
|
bottomModules.forEach((module) => {
|
||||||
|
module.originPos = {
|
||||||
|
left: module.left,
|
||||||
|
top: module.top,
|
||||||
|
}
|
||||||
|
if (height === -1) height = module.top - activeModule.top
|
||||||
|
module.set({ top: module.top - height })
|
||||||
|
module.setCoords()
|
||||||
|
canvas.renderAll()
|
||||||
|
isOverlapOtherModules.push(getIsOverlapOtherModules(module, topModules))
|
||||||
|
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
||||||
|
isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
|
||||||
|
})
|
||||||
|
targetModules = bottomModules
|
||||||
|
} else if (type === MODULE_REMOVE_TYPE.BOTTOM) {
|
||||||
|
topModules.forEach((module) => {
|
||||||
|
module.originPos = {
|
||||||
|
left: module.left,
|
||||||
|
top: module.top,
|
||||||
|
}
|
||||||
|
if (height === -1) height = activeModule.top - module.top
|
||||||
|
module.set({ top: module.top + height })
|
||||||
|
module.setCoords()
|
||||||
|
canvas.renderAll()
|
||||||
|
isOverlapOtherModules.push(getIsOverlapOtherModules(module, bottomModules))
|
||||||
|
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
||||||
|
isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
|
||||||
|
})
|
||||||
|
targetModules = topModules
|
||||||
|
} else if (type === MODULE_REMOVE_TYPE.VERTICAL_SIDE) {
|
||||||
|
topModules.forEach((module) => {
|
||||||
|
module.originPos = {
|
||||||
|
left: module.left,
|
||||||
|
top: module.top,
|
||||||
|
}
|
||||||
|
if (height === -1) height = activeModule.top - module.top
|
||||||
|
module.set({ top: module.top + height / 2 })
|
||||||
|
module.setCoords()
|
||||||
|
canvas.renderAll()
|
||||||
|
})
|
||||||
|
|
||||||
|
bottomModules.forEach((module) => {
|
||||||
|
module.originPos = {
|
||||||
|
left: module.left,
|
||||||
|
top: module.top,
|
||||||
|
}
|
||||||
|
if (height === -1) height = module.top - activeModule.top
|
||||||
|
module.set({ top: module.top - height / 2 })
|
||||||
|
module.setCoords()
|
||||||
|
canvas.renderAll()
|
||||||
|
})
|
||||||
|
|
||||||
|
const sideModules = [...topModules, ...bottomModules]
|
||||||
|
canvas.renderAll()
|
||||||
|
sideModules.forEach((module) => {
|
||||||
|
isOverlapOtherModules.push(
|
||||||
|
getIsOverlapOtherModules(
|
||||||
|
module,
|
||||||
|
sideModules.filter((m) => m.id !== module.id),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
||||||
|
isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
|
||||||
|
})
|
||||||
|
targetModules = sideModules
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
(isOverlapOtherModules.some((isOverlap) => isOverlap) ||
|
||||||
|
isOverlapObjects.some((isOverlap) => isOverlap) ||
|
||||||
|
isOutsideSurface.some((isOutside) => isOutside)) &&
|
||||||
|
type !== MODULE_REMOVE_TYPE.NONE
|
||||||
|
) {
|
||||||
|
swalFire({
|
||||||
|
title: isOverlapOtherModules.some((isOverlap) => isOverlap)
|
||||||
|
? '겹치는 모듈이 있습니다.'
|
||||||
|
: isOverlapObjects.some((isOverlap) => isOverlap)
|
||||||
|
? '모듈이 오브젝트와 겹칩니다.'
|
||||||
|
: '영역 밖',
|
||||||
|
icon: 'error',
|
||||||
|
type: 'confirm',
|
||||||
|
confirmFn: () => {
|
||||||
|
canvas.add(...rowModules)
|
||||||
|
targetModules.forEach((module) => {
|
||||||
|
module.set({ top: module.originPos.top, left: module.originPos.left })
|
||||||
|
module.setCoords()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
canvas.renderAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
const moduleColumnInsert = (type) => {
|
||||||
|
const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
|
||||||
|
const columnModules = getColumnModules(activeModule)
|
||||||
|
let otherModules = getOtherModules(columnModules)
|
||||||
|
const targetModules =
|
||||||
|
type === MODULE_INSERT_TYPE.LEFT
|
||||||
|
? otherModules.filter((module) => module.left < activeModule.left).sort((a, b) => a.left - b.left)
|
||||||
|
: otherModules.filter((module) => module.left > activeModule.left).sort((a, b) => b.left - a.left)
|
||||||
|
const objects = getObjects()
|
||||||
|
const copyModules = []
|
||||||
|
const moduleSetupSurface = canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
|
||||||
|
let width = -1
|
||||||
|
let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
|
||||||
|
if (targetModules.length === 0) {
|
||||||
|
swalFire({
|
||||||
|
title: '마지막 모듈입니다.',
|
||||||
|
icon: 'error',
|
||||||
|
type: 'alert',
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
canvas.discardActiveObject()
|
||||||
|
targetModules.forEach((module) => {
|
||||||
|
if (width === -1)
|
||||||
|
width = type === MODULE_INSERT_TYPE.LEFT ? Number(activeModule.left) - Number(module.left) : Number(module.left) - Number(activeModule.left)
|
||||||
|
const { top, left } = getPosotion(module, type, width, false)
|
||||||
|
module.originPos = {
|
||||||
|
left: module.left,
|
||||||
|
top: module.top,
|
||||||
|
}
|
||||||
|
module.set({ left, top })
|
||||||
|
canvas.renderAll()
|
||||||
|
if (objects.length > 0) {
|
||||||
|
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
||||||
|
}
|
||||||
|
|
||||||
|
isOutsideSurface.push(
|
||||||
|
!turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(module, true)) ||
|
||||||
|
!turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(moduleSetupSurface, true)),
|
||||||
|
)
|
||||||
|
module.setCoords()
|
||||||
|
})
|
||||||
|
otherModules = getOtherModules(columnModules)
|
||||||
|
columnModules.forEach((module) => {
|
||||||
|
const { top, left } = getPosotion(module, type, width, false)
|
||||||
|
const moduleOptions = { ...module, left, top, id: uuidv4() }
|
||||||
|
const copyModule = new QPolygon(module.points, moduleOptions)
|
||||||
|
canvas.add(copyModule)
|
||||||
|
copyModules.push(copyModule)
|
||||||
|
canvas.renderAll()
|
||||||
|
|
||||||
|
if (otherModules.length > 0) {
|
||||||
|
isOverlapOtherModules.push(
|
||||||
|
otherModules.some(
|
||||||
|
(otherModule) =>
|
||||||
|
turf.booleanOverlap(polygonToTurfPolygon(copyModule, true), polygonToTurfPolygon(otherModule, true)) ||
|
||||||
|
turf.booleanWithin(polygonToTurfPolygon(copyModule, true), polygonToTurfPolygon(otherModule, true)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (objects.length > 0) {
|
||||||
|
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
||||||
|
}
|
||||||
|
|
||||||
|
isOutsideSurface.push(
|
||||||
|
!turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(copyModule, true)) ||
|
||||||
|
!turf.booleanWithin(polygonToTurfPolygon(copyModule, true), polygonToTurfPolygon(moduleSetupSurface, true)),
|
||||||
|
)
|
||||||
|
module.setCoords()
|
||||||
|
})
|
||||||
|
|
||||||
|
if (
|
||||||
|
isOverlapOtherModules.some((isOverlap) => isOverlap) ||
|
||||||
|
isOverlapObjects.some((isOverlap) => isOverlap) ||
|
||||||
|
isOutsideSurface.some((isOutside) => isOutside)
|
||||||
|
) {
|
||||||
|
swalFire({
|
||||||
|
title: isOverlapOtherModules.some((isOverlap) => isOverlap)
|
||||||
|
? '겹치는 모듈이 있습니다.'
|
||||||
|
: isOverlapObjects.some((isOverlap) => isOverlap)
|
||||||
|
? '모듈이 오브젝트와 겹칩니다.'
|
||||||
|
: '영역 밖',
|
||||||
|
icon: 'error',
|
||||||
|
type: 'confirm',
|
||||||
|
confirmFn: () => {
|
||||||
|
targetModules.forEach((module) => {
|
||||||
|
module.set({ top: module.originPos.top, left: module.originPos.left })
|
||||||
|
module.setCoords()
|
||||||
|
})
|
||||||
|
canvas.renderAll()
|
||||||
|
copyModules.forEach((module) => {
|
||||||
|
canvas.remove(module)
|
||||||
|
})
|
||||||
|
canvas.renderAll()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const muduleRowInsert = (type) => {
|
||||||
|
console.log('🚀 ~ muduleRowInsert ~ type:', type)
|
||||||
|
const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
|
||||||
|
const rowModules = getRowModules(activeModule)
|
||||||
|
console.log('🚀 ~ muduleRowInsert ~ rowModules:', rowModules)
|
||||||
|
let otherModules = getOtherModules(rowModules)
|
||||||
|
const targetModules =
|
||||||
|
type === MODULE_INSERT_TYPE.TOP
|
||||||
|
? otherModules.filter((module) => module.top < activeModule.top).sort((a, b) => b.top - a.top)
|
||||||
|
: otherModules.filter((module) => module.top > activeModule.top).sort((a, b) => a.top - b.top)
|
||||||
|
console.log('🚀 ~ muduleRowInsert ~ targetModules:', targetModules)
|
||||||
|
if (targetModules.length === 0) {
|
||||||
|
swalFire({
|
||||||
|
title: '마지막 모듈입니다.',
|
||||||
|
icon: 'error',
|
||||||
|
type: 'alert',
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const objects = getObjects()
|
||||||
|
const copyModules = []
|
||||||
|
const moduleSetupSurface = canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
|
||||||
|
let height = -1
|
||||||
|
let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
|
||||||
|
canvas.discardActiveObject()
|
||||||
|
targetModules.forEach((module) => {
|
||||||
|
if (height === -1)
|
||||||
|
height = type === MODULE_INSERT_TYPE.TOP ? Number(activeModule.top) - Number(module.top) : Number(module.top) - Number(activeModule.top)
|
||||||
|
const { top, left } = getPosotion(module, type, height, false)
|
||||||
|
module.originPos = {
|
||||||
|
left: module.left,
|
||||||
|
top: module.top,
|
||||||
|
}
|
||||||
|
module.set({ left, top })
|
||||||
|
canvas.renderAll()
|
||||||
|
if (objects.length > 0) {
|
||||||
|
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
||||||
|
}
|
||||||
|
|
||||||
|
isOutsideSurface.push(
|
||||||
|
!turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(module, true)) ||
|
||||||
|
!turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(moduleSetupSurface, true)),
|
||||||
|
)
|
||||||
|
module.setCoords()
|
||||||
|
})
|
||||||
|
otherModules = getOtherModules(rowModules)
|
||||||
|
rowModules.forEach((module) => {
|
||||||
|
const { top, left } = getPosotion(module, type, height, false)
|
||||||
|
const moduleOptions = { ...module, left, top, id: uuidv4() }
|
||||||
|
const copyModule = new QPolygon(module.points, moduleOptions)
|
||||||
|
canvas.add(copyModule)
|
||||||
|
copyModules.push(copyModule)
|
||||||
|
canvas.renderAll()
|
||||||
|
|
||||||
|
if (otherModules.length > 0) {
|
||||||
|
isOverlapOtherModules.push(
|
||||||
|
otherModules.some(
|
||||||
|
(otherModule) =>
|
||||||
|
turf.booleanOverlap(polygonToTurfPolygon(copyModule, true), polygonToTurfPolygon(otherModule, true)) ||
|
||||||
|
turf.booleanWithin(polygonToTurfPolygon(copyModule, true), polygonToTurfPolygon(otherModule, true)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (objects.length > 0) {
|
||||||
|
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
||||||
|
}
|
||||||
|
|
||||||
|
isOutsideSurface.push(
|
||||||
|
!turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(copyModule, true)) ||
|
||||||
|
!turf.booleanWithin(polygonToTurfPolygon(copyModule, true), polygonToTurfPolygon(moduleSetupSurface, true)),
|
||||||
|
)
|
||||||
|
module.setCoords()
|
||||||
|
})
|
||||||
|
|
||||||
|
if (
|
||||||
|
isOverlapOtherModules.some((isOverlap) => isOverlap) ||
|
||||||
|
isOverlapObjects.some((isOverlap) => isOverlap) ||
|
||||||
|
isOutsideSurface.some((isOutside) => isOutside)
|
||||||
|
) {
|
||||||
|
swalFire({
|
||||||
|
title: isOverlapOtherModules.some((isOverlap) => isOverlap)
|
||||||
|
? '겹치는 모듈이 있습니다.'
|
||||||
|
: isOverlapObjects.some((isOverlap) => isOverlap)
|
||||||
|
? '모듈이 오브젝트와 겹칩니다.'
|
||||||
|
: '영역 밖',
|
||||||
|
icon: 'error',
|
||||||
|
type: 'confirm',
|
||||||
|
confirmFn: () => {
|
||||||
|
targetModules.forEach((module) => {
|
||||||
|
module.set({ top: module.originPos.top, left: module.originPos.left })
|
||||||
|
module.setCoords()
|
||||||
|
})
|
||||||
|
canvas.renderAll()
|
||||||
|
copyModules.forEach((module) => {
|
||||||
|
canvas.remove(module)
|
||||||
|
})
|
||||||
|
canvas.renderAll()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getRowModules = (target) => {
|
||||||
|
return canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => target.surfaceId === obj.surfaceId && obj.name === POLYGON_TYPE.MODULE && obj.top === target.top)
|
||||||
|
.sort((a, b) => a.left - b.left)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getColumnModules = (target) => {
|
||||||
|
return canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => target.surfaceId === obj.surfaceId && obj.name === POLYGON_TYPE.MODULE && obj.left === target.left)
|
||||||
|
.sort((a, b) => a.top - b.top)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getPosotion = (target, direction, length, hasMargin = false) => {
|
||||||
|
let top = target.top
|
||||||
|
let left = target.left
|
||||||
|
|
||||||
|
if (direction === 'up') {
|
||||||
|
top = Number(target.top) - Number(length)
|
||||||
|
top = hasMargin ? top - Number(target.height) : top
|
||||||
|
} else if (direction === 'down') {
|
||||||
|
top = Number(target.top) + Number(length)
|
||||||
|
top = hasMargin ? top + Number(target.height) : top
|
||||||
|
} else if (direction === 'left') {
|
||||||
|
left = Number(target.left) - Number(length)
|
||||||
|
left = hasMargin ? left - Number(target.width) : left
|
||||||
|
} else if (direction === 'right') {
|
||||||
|
left = Number(target.left) + Number(length)
|
||||||
|
left = hasMargin ? left + Number(target.width) : left
|
||||||
|
}
|
||||||
|
return { top, left }
|
||||||
|
}
|
||||||
|
|
||||||
|
const getOtherModules = (modules) => {
|
||||||
|
const moduleIds = modules.map((module) => module.id)
|
||||||
|
return canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => obj.surfaceId === modules[0].surfaceId && obj.name === POLYGON_TYPE.MODULE && !moduleIds.includes(obj.id))
|
||||||
|
}
|
||||||
|
|
||||||
|
const getObjects = () => {
|
||||||
|
return canvas
|
||||||
|
?.getObjects()
|
||||||
|
.filter((obj) => [BATCH_TYPE.OPENING, BATCH_TYPE.TRIANGLE_DORMER, BATCH_TYPE.PENTAGON_DORMER, BATCH_TYPE.SHADOW].includes(obj.name))
|
||||||
|
}
|
||||||
|
|
||||||
|
const getIsOverlapOtherModules = (module, otherModules) => {
|
||||||
|
return otherModules.some(
|
||||||
|
(otherModule) =>
|
||||||
|
turf.booleanOverlap(polygonToTurfPolygon(module, true), polygonToTurfPolygon(otherModule, true)) ||
|
||||||
|
turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(otherModule, true)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getIsOverlapObjects = (module, objects) => {
|
||||||
|
return !objects.some(
|
||||||
|
(object) =>
|
||||||
|
turf.booleanOverlap(polygonToTurfPolygon(module, true), polygonToTurfPolygon(object, true)) ||
|
||||||
|
turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(object, true)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getIsOutsideSurface = (module, moduleSetupSurface) => {
|
||||||
|
return (
|
||||||
|
!turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(module, true)) ||
|
||||||
|
!turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(moduleSetupSurface, true))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
moduleMove,
|
||||||
|
moduleMultiMove,
|
||||||
|
moduleCopy,
|
||||||
|
moduleMultiCopy,
|
||||||
|
moduleColumnRemove,
|
||||||
|
moduleRowRemove,
|
||||||
|
moduleColumnInsert,
|
||||||
|
muduleRowInsert,
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -428,7 +428,8 @@ export function useModuleBasicSetting() {
|
|||||||
dormerTurfPolygon = batchObjectGroupToTurfPolygon(object)
|
dormerTurfPolygon = batchObjectGroupToTurfPolygon(object)
|
||||||
} else {
|
} else {
|
||||||
//개구, 그림자
|
//개구, 그림자
|
||||||
dormerTurfPolygon = polygonToTurfPolygon(rectToPolygon(object))
|
object.set({ points: rectToPolygon(object) })
|
||||||
|
dormerTurfPolygon = polygonToTurfPolygon(object)
|
||||||
}
|
}
|
||||||
|
|
||||||
const intersection = turf.intersect(turf.featureCollection([dormerTurfPolygon, tempTurfModule])) //겹치는지 확인
|
const intersection = turf.intersect(turf.featureCollection([dormerTurfPolygon, tempTurfModule])) //겹치는지 확인
|
||||||
@ -567,35 +568,35 @@ export function useModuleBasicSetting() {
|
|||||||
return containsBatchObjects
|
return containsBatchObjects
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* 도머나 개구가 모듈에 걸치는지 확인하는 로직
|
// * 도머나 개구가 모듈에 걸치는지 확인하는 로직
|
||||||
* @param {*} squarePolygon
|
// * @param {*} squarePolygon
|
||||||
* @param {*} containsBatchObjects
|
// * @param {*} containsBatchObjects
|
||||||
* @returns
|
// * @returns
|
||||||
*/
|
// */
|
||||||
const checkModuleDisjointObjects = (squarePolygon, containsBatchObjects) => {
|
// const checkModuleDisjointObjects = (squarePolygon, containsBatchObjects) => {
|
||||||
let isDisjoint = false
|
// let isDisjoint = false
|
||||||
|
//
|
||||||
if (containsBatchObjects.length > 0) {
|
// if (containsBatchObjects.length > 0) {
|
||||||
let convertBatchObject
|
// let convertBatchObject
|
||||||
//도머가 있으면 적용되는 로직
|
// //도머가 있으면 적용되는 로직
|
||||||
isDisjoint = containsBatchObjects.every((batchObject) => {
|
// isDisjoint = containsBatchObjects.every((batchObject) => {
|
||||||
if (batchObject.type === 'group') {
|
// if (batchObject.type === 'group') {
|
||||||
convertBatchObject = batchObjectGroupToTurfPolygon(batchObject)
|
// convertBatchObject = batchObjectGroupToTurfPolygon(batchObject)
|
||||||
} else {
|
// } else {
|
||||||
convertBatchObject = polygonToTurfPolygon(batchObject)
|
// convertBatchObject = polygonToTurfPolygon(batchObject)
|
||||||
}
|
// }
|
||||||
/**
|
// /**
|
||||||
* 도머가 여러개일수있으므로 겹치는게 있다면...
|
// * 도머가 여러개일수있으므로 겹치는게 있다면...
|
||||||
* 안겹치는지 확인하는 로직이라 안겹치면 true를 반환
|
// * 안겹치는지 확인하는 로직이라 안겹치면 true를 반환
|
||||||
*/
|
// */
|
||||||
return turf.booleanDisjoint(squarePolygon, convertBatchObject)
|
// return turf.booleanDisjoint(squarePolygon, convertBatchObject)
|
||||||
})
|
// })
|
||||||
} else {
|
// } else {
|
||||||
isDisjoint = true
|
// isDisjoint = true
|
||||||
}
|
// }
|
||||||
return isDisjoint
|
// return isDisjoint
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 배치면 안에 있는지 확인
|
* 배치면 안에 있는지 확인
|
||||||
@ -2141,36 +2142,6 @@ export function useModuleBasicSetting() {
|
|||||||
return containsBatchObjects
|
return containsBatchObjects
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 도머나 개구가 모듈에 걸치는지 확인하는 로직
|
|
||||||
* @param {*} squarePolygon
|
|
||||||
* @param {*} containsBatchObjects
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
const checkModuleDisjointObjects = (squarePolygon, containsBatchObjects) => {
|
|
||||||
let isDisjoint = false
|
|
||||||
|
|
||||||
if (containsBatchObjects.length > 0) {
|
|
||||||
let convertBatchObject
|
|
||||||
//도머가 있으면 적용되는 로직
|
|
||||||
isDisjoint = containsBatchObjects.every((batchObject) => {
|
|
||||||
if (batchObject.type === 'group') {
|
|
||||||
convertBatchObject = batchObjectGroupToTurfPolygon(batchObject)
|
|
||||||
} else {
|
|
||||||
convertBatchObject = polygonToTurfPolygon(batchObject)
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 도머가 여러개일수있으므로 겹치는게 있다면...
|
|
||||||
* 안겹치는지 확인하는 로직이라 안겹치면 true를 반환
|
|
||||||
*/
|
|
||||||
return turf.booleanDisjoint(squarePolygon, convertBatchObject)
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
isDisjoint = true
|
|
||||||
}
|
|
||||||
return isDisjoint
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 배치면 안에 있는지 확인
|
* 배치면 안에 있는지 확인
|
||||||
* @param {*} squarePolygon
|
* @param {*} squarePolygon
|
||||||
@ -2431,6 +2402,39 @@ export function useModuleBasicSetting() {
|
|||||||
//드래그 하기위해 기능 활성화
|
//드래그 하기위해 기능 활성화
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 도머나 개구가 모듈에 걸치는지 확인하는 로직
|
||||||
|
* @param {*} squarePolygon
|
||||||
|
* @param {*} containsBatchObjects
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const checkModuleDisjointObjects = (squarePolygon, containsBatchObjects) => {
|
||||||
|
let isDisjoint = false
|
||||||
|
|
||||||
|
if (containsBatchObjects.length > 0) {
|
||||||
|
let convertBatchObject
|
||||||
|
//도머가 있으면 적용되는 로직
|
||||||
|
isDisjoint = containsBatchObjects.every((batchObject) => {
|
||||||
|
if (batchObject.type === 'group') {
|
||||||
|
convertBatchObject = batchObjectGroupToTurfPolygon(batchObject)
|
||||||
|
} else {
|
||||||
|
if (!batchObject.points) {
|
||||||
|
batchObject.set({ points: rectToPolygon(batchObject) })
|
||||||
|
}
|
||||||
|
convertBatchObject = polygonToTurfPolygon(batchObject)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 도머가 여러개일수있으므로 겹치는게 있다면...
|
||||||
|
* 안겹치는지 확인하는 로직이라 안겹치면 true를 반환
|
||||||
|
*/
|
||||||
|
return turf.booleanDisjoint(squarePolygon, convertBatchObject)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
isDisjoint = true
|
||||||
|
}
|
||||||
|
return isDisjoint
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
makeModuleInstArea,
|
makeModuleInstArea,
|
||||||
manualModuleSetup,
|
manualModuleSetup,
|
||||||
@ -2438,5 +2442,6 @@ export function useModuleBasicSetting() {
|
|||||||
restoreModuleInstArea,
|
restoreModuleInstArea,
|
||||||
manualFlatroofModuleSetup,
|
manualFlatroofModuleSetup,
|
||||||
autoFlatroofModuleSetup,
|
autoFlatroofModuleSetup,
|
||||||
|
checkModuleDisjointObjects,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -269,17 +269,6 @@ export function useCanvasSetting() {
|
|||||||
roofSizeSet: item.roofSizeSet,
|
roofSizeSet: item.roofSizeSet,
|
||||||
roofAngleSet: item.roofAngleSet,
|
roofAngleSet: item.roofAngleSet,
|
||||||
}
|
}
|
||||||
|
|
||||||
roofsArray = {
|
|
||||||
roofApply: true,
|
|
||||||
roofSeq: 1,
|
|
||||||
roofMatlCd: 'ROOF_ID_WA_53A',
|
|
||||||
roofWidth: 265,
|
|
||||||
roofHeight: 235,
|
|
||||||
roofHajebichi: 0,
|
|
||||||
roofGap: 'HEI_455',
|
|
||||||
roofLayout: 'P',
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
roofsRow = [
|
roofsRow = [
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import useMenu from '@/hooks/common/useMenu'
|
|||||||
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
|
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
|
||||||
import { menuTypeState } from '@/store/menuAtom'
|
import { menuTypeState } from '@/store/menuAtom'
|
||||||
import { useRoofFn } from '@/hooks/common/useRoofFn'
|
import { useRoofFn } from '@/hooks/common/useRoofFn'
|
||||||
|
import { ROOF_MATERIAL_LAYOUT } from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting'
|
||||||
|
|
||||||
// 지붕면 할당
|
// 지붕면 할당
|
||||||
export function useRoofAllocationSetting(id) {
|
export function useRoofAllocationSetting(id) {
|
||||||
@ -32,7 +33,7 @@ export function useRoofAllocationSetting(id) {
|
|||||||
const [currentRoofMaterial, setCurrentRoofMaterial] = useState(roofMaterials[0]) // 팝업 내 기준 지붕재
|
const [currentRoofMaterial, setCurrentRoofMaterial] = useState(roofMaterials[0]) // 팝업 내 기준 지붕재
|
||||||
const [roofList, setRoofList] = useRecoilState(addedRoofsState) // 배치면 초기설정에서 선택한 지붕재 배열
|
const [roofList, setRoofList] = useRecoilState(addedRoofsState) // 배치면 초기설정에서 선택한 지붕재 배열
|
||||||
const [editingLines, setEditingLines] = useState([])
|
const [editingLines, setEditingLines] = useState([])
|
||||||
const isFirstRef = useRef(0)
|
const [currentRoofList, setCurrentRoofList] = useState(roofList)
|
||||||
|
|
||||||
const { setSurfaceShapePattern } = useRoofFn()
|
const { setSurfaceShapePattern } = useRoofFn()
|
||||||
|
|
||||||
@ -76,20 +77,25 @@ export function useRoofAllocationSetting(id) {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const onAddRoofMaterial = () => {
|
const onAddRoofMaterial = () => {
|
||||||
if (roofList.length >= 4) {
|
if (currentRoofList.length >= 4) {
|
||||||
swalFire({ type: 'alert', icon: 'error', text: getMessage('지붕재는 4개까지 선택 가능합니다.') })
|
swalFire({ type: 'alert', icon: 'error', text: getMessage('지붕재는 4개까지 선택 가능합니다.') })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
setRoofList([...roofList, { ...currentRoofMaterial, selected: false, id: currentRoofMaterial.roofMatlCd, name: currentRoofMaterial.roofMatlNm }])
|
setCurrentRoofList([
|
||||||
|
...currentRoofList,
|
||||||
|
{ ...currentRoofMaterial, selected: false, id: currentRoofMaterial.roofMatlCd, name: currentRoofMaterial.roofMatlNm },
|
||||||
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
const onDeleteRoofMaterial = (idx) => {
|
const onDeleteRoofMaterial = (idx) => {
|
||||||
setRoofList([...roofList.filter((_, index) => index !== idx)])
|
const isSelected = currentRoofList[idx].selected
|
||||||
|
const newRoofList = [...currentRoofList].filter((_, index) => index !== idx)
|
||||||
|
if (isSelected) {
|
||||||
|
newRoofList[0].selected = true
|
||||||
|
}
|
||||||
|
setCurrentRoofList(newRoofList)
|
||||||
}
|
}
|
||||||
|
|
||||||
const { handleMenu } = useMenu()
|
|
||||||
const [currentMenu, setCurrentMenu] = useRecoilState(currentMenuState)
|
|
||||||
|
|
||||||
// 선택한 지붕재로 할당
|
// 선택한 지붕재로 할당
|
||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
// 모두 actualSize 있으면 바로 적용 없으면 actualSize 설정
|
// 모두 actualSize 있으면 바로 적용 없으면 actualSize 설정
|
||||||
@ -102,7 +108,7 @@ export function useRoofAllocationSetting(id) {
|
|||||||
|
|
||||||
// 지붕재 오른쪽 마우스 클릭 후 단일로 지붕재 변경 필요한 경우
|
// 지붕재 오른쪽 마우스 클릭 후 단일로 지붕재 변경 필요한 경우
|
||||||
const handleSaveContext = () => {
|
const handleSaveContext = () => {
|
||||||
const selectedRoofMaterial = roofList.find((roof) => roof.selected)
|
const selectedRoofMaterial = currentRoofList.find((roof) => roof.selected)
|
||||||
setSurfaceShapePattern(currentObject, roofDisplay.column, false, selectedRoofMaterial)
|
setSurfaceShapePattern(currentObject, roofDisplay.column, false, selectedRoofMaterial)
|
||||||
closeAll()
|
closeAll()
|
||||||
}
|
}
|
||||||
@ -169,11 +175,11 @@ export function useRoofAllocationSetting(id) {
|
|||||||
setBasicSetting((prev) => {
|
setBasicSetting((prev) => {
|
||||||
return {
|
return {
|
||||||
...prev,
|
...prev,
|
||||||
selectedRoofMaterial: roofList.find((roof) => roof.selected),
|
selectedRoofMaterial: currentRoofList.find((roof) => roof.selected),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
setRoofList(roofList)
|
setRoofList(currentRoofList)
|
||||||
|
|
||||||
const roofs = canvas.getObjects().filter((obj) => obj.name === 'roof')
|
const roofs = canvas.getObjects().filter((obj) => obj.name === 'roof')
|
||||||
|
|
||||||
@ -182,7 +188,12 @@ export function useRoofAllocationSetting(id) {
|
|||||||
roof.set({
|
roof.set({
|
||||||
isFixed: true,
|
isFixed: true,
|
||||||
})
|
})
|
||||||
setSurfaceShapePattern(roof, roofDisplay.column)
|
setSurfaceShapePattern(
|
||||||
|
roof,
|
||||||
|
roofDisplay.column,
|
||||||
|
false,
|
||||||
|
currentRoofList.find((roof) => roof.selected),
|
||||||
|
)
|
||||||
drawDirectionArrow(roof)
|
drawDirectionArrow(roof)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -216,54 +227,53 @@ export function useRoofAllocationSetting(id) {
|
|||||||
|
|
||||||
// 지붕재 변경
|
// 지붕재 변경
|
||||||
const handleChangeRoofMaterial = (value, index) => {
|
const handleChangeRoofMaterial = (value, index) => {
|
||||||
if (isFirstRef.current === 0) {
|
const selectedIndex = roofMaterials.findIndex((roof) => roof.selected)
|
||||||
isFirstRef.current++
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const selectedRoofMaterial = roofMaterials.find((roof) => roof.roofMatlCd === value.id)
|
const selectedRoofMaterial = roofMaterials.find((roof) => roof.roofMatlCd === value.id)
|
||||||
const newRoofList = roofList.map((roof, idx) => {
|
const newRoofList = currentRoofList.map((roof, idx) => {
|
||||||
if (idx === index) {
|
if (idx === index) {
|
||||||
return { ...selectedRoofMaterial }
|
return { ...selectedRoofMaterial }
|
||||||
}
|
}
|
||||||
return roof
|
return roof
|
||||||
})
|
})
|
||||||
|
|
||||||
setRoofList(newRoofList)
|
newRoofList[selectedIndex].selected = true
|
||||||
|
|
||||||
|
setCurrentRoofList(newRoofList)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 기본 지붕재 radio값 변경
|
// 기본 지붕재 radio값 변경
|
||||||
const handleDefaultRoofMaterial = (index) => {
|
const handleDefaultRoofMaterial = (index) => {
|
||||||
const newRoofList = roofList.map((roof, idx) => {
|
const newRoofList = currentRoofList.map((roof, idx) => {
|
||||||
return { ...roof, selected: idx === index }
|
return { ...roof, selected: idx === index }
|
||||||
})
|
})
|
||||||
|
|
||||||
setRoofList(newRoofList)
|
setCurrentRoofList(newRoofList)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 서까래 변경
|
// 서까래 변경
|
||||||
const handleChangeRaft = (e, index) => {
|
const handleChangeRaft = (e, index) => {
|
||||||
const raftValue = e.value
|
const raftValue = e.clCode
|
||||||
|
|
||||||
const newRoofList = roofList.map((roof, idx) => {
|
const newRoofList = currentRoofList.map((roof, idx) => {
|
||||||
if (idx === index) {
|
if (idx === index) {
|
||||||
return { ...roof, raft: raftValue }
|
return { ...roof, raft: raftValue }
|
||||||
}
|
}
|
||||||
return roof
|
return roof
|
||||||
})
|
})
|
||||||
|
|
||||||
setRoofList(newRoofList)
|
setCurrentRoofList(newRoofList)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleChangeLayout = (layoutValue, index) => {
|
const handleChangeLayout = (layoutValue, index) => {
|
||||||
const newRoofList = roofList.map((roof, idx) => {
|
const newRoofList = currentRoofList.map((roof, idx) => {
|
||||||
if (idx === index) {
|
if (idx === index) {
|
||||||
return { ...roof, layout: layoutValue }
|
return { ...roof, layout: layoutValue }
|
||||||
}
|
}
|
||||||
return roof
|
return roof
|
||||||
})
|
})
|
||||||
|
|
||||||
setRoofList(newRoofList)
|
setCurrentRoofList(newRoofList)
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -278,11 +288,11 @@ export function useRoofAllocationSetting(id) {
|
|||||||
setBasicSetting,
|
setBasicSetting,
|
||||||
currentRoofMaterial,
|
currentRoofMaterial,
|
||||||
setCurrentRoofMaterial,
|
setCurrentRoofMaterial,
|
||||||
roofList,
|
|
||||||
handleDefaultRoofMaterial,
|
handleDefaultRoofMaterial,
|
||||||
handleChangeRoofMaterial,
|
handleChangeRoofMaterial,
|
||||||
handleChangeRaft,
|
handleChangeRaft,
|
||||||
handleChangeLayout,
|
handleChangeLayout,
|
||||||
handleSaveContext,
|
handleSaveContext,
|
||||||
|
currentRoofList,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,7 +23,7 @@ import { useCommonUtils } from './common/useCommonUtils'
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useCanvasEvent } from '@/hooks/useCanvasEvent'
|
import { useCanvasEvent } from '@/hooks/useCanvasEvent'
|
||||||
import { contextMenuListState, contextMenuState } from '@/store/contextMenu'
|
import { contextMenuListState, contextMenuState } from '@/store/contextMenu'
|
||||||
import PanelEdit from '@/components/floor-plan/modal/module/PanelEdit'
|
import PanelEdit, { PANEL_EDIT_TYPE } from '@/components/floor-plan/modal/module/PanelEdit'
|
||||||
import DimensionLineSetting from '@/components/floor-plan/modal/dimensionLine/DimensionLineSetting'
|
import DimensionLineSetting from '@/components/floor-plan/modal/dimensionLine/DimensionLineSetting'
|
||||||
import ColumnRemove from '@/components/floor-plan/modal/module/column/ColumnRemove'
|
import ColumnRemove from '@/components/floor-plan/modal/module/column/ColumnRemove'
|
||||||
import ColumnInsert from '@/components/floor-plan/modal/module/column/ColumnInsert'
|
import ColumnInsert from '@/components/floor-plan/modal/module/column/ColumnInsert'
|
||||||
@ -36,6 +36,7 @@ import { fontSelector, globalFontAtom } from '@/store/fontAtom'
|
|||||||
import { useLine } from '@/hooks/useLine'
|
import { useLine } from '@/hooks/useLine'
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
import ContextRoofAllocationSetting from '@/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting'
|
import ContextRoofAllocationSetting from '@/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting'
|
||||||
|
import { useRoofFn } from '@/hooks/common/useRoofFn'
|
||||||
|
|
||||||
export function useContextMenu() {
|
export function useContextMenu() {
|
||||||
const canvas = useRecoilValue(canvasState)
|
const canvas = useRecoilValue(canvasState)
|
||||||
@ -59,6 +60,7 @@ export function useContextMenu() {
|
|||||||
const { addLine, removeLine } = useLine()
|
const { addLine, removeLine } = useLine()
|
||||||
const commonTextFont = useRecoilValue(fontSelector('commonText'))
|
const commonTextFont = useRecoilValue(fontSelector('commonText'))
|
||||||
const { swalFire } = useSwal()
|
const { swalFire } = useSwal()
|
||||||
|
const { removeRoofMaterial, removeAllRoofMaterial } = useRoofFn()
|
||||||
|
|
||||||
const currentMenuSetting = () => {
|
const currentMenuSetting = () => {
|
||||||
switch (currentMenu) {
|
switch (currentMenu) {
|
||||||
@ -110,10 +112,12 @@ export function useContextMenu() {
|
|||||||
{
|
{
|
||||||
id: 'roofMaterialRemove',
|
id: 'roofMaterialRemove',
|
||||||
name: getMessage('contextmenu.roof.material.remove'),
|
name: getMessage('contextmenu.roof.material.remove'),
|
||||||
|
fn: () => removeRoofMaterial(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'roofMaterialRemoveAll',
|
id: 'roofMaterialRemoveAll',
|
||||||
name: getMessage('contextmenu.roof.material.remove.all'),
|
name: getMessage('contextmenu.roof.material.remove.all'),
|
||||||
|
fn: () => removeAllRoofMaterial(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'selectMove',
|
id: 'selectMove',
|
||||||
@ -609,24 +613,24 @@ export function useContextMenu() {
|
|||||||
{
|
{
|
||||||
id: 'move',
|
id: 'move',
|
||||||
name: getMessage('contextmenu.move'),
|
name: getMessage('contextmenu.move'),
|
||||||
component: <PanelEdit id={popupId} type={'move'} />,
|
component: <PanelEdit id={popupId} type={PANEL_EDIT_TYPE.MOVE} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'copy',
|
id: 'copy',
|
||||||
name: getMessage('contextmenu.copy'),
|
name: getMessage('contextmenu.copy'),
|
||||||
component: <PanelEdit id={popupId} type={'copy'} />,
|
component: <PanelEdit id={popupId} type={PANEL_EDIT_TYPE.COPY} />,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
id: 'columnMove',
|
id: 'columnMove',
|
||||||
name: getMessage('contextmenu.column.move'),
|
name: getMessage('contextmenu.column.move'),
|
||||||
component: <PanelEdit id={popupId} type={'columnMove'} />,
|
component: <PanelEdit id={popupId} type={PANEL_EDIT_TYPE.COLUMN_MOVE} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'columnCopy',
|
id: 'columnCopy',
|
||||||
name: getMessage('contextmenu.column.copy'),
|
name: getMessage('contextmenu.column.copy'),
|
||||||
component: <PanelEdit id={popupId} type={'columnCopy'} />,
|
component: <PanelEdit id={popupId} type={PANEL_EDIT_TYPE.COLUMN_COPY} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'columnRemove',
|
id: 'columnRemove',
|
||||||
@ -643,12 +647,12 @@ export function useContextMenu() {
|
|||||||
{
|
{
|
||||||
id: 'rowMove',
|
id: 'rowMove',
|
||||||
name: getMessage('contextmenu.row.move'),
|
name: getMessage('contextmenu.row.move'),
|
||||||
component: <PanelEdit id={popupId} type={'rowMove'} />,
|
component: <PanelEdit id={popupId} type={PANEL_EDIT_TYPE.ROW_MOVE} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'rowCopy',
|
id: 'rowCopy',
|
||||||
name: getMessage('contextmenu.row.copy'),
|
name: getMessage('contextmenu.row.copy'),
|
||||||
component: <PanelEdit id={popupId} type={'rowCopy'} />,
|
component: <PanelEdit id={popupId} type={PANEL_EDIT_TYPE.ROW_COPY} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'rowRemove',
|
id: 'rowRemove',
|
||||||
|
|||||||
@ -224,9 +224,9 @@ export const roofMaterialsAtom = atom({
|
|||||||
export const selectedRoofMaterialSelector = selector({
|
export const selectedRoofMaterialSelector = selector({
|
||||||
key: 'selectedRoofMaterialSelector',
|
key: 'selectedRoofMaterialSelector',
|
||||||
get: ({ get }) => {
|
get: ({ get }) => {
|
||||||
const basicSetting = get(basicSettingState)
|
const addedRoofs = get(addedRoofsState)
|
||||||
|
|
||||||
return { ...basicSetting.selectedRoofMaterial }
|
return addedRoofs.find((roof) => roof.selected)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -239,16 +239,6 @@ export const roofMaterialsSelector = selector({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// 지붕면 할당에서 추가된 지붕재 목록
|
|
||||||
export const addedRoofsSelector = selector({
|
|
||||||
key: 'addedRoofsSelector',
|
|
||||||
get: ({ get }) => {
|
|
||||||
const basicSetting = get(basicSettingState)
|
|
||||||
return basicSetting.roofs
|
|
||||||
},
|
|
||||||
dangerouslyAllowMutability: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 현재 선택된 물건 번호
|
* 현재 선택된 물건 번호
|
||||||
*/
|
*/
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user