diff --git a/src/components/management/StuffSubHeader.jsx b/src/components/management/StuffSubHeader.jsx
index f1103143..12a51394 100644
--- a/src/components/management/StuffSubHeader.jsx
+++ b/src/components/management/StuffSubHeader.jsx
@@ -25,58 +25,90 @@ export default function StuffSubHeader({ type }) {
const moveFloorPlan = () => {
setFloorPlanObjectNo({ floorPlanObjectNo: objectNo })
- router.push('/floor-plan')
+ //상단 헤더에서 이동할땐 무조건 첫번째 플랜으로
+ router.push('/floor-plan/estimate/5/1')
}
return (
-
-
- {type === 'list' && (
-
-
{getMessage('header.menus.management')}
-
- )}
- {type === 'temp' && (
-
- -
-
- {getMessage('stuff.temp.subTitle')}
+ <>
+
+
+ {type === 'list' && (
+ <>
+
+
{getMessage('header.menus.management')}
-
-
- )}
- {type === 'detail' && (
-
- )}
-
- {type !== 'detail' && (
-
- -
-
-
-
-
- -
- {getMessage('header.menus.management')}
-
- -
- {getMessage('header.menus.management.stuff')}
-
-
- )}
+
+ -
+
+
+
+
+ -
+ {getMessage('header.menus.management')}
+
+ -
+ {getMessage('header.menus.management.stuffList')}
+
+
+ >
+ )}
+ {type === 'temp' && (
+ <>
+
+ -
+
+ {getMessage('stuff.temp.subTitle')}
+
+
+
+
+ -
+
+
+
+
+ -
+ {getMessage('header.menus.management')}
+
+ -
+ {getMessage('header.menus.management.newStuff')}
+
+
+ >
+ )}
+ {type === 'detail' && (
+ <>
+
+
+ -
+
+
+
+
+ -
+ {getMessage('header.menus.management')}
+
+ -
+ {getMessage('header.menus.management.newStuff')}
+
+
+ >
+ )}
+
-
+ >
)
}
diff --git a/src/hooks/common/useMenu.js b/src/hooks/common/useMenu.js
new file mode 100644
index 00000000..75905a73
--- /dev/null
+++ b/src/hooks/common/useMenu.js
@@ -0,0 +1,95 @@
+import WallLineSetting from '@/components/floor-plan/modal/outerlinesetting/WallLineSetting'
+import RoofShapeSetting from '@/components/floor-plan/modal/roofShape/RoofShapeSetting'
+import RoofShapePassivitySetting from '@/components/floor-plan/modal/roofShape/RoofShapePassivitySetting'
+import AuxiliaryDrawing from '@/components/floor-plan/modal/auxiliary/AuxiliaryDrawing'
+import EavesGableEdit from '@/components/floor-plan/modal/eavesGable/EavesGableEdit'
+import MovementSetting from '@/components/floor-plan/modal/movement/MovementSetting'
+import WallLineOffsetSetting from '@/components/floor-plan/modal/wallLineOffset/WallLineOffsetSetting'
+import RoofAllocationSetting from '@/components/floor-plan/modal/roofAllocation/RoofAllocationSetting'
+import Slope from '@/components/floor-plan/modal/Slope'
+import PlacementShapeDrawing from '@/components/floor-plan/modal/placementShape/PlacementShapeDrawing'
+import PlacementSurfaceSetting from '@/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting'
+import ObjectSetting from '@/components/floor-plan/modal/object/ObjectSetting'
+import BasicSetting from '@/components/floor-plan/modal/basic/BasicSetting'
+import CircuitTrestleSetting from '@/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting'
+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 { currentMenuState } from '@/store/canvasAtom'
+import { MENU } from '@/common/common'
+
+export default function useMenu() {
+ const menus = []
+ const currentMenu = useRecoilValue(currentMenuState)
+ const [popupId, setPopupId] = useState(uuidv4())
+ const { addPopup } = usePopup()
+ const { deleteAllSurfacesAndObjects } = useSurfaceShapeBatch()
+ const handleMenu = (type) => {
+ if (type === 'outline') {
+ switch (currentMenu) {
+ case MENU.ROOF_COVERING.EXTERIOR_WALL_LINE:
+ addPopup(popupId, 1, )
+ break
+ case MENU.ROOF_COVERING.ROOF_SHAPE_SETTINGS:
+ addPopup(popupId, 1, )
+ break
+ case MENU.ROOF_COVERING.ROOF_SHAPE_PASSIVITY_SETTINGS:
+ addPopup(popupId, 1, )
+ break
+ case MENU.ROOF_COVERING.HELP_LINE_DRAWING:
+ addPopup(popupId, 1, )
+ break
+ case MENU.ROOF_COVERING.EAVES_KERAVA_EDIT:
+ addPopup(popupId, 1, )
+ break
+ case MENU.ROOF_COVERING.MOVEMENT_SHAPE_UPDOWN:
+ addPopup(popupId, 1, )
+ break
+ case MENU.ROOF_COVERING.OUTLINE_EDIT_OFFSET:
+ addPopup(popupId, 1, )
+ break
+ case MENU.ROOF_COVERING.ROOF_SHAPE_ALLOC:
+ addPopup(popupId, 1, )
+ break
+ }
+ }
+
+ if (type === 'surface') {
+ switch (currentMenu) {
+ case MENU.BATCH_CANVAS.SLOPE_SETTING:
+ addPopup(popupId, 1, )
+ break
+ case MENU.BATCH_CANVAS.BATCH_DRAWING:
+ addPopup(popupId, 1, )
+ break
+ case MENU.BATCH_CANVAS.SURFACE_SHAPE_BATCH:
+ addPopup(popupId, 1, )
+ break
+ case MENU.BATCH_CANVAS.OBJECT_BATCH:
+ addPopup(popupId, 1, )
+ break
+ case MENU.BATCH_CANVAS.ALL_REMOVE:
+ deleteAllSurfacesAndObjects()
+ break
+ }
+ }
+
+ if (type === 'module') {
+ switch (currentMenu) {
+ case MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING:
+ addPopup(popupId, 1, )
+ break
+ case MENU.MODULE_CIRCUIT_SETTING.CIRCUIT_TRESTLE_SETTING:
+ addPopup(popupId, 1, )
+ break
+ }
+ }
+ }
+
+ return {
+ menus,
+ handleMenu,
+ }
+}
diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js
new file mode 100644
index 00000000..0f87e156
--- /dev/null
+++ b/src/hooks/option/useCanvasSetting.js
@@ -0,0 +1,305 @@
+import { useEffect, useState } from 'react'
+import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
+import { canvasState } from '@/store/canvasAtom'
+import { globalLocaleStore } from '@/store/localeAtom'
+import { useMessage } from '@/hooks/useMessage'
+import { useAxios } from '@/hooks/useAxios'
+import { useSwal } from '@/hooks/useSwal'
+import { settingModalFirstOptionsState, settingModalSecondOptionsState } from '@/store/settingAtom'
+import { setSurfaceShapePattern } from '@/util/canvas-util'
+import { POLYGON_TYPE } from '@/common/common'
+
+import { adsorptionPointModeState, adsorptionRangeState } from '@/store/canvasAtom'
+
+export function useCanvasSetting() {
+ const canvas = useRecoilValue(canvasState)
+
+ const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState)
+ const [settingModalSecondOptions, setSettingModalSecondOptions] = useRecoilState(settingModalSecondOptionsState)
+ const { option1, option2, dimensionDisplay } = settingModalFirstOptions
+ const { option3, option4 } = settingModalSecondOptions
+
+ const globalLocaleState = useRecoilValue(globalLocaleStore)
+ const { get, post } = useAxios(globalLocaleState)
+ const { getMessage } = useMessage()
+ const { swalFire } = useSwal()
+
+ const [adsorptionPointMode, setAdsorptionPointMode] = useRecoilState(adsorptionPointModeState)
+ const setAdsorptionRange = useSetRecoilState(adsorptionRangeState)
+
+ const [objectNo, setObjectNo] = useState('test123240912001') // 이후 삭제 필요
+
+ useEffect(() => {
+ console.log('useCanvasSetting useEffect 실행1')
+ fetchSettings()
+ }, [objectNo])
+
+ useEffect(() => {
+ console.log('useCanvasSetting useEffect 실행2')
+ //fetchSettings()
+ //onClickOption()
+ //fetchSettings()
+ }, [adsorptionPointMode])
+
+ useEffect(() => {
+ console.log('useCanvasSetting useEffect 실행3')
+ //fetchSettings()
+ //onClickOption()
+ //fetchSettings()
+ }, [settingModalFirstOptions, settingModalSecondOptions])
+
+ const fetchSettings = async () => {
+ try {
+ const res = await get({ url: `/api/canvas-management/canvas-settings/by-object/${objectNo}` })
+ console.log('res', res)
+ const optionData1 = settingModalFirstOptions.option1.map((item) => ({ ...item, selected: res[item.column] }))
+ const optionData2 = settingModalFirstOptions.option2.map((item) => ({ ...item, selected: res[item.column] }))
+ const optionData3 = settingModalSecondOptions.option3.map((item) => ({ ...item }))
+ const optionData4 = settingModalSecondOptions.option4.map((item) => ({ ...item, selected: res[item.column] }))
+ const optionData5 = settingModalFirstOptions.dimensionDisplay.map((item) => ({ ...item }))
+
+ const patternData = {
+ adsorpPoint: res.adsorpPoint,
+ }
+
+ // 데이터 설정
+ setSettingModalFirstOptions({
+ option1: optionData1,
+ option2: optionData2,
+ dimensionDisplay: optionData5,
+ })
+ setSettingModalSecondOptions({
+ option3: optionData3,
+ option4: optionData4,
+ })
+
+ setAdsorptionPointMode(patternData.adsorpPoint)
+
+ console.log('adsorptionPointMode', adsorptionPointMode)
+ } catch (error) {
+ console.error('Data fetching error:', error)
+ }
+ }
+
+ // 옵션 클릭 후 저장
+ const onClickOption = async (item) => {
+ //치수 표시(단 건 선택)
+ if (item.column === 'corridorDimension' || item.column === 'realDimension' || item.column === 'noneDimension') {
+ console.log('치수 표시 ', item)
+ const options = settingModalFirstOptions?.dimensionDisplay.map((option) => {
+ option.selected = option.id === item.id
+ return option
+ })
+
+ //화면 표시(단 건 선택)
+ } else if (item.column === 'onlyBorder' || item.column === 'lineHatch' || item.column === 'allPainted') {
+ console.log('화면 표시 ', item)
+ const options2 = settingModalFirstOptions?.option2.map((option2) => {
+ option2.selected = option2.id === item.id
+ return option2
+ })
+
+ const polygons = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
+
+ polygons.forEach((polygon) => {
+ setSurfaceShapePattern(polygon, item.column)
+ })
+
+ //흡착범위 설정(단 건 선택)
+ } else if (
+ item.column === 'adsorpRangeSmall' ||
+ item.column === 'adsorpRangeSmallSemi' ||
+ item.column === 'adsorpRangeMedium' ||
+ item.column === 'adsorpRangeLarge'
+ ) {
+ console.log('화면 표시2 ', item, option4)
+ // option4에서 한 개만 선택 가능하도록 처리
+ const updatedOption4 = option4.map((option) =>
+ option.id === item.id
+ ? { ...option, selected: true }
+ : {
+ ...option,
+ selected: false,
+ },
+ )
+
+ setSettingModalSecondOptions({ option3, option4: updatedOption4 })
+
+ //흡착점 ON / OFF
+ } else if (item === 'adsorpPoint') {
+ console.log('흡착점 ON / OFF ', item)
+ const options2 = settingModalFirstOptions?.option2.map((option2) => {
+ option2.selected = option2.id === item.id
+ return option2
+ })
+
+ const polygons = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
+
+ polygons.forEach((polygon) => {
+ setSurfaceShapePattern(polygon, item.column)
+ })
+
+ //디스플레이 설정(다 건 선택)
+ } else {
+ //console.log('디스플레이 설정1 ', item.column)
+ console.log('디스플레이 설정 ', item)
+ item.selected = !item.selected
+ }
+
+ setSettingModalFirstOptions({ option1, option2, dimensionDisplay })
+
+ try {
+ // 서버에 전송할 데이터
+ const dataToSend = {
+ firstOption1: option1.map((item) => ({
+ column: item.column,
+ selected: item.selected,
+ })),
+ firstOption2: option2.map((item) => ({
+ column: item.column,
+ selected: item.selected,
+ })),
+ firstOption3: dimensionDisplay.map((item) => ({
+ column: item.column,
+ selected: item.selected,
+ })),
+ // secondOption1: secondOptions[0].option1.map((item) => ({
+ // name: item.id,
+ // name: item.name,
+ // // 필요한 경우 데이터 항목 추가
+ // })),
+ secondOption2: option4.map((item) => ({
+ column: item.column,
+ selected: item.selected,
+ })),
+ }
+
+ const patternData = {
+ objectNo,
+ //디스플레이 설정(다중)
+ allocDisplay: dataToSend.firstOption1[0].selected,
+ outlineDisplay: dataToSend.firstOption1[1].selected,
+ gridDisplay: dataToSend.firstOption1[2].selected,
+ lineDisplay: dataToSend.firstOption1[3].selected,
+ wordDisplay: dataToSend.firstOption1[4].selected,
+ circuitNumDisplay: dataToSend.firstOption1[5].selected,
+ flowDisplay: dataToSend.firstOption1[6].selected,
+ trestleDisplay: dataToSend.firstOption1[7].selected,
+ imageDisplay: dataToSend.firstOption1[8].selected,
+ totalDisplay: dataToSend.firstOption1[9].selected,
+ //차수 표시(단 건)
+ corridorDimension: dataToSend.firstOption3[0].selected,
+ realDimension: dataToSend.firstOption3[1].selected,
+ noneDimension: dataToSend.firstOption3[2].selected,
+ //화면 표시(단 건)
+ onlyBorder: dataToSend.firstOption2[0].selected,
+ lineHatch: dataToSend.firstOption2[1].selected,
+ allPainted: dataToSend.firstOption2[2].selected,
+ //흡착범위 설정(단 건)
+ adsorpRangeSmall: dataToSend.secondOption2[0].selected,
+ adsorpRangeSmallSemi: dataToSend.secondOption2[1].selected,
+ adsorpRangeMedium: dataToSend.secondOption2[2].selected,
+ adsorpRangeLarge: dataToSend.secondOption2[3].selected,
+ //흡착점 ON/OFF
+ adsorpPoint: adsorptionPointMode,
+ }
+
+ console.log('patternData ', patternData)
+
+ // HTTP POST 요청 보내기
+ await post({ url: `/api/canvas-management/canvas-settings`, data: patternData }).then((res) => {
+ swalFire({ text: getMessage(res.returnMessage) })
+
+ // Canvas 디스플레이 설정 시 해당 옵션 적용
+ frontSettings()
+ })
+ } catch (error) {
+ swalFire({ text: getMessage(res.returnMessage), icon: 'error' })
+ }
+
+ setAdsorptionRange(item.range)
+ }
+
+ // Canvas 디스플레이 설정 시 해당 옵션 적용
+ const frontSettings = async () => {
+ const option1 = settingModalFirstOptions.option1
+
+ // 'allocDisplay' 할당 표시
+ // 'outlineDisplay' 외벽선 표시 'outerLine', 'wallLine'
+ // 'gridDisplay' 그리드 표시 'lindGrid', 'dotGrid'
+ // 'lineDisplay' 지붕선 표시 'roof', 'roofBase'
+ // 'wordDisplay' 문자 표시
+ // 'circuitNumDisplay' 회로번호 표시
+ // 'flowDisplay' 흐름방향 표시 'arrow'
+ // 'trestleDisplay' 가대 표시
+ // 'imageDisplay' 이미지 표시
+ // 'totalDisplay' 집계표 표시
+
+ let optionName //옵션명
+ let optionSelected //옵션상태
+
+ for (let i = 0; i < option1.length; i++) {
+ switch (option1[i].column) {
+ case 'allocDisplay': //할당 표시
+ optionName = ['1']
+ break
+ case 'outlineDisplay': //외벽선 표시
+ optionName = ['outerLine', 'wallLine']
+ break
+ case 'gridDisplay': //그리드 표시
+ optionName = ['lindGrid', 'dotGrid']
+ break
+ case 'lineDisplay': //지붕선 표시
+ optionName = ['roof', 'roofBase']
+ break
+ case 'wordDisplay': //문자 표시
+ optionName = ['6']
+ break
+ case 'circuitNumDisplay': //회로번호 표시
+ optionName = ['7']
+ break
+ case 'flowDisplay': //흐름방향 표시
+ optionName = ['arrow']
+ break
+ case 'trestleDisplay': //가대 표시
+ optionName = ['8']
+ break
+ case 'imageDisplay': //이미지 표시
+ optionName = ['9']
+ break
+ case 'totalDisplay': //집계표 표시
+ optionName = ['10']
+ break
+ }
+ // 표시 선택 상태(true/false)
+ optionSelected = option1[i].selected
+
+ canvas
+ .getObjects()
+ .filter((obj) => optionName.includes(obj.name))
+ //.filter((obj) => obj.name === optionName)
+ .forEach((obj) => {
+ obj.set({ visible: optionSelected })
+ //obj.set({ visible: !obj.visible })
+ })
+
+ // console.log(
+ // 'optionName',
+ // optionName,
+ // canvas.getObjects().filter((obj) => optionName.includes(obj.name)),
+ // )
+ }
+ }
+
+ return {
+ settingModalFirstOptions,
+ setSettingModalFirstOptions,
+ settingModalSecondOptions,
+ setSettingModalSecondOptions,
+ adsorptionPointMode,
+ setAdsorptionPointMode,
+ fetchSettings,
+ onClickOption,
+ frontSettings,
+ }
+}
diff --git a/src/hooks/option/useCanvasSettingController.js b/src/hooks/option/useCanvasSettingController.js
index 72a590eb..48db6c08 100644
--- a/src/hooks/option/useCanvasSettingController.js
+++ b/src/hooks/option/useCanvasSettingController.js
@@ -46,6 +46,7 @@ export const useCanvasSettingController = () => {
}
}
+ //
const onClickOption = async (option) => {
option.selected = !option.selected
diff --git a/src/hooks/roofcover/useEavesGableEdit.js b/src/hooks/roofcover/useEavesGableEdit.js
index b0085019..7696dc7a 100644
--- a/src/hooks/roofcover/useEavesGableEdit.js
+++ b/src/hooks/roofcover/useEavesGableEdit.js
@@ -170,7 +170,10 @@ export function useEavesGableEdit(id) {
})
const wallLines = canvas.getObjects().filter((obj) => obj.name === 'wallLine')
-
+ const removeTargets = canvas.getObjects().filter((obj) => obj.name === 'pitchText')
+ removeTargets.forEach((obj) => {
+ canvas.remove(obj)
+ })
wallLines.forEach((wallLine) => {
addPitchTextsByOuterLines()
const roof = drawRoofPolygon(wallLine)
diff --git a/src/hooks/roofcover/useMovementSetting.js b/src/hooks/roofcover/useMovementSetting.js
new file mode 100644
index 00000000..355a6bf8
--- /dev/null
+++ b/src/hooks/roofcover/useMovementSetting.js
@@ -0,0 +1,48 @@
+import { useRecoilValue } from 'recoil'
+import { canvasState } from '@/store/canvasAtom'
+import { usePopup } from '@/hooks/usePopup'
+import { useMessage } from '@/hooks/useMessage'
+import { useRef, useState } from 'react'
+
+//동선이동 형 올림 내림
+export function useMovementSetting(id) {
+ const TYPE = {
+ FLOW_LINE: 'flowLine', // 동선이동
+ UP_DOWN: 'updown', //형 올림내림
+ }
+ const canvas = useRecoilValue(canvasState)
+ const { closePopup } = usePopup()
+ const { getMessage } = useMessage()
+ const buttonType = [
+ { id: 1, name: getMessage('modal.movement.flow.line.move'), type: TYPE.FLOW_LINE },
+ { id: 2, name: getMessage('modal.movement.flow.line.updown'), type: TYPE.UP_DOWN },
+ ]
+ const [type, setType] = useState(TYPE.FLOW_LINE)
+
+ const FLOW_LINE_REF = {
+ DOWN_LEFT_INPUT_REF: useRef(null),
+ UP_RIGHT_INPUT_REF: useRef(null),
+ DOWN_LEFT_RADIO_REF: useRef(null),
+ UP_RIGHT_RADIO_REF: useRef(null),
+ }
+
+ const UP_DOWN_REF = {
+ UP_INPUT_REF: useRef(null),
+ DOWN_INPUT_REF: useRef(null),
+ UP_RADIO_REF: useRef(null),
+ DOWN_RADIO_REF: useRef(null),
+ }
+
+ const handleSave = () => {}
+
+ return {
+ TYPE,
+ closePopup,
+ buttonType,
+ type,
+ setType,
+ FLOW_LINE_REF,
+ UP_DOWN_REF,
+ handleSave,
+ }
+}
diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js
index 3f355111..3be745d6 100644
--- a/src/hooks/roofcover/useRoofAllocationSetting.js
+++ b/src/hooks/roofcover/useRoofAllocationSetting.js
@@ -130,6 +130,12 @@ export function useRoofAllocationSetting(id) {
setSurfaceShapePattern(roof, roofDisplay.column)
drawDirectionArrow(roof)
})
+
+ const removeTargets = canvas.getObjects().filter((obj) => obj.name === 'outerLinePoint' || obj.name === 'outerLine')
+ removeTargets.forEach((obj) => {
+ canvas.remove(obj)
+ })
+
closePopup(id)
}
diff --git a/src/hooks/useCanvas.js b/src/hooks/useCanvas.js
index 886407b4..6ffb03fc 100644
--- a/src/hooks/useCanvas.js
+++ b/src/hooks/useCanvas.js
@@ -13,6 +13,7 @@ import { writeImage } from '@/lib/canvas'
import { useCanvasEvent } from '@/hooks/useCanvasEvent'
import { useAxios } from '@/hooks/useAxios'
import { useFont } from '@/hooks/common/useFont'
+import { OBJECT_PROTOTYPE, RELOAD_TYPE_PROTOTYPE, SAVE_KEY } from '@/common/common'
export function useCanvas(id) {
const [canvas, setCanvas] = useRecoilState(canvasState)
@@ -103,6 +104,20 @@ export function useCanvas(id) {
fabric.Object.prototype.cornerStyle = 'rect'
fabric.Object.prototype.cornerStrokeColor = '#2BEBC8'
fabric.Object.prototype.cornerSize = 6
+
+ // 해당 오브젝트 타입의 경우 저장한 값 그대로 불러와야함
+ OBJECT_PROTOTYPE.forEach((type) => {
+ type.toObject = function (propertiesToInclude) {
+ let source = {}
+ for (let key in this) {
+ if (typeof this[key] !== 'function' && SAVE_KEY.includes(key)) {
+ source.key = this[key]
+ }
+ }
+ return fabric.util.object.extend(this.callSuper('toObject', propertiesToInclude), source)
+ }
+ })
+
fabric.QLine = QLine
fabric.QPolygon = QPolygon
QPolygon.prototype.canvas = canvas
diff --git a/src/hooks/useContextMenu.js b/src/hooks/useContextMenu.js
index 7549f8e1..a5c6143c 100644
--- a/src/hooks/useContextMenu.js
+++ b/src/hooks/useContextMenu.js
@@ -25,6 +25,7 @@ import { useCommonUtils } from './common/useCommonUtils'
import { useMessage } from '@/hooks/useMessage'
import { useCanvasEvent } from '@/hooks/useCanvasEvent'
import { contextMenuState } from '@/store/contextMenu'
+import ImageSizeSetting from '@/components/floor-plan/modal/image/ImageSizeSetting'
export function useContextMenu() {
const currentMenu = useRecoilValue(currentMenuState) // 현재 메뉴
@@ -40,7 +41,7 @@ export function useContextMenu() {
const [qContextMenu, setQContextMenu] = useRecoilState(contextMenuState)
const { handleZoomClear } = useCanvasEvent()
- const currentMenuSetting = (position) => {
+ const currentMenuSetting = () => {
switch (currentMenu) {
case MENU.PLAN_DRAWING:
setContextMenu([
@@ -108,6 +109,11 @@ export function useContextMenu() {
id: 'wallLineRemove',
name: getMessage('contextmenu.wallline.remove'),
},
+ {
+ id: 'imageSizeEdit',
+ name: getMessage('modal.image.size.setting'),
+ component: ,
+ },
],
[
{
@@ -174,6 +180,11 @@ export function useContextMenu() {
shortcut: ['c', 'C'],
name: `${getMessage('contextmenu.copy')}(C)`,
},
+ {
+ id: 'imageSizeEdit',
+ name: getMessage('modal.image.size.setting'),
+ component: ,
+ },
],
[
{
diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js
index 1cced0f0..ee3439f2 100644
--- a/src/hooks/usePlan.js
+++ b/src/hooks/usePlan.js
@@ -5,6 +5,7 @@ import { canvasState, currentCanvasPlanState, initCanvasPlansState, plansState,
import { useAxios } from '@/hooks/useAxios'
import { useMessage } from '@/hooks/useMessage'
import { useSwal } from '@/hooks/useSwal'
+import { SAVE_KEY } from '@/common/common'
export function usePlan() {
const [planNum, setPlanNum] = useState(0)
@@ -33,41 +34,7 @@ export function usePlan() {
}
const addCanvas = () => {
- const objs = canvas?.toJSON([
- 'selectable',
- 'name',
- 'parentId',
- 'id',
- 'length',
- 'idx',
- 'direction',
- 'parentDirection',
- 'lines',
- 'points',
- 'lockMovementX',
- 'lockMovementY',
- 'lockRotation',
- 'lockScalingX',
- 'lockScalingY',
- 'opacity',
- 'cells',
- 'maxX',
- 'maxY',
- 'minX',
- 'minY',
- 'x',
- 'y',
- 'x1',
- 'x2',
- 'y1',
- 'y2',
- 'attributes',
- 'stickeyPoint',
- 'text',
- 'pitch',
- 'uuid',
- 'originText',
- ])
+ const objs = canvas?.toJSON(SAVE_KEY)
const str = JSON.stringify(objs)
diff --git a/src/lib/authActions.js b/src/lib/authActions.js
index 618985b9..0834833e 100644
--- a/src/lib/authActions.js
+++ b/src/lib/authActions.js
@@ -52,6 +52,7 @@ export async function setSession(data) {
session.storeLvl = data.storeLvl
session.groupId = data.groupId
session.pwdInitYn = data.pwdInitYn
+ session.custCd = data.custCd
session.isLoggedIn = true
// console.log('session:', session)
diff --git a/src/locales/ja.json b/src/locales/ja.json
index 8c6d1208..27b20ada 100644
--- a/src/locales/ja.json
+++ b/src/locales/ja.json
@@ -3,8 +3,8 @@
"welcome": "환영합니다. {0}님",
"header.menus.home": "ホームへv",
"header.menus.management": "物品及び図面管理",
- "header.menus.management.stuff": "新規物件登録",
- "header.menus.management.plan": "モノ/図面管理",
+ "header.menus.management.newStuff": "新規 物件 登録",
+ "header.menus.management.stuffList": "物件の状況",
"header.menus.community": "コミュニティ",
"header.menus.community.notice": "お知らせ",
"header.menus.community.faq": "FAQ",
@@ -214,20 +214,20 @@
"modal.canvas.setting.font.plan.absorption.dimension.display": "見る",
"modal.canvas.setting.font.plan.absorption.plan.size.setting": "図面サイズの設定",
"modal.canvas.setting.first.option.info": "※図面に表示する項目をクリックすると適用されます。",
- "modal.canvas.setting.first.option.alloc": "할당표시",
- "modal.canvas.setting.first.option.outline": "외벽선표시",
- "modal.canvas.setting.first.option.plan": "도면표시",
- "modal.canvas.setting.first.option.roof.line": "지붕선표시",
- "modal.canvas.setting.first.option.grid": "그리드표시",
- "modal.canvas.setting.first.option.circuit.num": "회로 번호 표시",
- "modal.canvas.setting.first.option.word": "문자 표시",
- "modal.canvas.setting.first.option.trestle": "가대 표시",
- "modal.canvas.setting.first.option.flow": "흐름방향 표시",
- "modal.canvas.setting.first.option.total": "집계표 표시",
- "modal.canvas.setting.first.option.dimension": "치수 표시(JA)",
- "modal.canvas.setting.first.option.corridor.dimension": "복도치수 표시(JA)",
- "modal.canvas.setting.first.option.real.dimension": "실제치수 표시(JA)",
- "modal.canvas.setting.first.option.none.dimension": "치수표시없음(JA)",
+ "modal.canvas.setting.first.option.alloc": "割り当て表示",
+ "modal.canvas.setting.first.option.outline": "外壁線表示",
+ "modal.canvas.setting.first.option.grid": "グリッド表示",
+ "modal.canvas.setting.first.option.roof.line": "屋根線標示",
+ "modal.canvas.setting.first.option.word": "文字表示",
+ "modal.canvas.setting.first.option.circuit.num": "回路番号表示",
+ "modal.canvas.setting.first.option.flow": "流れ方向表示",
+ "modal.canvas.setting.first.option.trestle": "架台表示",
+ "modal.canvas.setting.first.option.image": "画像表示",
+ "modal.canvas.setting.first.option.total": "集計表表示",
+ "modal.canvas.setting.first.option.dimension": "寸法表示",
+ "modal.canvas.setting.first.option.corridor.dimension": "廊下寸法表示",
+ "modal.canvas.setting.first.option.real.dimension": "実際の寸法表示",
+ "modal.canvas.setting.first.option.none.dimension": "寸法表示なし",
"modal.canvas.setting.first.option.display": "画面表示",
"modal.canvas.setting.first.option.border": "ボーダーのみ",
"modal.canvas.setting.first.option.line": "ラインハッチ",
@@ -274,6 +274,7 @@
"modal.panel.batch.statistic.total": "合計",
"modal.flow.direction.setting": "流れ方向の設定",
"modal.flow.direction.setting.info": "流れ方向を選択してください。",
+ "modal.image.size.setting": "画像のサイズ変更",
"plan.message.confirm.save": "PLAN을 저장하시겠습니까?",
"plan.message.confirm.copy": "PLAN을 복사하시겠습니까?",
"plan.message.confirm.delete": "PLAN을 삭제하시겠습니까?",
@@ -298,6 +299,14 @@
"contextmenu.auxiliary.cut": "보조선 절삭(JA)",
"contextmenu.auxiliary.remove.all": "보조선 전체 삭제(JA)",
"contextmenu.line.property.edit": "各辺属性の変更",
+ "contextmenu.column.move": "열 이동(JA)",
+ "contextmenu.column.copy": "열 복사(JA)",
+ "contextmenu.column.remove": "コピー設定",
+ "contextmenu.column.insert": "열 삽입(JA)",
+ "contextmenu.row.move": "단 이동(JA)",
+ "contextmenu.row.copy": "단 복사(JA)",
+ "contextmenu.row.remove": "단 삭제(JA)",
+ "contextmenu.row.insert": "단 삽입(JA)",
"modal.line.property.edit.info": "属性を変更する辺を選択してください。",
"modal.line.property.edit.selected": "選択した値",
"contextmenu.flow.direction.edit": "흐름 방향 변경(JA)",
@@ -398,6 +407,8 @@
"common.message.writeToConfirm": "作成解除を実行しますか?",
"common.message.password.init.success": "パスワード [{0}] に初期化されました。",
"common.message.no.edit.save": "この文書は変更できません。",
+ "common.input.file": "ファイルを読み込む",
+ "common.input.file.load": "ファイルの追加",
"common.require": "必須",
"commons.west": "立つ",
"commons.east": "ドン",
@@ -595,7 +606,7 @@
"stuff.planReqPopup.search.schDateGbnR": "受付日",
"stuff.planReqPopup.error.message1": "設計依頼を選択してください。",
"stuff.search.title": "物件状況",
- "stuff.search.btn1": "物件登録",
+ "stuff.search.btn1": "新規 物件 登録",
"stuff.search.btn2": "照会",
"stuff.search.btn3": "初期化",
"stuff.search.schObjectNo": "品番",
@@ -719,14 +730,25 @@
"estimate.detail.receiveUser": "担当者 ",
"estimate.detail.title": "案件名",
"estimate.detail.remarks": "メモ",
+ "estimate.detail.orderType": "注文分類",
+ "estimate.detail.roofCns": "屋根材・仕様施工",
+ "estimate.detail.note": "備考",
+ "estimate.detail.nextSubmit": "後日資料提出",
"estimate.detail.header.fileList1": "ファイル添付",
"estimate.detail.fileList.btn": "ファイル選択",
"estimate.detail.header.fileList2": "添付ファイル一覧",
"estimate.detail.header.specialEstimate": "見積もりの具体的な",
"estimate.detail.header.specialEstimateProductInfo": "製品情報",
+ "estimate.detail.sepcialEstimateProductInfo.totPcs": "数量 (PCS)",
+ "estimate.detail.sepcialEstimateProductInfo.vol": "容量 (Kw)",
+ "estimate.detail.sepcialEstimateProductInfo.netAmt": "供給価格",
+ "estimate.detail.sepcialEstimateProductInfo.vat": "付加価値税 (10%)",
+ "estimate.detail.sepcialEstimateProductInfo.totPrice": "総額",
"estimate.detail.sepcialEstimateProductInfo.pkgUnitPrice": "住宅PKG単価 (W)",
"estimate.detail.sepcialEstimateProductInfo.pkgWeight": "PKG容量 (Kw)",
"estimate.detail.sepcialEstimateProductInfo.pkgPrice": "PKG金額",
+ "estimate.detail.sepcialEstimateProductInfo.calcFormula1": "(モジュール容量 × 数量)÷1000",
+ "estimate.detail.sepcialEstimateProductInfo.calcFormula2": "PKG単価 (W)×PKG容量(W)",
"estimate.detail.header.showPrice": "価格表示",
"estimate.detail.showPrice.btn1": "Pricing",
"estimate.detail.showPrice.description": "クリックして製品の特異性を確認する",
diff --git a/src/locales/ko.json b/src/locales/ko.json
index cecdf4af..ecd5b73b 100644
--- a/src/locales/ko.json
+++ b/src/locales/ko.json
@@ -3,8 +3,8 @@
"welcome": "환영합니다. {0}님",
"header.menus.home": "Home",
"header.menus.management": "물건 및 도면 관리",
- "header.menus.management.stuff": "신규 물건 등록",
- "header.menus.management.plan": "사물/도면 관리",
+ "header.menus.management.newStuff": "신규 물건 등록",
+ "header.menus.management.stuffList": "물건 현황",
"header.menus.community": "커뮤니티",
"header.menus.community.notice": "공지",
"header.menus.community.faq": "FAQ",
@@ -221,13 +221,13 @@
"modal.canvas.setting.first.option.info": "※도면에 표시하는 항목을 클릭하면 적용됩니다.",
"modal.canvas.setting.first.option.alloc": "할당표시",
"modal.canvas.setting.first.option.outline": "외벽선표시",
- "modal.canvas.setting.first.option.plan": "도면표시",
- "modal.canvas.setting.first.option.roof.line": "지붕선표시",
"modal.canvas.setting.first.option.grid": "그리드표시",
- "modal.canvas.setting.first.option.circuit.num": "회로 번호 표시",
+ "modal.canvas.setting.first.option.roof.line": "지붕선표시",
"modal.canvas.setting.first.option.word": "문자 표시",
- "modal.canvas.setting.first.option.trestle": "가대 표시",
+ "modal.canvas.setting.first.option.circuit.num": "회로 번호 표시",
"modal.canvas.setting.first.option.flow": "흐름방향 표시",
+ "modal.canvas.setting.first.option.trestle": "가대 표시",
+ "modal.canvas.setting.first.option.image": "이미지 표시",
"modal.canvas.setting.first.option.total": "집계표 표시",
"modal.canvas.setting.first.option.dimension": "치수 표시",
"modal.canvas.setting.first.option.corridor.dimension": "복도치수 표시",
@@ -279,6 +279,7 @@
"modal.panel.batch.statistic.total": "합계",
"modal.flow.direction.setting": "흐름 방향 설정",
"modal.flow.direction.setting.info": "흐름방향을 선택하세요.",
+ "modal.image.size.setting": "이미지 크기 조절",
"plan.message.confirm.save": "PLAN을 저장하시겠습니까?",
"plan.message.confirm.copy": "PLAN을 복사하시겠습니까?",
"plan.message.confirm.delete": "PLAN을 삭제하시겠습니까?",
@@ -303,6 +304,14 @@
"contextmenu.auxiliary.cut": "보조선 절삭",
"contextmenu.auxiliary.remove.all": "보조선 전체 삭제",
"contextmenu.line.property.edit": "각 변 속성 변경",
+ "contextmenu.column.move": "열 이동",
+ "contextmenu.column.copy": "열 복사",
+ "contextmenu.column.remove": "열 삭제",
+ "contextmenu.column.insert": "열 삽입",
+ "contextmenu.row.move": "단 이동",
+ "contextmenu.row.copy": "단 복사",
+ "contextmenu.row.remove": "단 삭제",
+ "contextmenu.row.insert": "단 삽입",
"modal.line.property.edit.info": "속성을 변경할 변을 선택해주세요.",
"modal.line.property.edit.selected": "선택한 값",
"contextmenu.flow.direction.edit": "흐름 방향 변경",
@@ -403,6 +412,8 @@
"common.message.writeToConfirm": "작성 해제를 실행하시겠습니까?",
"common.message.password.init.success": "비밀번호 [{0}]로 초기화 되었습니다.",
"common.message.no.edit.save": "This document cannot be changed.",
+ "common.input.file": "파일 불러오기",
+ "common.input.file.load": "불러오기",
"common.require": "필수",
"commons.west": "서",
"commons.east": "동",
@@ -600,7 +611,7 @@
"stuff.planReqPopup.search.schDateGbnR": "접수일",
"stuff.planReqPopup.error.message1": "설계의뢰를 선택해주세요.",
"stuff.search.title": "물건현황",
- "stuff.search.btn1": "신규등록",
+ "stuff.search.btn1": "신규 물건 등록",
"stuff.search.btn2": "조회",
"stuff.search.btn3": "초기화",
"stuff.search.schObjectNo": "물건번호",
@@ -724,14 +735,25 @@
"estimate.detail.receiveUser": "담당자",
"estimate.detail.title": "안건명",
"estimate.detail.remarks": "메모",
+ "estimate.detail.orderType": "주문분류",
+ "estimate.detail.roofCns": "지붕재・사양시공",
+ "estimate.detail.note": "비고",
+ "estimate.detail.nextSubmit": "후일자료제출",
"estimate.detail.header.fileList1": "파일첨부",
"estimate.detail.fileList.btn": "파일선택",
"estimate.detail.header.fileList2": "첨부파일 목록",
"estimate.detail.header.specialEstimate": "견적특이사항",
"estimate.detail.header.specialEstimateProductInfo": "제품정보",
+ "estimate.detail.sepcialEstimateProductInfo.totPcs": "수량 (PCS)",
+ "estimate.detail.sepcialEstimateProductInfo.vol": "용량 (Kw)",
+ "estimate.detail.sepcialEstimateProductInfo.netAmt": "공급가액",
+ "estimate.detail.sepcialEstimateProductInfo.vat": "부가세 (10%)",
+ "estimate.detail.sepcialEstimateProductInfo.totPrice": "총액",
"estimate.detail.sepcialEstimateProductInfo.pkgUnitPrice": "주택PKG단가 (W)",
"estimate.detail.sepcialEstimateProductInfo.pkgWeight": "PKG 용량 (Kw)",
"estimate.detail.sepcialEstimateProductInfo.pkgPrice": "PKG 금액",
+ "estimate.detail.sepcialEstimateProductInfo.calcFormula1": "(모듈수량 * 수량)÷100",
+ "estimate.detail.sepcialEstimateProductInfo.calcFormula2": "PKG단가(W) * PKG용량(W)",
"estimate.detail.header.showPrice": "가격표시",
"estimate.detail.showPrice.btn1": "Pricing",
"estimate.detail.showPrice.description": "클릭하여 제품 특이사항 확인",
diff --git a/src/store/canvasAtom.js b/src/store/canvasAtom.js
index bdce5876..0242a7b2 100644
--- a/src/store/canvasAtom.js
+++ b/src/store/canvasAtom.js
@@ -323,7 +323,6 @@ export const pitchSelector = selector({
set: ({ get, set }, newValue) => {
const basicSettingStateValue = get(basicSettingState)
const roofAngleSet = basicSettingStateValue.roofAngleSet
- console.log(newValue)
if (roofAngleSet === 'slope') {
set(globalPitchState, newValue)
} else {
diff --git a/src/store/floorPlanObjectAtom.js b/src/store/floorPlanObjectAtom.js
index 50cdccf4..3acd49a3 100644
--- a/src/store/floorPlanObjectAtom.js
+++ b/src/store/floorPlanObjectAtom.js
@@ -3,7 +3,7 @@ import { v1 } from 'uuid'
export const floorPlanObjectState = atom({
key: `floorPlanObjectState/${v1()}`,
default: {
- objectNo: '', //물건번호
+ floorPlanObjectNo: '', //물건번호
},
dangerouslyAllowMutability: true,
})
diff --git a/src/store/menuAtom.js b/src/store/menuAtom.js
index b86ecbd0..834498f0 100644
--- a/src/store/menuAtom.js
+++ b/src/store/menuAtom.js
@@ -1,6 +1,74 @@
import { atom } from 'recoil'
+import { MENU } from '@/common/common'
export const menuNumberState = atom({
key: 'menuNumberState',
default: null,
})
+
+export const menuTypeState = atom({
+ key: 'menuTypeState',
+ default: null,
+})
+
+export const menusState = atom({
+ key: 'menusState',
+ default: [
+ { index: 0, name: 'plan.menu.plan.drawing', icon: 'con00', title: MENU.PLAN_DRAWING },
+ {
+ index: 1,
+ name: 'plan.menu.placement.surface.initial.setting',
+ icon: 'con01',
+ title: MENU.INITIAL_CANVAS_SETTING,
+ },
+ { index: 2, name: 'plan.menu.roof.cover', icon: 'con02', title: MENU.ROOF_COVERING.DEFAULT },
+ { index: 3, name: 'plan.menu.placement.surface', icon: 'con03', title: MENU.BATCH_CANVAS.DEFAULT },
+ { index: 4, name: 'plan.menu.module.circuit.setting', icon: 'con04', title: MENU.MODULE_CIRCUIT_SETTING.DEFAULT },
+ { index: 5, name: 'plan.menu.estimate', icon: 'con06', title: MENU.ESTIMATE.DEFAULT },
+ { index: 6, name: 'plan.menu.simulation', icon: 'con05', title: MENU.POWER_GENERATION_SIMULATION.DEFAULT },
+ ],
+})
+
+export const subMenusState = atom({
+ key: 'subMenusState',
+ default: {
+ outline: [
+ // 지붕덮개
+ { id: 0, name: 'plan.menu.roof.cover.outline.drawing', menu: MENU.ROOF_COVERING.EXTERIOR_WALL_LINE },
+ { id: 1, name: 'plan.menu.roof.cover.roof.shape.setting', menu: MENU.ROOF_COVERING.ROOF_SHAPE_SETTINGS },
+ {
+ id: 2,
+ name: 'plan.menu.roof.cover.roof.shape.passivity.setting',
+ menu: MENU.ROOF_COVERING.ROOF_SHAPE_PASSIVITY_SETTINGS,
+ },
+ { id: 3, name: 'plan.menu.roof.cover.auxiliary.line.drawing', menu: MENU.ROOF_COVERING.HELP_LINE_DRAWING },
+ { id: 4, name: 'plan.menu.roof.cover.eaves.kerava.edit', menu: MENU.ROOF_COVERING.EAVES_KERAVA_EDIT },
+ { id: 5, name: 'plan.menu.roof.cover.movement.shape.updown', menu: MENU.ROOF_COVERING.MOVEMENT_SHAPE_UPDOWN },
+ { id: 6, name: 'plan.menu.roof.cover.outline.edit.offset', menu: MENU.ROOF_COVERING.OUTLINE_EDIT_OFFSET },
+ { id: 7, name: 'plan.menu.roof.cover.roof.surface.alloc', menu: MENU.ROOF_COVERING.ROOF_SHAPE_ALLOC },
+ ],
+ surface: [
+ // 배치면
+ { id: 0, name: 'plan.menu.placement.surface.slope.setting', menu: MENU.BATCH_CANVAS.SLOPE_SETTING },
+ { id: 1, name: 'plan.menu.placement.surface.drawing', menu: MENU.BATCH_CANVAS.BATCH_DRAWING },
+ { id: 2, name: 'plan.menu.placement.surface.arrangement', menu: MENU.BATCH_CANVAS.SURFACE_SHAPE_BATCH },
+ { id: 3, name: 'plan.menu.placement.surface.object', menu: MENU.BATCH_CANVAS.OBJECT_BATCH },
+ { id: 4, name: 'plan.menu.placement.surface.all.remove', menu: MENU.BATCH_CANVAS.ALL_REMOVE },
+ ],
+ module: [
+ // 모듈, 회로 구성
+
+ { id: 0, name: 'plan.menu.module.circuit.setting.default', menu: MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING },
+ {
+ id: 1,
+ name: 'plan.menu.module.circuit.setting.circuit.trestle.setting',
+ menu: MENU.MODULE_CIRCUIT_SETTING.CIRCUIT_TRESTLE_SETTING,
+ },
+ {
+ id: 2,
+ name: 'plan.menu.module.circuit.setting.plan.orientation',
+ menu: MENU.MODULE_CIRCUIT_SETTING.PLAN_ORIENTATION,
+ },
+ ],
+ },
+})
diff --git a/src/store/settingAtom.js b/src/store/settingAtom.js
index 2432d884..9679d2d7 100644
--- a/src/store/settingAtom.js
+++ b/src/store/settingAtom.js
@@ -12,10 +12,16 @@ export const settingModalFirstOptionsState = atom({
{ id: 6, column: 'circuitNumDisplay', name: 'modal.canvas.setting.first.option.circuit.num', selected: false },
{ id: 7, column: 'flowDisplay', name: 'modal.canvas.setting.first.option.flow', selected: false },
{ id: 8, column: 'trestleDisplay', name: 'modal.canvas.setting.first.option.trestle', selected: false },
- { id: 9, column: 'totalDisplay', name: 'modal.canvas.setting.first.option.total', selected: false },
+ { id: 9, column: 'imageDisplay', name: 'modal.canvas.setting.first.option.image', selected: false },
+ { id: 10, column: 'totalDisplay', name: 'modal.canvas.setting.first.option.total', selected: false },
],
dimensionDisplay: [
- { id: 1, column: 'corridorDimension', name: 'modal.canvas.setting.first.option.corridor.dimension', selected: true },
+ {
+ id: 1,
+ column: 'corridorDimension',
+ name: 'modal.canvas.setting.first.option.corridor.dimension',
+ selected: true,
+ },
{ id: 2, column: 'realDimension', name: 'modal.canvas.setting.first.option.real.dimension', selected: false },
{ id: 3, column: 'noneDimension', name: 'modal.canvas.setting.first.option.none.dimension', selected: false },
],
@@ -38,10 +44,34 @@ export const settingModalSecondOptionsState = atom({
{ id: 4, name: 'modal.canvas.setting.font.plan.edit.circuit.num' },
],
option4: [
- { id: 1, column: 'adsorpRangeSmall', name: 'modal.canvas.setting.font.plan.absorption.small', selected: true, range: 10 },
- { id: 2, column: 'adsorpRangeSmallSemi', name: 'modal.canvas.setting.font.plan.absorption.small.semi', selected: false, range: 30 },
- { id: 3, column: 'adsorpRangeMedium', name: 'modal.canvas.setting.font.plan.absorption.medium', selected: false, range: 50 },
- { id: 4, column: 'adsorpRangeLarge', name: 'modal.canvas.setting.font.plan.absorption.large', selected: false, range: 70 },
+ {
+ id: 1,
+ column: 'adsorpRangeSmall',
+ name: 'modal.canvas.setting.font.plan.absorption.small',
+ selected: true,
+ range: 10,
+ },
+ {
+ id: 2,
+ column: 'adsorpRangeSmallSemi',
+ name: 'modal.canvas.setting.font.plan.absorption.small.semi',
+ selected: false,
+ range: 30,
+ },
+ {
+ id: 3,
+ column: 'adsorpRangeMedium',
+ name: 'modal.canvas.setting.font.plan.absorption.medium',
+ selected: false,
+ range: 50,
+ },
+ {
+ id: 4,
+ column: 'adsorpRangeLarge',
+ name: 'modal.canvas.setting.font.plan.absorption.large',
+ selected: false,
+ range: 70,
+ },
],
},
dangerouslyAllowMutability: true,
@@ -130,6 +160,15 @@ export const trestleDisplaySelector = selector({
},
})
+// 디스플레이 설정 - 이미지 표시
+export const imageDisplaySelector = selector({
+ key: 'imageDisplaySelector',
+ get: ({ get }) => {
+ const settingModalFirstOptions = get(settingModalFirstOptionsState)
+ return settingModalFirstOptions.option1.find((option) => option.column === 'imageDisplay').selected
+ },
+})
+
// 디스플레이 설정 - 집계표 표시
export const totalDisplaySelector = selector({
key: 'totalDisplaySelector',
diff --git a/src/styles/_contents.scss b/src/styles/_contents.scss
index e3d8d1ee..8e29b78a 100644
--- a/src/styles/_contents.scss
+++ b/src/styles/_contents.scss
@@ -23,6 +23,7 @@
left: 0;
display: block;
width: 100%;
+ height: 46.8px;
padding-bottom: 0;
background-color: #383838;
transition: padding .17s ease-in-out;
@@ -329,7 +330,7 @@
border-top: 1px solid #000;
width: 100%;
transition: all .17s ease-in-out;
- z-index: 999;
+ z-index: 99;
&.active{
top: calc(92.8px + 50px);
}
@@ -544,9 +545,9 @@
.sub-content{
padding-top: 46px;
.sub-content-inner{
- max-width: 1720px;
+ max-width: 1760px;
margin: 0 auto;
- padding-top: 20px;
+ padding: 20px 20px 0;
.sub-content-box{
margin-bottom: 20px;
&:last-child{
@@ -897,45 +898,63 @@
display: flex;
align-items: center;
margin-right: 15px;
- .attachment-required{
+ .explane-item{
position: relative;
display: flex;
align-items: center;
+ padding: 0 10px;
font-size: 12px;
font-weight: 400;
- color: #45576F;
- padding-right: 10px;
- .ico{
- width: 23px;
- height: 23px;
+ span{
+ width: 20px;
+ height: 20px;
margin-right: 5px;
- background: url(../../public/static/images/sub/attachment_ico.svg)no-repeat center;
background-size: cover;
+ background-repeat: no-repeat;
+ background-position: center;
}
- &::before{
+ &:before{
content: '';
position: absolute;
top: 50%;
- right: 0;
+ left: 0;
transform: translateY(-50%);
width: 1px;
height: 12px;
background-color: #D9D9D9;
}
- }
- .click-check{
- display: flex;
- align-items: center;
- font-size: 12px;
- font-weight: 400;
- color: #F16A6A ;
- padding-left: 10px;
- .ico{
- width: 14px;
- height: 14px;
- margin-right: 5px;
- background: url(../../public/static/images/sub/click_check_ico.svg)no-repeat center;
- background-size: cover;
+ &:first-child{
+ padding-left: 0;
+ &::before{
+ display: none;
+ }
+ }
+ &:last-child{
+ padding-right: 0;
+ }
+ &.item01{
+ color: #3BBB48;
+ span{
+ background-image: url(../../public/static/images/sub/open_ico.svg);
+ }
+ }
+ &.item02{
+ color: #909000;
+ span{
+ background-image: url(../../public/static/images/sub/change_ico.svg);
+ }
+ }
+ &.item03{
+ color: #0191C9;
+ span{
+ background-image: url(../../public/static/images/sub/attachment_ico.svg);
+ }
+ }
+ &.item04{
+ color: #F16A6A;
+ span{
+ background-image: url(../../public/static/images/sub/click_check_ico.svg);
+ }
}
}
}
@@ -960,7 +979,6 @@
}
}
}
-
}
// 발전시물레이션
diff --git a/src/styles/_grid-detail.scss b/src/styles/_grid-detail.scss
index 0392bae8..1f6a2270 100644
--- a/src/styles/_grid-detail.scss
+++ b/src/styles/_grid-detail.scss
@@ -128,10 +128,3 @@
}
}
-.grid-tip{
- display: block;
- width: 15px;
- height: 15px;
- background: url(../../public/static/images/sub/grid_tip.svg)no-repeat center;
- background-size: cover;
-}
\ No newline at end of file
diff --git a/src/styles/_layout.scss b/src/styles/_layout.scss
index 2bddf61f..7f3834df 100644
--- a/src/styles/_layout.scss
+++ b/src/styles/_layout.scss
@@ -1,7 +1,7 @@
.wrap{
display: flex;
flex-direction: column;
- min-width: 1600px;
+ min-width: 1280px;
min-height: 100vh;
overflow-x: hidden;
}
diff --git a/src/styles/_modal.scss b/src/styles/_modal.scss
index 9dc39b65..361aa957 100644
--- a/src/styles/_modal.scss
+++ b/src/styles/_modal.scss
@@ -399,6 +399,12 @@ $alert-color: #101010;
color: $pop-color;
border-bottom: 1px solid #424242;
padding-left: 20px;
+ vertical-align: middle;
+ .flex-box{
+ display: flex;
+ align-items: center;
+ height: 100%;
+ }
}
&:first-child{
td,
@@ -470,6 +476,52 @@ $alert-color: #101010;
}
}
+.img-edit-wrap{
+ flex: none;
+ .img-edit-btn{
+ display: flex;
+ align-items: center;
+ height: 30px;
+ padding: 0 10px;
+ font-size: 12px;
+ font-weight: 400;
+ color: #101010;
+ background-color: #fff;
+ border-radius: 2px;
+ transition: all .15s ease-in-out;
+ .img-edit{
+ width: 16px;
+ height: 16px;
+ background: url(../../public/static/images/canvas/img_edit_ico.svg)no-repeat center;
+ background-size: cover;
+ margin-right: 5px;
+ }
+ &:hover{
+ background-color: #ebebeb;
+ }
+ }
+}
+.img-name-wrap{
+ display: flex;
+ align-items: center;
+ width: 100%;
+ margin-left: 10px;
+ input{
+ flex: 1;
+
+ }
+ .img-check{
+ flex: none;
+ width: 18px;
+ height: 18px;
+ margin-left: 5px;
+ background-repeat: no-repeat;
+ background-position: center;
+ background-size: cover;
+ background-image: url(../../public/static/images/canvas/img_check_fail.svg);
+ }
+}
+
// 외벽선 그리기
.outline-wrap{
padding: 24px 0;
@@ -1788,4 +1840,22 @@ $alert-color: #101010;
flex: none;
}
}
+}
+
+//이미지 크기 설정
+.range-wrap{
+ display: flex;
+ align-items: center;
+ input{
+ flex: 1;
+ margin-right: 10px;
+ }
+ label{
+ flex: none;
+ text-align: right;
+ width: 38px;
+ font-size: 13px;
+ color: #fff;
+ font-weight: 500;
+ }
}
\ No newline at end of file
diff --git a/src/styles/_reset.scss b/src/styles/_reset.scss
index 525c0488..4225db2e 100644
--- a/src/styles/_reset.scss
+++ b/src/styles/_reset.scss
@@ -130,6 +130,10 @@ button{
font-family: 'Pretendard', sans-serif !important;
}
+.no-click{
+ cursor: no-drop !important;
+}
+
// margin
.mt5{margin-top: 5px !important;}
.mt10{margin-top: 10px !important;}
diff --git a/src/styles/_table.scss b/src/styles/_table.scss
index d7e1c407..4dcef37a 100644
--- a/src/styles/_table.scss
+++ b/src/styles/_table.scss
@@ -430,4 +430,82 @@ table{
}
}
}
+}
+
+// 견적서 테이블
+.esimate-table{
+ table{
+ table-layout: fixed;
+ border-collapse: separate;
+ thead{
+ tr{
+ th{
+ text-align: center;
+ font-size: 13px;
+ color: #fff;
+ font-weight: 600;
+ padding: 11px 5px;
+ background-color: #5D6A76;
+ &:first-child{
+ border-radius: 4px 0 0 4px;
+ }
+ &:last-child{
+ border-radius: 0 4px 4px 0;
+ }
+ }
+ }
+ }
+ tbody{
+ tr{
+ td{
+ padding: 5px 10px;
+ font-size: 13px;
+ color: #45576F;
+ font-weight: 400;
+ border-bottom: 1px solid #ECF0F4;
+ .form-flex-wrap{
+ display: flex;
+ align-items: center;
+ .input-wrap,
+ .select-wrap{
+ flex: 1;
+ }
+ .btn-area{
+ flex: none;
+ }
+ .icon-wrap{
+ margin-left: auto;
+ display: flex;
+ align-items: center;
+ gap: 5px;
+ }
+ }
+ .tb_ico{
+ display: block;
+ width: 20px;
+ height: 20px;
+ background-repeat: no-repeat;
+ background-position: center;
+ background-size: cover;
+ &.change_check{
+ background-image: url(../../public/static/images/sub/change_ico.svg);
+ }
+ &.file_check{
+ background-image: url(../../public/static/images/sub/attachment_ico.svg);
+ }
+ &.open_check{
+ background-image: url(../../public/static/images/sub/open_ico.svg);
+ }
+ }
+ .grid-tip{
+ display: block;
+ width: 20px;
+ height: 20px;
+ background: url(../../public/static/images/sub/click_check_ico.svg)no-repeat center;
+ background-size: cover;
+ }
+ }
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/src/util/canvas-util.js b/src/util/canvas-util.js
index 9f8b9469..73464722 100644
--- a/src/util/canvas-util.js
+++ b/src/util/canvas-util.js
@@ -268,7 +268,7 @@ export const getDegreeByChon = (chon) => {
export const getChonByDegree = (degree) => {
// tan(theta) = height / base
const radians = (degree * Math.PI) / 180
- return Number(Number(Math.tan(radians) * 10).toFixed(1))
+ return Number(Number(Math.tan(radians) * 10).toFixed(2))
}
/**