415 lines
18 KiB
JavaScript
415 lines
18 KiB
JavaScript
import { forwardRef, useEffect, useState } from 'react'
|
|
import { useMessage } from '@/hooks/useMessage'
|
|
import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting'
|
|
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'
|
|
import { normalizeDigits } from '@/util/input-utils'
|
|
import Image from 'next/image'
|
|
|
|
const Placement = forwardRef((props, refs) => {
|
|
const { getMessage } = useMessage()
|
|
const [useTab, setUseTab] = useState(true)
|
|
const [guideType, setGuideType] = useState('batch')
|
|
|
|
const [isChidoriNotAble, setIsChidoriNotAble] = useState(false)
|
|
|
|
const [selectedItems, setSelectedItems] = useState({})
|
|
const [selectedModules, setSelectedModules] = useRecoilState(selectedModuleState)
|
|
|
|
const setCheckedModules = useSetRecoilState(checkedModuleState)
|
|
const moduleSelectionData = useRecoilValue(moduleSelectionDataState)
|
|
const { makeModuleInitArea, roofOutlineColor } = useModuleBasicSetting(3)
|
|
|
|
const [isMultiModule, setIsMultiModule] = useState(false)
|
|
|
|
//언마운트시 버튼 초기화
|
|
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 = useRecoilValue(moduleRowColArrayState)
|
|
|
|
//모듈 배치면 생성
|
|
useEffect(() => {
|
|
if (moduleSelectionData) {
|
|
//1개라도 치도리 불가가 있으면 치도리 불가
|
|
const isChidroriValue = moduleSelectionData.roofConstructions.some((item) => item.construction.plvrYn === 'N')
|
|
if (isChidroriValue) {
|
|
setIsChidoriNotAble(true)
|
|
}
|
|
makeModuleInitArea(moduleSelectionData)
|
|
}
|
|
|
|
if (moduleSelectionData.module.itemList.length > 1) {
|
|
setColspan(2)
|
|
}
|
|
|
|
return () => {
|
|
// 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)) {
|
|
//두번째 선택한 데이터가를 기반으로 세번째 선택을 체크한다
|
|
if (moduleSelectionData.roofConstructions.length > 0 && moduleSelectionData.module.itemList.length > 0) {
|
|
let initCheckedModule = {}
|
|
moduleSelectionData.module.itemList.forEach((obj, index) => {
|
|
if (index === 0) {
|
|
initCheckedModule = { [obj.itemId]: true }
|
|
} else {
|
|
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 })))
|
|
}
|
|
|
|
//모듈 배치면 생성
|
|
if (isObjectNotEmpty(moduleSelectionData.module) && moduleSelectionData.module.itemList.length > 1) {
|
|
setIsMultiModule(true)
|
|
}
|
|
}
|
|
}, [moduleSelectionData])
|
|
|
|
//체크된 모듈 데이터
|
|
useEffect(() => {
|
|
if (isObjectNotEmpty(selectedItems) && isObjectNotEmpty(selectedModules)) {
|
|
const checkedModuleIds = Object.keys(selectedItems).filter((key) => selectedItems[key])
|
|
const moduleArray = selectedModules.itemList.filter((item) => {
|
|
return checkedModuleIds.includes(item.itemId)
|
|
})
|
|
setCheckedModules(moduleArray)
|
|
}
|
|
}, [selectedItems, selectedModules])
|
|
|
|
const moduleData = {
|
|
header: [
|
|
{ type: 'check', name: '', prop: 'check', width: 70 },
|
|
{ type: 'color-box', name: getMessage('module'), prop: 'module' },
|
|
{ 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
|
|
setModuleSetupOption({ ...moduleSetupOption, isChidori: bool })
|
|
|
|
//변경하면 수동 다 꺼짐
|
|
setIsManualModuleSetup(false)
|
|
setIsManualModuleLayoutSetup(false)
|
|
setManualSetupMode('off')
|
|
}
|
|
|
|
const handleSetupLocation = (e) => {
|
|
setModuleSetupOption({ ...moduleSetupOption, setupLocation: e.target.value })
|
|
|
|
//변경하면 수동 다 꺼짐
|
|
setIsManualModuleSetup(false)
|
|
setIsManualModuleLayoutSetup(false)
|
|
setManualSetupMode('off')
|
|
}
|
|
|
|
//체크된 모듈 아이디 추출
|
|
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(normalizeDigits(e.target.value)),
|
|
}
|
|
props.setLayoutSetup(newLayoutSetup)
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<div className="module-table-flex-wrap">
|
|
<div className="module-table-box">
|
|
<div className="module-table-inner">
|
|
<div className="roof-module-table">
|
|
<table>
|
|
<thead>
|
|
{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 &&
|
|
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={(e) => handleSelectedItem(e, item.itemId)}
|
|
/>
|
|
<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-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 non-flex">
|
|
<div className="module-table-inner">
|
|
<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-tab-wrap">
|
|
<div className="hide-check-guide">
|
|
{getMessage('modal.module.basic.setting.module.placement.info')}
|
|
<button className={`arr ${useTab ? 'act' : ''}`} onClick={() => setUseTab(!useTab)}></button>
|
|
</div>
|
|
<div className={`hide-tab-contents ${!useTab ? 'hide' : ''}`}>
|
|
<div className="roof-content-tab-wrap">
|
|
<button className={`btn-frame block modal mr5 ${guideType === 'batch' ? 'act' : ''} `} onClick={() => setGuideType('batch')}>
|
|
{getMessage('modal.module.basic.setting.module.placement.info.batch')}
|
|
</button>
|
|
<button className={`btn-frame block modal mr5 ${guideType === 'module' ? 'act' : ''}`} onClick={() => setGuideType('module')}>
|
|
{getMessage('modal.module.basic.setting.module.placement.info.module')}
|
|
</button>
|
|
</div>
|
|
{guideType === 'batch' && (
|
|
<div className={`roof-warning-wrap mt10`}>
|
|
<div className="guide">
|
|
{getMessage('modal.module.basic.setting.module.placement.info.batch.content1')}
|
|
<br />
|
|
{getMessage('modal.module.basic.setting.module.placement.info.batch.content2')}
|
|
</div>
|
|
<div className="roof-warning-img-wrap">
|
|
<div className="roof-warning-img">
|
|
<Image src={'/static/images/canvas/roof_warning_correct.png'} width={350} height={198} alt="" />
|
|
</div>
|
|
<div className="roof-warning-img">
|
|
<Image src={'/static/images/canvas/roof_warning_wrong.png'} width={350} height={198} alt="" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
{guideType === 'module' && (
|
|
<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}>
|
|
<th>
|
|
<div className="color-wrap">
|
|
<span className="color-box" style={{ backgroundColor: item.color }}></span>
|
|
<span className="name">{item.itemNm}</span>
|
|
</div>
|
|
</th>
|
|
))}
|
|
{colspan > 1 && <th rowSpan={2}>{getMessage('modal.module.basic.setting.module.placement.max.rows.multiple')}</th>}
|
|
</tr>
|
|
<tr>
|
|
{selectedModules &&
|
|
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, index2) => (
|
|
<>
|
|
<td className="al-c">{item.moduleMaxRows}</td>
|
|
{/* {colspan > 1 && <td className="al-c">{item.mixModuleMaxRows}</td>} */}
|
|
{colspan > 1 && index2 === moduleRowColArray[index].length - 1 && <td className="al-c">{item.maxRow}</td>}
|
|
</>
|
|
))}
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</>
|
|
)
|
|
})
|
|
|
|
export default Placement
|