Compare commits

..

7 Commits

8 changed files with 72 additions and 83 deletions

View File

@ -224,6 +224,7 @@ export const SAVE_KEY = [
'viewportTransform', 'viewportTransform',
'outerLineFix', 'outerLineFix',
'adjustRoofLines', 'adjustRoofLines',
'northModuleYn',
] ]
export const OBJECT_PROTOTYPE = [fabric.Line.prototype, fabric.Polygon.prototype, fabric.Triangle.prototype, fabric.Group.prototype] export const OBJECT_PROTOTYPE = [fabric.Line.prototype, fabric.Polygon.prototype, fabric.Triangle.prototype, fabric.Group.prototype]

View File

@ -23,8 +23,23 @@ export const CalculatorInput = forwardRef(
}, [ref]) }, [ref])
// Sync displayValue with value prop // Sync displayValue with value prop
// useEffect(() => {
// setDisplayValue(value || '0')
// }, [value])
useEffect(() => { useEffect(() => {
setDisplayValue(value || '0') const newValue = value || '0'
setDisplayValue(newValue)
// value
const calculator = calculatorRef.current
if (calculator) {
//
calculator.currentOperand = newValue.toString()
calculator.previousOperand = ''
calculator.operation = undefined
setHasOperation(false)
}
}, [value]) }, [value])
// //

View File

@ -123,10 +123,14 @@ export default function PassivityCircuitAllocation(props) {
} }
// targetModule Y N . // targetModule Y N .
const targetModuleGroup = [...new Set(canvas const targetModuleGroup = [
.getObjects() ...new Set(
.filter((obj) => obj.name === POLYGON_TYPE.MODULE && targetModules.includes(obj.id)) canvas
.map((obj) => obj.moduleInfo.northModuleYn))] .getObjects()
.filter((obj) => obj.name === POLYGON_TYPE.MODULE && targetModules.includes(obj.id))
.map((obj) => obj.moduleInfo.northModuleYn),
),
]
if (targetModuleGroup.length > 1) { if (targetModuleGroup.length > 1) {
swalFire({ swalFire({
@ -142,16 +146,12 @@ export default function PassivityCircuitAllocation(props) {
const originHaveThisPcsModules = canvas const originHaveThisPcsModules = canvas
.getObjects() .getObjects()
.filter((obj) => obj.name === POLYGON_TYPE.MODULE && obj.pcs && obj.pcs.id === selectedPcs.id) .filter((obj) => obj.name === POLYGON_TYPE.MODULE && obj.pcs && obj.pcs.id === selectedPcs.id)
// pcs surface . // 1. ,
const originSurfaceList = canvas const targetModuleInfos = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE && targetModules.includes(obj.id))
.getObjects() debugger
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && originHaveThisPcsModules.map((obj) => obj.surfaceId).includes(obj.id)) const newTargetModuleGroup = [...new Set(targetModuleInfos.concat(originHaveThisPcsModules).map((obj) => obj.moduleInfo.northModuleYn))]
originSurfaceList.concat(originSurfaceList).forEach((surface) => { if (newTargetModuleGroup.length > 1) {
surfaceType[`${surface.direction}-${surface.roofMaterial.pitch}`] = surface
})
if (Object.keys(surfaceType).length > 1) {
swalFire({ swalFire({
text: getMessage('module.circuit.fix.not.same.roof.error'), text: getMessage('module.circuit.fix.not.same.roof.error'),
type: 'alert', type: 'alert',
@ -244,6 +244,7 @@ export default function PassivityCircuitAllocation(props) {
roofSurface: surface.direction, roofSurface: surface.direction,
roofSurfaceIncl: +canvas.getObjects().filter((obj) => obj.id === surface.parentId)[0].pitch, roofSurfaceIncl: +canvas.getObjects().filter((obj) => obj.id === surface.parentId)[0].pitch,
roofSurfaceNorthYn: surface.direction === 'north' ? 'Y' : 'N', roofSurfaceNorthYn: surface.direction === 'north' ? 'Y' : 'N',
roofSurfaceNorthModuleYn: surface.northModuleYn,
moduleList: surface.modules.map((module) => { moduleList: surface.modules.map((module) => {
return { return {
itemId: module.moduleInfo.itemId, itemId: module.moduleInfo.itemId,

View File

@ -2,6 +2,7 @@ import Image from 'next/image'
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils' import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
import { CalculatorInput } from '@/components/common/input/CalcInput' import { CalculatorInput } from '@/components/common/input/CalcInput'
import { useEffect } from 'react'
export default function Angle({ props }) { export default function Angle({ props }) {
const { getMessage } = useMessage() const { getMessage } = useMessage()
@ -31,11 +32,21 @@ export default function Angle({ props }) {
className="input-origin block" className="input-origin block"
value={angle1} value={angle1}
ref={angle1Ref} ref={angle1Ref}
onChange={(value) => setAngle1(value)} onChange={(value) => {
// Calculate the final value first
let finalValue = value;
const numValue = parseInt(value, 10);
if (!isNaN(numValue)) {
const clampedValue = Math.min(180, Math.max(-180, numValue));
finalValue = String(clampedValue);
}
// Set state once with the final value
setAngle1(finalValue);
}}
placeholder="45" placeholder="45"
onFocus={() => (angle1Ref.current.value = '')} onFocus={() => (angle1Ref.current.value = '')}
options={{ options={{
allowNegative: false, allowNegative: true,
allowDecimal: true allowDecimal: true
}} }}
/> />

View File

@ -11,44 +11,9 @@ export default function OuterLineWall({ props }) {
const { length1, setLength1, length1Ref, arrow1, setArrow1 } = props const { length1, setLength1, length1Ref, arrow1, setArrow1 } = props
const resetCalculatorValue = () => {
// 1. 0
setLength1(0);
if (length1Ref.current) {
// 2. input UI
length1Ref.current.focus();
length1Ref.current.value = '';
// 3. UI
setTimeout(() => {
const acButton = document.querySelector('.keypad-btn.ac, .btn-ac') ||
Array.from(document.querySelectorAll('button')).find(el => el.textContent === 'AC');
if (acButton) {
acButton.click();
} else {
// input Enter/Escape
length1Ref.current.dispatchEvent(new Event('input', { bubbles: true }));
}
// ()
length1Ref.current.focus();
}, 10);
}
}
// //
useEffect(() => { useEffect(() => {
const handleKeyDown = (e) => { const handleKeyDown = (e) => {
if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(e.key)) {
//
setTimeout(() => {
resetCalculatorValue();
}, 0);
return;
}
// //
const keypadVisible = document.querySelector('.keypad-container') const keypadVisible = document.querySelector('.keypad-container')
@ -123,58 +88,37 @@ export default function OuterLineWall({ props }) {
}} }}
/> />
</div> </div>
<button <button className="reset-btn" onClick={() => setLength1(0)}></button>
className="reset-btn"
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
resetCalculatorValue()
}}
></button>
</div> </div>
<div className="outline-form"> <div className="outline-form">
<span>{getMessage('modal.cover.outline.arrow')}</span> <span>{getMessage('modal.cover.outline.arrow')}</span>
<div className="grid-direction"> <div className="grid-direction">
<button <button
className={`direction up ${arrow1 === '↑' ? 'act' : ''}`} className={`direction up ${arrow1 === '↑' ? 'act' : ''}`}
onClick={(e) => { onClick={() => {
setArrow1('↑') setArrow1('↑')
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp' })) document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp' }))
e.preventDefault();
e.stopPropagation();
resetCalculatorValue()
}} }}
></button> ></button>
<button <button
className={`direction down ${arrow1 === '↓' ? 'act' : ''}`} className={`direction down ${arrow1 === '↓' ? 'act' : ''}`}
onClick={(e) => { onClick={() => {
setArrow1('↓') setArrow1('↓')
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' })) document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }))
e.preventDefault();
e.stopPropagation();
resetCalculatorValue()
}} }}
></button> ></button>
<button <button
className={`direction left ${arrow1 === '←' ? 'act' : ''}`} className={`direction left ${arrow1 === '←' ? 'act' : ''}`}
onClick={(e) => { onClick={() => {
setArrow1('←') setArrow1('←')
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowLeft' })) document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowLeft' }))
e.preventDefault();
e.stopPropagation();
resetCalculatorValue()
}} }}
></button> ></button>
<button <button
className={`direction right ${arrow1 === '→' ? 'act' : ''}`} className={`direction right ${arrow1 === '→' ? 'act' : ''}`}
onClick={(e) => { onClick={() => {
setArrow1('→') setArrow1('→')
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight' })) document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight' }))
e.preventDefault();
e.stopPropagation();
resetCalculatorValue()
}} }}
></button> ></button>
</div> </div>

View File

@ -830,7 +830,7 @@ export const useTrestle = () => {
return -surfaceCompass return -surfaceCompass
} }
let resultAzimuth = moduleCompass let resultAzimuth = parseInt(moduleCompass, 10)
switch (direction) { switch (direction) {
case 'south': { case 'south': {

View File

@ -99,6 +99,12 @@ export function useCircuitTrestle(executeEffect = false) {
// 지붕면 목록 // 지붕면 목록
const getRoofSurfaceList = () => { const getRoofSurfaceList = () => {
const roofSurfaceList = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) const roofSurfaceList = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
roofSurfaceList.forEach((roofSurface) => {
const modules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE && obj.surfaceId === roofSurface.id)
roofSurface.northModuleYn = modules.every((module) => module.moduleInfo.northModuleYn === 'Y') ? 'Y' : 'N'
})
roofSurfaceList.sort((a, b) => a.left - b.left || b.top - a.top) roofSurfaceList.sort((a, b) => a.left - b.left || b.top - a.top)
const result = roofSurfaceList const result = roofSurfaceList
@ -119,6 +125,7 @@ export function useCircuitTrestle(executeEffect = false) {
} }
}), }),
roofSurfaceNorthYn: obj.direction === 'north' ? 'Y' : 'N', roofSurfaceNorthYn: obj.direction === 'north' ? 'Y' : 'N',
roofSurfaceNorthModuleYn: obj.northModuleYn,
} }
}) })
.filter((surface) => surface.moduleList.length > 0) .filter((surface) => surface.moduleList.length > 0)
@ -139,11 +146,14 @@ export function useCircuitTrestle(executeEffect = false) {
let remaining = [...arr] let remaining = [...arr]
while (remaining.length > 0) { while (remaining.length > 0) {
const { roofSurface, roofSurfaceIncl } = remaining[0] const { roofSurface, roofSurfaceIncl, roofSurfaceNorthModuleYn } = remaining[0]
const key = `${roofSurface}|${roofSurfaceIncl}` const key = `${roofSurface}|${roofSurfaceIncl}|${roofSurfaceNorthModuleYn}`
// 해당 그룹 추출 // 해당 그룹 추출
const group = remaining.filter((item) => item.roofSurface === roofSurface && item.roofSurfaceIncl === roofSurfaceIncl) const group = remaining.filter(
(item) =>
item.roofSurface === roofSurface && item.roofSurfaceIncl === roofSurfaceIncl && item.roofSurfaceNorthModuleYn === roofSurfaceNorthModuleYn,
)
// 이미 처리했는지 체크 후 저장 // 이미 처리했는지 체크 후 저장
if (!seen.has(key)) { if (!seen.has(key)) {
@ -152,7 +162,14 @@ export function useCircuitTrestle(executeEffect = false) {
} }
// remaining에서 제거 // remaining에서 제거
remaining = remaining.filter((item) => !(item.roofSurface === roofSurface && item.roofSurfaceIncl === roofSurfaceIncl)) remaining = remaining.filter(
(item) =>
!(
item.roofSurface === roofSurface &&
item.roofSurfaceIncl === roofSurfaceIncl &&
item.roofSurfaceNorthModuleYn === roofSurfaceNorthModuleYn
),
)
} }
return result return result

View File

@ -80,7 +80,7 @@ export const getCenterPoint = (point1, point2) => {
* @returns * @returns
*/ */
export const getDistance = (x1, y1, x2, y2) => { export const getDistance = (x1, y1, x2, y2) => {
return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)).toFixed(0) return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)).toFixed(1)
} }
// polygon의 각 변에 해당 점과 점 사이의 거리를 나타내는 IText를 추가하는 함수 // polygon의 각 변에 해당 점과 점 사이의 거리를 나타내는 IText를 추가하는 함수