Merge branch 'dev' into feature/design-remake
This commit is contained in:
commit
ce5192ba1a
3
.gitignore
vendored
3
.gitignore
vendored
@ -42,4 +42,5 @@ next-env.d.ts
|
|||||||
yarn.lock
|
yarn.lock
|
||||||
package-lock.json
|
package-lock.json
|
||||||
pnpm-lock.yaml
|
pnpm-lock.yaml
|
||||||
certificates
|
certificates
|
||||||
|
.ai
|
||||||
@ -22,7 +22,7 @@
|
|||||||
"chart.js": "^4.4.6",
|
"chart.js": "^4.4.6",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"env-cmd": "^10.1.0",
|
"env-cmd": "^10.1.0",
|
||||||
"fabric": "^5.3.0",
|
"fabric": "^5.5.2",
|
||||||
"framer-motion": "^11.2.13",
|
"framer-motion": "^11.2.13",
|
||||||
"fs": "^0.0.1-security",
|
"fs": "^0.0.1-security",
|
||||||
"iron-session": "^8.0.2",
|
"iron-session": "^8.0.2",
|
||||||
|
|||||||
@ -58,7 +58,8 @@ export default async function RootLayout({ children }) {
|
|||||||
pwdInitYn: session.pwdInitYn,
|
pwdInitYn: session.pwdInitYn,
|
||||||
custCd: session.custCd,
|
custCd: session.custCd,
|
||||||
isLoggedIn: session.isLoggedIn,
|
isLoggedIn: session.isLoggedIn,
|
||||||
builderNo: session.builderNo
|
builderNo: session.builderNo,
|
||||||
|
custNm: session.custNm
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!headerPathname.includes('/login') && !session.isLoggedIn) {
|
if (!headerPathname.includes('/login') && !session.isLoggedIn) {
|
||||||
|
|||||||
@ -61,6 +61,7 @@ export const LINE_TYPE = {
|
|||||||
*/
|
*/
|
||||||
DEFAULT: 'default',
|
DEFAULT: 'default',
|
||||||
EAVES: 'eaves',
|
EAVES: 'eaves',
|
||||||
|
EAVE_HELP_LINE: 'eaveHelpLine',
|
||||||
GABLE: 'gable',
|
GABLE: 'gable',
|
||||||
GABLE_LEFT: 'gableLeft', //케라바 왼쪽
|
GABLE_LEFT: 'gableLeft', //케라바 왼쪽
|
||||||
GABLE_RIGHT: 'gableRight', //케라바 오른쪽
|
GABLE_RIGHT: 'gableRight', //케라바 오른쪽
|
||||||
@ -218,6 +219,9 @@ export const SAVE_KEY = [
|
|||||||
'originColor',
|
'originColor',
|
||||||
'originWidth',
|
'originWidth',
|
||||||
'originHeight',
|
'originHeight',
|
||||||
|
'skeletonLines',
|
||||||
|
'skeleton',
|
||||||
|
'viewportTransform',
|
||||||
]
|
]
|
||||||
|
|
||||||
export const OBJECT_PROTOTYPE = [fabric.Line.prototype, fabric.Polygon.prototype, fabric.Triangle.prototype, fabric.Group.prototype]
|
export const OBJECT_PROTOTYPE = [fabric.Line.prototype, fabric.Polygon.prototype, fabric.Triangle.prototype, fabric.Group.prototype]
|
||||||
|
|||||||
@ -24,7 +24,7 @@ export default function WithDraggable({ isShow, children, pos = { x: 0, y: 0 },
|
|||||||
<Draggable
|
<Draggable
|
||||||
position={{ x: position.x, y: position.y }}
|
position={{ x: position.x, y: position.y }}
|
||||||
onDrag={(e, data) => handleOnDrag(e, data)}
|
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"
|
cancel="input, button, select, textarea, [contenteditable], .sort-select"
|
||||||
>
|
>
|
||||||
<div className={`modal-pop-wrap ${className}`} style={{ visibility: isHidden ? 'hidden' : 'visible' }}>
|
<div className={`modal-pop-wrap ${className}`} style={{ visibility: isHidden ? 'hidden' : 'visible' }}>
|
||||||
@ -38,15 +38,18 @@ 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 (
|
return (
|
||||||
<div className="modal-head modal-handle">
|
<div className="modal-head modal-handle">
|
||||||
<h1 className="title">{title}</h1>
|
<h1 className="title">{title}</h1>
|
||||||
{onClose && (
|
<div className="modal-btn-wrap">
|
||||||
<button className="modal-close" onClick={() => onClose()}>
|
{onFold && <button className={`modal-fold ${isFold ? '' : 'act'}`} onClick={onFold}></button>}
|
||||||
닫기
|
{onClose && (
|
||||||
</button>
|
<button className="modal-close" onClick={() => onClose()}>
|
||||||
)}
|
닫기
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,14 +48,23 @@ export const CalculatorInput = forwardRef(
|
|||||||
const calculator = calculatorRef.current
|
const calculator = calculatorRef.current
|
||||||
let newDisplayValue = ''
|
let newDisplayValue = ''
|
||||||
|
|
||||||
|
// 소수점 이하 2자리 제한 로직 추가
|
||||||
|
const shouldPreventInput = (value) => {
|
||||||
|
const decimalParts = (value || '').split('.')
|
||||||
|
return decimalParts.length > 1 && decimalParts[1].length >= 2
|
||||||
|
}
|
||||||
|
|
||||||
if (hasOperation) {
|
if (hasOperation) {
|
||||||
// 연산자 이후 숫자 입력 시
|
// 연산자 이후 숫자 입력 시
|
||||||
if (calculator.currentOperand === '0' || calculator.shouldResetDisplay) {
|
if (calculator.currentOperand === '0' || calculator.shouldResetDisplay) {
|
||||||
calculator.currentOperand = num.toString()
|
calculator.currentOperand = num.toString()
|
||||||
calculator.shouldResetDisplay = false
|
calculator.shouldResetDisplay = false
|
||||||
} else {
|
}else if (!shouldPreventInput(calculator.currentOperand)) { //소수점 이하2자리
|
||||||
calculator.currentOperand = (calculator.currentOperand || '') + num
|
calculator.currentOperand = (calculator.currentOperand || '') + num
|
||||||
}
|
}
|
||||||
|
// else {
|
||||||
|
// calculator.currentOperand = (calculator.currentOperand || '') + num
|
||||||
|
// }
|
||||||
newDisplayValue = calculator.previousOperand + calculator.operation + calculator.currentOperand
|
newDisplayValue = calculator.previousOperand + calculator.operation + calculator.currentOperand
|
||||||
setDisplayValue(newDisplayValue)
|
setDisplayValue(newDisplayValue)
|
||||||
} else {
|
} else {
|
||||||
@ -68,7 +77,7 @@ export const CalculatorInput = forwardRef(
|
|||||||
if (!hasOperation) {
|
if (!hasOperation) {
|
||||||
onChange(calculator.currentOperand)
|
onChange(calculator.currentOperand)
|
||||||
}
|
}
|
||||||
} else {
|
} else if (!shouldPreventInput(calculator.currentOperand)) { //소수점 이하2자리
|
||||||
calculator.currentOperand = (calculator.currentOperand || '') + num
|
calculator.currentOperand = (calculator.currentOperand || '') + num
|
||||||
newDisplayValue = calculator.currentOperand
|
newDisplayValue = calculator.currentOperand
|
||||||
setDisplayValue(newDisplayValue)
|
setDisplayValue(newDisplayValue)
|
||||||
@ -76,6 +85,14 @@ export const CalculatorInput = forwardRef(
|
|||||||
onChange(newDisplayValue)
|
onChange(newDisplayValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// else {
|
||||||
|
// calculator.currentOperand = (calculator.currentOperand || '') + num
|
||||||
|
// newDisplayValue = calculator.currentOperand
|
||||||
|
// setDisplayValue(newDisplayValue)
|
||||||
|
// if (!hasOperation) {
|
||||||
|
// onChange(newDisplayValue)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// 커서를 텍스트 끝으로 이동하고 스크롤 처리
|
// 커서를 텍스트 끝으로 이동하고 스크롤 처리
|
||||||
|
|||||||
@ -22,7 +22,8 @@ export default function QnaRegModal({ setOpen, setReload, searchValue, selectPag
|
|||||||
const [sessionState, setSessionState] = useRecoilState(sessionStore)
|
const [sessionState, setSessionState] = useRecoilState(sessionStore)
|
||||||
const globalLocaleState = useRecoilValue(globalLocaleStore)
|
const globalLocaleState = useRecoilValue(globalLocaleStore)
|
||||||
const [files, setFiles] = useState([])
|
const [files, setFiles] = useState([])
|
||||||
const [qnaData, setQnaData] = useState([])
|
//const [qnaData, setQnaData] = useState([])
|
||||||
|
const [qnaData, setQnaData] = useState({})
|
||||||
const [closeMdFlg, setCloseMdFlg] = useState(true)
|
const [closeMdFlg, setCloseMdFlg] = useState(true)
|
||||||
const [closeSmFlg, setCloseSmFlg] = useState(true)
|
const [closeSmFlg, setCloseSmFlg] = useState(true)
|
||||||
const [hideSmFlg, setHideSmFlg] = useState(false)
|
const [hideSmFlg, setHideSmFlg] = useState(false)
|
||||||
@ -44,6 +45,10 @@ export default function QnaRegModal({ setOpen, setReload, searchValue, selectPag
|
|||||||
const [isBtnDisable, setIsBtnDisable] = useState(false);
|
const [isBtnDisable, setIsBtnDisable] = useState(false);
|
||||||
const { promiseGet, post, promisePost } = useAxios(globalLocaleState)
|
const { promiseGet, post, promisePost } = useAxios(globalLocaleState)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log('qnaData updated:', qnaData);
|
||||||
|
}, [qnaData]);
|
||||||
|
|
||||||
let fileCheck = false;
|
let fileCheck = false;
|
||||||
const regPhoneNumber = (e) => {
|
const regPhoneNumber = (e) => {
|
||||||
const result = e.target.value
|
const result = e.target.value
|
||||||
@ -80,14 +85,16 @@ let fileCheck = false;
|
|||||||
//setQnaData([])
|
//setQnaData([])
|
||||||
|
|
||||||
setQnaData({
|
setQnaData({
|
||||||
...qnaData,
|
|
||||||
compCd: "5200",
|
compCd: "5200",
|
||||||
siteTpCd: "QC",
|
siteTpCd: "QC",
|
||||||
schNoticeClsCd: "QNA",
|
schNoticeClsCd: "QNA",
|
||||||
regId: sessionState.userId,
|
regId: sessionState?.userId || '',
|
||||||
storeId: sessionState.userId,
|
storeId: sessionState?.storeId || '',
|
||||||
qstMail : sessionState.email
|
qstMail: sessionState?.email || '',
|
||||||
})
|
qnaClsLrgCd: '',
|
||||||
|
qnaClsMidCd: '',
|
||||||
|
qnaClsSmlCd: ''
|
||||||
|
});
|
||||||
|
|
||||||
const codeL = findCommonCode(204200)
|
const codeL = findCommonCode(204200)
|
||||||
if (codeL != null) {
|
if (codeL != null) {
|
||||||
@ -119,43 +126,42 @@ let fileCheck = false;
|
|||||||
|
|
||||||
}
|
}
|
||||||
const onChangeQnaTypeM = (e) => {
|
const onChangeQnaTypeM = (e) => {
|
||||||
|
if (!e?.clCode) return;
|
||||||
|
|
||||||
if(e === undefined || e === null) return;
|
// 중분류 코드 업데이트
|
||||||
const codeS = findCommonCode(204400)
|
setQnaData(prevState => ({
|
||||||
if (codeS != null) {
|
...prevState,
|
||||||
|
qnaClsMidCd: e.clCode,
|
||||||
let codeList = []
|
// 소분류는 초기화 (새로 선택하도록)
|
||||||
|
qnaClsSmlCd: ''
|
||||||
codeS.map((item) => {
|
}));
|
||||||
|
|
||||||
if (item.clRefChr1 === e.clCode) {
|
|
||||||
codeList.push(item);
|
|
||||||
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
setQnaData({ ...qnaData, qnaClsMidCd: e.clCode })
|
|
||||||
setCloseSmFlg(false)
|
|
||||||
setQnaTypeSmCodeList(codeList)
|
|
||||||
qnaTypeSmCodeRef.current?.setValue();
|
|
||||||
|
|
||||||
if(codeList.length > 0) {
|
|
||||||
setHideSmFlg(false)
|
|
||||||
}else{
|
|
||||||
setHideSmFlg(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
// 소분류 코드 목록 설정
|
||||||
|
const codeS = findCommonCode(204400);
|
||||||
|
if (codeS) {
|
||||||
|
const filteredCodeList = codeS.filter(item => item.clRefChr1 === e.clCode);
|
||||||
|
setQnaTypeSmCodeList(filteredCodeList);
|
||||||
|
|
||||||
|
// 소분류가 있으면 초기화, 없으면 숨김
|
||||||
|
const hasSubCategories = filteredCodeList.length > 0;
|
||||||
|
setCloseSmFlg(!hasSubCategories);
|
||||||
|
setHideSmFlg(!hasSubCategories);
|
||||||
} else {
|
} else {
|
||||||
setHideSmFlg(true)
|
setHideSmFlg(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
// 소분류 선택기 초기화
|
||||||
|
qnaTypeSmCodeRef.current?.setValue();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const onChangeQnaTypeS = (e) => {
|
const onChangeQnaTypeS = (e) => {
|
||||||
if(e === undefined || e === null) return;
|
if (!e?.clCode) return;
|
||||||
setQnaData({ ...qnaData, qnaClsSmlCd:e.clCode})
|
|
||||||
|
setQnaData(prevState => ({
|
||||||
|
...prevState,
|
||||||
|
qnaClsSmlCd: e.clCode
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
const onFileSave = () => {
|
const onFileSave = () => {
|
||||||
@ -356,6 +362,8 @@ let fileCheck = false;
|
|||||||
<td>{dayjs(new Date()).format('YYYY-MM-DD')}</td>
|
<td>{dayjs(new Date()).format('YYYY-MM-DD')}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
<th>Customer</th>
|
||||||
|
<td><input type="text" className="input-light" value={sessionState?.custNm || ''} readOnly /></td>
|
||||||
<th>{getMessage('qna.reg.header.regUserNm')}<span className="red">*</span></th>
|
<th>{getMessage('qna.reg.header.regUserNm')}<span className="red">*</span></th>
|
||||||
<td ><input type="text" className="input-light" required
|
<td ><input type="text" className="input-light" required
|
||||||
ref={regUserNmRef}
|
ref={regUserNmRef}
|
||||||
@ -363,7 +371,7 @@ let fileCheck = false;
|
|||||||
onChange={(e) => setQnaData({...qnaData, regUserNm: e.target.value })}
|
onChange={(e) => setQnaData({...qnaData, regUserNm: e.target.value })}
|
||||||
onBlur={(e) => setQnaData({ ...qnaData, regUserNm: e.target.value })} /> </td>
|
onBlur={(e) => setQnaData({ ...qnaData, regUserNm: e.target.value })} /> </td>
|
||||||
<th>{getMessage('qna.reg.header.regUserTelNo')}</th>
|
<th>{getMessage('qna.reg.header.regUserTelNo')}</th>
|
||||||
<td colSpan={3}><input type="text" className="input-light"
|
<td ><input type="text" className="input-light"
|
||||||
ref={regUserTelNoRef}
|
ref={regUserTelNoRef}
|
||||||
maxLength={13}
|
maxLength={13}
|
||||||
value={qnaData?.regUserTelNo || '' }
|
value={qnaData?.regUserTelNo || '' }
|
||||||
|
|||||||
@ -16,6 +16,7 @@ export const QLine = fabric.util.createClass(fabric.Line, {
|
|||||||
children: [],
|
children: [],
|
||||||
padding: 5,
|
padding: 5,
|
||||||
textVisible: true,
|
textVisible: true,
|
||||||
|
textBaseline: 'alphabetic',
|
||||||
initialize: function (points, options, length = 0) {
|
initialize: function (points, options, length = 0) {
|
||||||
// 소수점 전부 제거
|
// 소수점 전부 제거
|
||||||
|
|
||||||
|
|||||||
@ -250,6 +250,7 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
|||||||
obj.parentId === this.id &&
|
obj.parentId === this.id &&
|
||||||
obj.name !== POLYGON_TYPE.WALL &&
|
obj.name !== POLYGON_TYPE.WALL &&
|
||||||
obj.name !== POLYGON_TYPE.ROOF &&
|
obj.name !== POLYGON_TYPE.ROOF &&
|
||||||
|
obj.name !== 'lengthText' &&
|
||||||
obj.name !== 'outerLine' &&
|
obj.name !== 'outerLine' &&
|
||||||
obj.name !== 'baseLine',
|
obj.name !== 'baseLine',
|
||||||
// && obj.name !== 'outerLinePoint',
|
// && obj.name !== 'outerLinePoint',
|
||||||
@ -338,8 +339,8 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
|||||||
if (types.every((type) => type === LINE_TYPE.WALLLINE.EAVES)) {
|
if (types.every((type) => type === LINE_TYPE.WALLLINE.EAVES)) {
|
||||||
// 용마루 -- straight-skeleton
|
// 용마루 -- straight-skeleton
|
||||||
console.log('용마루 지붕')
|
console.log('용마루 지붕')
|
||||||
drawRidgeRoof(this.id, this.canvas, textMode)
|
///drawRidgeRoof(this.id, this.canvas, textMode)
|
||||||
//drawSkeletonRidgeRoof(this.id, this.canvas, textMode);
|
drawSkeletonRidgeRoof(this.id, this.canvas, textMode);
|
||||||
} else if (isGableRoof(types)) {
|
} else if (isGableRoof(types)) {
|
||||||
// A형, B형 박공 지붕
|
// A형, B형 박공 지붕
|
||||||
console.log('패턴 지붕')
|
console.log('패턴 지붕')
|
||||||
@ -378,9 +379,27 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
|||||||
const dy = Big(end.y).minus(Big(start.y))
|
const dy = Big(end.y).minus(Big(start.y))
|
||||||
const length = dx.pow(2).plus(dy.pow(2)).sqrt().times(10).round().toNumber()
|
const length = dx.pow(2).plus(dy.pow(2)).sqrt().times(10).round().toNumber()
|
||||||
|
|
||||||
|
const direction = getDirectionByPoint(start, end)
|
||||||
|
|
||||||
|
let left, top
|
||||||
|
|
||||||
|
if (direction === 'bottom') {
|
||||||
|
left = (start.x + end.x) / 2 - 50
|
||||||
|
top = (start.y + end.y) / 2
|
||||||
|
} else if (direction === 'top') {
|
||||||
|
left = (start.x + end.x) / 2 + 30
|
||||||
|
top = (start.y + end.y) / 2
|
||||||
|
} else if (direction === 'left') {
|
||||||
|
left = (start.x + end.x) / 2
|
||||||
|
top = (start.y + end.y) / 2 - 30
|
||||||
|
} else if (direction === 'right') {
|
||||||
|
left = (start.x + end.x) / 2
|
||||||
|
top = (start.y + end.y) / 2 + 30
|
||||||
|
}
|
||||||
|
|
||||||
let midPoint
|
let midPoint
|
||||||
|
|
||||||
midPoint = new fabric.Point((start.x + end.x) / 2, (start.y + end.y) / 2)
|
midPoint = new fabric.Point(left, top)
|
||||||
|
|
||||||
const degree = Big(Math.atan2(dy.toNumber(), dx.toNumber())).times(180).div(Math.PI).toNumber()
|
const degree = Big(Math.atan2(dy.toNumber(), dx.toNumber())).times(180).div(Math.PI).toNumber()
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import { useContext, useEffect, useRef } from 'react'
|
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 QContextMenu from '@/components/common/context-menu/QContextMenu'
|
||||||
import PanelBatchStatistics from '@/components/floor-plan/modal/panelBatch/PanelBatchStatistics'
|
import PanelBatchStatistics from '@/components/floor-plan/modal/panelBatch/PanelBatchStatistics'
|
||||||
@ -11,7 +11,7 @@ import { useCanvas } from '@/hooks/useCanvas'
|
|||||||
import { usePlan } from '@/hooks/usePlan'
|
import { usePlan } from '@/hooks/usePlan'
|
||||||
import { useContextMenu } from '@/hooks/useContextMenu'
|
import { useContextMenu } from '@/hooks/useContextMenu'
|
||||||
import { useCanvasConfigInitialize } from '@/hooks/common/useCanvasConfigInitialize'
|
import { useCanvasConfigInitialize } from '@/hooks/common/useCanvasConfigInitialize'
|
||||||
import { currentMenuState } from '@/store/canvasAtom'
|
import { canvasZoomState, currentMenuState } from '@/store/canvasAtom'
|
||||||
import { totalDisplaySelector } from '@/store/settingAtom'
|
import { totalDisplaySelector } from '@/store/settingAtom'
|
||||||
import { POLYGON_TYPE } from '@/common/common'
|
import { POLYGON_TYPE } from '@/common/common'
|
||||||
import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
|
import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider'
|
||||||
@ -32,6 +32,7 @@ import { useEvent } from '@/hooks/useEvent'
|
|||||||
import { compasDegAtom } from '@/store/orientationAtom'
|
import { compasDegAtom } from '@/store/orientationAtom'
|
||||||
import { hotkeyStore } from '@/store/hotkeyAtom'
|
import { hotkeyStore } from '@/store/hotkeyAtom'
|
||||||
import { usePopup } from '@/hooks/usePopup'
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
|
import { outerLinePointsState } from '@/store/outerLineAtom'
|
||||||
|
|
||||||
export default function CanvasFrame() {
|
export default function CanvasFrame() {
|
||||||
const canvasRef = useRef(null)
|
const canvasRef = useRef(null)
|
||||||
@ -45,11 +46,13 @@ export default function CanvasFrame() {
|
|||||||
const totalDisplay = useRecoilValue(totalDisplaySelector) // 집계표 표시 여부
|
const totalDisplay = useRecoilValue(totalDisplaySelector) // 집계표 표시 여부
|
||||||
const { setIsGlobalLoading } = useContext(QcastContext)
|
const { setIsGlobalLoading } = useContext(QcastContext)
|
||||||
const resetModuleStatisticsState = useResetRecoilState(moduleStatisticsState)
|
const resetModuleStatisticsState = useResetRecoilState(moduleStatisticsState)
|
||||||
|
const resetOuterLinePoints = useResetRecoilState(outerLinePointsState)
|
||||||
const resetMakersState = useResetRecoilState(makersState)
|
const resetMakersState = useResetRecoilState(makersState)
|
||||||
const resetSelectedMakerState = useResetRecoilState(selectedMakerState)
|
const resetSelectedMakerState = useResetRecoilState(selectedMakerState)
|
||||||
const resetSeriesState = useResetRecoilState(seriesState)
|
const resetSeriesState = useResetRecoilState(seriesState)
|
||||||
const resetModelsState = useResetRecoilState(modelsState)
|
const resetModelsState = useResetRecoilState(modelsState)
|
||||||
const resetCompasDeg = useResetRecoilState(compasDegAtom)
|
const resetCompasDeg = useResetRecoilState(compasDegAtom)
|
||||||
|
const [zoom, setCanvasZoom] = useRecoilState(canvasZoomState)
|
||||||
const resetSelectedModelsState = useResetRecoilState(selectedModelsState)
|
const resetSelectedModelsState = useResetRecoilState(selectedModelsState)
|
||||||
const resetPcsCheckState = useResetRecoilState(pcsCheckState)
|
const resetPcsCheckState = useResetRecoilState(pcsCheckState)
|
||||||
const { handleModuleSelectionTotal } = useCanvasPopupStatusController()
|
const { handleModuleSelectionTotal } = useCanvasPopupStatusController()
|
||||||
@ -67,6 +70,13 @@ export default function CanvasFrame() {
|
|||||||
canvasLoadInit() //config된 상태로 캔버스 객체를 그린다
|
canvasLoadInit() //config된 상태로 캔버스 객체를 그린다
|
||||||
canvas?.renderAll() // 캔버스를 다시 그립니다.
|
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) {
|
if (canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE).length > 0) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setSelectedMenu('module')
|
setSelectedMenu('module')
|
||||||
@ -129,6 +139,7 @@ export default function CanvasFrame() {
|
|||||||
|
|
||||||
const resetRecoilData = () => {
|
const resetRecoilData = () => {
|
||||||
// resetModuleStatisticsState()
|
// resetModuleStatisticsState()
|
||||||
|
resetOuterLinePoints()
|
||||||
resetMakersState()
|
resetMakersState()
|
||||||
resetSelectedMakerState()
|
resetSelectedMakerState()
|
||||||
resetSeriesState()
|
resetSeriesState()
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import { useContext, useEffect, useState } from 'react'
|
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'
|
import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil'
|
||||||
|
|
||||||
@ -25,17 +25,18 @@ import { useCommonUtils } from '@/hooks/common/useCommonUtils'
|
|||||||
import useMenu from '@/hooks/common/useMenu'
|
import useMenu from '@/hooks/common/useMenu'
|
||||||
import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController'
|
import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController'
|
||||||
import { useAxios } from '@/hooks/useAxios'
|
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 { sessionStore } from '@/store/commonAtom'
|
||||||
import { outerLinePointsState } from '@/store/outerLineAtom'
|
import { outerLinePointsState } from '@/store/outerLineAtom'
|
||||||
import { appMessageStore, globalLocaleStore } from '@/store/localeAtom'
|
import { appMessageStore, globalLocaleStore } from '@/store/localeAtom'
|
||||||
import {
|
import { addedRoofsState, basicSettingState, selectedRoofMaterialSelector, settingModalFirstOptionsState } from '@/store/settingAtom'
|
||||||
addedRoofsState,
|
|
||||||
basicSettingState,
|
|
||||||
corridorDimensionSelector,
|
|
||||||
selectedRoofMaterialSelector,
|
|
||||||
settingModalFirstOptionsState,
|
|
||||||
} from '@/store/settingAtom'
|
|
||||||
import { placementShapeDrawingPointsState } from '@/store/placementShapeDrawingAtom'
|
import { placementShapeDrawingPointsState } from '@/store/placementShapeDrawingAtom'
|
||||||
import { commonUtilsState } from '@/store/commonUtilsAtom'
|
import { commonUtilsState } from '@/store/commonUtilsAtom'
|
||||||
import { menusState } from '@/store/menuAtom'
|
import { menusState } from '@/store/menuAtom'
|
||||||
@ -51,6 +52,7 @@ import { QcastContext } from '@/app/QcastProvider'
|
|||||||
import { useRoofFn } from '@/hooks/common/useRoofFn'
|
import { useRoofFn } from '@/hooks/common/useRoofFn'
|
||||||
import { usePolygon } from '@/hooks/usePolygon'
|
import { usePolygon } from '@/hooks/usePolygon'
|
||||||
import { useTrestle } from '@/hooks/module/useTrestle'
|
import { useTrestle } from '@/hooks/module/useTrestle'
|
||||||
|
|
||||||
export default function CanvasMenu(props) {
|
export default function CanvasMenu(props) {
|
||||||
const [currentCanvasPlan, setCurrentCanvasPlan] = useRecoilState(currentCanvasPlanState)
|
const [currentCanvasPlan, setCurrentCanvasPlan] = useRecoilState(currentCanvasPlanState)
|
||||||
const { selectedMenu, setSelectedMenu } = props
|
const { selectedMenu, setSelectedMenu } = props
|
||||||
@ -515,7 +517,10 @@ export default function CanvasMenu(props) {
|
|||||||
if (createUser === 'T01' && sessionState.storeId !== 'T01') {
|
if (createUser === 'T01' && sessionState.storeId !== 'T01') {
|
||||||
setAllButtonStyles('none')
|
setAllButtonStyles('none')
|
||||||
} else {
|
} else {
|
||||||
setEstimateContextState({ tempFlg: estimateRecoilState.tempFlg, lockFlg: estimateRecoilState.lockFlg })
|
setEstimateContextState({
|
||||||
|
tempFlg: estimateRecoilState.tempFlg,
|
||||||
|
lockFlg: estimateRecoilState.lockFlg,
|
||||||
|
})
|
||||||
handleButtonStyles(estimateRecoilState.tempFlg, estimateRecoilState.lockFlg, estimateContextState.docNo)
|
handleButtonStyles(estimateRecoilState.tempFlg, estimateRecoilState.lockFlg, estimateContextState.docNo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import { globalPitchState, pitchSelector, pitchTextSelector } from '@/store/canv
|
|||||||
import { useRecoilState } from 'recoil'
|
import { useRecoilState } from 'recoil'
|
||||||
import { useRef } from 'react'
|
import { useRef } from 'react'
|
||||||
import { usePopup } from '@/hooks/usePopup'
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
export default function Slope({ id, pos = { x: 50, y: 230 } }) {
|
export default function Slope({ id, pos = { x: 50, y: 230 } }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -22,7 +23,19 @@ export default function Slope({ id, pos = { x: 50, y: 230 } }) {
|
|||||||
{getMessage('slope')}
|
{getMessage('slope')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5">
|
<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>
|
</div>
|
||||||
<span className="thin">{pitchText}</span>
|
<span className="thin">{pitchText}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -8,6 +8,7 @@ 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'
|
import { normalizeDigits } from '@/util/input-utils'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
export default function AuxiliaryEdit(props) {
|
export default function AuxiliaryEdit(props) {
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
@ -66,7 +67,19 @@ 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(normalizeDigits(e.target.value))} />
|
{/*<input type="text" className="input-origin" value={verticalSize} onChange={(e) => setVerticalSize(normalizeDigits(e.target.value))} />*/}
|
||||||
|
<CalculatorInput
|
||||||
|
id=""
|
||||||
|
name=""
|
||||||
|
label=""
|
||||||
|
className="input-origin block"
|
||||||
|
value={verticalSize}
|
||||||
|
onChange={(value) => setVerticalSize(value)}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span>mm</span>
|
<span>mm</span>
|
||||||
<div className="direction-move-wrap">
|
<div className="direction-move-wrap">
|
||||||
@ -88,7 +101,19 @@ 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(normalizeDigits(e.target.value))} />
|
{/*<input type="text" className="input-origin" value={horizonSize} onChange={(e) => setHorizonSize(normalizeDigits(e.target.value))} />*/}
|
||||||
|
<CalculatorInput
|
||||||
|
id=""
|
||||||
|
name=""
|
||||||
|
label=""
|
||||||
|
className="input-origin block"
|
||||||
|
value={horizonSize}
|
||||||
|
onChange={(value) => setHorizonSize(value)}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span>mm</span>
|
<span>mm</span>
|
||||||
<div className="direction-move-wrap">
|
<div className="direction-move-wrap">
|
||||||
|
|||||||
@ -8,19 +8,21 @@ 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'
|
import { normalizeDigits } from '@/util/input-utils'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
export default function AuxiliarySize(props) {
|
export default function AuxiliarySize(props) {
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
const { id, pos = contextPopupPosition } = props
|
const { id, pos = contextPopupPosition } = props
|
||||||
const [checkedRadio, setCheckedRadio] = useState(null)
|
const [checkedRadio, setCheckedRadio] = useState(null)
|
||||||
const [value1, setValue1] = useState(null)
|
const [value1, setValue1] = useState('')
|
||||||
const [value2, setValue2] = useState(null)
|
const [value2, setValue2] = useState('')
|
||||||
const [size, setSize] = useState(0)
|
const [size, setSize] = useState(0)
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
const { closePopup } = usePopup()
|
const { closePopup } = usePopup()
|
||||||
const currentObject = useRecoilValue(currentObjectState)
|
const currentObject = useRecoilValue(currentObjectState)
|
||||||
const canvas = useRecoilValue(canvasState)
|
const canvas = useRecoilValue(canvasState)
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
canvas?.discardActiveObject()
|
canvas?.discardActiveObject()
|
||||||
@ -37,7 +39,7 @@ export default function AuxiliarySize(props) {
|
|||||||
}, [currentObject])
|
}, [currentObject])
|
||||||
|
|
||||||
const handleInput = (e) => {
|
const handleInput = (e) => {
|
||||||
let value = e.target.value.replace(/^0+/, '')
|
let value = e.replace(/^0+/, '')
|
||||||
if (value === '') {
|
if (value === '') {
|
||||||
if (checkedRadio === 1) setValue1(value)
|
if (checkedRadio === 1) setValue1(value)
|
||||||
if (checkedRadio === 2) setValue2(value)
|
if (checkedRadio === 2) setValue2(value)
|
||||||
@ -130,7 +132,20 @@ export default function AuxiliarySize(props) {
|
|||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<span style={{ width: 'auto' }}>{getMessage('length')}</span>
|
<span style={{ width: 'auto' }}>{getMessage('length')}</span>
|
||||||
<div className="input-grid mr5">
|
<div className="input-grid mr5">
|
||||||
<input type="text" className="input-origin block" value={value1} readOnly={checkedRadio !== 1} onChange={handleInput} />
|
{/*<input type="text" className="input-origin block" value={value1} readOnly={checkedRadio !== 1} onChange={handleInput} />*/}
|
||||||
|
<CalculatorInput
|
||||||
|
id=""
|
||||||
|
name=""
|
||||||
|
label=""
|
||||||
|
className="input-origin block"
|
||||||
|
value={value1}
|
||||||
|
onChange={handleInput}
|
||||||
|
readOnly={checkedRadio !== 1}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -149,7 +164,20 @@ export default function AuxiliarySize(props) {
|
|||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<span style={{ width: 'auto' }}>{getMessage('length')}</span>
|
<span style={{ width: 'auto' }}>{getMessage('length')}</span>
|
||||||
<div className="input-grid mr5">
|
<div className="input-grid mr5">
|
||||||
<input type="text" className="input-origin block" value={value2} readOnly={checkedRadio !== 2} onChange={handleInput} />
|
{/*<input type="text" className="input-origin block" value={value2} readOnly={checkedRadio !== 2} onChange={handleInput} />*/}
|
||||||
|
<CalculatorInput
|
||||||
|
id=""
|
||||||
|
name=""
|
||||||
|
label=""
|
||||||
|
className="input-origin block"
|
||||||
|
value={value2}
|
||||||
|
onChange={handleInput}
|
||||||
|
readOnly={checkedRadio !== 2}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</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 WithDraggable from '@/components/common/draggable/WithDraggable'
|
||||||
import { Orientation } from '@/components/floor-plan/modal/basic/step/Orientation'
|
import { Orientation } from '@/components/floor-plan/modal/basic/step/Orientation'
|
||||||
import PitchPlacement from '@/components/floor-plan/modal/basic/step/pitch/PitchPlacement'
|
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: trestleTrigger } = useCanvasPopupStatusController(2)
|
||||||
const { trigger: placementTrigger } = useCanvasPopupStatusController(3)
|
const { trigger: placementTrigger } = useCanvasPopupStatusController(3)
|
||||||
const [roofsStore, setRoofsStore] = useRecoilState(roofsState)
|
const [roofsStore, setRoofsStore] = useRecoilState(roofsState)
|
||||||
|
const [isFold, setIsFold] = useState(false)
|
||||||
|
|
||||||
// const { initEvent } = useContext(EventContext)
|
// const { initEvent } = useContext(EventContext)
|
||||||
const { manualModuleSetup, autoModuleSetup, manualFlatroofModuleSetup, autoFlatroofModuleSetup, manualModuleLayoutSetup, restoreModuleInstArea } =
|
const { manualModuleSetup, autoModuleSetup, manualFlatroofModuleSetup, autoFlatroofModuleSetup, manualModuleLayoutSetup, restoreModuleInstArea } =
|
||||||
@ -282,35 +283,42 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<WithDraggable isShow={true} pos={pos} className={basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' ? 'll' : 'lx-2'}>
|
<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>
|
<WithDraggable.Body>
|
||||||
<div className="roof-module-tab">
|
<div style={{ display: isFold ? 'none' : 'block' }}>
|
||||||
<div className={`module-tab-bx act`}>{getMessage('modal.module.basic.setting.orientation.setting')}</div>
|
<div className="roof-module-tab">
|
||||||
<span className={`tab-arr ${tabNum !== 1 ? 'act' : ''}`}></span>
|
<div className={`module-tab-bx act`}>{getMessage('modal.module.basic.setting.orientation.setting')}</div>
|
||||||
{basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && (
|
<span className={`tab-arr ${tabNum !== 1 ? 'act' : ''}`}></span>
|
||||||
<>
|
{basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && (
|
||||||
<div className={`module-tab-bx ${tabNum !== 1 ? 'act' : ''}`}>{getMessage('modal.module.basic.setting.module.setting')}</div>
|
<>
|
||||||
<span className={`tab-arr ${tabNum === 3 ? 'act' : ''}`}></span>
|
<div className={`module-tab-bx ${tabNum !== 1 ? 'act' : ''}`}>{getMessage('modal.module.basic.setting.module.setting')}</div>
|
||||||
<div className={`module-tab-bx ${tabNum === 3 ? 'act' : ''}`}>{getMessage('modal.module.basic.setting.module.placement')}</div>
|
<span className={`tab-arr ${tabNum === 3 ? 'act' : ''}`}></span>
|
||||||
</>
|
<div className={`module-tab-bx ${tabNum === 3 ? 'act' : ''}`}>{getMessage('modal.module.basic.setting.module.placement')}</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && (
|
||||||
|
<>
|
||||||
|
<div className={`module-tab-bx ${tabNum === 2 ? 'act' : ''}`}>{getMessage('modal.module.basic.setting.module.placement')}</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{tabNum === 1 && <Orientation ref={orientationRef} {...orientationProps} />}
|
||||||
|
{/*배치면 초기설정 - 입력방법: 복시도 입력 || 실측값 입력*/}
|
||||||
|
{basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && tabNum === 2 && <Trestle ref={trestleRef} {...trestleProps} />}
|
||||||
|
{basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && tabNum === 3 && (
|
||||||
|
<Placement setTabNum={setTabNum} layoutSetup={layoutSetup} setLayoutSetup={setLayoutSetup} />
|
||||||
)}
|
)}
|
||||||
{basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && (
|
{/*배치면 초기설정 - 입력방법: 육지붕*/}
|
||||||
<>
|
{/* {basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && tabNum === 3 && <PitchModule setTabNum={setTabNum} />} */}
|
||||||
<div className={`module-tab-bx ${tabNum === 2 ? 'act' : ''}`}>{getMessage('modal.module.basic.setting.module.placement')}</div>
|
{basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && tabNum === 2 && (
|
||||||
</>
|
<PitchPlacement setTabNum={setTabNum} ref={placementFlatRef} />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{tabNum === 1 && <Orientation ref={orientationRef} {...orientationProps} />}
|
|
||||||
{/*배치면 초기설정 - 입력방법: 복시도 입력 || 실측값 입력*/}
|
|
||||||
{basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && tabNum === 2 && <Trestle ref={trestleRef} {...trestleProps} />}
|
|
||||||
{basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && tabNum === 3 && (
|
|
||||||
<Placement setTabNum={setTabNum} layoutSetup={layoutSetup} setLayoutSetup={setLayoutSetup} />
|
|
||||||
)}
|
|
||||||
{/*배치면 초기설정 - 입력방법: 육지붕*/}
|
|
||||||
{/* {basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && tabNum === 3 && <PitchModule setTabNum={setTabNum} />} */}
|
|
||||||
{basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && tabNum === 2 && (
|
|
||||||
<PitchPlacement setTabNum={setTabNum} ref={placementFlatRef} />
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div className="grid-btn-wrap">
|
<div className="grid-btn-wrap">
|
||||||
{/* {tabNum === 1 && <button className="btn-frame modal mr5">{getMessage('modal.common.save')}</button>} */}
|
{/* {tabNum === 1 && <button className="btn-frame modal mr5">{getMessage('modal.common.save')}</button>} */}
|
||||||
|
|||||||
@ -98,7 +98,7 @@ export const Orientation = forwardRef((props, ref) => {
|
|||||||
if (moduleSeriesList.length > 0 && foundModule.moduleSerCd) {
|
if (moduleSeriesList.length > 0 && foundModule.moduleSerCd) {
|
||||||
const currentSeries = moduleSeriesList.find(series => series.moduleSerCd === foundModule.moduleSerCd)
|
const currentSeries = moduleSeriesList.find(series => series.moduleSerCd === foundModule.moduleSerCd)
|
||||||
if (currentSeries && (!selectedModuleSeries || selectedModuleSeries.moduleSerCd !== currentSeries.moduleSerCd)) {
|
if (currentSeries && (!selectedModuleSeries || selectedModuleSeries.moduleSerCd !== currentSeries.moduleSerCd)) {
|
||||||
setSelectedModuleSeries(currentSeries)
|
//setSelectedModuleSeries(currentSeries)
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
setSelectedModuleSeries(allOption)
|
setSelectedModuleSeries(allOption)
|
||||||
|
|||||||
@ -20,8 +20,8 @@ import { useEstimate } from '@/hooks/useEstimate'
|
|||||||
import { useCircuitTrestle } from '@/hooks/useCirCuitTrestle'
|
import { useCircuitTrestle } from '@/hooks/useCirCuitTrestle'
|
||||||
import { useImgLoader } from '@/hooks/floorPlan/useImgLoader'
|
import { useImgLoader } from '@/hooks/floorPlan/useImgLoader'
|
||||||
import { QcastContext } from '@/app/QcastProvider'
|
import { QcastContext } from '@/app/QcastProvider'
|
||||||
import { fabric } from 'fabric'
|
|
||||||
import { fontSelector } from '@/store/fontAtom'
|
import { fontSelector } from '@/store/fontAtom'
|
||||||
|
import { fabric } from 'fabric'
|
||||||
|
|
||||||
const ALLOCATION_TYPE = {
|
const ALLOCATION_TYPE = {
|
||||||
AUTO: 'auto',
|
AUTO: 'auto',
|
||||||
@ -59,6 +59,9 @@ export default function CircuitTrestleSetting({ id }) {
|
|||||||
const passivityCircuitAllocationRef = useRef()
|
const passivityCircuitAllocationRef = useRef()
|
||||||
const { setIsGlobalLoading } = useContext(QcastContext)
|
const { setIsGlobalLoading } = useContext(QcastContext)
|
||||||
|
|
||||||
|
const originCanvasViewPortTransform = useRef([])
|
||||||
|
const [isFold, setIsFold] = useState(false)
|
||||||
|
|
||||||
const {
|
const {
|
||||||
makers,
|
makers,
|
||||||
setMakers,
|
setMakers,
|
||||||
@ -83,6 +86,7 @@ export default function CircuitTrestleSetting({ id }) {
|
|||||||
} = useCircuitTrestle()
|
} = useCircuitTrestle()
|
||||||
// const { trigger: moduleSelectedDataTrigger } = useCanvasPopupStatusController(2)
|
// const { trigger: moduleSelectedDataTrigger } = useCanvasPopupStatusController(2)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
originCanvasViewPortTransform.current = [...canvas.viewportTransform]
|
||||||
if (!managementState) {
|
if (!managementState) {
|
||||||
}
|
}
|
||||||
// setCircuitData({
|
// 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
|
let x, y
|
||||||
x = canvas.width / 2
|
x = canvas.width / 2
|
||||||
y = canvas.height / 2
|
y = canvas.height / 2
|
||||||
|
|
||||||
canvas.zoomToPoint(new fabric.Point(x, y), 0.4)
|
canvas.zoomToPoint(new fabric.Point(x, y), 0.4)
|
||||||
|
|
||||||
changeFontSize('lengthText', '28')
|
changeFontSize('lengthText', '28')
|
||||||
changeFontSize('circuitNumber', '28')
|
changeFontSize('circuitNumber', '28')
|
||||||
changeFontSize('flowText', '28')
|
changeFontSize('flowText', '28')
|
||||||
@ -188,9 +189,12 @@ export default function CircuitTrestleSetting({ id }) {
|
|||||||
|
|
||||||
// 캡쳐 후 처리
|
// 캡쳐 후 처리
|
||||||
const afterCapture = (type) => {
|
const afterCapture = (type) => {
|
||||||
setCanvasZoom(100)
|
if (originCanvasViewPortTransform.current[0] !== 1) {
|
||||||
canvas.set({ zoom: 1 })
|
setCanvasZoom(Number((originCanvasViewPortTransform.current[0] * 100).toFixed(0)))
|
||||||
canvas.viewportTransform = [1, 0, 0, 1, 0, 0]
|
}
|
||||||
|
canvas.viewportTransform = [...originCanvasViewPortTransform.current]
|
||||||
|
canvas.renderAll()
|
||||||
|
|
||||||
changeFontSize('lengthText', lengthText.fontSize.value)
|
changeFontSize('lengthText', lengthText.fontSize.value)
|
||||||
changeFontSize('circuitNumber', circuitNumberText.fontSize.value)
|
changeFontSize('circuitNumber', circuitNumberText.fontSize.value)
|
||||||
changeFontSize('flowText', flowText.fontSize.value)
|
changeFontSize('flowText', flowText.fontSize.value)
|
||||||
@ -223,11 +227,33 @@ export default function CircuitTrestleSetting({ id }) {
|
|||||||
return
|
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 = {
|
const params = {
|
||||||
...getOptYn(),
|
...getOptYn(),
|
||||||
useModuleItemList: getUseModuleItemList(),
|
useModuleItemList: getUseModuleItemList(),
|
||||||
roofSurfaceList: getRoofSurfaceList(),
|
roofSurfaceList: getRoofSurfaceList(),
|
||||||
pcsItemList: getPcsItemList(),
|
pcsItemList: getPcsItemList(isMultiModule),
|
||||||
}
|
}
|
||||||
|
|
||||||
// 파워컨디셔너 추천 목록 조회
|
// 파워컨디셔너 추천 목록 조회
|
||||||
@ -288,12 +314,12 @@ export default function CircuitTrestleSetting({ id }) {
|
|||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// 회로 구성 가능 여부 체크
|
// 회로 구성 가능 여부 체크
|
||||||
getPcsVoltageChk({ ...params, pcsItemList: getSelectedPcsItemList() }).then((res) => {
|
getPcsVoltageChk({ ...params, pcsItemList: getSelectedPcsItemList(isMultiModule) }).then((res) => {
|
||||||
if (res.resultCode === 'S') {
|
if (res.resultCode === 'S') {
|
||||||
// 회로 구성 가능 여부 체크 통과 시 승압설정 정보 조회
|
// 회로 구성 가능 여부 체크 통과 시 승압설정 정보 조회
|
||||||
getPcsVoltageStepUpList({
|
getPcsVoltageStepUpList({
|
||||||
...params,
|
...params,
|
||||||
pcsItemList: getSelectedPcsItemList(),
|
pcsItemList: getSelectedPcsItemList(isMultiModule),
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
if (res?.result.resultCode === 'S' && res?.data) {
|
if (res?.result.resultCode === 'S' && res?.data) {
|
||||||
setTabNum(2)
|
setTabNum(2)
|
||||||
@ -519,6 +545,7 @@ export default function CircuitTrestleSetting({ id }) {
|
|||||||
obj.circuit = null
|
obj.circuit = null
|
||||||
obj.pcsItemId = null
|
obj.pcsItemId = null
|
||||||
obj.circuitNumber = null
|
obj.circuitNumber = null
|
||||||
|
obj.pcs = null
|
||||||
})
|
})
|
||||||
setSelectedModels(
|
setSelectedModels(
|
||||||
JSON.parse(JSON.stringify(selectedModels)).map((model) => {
|
JSON.parse(JSON.stringify(selectedModels)).map((model) => {
|
||||||
@ -788,20 +815,30 @@ export default function CircuitTrestleSetting({ id }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<WithDraggable isShow={true} pos={{ x: 50, y: 230 }} className="l-2">
|
<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>
|
<WithDraggable.Body>
|
||||||
<div className="roof-module-tab">
|
<div style={{ display: !(tabNum === 1 && allocationType === ALLOCATION_TYPE.PASSIVITY) && isFold ? 'none' : 'block' }}>
|
||||||
<div className={`module-tab-bx act`}>{getMessage('modal.circuit.trestle.setting.power.conditional.select')}</div>
|
<div style={{ display: tabNum === 1 && allocationType === ALLOCATION_TYPE.PASSIVITY && isFold ? 'none' : 'block' }}>
|
||||||
<span className={`tab-arr ${tabNum === 2 ? 'act' : ''}`}></span>
|
<div className="roof-module-tab">
|
||||||
<div className={`module-tab-bx ${tabNum === 2 ? 'act' : ''}`}>
|
<div className={`module-tab-bx act`}>{getMessage('modal.circuit.trestle.setting.power.conditional.select')}</div>
|
||||||
{getMessage('modal.circuit.trestle.setting.circuit.allocation')}({getMessage('modal.circuit.trestle.setting.step.up.allocation')})
|
<span className={`tab-arr ${tabNum === 2 ? 'act' : ''}`}></span>
|
||||||
|
<div className={`module-tab-bx ${tabNum === 2 ? 'act' : ''}`}>
|
||||||
|
{getMessage('modal.circuit.trestle.setting.circuit.allocation')}({getMessage('modal.circuit.trestle.setting.step.up.allocation')})
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{tabNum === 1 && allocationType === ALLOCATION_TYPE.AUTO && <PowerConditionalSelect {...powerConditionalSelectProps} />}
|
||||||
|
{tabNum === 1 && allocationType === ALLOCATION_TYPE.PASSIVITY && (
|
||||||
|
<PassivityCircuitAllocation {...passivityProps} ref={passivityCircuitAllocationRef} isFold={isFold} />
|
||||||
|
)}
|
||||||
|
{tabNum === 2 && <StepUp {...stepUpProps} onInitialize={handleStepUpInitialize} />}
|
||||||
</div>
|
</div>
|
||||||
{tabNum === 1 && allocationType === ALLOCATION_TYPE.AUTO && <PowerConditionalSelect {...powerConditionalSelectProps} />}
|
|
||||||
{tabNum === 1 && allocationType === ALLOCATION_TYPE.PASSIVITY && (
|
|
||||||
<PassivityCircuitAllocation {...passivityProps} ref={passivityCircuitAllocationRef} />
|
|
||||||
)}
|
|
||||||
{tabNum === 2 && <StepUp {...stepUpProps} onInitialize={handleStepUpInitialize} />}
|
|
||||||
{tabNum === 1 && allocationType === ALLOCATION_TYPE.AUTO && (
|
{tabNum === 1 && allocationType === ALLOCATION_TYPE.AUTO && (
|
||||||
<div className="grid-btn-wrap">
|
<div className="grid-btn-wrap">
|
||||||
<button className="btn-frame modal mr5 act" onClick={() => onAutoRecommend()}>
|
<button className="btn-frame modal mr5 act" onClick={() => onAutoRecommend()}>
|
||||||
|
|||||||
@ -200,6 +200,7 @@ export default function PowerConditionalSelect(props) {
|
|||||||
const param = {
|
const param = {
|
||||||
pcsMkrCd: option.pcsMkrCd,
|
pcsMkrCd: option.pcsMkrCd,
|
||||||
mixMatlNo: moduleSelectionData.module.mixMatlNo,
|
mixMatlNo: moduleSelectionData.module.mixMatlNo,
|
||||||
|
moduleMatlCds: moduleSelectionData.module.itemList.map((item) => item.itemId).join(','),
|
||||||
}
|
}
|
||||||
|
|
||||||
getPcsMakerList(param).then((res) => {
|
getPcsMakerList(param).then((res) => {
|
||||||
|
|||||||
@ -649,7 +649,13 @@ export default function StepUp(props) {
|
|||||||
style={{ cursor: allocationType === 'auto' ? 'pointer' : 'default' }}
|
style={{ cursor: allocationType === 'auto' ? 'pointer' : 'default' }}
|
||||||
>
|
>
|
||||||
<td className="al-r">{item.serQty}</td>
|
<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>
|
</tr>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { GlobalDataContext } from '@/app/GlobalDataProvider'
|
import { GlobalDataContext } from '@/app/GlobalDataProvider'
|
||||||
import { POLYGON_TYPE } from '@/common/common'
|
import { POLYGON_TYPE } from '@/common/common'
|
||||||
import { useMasterController } from '@/hooks/common/useMasterController'
|
import { useMasterController } from '@/hooks/common/useMasterController'
|
||||||
import { useModule } from '@/hooks/module/useModule'
|
|
||||||
import { useCircuitTrestle } from '@/hooks/useCirCuitTrestle'
|
import { useCircuitTrestle } from '@/hooks/useCirCuitTrestle'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
@ -10,8 +9,8 @@ import { moduleStatisticsState } from '@/store/circuitTrestleAtom'
|
|||||||
import { fontSelector } from '@/store/fontAtom'
|
import { fontSelector } from '@/store/fontAtom'
|
||||||
import { selectedModuleState } from '@/store/selectedModuleOptions'
|
import { selectedModuleState } from '@/store/selectedModuleOptions'
|
||||||
import { circuitNumDisplaySelector } from '@/store/settingAtom'
|
import { circuitNumDisplaySelector } from '@/store/settingAtom'
|
||||||
import { useContext, useEffect, useState } from 'react'
|
import { useContext, useEffect, useRef, useState } from 'react'
|
||||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
import { useRecoilValue } from 'recoil'
|
||||||
import { normalizeDigits } from '@/util/input-utils'
|
import { normalizeDigits } from '@/util/input-utils'
|
||||||
|
|
||||||
export default function PassivityCircuitAllocation(props) {
|
export default function PassivityCircuitAllocation(props) {
|
||||||
@ -22,6 +21,7 @@ export default function PassivityCircuitAllocation(props) {
|
|||||||
getOptYn: getApiProps,
|
getOptYn: getApiProps,
|
||||||
getUseModuleItemList: getSelectedModuleList,
|
getUseModuleItemList: getSelectedModuleList,
|
||||||
getSelectModelList: getSelectModelList,
|
getSelectModelList: getSelectModelList,
|
||||||
|
isFold,
|
||||||
} = props
|
} = props
|
||||||
const { swalFire } = useSwal()
|
const { swalFire } = useSwal()
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -32,6 +32,7 @@ export default function PassivityCircuitAllocation(props) {
|
|||||||
const { header, rows, footer } = useRecoilValue(moduleStatisticsState)
|
const { header, rows, footer } = useRecoilValue(moduleStatisticsState)
|
||||||
const [circuitNumber, setCircuitNumber] = useState(1)
|
const [circuitNumber, setCircuitNumber] = useState(1)
|
||||||
const [targetModules, setTargetModules] = useState([])
|
const [targetModules, setTargetModules] = useState([])
|
||||||
|
const targetModulesRef = useRef([])
|
||||||
const { getPcsManualConfChk } = useMasterController()
|
const { getPcsManualConfChk } = useMasterController()
|
||||||
const isDisplayCircuitNumber = useRecoilValue(circuitNumDisplaySelector)
|
const isDisplayCircuitNumber = useRecoilValue(circuitNumDisplaySelector)
|
||||||
const { setModuleStatisticsData } = useCircuitTrestle()
|
const { setModuleStatisticsData } = useCircuitTrestle()
|
||||||
@ -59,6 +60,10 @@ export default function PassivityCircuitAllocation(props) {
|
|||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
targetModulesRef.current = targetModules
|
||||||
|
}, [targetModules])
|
||||||
|
|
||||||
const handleTargetModules = (obj) => {
|
const handleTargetModules = (obj) => {
|
||||||
if (!Array.isArray(targetModules)) {
|
if (!Array.isArray(targetModules)) {
|
||||||
setTargetModules([])
|
setTargetModules([])
|
||||||
@ -79,6 +84,7 @@ export default function PassivityCircuitAllocation(props) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleCircuitNumberFix = () => {
|
const handleCircuitNumberFix = () => {
|
||||||
|
const pcsTpCd = selectedPcs.pcsTpCd // 실내집중형, 옥외멀티형
|
||||||
let uniqueCircuitNumbers = [
|
let uniqueCircuitNumbers = [
|
||||||
...new Set(
|
...new Set(
|
||||||
canvas
|
canvas
|
||||||
@ -91,13 +97,13 @@ export default function PassivityCircuitAllocation(props) {
|
|||||||
const surfaceList = targetModules.map((module) => {
|
const surfaceList = targetModules.map((module) => {
|
||||||
return canvas.getObjects().filter((obj) => obj.id === canvas.getObjects().filter((obj) => obj.id === module)[0].surfaceId)[0]
|
return canvas.getObjects().filter((obj) => obj.id === canvas.getObjects().filter((obj) => obj.id === module)[0].surfaceId)[0]
|
||||||
})
|
})
|
||||||
|
let surfaceType = {}
|
||||||
|
|
||||||
|
surfaceList.forEach((surface) => {
|
||||||
|
surfaceType[`${surface.direction}-${surface.roofMaterial.pitch}`] = surface
|
||||||
|
})
|
||||||
|
|
||||||
if (surfaceList.length > 1) {
|
if (surfaceList.length > 1) {
|
||||||
let surfaceType = {}
|
|
||||||
|
|
||||||
surfaceList.forEach((surface) => {
|
|
||||||
surfaceType[`${surface.direction}-${surface.roofMaterial.pitch}`] = surface
|
|
||||||
})
|
|
||||||
if (Object.keys(surfaceType).length > 1) {
|
if (Object.keys(surfaceType).length > 1) {
|
||||||
swalFire({
|
swalFire({
|
||||||
text: getMessage('module.circuit.fix.not.same.roof.error'),
|
text: getMessage('module.circuit.fix.not.same.roof.error'),
|
||||||
@ -107,6 +113,7 @@ export default function PassivityCircuitAllocation(props) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!circuitNumber || circuitNumber === 0) {
|
if (!circuitNumber || circuitNumber === 0) {
|
||||||
swalFire({
|
swalFire({
|
||||||
text: getMessage('module.circuit.minimun.error'),
|
text: getMessage('module.circuit.minimun.error'),
|
||||||
@ -114,31 +121,65 @@ export default function PassivityCircuitAllocation(props) {
|
|||||||
icon: 'warning',
|
icon: 'warning',
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
} else if (targetModules.length === 0) {
|
}
|
||||||
|
|
||||||
|
if (targetModules.length === 0) {
|
||||||
swalFire({
|
swalFire({
|
||||||
text: getMessage('module.not.found'),
|
text: getMessage('module.not.found'),
|
||||||
type: 'alert',
|
type: 'alert',
|
||||||
icon: 'warning',
|
icon: 'warning',
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
} else if (selectedModels.length > 1) {
|
}
|
||||||
let result = false
|
|
||||||
|
|
||||||
uniqueCircuitNumbers.forEach((number) => {
|
switch (pcsTpCd) {
|
||||||
if (
|
case 'INDFCS': {
|
||||||
number.split('-')[1] === circuitNumber + ')' &&
|
const originHaveThisPcsModules = canvas
|
||||||
number.split('-')[0] !== '(' + (selectedModels.findIndex((model) => model.id === selectedPcs.id) + 1)
|
.getObjects()
|
||||||
) {
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE && obj.pcs && obj.pcs.id === selectedPcs.id)
|
||||||
result = true
|
// 이미 해당 pcs로 설치된 모듈의 surface의 방향을 구한다.
|
||||||
}
|
const originSurfaceList = canvas
|
||||||
})
|
.getObjects()
|
||||||
if (result) {
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && originHaveThisPcsModules.map((obj) => obj.surfaceId).includes(obj.id))
|
||||||
swalFire({
|
|
||||||
text: getMessage('module.already.exist.error'),
|
originSurfaceList.concat(originSurfaceList).forEach((surface) => {
|
||||||
type: 'alert',
|
surfaceType[`${surface.direction}-${surface.roofMaterial.pitch}`] = surface
|
||||||
icon: 'warning',
|
|
||||||
})
|
})
|
||||||
return
|
|
||||||
|
if (surfaceList.length > 1) {
|
||||||
|
if (Object.keys(surfaceType).length > 1) {
|
||||||
|
swalFire({
|
||||||
|
text: getMessage('module.circuit.fix.not.same.roof.error'),
|
||||||
|
type: 'alert',
|
||||||
|
icon: 'warning',
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'OUTDMULTI': {
|
||||||
|
if (selectedModels.length > 1) {
|
||||||
|
let result = false
|
||||||
|
|
||||||
|
uniqueCircuitNumbers.forEach((number) => {
|
||||||
|
if (
|
||||||
|
number.split('-')[1] === circuitNumber + ')' &&
|
||||||
|
number.split('-')[0] !== '(' + (selectedModels.findIndex((model) => model.id === selectedPcs.id) + 1)
|
||||||
|
) {
|
||||||
|
result = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (result) {
|
||||||
|
swalFire({
|
||||||
|
text: getMessage('module.already.exist.error'),
|
||||||
|
type: 'alert',
|
||||||
|
icon: 'warning',
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,6 +230,7 @@ export default function PassivityCircuitAllocation(props) {
|
|||||||
roofSurfaceId: surface.id,
|
roofSurfaceId: surface.id,
|
||||||
roofSurface: surface.direction,
|
roofSurface: surface.direction,
|
||||||
roofSurfaceIncl: +canvas.getObjects().filter((obj) => obj.id === surface.parentId)[0].pitch,
|
roofSurfaceIncl: +canvas.getObjects().filter((obj) => obj.id === surface.parentId)[0].pitch,
|
||||||
|
roofSurfaceNorthYn: surface.direction === 'north' ? 'Y' : 'N',
|
||||||
moduleList: surface.modules.map((module) => {
|
moduleList: surface.modules.map((module) => {
|
||||||
return {
|
return {
|
||||||
itemId: module.moduleInfo.itemId,
|
itemId: module.moduleInfo.itemId,
|
||||||
@ -270,6 +312,12 @@ export default function PassivityCircuitAllocation(props) {
|
|||||||
return
|
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([])
|
setTargetModules([])
|
||||||
setCircuitNumber(+circuitNumber + 1)
|
setCircuitNumber(+circuitNumber + 1)
|
||||||
setModuleStatisticsData()
|
setModuleStatisticsData()
|
||||||
@ -497,73 +545,77 @@ export default function PassivityCircuitAllocation(props) {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="properties-setting-wrap outer">
|
<div className="properties-setting-wrap outer">
|
||||||
<div className="setting-tit">{getMessage('modal.circuit.trestle.setting.circuit.allocation')}</div>
|
<div style={{ display: isFold ? 'none' : 'block' }}>
|
||||||
<div className="module-table-box mb10">
|
<div className="setting-tit">{getMessage('modal.circuit.trestle.setting.circuit.allocation')}</div>
|
||||||
<div className="module-table-inner">
|
<div className="module-table-box mb10">
|
||||||
<div className="bold-font mb10">{getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity')}</div>
|
<div className="module-table-inner">
|
||||||
<div className="normal-font mb15">{getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.info')}</div>
|
<div className="bold-font mb10">{getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity')}</div>
|
||||||
<div className="roof-module-table overflow-y">
|
<div className="normal-font mb15">{getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.info')}</div>
|
||||||
{header && (
|
<div className="roof-module-table overflow-y">
|
||||||
<table>
|
{header && (
|
||||||
<thead>
|
<table>
|
||||||
<tr>
|
<thead>
|
||||||
{header.map((header, index) => (
|
<tr>
|
||||||
<th key={'header' + index}>{header.name}</th>
|
{header.map((header, index) => (
|
||||||
|
<th key={'header' + index}>{header.name}</th>
|
||||||
|
))}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{rows.map((row, index) => (
|
||||||
|
<tr key={'row' + index}>
|
||||||
|
{header.map((header, i) => (
|
||||||
|
<td className="al-c" key={'rowcell' + i}>
|
||||||
|
{typeof row[header.prop] === 'number'
|
||||||
|
? (row[header.prop] ?? 0).toLocaleString('ko-KR', { maximumFractionDigits: 4 })
|
||||||
|
: (row[header.prop] ?? 0)}
|
||||||
|
</td>
|
||||||
|
))}
|
||||||
|
</tr>
|
||||||
))}
|
))}
|
||||||
</tr>
|
<tr>
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{rows.map((row, index) => (
|
|
||||||
<tr key={'row' + index}>
|
|
||||||
{header.map((header, i) => (
|
{header.map((header, i) => (
|
||||||
<td className="al-c" key={'rowcell' + i}>
|
<td className="al-c" key={'footer' + i}>
|
||||||
{typeof row[header.prop] === 'number'
|
{footer[header.prop]}
|
||||||
? (row[header.prop] ?? 0).toLocaleString('ko-KR', { maximumFractionDigits: 4 })
|
|
||||||
: (row[header.prop] ?? 0)}
|
|
||||||
</td>
|
</td>
|
||||||
))}
|
))}
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
</tbody>
|
||||||
<tr>
|
</table>
|
||||||
{header.map((header, i) => (
|
)}
|
||||||
<td className="al-c" key={'footer' + i}>
|
</div>
|
||||||
{footer[header.prop]}
|
|
||||||
</td>
|
|
||||||
))}
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div className="module-table-box mb10">
|
||||||
<div className="module-table-box mb10">
|
<div className="module-table-inner">
|
||||||
<div className="module-table-inner">
|
<div className="hexagonal-wrap">
|
||||||
<div className="hexagonal-wrap">
|
<div className="hexagonal-item">
|
||||||
<div className="hexagonal-item">
|
<div className="bold-font">
|
||||||
<div className="bold-font">{getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.selected.power.conditional')}</div>
|
{getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.selected.power.conditional')}
|
||||||
</div>
|
|
||||||
<div className="hexagonal-item">
|
|
||||||
{selectedModels.map((model, index) => (
|
|
||||||
<div className="d-check-radio pop mb10" key={'model' + index}>
|
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
name="radio01"
|
|
||||||
id={`ra0${index + 1}`}
|
|
||||||
value={model}
|
|
||||||
checked={selectedPcs?.id === model.id}
|
|
||||||
onChange={() => setSelectedPcs(model)}
|
|
||||||
/>
|
|
||||||
<label htmlFor={`ra0${index + 1}`}>
|
|
||||||
{model.goodsNo} (
|
|
||||||
{getMessage(
|
|
||||||
'modal.circuit.trestle.setting.circuit.allocation.passivity.circuit.info',
|
|
||||||
managementState?.coldRegionFlg === '1' ? [model.serMinQty, model.serColdZoneMaxQty] : [model.serMinQty, model.serMaxQty],
|
|
||||||
)}
|
|
||||||
)
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
))}
|
</div>
|
||||||
|
<div className="hexagonal-item">
|
||||||
|
{selectedModels.map((model, index) => (
|
||||||
|
<div className="d-check-radio pop mb10" key={'model' + index}>
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="radio01"
|
||||||
|
id={`ra0${index + 1}`}
|
||||||
|
value={model}
|
||||||
|
checked={selectedPcs?.id === model.id}
|
||||||
|
onChange={() => setSelectedPcs(model)}
|
||||||
|
/>
|
||||||
|
<label htmlFor={`ra0${index + 1}`}>
|
||||||
|
{model.goodsNo} (
|
||||||
|
{getMessage(
|
||||||
|
'modal.circuit.trestle.setting.circuit.allocation.passivity.circuit.info',
|
||||||
|
managementState?.coldRegionFlg === '1' ? [model.serMinQty, model.serColdZoneMaxQty] : [model.serMinQty, model.serMaxQty],
|
||||||
|
)}
|
||||||
|
)
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -4,6 +4,7 @@ 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'
|
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
export default function Eaves({ pitchRef, offsetRef, widthRef, radioTypeRef, pitchText }) {
|
export default function Eaves({ pitchRef, offsetRef, widthRef, radioTypeRef, pitchText }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -21,17 +22,32 @@ 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
|
{/*<input*/}
|
||||||
type="text"
|
{/* 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"
|
className="input-origin block"
|
||||||
defaultValue={currentAngleType === ANGLE_TYPE.SLOPE ? 4 : 21.8}
|
|
||||||
ref={pitchRef}
|
ref={pitchRef}
|
||||||
onChange={(e) => {
|
value={currentAngleType === ANGLE_TYPE.SLOPE ? 4 : 21.8}
|
||||||
const v = normalizeDecimalLimit(e.target.value, 2)
|
onChange={(value) => {
|
||||||
e.target.value = v
|
if (pitchRef?.current) pitchRef.current.value = value
|
||||||
if (pitchRef?.current) pitchRef.current.value = v
|
|
||||||
}}
|
}}
|
||||||
/>
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: true //(index !== 0),
|
||||||
|
}}
|
||||||
|
></CalculatorInput>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">{pitchText}</span>
|
<span className="thin">{pitchText}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -40,17 +56,32 @@ 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
|
{/*<input*/}
|
||||||
type="text"
|
{/* 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"
|
className="input-origin block"
|
||||||
defaultValue={500}
|
|
||||||
ref={offsetRef}
|
ref={offsetRef}
|
||||||
onChange={(e) => {
|
value={500}
|
||||||
const v = normalizeDigits(e.target.value)
|
onChange={(value) => {
|
||||||
e.target.value = v
|
if (offsetRef?.current) offsetRef.current.value = value
|
||||||
if (offsetRef?.current) offsetRef.current.value = v
|
|
||||||
}}
|
}}
|
||||||
/>
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false //(index !== 0),
|
||||||
|
}}
|
||||||
|
></CalculatorInput>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -91,18 +122,33 @@ 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
|
{/*<input*/}
|
||||||
type="text"
|
{/* 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"
|
className="input-origin block"
|
||||||
defaultValue={500}
|
|
||||||
ref={widthRef}
|
ref={widthRef}
|
||||||
readOnly={type === '1'}
|
value={500}
|
||||||
onChange={(e) => {
|
onChange={(value) => {
|
||||||
const v = normalizeDigits(e.target.value)
|
if (widthRef?.current) widthRef.current.value = value
|
||||||
e.target.value = v
|
|
||||||
if (widthRef?.current) widthRef.current.value = v
|
|
||||||
}}
|
}}
|
||||||
/>
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false //(index !== 0),
|
||||||
|
}}
|
||||||
|
></CalculatorInput>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</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 { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
export default function Gable({ pitchRef, offsetRef, widthRef, radioTypeRef, pitchText }) {
|
export default function Gable({ pitchRef, offsetRef, widthRef, radioTypeRef, pitchText }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -21,7 +22,19 @@ export default function Gable({ 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={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>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -65,13 +78,29 @@ export default function Gable({ 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
|
{/*<input*/}
|
||||||
type="text"
|
{/* 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"
|
className="input-origin block"
|
||||||
defaultValue={currentAngleType === ANGLE_TYPE.SLOPE ? 4.5 : 20}
|
|
||||||
ref={pitchRef}
|
ref={pitchRef}
|
||||||
|
value={currentAngleType === ANGLE_TYPE.SLOPE ? 4.5 : 20}
|
||||||
readOnly={type === '1'}
|
readOnly={type === '1'}
|
||||||
/>
|
onChange={(value) => {
|
||||||
|
if (pitchRef?.current) pitchRef.current.value = value
|
||||||
|
}}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: true //(index !== 0),
|
||||||
|
}}
|
||||||
|
></CalculatorInput>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">{pitchText}</span>
|
<span className="thin">{pitchText}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -91,7 +120,20 @@ export default function Gable({ 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={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>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
export default function Shed({ offsetRef }) {
|
export default function Shed({ offsetRef }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -10,7 +11,19 @@ export default function Shed({ offsetRef }) {
|
|||||||
{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" 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>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import Image from 'next/image'
|
import Image from 'next/image'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
export default function WallMerge({ offsetRef, radioTypeRef }) {
|
export default function WallMerge({ offsetRef, radioTypeRef }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -51,7 +52,20 @@ export default function WallMerge({ offsetRef, radioTypeRef }) {
|
|||||||
{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={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>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import Image from 'next/image'
|
import Image from 'next/image'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
export default function Angle({ props }) {
|
export default function Angle({ props }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -14,14 +15,29 @@ export default function Angle({ props }) {
|
|||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<span className="mr10">{getMessage('modal.cover.outline.angle')}</span>
|
<span className="mr10">{getMessage('modal.cover.outline.angle')}</span>
|
||||||
<div className="input-grid" style={{ width: '63px' }}>
|
<div className="input-grid" style={{ width: '63px' }}>
|
||||||
<input
|
{/*<input*/}
|
||||||
type="text"
|
{/* 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"
|
className="input-origin block"
|
||||||
value={angle1}
|
value={angle1}
|
||||||
ref={angle1Ref}
|
ref={angle1Ref}
|
||||||
onFocus={(e) => (angle1Ref.current.value = '')}
|
onChange={(value) => setAngle1(value)}
|
||||||
onChange={(e) => setAngle1(normalizeDecimalLimit(e.target.value, 2))}
|
|
||||||
placeholder="45"
|
placeholder="45"
|
||||||
|
onFocus={() => (angle1Ref.current.value = '')}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: true
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
@ -34,14 +50,29 @@ export default function Angle({ props }) {
|
|||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<span className="mr10">{getMessage('modal.cover.outline.length')}</span>
|
<span className="mr10">{getMessage('modal.cover.outline.length')}</span>
|
||||||
<div className="input-grid" style={{ width: '63px' }}>
|
<div className="input-grid" style={{ width: '63px' }}>
|
||||||
<input
|
{/*<input*/}
|
||||||
type="text"
|
{/* 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"
|
className="input-origin block"
|
||||||
value={length1}
|
value={length1}
|
||||||
ref={length1Ref}
|
ref={length1Ref}
|
||||||
onFocus={(e) => (length1Ref.current.value = '')}
|
onChange={(value) => setLength1(value)}
|
||||||
onChange={(e) => setLength1(normalizeDigits(e.target.value))}
|
|
||||||
placeholder="3000"
|
placeholder="3000"
|
||||||
|
onFocus={() => (length1Ref.current.value = '')}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { normalizeDigits } from '@/util/input-utils'
|
import { normalizeDigits } from '@/util/input-utils'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
export default function Diagonal({ props }) {
|
export default function Diagonal({ props }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -30,14 +31,29 @@ export default function Diagonal({ props }) {
|
|||||||
{getMessage('modal.cover.outline.length')}
|
{getMessage('modal.cover.outline.length')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid" style={{ width: '63px' }}>
|
<div className="input-grid" style={{ width: '63px' }}>
|
||||||
<input
|
{/*<input*/}
|
||||||
type="text"
|
{/* 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"
|
className="input-origin block"
|
||||||
value={outerLineDiagonalLength}
|
value={outerLineDiagonalLength}
|
||||||
ref={outerLineDiagonalLengthRef}
|
ref={outerLineDiagonalLengthRef}
|
||||||
onFocus={(e) => (outerLineDiagonalLengthRef.current.value = '')}
|
onChange={(value) => setOuterLineDiagonalLength(value)}
|
||||||
onChange={(e) => setOuterLineDiagonalLength(normalizeDigits(e.target.value))}
|
|
||||||
placeholder="3000"
|
placeholder="3000"
|
||||||
|
onFocus={() => (outerLineDiagonalLengthRef.current.value = '')}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
@ -52,14 +68,29 @@ export default function Diagonal({ props }) {
|
|||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<span className="mr10"> {getMessage('modal.cover.outline.length')}</span>
|
<span className="mr10"> {getMessage('modal.cover.outline.length')}</span>
|
||||||
<div className="input-grid" style={{ width: '63px' }}>
|
<div className="input-grid" style={{ width: '63px' }}>
|
||||||
<input
|
{/*<input*/}
|
||||||
type="text"
|
{/* 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"
|
className="input-origin block"
|
||||||
value={length1}
|
value={length1}
|
||||||
ref={length1Ref}
|
ref={length1Ref}
|
||||||
onFocus={(e) => (length1Ref.current.value = '')}
|
onChange={(value) => setLength1(value)}
|
||||||
onChange={(e) => setLength1(normalizeDigits(e.target.value))}
|
|
||||||
placeholder="3000"
|
placeholder="3000"
|
||||||
|
onFocus={() => (length1Ref.current.value = '')}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
@ -110,14 +141,29 @@ export default function Diagonal({ props }) {
|
|||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<span className="mr10"> {getMessage('modal.cover.outline.length')}</span>
|
<span className="mr10"> {getMessage('modal.cover.outline.length')}</span>
|
||||||
<div className="input-grid" style={{ width: '98px' }}>
|
<div className="input-grid" style={{ width: '98px' }}>
|
||||||
<input
|
{/*<input*/}
|
||||||
type="text"
|
{/* 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"
|
className="input-origin block"
|
||||||
value={length2}
|
value={length2}
|
||||||
ref={length2Ref}
|
ref={length2Ref}
|
||||||
onChange={(e) => setLength2(normalizeDigits(e.target.value))}
|
onChange={(value) => setLength2(value)}
|
||||||
readOnly={true}
|
|
||||||
placeholder="3000"
|
placeholder="3000"
|
||||||
|
onFocus={() => (length2Ref.current.value = '')}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
||||||
import { getDegreeByChon } from '@/util/canvas-util'
|
import { getDegreeByChon } from '@/util/canvas-util'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
export default function DoublePitch({ props }) {
|
export default function DoublePitch({ props }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -50,14 +51,29 @@ export default function DoublePitch({ props }) {
|
|||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<span className="mr10">{getMessage('modal.cover.outline.angle')}</span>
|
<span className="mr10">{getMessage('modal.cover.outline.angle')}</span>
|
||||||
<div className="input-grid" style={{ width: '63px' }}>
|
<div className="input-grid" style={{ width: '63px' }}>
|
||||||
<input
|
{/*<input*/}
|
||||||
type="text"
|
{/* 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"
|
className="input-origin block"
|
||||||
value={angle1}
|
value={angle1}
|
||||||
ref={angle1Ref}
|
ref={angle1Ref}
|
||||||
onFocus={(e) => (angle1Ref.current.value = '')}
|
onChange={(value) => setAngle1(value)}
|
||||||
onChange={(e) => setAngle1(normalizeDecimalLimit(e.target.value, 2))}
|
|
||||||
placeholder="45"
|
placeholder="45"
|
||||||
|
onFocus={() => (angle1Ref.current.value = '')}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: true
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button className="reset-btn" onClick={() => setAngle1(0)}></button>
|
<button className="reset-btn" onClick={() => setAngle1(0)}></button>
|
||||||
@ -67,14 +83,29 @@ export default function DoublePitch({ props }) {
|
|||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<span className="mr10">{getMessage('modal.cover.outline.length')}</span>
|
<span className="mr10">{getMessage('modal.cover.outline.length')}</span>
|
||||||
<div className="input-grid" style={{ width: '63px' }}>
|
<div className="input-grid" style={{ width: '63px' }}>
|
||||||
<input
|
{/*<input*/}
|
||||||
type="text"
|
{/* 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"
|
className="input-origin block"
|
||||||
value={length1}
|
value={length1}
|
||||||
ref={length1Ref}
|
ref={length1Ref}
|
||||||
onFocus={(e) => (length1Ref.current.value = '')}
|
onChange={(value) => setLength1(value)}
|
||||||
onChange={(e) => setLength1(normalizeDigits(e.target.value))}
|
|
||||||
placeholder="3000"
|
placeholder="3000"
|
||||||
|
onFocus={() => (length1Ref.current.value = '')}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
@ -125,18 +156,36 @@ export default function DoublePitch({ props }) {
|
|||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<span className="mr10">{getMessage('modal.cover.outline.angle')}</span>
|
<span className="mr10">{getMessage('modal.cover.outline.angle')}</span>
|
||||||
<div className="input-grid" style={{ width: '63px' }}>
|
<div className="input-grid" style={{ width: '63px' }}>
|
||||||
<input
|
{/*<input*/}
|
||||||
type="text"
|
{/* 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"
|
className="input-origin block"
|
||||||
value={angle2}
|
value={angle2}
|
||||||
ref={angle2Ref}
|
ref={angle2Ref}
|
||||||
onFocus={(e) => (angle2Ref.current.value = '')}
|
onChange={(value) => {
|
||||||
onChange={(e) => {
|
setAngle2(value)
|
||||||
const v = normalizeDecimalLimit(e.target.value, 2)
|
|
||||||
setAngle2(v)
|
|
||||||
setLength2(getLength2())
|
setLength2(getLength2())
|
||||||
}}
|
}}
|
||||||
placeholder="45"
|
placeholder="45"
|
||||||
|
onFocus={() => (angle2Ref.current.value = '')}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: true
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
@ -151,15 +200,30 @@ export default function DoublePitch({ props }) {
|
|||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<span className="mr10">{getMessage('modal.cover.outline.length')}</span>
|
<span className="mr10">{getMessage('modal.cover.outline.length')}</span>
|
||||||
<div className="input-grid" style={{ width: '63px' }}>
|
<div className="input-grid" style={{ width: '63px' }}>
|
||||||
<input
|
{/*<input*/}
|
||||||
type="text"
|
{/* 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"
|
className="input-origin block"
|
||||||
value={length2}
|
value={length2}
|
||||||
ref={length2Ref}
|
ref={length2Ref}
|
||||||
onFocus={(e) => (length2Ref.current.value = '')}
|
onChange={(value) => setLength2(value)}
|
||||||
onChange={(e) => setLength2(normalizeDigits(e.target.value))}
|
|
||||||
readOnly={true}
|
|
||||||
placeholder="3000"
|
placeholder="3000"
|
||||||
|
onFocus={() => (length2Ref.current.value = '')}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { normalizeDigits } from '@/util/input-utils'
|
import { normalizeDigits } from '@/util/input-utils'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
export default function RightAngle({ props }) {
|
export default function RightAngle({ props }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -22,14 +23,29 @@ export default function RightAngle({ props }) {
|
|||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<span className="mr10">{getMessage('modal.cover.outline.length')}</span>
|
<span className="mr10">{getMessage('modal.cover.outline.length')}</span>
|
||||||
<div className="input-grid" style={{ width: '63px' }}>
|
<div className="input-grid" style={{ width: '63px' }}>
|
||||||
<input
|
{/*<input*/}
|
||||||
type="text"
|
{/* 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"
|
className="input-origin block"
|
||||||
|
placeholder="3000"
|
||||||
value={length1}
|
value={length1}
|
||||||
ref={length1Ref}
|
ref={length1Ref}
|
||||||
onFocus={(e) => (length1Ref.current.value = '')}
|
onChange={(value) => setLength1(value)}
|
||||||
onChange={(e) => setLength1(normalizeDigits(e.target.value))}
|
onFocus={() => (length1Ref.current.value = '')}
|
||||||
placeholder="3000"
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
@ -78,14 +94,29 @@ export default function RightAngle({ props }) {
|
|||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<span className="mr10">{getMessage('modal.cover.outline.length')}</span>
|
<span className="mr10">{getMessage('modal.cover.outline.length')}</span>
|
||||||
<div className="input-grid" style={{ width: '63px' }}>
|
<div className="input-grid" style={{ width: '63px' }}>
|
||||||
<input
|
{/*<input*/}
|
||||||
type="text"
|
{/* 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"
|
className="input-origin block"
|
||||||
value={length2}
|
value={length2}
|
||||||
ref={length2Ref}
|
ref={length2Ref}
|
||||||
onFocus={(e) => (length2Ref.current.value = '')}
|
onFocus={() => (length2Ref.current.value = '')}
|
||||||
onChange={(e) => setLength2(normalizeDigits(e.target.value))}
|
onChange={(value) => setLength2(value)}
|
||||||
placeholder="3000"
|
placeholder="3000"
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { useMessage } from '@/hooks/useMessage'
|
|||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { currentObjectState } from '@/store/canvasAtom'
|
import { currentObjectState } from '@/store/canvasAtom'
|
||||||
import { useRecoilValue } from 'recoil'
|
import { useRecoilValue } from 'recoil'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
const FLOW_LINE_TYPE = {
|
const FLOW_LINE_TYPE = {
|
||||||
DOWN_LEFT: 'downLeft',
|
DOWN_LEFT: 'downLeft',
|
||||||
@ -69,13 +70,27 @@ export default function FlowLine({ FLOW_LINE_REF }) {
|
|||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<span>{getMessage('modal.movement.flow.line.movement')}</span>
|
<span>{getMessage('modal.movement.flow.line.movement')}</span>
|
||||||
<div className="input-grid mr5">
|
<div className="input-grid mr5">
|
||||||
<input
|
{/*<input*/}
|
||||||
type="text"
|
{/* type="text"*/}
|
||||||
|
{/* className="input-origin block"*/}
|
||||||
|
{/* ref={FLOW_LINE_REF.FILLED_INPUT_REF}*/}
|
||||||
|
{/* value={filledInput}*/}
|
||||||
|
{/* onFocus={handleFocus}*/}
|
||||||
|
{/* onChange={handleInput}*/}
|
||||||
|
{/*/>*/}
|
||||||
|
<CalculatorInput
|
||||||
|
id=""
|
||||||
|
name=""
|
||||||
|
label=""
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
ref={FLOW_LINE_REF.FILLED_INPUT_REF}
|
ref={FLOW_LINE_REF.FILLED_INPUT_REF}
|
||||||
value={filledInput}
|
value={filledInput}
|
||||||
onFocus={handleFocus}
|
onFocus={handleFocus}
|
||||||
onChange={handleInput}
|
onChange={(value)=>{setFilledInput(value)}}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
|
|||||||
@ -3,6 +3,7 @@ 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'
|
import { normalizeDigits } from '@/util/input-utils'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
const UP_DOWN_TYPE = {
|
const UP_DOWN_TYPE = {
|
||||||
UP: 'up',
|
UP: 'up',
|
||||||
@ -12,7 +13,7 @@ const UP_DOWN_TYPE = {
|
|||||||
export default function Updown({ UP_DOWN_REF }) {
|
export default function Updown({ UP_DOWN_REF }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
const [type, setType] = useState(UP_DOWN_TYPE.UP)
|
const [type, setType] = useState(UP_DOWN_TYPE.UP)
|
||||||
const [filledInput, setFilledInput] = useState('')
|
const [filledInput, setFilledInput] = useState('100')
|
||||||
const currentObject = useRecoilValue(currentObjectState)
|
const currentObject = useRecoilValue(currentObjectState)
|
||||||
const handleFocus = () => {
|
const handleFocus = () => {
|
||||||
if (currentObject === null) {
|
if (currentObject === null) {
|
||||||
@ -35,6 +36,7 @@ export default function Updown({ UP_DOWN_REF }) {
|
|||||||
<span>{getMessage('modal.movement.flow.line.position')}</span>
|
<span>{getMessage('modal.movement.flow.line.position')}</span>
|
||||||
<div className="input-grid mr5">
|
<div className="input-grid mr5">
|
||||||
<input type="text" className="input-origin block" defaultValue={100} readOnly={true} ref={UP_DOWN_REF.POINTER_INPUT_REF} />
|
<input type="text" className="input-origin block" defaultValue={100} readOnly={true} ref={UP_DOWN_REF.POINTER_INPUT_REF} />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="moving-tab-content">
|
<div className="moving-tab-content">
|
||||||
@ -68,14 +70,27 @@ export default function Updown({ UP_DOWN_REF }) {
|
|||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<span>{getMessage('modal.movement.flow.line.movement')}</span>
|
<span>{getMessage('modal.movement.flow.line.movement')}</span>
|
||||||
<div className="input-grid mr5">
|
<div className="input-grid mr5">
|
||||||
<input
|
{/*<input*/}
|
||||||
type="text"
|
{/* type="text"*/}
|
||||||
|
{/* className="input-origin block"*/}
|
||||||
|
{/* ref={UP_DOWN_REF.FILLED_INPUT_REF}*/}
|
||||||
|
{/* value={filledInput}*/}
|
||||||
|
{/* onFocus={handleFocus}*/}
|
||||||
|
{/* onChange={handleInput}*/}
|
||||||
|
{/*/>*/}
|
||||||
|
<CalculatorInput
|
||||||
|
id=""
|
||||||
|
name=""
|
||||||
|
label=""
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
defaultValue={100}
|
|
||||||
ref={UP_DOWN_REF.FILLED_INPUT_REF}
|
ref={UP_DOWN_REF.FILLED_INPUT_REF}
|
||||||
value={filledInput}
|
value={filledInput}
|
||||||
onFocus={handleFocus}
|
onFocus={handleFocus}
|
||||||
onChange={handleInput}
|
onChange={(value)=>{setFilledInput(value)}}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { useState, useEffect, useRef } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
||||||
import { useRecoilValue } from 'recoil'
|
import { useRecoilValue } from 'recoil'
|
||||||
@ -6,6 +6,7 @@ import { contextPopupPositionState } from '@/store/popupAtom'
|
|||||||
import { usePopup } from '@/hooks/usePopup'
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
import { useObjectBatch } from '@/hooks/object/useObjectBatch'
|
import { useObjectBatch } from '@/hooks/object/useObjectBatch'
|
||||||
import { canvasState } from '@/store/canvasAtom'
|
import { canvasState } from '@/store/canvasAtom'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
export default function DormerOffset(props) {
|
export default function DormerOffset(props) {
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
@ -14,8 +15,10 @@ export default function DormerOffset(props) {
|
|||||||
const { closePopup } = usePopup()
|
const { closePopup } = usePopup()
|
||||||
const [arrow1, setArrow1] = useState(null)
|
const [arrow1, setArrow1] = useState(null)
|
||||||
const [arrow2, setArrow2] = useState(null)
|
const [arrow2, setArrow2] = useState(null)
|
||||||
const arrow1LengthRef = useRef()
|
const arrow1LengthRef = useRef(0)
|
||||||
const arrow2LengthRef = useRef()
|
const arrow2LengthRef = useRef(0)
|
||||||
|
const [arrow1Length, setArrow1Length] = useState(0)
|
||||||
|
const [arrow2Length, setArrow2Length] = useState(0)
|
||||||
|
|
||||||
const canvas = useRecoilValue(canvasState)
|
const canvas = useRecoilValue(canvasState)
|
||||||
const { dormerOffsetKeyEvent, dormerOffset } = useObjectBatch({})
|
const { dormerOffsetKeyEvent, dormerOffset } = useObjectBatch({})
|
||||||
@ -50,7 +53,20 @@ export default function DormerOffset(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" 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 ?? 0}
|
||||||
|
ref={arrow1LengthRef}
|
||||||
|
onChange={() => {}} // No-op function to prevent error
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span>mm</span>
|
<span>mm</span>
|
||||||
<div className="direction-move-wrap">
|
<div className="direction-move-wrap">
|
||||||
@ -70,7 +86,20 @@ export default function DormerOffset(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" ref={arrow2LengthRef} placeholder="0" />
|
{/*<input type="text" className="input-origin" ref={arrow2LengthRef} placeholder="0" />*/}
|
||||||
|
<CalculatorInput
|
||||||
|
id=""
|
||||||
|
name=""
|
||||||
|
label=""
|
||||||
|
className="input-origin block"
|
||||||
|
value={arrow2LengthRef.current?.value ?? 0}
|
||||||
|
ref={arrow2LengthRef}
|
||||||
|
onChange={() => {}} // No-op function to prevent error
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span>mm</span>
|
<span>mm</span>
|
||||||
<div className="direction-move-wrap">
|
<div className="direction-move-wrap">
|
||||||
|
|||||||
@ -5,10 +5,11 @@ import { useMessage } from '@/hooks/useMessage'
|
|||||||
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
||||||
import { usePopup } from '@/hooks/usePopup'
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
import { contextPopupPositionState } from '@/store/popupAtom'
|
import { contextPopupPositionState } from '@/store/popupAtom'
|
||||||
import { useRef, useState } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
import { useObjectBatch } from '@/hooks/object/useObjectBatch'
|
import { useObjectBatch } from '@/hooks/object/useObjectBatch'
|
||||||
import { BATCH_TYPE, POLYGON_TYPE } from '@/common/common'
|
import { BATCH_TYPE, POLYGON_TYPE } from '@/common/common'
|
||||||
import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch'
|
import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
export default function SizeSetting(props) {
|
export default function SizeSetting(props) {
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
@ -20,7 +21,8 @@ export default function SizeSetting(props) {
|
|||||||
const { resizeSurfaceShapeBatch } = useSurfaceShapeBatch({})
|
const { resizeSurfaceShapeBatch } = useSurfaceShapeBatch({})
|
||||||
const widthRef = useRef(null)
|
const widthRef = useRef(null)
|
||||||
const heightRef = 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 } = useEvent()
|
||||||
// const { initEvent } = useContext(EventContext)
|
// const { initEvent } = useContext(EventContext)
|
||||||
|
|
||||||
@ -28,6 +30,15 @@ export default function SizeSetting(props) {
|
|||||||
// initEvent()
|
// initEvent()
|
||||||
// }, [])
|
// }, [])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (target?.width !== undefined) {
|
||||||
|
setWidth((target.width * 10).toFixed());
|
||||||
|
}
|
||||||
|
if (target?.height !== undefined) {
|
||||||
|
setHeight((target.height * 10).toFixed());
|
||||||
|
}
|
||||||
|
}, [target]);
|
||||||
|
|
||||||
const handleReSizeObject = () => {
|
const handleReSizeObject = () => {
|
||||||
const width = widthRef.current.value
|
const width = widthRef.current.value
|
||||||
const height = heightRef.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-top">
|
||||||
<div className="size-option-wrap">
|
<div className="size-option-wrap">
|
||||||
<div className="size-option mb5">
|
<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>
|
<span className="normal-font">mm</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="size-option">
|
<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>
|
<span className="normal-font">mm</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -60,11 +85,25 @@ export default function SizeSetting(props) {
|
|||||||
<div className="size-option-side">
|
<div className="size-option-side">
|
||||||
<div className="size-option-wrap">
|
<div className="size-option-wrap">
|
||||||
<div className="size-option mb5">
|
<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>
|
<span className="normal-font">mm</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="size-option">
|
<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>
|
<span className="normal-font">mm</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,10 +1,13 @@
|
|||||||
import { forwardRef, useState, useEffect } from 'react'
|
import { forwardRef, useState, useEffect } from 'react'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { INPUT_TYPE } from '@/common/common'
|
import { INPUT_TYPE } from '@/common/common'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
const OpenSpace = forwardRef((props, refs) => {
|
const OpenSpace = forwardRef((props, refs) => {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
const [selectedType, setSelectedType] = useState(INPUT_TYPE.FREE)
|
const [selectedType, setSelectedType] = useState(INPUT_TYPE.FREE)
|
||||||
|
const [width, setWidth] = useState(0)
|
||||||
|
const [height, setHeight] = useState(0)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedType === INPUT_TYPE.FREE) {
|
if (selectedType === INPUT_TYPE.FREE) {
|
||||||
@ -51,12 +54,26 @@ const OpenSpace = forwardRef((props, refs) => {
|
|||||||
<div className="eaves-keraba-td">
|
<div className="eaves-keraba-td">
|
||||||
<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
|
{/*<input*/}
|
||||||
type="text"
|
{/* type="text"*/}
|
||||||
|
{/* className="input-origin block"*/}
|
||||||
|
{/* placeholder={0}*/}
|
||||||
|
{/* ref={refs.widthRef}*/}
|
||||||
|
{/* disabled={selectedType !== INPUT_TYPE.DIMENSION}*/}
|
||||||
|
{/*/>*/}
|
||||||
|
<CalculatorInput
|
||||||
|
id=""
|
||||||
|
name=""
|
||||||
|
label=""
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
placeholder={0}
|
value={width}
|
||||||
ref={refs.widthRef}
|
ref={refs.widthRef}
|
||||||
|
onChange={(value) => setWidth(value)}
|
||||||
disabled={selectedType !== INPUT_TYPE.DIMENSION}
|
disabled={selectedType !== INPUT_TYPE.DIMENSION}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
@ -68,12 +85,26 @@ const OpenSpace = forwardRef((props, refs) => {
|
|||||||
<div className="eaves-keraba-td">
|
<div className="eaves-keraba-td">
|
||||||
<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
|
{/*<input*/}
|
||||||
type="text"
|
{/* type="text"*/}
|
||||||
|
{/* className="input-origin block"*/}
|
||||||
|
{/* placeholder={0}*/}
|
||||||
|
{/* ref={refs.heightRef}*/}
|
||||||
|
{/* disabled={selectedType !== INPUT_TYPE.DIMENSION}*/}
|
||||||
|
{/*/>*/}
|
||||||
|
<CalculatorInput
|
||||||
|
id=""
|
||||||
|
name=""
|
||||||
|
label=""
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
placeholder={0}
|
value={height}
|
||||||
ref={refs.heightRef}
|
ref={refs.heightRef}
|
||||||
|
onChange={(value) => setHeight(value)}
|
||||||
disabled={selectedType !== INPUT_TYPE.DIMENSION}
|
disabled={selectedType !== INPUT_TYPE.DIMENSION}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import Image from 'next/image'
|
import Image from 'next/image'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { forwardRef, useState } from 'react'
|
import { forwardRef, useState } from 'react'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
const PentagonDormer = forwardRef((props, refs) => {
|
const PentagonDormer = forwardRef((props, refs) => {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -11,6 +12,11 @@ const PentagonDormer = forwardRef((props, refs) => {
|
|||||||
setDirection(e.target.value)
|
setDirection(e.target.value)
|
||||||
refs.directionRef.current = 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 (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -30,7 +36,20 @@ const PentagonDormer = forwardRef((props, refs) => {
|
|||||||
<div className="eaves-keraba-td">
|
<div className="eaves-keraba-td">
|
||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<div className="input-grid mr5" style={{ width: '60px' }}>
|
<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>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -41,7 +60,20 @@ const PentagonDormer = forwardRef((props, refs) => {
|
|||||||
<div className="eaves-keraba-td">
|
<div className="eaves-keraba-td">
|
||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<div className="input-grid mr5" style={{ width: '60px' }}>
|
<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>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -55,7 +87,20 @@ const PentagonDormer = forwardRef((props, refs) => {
|
|||||||
<div className="eaves-keraba-td">
|
<div className="eaves-keraba-td">
|
||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<div className="input-grid mr5" style={{ width: '60px' }}>
|
<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>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -66,7 +111,20 @@ const PentagonDormer = forwardRef((props, refs) => {
|
|||||||
<div className="eaves-keraba-td">
|
<div className="eaves-keraba-td">
|
||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<div className="input-grid mr5" style={{ width: '60px' }}>
|
<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>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -77,7 +135,20 @@ const PentagonDormer = forwardRef((props, refs) => {
|
|||||||
<div className="eaves-keraba-td">
|
<div className="eaves-keraba-td">
|
||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<div className="input-grid mr5" style={{ width: '60px' }}>
|
<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>
|
</div>
|
||||||
<span className="thin">寸</span>
|
<span className="thin">寸</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,11 +1,14 @@
|
|||||||
import { forwardRef, useState, useEffect } from 'react'
|
import { forwardRef, useState, useEffect } from 'react'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { INPUT_TYPE } from '@/common/common'
|
import { INPUT_TYPE } from '@/common/common'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
const Shadow = forwardRef((props, refs) => {
|
const Shadow = forwardRef((props, refs) => {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
|
|
||||||
const [selectedType, setSelectedType] = useState(INPUT_TYPE.FREE)
|
const [selectedType, setSelectedType] = useState(INPUT_TYPE.FREE)
|
||||||
|
const [width, setWidth] = useState(0)
|
||||||
|
const [height, setHeight] = useState(0)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedType === INPUT_TYPE.FREE) {
|
if (selectedType === INPUT_TYPE.FREE) {
|
||||||
@ -51,12 +54,26 @@ const Shadow = forwardRef((props, refs) => {
|
|||||||
<div className="eaves-keraba-td">
|
<div className="eaves-keraba-td">
|
||||||
<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
|
{/*<input*/}
|
||||||
type="text"
|
{/* type="text"*/}
|
||||||
|
{/* className="input-origin block"*/}
|
||||||
|
{/* placeholder={0}*/}
|
||||||
|
{/* ref={refs.widthRef}*/}
|
||||||
|
{/* disabled={selectedType !== INPUT_TYPE.DIMENSION}*/}
|
||||||
|
{/*/>*/}
|
||||||
|
<CalculatorInput
|
||||||
|
id=""
|
||||||
|
name=""
|
||||||
|
label=""
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
placeholder={0}
|
value={width}
|
||||||
ref={refs.widthRef}
|
ref={refs.widthRef}
|
||||||
|
onChange={(value) => setWidth(value)}
|
||||||
disabled={selectedType !== INPUT_TYPE.DIMENSION}
|
disabled={selectedType !== INPUT_TYPE.DIMENSION}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
@ -68,12 +85,26 @@ const Shadow = forwardRef((props, refs) => {
|
|||||||
<div className="eaves-keraba-td">
|
<div className="eaves-keraba-td">
|
||||||
<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
|
{/*<input*/}
|
||||||
type="text"
|
{/* type="text"*/}
|
||||||
|
{/* className="input-origin block"*/}
|
||||||
|
{/* placeholder={0}*/}
|
||||||
|
{/* ref={refs.heightRef}*/}
|
||||||
|
{/* disabled={selectedType !== INPUT_TYPE.DIMENSION}*/}
|
||||||
|
{/*/>*/}
|
||||||
|
<CalculatorInput
|
||||||
|
id=""
|
||||||
|
name=""
|
||||||
|
label=""
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
placeholder={0}
|
value={height}
|
||||||
ref={refs.heightRef}
|
ref={refs.heightRef}
|
||||||
|
onChange={(value) => setHeight(value)}
|
||||||
disabled={selectedType !== INPUT_TYPE.DIMENSION}
|
disabled={selectedType !== INPUT_TYPE.DIMENSION}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import Image from 'next/image'
|
import Image from 'next/image'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { forwardRef, useState } from 'react'
|
import { forwardRef, useState } from 'react'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
const TriangleDormer = forwardRef((props, refs) => {
|
const TriangleDormer = forwardRef((props, refs) => {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -11,6 +12,9 @@ const TriangleDormer = forwardRef((props, refs) => {
|
|||||||
setDirection(e.target.value)
|
setDirection(e.target.value)
|
||||||
refs.directionRef.current = 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 (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -30,7 +34,20 @@ const TriangleDormer = forwardRef((props, refs) => {
|
|||||||
<div className="eaves-keraba-td">
|
<div className="eaves-keraba-td">
|
||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<div className="input-grid mr5" style={{ width: '60px' }}>
|
<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>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -41,7 +58,20 @@ const TriangleDormer = forwardRef((props, refs) => {
|
|||||||
<div className="eaves-keraba-td">
|
<div className="eaves-keraba-td">
|
||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<div className="input-grid mr5" style={{ width: '60px' }}>
|
<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>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -52,7 +82,20 @@ const TriangleDormer = forwardRef((props, refs) => {
|
|||||||
<div className="eaves-keraba-td">
|
<div className="eaves-keraba-td">
|
||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<div className="input-grid mr5" style={{ width: '60px' }}>
|
<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>
|
</div>
|
||||||
<span className="thin">寸</span>
|
<span className="thin">寸</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -170,8 +170,8 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla
|
|||||||
|
|
||||||
setCurrentRoof({
|
setCurrentRoof({
|
||||||
...selectedRoofMaterial,
|
...selectedRoofMaterial,
|
||||||
pitch: currentRoof?.pitch,
|
// pitch: currentRoof?.pitch,
|
||||||
angle: currentRoof?.angle,
|
// angle: currentRoof?.angle,
|
||||||
index: 0,
|
index: 0,
|
||||||
planNo: currentRoof.planNo,
|
planNo: currentRoof.planNo,
|
||||||
roofSizeSet: String(currentRoof.roofSizeSet),
|
roofSizeSet: String(currentRoof.roofSizeSet),
|
||||||
@ -350,27 +350,29 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla
|
|||||||
label=""
|
label=""
|
||||||
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 ?? basicSetting?.inclBase ?? '0') : (currentRoof?.angle ?? '0')}
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
if (index === 0) {
|
if (index === 0) {
|
||||||
const num = value === '' ? '' : Number(value)
|
const pitch = value === '' ? '' : Number(value);
|
||||||
|
const angle = pitch === '' ? '' : getDegreeByChon(pitch);
|
||||||
setCurrentRoof(prev => ({
|
setCurrentRoof(prev => ({
|
||||||
...prev,
|
...prev,
|
||||||
pitch: num === '' ? '' : num,
|
pitch,
|
||||||
angle: num === '' ? '' : getDegreeByChon(num),
|
angle
|
||||||
}))
|
}));
|
||||||
} else {
|
} else {
|
||||||
const num = value === '' ? '' : Number(value)
|
const angle = value === '' ? '' : Number(value);
|
||||||
setCurrentRoof( prev => ({
|
const pitch = angle === '' ? '' : getChonByDegree(angle);
|
||||||
|
setCurrentRoof(prev => ({
|
||||||
...prev,
|
...prev,
|
||||||
pitch: num === '' ? '' : getChonByDegree(num),
|
pitch,
|
||||||
angle: num === '' ? '' : num,
|
angle
|
||||||
}))
|
}));
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
options={{
|
options={{
|
||||||
allowNegative: false,
|
allowNegative: false,
|
||||||
allowDecimal: false //(index !== 0),
|
allowDecimal: true
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -514,13 +516,17 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla
|
|||||||
{/*/>*/}
|
{/*/>*/}
|
||||||
<CalculatorInput
|
<CalculatorInput
|
||||||
id=""
|
id=""
|
||||||
name={'hajebichi'}
|
name="hajebichi"
|
||||||
label=""
|
label=""
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
ref={roofRef.hajebichi}
|
ref={roofRef.hajebichi}
|
||||||
value={currentRoof?.hajebichi||0}
|
value={currentRoof?.hajebichi ?? basicSetting?.roofPchBase ?? '0'}
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
setCurrentRoof({ ...currentRoof, value })
|
const hajebichi = value === '' ? '' : Number(value);
|
||||||
|
setCurrentRoof(prev => ({
|
||||||
|
...prev,
|
||||||
|
hajebichi
|
||||||
|
}));
|
||||||
}}
|
}}
|
||||||
readOnly={currentRoof?.roofPchAuth === 'R'}
|
readOnly={currentRoof?.roofPchAuth === 'R'}
|
||||||
disabled={currentRoof?.roofSizeSet === '3'}
|
disabled={currentRoof?.roofSizeSet === '3'}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import Image from 'next/image'
|
import Image from 'next/image'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { forwardRef, useState } from 'react'
|
import { forwardRef, useState } from 'react'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
const PlacementSurface = forwardRef((props, refs) => {
|
const PlacementSurface = forwardRef((props, refs) => {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -74,10 +75,32 @@ const PlacementSurface = forwardRef((props, refs) => {
|
|||||||
<div className="eaves-keraba-td">
|
<div className="eaves-keraba-td">
|
||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<div className="input-grid mr5" style={{ width: '57px' }}>
|
<div className="input-grid mr5" style={{ width: '57px' }}>
|
||||||
<input
|
{/*<input*/}
|
||||||
type="text"
|
{/* type="text"*/}
|
||||||
|
{/* className="input-origin plane block"*/}
|
||||||
|
{/* defaultValue={line.value}*/}
|
||||||
|
{/* ref={*/}
|
||||||
|
{/* line.isDiagonal*/}
|
||||||
|
{/* ? lengthetc*/}
|
||||||
|
{/* : index === 0*/}
|
||||||
|
{/* ? length1*/}
|
||||||
|
{/* : index === 1*/}
|
||||||
|
{/* ? length2*/}
|
||||||
|
{/* : index === 2*/}
|
||||||
|
{/* ? length3*/}
|
||||||
|
{/* : index === 3*/}
|
||||||
|
{/* ? length4*/}
|
||||||
|
{/* : length5*/}
|
||||||
|
{/* }*/}
|
||||||
|
{/*/>*/}
|
||||||
|
|
||||||
|
<CalculatorInput
|
||||||
|
id=""
|
||||||
|
name=""
|
||||||
|
label=""
|
||||||
className="input-origin plane block"
|
className="input-origin plane block"
|
||||||
defaultValue={line.value}
|
value={line.value}
|
||||||
|
onChange={()=>{}}
|
||||||
ref={
|
ref={
|
||||||
line.isDiagonal
|
line.isDiagonal
|
||||||
? lengthetc
|
? lengthetc
|
||||||
@ -91,6 +114,10 @@ const PlacementSurface = forwardRef((props, refs) => {
|
|||||||
? length4
|
? length4
|
||||||
: length5
|
: length5
|
||||||
}
|
}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
|
|||||||
@ -13,6 +13,7 @@ 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'
|
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
export default function ContextRoofAllocationSetting(props) {
|
export default function ContextRoofAllocationSetting(props) {
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
@ -204,15 +205,29 @@ export default function ContextRoofAllocationSetting(props) {
|
|||||||
<div className="flex-ment">
|
<div className="flex-ment">
|
||||||
<span>{getMessage('modal.object.setting.offset.slope')}</span>
|
<span>{getMessage('modal.object.setting.offset.slope')}</span>
|
||||||
<div className="input-grid">
|
<div className="input-grid">
|
||||||
<input
|
{/*<input*/}
|
||||||
type="text"
|
{/* 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"
|
className="input-origin block"
|
||||||
onChange={(e) => {
|
|
||||||
e.target.value = normalizeDecimalLimit(e.target.value, 2)
|
|
||||||
handleChangePitch(e, index)
|
|
||||||
}}
|
|
||||||
value={currentAngleType === 'slope' ? (roof.pitch ?? '') : (roof.angle ?? '')}
|
value={currentAngleType === 'slope' ? (roof.pitch ?? '') : (roof.angle ?? '')}
|
||||||
/>
|
onChange={(value) => {
|
||||||
|
handleChangePitch(value, index)
|
||||||
|
}}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: true //(index !== 0),
|
||||||
|
}}
|
||||||
|
></CalculatorInput>
|
||||||
</div>
|
</div>
|
||||||
<span className="absol">{pitchText}</span>
|
<span className="absol">{pitchText}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -14,6 +14,7 @@ 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 { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
export default function RoofAllocationSetting(props) {
|
export default function RoofAllocationSetting(props) {
|
||||||
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
|
||||||
@ -205,15 +206,29 @@ export default function RoofAllocationSetting(props) {
|
|||||||
<div className="flex-ment">
|
<div className="flex-ment">
|
||||||
<span>{getMessage('modal.object.setting.offset.slope')}</span>
|
<span>{getMessage('modal.object.setting.offset.slope')}</span>
|
||||||
<div className="input-grid">
|
<div className="input-grid">
|
||||||
<input
|
{/*<input*/}
|
||||||
type="text"
|
{/* 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"
|
className="input-origin block"
|
||||||
onChange={(e) => {
|
|
||||||
e.target.value = normalizeDecimalLimit(e.target.value, 2)
|
|
||||||
handleChangePitch(e, index)
|
|
||||||
}}
|
|
||||||
value={currentAngleType === 'slope' ? (roof.pitch ?? '') : (roof.angle ?? '')}
|
value={currentAngleType === 'slope' ? (roof.pitch ?? '') : (roof.angle ?? '')}
|
||||||
/>
|
onChange={(value) => {
|
||||||
|
handleChangePitch(value, index)
|
||||||
|
}}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: true //(index !== 0),
|
||||||
|
}}
|
||||||
|
></CalculatorInput>
|
||||||
</div>
|
</div>
|
||||||
<span className="absol">{pitchText}</span>
|
<span className="absol">{pitchText}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { useRecoilValue } from 'recoil'
|
|||||||
import { ANGLE_TYPE, currentAngleTypeSelector } from '@/store/canvasAtom'
|
import { ANGLE_TYPE, currentAngleTypeSelector } from '@/store/canvasAtom'
|
||||||
import { selectedRoofMaterialSelector } from '@/store/settingAtom'
|
import { selectedRoofMaterialSelector } from '@/store/settingAtom'
|
||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
export default function Eaves({ offsetRef, pitchRef, pitchText }) {
|
export default function Eaves({ offsetRef, pitchRef, pitchText }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -16,12 +17,24 @@ export default function Eaves({ offsetRef, pitchRef, pitchText }) {
|
|||||||
{getMessage('slope')}
|
{getMessage('slope')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5">
|
<div className="input-grid mr5">
|
||||||
<input
|
{/*<input*/}
|
||||||
type="text"
|
{/* 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"
|
className="input-origin block"
|
||||||
defaultValue={currentAngleType === ANGLE_TYPE.SLOPE ? selectedRoofMaterial.pitch : selectedRoofMaterial.angle}
|
|
||||||
ref={pitchRef}
|
ref={pitchRef}
|
||||||
/>
|
value={currentAngleType === ANGLE_TYPE.SLOPE ? selectedRoofMaterial.pitch : selectedRoofMaterial.angle}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: true //(index !== 0),
|
||||||
|
}}
|
||||||
|
></CalculatorInput>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">{pitchText}</span>
|
<span className="thin">{pitchText}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -30,7 +43,20 @@ export default function Eaves({ offsetRef, pitchRef, pitchText }) {
|
|||||||
{getMessage('eaves.offset')}
|
{getMessage('eaves.offset')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5">
|
<div className="input-grid mr5">
|
||||||
<input type="text" className="input-origin block" defaultValue={500} ref={offsetRef} />
|
{/*<input type="text" className="input-origin block" defaultValue={500} ref={offsetRef} />*/}
|
||||||
|
<CalculatorInput
|
||||||
|
id=""
|
||||||
|
name=""
|
||||||
|
label=""
|
||||||
|
className="input-origin block"
|
||||||
|
value={offsetRef.current?.value ?? 500} // Set default value to 500
|
||||||
|
ref={offsetRef}
|
||||||
|
onChange={() => {}}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useRecoilValue } from 'recoil'
|
import { useRecoilValue } from 'recoil'
|
||||||
import { currentAngleTypeSelector } from '@/store/canvasAtom'
|
import { currentAngleTypeSelector } from '@/store/canvasAtom'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
export default function Gable({ offsetRef }) {
|
export default function Gable({ offsetRef }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -12,7 +13,20 @@ export default function Gable({ offsetRef }) {
|
|||||||
{getMessage('gable.offset')}
|
{getMessage('gable.offset')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5">
|
<div className="input-grid mr5">
|
||||||
<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"
|
||||||
|
value={offsetRef.current?.value ?? 300} // Set default value to 500
|
||||||
|
ref={offsetRef}
|
||||||
|
onChange={() => {}}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
export default function Shed({ offsetRef }) {
|
export default function Shed({ offsetRef }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -9,7 +10,20 @@ export default function Shed({ offsetRef }) {
|
|||||||
{getMessage('shed.width')}
|
{getMessage('shed.width')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5">
|
<div className="input-grid mr5">
|
||||||
<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"
|
||||||
|
value={offsetRef.current?.value ?? 300} // Set default value to 500
|
||||||
|
ref={offsetRef}
|
||||||
|
onChange={() => {}}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
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,12 +11,24 @@ 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
|
{/*<input*/}
|
||||||
type="text"
|
{/* type="text"*/}
|
||||||
|
{/* className="input-origin block"*/}
|
||||||
|
{/* value={pitch}*/}
|
||||||
|
{/* onChange={(e) => setPitch(normalizeDecimalLimit(e.target.value, 2))}*/}
|
||||||
|
{/*/>*/}
|
||||||
|
<CalculatorInput
|
||||||
|
id=""
|
||||||
|
name=""
|
||||||
|
label=""
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
value={pitch}
|
value={pitch}
|
||||||
onChange={(e) => setPitch(normalizeDecimalLimit(e.target.value, 2))}
|
onChange={(value) => setPitch(value)}
|
||||||
/>
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: true //(index !== 0),
|
||||||
|
}}
|
||||||
|
></CalculatorInput>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">{pitchText}</span>
|
<span className="thin">{pitchText}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -24,12 +37,24 @@ 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
|
{/*<input*/}
|
||||||
type="text"
|
{/* type="text"*/}
|
||||||
|
{/* className="input-origin block"*/}
|
||||||
|
{/* value={eavesOffset}*/}
|
||||||
|
{/* onChange={(e) => setEavesOffset(normalizeDigits(e.target.value))}*/}
|
||||||
|
{/*/>*/}
|
||||||
|
<CalculatorInput
|
||||||
|
id=""
|
||||||
|
name=""
|
||||||
|
label=""
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
value={eavesOffset}
|
value={eavesOffset}
|
||||||
onChange={(e) => setEavesOffset(normalizeDigits(e.target.value))}
|
onChange={(value) => setEavesOffset(value)}
|
||||||
/>
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false //(index !== 0),
|
||||||
|
}}
|
||||||
|
></CalculatorInput>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -38,12 +63,24 @@ 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
|
{/*<input*/}
|
||||||
type="text"
|
{/* type="text"*/}
|
||||||
|
{/* className="input-origin block"*/}
|
||||||
|
{/* value={gableOffset}*/}
|
||||||
|
{/* onChange={(e) => setGableOffset(normalizeDigits(e.target.value))}*/}
|
||||||
|
{/*/>*/}
|
||||||
|
<CalculatorInput
|
||||||
|
id=""
|
||||||
|
name=""
|
||||||
|
label=""
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
value={gableOffset}
|
value={gableOffset}
|
||||||
onChange={(e) => setGableOffset(normalizeDigits(e.target.value))}
|
onChange={(value) => setGableOffset(value)}
|
||||||
/>
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false //(index !== 0),
|
||||||
|
}}
|
||||||
|
></CalculatorInput>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -52,12 +89,24 @@ 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
|
{/*<input*/}
|
||||||
type="text"
|
{/* type="text"*/}
|
||||||
|
{/* className="input-origin block"*/}
|
||||||
|
{/* value={shedWidth}*/}
|
||||||
|
{/* onChange={(e) => setShedWidth(normalizeDigits(e.target.value))}*/}
|
||||||
|
{/*/>*/}
|
||||||
|
<CalculatorInput
|
||||||
|
id=""
|
||||||
|
name=""
|
||||||
|
label=""
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
value={shedWidth}
|
value={shedWidth}
|
||||||
onChange={(e) => setShedWidth(normalizeDigits(e.target.value))}
|
onChange={(value) => setShedWidth(value)}
|
||||||
/>
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false //(index !== 0),
|
||||||
|
}}
|
||||||
|
></CalculatorInput>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
export default function Pattern(props) {
|
export default function Pattern(props) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -11,7 +12,20 @@ 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) => 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>
|
</div>
|
||||||
<span className="thin"> {pitchText}</span>
|
<span className="thin"> {pitchText}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -20,7 +34,20 @@ 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) => 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>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -29,7 +56,20 @@ 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) => 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>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
export default function Ridge(props) {
|
export default function Ridge(props) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -13,7 +14,20 @@ 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) => 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>
|
</div>
|
||||||
<span className="thin">{pitchText}</span>
|
<span className="thin">{pitchText}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -22,7 +36,20 @@ 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) => 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>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
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 +11,21 @@ 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) => 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>
|
</div>
|
||||||
<span className="thin">{pitchText}</span>
|
<span className="thin">{pitchText}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -19,7 +34,20 @@ 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) => 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>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
import { normalizeDigits } from '@/util/input-utils'
|
import { normalizeDigits } from '@/util/input-utils'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
export default function Gable({ gableOffset, setGableOffset }) {
|
export default function Gable({ gableOffset, setGableOffset }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -10,7 +11,20 @@ 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) => 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>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
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 +11,20 @@ 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) => 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>
|
</div>
|
||||||
<span className="thin">{pitchText}</span>
|
<span className="thin">{pitchText}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -19,7 +33,21 @@ 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) => 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>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -28,12 +56,24 @@ export default function HipAndGable({ pitch, setPitch, eavesOffset, setEavesOffs
|
|||||||
{getMessage('hipandgable.width')}
|
{getMessage('hipandgable.width')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input
|
{/*<input*/}
|
||||||
type="text"
|
{/* type="text"*/}
|
||||||
|
{/* className="input-origin block"*/}
|
||||||
|
{/* value={hipAndGableWidth}*/}
|
||||||
|
{/* onChange={(e) => setHipAndGableWidth(normalizeDigits(e.target.value))}*/}
|
||||||
|
{/*/>*/}
|
||||||
|
<CalculatorInput
|
||||||
|
id=""
|
||||||
|
name=""
|
||||||
|
label=""
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
value={hipAndGableWidth}
|
value={hipAndGableWidth}
|
||||||
onChange={(e) => setHipAndGableWidth(normalizeDigits(e.target.value))}
|
onChange={(value) => setHipAndGableWidth(value)}
|
||||||
/>
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false //(index !== 0),
|
||||||
|
}}
|
||||||
|
></CalculatorInput>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
export default function Jerkinhead({
|
export default function Jerkinhead({
|
||||||
gableOffset,
|
gableOffset,
|
||||||
@ -18,7 +19,20 @@ 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) => 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>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -27,7 +41,21 @@ 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) => 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>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -36,12 +64,24 @@ export default function Jerkinhead({
|
|||||||
{getMessage('jerkinhead.slope')}
|
{getMessage('jerkinhead.slope')}
|
||||||
</span>
|
</span>
|
||||||
<div className="input-grid mr5" style={{ width: '100px' }}>
|
<div className="input-grid mr5" style={{ width: '100px' }}>
|
||||||
<input
|
{/*<input*/}
|
||||||
type="text"
|
{/* type="text"*/}
|
||||||
|
{/* className="input-origin block"*/}
|
||||||
|
{/* value={jerkinHeadPitch}*/}
|
||||||
|
{/* onChange={(e) => setJerkinHeadPitch(normalizeDecimalLimit(e.target.value, 2))}*/}
|
||||||
|
{/*/>*/}
|
||||||
|
<CalculatorInput
|
||||||
|
id=""
|
||||||
|
name=""
|
||||||
|
label=""
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
value={jerkinHeadPitch}
|
value={jerkinHeadPitch}
|
||||||
onChange={(e) => setJerkinHeadPitch(normalizeDecimalLimit(e.target.value, 2))}
|
onChange={(value) => setJerkinHeadPitch(value)}
|
||||||
/>
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: true //(index !== 0),
|
||||||
|
}}
|
||||||
|
></CalculatorInput>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">{pitchText}</span>
|
<span className="thin">{pitchText}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
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 +9,40 @@ 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) => 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>
|
</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) => 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>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { normalizeDigits } from '@/util/input-utils'
|
import { normalizeDigits } from '@/util/input-utils'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
export default function Wall({ sleeveOffset, setSleeveOffset, hasSleeve, setHasSleeve }) {
|
export default function Wall({ sleeveOffset, setSleeveOffset, hasSleeve, setHasSleeve }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -10,7 +11,8 @@ export default function Wall({ sleeveOffset, setSleeveOffset, hasSleeve, setHasS
|
|||||||
<div className="eaves-keraba-item">
|
<div className="eaves-keraba-item">
|
||||||
<div className="eaves-keraba-th">
|
<div className="eaves-keraba-th">
|
||||||
<div className="d-check-radio pop">
|
<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>
|
<label htmlFor="ra01">{getMessage('has.not.sleeve')}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -18,20 +20,34 @@ export default function Wall({ sleeveOffset, setSleeveOffset, hasSleeve, setHasS
|
|||||||
<div className="eaves-keraba-item">
|
<div className="eaves-keraba-item">
|
||||||
<div className="eaves-keraba-th">
|
<div className="eaves-keraba-th">
|
||||||
<div className="d-check-radio pop">
|
<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>
|
<label htmlFor="ra02">{getMessage('has.sleeve')}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="eaves-keraba-td">
|
<div className="eaves-keraba-td">
|
||||||
<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
|
{/*<input*/}
|
||||||
type="text"
|
{/* 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"
|
className="input-origin block"
|
||||||
value={sleeveOffset}
|
value={sleeveOffset}
|
||||||
onChange={(e) => setSleeveOffset(normalizeDigits(e.target.value))}
|
onChange={(value) => setSleeveOffset(value)}
|
||||||
readOnly={hasSleeve === '0'}
|
readOnly={hasSleeve === '0'}
|
||||||
/>
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false //(index !== 0),
|
||||||
|
}}
|
||||||
|
></CalculatorInput>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect } from 'react'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { POLYGON_TYPE } from '@/common/common'
|
import { POLYGON_TYPE } from '@/common/common'
|
||||||
import { useEvent } from '@/hooks/useEvent'
|
import { useEvent } from '@/hooks/useEvent'
|
||||||
import { useRoofFn } from '@/hooks/common/useRoofFn'
|
import { useRoofFn } from '@/hooks/common/useRoofFn'
|
||||||
|
import { outlineDisplaySelector } from '@/store/settingAtom'
|
||||||
|
import { useRecoilValue } from 'recoil'
|
||||||
|
|
||||||
export default function FirstOption(props) {
|
export default function FirstOption(props) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -11,6 +13,7 @@ export default function FirstOption(props) {
|
|||||||
const { option1, option2, dimensionDisplay } = settingModalFirstOptions
|
const { option1, option2, dimensionDisplay } = settingModalFirstOptions
|
||||||
const { initEvent } = useEvent()
|
const { initEvent } = useEvent()
|
||||||
const { setSurfaceShapePattern } = useRoofFn()
|
const { setSurfaceShapePattern } = useRoofFn()
|
||||||
|
const outlineDisplay = useRecoilValue(outlineDisplaySelector)
|
||||||
|
|
||||||
// 데이터를 최초 한 번만 조회
|
// 데이터를 최초 한 번만 조회
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -18,6 +21,13 @@ export default function FirstOption(props) {
|
|||||||
setSettingsDataSave({ ...settingsData })
|
setSettingsDataSave({ ...settingsData })
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const outline = canvas.getObjects().filter((obj) => obj.name === 'originRoofOuterLine')
|
||||||
|
outline.forEach((obj) => {
|
||||||
|
obj.visible = outlineDisplay
|
||||||
|
})
|
||||||
|
}, [outlineDisplay])
|
||||||
|
|
||||||
const onClickOption = async (item) => {
|
const onClickOption = async (item) => {
|
||||||
let dimensionDisplay = settingModalFirstOptions?.dimensionDisplay
|
let dimensionDisplay = settingModalFirstOptions?.dimensionDisplay
|
||||||
let option1 = settingModalFirstOptions?.option1
|
let option1 = settingModalFirstOptions?.option1
|
||||||
@ -58,7 +68,12 @@ export default function FirstOption(props) {
|
|||||||
// setSettingModalFirstOptions({ ...settingModalFirstOptions, option1: [...options] })
|
// setSettingModalFirstOptions({ ...settingModalFirstOptions, option1: [...options] })
|
||||||
}
|
}
|
||||||
|
|
||||||
setSettingsData({ ...settingsData, option1: [...option1], option2: [...option2], dimensionDisplay: [...dimensionDisplay] })
|
setSettingsData({
|
||||||
|
...settingsData,
|
||||||
|
option1: [...option1],
|
||||||
|
option2: [...option2],
|
||||||
|
dimensionDisplay: [...dimensionDisplay],
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// useEffect(() => {
|
// useEffect(() => {
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { useEvent } from '@/hooks/useEvent'
|
import { useEvent } from '@/hooks/useEvent'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
export default function Offset({ length1Ref, arrow1Ref, currentWallLineRef }) {
|
export default function Offset({ length1Ref, arrow1Ref, currentWallLineRef }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -74,7 +75,20 @@ export default function Offset({ length1Ref, arrow1Ref, currentWallLineRef }) {
|
|||||||
<div className="eaves-keraba-td">
|
<div className="eaves-keraba-td">
|
||||||
<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="text" className="input-origin block" placeholder={0} ref={length1Ref} />
|
{/*<input type="text" className="input-origin block" placeholder={0} ref={length1Ref} />*/}
|
||||||
|
<CalculatorInput
|
||||||
|
id=""
|
||||||
|
name=""
|
||||||
|
label=""
|
||||||
|
className="input-origin block"
|
||||||
|
value={length1Ref.current?.value ?? 0}
|
||||||
|
ref={length1Ref}
|
||||||
|
onChange={() => {}}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { forwardRef, useEffect, useImperativeHandle, useState } from 'react'
|
import { forwardRef, useEffect, useImperativeHandle, useState } from 'react'
|
||||||
import { useEvent } from '@/hooks/useEvent'
|
import { useEvent } from '@/hooks/useEvent'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
|
||||||
export default forwardRef(function WallLine({ length1Ref, length2Ref, arrow1Ref, arrow2Ref, radioTypeRef, currentWallLineRef }, ref) {
|
export default forwardRef(function WallLine({ length1Ref, length2Ref, arrow1Ref, arrow2Ref, radioTypeRef, currentWallLineRef }, ref) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
@ -46,7 +47,21 @@ export default forwardRef(function WallLine({ length1Ref, length2Ref, arrow1Ref,
|
|||||||
<div className="eaves-keraba-td">
|
<div className="eaves-keraba-td">
|
||||||
<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="text" className="input-origin block" placeholder={0} readOnly={type !== 1} ref={length1Ref} />
|
{/*<input type="text" className="input-origin block" placeholder={0} readOnly={type !== 1} ref={length1Ref} />*/}
|
||||||
|
<CalculatorInput
|
||||||
|
id=""
|
||||||
|
name=""
|
||||||
|
label=""
|
||||||
|
className="input-origin block"
|
||||||
|
value={length1Ref.current?.value ?? 0}
|
||||||
|
ref={length1Ref}
|
||||||
|
onChange={() => {}}
|
||||||
|
readOnly={type !== 1}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
@ -80,7 +95,21 @@ export default forwardRef(function WallLine({ length1Ref, length2Ref, arrow1Ref,
|
|||||||
<div className="eaves-keraba-td">
|
<div className="eaves-keraba-td">
|
||||||
<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="text" className="input-origin block" placeholder={0} readOnly={type !== 2} ref={length2Ref} />
|
{/*<input type="text" className="input-origin block" placeholder={0} readOnly={type !== 2} ref={length2Ref} />*/}
|
||||||
|
<CalculatorInput
|
||||||
|
id=""
|
||||||
|
name=""
|
||||||
|
label=""
|
||||||
|
className="input-origin block"
|
||||||
|
value={length2Ref.current?.value ?? 0}
|
||||||
|
ref={length2Ref}
|
||||||
|
onChange={() => {}}
|
||||||
|
readOnly={type !== 2}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">mm</span>
|
<span className="thin">mm</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -133,17 +133,21 @@ export default function Header(props) {
|
|||||||
{ id: 1, name: 'HANASYS ORDER', link: `${qOrderUrl}?autoLoginParam1=${encodeURIComponent(res.data)}`, target: '_blank' },
|
{ id: 1, name: 'HANASYS ORDER', link: `${qOrderUrl}?autoLoginParam1=${encodeURIComponent(res.data)}`, target: '_blank' },
|
||||||
{ id: 2, name: 'HANASYS Musubi', link: `${qMusubiUrl}?autoLoginParam1=${encodeURIComponent(res.data)}`, target: '_blank' },
|
{ id: 2, name: 'HANASYS Musubi', link: `${qMusubiUrl}?autoLoginParam1=${encodeURIComponent(res.data)}`, target: '_blank' },
|
||||||
{ id: 3, name: getMessage('site.header.link2'), link: `https://q-warranty.q-cells.jp/seller_login`, target: '_blank' },
|
{ id: 3, name: getMessage('site.header.link2'), link: `https://q-warranty.q-cells.jp/seller_login`, target: '_blank' },
|
||||||
|
{ id: 4, name: 'Q.PARTNERS', link: `https://q-partners.q-cells.jp/qcast_login.php`, target: '_blank' },
|
||||||
|
|
||||||
]
|
]
|
||||||
: userSession.groupId === '60000'
|
: userSession.groupId === '60000'
|
||||||
? [
|
? [
|
||||||
{ id: 0, name: getMessage('site.header.link1'), target: '_blank' },
|
{ id: 0, name: getMessage('site.header.link1'), target: '_blank' },
|
||||||
{ id: 1, name: 'HANASYS ORDER', link: `${qOrderUrl}?autoLoginParam1=${encodeURIComponent(res.data)}`, target: '_blank' },
|
{ id: 1, name: 'HANASYS ORDER', link: `${qOrderUrl}?autoLoginParam1=${encodeURIComponent(res.data)}`, target: '_blank' },
|
||||||
{ id: 2, name: getMessage('site.header.link2'), link: `https://q-warranty.q-cells.jp/seller_login`, target: '_blank' },
|
{ id: 2, name: getMessage('site.header.link2'), link: `https://q-warranty.q-cells.jp/seller_login`, target: '_blank' },
|
||||||
|
{ id: 3, name: 'Q.PARTNERS', link: `https://q-partners.q-cells.jp/qcast_login.php`, target: '_blank' },
|
||||||
]
|
]
|
||||||
: [
|
: [
|
||||||
{ id: 0, name: getMessage('site.header.link1'), target: '_blank' },
|
{ id: 0, name: getMessage('site.header.link1'), target: '_blank' },
|
||||||
{ id: 1, name: 'HANASYS Musubi', link: `${qMusubiUrl}?autoLoginParam1=${encodeURIComponent(res.data)}`, target: '_blank' },
|
{ id: 1, name: 'HANASYS Musubi', link: `${qMusubiUrl}?autoLoginParam1=${encodeURIComponent(res.data)}`, target: '_blank' },
|
||||||
{ id: 2, name: getMessage('site.header.link2'), link: `https://q-warranty.q-cells.jp/seller_login`, target: '_blank' },
|
{ id: 2, name: getMessage('site.header.link2'), link: `https://q-warranty.q-cells.jp/seller_login`, target: '_blank' },
|
||||||
|
{ id: 3, name: 'Q.PARTNERS', link: `https://q-partners.q-cells.jp/qcast_login.php`, target: '_blank' },
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
onChangeSelect({ id: 0, name: getMessage('site.header.link1') })
|
onChangeSelect({ id: 0, name: getMessage('site.header.link1') })
|
||||||
|
|||||||
@ -264,15 +264,14 @@ export default function Simulator() {
|
|||||||
style={{ width: '30%' }}
|
style={{ width: '30%' }}
|
||||||
className="select-light"
|
className="select-light"
|
||||||
value={pwrGnrSimType}
|
value={pwrGnrSimType}
|
||||||
defaultValue={`D`}
|
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
handleChartChangeData(e.target.value)
|
handleChartChangeData(e.target.value)
|
||||||
setPwrGnrSimType(e.target.value)
|
setPwrGnrSimType(e.target.value)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<option value={`A`}>積雪考慮なし(ピークカットなし発電量)</option>
|
{/*<option value={`A`}>積雪考慮なし(ピークカットなし発電量)</option>*/}
|
||||||
<option value={`B`}>積雪考慮なし(ピークカットあり発電量)</option>
|
<option value={`B`}>積雪考慮なし(ピークカットあり発電量)</option>
|
||||||
<option value={`C`}>積雪考慮あり(ピークカットなし発電量)</option>
|
{/*<option value={`C`}>積雪考慮あり(ピークカットなし発電量)</option>*/}
|
||||||
<option value={`D`}>積雪考慮あり(ピークカットあり発電量)</option>
|
<option value={`D`}>積雪考慮あり(ピークカットあり発電量)</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
@ -334,33 +333,31 @@ export default function Simulator() {
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{moduleInfoList.length > 0 ? (
|
{moduleInfoList.length > 0 ? (
|
||||||
moduleInfoList.map((moduleInfo) => {
|
moduleInfoList.map((moduleInfo) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<tr key={moduleInfo.itemId}>
|
||||||
<tr key={moduleInfo.itemId}>
|
{/* 지붕면 */}
|
||||||
{/* 지붕면 */}
|
<td>{moduleInfo.roofSurface}</td>
|
||||||
<td>{moduleInfo.roofSurface}</td>
|
{/* 경사각 */}
|
||||||
{/* 경사각 */}
|
<td>
|
||||||
<td>
|
{convertNumberToPriceDecimal(moduleInfo.slopeAngle)}
|
||||||
{convertNumberToPriceDecimal(moduleInfo.slopeAngle)}
|
{moduleInfo.classType == 0 ? '寸' : 'º'}
|
||||||
{moduleInfo.classType == 0 ? '寸' : 'º'}
|
</td>
|
||||||
</td>
|
{/* 방위각(도) */}
|
||||||
{/* 방위각(도) */}
|
<td>{convertNumberToPriceDecimal(moduleInfo.azimuth)}</td>
|
||||||
<td>{convertNumberToPriceDecimal(moduleInfo.azimuth)}</td>
|
{/* 태양전지모듈 */}
|
||||||
{/* 태양전지모듈 */}
|
<td>
|
||||||
<td>
|
<div className="overflow-lab">{moduleInfo.itemNo}</div>
|
||||||
<div className="overflow-lab">{moduleInfo.itemNo}</div>
|
</td>
|
||||||
</td>
|
{/* 매수 */}
|
||||||
{/* 매수 */}
|
<td>{convertNumberToPriceDecimal(moduleInfo.amount)}</td>
|
||||||
<td>{convertNumberToPriceDecimal(moduleInfo.amount)}</td>
|
</tr>
|
||||||
</tr>
|
)
|
||||||
</>
|
})
|
||||||
)
|
) : (
|
||||||
})
|
<tr>
|
||||||
) : (
|
<td colSpan={5}>{getMessage('common.message.no.data')}</td>
|
||||||
<tr>
|
|
||||||
<td colSpan={5}>{getMessage('common.message.no.data')}</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
)}
|
)}
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -385,25 +382,23 @@ export default function Simulator() {
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{pcsInfoList.length > 0 ? (
|
{pcsInfoList.length > 0 ? (
|
||||||
pcsInfoList.map((pcsInfo) => {
|
pcsInfoList.map((pcsInfo) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<tr key={pcsInfo.itemId}>
|
||||||
<tr key={pcsInfo.itemId}>
|
{/* 파워컨디셔너 */}
|
||||||
{/* 파워컨디셔너 */}
|
<td className="al-l">
|
||||||
<td className="al-l">
|
<div className="overflow-lab">{pcsInfo.itemNo}</div>
|
||||||
<div className="overflow-lab">{pcsInfo.itemNo}</div>
|
</td>
|
||||||
</td>
|
{/* 대 */}
|
||||||
{/* 대 */}
|
<td>{convertNumberToPriceDecimal(pcsInfo.amount)}</td>
|
||||||
<td>{convertNumberToPriceDecimal(pcsInfo.amount)}</td>
|
</tr>
|
||||||
</tr>
|
)
|
||||||
</>
|
})
|
||||||
)
|
) : (
|
||||||
})
|
<tr>
|
||||||
) : (
|
<td colSpan={2}>{getMessage('common.message.no.data')}</td>
|
||||||
<tr>
|
</tr>
|
||||||
<td colSpan={2}>{getMessage('common.message.no.data')}</td>
|
|
||||||
</tr>
|
|
||||||
)}
|
)}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@ -31,8 +31,11 @@ export function useCommonUtils() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
commonTextMode()
|
commonTextMode()
|
||||||
if (commonUtils.dimension) {
|
if (commonUtils.dimension) {
|
||||||
|
generateTempGrid()
|
||||||
commonDimensionMode()
|
commonDimensionMode()
|
||||||
return
|
return
|
||||||
|
} else {
|
||||||
|
removeTempGrid()
|
||||||
}
|
}
|
||||||
if (commonUtils.distance) {
|
if (commonUtils.distance) {
|
||||||
commonDistanceMode()
|
commonDistanceMode()
|
||||||
@ -645,6 +648,7 @@ export function useCommonUtils() {
|
|||||||
lockMovementY: true,
|
lockMovementY: true,
|
||||||
name: obj.name,
|
name: obj.name,
|
||||||
editable: false,
|
editable: false,
|
||||||
|
selectable: true, // 복사된 객체 선택 가능하도록 설정
|
||||||
id: uuidv4(), //복사된 객체라 새로 따준다
|
id: uuidv4(), //복사된 객체라 새로 따준다
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -653,19 +657,25 @@ export function useCommonUtils() {
|
|||||||
|
|
||||||
//배치면일 경우
|
//배치면일 경우
|
||||||
if (obj.name === 'roof') {
|
if (obj.name === 'roof') {
|
||||||
clonedObj.setCoords()
|
clonedObj.canvas = canvas // canvas 참조 설정
|
||||||
clonedObj.fire('modified')
|
|
||||||
clonedObj.fire('polygonMoved')
|
|
||||||
clonedObj.set({
|
clonedObj.set({
|
||||||
direction: obj.direction,
|
direction: obj.direction,
|
||||||
directionText: obj.directionText,
|
directionText: obj.directionText,
|
||||||
roofMaterial: obj.roofMaterial,
|
roofMaterial: obj.roofMaterial,
|
||||||
|
stroke: 'black', // 복사된 객체는 선택 해제 상태의 색상으로 설정
|
||||||
|
selectable: true, // 선택 가능하도록 설정
|
||||||
|
evented: true, // 마우스 이벤트를 받을 수 있도록 설정
|
||||||
|
isFixed: false, // containsPoint에서 특별 처리 방지
|
||||||
})
|
})
|
||||||
|
|
||||||
obj.lines.forEach((line, index) => {
|
obj.lines.forEach((line, index) => {
|
||||||
clonedObj.lines[index].set({ attributes: line.attributes })
|
clonedObj.lines[index].set({ attributes: line.attributes })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
clonedObj.fire('polygonMoved') // 내부 좌표 재계산 (points, pathOffset)
|
||||||
|
clonedObj.fire('modified')
|
||||||
|
clonedObj.setCoords() // 모든 속성 설정 후 좌표 업데이트
|
||||||
|
canvas.setActiveObject(clonedObj)
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
addLengthText(clonedObj) //수치 추가
|
addLengthText(clonedObj) //수치 추가
|
||||||
drawDirectionArrow(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 {
|
return {
|
||||||
commonFunctions,
|
commonFunctions,
|
||||||
dimensionSettings,
|
dimensionSettings,
|
||||||
@ -916,5 +965,7 @@ export function useCommonUtils() {
|
|||||||
editText,
|
editText,
|
||||||
changeDimensionExtendLine,
|
changeDimensionExtendLine,
|
||||||
deleteOuterLineObject,
|
deleteOuterLineObject,
|
||||||
|
generateTempGrid,
|
||||||
|
removeTempGrid,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { useRecoilValue, useResetRecoilState } from 'recoil'
|
import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil'
|
||||||
import { canvasState, currentObjectState } from '@/store/canvasAtom'
|
import { canvasState, currentObjectState } from '@/store/canvasAtom'
|
||||||
import { selectedRoofMaterialSelector } from '@/store/settingAtom'
|
import { selectedRoofMaterialSelector } from '@/store/settingAtom'
|
||||||
import { ROOF_MATERIAL_LAYOUT } from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting'
|
import { ROOF_MATERIAL_LAYOUT } from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting'
|
||||||
@ -25,6 +25,7 @@ export function useRoofFn() {
|
|||||||
const { addPitchText } = useLine()
|
const { addPitchText } = useLine()
|
||||||
const { setPolygonLinesActualSize } = usePolygon()
|
const { setPolygonLinesActualSize } = usePolygon()
|
||||||
const { changeCorridorDimensionText } = useText()
|
const { changeCorridorDimensionText } = useText()
|
||||||
|
const [outerLinePoints, setOuterLinePoints] = useRecoilState(outerLinePointsState)
|
||||||
|
|
||||||
//면형상 선택 클릭시 지붕 패턴 입히기
|
//면형상 선택 클릭시 지붕 패턴 입히기
|
||||||
function setSurfaceShapePattern(polygon, mode = 'onlyBorder', trestleMode = false, roofMaterial, isForceChange = false, isDisplay = false) {
|
function setSurfaceShapePattern(polygon, mode = 'onlyBorder', trestleMode = false, roofMaterial, isForceChange = false, isDisplay = false) {
|
||||||
@ -263,6 +264,9 @@ export function useRoofFn() {
|
|||||||
const deltaX = roof.left - originalRoofLeft
|
const deltaX = roof.left - originalRoofLeft
|
||||||
const deltaY = roof.top - originalRoofTop
|
const deltaY = roof.top - originalRoofTop
|
||||||
|
|
||||||
|
const originOuterLinePoints = [...outerLinePoints]
|
||||||
|
setOuterLinePoints(originOuterLinePoints.map((point) => ({ x: point.x + deltaX, y: point.y + deltaY })))
|
||||||
|
|
||||||
// Move all related objects by the delta
|
// Move all related objects by the delta
|
||||||
allRoofObject.forEach((obj) => {
|
allRoofObject.forEach((obj) => {
|
||||||
if (obj.points !== undefined) {
|
if (obj.points !== undefined) {
|
||||||
|
|||||||
@ -241,7 +241,11 @@ export const useEstimateController = (planNo, flag) => {
|
|||||||
|
|
||||||
//북면 먼저 체크
|
//북면 먼저 체크
|
||||||
if (estimateData.fileFlg === '0') {
|
if (estimateData.fileFlg === '0') {
|
||||||
if (estimateData?.northArrangement === '1') {
|
if (estimateData?.northArrangement === '1' &&
|
||||||
|
!estimateData?.moduleModel
|
||||||
|
?.replace(/\s+/g, '') // 모든 공백 제거
|
||||||
|
?.toUpperCase()
|
||||||
|
?.includes('RE.RISE-NBCAG')) {
|
||||||
fileFlg = false
|
fileFlg = false
|
||||||
setIsGlobalLoading(false)
|
setIsGlobalLoading(false)
|
||||||
return swalFire({ text: getMessage('estimate.detail.save.requiredNorthArrangementFileUpload'), type: 'alert', icon: 'warning' })
|
return swalFire({ text: getMessage('estimate.detail.save.requiredNorthArrangementFileUpload'), type: 'alert', icon: 'warning' })
|
||||||
|
|||||||
@ -743,7 +743,19 @@ export const useTrestle = () => {
|
|||||||
if (!data || data.length === 0) {
|
if (!data || data.length === 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
itemList = data
|
//itemList = data
|
||||||
|
// itemList에 northModuleYn 추가
|
||||||
|
itemList = data.map(item => {
|
||||||
|
if (item.itemTpCd === "MODULE") {
|
||||||
|
const matchedModule = modules.find(module => module.moduleItemId === item.itemId);
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
northModuleYn: matchedModule?.northModuleYn || 'N'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
//northArrangement 북면 설치 여부
|
//northArrangement 북면 설치 여부
|
||||||
const northArrangement = getNorthArrangement()
|
const northArrangement = getNorthArrangement()
|
||||||
@ -2586,6 +2598,7 @@ export const useTrestle = () => {
|
|||||||
return {
|
return {
|
||||||
moduleTpCd: module.moduleInfo.itemTp,
|
moduleTpCd: module.moduleInfo.itemTp,
|
||||||
moduleItemId: module.moduleInfo.itemId,
|
moduleItemId: module.moduleInfo.itemId,
|
||||||
|
northModuleYn: module?.moduleInfo?.northModuleYn || 'N' // 기본값 'N'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -2597,6 +2610,7 @@ export const useTrestle = () => {
|
|||||||
moduleTpCd: cur.moduleTpCd,
|
moduleTpCd: cur.moduleTpCd,
|
||||||
moduleItemId: cur.moduleItemId,
|
moduleItemId: cur.moduleItemId,
|
||||||
cnt: 0,
|
cnt: 0,
|
||||||
|
northModuleYn: cur.northModuleYn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
acc[key].cnt++
|
acc[key].cnt++
|
||||||
@ -2609,6 +2623,11 @@ export const useTrestle = () => {
|
|||||||
moduleTpCd: groupedParam.moduleTpCd,
|
moduleTpCd: groupedParam.moduleTpCd,
|
||||||
moduleItemId: groupedParam.moduleItemId,
|
moduleItemId: groupedParam.moduleItemId,
|
||||||
moduleCnt: groupedParam.cnt,
|
moduleCnt: groupedParam.cnt,
|
||||||
|
northModuleYn: groupedParam.northModuleYn
|
||||||
|
// northModuleYn: params.find(p =>
|
||||||
|
// p.moduleTpCd === groupedParam.moduleTpCd &&
|
||||||
|
// p.moduleItemId === groupedParam.moduleItemId
|
||||||
|
// )?.northModuleYn || 'N'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,6 +42,7 @@ import { useEvent } from '@/hooks/useEvent'
|
|||||||
import { logger } from '@/util/logger'
|
import { logger } from '@/util/logger'
|
||||||
import { useText } from '@/hooks/useText'
|
import { useText } from '@/hooks/useText'
|
||||||
import { usePolygon } from '@/hooks/usePolygon'
|
import { usePolygon } from '@/hooks/usePolygon'
|
||||||
|
import { getDegreeByChon } from '@/util/canvas-util'
|
||||||
|
|
||||||
const defaultDotLineGridSetting = {
|
const defaultDotLineGridSetting = {
|
||||||
INTERVAL: {
|
INTERVAL: {
|
||||||
@ -177,8 +178,8 @@ export function useCanvasSetting(executeEffect = true) {
|
|||||||
raft: item.raftBase && parseInt(item.raftBase),
|
raft: item.raftBase && parseInt(item.raftBase),
|
||||||
layout: ['ROOF_ID_SLATE', 'ROOF_ID_SINGLE'].includes(item.roofMatlCd) ? ROOF_MATERIAL_LAYOUT.STAIRS : ROOF_MATERIAL_LAYOUT.PARALLEL,
|
layout: ['ROOF_ID_SLATE', 'ROOF_ID_SINGLE'].includes(item.roofMatlCd) ? ROOF_MATERIAL_LAYOUT.STAIRS : ROOF_MATERIAL_LAYOUT.PARALLEL,
|
||||||
hajebichi: item.roofPchBase && parseInt(item.roofPchBase),
|
hajebichi: item.roofPchBase && parseInt(item.roofPchBase),
|
||||||
pitch: item.pitch ? parseInt(item.pitch) : 4,
|
pitch: item.inclBase ? parseInt(item.inclBase) : 4,
|
||||||
angle: item.angle ? parseInt(item.angle) : 21.8,
|
angle: getDegreeByChon(item.inclBase ? parseInt(item.inclBase): 4) //item.angle ? parseInt(item.angle) : 21.8,
|
||||||
}))
|
}))
|
||||||
setRoofMaterials(roofLists)
|
setRoofMaterials(roofLists)
|
||||||
return roofLists
|
return roofLists
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import { useSwal } from '@/hooks/useSwal'
|
|||||||
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
|
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
|
||||||
import Big from 'big.js'
|
import Big from 'big.js'
|
||||||
import { calcLinePlaneSize } from '@/util/qpolygon-utils'
|
import { calcLinePlaneSize } from '@/util/qpolygon-utils'
|
||||||
|
import { getSelectLinePosition } from '@/util/skeleton-utils'
|
||||||
import { useMouse } from '@/hooks/useMouse'
|
import { useMouse } from '@/hooks/useMouse'
|
||||||
|
|
||||||
//동선이동 형 올림 내림
|
//동선이동 형 올림 내림
|
||||||
@ -91,7 +92,7 @@ export function useMovementSetting(id) {
|
|||||||
}
|
}
|
||||||
wall.baseLines.forEach((line) => {
|
wall.baseLines.forEach((line) => {
|
||||||
if (type === TYPE.UP_DOWN) {
|
if (type === TYPE.UP_DOWN) {
|
||||||
line.set({ selectable: true, visible: true, stroke: '#1083E3', strokeWidth: 5 })
|
line.set({ selectable: true, visible: true, stroke: '#1085E5', strokeWidth: 5 })
|
||||||
line.setCoords()
|
line.setCoords()
|
||||||
line.bringToFront()
|
line.bringToFront()
|
||||||
} else {
|
} else {
|
||||||
@ -102,7 +103,7 @@ export function useMovementSetting(id) {
|
|||||||
|
|
||||||
/** outerLines 속성처리*/
|
/** outerLines 속성처리*/
|
||||||
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||||
outerLines.forEach((line) => line.set({ visible: false }))
|
outerLines.forEach((line) => line.set({ visible: true }))
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
}, [type])
|
}, [type])
|
||||||
|
|
||||||
@ -179,99 +180,238 @@ export function useMovementSetting(id) {
|
|||||||
name: 'followLine',
|
name: 'followLine',
|
||||||
})
|
})
|
||||||
canvas.add(followLine)
|
canvas.add(followLine)
|
||||||
|
followLine.bringToFront()
|
||||||
FOLLOW_LINE_REF.current = followLine
|
FOLLOW_LINE_REF.current = followLine
|
||||||
|
|
||||||
canvas.on('mouse:move', (event) => {
|
|
||||||
const mousePos = getIntersectMousePoint(event)
|
|
||||||
if (followLine.x1 === followLine.x2) {
|
|
||||||
followLine.left = mousePos.x - 2
|
|
||||||
} else {
|
|
||||||
followLine.top = mousePos.y - 2
|
|
||||||
}
|
|
||||||
canvas.renderAll()
|
|
||||||
})
|
|
||||||
|
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
}, [currentObject])
|
}, [currentObject])
|
||||||
|
|
||||||
|
|
||||||
const clearRef = () => {
|
const clearRef = () => {
|
||||||
if (type === TYPE.FLOW_LINE) {
|
if (type === TYPE.FLOW_LINE) {
|
||||||
FLOW_LINE_REF.POINTER_INPUT_REF.current.value = ''
|
// 안전한 ref 접근
|
||||||
FLOW_LINE_REF.FILLED_INPUT_REF.current.value = ''
|
if (FLOW_LINE_REF.POINTER_INPUT_REF.current) {
|
||||||
FLOW_LINE_REF.DOWN_LEFT_RADIO_REF.current.checked = true
|
FLOW_LINE_REF.POINTER_INPUT_REF.current.value = ''
|
||||||
FLOW_LINE_REF.UP_RIGHT_RADIO_REF.current.checked = false
|
}
|
||||||
}
|
if (FLOW_LINE_REF.FILLED_INPUT_REF.current) {
|
||||||
if (type === TYPE.UP_DOWN) {
|
FLOW_LINE_REF.FILLED_INPUT_REF.current.value = ''
|
||||||
UP_DOWN_REF.POINTER_INPUT_REF.current.value = ''
|
}
|
||||||
UP_DOWN_REF.FILLED_INPUT_REF.current.value = ''
|
|
||||||
UP_DOWN_REF.UP_RADIO_REF.current.checked = true
|
|
||||||
UP_DOWN_REF.DOWN_RADIO_REF.current.checked = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const mouseMoveEvent = (e) => {
|
const upRightChecked = FLOW_LINE_REF.UP_RIGHT_RADIO_REF.current?.checked || false
|
||||||
const target = canvas.getActiveObject()
|
const downLeftChecked = FLOW_LINE_REF.DOWN_LEFT_RADIO_REF.current?.checked || false
|
||||||
if (!target) return
|
|
||||||
|
|
||||||
const { top: targetTop, left: targetLeft } = target
|
if (upRightChecked || downLeftChecked) {
|
||||||
const currentX = Big(getIntersectMousePoint(e).x) //.round(0, Big.roundUp)
|
if (FLOW_LINE_REF.UP_RIGHT_RADIO_REF.current) {
|
||||||
const currentY = Big(getIntersectMousePoint(e).y) //.round(0, Big.roundUp)
|
FLOW_LINE_REF.UP_RIGHT_RADIO_REF.current.checked = !downLeftChecked
|
||||||
let value = ''
|
}
|
||||||
if (target.y1 === target.y2) {
|
if (FLOW_LINE_REF.DOWN_LEFT_RADIO_REF.current) {
|
||||||
value = Big(targetTop).minus(currentY).times(10).round(0)
|
FLOW_LINE_REF.DOWN_LEFT_RADIO_REF.current.checked = !upRightChecked
|
||||||
} else {
|
|
||||||
value = Big(targetLeft).minus(currentX).times(10).round(0).neg()
|
|
||||||
}
|
|
||||||
if (typeRef.current === TYPE.FLOW_LINE) {
|
|
||||||
FLOW_LINE_REF.POINTER_INPUT_REF.current.value = value.toNumber()
|
|
||||||
} else {
|
|
||||||
UP_DOWN_REF.POINTER_INPUT_REF.current.value = value.abs().toNumber()
|
|
||||||
const midX = Big(target.x1).plus(target.x2).div(2)
|
|
||||||
const midY = Big(target.y1).plus(target.y2).div(2)
|
|
||||||
const wall = canvas.getObjects().find((obj) => obj.id === target.attributes.wallId)
|
|
||||||
let checkPoint
|
|
||||||
if (target.y1 === target.y2) {
|
|
||||||
checkPoint = { x: midX.toNumber(), y: midY.plus(10).toNumber() }
|
|
||||||
if (wall.inPolygon(checkPoint)) {
|
|
||||||
if (value.s === -1) {
|
|
||||||
UP_DOWN_REF.UP_RADIO_REF.current.checked = false
|
|
||||||
UP_DOWN_REF.DOWN_RADIO_REF.current.checked = true
|
|
||||||
} else {
|
|
||||||
UP_DOWN_REF.UP_RADIO_REF.current.checked = true
|
|
||||||
UP_DOWN_REF.DOWN_RADIO_REF.current.checked = false
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (value.s === 1) {
|
|
||||||
UP_DOWN_REF.UP_RADIO_REF.current.checked = false
|
|
||||||
UP_DOWN_REF.DOWN_RADIO_REF.current.checked = true
|
|
||||||
} else {
|
|
||||||
UP_DOWN_REF.UP_RADIO_REF.current.checked = true
|
|
||||||
UP_DOWN_REF.DOWN_RADIO_REF.current.checked = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
checkPoint = { x: midX.plus(10).toNumber(), y: midY.toNumber() }
|
if (FLOW_LINE_REF.DOWN_LEFT_RADIO_REF.current) {
|
||||||
if (wall.inPolygon(checkPoint)) {
|
FLOW_LINE_REF.DOWN_LEFT_RADIO_REF.current.checked = true
|
||||||
if (value.s === 1) {
|
}
|
||||||
UP_DOWN_REF.UP_RADIO_REF.current.checked = false
|
if (FLOW_LINE_REF.UP_RIGHT_RADIO_REF.current) {
|
||||||
UP_DOWN_REF.DOWN_RADIO_REF.current.checked = true
|
FLOW_LINE_REF.UP_RIGHT_RADIO_REF.current.checked = false
|
||||||
} else {
|
|
||||||
UP_DOWN_REF.UP_RADIO_REF.current.checked = true
|
|
||||||
UP_DOWN_REF.DOWN_RADIO_REF.current.checked = false
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (value.s === -1) {
|
|
||||||
UP_DOWN_REF.UP_RADIO_REF.current.checked = false
|
|
||||||
UP_DOWN_REF.DOWN_RADIO_REF.current.checked = true
|
|
||||||
} else {
|
|
||||||
UP_DOWN_REF.UP_RADIO_REF.current.checked = true
|
|
||||||
UP_DOWN_REF.DOWN_RADIO_REF.current.checked = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type === TYPE.UP_DOWN) {
|
||||||
|
// 안전한 ref 접근
|
||||||
|
if (UP_DOWN_REF.POINTER_INPUT_REF.current) {
|
||||||
|
UP_DOWN_REF.POINTER_INPUT_REF.current.value = ''
|
||||||
|
}
|
||||||
|
if (UP_DOWN_REF.FILLED_INPUT_REF.current) {
|
||||||
|
UP_DOWN_REF.FILLED_INPUT_REF.current.value = ''
|
||||||
|
}
|
||||||
|
if (UP_DOWN_REF.UP_RADIO_REF.current) {
|
||||||
|
UP_DOWN_REF.UP_RADIO_REF.current.checked = true
|
||||||
|
}
|
||||||
|
if (UP_DOWN_REF.DOWN_RADIO_REF.current) {
|
||||||
|
UP_DOWN_REF.DOWN_RADIO_REF.current.checked = false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let currentCalculatedValue = 0
|
||||||
|
|
||||||
|
const mouseMoveEvent = (e) => {
|
||||||
|
//console.log('mouseMoveEvent:::::',e)
|
||||||
|
// 기존에는 activeObject를 사용했으나, 이 기능에서는 선택된 라인을 비선택(selectable:false) 상태로 두므로
|
||||||
|
// 항상 selectedObject.current를 기준으로 계산한다.
|
||||||
|
const target = selectedObject.current
|
||||||
|
if (!target) return
|
||||||
|
|
||||||
|
// 디버깅 로그 추가
|
||||||
|
// if (typeRef.current === TYPE.UP_DOWN) {
|
||||||
|
// console.log('UP_DOWN_REF.POINTER_INPUT_REF.current:', UP_DOWN_REF.POINTER_INPUT_REF.current);
|
||||||
|
// if (!UP_DOWN_REF.POINTER_INPUT_REF.current) {
|
||||||
|
// console.warn('UP_DOWN_REF.POINTER_INPUT_REF.current is null/undefined');
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
const { top: targetTop, left: targetLeft } = target
|
||||||
|
const currentX = Big(getIntersectMousePoint(e).x)
|
||||||
|
const currentY = Big(getIntersectMousePoint(e).y)
|
||||||
|
|
||||||
|
let value = ''
|
||||||
|
let direction = ''
|
||||||
|
|
||||||
|
if (Math.abs(target.y1 - target.y2) < 0.5) { // 수평 라인
|
||||||
|
value = Big(targetTop).minus(currentY).times(10).round(0)
|
||||||
|
|
||||||
|
// 방향 감지
|
||||||
|
if (value.toNumber() > 0) {
|
||||||
|
direction = 'up' // 마우스가 라인 위쪽에 있음 (위로 움직임)
|
||||||
|
} else if (value.toNumber() < 0) {
|
||||||
|
direction = 'down' // 마우스가 라인 아래쪽에 있음 (아래로 움직임)
|
||||||
|
}
|
||||||
|
} else { // 수직 라인
|
||||||
|
value = Big(targetLeft).minus(currentX).times(10).round(0).neg()
|
||||||
|
|
||||||
|
// 방향 감지
|
||||||
|
if (value.toNumber() > 0) {
|
||||||
|
direction = 'right' // 마우스가 라인 오른쪽에 있음 (오른쪽으로 움직임)
|
||||||
|
} else if (value.toNumber() < 0) {
|
||||||
|
direction = 'left' // 마우스가 라인 왼쪽에 있음 (왼쪽으로 움직임)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// followLine도 포인터를 따라가도록 동기화 (하나의 mouse:move 핸들러만 사용)
|
||||||
|
const followLine = FOLLOW_LINE_REF.current
|
||||||
|
if (followLine) {
|
||||||
|
if (followLine.x1 === followLine.x2) {
|
||||||
|
// 수직 라인: x만 이동
|
||||||
|
followLine.left = currentX.toNumber() - 2
|
||||||
|
} else {
|
||||||
|
// 수평 라인: y만 이동
|
||||||
|
followLine.top = currentY.toNumber() - 2
|
||||||
|
}
|
||||||
|
followLine.bringToFront()
|
||||||
|
followLine.setCoords && followLine.setCoords()
|
||||||
|
canvas.renderAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 방향 정보를 사용하여 라디오 버튼 상태 업데이트
|
||||||
|
|
||||||
|
currentCalculatedValue = value.toNumber()
|
||||||
|
|
||||||
|
if (typeRef.current === TYPE.FLOW_LINE) {
|
||||||
|
// ref가 존재하는지 확인 후 값 설정
|
||||||
|
if (FLOW_LINE_REF.POINTER_INPUT_REF.current) {
|
||||||
|
FLOW_LINE_REF.POINTER_INPUT_REF.current.value = value.toNumber()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// UP_DOWN 타입일 때 안전한 접근
|
||||||
|
if (UP_DOWN_REF.POINTER_INPUT_REF.current) {
|
||||||
|
UP_DOWN_REF.POINTER_INPUT_REF.current.value = value.abs().toNumber()
|
||||||
|
}
|
||||||
|
|
||||||
|
const midX = Big(target.x1).plus(target.x2).div(2)
|
||||||
|
const midY = Big(target.y1).plus(target.y2).div(2)
|
||||||
|
const wall = canvas.getObjects().find((obj) => obj.id === target.attributes.wallId)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const result = getSelectLinePosition(wall, target, {
|
||||||
|
testDistance: 5, // 테스트 거리
|
||||||
|
debug: true // 디버깅 로그 출력
|
||||||
|
});
|
||||||
|
//console.log("1111litarget:::::", target);
|
||||||
|
//console.log("1111linePosition:::::", result.position); // 'top', 'bottom', 'left', 'right'
|
||||||
|
|
||||||
|
let linePosition = result.position;
|
||||||
|
//console.log("1111linePosition:::::", direction, linePosition);
|
||||||
|
|
||||||
|
if (target.y1 === target.y2) { //수평벽
|
||||||
|
|
||||||
|
const setRadioStates = (isUp) => {
|
||||||
|
if (UP_DOWN_REF.UP_RADIO_REF.current) {
|
||||||
|
UP_DOWN_REF.UP_RADIO_REF.current.checked = isUp;
|
||||||
|
}
|
||||||
|
if (UP_DOWN_REF.DOWN_RADIO_REF.current) {
|
||||||
|
UP_DOWN_REF.DOWN_RADIO_REF.current.checked = !isUp;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (linePosition === 'top') {
|
||||||
|
setRadioStates(value.s !== -1);
|
||||||
|
} else if (linePosition === 'bottom') {
|
||||||
|
setRadioStates(value.s !== 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(direction === 'up') {
|
||||||
|
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
checkPoint = { x: midX.toNumber(), y: midY.plus(10).toNumber() }
|
||||||
|
if (wall.inPolygon(checkPoint)) { //선택라인이 내부
|
||||||
|
if (value.s === -1) {
|
||||||
|
console.log('1value:::', value.s)
|
||||||
|
if (UP_DOWN_REF.UP_RADIO_REF.current) UP_DOWN_REF.UP_RADIO_REF.current.checked = false
|
||||||
|
if (UP_DOWN_REF.DOWN_RADIO_REF.current) UP_DOWN_REF.DOWN_RADIO_REF.current.checked = true
|
||||||
|
} else {
|
||||||
|
if (UP_DOWN_REF.UP_RADIO_REF.current) UP_DOWN_REF.UP_RADIO_REF.current.checked = true
|
||||||
|
if (UP_DOWN_REF.DOWN_RADIO_REF.current) UP_DOWN_REF.DOWN_RADIO_REF.current.checked = false
|
||||||
|
}
|
||||||
|
} else { //
|
||||||
|
if (value.s === 1) { //선택라인이 외부
|
||||||
|
console.log('2value:::', value.s)
|
||||||
|
if (UP_DOWN_REF.UP_RADIO_REF.current) UP_DOWN_REF.UP_RADIO_REF.current.checked = false
|
||||||
|
if (UP_DOWN_REF.DOWN_RADIO_REF.current) UP_DOWN_REF.DOWN_RADIO_REF.current.checked = true
|
||||||
|
} else {
|
||||||
|
if (UP_DOWN_REF.UP_RADIO_REF.current) UP_DOWN_REF.UP_RADIO_REF.current.checked = true
|
||||||
|
if (UP_DOWN_REF.DOWN_RADIO_REF.current) UP_DOWN_REF.DOWN_RADIO_REF.current.checked = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
} else {
|
||||||
|
|
||||||
|
const setRadioStates = (isUp) => {
|
||||||
|
if (UP_DOWN_REF.UP_RADIO_REF.current) {
|
||||||
|
UP_DOWN_REF.UP_RADIO_REF.current.checked = isUp;
|
||||||
|
}
|
||||||
|
if (UP_DOWN_REF.DOWN_RADIO_REF.current) {
|
||||||
|
UP_DOWN_REF.DOWN_RADIO_REF.current.checked = !isUp;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (linePosition === 'left') {
|
||||||
|
setRadioStates(value.s !== 1);
|
||||||
|
} else if (linePosition === 'right') {
|
||||||
|
setRadioStates(value.s !== -1);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
checkPoint = { x: midX.plus(10).toNumber(), y: midY.toNumber() }
|
||||||
|
if (wall.inPolygon(checkPoint)) {
|
||||||
|
if (value.s === 1) {
|
||||||
|
console.log('3value:::', value.s)
|
||||||
|
if (UP_DOWN_REF.UP_RADIO_REF.current) UP_DOWN_REF.UP_RADIO_REF.current.checked = false
|
||||||
|
if (UP_DOWN_REF.DOWN_RADIO_REF.current) UP_DOWN_REF.DOWN_RADIO_REF.current.checked = true
|
||||||
|
} else {
|
||||||
|
if (UP_DOWN_REF.UP_RADIO_REF.current) UP_DOWN_REF.UP_RADIO_REF.current.checked = true
|
||||||
|
if (UP_DOWN_REF.DOWN_RADIO_REF.current) UP_DOWN_REF.DOWN_RADIO_REF.current.checked = false
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (value.s === -1) {
|
||||||
|
console.log('-1value:::', value.s)
|
||||||
|
if (UP_DOWN_REF.UP_RADIO_REF.current) UP_DOWN_REF.UP_RADIO_REF.current.checked = false
|
||||||
|
if (UP_DOWN_REF.DOWN_RADIO_REF.current) UP_DOWN_REF.DOWN_RADIO_REF.current.checked = true
|
||||||
|
} else {
|
||||||
|
if (UP_DOWN_REF.UP_RADIO_REF.current) UP_DOWN_REF.UP_RADIO_REF.current.checked = true
|
||||||
|
if (UP_DOWN_REF.DOWN_RADIO_REF.current) UP_DOWN_REF.DOWN_RADIO_REF.current.checked = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const mouseDownEvent = (e) => {
|
const mouseDownEvent = (e) => {
|
||||||
canvas
|
canvas
|
||||||
.getObjects()
|
.getObjects()
|
||||||
@ -279,6 +419,7 @@ export function useMovementSetting(id) {
|
|||||||
.forEach((obj) => canvas.remove(obj))
|
.forEach((obj) => canvas.remove(obj))
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
|
|
||||||
|
//const target = selectedObject.current
|
||||||
const target = selectedObject.current
|
const target = selectedObject.current
|
||||||
if (!target) return
|
if (!target) return
|
||||||
|
|
||||||
@ -313,14 +454,37 @@ export function useMovementSetting(id) {
|
|||||||
FOLLOW_LINE_REF.current = null
|
FOLLOW_LINE_REF.current = null
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
}
|
}
|
||||||
|
if (UP_DOWN_REF.current !== null) {
|
||||||
|
canvas.remove(UP_DOWN_REF.current)
|
||||||
|
UP_DOWN_REF.current = null
|
||||||
|
canvas.renderAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const target = selectedObject.current !== null ? selectedObject.current : CONFIRM_LINE_REF.current?.target
|
const target = selectedObject.current !== null ? selectedObject.current : CONFIRM_LINE_REF.current?.target
|
||||||
if (!target) return
|
if (!target) return
|
||||||
|
|
||||||
const roofId = target.attributes.roofId
|
const roofId = target.attributes.roofId
|
||||||
const roof = canvas.getObjects().find((obj) => obj.id === roofId)
|
const roof = canvas.getObjects().find((obj) => obj.id === roofId)
|
||||||
|
|
||||||
|
// 현이동, 동이동 추가
|
||||||
|
let flPointValue = FLOW_LINE_REF.POINTER_INPUT_REF.current?.value ?? 0;
|
||||||
|
let flFilledValue = FLOW_LINE_REF.FILLED_INPUT_REF.current?.value ?? 0;
|
||||||
|
flPointValue = (flFilledValue > 0 || flFilledValue < 0) ? flFilledValue : flPointValue;
|
||||||
|
const moveFlowLine = typeRef.current === TYPE.FLOW_LINE ? flPointValue : 0
|
||||||
|
|
||||||
|
let udPointValue = UP_DOWN_REF.POINTER_INPUT_REF.current?.value ?? 0;
|
||||||
|
let udFilledValue = UP_DOWN_REF.FILLED_INPUT_REF.current?.value ?? 0;
|
||||||
|
udPointValue = udFilledValue > 0 ? udFilledValue : udPointValue;
|
||||||
|
const moveUpDown = typeRef.current === TYPE.UP_DOWN ? udPointValue : 0
|
||||||
|
roof.moveFlowLine = parseInt(moveFlowLine, 10) || 0;
|
||||||
|
roof.moveUpDown = parseInt(moveUpDown, 10) || 0;
|
||||||
|
roof.moveDirect = "";
|
||||||
|
roof.moveSelectLine = target
|
||||||
|
//console.log("target::::", target, roof.moveSelectLine)
|
||||||
const wall = canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.WALL && obj.attributes.roofId === roofId)
|
const wall = canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.WALL && obj.attributes.roofId === roofId)
|
||||||
const baseLines = wall.baseLines
|
const baseLines = wall.baseLines
|
||||||
|
let centerPoint = wall.getCenterPoint();
|
||||||
let targetBaseLines = []
|
let targetBaseLines = []
|
||||||
let isGableRoof
|
let isGableRoof
|
||||||
if (typeRef.current === TYPE.FLOW_LINE) {
|
if (typeRef.current === TYPE.FLOW_LINE) {
|
||||||
@ -340,7 +504,7 @@ export function useMovementSetting(id) {
|
|||||||
isGableRoof = false
|
isGableRoof = false
|
||||||
}
|
}
|
||||||
const lineVector =
|
const lineVector =
|
||||||
target.y1 === target.y2
|
Math.abs(target.y1 - target.y2) < 0.2
|
||||||
? FLOW_LINE_REF.UP_RIGHT_RADIO_REF.current.checked
|
? FLOW_LINE_REF.UP_RIGHT_RADIO_REF.current.checked
|
||||||
? 'up'
|
? 'up'
|
||||||
: 'down'
|
: 'down'
|
||||||
@ -348,6 +512,7 @@ export function useMovementSetting(id) {
|
|||||||
? 'right'
|
? 'right'
|
||||||
: 'left'
|
: 'left'
|
||||||
let checkBaseLines, currentBaseLines
|
let checkBaseLines, currentBaseLines
|
||||||
|
roof.moveDirect = lineVector
|
||||||
switch (lineVector) {
|
switch (lineVector) {
|
||||||
case 'up':
|
case 'up':
|
||||||
checkBaseLines = baseLines.filter((line) => line.y1 === line.y2 && line.y1 < target.y1)
|
checkBaseLines = baseLines.filter((line) => line.y1 === line.y2 && line.y1 < target.y1)
|
||||||
@ -406,10 +571,23 @@ export function useMovementSetting(id) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
roof.moveDirect = UP_DOWN_REF.UP_RADIO_REF.current.checked ? 'out' : UP_DOWN_REF.DOWN_RADIO_REF.current.checked ? 'in' : 'out'
|
||||||
targetBaseLines.push({ line: target, distance: 0 })
|
targetBaseLines.push({ line: target, distance: 0 })
|
||||||
}
|
}
|
||||||
|
|
||||||
targetBaseLines.sort((a, b) => a.distance - b.distance)
|
// Remove duplicate lines
|
||||||
|
const uniqueLines = new Map();
|
||||||
|
targetBaseLines = targetBaseLines.filter(item => {
|
||||||
|
const key = `${item.line.x1},${item.line.y1},${item.line.x2},${item.line.y2}`;
|
||||||
|
if (!uniqueLines.has(key)) {
|
||||||
|
uniqueLines.set(key, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Sort by distance
|
||||||
|
targetBaseLines.sort((a, b) => a.distance - b.distance);
|
||||||
targetBaseLines = targetBaseLines.filter((line) => line.distance === targetBaseLines[0].distance)
|
targetBaseLines = targetBaseLines.filter((line) => line.distance === targetBaseLines[0].distance)
|
||||||
|
|
||||||
if (isGableRoof) {
|
if (isGableRoof) {
|
||||||
@ -442,18 +620,28 @@ export function useMovementSetting(id) {
|
|||||||
|
|
||||||
let value
|
let value
|
||||||
if (typeRef.current === TYPE.FLOW_LINE) {
|
if (typeRef.current === TYPE.FLOW_LINE) {
|
||||||
value =
|
value = (() => {
|
||||||
FLOW_LINE_REF.FILLED_INPUT_REF.current.value !== ''
|
const filledValue = FLOW_LINE_REF.FILLED_INPUT_REF.current?.value;
|
||||||
? Big(FLOW_LINE_REF.FILLED_INPUT_REF.current.value).times(2)
|
const pointerValue = FLOW_LINE_REF.POINTER_INPUT_REF.current?.value;
|
||||||
: Big(FLOW_LINE_REF.POINTER_INPUT_REF.current.value).times(2)
|
|
||||||
|
if (filledValue && !isNaN(filledValue) && filledValue.trim() !== '') {
|
||||||
|
return Big(filledValue).times(2);
|
||||||
|
} else if (pointerValue && !isNaN(pointerValue) && pointerValue.trim() !== '') {
|
||||||
|
return Big(pointerValue).times(2);
|
||||||
|
}
|
||||||
|
return Big(0); // 기본값으로 0 반환 또는 다른 적절한 기본값
|
||||||
|
})();
|
||||||
if (target.y1 === target.y2) {
|
if (target.y1 === target.y2) {
|
||||||
value = value.neg()
|
value = value.neg()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
value =
|
console.log("error::", UP_DOWN_REF.POINTER_INPUT_REF.current.value)
|
||||||
UP_DOWN_REF.FILLED_INPUT_REF.current.value !== ''
|
value = Big(
|
||||||
? Big(UP_DOWN_REF.FILLED_INPUT_REF.current.value)
|
(UP_DOWN_REF?.FILLED_INPUT_REF?.current?.value?.trim() ||
|
||||||
: Big(UP_DOWN_REF.POINTER_INPUT_REF.current.value)
|
UP_DOWN_REF?.POINTER_INPUT_REF?.current?.value?.trim() ||
|
||||||
|
'0'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
const midX = Big(target.x1).plus(target.x2).div(2)
|
const midX = Big(target.x1).plus(target.x2).div(2)
|
||||||
const midY = Big(target.y1).plus(target.y2).div(2)
|
const midY = Big(target.y1).plus(target.y2).div(2)
|
||||||
@ -467,17 +655,50 @@ export function useMovementSetting(id) {
|
|||||||
|
|
||||||
const inPolygon = wall.inPolygon(checkPoint)
|
const inPolygon = wall.inPolygon(checkPoint)
|
||||||
|
|
||||||
if (UP_DOWN_REF.UP_RADIO_REF.current.checked && inPolygon) {
|
// if (UP_DOWN_REF.UP_RADIO_REF.current.checked && inPolygon) {
|
||||||
value = value.neg()
|
// value = value.neg()
|
||||||
} else if (UP_DOWN_REF.DOWN_RADIO_REF.current.checked && !inPolygon) {
|
// } else if (UP_DOWN_REF.DOWN_RADIO_REF.current.checked && !inPolygon) {
|
||||||
value = value.neg()
|
// value = value.neg()
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
// console.log("2222titarget:::::", target);
|
||||||
|
// console.log("2222저장된 moveSelectLine:", roof.moveSelectLine);
|
||||||
|
// console.log("222wall::::", wall.points)
|
||||||
|
const result = getSelectLinePosition(wall, target, {
|
||||||
|
testDistance: 5, // 테스트 거리
|
||||||
|
debug: true // 디버깅 로그 출력
|
||||||
|
});
|
||||||
|
|
||||||
|
//console.log("2222linePosition:::::", result.position);
|
||||||
|
//console.log("222moveDirect:::::", roof.moveDirect);
|
||||||
|
|
||||||
|
|
||||||
|
// 디버깅용 분류 결과 확인
|
||||||
|
|
||||||
|
let linePosition = result.position;
|
||||||
|
roof.movePosition = linePosition
|
||||||
value = value.div(10)
|
value = value.div(10)
|
||||||
targetBaseLines
|
targetBaseLines
|
||||||
.filter((line) => Math.sqrt(Math.pow(line.line.x2 - line.line.x1, 2) + Math.pow(line.line.y2 - line.line.y1, 2)) >= 1)
|
.filter((line) => Math.sqrt(Math.pow(line.line.x2 - line.line.x1, 2) + Math.pow(line.line.y2 - line.line.y1, 2)) >= 1)
|
||||||
.forEach((target) => {
|
.forEach((target) => {
|
||||||
const currentLine = target.line
|
const currentLine = target.line
|
||||||
|
|
||||||
|
//console.log("linePosition::::::::::::::", linePosition)
|
||||||
|
if (UP_DOWN_REF?.DOWN_RADIO_REF?.current?.checked ){
|
||||||
|
//position확인
|
||||||
|
if(linePosition === 'bottom' || linePosition === 'right') {
|
||||||
|
//console.log("1value::::::::::::::", value.toString())
|
||||||
|
value = value.neg()
|
||||||
|
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
if(linePosition === 'top' || linePosition === 'left') {
|
||||||
|
//console.log("1value::::::::::::::", value.toString())
|
||||||
|
value = value.neg()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//console.log("2value::::::::::::::", value.toString())
|
||||||
const index = baseLines.findIndex((line) => line === currentLine)
|
const index = baseLines.findIndex((line) => line === currentLine)
|
||||||
const nextLine = baseLines[(index + 1) % baseLines.length]
|
const nextLine = baseLines[(index + 1) % baseLines.length]
|
||||||
const prevLine = baseLines[(index - 1 + baseLines.length) % baseLines.length]
|
const prevLine = baseLines[(index - 1 + baseLines.length) % baseLines.length]
|
||||||
@ -530,6 +751,9 @@ export function useMovementSetting(id) {
|
|||||||
closePopup(id)
|
closePopup(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// javascript
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
TYPE,
|
TYPE,
|
||||||
closePopup,
|
closePopup,
|
||||||
@ -541,3 +765,4 @@ export function useMovementSetting(id) {
|
|||||||
handleSave,
|
handleSave,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -252,6 +252,7 @@ export function useOuterLineWall(id, propertiesId) {
|
|||||||
canvas?.renderAll()
|
canvas?.renderAll()
|
||||||
setOuterLineFix(true)
|
setOuterLineFix(true)
|
||||||
closePopup(id)
|
closePopup(id)
|
||||||
|
ccwCheck()
|
||||||
addPopup(propertiesId, 1, <RoofShapeSetting id={propertiesId} pos={{ x: 50, y: 230 }} />)
|
addPopup(propertiesId, 1, <RoofShapeSetting id={propertiesId} pos={{ x: 50, y: 230 }} />)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -905,6 +906,51 @@ export function useOuterLineWall(id, propertiesId) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 시계방향으로 그려진 경우 반시게방향으로 변경
|
||||||
|
const ccwCheck = () => {
|
||||||
|
let outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||||
|
|
||||||
|
if (outerLines.length < 2) {
|
||||||
|
swalFire({ text: getMessage('wall.line.not.found') })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 외벽선이 시계방향인지 시계반대 방향인지 확인
|
||||||
|
*/
|
||||||
|
const outerLinePoints = outerLines.map((line) => ({ x: line.x1, y: line.y1 }))
|
||||||
|
let counterClockwise = true
|
||||||
|
let signedArea = 0
|
||||||
|
|
||||||
|
outerLinePoints.forEach((point, index) => {
|
||||||
|
const nextPoint = outerLinePoints[(index + 1) % outerLinePoints.length]
|
||||||
|
signedArea += point.x * nextPoint.y - point.y * nextPoint.x
|
||||||
|
})
|
||||||
|
|
||||||
|
if (signedArea > 0) {
|
||||||
|
counterClockwise = false
|
||||||
|
}
|
||||||
|
/** 시계 방향일 경우 외벽선 reverse*/
|
||||||
|
if (!counterClockwise) {
|
||||||
|
outerLines.reverse().forEach((line, index) => {
|
||||||
|
addLine([line.x2, line.y2, line.x1, line.y1], {
|
||||||
|
stroke: line.stroke,
|
||||||
|
strokeWidth: line.strokeWidth,
|
||||||
|
idx: index,
|
||||||
|
selectable: line.selectable,
|
||||||
|
name: 'outerLine',
|
||||||
|
x1: line.x2,
|
||||||
|
y1: line.y2,
|
||||||
|
x2: line.x1,
|
||||||
|
y2: line.y1,
|
||||||
|
visible: line.visible,
|
||||||
|
})
|
||||||
|
canvas.remove(line)
|
||||||
|
})
|
||||||
|
canvas.renderAll()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
points,
|
points,
|
||||||
setPoints,
|
setPoints,
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import {
|
|||||||
basicSettingState,
|
basicSettingState,
|
||||||
correntObjectNoState,
|
correntObjectNoState,
|
||||||
corridorDimensionSelector,
|
corridorDimensionSelector,
|
||||||
|
outlineDisplaySelector,
|
||||||
roofDisplaySelector,
|
roofDisplaySelector,
|
||||||
roofMaterialsSelector,
|
roofMaterialsSelector,
|
||||||
selectedRoofMaterialSelector,
|
selectedRoofMaterialSelector,
|
||||||
@ -29,6 +30,8 @@ import { QcastContext } from '@/app/QcastProvider'
|
|||||||
import { usePlan } from '@/hooks/usePlan'
|
import { usePlan } from '@/hooks/usePlan'
|
||||||
import { roofsState } from '@/store/roofAtom'
|
import { roofsState } from '@/store/roofAtom'
|
||||||
import { useText } from '@/hooks/useText'
|
import { useText } from '@/hooks/useText'
|
||||||
|
import { processEaveHelpLines } from '@/util/skeleton-utils'
|
||||||
|
import { QLine } from '@/components/fabric/QLine'
|
||||||
|
|
||||||
export function useRoofAllocationSetting(id) {
|
export function useRoofAllocationSetting(id) {
|
||||||
const canvas = useRecoilValue(canvasState)
|
const canvas = useRecoilValue(canvasState)
|
||||||
@ -59,9 +62,11 @@ export function useRoofAllocationSetting(id) {
|
|||||||
const { saveCanvas } = usePlan()
|
const { saveCanvas } = usePlan()
|
||||||
const [roofsStore, setRoofsStore] = useRecoilState(roofsState)
|
const [roofsStore, setRoofsStore] = useRecoilState(roofsState)
|
||||||
const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState)
|
const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState)
|
||||||
|
const outerLinePoints = useRecoilValue(outerLinePointsState)
|
||||||
const resetPoints = useResetRecoilState(outerLinePointsState)
|
const resetPoints = useResetRecoilState(outerLinePointsState)
|
||||||
const [corridorDimension, setCorridorDimension] = useRecoilState(corridorDimensionSelector)
|
const [corridorDimension, setCorridorDimension] = useRecoilState(corridorDimensionSelector)
|
||||||
const { changeCorridorDimensionText } = useText()
|
const { changeCorridorDimensionText } = useText()
|
||||||
|
const outlineDisplay = useRecoilValue(outlineDisplaySelector)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
/** 배치면 초기설정에서 선택한 지붕재 배열 설정 */
|
/** 배치면 초기설정에서 선택한 지붕재 배열 설정 */
|
||||||
@ -109,46 +114,54 @@ export function useRoofAllocationSetting(id) {
|
|||||||
*/
|
*/
|
||||||
const fetchBasicSettings = async (planNo) => {
|
const fetchBasicSettings = async (planNo) => {
|
||||||
try {
|
try {
|
||||||
await get({ url: `/api/canvas-management/canvas-basic-settings/by-object/${correntObjectNo}/${planNo}` }).then((res) => {
|
const response = await get({ url: `/api/canvas-management/canvas-basic-settings/by-object/${correntObjectNo}/${planNo}` });
|
||||||
let roofsArray = {}
|
|
||||||
|
let roofsArray = [];
|
||||||
if (res.length > 0) {
|
|
||||||
roofsArray = res.map((item) => {
|
// API에서 데이터를 성공적으로 가져온 경우
|
||||||
return {
|
if (response && response.length > 0) {
|
||||||
planNo: item.planNo,
|
roofsArray = response.map((item, index) => ({
|
||||||
roofApply: item.roofApply,
|
planNo: item.planNo,
|
||||||
roofSeq: item.roofSeq,
|
roofApply: item.roofApply,
|
||||||
roofMatlCd: item.roofMatlCd,
|
roofSeq: item.roofSeq || index,
|
||||||
roofWidth: item.roofWidth,
|
roofMatlCd: item.roofMatlCd,
|
||||||
roofHeight: item.roofHeight,
|
roofWidth: item.roofWidth,
|
||||||
roofHajebichi: item.roofHajebichi,
|
roofHeight: item.roofHeight,
|
||||||
roofGap: item.roofGap,
|
roofHajebichi: item.roofHajebichi,
|
||||||
roofLayout: item.roofLayout,
|
roofGap: item.roofGap,
|
||||||
roofPitch: item.roofPitch,
|
roofLayout: item.roofLayout,
|
||||||
roofAngle: item.roofAngle,
|
roofPitch: item.roofPitch,
|
||||||
}
|
roofAngle: item.roofAngle,
|
||||||
})
|
selected: index === 0, // 첫 번째 항목을 기본 선택으로 설정
|
||||||
} else {
|
index: index
|
||||||
if (roofList.length > 0) {
|
}));
|
||||||
roofsArray = roofList
|
}
|
||||||
} else {
|
// API에서 데이터가 없고 기존 roofList가 있는 경우
|
||||||
roofsArray = [
|
else if (roofList && roofList.length > 0) {
|
||||||
{
|
roofsArray = roofList.map((roof, index) => ({
|
||||||
planNo: planNo,
|
...roof,
|
||||||
roofApply: true,
|
selected: index === 0 // 첫 번째 항목을 기본 선택으로 설정
|
||||||
roofSeq: 0,
|
}));
|
||||||
roofMatlCd: 'ROOF_ID_WA_53A',
|
}
|
||||||
roofWidth: 265,
|
// 둘 다 없는 경우 기본값 설정
|
||||||
roofHeight: 235,
|
else {
|
||||||
roofHajebichi: 0,
|
roofsArray = [
|
||||||
roofGap: 'HEI_455',
|
{
|
||||||
roofLayout: 'P',
|
planNo: planNo,
|
||||||
|
roofApply: true,
|
||||||
|
roofSeq: 0,
|
||||||
|
roofMatlCd: 'ROOF_ID_WA_53A',
|
||||||
|
roofWidth: 265,
|
||||||
|
roofHeight: 235,
|
||||||
|
roofHajebichi: 0,
|
||||||
|
roofGap: 'HEI_455',
|
||||||
|
roofLayout: 'P',
|
||||||
roofPitch: 4,
|
roofPitch: 4,
|
||||||
roofAngle: 21.8,
|
roofAngle: 21.8,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 데이터 설정
|
* 데이터 설정
|
||||||
@ -200,7 +213,7 @@ export function useRoofAllocationSetting(id) {
|
|||||||
angle: roof.angle ?? '',
|
angle: roof.angle ?? '',
|
||||||
}))
|
}))
|
||||||
setCurrentRoofList(normalizedRoofs)
|
setCurrentRoofList(normalizedRoofs)
|
||||||
})
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Data fetching error:', error)
|
console.error('Data fetching error:', error)
|
||||||
}
|
}
|
||||||
@ -303,11 +316,53 @@ export function useRoofAllocationSetting(id) {
|
|||||||
addPopup(popupId, 1, <ActualSizeSetting id={popupId} />)
|
addPopup(popupId, 1, <ActualSizeSetting id={popupId} />)
|
||||||
} else {
|
} else {
|
||||||
apply()
|
apply()
|
||||||
|
//기존 지붕 선은 남겨둔다.
|
||||||
|
drawOriginRoofLine()
|
||||||
resetPoints()
|
resetPoints()
|
||||||
|
|
||||||
basicSettingSave()
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 지붕재 오른쪽 마우스 클릭 후 단일로 지붕재 변경 필요한 경우
|
* 지붕재 오른쪽 마우스 클릭 후 단일로 지붕재 변경 필요한 경우
|
||||||
*/
|
*/
|
||||||
@ -327,11 +382,18 @@ export function useRoofAllocationSetting(id) {
|
|||||||
setBasicSetting((prev) => {
|
setBasicSetting((prev) => {
|
||||||
return { ...prev, selectedRoofMaterial: newRoofList.find((roof) => roof.selected) }
|
return { ...prev, selectedRoofMaterial: newRoofList.find((roof) => roof.selected) }
|
||||||
})
|
})
|
||||||
|
const selectedRoofMaterial = newRoofList.find((roof) => roof.selected)
|
||||||
|
const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF && obj.roofMaterial?.index === selectedRoofMaterial.index)
|
||||||
|
|
||||||
|
roofs.forEach((roof) => {
|
||||||
|
setSurfaceShapePattern(roof, roofDisplay.column, false, { ...selectedRoofMaterial }, true)
|
||||||
|
drawDirectionArrow(roof)
|
||||||
|
})
|
||||||
|
|
||||||
setRoofList(newRoofList)
|
setRoofList(newRoofList)
|
||||||
setRoofMaterials(newRoofList)
|
setRoofMaterials(newRoofList)
|
||||||
setRoofsStore(newRoofList)
|
setRoofsStore(newRoofList)
|
||||||
const selectedRoofMaterial = newRoofList.find((roof) => roof.selected)
|
|
||||||
setSurfaceShapePattern(currentObject, roofDisplay.column, false, selectedRoofMaterial, true)
|
setSurfaceShapePattern(currentObject, roofDisplay.column, false, selectedRoofMaterial, true)
|
||||||
drawDirectionArrow(currentObject)
|
drawDirectionArrow(currentObject)
|
||||||
modifyModuleSelectionData()
|
modifyModuleSelectionData()
|
||||||
@ -404,6 +466,22 @@ export function useRoofAllocationSetting(id) {
|
|||||||
const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
||||||
roofBases.forEach((roofBase) => {
|
roofBases.forEach((roofBase) => {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
const roofEaveHelpLines = canvas.getObjects().filter((obj) => obj.lineName === 'eaveHelpLine' && obj.roofId === roofBase.id)
|
||||||
|
if (roofEaveHelpLines.length > 0) {
|
||||||
|
if (roofBase.lines) {
|
||||||
|
// Filter out any eaveHelpLines that are already in lines to avoid duplicates
|
||||||
|
const existingEaveLineIds = new Set(roofBase.lines.map((line) => line.id))
|
||||||
|
const newEaveLines = roofEaveHelpLines.filter((line) => !existingEaveLineIds.has(line.id))
|
||||||
|
roofBase.lines = [...newEaveLines]
|
||||||
|
} else {
|
||||||
|
roofBase.lines = [...roofEaveHelpLines]
|
||||||
|
}
|
||||||
|
if (!roofBase.innerLines) {
|
||||||
|
roofBase.innerLines = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (roofBase.separatePolygon.length > 0) {
|
if (roofBase.separatePolygon.length > 0) {
|
||||||
splitPolygonWithSeparate(roofBase.separatePolygon)
|
splitPolygonWithSeparate(roofBase.separatePolygon)
|
||||||
} else {
|
} else {
|
||||||
@ -569,7 +647,7 @@ export function useRoofAllocationSetting(id) {
|
|||||||
* 피치 변경
|
* 피치 변경
|
||||||
*/
|
*/
|
||||||
const handleChangePitch = (e, index) => {
|
const handleChangePitch = (e, index) => {
|
||||||
let value = e.target.value
|
let value = e //e.target.value
|
||||||
|
|
||||||
const reg = /^[0-9]+(\.[0-9]{0,1})?$/
|
const reg = /^[0-9]+(\.[0-9]{0,1})?$/
|
||||||
if (!reg.test(value)) {
|
if (!reg.test(value)) {
|
||||||
|
|||||||
@ -179,46 +179,6 @@ export function useRoofShapeSetting(id) {
|
|||||||
let outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
let outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||||
let direction
|
let direction
|
||||||
|
|
||||||
if (outerLines.length < 2) {
|
|
||||||
swalFire({ text: getMessage('wall.line.not.found') })
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 외벽선이 시계방향인지 시계반대 방향인지 확인
|
|
||||||
*/
|
|
||||||
const outerLinePoints = outerLines.map((line) => ({ x: line.x1, y: line.y1 }))
|
|
||||||
let counterClockwise = true
|
|
||||||
let signedArea = 0
|
|
||||||
|
|
||||||
outerLinePoints.forEach((point, index) => {
|
|
||||||
const nextPoint = outerLinePoints[(index + 1) % outerLinePoints.length]
|
|
||||||
signedArea += point.x * nextPoint.y - point.y * nextPoint.x
|
|
||||||
})
|
|
||||||
|
|
||||||
if (signedArea > 0) {
|
|
||||||
counterClockwise = false
|
|
||||||
}
|
|
||||||
/** 시계 방향일 경우 외벽선 reverse*/
|
|
||||||
if (!counterClockwise) {
|
|
||||||
outerLines.reverse().forEach((line, index) => {
|
|
||||||
addLine([line.x2, line.y2, line.x1, line.y1], {
|
|
||||||
stroke: line.stroke,
|
|
||||||
strokeWidth: line.strokeWidth,
|
|
||||||
idx: index,
|
|
||||||
selectable: line.selectable,
|
|
||||||
name: 'outerLine',
|
|
||||||
x1: line.x2,
|
|
||||||
y1: line.y2,
|
|
||||||
x2: line.x1,
|
|
||||||
y2: line.y1,
|
|
||||||
visible: line.visible,
|
|
||||||
})
|
|
||||||
canvas.remove(line)
|
|
||||||
})
|
|
||||||
canvas.renderAll()
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([1, 2, 3, 5, 6, 7, 8].includes(shapeNum)) {
|
if ([1, 2, 3, 5, 6, 7, 8].includes(shapeNum)) {
|
||||||
// 변별로 설정이 아닌 경우 경사를 지붕재에 적용해주어야함
|
// 변별로 설정이 아닌 경우 경사를 지붕재에 적용해주어야함
|
||||||
setRoofPitch()
|
setRoofPitch()
|
||||||
@ -507,7 +467,7 @@ export function useRoofShapeSetting(id) {
|
|||||||
originX: 'center',
|
originX: 'center',
|
||||||
originY: 'center',
|
originY: 'center',
|
||||||
})
|
})
|
||||||
polygon.setViewLengthText(false)
|
// polygon.setViewLengthText(false)
|
||||||
polygon.lines = [...outerLines]
|
polygon.lines = [...outerLines]
|
||||||
|
|
||||||
addPitchTextsByOuterLines()
|
addPitchTextsByOuterLines()
|
||||||
|
|||||||
@ -1,7 +1,13 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useRecoilValue, useResetRecoilState } from 'recoil'
|
import { useRecoilValue, useResetRecoilState } from 'recoil'
|
||||||
import { canvasSettingState, canvasState, currentCanvasPlanState, currentObjectState, globalPitchState } from '@/store/canvasAtom'
|
import {
|
||||||
|
canvasSettingState,
|
||||||
|
canvasState,
|
||||||
|
currentCanvasPlanState,
|
||||||
|
currentObjectState,
|
||||||
|
globalPitchState,
|
||||||
|
} from '@/store/canvasAtom'
|
||||||
import { LINE_TYPE, MENU, POLYGON_TYPE } from '@/common/common'
|
import { LINE_TYPE, MENU, POLYGON_TYPE } from '@/common/common'
|
||||||
import { getIntersectionPoint } from '@/util/canvas-util'
|
import { getIntersectionPoint } from '@/util/canvas-util'
|
||||||
import { degreesToRadians } from '@turf/turf'
|
import { degreesToRadians } from '@turf/turf'
|
||||||
@ -879,7 +885,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// roof.fire('polygonMoved')
|
roof.fire('polygonMoved')
|
||||||
roof.fire('modified')
|
roof.fire('modified')
|
||||||
drawDirectionArrow(roof)
|
drawDirectionArrow(roof)
|
||||||
changeCorridorDimensionText()
|
changeCorridorDimensionText()
|
||||||
@ -1451,6 +1457,50 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
|
|||||||
// 그룹화할 객체들 배열 (currentObject + relatedObjects)
|
// 그룹화할 객체들 배열 (currentObject + relatedObjects)
|
||||||
const objectsToGroup = [currentObject, ...relatedObjects]
|
const objectsToGroup = [currentObject, ...relatedObjects]
|
||||||
|
|
||||||
|
// 회전 카운트 초기화 및 최초 상태 저장
|
||||||
|
if (!currentObject.rotationCount) {
|
||||||
|
currentObject.rotationCount = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// 최초 회전일 때 (rotationCount === 0) 원본 상태 저장
|
||||||
|
if (currentObject.rotationCount === 0) {
|
||||||
|
objectsToGroup.forEach((obj) => {
|
||||||
|
if (!obj.originalState) {
|
||||||
|
obj.originalState = {
|
||||||
|
left: obj.left,
|
||||||
|
top: obj.top,
|
||||||
|
angle: obj.angle || 0,
|
||||||
|
points: obj.type === 'QPolygon' ? JSON.parse(JSON.stringify(obj.points)) : null,
|
||||||
|
scaleX: obj.scaleX || 1,
|
||||||
|
scaleY: obj.scaleY || 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 회전 카운트 증가 (먼저 증가시켜서 목표 각도 계산)
|
||||||
|
currentObject.rotationCount = (currentObject.rotationCount + 1) % 4
|
||||||
|
|
||||||
|
// 목표 회전 각도 계산 (원본 기준)
|
||||||
|
const targetAngle = currentObject.rotationCount * 90
|
||||||
|
|
||||||
|
// 원본 상태로 먼저 복원한 후 목표 각도만큼 회전
|
||||||
|
objectsToGroup.forEach((obj) => {
|
||||||
|
if (obj.originalState) {
|
||||||
|
// 원본 상태로 복원
|
||||||
|
obj.set({
|
||||||
|
left: obj.originalState.left,
|
||||||
|
top: obj.originalState.top,
|
||||||
|
angle: obj.originalState.angle,
|
||||||
|
scaleX: obj.originalState.scaleX,
|
||||||
|
scaleY: obj.originalState.scaleY,
|
||||||
|
})
|
||||||
|
if (obj.originalState.points && obj.type === 'QPolygon') {
|
||||||
|
obj.set({ points: JSON.parse(JSON.stringify(obj.originalState.points)) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// 기존 객체들을 캔버스에서 제거
|
// 기존 객체들을 캔버스에서 제거
|
||||||
objectsToGroup.forEach((obj) => canvas.remove(obj))
|
objectsToGroup.forEach((obj) => canvas.remove(obj))
|
||||||
|
|
||||||
@ -1463,12 +1513,8 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) {
|
|||||||
// 그룹을 캔버스에 추가
|
// 그룹을 캔버스에 추가
|
||||||
canvas.add(group)
|
canvas.add(group)
|
||||||
|
|
||||||
// 현재 회전값에 90도 추가
|
// 목표 각도로 회전 (원본 기준)
|
||||||
const currentAngle = group.angle || 0
|
group.rotate(targetAngle)
|
||||||
const newAngle = (currentAngle + 90) % 360
|
|
||||||
|
|
||||||
// 그룹 전체를 회전
|
|
||||||
group.rotate(newAngle)
|
|
||||||
group.setCoords()
|
group.setCoords()
|
||||||
|
|
||||||
// 그룹을 해제하고 개별 객체로 복원
|
// 그룹을 해제하고 개별 객체로 복원
|
||||||
|
|||||||
@ -402,7 +402,8 @@ export function useCanvasEvent() {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
zoom = canvasZoom - 10
|
zoom = canvasZoom - 10
|
||||||
if (zoom < 10) { //50%->10%
|
if (zoom < 10) {
|
||||||
|
//50%->10%
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -412,8 +413,33 @@ export function useCanvasEvent() {
|
|||||||
|
|
||||||
const handleZoomClear = () => {
|
const handleZoomClear = () => {
|
||||||
setCanvasZoom(100)
|
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()
|
canvas.renderAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -42,7 +42,18 @@ export function useCircuitTrestle(executeEffect = false) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// PCS 아이템 목록
|
// 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 models.map((model) => {
|
||||||
return {
|
return {
|
||||||
itemId: model.itemId,
|
itemId: model.itemId,
|
||||||
@ -53,7 +64,18 @@ export function useCircuitTrestle(executeEffect = false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 선택된 PCS 아이템 목록
|
// 선택된 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 selectedModels.map((model) => {
|
||||||
return {
|
return {
|
||||||
itemId: model.itemId,
|
itemId: model.itemId,
|
||||||
@ -95,6 +117,7 @@ export function useCircuitTrestle(executeEffect = false) {
|
|||||||
uniqueId: module.id ? module.id : null,
|
uniqueId: module.id ? module.id : null,
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
roofSurfaceNorthYn: obj.direction === 'north' ? 'Y' : 'N',
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter((surface) => surface.moduleList.length > 0)
|
.filter((surface) => surface.moduleList.length > 0)
|
||||||
|
|||||||
@ -123,7 +123,7 @@ export function useContextMenu() {
|
|||||||
}, [currentContextMenu])
|
}, [currentContextMenu])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log('currentObject', currentObject)
|
//console.log('currentObject', currentObject)
|
||||||
if (currentObject?.name) {
|
if (currentObject?.name) {
|
||||||
switch (currentObject.name) {
|
switch (currentObject.name) {
|
||||||
case 'triangleDormer':
|
case 'triangleDormer':
|
||||||
@ -162,6 +162,7 @@ export function useContextMenu() {
|
|||||||
case 'auxiliaryLine':
|
case 'auxiliaryLine':
|
||||||
case 'hip':
|
case 'hip':
|
||||||
case 'ridge':
|
case 'ridge':
|
||||||
|
case 'eaveHelpLine':
|
||||||
if (selectedMenu === 'surface') {
|
if (selectedMenu === 'surface') {
|
||||||
setContextMenu([
|
setContextMenu([
|
||||||
[
|
[
|
||||||
|
|||||||
@ -1809,6 +1809,7 @@ export function useMode() {
|
|||||||
const currentWall = line.currentWall
|
const currentWall = line.currentWall
|
||||||
const nextWall = line.nextWall
|
const nextWall = line.nextWall
|
||||||
const index = line.index + addPoint
|
const index = line.index + addPoint
|
||||||
|
const direction = currentWall.direction
|
||||||
const xDiff = Big(currentWall.x1).minus(Big(nextWall.x1))
|
const xDiff = Big(currentWall.x1).minus(Big(nextWall.x1))
|
||||||
const yDiff = Big(currentWall.y1).minus(Big(nextWall.y1))
|
const yDiff = Big(currentWall.y1).minus(Big(nextWall.y1))
|
||||||
const offsetCurrentPoint = offsetPolygon[index]
|
const offsetCurrentPoint = offsetPolygon[index]
|
||||||
@ -1820,7 +1821,11 @@ export function useMode() {
|
|||||||
x: xDiff.eq(0) ? offsetCurrentPoint.x : nextWall.x1,
|
x: xDiff.eq(0) ? offsetCurrentPoint.x : nextWall.x1,
|
||||||
y: yDiff.eq(0) ? offsetCurrentPoint.y : nextWall.y1,
|
y: yDiff.eq(0) ? offsetCurrentPoint.y : nextWall.y1,
|
||||||
}
|
}
|
||||||
const diffOffset = Big(nextWall.attributes.offset).minus(Big(currentWall.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 = {
|
const offsetPoint2 = {
|
||||||
x: yDiff.eq(0) ? offsetPoint1.x : Big(offsetPoint1.x).plus(diffOffset).toNumber(),
|
x: yDiff.eq(0) ? offsetPoint1.x : Big(offsetPoint1.x).plus(diffOffset).toNumber(),
|
||||||
y: xDiff.eq(0) ? offsetPoint1.y : Big(offsetPoint1.y).plus(diffOffset).toNumber(),
|
y: xDiff.eq(0) ? offsetPoint1.y : Big(offsetPoint1.y).plus(diffOffset).toNumber(),
|
||||||
|
|||||||
@ -845,6 +845,8 @@ export const usePolygon = () => {
|
|||||||
polygonLines.forEach((line) => {
|
polygonLines.forEach((line) => {
|
||||||
line.need = true
|
line.need = true
|
||||||
})
|
})
|
||||||
|
// 순서에 의존하지 않도록 모든 조합을 먼저 확인한 후 처리
|
||||||
|
const innerLineMapping = new Map() // innerLine -> polygonLine 매핑 저장
|
||||||
|
|
||||||
// innerLines와 polygonLines의 겹침을 확인하고 type 변경
|
// innerLines와 polygonLines의 겹침을 확인하고 type 변경
|
||||||
innerLines.forEach((innerLine) => {
|
innerLines.forEach((innerLine) => {
|
||||||
@ -854,14 +856,26 @@ export const usePolygon = () => {
|
|||||||
if (innerLine.attributes && polygonLine.attributes.type) {
|
if (innerLine.attributes && polygonLine.attributes.type) {
|
||||||
// innerLine이 polygonLine보다 긴 경우 polygonLine.need를 false로 변경
|
// innerLine이 polygonLine보다 긴 경우 polygonLine.need를 false로 변경
|
||||||
if (polygonLine.length < innerLine.length) {
|
if (polygonLine.length < innerLine.length) {
|
||||||
polygonLine.need = false
|
if (polygonLine.lineName !== 'eaveHelpLine') {
|
||||||
|
polygonLine.need = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
innerLine.attributes.planeSize = innerLine.attributes.planeSize ?? polygonLine.attributes.planeSize
|
// innerLine.attributes.planeSize = innerLine.attributes.planeSize ?? polygonLine.attributes.planeSize
|
||||||
innerLine.attributes.actualSize = innerLine.attributes.actualSize ?? polygonLine.attributes.actualSize
|
// innerLine.attributes.actualSize = innerLine.attributes.actualSize ?? polygonLine.attributes.actualSize
|
||||||
innerLine.attributes.type = polygonLine.attributes.type
|
// innerLine.attributes.type = polygonLine.attributes.type
|
||||||
innerLine.direction = polygonLine.direction
|
// innerLine.direction = polygonLine.direction
|
||||||
innerLine.attributes.isStart = true
|
// innerLine.attributes.isStart = true
|
||||||
innerLine.parentLine = polygonLine
|
// innerLine.parentLine = polygonLine
|
||||||
|
|
||||||
|
// 매핑된 innerLine의 attributes를 변경 (교차점 계산 전에 적용)
|
||||||
|
innerLineMapping.forEach((polygonLine, innerLine) => {
|
||||||
|
innerLine.attributes.planeSize = innerLine.attributes.planeSize ?? polygonLine.attributes.planeSize
|
||||||
|
innerLine.attributes.actualSize = innerLine.attributes.actualSize ?? polygonLine.attributes.actualSize
|
||||||
|
innerLine.attributes.type = polygonLine.attributes.type
|
||||||
|
innerLine.direction = polygonLine.direction
|
||||||
|
innerLine.attributes.isStart = true
|
||||||
|
innerLine.parentLine = polygonLine
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -1386,7 +1400,10 @@ export const usePolygon = () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (startFlag && endFlag) {
|
if (startFlag && endFlag) {
|
||||||
if (!representLines.includes(line) && line.attributes.type === LINE_TYPE.WALLLINE.EAVES) {
|
if (
|
||||||
|
!representLines.includes(line) &&
|
||||||
|
(line.attributes.type === LINE_TYPE.WALLLINE.EAVES || line.attributes.type === LINE_TYPE.WALLLINE.EAVE_HELP_LINE)
|
||||||
|
) {
|
||||||
representLines.push(line)
|
representLines.push(line)
|
||||||
} else if (!representLines.includes(line) && line.attributes.type === LINE_TYPE.WALLLINE.HIPANDGABLE) {
|
} else if (!representLines.includes(line) && line.attributes.type === LINE_TYPE.WALLLINE.HIPANDGABLE) {
|
||||||
representLines.push(line)
|
representLines.push(line)
|
||||||
@ -1567,50 +1584,125 @@ export const usePolygon = () => {
|
|||||||
|
|
||||||
// ==== Dijkstra pathfinding ====
|
// ==== Dijkstra pathfinding ====
|
||||||
|
|
||||||
|
// function findShortestPath(start, end, graph, epsilon = 1) {
|
||||||
|
// const startKey = pointToKey(start, epsilon)
|
||||||
|
// const endKey = pointToKey(end, epsilon)
|
||||||
|
//
|
||||||
|
// const distances = {}
|
||||||
|
// const previous = {}
|
||||||
|
// const visited = new Set()
|
||||||
|
// const queue = [{ key: startKey, dist: 0 }]
|
||||||
|
//
|
||||||
|
// for (const key in graph) distances[key] = Infinity
|
||||||
|
// distances[startKey] = 0
|
||||||
|
//
|
||||||
|
// while (queue.length > 0) {
|
||||||
|
// queue.sort((a, b) => a.dist - b.dist)
|
||||||
|
// const { key } = queue.shift()
|
||||||
|
// if (visited.has(key)) continue
|
||||||
|
// visited.add(key)
|
||||||
|
//
|
||||||
|
// for (const neighbor of graph[key] || []) {
|
||||||
|
// const neighborKey = pointToKey(neighbor.point, epsilon)
|
||||||
|
// const alt = distances[key] + neighbor.distance
|
||||||
|
// if (alt < distances[neighborKey]) {
|
||||||
|
// distances[neighborKey] = alt
|
||||||
|
// previous[neighborKey] = key
|
||||||
|
// queue.push({ key: neighborKey, dist: alt })
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// const path = []
|
||||||
|
// let currentKey = endKey
|
||||||
|
//
|
||||||
|
// if (!previous[currentKey]) return null
|
||||||
|
//
|
||||||
|
// while (currentKey !== startKey) {
|
||||||
|
// const [x, y] = currentKey.split(',').map(Number)
|
||||||
|
// path.unshift({ x, y })
|
||||||
|
// currentKey = previous[currentKey]
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// const [sx, sy] = startKey.split(',').map(Number)
|
||||||
|
// path.unshift({ x: sx, y: sy })
|
||||||
|
//
|
||||||
|
// return path
|
||||||
|
// }
|
||||||
|
|
||||||
function findShortestPath(start, end, graph, epsilon = 1) {
|
function findShortestPath(start, end, graph, epsilon = 1) {
|
||||||
const startKey = pointToKey(start, epsilon)
|
const startKey = pointToKey(start, epsilon)
|
||||||
const endKey = pointToKey(end, epsilon)
|
const endKey = pointToKey(end, epsilon)
|
||||||
|
|
||||||
const distances = {}
|
// 거리와 이전 노드 추적
|
||||||
|
const distances = { [startKey]: 0 }
|
||||||
const previous = {}
|
const previous = {}
|
||||||
const visited = new Set()
|
const visited = new Set()
|
||||||
|
|
||||||
|
// 우선순위 큐 (거리가 짧은 순으로 정렬)
|
||||||
const queue = [{ key: startKey, dist: 0 }]
|
const queue = [{ key: startKey, dist: 0 }]
|
||||||
|
|
||||||
for (const key in graph) distances[key] = Infinity
|
// 모든 노드 초기화
|
||||||
distances[startKey] = 0
|
for (const key in graph) {
|
||||||
|
if (key !== startKey) {
|
||||||
|
distances[key] = Infinity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while (queue.length > 0) {
|
// 우선순위 큐에서 다음 노드 선택
|
||||||
|
const getNextNode = () => {
|
||||||
|
if (queue.length === 0) return null
|
||||||
queue.sort((a, b) => a.dist - b.dist)
|
queue.sort((a, b) => a.dist - b.dist)
|
||||||
const { key } = queue.shift()
|
return queue.shift()
|
||||||
if (visited.has(key)) continue
|
}
|
||||||
visited.add(key)
|
|
||||||
|
|
||||||
for (const neighbor of graph[key] || []) {
|
let current
|
||||||
|
while ((current = getNextNode())) {
|
||||||
|
const currentKey = current.key
|
||||||
|
|
||||||
|
// 목적지에 도달하면 종료
|
||||||
|
if (currentKey === endKey) break
|
||||||
|
|
||||||
|
// 이미 방문한 노드는 건너뜀
|
||||||
|
if (visited.has(currentKey)) continue
|
||||||
|
visited.add(currentKey)
|
||||||
|
|
||||||
|
// 인접 노드 탐색
|
||||||
|
for (const neighbor of graph[currentKey] || []) {
|
||||||
const neighborKey = pointToKey(neighbor.point, epsilon)
|
const neighborKey = pointToKey(neighbor.point, epsilon)
|
||||||
const alt = distances[key] + neighbor.distance
|
if (visited.has(neighborKey)) continue
|
||||||
if (alt < distances[neighborKey]) {
|
|
||||||
|
const alt = distances[currentKey] + neighbor.distance
|
||||||
|
|
||||||
|
// 더 짧은 경로를 찾은 경우 업데이트
|
||||||
|
if (alt < (distances[neighborKey] || Infinity)) {
|
||||||
distances[neighborKey] = alt
|
distances[neighborKey] = alt
|
||||||
previous[neighborKey] = key
|
previous[neighborKey] = currentKey
|
||||||
|
|
||||||
|
// 우선순위 큐에 추가
|
||||||
queue.push({ key: neighborKey, dist: alt })
|
queue.push({ key: neighborKey, dist: alt })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 경로 재구성
|
||||||
const path = []
|
const path = []
|
||||||
let currentKey = endKey
|
let currentKey = endKey
|
||||||
|
|
||||||
if (!previous[currentKey]) return null
|
// 시작점에 도달할 때까지 역추적
|
||||||
|
while (previous[currentKey] !== undefined) {
|
||||||
while (currentKey !== startKey) {
|
|
||||||
const [x, y] = currentKey.split(',').map(Number)
|
const [x, y] = currentKey.split(',').map(Number)
|
||||||
path.unshift({ x, y })
|
path.unshift({ x, y })
|
||||||
currentKey = previous[currentKey]
|
currentKey = previous[currentKey]
|
||||||
}
|
}
|
||||||
|
|
||||||
const [sx, sy] = startKey.split(',').map(Number)
|
// 시작점 추가
|
||||||
path.unshift({ x: sx, y: sy })
|
if (path.length > 0) {
|
||||||
|
const [sx, sy] = startKey.split(',').map(Number)
|
||||||
|
path.unshift({ x: sx, y: sy })
|
||||||
|
}
|
||||||
|
|
||||||
return path
|
return path.length > 0 ? path : null
|
||||||
}
|
}
|
||||||
|
|
||||||
// 최종 함수
|
// 최종 함수
|
||||||
|
|||||||
@ -49,6 +49,7 @@ export async function setSession(data) {
|
|||||||
session.custCd = data.custCd
|
session.custCd = data.custCd
|
||||||
session.isLoggedIn = true
|
session.isLoggedIn = true
|
||||||
session.builderNo = data.builderNo
|
session.builderNo = data.builderNo
|
||||||
|
session.custNm = data.custNm
|
||||||
|
|
||||||
await session.save()
|
await session.save()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -614,7 +614,7 @@
|
|||||||
"qna.sub.title": "お問合せリスト",
|
"qna.sub.title": "お問合せリスト",
|
||||||
"qna.reg.header.regDt": "お問い合わせ登録日",
|
"qna.reg.header.regDt": "お問い合わせ登録日",
|
||||||
"qna.reg.header.regUserNm": "名前",
|
"qna.reg.header.regUserNm": "名前",
|
||||||
"qna.reg.header.regUserTelNo": "お問い合わせ",
|
"qna.reg.header.regUserTelNo": "電話番号",
|
||||||
"qna.reg.header.type": "お問い合わせ区分",
|
"qna.reg.header.type": "お問い合わせ区分",
|
||||||
"qna.reg.header.title": "お問い合わせタイトル",
|
"qna.reg.header.title": "お問い合わせタイトル",
|
||||||
"qna.reg.header.contents": "お問い合わせ内容",
|
"qna.reg.header.contents": "お問い合わせ内容",
|
||||||
@ -1089,6 +1089,7 @@
|
|||||||
"module.circuit.minimun.error": "回路番号は1以上の数値を入力してください。",
|
"module.circuit.minimun.error": "回路番号は1以上の数値を入力してください。",
|
||||||
"module.already.exist.error": "回路番号が同じで異なるパワーコンディショナのモジュールがあります。 別の回路番号を設定してください。",
|
"module.already.exist.error": "回路番号が同じで異なるパワーコンディショナのモジュールがあります。 別の回路番号を設定してください。",
|
||||||
"module.circuit.fix.not.same.roof.error": "異なる屋根面のモジュールが選択されています。 モジュールの選択をや直してください。",
|
"module.circuit.fix.not.same.roof.error": "異なる屋根面のモジュールが選択されています。 モジュールの選択をや直してください。",
|
||||||
|
"module.circuit.indoor.focused.error": "混合モジュールと屋内集中PCSを組み合わせる場合は、手動回路割り当てのみ対応可能です。",
|
||||||
"construction.length.difference": "屋根面工法をすべて選択してください。",
|
"construction.length.difference": "屋根面工法をすべて選択してください。",
|
||||||
"menu.validation.canvas.roof": "パネルを配置するには、屋根面を入力する必要があります。",
|
"menu.validation.canvas.roof": "パネルを配置するには、屋根面を入力する必要があります。",
|
||||||
"batch.object.outside.roof": "オブジェクトは屋根に設置する必要があります。",
|
"batch.object.outside.roof": "オブジェクトは屋根に設置する必要があります。",
|
||||||
|
|||||||
@ -1089,6 +1089,7 @@
|
|||||||
"module.circuit.minimun.error": "회로번호는 1 이상입력해주세요.",
|
"module.circuit.minimun.error": "회로번호는 1 이상입력해주세요.",
|
||||||
"module.already.exist.error": "회로번호가 같은 다른 파워 컨디셔너 모듈이 있습니다. 다른 회로번호를 설정하십시오.",
|
"module.already.exist.error": "회로번호가 같은 다른 파워 컨디셔너 모듈이 있습니다. 다른 회로번호를 설정하십시오.",
|
||||||
"module.circuit.fix.not.same.roof.error": "다른 지붕면의 모듈이 선택되어 있습니다. 모듈 선택을 다시 하세요.",
|
"module.circuit.fix.not.same.roof.error": "다른 지붕면의 모듈이 선택되어 있습니다. 모듈 선택을 다시 하세요.",
|
||||||
|
"module.circuit.indoor.focused.error": "혼합 모듈과 실내 집중형 PCS를 조합하는 경우, 수동 회로 할당만 가능합니다.",
|
||||||
"construction.length.difference": "지붕면 공법을 모두 선택하십시오.",
|
"construction.length.difference": "지붕면 공법을 모두 선택하십시오.",
|
||||||
"menu.validation.canvas.roof": "패널을 배치하려면 지붕면을 입력해야 합니다.",
|
"menu.validation.canvas.roof": "패널을 배치하려면 지붕면을 입력해야 합니다.",
|
||||||
"batch.object.outside.roof": "오브젝트는 지붕내에 설치해야 합니다.",
|
"batch.object.outside.roof": "오브젝트는 지붕내에 설치해야 합니다.",
|
||||||
|
|||||||
@ -133,8 +133,23 @@ $alert-color: #101010;
|
|||||||
color: $pop-color;
|
color: $pop-color;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
.modal-close{
|
.modal-btn-wrap{
|
||||||
margin-left: auto;
|
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;
|
color: transparent;
|
||||||
font-size: 0;
|
font-size: 0;
|
||||||
width: 10px;
|
width: 10px;
|
||||||
|
|||||||
@ -460,7 +460,11 @@ button{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.table-select{
|
||||||
|
height: 20px;
|
||||||
|
color: #fff !important;
|
||||||
|
font-size: 11px !important;
|
||||||
|
}
|
||||||
// input
|
// input
|
||||||
.form-input{
|
.form-input{
|
||||||
label{
|
label{
|
||||||
|
|||||||
@ -269,7 +269,7 @@ export const getDegreeByChon = (chon) => {
|
|||||||
* @returns {number}
|
* @returns {number}
|
||||||
*/
|
*/
|
||||||
export const getChonByDegree = (degree) => {
|
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: -51, max: -37, value: -45 },
|
||||||
{ min: -36, max: -22, value: -30 },
|
{ min: -36, max: -22, value: -30 },
|
||||||
{ min: -21, max: -7, value: -15 },
|
{ 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
|
return range ? range.value : degree
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -29,22 +29,39 @@ fabric.Rect.prototype.getCurrentPoints = function () {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* fabric.Group에 getCurrentPoints 메서드를 추가 (도머 그룹용)
|
* fabric.Group에 getCurrentPoints 메서드를 추가 (도머 그룹용)
|
||||||
* 그룹의 groupPoints를 다시 계산하여 반환
|
* 그룹 내 객체들의 점들을 수집하여 현재 월드 좌표를 반환
|
||||||
*/
|
*/
|
||||||
fabric.Group.prototype.getCurrentPoints = function () {
|
fabric.Group.prototype.getCurrentPoints = function () {
|
||||||
// groupPoints를 다시 계산
|
// 그룹 내 객체들로부터 실시간으로 점들을 계산
|
||||||
|
if (this._objects && this._objects.length > 0) {
|
||||||
|
let allPoints = []
|
||||||
|
|
||||||
// 그룹에 groupPoints가 있으면 해당 점들을 사용 (도머의 경우)
|
// 그룹 내 모든 객체의 점들을 수집
|
||||||
if (this.groupPoints && Array.isArray(this.groupPoints)) {
|
this._objects.forEach(function (obj) {
|
||||||
const matrix = this.calcTransformMatrix()
|
if (obj.getCurrentPoints && typeof obj.getCurrentPoints === 'function') {
|
||||||
console.log('this.groupPoints', this.groupPoints)
|
const objPoints = obj.getCurrentPoints()
|
||||||
return this.groupPoints.map(function (p) {
|
allPoints = allPoints.concat(objPoints)
|
||||||
const point = new fabric.Point(p.x, p.y)
|
} else if (obj.points && Array.isArray(obj.points)) {
|
||||||
return fabric.util.transformPoint(point, matrix)
|
const pathOffset = obj.pathOffset || { x: 0, y: 0 }
|
||||||
|
const matrix = obj.calcTransformMatrix()
|
||||||
|
const transformedPoints = obj.points
|
||||||
|
.map(function (p) {
|
||||||
|
return new fabric.Point(p.x - pathOffset.x, p.y - pathOffset.y)
|
||||||
|
})
|
||||||
|
.map(function (p) {
|
||||||
|
return fabric.util.transformPoint(p, matrix)
|
||||||
|
})
|
||||||
|
allPoints = allPoints.concat(transformedPoints)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (allPoints.length > 0) {
|
||||||
|
// Convex Hull 알고리즘을 사용하여 외곽 점들만 반환
|
||||||
|
return this.getConvexHull(allPoints)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// groupPoints가 없으면 바운딩 박스를 사용
|
// 객체가 없으면 바운딩 박스를 사용
|
||||||
const bounds = this.getBoundingRect()
|
const bounds = this.getBoundingRect()
|
||||||
const points = [
|
const points = [
|
||||||
{ x: bounds.left, y: bounds.top },
|
{ x: bounds.left, y: bounds.top },
|
||||||
|
|||||||
@ -12027,7 +12027,11 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => {
|
|||||||
.filter((line) => (line.x2 === ridge.x1 && line.y2 === ridge.y1) || (line.x2 === ridge.x2 && line.y2 === ridge.y2))
|
.filter((line) => (line.x2 === ridge.x1 && line.y2 === ridge.y1) || (line.x2 === ridge.x2 && line.y2 === ridge.y2))
|
||||||
.filter((line) => baseLines.filter((baseLine) => baseLine.x1 === line.x1 && baseLine.y1 === line.y1).length > 0)
|
.filter((line) => baseLines.filter((baseLine) => baseLine.x1 === line.x1 && baseLine.y1 === line.y1).length > 0)
|
||||||
basePoints.sort((a, b) => a.line.attributes.planeSize - b.line.attributes.planeSize)
|
basePoints.sort((a, b) => a.line.attributes.planeSize - b.line.attributes.planeSize)
|
||||||
hipSize = Big(basePoints[0].line.attributes.planeSize)
|
if (basePoints.length > 0 && basePoints[0].line) {
|
||||||
|
hipSize = Big(basePoints[0].line.attributes.planeSize)
|
||||||
|
} else {
|
||||||
|
hipSize = Big(0) // 또는 기본값 설정
|
||||||
|
}
|
||||||
}
|
}
|
||||||
hipSize = hipSize.pow(2).div(2).sqrt().round().div(10).toNumber()
|
hipSize = hipSize.pow(2).div(2).sqrt().round().div(10).toNumber()
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user