Merge branch 'dev' of https://git.hanasys.jp/qcast3/qcast-front into feature/skeleton-dev
# Conflicts: # src/util/skeleton-utils.js
This commit is contained in:
commit
7de3cccc34
1
.gitignore
vendored
1
.gitignore
vendored
@ -43,3 +43,4 @@ yarn.lock
|
||||
package-lock.json
|
||||
pnpm-lock.yaml
|
||||
certificates
|
||||
.ai
|
||||
@ -219,7 +219,8 @@ export const SAVE_KEY = [
|
||||
'originWidth',
|
||||
'originHeight',
|
||||
'skeletonLines',
|
||||
'skeleton'
|
||||
'skeleton',
|
||||
'viewportTransform',
|
||||
]
|
||||
|
||||
export const OBJECT_PROTOTYPE = [fabric.Line.prototype, fabric.Polygon.prototype, fabric.Triangle.prototype, fabric.Group.prototype]
|
||||
|
||||
@ -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,16 +38,19 @@ export default function WithDraggable({ isShow, children, pos = { x: 0, y: 0 },
|
||||
)
|
||||
}
|
||||
|
||||
function WithDraggableHeader({ title, onClose, children }) {
|
||||
function WithDraggableHeader({ title, onClose, children, isFold, onFold = null }) {
|
||||
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>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -48,14 +48,23 @@ 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 {
|
||||
}else if (!shouldPreventInput(calculator.currentOperand)) { //소수점 이하2자리
|
||||
calculator.currentOperand = (calculator.currentOperand || '') + num
|
||||
}
|
||||
// else {
|
||||
// calculator.currentOperand = (calculator.currentOperand || '') + num
|
||||
// }
|
||||
newDisplayValue = calculator.previousOperand + calculator.operation + calculator.currentOperand
|
||||
setDisplayValue(newDisplayValue)
|
||||
} else {
|
||||
@ -68,7 +77,7 @@ export const CalculatorInput = forwardRef(
|
||||
if (!hasOperation) {
|
||||
onChange(calculator.currentOperand)
|
||||
}
|
||||
} else {
|
||||
} else if (!shouldPreventInput(calculator.currentOperand)) { //소수점 이하2자리
|
||||
calculator.currentOperand = (calculator.currentOperand || '') + num
|
||||
newDisplayValue = calculator.currentOperand
|
||||
setDisplayValue(newDisplayValue)
|
||||
@ -76,6 +85,14 @@ export const CalculatorInput = forwardRef(
|
||||
onChange(newDisplayValue)
|
||||
}
|
||||
}
|
||||
// else {
|
||||
// calculator.currentOperand = (calculator.currentOperand || '') + num
|
||||
// newDisplayValue = calculator.currentOperand
|
||||
// setDisplayValue(newDisplayValue)
|
||||
// if (!hasOperation) {
|
||||
// onChange(newDisplayValue)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
// 커서를 텍스트 끝으로 이동하고 스크롤 처리
|
||||
|
||||
@ -89,7 +89,7 @@ let fileCheck = false;
|
||||
siteTpCd: "QC",
|
||||
schNoticeClsCd: "QNA",
|
||||
regId: sessionState?.userId || '',
|
||||
storeId: sessionState?.userId || '',
|
||||
storeId: sessionState?.storeId || '',
|
||||
qstMail: sessionState?.email || '',
|
||||
qnaClsLrgCd: '',
|
||||
qnaClsMidCd: '',
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
import { useContext, useEffect, useRef } from 'react'
|
||||
|
||||
import { useRecoilValue, useResetRecoilState } from 'recoil'
|
||||
import { useRecoilState, 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 { currentMenuState } from '@/store/canvasAtom'
|
||||
import { canvasZoomState, currentMenuState } from '@/store/canvasAtom'
|
||||
import { totalDisplaySelector } from '@/store/settingAtom'
|
||||
import { POLYGON_TYPE } from '@/common/common'
|
||||
import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
|
||||
@ -50,6 +50,7 @@ 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()
|
||||
@ -67,6 +68,13 @@ 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')
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
import { useContext, useEffect, useState } from 'react'
|
||||
|
||||
import { usePathname, useRouter, useSearchParams } from 'next/navigation'
|
||||
import { usePathname, useRouter } from 'next/navigation'
|
||||
|
||||
import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil'
|
||||
|
||||
@ -25,17 +25,18 @@ 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, currentMenuState, verticalHorizontalModeState, currentCanvasPlanState } from '@/store/canvasAtom'
|
||||
import {
|
||||
canvasSettingState,
|
||||
canvasState,
|
||||
canvasZoomState,
|
||||
currentCanvasPlanState,
|
||||
currentMenuState,
|
||||
verticalHorizontalModeState,
|
||||
} from '@/store/canvasAtom'
|
||||
import { sessionStore } from '@/store/commonAtom'
|
||||
import { outerLinePointsState } from '@/store/outerLineAtom'
|
||||
import { appMessageStore, globalLocaleStore } from '@/store/localeAtom'
|
||||
import {
|
||||
addedRoofsState,
|
||||
basicSettingState,
|
||||
corridorDimensionSelector,
|
||||
selectedRoofMaterialSelector,
|
||||
settingModalFirstOptionsState,
|
||||
} from '@/store/settingAtom'
|
||||
import { addedRoofsState, basicSettingState, selectedRoofMaterialSelector, settingModalFirstOptionsState } from '@/store/settingAtom'
|
||||
import { placementShapeDrawingPointsState } from '@/store/placementShapeDrawingAtom'
|
||||
import { commonUtilsState } from '@/store/commonUtilsAtom'
|
||||
import { menusState } from '@/store/menuAtom'
|
||||
@ -51,6 +52,7 @@ 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
|
||||
@ -515,7 +517,10 @@ 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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ 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()
|
||||
@ -22,7 +23,19 @@ 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} />
|
||||
{/*<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>
|
||||
</div>
|
||||
<span className="thin">{pitchText}</span>
|
||||
</div>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { POLYGON_TYPE, MODULE_SETUP_TYPE } from '@/common/common'
|
||||
import { MODULE_SETUP_TYPE, POLYGON_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,6 +74,7 @@ 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 } =
|
||||
@ -282,8 +283,14 @@ 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')} onClose={() => handleClosePopup(id)} />
|
||||
<WithDraggable.Header
|
||||
title={getMessage('plan.menu.module.circuit.setting.default')}
|
||||
isFold={isFold}
|
||||
onClose={() => handleClosePopup(id)}
|
||||
onFold={() => setIsFold(!isFold)}
|
||||
/>
|
||||
<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>
|
||||
@ -311,6 +318,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
|
||||
{basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && tabNum === 2 && (
|
||||
<PitchPlacement setTabNum={setTabNum} ref={placementFlatRef} />
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="grid-btn-wrap">
|
||||
{/* {tabNum === 1 && <button className="btn-frame modal mr5">{getMessage('modal.common.save')}</button>} */}
|
||||
|
||||
@ -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 { fabric } from 'fabric'
|
||||
import { fontSelector } from '@/store/fontAtom'
|
||||
import { fabric } from 'fabric'
|
||||
|
||||
const ALLOCATION_TYPE = {
|
||||
AUTO: 'auto',
|
||||
@ -59,6 +59,9 @@ export default function CircuitTrestleSetting({ id }) {
|
||||
const passivityCircuitAllocationRef = useRef()
|
||||
const { setIsGlobalLoading } = useContext(QcastContext)
|
||||
|
||||
const originCanvasViewPortTransform = useRef([])
|
||||
const [isFold, setIsFold] = useState(false)
|
||||
|
||||
const {
|
||||
makers,
|
||||
setMakers,
|
||||
@ -83,6 +86,7 @@ export default function CircuitTrestleSetting({ id }) {
|
||||
} = useCircuitTrestle()
|
||||
// const { trigger: moduleSelectedDataTrigger } = useCanvasPopupStatusController(2)
|
||||
useEffect(() => {
|
||||
originCanvasViewPortTransform.current = [...canvas.viewportTransform]
|
||||
if (!managementState) {
|
||||
}
|
||||
// setCircuitData({
|
||||
@ -171,15 +175,12 @@ 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')
|
||||
@ -188,9 +189,12 @@ export default function CircuitTrestleSetting({ id }) {
|
||||
|
||||
// 캡쳐 후 처리
|
||||
const afterCapture = (type) => {
|
||||
setCanvasZoom(100)
|
||||
canvas.set({ zoom: 1 })
|
||||
canvas.viewportTransform = [1, 0, 0, 1, 0, 0]
|
||||
if (originCanvasViewPortTransform.current[0] !== 1) {
|
||||
setCanvasZoom(Number((originCanvasViewPortTransform.current[0] * 100).toFixed(0)))
|
||||
}
|
||||
canvas.viewportTransform = [...originCanvasViewPortTransform.current]
|
||||
canvas.renderAll()
|
||||
|
||||
changeFontSize('lengthText', lengthText.fontSize.value)
|
||||
changeFontSize('circuitNumber', circuitNumberText.fontSize.value)
|
||||
changeFontSize('flowText', flowText.fontSize.value)
|
||||
@ -223,11 +227,33 @@ 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(),
|
||||
pcsItemList: getPcsItemList(isMultiModule),
|
||||
}
|
||||
|
||||
// 파워컨디셔너 추천 목록 조회
|
||||
@ -288,12 +314,12 @@ export default function CircuitTrestleSetting({ id }) {
|
||||
})
|
||||
} else {
|
||||
// 회로 구성 가능 여부 체크
|
||||
getPcsVoltageChk({ ...params, pcsItemList: getSelectedPcsItemList() }).then((res) => {
|
||||
getPcsVoltageChk({ ...params, pcsItemList: getSelectedPcsItemList(isMultiModule) }).then((res) => {
|
||||
if (res.resultCode === 'S') {
|
||||
// 회로 구성 가능 여부 체크 통과 시 승압설정 정보 조회
|
||||
getPcsVoltageStepUpList({
|
||||
...params,
|
||||
pcsItemList: getSelectedPcsItemList(),
|
||||
pcsItemList: getSelectedPcsItemList(isMultiModule),
|
||||
}).then((res) => {
|
||||
if (res?.result.resultCode === 'S' && res?.data) {
|
||||
setTabNum(2)
|
||||
@ -519,6 +545,7 @@ 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) => {
|
||||
@ -788,8 +815,15 @@ 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()} />
|
||||
<WithDraggable.Header
|
||||
title={getMessage('modal.circuit.trestle.setting')}
|
||||
onClose={() => handleClose()}
|
||||
isFold={isFold}
|
||||
onFold={() => setIsFold(!isFold)}
|
||||
/>
|
||||
<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>
|
||||
@ -797,11 +831,14 @@ export default function CircuitTrestleSetting({ id }) {
|
||||
{getMessage('modal.circuit.trestle.setting.circuit.allocation')}({getMessage('modal.circuit.trestle.setting.step.up.allocation')})
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{tabNum === 1 && allocationType === ALLOCATION_TYPE.AUTO && <PowerConditionalSelect {...powerConditionalSelectProps} />}
|
||||
{tabNum === 1 && allocationType === ALLOCATION_TYPE.PASSIVITY && (
|
||||
<PassivityCircuitAllocation {...passivityProps} ref={passivityCircuitAllocationRef} />
|
||||
<PassivityCircuitAllocation {...passivityProps} ref={passivityCircuitAllocationRef} isFold={isFold} />
|
||||
)}
|
||||
{tabNum === 2 && <StepUp {...stepUpProps} onInitialize={handleStepUpInitialize} />}
|
||||
</div>
|
||||
|
||||
{tabNum === 1 && allocationType === ALLOCATION_TYPE.AUTO && (
|
||||
<div className="grid-btn-wrap">
|
||||
<button className="btn-frame modal mr5 act" onClick={() => onAutoRecommend()}>
|
||||
|
||||
@ -649,7 +649,13 @@ export default function StepUp(props) {
|
||||
style={{ cursor: allocationType === 'auto' ? 'pointer' : 'default' }}
|
||||
>
|
||||
<td className="al-r">{item.serQty}</td>
|
||||
<td className="al-r">{item.paralQty}</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> */}
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
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'
|
||||
@ -10,8 +9,8 @@ import { moduleStatisticsState } from '@/store/circuitTrestleAtom'
|
||||
import { fontSelector } from '@/store/fontAtom'
|
||||
import { selectedModuleState } from '@/store/selectedModuleOptions'
|
||||
import { circuitNumDisplaySelector } from '@/store/settingAtom'
|
||||
import { useContext, useEffect, useState } from 'react'
|
||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||
import { useContext, useEffect, useRef, useState } from 'react'
|
||||
import { useRecoilValue } from 'recoil'
|
||||
import { normalizeDigits } from '@/util/input-utils'
|
||||
|
||||
export default function PassivityCircuitAllocation(props) {
|
||||
@ -22,6 +21,7 @@ export default function PassivityCircuitAllocation(props) {
|
||||
getOptYn: getApiProps,
|
||||
getUseModuleItemList: getSelectedModuleList,
|
||||
getSelectModelList: getSelectModelList,
|
||||
isFold,
|
||||
} = props
|
||||
const { swalFire } = useSwal()
|
||||
const { getMessage } = useMessage()
|
||||
@ -32,6 +32,7 @@ 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()
|
||||
@ -59,6 +60,10 @@ export default function PassivityCircuitAllocation(props) {
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
targetModulesRef.current = targetModules
|
||||
}, [targetModules])
|
||||
|
||||
const handleTargetModules = (obj) => {
|
||||
if (!Array.isArray(targetModules)) {
|
||||
setTargetModules([])
|
||||
@ -79,6 +84,7 @@ export default function PassivityCircuitAllocation(props) {
|
||||
}
|
||||
|
||||
const handleCircuitNumberFix = () => {
|
||||
const pcsTpCd = selectedPcs.pcsTpCd // 실내집중형, 옥외멀티형
|
||||
let uniqueCircuitNumbers = [
|
||||
...new Set(
|
||||
canvas
|
||||
@ -91,13 +97,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]
|
||||
})
|
||||
|
||||
if (surfaceList.length > 1) {
|
||||
let surfaceType = {}
|
||||
|
||||
surfaceList.forEach((surface) => {
|
||||
surfaceType[`${surface.direction}-${surface.roofMaterial.pitch}`] = surface
|
||||
})
|
||||
|
||||
if (surfaceList.length > 1) {
|
||||
if (Object.keys(surfaceType).length > 1) {
|
||||
swalFire({
|
||||
text: getMessage('module.circuit.fix.not.same.roof.error'),
|
||||
@ -107,6 +113,7 @@ export default function PassivityCircuitAllocation(props) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (!circuitNumber || circuitNumber === 0) {
|
||||
swalFire({
|
||||
text: getMessage('module.circuit.minimun.error'),
|
||||
@ -114,14 +121,46 @@ export default function PassivityCircuitAllocation(props) {
|
||||
icon: 'warning',
|
||||
})
|
||||
return
|
||||
} else if (targetModules.length === 0) {
|
||||
}
|
||||
|
||||
if (targetModules.length === 0) {
|
||||
swalFire({
|
||||
text: getMessage('module.not.found'),
|
||||
type: 'alert',
|
||||
icon: 'warning',
|
||||
})
|
||||
return
|
||||
} else if (selectedModels.length > 1) {
|
||||
}
|
||||
|
||||
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
|
||||
})
|
||||
|
||||
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) => {
|
||||
@ -141,6 +180,8 @@ export default function PassivityCircuitAllocation(props) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let tempSelectedPcs = { ...selectedPcs }
|
||||
canvas.discardActiveObject()
|
||||
@ -189,6 +230,7 @@ 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,
|
||||
@ -270,6 +312,12 @@ 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()
|
||||
@ -497,6 +545,7 @@ 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">
|
||||
@ -541,7 +590,9 @@ export default function PassivityCircuitAllocation(props) {
|
||||
<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="bold-font">
|
||||
{getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.selected.power.conditional')}
|
||||
</div>
|
||||
</div>
|
||||
<div className="hexagonal-item">
|
||||
{selectedModels.map((model, index) => (
|
||||
@ -568,6 +619,7 @@ export default function PassivityCircuitAllocation(props) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="slope-wrap">
|
||||
<div className="circuit-right-wrap mb15">
|
||||
<div className="outline-form">
|
||||
|
||||
@ -4,6 +4,7 @@ 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()
|
||||
@ -21,17 +22,32 @@ export default function Eaves({ pitchRef, offsetRef, widthRef, radioTypeRef, pit
|
||||
{getMessage('slope')}
|
||||
</span>
|
||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||
<input
|
||||
type="text"
|
||||
{/*<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=""
|
||||
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
|
||||
value={currentAngleType === ANGLE_TYPE.SLOPE ? 4 : 21.8}
|
||||
onChange={(value) => {
|
||||
if (pitchRef?.current) pitchRef.current.value = value
|
||||
}}
|
||||
/>
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: true //(index !== 0),
|
||||
}}
|
||||
></CalculatorInput>
|
||||
</div>
|
||||
<span className="thin">{pitchText}</span>
|
||||
</div>
|
||||
@ -40,17 +56,32 @@ export default function Eaves({ pitchRef, offsetRef, widthRef, radioTypeRef, pit
|
||||
{getMessage('offset')}
|
||||
</span>
|
||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||
<input
|
||||
type="text"
|
||||
{/*<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=""
|
||||
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
|
||||
value={500}
|
||||
onChange={(value) => {
|
||||
if (offsetRef?.current) offsetRef.current.value = value
|
||||
}}
|
||||
/>
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false //(index !== 0),
|
||||
}}
|
||||
></CalculatorInput>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
@ -91,18 +122,33 @@ 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"
|
||||
{/*<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=""
|
||||
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
|
||||
value={500}
|
||||
onChange={(value) => {
|
||||
if (widthRef?.current) widthRef.current.value = value
|
||||
}}
|
||||
/>
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false //(index !== 0),
|
||||
}}
|
||||
></CalculatorInput>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
|
||||
@ -3,6 +3,7 @@ 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()
|
||||
@ -21,7 +22,19 @@ 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} />
|
||||
{/*<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>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
@ -65,13 +78,29 @@ export default function Gable({ pitchRef, offsetRef, widthRef, radioTypeRef, pit
|
||||
{getMessage('slope')}
|
||||
</span>
|
||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||
<input
|
||||
type="text"
|
||||
{/*<input*/}
|
||||
{/* type="text"*/}
|
||||
{/* className="input-origin block"*/}
|
||||
{/* defaultValue={currentAngleType === ANGLE_TYPE.SLOPE ? 4.5 : 20}*/}
|
||||
{/* ref={pitchRef}*/}
|
||||
{/* readOnly={type === '1'}*/}
|
||||
{/*/>*/}
|
||||
<CalculatorInput
|
||||
id=""
|
||||
name=""
|
||||
label=""
|
||||
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>
|
||||
@ -91,7 +120,20 @@ 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'} />
|
||||
{/*<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>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||
|
||||
export default function Shed({ offsetRef }) {
|
||||
const { getMessage } = useMessage()
|
||||
@ -10,7 +11,19 @@ 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} />
|
||||
{/*<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>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
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()
|
||||
@ -51,7 +52,20 @@ 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'} />
|
||||
{/*<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>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
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()
|
||||
@ -14,14 +15,29 @@ 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"
|
||||
{/*<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=""
|
||||
className="input-origin block"
|
||||
value={angle1}
|
||||
ref={angle1Ref}
|
||||
onFocus={(e) => (angle1Ref.current.value = '')}
|
||||
onChange={(e) => setAngle1(normalizeDecimalLimit(e.target.value, 2))}
|
||||
onChange={(value) => setAngle1(value)}
|
||||
placeholder="45"
|
||||
onFocus={() => (angle1Ref.current.value = '')}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: true
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
@ -34,14 +50,29 @@ 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"
|
||||
{/*<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=""
|
||||
className="input-origin block"
|
||||
value={length1}
|
||||
ref={length1Ref}
|
||||
onFocus={(e) => (length1Ref.current.value = '')}
|
||||
onChange={(e) => setLength1(normalizeDigits(e.target.value))}
|
||||
onChange={(value) => setLength1(value)}
|
||||
placeholder="3000"
|
||||
onFocus={() => (length1Ref.current.value = '')}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
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()
|
||||
@ -30,14 +31,29 @@ export default function Diagonal({ props }) {
|
||||
{getMessage('modal.cover.outline.length')}
|
||||
</span>
|
||||
<div className="input-grid" style={{ width: '63px' }}>
|
||||
<input
|
||||
type="text"
|
||||
{/*<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=""
|
||||
className="input-origin block"
|
||||
value={outerLineDiagonalLength}
|
||||
ref={outerLineDiagonalLengthRef}
|
||||
onFocus={(e) => (outerLineDiagonalLengthRef.current.value = '')}
|
||||
onChange={(e) => setOuterLineDiagonalLength(normalizeDigits(e.target.value))}
|
||||
onChange={(value) => setOuterLineDiagonalLength(value)}
|
||||
placeholder="3000"
|
||||
onFocus={() => (outerLineDiagonalLengthRef.current.value = '')}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
@ -52,14 +68,29 @@ 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"
|
||||
{/*<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=""
|
||||
className="input-origin block"
|
||||
value={length1}
|
||||
ref={length1Ref}
|
||||
onFocus={(e) => (length1Ref.current.value = '')}
|
||||
onChange={(e) => setLength1(normalizeDigits(e.target.value))}
|
||||
onChange={(value) => setLength1(value)}
|
||||
placeholder="3000"
|
||||
onFocus={() => (length1Ref.current.value = '')}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
@ -110,14 +141,29 @@ 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"
|
||||
{/*<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=""
|
||||
className="input-origin block"
|
||||
value={length2}
|
||||
ref={length2Ref}
|
||||
onChange={(e) => setLength2(normalizeDigits(e.target.value))}
|
||||
readOnly={true}
|
||||
onChange={(value) => setLength2(value)}
|
||||
placeholder="3000"
|
||||
onFocus={() => (length2Ref.current.value = '')}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
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()
|
||||
@ -50,14 +51,29 @@ 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"
|
||||
{/*<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=""
|
||||
className="input-origin block"
|
||||
value={angle1}
|
||||
ref={angle1Ref}
|
||||
onFocus={(e) => (angle1Ref.current.value = '')}
|
||||
onChange={(e) => setAngle1(normalizeDecimalLimit(e.target.value, 2))}
|
||||
onChange={(value) => setAngle1(value)}
|
||||
placeholder="45"
|
||||
onFocus={() => (angle1Ref.current.value = '')}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: true
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<button className="reset-btn" onClick={() => setAngle1(0)}></button>
|
||||
@ -67,14 +83,29 @@ 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"
|
||||
{/*<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=""
|
||||
className="input-origin block"
|
||||
value={length1}
|
||||
ref={length1Ref}
|
||||
onFocus={(e) => (length1Ref.current.value = '')}
|
||||
onChange={(e) => setLength1(normalizeDigits(e.target.value))}
|
||||
onChange={(value) => setLength1(value)}
|
||||
placeholder="3000"
|
||||
onFocus={() => (length1Ref.current.value = '')}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
@ -125,18 +156,36 @@ 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"
|
||||
{/*<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=""
|
||||
className="input-origin block"
|
||||
value={angle2}
|
||||
ref={angle2Ref}
|
||||
onFocus={(e) => (angle2Ref.current.value = '')}
|
||||
onChange={(e) => {
|
||||
const v = normalizeDecimalLimit(e.target.value, 2)
|
||||
setAngle2(v)
|
||||
onChange={(value) => {
|
||||
setAngle2(value)
|
||||
setLength2(getLength2())
|
||||
}}
|
||||
placeholder="45"
|
||||
onFocus={() => (angle2Ref.current.value = '')}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: true
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
@ -151,15 +200,30 @@ 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"
|
||||
{/*<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=""
|
||||
className="input-origin block"
|
||||
value={length2}
|
||||
ref={length2Ref}
|
||||
onFocus={(e) => (length2Ref.current.value = '')}
|
||||
onChange={(e) => setLength2(normalizeDigits(e.target.value))}
|
||||
readOnly={true}
|
||||
onChange={(value) => setLength2(value)}
|
||||
placeholder="3000"
|
||||
onFocus={() => (length2Ref.current.value = '')}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
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()
|
||||
@ -22,14 +23,29 @@ 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"
|
||||
{/*<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=""
|
||||
className="input-origin block"
|
||||
placeholder="3000"
|
||||
value={length1}
|
||||
ref={length1Ref}
|
||||
onFocus={(e) => (length1Ref.current.value = '')}
|
||||
onChange={(e) => setLength1(normalizeDigits(e.target.value))}
|
||||
placeholder="3000"
|
||||
onChange={(value) => setLength1(value)}
|
||||
onFocus={() => (length1Ref.current.value = '')}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
@ -78,14 +94,29 @@ 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"
|
||||
{/*<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=""
|
||||
className="input-origin block"
|
||||
value={length2}
|
||||
ref={length2Ref}
|
||||
onFocus={(e) => (length2Ref.current.value = '')}
|
||||
onChange={(e) => setLength2(normalizeDigits(e.target.value))}
|
||||
onFocus={() => (length2Ref.current.value = '')}
|
||||
onChange={(value) => setLength2(value)}
|
||||
placeholder="3000"
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
|
||||
@ -6,6 +6,7 @@ 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)
|
||||
@ -16,6 +17,8 @@ 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({})
|
||||
@ -50,7 +53,20 @@ 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" />
|
||||
{/*<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
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<span>mm</span>
|
||||
<div className="direction-move-wrap">
|
||||
|
||||
@ -5,10 +5,11 @@ import { useMessage } from '@/hooks/useMessage'
|
||||
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
||||
import { usePopup } from '@/hooks/usePopup'
|
||||
import { contextPopupPositionState } from '@/store/popupAtom'
|
||||
import { useRef, useState } from 'react'
|
||||
import { useEffect, 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)
|
||||
@ -20,7 +21,8 @@ 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)
|
||||
|
||||
@ -28,6 +30,15 @@ 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
|
||||
@ -47,11 +58,25 @@ 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={(target?.originWidth * 10).toFixed(0)} readOnly={true} />
|
||||
<input type="text" className="input-origin mr5" value={width}
|
||||
onChange={(e) => setWidth(e.target.value)} 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} />
|
||||
{/*<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
|
||||
}}
|
||||
/>
|
||||
<span className="normal-font">mm</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -60,11 +85,25 @@ 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={(target?.originHeight * 10).toFixed(0)} readOnly={true} />
|
||||
<input type="text" className="input-origin mr5" value={height}
|
||||
onChange={(e) => setHeight(e.target.value)} 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} />
|
||||
{/*<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
|
||||
}}
|
||||
/>
|
||||
<span className="normal-font">mm</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,10 +1,13 @@
|
||||
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) {
|
||||
@ -51,12 +54,26 @@ 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"
|
||||
{/*<input*/}
|
||||
{/* type="text"*/}
|
||||
{/* className="input-origin block"*/}
|
||||
{/* placeholder={0}*/}
|
||||
{/* ref={refs.widthRef}*/}
|
||||
{/* disabled={selectedType !== INPUT_TYPE.DIMENSION}*/}
|
||||
{/*/>*/}
|
||||
<CalculatorInput
|
||||
id=""
|
||||
name=""
|
||||
label=""
|
||||
className="input-origin block"
|
||||
placeholder={0}
|
||||
value={width}
|
||||
ref={refs.widthRef}
|
||||
onChange={(value) => setWidth(value)}
|
||||
disabled={selectedType !== INPUT_TYPE.DIMENSION}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
@ -68,12 +85,26 @@ 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"
|
||||
{/*<input*/}
|
||||
{/* type="text"*/}
|
||||
{/* className="input-origin block"*/}
|
||||
{/* placeholder={0}*/}
|
||||
{/* ref={refs.heightRef}*/}
|
||||
{/* disabled={selectedType !== INPUT_TYPE.DIMENSION}*/}
|
||||
{/*/>*/}
|
||||
<CalculatorInput
|
||||
id=""
|
||||
name=""
|
||||
label=""
|
||||
className="input-origin block"
|
||||
placeholder={0}
|
||||
value={height}
|
||||
ref={refs.heightRef}
|
||||
onChange={(value) => setHeight(value)}
|
||||
disabled={selectedType !== INPUT_TYPE.DIMENSION}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
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()
|
||||
@ -11,6 +12,11 @@ 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 (
|
||||
<>
|
||||
@ -30,7 +36,20 @@ 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} />
|
||||
{/*<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
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
@ -41,7 +60,20 @@ 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} />
|
||||
{/*<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
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
@ -55,7 +87,20 @@ 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} />
|
||||
{/*<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
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
@ -66,7 +111,20 @@ 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} />
|
||||
{/*<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
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
@ -77,7 +135,20 @@ 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} />
|
||||
{/*<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>
|
||||
</div>
|
||||
<span className="thin">寸</span>
|
||||
</div>
|
||||
|
||||
@ -1,11 +1,14 @@
|
||||
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) {
|
||||
@ -51,12 +54,26 @@ 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"
|
||||
{/*<input*/}
|
||||
{/* type="text"*/}
|
||||
{/* className="input-origin block"*/}
|
||||
{/* placeholder={0}*/}
|
||||
{/* ref={refs.widthRef}*/}
|
||||
{/* disabled={selectedType !== INPUT_TYPE.DIMENSION}*/}
|
||||
{/*/>*/}
|
||||
<CalculatorInput
|
||||
id=""
|
||||
name=""
|
||||
label=""
|
||||
className="input-origin block"
|
||||
placeholder={0}
|
||||
value={width}
|
||||
ref={refs.widthRef}
|
||||
onChange={(value) => setWidth(value)}
|
||||
disabled={selectedType !== INPUT_TYPE.DIMENSION}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
@ -68,12 +85,26 @@ 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"
|
||||
{/*<input*/}
|
||||
{/* type="text"*/}
|
||||
{/* className="input-origin block"*/}
|
||||
{/* placeholder={0}*/}
|
||||
{/* ref={refs.heightRef}*/}
|
||||
{/* disabled={selectedType !== INPUT_TYPE.DIMENSION}*/}
|
||||
{/*/>*/}
|
||||
<CalculatorInput
|
||||
id=""
|
||||
name=""
|
||||
label=""
|
||||
className="input-origin block"
|
||||
placeholder={0}
|
||||
value={height}
|
||||
ref={refs.heightRef}
|
||||
onChange={(value) => setHeight(value)}
|
||||
disabled={selectedType !== INPUT_TYPE.DIMENSION}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
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()
|
||||
@ -11,6 +12,9 @@ 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 (
|
||||
<>
|
||||
@ -30,7 +34,20 @@ const TriangleDormer = 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={1500} />
|
||||
{/*<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
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
@ -41,7 +58,20 @@ const TriangleDormer = 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} />
|
||||
{/*<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
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
@ -52,7 +82,20 @@ const TriangleDormer = 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} />
|
||||
{/*<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
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<span className="thin">寸</span>
|
||||
</div>
|
||||
|
||||
@ -13,6 +13,7 @@ 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)
|
||||
@ -204,15 +205,29 @@ export default function ContextRoofAllocationSetting(props) {
|
||||
<div className="flex-ment">
|
||||
<span>{getMessage('modal.object.setting.offset.slope')}</span>
|
||||
<div className="input-grid">
|
||||
<input
|
||||
type="text"
|
||||
{/*<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=""
|
||||
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>
|
||||
|
||||
@ -14,6 +14,7 @@ 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)
|
||||
@ -205,15 +206,29 @@ export default function RoofAllocationSetting(props) {
|
||||
<div className="flex-ment">
|
||||
<span>{getMessage('modal.object.setting.offset.slope')}</span>
|
||||
<div className="input-grid">
|
||||
<input
|
||||
type="text"
|
||||
{/*<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=""
|
||||
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>
|
||||
|
||||
@ -3,6 +3,7 @@ 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()
|
||||
@ -16,12 +17,24 @@ export default function Eaves({ offsetRef, pitchRef, pitchText }) {
|
||||
{getMessage('slope')}
|
||||
</span>
|
||||
<div className="input-grid mr5">
|
||||
<input
|
||||
type="text"
|
||||
{/*<input*/}
|
||||
{/* type="text"*/}
|
||||
{/* className="input-origin block"*/}
|
||||
{/* defaultValue={currentAngleType === ANGLE_TYPE.SLOPE ? selectedRoofMaterial.pitch : selectedRoofMaterial.angle}*/}
|
||||
{/* ref={pitchRef}*/}
|
||||
{/*/>*/}
|
||||
<CalculatorInput
|
||||
id=""
|
||||
name=""
|
||||
label=""
|
||||
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>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
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()
|
||||
@ -10,12 +11,24 @@ export default function Direction({ pitch, setPitch, eavesOffset, setEavesOffset
|
||||
{getMessage('slope')}
|
||||
</span>
|
||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||
<input
|
||||
type="text"
|
||||
{/*<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={(e) => setPitch(normalizeDecimalLimit(e.target.value, 2))}
|
||||
/>
|
||||
onChange={(value) => setPitch(value)}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: true //(index !== 0),
|
||||
}}
|
||||
></CalculatorInput>
|
||||
</div>
|
||||
<span className="thin">{pitchText}</span>
|
||||
</div>
|
||||
@ -24,12 +37,24 @@ export default function Direction({ pitch, setPitch, eavesOffset, setEavesOffset
|
||||
{getMessage('eaves.offset')}
|
||||
</span>
|
||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||
<input
|
||||
type="text"
|
||||
{/*<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={(e) => setEavesOffset(normalizeDigits(e.target.value))}
|
||||
/>
|
||||
onChange={(value) => setEavesOffset(value)}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false //(index !== 0),
|
||||
}}
|
||||
></CalculatorInput>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
@ -38,12 +63,24 @@ export default function Direction({ pitch, setPitch, eavesOffset, setEavesOffset
|
||||
{getMessage('gable.offset')}
|
||||
</span>
|
||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||
<input
|
||||
type="text"
|
||||
{/*<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={(e) => setGableOffset(normalizeDigits(e.target.value))}
|
||||
/>
|
||||
onChange={(value) => setGableOffset(value)}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false //(index !== 0),
|
||||
}}
|
||||
></CalculatorInput>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
@ -52,12 +89,24 @@ export default function Direction({ pitch, setPitch, eavesOffset, setEavesOffset
|
||||
{getMessage('windage.width')}
|
||||
</span>
|
||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||
<input
|
||||
type="text"
|
||||
{/*<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={(e) => setShedWidth(normalizeDigits(e.target.value))}
|
||||
/>
|
||||
onChange={(value) => setShedWidth(value)}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false //(index !== 0),
|
||||
}}
|
||||
></CalculatorInput>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
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()
|
||||
@ -11,7 +12,20 @@ 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))} />
|
||||
{/*<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>
|
||||
</div>
|
||||
<span className="thin"> {pitchText}</span>
|
||||
</div>
|
||||
@ -20,7 +34,20 @@ 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))} />
|
||||
{/*<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>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
@ -29,7 +56,20 @@ 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))} />
|
||||
{/*<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>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
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()
|
||||
@ -13,7 +14,20 @@ 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))} />
|
||||
{/*<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>
|
||||
</div>
|
||||
<span className="thin">{pitchText}</span>
|
||||
</div>
|
||||
@ -22,7 +36,20 @@ 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))} />
|
||||
{/*<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>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
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()
|
||||
@ -10,7 +11,21 @@ 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))} />
|
||||
{/*<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>
|
||||
|
||||
</div>
|
||||
<span className="thin">{pitchText}</span>
|
||||
</div>
|
||||
@ -19,7 +34,20 @@ 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))} />
|
||||
{/*<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>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
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()
|
||||
@ -10,7 +11,20 @@ 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))} />
|
||||
{/*<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>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
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()
|
||||
@ -10,7 +11,20 @@ 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))} />
|
||||
{/*<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>
|
||||
</div>
|
||||
<span className="thin">{pitchText}</span>
|
||||
</div>
|
||||
@ -19,7 +33,21 @@ 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))} />
|
||||
{/*<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>
|
||||
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
@ -28,12 +56,24 @@ export default function HipAndGable({ pitch, setPitch, eavesOffset, setEavesOffs
|
||||
{getMessage('hipandgable.width')}
|
||||
</span>
|
||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||
<input
|
||||
type="text"
|
||||
{/*<input*/}
|
||||
{/* type="text"*/}
|
||||
{/* className="input-origin block"*/}
|
||||
{/* value={hipAndGableWidth}*/}
|
||||
{/* onChange={(e) => setHipAndGableWidth(normalizeDigits(e.target.value))}*/}
|
||||
{/*/>*/}
|
||||
<CalculatorInput
|
||||
id=""
|
||||
name=""
|
||||
label=""
|
||||
className="input-origin block"
|
||||
value={hipAndGableWidth}
|
||||
onChange={(e) => setHipAndGableWidth(normalizeDigits(e.target.value))}
|
||||
/>
|
||||
onChange={(value) => setHipAndGableWidth(value)}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false //(index !== 0),
|
||||
}}
|
||||
></CalculatorInput>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
||||
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||
|
||||
export default function Jerkinhead({
|
||||
gableOffset,
|
||||
@ -18,7 +19,20 @@ 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))} />
|
||||
{/*<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>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
@ -27,7 +41,21 @@ 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))} />
|
||||
{/*<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>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
@ -36,12 +64,24 @@ export default function Jerkinhead({
|
||||
{getMessage('jerkinhead.slope')}
|
||||
</span>
|
||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||
<input
|
||||
type="text"
|
||||
{/*<input*/}
|
||||
{/* type="text"*/}
|
||||
{/* className="input-origin block"*/}
|
||||
{/* value={jerkinHeadPitch}*/}
|
||||
{/* onChange={(e) => setJerkinHeadPitch(normalizeDecimalLimit(e.target.value, 2))}*/}
|
||||
{/*/>*/}
|
||||
<CalculatorInput
|
||||
id=""
|
||||
name=""
|
||||
label=""
|
||||
className="input-origin block"
|
||||
value={jerkinHeadPitch}
|
||||
onChange={(e) => setJerkinHeadPitch(normalizeDecimalLimit(e.target.value, 2))}
|
||||
/>
|
||||
onChange={(value) => setJerkinHeadPitch(value)}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: true //(index !== 0),
|
||||
}}
|
||||
></CalculatorInput>
|
||||
</div>
|
||||
<span className="thin">{pitchText}</span>
|
||||
</div>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
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()
|
||||
@ -8,14 +9,40 @@ 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))} />
|
||||
{/*<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>
|
||||
</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))} />
|
||||
{/*<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>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
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()
|
||||
@ -10,7 +11,8 @@ 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>
|
||||
@ -18,20 +20,34 @@ 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"
|
||||
{/*<input*/}
|
||||
{/* type="text"*/}
|
||||
{/* className="input-origin block"*/}
|
||||
{/* value={sleeveOffset}*/}
|
||||
{/* onChange={(e) => setSleeveOffset(normalizeDigits(e.target.value))}*/}
|
||||
{/* readOnly={hasSleeve === '0'}*/}
|
||||
{/*/>*/}
|
||||
<CalculatorInput
|
||||
id=""
|
||||
name=""
|
||||
label=""
|
||||
className="input-origin block"
|
||||
value={sleeveOffset}
|
||||
onChange={(e) => setSleeveOffset(normalizeDigits(e.target.value))}
|
||||
onChange={(value) => setSleeveOffset(value)}
|
||||
readOnly={hasSleeve === '0'}
|
||||
/>
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false //(index !== 0),
|
||||
}}
|
||||
></CalculatorInput>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
</div>
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import React, { useEffect } 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()
|
||||
@ -11,6 +13,7 @@ export default function FirstOption(props) {
|
||||
const { option1, option2, dimensionDisplay } = settingModalFirstOptions
|
||||
const { initEvent } = useEvent()
|
||||
const { setSurfaceShapePattern } = useRoofFn()
|
||||
const outlineDisplay = useRecoilValue(outlineDisplaySelector)
|
||||
|
||||
// 데이터를 최초 한 번만 조회
|
||||
useEffect(() => {
|
||||
@ -18,6 +21,13 @@ 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
|
||||
@ -58,7 +68,12 @@ 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(() => {
|
||||
|
||||
@ -31,8 +31,11 @@ export function useCommonUtils() {
|
||||
useEffect(() => {
|
||||
commonTextMode()
|
||||
if (commonUtils.dimension) {
|
||||
generateTempGrid()
|
||||
commonDimensionMode()
|
||||
return
|
||||
} else {
|
||||
removeTempGrid()
|
||||
}
|
||||
if (commonUtils.distance) {
|
||||
commonDistanceMode()
|
||||
@ -645,6 +648,7 @@ export function useCommonUtils() {
|
||||
lockMovementY: true,
|
||||
name: obj.name,
|
||||
editable: false,
|
||||
selectable: true, // 복사된 객체 선택 가능하도록 설정
|
||||
id: uuidv4(), //복사된 객체라 새로 따준다
|
||||
})
|
||||
|
||||
@ -653,19 +657,25 @@ export function useCommonUtils() {
|
||||
|
||||
//배치면일 경우
|
||||
if (obj.name === 'roof') {
|
||||
clonedObj.setCoords()
|
||||
clonedObj.fire('modified')
|
||||
clonedObj.fire('polygonMoved')
|
||||
clonedObj.canvas = canvas // canvas 참조 설정
|
||||
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) //방향 화살표 추가
|
||||
@ -905,6 +915,45 @@ 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,
|
||||
@ -916,5 +965,7 @@ export function useCommonUtils() {
|
||||
editText,
|
||||
changeDimensionExtendLine,
|
||||
deleteOuterLineObject,
|
||||
generateTempGrid,
|
||||
removeTempGrid,
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ import {
|
||||
basicSettingState,
|
||||
correntObjectNoState,
|
||||
corridorDimensionSelector,
|
||||
outlineDisplaySelector,
|
||||
roofDisplaySelector,
|
||||
roofMaterialsSelector,
|
||||
selectedRoofMaterialSelector,
|
||||
@ -61,9 +62,11 @@ 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(() => {
|
||||
/** 배치면 초기설정에서 선택한 지붕재 배열 설정 */
|
||||
@ -305,11 +308,53 @@ 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()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 지붕재 오른쪽 마우스 클릭 후 단일로 지붕재 변경 필요한 경우
|
||||
*/
|
||||
@ -587,7 +632,7 @@ export function useRoofAllocationSetting(id) {
|
||||
* 피치 변경
|
||||
*/
|
||||
const handleChangePitch = (e, index) => {
|
||||
let value = e.target.value
|
||||
let value = e //e.target.value
|
||||
|
||||
const reg = /^[0-9]+(\.[0-9]{0,1})?$/
|
||||
if (!reg.test(value)) {
|
||||
|
||||
@ -402,7 +402,8 @@ export function useCanvasEvent() {
|
||||
}
|
||||
} else {
|
||||
zoom = canvasZoom - 10
|
||||
if (zoom < 10) { //50%->10%
|
||||
if (zoom < 10) {
|
||||
//50%->10%
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -412,8 +413,33 @@ export function useCanvasEvent() {
|
||||
|
||||
const handleZoomClear = () => {
|
||||
setCanvasZoom(100)
|
||||
canvas.set({ zoom: 1 })
|
||||
canvas.viewportTransform = [1, 0, 0, 1, 0, 0]
|
||||
|
||||
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.renderAll()
|
||||
}
|
||||
|
||||
|
||||
@ -42,7 +42,18 @@ export function useCircuitTrestle(executeEffect = false) {
|
||||
}
|
||||
}
|
||||
// PCS 아이템 목록
|
||||
const getPcsItemList = () => {
|
||||
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,
|
||||
}
|
||||
})
|
||||
}
|
||||
return models.map((model) => {
|
||||
return {
|
||||
itemId: model.itemId,
|
||||
@ -53,7 +64,18 @@ export function useCircuitTrestle(executeEffect = false) {
|
||||
}
|
||||
|
||||
// 선택된 PCS 아이템 목록
|
||||
const getSelectedPcsItemList = () => {
|
||||
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,
|
||||
}
|
||||
})
|
||||
}
|
||||
return selectedModels.map((model) => {
|
||||
return {
|
||||
itemId: model.itemId,
|
||||
@ -95,6 +117,7 @@ export function useCircuitTrestle(executeEffect = false) {
|
||||
uniqueId: module.id ? module.id : null,
|
||||
}
|
||||
}),
|
||||
roofSurfaceNorthYn: obj.direction === 'north' ? 'Y' : 'N',
|
||||
}
|
||||
})
|
||||
.filter((surface) => surface.moduleList.length > 0)
|
||||
|
||||
@ -1809,6 +1809,7 @@ 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]
|
||||
@ -1820,12 +1821,10 @@ export function useMode() {
|
||||
x: xDiff.eq(0) ? offsetCurrentPoint.x : nextWall.x1,
|
||||
y: yDiff.eq(0) ? offsetCurrentPoint.y : nextWall.y1,
|
||||
}
|
||||
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))
|
||||
}
|
||||
|
||||
let diffOffset = ['top', 'right'].includes(direction)
|
||||
? Big(nextWall.attributes.offset).minus(Big(currentWall.attributes.offset))
|
||||
: Big(currentWall.attributes.offset).minus(Big(nextWall.attributes.offset))
|
||||
|
||||
const offsetPoint2 = {
|
||||
x: yDiff.eq(0) ? offsetPoint1.x : Big(offsetPoint1.x).plus(diffOffset).toNumber(),
|
||||
|
||||
@ -1089,6 +1089,7 @@
|
||||
"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": "オブジェクトは屋根に設置する必要があります。",
|
||||
|
||||
@ -1089,6 +1089,7 @@
|
||||
"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": "오브젝트는 지붕내에 설치해야 합니다.",
|
||||
|
||||
@ -133,8 +133,23 @@ $alert-color: #101010;
|
||||
color: $pop-color;
|
||||
font-weight: 700;
|
||||
}
|
||||
.modal-close{
|
||||
.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{
|
||||
color: transparent;
|
||||
font-size: 0;
|
||||
width: 10px;
|
||||
|
||||
@ -460,7 +460,11 @@ button{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.table-select{
|
||||
height: 20px;
|
||||
color: #fff !important;
|
||||
font-size: 11px !important;
|
||||
}
|
||||
// input
|
||||
.form-input{
|
||||
label{
|
||||
|
||||
@ -269,7 +269,7 @@ export const getDegreeByChon = (chon) => {
|
||||
* @returns {number}
|
||||
*/
|
||||
export const getChonByDegree = (degree) => {
|
||||
return Number((Math.tan((degree * Math.PI) / 180) * 10).toFixed(1))
|
||||
return Number((Math.tan((degree * Math.PI) / 180) * 10).toFixed(2))
|
||||
}
|
||||
|
||||
/**
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -6,7 +6,6 @@ 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
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user