Merge pull request '[1252] 일본의 전각 숫자, 반각 숫자 입력' (#296) from dev into dev-deploy
Reviewed-on: #296
This commit is contained in:
commit
9877813dd1
@ -23,6 +23,7 @@ import { usePopup } from '@/hooks/usePopup'
|
|||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
import { QcastContext } from '@/app/QcastProvider'
|
import { QcastContext } from '@/app/QcastProvider'
|
||||||
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
|
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
|
||||||
|
import {normalizeDigits, normalizeDecimal} from '@/util/input-utils'
|
||||||
export default function Estimate({}) {
|
export default function Estimate({}) {
|
||||||
const [uniqueData, setUniqueData] = useState([])
|
const [uniqueData, setUniqueData] = useState([])
|
||||||
const [handlePricingFlag, setHandlePricingFlag] = useState(false)
|
const [handlePricingFlag, setHandlePricingFlag] = useState(false)
|
||||||
@ -645,11 +646,14 @@ export default function Estimate({}) {
|
|||||||
newValue = parts[0] + '.' + parts[1].substring(0, 2)
|
newValue = parts[0] + '.' + parts[1].substring(0, 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
let pkgAsp = newValue || '0'
|
let pkgAsp = normalizeDecimal(newValue || '0')
|
||||||
|
|
||||||
//현재 PKG용량값 가져오기
|
//현재 PKG용량값 가져오기
|
||||||
let totVolKw = estimateContextState.totVolKw * 1000
|
let totVolKw = estimateContextState.totVolKw * 1000
|
||||||
let pkgTotPrice = parseFloat(pkgAsp?.replaceAll(',', '')) * totVolKw * 1000
|
// let pkgTotPrice = parseFloat(pkgAsp?.replaceAll(',', '')) * totVolKw * 1000
|
||||||
|
|
||||||
|
const pkgAspNumber = Number(normalizeDecimal(pkgAsp))
|
||||||
|
const pkgTotPrice = pkgAspNumber * totVolKw * 1000
|
||||||
|
|
||||||
setEstimateContextState({
|
setEstimateContextState({
|
||||||
pkgAsp: pkgAsp,
|
pkgAsp: pkgAsp,
|
||||||
@ -663,7 +667,7 @@ export default function Estimate({}) {
|
|||||||
// 수량 변경
|
// 수량 변경
|
||||||
const onChangeAmount = (value, dispOrder, index) => {
|
const onChangeAmount = (value, dispOrder, index) => {
|
||||||
//itemChangeFlg = 1, partAdd = 0 셋팅
|
//itemChangeFlg = 1, partAdd = 0 셋팅
|
||||||
let amount = Number(value.replace(/[^0-9]/g, '').replaceAll(',', ''))
|
let amount = Number(normalizeDigits(value))
|
||||||
|
|
||||||
if (isNaN(amount)) {
|
if (isNaN(amount)) {
|
||||||
amount = '0'
|
amount = '0'
|
||||||
@ -701,7 +705,8 @@ export default function Estimate({}) {
|
|||||||
// 단가 변경
|
// 단가 변경
|
||||||
const onChangeSalePrice = (value, dispOrder, index) => {
|
const onChangeSalePrice = (value, dispOrder, index) => {
|
||||||
//itemChangeFlg, partAdd 받아온 그대로
|
//itemChangeFlg, partAdd 받아온 그대로
|
||||||
let salePrice = Number(value.replace(/[^0-9]/g, '').replaceAll(',', ''))
|
let salePrice = Number(normalizeDecimal(value))
|
||||||
|
|
||||||
if (isNaN(salePrice)) {
|
if (isNaN(salePrice)) {
|
||||||
salePrice = 0
|
salePrice = 0
|
||||||
} else {
|
} else {
|
||||||
@ -940,7 +945,7 @@ export default function Estimate({}) {
|
|||||||
delete item.showSalePrice
|
delete item.showSalePrice
|
||||||
delete item.showSaleTotPrice
|
delete item.showSaleTotPrice
|
||||||
if (item.delFlg === '0') {
|
if (item.delFlg === '0') {
|
||||||
let amount = Number(item.amount?.replace(/[^0-9]/g, '').replaceAll(',', '')) || 0
|
let amount = Number(normalizeDigits(item.amount)) || 0
|
||||||
let price
|
let price
|
||||||
if (amount === 0) {
|
if (amount === 0) {
|
||||||
price = 0
|
price = 0
|
||||||
@ -975,7 +980,7 @@ export default function Estimate({}) {
|
|||||||
makeUniqueSpecialNoteCd(itemList)
|
makeUniqueSpecialNoteCd(itemList)
|
||||||
itemList.forEach((item) => {
|
itemList.forEach((item) => {
|
||||||
if (item.delFlg === '0') {
|
if (item.delFlg === '0') {
|
||||||
let amount = Number(item.amount?.replace(/[^0-9]/g, '').replaceAll(',', '')) || 0
|
let amount = Number(normalizeDigits(item.amount)) || 0
|
||||||
let salePrice
|
let salePrice
|
||||||
if (item.moduleFlg === '1') {
|
if (item.moduleFlg === '1') {
|
||||||
const volKw = (item.pnowW * amount) / 1000
|
const volKw = (item.pnowW * amount) / 1000
|
||||||
@ -1009,8 +1014,8 @@ export default function Estimate({}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
let pkgAsp = estimateContextState.pkgAsp ? Number(estimateContextState.pkgAsp.replaceAll(',', '')) : 0
|
//let pkgAsp = estimateContextState.pkgAsp ? Number(estimateContextState.pkgAsp.replaceAll(',', '')) : 0
|
||||||
|
const pkgAsp = Number(normalizeDecimal(estimateContextState.pkgAsp))
|
||||||
totals.pkgTotPrice = pkgAsp * totals.totVolKw * 1000
|
totals.pkgTotPrice = pkgAsp * totals.totVolKw * 1000
|
||||||
totals.supplyPrice = totals.addSupplyPrice + totals.pkgTotPrice
|
totals.supplyPrice = totals.addSupplyPrice + totals.pkgTotPrice
|
||||||
totals.vatPrice = totals.supplyPrice * 0.1
|
totals.vatPrice = totals.supplyPrice * 0.1
|
||||||
@ -1069,7 +1074,7 @@ export default function Estimate({}) {
|
|||||||
let dispCableFlgCnt = 0
|
let dispCableFlgCnt = 0
|
||||||
estimateContextState.itemList.forEach((item) => {
|
estimateContextState.itemList.forEach((item) => {
|
||||||
if (item.delFlg === '0') {
|
if (item.delFlg === '0') {
|
||||||
let amount = Number(item.amount?.replace(/[^0-9]/g, '').replaceAll(',', '')) || 0
|
let amount = Number(normalizeDigits(item.amount)) || 0
|
||||||
let salePrice
|
let salePrice
|
||||||
if (item.moduleFlg === '1') {
|
if (item.moduleFlg === '1') {
|
||||||
const volKw = (item.pnowW * amount) / 1000
|
const volKw = (item.pnowW * amount) / 1000
|
||||||
@ -1102,7 +1107,7 @@ export default function Estimate({}) {
|
|||||||
item.showSaleTotPrice = '0'
|
item.showSaleTotPrice = '0'
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.dispCableFlg === '1' ) {
|
if (item.dispCableFlg === '1') {
|
||||||
dispCableFlgCnt++
|
dispCableFlgCnt++
|
||||||
if(item.itemTpCd === 'M12' || item.itemTpCd === 'S13') {
|
if(item.itemTpCd === 'M12' || item.itemTpCd === 'S13') {
|
||||||
setCableDbItem(item.itemId)
|
setCableDbItem(item.itemId)
|
||||||
@ -1118,9 +1123,10 @@ export default function Estimate({}) {
|
|||||||
setCableDbItem('100037')
|
setCableDbItem('100037')
|
||||||
}
|
}
|
||||||
|
|
||||||
let pkgAsp = estimateContextState.pkgAsp ? Number(estimateContextState.pkgAsp.replaceAll(',', '')) : 0
|
// let pkgAsp = estimateContextState.pkgAsp ? Number(estimateContextState.pkgAsp.replaceAll(',', '')) : 0
|
||||||
|
const pkgAsp = Number(normalizeDecimal(estimateContextState.pkgAsp))
|
||||||
totals.pkgTotPrice = pkgAsp * totals.totVolKw * 1000
|
totals.pkgTotPrice = pkgAsp * totals.totVolKw * 1000
|
||||||
|
|
||||||
totals.supplyPrice = totals.addSupplyPrice + totals.pkgTotPrice
|
totals.supplyPrice = totals.addSupplyPrice + totals.pkgTotPrice
|
||||||
totals.vatPrice = totals.supplyPrice * 0.1
|
totals.vatPrice = totals.supplyPrice * 0.1
|
||||||
totals.totPrice = totals.supplyPrice + totals.vatPrice
|
totals.totPrice = totals.supplyPrice + totals.vatPrice
|
||||||
@ -1150,7 +1156,7 @@ export default function Estimate({}) {
|
|||||||
delete item.showSalePrice
|
delete item.showSalePrice
|
||||||
delete item.showSaleTotPrice
|
delete item.showSaleTotPrice
|
||||||
if (item.delFlg === '0') {
|
if (item.delFlg === '0') {
|
||||||
let amount = Number(item.amount?.replace(/[^0-9]/g, '').replaceAll(',', '')) || 0
|
let amount = Number(normalizeDigits(item.amount)) || 0
|
||||||
let price
|
let price
|
||||||
if (amount === 0) {
|
if (amount === 0) {
|
||||||
price = 0
|
price = 0
|
||||||
@ -1176,10 +1182,6 @@ export default function Estimate({}) {
|
|||||||
|
|
||||||
if (item.dispCableFlg === '1') {
|
if (item.dispCableFlg === '1') {
|
||||||
dispCableFlgCnt++
|
dispCableFlgCnt++
|
||||||
}
|
|
||||||
|
|
||||||
if (item.dispCableFlg === '1'){
|
|
||||||
|
|
||||||
if(item.itemTpCd === 'M12' || item.itemTpCd === 'S13') {
|
if(item.itemTpCd === 'M12' || item.itemTpCd === 'S13') {
|
||||||
setCableDbItem(item.itemId)
|
setCableDbItem(item.itemId)
|
||||||
}else{
|
}else{
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import { useState } from 'react'
|
|||||||
import { currentObjectState } from '@/store/canvasAtom'
|
import { currentObjectState } from '@/store/canvasAtom'
|
||||||
import { useAuxiliaryDrawing } from '@/hooks/roofcover/useAuxiliaryDrawing'
|
import { useAuxiliaryDrawing } from '@/hooks/roofcover/useAuxiliaryDrawing'
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
|
import { normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function AuxiliaryEdit(props) {
|
export default function AuxiliaryEdit(props) {
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
@ -40,15 +41,15 @@ export default function AuxiliaryEdit(props) {
|
|||||||
if (currentObject) {
|
if (currentObject) {
|
||||||
copy(
|
copy(
|
||||||
currentObject,
|
currentObject,
|
||||||
arrow2 ? (arrow2 === '←' ? Number(+horizonSize / 10) * -1 : Number(+horizonSize / 10)) : 0,
|
arrow2 ? (arrow2 === '←' ? (Number(normalizeDigits(horizonSize)) / 10) * -1 : Number(normalizeDigits(horizonSize)) / 10) : 0,
|
||||||
arrow1 ? (arrow1 === '↑' ? Number(+verticalSize / 10) * -1 : Number(+verticalSize / 10)) : 0,
|
arrow1 ? (arrow1 === '↑' ? (Number(normalizeDigits(verticalSize)) / 10) * -1 : Number(normalizeDigits(verticalSize)) / 10) : 0,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
move(
|
move(
|
||||||
currentObject,
|
currentObject,
|
||||||
arrow2 ? (arrow2 === '←' ? Number(+horizonSize / 10) * -1 : Number(+horizonSize / 10)) : 0,
|
arrow2 ? (arrow2 === '←' ? (Number(normalizeDigits(horizonSize)) / 10) * -1 : Number(normalizeDigits(horizonSize)) / 10) : 0,
|
||||||
arrow1 ? (arrow1 === '↑' ? Number(+verticalSize / 10) * -1 : Number(+verticalSize / 10)) : 0,
|
arrow1 ? (arrow1 === '↑' ? (Number(normalizeDigits(verticalSize)) / 10) * -1 : Number(normalizeDigits(verticalSize)) / 10) : 0,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +66,7 @@ export default function AuxiliaryEdit(props) {
|
|||||||
<p className="mb5">{getMessage('length')}</p>
|
<p className="mb5">{getMessage('length')}</p>
|
||||||
<div className="input-move-wrap mb5">
|
<div className="input-move-wrap mb5">
|
||||||
<div className="input-move">
|
<div className="input-move">
|
||||||
<input type="text" className="input-origin" value={verticalSize} onChange={(e) => setVerticalSize(e.target.value)} />
|
<input type="text" className="input-origin" value={verticalSize} onChange={(e) => setVerticalSize(normalizeDigits(e.target.value))} />
|
||||||
</div>
|
</div>
|
||||||
<span>mm</span>
|
<span>mm</span>
|
||||||
<div className="direction-move-wrap">
|
<div className="direction-move-wrap">
|
||||||
@ -87,7 +88,7 @@ export default function AuxiliaryEdit(props) {
|
|||||||
</div>
|
</div>
|
||||||
<div className="input-move-wrap">
|
<div className="input-move-wrap">
|
||||||
<div className="input-move">
|
<div className="input-move">
|
||||||
<input type="text" className="input-origin" value={horizonSize} onChange={(e) => setHorizonSize(e.target.value)} />
|
<input type="text" className="input-origin" value={horizonSize} onChange={(e) => setHorizonSize(normalizeDigits(e.target.value))} />
|
||||||
</div>
|
</div>
|
||||||
<span>mm</span>
|
<span>mm</span>
|
||||||
<div className="direction-move-wrap">
|
<div className="direction-move-wrap">
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import { canvasState, currentObjectState } from '@/store/canvasAtom'
|
|||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import Big from 'big.js'
|
import Big from 'big.js'
|
||||||
import { calcLineActualSize, calcLinePlaneSize } from '@/util/qpolygon-utils'
|
import { calcLineActualSize, calcLinePlaneSize } from '@/util/qpolygon-utils'
|
||||||
|
import { normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function AuxiliarySize(props) {
|
export default function AuxiliarySize(props) {
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
@ -42,7 +43,8 @@ export default function AuxiliarySize(props) {
|
|||||||
if (checkedRadio === 2) setValue2(value)
|
if (checkedRadio === 2) setValue2(value)
|
||||||
setSize(0)
|
setSize(0)
|
||||||
} else {
|
} else {
|
||||||
value = Big(value.replace(/[^0-9]/g, ''))
|
//value = Big(value.replace(/[^0-9]/g, ''))
|
||||||
|
value = Big(normalizeDigits(value))
|
||||||
if (checkedRadio === 1) setValue1(value.toNumber())
|
if (checkedRadio === 1) setValue1(value.toNumber())
|
||||||
if (checkedRadio === 2) setValue2(value.toNumber())
|
if (checkedRadio === 2) setValue2(value.toNumber())
|
||||||
setSize(value.div(10).toNumber())
|
setSize(value.div(10).toNumber())
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import { useDebounceValue } from 'usehooks-ts'
|
|||||||
import { moduleSelectionDataState } from '@/store/selectedModuleOptions'
|
import { moduleSelectionDataState } from '@/store/selectedModuleOptions'
|
||||||
import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController'
|
import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController'
|
||||||
import { isObjectNotEmpty } from '@/util/common-utils'
|
import { isObjectNotEmpty } from '@/util/common-utils'
|
||||||
|
import { normalizeDecimal} from '@/util/input-utils'
|
||||||
|
|
||||||
export default function Module({ setTabNum }) {
|
export default function Module({ setTabNum }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -188,7 +189,7 @@ export default function Module({ setTabNum }) {
|
|||||||
type="text"
|
type="text"
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
value={inputInstallHeight}
|
value={inputInstallHeight}
|
||||||
onChange={(e) => setInputInstallHeight(e.target.value)}
|
onChange={(e) => setInputInstallHeight(normalizeDecimal(e.target.value))}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">m</span>
|
<span className="thin">m</span>
|
||||||
@ -225,7 +226,7 @@ export default function Module({ setTabNum }) {
|
|||||||
type="text"
|
type="text"
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
value={inputVerticalSnowCover}
|
value={inputVerticalSnowCover}
|
||||||
onChange={(e) => setInputVerticalSnowCover(e.target.value)}
|
onChange={(e) => setInputVerticalSnowCover(normalizeDecimal(e.target.value))}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">cm</span>
|
<span className="thin">cm</span>
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import QSelectBox from '@/components/common/select/QSelectBox'
|
|||||||
import { roofsState } from '@/store/roofAtom'
|
import { roofsState } from '@/store/roofAtom'
|
||||||
import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting'
|
import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting'
|
||||||
import Swal from 'sweetalert2'
|
import Swal from 'sweetalert2'
|
||||||
|
import { normalizeDecimal} from '@/util/input-utils'
|
||||||
|
|
||||||
export const Orientation = forwardRef((props, ref) => {
|
export const Orientation = forwardRef((props, ref) => {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -177,9 +178,10 @@ export const Orientation = forwardRef((props, ref) => {
|
|||||||
setInputCompasDeg('-0')
|
setInputCompasDeg('-0')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (Number(e) >= -180 && Number(e) <= 180) {
|
const n = Number(normalizeDecimal(e))
|
||||||
if (numberCheck(Number(e))) {
|
if (n >= -180 && n <= 180) {
|
||||||
setInputCompasDeg(Number(e))
|
if (numberCheck(n)) {
|
||||||
|
setInputCompasDeg(n)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setInputCompasDeg(compasDeg)
|
setInputCompasDeg(compasDeg)
|
||||||
@ -398,7 +400,7 @@ export const Orientation = forwardRef((props, ref) => {
|
|||||||
<div className="outline-form mt15">
|
<div className="outline-form mt15">
|
||||||
<span>{getMessage('modal.module.basic.setting.module.placement.area')}</span>
|
<span>{getMessage('modal.module.basic.setting.module.placement.area')}</span>
|
||||||
<div className="input-grid mr10" style={{ width: '60px' }}>
|
<div className="input-grid mr10" style={{ width: '60px' }}>
|
||||||
<input type="number" className="input-origin block" value={inputMargin} onChange={(e) => setInputMargin(e.target.value)} />
|
<input type="text" className="input-origin block" value={inputMargin} onChange={(e) => setInputMargin(normalizeDecimal(e.target.value))} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">m</span>
|
<span className="thin">m</span>
|
||||||
</div>
|
</div>
|
||||||
@ -427,10 +429,10 @@ export const Orientation = forwardRef((props, ref) => {
|
|||||||
<span>{getMessage('modal.module.basic.setting.module.fitting.height')}</span>
|
<span>{getMessage('modal.module.basic.setting.module.fitting.height')}</span>
|
||||||
<div className="input-grid mr10">
|
<div className="input-grid mr10">
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="text"
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
value={inputInstallHeight}
|
value={inputInstallHeight}
|
||||||
onChange={(e) => handleChangeInstallHeight(e.target.value)}
|
onChange={(e) => handleChangeInstallHeight(normalizeDecimal(e.target.value))}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">m</span>
|
<span className="thin">m</span>
|
||||||
@ -455,10 +457,10 @@ export const Orientation = forwardRef((props, ref) => {
|
|||||||
<span>{getMessage('modal.module.basic.setting.module.standard.snowfall.amount')}</span>
|
<span>{getMessage('modal.module.basic.setting.module.standard.snowfall.amount')}</span>
|
||||||
<div className="input-grid mr10">
|
<div className="input-grid mr10">
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="text"
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
value={inputVerticalSnowCover}
|
value={inputVerticalSnowCover}
|
||||||
onChange={(e) => handleChangeVerticalSnowCover(e.target.value)}
|
onChange={(e) => handleChangeVerticalSnowCover(normalizeDecimal(e.target.value))}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">cm</span>
|
<span className="thin">cm</span>
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import {
|
|||||||
import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil'
|
import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil'
|
||||||
import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions'
|
import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions'
|
||||||
import { isObjectNotEmpty } from '@/util/common-utils'
|
import { isObjectNotEmpty } from '@/util/common-utils'
|
||||||
|
import { normalizeDigits } from '@/util/input-utils'
|
||||||
import Image from 'next/image'
|
import Image from 'next/image'
|
||||||
|
|
||||||
const Placement = forwardRef((props, refs) => {
|
const Placement = forwardRef((props, refs) => {
|
||||||
@ -155,7 +156,7 @@ const Placement = forwardRef((props, refs) => {
|
|||||||
newLayoutSetup[index] = {
|
newLayoutSetup[index] = {
|
||||||
...newLayoutSetup[index],
|
...newLayoutSetup[index],
|
||||||
moduleId: itemId,
|
moduleId: itemId,
|
||||||
[e.target.name]: Number(e.target.value),
|
[e.target.name]: Number(normalizeDigits(e.target.value)),
|
||||||
}
|
}
|
||||||
props.setLayoutSetup(newLayoutSetup)
|
props.setLayoutSetup(newLayoutSetup)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedM
|
|||||||
import { forwardRef, useContext, useEffect, useImperativeHandle, useRef, useState } from 'react'
|
import { forwardRef, useContext, useEffect, useImperativeHandle, useRef, useState } from 'react'
|
||||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||||
import Swal from 'sweetalert2'
|
import Swal from 'sweetalert2'
|
||||||
|
import { normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
const Trestle = forwardRef((props, ref) => {
|
const Trestle = forwardRef((props, ref) => {
|
||||||
const { tabNum, setTabNum, trestleTrigger, roofs, setRoofs, moduleSelectionData, setModuleSelectionData, setRoofsStore } = props
|
const { tabNum, setTabNum, trestleTrigger, roofs, setRoofs, moduleSelectionData, setModuleSelectionData, setRoofsStore } = props
|
||||||
@ -558,7 +559,19 @@ const Trestle = forwardRef((props, ref) => {
|
|||||||
type="text"
|
type="text"
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
value={lengthBase}
|
value={lengthBase}
|
||||||
onChange={(e) => onChangeLength(e.target.value)}
|
onChange={(e) => {
|
||||||
|
const v = e.target.value
|
||||||
|
if (v === '') {
|
||||||
|
onChangeLength('')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const n = Number(normalizeDigits(v))
|
||||||
|
if (Number.isNaN(n)) {
|
||||||
|
onChangeLength('')
|
||||||
|
} else {
|
||||||
|
onChangeLength(n)
|
||||||
|
}
|
||||||
|
}}
|
||||||
disabled={selectedRoof.lenAuth === 'R'}
|
disabled={selectedRoof.lenAuth === 'R'}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -598,7 +611,19 @@ const Trestle = forwardRef((props, ref) => {
|
|||||||
type="text"
|
type="text"
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
disabled={selectedRoof.roofPchAuth === 'R'}
|
disabled={selectedRoof.roofPchAuth === 'R'}
|
||||||
onChange={(e) => onChangeHajebichi(e.target.value)}
|
onChange={(e) => {
|
||||||
|
const v = e.target.value
|
||||||
|
if (v === '') {
|
||||||
|
onChangeHajebichi('')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const n = Number(normalizeDigits(v))
|
||||||
|
if (Number.isNaN(n)) {
|
||||||
|
onChangeHajebichi('')
|
||||||
|
} else {
|
||||||
|
onChangeHajebichi(n)
|
||||||
|
}
|
||||||
|
}}
|
||||||
value={hajebichi}
|
value={hajebichi}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import { selectedModuleState } from '@/store/selectedModuleOptions'
|
|||||||
import { circuitNumDisplaySelector } from '@/store/settingAtom'
|
import { circuitNumDisplaySelector } from '@/store/settingAtom'
|
||||||
import { useContext, useEffect, useState } from 'react'
|
import { useContext, useEffect, useState } from 'react'
|
||||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||||
|
import { normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function PassivityCircuitAllocation(props) {
|
export default function PassivityCircuitAllocation(props) {
|
||||||
const {
|
const {
|
||||||
@ -580,7 +581,20 @@ export default function PassivityCircuitAllocation(props) {
|
|||||||
value={circuitNumber}
|
value={circuitNumber}
|
||||||
min={1}
|
min={1}
|
||||||
max={99}
|
max={99}
|
||||||
onChange={(e) => setCircuitNumber(e.target.value)}
|
onChange={(e) => {
|
||||||
|
const v = e.target.value
|
||||||
|
if (v === '') {
|
||||||
|
setCircuitNumber('')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const n = Number(normalizeDigits(v))
|
||||||
|
if (Number.isNaN(n)) {
|
||||||
|
setCircuitNumber('')
|
||||||
|
} else {
|
||||||
|
const clamped = Math.max(1, Math.min(99, n))
|
||||||
|
setCircuitNumber(clamped)
|
||||||
|
}
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button className="btn-frame roof" onClick={() => handleCircuitNumberFix()}>
|
<button className="btn-frame roof" onClick={() => handleCircuitNumberFix()}>
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import { defaultSlope } from '@/store/commonAtom'
|
|||||||
import { re } from 'mathjs'
|
import { re } from 'mathjs'
|
||||||
import { basicSettingState } from '@/store/settingAtom'
|
import { basicSettingState } from '@/store/settingAtom'
|
||||||
import { getChonByDegree, getDegreeByChon } from '@/util/canvas-util'
|
import { getChonByDegree, getDegreeByChon } from '@/util/canvas-util'
|
||||||
|
import { normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function DimensionLineSetting(props) {
|
export default function DimensionLineSetting(props) {
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
@ -144,8 +145,13 @@ export default function DimensionLineSetting(props) {
|
|||||||
defaultValue={''}
|
defaultValue={''}
|
||||||
value={changeLength}
|
value={changeLength}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
console.log(e.target)
|
const v = e.target.value
|
||||||
setChangeLength(e.target.value)
|
if (v === '') {
|
||||||
|
setChangeLength('')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const n = Number(normalizeDigits(v))
|
||||||
|
setChangeLength(Number.isNaN(n) ? '' : n)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import Image from 'next/image'
|
|||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { useRecoilValue } from 'recoil'
|
import { useRecoilValue } from 'recoil'
|
||||||
import { ANGLE_TYPE, currentAngleTypeSelector } from '@/store/canvasAtom'
|
import { ANGLE_TYPE, currentAngleTypeSelector } from '@/store/canvasAtom'
|
||||||
|
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function Eaves({ pitchRef, offsetRef, widthRef, radioTypeRef, pitchText }) {
|
export default function Eaves({ pitchRef, offsetRef, widthRef, radioTypeRef, pitchText }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -20,7 +21,17 @@ export default function Eaves({ pitchRef, offsetRef, widthRef, radioTypeRef, pit
|
|||||||
{getMessage('slope')}
|
{getMessage('slope')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" defaultValue={currentAngleType === ANGLE_TYPE.SLOPE ? 4 : 21.8} ref={pitchRef} />
|
<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
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">{pitchText}</span>
|
<span className="thin">{pitchText}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -29,7 +40,17 @@ export default function Eaves({ pitchRef, offsetRef, widthRef, radioTypeRef, pit
|
|||||||
{getMessage('offset')}
|
{getMessage('offset')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" defaultValue={500} ref={offsetRef} />
|
<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
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -66,7 +87,18 @@ export default function Eaves({ pitchRef, offsetRef, widthRef, radioTypeRef, pit
|
|||||||
<div className="eaves-keraba-th">
|
<div className="eaves-keraba-th">
|
||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="number" min={0} className="input-origin block" defaultValue={500} ref={widthRef} readOnly={type === '1'} />
|
<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
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -4,10 +4,10 @@ import { useEffect, useState } from 'react'
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { canvasState } from '@/store/canvasAtom'
|
import { canvasState } from '@/store/canvasAtom'
|
||||||
import { useRecoilValue } from 'recoil'
|
import { useRecoilValue } from 'recoil'
|
||||||
import { onlyNumberInputChange } from '@/util/input-utils'
|
|
||||||
import { usePopup } from '@/hooks/usePopup'
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
import { useCanvasSetting } from '@/hooks/option/useCanvasSetting'
|
import { useCanvasSetting } from '@/hooks/option/useCanvasSetting'
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
|
import { normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
const TYPE = {
|
const TYPE = {
|
||||||
DOT: 'DOT',
|
DOT: 'DOT',
|
||||||
@ -218,7 +218,7 @@ export default function DotLineGrid(props) {
|
|||||||
className="input-origin"
|
className="input-origin"
|
||||||
name={`horizontalInterval`}
|
name={`horizontalInterval`}
|
||||||
value={copyCurrentSetting.INTERVAL.horizontalInterval}
|
value={copyCurrentSetting.INTERVAL.horizontalInterval}
|
||||||
onChange={(e) => onlyNumberInputChange(e, changeInput)}
|
onChange={(e) => changeInput(normalizeDigits(e.target.value), e)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span>mm</span>
|
<span>mm</span>
|
||||||
@ -231,7 +231,7 @@ export default function DotLineGrid(props) {
|
|||||||
className="input-origin"
|
className="input-origin"
|
||||||
name={`verticalInterval`}
|
name={`verticalInterval`}
|
||||||
value={copyCurrentSetting.INTERVAL.verticalInterval}
|
value={copyCurrentSetting.INTERVAL.verticalInterval}
|
||||||
onChange={(e) => onlyNumberInputChange(e, changeInput)}
|
onChange={(e) => changeInput(normalizeDigits(e.target.value), e)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span>mm</span>
|
<span>mm</span>
|
||||||
@ -258,7 +258,7 @@ export default function DotLineGrid(props) {
|
|||||||
className="input-origin"
|
className="input-origin"
|
||||||
name={`ratioInterval`}
|
name={`ratioInterval`}
|
||||||
value={copyCurrentSetting.INTERVAL.ratioInterval}
|
value={copyCurrentSetting.INTERVAL.ratioInterval}
|
||||||
onChange={(e) => onlyNumberInputChange(e, changeInput)}
|
onChange={(e) => changeInput(normalizeDigits(e.target.value), e)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span>mm</span>
|
<span>mm</span>
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import { contextPopupPositionState } from '@/store/popupAtom'
|
|||||||
import { canvasState, currentObjectState } from '@/store/canvasAtom'
|
import { canvasState, currentObjectState } from '@/store/canvasAtom'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
|
import { normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function GridMove(props) {
|
export default function GridMove(props) {
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
@ -50,15 +51,15 @@ export default function GridMove(props) {
|
|||||||
.forEach((grid) => {
|
.forEach((grid) => {
|
||||||
move(
|
move(
|
||||||
grid,
|
grid,
|
||||||
arrow2 === '←' ? (Number(horizonSize) * -1) / 10 : Number(horizonSize) / 10,
|
arrow2 === '←' ? (Number(normalizeDigits(horizonSize)) * -1) / 10 : Number(normalizeDigits(horizonSize)) / 10,
|
||||||
arrow1 === '↑' ? (Number(verticalSize) * -1) / 10 : Number(verticalSize) / 10,
|
arrow1 === '↑' ? (Number(normalizeDigits(verticalSize)) * -1) / 10 : Number(normalizeDigits(verticalSize)) / 10,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
move(
|
move(
|
||||||
currentObject,
|
currentObject,
|
||||||
arrow2 === '←' ? (Number(horizonSize) * -1) / 10 : Number(horizonSize) / 10,
|
arrow2 === '←' ? (Number(normalizeDigits(horizonSize)) * -1) / 10 : Number(normalizeDigits(horizonSize)) / 10,
|
||||||
arrow1 === '↑' ? (Number(verticalSize) * -1) / 10 : Number(verticalSize) / 10,
|
arrow1 === '↑' ? (Number(normalizeDigits(verticalSize)) * -1) / 10 : Number(normalizeDigits(verticalSize)) / 10,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
@ -97,7 +98,7 @@ export default function GridMove(props) {
|
|||||||
type="text"
|
type="text"
|
||||||
className="input-origin"
|
className="input-origin"
|
||||||
value={verticalSize}
|
value={verticalSize}
|
||||||
onChange={(e) => setVerticalSize(e.target.value)}
|
onChange={(e) => setVerticalSize(normalizeDigits(e.target.value))}
|
||||||
readOnly={!isAll && currentObject?.direction === 'vertical'}
|
readOnly={!isAll && currentObject?.direction === 'vertical'}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -125,7 +126,7 @@ export default function GridMove(props) {
|
|||||||
type="text"
|
type="text"
|
||||||
className="input-origin"
|
className="input-origin"
|
||||||
value={horizonSize}
|
value={horizonSize}
|
||||||
onChange={(e) => setHorizonSize(e.target.value)}
|
onChange={(e) => setHorizonSize(normalizeDigits(e.target.value))}
|
||||||
readOnly={!isAll && currentObject?.direction === 'horizontal'}
|
readOnly={!isAll && currentObject?.direction === 'horizontal'}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import Image from 'next/image'
|
import Image from 'next/image'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils'
|
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function Angle({ props }) {
|
export default function Angle({ props }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -20,7 +20,7 @@ export default function Angle({ props }) {
|
|||||||
value={angle1}
|
value={angle1}
|
||||||
ref={angle1Ref}
|
ref={angle1Ref}
|
||||||
onFocus={(e) => (angle1Ref.current.value = '')}
|
onFocus={(e) => (angle1Ref.current.value = '')}
|
||||||
onChange={(e) => onlyNumberWithDotInputChange(e, setAngle1)}
|
onChange={(e) => setAngle1(normalizeDecimalLimit(e.target.value, 2))}
|
||||||
placeholder="45"
|
placeholder="45"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -40,7 +40,7 @@ export default function Angle({ props }) {
|
|||||||
value={length1}
|
value={length1}
|
||||||
ref={length1Ref}
|
ref={length1Ref}
|
||||||
onFocus={(e) => (length1Ref.current.value = '')}
|
onFocus={(e) => (length1Ref.current.value = '')}
|
||||||
onChange={(e) => onlyNumberInputChange(e, setLength1)}
|
onChange={(e) => setLength1(normalizeDigits(e.target.value))}
|
||||||
placeholder="3000"
|
placeholder="3000"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { onlyNumberInputChange } from '@/util/input-utils'
|
import { normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function Diagonal({ props }) {
|
export default function Diagonal({ props }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -36,7 +36,7 @@ export default function Diagonal({ props }) {
|
|||||||
value={outerLineDiagonalLength}
|
value={outerLineDiagonalLength}
|
||||||
ref={outerLineDiagonalLengthRef}
|
ref={outerLineDiagonalLengthRef}
|
||||||
onFocus={(e) => (outerLineDiagonalLengthRef.current.value = '')}
|
onFocus={(e) => (outerLineDiagonalLengthRef.current.value = '')}
|
||||||
onChange={(e) => onlyNumberInputChange(e, setOuterLineDiagonalLength)}
|
onChange={(e) => setOuterLineDiagonalLength(normalizeDigits(e.target.value))}
|
||||||
placeholder="3000"
|
placeholder="3000"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -58,7 +58,7 @@ export default function Diagonal({ props }) {
|
|||||||
value={length1}
|
value={length1}
|
||||||
ref={length1Ref}
|
ref={length1Ref}
|
||||||
onFocus={(e) => (length1Ref.current.value = '')}
|
onFocus={(e) => (length1Ref.current.value = '')}
|
||||||
onChange={(e) => onlyNumberInputChange(e, setLength1)}
|
onChange={(e) => setLength1(normalizeDigits(e.target.value))}
|
||||||
placeholder="3000"
|
placeholder="3000"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -115,7 +115,7 @@ export default function Diagonal({ props }) {
|
|||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
value={length2}
|
value={length2}
|
||||||
ref={length2Ref}
|
ref={length2Ref}
|
||||||
onChange={(e) => onlyNumberInputChange(e, setLength2)}
|
onChange={(e) => setLength2(normalizeDigits(e.target.value))}
|
||||||
readOnly={true}
|
readOnly={true}
|
||||||
placeholder="3000"
|
placeholder="3000"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils'
|
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
||||||
import { getDegreeByChon } from '@/util/canvas-util'
|
import { getDegreeByChon } from '@/util/canvas-util'
|
||||||
|
|
||||||
export default function DoublePitch({ props }) {
|
export default function DoublePitch({ props }) {
|
||||||
@ -56,7 +56,7 @@ export default function DoublePitch({ props }) {
|
|||||||
value={angle1}
|
value={angle1}
|
||||||
ref={angle1Ref}
|
ref={angle1Ref}
|
||||||
onFocus={(e) => (angle1Ref.current.value = '')}
|
onFocus={(e) => (angle1Ref.current.value = '')}
|
||||||
onChange={(e) => onlyNumberWithDotInputChange(e, setAngle1)}
|
onChange={(e) => setAngle1(normalizeDecimalLimit(e.target.value, 2))}
|
||||||
placeholder="45"
|
placeholder="45"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -73,7 +73,7 @@ export default function DoublePitch({ props }) {
|
|||||||
value={length1}
|
value={length1}
|
||||||
ref={length1Ref}
|
ref={length1Ref}
|
||||||
onFocus={(e) => (length1Ref.current.value = '')}
|
onFocus={(e) => (length1Ref.current.value = '')}
|
||||||
onChange={(e) => onlyNumberInputChange(e, setLength1)}
|
onChange={(e) => setLength1(normalizeDigits(e.target.value))}
|
||||||
placeholder="3000"
|
placeholder="3000"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -132,7 +132,8 @@ export default function DoublePitch({ props }) {
|
|||||||
ref={angle2Ref}
|
ref={angle2Ref}
|
||||||
onFocus={(e) => (angle2Ref.current.value = '')}
|
onFocus={(e) => (angle2Ref.current.value = '')}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
onlyNumberWithDotInputChange(e, setAngle2)
|
const v = normalizeDecimalLimit(e.target.value, 2)
|
||||||
|
setAngle2(v)
|
||||||
setLength2(getLength2())
|
setLength2(getLength2())
|
||||||
}}
|
}}
|
||||||
placeholder="45"
|
placeholder="45"
|
||||||
@ -156,7 +157,7 @@ export default function DoublePitch({ props }) {
|
|||||||
value={length2}
|
value={length2}
|
||||||
ref={length2Ref}
|
ref={length2Ref}
|
||||||
onFocus={(e) => (length2Ref.current.value = '')}
|
onFocus={(e) => (length2Ref.current.value = '')}
|
||||||
onChange={(e) => onlyNumberInputChange(e, setLength2)}
|
onChange={(e) => setLength2(normalizeDigits(e.target.value))}
|
||||||
readOnly={true}
|
readOnly={true}
|
||||||
placeholder="3000"
|
placeholder="3000"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { onlyNumberInputChange } from '@/util/input-utils'
|
import { normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function OuterLineWall({ props }) {
|
export default function OuterLineWall({ props }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -23,7 +23,7 @@ export default function OuterLineWall({ props }) {
|
|||||||
length1Ref.current.value = ''
|
length1Ref.current.value = ''
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onChange={(e) => onlyNumberInputChange(e, setLength1)}
|
onChange={(e) => setLength1(normalizeDigits(e.target.value))}
|
||||||
placeholder="3000"
|
placeholder="3000"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { onlyNumberInputChange } from '@/util/input-utils'
|
import { normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function RightAngle({ props }) {
|
export default function RightAngle({ props }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -28,7 +28,7 @@ export default function RightAngle({ props }) {
|
|||||||
value={length1}
|
value={length1}
|
||||||
ref={length1Ref}
|
ref={length1Ref}
|
||||||
onFocus={(e) => (length1Ref.current.value = '')}
|
onFocus={(e) => (length1Ref.current.value = '')}
|
||||||
onChange={(e) => onlyNumberInputChange(e, setLength1)}
|
onChange={(e) => setLength1(normalizeDigits(e.target.value))}
|
||||||
placeholder="3000"
|
placeholder="3000"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -84,7 +84,7 @@ export default function RightAngle({ props }) {
|
|||||||
value={length2}
|
value={length2}
|
||||||
ref={length2Ref}
|
ref={length2Ref}
|
||||||
onFocus={(e) => (length2Ref.current.value = '')}
|
onFocus={(e) => (length2Ref.current.value = '')}
|
||||||
onChange={(e) => onlyNumberInputChange(e, setLength2)}
|
onChange={(e) => setLength2(normalizeDigits(e.target.value))}
|
||||||
placeholder="3000"
|
placeholder="3000"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { useMessage } from '@/hooks/useMessage'
|
|||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { useRecoilValue } from 'recoil'
|
import { useRecoilValue } from 'recoil'
|
||||||
import { currentObjectState } from '@/store/canvasAtom'
|
import { currentObjectState } from '@/store/canvasAtom'
|
||||||
|
import { normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
const UP_DOWN_TYPE = {
|
const UP_DOWN_TYPE = {
|
||||||
UP: 'up',
|
UP: 'up',
|
||||||
@ -22,7 +23,8 @@ export default function Updown({ UP_DOWN_REF }) {
|
|||||||
}
|
}
|
||||||
const handleInput = (e) => {
|
const handleInput = (e) => {
|
||||||
const value = e.target.value.replace(/^0+/, '')
|
const value = e.target.value.replace(/^0+/, '')
|
||||||
setFilledInput(value.replace(/[^0-9]/g, ''))
|
//setFilledInput(value.replace(/[^0-9]/g, ''))
|
||||||
|
setFilledInput(normalizeDigits(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import Shadow from '@/components/floor-plan/modal/object/type/Shadow'
|
|||||||
import TriangleDormer from '@/components/floor-plan/modal/object/type/TriangleDormer'
|
import TriangleDormer from '@/components/floor-plan/modal/object/type/TriangleDormer'
|
||||||
import PentagonDormer from '@/components/floor-plan/modal/object/type/PentagonDormer'
|
import PentagonDormer from '@/components/floor-plan/modal/object/type/PentagonDormer'
|
||||||
import { usePopup } from '@/hooks/usePopup'
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
|
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function ObjectSetting({ id, pos = { x: 50, y: 230 } }) {
|
export default function ObjectSetting({ id, pos = { x: 50, y: 230 } }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -61,20 +62,20 @@ export default function ObjectSetting({ id, pos = { x: 50, y: 230 } }) {
|
|||||||
if (buttonAct === 1 || buttonAct === 2) {
|
if (buttonAct === 1 || buttonAct === 2) {
|
||||||
applyOpeningAndShadow(objectPlacement, buttonAct)
|
applyOpeningAndShadow(objectPlacement, buttonAct)
|
||||||
} else {
|
} else {
|
||||||
const height = dormerPlacement.heightRef.current !== null ? dormerPlacement.heightRef.current.value / 10 : 0
|
const height = dormerPlacement.heightRef.current !== null ? Number(normalizeDigits(dormerPlacement.heightRef.current.value)) / 10 : 0
|
||||||
const width = dormerPlacement.widthRef.current !== null ? dormerPlacement.widthRef.current.value / 10 : 0 //triangle일때는 없음
|
const width = dormerPlacement.widthRef.current !== null ? Number(normalizeDigits(dormerPlacement.widthRef.current.value)) / 10 : 0 //triangle일때는 없음
|
||||||
const pitch = dormerPlacement.pitchRef.current !== null ? Number(dormerPlacement.pitchRef.current.value) : 0
|
const pitch = dormerPlacement.pitchRef.current !== null ? Number(normalizeDecimalLimit(dormerPlacement.pitchRef.current.value, 2)) : 0
|
||||||
const offsetRef =
|
const offsetRef =
|
||||||
dormerPlacement.offsetRef.current !== null
|
dormerPlacement.offsetRef.current !== null
|
||||||
? dormerPlacement.offsetRef.current.value === ''
|
? dormerPlacement.offsetRef.current.value === ''
|
||||||
? 0
|
? 0
|
||||||
: parseInt(dormerPlacement.offsetRef.current.value) / 10
|
: Number(normalizeDigits(dormerPlacement.offsetRef.current.value)) / 10
|
||||||
: 0
|
: 0
|
||||||
const offsetWidthRef =
|
const offsetWidthRef =
|
||||||
dormerPlacement.offsetWidthRef.current !== null
|
dormerPlacement.offsetWidthRef.current !== null
|
||||||
? dormerPlacement.offsetWidthRef.current.value === ''
|
? dormerPlacement.offsetWidthRef.current.value === ''
|
||||||
? 0
|
? 0
|
||||||
: parseInt(dormerPlacement.offsetWidthRef.current.value) / 10
|
: Number(normalizeDigits(dormerPlacement.offsetWidthRef.current.value)) / 10
|
||||||
: 0
|
: 0
|
||||||
const directionRef = dormerPlacement.directionRef.current
|
const directionRef = dormerPlacement.directionRef.current
|
||||||
|
|
||||||
|
|||||||
@ -14,12 +14,12 @@ import { useCommonCode } from '@/hooks/common/useCommonCode'
|
|||||||
import QSelectBox from '@/components/common/select/QSelectBox'
|
import QSelectBox from '@/components/common/select/QSelectBox'
|
||||||
import { globalLocaleStore } from '@/store/localeAtom'
|
import { globalLocaleStore } from '@/store/localeAtom'
|
||||||
|
|
||||||
import { onlyNumberInputChange } from '@/util/input-utils'
|
|
||||||
import { getChonByDegree, getDegreeByChon } from '@/util/canvas-util'
|
import { getChonByDegree, getDegreeByChon } from '@/util/canvas-util'
|
||||||
import { usePolygon } from '@/hooks/usePolygon'
|
import { usePolygon } from '@/hooks/usePolygon'
|
||||||
import { canvasState } from '@/store/canvasAtom'
|
import { canvasState } from '@/store/canvasAtom'
|
||||||
import { useRoofFn } from '@/hooks/common/useRoofFn'
|
import { useRoofFn } from '@/hooks/common/useRoofFn'
|
||||||
import { usePlan } from '@/hooks/usePlan'
|
import { usePlan } from '@/hooks/usePlan'
|
||||||
|
import { normalizeDecimal, normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 지붕 레이아웃
|
* 지붕 레이아웃
|
||||||
@ -182,7 +182,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla
|
|||||||
*/
|
*/
|
||||||
const changeInput = (value, e) => {
|
const changeInput = (value, e) => {
|
||||||
const { name } = e.target
|
const { name } = e.target
|
||||||
setCurrentRoof({ ...currentRoof, [name]: Number(value) })
|
setCurrentRoof({ ...currentRoof, [name]: Number(normalizeDecimal(value)) })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -325,15 +325,21 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla
|
|||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5">
|
<div className="input-grid mr5">
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="text"
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
readOnly={currentRoof?.roofAngleSet !== item.value}
|
readOnly={currentRoof?.roofAngleSet !== item.value}
|
||||||
value={index === 0 ? (currentRoof?.pitch || '0') : (currentRoof?.angle || '0')}
|
value={index === 0 ? (currentRoof?.pitch || '0') : (currentRoof?.angle || '0')}
|
||||||
onChange={(e) =>
|
onChange={(e) => {
|
||||||
index === 0
|
const v = normalizeDecimal(e.target.value)
|
||||||
? setCurrentRoof({ ...currentRoof, pitch: e.target.value * 1, angle: getDegreeByChon(e.target.value * 1) })
|
e.target.value = v
|
||||||
: setCurrentRoof({ ...currentRoof, pitch: getChonByDegree(e.target.value*1), angle: e.target.value * 1})
|
if (index === 0) {
|
||||||
}
|
const num = v === '' ? '' : Number(v)
|
||||||
|
setCurrentRoof({ ...currentRoof, pitch: num === '' ? '' : num, angle: num === '' ? '' : getDegreeByChon(num) })
|
||||||
|
} else {
|
||||||
|
const num = v === '' ? '' : Number(v)
|
||||||
|
setCurrentRoof({ ...currentRoof, pitch: num === '' ? '' : getChonByDegree(num), angle: num === '' ? '' : num })
|
||||||
|
}
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">{index === 0 ? '寸' : '度'}</span>
|
<span className="thin">{index === 0 ? '寸' : '度'}</span>
|
||||||
@ -381,7 +387,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla
|
|||||||
name={`width`}
|
name={`width`}
|
||||||
ref={roofRef.width}
|
ref={roofRef.width}
|
||||||
value={parseInt(currentRoof?.width)}
|
value={parseInt(currentRoof?.width)}
|
||||||
onChange={(e) => onlyNumberInputChange(e, changeInput)}
|
onChange={(e) => changeInput(normalizeDigits(e.target.value), e)}
|
||||||
readOnly={currentRoof?.widAuth === 'R'}
|
readOnly={currentRoof?.widAuth === 'R'}
|
||||||
disabled={currentRoof?.roofSizeSet === '3'}
|
disabled={currentRoof?.roofSizeSet === '3'}
|
||||||
/>
|
/>
|
||||||
@ -398,7 +404,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla
|
|||||||
name={`length`}
|
name={`length`}
|
||||||
ref={roofRef.length}
|
ref={roofRef.length}
|
||||||
value={parseInt(currentRoof?.length)}
|
value={parseInt(currentRoof?.length)}
|
||||||
onChange={(e) => onlyNumberInputChange(e, changeInput)}
|
onChange={(e) => changeInput(normalizeDigits(e.target.value), e)}
|
||||||
readOnly={currentRoof?.lenAuth === 'R'}
|
readOnly={currentRoof?.lenAuth === 'R'}
|
||||||
disabled={currentRoof?.roofSizeSet === '3'}
|
disabled={currentRoof?.roofSizeSet === '3'}
|
||||||
/>
|
/>
|
||||||
@ -437,7 +443,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla
|
|||||||
name={`hajebichi`}
|
name={`hajebichi`}
|
||||||
ref={roofRef.hajebichi}
|
ref={roofRef.hajebichi}
|
||||||
value={parseInt(currentRoof?.hajebichi)}
|
value={parseInt(currentRoof?.hajebichi)}
|
||||||
onChange={(e) => onlyNumberInputChange(e, changeInput)}
|
onChange={(e) => changeInput(normalizeDigits(e.target.value), e)}
|
||||||
readOnly={currentRoof?.roofPchAuth === 'R'}
|
readOnly={currentRoof?.roofPchAuth === 'R'}
|
||||||
disabled={currentRoof?.roofSizeSet === '3'}
|
disabled={currentRoof?.roofSizeSet === '3'}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import { useEffect, useState } from 'react'
|
|||||||
import { currentObjectState } from '@/store/canvasAtom'
|
import { currentObjectState } from '@/store/canvasAtom'
|
||||||
import { useRoofAllocationSetting } from '@/hooks/roofcover/useRoofAllocationSetting'
|
import { useRoofAllocationSetting } from '@/hooks/roofcover/useRoofAllocationSetting'
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
|
import { normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function ActualSizeSetting(props) {
|
export default function ActualSizeSetting(props) {
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
@ -87,7 +88,7 @@ export default function ActualSizeSetting(props) {
|
|||||||
<div className="eaves-keraba-td">
|
<div className="eaves-keraba-td">
|
||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<div className="input-grid mr5">
|
<div className="input-grid mr5">
|
||||||
<input type="text" className="input-origin block" value={actualSize} onChange={(e) => setActualSize(Number(e.target.value))} />
|
<input type="text" className="input-origin block" value={actualSize} onChange={(e) => setActualSize(Number(normalizeDigits(e.target.value)))} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import { useCanvasSetting } from '@/hooks/option/useCanvasSetting'
|
|||||||
import { useCommonCode } from '@/hooks/common/useCommonCode'
|
import { useCommonCode } from '@/hooks/common/useCommonCode'
|
||||||
import { globalLocaleStore } from '@/store/localeAtom'
|
import { globalLocaleStore } from '@/store/localeAtom'
|
||||||
import { currentAngleTypeSelector, pitchTextSelector } from '@/store/canvasAtom'
|
import { currentAngleTypeSelector, pitchTextSelector } from '@/store/canvasAtom'
|
||||||
|
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function ContextRoofAllocationSetting(props) {
|
export default function ContextRoofAllocationSetting(props) {
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
@ -151,6 +152,7 @@ export default function ContextRoofAllocationSetting(props) {
|
|||||||
defaultValue={roof.width}
|
defaultValue={roof.width}
|
||||||
readOnly={roof.widAuth === 'R'}
|
readOnly={roof.widAuth === 'R'}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
|
e.target.value = normalizeDigits(e.target.value)
|
||||||
handleChangeInput(e, 'width', index)
|
handleChangeInput(e, 'width', index)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@ -169,6 +171,7 @@ export default function ContextRoofAllocationSetting(props) {
|
|||||||
defaultValue={roof.length}
|
defaultValue={roof.length}
|
||||||
readOnly={roof.lenAuth === 'R'}
|
readOnly={roof.lenAuth === 'R'}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
|
e.target.value = normalizeDigits(e.target.value)
|
||||||
handleChangeInput(e, 'length', index)
|
handleChangeInput(e, 'length', index)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@ -188,7 +191,10 @@ export default function ContextRoofAllocationSetting(props) {
|
|||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
value={roof.hajebichi === '' ? '0' : roof.hajebichi}
|
value={roof.hajebichi === '' ? '0' : roof.hajebichi}
|
||||||
readOnly={roof.roofPchAuth === 'R'}
|
readOnly={roof.roofPchAuth === 'R'}
|
||||||
onChange={(e) => handleChangeInput(e, 'hajebichi', index)}
|
onChange={(e) => {
|
||||||
|
e.target.value = normalizeDigits(e.target.value)
|
||||||
|
handleChangeInput(e, 'hajebichi', index)
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -202,7 +208,7 @@ export default function ContextRoofAllocationSetting(props) {
|
|||||||
type="text"
|
type="text"
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
// handleChangeInput(e, currentAngleType === 'slope' ? 'pitch' : 'angle', index)
|
e.target.value = normalizeDecimalLimit(e.target.value, 2)
|
||||||
handleChangePitch(e, index)
|
handleChangePitch(e, index)
|
||||||
}}
|
}}
|
||||||
value={currentAngleType === 'slope' ? (roof.pitch || '0') : (roof.angle || '0')}
|
value={currentAngleType === 'slope' ? (roof.pitch || '0') : (roof.angle || '0')}
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import { globalLocaleStore } from '@/store/localeAtom'
|
|||||||
import { useRoofShapeSetting } from '@/hooks/roofcover/useRoofShapeSetting'
|
import { useRoofShapeSetting } from '@/hooks/roofcover/useRoofShapeSetting'
|
||||||
import { currentAngleTypeSelector, pitchTextSelector } from '@/store/canvasAtom'
|
import { currentAngleTypeSelector, pitchTextSelector } from '@/store/canvasAtom'
|
||||||
import { getDegreeByChon } from '@/util/canvas-util'
|
import { getDegreeByChon } from '@/util/canvas-util'
|
||||||
import { onlyNumberWithDotInputChange } from '@/util/input-utils'
|
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function RoofAllocationSetting(props) {
|
export default function RoofAllocationSetting(props) {
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
@ -151,7 +151,10 @@ export default function RoofAllocationSetting(props) {
|
|||||||
type="text"
|
type="text"
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
defaultValue={roof.width}
|
defaultValue={roof.width}
|
||||||
onChange={(e) => handleChangeInput(e, 'width', index)}
|
onChange={(e) => {
|
||||||
|
e.target.value = normalizeDigits(e.target.value)
|
||||||
|
handleChangeInput(e, 'width', index)
|
||||||
|
}}
|
||||||
readOnly={roof.widAuth === 'R'}
|
readOnly={roof.widAuth === 'R'}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -167,7 +170,10 @@ export default function RoofAllocationSetting(props) {
|
|||||||
type="text"
|
type="text"
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
defaultValue={roof.length}
|
defaultValue={roof.length}
|
||||||
onChange={(e) => handleChangeInput(e, 'length', index)}
|
onChange={(e) => {
|
||||||
|
e.target.value = normalizeDigits(e.target.value)
|
||||||
|
handleChangeInput(e, 'length', index)
|
||||||
|
}}
|
||||||
readOnly={roof.lenAuth === 'R'}
|
readOnly={roof.lenAuth === 'R'}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -184,7 +190,10 @@ export default function RoofAllocationSetting(props) {
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
onChange={(e) => handleChangeInput(e, 'hajebichi', index)}
|
onChange={(e) => {
|
||||||
|
e.target.value = normalizeDigits(e.target.value)
|
||||||
|
handleChangeInput(e, 'hajebichi', index)
|
||||||
|
}}
|
||||||
value={parseInt(roof.hajebichi)}
|
value={parseInt(roof.hajebichi)}
|
||||||
readOnly={roof.roofPchAuth === 'R'}
|
readOnly={roof.roofPchAuth === 'R'}
|
||||||
/>
|
/>
|
||||||
@ -200,6 +209,7 @@ export default function RoofAllocationSetting(props) {
|
|||||||
type="text"
|
type="text"
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
|
e.target.value = normalizeDecimalLimit(e.target.value, 2)
|
||||||
handleChangePitch(e, index)
|
handleChangePitch(e, index)
|
||||||
}}
|
}}
|
||||||
value={currentAngleType === 'slope' ? roof.pitch : roof.angle}
|
value={currentAngleType === 'slope' ? roof.pitch : roof.angle}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils'
|
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function Direction({ pitch, setPitch, eavesOffset, setEavesOffset, gableOffset, setGableOffset, shedWidth, setShedWidth, pitchText }) {
|
export default function Direction({ pitch, setPitch, eavesOffset, setEavesOffset, gableOffset, setGableOffset, shedWidth, setShedWidth, pitchText }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -10,7 +10,12 @@ export default function Direction({ pitch, setPitch, eavesOffset, setEavesOffset
|
|||||||
{getMessage('slope')}
|
{getMessage('slope')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" value={pitch} onChange={(e) => onlyNumberWithDotInputChange(e, setPitch)} />
|
<input
|
||||||
|
type="text"
|
||||||
|
className="input-origin block"
|
||||||
|
value={pitch}
|
||||||
|
onChange={(e) => setPitch(normalizeDecimalLimit(e.target.value, 2))}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">{pitchText}</span>
|
<span className="thin">{pitchText}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -19,7 +24,12 @@ export default function Direction({ pitch, setPitch, eavesOffset, setEavesOffset
|
|||||||
{getMessage('eaves.offset')}
|
{getMessage('eaves.offset')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" value={eavesOffset} onChange={(e) => onlyNumberInputChange(e, setEavesOffset)} />
|
<input
|
||||||
|
type="text"
|
||||||
|
className="input-origin block"
|
||||||
|
value={eavesOffset}
|
||||||
|
onChange={(e) => setEavesOffset(normalizeDigits(e.target.value))}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -28,7 +38,12 @@ export default function Direction({ pitch, setPitch, eavesOffset, setEavesOffset
|
|||||||
{getMessage('gable.offset')}
|
{getMessage('gable.offset')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" value={gableOffset} onChange={(e) => onlyNumberInputChange(e, setGableOffset)} />
|
<input
|
||||||
|
type="text"
|
||||||
|
className="input-origin block"
|
||||||
|
value={gableOffset}
|
||||||
|
onChange={(e) => setGableOffset(normalizeDigits(e.target.value))}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -37,7 +52,12 @@ export default function Direction({ pitch, setPitch, eavesOffset, setEavesOffset
|
|||||||
{getMessage('windage.width')}
|
{getMessage('windage.width')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" value={shedWidth} onChange={(e) => onlyNumberInputChange(e, setShedWidth)} />
|
<input
|
||||||
|
type="text"
|
||||||
|
className="input-origin block"
|
||||||
|
value={shedWidth}
|
||||||
|
onChange={(e) => setShedWidth(normalizeDigits(e.target.value))}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils'
|
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function Pattern(props) {
|
export default function Pattern(props) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -11,7 +11,7 @@ export default function Pattern(props) {
|
|||||||
{getMessage('slope')}
|
{getMessage('slope')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" value={pitch} onChange={(e) => onlyNumberWithDotInputChange(e, setPitch)} />
|
<input type="text" className="input-origin block" value={pitch} onChange={(e) => setPitch(normalizeDecimalLimit(e.target.value, 2))} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin"> {pitchText}</span>
|
<span className="thin"> {pitchText}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -20,7 +20,7 @@ export default function Pattern(props) {
|
|||||||
{getMessage('eaves.offset')}
|
{getMessage('eaves.offset')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" value={eavesOffset} onChange={(e) => onlyNumberInputChange(e, setEavesOffset)} />
|
<input type="text" className="input-origin block" value={eavesOffset} onChange={(e) => setEavesOffset(normalizeDigits(e.target.value))} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -29,7 +29,7 @@ export default function Pattern(props) {
|
|||||||
{getMessage('gable.offset')}
|
{getMessage('gable.offset')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" value={gableOffset} onChange={(e) => onlyNumberInputChange(e, setGableOffset)} />
|
<input type="text" className="input-origin block" value={gableOffset} onChange={(e) => setGableOffset(normalizeDigits(e.target.value))} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils'
|
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function Ridge(props) {
|
export default function Ridge(props) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -13,7 +13,7 @@ export default function Ridge(props) {
|
|||||||
{getMessage('slope')}
|
{getMessage('slope')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" value={pitch} onChange={(e) => onlyNumberWithDotInputChange(e, setPitch)} />
|
<input type="text" className="input-origin block" value={pitch} onChange={(e) => setPitch(normalizeDecimalLimit(e.target.value, 2))} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">{pitchText}</span>
|
<span className="thin">{pitchText}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -22,7 +22,7 @@ export default function Ridge(props) {
|
|||||||
{getMessage('eaves.offset')}
|
{getMessage('eaves.offset')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" value={eavesOffset} onChange={(e) => onlyNumberInputChange(e, setEavesOffset)} />
|
<input type="text" className="input-origin block" value={eavesOffset} onChange={(e) => setEavesOffset(normalizeDigits(e.target.value))} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils'
|
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function Eaves({ pitch, setPitch, eavesOffset, setEavesOffset, pitchText }) {
|
export default function Eaves({ pitch, setPitch, eavesOffset, setEavesOffset, pitchText }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -10,7 +10,7 @@ export default function Eaves({ pitch, setPitch, eavesOffset, setEavesOffset, pi
|
|||||||
{getMessage('slope')}
|
{getMessage('slope')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" value={pitch} onChange={(e) => onlyNumberWithDotInputChange(e, setPitch)} />
|
<input type="text" className="input-origin block" value={pitch} onChange={(e) => setPitch(normalizeDecimalLimit(e.target.value, 2))} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">{pitchText}</span>
|
<span className="thin">{pitchText}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -19,7 +19,7 @@ export default function Eaves({ pitch, setPitch, eavesOffset, setEavesOffset, pi
|
|||||||
{getMessage('eaves.offset')}
|
{getMessage('eaves.offset')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" value={eavesOffset} onChange={(e) => onlyNumberInputChange(e, setEavesOffset)} />
|
<input type="text" className="input-origin block" value={eavesOffset} onChange={(e) => setEavesOffset(normalizeDigits(e.target.value))} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
import { onlyNumberInputChange } from '@/util/input-utils'
|
import { normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function Gable({ gableOffset, setGableOffset }) {
|
export default function Gable({ gableOffset, setGableOffset }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -10,7 +10,7 @@ export default function Gable({ gableOffset, setGableOffset }) {
|
|||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<span className="mr10">{getMessage('gable.offset')}</span>
|
<span className="mr10">{getMessage('gable.offset')}</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" value={gableOffset} onChange={(e) => onlyNumberInputChange(e, setGableOffset)} />
|
<input type="text" className="input-origin block" value={gableOffset} onChange={(e) => setGableOffset(normalizeDigits(e.target.value))} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils'
|
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function HipAndGable({ pitch, setPitch, eavesOffset, setEavesOffset, hipAndGableWidth, setHipAndGableWidth, pitchText }) {
|
export default function HipAndGable({ pitch, setPitch, eavesOffset, setEavesOffset, hipAndGableWidth, setHipAndGableWidth, pitchText }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -10,7 +10,7 @@ export default function HipAndGable({ pitch, setPitch, eavesOffset, setEavesOffs
|
|||||||
{getMessage('slope')}
|
{getMessage('slope')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" value={pitch} onChange={(e) => onlyNumberWithDotInputChange(e, setPitch)} />
|
<input type="text" className="input-origin block" value={pitch} onChange={(e) => setPitch(normalizeDecimalLimit(e.target.value, 2))} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">{pitchText}</span>
|
<span className="thin">{pitchText}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -19,7 +19,7 @@ export default function HipAndGable({ pitch, setPitch, eavesOffset, setEavesOffs
|
|||||||
{getMessage('eaves.offset')}
|
{getMessage('eaves.offset')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" value={eavesOffset} onChange={(e) => onlyNumberInputChange(e, setEavesOffset)} />
|
<input type="text" className="input-origin block" value={eavesOffset} onChange={(e) => setEavesOffset(normalizeDigits(e.target.value))} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -32,7 +32,7 @@ export default function HipAndGable({ pitch, setPitch, eavesOffset, setEavesOffs
|
|||||||
type="text"
|
type="text"
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
value={hipAndGableWidth}
|
value={hipAndGableWidth}
|
||||||
onChange={(e) => onlyNumberInputChange(e, setHipAndGableWidth)}
|
onChange={(e) => setHipAndGableWidth(normalizeDigits(e.target.value))}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils'
|
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function Jerkinhead({
|
export default function Jerkinhead({
|
||||||
gableOffset,
|
gableOffset,
|
||||||
@ -18,7 +18,7 @@ export default function Jerkinhead({
|
|||||||
{getMessage('gable.offset')}
|
{getMessage('gable.offset')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" value={gableOffset} onChange={(e) => onlyNumberInputChange(e, setGableOffset)} />
|
<input type="text" className="input-origin block" value={gableOffset} onChange={(e) => setGableOffset(normalizeDigits(e.target.value))} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -27,7 +27,7 @@ export default function Jerkinhead({
|
|||||||
{getMessage('jerkinhead.width')}
|
{getMessage('jerkinhead.width')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" value={jerkinHeadWidth} onChange={(e) => onlyNumberInputChange(e, setJerkinHeadWidth)} />
|
<input type="text" className="input-origin block" value={jerkinHeadWidth} onChange={(e) => setJerkinHeadWidth(normalizeDigits(e.target.value))} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -40,7 +40,7 @@ export default function Jerkinhead({
|
|||||||
type="text"
|
type="text"
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
value={jerkinHeadPitch}
|
value={jerkinHeadPitch}
|
||||||
onChange={(e) => onlyNumberWithDotInputChange(e, setJerkinHeadPitch)}
|
onChange={(e) => setJerkinHeadPitch(normalizeDecimalLimit(e.target.value, 2))}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">{pitchText}</span>
|
<span className="thin">{pitchText}</span>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { onlyNumberInputChange, onlyNumberWithDotInputChange } from '@/util/input-utils'
|
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function Shed({ shedWidth, setShedWidth, shedPitch, setShedPitch, pitchText }) {
|
export default function Shed({ shedWidth, setShedWidth, shedPitch, setShedPitch, pitchText }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -8,14 +8,14 @@ export default function Shed({ shedWidth, setShedWidth, shedPitch, setShedPitch,
|
|||||||
<div className="outline-form mb10">
|
<div className="outline-form mb10">
|
||||||
<span className="mr10">{getMessage('slope')}</span>
|
<span className="mr10">{getMessage('slope')}</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" value={shedPitch} onChange={(e) => onlyNumberWithDotInputChange(e, setShedPitch)} />
|
<input type="text" className="input-origin block" value={shedPitch} onChange={(e) => setShedPitch(normalizeDecimalLimit(e.target.value, 2))} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">{pitchText}</span>
|
<span className="thin">{pitchText}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<span className="mr10">{getMessage('shed.width')}</span>
|
<span className="mr10">{getMessage('shed.width')}</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input type="text" className="input-origin block" value={shedWidth} onChange={(e) => onlyNumberInputChange(e, setShedWidth)} />
|
<input type="text" className="input-origin block" value={shedWidth} onChange={(e) => setShedWidth(normalizeDigits(e.target.value))} />
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { onlyNumberInputChange } from '@/util/input-utils'
|
import { normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function Wall({ sleeveOffset, setSleeveOffset, hasSleeve, setHasSleeve }) {
|
export default function Wall({ sleeveOffset, setSleeveOffset, hasSleeve, setHasSleeve }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -29,7 +29,7 @@ export default function Wall({ sleeveOffset, setSleeveOffset, hasSleeve, setHasS
|
|||||||
type="text"
|
type="text"
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
value={sleeveOffset}
|
value={sleeveOffset}
|
||||||
onChange={(e) => onlyNumberInputChange(e, setSleeveOffset)}
|
onChange={(e) => setSleeveOffset(normalizeDigits(e.target.value))}
|
||||||
readOnly={hasSleeve === '0'}
|
readOnly={hasSleeve === '0'}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { usePopup } from '@/hooks/usePopup'
|
|||||||
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
||||||
import { canvasState } from '@/store/canvasAtom'
|
import { canvasState } from '@/store/canvasAtom'
|
||||||
import { useCanvasSetting } from '@/hooks/option/useCanvasSetting'
|
import { useCanvasSetting } from '@/hooks/option/useCanvasSetting'
|
||||||
import { onlyNumberInputChange } from '@/util/input-utils'
|
import { normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function PlanSizeSetting(props) {
|
export default function PlanSizeSetting(props) {
|
||||||
const { setIsShow, horizon, vertical, id, pos = { x: 985, y: 180 }, settingsData, setSettingsData, settingsDataSave, setSettingsDataSave } = props
|
const { setIsShow, horizon, vertical, id, pos = { x: 985, y: 180 }, settingsData, setSettingsData, settingsDataSave, setSettingsDataSave } = props
|
||||||
@ -24,15 +24,15 @@ export default function PlanSizeSetting(props) {
|
|||||||
setPlanSizeSettingMode((prev) => {
|
setPlanSizeSettingMode((prev) => {
|
||||||
return {
|
return {
|
||||||
...prev,
|
...prev,
|
||||||
originHorizon: Number(planSizeSettingMode.originHorizon),
|
originHorizon: Number(normalizeDigits(planSizeSettingMode.originHorizon)),
|
||||||
originVertical: Number(planSizeSettingMode.originVertical),
|
originVertical: Number(normalizeDigits(planSizeSettingMode.originVertical)),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
setSettingsData({
|
setSettingsData({
|
||||||
...settingsData,
|
...settingsData,
|
||||||
originHorizon: Number(planSizeSettingMode.originHorizon),
|
originHorizon: Number(normalizeDigits(planSizeSettingMode.originHorizon)),
|
||||||
originVertical: Number(planSizeSettingMode.originVertical),
|
originVertical: Number(normalizeDigits(planSizeSettingMode.originVertical)),
|
||||||
})
|
})
|
||||||
|
|
||||||
canvas.setWidth(planSizeSettingMode.originHorizon)
|
canvas.setWidth(planSizeSettingMode.originHorizon)
|
||||||
@ -46,14 +46,15 @@ export default function PlanSizeSetting(props) {
|
|||||||
const changeInput = (value, e) => {
|
const changeInput = (value, e) => {
|
||||||
const { name } = e.target
|
const { name } = e.target
|
||||||
|
|
||||||
if (Number(value) > 100000) {
|
let n = Number(normalizeDigits(value))
|
||||||
value = 100000
|
if (n > 100000) {
|
||||||
|
n = 100000
|
||||||
}
|
}
|
||||||
|
|
||||||
setPlanSizeSettingMode((prev) => {
|
setPlanSizeSettingMode((prev) => {
|
||||||
return {
|
return {
|
||||||
...prev,
|
...prev,
|
||||||
[name]: Number(value) / 10,
|
[name]: n / 10,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -77,7 +78,7 @@ export default function PlanSizeSetting(props) {
|
|||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
name={`originHorizon`}
|
name={`originHorizon`}
|
||||||
value={planSizeSettingMode.originHorizon * 10}
|
value={planSizeSettingMode.originHorizon * 10}
|
||||||
onChange={(e) => onlyNumberInputChange(e, changeInput)}
|
onChange={(e) => changeInput(normalizeDigits(e.target.value), e)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
@ -90,7 +91,7 @@ export default function PlanSizeSetting(props) {
|
|||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
name={`originVertical`}
|
name={`originVertical`}
|
||||||
value={planSizeSettingMode.originVertical * 10}
|
value={planSizeSettingMode.originVertical * 10}
|
||||||
onChange={(e) => onlyNumberInputChange(e, changeInput)}
|
onChange={(e) => changeInput(normalizeDigits(e.target.value), e)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import { stuffSearchState } from '@/store/stuffAtom'
|
|||||||
import { QcastContext } from '@/app/QcastProvider'
|
import { QcastContext } from '@/app/QcastProvider'
|
||||||
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
|
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
|
import { sanitizeDecimalInputEvent} from '@/util/input-utils'
|
||||||
|
|
||||||
export default function StuffDetail() {
|
export default function StuffDetail() {
|
||||||
const [stuffSearch, setStuffSearch] = useRecoilState(stuffSearchState)
|
const [stuffSearch, setStuffSearch] = useRecoilState(stuffSearchState)
|
||||||
@ -1634,13 +1635,15 @@ export default function StuffDetail() {
|
|||||||
|
|
||||||
// 숫자만 입력 가능
|
// 숫자만 입력 가능
|
||||||
const handleKeyUp = (e) => {
|
const handleKeyUp = (e) => {
|
||||||
let input = e.target
|
// let input = e.target
|
||||||
input.value = input.value.replace(/[^0-9]/g, '')
|
// input.value = input.value.replace(/[^0-9]/g, '')
|
||||||
|
sanitizeIntegerInputEvent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleBlur = (e) => {
|
const handleBlur = (e) => {
|
||||||
let input = e.target
|
// let input = e.target
|
||||||
input.value = input.value.replace(/[^0-9]/g, '')
|
// input.value = input.value.replace(/[^0-9]/g, '')
|
||||||
|
sanitizeIntegerInputEvent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 그리드 더블 클릭 해당플랜의 도면작성 화면으로 이동
|
// 그리드 더블 클릭 해당플랜의 도면작성 화면으로 이동
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import { useMessage } from '@/hooks/useMessage'
|
|||||||
import { isNotEmptyArray } from '@/util/common-utils'
|
import { isNotEmptyArray } from '@/util/common-utils'
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
import { QcastContext } from '@/app/QcastProvider'
|
import { QcastContext } from '@/app/QcastProvider'
|
||||||
|
import { sanitizeIntegerInputEvent } from '@/util/input-utils'
|
||||||
export default function FindAddressPop(props) {
|
export default function FindAddressPop(props) {
|
||||||
const globalLocaleState = useRecoilValue(globalLocaleStore)
|
const globalLocaleState = useRecoilValue(globalLocaleStore)
|
||||||
|
|
||||||
@ -113,12 +114,12 @@ export default function FindAddressPop(props) {
|
|||||||
|
|
||||||
//숫자만
|
//숫자만
|
||||||
const handleKeyUp = (e) => {
|
const handleKeyUp = (e) => {
|
||||||
let input = e.target
|
// let input = e.target
|
||||||
input.value = input.value.replace(/[^0-9]/g, '')
|
// input.value = input.value.replace(/[^0-9]/g, '')
|
||||||
|
// if (e.key === 'Enter') {
|
||||||
if (e.key === 'Enter') {
|
// searchPostNum()
|
||||||
searchPostNum()
|
// }
|
||||||
}
|
sanitizeIntegerInputEvent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
//그리드에서 선택한 우편정보
|
//그리드에서 선택한 우편정보
|
||||||
|
|||||||
@ -11,6 +11,8 @@ import { isObjectNotEmpty, queryStringFormatter } from '@/util/common-utils'
|
|||||||
import QPagination from '@/components/common/pagination/QPagination'
|
import QPagination from '@/components/common/pagination/QPagination'
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
import { QcastContext } from '@/app/QcastProvider'
|
import { QcastContext } from '@/app/QcastProvider'
|
||||||
|
import { sanitizeDecimalInputEvent } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function PlanRequestPop(props) {
|
export default function PlanRequestPop(props) {
|
||||||
const [pageNo, setPageNo] = useState(1) //현재 페이지 번호
|
const [pageNo, setPageNo] = useState(1) //현재 페이지 번호
|
||||||
const [pageSize, setPageSize] = useState(20) //페이지 당 게시물 개수
|
const [pageSize, setPageSize] = useState(20) //페이지 당 게시물 개수
|
||||||
@ -233,16 +235,16 @@ export default function PlanRequestPop(props) {
|
|||||||
|
|
||||||
// 숫자만 입력 가능
|
// 숫자만 입력 가능
|
||||||
const handleKeyUp = (e) => {
|
const handleKeyUp = (e) => {
|
||||||
let input = e.target
|
sanitizeIntegerInputEvent(e)
|
||||||
input.value = input.value.replace(/[^0-9]/g, '')
|
|
||||||
if (e.key === 'Enter') {
|
if (e.key === 'Enter') {
|
||||||
onSubmit(pageNo, 'S')
|
onSubmit(pageNo, 'S')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleBlur = (e) => {
|
const handleBlur = (e) => {
|
||||||
let input = e.target
|
// let input = e.target
|
||||||
input.value = input.value.replace(/[^0-9]/g, '')
|
// input.value = input.value.replace(/[^0-9]/g, '')
|
||||||
|
sanitizeIntegerInputEvent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 엔터 이벤트
|
// 엔터 이벤트
|
||||||
|
|||||||
@ -18,3 +18,41 @@ export const onlyNumberWithDotInputChange = (e, callback) => {
|
|||||||
|
|
||||||
callback(val, e)
|
callback(val, e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// =============================
|
||||||
|
// Number normalization utilities
|
||||||
|
// =============================
|
||||||
|
// 1) Normalize any string to NFKC and keep only ASCII digits 0-9.
|
||||||
|
export function normalizeDigits(value) {
|
||||||
|
return String(value ?? '').normalize('NFKC').replace(/[^0-9]/g, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2) Normalize decimal numbers (allow one dot).
|
||||||
|
export function normalizeDecimal(value) {
|
||||||
|
const s = String(value ?? '').normalize('NFKC').replace(/[^0-9.]/g, '')
|
||||||
|
const [head, ...rest] = s.split('.')
|
||||||
|
return rest.length ? `${head}.${rest.join('').replace(/\./g, '')}` : head
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2-1) Limit fractional digits for decimal numbers. Default to 2 digits.
|
||||||
|
export function normalizeDecimalLimit(value, maxFractionDigits = 2) {
|
||||||
|
const s = normalizeDecimal(value)
|
||||||
|
if (!s) return s
|
||||||
|
const [intPart, fracPart] = s.split('.')
|
||||||
|
if (fracPart === undefined) return intPart
|
||||||
|
return `${intPart}.${fracPart.slice(0, Math.max(0, maxFractionDigits))}`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3) DOM input event helpers (optional): mutate target.value and return normalized value
|
||||||
|
export function sanitizeIntegerInputEvent(e) {
|
||||||
|
const v = normalizeDigits(e?.target?.value)
|
||||||
|
if (e?.target) e.target.value = v
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
export function sanitizeDecimalInputEvent(e) {
|
||||||
|
const v = normalizeDecimal(e?.target?.value)
|
||||||
|
if (e?.target) e.target.value = v
|
||||||
|
return v
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user