Compare commits

..

No commits in common. "e646f2993b456e1d45f0bfed8fe68addc1b30b65" and "592e2238b2c42a6db1a5e7b856613aa7c5e50395" have entirely different histories.

51 changed files with 365 additions and 1616 deletions

1
.gitignore vendored
View File

@ -43,4 +43,3 @@ yarn.lock
package-lock.json
pnpm-lock.yaml
certificates
.ai

View File

@ -219,8 +219,7 @@ export const SAVE_KEY = [
'originWidth',
'originHeight',
'skeletonLines',
'skeleton',
'viewportTransform',
'skeleton'
]
export const OBJECT_PROTOTYPE = [fabric.Line.prototype, fabric.Polygon.prototype, fabric.Triangle.prototype, fabric.Group.prototype]

View File

@ -24,7 +24,7 @@ export default function WithDraggable({ isShow, children, pos = { x: 0, y: 0 },
<Draggable
position={{ x: position.x, y: position.y }}
onDrag={(e, data) => handleOnDrag(e, data)}
handle="" //{handle === '' ? '.modal-handle' : handle} //전체 handle
handle= ''//{handle === '' ? '.modal-handle' : handle} //전체 handle
cancel="input, button, select, textarea, [contenteditable], .sort-select"
>
<div className={`modal-pop-wrap ${className}`} style={{ visibility: isHidden ? 'hidden' : 'visible' }}>
@ -38,18 +38,15 @@ export default function WithDraggable({ isShow, children, pos = { x: 0, y: 0 },
)
}
function WithDraggableHeader({ title, onClose, children, isFold, onFold = null }) {
function WithDraggableHeader({ title, onClose, children }) {
return (
<div className="modal-head modal-handle">
<h1 className="title">{title}</h1>
<div className="modal-btn-wrap">
{onFold && <button className={`modal-fold ${isFold ? '' : 'act'}`} onClick={onFold}></button>}
{onClose && (
<button className="modal-close" onClick={() => onClose()}>
닫기
</button>
)}
</div>
{onClose && (
<button className="modal-close" onClick={() => onClose()}>
닫기
</button>
)}
</div>
)
}

View File

@ -48,23 +48,14 @@ export const CalculatorInput = forwardRef(
const calculator = calculatorRef.current
let newDisplayValue = ''
// 2
const shouldPreventInput = (value) => {
const decimalParts = (value || '').split('.')
return decimalParts.length > 1 && decimalParts[1].length >= 2
}
if (hasOperation) {
//
if (calculator.currentOperand === '0' || calculator.shouldResetDisplay) {
calculator.currentOperand = num.toString()
calculator.shouldResetDisplay = false
}else if (!shouldPreventInput(calculator.currentOperand)) { // 2
} else {
calculator.currentOperand = (calculator.currentOperand || '') + num
}
// else {
// calculator.currentOperand = (calculator.currentOperand || '') + num
// }
newDisplayValue = calculator.previousOperand + calculator.operation + calculator.currentOperand
setDisplayValue(newDisplayValue)
} else {
@ -77,7 +68,7 @@ export const CalculatorInput = forwardRef(
if (!hasOperation) {
onChange(calculator.currentOperand)
}
} else if (!shouldPreventInput(calculator.currentOperand)) { // 2
} else {
calculator.currentOperand = (calculator.currentOperand || '') + num
newDisplayValue = calculator.currentOperand
setDisplayValue(newDisplayValue)
@ -85,14 +76,6 @@ export const CalculatorInput = forwardRef(
onChange(newDisplayValue)
}
}
// else {
// calculator.currentOperand = (calculator.currentOperand || '') + num
// newDisplayValue = calculator.currentOperand
// setDisplayValue(newDisplayValue)
// if (!hasOperation) {
// onChange(newDisplayValue)
// }
// }
}
//

View File

@ -89,7 +89,7 @@ let fileCheck = false;
siteTpCd: "QC",
schNoticeClsCd: "QNA",
regId: sessionState?.userId || '',
storeId: sessionState?.storeId || '',
storeId: sessionState?.userId || '',
qstMail: sessionState?.email || '',
qnaClsLrgCd: '',
qnaClsMidCd: '',

View File

@ -2,7 +2,7 @@
import { useContext, useEffect, useRef } from 'react'
import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil'
import { useRecoilValue, useResetRecoilState } from 'recoil'
import QContextMenu from '@/components/common/context-menu/QContextMenu'
import PanelBatchStatistics from '@/components/floor-plan/modal/panelBatch/PanelBatchStatistics'
@ -11,7 +11,7 @@ import { useCanvas } from '@/hooks/useCanvas'
import { usePlan } from '@/hooks/usePlan'
import { useContextMenu } from '@/hooks/useContextMenu'
import { useCanvasConfigInitialize } from '@/hooks/common/useCanvasConfigInitialize'
import { canvasZoomState, currentMenuState } from '@/store/canvasAtom'
import { currentMenuState } from '@/store/canvasAtom'
import { totalDisplaySelector } from '@/store/settingAtom'
import { POLYGON_TYPE } from '@/common/common'
import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
@ -50,7 +50,6 @@ export default function CanvasFrame() {
const resetSeriesState = useResetRecoilState(seriesState)
const resetModelsState = useResetRecoilState(modelsState)
const resetCompasDeg = useResetRecoilState(compasDegAtom)
const [zoom, setCanvasZoom] = useRecoilState(canvasZoomState)
const resetSelectedModelsState = useResetRecoilState(selectedModelsState)
const resetPcsCheckState = useResetRecoilState(pcsCheckState)
const { handleModuleSelectionTotal } = useCanvasPopupStatusController()
@ -68,13 +67,6 @@ export default function CanvasFrame() {
canvasLoadInit() //config
canvas?.renderAll() // .
if (canvas.viewportTransform) {
if (canvas.viewportTransform[0] !== 1) {
setCanvasZoom(Number((canvas.viewportTransform[0] * 100).toFixed(0)))
}
}
canvas.originViewPortTransform = canvas.viewportTransform
if (canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE).length > 0) {
setTimeout(() => {
setSelectedMenu('module')

View File

@ -2,7 +2,7 @@
import { useContext, useEffect, useState } from 'react'
import { usePathname, useRouter } from 'next/navigation'
import { usePathname, useRouter, useSearchParams } from 'next/navigation'
import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil'
@ -25,18 +25,17 @@ 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 {
canvasSettingState,
canvasState,
canvasZoomState,
currentCanvasPlanState,
currentMenuState,
verticalHorizontalModeState,
} from '@/store/canvasAtom'
import { canvasSettingState, canvasState, canvasZoomState, currentMenuState, verticalHorizontalModeState, currentCanvasPlanState } from '@/store/canvasAtom'
import { sessionStore } from '@/store/commonAtom'
import { outerLinePointsState } from '@/store/outerLineAtom'
import { appMessageStore, globalLocaleStore } from '@/store/localeAtom'
import { addedRoofsState, basicSettingState, selectedRoofMaterialSelector, settingModalFirstOptionsState } from '@/store/settingAtom'
import {
addedRoofsState,
basicSettingState,
corridorDimensionSelector,
selectedRoofMaterialSelector,
settingModalFirstOptionsState,
} from '@/store/settingAtom'
import { placementShapeDrawingPointsState } from '@/store/placementShapeDrawingAtom'
import { commonUtilsState } from '@/store/commonUtilsAtom'
import { menusState } from '@/store/menuAtom'
@ -52,7 +51,6 @@ import { QcastContext } from '@/app/QcastProvider'
import { useRoofFn } from '@/hooks/common/useRoofFn'
import { usePolygon } from '@/hooks/usePolygon'
import { useTrestle } from '@/hooks/module/useTrestle'
export default function CanvasMenu(props) {
const [currentCanvasPlan, setCurrentCanvasPlan] = useRecoilState(currentCanvasPlanState)
const { selectedMenu, setSelectedMenu } = props
@ -517,10 +515,7 @@ export default function CanvasMenu(props) {
if (createUser === 'T01' && sessionState.storeId !== 'T01') {
setAllButtonStyles('none')
} else {
setEstimateContextState({
tempFlg: estimateRecoilState.tempFlg,
lockFlg: estimateRecoilState.lockFlg,
})
setEstimateContextState({ tempFlg: estimateRecoilState.tempFlg, lockFlg: estimateRecoilState.lockFlg })
handleButtonStyles(estimateRecoilState.tempFlg, estimateRecoilState.lockFlg, estimateContextState.docNo)
}
}

View File

@ -4,7 +4,6 @@ import { globalPitchState, pitchSelector, pitchTextSelector } from '@/store/canv
import { useRecoilState } from 'recoil'
import { useRef } from 'react'
import { usePopup } from '@/hooks/usePopup'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function Slope({ id, pos = { x: 50, y: 230 } }) {
const { getMessage } = useMessage()
@ -23,19 +22,7 @@ export default function Slope({ id, pos = { x: 50, y: 230 } }) {
{getMessage('slope')}
</span>
<div className="input-grid mr5">
{/*<input type="text" className="input-origin block" defaultValue={globalPitch} ref={inputRef} />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
ref={inputRef}
value={globalPitch}
options={{
allowNegative: false,
allowDecimal: true //(index !== 0),
}}
></CalculatorInput>
<input type="text" className="input-origin block" defaultValue={globalPitch} ref={inputRef} />
</div>
<span className="thin">{pitchText}</span>
</div>

View File

@ -1,4 +1,4 @@
import { MODULE_SETUP_TYPE, POLYGON_TYPE } from '@/common/common'
import { POLYGON_TYPE, MODULE_SETUP_TYPE } from '@/common/common'
import WithDraggable from '@/components/common/draggable/WithDraggable'
import { Orientation } from '@/components/floor-plan/modal/basic/step/Orientation'
import PitchPlacement from '@/components/floor-plan/modal/basic/step/pitch/PitchPlacement'
@ -74,7 +74,6 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
const { trigger: trestleTrigger } = useCanvasPopupStatusController(2)
const { trigger: placementTrigger } = useCanvasPopupStatusController(3)
const [roofsStore, setRoofsStore] = useRecoilState(roofsState)
const [isFold, setIsFold] = useState(false)
// const { initEvent } = useContext(EventContext)
const { manualModuleSetup, autoModuleSetup, manualFlatroofModuleSetup, autoFlatroofModuleSetup, manualModuleLayoutSetup, restoreModuleInstArea } =
@ -283,42 +282,35 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
return (
<WithDraggable isShow={true} pos={pos} className={basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' ? 'll' : 'lx-2'}>
<WithDraggable.Header
title={getMessage('plan.menu.module.circuit.setting.default')}
isFold={isFold}
onClose={() => handleClosePopup(id)}
onFold={() => setIsFold(!isFold)}
/>
<WithDraggable.Header title={getMessage('plan.menu.module.circuit.setting.default')} onClose={() => handleClosePopup(id)} />
<WithDraggable.Body>
<div style={{ display: isFold ? 'none' : 'block' }}>
<div className="roof-module-tab">
<div className={`module-tab-bx act`}>{getMessage('modal.module.basic.setting.orientation.setting')}</div>
<span className={`tab-arr ${tabNum !== 1 ? 'act' : ''}`}></span>
{basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && (
<>
<div className={`module-tab-bx ${tabNum !== 1 ? 'act' : ''}`}>{getMessage('modal.module.basic.setting.module.setting')}</div>
<span className={`tab-arr ${tabNum === 3 ? 'act' : ''}`}></span>
<div className={`module-tab-bx ${tabNum === 3 ? 'act' : ''}`}>{getMessage('modal.module.basic.setting.module.placement')}</div>
</>
)}
{basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && (
<>
<div className={`module-tab-bx ${tabNum === 2 ? 'act' : ''}`}>{getMessage('modal.module.basic.setting.module.placement')}</div>
</>
)}
</div>
{tabNum === 1 && <Orientation ref={orientationRef} {...orientationProps} />}
{/*배치면 초기설정 - 입력방법: 복시도 입력 || 실측값 입력*/}
{basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && tabNum === 2 && <Trestle ref={trestleRef} {...trestleProps} />}
{basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && tabNum === 3 && (
<Placement setTabNum={setTabNum} layoutSetup={layoutSetup} setLayoutSetup={setLayoutSetup} />
<div className="roof-module-tab">
<div className={`module-tab-bx act`}>{getMessage('modal.module.basic.setting.orientation.setting')}</div>
<span className={`tab-arr ${tabNum !== 1 ? 'act' : ''}`}></span>
{basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && (
<>
<div className={`module-tab-bx ${tabNum !== 1 ? 'act' : ''}`}>{getMessage('modal.module.basic.setting.module.setting')}</div>
<span className={`tab-arr ${tabNum === 3 ? 'act' : ''}`}></span>
<div className={`module-tab-bx ${tabNum === 3 ? 'act' : ''}`}>{getMessage('modal.module.basic.setting.module.placement')}</div>
</>
)}
{/*배치면 초기설정 - 입력방법: 육지붕*/}
{/* {basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && tabNum === 3 && <PitchModule setTabNum={setTabNum} />} */}
{basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && tabNum === 2 && (
<PitchPlacement setTabNum={setTabNum} ref={placementFlatRef} />
{basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && (
<>
<div className={`module-tab-bx ${tabNum === 2 ? 'act' : ''}`}>{getMessage('modal.module.basic.setting.module.placement')}</div>
</>
)}
</div>
{tabNum === 1 && <Orientation ref={orientationRef} {...orientationProps} />}
{/*배치면 초기설정 - 입력방법: 복시도 입력 || 실측값 입력*/}
{basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && tabNum === 2 && <Trestle ref={trestleRef} {...trestleProps} />}
{basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && tabNum === 3 && (
<Placement setTabNum={setTabNum} layoutSetup={layoutSetup} setLayoutSetup={setLayoutSetup} />
)}
{/*배치면 초기설정 - 입력방법: 육지붕*/}
{/* {basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && tabNum === 3 && <PitchModule setTabNum={setTabNum} />} */}
{basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && tabNum === 2 && (
<PitchPlacement setTabNum={setTabNum} ref={placementFlatRef} />
)}
<div className="grid-btn-wrap">
{/* {tabNum === 1 && <button className="btn-frame modal mr5">{getMessage('modal.common.save')}</button>} */}

View File

@ -20,8 +20,8 @@ import { useEstimate } from '@/hooks/useEstimate'
import { useCircuitTrestle } from '@/hooks/useCirCuitTrestle'
import { useImgLoader } from '@/hooks/floorPlan/useImgLoader'
import { QcastContext } from '@/app/QcastProvider'
import { fontSelector } from '@/store/fontAtom'
import { fabric } from 'fabric'
import { fontSelector } from '@/store/fontAtom'
const ALLOCATION_TYPE = {
AUTO: 'auto',
@ -59,9 +59,6 @@ export default function CircuitTrestleSetting({ id }) {
const passivityCircuitAllocationRef = useRef()
const { setIsGlobalLoading } = useContext(QcastContext)
const originCanvasViewPortTransform = useRef([])
const [isFold, setIsFold] = useState(false)
const {
makers,
setMakers,
@ -86,7 +83,6 @@ export default function CircuitTrestleSetting({ id }) {
} = useCircuitTrestle()
// const { trigger: moduleSelectedDataTrigger } = useCanvasPopupStatusController(2)
useEffect(() => {
originCanvasViewPortTransform.current = [...canvas.viewportTransform]
if (!managementState) {
}
// setCircuitData({
@ -175,12 +171,15 @@ export default function CircuitTrestleSetting({ id }) {
})
}
canvas.renderAll()
// roof polygon
const roofPolygons = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
let x, y
x = canvas.width / 2
y = canvas.height / 2
canvas.zoomToPoint(new fabric.Point(x, y), 0.4)
changeFontSize('lengthText', '28')
changeFontSize('circuitNumber', '28')
changeFontSize('flowText', '28')
@ -189,12 +188,9 @@ export default function CircuitTrestleSetting({ id }) {
//
const afterCapture = (type) => {
if (originCanvasViewPortTransform.current[0] !== 1) {
setCanvasZoom(Number((originCanvasViewPortTransform.current[0] * 100).toFixed(0)))
}
canvas.viewportTransform = [...originCanvasViewPortTransform.current]
canvas.renderAll()
setCanvasZoom(100)
canvas.set({ zoom: 1 })
canvas.viewportTransform = [1, 0, 0, 1, 0, 0]
changeFontSize('lengthText', lengthText.fontSize.value)
changeFontSize('circuitNumber', circuitNumberText.fontSize.value)
changeFontSize('flowText', flowText.fontSize.value)
@ -227,33 +223,11 @@ export default function CircuitTrestleSetting({ id }) {
return
}
const isMultiModule = selectedModules.itemList.length > 1
let isAllIndfcs = false
if (isMultiModule) {
//INDFCS , OUTDMULTI
// 1. pcs alert
if (selectedModels.length > 0) {
isAllIndfcs = selectedModels.every((model) => model.pcsTpCd === 'INDFCS')
} else {
isAllIndfcs = models.every((model) => model.pcsTpCd === 'INDFCS')
}
}
if (isAllIndfcs) {
swalFire({
title: getMessage('module.circuit.indoor.focused.error'),
type: 'alert',
})
return
}
const params = {
...getOptYn(),
useModuleItemList: getUseModuleItemList(),
roofSurfaceList: getRoofSurfaceList(),
pcsItemList: getPcsItemList(isMultiModule),
pcsItemList: getPcsItemList(),
}
//
@ -314,12 +288,12 @@ export default function CircuitTrestleSetting({ id }) {
})
} else {
//
getPcsVoltageChk({ ...params, pcsItemList: getSelectedPcsItemList(isMultiModule) }).then((res) => {
getPcsVoltageChk({ ...params, pcsItemList: getSelectedPcsItemList() }).then((res) => {
if (res.resultCode === 'S') {
//
getPcsVoltageStepUpList({
...params,
pcsItemList: getSelectedPcsItemList(isMultiModule),
pcsItemList: getSelectedPcsItemList(),
}).then((res) => {
if (res?.result.resultCode === 'S' && res?.data) {
setTabNum(2)
@ -545,7 +519,6 @@ export default function CircuitTrestleSetting({ id }) {
obj.circuit = null
obj.pcsItemId = null
obj.circuitNumber = null
obj.pcs = null
})
setSelectedModels(
JSON.parse(JSON.stringify(selectedModels)).map((model) => {
@ -815,30 +788,20 @@ export default function CircuitTrestleSetting({ id }) {
return (
<WithDraggable isShow={true} pos={{ x: 50, y: 230 }} className="l-2">
<WithDraggable.Header
title={getMessage('modal.circuit.trestle.setting')}
onClose={() => handleClose()}
isFold={isFold}
onFold={() => setIsFold(!isFold)}
/>
<WithDraggable.Header title={getMessage('modal.circuit.trestle.setting')} onClose={() => handleClose()} />
<WithDraggable.Body>
<div style={{ display: !(tabNum === 1 && allocationType === ALLOCATION_TYPE.PASSIVITY) && isFold ? 'none' : 'block' }}>
<div style={{ display: tabNum === 1 && allocationType === ALLOCATION_TYPE.PASSIVITY && isFold ? 'none' : 'block' }}>
<div className="roof-module-tab">
<div className={`module-tab-bx act`}>{getMessage('modal.circuit.trestle.setting.power.conditional.select')}</div>
<span className={`tab-arr ${tabNum === 2 ? 'act' : ''}`}></span>
<div className={`module-tab-bx ${tabNum === 2 ? 'act' : ''}`}>
{getMessage('modal.circuit.trestle.setting.circuit.allocation')}({getMessage('modal.circuit.trestle.setting.step.up.allocation')})
</div>
</div>
<div className="roof-module-tab">
<div className={`module-tab-bx act`}>{getMessage('modal.circuit.trestle.setting.power.conditional.select')}</div>
<span className={`tab-arr ${tabNum === 2 ? 'act' : ''}`}></span>
<div className={`module-tab-bx ${tabNum === 2 ? 'act' : ''}`}>
{getMessage('modal.circuit.trestle.setting.circuit.allocation')}({getMessage('modal.circuit.trestle.setting.step.up.allocation')})
</div>
{tabNum === 1 && allocationType === ALLOCATION_TYPE.AUTO && <PowerConditionalSelect {...powerConditionalSelectProps} />}
{tabNum === 1 && allocationType === ALLOCATION_TYPE.PASSIVITY && (
<PassivityCircuitAllocation {...passivityProps} ref={passivityCircuitAllocationRef} isFold={isFold} />
)}
{tabNum === 2 && <StepUp {...stepUpProps} onInitialize={handleStepUpInitialize} />}
</div>
{tabNum === 1 && allocationType === ALLOCATION_TYPE.AUTO && <PowerConditionalSelect {...powerConditionalSelectProps} />}
{tabNum === 1 && allocationType === ALLOCATION_TYPE.PASSIVITY && (
<PassivityCircuitAllocation {...passivityProps} ref={passivityCircuitAllocationRef} />
)}
{tabNum === 2 && <StepUp {...stepUpProps} onInitialize={handleStepUpInitialize} />}
{tabNum === 1 && allocationType === ALLOCATION_TYPE.AUTO && (
<div className="grid-btn-wrap">
<button className="btn-frame modal mr5 act" onClick={() => onAutoRecommend()}>

View File

@ -649,13 +649,7 @@ export default function StepUp(props) {
style={{ cursor: allocationType === 'auto' ? 'pointer' : 'default' }}
>
<td className="al-r">{item.serQty}</td>
<td className="al-r">
{/* 2025.12.04 select 추가 */}
<select className="select-light dark table-select" name="" id="">
<option value="">{item.paralQty}</option>
</select>
</td>
{/* <td className="al-r">{item.paralQty}</td> */}
<td className="al-r">{item.paralQty}</td>
</tr>
)
})}

View File

@ -1,6 +1,7 @@
import { GlobalDataContext } from '@/app/GlobalDataProvider'
import { POLYGON_TYPE } from '@/common/common'
import { useMasterController } from '@/hooks/common/useMasterController'
import { useModule } from '@/hooks/module/useModule'
import { useCircuitTrestle } from '@/hooks/useCirCuitTrestle'
import { useMessage } from '@/hooks/useMessage'
import { useSwal } from '@/hooks/useSwal'
@ -9,8 +10,8 @@ import { moduleStatisticsState } from '@/store/circuitTrestleAtom'
import { fontSelector } from '@/store/fontAtom'
import { selectedModuleState } from '@/store/selectedModuleOptions'
import { circuitNumDisplaySelector } from '@/store/settingAtom'
import { useContext, useEffect, useRef, useState } from 'react'
import { useRecoilValue } from 'recoil'
import { useContext, useEffect, useState } from 'react'
import { useRecoilState, useRecoilValue } from 'recoil'
import { normalizeDigits } from '@/util/input-utils'
export default function PassivityCircuitAllocation(props) {
@ -21,7 +22,6 @@ export default function PassivityCircuitAllocation(props) {
getOptYn: getApiProps,
getUseModuleItemList: getSelectedModuleList,
getSelectModelList: getSelectModelList,
isFold,
} = props
const { swalFire } = useSwal()
const { getMessage } = useMessage()
@ -32,7 +32,6 @@ export default function PassivityCircuitAllocation(props) {
const { header, rows, footer } = useRecoilValue(moduleStatisticsState)
const [circuitNumber, setCircuitNumber] = useState(1)
const [targetModules, setTargetModules] = useState([])
const targetModulesRef = useRef([])
const { getPcsManualConfChk } = useMasterController()
const isDisplayCircuitNumber = useRecoilValue(circuitNumDisplaySelector)
const { setModuleStatisticsData } = useCircuitTrestle()
@ -60,10 +59,6 @@ export default function PassivityCircuitAllocation(props) {
}
}, [])
useEffect(() => {
targetModulesRef.current = targetModules
}, [targetModules])
const handleTargetModules = (obj) => {
if (!Array.isArray(targetModules)) {
setTargetModules([])
@ -84,7 +79,6 @@ export default function PassivityCircuitAllocation(props) {
}
const handleCircuitNumberFix = () => {
const pcsTpCd = selectedPcs.pcsTpCd // ,
let uniqueCircuitNumbers = [
...new Set(
canvas
@ -97,13 +91,13 @@ export default function PassivityCircuitAllocation(props) {
const surfaceList = targetModules.map((module) => {
return canvas.getObjects().filter((obj) => obj.id === canvas.getObjects().filter((obj) => obj.id === module)[0].surfaceId)[0]
})
let surfaceType = {}
surfaceList.forEach((surface) => {
surfaceType[`${surface.direction}-${surface.roofMaterial.pitch}`] = surface
})
if (surfaceList.length > 1) {
let surfaceType = {}
surfaceList.forEach((surface) => {
surfaceType[`${surface.direction}-${surface.roofMaterial.pitch}`] = surface
})
if (Object.keys(surfaceType).length > 1) {
swalFire({
text: getMessage('module.circuit.fix.not.same.roof.error'),
@ -113,7 +107,6 @@ export default function PassivityCircuitAllocation(props) {
return
}
}
if (!circuitNumber || circuitNumber === 0) {
swalFire({
text: getMessage('module.circuit.minimun.error'),
@ -121,65 +114,31 @@ export default function PassivityCircuitAllocation(props) {
icon: 'warning',
})
return
}
if (targetModules.length === 0) {
} else if (targetModules.length === 0) {
swalFire({
text: getMessage('module.not.found'),
type: 'alert',
icon: 'warning',
})
return
}
} else if (selectedModels.length > 1) {
let result = false
switch (pcsTpCd) {
case 'INDFCS': {
const originHaveThisPcsModules = canvas
.getObjects()
.filter((obj) => obj.name === POLYGON_TYPE.MODULE && obj.pcs && obj.pcs.id === selectedPcs.id)
// pcs surface .
const originSurfaceList = canvas
.getObjects()
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && originHaveThisPcsModules.map((obj) => obj.surfaceId).includes(obj.id))
originSurfaceList.concat(originSurfaceList).forEach((surface) => {
surfaceType[`${surface.direction}-${surface.roofMaterial.pitch}`] = surface
uniqueCircuitNumbers.forEach((number) => {
if (
number.split('-')[1] === circuitNumber + ')' &&
number.split('-')[0] !== '(' + (selectedModels.findIndex((model) => model.id === selectedPcs.id) + 1)
) {
result = true
}
})
if (result) {
swalFire({
text: getMessage('module.already.exist.error'),
type: 'alert',
icon: 'warning',
})
if (surfaceList.length > 1) {
if (Object.keys(surfaceType).length > 1) {
swalFire({
text: getMessage('module.circuit.fix.not.same.roof.error'),
type: 'alert',
icon: 'warning',
})
return
}
}
break
}
case 'OUTDMULTI': {
if (selectedModels.length > 1) {
let result = false
uniqueCircuitNumbers.forEach((number) => {
if (
number.split('-')[1] === circuitNumber + ')' &&
number.split('-')[0] !== '(' + (selectedModels.findIndex((model) => model.id === selectedPcs.id) + 1)
) {
result = true
}
})
if (result) {
swalFire({
text: getMessage('module.already.exist.error'),
type: 'alert',
icon: 'warning',
})
return
}
}
return
}
}
@ -230,7 +189,6 @@ export default function PassivityCircuitAllocation(props) {
roofSurfaceId: surface.id,
roofSurface: surface.direction,
roofSurfaceIncl: +canvas.getObjects().filter((obj) => obj.id === surface.parentId)[0].pitch,
roofSurfaceNorthYn: surface.direction === 'north' ? 'Y' : 'N',
moduleList: surface.modules.map((module) => {
return {
itemId: module.moduleInfo.itemId,
@ -312,12 +270,6 @@ export default function PassivityCircuitAllocation(props) {
return
}
targetModules.forEach((module) => {
const modules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE)
const targetModule = modules.find((obj) => obj.id === module)
targetModule.pcs = selectedPcs
})
setTargetModules([])
setCircuitNumber(+circuitNumber + 1)
setModuleStatisticsData()
@ -545,77 +497,73 @@ export default function PassivityCircuitAllocation(props) {
return (
<>
<div className="properties-setting-wrap outer">
<div style={{ display: isFold ? 'none' : 'block' }}>
<div className="setting-tit">{getMessage('modal.circuit.trestle.setting.circuit.allocation')}</div>
<div className="module-table-box mb10">
<div className="module-table-inner">
<div className="bold-font mb10">{getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity')}</div>
<div className="normal-font mb15">{getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.info')}</div>
<div className="roof-module-table overflow-y">
{header && (
<table>
<thead>
<tr>
{header.map((header, index) => (
<th key={'header' + index}>{header.name}</th>
))}
</tr>
</thead>
<tbody>
{rows.map((row, index) => (
<tr key={'row' + index}>
{header.map((header, i) => (
<td className="al-c" key={'rowcell' + i}>
{typeof row[header.prop] === 'number'
? (row[header.prop] ?? 0).toLocaleString('ko-KR', { maximumFractionDigits: 4 })
: (row[header.prop] ?? 0)}
</td>
))}
</tr>
<div className="setting-tit">{getMessage('modal.circuit.trestle.setting.circuit.allocation')}</div>
<div className="module-table-box mb10">
<div className="module-table-inner">
<div className="bold-font mb10">{getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity')}</div>
<div className="normal-font mb15">{getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.info')}</div>
<div className="roof-module-table overflow-y">
{header && (
<table>
<thead>
<tr>
{header.map((header, index) => (
<th key={'header' + index}>{header.name}</th>
))}
<tr>
</tr>
</thead>
<tbody>
{rows.map((row, index) => (
<tr key={'row' + index}>
{header.map((header, i) => (
<td className="al-c" key={'footer' + i}>
{footer[header.prop]}
<td className="al-c" key={'rowcell' + i}>
{typeof row[header.prop] === 'number'
? (row[header.prop] ?? 0).toLocaleString('ko-KR', { maximumFractionDigits: 4 })
: (row[header.prop] ?? 0)}
</td>
))}
</tr>
</tbody>
</table>
)}
</div>
))}
<tr>
{header.map((header, i) => (
<td className="al-c" key={'footer' + i}>
{footer[header.prop]}
</td>
))}
</tr>
</tbody>
</table>
)}
</div>
</div>
<div className="module-table-box mb10">
<div className="module-table-inner">
<div className="hexagonal-wrap">
<div className="hexagonal-item">
<div className="bold-font">
{getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.selected.power.conditional')}
</div>
<div className="module-table-box mb10">
<div className="module-table-inner">
<div className="hexagonal-wrap">
<div className="hexagonal-item">
<div className="bold-font">{getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.selected.power.conditional')}</div>
</div>
<div className="hexagonal-item">
{selectedModels.map((model, index) => (
<div className="d-check-radio pop mb10" key={'model' + index}>
<input
type="radio"
name="radio01"
id={`ra0${index + 1}`}
value={model}
checked={selectedPcs?.id === model.id}
onChange={() => setSelectedPcs(model)}
/>
<label htmlFor={`ra0${index + 1}`}>
{model.goodsNo} (
{getMessage(
'modal.circuit.trestle.setting.circuit.allocation.passivity.circuit.info',
managementState?.coldRegionFlg === '1' ? [model.serMinQty, model.serColdZoneMaxQty] : [model.serMinQty, model.serMaxQty],
)}
)
</label>
</div>
</div>
<div className="hexagonal-item">
{selectedModels.map((model, index) => (
<div className="d-check-radio pop mb10" key={'model' + index}>
<input
type="radio"
name="radio01"
id={`ra0${index + 1}`}
value={model}
checked={selectedPcs?.id === model.id}
onChange={() => setSelectedPcs(model)}
/>
<label htmlFor={`ra0${index + 1}`}>
{model.goodsNo} (
{getMessage(
'modal.circuit.trestle.setting.circuit.allocation.passivity.circuit.info',
managementState?.coldRegionFlg === '1' ? [model.serMinQty, model.serColdZoneMaxQty] : [model.serMinQty, model.serMaxQty],
)}
)
</label>
</div>
))}
</div>
))}
</div>
</div>
</div>

View File

@ -4,7 +4,6 @@ import { useState } from 'react'
import { useRecoilValue } from 'recoil'
import { ANGLE_TYPE, currentAngleTypeSelector } from '@/store/canvasAtom'
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function Eaves({ pitchRef, offsetRef, widthRef, radioTypeRef, pitchText }) {
const { getMessage } = useMessage()
@ -22,32 +21,17 @@ export default function Eaves({ pitchRef, offsetRef, widthRef, radioTypeRef, pit
{getMessage('slope')}
</span>
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input*/}
{/* type="text"*/}
{/* className="input-origin block"*/}
{/* defaultValue={currentAngleType === ANGLE_TYPE.SLOPE ? 4 : 21.8}*/}
{/* ref={pitchRef}*/}
{/* onChange={(e) => {*/}
{/* const v = normalizeDecimalLimit(e.target.value, 2)*/}
{/* e.target.value = v*/}
{/* if (pitchRef?.current) pitchRef.current.value = v*/}
{/* }}*/}
{/*/>*/}
<CalculatorInput
id=""
name=""
label=""
<input
type="text"
className="input-origin block"
defaultValue={currentAngleType === ANGLE_TYPE.SLOPE ? 4 : 21.8}
ref={pitchRef}
value={currentAngleType === ANGLE_TYPE.SLOPE ? 4 : 21.8}
onChange={(value) => {
if (pitchRef?.current) pitchRef.current.value = value
onChange={(e) => {
const v = normalizeDecimalLimit(e.target.value, 2)
e.target.value = v
if (pitchRef?.current) pitchRef.current.value = v
}}
options={{
allowNegative: false,
allowDecimal: true //(index !== 0),
}}
></CalculatorInput>
/>
</div>
<span className="thin">{pitchText}</span>
</div>
@ -56,32 +40,17 @@ export default function Eaves({ pitchRef, offsetRef, widthRef, radioTypeRef, pit
{getMessage('offset')}
</span>
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input*/}
{/* type="text"*/}
{/* className="input-origin block"*/}
{/* defaultValue={500}*/}
{/* ref={offsetRef}*/}
{/* onChange={(e) => {*/}
{/* const v = normalizeDigits(e.target.value)*/}
{/* e.target.value = v*/}
{/* if (offsetRef?.current) offsetRef.current.value = v*/}
{/* }}*/}
{/*/>*/}
<CalculatorInput
id=""
name=""
label=""
<input
type="text"
className="input-origin block"
defaultValue={500}
ref={offsetRef}
value={500}
onChange={(value) => {
if (offsetRef?.current) offsetRef.current.value = value
onChange={(e) => {
const v = normalizeDigits(e.target.value)
e.target.value = v
if (offsetRef?.current) offsetRef.current.value = v
}}
options={{
allowNegative: false,
allowDecimal: false //(index !== 0),
}}
></CalculatorInput>
/>
</div>
<span className="thin">mm</span>
</div>
@ -122,33 +91,18 @@ export default function Eaves({ pitchRef, offsetRef, widthRef, radioTypeRef, pit
<div className="eaves-keraba-th">
<div className="outline-form">
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input*/}
{/* type="text"*/}
{/* className="input-origin block"*/}
{/* defaultValue={500}*/}
{/* ref={widthRef}*/}
{/* readOnly={type === '1'}*/}
{/* onChange={(e) => {*/}
{/* const v = normalizeDigits(e.target.value)*/}
{/* e.target.value = v*/}
{/* if (widthRef?.current) widthRef.current.value = v*/}
{/* }}*/}
{/*/>*/}
<CalculatorInput
id=""
name=""
label=""
<input
type="text"
className="input-origin block"
defaultValue={500}
ref={widthRef}
value={500}
onChange={(value) => {
if (widthRef?.current) widthRef.current.value = value
readOnly={type === '1'}
onChange={(e) => {
const v = normalizeDigits(e.target.value)
e.target.value = v
if (widthRef?.current) widthRef.current.value = v
}}
options={{
allowNegative: false,
allowDecimal: false //(index !== 0),
}}
></CalculatorInput>
/>
</div>
<span className="thin">mm</span>
</div>

View File

@ -3,7 +3,6 @@ import Image from 'next/image'
import { useState } from 'react'
import { useRecoilValue } from 'recoil'
import { ANGLE_TYPE, currentAngleTypeSelector } from '@/store/canvasAtom'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function Gable({ pitchRef, offsetRef, widthRef, radioTypeRef, pitchText }) {
const { getMessage } = useMessage()
@ -22,19 +21,7 @@ export default function Gable({ pitchRef, offsetRef, widthRef, radioTypeRef, pit
{getMessage('offset')}
</span>
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input type="text" className="input-origin block" defaultValue={300} ref={offsetRef} />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
ref={offsetRef}
value={300}
options={{
allowNegative: false,
allowDecimal: false //(index !== 0),
}}
></CalculatorInput>
<input type="text" className="input-origin block" defaultValue={300} ref={offsetRef} />
</div>
<span className="thin">mm</span>
</div>
@ -78,29 +65,13 @@ export default function Gable({ pitchRef, offsetRef, widthRef, radioTypeRef, pit
{getMessage('slope')}
</span>
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input*/}
{/* type="text"*/}
{/* className="input-origin block"*/}
{/* defaultValue={currentAngleType === ANGLE_TYPE.SLOPE ? 4.5 : 20}*/}
{/* ref={pitchRef}*/}
{/* readOnly={type === '1'}*/}
{/*/>*/}
<CalculatorInput
id=""
name=""
label=""
<input
type="text"
className="input-origin block"
defaultValue={currentAngleType === ANGLE_TYPE.SLOPE ? 4.5 : 20}
ref={pitchRef}
value={currentAngleType === ANGLE_TYPE.SLOPE ? 4.5 : 20}
readOnly={type === '1'}
onChange={(value) => {
if (pitchRef?.current) pitchRef.current.value = value
}}
options={{
allowNegative: false,
allowDecimal: true //(index !== 0),
}}
></CalculatorInput>
/>
</div>
<span className="thin">{pitchText}</span>
</div>
@ -120,20 +91,7 @@ export default function Gable({ pitchRef, offsetRef, widthRef, radioTypeRef, pit
{getMessage('offset')}
</span>
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input type="text" className="input-origin block" defaultValue={800} ref={widthRef} readOnly={type === '1'} />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
ref={widthRef}
value={800}
readOnly={type === '1'}
options={{
allowNegative: false,
allowDecimal: false //(index !== 0),
}}
></CalculatorInput>
<input type="text" className="input-origin block" defaultValue={800} ref={widthRef} readOnly={type === '1'} />
</div>
<span className="thin">mm</span>
</div>

View File

@ -1,5 +1,4 @@
import { useMessage } from '@/hooks/useMessage'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function Shed({ offsetRef }) {
const { getMessage } = useMessage()
@ -11,19 +10,7 @@ export default function Shed({ offsetRef }) {
{getMessage('offset')}
</span>
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input type="text" className="input-origin block" ref={offsetRef} defaultValue={300} />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
ref={offsetRef}
value={300}
options={{
allowNegative: false,
allowDecimal: false //(index !== 0),
}}
></CalculatorInput>
<input type="text" className="input-origin block" ref={offsetRef} defaultValue={300} />
</div>
<span className="thin">mm</span>
</div>

View File

@ -1,7 +1,6 @@
import { useMessage } from '@/hooks/useMessage'
import Image from 'next/image'
import { useState } from 'react'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function WallMerge({ offsetRef, radioTypeRef }) {
const { getMessage } = useMessage()
@ -52,20 +51,7 @@ export default function WallMerge({ offsetRef, radioTypeRef }) {
{getMessage('offset')}
</span>
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input type="text" className="input-origin block" defaultValue={300} ref={offsetRef} readOnly={type === '1'} />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
ref={offsetRef}
value={300}
readOnly={type === '1'}
options={{
allowNegative: false,
allowDecimal: false //(index !== 0),
}}
></CalculatorInput>
<input type="text" className="input-origin block" defaultValue={300} ref={offsetRef} readOnly={type === '1'} />
</div>
<span className="thin">mm</span>
</div>

View File

@ -1,7 +1,6 @@
import Image from 'next/image'
import { useMessage } from '@/hooks/useMessage'
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function Angle({ props }) {
const { getMessage } = useMessage()
@ -15,29 +14,14 @@ export default function Angle({ props }) {
<div className="outline-form">
<span className="mr10">{getMessage('modal.cover.outline.angle')}</span>
<div className="input-grid" style={{ width: '63px' }}>
{/*<input*/}
{/* type="text"*/}
{/* className="input-origin block"*/}
{/* value={angle1}*/}
{/* ref={angle1Ref}*/}
{/* onFocus={(e) => (angle1Ref.current.value = '')}*/}
{/* onChange={(e) => setAngle1(normalizeDecimalLimit(e.target.value, 2))}*/}
{/* placeholder="45"*/}
{/*/>*/}
<CalculatorInput
id=""
name=""
label=""
<input
type="text"
className="input-origin block"
value={angle1}
ref={angle1Ref}
onChange={(value) => setAngle1(value)}
onFocus={(e) => (angle1Ref.current.value = '')}
onChange={(e) => setAngle1(normalizeDecimalLimit(e.target.value, 2))}
placeholder="45"
onFocus={() => (angle1Ref.current.value = '')}
options={{
allowNegative: false,
allowDecimal: true
}}
/>
</div>
<button
@ -50,29 +34,14 @@ export default function Angle({ props }) {
<div className="outline-form">
<span className="mr10">{getMessage('modal.cover.outline.length')}</span>
<div className="input-grid" style={{ width: '63px' }}>
{/*<input*/}
{/* type="text"*/}
{/* className="input-origin block"*/}
{/* value={length1}*/}
{/* ref={length1Ref}*/}
{/* onFocus={(e) => (length1Ref.current.value = '')}*/}
{/* onChange={(e) => setLength1(normalizeDigits(e.target.value))}*/}
{/* placeholder="3000"*/}
{/*/>*/}
<CalculatorInput
id=""
name=""
label=""
<input
type="text"
className="input-origin block"
value={length1}
ref={length1Ref}
onChange={(value) => setLength1(value)}
onFocus={(e) => (length1Ref.current.value = '')}
onChange={(e) => setLength1(normalizeDigits(e.target.value))}
placeholder="3000"
onFocus={() => (length1Ref.current.value = '')}
options={{
allowNegative: false,
allowDecimal: false
}}
/>
</div>
<button

View File

@ -1,6 +1,5 @@
import { useMessage } from '@/hooks/useMessage'
import { normalizeDigits } from '@/util/input-utils'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function Diagonal({ props }) {
const { getMessage } = useMessage()
@ -31,29 +30,14 @@ export default function Diagonal({ props }) {
{getMessage('modal.cover.outline.length')}
</span>
<div className="input-grid" style={{ width: '63px' }}>
{/*<input*/}
{/* type="text"*/}
{/* className="input-origin block"*/}
{/* value={outerLineDiagonalLength}*/}
{/* ref={outerLineDiagonalLengthRef}*/}
{/* onFocus={(e) => (outerLineDiagonalLengthRef.current.value = '')}*/}
{/* onChange={(e) => setOuterLineDiagonalLength(normalizeDigits(e.target.value))}*/}
{/* placeholder="3000"*/}
{/*/>*/}
<CalculatorInput
id=""
name=""
label=""
<input
type="text"
className="input-origin block"
value={outerLineDiagonalLength}
ref={outerLineDiagonalLengthRef}
onChange={(value) => setOuterLineDiagonalLength(value)}
onFocus={(e) => (outerLineDiagonalLengthRef.current.value = '')}
onChange={(e) => setOuterLineDiagonalLength(normalizeDigits(e.target.value))}
placeholder="3000"
onFocus={() => (outerLineDiagonalLengthRef.current.value = '')}
options={{
allowNegative: false,
allowDecimal: false
}}
/>
</div>
<button
@ -68,29 +52,14 @@ export default function Diagonal({ props }) {
<div className="outline-form">
<span className="mr10"> {getMessage('modal.cover.outline.length')}</span>
<div className="input-grid" style={{ width: '63px' }}>
{/*<input*/}
{/* type="text"*/}
{/* className="input-origin block"*/}
{/* value={length1}*/}
{/* ref={length1Ref}*/}
{/* onFocus={(e) => (length1Ref.current.value = '')}*/}
{/* onChange={(e) => setLength1(normalizeDigits(e.target.value))}*/}
{/* placeholder="3000"*/}
{/*/>*/}
<CalculatorInput
id=""
name=""
label=""
<input
type="text"
className="input-origin block"
value={length1}
ref={length1Ref}
onChange={(value) => setLength1(value)}
onFocus={(e) => (length1Ref.current.value = '')}
onChange={(e) => setLength1(normalizeDigits(e.target.value))}
placeholder="3000"
onFocus={() => (length1Ref.current.value = '')}
options={{
allowNegative: false,
allowDecimal: false
}}
/>
</div>
<button
@ -141,29 +110,14 @@ export default function Diagonal({ props }) {
<div className="outline-form">
<span className="mr10"> {getMessage('modal.cover.outline.length')}</span>
<div className="input-grid" style={{ width: '98px' }}>
{/*<input*/}
{/* type="text"*/}
{/* className="input-origin block"*/}
{/* value={length2}*/}
{/* ref={length2Ref}*/}
{/* onChange={(e) => setLength2(normalizeDigits(e.target.value))}*/}
{/* readOnly={true}*/}
{/* placeholder="3000"*/}
{/*/>*/}
<CalculatorInput
id=""
name=""
label=""
<input
type="text"
className="input-origin block"
value={length2}
ref={length2Ref}
onChange={(value) => setLength2(value)}
onChange={(e) => setLength2(normalizeDigits(e.target.value))}
readOnly={true}
placeholder="3000"
onFocus={() => (length2Ref.current.value = '')}
options={{
allowNegative: false,
allowDecimal: false
}}
/>
</div>
</div>

View File

@ -1,7 +1,6 @@
import { useMessage } from '@/hooks/useMessage'
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
import { getDegreeByChon } from '@/util/canvas-util'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function DoublePitch({ props }) {
const { getMessage } = useMessage()
@ -51,29 +50,14 @@ export default function DoublePitch({ props }) {
<div className="outline-form">
<span className="mr10">{getMessage('modal.cover.outline.angle')}</span>
<div className="input-grid" style={{ width: '63px' }}>
{/*<input*/}
{/* type="text"*/}
{/* className="input-origin block"*/}
{/* value={angle1}*/}
{/* ref={angle1Ref}*/}
{/* onFocus={(e) => (angle1Ref.current.value = '')}*/}
{/* onChange={(e) => setAngle1(normalizeDecimalLimit(e.target.value, 2))}*/}
{/* placeholder="45"*/}
{/*/>*/}
<CalculatorInput
id=""
name=""
label=""
<input
type="text"
className="input-origin block"
value={angle1}
ref={angle1Ref}
onChange={(value) => setAngle1(value)}
onFocus={(e) => (angle1Ref.current.value = '')}
onChange={(e) => setAngle1(normalizeDecimalLimit(e.target.value, 2))}
placeholder="45"
onFocus={() => (angle1Ref.current.value = '')}
options={{
allowNegative: false,
allowDecimal: true
}}
/>
</div>
<button className="reset-btn" onClick={() => setAngle1(0)}></button>
@ -83,29 +67,14 @@ export default function DoublePitch({ props }) {
<div className="outline-form">
<span className="mr10">{getMessage('modal.cover.outline.length')}</span>
<div className="input-grid" style={{ width: '63px' }}>
{/*<input*/}
{/* type="text"*/}
{/* className="input-origin block"*/}
{/* value={length1}*/}
{/* ref={length1Ref}*/}
{/* onFocus={(e) => (length1Ref.current.value = '')}*/}
{/* onChange={(e) => setLength1(normalizeDigits(e.target.value))}*/}
{/* placeholder="3000"*/}
{/*/>*/}
<CalculatorInput
id=""
name=""
label=""
<input
type="text"
className="input-origin block"
value={length1}
ref={length1Ref}
onChange={(value) => setLength1(value)}
onFocus={(e) => (length1Ref.current.value = '')}
onChange={(e) => setLength1(normalizeDigits(e.target.value))}
placeholder="3000"
onFocus={() => (length1Ref.current.value = '')}
options={{
allowNegative: false,
allowDecimal: false
}}
/>
</div>
<button
@ -156,36 +125,18 @@ export default function DoublePitch({ props }) {
<div className="outline-form">
<span className="mr10">{getMessage('modal.cover.outline.angle')}</span>
<div className="input-grid" style={{ width: '63px' }}>
{/*<input*/}
{/* type="text"*/}
{/* className="input-origin block"*/}
{/* value={angle2}*/}
{/* ref={angle2Ref}*/}
{/* onFocus={(e) => (angle2Ref.current.value = '')}*/}
{/* onChange={(e) => {*/}
{/* const v = normalizeDecimalLimit(e.target.value, 2)*/}
{/* setAngle2(v)*/}
{/* setLength2(getLength2())*/}
{/* }}*/}
{/* placeholder="45"*/}
{/*/>*/}
<CalculatorInput
id=""
name=""
label=""
<input
type="text"
className="input-origin block"
value={angle2}
ref={angle2Ref}
onChange={(value) => {
setAngle2(value)
onFocus={(e) => (angle2Ref.current.value = '')}
onChange={(e) => {
const v = normalizeDecimalLimit(e.target.value, 2)
setAngle2(v)
setLength2(getLength2())
}}
placeholder="45"
onFocus={() => (angle2Ref.current.value = '')}
options={{
allowNegative: false,
allowDecimal: true
}}
/>
</div>
<button
@ -200,30 +151,15 @@ export default function DoublePitch({ props }) {
<div className="outline-form">
<span className="mr10">{getMessage('modal.cover.outline.length')}</span>
<div className="input-grid" style={{ width: '63px' }}>
{/*<input*/}
{/* type="text"*/}
{/* className="input-origin block"*/}
{/* value={length2}*/}
{/* ref={length2Ref}*/}
{/* onFocus={(e) => (length2Ref.current.value = '')}*/}
{/* onChange={(e) => setLength2(normalizeDigits(e.target.value))}*/}
{/* readOnly={true}*/}
{/* placeholder="3000"*/}
{/*/>*/}
<CalculatorInput
id=""
name=""
label=""
<input
type="text"
className="input-origin block"
value={length2}
ref={length2Ref}
onChange={(value) => setLength2(value)}
onFocus={(e) => (length2Ref.current.value = '')}
onChange={(e) => setLength2(normalizeDigits(e.target.value))}
readOnly={true}
placeholder="3000"
onFocus={() => (length2Ref.current.value = '')}
options={{
allowNegative: false,
allowDecimal: false
}}
/>
</div>
<button

View File

@ -1,6 +1,5 @@
import { useMessage } from '@/hooks/useMessage'
import { normalizeDigits } from '@/util/input-utils'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function RightAngle({ props }) {
const { getMessage } = useMessage()
@ -23,29 +22,14 @@ export default function RightAngle({ props }) {
<div className="outline-form">
<span className="mr10">{getMessage('modal.cover.outline.length')}</span>
<div className="input-grid" style={{ width: '63px' }}>
{/*<input*/}
{/* type="text"*/}
{/* className="input-origin block"*/}
{/* value={length1}*/}
{/* ref={length1Ref}*/}
{/* onFocus={(e) => (length1Ref.current.value = '')}*/}
{/* onChange={(e) => setLength1(normalizeDigits(e.target.value))}*/}
{/* placeholder="3000"*/}
{/*/>*/}
<CalculatorInput
id=""
name=""
label=""
<input
type="text"
className="input-origin block"
placeholder="3000"
value={length1}
ref={length1Ref}
onChange={(value) => setLength1(value)}
onFocus={() => (length1Ref.current.value = '')}
options={{
allowNegative: false,
allowDecimal: false
}}
onFocus={(e) => (length1Ref.current.value = '')}
onChange={(e) => setLength1(normalizeDigits(e.target.value))}
placeholder="3000"
/>
</div>
<button
@ -94,29 +78,14 @@ export default function RightAngle({ props }) {
<div className="outline-form">
<span className="mr10">{getMessage('modal.cover.outline.length')}</span>
<div className="input-grid" style={{ width: '63px' }}>
{/*<input*/}
{/* type="text"*/}
{/* className="input-origin block"*/}
{/* value={length2}*/}
{/* ref={length2Ref}*/}
{/* onFocus={(e) => (length2Ref.current.value = '')}*/}
{/* onChange={(e) => setLength2(normalizeDigits(e.target.value))}*/}
{/* placeholder="3000"*/}
{/*/>*/}
<CalculatorInput
id=""
name=""
label=""
<input
type="text"
className="input-origin block"
value={length2}
ref={length2Ref}
onFocus={() => (length2Ref.current.value = '')}
onChange={(value) => setLength2(value)}
onFocus={(e) => (length2Ref.current.value = '')}
onChange={(e) => setLength2(normalizeDigits(e.target.value))}
placeholder="3000"
options={{
allowNegative: false,
allowDecimal: false
}}
/>
</div>
<button

View File

@ -6,7 +6,6 @@ import { contextPopupPositionState } from '@/store/popupAtom'
import { usePopup } from '@/hooks/usePopup'
import { useObjectBatch } from '@/hooks/object/useObjectBatch'
import { canvasState } from '@/store/canvasAtom'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function DormerOffset(props) {
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
@ -17,8 +16,6 @@ export default function DormerOffset(props) {
const [arrow2, setArrow2] = useState(null)
const arrow1LengthRef = useRef()
const arrow2LengthRef = useRef()
const [arrow1Length, setArrow1Length] = useState(0)
const [arrow2Length, setArrow2Length] = useState(0)
const canvas = useRecoilValue(canvasState)
const { dormerOffsetKeyEvent, dormerOffset } = useObjectBatch({})
@ -53,20 +50,7 @@ export default function DormerOffset(props) {
<p className="mb5">{getMessage('length')}</p>
<div className="input-move-wrap mb5">
<div className="input-move">
{/*<input type="text" className="input-origin" ref={arrow1LengthRef} placeholder="0" />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
value={arrow1LengthRef.current.value}
ref={arrow1LengthRef}
onChange={(value) => setArrow1Length(value)}
options={{
allowNegative: false,
allowDecimal: false
}}
/>
<input type="text" className="input-origin" ref={arrow1LengthRef} placeholder="0" />
</div>
<span>mm</span>
<div className="direction-move-wrap">

View File

@ -5,11 +5,10 @@ import { useMessage } from '@/hooks/useMessage'
import WithDraggable from '@/components/common/draggable/WithDraggable'
import { usePopup } from '@/hooks/usePopup'
import { contextPopupPositionState } from '@/store/popupAtom'
import { useEffect, useRef, useState } from 'react'
import { useRef, useState } from 'react'
import { useObjectBatch } from '@/hooks/object/useObjectBatch'
import { BATCH_TYPE, POLYGON_TYPE } from '@/common/common'
import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function SizeSetting(props) {
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
@ -21,8 +20,7 @@ export default function SizeSetting(props) {
const { resizeSurfaceShapeBatch } = useSurfaceShapeBatch({})
const widthRef = useRef(null)
const heightRef = useRef(null)
const [width, setWidth] = useState(target?.width ? (target.width * 10).toFixed() : 0)
const [height, setHeight] = useState(target?.height ? (target.height * 10) : 0)
// const { initEvent } = useEvent()
// const { initEvent } = useContext(EventContext)
@ -30,15 +28,6 @@ export default function SizeSetting(props) {
// initEvent()
// }, [])
useEffect(() => {
if (target?.width !== undefined) {
setWidth((target.width * 10).toFixed());
}
if (target?.height !== undefined) {
setHeight((target.height * 10).toFixed());
}
}, [target]);
const handleReSizeObject = () => {
const width = widthRef.current.value
const height = heightRef.current.value
@ -58,25 +47,11 @@ export default function SizeSetting(props) {
<div className="size-option-top">
<div className="size-option-wrap">
<div className="size-option mb5">
<input type="text" className="input-origin mr5" value={width}
onChange={(e) => setWidth(e.target.value)} readOnly={true} />
<input type="text" className="input-origin mr5" value={(target?.originWidth * 10).toFixed(0)} readOnly={true} />
<span className="normal-font">mm</span>
</div>
<div className="size-option">
{/*<input type="text" className="input-origin mr5" defaultValue={(target?.originWidth * 10).toFixed(0)} ref={widthRef} />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
value={width}
ref={widthRef}
onChange={(value) => setWidth(value)}
options={{
allowNegative: false,
allowDecimal: false
}}
/>
<input type="text" className="input-origin mr5" defaultValue={(target?.originWidth * 10).toFixed(0)} ref={widthRef} />
<span className="normal-font">mm</span>
</div>
</div>
@ -85,25 +60,11 @@ export default function SizeSetting(props) {
<div className="size-option-side">
<div className="size-option-wrap">
<div className="size-option mb5">
<input type="text" className="input-origin mr5" value={height}
onChange={(e) => setHeight(e.target.value)} readOnly={true} />
<input type="text" className="input-origin mr5" value={(target?.originHeight * 10).toFixed(0)} readOnly={true} />
<span className="normal-font">mm</span>
</div>
<div className="size-option">
{/*<input type="text" className="input-origin mr5" defaultValue={(target?.originHeight * 10).toFixed(0)} ref={heightRef} />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
value={height}
ref={heightRef}
onChange={(value) => setHeight(value)}
options={{
allowNegative: false,
allowDecimal: false
}}
/>
<input type="text" className="input-origin mr5" defaultValue={(target?.originHeight * 10).toFixed(0)} ref={heightRef} />
<span className="normal-font">mm</span>
</div>
</div>

View File

@ -1,13 +1,10 @@
import { forwardRef, useState, useEffect } from 'react'
import { useMessage } from '@/hooks/useMessage'
import { INPUT_TYPE } from '@/common/common'
import { CalculatorInput } from '@/components/common/input/CalcInput'
const OpenSpace = forwardRef((props, refs) => {
const { getMessage } = useMessage()
const [selectedType, setSelectedType] = useState(INPUT_TYPE.FREE)
const [width, setWidth] = useState(0)
const [height, setHeight] = useState(0)
useEffect(() => {
if (selectedType === INPUT_TYPE.FREE) {
@ -54,26 +51,12 @@ const OpenSpace = forwardRef((props, refs) => {
<div className="eaves-keraba-td">
<div className="outline-form">
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input*/}
{/* type="text"*/}
{/* className="input-origin block"*/}
{/* placeholder={0}*/}
{/* ref={refs.widthRef}*/}
{/* disabled={selectedType !== INPUT_TYPE.DIMENSION}*/}
{/*/>*/}
<CalculatorInput
id=""
name=""
label=""
<input
type="text"
className="input-origin block"
value={width}
placeholder={0}
ref={refs.widthRef}
onChange={(value) => setWidth(value)}
disabled={selectedType !== INPUT_TYPE.DIMENSION}
options={{
allowNegative: false,
allowDecimal: false
}}
/>
</div>
<span className="thin">mm</span>
@ -85,26 +68,12 @@ const OpenSpace = forwardRef((props, refs) => {
<div className="eaves-keraba-td">
<div className="outline-form">
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input*/}
{/* type="text"*/}
{/* className="input-origin block"*/}
{/* placeholder={0}*/}
{/* ref={refs.heightRef}*/}
{/* disabled={selectedType !== INPUT_TYPE.DIMENSION}*/}
{/*/>*/}
<CalculatorInput
id=""
name=""
label=""
<input
type="text"
className="input-origin block"
value={height}
placeholder={0}
ref={refs.heightRef}
onChange={(value) => setHeight(value)}
disabled={selectedType !== INPUT_TYPE.DIMENSION}
options={{
allowNegative: false,
allowDecimal: false
}}
/>
</div>
<span className="thin">mm</span>

View File

@ -1,7 +1,6 @@
import Image from 'next/image'
import { useMessage } from '@/hooks/useMessage'
import { forwardRef, useState } from 'react'
import { CalculatorInput } from '@/components/common/input/CalcInput'
const PentagonDormer = forwardRef((props, refs) => {
const { getMessage } = useMessage()
@ -12,11 +11,6 @@ const PentagonDormer = forwardRef((props, refs) => {
setDirection(e.target.value)
refs.directionRef.current = e.target.value
}
const [pitch, setPitch] = useState(4) // pitch , 4
const [offsetWidth, setOffsetWidth] = useState(300) // offsetWidth , 300
const [offsetDepth, setOffsetDepth] = useState(400) // offsetDepth , 400
const [width, setWidth] = useState(2000) // width , 2000
const [height, setHeight] = useState(2000) // height , 2000
return (
<>
@ -36,20 +30,7 @@ const PentagonDormer = forwardRef((props, refs) => {
<div className="eaves-keraba-td">
<div className="outline-form">
<div className="input-grid mr5" style={{ width: '60px' }}>
{/*<input type="text" className="input-origin block" placeholder={0} ref={refs.heightRef} defaultValue={2000} />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
value={height}
ref={refs.heightRef}
onChange={(value) => setHeight(value)}
options={{
allowNegative: false,
allowDecimal: false
}}
/>
<input type="text" className="input-origin block" placeholder={0} ref={refs.heightRef} defaultValue={2000} />
</div>
<span className="thin">mm</span>
</div>
@ -60,20 +41,7 @@ const PentagonDormer = forwardRef((props, refs) => {
<div className="eaves-keraba-td">
<div className="outline-form">
<div className="input-grid mr5" style={{ width: '60px' }}>
{/*<input type="text" className="input-origin block" placeholder={0} ref={refs.offsetRef} defaultValue={400} />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
value={offsetDepth}
ref={refs.offsetRef}
onChange={(value) => setOffsetDepth(value)}
options={{
allowNegative: false,
allowDecimal: false
}}
/>
<input type="text" className="input-origin block" placeholder={0} ref={refs.offsetRef} defaultValue={400} />
</div>
<span className="thin">mm</span>
</div>
@ -87,20 +55,7 @@ const PentagonDormer = forwardRef((props, refs) => {
<div className="eaves-keraba-td">
<div className="outline-form">
<div className="input-grid mr5" style={{ width: '60px' }}>
{/*<input type="text" className="input-origin block" placeholder={0} ref={refs.widthRef} defaultValue={2000} />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
value={width}
ref={refs.widthRef}
onChange={(value) => setWidth(value)}
options={{
allowNegative: false,
allowDecimal: false
}}
/>
<input type="text" className="input-origin block" placeholder={0} ref={refs.widthRef} defaultValue={2000} />
</div>
<span className="thin">mm</span>
</div>
@ -111,20 +66,7 @@ const PentagonDormer = forwardRef((props, refs) => {
<div className="eaves-keraba-td">
<div className="outline-form">
<div className="input-grid mr5" style={{ width: '60px' }}>
{/*<input type="text" className="input-origin block" placeholder={0} ref={refs.offsetWidthRef} defaultValue={300} />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
value={offsetWidth}
ref={refs.offsetWidthRef}
onChange={(value) => setOffsetWidth(value)}
options={{
allowNegative: false,
allowDecimal: false
}}
/>
<input type="text" className="input-origin block" placeholder={0} ref={refs.offsetWidthRef} defaultValue={300} />
</div>
<span className="thin">mm</span>
</div>
@ -135,20 +77,7 @@ const PentagonDormer = forwardRef((props, refs) => {
<div className="eaves-keraba-td">
<div className="outline-form">
<div className="input-grid mr5" style={{ width: '60px' }}>
{/*<input type="text" className="input-origin block" placeholder={0} ref={refs.pitchRef} defaultValue={4} />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
ref={refs.pitchRef}
value={pitch}
onChange={(value) => setPitch(value)}
options={{
allowNegative: false,
allowDecimal: true //(index !== 0),
}}
></CalculatorInput>
<input type="text" className="input-origin block" placeholder={0} ref={refs.pitchRef} defaultValue={4} />
</div>
<span className="thin"></span>
</div>

View File

@ -1,14 +1,11 @@
import { forwardRef, useState, useEffect } from 'react'
import { useMessage } from '@/hooks/useMessage'
import { INPUT_TYPE } from '@/common/common'
import { CalculatorInput } from '@/components/common/input/CalcInput'
const Shadow = forwardRef((props, refs) => {
const { getMessage } = useMessage()
const [selectedType, setSelectedType] = useState(INPUT_TYPE.FREE)
const [width, setWidth] = useState(0)
const [height, setHeight] = useState(0)
useEffect(() => {
if (selectedType === INPUT_TYPE.FREE) {
@ -54,26 +51,12 @@ const Shadow = forwardRef((props, refs) => {
<div className="eaves-keraba-td">
<div className="outline-form">
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input*/}
{/* type="text"*/}
{/* className="input-origin block"*/}
{/* placeholder={0}*/}
{/* ref={refs.widthRef}*/}
{/* disabled={selectedType !== INPUT_TYPE.DIMENSION}*/}
{/*/>*/}
<CalculatorInput
id=""
name=""
label=""
<input
type="text"
className="input-origin block"
value={width}
placeholder={0}
ref={refs.widthRef}
onChange={(value) => setWidth(value)}
disabled={selectedType !== INPUT_TYPE.DIMENSION}
options={{
allowNegative: false,
allowDecimal: false
}}
/>
</div>
<span className="thin">mm</span>
@ -85,26 +68,12 @@ const Shadow = forwardRef((props, refs) => {
<div className="eaves-keraba-td">
<div className="outline-form">
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input*/}
{/* type="text"*/}
{/* className="input-origin block"*/}
{/* placeholder={0}*/}
{/* ref={refs.heightRef}*/}
{/* disabled={selectedType !== INPUT_TYPE.DIMENSION}*/}
{/*/>*/}
<CalculatorInput
id=""
name=""
label=""
<input
type="text"
className="input-origin block"
value={height}
placeholder={0}
ref={refs.heightRef}
onChange={(value) => setHeight(value)}
disabled={selectedType !== INPUT_TYPE.DIMENSION}
options={{
allowNegative: false,
allowDecimal: false
}}
/>
</div>
<span className="thin">mm</span>

View File

@ -1,7 +1,6 @@
import Image from 'next/image'
import { useMessage } from '@/hooks/useMessage'
import { forwardRef, useState } from 'react'
import { CalculatorInput } from '@/components/common/input/CalcInput'
const TriangleDormer = forwardRef((props, refs) => {
const { getMessage } = useMessage()
@ -12,9 +11,6 @@ const TriangleDormer = forwardRef((props, refs) => {
setDirection(e.target.value)
refs.directionRef.current = e.target.value
}
const [height, setHeight] = useState(1500)
const [offset, setOffset] = useState(400)
const [pitch, setPitch] = useState(4)
return (
<>
@ -34,20 +30,7 @@ const [pitch, setPitch] = useState(4)
<div className="eaves-keraba-td">
<div className="outline-form">
<div className="input-grid mr5" style={{ width: '60px' }}>
{/*<input type="text" className="input-origin block" placeholder={0} ref={refs.heightRef} defaultValue={1500} />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
value={height}
ref={refs.heightRef}
onChange={(value) => setHeight(value)}
options={{
allowNegative: false,
allowDecimal: false
}}
/>
<input type="text" className="input-origin block" placeholder={0} ref={refs.heightRef} defaultValue={1500} />
</div>
<span className="thin">mm</span>
</div>
@ -58,20 +41,7 @@ const [pitch, setPitch] = useState(4)
<div className="eaves-keraba-td">
<div className="outline-form">
<div className="input-grid mr5" style={{ width: '60px' }}>
{/*<input type="text" className="input-origin block" placeholder={0} ref={refs.offsetRef} defaultValue={400} />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
value={offset}
ref={refs.offsetRef}
onChange={(value) => setOffset(value)}
options={{
allowNegative: false,
allowDecimal: false
}}
/>
<input type="text" className="input-origin block" placeholder={0} ref={refs.offsetRef} defaultValue={400} />
</div>
<span className="thin">mm</span>
</div>
@ -82,20 +52,7 @@ const [pitch, setPitch] = useState(4)
<div className="eaves-keraba-td">
<div className="outline-form">
<div className="input-grid mr5" style={{ width: '60px' }}>
{/*<input type="text" className="input-origin block" placeholder={0} ref={refs.pitchRef} defaultValue={4} />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
ref={refs.pitchRef}
value={pitch}
onChange={(value) => setPitch(value)}
options={{
allowNegative: false,
allowDecimal: true
}}
/>
<input type="text" className="input-origin block" placeholder={0} ref={refs.pitchRef} defaultValue={4} />
</div>
<span className="thin"></span>
</div>

View File

@ -13,7 +13,6 @@ import { useCommonCode } from '@/hooks/common/useCommonCode'
import { globalLocaleStore } from '@/store/localeAtom'
import { currentAngleTypeSelector, pitchTextSelector } from '@/store/canvasAtom'
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function ContextRoofAllocationSetting(props) {
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
@ -205,29 +204,15 @@ export default function ContextRoofAllocationSetting(props) {
<div className="flex-ment">
<span>{getMessage('modal.object.setting.offset.slope')}</span>
<div className="input-grid">
{/*<input*/}
{/* type="text"*/}
{/* className="input-origin block"*/}
{/* onChange={(e) => {*/}
{/* e.target.value = normalizeDecimalLimit(e.target.value, 2)*/}
{/* handleChangePitch(e, index)*/}
{/* }}*/}
{/* value={currentAngleType === 'slope' ? (roof.pitch ?? '') : (roof.angle ?? '')}*/}
{/*/>*/}
<CalculatorInput
id=""
name=""
label=""
<input
type="text"
className="input-origin block"
onChange={(e) => {
e.target.value = normalizeDecimalLimit(e.target.value, 2)
handleChangePitch(e, index)
}}
value={currentAngleType === 'slope' ? (roof.pitch ?? '') : (roof.angle ?? '')}
onChange={(value) => {
handleChangePitch(value, index)
}}
options={{
allowNegative: false,
allowDecimal: true //(index !== 0),
}}
></CalculatorInput>
/>
</div>
<span className="absol">{pitchText}</span>
</div>

View File

@ -14,7 +14,6 @@ import { useRoofShapeSetting } from '@/hooks/roofcover/useRoofShapeSetting'
import { currentAngleTypeSelector, pitchTextSelector } from '@/store/canvasAtom'
import { getDegreeByChon } from '@/util/canvas-util'
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function RoofAllocationSetting(props) {
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
@ -206,29 +205,15 @@ export default function RoofAllocationSetting(props) {
<div className="flex-ment">
<span>{getMessage('modal.object.setting.offset.slope')}</span>
<div className="input-grid">
{/*<input*/}
{/* type="text"*/}
{/* className="input-origin block"*/}
{/* onChange={(e) => {*/}
{/* e.target.value = normalizeDecimalLimit(e.target.value, 2)*/}
{/* handleChangePitch(e, index)*/}
{/* }}*/}
{/* value={currentAngleType === 'slope' ? (roof.pitch ?? '') : (roof.angle ?? '')}*/}
{/*/>*/}
<CalculatorInput
id=""
name=""
label=""
<input
type="text"
className="input-origin block"
onChange={(e) => {
e.target.value = normalizeDecimalLimit(e.target.value, 2)
handleChangePitch(e, index)
}}
value={currentAngleType === 'slope' ? (roof.pitch ?? '') : (roof.angle ?? '')}
onChange={(value) => {
handleChangePitch(value, index)
}}
options={{
allowNegative: false,
allowDecimal: true //(index !== 0),
}}
></CalculatorInput>
/>
</div>
<span className="absol">{pitchText}</span>
</div>

View File

@ -3,7 +3,6 @@ import { useRecoilValue } from 'recoil'
import { ANGLE_TYPE, currentAngleTypeSelector } from '@/store/canvasAtom'
import { selectedRoofMaterialSelector } from '@/store/settingAtom'
import { useEffect } from 'react'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function Eaves({ offsetRef, pitchRef, pitchText }) {
const { getMessage } = useMessage()
@ -17,24 +16,12 @@ export default function Eaves({ offsetRef, pitchRef, pitchText }) {
{getMessage('slope')}
</span>
<div className="input-grid mr5">
{/*<input*/}
{/* type="text"*/}
{/* className="input-origin block"*/}
{/* defaultValue={currentAngleType === ANGLE_TYPE.SLOPE ? selectedRoofMaterial.pitch : selectedRoofMaterial.angle}*/}
{/* ref={pitchRef}*/}
{/*/>*/}
<CalculatorInput
id=""
name=""
label=""
<input
type="text"
className="input-origin block"
defaultValue={currentAngleType === ANGLE_TYPE.SLOPE ? selectedRoofMaterial.pitch : selectedRoofMaterial.angle}
ref={pitchRef}
value={currentAngleType === ANGLE_TYPE.SLOPE ? selectedRoofMaterial.pitch : selectedRoofMaterial.angle}
options={{
allowNegative: false,
allowDecimal: true //(index !== 0),
}}
></CalculatorInput>
/>
</div>
<span className="thin">{pitchText}</span>
</div>

View File

@ -1,6 +1,5 @@
import { useMessage } from '@/hooks/useMessage'
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function Direction({ pitch, setPitch, eavesOffset, setEavesOffset, gableOffset, setGableOffset, shedWidth, setShedWidth, pitchText }) {
const { getMessage } = useMessage()
@ -11,24 +10,12 @@ export default function Direction({ pitch, setPitch, eavesOffset, setEavesOffset
{getMessage('slope')}
</span>
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input*/}
{/* type="text"*/}
{/* className="input-origin block"*/}
{/* value={pitch}*/}
{/* onChange={(e) => setPitch(normalizeDecimalLimit(e.target.value, 2))}*/}
{/*/>*/}
<CalculatorInput
id=""
name=""
label=""
<input
type="text"
className="input-origin block"
value={pitch}
onChange={(value) => setPitch(value)}
options={{
allowNegative: false,
allowDecimal: true //(index !== 0),
}}
></CalculatorInput>
onChange={(e) => setPitch(normalizeDecimalLimit(e.target.value, 2))}
/>
</div>
<span className="thin">{pitchText}</span>
</div>
@ -37,24 +24,12 @@ export default function Direction({ pitch, setPitch, eavesOffset, setEavesOffset
{getMessage('eaves.offset')}
</span>
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input*/}
{/* type="text"*/}
{/* className="input-origin block"*/}
{/* value={eavesOffset}*/}
{/* onChange={(e) => setEavesOffset(normalizeDigits(e.target.value))}*/}
{/*/>*/}
<CalculatorInput
id=""
name=""
label=""
<input
type="text"
className="input-origin block"
value={eavesOffset}
onChange={(value) => setEavesOffset(value)}
options={{
allowNegative: false,
allowDecimal: false //(index !== 0),
}}
></CalculatorInput>
onChange={(e) => setEavesOffset(normalizeDigits(e.target.value))}
/>
</div>
<span className="thin">mm</span>
</div>
@ -63,24 +38,12 @@ export default function Direction({ pitch, setPitch, eavesOffset, setEavesOffset
{getMessage('gable.offset')}
</span>
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input*/}
{/* type="text"*/}
{/* className="input-origin block"*/}
{/* value={gableOffset}*/}
{/* onChange={(e) => setGableOffset(normalizeDigits(e.target.value))}*/}
{/*/>*/}
<CalculatorInput
id=""
name=""
label=""
<input
type="text"
className="input-origin block"
value={gableOffset}
onChange={(value) => setGableOffset(value)}
options={{
allowNegative: false,
allowDecimal: false //(index !== 0),
}}
></CalculatorInput>
onChange={(e) => setGableOffset(normalizeDigits(e.target.value))}
/>
</div>
<span className="thin">mm</span>
</div>
@ -89,24 +52,12 @@ export default function Direction({ pitch, setPitch, eavesOffset, setEavesOffset
{getMessage('windage.width')}
</span>
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input*/}
{/* type="text"*/}
{/* className="input-origin block"*/}
{/* value={shedWidth}*/}
{/* onChange={(e) => setShedWidth(normalizeDigits(e.target.value))}*/}
{/*/>*/}
<CalculatorInput
id=""
name=""
label=""
<input
type="text"
className="input-origin block"
value={shedWidth}
onChange={(value) => setShedWidth(value)}
options={{
allowNegative: false,
allowDecimal: false //(index !== 0),
}}
></CalculatorInput>
onChange={(e) => setShedWidth(normalizeDigits(e.target.value))}
/>
</div>
<span className="thin">mm</span>
</div>

View File

@ -1,6 +1,5 @@
import { useMessage } from '@/hooks/useMessage'
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function Pattern(props) {
const { getMessage } = useMessage()
@ -12,20 +11,7 @@ export default function Pattern(props) {
{getMessage('slope')}
</span>
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input type="text" className="input-origin block" value={pitch} */}
{/* onChange={(e) => setPitch(normalizeDecimalLimit(e.target.value, 2))} />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
value={pitch}
onChange={(value) => setPitch(value)}
options={{
allowNegative: false,
allowDecimal: true //(index !== 0),
}}
></CalculatorInput>
<input type="text" className="input-origin block" value={pitch} onChange={(e) => setPitch(normalizeDecimalLimit(e.target.value, 2))} />
</div>
<span className="thin"> {pitchText}</span>
</div>
@ -34,20 +20,7 @@ export default function Pattern(props) {
{getMessage('eaves.offset')}
</span>
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input type="text" className="input-origin block" value={eavesOffset} */}
{/* onChange={(e) => setEavesOffset(normalizeDigits(e.target.value))} />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
value={eavesOffset}
onChange={(value) => setEavesOffset(value)}
options={{
allowNegative: false,
allowDecimal: false //(index !== 0),
}}
></CalculatorInput>
<input type="text" className="input-origin block" value={eavesOffset} onChange={(e) => setEavesOffset(normalizeDigits(e.target.value))} />
</div>
<span className="thin">mm</span>
</div>
@ -56,20 +29,7 @@ export default function Pattern(props) {
{getMessage('gable.offset')}
</span>
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input type="text" className="input-origin block" value={gableOffset} */}
{/* onChange={(e) => setGableOffset(normalizeDigits(e.target.value))} />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
value={gableOffset}
onChange={(value) => setGableOffset(value)}
options={{
allowNegative: false,
allowDecimal: false //(index !== 0),
}}
></CalculatorInput>
<input type="text" className="input-origin block" value={gableOffset} onChange={(e) => setGableOffset(normalizeDigits(e.target.value))} />
</div>
<span className="thin">mm</span>
</div>

View File

@ -1,7 +1,6 @@
import { useMessage } from '@/hooks/useMessage'
import { useEffect } from 'react'
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function Ridge(props) {
const { getMessage } = useMessage()
@ -14,20 +13,7 @@ export default function Ridge(props) {
{getMessage('slope')}
</span>
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input type="text" className="input-origin block" value={pitch} */}
{/* onChange={(e) => setPitch(normalizeDecimalLimit(e.target.value, 2))} />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
value={pitch}
onChange={(value) => setPitch(value)}
options={{
allowNegative: false,
allowDecimal: true //(index !== 0),
}}
></CalculatorInput>
<input type="text" className="input-origin block" value={pitch} onChange={(e) => setPitch(normalizeDecimalLimit(e.target.value, 2))} />
</div>
<span className="thin">{pitchText}</span>
</div>
@ -36,20 +22,7 @@ export default function Ridge(props) {
{getMessage('eaves.offset')}
</span>
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input type="text" className="input-origin block" value={eavesOffset} */}
{/* onChange={(e) => setEavesOffset(normalizeDigits(e.target.value))} />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
value={eavesOffset}
onChange={(value) => setEavesOffset(value)}
options={{
allowNegative: false,
allowDecimal: false //(index !== 0),
}}
></CalculatorInput>
<input type="text" className="input-origin block" value={eavesOffset} onChange={(e) => setEavesOffset(normalizeDigits(e.target.value))} />
</div>
<span className="thin">mm</span>
</div>

View File

@ -1,6 +1,5 @@
import { useMessage } from '@/hooks/useMessage'
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function Eaves({ pitch, setPitch, eavesOffset, setEavesOffset, pitchText }) {
const { getMessage } = useMessage()
@ -11,21 +10,7 @@ export default function Eaves({ pitch, setPitch, eavesOffset, setEavesOffset, pi
{getMessage('slope')}
</span>
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input type="text" className="input-origin block" value={pitch} */}
{/* onChange={(e) => setPitch(normalizeDecimalLimit(e.target.value, 2))} />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
value={pitch}
onChange={(value) => setPitch(value)}
options={{
allowNegative: false,
allowDecimal: true //(index !== 0),
}}
></CalculatorInput>
<input type="text" className="input-origin block" value={pitch} onChange={(e) => setPitch(normalizeDecimalLimit(e.target.value, 2))} />
</div>
<span className="thin">{pitchText}</span>
</div>
@ -34,20 +19,7 @@ export default function Eaves({ pitch, setPitch, eavesOffset, setEavesOffset, pi
{getMessage('eaves.offset')}
</span>
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input type="text" className="input-origin block" value={eavesOffset} */}
{/* onChange={(e) => setEavesOffset(normalizeDigits(e.target.value))} />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
value={eavesOffset}
onChange={(value) => setEavesOffset(value)}
options={{
allowNegative: false,
allowDecimal: false //(index !== 0),
}}
></CalculatorInput>
<input type="text" className="input-origin block" value={eavesOffset} onChange={(e) => setEavesOffset(normalizeDigits(e.target.value))} />
</div>
<span className="thin">mm</span>
</div>

View File

@ -1,7 +1,6 @@
import { useMessage } from '@/hooks/useMessage'
import { useEffect } from 'react'
import { normalizeDigits } from '@/util/input-utils'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function Gable({ gableOffset, setGableOffset }) {
const { getMessage } = useMessage()
@ -11,20 +10,7 @@ export default function Gable({ gableOffset, setGableOffset }) {
<div className="outline-form">
<span className="mr10">{getMessage('gable.offset')}</span>
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input type="text" className="input-origin block" value={gableOffset}*/}
{/* onChange={(e) => setGableOffset(normalizeDigits(e.target.value))} />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
value={gableOffset}
onChange={(value) => setGableOffset(value)}
options={{
allowNegative: false,
allowDecimal: false //(index !== 0),
}}
></CalculatorInput>
<input type="text" className="input-origin block" value={gableOffset} onChange={(e) => setGableOffset(normalizeDigits(e.target.value))} />
</div>
<span className="thin">mm</span>
</div>

View File

@ -1,6 +1,5 @@
import { useMessage } from '@/hooks/useMessage'
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function HipAndGable({ pitch, setPitch, eavesOffset, setEavesOffset, hipAndGableWidth, setHipAndGableWidth, pitchText }) {
const { getMessage } = useMessage()
@ -11,20 +10,7 @@ export default function HipAndGable({ pitch, setPitch, eavesOffset, setEavesOffs
{getMessage('slope')}
</span>
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input type="text" className="input-origin block" value={pitch}*/}
{/* onChange={(e) => setPitch(normalizeDecimalLimit(e.target.value, 2))} />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
value={pitch}
onChange={(value) => setPitch(value)}
options={{
allowNegative: false,
allowDecimal: true //(index !== 0),
}}
></CalculatorInput>
<input type="text" className="input-origin block" value={pitch} onChange={(e) => setPitch(normalizeDecimalLimit(e.target.value, 2))} />
</div>
<span className="thin">{pitchText}</span>
</div>
@ -33,21 +19,7 @@ export default function HipAndGable({ pitch, setPitch, eavesOffset, setEavesOffs
{getMessage('eaves.offset')}
</span>
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input type="text" className="input-origin block" value={eavesOffset}*/}
{/* onChange={(e) => setEavesOffset(normalizeDigits(e.target.value))} />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
value={eavesOffset}
onChange={(value) => setEavesOffset(value)}
options={{
allowNegative: false,
allowDecimal: false //(index !== 0),
}}
></CalculatorInput>
<input type="text" className="input-origin block" value={eavesOffset} onChange={(e) => setEavesOffset(normalizeDigits(e.target.value))} />
</div>
<span className="thin">mm</span>
</div>
@ -56,24 +28,12 @@ export default function HipAndGable({ pitch, setPitch, eavesOffset, setEavesOffs
{getMessage('hipandgable.width')}
</span>
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input*/}
{/* type="text"*/}
{/* className="input-origin block"*/}
{/* value={hipAndGableWidth}*/}
{/* onChange={(e) => setHipAndGableWidth(normalizeDigits(e.target.value))}*/}
{/*/>*/}
<CalculatorInput
id=""
name=""
label=""
<input
type="text"
className="input-origin block"
value={hipAndGableWidth}
onChange={(value) => setHipAndGableWidth(value)}
options={{
allowNegative: false,
allowDecimal: false //(index !== 0),
}}
></CalculatorInput>
onChange={(e) => setHipAndGableWidth(normalizeDigits(e.target.value))}
/>
</div>
<span className="thin">mm</span>
</div>

View File

@ -1,6 +1,5 @@
import { useMessage } from '@/hooks/useMessage'
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function Jerkinhead({
gableOffset,
@ -19,20 +18,7 @@ export default function Jerkinhead({
{getMessage('gable.offset')}
</span>
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input type="text" className="input-origin block" value={gableOffset}*/}
{/* onChange={(e) => setGableOffset(normalizeDigits(e.target.value))} />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
value={gableOffset}
onChange={(value) => setGableOffset(value)}
options={{
allowNegative: false,
allowDecimal: false //(index !== 0),
}}
></CalculatorInput>
<input type="text" className="input-origin block" value={gableOffset} onChange={(e) => setGableOffset(normalizeDigits(e.target.value))} />
</div>
<span className="thin">mm</span>
</div>
@ -41,21 +27,7 @@ export default function Jerkinhead({
{getMessage('jerkinhead.width')}
</span>
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input type="text" className="input-origin block" value={jerkinHeadWidth}*/}
{/* onChange={(e) => setJerkinHeadWidth(normalizeDigits(e.target.value))} />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
value={jerkinHeadWidth}
onChange={(value) => setJerkinHeadWidth(value)}
options={{
allowNegative: false,
allowDecimal: false //(index !== 0),
}}
></CalculatorInput>
<input type="text" className="input-origin block" value={jerkinHeadWidth} onChange={(e) => setJerkinHeadWidth(normalizeDigits(e.target.value))} />
</div>
<span className="thin">mm</span>
</div>
@ -64,24 +36,12 @@ export default function Jerkinhead({
{getMessage('jerkinhead.slope')}
</span>
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input*/}
{/* type="text"*/}
{/* className="input-origin block"*/}
{/* value={jerkinHeadPitch}*/}
{/* onChange={(e) => setJerkinHeadPitch(normalizeDecimalLimit(e.target.value, 2))}*/}
{/*/>*/}
<CalculatorInput
id=""
name=""
label=""
<input
type="text"
className="input-origin block"
value={jerkinHeadPitch}
onChange={(value) => setJerkinHeadPitch(value)}
options={{
allowNegative: false,
allowDecimal: true //(index !== 0),
}}
></CalculatorInput>
onChange={(e) => setJerkinHeadPitch(normalizeDecimalLimit(e.target.value, 2))}
/>
</div>
<span className="thin">{pitchText}</span>
</div>

View File

@ -1,6 +1,5 @@
import { useMessage } from '@/hooks/useMessage'
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function Shed({ shedWidth, setShedWidth, shedPitch, setShedPitch, pitchText }) {
const { getMessage } = useMessage()
@ -9,40 +8,14 @@ export default function Shed({ shedWidth, setShedWidth, shedPitch, setShedPitch,
<div className="outline-form mb10">
<span className="mr10">{getMessage('slope')}</span>
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input type="text" className="input-origin block" value={shedPitch}*/}
{/* onChange={(e) => setShedPitch(normalizeDecimalLimit(e.target.value, 2))} />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
value={shedPitch}
onChange={(value) => setShedPitch(value)}
options={{
allowNegative: false,
allowDecimal: true //(index !== 0),
}}
></CalculatorInput>
<input type="text" className="input-origin block" value={shedPitch} onChange={(e) => setShedPitch(normalizeDecimalLimit(e.target.value, 2))} />
</div>
<span className="thin">{pitchText}</span>
</div>
<div className="outline-form">
<span className="mr10">{getMessage('shed.width')}</span>
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input type="text" className="input-origin block" value={shedWidth}*/}
{/* onChange={(e) => setShedWidth(normalizeDigits(e.target.value))} />*/}
<CalculatorInput
id=""
name=""
label=""
className="input-origin block"
value={shedWidth}
onChange={(value) => setShedWidth(value)}
options={{
allowNegative: false,
allowDecimal: false //(index !== 0),
}}
></CalculatorInput>
<input type="text" className="input-origin block" value={shedWidth} onChange={(e) => setShedWidth(normalizeDigits(e.target.value))} />
</div>
<span className="thin">mm</span>
</div>

View File

@ -1,7 +1,6 @@
import { useState } from 'react'
import { useMessage } from '@/hooks/useMessage'
import { normalizeDigits } from '@/util/input-utils'
import { CalculatorInput } from '@/components/common/input/CalcInput'
export default function Wall({ sleeveOffset, setSleeveOffset, hasSleeve, setHasSleeve }) {
const { getMessage } = useMessage()
@ -11,8 +10,7 @@ export default function Wall({ sleeveOffset, setSleeveOffset, hasSleeve, setHasS
<div className="eaves-keraba-item">
<div className="eaves-keraba-th">
<div className="d-check-radio pop">
<input type="radio" name="radio01" checked={hasSleeve === '0'} id="ra01" value={'0'}
onChange={(e) => setHasSleeve(e.target.value)} />
<input type="radio" name="radio01" checked={hasSleeve === '0'} id="ra01" value={'0'} onChange={(e) => setHasSleeve(e.target.value)} />
<label htmlFor="ra01">{getMessage('has.not.sleeve')}</label>
</div>
</div>
@ -20,34 +18,20 @@ export default function Wall({ sleeveOffset, setSleeveOffset, hasSleeve, setHasS
<div className="eaves-keraba-item">
<div className="eaves-keraba-th">
<div className="d-check-radio pop">
<input type="radio" name="radio01" checked={hasSleeve !== '0'} id="ra02" value={'1'}
onChange={(e) => setHasSleeve(e.target.value)} />
<input type="radio" name="radio01" checked={hasSleeve !== '0'} id="ra02" value={'1'} onChange={(e) => setHasSleeve(e.target.value)} />
<label htmlFor="ra02">{getMessage('has.sleeve')}</label>
</div>
</div>
<div className="eaves-keraba-td">
<div className="outline-form">
<div className="input-grid mr5" style={{ width: '100px' }}>
{/*<input*/}
{/* type="text"*/}
{/* className="input-origin block"*/}
{/* value={sleeveOffset}*/}
{/* onChange={(e) => setSleeveOffset(normalizeDigits(e.target.value))}*/}
{/* readOnly={hasSleeve === '0'}*/}
{/*/>*/}
<CalculatorInput
id=""
name=""
label=""
<input
type="text"
className="input-origin block"
value={sleeveOffset}
onChange={(value) => setSleeveOffset(value)}
onChange={(e) => setSleeveOffset(normalizeDigits(e.target.value))}
readOnly={hasSleeve === '0'}
options={{
allowNegative: false,
allowDecimal: false //(index !== 0),
}}
></CalculatorInput>
/>
</div>
<span className="thin">mm</span>
</div>

View File

@ -1,10 +1,8 @@
import React, { useEffect } from 'react'
import React, { useEffect, useState } from 'react'
import { useMessage } from '@/hooks/useMessage'
import { POLYGON_TYPE } from '@/common/common'
import { useEvent } from '@/hooks/useEvent'
import { useRoofFn } from '@/hooks/common/useRoofFn'
import { outlineDisplaySelector } from '@/store/settingAtom'
import { useRecoilValue } from 'recoil'
export default function FirstOption(props) {
const { getMessage } = useMessage()
@ -13,7 +11,6 @@ export default function FirstOption(props) {
const { option1, option2, dimensionDisplay } = settingModalFirstOptions
const { initEvent } = useEvent()
const { setSurfaceShapePattern } = useRoofFn()
const outlineDisplay = useRecoilValue(outlineDisplaySelector)
//
useEffect(() => {
@ -21,13 +18,6 @@ export default function FirstOption(props) {
setSettingsDataSave({ ...settingsData })
}, [])
useEffect(() => {
const outline = canvas.getObjects().filter((obj) => obj.name === 'originRoofOuterLine')
outline.forEach((obj) => {
obj.visible = outlineDisplay
})
}, [outlineDisplay])
const onClickOption = async (item) => {
let dimensionDisplay = settingModalFirstOptions?.dimensionDisplay
let option1 = settingModalFirstOptions?.option1
@ -68,12 +58,7 @@ export default function FirstOption(props) {
// setSettingModalFirstOptions({ ...settingModalFirstOptions, option1: [...options] })
}
setSettingsData({
...settingsData,
option1: [...option1],
option2: [...option2],
dimensionDisplay: [...dimensionDisplay],
})
setSettingsData({ ...settingsData, option1: [...option1], option2: [...option2], dimensionDisplay: [...dimensionDisplay] })
}
// useEffect(() => {

View File

@ -31,11 +31,8 @@ export function useCommonUtils() {
useEffect(() => {
commonTextMode()
if (commonUtils.dimension) {
generateTempGrid()
commonDimensionMode()
return
} else {
removeTempGrid()
}
if (commonUtils.distance) {
commonDistanceMode()
@ -648,7 +645,6 @@ export function useCommonUtils() {
lockMovementY: true,
name: obj.name,
editable: false,
selectable: true, // 복사된 객체 선택 가능하도록 설정
id: uuidv4(), //복사된 객체라 새로 따준다
})
@ -657,25 +653,19 @@ export function useCommonUtils() {
//배치면일 경우
if (obj.name === 'roof') {
clonedObj.canvas = canvas // canvas 참조 설정
clonedObj.setCoords()
clonedObj.fire('modified')
clonedObj.fire('polygonMoved')
clonedObj.set({
direction: obj.direction,
directionText: obj.directionText,
roofMaterial: obj.roofMaterial,
stroke: 'black', // 복사된 객체는 선택 해제 상태의 색상으로 설정
selectable: true, // 선택 가능하도록 설정
evented: true, // 마우스 이벤트를 받을 수 있도록 설정
isFixed: false, // containsPoint에서 특별 처리 방지
})
obj.lines.forEach((line, index) => {
clonedObj.lines[index].set({ attributes: line.attributes })
})
clonedObj.fire('polygonMoved') // 내부 좌표 재계산 (points, pathOffset)
clonedObj.fire('modified')
clonedObj.setCoords() // 모든 속성 설정 후 좌표 업데이트
canvas.setActiveObject(clonedObj)
canvas.renderAll()
addLengthText(clonedObj) //수치 추가
drawDirectionArrow(clonedObj) //방향 화살표 추가
@ -915,45 +905,6 @@ export function useCommonUtils() {
}
}
const generateTempGrid = () => {
if (!canvas) return
const objects = canvas.getObjects().filter((obj) => ['QPolygon'].includes(obj.type))
const gridLines = []
objects.forEach((obj) => {
const lines = obj.lines
lines.forEach((line) => {
const gridLine = new fabric.Line([line.x1, line.y1, line.x2, line.y2], {
stroke: 'gray',
strokeWidth: 1,
selectable: false,
evented: false,
opacity: 0.5,
name: 'tempGrid',
direction: line.x1 === line.x2 ? 'vertical' : 'horizontal',
visible: false,
})
gridLines.push(gridLine)
})
})
gridLines.forEach((line) => {
canvas.add(line)
})
canvas.renderAll()
}
const removeTempGrid = () => {
if (!canvas) return
const tempGrids = canvas.getObjects().filter((obj) => obj.name === 'tempGrid' && !obj.visible)
tempGrids.forEach((grid) => canvas.remove(grid))
canvas.renderAll()
}
return {
commonFunctions,
dimensionSettings,
@ -965,7 +916,5 @@ export function useCommonUtils() {
editText,
changeDimensionExtendLine,
deleteOuterLineObject,
generateTempGrid,
removeTempGrid,
}
}

View File

@ -9,7 +9,6 @@ import {
basicSettingState,
correntObjectNoState,
corridorDimensionSelector,
outlineDisplaySelector,
roofDisplaySelector,
roofMaterialsSelector,
selectedRoofMaterialSelector,
@ -62,11 +61,9 @@ export function useRoofAllocationSetting(id) {
const { saveCanvas } = usePlan()
const [roofsStore, setRoofsStore] = useRecoilState(roofsState)
const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState)
const outerLinePoints = useRecoilValue(outerLinePointsState)
const resetPoints = useResetRecoilState(outerLinePointsState)
const [corridorDimension, setCorridorDimension] = useRecoilState(corridorDimensionSelector)
const { changeCorridorDimensionText } = useText()
const outlineDisplay = useRecoilValue(outlineDisplaySelector)
useEffect(() => {
/** 배치면 초기설정에서 선택한 지붕재 배열 설정 */
@ -308,53 +305,11 @@ export function useRoofAllocationSetting(id) {
addPopup(popupId, 1, <ActualSizeSetting id={popupId} />)
} else {
apply()
//기존 지붕 선은 남겨둔다.
drawOriginRoofLine()
resetPoints()
basicSettingSave()
}
}
const drawOriginRoofLine = () => {
// outerLinePoints 배열을 이용하여 빨간색 Line 객체들 생성
if (outerLinePoints && outerLinePoints.length > 1) {
// 연속된 점들을 연결하여 라인 생성
for (let i = 0; i < outerLinePoints.length - 1; i++) {
const point1 = outerLinePoints[i]
const point2 = outerLinePoints[i + 1]
const line = new fabric.Line([point1.x, point1.y, point2.x, point2.y], {
stroke: 'black',
strokeDashArray: [5, 2],
strokeWidth: 1,
selectable: false,
name: 'originRoofOuterLine',
visible: outlineDisplay,
})
canvas.add(line)
}
// 마지막 점과 첫 점을 연결하여 폐곡선 만들기
if (outerLinePoints.length > 2) {
const lastPoint = outerLinePoints[outerLinePoints.length - 1]
const firstPoint = outerLinePoints[0]
const closingLine = new fabric.Line([lastPoint.x, lastPoint.y, firstPoint.x, firstPoint.y], {
stroke: 'red',
strokeWidth: 2,
selectable: false,
name: 'originRoofOuterLine',
})
canvas.add(closingLine)
}
canvas.renderAll()
}
}
/**
* 지붕재 오른쪽 마우스 클릭 단일로 지붕재 변경 필요한 경우
*/
@ -632,7 +587,7 @@ export function useRoofAllocationSetting(id) {
* 피치 변경
*/
const handleChangePitch = (e, index) => {
let value = e //e.target.value
let value = e.target.value
const reg = /^[0-9]+(\.[0-9]{0,1})?$/
if (!reg.test(value)) {

View File

@ -402,8 +402,7 @@ export function useCanvasEvent() {
}
} else {
zoom = canvasZoom - 10
if (zoom < 10) {
//50%->10%
if (zoom < 10) { //50%->10%
return
}
}
@ -413,33 +412,8 @@ export function useCanvasEvent() {
const handleZoomClear = () => {
setCanvasZoom(100)
zoomToAllObjects()
canvas.renderAll()
}
const zoomToAllObjects = () => {
const objects = canvas.getObjects().filter((obj) => obj.visible)
if (objects.length === 0) return
let minX = Infinity,
minY = Infinity
let maxX = -Infinity,
maxY = -Infinity
objects.forEach((obj) => {
const bounds = obj.getBoundingRect()
minX = Math.min(minX, bounds.left)
minY = Math.min(minY, bounds.top)
maxX = Math.max(maxX, bounds.left + bounds.width)
maxY = Math.max(maxY, bounds.top + bounds.height)
})
const centerX = (minX + maxX) / 2
const centerY = (minY + maxY) / 2
const centerPoint = new fabric.Point(centerX, centerY)
canvas.zoomToPoint(centerPoint, 1)
canvas.set({ zoom: 1 })
canvas.viewportTransform = [1, 0, 0, 1, 0, 0]
canvas.renderAll()
}

View File

@ -42,18 +42,7 @@ export function useCircuitTrestle(executeEffect = false) {
}
}
// PCS 아이템 목록
const getPcsItemList = (isMultiModule = false) => {
if (isMultiModule) {
return models
.filter((model) => model.pcsTpCd !== 'INDFCS')
.map((model) => {
return {
itemId: model.itemId,
pcsMkrCd: model.pcsMkrCd,
pcsSerCd: model.pcsSerCd,
}
})
}
const getPcsItemList = () => {
return models.map((model) => {
return {
itemId: model.itemId,
@ -64,18 +53,7 @@ export function useCircuitTrestle(executeEffect = false) {
}
// 선택된 PCS 아이템 목록
const getSelectedPcsItemList = (isMultiModule = false) => {
if (isMultiModule) {
return selectedModels
.filter((model) => model.pcsTpCd !== 'INDFCS')
.map((model) => {
return {
itemId: model.itemId,
pcsMkrCd: model.pcsMkrCd,
pcsSerCd: model.pcsSerCd,
}
})
}
const getSelectedPcsItemList = () => {
return selectedModels.map((model) => {
return {
itemId: model.itemId,
@ -117,7 +95,6 @@ export function useCircuitTrestle(executeEffect = false) {
uniqueId: module.id ? module.id : null,
}
}),
roofSurfaceNorthYn: obj.direction === 'north' ? 'Y' : 'N',
}
})
.filter((surface) => surface.moduleList.length > 0)

View File

@ -1809,7 +1809,6 @@ export function useMode() {
const currentWall = line.currentWall
const nextWall = line.nextWall
const index = line.index + addPoint
const direction = currentWall.direction
const xDiff = Big(currentWall.x1).minus(Big(nextWall.x1))
const yDiff = Big(currentWall.y1).minus(Big(nextWall.y1))
const offsetCurrentPoint = offsetPolygon[index]
@ -1821,10 +1820,12 @@ export function useMode() {
x: xDiff.eq(0) ? offsetCurrentPoint.x : nextWall.x1,
y: yDiff.eq(0) ? offsetCurrentPoint.y : nextWall.y1,
}
let diffOffset = ['top', 'right'].includes(direction)
? Big(nextWall.attributes.offset).minus(Big(currentWall.attributes.offset))
: Big(currentWall.attributes.offset).minus(Big(nextWall.attributes.offset))
let diffOffset
if (nextWall.index > currentWall.index) {
diffOffset = Big(nextWall.attributes.offset).minus(Big(currentWall.attributes.offset)).abs()
} else {
diffOffset = Big(currentWall.attributes.offset).minus(Big(nextWall.attributes.offset))
}
const offsetPoint2 = {
x: yDiff.eq(0) ? offsetPoint1.x : Big(offsetPoint1.x).plus(diffOffset).toNumber(),

View File

@ -1089,7 +1089,6 @@
"module.circuit.minimun.error": "回路番号は1以上の数値を入力してください。",
"module.already.exist.error": "回路番号が同じで異なるパワーコンディショナのモジュールがあります。 別の回路番号を設定してください。",
"module.circuit.fix.not.same.roof.error": "異なる屋根面のモジュールが選択されています。 モジュールの選択をや直してください。",
"module.circuit.indoor.focused.error": "混合モジュールと屋内集中PCSを組み合わせる場合は、手動回路割り当てのみ対応可能です。",
"construction.length.difference": "屋根面工法をすべて選択してください。",
"menu.validation.canvas.roof": "パネルを配置するには、屋根面を入力する必要があります。",
"batch.object.outside.roof": "オブジェクトは屋根に設置する必要があります。",

View File

@ -1089,7 +1089,6 @@
"module.circuit.minimun.error": "회로번호는 1 이상입력해주세요.",
"module.already.exist.error": "회로번호가 같은 다른 파워 컨디셔너 모듈이 있습니다. 다른 회로번호를 설정하십시오.",
"module.circuit.fix.not.same.roof.error": "다른 지붕면의 모듈이 선택되어 있습니다. 모듈 선택을 다시 하세요.",
"module.circuit.indoor.focused.error": "혼합 모듈과 실내 집중형 PCS를 조합하는 경우, 수동 회로 할당만 가능합니다.",
"construction.length.difference": "지붕면 공법을 모두 선택하십시오.",
"menu.validation.canvas.roof": "패널을 배치하려면 지붕면을 입력해야 합니다.",
"batch.object.outside.roof": "오브젝트는 지붕내에 설치해야 합니다.",

View File

@ -133,23 +133,8 @@ $alert-color: #101010;
color: $pop-color;
font-weight: 700;
}
.modal-btn-wrap{
margin-left: auto;
display: flex;
align-items: center;
gap: 15px;
}
.modal-fold{
display: block;
width: 15px;
height: 15px;
background: url(../../public/static/images/canvas/penal_arr_white.svg)no-repeat center;
background-size: contain;
&.act{
transform: rotate(180deg);
}
}
.modal-close{
margin-left: auto;
color: transparent;
font-size: 0;
width: 10px;

View File

@ -460,11 +460,7 @@ button{
}
}
.table-select{
height: 20px;
color: #fff !important;
font-size: 11px !important;
}
// input
.form-input{
label{

View File

@ -269,7 +269,7 @@ export const getDegreeByChon = (chon) => {
* @returns {number}
*/
export const getChonByDegree = (degree) => {
return Number((Math.tan((degree * Math.PI) / 180) * 10).toFixed(2))
return Number((Math.tan((degree * Math.PI) / 180) * 10).toFixed(1))
}
/**
@ -1036,11 +1036,11 @@ export const getDegreeInOrientation = (degree) => {
{ min: -51, max: -37, value: -45 },
{ min: -36, max: -22, value: -30 },
{ min: -21, max: -7, value: -15 },
{ min: -6, max: 0, value: 0 },
{ min: -6, max: 0, value: 0 }
]
// 해당 범위에 맞는 값 찾기
const range = degreeRanges.find((range) => degree >= range.min && degree <= range.max)
const range = degreeRanges.find(range => degree >= range.min && degree <= range.max)
return range ? range.value : degree
}

View File

@ -6,6 +6,7 @@ import { QPolygon } from '@/components/fabric/QPolygon'
import * as turf from '@turf/turf'
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
import Big from 'big.js'
import { canvas } from 'framer-motion/m'
const TWO_PI = Math.PI * 2

View File

@ -754,7 +754,6 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
const sortedCurrentRoofLines = sortCurrentRoofLines(alignedCurrentRoofLines);
const sortedRoofLines = sortCurrentRoofLines(roofLines);
const sortedWallBaseLines = sortCurrentRoofLines(wall.baseLines);
const sortedBaseLines = sortBaseLinesByWallLines(wall.baseLines, wallLines);
//wall.lines 는 기본 벽 라인
@ -773,8 +772,8 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
const roofLine = roofLines[index];
const currentRoofLine = currentRoofLines[index];
const moveLine = sortedBaseLines[index]
const wallBaseLine = sortedBaseLines[index]
const moveLine = wall.baseLines[index]
const wallBaseLine = wall.baseLines[index]
//roofline 외곽선 설정
@ -862,13 +861,14 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
//두 포인트가 변경된 라인인
if (fullyMoved ) {
//반시계방향향
console.log("moveFully:::::::::::::", wallBaseLine, newPStart, newPEnd)
console.log("moveFully:::::::::::::", roofLine.direction)
const mLine = getSelectLinePosition(wall, wallBaseLine)
if (getOrientation(roofLine) === 'vertical') {
if (['left', 'right'].includes(mLine.position)) {
if(Math.abs(wallLine.x1 - wallBaseLine.x1) < 0.1 || Math.abs(wallLine.x2 - wallBaseLine.x2) < 0.1) {
if(wallLine.x1 === wallBaseLine.x1) {
return false
}
const positionType =
@ -876,7 +876,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
(mLine.position === 'right' && wallLine.x1 > wallBaseLine.x1)
? 'in' : 'out';
const condition = `${mLine.position}_${positionType}`;
let isStartEnd = findInteriorPoint(wallBaseLine, sortedBaseLines)
let isStartEnd = findInteriorPoint(wallBaseLine, wall.baseLines)
let sPoint, ePoint;
if(condition === 'left_in') {
isIn = true
@ -1014,7 +1014,6 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
}
}
findPoints.push({ y: newPStart.y, x: newPEnd.x, position: 'left_out_end' });
}
}else if(condition === 'right_in') {
if (isStartEnd.start ) {
@ -1166,7 +1165,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
} else if (getOrientation(roofLine) === 'horizontal') { //red
if (['top', 'bottom'].includes(mLine.position)) {
if(Math.abs(wallLine.y1 - wallBaseLine.y1) < 0.1 || Math.abs(wallLine.y2 - wallBaseLine.y2) < 0.1) {
if(Math.abs(wallLine.y1 - wallBaseLine.y1) < 0.1) {
return false
}
const positionType =
@ -1175,7 +1174,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
? 'in' : 'out';
const condition = `${mLine.position}_${positionType}`;
let isStartEnd = findInteriorPoint(wallBaseLine, sortedBaseLines)
let isStartEnd = findInteriorPoint(wallBaseLine, wall.baseLines)
let sPoint, ePoint;
@ -1402,15 +1401,15 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
const eLineX = Big(bStartX).minus(wallLine.x2).abs().toNumber()
newPEnd.x = aStartX
newPStart.x = Big(roofLine.x1).plus(eLineX).toNumber()
let idx = (roofLines.length < index + 1)?0:index
const newLine = roofLines[idx + 1];
let idx = (0 > index - 1)?roofLines.length:index
const newLine = roofLines[idx-1];
if(Math.abs(wallBaseLine.x2 - wallLine.x2) < 0.1) {
if(inLine){
if(inLine.y2 < inLine.y1 ) {
getAddLine({ x: bStartX, y: wallLine.y1 }, { x: inLine.x2, y: inLine.y2 }, 'pink')
}else{
getAddLine({ x: inLine.x1, y: inLine.y1 }, { x: bStartX, y: wallLine.y1 }, 'pink')
getAddLine({ x: inLine.x2, y: inLine.y2 }, { x: bStartX, y: wallLine.y1 }, 'pink')
}
}
getAddLine({ x: bStartX, y: wallLine.y1 }, { x: roofLine.x2, y: wallLine.y2 }, 'magenta')
@ -3137,7 +3136,7 @@ function updateAndAddLine(innerLines, targetPoint) {
isUpdatingStart = true;
}
}else if(targetPoint.position === "top_out_end"){
if(foundLine.y2 >= foundLine.y1){
if(foundLine.y2 > foundLine.y1){
isUpdatingStart = true;
}
}else if(targetPoint.position === "bottom_out_start"){
@ -3319,81 +3318,3 @@ function findInteriorPoint(line, polygonLines) {
end: endIsValley
};
}
/**
* baseLines의 순서를 wallLines의 순서와 일치시킵니다.
* wallLine에 대해 가장 가깝고 평행한 baseLine을 찾아 정렬된 배열을 반환합니다.
*
* @param {Array} baseLines - 정렬할 원본 baseLine 배열
* @param {Array} wallLines - 기준이 되는 wallLine 배열
* @returns {Array} wallLines 순서에 맞춰 정렬된 baseLines
*/
export const sortBaseLinesByWallLines = (baseLines, wallLines) => {
if (!baseLines || !wallLines || baseLines.length === 0 || wallLines.length === 0) {
return baseLines;
}
const sortedBaseLines = [];
const usedIndices = new Set(); // 이미 매칭된 baseLine 인덱스를 추적
wallLines.forEach((wallLine) => {
let bestMatchIndex = -1;
let minDistance = Infinity;
// wallLine의 중점 계산
const wMidX = (wallLine.x1 + wallLine.x2) / 2;
const wMidY = (wallLine.y1 + wallLine.y2) / 2;
// wallLine의 방향 벡터 (평행 확인용)
const wDx = wallLine.x2 - wallLine.x1;
const wDy = wallLine.y2 - wallLine.y1;
const wLen = Math.hypot(wDx, wDy);
baseLines.forEach((baseLine, index) => {
// 이미 매칭된 라인은 건너뜀 (1:1 매칭)
if (usedIndices.has(index)) return;
// baseLine의 중점 계산
const bMidX = (baseLine.x1 + baseLine.x2) / 2;
const bMidY = (baseLine.y1 + baseLine.y2) / 2;
// 두 라인의 중점 사이 거리 계산
const dist = Math.hypot(wMidX - bMidX, wMidY - bMidY);
// 평행 여부 확인 (내적 사용)
const bDx = baseLine.x2 - baseLine.x1;
const bDy = baseLine.y2 - baseLine.y1;
const bLen = Math.hypot(bDx, bDy);
if (wLen > 0 && bLen > 0) {
// 단위 벡터 내적값 (-1 ~ 1)
const dot = (wDx * bDx + wDy * bDy) / (wLen * bLen);
// 내적의 절대값이 1에 가까우면 평행 (약 10도 오차 허용)
if (Math.abs(Math.abs(dot) - 1) < 0.1) {
if (dist < minDistance) {
minDistance = dist;
bestMatchIndex = index;
}
}
}
});
if (bestMatchIndex !== -1) {
sortedBaseLines.push(baseLines[bestMatchIndex]);
usedIndices.add(bestMatchIndex);
} else {
// 매칭되는 라인을 찾지 못한 경우, 아직 사용되지 않은 첫 번째 라인을 할당 (Fallback)
const unusedIndex = baseLines.findIndex((_, idx) => !usedIndices.has(idx));
if (unusedIndex !== -1) {
sortedBaseLines.push(baseLines[unusedIndex]);
usedIndices.add(unusedIndex);
} else {
// 더 이상 남은 라인이 없으면 null 또는 기존 라인 중 하나(에러 방지)
sortedBaseLines.push(baseLines[0]);
}
}
});
return sortedBaseLines;
};