# Conflicts:
#	README.md
This commit is contained in:
김민식 2025-04-18 10:23:33 +09:00
commit e717c28758
29 changed files with 2750 additions and 933 deletions

View File

@ -35,4 +35,4 @@ The easiest way to deploy your Next.js app is to use the [Vercel Platform](https
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
test
deploy test

View File

@ -24,7 +24,7 @@
"js-cookie": "^3.0.5",
"mathjs": "^13.0.2",
"mssql": "^11.0.1",
"next": "14.2.25",
"next": "14.2.26",
"next-international": "^1.2.4",
"react": "^18",
"react-chartjs-2": "^5.2.0",

View File

@ -39,7 +39,7 @@ export default function QSelectBox({
if (showKey !== '' && !value) {
//value showKey
// return options[0][showKey]
return title
return title !== '' ? title : getMessage('selectbox.title')
} else if (showKey !== '' && value) {
//value sourceKey targetKey

View File

@ -13,7 +13,7 @@ import dayjs from 'dayjs'
import { useCommonCode } from '@/hooks/common/useCommonCode'
import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController'
import { SessionContext } from '@/app/SessionProvider'
import Select, {components} from 'react-select'
import Select, { components } from 'react-select'
import { convertNumberToPriceDecimal, convertNumberToPriceDecimalToFixed } from '@/util/common-utils'
import ProductFeaturesPop from './popup/ProductFeaturesPop'
import { v4 as uuidv4 } from 'uuid'
@ -504,6 +504,8 @@ export default function Estimate({}) {
saleStoreId: estimateContextState.sapSaleStoreId,
sapSalesStoreCd: estimateContextState.sapSalesStoreCd,
docTpCd: estimateContextState.estimateType,
secSapSalesStoreCd:
estimateContextState.secSapSalesStoreCd?.length > 0 && showPriceCd === 'QSP_PRICE' ? estimateContextState.secSapSalesStoreCd : '',
priceCd: showPriceCd,
itemIdList: estimateContextState.itemList.filter((item) => item.delFlg === '0' && item.paDispOrder === null),
}
@ -715,7 +717,7 @@ export default function Estimate({}) {
/* 케이블 select 변경시 */
const onChangeDisplayCableItem = (value, itemList) => {
itemList.map((item, index) => {
if (item.dispCableFlg === '1') {
if (item.dispCableFlg === '1' && item.itemTpCd !== 'M12') {
if (value !== '') {
onChangeDisplayItem(value, item.dispOrder, index, true)
}
@ -1144,7 +1146,7 @@ export default function Estimate({}) {
dispCableFlgCnt++
}
if (item.dispCableFlg === '1') {
if (item.dispCableFlg === '1' && item.itemTpCd !== 'M12') {
setCableItem(item.itemId)
}
}
@ -1216,6 +1218,21 @@ export default function Estimate({}) {
}
}, [estimateContextState?.itemList, cableItemList])
const [agencyCustList, setAgencyCustList] = useState([])
useEffect(() => {
// 952 - 2 sapSalesStoreCd
if (estimateContextState?.sapSalesStoreCd && session?.storeLvl === '1') {
const param = {
sapSalesStoreCd: estimateContextState.sapSalesStoreCd,
}
const apiUrl = `api/estimate/agency-cust-list?${queryStringFormatter(param)}`
get({ url: apiUrl }).then((res) => {
if (isNotEmptyArray(res?.data)) {
setAgencyCustList(res?.data)
}
})
}
}, [estimateContextState?.sapSalesStoreCd])
return (
<div className="sub-content estimate">
<div className="sub-content-inner">
@ -1360,41 +1377,79 @@ export default function Estimate({}) {
{getMessage('estimate.detail.estimateType')} <span className="important">*</span>
</th>
<td colSpan={3}>
<div className="radio-wrap">
{/*pkgRank is null, empty 인 경우 : 사용불가, 이전에 등록된 경우 사용가능, style로 제어*/}
<div className="d-check-radio light mr10" style={{display:
(isNotEmptyArray(storePriceList) > 0
&& storePriceList[0].pkgRank !== null
&& storePriceList[0].pkgRank !== ''
|| estimateContextState?.estimateType === 'YJSS') ? "" : "none"}}>
<input
type="radio"
name="estimateType"
id="YJSS"
value={'YJSS'}
checked={estimateContextState?.estimateType === 'YJSS' ? true : false}
onChange={(e) => {
//
setHandlePricingFlag(true)
setEstimateContextState({ estimateType: e.target.value })
<div className="form-flex-wrap">
<div className="radio-wrap">
{/*pkgRank is null, empty 인 경우 : 사용불가, 이전에 등록된 경우 사용가능, style로 제어*/}
<div
className="d-check-radio light mr10"
style={{
display:
(isNotEmptyArray(storePriceList) > 0 && storePriceList[0].pkgRank !== null && storePriceList[0].pkgRank !== '') ||
estimateContextState?.estimateType === 'YJSS'
? ''
: 'none',
}}
/>
<label htmlFor="YJSS">{getMessage('estimate.detail.estimateType.yjss')}</label>
</div>
<div className="d-check-radio light">
<input
type="radio"
name="estimateType"
id="YJOD"
value={'YJOD'}
checked={estimateContextState?.estimateType === 'YJOD' ? true : false}
onChange={(e) => {
setHandlePricingFlag(true)
setEstimateContextState({ estimateType: e.target.value })
}}
/>
<label htmlFor="YJOD">{getMessage('estimate.detail.estimateType.yjod')}</label>
>
<input
type="radio"
name="estimateType"
id="YJSS"
value={'YJSS'}
checked={estimateContextState?.estimateType === 'YJSS' ? true : false}
onChange={(e) => {
//
setHandlePricingFlag(true)
setEstimateContextState({ estimateType: e.target.value })
}}
/>
<label htmlFor="YJSS">{getMessage('estimate.detail.estimateType.yjss')}</label>
</div>
<div className="d-check-radio light">
<input
type="radio"
name="estimateType"
id="YJOD"
value={'YJOD'}
checked={estimateContextState?.estimateType === 'YJOD' ? true : false}
onChange={(e) => {
setHandlePricingFlag(true)
setEstimateContextState({ estimateType: e.target.value })
}}
/>
<label htmlFor="YJOD">{getMessage('estimate.detail.estimateType.yjod')}</label>
</div>
</div>
{session?.storeLvl === '1' && agencyCustList.length > 0 ? (
<div className="form-flex-select ml10">
<label htmlFor="">{getMessage('estimate.detail.agency')}</label>
<div className="select-wrap" style={{ width: '400px' }}>
<Select
id="agencyName"
instanceId="agencyName"
className="react-select-custom"
classNamePrefix="custom"
placeholder="Select"
options={agencyCustList}
onChange={(e) => {
if (isObjectNotEmpty(e)) {
setEstimateContextState({ secSapSalesStoreCd: e.sapSalesStoreCd })
} else {
setEstimateContextState({ secSapSalesStoreCd: '' })
}
}}
getOptionLabel={(x) => x.sapSalesStoreNm}
getOptionValue={(x) => x.sapSalesStoreCd}
isClearable={true}
isSearchable={true}
value={agencyCustList.filter(function (option) {
return option.sapSalesStoreCd === estimateContextState.secSapSalesStoreCd
})}
/>
</div>
</div>
) : (
''
)}
</div>
</td>
</tr>
@ -1883,16 +1938,12 @@ export default function Estimate({}) {
}
}}
menuPlacement={'auto'}
getOptionLabel={(x) => x.itemName + " (" + x.itemNo + ")"}
getOptionLabel={(x) => x.itemName + ' (' + x.itemNo + ')'}
getOptionValue={(x) => x.itemNo}
components={{
SingleValue:({children, ...props}) =>{
return (
<components.SingleValue{...props}>
{props.data.itemName}
</components.SingleValue>
)
}
SingleValue: ({ children, ...props }) => {
return <components.SingleValue {...props}>{props.data.itemName}</components.SingleValue>
},
}}
isClearable={false}
isDisabled={!!item?.paDispOrder}
@ -1913,21 +1964,17 @@ export default function Estimate({}) {
placeholder="Select"
options={cableItemList}
menuPlacement={'auto'}
getOptionLabel={(x) => x.clRefChr3 + " (" + x.clRefChr1 + ")"}
getOptionLabel={(x) => x.clRefChr3 + ' (' + x.clRefChr1 + ')'}
getOptionValue={(x) => x.clRefChr1}
components={{
SingleValue:({children, ...props}) =>{
return (
<components.SingleValue{...props}>
{props.data.clRefChr3}
</components.SingleValue>
)
}
SingleValue: ({ children, ...props }) => {
return <components.SingleValue {...props}>{(item.itemTpCd === 'M12')? item.itemName : props.data.clRefChr3}</components.SingleValue>
},
}}
isClearable={false}
isDisabled={true}
value={cableItemList.filter(function (option) {
return option.clRefChr1 === item.itemId
return (item.itemTpCd === 'M12')? item.itemId : option.clRefChr1 === item.itemId
})}
/>
)}
@ -1978,7 +2025,11 @@ export default function Estimate({}) {
<input
type="text"
className="input-light al-r"
value={convertNumberToPriceDecimal(item?.showSalePrice === '0' ? null : item?.salePrice?.replaceAll(',', ''))}
value={
item.openFlg === '1'
? 'OPEN'
: convertNumberToPriceDecimal(item?.showSalePrice === '0' ? null : item?.salePrice?.replaceAll(',', ''))
}
disabled={
item.openFlg === '1'
? true
@ -2006,15 +2057,17 @@ export default function Estimate({}) {
</div>
</td>
<td className="al-r">
{convertNumberToPriceDecimal(
item?.showSaleTotPrice === '0'
? null
: item?.amount === ''
? null
: item?.saleTotPrice === '0'
{item?.openFlg === '1'
? 'OPEN'
: convertNumberToPriceDecimal(
item?.showSaleTotPrice === '0'
? null
: item?.saleTotPrice?.replaceAll(',', ''),
)}
: item?.amount === ''
? null
: item?.saleTotPrice === '0'
? null
: item?.saleTotPrice?.replaceAll(',', ''),
)}
</td>
</tr>
)

View File

@ -1,39 +1,41 @@
import { useMessage } from '@/hooks/useMessage'
import { POLYGON_TYPE } from '@/common/common'
import WithDraggable from '@/components/common/draggable/WithDraggable'
import { useContext, useEffect, useRef, useState } from 'react'
import Module from '@/components/floor-plan/modal/basic/step/Module'
import PitchModule from '@/components/floor-plan/modal/basic/step/pitch/PitchModule'
import { Orientation } from '@/components/floor-plan/modal/basic/step/Orientation'
import PitchPlacement from '@/components/floor-plan/modal/basic/step/pitch/PitchPlacement'
import Placement from '@/components/floor-plan/modal/basic/step/Placement'
import { useRecoilValue, useRecoilState } from 'recoil'
import { canvasSettingState, canvasState, checkedModuleState, isManualModuleSetupState } from '@/store/canvasAtom'
import { usePopup } from '@/hooks/usePopup'
import { Orientation } from '@/components/floor-plan/modal/basic/step/Orientation'
import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting'
import { useEvent } from '@/hooks/useEvent'
import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions'
import { addedRoofsState, corridorDimensionSelector, basicSettingState } from '@/store/settingAtom'
import { isObjectNotEmpty } from '@/util/common-utils'
import Swal from 'sweetalert2'
import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController'
import { useMasterController } from '@/hooks/common/useMasterController'
import { loginUserStore } from '@/store/commonAtom'
import { currentCanvasPlanState } from '@/store/canvasAtom'
import { POLYGON_TYPE } from '@/common/common'
import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting'
import { useModuleSelection } from '@/hooks/module/useModuleSelection'
import { useOrientation } from '@/hooks/module/useOrientation'
import Trestle from './step/Trestle'
import { useMessage } from '@/hooks/useMessage'
import { usePopup } from '@/hooks/usePopup'
import {
canvasState,
checkedModuleState,
currentCanvasPlanState,
isManualModuleLayoutSetupState,
isManualModuleSetupState,
toggleManualSetupModeState,
} from '@/store/canvasAtom'
import { loginUserStore } from '@/store/commonAtom'
import { roofsState } from '@/store/roofAtom'
import { moduleSelectionDataState } from '@/store/selectedModuleOptions'
import { addedRoofsState, basicSettingState } from '@/store/settingAtom'
import { isObjectNotEmpty } from '@/util/common-utils'
import { useEffect, useRef, useState } from 'react'
import { useRecoilState, useRecoilValue } from 'recoil'
import Swal from 'sweetalert2'
import Trestle from './step/Trestle'
export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
const { getMessage } = useMessage()
const { closePopup } = usePopup()
const [tabNum, setTabNum] = useState(1)
const canvasSetting = useRecoilValue(canvasSettingState)
const orientationRef = useRef(null)
const trestleRef = useRef(null)
const { initEvent } = useEvent()
const [isManualModuleSetup, setIsManualModuleSetup] = useRecoilState(isManualModuleSetupState)
const [isManualModuleLayoutSetup, setIsManualModuleLayoutSetup] = useRecoilState(isManualModuleLayoutSetupState)
const trestleRef = useRef(null)
const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState)
const [addedRoofs, setAddedRoofs] = useRecoilState(addedRoofsState)
const loginUserState = useRecoilValue(loginUserStore)
@ -43,6 +45,8 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
const [isClosePopup, setIsClosePopup] = useState({ close: false, id: 0 })
const [checkedModules, setCheckedModules] = useRecoilState(checkedModuleState)
const [roofs, setRoofs] = useState(addedRoofs)
const [manualSetupMode, setManualSetupMode] = useRecoilState(toggleManualSetupModeState)
const [layoutSetup, setLayoutSetup] = useState([{}])
const {
moduleSelectionInitParams,
selectedModules,
@ -70,23 +74,37 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
const { trigger: orientationTrigger } = useCanvasPopupStatusController(1)
const { trigger: trestleTrigger } = useCanvasPopupStatusController(2)
const { trigger: placementTrigger } = useCanvasPopupStatusController(3)
const roofsStore = useRecoilValue(roofsState)
const [roofsStore, setRoofsStore] = useRecoilState(roofsState)
// const { initEvent } = useContext(EventContext)
const { manualModuleSetup, autoModuleSetup, manualFlatroofModuleSetup, autoFlatroofModuleSetup } = useModuleBasicSetting(tabNum)
const { manualModuleSetup, autoModuleSetup, manualFlatroofModuleSetup, autoFlatroofModuleSetup, manualModuleLayoutSetup, restoreModuleInstArea } =
useModuleBasicSetting(tabNum)
const { updateObjectDate } = useMasterController()
useEffect(() => {
if (managementState) console.log('managementState', managementState)
}, [managementState])
const moduleTabNum = basicSetting.roofSizeSet != 3 ? 3 : 2
let hasModules = canvas
.getObjects()
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
.some((obj) => obj.modules?.length > 0)
if (hasModules) {
orientationRef.current.handleNextStep()
setTabNum(moduleTabNum)
}
}, [])
useEffect(() => {
if (roofsStore && addedRoofs) {
console.log('🚀 ~ useEffect ~ roofsStore, addedRoofs:', roofsStore, addedRoofs)
setRoofs(
addedRoofs.map((roof, index) => {
return {
...roof,
...roofsStore[index].addRoof,
...roofsStore[index]?.addRoof,
construction: roofsStore[index]?.construction,
trestle: roofsStore[index]?.trestle,
trestleDetail: roofsStore[index]?.trestleDetail,
}
}),
)
@ -95,36 +113,20 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
...moduleSelectionData,
roofConstructions: roofsStore.map((roof) => {
return {
addRoof: {
...roof.addRoof,
},
construction: {
...roof.construction,
},
trestle: {
...roof.trestle,
},
roofIndex: roof.roofIndex,
addRoof: roof.addRoof,
construction: roof.construction,
trestle: roof.trestle,
trestleDetail: roof.trestleDetail,
}
}),
})
}
}, [roofsStore, addedRoofs])
useEffect(() => {
let hasModules = canvas
.getObjects()
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
.some((obj) => obj.modules?.length > 0)
if (hasModules) {
orientationRef.current.handleNextStep()
setTabNum(3)
}
}, [])
useEffect(() => {
if (basicSetting.roofSizeSet !== '3') {
manualModuleSetup(placementRef)
manualModuleSetup()
} else {
manualFlatroofModuleSetup(placementFlatRef)
}
@ -137,22 +139,45 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
setIsManualModuleSetup(false)
}, [checkedModules])
useEffect(() => {
if (basicSetting.roofSizeSet !== '3') {
if (manualSetupMode.indexOf('manualSetup') > -1) {
manualModuleSetup()
} else if (manualSetupMode.indexOf('manualLayoutSetup') > -1) {
manualModuleLayoutSetup(layoutSetup)
} else if (manualSetupMode.indexOf('off') > -1) {
manualModuleSetup()
manualModuleLayoutSetup(layoutSetup)
}
} else {
manualFlatroofModuleSetup(placementFlatRef)
}
if (isClosePopup.close) {
closePopup(isClosePopup.id)
}
}, [manualSetupMode, isClosePopup])
useEffect(() => {
if (isManualModuleLayoutSetup) {
manualModuleLayoutSetup(layoutSetup)
}
}, [layoutSetup])
useEffect(() => {
setIsManualModuleSetup(false)
setIsManualModuleLayoutSetup(false)
setManualSetupMode(`off`)
}, [checkedModules])
const handleBtnNextStep = () => {
if (tabNum === 1) {
console.log('moduleSelectionData', moduleSelectionData)
orientationRef.current.handleNextStep()
setAddedRoofs(roofs)
// setTabNum(tabNum + 1)
return
} else if (tabNum === 2) {
if (basicSetting.roofSizeSet !== '3') {
if (!isObjectNotEmpty(moduleSelectionData.module)) {
Swal.fire({
title: getMessage('module.not.found'),
icon: 'warning',
})
return
}
// if (addedRoofs.length !== moduleSelectionData.roofConstructions.length) {
// Swal.fire({
// title: getMessage('construction.length.difference'),
@ -160,14 +185,9 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
// })
// return
// }
if (!trestleRef.current.isComplete()) {
Swal.fire({
title: getMessage('아직 멀었따'),
icon: 'warning',
})
return
}
trestleRef.current.isComplete().then((res) => {
if (!res) return
})
//
} else {
if (!isObjectNotEmpty(moduleSelectionData.module)) {
@ -177,16 +197,10 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
})
return
}
setTabNum(tabNum + 1)
}
}
setTabNum(tabNum + 1)
}
const placementRef = {
isChidori: useRef('false'),
setupLocation: useRef('eaves'),
isMaxSetup: useRef('false'),
}
const placementFlatRef = {
@ -194,9 +208,15 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
}
const handleManualModuleSetup = () => {
setManualSetupMode(`manualSetup_${!isManualModuleSetup}`)
setIsManualModuleSetup(!isManualModuleSetup)
}
const handleManualModuleLayoutSetup = () => {
setManualSetupMode(`manualLayoutSetup_${!isManualModuleLayoutSetup}`)
setIsManualModuleLayoutSetup(!isManualModuleLayoutSetup)
}
const updateObjectDataApi = async (params) => {
const res = await updateObjectDate(params)
}
@ -207,6 +227,9 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
if (isManualModuleSetup) {
setIsManualModuleSetup(false)
}
if (isManualModuleLayoutSetup) {
setIsManualModuleLayoutSetup(false)
}
}
setIsClosePopup({ close: true, id: id })
}
@ -250,6 +273,8 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
const trestleProps = {
roofs,
setRoofs,
setRoofsStore,
tabNum,
setTabNum,
moduleSelectionData,
setModuleSelectionData,
@ -258,7 +283,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
const placementProps = {}
return (
<WithDraggable isShow={true} pos={pos} className="ll">
<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.Body>
<div className="roof-module-tab">
@ -280,8 +305,9 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
{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} ref={placementRef} />}
{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 && (
@ -290,35 +316,45 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
<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" onClick={() => setTabNum(tabNum - 1)}>
{getMessage('modal.module.basic.setting.prev')}
</button>
)}
{/*{tabNum !== 3 && <button className="btn-frame modal act mr5">{getMessage('modal.common.save')}</button>}*/}
{tabNum !== 3 && (
<button className="btn-frame modal" onClick={handleBtnNextStep}>
Next
</button>
)}
{tabNum === 3 && (
{basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && (
<>
{basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && (
{tabNum !== 1 && (
<button className="btn-frame modal mr5" onClick={() => setTabNum(tabNum - 1)}>
{getMessage('modal.module.basic.setting.prev')}
</button>
)}
{tabNum !== 3 && (
<button className="btn-frame modal" onClick={handleBtnNextStep}>
Next
</button>
)}
{tabNum === 3 && (
<>
<button className="btn-frame modal mr5">{getMessage('modal.module.basic.setting.row.batch')}</button>
<button className={`btn-frame modal mr5 ${isManualModuleLayoutSetup ? 'act' : ''}`} onClick={handleManualModuleLayoutSetup}>
{getMessage('modal.module.basic.setting.row.batch')}
</button>
<button className={`btn-frame modal mr5 ${isManualModuleSetup ? 'act' : ''}`} onClick={handleManualModuleSetup}>
{getMessage('modal.module.basic.setting.passivity.placement')}
</button>
<button className="btn-frame modal act" onClick={() => autoModuleSetup(placementRef)}>
<button className="btn-frame modal act" onClick={() => autoModuleSetup()}>
{getMessage('modal.module.basic.setting.auto.placement')}
</button>
</>
)}
{basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && (
</>
)}
{basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && (
<>
{tabNum === 1 && (
<button className="btn-frame modal" onClick={handleBtnNextStep}>
Next
</button>
)}
{tabNum === 2 && (
<>
<button className="btn-frame modal mr5">{getMessage('modal.module.basic.setting.row.batch')}</button>
<button className="btn-frame modal mr5" onClick={() => setTabNum(tabNum - 1)}>
{getMessage('modal.module.basic.setting.prev')}
</button>
<button className={`btn-frame modal mr5 ${isManualModuleSetup ? 'act' : ''}`} onClick={handleManualModuleSetup}>
{getMessage('modal.module.basic.setting.passivity.placement')}
</button>

View File

@ -1,19 +1,20 @@
import { forwardRef, use, useContext, useEffect, useImperativeHandle, useState } from 'react'
import { useMessage } from '@/hooks/useMessage'
import { useOrientation } from '@/hooks/module/useOrientation'
import { getDegreeInOrientation } from '@/util/canvas-util'
import { numberCheck } from '@/util/common-utils'
import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController'
import { addedRoofsState, basicSettingState } from '@/store/settingAtom'
import { useRecoilState, useRecoilValue } from 'recoil'
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
import QSelectBox from '@/components/common/select/QSelectBox'
import { moduleSelectionDataState } from '@/store/selectedModuleOptions'
import { roofsState } from '@/store/roofAtom'
import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting'
import Swal from 'sweetalert2'
export const Orientation = forwardRef((props, ref) => {
const { getMessage } = useMessage()
const [hasAnglePassivity, setHasAnglePassivity] = useState(false)
const basicSetting = useRecoilValue(basicSettingState)
const [addedRoofs, setAddedRoofs] = useRecoilState(addedRoofsState) //
const [roofsStore, setRoofsStore] = useRecoilState(roofsState)
const [roofTab, setRoofTab] = useState(0) //
const {
roofs,
@ -48,9 +49,11 @@ export const Orientation = forwardRef((props, ref) => {
} = props
const [inputCompasDeg, setInputCompasDeg] = useState(compasDeg ?? 0)
const [inputInstallHeight, setInputInstallHeight] = useState('0')
const [inputMargin, setInputMargin] = useState('0')
const [inputVerticalSnowCover, setInputVerticalSnowCover] = useState('0')
const [inputRoughness, setInputRoughness] = useState(selectedSurfaceType)
const [inputStandardWindSpeed, setInputStandardWindSpeed] = useState(standardWindSpeed)
const { restoreModuleInstArea } = useModuleBasicSetting()
const moduleData = {
header: [
{ name: getMessage('module'), width: 150, prop: 'module', type: 'color-box' },
@ -63,20 +66,36 @@ export const Orientation = forwardRef((props, ref) => {
],
}
useEffect(() => {
if (basicSetting.roofSizeSet == '3') {
restoreModuleInstArea()
}
}, [])
useEffect(() => {
if (moduleSelectionData?.common) {
setInputMargin(moduleSelectionData?.common?.margin)
}
}, [moduleSelectionData])
useEffect(() => {
if (selectedModules) {
setSelectedModules(moduleList.find((module) => module.itemId === selectedModules.itemId))
}
}, [selectedModules])
useEffect(() => {
if (selectedSurfaceType) {
console.log(roughnessCodes, selectedSurfaceType)
setInputRoughness(roughnessCodes.find((code) => code.clCode === moduleSelectionData.common.illuminationTp))
setInputRoughness(roughnessCodes.find((code) => code.clCode === managementState?.surfaceTypeValue))
}
}, [selectedSurfaceType])
useEffect(() => {
if (standardWindSpeed) setInputStandardWindSpeed(windSpeedCodes.find((code) => code.clCode === moduleSelectionData.common.stdWindSpeed))
if (standardWindSpeed) setInputStandardWindSpeed(windSpeedCodes.find((code) => code.clCode === managementState?.standardWindSpeedId))
}, [standardWindSpeed])
useEffect(() => {
if (managementState?.installHeight && managementState?.installHeight) {
console.log('🚀 ~ useEffect ~ managementState:', managementState)
setSelectedSurfaceType(roughnessCodes.find((code) => code.clCode === managementState?.surfaceTypeValue))
setInputInstallHeight(managementState?.installHeight)
setStandardWindSpeed(windSpeedCodes.find((code) => code.clCode === managementState?.standardWindSpeedId))
@ -84,12 +103,6 @@ export const Orientation = forwardRef((props, ref) => {
}
}, [managementState])
useEffect(() => {
if (moduleSelectionData) {
console.log('moduleSelectionData', moduleSelectionData)
}
}, [moduleSelectionData])
useImperativeHandle(ref, () => ({
handleNextStep,
}))
@ -100,23 +113,24 @@ export const Orientation = forwardRef((props, ref) => {
illuminationTp: inputRoughness.clCode,
illuminationTpNm: inputRoughness.clCodeNm,
instHt: inputInstallHeight,
stdWindSpeed: inputStandardWindSpeed.clCode,
stdWindSpeed: inputStandardWindSpeed?.clCode,
stdSnowLd: inputVerticalSnowCover,
saleStoreNorthFlg: managementState?.saleStoreNorthFlg,
moduleTpCd: selectedModules.itemTp,
moduleItemId: selectedModules.itemId,
margin: inputMargin,
}
setCompasDeg(inputCompasDeg)
setInstallHeight(inputInstallHeight)
setVerticalSnowCover(inputVerticalSnowCover)
setSelectedSurfaceType(inputRoughness)
setStandardWindSpeed(inputStandardWindSpeed)
nextStep()
nextStep(inputCompasDeg)
setManagementState({
...managementState,
installHeight: inputInstallHeight,
verticalSnowCover: inputVerticalSnowCover,
standardWindSpeedId: inputStandardWindSpeed.clCode,
standardWindSpeedId: inputStandardWindSpeed?.clCode,
surfaceType: inputRoughness.clCodeNm,
surfaceTypeValue: inputRoughness.clCode,
})
@ -125,6 +139,7 @@ export const Orientation = forwardRef((props, ref) => {
module: {
...selectedModules,
},
common,
})
orientationTrigger({
compasDeg: inputCompasDeg,
@ -132,16 +147,25 @@ export const Orientation = forwardRef((props, ref) => {
module: {
...selectedModules,
},
margin: inputMargin,
})
updateObjectDataApi({
objectNo: currentCanvasPlan.objectNo, //_no
standardWindSpeedId: inputStandardWindSpeed.clCode, //
standardWindSpeedId: inputStandardWindSpeed?.clCode, //
verticalSnowCover: inputVerticalSnowCover, //
surfaceType: inputRoughness.clCodeNm, //
installHeight: inputInstallHeight, //
userId: loginUserState.userId, //
})
setTabNum(2)
} else {
if (!selectedModules || !selectedModules.itemId) {
Swal.fire({
title: getMessage('module.not.found'),
icon: 'warning',
})
return
}
}
}
@ -151,19 +175,20 @@ export const Orientation = forwardRef((props, ref) => {
return
}
if (e === '0-') {
setCompasDeg('-0')
setInputCompasDeg('-0')
return
}
if (Number(e) >= -180 && Number(e) <= 180) {
if (numberCheck(Number(e))) {
setCompasDeg(Number(e))
setInputCompasDeg(Number(e))
}
} else {
setCompasDeg(compasDeg)
setInputCompasDeg(compasDeg)
}
}
const isComplete = () => {
if (!selectedModules || !selectedModules.itemId) return false
if (basicSetting && basicSetting.roofSizeSet !== '3') {
if (inputInstallHeight <= 0) {
return false
@ -181,27 +206,61 @@ export const Orientation = forwardRef((props, ref) => {
}
const handleChangeModule = (e) => {
resetRoofs()
setSelectedModules(e)
}
const handleChangeRoughness = (e) => {
resetRoofs()
setInputRoughness(e)
}
const handleChangeInstallHeight = (e) => {
resetRoofs()
setInputInstallHeight(e)
}
const handleChangeStandardWindSpeed = (e) => {
resetRoofs()
setInputStandardWindSpeed(e)
}
const handleChangeVerticalSnowCover = (e) => {
resetRoofs()
setInputVerticalSnowCover(e)
}
const resetRoofs = () => {
const newRoofs = addedRoofs.map((roof) => {
return {
...roof,
lengthBase: null,
raftBaseCd: null,
trestleMkrCd: null,
constMthdCd: null,
constTp: null,
roofBaseCd: null,
ridgeMargin: null,
kerabaMargin: null,
eavesMargin: null,
roofPchBase: null,
cvrYn: 'N',
snowGdPossYn: 'N',
cvrChecked: false,
snowGdChecked: false,
trestle: {
lengthBase: null,
trestleMkrCd: null,
constMthdCd: null,
constTp: null,
roofBaseCd: null,
roofPchBase: null,
},
addRoof: {
...roof.addRoof,
lengthBase: null,
eavesMargin: null,
kerabaMargin: null,
ridgeMargin: null,
},
construction: {
constTp: null,
cvrYn: 'N',
snowGdPossYn: 'N',
cvrChecked: false,
snowGdChecked: false,
},
}
})
setRoofs(newRoofs)
setSelectedModules(e)
// setRoofs(newRoofs)
// setAddedRoofs(newRoofs)
setRoofsStore(newRoofs)
}
return (
@ -275,8 +334,8 @@ export const Orientation = forwardRef((props, ref) => {
{moduleList && (
<QSelectBox
options={moduleList}
value={moduleSelectionInitParams}
targetKey={'moduleItemId'}
value={selectedModules}
targetKey={'itemId'}
sourceKey={'itemId'}
showKey={'itemNm'}
onChange={(e) => handleChangeModule(e)}
@ -298,7 +357,7 @@ export const Orientation = forwardRef((props, ref) => {
</tr>
</thead>
<tbody>
{Array.from({ length: 2 }).map((_, index) => {
{Array.from({ length: 3 }).map((_, index) => {
return selectedModules && selectedModules?.itemList && selectedModules?.itemList?.length >= index + 1 ? (
<tr key={index}>
<td>
@ -330,23 +389,18 @@ export const Orientation = forwardRef((props, ref) => {
</tbody>
</table>
</div>
{basicSetting && basicSetting.roofSizeSet === '3' && (
{basicSetting && basicSetting.roofSizeSet == '3' && (
<div className="outline-form mt15">
<span>{getMessage('modal.module.basic.setting.module.placement.area')}</span>
<div className="input-grid mr10" style={{ width: '60px' }}>
<input
type="text"
className="input-origin block"
value={inputInstallHeight}
onChange={(e) => setInputInstallHeight(e.target.value)}
/>
<input type="text" className="input-origin block" value={inputMargin} onChange={(e) => setInputMargin(e.target.value)} />
</div>
<span className="thin">m</span>
</div>
)}
</div>
{basicSetting && basicSetting.roofSizeSet !== '3' && (
{basicSetting && basicSetting.roofSizeSet != '3' && (
<div className="compas-table-box">
<div className="compas-grid-table">
<div className="outline-form">
@ -359,10 +413,7 @@ export const Orientation = forwardRef((props, ref) => {
targetKey={'clCode'}
sourceKey={'clCode'}
showKey={'clCodeNm'}
onChange={(e) => {
console.log('🚀 ~ handleChangeModule ~ inputRoughness:', e)
setInputRoughness(e)
}}
onChange={(e) => handleChangeRoughness(e)}
/>
)}
</div>
@ -374,7 +425,7 @@ export const Orientation = forwardRef((props, ref) => {
type="text"
className="input-origin block"
value={inputInstallHeight}
onChange={(e) => setInputInstallHeight(e.target.value)}
onChange={(e) => handleChangeInstallHeight(e.target.value)}
/>
</div>
<span className="thin">m</span>
@ -390,10 +441,7 @@ export const Orientation = forwardRef((props, ref) => {
targetKey={'clCode'}
sourceKey={'clCode'}
showKey={'clCodeNm'}
onChange={(e) => {
console.log('🚀 ~ handleChangeModule ~ inputStandardWindSpeed:', e)
setInputStandardWindSpeed(e)
}}
onChange={(e) => handleChangeStandardWindSpeed(e)}
/>
)}
</div>
@ -405,7 +453,7 @@ export const Orientation = forwardRef((props, ref) => {
type="text"
className="input-origin block"
value={inputVerticalSnowCover}
onChange={(e) => setInputVerticalSnowCover(e.target.value)}
onChange={(e) => handleChangeVerticalSnowCover(e.target.value)}
/>
</div>
<span className="thin">cm</span>

View File

@ -1,29 +1,43 @@
import { forwardRef, useEffect, useState } from 'react'
import { useMessage } from '@/hooks/useMessage'
import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting'
import { checkedModuleState, currentCanvasPlanState, isManualModuleSetupState } from '@/store/canvasAtom'
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
import {
checkedModuleState,
isManualModuleLayoutSetupState,
isManualModuleSetupState,
moduleRowColArrayState,
moduleSetupOptionState,
toggleManualSetupModeState,
} from '@/store/canvasAtom'
import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil'
import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions'
import { isObjectNotEmpty } from '@/util/common-utils'
const Placement = forwardRef((props, refs) => {
const { getMessage } = useMessage()
const [isChidori, setIsChidori] = useState(false)
const [useTab, setUseTab] = useState(true)
const [isChidoriNotAble, setIsChidoriNotAble] = useState(false)
const [setupLocation, setSetupLocation] = useState('eaves')
const [isMaxSetup, setIsMaxSetup] = useState('false')
const [selectedItems, setSelectedItems] = useState({})
const [selectedModules, setSelectedModules] = useRecoilState(selectedModuleState)
const setCheckedModules = useSetRecoilState(checkedModuleState)
const moduleSelectionData = useRecoilValue(moduleSelectionDataState)
const { makeModuleInitArea } = useModuleBasicSetting(3)
const { makeModuleInitArea, roofOutlineColor } = useModuleBasicSetting(3)
const [isMultiModule, setIsMultiModule] = useState(false)
const [isManualModuleSetup, setIsManualModuleSetup] = useRecoilState(isManualModuleSetupState)
//
const setIsManualModuleSetup = useSetRecoilState(isManualModuleSetupState)
const setIsManualModuleLayoutSetup = useSetRecoilState(isManualModuleLayoutSetupState)
const setManualSetupMode = useSetRecoilState(toggleManualSetupModeState)
const [moduleSetupOption, setModuleSetupOption] = useRecoilState(moduleSetupOptionState) //
const resetModuleSetupOption = useResetRecoilState(moduleSetupOptionState)
const [colspan, setColspan] = useState(1)
const [moduleRowColArray, setModuleRowColArray] = useRecoilState(moduleRowColArrayState)
//
useEffect(() => {
@ -36,13 +50,24 @@ const Placement = forwardRef((props, refs) => {
makeModuleInitArea(moduleSelectionData)
}
if (moduleSelectionData.module.itemList.length > 1) {
setColspan(2)
}
return () => {
refs.isChidori.current = 'false'
refs.setupLocation.current = 'eaves'
// refs.isChidori.current = 'false'
// refs.setupLocation.current = 'eaves'
setIsManualModuleSetup(false)
setIsManualModuleLayoutSetup(false)
setManualSetupMode('off')
resetModuleSetupOption()
}
}, [])
useEffect(() => {
console.log('moduleRowColArray', moduleRowColArray)
}, [moduleRowColArray])
//
useEffect(() => {
if (isObjectNotEmpty(moduleSelectionData)) {
@ -56,8 +81,10 @@ const Placement = forwardRef((props, refs) => {
initCheckedModule = { ...initCheckedModule, [obj.itemId]: true }
}
})
setSelectedItems(initCheckedModule)
setSelectedModules(moduleSelectionData.module)
props.setLayoutSetup(moduleSelectionData.module.itemList.map((item) => ({ moduleId: item.itemId, col: 0, row: 0, checked: true })))
}
//
@ -82,59 +109,75 @@ const Placement = forwardRef((props, refs) => {
header: [
{ type: 'check', name: '', prop: 'check', width: 70 },
{ type: 'color-box', name: getMessage('module'), prop: 'module' },
{ type: 'text', name: `${getMessage('output')} (W)`, prop: 'output', width: 70 },
{ type: 'text', name: getMessage('modal.module.basic.setting.module.placement.mix.asg.yn'), prop: 'mixAsgYn', width: 50 },
{ type: 'text', name: `単数`, prop: 'rows', width: 60 },
{ type: 'text', name: `熱水`, prop: 'cols', width: 60 },
],
rows: [],
}
const handleChangeChidori = (e) => {
const bool = e.target.value === 'true' ? true : false
setIsChidori(bool)
refs.isChidori.current = e.target.value
setModuleSetupOption({ ...moduleSetupOption, isChidori: bool })
//
setIsManualModuleSetup(false)
setIsManualModuleLayoutSetup(false)
setManualSetupMode('off')
}
const handleSetupLocation = (e) => {
setSetupLocation(e.target.value)
refs.setupLocation.current = e.target.value
}
setModuleSetupOption({ ...moduleSetupOption, setupLocation: e.target.value })
const handleMaxSetup = (e) => {
if (e.target.checked) {
setIsMaxSetup('true')
refs.isMaxSetup.current = 'true'
} else {
setIsMaxSetup('false')
refs.isMaxSetup.current = 'false'
}
//
setIsManualModuleSetup(false)
setIsManualModuleLayoutSetup(false)
setManualSetupMode('off')
}
//
const handleSelectedItem = (e) => {
const handleSelectedItem = (e, itemId) => {
setSelectedItems({ ...selectedItems, [e.target.name]: e.target.checked })
const newLayoutSetup = [...props.layoutSetup]
props.layoutSetup.forEach((item, index) => {
if (item.moduleId === itemId) {
newLayoutSetup[index] = { ...props.layoutSetup[index], checked: e.target.checked }
}
})
props.setLayoutSetup(newLayoutSetup)
}
const handleLayoutSetup = (e, itemId, index) => {
const newLayoutSetup = [...props.layoutSetup]
newLayoutSetup[index] = {
...newLayoutSetup[index],
moduleId: itemId,
[e.target.name]: Number(e.target.value),
}
props.setLayoutSetup(newLayoutSetup)
}
return (
<>
<div className="module-table-flex-wrap mb10">
<div className="module-table-flex-wrap">
<div className="module-table-box">
<div className="module-table-inner">
<div className="roof-module-table">
<table>
<thead>
<tr>
{moduleData.header.map((data) => (
<th key={data.prop} style={{ width: data.width ? data.width : '' }}>
{data.type === 'check' ? (
<div className="d-check-box no-text pop">
<input type="checkbox" id="ch01" disabled />
<label htmlFor="ch01"></label>
</div>
) : (
data.name
)}
</th>
))}
</tr>
{moduleData.header.map((data) => (
<th key={data.prop} style={{ width: data.width ? data.width : '' }}>
{data.type === 'check' ? (
<div className="d-check-box no-text pop">
<input type="checkbox" id="ch01" disabled />
<label htmlFor="ch01"></label>
</div>
) : (
data.name
)}
</th>
))}
</thead>
<tbody>
{selectedModules.itemList &&
@ -147,7 +190,7 @@ const Placement = forwardRef((props, refs) => {
id={item.itemId}
name={item.itemId}
checked={selectedItems[item.itemId]}
onChange={handleSelectedItem}
onChange={(e) => handleSelectedItem(e, item.itemId)}
/>
<label htmlFor={item.itemId}></label>
</div>
@ -158,93 +201,174 @@ const Placement = forwardRef((props, refs) => {
<span className="name">{item.itemNm}</span>
</div>
</td>
<td className="al-r">{item.wpOut}</td>
<td className="al-c">
<div className="color-wrap">
<span className="name">{item.mixAsgYn}</span>
</div>
</td>
<td className="al-r">
<div className="input-grid">
<input
type="text"
className="input-origin block"
name="row"
value={props.layoutSetup[index]?.row ?? 1}
defaultValue={0}
onChange={(e) => handleLayoutSetup(e, item.itemId, index)}
/>
</div>
</td>
<td className="al-r">
<div className="input-grid">
<input
type="text"
className="input-origin block"
name="col"
value={props.layoutSetup[index]?.col ?? 1}
defaultValue={0}
onChange={(e) => handleLayoutSetup(e, item.itemId, index)}
/>
</div>
</td>
</tr>
))}
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div className="module-table-box">
<div className="module-table-box non-flex">
<div className="module-table-inner">
<div className="self-table-tit">{getMessage('modal.module.basic.setting.module.placement.select.fitting.type')}</div>
<div className="module-self-table">
<div className="self-table-item">
<div className="self-item-th">{getMessage('modal.module.basic.setting.module.placement.waterfowl.arrangement')}</div>
<div className="self-item-td">
<div className="pop-form-radio">
<div className="d-check-radio pop">
<input
type="radio"
name="radio01"
id="ra01"
checked={isChidori}
disabled={isChidoriNotAble}
value={'true'}
onChange={(e) => handleChangeChidori(e)}
/>
<label htmlFor="ra01">{getMessage('modal.module.basic.setting.module.placement.do')}</label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio02" id="ra02" checked={!isChidori} value={'false'} onChange={(e) => handleChangeChidori(e)} />
<label htmlFor="ra02">{getMessage('modal.module.basic.setting.module.placement.do.not')}</label>
</div>
</div>
</div>
</div>
<div className="self-table-item">
<div className="self-item-th">{getMessage('modal.module.basic.setting.module.placement.arrangement.standard')}</div>
<div className="self-item-td">
<div className="pop-form-radio">
<div className="d-check-radio pop">
<input
type="radio"
name="radio03"
id="ra03"
checked={setupLocation === 'center'}
value={'center'}
onChange={handleSetupLocation}
disabled={isMultiModule}
/>
<label htmlFor="ra03">{getMessage('modal.module.basic.setting.module.placement.arrangement.standard.center')}</label>
</div>
<div className="d-check-radio pop">
<input
type="radio"
name="radio04"
id="ra04"
checked={setupLocation === 'eaves'}
value={'eaves'}
onChange={handleSetupLocation}
/>
<label htmlFor="ra04">{getMessage('modal.module.basic.setting.module.placement.arrangement.standard.eaves')}</label>
</div>
<div className="d-check-radio pop">
<input
type="radio"
name="radio05"
id="ra05"
checked={setupLocation === 'ridge'}
value={'ridge'}
onChange={handleSetupLocation}
disabled={isMultiModule}
/>
<label htmlFor="ra05">{getMessage('modal.module.basic.setting.module.placement.arrangement.standard.ridge')}</label>
</div>
</div>
</div>
</div>
</div>
<div className="self-table-flx">
{/* <div className="d-check-box pop">
<input type="checkbox" id="ch04" checked={isMaxSetup === 'true'} value={'true'} onChange={handleMaxSetup} />
<label htmlFor="ch04">{getMessage('modal.module.basic.setting.module.placement.maximum')}</label>
</div> */}
<div className="roof-module-table">
<table>
<thead>
<tr>
<th>{getMessage('modal.module.basic.setting.module.placement.waterfowl.arrangement')}</th>
<th>{getMessage('modal.module.basic.setting.module.placement.arrangement.standard')}</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div className="hexagonal-radio-wrap">
<div className="d-check-radio pop mb10">
<input
type="radio"
name="radio02"
id="ra03"
checked={moduleSetupOption.isChidori}
disabled={isChidoriNotAble}
value={'true'}
onChange={(e) => handleChangeChidori(e)}
/>
<label htmlFor="ra03">{getMessage('modal.module.basic.setting.module.placement.do')}</label>
</div>
<div className="d-check-radio pop">
<input
type="radio"
name="radio02"
id="ra04"
checked={!moduleSetupOption.isChidori}
value={'false'}
onChange={(e) => handleChangeChidori(e)}
/>
<label htmlFor="ra04">{getMessage('modal.module.basic.setting.module.placement.do.not')}</label>
</div>
</div>
</td>
<td>
<div className="hexagonal-radio-wrap">
<div className="d-check-radio pop mb10">
<input
type="radio"
name="radio03"
id="ra05"
checked={moduleSetupOption.setupLocation === 'eaves'}
value={'eaves'}
onChange={handleSetupLocation}
/>
<label htmlFor="ra05">{getMessage('modal.module.basic.setting.module.placement.arrangement.standard.eaves')}</label>
</div>
<div className="d-check-radio pop">
<input
type="radio"
name="radio03"
id="ra06"
checked={moduleSetupOption.setupLocation === 'ridge'}
value={'ridge'}
onChange={handleSetupLocation}
disabled={isMultiModule}
/>
<label htmlFor="ra06">{getMessage('modal.module.basic.setting.module.placement.arrangement.standard.ridge')}</label>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div className="hide-check-guide">
{getMessage('modal.module.basic.setting.module.placement.max.size.check')}
<button className={`arr ${!useTab ? 'act' : ''}`} onClick={() => setUseTab(!useTab)}></button>
</div>
<div className={`module-table-box mt10 ${useTab ? 'hide' : ''}`}>
<div className="module-table-inner">
<div className="roof-module-table">
<table className="">
<thead>
<tr>
<th rowSpan={2} style={{ width: '22%' }}></th>
{selectedModules &&
selectedModules.itemList.map((item) => (
<th colSpan={colspan}>
<div className="color-wrap">
<span className="color-box" style={{ backgroundColor: item.color }}></span>
<span className="name">{item.itemNm}</span>
</div>
</th>
))}
</tr>
<tr>
{selectedModules.itemList.map((item) => (
<>
<th>{getMessage('modal.module.basic.setting.module.placement.max.row')}</th>
{colspan > 1 && <th>{getMessage('modal.module.basic.setting.module.placement.max.rows.multiple')}</th>}
</>
))}
</tr>
</thead>
<tbody>
{moduleSelectionData.roofConstructions.map((item, index) => (
<tr>
<td>
<div className="color-wrap">
<span className="color-box" style={{ backgroundColor: roofOutlineColor(item.addRoof?.index) }}></span>
<span className="name">{item.addRoof?.roofMatlNmJp}</span>
</div>
</td>
{moduleRowColArray[index]?.map((item) => (
<>
<td className="al-c">{item.moduleMaxRows}</td>
{colspan > 1 && <td className="al-c">{item.mixModuleMaxRows}</td>}
</>
))}
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
</>
)
})

View File

@ -1,23 +1,25 @@
import { GlobalDataContext } from '@/app/GlobalDataProvider'
import QSelectBox from '@/components/common/select/QSelectBox'
import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting'
import { useModuleTrestle } from '@/hooks/module/useModuleTrestle'
import { useMessage } from '@/hooks/useMessage'
import { currentAngleTypeSelector, pitchTextSelector } from '@/store/canvasAtom'
import { roofsState } from '@/store/roofAtom'
import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions'
import { isObjectNotEmpty } from '@/util/common-utils'
import { forwardRef, useContext, useEffect, useImperativeHandle, useState } from 'react'
import { forwardRef, useContext, useEffect, useImperativeHandle, useRef, useState } from 'react'
import { useRecoilState, useRecoilValue } from 'recoil'
import Swal from 'sweetalert2'
const Trestle = forwardRef((props, ref) => {
const { setTabNum, trestleTrigger, roofs, setRoofs, moduleSelectionData, setModuleSelectionData } = props
const { tabNum, setTabNum, trestleTrigger, roofs, setRoofs, moduleSelectionData, setModuleSelectionData, setRoofsStore } = props
const { getMessage } = useMessage()
// const [selectedTrestle, setSelectedTrestle] = useState()
const currentAngleType = useRecoilValue(currentAngleTypeSelector)
const pitchText = useRecoilValue(pitchTextSelector)
const [selectedRoof, setSelectedRoof] = useState()
const [selectedRoof, setSelectedRoof] = useState(null)
const {
trestleState,
trestleDetail,
dispatch,
raftBaseList,
trestleList,
@ -30,6 +32,10 @@ const Trestle = forwardRef((props, ref) => {
setEavesMargin,
setRidgeMargin,
setKerabaMargin,
lengthBase,
setLengthBase,
hajebichi,
setHajebichi,
cvrYn,
cvrChecked,
snowGdPossYn,
@ -43,46 +49,84 @@ const Trestle = forwardRef((props, ref) => {
})
const selectedModules = useRecoilValue(selectedModuleState) //
// const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState)
const [lengthBase, setLengthBase] = useState(0)
const [hajebichi, setHajebichi] = useState(0)
const [selectedRaftBase, setSelectedRaftBase] = useState(null)
const [selectedTrestle, setSelectedTrestle] = useState(null)
const [selectedConstMthd, setSelectedConstMthd] = useState(null)
const [selectedConstruction, setSelectedConstruction] = useState(null)
const [selectedRoofBase, setSelectedRoofBase] = useState(null)
const { managementState } = useContext(GlobalDataContext)
const { restoreModuleInstArea } = useModuleBasicSetting()
const [flag, setFlag] = useState(false)
const tempModuleSelectionData = useRef(null)
useEffect(() => {
if (roofs && !selectedRoof) {
setSelectedRoof(roofs[0])
}
//
restoreModuleInstArea()
}, [roofs])
useEffect(() => {
if (flag && moduleSelectionData) {
if (JSON.stringify(tempModuleSelectionData.current) === JSON.stringify(moduleSelectionData)) {
setTabNum(tabNum + 1)
}
}
}, [flag, moduleSelectionData])
useEffect(() => {
if (selectedRoof) {
dispatch({ type: 'SET_INITIALIZE', roof: { ...selectedRoof, moduleTpCd: selectedModules.itemTp } })
if (moduleSelectionData?.roofConstructions?.length >= selectedRoof.index + 1) {
const { construction, trestle, trestleDetail } = moduleSelectionData?.roofConstructions[selectedRoof.index]
dispatch({
type: 'SET_INITIALIZE',
roof: { common: moduleSelectionData.common, module: moduleSelectionData.module, construction, trestle, trestleDetail, ...selectedRoof },
})
} else {
dispatch({ type: 'SET_INITIALIZE', roof: { ...selectedRoof, common: moduleSelectionData.common, module: moduleSelectionData.module } })
}
}
}, [selectedRoof])
useEffect(() => {
if (raftBaseList.length > 0) setSelectedRaftBase(raftBaseList.find((raft) => raft.clCode === trestleState?.raftBaseCd) ?? null)
if (raftBaseList.length > 0) {
setSelectedRaftBase(raftBaseList.find((raft) => raft.clCode === trestleState?.raftBaseCd) ?? null)
} else {
setSelectedRaftBase(null)
}
}, [raftBaseList])
useEffect(() => {
if (trestleList.length > 0) setSelectedTrestle(trestleList.find((trestle) => trestle.trestleMkrCd === trestleState?.trestleMkrCd) ?? null)
if (trestleList.length > 0) {
setSelectedTrestle(trestleList.find((trestle) => trestle.trestleMkrCd === trestleState?.trestleMkrCd) ?? null)
} else {
setSelectedTrestle(null)
}
}, [trestleList])
useEffect(() => {
if (roofBaseList.length > 0) setSelectedRoofBase(roofBaseList.find((roofBase) => roofBase.roofBaseCd === trestleState?.roofBaseCd) ?? null)
if (roofBaseList.length > 0) {
setSelectedRoofBase(roofBaseList.find((roofBase) => roofBase.roofBaseCd === trestleState?.roofBaseCd) ?? null)
} else {
setSelectedRoofBase(null)
}
}, [roofBaseList])
useEffect(() => {
if (constMthdList.length > 0) setSelectedConstMthd(constMthdList.find((constMthd) => constMthd.constMthdCd === trestleState?.constMthdCd) ?? null)
if (constMthdList.length > 0) {
setSelectedConstMthd(constMthdList.find((constMthd) => constMthd.constMthdCd === trestleState?.constMthdCd) ?? null)
} else {
setSelectedConstMthd(null)
}
}, [constMthdList])
useEffect(() => {
if (constructionList.length > 0) {
setSelectedConstruction(constructionList.find((construction) => construction.constTp === trestleState?.constTp) ?? null)
setSelectedConstruction(constructionList.find((construction) => construction.constTp === trestleState?.construction?.constTp) ?? null)
} else {
setSelectedConstruction(null)
}
}, [constructionList])
@ -118,7 +162,7 @@ const Trestle = forwardRef((props, ref) => {
roof: {
moduleTpCd: selectedModules.itemTp ?? '',
roofMatlCd: selectedRoof?.roofMatlCd ?? '',
raftBaseCd: trestleState.raftBaseCd ?? '',
raftBaseCd: selectedRaftBase?.clCode,
trestleMkrCd: e.trestleMkrCd,
},
})
@ -131,8 +175,8 @@ const Trestle = forwardRef((props, ref) => {
roof: {
moduleTpCd: selectedModules.itemTp ?? '',
roofMatlCd: selectedRoof?.roofMatlCd ?? '',
raftBaseCd: trestleState.raftBaseCd ?? '',
trestleMkrCd: trestleState.trestleMkrCd,
raftBaseCd: selectedRaftBase?.clCode,
trestleMkrCd: selectedTrestle.trestleMkrCd,
constMthdCd: e.constMthdCd,
},
})
@ -145,9 +189,9 @@ const Trestle = forwardRef((props, ref) => {
roof: {
moduleTpCd: selectedModules.itemTp ?? '',
roofMatlCd: selectedRoof?.roofMatlCd ?? '',
raftBaseCd: trestleState.raftBaseCd ?? '',
trestleMkrCd: trestleState.trestleMkrCd,
constMthdCd: trestleState.constMthdCd,
raftBaseCd: selectedRaftBase?.clCode,
trestleMkrCd: selectedTrestle.trestleMkrCd,
constMthdCd: selectedConstMthd.constMthdCd,
roofBaseCd: e.roofBaseCd,
illuminationTp: managementState?.surfaceTypeValue ?? '',
instHt: managementState?.installHeight ?? '',
@ -158,26 +202,6 @@ const Trestle = forwardRef((props, ref) => {
},
})
}
const handleChangeRoofMaterial = (index) => {
const newAddedRoofs = roofs.map((roof, i) => {
if (i === selectedRoof.index) {
return {
...selectedRoof,
...trestleState,
eavesMargin,
ridgeMargin,
kerabaMargin,
cvrYn,
snowGdPossYn,
cvrChecked,
snowGdChecked,
}
}
return { ...roof }
})
setRoofs(newAddedRoofs)
setSelectedRoof(newAddedRoofs[index])
}
const handleConstruction = (index) => {
if (constructionList[index]?.constPossYn === 'Y') {
@ -186,21 +210,21 @@ const Trestle = forwardRef((props, ref) => {
roof: {
moduleTpCd: selectedModules.itemTp ?? '',
roofMatlCd: selectedRoof?.roofMatlCd ?? '',
raftBaseCd: trestleState.raftBaseCd ?? '',
trestleMkrCd: trestleState.trestleMkrCd,
constMthdCd: trestleState.constMthdCd,
roofBaseCd: trestleState.roofBaseCd,
raftBaseCd: selectedRaftBase?.clCode,
trestleMkrCd: selectedTrestle.trestleMkrCd,
constMthdCd: selectedConstMthd.constMthdCd,
roofBaseCd: selectedRoofBase.roofBaseCd,
illuminationTp: managementState?.surfaceTypeValue ?? '',
instHt: managementState?.installHeight ?? '',
stdWindSpeed: managementState?.standardWindSpeedId ?? '',
stdSnowLd: +managementState?.verticalSnowCover ?? '',
inclCd: selectedRoof?.pitch.toString() ?? 0,
inclCd: selectedRoof?.pitch ?? 0,
roofPitch: Math.round(selectedRoof?.roofPchBase ?? 0),
constTp: constructionList[index].constTp,
snowGdPossYn: constructionList[index].snowGdPossYn,
cvrYn: constructionList[index].cvrYn,
mixMatlNo: selectedModules.mixMatlNo,
workingWidth: selectedRoof?.length.toString() ?? '',
// snowGdPossYn: constructionList[index].snowGdPossYn,
// cvrYn: constructionList[index].cvrYn,
workingWidth: selectedRoof?.length?.toString() ?? '',
},
})
@ -211,93 +235,254 @@ const Trestle = forwardRef((props, ref) => {
}
}
const isComplete = () => {
const handleChangeRoofMaterial = (index) => {
const newAddedRoofs = roofs.map((roof, i) => {
if (i === selectedRoof.index) {
return {
...selectedRoof,
hajebichi,
lenBase: lengthBase,
eavesMargin,
ridgeMargin,
kerabaMargin,
roofIndex: selectedRoof.index,
trestle: {
hajebichi: hajebichi,
length: lengthBase,
...selectedRaftBase,
...selectedTrestle,
...selectedConstMthd,
...selectedRoofBase,
},
construction: {
...constructionList.find((data) => data.constTp === trestleState.constTp),
cvrYn: cvrYn,
snowGdPossYn: snowGdPossYn,
cvrChecked: cvrChecked,
snowGdChecked: snowGdChecked,
},
trestleDetail: trestleDetail,
}
}
return roof
})
setRoofs(newAddedRoofs)
setSelectedRoof(newAddedRoofs[index])
}
const isComplete = async () => {
const newAddedRoofs = roofs.map((roof, i) => {
if (i === selectedRoof?.index) {
return {
...selectedRoof,
...trestleState,
length: lengthBase,
eavesMargin,
ridgeMargin,
kerabaMargin,
cvrYn,
snowGdPossYn,
cvrChecked,
snowGdChecked,
roofIndex: roof.index,
trestle: {
length: lengthBase,
hajebichi: hajebichi,
...selectedRaftBase,
...selectedTrestle,
...selectedConstMthd,
...selectedRoofBase,
},
construction: {
...constructionList.find((data) => data.constTp === trestleState.constTp),
cvrYn,
snowGdPossYn,
cvrChecked,
snowGdChecked,
setupCover: cvrChecked,
setupSnowCover: snowGdChecked,
},
trestleDetail: trestleDetail,
}
}
return { ...roof }
return roof
})
let result = true
newAddedRoofs.forEach((roof) => {
if (roof.eavesMargin && roof.ridgeMargin && roof.kerabaMargin) {
return true
console.log(newAddedRoofs)
for (let i = 0; i < newAddedRoofs.length; i++) {
const roof = newAddedRoofs[i]
if (!roof.trestle?.trestleMkrCd) {
Swal.fire({
title: getMessage('modal.module.basic.settting.module.error1', [roof.nameJp]), // .
icon: 'warning',
})
result = false
return false
}
if (!roof.trestleMkrCd) result = false
if (!roof.constMthdCd) result = false
if (!roof.roofBaseCd) result = false
if (!roof.constTp) result = false
if (selectedRoof.lenAuth === 'C') {
if (!trestleState?.lengthBase) result = false
if (!roof.trestle?.constMthdCd) {
Swal.fire({
title: getMessage('modal.module.basic.settting.module.error2', [roof.nameJp]), // .
icon: 'warning',
})
result = false
return false
}
if (['C', 'R'].includes(selectedRoof.raftAuth)) {
if (!roof.raftBaseCd) result = false
if (!roof.trestle?.roofBaseCd) {
Swal.fire({
title: getMessage('modal.module.basic.settting.module.error3', [roof.nameJp]), // .
icon: 'warning',
})
result = false
return false
}
if (!roof.construction?.constTp) {
Swal.fire({
title: getMessage('modal.module.basic.settting.module.error4', [roof.nameJp]), // .
icon: 'warning',
})
result = false
return false
}
if (['C', 'R'].includes(selectedRoof.roofPchAuth)) {
if (!roof.roofPchBase) result = false
if (roof.lenAuth === 'C') {
if (!roof.trestle?.length) {
Swal.fire({
title: getMessage('modal.module.basic.settting.module.error5', [roof.nameJp]), // L .
icon: 'warning',
})
result = false
return false
}
}
if (['C', 'R'].includes(roof.raftAuth)) {
if (!roof?.raftBaseCd) {
Swal.fire({
title: getMessage('modal.module.basic.settting.module.error6', [roof.nameJp]), // .
icon: 'warning',
})
result = false
return false
}
}
})
console.log('newAddedRoofs', newAddedRoofs)
if (['C', 'R'].includes(roof.roofPchAuth)) {
if (!roof?.roofPchBase) {
Swal.fire({
title: getMessage('modal.module.basic.settting.module.error7', [roof.nameJp]), // .
icon: 'warning',
})
result = false
return false
}
}
if (!roof?.eavesMargin || !roof?.ridgeMargin || !roof?.kerabaMargin) {
Swal.fire({
title: getMessage('modal.module.basic.settting.module.error8', [roof.nameJp]), // .
icon: 'warning',
})
result = false
return false
}
if (roof.trestle.trestleMkrCd !== 'NO_DATA') {
//
if (roof.trestleDetail?.eaveIntvl > roof.eavesMargin) {
Swal.fire({
title: getMessage('modal.module.basic.settting.module.error9', [roof.trestleDetail?.eaveIntvl, roof.nameJp]), // {0}mm .
icon: 'warning',
})
result = false
return false
}
if (roof.trestleDetail?.ridgeIntvl > roof.ridgeMargin) {
Swal.fire({
title: getMessage('modal.module.basic.settting.module.error10', [roof.trestleDetail?.ridgeIntvl, roof.nameJp]), // {0}mm .
icon: 'warning',
})
result = false
return false
}
if (roof.trestleDetail?.kerabaIntvl > roof.kerabaMargin) {
Swal.fire({
title: getMessage('modal.module.basic.settting.module.error11', [roof.trestleDetail?.kerabaIntvl, roof.nameJp]), // {0}mm .
icon: 'warning',
})
result = false
return false
}
}
}
if (result) {
setRoofs(newAddedRoofs)
const newRoofs = newAddedRoofs.map((roof) => {
const { addRoof, construction, trestle, trestleDetail, roofConstructions, ...rest } = roof
return rest
})
setModuleSelectionData({
...moduleSelectionData,
roofConstructions: newAddedRoofs.map((roof) => {
return {
addRoof: {
...roof.addRoof,
},
roofConstructions: newAddedRoofs.map((roof, index) => ({
roofIndex: newRoofs[index].index,
trestle: roof.trestle,
addRoof: newRoofs[index],
construction: roof.construction,
trestleDetail: roof.trestleDetail,
})),
})
setFlag(true)
tempModuleSelectionData.current = {
...moduleSelectionData,
roofConstructions: newAddedRoofs.map((roof, index) => ({
roofIndex: newRoofs[index].index,
trestle: roof.trestle,
addRoof: newRoofs[index],
construction: roof.construction,
trestleDetail: roof.trestleDetail,
})),
}
const updatePromises = [
// new Promise((resolve) => {
// resolve()
// }),
new Promise((resolve) => {
setRoofs(newRoofs)
resolve()
}),
new Promise((resolve) => {
const roofConstruction = newAddedRoofs.map((roof, index) => ({
roofIndex: newRoofs[index].index,
addRoof: newRoofs[index],
trestle: {
...roof.trestle,
},
construction: {
...roof.construction,
},
}
}),
})
trestleTrigger({
roofConstruction: newAddedRoofs.map((roof) => {
return {
roofIndex: roof.index,
addRoof: {
...roof,
},
trestle: {
...selectedTrestle,
raftBaseCd: roof.raftBaseCd,
},
construction: {
...constructionList.find((construction) => trestleState.constTp === construction.constTp),
// ...constructionList.find((construction) => newAddedRoofs[index].construction.constTp === construction.constTp),
...roof.construction,
roofIndex: roof.index,
setupCover: roof.cvrYn === 'Y',
setupSnowCover: roof.snowGdYn === 'Y',
selectedIndex: roof.index,
},
}
trestleDetail: roof.trestleDetail,
}))
trestleTrigger({
roofConstruction,
})
setRoofsStore(roofConstruction)
resolve()
}),
})
]
await Promise.all(updatePromises)
return true
}
return result
return false
}
const onMarginCheck = (target, data) => {}
useImperativeHandle(ref, () => ({
isComplete,
}))
@ -330,7 +515,7 @@ const Trestle = forwardRef((props, ref) => {
<input
type="text"
className="input-origin block"
value={trestleState?.lengthBase}
value={lengthBase}
onChange={(e) => setLengthBase(e.target.value)}
disabled={selectedRoof.lenAuth === 'R'}
/>
@ -371,7 +556,7 @@ const Trestle = forwardRef((props, ref) => {
type="text"
className="input-origin block"
disabled={selectedRoof.roofPchAuth === 'R'}
onChange={(e) => handleHajebichiAndLength(e, 'hajebichi')}
onChange={(e) => setHajebichi(e.target.value)}
value={hajebichi}
/>
</div>
@ -469,7 +654,7 @@ const Trestle = forwardRef((props, ref) => {
<input
type="checkbox"
id={`ch02`}
disabled={!trestleState?.snowGdPossYn || trestleState?.snowGdPossYn === 'N'}
disabled={!snowGdPossYn || snowGdPossYn === 'N'}
checked={snowGdChecked || false}
// onChange={() => dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, snowGdChecked: !trestleState.snowGdChecked } })}
onChange={() => setSnowGdChecked(!snowGdChecked)}
@ -490,7 +675,7 @@ const Trestle = forwardRef((props, ref) => {
className="input-origin block"
value={eavesMargin ?? 0}
// onChange={(e) => dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, eavesMargin: e.target.value } })}
onChange={(e) => setEavesMargin(e.target.value)}
onChange={(e) => setEavesMargin(+e.target.value)}
/>
</div>
<span className="thin">mm</span>
@ -503,7 +688,7 @@ const Trestle = forwardRef((props, ref) => {
className="input-origin block"
value={ridgeMargin ?? 0}
// onChange={(e) => dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, ridgeMargin: e.target.value } })}
onChange={(e) => setRidgeMargin(e.target.value)}
onChange={(e) => setRidgeMargin(+e.target.value)}
/>
</div>
<span className="thin">mm</span>
@ -516,7 +701,7 @@ const Trestle = forwardRef((props, ref) => {
className="input-origin block"
value={kerabaMargin ?? 0}
// onChange={(e) => dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, kerabaMargin: e.target.value } })}
onChange={(e) => setKerabaMargin(e.target.value)}
onChange={(e) => setKerabaMargin(+e.target.value)}
/>
</div>
<span className="thin">mm</span>

View File

@ -33,14 +33,6 @@ const PitchPlacement = forwardRef((props, refs) => {
setSelectedItems({ ...selectedItems, [e.target.name]: e.target.checked })
}
const moduleData = {
header: [
{ type: 'check', name: '', prop: 'check', width: 70 },
{ type: 'color-box', name: getMessage('module'), prop: 'module' },
{ type: 'text', name: `${getMessage('output')} (W)`, prop: 'output', width: 70 },
],
}
//
useEffect(() => {
const checkedModuleIds = Object.keys(selectedItems).filter((key) => selectedItems[key])
@ -105,87 +97,91 @@ const PitchPlacement = forwardRef((props, refs) => {
return (
<>
<div className="module-table-box mb10">
<div className="module-table-inner">
<div className="roof-module-table">
<table>
<thead>
<tr>
{moduleData.header.map((data) => (
<th key={data.prop} style={{ width: data.width ? data.width : '' }}>
{data.type === 'check' ? (
<div className="d-check-box no-text pop">
<input type="checkbox" id="ch01" disabled />
<label htmlFor="ch01"></label>
</div>
) : (
data.name
)}
<div className="hexagonal-flex-wrap">
<div className="module-table-box ">
<div className="module-table-inner">
<div className="roof-module-table">
<table>
<thead>
<tr>
<th style={{ width: '70px' }}>
<div className="d-check-box no-text pop">
<input type="checkbox" id="ch01" disabled />
<label htmlFor="ch01"></label>
</div>
</th>
))}
</tr>
</thead>
<tbody>
{selectedModules.itemList &&
selectedModules.itemList.map((item, index) => (
<tr key={index}>
<td className="al-c">
<div className="d-check-box no-text pop">
<input
type="checkbox"
id={item.itemId}
name={item.itemId}
checked={selectedItems[item.itemId]}
onChange={handleSelectedItem}
/>
<label htmlFor={item.itemId}></label>
</div>
</td>
<td>
<div className="color-wrap">
<span className="color-box" style={{ backgroundColor: item.color }}></span>
<span className="name">{item.itemNm}</span>
</div>
</td>
<td className="al-r">{item.wpOut}</td>
</tr>
))}
</tbody>
</table>
<th>{getMessage('module')}</th>
</tr>
</thead>
<tbody>
{selectedModules.itemList &&
selectedModules.itemList.map((item, index) => (
<tr key={index}>
<td className="al-c">
<div className="d-check-box no-text pop">
<input
type="checkbox"
id={item.itemId}
name={item.itemId}
checked={selectedItems[item.itemId]}
onChange={handleSelectedItem}
/>
<label htmlFor={item.itemId}></label>
</div>
</td>
<td>
<div className="color-wrap">
<span className="color-box" style={{ backgroundColor: item.color }}></span>
<span className="name">{item.itemNm}</span>
</div>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
</div>
<div className="module-table-box mb10">
<div className="module-table-inner">
<div className="hexagonal-wrap">
<div className="hexagonal-item">
<div className="bold-font">{getMessage('modal.module.basic.setting.pitch.module.placement.standard.setting')}</div>
</div>
<div className="hexagonal-item">
<div className="pop-form-radio">
<div className="d-check-radio pop">
<input
type="radio"
name="radio01"
id="ra01"
value={'south'}
defaultChecked={setupLocation === 'south'}
onClick={handleSetupLocation}
/>
<label htmlFor="ra01">{getMessage('modal.module.basic.setting.pitch.module.placement.standard.setting.south')}</label>
</div>
<div className="d-check-radio pop">
<input
type="radio"
name="radio01"
id="ra02"
value={'excreta'}
defaultChecked={setupLocation === 'excreta'}
onClick={handleSetupLocation}
/>
<label htmlFor="ra02">{getMessage('modal.module.basic.setting.pitch.module.placement.standard.setting.select')}</label>
</div>
</div>
<div className="module-table-box non-flex">
<div className="module-table-inner">
<div className="roof-module-table">
<table>
<thead>
<tr>
<th>{getMessage('modal.module.basic.setting.pitch.module.placement.standard.setting')}</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div className="hexagonal-radio-wrap">
<div className="d-check-radio pop mb10">
<input
type="radio"
name="radio01"
id="ra01"
value={'south'}
defaultChecked={setupLocation === 'south'}
onClick={handleSetupLocation}
/>
<label htmlFor="ra01">{getMessage('modal.module.basic.setting.pitch.module.placement.standard.setting.south')}</label>
</div>
<div className="d-check-radio pop">
<input
type="radio"
name="radio01"
id="ra02"
value={'excreta'}
defaultChecked={setupLocation === 'excreta'}
onClick={handleSetupLocation}
/>
<label htmlFor="ra02">{getMessage('modal.module.basic.setting.pitch.module.placement.standard.setting.select')}</label>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>

View File

@ -100,7 +100,7 @@ export default function ObjectSetting({ id, pos = { x: 50, y: 230 } }) {
]
return (
<WithDraggable isShow={true} pos={pos} className="lrr" style={{ visibility: isHidden ? 'hidden' : 'visible' }}>
<WithDraggable isShow={true} pos={pos} className="lrr" isHidden={isHidden}>
<WithDraggable.Header title={getMessage('plan.menu.placement.surface.object')} onClose={() => closePopup(id)} />
<WithDraggable.Body>
<div className="modal-btn-wrap">

View File

@ -16,12 +16,13 @@ import { usePopup } from '@/hooks/usePopup'
import { useState } from 'react'
import { v4 as uuidv4 } from 'uuid'
import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch'
import { useRecoilValue } from 'recoil'
import { useRecoilState, useRecoilValue } from 'recoil'
import { canvasState, currentMenuState } from '@/store/canvasAtom'
import { MENU } from '@/common/common'
import { useTrestle } from '@/hooks/module/useTrestle'
import { usePolygon } from '@/hooks/usePolygon'
import { useOrientation } from '@/hooks/module/useOrientation'
import { settingModalFirstOptionsState } from '@/store/settingAtom'
/**
* 메뉴 처리
@ -36,8 +37,22 @@ export default function useMenu() {
const { deleteAllSurfacesAndObjects } = useSurfaceShapeBatch({})
const { clear: trestleClear, setAllModuleSurfaceIsComplete } = useTrestle()
const { nextStep } = useOrientation()
const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState)
const handleMenu = (type) => {
if (type === 'outline') {
// 지붕 덮개 메뉴의 경우는 복도치수로 적용한다.
setSettingModalFirstOptions((prev) => {
return {
...prev,
dimensionDisplay: prev.dimensionDisplay.map((item, index) => {
if (index === 0) {
return { ...item, selected: true }
} else {
return { ...item, selected: false }
}
}),
}
})
switch (currentMenu) {
case MENU.ROOF_COVERING.EXTERIOR_WALL_LINE:
addPopup(popupId, 1, <WallLineSetting id={popupId} />)
@ -67,6 +82,19 @@ export default function useMenu() {
}
if (type === 'surface') {
// 배치면 메뉴의 경우는 실치수로 적용한다.
setSettingModalFirstOptions((prev) => {
return {
...prev,
dimensionDisplay: prev.dimensionDisplay.map((item, index) => {
if (index === 1) {
return { ...item, selected: true }
} else {
return { ...item, selected: false }
}
}),
}
})
switch (currentMenu) {
// case MENU.BATCH_CANVAS.SLOPE_SETTING:
// addPopup(popupId, 1, <Slope id={popupId} />)
@ -87,6 +115,19 @@ export default function useMenu() {
}
if (type === 'module') {
// 모듈,회로 구성 메뉴의 경우는 실치수로 적용한다.
setSettingModalFirstOptions((prev) => {
return {
...prev,
dimensionDisplay: prev.dimensionDisplay.map((item, index) => {
if (index === 1) {
return { ...item, selected: true }
} else {
return { ...item, selected: false }
}
}),
}
})
switch (currentMenu) {
case MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING:
trestleClear()

View File

@ -130,6 +130,7 @@ export const useEstimateController = (planNo, flag) => {
addFlg: true,
paDispOrder: null,
dispCableFlg: '0',
itemTpCd: '',
},
],
})
@ -321,6 +322,7 @@ export const useEstimateController = (planNo, flag) => {
}
})
if (delCnt === estimateData.itemList.length) {
itemFlg = false
setIsGlobalLoading(false)
return swalFire({ text: getMessage('estimate.detail.save.requiredItem'), type: 'alert', icon: 'warning' })
}

File diff suppressed because it is too large Load Diff

View File

@ -13,26 +13,22 @@ import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting'
export function useModuleSelection(props) {
const canvas = useRecoilValue(canvasState)
const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext)
const [roughnessCodes, setRoughnessCodes] = useState([]) //면조도 목록
const [windSpeedCodes, setWindSpeedCodes] = useState([]) //기준풍속 목록
const [moduleList, setModuleList] = useState([{}]) //모듈 목록
const [selectedSurfaceType, setSelectedSurfaceType] = useState({}) //선택된 면조도
const [installHeight, setInstallHeight] = useState(managementState?.installHeight) //설치 높이
const [standardWindSpeed, setStandardWindSpeed] = useState() //기준풍속
const [verticalSnowCover, setVerticalSnowCover] = useState(managementState?.verticalSnowCover) //수직적설량
const [selectedModules, setSelectedModules] = useRecoilState(selectedModuleState) //선택된 모듈
const [margin, setMargin] = useState(100)
const [moduleSelectionInitParams, setModuleSelectionInitParams] = useRecoilState(moduleSelectionInitParamsState) //모듈 기본 데이터 ex) 면조도, 높이등등
const { getModuleTypeItemList } = useMasterController()
const { findCommonCode } = useCommonCode()
const resetStatisticsData = useResetRecoilState(moduleStatisticsState)
const { restoreModuleInstArea } = useModuleBasicSetting()
const bindInitData = () => {
console.log('bindInitData', managementState)
setInstallHeight(managementState?.installHeight)
setStandardWindSpeed(managementState?.standardWindSpeedId)
setVerticalSnowCover(managementState?.verticalSnowCover)
@ -96,7 +92,7 @@ export function useModuleSelection(props) {
getModuleData(roofsIds)
//모듈설치면 초기화
restoreModuleInstArea()
// restoreModuleInstArea()
resetStatisticsData()
}, [])

View File

@ -2,14 +2,13 @@ import { use, useContext, useEffect, useReducer, useState } from 'react'
import { useCommonCode } from '../common/useCommonCode'
import { useMasterController } from '../common/useMasterController'
import { selectedModuleState } from '@/store/selectedModuleOptions'
import { useRecoilValue } from 'recoil'
import { useRecoilState, useRecoilValue } from 'recoil'
import { GlobalDataContext } from '@/app/GlobalDataProvider'
import { popSpinnerState } from '@/store/popupAtom'
const RAFT_BASE_CODE = '203800'
const trestleReducer = (state, action) => {
console.log('🚀 ~ trestleReducer ~ state:', state)
console.log('🚀 ~ trestleReducer ~ action:', action)
switch (action.type) {
case 'SET_RAFT_BASE':
case 'SET_TRESTLE_MAKER':
@ -21,26 +20,26 @@ const trestleReducer = (state, action) => {
...action.roof,
}
case 'SET_INITIALIZE':
console.log('SET_INITIALIZE')
return {
moduleTpCd: action.roof.moduleTpCd ?? '',
roofMatlCd: action.roof.roofMatlCd ?? '',
raftBaseCd: action.roof.raftBaseCd ?? null,
trestleMkrCd: action.roof.trestleMkrCd ?? null,
constMthdCd: action.roof.constMthdCd ?? null,
constTp: action.roof.constTp ?? null,
roofBaseCd: action.roof.roofBaseCd ?? null,
moduleTpCd: action.roof.module?.itemTp ?? '',
roofMatlCd: action.roof?.roofMatlCd ?? '',
hajebichi: action.roof?.hajebichi ?? 0,
raftBaseCd: action.roof?.raftBaseCd ?? null,
trestleMkrCd: action.roof.trestle?.trestleMkrCd ?? null,
constMthdCd: action.roof.trestle?.constMthdCd ?? null,
constTp: action.roof.construction?.constTp ?? null,
roofBaseCd: action.roof.trestle?.roofBaseCd ?? null,
workingWidth: action.roof.workingWidth ?? 0,
lengthBase: action.roof.length ?? 0,
illuminationTp: action.roof.illuminationTp ?? null,
instHt: action.roof.instHt ?? null,
stdWindSpeed: action.roof.stdWindSpeed ?? null,
stdSnowLd: action.roof.stdSnowLd ?? null,
inclCd: action.roof.inclCd ?? null,
roofPitch: action.roof.roofPchBase ?? 0,
eavesMargin: action.roof.eavesMargin ?? null,
ridgeMargin: action.roof.ridgeMargin ?? null,
kerabaMargin: action.roof.kerabaMargin ?? null,
lengthBase: action.roof?.length ?? 0,
illuminationTp: action.roof.common?.illuminationTp ?? null,
instHt: action.roof.common?.instHt ?? null,
stdWindSpeed: action.roof.common?.stdWindSpeed ?? null,
stdSnowLd: action.roof.common?.stdSnowLd ?? null,
inclCd: action.roof?.pitch ?? null,
roofPitch: action.roof?.roofPchBase ?? 0,
eavesMargin: action.roof?.eavesMargin ?? null,
ridgeMargin: action.roof?.ridgeMargin ?? null,
kerabaMargin: action.roof?.kerabaMargin ?? null,
}
default:
return state
@ -56,6 +55,9 @@ export function useModuleTrestle(props) {
const [roofBaseList, setRoofBaseList] = useState([])
const [constructionList, setConstructionList] = useState([])
const { getTrestleList, getConstructionList, getTrestleDetailList } = useMasterController()
const [lengthBase, setLengthBase] = useState(0)
const [hajebichi, setHajebichi] = useState(0)
const [cvrYn, setCvrYn] = useState('N')
const [cvrChecked, setCvrChecked] = useState(false)
const [snowGdPossYn, setSnowGdPossYn] = useState('N')
@ -64,6 +66,8 @@ export function useModuleTrestle(props) {
const [ridgeMargin, setRidgeMargin] = useState(0)
const [kerabaMargin, setKerabaMargin] = useState(0)
const [trestleState, dispatch] = useReducer(trestleReducer, null)
const [trestleDetail, setTrestleDetail] = useState(null)
const [popSpinnerStore, setPopSpinnerStore] = useRecoilState(popSpinnerState)
useEffect(() => {
const raftCodeList = findCommonCode(RAFT_BASE_CODE)
@ -73,103 +77,138 @@ export function useModuleTrestle(props) {
setConstMthdList([])
setRoofBaseList([])
setConstructionList([])
// setEavesMargin(selectedRoof?.addRoof?.eavesMargin ?? 0)
// setRidgeMargin(selectedRoof?.addRoof?.ridgeMargin ?? 0)
// setKerabaMargin(selectedRoof?.addRoof?.kerabaMargin ?? 0)
setHajebichi(selectedRoof?.hajebichi ?? 0)
setEavesMargin(selectedRoof?.eavesMargin ?? 0)
setRidgeMargin(selectedRoof?.ridgeMargin ?? 0)
setKerabaMargin(selectedRoof?.kerabaMargin ?? 0)
setCvrYn(selectedRoof?.cvrYn ?? 'N')
setCvrChecked(selectedRoof?.cvrChecked ?? false)
setSnowGdPossYn(selectedRoof?.snowGdPossYn ?? 'N')
setSnowGdChecked(selectedRoof?.snowGdChecked ?? false)
setLengthBase(Math.round(selectedRoof?.length ?? 0))
setCvrYn(selectedRoof?.construction?.cvrYn ?? 'N')
setCvrChecked(selectedRoof?.construction?.cvrChecked ?? false)
setSnowGdPossYn(selectedRoof?.construction?.snowGdPossYn ?? 'N')
setSnowGdChecked(selectedRoof?.construction?.snowGdChecked ?? false)
setTrestleDetail(selectedRoof?.trestleDetail)
}, [selectedRoof])
useEffect(() => {
if (trestleState) {
console.log('🚀 ~ useEffect ~ trestleState:', trestleState)
handleSetTrestleList()
if (!trestleState.trestleMkrCd) {
if (!trestleState?.trestleMkrCd) {
setConstMthdList([])
setRoofBaseList([])
setConstructionList([])
setTrestleDetail(null)
return
}
handleSetConstMthdList()
if (!trestleState.constMthdCd) {
if (!trestleState?.constMthdCd) {
setRoofBaseList([])
setConstructionList([])
setTrestleDetail(null)
return
}
handleSetRoofBaseList()
if (!trestleState.roofBaseCd) {
if (!trestleState?.roofBaseCd) {
setConstructionList([])
setTrestleDetail(null)
return
}
handleSetConstructionList()
if (!trestleState.constTp) {
if (!trestleState?.constTp) {
setTrestleDetail(null)
return
}
if (!trestleState.eavesMargin) {
if (!trestleState?.eavesMargin) {
handleSetTrestleDetailData()
}
}
}, [trestleState])
const handleSetTrestleList = () => {
setPopSpinnerStore(true)
getTrestleList({
moduleTpCd: trestleState.moduleTpCd ?? '',
roofMatlCd: trestleState.roofMatlCd ?? '',
raftBaseCd: trestleState.raftBaseCd ?? '',
}).then((res) => {
if (res?.data) setTrestleList(res.data)
moduleTpCd: trestleState?.moduleTpCd ?? '',
roofMatlCd: trestleState?.roofMatlCd ?? '',
raftBaseCd: trestleState?.raftBaseCd ?? '',
})
.then((res) => {
if (res?.data) setTrestleList(res.data)
setPopSpinnerStore(false)
})
.catch((e) => {
setPopSpinnerStore(false)
})
}
const handleSetConstMthdList = () => {
setPopSpinnerStore(true)
getTrestleList({
moduleTpCd: trestleState.moduleTpCd ?? '',
roofMatlCd: trestleState.roofMatlCd ?? '',
raftBaseCd: trestleState.raftBaseCd ?? '',
trestleMkrCd: trestleState.trestleMkrCd ?? '',
}).then((res) => {
if (res?.data) setConstMthdList(res.data)
moduleTpCd: trestleState?.moduleTpCd ?? '',
roofMatlCd: trestleState?.roofMatlCd ?? '',
raftBaseCd: trestleState?.raftBaseCd ?? '',
trestleMkrCd: trestleState?.trestleMkrCd ?? '',
})
.then((res) => {
if (res?.data) setConstMthdList(res.data)
setPopSpinnerStore(false)
})
.catch((e) => {
setPopSpinnerStore(false)
})
}
const handleSetRoofBaseList = () => {
setPopSpinnerStore(true)
getTrestleList({
moduleTpCd: trestleState.moduleTpCd ?? '',
roofMatlCd: trestleState.roofMatlCd ?? '',
raftBaseCd: trestleState.raftBaseCd ?? '',
trestleMkrCd: trestleState.trestleMkrCd ?? '',
constMthdCd: trestleState.constMthdCd ?? '',
}).then((res) => {
if (res?.data) setRoofBaseList(res.data)
moduleTpCd: trestleState?.moduleTpCd ?? '',
roofMatlCd: trestleState?.roofMatlCd ?? '',
raftBaseCd: trestleState?.raftBaseCd ?? '',
trestleMkrCd: trestleState?.trestleMkrCd ?? '',
constMthdCd: trestleState?.constMthdCd ?? '',
})
.then((res) => {
if (res?.data) setRoofBaseList(res.data)
setPopSpinnerStore(false)
})
.catch((e) => {
setPopSpinnerStore(false)
})
}
const handleSetConstructionList = () => {
setPopSpinnerStore(true)
getConstructionList({
moduleTpCd: trestleState.moduleTpCd ?? '',
roofMatlCd: trestleState.roofMatlCd ?? '',
trestleMkrCd: trestleState.trestleMkrCd ?? '',
constMthdCd: trestleState.constMthdCd ?? '',
roofBaseCd: trestleState.roofBaseCd ?? '',
moduleTpCd: trestleState?.moduleTpCd ?? '',
roofMatlCd: trestleState?.roofMatlCd ?? '',
trestleMkrCd: trestleState?.trestleMkrCd ?? '',
constMthdCd: trestleState?.constMthdCd ?? '',
roofBaseCd: trestleState?.roofBaseCd ?? '',
illuminationTp: trestleState.illuminationTp ?? '',
instHt: trestleState.instHt ?? '',
stdWindSpeed: trestleState.stdWindSpeed ?? '',
stdSnowLd: trestleState.stdSnowLd ?? '',
inclCd: trestleState.inclCd ?? '',
raftBaseCd: trestleState.raftBaseCd ?? '',
roofPitch: trestleState.roofPitch ?? '',
}).then((res) => {
if (res?.data) setConstructionList(res.data)
roofPitch: Math.round(trestleState.roofPitch) ?? '',
})
.then((res) => {
if (res?.data) setConstructionList(res.data)
setPopSpinnerStore(false)
})
.catch((e) => {
setPopSpinnerStore(false)
})
}
const handleSetTrestleDetailData = () => {
setPopSpinnerStore(true)
getTrestleDetailList([
{
moduleTpCd: trestleState.moduleTpCd ?? '',
@ -187,27 +226,35 @@ export function useModuleTrestle(props) {
roofPitch: trestleState.roofPitch ?? '',
workingWidth: trestleState.workingWidth ?? '',
},
]).then((res) => {
if (res.length > 0) {
if (!res[0].data) return
setEavesMargin(res[0].data.eaveIntvl)
setRidgeMargin(res[0].data.ridgeIntvl)
setKerabaMargin(res[0].data.kerabaIntvl)
// dispatch({
// type: 'SET_TRESTLE_DETAIL',
// roof: {
// ...trestleState,
// eavesMargin: res[0].data.eaveIntvl,
// ridgeMargin: res[0].data.ridgeIntvl,
// kerabaMargin: res[0].data.kerabaIntvl,
// },
// })
}
})
])
.then((res) => {
if (res.length > 0) {
if (!res[0].data) return
setEavesMargin(res[0].data.eaveIntvl)
setRidgeMargin(res[0].data.ridgeIntvl)
setKerabaMargin(res[0].data.kerabaIntvl)
setTrestleDetail(res[0].data)
// dispatch({
// type: 'SET_TRESTLE_DETAIL',
// roof: {
// ...trestleState,
// eavesMargin: res[0].data.eaveIntvl,
// ridgeMargin: res[0].data.ridgeIntvl,
// kerabaMargin: res[0].data.kerabaIntvl,
// },
// })
}
setPopSpinnerStore(false)
})
.catch((e) => {
setPopSpinnerStore(false)
})
}
return {
trestleState,
trestleDetail,
dispatch,
raftBaseList,
trestleList,
@ -219,16 +266,20 @@ export function useModuleTrestle(props) {
handleSetRoofBaseList,
handleSetConstructionList,
handleSetTrestleDetailData,
lengthBase,
setLengthBase,
hajebichi,
setHajebichi,
cvrYn,
cvrChecked,
snowGdPossYn,
snowGdChecked,
eavesMargin,
ridgeMargin,
kerabaMargin,
setEavesMargin,
setRidgeMargin,
setKerabaMargin,
cvrYn,
cvrChecked,
snowGdPossYn,
snowGdChecked,
setCvrYn,
setCvrChecked,
setSnowGdPossYn,

View File

@ -22,8 +22,8 @@ export function useOrientation() {
})
}, [])*/
const nextStep = () => {
if (isNaN(compasDeg)) {
const nextStep = (compas = compasDeg) => {
if (isNaN(compas)) {
setCompasDeg(0)
}
const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
@ -36,7 +36,7 @@ export function useOrientation() {
roofs.forEach((roof) => {
roof.set({
moduleCompass: isNaN(compasDeg) ? 0 : compasDeg,
moduleCompass: isNaN(compas) ? 0 : compas,
})
drawDirectionArrow(roof)
})

View File

@ -371,11 +371,16 @@ export const useTrestle = () => {
rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0)
)
} else {
//C1C2C3인 경우
let newLeftRowsInfo = normalizeModules(rack.value.moduleTpCd, leftRowsInfo)
return (
rack.value.moduleTpCd === leftRowsInfo.moduleTotalTp &&
rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) &&
Number(rack.value.moduleTpRows1) === leftRowsInfo.rowsInfo[0].count &&
Number(rack.value.moduleTpRows2) === leftRowsInfo.rowsInfo[1].count
rack.value.moduleTpCd === newLeftRowsInfo.moduleTotalTp &&
rack.value.moduleRows === newLeftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) &&
newLeftRowsInfo.rowsInfo.every((row, index) => {
const rackRowCount = Number(rack.value[`moduleTpRows${index + 1}`]) // 동적으로 접근
return rackRowCount === row.count
})
)
}
})?.value.racks
@ -388,11 +393,15 @@ export const useTrestle = () => {
rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0)
)
} else {
let newRightRowsInfo = normalizeModules(rack.value.moduleTpCd, rightRowsInfo)
return (
rack.value.moduleTpCd === rightRowsInfo.moduleTotalTp &&
rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) &&
Number(rack.value.moduleTpRows1) === rightRowsInfo.rowsInfo[0].count &&
Number(rack.value.moduleTpRows2) === rightRowsInfo.rowsInfo[1].count
rack.value.moduleTpCd === newRightRowsInfo.moduleTotalTp &&
rack.value.moduleRows === newRightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) &&
newRightRowsInfo.rowsInfo.every((row, index) => {
const rackRowCount = Number(rack.value[`moduleTpRows${index + 1}`]) // 동적으로 접근
return rackRowCount === row.count
})
)
}
})?.value.racks
@ -405,11 +414,15 @@ export const useTrestle = () => {
rack.value.moduleRows === centerRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0)
)
} else {
let newCenterRowsInfo = normalizeModules(rack.value.moduleTpCd, centerRowsInfo)
return (
rack.value.moduleTpCd === centerRowsInfo.moduleTotalTp &&
rack.value.moduleRows === centerRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) &&
Number(rack.value.moduleTpRows1) === centerRowsInfo.rowsInfo[0].count &&
Number(rack.value.moduleTpRows2) === centerRowsInfo.rowsInfo[1].count
rack.value.moduleTpCd === newCenterRowsInfo.moduleTotalTp &&
rack.value.moduleRows === newCenterRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) &&
newCenterRowsInfo.rowsInfo.every((row, index) => {
const rackRowCount = Number(rack.value[`moduleTpRows${index + 1}`]) // 동적으로 접근
return rackRowCount === row.count
})
)
}
})?.value.racks
@ -500,11 +513,15 @@ export const useTrestle = () => {
rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0)
)
} else {
let newLeftRowsInfo = normalizeModules(rack.value.moduleTpCd, leftRowsInfo)
return (
rack.value.moduleTpCd === leftRowsInfo.moduleTotalTp &&
rack.value.moduleRows === leftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) &&
Number(rack.value.moduleTpRows1) === leftRowsInfo.rowsInfo[0].count &&
Number(rack.value.moduleTpRows2) === leftRowsInfo.rowsInfo[1].count
rack.value.moduleTpCd === newLeftRowsInfo.moduleTotalTp &&
rack.value.moduleRows === newLeftRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) &&
newLeftRowsInfo.rowsInfo.every((row, index) => {
const rackRowCount = Number(rack.value[`moduleTpRows${index + 1}`]) // 동적으로 접근
return rackRowCount === row.count
})
)
}
})?.value.racks
@ -576,11 +593,16 @@ export const useTrestle = () => {
rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0)
)
} else {
// 변환 C1C2만 있는경우 C3 0개로 추가해준다.
let newRightRowsInfo = normalizeModules(rack.value.moduleTpCd, rightRowsInfo)
return (
rack.value.moduleTpCd === rightRowsInfo.moduleTotalTp &&
rack.value.moduleRows === rightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) &&
Number(rack.value.moduleTpRows1) === rightRowsInfo.rowsInfo[0].count &&
Number(rack.value.moduleTpRows2) === rightRowsInfo.rowsInfo[1].count
rack.value.moduleTpCd === newRightRowsInfo.moduleTotalTp &&
rack.value.moduleRows === newRightRowsInfo.rowsInfo.reduce((acc, row) => acc + row.count, 0) &&
newRightRowsInfo.rowsInfo.every((row, index) => {
const rackRowCount = Number(rack.value[`moduleTpRows${index + 1}`]) // 동적으로 접근
return rackRowCount === row.count
})
)
}
})?.value.racks
@ -635,6 +657,31 @@ export const useTrestle = () => {
return { moduleTotalTp, rowsInfo }
}
function normalizeModules(rackTpCd, data) {
// rackTpCd를 숫자를 기준으로 자른다.
const allModules = rackTpCd.match(/[A-Za-z]+\d+/g) || [] // 모든 모듈 유형
// 현재 존재하는 모듈 유형을 추출
const existingModules = data.rowsInfo.map((row) => row.moduleTpCd)
const result = { ...data, rowsInfo: [...data.rowsInfo] }
// 없는 모듈을 추가 (count: 0)
allModules.forEach((module) => {
if (!existingModules.includes(module)) {
result.rowsInfo.push({ moduleTpCd: module, count: 0 })
}
})
// rowsInfo를 C1, C2, C3 순서로 정렬
result.rowsInfo.sort((a, b) => allModules.indexOf(a.moduleTpCd) - allModules.indexOf(b.moduleTpCd))
// moduleTotalTp를 C1C2C3로 설정
result.moduleTotalTp = allModules.join('')
return result
}
// itemList 조회 후 estimateParam에 저장
const getEstimateData = async () => {
const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
@ -661,13 +708,18 @@ export const useTrestle = () => {
})
// trestles 배열에서 null인 경우 제거
const params = { trestles, pcses, modules }
const dblCblTotCnt = getTotalConnectCableCnt()
const params = { trestles, pcses, modules, dblCblTotCnt }
//견적서 itemList 조회
const { data, data2, result } = await getQuotationItem(params)
if (result.resultCode === 'E') {
swalFire({ text: result.resultMsg, icon: 'error' })
clear()
setViewCircuitNumberTexts(true)
setIsGlobalLoading(false)
return
}
@ -1000,9 +1052,7 @@ export const useTrestle = () => {
if (!rackInfos) {
const maxRows = surface.trestleDetail.moduleMaxRows
const maxCols = surface.trestleDetail.moduleMaxCols
const msg = `選択した家で設置可能
モジュールの最大段数は${maxRows}最大列数は${maxCols}です
上限より上部に取り付けたモジュールを削除してください`
const msg = `段数の上限は${maxRows}段です。 上限より上の段には設置できません`
swalFire({ title: msg, type: 'alert' })
throw new Error('rackInfos is null')
}
@ -2131,12 +2181,13 @@ export const useTrestle = () => {
const visited = new Set()
const width = Math.floor(moduleExample.width)
const height = Math.floor(moduleExample.height)
const horizonPadding = 0 // 가로 패딩
const verticalPadding = 0 // 세로 패딩
const horizonPadding = 3 // 가로 패딩
const verticalPadding = 7 // 세로 패딩
function isAdjacent(p1, p2) {
const dx = Math.abs(p1.x - p2.x)
const dy = Math.abs(p1.y - p2.y)
return (
(Math.abs(width + horizonPadding - dx) < 2 && dy < 2) ||
(dx < 2 && Math.abs(dy - height + verticalPadding)) < 2 ||
@ -2168,6 +2219,128 @@ export const useTrestle = () => {
return groups
}
function areConnected(m1, m2, surface) {
/*const m1Fill = m1.fill
const m2Fill = m2.fill
m1.set({ fill: 'red' })
m2.set({ fill: 'blue' })
canvas.renderAll()*/
let sizes = []
const { width: currentWidth, height: currentHeight, moduleInfo: currentModuleInfo } = m1
const { width: neighborWidth, height: neighborHeight, moduleInfo: neighborModuleInfo } = m2
const { moduleTpCd: currentModuleTpCd } = currentModuleInfo
const { moduleTpCd: neighborModuleTpCd } = neighborModuleInfo
const { x: m1X, y: m1Y } = m1.getCenterPoint()
const { x: m2X, y: m2Y } = m2.getCenterPoint()
sizes.push({ width: currentWidth, height: currentHeight })
if (currentModuleTpCd !== neighborModuleTpCd) {
sizes.push({ width: neighborWidth, height: neighborHeight })
}
/*m1.set({ fill: m1Fill })
m2.set({ fill: m2Fill })
canvas.renderAll()*/
return sizes.some(({ width, height }) => {
let maxX
let maxY
let halfMaxX
let halfMaxY
const { direction, trestleDetail } = surface
const { moduleIntvlHor, moduleIntvlVer } = trestleDetail
if (direction === 'south' || direction === 'north') {
maxX = width + moduleIntvlHor / 10
maxY = height + moduleIntvlVer / 10
halfMaxX = moduleIntvlHor / 10
halfMaxY = moduleIntvlVer / 10
if (currentModuleTpCd !== neighborModuleTpCd) {
maxX = currentWidth / 2 + neighborWidth / 2 + moduleIntvlHor / 10
maxY = currentHeight / 2 + neighborHeight / 2 + moduleIntvlVer / 10
}
// console.log(maxX, maxY, halfMaxX, halfMaxY)
if (Math.abs(m1X - m2X) < 1) {
return Math.abs(Math.abs(m1Y - m2Y) - maxY) < 1
} else if (Math.abs(m1Y - m2Y) < 1) {
return Math.abs(Math.abs(m1X - m2X) - maxX) < 1
}
return (
(Math.abs(m1X - m2X) < maxX - moduleIntvlHor / 10 && Math.abs(m1Y - m2Y) < maxY - moduleIntvlVer / 10) ||
(Math.abs(Math.abs(m1X - m2X) - maxX / 2) < halfMaxX + 1 && Math.abs(Math.abs(m1Y - m2Y) - maxY) < halfMaxY + 1) ||
(Math.abs(Math.abs(m1X - m2X) - maxX) < halfMaxX + 1 && Math.abs(Math.abs(m1Y - m2Y) - maxY / 2) < halfMaxY + 1)
)
} else if (direction === 'east' || direction === 'west') {
maxX = height + moduleIntvlHor / 10
maxY = width + moduleIntvlVer / 10
halfMaxX = moduleIntvlVer / 10
halfMaxY = moduleIntvlHor / 10
if (currentModuleTpCd !== neighborModuleTpCd) {
maxX = currentHeight / 2 + neighborHeight / 2 + moduleIntvlVer / 10
maxY = currentWidth / 2 + neighborWidth / 2 + moduleIntvlHor / 10
}
if (Math.abs(m1X - m2X) < 1) {
return Math.abs(Math.abs(m1Y - m2Y) - maxX) < 1
} else if (Math.abs(m1Y - m2Y) < 1) {
return Math.abs(Math.abs(m1X - m2X) - maxY) < 1
}
return (
(Math.abs(m1X - m2X) <= maxY - moduleIntvlVer / 10 && Math.abs(m1Y - m2Y) <= maxX - moduleIntvlHor / 10) ||
(Math.abs(Math.abs(m1X - m2X) - maxY / 2) < halfMaxY + 1 && Math.abs(Math.abs(m1Y - m2Y) - maxX) < halfMaxX + 1) ||
(Math.abs(Math.abs(m1X - m2X) - maxY) < halfMaxY + 1 && Math.abs(Math.abs(m1Y - m2Y) - maxX / 2) < halfMaxX + 1)
)
}
})
}
// 25-04-02 추가
// 그룹화
function groupPoints(modules, surface) {
const groups = []
const visited = new Set()
for (const point of modules) {
const { x: pointX, y: pointY } = point.getCenterPoint()
const key = `${pointX},${pointY}`
if (visited.has(key)) continue
const queue = [point]
const group = []
while (queue.length > 0) {
const current = queue.shift()
const { x: currentX, y: currentY } = current.getCenterPoint()
const currentKey = `${currentX},${currentY}`
if (visited.has(currentKey)) continue
visited.add(currentKey)
group.push(current)
for (const neighbor of modules) {
const { x: neighborX, y: neighborY } = neighbor.getCenterPoint()
const neighborKey = `${neighborX},${neighborY}`
if (!visited.has(neighborKey) && areConnected(current, neighbor, surface)) {
queue.push(neighbor)
}
}
}
groups.push(group)
}
return groups
}
// 각도에 따른 길이 반환
function getTrestleLength(length, degree) {
if (roofSizeSet !== 1) {
@ -2865,5 +3038,82 @@ export const useTrestle = () => {
return surfaces.every((surface) => surface.isComplete)
}
return { apply, getTrestleParams, clear, setViewCircuitNumberTexts, getEstimateData, setAllModuleSurfaceIsComplete, isAllComplete }
const groupByType = (originArr = []) => {
const grouped = {}
const newArr = [...originArr]
// 타입별로 객체들을 분류
for (const item of newArr) {
if (!grouped[item.circuitNumber]) {
grouped[item.circuitNumber] = []
}
grouped[item.circuitNumber].push(item)
}
// 객체를 배열로 변환
return Object.values(grouped)
}
function groupByCircuitAndSurface(arr) {
const circuitGroups = {}
for (const item of arr) {
const { circuitNumber, surfaceId } = item
if (!circuitGroups[circuitNumber]) {
circuitGroups[circuitNumber] = new Map()
}
const surfaceMap = circuitGroups[circuitNumber]
const key = surfaceId
if (!surfaceMap.has(key)) {
surfaceMap.set(key, [])
}
surfaceMap.get(key).push(item)
}
// 결과: circuitNumber별 surface 그룹 수
const result = {}
for (const [circuit, surfaceMap] of Object.entries(circuitGroups)) {
result[circuit] = surfaceMap.size
}
return result
}
// 양단 케이블 구하는 공식
const getTotalConnectCableCnt = () => {
let cnt = 0
const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
const modules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE)
surfaces.forEach((surface) => {
const modules = surface.modules
const groups = groupByType(modules)
groups.forEach((group) => {
const result = groupPoints(group, surface)
cnt += result.length - 1
})
})
const groupByCircuitAndSurfaceCnt = groupByCircuitAndSurface(modules)
Object.keys(groupByCircuitAndSurfaceCnt).forEach((key) => {
cnt += groupByCircuitAndSurfaceCnt[key] - 1
})
return cnt
}
return {
apply,
getTrestleParams,
clear,
setViewCircuitNumberTexts,
getEstimateData,
setAllModuleSurfaceIsComplete,
isAllComplete,
groupCoordinates,
groupPoints,
}
}

View File

@ -123,6 +123,7 @@ export function useCanvasSetting(executeEffect = true) {
const resetModuleSelectionData = useResetRecoilState(moduleSelectionDataState) /* 다음으로 넘어가는 최종 데이터 */
const resetSelectedModules = useResetRecoilState(selectedModuleState) /* 선택된 모듈 */
const { trigger: orientationTrigger } = useCanvasPopupStatusController(1)
const { trigger: moduleSelectedDataTrigger } = useCanvasPopupStatusController(2)
const [raftCodes, setRaftCodes] = useState([]) /* 서까래 정보 */
@ -526,7 +527,10 @@ export function useCanvasSetting(executeEffect = true) {
/** 모듈 선택 데이터 초기화 */
resetModuleSelectionData()
moduleSelectedDataTrigger({ common: {}, module: {}, roofConstructions: [] })
//1번 초기화
orientationTrigger({ compasDeg: 0, common: {}, module: {} })
//2번 초기화
moduleSelectedDataTrigger({ roofConstructions: [] })
const isModuleExist = canvas.getObjects().some((obj) => obj.name === POLYGON_TYPE.MODULE)
if (!isModuleExist) {
resetSelectedModules()

View File

@ -32,6 +32,7 @@ import { outlineDisplaySelector } from '@/store/settingAtom'
import { usePopup } from '@/hooks/usePopup'
import PropertiesSetting from '@/components/floor-plan/modal/outerlinesetting/PropertiesSetting'
import Big from 'big.js'
import RoofShapeSetting from '@/components/floor-plan/modal/roofShape/RoofShapeSetting'
//외벽선 그리기
export function useOuterLineWall(id, propertiesId) {
@ -256,7 +257,7 @@ export function useOuterLineWall(id, propertiesId) {
canvas?.renderAll()
setOuterLineFix(true)
closePopup(id)
addPopup(propertiesId, 1, <PropertiesSetting id={propertiesId} pos={{ x: 50, y: 230 }} />)
addPopup(propertiesId, 1, <RoofShapeSetting id={propertiesId} pos={{ x: 50, y: 230 }} />)
}
if (points.length < 3) {

View File

@ -11,6 +11,7 @@ import {
roofDisplaySelector,
roofMaterialsSelector,
selectedRoofMaterialSelector,
settingModalFirstOptionsState,
} from '@/store/settingAtom'
import { usePopup } from '@/hooks/usePopup'
import { POLYGON_TYPE } from '@/common/common'
@ -28,6 +29,7 @@ import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupSta
import { outerLinePointsState } from '@/store/outerLineAtom'
import { QcastContext } from '@/app/QcastProvider'
import { usePlan } from '@/hooks/usePlan'
import { roofsState } from '@/store/roofAtom'
export function useRoofAllocationSetting(id) {
const canvas = useRecoilValue(canvasState)
@ -54,9 +56,10 @@ export function useRoofAllocationSetting(id) {
const { setIsGlobalLoading } = useContext(QcastContext)
const { setSurfaceShapePattern } = useRoofFn()
const { saveCanvas } = usePlan()
const [roofsStore, setRoofsStore] = useRecoilState(roofsState)
const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState)
const resetPoints = useResetRecoilState(outerLinePointsState)
const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState)
useEffect(() => {
/** 배치면 초기설정에서 선택한 지붕재 배열 설정 */
@ -265,6 +268,8 @@ export function useRoofAllocationSetting(id) {
newRoofList[0].selected = true
}
setCurrentRoofList(newRoofList)
setRoofsStore(newRoofList)
setModuleSelectionData({ ...moduleSelectionData, roofConstructions: newRoofList })
}
/**
@ -305,12 +310,14 @@ export function useRoofAllocationSetting(id) {
setRoofList(newRoofList)
setRoofMaterials(newRoofList)
setRoofsStore(newRoofList)
const selectedRoofMaterial = newRoofList.find((roof) => roof.selected)
setSurfaceShapePattern(currentObject, roofDisplay.column, false, selectedRoofMaterial, true)
drawDirectionArrow(currentObject)
modifyModuleSelectionData()
closeAll()
basicSettingSave()
setModuleSelectionData({ ...moduleSelectionData, roofConstructions: newRoofList })
}
/**
@ -419,7 +426,7 @@ export function useRoofAllocationSetting(id) {
})
setRoofMaterials(newRoofList)
setRoofsStore(newRoofList)
/** 외곽선 삭제 */
const removeTargets = canvas.getObjects().filter((obj) => obj.name === 'outerLinePoint' || obj.name === 'outerLine')
removeTargets.forEach((obj) => {
@ -428,9 +435,23 @@ export function useRoofAllocationSetting(id) {
setEditingLines([])
closeAll()
setSelectedMenu('surface')
//지붕면 완성 후 실측치 로 보이도록 수정
setSettingModalFirstOptions((prev) => {
return {
...prev,
dimensionDisplay: prev.dimensionDisplay.map((item, index) => {
if (index === 1) {
return { ...item, selected: true }
} else {
return { ...item, selected: false }
}
}),
}
})
/** 모듈 선택 데이터 초기화 */
modifyModuleSelectionData()
// modifyModuleSelectionData()
setModuleSelectionData({ ...moduleSelectionData, roofConstructions: newRoofList })
}
/**
@ -548,7 +569,7 @@ export function useRoofAllocationSetting(id) {
* 모듈 선택에서 선택한 데이터 초기화
*/
const modifyModuleSelectionData = () => {
if (moduleSelectionData.roofConstructions.length > 0) {
if (moduleSelectionData.roofConstructions?.length > 0) {
setModuleSelectionData({ ...moduleSelectionData, roofConstructions: [] })
moduleSelectedDataTrigger({ ...moduleSelectionData, roofConstructions: [] })
}

View File

@ -231,6 +231,21 @@ export function useRoofShapeSetting(id) {
pitch: pitchRef.current,
onlyOffset: true,
}
switch (line.direction) {
case 'bottom':
direction = 'east'
break
case 'top':
direction = 'west'
break
case 'left':
direction = 'south'
break
case 'right':
direction = 'north'
break
}
}
})
}
@ -716,6 +731,7 @@ export function useRoofShapeSetting(id) {
type: LINE_TYPE.WALLLINE.SHED,
pitch: shedPitchRef.current,
width: shedWidth / 10,
offset: shedWidth / 10,
}
selectedLine.attributes = { ...attributes, isFixed: true }
addPitchText(currentObject)

View File

@ -31,7 +31,7 @@ export function useCircuitTrestle(executeEffect = false) {
const { getMessage } = useMessage()
useEffect(() => {
if (Object.keys(selectedModules).length > 0 && executeEffect) setModuleStatisticsData()
if (selectedModules && Object.keys(selectedModules).length > 0 && executeEffect) setModuleStatisticsData()
}, [selectedModules])
const getOptYn = () => {

View File

@ -77,10 +77,10 @@ export function useEvent() {
setCanvasZoom(Number((zoom * 100).toFixed(0)))
// 마우스 위치 기준으로 확대/축소
canvas.zoomToPoint({ x: opt.e.offsetX, y: opt.e.offsetY }, zoom)
canvas.requestRenderAll()
canvas.zoomToPoint(new fabric.Point(opt.e.offsetX, opt.e.offsetY), zoom)
canvas.calcOffset()
canvas.setViewportTransform(canvas.viewportTransform)
canvas.requestRenderAll()
// 이벤트의 기본 동작 방지 (스크롤 방지)
opt.e.preventDefault()

View File

@ -37,7 +37,7 @@
"modal.roof.shape.setting.ridge": "棟",
"modal.roof.shape.setting.patten.a": "Aパターン",
"modal.roof.shape.setting.patten.b": "Bパターン",
"modal.roof.shape.setting.side": "別に設定",
"modal.roof.shape.setting.side": "別に設定",
"plan.menu.roof.cover": "伏せ図入力",
"plan.menu.roof.cover.outline.drawing": "外壁線を描く",
"plan.menu.roof.cover.roof.shape.setting": "屋根形状の設定",
@ -114,6 +114,17 @@
"modal.module.basic.setting.module.eaves.bar.fitting": "軒カバーの設置",
"modal.module.basic.setting.module.blind.metal.fitting": "落雪防止金具設置",
"modal.module.basic.setting.module.select": "モジュール/架台選択",
"modal.module.basic.settting.module.error1": "架台メーカーを選択してください。(屋根材: {0})(JA)",
"modal.module.basic.settting.module.error2": "工法を選択してください。(屋根材: {0})(JA)",
"modal.module.basic.settting.module.error3": "屋根の下を選択してください。(屋根材: {0})(JA)",
"modal.module.basic.settting.module.error4": "施工法を選択してください。(屋根材: {0})(JA)",
"modal.module.basic.settting.module.error5": "L を選択してください。(屋根材: {0})(JA)",
"modal.module.basic.settting.module.error6": "垂木の間隔を入力してください。(屋根材: {0})(JA)",
"modal.module.basic.settting.module.error7": "下在ビーチを入力してください。(屋根材: {0})(JA)",
"modal.module.basic.settting.module.error8": "モジュール配置領域の値を入力してください。(屋根材: {0})(JA)",
"modal.module.basic.settting.module.error9": "軒側の値は{0} mm以上でなければなりません。(屋根材: {1})(JA)",
"modal.module.basic.settting.module.error10": "吊下側の値は{0} mm以上でなければなりません。(屋根材: {1})(JA)",
"modal.module.basic.settting.module.error11": "ケラバ側の値は{0} mm以上でなければなりません。(屋根材: {1})(JA)",
"modal.module.basic.setting.module.placement": "モジュールの配置",
"modal.module.basic.setting.module.placement.select.fitting.type": "設置形態を選択してください。",
"modal.module.basic.setting.module.placement.waterfowl.arrangement": "千鳥配置",
@ -125,19 +136,19 @@
"modal.module.basic.setting.module.placement.do.not": "しない",
"modal.module.basic.setting.module.placement.arrangement.standard": "配置基準",
"modal.module.basic.setting.module.placement.arrangement.standard.center": "中央",
"modal.module.basic.setting.module.placement.arrangement.standard.eaves": "軒側",
"modal.module.basic.setting.module.placement.arrangement.standard.ridge": "龍丸側",
"modal.module.basic.setting.module.placement.arrangement.standard.eaves": "軒側",
"modal.module.basic.setting.module.placement.arrangement.standard.ridge": "側",
"modal.module.basic.setting.module.placement.maximum": "最大配置",
"modal.module.basic.setting.pitch.module.placement.standard.setting": "配置基準設定",
"modal.module.basic.setting.pitch.module.placement.standard.setting.south": "南向き設置",
"modal.module.basic.setting.pitch.module.placement.standard.setting.select": "指定した辺を基準に設置",
"modal.module.basic.setting.pitch.module.placement.standard.setting": "配置基準設定",
"modal.module.basic.setting.pitch.module.placement.standard.setting.south": "南向き設置",
"modal.module.basic.setting.pitch.module.placement.standard.setting.select": "指定した辺を基準に設置する",
"modal.module.basic.setting.pitch.module.allocation.setting": "割り当て設定",
"modal.module.basic.setting.pitch.module.allocation.setting.info": "※配置パネルの種類が1種類の場合のみ使用できます。",
"modal.module.basic.setting.pitch.module.row.amount": "単数",
"modal.module.basic.setting.pitch.module.row.margin": "上下間隔",
"modal.module.basic.setting.pitch.module.column.amount": "列数",
"modal.module.basic.setting.pitch.module.column.margin": "左右間隔",
"modal.module.basic.setting.prev": "移転",
"modal.module.basic.setting.prev": "前に戻る",
"modal.module.basic.setting.row.batch": "単数指定配置",
"modal.module.basic.setting.passivity.placement": "手動配置",
"modal.module.basic.setting.auto.placement": "自動配置",
@ -604,6 +615,7 @@
"myinfo.message.password.error": "パスワードが間違っています。",
"login": "ログイン",
"login.auto.page.text": "自動ログイン中です。",
"login.fail": "계정이 없거나 비밀번호가 잘못되었습니다.",
"login.id.save": "ID保存",
"login.id.placeholder": "IDを入力してください。",
"login.password.placeholder": "パスワードを入力してください。",
@ -851,7 +863,7 @@
"has.not.sleeve": "袖なし",
"jerkinhead.width": "半切妻幅",
"jerkinhead.slope": "半切妻傾斜",
"shed.width": "片流幅",
"shed.width": "片流れの出幅",
"windage": "片流れ",
"windage.width": "片流れの出幅",
"write": "作成",
@ -905,6 +917,7 @@
"estimate.detail.estimateType": "注文分類",
"estimate.detail.estimateType.yjss": "住宅PKG",
"estimate.detail.estimateType.yjod": "積上げYJOD",
"estimate.detail.agency": "2次店名",
"estimate.detail.roofCns": "屋根材・施工区分",
"estimate.detail.remarks": "備考",
"estimate.detail.fileFlg": "後日資料提出",
@ -1046,12 +1059,19 @@
"outerLine.property.fix": "外壁線の属性設定 を完了しますか?",
"outerLine.property.close": "外壁線の属性設定 を終了しますか?",
"want.to.complete.auxiliary.creation": "補助線の作成を完了しますか?",
"module.layout.setup.has.zero.value": "モジュールの列、行を入力してください.",
"modal.placement.initial.setting.plan.drawing.only.number": "(※数字は[半角]入力のみ可能です。)",
"wall.line.not.found": "外壁がありません",
"roof.line.not.found": "屋根形状がありません",
"roof.material.can.not.delete": "割り当てられた配置面があります。",
"chidory.can.not.install": "千鳥配置できない工法です。",
"module.layout.setup.max.count": "모듈의 최대 단수는 {0}, 최대 열수는 {1} 입니다. (JA)",
"module.layout.setup.max.count.multiple": "모듈 {0}번의 최대 단수는 {1}, 최대 열수는 {2} 입니다. (JA)",
"roofAllocation.not.found": "할당할 지붕이 없습니다. (JA)"
"module.layout.setup.max.count": "モジュールの最大段数は{0}、最大列数は{1}です。 (JA)",
"module.layout.setup.max.count.multiple": "モジュール{0}の最大段数は{1}、最大列数は{2}です。 (JA)",
"roofAllocation.not.found": "割り当てる屋根がありません。 (JA)",
"modal.module.basic.setting.module.placement.max.size.check": "屋根材別モジュールの最大単数。混合最大単数を確認してください。 (JA)",
"modal.module.basic.setting.module.placement.max.row": "最大 単数(JA)",
"modal.module.basic.setting.module.placement.max.rows.multiple": "混合単数(JA)",
"modal.module.basic.setting.module.placement.mix.asg.yn.error": "混合インストール不可能なモジュールです。 (JA)",
"modal.module.basic.setting.module.placement.mix.asg.yn": "ミックス. (JA)",
"modal.module.basic.setting.layoutpassivity.placement": "layout配置 (JA)"
}

View File

@ -114,6 +114,17 @@
"modal.module.basic.setting.module.eaves.bar.fitting": "처마커버설치",
"modal.module.basic.setting.module.blind.metal.fitting": "적설방지금구설치",
"modal.module.basic.setting.module.select": "모듈/가대 선택",
"modal.module.basic.settting.module.error1": "가대메이커를 선택해주세요.(지붕재: {0})",
"modal.module.basic.settting.module.error2": "공법를 선택해주세요.(지붕재: {0})",
"modal.module.basic.settting.module.error3": "지붕밑바탕을 선택해주세요.(지붕재: {0})",
"modal.module.basic.settting.module.error4": "시공법을 선택해주세요.(지붕재: {0})",
"modal.module.basic.settting.module.error5": "L 을 입력해주세요.(지붕재: {0})",
"modal.module.basic.settting.module.error6": "서까래 간격을 입력해주세요.(지붕재: {0})",
"modal.module.basic.settting.module.error7": "하제비치를 입력해주세요.(지붕재: {0})",
"modal.module.basic.settting.module.error8": "모듈 배치 영역 값을 입력해주세요.(지붕재: {0})",
"modal.module.basic.settting.module.error9": "처마쪽 값은 {0}mm 이상이어야 합니다.(지붕재: {1})",
"modal.module.basic.settting.module.error10": "용마루쪽 값은 {0}mm 이상이어야 합니다.(지붕재: {1})",
"modal.module.basic.settting.module.error11": "케라바쪽 값은 {0}mm 이상이어야 합니다.(지붕재: {1})",
"modal.module.basic.setting.module.placement": "모듈 배치",
"modal.module.basic.setting.module.placement.select.fitting.type": "설치형태를 선택합니다.",
"modal.module.basic.setting.module.placement.waterfowl.arrangement": "물떼새 배치",
@ -128,6 +139,7 @@
"modal.module.basic.setting.module.placement.arrangement.standard.eaves": "처마쪽",
"modal.module.basic.setting.module.placement.arrangement.standard.ridge": "용마루쪽",
"modal.module.basic.setting.module.placement.maximum": "최대배치",
"modal.module.basic.setting.module.placement.margin.check1": "가대메이커를 선택해주세요.",
"modal.module.basic.setting.pitch.module.placement.standard.setting": "배치기준 설정",
"modal.module.basic.setting.pitch.module.placement.standard.setting.south": "남향설치",
"modal.module.basic.setting.pitch.module.placement.standard.setting.select": "지정한 변을 기준으로 설치",
@ -906,6 +918,7 @@
"estimate.detail.estimateType": "주문분류",
"estimate.detail.estimateType.yjss": "住宅PKG",
"estimate.detail.estimateType.yjod": "積上げ( YJOD )",
"estimate.detail.agency": "2차점명",
"estimate.detail.roofCns": "지붕재・사양시공",
"estimate.detail.remarks": "비고",
"estimate.detail.fileFlg": "후일자료제출",
@ -1047,6 +1060,7 @@
"outerLine.property.fix": "외벽선 속성 설정을 완료하시겠습니까?",
"outerLine.property.close": "외벽선 속성 설정을 종료하시겠습니까?",
"want.to.complete.auxiliary.creation": "보조선 작성을 완료하시겠습니까?",
"module.layout.setup.has.zero.value": "모듈의 열, 행을 입력해 주세요.",
"modal.placement.initial.setting.plan.drawing.only.number": "(※ 숫자는 [반각]입력만 가능합니다.)",
"wall.line.not.found": "외벽선이 없습니다.",
"roof.line.not.found": "지붕형상이 없습니다.",
@ -1054,5 +1068,11 @@
"chidory.can.not.install": "치조 불가 공법입니다.",
"module.layout.setup.max.count": "모듈의 최대 단수는 {0}, 최대 열수는 {1} 입니다.",
"module.layout.setup.max.count.multiple": "모듈 {0}번의 최대 단수는 {1}, 최대 열수는 {2} 입니다.",
"roofAllocation.not.found": "할당할 지붕이 없습니다."
"roofAllocation.not.found": "할당할 지붕이 없습니다.",
"modal.module.basic.setting.module.placement.max.size.check": "지붕재별 모듈의 최대 단수. 혼합 최대 단수를 확인하십시오.",
"modal.module.basic.setting.module.placement.max.row": "최대 단수",
"modal.module.basic.setting.module.placement.max.rows.multiple": "혼합 단수",
"modal.module.basic.setting.module.placement.mix.asg.yn.error": "혼합 설치 불가능한 모듈입니다.",
"modal.module.basic.setting.module.placement.mix.asg.yn": "혼합",
"modal.module.basic.setting.layoutpassivity.placement": "레이아웃 배치"
}

View File

@ -384,3 +384,27 @@ export const isManualModuleSetupState = atom({
key: 'isManualModuleSetupState',
default: false,
})
export const isManualModuleLayoutSetupState = atom({
key: 'isManualModuleLayoutSetupState',
default: false,
})
export const moduleSetupOptionState = atom({
key: 'moduleSetupOptionState',
default: {
isChidori: false, //치조 안함
setupLocation: 'eaves', //처마
},
})
export const toggleManualSetupModeState = atom({
key: 'toggleManualSetupModeState',
default: '',
})
export const moduleRowColArrayState = atom({
key: 'moduleRowColArrayState',
default: [],
dangerouslyAllowMutability: true,
})

View File

@ -2,7 +2,7 @@ import { atom } from 'recoil'
export const selectedModuleState = atom({
key: 'selectedModuleState',
default: [],
default: null,
dangerouslyAllowMutability: true,
})

View File

@ -47,6 +47,16 @@ table{
}
.form-flex-wrap{
@include flexbox;
.form-flex-select{
@include flexbox;
label{
flex: none;
margin-right: 5px;
}
.form-select{
min-width: 300px;
}
}
}
.date-picker-wrap{
width: 100%;

2
startscript-3000.js Normal file
View File

@ -0,0 +1,2 @@
var exec = require('child_process').exec
exec('yarn dev -p 3000', { windowsHide: true })