Merge remote-tracking branch 'origin/qcast-pub' into dev
This commit is contained in:
commit
380f63590f
File diff suppressed because one or more lines are too long
@ -66,7 +66,7 @@ export default function ColorPickerModal(props) {
|
|||||||
|
|
||||||
//치수선색설정 아닐 때만 바로 저장 실행
|
//치수선색설정 아닐 때만 바로 저장 실행
|
||||||
if (name !== 'DimensionLineColor')
|
if (name !== 'DimensionLineColor')
|
||||||
setSettingsData({
|
setSettingsDataSave({
|
||||||
...settingsData,
|
...settingsData,
|
||||||
color: originColor,
|
color: originColor,
|
||||||
})
|
})
|
||||||
|
|||||||
@ -40,105 +40,44 @@ export default function PanelEdit(props) {
|
|||||||
|
|
||||||
//모듈 이동 적용
|
//모듈 이동 적용
|
||||||
const handleApply = () => {
|
const handleApply = () => {
|
||||||
// const activeModuleIds = canvas.getActiveObjects().map((obj) => obj.id)
|
switch (type) {
|
||||||
if (type === PANEL_EDIT_TYPE.MOVE) {
|
case PANEL_EDIT_TYPE.MOVE:
|
||||||
moduleMove(length, direction)
|
moduleMove(length, direction)
|
||||||
} else if (type === PANEL_EDIT_TYPE.COPY) {
|
break
|
||||||
moduleCopy(length, direction)
|
case PANEL_EDIT_TYPE.COPY:
|
||||||
} else if (type === PANEL_EDIT_TYPE.COLUMN_MOVE) {
|
moduleCopy(length, direction)
|
||||||
moduleMultiMove('column', length, direction)
|
break
|
||||||
} else if (type === PANEL_EDIT_TYPE.COLUMN_COPY) {
|
case PANEL_EDIT_TYPE.COLUMN_MOVE:
|
||||||
moduleMultiCopy('column', length, direction)
|
moduleMultiMove('column', length, direction)
|
||||||
} else if (type === PANEL_EDIT_TYPE.ROW_MOVE) {
|
break
|
||||||
moduleMultiMove('row', length, direction)
|
case PANEL_EDIT_TYPE.COLUMN_COPY:
|
||||||
} else if (type === PANEL_EDIT_TYPE.ROW_COPY) {
|
moduleMultiCopy('column', length, direction)
|
||||||
moduleMultiCopy('row', length, direction)
|
break
|
||||||
|
case PANEL_EDIT_TYPE.ROW_MOVE:
|
||||||
|
moduleMultiMove('row', length, direction)
|
||||||
|
break
|
||||||
|
case PANEL_EDIT_TYPE.ROW_COPY:
|
||||||
|
moduleMultiCopy('row', length, direction)
|
||||||
|
break
|
||||||
}
|
}
|
||||||
closePopup(id)
|
closePopup(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
const contextModuleMove = (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 = []
|
|
||||||
|
|
||||||
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)
|
|
||||||
})
|
|
||||||
|
|
||||||
const isNotOverlap = isOverlapArray.some((isOverlap) => isOverlap) // true면 겹침
|
|
||||||
const isNotOutSurface = isInSurfaceArray.every((isOutSurface) => isOutSurface) //false면 밖으로 나감
|
|
||||||
|
|
||||||
//안겹치고 안나갔으면 이동시킨다 아니면 원래 위치로 돌려놓는다
|
|
||||||
if (isNotOverlap || !isNotOutSurface) {
|
|
||||||
selectedModules.forEach((module) => {
|
|
||||||
module.set({ ...module, left: module.originCoords.left, top: module.originCoords.top })
|
|
||||||
module.setCoords()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas.add(...selectedModules)
|
|
||||||
canvas.renderAll()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<WithDraggable isShow={true} pos={pos}>
|
<WithDraggable isShow={true} pos={pos}>
|
||||||
<div className={`modal-pop-wrap xm mount`}>
|
<div className={`modal-pop-wrap xm mount`}>
|
||||||
<div className="modal-head">
|
<div className="modal-head">
|
||||||
<h1 className="title">{getMessage(type === 'move' ? 'modal.move.setting' : 'modal.copy.setting')} </h1>
|
<h1 className="title">
|
||||||
|
{getMessage([PANEL_EDIT_TYPE.MOVE, PANEL_EDIT_TYPE.COLUMN_MOVE].includes(type) ? 'modal.move.setting' : 'modal.copy.setting')}{' '}
|
||||||
|
</h1>
|
||||||
<button className="modal-close" onClick={() => closePopup(id)}>
|
<button className="modal-close" onClick={() => closePopup(id)}>
|
||||||
닫기
|
닫기
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="modal-body">
|
<div className="modal-body">
|
||||||
<div className="grid-option-tit">{getMessage(type === 'move' ? 'modal.move.setting.info' : 'modal.copy.setting.info')}</div>
|
<div className="grid-option-tit">
|
||||||
|
{getMessage([PANEL_EDIT_TYPE.MOVE, PANEL_EDIT_TYPE.COLUMN_MOVE].includes(type) ? 'modal.move.setting.info' : 'modal.copy.setting.info')}
|
||||||
|
</div>
|
||||||
<div className="grid-option-wrap">
|
<div className="grid-option-wrap">
|
||||||
<div className="grid-option-box">
|
<div className="grid-option-box">
|
||||||
<div className="grid-input-form">
|
<div className="grid-input-form">
|
||||||
|
|||||||
@ -28,11 +28,7 @@ export function useGrid() {
|
|||||||
// 1. 점.선 그리드 설정으로 만들어진 기존 오브젝트 제거
|
// 1. 점.선 그리드 설정으로 만들어진 기존 오브젝트 제거
|
||||||
canvas
|
canvas
|
||||||
?.getObjects()
|
?.getObjects()
|
||||||
.filter((obj) => obj.name === 'lineGrid')
|
.filter((obj) => ['lineGrid', 'dotGrid'].includes(obj.name))
|
||||||
.forEach((obj) => canvas?.remove(obj))
|
|
||||||
canvas
|
|
||||||
?.getObjects()
|
|
||||||
.filter((obj) => obj.name === 'dotGrid')
|
|
||||||
.forEach((obj) => canvas?.remove(obj))
|
.forEach((obj) => canvas?.remove(obj))
|
||||||
|
|
||||||
//const horizontalInterval = interval.horizontalInterval
|
//const horizontalInterval = interval.horizontalInterval
|
||||||
@ -181,8 +177,17 @@ export function useGrid() {
|
|||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const removeGrid = () => {
|
||||||
|
canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => ['lineGrid', 'dotGrid', 'tempGrid'].includes(obj.name))
|
||||||
|
.forEach((obj) => canvas.remove(obj))
|
||||||
|
canvas.renderAll()
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
move,
|
move,
|
||||||
copy,
|
copy,
|
||||||
|
removeGrid,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,8 +5,8 @@ import { useRecoilValue } from 'recoil'
|
|||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
import * as turf from '@turf/turf'
|
import * as turf from '@turf/turf'
|
||||||
import { useSwal } from '../useSwal'
|
import { useSwal } from '../useSwal'
|
||||||
import { QPolygon } from '@/components/fabric/QPolygon'
|
|
||||||
import { useModuleBasicSetting } from './useModuleBasicSetting'
|
import { useModuleBasicSetting } from './useModuleBasicSetting'
|
||||||
|
import { useMessage } from '../useMessage'
|
||||||
|
|
||||||
export const MODULE_REMOVE_TYPE = {
|
export const MODULE_REMOVE_TYPE = {
|
||||||
LEFT: 'left',
|
LEFT: 'left',
|
||||||
@ -25,9 +25,14 @@ export const MODULE_INSERT_TYPE = {
|
|||||||
BOTTOM: 'down',
|
BOTTOM: 'down',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const MODULE_ALIGN_TYPE = {
|
||||||
|
TOP: 'top',
|
||||||
|
}
|
||||||
|
|
||||||
export function useModule() {
|
export function useModule() {
|
||||||
const canvas = useRecoilValue(canvasState)
|
const canvas = useRecoilValue(canvasState)
|
||||||
const { swalFire } = useSwal()
|
const { swalFire } = useSwal()
|
||||||
|
const { getMessage } = useMessage()
|
||||||
const { checkModuleDisjointObjects } = useModuleBasicSetting()
|
const { checkModuleDisjointObjects } = useModuleBasicSetting()
|
||||||
|
|
||||||
const moduleMove = (length, direction) => {
|
const moduleMove = (length, direction) => {
|
||||||
@ -99,7 +104,7 @@ export function useModule() {
|
|||||||
? '모듈이 오브젝트와 겹칩니다.'
|
? '모듈이 오브젝트와 겹칩니다.'
|
||||||
: '영역 밖',
|
: '영역 밖',
|
||||||
icon: 'error',
|
icon: 'error',
|
||||||
type: 'confirm',
|
type: 'alert',
|
||||||
confirmFn: () => {
|
confirmFn: () => {
|
||||||
selectedModules.forEach((module) => {
|
selectedModules.forEach((module) => {
|
||||||
module.set({ ...module, left: module.originCoords.left, top: module.originCoords.top })
|
module.set({ ...module, left: module.originCoords.left, top: module.originCoords.top })
|
||||||
@ -123,47 +128,55 @@ export function useModule() {
|
|||||||
const moduleSetupSurface = canvas
|
const moduleSetupSurface = canvas
|
||||||
.getObjects()
|
.getObjects()
|
||||||
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === modules[0].surfaceId)[0]
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === modules[0].surfaceId)[0]
|
||||||
let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
|
let isWarning = false
|
||||||
|
let copyModules = []
|
||||||
|
let copyModule = null
|
||||||
canvas.discardActiveObject() //선택해제
|
canvas.discardActiveObject() //선택해제
|
||||||
modules.forEach((module) => {
|
modules.forEach((module) => {
|
||||||
const { top, left } = getPosotion(module, direction, length, true)
|
const { top, left } = getPosotion(module, direction, length, true)
|
||||||
const moduleOptions = { ...module, left, top, id: uuidv4() }
|
module.clone((obj) => {
|
||||||
const rect = new QPolygon(module.points, moduleOptions)
|
obj.set({
|
||||||
canvas.add(rect)
|
parentId: module.parentId,
|
||||||
rect.setCoords()
|
initOptions: module.initOptions,
|
||||||
canvas.renderAll()
|
direction: module.direction,
|
||||||
|
arrow: module.arrow,
|
||||||
isOverlapOtherModules.push(
|
name: module.name,
|
||||||
otherModules.some(
|
type: module.type,
|
||||||
(otherModule) =>
|
length: module.length,
|
||||||
turf.booleanOverlap(polygonToTurfPolygon(rect, true), polygonToTurfPolygon(otherModule, true)) ||
|
points: module.points,
|
||||||
turf.booleanWithin(polygonToTurfPolygon(rect, true), polygonToTurfPolygon(otherModule, true)),
|
surfaceId: module.surfaceId,
|
||||||
),
|
left,
|
||||||
)
|
top,
|
||||||
|
id: uuidv4(),
|
||||||
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(rect, true), objects))
|
})
|
||||||
|
copyModules.push(obj)
|
||||||
isOutsideSurface.push(
|
copyModule = obj
|
||||||
!turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(rect, true)) ||
|
canvas.add(obj)
|
||||||
!turf.booleanWithin(polygonToTurfPolygon(rect, true), polygonToTurfPolygon(moduleSetupSurface, true)),
|
canvas.renderAll()
|
||||||
)
|
})
|
||||||
|
|
||||||
if (
|
if (
|
||||||
isOverlapOtherModules.some((isOverlap) => isOverlap) ||
|
isOverlapOtherModules(copyModule, otherModules) ||
|
||||||
isOutsideSurface.some((isOutside) => isOutside) ||
|
isOverlapObjects(copyModule, objects) ||
|
||||||
isOverlapObjects.some((isOverlap) => isOverlap)
|
isOutsideSurface(copyModule, moduleSetupSurface)
|
||||||
) {
|
) {
|
||||||
swalFire({
|
isWarning = true
|
||||||
title: isOverlapOtherModules ? '겹치는 모듈이 있습니다.' : isOutsideSurface ? '모듈이 오브젝트와 겹칩니다.' : '영역 밖',
|
copyModule.set({ fill: 'red' })
|
||||||
icon: 'error',
|
canvas.renderAll()
|
||||||
type: 'confirm',
|
|
||||||
confirmFn: () => {
|
|
||||||
canvas.remove(rect)
|
|
||||||
canvas.renderAll()
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (isWarning) {
|
||||||
|
swalFire({
|
||||||
|
title: getMessage('can.not.copy.module'),
|
||||||
|
icon: 'error',
|
||||||
|
type: 'alert',
|
||||||
|
confirmFn: () => {
|
||||||
|
canvas.remove(...copyModules)
|
||||||
|
canvas.renderAll()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const moduleMultiMove = (type, length, direction) => {
|
const moduleMultiMove = (type, length, direction) => {
|
||||||
@ -181,18 +194,17 @@ export function useModule() {
|
|||||||
const modules = type === 'row' ? getRowModules(activeModule) : getColumnModules(activeModule)
|
const modules = type === 'row' ? getRowModules(activeModule) : getColumnModules(activeModule)
|
||||||
const otherModules = getOtherModules(modules)
|
const otherModules = getOtherModules(modules)
|
||||||
const objects = getObjects()
|
const objects = getObjects()
|
||||||
console.log('🚀 ~ moduleMultiMove ~ objects:', objects)
|
|
||||||
|
|
||||||
const moduleSetupSurface = canvas
|
const moduleSetupSurface = canvas
|
||||||
.getObjects()
|
.getObjects()
|
||||||
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
|
||||||
let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
|
let isWarning = false
|
||||||
|
|
||||||
modules.forEach((module) => {
|
modules.forEach((module) => {
|
||||||
const { top, left } = getPosotion(module, direction, length, false)
|
const { top, left } = getPosotion(module, direction, length, false)
|
||||||
module.originPos = {
|
module.originPos = {
|
||||||
top: module.top,
|
top: module.top,
|
||||||
left: module.left,
|
left: module.left,
|
||||||
|
fill: module.fill,
|
||||||
}
|
}
|
||||||
|
|
||||||
module.set({ top, left })
|
module.set({ top, left })
|
||||||
@ -200,41 +212,22 @@ export function useModule() {
|
|||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
|
|
||||||
if (otherModules.length > 0) {
|
if (otherModules.length > 0) {
|
||||||
isOverlapOtherModules.push(
|
if (isOverlapOtherModules(module, otherModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
||||||
otherModules.some(
|
isWarning = true
|
||||||
(otherModule) =>
|
module.set({ fill: 'red' })
|
||||||
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 (
|
canvas.renderAll()
|
||||||
isOverlapOtherModules.some((isOverlap) => isOverlap) ||
|
if (isWarning) {
|
||||||
isOverlapObjects.some((isOverlap) => isOverlap) ||
|
|
||||||
isOutsideSurface.some((isOutside) => isOutside)
|
|
||||||
) {
|
|
||||||
swalFire({
|
swalFire({
|
||||||
title: isOverlapOtherModules.some((isOverlap) => isOverlap)
|
title: getMessage('can.not.move.module'),
|
||||||
? '겹치는 모듈이 있습니다.'
|
|
||||||
: isOverlapObjects.some((isOverlap) => isOverlap)
|
|
||||||
? '모듈이 오브젝트와 겹칩니다.'
|
|
||||||
: '영역 밖',
|
|
||||||
icon: 'error',
|
icon: 'error',
|
||||||
type: 'confirm',
|
type: 'alert',
|
||||||
confirmFn: () => {
|
confirmFn: () => {
|
||||||
modules.forEach((module) => {
|
modules.forEach((module) => {
|
||||||
module.set({ top: module.originPos.top, left: module.originPos.left })
|
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
})
|
})
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
@ -258,11 +251,12 @@ export function useModule() {
|
|||||||
const modules = type === 'row' ? getRowModules(activeModule) : getColumnModules(activeModule)
|
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 otherModules = canvas.getObjects().filter((obj) => obj.surfaceId === modules[0].surfaceId && obj.name === POLYGON_TYPE.MODULE)
|
||||||
const objects = getObjects()
|
const objects = getObjects()
|
||||||
const copyRects = []
|
const copyModules = []
|
||||||
|
let copyModule = null
|
||||||
const moduleSetupSurface = canvas
|
const moduleSetupSurface = canvas
|
||||||
.getObjects()
|
.getObjects()
|
||||||
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === modules[0].surfaceId)[0]
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === modules[0].surfaceId)[0]
|
||||||
let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
|
let isWarning = false
|
||||||
let moduleLength = 0
|
let moduleLength = 0
|
||||||
if (['up', 'down'].includes(direction)) {
|
if (['up', 'down'].includes(direction)) {
|
||||||
moduleLength = Number(modules[modules.length - 1].top) + Number(modules[modules.length - 1].height) - Number(modules[0].top)
|
moduleLength = Number(modules[modules.length - 1].top) + Number(modules[modules.length - 1].height) - Number(modules[0].top)
|
||||||
@ -272,52 +266,47 @@ export function useModule() {
|
|||||||
|
|
||||||
modules.forEach((module) => {
|
modules.forEach((module) => {
|
||||||
const { top, left } = getPosotion(module, direction, Number(length) + Number(moduleLength), false)
|
const { top, left } = getPosotion(module, direction, Number(length) + Number(moduleLength), false)
|
||||||
const moduleOptions = { ...module, left, top, id: uuidv4() }
|
module.clone((obj) => {
|
||||||
const rect = new QPolygon(module.getCurrentPoints(), moduleOptions)
|
obj.set({
|
||||||
canvas.add(rect)
|
parentId: module.parentId,
|
||||||
copyRects.push(rect)
|
initOptions: module.initOptions,
|
||||||
module.setCoords()
|
direction: module.direction,
|
||||||
|
arrow: module.arrow,
|
||||||
if (otherModules.length > 0) {
|
name: module.name,
|
||||||
isOverlapOtherModules.push(
|
type: module.type,
|
||||||
otherModules.some(
|
length: module.length,
|
||||||
(otherModule) =>
|
points: module.points,
|
||||||
turf.booleanOverlap(polygonToTurfPolygon(rect, true), polygonToTurfPolygon(otherModule, true)) ||
|
surfaceId: module.surfaceId,
|
||||||
turf.booleanWithin(polygonToTurfPolygon(rect, true), polygonToTurfPolygon(otherModule, true)),
|
left,
|
||||||
),
|
top,
|
||||||
)
|
id: uuidv4(),
|
||||||
|
})
|
||||||
|
copyModule = obj
|
||||||
|
canvas.add(obj)
|
||||||
|
copyModules.push(obj)
|
||||||
|
obj.setCoords()
|
||||||
|
})
|
||||||
|
if (
|
||||||
|
isOverlapOtherModules(copyModule, otherModules) ||
|
||||||
|
isOverlapObjects(copyModule, objects) ||
|
||||||
|
isOutsideSurface(copyModule, moduleSetupSurface)
|
||||||
|
) {
|
||||||
|
isWarning = true
|
||||||
|
copyModule.set({ fill: 'red' })
|
||||||
}
|
}
|
||||||
|
canvas.renderAll()
|
||||||
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 (
|
if (isWarning) {
|
||||||
isOverlapOtherModules.some((isOverlap) => isOverlap) ||
|
|
||||||
isOverlapObjects.some((isOverlap) => isOverlap) ||
|
|
||||||
isOutsideSurface.some((isOutside) => isOutside)
|
|
||||||
) {
|
|
||||||
swalFire({
|
swalFire({
|
||||||
title: isOverlapOtherModules.some((isOverlap) => isOverlap)
|
title: getMessage('can.not.copy.module'),
|
||||||
? '겹치는 모듈이 있습니다.'
|
|
||||||
: isOverlapObjects.some((isOverlap) => isOverlap)
|
|
||||||
? '모듈이 오브젝트와 겹칩니다.'
|
|
||||||
: '영역 밖',
|
|
||||||
icon: 'error',
|
icon: 'error',
|
||||||
type: 'confirm',
|
type: 'alert',
|
||||||
confirmFn: () => {
|
confirmFn: () => {
|
||||||
canvas.remove(...copyRects)
|
canvas.remove(...copyModules)
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
|
||||||
canvas.renderAll()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,7 +322,7 @@ export function useModule() {
|
|||||||
const moduleSetupSurface = canvas
|
const moduleSetupSurface = canvas
|
||||||
.getObjects()
|
.getObjects()
|
||||||
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
|
||||||
let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
|
let isWarning = false
|
||||||
canvas.discardActiveObject()
|
canvas.discardActiveObject()
|
||||||
canvas.remove(...columnModules)
|
canvas.remove(...columnModules)
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
@ -343,30 +332,36 @@ export function useModule() {
|
|||||||
module.originPos = {
|
module.originPos = {
|
||||||
left: module.left,
|
left: module.left,
|
||||||
top: module.top,
|
top: module.top,
|
||||||
|
fill: module.fill,
|
||||||
}
|
}
|
||||||
if (width === -1) width = module.left - activeModule.left
|
if (width === -1) width = module.left - activeModule.left
|
||||||
module.set({ left: module.left - width })
|
module.set({ left: module.left - width })
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
isOverlapOtherModules.push(getIsOverlapOtherModules(module, leftModules))
|
if (isOverlapOtherModules(module, leftModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
||||||
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
module.set({ fill: 'red' })
|
||||||
isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
|
isWarning = true
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
canvas.renderAll()
|
||||||
targetModules = rightModules
|
targetModules = rightModules
|
||||||
} else if (type === MODULE_REMOVE_TYPE.RIGHT) {
|
} else if (type === MODULE_REMOVE_TYPE.RIGHT) {
|
||||||
leftModules.forEach((module) => {
|
leftModules.forEach((module) => {
|
||||||
module.originPos = {
|
module.originPos = {
|
||||||
left: module.left,
|
left: module.left,
|
||||||
top: module.top,
|
top: module.top,
|
||||||
|
fill: module.fill,
|
||||||
}
|
}
|
||||||
if (width === -1) width = activeModule.left - module.left
|
if (width === -1) width = activeModule.left - module.left
|
||||||
module.set({ left: module.left + width })
|
module.set({ left: module.left + width })
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
isOverlapOtherModules.push(getIsOverlapOtherModules(module, rightModules))
|
if (isOverlapOtherModules(module, rightModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
||||||
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
module.set({ fill: 'red' })
|
||||||
isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
|
isWarning = true
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
canvas.renderAll()
|
||||||
targetModules = leftModules
|
targetModules = leftModules
|
||||||
} else if (type === MODULE_REMOVE_TYPE.HORIZONTAL_SIDE) {
|
} else if (type === MODULE_REMOVE_TYPE.HORIZONTAL_SIDE) {
|
||||||
const sideModules = [...leftModules, ...rightModules]
|
const sideModules = [...leftModules, ...rightModules]
|
||||||
@ -374,6 +369,7 @@ export function useModule() {
|
|||||||
module.originPos = {
|
module.originPos = {
|
||||||
left: module.left,
|
left: module.left,
|
||||||
top: module.top,
|
top: module.top,
|
||||||
|
fill: module.fill,
|
||||||
}
|
}
|
||||||
if (width === -1) width = activeModule.left - module.left
|
if (width === -1) width = activeModule.left - module.left
|
||||||
module.set({ left: module.left + width / 2 })
|
module.set({ left: module.left + width / 2 })
|
||||||
@ -385,50 +381,46 @@ export function useModule() {
|
|||||||
module.originPos = {
|
module.originPos = {
|
||||||
left: module.left,
|
left: module.left,
|
||||||
top: module.top,
|
top: module.top,
|
||||||
|
fill: module.fill,
|
||||||
}
|
}
|
||||||
if (width === -1) width = module.left - activeModule.left
|
if (width === -1) width = module.left - activeModule.left
|
||||||
module.set({ left: module.left - width / 2 })
|
module.set({ left: module.left - width / 2 })
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
})
|
})
|
||||||
canvas.renderAll()
|
|
||||||
sideModules.forEach((module) => {
|
sideModules.forEach((module) => {
|
||||||
isOverlapOtherModules.push(
|
if (
|
||||||
getIsOverlapOtherModules(
|
isOverlapOtherModules(
|
||||||
module,
|
module,
|
||||||
sideModules.filter((m) => m.id !== module.id),
|
sideModules.filter((m) => m.id !== module.id),
|
||||||
),
|
) ||
|
||||||
)
|
isOverlapObjects(module, objects) ||
|
||||||
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
isOutsideSurface(module, moduleSetupSurface)
|
||||||
isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
|
) {
|
||||||
|
isWarning = true
|
||||||
|
module.set({ fill: 'red' })
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
targetModules = sideModules
|
targetModules = sideModules
|
||||||
}
|
}
|
||||||
if (
|
canvas.renderAll()
|
||||||
(isOverlapOtherModules.some((isOverlap) => isOverlap) ||
|
if (isWarning) {
|
||||||
isOverlapObjects.some((isOverlap) => isOverlap) ||
|
|
||||||
isOutsideSurface.some((isOutside) => isOutside)) &&
|
|
||||||
type !== MODULE_REMOVE_TYPE.NONE
|
|
||||||
) {
|
|
||||||
swalFire({
|
swalFire({
|
||||||
title: isOverlapOtherModules.some((isOverlap) => isOverlap)
|
title: getMessage('can.not.remove.module'),
|
||||||
? '겹치는 모듈이 있습니다.'
|
|
||||||
: isOverlapObjects.some((isOverlap) => isOverlap)
|
|
||||||
? '모듈이 오브젝트와 겹칩니다.'
|
|
||||||
: '영역 밖',
|
|
||||||
icon: 'error',
|
icon: 'error',
|
||||||
type: 'confirm',
|
type: 'alert',
|
||||||
confirmFn: () => {
|
confirmFn: () => {
|
||||||
canvas.add(...columnModules)
|
canvas.add(...columnModules)
|
||||||
targetModules.forEach((module) => {
|
targetModules.forEach((module) => {
|
||||||
module.set({ top: module.originPos.top, left: module.originPos.left })
|
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
})
|
})
|
||||||
|
canvas.renderAll()
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
canvas.renderAll()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const moduleRowRemove = (type) => {
|
const moduleRowRemove = (type) => {
|
||||||
@ -443,7 +435,7 @@ export function useModule() {
|
|||||||
const moduleSetupSurface = canvas
|
const moduleSetupSurface = canvas
|
||||||
.getObjects()
|
.getObjects()
|
||||||
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
|
||||||
let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
|
let isWarning = false
|
||||||
|
|
||||||
canvas.discardActiveObject()
|
canvas.discardActiveObject()
|
||||||
canvas.remove(...rowModules)
|
canvas.remove(...rowModules)
|
||||||
@ -454,29 +446,34 @@ export function useModule() {
|
|||||||
module.originPos = {
|
module.originPos = {
|
||||||
left: module.left,
|
left: module.left,
|
||||||
top: module.top,
|
top: module.top,
|
||||||
|
fill: module.fill,
|
||||||
}
|
}
|
||||||
if (height === -1) height = module.top - activeModule.top
|
if (height === -1) height = module.top - activeModule.top
|
||||||
module.set({ top: module.top - height })
|
module.set({ top: module.top - height })
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
isOverlapOtherModules.push(getIsOverlapOtherModules(module, topModules))
|
if (isOverlapOtherModules(module, topModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
||||||
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
isWarning = true
|
||||||
isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
|
module.set({ fill: 'red' })
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
canvas.renderAll()
|
||||||
targetModules = bottomModules
|
targetModules = bottomModules
|
||||||
} else if (type === MODULE_REMOVE_TYPE.BOTTOM) {
|
} else if (type === MODULE_REMOVE_TYPE.BOTTOM) {
|
||||||
topModules.forEach((module) => {
|
topModules.forEach((module) => {
|
||||||
module.originPos = {
|
module.originPos = {
|
||||||
left: module.left,
|
left: module.left,
|
||||||
top: module.top,
|
top: module.top,
|
||||||
|
fill: module.fill,
|
||||||
}
|
}
|
||||||
if (height === -1) height = activeModule.top - module.top
|
if (height === -1) height = activeModule.top - module.top
|
||||||
module.set({ top: module.top + height })
|
module.set({ top: module.top + activeModule.height })
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
isOverlapOtherModules.push(getIsOverlapOtherModules(module, bottomModules))
|
if (isOverlapOtherModules(module, bottomModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
||||||
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
isWarning = true
|
||||||
isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
|
module.set({ fill: 'red' })
|
||||||
|
}
|
||||||
})
|
})
|
||||||
targetModules = topModules
|
targetModules = topModules
|
||||||
} else if (type === MODULE_REMOVE_TYPE.VERTICAL_SIDE) {
|
} else if (type === MODULE_REMOVE_TYPE.VERTICAL_SIDE) {
|
||||||
@ -484,63 +481,60 @@ export function useModule() {
|
|||||||
module.originPos = {
|
module.originPos = {
|
||||||
left: module.left,
|
left: module.left,
|
||||||
top: module.top,
|
top: module.top,
|
||||||
|
fill: module.fill,
|
||||||
}
|
}
|
||||||
if (height === -1) height = activeModule.top - module.top
|
// if (height === -1) height = activeModule.top - module.top
|
||||||
|
if (height === -1) height = activeModule.height
|
||||||
module.set({ top: module.top + height / 2 })
|
module.set({ top: module.top + height / 2 })
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
canvas.renderAll()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
bottomModules.forEach((module) => {
|
bottomModules.forEach((module) => {
|
||||||
module.originPos = {
|
module.originPos = {
|
||||||
left: module.left,
|
left: module.left,
|
||||||
top: module.top,
|
top: module.top,
|
||||||
|
fill: module.fill,
|
||||||
}
|
}
|
||||||
if (height === -1) height = module.top - activeModule.top
|
// if (height === -1) height = module.top - activeModule.top
|
||||||
|
if (height === -1) height = activeModule.height
|
||||||
module.set({ top: module.top - height / 2 })
|
module.set({ top: module.top - height / 2 })
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
canvas.renderAll()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const sideModules = [...topModules, ...bottomModules]
|
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
|
const sideModules = [...topModules, ...bottomModules]
|
||||||
sideModules.forEach((module) => {
|
sideModules.forEach((module) => {
|
||||||
isOverlapOtherModules.push(
|
if (
|
||||||
getIsOverlapOtherModules(
|
isOverlapOtherModules(
|
||||||
module,
|
module,
|
||||||
sideModules.filter((m) => m.id !== module.id),
|
sideModules.filter((m) => m.id !== module.id),
|
||||||
),
|
) ||
|
||||||
)
|
isOverlapObjects(module, objects) ||
|
||||||
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
isOutsideSurface(module, moduleSetupSurface)
|
||||||
isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
|
) {
|
||||||
|
isWarning = true
|
||||||
|
module.set({ fill: 'red' })
|
||||||
|
}
|
||||||
})
|
})
|
||||||
targetModules = sideModules
|
targetModules = sideModules
|
||||||
}
|
}
|
||||||
|
canvas.renderAll()
|
||||||
if (
|
if (isWarning && type !== MODULE_REMOVE_TYPE.NONE) {
|
||||||
(isOverlapOtherModules.some((isOverlap) => isOverlap) ||
|
targetModules.forEach((rect) => rect.set({ fill: 'red' }))
|
||||||
isOverlapObjects.some((isOverlap) => isOverlap) ||
|
|
||||||
isOutsideSurface.some((isOutside) => isOutside)) &&
|
|
||||||
type !== MODULE_REMOVE_TYPE.NONE
|
|
||||||
) {
|
|
||||||
swalFire({
|
swalFire({
|
||||||
title: isOverlapOtherModules.some((isOverlap) => isOverlap)
|
title: getMessage('can.not.remove.module'),
|
||||||
? '겹치는 모듈이 있습니다.'
|
|
||||||
: isOverlapObjects.some((isOverlap) => isOverlap)
|
|
||||||
? '모듈이 오브젝트와 겹칩니다.'
|
|
||||||
: '영역 밖',
|
|
||||||
icon: 'error',
|
icon: 'error',
|
||||||
type: 'confirm',
|
type: 'alert',
|
||||||
confirmFn: () => {
|
confirmFn: () => {
|
||||||
canvas.add(...rowModules)
|
canvas.add(...rowModules)
|
||||||
targetModules.forEach((module) => {
|
targetModules.forEach((module) => {
|
||||||
module.set({ top: module.originPos.top, left: module.originPos.left })
|
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
})
|
})
|
||||||
|
canvas.renderAll()
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
canvas.renderAll()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const moduleColumnInsert = (type) => {
|
const moduleColumnInsert = (type) => {
|
||||||
@ -550,14 +544,14 @@ export function useModule() {
|
|||||||
const targetModules =
|
const targetModules =
|
||||||
type === MODULE_INSERT_TYPE.LEFT
|
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) => a.left - b.left)
|
||||||
: otherModules.filter((module) => module.left > activeModule.left).sort((a, b) => b.left - a.left)
|
: otherModules.filter((module) => module.left > activeModule.left).sort((a, b) => a.left - b.left)
|
||||||
const objects = getObjects()
|
const objects = getObjects()
|
||||||
const copyModules = []
|
const copyModules = []
|
||||||
const moduleSetupSurface = canvas
|
const moduleSetupSurface = canvas
|
||||||
.getObjects()
|
.getObjects()
|
||||||
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
|
||||||
let width = -1
|
let width = -1
|
||||||
let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
|
let isWarning = false
|
||||||
if (targetModules.length === 0) {
|
if (targetModules.length === 0) {
|
||||||
swalFire({
|
swalFire({
|
||||||
title: '마지막 모듈입니다.',
|
title: '마지막 모듈입니다.',
|
||||||
@ -570,75 +564,68 @@ export function useModule() {
|
|||||||
targetModules.forEach((module) => {
|
targetModules.forEach((module) => {
|
||||||
if (width === -1)
|
if (width === -1)
|
||||||
width = type === MODULE_INSERT_TYPE.LEFT ? Number(activeModule.left) - Number(module.left) : Number(module.left) - Number(activeModule.left)
|
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)
|
const { top, left } = getPosotion(module, type, module.width, false)
|
||||||
module.originPos = {
|
module.originPos = {
|
||||||
left: module.left,
|
left: module.left,
|
||||||
top: module.top,
|
top: module.top,
|
||||||
|
fill: module.fill,
|
||||||
}
|
}
|
||||||
module.set({ left, top })
|
module.set({ left, top })
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
if (objects.length > 0) {
|
if (isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
||||||
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
isWarning = true
|
||||||
|
module.set({ fill: 'red' })
|
||||||
}
|
}
|
||||||
|
|
||||||
isOutsideSurface.push(
|
|
||||||
!turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(module, true)) ||
|
|
||||||
!turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(moduleSetupSurface, true)),
|
|
||||||
)
|
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
})
|
})
|
||||||
|
canvas.renderAll()
|
||||||
otherModules = getOtherModules(columnModules)
|
otherModules = getOtherModules(columnModules)
|
||||||
columnModules.forEach((module) => {
|
columnModules.forEach((module) => {
|
||||||
const { top, left } = getPosotion(module, type, width, false)
|
const { top, left } = getPosotion(module, type, module.width, false)
|
||||||
const moduleOptions = { ...module, left, top, id: uuidv4() }
|
let copyModule = null
|
||||||
const copyModule = new QPolygon(module.points, moduleOptions)
|
module.clone((obj) => {
|
||||||
canvas.add(copyModule)
|
obj.set({
|
||||||
copyModules.push(copyModule)
|
parentId: module.parentId,
|
||||||
|
initOptions: module.initOptions,
|
||||||
|
direction: module.direction,
|
||||||
|
arrow: module.arrow,
|
||||||
|
name: module.name,
|
||||||
|
type: module.type,
|
||||||
|
length: module.length,
|
||||||
|
points: module.points,
|
||||||
|
surfaceId: module.surfaceId,
|
||||||
|
left,
|
||||||
|
top,
|
||||||
|
id: uuidv4(),
|
||||||
|
})
|
||||||
|
copyModule = obj
|
||||||
|
canvas.add(obj)
|
||||||
|
copyModules.push(obj)
|
||||||
|
obj.setCoords()
|
||||||
|
})
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
|
|
||||||
if (otherModules.length > 0) {
|
if (
|
||||||
isOverlapOtherModules.push(
|
isOverlapOtherModules(copyModule, otherModules) ||
|
||||||
otherModules.some(
|
isOverlapObjects(copyModule, objects) ||
|
||||||
(otherModule) =>
|
isOutsideSurface(copyModule, moduleSetupSurface)
|
||||||
turf.booleanOverlap(polygonToTurfPolygon(copyModule, true), polygonToTurfPolygon(otherModule, true)) ||
|
) {
|
||||||
turf.booleanWithin(polygonToTurfPolygon(copyModule, true), polygonToTurfPolygon(otherModule, true)),
|
isWarning = 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()
|
module.setCoords()
|
||||||
})
|
})
|
||||||
|
canvas.renderAll()
|
||||||
if (
|
if (isWarning) {
|
||||||
isOverlapOtherModules.some((isOverlap) => isOverlap) ||
|
|
||||||
isOverlapObjects.some((isOverlap) => isOverlap) ||
|
|
||||||
isOutsideSurface.some((isOutside) => isOutside)
|
|
||||||
) {
|
|
||||||
swalFire({
|
swalFire({
|
||||||
title: isOverlapOtherModules.some((isOverlap) => isOverlap)
|
title: getMessage('can.not.insert.module'),
|
||||||
? '겹치는 모듈이 있습니다.'
|
|
||||||
: isOverlapObjects.some((isOverlap) => isOverlap)
|
|
||||||
? '모듈이 오브젝트와 겹칩니다.'
|
|
||||||
: '영역 밖',
|
|
||||||
icon: 'error',
|
icon: 'error',
|
||||||
type: 'confirm',
|
type: 'alert',
|
||||||
confirmFn: () => {
|
confirmFn: () => {
|
||||||
targetModules.forEach((module) => {
|
targetModules.forEach((module) => {
|
||||||
module.set({ top: module.originPos.top, left: module.originPos.left })
|
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
})
|
})
|
||||||
canvas.renderAll()
|
canvas.remove(...copyModules)
|
||||||
copyModules.forEach((module) => {
|
|
||||||
canvas.remove(module)
|
|
||||||
})
|
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -646,16 +633,13 @@ export function useModule() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const muduleRowInsert = (type) => {
|
const muduleRowInsert = (type) => {
|
||||||
console.log('🚀 ~ muduleRowInsert ~ type:', type)
|
|
||||||
const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
|
const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
|
||||||
const rowModules = getRowModules(activeModule)
|
const rowModules = getRowModules(activeModule)
|
||||||
console.log('🚀 ~ muduleRowInsert ~ rowModules:', rowModules)
|
|
||||||
let otherModules = getOtherModules(rowModules)
|
let otherModules = getOtherModules(rowModules)
|
||||||
const targetModules =
|
const targetModules =
|
||||||
type === MODULE_INSERT_TYPE.TOP
|
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)
|
||||||
: otherModules.filter((module) => module.top > activeModule.top).sort((a, b) => a.top - b.top)
|
: otherModules.filter((module) => module.top > activeModule.top).sort((a, b) => a.top - b.top)
|
||||||
console.log('🚀 ~ muduleRowInsert ~ targetModules:', targetModules)
|
|
||||||
if (targetModules.length === 0) {
|
if (targetModules.length === 0) {
|
||||||
swalFire({
|
swalFire({
|
||||||
title: '마지막 모듈입니다.',
|
title: '마지막 모듈입니다.',
|
||||||
@ -670,86 +654,102 @@ export function useModule() {
|
|||||||
.getObjects()
|
.getObjects()
|
||||||
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
|
||||||
let height = -1
|
let height = -1
|
||||||
let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
|
let isWarning = false
|
||||||
canvas.discardActiveObject()
|
canvas.discardActiveObject()
|
||||||
targetModules.forEach((module) => {
|
targetModules.forEach((module) => {
|
||||||
if (height === -1)
|
if (height === -1)
|
||||||
height = type === MODULE_INSERT_TYPE.TOP ? Number(activeModule.top) - Number(module.top) : Number(module.top) - Number(activeModule.top)
|
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)
|
const { top, left } = getPosotion(module, type, activeModule.height, false)
|
||||||
module.originPos = {
|
module.originPos = {
|
||||||
left: module.left,
|
left: module.left,
|
||||||
top: module.top,
|
top: module.top,
|
||||||
|
fill: module.fill,
|
||||||
}
|
}
|
||||||
module.set({ left, top })
|
module.set({ left, top })
|
||||||
canvas.renderAll()
|
if (isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
||||||
if (objects.length > 0) {
|
isWarning = true
|
||||||
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
module.set({ fill: 'red' })
|
||||||
}
|
}
|
||||||
|
|
||||||
isOutsideSurface.push(
|
|
||||||
!turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(module, true)) ||
|
|
||||||
!turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(moduleSetupSurface, true)),
|
|
||||||
)
|
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
})
|
})
|
||||||
|
canvas.renderAll()
|
||||||
otherModules = getOtherModules(rowModules)
|
otherModules = getOtherModules(rowModules)
|
||||||
rowModules.forEach((module) => {
|
rowModules.forEach((module) => {
|
||||||
const { top, left } = getPosotion(module, type, height, false)
|
const { top, left } = getPosotion(module, type, activeModule.height, false)
|
||||||
const moduleOptions = { ...module, left, top, id: uuidv4() }
|
let copyModule = null
|
||||||
const copyModule = new QPolygon(module.points, moduleOptions)
|
module.clone((obj) => {
|
||||||
canvas.add(copyModule)
|
obj.set({
|
||||||
copyModules.push(copyModule)
|
parentId: module.parentId,
|
||||||
|
initOptions: module.initOptions,
|
||||||
|
direction: module.direction,
|
||||||
|
arrow: module.arrow,
|
||||||
|
name: module.name,
|
||||||
|
type: module.type,
|
||||||
|
length: module.length,
|
||||||
|
points: module.points,
|
||||||
|
surfaceId: module.surfaceId,
|
||||||
|
fill: module.fill,
|
||||||
|
left,
|
||||||
|
top,
|
||||||
|
id: uuidv4(),
|
||||||
|
})
|
||||||
|
copyModule = obj
|
||||||
|
canvas.add(obj)
|
||||||
|
copyModules.push(obj)
|
||||||
|
obj.setCoords()
|
||||||
|
})
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
|
|
||||||
if (otherModules.length > 0) {
|
if (
|
||||||
isOverlapOtherModules.push(
|
isOverlapOtherModules(copyModule, otherModules) ||
|
||||||
otherModules.some(
|
isOverlapObjects(copyModule, objects) ||
|
||||||
(otherModule) =>
|
isOutsideSurface(copyModule, moduleSetupSurface)
|
||||||
turf.booleanOverlap(polygonToTurfPolygon(copyModule, true), polygonToTurfPolygon(otherModule, true)) ||
|
) {
|
||||||
turf.booleanWithin(polygonToTurfPolygon(copyModule, true), polygonToTurfPolygon(otherModule, true)),
|
isWarning = true
|
||||||
),
|
copyModule.set({ fill: 'red' })
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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()
|
module.setCoords()
|
||||||
})
|
})
|
||||||
|
canvas.renderAll()
|
||||||
|
|
||||||
if (
|
if (isWarning) {
|
||||||
isOverlapOtherModules.some((isOverlap) => isOverlap) ||
|
|
||||||
isOverlapObjects.some((isOverlap) => isOverlap) ||
|
|
||||||
isOutsideSurface.some((isOutside) => isOutside)
|
|
||||||
) {
|
|
||||||
swalFire({
|
swalFire({
|
||||||
title: isOverlapOtherModules.some((isOverlap) => isOverlap)
|
title: getMessage('can.not.insert.module'),
|
||||||
? '겹치는 모듈이 있습니다.'
|
|
||||||
: isOverlapObjects.some((isOverlap) => isOverlap)
|
|
||||||
? '모듈이 오브젝트와 겹칩니다.'
|
|
||||||
: '영역 밖',
|
|
||||||
icon: 'error',
|
icon: 'error',
|
||||||
type: 'confirm',
|
type: 'alert',
|
||||||
confirmFn: () => {
|
confirmFn: () => {
|
||||||
targetModules.forEach((module) => {
|
targetModules.forEach((module) => {
|
||||||
module.set({ top: module.originPos.top, left: module.originPos.left })
|
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
})
|
})
|
||||||
canvas.renderAll()
|
canvas.remove(...copyModules)
|
||||||
copyModules.forEach((module) => {
|
|
||||||
canvas.remove(module)
|
|
||||||
})
|
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const alignModule = (type) => {}
|
||||||
|
|
||||||
|
const isOverlapOtherModules = (module, otherModules) => {
|
||||||
|
return otherModules.some(
|
||||||
|
(otherModule) =>
|
||||||
|
turf.booleanOverlap(polygonToTurfPolygon(module, true), polygonToTurfPolygon(otherModule, true)) ||
|
||||||
|
turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(otherModule, true)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const isOverlapObjects = (module, objects) => {
|
||||||
|
return !checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects)
|
||||||
|
}
|
||||||
|
|
||||||
|
const isOutsideSurface = (module, moduleSetupSurface) => {
|
||||||
|
return (
|
||||||
|
!turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(module, true)) ||
|
||||||
|
!turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(moduleSetupSurface, true))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
const getRowModules = (target) => {
|
const getRowModules = (target) => {
|
||||||
return canvas
|
return canvas
|
||||||
.getObjects()
|
.getObjects()
|
||||||
@ -797,29 +797,6 @@ export function useModule() {
|
|||||||
.filter((obj) => [BATCH_TYPE.OPENING, BATCH_TYPE.TRIANGLE_DORMER, BATCH_TYPE.PENTAGON_DORMER, BATCH_TYPE.SHADOW].includes(obj.name))
|
.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 {
|
return {
|
||||||
moduleMove,
|
moduleMove,
|
||||||
moduleMultiMove,
|
moduleMultiMove,
|
||||||
|
|||||||
@ -36,11 +36,20 @@ export function useAdsorptionPoint() {
|
|||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const removeAdsorptionPoint = () => {
|
||||||
|
const adsorptionPoints = getAdsorptionPoints()
|
||||||
|
adsorptionPoints.forEach((adsorptionPoint) => {
|
||||||
|
canvas.remove(adsorptionPoint)
|
||||||
|
})
|
||||||
|
canvas.renderAll()
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
adsorptionPointAddMode,
|
adsorptionPointAddMode,
|
||||||
adsorptionPointMode,
|
adsorptionPointMode,
|
||||||
adsorptionRange,
|
adsorptionRange,
|
||||||
getAdsorptionPoints,
|
getAdsorptionPoints,
|
||||||
adsorptionPointAddModeStateEvent,
|
adsorptionPointAddModeStateEvent,
|
||||||
|
removeAdsorptionPoint,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,6 +36,9 @@ 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 { useCanvasSetting } from './option/useCanvasSetting'
|
||||||
|
import { useGrid } from './common/useGrid'
|
||||||
|
import { useAdsorptionPoint } from './useAdsorptionPoint'
|
||||||
import { useRoofFn } from '@/hooks/common/useRoofFn'
|
import { useRoofFn } from '@/hooks/common/useRoofFn'
|
||||||
|
|
||||||
export function useContextMenu() {
|
export function useContextMenu() {
|
||||||
@ -58,7 +61,10 @@ export function useContextMenu() {
|
|||||||
const { moveSurfaceShapeBatch } = useSurfaceShapeBatch()
|
const { moveSurfaceShapeBatch } = useSurfaceShapeBatch()
|
||||||
const [globalFont, setGlobalFont] = useRecoilState(globalFontAtom)
|
const [globalFont, setGlobalFont] = useRecoilState(globalFontAtom)
|
||||||
const { addLine, removeLine } = useLine()
|
const { addLine, removeLine } = useLine()
|
||||||
|
const { removeGrid } = useGrid()
|
||||||
|
const { removeAdsorptionPoint } = useAdsorptionPoint()
|
||||||
const commonTextFont = useRecoilValue(fontSelector('commonText'))
|
const commonTextFont = useRecoilValue(fontSelector('commonText'))
|
||||||
|
const { settingsData, setSettingsDataSave } = useCanvasSetting()
|
||||||
const { swalFire } = useSwal()
|
const { swalFire } = useSwal()
|
||||||
const { removeRoofMaterial, removeAllRoofMaterial } = useRoofFn()
|
const { removeRoofMaterial, removeAllRoofMaterial } = useRoofFn()
|
||||||
|
|
||||||
@ -80,7 +86,15 @@ export function useContextMenu() {
|
|||||||
{
|
{
|
||||||
id: 'gridColorEdit',
|
id: 'gridColorEdit',
|
||||||
name: getMessage('modal.grid.color.edit'),
|
name: getMessage('modal.grid.color.edit'),
|
||||||
component: <ColorPickerModal id={popupId} color={gridColor} setColor={setGridColor} />,
|
component: (
|
||||||
|
<ColorPickerModal
|
||||||
|
id={popupId}
|
||||||
|
color={gridColor}
|
||||||
|
setColor={setGridColor}
|
||||||
|
settingsData={settingsData}
|
||||||
|
setSettingsDataSave={setSettingsDataSave}
|
||||||
|
/>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'remove',
|
id: 'remove',
|
||||||
@ -89,6 +103,10 @@ export function useContextMenu() {
|
|||||||
{
|
{
|
||||||
id: 'removeAll',
|
id: 'removeAll',
|
||||||
name: getMessage('delete.all'),
|
name: getMessage('delete.all'),
|
||||||
|
fn: () => {
|
||||||
|
removeGrid()
|
||||||
|
removeAdsorptionPoint()
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
])
|
])
|
||||||
@ -522,7 +540,15 @@ export function useContextMenu() {
|
|||||||
{
|
{
|
||||||
id: 'gridColorEdit',
|
id: 'gridColorEdit',
|
||||||
name: getMessage('contextmenu.grid.color.edit'),
|
name: getMessage('contextmenu.grid.color.edit'),
|
||||||
component: <ColorPickerModal id={popupId} color={gridColor} setColor={setGridColor} />,
|
component: (
|
||||||
|
<ColorPickerModal
|
||||||
|
id={popupId}
|
||||||
|
color={gridColor}
|
||||||
|
setColor={setGridColor}
|
||||||
|
settingsData={settingsData}
|
||||||
|
setSettingsDataSave={setSettingsDataSave}
|
||||||
|
/>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'remove',
|
id: 'remove',
|
||||||
@ -536,12 +562,8 @@ export function useContextMenu() {
|
|||||||
id: 'removeAll',
|
id: 'removeAll',
|
||||||
name: getMessage('contextmenu.remove.all'),
|
name: getMessage('contextmenu.remove.all'),
|
||||||
fn: () => {
|
fn: () => {
|
||||||
canvas
|
removeGrid()
|
||||||
.getObjects()
|
removeAdsorptionPoint()
|
||||||
.filter((obj) => ['tempGrid', 'lineGrid', 'dotGrid'].includes(obj.name))
|
|
||||||
.forEach((grid) => {
|
|
||||||
canvas.remove(grid)
|
|
||||||
})
|
|
||||||
canvas.discardActiveObject()
|
canvas.discardActiveObject()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -933,5 +933,9 @@
|
|||||||
"simulator.table.sub9": "予測発電量 (kWh)",
|
"simulator.table.sub9": "予測発電量 (kWh)",
|
||||||
"simulator.notice.sub1": "Hanwha Japan 年間発電量",
|
"simulator.notice.sub1": "Hanwha Japan 年間発電量",
|
||||||
"simulator.notice.sub2": "シミュレーション案内事項",
|
"simulator.notice.sub2": "シミュレーション案内事項",
|
||||||
"master.moduletypeitem.message.error": "지붕재 코드를 입력하세요."
|
"master.moduletypeitem.message.error": "지붕재 코드를 입력하세요.",
|
||||||
|
"can.not.move.module": "모듈을 이동할 수 없습니다.(JA)",
|
||||||
|
"can.not.copy.module": "모듈을 복사할 수 없습니다.(JA)",
|
||||||
|
"can.not.remove.module": "모듈을 삭제할 수 없습니다.(JA)",
|
||||||
|
"can.not.insert.module": "모듈을 삽입할 수 없습니다.(JA)"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -943,5 +943,9 @@
|
|||||||
"simulator.table.sub9": "예측발전량 (kWh)",
|
"simulator.table.sub9": "예측발전량 (kWh)",
|
||||||
"simulator.notice.sub1": "Hanwha Japan 연간 발전량",
|
"simulator.notice.sub1": "Hanwha Japan 연간 발전량",
|
||||||
"simulator.notice.sub2": "시뮬레이션 안내사항",
|
"simulator.notice.sub2": "시뮬레이션 안내사항",
|
||||||
"master.moduletypeitem.message.error": "지붕재 코드를 입력하세요."
|
"master.moduletypeitem.message.error": "지붕재 코드를 입력하세요.",
|
||||||
|
"can.not.move.module": "모듈을 이동할 수 없습니다.",
|
||||||
|
"can.not.copy.module": "모듈을 복사할 수 없습니다.",
|
||||||
|
"can.not.remove.module": "모듈을 삭제할 수 없습니다.",
|
||||||
|
"can.not.insert.module": "모듈을 삽입할 수 없습니다."
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user