diff --git a/src/components/floor-plan/modal/roofAllocation/ActualSizeSetting.jsx b/src/components/floor-plan/modal/roofAllocation/ActualSizeSetting.jsx new file mode 100644 index 00000000..edca1208 --- /dev/null +++ b/src/components/floor-plan/modal/roofAllocation/ActualSizeSetting.jsx @@ -0,0 +1,122 @@ +import WithDraggable from '@/components/common/draggable/WithDraggable' +import { useMessage } from '@/hooks/useMessage' +import { usePopup } from '@/hooks/usePopup' +import { useRecoilValue } from 'recoil' +import { contextPopupPositionState } from '@/store/popupAtom' +import { useEffect, useState } from 'react' +import { currentObjectState } from '@/store/canvasAtom' +import { useRoofAllocationSetting } from '@/hooks/roofcover/useRoofAllocationSetting' +import { useSwal } from '@/hooks/useSwal' + +export default function ActualSizeSetting(props) { + const contextPopupPosition = useRecoilValue(contextPopupPositionState) + const { id, pos = contextPopupPosition } = props + const currentObject = useRecoilValue(currentObjectState) + const [planeSize, setPlaneSize] = useState(0) + const [actualSize, setActualSize] = useState(0) + const { setLineSize, handleAlloc } = useRoofAllocationSetting() + const { closePopup } = usePopup() + const { getMessage } = useMessage() + const { swalFire } = useSwal() + useEffect(() => { + if (currentObject && currentObject.attributes) { + setPlaneSize(currentObject.attributes.planeSize ?? 0) + setActualSize(currentObject.attributes.actualSize ?? 0) + } + }, [currentObject]) + + const handleFinish = () => { + swalFire({ + text: '완료 하시겠습니까?', + type: 'confirm', + confirmFn: () => { + handleAlloc() + }, + }) + } + + const handleClose = () => { + swalFire({ + text: '완료 하시겠습니까?', + type: 'confirm', + confirmFn: () => { + handleAlloc() + }, + // denyFn: () => { + // swalFire({ text: '취소되었습니다.', icon: 'error' }) + // }, + }) + } + + const handleApply = () => { + if (!currentObject) { + swalFire({ type: 'alert', icon: 'error', text: getMessage('modal.actual.size.setting.not.exist.auxiliary.line') }) + return + } + if (actualSize !== 0) { + setLineSize(currentObject?.id, actualSize) + } else { + swalFire({ type: 'alert', icon: 'error', text: getMessage('modal.actual.size.setting.not.exist.size') }) + } + } + + return ( + +
+
+

{getMessage('modal.actual.size.setting')}

+ +
+
+
+ {getMessage('modal.actual.size.setting.info')} +
+
+
{getMessage('setting')}
+
+
+
+
{getMessage('modal.actual.size.setting.plane.size.length')}
+
+
+
+ +
+ mm +
+
+
+
+
{getMessage('modal.actual.size.setting.actual.size.length')}
+
+
+
+ setActualSize(Number(e.target.value))} + /> +
+ mm +
+
+
+
+
+
+
+ + +
+
+
+
+ ) +} diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js index 921e737a..b99af935 100644 --- a/src/hooks/roofcover/useRoofAllocationSetting.js +++ b/src/hooks/roofcover/useRoofAllocationSetting.js @@ -1,5 +1,5 @@ import { useRecoilValue } from 'recoil' -import { canvasState } from '@/store/canvasAtom' +import { canvasState, currentObjectState } from '@/store/canvasAtom' import { useEffect, useState } from 'react' import { setSurfaceShapePattern } from '@/util/canvas-util' import { useSwal } from '@/hooks/useSwal' @@ -7,16 +7,20 @@ import { usePolygon } from '@/hooks/usePolygon' import { roofDisplaySelector } from '@/store/settingAtom' import { usePopup } from '@/hooks/usePopup' import { POLYGON_TYPE } from '@/common/common' +import { v4 as uuidv4 } from 'uuid' +import ActualSizeSetting from '@/components/floor-plan/modal/roofAllocation/ActualSizeSetting' +import { useMessage } from '@/hooks/useMessage' // 지붕면 할당 export function useRoofAllocationSetting(id) { const canvas = useRecoilValue(canvasState) const roofDisplay = useRecoilValue(roofDisplaySelector) const { drawDirectionArrow, addLengthText, splitPolygonWithLines } = usePolygon() - const { closePopup } = usePopup() - + const [popupId, setPopupId] = useState(uuidv4()) + const { addPopup, closePopup, closeAll } = usePopup() + const { getMessage } = useMessage() + const currentObject = useRecoilValue(currentObjectState) const { swalFire } = useSwal() - const roofMaterials = [ { id: 'A', @@ -77,23 +81,55 @@ export function useRoofAllocationSetting(id) { ]) const [radioValue, setRadioValue] = useState('A') + const [editingLines, setEditingLines] = useState([]) const [selectedRoofMaterial, setSelectedRoofMaterial] = useState(roofMaterials[0]) + useEffect(() => { + const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) // roofPolygon.innerLines + + roofBases.forEach((roof) => { + roof.innerLines.forEach((line) => { + if (!line.attributes.actualSize || line.attributes?.actualSize === 0) { + line.set({ + strokeWidth: 4, + stroke: 'black', + selectable: true, + }) + } + + if (editingLines.includes(line)) { + line.set({ + strokeWidth: 2, + stroke: 'black', + selectable: true, + }) + } + }) + }) + if (currentObject) { + console.log(currentObject.name) + if (currentObject.name.toLowerCase().includes('line')) { + currentObject.set({ + strokeWidth: 4, + stroke: '#EA10AC', + }) + } + } + }, [currentObject]) + useEffect(() => { const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) if (roofBases.length === 0) { swalFire({ text: '할당할 지붕이 없습니다.' }) closePopup(id) } - // if (type === POLYGON_TYPE.ROOF) { - // // 지붕면 할당 - // - // } else if ('roof') { - // // 지붕재 변경 - // } }, []) + useEffect(() => { + console.log('editingLines', editingLines) + }, [editingLines]) + const onAddRoofMaterial = () => { setValues([...values, selectedRoofMaterial]) } @@ -104,6 +140,48 @@ export function useRoofAllocationSetting(id) { // 선택한 지붕재로 할당 const handleSave = () => { + // 모두 actualSize 있으면 바로 적용 없으면 actualSize 설정 + if (checkInnerLines()) { + addPopup(popupId, 1, ) + } else { + apply() + } + } + + const handleAlloc = () => { + if (!checkInnerLines()) { + apply() + } else { + swalFire({ + type: 'alert', + icon: 'error', + text: getMessage('실제치수를 입력해 주세요.'), + }) + } + } + + const checkInnerLines = () => { + const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) // roofPolygon.innerLines + let result = false + console.log(roofBases) + roofBases.forEach((roof) => { + roof.innerLines.forEach((line) => { + if (!line.attributes.actualSize || line.attributes?.actualSize === 0) { + line.set({ + strokeWidth: 4, + stroke: 'black', + selectable: true, + }) + result = true + } + }) + }) + if (result) canvas?.renderAll() + + return result + } + + const apply = () => { const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL) roofBases.forEach((roofBase) => { @@ -135,8 +213,26 @@ export function useRoofAllocationSetting(id) { removeTargets.forEach((obj) => { canvas.remove(obj) }) + setEditingLines([]) + closeAll() + } - closePopup(id) + const setLineSize = (id, size) => { + const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) + roofBases.forEach((roof) => { + roof.innerLines.forEach((line) => { + if (id === line.id) { + setEditingLines([...editingLines.filter((editLine) => editLine.id !== line.id), line]) + line.attributes.actualSize = size + line.set({ + strokeWidth: 2, + stroke: 'black', + }) + } + }) + }) + + canvas?.renderAll() } const handleRadioOnChange = (e) => { @@ -148,6 +244,8 @@ export function useRoofAllocationSetting(id) { onAddRoofMaterial, onDeleteRoofMaterial, handleRadioOnChange, + handleAlloc, + setLineSize, widths, lengths, rafters, diff --git a/src/locales/ja.json b/src/locales/ja.json index 2d0c2871..15f2473b 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -285,6 +285,12 @@ "modal.flow.direction.setting": "流れ方向の設定", "modal.flow.direction.setting.info": "流れ方向を選択してください。", "modal.image.size.setting": "画像のサイズ変更", + "modal.actual.size.setting": "実測値設定", + "modal.actual.size.setting.info": "※隅棟・谷・棟の実際の寸法を入力してください。", + "modal.actual.size.setting.not.exist.auxiliary.line": "실측치 입력할 보조선을 선택해 주세요(JA)", + "modal.actual.size.setting.not.exist.size": "실제치수 길이를 입력해 주세요.(JA)", + "modal.actual.size.setting.plane.size.length": "廊下の寸法の長さ", + "modal.actual.size.setting.actual.size.length": "実寸長", "plan.message.confirm.save": "PLAN을 저장하시겠습니까?", "plan.message.confirm.copy": "PLAN을 복사하시겠습니까?", "plan.message.confirm.delete": "PLAN을 삭제하시겠습니까?", diff --git a/src/locales/ko.json b/src/locales/ko.json index 55e1becb..d52334bf 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -290,6 +290,12 @@ "modal.flow.direction.setting": "흐름 방향 설정", "modal.flow.direction.setting.info": "흐름방향을 선택하세요.", "modal.image.size.setting": "이미지 크기 조절", + "modal.actual.size.setting": "실측치 설정", + "modal.actual.size.setting.info": "※隅棟・谷・棟의 실제 치수를 입력해주세요.", + "modal.actual.size.setting.not.exist.auxiliary.line": "실측치 입력할 보조선을 선택해 주세요", + "modal.actual.size.setting.not.exist.size": "실제치수 길이를 입력해 주세요", + "modal.actual.size.setting.plane.size.length": "복도치수 길이", + "modal.actual.size.setting.actual.size.length": "실제치수 길이", "plan.message.confirm.save": "PLAN을 저장하시겠습니까?", "plan.message.confirm.copy": "PLAN을 복사하시겠습니까?", "plan.message.confirm.delete": "PLAN을 삭제하시겠습니까?",