This commit is contained in:
hyojun.choi 2024-10-28 09:34:33 +09:00
commit 31a89aab4d
15 changed files with 395 additions and 276 deletions

View File

@ -81,11 +81,11 @@ export default function Table({ clsCode }) {
{/* 번호 */}
{board.rowNumber}
</td>
<td style={{ textAlign: 'center' }}>
<td>
{/* 제목 */}
<div className="text-frame">
<div className="text-overflow">{board.title}</div>
{board.attachYn && <span className="clip"></span>}
{board.attachYn === 'Y' && <span className="clip"></span>}
</div>
</td>
<td className="al-c">

View File

@ -8,25 +8,23 @@ import { useCanvas } from '@/hooks/useCanvas'
import { useEvent } from '@/hooks/useEvent'
import { usePlan } from '@/hooks/usePlan'
import { useContextMenu } from '@/hooks/useContextMenu'
import { currentObjectState, modifiedPlanFlagState } from '@/store/canvasAtom'
import { currentMenuState, currentObjectState, modifiedPlanFlagState } from '@/store/canvasAtom'
import { useCanvasEvent } from '@/hooks/useCanvasEvent'
import QContextMenu from '@/components/common/context-menu/QContextMenu'
import { useCanvasConfigInitialize } from '@/hooks/common/useCanvasConfigInitialize'
import { MENU } from '@/common/common'
import PanelBatchStatistics from '@/components/floor-plan/modal/panelBatch/PanelBatchStatistics'
export default function CanvasFrame({ plan }) {
const canvasRef = useRef(null)
const [modifiedPlanFlag, setModifiedPlanFlag] = useRecoilState(modifiedPlanFlagState)
const { canvas } = useCanvas('canvas')
const { handleZoomClear } = useCanvasEvent()
const { contextMenu, currentContextMenu, setCurrentContextMenu, handleClick } = useContextMenu({
externalFn: {
handleZoomClear,
},
})
const { checkCanvasObjectEvent, resetModifiedPlans } = usePlan()
const { canvasLoadInit, gridInit } = useCanvasConfigInitialize()
const currentObject = useRecoilValue(currentObjectState)
const currentMenu = useRecoilValue(currentMenuState)
const { contextMenu, handleClick } = useContextMenu()
const { checkCanvasObjectEvent, checkUnsavedCanvasPlan, resetModifiedPlans } = usePlan()
useEvent()
const loadCanvas = () => {
@ -53,8 +51,6 @@ export default function CanvasFrame({ plan }) {
resetModifiedPlans()
}, [plan, canvas])
const onClickContextMenu = (index) => {}
return (
<div className="canvas-frame">
<canvas ref={canvasRef} id="canvas" style={{ position: 'relative' }}></canvas>
@ -78,6 +74,11 @@ export default function CanvasFrame({ plan }) {
</ul>
))}
</QContextMenu>
{[
MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING,
MENU.MODULE_CIRCUIT_SETTING.CIRCUIT_TRESTLE_SETTING,
MENU.MODULE_CIRCUIT_SETTING.PLAN_ORIENTATION,
].includes(currentMenu) && <PanelBatchStatistics />}
</div>
)
}

View File

@ -1,24 +1,68 @@
import WithDraggable from '@/components/common/draggable/withDraggable'
import { useState } from 'react'
import { useEffect, useState } from 'react'
import QSelectBox from '@/components/common/select/QSelectBox'
import { useRecoilValue } from 'recoil'
import { contextPopupPositionState } from '@/store/popupAtom'
import { useMessage } from '@/hooks/useMessage'
import { usePopup } from '@/hooks/usePopup'
const SelectOption01 = [{ name: 'M' }, { name: 'M' }, { name: 'M' }, { name: 'M' }]
export default function FlowDirectionSetting(props) {
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
const { id, pos = contextPopupPosition } = props
const { id, pos = contextPopupPosition, target } = props
const { getMessage } = useMessage()
const { closePopup } = usePopup()
const [compasDeg, setCompasDeg] = useState(0)
const [compasDeg, setCompasDeg] = useState(360)
const orientations = [
{ name: `${getMessage('commons.south')}`, value: 360 },
{ name: `${getMessage('commons.south')}${getMessage('commons.east')}`, value: 315 },
{ name: `${getMessage('commons.south')}${getMessage('commons.west')}`, value: 45 },
{ name: `${getMessage('commons.east')}`, value: 270 },
{ name: `${getMessage('commons.west')}`, value: 90 },
{ name: `${getMessage('commons.north')}${getMessage('commons.east')}`, value: 225 },
{ name: `${getMessage('commons.north')}${getMessage('commons.west')}`, value: 135 },
{ name: `${getMessage('commons.north')}`, value: 180 },
]
const [selectedOrientation, setSelectedOrientation] = useState(orientations[0])
const [type, setType] = useState('0')
useEffect(() => {
if (target?.angle === 0) {
setCompasDeg(360)
} else {
setCompasDeg(target?.angle ?? 360)
}
}, [])
useEffect(() => {
if (type === '0') {
setCompasDeg(selectedOrientation.value)
}
}, [selectedOrientation])
useEffect(() => {
if (type === '1') {
if ([15, 345, 360].includes(compasDeg)) {
setSelectedOrientation(orientations[0])
} else if ([30, 45, 60].includes(compasDeg)) {
setSelectedOrientation(orientations[2])
} else if ([75, 90, 105].includes(compasDeg)) {
setSelectedOrientation(orientations[4])
} else if ([120, 135, 150].includes(compasDeg)) {
setSelectedOrientation(orientations[6])
} else if ([165, 180, 195].includes(compasDeg)) {
setSelectedOrientation(orientations[7])
} else if ([210, 225, 240].includes(compasDeg)) {
setSelectedOrientation(orientations[5])
} else if ([255, 270, 285].includes(compasDeg)) {
setSelectedOrientation(orientations[3])
} else if ([300, 315, 330].includes(compasDeg)) {
setSelectedOrientation(orientations[1])
}
}
}, [compasDeg])
return (
<WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap lx`}>
<div className="modal-head">
<h1 className="title">面フローの設定 </h1>
<h1 className="title">{getMessage('modal.shape.flow.direction.setting')} </h1>
<button className="modal-close" onClick={() => closePopup(id)}>
닫기
</button>
@ -26,113 +70,59 @@ export default function FlowDirectionSetting(props) {
<div className="modal-body">
<div className="drawing-flow-wrap">
<div className="discrimination-box">
<div className="discrimination-tit mb15">流れ方向の設定</div>
<div className="guide">流れ方向を選択してください</div>
<div className="discrimination-tit mb15">{getMessage('modal.flow.direction.setting')}</div>
<div className="guide">{getMessage('modal.flow.direction.setting.info')}</div>
<div className="object-direction-wrap">
<div className="plane-direction">
<span className="top"></span>
<span className="right">ドン</span>
<span className="bottom"></span>
<span className="left">立つ</span>
<span className="top">{getMessage('commons.north')}</span>
<button className="plane-btn up"></button>
<span className="right">{getMessage('commons.east')}</span>
<button className="plane-btn right"></button>
<span className="bottom">{getMessage('commons.south')}</span>
<button className="plane-btn down act"></button>
<span className="left">{getMessage('commons.west')}</span>
<button className="plane-btn left"></button>
</div>
</div>
</div>
<div className="discrimination-box">
<div className="discrimination-tit mb15">方位設定</div>
<div className="guide">シミュレーション計算の方向を指定します面が向いている方位を選択してください</div>
<div className="discrimination-tit mb15">{getMessage('modal.module.basic.setting.orientation.setting')}</div>
<div className="guide">{getMessage('modal.shape.flow.direction.setting.orientation.setting.info')}</div>
<div className="mb-box">
<div className="d-check-radio pop mb15">
<input type="radio" name="radio01" id="ra01" />
<label htmlFor="ra01">8方位に選ぶ</label>
<input type="radio" name="radio01" id="ra01" value={0} checked={type === '0'} onChange={(e) => setType(e.target.value)} />
<label htmlFor="ra01">{getMessage('modal.shape.flow.direction.setting.orientation.8')}</label>
</div>
<div className="grid-select ">
<QSelectBox title={'M'} options={SelectOption01} />
<QSelectBox title={''} options={orientations} value={selectedOrientation} onChange={(e) => setSelectedOrientation(e)} />
</div>
</div>
<div className="mb-box">
<div className="d-check-radio pop">
<input type="radio" name="radio02" id="ra02" />
<label htmlFor="ra02">24方位から選択する (表記は8方位です)</label>
<input type="radio" name="radio01" id="ra02" value={1} checked={type === '1'} onChange={(e) => setType(e.target.value)} />
<label htmlFor="ra02">{getMessage('modal.shape.flow.direction.setting.orientation.24')}</label>
</div>
</div>
<div className="compas-box">
<div className="compas-box-inner">
<div className={`circle ${compasDeg === 180 ? 'act' : ''}`} onClick={() => setCompasDeg(180)}>
<i>13</i>
</div>
<div className={`circle ${compasDeg === 195 ? 'act' : ''}`} onClick={() => setCompasDeg(195)}>
<i>12</i>
</div>
<div className={`circle ${compasDeg === 210 ? 'act' : ''}`} onClick={() => setCompasDeg(210)}>
<i>11</i>
</div>
<div className={`circle ${compasDeg === 225 ? 'act' : ''}`} onClick={() => setCompasDeg(225)}>
<i>10</i>
</div>
<div className={`circle ${compasDeg === 240 ? 'act' : ''}`} onClick={() => setCompasDeg(240)}>
<i>9</i>
</div>
<div className={`circle ${compasDeg === 255 ? 'act' : ''}`} onClick={() => setCompasDeg(255)}>
<i>8</i>
</div>
<div className={`circle ${compasDeg === 270 ? 'act' : ''}`} onClick={() => setCompasDeg(270)}>
<i>7</i>
</div>
<div className={`circle ${compasDeg === 285 ? 'act' : ''}`} onClick={() => setCompasDeg(285)}>
<i>6</i>
</div>
<div className={`circle ${compasDeg === 300 ? 'act' : ''}`} onClick={() => setCompasDeg(300)}>
<i>5</i>
</div>
<div className={`circle ${compasDeg === 315 ? 'act' : ''}`} onClick={() => setCompasDeg(315)}>
<i>4</i>
</div>
<div className={`circle ${compasDeg === 330 ? 'act' : ''}`} onClick={() => setCompasDeg(330)}>
<i>3</i>
</div>
<div className={`circle ${compasDeg === 345 ? 'act' : ''}`} onClick={() => setCompasDeg(345)}>
<i>2</i>
</div>
<div className={`circle ${compasDeg === 0 ? 'act' : ''}`} onClick={() => setCompasDeg(0)}>
<i>1</i>
</div>
<div className={`circle ${compasDeg === 15 ? 'act' : ''}`} onClick={() => setCompasDeg(15)}>
<i>24</i>
</div>
<div className={`circle ${compasDeg === 30 ? 'act' : ''}`} onClick={() => setCompasDeg(30)}>
<i>23</i>
</div>
<div className={`circle ${compasDeg === 45 ? 'act' : ''}`} onClick={() => setCompasDeg(45)}>
<i>22</i>
</div>
<div className={`circle ${compasDeg === 60 ? 'act' : ''}`} onClick={() => setCompasDeg(60)}>
<i>21</i>
</div>
<div className={`circle ${compasDeg === 75 ? 'act' : ''}`} onClick={() => setCompasDeg(75)}>
<i>20</i>
</div>
<div className={`circle ${compasDeg === 90 ? 'act' : ''}`} onClick={() => setCompasDeg(90)}>
<i>19</i>
</div>
<div className={`circle ${compasDeg === 105 ? 'act' : ''}`} onClick={() => setCompasDeg(105)}>
<i>18</i>
</div>
<div className={`circle ${compasDeg === 120 ? 'act' : ''}`} onClick={() => setCompasDeg(120)}>
<i>17</i>
</div>
<div className={`circle ${compasDeg === 135 ? 'act' : ''}`} onClick={() => setCompasDeg(135)}>
<i>16</i>
</div>
<div className={`circle ${compasDeg === 150 ? 'act' : ''}`} onClick={() => setCompasDeg(150)}>
<i>15</i>
</div>
<div className={`circle ${compasDeg === 165 ? 'act' : ''}`} onClick={() => setCompasDeg(165)}>
<i>14</i>
</div>
{Array.from({ length: 180 / 15 + 1 }).map((dot, index) => (
<div
key={index}
className={`circle ${compasDeg === 15 * (12 + index) ? 'act' : ''}`}
onClick={() => setCompasDeg(15 * (12 + index))}
>
<i>{13 - index}</i>
</div>
))}
{Array.from({ length: 180 / 15 - 1 }).map((dot, index) => (
<div
key={index}
className={`circle ${compasDeg === 15 * (index + 1) ? 'act' : ''}`}
onClick={() => setCompasDeg(15 * (index + 1))}
>
<i>{24 - index}</i>
</div>
))}
<div className="compas">
<div className="compas-arr" style={{ transform: `rotate(${compasDeg}deg)` }}></div>
</div>
@ -141,7 +131,7 @@ export default function FlowDirectionSetting(props) {
</div>
</div>
<div className="grid-btn-wrap">
<button className="btn-frame modal act">保存</button>
<button className="btn-frame modal act">{getMessage('modal.common.save')}</button>
</div>
</div>
</div>

View File

@ -3,99 +3,70 @@ import { useRecoilValue } from 'recoil'
import { contextPopupPositionState } from '@/store/popupAtom'
import { useMessage } from '@/hooks/useMessage'
import { usePopup } from '@/hooks/usePopup'
import { useState } from 'react'
export default function LinePropertySetting(props) {
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
const { id, pos = contextPopupPosition } = props
const { getMessage } = useMessage()
const { closePopup } = usePopup()
const properties = [
{ name: getMessage('eaves.line'), value: 'eaves' },
{ name: getMessage('ridge'), value: 'ridge' },
{ name: getMessage('oneside.flow.ridge'), value: 'onesideFlowRidge' },
{ name: getMessage('gable'), value: 'gable' },
{ name: getMessage('gable.left'), value: 'gableLeft' },
{ name: getMessage('gable.right'), value: 'gableRight' },
{ name: getMessage('yosemune'), value: 'yosemune' },
{ name: getMessage('valley'), value: 'valley' },
{ name: getMessage('l.abandon.valley'), value: 'lAbandonValley' },
{ name: getMessage('mansard'), value: 'mansard' },
{ name: getMessage('wall.merge'), value: 'wallCollection' },
{ name: getMessage('wall.merge.type'), value: 'wallCollectionType' },
{ name: getMessage('wall.merge.flow'), value: 'wallCollectionFlow' },
{ name: getMessage('wall.merge.flow.left'), value: 'wallCollectionFlowLeft' },
{ name: getMessage('wall.merge.flow.right'), value: 'wallCollectionFlowRight' },
{ name: getMessage('no.setting'), value: 'noSetting' },
]
const [selectedProperty, setSelectedProperty] = useState(null)
return (
<WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap r`}>
<div className={`modal-pop-wrap r mount`}>
<div className="modal-head">
<h1 className="title">各辺属性の変更 </h1>
<h1 className="title">{getMessage('contextmenu.line.property.edit')} </h1>
<button className="modal-close" onClick={() => closePopup(id)}>
닫기
</button>
</div>
<div className="modal-body">
<div className="guide">
<span className="mb10">属性を変更する辺を選択してください</span>
<span>選択した値 [龍丸]</span>
<span className="mb10">{getMessage('modal.line.property.edit.info')}</span>
<span>
{getMessage('modal.line.property.edit.selected')} [ {selectedProperty?.name} ]
</span>
</div>
<div className="properties-setting-wrap outer">
<div className="setting-tit">設定</div>
<div className="setting-tit">{getMessage('setting')}</div>
<div className="outline-wrap">
<div className="radio-grid-wrap">
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra01" />
<label htmlFor="ra01">軒先</label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra02" />
<label htmlFor="ra02">ケラバ</label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra03" />
<label htmlFor="ra03">龍丸</label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra04" />
<label htmlFor="ra04">ケラバ左</label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra05" />
<label htmlFor="ra05">ヨセムネ</label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra06" />
<label htmlFor="ra06">ケラバ右</label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra07" />
<label htmlFor="ra07">片側の流れ</label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra08" />
<label htmlFor="ra08"></label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra09" />
<label htmlFor="ra09">壁取り</label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra10" />
<label htmlFor="ra10">Lの捨て渓谷</label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra11" />
<label htmlFor="ra11">壁取り()</label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra12" />
<label htmlFor="ra12">マンサード</label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra13" />
<label htmlFor="ra13">壁取合(流れ)</label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra14" />
<label htmlFor="ra14">設定なし</label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra15" />
<label htmlFor="ra15">壁取合(流れ左)</label>
</div>
<div className="d-check-radio pop">
<input type="radio" name="radio01" id="ra16" />
<label htmlFor="ra16">壁取り(流れ右)</label>
</div>
{properties.map((property, index) => {
return (
<div className="d-check-radio pop" key={index}>
<input
type="radio"
name="radio01"
id={'ra' + (index + 1 >= 10 ? index + 1 : `0${index + 1}`)}
onChange={(e) => setSelectedProperty(property)}
/>
<label htmlFor={'ra' + (index + 1 > 10 ? index + 1 : `0${index + 1}`)}>{property.name}</label>
</div>
)
})}
</div>
</div>
</div>
<div className="grid-btn-wrap">
<button className="btn-frame modal act">保存</button>
<button className="btn-frame modal act">{getMessage('modal.common.save')}</button>
</div>
</div>
</div>

View File

@ -13,26 +13,26 @@ export default function DormerOffset(props) {
<WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap xm`}>
<div className="modal-head">
<h1 className="title">도머 오프셋 </h1>
<h1 className="title">{getMessage('contextmenu.dormer.offset')}</h1>
<button className="modal-close" onClick={() => closePopup(id)}>
닫기
</button>
</div>
<div className="modal-body">
<div className="grid-option-tit">移動する方向を入力してください</div>
<div className="grid-option-tit">{getMessage('modal.dormer.offset.info')}</div>
<div className="grid-option-wrap">
<div className="grid-option-box">
<div className="move-form">
<p className="mb5">長さ</p>
<p className="mb5">{getMessage('length')}</p>
<div className="input-move-wrap mb5">
<div className="input-move">
<input type="text" className="input-origin" defaultValue={910} />
<input type="text" className="input-origin" defaultValue={0} />
</div>
<span>mm</span>
</div>
<div className="input-move-wrap">
<div className="input-move">
<input type="text" className="input-origin" defaultValue={910} />
<input type="text" className="input-origin" defaultValue={0} />
</div>
<span>mm</span>
</div>
@ -46,7 +46,7 @@ export default function DormerOffset(props) {
</div>
</div>
<div className="grid-btn-wrap">
<button className="btn-frame modal act">保存</button>
<button className="btn-frame modal act">{getMessage('modal.common.save')}</button>
</div>
</div>
</div>

View File

@ -2,7 +2,6 @@
import { useRecoilValue } from 'recoil'
import { useMessage } from '@/hooks/useMessage'
import { canvasState } from '@/store/canvasAtom'
import WithDraggable from '@/components/common/draggable/WithDraggable'
import { usePopup } from '@/hooks/usePopup'
import { contextPopupPositionState } from '@/store/popupAtom'
@ -11,16 +10,15 @@ import { useState } from 'react'
export default function SizeSetting(props) {
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
const [settingTarget, setSettingTarget] = useState(1)
const { id, pos = contextPopupPosition } = props
const { id, pos = contextPopupPosition, target } = props
const { getMessage } = useMessage()
const canvas = useRecoilValue(canvasState)
const { closePopup } = usePopup()
return (
<WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap ssm`}>
<div className="modal-head">
<h1 className="title">サイズ変更 </h1>
<h1 className="title">{getMessage('modal.size.setting')} </h1>
<button className="modal-close" onClick={() => closePopup(id)}>
닫기
</button>
@ -30,11 +28,11 @@ export default function SizeSetting(props) {
<div className="size-option-top">
<div className="size-option-wrap">
<div className="size-option mb5">
<input type="text" className="input-origin mr5" defaultValue={1000} readOnly />
<input type="text" className="input-origin mr5" defaultValue={1000} readOnly value={target?.width * 10 * 2} />
<span className="normal-font">mm</span>
</div>
<div className="size-option">
<input type="text" className="input-origin mr5" defaultValue={1000} />
<input type="text" className="input-origin mr5" defaultValue={1000} value={target?.width * 10 * 2} />
<span className="normal-font">mm</span>
</div>
</div>
@ -43,11 +41,11 @@ export default function SizeSetting(props) {
<div className="size-option-side">
<div className="size-option-wrap">
<div className="size-option mb5">
<input type="text" className="input-origin mr5" defaultValue={1000} readOnly />
<input type="text" className="input-origin mr5" defaultValue={1000} readOnly value={target?.height * 10} />
<span className="normal-font">mm</span>
</div>
<div className="size-option">
<input type="text" className="input-origin mr5" defaultValue={1000} />
<input type="text" className="input-origin mr5" defaultValue={1000} value={target?.height * 10} />
<span className="normal-font">mm</span>
</div>
</div>
@ -62,7 +60,7 @@ export default function SizeSetting(props) {
</div>
</div>
<div className="grid-btn-wrap">
<button className="btn-frame modal act">作成</button>
<button className="btn-frame modal act">{getMessage('write')}</button>
</div>
</div>
</div>

View File

@ -0,0 +1,37 @@
import WithDraggable from '@/components/common/draggable/withDraggable'
import { useState } from 'react'
import { useMessage } from '@/hooks/useMessage'
export default function PanelBatchStatistics() {
const { getMessage } = useMessage()
const [isFold, setIsFold] = useState(false)
const [pos, setPos] = useState({
x: 0,
y: 30,
})
return (
<WithDraggable isShow={true} handle=".penal-wrap" pos={pos}>
<div className={`penal-wrap ${!isFold ? 'act' : ''}`}>
<h2>{getMessage('modal.panel.batch.statistic')}</h2>
<button className="penal-arr" onClick={() => setIsFold(!isFold)}></button>
<div className="penal-table-wrap">
<table className="penal-table">
<thead>
<tr>
<th>{getMessage('modal.panel.batch.statistic.roof.shape')}</th>
<th>{getMessage('modal.panel.batch.statistic.power.generation.amount')} (kW)</th>
</tr>
</thead>
<tbody>
<tr>
<td>{getMessage('modal.panel.batch.statistic.total')}</td>
<td className="al-r">0.000</td>
</tr>
</tbody>
</table>
</div>
</div>
</WithDraggable>
)
}

View File

@ -1122,7 +1122,6 @@ export default function StuffDetail() {
workName: null,
}
return
//1 or 2
if (params.saleStoreId == '') {
params.saleStoreId = sessionState.storeId

View File

@ -59,13 +59,15 @@ export default function StuffHeader() {
<div className="sub-table-box">
<div className="info-title">{getMessage('stuff.detail.header.lastEditDatetime')}</div>
<div className="info-inner">
{dayjs(headerData.lastEditDatetime).format('YYYY.MM.DD HH:mm:ss')} ({headerData.lastEditUserName})
{headerData?.lastEditDatetime ? `${dayjs(headerData.lastEditDatetime).format('YYYY.MM.DD HH:mm:ss')}` : ''}{' '}
{headerData?.lastEditUserName ? `(${headerData.lastEditUserName})` : null}
</div>
</div>
<div className="sub-table-box">
<div className="info-title">{getMessage('stuff.detail.header.createDatetime')}</div>
<div className="info-inner">
{dayjs(headerData.createDatetime).format('YYYY.MM.DD')} ({headerData.createUserName})
{headerData?.createDatetime ? `${dayjs(headerData.lastEditDatetime).format('YYYY.MM.DD')}` : ''}{' '}
{headerData?.createUserName ? `(${headerData.createUserName})` : null}
</div>
</div>
</div>

View File

@ -20,16 +20,20 @@ import DimensionLineSetting from '@/components/floor-plan/modal/dimensionLine/Di
import RoofAllocationSetting from '@/components/floor-plan/modal/roofAllocation/RoofAllocationSetting'
import LinePropertySetting from '@/components/floor-plan/modal/lineProperty/LinePropertySetting'
import FlowDirectionSetting from '@/components/floor-plan/modal/flowDirection/FlowDirectionSetting'
import { useMessage } from '@/hooks/useMessage'
import { useCanvasEvent } from '@/hooks/useCanvasEvent'
export function useContextMenu({ externalFn }) {
export function useContextMenu() {
const currentMenu = useRecoilValue(currentMenuState) // 현재 메뉴
const setContextPopupPosition = useSetRecoilState(contextPopupPositionState) // 현재 메뉴
const [contextMenu, setContextMenu] = useState([[]]) // 메뉴.object 별 context menu
const [currentContextMenu, setCurrentContextMenu] = useState(null) // 선택한 contextMenu
const currentObject = useRecoilValue(currentObjectState)
const { getMessage } = useMessage()
const { addPopup } = usePopup()
const [popupId, setPopupId] = useState(uuidv4())
const [gridColor, setGridColor] = useRecoilState(gridColorState)
const { handleZoomClear } = useCanvasEvent()
const currentMenuSetting = (position) => {
switch (currentMenu) {
case MENU.PLAN_DRAWING:
@ -37,26 +41,26 @@ export function useContextMenu({ externalFn }) {
[
{
id: 'gridMove',
name: '그리드 이동',
name: getMessage('modal.grid.move'),
component: <GridMove id={popupId} />,
},
{
id: 'gridCopy',
name: '그리드 복사',
name: getMessage('modal.grid.copy'),
component: <GridCopy id={popupId} />,
},
{
id: 'gridColorEdit',
name: '그리드 색 변경',
name: getMessage('modal.grid.color.edit'),
component: <ColorPickerModal id={popupId} color={gridColor} setColor={setGridColor} />,
},
{
id: 'remove',
name: '삭제',
name: getMessage('delete'),
},
{
id: 'removeAll',
name: '전체 삭제',
name: getMessage('delete.all'),
},
],
])
@ -75,63 +79,61 @@ export function useContextMenu({ externalFn }) {
[
{
id: 'refresh',
name: '새로고침',
fn: () => {
externalFn.handleZoomClear()
},
name: getMessage('refresh'),
fn: () => handleZoomClear(),
},
{
id: 'roofMaterialPlacement',
name: '지붕재 배치',
name: getMessage('contextmenu.roof.material.placement'),
},
{
id: 'roofMaterialRemove',
name: '지붕재 삭제',
name: getMessage('contextmenu.roof.material.remove'),
},
{
id: 'roofMaterialRemoveAll',
name: '지붕재 전체 삭제',
name: getMessage('contextmenu.roof.material.remove.all'),
},
{
id: 'selectMove',
name: '선택・이동',
name: getMessage('contextmenu.select.move'),
},
{
id: 'wallLineRemove',
name: '외벽선 삭제',
name: getMessage('contextmenu.wallline.remove'),
},
],
[
{
id: 'sizeEdit',
name: '사이즈 변경',
name: getMessage('contextmenu.size.edit'),
component: <AuxiliarySize id={popupId} />,
},
{
id: 'auxiliaryMove',
name: '보조선 이동(M)',
name: `${getMessage('contextmenu.auxiliary.move')}(M)`,
component: <AuxiliaryMove id={popupId} />,
},
{
id: 'auxiliaryCopy',
name: '보조선 복사(C)',
name: `${getMessage('contextmenu.auxiliary.copy')}(C)`,
component: <AuxiliaryCopy id={popupId} />,
},
{
id: 'auxiliaryRemove',
name: '보조선 삭제(D)',
name: `${getMessage('contextmenu.auxiliary.remove')}(D)`,
},
{
id: 'auxiliaryVerticalBisector',
name: '보조선 수직이등분선',
name: getMessage('contextmenu.auxiliary.vertical.bisector'),
},
{
id: 'auxiliaryCut',
name: '보조선 절삭',
name: getMessage('contextmenu.auxiliary.cut'),
},
{
id: 'auxiliaryRemoveAll',
name: '보조선 전체 삭제',
name: getMessage('contextmenu.auxiliary.remove.all'),
},
],
])
@ -146,33 +148,34 @@ export function useContextMenu({ externalFn }) {
[
{
id: 'sizeEdit',
name: '사이즈 변경',
name: getMessage('contextmenu.size.edit'),
},
{
id: 'remove',
name: '삭제(D)',
name: `${getMessage('contextmenu.remove')}(D)`,
},
{
id: 'move',
name: '이동(M)',
name: `${getMessage('contextmenu.move')}(M)`,
},
{
id: 'copy',
name: '복사(C)',
name: `${getMessage('contextmenu.copy')}(C)`,
},
],
[
{
id: 'roofMaterialEdit',
name: '지붕재 변경',
name: getMessage('contextmenu.roof.material.edit'),
},
{
id: 'linePropertyEdit',
name: '각 변 속성 변경',
name: getMessage('contextmenu.line.property.edit'),
component: <LinePropertySetting id={popupId} />,
},
{
id: 'flowDirectionEdit',
name: '흐름 방향 변경',
name: getMessage('contextmenu.flow.direction.edit'),
},
],
])
@ -200,7 +203,6 @@ export function useContextMenu({ externalFn }) {
}, [currentContextMenu])
useEffect(() => {
console.log('object name', currentObject?.name)
if (currentObject?.name) {
switch (currentObject.name) {
case 'triangleDormer':
@ -209,29 +211,29 @@ export function useContextMenu({ externalFn }) {
[
{
id: 'sizeEdit',
name: '사이즈 변경',
component: <SizeSetting id={popupId} />,
name: getMessage('contextmenu.size.edit'),
component: <SizeSetting id={popupId} target={currentObject} />,
},
{
id: 'dormerRemove',
name: '삭제(D)',
name: `${getMessage('contextmenu.remove')}(D)`,
},
{
id: 'dormerMove',
name: '이동(M)',
name: `${getMessage('contextmenu.move')}(M)`,
},
{
id: 'dormerCopy',
name: '복사(C)',
name: `${getMessage('contextmenu.copy')}(C)`,
},
{
id: 'roofMaterialEdit',
name: '지붕재 변경',
name: getMessage('contextmenu.roof.material.edit'),
component: <RoofMaterialSetting id={popupId} />,
},
{
id: 'dormerOffset',
name: '도머 오프셋',
name: getMessage('contextmenu.dormer.offset'),
component: <DormerOffset id={popupId} />,
},
],
@ -247,32 +249,32 @@ export function useContextMenu({ externalFn }) {
},
{
id: 'roofMaterialRemove',
name: '삭제(D)',
name: `${getMessage('contextmenu.remove')}(D)`,
},
{
id: 'roofMaterialMove',
name: '이동(M)',
name: `${getMessage('contextmenu.move')}(M)`,
},
{
id: 'roofMaterialCopy',
name: '복사(C)',
name: `${getMessage('contextmenu.copy')}(C)`,
},
],
[
{
id: 'roofMaterialEdit',
name: '지붕재 변경',
name: getMessage('contextmenu.roof.material.edit'),
component: <RoofAllocationSetting id={popupId} />,
},
{
id: 'linePropertyEdit',
name: '각 변 속성 변경',
name: getMessage('contextmenu.line.property.edit'),
component: <LinePropertySetting id={popupId} />,
},
{
id: 'flowDirectionEdit',
name: '흐름 뱡향 변경',
component: <FlowDirectionSetting id={popupId} />,
name: getMessage('contextmenu.flow.direction.edit'),
component: <FlowDirectionSetting id={popupId} target={currentObject} />,
},
],
])
@ -282,23 +284,23 @@ export function useContextMenu({ externalFn }) {
[
{
id: 'sizeEdit',
name: '사이즈 변경',
name: getMessage('contextmenu.size.edit'),
},
{
id: 'openingRemove',
name: '삭제(D)',
name: `${getMessage('contextmenu.remove')}(D)`,
},
{
id: 'openingMove',
name: '이동(M)',
name: `${getMessage('contextmenu.move')}(M)`,
},
{
id: 'openingCopy',
name: '복사(C)',
name: `${getMessage('contextmenu.copy')}(C)`,
},
{
id: 'openingOffset',
name: '개구 오프셋',
name: getMessage('contextmenu.opening.offset'),
},
],
])
@ -308,19 +310,19 @@ export function useContextMenu({ externalFn }) {
[
{
id: 'lengthTextRemove',
name: '삭제',
name: getMessage('contextmenu.remove'),
},
{
id: 'lengthTextMove',
name: '이동',
name: getMessage('contextmenu.move'),
},
{
id: 'lengthTextAuxiliaryLineEdit',
name: '치수 보조선 변경',
name: getMessage('contextmenu.dimension.auxiliary.line.edit'),
},
{
id: 'displayEdit',
name: '표시 변경',
name: getMessage('contextmenu.display.edit'),
},
],
])
@ -330,24 +332,24 @@ export function useContextMenu({ externalFn }) {
[
{
id: 'commonTextRemove',
name: '삭제',
name: getMessage('contextmenu.remove'),
},
{
id: 'commonTextMove',
name: '이동',
name: getMessage('contextmenu.move'),
},
{
id: 'commonTextCopy',
name: '복사',
name: getMessage('contextmenu.copy'),
},
{
id: 'commonTextFontSetting',
name: '폰트 설정',
name: getMessage('contextmenu.font.setting'),
component: <FontSetting id={popupId} type={'commonText'} />,
},
{
id: 'commonTextEdit',
name: '편집',
name: getMessage('contextmenu.edit'),
},
],
])
@ -357,23 +359,23 @@ export function useContextMenu({ externalFn }) {
[
{
id: 'gridMove',
name: '그리드 이동',
name: getMessage('modal.grid.move'),
},
{
id: 'gridCopy',
name: '그리드 복사',
name: getMessage('modal.grid.copy'),
},
{
id: 'gridColorEdit',
name: '그리드 색 변경',
name: getMessage('contextmenu.grid.color.edit'),
},
{
id: 'remove',
name: '삭제',
name: getMessage('contextmenu.remove'),
},
{
id: 'removeAll',
name: '전체 삭제',
name: getMessage('contextmenu.remove.all'),
},
],
])
@ -383,19 +385,19 @@ export function useContextMenu({ externalFn }) {
[
{
id: 'dimensionLineRemove',
name: '삭제',
name: getMessage('contextmenu.remove'),
},
{
id: 'dimensionLineMove',
name: '이동',
name: getMessage('contextmenu.move'),
},
{
id: 'dimensionAuxiliaryLineEdit',
name: '치수 보조선 변경',
name: getMessage('contextmenu.dimension.auxiliary.line.edit'),
},
{
id: 'dimensionLineDisplayEdit',
name: '표시 변경',
name: getMessage('contextmenu.display.edit'),
component: <DimensionLineSetting id={popupId} />,
},
],
@ -406,20 +408,20 @@ export function useContextMenu({ externalFn }) {
[
{
id: 'sizeEdit',
name: '사이즈 변경',
name: getMessage('contextmenu.size.edit'),
component: <SizeSetting id={popupId} />,
},
{
id: 'remove',
name: '삭제(D)',
name: `${getMessage('contextmenu.remove')}(D)`,
},
{
id: 'move',
name: '이동(M)',
name: `${getMessage('contextmenu.move')}(M)`,
},
{
id: 'copy',
name: '복사(C)',
name: `${getMessage('contextmenu.copy')}(C)`,
},
],
])

View File

@ -192,6 +192,8 @@
"modal.grid.copy.info": "間隔を設定し、コピー方向を選択します",
"modal.grid.copy.length": "長さ",
"modal.grid.copy.save": "保存",
"modal.grid.color.edit": "그리드 색 변경(JA)",
"modal.dormer.offset.info": "移動する方向を入力してください",
"modal.common.save": "保存",
"modal.common.add": "追加",
"modal.common.prev": "以前",
@ -261,12 +263,54 @@
"modal.placement.surface.setting.diagonal.length": "斜めの長さ",
"modal.color.picker.title": "色の設定",
"modal.color.picker.default.color": "基本色",
"modal.size.setting": "サイズ変更",
"modal.shape.flow.direction.setting": "面フローの設定",
"modal.shape.flow.direction.setting.orientation.setting.info": "シミュレーション計算の方向を指定します。面が向いている方位を選択してください。",
"modal.shape.flow.direction.setting.orientation.8": "8方位に選ぶ",
"modal.shape.flow.direction.setting.orientation.24": "24方位から選択する (表記は8方位です。)",
"modal.panel.batch.statistic": "パネル配置集計",
"modal.panel.batch.statistic.roof.shape": "屋根面",
"modal.panel.batch.statistic.power.generation.amount": "発電量",
"modal.panel.batch.statistic.total": "合計",
"modal.flow.direction.setting": "流れ方向の設定",
"modal.flow.direction.setting.info": "流れ方向を選択してください。",
"plan.message.confirm.save": "PLAN을 저장하시겠습니까?",
"plan.message.confirm.copy": "PLAN을 복사하시겠습니까?",
"plan.message.confirm.delete": "PLAN을 삭제하시겠습니까?",
"plan.message.save": "저장되었습니다.",
"plan.message.delete": "삭제되었습니다.",
"setting": "設定",
"delete": "삭제(JA)",
"delete.all": "전체 삭제(JA)",
"refresh": "새로고침(JA)",
"contextmenu.roof.material.placement": "지붕재 배치(JA)",
"contextmenu.roof.material.edit": "지붕재 변경(JA)",
"contextmenu.roof.material.remove": "지붕재 삭제(JA)",
"contextmenu.roof.material.remove.all": "지붕재 전체 삭제(JA)",
"contextmenu.dormer.offset": "도머 오프셋(JA)",
"contextmenu.select.move": "선택・이동(JA)",
"contextmenu.wallline.remove": "외벽선 삭제(JA)",
"contextmenu.size.edit": "サイズ変更",
"contextmenu.auxiliary.move": "보조선 이동(JA)",
"contextmenu.auxiliary.copy": "보조선 복사(JA)",
"contextmenu.auxiliary.remove": "보조선 삭제(JA)",
"contextmenu.auxiliary.vertical.bisector": "보조선 수직이등분선(JA)",
"contextmenu.auxiliary.cut": "보조선 절삭(JA)",
"contextmenu.auxiliary.remove.all": "보조선 전체 삭제(JA)",
"contextmenu.line.property.edit": "各辺属性の変更",
"modal.line.property.edit.info": "属性を変更する辺を選択してください。",
"modal.line.property.edit.selected": "選択した値",
"contextmenu.flow.direction.edit": "흐름 방향 변경(JA)",
"contextmenu.font.setting": "폰트 설정(JA)",
"contextmenu.grid.color.edit": "그리드 색 변경(JA)",
"contextmenu.dimension.auxiliary.line.edit": "치수 보조선 변경(JA)",
"contextmenu.display.edit": "표시 변경(JA)",
"contextmenu.opening.offset": "개구 오프셋(JA)",
"contextmenu.remove": "삭제(JA)",
"contextmenu.remove.all": "전체 삭제(JA)",
"contextmenu.move": "이동(JA)",
"contextmenu.copy": "복사(JA)",
"contextmenu.edit": "편집(JA)",
"common.message.no.data": "No data",
"common.message.no.dataDown": "ダウンロードするデータがありません",
"common.message.noData": "表示するデータがありません",
@ -357,7 +401,7 @@
"common.require": "必須",
"commons.west": "立つ",
"commons.east": "ドン",
"commons.south": "立つ",
"commons.south": "",
"commons.north": "北",
"site.name": "Q.CAST III",
"site.sub_name": "太陽光発電システム図面管理サイト",
@ -600,9 +644,23 @@
"size": "寸",
"size.angle": "寸(度)",
"eaves": "軒",
"eaves.line": "軒先",
"gable": "ケラバ",
"gable.left": "ケラバ左",
"gable.right": "ケラバ右",
"ridge": "龍丸",
"oneside.flow.ridge": "片側の流れ",
"yosemune": "ヨセムネ",
"valley": "谷",
"l.abandon.valley": "Lの捨て渓谷",
"mansard": "マンサード",
"wall": "壁",
"wall.merge": "壁取り",
"wall.merge.type": "壁取り(型)",
"wall.merge.flow": "壁取合(流れ)",
"wall.merge.flow.left": "壁取合(流れ左)",
"wall.merge.flow.right": "壁取り(流れ右)",
"no.setting": "설정없음",
"hajebichi": "ハゼビーチ",
"straight.line": "直線",
"right.angle": "直角",

View File

@ -196,6 +196,8 @@
"modal.grid.copy.info": "간격을 설정하고 복사 방향을 선택하십시오",
"modal.grid.copy.length": "길이",
"modal.grid.copy.save": "저장",
"modal.grid.color.edit": "그리드 색 변경",
"modal.dormer.offset.info": "이동할 거리와 방향을 입력해주세요.",
"modal.common.save": "저장",
"modal.common.add": "추가",
"modal.common.prev": "이전",
@ -266,12 +268,54 @@
"modal.placement.surface.setting.diagonal.length": "대각선 길이",
"modal.color.picker.title": "색 설정",
"modal.color.picker.default.color": "기본색상",
"modal.size.setting": "사이즈 변경",
"modal.shape.flow.direction.setting": "면 흐름 설정",
"modal.shape.flow.direction.setting.orientation.setting.info": "시뮬레이션 계산용 방위를 지정합니다. 면이 향하고 있는 방위를 선택해 주세요.",
"modal.shape.flow.direction.setting.orientation.8": "8방위로 선택한다.",
"modal.shape.flow.direction.setting.orientation.24": "24방위로 선택한다.(표기는 8방위입니다.)",
"modal.panel.batch.statistic": "패널 배치 집계",
"modal.panel.batch.statistic.roof.shape": "지붕면",
"modal.panel.batch.statistic.power.generation.amount": "발전량",
"modal.panel.batch.statistic.total": "합계",
"modal.flow.direction.setting": "흐름 방향 설정",
"modal.flow.direction.setting.info": "흐름방향을 선택하세요.",
"plan.message.confirm.save": "PLAN을 저장하시겠습니까?",
"plan.message.confirm.copy": "PLAN을 복사하시겠습니까?",
"plan.message.confirm.delete": "PLAN을 삭제하시겠습니까?",
"plan.message.save": "저장되었습니다.",
"plan.message.delete": "삭제되었습니다.",
"setting": "설정",
"delete": "삭제",
"delete.all": "전체 삭제",
"refresh": "새로고침",
"contextmenu.roof.material.placement": "지붕재 배치",
"contextmenu.roof.material.edit": "지붕재 변경",
"contextmenu.roof.material.remove": "지붕재 삭제",
"contextmenu.roof.material.remove.all": "지붕재 전체 삭제",
"contextmenu.dormer.offset": "도머 오프셋",
"contextmenu.select.move": "선택・이동",
"contextmenu.wallline.remove": "외벽선 삭제",
"contextmenu.size.edit": "사이즈 변경",
"contextmenu.auxiliary.move": "보조선 이동",
"contextmenu.auxiliary.copy": "보조선 복사",
"contextmenu.auxiliary.remove": "보조선 삭제",
"contextmenu.auxiliary.vertical.bisector": "보조선 수직이등분선",
"contextmenu.auxiliary.cut": "보조선 절삭",
"contextmenu.auxiliary.remove.all": "보조선 전체 삭제",
"contextmenu.line.property.edit": "각 변 속성 변경",
"modal.line.property.edit.info": "속성을 변경할 변을 선택해주세요.",
"modal.line.property.edit.selected": "선택한 값",
"contextmenu.flow.direction.edit": "흐름 방향 변경",
"contextmenu.font.setting": "폰트 설정",
"contextmenu.grid.color.edit": "그리드 색 변경",
"contextmenu.dimension.auxiliary.line.edit": "치수 보조선 변경",
"contextmenu.display.edit": "표시 변경",
"contextmenu.opening.offset": "개구 오프셋",
"contextmenu.remove": "삭제",
"contextmenu.remove.all": "전체 삭제",
"contextmenu.move": "이동",
"contextmenu.copy": "복사",
"contextmenu.edit": "편집",
"common.message.no.data": "No data",
"common.message.no.dataDown": "No data to download",
"common.message.noData": "No data to display",
@ -605,9 +649,23 @@
"size": "치수",
"size.angle": "寸(度)",
"eaves": "처마",
"eaves.line": "처마선",
"gable": "케라바",
"gable.left": "케라바 왼쪽",
"gable.right": "케라바 오른쪽",
"ridge": "용마루",
"oneside.flow.ridge": "한쪽흐름 용마루",
"yosemune": "요세무네",
"valley": "골짜기",
"l.abandon.valley": "L의 버림 계곡",
"mansard": "멘사드",
"wall": "벽",
"wall.merge": "벽취합",
"wall.merge.type": "벽취합(형)",
"wall.merge.flow": "벽취합(흐름)",
"wall.merge.flow.left": "벽취합(흐름 왼쪽)",
"wall.merge.flow.right": "벽취합(흐름 오른쪽)",
"no.setting": "설정없음",
"hajebichi": "하제비치",
"straight.line": "직선",
"right.angle": "직각",

View File

@ -4,30 +4,28 @@
top: 200px;
left: 50px;
z-index: 999999;
display: flex;
width: 237px;
height: 40px;
line-height: 40px;
background-color: #fff;
border: 1px solid #DFDFDF;
padding: 0 34px 0 10px;
padding: 0 10px 0 10px;
border-radius: 2px;
box-shadow: 0px 7px 14px 0px rgba(0, 0, 0, 0.05);
cursor: pointer;
&::before{
content: '';
position: absolute;
top: 50%;
right: 12px;
transform: translateY(-50%);
width: 10px;
height: 6px;
.penal-arr{
flex: none;
width: 24px;
height: 100%;
background: url(../../public/static/images/canvas/penal_arr.svg)no-repeat center;
background-size: cover;
background-size: 10px 6px;
}
h2{
font-size: 12px;
font-weight: 500;
color: #3D3D3D;
flex: 1;
}
.penal-table-wrap{
display: none;
@ -69,7 +67,7 @@
h2{
color: #fff;
}
&::before{
.penal-arr{
background: url(../../public/static/images/canvas/penal_arr_white.svg)no-repeat center;
}
.penal-table-wrap{

View File

@ -679,7 +679,6 @@
.infomation-box-wrap{
display: flex;
align-items: center;
gap: 10px;
.sub-table-box{
flex: 1 ;

View File

@ -482,6 +482,9 @@ input[type=text]{
}
&:read-only{
color: #AAA;
&:focus{
border: 1px solid #323234;
}
}
&.plane{
font-family: 'Noto Sans JP', sans-serif;
@ -509,6 +512,9 @@ input[type=text]{
&:read-only{
background-color: #FAFAFA;
color: #999999;
&:focus{
border-color: #eee;
}
}
}
}