From 9f6bbdf01c5240155474cbe0597ddfeadad703ce Mon Sep 17 00:00:00 2001 From: basssy Date: Thu, 13 Feb 2025 17:47:24 +0900 Subject: [PATCH 001/352] #747 --- src/components/floor-plan/CanvasMenu.jsx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 3dd85620..58ec721e 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -615,6 +615,16 @@ export default function CanvasMenu(props) { {menuNumber === 5 && ( <>
+
+
+
COLOR PICKER
diff --git a/src/components/common/font/FontSetting.jsx b/src/components/common/font/FontSetting.jsx index ddddefca..beb31aa3 100644 --- a/src/components/common/font/FontSetting.jsx +++ b/src/components/common/font/FontSetting.jsx @@ -82,6 +82,8 @@ export default function FontSetting(props) {
+
+
diff --git a/src/components/floor-plan/modal/ImgLoad.jsx b/src/components/floor-plan/modal/ImgLoad.jsx index fdff181f..04127bba 100644 --- a/src/components/floor-plan/modal/ImgLoad.jsx +++ b/src/components/floor-plan/modal/ImgLoad.jsx @@ -86,6 +86,8 @@ export default function ImgLoad() {
+
+
{getMessage('modal.image.load.size.rotate')}
+
+
diff --git a/src/components/floor-plan/modal/auxiliary/AuxiliaryDrawing.jsx b/src/components/floor-plan/modal/auxiliary/AuxiliaryDrawing.jsx index b85d76c6..3a9d64d6 100644 --- a/src/components/floor-plan/modal/auxiliary/AuxiliaryDrawing.jsx +++ b/src/components/floor-plan/modal/auxiliary/AuxiliaryDrawing.jsx @@ -133,6 +133,8 @@ export default function AuxiliaryDrawing({ id, pos = { x: 50, y: 230 } }) {
+
+
{types.map((type, idx) => (
+
+
{getMessage(type === 'copy' ? 'modal.auxiliary.copy.info' : 'modal.auxiliary.move.info')}
diff --git a/src/components/floor-plan/modal/auxiliary/AuxiliarySize.jsx b/src/components/floor-plan/modal/auxiliary/AuxiliarySize.jsx index f8bf4ca7..a9f7fc82 100644 --- a/src/components/floor-plan/modal/auxiliary/AuxiliarySize.jsx +++ b/src/components/floor-plan/modal/auxiliary/AuxiliarySize.jsx @@ -120,6 +120,8 @@ export default function AuxiliarySize(props) {
+
+
setCheckedRadio(1)} /> diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index 3baa57e2..9a537163 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -144,6 +144,8 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
+
+
{getMessage('modal.module.basic.setting.orientation.setting')}
diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index d53c1f4f..2c904ddd 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -509,6 +509,8 @@ export default function CircuitTrestleSetting({ id }) {
+
+
{getMessage('modal.circuit.trestle.setting.power.conditional.select')}
diff --git a/src/components/floor-plan/modal/dimensionLine/DimensionLineSetting.jsx b/src/components/floor-plan/modal/dimensionLine/DimensionLineSetting.jsx index 1ec3684e..9e2ce27b 100644 --- a/src/components/floor-plan/modal/dimensionLine/DimensionLineSetting.jsx +++ b/src/components/floor-plan/modal/dimensionLine/DimensionLineSetting.jsx @@ -92,6 +92,8 @@ export default function DimensionLineSetting(props) {
+
+
{getMessage('modal.display.edit.info')}
diff --git a/src/components/floor-plan/modal/distance/Distance.jsx b/src/components/floor-plan/modal/distance/Distance.jsx index d37302b6..e9c175d3 100644 --- a/src/components/floor-plan/modal/distance/Distance.jsx +++ b/src/components/floor-plan/modal/distance/Distance.jsx @@ -25,6 +25,8 @@ export default function Distance(props) {
+
+
diff --git a/src/components/floor-plan/modal/eavesGable/EavesGableEdit.jsx b/src/components/floor-plan/modal/eavesGable/EavesGableEdit.jsx index 56e88ba8..c3975543 100644 --- a/src/components/floor-plan/modal/eavesGable/EavesGableEdit.jsx +++ b/src/components/floor-plan/modal/eavesGable/EavesGableEdit.jsx @@ -47,6 +47,8 @@ export default function EavesGableEdit({ id, pos = { x: 50, y: 230 } }) {
+
+
{buttonMenu.map((item) => (
+
+
{getMessage('modal.flow.direction.setting')}
diff --git a/src/components/floor-plan/modal/grid/DotLineGrid.jsx b/src/components/floor-plan/modal/grid/DotLineGrid.jsx index 26b5f84c..853d27c1 100644 --- a/src/components/floor-plan/modal/grid/DotLineGrid.jsx +++ b/src/components/floor-plan/modal/grid/DotLineGrid.jsx @@ -192,6 +192,8 @@ export default function DotLineGrid(props) {
+
+
diff --git a/src/components/floor-plan/modal/grid/GridCopy.jsx b/src/components/floor-plan/modal/grid/GridCopy.jsx index 0d34b3d4..fa0b0ba8 100644 --- a/src/components/floor-plan/modal/grid/GridCopy.jsx +++ b/src/components/floor-plan/modal/grid/GridCopy.jsx @@ -29,6 +29,8 @@ export default function GridCopy(props) {
+
+
{getMessage('modal.grid.copy.info')}
diff --git a/src/components/floor-plan/modal/grid/GridMove.jsx b/src/components/floor-plan/modal/grid/GridMove.jsx index 1713647b..dbf15206 100644 --- a/src/components/floor-plan/modal/grid/GridMove.jsx +++ b/src/components/floor-plan/modal/grid/GridMove.jsx @@ -82,6 +82,8 @@ export default function GridMove(props) {
+
+
{getMessage('modal.grid.move.info')}
diff --git a/src/components/floor-plan/modal/lineProperty/LinePropertySetting.jsx b/src/components/floor-plan/modal/lineProperty/LinePropertySetting.jsx index 74a67576..e309646a 100644 --- a/src/components/floor-plan/modal/lineProperty/LinePropertySetting.jsx +++ b/src/components/floor-plan/modal/lineProperty/LinePropertySetting.jsx @@ -59,6 +59,8 @@ export default function LinePropertySetting(props) {
+
+
{getMessage('modal.line.property.edit.info')} diff --git a/src/components/floor-plan/modal/module/CircuitNumberEdit.jsx b/src/components/floor-plan/modal/module/CircuitNumberEdit.jsx index 62a0baaf..50c819ed 100644 --- a/src/components/floor-plan/modal/module/CircuitNumberEdit.jsx +++ b/src/components/floor-plan/modal/module/CircuitNumberEdit.jsx @@ -23,6 +23,8 @@ export default function CircuitNumberEdit(props) {
+
+
{getMessage('modal.module.circuit.number.edit.info')}
diff --git a/src/components/floor-plan/modal/module/PanelEdit.jsx b/src/components/floor-plan/modal/module/PanelEdit.jsx index bfff66a2..bf03dae6 100644 --- a/src/components/floor-plan/modal/module/PanelEdit.jsx +++ b/src/components/floor-plan/modal/module/PanelEdit.jsx @@ -105,6 +105,8 @@ export default function PanelEdit(props) {
+
+
{getMessage([PANEL_EDIT_TYPE.MOVE, PANEL_EDIT_TYPE.COLUMN_MOVE].includes(type) ? 'modal.move.setting.info' : 'modal.copy.setting.info')}
diff --git a/src/components/floor-plan/modal/module/column/ColumnInsert.jsx b/src/components/floor-plan/modal/module/column/ColumnInsert.jsx index 03b5b4e0..e42d2ca3 100644 --- a/src/components/floor-plan/modal/module/column/ColumnInsert.jsx +++ b/src/components/floor-plan/modal/module/column/ColumnInsert.jsx @@ -33,6 +33,8 @@ export default function ColumnInsert(props) {
+
+
{getMessage('modal.panel.column.insert.info')}
diff --git a/src/components/floor-plan/modal/module/column/ColumnRemove.jsx b/src/components/floor-plan/modal/module/column/ColumnRemove.jsx index 95cdd942..a7ad2044 100644 --- a/src/components/floor-plan/modal/module/column/ColumnRemove.jsx +++ b/src/components/floor-plan/modal/module/column/ColumnRemove.jsx @@ -36,6 +36,8 @@ export default function ColumnRemove(props) {
+
+
{getMessage('modal.panel.column.remove.info')}
diff --git a/src/components/floor-plan/modal/module/row/RowInsert.jsx b/src/components/floor-plan/modal/module/row/RowInsert.jsx index fa3c2fff..9b558706 100644 --- a/src/components/floor-plan/modal/module/row/RowInsert.jsx +++ b/src/components/floor-plan/modal/module/row/RowInsert.jsx @@ -33,6 +33,8 @@ export default function RowInsert(props) {
+
+
{getMessage('modal.row.insert.info')}
diff --git a/src/components/floor-plan/modal/module/row/RowRemove.jsx b/src/components/floor-plan/modal/module/row/RowRemove.jsx index 70c57c24..500fbfb3 100644 --- a/src/components/floor-plan/modal/module/row/RowRemove.jsx +++ b/src/components/floor-plan/modal/module/row/RowRemove.jsx @@ -36,6 +36,8 @@ export default function RowRemove(props) {
+
+
{getMessage('modal.row.remove.info')}
diff --git a/src/components/floor-plan/modal/movement/MovementSetting.jsx b/src/components/floor-plan/modal/movement/MovementSetting.jsx index 057d7d37..916a40bd 100644 --- a/src/components/floor-plan/modal/movement/MovementSetting.jsx +++ b/src/components/floor-plan/modal/movement/MovementSetting.jsx @@ -25,6 +25,8 @@ export default function MovementSetting({ id, pos = { x: 50, y: 230 } }) {
+
+
{buttonType.map((item) => (
+
+
{getMessage('modal.dormer.offset.info')}
diff --git a/src/components/floor-plan/modal/object/ObjectSetting.jsx b/src/components/floor-plan/modal/object/ObjectSetting.jsx index 69c4232c..909aad99 100644 --- a/src/components/floor-plan/modal/object/ObjectSetting.jsx +++ b/src/components/floor-plan/modal/object/ObjectSetting.jsx @@ -84,6 +84,8 @@ export default function ObjectSetting({ id, pos = { x: 50, y: 230 } }) {
+
+
{buttonMenu.map((item) => (
+
+
diff --git a/src/components/floor-plan/modal/object/SizeSetting.jsx b/src/components/floor-plan/modal/object/SizeSetting.jsx index b7df4986..22a5f597 100644 --- a/src/components/floor-plan/modal/object/SizeSetting.jsx +++ b/src/components/floor-plan/modal/object/SizeSetting.jsx @@ -54,6 +54,8 @@ export default function SizeSetting(props) {
+
+
diff --git a/src/components/floor-plan/modal/outerlinesetting/PropertiesSetting.jsx b/src/components/floor-plan/modal/outerlinesetting/PropertiesSetting.jsx index 86724267..c57eabfa 100644 --- a/src/components/floor-plan/modal/outerlinesetting/PropertiesSetting.jsx +++ b/src/components/floor-plan/modal/outerlinesetting/PropertiesSetting.jsx @@ -17,6 +17,8 @@ export default function PropertiesSetting(props) {
+
+
{getMessage('modal.canvas.setting.wallline.properties.setting.info')}
{getMessage('setting')}
diff --git a/src/components/floor-plan/modal/outerlinesetting/WallLineSetting.jsx b/src/components/floor-plan/modal/outerlinesetting/WallLineSetting.jsx index c95c7c5a..c71d2767 100644 --- a/src/components/floor-plan/modal/outerlinesetting/WallLineSetting.jsx +++ b/src/components/floor-plan/modal/outerlinesetting/WallLineSetting.jsx @@ -121,6 +121,8 @@ export default function WallLineSetting(props) {
+
+
+
+
{types.map((type, idx) => (
+
+
diff --git a/src/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting.jsx b/src/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting.jsx index 263054cf..7f7919c9 100644 --- a/src/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting.jsx +++ b/src/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting.jsx @@ -253,6 +253,8 @@ export default function PlacementSurfaceSetting({ id, pos = { x: 50, y: 230 } })
+
+
diff --git a/src/components/floor-plan/modal/roofAllocation/ActualSizeSetting.jsx b/src/components/floor-plan/modal/roofAllocation/ActualSizeSetting.jsx index d9456bbd..0af71db1 100644 --- a/src/components/floor-plan/modal/roofAllocation/ActualSizeSetting.jsx +++ b/src/components/floor-plan/modal/roofAllocation/ActualSizeSetting.jsx @@ -70,6 +70,8 @@ export default function ActualSizeSetting(props) {
+
+
{getMessage('modal.actual.size.setting.info')}
diff --git a/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx b/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx index a4cfa8dd..c9b40430 100644 --- a/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx +++ b/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx @@ -57,6 +57,8 @@ export default function ContextRoofAllocationSetting(props) {
+
+
{getMessage('modal.roof.alloc.info')}
{getMessage('modal.roof.alloc.select.roof.material')} diff --git a/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx b/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx index 9ceeb9e0..83310c2e 100644 --- a/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx +++ b/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx @@ -57,6 +57,8 @@ export default function RoofAllocationSetting(props) {
+
+
{getMessage('modal.roof.alloc.info')}
{getMessage('modal.roof.alloc.select.roof.material')} diff --git a/src/components/floor-plan/modal/roofShape/RoofShapePassivitySetting.jsx b/src/components/floor-plan/modal/roofShape/RoofShapePassivitySetting.jsx index b47d2356..44152cf8 100644 --- a/src/components/floor-plan/modal/roofShape/RoofShapePassivitySetting.jsx +++ b/src/components/floor-plan/modal/roofShape/RoofShapePassivitySetting.jsx @@ -38,6 +38,8 @@ export default function RoofShapePassivitySetting({ id, pos = { x: 50, y: 230 }
+
+
{buttons.map((button) => (
+
+
{shapeMenu.map((item) => (
+
+
+
+
+
+
{getMessage('common.horizon')} diff --git a/src/components/floor-plan/modal/wallLineOffset/WallLineOffsetSetting.jsx b/src/components/floor-plan/modal/wallLineOffset/WallLineOffsetSetting.jsx index 5e01918d..60bab5b7 100644 --- a/src/components/floor-plan/modal/wallLineOffset/WallLineOffsetSetting.jsx +++ b/src/components/floor-plan/modal/wallLineOffset/WallLineOffsetSetting.jsx @@ -48,6 +48,8 @@ export default function WallLineOffsetSetting({ id, pos = { x: 50, y: 230 } }) {
+
+
{buttonMenu.map((item) => (
- - + {/* + */} + +
diff --git a/src/hooks/surface/useSurfaceShapeBatch.js b/src/hooks/surface/useSurfaceShapeBatch.js index 10201c8c..0e08f45b 100644 --- a/src/hooks/surface/useSurfaceShapeBatch.js +++ b/src/hooks/surface/useSurfaceShapeBatch.js @@ -88,7 +88,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { console.log('surfaceRefs.xInversion', surfaceRefs.xInversion) console.log('surfaceRefs.yInversion', surfaceRefs.yInversion) console.log('surfaceRefs.rotate', surfaceRefs.rotate) - + const { xInversion, yInversion, rotate } = surfaceRefs const options = { fill: 'transparent', stroke: 'black', @@ -102,9 +102,9 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { lockScalingX: true, // X 축 크기 조정 잠금 lockScalingY: true, // Y 축 크기 조정 잠금 name: MENU.BATCH_CANVAS.SURFACE_SHAPE_BATCH_TEMP, - flipX: surfaceRefs.yInversion, - flipY: surfaceRefs.xInversion, - angle: Math.abs(surfaceRefs.rotate), + flipX: xInversion !== yInversion ? surfaceRefs.yInversion : false, + flipY: xInversion !== yInversion ? surfaceRefs.xInversion : false, + angle: xInversion && yInversion ? Math.abs((surfaceRefs.rotate + 180) % 360) : Math.abs(surfaceRefs.rotate), originX: 'center', originY: 'center', pitch: globalPitch, @@ -199,7 +199,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { swalFire({ text: getMessage('common.canvas.validate.size'), icon: 'error' }) check = false } - if (surfaceId === 3 && length3 > length1) { + if (surfaceId === 3 && length3 >= length1) { swalFire({ text: getMessage('surface.shape.validate.size.1to3'), icon: 'error' }) check = false } From ee913ee7820a7b2a9a138452e5570744927bc0e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Fri, 14 Feb 2025 16:18:42 +0900 Subject: [PATCH 008/352] =?UTF-8?q?-=20console.log=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/placementSurface/PlacementSurfaceSetting.jsx | 1 - src/hooks/surface/useSurfaceShapeBatch.js | 9 +++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting.jsx b/src/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting.jsx index e321c52a..1e697e6f 100644 --- a/src/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting.jsx +++ b/src/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting.jsx @@ -236,7 +236,6 @@ export default function PlacementSurfaceSetting({ id, pos = { x: 50, y: 230 } }) surfaceRefs.yInversion = yInversion //상하반전 surfaceRefs.rotate = rotate * 90 //앵글 setIsHidden(true) - console.log('surfaceRefs', surfaceRefs) applySurfaceShape(surfaceRefs, selectedType, id) } diff --git a/src/hooks/surface/useSurfaceShapeBatch.js b/src/hooks/surface/useSurfaceShapeBatch.js index 0e08f45b..983997ab 100644 --- a/src/hooks/surface/useSurfaceShapeBatch.js +++ b/src/hooks/surface/useSurfaceShapeBatch.js @@ -85,9 +85,6 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === MENU.BATCH_CANVAS.SURFACE_SHAPE_BATCH_TEMP)) points = getSurfaceShape(surfaceId, pointer, { length1, length2, length3, length4, length5 }) - console.log('surfaceRefs.xInversion', surfaceRefs.xInversion) - console.log('surfaceRefs.yInversion', surfaceRefs.yInversion) - console.log('surfaceRefs.rotate', surfaceRefs.rotate) const { xInversion, yInversion, rotate } = surfaceRefs const options = { fill: 'transparent', @@ -102,9 +99,9 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { lockScalingX: true, // X 축 크기 조정 잠금 lockScalingY: true, // Y 축 크기 조정 잠금 name: MENU.BATCH_CANVAS.SURFACE_SHAPE_BATCH_TEMP, - flipX: xInversion !== yInversion ? surfaceRefs.yInversion : false, - flipY: xInversion !== yInversion ? surfaceRefs.xInversion : false, - angle: xInversion && yInversion ? Math.abs((surfaceRefs.rotate + 180) % 360) : Math.abs(surfaceRefs.rotate), + flipX: xInversion !== yInversion ? yInversion : false, + flipY: xInversion !== yInversion ? xInversion : false, + angle: xInversion && yInversion ? Math.abs((rotate + 180) % 360) : Math.abs(rotate), originX: 'center', originY: 'center', pitch: globalPitch, From 4dbf59b7a9ab5160c35aca0bedff9fc6332d75de Mon Sep 17 00:00:00 2001 From: changkyu choi Date: Fri, 14 Feb 2025 17:07:53 +0900 Subject: [PATCH 009/352] =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=A9=B4=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=EC=84=A4=EC=A0=95=20plan=5Fno=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 5 + src/components/floor-plan/FloorPlan.jsx | 19 +- .../circuitTrestle/CircuitTrestleSetting.jsx | 3 +- .../placementShape/PlacementShapeSetting.jsx | 55 ++- src/hooks/option/useCanvasSetting.js | 414 +++++++++++------- .../roofcover/useRoofAllocationSetting.js | 102 ++--- src/hooks/usePlan.js | 28 ++ 7 files changed, 397 insertions(+), 229 deletions(-) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 58ec721e..07e2c1ec 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -329,7 +329,12 @@ export default function CanvasMenu(props) { x: 50, y: 180, }, + planNo: selectedPlan?.planNo ? selectedPlan.planNo : pid, + openPiont: 'canvasMenus', } + /** + * 배치면 초기설정 팝업 열기 + */ const onClickPlacementInitialMenu = () => { addPopup(placementInitialId, 1, ) } diff --git a/src/components/floor-plan/FloorPlan.jsx b/src/components/floor-plan/FloorPlan.jsx index 6adae9a8..054f1e00 100644 --- a/src/components/floor-plan/FloorPlan.jsx +++ b/src/components/floor-plan/FloorPlan.jsx @@ -19,7 +19,7 @@ export default function FloorPlan({ children }) { const { closeAll } = usePopup() const { menuNumber, setMenuNumber } = useCanvasMenu() - const { fetchSettings, fetchBasicSettings } = useCanvasSetting() + const { fetchSettings } = useCanvasSetting() const resetCurrentMenu = useResetRecoilState(currentMenuState) useEffect(() => { return () => { @@ -27,7 +27,9 @@ export default function FloorPlan({ children }) { } }, []) - // URL 파라미터에서 objectNo 설정 + /** + * URL 파라미터에서 objectNo 설정 + */ useEffect(() => { if (!objectNo) { notFound() @@ -35,15 +37,16 @@ export default function FloorPlan({ children }) { setCurrentObjectNo(objectNo) }, [objectNo, setCurrentObjectNo]) - // 설정 데이터 fetch + /** + * 설정 데이터 fetch + */ useEffect(() => { - if (!correntObjectNo) return // correntObjectNo가 없으면 실행하지 않음 + /** + * correntObjectNo가 없으면 실행하지 않음 + */ + if (!correntObjectNo) return - if (menuNumber === null) { - //setMenuNumber(1) - } fetchSettings() - fetchBasicSettings() return () => { closeAll() diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index 2c904ddd..0df59150 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -475,8 +475,9 @@ export default function CircuitTrestleSetting({ id }) { type: 'alert', }) return + } else { + setTabNum(2) } - setTabNum(2) } // 닫기 버튼 클릭 시 처리하는 함수 추가 diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx index 046a89a9..0e127c74 100644 --- a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx @@ -20,7 +20,7 @@ export const ROOF_MATERIAL_LAYOUT = { PARALLEL: 'P', STAIRS: 'S', } -export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, setShowPlaceShapeModal }) { +export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, planNo, openPiont }) { const [showSizeGuideModal, setShowSizeGuidModal] = useState(false) const [showMaterialGuideModal, setShowMaterialGuidModal] = useState(false) const { closePopup } = usePopup() @@ -28,7 +28,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set const roofMaterials = useRecoilValue(roofMaterialsAtom) const globalLocale = useRecoilValue(globalLocaleStore) - const { basicSetting, setBasicSettings, basicSettingSave } = useCanvasSetting() + const { basicSetting, setBasicSettings, fetchBasicSettings, basicSettingSave } = useCanvasSetting() const [addedRoofs, setAddedRoofs] = useRecoilState(addedRoofsState) const { findCommonCode } = useCommonCode() const [raftCodes, setRaftCodes] = useState([]) // 서까래 정보 @@ -42,19 +42,26 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set hajebichi: useRef(null), } - //치수 입력방법(복시도입력/실측값입력/육지붕) + /** + * 치수 입력방법(복시도입력/실측값입력/육지붕) + */ const roofSizeSetArray = [ { id: 'ra01', name: 'roofSizeSet', value: '1', message: 'modal.placement.initial.setting.size.roof' }, { id: 'ra02', name: 'roofSizeSet', value: '2', message: 'modal.placement.initial.setting.size.actual' }, { id: 'ra03', name: 'roofSizeSet', value: '3', message: 'modal.placement.initial.setting.size.none.pitch' }, ] - //지붕각도 설정(경사/각도) + /** + * 지붕각도 설정(경사/각도) + */ const roofAngleSetArray = [ { id: 'ra04', name: 'roofAngleSet', value: 'slope', message: 'modal.placement.initial.setting.roof.pitch' }, { id: 'ra05', name: 'roofAngleSet', value: 'flat', message: 'modal.placement.initial.setting.roof.angle' }, ] + /** + * 지붕재 초기값 + */ const defaultRoofSettings = { roofSizeSet: '1', // 기본 치수 입력 방법 roofAngleSet: 'slope', // 기본 지붕 각도 설정 @@ -86,14 +93,24 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set width: '265', } + useEffect(() => { + console.log('🚀 ~ useEffect ~ planNo:', planNo, openPiont) + /** + * 메뉴에서 배치면초기설정 선택 시 조회 + */ + if (openPiont && openPiont === 'canvasMenus') fetchBasicSettings(planNo, openPiont) + }, []) + useEffect(() => { if (addedRoofs.length > 0) { const raftCodeList = findCommonCode('203800') setRaftCodes(raftCodeList) - // 데이터 설정 확인 후 데이터가 없으면 기본 데이터 설정 + /** + * 데이터 설정 확인 후 데이터가 없으면 기본 데이터 설정 + */ if (addedRoofs.length > 0) { - setCurrentRoof({ ...addedRoofs[0] }) + setCurrentRoof({ ...addedRoofs[0], planNo: basicSetting.planNo }) } else { setCurrentRoof(defaultRoofSettings) } @@ -101,13 +118,14 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set }, [addedRoofs]) useEffect(() => { - //console.log('🚀 ~ fetchBasicSettings ~ currentRoof :', currentRoof) if (!currentRoof) return setBasicSettings({ ...basicSetting, + planNo: Number(currentRoof.planNo), roofSizeSet: String(currentRoof.roofSizeSet), roofAngleSet: currentRoof.roofAngleSet, roofsData: { + planNo: Number(currentRoof.planNo), roofApply: true, roofSeq: 0, roofMatlCd: currentRoof.roofMatlCd, @@ -130,10 +148,15 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set setCurrentRoof({ ...currentRoof, roofAngleSet: value }) } - // Function to update the roofType and corresponding values const handleRoofTypeChange = (value) => { const selectedRoofMaterial = roofMaterials.find((roof) => roof.roofMatlCd === value) - setCurrentRoof({ ...selectedRoofMaterial, index: 0, roofSizeSet: String(currentRoof.roofSizeSet), roofAngleSet: currentRoof.roofAngleSet }) + setCurrentRoof({ + ...selectedRoofMaterial, + index: 0, + planNo: currentRoof.planNo, + roofSizeSet: String(currentRoof.roofSizeSet), + roofAngleSet: currentRoof.roofAngleSet, + }) } const changeInput = (value, e) => { @@ -152,6 +175,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set const handleSaveBtn = () => { const roofInfo = { ...currentRoof, + planNo: basicSetting.planNo, roofCd: roofRef.roofCd.current?.value, width: roofRef.width.current?.value, length: roofRef.length.current?.value, @@ -169,16 +193,19 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set console.log('save Info', { ...basicSetting, selectedRoofMaterial: { - // 선택된 지붕재 정보 roofInfo, }, }) - // 배치면초기설정 저장 + /** + * 배치면초기설정 저장 + */ basicSettingSave({ ...basicSetting, + /** + * 선택된 지붕재 정보 + */ selectedRoofMaterial: { - // 선택된 지붕재 정보 roofInfo, }, }) @@ -239,9 +266,9 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set
{currentRoof && roofAngleSetArray.map((item, index) => ( -
+
-
+
{ const tempFetchRoofMaterials = !fetchRoofMaterials - //최초 1회만 실행하도록 처리 + /* 초 1회만 실행하도록 처리 */ setFetchRoofMaterials(tempFetchRoofMaterials) if (tempFetchRoofMaterials) { addRoofMaterials() } }, []) - useEffect(() => { - // 지붕재 select 정보가 존재해야 배치면초기설정 DB 정보 비교 후 지붕재 정보를 가져올 수 있음 - if ( - (!previousObjectNoRef.current && !correntObjectNo && previousObjectNoRef.current !== correntObjectNo) || - (roofMaterials.length !== 0 && JSON.stringify(previousRoofMaterialsRef.current) !== JSON.stringify(roofMaterials)) - ) { - // 1회만 실행 - if (roofMaterials && previousRoofMaterialsYn === 'N') { - if (correntObjectNo) { - fetchBasicSettings() - previousRoofMaterialsYn = 'Y' - } - } - - // 이전 값을 업데이트 - previousObjectNoRef.current = correntObjectNo - previousRoofMaterialsRef.current = roofMaterials + /** + * 지붕재 초기세팅 + */ + const addRoofMaterials = async () => { + if (roofMaterials.length !== 0) { + return } - }, [roofMaterials, correntObjectNo]) + const { data } = await getRoofMaterialList() - //배치면 초기설정 화면이 열리지 않아도 데이터 set 하기 위해서 추가 + const roofLists = data.map((item, idx) => ({ + ...item, + id: item.roofMatlCd, + name: item.roofMatlNm, + selected: idx === 0, + index: idx, + nameJp: item.roofMatlNmJp, + length: item.lenBase && parseInt(item.lenBase), + width: item.widBase && parseInt(item.widBase), + raft: item.raftBase && parseInt(item.raftBase), + layout: ['ROOF_ID_SLATE', 'ROOF_ID_SINGLE'].includes(item.roofMatlCd) ? ROOF_MATERIAL_LAYOUT.STAIRS : ROOF_MATERIAL_LAYOUT.PARALLEL, + hajebichi: item.roofPchBase && parseInt(item.roofPchBase), + pitch: item.pitch ? parseInt(item.pitch) : 4, + angle: item.angle ? parseInt(item.angle) : 21.8, + })) + setRoofMaterials(roofLists) + const selectedRoofMaterial = roofLists[0] + + if (addedRoofs.length === 0) { + const newAddedRoofs = [] + newAddedRoofs.push({ ...selectedRoofMaterial, selected: true, index: 0 }) + setAddedRoofs(newAddedRoofs) + } + setBasicSettings({ ...basicSetting, selectedRoofMaterial: selectedRoofMaterial }) + } + + // // ObjectNo 최초 데이터 설정 확인 + // const previousObjectNoRef = useRef(null) + // // 지붕재 정보 최초 데이터 설정 확인 + // const previousRoofMaterialsRef = useRef(null) + + // useEffect(() => { + // // 지붕재 select 정보가 존재해야 배치면초기설정 DB 정보 비교 후 지붕재 정보를 가져올 수 있음 + // if ( + // (!previousObjectNoRef.current && !correntObjectNo && previousObjectNoRef.current !== correntObjectNo) || + // (roofMaterials.length !== 0 && JSON.stringify(previousRoofMaterialsRef.current) !== JSON.stringify(roofMaterials)) + // ) { + // // 1회만 실행 + // if (roofMaterials && previousRoofMaterialsYn === 'N') { + // if (correntObjectNo) { + // //fetchBasicSettings() + // previousRoofMaterialsYn = 'Y' + // } + // } + + // // 이전 값을 업데이트 + // previousObjectNoRef.current = correntObjectNo + // previousRoofMaterialsRef.current = roofMaterials + // } + // }, [roofMaterials, correntObjectNo]) + + /** + * 배치면 초기설정 화면이 열리지 않아도 데이터 set 하기 위해서 추가 + */ useEffect(() => { if (addedRoofs.length > 0) { const raftCodeList = findCommonCode('203800') @@ -215,39 +260,6 @@ export function useCanvasSetting() { if (settingsDataSave !== undefined) onClickOption2() }, [settingsData]) - //지붕재 초기세팅 - const addRoofMaterials = async () => { - if (roofMaterials.length !== 0) { - return - } - const { data } = await getRoofMaterialList() - - const roofLists = data.map((item, idx) => ({ - ...item, - id: item.roofMatlCd, - name: item.roofMatlNm, - selected: idx === 0, - index: idx, - nameJp: item.roofMatlNmJp, - length: item.lenBase && parseInt(item.lenBase), - width: item.widBase && parseInt(item.widBase), - raft: item.raftBase && parseInt(item.raftBase), - layout: ['ROOF_ID_SLATE', 'ROOF_ID_SINGLE'].includes(item.roofMatlCd) ? ROOF_MATERIAL_LAYOUT.STAIRS : ROOF_MATERIAL_LAYOUT.PARALLEL, - hajebichi: item.roofPchBase && parseInt(item.roofPchBase), - pitch: item.pitch ? parseInt(item.pitch) : 4, - angle: item.angle ? parseInt(item.angle) : 21.8, - })) - setRoofMaterials(roofLists) - const selectedRoofMaterial = roofLists[0] - - if (addedRoofs.length === 0) { - const newAddedRoofs = [] - newAddedRoofs.push({ ...selectedRoofMaterial, selected: true, index: 0 }) - setAddedRoofs(newAddedRoofs) - } - setBasicSettings({ ...basicSetting, selectedRoofMaterial: selectedRoofMaterial }) - } - const getFonts = (itemValue) => { if (!itemValue) return { id: 1, name: 'MS PGothic', value: 'MS PGothic' } const data = [ @@ -319,22 +331,30 @@ export function useCanvasSetting() { } } - // 기본설정(PlacementShapeSetting) 조회 및 초기화 - const fetchBasicSettings = async () => { + /** + * 기본설정(PlacementShapeSetting) 조회 및 초기화 + */ + const fetchBasicSettings = async (planNo, openPiont) => { try { - await get({ url: `/api/canvas-management/canvas-basic-settings/by-object/${correntObjectNo}` }).then((res) => { + await get({ + //url: `/api/canvas-management/canvas-basic-settings/by-object?objectNo=${correntObjectNo}&planNo=${pid}`, + url: `http://localhost:8080/api/canvas-management/canvas-basic-settings/by-object/${correntObjectNo}/${planNo}`, + //url: `/api/canvas-management/canvas-basic-settings/by-object/${correntObjectNo}/${planNo}`, + }).then((res) => { let roofsRow = {} let roofsArray = {} if (res.length > 0) { roofsRow = res.map((item) => { return { + planNo: item.planNo, roofSizeSet: String(item.roofSizeSet), roofAngleSet: item.roofAngleSet, } }) roofsArray = res.map((item) => { return { + planNo: item.planNo, roofApply: item.roofApply, roofSeq: item.roofSeq, roofMatlCd: item.roofMatlCd, @@ -350,6 +370,7 @@ export function useCanvasSetting() { } else { roofsRow = [ { + planNo: planNo, roofSizeSet: '1', roofAngleSet: 'slope', }, @@ -357,6 +378,7 @@ export function useCanvasSetting() { roofsArray = [ { + planNo: planNo, roofApply: true, roofSeq: 0, roofMatlCd: 'ROOF_ID_WA_53A', @@ -370,10 +392,23 @@ export function useCanvasSetting() { }, ] - setMenuNumber(1) + /* 메뉴에서 배치면 초기설정 클릭 시 실행하지 않음 */ + if (openPiont === null) { + /* 배치면 초기설정 미저장 상태이면 화면 열기 */ + const placementInitialProps = { + id: popupId, + pos: { + x: 50, + y: 180, + }, + planNo: planNo, + openPiont: 'useCanvasSetting', + } + addPopup(popupId, 1, ) + } } - // 데이터 설정 + /* 데이터 설정 */ const addRoofs = [] for (let i = 0; i < roofsArray.length; i++) { roofMaterials?.map((material) => { @@ -387,6 +422,7 @@ export function useCanvasSetting() { hajebichi: roofsArray[i].roofHajebichi, raft: roofsArray[i].roofGap, layout: roofsArray[i].roofLayout, + planNo: roofsRow[i].planNo, roofSizeSet: roofsRow[i].roofSizeSet, roofAngleSet: roofsRow[i].roofAngleSet, pitch: roofsArray[i].roofPitch, @@ -399,6 +435,7 @@ export function useCanvasSetting() { setBasicSettings({ ...basicSetting, roofMaterials: addRoofs[0], + planNo: roofsRow[0].planNo, roofSizeSet: roofsRow[0].roofSizeSet, roofAngleSet: roofsRow[0].roofAngleSet, roofsData: roofsArray, @@ -412,15 +449,19 @@ export function useCanvasSetting() { setCanvasSetting({ ...basicSetting }) } - // 기본설정(PlacementShapeSetting) 저장 + /** + * 기본설정(PlacementShapeSetting) 저장 + */ const basicSettingSave = async (params) => { try { const patternData = { objectNo: correntObjectNo, + planNo: Number(params.planNo), roofSizeSet: Number(params.roofSizeSet), roofAngleSet: params.roofAngleSet, roofMaterialsAddList: [ { + planNo: Number(params.planNo), roofApply: true, roofSeq: 0, roofMatlCd: @@ -438,21 +479,20 @@ export function useCanvasSetting() { } //await post({ url: `/api/canvas-management/canvas-basic-settings`, data: patternData }) - await post({ url: `/api/canvas-management/canvas-basic-settings`, data: patternData }).then((res) => { - console.log('🚀 ~ basicSettingSave ~ res :', res) - + await post({ url: `http://localhost:8080/api/canvas-management/canvas-basic-settings`, data: patternData }).then((res) => { + // await post({ url: `/api/canvas-management/canvas-basic-settings`, data: patternData }).then((res) => { swalFire({ text: getMessage(res.returnMessage) }) - + /* 배치면초기설정 조회 */ setBasicSettings({ ...params }) }) - //Recoil 설정 + /* CanvasSetting Recoil 설정 */ setCanvasSetting({ ...basicSetting }) - // 배치면초기설정 조회 - fetchBasicSettings() + /* 배치면초기설정 조회 */ + fetchBasicSettings(params.planNo, null) - // 메뉴 설정 + /* 메뉴 설정 */ if (['2', '3'].includes(basicSetting?.roofSizeSet)) { setMenuNumber(3) setType('surface') @@ -463,16 +503,11 @@ export function useCanvasSetting() { setCurrentMenu(MENU.ROOF_COVERING.EXTERIOR_WALL_LINE) } - //모듈 선택 데이터 초기화 + /* 모듈 선택 데이터 초기화 */ resetModuleSelectionData() - - // 모듈 선택 데이터 초기화 moduleSelectedDataTrigger({ common: {}, module: {}, roofConstructions: [] }) - - // 모듈 선택 데이터 초기화 const isModuleExist = canvas.getObjects().some((obj) => obj.name === POLYGON_TYPE.MODULE) if (!isModuleExist) { - // 모듈 선택 데이터 초기화 resetSelectedModules() } } catch (error) { @@ -480,7 +515,9 @@ export function useCanvasSetting() { } } - // CanvasSetting 조회 및 초기화 + /** + * CanvasSetting 조회 및 초기화 + */ const fetchSettings = async () => { try { const res = await get({ url: `/api/canvas-management/canvas-settings/by-object/${correntObjectNo}` }) @@ -493,16 +530,24 @@ export function useCanvasSetting() { const optionData4 = settingModalSecondOptions.option4.map((item) => ({ ...item, selected: res[item.column] })) const optionData5 = settingModalFirstOptions.dimensionDisplay.map((item) => ({ ...item })) - //흡착점 ON/OFF + /** + * 흡착점 ON/OFF + */ setAdsorptionPointMode({ ...adsorptionPointMode, adsorptionPoint: res.adsorpPoint }) - //치수선 설정 + /** + * 치수선 설정 + */ setDimensionLineSettings({ ...dimensionLineSettings, pixel: res.originPixel, color: res.originColor }) - //도면크기 설정 + /** + * 도면크기 설정 + */ setPlanSizeSettingMode({ ...planSizeSettingMode, originHorizon: res.originHorizon, originVertical: res.originVertical }) - // 데이터 설정 + /** + * 데이터 설정 + */ setSettingModalFirstOptions({ ...settingModalFirstOptions, option1: optionData1, @@ -517,35 +562,45 @@ export function useCanvasSetting() { const fontPatternData = { commonText: { - //문자 글꼴 조회 데이터 + /** + * 문자 글꼴 조회 데이터 + */ fontFamily: getFonts(res.wordFont), fontWeight: getFontStyles(res.wordFontStyle), fontSize: getFontSizes(res.wordFontSize), fontColor: getFontColors(res.wordFontColor), }, flowText: { - //흐름방향 글꼴 조회 데이터 + /** + * 흐름방향 글꼴 조회 데이터 + */ fontFamily: getFonts(res.flowFont), fontWeight: getFontStyles(res.flowFontStyle), fontSize: getFontSizes(res.flowFontSize), fontColor: getFontColors(res.flowFontColor), }, dimensionLineText: { - //치수 글꼴 조회 데이터 + /** + * 치수 글꼴 조회 데이터 + */ fontFamily: getFonts(res.dimensioFont), fontWeight: getFontStyles(res.dimensioFontStyle), fontSize: getFontSizes(res.dimensioFontSize), fontColor: getFontColors(res.dimensioFontColor), }, circuitNumberText: { - //회로번호 글꼴 조회 데이터 + /** + * 회로번호 글꼴 조회 데이터 + */ fontFamily: getFonts(res.circuitNumFont), fontWeight: getFontStyles(res.circuitNumFontStyle), fontSize: getFontSizes(res.circuitNumFontSize), fontColor: getFontColors(res.circuitNumFontColor), }, lengthText: { - //치수선 글꼴 조회 데이터 + /** + * 치수선 글꼴 조회 데이터 + */ fontFamily: getFonts(res.lengthFont), fontWeight: getFontStyles(res.lengthFontStyle), fontSize: getFontSizes(res.lengthFontSize), @@ -553,10 +608,14 @@ export function useCanvasSetting() { }, } - //조회된 글꼴 데이터 set + /** + * 조회된 글꼴 데이터 set + */ setGlobalFont(fontPatternData) - //점/선 그리드 + /** + * 점/선 그리드 + */ const patternData = { INTERVAL: { type: res.gridType, @@ -572,32 +631,48 @@ export function useCanvasSetting() { setDotLineGridSettingState(patternData) //setCurrentSetting(patternData) - //그리드 색 설정 + /** + * 그리드 색 설정 + */ setGridColor(res.gridColor) } else { //조회된 글꼴 데이터가 없는 경우 (데이터 초기화) - //흡착점 ON/OFF + /** + * 흡착점 ON/OFF + */ setAdsorptionPointMode({ ...adsorptionPointMode, adsorptionPoint: false }) - //치수선 설정 + /** + * 치수선 설정 + */ resetDimensionLineSettings() - //도면크기 설정 + /** + * 도면크기 설정 + */ resetPlanSizeSettingMode() - // 데이터 설정 + /** + * 데이터 설정 + */ resetSettingModalFirstOptions() resetSettingModalSecondOptions() - // 데이터 초기화 + /** + * 데이터 초기화 + */ resetGlobalFont() - //점/선 그리드 + /** + * 점/선 그리드 + */ setDotLineGridSettingState({ ...defaultDotLineGridSetting }) //setCurrentSetting({ ...defaultDotLineGridSetting }) - //그리드 색 설정 + /** + * 그리드 색 설정 + */ setGridColor('#FF0000') } @@ -607,9 +682,13 @@ export function useCanvasSetting() { } } - // CanvasSetting 옵션 클릭 후 저장 + /** + * CanvasSetting 옵션 클릭 후 저장 + */ const onClickOption2 = async () => { - // 서버에 전송할 데이터 + /** + * 서버에 전송할 데이터 + */ const dataToSend = { firstOption1: option1.map((item) => ({ column: item.column, @@ -630,9 +709,13 @@ export function useCanvasSetting() { })), } const patternData = { - //견적서 번호 + /** + * 견적서 번호 + */ objectNo: correntObjectNo, - //디스플레이 설정(다중) + /** + * 디스플레이 설정(다중) + */ allocDisplay: dataToSend.firstOption1[0].selected, outlineDisplay: dataToSend.firstOption1[1].selected, gridDisplay: dataToSend.firstOption1[2].selected, @@ -643,60 +726,82 @@ export function useCanvasSetting() { 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 + /** + * 흡착점 ON/OFF + */ adsorpPoint: adsorptionPointMode.adsorptionPoint, //??: adsorptionRange, 사용여부 확인 필요 - //글꼴 설정 + /** + * 글꼴 설정 + */ //문자 글꼴 wordFont: globalFont.commonText.fontFamily?.value ?? 'MS PGothic', wordFontStyle: globalFont.commonText.fontWeight?.value ?? 'normal', wordFontSize: globalFont.commonText.fontSize?.value ?? 16, wordFontColor: globalFont.commonText.fontColor?.value ?? 'black', - //흐름방향 글꼴 + /** + * 흐름방향 글꼴 + */ flowFont: globalFont.flowText.fontFamily?.value ?? 'MS PGothic', flowFontStyle: globalFont.flowText.fontWeight?.value ?? 'normal', flowFontSize: globalFont.flowText.fontSize?.value ?? 16, flowFontColor: globalFont.flowText.fontColor?.value ?? 'black', - //치수 글꼴 + /** + * 치수 글꼴 + */ dimensioFont: globalFont.dimensionLineText.fontFamily?.value ?? 'MS PGothic', dimensioFontStyle: globalFont.dimensionLineText.fontWeight?.value ?? 'normal', dimensioFontSize: globalFont.dimensionLineText.fontSize?.value ?? 16, dimensioFontColor: globalFont.dimensionLineText.fontColor?.value ?? 'black', - //회로번호 글꼴 + /** + * 회로번호 글꼴 + */ circuitNumFont: globalFont.circuitNumberText.fontFamily?.value ?? 'MS PGothic', circuitNumFontStyle: globalFont.circuitNumberText.fontWeight?.value ?? 'normal', circuitNumFontSize: globalFont.circuitNumberText.fontSize?.value ?? 16, circuitNumFontColor: globalFont.circuitNumberText.fontColor?.value ?? 'black', - //치수선 글꼴 + /** + * 치수선 글꼴 + */ lengthFont: globalFont.lengthText.fontFamily?.value ?? 'MS PGothic', lengthFontStyle: globalFont.lengthText.fontWeight?.value ?? 'normal', lengthFontSize: globalFont.lengthText.fontSize?.value ?? 16, lengthFontColor: globalFont.lengthText.fontColor?.value ?? 'black', - //치수선 설정 + /** + * 치수선 설정 + */ originPixel: dimensionLineSettings.pixel, originColor: dimensionLineSettings.color, - //도면크기 설정 + /** + * 도면크기 설정 + */ originHorizon: planSizeSettingMode.originHorizon, originVertical: planSizeSettingMode.originVertical, @@ -713,14 +818,20 @@ export function useCanvasSetting() { console.log('patternData ', patternData) - // HTTP POST 요청 보내기 + /** + * 저장 API 호출 + */ await post({ url: `/api/canvas-management/canvas-settings`, data: patternData }) .then((res) => { //swalFire({ text: getMessage(res.returnMessage) }) - // Canvas 디스플레이 설정 시 해당 옵션 적용 + /** + * Canvas 디스플레이 설정 시 해당 옵션 적용 + */ frontSettings() - // 저장 후 재조회 + /** + * 저장 후 재조회 + */ fetchSettings() }) .catch((error) => { @@ -731,77 +842,80 @@ export function useCanvasSetting() { //setAdsorptionRange(item.range) } - // Canvas 디스플레이 설정 시 해당 옵션 적용 + /** + * Canvas 디스플레이 설정 시 해당 옵션 적용 + */ const frontSettings = async () => { const option1 = settingModalFirstOptions.option1 - // 'allocDisplay' 할당 표시 - // 'outlineDisplay' 외벽선 표시 'outerLine', POLYGON_TYPE.WALL - // 'gridDisplay' 그리드 표시 'lindGrid', 'dotGrid' - // 'lineDisplay' 지붕선 표시 'roof', POLYGON_TYPE.ROOF - // 'wordDisplay' 문자 표시 - // 'circuitNumDisplay' 회로번호 표시 - // 'flowDisplay' 흐름방향 표시 'arrow', 'flowText' - // 'trestleDisplay' 가대 표시 - // 'imageDisplay' 이미지 표시 - // 'totalDisplay' 집계표 표시 + /** + * 'allocDisplay' 할당 표시 + * 'outlineDisplay' 외벽선 표시 'outerLine', POLYGON_TYPE.WALL + * 'gridDisplay' 그리드 표시 'lindGrid', 'dotGrid' + * 'lineDisplay' 지붕선 표시 'roof', POLYGON_TYPE.ROOF + * 'wordDisplay' 문자 표시 + * 'circuitNumDisplay' 회로번호 표시 + * 'flowDisplay' 흐름방향 표시 'arrow', 'flowText' + * 'trestleDisplay' 가대 표시 + * 'imageDisplay' 이미지 표시 + * 'totalDisplay' 집계표 표시 + */ - let optionName //옵션명 - let optionSelected //옵션상태 + /** + * 옵션명 + * 옵션상태 + */ + let optionName + let optionSelected for (let i = 0; i < option1.length; i++) { switch (option1[i].column) { - case 'allocDisplay': //할당 표시 + case 'allocDisplay': optionName = [] break - case 'outlineDisplay': //외벽선 표시 + case 'outlineDisplay': optionName = ['outerLine', POLYGON_TYPE.WALL] break - case 'gridDisplay': //그리드 표시 + case 'gridDisplay': optionName = ['lindGrid', 'dotGrid', 'tempGrid'] break - case 'lineDisplay': //지붕선 표시 + case 'lineDisplay': optionName = ['roof', POLYGON_TYPE.ROOF] break - case 'wordDisplay': //문자 표시 + case 'wordDisplay': optionName = ['commonText'] break - case 'circuitNumDisplay': //회로번호 표시 + case 'circuitNumDisplay': optionName = ['circuitNumber'] break - case 'flowDisplay': //흐름방향 표시 + case 'flowDisplay': optionName = ['arrow', 'flowText'] break - case 'trestleDisplay': //가대 표시 + case 'trestleDisplay': optionName = ['rack', 'smartRack', 'bracket', 'eaveBar', 'halfEaveBar'] break - case 'imageDisplay': //이미지 표시 + case 'imageDisplay': optionName = ['9'] break - case 'totalDisplay': //집계표 표시 - // 작업할 필요 없음 + case 'totalDisplay': + /** + * 작업할 필요 없음 + */ optionName = [] break } - // 표시 선택 상태(true/false) + /** + * 표시 선택 상태(true/false) + */ optionSelected = option1[i].selected - //canvas.getObjects() >> canvasObjects canvasObjects .filter((obj) => optionName.includes(obj.name)) - //.filter((obj) => obj.name === optionName) .forEach((obj) => { obj.set({ visible: optionSelected }) - //obj.set({ visible: !obj.visible }) }) canvas?.renderAll() - - // console.log( - // 'optionName', - // optionName, - // canvas.getObjects().filter((obj) => optionName.includes(obj.name)), - // ) } } diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js index 34ec3f13..f54ac44d 100644 --- a/src/hooks/roofcover/useRoofAllocationSetting.js +++ b/src/hooks/roofcover/useRoofAllocationSetting.js @@ -100,19 +100,26 @@ export function useRoofAllocationSetting(id) { closePopup(id) } - fetchBasicSettings() + fetchBasicSettings(basicSetting.planNo, null) }, []) - // 지붕면 할당 조회 및 초기화 - const fetchBasicSettings = async () => { + /** + * 지붕면 할당 조회 및 초기화 + */ + const fetchBasicSettings = async (planNo, openPiont) => { try { - await get({ url: `/api/canvas-management/canvas-basic-settings/by-object/${correntObjectNo}` }).then((res) => { + await get({ + //url: `/api/canvas-management/canvas-basic-settings/by-object/objectNo=${correntObjectNo}/planNo=${currentCanvasPlan.planNo}`, + url: `http://localhost:8080/api/canvas-management/canvas-basic-settings/by-object/${correntObjectNo}/${planNo}`, + // url: `/api/canvas-management/canvas-basic-settings/by-object/${correntObjectNo}/${planNo}`, + }).then((res) => { console.log('🚀 ~ useRoofAllocationSetting ~ fetchBasicSettings ~ res >>>>>>>>>>>>>>>>>>>>> :', res) let roofsArray = {} if (res.length > 0) { roofsArray = res.map((item) => { return { + planNo: item.planNo, roofApply: item.roofApply, roofSeq: item.roofSeq, roofMatlCd: item.roofMatlCd, @@ -128,6 +135,7 @@ export function useRoofAllocationSetting(id) { } else { roofsArray = [ { + planNo: planNo, roofApply: true, roofSeq: 0, roofMatlCd: 'ROOF_ID_WA_53A', @@ -142,11 +150,9 @@ export function useRoofAllocationSetting(id) { ] } - console.log('fetchBasicSettings roofsArray', roofsArray) - - console.log(roofsArray) - - // 데이터 설정 + /** + * 데이터 설정 + */ const selectRoofs = [] for (let i = 0; i < roofsArray.length; i++) { roofMaterials?.map((material) => { @@ -169,15 +175,16 @@ export function useRoofAllocationSetting(id) { } // setCurrentRoofList(selectRoofs) - //setBasicSetting({ ...basicSetting, roofsData: roofsArray }) setBasicSetting({ ...basicSetting, + planNo: res[0].planNo, roofSizeSet: res[0].roofSizeSet, roofAngleSet: res[0].roofAngleSet, roofsData: roofsArray, selectedRoofMaterial: selectRoofs.find((roof) => roof.selected), }) setBasicInfo({ + planNo: '' + res[0].planNo, roofSizeSet: '' + res[0].roofSizeSet, roofAngleSet: '' + res[0].roofAngleSet, }) @@ -187,14 +194,18 @@ export function useRoofAllocationSetting(id) { } } - // 지붕면 할당 저장 + /** + * 지붕면 할당 저장 + */ const basicSettingSave = async () => { try { const patternData = { objectNo: correntObjectNo, + planNo: Number(basicSetting.planNo), roofSizeSet: Number(basicSetting.roofSizeSet), roofAngleSet: basicSetting.roofAngleSet, roofAllocationList: currentRoofList.map((item, index) => ({ + planNo: Number(basicSetting.planNo), roofApply: item.selected, roofSeq: index, roofMatlCd: item.roofMatlCd === null || item.roofMatlCd === undefined ? 'ROOF_ID_WA_53A' : item.roofMatlCd, @@ -210,14 +221,15 @@ export function useRoofAllocationSetting(id) { console.log('🚀 ~ basicSettingSave ~ patternData >>>>>>>>>>>>> :', patternData) - await post({ url: `/api/canvas-management/roof-allocation-settings`, data: patternData }).then((res) => { + await post({ url: `http://localhost:8080/api/canvas-management/roof-allocation-settings`, data: patternData }).then((res) => { + // await post({ url: `/api/canvas-management/roof-allocation-settings`, data: patternData }).then((res) => { console.log('roof-allocation-settings res ', res) swalFire({ text: getMessage(res.returnMessage) }) }) //Recoil 설정 //setCanvasSetting({ ...basicSetting }) - fetchBasicSettings() + fetchBasicSettings(basicSetting.planNo, null) } catch (error) { swalFire({ text: error.message, icon: 'error' }) } @@ -249,11 +261,15 @@ export function useRoofAllocationSetting(id) { setCurrentRoofList(newRoofList) } - // 선택한 지붕재로 할당 + /** + * 선택한 지붕재로 할당 + */ const handleSave = () => { basicSettingSave() - // 모두 actualSize 있으면 바로 적용 없으면 actualSize 설정 + /** + * 모두 actualSize 있으면 바로 적용 없으면 actualSize 설정 + */ if (checkInnerLines()) { addPopup(popupId, 1, ) } else { @@ -262,7 +278,9 @@ export function useRoofAllocationSetting(id) { } } - // 지붕재 오른쪽 마우스 클릭 후 단일로 지붕재 변경 필요한 경우 + /** + * 지붕재 오른쪽 마우스 클릭 후 단일로 지붕재 변경 필요한 경우 + */ const handleSaveContext = () => { basicSettingSave() const newRoofList = currentRoofList.map((roof, idx) => { @@ -400,7 +418,9 @@ export function useRoofAllocationSetting(id) { canvas?.renderAll() } - // 지붕재 변경 + /** + * 지붕재 변경 + */ const handleChangeRoofMaterial = (value, index) => { const selectedIndex = roofMaterials.findIndex((roof) => roof.selected) @@ -415,7 +435,9 @@ export function useRoofAllocationSetting(id) { setCurrentRoofList(newRoofList) } - // 기본 지붕재 radio값 변경 + /** + * 기본 지붕재 radio값 변경 + */ const handleDefaultRoofMaterial = (index) => { const newRoofList = currentRoofList.map((roof, idx) => { return { ...roof, selected: idx === index } @@ -424,7 +446,9 @@ export function useRoofAllocationSetting(id) { setCurrentRoofList(newRoofList) } - // 서까래 변경 + /** + * 서까래 변경 + */ const handleChangeRaft = (e, index) => { const raftValue = e.clCode @@ -451,42 +475,6 @@ export function useRoofAllocationSetting(id) { const handleChangeInput = (e, type = '', index) => { const value = e.target.value - /*if (type === 'pitch') { - // type이 pitch인 경우 소수점 1자리까지만 입력 가능 - const reg = /^[0-9]+(\.[0-9]{0,1})?$/ - - if (!reg.test(value)) { - e.target.value = value.substring(0, value.length - 1) - const newRoofList = currentRoofList.map((roof, idx) => { - if (idx === index) { - return { - ...roof, - [type]: currentAngleType === 'slope' ? value.substring(0, value.length - 1) : getChonByDegree(value.substring(0, value.length - 1)), - } - } - return roof - }) - - setCurrentRoofList(newRoofList) - - return - } else { - const newRoofList = currentRoofList.map((roof, idx) => { - if (idx === index) { - return { - ...roof, - [type]: currentAngleType === 'slope' ? value : getChonByDegree(value), - } - } - return roof - }) - - setCurrentRoofList(newRoofList) - } - - return - }*/ - const newRoofList = currentRoofList.map((roof, idx) => { if (idx === index) { return { ...roof, [type]: value } @@ -516,7 +504,9 @@ export function useRoofAllocationSetting(id) { setCurrentRoofList(newRoofList) } - // 모듈 선택에서 선택한 데이터 초기화 + /** + * 모듈 선택에서 선택한 데이터 초기화 + */ const modifyModuleSelectionData = () => { if (moduleSelectionData.roofConstructions.length > 0) { setModuleSelectionData({ ...moduleSelectionData, roofConstructions: [] }) diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js index c78448db..348686d0 100644 --- a/src/hooks/usePlan.js +++ b/src/hooks/usePlan.js @@ -15,6 +15,7 @@ import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider' import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController' import { outerLinePointsState } from '@/store/outerLineAtom' import { placementShapeDrawingPointsState } from '@/store/placementShapeDrawingAtom' +import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' export function usePlan(params = {}) { const { floorPlanState } = useContext(FloorPlanContext) @@ -38,6 +39,8 @@ export function usePlan(params = {}) { const resetOuterLinePoints = useResetRecoilState(outerLinePointsState) const resetPlacementShapeDrawingPoints = useResetRecoilState(placementShapeDrawingPointsState) + const { fetchBasicSettings } = useCanvasSetting() + /** * 마우스 포인터의 가이드라인 제거 */ @@ -209,6 +212,9 @@ export function usePlan(params = {}) { setPlans((plans) => [...plans.map((plan) => ({ ...plan, isCurrent: false })), newPlan]) swalFire({ text: getMessage('plan.message.save') }) } + + /* 플랜 추가 시 배치면초기설정 정보 조회 */ + fetchBasicSettings(newPlan.planNo, null) }) .catch((error) => { swalFire({ text: error.response.data.message, icon: 'error' }) @@ -267,6 +273,10 @@ export function usePlan(params = {}) { const handleCurrentPlan = async (newCurrentId) => { const planNo = plans?.find((obj) => obj.id === newCurrentId).planNo const objectNo = floorPlanState.objectNo + + /* 플랜 이동 시 배치면초기설정 정보 조회 */ + fetchBasicSettings(planNo, null) + //견적서 or 발전시뮬 if (pathname !== '/floor-plan') { @@ -409,6 +419,10 @@ export function usePlan(params = {}) { .then((res) => { setPlans((plans) => plans.filter((plan) => plan.id !== targetPlan.id)) removeImage(currentCanvasPlan.id) + + /* 플랜 삭제 후 배치면 초기설정 삭제 */ + deleteBasicSettings(targetPlan.objectNo, targetPlan.planNo) + swalFire({ text: getMessage('plan.message.delete') }) }) .catch((error) => { @@ -422,6 +436,9 @@ export function usePlan(params = {}) { } else if (targetPlan.id !== lastPlan.id) { setCurrentCanvasPlan(lastPlan) setPlans((plans) => plans.map((plan) => ({ ...plan, isCurrent: plan.id === lastPlan.id }))) + + /* 플랜 삭제 시 그 전 플랫의 배치면초기설정 정보 조회 */ + fetchBasicSettings(lastPlan.planNo, null) } } @@ -470,6 +487,17 @@ export function usePlan(params = {}) { } } + /** + * 플랜 삭제 시 배치면 초기설정 데이터 삭제 + * + * @param {string} objectNo - 물건번호 + * @param {string} planNo - 플랜번호 + */ + const deleteBasicSettings = async (objectNo, planNo) => { + await promiseDel({ url: `http://localhost:8080/api/canvas-management/delete-basic-settings/${objectNo}/${planNo}` }) + //await promiseDel({ url: `/api/canvas-management/delete-basic-settings/${objectNo}/${planNo}` }) + } + return { canvas, plans, From 138dc288063d794d5d6b4406109dc36226769dab Mon Sep 17 00:00:00 2001 From: changkyu choi Date: Fri, 14 Feb 2025 17:10:42 +0900 Subject: [PATCH 010/352] =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=A9=B4=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=EC=84=A4=EC=A0=95=20plan=5Fno=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9=20>>=20=EB=88=84=EB=9D=BD=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/option/useCanvasSetting.js | 8 ++++---- src/hooks/roofcover/useRoofAllocationSetting.js | 8 ++++---- src/hooks/usePlan.js | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js index 90b69b5b..78f8beb5 100644 --- a/src/hooks/option/useCanvasSetting.js +++ b/src/hooks/option/useCanvasSetting.js @@ -338,8 +338,8 @@ export function useCanvasSetting() { try { await get({ //url: `/api/canvas-management/canvas-basic-settings/by-object?objectNo=${correntObjectNo}&planNo=${pid}`, - url: `http://localhost:8080/api/canvas-management/canvas-basic-settings/by-object/${correntObjectNo}/${planNo}`, - //url: `/api/canvas-management/canvas-basic-settings/by-object/${correntObjectNo}/${planNo}`, + // url: `http://localhost:8080/api/canvas-management/canvas-basic-settings/by-object/${correntObjectNo}/${planNo}`, + url: `/api/canvas-management/canvas-basic-settings/by-object/${correntObjectNo}/${planNo}`, }).then((res) => { let roofsRow = {} let roofsArray = {} @@ -479,8 +479,8 @@ export function useCanvasSetting() { } //await post({ url: `/api/canvas-management/canvas-basic-settings`, data: patternData }) - await post({ url: `http://localhost:8080/api/canvas-management/canvas-basic-settings`, data: patternData }).then((res) => { - // await post({ url: `/api/canvas-management/canvas-basic-settings`, data: patternData }).then((res) => { + // await post({ url: `http://localhost:8080/api/canvas-management/canvas-basic-settings`, data: patternData }).then((res) => { + await post({ url: `/api/canvas-management/canvas-basic-settings`, data: patternData }).then((res) => { swalFire({ text: getMessage(res.returnMessage) }) /* 배치면초기설정 조회 */ setBasicSettings({ ...params }) diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js index f54ac44d..7bfee7ba 100644 --- a/src/hooks/roofcover/useRoofAllocationSetting.js +++ b/src/hooks/roofcover/useRoofAllocationSetting.js @@ -110,8 +110,8 @@ export function useRoofAllocationSetting(id) { try { await get({ //url: `/api/canvas-management/canvas-basic-settings/by-object/objectNo=${correntObjectNo}/planNo=${currentCanvasPlan.planNo}`, - url: `http://localhost:8080/api/canvas-management/canvas-basic-settings/by-object/${correntObjectNo}/${planNo}`, - // url: `/api/canvas-management/canvas-basic-settings/by-object/${correntObjectNo}/${planNo}`, + // url: `http://localhost:8080/api/canvas-management/canvas-basic-settings/by-object/${correntObjectNo}/${planNo}`, + url: `/api/canvas-management/canvas-basic-settings/by-object/${correntObjectNo}/${planNo}`, }).then((res) => { console.log('🚀 ~ useRoofAllocationSetting ~ fetchBasicSettings ~ res >>>>>>>>>>>>>>>>>>>>> :', res) let roofsArray = {} @@ -221,8 +221,8 @@ export function useRoofAllocationSetting(id) { console.log('🚀 ~ basicSettingSave ~ patternData >>>>>>>>>>>>> :', patternData) - await post({ url: `http://localhost:8080/api/canvas-management/roof-allocation-settings`, data: patternData }).then((res) => { - // await post({ url: `/api/canvas-management/roof-allocation-settings`, data: patternData }).then((res) => { + // await post({ url: `http://localhost:8080/api/canvas-management/roof-allocation-settings`, data: patternData }).then((res) => { + await post({ url: `/api/canvas-management/roof-allocation-settings`, data: patternData }).then((res) => { console.log('roof-allocation-settings res ', res) swalFire({ text: getMessage(res.returnMessage) }) }) diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js index 348686d0..95b6c902 100644 --- a/src/hooks/usePlan.js +++ b/src/hooks/usePlan.js @@ -494,8 +494,8 @@ export function usePlan(params = {}) { * @param {string} planNo - 플랜번호 */ const deleteBasicSettings = async (objectNo, planNo) => { - await promiseDel({ url: `http://localhost:8080/api/canvas-management/delete-basic-settings/${objectNo}/${planNo}` }) - //await promiseDel({ url: `/api/canvas-management/delete-basic-settings/${objectNo}/${planNo}` }) + // await promiseDel({ url: `http://localhost:8080/api/canvas-management/delete-basic-settings/${objectNo}/${planNo}` }) + await promiseDel({ url: `/api/canvas-management/delete-basic-settings/${objectNo}/${planNo}` }) } return { From 85ee69d08a714132cd6c27ddf8b3525e556cc22b Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Mon, 17 Feb 2025 10:28:52 +0900 Subject: [PATCH 011/352] =?UTF-8?q?=ED=95=A8=EC=88=98=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../circuitTrestle/CircuitTrestleSetting.jsx | 7 +++++-- src/hooks/module/useTrestle.js | 18 +++++++++--------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index 0df59150..fbff17b2 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -33,7 +33,7 @@ const ALLOCATION_TYPE = { export default function CircuitTrestleSetting({ id }) { const { getMessage } = useMessage() const { closePopup } = usePopup() - const { apply, setViewCircuitNumberTexts } = useTrestle() + const { apply, setViewCircuitNumberTexts, getEstimateData } = useTrestle() const { swalFire } = useSwal() const { saveEstimate } = useEstimate() const canvas = useRecoilValue(canvasState) @@ -344,7 +344,10 @@ export default function CircuitTrestleSetting({ id }) { handleCanvasToPng(1) //회로할당 저장 클릭 시 - const result = await apply() + // 가대 및 지지금구 설치 + apply() + + const result = await getEstimateData() //회로할당 저장 시 result=null인 경우에도 회로번호 텍스트 표시 유지 처리 setViewCircuitNumberTexts(true) diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index 3f52f0ca..d4f54339 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -598,7 +598,6 @@ export const useTrestle = () => { surface.set({ quotationParam, isComplete: true }) }) - return setEstimateData() } catch (e) { // 에러 발생시 가대 초기화 console.error(e) @@ -624,7 +623,7 @@ export const useTrestle = () => { } // itemList 조회 후 estimateParam에 저장 - const setEstimateData = async () => { + const getEstimateData = async () => { const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) //surfaces.pcses들을 배열로 묶는다 const pcses = surfaces[0].pcses.filter((pcs) => pcs !== null && pcs !== undefined) @@ -653,17 +652,18 @@ export const useTrestle = () => { //견적서 itemList 조회 const { data, data2, result } = await getQuotationItem(params) - let itemList - if (!data) { - return - } - itemList = data if (result.resultCode === 'E') { swalFire({ text: result.resultMsg, icon: 'error' }) - return null + return } + let itemList + if (!data || data.length === 0) { + return + } + itemList = data + //northArrangement 북면 설치 여부 const northArrangement = getNorthArrangement() // circuitItemList의 경우는 moduleList에서 circuitId만 groupBy한다. @@ -2698,5 +2698,5 @@ export const useTrestle = () => { canvas.renderAll() } - return { apply, getTrestleParams, clear, setViewCircuitNumberTexts } + return { apply, getTrestleParams, clear, setViewCircuitNumberTexts, getEstimateData } } From 872817152dd45b046feef158746b71ca12ca5664 Mon Sep 17 00:00:00 2001 From: changkyu choi Date: Mon, 17 Feb 2025 14:36:54 +0900 Subject: [PATCH 012/352] =?UTF-8?q?=EA=B2=BD=EC=82=AC=20default=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=EB=90=98=EC=96=B4=20=EC=9E=88=EC=96=B4?= =?UTF-8?q?=EC=84=9C=20defaultValue=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/placementShape/PlacementShapeSetting.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx index 0e127c74..87b71111 100644 --- a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx @@ -284,7 +284,6 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla From 2a6f82c6ecf410f72839b5c369120c49c64100a1 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Mon, 17 Feb 2025 14:38:59 +0900 Subject: [PATCH 013/352] =?UTF-8?q?-=20canvas=20object=20=EC=84=A0?= =?UTF-8?q?=ED=83=9D=EC=8B=9C=20=EC=A0=9C=EC=9D=BC=20=EC=95=9E=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=98=A4=EB=8A=94=20=ED=98=84=EC=83=81=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=20-=20=EC=A7=80=EB=B6=95=ED=98=95=EC=83=81=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EC=8B=9C=20=EC=A7=80=EB=B6=95=EC=9E=AC=20?= =?UTF-8?q?=EA=B2=BD=EC=82=AC=EC=99=80=20=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/roofcover/useRoofShapeSetting.js | 31 +++++++++++++++++++--- src/hooks/useCanvas.js | 1 + 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/hooks/roofcover/useRoofShapeSetting.js b/src/hooks/roofcover/useRoofShapeSetting.js index e9b7bafe..9146e615 100644 --- a/src/hooks/roofcover/useRoofShapeSetting.js +++ b/src/hooks/roofcover/useRoofShapeSetting.js @@ -1,6 +1,6 @@ import { useEffect, useRef, useState } from 'react' import { useMessage } from '@/hooks/useMessage' -import { useRecoilValue, useSetRecoilState } from 'recoil' +import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' import { ANGLE_TYPE, canvasState, currentAngleTypeSelector, currentMenuState, currentObjectState, pitchTextSelector } from '@/store/canvasAtom' import { LINE_TYPE, POLYGON_TYPE } from '@/common/common' import { usePolygon } from '@/hooks/usePolygon' @@ -9,9 +9,9 @@ import { useLine } from '@/hooks/useLine' import { outerLineFixState } from '@/store/outerLineAtom' import { useSwal } from '@/hooks/useSwal' import { usePopup } from '@/hooks/usePopup' -import { getChonByDegree } from '@/util/canvas-util' +import { getChonByDegree, getDegreeByChon } from '@/util/canvas-util' import RoofAllocationSetting from '@/components/floor-plan/modal/roofAllocation/RoofAllocationSetting' -import { settingModalFirstOptionsState } from '@/store/settingAtom' +import { addedRoofsState, basicSettingState, settingModalFirstOptionsState } from '@/store/settingAtom' // 지붕형상 설정 export function useRoofShapeSetting(id) { @@ -52,6 +52,10 @@ export function useRoofShapeSetting(id) { const settingModalFirstOptions = useRecoilValue(settingModalFirstOptionsState) + const [addedRoofs, setAddedRoofs] = useRecoilState(addedRoofsState) + + const [basicSetting, setBasicSetting] = useRecoilState(basicSettingState) + useEffect(() => { pitchRef.current = currentAngleType === ANGLE_TYPE.SLOPE ? pitch : getChonByDegree(pitch) }, [pitch]) @@ -179,6 +183,11 @@ export function useRoofShapeSetting(id) { return } + if ([1, 2, 3, 5, 6, 7, 8].includes(shapeNum)) { + // 변별로 설정이 아닌 경우 경사를 지붕재에 적용해주어야함 + setRoofPitch() + } + switch (shapeNum) { case 1: { outerLines = saveRidge() @@ -479,6 +488,22 @@ export function useRoofShapeSetting(id) { canvas.remove(tempPolygon) } + // 저장된 경사를 addedRoof 첫번째요소, basicSettings의 selectedRoofMaterial에 적용 + const setRoofPitch = () => { + const newAddedRoofs = addedRoofs.map((roof, index) => { + if (index === 0) { + return { ...roof, pitch: pitchRef.current, angle: getDegreeByChon(pitchRef.current) } + } else { + return { ...roof } + } + }) + + const newBasicSetting = { ...basicSetting, selectedRoofMaterial: { ...newAddedRoofs[0] } } + + setBasicSetting(newBasicSetting) + setAddedRoofs(newAddedRoofs) + } + // 동, 서 선택 시 가로라인을 케라바로 설정 const setWestAndEastRoof = (line) => { if (line.direction === 'left' || line.direction === 'right') { diff --git a/src/hooks/useCanvas.js b/src/hooks/useCanvas.js index 8dec3cc0..52be5c90 100644 --- a/src/hooks/useCanvas.js +++ b/src/hooks/useCanvas.js @@ -34,6 +34,7 @@ export function useCanvas(id) { height: canvasSize.vertical, width: canvasSize.horizontal, backgroundColor: 'white', + preserveObjectStacking: true, selection: false, }) From 465ed72a4c5756f05358326ae6dcebbc6b53419f Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Mon, 17 Feb 2025 15:51:00 +0900 Subject: [PATCH 014/352] =?UTF-8?q?=EC=A0=80=EC=9E=A5=20=EC=8B=9C=20db?= =?UTF-8?q?=EB=8F=84=20update=20=ED=95=84=EC=9A=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/roofcover/useRoofShapeSetting.js | 53 ++++++++++++++++++++-- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/src/hooks/roofcover/useRoofShapeSetting.js b/src/hooks/roofcover/useRoofShapeSetting.js index 9146e615..8e1f97b6 100644 --- a/src/hooks/roofcover/useRoofShapeSetting.js +++ b/src/hooks/roofcover/useRoofShapeSetting.js @@ -11,7 +11,9 @@ import { useSwal } from '@/hooks/useSwal' import { usePopup } from '@/hooks/usePopup' import { getChonByDegree, getDegreeByChon } from '@/util/canvas-util' import RoofAllocationSetting from '@/components/floor-plan/modal/roofAllocation/RoofAllocationSetting' -import { addedRoofsState, basicSettingState, settingModalFirstOptionsState } from '@/store/settingAtom' +import { addedRoofsState, basicSettingState, correntObjectNoState, settingModalFirstOptionsState } from '@/store/settingAtom' +import { useAxios } from '@/hooks/useAxios' +import { globalLocaleStore } from '@/store/localeAtom' // 지붕형상 설정 export function useRoofShapeSetting(id) { @@ -55,6 +57,9 @@ export function useRoofShapeSetting(id) { const [addedRoofs, setAddedRoofs] = useRecoilState(addedRoofsState) const [basicSetting, setBasicSetting] = useRecoilState(basicSettingState) + const correntObjectNo = useRecoilValue(correntObjectNoState) + const globalLocaleState = useRecoilValue(globalLocaleStore) + const { post } = useAxios(globalLocaleState) useEffect(() => { pitchRef.current = currentAngleType === ANGLE_TYPE.SLOPE ? pitch : getChonByDegree(pitch) @@ -492,7 +497,7 @@ export function useRoofShapeSetting(id) { const setRoofPitch = () => { const newAddedRoofs = addedRoofs.map((roof, index) => { if (index === 0) { - return { ...roof, pitch: pitchRef.current, angle: getDegreeByChon(pitchRef.current) } + return { ...roof, pitch: Number(pitchRef.current), angle: getDegreeByChon(pitchRef.current) } } else { return { ...roof } } @@ -500,8 +505,48 @@ export function useRoofShapeSetting(id) { const newBasicSetting = { ...basicSetting, selectedRoofMaterial: { ...newAddedRoofs[0] } } - setBasicSetting(newBasicSetting) - setAddedRoofs(newAddedRoofs) + try { + basicSettingSave(newAddedRoofs) + + setBasicSetting(newBasicSetting) + setAddedRoofs(newAddedRoofs) + } catch (error) { + swalFire({ text: error.message, icon: 'error' }) + } + } + + /** + * 지붕면 할당 저장 + */ + const basicSettingSave = async (newAddedRoofs) => { + try { + const patternData = { + objectNo: correntObjectNo, + planNo: Number(basicSetting.planNo), + roofSizeSet: Number(basicSetting.roofSizeSet), + roofAngleSet: basicSetting.roofAngleSet, + roofAllocationList: newAddedRoofs.map((item, index) => ({ + planNo: Number(basicSetting.planNo), + roofApply: item.selected, + roofSeq: index, + roofMatlCd: item.roofMatlCd === null || item.roofMatlCd === undefined ? 'ROOF_ID_WA_53A' : item.roofMatlCd, + roofWidth: item.width === null || item.width === undefined ? 0 : Number(item.width), + roofHeight: item.length === null || item.length === undefined ? 0 : Number(item.length), + roofHajebichi: item.hajebichi === null || item.hajebichi === undefined ? 0 : Number(item.hajebichi), + roofGap: !item.raft ? item.raftBaseCd : item.raft, + roofLayout: item.layout === null || item.layout === undefined ? 'P' : item.layout, + roofPitch: item.pitch === null || item.pitch === undefined ? 4 : Number(item.pitch), + roofAngle: item.angle === null || item.angle === undefined ? 21.8 : Number(item.angle), + })), + } + + await post({ url: `/api/canvas-management/roof-allocation-settings`, data: patternData }) + + //Recoil 설정 + //setCanvasSetting({ ...basicSetting }) + } catch (error) { + swalFire({ text: error.message, icon: 'error' }) + } } // 동, 서 선택 시 가로라인을 케라바로 설정 From 748d7f83711a8ad96c1579cfa382a1058583df75 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Mon, 17 Feb 2025 16:06:20 +0900 Subject: [PATCH 015/352] =?UTF-8?q?=EA=B2=BD=EC=82=AC,=20=EA=B0=81?= =?UTF-8?q?=EB=8F=84=20=EB=B3=80=EA=B2=BD=20=EC=8B=9C=20=EC=96=91=EB=B0=A9?= =?UTF-8?q?=ED=96=A5=EC=9C=BC=EB=A1=9C=20=EC=88=98=EC=A0=95=EB=90=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/placementShape/PlacementShapeSetting.jsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx index 87b71111..d3aabd8e 100644 --- a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx @@ -15,6 +15,7 @@ import QSelectBox from '@/components/common/select/QSelectBox' import { globalLocaleStore } from '@/store/localeAtom' import { onlyNumberInputChange } from '@/util/input-utils' +import { getChonByDegree, getDegreeByChon } from '@/util/canvas-util' export const ROOF_MATERIAL_LAYOUT = { PARALLEL: 'P', @@ -79,14 +80,12 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla raft: '', raftAuth: 'C', raftBaseCd: 'HEI_455', - roofAngleSet: 'slope', roofCd: '', roofMatlCd: 'ROOF_ID_WA_53A', roofMatlNm: '일본기와 A', roofMatlNmJp: '和瓦A', roofPchAuth: null, roofPchBase: null, - roofSizeSet: '1', selected: true, widAuth: 'R', widBase: '265.000', @@ -288,8 +287,8 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla value={index === 0 ? currentRoof?.pitch : currentRoof?.angle} onChange={(e) => index === 0 - ? setCurrentRoof({ ...currentRoof, pitch: e.target.value }) - : setCurrentRoof({ ...currentRoof, angle: e.target.value }) + ? setCurrentRoof({ ...currentRoof, pitch: e.target.value, angle: getDegreeByChon(e.target.value) }) + : setCurrentRoof({ ...currentRoof, pitch: getChonByDegree(e.target.value), angle: e.target.value }) } />
From c54d096d44efc7dc984c166076d97ee84a5c81ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Mon, 17 Feb 2025 17:30:03 +0900 Subject: [PATCH 016/352] =?UTF-8?q?debugger=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/modal/module/PanelEdit.jsx | 1 - src/hooks/module/useModule.js | 1 - 2 files changed, 2 deletions(-) diff --git a/src/components/floor-plan/modal/module/PanelEdit.jsx b/src/components/floor-plan/modal/module/PanelEdit.jsx index bf03dae6..4d3c5a22 100644 --- a/src/components/floor-plan/modal/module/PanelEdit.jsx +++ b/src/components/floor-plan/modal/module/PanelEdit.jsx @@ -52,7 +52,6 @@ export default function PanelEdit(props) { }) return } - debugger const completeSurfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.isComplete) if (completeSurfaces.length > 0) { diff --git a/src/hooks/module/useModule.js b/src/hooks/module/useModule.js index bd462b5e..c7f13dc0 100644 --- a/src/hooks/module/useModule.js +++ b/src/hooks/module/useModule.js @@ -47,7 +47,6 @@ export function useModule() { canvas.discardActiveObject() //선택해제 - debugger const isSetupModules = getOtherModules(selectedObj) const selectedModules = canvas.getObjects().filter((obj) => selectedIds.includes(obj.id) && obj.name === 'module') //선택했던 객체들만 가져옴 const setupSurface = canvas From 8a0be28ac81d16bff92dc6bcf654126430148b2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Mon, 17 Feb 2025 17:30:29 +0900 Subject: [PATCH 017/352] =?UTF-8?q?=EB=8B=A4=EA=B5=AD=EC=96=B4=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EB=B0=8F=20PCS=20=EC=8B=9C=EB=A6=AC=EC=A6=88=20?= =?UTF-8?q?=EC=84=A0=ED=83=9D=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../step/PowerConditionalSelect.jsx | 23 +++++++++++++++---- src/locales/ja.json | 1 + src/locales/ko.json | 1 + 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx b/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx index 5957103c..df6d15b1 100644 --- a/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx @@ -13,6 +13,12 @@ import { useRecoilState } from 'recoil' import { useRecoilValue } from 'recoil' import { v4 as uuidv4 } from 'uuid' +const PCS_MKR_MULTI_TYPE = { + MULTI: 'MULTI', + SINGLE_P: 'SINGLE-P', + SINGLE_N: 'SINGLE-N', +} + export default function PowerConditionalSelect(props) { let { tabNum, @@ -75,18 +81,26 @@ export default function PowerConditionalSelect(props) { const onCheckSeries = (data) => { let copySeries = [] - if (data.pcsMkrMultiType === 'MULTI') { + if (data.pcsMkrMultiType === PCS_MKR_MULTI_TYPE.MULTI) { copySeries = series.map((s) => { return { ...s, selected: s.pcsSerCd === data.pcsSerCd ? !s.selected : s.selected, } }) - } else if (data.pcsMkrMultiType === 'SINGLE-P') { + } else if (data.pcsMkrMultiType === PCS_MKR_MULTI_TYPE.SINGLE_P) { + if (series.filter((s) => s.selected).length === 0 && data.pcsSerParallelYn === 'Y') { + swalFire({ + title: getMessage('modal.module.pcs.error1'), + icon: 'warning', + }) + + return + } copySeries = series.map((s) => { return { ...s, - selected: s.pcsSerCd === data.pcsSerCd ? !s.selected : s.pcsMkrMultiType === 'MULTI' ? s.selected : false, + selected: s.pcsSerCd === data.pcsSerCd ? !s.selected : data.pcsSerParallelYn === 'Y' ? s.selected : false, } }) } else { @@ -107,7 +121,6 @@ export default function PowerConditionalSelect(props) { setSelectedModels([]) return } - console.log('moduleSelectionData', moduleSelectionData) const pcsMkrCd = selectedSeries[0]?.pcsMkrCd const pcsSerList = selectedSeries.map((series) => { return { pcsSerCd: series.pcsSerCd } @@ -147,7 +160,7 @@ export default function PowerConditionalSelect(props) { return } - if (selectedMaker.pcsMkrMultiType === 'MULTI') { + if (selectedMaker.pcsMkrMultiType === PCS_MKR_MULTI_TYPE.MULTI) { setSelectedModels([...selectedModels, { ...selectedRow, id: uuidv4(), isUsed: false }]) } else if (!selectedModels.find((m) => m.itemId === selectedRow.itemId)) { setSelectedModels([...selectedModels, { ...selectedRow, id: uuidv4(), isUsed: false }]) diff --git a/src/locales/ja.json b/src/locales/ja.json index fd2626b4..1255e72b 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -421,6 +421,7 @@ "modal.module.circuit.number.edit": "モジュール一括回路番号の変更", "modal.module.circuit.number.edit.info": "回路番号を入力してください。", "modal.module.circuit.number": "回路番号", + "modal.module.pcs.error1": "병설용 PCS는 단독으로 선택할 수 없습니다.(JA)", "modal.module.can.not.edit": "회로 구성을 완료한 모듈은 변경할 수 없습니다.(JA)", "modal.line.property.change": "変更する属性を選択してください。", "modal.line.property.change.unselect": "変更するラインを選択してください。", diff --git a/src/locales/ko.json b/src/locales/ko.json index d0bead71..5ea7765f 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -421,6 +421,7 @@ "modal.module.circuit.number.edit": "모듈 일괄 회로 번호 변경", "modal.module.circuit.number.edit.info": "회로 번호를 입력해주세요.", "modal.module.circuit.number": "회로 번호", + "modal.module.pcs.error1": "병설용 PCS는 단독으로 선택할 수 없습니다.", "modal.module.can.not.edit": "회로 구성을 완료한 모듈은 변경할 수 없습니다.", "modal.line.property.change": "변경할 속성을 선택해 주세요.", "modal.line.property.change.unselect": "변경할 라인을 선택해 주세요.", From 3cdfe24b6c789d75c1e7257d8173004062b0d4f6 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Tue, 18 Feb 2025 09:52:37 +0900 Subject: [PATCH 018/352] =?UTF-8?q?=EA=B2=BD=EC=82=AC,=20=EA=B0=81?= =?UTF-8?q?=EB=8F=84=20=EC=9C=A0=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/placementShape/PlacementShapeSetting.jsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx index d3aabd8e..a4162264 100644 --- a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx @@ -149,8 +149,11 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla const handleRoofTypeChange = (value) => { const selectedRoofMaterial = roofMaterials.find((roof) => roof.roofMatlCd === value) + setCurrentRoof({ ...selectedRoofMaterial, + pitch: currentRoof?.pitch, + angle: currentRoof?.angle, index: 0, planNo: currentRoof.planNo, roofSizeSet: String(currentRoof.roofSizeSet), From 1f5351fc5967625d4f390bde993f75dbbc5a6adf Mon Sep 17 00:00:00 2001 From: LEEYONGJAE Date: Tue, 18 Feb 2025 10:15:10 +0900 Subject: [PATCH 019/352] =?UTF-8?q?=EB=B0=9C=EC=A0=84=EC=8B=9C=EB=AE=AC?= =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=85=98=20=EB=A9=94=EB=89=B4=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=20=EC=8B=9C,=20=EA=B2=AC=EC=A0=81=EC=84=9C=20?= =?UTF-8?q?=EB=B2=88=ED=98=B8=20=EC=B2=B4=ED=81=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 2 +- src/hooks/usePlan.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 07e2c1ec..2210b157 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -245,7 +245,7 @@ export default function CanvasMenu(props) { promiseGet({ url: `/api/estimate/${objectNo}/${selectedPlan.planNo}/detail` }).then((res) => { if (res.status === 200) { const estimateDetail = res.data - if (estimateDetail.estimateDate !== null) { + if (estimateDetail.estimateDate !== null && estimateDetail.docNo) { setMenuNumber(menu.index) setCurrentMenu(menu.title) router.push(`/floor-plan/simulator/${menu.index}?pid=${selectedPlan.planNo}&objectNo=${objectNo}`) diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js index 95b6c902..21e391f2 100644 --- a/src/hooks/usePlan.js +++ b/src/hooks/usePlan.js @@ -312,7 +312,7 @@ export function usePlan(params = {}) { } } else { // 발전시뮬레이션 - if (estimateDetail.estimateDate !== null) { + if (estimateDetail.estimateDate !== null && estimateDetail.docNo) { setCurrentCanvasPlan(plans.find((plan) => plan.id === newCurrentId)) setPlans((plans) => plans.map((plan) => ({ ...plan, isCurrent: plan.id === newCurrentId }))) } else { From 9450f7bfa4af737e5a942f6619155e20bb0c250e Mon Sep 17 00:00:00 2001 From: changkyu choi Date: Tue, 18 Feb 2025 10:56:11 +0900 Subject: [PATCH 020/352] =?UTF-8?q?=ED=9A=8C=EB=A1=9C/=EA=B0=80=EB=8C=80?= =?UTF-8?q?=20=EC=8A=B9=EC=95=95=20=EC=A0=80=EC=9E=A5=20=EC=8B=9C=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/circuitTrestle/CircuitTrestleSetting.jsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index fbff17b2..fa26bafa 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -343,9 +343,15 @@ export default function CircuitTrestleSetting({ id }) { handleCanvasToPng(1) - //회로할당 저장 클릭 시 + // 회로할당 저장 클릭 시 // 가대 및 지지금구 설치 - apply() + // apply() + // apply() 결과를 체크하여 null이면 함수 종료 + const applyResult = apply() + if (applyResult === null) { + setIsGlobalLoading(false) + return + } const result = await getEstimateData() From d91c2c8ef5c1867d7ce070cf188527cb44ab01dc Mon Sep 17 00:00:00 2001 From: changkyu choi Date: Tue, 18 Feb 2025 11:00:39 +0900 Subject: [PATCH 021/352] =?UTF-8?q?=ED=9A=8C=EB=A1=9C/=EA=B0=80=EB=8C=80?= =?UTF-8?q?=20=EC=8A=B9=EC=95=95=20=EC=A0=80=EC=9E=A5=20=ED=9B=84=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EB=B0=9C=EC=83=9D=20=EC=8B=9C=20=ED=9A=8C?= =?UTF-8?q?=EB=B2=88=ED=98=B8=20=EC=9C=A0=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/circuitTrestle/CircuitTrestleSetting.jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index fa26bafa..bb5f8e0b 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -343,6 +343,9 @@ export default function CircuitTrestleSetting({ id }) { handleCanvasToPng(1) + //회로할당 저장 시 result=null인 경우에도 회로번호 텍스트 표시 유지 처리 + setViewCircuitNumberTexts(true) + // 회로할당 저장 클릭 시 // 가대 및 지지금구 설치 // apply() @@ -355,9 +358,6 @@ export default function CircuitTrestleSetting({ id }) { const result = await getEstimateData() - //회로할당 저장 시 result=null인 경우에도 회로번호 텍스트 표시 유지 처리 - setViewCircuitNumberTexts(true) - if (result) { handleCanvasToPng(2) // 캔버스 저장 From 96006188e8e7a5a0ce7cc1015ca5617e19faa85e Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 18 Feb 2025 11:35:23 +0900 Subject: [PATCH 022/352] =?UTF-8?q?=EB=AC=BC=EA=B1=B4=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=20=EA=B0=80=EB=8C=80=20=ED=95=84=EB=93=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 5 +- src/components/management/StuffDetail.jsx | 116 ++++++++++---------- src/hooks/main/useMainContentsController.js | 32 +----- src/locales/ja.json | 2 +- src/locales/ko.json | 2 +- 5 files changed, 64 insertions(+), 93 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index be1ea754..82ee8c72 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -69,9 +69,9 @@ export default function Estimate({}) { * objectNo 셋팅 * url로 넘어온 objectNo을 리코일에 세팅 */ - const setCurrentObjectNo = useSetRecoilState(correntObjectNoState) const searchParams = useSearchParams() const objectRecoil = useRecoilValue(floorPlanObjectState) + const currentObjectNo = searchParams.get('objectNo') const currentPid = searchParams.get('pid') //견적서 상세데이터 const { estimateContextState, setEstimateContextState, addItem, handleEstimateFileDownload } = useEstimateController(currentPid, false) @@ -92,9 +92,6 @@ export default function Estimate({}) { const { closeAll } = usePopup() - const currentObjectNo = searchParams.get('objectNo') - setCurrentObjectNo(currentObjectNo) - //새로 추가한 첨부파일 props const fileUploadProps = { uploadFiles: files, diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index 6a2ea628..0b722f35 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -76,7 +76,7 @@ export default function StuffDetail() { standardWindSpeedId: '', //기준풍속 verticalSnowCover: '', //수직적설량 coldRegionFlg: false, //한랭지대책시행(true : 1 / false : 0) - surfaceType: 'Ⅲ・Ⅳ', //면조도구분(Ⅲ・Ⅳ / Ⅱ) + surfaceType: '', //면조도구분(Ⅲ・Ⅳ / Ⅱ) saltAreaFlg: false, //염해지역용아이템사용 (true : 1 / false : 0) installHeight: '', //설치높이 conType: '0', //계약조건(잉여 / 전량) @@ -95,6 +95,7 @@ export default function StuffDetail() { const [selectObjectStatusId, setSelectObjectStatusId] = useState('0') //신축기축 선택값 const [windSpeedList, setWindSpeedList] = useState([]) //기준 풍속 공통코드 리스트 + const [surfaceTypeList, setSurfaceTypeList] = useState([]) //면조도도 공통코드 리스트 const [prefCodeList, setPrefCodeList] = useState([]) //도도부현 코트 리스트 const [prefValue, setPrefValue] = useState('') const [saleStoreList, setSaleStoreList] = useState([]) // 판매점 리스트 @@ -493,6 +494,7 @@ export default function StuffDetail() { const code1 = findCommonCode(200800) //경칭 const code2 = findCommonCode(201700) //신축/기축 const code3 = findCommonCode(202000) //기준풍속 202000 + const code4 = findCommonCode(113700) //면조도 if (code1 != null) { setHonorificCodeList(code1) } @@ -502,6 +504,9 @@ export default function StuffDetail() { if (code3 != null) { setWindSpeedList(code3) } + if (code4 != null) { + setSurfaceTypeList(code4) + } }, [commonCode]) useEffect(() => { @@ -1434,6 +1439,21 @@ export default function StuffDetail() { } } + const checkLength = (value) => { + let str = new String(value) + let _byte = 0 + if (str.length !== 0) { + for (let i = 0; i < str.length; i++) { + let str2 = str.charAt(i) + if (encodeURIComponent(str2).length > 4) { + _byte += 2 + } else { + _byte++ + } + } + } + return _byte + } // 임시저장 const onTempSave = async () => { const formData = form.getValues() @@ -1482,7 +1502,7 @@ export default function StuffDetail() { // 담당자 자리수 체크 if (params?.receiveUser !== '') { - if (params?.receiveUser.trim().length > 10) { + if (checkLength(params?.receiveUser.trim()) > 10) { return swalFire({ text: getMessage('stuff.detail.tempSave.message2'), type: 'alert', icon: 'warning' }) } } @@ -2101,34 +2121,26 @@ export default function StuffDetail() {
- {/* - */} diff --git a/src/components/management/popup/PlanRequestPopQGrid.jsx b/src/components/management/popup/PlanRequestPopQGrid.jsx index 5f78f7a3..a22799bc 100644 --- a/src/components/management/popup/PlanRequestPopQGrid.jsx +++ b/src/components/management/popup/PlanRequestPopQGrid.jsx @@ -15,7 +15,7 @@ export default function PlanRequestPopQGrid(props) { const [gridApi, setGridApi] = useState(null) - const [colDefs, setColDefs] = useState(gridColumns) + const [colDefs] = useState(gridColumns) const defaultColDef = useMemo(() => { return { @@ -65,6 +65,7 @@ export default function PlanRequestPopQGrid(props) { onSelectionChanged={onSelectionChanged} onCellDoubleClicked={onCellDoubleClicked} autoSizeAllColumns={true} + rowSelection={props.rowSelection} overlayNoRowsTemplate={`${getMessage('stuff.grid.noData')}`} /> From faf0ab2365800585b0b013e75180bfb3c1b0078b Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Tue, 25 Feb 2025 14:57:38 +0900 Subject: [PATCH 144/352] =?UTF-8?q?alert=20=3D>=20swal=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20=EC=A3=BC=EC=84=9D=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useTrestle.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index 2e40dab5..38c56f84 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -53,7 +53,7 @@ export const useTrestle = () => { } const construction = moduleSelectionData?.roofConstructions?.find((construction) => construction.roofIndex === roofMaterialIndex).construction if (!construction) { - alert('앞에서 셋팅 안됨') + swalFire({ text: 'construction 존재안함', icon: 'error' }) return } @@ -78,6 +78,7 @@ export const useTrestle = () => { }) } + // 모듈들의 centerPoint들을 이용해 각 모듈의 정보(가장 아랫라인 모듈, 가장 윗라인 모듈, 접면, 반접면 등 계산) const result = calculateForApi(surface) if (!result) { @@ -122,11 +123,10 @@ export const useTrestle = () => { rightExposedHalfBottomPoints.length > 0 || leftExposedHalfTopModules.length > 0 || rightExposedHalfTopPoints.length > 0 - surface.isChidory = isChidory if (plvrYn === 'N' && isChidory) { - alert('치조불가공법입니다.') + swalFire({ text: '치조불가공법입니다.', icon: 'error' }) clear() throw new Error('치조불가공법입니다.') } @@ -732,6 +732,7 @@ export const useTrestle = () => { return { itemList, northArrangement, roofSurfaceList, circuitItemList } } + // 발전 시뮬레이션 용 각도 재계산 const getAzimuth = (parent) => { const { moduleCompass, surfaceCompass, direction } = parent @@ -796,6 +797,7 @@ export const useTrestle = () => { return 0 } + // 북면설치가 한개라도 되어있는지 확인 const getNorthArrangement = () => { const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) let northArrangement = '0' @@ -814,6 +816,7 @@ export const useTrestle = () => { return northArrangement } + // 다음 윗 모듈을 찾는다. const findNextModule = (currentPoint, centerPoints, direction) => { let { x, y, horizontal, vertical } = { ...currentPoint } let { widthArr, heightArr } = centerPoints[0] @@ -860,6 +863,7 @@ export const useTrestle = () => { return result } + // 다음 왼쪽 모듈을 찾는다. const findNextLeftModule = (currentPoint, centerPoints, direction) => { let { x, y, horizontal, vertical } = { ...currentPoint } let { widthArr, heightArr } = centerPoints[0] @@ -923,6 +927,8 @@ export const useTrestle = () => { return result } + + // 다음 오른쪽 모듈을 찾는다. const findNextRightModule = (currentPoint, centerPoints, direction) => { let { x, y, horizontal, vertical } = { ...currentPoint } let { widthArr, heightArr } = centerPoints[0] @@ -1357,6 +1363,7 @@ export const useTrestle = () => { } } + //파라미터로 받은 배치면의 rack을 가지고 지지금구를 그린다. const installBracket = (surface) => { const modules = surface.modules const racks = [] @@ -1555,6 +1562,7 @@ export const useTrestle = () => { } } + // 랙 없음의 지지금구를 그린다. const drawBracketWithOutRack = (module, rackIntvlPct, count, l, direction, moduleIntvlHor, moduleIntvlVer) => { let { width, height, left, top } = module let startPointX From 3b2dfa3ed4a3ff3a12fc531e6828c4c777b3e9a7 Mon Sep 17 00:00:00 2001 From: changkyu choi Date: Tue, 25 Feb 2025 15:09:27 +0900 Subject: [PATCH 145/352] =?UTF-8?q?=EC=A3=BC=EC=84=9D=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/FloorPlan.jsx | 6 +- .../modal/circuitTrestle/step/StepUp.jsx | 158 ++++++++++-------- .../placementShape/PlacementShapeSetting.jsx | 72 +++----- .../roofcover/useRoofAllocationSetting.js | 74 ++++++-- src/store/settingAtom.js | 91 +++++++--- 5 files changed, 247 insertions(+), 154 deletions(-) diff --git a/src/components/floor-plan/FloorPlan.jsx b/src/components/floor-plan/FloorPlan.jsx index 25efa782..18f3ea0d 100644 --- a/src/components/floor-plan/FloorPlan.jsx +++ b/src/components/floor-plan/FloorPlan.jsx @@ -15,7 +15,6 @@ export default function FloorPlan({ children }) { const [correntObjectNo, setCurrentObjectNo] = useRecoilState(correntObjectNoState) const searchParams = useSearchParams() const objectNo = searchParams.get('objectNo') - const pid = searchParams.get('pid') const { closeAll } = usePopup() const { selectedMenu, setSelectedMenu } = useCanvasMenu() @@ -41,11 +40,10 @@ export default function FloorPlan({ children }) { * 설정 데이터 fetch */ useEffect(() => { - /** - * correntObjectNo가 없으면 실행하지 않음 - */ + /** correntObjectNo가 없으면 실행하지 않음 */ if (!correntObjectNo) return + /** CanvasSetting 데이터 fetch */ fetchSettings() return () => { diff --git a/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx b/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx index 8b519e86..5320bef9 100644 --- a/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx @@ -46,8 +46,6 @@ export default function StepUp(props) { const [selectedRows, setSelectedRows] = useState({}) const [isManualSelection, setIsManualSelection] = useState({}) - // 선택된 값들을 저장할 상태 추가 - const [selectedValues, setSelectedValues] = useState({}) const isDisplayCircuitNumber = useRecoilValue(circuitNumDisplaySelector) const circuitNumberText = useRecoilValue(fontSelector('circuitNumberText')) // useCanvasPopupStatusController(6) @@ -58,7 +56,7 @@ export default function StepUp(props) { useEffect(() => { if (allocationType === 'auto') { - // 자동일 때 모듈의 회로 정보 초기화 + /** 자동일 때 모듈의 회로 정보 초기화 */ canvas .getObjects() .filter((obj) => obj.name === POLYGON_TYPE.MODULE) @@ -70,40 +68,41 @@ export default function StepUp(props) { canvas.renderAll() - // PCS 자동 승압설정 정보 조회 + /** PCS 자동 승압설정 정보 조회 */ fetchAutoStepUpData() } else { - // PCS 수동 승압설정 정보 조회 + /** PCS 수동 승압설정 정보 조회 */ fetchPassiStepUpData() } }, []) - // PCS 자동 승압설정 정보 조회 + /** + * PCS 자동 승압설정 정보 조회 + */ const fetchAutoStepUpData = async () => { try { const params = { - ...props.getOptYn(), // 옵션 Y/N - useModuleItemList: props.getUseModuleItemList(), // 사용된 모듈아이템 List - roofSurfaceList: props.getRoofSurfaceList(), // 지붕면 목록 - pcsItemList: props.getSelectedPcsItemList(), // PCS 아이템 목록 + ...props.getOptYn() /** 옵션 Y/N */, + useModuleItemList: props.getUseModuleItemList() /** 사용된 모듈아이템 List */, + roofSurfaceList: props.getRoofSurfaceList() /** 지붕면 목록 */, + pcsItemList: props.getSelectedPcsItemList() /** PCS 아이템 목록 */, } - // 회로 구성 가능 여부 체크 통과 시 승압설정 정보 조회 + /** 회로 구성 가능 여부 체크 통과 시 승압설정 정보 조회 */ getPcsVoltageStepUpList(params).then((res) => { if (res?.result.resultCode === 'S' && res?.data) { const dataArray = Array.isArray(res.data) ? res.data : [res.data] const stepUpListData = formatStepUpListData(dataArray) - // PCS 승압설정 정보 SET + /** PCS 승압설정 정보 SET */ setStepUpListData(stepUpListData) - // PCS 옵션 조회 + /** PCS 옵션 조회 */ const formattedOptCodes = formatOptionCodes(res.data.optionList) setOptCodes(formattedOptCodes) setSeletedOption(formattedOptCodes[0]) - // 캔버스에 회로 정보 적용 - //stepUpListData[0].pcsItemList.forEach((pcsItem) => { + /** 캔버스에 회로 정보 적용 */ stepUpListData[0].pcsItemList.forEach((pcsItem) => { const selectedSerQty = pcsItem.serQtyList.find((serQty) => serQty.selected) if (selectedSerQty) { @@ -111,13 +110,13 @@ export default function StepUp(props) { const targetSurface = canvas.getObjects().filter((obj) => obj.id === roofSurface.roofSurfaceId)[0] const moduleIds = targetSurface.modules.map((module) => module.id) - // 기존 모듈 텍스트 삭제 + /** 기존 모듈 텍스트 삭제 */ canvas .getObjects() .filter((obj) => moduleIds.includes(obj.parentId)) .forEach((text) => canvas.remove(text)) - // 새로운 모듈 회로 정보 추가 + /** 새로운 모듈 회로 정보 추가 */ roofSurface.moduleList.forEach((module) => { const targetModule = canvas.getObjects().find((obj) => obj.id === module.uniqueId) if (targetModule && module.circuit !== '' && module.circuit) { @@ -154,10 +153,6 @@ export default function StepUp(props) { setModuleStatisticsData() } else { swalFire({ text: getMessage('common.message.send.error') }) - // swalFire({ - // title: res.result.resultMsg, - // type: 'alert', - // }) } }) } catch (error) { @@ -165,7 +160,9 @@ export default function StepUp(props) { } } - // PCS 수동 승압설정 정보 조회 + /** + * PCS 수동 승압설정 정보 조회 + */ const fetchPassiStepUpData = async () => { try { // 1-1 2-2 @@ -174,13 +171,13 @@ export default function StepUp(props) { // .filter((obj) => obj.name === POLYGON_TYPE.MODULE && obj.circuit) // .map((module) => module.circuitNumber) - // 모듈 데이터 가져오기 + /** 모듈 데이터 가져오기 */ const modules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE) - // PCS별 회로 정보를 저장할 객체 + /** PCS별 회로 정보를 저장할 객체 */ const pcsSummary = {} - // 각 모듈을 순회하며 PCS별 회로 정보 수집 + /** 각 모듈을 순회하며 PCS별 회로 정보 수집 */ modules.forEach((module) => { if (!module.circuit || !module.pcsItemId) return @@ -204,10 +201,10 @@ export default function StepUp(props) { pcsItemList: getSelectedPcsItemList(), } - // PCS 접속함 및 옵션 목록 조회 + /** PCS 접속함 및 옵션 목록 조회 */ getPcsConnOptionItemList(params).then((res) => { if (res?.result.code === 200 && res?.data) { - // PCS 아이템 리스트에 serQtyList 추가 + /** PCS 아이템 리스트에 serQtyList 추가 */ const pcsItemListWithSerQty = res.data.pcsItemList.map((pcsItem) => { const pcsData = pcsSummary[pcsItem.itemId] || { circuits: {}, totalModules: 0 } const circuitCounts = Object.values(pcsData.circuits) @@ -215,9 +212,9 @@ export default function StepUp(props) { ...pcsItem, serQtyList: [ { - // 한 회로당 최대 모듈 수 + /** 한 회로당 최대 모듈 수 */ serQty: circuitCounts.length > 0 ? Math.max(...circuitCounts) : 0, - // 회로 개수 + /** 회로 개수 */ paralQty: Object.keys(pcsData.circuits).length || 0, rmdYn: 'Y', usePossYn: 'Y', @@ -227,16 +224,16 @@ export default function StepUp(props) { } }) - // Update res.data with modified pcsItemList + /** res.data with modified pcsItemList */ res.data.pcsItemList = pcsItemListWithSerQty const dataArray = Array.isArray(res.data) ? res.data : [res.data] const stepUpListData = formatStepUpListData(dataArray) - // PCS 승압설정 정보 SET + /** PCS 승압설정 정보 SET */ setStepUpListData(stepUpListData) - // PCS 옵션 조회 + /** PCS 옵션 조회 */ const formattedOptCodes = formatOptionCodes(res.data.optionList) setOptCodes(formattedOptCodes) setSeletedOption(formattedOptCodes[0]) @@ -247,7 +244,9 @@ export default function StepUp(props) { } } - // PCS 옵션 조회 + /** + * PCS 옵션 조회 + */ const formatOptionCodes = (optionList = []) => { return optionList?.map((opt) => ({ code: opt.pcsOptCd ? opt.pcsOptCd : '', @@ -256,7 +255,9 @@ export default function StepUp(props) { })) } - // PCS 승압설정 정보 포맷 후 추천 값 저장 + /** + * PCS 승압설정 정보 포맷 후 추천 값 저장 + */ const formatStepUpListData = (dataArray = []) => { const formattedData = dataArray?.map((stepUps) => ({ ...stepUps, @@ -268,7 +269,9 @@ export default function StepUp(props) { return formattedData } - // PCS 옵션 포맷 + /** + * PCS 옵션 포맷 + */ const formatOptionList = (optionList = []) => { return optionList?.map((option) => ({ pcsOptCd: option.pcsOptCd ? option.pcsOptCd : '', @@ -277,7 +280,9 @@ export default function StepUp(props) { })) } - // PCS 아이템 포맷 + /** + * PCS 아이템 포맷 + */ const formatPcsItemList = (pcsItemList = []) => { return pcsItemList?.map((item, index) => ({ goodsNo: item.goodsNo ? item.goodsNo : '', @@ -291,7 +296,9 @@ export default function StepUp(props) { })) } - // PCS 연결 포맷 + /** + * PCS 연결 포맷 + */ const formatConnList = (connList = []) => { if (!connList) return [] // null인 경우 빈 배열 반환 @@ -305,7 +312,9 @@ export default function StepUp(props) { })) } - // PCS 시리즈 포맷 + /** + * PCS 시리즈 포맷 + */ const formatSerQtyList = (serQtyList = []) => { return serQtyList?.map((qty) => ({ code: uuidv4(), @@ -318,7 +327,9 @@ export default function StepUp(props) { })) } - // PCS RoofSurface 포맷 + /** + * PCS RoofSurface 포맷 + */ const formatRoofSurfaceList = (roofSurfaceList = []) => { return roofSurfaceList?.map((rsf) => ({ moduleList: formatModuleList(rsf.moduleList), @@ -327,7 +338,10 @@ export default function StepUp(props) { roofSurfaceIncl: rsf.roofSurfaceIncl ? +rsf.roofSurfaceIncl : '', })) } - // PCS MatModule 포맷 + + /** + * PCS MatModule 포맷 + */ const formatModuleList = (moduleList = []) => { return moduleList?.map((module) => ({ circuit: module.circuit ? module.circuit : '', @@ -337,7 +351,9 @@ export default function StepUp(props) { })) } - // 각 모듈의 탭을 변경하는 함수 + /** + * 각 모듈의 탭을 변경하는 함수 + */ const handleTabChange = (goodsNo, idx, tabNumber) => { setModuleTabs((prev) => ({ ...prev, @@ -345,9 +361,11 @@ export default function StepUp(props) { })) } - // 행 선택 핸들러 함수 추가 + /** + * 행 선택 핸들러 함수 추가 + */ const handleRowClick = (mainIdx, subIdx) => { - // 자동 승압 설정인 경우만 실행 + /** 자동 승압 설정인 경우만 실행 */ if (allocationType !== 'auto') return let tempStepUpListData = [...stepUpListData] @@ -359,26 +377,24 @@ export default function StepUp(props) { } item.selected = index === subIdx }) - // 선택된 행 정보 저장 + /** 선택된 행 정보 저장 */ setStepUpListData(tempStepUpListData) - // console.log('🚀 ~ handleRowClick ~ tempStepUpListData:', tempStepUpListData) - // console.log('🚀 ~ handleRowClick ~ selectedData:', selectedData) - - // PCS 2개 이상 또는 첫번째 PCS 선택 시에만 실행 + /** PCS 2개 이상 또는 첫번째 PCS 선택 시에만 실행 */ if (tempStepUpListData[0].pcsItemList.length > 1 && mainIdx === 0) { - // 파워컨디셔너 옵션 조회 요청 파라미터 + /** 파워컨디셔너 옵션 조회 요청 파라미터 */ const params = { ...props.getOptYn(), // 옵션 Y/N useModuleItemList: props.getUseModuleItemList(), // 사용된 모듈아이템 List roofSurfaceList: props.getRoofSurfaceList(), // 지붕면 목록 pcsItemList: props.getSelectedPcsItemList().map((pcsItem, index) => { - // PCS 아이템 목록 - // tempStepUpListData에서 해당 PCS 아이템 찾기 - // uniqueIndex를 사용하여 매칭 + /** PCS 아이템 목록 + * tempStepUpListData에서 해당 PCS 아이템 찾기 + * uniqueIndex를 사용하여 매칭 + */ const matchingPcsItem = tempStepUpListData[0].pcsItemList.find((item) => item.uniqueIndex === `${pcsItem.itemId}_${index}`) - // 선택된 serQty 찾기 + /** 선택된 serQty 찾기 */ const selectedSerQty = matchingPcsItem?.serQtyList.find((serQty) => serQty.selected)?.serQty || 0 return { @@ -388,34 +404,29 @@ export default function StepUp(props) { }), } - // PCS가 1개 이고 2번째 또는 3번째 PCS serQty가 0인 경우는 추천 API 실행하지 않음 + /** PCS가 1개 이고 2번째 또는 3번째 PCS serQty가 0인 경우는 추천 API 실행하지 않음 */ if (params.pcsItemList.length !== 1 && (params.pcsItemList[1]?.applySerQty !== 0 || params.pcsItemList[2]?.applySerQty) !== 0) { - // PCS 승압설정 정보 조회 - //const res = await getPcsVoltageStepUpList(params) - //getPcsManualConfChk(params).then((res) => { + /** PCS 승압설정 정보 조회 */ getPcsVoltageStepUpList(params).then((res) => { if (res?.result.resultCode === 'S' && res?.data) { const dataArray = Array.isArray(res.data) ? res.data : [res.data] const stepUpListData = formatStepUpListData(dataArray) - // PCS 승압설정 정보 SET + /** PCS 승압설정 정보 SET */ setStepUpListData(stepUpListData) - // PCS 옵션 조회 + /** PCS 옵션 조회 */ const formattedOptCodes = formatOptionCodes(res.data.optionList) setOptCodes(formattedOptCodes) setSeletedOption(formattedOptCodes[0]) } else { swalFire({ text: getMessage('common.message.send.error') }) - // swalFire({ - // title: res.result.resultMsg, - // type: 'alert', - // }) } }) } } + /** 모듈 목록 삭제 */ canvas .getObjects() .filter((obj) => obj.name === POLYGON_TYPE.MODULE) @@ -425,13 +436,14 @@ export default function StepUp(props) { module.pcsItemId = null }) + /** 선택된 모듈 목록 추가 */ selectedData.roofSurfaceList.forEach((roofSurface) => { const targetSurface = canvas.getObjects().filter((obj) => obj.id === roofSurface.roofSurfaceId)[0] const moduleIds = targetSurface.modules.map((module) => { return module.id }) - // 모듈 목록 삭제 + /** 모듈 목록 삭제 */ canvas .getObjects() .filter((obj) => moduleIds.includes(obj.parentId)) @@ -439,7 +451,7 @@ export default function StepUp(props) { canvas.remove(text) }) - // 모듈 목록 추가 + /** 모듈 목록 추가 */ canvas.renderAll() roofSurface.moduleList.forEach((module) => { @@ -475,7 +487,9 @@ export default function StepUp(props) { setModuleStatisticsData() } - // 현재 선택된 값들을 가져오는 함수 추가 + /** + * 현재 선택된 값들을 가져오는 함수 추가 + */ const getCurrentSelections = () => { const selectedValues = stepUpListData[0].pcsItemList.forEach((item) => { item.serQtyList.filter((serQty) => serQty.selected) @@ -496,20 +510,20 @@ export default function StepUp(props) { return selectedValues } - // props로 getCurrentSelections 함수 전달 + /** props로 getCurrentSelections 함수 전달 */ useEffect(() => { if (props.onInitialize) { props.onInitialize(getCurrentSelections) } }, []) - // stepUpListData가 변경될 때마다 업데이트하는 useEffect + /** stepUpListData가 변경될 때마다 업데이트하는 useEffect */ useEffect(() => { if (props.onInitialize) { - // onInitialize를 props에서 가져옴 + /** onInitialize를 props에서 가져옴 */ props.onInitialize(() => ({ ...getCurrentSelections(), - stepUpListData, // stepUpListData를 포함하여 반환 + stepUpListData /** stepUpListData를 포함하여 반환 */, })) } }, [stepUpListData]) @@ -524,9 +538,7 @@ export default function StepUp(props) { {optCodes.length > 0 && (
- {/* */} { return { ...roof, name: globalLocale === 'ko' ? roof.name : roof.nameJp } })} @@ -628,8 +640,6 @@ export default function StepUp(props) {
-
-
- { - handleRadioChange(e) - }} - /> - + {surfaceTypeList.length > 0 && ( +
+ {surfaceTypeList.map((option, index) => ( +
+ { + handleRadioChange(e) + }} + /> + +
+ ))}
-
- { - handleRadioChange(e) - }} - /> - -
-
+ )}
@@ -2689,35 +2701,25 @@ export default function StuffDetail() {
-
-
- { - handleRadioChange(e) - }} - /> - + {surfaceTypeList.length > 0 && ( +
+ {surfaceTypeList.map((option, index) => ( +
+ { + handleRadioChange(e) + }} + /> + +
+ ))}
-
- { - handleRadioChange(e) - }} - /> - -
-
- + )}
diff --git a/src/hooks/main/useMainContentsController.js b/src/hooks/main/useMainContentsController.js index 01f75658..09b4fc0c 100644 --- a/src/hooks/main/useMainContentsController.js +++ b/src/hooks/main/useMainContentsController.js @@ -14,19 +14,6 @@ export const useMainContentsController = () => { setIsGlobalLoading(true) }, []) - /** - * main search area - */ - // const [saleStoreId, setSaleStoreId] = useState('') - // const [saleStoreName, setSaleStoreName] = useState('') - - /** - * main contents area - */ - // const [objectList, setObjectList] = useState([]) - // const [businessCharger, setBusinessCharger] = useState(null) - // const [businessChargerMail, setBusinessChargerMail] = useState(null) - /** * 최근 물건 목록 조회 */ @@ -37,12 +24,6 @@ export const useMainContentsController = () => { url: apiUrl, }).then((res) => { if (res.status === 200) { - // setSaleStoreId(res.data.saleStoreId) - // setSaleStoreName(res.data.saleStoreName) - - // setObjectList(res.data.objectList) - // setBusinessCharger(res.data.businessCharger) - // setBusinessChargerMail(res.data.businessChargerMail) setQcastState({ saleStoreId: res.data.saleStoreId, saleStoreName: res.data.saleStoreName, @@ -52,12 +33,6 @@ export const useMainContentsController = () => { }) setIsGlobalLoading(false) } else { - // setSaleStoreId('') - // setSaleStoreName('') - - // setObjectList([]) - // setBusinessCharger(null) - // setBusinessChargerMail(null) setQcastState({ saleStoreId: '', saleStoreName: '', @@ -65,9 +40,11 @@ export const useMainContentsController = () => { businessCharger: null, businessChargerMail: null, }) + setIsGlobalLoading(false) } }) } catch (error) { + setIsGlobalLoading(false) console.error('MAIN API fetching error:', error) } } @@ -83,11 +60,6 @@ export const useMainContentsController = () => { } return { - // saleStoreId, - // saleStoreName, - // objectList, - // businessCharger, - // businessChargerMail, fetchObjectList, initObjectList, } diff --git a/src/locales/ja.json b/src/locales/ja.json index 1255e72b..9f06310e 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -783,7 +783,7 @@ "stuff.detail.planGridHeader.capacity": "システム容量", "stuff.detail.planGridHeader.roofMaterialIdMulti": "屋根材", "stuff.detail.planGridHeader.constructSpecificationMulti": "施工方法", - "stuff.detail.planGridHeader.standTypeNo": "架台", + "stuff.detail.planGridHeader.supprotMethodIdMulti": "架台", "stuff.detail.planGridHeader.pcTypeNo": "パワーコンディショナー", "stuff.detail.planGridHeader.management": "管理", "stuff.detail.planGrid.btn1": "見積書の照会", diff --git a/src/locales/ko.json b/src/locales/ko.json index 5ea7765f..b43e6853 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -783,7 +783,7 @@ "stuff.detail.planGridHeader.capacity": "시스템용량", "stuff.detail.planGridHeader.roofMaterialIdMulti": "지붕재", "stuff.detail.planGridHeader.constructSpecificationMulti": "시공방법", - "stuff.detail.planGridHeader.standTypeNo": "가대", + "stuff.detail.planGridHeader.supprotMethodIdMulti": "가대", "stuff.detail.planGridHeader.pcTypeNo": "파워컨디셔너", "stuff.detail.planGridHeader.management": "관리", "stuff.detail.planGrid.btn1": "견적서 조회", From d88445c5f0978383e80ae3ae04390c4d0c8127d1 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Tue, 18 Feb 2025 12:17:40 +0900 Subject: [PATCH 023/352] =?UTF-8?q?-=20=EC=BA=94=EB=B2=84=EC=8A=A4=20rende?= =?UTF-8?q?rAll=20=EC=B6=94=EA=B0=80=20-=20=EB=B0=B0=EC=B9=98=EB=A9=B4=20?= =?UTF-8?q?=EC=B4=88=EA=B8=B0=EC=84=A4=EC=A0=95=20=EA=B0=92=20=EC=9C=A0?= =?UTF-8?q?=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../roofAllocation/ContextRoofAllocationSetting.jsx | 3 ++- .../floor-plan/modal/roofShape/passivity/Eaves.jsx | 11 ++++++++++- src/hooks/module/useTrestle.js | 3 ++- src/hooks/roofcover/useEavesGableEdit.js | 2 ++ src/hooks/roofcover/useRoofShapeSetting.js | 13 ++++++++++--- 5 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx b/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx index c9b40430..64b72458 100644 --- a/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx +++ b/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx @@ -23,6 +23,7 @@ export default function ContextRoofAllocationSetting(props) { onAddRoofMaterial, onDeleteRoofMaterial, roofMaterials, + currentRoofMaterial, setCurrentRoofMaterial, roofList, handleDefaultRoofMaterial, @@ -67,7 +68,7 @@ export default function ContextRoofAllocationSetting(props) { options={roofMaterials.map((roof) => { return { ...roof, name: globalLocale === 'ko' ? roof.roofMatlNm : roof.roofMatlNmJp } })} - value={roofMaterials[0]} + value={currentRoofMaterial} onChange={(e) => { // const selected = roofMaterials.find((roofMaterial) => roofMaterial.roofMatlCd === e.id) setCurrentRoofMaterial(e) diff --git a/src/components/floor-plan/modal/roofShape/passivity/Eaves.jsx b/src/components/floor-plan/modal/roofShape/passivity/Eaves.jsx index 2ba0f3e3..c49cb3fa 100644 --- a/src/components/floor-plan/modal/roofShape/passivity/Eaves.jsx +++ b/src/components/floor-plan/modal/roofShape/passivity/Eaves.jsx @@ -1,10 +1,14 @@ import { useMessage } from '@/hooks/useMessage' import { useRecoilValue } from 'recoil' import { ANGLE_TYPE, currentAngleTypeSelector } from '@/store/canvasAtom' +import { selectedRoofMaterialSelector } from '@/store/settingAtom' +import { useEffect } from 'react' export default function Eaves({ offsetRef, pitchRef, pitchText }) { const { getMessage } = useMessage() const currentAngleType = useRecoilValue(currentAngleTypeSelector) + const selectedRoofMaterial = useRecoilValue(selectedRoofMaterialSelector) + return ( <>
@@ -12,7 +16,12 @@ export default function Eaves({ offsetRef, pitchRef, pitchText }) { {getMessage('slope')}
- +
{pitchText}
diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index d4f54339..59b0ff07 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -672,7 +672,8 @@ export const useTrestle = () => { // roofSurfaceList 생성 const roofSurfaceList = surfaces.map((surface) => { const parent = canvas.getObjects().find((obj) => obj.id === surface.parentId) - const { directionText, roofMaterial, pitch: slope, moduleCompass, surfaceCompass } = parent + const { directionText, roofMaterial, moduleCompass, surfaceCompass } = parent + const slope = Number(roofMaterial.pitch) const roofMaterialIndex = parent.roofMaterial.index const { nameJp: roofMaterialIdMulti } = roofMaterial const moduleSelection = moduleSelectionData?.roofConstructions?.find((construction) => construction.roofIndex === roofMaterialIndex) diff --git a/src/hooks/roofcover/useEavesGableEdit.js b/src/hooks/roofcover/useEavesGableEdit.js index 7e84994e..ff0073ae 100644 --- a/src/hooks/roofcover/useEavesGableEdit.js +++ b/src/hooks/roofcover/useEavesGableEdit.js @@ -190,6 +190,8 @@ export function useEavesGableEdit(id) { convertPolygonToLines(wallLine) }) + canvas.renderAll() + addCanvasMouseEventListener('mouse:over', mouseOverEvent) addCanvasMouseEventListener('mouse:down', mouseDownEvent) } diff --git a/src/hooks/roofcover/useRoofShapeSetting.js b/src/hooks/roofcover/useRoofShapeSetting.js index 8e1f97b6..b4909170 100644 --- a/src/hooks/roofcover/useRoofShapeSetting.js +++ b/src/hooks/roofcover/useRoofShapeSetting.js @@ -11,7 +11,13 @@ import { useSwal } from '@/hooks/useSwal' import { usePopup } from '@/hooks/usePopup' import { getChonByDegree, getDegreeByChon } from '@/util/canvas-util' import RoofAllocationSetting from '@/components/floor-plan/modal/roofAllocation/RoofAllocationSetting' -import { addedRoofsState, basicSettingState, correntObjectNoState, settingModalFirstOptionsState } from '@/store/settingAtom' +import { + addedRoofsState, + basicSettingState, + correntObjectNoState, + selectedRoofMaterialSelector, + settingModalFirstOptionsState, +} from '@/store/settingAtom' import { useAxios } from '@/hooks/useAxios' import { globalLocaleStore } from '@/store/localeAtom' @@ -25,15 +31,16 @@ export function useRoofShapeSetting(id) { const currentAngleType = useRecoilValue(currentAngleTypeSelector) const pitchText = useRecoilValue(pitchTextSelector) const { addPolygonByLines } = usePolygon() + const selectedRoofMaterial = useRecoilValue(selectedRoofMaterialSelector) - const [pitch, setPitch] = useState(currentAngleType === ANGLE_TYPE.SLOPE ? 4 : 21.8) // 경사 + const [pitch, setPitch] = useState(currentAngleType === ANGLE_TYPE.SLOPE ? selectedRoofMaterial.pitch : selectedRoofMaterial.angle) // 경사 const [eavesOffset, setEavesOffset] = useState(500) // 처마출폭 const [gableOffset, setGableOffset] = useState(300) // 케라바출폭 const [sleeveOffset, setSleeveOffset] = useState(300) // 소매출폭 const [jerkinHeadWidth, setJerkinHeadWidth] = useState(800) // 반절처 폭 const [jerkinHeadPitch, setJerkinHeadPitch] = useState(currentAngleType === ANGLE_TYPE.SLOPE ? 4.5 : 20) // 반절처 경사 const [hipAndGableWidth, setHipAndGableWidth] = useState(800) // 팔작지붕 폭 - const [shedPitch, setShedPitch] = useState(currentAngleType === ANGLE_TYPE.SLOPE ? 4 : 21.8) // 팔작지붕 폭 + const [shedPitch, setShedPitch] = useState(currentAngleType === ANGLE_TYPE.SLOPE ? selectedRoofMaterial.pitch : selectedRoofMaterial.angle) // 팔작지붕 폭 const [shedWidth, setShedWidth] = useState(300) // 한쪽흐름 폭 const [hasSleeve, setHasSleeve] = useState('0') const currentObject = useRecoilValue(currentObjectState) From 77e5fa9e8ab7fda56e1e3c4814d91968347fb64b Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Tue, 18 Feb 2025 12:23:48 +0900 Subject: [PATCH 024/352] =?UTF-8?q?=EA=B0=80=EB=8C=80=20=EC=84=A4=EC=B9=98?= =?UTF-8?q?=EC=A4=91=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index bb5f8e0b..b0ad53fb 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -351,7 +351,7 @@ export default function CircuitTrestleSetting({ id }) { // apply() // apply() 결과를 체크하여 null이면 함수 종료 const applyResult = apply() - if (applyResult === null) { + if (!applyResult) { setIsGlobalLoading(false) return } From c895a14fc8228320aba4bcb0de3d5d3cd92eda81 Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 18 Feb 2025 12:35:42 +0900 Subject: [PATCH 025/352] =?UTF-8?q?#766=ED=92=88=EB=AA=85=EC=98=A4?= =?UTF-8?q?=EB=A5=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 82ee8c72..01c2bb0d 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -120,7 +120,15 @@ export default function Estimate({}) { const apiUrl = `/api/display-item/item-list?${queryStringFormatter(param)}` post({ url: apiUrl, data: param }).then((res) => { if (res.length > 0) { - setDisplayItemList(res) + let tempList + let updatedRes = [] + if (estimateContextState?.itemList.length > 0) { + tempList = estimateContextState.itemList.filter((item) => !res.some((resItem) => resItem.itemId === item.itemId)) + updatedRes = [...res, ...tempList] + } else { + updatedRes = [...res] + } + setDisplayItemList(updatedRes) } }) //견적특이사항 API호출 @@ -1776,7 +1784,7 @@ export default function Estimate({}) { onChangeDisplayItem(e.itemId, item.dispOrder, index) } }} - defaultInputValue={item.itemName} + // defaultInputValue={item.itemName} getOptionLabel={(x) => x.itemName} getOptionValue={(x) => x.itemId} isClearable={false} From 9213edb9ddc541747f719ed9c426db623df56f64 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Tue, 18 Feb 2025 15:14:57 +0900 Subject: [PATCH 026/352] =?UTF-8?q?=EB=B3=80=EB=B3=84=EB=A1=9C=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=EC=8B=9C=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/roofcover/useRoofShapeSetting.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/hooks/roofcover/useRoofShapeSetting.js b/src/hooks/roofcover/useRoofShapeSetting.js index b4909170..178f7da8 100644 --- a/src/hooks/roofcover/useRoofShapeSetting.js +++ b/src/hooks/roofcover/useRoofShapeSetting.js @@ -735,32 +735,36 @@ export function useRoofShapeSetting(id) { const index = lines.findIndex((line) => line.idx === selectedLine.idx) const nextLine = lines[index + 1] || lines[0] + history.current.push(selectedLine) if (nextLine.attributes?.isFixed) { canvas.discardActiveObject() return } - history.current.push(selectedLine) + canvas.setActiveObject(nextLine) } // 변별로 설정 내 일변 전으로 돌아가기 const handleRollBack = () => { if (history.current.length === 0) { + canvas.discardActiveObject() return } const lastLine = history.current.pop() + canvas.setActiveObject(lastLine) - currentObject.set({ + currentObject?.set({ stroke: '#000000', strokeWidth: 4, + attributes: { isFixed: false }, }) lastLine.set({ stroke: '#000000', strokeWidth: 4, + attributes: { isFixed: false }, }) - canvas.setActiveObject(lastLine) canvas.renderAll() } From 3ed4325775313f3ce3b27766de4f9f7b3a95d024 Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 18 Feb 2025 15:20:46 +0900 Subject: [PATCH 027/352] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=ED=83=AD?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=ED=83=AD=20=EC=9D=B4=EB=8F=99=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 01c2bb0d..87f2804d 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -88,8 +88,6 @@ export default function Estimate({}) { const { getMessage } = useMessage() - const { setMenuNumber } = useCanvasMenu() - const { closeAll } = usePopup() //새로 추가한 첨부파일 props @@ -101,8 +99,6 @@ export default function Estimate({}) { const initEstimate = (currPid = currentPid) => { console.log('🚀 ~ initEstimate ~ currPid:', currPid) closeAll() - setMenuNumber(5) - setObjectNo(objectRecoil.floorPlanObjectNo) setPlanNo(currPid) @@ -120,11 +116,13 @@ export default function Estimate({}) { const apiUrl = `/api/display-item/item-list?${queryStringFormatter(param)}` post({ url: apiUrl, data: param }).then((res) => { if (res.length > 0) { - let tempList + let tempList = [] let updatedRes = [] if (estimateContextState?.itemList.length > 0) { tempList = estimateContextState.itemList.filter((item) => !res.some((resItem) => resItem.itemId === item.itemId)) updatedRes = [...res, ...tempList] + // console.log('tempList::::::::', tempList) + // console.log('updatedRes::::::::', updatedRes) } else { updatedRes = [...res] } From 7af6eeb020cd800167b3d59de0a29f8b16d33e33 Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 18 Feb 2025 15:39:31 +0900 Subject: [PATCH 028/352] =?UTF-8?q?=ED=8C=9D=EC=97=85=EC=97=90=20=EB=A1=9C?= =?UTF-8?q?=EB=94=A9=EB=B0=94=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 6 ++---- src/components/estimate/popup/DocDownOptionPop.jsx | 8 +++++++- src/components/main/ChangePasswordPop.jsx | 9 ++++++++- src/components/management/popup/FindAddressPop.jsx | 9 ++++++++- src/components/management/popup/PlanRequestPop.jsx | 8 +++++++- src/components/management/popup/WindSelectPop.jsx | 9 ++++++++- src/hooks/floorPlan/estimate/useEstimateController.js | 4 ++++ 7 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 87f2804d..aedb141b 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -1,10 +1,9 @@ 'use client' import { useEffect, useState, useContext } from 'react' -import { useRecoilValue, useSetRecoilState } from 'recoil' +import { useRecoilValue } from 'recoil' import { floorPlanObjectState } from '@/store/floorPlanObjectAtom' import { useMessage } from '@/hooks/useMessage' -import { useCanvasMenu } from '@/hooks/common/useCanvasMenu' import SingleDatePicker from '../common/datepicker/SingleDatePicker' import EstimateFileUploader from './EstimateFileUploader' import { useAxios } from '@/hooks/useAxios' @@ -14,11 +13,10 @@ import dayjs from 'dayjs' import { useCommonCode } from '@/hooks/common/useCommonCode' import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController' import { SessionContext } from '@/app/SessionProvider' -import Select, { components } from 'react-select' +import Select from 'react-select' import { convertNumberToPriceDecimal, convertNumberToPriceDecimalToFixed } from '@/util/common-utils' import ProductFeaturesPop from './popup/ProductFeaturesPop' import { v4 as uuidv4 } from 'uuid' -import { correntObjectNoState } from '@/store/settingAtom' import { useSearchParams } from 'next/navigation' import { usePlan } from '@/hooks/usePlan' import { usePopup } from '@/hooks/usePopup' diff --git a/src/components/estimate/popup/DocDownOptionPop.jsx b/src/components/estimate/popup/DocDownOptionPop.jsx index 13477b63..62107a08 100644 --- a/src/components/estimate/popup/DocDownOptionPop.jsx +++ b/src/components/estimate/popup/DocDownOptionPop.jsx @@ -1,12 +1,15 @@ 'use client' -import { useState } from 'react' +import { useState, useContext } from 'react' import { useMessage } from '@/hooks/useMessage' import { useAxios } from '@/hooks/useAxios' import { useRecoilValue } from 'recoil' import { floorPlanObjectState, estimateState } from '@/store/floorPlanObjectAtom' import { usePathname, useSearchParams } from 'next/navigation' +import { QcastContext } from '@/app/QcastProvider' export default function DocDownOptionPop({ planNo, setEstimatePopupOpen, docDownPopLockFlg }) { + const { setIsGlobalLoading } = useContext(QcastContext) + const { getMessage } = useMessage() const { promisePost } = useAxios() @@ -68,8 +71,10 @@ export default function DocDownOptionPop({ planNo, setEstimatePopupOpen, docDown const options = { responseType: 'blob' } + setIsGlobalLoading(true) await promisePost({ url: url, data: params, option: options }) .then((resultData) => { + setIsGlobalLoading(false) if (resultData) { let fileName = 'unknow' const blob = new Blob([resultData.data], { type: resultData.headers['content-type'] || 'application/octet-stream' }) @@ -97,6 +102,7 @@ export default function DocDownOptionPop({ planNo, setEstimatePopupOpen, docDown } }) .catch((error) => { + setIsGlobalLoading(false) console.log('::FileDownLoad Error::', error) alert('File does not exist.') }) diff --git a/src/components/main/ChangePasswordPop.jsx b/src/components/main/ChangePasswordPop.jsx index b0d99d2c..dbc9d6e4 100644 --- a/src/components/main/ChangePasswordPop.jsx +++ b/src/components/main/ChangePasswordPop.jsx @@ -1,4 +1,4 @@ -import React from 'react' +import { useContext } from 'react' import { useMessage } from '@/hooks/useMessage' import { useForm } from 'react-hook-form' import { sessionStore } from '@/store/commonAtom' @@ -7,10 +7,13 @@ import { useAxios } from '@/hooks/useAxios' import { globalLocaleStore } from '@/store/localeAtom' import { logout, setSession, login } from '@/lib/authActions' import { useSwal } from '@/hooks/useSwal' +import { QcastContext } from '@/app/QcastProvider' export default function ChangePasswordPop(props) { const globalLocaleState = useRecoilValue(globalLocaleStore) + const { setIsGlobalLoading } = useContext(QcastContext) + const { swalFire } = useSwal() const { patch } = useAxios(globalLocaleState) const { getMessage } = useMessage() @@ -98,9 +101,11 @@ export default function ChangePasswordPop(props) { chgPwd: _password1, } + setIsGlobalLoading(true) await patch({ url: '/api/login/v1.0/user/change-password', data: param }) .then((res) => { if (res?.result?.code === 200) { + setIsGlobalLoading(false) if (res?.result?.resultCode === 'S') { swalFire({ text: getMessage('main.popup.login.success'), @@ -117,11 +122,13 @@ export default function ChangePasswordPop(props) { alert(res?.result?.resultMsg) } } else { + setIsGlobalLoading(false) logout() console.log('code not 200 error') } }) .catch((error) => { + setIsGlobalLoading(false) logout() console.log('catch::::::::', error) }) diff --git a/src/components/management/popup/FindAddressPop.jsx b/src/components/management/popup/FindAddressPop.jsx index 9deff9ad..5ed7999b 100644 --- a/src/components/management/popup/FindAddressPop.jsx +++ b/src/components/management/popup/FindAddressPop.jsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react' +import { useState, useContext } from 'react' import { useForm } from 'react-hook-form' import { queryStringFormatter } from '@/util/common-utils' import { useAxios } from '@/hooks/useAxios' @@ -8,9 +8,12 @@ import FindAddressPopQGrid from './FindAddressPopQGrid' import { useMessage } from '@/hooks/useMessage' import { isNotEmptyArray } from '@/util/common-utils' import { useSwal } from '@/hooks/useSwal' +import { QcastContext } from '@/app/QcastProvider' export default function FindAddressPop(props) { const globalLocaleState = useRecoilValue(globalLocaleStore) + const { setIsGlobalLoading } = useContext(QcastContext) + const { get } = useAxios(globalLocaleState) const { getMessage } = useMessage() @@ -61,8 +64,10 @@ export default function FindAddressPop(props) { zipcode: watch('zipNo'), } + setIsGlobalLoading(true) get({ url: `https://zipcloud.ibsnet.co.jp/api/search?${queryStringFormatter(params)}` }).then((res) => { if (res.status === 200) { + setIsGlobalLoading(false) if (isNotEmptyArray(res.results)) { setGridProps({ ...gridProps, gridData: res.results }) } else { @@ -70,10 +75,12 @@ export default function FindAddressPop(props) { setGridProps({ ...gridProps, gridData: [] }) } } else { + setIsGlobalLoading(false) swalFire({ text: getMessage('stuff.addressPopup.error.message1'), type: 'alert', icon: 'warning' }) setGridProps({ ...gridProps, gridData: [] }) } }) + setIsGlobalLoading(false) } // 주소적용 클릭 const applyAddress = () => { diff --git a/src/components/management/popup/PlanRequestPop.jsx b/src/components/management/popup/PlanRequestPop.jsx index 50b79d7f..0e37c7be 100644 --- a/src/components/management/popup/PlanRequestPop.jsx +++ b/src/components/management/popup/PlanRequestPop.jsx @@ -1,4 +1,4 @@ -import { useEffect, useState, useRef } from 'react' +import { useEffect, useState, useRef, useContext } from 'react' import { useAxios } from '@/hooks/useAxios' import { globalLocaleStore } from '@/store/localeAtom' import { useRecoilValue } from 'recoil' @@ -10,6 +10,7 @@ import PlanRequestPopQGrid from './PlanRequestPopQGrid' import { isObjectNotEmpty, queryStringFormatter } from '@/util/common-utils' import QPagination from '@/components/common/pagination/QPagination' import { useSwal } from '@/hooks/useSwal' +import { QcastContext } from '@/app/QcastProvider' export default function PlanRequestPop(props) { const [pageNo, setPageNo] = useState(1) //현재 페이지 번호 const [pageSize, setPageSize] = useState(20) //페이지 당 게시물 개수 @@ -17,6 +18,7 @@ export default function PlanRequestPop(props) { const { swalFire } = useSwal() const globalLocaleState = useRecoilValue(globalLocaleStore) + const { setIsGlobalLoading } = useContext(QcastContext) const [planReqObject, setPlanReqObject] = useState({}) const { promiseGet } = useAxios(globalLocaleState) @@ -89,8 +91,10 @@ export default function PlanRequestPop(props) { } const apiUrl = `/api/object/planReq/list?${queryStringFormatter(params)}` + setIsGlobalLoading(true) promiseGet({ url: apiUrl }).then((res) => { if (res.status === 200) { + setIsGlobalLoading(false) if (isNotEmptyArray(res.data.data)) { setGridProps({ ...gridProps, gridData: res.data.data, gridCount: res.data.data[0].totCnt }) setTotalCount(res.data.data[0].totCnt) @@ -99,10 +103,12 @@ export default function PlanRequestPop(props) { setTotalCount(0) } } else { + setIsGlobalLoading(false) setGridProps({ ...gridProps, gridData: [], gridCount: 0 }) setTotalCount(0) } }) + setIsGlobalLoading(false) } // 페이징 현재페이지 변경 const handleChangePage = (page) => { diff --git a/src/components/management/popup/WindSelectPop.jsx b/src/components/management/popup/WindSelectPop.jsx index ec4e2d55..1f8ecbb3 100644 --- a/src/components/management/popup/WindSelectPop.jsx +++ b/src/components/management/popup/WindSelectPop.jsx @@ -1,10 +1,11 @@ -import React, { useState, useEffect } from 'react' +import { useState, useEffect, useContext } from 'react' import { useMessage } from '@/hooks/useMessage' import { useAxios } from '@/hooks/useAxios' import { globalLocaleStore } from '@/store/localeAtom' import { useRecoilValue } from 'recoil' import { isEmptyArray } from '@/util/common-utils' import { useSwal } from '@/hooks/useSwal' +import { QcastContext } from '@/app/QcastProvider' export default function WindSelectPop(props) { const globalLocaleState = useRecoilValue(globalLocaleStore) @@ -13,6 +14,7 @@ export default function WindSelectPop(props) { const [windSpeed, setWindSpeed] = useState(null) const { getMessage } = useMessage() const { swalFire } = useSwal() + const { setIsGlobalLoading } = useContext(QcastContext) //선택한 라디오 값 세팅 const handleChangeRadio = (e) => { setWindSpeed(e.target.value) @@ -31,15 +33,20 @@ export default function WindSelectPop(props) { } useEffect(() => { + setIsGlobalLoading(true) if (props.prefName !== '') { promiseGet({ url: `/api/object/windSpeed/${props.prefName}/list` }).then((res) => { if (res.status === 200) { + setIsGlobalLoading(false) if (!isEmptyArray(res.data)) { setWindSpeedList(res.data) } } }) + } else { + setIsGlobalLoading(false) } + setIsGlobalLoading(false) }, [props]) return ( diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index b3c4c452..10d90416 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -445,7 +445,9 @@ export const useEstimateController = (planNo, flag) => { userId: session.userId, } + setIsGlobalLoading(true) await promisePost({ url: '/api/estimate/save-estimate-copy', data: params }).then((res) => { + setIsGlobalLoading(false) if (res.status === 201) { if (isObjectNotEmpty(res.data)) { let newObjectNo = res.data.objectNo @@ -457,6 +459,8 @@ export const useEstimateController = (planNo, flag) => { }, }) } + } else { + setIsGlobalLoading(false) } }) } From 808f497f43ed5aa11a3d2582283ea8394544837e Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Tue, 18 Feb 2025 15:40:17 +0900 Subject: [PATCH 029/352] =?UTF-8?q?=ED=9A=8C=EB=A1=9C=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=20=EC=9D=B4=ED=9B=84=20=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=95=88?= =?UTF-8?q?=EB=84=98=EC=96=B4=EA=B0=80=EB=8A=94=20=ED=98=84=EC=83=81=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useTrestle.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index 59b0ff07..ebbfd7cf 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -27,7 +27,7 @@ export const useTrestle = () => { if (notAllocationModules.length > 0) { swalFire({ text: '回路番号が設定されていないモジュールがあります。 番号を設定しなおすか、 パネルを削除してください。', icon: 'error' }) setIsGlobalLoading(false) - return null + return } try { //처마력바가 체크되어 있는 경우 exposedBottomPoints를 이용해 처마력바 그려줘야함. @@ -598,13 +598,14 @@ export const useTrestle = () => { surface.set({ quotationParam, isComplete: true }) }) + return true } catch (e) { // 에러 발생시 가대 초기화 console.error(e) // clear() setViewCircuitNumberTexts(true) setIsGlobalLoading(false) - return null + return false } } From 1b54c06217f62cbfd8351dfd9d14b582a0d6e356 Mon Sep 17 00:00:00 2001 From: LEEYONGJAE Date: Tue, 18 Feb 2025 15:42:57 +0900 Subject: [PATCH 030/352] =?UTF-8?q?=EB=B0=9C=EC=A0=84=EC=8B=9C=EB=AE=AC?= =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=85=98=20=ED=83=AD=20=EC=9D=B4=EB=8F=99=20?= =?UTF-8?q?=EB=A9=94=EB=89=B4=EB=84=98=EB=B2=84=20=EC=85=8B=ED=8C=85=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/simulator/Simulator.jsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/components/simulator/Simulator.jsx b/src/components/simulator/Simulator.jsx index f7f09969..6683ff9e 100644 --- a/src/components/simulator/Simulator.jsx +++ b/src/components/simulator/Simulator.jsx @@ -12,11 +12,10 @@ import { pwrGnrSimTypeState } from '@/store/simulatorAtom' import { useAxios } from '@/hooks/useAxios' import { useMessage } from '@/hooks/useMessage' -import { useCanvasMenu } from '@/hooks/common/useCanvasMenu' import { convertNumberToPriceDecimal } from '@/util/common-utils' import { usePlan } from '@/hooks/usePlan' -import { usePopup, closeAll } from '@/hooks/usePopup' +import { usePopup } from '@/hooks/usePopup' import { QcastContext } from '@/app/QcastProvider' @@ -31,7 +30,6 @@ export default function Simulator() { const chartRef = useRef(null) // 캔버스 메뉴 넘버 셋팅 - const { setMenuNumber } = useCanvasMenu() const { closeAll } = usePopup() const { get } = useAxios() @@ -120,7 +118,6 @@ export default function Simulator() { fetchSimulatorNotice() setPwrGnrSimType('D') setPwrRecoil({ ...pwrRecoil, type: 'D' }) - setMenuNumber(6) closeAll() } }, [objectNo, pid, selectedPlan]) From 87353d4238b281e84e9359945b216703ae7bfee1 Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 18 Feb 2025 15:58:58 +0900 Subject: [PATCH 031/352] =?UTF-8?q?=EC=88=98=EC=A7=81=EC=A0=81=EC=84=A4?= =?UTF-8?q?=EB=9F=89=20=EC=B2=B4=ED=81=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/management/StuffDetail.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index 0b722f35..748de71c 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -1376,7 +1376,7 @@ export default function StuffDetail() { } if (params?.receiveUser !== '') { - if (params?.receiveUser.trim().length > 10) { + if (checkLength(params?.receiveUser.trim()) > 10) { return swalFire({ text: getMessage('stuff.detail.tempSave.message2'), type: 'alert', icon: 'warning' }) } } From e4916b1a066fb6db70e2697c2bcb6b74ef72c1a1 Mon Sep 17 00:00:00 2001 From: changkyu choi Date: Tue, 18 Feb 2025 16:47:48 +0900 Subject: [PATCH 032/352] =?UTF-8?q?floor-plan=20=EC=B4=88=EA=B8=B0=20?= =?UTF-8?q?=EC=A7=84=EC=9E=85=20=EC=8B=9C=20=EB=B0=B0=EC=B9=98=EB=A9=B4?= =?UTF-8?q?=EC=B4=88=EA=B8=B0=EC=84=A4=EC=A0=95=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EB=A1=9C=EB=93=9C=20=EC=98=A4=EB=A5=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasFrame.jsx | 10 ++++ src/components/floor-plan/CanvasMenu.jsx | 2 +- .../placementShape/PlacementShapeSetting.jsx | 5 +- src/hooks/option/useCanvasSetting.js | 47 +++++++++---------- .../roofcover/useRoofAllocationSetting.js | 9 +--- src/hooks/usePlan.js | 7 ++- 6 files changed, 39 insertions(+), 41 deletions(-) diff --git a/src/components/floor-plan/CanvasFrame.jsx b/src/components/floor-plan/CanvasFrame.jsx index f5ecb10d..6f0ac28c 100644 --- a/src/components/floor-plan/CanvasFrame.jsx +++ b/src/components/floor-plan/CanvasFrame.jsx @@ -26,6 +26,7 @@ import { seriesState, } from '@/store/circuitTrestleAtom' import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController' +import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' export default function CanvasFrame() { const canvasRef = useRef(null) @@ -45,6 +46,7 @@ export default function CanvasFrame() { const resetSelectedModelsState = useResetRecoilState(selectedModelsState) const resetPcsCheckState = useResetRecoilState(pcsCheckState) const { handleModuleSelectionTotal } = useCanvasPopupStatusController() + const { fetchBasicSettings } = useCanvasSetting() const loadCanvas = () => { if (!canvas) return @@ -66,6 +68,14 @@ export default function CanvasFrame() { loadCanvas() resetRecoilData() Object.keys(currentCanvasPlan).length > 0 && handleModuleSelectionTotal() + + /* 플랜번호가 있으면 베이직세팅 팝업 데이터 로드 */ + if (currentCanvasPlan.planNo) { + /* 약간의 지연을 줘서 roofMaterials가 로드될 시간을 확보 */ + setTimeout(() => { + fetchBasicSettings(Number(currentCanvasPlan.planNo), null) + }, 100) + } }, [currentCanvasPlan, canvas]) useEffect(() => { diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 2210b157..59f2b673 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -330,7 +330,7 @@ export default function CanvasMenu(props) { y: 180, }, planNo: selectedPlan?.planNo ? selectedPlan.planNo : pid, - openPiont: 'canvasMenus', + openPoint: 'canvasMenus', } /** * 배치면 초기설정 팝업 열기 diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx index a4162264..9f8c54b2 100644 --- a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx @@ -21,7 +21,7 @@ export const ROOF_MATERIAL_LAYOUT = { PARALLEL: 'P', STAIRS: 'S', } -export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, planNo, openPiont }) { +export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, planNo, openPoint }) { const [showSizeGuideModal, setShowSizeGuidModal] = useState(false) const [showMaterialGuideModal, setShowMaterialGuidModal] = useState(false) const { closePopup } = usePopup() @@ -93,11 +93,10 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla } useEffect(() => { - console.log('🚀 ~ useEffect ~ planNo:', planNo, openPiont) /** * 메뉴에서 배치면초기설정 선택 시 조회 */ - if (openPiont && openPiont === 'canvasMenus') fetchBasicSettings(planNo, openPiont) + if (openPoint && openPoint === 'canvasMenus') fetchBasicSettings(planNo, openPoint) }, []) useEffect(() => { diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js index 78f8beb5..5df718ec 100644 --- a/src/hooks/option/useCanvasSetting.js +++ b/src/hooks/option/useCanvasSetting.js @@ -188,11 +188,6 @@ export function useCanvasSetting() { setBasicSettings({ ...basicSetting, selectedRoofMaterial: selectedRoofMaterial }) } - // // ObjectNo 최초 데이터 설정 확인 - // const previousObjectNoRef = useRef(null) - // // 지붕재 정보 최초 데이터 설정 확인 - // const previousRoofMaterialsRef = useRef(null) - // useEffect(() => { // // 지붕재 select 정보가 존재해야 배치면초기설정 DB 정보 비교 후 지붕재 정보를 가져올 수 있음 // if ( @@ -334,11 +329,15 @@ export function useCanvasSetting() { /** * 기본설정(PlacementShapeSetting) 조회 및 초기화 */ - const fetchBasicSettings = async (planNo, openPiont) => { + const fetchBasicSettings = async (planNo, openPoint) => { + /* roofMaterials가 로드될 때까지 대기 */ + if (!roofMaterials || roofMaterials.length === 0) { + console.log('Waiting for roofMaterials to load...') + return + } + try { await get({ - //url: `/api/canvas-management/canvas-basic-settings/by-object?objectNo=${correntObjectNo}&planNo=${pid}`, - // url: `http://localhost:8080/api/canvas-management/canvas-basic-settings/by-object/${correntObjectNo}/${planNo}`, url: `/api/canvas-management/canvas-basic-settings/by-object/${correntObjectNo}/${planNo}`, }).then((res) => { let roofsRow = {} @@ -393,7 +392,7 @@ export function useCanvasSetting() { ] /* 메뉴에서 배치면 초기설정 클릭 시 실행하지 않음 */ - if (openPiont === null) { + if (openPoint === null) { /* 배치면 초기설정 미저장 상태이면 화면 열기 */ const placementInitialProps = { id: popupId, @@ -402,7 +401,7 @@ export function useCanvasSetting() { y: 180, }, planNo: planNo, - openPiont: 'useCanvasSetting', + openPoint: 'useCanvasSetting', } addPopup(popupId, 1, ) } @@ -431,16 +430,19 @@ export function useCanvasSetting() { } }) } - setAddedRoofs(addRoofs) - setBasicSettings({ - ...basicSetting, - roofMaterials: addRoofs[0], - planNo: roofsRow[0].planNo, - roofSizeSet: roofsRow[0].roofSizeSet, - roofAngleSet: roofsRow[0].roofAngleSet, - roofsData: roofsArray, - selectedRoofMaterial: addRoofs.find((roof) => roof.selected), - }) + + if (addRoofs.length > 0) { + setAddedRoofs(addRoofs) + setBasicSettings({ + ...basicSetting, + roofMaterials: addRoofs[0], + planNo: roofsRow[0].planNo, + roofSizeSet: roofsRow[0].roofSizeSet, + roofAngleSet: roofsRow[0].roofAngleSet, + roofsData: roofsArray, + selectedRoofMaterial: addRoofs.find((roof) => roof.selected), + }) + } }) } catch (error) { console.error('Data fetching error:', error) @@ -478,8 +480,6 @@ export function useCanvasSetting() { ], } - //await post({ url: `/api/canvas-management/canvas-basic-settings`, data: patternData }) - // await post({ url: `http://localhost:8080/api/canvas-management/canvas-basic-settings`, data: patternData }).then((res) => { await post({ url: `/api/canvas-management/canvas-basic-settings`, data: patternData }).then((res) => { swalFire({ text: getMessage(res.returnMessage) }) /* 배치면초기설정 조회 */ @@ -521,7 +521,6 @@ export function useCanvasSetting() { const fetchSettings = async () => { try { const res = await get({ url: `/api/canvas-management/canvas-settings/by-object/${correntObjectNo}` }) - console.log('res', res) if (Object.keys(res).length > 0) { const optionData1 = settingModalFirstOptions.option1.map((item) => ({ ...item, selected: res[item.column] })) @@ -629,7 +628,6 @@ export function useCanvasSetting() { } setDotLineGridSettingState(patternData) - //setCurrentSetting(patternData) /** * 그리드 색 설정 @@ -668,7 +666,6 @@ export function useCanvasSetting() { * 점/선 그리드 */ setDotLineGridSettingState({ ...defaultDotLineGridSetting }) - //setCurrentSetting({ ...defaultDotLineGridSetting }) /** * 그리드 색 설정 diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js index 7bfee7ba..bf2756ec 100644 --- a/src/hooks/roofcover/useRoofAllocationSetting.js +++ b/src/hooks/roofcover/useRoofAllocationSetting.js @@ -106,14 +106,11 @@ export function useRoofAllocationSetting(id) { /** * 지붕면 할당 조회 및 초기화 */ - const fetchBasicSettings = async (planNo, openPiont) => { + const fetchBasicSettings = async (planNo, openPoint) => { try { await get({ - //url: `/api/canvas-management/canvas-basic-settings/by-object/objectNo=${correntObjectNo}/planNo=${currentCanvasPlan.planNo}`, - // url: `http://localhost:8080/api/canvas-management/canvas-basic-settings/by-object/${correntObjectNo}/${planNo}`, url: `/api/canvas-management/canvas-basic-settings/by-object/${correntObjectNo}/${planNo}`, }).then((res) => { - console.log('🚀 ~ useRoofAllocationSetting ~ fetchBasicSettings ~ res >>>>>>>>>>>>>>>>>>>>> :', res) let roofsArray = {} if (res.length > 0) { @@ -219,11 +216,7 @@ export function useRoofAllocationSetting(id) { })), } - console.log('🚀 ~ basicSettingSave ~ patternData >>>>>>>>>>>>> :', patternData) - - // await post({ url: `http://localhost:8080/api/canvas-management/roof-allocation-settings`, data: patternData }).then((res) => { await post({ url: `/api/canvas-management/roof-allocation-settings`, data: patternData }).then((res) => { - console.log('roof-allocation-settings res ', res) swalFire({ text: getMessage(res.returnMessage) }) }) diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js index 21e391f2..40b2b29e 100644 --- a/src/hooks/usePlan.js +++ b/src/hooks/usePlan.js @@ -274,9 +274,6 @@ export function usePlan(params = {}) { const planNo = plans?.find((obj) => obj.id === newCurrentId).planNo const objectNo = floorPlanState.objectNo - /* 플랜 이동 시 배치면초기설정 정보 조회 */ - fetchBasicSettings(planNo, null) - //견적서 or 발전시뮬 if (pathname !== '/floor-plan') { @@ -307,6 +304,9 @@ export function usePlan(params = {}) { // 클릭한 플랜 탭으로 이동 setCurrentCanvasPlan(plans.find((plan) => plan.id === newCurrentId)) setPlans((plans) => plans.map((plan) => ({ ...plan, isCurrent: plan.id === newCurrentId }))) + + /* 플랜 이동 시 배치면초기설정 정보 조회 (견적서 메뉴 제외) */ + fetchBasicSettings(planNo, null) } else { swalFire({ text: getMessage('estimate.menu.move.valid1') }) } @@ -494,7 +494,6 @@ export function usePlan(params = {}) { * @param {string} planNo - 플랜번호 */ const deleteBasicSettings = async (objectNo, planNo) => { - // await promiseDel({ url: `http://localhost:8080/api/canvas-management/delete-basic-settings/${objectNo}/${planNo}` }) await promiseDel({ url: `/api/canvas-management/delete-basic-settings/${objectNo}/${planNo}` }) } From 16a44296db3ba22e1926d5770d1c7e1e48d09f12 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Tue, 18 Feb 2025 17:09:02 +0900 Subject: [PATCH 033/352] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=95=84?= =?UTF-8?q?=EC=9D=B4=ED=85=9C=20=EC=A1=B0=ED=9A=8C=20=EC=8B=9C=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index b0ad53fb..a7f26838 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -364,6 +364,8 @@ export default function CircuitTrestleSetting({ id }) { await saveCanvas(false) // 견적서 저장 await saveEstimate(result) + } else { + setIsGlobalLoading(false) } // removeNotAllocationModules() } From 724002f7b8bbe67d23fd44c308e3e4947b840d5c Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Tue, 18 Feb 2025 17:46:09 +0900 Subject: [PATCH 034/352] =?UTF-8?q?=EC=A7=80=EB=B6=95=EC=9E=AC=EC=84=A0?= =?UTF-8?q?=ED=83=9D=20=ED=8C=9D=EC=97=85=20=EB=82=B4=EC=9A=A9=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx b/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx index 83310c2e..f74ef018 100644 --- a/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx +++ b/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx @@ -25,6 +25,7 @@ export default function RoofAllocationSetting(props) { onAddRoofMaterial, onDeleteRoofMaterial, roofMaterials, + currentRoofMaterial, setCurrentRoofMaterial, roofList, handleDefaultRoofMaterial, @@ -67,7 +68,7 @@ export default function RoofAllocationSetting(props) { options={roofMaterials.map((roof) => { return { ...roof, name: globalLocale === 'ko' ? roof.roofMatlNm : roof.roofMatlNmJp } })} - value={roofMaterials[0]} + value={currentRoofMaterial} onChange={(e) => { // const selected = roofMaterials.find((roofMaterial) => roofMaterial.roofMatlCd === e.id) setCurrentRoofMaterial(e) From 9c0c74128757bea24ec14d28808e4f04a374488b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Tue, 18 Feb 2025 18:18:50 +0900 Subject: [PATCH 035/352] =?UTF-8?q?=EB=A9=B4=ED=98=95=EC=83=81=20=EB=B0=B0?= =?UTF-8?q?=EC=B9=98=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../placementSurface/PlacementSurface.jsx | 47 +++++++++++++------ .../PlacementSurfaceSetting.jsx | 6 +-- src/hooks/surface/useSurfaceShapeBatch.js | 31 ++++++++++-- 3 files changed, 64 insertions(+), 20 deletions(-) diff --git a/src/components/floor-plan/modal/placementSurface/PlacementSurface.jsx b/src/components/floor-plan/modal/placementSurface/PlacementSurface.jsx index c06386b5..a4722bff 100644 --- a/src/components/floor-plan/modal/placementSurface/PlacementSurface.jsx +++ b/src/components/floor-plan/modal/placementSurface/PlacementSurface.jsx @@ -11,23 +11,42 @@ const PlacementSurface = forwardRef((props, refs) => { const num = ['①', '②', '③', '④', '⑤'] const getImageUrl = () => { + // re_는 normal의 y축 대칭 이미지 + const imageName = id < 10 ? '0' + id : id + let imageRotate = 0 if (xInversion && !yInversion) { - return `/static/images/canvas/shape/re_${rotate % 4 !== 0 ? Math.abs(rotate % 4) * 90 + 'deg' : 'normal'}/plane_tab${id < 10 ? '0' + id : id}.svg` + if (rotate % 2 === 0 || rotate < 0) { + imageRotate = Math.abs(rotate % 4) + } else { + if (rotate < 0) { + imageRotate = Math.abs((rotate - 2) % 4) + } else { + imageRotate = Math.abs((rotate + 2) % 4) + } + } + } else if (xInversion && yInversion) { + imageRotate = Math.abs((rotate + 4) % 4) + } else if (xInversion !== yInversion && rotate < 0) { + imageRotate = Math.abs(rotate) + } else if (!xInversion && yInversion) { + if (rotate % 2 === 0 || rotate < 0) { + imageRotate = Math.abs(rotate % 4) + } else { + if (rotate < 0) { + imageRotate = Math.abs((rotate + 2) % 4) + } else { + imageRotate = Math.abs((rotate - 2) % 4) + } + } + } else { + imageRotate = (rotate + 4) % 4 } - - if (!xInversion && yInversion) { - return `/static/images/canvas/shape/re_${rotate % 4 !== 0 ? Math.abs(rotate % 4) * 90 + 'deg' : 'normal'}/plane_tab${id < 10 ? '0' + id : id}.svg` + const rotateType = imageRotate % 4 !== 0 ? (imageRotate % 4) * 90 + 'deg' : 'normal' + if (xInversion !== yInversion) { + return `/static/images/canvas/shape/re_${rotateType}/plane_tab${imageName}.svg` + } else { + return `/static/images/canvas/shape/${rotateType}/plane_tab${imageName}.svg` } - - if (xInversion && yInversion) { - return `/static/images/canvas/shape/${rotate % 4 !== 0 ? Math.abs(rotate % 4) * 90 + 'deg' : 'normal'}/plane_tab${id < 10 ? '0' + id : id}.svg` - } - - if (rotate < 0) { - return `/static/images/canvas/shape/${rotate !== 0 ? Math.abs((rotate + 4) * 90) + 'deg' : 'normal'}/plane_tab${id < 10 ? '0' + id : id}.svg` - } - - return `/static/images/canvas/shape/${rotate !== 0 ? Math.abs(rotate * 90) + 'deg' : 'normal'}/plane_tab${id < 10 ? '0' + id : id}.svg` } const azimuthButton = (direction, e) => { diff --git a/src/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting.jsx b/src/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting.jsx index 58ab430a..967d849e 100644 --- a/src/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting.jsx +++ b/src/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting.jsx @@ -239,12 +239,11 @@ export default function PlacementSurfaceSetting({ id, pos = { x: 50, y: 230 } }) applySurfaceShape(surfaceRefs, selectedType, id) } - const handleRotate = () => {} - const handleInversion = (type) => { if (type === 'x') { + const x = xInversion setXInversion(!xInversion) - setRotate(xInversion ? rotate + 2 : rotate - 2) + setRotate(x ? rotate + 2 : rotate - 2) // setXInversion(!xInversion) } else if (type === 'y') { // setRotate(rotate + 2) @@ -295,6 +294,7 @@ export default function PlacementSurfaceSetting({ id, pos = { x: 50, y: 230 } })
+ {/* */} {/* */} diff --git a/src/hooks/surface/useSurfaceShapeBatch.js b/src/hooks/surface/useSurfaceShapeBatch.js index 298ef982..6f7d1dfa 100644 --- a/src/hooks/surface/useSurfaceShapeBatch.js +++ b/src/hooks/surface/useSurfaceShapeBatch.js @@ -101,15 +101,40 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { lockScalingX: true, // X 축 크기 조정 잠금 lockScalingY: true, // Y 축 크기 조정 잠금 name: MENU.BATCH_CANVAS.SURFACE_SHAPE_BATCH_TEMP, - flipX: xInversion !== yInversion ? yInversion : false, - flipY: xInversion !== yInversion ? xInversion : false, - angle: xInversion && yInversion ? Math.abs((rotate + 180) % 360) : Math.abs(rotate), + flipX: xInversion !== yInversion, + // angle: xInversion && yInversion ? Math.abs((rotate + 180) % 360) : Math.abs(rotate), + // angle: rotate, originX: 'center', originY: 'center', pitch: globalPitch, } obj = new QPolygon(points, options) + let imageRotate = 0 + if (xInversion && !yInversion) { + if (rotate % 180 === 0 || rotate < 0) { + imageRotate = Math.abs(rotate % 360) + } else { + imageRotate = Math.abs((rotate - 180) % 4) + } + } else if (xInversion && yInversion) { + imageRotate = Math.abs((rotate + 360) % 360) + } else if (xInversion !== yInversion && rotate < 0) { + imageRotate = Math.abs(rotate) + } else if (!xInversion && yInversion) { + if (rotate % 180 === 0 || rotate < 0) { + imageRotate = Math.abs(rotate % 360) + } else { + if (rotate < 0) { + imageRotate = Math.abs((rotate + 180) % 360) + } else { + imageRotate = Math.abs((rotate - 180) % 360) + } + } + } else { + imageRotate = (rotate + 360) % 360 + } + obj.set({ angle: imageRotate }) obj.setCoords() //좌표 변경 적용 canvas?.add(obj) From 0f56016daa8a7be47cd5dab7a453fd4dc82f8986 Mon Sep 17 00:00:00 2001 From: basssy Date: Wed, 19 Feb 2025 09:15:53 +0900 Subject: [PATCH 036/352] =?UTF-8?q?=EB=AC=BC=EA=B1=B4=EC=83=81=EC=84=B8&?= =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EB=AC=B8=EC=84=9C=EB=8B=A4?= =?UTF-8?q?=EC=9A=B4=EB=A1=9C=EB=93=9C=20=ED=8C=9D=EC=97=85=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=EB=85=B8=EC=B6=9C=EC=A1=B0=EA=B1=B4=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 20 +++++++++----------- src/components/management/StuffDetail.jsx | 9 ++++----- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 59f2b673..0b0f4b2d 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -435,21 +435,16 @@ export default function CanvasMenu(props) { useEffect(() => { if (isObjectNotEmpty(estimateContextState)) { - const { createUser, tempFlg, lockFlg } = estimateContextState - + const { createUser, tempFlg, lockFlg, docNo } = estimateContextState if (createUser && tempFlg && lockFlg) { - if (createUser === 'T01') { - if (sessionState.storeId !== 'T01') { - setAllButtonStyles('none') - } else { - handleButtonStyles(tempFlg, lockFlg) - } + if (createUser === 'T01' && sessionState.storeId !== 'T01') { + setAllButtonStyles('none') } else { - handleButtonStyles(tempFlg, lockFlg) + handleButtonStyles(tempFlg, lockFlg, docNo) } } } - }, [estimateContextState?.createUser, estimateContextState?.tempFlg, estimateContextState?.lockFlg]) + }, [estimateContextState?.createUser, estimateContextState?.tempFlg, estimateContextState?.lockFlg, estimateContextState.docNo]) const setAllButtonStyles = (style) => { setButtonStyle1(style) @@ -459,7 +454,7 @@ export default function CanvasMenu(props) { setButtonStyle5(style) } - const handleButtonStyles = (tempFlg, lockFlg) => { + const handleButtonStyles = (tempFlg, lockFlg, docNo) => { if (tempFlg === '1') { setAllButtonStyles('none') setButtonStyle2('') @@ -472,6 +467,9 @@ export default function CanvasMenu(props) { setButtonStyle4('') setButtonStyle5('') } + if (!docNo) { + setButtonStyle1('none') + } } /** diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index 748de71c..078873d3 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -291,15 +291,14 @@ export default function StuffDetail() { buttonStyle = 'none' buttonStyle2 = 'none' } else { - if (params?.data?.createSaleStoreId === 'T01') { - if (session?.storeId !== 'T01') { - buttonStyle = 'none' - } + if (params?.data?.createSaleStoreId === 'T01' && session?.storeId !== 'T01') { + buttonStyle = 'none' } - if (params?.data?.tempFlg === '1') { + if (params?.data?.tempFlg === '1' || !params?.data?.docNo) { buttonStyle2 = 'none' } } + return ( <>
From 5777a550a3d5f8cc1f37197ce6d4e13757627cc0 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Wed, 19 Feb 2025 09:45:34 +0900 Subject: [PATCH 037/352] =?UTF-8?q?=F0=9F=93=8Cfix:=20production=20?= =?UTF-8?q?=ED=99=98=EA=B2=BD=20=EA=B8=B0=EB=8F=99=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=A6=BD=ED=8A=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- startscript.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/startscript.js b/startscript.js index 37f52696..350b2c06 100644 --- a/startscript.js +++ b/startscript.js @@ -1,2 +1,2 @@ var exec = require('child_process').exec -exec('yarn start', { windowsHide: true }) +exec('yarn serve', { windowsHide: true }) From a731dc7dd44e1d9ff083fbabcfee31da77c86b66 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Wed, 19 Feb 2025 10:25:32 +0900 Subject: [PATCH 038/352] =?UTF-8?q?=F0=9F=93=8Cfix:=20=EB=B0=B0=EC=B9=98?= =?UTF-8?q?=EB=A9=B4=20=EB=A9=94=EB=89=B4=20=EC=9D=B4=EB=8F=99=EC=8B=9C=20?= =?UTF-8?q?=EC=B2=B4=ED=81=AC=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - confirm 창 띄우기 전 동작 금지 --- src/components/floor-plan/CanvasMenu.jsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 0b0f4b2d..2d4a323b 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -171,8 +171,6 @@ export default function CanvasMenu(props) { await reloadCanvasStatus(objectNo, pid) break case 3: - console.log('🚀 ~ onClickNav ~ menu:', menu) - console.log('🚀 ~ onClickNav ~ menuNumber:', menuNumber) if (menuNumber > menu.index) { const modules = canvas.getObjects().filter((module) => module.name === POLYGON_TYPE.MODULE) if (modules.length > 0) { @@ -199,6 +197,7 @@ export default function CanvasMenu(props) { return }, }) + return } else { setType('surface') } From 8b9a2a122c372e3b2ae1bc788e4eacd85d597fdc Mon Sep 17 00:00:00 2001 From: basssy Date: Wed, 19 Feb 2025 10:53:22 +0900 Subject: [PATCH 039/352] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=ED=83=AD?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EA=B2=AC=EC=A0=81=EC=84=9C=20=ED=83=AD=20?= =?UTF-8?q?=EB=8B=A4=EC=8B=9C=20=EB=88=8C=EB=A0=80=EC=9D=84=EB=95=8C=20?= =?UTF-8?q?=EB=A1=9C=EB=94=A9=EB=B0=94false?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 4 +--- src/components/management/StuffSubHeader.jsx | 9 +++------ 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 2d4a323b..21c7bedf 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -220,16 +220,14 @@ export default function CanvasMenu(props) { await reloadCanvasStatus(objectNo, pid) break case 5: - setIsGlobalLoading(true) - //로딩바해제는 견적서 상세조회쪽(useEstimateController.js)에서 setIsGlobalLoading(false) promiseGet({ url: `/api/estimate/${objectNo}/${selectedPlan.planNo}/detail` }).then((res) => { if (res.status === 200) { const estimateDetail = res.data - // if (estimateDetail.tempFlg === '0' && estimateDetail.estimateDate !== null) { if (estimateDetail.estimateDate !== null) { setMenuNumber(menu.index) setCurrentMenu(menu.title) setFloorPlanObjectNo({ floorPlanObjectNo: objectNo }) + setIsGlobalLoading(false) router.push(`/floor-plan/estimate/${menu.index}?pid=${selectedPlan.planNo}&objectNo=${objectNo}`) } else { setIsGlobalLoading(false) diff --git a/src/components/management/StuffSubHeader.jsx b/src/components/management/StuffSubHeader.jsx index bb6f48b9..368926a2 100644 --- a/src/components/management/StuffSubHeader.jsx +++ b/src/components/management/StuffSubHeader.jsx @@ -8,7 +8,6 @@ import { useRouter, useSearchParams } from 'next/navigation' import { useSetRecoilState } from 'recoil' -import { QcastContext } from '@/app/QcastProvider' import { useMessage } from '@/hooks/useMessage' import { floorPlanObjectState } from '@/store/floorPlanObjectAtom' import { isObjectNotEmpty, queryStringFormatter } from '@/util/common-utils' @@ -24,8 +23,6 @@ export default function StuffSubHeader({ type }) { const setFloorPlanObjectNo = useSetRecoilState(floorPlanObjectState) - const { isGlobalLoading } = useContext(QcastContext) - const { managementState } = useContext(GlobalDataContext) const [buttonStyle, setButtonStyle] = useState('') @@ -70,7 +67,7 @@ export default function StuffSubHeader({ type }) {
{type === 'list' && ( <> - +

{getMessage('header.menus.management')}

    @@ -92,7 +89,7 @@ export default function StuffSubHeader({ type }) { <>
    • - + {getMessage('stuff.temp.subTitle')}
    • @@ -116,7 +113,7 @@ export default function StuffSubHeader({ type }) { <>
      • - + {getMessage('stuff.temp.subTitle')}
      • From a69d2879f39ecddcaac657894c3a592c434d4010 Mon Sep 17 00:00:00 2001 From: basssy Date: Wed, 19 Feb 2025 12:07:00 +0900 Subject: [PATCH 040/352] =?UTF-8?q?=EB=8F=84=EB=A9=B4=EC=9E=91=EC=84=B1=20?= =?UTF-8?q?=ED=9B=84=20=EA=B2=AC=EC=A0=81=EC=84=9C=20=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?=EB=A9=94=EB=89=B4=ED=83=AD=EB=8F=84=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index aedb141b..6451498d 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -22,7 +22,7 @@ import { usePlan } from '@/hooks/usePlan' import { usePopup } from '@/hooks/usePopup' import { useSwal } from '@/hooks/useSwal' import { QcastContext } from '@/app/QcastProvider' - +import { useCanvasMenu } from '@/hooks/common/useCanvasMenu' export default function Estimate({}) { const [uniqueData, setUniqueData] = useState([]) const [handlePricingFlag, setHandlePricingFlag] = useState(false) @@ -87,7 +87,7 @@ export default function Estimate({}) { const { getMessage } = useMessage() const { closeAll } = usePopup() - + const { setMenuNumber } = useCanvasMenu() //새로 추가한 첨부파일 props const fileUploadProps = { uploadFiles: files, @@ -119,8 +119,6 @@ export default function Estimate({}) { if (estimateContextState?.itemList.length > 0) { tempList = estimateContextState.itemList.filter((item) => !res.some((resItem) => resItem.itemId === item.itemId)) updatedRes = [...res, ...tempList] - // console.log('tempList::::::::', tempList) - // console.log('updatedRes::::::::', updatedRes) } else { updatedRes = [...res] } @@ -144,6 +142,7 @@ export default function Estimate({}) { }, [selectedPlan]) useEffect(() => { + setMenuNumber(5) initEstimate() }, []) From 1e3ad6a2917363725330f5f55e76f41e3b5e89a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 19 Feb 2025 13:15:58 +0900 Subject: [PATCH 041/352] =?UTF-8?q?=EC=A7=80=EB=B6=95=EB=A9=B4=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=EC=8B=9C=20=EC=A7=91=EA=B3=84=ED=91=9C=20=EB=B0=98?= =?UTF-8?q?=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleSelection.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/hooks/module/useModuleSelection.js b/src/hooks/module/useModuleSelection.js index 26bac8e8..23c201b0 100644 --- a/src/hooks/module/useModuleSelection.js +++ b/src/hooks/module/useModuleSelection.js @@ -1,4 +1,4 @@ -import { useRecoilState, useRecoilValue } from 'recoil' +import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil' import { useContext, useEffect, useState } from 'react' import { GlobalDataContext } from '@/app/GlobalDataProvider' import { useMasterController } from '@/hooks/common/useMasterController' @@ -7,6 +7,7 @@ import { selectedModuleState, moduleSelectionInitParamsState, moduleSelectionDat import { isObjectNotEmpty } from '@/util/common-utils' import { canvasState } from '@/store/canvasAtom' import { POLYGON_TYPE } from '@/common/common' +import { moduleStatisticsState } from '@/store/circuitTrestleAtom' export function useModuleSelection(props) { const canvas = useRecoilValue(canvasState) @@ -25,6 +26,7 @@ export function useModuleSelection(props) { const [moduleSelectionInitParams, setModuleSelectionInitParams] = useRecoilState(moduleSelectionInitParamsState) //모듈 기본 데이터 ex) 면조도, 높이등등 const { getModuleTypeItemList } = useMasterController() const { findCommonCode } = useCommonCode() + const resetStatisticsData = useResetRecoilState(moduleStatisticsState) const bindInitData = () => { setInstallHeight(managementState?.installHeight) @@ -98,6 +100,7 @@ export function useModuleSelection(props) { canvas.remove(moduleSurface) }) canvas.renderAll() + resetStatisticsData() } }, []) From fefddac1a9782e54f32ba59a9cafc9d9193927ef Mon Sep 17 00:00:00 2001 From: changkyu choi Date: Wed, 19 Feb 2025 13:21:25 +0900 Subject: [PATCH 042/352] =?UTF-8?q?roofMaterials=EA=B0=80=20=EB=A1=9C?= =?UTF-8?q?=EB=93=9C=20=ED=9B=84=20=EC=8B=A4=ED=96=89=20=EB=B0=B0=EC=B9=98?= =?UTF-8?q?=EB=A9=B4=EC=B4=88=EA=B8=B0=EC=84=A4=EC=A0=95=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EC=B2=98=EB=A6=AC=20=EB=B0=8F=20setCanvasSetting?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/option/useCanvasSetting.js | 77 ++++++++++++++++------------ 1 file changed, 45 insertions(+), 32 deletions(-) diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js index 5df718ec..08ac6470 100644 --- a/src/hooks/option/useCanvasSetting.js +++ b/src/hooks/option/useCanvasSetting.js @@ -140,8 +140,7 @@ export function useCanvasSetting() { const selectedRoofMaterial = useRecoilValue(selectedRoofMaterialSelector) // 선택된 지붕재 정보 const { floorPlanState } = useContext(FloorPlanContext) // 플랜 상태 const { closeAll } = usePopup() // 팝업 닫기 - // const previousObjectNoRef = useRef(null) // 최초 데이터 설정 확인 - // const previousRoofMaterialsRef = useRef(null) // 최초 데이터 설정 확인 + const [isRoofMaterialsLoaded, setIsRoofMaterialsLoaded] = useState(false) // roofMaterials 로드 상태 확인 useEffect(() => { const tempFetchRoofMaterials = !fetchRoofMaterials @@ -153,6 +152,15 @@ export function useCanvasSetting() { } }, []) + /** + * roofMaterials가 변경될 때마다 로드 상태 업데이트 + */ + useEffect(() => { + if (roofMaterials.length > 0) { + setIsRoofMaterialsLoaded(true) + } + }, [roofMaterials]) + /** * 지붕재 초기세팅 */ @@ -188,26 +196,6 @@ export function useCanvasSetting() { setBasicSettings({ ...basicSetting, selectedRoofMaterial: selectedRoofMaterial }) } - // useEffect(() => { - // // 지붕재 select 정보가 존재해야 배치면초기설정 DB 정보 비교 후 지붕재 정보를 가져올 수 있음 - // if ( - // (!previousObjectNoRef.current && !correntObjectNo && previousObjectNoRef.current !== correntObjectNo) || - // (roofMaterials.length !== 0 && JSON.stringify(previousRoofMaterialsRef.current) !== JSON.stringify(roofMaterials)) - // ) { - // // 1회만 실행 - // if (roofMaterials && previousRoofMaterialsYn === 'N') { - // if (correntObjectNo) { - // //fetchBasicSettings() - // previousRoofMaterialsYn = 'Y' - // } - // } - - // // 이전 값을 업데이트 - // previousObjectNoRef.current = correntObjectNo - // previousRoofMaterialsRef.current = roofMaterials - // } - // }, [roofMaterials, correntObjectNo]) - /** * 배치면 초기설정 화면이 열리지 않아도 데이터 set 하기 위해서 추가 */ @@ -330,13 +318,24 @@ export function useCanvasSetting() { * 기본설정(PlacementShapeSetting) 조회 및 초기화 */ const fetchBasicSettings = async (planNo, openPoint) => { - /* roofMaterials가 로드될 때까지 대기 */ - if (!roofMaterials || roofMaterials.length === 0) { - console.log('Waiting for roofMaterials to load...') - return - } - try { + /* roofMaterials가 로드될 때까지 대기 후 실행 */ + if (!isRoofMaterialsLoaded) { + /* roofMaterials가 아직 로드되지 않았다면 */ + await new Promise((resolve) => { + /* 새로운 Promise 생성 */ + const checkInterval = setInterval(() => { + /* 100ms마다 체크하는 인터벌 설정 */ + console.log('roofMaterials loading... ', roofMaterials.length) + if (roofMaterials.length > 0) { + /* roofMaterials가 로드되었다면 */ + clearInterval(checkInterval) // 인터벌 중지 + resolve() // Promise 완료 + } + }, 100) + }) + } + await get({ url: `/api/canvas-management/canvas-basic-settings/by-object/${correntObjectNo}/${planNo}`, }).then((res) => { @@ -433,6 +432,7 @@ export function useCanvasSetting() { if (addRoofs.length > 0) { setAddedRoofs(addRoofs) + setBasicSettings({ ...basicSetting, roofMaterials: addRoofs[0], @@ -442,13 +442,23 @@ export function useCanvasSetting() { roofsData: roofsArray, selectedRoofMaterial: addRoofs.find((roof) => roof.selected), }) + + setCanvasSetting({ + ...basicSetting, + roofMaterials: addRoofs[0], + planNo: roofsRow[0].planNo, + roofSizeSet: roofsRow[0].roofSizeSet, + roofAngleSet: roofsRow[0].roofAngleSet, + roofsData: roofsArray, + selectedRoofMaterial: addRoofs.find((roof) => roof.selected), + }) } }) } catch (error) { console.error('Data fetching error:', error) } - setCanvasSetting({ ...basicSetting }) + // setCanvasSetting({ ...basicSetting }) } /** @@ -482,12 +492,15 @@ export function useCanvasSetting() { await post({ url: `/api/canvas-management/canvas-basic-settings`, data: patternData }).then((res) => { swalFire({ text: getMessage(res.returnMessage) }) - /* 배치면초기설정 조회 */ + /* BasicSettings Recoil 설정 */ setBasicSettings({ ...params }) }) - /* CanvasSetting Recoil 설정 */ - setCanvasSetting({ ...basicSetting }) + /* CanvasSetting Recoil 설정 - roofSizeSet을 문자열로 변환 */ + setCanvasSetting({ + ...basicSetting, + roofSizeSet: String(params.roofSizeSet), + }) /* 배치면초기설정 조회 */ fetchBasicSettings(params.planNo, null) From 993ca373a2fb03c4c072d5683228c6ef313c2067 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 19 Feb 2025 13:38:16 +0900 Subject: [PATCH 043/352] =?UTF-8?q?#782=20-=20=EB=B3=80=EB=B3=84=EB=A1=9C?= =?UTF-8?q?=20=EC=84=A4=EC=A0=95=EC=9C=BC=EB=A1=9C=20=EC=A7=80=EB=B6=95?= =?UTF-8?q?=ED=98=95=EC=83=81=20=EC=9E=90=EB=8F=99=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=ED=9B=84=20=EC=A7=80=EB=B6=95=ED=98=95=EC=83=81=20=EC=88=98?= =?UTF-8?q?=EB=8F=99=EC=84=A4=EC=A0=95=20=ED=8C=9D=EC=97=85=EC=B0=BD=20?= =?UTF-8?q?=ED=98=B8=EC=B6=9C=20=EC=98=A4=EB=A5=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useLine.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hooks/useLine.js b/src/hooks/useLine.js index e2667e80..b447d4f0 100644 --- a/src/hooks/useLine.js +++ b/src/hooks/useLine.js @@ -40,7 +40,7 @@ export const useLine = () => { }) canvas ?.getObjects() - .find((obj) => obj.parent === line) + .find((obj) => obj.parentId === line.id) .set({ visible: false, }) @@ -53,7 +53,7 @@ export const useLine = () => { }) canvas ?.getObjects() - .find((obj) => obj.parent === line) + .find((obj) => obj.parentId === line.id) .set({ visible: true, }) From 84c9f3914ef0760be216bdc2f29d70a4658058d1 Mon Sep 17 00:00:00 2001 From: basssy Date: Wed, 19 Feb 2025 13:49:43 +0900 Subject: [PATCH 044/352] #756 --- src/components/floor-plan/CanvasMenu.jsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 21c7bedf..a5fd5587 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -215,6 +215,9 @@ export default function CanvasMenu(props) { setType('module') } } else { + //menuNumber가 모듈,회로 구성(4) 보다 큰 경우. (견적서:5, 발전시뮬:6) + //화면은 이동되는데 MenuDapth01 type이 null로 들어가서 모듈/가대설정, 회로설정 하위뎁스메뉴 안나오는 문제 수정 + setType('module') router.push(`/floor-plan?pid=${pid}&objectNo=${objectNo}`) } await reloadCanvasStatus(objectNo, pid) From 3ed6aaa468b44502733f99d826236919c705cccf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 19 Feb 2025 14:24:07 +0900 Subject: [PATCH 045/352] =?UTF-8?q?=F0=9F=9A=A8chore:=20Sync=20Sass?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/styles/_modal.scss | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/styles/_modal.scss b/src/styles/_modal.scss index b6e2d322..a19aba2e 100644 --- a/src/styles/_modal.scss +++ b/src/styles/_modal.scss @@ -769,6 +769,13 @@ $alert-color: #101010; background-color: #365f6e; } } + &.gray{ + background-color: #535353; + border: 1px solid #9e9e9e; + &:hover{ + background-color: #6b6b6b; + } + } } } } From 5027e7355d789a9b18563e0485635f37800b5f96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 19 Feb 2025 14:24:51 +0900 Subject: [PATCH 046/352] =?UTF-8?q?-=20=EB=B0=B0=EC=B9=98=EB=A9=B4=20?= =?UTF-8?q?=EA=B7=B8=EB=A6=AC=EA=B8=B0=20=EC=9D=B4=ED=9B=84=20=EC=84=A0?= =?UTF-8?q?=EC=86=8D=EC=84=B1=20=EC=84=A4=EC=A0=95=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20-=20=EB=8B=A4=EA=B5=AD=EC=96=B4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PlacementSurfaceLineProperty.jsx | 74 +++++++++ .../surface/useRoofLinePropertySetting.js | 151 ++++++++++++++++++ src/locales/ja.json | 4 + src/locales/ko.json | 4 + 4 files changed, 233 insertions(+) create mode 100644 src/components/floor-plan/modal/placementShape/PlacementSurfaceLineProperty.jsx create mode 100644 src/hooks/surface/useRoofLinePropertySetting.js diff --git a/src/components/floor-plan/modal/placementShape/PlacementSurfaceLineProperty.jsx b/src/components/floor-plan/modal/placementShape/PlacementSurfaceLineProperty.jsx new file mode 100644 index 00000000..00f00e80 --- /dev/null +++ b/src/components/floor-plan/modal/placementShape/PlacementSurfaceLineProperty.jsx @@ -0,0 +1,74 @@ +import WithDraggable from '@/components/common/draggable/WithDraggable' +import { useMessage } from '@/hooks/useMessage' +import { usePopup } from '@/hooks/usePopup' +import { useRoofLinePropertySetting } from '@/hooks/surface/useRoofLinePropertySetting' +import { useEffect } from 'react' +import { LINE_TYPE } from '@/common/common' +import { useSwal } from '@/hooks/useSwal' + +export default function PlacementSurfaceLineProperty(props) { + const { id, pos = { x: 50, y: 230 }, roof } = props + const { closePopup } = usePopup() + // const { handleSetEaves, handleSetGable, handleRollback, handleFix, closeModal } = usePropertiesSetting(id) + const { roofLinesInit, handleSetRidge, handleSetEaves, handleSetGable, handleRollback, handleFix } = useRoofLinePropertySetting(id, roof) + const { getMessage } = useMessage() + const { swalFire } = useSwal() + + useEffect(() => { + roofLinesInit(roof) + }, []) + + const handleClose = () => { + const notSettingLines = roof.lines.filter( + (line) => + !line.attributes.type || ![LINE_TYPE.WALLLINE.EAVES, LINE_TYPE.WALLLINE.GABLE, LINE_TYPE.SUBLINE.RIDGE].includes(line.attributes.type), + ) + if (notSettingLines.length > 0) { + swalFire({ text: getMessage('modal.canvas.setting.roofline.properties.setting.not.setting'), type: 'alert', icon: 'warning' }) + return + } + + closePopup(id) + } + + return ( + +
        +
        +

        {getMessage('modal.canvas.setting.roofline.properties.setting')}

        + +
        +
        +
        +
        +
        {getMessage('modal.canvas.setting.roofline.properties.setting.info')}
        +
        +
        {getMessage('setting')}
        +
        + + + +
        +
        +
        + + +
        +
        +
        +
        +
        + ) +} diff --git a/src/hooks/surface/useRoofLinePropertySetting.js b/src/hooks/surface/useRoofLinePropertySetting.js new file mode 100644 index 00000000..184d7f4e --- /dev/null +++ b/src/hooks/surface/useRoofLinePropertySetting.js @@ -0,0 +1,151 @@ +import { LINE_TYPE } from '@/common/common' +import { canvasState, currentObjectState } from '@/store/canvasAtom' +import { useEffect, useRef } from 'react' +import { useRecoilValue } from 'recoil' +import { usePopup } from '../usePopup' +import useSWR from 'swr' +import { useSwal } from '../useSwal' +import { useMessage } from '../useMessage' + +const LINE_COLOR = { + EAVES: '#45CD7D', + GABLE: '#3FBAE6', + RIDGE: '#9e9e9e', + DEFAULT: '#000000', +} + +export function useRoofLinePropertySetting(id, roof) { + const canvas = useRecoilValue(canvasState) + const currentObject = useRecoilValue(currentObjectState) + const history = useRef([]) + const { closePopup } = usePopup() + const { swalFire } = useSwal() + const { getMessage } = useMessage() + + useEffect(() => { + if (currentObject) { + currentObject.set({ + stroke: '#EA10AC', + strokeWidth: 4, + }) + } + }, [currentObject]) + + const roofLinesInit = () => { + roof.lines.forEach((line) => { + line.set({ + stroke: '#000000', + strokeWidth: 4, + visible: true, + }) + line.bringToFront() + line.setViewLengthText(false) + }) + canvas.renderAll() + } + + const handleSetEaves = () => { + currentObject.set({ + attributes: { + ...currentObject.attributes, + type: LINE_TYPE.WALLLINE.EAVES, + }, + stroke: LINE_COLOR.EAVES, + }) + + history.current.push(currentObject) + nextLineFocus(currentObject) + canvas.renderAll() + } + + const handleSetGable = () => { + currentObject.set({ + attributes: { + ...currentObject.attributes, + type: LINE_TYPE.WALLLINE.GABLE, + }, + stroke: LINE_COLOR.GABLE, + }) + + history.current.push(currentObject) + nextLineFocus(currentObject) + canvas.renderAll() + } + + const handleSetRidge = () => { + currentObject.set({ + attributes: { + ...currentObject.attributes, + type: LINE_TYPE.SUBLINE.RIDGE, + }, + stroke: LINE_COLOR.RIDGE, + }) + + history.current.push(currentObject) + nextLineFocus(currentObject) + canvas.renderAll() + } + + const handleRollback = () => { + if (history.current.length === 0) { + return + } + const lastLine = history.current.pop() + + delete lastLine.attributes + lastLine.set({ + stroke: LINE_COLOR.DEFAULT, + strokeWidth: 4, + }) + + canvas.setActiveObject(lastLine) + canvas.renderAll() + } + + const handleFix = () => { + // const roof = canvas.getObjects().find((obj) => currentObject.parentId === obj.id) + const notSettingLines = roof.lines.filter( + (line) => + !line.attributes.type || ![LINE_TYPE.WALLLINE.EAVES, LINE_TYPE.WALLLINE.GABLE, LINE_TYPE.SUBLINE.RIDGE].includes(line.attributes.type), + ) + if (notSettingLines.length > 0) { + swalFire({ text: getMessage('modal.canvas.setting.roofline.properties.setting.not.setting'), type: 'alert', icon: 'warning' }) + return + } + + roof.lines.forEach((line) => { + line.set({ + stroke: LINE_COLOR.DEFAULT, + strokeWidth: 4, + visible: false, + }) + }) + + canvas.renderAll() + closePopup(id) + } + + const nextLineFocus = (selectedLine) => { + // const roof = canvas.getObjects().find((obj) => currentObject.parentId === obj.id) + const lines = roof?.lines + if (!lines) return + const index = lines.findIndex((line) => line === selectedLine) + + const nextLine = lines[index + 1] || lines[0] + if (!nextLine.attributes?.type) { + canvas.setActiveObject(nextLine) + } else { + //activeObject 해제 + canvas.discardActiveObject() + } + } + + return { + roofLinesInit, + handleSetEaves, + handleSetGable, + handleSetRidge, + handleRollback, + handleFix, + } +} diff --git a/src/locales/ja.json b/src/locales/ja.json index 9f06310e..7c3333c3 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -269,6 +269,10 @@ "modal.canvas.setting.wallline.properties.setting.info": "※属性を変更する外壁線を選択し、軒で設定またはケラバで設定\nボタンをクリックして設定値を適用してください。\n", "modal.canvas.setting.wallline.properties.setting.eaves": "軒で設定", "modal.canvas.setting.wallline.properties.setting.edge": "ケラバに設定", + "modal.canvas.setting.wallline.properties.setting.ridge": "용마루로 설정(JA)", + "modal.canvas.setting.roofline.properties.setting": "지붕선 속성 설정(JA)", + "modal.canvas.setting.roofline.properties.setting.info": "※ 속성을 변경할 지붕선을 선택하고 처마로 설정 또는 케라바로 설정\n 버튼을 클릭하여 설정값을 적용하십시오.\n(JA)", + "modal.canvas.setting.roofline.properties.setting.not.setting": "설정하지 않은 라인이 존재합니다.(JA)", "modal.eaves.gable.edit": "軒/ケラバ変更", "modal.eaves.gable.edit.basic": "通常", "modal.eaves.gable.edit.wall.merge.info": "河屋などの壁に面する屋根を作成します。", diff --git a/src/locales/ko.json b/src/locales/ko.json index b43e6853..d4ea7929 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -269,6 +269,10 @@ "modal.canvas.setting.wallline.properties.setting.info": "※ 속성을 변경할 외벽선을 선택하고 처마로 설정 또는 케라바로 설정\n 버튼을 클릭하여 설정값을 적용하십시오.\n", "modal.canvas.setting.wallline.properties.setting.eaves": "처마로 설정", "modal.canvas.setting.wallline.properties.setting.edge": "케라바로 설정", + "modal.canvas.setting.wallline.properties.setting.ridge": "용마루로 설정", + "modal.canvas.setting.roofline.properties.setting": "지붕선 속성 설정", + "modal.canvas.setting.roofline.properties.setting.info": "※ 속성을 변경할 지붕선을 선택하고 처마로 설정 또는 케라바로 설정\n 버튼을 클릭하여 설정값을 적용하십시오.\n", + "modal.canvas.setting.roofline.properties.setting.not.setting": "설정하지 않은 라인이 존재합니다.", "modal.eaves.gable.edit": "처마/케라바 변경", "modal.eaves.gable.edit.basic": "통상", "modal.eaves.gable.edit.wall.merge.info": "하옥 등 벽에 접하는 지붕을 작성합니다.", From dfccb516931ce81aac4ea6b50d81143fa21c754c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 19 Feb 2025 14:25:21 +0900 Subject: [PATCH 047/352] =?UTF-8?q?-=20=ED=9A=8C=EB=A1=9C=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EC=B4=88=EA=B8=B0=ED=99=94=20=ED=9B=84=20=ED=9A=8C?= =?UTF-8?q?=EB=A1=9C=EB=B2=88=ED=98=B8=20infinity=20=EB=B2=84=EA=B7=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../circuitTrestle/step/type/PassivityCircuitAllocation.jsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx b/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx index 6ec3ba25..ee118601 100644 --- a/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx @@ -262,12 +262,13 @@ export default function PassivityCircuitAllocation(props) { const circuitModules = canvas.getObjects().filter((obj) => obj.name === 'module' && obj.circuit?.circuitInfo?.id === selectedPcs.id) const circuitNumbers = circuitModules.map((obj) => { const circuitNumber = obj.circuitNumber.replace(/[()]/g, '').split('-') - return parseInt(circuitNumber[circuitNumber.length - 1]) + return parseInt(circuitNumber[0]) }) const minCircuitNumber = Math.min(...circuitNumbers) canvas.remove(...circuitModules.map((module) => module.circuit)) circuitModules.forEach((obj) => { obj.circuit = null + obj.circuitNumber = null obj.pcsItemId = null }) setCircuitNumber(minCircuitNumber) @@ -293,9 +294,11 @@ export default function PassivityCircuitAllocation(props) { canvas.remove(...circuitModules.map((module) => module.circuit)) circuitModules.forEach((obj) => { obj.circuit = null + obj.circuitNumber = null obj.pcsItemId = null }) canvas.renderAll() + setCircuitNumber(1) setTargetModules([]) setModuleStatisticsData() }, From f0a9c5963f2282c08ee2baa59dc5140109c7dbc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 19 Feb 2025 14:26:29 +0900 Subject: [PATCH 048/352] =?UTF-8?q?-=20=EB=B0=B0=EC=B9=98=EB=A9=B4=20?= =?UTF-8?q?=ED=99=95=EC=A0=95=20=ED=9B=84=20=EC=A7=80=EB=B6=95=EC=84=A0=20?= =?UTF-8?q?=EC=86=8D=EC=84=B1=20=EC=84=A4=EC=A0=95=20=ED=8C=9D=EC=97=85=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/surface/usePlacementShapeDrawing.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hooks/surface/usePlacementShapeDrawing.js b/src/hooks/surface/usePlacementShapeDrawing.js index dee54673..c2b7ff98 100644 --- a/src/hooks/surface/usePlacementShapeDrawing.js +++ b/src/hooks/surface/usePlacementShapeDrawing.js @@ -34,6 +34,7 @@ import { usePopup } from '@/hooks/usePopup' import { roofDisplaySelector } from '@/store/settingAtom' import { useRoofFn } from '@/hooks/common/useRoofFn' +import PlacementSurfaceLineProperty from '@/components/floor-plan/modal/placementShape/PlacementSurfaceLineProperty' // 면형상 배치 export function usePlacementShapeDrawing(id) { @@ -76,7 +77,7 @@ export function usePlacementShapeDrawing(id) { const isFix = useRef(false) - const { closePopup } = usePopup() + const { closePopup, addPopup } = usePopup() const globalPitch = useRecoilValue(globalPitchState) @@ -244,7 +245,8 @@ export function usePlacementShapeDrawing(id) { setPoints([]) canvas?.renderAll() - closePopup(id) + + addPopup(id, 1, , false) } if (points.length < 3) { From 966f7db9b846eadb4bcf62dcf991d72e1be5522c Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 19 Feb 2025 14:29:44 +0900 Subject: [PATCH 049/352] =?UTF-8?q?=EC=A7=80=EB=B6=95=EB=A9=B4=20=ED=95=A0?= =?UTF-8?q?=EB=8B=B9=20=EC=8B=9C=20lineType=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/usePolygon.js | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/hooks/usePolygon.js b/src/hooks/usePolygon.js index 99845d46..1dc3f231 100644 --- a/src/hooks/usePolygon.js +++ b/src/hooks/usePolygon.js @@ -7,7 +7,7 @@ import { isSamePoint, removeDuplicatePolygons } from '@/util/qpolygon-utils' import { flowDisplaySelector } from '@/store/settingAtom' import { fontSelector } from '@/store/fontAtom' import { QLine } from '@/components/fabric/QLine' -import { POLYGON_TYPE } from '@/common/common' +import { LINE_TYPE, POLYGON_TYPE } from '@/common/common' export const usePolygon = () => { const canvas = useRecoilValue(canvasState) @@ -909,6 +909,29 @@ export const usePolygon = () => { const allLines = [...polygonLines, ...innerLines] + // 2025-02-19 대각선은 케라바, 직선은 용마루로 세팅 + innerLines.forEach((innerLine) => { + const startPoint = innerLine.startPoint + const endPoint = innerLine.endPoint + + // startPoint와 endPoint의 각도가 0,90,180,270이면 직선으로 판단 + if (Math.abs(startPoint.x - endPoint.x) < 2 || Math.abs(startPoint.y - endPoint.y) < 2) { + if (!innerLine.attributes || !innerLine.attributes.type) { + innerLine.attributes = { + ...innerLine.attributes, + type: LINE_TYPE.SUBLINE.RIDGE, + } + } + } else { + if (!innerLine.attributes || !innerLine.attributes.type) { + innerLine.attributes = { + ...innerLine.attributes, + type: LINE_TYPE.SUBLINE.GABLE, + } + } + } + }) + /** * 왼쪽 상단을 startPoint로 전부 변경 */ From 0f07b885d5f04eaf4d7698d7f6df735bdb8d2ca7 Mon Sep 17 00:00:00 2001 From: basssy Date: Wed, 19 Feb 2025 15:27:57 +0900 Subject: [PATCH 050/352] =?UTF-8?q?docNo=EC=A0=95=EC=B1=85=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index a5fd5587..065a827e 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -498,16 +498,11 @@ export default function CanvasMenu(props) { estimateRecoilState.lockFlg = estimateRecoilState.lockFlg === '0' ? '1' : '0' const { createUser, tempFlg, lockFlg } = estimateRecoilState if (createUser && tempFlg && lockFlg) { - if (createUser === 'T01') { - if (sessionState.storeId !== 'T01') { - setAllButtonStyles('none') - } else { - setEstimateContextState({ tempFlg: estimateRecoilState.tempFlg, lockFlg: estimateRecoilState.lockFlg }) - handleButtonStyles(estimateRecoilState.tempFlg, estimateRecoilState.lockFlg) - } + if (createUser === 'T01' && sessionState.storeId !== 'T01') { + setAllButtonStyles('none') } else { setEstimateContextState({ tempFlg: estimateRecoilState.tempFlg, lockFlg: estimateRecoilState.lockFlg }) - handleButtonStyles(estimateRecoilState.tempFlg, estimateRecoilState.lockFlg) + handleButtonStyles(estimateRecoilState.tempFlg, estimateRecoilState.lockFlg, estimateContextState.docNo) } } } From c35bc134b80cccbfd2abceb8ae5227493d45d6d0 Mon Sep 17 00:00:00 2001 From: basssy Date: Wed, 19 Feb 2025 15:59:26 +0900 Subject: [PATCH 051/352] =?UTF-8?q?#754=20=EC=9B=90=EB=B3=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 065a827e..cb46640e 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -215,9 +215,6 @@ export default function CanvasMenu(props) { setType('module') } } else { - //menuNumber가 모듈,회로 구성(4) 보다 큰 경우. (견적서:5, 발전시뮬:6) - //화면은 이동되는데 MenuDapth01 type이 null로 들어가서 모듈/가대설정, 회로설정 하위뎁스메뉴 안나오는 문제 수정 - setType('module') router.push(`/floor-plan?pid=${pid}&objectNo=${objectNo}`) } await reloadCanvasStatus(objectNo, pid) From 074b405abacc898fcb491e7b19e2833260657bff Mon Sep 17 00:00:00 2001 From: basssy Date: Wed, 19 Feb 2025 16:38:02 +0900 Subject: [PATCH 052/352] =?UTF-8?q?=EB=B0=9C=EC=A0=84=EC=8B=9C=EB=AE=AC?= =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=85=98=20=ED=83=AD=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EB=B0=9C=EC=A0=84=EC=8B=9C=EB=AE=AC=EB=A0=88=EC=9D=B4=EC=85=98?= =?UTF-8?q?=20=ED=83=AD=20=EB=8B=A4=EC=8B=9C=20=EB=88=8C=EB=A0=80=EC=9D=84?= =?UTF-8?q?=EB=95=8C=20=EB=A1=9C=EB=94=A9=EB=B0=94=20=ED=95=B4=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 1 + src/components/management/StuffSearchCondition.jsx | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index cb46640e..b3b461b3 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -246,6 +246,7 @@ export default function CanvasMenu(props) { setMenuNumber(menu.index) setCurrentMenu(menu.title) router.push(`/floor-plan/simulator/${menu.index}?pid=${selectedPlan.planNo}&objectNo=${objectNo}`) + setIsGlobalLoading(false) } else { setIsGlobalLoading(false) swalFire({ text: getMessage('simulator.menu.move.valid1') }) diff --git a/src/components/management/StuffSearchCondition.jsx b/src/components/management/StuffSearchCondition.jsx index 58be659c..05c00a13 100644 --- a/src/components/management/StuffSearchCondition.jsx +++ b/src/components/management/StuffSearchCondition.jsx @@ -761,6 +761,15 @@ export default function StuffSearchCondition() { setSchSelSaleStoreId('') setOtherSaleStoreId('') } else { + setObjectNo(stuffSearch.schObjectNo ? stuffSearch.schObjectNo : objectNo) + setSaleStoreName(stuffSearch.schSaleStoreName ? stuffSearch.schSaleStoreName : saleStoreName) + setDispCompanyName(stuffSearch.schDispCompanyName ? stuffSearch.schDispCompanyName : dispCompanyName) + setObjectName(stuffSearch.schObjectName ? stuffSearch.schObjectName : objectName) + setReceiveUser(stuffSearch.schReceiveUser ? stuffSearch.schReceiveUser : receiveUser) + setAddress(stuffSearch.schAddress ? stuffSearch.schAddress : address) + setDateType(stuffSearch.schDateType ? stuffSearch.schDateType : dateType) + setStartDate(stuffSearch?.schFromDt ? stuffSearch.schFromDt : dayjs(new Date()).add(-1, 'year').format('YYYY-MM-DD')) + setEndDate(stuffSearch?.schToDt ? stuffSearch.schToDt : dayjs(new Date()).format('YYYY-MM-DD')) setTempFlg(stuffSearch.schTempFlg ? stuffSearch.schTempFlg : tempFlg) } } else { From 575b507262027e11f9d1f62e69a3e73bbc8109bb Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 19 Feb 2025 16:47:02 +0900 Subject: [PATCH 053/352] =?UTF-8?q?textVisbile=20=EC=86=8D=EC=84=B1=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/common.js | 1 + src/components/fabric/QLine.js | 5 +++++ src/components/fabric/QPolygon.js | 1 + src/hooks/surface/useRoofLinePropertySetting.js | 3 ++- 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/common/common.js b/src/common/common.js index 9aad21d6..0424fcfd 100644 --- a/src/common/common.js +++ b/src/common/common.js @@ -187,6 +187,7 @@ export const SAVE_KEY = [ 'circuit', 'onlyOffset', 'isChidory', + 'textVisible', ] export const OBJECT_PROTOTYPE = [fabric.Line.prototype, fabric.Polygon.prototype, fabric.Triangle.prototype] diff --git a/src/components/fabric/QLine.js b/src/components/fabric/QLine.js index 7fc1afc1..9c9791c9 100644 --- a/src/components/fabric/QLine.js +++ b/src/components/fabric/QLine.js @@ -13,6 +13,7 @@ export const QLine = fabric.util.createClass(fabric.Line, { area: 0, children: [], padding: 5, + textVisible: true, initialize: function (points, options, length = 0) { // 소수점 전부 제거 @@ -29,6 +30,7 @@ export const QLine = fabric.util.createClass(fabric.Line, { this.idx = options.idx ?? 0 this.direction = options.direction ?? getDirectionByPoint({ x: this.x1, y: this.y1 }, { x: this.x2, y: this.y2 }) this.textMode = options.textMode ?? 'plane' // plane:복시도, actual:실측, none:표시안함 + this.textVisible = options.textVisible ?? true if (length !== 0) { this.length = length } else { @@ -40,6 +42,9 @@ export const QLine = fabric.util.createClass(fabric.Line, { }, init: function () { + if (!this.textVisible) { + return + } this.addLengthText() this.on('moving', () => { diff --git a/src/components/fabric/QPolygon.js b/src/components/fabric/QPolygon.js index 23e0de55..b0c46798 100644 --- a/src/components/fabric/QPolygon.js +++ b/src/components/fabric/QPolygon.js @@ -177,6 +177,7 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, { attributes: { offset: 0, }, + textVisible: false, parent: this, parentId: this.id, direction: getDirectionByPoint(point, nextPoint), diff --git a/src/hooks/surface/useRoofLinePropertySetting.js b/src/hooks/surface/useRoofLinePropertySetting.js index 184d7f4e..22fde4b6 100644 --- a/src/hooks/surface/useRoofLinePropertySetting.js +++ b/src/hooks/surface/useRoofLinePropertySetting.js @@ -33,13 +33,14 @@ export function useRoofLinePropertySetting(id, roof) { const roofLinesInit = () => { roof.lines.forEach((line) => { + canvas.add(line) line.set({ stroke: '#000000', strokeWidth: 4, visible: true, }) line.bringToFront() - line.setViewLengthText(false) + // line.setViewLengthText(false) }) canvas.renderAll() } From 9a68559323535d98600c806224e4c699aacc7198 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Wed, 19 Feb 2025 16:55:58 +0900 Subject: [PATCH 054/352] =?UTF-8?q?=F0=9F=93=8Cfix:=20=EA=B2=AC=EC=A0=81?= =?UTF-8?q?=EC=84=9C/=EB=B0=9C=EC=A0=84=20=EC=8B=9C=EB=AE=AC=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=EC=97=90=EC=84=9C=20=EB=AA=A8=EB=93=88=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EC=9D=B4=EB=8F=99=EC=8B=9C=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 서브 메뉴 안나오던 문제 해결 --- src/components/floor-plan/CanvasMenu.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index b3b461b3..e2b997ce 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -216,6 +216,7 @@ export default function CanvasMenu(props) { } } else { router.push(`/floor-plan?pid=${pid}&objectNo=${objectNo}`) + setType('module') } await reloadCanvasStatus(objectNo, pid) break From fdf834260d9eb510a8e7ad90f71e55f504d99a10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 19 Feb 2025 17:05:31 +0900 Subject: [PATCH 055/352] =?UTF-8?q?-=20=EB=A9=B4=ED=98=95=EC=83=81=20?= =?UTF-8?q?=EB=B0=B0=EC=B9=98=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/placementSurface/PlacementSurface.jsx | 4 ++-- src/hooks/surface/useSurfaceShapeBatch.js | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/floor-plan/modal/placementSurface/PlacementSurface.jsx b/src/components/floor-plan/modal/placementSurface/PlacementSurface.jsx index a4722bff..7ab89106 100644 --- a/src/components/floor-plan/modal/placementSurface/PlacementSurface.jsx +++ b/src/components/floor-plan/modal/placementSurface/PlacementSurface.jsx @@ -33,9 +33,9 @@ const PlacementSurface = forwardRef((props, refs) => { imageRotate = Math.abs(rotate % 4) } else { if (rotate < 0) { - imageRotate = Math.abs((rotate + 2) % 4) - } else { imageRotate = Math.abs((rotate - 2) % 4) + } else { + imageRotate = Math.abs((rotate + 2) % 4) } } } else { diff --git a/src/hooks/surface/useSurfaceShapeBatch.js b/src/hooks/surface/useSurfaceShapeBatch.js index 6f7d1dfa..6ad9861e 100644 --- a/src/hooks/surface/useSurfaceShapeBatch.js +++ b/src/hooks/surface/useSurfaceShapeBatch.js @@ -113,9 +113,9 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { let imageRotate = 0 if (xInversion && !yInversion) { if (rotate % 180 === 0 || rotate < 0) { - imageRotate = Math.abs(rotate % 360) + imageRotate = Math.abs((rotate - 180) % 360) } else { - imageRotate = Math.abs((rotate - 180) % 4) + imageRotate = Math.abs((rotate + 180) % 4) } } else if (xInversion && yInversion) { imageRotate = Math.abs((rotate + 360) % 360) @@ -126,9 +126,9 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { imageRotate = Math.abs(rotate % 360) } else { if (rotate < 0) { - imageRotate = Math.abs((rotate + 180) % 360) - } else { imageRotate = Math.abs((rotate - 180) % 360) + } else { + imageRotate = Math.abs((rotate + 180) % 360) } } } else { From 4507e6f9de0447ea02ec67654b6e7c2d08e0bfbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 19 Feb 2025 17:06:04 +0900 Subject: [PATCH 056/352] =?UTF-8?q?-=20=EA=B2=BD=EC=82=AC=20type=20number?= =?UTF-8?q?=20=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx | 2 +- .../circuitTrestle/step/type/PassivityCircuitAllocation.jsx | 2 +- src/hooks/useCirCuitTrestle.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx b/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx index d8fa01e5..239487e9 100644 --- a/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx @@ -322,7 +322,7 @@ export default function StepUp(props) { moduleList: formatModuleList(rsf.moduleList), roofSurface: rsf.roofSurface ? rsf.roofSurface : '', roofSurfaceId: rsf.roofSurfaceId ? rsf.roofSurfaceId : '', - roofSurfaceIncl: rsf.roofSurfaceIncl ? rsf.roofSurfaceIncl : '', + roofSurfaceIncl: rsf.roofSurfaceIncl ? +rsf.roofSurfaceIncl : '', })) } // PCS MatModule 포맷 diff --git a/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx b/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx index ee118601..36fdad35 100644 --- a/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx @@ -175,7 +175,7 @@ export default function PassivityCircuitAllocation(props) { return { roofSurfaceId: surface.id, roofSurface: surface.direction, - roofSurfaceIncl: canvas.getObjects().filter((obj) => obj.id === surface.parentId)[0].pitch, + roofSurfaceIncl: +canvas.getObjects().filter((obj) => obj.id === surface.parentId)[0].pitch, moduleList: surface.modules.map((module) => { return { itemId: module.moduleInfo.itemId, diff --git a/src/hooks/useCirCuitTrestle.js b/src/hooks/useCirCuitTrestle.js index 0d811dfd..aacc7e5d 100644 --- a/src/hooks/useCirCuitTrestle.js +++ b/src/hooks/useCirCuitTrestle.js @@ -83,7 +83,7 @@ export function useCircuitTrestle() { .getObjects() .filter((o) => o.id === obj.parentId)[0] .directionText.replace(/[0-9]/g, ''), - roofSurfaceIncl: canvas.getObjects().filter((o) => o.id === obj.parentId)[0].roofMaterial.pitch, + roofSurfaceIncl: +canvas.getObjects().filter((o) => o.id === obj.parentId)[0].roofMaterial.pitch, moduleList: getModuleList(obj).map((module) => { return { itemId: module.moduleInfo.itemId, From 03be41ceba4f9a282b4fac1d128d0590f18f9a78 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 19 Feb 2025 17:17:51 +0900 Subject: [PATCH 057/352] =?UTF-8?q?=EB=A9=B4=ED=98=95=EC=83=81=20=EB=B0=B0?= =?UTF-8?q?=EC=B9=98=20=ED=9B=84=20=EC=83=9D=EC=84=B1=EB=90=9C=20object=20?= =?UTF-8?q?=EC=84=A0=ED=83=9D=EB=90=9C=20=EC=83=81=ED=83=9C=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/surface/useSurfaceShapeBatch.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hooks/surface/useSurfaceShapeBatch.js b/src/hooks/surface/useSurfaceShapeBatch.js index 6f7d1dfa..dc073bde 100644 --- a/src/hooks/surface/useSurfaceShapeBatch.js +++ b/src/hooks/surface/useSurfaceShapeBatch.js @@ -184,6 +184,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { direction: direction, }) canvas?.add(batchSurface) + canvas.setActiveObject(batchSurface) setSurfaceShapePattern(batchSurface, roofDisplay.column) drawDirectionArrow(batchSurface) From c5c05a0504d9da397d3aa9393a3db8f742a0f759 Mon Sep 17 00:00:00 2001 From: basssy Date: Wed, 19 Feb 2025 17:43:25 +0900 Subject: [PATCH 058/352] =?UTF-8?q?=EB=AC=BC=EA=B1=B4=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=20=ED=94=8C=EB=9E=9C=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EA=B0=80?= =?UTF-8?q?=EB=8C=80=20=EC=96=B8=EC=96=B4=ED=8C=A9=20=EC=98=A4=ED=83=80=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/management/StuffDetail.jsx | 5 ++--- src/locales/ja.json | 2 +- src/locales/ko.json | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index 078873d3..a95f34d2 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -229,9 +229,8 @@ export default function StuffDetail() { }, { // 가대 - // field: 'supportMethodIdMulti', - field: 'standTypeNo', - headerName: getMessage('stuff.detail.planGridHeader.standTypeNo'), + field: 'supportMethodIdMulti', + headerName: getMessage('stuff.detail.planGridHeader.supportMethodIdMulti'), wrapText: true, autoHeight: true, cellStyle: { alignItems: 'flex-start' /* 좌측정렬*/, cursor: 'pointer' }, diff --git a/src/locales/ja.json b/src/locales/ja.json index 7c3333c3..e78f57d7 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -787,7 +787,7 @@ "stuff.detail.planGridHeader.capacity": "システム容量", "stuff.detail.planGridHeader.roofMaterialIdMulti": "屋根材", "stuff.detail.planGridHeader.constructSpecificationMulti": "施工方法", - "stuff.detail.planGridHeader.supprotMethodIdMulti": "架台", + "stuff.detail.planGridHeader.supportMethodIdMulti": "架台", "stuff.detail.planGridHeader.pcTypeNo": "パワーコンディショナー", "stuff.detail.planGridHeader.management": "管理", "stuff.detail.planGrid.btn1": "見積書の照会", diff --git a/src/locales/ko.json b/src/locales/ko.json index d4ea7929..f898200a 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -787,7 +787,7 @@ "stuff.detail.planGridHeader.capacity": "시스템용량", "stuff.detail.planGridHeader.roofMaterialIdMulti": "지붕재", "stuff.detail.planGridHeader.constructSpecificationMulti": "시공방법", - "stuff.detail.planGridHeader.supprotMethodIdMulti": "가대", + "stuff.detail.planGridHeader.supportMethodIdMulti": "가대", "stuff.detail.planGridHeader.pcTypeNo": "파워컨디셔너", "stuff.detail.planGridHeader.management": "관리", "stuff.detail.planGrid.btn1": "견적서 조회", From 7a17daff1100113d945f8c971cf1d1a3f4af826e Mon Sep 17 00:00:00 2001 From: basssy Date: Wed, 19 Feb 2025 17:53:26 +0900 Subject: [PATCH 059/352] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20YJSS?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20TO-DO=20=EC=A3=BC=EC=84=9D=20=EC=A0=95?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 6451498d..f4214e68 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -1139,7 +1139,6 @@ export default function Estimate({}) {
        {getMessage('estimate.detail.objectNo')}
        - {/* {objectNo} (Plan No: {estimateContextState.planNo}) */} {currentObjectNo} (Plan No: {planNo})
        @@ -1568,9 +1567,7 @@ export default function Estimate({}) { {/* 견적특이사항 선택한 내용 영역끝 */}
- {/* 견적 특이사항 코드영역 끝 */} - {/* 견적특이사항 영역끝 */} {/* 제품정보 시작 */}
@@ -1580,10 +1577,6 @@ export default function Estimate({}) {
- {/*
-
{getMessage('estimate.detail.sepcialEstimateProductInfo.totAmount')}
-
{convertNumberToPriceDecimal(estimateContextState?.totAmount)}
-
*/}
{getMessage('estimate.detail.sepcialEstimateProductInfo.totVolKw')}
{convertNumberToPriceDecimalToFixed(estimateContextState?.totVolKw, 2)}
@@ -1602,6 +1595,7 @@ export default function Estimate({}) {
+ {/* //todo: 추후 YJSS가 다시 나타날 경우 주석 풀기 */} {/* YJOD면 아래영역 숨김 */} {/*
@@ -1882,7 +1876,6 @@ export default function Estimate({}) {
- {/* html테이블끝 */}
From dac1795aed60f206fe79091b652acb02b03869a3 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 19 Feb 2025 17:59:36 +0900 Subject: [PATCH 060/352] =?UTF-8?q?#786=20=EB=B0=B0=EC=B9=98=EB=A9=B4=20?= =?UTF-8?q?=EB=B3=B5=EC=82=AC=20=EC=8B=9C,=20=EB=B3=B5=EC=82=AC=ED=95=9C?= =?UTF-8?q?=20=EB=B0=B0=EC=B9=98=EB=A9=B4=20=EB=AA=A8=EB=93=88=20=EB=B0=B0?= =?UTF-8?q?=EC=B9=98=20=EC=95=88=EB=90=98=EB=8A=94=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=ED=99=95=EC=9D=B8=20=EC=9A=94=EC=B2=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/common/useCommonUtils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/common/useCommonUtils.js b/src/hooks/common/useCommonUtils.js index 60bbb9ec..b7e944c5 100644 --- a/src/hooks/common/useCommonUtils.js +++ b/src/hooks/common/useCommonUtils.js @@ -592,7 +592,7 @@ export function useCommonUtils() { if (obj.name === 'roof') { clonedObj.setCoords() clonedObj.fire('polygonMoved') - clonedObj.set({ direction: obj.direction, directionText: obj.directionText }) + clonedObj.set({ direction: obj.direction, directionText: obj.directionText, roofMaterial: obj.roofMaterial }) canvas.renderAll() addLengthText(clonedObj) //수치 추가 drawDirectionArrow(clonedObj) //방향 화살표 추가 From c2a063cf9ed1302c7b00082e0f47479c1bd43221 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 19 Feb 2025 18:17:47 +0900 Subject: [PATCH 061/352] =?UTF-8?q?=EC=9C=A1=EC=A7=80=EB=B6=95=20=EB=8C=80?= =?UTF-8?q?=EC=9D=91=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 20 ++++++++++++++----- .../placementShape/PlacementShapeSetting.jsx | 8 ++++++-- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index e2b997ce..df43d7bb 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -565,16 +565,26 @@ export default function CanvasMenu(props) {
{ { - return { ...roof, name: globalLocale === 'ko' ? roof.roofMatlNm : roof.roofMatlNmJp } - })} - //showKey={'roofMatlNm'} + title={ + +basicSetting.roofSizeSet === 3 + ? getMessage('modal.placement.initial.setting.size.none.pitch') + : globalLocale === 'ko' + ? selectedRoofMaterial?.roofMatlNm + : selectedRoofMaterial?.roofMatlNmJp + } + options={ + +basicSetting.roofSizeSet === 3 + ? [] + : addedRoofs.map((roof) => { + return { ...roof, name: globalLocale === 'ko' ? roof.roofMatlNm : roof.roofMatlNmJp } + }) + } showKey={'name'} value={selectedRoofMaterial} onChange={changeSelectedRoofMaterial} sourceKey={'index'} targetKey={'index'} + disabled={+basicSetting.roofSizeSet === 3} /> }
diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx index 9f8c54b2..140c9abd 100644 --- a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx @@ -170,6 +170,10 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla } const handleRoofLayoutChange = (value) => { + if (+currentRoof.roofSizeSet === 3) { + setCurrentRoof({ ...currentRoof, layout: ROOF_MATERIAL_LAYOUT.PARALLEL }) + return + } setCurrentRoof({ ...currentRoof, layout: value }) } @@ -451,7 +455,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla
From c4fa290dd5af0384bd7f82c33c2a784a28e67b1a Mon Sep 17 00:00:00 2001 From: yjnoh Date: Thu, 20 Feb 2025 17:45:04 +0900 Subject: [PATCH 090/352] =?UTF-8?q?=EB=A9=80=ED=8B=B0=20=EB=AA=A8=EB=93=88?= =?UTF-8?q?=20=EC=9C=84=EC=B9=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 29 +++++++++++++---------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 3c27393b..a0741c1b 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -387,6 +387,7 @@ export function useModuleBasicSetting(tabNum) { */ const manualModuleSetup = () => { // console.log('isManualModuleSetup', isManualModuleSetup) + const moduleSetupSurfaces = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) //모듈설치면를 가져옴 if (isManualModuleSetup) { @@ -414,7 +415,7 @@ export function useModuleBasicSetting(tabNum) { const moduleOptions = { fill: checkedModule[0].color, stroke: 'black', - strokeWidth: 0.1, + strokeWidth: 0.3, selectable: true, // 선택 가능하게 설정 lockMovementX: true, // X 축 이동 잠금 lockMovementY: true, // Y 축 이동 잠금 @@ -933,6 +934,10 @@ export function useModuleBasicSetting(tabNum) { //근데 양변이 곡선이면 중앙에 맞추기 위해 아래와 위의 길이를 재서 모듈의 길이를 나눠서 들어갈수 있는 갯수가 동일하면 가운데로 정렬 시킨다 if (flowLines.left.type === 'curve' && flowLines.right.type === 'curve') { startPointX = flowLines.left.x1 + (calcAreaWidth - totalModuleWidthCount * width) / 2 + + if (flowLines.left.x1 < flowLines.bottom.x1) { + startPointX = flowLines.left.x1 + } } let heightMargin = 0 @@ -948,7 +953,7 @@ export function useModuleBasicSetting(tabNum) { let isInstall = false for (let i = 0; i < moduleMaxRows; i++) { - let moduleY = flowLines.bottom.y1 - height * i - 0.1 //살짝 여유를 준다 + let moduleY = flowLines.bottom.y1 - height * i - 1 //살짝 여유를 준다 //두번째 모듈 -> 혼합일 경우의 설치될 모듈 높이를 계산 if (moduleIndex > 0) { @@ -964,7 +969,7 @@ export function useModuleBasicSetting(tabNum) { heightMargin = i === 0 ? 0 : intvVer * i for (let j = 0; j < totalModuleWidthCount; j++) { - let moduleX = startPointX + width * j + 0.1 //5정도 마진을 준다 + let moduleX = startPointX + width * j + 1 //5정도 마진을 준다 widthMargin = j === 0 ? 0 : intvHor * j // 가로 마진값 chidoriLength = 0 //치도리가 아니여도 기본값을 5정도 준다 if (isChidori && !isMaxSetup) { @@ -1024,9 +1029,9 @@ export function useModuleBasicSetting(tabNum) { // } } else { //디버깅용 - // tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) - // canvas?.add(tempModule) - // canvas.renderAll() + tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) + canvas?.add(tempModule) + canvas.renderAll() } } if (isInstall) { @@ -1893,13 +1898,13 @@ export function useModuleBasicSetting(tabNum) { // } } else { //디버깅용 - // tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) - // canvas?.add(tempModule) - // canvas.renderAll() + tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) + canvas?.add(tempModule) + canvas.renderAll() } } - installedLastHeightCoord = moduleY + height + heightMargin + installedLastHeightCoord = moduleY - width - heightMargin if (isInstall) { ++installedModuleHeightCount @@ -2462,7 +2467,7 @@ export function useModuleBasicSetting(tabNum) { let moduleOptions = { fill: '#BFFD9F', stroke: 'black', - strokeWidth: 0.1, + strokeWidth: 0.3, selectable: true, // 선택 가능하게 설정 lockMovementX: true, // X 축 이동 잠금 lockMovementY: true, // Y 축 이동 잠금 @@ -2897,7 +2902,7 @@ export function useModuleBasicSetting(tabNum) { let moduleOptions = { fill: '#BFFD9F', stroke: 'black', - strokeWidth: 0.1, + strokeWidth: 0.3, selectable: true, // 선택 가능하게 설정 lockMovementX: true, // X 축 이동 잠금 lockMovementY: true, // Y 축 이동 잠금 From 25b58dafec512099dd1a0480343f2e030ded3cf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 20 Feb 2025 17:52:52 +0900 Subject: [PATCH 091/352] =?UTF-8?q?-=20=EC=B9=98=EC=88=98=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=20=EB=B0=A9=EB=B2=95=EC=9D=B4=20=EC=9C=A1=EC=A7=80?= =?UTF-8?q?=EB=B6=95=EC=9D=BC=20=EB=95=8C=20=EC=84=A0=20=EC=86=8D=EC=84=B1?= =?UTF-8?q?=20=EC=84=A4=EC=A0=95=20=EC=83=9D=EB=9E=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/surface/usePlacementShapeDrawing.js | 7 ++++++- src/hooks/surface/useSurfaceShapeBatch.js | 5 +++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/hooks/surface/usePlacementShapeDrawing.js b/src/hooks/surface/usePlacementShapeDrawing.js index c2b7ff98..6ebd1414 100644 --- a/src/hooks/surface/usePlacementShapeDrawing.js +++ b/src/hooks/surface/usePlacementShapeDrawing.js @@ -3,6 +3,7 @@ import { adsorptionPointAddModeState, adsorptionPointModeState, adsorptionRangeState, + canvasSettingState, canvasState, dotLineIntervalSelector, globalPitchState, @@ -49,7 +50,7 @@ export function usePlacementShapeDrawing(id) { const { addPolygonByLines, drawDirectionArrow } = usePolygon() const { tempGridMode } = useTempGrid() const { setSurfaceShapePattern } = useRoofFn() - + const canvasSetting = useRecoilValue(canvasSettingState) const verticalHorizontalMode = useRecoilValue(verticalHorizontalModeState) const adsorptionPointAddMode = useRecoilValue(adsorptionPointAddModeState) const adsorptionPointMode = useRecoilValue(adsorptionPointModeState) @@ -246,6 +247,10 @@ export function usePlacementShapeDrawing(id) { setPoints([]) canvas?.renderAll() + if (+canvasSetting?.roofSizeSet === 3) { + closePopup(id) + return + } addPopup(id, 1, , false) } diff --git a/src/hooks/surface/useSurfaceShapeBatch.js b/src/hooks/surface/useSurfaceShapeBatch.js index abb3688b..7b0efec8 100644 --- a/src/hooks/surface/useSurfaceShapeBatch.js +++ b/src/hooks/surface/useSurfaceShapeBatch.js @@ -2,7 +2,7 @@ import { useEffect } from 'react' import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil' -import { canvasState, currentCanvasPlanState, globalPitchState } from '@/store/canvasAtom' +import { canvasSettingState, canvasState, currentCanvasPlanState, globalPitchState } from '@/store/canvasAtom' import { MENU, POLYGON_TYPE } from '@/common/common' import { getIntersectionPoint } from '@/util/canvas-util' import { degreesToRadians } from '@turf/turf' @@ -29,7 +29,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { const lengthTextFont = useRecoilValue(fontSelector('lengthText')) const resetOuterLinePoints = useResetRecoilState(outerLinePointsState) const resetPlacementShapeDrawingPoints = useResetRecoilState(placementShapeDrawingPointsState) - + const canvasSetting = useRecoilValue(canvasSettingState) const canvas = useRecoilValue(canvasState) const globalPitch = useRecoilValue(globalPitchState) const roofDisplay = useRecoilValue(roofDisplaySelector) @@ -200,6 +200,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { // closePopup(id) initEvent() + if (+canvasSetting?.roofSizeSet === 3) return const popupId = uuidv4() addPopup(popupId, 2, ) }) From 76725cef94ec143a898fbdd456899476f54c5510 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Thu, 20 Feb 2025 18:03:46 +0900 Subject: [PATCH 092/352] =?UTF-8?q?=F0=9F=93=8Cfix:=20=EB=B0=B0=EC=B9=98?= =?UTF-8?q?=EB=A9=B4=20=EC=82=AD=EC=A0=9C=ED=95=A0=20=EA=B2=BD=EC=9A=B0=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=9E=88=EC=9D=84=EB=95=8C?= =?UTF-8?q?=EB=A7=8C=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=ED=86=B5=EA=B3=BC=ED=95=98=EA=B2=8C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/surface/useSurfaceShapeBatch.js | 44 ++++++++++++----------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/src/hooks/surface/useSurfaceShapeBatch.js b/src/hooks/surface/useSurfaceShapeBatch.js index abb3688b..46c4ad82 100644 --- a/src/hooks/surface/useSurfaceShapeBatch.js +++ b/src/hooks/surface/useSurfaceShapeBatch.js @@ -734,28 +734,30 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { confirmFn: () => { canvas.clear() - fabric.Image.fromURL(`${backgroundImage.path}`, function (img) { - console.log('🚀 ~ img:', img) - img.set({ - left: 0, - top: 0, - width: img.width, - height: img.height, - name: 'backGroundImage', - selectable: false, - hasRotatingPoint: false, // 회전 핸들 활성화 - lockMovementX: false, - lockMovementY: false, - lockRotation: false, - lockScalingX: false, - lockScalingY: false, + if (backgroundImage) { + fabric.Image.fromURL(`${backgroundImage.path}`, function (img) { + console.log('🚀 ~ img:', img) + img.set({ + left: 0, + top: 0, + width: img.width, + height: img.height, + name: 'backGroundImage', + selectable: false, + hasRotatingPoint: false, // 회전 핸들 활성화 + lockMovementX: false, + lockMovementY: false, + lockRotation: false, + lockScalingX: false, + lockScalingY: false, + }) + // image = img + canvas?.add(img) + canvas?.sendToBack(img) + canvas?.renderAll() + // setBackImg(img) }) - // image = img - canvas?.add(img) - canvas?.sendToBack(img) - canvas?.renderAll() - // setBackImg(img) - }) + } resetOuterLinePoints() resetPlacementShapeDrawingPoints() From e0006875c7964aaae6bed305d59f2134618e5e38 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Thu, 20 Feb 2025 18:27:52 +0900 Subject: [PATCH 093/352] =?UTF-8?q?=F0=9F=93=8Cfix:=20metadata=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/layout.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/layout.js b/src/app/layout.js index 8071159a..c88dd7d8 100644 --- a/src/app/layout.js +++ b/src/app/layout.js @@ -17,8 +17,8 @@ import Footer from '@/components/footer/Footer' import GlobalLoadingProvider from './GlobalLoadingProvider' export const metadata = { - title: 'Create Next App', - description: 'Generated by create next app', + title: 'HANASYS設計', + description: 'HANASYS設計', } export default async function RootLayout({ children }) { From c52034ab53bdb5f45ca9def40f52a87993b5de20 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Fri, 21 Feb 2025 11:22:40 +0900 Subject: [PATCH 094/352] =?UTF-8?q?-=20=EB=AA=A8=EB=93=88=EC=9D=B4=20?= =?UTF-8?q?=EC=9E=88=EB=8A=94=20=EA=B2=BD=EC=9A=B0=20=EB=B0=B0=EC=B9=98?= =?UTF-8?q?=EB=A9=B4=EC=9C=BC=EB=A1=9C=20=EB=8B=A4=EC=8B=9C=20=EC=A7=84?= =?UTF-8?q?=EC=9E=85=20=EC=8B=9C=20=EB=AA=A8=EB=93=88=20=EC=A0=9C=EA=B1=B0?= =?UTF-8?q?=20=EB=B0=8F=20=EC=A7=80=EB=B6=95=EB=A9=B4=20=ED=95=A0=EB=8B=B9?= =?UTF-8?q?=20=EC=9E=AC=20=EC=8B=A4=ED=96=89,=20=EB=A9=94=EB=89=B4=20?= =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=A9=B4=EC=9C=BC=EB=A1=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 1ed413cf..db11d3d1 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -48,6 +48,7 @@ import KO from '@/locales/ko.json' import JA from '@/locales/ja.json' import { QcastContext } from '@/app/QcastProvider' +import { useRoofFn } from '@/hooks/common/useRoofFn' export default function CanvasMenu(props) { const { menuNumber, setMenuNumber } = props const pathname = usePathname() @@ -104,6 +105,7 @@ export default function CanvasMenu(props) { const pwrGnrSimTypeRecoil = useRecoilValue(pwrGnrSimTypeState) const { setIsGlobalLoading } = useContext(QcastContext) + const { setSurfaceShapePattern } = useRoofFn() //임시 const { selectedPlan } = usePlan() @@ -190,6 +192,14 @@ export default function CanvasMenu(props) { canvas.remove(moduleSurface) }) canvas.renderAll() + onClickNav(menu) + canvas + .getObjects() + .filter((obj) => obj.name === POLYGON_TYPE.ROOF) + .forEach((roof) => { + roof.set({ selectable: true }) + setSurfaceShapePattern(roof, null, false, roof.roofMaterial) + }) } setType('surface') }, From 6c0e9c5c0d66e26efb402f0814851466e0e55aba Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Fri, 21 Feb 2025 11:27:51 +0900 Subject: [PATCH 095/352] =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=A9=B4=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=8F=8C=EC=95=84=EC=98=A4=EB=8A=94=20=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0=20=EC=A7=80=EB=B6=95=20=EC=A0=95=EC=83=81=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index db11d3d1..8ccfff42 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -49,6 +49,7 @@ import JA from '@/locales/ja.json' import { QcastContext } from '@/app/QcastProvider' import { useRoofFn } from '@/hooks/common/useRoofFn' +import { usePolygon } from '@/hooks/usePolygon' export default function CanvasMenu(props) { const { menuNumber, setMenuNumber } = props const pathname = usePathname() @@ -106,6 +107,7 @@ export default function CanvasMenu(props) { const { setIsGlobalLoading } = useContext(QcastContext) const { setSurfaceShapePattern } = useRoofFn() + const { drawDirectionArrow } = usePolygon() //임시 const { selectedPlan } = usePlan() @@ -175,6 +177,17 @@ export default function CanvasMenu(props) { case 3: if (menuNumber > menu.index) { const modules = canvas.getObjects().filter((module) => module.name === POLYGON_TYPE.MODULE) + + canvas + .getObjects() + .filter((obj) => obj.name === POLYGON_TYPE.ROOF) + .forEach((roof) => { + roof.set({ selectable: true }) + delete roof.moduleCompass + drawDirectionArrow(roof) + setSurfaceShapePattern(roof, null, false, roof.roofMaterial) + }) + if (modules.length > 0) { swalFire({ text: getMessage('module.delete.confirm'), @@ -187,19 +200,13 @@ export default function CanvasMenu(props) { (obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE || obj.name === POLYGON_TYPE.MODULE || obj.name === POLYGON_TYPE.OBJECT_SURFACE, ) + if (moduleSurfacesArray.length > 0) { moduleSurfacesArray.forEach((moduleSurface) => { canvas.remove(moduleSurface) }) canvas.renderAll() onClickNav(menu) - canvas - .getObjects() - .filter((obj) => obj.name === POLYGON_TYPE.ROOF) - .forEach((roof) => { - roof.set({ selectable: true }) - setSurfaceShapePattern(roof, null, false, roof.roofMaterial) - }) } setType('surface') }, From dda24a11257f08cf3ebe403ef793ed58f49211a0 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Fri, 21 Feb 2025 11:34:08 +0900 Subject: [PATCH 096/352] =?UTF-8?q?=EB=AA=A8=EB=93=88=EB=A9=B4=20=EC=9E=88?= =?UTF-8?q?=EC=9D=84=20=EA=B2=BD=EC=9A=B0=EB=A7=8C=20=EC=A7=80=EB=B6=95?= =?UTF-8?q?=EB=A9=B4=20=ED=95=A0=EB=8B=B9=20=EB=8B=A4=EC=8B=9C=ED=95=B4?= =?UTF-8?q?=EC=95=BC=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 8ccfff42..99499e88 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -177,16 +177,12 @@ export default function CanvasMenu(props) { case 3: if (menuNumber > menu.index) { const modules = canvas.getObjects().filter((module) => module.name === POLYGON_TYPE.MODULE) + const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) - canvas - .getObjects() - .filter((obj) => obj.name === POLYGON_TYPE.ROOF) - .forEach((roof) => { - roof.set({ selectable: true }) - delete roof.moduleCompass - drawDirectionArrow(roof) - setSurfaceShapePattern(roof, null, false, roof.roofMaterial) - }) + roofs.forEach((roof) => { + delete roof.moduleCompass + drawDirectionArrow(roof) + }) if (modules.length > 0) { swalFire({ @@ -194,6 +190,7 @@ export default function CanvasMenu(props) { type: 'confirm', confirmFn: () => { //해당 메뉴 이동시 배치면 삭제 + const moduleSurfacesArray = canvas .getObjects() .filter( @@ -202,6 +199,11 @@ export default function CanvasMenu(props) { ) if (moduleSurfacesArray.length > 0) { + // 모듈면 있을 경우 지붕면 할당 다시해야함 + roofs.forEach((roof) => { + roof.set({ selectable: true }) + setSurfaceShapePattern(roof, null, false, roof.roofMaterial) + }) moduleSurfacesArray.forEach((moduleSurface) => { canvas.remove(moduleSurface) }) From 97d7798d565fffc7c4a2c9496fb4d58481fa71cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Fri, 21 Feb 2025 12:56:06 +0900 Subject: [PATCH 097/352] =?UTF-8?q?-=20=EB=B3=80=20=EC=86=8D=EC=84=B1?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=9D=BC=20surface=20margin=20=EA=B0=92?= =?UTF-8?q?=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 25 +++++++++++++++++++++-- src/hooks/useMode.js | 2 ++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 3c27393b..9fdab1f1 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -7,7 +7,7 @@ import offsetPolygon, { calculateAngle } from '@/util/qpolygon-utils' import { QPolygon } from '@/components/fabric/QPolygon' import { moduleSetupSurfaceState, moduleIsSetupState } from '@/store/canvasAtom' import { useEvent } from '@/hooks/useEvent' -import { POLYGON_TYPE, BATCH_TYPE } from '@/common/common' +import { POLYGON_TYPE, BATCH_TYPE, LINE_TYPE } from '@/common/common' import * as turf from '@turf/turf' import { useSwal } from '@/hooks/useSwal' import { compasDegAtom } from '@/store/orientationAtom' @@ -22,6 +22,7 @@ import { v4 as uuidv4 } from 'uuid' // import { useCircuitTrestle } from '@/hooks/useCirCuitTrestle' import { isObjectNotEmpty } from '@/util/common-utils' import { useCircuitTrestle } from '@/hooks/useCirCuitTrestle' +import { useMode } from '../useMode' export function useModuleBasicSetting(tabNum) { const canvas = useRecoilValue(canvasState) @@ -51,6 +52,7 @@ export function useModuleBasicSetting(tabNum) { const [currentObject, setCurrentObject] = useRecoilState(currentObjectState) const { setModuleStatisticsData } = useCircuitTrestle() + const { createRoofPolygon, createMarginPolygon } = useMode() useEffect(() => { // console.log('basicSetting', basicSetting) @@ -131,6 +133,7 @@ export function useModuleBasicSetting(tabNum) { //가대 상세 데이터 들어오면 실행 useEffect(() => { if (trestleDetailList.length > 0) { + console.log('trestleDetailList', trestleDetailList) //지붕을 가져옴 canvas .getObjects() @@ -143,6 +146,12 @@ export function useModuleBasicSetting(tabNum) { if (Number(detail.data.roofIndex) === roofIndex) { //roof에 상세 데이터 추가 roof.set({ trestleDetail: detail.data }) + roof.lines.forEach((line) => { + line.attributes = { + ...line.attributes, + offset: getOffset(detail.data, line.attributes.type), + } + }) //배치면 설치 영역 makeModuleInstArea(roof, detail.data) //surface에 상세 데이터 추가 @@ -153,6 +162,18 @@ export function useModuleBasicSetting(tabNum) { } }, [trestleDetailList]) + const getOffset = (data, type) => { + switch (type) { + case LINE_TYPE.WALLLINE.EAVES: + return data.eaveIntvl / 10 + case LINE_TYPE.WALLLINE.GABLE: + return data.kerabaIntvl / 10 + case LINE_TYPE.SUBLINE.RIDGE: + return data.ridgeIntvl / 10 + default: + return 60 + } + } //선택 배치면 배열` let selectedModuleInstSurfaceArray = [] @@ -220,7 +241,7 @@ export function useModuleBasicSetting(tabNum) { } else { let offsetLength = canvasSetting.roofSizeSet === '3' ? -30 : (trestleDetail.eaveIntvl / 10) * -1 setSurfaceShapePattern(roof, roofDisplay.column, true, roof.roofMaterial) //패턴 변경 - const offsetPoints = offsetPolygon(roof.points, offsetLength) //안쪽 offset + const offsetPoints = createMarginPolygon(createRoofPolygon(roof.getCurrentPoints()), roof.lines).vertices //안쪽 offset //모듈설치영역?? 생성 const surfaceId = uuidv4() diff --git a/src/hooks/useMode.js b/src/hooks/useMode.js index 06f1428a..4665baf8 100644 --- a/src/hooks/useMode.js +++ b/src/hooks/useMode.js @@ -5743,5 +5743,7 @@ export function useMode() { drawCellManualInTrestle, setDirectionTrestles, cutHelpLines, + createRoofPolygon, + createMarginPolygon, } } From 7b467a679637ac1cb6a0e1b0adf4ed1894440921 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Fri, 21 Feb 2025 13:14:29 +0900 Subject: [PATCH 098/352] =?UTF-8?q?-=201=EC=B0=A8=20=ED=86=B5=ED=95=A9?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8(Integration=20Test)=20#803=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 9fdab1f1..0babe2df 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -712,7 +712,7 @@ export function useModuleBasicSetting(tabNum) { canvas?.add(manualModule) manualDrawModules.push(manualModule) setModuleStatisticsData() - getModuleStatistics() + // getModuleStatistics() } else { swalFire({ text: getMessage('module.place.overlab') }) } @@ -2130,7 +2130,8 @@ export function useModuleBasicSetting(tabNum) { }) moduleSetupSurface.set({ modules: moduleSetupArray }) - getModuleStatistics() + // getModuleStatistics() + setModuleStatisticsData() // const moduleArray = [...moduleIsSetup] // moduleArray.push({ // surfaceId: moduleSetupSurface.surfaceId, @@ -2794,7 +2795,8 @@ export function useModuleBasicSetting(tabNum) { } }) } - getModuleStatistics() + // getModuleStatistics() + setModuleStatisticsData() } else { if (moduleSetupSurfaces) { //수동모드 해제시 모듈 설치면 선택 잠금 @@ -3210,7 +3212,8 @@ export function useModuleBasicSetting(tabNum) { }) moduleSetupSurface.set({ modules: setupedModules }) - getModuleStatistics() + setModuleStatisticsData() + // getModuleStatistics() // console.log('moduleSetupSurface', moduleSetupSurface) // console.log('setupedModules', setupedModules) From b0a24c7daf8912872fc03cd6ef1e8d6b8c4b60ca Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Fri, 21 Feb 2025 15:12:07 +0900 Subject: [PATCH 099/352] =?UTF-8?q?contextmenu=20roof=20=EB=B3=B5=EC=82=AC?= =?UTF-8?q?=20=ED=95=A0=20=EB=95=8C=20lines=20=EB=B3=B5=EC=82=AC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/common/useCommonUtils.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/hooks/common/useCommonUtils.js b/src/hooks/common/useCommonUtils.js index b7e944c5..538ee8c5 100644 --- a/src/hooks/common/useCommonUtils.js +++ b/src/hooks/common/useCommonUtils.js @@ -593,6 +593,11 @@ export function useCommonUtils() { clonedObj.setCoords() clonedObj.fire('polygonMoved') clonedObj.set({ direction: obj.direction, directionText: obj.directionText, roofMaterial: obj.roofMaterial }) + + obj.lines.forEach((line, index) => { + clonedObj.lines[index].set({ attributes: line.attributes }) + }) + canvas.renderAll() addLengthText(clonedObj) //수치 추가 drawDirectionArrow(clonedObj) //방향 화살표 추가 From 476e2f7cbc34398916680f241a9621332aa88cb0 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Fri, 21 Feb 2025 16:02:29 +0900 Subject: [PATCH 100/352] =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EC=84=A4=EC=B9=98?= =?UTF-8?q?=20=EC=98=81=EC=97=AD=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 10 ++++++++-- src/hooks/useMode.js | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 0babe2df..c5ef9667 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -52,7 +52,7 @@ export function useModuleBasicSetting(tabNum) { const [currentObject, setCurrentObject] = useRecoilState(currentObjectState) const { setModuleStatisticsData } = useCircuitTrestle() - const { createRoofPolygon, createMarginPolygon } = useMode() + const { createRoofPolygon, createMarginPolygon, createPaddingPolygon } = useMode() useEffect(() => { // console.log('basicSetting', basicSetting) @@ -241,7 +241,13 @@ export function useModuleBasicSetting(tabNum) { } else { let offsetLength = canvasSetting.roofSizeSet === '3' ? -30 : (trestleDetail.eaveIntvl / 10) * -1 setSurfaceShapePattern(roof, roofDisplay.column, true, roof.roofMaterial) //패턴 변경 - const offsetPoints = createMarginPolygon(createRoofPolygon(roof.getCurrentPoints()), roof.lines).vertices //안쪽 offset + let offsetPoints = null + + if (['south', 'west'].includes(roof.direction)) { + offsetPoints = createPaddingPolygon(createRoofPolygon(roof.getCurrentPoints()), roof.lines).vertices //안쪽 offset + } else { + offsetPoints = createMarginPolygon(createRoofPolygon(roof.getCurrentPoints()), roof.lines).vertices //안쪽 offset + } //모듈설치영역?? 생성 const surfaceId = uuidv4() diff --git a/src/hooks/useMode.js b/src/hooks/useMode.js index 4665baf8..392711b0 100644 --- a/src/hooks/useMode.js +++ b/src/hooks/useMode.js @@ -5745,5 +5745,6 @@ export function useMode() { cutHelpLines, createRoofPolygon, createMarginPolygon, + createPaddingPolygon, } } From 6401195debddd71dc7cb89f9da47db08c2e68094 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Fri, 21 Feb 2025 16:19:52 +0900 Subject: [PATCH 101/352] =?UTF-8?q?-=20=EC=9C=A1=EC=A7=80=EB=B6=95?= =?UTF-8?q?=EC=9D=BC=20=EB=95=8C=20=EC=84=A0=EC=86=8D=EC=84=B1=20=ED=8C=9D?= =?UTF-8?q?=EC=97=85=20=EC=95=88=EB=9C=A8=EA=B2=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useContextMenu.js | 72 +++++++++---------------------------- 1 file changed, 16 insertions(+), 56 deletions(-) diff --git a/src/hooks/useContextMenu.js b/src/hooks/useContextMenu.js index fcac9947..842cad28 100644 --- a/src/hooks/useContextMenu.js +++ b/src/hooks/useContextMenu.js @@ -1,5 +1,5 @@ import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' -import { canvasState, currentMenuState, currentObjectState } from '@/store/canvasAtom' +import { canvasSettingState, canvasState, currentMenuState, currentObjectState } from '@/store/canvasAtom' import { useEffect, useState } from 'react' import { MENU, POLYGON_TYPE } from '@/common/common' import AuxiliarySize from '@/components/floor-plan/modal/auxiliary/AuxiliarySize' @@ -41,9 +41,11 @@ import { useGrid } from './common/useGrid' import { useAdsorptionPoint } from './useAdsorptionPoint' import { useRoofFn } from '@/hooks/common/useRoofFn' import { MODULE_ALIGN_TYPE, useModule } from './module/useModule' +import PlacementSurfaceLineProperty from '@/components/floor-plan/modal/placementShape/PlacementSurfaceLineProperty' export function useContextMenu() { const canvas = useRecoilValue(canvasState) + const canvasSetting = useRecoilValue(canvasSettingState) const currentMenu = useRecoilValue(currentMenuState) // 현재 메뉴 const setContextPopupPosition = useSetRecoilState(contextPopupPositionState) // 현재 메뉴 const [contextMenu, setContextMenu] = useRecoilState(contextMenuListState) // 메뉴.object 별 context menu @@ -263,54 +265,6 @@ export function useContextMenu() { ], ]) break - case MENU.BATCH_CANVAS.SLOPE_SETTING: - case MENU.BATCH_CANVAS.BATCH_DRAWING: - case MENU.BATCH_CANVAS.SURFACE_SHAPE_BATCH: - case MENU.BATCH_CANVAS.OBJECT_BATCH: - case MENU.BATCH_CANVAS.ALL_REMOVE: - case MENU.BATCH_CANVAS.DEFAULT: - setContextMenu([ - [ - { - id: 'sizeEdit', - name: getMessage('contextmenu.size.edit'), - component: , - }, - { - id: 'remove', - shortcut: ['d', 'D'], - name: `${getMessage('contextmenu.remove')}(D)`, - }, - { - id: 'move', - shortcut: ['m', 'M'], - name: `${getMessage('contextmenu.move')}(M)`, - }, - { - id: 'copy', - shortcut: ['c', 'C'], - name: `${getMessage('contextmenu.copy')}(C)`, - }, - ], - [ - { - id: 'roofMaterialEdit', - name: getMessage('contextmenu.roof.material.edit'), - component: , - }, - { - id: 'linePropertyEdit', - name: getMessage('contextmenu.line.property.edit'), - component: , - }, - { - id: 'flowDirectionEdit', - name: getMessage('contextmenu.flow.direction.edit'), - component: , - }, - ], - ]) - break default: setContextMenu([]) break @@ -432,7 +386,14 @@ export function useContextMenu() { { id: 'linePropertyEdit', name: getMessage('contextmenu.line.property.edit'), - component: , + fn: () => { + if (+canvasSetting.roofSizeSet === 3) { + swalFire({ text: getMessage('contextmenu.line.property.edit.roof.size.3') }) + } else { + addPopup(popupId, 1, ) + } + }, + // component: , }, { id: 'flowDirectionEdit', @@ -740,24 +701,23 @@ export function useContextMenu() { ]) break case 'moduleSetupSurface': - case 'roof': setContextMenu([ [ { id: 'moduleVerticalCenterAlign', name: getMessage('contextmenu.module.vertical.align'), - fn: () => alignModule(MODULE_ALIGN_TYPE.VERTICAL, currentObject.arrayData), + fn: () => alignModule(MODULE_ALIGN_TYPE.VERTICAL, currentObject.arrayData ?? [currentObject]), }, { id: 'moduleHorizonCenterAlign', name: getMessage('contextmenu.module.horizon.align'), - fn: () => alignModule(MODULE_ALIGN_TYPE.HORIZONTAL, currentObject.arrayData), + fn: () => alignModule(MODULE_ALIGN_TYPE.HORIZONTAL, currentObject.arrayData ?? [currentObject]), }, { id: 'moduleRemove', name: getMessage('contextmenu.module.remove'), fn: () => { - moduleRoofRemove(currentObject.arrayData) + moduleRoofRemove(currentObject.arrayData ?? [currentObject]) // const moduleSetupSurface = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0] // const modules = canvas.getObjects().filter((obj) => obj.surfaceId === moduleSetupSurface.id && obj.name === POLYGON_TYPE.MODULE) @@ -768,12 +728,12 @@ export function useContextMenu() { { id: 'moduleMove', name: getMessage('contextmenu.module.move'), - component: , + component: , }, { id: 'moduleCopy', name: getMessage('contextmenu.module.copy'), - component: , + component: , }, // { // id: 'moduleCircuitNumberEdit', From 28640a700071e4d72810edaed18a80eb146797ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Fri, 21 Feb 2025 16:20:33 +0900 Subject: [PATCH 102/352] =?UTF-8?q?-=20api=20=EB=8D=B0=EC=9D=B4=ED=84=B0?= =?UTF-8?q?=20=EC=A4=91=20circuit=20=EC=A0=95=EB=B3=B4=20=EC=97=86?= =?UTF-8?q?=EB=8A=94=20module=20=EC=84=A4=EC=A0=95=EC=95=88=ED=95=98?= =?UTF-8?q?=EA=B2=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/circuitTrestle/step/StepUp.jsx | 54 ++++++++++--------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx b/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx index f3536bc9..8b519e86 100644 --- a/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx @@ -119,30 +119,32 @@ export default function StepUp(props) { // 새로운 모듈 회로 정보 추가 roofSurface.moduleList.forEach((module) => { - const targetModule = canvas.getObjects().filter((obj) => obj.id === module.uniqueId)[0] - const moduleCircuitText = new fabric.Text(module.circuit, { - left: targetModule.left + targetModule.width / 2, - top: targetModule.top + targetModule.height / 2, - fontFamily: circuitNumberText.fontFamily.value, - fontWeight: circuitNumberText.fontWeight.value.toLowerCase().includes('bold') ? 'bold' : 'normal', - fontStyle: circuitNumberText.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal', - fontSize: circuitNumberText.fontSize.value, - fill: circuitNumberText.fontColor.value, - width: targetModule.width, - height: targetModule.height, - textAlign: 'center', - originX: 'center', - originY: 'center', - name: 'circuitNumber', - parentId: targetModule.id, - circuitInfo: module.pcsItemId, - selectable: false, - visible: isDisplayCircuitNumber, - }) - targetModule.circuit = moduleCircuitText - targetModule.pcsItemId = module.pcsItemId - targetModule.circuitNumber = module.circuit - canvas.add(moduleCircuitText) + const targetModule = canvas.getObjects().find((obj) => obj.id === module.uniqueId) + if (targetModule && module.circuit !== '' && module.circuit) { + const moduleCircuitText = new fabric.Text(module.circuit, { + left: targetModule.left + targetModule.width / 2, + top: targetModule.top + targetModule.height / 2, + fontFamily: circuitNumberText.fontFamily.value, + fontWeight: circuitNumberText.fontWeight.value.toLowerCase().includes('bold') ? 'bold' : 'normal', + fontStyle: circuitNumberText.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal', + fontSize: circuitNumberText.fontSize.value, + fill: circuitNumberText.fontColor.value, + width: targetModule.width, + height: targetModule.height, + textAlign: 'center', + originX: 'center', + originY: 'center', + name: 'circuitNumber', + parentId: targetModule.id, + circuitInfo: module.pcsItemId, + selectable: false, + visible: isDisplayCircuitNumber, + }) + targetModule.circuit = moduleCircuitText + targetModule.pcsItemId = module.pcsItemId + targetModule.circuitNumber = module.circuit + canvas.add(moduleCircuitText) + } }) }) } @@ -441,8 +443,8 @@ export default function StepUp(props) { canvas.renderAll() roofSurface.moduleList.forEach((module) => { - const targetModule = canvas.getObjects().filter((obj) => obj.id === module.uniqueId)[0] - if (module.circuit !== '' && module.circuit) { + const targetModule = canvas.getObjects().find((obj) => obj.id === module.uniqueId) + if (targetModule && module.circuit !== '' && module.circuit !== null) { const moduleCircuitText = new fabric.Text(module.circuit, { left: targetModule.left + targetModule.width / 2, top: targetModule.top + targetModule.height / 2, From 5040f2171cb766b037d28065ec1d1a9978a2dee2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Fri, 21 Feb 2025 16:20:57 +0900 Subject: [PATCH 103/352] =?UTF-8?q?-=20module=20list=20=ED=83=90=EC=83=89?= =?UTF-8?q?=20=EB=B0=A9=EC=8B=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModule.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/hooks/module/useModule.js b/src/hooks/module/useModule.js index c7f13dc0..0c884608 100644 --- a/src/hooks/module/useModule.js +++ b/src/hooks/module/useModule.js @@ -822,10 +822,7 @@ export function useModule() { const alignModule = (type, surfaceArray) => { surfaceArray.forEach((surface) => { - const modules = canvas - .getObjects() - .filter((module) => module.name === POLYGON_TYPE.MODULE) - .filter((module) => module.surfaceId === surface.id) + const modules = surface.modules const objects = getObjects() let [top, bottom, left, right] = [0, 0, 0, 0] From 0ae09e17dd71a7a9b8c9a8375638217699bb3e9b Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Fri, 21 Feb 2025 17:09:46 +0900 Subject: [PATCH 104/352] =?UTF-8?q?=EC=A0=80=EC=9E=A5=20=ED=9B=84=20?= =?UTF-8?q?=EB=B6=88=EB=9F=AC=EC=98=AC=20=EB=95=8C=20lines=20attributes=20?= =?UTF-8?q?=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/fabric/QPolygon.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/components/fabric/QPolygon.js b/src/components/fabric/QPolygon.js index b0c46798..b8c3bbed 100644 --- a/src/components/fabric/QPolygon.js +++ b/src/components/fabric/QPolygon.js @@ -162,9 +162,10 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, { }, initLines() { - // if (this.lines.length > 0) { - // return - // } + let attributes = null + if (this.lines.length > 0) { + attributes = this.lines.map((line) => line.attributes) + } this.lines = [] @@ -174,9 +175,11 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, { stroke: this.stroke, strokeWidth: this.strokeWidth, fontSize: this.fontSize, - attributes: { - offset: 0, - }, + attributes: attributes + ? attributes[i] + : { + offset: 0, + }, textVisible: false, parent: this, parentId: this.id, From e99236fd3066150abcd5d2a976ff8a28d6108430 Mon Sep 17 00:00:00 2001 From: changkyu choi Date: Fri, 21 Feb 2025 17:29:49 +0900 Subject: [PATCH 105/352] =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=A9=B4=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=EC=84=A4=EC=A0=95=20=EB=AF=B8=EC=A0=80=EC=9E=A5=20pla?= =?UTF-8?q?n=EC=97=90=EC=84=9C=20=EC=A0=80=EC=9E=A5=ED=95=9C=20plan=20=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=20=EC=8B=9C=20=EB=B0=B0=EC=B9=98=EB=A9=B4?= =?UTF-8?q?=EC=B4=88=EA=B8=B0=EC=84=A4=EC=A0=95=20=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?=EB=8B=AB=ED=9E=98=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../placementShape/PlacementShapeSetting.jsx | 4 ++++ src/hooks/option/useCanvasSetting.js | 21 ++++++++++++------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx index 05880782..ed400f95 100644 --- a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx @@ -33,6 +33,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla const { findCommonCode } = useCommonCode() const [raftCodes, setRaftCodes] = useState([]) // 서까래 정보 const [currentRoof, setCurrentRoof] = useState(null) // 현재 선택된 지붕재 정보 + const { closePopup } = usePopup() // usePopup에서 closeAll 함수 가져오기 const roofRef = { roofCd: useRef(null), @@ -213,6 +214,9 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla roofInfo, }, }) + + /* 저장 후 화면 닫기 */ + closePopup(id) } return ( diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js index 37161700..255cc9ee 100644 --- a/src/hooks/option/useCanvasSetting.js +++ b/src/hooks/option/useCanvasSetting.js @@ -139,7 +139,7 @@ export function useCanvasSetting() { const selectedRoofMaterial = useRecoilValue(selectedRoofMaterialSelector) // 선택된 지붕재 정보 const { floorPlanState } = useContext(FloorPlanContext) // 플랜 상태 - const { closeAll } = usePopup() // 팝업 닫기 + const { closePopup } = usePopup() // 팝업 닫기 useEffect(() => { const tempFetchRoofMaterials = !fetchRoofMaterials @@ -338,6 +338,11 @@ export function useCanvasSetting() { roofAngle: item.roofAngle, } }) + + /* 데이터 존재 시 화면 닫기(메뉴/저장 클릭 시 제외) */ + if (openPoint !== 'canvasMenus' && openPoint !== 'basicSettingSave') { + closePopup(popupId) + } } else { roofsRow = [ { @@ -475,11 +480,8 @@ export function useCanvasSetting() { roofSizeSet: String(params.roofSizeSet), }) - /* 배치면초기설정 조회 */ - fetchBasicSettings(params.planNo, null) - /* 메뉴 설정 */ - if (['2', '3'].includes(basicSetting?.roofSizeSet)) { + if (['2', '3'].includes(params.roofSizeSet)) { setMenuNumber(3) setType('surface') setCurrentMenu(MENU.BATCH_CANVAS.BATCH_DRAWING) @@ -489,6 +491,9 @@ export function useCanvasSetting() { setCurrentMenu(MENU.ROOF_COVERING.EXTERIOR_WALL_LINE) } + /* 배치면초기설정 조회 */ + fetchBasicSettings(params.planNo, 'basicSettingSave') + /* 모듈 선택 데이터 초기화 */ resetModuleSelectionData() moduleSelectedDataTrigger({ common: {}, module: {}, roofConstructions: [] }) @@ -536,9 +541,6 @@ export function useCanvasSetting() { roofSizeSet: String(params.roofSizeSet), }) - /* 배치면초기설정 조회 */ - fetchBasicSettings(Number(params.planNo), null) - /* 메뉴 설정 */ if (['2', '3'].includes(params?.roofSizeSet)) { setMenuNumber(3) @@ -550,6 +552,9 @@ export function useCanvasSetting() { setCurrentMenu(MENU.ROOF_COVERING.EXTERIOR_WALL_LINE) } + /* 배치면초기설정 조회 */ + fetchBasicSettings(Number(params.planNo), null) + /* 모듈 선택 데이터 초기화 */ resetModuleSelectionData() moduleSelectedDataTrigger({ common: {}, module: {}, roofConstructions: [] }) From a7d9c7e5549441c462545d22d4b548051fba6c86 Mon Sep 17 00:00:00 2001 From: changkyu choi Date: Fri, 21 Feb 2025 18:05:44 +0900 Subject: [PATCH 106/352] =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=A9=B4=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=EC=84=A4=EC=A0=95=20=EB=AF=B8=EC=A0=80=EC=9E=A5=20pla?= =?UTF-8?q?n=EC=97=90=EC=84=9C=20=EC=A0=80=EC=9E=A5=ED=95=9C=20plan=20=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=20=EC=8B=9C=20=EB=B0=B0=EC=B9=98=EB=A9=B4?= =?UTF-8?q?=EC=B4=88=EA=B8=B0=EC=84=A4=EC=A0=95=20=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?=EB=8B=AB=ED=9E=98=20=EC=B2=98=EB=A6=AC=20closeAll=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/option/useCanvasSetting.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js index 255cc9ee..8cdecf1c 100644 --- a/src/hooks/option/useCanvasSetting.js +++ b/src/hooks/option/useCanvasSetting.js @@ -139,7 +139,7 @@ export function useCanvasSetting() { const selectedRoofMaterial = useRecoilValue(selectedRoofMaterialSelector) // 선택된 지붕재 정보 const { floorPlanState } = useContext(FloorPlanContext) // 플랜 상태 - const { closePopup } = usePopup() // 팝업 닫기 + const { closePopup, closeAll } = usePopup() // 팝업 닫기 useEffect(() => { const tempFetchRoofMaterials = !fetchRoofMaterials @@ -341,7 +341,8 @@ export function useCanvasSetting() { /* 데이터 존재 시 화면 닫기(메뉴/저장 클릭 시 제외) */ if (openPoint !== 'canvasMenus' && openPoint !== 'basicSettingSave') { - closePopup(popupId) + //closePopup(popupId) + closeAll() } } else { roofsRow = [ @@ -553,7 +554,7 @@ export function useCanvasSetting() { } /* 배치면초기설정 조회 */ - fetchBasicSettings(Number(params.planNo), null) + fetchBasicSettings(Number(params.planNo), 'basicSettingSave') /* 모듈 선택 데이터 초기화 */ resetModuleSelectionData() From 36497d5594327867cc6cfbdf7c9bed5d6d787c4f Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Mon, 24 Feb 2025 10:11:30 +0900 Subject: [PATCH 107/352] =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=A9=B4=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B4=EB=8F=99=20=EC=8B=9C=20=EC=BB=A8=ED=8E=8C?= =?UTF-8?q?=20=ED=99=95=EC=9D=B8=20=EB=88=8C=EB=A0=80=EC=9D=84=EB=95=8C?= =?UTF-8?q?=EB=A7=8C=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 99499e88..b6b4520f 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -179,11 +179,6 @@ export default function CanvasMenu(props) { const modules = canvas.getObjects().filter((module) => module.name === POLYGON_TYPE.MODULE) const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) - roofs.forEach((roof) => { - delete roof.moduleCompass - drawDirectionArrow(roof) - }) - if (modules.length > 0) { swalFire({ text: getMessage('module.delete.confirm'), @@ -191,6 +186,13 @@ export default function CanvasMenu(props) { confirmFn: () => { //해당 메뉴 이동시 배치면 삭제 + roofs.forEach((roof) => { + roof.set({ selectable: true }) + setSurfaceShapePattern(roof, null, false, roof.roofMaterial) + delete roof.moduleCompass + drawDirectionArrow(roof) + }) + const moduleSurfacesArray = canvas .getObjects() .filter( @@ -200,10 +202,6 @@ export default function CanvasMenu(props) { if (moduleSurfacesArray.length > 0) { // 모듈면 있을 경우 지붕면 할당 다시해야함 - roofs.forEach((roof) => { - roof.set({ selectable: true }) - setSurfaceShapePattern(roof, null, false, roof.roofMaterial) - }) moduleSurfacesArray.forEach((moduleSurface) => { canvas.remove(moduleSurface) }) From eb48e11a5d693c0a0196d96d315d00173bda98f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Mon, 24 Feb 2025 10:11:50 +0900 Subject: [PATCH 108/352] =?UTF-8?q?-=20surface=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EC=8B=9C=20padding=20/=20margin=20polygon=20=EA=B2=80=EC=A6=9D?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index c5ef9667..53b03c01 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -171,7 +171,7 @@ export function useModuleBasicSetting(tabNum) { case LINE_TYPE.SUBLINE.RIDGE: return data.ridgeIntvl / 10 default: - return 60 + return 60 / 10 } } //선택 배치면 배열` @@ -241,13 +241,23 @@ export function useModuleBasicSetting(tabNum) { } else { let offsetLength = canvasSetting.roofSizeSet === '3' ? -30 : (trestleDetail.eaveIntvl / 10) * -1 setSurfaceShapePattern(roof, roofDisplay.column, true, roof.roofMaterial) //패턴 변경 + // let offsetPoints = createPaddingPolygon(createRoofPolygon(roof.points), roof.lines).vertices //안쪽 offset let offsetPoints = null + console.log(roof, roof.getCurrentPoints()) + const polygon = createRoofPolygon(roof.getCurrentPoints()) + const originPolygon = new QPolygon(roof.getCurrentPoints(), { fontSize: 0 }) - if (['south', 'west'].includes(roof.direction)) { - offsetPoints = createPaddingPolygon(createRoofPolygon(roof.getCurrentPoints()), roof.lines).vertices //안쪽 offset + let result = createPaddingPolygon(polygon, roof.lines).vertices + + //margin polygon 의 point가 기준 polygon의 밖에 있는지 판단한다. + const allPointsOutside = result.every((point) => !originPolygon.inPolygon(point)) + + if (allPointsOutside) { + offsetPoints = createMarginPolygon(polygon, roof.lines).vertices } else { - offsetPoints = createMarginPolygon(createRoofPolygon(roof.getCurrentPoints()), roof.lines).vertices //안쪽 offset + offsetPoints = createPaddingPolygon(polygon, roof.lines).vertices } + //모듈설치영역?? 생성 const surfaceId = uuidv4() From 864243e80bee4d054045933829c94476f5c52a59 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Mon, 24 Feb 2025 10:31:11 +0900 Subject: [PATCH 109/352] =?UTF-8?q?fontSize=EA=B0=80=20=EC=97=86=EB=8A=94?= =?UTF-8?q?=20=EA=B2=BD=EC=9A=B0=20lengthText=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/fabric/QPolygon.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/fabric/QPolygon.js b/src/components/fabric/QPolygon.js index b8c3bbed..2ec45422 100644 --- a/src/components/fabric/QPolygon.js +++ b/src/components/fabric/QPolygon.js @@ -276,6 +276,10 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, { if ([POLYGON_TYPE.MODULE, 'arrow', POLYGON_TYPE.MODULE_SETUP_SURFACE, POLYGON_TYPE.OBJECT_SURFACE].includes(this.name)) { return } + + if (!this.fontSize) { + return + } this.canvas ?.getObjects() .filter((obj) => obj.name === 'lengthText' && obj.parentId === this.id) From d9d929033be4b7b25cca688f28050986067e0337 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Mon, 24 Feb 2025 10:52:41 +0900 Subject: [PATCH 110/352] =?UTF-8?q?=EB=AA=A8=EB=93=88=EC=9D=B4=20=EC=97=86?= =?UTF-8?q?=EC=9D=84=20=EA=B2=BD=EC=9A=B0=EC=97=90=EB=8F=84=20=EC=9B=90?= =?UTF-8?q?=EB=B3=B5=20=ED=95=84=EC=9A=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index b6b4520f..924bfa95 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -177,7 +177,6 @@ export default function CanvasMenu(props) { case 3: if (menuNumber > menu.index) { const modules = canvas.getObjects().filter((module) => module.name === POLYGON_TYPE.MODULE) - const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) if (modules.length > 0) { swalFire({ @@ -185,7 +184,7 @@ export default function CanvasMenu(props) { type: 'confirm', confirmFn: () => { //해당 메뉴 이동시 배치면 삭제 - + const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) roofs.forEach((roof) => { roof.set({ selectable: true }) setSurfaceShapePattern(roof, null, false, roof.roofMaterial) @@ -315,6 +314,13 @@ export default function CanvasMenu(props) { if (menuNumber === 3) { const moduleSurfacesArray = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) if (moduleSurfacesArray.length > 0) { + const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) + roofs.forEach((roof) => { + roof.set({ selectable: true }) + setSurfaceShapePattern(roof, null, false, roof.roofMaterial) + delete roof.moduleCompass + drawDirectionArrow(roof) + }) moduleSurfacesArray.forEach((moduleSurface) => { moduleSurface.modules = [] canvas.remove(moduleSurface) From 3efec0ace584f958790679c87d94612626653f1d Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Mon, 24 Feb 2025 10:53:16 +0900 Subject: [PATCH 111/352] =?UTF-8?q?=F0=9F=9A=A6fix:=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EC=A3=BC=EC=84=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 주석 및 설명 추가 --- src/app/layout.js | 9 +++++++++ src/components/common/spinner/GlobalSpinner.jsx | 5 +++++ src/components/floor-plan/modal/ImgLoad.jsx | 4 ++++ src/hooks/common/useMenu.js | 4 ++++ src/hooks/common/useRefFiles.js | 4 ++++ src/hooks/usePlan.js | 6 ++++++ src/lib/imageActions.js | 13 +++++++++++++ 7 files changed, 45 insertions(+) diff --git a/src/app/layout.js b/src/app/layout.js index c88dd7d8..a77f926c 100644 --- a/src/app/layout.js +++ b/src/app/layout.js @@ -16,11 +16,20 @@ import '../styles/contents.scss' import Footer from '@/components/footer/Footer' import GlobalLoadingProvider from './GlobalLoadingProvider' +/** + * 어플리케이션 메타데이터 + * 서버 컴포넌트에 한해서 개별로 설정할 수 있음 + */ export const metadata = { title: 'HANASYS設計', description: 'HANASYS設計', } +/** + * 어플리케이션 전체 레이아웃 컴포넌트 + * @param {*} param0 + * @returns + */ export default async function RootLayout({ children }) { const headersList = headers() const headerPathname = headersList.get('x-pathname') || '' diff --git a/src/components/common/spinner/GlobalSpinner.jsx b/src/components/common/spinner/GlobalSpinner.jsx index 1da91ef9..458bcabb 100644 --- a/src/components/common/spinner/GlobalSpinner.jsx +++ b/src/components/common/spinner/GlobalSpinner.jsx @@ -2,6 +2,11 @@ import '@/styles/spinner.scss' +/** + * 전역 스피너 + * 전역 로딩 스피너 + * @returns + */ export default function GlobalSpinner() { return ( <> diff --git a/src/components/floor-plan/modal/ImgLoad.jsx b/src/components/floor-plan/modal/ImgLoad.jsx index 04127bba..b33871ef 100644 --- a/src/components/floor-plan/modal/ImgLoad.jsx +++ b/src/components/floor-plan/modal/ImgLoad.jsx @@ -12,6 +12,10 @@ import { useCanvas } from '@/hooks/useCanvas' import { useImgLoader } from '@/hooks/floorPlan/useImgLoader' // import { initImageLoaderPopup } from '@/lib/planAction' +/** + * 이미지 로드 모달 + * @returns + */ export default function ImgLoad() { const { currentCanvasPlan, setCurrentCanvasPlan } = usePlan() const { getMessage } = useMessage() diff --git a/src/hooks/common/useMenu.js b/src/hooks/common/useMenu.js index 84c8cef7..d65611b5 100644 --- a/src/hooks/common/useMenu.js +++ b/src/hooks/common/useMenu.js @@ -23,6 +23,10 @@ import { useTrestle } from '@/hooks/module/useTrestle' import { usePolygon } from '@/hooks/usePolygon' import { useOrientation } from '@/hooks/module/useOrientation' +/** + * 메뉴 처리 훅 + * @returns + */ export default function useMenu() { const menus = [] const currentMenu = useRecoilValue(currentMenuState) diff --git a/src/hooks/common/useRefFiles.js b/src/hooks/common/useRefFiles.js index 52f8ef47..b21cc954 100644 --- a/src/hooks/common/useRefFiles.js +++ b/src/hooks/common/useRefFiles.js @@ -11,6 +11,10 @@ import { settingModalFirstOptionsState } from '@/store/settingAtom' /** * 배경 이미지 관리 * 도면에 배경이미지를 로딩하는 기능을 제공 + * + * 이미지 -> 캔버스 배경에 이미지 로드 + * 주소 -> 구글 맵에서 주소 검색 후 이미지로 다운로드 받아서 캔버스 배경에 이미지 로드 + * .dwg -> api를 통해서 .png로 변환 후 캔버스 배경에 이미지 로드 * @returns {object} */ export function useRefFiles() { diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js index 10bc7e45..c422b7f5 100644 --- a/src/hooks/usePlan.js +++ b/src/hooks/usePlan.js @@ -17,6 +17,12 @@ import { outerLinePointsState } from '@/store/outerLineAtom' import { placementShapeDrawingPointsState } from '@/store/placementShapeDrawingAtom' import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' +/** + * 플랜 처리 훅 + * 플랜을 표시하는 탭 UI 전반적인 처리 로직 관리 + * @param {*} params + * @returns + */ export function usePlan(params = {}) { const { floorPlanState } = useContext(FloorPlanContext) diff --git a/src/lib/imageActions.js b/src/lib/imageActions.js index f3276d64..b085b1a2 100644 --- a/src/lib/imageActions.js +++ b/src/lib/imageActions.js @@ -3,6 +3,10 @@ import sqlite3 from 'sqlite3' import { open } from 'sqlite' +/** + * 캔바스 배경 이미지가 설정되면 데이터를 저장한다. + * @param {*} param0 + */ export const setBackGroundImage = async ({ objectId, planNo, imagePath }) => { let db = null @@ -24,6 +28,11 @@ export const setBackGroundImage = async ({ objectId, planNo, imagePath }) => { } } +/** + * 캔바스 배경 이미지 데이터를 조회한다. + * @param {*} param0 + * @returns + */ export const getBackGroundImage = async ({ objectId, planNo }) => { let db = null @@ -39,6 +48,10 @@ export const getBackGroundImage = async ({ objectId, planNo }) => { return result } +/** + * 캔바스 배경 이미지 데이터를 삭제한다. + * @param {*} param0 + */ export const deleteBackGroundImage = async ({ objectId, planNo }) => { let db = null From 1f535297ce3db4c7604a74943d5f10b9acb09cf1 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Mon, 24 Feb 2025 11:18:36 +0900 Subject: [PATCH 112/352] =?UTF-8?q?=EC=A7=80=EB=B6=95=20=EC=B4=88=EA=B8=B0?= =?UTF-8?q?=ED=99=94=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 27 ++++++++++++------------ 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 924bfa95..4546034e 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -153,6 +153,17 @@ export default function CanvasMenu(props) { setIsGlobalLoading(false) } + // roof 초기화 + const initRoofs = () => { + const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) + roofs.forEach((roof) => { + roof.set({ selectable: true }) + setSurfaceShapePattern(roof, null, false, roof.roofMaterial) + delete roof.moduleCompass + drawDirectionArrow(roof) + }) + } + const onClickNav = async (menu) => { switch (menu.index) { case 0: @@ -184,13 +195,7 @@ export default function CanvasMenu(props) { type: 'confirm', confirmFn: () => { //해당 메뉴 이동시 배치면 삭제 - const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) - roofs.forEach((roof) => { - roof.set({ selectable: true }) - setSurfaceShapePattern(roof, null, false, roof.roofMaterial) - delete roof.moduleCompass - drawDirectionArrow(roof) - }) + initRoofs() const moduleSurfacesArray = canvas .getObjects() @@ -314,13 +319,7 @@ export default function CanvasMenu(props) { if (menuNumber === 3) { const moduleSurfacesArray = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) if (moduleSurfacesArray.length > 0) { - const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) - roofs.forEach((roof) => { - roof.set({ selectable: true }) - setSurfaceShapePattern(roof, null, false, roof.roofMaterial) - delete roof.moduleCompass - drawDirectionArrow(roof) - }) + initRoofs() moduleSurfacesArray.forEach((moduleSurface) => { moduleSurface.modules = [] canvas.remove(moduleSurface) From 6b3d0918488b16bd365681bf649e7d031793875c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Mon, 24 Feb 2025 13:20:13 +0900 Subject: [PATCH 113/352] =?UTF-8?q?-=20=EC=B4=88=EA=B8=B0=ED=99=94?= =?UTF-8?q?=EC=8B=9C=20=ED=9A=8C=EB=A1=9C=EB=B2=88=ED=98=B8=20infinity=20?= =?UTF-8?q?=EB=A1=9C=20=ED=91=9C=EA=B8=B0=EB=90=98=EB=8A=94=20=EB=B6=80?= =?UTF-8?q?=EB=B6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../circuitTrestle/step/type/PassivityCircuitAllocation.jsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx b/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx index a526f05a..69f5383e 100644 --- a/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx @@ -284,6 +284,9 @@ export default function PassivityCircuitAllocation(props) { icon: 'warning', confirmFn: () => { const circuitModules = canvas.getObjects().filter((obj) => obj.name === 'module' && obj.circuit?.circuitInfo?.id === selectedPcs.id) + if (circuitModules.length === 0) { + return + } const circuitNumbers = circuitModules.map((obj) => { const circuitNumber = obj.circuitNumber.replace(/[()]/g, '').split('-') return parseInt(circuitNumber[0]) From aa2425bf812ec884872b0a1f0a72cd49ece0b0fc Mon Sep 17 00:00:00 2001 From: yjnoh Date: Mon, 24 Feb 2025 13:33:20 +0900 Subject: [PATCH 114/352] =?UTF-8?q?=EC=9C=A1=EC=A7=80=EB=B6=95=20=EB=AA=A8?= =?UTF-8?q?=EB=93=88=20=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/basic/step/pitch/PitchModule.jsx | 8 +- .../modal/basic/step/pitch/PitchPlacement.jsx | 8 +- src/hooks/module/useModuleBasicSetting.js | 202 +++++++++++++----- src/util/qpolygon-utils.js | 15 ++ 4 files changed, 177 insertions(+), 56 deletions(-) diff --git a/src/components/floor-plan/modal/basic/step/pitch/PitchModule.jsx b/src/components/floor-plan/modal/basic/step/pitch/PitchModule.jsx index 39d0ee19..e248c272 100644 --- a/src/components/floor-plan/modal/basic/step/pitch/PitchModule.jsx +++ b/src/components/floor-plan/modal/basic/step/pitch/PitchModule.jsx @@ -47,17 +47,17 @@ export default function PitchModule({}) { setSelectedModules(option) //선택값 저장 setModuleSelectionData({ ...moduleSelectionData, - flatModule: option, + module: option, }) moduleSelectedDataTrigger({ ...moduleSelectionData, - flatModule: option, + module: option, }) } useEffect(() => { - if (isObjectNotEmpty(moduleSelectionData.flatModule) && moduleList.length > 0) { - handleChangeModule(moduleSelectionData.flatModule) + if (isObjectNotEmpty(moduleSelectionData.module) && moduleList.length > 0) { + handleChangeModule(moduleSelectionData.module) } }, [moduleList]) diff --git a/src/components/floor-plan/modal/basic/step/pitch/PitchPlacement.jsx b/src/components/floor-plan/modal/basic/step/pitch/PitchPlacement.jsx index 64d91881..b4137ac6 100644 --- a/src/components/floor-plan/modal/basic/step/pitch/PitchPlacement.jsx +++ b/src/components/floor-plan/modal/basic/step/pitch/PitchPlacement.jsx @@ -69,7 +69,7 @@ const PitchPlacement = forwardRef((props, refs) => { excretaLine.forEach((line) => { line.set({ stroke: '#642EFB', - strokeWidth: 5, + strokeWidth: 3, surfaceId: surface.surfaceId, name: 'flatExcretaLine', }) @@ -89,10 +89,10 @@ const PitchPlacement = forwardRef((props, refs) => { } useEffect(() => { - if (!moduleSelectionData.flatModule) return // null 오류 차단 로직 추가 - if (moduleSelectionData && moduleSelectionData.flatModule.itemList.length > 0) { + if (!moduleSelectionData.module) return // null 오류 차단 로직 추가 + if (moduleSelectionData && moduleSelectionData.module.itemList.length > 0) { let initCheckedModule = {} - moduleSelectionData.flatModule.itemList.forEach((obj, index) => { + moduleSelectionData.module.itemList.forEach((obj, index) => { if (index === 0) { initCheckedModule = { [obj.itemId]: true } } else { diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 7d99f9b1..d96b96a1 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -3,7 +3,7 @@ import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' import { canvasSettingState, canvasState, checkedModuleState, currentObjectState, isManualModuleSetupState } from '@/store/canvasAtom' import { rectToPolygon, polygonToTurfPolygon, calculateVisibleModuleHeight, getDegreeByChon } from '@/util/canvas-util' import { addedRoofsState, basicSettingState, roofDisplaySelector } from '@/store/settingAtom' -import offsetPolygon, { calculateAngle } from '@/util/qpolygon-utils' +import offsetPolygon, { calculateAngle, createLinesFromPolygon } from '@/util/qpolygon-utils' import { QPolygon } from '@/components/fabric/QPolygon' import { moduleSetupSurfaceState, moduleIsSetupState } from '@/store/canvasAtom' import { useEvent } from '@/hooks/useEvent' @@ -239,7 +239,6 @@ export function useModuleBasicSetting(tabNum) { toggleSelection(isExistSurface) }) } else { - let offsetLength = canvasSetting.roofSizeSet === '3' ? -30 : (trestleDetail.eaveIntvl / 10) * -1 setSurfaceShapePattern(roof, roofDisplay.column, true, roof.roofMaterial) //패턴 변경 // let offsetPoints = createPaddingPolygon(createRoofPolygon(roof.points), roof.lines).vertices //안쪽 offset let offsetPoints = null @@ -252,10 +251,16 @@ export function useModuleBasicSetting(tabNum) { //margin polygon 의 point가 기준 polygon의 밖에 있는지 판단한다. const allPointsOutside = result.every((point) => !originPolygon.inPolygon(point)) - if (allPointsOutside) { - offsetPoints = createMarginPolygon(polygon, roof.lines).vertices + if (canvasSetting.roofSizeSet == '3') { + //육지붕일때는 그냥 하드코딩 + offsetPoints = offsetPolygon(roof.points, -30) //육지붕일때 } else { - offsetPoints = createPaddingPolygon(polygon, roof.lines).vertices + //육지붕이 아닐때 + if (allPointsOutside) { + offsetPoints = createMarginPolygon(polygon, roof.lines).vertices + } else { + offsetPoints = createPaddingPolygon(polygon, roof.lines).vertices + } } //모듈설치영역?? 생성 @@ -263,7 +268,7 @@ export function useModuleBasicSetting(tabNum) { const surfaceId = uuidv4() let isNorth = false - if (canvasSetting.roofSizeSet !== '3') { + if (canvasSetting.roofSizeSet != '3') { //북면이 있지만 if (roof.directionText && roof.directionText.indexOf('北') > -1) { //북쪽일때 해당 서북서, 동북동은 제외한다고 한다 @@ -2895,8 +2900,13 @@ export function useModuleBasicSetting(tabNum) { targetRoof.angle = -angle targetSurface.angle = -angle + const newLines = createLinesFromPolygon(targetSurface.getCurrentPoints()) + targetSurface.set({ lines: newLines }) + targetRoof.fire('modified') targetSurface.fire('modified') + targetRoof.setCoords() + targetSurface.setCoords() moduleSetupSurfaces.push(targetSurface) } canvas.remove(obj) @@ -2990,37 +3000,92 @@ export function useModuleBasicSetting(tabNum) { let moduleGroup = [] - const flatRoofDownFlowSetupModule = (surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight) => { - checkedModule.forEach((module, index) => { - const { width, height } = getModuleWidthHeight(maxLengthLine, moduleSetupSurface, module) + const flatRoofDownFlowSetupModule = ( + surfaceMaxLines, + maxLengthLine, + moduleSetupArray, + moduleSetupSurface, + intvHor, + intvVer, + containsBatchObjects, + ) => { + let setupModule = [] - const flowLines = getFlowLines(moduleSetupSurface, height) + let installedLastHeightCoord = 0 //마지막으로 설치된 모듈의 좌표 + let installedModuleHeightCount = 0 //마지막으로 설치된 모듈의 카운트 + let flowLines - let startPoint = flowLines.bottom + checkedModule.forEach((module, moduleIndex) => { + //모듈의 넓이 높이를 가져옴 (복시도 촌수 적용) + //1번 깔았던 모듈 기준으로 잡야아함 + let { width, height } = getModuleWidthHeight(maxLengthLine, moduleSetupSurface, module) - const maxLeftEndPoint = surfaceMaxLines.left.x1 //최 좌측 - const maxRightEndPoint = surfaceMaxLines.right.x1 //최 우측 - const maxTopEndPoint = surfaceMaxLines.top.y1 //최 상단 + if (moduleIndex === 0) { + flowLines = getFlowLines(moduleSetupSurface, height) + if (flowLines.bottom.type === 'curve') { + flowLines = getFlowLines(moduleSetupSurface, width) + } + } - let totalLeftEndPoint = maxLeftEndPoint - startPoint.x1 - let totalTopEndPoint = maxTopEndPoint - startPoint.y1 - let totalWidth = Math.ceil(Math.abs(maxRightEndPoint - maxLeftEndPoint) / width) - let diffLeftEndPoint = Math.abs(totalLeftEndPoint / width) - let diffTopEndPoint = Math.abs(totalTopEndPoint / height) - let startColPoint = Math.abs(width * Math.ceil(diffLeftEndPoint) - startPoint.x1) - let tempMaxWidth = width //최대배치인지 확인하려고 넣음 + //육지붕이 아닐때만 넣는다 육지붕일땐 클릭 이벤트에 별도로 넣어놓음 + const moduleArray = [] - for (let j = 0; j < diffTopEndPoint; j++) { - bottomMargin = marginHeight * j - for (let i = 0; i <= totalWidth; i++) { - leftMargin = marginWidth * i + let calcAreaWidth = flowLines.right.x1 - flowLines.left.x1 //오른쪽 x에서 왼쪽 x를 뺀 가운데를 찾는 로직 + let calcModuleWidthCount = calcAreaWidth / (width + intvHor) //뺀 공간에서 모듈을 몇개를 넣을수 있는지 확인하는 로직 + let calcMaxModuleWidthCount = calcModuleWidthCount //최대 모듈 단수가 있기 때문에 최대 단수보다 카운트가 크면 최대 단수로 씀씀 + let totalModuleWidthCount = Math.floor(calcMaxModuleWidthCount) //치조배치일경우는 한개 더 넣는다 - square = [ - [startColPoint + tempMaxWidth * i + leftMargin, startPoint.y1 - height * j - bottomMargin], - [startColPoint + tempMaxWidth * i + width + leftMargin, startPoint.y1 - height * j - bottomMargin], - [startColPoint + tempMaxWidth * i + width + leftMargin, startPoint.y1 - height * j - height - bottomMargin], - [startColPoint + tempMaxWidth * i + leftMargin, startPoint.y1 - height * j - height - bottomMargin], - [startColPoint + tempMaxWidth * i + leftMargin, startPoint.y1 - height * j - bottomMargin], + let calcAreaheight = flowLines.bottom.y1 - flowLines.top.y1 //오른쪽 y에서 왼쪽 y를 뺀 가운데를 찾는 로직 + let calcModuleHeightCount = calcAreaheight / (height + intvVer) //뺀 공간에서 모듈을 몇개를 넣을수 있는지 확인하는 로직 + let calcMaxModuleHeightCount = calcModuleHeightCount //최대 모듈 단수가 있기 때문에 최대 단수보다 카운트가 크면 최대 단수로 씀씀 + let totalModuleHeightCount = Math.floor(calcMaxModuleHeightCount) //치조배치일경우는 한개 더 넣는다 + + let calcStartPoint = flowLines.right.type === 'flat' ? (calcAreaWidth - totalModuleWidthCount * width) / 2 : 0 //반씩 나눠서 중앙에 맞춤 bottom 기준으로 양변이 직선일때만 가운데 정렬 + let startPointX = flowLines.left.x1 + calcStartPoint //시작점을 만든다 + + //근데 양변이 곡선이면 중앙에 맞추기 위해 아래와 위의 길이를 재서 모듈의 길이를 나눠서 들어갈수 있는 갯수가 동일하면 가운데로 정렬 시킨다 + if (flowLines.left.type === 'curve' && flowLines.right.type === 'curve') { + startPointX = flowLines.left.x1 + (calcAreaWidth - totalModuleWidthCount * width) / 2 + + if (flowLines.left.x1 < flowLines.bottom.x1) { + startPointX = flowLines.left.x1 + } + } + + let heightMargin = 0 + let widthMargin = 0 + let chidoriLength = 0 + let moduleMaxRows = totalModuleHeightCount + + //첫번재 모듈 설치 후 두번째 모듈을 몇개까지 설치 할 수 있는지 계산 + if (moduleIndex > 0) { + moduleMaxRows = moduleMaxRows - installedModuleHeightCount //두번째 모듈일때 + } + + let isInstall = false + + for (let i = 0; i < moduleMaxRows; i++) { + let moduleY = flowLines.bottom.y1 - height * i - 1 //살짝 여유를 준다 + + //두번째 모듈 -> 혼합일 경우의 설치될 모듈 높이를 계산 + if (moduleIndex > 0) { + moduleY = installedLastHeightCoord - intvVer + } + + //첫번째는 붙여서 두번째는 마진을 주고 설치 + heightMargin = i === 0 ? 0 : intvVer * i + + for (let j = 0; j < totalModuleWidthCount; j++) { + let moduleX = startPointX + width * j + 1 //5정도 마진을 준다 + widthMargin = j === 0 ? 0 : intvHor * j // 가로 마진값 + chidoriLength = 0 //치도리가 아니여도 기본값을 5정도 준다 + + let square = [ + [moduleX + widthMargin, moduleY - height - heightMargin], + [moduleX + widthMargin, moduleY - heightMargin], + [moduleX + width + widthMargin, moduleY - heightMargin], + [moduleX + width + widthMargin, moduleY - height - heightMargin], + [moduleX + widthMargin, moduleY - height - heightMargin], ] let squarePolygon = turf.polygon([square]) @@ -3029,15 +3094,47 @@ export function useModuleBasicSetting(tabNum) { moduleOptions = { ...moduleOptions, fill: module.color, surfaceId: moduleSetupSurface.id, moduleInfo: module } let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon }) - canvas?.add(tempModule) - moduleSetupArray.push(tempModule) - moduleGroup.push(tempModule) + + let disjointFromTrestle = checkModuleDisjointSurface(squarePolygon, polygonToTurfPolygon(moduleSetupSurface, true)) + let isDisjoint = checkModuleDisjointObjects(squarePolygon, containsBatchObjects) + + if (disjointFromTrestle && isDisjoint) { + //최초 한번은 그냥 그린다 + //겹치는지 확인해서 포함된 모듈만 그린다 + canvas?.add(tempModule) + moduleSetupArray.push(tempModule) + moduleArray.push(tempModule) + canvas.renderAll() + + // ++installedModuleHeightCount + + isInstall = true + //마지막에 설치된 모듈의 Y 좌표 + installedLastHeightCoord = moduleY - height - heightMargin + } else { + //디버깅용 + // tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) + // canvas?.add(tempModule) + // canvas.renderAll() + } + } + if (isInstall) { + ++installedModuleHeightCount } } + setupModule.push(moduleArray) }) } - const flatRoofLeftFlowSetupModule = (surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight) => { + const flatRoofLeftFlowSetupModule = ( + surfaceMaxLines, + maxLengthLine, + moduleSetupArray, + moduleSetupSurface, + intvHor, + intvVer, + containsBatchObjects, + ) => { checkedModule.forEach((module, index) => { const { width, height } = getModuleWidthHeight(maxLengthLine, moduleSetupSurface, module) const flowLines = getFlowLines(moduleSetupSurface, width) @@ -3082,7 +3179,15 @@ export function useModuleBasicSetting(tabNum) { }) } - const flatRoofTopFlowSetupModule = (surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight) => { + const flatRoofTopFlowSetupModule = ( + surfaceMaxLines, + maxLengthLine, + moduleSetupArray, + moduleSetupSurface, + intvHor, + intvVer, + containsBatchObjects, + ) => { checkedModule.forEach((module, index) => { const { width, height } = getModuleWidthHeight(maxLengthLine, moduleSetupSurface, module) const flowLines = getFlowLines(moduleSetupSurface, height) @@ -3129,7 +3234,15 @@ export function useModuleBasicSetting(tabNum) { }) } - const flatRoofRightFlowSetupModule = (surfaceMaxLines, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight) => { + const flatRoofRightFlowSetupModule = ( + surfaceMaxLines, + maxLengthLine, + moduleSetupArray, + moduleSetupSurface, + intvHor, + intvVer, + containsBatchObjects, + ) => { checkedModule.forEach((module, index) => { const { width, height } = getModuleWidthHeight(maxLengthLine, moduleSetupSurface, module) const flowLines = getFlowLines(moduleSetupSurface, width) @@ -3186,20 +3299,13 @@ export function useModuleBasicSetting(tabNum) { const containsBatchObjects = objectsIncludeSurface(turfModuleSetupSurface) //배치면에 오브젝트(도머, 개구등)이 있는지 확인하는 로직 const surfaceMaxLines = findSetupSurfaceMaxLines(moduleSetupSurface) - const marginWidth = 1 - const marginHeight = 3 + const intvHor = 30 + const intvVer = 10 canvas.renderAll() - if (compasDeg >= 0 && compasDeg < 90) { - flatRoofDownFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight) - } else if (compasDeg >= 90 && compasDeg < 180) { - flatRoofLeftFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight) - } else if (compasDeg >= 180 && compasDeg < 270) { - flatRoofRightFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight) - } else { - flatRoofTopFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, marginWidth, marginHeight) - } + //육지붕은 왼쪽 기준으로 그려진다 + flatRoofDownFlowSetupModule(surfaceMaxLines, maxLengthLine, moduleSetupArray, moduleSetupSurface, intvHor, intvVer, containsBatchObjects) const setupedModules = moduleSetupArray.filter((module, index) => { let disjointFromTrestle = checkModuleDisjointSurface(module.turfPoints, turfModuleSetupSurface) diff --git a/src/util/qpolygon-utils.js b/src/util/qpolygon-utils.js index 557342b8..348f1291 100644 --- a/src/util/qpolygon-utils.js +++ b/src/util/qpolygon-utils.js @@ -3536,3 +3536,18 @@ export const calcLineActualSize = (points, degree) => { } return Big(planeSize).pow(2).plus(height.pow(2)).sqrt().abs().round().toNumber() } + +export const createLinesFromPolygon = (points) => { + const lines = [] + for (let i = 0; i < points.length; i++) { + const nextIndex = (i + 1) % points.length + const line = new fabric.Line([points[i].x, points[i].y, points[nextIndex].x, points[nextIndex].y], { + stroke: 'red', + strokeWidth: 2, + selectable: false, + evented: false, + }) + lines.push(line) + } + return lines +} From 6e8a4729fbf9442e498837ed0d4cd7e2f3765799 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Mon, 24 Feb 2025 13:47:12 +0900 Subject: [PATCH 115/352] =?UTF-8?q?=EC=9C=A1=EC=A7=80=EB=B6=95=20=EB=AA=A8?= =?UTF-8?q?=EB=93=88=20=EC=96=BC=EB=9F=BF=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/modal/basic/BasicSetting.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index 9a537163..291ef086 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -70,7 +70,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { userId: loginUserState.userId, //작성자아아디 }) } else { - if (!isObjectNotEmpty(moduleSelectionData.flatModule)) { + if (!isObjectNotEmpty(moduleSelectionData.module)) { Swal.fire({ title: getMessage('module.not.found'), icon: 'warning', From 8820711ac6d7100275b61db2ce74abee1e1fb302 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Mon, 24 Feb 2025 14:28:19 +0900 Subject: [PATCH 116/352] =?UTF-8?q?=EB=94=94=EB=B2=84=EA=B9=85=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 12 ++++++------ src/hooks/object/useObjectBatch.js | 11 +++++++++-- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index d96b96a1..c284f47f 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -1071,9 +1071,9 @@ export function useModuleBasicSetting(tabNum) { // } } else { //디버깅용 - tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) - canvas?.add(tempModule) - canvas.renderAll() + // tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) + // canvas?.add(tempModule) + // canvas.renderAll() } } if (isInstall) { @@ -1940,9 +1940,9 @@ export function useModuleBasicSetting(tabNum) { // } } else { //디버깅용 - tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) - canvas?.add(tempModule) - canvas.renderAll() + // tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) + // canvas?.add(tempModule) + // canvas.renderAll() } } diff --git a/src/hooks/object/useObjectBatch.js b/src/hooks/object/useObjectBatch.js index ff446673..c82846f2 100644 --- a/src/hooks/object/useObjectBatch.js +++ b/src/hooks/object/useObjectBatch.js @@ -482,10 +482,11 @@ export function useObjectBatch({ isHidden, setIsHidden }) { stroke: 'black', strokeWidth: 1, originX: 'center', - originY: 'center', + originY: 'top', fontSize: lengthTextFont.fontSize.value, fontStyle: lengthTextFont.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal', fontWeight: lengthTextFont.fontWeight.value, + angle: originAngle, }) } @@ -620,15 +621,20 @@ export function useObjectBatch({ isHidden, setIsHidden }) { //각도 추가 + let originAngle = 0 //기본 남쪽 let direction = 'south' + if (directionRef === 'left') { //서 + originAngle = 90 direction = 'west' } else if (directionRef === 'right') { //동 + originAngle = 270 direction = 'east' } else if (directionRef === 'up') { //북 + originAngle = 180 direction = 'north' } @@ -708,10 +714,11 @@ export function useObjectBatch({ isHidden, setIsHidden }) { stroke: 'black', strokeWidth: 1, originX: 'center', - originY: 'center', + originY: 'top', fontSize: lengthTextFont.fontSize.value, fontStyle: lengthTextFont.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal', fontWeight: lengthTextFont.fontWeight.value, + angle: originAngle, }) } From de9e87b5867305f514d18791ac2d15bb996bd421 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Mon, 24 Feb 2025 14:33:26 +0900 Subject: [PATCH 117/352] =?UTF-8?q?=EC=9C=A1=EC=A7=80=EB=B6=95=20=EB=8C=80?= =?UTF-8?q?=EC=9D=91=EC=9E=91=EC=97=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useTrestle.js | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index 3304d180..14bf6447 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -48,6 +48,9 @@ export const useTrestle = () => { surfaces.forEach((surface) => { const parent = canvas.getObjects().find((obj) => obj.id === surface.parentId) const roofMaterialIndex = parent.roofMaterial.index + if (+roofSizeSet === 3) { + return true + } const construction = moduleSelectionData?.roofConstructions?.find((construction) => construction.roofIndex === roofMaterialIndex).construction if (!construction) { alert('앞에서 셋팅 안됨') @@ -678,14 +681,17 @@ export const useTrestle = () => { const roofMaterialIndex = parent.roofMaterial.index const { nameJp: roofMaterialIdMulti } = roofMaterial const moduleSelection = moduleSelectionData?.roofConstructions?.find((construction) => construction.roofIndex === roofMaterialIndex) - const { constTp: constructSpecification, constTpJp: constructSpecificationMulti } = moduleSelection.construction - const { - trestleMkrCd, - constMthdCd: supportMethodId, - roofBaseCd, - trestleMkrCdJp: supportMeaker, - constMthdCdJp: supportMethodIdMulti, - } = moduleSelection.trestle + let construction = moduleSelection?.construction + let constructSpecification = +roofSizeSet === 3 ? null : construction.constTp + let constructSpecificationMulti = +roofSizeSet === 3 ? null : construction.constTpJp + + const trestle = moduleSelection?.trestle + + let trestleMkrCd = +roofSizeSet === 3 ? null : trestle.trestleMkrCd + let supportMethodId = +roofSizeSet === 3 ? null : trestle.constMthdCd + let roofBaseCd = +roofSizeSet === 3 ? null : trestle.roofBaseCd + let supportMeaker = +roofSizeSet === 3 ? null : trestle.trestleMkrCdJp + let supportMethodIdMulti = +roofSizeSet === 3 ? null : trestle.constMthdCdJp const modules = surface.modules const moduleList = modules.map((module) => { @@ -700,16 +706,16 @@ export const useTrestle = () => { return { roofSurfaceId: surface.id, roofSurface: directionText.replace(/[0-9]/g, ''), - roofMaterialId: roofMaterial.roofMatlCd, + roofMaterialId: +roofSizeSet === 3 ? '陸屋根' : roofMaterial.roofMatlCd, // 육지붕의 경우 지붕재 ID 값이 없기 때문에 임의 값 지정 supportMethodId, constructSpecification, constructSpecificationMulti, - roofMaterialIdMulti, + roofMaterialIdMulti: +roofSizeSet === 3 ? '陸屋根' : roofMaterialIdMulti, supportMethodIdMulti, supportMeaker, - slope, + slope: +roofSizeSet === 3 ? 0 : slope, classType: currentAngleType === 'slope' ? '0' : '1', - angle: getDegreeByChon(slope), + angle: +roofSizeSet === 3 ? 0 : getDegreeByChon(slope), azimuth: getAzimuth(parent), moduleList, } From 9109db9b404aef77519e25eb8c34742dc10a8485 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Mon, 24 Feb 2025 16:47:27 +0900 Subject: [PATCH 118/352] =?UTF-8?q?=EC=88=98=EB=8F=99=EB=AA=A8=EB=93=88=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=EC=8B=9C=20=EC=96=B8=EB=A7=88=EC=9A=B4?= =?UTF-8?q?=ED=8A=B8,=20=EB=8F=84=EB=A8=B8=20=EB=B0=A9=ED=96=A5=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/common.js | 1 + .../floor-plan/modal/basic/BasicSetting.jsx | 5 - .../floor-plan/modal/basic/step/Placement.jsx | 8 +- src/hooks/module/useModuleBasicSetting.js | 3 +- src/hooks/object/useObjectBatch.js | 103 +++++++++++++++--- 5 files changed, 98 insertions(+), 22 deletions(-) diff --git a/src/common/common.js b/src/common/common.js index 0424fcfd..1452aa3a 100644 --- a/src/common/common.js +++ b/src/common/common.js @@ -188,6 +188,7 @@ export const SAVE_KEY = [ 'onlyOffset', 'isChidory', 'textVisible', + 'groupPoints', ] export const OBJECT_PROTOTYPE = [fabric.Line.prototype, fabric.Polygon.prototype, fabric.Triangle.prototype] diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index 291ef086..e7ead904 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -115,11 +115,6 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { //팝업 닫기 버튼 이벤트 const handleClosePopup = (id) => { - if (tabNum == 3) { - if (isManualModuleSetup) { - setIsManualModuleSetup(false) - } - } setIsClosePopup({ close: true, id: id }) } diff --git a/src/components/floor-plan/modal/basic/step/Placement.jsx b/src/components/floor-plan/modal/basic/step/Placement.jsx index e8d8048f..2b0e9c03 100644 --- a/src/components/floor-plan/modal/basic/step/Placement.jsx +++ b/src/components/floor-plan/modal/basic/step/Placement.jsx @@ -1,7 +1,7 @@ import { forwardRef, useEffect, useState } from 'react' import { useMessage } from '@/hooks/useMessage' import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting' -import { checkedModuleState, currentCanvasPlanState } from '@/store/canvasAtom' +import { checkedModuleState, currentCanvasPlanState, isManualModuleSetupState } from '@/store/canvasAtom' import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions' import { isObjectNotEmpty } from '@/util/common-utils' @@ -23,6 +23,8 @@ const Placement = forwardRef((props, refs) => { const [isMultiModule, setIsMultiModule] = useState(false) + const [isManualModuleSetup, setIsManualModuleSetup] = useRecoilState(isManualModuleSetupState) + //모듈 배치면 생성 useEffect(() => { if (moduleSelectionData) { @@ -33,6 +35,10 @@ const Placement = forwardRef((props, refs) => { } makeModuleInitArea(moduleSelectionData) } + + return () => { + setIsManualModuleSetup(false) + } }, []) //최초 지입시 체크 diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index c284f47f..e14011ab 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -22,14 +22,13 @@ import { v4 as uuidv4 } from 'uuid' // import { useCircuitTrestle } from '@/hooks/useCirCuitTrestle' import { isObjectNotEmpty } from '@/util/common-utils' import { useCircuitTrestle } from '@/hooks/useCirCuitTrestle' -import { useMode } from '../useMode' +import { useMode } from '@/hooks/useMode' export function useModuleBasicSetting(tabNum) { const canvas = useRecoilValue(canvasState) const { getMessage } = useMessage() const roofDisplay = useRecoilValue(roofDisplaySelector) const [moduleSetupSurface, setModuleSetupSurface] = useRecoilState(moduleSetupSurfaceState) - const [moduleIsSetup, setModuleIsSetup] = useRecoilState(moduleIsSetupState) const { addCanvasMouseEventListener, initEvent, removeMouseEvent, addTargetMouseEventListener } = useEvent() // const { setModuleStatisticsData } = useCircuitTrestle() const { swalFire } = useSwal() diff --git a/src/hooks/object/useObjectBatch.js b/src/hooks/object/useObjectBatch.js index c82846f2..231f422c 100644 --- a/src/hooks/object/useObjectBatch.js +++ b/src/hooks/object/useObjectBatch.js @@ -298,6 +298,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) { if (buttonAct === 3) { const bottomLength = height / (pitch * 0.25) const bottomOffsetLength = (height + offsetRef) / (pitch * 0.25) + let groupDormerPoints = [] //나중에 offset을 위한 포인트 저장용 addCanvasMouseEventListener('mouse:move', (e) => { isDown = true @@ -403,9 +404,8 @@ export function useObjectBatch({ isHidden, setIsHidden }) { direction = 'north' } - const groupPoints = offsetRef > 0 ? triangleToPolygon(dormerOffset) : triangleToPolygon(dormer) - - let splitedTriangle = offsetRef > 0 ? splitDormerTriangle(dormerOffset, directionRef) : splitDormerTriangle(dormer, directionRef) + let { leftPoints, rightPoints, groupPoints } = + offsetRef > 0 ? splitDormerTriangle(dormerOffset, directionRef) : splitDormerTriangle(dormer, directionRef) canvas?.remove(offsetRef > 0 ? dormerOffset : dormer) if (offsetRef > 0) @@ -416,7 +416,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) { strokeDashArray: [0], }) //오프셋이 있을땐 같이 도머로 만든다 - const leftTriangle = new QPolygon(splitedTriangle[0], { + const leftTriangle = new QPolygon(leftPoints, { fill: 'white', stroke: 'black', strokeWidth: 1, @@ -435,7 +435,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) { fontWeight: lengthTextFont.fontWeight.value, }) - const rightTriangle = new QPolygon(splitedTriangle[1], { + const rightTriangle = new QPolygon(rightPoints, { fill: 'white', stroke: 'black', strokeWidth: 1, @@ -467,6 +467,8 @@ export function useObjectBatch({ isHidden, setIsHidden }) { let offsetPolygon + groupDormerPoints = groupPoints + if (offsetRef > 0) { canvas?.remove(dormer) @@ -499,7 +501,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) { parentId: selectedSurface.id, originX: 'center', originY: 'center', - groupPoints: groupPoints, + groupPoints: groupDormerPoints, }) canvas?.add(objectGroup) @@ -526,6 +528,8 @@ export function useObjectBatch({ isHidden, setIsHidden }) { //(동의길이 깊이)+출폭(깊이)-[(입력한 폭값)/2+출폭(폭)]*(0.25*입력한 寸) const heightOffsetLength = height + offsetRef - (width / 2 + offsetWidthRef) * (pitch * 0.25) + let groupDormerPoints = [] + addCanvasMouseEventListener('mouse:move', (e) => { isDown = true if (!isDown) return @@ -639,7 +643,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) { } const offsetMode = offsetRef > 0 || offsetWidthRef > 0 ? 'offset' : 'normal' - let splitedPentagon = + let { leftPoints, rightPoints, groupPoints } = offsetRef > 0 || offsetWidthRef > 0 ? splitDormerPentagon(dormerOffset, directionRef, offsetMode) : splitDormerPentagon(dormer, directionRef, offsetMode) @@ -653,7 +657,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) { strokeDashArray: [0], }) //오프셋이 있을땐 같이 도머로 만든다 - const leftPentagon = new QPolygon(splitedPentagon[0], { + const leftPentagon = new QPolygon(leftPoints, { fill: 'transparent', stroke: 'red', strokeWidth: 1, @@ -670,7 +674,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) { pitch: pitch, }) - const rightPentagon = new QPolygon(splitedPentagon[1], { + const rightPentagon = new QPolygon(rightPoints, { fill: 'transparent', stroke: 'red', strokeWidth: 1, @@ -699,6 +703,8 @@ export function useObjectBatch({ isHidden, setIsHidden }) { let offsetPolygon + groupDormerPoints = groupPoints + if (offsetRef > 0) { canvas?.remove(dormer) @@ -723,7 +729,6 @@ export function useObjectBatch({ isHidden, setIsHidden }) { } const groupPolygon = offsetPolygon ? [leftPentagon, rightPentagon, offsetPolygon] : [leftPentagon, rightPentagon] - const groupPoints = offsetRef > 0 ? pentagonOffsetPoints : pentagonPoints const objectGroup = new fabric.Group(groupPolygon, { subTargetCheck: true, @@ -733,7 +738,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) { groupYn: true, originX: 'center', originY: 'center', - groupPoints: groupPoints, + groupPoints: groupDormerPoints, }) canvas?.add(objectGroup) @@ -774,6 +779,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) { let leftPoints = [] let rightPoints = [] + let groupPoints = [] if (direction === 'down') { leftPoints = [ @@ -787,6 +793,12 @@ export function useObjectBatch({ isHidden, setIsHidden }) { { x: triangle.left, y: triangle.top + triangle.height }, { x: triangle.left + halfWidth, y: triangle.top + triangle.height }, ] + + groupPoints = [ + { x: triangle.left, y: triangle.top }, + { x: triangle.left - halfWidth, y: triangle.top + triangle.height }, + { x: triangle.left + halfWidth, y: triangle.top + triangle.height }, + ] } else if (direction === 'up') { leftPoints = [ { x: triangle.left, y: triangle.top }, @@ -799,6 +811,12 @@ export function useObjectBatch({ isHidden, setIsHidden }) { { x: triangle.left, y: triangle.top - triangle.height }, { x: triangle.left + halfWidth, y: triangle.top - triangle.height }, ] + + groupPoints = [ + { x: triangle.left, y: triangle.top }, + { x: triangle.left - halfWidth, y: triangle.top - triangle.height }, + { x: triangle.left + halfWidth, y: triangle.top - triangle.height }, + ] } else if (direction === 'left') { leftPoints = [ { x: triangle.left, y: triangle.top }, @@ -811,6 +829,12 @@ export function useObjectBatch({ isHidden, setIsHidden }) { { x: triangle.left - triangle.height, y: triangle.top }, { x: triangle.left - triangle.height, y: triangle.top + halfWidth }, ] + + groupPoints = [ + { x: triangle.left, y: triangle.top }, + { x: triangle.left - triangle.height, y: triangle.top - halfWidth }, + { x: triangle.left - triangle.height, y: triangle.top + halfWidth }, + ] } else if (direction === 'right') { leftPoints = [ { x: triangle.left, y: triangle.top }, @@ -820,11 +844,17 @@ export function useObjectBatch({ isHidden, setIsHidden }) { rightPoints = [ { x: triangle.left, y: triangle.top }, - { x: triangle.left + triangle.height, y: triangle.top }, + { x: triangle.left + triangle.height, y: triangle.top + triangle.height }, + { x: triangle.left + triangle.height, y: triangle.top - triangle.height }, + ] + + groupPoints = [ + { x: triangle.left, y: triangle.top }, + { x: triangle.left + triangle.height, y: triangle.top + triangle.height }, { x: triangle.left + triangle.height, y: triangle.top - triangle.height }, ] } - return [leftPoints, rightPoints] + return { leftPoints, rightPoints, groupPoints } } const splitDormerPentagon = (pentagon, direction, offsetMode) => { @@ -832,6 +862,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) { let leftPoints = [] let rightPoints = [] + let groupPoints = [] if (direction === 'down') { leftPoints = [ @@ -847,6 +878,14 @@ export function useObjectBatch({ isHidden, setIsHidden }) { { x: points[3].x, y: points[3].y }, { x: points[4].x, y: points[4].y }, ] + + groupPoints = [ + { x: points[0].x, y: points[0].y }, + { x: points[1].x, y: points[1].y }, + { x: points[2].x, y: points[3].y }, + { x: points[3].x, y: points[3].y }, + { x: points[4].x, y: points[4].y }, + ] } else if (direction === 'up') { leftPoints = [ { x: points[0].x, y: points[0].y }, @@ -861,6 +900,14 @@ export function useObjectBatch({ isHidden, setIsHidden }) { { x: points[3].x, y: points[0].y - (points[2].y - points[0].y) }, { x: points[0].x, y: points[0].y - (points[2].y - points[0].y) }, ] + + groupPoints = [ + { x: points[0].x, y: points[0].y }, // 기준점 + { x: points[1].x, y: points[0].y - (points[1].y - points[0].y) }, + { x: points[2].x, y: points[0].y - (points[2].y - points[0].y) }, + { x: points[3].x, y: points[0].y - (points[2].y - points[0].y) }, + { x: points[3].x, y: points[0].y - (points[1].y - points[0].y) }, + ] } else if (direction === 'left') { leftPoints = [ { x: points[0].x, y: points[0].y }, @@ -881,6 +928,20 @@ export function useObjectBatch({ isHidden, setIsHidden }) { }, { x: points[0].x - (points[1].y - points[0].y) - (points[2].y - points[1].y), y: points[0].y }, ] + + groupPoints = [ + { x: points[0].x, y: points[0].y }, + { x: points[0].x - (points[1].y - points[0].y), y: points[0].y - (points[0].x - points[1].x) }, + { + x: points[0].x - (points[1].y - points[0].y) - (points[2].y - points[1].y), + y: points[0].y - (points[0].x - points[1].x), + }, + { + x: points[0].x - (points[1].y - points[0].y) - (points[2].y - points[1].y), + y: points[0].y + (points[0].x - points[1].x), + }, + { x: points[0].x - (points[1].y - points[0].y), y: points[0].y + (points[0].x - points[1].x) }, + ] } else if (direction === 'right') { leftPoints = [ { x: points[0].x, y: points[0].y }, @@ -901,9 +962,23 @@ export function useObjectBatch({ isHidden, setIsHidden }) { }, { x: points[0].x + (points[1].y - points[0].y) + (points[2].y - points[1].y), y: points[0].y }, ] + + groupPoints = [ + { x: points[0].x, y: points[0].y }, + { x: points[0].x + (points[1].y - points[0].y), y: points[0].y + (points[0].x - points[1].x) }, + { + x: points[0].x + (points[1].y - points[0].y) + (points[2].y - points[1].y), + y: points[0].y + (points[0].x - points[1].x), + }, + { + x: points[0].x + (points[1].y - points[0].y) + (points[2].y - points[1].y), + y: points[0].y - (points[0].x - points[1].x), + }, + { x: points[0].x + (points[1].y - points[0].y), y: points[0].y - (points[0].x - points[1].x) }, + ] } - return [leftPoints, rightPoints] + return { leftPoints, rightPoints, groupPoints } } const resizeObjectBatch = (side, target, width, height) => { From 6ecdc1bf971f23d6116b4f0189421b0ca4bf5af1 Mon Sep 17 00:00:00 2001 From: changkyu choi Date: Mon, 24 Feb 2025 17:32:03 +0900 Subject: [PATCH 119/352] =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=A9=B4=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=EC=84=A4=EC=A0=95=20=EC=B4=88=EA=B8=B0=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EB=B0=8F=20=EC=A3=BC=EC=84=9D=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../placementShape/PlacementShapeSetting.jsx | 35 ++- src/hooks/option/useCanvasSetting.js | 270 +++++++----------- 2 files changed, 116 insertions(+), 189 deletions(-) diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx index ed400f95..2fed8591 100644 --- a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx @@ -63,20 +63,21 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla /** * 지붕재 초기값 */ - const defaultRoofSettings = { - roofSizeSet: '1', // 기본 치수 입력 방법 - roofAngleSet: 'slope', // 기본 지붕 각도 설정 + const DEFAULT_ROOF_SETTINGS = { + roofSizeSet: '1', + roofAngleSet: 'slope', angle: 21.8, - hajebichi: '', + hajebichi: null, id: 'ROOF_ID_WA_53A', index: 0, layout: ROOF_MATERIAL_LAYOUT.PARALLEL, lenAuth: 'R', lenBase: '235.000', - length: '235', + length: 235, name: '일본기와 A', nameJp: '和瓦A', pitch: 4, + planNo: planNo, raft: '', raftAuth: 'C', raftBaseCd: 'HEI_455', @@ -89,12 +90,12 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla selected: true, widAuth: 'R', widBase: '265.000', - width: '265', + width: 265, } useEffect(() => { /** - * 메뉴에서 배치면초기설정 선택 시 조회 + * 메뉴에서 배치면초기설정 선택 시 조회 후 화면 오픈 */ if (openPoint && openPoint === 'canvasMenus') fetchBasicSettings(planNo, openPoint) }, []) @@ -103,18 +104,16 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla if (addedRoofs.length > 0) { const raftCodeList = findCommonCode('203800') setRaftCodes(raftCodeList) - - /** - * 데이터 설정 확인 후 데이터가 없으면 기본 데이터 설정 - */ - if (addedRoofs.length > 0) { - setCurrentRoof({ ...addedRoofs[0], planNo: basicSetting.planNo }) - } else { - setCurrentRoof(defaultRoofSettings) - } + setCurrentRoof({ ...addedRoofs[0], planNo: planNo, roofSizeSet: String(basicSetting.roofSizeSet), roofAngleSet: basicSetting.roofAngleSet }) + } else { + /** 데이터 설정 확인 후 데이터가 없으면 기본 데이터 설정 */ + setCurrentRoof({ ...DEFAULT_ROOF_SETTINGS }) } }, [addedRoofs]) + /** + * 배치면초기설정 정보 변경 시 basicSettings 설정 + */ useEffect(() => { if (!currentRoof) return setBasicSettings({ @@ -256,7 +255,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla id={item.id} name={item.name} value={item.value} - checked={currentRoof?.roofSizeSet === item.value} + checked={String(currentRoof?.roofSizeSet) === item.value} onChange={(e) => setCurrentRoof({ ...currentRoof, roofSizeSet: e.target.value })} /> @@ -279,7 +278,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla id={item.id} name={item.name} value={item.value} - checked={currentRoof?.roofAngleSet === item.value} + checked={String(currentRoof?.roofAngleSet) === item.value} onChange={(e) => setCurrentRoof({ ...currentRoof, roofAngleSet: e.target.value })} /> diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js index 8cdecf1c..37f53f5e 100644 --- a/src/hooks/option/useCanvasSetting.js +++ b/src/hooks/option/useCanvasSetting.js @@ -43,21 +43,19 @@ import { v4 as uuidv4 } from 'uuid' const defaultDotLineGridSetting = { INTERVAL: { - type: 2, // 1: 가로,세로 간격 수동, 2: 비율 간격 + type: 2 /* 1: 가로,세로 간격 수동, 2: 비율 간격 */, ratioInterval: 910, verticalInterval: 910, horizontalInterval: 910, - dimension: 1, // 치수 + dimension: 1 /* 치수 */, }, DOT: false, LINE: false, } -// let previousRoofMaterialsYn = 'N' // 지붕재 select 정보 비교 후 변경된 것이 없으면 1회만 실행 - export function useCanvasSetting() { const canvas = useRecoilValue(canvasState) - /* canvas가 null이 아닐 때에만 getObjects 호출 */ + /** canvas가 null이 아닐 때에만 getObjects 호출 */ const canvasObjects = canvas ? canvas.getObjects() : [] const [correntObjectNo, setCorrentObjectNo] = useRecoilState(correntObjectNoState) @@ -119,14 +117,14 @@ export function useCanvasSetting() { const [type, setType] = useRecoilState(menuTypeState) const setCurrentMenu = useSetRecoilState(currentMenuState) - const resetModuleSelectionData = useResetRecoilState(moduleSelectionDataState) //다음으로 넘어가는 최종 데이터 - const resetSelectedModules = useResetRecoilState(selectedModuleState) //선택된 모듈 + const resetModuleSelectionData = useResetRecoilState(moduleSelectionDataState) /* 다음으로 넘어가는 최종 데이터 */ + const resetSelectedModules = useResetRecoilState(selectedModuleState) /* 선택된 모듈 */ const { trigger: moduleSelectedDataTrigger } = useCanvasPopupStatusController(2) - const [raftCodes, setRaftCodes] = useState([]) // 서까래 정보 + const [raftCodes, setRaftCodes] = useState([]) /* 서까래 정보 */ const { findCommonCode } = useCommonCode() - const [currentRoof, setCurrentRoof] = useState(null) // 현재 선택된 지붕재 정보 + const [currentRoof, setCurrentRoof] = useState(null) /* 현재 선택된 지붕재 정보 */ const { addPopup } = usePopup() const [popupId, setPopupId] = useState(uuidv4()) @@ -144,7 +142,7 @@ export function useCanvasSetting() { useEffect(() => { const tempFetchRoofMaterials = !fetchRoofMaterials - /* 초 1회만 실행하도록 처리 */ + /** 초 1회만 실행하도록 처리 */ setFetchRoofMaterials(tempFetchRoofMaterials) if (tempFetchRoofMaterials) { addRoofMaterials() @@ -176,7 +174,23 @@ export function useCanvasSetting() { angle: item.angle ? parseInt(item.angle) : 21.8, })) setRoofMaterials(roofLists) - const selectedRoofMaterial = roofLists[0] + } + + useEffect(() => { + if (addedRoofs.length > 0 && addedRoofs[0].planNo === basicSetting.planNo) { + const raftCodeList = findCommonCode('203800') + setRaftCodes(raftCodeList) + setCurrentRoof({ + ...addedRoofs[0], + planNo: addedRoofs[0].planNo, + roofSizeSet: String(basicSetting.roofSizeSet), + roofAngleSet: basicSetting.roofAngleSet, + }) + } + }, [addedRoofs]) + + useEffect(() => { + const selectedRoofMaterial = roofMaterials[0] if (addedRoofs.length === 0) { const newAddedRoofs = [] @@ -184,19 +198,7 @@ export function useCanvasSetting() { setAddedRoofs(newAddedRoofs) } setBasicSettings({ ...basicSetting, selectedRoofMaterial: selectedRoofMaterial }) - } - - /** - * 배치면 초기설정 화면이 열리지 않아도 데이터 set 하기 위해서 추가 - */ - useEffect(() => { - if (addedRoofs.length > 0) { - const raftCodeList = findCommonCode('203800') - setRaftCodes(raftCodeList) - - setCurrentRoof({ ...addedRoofs[0] }) - } - }, [addedRoofs]) + }, [roofMaterials]) useEffect(() => { if (!canvas) { @@ -339,7 +341,7 @@ export function useCanvasSetting() { } }) - /* 데이터 존재 시 화면 닫기(메뉴/저장 클릭 시 제외) */ + /** 데이터 존재 시 화면 닫기(메뉴/저장 클릭 시 제외) */ if (openPoint !== 'canvasMenus' && openPoint !== 'basicSettingSave') { //closePopup(popupId) closeAll() @@ -369,9 +371,9 @@ export function useCanvasSetting() { }, ] - /* 메뉴에서 배치면 초기설정 클릭 시 실행하지 않음 */ + /** 메뉴에서 배치면 초기설정 클릭 시 실행하지 않음 */ if (openPoint === null) { - /* 배치면 초기설정 미저장 상태이면 화면 열기 */ + /** 배치면 초기설정 미저장 상태이면 화면 열기 */ const placementInitialProps = { id: popupId, pos: { @@ -385,7 +387,7 @@ export function useCanvasSetting() { } } - /* 데이터 설정 */ + /** 데이터 설정 */ const addRoofs = [] for (let i = 0; i < roofsArray.length; i++) { roofMaterials?.map((material) => { @@ -440,6 +442,21 @@ export function useCanvasSetting() { // setCanvasSetting({ ...basicSetting }) } + /** + * 저장/복사저장 시 지붕 크기에 따른 메뉴 설정 + */ + const setMenuByRoofSize = (roofSizeSet) => { + if (['2', '3'].includes(String(roofSizeSet))) { + setMenuNumber(3) + setType('surface') + setCurrentMenu(MENU.BATCH_CANVAS.BATCH_DRAWING) + } else { + setMenuNumber(2) + setType('outline') + setCurrentMenu(MENU.ROOF_COVERING.EXTERIOR_WALL_LINE) + } + } + /** * 기본설정(PlacementShapeSetting) 저장 */ @@ -471,31 +488,23 @@ export function useCanvasSetting() { await post({ url: `/api/canvas-management/canvas-basic-settings`, data: patternData }).then((res) => { swalFire({ text: getMessage(res.returnMessage) }) - /* BasicSettings Recoil 설정 */ + /** BasicSettings Recoil 설정 */ setBasicSettings({ ...params }) }) - /* CanvasSetting Recoil 설정 - roofSizeSet을 문자열로 변환 */ + /** CanvasSetting Recoil 설정 - roofSizeSet을 문자열로 변환 */ setCanvasSetting({ ...basicSetting, roofSizeSet: String(params.roofSizeSet), }) - /* 메뉴 설정 */ - if (['2', '3'].includes(params.roofSizeSet)) { - setMenuNumber(3) - setType('surface') - setCurrentMenu(MENU.BATCH_CANVAS.BATCH_DRAWING) - } else { - setMenuNumber(2) - setType('outline') - setCurrentMenu(MENU.ROOF_COVERING.EXTERIOR_WALL_LINE) - } + /** 메뉴 설정 */ + setMenuByRoofSize(params.roofSizeSet) - /* 배치면초기설정 조회 */ + /** 배치면초기설정 조회 */ fetchBasicSettings(params.planNo, 'basicSettingSave') - /* 모듈 선택 데이터 초기화 */ + /** 모듈 선택 데이터 초기화 */ resetModuleSelectionData() moduleSelectedDataTrigger({ common: {}, module: {}, roofConstructions: [] }) const isModuleExist = canvas.getObjects().some((obj) => obj.name === POLYGON_TYPE.MODULE) @@ -536,27 +545,19 @@ export function useCanvasSetting() { swalFire({ text: getMessage(res.returnMessage) }) }) - /* CanvasSetting Recoil 설정 - roofSizeSet을 문자열로 변환 */ + /** CanvasSetting Recoil 설정 - roofSizeSet을 문자열로 변환 */ setCanvasSetting({ ...basicSetting, roofSizeSet: String(params.roofSizeSet), }) - /* 메뉴 설정 */ - if (['2', '3'].includes(params?.roofSizeSet)) { - setMenuNumber(3) - setType('surface') - setCurrentMenu(MENU.BATCH_CANVAS.BATCH_DRAWING) - } else { - setMenuNumber(2) - setType('outline') - setCurrentMenu(MENU.ROOF_COVERING.EXTERIOR_WALL_LINE) - } + /** 메뉴 설정 */ + setMenuByRoofSize(params.roofSizeSet) - /* 배치면초기설정 조회 */ + /** 배치면초기설정 조회 */ fetchBasicSettings(Number(params.planNo), 'basicSettingSave') - /* 모듈 선택 데이터 초기화 */ + /** 모듈 선택 데이터 초기화 */ resetModuleSelectionData() moduleSelectedDataTrigger({ common: {}, module: {}, roofConstructions: [] }) const isModuleExist = canvas.getObjects().some((obj) => obj.name === POLYGON_TYPE.MODULE) @@ -582,24 +583,16 @@ export function useCanvasSetting() { const optionData4 = settingModalSecondOptions.option4.map((item) => ({ ...item, selected: res[item.column] })) const optionData5 = settingModalFirstOptions.dimensionDisplay.map((item) => ({ ...item })) - /** - * 흡착점 ON/OFF - */ + /** 흡착점 ON/OFF */ setAdsorptionPointMode({ ...adsorptionPointMode, adsorptionPoint: res.adsorpPoint }) - /** - * 치수선 설정 - */ + /** 치수선 설정 */ setDimensionLineSettings({ ...dimensionLineSettings, pixel: res.originPixel, color: res.originColor }) - /** - * 도면크기 설정 - */ + /** 도면크기 설정 */ setPlanSizeSettingMode({ ...planSizeSettingMode, originHorizon: res.originHorizon, originVertical: res.originVertical }) - /** - * 데이터 설정 - */ + /** 데이터 설정 */ setSettingModalFirstOptions({ ...settingModalFirstOptions, option1: optionData1, @@ -614,45 +607,35 @@ export function useCanvasSetting() { const fontPatternData = { commonText: { - /** - * 문자 글꼴 조회 데이터 - */ + /** 문자 글꼴 조회 데이터 */ fontFamily: getFonts(res.wordFont), fontWeight: getFontStyles(res.wordFontStyle), fontSize: getFontSizes(res.wordFontSize), fontColor: getFontColors(res.wordFontColor), }, flowText: { - /** - * 흐름방향 글꼴 조회 데이터 - */ + /** 흐름방향 글꼴 조회 데이터 */ fontFamily: getFonts(res.flowFont), fontWeight: getFontStyles(res.flowFontStyle), fontSize: getFontSizes(res.flowFontSize), fontColor: getFontColors(res.flowFontColor), }, dimensionLineText: { - /** - * 치수 글꼴 조회 데이터 - */ + /** 치수 글꼴 조회 데이터 */ fontFamily: getFonts(res.dimensioFont), fontWeight: getFontStyles(res.dimensioFontStyle), fontSize: getFontSizes(res.dimensioFontSize), fontColor: getFontColors(res.dimensioFontColor), }, circuitNumberText: { - /** - * 회로번호 글꼴 조회 데이터 - */ + /** 회로번호 글꼴 조회 데이터 */ fontFamily: getFonts(res.circuitNumFont), fontWeight: getFontStyles(res.circuitNumFontStyle), fontSize: getFontSizes(res.circuitNumFontSize), fontColor: getFontColors(res.circuitNumFontColor), }, lengthText: { - /** - * 치수선 글꼴 조회 데이터 - */ + /** 치수선 글꼴 조회 데이터 */ fontFamily: getFonts(res.lengthFont), fontWeight: getFontStyles(res.lengthFontStyle), fontSize: getFontSizes(res.lengthFontSize), @@ -660,14 +643,10 @@ export function useCanvasSetting() { }, } - /** - * 조회된 글꼴 데이터 set - */ + /** 조회된 글꼴 데이터 set */ setGlobalFont(fontPatternData) - /** - * 점/선 그리드 - */ + /** 점/선 그리드 */ const patternData = { INTERVAL: { type: res.gridType, @@ -682,47 +661,31 @@ export function useCanvasSetting() { setDotLineGridSettingState(patternData) - /** - * 그리드 색 설정 - */ + /** 그리드 색 설정 */ setGridColor(res.gridColor) } else { - //조회된 글꼴 데이터가 없는 경우 (데이터 초기화) + /** 조회된 글꼴 데이터가 없는 경우 (데이터 초기화) */ - /** - * 흡착점 ON/OFF - */ + /** 흡착점 ON/OFF */ setAdsorptionPointMode({ ...adsorptionPointMode, adsorptionPoint: false }) - /** - * 치수선 설정 - */ + /** 치수선 설정 */ resetDimensionLineSettings() - /** - * 도면크기 설정 - */ + /** 도면크기 설정 */ resetPlanSizeSettingMode() - /** - * 데이터 설정 - */ + /** 데이터 설정 */ resetSettingModalFirstOptions() resetSettingModalSecondOptions() - /** - * 데이터 초기화 - */ + /** 데이터 초기화 */ resetGlobalFont() - /** - * 점/선 그리드 - */ + /** 점/선 그리드 */ setDotLineGridSettingState({ ...defaultDotLineGridSetting }) - /** - * 그리드 색 설정 - */ + /** 그리드 색 설정 */ setGridColor('#FF0000') } @@ -736,9 +699,7 @@ export function useCanvasSetting() { * CanvasSetting 옵션 클릭 후 저장 */ const onClickOption2 = async () => { - /** - * 서버에 전송할 데이터 - */ + /** 서버에 전송할 데이터 */ const dataToSend = { firstOption1: option1.map((item) => ({ column: item.column, @@ -759,13 +720,9 @@ export function useCanvasSetting() { })), } const patternData = { - /** - * 견적서 번호 - */ + /** 견적서 번호 */ objectNo: correntObjectNo, - /** - * 디스플레이 설정(다중) - */ + /** 디스플레이 설정(다중) */ allocDisplay: dataToSend.firstOption1[0].selected, outlineDisplay: dataToSend.firstOption1[1].selected, gridDisplay: dataToSend.firstOption1[2].selected, @@ -776,85 +733,62 @@ export function useCanvasSetting() { 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 - */ + /** 흡착점 ON/OFF */ adsorpPoint: adsorptionPointMode.adsorptionPoint, //??: adsorptionRange, 사용여부 확인 필요 - /** - * 글꼴 설정 - */ - //문자 글꼴 + /** 문자 글꼴 설정 */ wordFont: globalFont.commonText.fontFamily?.value ?? 'MS PGothic', wordFontStyle: globalFont.commonText.fontWeight?.value ?? 'normal', wordFontSize: globalFont.commonText.fontSize?.value ?? 16, wordFontColor: globalFont.commonText.fontColor?.value ?? 'black', - /** - * 흐름방향 글꼴 - */ + /** 흐름방향 글꼴 설정 */ flowFont: globalFont.flowText.fontFamily?.value ?? 'MS PGothic', flowFontStyle: globalFont.flowText.fontWeight?.value ?? 'normal', flowFontSize: globalFont.flowText.fontSize?.value ?? 16, flowFontColor: globalFont.flowText.fontColor?.value ?? 'black', - /** - * 치수 글꼴 - */ + /** 치수 글꼴 설정 */ dimensioFont: globalFont.dimensionLineText.fontFamily?.value ?? 'MS PGothic', dimensioFontStyle: globalFont.dimensionLineText.fontWeight?.value ?? 'normal', dimensioFontSize: globalFont.dimensionLineText.fontSize?.value ?? 16, dimensioFontColor: globalFont.dimensionLineText.fontColor?.value ?? 'black', - /** - * 회로번호 글꼴 - */ + /** 회로번호 글꼴 설정 */ circuitNumFont: globalFont.circuitNumberText.fontFamily?.value ?? 'MS PGothic', circuitNumFontStyle: globalFont.circuitNumberText.fontWeight?.value ?? 'normal', circuitNumFontSize: globalFont.circuitNumberText.fontSize?.value ?? 16, circuitNumFontColor: globalFont.circuitNumberText.fontColor?.value ?? 'black', - /** - * 치수선 글꼴 - */ + /** 치수선 글꼴 설정 */ lengthFont: globalFont.lengthText.fontFamily?.value ?? 'MS PGothic', lengthFontStyle: globalFont.lengthText.fontWeight?.value ?? 'normal', lengthFontSize: globalFont.lengthText.fontSize?.value ?? 16, lengthFontColor: globalFont.lengthText.fontColor?.value ?? 'black', - /** - * 치수선 설정 - */ + /** 치수선 설정 */ originPixel: dimensionLineSettings.pixel, originColor: dimensionLineSettings.color, - /** - * 도면크기 설정 - */ + /** 도면크기 설정 */ originHorizon: planSizeSettingMode.originHorizon, originVertical: planSizeSettingMode.originVertical, + /** 점/선 그리드 */ dotGridDisplay: dotLineGridSetting.DOT, lineGridDisplay: dotLineGridSetting.LINE, gridType: dotLineGridSetting.INTERVAL.type, @@ -863,6 +797,7 @@ export function useCanvasSetting() { gridRatio: dotLineGridSetting.INTERVAL.ratioInterval / 10, gridDimen: dotLineGridSetting.INTERVAL.dimension, + /** 그리드 색 설정 */ gridColor: gridColor, } @@ -875,13 +810,10 @@ export function useCanvasSetting() { .then((res) => { //swalFire({ text: getMessage(res.returnMessage) }) - /** - * Canvas 디스플레이 설정 시 해당 옵션 적용 - */ + /** Canvas 디스플레이 설정 시 해당 옵션 적용 */ frontSettings() - /** - * 저장 후 재조회 - */ + + /** 저장 후 재조회 */ fetchSettings() }) .catch((error) => { @@ -912,8 +844,8 @@ export function useCanvasSetting() { */ /** - * 옵션명 - * 옵션상태 + * 옵션명 optionName + * 옵션상태 optionSelected */ let optionName let optionSelected @@ -948,15 +880,11 @@ export function useCanvasSetting() { optionName = ['backGroundImage'] break case 'totalDisplay': - /** - * 작업할 필요 없음 - */ + /** 작업할 필요 없음 */ optionName = [] break } - /** - * 표시 선택 상태(true/false) - */ + /** 표시 선택 상태(true/false)*/ optionSelected = option1[i].selected canvasObjects From 2769ac23583377ba5fd66e405556b4aa9b412030 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Mon, 24 Feb 2025 18:08:24 +0900 Subject: [PATCH 120/352] =?UTF-8?q?=F0=9F=9A=A6fix:=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/api/html2canvas/route.js | 22 - src/app/api/image-upload/route.js | 15 - src/app/api/swr-tutorial/route.js | 25 - src/app/playground/page.jsx | 9 - src/app/roof/page.jsx | 13 - src/app/roof2/page.jsx | 11 - src/app/settings/page.jsx | 13 - src/components/GridSettingsModal.jsx | 273 ------ src/components/Headers.jsx | 21 - src/components/Hero.jsx | 7 - src/components/InitSettingsModal.jsx | 253 ------ src/components/Playground.jsx | 919 ------------------- src/components/Roof.jsx | 351 -------- src/components/Roof2.jsx | 1099 ----------------------- src/components/Settings.jsx | 324 ------- src/components/playground.module.css | 4 - src/hooks/common/useMasterController.js | 4 - 17 files changed, 3363 deletions(-) delete mode 100644 src/app/api/html2canvas/route.js delete mode 100644 src/app/api/image-upload/route.js delete mode 100644 src/app/api/swr-tutorial/route.js delete mode 100644 src/app/playground/page.jsx delete mode 100644 src/app/roof/page.jsx delete mode 100644 src/app/roof2/page.jsx delete mode 100644 src/app/settings/page.jsx delete mode 100644 src/components/GridSettingsModal.jsx delete mode 100644 src/components/Headers.jsx delete mode 100644 src/components/Hero.jsx delete mode 100644 src/components/InitSettingsModal.jsx delete mode 100644 src/components/Playground.jsx delete mode 100644 src/components/Roof.jsx delete mode 100644 src/components/Roof2.jsx delete mode 100644 src/components/Settings.jsx delete mode 100644 src/components/playground.module.css diff --git a/src/app/api/html2canvas/route.js b/src/app/api/html2canvas/route.js deleted file mode 100644 index 21f93c82..00000000 --- a/src/app/api/html2canvas/route.js +++ /dev/null @@ -1,22 +0,0 @@ -'use server' - -import fs from 'fs/promises' - -import { NextResponse } from 'next/server' -import { writeImage, writeImageBuffer } from '@/lib/fileAction' - -export async function GET(req) { - const path = 'public/plan-map-images' - const q = req.nextUrl.searchParams.get('q') - const fileNm = req.nextUrl.searchParams.get('fileNm') - const zoom = req.nextUrl.searchParams.get('zoom') - const targetUrl = `https://maps.googleapis.com/maps/api/staticmap?center=${q}&zoom=${zoom}&maptype=satellite&size=640x640&scale=1&key=AIzaSyDO7nVR1N_D2tKy60hgGFavpLaXkHpiHpc` - const decodeUrl = decodeURIComponent(targetUrl) - - const response = await fetch(decodeUrl) - const data = await response.arrayBuffer() - const buffer = Buffer.from(data) - await writeImage(fileNm, buffer) - - return NextResponse.json({ fileNm: `${fileNm}.png` }) -} diff --git a/src/app/api/image-upload/route.js b/src/app/api/image-upload/route.js deleted file mode 100644 index 219544fe..00000000 --- a/src/app/api/image-upload/route.js +++ /dev/null @@ -1,15 +0,0 @@ -'use server' - -import { NextResponse } from 'next/server' -import { writeImage } from '@/lib/fileAction' - -export async function POST(req) { - const formData = await req.formData() - const file = formData.get('file') - const fileName = formData.get('fileName') - const arrayBuffer = await file.arrayBuffer() - const buffer = Buffer.from(arrayBuffer) - await writeImage(fileName, buffer) - - return NextResponse.json({ fileNm: `${fileName}.png` }) -} diff --git a/src/app/api/swr-tutorial/route.js b/src/app/api/swr-tutorial/route.js deleted file mode 100644 index 99ebaf15..00000000 --- a/src/app/api/swr-tutorial/route.js +++ /dev/null @@ -1,25 +0,0 @@ -import { NextResponse } from 'next/server' - -const defaultData = [ - { - id: 1, - name: 'John Doe', - email: 'john.doe@example.com', - }, - { - id: 2, - name: 'Jane Lee', - email: 'jane.lee@example.com', - }, -] - -export async function GET(req, res) { - return NextResponse.json(defaultData) -} - -export const POST = async (req, res) => { - const { id, name, email } = await req.json() - const newData = { id, name, email } - console.log('🚀 ~ POST ~ newData:', newData) - return NextResponse.json([...defaultData, newData]) -} diff --git a/src/app/playground/page.jsx b/src/app/playground/page.jsx deleted file mode 100644 index 3a3ad1d1..00000000 --- a/src/app/playground/page.jsx +++ /dev/null @@ -1,9 +0,0 @@ -import Playground from '@/components/Playground' - -export default async function PlaygroundPage() { - return ( - <> - - - ) -} diff --git a/src/app/roof/page.jsx b/src/app/roof/page.jsx deleted file mode 100644 index 960ffa89..00000000 --- a/src/app/roof/page.jsx +++ /dev/null @@ -1,13 +0,0 @@ -import Hero from '@/components/Hero' -import Roof from '@/components/Roof' - -export default async function RoofPage() { - return ( - <> - -
- -
- - ) -} diff --git a/src/app/roof2/page.jsx b/src/app/roof2/page.jsx deleted file mode 100644 index 94e86fbe..00000000 --- a/src/app/roof2/page.jsx +++ /dev/null @@ -1,11 +0,0 @@ -import Roof2 from '@/components/Roof2' - -export default async function Roof2Page() { - return ( - <> -
- -
- - ) -} diff --git a/src/app/settings/page.jsx b/src/app/settings/page.jsx deleted file mode 100644 index ab714682..00000000 --- a/src/app/settings/page.jsx +++ /dev/null @@ -1,13 +0,0 @@ -import Hero from '@/components/Hero' -import Settings from '@/components/Settings' - -export default async function SettingsPage() { - return ( - <> - -
- -
- - ) -} diff --git a/src/components/GridSettingsModal.jsx b/src/components/GridSettingsModal.jsx deleted file mode 100644 index 92b2e618..00000000 --- a/src/components/GridSettingsModal.jsx +++ /dev/null @@ -1,273 +0,0 @@ -import { useEffect, useRef, useState } from 'react' -import { Button, Checkbox, CheckboxGroup, RadioGroup, Radio, Input } from '@nextui-org/react' -import { useRecoilState, useRecoilValue } from 'recoil' -import { modalContent, modalState } from '@/store/modalAtom' -import { guideLineState, horiGuideLinesState, vertGuideLinesState } from '@/store/canvasAtom' -import { fabric } from 'fabric' -import { ColorPicker, useColor } from 'react-color-palette' -import 'react-color-palette/css' -import { gridColorState } from '@/store/gridAtom' - -export default function GridSettingsModal(props) { - const { canvasProps } = props - const [isCustomGridSetting, setIsCustomGridSetting] = useState(true) - const [gridCheckedValue, setGridCheckValue] = useState([]) - const [ratioValue, setRatioValue] = useState('1') - const moduleLength = useRef(null) //모듈 mm 길이 입력 - const customModuleHoriLength = useRef(null) - const customModuleVertLength = useRef(null) - - const [open, setOpen] = useRecoilState(modalState) - const [guideLine, setGuideLine] = useRecoilState(guideLineState) - const [horiGuideLines, setHoriGuideLines] = useRecoilState(horiGuideLinesState) - const [vertGuideLines, setVertGuideLines] = useRecoilState(vertGuideLinesState) - - const gridSettingArray = [] - - const gridColor = useRecoilValue(gridColorState) - const [colorPickerShow, setColorPickerShow] = useState(false) - - const boxStyle = { - width: '50px', - height: '30px', - border: '1px solid black', - backgroundColor: guideColor.hex, - } - useEffect(() => { - moduleLength.current.value = 90 - customModuleHoriLength.current.value = 90 - customModuleVertLength.current.value = 90 - }, []) - - useEffect(() => { - setIsCustomGridSetting(ratioValue !== 'custom') - }, [ratioValue]) - - const drawGridSettings = () => { - //기존에 선택된 데이터가 있으면 그 데이터를 포함한다 - if (!(Object.keys(guideLine).length === 0 && guideLine.constructor === Object)) { - gridSettingArray.push(...guideLine) - } - - let moduleHoriLength = moduleLength.current.value //가로 간격 - let moduleVertLength = moduleLength.current.value //새로 간격 - - if (ratioValue === 'custom') { - moduleHoriLength = customModuleHoriLength.current.value - moduleVertLength = customModuleVertLength.current.value - } else { - moduleHoriLength = moduleHoriLength / ratioValue - moduleVertLength = moduleVertLength / ratioValue - } - - if (gridCheckedValue.includes('line')) { - const horizontalLineArray = [] - const verticalLineArray = [] - - for (let i = 0; i < canvasProps.height / moduleVertLength + 1; i++) { - const horizontalLine = new fabric.Line( - [0, i * moduleVertLength - moduleVertLength / 2, canvasProps.width, i * moduleVertLength - moduleVertLength / 2], - { - stroke: gridColor, - strokeWidth: 1, - selectable: true, - lockMovementX: true, - lockMovementY: true, - lockRotation: true, - lockScalingX: true, - lockScalingY: true, - name: 'guideLine', - strokeDashArray: [5, 2], - opacity: 0.3, - direction: 'horizontal', - }, - ) - canvasProps.add(horizontalLine) - horizontalLineArray.push(horizontalLine) - } - - for (let i = 0; i < canvasProps.width / moduleHoriLength + 1; i++) { - const verticalLine = new fabric.Line( - [i * moduleHoriLength - moduleHoriLength / 2, 0, i * moduleHoriLength - moduleHoriLength / 2, canvasProps.height], - { - stroke: gridColor, - strokeWidth: 1, - selectable: true, - lockMovementX: true, - lockMovementY: true, - lockRotation: true, - lockScalingX: true, - lockScalingY: true, - name: 'guideLine', - strokeDashArray: [5, 2], - opacity: 0.3, - direction: 'vertical', - }, - ) - canvasProps.add(verticalLine) - verticalLineArray.push(verticalLine) - } - canvasProps.renderAll() - - const snapDistance = 10 - - const recoilObj = { - guideMode: 'guideLine', - horizontalLineArray, - verticalLineArray, - moduleVertLength: moduleVertLength, - moduleHoriLength: moduleHoriLength, - } - gridSettingArray.push(recoilObj) - const newHoriGuideLines = [...horiGuideLines] - horizontalLineArray.forEach((line) => { - newHoriGuideLines.push(line) - }) - const newVertGuideLines = [...vertGuideLines] - verticalLineArray.forEach((line) => { - newVertGuideLines.push(line) - }) - setHoriGuideLines(newHoriGuideLines) - setVertGuideLines(newVertGuideLines) - } - - if (gridCheckedValue.includes('dot')) { - const circle = new fabric.Circle({ - radius: 2, - fill: 'white', - stroke: guideColor.hex, - strokeWidth: 0.7, - originX: 'center', - originY: 'center', - selectable: false, - lockMovementX: true, - lockMovementY: true, - lockRotation: true, - lockScalingX: true, - lockScalingY: true, - }) - - const patternSourceCanvas = new fabric.StaticCanvas(null, { - width: moduleHoriLength, - height: moduleVertLength, - }) - - patternSourceCanvas.add(circle) - - circle.set({ - left: patternSourceCanvas.width / 2, - top: patternSourceCanvas.height / 2, - }) - - patternSourceCanvas.renderAll() - - const pattern = new fabric.Pattern({ - source: patternSourceCanvas.getElement(), - repeat: 'repeat', - }) - - const backgroundPolygon = new fabric.Polygon( - [ - { x: 0, y: 0 }, - { x: canvasProps.width, y: 0 }, - { x: canvasProps.width, y: canvasProps.height }, - { x: 0, y: canvasProps.height }, - ], - { - fill: pattern, - selectable: false, - name: 'guideDot', - }, - ) - - canvasProps.add(backgroundPolygon) - backgroundPolygon.sendToBack() - canvasProps.renderAll() - - const recoilObj = { - guideMode: 'guideDot', - moduleVertLength: moduleVertLength, - moduleHoriLength: moduleHoriLength, - } - - gridSettingArray.push(recoilObj) - } - canvasProps.renderAll() - setGuideLine(gridSettingArray) - } - - const removeGuideLines = () => { - if (!(Object.keys(guideLine).length === 0 && guideLine.constructor === Object)) { - const guideLines = canvasProps._objects.filter((obj) => obj.name === 'guideLine' || obj.name === 'guideDot') - guideLines?.forEach((item) => canvasProps.remove(item)) - canvasProps.renderAll() - setGuideLine([]) - setHoriGuideLines([]) - setVertGuideLines([]) - } else { - alert('그리드가 없습니다.') - return - } - } - - return ( - <> -
-
- -
-
- - mm -
-
- - 원치수 - 1/2 - 1/4 - 1/10 - 임의간격 - -
-
- 가이드컬러
setColorPickerShow(!colorPickerShow)}>
-
- {colorPickerShow && ( - - )} - -
- - 종횡연동 - -
-
-
- - mm -
-
- - mm -
- -
- - - - -
- - ) -} diff --git a/src/components/Headers.jsx b/src/components/Headers.jsx deleted file mode 100644 index 02859c96..00000000 --- a/src/components/Headers.jsx +++ /dev/null @@ -1,21 +0,0 @@ -import Link from 'next/link' - -export default function Headers() { - return ( -
- -
- ) -} diff --git a/src/components/Hero.jsx b/src/components/Hero.jsx deleted file mode 100644 index a6e7761f..00000000 --- a/src/components/Hero.jsx +++ /dev/null @@ -1,7 +0,0 @@ -export default function Hero(props) { - return ( -
-

{props.title}

-
- ) -} diff --git a/src/components/InitSettingsModal.jsx b/src/components/InitSettingsModal.jsx deleted file mode 100644 index 4cfc483d..00000000 --- a/src/components/InitSettingsModal.jsx +++ /dev/null @@ -1,253 +0,0 @@ -'use client' - -import { useEffect, useState, memo, useCallback } from 'react' -import { Button, Checkbox, CheckboxGroup, RadioGroup, Radio, Input, Select, SelectItem } from '@nextui-org/react' -import { useRecoilState, useRecoilValue } from 'recoil' -import { modalContent, modalState } from '@/store/modalAtom' -import { canvasSettingState } from '@/store/canvasAtom' -import { useAxios } from '@/hooks/useAxios' - -export default function InitSettingsModal(props) { - const [objectNo, setObjectNo] = useState('test123240909003') // 후에 삭제 필요 - const [open, setOpen] = useRecoilState(modalState) - const [canvasSetting, setCanvasSetting] = useRecoilState(canvasSettingState) - const [roofMaterials, setRoofMaterials] = useState([]) - const [basicSetting, setBasicSettings] = useState({ - roofDrawingSet: '1', - roofSizeSet: '1', - roofAngleSet: 'slope', - roofs: [{ roofSeq: '1', roofType: '3', roofWidth: '200', roofHeight: '200', roofGap: '0', roofLayout: 'parallel' }], - }) - - const modelProps = { - open, - setOpen, - } - - const { get, post } = useAxios() - - useEffect(() => { - get({ url: `/api/canvas-management/canvas-basic-settings/by-object/${objectNo}` }).then((res) => { - if (res.length == 0) return - - // 'roofs' 배열을 생성하여 각 항목을 추가 - const roofsRow = res.map((item) => { - return { - roofDrawingSet: String(item.roofDrawingSet), - roofSizeSet: String(item.roofSizeSet), - roofAngleSet: item.roofAngleSet, - } - }) - - const roofsArray = res.some((item) => !item.roofSeq) - ? //최초 지붕재 추가 정보의 경우 roofsArray를 초기화 설정 - [{ roofSeq: '1', roofType: '3', roofWidth: '200', roofHeight: '200', roofGap: '0', roofLayout: 'parallel' }] - : res.map((item) => ({ - roofSeq: String(item.roofSeq), - roofType: String(item.roofType), - roofWidth: String(item.roofWidth), - roofHeight: String(item.roofHeight), - roofGap: String(item.roofGap), - roofLayout: item.roofLayout, - })) - - // 나머지 데이터와 함께 'roofs' 배열을 patternData에 넣음 - const patternData = { - roofDrawingSet: roofsRow[0].roofDrawingSet, // 첫 번째 항목의 값을 사용 - roofSizeSet: roofsRow[0].roofSizeSet, // 첫 번째 항목의 값을 사용 - roofAngleSet: roofsRow[0].roofAngleSet, // 첫 번째 항목의 값을 사용 - roofs: roofsArray, // 만들어진 roofs 배열 - } - - // 데이터 설정 - setBasicSettings({ ...patternData }) - }) - - if (!(Object.keys(canvasSetting).length === 0 && canvasSetting.constructor === Object)) { - setBasicSettings({ ...canvasSetting }) - } - }, []) - - //기본 설정값 변경 함수 - const handleBasicSetting = (event) => { - const newBasicSetting = { ...basicSetting, [event.target.name]: event.target.value } - setBasicSettings(newBasicSetting) - } - - //배열 값 변경 함수 - const handleRoofSettings = (id, event) => { - // 기본 세팅에서 roofs 배열을 복사 - const updatedRoofs = [...basicSetting.roofs] - - // roofSeq가 id와 일치하는 항목의 인덱스 찾기 - const index = updatedRoofs.findIndex((roof) => roof.roofSeq === id) - - if (index !== -1) { - // 해당 인덱스의 항목을 수정 - updatedRoofs[index] = { - ...updatedRoofs[index], - [event.target.name]: event.target.value, - } - - // 수정된 배열을 상태에 반영 - setBasicSettings((prevState) => ({ - ...prevState, - roofs: updatedRoofs, - })) - } - } - - //저장 - const submitCanvasConfig = async () => { - if (!objectNo) { - alert('object_no를 입력하세요.') - return - } - - const patternData = { - objectNo, - roofDrawingSet: basicSetting.roofDrawingSet, - roofSizeSet: basicSetting.roofSizeSet, - roofAngleSet: basicSetting.roofAngleSet, - roofMaterialsAddList: basicSetting.roofs, - } - await post({ url: `/api/canvas-management/canvas-basic-settings`, data: patternData }) - - //Recoil 설정 - setCanvasSetting({ ...basicSetting }) - - // 저장 후 재조회 - //await handleSelect() - } - - return ( - <> -
-
배치면 초기설정
- -
-
- - 치수 입력에 의한 물건작성 - -
-
- -
-
- - 복사도 입력 - 실측값 입력 - 육지붕 - -
-
- -
-
- - 경사 - 각도 - -
-
- - {/* Roofs Array Rendering */} - {basicSetting.roofs && - basicSetting.roofs.map((roof, index) => { - return ( -
- 타입 : - - 너비 : - handleRoofSettings(roof.roofSeq, e)} - /> - mm - 높이 : - handleRoofSettings(roof.roofSeq, e)} - /> - mm - 서까래 간격 : - handleRoofSettings(roof.roofSeq, e)} - /> - mm -
- handleRoofSettings(roof.roofSeq, e)} - > - 병렬식 - 계단식 - -
-
- ) - })} - -
- - - setObjectNo(e.target.value)} /> -
-
- - ) -} diff --git a/src/components/Playground.jsx b/src/components/Playground.jsx deleted file mode 100644 index 8a365646..00000000 --- a/src/components/Playground.jsx +++ /dev/null @@ -1,919 +0,0 @@ -'use client' - -import { useRef, useState, useEffect, useContext } from 'react' -import Image from 'next/image' -import { useRecoilState } from 'recoil' -import { v4 as uuidv4 } from 'uuid' -import { FaAnglesUp } from 'react-icons/fa6' -import { FaAnglesDown } from 'react-icons/fa6' -import { Button } from '@nextui-org/react' -import ColorPicker from './common/color-picker/ColorPicker' -import { cadFileNameState, googleMapFileNameState, useCadFileState, useGoogleMapFileState } from '@/store/canvasAtom' - -import { useAxios } from '@/hooks/useAxios' -import { useMessage } from '@/hooks/useMessage' -import { useMasterController } from '@/hooks/common/useMasterController' -import { useSwal } from '@/hooks/useSwal' -import { convertDwgToPng } from '@/lib/cadAction' -import { GlobalDataContext } from '@/app/GlobalDataProvider' -import QInput from './common/input/Qinput' -import QSelect from './common/select/QSelect' -import QPagination from './common/pagination/QPagination' -import QSelectBox from './common/select/QSelectBox' -import SampleReducer from './sample/SampleReducer' - -import styles from './playground.module.css' -import useSWR from 'swr' -import useSWRMutation from 'swr/mutation' -import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController' -import { canvasPopupStatusStore } from '@/store/canvasPopupStatusAtom' -import { moduleSelectionDataPlanListState } from '@/store/selectedModuleOptions' -import { useRouter } from 'next/navigation' -import { QcastContext } from '@/app/QcastProvider' - -export default function Playground() { - const [useCadFile, setUseCadFile] = useRecoilState(useCadFileState) - const [cadFileName, setCadFileName] = useRecoilState(cadFileNameState) - const [useGoogleMapFile, setUseGoogleMapFile] = useRecoilState(useGoogleMapFileState) - const [googleMapFileName, setGoogleMapFileName] = useRecoilState(googleMapFileNameState) - const fileRef = useRef(null) - const queryRef = useRef(null) - const [zoom, setZoom] = useState(20) - const { get, promiseGet, post, promisePost, getFetcher, postFetcher } = useAxios() - const testVar = process.env.NEXT_PUBLIC_TEST - const converterUrl = process.env.NEXT_PUBLIC_CONVERTER_API_URL - const { getMessage } = useMessage() - const { swalFire } = useSwal() - const { getRoofMaterialList, getModuleTypeItemList, getTrestleList, getConstructionList, getTrestleDetailList } = useMasterController() - - const [color, setColor] = useState('#ff0000') - - const [textInput, setTextInput] = useState('') - const [numberInput, setNumberInput] = useState('') - const [radioInput, setRadioInput] = useState('') - const [checkboxInput, setCheckboxInput] = useState([]) - const [selectedValue, setSelectedValue] = useState('') - - const [users, setUsers] = useState([]) - - const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext) - - const router = useRouter() - const { setIsGlobalLoading } = useContext(QcastContext) - - useEffect(() => { - setIsGlobalLoading(false) - }, []) - - useEffect(() => { - console.log('textInput:', textInput) - }, [textInput]) - useEffect(() => { - console.log('numberInput:', numberInput) - }, [numberInput]) - useEffect(() => { - console.log('radioInput:', radioInput) - }, [radioInput]) - useEffect(() => { - console.log('checkboxInput:', checkboxInput) - }, [checkboxInput]) - useEffect(() => { - console.log('selectedValue:', selectedValue) - }, [selectedValue]) - - const handleUsers = async () => { - // const users = await get('/api/user/find-all') - const params = { - url: '/api/user/find-all', - } - const users = await get(params) - console.log('users', users) - } - - const handleConvert = async () => { - console.log('file', fileRef.current.files[0]) - - const formData = new FormData() - formData.append('file', fileRef.current.files[0]) - - await promisePost({ url: converterUrl, data: formData }) - .then((res) => { - console.log('response: ', res) - convertDwgToPng(res.data.Files[0].FileName, res.data.Files[0].FileData) - setUseCadFile(true) - setCadFileName(res.data.Files[0].FileName) - swalFire({ text: '파일 변환 완료' }) - }) - .catch((err) => { - console.error(err) - swalFire({ text: '파일 변환 실패' }) - }) - } - - const handleDownImage = async (fileName = '') => { - const fileNm = fileName === '' ? uuidv4() : fileName - const queryString = queryRef.current.value === '' ? '서울시 서대문구 연세로5다길 22-3 발리빌라 3층' : queryRef.current.value - const res = await get({ url: `http://localhost:3000/api/html2canvas?q=${queryString}&fileNm=${fileNm}&zoom=${zoom}` }) - console.log('res', res) - setGoogleMapFileName(res.fileNm) - swalFire({ text: '이미지 저장 완료' }) - setUseGoogleMapFile(true) - } - - const handleZoom = async (type) => { - if (type === 'up') { - setZoom((prevState) => prevState + 1) - } else { - setZoom((prevState) => prevState - 1) - } - - await handleDownImage() - } - - const data = [ - { - id: 1, - author: 'SWYOO', - contents: '버튼 정리(템플릿 적용)', - date: '2024.07.16', - }, - { - id: 2, - author: 'SWYOO', - contents: 'README.md 파일 이미지 경로 수정', - date: '2024.07.17', - }, - { - id: 3, - author: 'SWYOO', - contents: '', - date: '', - }, - ] - - const handleSwalAlert = () => { - swalFire({ - text: '알림 테스트입니다.', - }) - } - - const paginationProps = { - pageNo: 1, - pageSize: 10, - pagePerBlock: 10, - totalCount: 26, - handleChangePage: (page) => { - console.log('page', page) - }, - } - - useEffect(() => { - console.log('users:', users) - }, [users]) - - const codes = [ - { - clHeadCd: '203800', - clCode: 'HEI_455', - clCodeNm: '세로 455mm이하', - clPriority: 1, - name: '세로 455mm이하', - id: 'HEI_455', - }, - { - clHeadCd: '203800', - clCode: 'HEI_500', - clCodeNm: '세로 500mm이하', - clPriority: 2, - name: '세로 500mm이하', - id: 'HEI_500', - }, - { - clHeadCd: '203800', - clCode: 'HEI_606', - clCodeNm: '세로 606mm이하', - clPriority: 3, - name: '세로 606mm이하', - id: 'HEI_606', - }, - { - clHeadCd: '203800', - clCode: 'WID_606', - clCodeNm: '가로 606mm이하', - clPriority: 4, - name: '가로 606mm이하', - id: 'WID_606', - }, - { - clHeadCd: '203800', - clCode: 'ETC', - clCodeNm: '기타', - clPriority: 5, - name: '기타', - id: 'ETC', - }, - ] - - const [myData, setMyData] = useState({ - roofMatlCd: 'ROOF_ID_WA_53A', - roofMatlNm: '화와 A', - roofMatlNmJp: '和瓦A', - widAuth: 'R', - widBase: '265.000', - lenAuth: 'R', - lenBase: '235.000', - roofPchAuth: null, - roofPchBase: null, - raftAuth: 'C', - raftBaseCd: 'HEI_455', - id: 'ROOF_ID_WA_53A', - name: '화와 A', - selected: true, - nameJp: '和瓦A', - length: 235, - width: 265, - layout: 'P', - hajebichi: null, - }) - - const handleChangeMyData = () => { - setMyData({ ...myData, raftBaseCd: 'HEI_500' }) - } - - const [myData2, setMyData2] = useState({}) - - const handleChangeMyData2 = () => { - setMyData2({ - roofMatlCd: 'ROOF_ID_WA_53A', - roofMatlNm: '화와 A', - roofMatlNmJp: '和瓦A', - widAuth: 'R', - widBase: '265.000', - lenAuth: 'R', - lenBase: '235.000', - roofPchAuth: null, - roofPchBase: null, - raftAuth: 'C', - raftBaseCd: 'HEI_455', - id: 'ROOF_ID_WA_53A', - name: '화와 A', - selected: true, - nameJp: '和瓦A', - length: 235, - width: 265, - layout: 'P', - hajebichi: null, - }) - } - - // const [callFlag, setCallFlag] = useState(false) - // const { data: tutoData, error, isLoading } = useSWR('http://localhost:8080/api/tutorial', getFetcher) - // const { data: tutoData, error, isLoading } = useSWR(callFlag ? 'http://localhost:8080/api/tutorial' : null, getFetcher) - // const { trigger, isMutating } = useSWRMutation('http://localhost:8080/api/tutorial', postFetcher) - - // if (isLoading) { - // return
Loading...
- // } - - // if (error) { - // return
Error...
- // } - - // const [moduleSelectionDataPlanListStore, setModuleSelectionDataPlanListStore] = useRecoilState(moduleSelectionDataPlanListState) - // useEffect(() => { - // console.log('🚀 ~ Playground ~ moduleSelectionDataPlanListStore:', moduleSelectionDataPlanListStore) - // }, [moduleSelectionDataPlanListStore]) - // const { trigger: canvasPopupStatusTrigger } = useCanvasPopupStatusController({ objectNo: 'R201T01241120001', planNo: 2, popupType: 2 }) - - return ( - <> -
-
이 영역은 테스트입니다.
-
- {' '} - {' '} - {' '} - {' '} - -
- -
- - - -
- - - -
- - -
- - -
-
-
- - - - -
-
{testVar}
-
-
- -
-
-
-

Sass 테스트입니다.

-
-
test']) }}>
-
-

React ColorPicker

- -
{color}
-
-
-

캐드 파일 이미지 사용

- -
- -
-
-
-

구글 맵 이미지 사용

- -
- -
- {useGoogleMapFile && ( - <> -
-

Zoom Controller : {zoom}

- - -
-
- -
- - )} -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
- {/*
-

{managementStateLoaded?.objectNo}

-
*/} -
- -
- {/*
- {tutoData && - tutoData.map((item) => ( -
- {item.name} / {item.email} -
- ))} -
-
- -
-
- -
*/} -
- -
-
- -
-
- - ) -} diff --git a/src/components/Roof.jsx b/src/components/Roof.jsx deleted file mode 100644 index 51ba639e..00000000 --- a/src/components/Roof.jsx +++ /dev/null @@ -1,351 +0,0 @@ -'use client' - -import { useEffect } from 'react' -import { addDistanceTextToPolygon, getDistance } from '@/util/canvas-util' -import { useCanvas } from '@/hooks/useCanvas' -import { fabric } from 'fabric' -import { v4 as uuidv4 } from 'uuid' - -export default function Roof() { - const { - canvas, - addShape, - handleUndo, - handleRedo, - handleClear, - handleCopy, - handleDelete, - handleSave, - handlePaste, - handleRotate, - attachCustomControlOnPolygon, - saveImage, - handleFlip, - } = useCanvas('canvas') - - useEffect(() => { - let circle = new fabric.Circle({ - radius: 40, - fill: 'rgba(200, 0, 0, 0.3)', - originX: 'center', - originY: 'center', - }) - - let text = new fabric.Textbox('AJLoveChina', { - originX: 'center', - originY: 'center', - textAlign: 'center', - fontSize: 12, - }) - - let group = new fabric.Group([circle, text], { - left: 100, - top: 100, - originX: 'center', - originY: 'center', - }) - - group.on('mousedblclick', () => { - // textForEditing is temporary obj, - // and will be removed after editing - console.log(text.type) - let textForEditing = new fabric.Textbox(text.text, { - originX: 'center', - originY: 'center', - textAlign: text.textAlign, - fontSize: text.fontSize, - - left: group.left, - top: group.top, - }) - - // hide group inside text - text.visible = false - // note important, text cannot be hidden without this - group.addWithUpdate() - - textForEditing.visible = true - // do not give controls, do not allow move/resize/rotation on this - textForEditing.hasConstrols = false - - // now add this temporary obj to canvas - canvas.add(textForEditing) - canvas.setActiveObject(textForEditing) - // make the cursor showing - textForEditing.enterEditing() - textForEditing.selectAll() - - // editing:exited means you click outside of the textForEditing - textForEditing.on('editing:exited', () => { - let newVal = textForEditing.text - let oldVal = text.text - - // then we check if text is changed - if (newVal !== oldVal) { - text.set({ - text: newVal, - visible: true, - }) - - // comment before, you must call this - group.addWithUpdate() - - // we do not need textForEditing anymore - textForEditing.visible = false - canvas?.remove(textForEditing) - - // optional, buf for better user experience - canvas?.setActiveObject(group) - } - }) - }) - - canvas?.add(group) - }, [canvas]) - - const addRect = () => { - const rect = new fabric.Rect({ - height: 200, - width: 200, - top: 10, - left: 10, - opacity: 0.4, - fill: randomColor(), - stroke: 'red', - name: uuidv4(), - }) - - addShape(rect) - } - - const addHorizontalLine = () => { - const { x1, y1, x2, y2 } = { x1: 20, y1: 100, x2: 220, y2: 100 } - /** - * 시작X,시작Y,도착X,도착Y 좌표 - */ - const horizontalLine = new fabric.Line([x1, y1, x2, y2], { - name: uuidv4(), - stroke: 'red', - strokeWidth: 3, - selectable: true, - }) - - const text = new fabric.Text(getDistance(x1, y1, x2, y2).toString(), { - fontSize: 20, - left: (x2 - x1) / 2, - top: y1 - 20, - }) - - const group = new fabric.Group([horizontalLine, text], { - left: 20, - top: 20, - }) - - // addShape(horizontalLine) - addShape(group) - console.log(JSON.stringify(canvas)) - } - - const addVerticalLine = () => { - const verticalLine = new fabric.Line([10, 10, 10, 100], { - name: uuidv4(), - stroke: 'red', - strokeWidth: 3, - selectable: true, - }) - - addShape(verticalLine) - } - - const addTriangle = () => { - const triangle = new fabric.Triangle({ - name: uuidv4(), - top: 50, - left: 50, - width: 100, - stroke: randomColor(), - strokeWidth: 3, - }) - - addShape(triangle) - } - - const addTrapezoid = () => { - const trapezoid = new fabric.Polygon( - [ - { x: 100, y: 100 }, // 좌상단 - { x: 500, y: 100 }, // 우상단 - { x: 750, y: 700 }, // 우하단 - { x: 250, y: 400 }, // 좌하단 - ], - { - name: uuidv4(), - stroke: 'red', - opacity: 0.4, - strokeWidth: 3, - selectable: true, - objectCaching: false, - }, - ) - attachCustomControlOnPolygon(trapezoid) - const group = addDistanceTextToPolygon(trapezoid) - addGroupClickEvent(group) - canvas?.add(group) - canvas?.renderAll() - } - - // group에 클릭 이벤트를 추가하여 클릭 시 group을 제거하고 object들만 남기는 함수 - function addGroupClickEvent(group) { - group.on('selected', (e) => { - console.log(e) - }) - group.on('mousedblclick', (e) => { - // textForEditing is temporary obj, - // and will be removed after editing - const pointer = canvas?.getPointer(e.e) // 마우스 클릭 위치 가져오기 - let minDistance = Infinity - let closestTextbox = null - const groupPoint = group.getCenterPoint() - group.getObjects().forEach(function (object) { - if (object.type === 'textbox') { - // 객체가 TextBox인지 확인 - - const objectCenter = object.getCenterPoint() // TextBox 객체의 중심점 가져오기 - const dx = objectCenter.x + groupPoint.x - pointer.x - const dy = objectCenter.y + groupPoint.y - pointer.y - const distance = Math.sqrt(dx * dx + dy * dy) // 마우스 클릭 위치와 TextBox 객체 사이의 거리 계산 - - if (distance < minDistance) { - // 가장 짧은 거리를 가진 TextBox 객체 찾기 - minDistance = distance - closestTextbox = object - } - } - }) - - let textForEditing = new fabric.Textbox(closestTextbox.text, { - originX: 'center', - originY: 'center', - textAlign: closestTextbox.textAlign, - fontSize: closestTextbox.fontSize, - left: closestTextbox.left + groupPoint.x, - top: closestTextbox.top + groupPoint.y, - }) - - // hide group inside text - closestTextbox.visible = false - // note important, text cannot be hidden without this - group.addWithUpdate() - - textForEditing.visible = true - // do not give controls, do not allow move/resize/rotation on this - textForEditing.hasConstrols = false - - // now add this temporary obj to canvas - canvas?.add(textForEditing) - canvas?.setActiveObject(textForEditing) - // make the cursor showing - textForEditing?.enterEditing() - textForEditing?.selectAll() - - // editing:exited means you click outside of the textForEditing - textForEditing?.on('editing:exited', () => { - let newVal = textForEditing.text - - // then we check if text is changed - closestTextbox.set({ - text: newVal, - visible: true, - }) - - // comment before, you must call this - group.addWithUpdate() - - // we do not need textForEditing anymore - textForEditing.visible = false - canvas?.remove(textForEditing) - - // optional, buf for better user experience - canvas?.setActiveObject(group) - }) - }) - } - - // IText를 수정할 때 해당 값을 길이로 갖는 다른 polygon을 생성하고 다시 그룹화하는 함수 - function addTextModifiedEvent(text, polygon, index) { - text.on('editing:exited', function () {}) - } - - const randomColor = () => { - return '#' + Math.round(Math.random() * 0xffffff).toString(16) - } - - return ( - <> -
- - - - - - - - - - - - - - - -
- -
- -
- - ) -} diff --git a/src/components/Roof2.jsx b/src/components/Roof2.jsx deleted file mode 100644 index 731fe8c6..00000000 --- a/src/components/Roof2.jsx +++ /dev/null @@ -1,1099 +0,0 @@ -'use client' - -import { useCanvas } from '@/hooks/useCanvas' -import { useEffect, useRef, useState } from 'react' -import { v4 as uuidv4 } from 'uuid' -import { useMode } from '@/hooks/useMode' -import { LINE_TYPE, Mode } from '@/common/common' -import { Button } from '@nextui-org/react' -import RangeSlider from './ui/RangeSlider' -import { useRecoilState, useRecoilValue } from 'recoil' -import { - cadFileCompleteState, - cadFileNameState, - canvasSizeState, - compassState, - currentObjectState, - fontSizeState, - globalCompassState, - googleMapFileNameState, - roofMaterialState, - roofState, - sortedPolygonArray, - templateTypeState, - useCadFileState, - useGoogleMapFileState, - wallState, -} from '@/store/canvasAtom' -import { QLine } from '@/components/fabric/QLine' -import { getCanvasState, insertCanvasState } from '@/lib/canvas' -import { calculateIntersection } from '@/util/canvas-util' -import { QPolygon } from '@/components/fabric/QPolygon' -import QContextMenu from './common/context-menu/QContextMenu' -import { modalContent, modalState } from '@/store/modalAtom' -import { useAxios } from '@/hooks/useAxios' -import QPolygonContextMenu from '@/components/common/context-menu/QPolygonContextMenu' -import QLineContextMenu from '@/components/common/context-menu/QLineContextMenu' -import QEmptyContextMenu from '@/components/common/context-menu/QEmptyContextMenu' - -import InitSettingsModal from './InitSettingsModal' -import GridSettingsModal from './GridSettingsModal' -import { SurfaceShapeModal } from '@/components/ui/SurfaceShape' -import { changeCurrentRoof, drawDirectionStringToArrow } from '@/util/qpolygon-utils' -import ThumbnailList from '@/components/ui/ThumbnailLIst' -import ObjectPlacement from '@/components/ui/ObjectPlacement' -import { globalLocaleStore } from '@/store/localeAtom' - -export default function Roof2(props) { - const { name, userId, email, isLoggedIn } = props - const { - canvas, - handleRedo, - handleUndo, - setCanvasBackgroundWithDots, - saveImage, - addCanvas, - handleBackImageLoadToCanvas, - handleCadImageInit, - backImg, - setBackImg, - } = useCanvas('canvas') - - const globalLocaleState = useRecoilValue(globalLocaleStore) - - const { get } = useAxios(globalLocaleState) - - const canvasRef = useRef(null) - - //canvas 기본 사이즈 - const [canvasSize, setCanvasSize] = useRecoilState(canvasSizeState) - - //canvas 가로 사이즈 - const [verticalSize, setVerticalSize] = useState(canvasSize.vertical) - //canvas 세로 사이즈 - const [horizontalSize, setHorizontalSize] = useState(canvasSize.horizontal) - // 글자크기 - const [fontSize, setFontSize] = useRecoilState(fontSizeState) - - const [sortedArray] = useRecoilState(sortedPolygonArray) - - const [angle, setAngle] = useState(0) - - const [showControl, setShowControl] = useState(false) - - //지붕재 - const roofMaterial = useRecoilValue(roofMaterialState) - - const [templateType, setTemplateType] = useRecoilState(templateTypeState) - - const [compass, setCompass] = useRecoilState(compassState) - - const roof = useRecoilValue(roofState) - - const wall = useRecoilValue(wallState) - - const [open, setOpen] = useRecoilState(modalState) - const [contents, setContent] = useRecoilState(modalContent) - - const [scale, setScale] = useState(1) - const currentObject = useRecoilValue(currentObjectState) - - //canvas 썸네일 - const [thumbnails, setThumbnails] = useState([]) - const thumbnailProps = { - thumbnails, - canvas, - } - - let imgPath - // cad 파일 업로드 - const [useCadFile, setUseCadFile] = useRecoilState(useCadFileState) - const [cadFileName, setCadFileName] = useRecoilState(cadFileNameState) - const [cadFileComplete, setCadFileComplete] = useRecoilState(cadFileCompleteState) - useCadFile && (imgPath = `/cadImages/${cadFileName}`) - - // 구글맵 이미지 업로드 - const [useGoogleMapFile, setUseGoogleMapFile] = useRecoilState(useGoogleMapFileState) - const [googleMapFileName, setGoogleMapFileName] = useRecoilState(googleMapFileNameState) - useGoogleMapFile && (imgPath = `/mapImages/${googleMapFileName}`) - - const [globalCampass, setGlobalCampass] = useRecoilState(globalCompassState) - - const { - mode, - setMode, - changeMode, - handleClear, - zoomIn, - zoomOut, - zoom, - togglePolygonLine, - handleOuterlinesTest, - handleOuterlinesTest2, - applyTemplateB, - makeRoofPatternPolygon, - createRoofRack, - drawRoofPolygon, - drawCellInTrestle, - drawCellManualInTrestle, - setDirectionTrestles, - cutHelpLines, - } = useMode() - - // const [canvasState, setCanvasState] = useRecoilState(canvasAtom) - - useEffect(() => { - get({ url: `/api/canvas-management/canvas-statuses/by-object/test123240822001/${userId}` }).then((res) => { - // console.log(res) - - const arrangeData = res.map((item) => { - // console.log(item.canvasStatus.replace(/##/g, '"').replace(/\\/g, '')) - const test = item.canvasStatus.replace(/##/g, '"').replace(/\\/g, '') - const test2 = test.substring(1, test.length - 1) - return { - id: item.id, - userId: item.userId, - imageName: `/canvasState/${item.imageName}.png`, - canvasStatus: JSON.stringify(test2), - } - }) - setThumbnails(arrangeData) - }) - }, []) - - useEffect(() => { - if (!canvas) { - return - } - changeMode(canvas, mode) - - if (!cadFileComplete && useCadFile) { - // cad 파일 로드 - useCadFile && handleBackImageLoadToCanvas(imgPath, canvas) - } - - if (useGoogleMapFile) { - handleBackImageLoadToCanvas(imgPath, canvas) - } - }, [canvas, mode]) - - const makeLine = () => { - if (canvas) { - const line = new QLine([50, 50, 200, 50], { - stroke: 'black', - selectable: true, - strokeWidth: 2, - fontSize: fontSize, - }) - - canvas?.add(line) - } - } - - const makePolygon = () => { - if (canvas) { - const polygon = new QPolygon( - [ - { x: 100, y: 100 }, - { x: 600, y: 200 }, - { x: 700, y: 800 }, - { x: 100, y: 800 }, - ], - { - fill: 'transparent', - stroke: 'black', - strokeWidth: 2, - selectable: true, - fontSize: fontSize, - }, - ) - canvas?.add(polygon) - - // polygon.fillCell({ width: 50, height: 30, padding: 10 }) - } - } - - useEffect(() => { - setCanvasSize({ ...canvasSize, vertical: parseInt(verticalSize), horizontal: parseInt(horizontalSize) }) - }, [verticalSize, horizontalSize]) - - /** - * 값 변경시 - */ - // useEffect(() => { - // canvasSizeMode() - // }, [verticalSize, horizontalSize]) - useEffect(() => { - const { vertical, horizontal } = canvasSize - if (vertical !== verticalSize || horizontal !== horizontalSize) { - canvas?.setWidth(horizontalSize) - canvas?.setHeight(verticalSize) - canvas?.renderAll() - } - }, [canvasSize, canvas]) - - const makeQPolygon = () => { - const type1 = [ - { x: 100, y: 100 }, - { x: 850, y: 100 }, - { x: 850, y: 800 }, - { x: 500, y: 800 }, - { x: 500, y: 400 }, - { x: 100, y: 400 }, - ] - const type2 = [ - { x: 200, y: 100 }, - { x: 200, y: 1000 }, - { x: 1100, y: 1000 }, - { x: 1100, y: 600 }, - { x: 650, y: 600 }, - { x: 650, y: 100 }, - ] - - const type3 = [ - { x: 200, y: 100 }, - { x: 200, y: 800 }, - { x: 500, y: 800 }, - { x: 500, y: 300 }, - { x: 800, y: 300 }, - { x: 800, y: 100 }, - ] - - const type4 = [ - { x: 150, y: 450 }, - { x: 150, y: 800 }, - { x: 750, y: 800 }, - { x: 750, y: 300 }, - { x: 550, y: 300 }, - { x: 550, y: 450 }, - ] - - const type1A = [ - { x: 67, y: 81 }, - { x: 67, y: 660 }, - { x: 437, y: 660 }, - { x: 437, y: 1190 }, - { x: 858, y: 1190 }, - { x: 858, y: 81 }, - ] - - const type1B = [ - { x: 137, y: 42 }, - { x: 137, y: 621 }, - { x: 667, y: 621 }, - { x: 667, y: 991 }, - { x: 1088, y: 991 }, - { x: 1088, y: 42 }, - ] - - const eightPoint = [ - { x: 240.1111, y: 130.1111 }, - { x: 240.1111, y: 630.1111 }, - { x: 640.1111, y: 630.1111 }, - { x: 640.1111, y: 480.1111 }, - { x: 440.1111, y: 480.1111 }, - { x: 440.1111, y: 280.1111 }, - { x: 740.1111, y: 280.1111 }, - { x: 740.1111, y: 130.1111 }, - ] - - const eightPoint2 = [ - { x: 197, y: 215 }, - { x: 197, y: 815 }, - { x: 397, y: 815 }, - { x: 397, y: 1115 }, - { x: 697, y: 1115 }, - { x: 697, y: 815 }, - { x: 897, y: 815 }, - { x: 897, y: 215 }, - ] - - const eightPoint3 = [ - { x: 190, y: 147 }, - { x: 190, y: 747 }, - { x: 490, y: 747 }, - { x: 490, y: 497 }, - { x: 640, y: 497 }, - { x: 640, y: 747 }, - { x: 1090, y: 747 }, - { x: 1090, y: 147 }, - ] - - const eightPoint4 = [ - { x: 200, y: 200 }, - { x: 200, y: 400 }, - { x: 500, y: 400 }, - { x: 500, y: 700 }, - { x: 800, y: 700 }, - { x: 800, y: 400 }, - { x: 1100, y: 400 }, - { x: 1100, y: 200 }, - ] - - const eightPoint5 = [ - { x: 140, y: 101 }, - { x: 140, y: 601 }, - { x: 440, y: 601 }, - { x: 440, y: 801 }, - { x: 840, y: 801 }, - { x: 840, y: 601 }, - { x: 1140, y: 601 }, - { x: 1140, y: 101 }, - ] - - const twelvePoint = [ - { x: 195, y: 166 }, - { x: 195, y: 466 }, - { x: 395, y: 466 }, - { x: 395, y: 766 }, - { x: 545, y: 766 }, - { x: 545, y: 466 }, - { x: 695, y: 466 }, - { x: 695, y: 666 }, - { x: 845, y: 666 }, - { x: 845, y: 466 }, - { x: 995, y: 466 }, - { x: 995, y: 166 }, - ] - - const twelvePoint2 = [ - { x: 165, y: 81 }, - { x: 165, y: 1081 }, - { x: 465, y: 1081 }, - { x: 465, y: 781 }, - { x: 765, y: 781 }, - { x: 765, y: 1081 }, - { x: 1065, y: 1081 }, - { x: 1065, y: 581 }, - { x: 765, y: 581 }, - { x: 765, y: 281 }, - { x: 1065, y: 281 }, - { x: 1065, y: 81 }, - ] - - const complicatedType = [ - { x: 100, y: 100 }, - { x: 100, y: 1100 }, - { x: 400, y: 1100 }, - { x: 400, y: 800 }, - { x: 700, y: 800 }, - { x: 700, y: 1100 }, - { x: 1000, y: 1100 }, - { x: 1000, y: 600 }, - { x: 700, y: 600 }, - { x: 700, y: 300 }, - { x: 1000, y: 300 }, - { x: 1000, y: 100 }, - ] - - const testType = [ - { x: 500, y: 400 }, - { x: 650, y: 550 }, - { x: 575, y: 625 }, - { x: 325, y: 625 }, - { x: 100, y: 400 }, - ] - - const testType2 = [ - { x: 100, y: 400 }, - { x: 325, y: 625 }, - { x: 575, y: 625 }, - { x: 650, y: 550 }, - { x: 500, y: 400 }, - ] - - const triangleType = [ - { x: 100, y: 100 }, - { x: 100, y: 600 }, - { x: 600, y: 600 }, - { x: 600, y: 100 }, - ] - - const rectangleType1 = [ - { x: 500, y: 100 }, - { x: 500, y: 800 }, - { x: 900, y: 800 }, - { x: 900, y: 100 }, - ] - - const rectangleType2 = [ - { x: 100, y: 100 }, - { x: 100, y: 300 }, - { x: 600, y: 300 }, - { x: 600, y: 100 }, - ] - - const types = [type1, type2, type3, type4, type1A, type1B, eightPoint, eightPoint2, eightPoint3, eightPoint4, twelvePoint] - const newP = [ - { x: 450, y: 450 }, - { x: 650, y: 250 }, - { x: 675, y: 275 }, - { x: 450, y: 850 }, - ] - - const test1 = [ - { x: 381, y: 178 }, - { x: 381, y: 659.3 }, - { x: 773.3, y: 659.3 }, - { x: 773.3, y: 497.9 }, - { x: 1457, y: 497.9 }, - { x: 1457, y: 178 }, - ] - - const test2 = [ - { x: 113, y: 114.9 }, - { x: 113, y: 371.9 }, - { x: 762, y: 371.9 }, - { x: 762, y: 818.7 }, - { x: 1478.6, y: 818.7 }, - { x: 1478.6, y: 114.9 }, - ] - - const test3 = [ - { x: 100, y: 100 }, - { x: 100, y: 600 }, - { x: 600, y: 600 }, - { x: 600, y: 100 }, - { x: 500, y: 100 }, - { x: 500, y: 200 }, - { x: 200, y: 200 }, - { x: 200, y: 100 }, - ] - - const test4 = [ - { x: 100, y: 100 }, - { x: 100, y: 1000 }, - { x: 1100, y: 1000 }, - { x: 1100, y: 550 }, - { x: 500, y: 550 }, - { x: 500, y: 100 }, - ] - - const polygon = new QPolygon(test4, { - fill: 'transparent', - stroke: 'green', - strokeWidth: 1, - selectable: false, - fontSize: fontSize, - name: 'wall', - }) - - canvas?.add(polygon) - handleOuterlinesTest2(polygon, 50) - setTemplateType(1) - } - - const rotateShape = () => { - if (canvas) { - const activeObject = canvas?.getActiveObject() - - if (activeObject) { - activeObject.rotate(angle) - canvas?.renderAll() - } - } - } - - const makeQLine = () => { - if (canvas) { - const line = new QLine([50, 250, 900, 250], { - stroke: 'black', - strokeWidth: 5, - fontSize: fontSize, - selectable: true, - }) - - const line2 = new QLine([450, 450, 821, 78], { - stroke: 'black', - strokeWidth: 5, - fontSize: fontSize, - selectable: true, - }) - - canvas?.add(line) - canvas?.add(line2) - - const interSectionPoint = calculateIntersection(line, line2) - - if (interSectionPoint) { - const circle = new fabric.Circle({ - radius: 5, - fill: 'red', - left: interSectionPoint.x - 5, - top: interSectionPoint.y - 5, - }) - - canvas?.add(circle) - } - } - } - - const addBackgroundInPolygon = (polygon) => { - fabric.Image.fromURL('assets/img/check2.png', function (img) { - // 패턴 객체를 생성합니다. - const pattern = new fabric.Pattern({ - source: img.getElement(), - repeat: 'repeat', - }) - - polygon.fillBackground(pattern) - }) - } - - function PolygonToLine() { - const polygon = canvas?.getActiveObject() - - if (polygon.type !== 'QPolygon') { - return - } - - const lines = togglePolygonLine(polygon) - } - - /** - * canvas 내용 저장하기 - */ - const handleSaveCanvas = async () => { - // const jsonStr = JSON.stringify(canvas?.toDatalessJSON(['type', 'fontSize'])) - const jsonObj = JSON.stringify(canvas?.toDatalessJSON(['type', 'fontSize', 'lines'])) - console.log(jsonObj) - - const param = { - loginId: 'test', - canvas: jsonObj, - } - console.log(param) - - await insertCanvasState(param) - handleClear() - } - - const drawRoofMaterial = () => { - const { width, height, roofStyle } = roofMaterial - - const wallPolygon = canvas?.getObjects().find((obj) => obj.name === 'wall') - - wallPolygon.set('strokeDashArray', [10, 5, 2, 5]) - wallPolygon.set('stroke', 'blue') - wallPolygon.set('strokeWidth', 1) - - const roofs = canvas?.getObjects().filter((obj) => obj.name === 'roof') - - roofs.forEach((roof) => { - let maxLengthLine = roof.lines.reduce((acc, cur) => { - return acc.length > cur.length ? acc : cur - }) - - const roofRatio = window.devicePixelRatio || 1 - - // 패턴 소스를 위한 임시 캔버스 생성 - const patternSourceCanvas = document.createElement('canvas') - if (roofStyle === 1) { - if (maxLengthLine.direction === 'right' || maxLengthLine.direction === 'left') { - patternSourceCanvas.width = width * roofRatio - patternSourceCanvas.height = height * roofRatio - } else { - patternSourceCanvas.width = height * roofRatio - patternSourceCanvas.height = width * roofRatio - } - } else if (roofStyle === 2) { - if (maxLengthLine.direction === 'right' || maxLengthLine.direction === 'left') { - patternSourceCanvas.width = width * 2 - patternSourceCanvas.height = height * 2 - } else { - patternSourceCanvas.width = height * 2 - patternSourceCanvas.height = width * 2 - } - } - - const ctx = patternSourceCanvas.getContext('2d') - - ctx.scale(roofRatio, roofRatio) - ctx.strokeStyle = 'green' - ctx.lineWidth = 0.4 - // 벽돌 패턴 그리기 - if (roofStyle === 1) { - ctx.strokeRect(0, 0, 50, 30) - } else if (roofStyle === 2) { - // 지그재그 - ctx.strokeRect(0, 0, 200, 100) - ctx.strokeRect(100, 100, 200, 100) - } - - // 패턴 생성 - const pattern = new fabric.Pattern({ - source: patternSourceCanvas, - repeat: 'repeat', - }) - roof.set('fill', null) - - roof.set('fill', pattern) - canvas?.renderAll() - }) - } - - /** - * canvas 내용 불러오기 - */ - const handleLoadCanvas = async () => { - const canvasStates = await getCanvasState() - console.log(JSON.parse(canvasStates.canvas)) - canvas?.loadFromJSON(JSON.parse(canvasStates.canvas)) - } - - /** - * 컨트롤러 보이기/숨기기 - */ - const handleShowController = () => { - setShowControl(!showControl) - } - - const drawRoofPatterns = (roofStyle) => { - makeRoofPatternPolygon(roofStyle) - } - - const deleteCell = () => { - const selectedCells = canvas?.getObjects().filter((obj) => obj.name === 'cell' && obj.selected) - - selectedCells.forEach((cell) => { - canvas?.remove(cell) - }) - } - - const setCompassState = (degree) => { - setCompass(degree) - } - - const changeLength = (e) => { - const polygon = canvas?.getActiveObject() - - if (polygon?.type !== 'QPolygon') { - return - } - setScale(e) - polygon.setScaleX(e) - - canvas?.renderAll() - } - - const moduleConfiguration = () => { - createRoofRack() - } - - const setDirectionStringToArrow = () => { - drawDirectionStringToArrow(canvas, globalCampass) - - /** - * 나중에 유틸로 다시 구현 - */ - // const groupShapes = canvas?.getObjects().filter((obj) => obj.name === 'cellGroup') - - // console.log('groupShapes', groupShapes) - - // groupShapes.forEach((obj) => { - // let originAngle = obj._objects.find((array) => array.originAngle !== undefined).originAngle - - // console.log('originAngle', originAngle) - - // let rotateAngle = globalCampass - - // // let rotateAngle = originAngle + globalCampass - // // if (rotateAngle > 360) { - // // rotateAngle -= 360 - // // } - - // console.log('rotateAngle', rotateAngle) - - // obj.set({ angle: rotateAngle, originX: 'center', originY: 'center' }) - // obj.setCoords() - // }) - canvas?.renderAll() - } - - const setHipRoof = () => { - const polygon = canvas?.getObjects().find((obj) => obj.name === 'roof') - const currentRoof = polygon.lines[2] - currentRoof.attributes.type = LINE_TYPE.WALLLINE.EAVES - currentRoof.attributes.offset = 50 - changeCurrentRoof(currentRoof, canvas) - } - const setGableRoof = () => { - const polygon = canvas?.getObjects().find((obj) => obj.name === 'roof') - const currentRoof = polygon.lines[2] - currentRoof.attributes.type = LINE_TYPE.WALLLINE.GABLE - currentRoof.attributes.offset = 30 - changeCurrentRoof(currentRoof, canvas) - } - const setHipAndGableRoof = () => { - let offset = Number(prompt('팔작지붕 폭', '50')) - if (!isNaN(offset) && offset > 0) { - const polygon = canvas?.getObjects().find((obj) => obj.name === 'roof') - const currentRoof = polygon.lines[2] - currentRoof.attributes.type = LINE_TYPE.WALLLINE.HIPANDGABLE - currentRoof.attributes.width = offset - changeCurrentRoof(currentRoof, canvas) - } else { - alert('폭은 0 보다 커야 함') - } - } - const setJerkInHeadRoof = () => { - let offset = Number(prompt('팔작지붕 폭', '50')) - if (!isNaN(offset) && offset > 0) { - const polygon = canvas?.getObjects().find((obj) => obj.name === 'roof') - const currentRoof = polygon.lines[2] - currentRoof.attributes.type = LINE_TYPE.WALLLINE.JERKINHEAD - currentRoof.attributes.width = offset - changeCurrentRoof(currentRoof, canvas) - } else { - alert('폭은 0 보다 커야 함') - } - } - const setWallRoof = () => { - let offset = Number(prompt('소매 폭', '0')) - const polygon = canvas?.getObjects().find((obj) => obj.name === 'roof') - const currentRoof = polygon.lines[2] - currentRoof.attributes.type = LINE_TYPE.WALLLINE.WALL - currentRoof.attributes.width = offset - changeCurrentRoof(currentRoof, canvas) - } - return ( - <> - {canvas && ( - <> -
- - - - - - - - - - - - - - - - - - - - - - - - - - { - - } - - 현재 줌 : {zoom}% - - - {/*{templateType === 0 && (*/} - {/* <>*/} - - {/* */} - {/*)}*/} - - - - - - - - - {/**/} - {/* - - */} - - {templateType === 1 && ( - <> - - - - - - )} - - - - - - - -
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- - )} - - {/*
-

각도 입력(0~360) 후 방향설정 클릭

- { - const val = e.target.value.replace(/[^-0-9]/g, '') - if (val < 0 || val > 360) { - setGlobalCampass(0) - } else { - setGlobalCampass(Number(val)) - } - }} - /> - -
*/} - {/*
- Compass Circle -
- N, S, E, W Labels -
N
-
S
-
- E -
-
- W -
-
- - Compass Pointer -
- Red Upper Triangle -
-
-
*/} -
- - {!canvas ? null : mode === Mode.DRAW_LINE ? ( - - ) : currentObject?.type === 'QPolygon' ? ( - - ) : currentObject?.type === 'QLine' ? ( - - ) : ( - - )} -
- - ) -} diff --git a/src/components/Settings.jsx b/src/components/Settings.jsx deleted file mode 100644 index 51680711..00000000 --- a/src/components/Settings.jsx +++ /dev/null @@ -1,324 +0,0 @@ -'use client' - -import React, { useEffect, useState } from 'react' -import { Button } from '@nextui-org/react' - -import { useAxios } from '@/hooks/useAxios' - -import { useRecoilState } from 'recoil' -import { customSettingsState } from '@/store/canvasAtom' -import { modalContent, modalState } from '@/store/modalAtom' - -import ColorPicker from './common/color-picker/ColorPicker' - -export default function Settings() { - const [objectNo, setObjectNo] = useState('test123240829010') - const [error, setError] = useState(null) - const [customSettings, setCustomSettings] = useRecoilState(customSettingsState) - - const [color, setColor] = useState('#ff0000') - - const [open, setOpen] = useRecoilState(modalState) - const [contents, setContent] = useRecoilState(modalContent) - - const { get, post } = useAxios() - - const handleSavePopup = () => { - console.log('color ', color) - } - - const handleClosePopup = () => { - setContent('') - setOpen(false) - console.log('colorSetting ', color) - } - - const colorSetting = ( - <> -
-

React ColorPicker

- -
{color}
-
-

- -

- - ) - - const customStyles = { - overlay: { - backgroundColor: 'rgba(0,0,0,0.5)', - }, - content: { - width: '300px', - height: '400px', - margin: 'auto', - borderRadius: '4px', - boxShadow: '0 2px 4px rgba(0,0,0,0.2)', - padding: '20px', - }, - } - - // 상태를 하나의 객체로 관리 - const [settings, setSettings] = useState({ - display1: Array(11).fill(false), // 화면 표시1 - display2: Array(3).fill(false), // 화면 표시2 - rangeSetting: 0, // 흡착 범위 설정 - gridSettings: Array(5).fill(false), // 그리드 설정 - }) - - const gridItems = { - display1: [ - '할당 표시', - '도면 표시', - '그리드 표시', - '문자 표시', - '흐름방향 표시', - '복도치수 표시', - '실제치수 표시', - '치수 표시 없음', - '가대 표시', - '좌표 표시', - '도면전환 표시', - ], - display2: ['테두리만', '라인해치', 'All Painted'], - rangeSetting: ['극소', '소', '중', '대'], - gridSettings: ['임의 그리드', '실선 그리드', '점 그리드', '그리드 색 설정', '흡착점 추가'], - } - - // 초기 조회 - useEffect(() => { - if (!objectNo) { - alert('object_no를 입력하세요.') - } - }, []) - - // 클릭 시 상태 변경 함수 - const handleToggle = (type, index) => { - // '실선 그리드' 클릭 시 팝업 열기 - if (type === 'gridSettings' && gridItems.gridSettings[index] === '실선 그리드') { - //openGridPopup() - } - - // '그리드 색 설정' 클릭 시 팝업 열기 - if (type === 'gridSettings' && gridItems.gridSettings[index] === '그리드 색 설정') { - //setSelectedGridSetting(gridItems.gridSettings[index]) - //setIsPopupOpen(true) - //return prevSettings // 설정은 변경하지 않음 - - setOpen(true) - setContent({ ...colorSetting }) - } - - setSettings((prevSettings) => { - // prevSettings[type]이 배열인지 확인하고, 그렇지 않은 경우 빈 배열로 초기화 - let updated = Array.isArray(prevSettings[type]) ? [...prevSettings[type]] : [] - - if (type === 'rangeSetting') { - return { ...prevSettings, [type]: index } - } - - updated[index] = updated[index] === false ? true : false - return { ...prevSettings, [type]: updated } - }) - } - - // '실선 그리드' 클릭 시 팝업을 열기 위한 함수 - const openGridPopup = () => { - const popupWidth = 500 - const popupHeight = 300 - - // 팝업 창 위치를 화면 중앙으로 조정하기 위해 계산 - const left = window.innerWidth / 2 - popupWidth / 2 - const top = window.innerHeight / 2 - popupHeight / 2 - - // 새 창 열기 - window - .open - //'./components/intro', // 팝업으로 띄울 페이지의 URL - //'_blank', // 새 창으로 열기 - //`width=${popupWidth},height=${popupHeight},top=${top},left=${left}`, // 크기와 위치 지정 - () - } - - // Canvas Setting 조회 및 초기화 - const handleSelect = async () => { - try { - if (!objectNo) { - alert('object_no를 입력하세요.') - return - } - - const res = await get({ url: `/api/canvas-management/canvas-settings/by-object/${objectNo}` }) - - // 데이터가 없는 경우 - if (!res) { - console.warn('조회 결과가 없습니다.') - // 기본값을 설정하거나 사용자에게 알림 표시 - setSettings({ - display1: Array(11).fill(false), // 화면 표시1 기본값 - display2: Array(3).fill(false), // 화면 표시2 기본값 - rangeSetting: 0, // 흡착 범위 설정 기본값 - gridSettings: Array(5).fill(false), // 그리드 설정 기본값 - }) - - alert('조회된 데이터가 없습니다. 기본 설정이 적용됩니다.') - return // 이후 코드 실행을 중단 - } - - const data = { - display1: [ - res.assignDisplay, - res.drawDisplay, - res.gridDisplay, - res.charDisplay, - res.flowDisplay, - res.hallwayDimenDisplay, - res.actualDimenDisplay, - res.noDimenDisplay, - res.trestleDisplay, - res.coordiDisplay, - res.drawConverDisplay, - ], - display2: [res.onlyBorder, res.lineHatch, res.allPainted], - rangeSetting: res.adsorpRangeSetting, - gridSettings: [res.randomGrid, res.solidGrid, res.dotGrid, res.gridColorSet, res.adsorpPointAdd], - } - - // 데이터 설정 - setSettings({ - display1: data.display1, - display2: data.display2, - rangeSetting: data.rangeSetting, - gridSettings: data.gridSettings, - }) - } catch (error) { - console.error('Data fetching error:', error) - } - } - - // Canvas Setting 저장 - const handleSubmit = async () => { - if (!objectNo) { - alert('object_no를 입력하세요.') - return - } - - const patternData = { - objectNo, - assignDisplay: settings.display1[0], - drawDisplay: settings.display1[1], - gridDisplay: settings.display1[2], - charDisplay: settings.display1[3], - flowDisplay: settings.display1[4], - hallwayDimenDisplay: settings.display1[5], - actualDimenDisplay: settings.display1[6], - noDimenDisplay: settings.display1[7], - trestleDisplay: settings.display1[8], - coordiDisplay: settings.display1[9], - drawConverDisplay: settings.display1[10], - onlyBorder: settings.display2[0], - lineHatch: settings.display2[1], - allPainted: settings.display2[2], - adsorpRangeSetting: settings.rangeSetting, - randomGrid: settings.gridSettings[0], - solidGrid: settings.gridSettings[1], - dotGrid: settings.gridSettings[2], - gridColorSet: settings.gridSettings[3], - adsorpPointAdd: settings.gridSettings[4], - } - - console.log('patternData', patternData) - - await post({ url: `/api/canvas-management/canvas-settings`, data: patternData }) - - //Recoil 설정 - setCustomSettings({ ...patternData }) - - // 저장 후 재조회 - await handleSelect() - } - - return ( - <> -
-
- setObjectNo(e.target.value)} /> - - -
-
-

[디스플레이 설정]

-

* 도면에 표시할 항목을 클릭하면 적용 됩니다.

-
- {gridItems.display1.map((item, index) => ( -
handleToggle('display1', index)} - > - {settings.display1[index]} {item} -
- ))} -
-
-

* 화면 표시

-
- {gridItems.display2.map((item, index) => ( -
handleToggle('display2', index)} - > - {settings.display2[index]} {item} -
- ))} -
-

[글꼴/도면크기 설정]

-

* 글꼴 및 크기 변경

-
-
문자 글꼴 변경
-
흐름방향 글꼴 변경
-
치수 글꼴 변경
-
회로번호 글꼴 변경
-
- `` -

* 흡착 범위 설정

-
- {gridItems.rangeSetting.map((item, index) => ( -
handleToggle('rangeSetting', index)} - > - {item} -
- ))} -
-
-
치수선 설정
-
도면 크기 설정
-
흡착점 ON
-
-

[그리드 설정]

-
- -
{color}
-
-
- {gridItems.gridSettings.map((item, index) => ( -
handleToggle('gridSettings', index)} - > - {settings.gridSettings[index]} {item} -
- ))} -
-
-
- - ) -} diff --git a/src/components/playground.module.css b/src/components/playground.module.css deleted file mode 100644 index 273a4a34..00000000 --- a/src/components/playground.module.css +++ /dev/null @@ -1,4 +0,0 @@ -.test { - @apply bg-red-500; - @apply text-2xl; -} diff --git a/src/hooks/common/useMasterController.js b/src/hooks/common/useMasterController.js index e1c37915..60aab800 100644 --- a/src/hooks/common/useMasterController.js +++ b/src/hooks/common/useMasterController.js @@ -2,10 +2,6 @@ import { useAxios } from '@/hooks/useAxios' import { useMessage } from '@/hooks/useMessage' import { useSwal } from '@/hooks/useSwal' import { getQueryString } from '@/util/common-utils' -import { trestleRequest, constructionRequest, trestleDetailRequest } from '@/models/apiModels' -import { POST } from '@/app/api/image-upload/route' -import { canvasState } from '@/store/canvasAtom' -import { useRecoilValue } from 'recoil' /** * 마스터 컨트롤러 훅 From 4b469c4b1cb36dedeb2bb77520291562f285d64d Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Mon, 24 Feb 2025 18:09:27 +0900 Subject: [PATCH 121/352] =?UTF-8?q?-=20=EB=B0=B0=EC=B9=98=EB=A9=B4=20?= =?UTF-8?q?=EA=B7=B8=EB=A6=AC=EA=B8=B0=20=ED=8C=9D=EC=97=85=20close=20-=20?= =?UTF-8?q?point=20=EC=A0=9C=EA=B1=B0=20-=20=EB=B0=B0=EC=B9=98=EB=A9=B4=20?= =?UTF-8?q?=EA=B7=B8=EB=A6=AC=EA=B8=B0=20hook=20=EC=A3=BC=EC=84=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useTrestle.js | 2 +- src/hooks/surface/usePlacementShapeDrawing.js | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index 14bf6447..2e40dab5 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -49,7 +49,7 @@ export const useTrestle = () => { const parent = canvas.getObjects().find((obj) => obj.id === surface.parentId) const roofMaterialIndex = parent.roofMaterial.index if (+roofSizeSet === 3) { - return true + return } const construction = moduleSelectionData?.roofConstructions?.find((construction) => construction.roofIndex === roofMaterialIndex).construction if (!construction) { diff --git a/src/hooks/surface/usePlacementShapeDrawing.js b/src/hooks/surface/usePlacementShapeDrawing.js index 6ebd1414..50f61172 100644 --- a/src/hooks/surface/usePlacementShapeDrawing.js +++ b/src/hooks/surface/usePlacementShapeDrawing.js @@ -37,7 +37,7 @@ import { roofDisplaySelector } from '@/store/settingAtom' import { useRoofFn } from '@/hooks/common/useRoofFn' import PlacementSurfaceLineProperty from '@/components/floor-plan/modal/placementShape/PlacementSurfaceLineProperty' -// 면형상 배치 +// 배치면 그리기 export function usePlacementShapeDrawing(id) { const canvas = useRecoilValue(canvasState) const roofDisplay = useRecoilValue(roofDisplaySelector) @@ -93,6 +93,12 @@ export function usePlacementShapeDrawing(id) { useEffect(() => { setPoints([]) + + return () => { + const placementShapeDrawingStartPoint = canvas.getObjects().find((obj) => obj.name === 'placementShapeDrawingStartPoint') + + canvas.remove(placementShapeDrawingStartPoint) + } }, []) useEffect(() => { From dfc412140bfa150433896f65ae254be6c321419b Mon Sep 17 00:00:00 2001 From: basssy Date: Mon, 24 Feb 2025 18:13:41 +0900 Subject: [PATCH 122/352] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=B2=A8?= =?UTF-8?q?=EB=B6=80=ED=8C=8C=EC=9D=BC=20=EC=9D=B4=EB=AF=B8=EC=A7=80,pdf,?= =?UTF-8?q?=EC=97=91=EC=85=80=ED=8C=8C=EC=9D=BC=20=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../estimate/EstimateFileUploader.jsx | 31 +++++-------------- src/locales/ja.json | 2 +- src/locales/ko.json | 2 +- 3 files changed, 10 insertions(+), 25 deletions(-) diff --git a/src/components/estimate/EstimateFileUploader.jsx b/src/components/estimate/EstimateFileUploader.jsx index 950ed6af..26f28405 100644 --- a/src/components/estimate/EstimateFileUploader.jsx +++ b/src/components/estimate/EstimateFileUploader.jsx @@ -3,11 +3,14 @@ import { useRef } from 'react' import { v4 as uuidv4 } from 'uuid' import { useMessage } from '@/hooks/useMessage' +import { useSwal } from '@/hooks/useSwal' export default function EstimateFileUploader({ uploadFiles, setUploadFiles }) { const fileInputRef = useRef(null) const { getMessage } = useMessage() + const { swalFire } = useSwal() + const handleButtonClick = (e) => { e.preventDefault() fileInputRef.current.click() @@ -22,7 +25,8 @@ export default function EstimateFileUploader({ uploadFiles, setUploadFiles }) { let passFlag = true Array.from(e.target.files).forEach((file) => { let fileType = file.type - if (!fileType.includes('image')) { + //엑셀, pdf, 이미지 + if (!fileType.includes('image') && !fileType.includes('pdf') && !fileType.includes('spreadsheet')) { passFlag = false } else { fileList.push({ data: file, id: uuidv4() }) @@ -30,30 +34,11 @@ export default function EstimateFileUploader({ uploadFiles, setUploadFiles }) { }) if (!passFlag) { - alert(getMessage('estimate.detail.fileList.extCheck')) + swalFire({ text: getMessage('estimate.detail.fileList.extCheck'), type: 'alert' }) } - // const { files } = e.target - // const file = files[0] - // const fileType = file.type - // if (!fileType.includes('image')) { - // return alert(getMessage('estimate.detail.fileList.extCheck')) - // } - - // setUploadFiles([...uploadFiles, { data: e.target.files[0], id: uuidv4() }]) - //다중으로 변경 setUploadFiles([...uploadFiles, ...fileList]) e.target.value = '' - // const formData = new FormData() - // formData.append('file', e.target.files[0]) - // formData.append('objectNo', objectNo) // 받아와야 하는 값 - // formData.append('planNo', planNo) // 받아와야 하는 값 - // formData.append('category', category) // 받아와야 하는 값 - // formData.append('userId', session.userId) - - // await promisePost({ url: '/api/file/fileUpload', data: formData }).then((res) => { - // if (res.data > 0) setUploadFiles([...files, { name: e.target.files[0].name, id: uuidv4() }]) - // }) } const deleteFile = (id) => { @@ -76,7 +61,7 @@ export default function EstimateFileUploader({ uploadFiles, setUploadFiles }) { }) if (!passFlag) { - alert(getMessage('estimate.detail.fileList.extCheck')) + swalFire({ text: getMessage('estimate.detail.fileList.extCheck'), type: 'alert' }) } setUploadFiles([...uploadFiles, ...fileList]) @@ -108,7 +93,7 @@ export default function EstimateFileUploader({ uploadFiles, setUploadFiles }) { multiple name="file" id="img" - accept="image/*" + // accept="image/*" ref={fileInputRef} style={{ display: 'none' }} onChange={(e) => onChangeFiles(e)} diff --git a/src/locales/ja.json b/src/locales/ja.json index 677f9cab..ef70bb9b 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -896,7 +896,7 @@ "estimate.detail.dragFileGuide": "(※北面設置の場合、ファイル添付が必須です.)", "estimate.detail.header.fileList1": "ファイル添付", "estimate.detail.fileList.btn": "ファイル選択", - "estimate.detail.fileList.extCheck": "画像ファイルのみ添付可能です。", + "estimate.detail.fileList.extCheck": "画像、PDF、Excelファイルのみ添付可能.", "estimate.detail.header.fileList2": "添付ファイル一覧", "estimate.detail.fileList2.btn.return": "復元", "estimate.detail.header.specialEstimate": "見積もりの特定", diff --git a/src/locales/ko.json b/src/locales/ko.json index 67b4b301..d60e226d 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -897,7 +897,7 @@ "estimate.detail.dragFileGuide": "(※ 북면설치인 경우, 파일 첨부가 필수입니다.)", "estimate.detail.header.fileList1": "파일첨부", "estimate.detail.fileList.btn": "파일선택", - "estimate.detail.fileList.extCheck": "이미지 파일만 첨부 가능합니다.", + "estimate.detail.fileList.extCheck": "이미지, PDF, 엑셀 파일만 첨부 가능합니다.", "estimate.detail.header.fileList2": "첨부파일 목록", "estimate.detail.fileList2.btn.return": "복원", "estimate.detail.header.specialEstimate": "견적특이사항", From c07a8fb91c4ed8bd7c34e11a50bfb1df7f60f7d2 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Mon, 24 Feb 2025 18:53:12 +0900 Subject: [PATCH 123/352] =?UTF-8?q?=F0=9F=9A=A6fix:=20=EB=8B=A4=EC=9D=B4?= =?UTF-8?q?=EC=96=B4=EA=B7=B8=EB=9E=A8=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../diagrams/MainLayout.codediagram | 0 docs/diagrams/canvas-setting.codediagram | 1 + docs/diagrams/배치면초기설정.codediagram | 1 + src/lib/authActions.js | 29 ------------------- 4 files changed, 2 insertions(+), 29 deletions(-) rename MainLayout.codediagram => docs/diagrams/MainLayout.codediagram (100%) create mode 100644 docs/diagrams/canvas-setting.codediagram create mode 100644 docs/diagrams/배치면초기설정.codediagram diff --git a/MainLayout.codediagram b/docs/diagrams/MainLayout.codediagram similarity index 100% rename from MainLayout.codediagram rename to docs/diagrams/MainLayout.codediagram diff --git a/docs/diagrams/canvas-setting.codediagram b/docs/diagrams/canvas-setting.codediagram new file mode 100644 index 00000000..bd87ebb4 --- /dev/null +++ b/docs/diagrams/canvas-setting.codediagram @@ -0,0 +1 @@ +{"id":-1,"name":"Onboarding diagram","userId":-1,"createdAt":"","updatedAt":"","content":{"items":[{"uid":"HduNR37Az-","position":{"x":800,"y":-590},"sizes":{"width":400,"height":146},"autoheight":true,"blockContent":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"type":"text","text":"\bCanvas Setting "},{"type":"text","marks":[{"type":"bold"}],"text":"☀️"}]},{"type":"bulletList","content":[{"type":"listItem","content":[{"type":"paragraph","content":[{"type":"text","text":"canvas 전체 내용을 설정한다."}]}]},{"type":"listItem","content":[{"type":"paragraph","content":[{"type":"text","text":"저장 버튼 없이 UI를 변경하면 Update가 일어난다."}]}]}]}]},"color":{"bgColor":"hsla(211, 33%, 22%, 1)","bgName":"blue"},"nodeType":"block"},{"uid":"DiKZ2umB3G","position":{"x":450,"y":-250},"sizes":{"width":549.78125,"height":189.5},"autoheight":true,"blockContent":{"content":[{"type":"filePathNode","attrs":{"pathToFile":"src/components/floor-plan/modal/setting01/","version":1},"content":[{"type":"text","marks":[{"type":"bold"}],"text":"SettingModal01.jsx"}]},{"type":"codeBlock","attrs":{"language":"javascript","wrapCode":true},"content":[{"type":"text","text":"{buttonAct === 1 && }\n{buttonAct === 2 && }\n{buttonAct === 3 && }"}]}]},"nodeType":"block"},{"uid":"EAKK_XFrUP","position":{"x":70,"y":90},"sizes":{"width":400,"height":210},"autoheight":false,"blockContent":{"type":"doc","content":[{"type":"filePathNode","attrs":{"pathToFile":"src/components/floor-plan/modal/setting01/","version":1},"content":[{"type":"text","marks":[{"type":"bold"}],"text":"FirstOption.jsx"}]},{"type":"paragraph","content":[{"type":"text","marks":[{"type":"bold"}],"text":"디스플레이 설정"}]},{"type":"codeBlock","attrs":{"language":"javascript","wrapCode":true},"content":[{"type":"text","text":"export default function FirstOption(props) {"}]}]},"nodeType":"block"},{"uid":"-QZuVi6n7M","position":{"x":540,"y":90},"sizes":{"width":400,"height":182.5},"autoheight":true,"blockContent":{"type":"doc","content":[{"type":"filePathNode","attrs":{"pathToFile":"src/components/floor-plan/modal/setting01/","version":1},"content":[{"type":"text","marks":[{"type":"bold"}],"text":"SecondOption.jsx"}]},{"type":"paragraph","content":[{"type":"text","marks":[{"type":"bold"}],"text":"글꼴 및 도면 크기 설정"}]},{"type":"codeBlock","attrs":{"language":"javascript","wrapCode":true},"content":[{"type":"text","text":"export default function SecondOption(props) {"}]}]},"nodeType":"block"},{"uid":"OIDIoPPwFU","position":{"x":1220,"y":90},"sizes":{"width":400,"height":182.5},"autoheight":true,"blockContent":{"type":"doc","content":[{"type":"filePathNode","attrs":{"pathToFile":"src/components/floor-plan/modal/setting01/","version":1},"content":[{"type":"text","marks":[{"type":"bold"}],"text":"GridOption.jsx"}]},{"type":"paragraph","content":[{"type":"text","marks":[{"type":"bold"}],"text":"그리드 설정"}]},{"type":"codeBlock","attrs":{"language":"javascript","wrapCode":true},"content":[{"type":"text","text":"export default function GridOption(props) {"}]}]},"nodeType":"block"},{"uid":"iEbZe6FrdP","position":{"x":550,"y":380},"sizes":{"width":400,"height":200},"autoheight":true,"blockContent":{"type":"doc","content":[{"type":"filePathNode","attrs":{"pathToFile":"src/components/floor-plan/modal/dimensionLine/","version":1},"content":[{"type":"text","marks":[{"type":"bold"}],"text":"DimensionLineSetting.jsx"}]},{"type":"paragraph","content":[{"type":"text","marks":[{"type":"bold"}],"text":"글꼴 및 크기 변경"}]},{"type":"codeBlock","attrs":{"language":"javascript","wrapCode":true},"content":[{"type":"text","text":"export default function DimensionLineSetting(props) {"}]}]},"nodeType":"block"},{"uid":"5ovY6Y7atI","position":{"x":1010,"y":380},"sizes":{"width":400,"height":182.5},"autoheight":true,"blockContent":{"type":"doc","content":[{"type":"filePathNode","attrs":{"pathToFile":"src/components/floor-plan/modal/grid/","version":1},"content":[{"type":"text","marks":[{"type":"bold"}],"text":"DotLineGrid.jsx"}]},{"type":"paragraph","content":[{"type":"text","marks":[{"type":"bold"}],"text":"점, 선, 그리드 설정"}]},{"type":"codeBlock","attrs":{"language":"javascript","wrapCode":true},"content":[{"type":"text","text":"export default function DotLineGrid(props) {"}]}]},"nodeType":"block"},{"uid":"yVBft0fd68","position":{"x":1470,"y":380},"sizes":{"width":400,"height":200},"autoheight":true,"blockContent":{"type":"doc","content":[{"type":"filePathNode","attrs":{"pathToFile":"src/components/common/color-picker/","version":1},"content":[{"type":"text","marks":[{"type":"bold"}],"text":"ColorPickerModal.jsx"}]},{"type":"paragraph","content":[{"type":"text","marks":[{"type":"bold"}],"text":"색 설정"}]},{"type":"codeBlock","attrs":{"language":"javascript","wrapCode":true},"content":[{"type":"text","text":"export default function ColorPickerModal(props) {"}]}]},"nodeType":"block"},{"uid":"KcDc1JqWZL","position":{"x":270,"y":-700},"sizes":{"width":470,"height":336.5},"autoheight":true,"blockContent":{"type":"doc","content":[{"type":"filePathNode","attrs":{"pathToFile":"src/components/floor-plan/","version":1},"content":[{"type":"text","marks":[{"type":"bold"}],"text":"CanvasMenu.jsx"}]},{"type":"paragraph","content":[{"type":"text","marks":[{"type":"bold"}],"text":"modal 창 ON"}]},{"type":"codeBlock","attrs":{"language":"javascript","wrapCode":true},"content":[{"type":"text","text":"const handlePopup = () => {\n const id = uuidv4()\n addPopup(id, 1, , true)\n}"}]},{"type":"paragraph","content":[{"type":"text","text":"canvas 설정 조회"}]},{"type":"codeBlock","attrs":{"language":"javascriptreact","wrapCode":false},"content":[{"type":"text","text":"const { fetchSettings } = useCanvasSetting()"}]}]},"nodeType":"block"},{"uid":"y2Vg-dWtlJ","position":{"x":-390,"y":-620},"sizes":{"width":520,"height":385.5},"autoheight":true,"blockContent":{"type":"doc","content":[{"type":"filePathNode","attrs":{"pathToFile":"src/hooks/option/","version":1},"content":[{"type":"text","marks":[{"type":"bold"}],"text":"useCanvasSetting.js"}]},{"type":"paragraph","content":[{"type":"text","marks":[{"type":"bold"}],"text":"canvas 설정 관리 hook"}]},{"type":"codeBlock","attrs":{"language":"javascript","wrapCode":true},"content":[{"type":"text","text":"const fetchSettings = async () => {"}]},{"type":"codeBlock","attrs":{"language":"javascript","wrapCode":false},"content":[{"type":"text","text":"const [settingsData, setSettingsData] = useState({\n ...settingModalFirstOptions,\n ...settingModalSecondOptions,\n ...globalFont,\n ...dotLineGridSetting,\n ...planSizeSettingMode,\n ...dimensionLineSettings,\n ...color,\n })"}]}]},"nodeType":"block"}],"configs":{"centerX":373.0590486994188,"centerY":572.9825354968084,"zoomLevel":1.017264811197917},"arrowData":{"arrowsMap":{"arrow-point-bI0wBh3Ufk-bottom-point-PSPLIYKa9J-top":{"to":"point-PSPLIYKa9J-top","from":"point-bI0wBh3Ufk-bottom","label":"Normal Box","direction":"ft","selectable":true},"arrow-point-bI0wBh3Ufk-bottom-point-ytXK_ayIc1-top":{"to":"point-ytXK_ayIc1-top","from":"point-bI0wBh3Ufk-bottom","label":"Code Box","direction":"ft","selectable":true},"arrow-point-hyyRZE3E8u-right-point-6ZopTaEaDZ-left":{"to":"point-6ZopTaEaDZ-left","from":"point-hyyRZE3E8u-right","label":"call","direction":"ft","selectable":true}},"pointsMap":{"point-PSPLIYKa9J-top":{"x":805.9999797489683,"y":60,"id":"point-PSPLIYKa9J-top","direction":"top"},"point-ytXK_ayIc1-top":{"x":205.99999493724206,"y":60,"id":"point-ytXK_ayIc1-top","direction":"top"},"point-6ZopTaEaDZ-left":{"x":220,"y":605.9999898744841,"id":"point-6ZopTaEaDZ-left","direction":"left"},"point-hyyRZE3E8u-right":{"x":100,"y":606,"id":"point-hyyRZE3E8u-right","direction":"right"},"point-bI0wBh3Ufk-bottom":{"x":515.9999797489683,"y":-40,"id":"point-bI0wBh3Ufk-bottom","direction":"bottom"}},"edgesMap":{"edge-DiKZ2umB3G-DiKZ2umB3G-bottom-EAKK_XFrUP-EAKK_XFrUP-top":{"uid":"edge-DiKZ2umB3G-DiKZ2umB3G-bottom-EAKK_XFrUP-EAKK_XFrUP-top","fromNodeId":"DiKZ2umB3G","fromHandleId":"DiKZ2umB3G-bottom","toNodeId":"EAKK_XFrUP","toHandleId":"EAKK_XFrUP-top","direction":"ft","selectable":true,"type":"solid","content":{"label":""}},"edge-DiKZ2umB3G-DiKZ2umB3G-bottom--QZuVi6n7M--QZuVi6n7M-top":{"uid":"edge-DiKZ2umB3G-DiKZ2umB3G-bottom--QZuVi6n7M--QZuVi6n7M-top","fromNodeId":"DiKZ2umB3G","fromHandleId":"DiKZ2umB3G-bottom","toNodeId":"-QZuVi6n7M","toHandleId":"-QZuVi6n7M-top","direction":"ft","selectable":true,"type":"solid","content":{"label":""}},"edge-DiKZ2umB3G-DiKZ2umB3G-bottom-OIDIoPPwFU-OIDIoPPwFU-top":{"uid":"edge-DiKZ2umB3G-DiKZ2umB3G-bottom-OIDIoPPwFU-OIDIoPPwFU-top","fromNodeId":"DiKZ2umB3G","fromHandleId":"DiKZ2umB3G-bottom","toNodeId":"OIDIoPPwFU","toHandleId":"OIDIoPPwFU-top","direction":"ft","selectable":true,"type":"solid","content":{"label":""}},"edge--QZuVi6n7M--QZuVi6n7M-bottom-iEbZe6FrdP-iEbZe6FrdP-top":{"uid":"edge--QZuVi6n7M--QZuVi6n7M-bottom-iEbZe6FrdP-iEbZe6FrdP-top","fromNodeId":"-QZuVi6n7M","fromHandleId":"-QZuVi6n7M-bottom","toNodeId":"iEbZe6FrdP","toHandleId":"iEbZe6FrdP-top","direction":"ft","selectable":true,"type":"solid","content":{"label":""}},"edge-OIDIoPPwFU-OIDIoPPwFU-bottom-5ovY6Y7atI-5ovY6Y7atI-top":{"uid":"edge-OIDIoPPwFU-OIDIoPPwFU-bottom-5ovY6Y7atI-5ovY6Y7atI-top","fromNodeId":"OIDIoPPwFU","fromHandleId":"OIDIoPPwFU-bottom","toNodeId":"5ovY6Y7atI","toHandleId":"5ovY6Y7atI-top","direction":"ft","selectable":true,"type":"solid","content":{"label":""}},"edge-OIDIoPPwFU-OIDIoPPwFU-bottom-yVBft0fd68-yVBft0fd68-top":{"uid":"edge-OIDIoPPwFU-OIDIoPPwFU-bottom-yVBft0fd68-yVBft0fd68-top","fromNodeId":"OIDIoPPwFU","fromHandleId":"OIDIoPPwFU-bottom","toNodeId":"yVBft0fd68","toHandleId":"yVBft0fd68-top","direction":"ft","selectable":true,"type":"solid","content":{"label":""}},"edge-KcDc1JqWZL-KcDc1JqWZL-bottom-DiKZ2umB3G-DiKZ2umB3G-top":{"uid":"edge-KcDc1JqWZL-KcDc1JqWZL-bottom-DiKZ2umB3G-DiKZ2umB3G-top","fromNodeId":"KcDc1JqWZL","fromHandleId":"KcDc1JqWZL-bottom","toNodeId":"DiKZ2umB3G","toHandleId":"DiKZ2umB3G-top","direction":"ft","selectable":true,"type":"solid","content":{"label":""}},"edge-KcDc1JqWZL-KcDc1JqWZL-left-y2Vg-dWtlJ-y2Vg-dWtlJ-right":{"uid":"edge-KcDc1JqWZL-KcDc1JqWZL-left-y2Vg-dWtlJ-y2Vg-dWtlJ-right","fromNodeId":"KcDc1JqWZL","fromHandleId":"KcDc1JqWZL-left","toNodeId":"y2Vg-dWtlJ","toHandleId":"y2Vg-dWtlJ-right","direction":"ft","selectable":true,"type":"solid","content":{"label":""}}}}}} \ No newline at end of file diff --git a/docs/diagrams/배치면초기설정.codediagram b/docs/diagrams/배치면초기설정.codediagram new file mode 100644 index 00000000..814a256d --- /dev/null +++ b/docs/diagrams/배치면초기설정.codediagram @@ -0,0 +1 @@ +{"id":-1,"name":"Onboarding diagram","userId":-1,"createdAt":"","updatedAt":"","content":{"items":[{"uid":"HduNR37Az-","position":{"x":690,"y":-270},"sizes":{"width":400,"height":168},"autoheight":true,"blockContent":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"type":"text","text":"배치면 초기설정 "},{"type":"text","marks":[{"type":"bold"}],"text":"☀️"}]},{"type":"bulletList","content":[{"type":"listItem","content":[{"type":"paragraph","content":[{"type":"text","text":"플랜당 필수 설정"}]}]},{"type":"listItem","content":[{"type":"paragraph","content":[{"type":"text","text":"필수로 설정이 저장되어야 하기 때문에 닫기 버튼 없음"}]}]},{"type":"listItem","content":[{"type":"paragraph","content":[{"type":"text","text":"저장 버튼으로 update 처리"}]}]}]}]},"color":{"bgColor":"hsla(211, 33%, 22%, 1)","bgName":"blue"},"nodeType":"block"},{"uid":"eB4rr9xOVw","position":{"x":500,"y":-40},"sizes":{"width":810,"height":182.5},"autoheight":true,"blockContent":{"type":"doc","content":[{"type":"filePathNode","attrs":{"pathToFile":"src/components/floor-plan/modal/placementShape/","version":1},"content":[{"type":"text","marks":[{"type":"bold"}],"text":"PlacementShapeSetting.jsx"}]},{"type":"paragraph","content":[{"type":"text","marks":[{"type":"bold"}],"text":"배치면 초기 설정 팝업"}]},{"type":"codeBlock","attrs":{"language":"javascript","wrapCode":true},"content":[{"type":"text","text":"export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, planNo, openPoint }) {"}]}]},"nodeType":"block"},{"uid":"dzN8hw1chO","position":{"x":990,"y":310},"sizes":{"width":550,"height":361},"autoheight":true,"blockContent":{"type":"doc","content":[{"type":"filePathNode","attrs":{"pathToFile":"src/hooks/option/","version":1},"content":[{"type":"text","marks":[{"type":"bold"}],"text":"useCanvasSetting.js"}]},{"type":"codeBlock","attrs":{"language":"javascript","wrapCode":true},"content":[{"type":"text","text":"/**\n * 기본설정(PlacementShapeSetting) 조회 및 초기화\n */\nconst fetchBasicSettings = async (planNo, openPoint) => {"}]},{"type":"paragraph"},{"type":"codeBlock","attrs":{"language":"javascript","wrapCode":false},"content":[{"type":"text","text":"/**\n * 기본설정(PlacementShapeSetting) 저장\n */\nconst basicSettingSave = async (params) => {"}]}]},"nodeType":"block"},{"uid":"YX7IHZIiqg","position":{"x":330,"y":310},"sizes":{"width":590,"height":259.5},"autoheight":true,"blockContent":{"content":[{"type":"filePathNode","attrs":{"pathToFile":"src/hooks/","version":1},"content":[{"type":"text","marks":[{"type":"bold"}],"text":"usePlan.js"}]},{"type":"codeBlock","attrs":{"language":"javascript","wrapCode":true},"content":[{"type":"text","text":"/**\n * 플랜 삭제 시 배치면 초기설정 데이터 삭제\n *\n * @param {string} objectNo - 물건번호\n * @param {string} planNo - 플랜번호\n */\nconst deleteBasicSettings = async (objectNo, planNo) => {"}]}]},"nodeType":"block"}],"configs":{"centerX":47.05904869941878,"centerY":349.9825354968084,"zoomLevel":1.017264811197917},"arrowData":{"arrowsMap":{"arrow-point-bI0wBh3Ufk-bottom-point-PSPLIYKa9J-top":{"to":"point-PSPLIYKa9J-top","from":"point-bI0wBh3Ufk-bottom","label":"Normal Box","direction":"ft","selectable":true},"arrow-point-bI0wBh3Ufk-bottom-point-ytXK_ayIc1-top":{"to":"point-ytXK_ayIc1-top","from":"point-bI0wBh3Ufk-bottom","label":"Code Box","direction":"ft","selectable":true},"arrow-point-hyyRZE3E8u-right-point-6ZopTaEaDZ-left":{"to":"point-6ZopTaEaDZ-left","from":"point-hyyRZE3E8u-right","label":"call","direction":"ft","selectable":true}},"pointsMap":{"point-PSPLIYKa9J-top":{"x":805.9999797489683,"y":60,"id":"point-PSPLIYKa9J-top","direction":"top"},"point-ytXK_ayIc1-top":{"x":205.99999493724206,"y":60,"id":"point-ytXK_ayIc1-top","direction":"top"},"point-6ZopTaEaDZ-left":{"x":220,"y":605.9999898744841,"id":"point-6ZopTaEaDZ-left","direction":"left"},"point-hyyRZE3E8u-right":{"x":100,"y":606,"id":"point-hyyRZE3E8u-right","direction":"right"},"point-bI0wBh3Ufk-bottom":{"x":515.9999797489683,"y":-40,"id":"point-bI0wBh3Ufk-bottom","direction":"bottom"}},"edgesMap":{"edge-eB4rr9xOVw-eB4rr9xOVw-bottom-YX7IHZIiqg-YX7IHZIiqg-top":{"uid":"edge-eB4rr9xOVw-eB4rr9xOVw-bottom-YX7IHZIiqg-YX7IHZIiqg-top","fromNodeId":"eB4rr9xOVw","fromHandleId":"eB4rr9xOVw-bottom","toNodeId":"YX7IHZIiqg","toHandleId":"YX7IHZIiqg-top","direction":"ft","selectable":true,"type":"solid","content":{"label":""}},"edge-eB4rr9xOVw-eB4rr9xOVw-bottom-dzN8hw1chO-dzN8hw1chO-top":{"uid":"edge-eB4rr9xOVw-eB4rr9xOVw-bottom-dzN8hw1chO-dzN8hw1chO-top","fromNodeId":"eB4rr9xOVw","fromHandleId":"eB4rr9xOVw-bottom","toNodeId":"dzN8hw1chO","toHandleId":"dzN8hw1chO-top","direction":"ft","selectable":true,"type":"solid","content":{"label":""}}}}}} \ No newline at end of file diff --git a/src/lib/authActions.js b/src/lib/authActions.js index e1bbd192..68dab9f7 100644 --- a/src/lib/authActions.js +++ b/src/lib/authActions.js @@ -58,32 +58,3 @@ export async function login() { redirect('/') } } - -export const customSetMenuNumber = async ({ objectNo, pid, menuNum, callback = () => {} }) => { - let db = null - - if (!db) { - db = await open({ - filename: 'qcast3.global.sqlite', - driver: sqlite3.Database, - }) - } - - const chkSql = `SELECT menu_num FROM current_menu WHERE object_no = ? AND pid = ?` - const prevMenuNum = await getInstance().get(chkSql, objectNo, pid) - - if (prevMenuNum) { - if (prevMenuNum > menuNum) { - callback() - } else { - const sql = `UPDATE current_menu SET menu_num = ? WHERE object_no = ? AND pid = ?` - await getInstance().run(sql, menuNum, objectNo, pid) - - setMenuNumber(menuNum) - } - } else { - const sql = `INSERT INTO current_menu (object_no, pid, menu_num) VALUES (?, ?, ?)` - await getInstance().run(sql, objectNo, pid, menuNum) - setMenuNumber(menuNum) - } -} From 60ed70445b97d7320e69b2e5676774a42f23df49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Mon, 24 Feb 2025 18:54:03 +0900 Subject: [PATCH 124/352] =?UTF-8?q?-=20menuNumber=20->=20selectedMenu=20?= =?UTF-8?q?=EB=AA=85=EC=B9=AD=20=EB=B3=80=EA=B2=BD=20-=20menuType=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 4 +- src/components/floor-plan/CanvasLayout.jsx | 4 +- src/components/floor-plan/CanvasMenu.jsx | 90 ++++++++----------- src/components/floor-plan/FloorPlan.jsx | 10 ++- src/components/floor-plan/MenuDepth01.jsx | 15 ++-- .../step/type/PassivityCircuitAllocation.jsx | 4 +- src/components/management/StuffDetail.jsx | 6 +- src/components/management/StuffSubHeader.jsx | 4 +- src/hooks/common/useCanvasMenu.js | 24 +---- src/hooks/option/useCanvasSetting.js | 16 ++-- .../roofcover/useRoofAllocationSetting.js | 7 +- src/hooks/surface/useSurfaceShapeBatch.js | 2 +- src/store/menuAtom.js | 19 ++-- 13 files changed, 85 insertions(+), 120 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index deb95caf..72e7bb30 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -87,7 +87,7 @@ export default function Estimate({}) { const { getMessage } = useMessage() const { closeAll } = usePopup() - const { setMenuNumber } = useCanvasMenu() + const { setSelectedMenu } = useCanvasMenu() //새로 추가한 첨부파일 props const fileUploadProps = { uploadFiles: files, @@ -142,7 +142,7 @@ export default function Estimate({}) { }, [selectedPlan]) useEffect(() => { - setMenuNumber(5) + setSelectedMenu('estimate') initEstimate() }, []) diff --git a/src/components/floor-plan/CanvasLayout.jsx b/src/components/floor-plan/CanvasLayout.jsx index 6a7d5ef0..22215fd2 100644 --- a/src/components/floor-plan/CanvasLayout.jsx +++ b/src/components/floor-plan/CanvasLayout.jsx @@ -14,7 +14,7 @@ import { globalLocaleStore } from '@/store/localeAtom' export default function CanvasLayout({ children }) { // const { menuNumber } = props const pathname = usePathname() - const { menuNumber } = useCanvasMenu() + const { selectedMenu } = useCanvasMenu() const { session } = useContext(SessionContext) const { floorPlanState } = useContext(FloorPlanContext) const { objectNo, pid } = floorPlanState @@ -30,7 +30,7 @@ export default function CanvasLayout({ children }) { return (
-
+
{plans.map((plan, index) => (
-
num === menuNumber) ? 'active' : ''}`}> - {[2, 3, 4].some((num) => num === menuNumber) && } +
num === selectedMenu) ? 'active' : ''}`}> + {['outline', 'surface', 'module'].some((num) => num === selectedMenu) && }
{/* 견적서(menuNumber=== 5) 상세화면인경우 문서다운로드 팝업 */} {estimatePopupOpen && ( diff --git a/src/components/floor-plan/FloorPlan.jsx b/src/components/floor-plan/FloorPlan.jsx index 054f1e00..25efa782 100644 --- a/src/components/floor-plan/FloorPlan.jsx +++ b/src/components/floor-plan/FloorPlan.jsx @@ -18,7 +18,7 @@ export default function FloorPlan({ children }) { const pid = searchParams.get('pid') const { closeAll } = usePopup() - const { menuNumber, setMenuNumber } = useCanvasMenu() + const { selectedMenu, setSelectedMenu } = useCanvasMenu() const { fetchSettings } = useCanvasSetting() const resetCurrentMenu = useResetRecoilState(currentMenuState) useEffect(() => { @@ -54,15 +54,17 @@ export default function FloorPlan({ children }) { }, [correntObjectNo]) const modalProps = { - menuNumber, - setMenuNumber, + selectedMenu, + setSelectedMenu, } return ( <>
-
{children}
+
+ {children} +
) diff --git a/src/components/floor-plan/MenuDepth01.jsx b/src/components/floor-plan/MenuDepth01.jsx index c1f40140..693ccc9d 100644 --- a/src/components/floor-plan/MenuDepth01.jsx +++ b/src/components/floor-plan/MenuDepth01.jsx @@ -6,32 +6,37 @@ import { useMessage } from '@/hooks/useMessage' import useMenu from '@/hooks/common/useMenu' import { canvasState, currentMenuState } from '@/store/canvasAtom' import { useRecoilState, useRecoilValue } from 'recoil' -import { menuTypeState, subMenusState } from '@/store/menuAtom' +import { subMenusState } from '@/store/menuAtom' +import { useCanvasMenu } from '@/hooks/common/useCanvasMenu' export default function MenuDepth01() { - const type = useRecoilValue(menuTypeState) const canvas = useRecoilValue(canvasState) const { getMessage } = useMessage() const { handleMenu } = useMenu() + const { selectedMenu, setSelectedMenu } = useCanvasMenu() const [currentMenu, setCurrentMenu] = useRecoilState(currentMenuState) const subMenus = useRecoilValue(subMenusState) const onClickMenu = ({ id, menu }) => { if (menu === currentMenu) { - handleMenu(type) + handleMenu(selectedMenu) } else { setCurrentMenu(menu) } } useEffect(() => { - handleMenu(type) + console.log(subMenus[selectedMenu]) + }, [selectedMenu]) + + useEffect(() => { + handleMenu(selectedMenu) canvas?.discardActiveObject() }, [currentMenu]) return (
    - {subMenus[type]?.map((menu) => { + {subMenus[selectedMenu]?.map((menu) => { return (
  • diff --git a/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx b/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx index 69f5383e..eaf41524 100644 --- a/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx @@ -220,8 +220,8 @@ export default function PassivityCircuitAllocation(props) { goodsNo: model.goodsNo, serQtyList: [ { - serQty: result[index + 1].maxValue, - paralQty: result[index + 1].count, + serQty: result[(index + 1).toString()].maxValue, + paralQty: result[(index + 1).toString()].count, rmdYn: 'Y', usePossYn: 'Y', roofSurfaceList: roofSurfaceList, diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index a95f34d2..aacaeea4 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -38,7 +38,7 @@ export default function StuffDetail() { const [showButton, setShowButton] = useState('') //임시저장, 저장, 삭제 버튼 컨트롤 - const { setMenuNumber } = useCanvasMenu() + const { setSelectedMenu } = useCanvasMenu() //공통코드 const { commonCode, findCommonCode } = useCommonCode() @@ -308,7 +308,7 @@ export default function StuffDetail() { onClick={() => { setFloorPlanObjectNo({ floorPlanObjectNo: params.data.objectNo }) setIsGlobalLoading(true) - setMenuNumber(5) + setSelectedMenu('estimate') router.push(`/floor-plan/estimate/5?pid=${params.data.planNo}&objectNo=${params.data.objectNo}`) }} > @@ -1653,7 +1653,7 @@ export default function StuffDetail() { pid: planNo, objectNo: objectNo, } - setMenuNumber(null) + setSelectedMenu(null) const url = `/floor-plan?${queryStringFormatter(param)}` router.push(url) } diff --git a/src/components/management/StuffSubHeader.jsx b/src/components/management/StuffSubHeader.jsx index 368926a2..18eaa761 100644 --- a/src/components/management/StuffSubHeader.jsx +++ b/src/components/management/StuffSubHeader.jsx @@ -27,7 +27,7 @@ export default function StuffSubHeader({ type }) { const [buttonStyle, setButtonStyle] = useState('') - const { setMenuNumber } = useCanvasMenu() + const { setSelectedMenu } = useCanvasMenu() useEffect(() => { window.scrollTo(0, 0) @@ -55,7 +55,7 @@ export default function StuffSubHeader({ type }) { objectNo: objectNo, } - setMenuNumber(null) + setSelectedMenu(null) const url = `/floor-plan?${queryStringFormatter(param)}` router.push(url) diff --git a/src/hooks/common/useCanvasMenu.js b/src/hooks/common/useCanvasMenu.js index 0fb1e87d..f90881d3 100644 --- a/src/hooks/common/useCanvasMenu.js +++ b/src/hooks/common/useCanvasMenu.js @@ -1,4 +1,4 @@ -import { menuNumberState } from '@/store/menuAtom' +import { selectedMenuState } from '@/store/menuAtom' import { useRecoilState, useRecoilValue } from 'recoil' import { useEffect } from 'react' import { canvasState } from '@/store/canvasAtom' @@ -6,28 +6,12 @@ import { usePolygon } from '@/hooks/usePolygon' import { POLYGON_TYPE } from '@/common/common' export const useCanvasMenu = () => { - const [menuNumber, setMenuNumber] = useRecoilState(menuNumberState) + const [selectedMenu, setSelectedMenu] = useRecoilState(selectedMenuState) const canvas = useRecoilValue(canvasState) const { drawDirectionArrow } = usePolygon() - /*useEffect(() => { - /!* - * 모듈,회로 구성을 벗어나면 방향 표시 초기화 필요 - * *!/ - if (!canvas) return - if (![4, 5].includes(menuNumber)) { - canvas - .getObjects() - .filter((obj) => obj.name === POLYGON_TYPE.ROOF) - .forEach((obj) => { - obj.set('moduleCompass', null) - // drawDirectionArrow(obj) - }) - } - }, [menuNumber])*/ - return { - menuNumber, - setMenuNumber, + selectedMenu, + setSelectedMenu, } } diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js index 255cc9ee..b1502934 100644 --- a/src/hooks/option/useCanvasSetting.js +++ b/src/hooks/option/useCanvasSetting.js @@ -33,7 +33,6 @@ import { useColor } from 'react-color-palette' import { useMasterController } from '@/hooks/common/useMasterController' import PlacementShapeSetting, { ROOF_MATERIAL_LAYOUT } from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting' import { useCanvasMenu } from '../common/useCanvasMenu' -import { menuTypeState } from '@/store/menuAtom' import { usePopup } from '../usePopup' import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider' import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions' @@ -88,7 +87,7 @@ export function useCanvasSetting() { ) const [gridColor, setGridColor] = useRecoilState(gridColorState) const [color, setColor] = useColor(gridColor ?? '#FF0000') - const { menuNumber, setMenuNumber } = useCanvasMenu() + const { selectedMenu, setSelectedMenu } = useCanvasMenu() const [settingsData, setSettingsData] = useState({ ...settingModalFirstOptions, @@ -116,7 +115,6 @@ export function useCanvasSetting() { const [roofMaterials, setRoofMaterials] = useRecoilState(roofMaterialsAtom) const [addedRoofs, setAddedRoofs] = useRecoilState(addedRoofsState) const [fetchRoofMaterials, setFetchRoofMaterials] = useRecoilState(fetchRoofMaterialsState) - const [type, setType] = useRecoilState(menuTypeState) const setCurrentMenu = useSetRecoilState(currentMenuState) const resetModuleSelectionData = useResetRecoilState(moduleSelectionDataState) //다음으로 넘어가는 최종 데이터 @@ -482,12 +480,10 @@ export function useCanvasSetting() { /* 메뉴 설정 */ if (['2', '3'].includes(params.roofSizeSet)) { - setMenuNumber(3) - setType('surface') + setSelectedMenu('surface') setCurrentMenu(MENU.BATCH_CANVAS.BATCH_DRAWING) } else { - setMenuNumber(2) - setType('outline') + setSelectedMenu('outline') setCurrentMenu(MENU.ROOF_COVERING.EXTERIOR_WALL_LINE) } @@ -543,12 +539,10 @@ export function useCanvasSetting() { /* 메뉴 설정 */ if (['2', '3'].includes(params?.roofSizeSet)) { - setMenuNumber(3) - setType('surface') + setSelectedMenu('surface') setCurrentMenu(MENU.BATCH_CANVAS.BATCH_DRAWING) } else { - setMenuNumber(2) - setType('outline') + setSelectedMenu('outline') setCurrentMenu(MENU.ROOF_COVERING.EXTERIOR_WALL_LINE) } diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js index bf2756ec..4dc7d839 100644 --- a/src/hooks/roofcover/useRoofAllocationSetting.js +++ b/src/hooks/roofcover/useRoofAllocationSetting.js @@ -19,7 +19,6 @@ import ActualSizeSetting from '@/components/floor-plan/modal/roofAllocation/Actu import { useMessage } from '@/hooks/useMessage' import useMenu from '@/hooks/common/useMenu' import { useCanvasMenu } from '@/hooks/common/useCanvasMenu' -import { menuTypeState } from '@/store/menuAtom' import { useRoofFn } from '@/hooks/common/useRoofFn' import { ROOF_MATERIAL_LAYOUT } from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting' import { globalLocaleStore } from '@/store/localeAtom' @@ -37,8 +36,7 @@ export function useRoofAllocationSetting(id) { const [popupId, setPopupId] = useState(uuidv4()) const { addPopup, closePopup, closeAll } = usePopup() const currentObject = useRecoilValue(currentObjectState) - const { setMenuNumber } = useCanvasMenu() - const setMenuType = useSetRecoilState(menuTypeState) + const { setSelectedMenu } = useCanvasMenu() const roofMaterials = useRecoilValue(roofMaterialsSelector) const selectedRoofMaterial = useRecoilValue(selectedRoofMaterialSelector) const [basicSetting, setBasicSetting] = useRecoilState(basicSettingState) @@ -387,8 +385,7 @@ export function useRoofAllocationSetting(id) { }) setEditingLines([]) closeAll() - setMenuNumber(3) - setMenuType('surface') + setSelectedMenu('surface') modifyModuleSelectionData() } diff --git a/src/hooks/surface/useSurfaceShapeBatch.js b/src/hooks/surface/useSurfaceShapeBatch.js index 9b8831ed..a90a1b97 100644 --- a/src/hooks/surface/useSurfaceShapeBatch.js +++ b/src/hooks/surface/useSurfaceShapeBatch.js @@ -140,7 +140,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { } } } else { - imageRotate = (rotate + 4) % 4 + imageRotate = (rotate + 360) % 360 } obj.set({ angle: imageRotate }) obj.setCoords() //좌표 변경 적용 diff --git a/src/store/menuAtom.js b/src/store/menuAtom.js index 759df0fd..0254cbb9 100644 --- a/src/store/menuAtom.js +++ b/src/store/menuAtom.js @@ -6,32 +6,33 @@ export const menuNumberState = atom({ default: null, }) -export const menuTypeState = atom({ - key: 'menuTypeState', +export const selectedMenuState = atom({ + key: 'selectedMenuState', default: null, }) export const menusState = atom({ key: 'menusState', default: [ - { index: 0, name: 'plan.menu.plan.drawing', icon: 'con00', title: MENU.PLAN_DRAWING }, + { type: 'drawing', name: 'plan.menu.plan.drawing', icon: 'con00', title: MENU.PLAN_DRAWING }, //. 도면 작성 { - index: 1, + type: 'placement', // 배치면 초기설정 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 }, + { type: 'outline', name: 'plan.menu.roof.cover', icon: 'con02', title: MENU.ROOF_COVERING.DEFAULT }, + { type: 'surface', name: 'plan.menu.placement.surface', icon: 'con03', title: MENU.BATCH_CANVAS.DEFAULT }, + { type: 'module', name: 'plan.menu.module.circuit.setting', icon: 'con04', title: MENU.MODULE_CIRCUIT_SETTING.DEFAULT }, + { type: 'estimate', name: 'plan.menu.estimate', icon: 'con06', title: MENU.ESTIMATE.DEFAULT }, + { type: 'simulation', name: 'plan.menu.simulation', icon: 'con05', title: MENU.POWER_GENERATION_SIMULATION.DEFAULT }, ], }) export const subMenusState = atom({ key: 'subMenusState', default: { + placement: [], // 배치면 초기 설정 outline: [ // 지붕덮개 { id: 0, name: 'plan.menu.roof.cover.outline.drawing', menu: MENU.ROOF_COVERING.EXTERIOR_WALL_LINE }, From bb8d22ea789e131aa10818c638f9ed8fc9b3df1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Mon, 24 Feb 2025 18:54:18 +0900 Subject: [PATCH 125/352] =?UTF-8?q?=F0=9F=9A=A8chore:=20Sync=20Sass?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/styles/_modal.scss | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/styles/_modal.scss b/src/styles/_modal.scss index a19aba2e..fed29abe 100644 --- a/src/styles/_modal.scss +++ b/src/styles/_modal.scss @@ -995,6 +995,26 @@ $alert-color: #101010; } } } + &:disabled{ + color: $pop-color; + border: 1px solid #646464; + background-color: transparent; + opacity: 0.5; + &.act, + &:hover{ + color: $pop-color; + border: 1px solid #646464; + background-color: transparent; + i{ + &.allocation01{ + background-image: url(../../public/static/images/canvas/allocation_icon01_white.svg); + } + &.allocation02{ + background-image: url(../../public/static/images/canvas/allocation_icon02_white.svg); + } + } + } + } } } From eb751af4329f9bc99de4f6078838e68798ede8fb Mon Sep 17 00:00:00 2001 From: changkyu choi Date: Mon, 24 Feb 2025 19:07:35 +0900 Subject: [PATCH 126/352] =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=A9=B4=EC=84=A4?= =?UTF-8?q?=EC=A0=95=ED=99=94=EB=A9=B4=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20?= =?UTF-8?q?=EC=A1=B4=EC=9E=AC=20=EC=8B=9C=20=ED=99=94=EB=A9=B4=20=EB=8B=AB?= =?UTF-8?q?=EA=B8=B0(=EB=A9=94=EB=89=B4/=EC=A0=80=EC=9E=A5=20=ED=81=B4?= =?UTF-8?q?=EB=A6=AD=20=EC=8B=9C=20=EC=A0=9C=EC=99=B8)=20-closeAll()=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/option/useCanvasSetting.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js index b6be8894..5ae28ba9 100644 --- a/src/hooks/option/useCanvasSetting.js +++ b/src/hooks/option/useCanvasSetting.js @@ -341,7 +341,8 @@ export function useCanvasSetting() { /* 데이터 존재 시 화면 닫기(메뉴/저장 클릭 시 제외) */ if (openPoint !== 'canvasMenus' && openPoint !== 'basicSettingSave') { - closePopup(popupId) + //closePopup(popupId) + closeAll() } } else { roofsRow = [ From 7ebe77c7638e672ccbcb4d44587efc2699a5f075 Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 25 Feb 2025 09:22:56 +0900 Subject: [PATCH 127/352] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=B2=A8?= =?UTF-8?q?=EB=B6=80=ED=8C=8C=EC=9D=BC=20=ED=99=95=EC=9E=A5=EC=9E=90=20?= =?UTF-8?q?=EC=B2=B4=ED=81=AC=20=EB=93=9C=EB=9E=98=EA=B7=B8&=EB=93=9C?= =?UTF-8?q?=EB=9E=8D=EB=8F=84=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../estimate/EstimateFileUploader.jsx | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/components/estimate/EstimateFileUploader.jsx b/src/components/estimate/EstimateFileUploader.jsx index 26f28405..c02d4637 100644 --- a/src/components/estimate/EstimateFileUploader.jsx +++ b/src/components/estimate/EstimateFileUploader.jsx @@ -23,10 +23,16 @@ export default function EstimateFileUploader({ uploadFiles, setUploadFiles }) { const fileList = [] let passFlag = true + const allowedFileTypes = [ + 'image/', + 'application/pdf', + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'application/vnd.ms-excel', + ] Array.from(e.target.files).forEach((file) => { - let fileType = file.type //엑셀, pdf, 이미지 - if (!fileType.includes('image') && !fileType.includes('pdf') && !fileType.includes('spreadsheet')) { + const fileType = file.type + if (!allowedFileTypes.some((type) => fileType.includes(type))) { passFlag = false } else { fileList.push({ data: file, id: uuidv4() }) @@ -34,7 +40,7 @@ export default function EstimateFileUploader({ uploadFiles, setUploadFiles }) { }) if (!passFlag) { - swalFire({ text: getMessage('estimate.detail.fileList.extCheck'), type: 'alert' }) + swalFire({ text: getMessage('estimate.detail.fileList.extCheck'), type: 'alert', icon: 'error' }) } setUploadFiles([...uploadFiles, ...fileList]) @@ -50,10 +56,17 @@ export default function EstimateFileUploader({ uploadFiles, setUploadFiles }) { e.stopPropagation() const fileList = [] let passFlag = true + const allowedFileTypes = [ + 'image/', + 'application/pdf', + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'application/vnd.ms-excel', + ] Array.from(e.dataTransfer.files).forEach((file) => { + //엑셀, pdf, 이미지 let fileType = file.type - if (!fileType.includes('image')) { + if (!allowedFileTypes.some((type) => fileType.includes(type))) { passFlag = false } else { fileList.push({ data: file, id: uuidv4() }) @@ -61,7 +74,7 @@ export default function EstimateFileUploader({ uploadFiles, setUploadFiles }) { }) if (!passFlag) { - swalFire({ text: getMessage('estimate.detail.fileList.extCheck'), type: 'alert' }) + swalFire({ text: getMessage('estimate.detail.fileList.extCheck'), type: 'alert', icon: 'error' }) } setUploadFiles([...uploadFiles, ...fileList]) @@ -88,16 +101,7 @@ export default function EstimateFileUploader({ uploadFiles, setUploadFiles }) { - onChangeFiles(e)} - /> + onChangeFiles(e)} />
Date: Tue, 25 Feb 2025 09:37:47 +0900 Subject: [PATCH 128/352] =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EB=86=92=EC=9D=B4?= =?UTF-8?q?=20=EA=B3=84=EC=82=B0=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 71 ++++++++++++----------- src/hooks/surface/useSurfaceShapeBatch.js | 2 +- 2 files changed, 39 insertions(+), 34 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index e14011ab..224e088f 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -911,7 +911,7 @@ export function useModuleBasicSetting(tabNum) { let moduleMaxRows = tmpModuleData.mixModuleMaxRows === 0 ? tmpModuleData.moduleMaxRows : tmpModuleData.mixModuleMaxRows // 혼합모듈 포함 총 모듈 설치 높이 갯수 - const totalModuleMaxRows = tmpModuleData.moduleMaxRows + // const totalModuleMaxRows = tmpModuleData.moduleMaxRows //모듈의 넓이 높이를 가져옴 (복시도 촌수 적용) //1번 깔았던 모듈 기준으로 잡야아함 @@ -962,12 +962,13 @@ export function useModuleBasicSetting(tabNum) { let calcAreaWidth = flowLines.right.x1 - flowLines.left.x1 //오른쪽 x에서 왼쪽 x를 뺀 가운데를 찾는 로직 let calcModuleWidthCount = calcAreaWidth / (width + intvHor) //뺀 공간에서 모듈을 몇개를 넣을수 있는지 확인하는 로직 + let calcMaxModuleWidthCount = calcModuleWidthCount > moduleMaxCols ? moduleMaxCols : calcModuleWidthCount //최대 모듈 단수가 있기 때문에 최대 단수보다 카운트가 크면 최대 단수로 씀씀 // let totalModuleWidthCount = isChidori ? Math.abs(calcMaxModuleWidthCount) : Math.floor(calcMaxModuleWidthCount) //치조배치일경우는 한개 더 넣는다 let totalModuleWidthCount = Math.floor(calcMaxModuleWidthCount) //치조배치일경우는 한개 더 넣는다 - // let calcAreaHeight = flowLines.bottom.y1 - flowLines.top.y1 - // let calcModuleHeightCount = calcAreaHeight / (height + intvVer) + let calcAreaHeight = flowLines.bottom.y1 - flowLines.top.y1 + let calcModuleHeightCount = calcAreaHeight / (height + intvVer) let calcStartPoint = flowLines.right.type === 'flat' ? (calcAreaWidth - totalModuleWidthCount * width) / 2 : 0 //반씩 나눠서 중앙에 맞춤 bottom 기준으로 양변이 직선일때만 가운데 정렬 let startPointX = flowLines.left.x1 + calcStartPoint //시작점을 만든다 @@ -976,9 +977,9 @@ export function useModuleBasicSetting(tabNum) { if (flowLines.left.type === 'curve' && flowLines.right.type === 'curve') { startPointX = flowLines.left.x1 + (calcAreaWidth - totalModuleWidthCount * width) / 2 - if (flowLines.left.x1 < flowLines.bottom.x1) { - startPointX = flowLines.left.x1 - } + // if (flowLines.left.x1 < flowLines.bottom.x1) { + // startPointX = flowLines.left.x1 + // } } let heightMargin = 0 @@ -987,13 +988,13 @@ export function useModuleBasicSetting(tabNum) { //첫번재 모듈 설치 후 두번째 모듈을 몇개까지 설치 할 수 있는지 계산 if (moduleIndex > 0) { - moduleMaxRows = totalModuleMaxRows - installedModuleHeightCount //두번째 모듈일때 + // moduleMaxRows = totalModuleMaxRows - installedModuleHeightCount //두번째 모듈일때 isChidoriLine = installedModuleHeightCount % 2 != 0 ? true : false //첫번째에서 짝수에서 끝났으면 홀수는 치도리가 아님 짝수는 치도리 } let isInstall = false - for (let i = 0; i < moduleMaxRows; i++) { + for (let i = 0; i < calcModuleHeightCount; i++) { let moduleY = flowLines.bottom.y1 - height * i - 1 //살짝 여유를 준다 //두번째 모듈 -> 혼합일 경우의 설치될 모듈 높이를 계산 @@ -1002,9 +1003,10 @@ export function useModuleBasicSetting(tabNum) { } //전체 설치 간으 모듈이랑 같으면 반복을 멈춘다 - if (totalModuleMaxRows === installedModuleHeightCount) { - break - } + //사용안함 전체를 위로 올리기로 했음 + // if (totalModuleMaxRows === installedModuleHeightCount) { + // break + // } //첫번째는 붙여서 두번째는 마진을 주고 설치 heightMargin = i === 0 ? 0 : intvVer * i @@ -1233,6 +1235,9 @@ export function useModuleBasicSetting(tabNum) { // let totalModuleWidthCount = isChidori ? Math.abs(calcMaxModuleWidthCount) : Math.floor(calcMaxModuleWidthCount) //치조배치일경우는 한개 더 넣는다 //??어쩔때는 붙고 어쩔때는 안붙고 멋대로??? let totalModuleWidthCount = Math.floor(calcMaxModuleWidthCount) //치조배치일경우는 한개 더 넣는다 + let calcAreaHeight = flowLines.bottom.y1 - flowLines.top.y1 + let calcModuleHeightCount = calcAreaHeight / (height + intvVer) + let calcStartPoint = flowLines.left.type === 'flat' ? (calcAreaWidth - totalModuleWidthCount * width) / 2 : 0 //반씩 나눠서 중앙에 맞춤 bottom 기준으로 양변이 직선일때만 가운데 정렬 let startPointX = flowLines.right.x1 - calcStartPoint //시작점을 만든다 @@ -1257,7 +1262,7 @@ export function useModuleBasicSetting(tabNum) { let isInstall = false - for (let i = 0; i < moduleMaxRows; i++) { + for (let i = 0; i < calcModuleHeightCount; i++) { let moduleY = flowLines.top.y1 + height * i //탑의 y점에서부터 아래로 그려 내려간다 if (moduleIndex > 0) { @@ -1265,9 +1270,9 @@ export function useModuleBasicSetting(tabNum) { } //전체 설치 간으 모듈이랑 같으면 반복을 멈춘다 - if (totalModuleMaxRows === installedModuleHeightCount) { - break - } + // if (totalModuleMaxRows === installedModuleHeightCount) { + // break + // } heightMargin = i === 0 ? 0 : intvVer * i //모듈간에 마진이 있어 마진값도 넣음 for (let j = 0; j < totalModuleWidthCount; j++) { @@ -1328,9 +1333,9 @@ export function useModuleBasicSetting(tabNum) { installedLastHeightCoord = moduleY + height + heightMargin } else { //디버깅용 - // tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) - // canvas?.add(tempModule) - // canvas.renderAll() + tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) + canvas?.add(tempModule) + canvas.renderAll() } } if (isInstall) { @@ -1533,8 +1538,8 @@ export function useModuleBasicSetting(tabNum) { // let totalModuleWidthCount = isChidori ? Math.abs(calcMaxModuleWidthCount) : Math.floor(calcMaxModuleWidthCount) //치조배치일경우는 한개 더 넣는다 let totalModuleWidthCount = Math.floor(calcMaxModuleWidthCount) //치조배치일경우는 한개 더 넣는다 - // let calcAreaHeight = flowLines.bottom.y1 - flowLines.top.y1 - // let calcModuleHeightCount = calcAreaHeight / (height + intvVer) + let calcAreaHeight = flowLines.right.x1 - flowLines.left.x1 + let calcModuleHeightCount = calcAreaHeight / (width + intvVer) let calcStartPoint = flowLines.bottom.type === 'flat' ? (calcAreaWidth - totalModuleWidthCount * height) / 2 : 0 //반씩 나눠서 중앙에 맞춤 left 높이 기준으로 양변이 직선일때만 가운데 정렬 let startPointX = flowLines.top.y1 + calcStartPoint //시작점을 만든다 @@ -1561,7 +1566,7 @@ export function useModuleBasicSetting(tabNum) { let isInstall = false - for (let i = 0; i < moduleMaxRows; i++) { + for (let i = 0; i < calcModuleHeightCount; i++) { let moduleY = flowLines.left.x1 + width * i + 1 //살짝 여유를 준다 //두번째 모듈 -> 혼합일 경우의 설치될 모듈 높이를 계산 @@ -1570,9 +1575,9 @@ export function useModuleBasicSetting(tabNum) { } //전체 설치 간으 모듈이랑 같으면 반복을 멈춘다 - if (totalModuleMaxRows === installedModuleHeightCount) { - break - } + // if (totalModuleMaxRows === installedModuleHeightCount) { + // break + // } //첫번째는 붙여서 두번째는 마진을 주고 설치 heightMargin = i === 0 ? 0 : intvHor * i @@ -1638,9 +1643,9 @@ export function useModuleBasicSetting(tabNum) { // } } else { //디버깅용 - // tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) - // canvas?.add(tempModule) - // canvas.renderAll() + tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) + canvas?.add(tempModule) + canvas.renderAll() } } @@ -1835,8 +1840,8 @@ export function useModuleBasicSetting(tabNum) { // let totalModuleWidthCount = isChidori ? Math.abs(calcMaxModuleWidthCount) : Math.floor(calcMaxModuleWidthCount) //치조배치일경우는 한개 더 넣는다 let totalModuleWidthCount = Math.floor(calcMaxModuleWidthCount) //치조배치일경우는 한개 더 넣는다 - // let calcAreaHeight = flowLines.bottom.y1 - flowLines.top.y1 - // let calcModuleHeightCount = calcAreaHeight / (height + intvVer) + let calcAreaHeight = flowLines.right.x1 - flowLines.left.x1 + let calcModuleHeightCount = calcAreaHeight / (width + intvVer) let calcStartPoint = flowLines.top.type === 'flat' ? (calcAreaWidth - totalModuleWidthCount * height) / 2 : 0 //반씩 나눠서 중앙에 맞춤 left 높이 기준으로 양변이 직선일때만 가운데 정렬 let startPointX = flowLines.bottom.y2 - calcStartPoint //시작점을 만든다 @@ -1863,7 +1868,7 @@ export function useModuleBasicSetting(tabNum) { let isInstall = false - for (let i = 0; i < moduleMaxRows; i++) { + for (let i = 0; i < calcModuleHeightCount; i++) { let moduleY = flowLines.right.x1 - width * i - 1 //살짝 여유를 준다 //두번째 모듈 -> 혼합일 경우의 설치될 모듈 높이를 계산 @@ -1872,9 +1877,9 @@ export function useModuleBasicSetting(tabNum) { } //전체 설치 간으 모듈이랑 같으면 반복을 멈춘다 - if (totalModuleMaxRows === installedModuleHeightCount) { - break - } + // if (totalModuleMaxRows === installedModuleHeightCount) { + // break + // } //첫번째는 붙여서 두번째는 마진을 주고 설치 heightMargin = i === 0 ? 0 : intvHor * i diff --git a/src/hooks/surface/useSurfaceShapeBatch.js b/src/hooks/surface/useSurfaceShapeBatch.js index 9b8831ed..a90a1b97 100644 --- a/src/hooks/surface/useSurfaceShapeBatch.js +++ b/src/hooks/surface/useSurfaceShapeBatch.js @@ -140,7 +140,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { } } } else { - imageRotate = (rotate + 4) % 4 + imageRotate = (rotate + 360) % 360 } obj.set({ angle: imageRotate }) obj.setCoords() //좌표 변경 적용 From 960046813be0a90a5bc43d0c9e82358b5fc1a3ff Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Tue, 25 Feb 2025 09:47:07 +0900 Subject: [PATCH 129/352] =?UTF-8?q?=F0=9F=9A=A6chore:=20=EB=B9=8C=EB=93=9C?= =?UTF-8?q?=20=EA=B2=BD=EA=B3=A0=20=EC=A0=9C=EA=B1=B0=20=EB=B0=8F=20?= =?UTF-8?q?=EC=95=88=EC=93=B0=EB=8A=94=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/community/archive/page.jsx | 1 - src/app/initSettingsModal/page.jsx | 13 ------------- src/app/management/plan/page.jsx | 13 ------------- src/app/master/company/page.jsx | 13 ------------- src/app/master/price/page.jsx | 13 ------------- src/components/management/Plan.jsx | 7 ------- src/components/master/Company.jsx | 7 ------- src/components/master/Price.jsx | 7 ------- 8 files changed, 74 deletions(-) delete mode 100644 src/app/initSettingsModal/page.jsx delete mode 100644 src/app/management/plan/page.jsx delete mode 100644 src/app/master/company/page.jsx delete mode 100644 src/app/master/price/page.jsx delete mode 100644 src/components/management/Plan.jsx delete mode 100644 src/components/master/Company.jsx delete mode 100644 src/components/master/Price.jsx diff --git a/src/app/community/archive/page.jsx b/src/app/community/archive/page.jsx index eee23c36..4713bb0b 100644 --- a/src/app/community/archive/page.jsx +++ b/src/app/community/archive/page.jsx @@ -1,4 +1,3 @@ -import Hero from '@/components/Hero' import Archive from '@/components/community/Archive' export default async function CommunityArchivePage() { diff --git a/src/app/initSettingsModal/page.jsx b/src/app/initSettingsModal/page.jsx deleted file mode 100644 index fc51b5cc..00000000 --- a/src/app/initSettingsModal/page.jsx +++ /dev/null @@ -1,13 +0,0 @@ -import Hero from '@/components/Hero' -import InitSettingsModal from '@/components/InitSettingsModal' - -export default async function InitSettingsModalPage() { - return ( - <> - -
- -
- - ) -} diff --git a/src/app/management/plan/page.jsx b/src/app/management/plan/page.jsx deleted file mode 100644 index 51d67116..00000000 --- a/src/app/management/plan/page.jsx +++ /dev/null @@ -1,13 +0,0 @@ -import Hero from '@/components/Hero' -import Plan from '@/components/management/Plan' - -export default async function ManagementPlanPage() { - return ( - <> - -
- -
- - ) -} diff --git a/src/app/master/company/page.jsx b/src/app/master/company/page.jsx deleted file mode 100644 index 968452e8..00000000 --- a/src/app/master/company/page.jsx +++ /dev/null @@ -1,13 +0,0 @@ -import Hero from '@/components/Hero' -import Company from '@/components/master/Company' - -export default async function MasterCompanyPage() { - return ( - <> - -
- -
- - ) -} diff --git a/src/app/master/price/page.jsx b/src/app/master/price/page.jsx deleted file mode 100644 index 57fa0bd2..00000000 --- a/src/app/master/price/page.jsx +++ /dev/null @@ -1,13 +0,0 @@ -import Hero from '@/components/Hero' -import Price from '@/components/master/Price' - -export default async function MasterPricePage() { - return ( - <> - -
- -
- - ) -} diff --git a/src/components/management/Plan.jsx b/src/components/management/Plan.jsx deleted file mode 100644 index 0a627cc5..00000000 --- a/src/components/management/Plan.jsx +++ /dev/null @@ -1,7 +0,0 @@ -export default function Plan() { - return ( - <> -

Management Plan

- - ) -} diff --git a/src/components/master/Company.jsx b/src/components/master/Company.jsx deleted file mode 100644 index 0955e94c..00000000 --- a/src/components/master/Company.jsx +++ /dev/null @@ -1,7 +0,0 @@ -export default function Company() { - return ( - <> -

Master Company

- - ) -} diff --git a/src/components/master/Price.jsx b/src/components/master/Price.jsx deleted file mode 100644 index 9947f760..00000000 --- a/src/components/master/Price.jsx +++ /dev/null @@ -1,7 +0,0 @@ -export default function Price() { - return ( - <> -

Master Price

- - ) -} From 9561cd077c7d681bb31484d4a0d35bee802f6207 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Tue, 25 Feb 2025 10:05:52 +0900 Subject: [PATCH 130/352] =?UTF-8?q?=EB=94=94=EB=B2=84=EA=B9=85=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 224e088f..1d86e5bf 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -1333,9 +1333,9 @@ export function useModuleBasicSetting(tabNum) { installedLastHeightCoord = moduleY + height + heightMargin } else { //디버깅용 - tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) - canvas?.add(tempModule) - canvas.renderAll() + // tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) + // canvas?.add(tempModule) + // canvas.renderAll() } } if (isInstall) { @@ -1643,9 +1643,9 @@ export function useModuleBasicSetting(tabNum) { // } } else { //디버깅용 - tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) - canvas?.add(tempModule) - canvas.renderAll() + // tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) + // canvas?.add(tempModule) + // canvas.renderAll() } } @@ -2625,7 +2625,7 @@ export function useModuleBasicSetting(tabNum) { * 스냅기능 */ let snapDistance = 10 - let cellSnapDistance = 20 + let cellSnapDistance = 50 let intvHor = flowDirection === 'south' || flowDirection === 'north' ? 1 : 3 let intvVer = flowDirection === 'south' || flowDirection === 'north' ? 3 : 1 From dc1c2311f96069da84f70c9125139d12aaf9c6a3 Mon Sep 17 00:00:00 2001 From: LEEYONGJAE Date: Tue, 25 Feb 2025 10:06:31 +0900 Subject: [PATCH 131/352] =?UTF-8?q?=EB=B0=9C=EC=A0=84=EC=8B=9C=EB=AC=BC?= =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=85=98=20=EC=BA=94=EB=B2=84=EC=8A=A4?= =?UTF-8?q?=EB=A9=94=EB=89=B4=20index=EC=97=90=EC=84=9C=20type=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 9bf081d6..d76d4519 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -257,7 +257,7 @@ export default function CanvasMenu(props) { } }) break - case 6: + case 'simulation': setIsGlobalLoading(true) promiseGet({ url: `/api/estimate/${objectNo}/${selectedPlan.planNo}/detail` }).then((res) => { if (res.status === 200) { @@ -265,7 +265,7 @@ export default function CanvasMenu(props) { if (estimateDetail.estimateDate !== null && estimateDetail.docNo) { setSelectedMenu(menu.type) setCurrentMenu(menu.title) - router.push(`/floor-plan/simulator/${menu.index}?pid=${selectedPlan.planNo}&objectNo=${objectNo}`) + router.push(`/floor-plan/simulator/6?pid=${selectedPlan.planNo}&objectNo=${objectNo}`) if (pathname === '/floor-plan/simulator/6') { setIsGlobalLoading(false) } From 4da4bd5959e5fba716cb208dc7db33ef2e3212b0 Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 25 Feb 2025 10:07:38 +0900 Subject: [PATCH 132/352] =?UTF-8?q?CanvasMenu=20case=EB=AC=B8=20=EB=AA=A8?= =?UTF-8?q?=EB=93=88,=ED=9A=8C=EB=A1=9C=EA=B5=AC=EC=84=B1/=EA=B2=AC?= =?UTF-8?q?=EC=A0=81=EC=84=9C/=EB=B0=9C=EC=A0=84=EC=8B=9C=EB=AE=AC?= =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=85=98=20=ED=83=AD=204,5,6=20->=20'module'?= =?UTF-8?q?,=20'estimate',=20'simulation'=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 7 +++---- src/store/menuAtom.js | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 9bf081d6..356b461e 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -222,7 +222,7 @@ export default function CanvasMenu(props) { } await reloadCanvasStatus(objectNo, pid) break - case 4: + case 'module': if (selectedMenu < menu.index) { if (!checkMenuAndCanvasState()) { swalFire({ text: getMessage('menu.validation.canvas.roof') }) @@ -236,7 +236,7 @@ export default function CanvasMenu(props) { } await reloadCanvasStatus(objectNo, pid) break - case 5: + case 'estimate': setIsGlobalLoading(true) promiseGet({ url: `/api/estimate/${objectNo}/${selectedPlan.planNo}/detail` }).then((res) => { if (res.status === 200) { @@ -257,7 +257,7 @@ export default function CanvasMenu(props) { } }) break - case 6: + case 'simulation': setIsGlobalLoading(true) promiseGet({ url: `/api/estimate/${objectNo}/${selectedPlan.planNo}/detail` }).then((res) => { if (res.status === 200) { @@ -283,7 +283,6 @@ export default function CanvasMenu(props) { setCurrentMenu(menu.title) } if (pathname !== '/floor-plan') { - // if (menu.index !== 0 ) { //견적서 or 발전시뮬레이션 탭에서 같은 탭 클릭시 화면 이동했다 돌아오지않도록.. if (menu.type !== 'drawing' && menu.type !== 'estimate' && menu.type !== 'simulation') { router.push(`/floor-plan?pid=${pid}&objectNo=${objectNo}`) diff --git a/src/store/menuAtom.js b/src/store/menuAtom.js index 0254cbb9..6cfa656c 100644 --- a/src/store/menuAtom.js +++ b/src/store/menuAtom.js @@ -14,7 +14,7 @@ export const selectedMenuState = atom({ export const menusState = atom({ key: 'menusState', default: [ - { type: 'drawing', name: 'plan.menu.plan.drawing', icon: 'con00', title: MENU.PLAN_DRAWING }, //. 도면 작성 + { type: 'drawing', name: 'plan.menu.plan.drawing', icon: 'con00', title: MENU.PLAN_DRAWING }, //. 물건정보 { type: 'placement', // 배치면 초기설정 name: 'plan.menu.placement.surface.initial.setting', From 1f5ea792799656cd229d2434dbdd9a3cc4dda5eb Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 25 Feb 2025 10:12:17 +0900 Subject: [PATCH 133/352] =?UTF-8?q?CanvasMenu=20=EA=B2=AC=EC=A0=81?= =?UTF-8?q?=EC=84=9C=20=EC=9D=B4=EB=8F=99=20=EB=A9=94=EB=89=B4=EB=B2=88?= =?UTF-8?q?=ED=98=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 80c48640..108ff52d 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -246,7 +246,7 @@ export default function CanvasMenu(props) { setCurrentMenu(menu.title) setFloorPlanObjectNo({ floorPlanObjectNo: objectNo }) setIsGlobalLoading(false) - router.push(`/floor-plan/estimate/${menu.type}?pid=${selectedPlan.planNo}&objectNo=${objectNo}`) + router.push(`/floor-plan/estimate/5?pid=${selectedPlan.planNo}&objectNo=${objectNo}`) if (pathname === '/floor-plan/estimate/5') { setIsGlobalLoading(false) } From a96b90dc3a68de45f7cf6856d28000b6c2ed5af7 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Tue, 25 Feb 2025 10:21:54 +0900 Subject: [PATCH 134/352] =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=A9=B4=20=EC=A0=84?= =?UTF-8?q?=EC=B2=B4=20=EC=82=AD=EC=A0=9C=20=EC=8B=9C=20=EA=B7=B8=EB=A6=AC?= =?UTF-8?q?=EB=93=9C=EB=8F=84=20=EC=82=AC=EB=9D=BC=EC=A7=80=EB=8A=94=20?= =?UTF-8?q?=ED=98=84=EC=83=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/option/useCanvasSetting.js | 19 ++++++++++++++++++- src/hooks/surface/useSurfaceShapeBatch.js | 3 +++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js index 5ae28ba9..ab72fbc2 100644 --- a/src/hooks/option/useCanvasSetting.js +++ b/src/hooks/option/useCanvasSetting.js @@ -52,7 +52,9 @@ const defaultDotLineGridSetting = { LINE: false, } -export function useCanvasSetting() { +// hook 추가 시 executeEffect를 인자로 받고 false일 경우 useEffect를 실행하지 않는다. default true +// 아래 hook에 추가 된 함수만 사용하고 싶을 경우 false로 인자 전달 +export function useCanvasSetting(executeEffect = true) { const canvas = useRecoilValue(canvasState) /** canvas가 null이 아닐 때에만 getObjects 호출 */ const canvasObjects = canvas ? canvas.getObjects() : [] @@ -138,6 +140,9 @@ export function useCanvasSetting() { const { closePopup, closeAll } = usePopup() // 팝업 닫기 useEffect(() => { + if (!executeEffect) { + return + } const tempFetchRoofMaterials = !fetchRoofMaterials /** 초 1회만 실행하도록 처리 */ @@ -175,6 +180,9 @@ export function useCanvasSetting() { } useEffect(() => { + if (!executeEffect) { + return + } if (addedRoofs.length > 0 && addedRoofs[0].planNo === basicSetting.planNo) { const raftCodeList = findCommonCode('203800') setRaftCodes(raftCodeList) @@ -188,6 +196,9 @@ export function useCanvasSetting() { }, [addedRoofs]) useEffect(() => { + if (!executeEffect) { + return + } const selectedRoofMaterial = roofMaterials[0] if (addedRoofs.length === 0) { @@ -202,6 +213,9 @@ export function useCanvasSetting() { if (!canvas) { return } + if (!executeEffect) { + return + } const { column } = corridorDimension const lengthTexts = canvas.getObjects().filter((obj) => obj.name === 'lengthText') @@ -230,6 +244,9 @@ export function useCanvasSetting() { }, [corridorDimension]) useEffect(() => { + if (!executeEffect) { + return + } if (settingsDataSave !== undefined) onClickOption2() }, [settingsData]) diff --git a/src/hooks/surface/useSurfaceShapeBatch.js b/src/hooks/surface/useSurfaceShapeBatch.js index a90a1b97..439465a0 100644 --- a/src/hooks/surface/useSurfaceShapeBatch.js +++ b/src/hooks/surface/useSurfaceShapeBatch.js @@ -22,6 +22,7 @@ import { placementShapeDrawingPointsState } from '@/store/placementShapeDrawingA import { getBackGroundImage } from '@/lib/imageActions' import PlacementSurfaceLineProperty from '@/components/floor-plan/modal/placementShape/PlacementSurfaceLineProperty' import { v4 as uuidv4 } from 'uuid' +import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { const { getMessage } = useMessage() @@ -40,6 +41,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { const { addPopup, closePopup } = usePopup() const { setSurfaceShapePattern } = useRoofFn() const currentCanvasPlan = useRecoilValue(currentCanvasPlanState) + const { fetchSettings } = useCanvasSetting(false) const applySurfaceShape = (surfaceRefs, selectedType, id) => { let length1, length2, length3, length4, length5 @@ -762,6 +764,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { resetOuterLinePoints() resetPlacementShapeDrawingPoints() + fetchSettings() swalFire({ text: getMessage('plan.message.delete') }) }, // denyFn: () => { From 758ae8cda57c32b91ca2a2184a0183ae170faa38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Tue, 25 Feb 2025 10:54:55 +0900 Subject: [PATCH 135/352] =?UTF-8?q?=EC=9C=A1=EC=A7=80=EB=B6=95=EC=9D=BC?= =?UTF-8?q?=EB=95=8C=20=EC=A7=80=EB=B6=95=EC=9E=AC=20=EB=B0=B0=EC=B9=98=20?= =?UTF-8?q?=EB=B0=A9=EC=8B=9D=20=EB=B2=84=ED=8A=BC=20=EB=B9=84=ED=99=9C?= =?UTF-8?q?=EC=84=B1=ED=99=94=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/placementShape/PlacementShapeSetting.jsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx index ed400f95..e058b918 100644 --- a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx @@ -457,6 +457,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla
{getMessage('stuff.planReqPopup.search.planStatName')} -
-
{getMessage('stuff.planReqPopup.search.period')}
- {/* - */} diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx index bfa86372..a7decdb7 100644 --- a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx @@ -17,10 +17,14 @@ import { globalLocaleStore } from '@/store/localeAtom' import { onlyNumberInputChange } from '@/util/input-utils' import { getChonByDegree, getDegreeByChon } from '@/util/canvas-util' +/** + * 지붕 레이아웃 + */ export const ROOF_MATERIAL_LAYOUT = { PARALLEL: 'P', STAIRS: 'S', } + export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, planNo, openPoint }) { const [showSizeGuideModal, setShowSizeGuidModal] = useState(false) const [showMaterialGuideModal, setShowMaterialGuidModal] = useState(false) @@ -31,9 +35,9 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla const { basicSetting, setBasicSettings, fetchBasicSettings, basicSettingSave } = useCanvasSetting() const [addedRoofs, setAddedRoofs] = useRecoilState(addedRoofsState) const { findCommonCode } = useCommonCode() - const [raftCodes, setRaftCodes] = useState([]) // 서까래 정보 - const [currentRoof, setCurrentRoof] = useState(null) // 현재 선택된 지붕재 정보 - const { closePopup } = usePopup() // usePopup에서 closeAll 함수 가져오기 + const [raftCodes, setRaftCodes] = useState([]) /** 서까래 정보 */ + const [currentRoof, setCurrentRoof] = useState(null) /** 현재 선택된 지붕재 정보 */ + const { closePopup } = usePopup() /** usePopup에서 closePopup 함수 가져오기 */ const roofRef = { roofCd: useRef(null), @@ -100,6 +104,9 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla if (openPoint && openPoint === 'canvasMenus') fetchBasicSettings(planNo, openPoint) }, []) + /** + * 배치면초기설정 데이터 조회 후 화면 오픈 + */ useEffect(() => { if (addedRoofs.length > 0) { const raftCodeList = findCommonCode('203800') @@ -145,6 +152,9 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla setCurrentRoof({ ...currentRoof, roofAngleSet: value }) } + /** + * 지붕재 변경 시 현재 지붕 정보 변경 + */ const handleRoofTypeChange = (value) => { const selectedRoofMaterial = roofMaterials.find((roof) => roof.roofMatlCd === value) @@ -159,15 +169,24 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla }) } + /** + * 입력 값 변경 시 현재 지붕 정보 변경 + */ const changeInput = (value, e) => { const { name } = e.target setCurrentRoof({ ...currentRoof, [name]: Number(value) }) } + /** + * 서까래 변경 시 현재 지붕 정보 변경 + */ const handleRafterChange = (value) => { setCurrentRoof({ ...currentRoof, raft: value }) } + /** + * 지붕 레이아웃 변경 시 현재 지붕 정보 변경 + */ const handleRoofLayoutChange = (value) => { if (+currentRoof.roofSizeSet === 3) { setCurrentRoof({ ...currentRoof, layout: ROOF_MATERIAL_LAYOUT.PARALLEL }) @@ -176,6 +195,9 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla setCurrentRoof({ ...currentRoof, layout: value }) } + /** + * 배치면초기설정 저장 버튼 클릭 + */ const handleSaveBtn = () => { const roofInfo = { ...currentRoof, @@ -321,7 +343,6 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla ? currentRoof?.roofMatlNm : currentRoof?.roofMatlNmJp } - //ref={roofRef.roofCd} options={roofMaterials.map((roof) => { return { ...roof, name: globalLocale === 'ko' ? roof.roofMatlNm : roof.roofMatlNmJp } })} @@ -332,23 +353,6 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla showKey="name" disabled={currentRoof?.roofSizeSet === '3'} /> - {/* */} {currentRoof && ['R', 'C'].includes(currentRoof.widAuth) && (
@@ -365,14 +369,6 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla disabled={currentRoof?.roofSizeSet === '3'} />
- {/*
- -
*/} )} {currentRoof && ['R', 'C'].includes(currentRoof.lenAuth) && ( @@ -390,14 +386,6 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla disabled={currentRoof?.roofSizeSet === '3'} /> - {/*
- -
*/} )} {currentRoof && ['C', 'R'].includes(currentRoof.raftAuth) && ( @@ -407,7 +395,6 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla
r.clCode === (currentRoof?.raft === undefined ? currentRoof?.raftBaseCd : currentRoof?.raft)) .clCodeNm @@ -419,15 +406,6 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla showKey="clCodeNm" disabled={currentRoof?.roofSizeSet === '3'} /> - {/* */}
)} diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js index 4dc7d839..5fb72a1f 100644 --- a/src/hooks/roofcover/useRoofAllocationSetting.js +++ b/src/hooks/roofcover/useRoofAllocationSetting.js @@ -27,7 +27,6 @@ import { moduleSelectionDataState } from '@/store/selectedModuleOptions' import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController' import { outerLinePointsState } from '@/store/outerLineAtom' -// 지붕면 할당 export function useRoofAllocationSetting(id) { const canvas = useRecoilValue(canvasState) const [correntObjectNo, setCorrentObjectNo] = useRecoilState(correntObjectNoState) @@ -40,8 +39,8 @@ export function useRoofAllocationSetting(id) { const roofMaterials = useRecoilValue(roofMaterialsSelector) const selectedRoofMaterial = useRecoilValue(selectedRoofMaterialSelector) const [basicSetting, setBasicSetting] = useRecoilState(basicSettingState) - const [currentRoofMaterial, setCurrentRoofMaterial] = useState(roofMaterials[0]) // 팝업 내 기준 지붕재 - const [roofList, setRoofList] = useRecoilState(addedRoofsState) // 배치면 초기설정에서 선택한 지붕재 배열 + const [currentRoofMaterial, setCurrentRoofMaterial] = useState(roofMaterials[0]) /** 팝업 내 기준 지붕재 */ + const [roofList, setRoofList] = useRecoilState(addedRoofsState) /** 배치면 초기설정에서 선택한 지붕재 배열 */ const [editingLines, setEditingLines] = useState([]) const [currentRoofList, setCurrentRoofList] = useState([]) const currentAngleType = useRecoilValue(currentAngleTypeSelector) @@ -57,14 +56,25 @@ export function useRoofAllocationSetting(id) { const resetPoints = useResetRecoilState(outerLinePointsState) useEffect(() => { + /** 배치면 초기설정에서 선택한 지붕재 배열 설정 */ setCurrentRoofList(roofList) }, []) useEffect(() => { - const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) // roofPolygon.innerLines + const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) /** roofPolygon.innerLines */ roofBases.forEach((roof) => { + /** 현재 선택된 라인인 경우 라인 두께 2로 설정 */ + if (editingLines.includes(line)) { + line.set({ + strokeWidth: 2, + stroke: 'black', + selectable: true, + }) + } + roof.innerLines.forEach((line) => { + /** 실측값이 없는 경우 라인 두께 4로 설정 */ if (!line.attributes.actualSize || line.attributes?.actualSize === 0) { line.set({ strokeWidth: 4, @@ -73,6 +83,7 @@ export function useRoofAllocationSetting(id) { }) } + /** 현재 선택된 라인인 경우 라인 두께 2로 설정 */ if (editingLines.includes(line)) { line.set({ strokeWidth: 2, @@ -82,6 +93,8 @@ export function useRoofAllocationSetting(id) { } }) }) + + /** 현재 선택된 객체가 보조라인, 피라미드, 힙인 경우 두께 4로 설정 */ if (currentObject && currentObject.name && ['auxiliaryLine', 'ridge', 'hip'].includes(currentObject.name)) { currentObject.set({ strokeWidth: 4, @@ -91,20 +104,21 @@ export function useRoofAllocationSetting(id) { }, [currentObject]) useEffect(() => { - // canvas.getObjects().filter((obj) => obj.type === 'QLine') + /** 현재 선택된 객체가 보조라인, 피라미드, 힙인 경우 두께 4로 설정 */ const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) if (roofBases.length === 0) { swalFire({ text: '할당할 지붕이 없습니다.' }) closePopup(id) } - fetchBasicSettings(basicSetting.planNo, null) + /** 배치면 초기설정 조회 */ + fetchBasicSettings(basicSetting.planNo) }, []) /** - * 지붕면 할당 조회 및 초기화 + * 배치면 초기설정 조회 */ - const fetchBasicSettings = async (planNo, openPoint) => { + const fetchBasicSettings = async (planNo) => { try { await get({ url: `/api/canvas-management/canvas-basic-settings/by-object/${correntObjectNo}/${planNo}`, @@ -169,7 +183,6 @@ export function useRoofAllocationSetting(id) { }) } - // setCurrentRoofList(selectRoofs) setBasicSetting({ ...basicSetting, planNo: res[0].planNo, @@ -178,6 +191,7 @@ export function useRoofAllocationSetting(id) { roofsData: roofsArray, selectedRoofMaterial: selectRoofs.find((roof) => roof.selected), }) + setBasicInfo({ planNo: '' + res[0].planNo, roofSizeSet: '' + res[0].roofSizeSet, @@ -220,12 +234,17 @@ export function useRoofAllocationSetting(id) { //Recoil 설정 //setCanvasSetting({ ...basicSetting }) - fetchBasicSettings(basicSetting.planNo, null) + + /** 배치면 초기설정 조회 */ + fetchBasicSettings(basicSetting.planNo) } catch (error) { swalFire({ text: error.message, icon: 'error' }) } } + /** + * 지붕재 추가 + */ const onAddRoofMaterial = () => { if (currentRoofList.length >= 4) { swalFire({ type: 'alert', icon: 'error', text: getMessage('지붕재는 4개까지 선택 가능합니다.') }) @@ -243,6 +262,9 @@ export function useRoofAllocationSetting(id) { ]) } + /** + * 지붕재 삭제 + */ const onDeleteRoofMaterial = (idx) => { const isSelected = currentRoofList[idx].selected const newRoofList = JSON.parse(JSON.stringify(currentRoofList)).filter((_, index) => index !== idx) @@ -292,6 +314,9 @@ export function useRoofAllocationSetting(id) { closeAll() } + /** + * 지붕면 할당 + */ const handleAlloc = () => { if (!checkInnerLines()) { apply() @@ -304,6 +329,9 @@ export function useRoofAllocationSetting(id) { } } + /** + * 실측값 없는 경우 체크 + */ const checkInnerLines = () => { const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) // roofPolygon.innerLines let result = false @@ -327,6 +355,9 @@ export function useRoofAllocationSetting(id) { return result } + /** + * 지붕면 할당 + */ const apply = () => { const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF && !obj.roofMaterial) const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL) @@ -340,6 +371,8 @@ export function useRoofAllocationSetting(id) { } catch (e) { return } + + /** 라인 삭제 */ roofBase.innerLines.forEach((line) => { canvas.remove(line) }) @@ -347,10 +380,12 @@ export function useRoofAllocationSetting(id) { canvas.remove(roofBase) }) + /** 벽면 삭제 */ wallLines.forEach((wallLine) => { canvas.remove(wallLine) }) + /** 데이터 설정 */ const newRoofList = currentRoofList.map((roof, idx) => { return { ...roof, index: idx, ...basicInfo } }) @@ -370,6 +405,8 @@ export function useRoofAllocationSetting(id) { roof.set({ isFixed: true, }) + + /** 모양 패턴 설정 */ setSurfaceShapePattern( roof, roofDisplay.column, @@ -379,6 +416,7 @@ export function useRoofAllocationSetting(id) { drawDirectionArrow(roof) }) + /** 외곽선 삭제 */ const removeTargets = canvas.getObjects().filter((obj) => obj.name === 'outerLinePoint' || obj.name === 'outerLine') removeTargets.forEach((obj) => { canvas.remove(obj) @@ -387,9 +425,13 @@ export function useRoofAllocationSetting(id) { closeAll() setSelectedMenu('surface') + /** 모듈 선택 데이터 초기화 */ modifyModuleSelectionData() } + /** + * 라인 사이즈 설정 + */ const setLineSize = (id, size) => { const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) roofBases.forEach((roof) => { @@ -452,6 +494,9 @@ export function useRoofAllocationSetting(id) { setCurrentRoofList(newRoofList) } + /** + * 레이아웃 변경 + */ const handleChangeLayout = (layoutValue, index) => { const newRoofList = currentRoofList.map((roof, idx) => { if (idx === index) { @@ -463,6 +508,9 @@ export function useRoofAllocationSetting(id) { setCurrentRoofList(newRoofList) } + /** + * 치수 입력방법(복시도입력/실측값입력/육지붕) + */ const handleChangeInput = (e, type = '', index) => { const value = e.target.value const newRoofList = currentRoofList.map((roof, idx) => { @@ -475,6 +523,9 @@ export function useRoofAllocationSetting(id) { setCurrentRoofList(newRoofList) } + /** + * 피치 변경 + */ const handleChangePitch = (e, index) => { let value = e.target.value @@ -504,6 +555,9 @@ export function useRoofAllocationSetting(id) { } } + /** + * 모듈 선택 데이터 트리거 + */ const { trigger: moduleSelectedDataTrigger } = useCanvasPopupStatusController(2) return { diff --git a/src/store/settingAtom.js b/src/store/settingAtom.js index 0addc5c8..012e5bdc 100644 --- a/src/store/settingAtom.js +++ b/src/store/settingAtom.js @@ -1,8 +1,12 @@ import { atom, selector } from 'recoil' +/** + * 디스플레이 설정 + */ export const settingModalFirstOptionsState = atom({ key: 'settingModalFirstOptions', default: { + /** 디스플레이 설정 */ option1: [ { id: 1, column: 'allocDisplay', name: 'modal.canvas.setting.first.option.alloc', selected: true }, { id: 2, column: 'outlineDisplay', name: 'modal.canvas.setting.first.option.outline', selected: true }, @@ -15,6 +19,7 @@ export const settingModalFirstOptionsState = atom({ { 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: true }, ], + /** 치수 표시 */ dimensionDisplay: [ { id: 1, @@ -25,6 +30,7 @@ export const settingModalFirstOptionsState = atom({ { 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 }, ], + /** 화면 표시 */ option2: [ { id: 1, column: 'onlyBorder', name: 'modal.canvas.setting.first.option.border', selected: true }, { id: 2, column: 'lineHatch', name: 'modal.canvas.setting.first.option.line', selected: false }, @@ -34,15 +40,20 @@ export const settingModalFirstOptionsState = atom({ dangerouslyAllowMutability: true, }) +/** + * 디스플레이 설정 - 문자 표시 + */ export const settingModalSecondOptionsState = atom({ key: 'settingModalSecondOptions', default: { + /** 문자 표시 */ option3: [ { id: 1, name: 'modal.canvas.setting.font.plan.edit.word' }, { id: 2, name: 'modal.canvas.setting.font.plan.edit.flow' }, { id: 3, name: 'modal.canvas.setting.font.plan.edit.dimension' }, { id: 4, name: 'modal.canvas.setting.font.plan.edit.circuit.num' }, ], + /** 흡수범위 */ option4: [ { id: 1, @@ -77,6 +88,9 @@ export const settingModalSecondOptionsState = atom({ dangerouslyAllowMutability: true, }) +/** + * 디스플레이 설정 - 그리드 표시 + */ export const settingModalGridOptionsState = atom({ key: 'settingModalGridOptions', default: [ @@ -88,7 +102,9 @@ export const settingModalGridOptionsState = atom({ dangerouslyAllowMutability: true, }) -// 디스플레이 설정 - 할당 표시 +/** + * 디스플레이 설정 - 할당 표시 + */ export const allocDisplaySelector = selector({ key: 'allocDisplaySelector', get: ({ get }) => { @@ -97,7 +113,9 @@ export const allocDisplaySelector = selector({ }, }) -// 디스플레이 설정 - 외벽선 표시 +/** + * 디스플레이 설정 - 외벽선 표시 + */ export const outlineDisplaySelector = selector({ key: 'outlineDisplaySelector', get: ({ get }) => { @@ -106,7 +124,9 @@ export const outlineDisplaySelector = selector({ }, }) -// 디스플레이 설정 - 그리드 표시 +/** + * 디스플레이 설정 - 그리드 표시 + */ export const gridDisplaySelector = selector({ key: 'gridDisplaySelector', get: ({ get }) => { @@ -115,7 +135,9 @@ export const gridDisplaySelector = selector({ }, }) -// 디스플레이 설정 - 지붕선 표시 +/** + * 디스플레이 설정 - 지붕선 표시 + */ export const roofLineDisplaySelector = selector({ key: 'lineDisplaySelector', get: ({ get }) => { @@ -124,7 +146,9 @@ export const roofLineDisplaySelector = selector({ }, }) -// 디스플레이 설정 - 문자 표시 +/** + * 디스플레이 설정 - 문자 표시 + */ export const wordDisplaySelector = selector({ key: 'wordDisplaySelector', get: ({ get }) => { @@ -133,7 +157,9 @@ export const wordDisplaySelector = selector({ }, }) -// 디스플레이 설정 - 회로번호 표시 +/** + * 디스플레이 설정 - 회로번호 표시 + */ export const circuitNumDisplaySelector = selector({ key: 'circuitNumDisplaySelector', get: ({ get }) => { @@ -142,7 +168,9 @@ export const circuitNumDisplaySelector = selector({ }, }) -// 디스플레이 설정 - 흐름 방향 표시 +/** + * 디스플레이 설정 - 흐름 방향 표시 + */ export const flowDisplaySelector = selector({ key: 'flowDisplaySelector', get: ({ get }) => { @@ -151,7 +179,9 @@ export const flowDisplaySelector = selector({ }, }) -// 디스플레이 설정 - 가대 표시 +/** + * 디스플레이 설정 - 가대 표시 + */ export const trestleDisplaySelector = selector({ key: 'trestleDisplaySelector', get: ({ get }) => { @@ -160,7 +190,9 @@ export const trestleDisplaySelector = selector({ }, }) -// 디스플레이 설정 - 이미지 표시 +/** + * 디스플레이 설정 - 이미지 표시 + */ export const imageDisplaySelector = selector({ key: 'imageDisplaySelector', get: ({ get }) => { @@ -169,7 +201,9 @@ export const imageDisplaySelector = selector({ }, }) -// 디스플레이 설정 - 집계표 표시 +/** + * 디스플레이 설정 - 집계표 표시 + */ export const totalDisplaySelector = selector({ key: 'totalDisplaySelector', get: ({ get }) => { @@ -178,7 +212,9 @@ export const totalDisplaySelector = selector({ }, }) -// 디스플레이 설정 - 치수 표시 +/** + * 디스플레이 설정 - 치수 표시 + */ export const corridorDimensionSelector = selector({ key: 'corridorDimensionSelector', get: ({ get }) => { @@ -188,7 +224,9 @@ export const corridorDimensionSelector = selector({ dangerouslyAllowMutability: true, }) -// 디스플레이 설정 - 화면 표시 +/** + * 디스플레이 설정 - 화면 표시 + */ export const roofDisplaySelector = selector({ key: 'roofDisplaySelector', get: ({ get }) => { @@ -198,29 +236,39 @@ export const roofDisplaySelector = selector({ dangerouslyAllowMutability: true, }) +/** + * basicSetting 설정 + */ export const basicSettingState = atom({ key: 'basicSettingState', default: { - roofSizeSet: 1, - roofAngleSet: 'slope', - selectedRoofMaterial: {}, // 선택된 지붕재 - roofs: [], // 지붕면 할당에서 추가된 지붕재 목록 + roofSizeSet: 1 /** 지붕크기 */, + roofAngleSet: 'slope' /** 지붕각도 */, + selectedRoofMaterial: {} /** 선택된 지붕재 */, + roofs: [] /** 지붕면 할당에서 추가된 지붕재 목록 */, }, dangerouslyAllowMutability: true, }) +/** + * 지붕면 할당에서 추가된 지붕재 목록 + */ export const addedRoofsState = atom({ key: 'addedRoofsState', default: [], }) -// db에 등록된 지붕재 목록 +/** + * db에 등록된 지붕재 목록 + */ export const roofMaterialsAtom = atom({ key: 'roofMaterialState', default: [], }) -//현재 선택된 지붕재 +/** + * 현재 선택된 지붕재 + */ export const selectedRoofMaterialSelector = selector({ key: 'selectedRoofMaterialSelector', get: ({ get }) => { @@ -228,7 +276,9 @@ export const selectedRoofMaterialSelector = selector({ }, }) -// QSelectBox에서 사용할 지붕재 목록 +/** + * QSelectBox에서 사용할 지붕재 목록 + */ export const roofMaterialsSelector = selector({ key: 'roofMaterialsSelector', get: ({ get }) => { @@ -245,6 +295,9 @@ export const correntObjectNoState = atom({ default: '', }) +/** + * 지붕재 목록 조회 여부 + */ export const fetchRoofMaterialsState = atom({ key: 'fetchRoofMaterialsState', default: false, From ae5b129bcd9d056a581e37dc78b099edc23afb61 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Tue, 25 Feb 2025 15:11:03 +0900 Subject: [PATCH 146/352] =?UTF-8?q?mouseLine=20=EB=B2=94=EC=9C=84=20?= =?UTF-8?q?=ED=99=95=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useEvent.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hooks/useEvent.js b/src/hooks/useEvent.js index cd2775a9..d3d270f6 100644 --- a/src/hooks/useEvent.js +++ b/src/hooks/useEvent.js @@ -199,7 +199,7 @@ export function useEvent() { } } catch (e) {} - const horizontalLine = new fabric.Line([-1 * canvas.width, arrivalPoint.y, 2 * canvas.width, arrivalPoint.y], { + const horizontalLine = new fabric.Line([-4 * canvas.width, arrivalPoint.y, 4 * canvas.width, arrivalPoint.y], { stroke: 'red', strokeWidth: 1, selectable: false, @@ -207,7 +207,7 @@ export function useEvent() { }) // 세로선 - const verticalLine = new fabric.Line([arrivalPoint.x, -1 * canvas.height, arrivalPoint.x, 2 * canvas.height], { + const verticalLine = new fabric.Line([arrivalPoint.x, -4 * canvas.height, arrivalPoint.x, 4 * canvas.height], { stroke: 'red', strokeWidth: 1, selectable: false, From 353cc67fe8049b73531390de8fe2db2fb5ccd162 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Tue, 25 Feb 2025 16:09:29 +0900 Subject: [PATCH 147/352] =?UTF-8?q?fetchSetting=20=EC=A0=84=20initEvent=20?= =?UTF-8?q?=ED=98=B8=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/option/useCanvasSetting.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js index ab72fbc2..cf61ac2b 100644 --- a/src/hooks/option/useCanvasSetting.js +++ b/src/hooks/option/useCanvasSetting.js @@ -39,6 +39,7 @@ import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedM import { useCommonCode } from '@/hooks/common/useCommonCode' import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController' import { v4 as uuidv4 } from 'uuid' +import { useEvent } from '@/hooks/useEvent' const defaultDotLineGridSetting = { INTERVAL: { @@ -89,6 +90,8 @@ export function useCanvasSetting(executeEffect = true) { const [color, setColor] = useColor(gridColor ?? '#FF0000') const { selectedMenu, setSelectedMenu } = useCanvasMenu() + const { initEvent } = useEvent() + const [settingsData, setSettingsData] = useState({ ...settingModalFirstOptions, ...settingModalSecondOptions, @@ -587,6 +590,7 @@ export function useCanvasSetting(executeEffect = true) { */ const fetchSettings = async () => { try { + initEvent() const res = await get({ url: `/api/canvas-management/canvas-settings/by-object/${correntObjectNo}` }) if (Object.keys(res).length > 0) { From e2f9e1cd067c2cbbf497e22884860b708bf973ef Mon Sep 17 00:00:00 2001 From: changkyu choi Date: Tue, 25 Feb 2025 16:46:21 +0900 Subject: [PATCH 148/352] =?UTF-8?q?=EB=88=84=EB=9D=BD=20=EC=86=8C=EC=8A=A4?= =?UTF-8?q?=20=EC=9B=90=EB=B3=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/roofcover/useRoofAllocationSetting.js | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js index 5fb72a1f..93f51514 100644 --- a/src/hooks/roofcover/useRoofAllocationSetting.js +++ b/src/hooks/roofcover/useRoofAllocationSetting.js @@ -61,18 +61,10 @@ export function useRoofAllocationSetting(id) { }, []) useEffect(() => { + /** 지붕면 조회 */ const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) /** roofPolygon.innerLines */ roofBases.forEach((roof) => { - /** 현재 선택된 라인인 경우 라인 두께 2로 설정 */ - if (editingLines.includes(line)) { - line.set({ - strokeWidth: 2, - stroke: 'black', - selectable: true, - }) - } - roof.innerLines.forEach((line) => { /** 실측값이 없는 경우 라인 두께 4로 설정 */ if (!line.attributes.actualSize || line.attributes?.actualSize === 0) { From c4bcc3033fed0e63fb18c22ca054cfa7dee9291f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Tue, 25 Feb 2025 16:56:17 +0900 Subject: [PATCH 149/352] =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EC=9E=88=EC=9D=84?= =?UTF-8?q?=EB=95=8C=20'=EB=B0=B0=EC=B9=98=EB=A9=B4=20=EC=B4=88=EA=B8=B0?= =?UTF-8?q?=EC=84=A4=EC=A0=95',=20'=EC=A7=80=EB=B6=95=EB=8D=AE=EA=B0=9C'?= =?UTF-8?q?=20=EC=A0=91=EA=B7=BC=20=EC=A0=9C=ED=95=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 84 +++++++++++------------- 1 file changed, 37 insertions(+), 47 deletions(-) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 54a83677..e94c1ff2 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -183,43 +183,38 @@ export default function CanvasMenu(props) { await reloadCanvasStatus(objectNo, pid) break case 'surface': - if (['module', 'estimate', 'simulation'].some((menu) => menu === selectedMenu)) { - const modules = canvas.getObjects().filter((module) => module.name === POLYGON_TYPE.MODULE) + const modules = canvas.getObjects().filter((module) => module.name === POLYGON_TYPE.MODULE) + if (modules.length > 0) { + swalFire({ + text: getMessage('module.delete.confirm'), + type: 'confirm', + confirmFn: () => { + //해당 메뉴 이동시 배치면 삭제 + initRoofs() - if (modules.length > 0) { - swalFire({ - text: getMessage('module.delete.confirm'), - type: 'confirm', - confirmFn: () => { - //해당 메뉴 이동시 배치면 삭제 - initRoofs() + const moduleSurfacesArray = canvas + .getObjects() + .filter( + (obj) => + obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE || obj.name === POLYGON_TYPE.MODULE || obj.name === POLYGON_TYPE.OBJECT_SURFACE, + ) - const moduleSurfacesArray = canvas - .getObjects() - .filter( - (obj) => - obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE || obj.name === POLYGON_TYPE.MODULE || obj.name === POLYGON_TYPE.OBJECT_SURFACE, - ) - - if (moduleSurfacesArray.length > 0) { - // 모듈면 있을 경우 지붕면 할당 다시해야함 - moduleSurfacesArray.forEach((moduleSurface) => { - canvas.remove(moduleSurface) - }) - canvas.renderAll() - onClickNav(menu) - } - }, - denyFn: () => { - return - }, - }) - return - } else { - } - } else { - setSelectedMenu(menu.type) + if (moduleSurfacesArray.length > 0) { + // 모듈면 있을 경우 지붕면 할당 다시해야함 + moduleSurfacesArray.forEach((moduleSurface) => { + canvas.remove(moduleSurface) + }) + canvas.renderAll() + onClickNav(menu) + } + }, + denyFn: () => { + return + }, + }) + return } + setSelectedMenu(menu.type) await reloadCanvasStatus(objectNo, pid) break case 'module': @@ -311,18 +306,6 @@ export default function CanvasMenu(props) { if (selectedMenu === 'placement') { onClickPlacementInitialMenu() } - if (selectedMenu === 'surface') { - const moduleSurfacesArray = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) - if (moduleSurfacesArray.length > 0) { - initRoofs() - moduleSurfacesArray.forEach((moduleSurface) => { - canvas.remove(...moduleSurface.modules) - canvas.remove(moduleSurface) - moduleSurface.modules = [] - }) - canvas.renderAll() - } - } }, [selectedMenu]) // 저장버튼(btn08) 클릭 시 호출되는 함수 @@ -425,10 +408,16 @@ export default function CanvasMenu(props) { const checkMenuState = (menu) => { return ( (['2', '3'].includes(canvasSetting?.roofSizeSet) && menu.type === 'outline') || - (selectedMenu === 'module' && ['drawing', 'placement'].includes(menu.type)) + (selectedMenu === 'module' && ['drawing', 'placement'].includes(menu.type)) || + (isExistModule() && ['placement', 'outline'].some((num) => num === menu.type)) ) } + const isExistModule = () => { + const modules = canvas?.getObjects().filter((module) => module.name === POLYGON_TYPE.MODULE) ?? [] + return modules.length > 0 + } + /** * 모듈, 회로 구성 이전 메뉴에서 메뉴 클릭으로 넘어올때 * 지붕면 할당이 끝난 지붕이 하나라도 있는지 체크 @@ -546,6 +535,7 @@ export default function CanvasMenu(props) { onClick={async () => { if (['2', '3'].includes(canvasSetting?.roofSizeSet) && menu.type === 'outline') return if (selectedMenu === 'module' && ['drawing', 'placement'].includes(menu.type)) return + if (isExistModule() && ['placement', 'outline'].some((num) => num === menu.type)) return await onClickNav(menu) }} > From 2e49c8cf56e8b7a4bb004f9b85ca5097e8825a72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Tue, 25 Feb 2025 17:49:45 +0900 Subject: [PATCH 150/352] =?UTF-8?q?=EB=B3=80=20=EC=86=8D=EC=84=B1=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PlacementSurfaceLineProperty.jsx | 3 +- .../surface/useRoofLinePropertySetting.js | 117 +++++++++++++----- 2 files changed, 90 insertions(+), 30 deletions(-) diff --git a/src/components/floor-plan/modal/placementShape/PlacementSurfaceLineProperty.jsx b/src/components/floor-plan/modal/placementShape/PlacementSurfaceLineProperty.jsx index cd20adf3..bc532242 100644 --- a/src/components/floor-plan/modal/placementShape/PlacementSurfaceLineProperty.jsx +++ b/src/components/floor-plan/modal/placementShape/PlacementSurfaceLineProperty.jsx @@ -10,7 +10,7 @@ export default function PlacementSurfaceLineProperty(props) { const { id, pos = { x: 50, y: 230 }, roof, setIsHidden } = props const { closePopup } = usePopup() // const { handleSetEaves, handleSetGable, handleRollback, handleFix, closeModal } = usePropertiesSetting(id) - const { roofLinesInit, handleSetRidge, handleSetEaves, handleSetGable, handleRollback, handleFix } = useRoofLinePropertySetting({ + const { roofLinesInit, handleSetRidge, handleSetEaves, handleSetGable, handleRollback, handleFix, handleClosed } = useRoofLinePropertySetting({ id, roof, setIsHidden, @@ -33,6 +33,7 @@ export default function PlacementSurfaceLineProperty(props) { } closePopup(id) + handleClosed() if (setIsHidden) { setIsHidden(false) diff --git a/src/hooks/surface/useRoofLinePropertySetting.js b/src/hooks/surface/useRoofLinePropertySetting.js index d6615ddf..97097135 100644 --- a/src/hooks/surface/useRoofLinePropertySetting.js +++ b/src/hooks/surface/useRoofLinePropertySetting.js @@ -25,16 +25,20 @@ export function useRoofLinePropertySetting(props) { const { getMessage } = useMessage() useEffect(() => { - if (currentObject && currentObject.name === 'roofLine') { - roof.lines.forEach((line) => { - const lineType = line.attributes?.type - if (!lineType) { - line.set({ - stroke: '#000000', - strokeWidth: 4, - }) - } - }) + if (currentObject && currentObject.name === 'cloneRoofLine') { + // roof.lines.forEach((line) => { + canvas + .getObjects() + .filter((obj) => obj.name === 'cloneRoofLine') + .forEach((line) => { + const lineType = line.attributes?.type + if (!lineType) { + line.set({ + stroke: '#000000', + strokeWidth: 4, + }) + } + }) currentObject.set({ stroke: LINE_COLOR.ACTIVE, strokeWidth: 4, @@ -44,15 +48,31 @@ export function useRoofLinePropertySetting(props) { }, [currentObject]) const roofLinesInit = () => { + console.log('🚀 ~ roofLinesInit ~ roof:', roof) roof.lines.forEach((line) => { - canvas.add(line) - line.set({ - stroke: LINE_COLOR.DEFAULT, - strokeWidth: 4, - visible: true, - name: 'roofLine', + line.clone((cloned) => { + cloned.set({ + ...line, + stroke: line.attributes?.type ? LINE_COLOR[line.attributes.type.toUpperCase()] : LINE_COLOR.DEFAULT, + strokeWidth: 4, + visible: true, + name: 'cloneRoofLine', + selectable: true, + originLine: line.id, + }) + line.set({ + visible: false, + }) + canvas.add(cloned) + cloned.bringToFront() }) - line.bringToFront() + // line.set({ + // stroke: line.attributes?.type ? LINE_COLOR[line.attributes.type.toUpperCase()] : LINE_COLOR.DEFAULT, + // strokeWidth: 4, + // visible: true, + // name: 'roofLine', + // }) + // line.bringToFront() }) canvas.renderAll() } @@ -121,22 +141,43 @@ export function useRoofLinePropertySetting(props) { const handleFix = () => { // const roof = canvas.getObjects().find((obj) => currentObject.parentId === obj.id) - const notSettingLines = roof.lines.filter( - (line) => - !line.attributes.type || ![LINE_TYPE.WALLLINE.EAVES, LINE_TYPE.WALLLINE.GABLE, LINE_TYPE.SUBLINE.RIDGE].includes(line.attributes.type), - ) + // const notSettingLines = roof.lines.filter( + console.log(canvas.getObjects().filter((obj) => obj.name === 'cloneRoofLine')) + const notSettingLines = canvas + .getObjects() + .filter((obj) => obj.name === 'cloneRoofLine') + .filter( + (line) => + !line.attributes.type || ![LINE_TYPE.WALLLINE.EAVES, LINE_TYPE.WALLLINE.GABLE, LINE_TYPE.SUBLINE.RIDGE].includes(line.attributes.type), + ) if (notSettingLines.length > 0) { swalFire({ text: getMessage('modal.canvas.setting.roofline.properties.setting.not.setting'), type: 'alert', icon: 'warning' }) return } - roof.lines.forEach((line) => { - line.set({ - stroke: LINE_COLOR.DEFAULT, - strokeWidth: 4, - visible: false, + canvas + .getObjects() + .filter((obj) => obj.name === 'cloneRoofLine') + .forEach((line) => { + const originLine = roof.lines.find((obj) => obj.id === line.originLine) + + originLine.set({ + attributes: { + ...originLine.attributes, + type: line.attributes.type, + }, + visible: true, + }) + canvas.remove(line) }) - }) + + // roof.lines.forEach((line) => { + // line.set({ + // stroke: LINE_COLOR.DEFAULT, + // strokeWidth: 4, + // visible: false, + // }) + // }) canvas.renderAll() closePopup(id) @@ -145,12 +186,15 @@ export function useRoofLinePropertySetting(props) { const nextLineFocus = (selectedLine) => { // const roof = canvas.getObjects().find((obj) => currentObject.parentId === obj.id) - const lines = roof?.lines + // const lines = roof?.lines + const lines = canvas.getObjects().filter((obj) => obj.name === 'cloneRoofLine') + console.log('🚀 ~ nextLineFocus ~ lines:', lines) + if (!lines) return const index = lines.findIndex((line) => line === selectedLine) const nextLine = lines[index + 1] || lines[0] - if (!nextLine.attributes?.type) { + if (nextLine.attributes?.type === 'default') { canvas.setActiveObject(nextLine) } else { //activeObject 해제 @@ -158,6 +202,20 @@ export function useRoofLinePropertySetting(props) { } } + const handleClosed = () => { + canvas + .getObjects() + .filter((obj) => obj.name === 'cloneRoofLine') + .forEach((line) => { + roof.lines + .find((obj) => obj.id === line.originLine) + .set({ + visible: true, + }) + canvas.remove(line) + }) + } + return { roofLinesInit, handleSetEaves, @@ -165,5 +223,6 @@ export function useRoofLinePropertySetting(props) { handleSetRidge, handleRollback, handleFix, + handleClosed, } } From 33da1da7a441a129c493303b4b519f7a4fe2a20b Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 25 Feb 2025 17:51:04 +0900 Subject: [PATCH 151/352] =?UTF-8?q?Home=20=EC=86=8C=EC=8A=A4=EC=A0=95?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/main/MainContents.jsx | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/components/main/MainContents.jsx b/src/components/main/MainContents.jsx index 2985484e..0d9a315f 100644 --- a/src/components/main/MainContents.jsx +++ b/src/components/main/MainContents.jsx @@ -12,13 +12,10 @@ import { globalLocaleStore } from '@/store/localeAtom' import { queryStringFormatter } from '@/util/common-utils' import { useMainContentsController } from '@/hooks/main/useMainContentsController' import { QcastContext } from '@/app/QcastProvider' -import { useSwal } from '@/hooks/useSwal' import { handleFileDown } from '@/util/board-utils' export default function MainContents({ setFaqOpen, setFaqModalNoticeNo }) { - const { swalFire } = useSwal() - const { getMessage } = useMessage() const router = useRouter() const globalLocaleState = useRecoilValue(globalLocaleStore) @@ -33,7 +30,7 @@ export default function MainContents({ setFaqOpen, setFaqModalNoticeNo }) { const { fetchObjectList, initObjectList } = useMainContentsController() //첨부파일 - const [boardList, setBoardList] = useState([]) + const [fileList, setFileList] = useState([]) useEffect(() => { fetchObjectList() fetchNoticeList() @@ -62,9 +59,7 @@ export default function MainContents({ setFaqOpen, setFaqModalNoticeNo }) { if (resultData) { if (resultData.result.code === 200) { - setBoardList(resultData.data) - } else { - alert(resultData.result.message) + setFileList(resultData.data) } } } @@ -205,11 +200,11 @@ export default function MainContents({ setFaqOpen, setFaqModalNoticeNo }) { )} - {boardList.length > 0 ? ( + {fileList.length > 0 ? (
- {boardList?.map((board) => ( - ))}
From e4beabcbad53216f8bb03d90ac848fc307c358ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Tue, 25 Feb 2025 17:56:34 +0900 Subject: [PATCH 152/352] =?UTF-8?q?=ED=9A=8C=EB=A1=9C=20=EB=B2=88=ED=98=B8?= =?UTF-8?q?=20=EC=B4=88=EA=B8=B0=ED=99=94=EC=8B=9C=20=EC=B5=9C=EC=86=8C=20?= =?UTF-8?q?=ED=9A=8C=EB=A1=9C=20=EB=B2=88=ED=98=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../circuitTrestle/step/type/PassivityCircuitAllocation.jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx b/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx index 03045429..faf31eef 100644 --- a/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx @@ -292,7 +292,7 @@ export default function PassivityCircuitAllocation(props) { } const circuitNumbers = circuitModules.map((obj) => { const circuitNumber = obj.circuitNumber.replace(/[()]/g, '').split('-') - return parseInt(circuitNumber[0]) + return parseInt(circuitNumber[circuitNumber.length - 1]) }) const minCircuitNumber = Math.min(...circuitNumbers) canvas.remove(...circuitModules.map((module) => module.circuit)) @@ -526,8 +526,8 @@ export default function PassivityCircuitAllocation(props) { {header.map((header, i) => (
))} From 1412a141f286bd4c17c4b9f7d95b8ff7defa8920 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Tue, 25 Feb 2025 18:20:43 +0900 Subject: [PATCH 153/352] =?UTF-8?q?=EB=B3=B4=EC=A1=B0=EC=84=A0=20=EB=B3=B5?= =?UTF-8?q?=EC=82=AC=20/=20=EC=9D=B4=EB=8F=99=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/modal/auxiliary/AuxiliaryEdit.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/floor-plan/modal/auxiliary/AuxiliaryEdit.jsx b/src/components/floor-plan/modal/auxiliary/AuxiliaryEdit.jsx index 5a8cb3f3..c8e7b95a 100644 --- a/src/components/floor-plan/modal/auxiliary/AuxiliaryEdit.jsx +++ b/src/components/floor-plan/modal/auxiliary/AuxiliaryEdit.jsx @@ -26,12 +26,12 @@ export default function AuxiliaryEdit(props) { return } - if ((verticalSize && +verticalSize === 0) || !arrow1) { + if (verticalSize && +verticalSize !== 0 && !arrow1) { swalFire({ title: getMessage('length.direction.is.required'), type: 'alert' }) return } - if ((horizonSize && +horizonSize === 0) || !arrow2) { + if (horizonSize && +horizonSize !== 0 && !arrow2) { swalFire({ title: getMessage('length.direction.is.required'), type: 'alert' }) return } From c453ede3db751337bd191187c2b8fca60b2c73da Mon Sep 17 00:00:00 2001 From: yjnoh Date: Wed, 26 Feb 2025 09:32:28 +0900 Subject: [PATCH 154/352] =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EB=94=94=EB=B2=84?= =?UTF-8?q?=EA=B9=85=20=EB=9D=BC=EC=9D=B8=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index d0b0bf36..930f75d7 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -1142,9 +1142,9 @@ export function useModuleBasicSetting(tabNum) { installedLastHeightCoord = moduleY + height + heightMargin } else { //디버깅용 - tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) - canvas?.add(tempModule) - canvas.renderAll() + // tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) + // canvas?.add(tempModule) + // canvas.renderAll() } } if (isInstall) { @@ -1281,9 +1281,9 @@ export function useModuleBasicSetting(tabNum) { installedLastHeightCoord = moduleY + width + widthMargin } else { //디버깅용 - tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) - canvas?.add(tempModule) - canvas.renderAll() + // tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) + // canvas?.add(tempModule) + // canvas.renderAll() } } From b227a7deeafb613d664bb138de7e9abb126c9a39 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Wed, 26 Feb 2025 11:12:36 +0900 Subject: [PATCH 155/352] =?UTF-8?q?=F0=9F=91=80fix:=20=ED=94=8C=EB=9E=9C?= =?UTF-8?q?=20=EB=B3=B5=EC=82=AC=20=EC=8B=9C=20=EB=AA=A8=EB=93=88=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/useCanvasPopupStatusController.js | 2 +- src/hooks/option/useCanvasSetting.js | 2 +- src/hooks/usePlan.js | 138 ++++++++++++------ 3 files changed, 96 insertions(+), 46 deletions(-) diff --git a/src/hooks/common/useCanvasPopupStatusController.js b/src/hooks/common/useCanvasPopupStatusController.js index 22de7b76..b0c0f6f8 100644 --- a/src/hooks/common/useCanvasPopupStatusController.js +++ b/src/hooks/common/useCanvasPopupStatusController.js @@ -85,5 +85,5 @@ export function useCanvasPopupStatusController(param = 1) { }, ) - return { handleModuleSelectionTotal, trigger } + return { getModuleSelection, handleModuleSelectionTotal, trigger } } diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js index cf61ac2b..6567838f 100644 --- a/src/hooks/option/useCanvasSetting.js +++ b/src/hooks/option/useCanvasSetting.js @@ -575,7 +575,7 @@ export function useCanvasSetting(executeEffect = true) { /** 모듈 선택 데이터 초기화 */ resetModuleSelectionData() - moduleSelectedDataTrigger({ common: {}, module: {}, roofConstructions: [] }) + // moduleSelectedDataTrigger({ common: {}, module: {}, roofConstructions: [] }) const isModuleExist = canvas.getObjects().some((obj) => obj.name === POLYGON_TYPE.MODULE) if (!isModuleExist) { resetSelectedModules() diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js index c422b7f5..befc05d8 100644 --- a/src/hooks/usePlan.js +++ b/src/hooks/usePlan.js @@ -9,13 +9,16 @@ import { canvasState, currentCanvasPlanState, plansState, canvasSettingState } f import { useAxios } from '@/hooks/useAxios' import { useMessage } from '@/hooks/useMessage' import { useSwal } from '@/hooks/useSwal' -import { SAVE_KEY } from '@/common/common' +import { POLYGON_TYPE, SAVE_KEY } from '@/common/common' import { removeImage } from '@/lib/fileAction' import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider' import { useEstimateController } from '@/hooks/floorPlan/estimate/useEstimateController' import { outerLinePointsState } from '@/store/outerLineAtom' import { placementShapeDrawingPointsState } from '@/store/placementShapeDrawingAtom' import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' +import { compasDegAtom } from '@/store/orientationAtom' +import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions' +import { useCanvasPopupStatusController } from './common/useCanvasPopupStatusController' /** * 플랜 처리 훅 @@ -38,7 +41,7 @@ export function usePlan(params = {}) { const { swalFire } = useSwal() const { getMessage } = useMessage() - const { get, promisePost, promisePut, promiseDel, promiseGet } = useAxios() + const { get, post, promisePost, promisePut, promiseDel, promiseGet } = useAxios() const { setEstimateContextState } = useEstimateController() @@ -48,6 +51,14 @@ export function usePlan(params = {}) { const { fetchBasicSettings, basicSettingCopySave } = useCanvasSetting() const [canvasSetting, setCanvasSetting] = useRecoilState(canvasSettingState) + /** + * 플랜 복사 시 모듈이 있을경우 모듈 데이터 복사하기 위한 처리 + */ + const { getModuleSelection } = useCanvasPopupStatusController() + const [compasDeg, setCompasDeg] = useRecoilState(compasDegAtom) + const [moduleSelectionDataStore, setModuleSelectionDataStore] = useRecoilState(moduleSelectionDataState) + const [selectedModules, setSelectedModules] = useRecoilState(selectedModuleState) + /** * 마우스 포인터의 가이드라인 제거 */ @@ -191,54 +202,93 @@ export function usePlan(params = {}) { objectNo: objectNo, copyFlg: '0', } - try { - const res = await promisePost({ url: '/api/object/add-plan', data: planData }) - let newPlan = { - id: res.data.canvasId, - objectNo: objectNo, - planNo: res.data.planNo, - userId: userId, - canvasStatus: '', - isCurrent: true, - bgImageName: null, - mapPositionAddress: null, - } - if (isInitPlan) { - /* 초기 플랜 생성인 경우 플랜 목록 초기화 */ - setCurrentCanvasPlan(newPlan) - setPlans([newPlan]) + const res = await promisePost({ url: '/api/object/add-plan', data: planData }) + let newPlan = { + id: res.data.canvasId, + objectNo: objectNo, + planNo: res.data.planNo, + userId: userId, + canvasStatus: '', + isCurrent: true, + bgImageName: null, + mapPositionAddress: null, + } - /* 플랜 추가 시 배치면초기설정 정보 조회 */ - fetchBasicSettings(newPlan.planNo, null) - } else { - if (isCopy) { - /* 복제 플랜 생성인 경우 현재 캔버스 데이터를 복제 */ - newPlan.canvasStatus = currentCanvasData() - newPlan.bgImageName = currentCanvasPlan?.bgImageName ?? null - newPlan.mapPositionAddress = currentCanvasPlan?.mapPositionAddress ?? null + if (isInitPlan) { + /* 초기 플랜 생성인 경우 플랜 목록 초기화 */ + setCurrentCanvasPlan(newPlan) + setPlans([newPlan]) - /* 복제 시 배치면 초기설정 복사 */ - basicSettingCopySave({ - ...canvasSetting, + /* 플랜 추가 시 배치면초기설정 정보 조회 */ + fetchBasicSettings(newPlan.planNo, null) + } else { + if (isCopy) { + /* 복제 플랜 생성인 경우 현재 캔버스 데이터를 복제 */ + newPlan.canvasStatus = currentCanvasData() + newPlan.bgImageName = currentCanvasPlan?.bgImageName ?? null + newPlan.mapPositionAddress = currentCanvasPlan?.mapPositionAddress ?? null + + /* 복제 시 배치면 초기설정 복사 */ + basicSettingCopySave({ + ...canvasSetting, + planNo: newPlan.planNo, + selectedRoofMaterial: { + ...canvasSetting.selectedRoofMaterial, planNo: newPlan.planNo, - selectedRoofMaterial: { - ...canvasSetting.selectedRoofMaterial, - planNo: newPlan.planNo, - }, - roofsData: canvasSetting.roofsData.map((roof) => ({ - ...roof, - planNo: newPlan.planNo, - })), - }) - } - setCurrentCanvasPlan(newPlan) - setPlans((plans) => [...plans.map((plan) => ({ ...plan, isCurrent: false })), newPlan]) + }, + roofsData: canvasSetting.roofsData.map((roof) => ({ + ...roof, + planNo: newPlan.planNo, + })), + }) - swalFire({ text: getMessage('plan.message.save') }) + /** + * 방위 데이터 복사 + */ + const sourceDegree = await getModuleSelection(1) + console.log('🚀 ~ sourceDegree:', sourceDegree) + const degreeData = { + objectNo, + planNo: parseInt(newPlan.planNo), + popupType: 1, + popupStatus: sourceDegree.popupStatus, + } + console.log('🚀 ~ postObjectPlan ~ degreeData:', degreeData) + await post({ url: `/api/v1/canvas-popup-status`, data: degreeData }) + /** 리코일 세팅 */ + setCompasDeg(sourceDegree.popupStatus) + + /** + * 모듈 선택 데이터 복사 + */ + const moduleSelectionData = await getModuleSelection(2) + console.log('🚀 ~ moduleSelectionData:', moduleSelectionData) + const moduleStatus = moduleSelectionData.popupStatus.replace(/"/g, '\"') + const moduleData = { + objectNo, + planNo: parseInt(newPlan.planNo), + popupType: 2, + popupStatus: moduleStatus, + } + console.log('🚀 ~ postObjectPlan ~ moduleData:', moduleData) + await post({ url: `/api/v1/canvas-popup-status`, data: moduleData }) + const copyData = JSON.parse(moduleStatus) + console.log('🚀 ~ postObjectPlan ~ copyData:', copyData) + + /** 리코일 세팅 */ + setModuleSelectionDataStore(copyData) + if (copyData.module) setSelectedModules(copyData.module) + const roofSurfaceList = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) + const modules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE) + roofSurfaceList.forEach((surface) => { + surface.modules = modules.filter((module) => module.surfaceId === surface.id) + }) } - } catch (error) { - swalFire({ text: error.response.data.message, icon: 'error' }) + setCurrentCanvasPlan(newPlan) + setPlans((plans) => [...plans.map((plan) => ({ ...plan, isCurrent: false })), newPlan]) + + swalFire({ text: getMessage('plan.message.save') }) } } From d908dea9bf0380eb7249c0de3fc8b7cc72126b05 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Wed, 26 Feb 2025 13:23:20 +0900 Subject: [PATCH 156/352] =?UTF-8?q?=EC=88=98=EB=8F=99=EC=84=A4=EC=B9=98=20?= =?UTF-8?q?=EC=9C=84=EC=B9=98=20=EB=B3=B4=EC=A0=95,=20=EB=AA=A8=EB=93=88?= =?UTF-8?q?=20=EC=9D=B4=EB=8F=99=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/BasicSetting.jsx | 5 + src/hooks/module/useModule.js | 10 +- src/hooks/module/useModuleBasicSetting.js | 101 ++++++++++++------ src/hooks/module/useModuleSelection.js | 17 ++- 4 files changed, 82 insertions(+), 51 deletions(-) diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index e7ead904..291ef086 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -115,6 +115,11 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { //팝업 닫기 버튼 이벤트 const handleClosePopup = (id) => { + if (tabNum == 3) { + if (isManualModuleSetup) { + setIsManualModuleSetup(false) + } + } setIsClosePopup({ close: true, id: id }) } diff --git a/src/hooks/module/useModule.js b/src/hooks/module/useModule.js index 0c884608..94b3bbc5 100644 --- a/src/hooks/module/useModule.js +++ b/src/hooks/module/useModule.js @@ -121,11 +121,9 @@ export function useModule() { module.setCoords() canvas.renderAll() - if (otherModules.length > 0) { - if (isOverlapOtherModules(module, otherModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) { - isWarning = true - module.set({ fill: 'red' }) - } + if (isOverlapOtherModules(module, otherModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) { + isWarning = true + module.set({ fill: 'red' }) } }) @@ -912,6 +910,8 @@ export function useModule() { } const isOverlapOtherModules = (module, otherModules) => { + if (otherModules.length === 0) return false + return otherModules.some( (otherModule) => turf.booleanOverlap(polygonToTurfPolygon(module, true), polygonToTurfPolygon(otherModule, true)) || diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index d0b0bf36..d901dcf1 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -61,6 +61,13 @@ export function useModuleBasicSetting(tabNum) { // canvas.selection = true // canvas.selectionFullyContained = true } + + return () => { + //수동 설치시 초기화 + removeMouseEvent('mouse:up') + removeMouseEvent('mouse:move') + canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'tempModule')) //움직일때 일단 지워가면서 움직임 + } }, []) // const { addTargetMouseEventListener, addCanvasMouseEventListener, initEvent } = useContext(EventContext) @@ -168,9 +175,10 @@ export function useModuleBasicSetting(tabNum) { case LINE_TYPE.WALLLINE.GABLE: return data.kerabaIntvl / 10 case LINE_TYPE.SUBLINE.RIDGE: + case LINE_TYPE.WALLLINE.SHED: return data.ridgeIntvl / 10 default: - return 60 / 10 + return 200 / 10 } } //선택 배치면 배열` @@ -426,7 +434,7 @@ export function useModuleBasicSetting(tabNum) { * trestle에서 영역을 가져와 mouse:move 이벤트로 해당 영역에 진입했을때 booleanPointInPolygon 로 진입여부를 확인 * 확인 후 셀을 이동시킴 */ - const manualModuleSetup = () => { + const manualModuleSetup = (placementRef) => { // console.log('isManualModuleSetup', isManualModuleSetup) const moduleSetupSurfaces = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) //모듈설치면를 가져옴 @@ -495,10 +503,22 @@ export function useModuleBasicSetting(tabNum) { : { width: tmpWidth, height: tmpHeight } const points = [ - { x: mousePoint.x - width / 2, y: mousePoint.y - height / 2 }, - { x: mousePoint.x + width / 2, y: mousePoint.y - height / 2 }, - { x: mousePoint.x + width / 2, y: mousePoint.y + height / 2 }, - { x: mousePoint.x - width / 2, y: mousePoint.y + height / 2 }, + { + x: Number(mousePoint.x.toFixed(1)) + Number((width / 2).toFixed(1)), + y: Number(mousePoint.y.toFixed(1)) - Number((height / 2).toFixed(1)), + }, + { + x: Number(mousePoint.x.toFixed(1)) + Number((width / 2).toFixed(1)), + y: Number(mousePoint.y.toFixed(1)) + Number((height / 2).toFixed(1)), + }, + { + x: Number(mousePoint.x.toFixed(1)) - Number((width / 2).toFixed(1)), + y: Number(mousePoint.y.toFixed(1)) - Number((height / 2).toFixed(1)), + }, + { + x: Number(mousePoint.x.toFixed(1)) - Number((width / 2).toFixed(1)), + y: Number(mousePoint.y.toFixed(1)) + Number((height / 2).toFixed(1)), + }, ] const turfPoints = coordToTurfPolygon(points) @@ -513,10 +533,10 @@ export function useModuleBasicSetting(tabNum) { fill: 'white', stroke: 'black', strokeWidth: 0.3, - width: width, - height: height, - left: mousePoint.x - width / 2, - top: mousePoint.y - height / 2, + width: Number(width.toFixed(1)), + height: Number(height.toFixed(1)), + left: Number(mousePoint.x.toFixed(1) - Number((width / 2).toFixed(1))), + top: Number(mousePoint.y.toFixed(1) - Number((height / 2).toFixed(1))), selectable: false, lockMovementX: true, lockMovementY: true, @@ -555,13 +575,13 @@ export function useModuleBasicSetting(tabNum) { const trestleBottom = trestleTop + moduleSetupSurfaces[i].height * moduleSetupSurfaces[i].scaleY const bigCenterY = (trestleTop + trestleTop + moduleSetupSurfaces[i].height) / 2 - // 작은 폴리곤의 경계 좌표 계산 - const smallLeft = tempModule.left - const smallTop = tempModule.top - const smallRight = smallLeft + tempModule.width * tempModule.scaleX - const smallBottom = smallTop + tempModule.height * tempModule.scaleY - const smallCenterX = smallLeft + (tempModule.width * tempModule.scaleX) / 2 - const smallCenterY = smallTop + (tempModule.height * tempModule.scaleX) / 2 + // 이동하는 모듈의 경계 좌표 + const smallLeft = Number(tempModule.left.toFixed(1)) + const smallTop = Number(tempModule.top.toFixed(1)) + const smallRight = smallLeft + Number(tempModule.width.toFixed(1)) + const smallBottom = smallTop + Number(tempModule.height.toFixed(1)) + const smallCenterX = smallLeft + Number((tempModule.width / 2).toFixed(1)) + const smallCenterY = smallTop + Number((tempModule.height / 2).toFixed(1)) /** * 미리 깔아놓은 셀이 있을때 셀에 흡착됨 @@ -570,10 +590,10 @@ export function useModuleBasicSetting(tabNum) { manualDrawModules.forEach((cell) => { const holdCellLeft = cell.left const holdCellTop = cell.top - const holdCellRight = holdCellLeft + cell.width * cell.scaleX - const holdCellBottom = holdCellTop + cell.height * cell.scaleY - const holdCellCenterX = holdCellLeft + (cell.width * cell.scaleX) / 2 - const holdCellCenterY = holdCellTop + (cell.height * cell.scaleY) / 2 + const holdCellRight = holdCellLeft + Number(cell.width.toFixed(1)) + const holdCellBottom = holdCellTop + Number(cell.height.toFixed(1)) + const holdCellCenterX = holdCellLeft + Number((cell.width / 2).toFixed(1)) + const holdCellCenterY = holdCellTop + Number((cell.height / 2).toFixed(1)) //설치된 셀에 좌측에 스냅 if (Math.abs(smallRight - holdCellLeft) < snapDistance) { @@ -596,7 +616,7 @@ export function useModuleBasicSetting(tabNum) { } //가운데 -> 가운데 if (Math.abs(smallCenterX - holdCellCenterX) < cellSnapDistance) { - tempModule.left = holdCellCenterX - width / 2 + tempModule.left = holdCellCenterX - Number((width / 2).toFixed(1)) } //왼쪽 -> 가운데 if (Math.abs(smallLeft - holdCellCenterX) < cellSnapDistance) { @@ -608,7 +628,7 @@ export function useModuleBasicSetting(tabNum) { } //세로 가운데 -> 가운데 if (Math.abs(smallCenterY - holdCellCenterY) < cellSnapDistance) { - tempModule.top = holdCellCenterY - height / 2 + tempModule.top = holdCellCenterY - Number((height / 2).toFixed(1)) } //위쪽 -> 가운데 if (Math.abs(smallTop - holdCellCenterY) < cellSnapDistance) { @@ -691,13 +711,13 @@ export function useModuleBasicSetting(tabNum) { if (!inside) return if (tempModule) { const rectPoints = [ - { x: tempModule.left, y: tempModule.top }, - { x: tempModule.left + tempModule.width * tempModule.scaleX, y: tempModule.top }, + { x: Number(tempModule.left.toFixed(1)), y: Number(tempModule.top.toFixed(1)) }, + { x: Number(tempModule.left.toFixed(1)) + Number(tempModule.width.toFixed(1)), y: Number(tempModule.top.toFixed(1)) }, { - x: tempModule.left + tempModule.width * tempModule.scaleX, - y: tempModule.top + tempModule.height * tempModule.scaleY, + x: Number(tempModule.left.toFixed(1)) + Number(tempModule.width.toFixed(1)), + y: Number(tempModule.top.toFixed(1)) + Number(tempModule.height.toFixed(1)), }, - { x: tempModule.left, y: tempModule.top + tempModule.height * tempModule.scaleY }, + { x: Number(tempModule.left.toFixed(1)), y: Number(tempModule.top.toFixed(1)) + Number(tempModule.height.toFixed(1)) }, ] tempModule.set({ points: rectPoints }) @@ -729,7 +749,16 @@ export function useModuleBasicSetting(tabNum) { // tempModule.setCoords() moduleOptions.surfaceId = trestlePolygon.id - let manualModule = new QPolygon(tempModule.points, { ...moduleOptions, moduleInfo: checkedModule[0] }) + // console.log('tempModule.points', tempModule.points) + + let manualModule = new QPolygon(tempModule.points, { + ...moduleOptions, + moduleInfo: checkedModule[0], + left: Number(tempModule.left.toFixed(1)), + top: Number(tempModule.top.toFixed(1)), + width: Number(tempModule.width.toFixed(1)), + height: Number(tempModule.height.toFixed(1)), + }) canvas?.add(manualModule) manualDrawModules.push(manualModule) setModuleStatisticsData() @@ -984,6 +1013,8 @@ export function useModuleBasicSetting(tabNum) { [moduleX + widthMargin + chidoriLength, moduleY - height - heightMargin], ] + // console.log('square', square) + let squarePolygon = turf.polygon([square]) let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1) let points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] })) @@ -1142,9 +1173,9 @@ export function useModuleBasicSetting(tabNum) { installedLastHeightCoord = moduleY + height + heightMargin } else { //디버깅용 - tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) - canvas?.add(tempModule) - canvas.renderAll() + // tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) + // canvas?.add(tempModule) + // canvas.renderAll() } } if (isInstall) { @@ -1281,9 +1312,9 @@ export function useModuleBasicSetting(tabNum) { installedLastHeightCoord = moduleY + width + widthMargin } else { //디버깅용 - tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) - canvas?.add(tempModule) - canvas.renderAll() + // tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 }) + // canvas?.add(tempModule) + // canvas.renderAll() } } diff --git a/src/hooks/module/useModuleSelection.js b/src/hooks/module/useModuleSelection.js index 23c201b0..8fa274a4 100644 --- a/src/hooks/module/useModuleSelection.js +++ b/src/hooks/module/useModuleSelection.js @@ -8,6 +8,7 @@ import { isObjectNotEmpty } from '@/util/common-utils' import { canvasState } from '@/store/canvasAtom' import { POLYGON_TYPE } from '@/common/common' import { moduleStatisticsState } from '@/store/circuitTrestleAtom' +import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting' export function useModuleSelection(props) { const canvas = useRecoilValue(canvasState) @@ -28,6 +29,8 @@ export function useModuleSelection(props) { const { findCommonCode } = useCommonCode() const resetStatisticsData = useResetRecoilState(moduleStatisticsState) + const { restoreModuleInstArea } = useModuleBasicSetting() + const bindInitData = () => { setInstallHeight(managementState?.installHeight) setStandardWindSpeed(managementState?.standardWindSpeedId) @@ -91,17 +94,9 @@ export function useModuleSelection(props) { getModuleData(roofsIds) - //해당 메뉴 이동시 배치면 삭제 - const moduleSurfacesArray = canvas - .getObjects() - .filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE || obj.name === POLYGON_TYPE.MODULE || obj.name === POLYGON_TYPE.OBJECT_SURFACE) - if (moduleSurfacesArray.length > 0) { - moduleSurfacesArray.forEach((moduleSurface) => { - canvas.remove(moduleSurface) - }) - canvas.renderAll() - resetStatisticsData() - } + //모듈설치면 초기화 + restoreModuleInstArea() + resetStatisticsData() }, []) const getModuleData = async (roofsIds) => { From a4ae33d66fbd65267a96f470c73b5b48c32e6997 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 26 Feb 2025 14:11:46 +0900 Subject: [PATCH 157/352] =?UTF-8?q?-=20=EA=B2=AC=EC=A0=81=EC=84=9C,=20?= =?UTF-8?q?=EC=8B=9C=EB=AE=AC=EB=A0=88=EC=9D=B4=EC=85=98=20=EB=A9=94?= =?UTF-8?q?=EB=89=B4=EC=97=90=EC=84=9C=EB=8A=94=20=EB=AA=A8=EB=AE=AC=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=EB=A9=94=EB=89=B4=20=EC=A0=9C=EC=99=B8?= =?UTF-8?q?=ED=95=9C=20=EB=A9=94=EB=89=B4=EB=A1=9C=20=EC=9D=B4=EB=8F=99=20?= =?UTF-8?q?=EB=B6=88=EA=B0=80=ED=95=98=EA=B2=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index e94c1ff2..9c2db6bd 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -409,7 +409,8 @@ export default function CanvasMenu(props) { return ( (['2', '3'].includes(canvasSetting?.roofSizeSet) && menu.type === 'outline') || (selectedMenu === 'module' && ['drawing', 'placement'].includes(menu.type)) || - (isExistModule() && ['placement', 'outline'].some((num) => num === menu.type)) + (isExistModule() && ['placement', 'outline'].some((num) => num === menu.type)) || + (['estimate', 'simulation'].includes(selectedMenu) && ['drawing', 'placement', 'outline', 'surface'].includes(menu.type)) ) } @@ -533,9 +534,7 @@ export default function CanvasMenu(props) { key={`canvas-menu-${menu.type}`} className={`canvas-menu-item ${selectedMenu === menu.type ? 'active' : ''}`} onClick={async () => { - if (['2', '3'].includes(canvasSetting?.roofSizeSet) && menu.type === 'outline') return - if (selectedMenu === 'module' && ['drawing', 'placement'].includes(menu.type)) return - if (isExistModule() && ['placement', 'outline'].some((num) => num === menu.type)) return + if (checkMenuState(menu)) return await onClickNav(menu) }} > From e03823b15320c06d988a2650d74a82edf011e636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 26 Feb 2025 14:11:57 +0900 Subject: [PATCH 158/352] =?UTF-8?q?-=20=EC=B9=98=EC=88=98=EC=84=A0=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dimensionLine/DimensionLineSetting.jsx | 98 +++++++++++++------ 1 file changed, 69 insertions(+), 29 deletions(-) diff --git a/src/components/floor-plan/modal/dimensionLine/DimensionLineSetting.jsx b/src/components/floor-plan/modal/dimensionLine/DimensionLineSetting.jsx index 9e2ce27b..81395b31 100644 --- a/src/components/floor-plan/modal/dimensionLine/DimensionLineSetting.jsx +++ b/src/components/floor-plan/modal/dimensionLine/DimensionLineSetting.jsx @@ -7,6 +7,9 @@ import { contextPopupPositionState } from '@/store/popupAtom' import QSelectBox from '@/components/common/select/QSelectBox' import { canvasState, pitchTextSelector } from '@/store/canvasAtom' import { defaultSlope } from '@/store/commonAtom' +import { re } from 'mathjs' +import { basicSettingState } from '@/store/settingAtom' +import { getChonByDegree } from '@/util/canvas-util' export default function DimensionLineSetting(props) { const contextPopupPosition = useRecoilValue(contextPopupPositionState) @@ -18,7 +21,11 @@ export default function DimensionLineSetting(props) { const SelectOption01 = defaultSlope const [basicLength, setBasicLength] = useState(0) const [slopeAble, setSlopeAble] = useState(false) + const basicSetting = useRecoilValue(basicSettingState) const changeSlopeRef = useRef() + const [options, setOptions] = useState([]) + const [selectedSlope1, setSelectedSlope1] = useState(null) + const [selectedSlope2, setSelectedSlope2] = useState(null) let slopeInput1, slopeInput2 @@ -26,10 +33,30 @@ export default function DimensionLineSetting(props) { if (canvas) { const dimensionObject = canvas.getActiveObject() const id = dimensionObject.groupId - const textObj = dimensionObject._objects.filter((obj) => obj.name === 'dimensionLineText' && obj.id === id)[0] + const textObj = dimensionObject._objects.filter((obj) => obj.name === 'dimensionLineText' && obj.group.groupId === id)[0] + if (!textObj) return setBasicLength(parseInt(textObj.text)) } + if (basicSetting.roofAngleSet === 'slope') { + setOptions( + Array.from({ length: 21 }).map((_, index) => { + return { + name: index * 0.5, + value: index * 0.5, + } + }), + ) + } else { + setOptions( + Array.from({ length: 7 }).map((_, index) => { + return { + name: index * 5, + value: index * 5, + } + }), + ) + } return () => { setBasicLength(0) } @@ -41,45 +68,40 @@ export default function DimensionLineSetting(props) { if (canvas) { const dimensionObject = canvas.getActiveObject() const id = dimensionObject.groupId - const textObj = dimensionObject._objects.filter((obj) => obj.name === 'dimensionLineText' && obj.id === id)[0] + const textObj = dimensionObject._objects.filter((obj) => obj.name === 'dimensionLineText' && obj.group.groupId === id)[0] let resultText = changeLength.value > 0 ? changeLength.value : '0' if (slopeAble) { - if (slopeInput1) { - resultText = calculateLength(basicLength, slopeInput1.angleValue).toFixed(0) - - if (slopeInput2) { - const length = calculateLength(basicLength, slopeInput1.angleValue, slopeInput2.angleValue) - resultText = length.toFixed(0) - } - } + resultText = !selectedSlope2 + ? calculateLength(basicLength, selectedSlope1.value).toFixed(0) + : calculateLength(basicLength, selectedSlope1.value, selectedSlope2.value).toFixed(0) } textObj.set({ text: String(resultText), }) + setBasicLength(resultText) canvas.renderAll() } } - const handleSelectbox = (option, params) => { - const index = params.index - if (index === 1) slopeInput1 = option - if (index === 2) slopeInput2 = option - } - - function calculateLength(originalLength, angle) { - const angleInRadians = angle * (Math.PI / 180) - const result = Math.sqrt(Math.pow(originalLength * Math.tan(angleInRadians), 2) + Math.pow(originalLength, 2)) - return result - } - - function calculateLength(originalLength, angle1, angle2) { - const numerator = Math.sqrt(Math.pow(angle1, 2) + 100 + Math.pow((10 * angle1) / angle2, 2)) * originalLength - const denominator = Math.sqrt(Math.pow((10 * angle1) / angle2, 2) + 100) - const result = numerator / denominator - return result + function calculateLength(originalLength, angle, angle1) { + console.log(angle, angle1) + const slope1 = basicSetting.roofAngleSet !== 'slope' ? getChonByDegree(angle) : angle + const slope2 = basicSetting.roofAngleSet !== 'slope' ? getChonByDegree(angle1 ?? 0) : angle1 + if (!angle1) { + const angleInRadians = slope1 * (Math.PI / 180) + const result = Math.sqrt(Math.pow(originalLength * Math.tan(angleInRadians), 2) + Math.pow(originalLength, 2)) + console.log(angleInRadians, result) + return result + } else { + const numerator = Math.sqrt(Math.pow(slope1, 2) + 100 + Math.pow((10 * slope1) / slope2, 2)) * originalLength + const denominator = Math.sqrt(Math.pow((10 * slope1) / slope2, 2) + 100) + const result = numerator / denominator + console.log('2222222222222222') + return result + } } return ( @@ -123,14 +145,32 @@ export default function DimensionLineSetting(props) {
{getMessage('slope')}
- + setSelectedSlope1(e)} + showKey={'name'} + sourceKey={'value'} + targetKey={'value'} + />
{pitchText}
{getMessage('slope')}
- + setSelectedSlope2(e)} + showKey={'name'} + sourceKey={'value'} + targetKey={'value'} + />
{pitchText}
From 94896b983727b3c85e1b1604c7271b1ace22c19c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 26 Feb 2025 14:13:18 +0900 Subject: [PATCH 159/352] =?UTF-8?q?-=20=EB=B3=B4=EC=A1=B0=EC=84=A0=20?= =?UTF-8?q?=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/roofcover/useAuxiliaryDrawing.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hooks/roofcover/useAuxiliaryDrawing.js b/src/hooks/roofcover/useAuxiliaryDrawing.js index 7cacdd03..dd5a2a49 100644 --- a/src/hooks/roofcover/useAuxiliaryDrawing.js +++ b/src/hooks/roofcover/useAuxiliaryDrawing.js @@ -129,6 +129,7 @@ export function useAuxiliaryDrawing(id, isUseEffect = true) { const copy = (object, x, y) => { return addLine([object.x1 + x, object.y1 + y, object.x2 + x, object.y2 + y], { + attributes: object.attributes, stroke: 'red', strokeWidth: 1, selectable: true, From 135440a0dee51c327140073bb77c7926d2480816 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 26 Feb 2025 15:44:24 +0900 Subject: [PATCH 160/352] =?UTF-8?q?=EB=B3=B4=EC=A1=B0=EC=84=A0=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1=20=EC=8B=9C=20=EC=A7=80=EB=B6=95=20=EC=97=86=EC=9D=84?= =?UTF-8?q?=20=EA=B2=BD=EC=9A=B0=20=EC=9D=98=EB=8F=84=ED=95=98=EC=A7=80=20?= =?UTF-8?q?=EC=95=8A=EC=9D=80=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/roofcover/useAuxiliaryDrawing.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/hooks/roofcover/useAuxiliaryDrawing.js b/src/hooks/roofcover/useAuxiliaryDrawing.js index dd5a2a49..da6391b8 100644 --- a/src/hooks/roofcover/useAuxiliaryDrawing.js +++ b/src/hooks/roofcover/useAuxiliaryDrawing.js @@ -104,6 +104,10 @@ export function useAuxiliaryDrawing(id, isUseEffect = true) { }, []) useEffect(() => { + const roofs = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) + if (roofs.length === 0) { + return + } addCanvasMouseEventListener('mouse:down', mouseDown) }, [verticalHorizontalMode]) From af0120b8a254da9cd1c06294e4fc88e775b3c795 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 26 Feb 2025 16:06:25 +0900 Subject: [PATCH 161/352] =?UTF-8?q?-=20=EB=AA=A8=EB=93=88=20=EB=B3=B5?= =?UTF-8?q?=EC=82=AC=ED=95=A0=EB=95=8C=20moduleInfo=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModule.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/hooks/module/useModule.js b/src/hooks/module/useModule.js index 0c884608..4d54a3ea 100644 --- a/src/hooks/module/useModule.js +++ b/src/hooks/module/useModule.js @@ -225,6 +225,7 @@ export function useModule() { length: module.length, points: module.points, surfaceId: module.surfaceId, + moduleInfo: module.moduleInfo, left, top, id: uuidv4(), @@ -281,6 +282,7 @@ export function useModule() { length: module.length, points: module.points, surfaceId: module.surfaceId, + moduleInfo: module.moduleInfo, left, top, id: uuidv4(), @@ -358,6 +360,7 @@ export function useModule() { type: module.type, length: module.length, points: module.points, + moduleInfo: module.moduleInfo, surfaceId: module.surfaceId, left, top, @@ -682,6 +685,7 @@ export function useModule() { type: module.type, length: module.length, points: module.points, + moduleInfo: module.moduleInfo, surfaceId: module.surfaceId, left, top, @@ -778,6 +782,7 @@ export function useModule() { length: module.length, points: module.points, surfaceId: module.surfaceId, + moduleInfo: module.moduleInfo, fill: module.fill, left, top, @@ -949,16 +954,16 @@ export function useModule() { let left = target.left if (direction === 'up') { - top = Number(target.top) - Number(length) + top = Number(target.top) - Number(length) / 10 top = hasMargin ? top - Number(target.height) : top } else if (direction === 'down') { - top = Number(target.top) + Number(length) + top = Number(target.top) + Number(length) / 10 top = hasMargin ? top + Number(target.height) : top } else if (direction === 'left') { - left = Number(target.left) - Number(length) + left = Number(target.left) - Number(length) / 10 left = hasMargin ? left - Number(target.width) : left } else if (direction === 'right') { - left = Number(target.left) + Number(length) + left = Number(target.left) + Number(length) / 10 left = hasMargin ? left + Number(target.width) : left } return { top, left } From 4e963254d1ac2cab4f2b46b54c11a12b4e0832e2 Mon Sep 17 00:00:00 2001 From: basssy Date: Wed, 26 Feb 2025 16:41:39 +0900 Subject: [PATCH 162/352] =?UTF-8?q?=EB=AC=BC=EA=B1=B4=EC=83=81=EC=84=B8=20?= =?UTF-8?q?->=20=ED=94=8C=EB=9E=9C=20=EA=B7=B8=EB=A6=AC=EB=93=9C=20?= =?UTF-8?q?=EB=8D=94=EB=B8=94=ED=81=B4=EB=A6=AD=20=EB=8F=84=EB=A9=B4?= =?UTF-8?q?=EC=9E=91=EC=84=B1=20=EC=9D=B4=EB=8F=99=20/=20=EC=83=81?= =?UTF-8?q?=EB=8B=A8=EC=97=90=20=EB=8F=84=EB=A9=B4=EC=9E=91=EC=84=B1=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=EC=9C=BC=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= =?UTF-8?q?=EC=8B=9C=20SelectedMenu=20=EB=B6=84=EB=A6=AC=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/management/StuffDetail.jsx | 20 +++++++------------- src/components/management/StuffSubHeader.jsx | 15 ++++++++++++++- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index aacaeea4..0c825c20 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -1625,17 +1625,6 @@ export default function StuffDetail() { input.value = input.value.replace(/[^0-9]/g, '') } - //자동완성 옵션 없을때 메세지 컴포넌트.. - const NoOptionsMessage = (props) => { - return ( - - - TEXTTTTTTT - - - ) - } - // 그리드 더블 클릭 해당플랜의 도면작성 화면으로 이동 const getCellDoubleClicked = (params) => { if (managementState?.createSaleStoreId === 'T01') { @@ -1653,7 +1642,13 @@ export default function StuffDetail() { pid: planNo, objectNo: objectNo, } - setSelectedMenu(null) + // 견적서 생성 여부에 따라 selectedMenu 셋팅 + if (params?.data?.estimateDate) { + setSelectedMenu('module') + } else { + setSelectedMenu('surface') + } + const url = `/floor-plan?${queryStringFormatter(param)}` router.push(url) } @@ -1946,7 +1941,6 @@ export default function StuffDetail() {
{ - handleChangeTabsData({ ...s, range: e.target.value }) - }} - /> - { - handleChangeTabsData({ ...s, maker: e.target.value }) - }} - /> - { - handleChangeTabsData({ ...s, law: e.target.value }) - }} - /> - { - handleChangeTabsData({ ...s, basis: e.target.value }) - }} - /> -
- - - - ))} - - - - ) -} From 15c51547ce9a7b47801c87ca622b5c45702b0bcc Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 27 Feb 2025 10:09:06 +0900 Subject: [PATCH 167/352] =?UTF-8?q?=EA=B0=80=EB=8C=80=20=EA=B4=80=EB=A0=A8?= =?UTF-8?q?=20item=20=EC=83=81=EC=88=98=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/common.js | 9 +++++++++ src/hooks/module/useTrestle.js | 34 +++++++++++++++++----------------- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/common/common.js b/src/common/common.js index 1452aa3a..ca472a11 100644 --- a/src/common/common.js +++ b/src/common/common.js @@ -116,6 +116,15 @@ export const POLYGON_TYPE = { OBJECT_SURFACE: 'objectOffset', } +// 가대 관련 상수 +export const TRESTLE_MATERIAL = { + EAVE_BAR: 'eaveBar', + HALF_EAVE_BAR: 'halfEaveBar', + RACK: 'rack', + SMART_RACK: 'smartRack', + BRACKET: 'bracket', +} + export const SAVE_KEY = [ 'selectable', 'name', diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index 38c56f84..2b35aaf6 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -1,6 +1,6 @@ import { useRecoilValue } from 'recoil' import { canvasState, currentAngleTypeSelector } from '@/store/canvasAtom' -import { POLYGON_TYPE } from '@/common/common' +import { POLYGON_TYPE, TRESTLE_MATERIAL } from '@/common/common' import { moduleSelectionDataState } from '@/store/selectedModuleOptions' import { getDegreeByChon } from '@/util/canvas-util' import { v4 as uuidv4 } from 'uuid' @@ -147,7 +147,7 @@ export const useTrestle = () => { if (!bottomPoints) return const eaveBar = new fabric.Line([bottomPoints[0].x, bottomPoints[0].y, bottomPoints[1].x, bottomPoints[1].y], { parent: surface, - name: 'eaveBar', + name: TRESTLE_MATERIAL.EAVE_BAR, stroke: 'blue', strokeWidth: 4, selectable: false, @@ -178,7 +178,7 @@ export const useTrestle = () => { if (!bottomPoints) return const halfEaveBar = new fabric.Line(barPoints, { parent: surface, - name: 'halfEaveBar', + name: TRESTLE_MATERIAL.HALF_EAVE_BAR, stroke: 'blue', strokeWidth: 4, selectable: false, @@ -208,7 +208,7 @@ export const useTrestle = () => { if (!bottomPoints) return const halfEaveBar = new fabric.Line(barPoints, { parent: surface, - name: 'halfEaveBar', + name: TRESTLE_MATERIAL.HALF_EAVE_BAR, stroke: 'blue', strokeWidth: 4, selectable: false, @@ -1086,7 +1086,7 @@ export const useTrestle = () => { rackLength = getTrestleLength(setRackTpLen, degree) / 10 if (setRackTpCd === 'RACK') { const rack = new fabric.Line([startPointX, startPointY, startPointX, startPointY - rackLength], { - name: 'smartRack', + name: TRESTLE_MATERIAL.SMART_RACK, stroke: 'red', strokeWidth: 4, selectable: true, @@ -1117,7 +1117,7 @@ export const useTrestle = () => { }) } else { const rack = new fabric.Line([startPointX, startPointY, startPointX, startPointY - rackLength], { - name: 'rack', + name: TRESTLE_MATERIAL.RACK, stroke: 'red', strokeWidth: 4, selectable: false, @@ -1159,7 +1159,7 @@ export const useTrestle = () => { rackLength = getTrestleLength(setRackTpLen, degree) / 10 if (setRackTpCd === 'RACK') { const rack = new fabric.Line([startPointX, startPointY, startPointX - rackLength, startPointY], { - name: 'smartRack', + name: TRESTLE_MATERIAL.SMART_RACK, stroke: 'red', strokeWidth: 4, selectable: false, @@ -1190,7 +1190,7 @@ export const useTrestle = () => { }) } else { const rack = new fabric.Line([startPointX, startPointY, startPointX - rackLength, startPointY], { - name: 'rack', + name: TRESTLE_MATERIAL.RACK, stroke: 'red', shadow: { color: 'black', // Outline color @@ -1231,7 +1231,7 @@ export const useTrestle = () => { rackLength = getTrestleLength(setRackTpLen, degree) / 10 if (setRackTpCd === 'RACK') { const rack = new fabric.Line([startPointX, startPointY, startPointX + rackLength, startPointY], { - name: 'smartRack', + name: TRESTLE_MATERIAL.SMART_RACK, stroke: 'red', strokeWidth: 4, selectable: false, @@ -1262,7 +1262,7 @@ export const useTrestle = () => { }) } else { const rack = new fabric.Line([startPointX, startPointY, startPointX + rackLength, startPointY], { - name: 'rack', + name: TRESTLE_MATERIAL.RACK, stroke: 'red', shadow: { color: 'black', // Outline color @@ -1301,7 +1301,7 @@ export const useTrestle = () => { rackLength = getTrestleLength(setRackTpLen, degree) / 10 if (setRackTpCd === 'RACK') { const rack = new fabric.Line([startPointX, startPointY, startPointX, startPointY + rackLength], { - name: 'smartRack', + name: TRESTLE_MATERIAL.SMART_RACK, stroke: 'red', strokeWidth: 4, selectable: false, @@ -1332,7 +1332,7 @@ export const useTrestle = () => { }) } else { const rack = new fabric.Line([startPointX, startPointY, startPointX, startPointY + rackLength], { - name: 'rack', + name: TRESTLE_MATERIAL.RACK, stroke: 'red', shadow: { color: 'black', // Outline color @@ -1394,7 +1394,7 @@ export const useTrestle = () => { left: x2 - bracketLength / 3, top: len, fill: 'green', - name: 'bracket', + name: TRESTLE_MATERIAL.BRACKET, parentId: rack.parentId, visible: isTrestleDisplay, surfaceId: surface.id, @@ -1416,7 +1416,7 @@ export const useTrestle = () => { left: len, top: y2 - bracketLength / 3, fill: 'green', - name: 'bracket', + name: TRESTLE_MATERIAL.BRACKET, parentId: rack.parentId, visible: isTrestleDisplay, surfaceId: surface.id, @@ -1441,7 +1441,7 @@ export const useTrestle = () => { parentId: rack.parentId, visible: isTrestleDisplay, surfaceId: surface.id, - name: 'bracket', + name: TRESTLE_MATERIAL.BRACKET, width: bracketLength, height: bracketLength, selectable: false, @@ -1459,7 +1459,7 @@ export const useTrestle = () => { left: x2 - bracketLength / 3, top: len, fill: 'green', - name: 'bracket', + name: TRESTLE_MATERIAL.BRACKET, parentId: rack.parentId, visible: isTrestleDisplay, surfaceId: surface.id, @@ -1645,7 +1645,7 @@ export const useTrestle = () => { left: startPointX - 5, top: startPointY - 5, fill: 'green', - name: 'bracket', + name: TRESTLE_MATERIAL.BRACKET, parentId: module.id, surfaceId: module.surfaceId, width: 10, From 01ee1297185e64429acf7097ac680f6f69ded889 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Thu, 27 Feb 2025 13:46:06 +0900 Subject: [PATCH 168/352] =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=A9=B4=20=EC=96=BC?= =?UTF-8?q?=EB=9F=BF=20=EB=AC=B8=EA=B5=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/surface/useSurfaceShapeBatch.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/hooks/surface/useSurfaceShapeBatch.js b/src/hooks/surface/useSurfaceShapeBatch.js index 73bd1d9a..ed7b2ca1 100644 --- a/src/hooks/surface/useSurfaceShapeBatch.js +++ b/src/hooks/surface/useSurfaceShapeBatch.js @@ -74,11 +74,11 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { console.log(' before length : ', length1, length2, length3, length4, length5) - length1 = parseFloat(length1 === undefined ? 0 : length1 / 10) - length2 = parseFloat(length2 === undefined ? 0 : length2 / 10) - length3 = parseFloat(length3 === undefined ? 0 : length3 / 10) - length4 = parseFloat(length4 === undefined ? 0 : length4 / 10) - length5 = parseFloat(length5 === undefined ? 0 : length5 / 10) + length1 = parseFloat(length1 === undefined ? 0 : Number(length1 / 10).toFixed(1)) + length2 = parseFloat(length2 === undefined ? 0 : Number(length2 / 10).toFixed(1)) + length3 = parseFloat(length3 === undefined ? 0 : Number(length3 / 10).toFixed(1)) + length4 = parseFloat(length4 === undefined ? 0 : Number(length4 / 10).toFixed(1)) + length5 = parseFloat(length5 === undefined ? 0 : Number(length5 / 10).toFixed(1)) console.log(' after length : ', length1, length2, length3, length4, length5) @@ -289,7 +289,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { } if (length4 >= length3) { - swalFire({ text: getMessage('surface.shape.validate.size.1to2'), icon: 'error' }) + swalFire({ text: getMessage('surface.shape.validate.size.3to4'), icon: 'error' }) check = false } } From 804feae1d6c7bb34c3cf54e1107b805741d31097 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 27 Feb 2025 13:51:15 +0900 Subject: [PATCH 169/352] =?UTF-8?q?innerLines=20=EC=97=86=EB=8A=94=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=20=EB=B3=B5=EA=B5=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/usePolygon.js | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/hooks/usePolygon.js b/src/hooks/usePolygon.js index 1dc3f231..a8942814 100644 --- a/src/hooks/usePolygon.js +++ b/src/hooks/usePolygon.js @@ -1,7 +1,7 @@ -import { ANGLE_TYPE, canvasState, currentAngleTypeSelector, fontFamilyState, fontSizeState, pitchTextSelector } from '@/store/canvasAtom' +import { ANGLE_TYPE, canvasState, currentAngleTypeSelector, pitchTextSelector } from '@/store/canvasAtom' import { useRecoilValue } from 'recoil' import { fabric } from 'fabric' -import { findAndRemoveClosestPoint, getDegreeByChon, getDegreeInOrientation, getDirectionByPoint, isPointOnLine } from '@/util/canvas-util' +import { findAndRemoveClosestPoint, getDegreeByChon, getDegreeInOrientation, isPointOnLine } from '@/util/canvas-util' import { QPolygon } from '@/components/fabric/QPolygon' import { isSamePoint, removeDuplicatePolygons } from '@/util/qpolygon-utils' import { flowDisplaySelector } from '@/store/settingAtom' @@ -753,6 +753,25 @@ export const usePolygon = () => { polygon.set({ visible: false }) let innerLines = [...polygon.innerLines] + // innerLine이 세팅이 안되어있는경우 찾아서 세팅한다. + if (!innerLines || innerLines.length === 0) { + let innerLineTypes = [] + Object.keys(LINE_TYPE.SUBLINE).forEach((key, value) => { + innerLineTypes.push(LINE_TYPE.SUBLINE[key]) + }) + polygon.innerLines = canvas + .getObjects() + .filter( + (obj) => + obj.type === 'QLine' && + obj.attributes?.type !== 'pitchSizeLine' && + obj.attributes?.roofId === polygon.id && + (innerLineTypes.includes(obj.name) || !obj.name), + ) + + innerLines = [...polygon.innerLines] + } + canvas.renderAll() let polygonLines = [...polygon.lines] const roofs = [] From 707a8daf02f7901fa25a819cc03d2da9d3b75692 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 27 Feb 2025 13:54:36 +0900 Subject: [PATCH 170/352] =?UTF-8?q?=F0=9F=9A=A8chore:=20Sync=20Sass?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/static/images/canvas/object_img01.svg | 14 ++++------ public/static/images/canvas/object_img02.svg | 19 +++++++------ .../canvas/shape/180deg/plane_tab01.svg | 26 +++++++++-------- .../canvas/shape/270deg/plane_tab01.svg | 26 +++++++++-------- .../images/canvas/shape/90deg/plane_tab01.svg | 26 +++++++++-------- .../canvas/shape/normal/plane_tab01.svg | 26 +++++++++-------- .../canvas/shape/re_180deg/plane_tab01.svg | 26 +++++++++-------- .../canvas/shape/re_270deg/plane_tab01.svg | 26 +++++++++-------- .../canvas/shape/re_90deg/plane_tab01.svg | 26 +++++++++-------- .../canvas/shape/re_normal/plane_tab01.svg | 28 ++++++++++--------- src/styles/_modal.scss | 19 ++++++++++++- 11 files changed, 154 insertions(+), 108 deletions(-) diff --git a/public/static/images/canvas/object_img01.svg b/public/static/images/canvas/object_img01.svg index 1d72f00b..0f5615a6 100644 --- a/public/static/images/canvas/object_img01.svg +++ b/public/static/images/canvas/object_img01.svg @@ -1,16 +1,14 @@ - - + + + + + - - - - - - + diff --git a/public/static/images/canvas/object_img02.svg b/public/static/images/canvas/object_img02.svg index ab1e8f43..85f47edf 100644 --- a/public/static/images/canvas/object_img02.svg +++ b/public/static/images/canvas/object_img02.svg @@ -1,21 +1,22 @@ - - + + + + + - + - - - - - + + + - + diff --git a/public/static/images/canvas/shape/180deg/plane_tab01.svg b/public/static/images/canvas/shape/180deg/plane_tab01.svg index 84c22986..7669a51b 100644 --- a/public/static/images/canvas/shape/180deg/plane_tab01.svg +++ b/public/static/images/canvas/shape/180deg/plane_tab01.svg @@ -1,12 +1,16 @@ - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/270deg/plane_tab01.svg b/public/static/images/canvas/shape/270deg/plane_tab01.svg index 22b32884..3fd9d7e7 100644 --- a/public/static/images/canvas/shape/270deg/plane_tab01.svg +++ b/public/static/images/canvas/shape/270deg/plane_tab01.svg @@ -1,12 +1,16 @@ - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/90deg/plane_tab01.svg b/public/static/images/canvas/shape/90deg/plane_tab01.svg index 46476194..c41f7dee 100644 --- a/public/static/images/canvas/shape/90deg/plane_tab01.svg +++ b/public/static/images/canvas/shape/90deg/plane_tab01.svg @@ -1,12 +1,16 @@ - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/normal/plane_tab01.svg b/public/static/images/canvas/shape/normal/plane_tab01.svg index 121b7025..1091f744 100644 --- a/public/static/images/canvas/shape/normal/plane_tab01.svg +++ b/public/static/images/canvas/shape/normal/plane_tab01.svg @@ -1,12 +1,16 @@ - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_180deg/plane_tab01.svg b/public/static/images/canvas/shape/re_180deg/plane_tab01.svg index aab78f30..60521209 100644 --- a/public/static/images/canvas/shape/re_180deg/plane_tab01.svg +++ b/public/static/images/canvas/shape/re_180deg/plane_tab01.svg @@ -1,12 +1,16 @@ - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_270deg/plane_tab01.svg b/public/static/images/canvas/shape/re_270deg/plane_tab01.svg index c225ea23..2b9f1f06 100644 --- a/public/static/images/canvas/shape/re_270deg/plane_tab01.svg +++ b/public/static/images/canvas/shape/re_270deg/plane_tab01.svg @@ -1,12 +1,16 @@ - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_90deg/plane_tab01.svg b/public/static/images/canvas/shape/re_90deg/plane_tab01.svg index 36c1d46b..b7cd5f4d 100644 --- a/public/static/images/canvas/shape/re_90deg/plane_tab01.svg +++ b/public/static/images/canvas/shape/re_90deg/plane_tab01.svg @@ -1,12 +1,16 @@ - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/public/static/images/canvas/shape/re_normal/plane_tab01.svg b/public/static/images/canvas/shape/re_normal/plane_tab01.svg index 8fc73ac0..77db4276 100644 --- a/public/static/images/canvas/shape/re_normal/plane_tab01.svg +++ b/public/static/images/canvas/shape/re_normal/plane_tab01.svg @@ -1,14 +1,16 @@ - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/src/styles/_modal.scss b/src/styles/_modal.scss index fed29abe..9ec806ef 100644 --- a/src/styles/_modal.scss +++ b/src/styles/_modal.scss @@ -904,6 +904,8 @@ $alert-color: #101010; .allocation-edit{ display: flex; align-items: center; + justify-content: center; + width: 100%; height: 30px; padding: 0 10px; margin-left: 5px; @@ -912,6 +914,7 @@ $alert-color: #101010; font-weight: $pop-normal-weight; border: 1px solid #484848; background-color: #323234; + transition: background-color .13s ease-in-out; i{ display: block; width: 12px; @@ -920,6 +923,9 @@ $alert-color: #101010; background: url(../../public/static/images/canvas/allocation_edit.svg)no-repeat center; background-size: cover; } + &:hover{ + background-color: #464545; + } } } @@ -1232,7 +1238,6 @@ $alert-color: #101010; .object-size-wrap{ display: flex; min-height: 206px; - gap: 24px; margin-top: 14px; .object-size-img{ position: relative; @@ -1246,6 +1251,18 @@ $alert-color: #101010; transform: translate(-50%, -50%); } } + .object-size-input{ + margin-left: auto; + .eaves-keraba-th{ + position: relative; + .object-input-num{ + position: absolute; + top: 7px; + left: -20px; + font-size: 13px; + } + } + } } // 표시변경 From f3acae7a46bf87357f17f8b54288a18ef8a3a1aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 27 Feb 2025 13:56:05 +0900 Subject: [PATCH 171/352] =?UTF-8?q?=ED=9A=8C=EB=A1=9C=20=ED=95=A0=EB=8B=B9?= =?UTF-8?q?=20=ED=9B=84=20=EB=AA=A8=EB=93=88=20=EC=82=AD=EC=A0=9C,=20?= =?UTF-8?q?=EB=8B=A8/=EC=97=B4=20=EC=9D=B4=EB=8F=99=20=EC=A0=9C=ED=95=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModule.js | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/hooks/module/useModule.js b/src/hooks/module/useModule.js index 4d54a3ea..41592eda 100644 --- a/src/hooks/module/useModule.js +++ b/src/hooks/module/useModule.js @@ -44,7 +44,14 @@ export function useModule() { const moduleMove = (length, direction) => { const selectedObj = canvas.getActiveObjects() //선택된 객체들을 가져옴 const selectedIds = selectedObj.map((obj) => obj.id) // selectedObj의 ID 추출 - + if (selectedObj[0].circuit) { + swalFire({ + title: getMessage('can.not.move.module'), + icon: 'error', + type: 'alert', + }) + return + } canvas.discardActiveObject() //선택해제 const isSetupModules = getOtherModules(selectedObj) @@ -101,6 +108,14 @@ export function useModule() { return } const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0] + if (activeModule.circuit) { + swalFire({ + title: getMessage('can.not.move.module'), + icon: 'error', + type: 'alert', + }) + return + } const modules = type === 'row' ? getRowModules(activeModule) : getColumnModules(activeModule) const otherModules = getOtherModules(modules) const objects = getObjects() @@ -400,6 +415,14 @@ export function useModule() { const moduleColumnRemove = (type) => { const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0] + if (activeModule.circuit) { + swalFire({ + title: getMessage('can.not.move.module'), + icon: 'error', + type: 'alert', + }) + return + } const columnModules = getColumnModules(activeModule) const otherModules = getOtherModules(columnModules) const objects = getObjects() @@ -515,6 +538,14 @@ export function useModule() { const moduleRowRemove = (type) => { const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0] + if (activeModule.circuit) { + swalFire({ + title: getMessage('can.not.remove.module'), + icon: 'error', + type: 'alert', + }) + return + } const rowModules = getRowModules(activeModule) const otherModules = getOtherModules(rowModules) const objects = getObjects() @@ -887,7 +918,7 @@ export function useModule() { const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0] if (activeModule.circuit) { swalFire({ - title: getMessage('can.not.remove.module'), + title: getMessage('can.not.move.module'), icon: 'error', type: 'alert', }) From 7bd2ba637a759fd9a1f8d7d61c291559277cee93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 27 Feb 2025 13:56:38 +0900 Subject: [PATCH 172/352] =?UTF-8?q?=ED=8D=BC=EB=B8=94=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=20=EB=B0=8F=20=EB=8B=A4=EA=B5=AD=EC=96=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/object/type/PentagonDormer.jsx | 10 ++++++++-- .../floor-plan/modal/object/type/TriangleDormer.jsx | 5 ++++- src/locales/ja.json | 8 +++++--- src/locales/ko.json | 8 +++++--- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/components/floor-plan/modal/object/type/PentagonDormer.jsx b/src/components/floor-plan/modal/object/type/PentagonDormer.jsx index 0bca7527..87a92835 100644 --- a/src/components/floor-plan/modal/object/type/PentagonDormer.jsx +++ b/src/components/floor-plan/modal/object/type/PentagonDormer.jsx @@ -23,7 +23,10 @@ const PentagonDormer = forwardRef((props, refs) => {
-
{getMessage('modal.object.setting.agreement.depth')}
+
+ + {getMessage('modal.object.setting.agreement.depth')} +
@@ -45,7 +48,10 @@ const PentagonDormer = forwardRef((props, refs) => {
-
{getMessage('width')}
+
+ + {getMessage('modal.object.setting.size.width')} +
diff --git a/src/components/floor-plan/modal/object/type/TriangleDormer.jsx b/src/components/floor-plan/modal/object/type/TriangleDormer.jsx index 229043c8..62fd729d 100644 --- a/src/components/floor-plan/modal/object/type/TriangleDormer.jsx +++ b/src/components/floor-plan/modal/object/type/TriangleDormer.jsx @@ -23,7 +23,10 @@ const TriangleDormer = forwardRef((props, refs) => {
-
{getMessage('modal.object.setting.agreement.depth')}
+
+ + {getMessage('modal.object.setting.agreement.depth')} +
diff --git a/src/locales/ja.json b/src/locales/ja.json index ef70bb9b..dc87c49d 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -292,9 +292,11 @@ "modal.object.setting.height": "縦長", "modal.object.setting.area.cross": "エリア交差", "modal.object.setting.size.setting": "サイズ設定", - "modal.object.setting.agreement.depth": "棟の長さ・深さ", - "modal.object.setting.offset.depth": "出幅(深さ)", - "modal.object.setting.offset.width": "出幅(幅)", + "modal.object.setting.agreement.depth": "棟の長さ", + "modal.object.setting.offset.depth": "棟の出幅", + "modal.object.setting.size.width": "幅", + "modal.object.setting.offset.width": "幅の出幅", + "modal.object.setting.offset.slope": "勾配", "modal.object.setting.direction.select": "方向の選択", "modal.placement.surface.setting.info": "ⓘ①の長さ入力後、対角線長を入力すると②の長さを自動計算します。", "modal.placement.surface.setting.diagonal.length": "斜めの長さ", diff --git a/src/locales/ko.json b/src/locales/ko.json index d60e226d..58d68115 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -292,9 +292,11 @@ "modal.object.setting.height": "세로길이", "modal.object.setting.area.cross": "영역교차", "modal.object.setting.size.setting": "사이즈설정", - "modal.object.setting.agreement.depth": "동의길이 깊이", - "modal.object.setting.offset.depth": "출폭(깊이)", - "modal.object.setting.offset.width": "출폭(폭)", + "modal.object.setting.agreement.depth": "동의 길이", + "modal.object.setting.offset.depth": "동의 출폭", + "modal.object.setting.size.width": "너비", + "modal.object.setting.offset.width": "너비의 출폭", + "modal.object.setting.offset.slope": "경사", "modal.object.setting.direction.select": "방향 선택", "modal.placement.surface.setting.info": "ⓘ ①의 길이 입력 후 대각선 길이를 입력하면 ②의 길이를 자동 계산합니다.", "modal.placement.surface.setting.diagonal.length": "대각선 길이", From 6e1ae73cccfb1c109bff2a68143db5cd9e15a650 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 27 Feb 2025 13:57:18 +0900 Subject: [PATCH 173/352] =?UTF-8?q?api=20=EB=8D=B0=EC=9D=B4=ED=85=A8=20?= =?UTF-8?q?=ED=98=95=ED=83=9C=20=EB=B3=80=EA=B2=BD=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EB=90=9C=20PCS=20->=20PCS=20=EC=A0=84=EC=B2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../step/PowerConditionalSelect.jsx | 4 +- .../step/type/PassivityCircuitAllocation.jsx | 62 +++++-------------- 2 files changed, 19 insertions(+), 47 deletions(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx b/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx index df6d15b1..f531f97f 100644 --- a/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx @@ -161,9 +161,9 @@ export default function PowerConditionalSelect(props) { return } if (selectedMaker.pcsMkrMultiType === PCS_MKR_MULTI_TYPE.MULTI) { - setSelectedModels([...selectedModels, { ...selectedRow, id: uuidv4(), isUsed: false }]) + setSelectedModels([...selectedModels, { ...selectedRow, id: uuidv4() }]) } else if (!selectedModels.find((m) => m.itemId === selectedRow.itemId)) { - setSelectedModels([...selectedModels, { ...selectedRow, id: uuidv4(), isUsed: false }]) + setSelectedModels([...selectedModels, { ...selectedRow, id: uuidv4() }]) } setSelectedRow(null) } diff --git a/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx b/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx index faf31eef..e009a864 100644 --- a/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/step/type/PassivityCircuitAllocation.jsx @@ -157,18 +157,10 @@ export default function PassivityCircuitAllocation(props) { obj.pcsItemCode = selectedPcs.id obj.circuit = moduleCircuitText obj.circuitNumber = getCircuitNumber() - tempSelectedPcs.used = true setSelectedPcs(tempSelectedPcs) canvas.add(moduleCircuitText) }) - let pcsList = JSON.parse(JSON.stringify(selectedModels)).map((model) => { - if (model.id === selectedPcs.id) { - model.isUsed = true - } - return model - }) - const roofSurfaceList = canvas .getObjects() .filter((obj) => POLYGON_TYPE.MODULE_SETUP_SURFACE === obj.name && obj?.modules.length > 0) @@ -210,29 +202,24 @@ export default function PassivityCircuitAllocation(props) { result[firstPart].count += 1 } } - console.log('🚀 ~ handleCircuitNumberFix ~ result:', result) - const usedPcses = pcsList.filter((model) => model.isUsed) - const pcsItemList = usedPcses.map((model, index) => { - if (result[(index + 1).toString()]) { - return { - pcsMkrCd: model.pcsMkrCd, - pcsSerCd: model.pcsSerCd, - itemId: model.itemId, - itemNm: model.itemNm, - goodsNo: model.goodsNo, - serQtyList: [ - { - serQty: result[(index + 1).toString()].maxValue, - paralQty: result[(index + 1).toString()].count, - rmdYn: 'Y', - usePossYn: 'Y', - roofSurfaceList: roofSurfaceList, - }, - ], - } + const pcsItemList = selectedModels.map((model, index) => { + return { + pcsMkrCd: model.pcsMkrCd, + pcsSerCd: model.pcsSerCd, + itemId: model.itemId, + itemNm: model.itemNm, + goodsNo: model.goodsNo, + serQtyList: [ + { + serQty: result[(index + 1).toString()] ? result[(index + 1).toString()].maxValue : 0, + paralQty: result[(index + 1).toString()] ? result[(index + 1).toString()].count : 0, + rmdYn: 'Y', + usePossYn: 'Y', + roofSurfaceList: roofSurfaceList, + }, + ], } }) - const params = { ...getApiProps(), useModuleItemList: getSelectedModuleList(), @@ -259,13 +246,10 @@ export default function PassivityCircuitAllocation(props) { canvas.renderAll() }, }) - setSelectedPcs({ ...selectedPcs, used: false }) setTargetModules([]) return } - setSelectedModels(pcsList) - setTargetModules([]) setCircuitNumber(+circuitNumber + 1) setModuleStatisticsData() @@ -414,18 +398,10 @@ export default function PassivityCircuitAllocation(props) { obj.pcsItemCode = selectedPcs.id obj.circuit = moduleCircuitText obj.circuitNumber = getCircuitNumber() - tempSelectedPcs.used = true setSelectedPcs(tempSelectedPcs) canvas.add(moduleCircuitText) }) - let pcsList = JSON.parse(JSON.stringify(selectedModels)).map((model) => { - if (model.id === selectedPcs.id) { - model.isUsed = true - } - return model - }) - const roofSurfaceList = canvas .getObjects() .filter((obj) => POLYGON_TYPE.MODULE_SETUP_SURFACE === obj.name && obj?.modules.length > 0) @@ -443,8 +419,7 @@ export default function PassivityCircuitAllocation(props) { }), } }) - const usedPcses = pcsList.filter((model) => model.isUsed) - const pcsItemList = usedPcses.map((model, index) => { + const pcsItemList = selectedModels.map((model, index) => { return { pcsMkrCd: model.pcsMkrCd, pcsSerCd: model.pcsSerCd, @@ -489,13 +464,10 @@ export default function PassivityCircuitAllocation(props) { canvas.renderAll() }, }) - setSelectedPcs({ ...selectedPcs, used: false }) setTargetModules([]) return } - setSelectedModels(pcsList) - setTargetModules([]) setModuleStatisticsData() setTabNum(2) From d2996ee21733cf08e5001c521262859e26b152ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 27 Feb 2025 14:08:13 +0900 Subject: [PATCH 174/352] =?UTF-8?q?=EC=B4=88=EA=B8=B0=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EC=9D=BC=EB=B3=B8=EC=96=B4=EB=A1=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/circuitTrestleAtom.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/store/circuitTrestleAtom.js b/src/store/circuitTrestleAtom.js index d1477e13..b513a16c 100644 --- a/src/store/circuitTrestleAtom.js +++ b/src/store/circuitTrestleAtom.js @@ -36,8 +36,8 @@ export const moduleStatisticsState = atom({ key: 'moduleStatisticsState', default: { header: [ - { name: '지붕면', prop: 'name' }, - { name: `발전량(kW)`, prop: 'amount' }, + { name: '屋根面', prop: 'name' }, + { name: `合計(kW)`, prop: 'amount' }, ], rows: [], footer: [ From 3c7c28d72cfde6b62885b6ef4bea28e8ad444e61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 27 Feb 2025 14:12:15 +0900 Subject: [PATCH 175/352] =?UTF-8?q?=EC=A7=80=EB=B6=95=EC=9E=AC=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=ED=8D=BC=EB=B8=94=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dimensionLine/DimensionLineSetting.jsx | 41 ++++++++++++++----- .../roofAllocation/RoofAllocationSetting.jsx | 4 +- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/components/floor-plan/modal/dimensionLine/DimensionLineSetting.jsx b/src/components/floor-plan/modal/dimensionLine/DimensionLineSetting.jsx index 81395b31..a49c9ad6 100644 --- a/src/components/floor-plan/modal/dimensionLine/DimensionLineSetting.jsx +++ b/src/components/floor-plan/modal/dimensionLine/DimensionLineSetting.jsx @@ -24,18 +24,20 @@ export default function DimensionLineSetting(props) { const basicSetting = useRecoilValue(basicSettingState) const changeSlopeRef = useRef() const [options, setOptions] = useState([]) + const [changeLength, setChangeLength] = useState(null) const [selectedSlope1, setSelectedSlope1] = useState(null) const [selectedSlope2, setSelectedSlope2] = useState(null) - let slopeInput1, slopeInput2 - useEffect(() => { if (canvas) { const dimensionObject = canvas.getActiveObject() const id = dimensionObject.groupId const textObj = dimensionObject._objects.filter((obj) => obj.name === 'dimensionLineText' && obj.group.groupId === id)[0] if (!textObj) return - setBasicLength(parseInt(textObj.text)) + // setBasicLength(parseInt(textObj.text)) + setBasicLength(+dimensionObject.length) + setSelectedSlope1(dimensionObject.angle1) + setSelectedSlope2(dimensionObject.angle2) } if (basicSetting.roofAngleSet === 'slope') { @@ -62,15 +64,23 @@ export default function DimensionLineSetting(props) { } }, []) - const handleChangeLength = () => { - const changeLength = changeSlopeRef.current + useEffect(() => { + if (!slopeAble) { + const dimensionObject = canvas.getActiveObject() + dimensionObject.set({ + angle1: null, + angle2: null, + }) + } + }, [slopeAble]) + const handleChangeLength = () => { if (canvas) { const dimensionObject = canvas.getActiveObject() const id = dimensionObject.groupId const textObj = dimensionObject._objects.filter((obj) => obj.name === 'dimensionLineText' && obj.group.groupId === id)[0] - let resultText = changeLength.value > 0 ? changeLength.value : '0' - + let resultText = +changeLength > 0 ? +changeLength : '0' + console.log(changeLength) if (slopeAble) { resultText = !selectedSlope2 ? calculateLength(basicLength, selectedSlope1.value).toFixed(0) @@ -81,13 +91,14 @@ export default function DimensionLineSetting(props) { text: String(resultText), }) + dimensionObject.set({ length: +resultText }) setBasicLength(resultText) + setChangeLength('') canvas.renderAll() } } - function calculateLength(originalLength, angle, angle1) { - console.log(angle, angle1) + const calculateLength = (originalLength, angle, angle1) => { const slope1 = basicSetting.roofAngleSet !== 'slope' ? getChonByDegree(angle) : angle const slope2 = basicSetting.roofAngleSet !== 'slope' ? getChonByDegree(angle1 ?? 0) : angle1 if (!angle1) { @@ -99,7 +110,6 @@ export default function DimensionLineSetting(props) { const numerator = Math.sqrt(Math.pow(slope1, 2) + 100 + Math.pow((10 * slope1) / slope2, 2)) * originalLength const denominator = Math.sqrt(Math.pow((10 * slope1) / slope2, 2) + 100) const result = numerator / denominator - console.log('2222222222222222') return result } } @@ -129,7 +139,16 @@ export default function DimensionLineSetting(props) {
{getMessage('modal.display.edit.after.length')}
- + { + console.log(e.target) + setChangeLength(e.target.value) + }} + />
diff --git a/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx b/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx index f74ef018..965f1ec9 100644 --- a/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx +++ b/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx @@ -62,7 +62,7 @@ export default function RoofAllocationSetting(props) {
{getMessage('modal.roof.alloc.info')}
- {getMessage('modal.roof.alloc.select.roof.material')} + {/* {getMessage('modal.roof.alloc.select.roof.material')}
{ @@ -77,7 +77,7 @@ export default function RoofAllocationSetting(props) { sourceKey={'roofMatlCd'} targetKey={'roofMatlCd'} /> -
+
*/}
- setSlopeAble(!slopeAble)} /> + setSlopeAble(!slopeAble)} />
diff --git a/src/hooks/common/useCommonUtils.js b/src/hooks/common/useCommonUtils.js index 538ee8c5..dbad7a88 100644 --- a/src/hooks/common/useCommonUtils.js +++ b/src/hooks/common/useCommonUtils.js @@ -282,6 +282,10 @@ export function useCommonUtils() { originY: 'center', lineDirection: lineDirection, groupId: uuid, + length: distance * 10, + slopeAble: false, + angle1: null, + angle2: null, }) canvas.add(group) From 8016b05485aa1801a455db1571131cbaf0a8d8c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 27 Feb 2025 18:14:17 +0900 Subject: [PATCH 187/352] =?UTF-8?q?=EB=AF=B8=ED=95=A0=EB=8B=B9=20=EB=AA=A8?= =?UTF-8?q?=EB=93=88=EC=9E=88=EC=9D=84=EB=95=8C=20alert=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/circuitTrestle/CircuitTrestleSetting.jsx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index 681a425d..981201ec 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -521,6 +521,15 @@ export default function CircuitTrestleSetting({ id }) { const handlePassivityAllocationCkeck = () => { let pcsCount = {} let result = {} + const notAllocationModules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE && !obj.circuit) + if (notAllocationModules.length > 0) { + swalFire({ + text: getMessage('not.allocation.exist.module'), + type: 'alert', + icon: 'warning', + }) + return + } canvas .getObjects() .filter((obj) => obj.name === POLYGON_TYPE.MODULE) From 9dff9273f75091b517f052abb9395aafc207160e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 27 Feb 2025 18:14:46 +0900 Subject: [PATCH 188/352] =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=A9=B4=20=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=EC=84=A4=EC=A0=95=20=ED=95=98=EB=8B=A8=20=EC=A7=80?= =?UTF-8?q?=EB=B6=95=EC=9E=AC=20=EB=B2=84=ED=8A=BC=20hide=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/placementShape/PlacementShapeSetting.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx index a7decdb7..ccf6ed4b 100644 --- a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx @@ -428,7 +428,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla
)}
- {currentRoof && ( + {/* {currentRoof && (
- )} + )} */} From d58646efd4a0538b624f9c5c1c05b6579ed16a16 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Thu, 27 Feb 2025 18:24:07 +0900 Subject: [PATCH 189/352] =?UTF-8?q?=F0=9F=91=80fix:=20=EC=9D=BC=EB=B3=B8?= =?UTF-8?q?=EC=96=B4=20=EB=B2=88=EC=97=AD=ED=8C=8C=EC=9D=BC=20=EB=82=B4?= =?UTF-8?q?=EC=9A=A9=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/locales/ja.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/locales/ja.json b/src/locales/ja.json index 54276e0d..52ebfeba 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -269,10 +269,10 @@ "modal.canvas.setting.wallline.properties.setting.info": "※属性を変更する外壁線を選択し、軒で設定またはケラバで設定\nボタンをクリックして設定値を適用してください。\n", "modal.canvas.setting.wallline.properties.setting.eaves": "軒で設定", "modal.canvas.setting.wallline.properties.setting.edge": "ケラバに設定", - "modal.canvas.setting.wallline.properties.setting.ridge": "", - "modal.canvas.setting.roofline.properties.setting": "", - "modal.canvas.setting.roofline.properties.setting.info": "", - "modal.canvas.setting.roofline.properties.setting.not.setting": "", + "modal.canvas.setting.wallline.properties.setting.ridge": "용마루로 설정(JA)", + "modal.canvas.setting.roofline.properties.setting": "지붕선 속성 설정(JA)", + "modal.canvas.setting.roofline.properties.setting.info": "※ 속성을 변경할 지붕선을 선택하고 처마로 설정 또는 케라바로 설정\n 버튼을 클릭하여 설정값을 적용하십시오.\n(JA)", + "modal.canvas.setting.roofline.properties.setting.not.setting": "설정하지 않은 라인이 존재합니다.(JA)", "modal.eaves.gable.edit": "軒/ケラバ変更", "modal.eaves.gable.edit.basic": "通常", "modal.eaves.gable.edit.wall.merge.info": "下屋などの壁に面する屋根を作成します。", From ec0f63de78ad999bdf8cfb65f3e8f3efe8bce29a Mon Sep 17 00:00:00 2001 From: basssy Date: Fri, 28 Feb 2025 10:07:23 +0900 Subject: [PATCH 190/352] =?UTF-8?q?=EB=AC=BC=EA=B1=B4=EC=83=81=EC=84=B8=20?= =?UTF-8?q?=EC=86=8C=EC=8A=A4=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/management/StuffDetail.jsx | 45 ++++++++++++++--------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index 0c825c20..5915fb38 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -3,7 +3,7 @@ import { useState, useEffect, useRef, useContext } from 'react' import { useRouter, useSearchParams } from 'next/navigation' import { Button } from '@nextui-org/react' -import Select, { components } from 'react-select' +import Select from 'react-select' import { useAxios } from '@/hooks/useAxios' import { globalLocaleStore } from '@/store/localeAtom' import { isEmptyArray, isNotEmptyArray, isObjectNotEmpty, queryStringFormatter } from '@/util/common-utils' @@ -1404,6 +1404,11 @@ export default function StuffDetail() { }) .catch((error) => { setIsGlobalLoading(false) + swalFire({ + text: error?.response?.data?.message, + type: 'alert', + icon: 'error', + }) console.log('error::::::', error) }) } else { @@ -1432,6 +1437,11 @@ export default function StuffDetail() { }) .catch((error) => { setIsGlobalLoading(false) + swalFire({ + text: error?.response?.data?.message, + type: 'alert', + icon: 'error', + }) console.log('error::::::', error) }) } @@ -1523,6 +1533,11 @@ export default function StuffDetail() { }) .catch((error) => { setIsGlobalLoading(false) + swalFire({ + text: error?.response?.data?.message, + type: 'alert', + icon: 'error', + }) console.log('error::::::', error) }) } else { @@ -1542,6 +1557,11 @@ export default function StuffDetail() { }) .catch((error) => { setIsGlobalLoading(false) + swalFire({ + text: error?.response?.data?.message, + type: 'alert', + icon: 'error', + }) console.log('error::::::', error) }) } @@ -1606,8 +1626,13 @@ export default function StuffDetail() { router.push('/management/stuff', { scroll: false }) }) .catch((error) => { - console.log('error::::::', error) setIsGlobalLoading(false) + swalFire({ + text: error?.response?.data?.message, + type: 'alert', + icon: 'error', + }) + console.log('error::::::', error) }) }, }) @@ -1691,15 +1716,12 @@ export default function StuffDetail() { {getMessage('stuff.detail.required')}
- {/* {!isFormValid ? ( */} - {/* ) : ( */} - {/* )} */}
- {/* {!isFormValid ? ( */} - {/* ) : ( */} - {/* )} */} - {/* ) : ( */} - {/* )} */}
名称昇圧回路数{getMessage('modal.circuit.trestle.setting.power.conditional.select.name')} {getMessage('modal.circuit.trestle.setting.step.up.allocation.circuit.amount')}
{typeof row[header.prop] === 'number' - ? row[header.prop].toLocaleString('ko-KR', { maximumFractionDigits: 4 }) - : row[header.prop]} + ? (row[header.prop] ?? 0).toLocaleString('ko-KR', { maximumFractionDigits: 4 }) + : (row[header.prop] ?? 0)}
- + From 37c72b8238d6ed04aac708d23ec50d7f2368825f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Fri, 28 Feb 2025 10:59:10 +0900 Subject: [PATCH 192/352] =?UTF-8?q?=EB=AA=A8=EB=93=88=EB=A9=94=EB=89=B4?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EB=B0=B0=EC=B9=98=EB=A9=B4=20=EB=A9=94?= =?UTF-8?q?=EB=89=B4=20=EC=95=88=EB=93=A4=EC=96=B4=EA=B0=80=EC=A7=80?= =?UTF-8?q?=EB=8A=94=20=ED=98=84=EC=83=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index b52b4a91..63ecdef3 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -408,7 +408,7 @@ export default function CanvasMenu(props) { const checkMenuState = (menu) => { return ( (['2', '3'].includes(canvasSetting?.roofSizeSet) && menu.type === 'outline') || - (selectedMenu === 'module' && ['placement', 'outline', 'surface'].includes(menu.type)) || + (selectedMenu === 'module' && ['placement', 'outline'].includes(menu.type)) || (isExistModule() && ['placement', 'outline'].some((num) => num === menu.type)) || (['estimate', 'simulation'].includes(selectedMenu) && ['placement', 'outline', 'surface'].includes(menu.type)) ) From c7b7763d02626d9c0e69fa2fe7b4c6ea0721941b Mon Sep 17 00:00:00 2001 From: basssy Date: Fri, 28 Feb 2025 13:10:19 +0900 Subject: [PATCH 193/352] =?UTF-8?q?=EB=8F=84=EB=A9=B4=EC=9E=91=EC=84=B1=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=EC=8B=9C=20selectedMenu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/management/StuffSubHeader.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/management/StuffSubHeader.jsx b/src/components/management/StuffSubHeader.jsx index 8f0df06c..14cc6d9b 100644 --- a/src/components/management/StuffSubHeader.jsx +++ b/src/components/management/StuffSubHeader.jsx @@ -60,7 +60,7 @@ export default function StuffSubHeader({ type }) { * 1.물건작성하고 바로 -> planList 생성전. surface * 2.물건이 여러건있을때 1번 플랜의 estimateDate 여부로 selectedMenu 셋팅 */ - if (managementState?.planList.length === 0) { + if (managementState?.planList?.length === 0) { setSelectedMenu('surface') } else { if (managementState?.planList[0].estimateDate) { From 4040b7b5a8164c651bcae81fc3a56ab4e36a4c2c Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Fri, 28 Feb 2025 14:22:08 +0900 Subject: [PATCH 194/352] =?UTF-8?q?context=EC=97=90=EC=84=9C=20=EC=84=9C?= =?UTF-8?q?=EA=B9=8C=EB=9E=98=20=EB=B3=80=EA=B2=BD=20=EC=95=88=EB=90=98?= =?UTF-8?q?=EB=8A=94=20=ED=98=84=EC=83=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/roofAllocation/ContextRoofAllocationSetting.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx b/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx index e1846f33..eb76dcb8 100644 --- a/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx +++ b/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx @@ -139,6 +139,7 @@ export default function ContextRoofAllocationSetting(props) { showKey={'clCodeNm'} sourceKey={'clCode'} targetKey={roof.raft ? 'raft' : 'raftBaseCd'} + onChange={(e) => handleChangeRaft(e, index)} /> )} From a63cf6d996d66cc4bc70c339c301dc955f1dde89 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Fri, 28 Feb 2025 14:53:22 +0900 Subject: [PATCH 195/352] =?UTF-8?q?#863=20=EC=A7=80=EB=B6=95=EC=9E=AC=20?= =?UTF-8?q?=ED=95=98=EB=82=98=EB=A1=9C=20=ED=86=B5=EC=9D=BC=EB=90=98?= =?UTF-8?q?=EB=8A=94=20=ED=98=84=EC=83=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/common/useRoofFn.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/hooks/common/useRoofFn.js b/src/hooks/common/useRoofFn.js index 3707af74..fdb7f4ba 100644 --- a/src/hooks/common/useRoofFn.js +++ b/src/hooks/common/useRoofFn.js @@ -22,14 +22,8 @@ export function useRoofFn() { const { addPitchText } = useLine() //면형상 선택 클릭시 지붕 패턴 입히기 - function setSurfaceShapePattern( - polygon, - mode = 'onlyBorder', - trestleMode = false, - roofMaterial = selectedRoofMaterial, - isForceChange = false, - isDisplay = false, - ) { + function setSurfaceShapePattern(polygon, mode = 'onlyBorder', trestleMode = false, roofMaterial, isForceChange = false, isDisplay = false) { + debugger if (!polygon) { return } @@ -41,6 +35,9 @@ export function useRoofFn() { polygon.roofMaterial = null }*/ } + if (!roofMaterial) { + roofMaterial = polygon.roofMaterial ?? selectedRoofMaterial + } const ratio = window.devicePixelRatio || 1 const layout = roofMaterial.layout From ebcd3222da6937f016d93f2f07fc45fe96dc92d9 Mon Sep 17 00:00:00 2001 From: basssy Date: Fri, 28 Feb 2025 16:07:42 +0900 Subject: [PATCH 196/352] =?UTF-8?q?=EB=AC=BC=EA=B1=B4=20=EC=A6=90=EA=B2=A8?= =?UTF-8?q?=EC=B0=BE=EA=B8=B0=20style?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/management/StuffDetail.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index 5915fb38..f4d7fbd4 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -2547,6 +2547,7 @@ export default function StuffDetail() { value={otherSaleStoreList.filter(function (option) { return option.saleStoreId === otherSelOptions })} + components={{ Option: CustomOption2 }} />
From 200cdff8cf276acd551640670b7c80de7fc3d9b8 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Fri, 28 Feb 2025 16:37:22 +0900 Subject: [PATCH 197/352] =?UTF-8?q?debugger=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/common/useRoofFn.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hooks/common/useRoofFn.js b/src/hooks/common/useRoofFn.js index fdb7f4ba..c49128e7 100644 --- a/src/hooks/common/useRoofFn.js +++ b/src/hooks/common/useRoofFn.js @@ -23,7 +23,6 @@ export function useRoofFn() { //면형상 선택 클릭시 지붕 패턴 입히기 function setSurfaceShapePattern(polygon, mode = 'onlyBorder', trestleMode = false, roofMaterial, isForceChange = false, isDisplay = false) { - debugger if (!polygon) { return } From 3e3ec323c42a1015903f61e4d4eec0121b38eb47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Fri, 28 Feb 2025 16:41:59 +0900 Subject: [PATCH 198/352] =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EC=A0=95=EB=A0=AC?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModule.js | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/hooks/module/useModule.js b/src/hooks/module/useModule.js index 50e8e091..49fef2be 100644 --- a/src/hooks/module/useModule.js +++ b/src/hooks/module/useModule.js @@ -854,14 +854,6 @@ export function useModule() { } const alignModule = (type, surfaceArray) => { - if (activeModule.circuit) { - swalFire({ - title: getMessage('can.not.remove.module'), - icon: 'error', - type: 'alert', - }) - return - } surfaceArray.forEach((surface) => { const modules = surface.modules @@ -950,6 +942,7 @@ export function useModule() { canvas.remove(module) }) }) + canvas.renderAll() setModuleStatisticsData() } From 77ec18c05bc2ef74c802e03f64964a1bcd3e2ab4 Mon Sep 17 00:00:00 2001 From: basssy Date: Fri, 28 Feb 2025 16:44:09 +0900 Subject: [PATCH 199/352] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EB=B3=B5?= =?UTF-8?q?=EC=82=AC=20=EB=8B=B4=EB=8B=B9=EC=9E=90=20=EC=9E=90=EB=A6=AC?= =?UTF-8?q?=EC=88=98=20=EC=B2=B4=ED=81=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../estimate/useEstimateController.js | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index 4a3bf0c2..9c00d5bb 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -437,7 +437,12 @@ export const useEstimateController = (planNo, flag) => { type: 'alert', icon: 'warning', }) + } else { + if (checkLength(copyReceiveUser.trim()) > 10) { + return swalFire({ text: getMessage('stuff.detail.tempSave.message2'), type: 'alert', icon: 'warning' }) + } } + const params = { saleStoreId: session.storeId, sapSalesStoreCd: session.custCd, @@ -469,6 +474,22 @@ export const useEstimateController = (planNo, flag) => { }) } + const checkLength = (value) => { + let str = new String(value) + let _byte = 0 + if (str.length !== 0) { + for (let i = 0; i < str.length; i++) { + let str2 = str.charAt(i) + if (encodeURIComponent(str2).length > 4) { + _byte += 2 + } else { + _byte++ + } + } + } + return _byte + } + return { estimateContextState, setEstimateContextState, From 58ebe7e32bfed93c11380cc48fbebb0a7027660d Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Fri, 28 Feb 2025 17:07:06 +0900 Subject: [PATCH 200/352] =?UTF-8?q?angleType=20=EA=B2=80=EC=82=AC=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/basic/step/ModuleTabContents.jsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/floor-plan/modal/basic/step/ModuleTabContents.jsx b/src/components/floor-plan/modal/basic/step/ModuleTabContents.jsx index 75c8dcd9..7cdef358 100644 --- a/src/components/floor-plan/modal/basic/step/ModuleTabContents.jsx +++ b/src/components/floor-plan/modal/basic/step/ModuleTabContents.jsx @@ -3,10 +3,13 @@ import { useMessage } from '@/hooks/useMessage' import { isObjectNotEmpty } from '@/util/common-utils' import QSelectBox from '@/components/common/select/QSelectBox' import { useModuleTabContents } from '@/hooks/module/useModuleTabContents' +import { useRecoilValue } from 'recoil' +import { ANGLE_TYPE, currentAngleTypeSelector } from '@/store/canvasAtom' export default function ModuleTabContents({ tabIndex, addRoof, setAddedRoofs, roofTab, tempModuleSelectionData, setTempModuleSelectionData }) { const { getMessage } = useMessage() const [roofMaterial, setRoofMaterial] = useState(addRoof) //지붕재` + const currentAngleType = useRecoilValue(currentAngleTypeSelector) const { raftCodes, @@ -45,7 +48,7 @@ export default function ModuleTabContents({ tabIndex, addRoof, setAddedRoofs, ro
{getMessage('modal.module.basic.setting.module.roof.material')}:{roofMaterial.nameJp}( - {addRoof.roofAngleSet === 'slope' ? roofMaterial.pitch : roofMaterial.angle} + {currentAngleType === ANGLE_TYPE.SLOPE ? roofMaterial.pitch : roofMaterial.angle} {globalPitchText})
From 58c401b17520afacea16d2ecac1a4e22bc9799a0 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Fri, 28 Feb 2025 17:10:47 +0900 Subject: [PATCH 201/352] =?UTF-8?q?[=EC=A7=80=EB=B6=95=EB=8D=AE=EA=B0=9C]?= =?UTF-8?q?=20=EC=9E=90=EB=8F=99=ED=98=95=EC=83=81=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?-=20=EB=B3=80=EB=B3=84=EB=A1=9C=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=ED=99=95=EC=9D=B8=20=EC=9A=94=EC=B2=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/roofcover/useRoofShapeSetting.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/hooks/roofcover/useRoofShapeSetting.js b/src/hooks/roofcover/useRoofShapeSetting.js index 178f7da8..6c1adc23 100644 --- a/src/hooks/roofcover/useRoofShapeSetting.js +++ b/src/hooks/roofcover/useRoofShapeSetting.js @@ -215,9 +215,13 @@ export function useRoofShapeSetting(id) { } case 4: { outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') - + let isValid = outerLines.every((line) => line.attributes?.isFixed) + if (!isValid) { + swalFire({ text: '설정이 완료되지 않았습니다.', icon: 'error' }) + return + } const pitch = outerLines.find((line) => line.attributes.type === LINE_TYPE.WALLLINE.SHED)?.attributes.pitch - let isValid = outerLines.every((line) => line.attributes.isFixed) + // 변별로 설정중 한쪽흐름일 경우 한쪽흐름의 pitch로 설정 if (pitch) { outerLines.forEach((line) => { @@ -230,10 +234,6 @@ export function useRoofShapeSetting(id) { } }) } - if (!isValid) { - swalFire({ text: '설정이 완료되지 않았습니다.', icon: 'error' }) - return - } break } From b87048552c3f9cc98dd3ba5daf45332fc2efe732 Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 4 Mar 2025 09:37:12 +0900 Subject: [PATCH 202/352] #868 --- src/components/management/StuffSubHeader.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/management/StuffSubHeader.jsx b/src/components/management/StuffSubHeader.jsx index 14cc6d9b..f130b729 100644 --- a/src/components/management/StuffSubHeader.jsx +++ b/src/components/management/StuffSubHeader.jsx @@ -41,7 +41,7 @@ export default function StuffSubHeader({ type }) { } } } - }, [managementState]) + }, [managementState?.createSaleStoreId]) const searchParams = useSearchParams() const objectNo = searchParams.get('objectNo') //url에서 물건번호 꺼내서 바로 set From 95c5a99aa777d33bd509aafdb7f6476d41fb3bf9 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Tue, 4 Mar 2025 10:17:54 +0900 Subject: [PATCH 203/352] =?UTF-8?q?alert=20=EB=AC=B8=EA=B5=AC=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/roofcover/useRoofShapeSetting.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/roofcover/useRoofShapeSetting.js b/src/hooks/roofcover/useRoofShapeSetting.js index 6c1adc23..1167aac9 100644 --- a/src/hooks/roofcover/useRoofShapeSetting.js +++ b/src/hooks/roofcover/useRoofShapeSetting.js @@ -217,7 +217,7 @@ export function useRoofShapeSetting(id) { outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') let isValid = outerLines.every((line) => line.attributes?.isFixed) if (!isValid) { - swalFire({ text: '설정이 완료되지 않았습니다.', icon: 'error' }) + swalFire({ text: getMessage('modal.canvas.setting.roofline.properties.setting.not.setting'), type: 'alert', icon: 'warning' }) return } const pitch = outerLines.find((line) => line.attributes.type === LINE_TYPE.WALLLINE.SHED)?.attributes.pitch From 4953ebb0d9037ca27235434075371fea68bf345e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Tue, 4 Mar 2025 10:37:07 +0900 Subject: [PATCH 204/352] =?UTF-8?q?unmount=EC=8B=9C=20clone=20line=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/surface/useRoofLinePropertySetting.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/hooks/surface/useRoofLinePropertySetting.js b/src/hooks/surface/useRoofLinePropertySetting.js index 97097135..6115f76e 100644 --- a/src/hooks/surface/useRoofLinePropertySetting.js +++ b/src/hooks/surface/useRoofLinePropertySetting.js @@ -47,8 +47,14 @@ export function useRoofLinePropertySetting(props) { } }, [currentObject]) + useEffect(() => { + return () => { + canvas.remove(...canvas.getObjects().filter((obj) => obj.name === 'cloneRoofLine')) + canvas.renderAll() + } + }, []) + const roofLinesInit = () => { - console.log('🚀 ~ roofLinesInit ~ roof:', roof) roof.lines.forEach((line) => { line.clone((cloned) => { cloned.set({ @@ -62,6 +68,9 @@ export function useRoofLinePropertySetting(props) { }) line.set({ visible: false, + attributes: { + ...line.attributes, + }, }) canvas.add(cloned) cloned.bringToFront() @@ -142,7 +151,6 @@ export function useRoofLinePropertySetting(props) { const handleFix = () => { // const roof = canvas.getObjects().find((obj) => currentObject.parentId === obj.id) // const notSettingLines = roof.lines.filter( - console.log(canvas.getObjects().filter((obj) => obj.name === 'cloneRoofLine')) const notSettingLines = canvas .getObjects() .filter((obj) => obj.name === 'cloneRoofLine') @@ -188,7 +196,6 @@ export function useRoofLinePropertySetting(props) { // const roof = canvas.getObjects().find((obj) => currentObject.parentId === obj.id) // const lines = roof?.lines const lines = canvas.getObjects().filter((obj) => obj.name === 'cloneRoofLine') - console.log('🚀 ~ nextLineFocus ~ lines:', lines) if (!lines) return const index = lines.findIndex((line) => line === selectedLine) From 6bc777b2c11bfecef059ab0d8c210aaab162b5c6 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Tue, 4 Mar 2025 11:27:29 +0900 Subject: [PATCH 205/352] =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EC=B4=88=EA=B8=B0?= =?UTF-8?q?=ED=99=94=EC=8B=9C=20=ED=8C=A8=ED=84=B4=20=EC=9D=BC=EA=B4=84=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD,=20=EC=84=A0=ED=83=9D=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EC=97=86=EC=9D=84=EA=B2=BD=EC=9A=B0=20=EB=AA=A8?= =?UTF-8?q?=EB=93=88=20=EC=B2=98=EC=9D=8C=20=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=EB=A1=9C=20=ED=98=B8=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/modal/basic/step/Placement.jsx | 2 +- src/hooks/module/useModuleBasicSetting.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/floor-plan/modal/basic/step/Placement.jsx b/src/components/floor-plan/modal/basic/step/Placement.jsx index 2b0e9c03..d4b979c7 100644 --- a/src/components/floor-plan/modal/basic/step/Placement.jsx +++ b/src/components/floor-plan/modal/basic/step/Placement.jsx @@ -59,7 +59,7 @@ const Placement = forwardRef((props, refs) => { } //모듈 배치면 생성 - if (moduleSelectionData.module.itemList.length > 1) { + if (isObjectNotEmpty(moduleSelectionData.module) && moduleSelectionData.module.itemList.length > 1) { setIsMultiModule(true) } } diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 3deee779..a7a03c42 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -407,7 +407,7 @@ export function useModuleBasicSetting(tabNum) { //지붕패턴 변경 const roofs = canvas.getObjects().filter((obj) => obj.name === 'roof') roofs.forEach((roof) => { - setSurfaceShapePattern(roof, roofDisplay.column, false) //패턴 변경 + setSurfaceShapePattern(roof, roofDisplay.column, false, roof.roofMaterial) //패턴 변경 }) } From 432604ed55e0b478ea8b948e2edcc2f36256c185 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Tue, 4 Mar 2025 11:28:02 +0900 Subject: [PATCH 206/352] =?UTF-8?q?raft=20=EC=84=A4=EC=A0=95=20=EB=88=84?= =?UTF-8?q?=EB=9D=BD=20=EC=8B=9C=20=EA=B8=B0=EB=B3=B8=EA=B0=92=20=EC=84=B8?= =?UTF-8?q?=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/roofcover/useRoofAllocationSetting.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js index 93f51514..9d0a850a 100644 --- a/src/hooks/roofcover/useRoofAllocationSetting.js +++ b/src/hooks/roofcover/useRoofAllocationSetting.js @@ -289,7 +289,7 @@ export function useRoofAllocationSetting(id) { const handleSaveContext = () => { basicSettingSave() const newRoofList = currentRoofList.map((roof, idx) => { - return { ...roof, index: idx } + return { ...roof, index: idx, raft: roof.raft ? roof.raft : roof.raftBaseCd } }) setBasicSetting((prev) => { return { @@ -379,7 +379,7 @@ export function useRoofAllocationSetting(id) { /** 데이터 설정 */ const newRoofList = currentRoofList.map((roof, idx) => { - return { ...roof, index: idx, ...basicInfo } + return { ...roof, index: idx, ...basicInfo, raft: roof.raft ? roof.raft : roof.raftBaseCd } }) setBasicSetting((prev) => { From ff7eb367625609998404ccc0e8cd036911f0f57d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Tue, 4 Mar 2025 11:29:06 +0900 Subject: [PATCH 207/352] =?UTF-8?q?=EB=B9=A0=EC=A7=84=20=EB=8B=A4=EA=B5=AD?= =?UTF-8?q?=EC=96=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/object/type/PentagonDormer.jsx | 2 +- .../modal/object/type/TriangleDormer.jsx | 2 +- src/hooks/useContextMenu.js | 17 +++++------------ src/locales/ja.json | 8 ++++---- 4 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/components/floor-plan/modal/object/type/PentagonDormer.jsx b/src/components/floor-plan/modal/object/type/PentagonDormer.jsx index 87a92835..9d82485c 100644 --- a/src/components/floor-plan/modal/object/type/PentagonDormer.jsx +++ b/src/components/floor-plan/modal/object/type/PentagonDormer.jsx @@ -73,7 +73,7 @@ const PentagonDormer = forwardRef((props, refs) => {
-
{getMessage('slope')}
+
{getMessage('modal.object.setting.offset.slope')}
diff --git a/src/components/floor-plan/modal/object/type/TriangleDormer.jsx b/src/components/floor-plan/modal/object/type/TriangleDormer.jsx index 62fd729d..65fed20b 100644 --- a/src/components/floor-plan/modal/object/type/TriangleDormer.jsx +++ b/src/components/floor-plan/modal/object/type/TriangleDormer.jsx @@ -48,7 +48,7 @@ const TriangleDormer = forwardRef((props, refs) => {
-
{getMessage('slope')}
+
{getMessage('modal.object.setting.offset.slope')}
diff --git a/src/hooks/useContextMenu.js b/src/hooks/useContextMenu.js index f1cb43e4..731d7476 100644 --- a/src/hooks/useContextMenu.js +++ b/src/hooks/useContextMenu.js @@ -42,6 +42,7 @@ import { useAdsorptionPoint } from './useAdsorptionPoint' import { useRoofFn } from '@/hooks/common/useRoofFn' import { MODULE_ALIGN_TYPE, useModule } from './module/useModule' import PlacementSurfaceLineProperty from '@/components/floor-plan/modal/placementShape/PlacementSurfaceLineProperty' +import { selectedMenuState } from '@/store/menuAtom' export function useContextMenu() { const canvas = useRecoilValue(canvasState) @@ -71,10 +72,11 @@ export function useContextMenu() { const { swalFire } = useSwal() const { alignModule, modulesRemove, moduleRoofRemove } = useModule() const { removeRoofMaterial, removeAllRoofMaterial, moveRoofMaterial, removeOuterLines } = useRoofFn() + const selectedMenu = useRecoilValue(selectedMenuState) const currentMenuSetting = () => { - switch (currentMenu) { - case MENU.PLAN_DRAWING: + switch (selectedMenu) { + case 'placement': setContextMenu([ [ { @@ -115,16 +117,7 @@ export function useContextMenu() { ], ]) break - case MENU.ROOF_COVERING.EXTERIOR_WALL_LINE: - case MENU.ROOF_COVERING.ROOF_SHAPE_SETTINGS: - case MENU.ROOF_COVERING.ROOF_SHAPE_PASSIVITY_SETTINGS: - case MENU.ROOF_COVERING.ROOF_SHAPE_EDITING: - case MENU.ROOF_COVERING.HELP_LINE_DRAWING: - case MENU.ROOF_COVERING.EAVES_KERAVA_EDIT: - case MENU.ROOF_COVERING.MOVEMENT_SHAPE_UPDOWN: - case MENU.ROOF_COVERING.OUTLINE_EDIT_OFFSET: - case MENU.ROOF_COVERING.ROOF_SHAPE_ALLOC: - case MENU.ROOF_COVERING.DEFAULT: + case 'outline': setContextMenu([ [ { diff --git a/src/locales/ja.json b/src/locales/ja.json index 52ebfeba..ecaab098 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -294,9 +294,9 @@ "modal.object.setting.size.setting": "サイズ設定", "modal.object.setting.agreement.depth": "棟の長さ・深さ", "modal.object.setting.offset.depth": "出幅(深さ)", - "modal.object.setting.size.width": "", + "modal.object.setting.size.width": "幅", "modal.object.setting.offset.width": "出幅(幅)", - "modal.object.setting.offset.slope": "", + "modal.object.setting.offset.slope": "勾配", "modal.object.setting.direction.select": "方向の選択", "modal.placement.surface.setting.info": "ⓘ①の長さ入力後、対角線長を入力すると②の長さを自動計算します。", "modal.placement.surface.setting.diagonal.length": "斜めの長さ", @@ -1015,8 +1015,8 @@ "module.place.select.one.module": "モジュールは1つだけ選択してください。", "batch.canvas.delete.all": "配置面の内容をすべて削除しますか?", "module.not.found": "インストールモジュールを選択してください。", - "module.circuit.minimun.error": "", - "module.already.exist.error": "", + "module.circuit.minimun.error": "회로번호는 1 이상입력해주세요.(JA)", + "module.already.exist.error": "회로번호가 같은 다른 파워 컨디셔너 모듈이 있습니다. 다른 회로번호를 설정하십시오.(JA)", "construction.length.difference": "屋根面工法をすべて選択してください。", "menu.validation.canvas.roof": "パネルを配置するには、屋根面を入力する必要があります。", "batch.object.outside.roof": "オブジェクトは屋根に設置する必要があります。", From fad86d45853c7ddc4f4ccd64fbae9014e8e9c029 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Tue, 4 Mar 2025 13:14:03 +0900 Subject: [PATCH 208/352] =?UTF-8?q?currentObject=EB=B3=84=20context?= =?UTF-8?q?=EB=A9=94=EB=89=B4=EC=97=90=20=EC=84=A0=ED=83=9D=20menu=20?= =?UTF-8?q?=EB=B6=84=EA=B8=B0=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useContextMenu.js | 463 ++++++++++++++++++------------------ 1 file changed, 237 insertions(+), 226 deletions(-) diff --git a/src/hooks/useContextMenu.js b/src/hooks/useContextMenu.js index 731d7476..97e9cf6c 100644 --- a/src/hooks/useContextMenu.js +++ b/src/hooks/useContextMenu.js @@ -118,145 +118,8 @@ export function useContextMenu() { ]) break case 'outline': - setContextMenu([ - [ - { - id: 'roofMaterialPlacement', - name: getMessage('contextmenu.roof.material.placement'), - component: , - }, - - { - id: 'roofMaterialRemoveAll', - name: getMessage('contextmenu.roof.material.remove.all'), - fn: () => removeAllRoofMaterial(), - }, - { - id: 'selectMove', - name: getMessage('contextmenu.select.move'), - fn: (currentMousePos) => { - moveRoofMaterial(currentMousePos) - }, - }, - { - id: 'wallLineRemove', - name: getMessage('contextmenu.wallline.remove'), - fn: (currentMousePos) => { - removeOuterLines(currentMousePos) - }, - }, - ], - [ - { - id: 'sizeEdit', - name: getMessage('contextmenu.size.edit'), - component: , - }, - { - id: 'auxiliaryMove', - name: `${getMessage('contextmenu.auxiliary.move')}(M)`, - shortcut: ['m', 'M'], - component: , - }, - { - id: 'auxiliaryCopy', - name: `${getMessage('contextmenu.auxiliary.copy')}(C)`, - shortcut: ['c', 'C'], - component: , - }, - { - id: 'auxiliaryRemove', - shortcut: ['d', 'D'], - name: `${getMessage('contextmenu.auxiliary.remove')}(D)`, - fn: () => { - if (!currentObject) return - const roof = canvas.getObjects().filter((obj) => obj.id === currentObject.attributes.roofId)[0] - if (!roof) { - // 아직 innerLines로 세팅이 안되어있는 line인 경우 제거 - canvas.remove(currentObject) - canvas.discardActiveObject() - return - } - const innerLines = roof.innerLines?.filter((line) => currentObject.id !== line.id) - roof.innerLines = [...innerLines] - canvas.remove(currentObject) - canvas.discardActiveObject() - }, - }, - { - id: 'auxiliaryVerticalBisector', - name: getMessage('contextmenu.auxiliary.vertical.bisector'), - fn: () => { - if (!currentObject) return - const slope = (currentObject.y2 - currentObject.y1) / (currentObject.x2 - currentObject.x1) - const length = currentObject.length - - let startX, startY, endX, endY - if (slope === 0) { - startX = endX = (currentObject.x1 + currentObject.x2) / 2 - startY = currentObject.y2 - length / 2 - endY = currentObject.y2 + length / 2 - } else if (slope === Infinity) { - startX = currentObject.x1 - length / 2 - startY = endY = (currentObject.y1 + currentObject.y2) / 2 - endX = currentObject.x1 + length / 2 - } else { - const bisectorSlope = -1 / slope - const dx = length / 2 / Math.sqrt(1 + bisectorSlope * bisectorSlope) - const dy = bisectorSlope * dx - - startX = (currentObject.x1 + currentObject.x2) / 2 + dx - startY = (currentObject.y1 + currentObject.y2) / 2 + dy - endX = (currentObject.x1 + currentObject.x2) / 2 - dx - endY = (currentObject.y1 + currentObject.y2) / 2 - dy - } - - const line = addLine([startX, startY, endX, endY], { - stroke: 'red', - strokeWidth: 1, - selectable: true, - name: 'auxiliaryLine', - attributes: { ...currentObject.attributes }, - }) - - if (!currentObject.attributes.roofId) { - return - } - - canvas - .getObjects() - .filter((obj) => obj.id === currentObject.attributes.roofId)[0] - .innerLines.push(line) - }, - }, - { - id: 'auxiliaryRemoveAll', - name: getMessage('contextmenu.auxiliary.remove.all'), - fn: () => { - if (!currentObject) { - swalFire({ text: getMessage('roof.is.not.selected') }) - return - } - const innerLines = canvas.getObjects().filter((obj) => obj.id === currentObject.attributes.roofId)[0]?.innerLines - if (innerLines) { - innerLines.forEach((line) => { - canvas.remove(line) - }) - innerLines.length = 0 - } - - // 확정되지 않은 보조선 - const notFixedAuxiliaryLines = canvas.getObjects().filter((obj) => obj.name === 'auxiliaryLine' && !obj.isAuxiliaryFixed) - - notFixedAuxiliaryLines.forEach((line) => { - canvas.remove(line) - }) - - canvas.renderAll() - }, - }, - ], - ]) + if (['roof', 'auxiliaryLine'].includes(currentObject?.name)) { + } break default: setContextMenu([]) @@ -305,96 +168,244 @@ export function useContextMenu() { switch (currentObject.name) { case 'triangleDormer': case 'pentagonDormer': - setContextMenu([ - [ - { - id: 'sizeEdit', - name: getMessage('contextmenu.size.edit'), - component: , - }, - { - id: 'dormerRemove', - shortcut: ['d', 'D'], - name: `${getMessage('contextmenu.remove')}(D)`, - fn: () => deleteObject(), - }, - { - id: 'dormerMove', - shortcut: ['m', 'M'], - name: `${getMessage('contextmenu.move')}(M)`, - fn: () => moveObjectBatch(), - }, - { - id: 'dormerCopy', - shortcut: ['c', 'C'], - name: `${getMessage('contextmenu.copy')}(C)`, - fn: () => copyObject(), - }, - { - id: 'roofMaterialEdit', - name: getMessage('contextmenu.roof.material.edit'), - component: , - }, - { - id: 'dormerOffset', - name: getMessage('contextmenu.dormer.offset'), - component: , - }, - ], - ]) + if (selectedMenu === 'surface') { + setContextMenu([ + [ + { + id: 'sizeEdit', + name: getMessage('contextmenu.size.edit'), + component: , + }, + { + id: 'dormerRemove', + shortcut: ['d', 'D'], + name: `${getMessage('contextmenu.remove')}(D)`, + fn: () => deleteObject(), + }, + { + id: 'dormerMove', + shortcut: ['m', 'M'], + name: `${getMessage('contextmenu.move')}(M)`, + fn: () => moveObjectBatch(), + }, + { + id: 'dormerCopy', + shortcut: ['c', 'C'], + name: `${getMessage('contextmenu.copy')}(C)`, + fn: () => copyObject(), + }, + { + id: 'roofMaterialEdit', + name: getMessage('contextmenu.roof.material.edit'), + component: , + }, + { + id: 'dormerOffset', + name: getMessage('contextmenu.dormer.offset'), + component: , + }, + ], + ]) + } break case 'roof': - setContextMenu([ - [ - { - id: 'sizeEdit', - name: getMessage('contextmenu.size.edit'), - component: , - }, - { - id: 'roofMaterialRemove', - shortcut: ['d', 'D'], - name: `${getMessage('contextmenu.remove')}(D)`, - fn: () => deleteObject(), - }, - { - id: 'roofMaterialMove', - shortcut: ['m', 'M'], - name: `${getMessage('contextmenu.move')}(M)`, - fn: () => moveSurfaceShapeBatch(), - }, - { - id: 'roofMaterialCopy', - shortcut: ['c', 'C'], - name: `${getMessage('contextmenu.copy')}(C)`, - fn: () => copyObject(), - }, - ], - [ - { - id: 'roofMaterialEdit', - name: getMessage('contextmenu.roof.material.edit'), - component: , - }, - { - id: 'linePropertyEdit', - name: getMessage('contextmenu.line.property.edit'), - fn: () => { - if (+canvasSetting.roofSizeSet === 3) { - swalFire({ text: getMessage('contextmenu.line.property.edit.roof.size.3') }) - } else { - addPopup(popupId, 1, ) - } + case 'auxiliaryLine': + case 'hip': + case 'ridge': + if (selectedMenu === 'surface') { + setContextMenu([ + [ + { + id: 'sizeEdit', + name: getMessage('contextmenu.size.edit'), + component: , }, - // component: , - }, - { - id: 'flowDirectionEdit', - name: getMessage('contextmenu.flow.direction.edit'), - component: , - }, - ], - ]) + { + id: 'roofMaterialRemove', + shortcut: ['d', 'D'], + name: `${getMessage('contextmenu.remove')}(D)`, + fn: () => deleteObject(), + }, + { + id: 'roofMaterialMove', + shortcut: ['m', 'M'], + name: `${getMessage('contextmenu.move')}(M)`, + fn: () => moveSurfaceShapeBatch(), + }, + { + id: 'roofMaterialCopy', + shortcut: ['c', 'C'], + name: `${getMessage('contextmenu.copy')}(C)`, + fn: () => copyObject(), + }, + ], + [ + { + id: 'roofMaterialEdit', + name: getMessage('contextmenu.roof.material.edit'), + component: , + }, + { + id: 'linePropertyEdit', + name: getMessage('contextmenu.line.property.edit'), + fn: () => { + if (+canvasSetting.roofSizeSet === 3) { + swalFire({ text: getMessage('contextmenu.line.property.edit.roof.size.3') }) + } else { + addPopup(popupId, 1, ) + } + }, + // component: , + }, + { + id: 'flowDirectionEdit', + name: getMessage('contextmenu.flow.direction.edit'), + component: , + }, + ], + ]) + } else if (selectedMenu === 'outline') { + setContextMenu([ + [ + { + id: 'roofMaterialPlacement', + name: getMessage('contextmenu.roof.material.placement'), + component: , + }, + + { + id: 'roofMaterialRemoveAll', + name: getMessage('contextmenu.roof.material.remove.all'), + fn: () => removeAllRoofMaterial(), + }, + { + id: 'selectMove', + name: getMessage('contextmenu.select.move'), + fn: (currentMousePos) => { + moveRoofMaterial(currentMousePos) + }, + }, + { + id: 'wallLineRemove', + name: getMessage('contextmenu.wallline.remove'), + fn: (currentMousePos) => { + removeOuterLines(currentMousePos) + }, + }, + ], + [ + { + id: 'sizeEdit', + name: getMessage('contextmenu.size.edit'), + component: , + }, + { + id: 'auxiliaryMove', + name: `${getMessage('contextmenu.auxiliary.move')}(M)`, + shortcut: ['m', 'M'], + component: , + }, + { + id: 'auxiliaryCopy', + name: `${getMessage('contextmenu.auxiliary.copy')}(C)`, + shortcut: ['c', 'C'], + component: , + }, + { + id: 'auxiliaryRemove', + shortcut: ['d', 'D'], + name: `${getMessage('contextmenu.auxiliary.remove')}(D)`, + fn: () => { + if (!currentObject) return + const roof = canvas.getObjects().filter((obj) => obj.id === currentObject.attributes.roofId)[0] + if (!roof) { + // 아직 innerLines로 세팅이 안되어있는 line인 경우 제거 + canvas.remove(currentObject) + canvas.discardActiveObject() + return + } + const innerLines = roof.innerLines?.filter((line) => currentObject.id !== line.id) + roof.innerLines = [...innerLines] + canvas.remove(currentObject) + canvas.discardActiveObject() + }, + }, + { + id: 'auxiliaryVerticalBisector', + name: getMessage('contextmenu.auxiliary.vertical.bisector'), + fn: () => { + if (!currentObject) return + const slope = (currentObject.y2 - currentObject.y1) / (currentObject.x2 - currentObject.x1) + const length = currentObject.length + + let startX, startY, endX, endY + if (slope === 0) { + startX = endX = (currentObject.x1 + currentObject.x2) / 2 + startY = currentObject.y2 - length / 2 + endY = currentObject.y2 + length / 2 + } else if (slope === Infinity) { + startX = currentObject.x1 - length / 2 + startY = endY = (currentObject.y1 + currentObject.y2) / 2 + endX = currentObject.x1 + length / 2 + } else { + const bisectorSlope = -1 / slope + const dx = length / 2 / Math.sqrt(1 + bisectorSlope * bisectorSlope) + const dy = bisectorSlope * dx + + startX = (currentObject.x1 + currentObject.x2) / 2 + dx + startY = (currentObject.y1 + currentObject.y2) / 2 + dy + endX = (currentObject.x1 + currentObject.x2) / 2 - dx + endY = (currentObject.y1 + currentObject.y2) / 2 - dy + } + + const line = addLine([startX, startY, endX, endY], { + stroke: 'red', + strokeWidth: 1, + selectable: true, + name: 'auxiliaryLine', + attributes: { ...currentObject.attributes }, + }) + + if (!currentObject.attributes.roofId) { + return + } + + canvas + .getObjects() + .filter((obj) => obj.id === currentObject.attributes.roofId)[0] + .innerLines.push(line) + }, + }, + { + id: 'auxiliaryRemoveAll', + name: getMessage('contextmenu.auxiliary.remove.all'), + fn: () => { + if (!currentObject) { + swalFire({ text: getMessage('roof.is.not.selected') }) + return + } + const innerLines = canvas.getObjects().filter((obj) => obj.id === currentObject.attributes.roofId)[0]?.innerLines + if (innerLines) { + innerLines.forEach((line) => { + canvas.remove(line) + }) + innerLines.length = 0 + } + + // 확정되지 않은 보조선 + const notFixedAuxiliaryLines = canvas.getObjects().filter((obj) => obj.name === 'auxiliaryLine' && !obj.isAuxiliaryFixed) + + notFixedAuxiliaryLines.forEach((line) => { + canvas.remove(line) + }) + + canvas.renderAll() + }, + }, + ], + ]) + } + break case 'opening': setContextMenu([ From 93d4db89d5a95f841fb031f0ba6e8bc905a04ad5 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Tue, 4 Mar 2025 13:15:51 +0900 Subject: [PATCH 209/352] =?UTF-8?q?=EB=B2=88=EC=97=AD=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/roofcover/useRoofAllocationSetting.js | 2 +- src/locales/ja.json | 3 ++- src/locales/ko.json | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js index 9d0a850a..671d4c7e 100644 --- a/src/hooks/roofcover/useRoofAllocationSetting.js +++ b/src/hooks/roofcover/useRoofAllocationSetting.js @@ -239,7 +239,7 @@ export function useRoofAllocationSetting(id) { */ const onAddRoofMaterial = () => { if (currentRoofList.length >= 4) { - swalFire({ type: 'alert', icon: 'error', text: getMessage('지붕재는 4개까지 선택 가능합니다.') }) + swalFire({ type: 'alert', icon: 'error', text: getMessage('roof.exceed.count') }) return } setCurrentRoofList([ diff --git a/src/locales/ja.json b/src/locales/ja.json index ecaab098..76f16b36 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -1028,5 +1028,6 @@ "not.allocation.exist.module": "回路を割り当てていないモジュールがあります。", "roof.is.not.selected": "屋根の選択をお願いします。", "length.direction.is.required": "長さと方向を入力します。", - "canvas.infomation.text": "数字は [半角] 入力のみ可能です。" + "canvas.infomation.text": "数字は [半角] 入力のみ可能です。", + "roof.exceed.count": "屋根材は4つまで選択可能です。" } diff --git a/src/locales/ko.json b/src/locales/ko.json index eb853d83..0a1119d0 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -1028,5 +1028,6 @@ "not.allocation.exist.module": "회로를 할당하지 않은 모듈이 있습니다.", "roof.is.not.selected": "지붕을 선택해주세요.", "length.direction.is.required": "길이와 방향을 입력하세요.", - "canvas.infomation.text": "숫자는 [반각] 입력만 가능합니다." + "canvas.infomation.text": "숫자는 [반각] 입력만 가능합니다.", + "roof.exceed.count": "지붕재는 4개까지 선택 가능합니다." } From bdd3322d8c338a1a829c4379aca5f7057d3ea187 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Tue, 4 Mar 2025 14:06:15 +0900 Subject: [PATCH 210/352] =?UTF-8?q?module=20row=20remove=20=20=EC=98=A4?= =?UTF-8?q?=ED=83=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModule.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hooks/module/useModule.js b/src/hooks/module/useModule.js index 49fef2be..0896fe04 100644 --- a/src/hooks/module/useModule.js +++ b/src/hooks/module/useModule.js @@ -536,7 +536,6 @@ export function useModule() { const moduleRowRemove = (type) => { const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0] - c const rowModules = getRowModules(activeModule) const otherModules = getOtherModules(rowModules) const objects = getObjects() From aef7cafc1bf2908fd679fa7f11820e73bf556109 Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 4 Mar 2025 14:38:24 +0900 Subject: [PATCH 211/352] =?UTF-8?q?=EB=AC=BC=EA=B1=B4=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=95=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=BB=A4?= =?UTF-8?q?=EC=84=9C=20=EB=B3=B4=EC=99=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/pagination/QPagination.jsx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/components/common/pagination/QPagination.jsx b/src/components/common/pagination/QPagination.jsx index c6cab52d..8c6032b7 100644 --- a/src/components/common/pagination/QPagination.jsx +++ b/src/components/common/pagination/QPagination.jsx @@ -12,10 +12,12 @@ export default function QPagination(props) { return (
  1. - +
  2. {pageRange.map((page) => (
  3. - +
  4. ))}
  5. - +
) From edcb51e224b5f56d886b1fc3ca8796d3cde2deed Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Tue, 4 Mar 2025 14:59:39 +0900 Subject: [PATCH 212/352] =?UTF-8?q?#695=20=EC=A7=80=EB=B6=95=EC=9E=AC=20?= =?UTF-8?q?=ED=9D=90=EB=A6=84=20=ED=99=95=EC=9D=B8=20=EC=9A=94=EC=B2=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/usePolygon.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/hooks/usePolygon.js b/src/hooks/usePolygon.js index 3e706b84..3bb004cf 100644 --- a/src/hooks/usePolygon.js +++ b/src/hooks/usePolygon.js @@ -755,10 +755,7 @@ export const usePolygon = () => { // innerLine이 세팅이 안되어있는경우 찾아서 세팅한다. if (!innerLines || innerLines.length === 0) { - let innerLineTypes = [] - Object.keys(LINE_TYPE.SUBLINE).forEach((key, value) => { - innerLineTypes.push(LINE_TYPE.SUBLINE[key]) - }) + let innerLineTypes = Object.keys(LINE_TYPE.SUBLINE).map((key, value) => LINE_TYPE.SUBLINE[key]) polygon.innerLines = canvas .getObjects() .filter( @@ -1102,6 +1099,8 @@ export const usePolygon = () => { } }) + // blue로 생성된 것들은 대표라인이 될 수 없음. + representLines = representLines.filter((line) => line.stroke !== 'blue') // representLines중 가장 긴 line을 찾는다. representLines.forEach((line) => { if (!representLine) { From 6a0072b0588bbb1cd772528afb58191aa616477c Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 4 Mar 2025 15:28:43 +0900 Subject: [PATCH 213/352] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=B2=A8?= =?UTF-8?q?=EB=B6=80=ED=8C=8C=EC=9D=BC=20ppt,=20pptx=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/EstimateFileUploader.jsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/estimate/EstimateFileUploader.jsx b/src/components/estimate/EstimateFileUploader.jsx index c02d4637..b02daef1 100644 --- a/src/components/estimate/EstimateFileUploader.jsx +++ b/src/components/estimate/EstimateFileUploader.jsx @@ -28,6 +28,8 @@ export default function EstimateFileUploader({ uploadFiles, setUploadFiles }) { 'application/pdf', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.ms-excel', + 'application/vnd.openxmlformats-officedocument.presentationml.presentation', // PPTX 형식 + 'application/vnd.ms-powerpoint', // PPT 형식 ] Array.from(e.target.files).forEach((file) => { //엑셀, pdf, 이미지 @@ -61,6 +63,8 @@ export default function EstimateFileUploader({ uploadFiles, setUploadFiles }) { 'application/pdf', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.ms-excel', + 'application/vnd.openxmlformats-officedocument.presentationml.presentation', // PPTX 형식 + 'application/vnd.ms-powerpoint', // PPT 형식 ] Array.from(e.dataTransfer.files).forEach((file) => { From d031c0d6e000d4d9d6e597e5007ab92e3caae1ab Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Tue, 4 Mar 2025 16:46:11 +0900 Subject: [PATCH 214/352] =?UTF-8?q?directionText=20=EA=B8=B0=EC=A1=B4=20?= =?UTF-8?q?=EC=9E=88=EB=8D=98=20=EB=82=B4=EC=9A=A9=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 5 ++- src/hooks/module/useOrientation.js | 5 +++ src/hooks/usePolygon.js | 47 +++++++++++++----------- 3 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 63ecdef3..4ce1ec27 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -159,7 +159,7 @@ export default function CanvasMenu(props) { roof.set({ selectable: true }) setSurfaceShapePattern(roof, null, false, roof.roofMaterial) delete roof.moduleCompass - drawDirectionArrow(roof) + drawDirectionArrow(roof, false) }) } @@ -184,13 +184,13 @@ export default function CanvasMenu(props) { break case 'surface': const modules = canvas.getObjects().filter((module) => module.name === POLYGON_TYPE.MODULE) + initRoofs() if (modules.length > 0) { swalFire({ text: getMessage('module.delete.confirm'), type: 'confirm', confirmFn: () => { //해당 메뉴 이동시 배치면 삭제 - initRoofs() const moduleSurfacesArray = canvas .getObjects() @@ -204,6 +204,7 @@ export default function CanvasMenu(props) { moduleSurfacesArray.forEach((moduleSurface) => { canvas.remove(moduleSurface) }) + canvas.renderAll() onClickNav(menu) } diff --git a/src/hooks/module/useOrientation.js b/src/hooks/module/useOrientation.js index 9e57c687..9119398d 100644 --- a/src/hooks/module/useOrientation.js +++ b/src/hooks/module/useOrientation.js @@ -27,6 +27,11 @@ export function useOrientation() { setCompasDeg(0) } const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) + + roofs.forEach((roof) => { + delete roof.directionText + }) + roofs.forEach((roof) => { roof.set({ moduleCompass: isNaN(compasDeg) ? 0 : compasDeg, diff --git a/src/hooks/usePolygon.js b/src/hooks/usePolygon.js index 3bb004cf..04507c17 100644 --- a/src/hooks/usePolygon.js +++ b/src/hooks/usePolygon.js @@ -172,8 +172,9 @@ export const usePolygon = () => { /** * poolygon의 방향에 따라 화살표를 추가한다. * @param polygon + * @param showDirectionText */ - const drawDirectionArrow = (polygon) => { + const drawDirectionArrow = (polygon, showDirectionText = true) => { if (polygon.points.length < 3) { return } @@ -319,17 +320,16 @@ export const usePolygon = () => { pitch: polygon.roofMaterial?.pitch ?? 4, parentId: polygon.id, }) - arrow.setViewLengthText(false) polygon.arrow = arrow polygon.canvas.add(arrow) polygon.canvas.renderAll() - drawDirectionStringToArrow2(polygon) + drawDirectionStringToArrow2(polygon, showDirectionText) // drawDirectionStringToArrow() } //arrow의 compass 값으로 방향 글자 설정 필요 - const drawDirectionStringToArrow2 = (polygon) => { + const drawDirectionStringToArrow2 = (polygon, showDirectionText) => { const { direction, surfaceCompass, moduleCompass, arrow } = polygon if (moduleCompass === null || moduleCompass === undefined) { const textObj = new fabric.Text(`${currentAngleType === ANGLE_TYPE.SLOPE ? arrow.pitch : getDegreeByChon(arrow.pitch)}${pitchText}`, { @@ -510,24 +510,27 @@ export const usePolygon = () => { text = text + (sameDirectionCnt.length + 1) polygon.set('directionText', text) - const textObj = new fabric.Text(`${text} (${currentAngleType === ANGLE_TYPE.SLOPE ? arrow.pitch : getDegreeByChon(arrow.pitch)}${pitchText})`, { - fontFamily: flowFontOptions.fontFamily.value, - fontWeight: flowFontOptions.fontWeight.value.toLowerCase().includes('bold') ? 'bold' : 'normal', - fontStyle: flowFontOptions.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal', - fontSize: flowFontOptions.fontSize.value, - fill: flowFontOptions.fontColor.value, - pitch: arrow.pitch, - originX: 'center', - originY: 'center', - name: 'flowText', - originText: text, - selectable: false, - left: arrow.stickeyPoint.x, - top: arrow.stickeyPoint.y, - parent: arrow, - parentId: arrow.id, - visible: isFlowDisplay, - }) + const textObj = new fabric.Text( + `${showDirectionText && text} (${currentAngleType === ANGLE_TYPE.SLOPE ? arrow.pitch : getDegreeByChon(arrow.pitch)}${pitchText})`, + { + fontFamily: flowFontOptions.fontFamily.value, + fontWeight: flowFontOptions.fontWeight.value.toLowerCase().includes('bold') ? 'bold' : 'normal', + fontStyle: flowFontOptions.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal', + fontSize: flowFontOptions.fontSize.value, + fill: flowFontOptions.fontColor.value, + pitch: arrow.pitch, + originX: 'center', + originY: 'center', + name: 'flowText', + originText: text, + selectable: false, + left: arrow.stickeyPoint.x, + top: arrow.stickeyPoint.y, + parent: arrow, + parentId: arrow.id, + visible: isFlowDisplay, + }, + ) polygon.canvas.add(textObj) } From aaeae69453bf21dc2d4ff55df8c8e67b5a5e1b8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Tue, 4 Mar 2025 16:52:35 +0900 Subject: [PATCH 215/352] =?UTF-8?q?=EC=A7=80=EB=B6=95=EC=9E=AC=20=EC=A0=95?= =?UTF-8?q?=EB=A0=AC=EB=B0=A9=EC=8B=9D=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ContextRoofAllocationSetting.jsx | 23 +------------------ .../roofAllocation/RoofAllocationSetting.jsx | 6 ++--- 2 files changed, 4 insertions(+), 25 deletions(-) diff --git a/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx b/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx index eb76dcb8..37fc53bc 100644 --- a/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx +++ b/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx @@ -205,7 +205,7 @@ export default function ContextRoofAllocationSetting(props) { )}
- {getMessage('slope')} + {getMessage('modal.object.setting.offset.slope')}
{pitchText}
-
-
- - -
-
) diff --git a/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx b/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx index 965f1ec9..7723b9de 100644 --- a/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx +++ b/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx @@ -202,7 +202,7 @@ export default function RoofAllocationSetting(props) { )}
- {getMessage('slope')} + {getMessage('modal.object.setting.offset.slope')}
{pitchText}
-
+ {/*
-
+
*/}
) From 2f53c6e22ec82d0eb1d93ea1a586af4c76507cf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Tue, 4 Mar 2025 16:52:58 +0900 Subject: [PATCH 216/352] =?UTF-8?q?surface=20=EC=9E=88=EB=8A=94=20?= =?UTF-8?q?=EC=83=81=ED=83=9C=EC=97=90=EC=84=9C=20=EB=B0=B0=EC=B9=98?= =?UTF-8?q?=EB=A9=B4=EC=9C=BC=EB=A1=9C=20=EC=9D=B4=EB=8F=99=EC=8B=9C=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 63ecdef3..c97907c5 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -183,7 +183,10 @@ export default function CanvasMenu(props) { await reloadCanvasStatus(objectNo, pid) break case 'surface': - const modules = canvas.getObjects().filter((module) => module.name === POLYGON_TYPE.MODULE) + const modules = canvas + .getObjects() + .filter((obj) => [POLYGON_TYPE.MODULE_SETUP_SURFACE, POLYGON_TYPE.MODULE, POLYGON_TYPE.OBJECT_SURFACE].includes(obj.name)) + if (modules.length > 0) { swalFire({ text: getMessage('module.delete.confirm'), @@ -194,10 +197,7 @@ export default function CanvasMenu(props) { const moduleSurfacesArray = canvas .getObjects() - .filter( - (obj) => - obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE || obj.name === POLYGON_TYPE.MODULE || obj.name === POLYGON_TYPE.OBJECT_SURFACE, - ) + .filter((obj) => [POLYGON_TYPE.MODULE_SETUP_SURFACE, POLYGON_TYPE.MODULE, POLYGON_TYPE.OBJECT_SURFACE].includes(obj.name)) if (moduleSurfacesArray.length > 0) { // 모듈면 있을 경우 지붕면 할당 다시해야함 @@ -302,7 +302,6 @@ export default function CanvasMenu(props) { const settingsModalOptions = useRecoilState(settingModalFirstOptionsState) useEffect(() => { - console.log(selectedMenu) if (selectedMenu === 'placement') { onClickPlacementInitialMenu() } From 81d04ff25a4a917faefd4310c8e7fd7d3c519b73 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Tue, 4 Mar 2025 16:58:17 +0900 Subject: [PATCH 217/352] =?UTF-8?q?=EB=B3=B5=EC=82=AC=EB=90=9C=20object=20?= =?UTF-8?q?=EC=82=AC=EC=9D=B4=EC=A6=88=20=EB=B3=80=EA=B2=BD=20=EC=8B=9C=20?= =?UTF-8?q?=EA=B8=B8=EC=9D=B4=20=EB=B0=98=EC=98=81=20=EC=95=88=EB=90=98?= =?UTF-8?q?=EB=8A=94=20=ED=98=84=EC=83=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/common/useCommonUtils.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/hooks/common/useCommonUtils.js b/src/hooks/common/useCommonUtils.js index dbad7a88..8ecb912b 100644 --- a/src/hooks/common/useCommonUtils.js +++ b/src/hooks/common/useCommonUtils.js @@ -17,6 +17,7 @@ export function useCommonUtils() { const { addCanvasMouseEventListener, addDocumentEventListener, initEvent } = useEvent() const dimensionSettings = useRecoilValue(dimensionLineSettingsState) const dimensionLineTextFont = useRecoilValue(fontSelector('dimensionLineText')) + const lengthTextFont = useRecoilValue(fontSelector('lengthText')) const commonTextFont = useRecoilValue(fontSelector('commonText')) const [commonUtils, setCommonUtilsState] = useRecoilState(commonUtilsState) const { addPopup } = usePopup() @@ -561,6 +562,7 @@ export function useCommonUtils() { obj.clone((cloned) => { clonedObj = cloned + clonedObj.fontSize = lengthTextFont.fontSize.value }) addCanvasMouseEventListener('mouse:move', (e) => { @@ -595,6 +597,7 @@ export function useCommonUtils() { //배치면일 경우 if (obj.name === 'roof') { clonedObj.setCoords() + clonedObj.fire('modified') clonedObj.fire('polygonMoved') clonedObj.set({ direction: obj.direction, directionText: obj.directionText, roofMaterial: obj.roofMaterial }) From ec284a5fe2abb31fe23d2bb4ef39e3087dbdf1d3 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Tue, 4 Mar 2025 17:18:41 +0900 Subject: [PATCH 218/352] =?UTF-8?q?directionText=20=EC=9A=B0=EC=84=A0=20?= =?UTF-8?q?=EC=A3=BC=EC=84=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useOrientation.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hooks/module/useOrientation.js b/src/hooks/module/useOrientation.js index 9119398d..cef2b5a6 100644 --- a/src/hooks/module/useOrientation.js +++ b/src/hooks/module/useOrientation.js @@ -28,9 +28,9 @@ export function useOrientation() { } const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) - roofs.forEach((roof) => { - delete roof.directionText - }) + /*roofs.forEach((roof) => { + roof.directionText = null + })*/ roofs.forEach((roof) => { roof.set({ From 6c6ba0eb72781541f5f5f12f991043d2550d19f2 Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 4 Mar 2025 17:19:43 +0900 Subject: [PATCH 219/352] =?UTF-8?q?=EB=AC=BC=EA=B1=B4=20=EB=8F=84=EB=A9=B4?= =?UTF-8?q?=EC=9E=91=EC=84=B1=20=EB=B2=84=ED=8A=BC=20=EC=BB=A8=ED=8A=B8?= =?UTF-8?q?=EB=A1=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/management/StuffSubHeader.jsx | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/components/management/StuffSubHeader.jsx b/src/components/management/StuffSubHeader.jsx index f130b729..c22f4cb8 100644 --- a/src/components/management/StuffSubHeader.jsx +++ b/src/components/management/StuffSubHeader.jsx @@ -23,7 +23,7 @@ export default function StuffSubHeader({ type }) { const setFloorPlanObjectNo = useSetRecoilState(floorPlanObjectState) - const { managementState } = useContext(GlobalDataContext) + const { managementState, setManagementState } = useContext(GlobalDataContext) const [buttonStyle, setButtonStyle] = useState('') @@ -31,17 +31,20 @@ export default function StuffSubHeader({ type }) { useEffect(() => { window.scrollTo(0, 0) + setManagementState({}) }, []) useEffect(() => { - if (isObjectNotEmpty(managementState)) { - if (managementState?.createSaleStoreId === 'T01') { - if (session?.storeId !== 'T01') { - setButtonStyle('none') + if (type === 'detail') { + if (isObjectNotEmpty(managementState)) { + if (managementState?.createSaleStoreId === 'T01') { + if (session?.storeId !== 'T01') { + setButtonStyle('none') + } } } } - }, [managementState?.createSaleStoreId]) + }, [type, managementState]) const searchParams = useSearchParams() const objectNo = searchParams.get('objectNo') //url에서 물건번호 꺼내서 바로 set From bc07fc9e047526e980590322349140fb3828e821 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Tue, 4 Mar 2025 17:51:26 +0900 Subject: [PATCH 220/352] =?UTF-8?q?module=EC=9D=B4=20=EC=97=86=EC=9D=84=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=EC=97=90=EB=8A=94=20directionText=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useOrientation.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/hooks/module/useOrientation.js b/src/hooks/module/useOrientation.js index cef2b5a6..649d8f79 100644 --- a/src/hooks/module/useOrientation.js +++ b/src/hooks/module/useOrientation.js @@ -27,10 +27,12 @@ export function useOrientation() { setCompasDeg(0) } const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) - - /*roofs.forEach((roof) => { - roof.directionText = null - })*/ + const hasModules = canvas.getObjects().some((obj) => obj.name === 'module') + if (!hasModules) { + roofs.forEach((roof) => { + delete roof.directionText + }) + } roofs.forEach((roof) => { roof.set({ From 89f5c2d708d7a36e2cf53c56a56bed4de07c5317 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Tue, 4 Mar 2025 18:15:13 +0900 Subject: [PATCH 221/352] =?UTF-8?q?-=20=EA=B2=AC=EC=A0=81=EC=84=9C=20API?= =?UTF-8?q?=20circuitItemList=20=EB=82=B4=EC=9A=A9=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/circuitTrestle/CircuitTrestleSetting.jsx | 4 ++-- src/hooks/module/useTrestle.js | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index 981201ec..e0d32bbc 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -563,8 +563,8 @@ export default function CircuitTrestleSetting({ id }) { goodsNo: model.goodsNo, serQtyList: [ { - serQty: result[index + 1].maxValue, - paralQty: result[index + 1].count, + serQty: result[(index + 1).toString()] ? result[(index + 1).toString()].maxValue : 0, + paralQty: result[(index + 1).toString()] ? result[(index + 1).toString()].count : 0, rmdYn: 'Y', usePossYn: 'Y', roofSurfaceList: canvas diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index 73fca74e..b122a19e 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -9,6 +9,7 @@ import { basicSettingState, trestleDisplaySelector } from '@/store/settingAtom' import { useSwal } from '@/hooks/useSwal' import { useContext } from 'react' import { QcastContext } from '@/app/QcastProvider' +import { useCircuitTrestle } from '@/hooks/useCirCuitTrestle' // 모듈간 같은 행, 열의 마진이 10 이하인 경우는 같은 행, 열로 간주 const MODULE_MARGIN = 10 @@ -22,6 +23,9 @@ export const useTrestle = () => { const isTrestleDisplay = useRecoilValue(trestleDisplaySelector) const { swalFire } = useSwal() const { setIsGlobalLoading } = useContext(QcastContext) + + const { getSelectedPcsItemList } = useCircuitTrestle() + const apply = () => { const notAllocationModules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE && !obj.circuit) if (notAllocationModules.length > 0) { @@ -723,11 +727,7 @@ export const useTrestle = () => { // circuitItemList 중복제거 circuitItemList = circuitItemList.filter((item, index) => circuitItemList.indexOf(item) === index) - circuitItemList = circuitItemList.map((circuitId) => { - return { - itemId: circuitId, - } - }) + circuitItemList = getSelectedPcsItemList() return { itemList, northArrangement, roofSurfaceList, circuitItemList } } From 087d43cc15b61b24eeefb2ac783aa2f1ac1cff2f Mon Sep 17 00:00:00 2001 From: basssy Date: Wed, 5 Mar 2025 10:13:33 +0900 Subject: [PATCH 222/352] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=95=88?= =?UTF-8?q?=EA=B1=B4=EB=AA=85Omit=20select=20isClearable=20true?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 3810bd7b..da241db1 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -1263,7 +1263,7 @@ export default function Estimate({}) { }} getOptionLabel={(x) => x.clCodeNm} getOptionValue={(x) => x.clCode} - isClearable={false} + isClearable={true} isSearchable={false} value={honorificCodeList.filter(function (option) { return option.clCodeNm === estimateContextState.objectNameOmit From 0a24c23bf15c0b05d24153b92207b5216e613076 Mon Sep 17 00:00:00 2001 From: basssy Date: Wed, 5 Mar 2025 12:29:54 +0900 Subject: [PATCH 223/352] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=EB=B3=B5?= =?UTF-8?q?=EC=82=AC=ED=8C=9D=EC=97=85=20=EB=8B=B4=EB=8B=B9=EC=9E=90?= =?UTF-8?q?=EB=AA=85=20default=20value=20session=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/popup/EstimateCopyPop.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/estimate/popup/EstimateCopyPop.jsx b/src/components/estimate/popup/EstimateCopyPop.jsx index 3bc25c74..564a1aae 100644 --- a/src/components/estimate/popup/EstimateCopyPop.jsx +++ b/src/components/estimate/popup/EstimateCopyPop.jsx @@ -106,7 +106,7 @@ export default function EstimateCopyPop({ planNo, setEstimateCopyPopupOpen }) { useEffect(() => { if (estimateContextState?.charger) { - setCopyReceiveUser(estimateContextState.charger) + setCopyReceiveUser(session?.userNm) } }, [estimateContextState?.charger]) From 4ca23c1827243d3439d31948d03acc2e550b2c1a Mon Sep 17 00:00:00 2001 From: yjnoh Date: Wed, 5 Mar 2025 12:46:09 +0900 Subject: [PATCH 224/352] =?UTF-8?q?=EB=8F=84=EB=A8=B8=20=EC=B9=B4=ED=94=BC?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/common.js | 6 +- .../floor-plan/modal/object/ObjectSetting.jsx | 33 ++++- src/hooks/common/useCanvasConfigInitialize.js | 18 ++- src/hooks/common/useCommonUtils.js | 118 ++++++++++-------- src/hooks/module/useModuleBasicSetting.js | 4 +- src/hooks/object/useObjectBatch.js | 117 +++++++++++++---- src/util/canvas-util.js | 5 + 7 files changed, 217 insertions(+), 84 deletions(-) diff --git a/src/common/common.js b/src/common/common.js index ca472a11..0fa678db 100644 --- a/src/common/common.js +++ b/src/common/common.js @@ -198,6 +198,10 @@ export const SAVE_KEY = [ 'isChidory', 'textVisible', 'groupPoints', + 'fontSize', + 'fontStyle', + 'fontWeight', + 'dormerAttributes', ] -export const OBJECT_PROTOTYPE = [fabric.Line.prototype, fabric.Polygon.prototype, fabric.Triangle.prototype] +export const OBJECT_PROTOTYPE = [fabric.Line.prototype, fabric.Polygon.prototype, fabric.Triangle.prototype, fabric.Group.prototype] diff --git a/src/components/floor-plan/modal/object/ObjectSetting.jsx b/src/components/floor-plan/modal/object/ObjectSetting.jsx index 909aad99..b602f163 100644 --- a/src/components/floor-plan/modal/object/ObjectSetting.jsx +++ b/src/components/floor-plan/modal/object/ObjectSetting.jsx @@ -24,7 +24,6 @@ export default function ObjectSetting({ id, pos = { x: 50, y: 230 } }) { const { closePopup } = usePopup() const surfaceShapePolygons = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) - //오브젝트 배치로 넘어오면 면형상 선택 불가 useEffect(() => { canvas.discardActiveObject() @@ -54,15 +53,41 @@ export default function ObjectSetting({ id, pos = { x: 50, y: 230 } }) { const applyObject = () => { if (surfaceShapePolygons.length === 0) { - swalFire({ text: '지붕이 없어요 지붕부터 그리세요', icon: 'error' }) + swalFire({ text: getMessage('batch.object.outside.roof'), icon: 'error' }) return } //개구배치, 그림자배치 if (buttonAct === 1 || buttonAct === 2) { - applyOpeningAndShadow(objectPlacement, buttonAct, surfaceShapePolygons) + applyOpeningAndShadow(objectPlacement, buttonAct) } else { - applyDormers(dormerPlacement, buttonAct, surfaceShapePolygons) + const height = dormerPlacement.heightRef.current !== null ? dormerPlacement.heightRef.current.value / 10 : 0 + const width = dormerPlacement.widthRef.current !== null ? dormerPlacement.widthRef.current.value / 10 : 0 //triangle일때는 없음 + const pitch = dormerPlacement.pitchRef.current !== null ? Number(dormerPlacement.pitchRef.current.value) : 0 + const offsetRef = + dormerPlacement.offsetRef.current !== null + ? dormerPlacement.offsetRef.current.value === '' + ? 0 + : parseInt(dormerPlacement.offsetRef.current.value) / 10 + : 0 + const offsetWidthRef = + dormerPlacement.offsetWidthRef.current !== null + ? dormerPlacement.offsetWidthRef.current.value === '' + ? 0 + : parseInt(dormerPlacement.offsetWidthRef.current.value) / 10 + : 0 + const directionRef = dormerPlacement.directionRef.current + + const dormerParams = { + height: height, + width: width, + pitch: pitch, + offsetRef: offsetRef, + offsetWidthRef: offsetWidthRef, + directionRef: directionRef, + } + + applyDormers(dormerParams, buttonAct) } setIsHidden(true) } diff --git a/src/hooks/common/useCanvasConfigInitialize.js b/src/hooks/common/useCanvasConfigInitialize.js index 089aeea9..19736e81 100644 --- a/src/hooks/common/useCanvasConfigInitialize.js +++ b/src/hooks/common/useCanvasConfigInitialize.js @@ -23,7 +23,7 @@ export function useCanvasConfigInitialize() { const {} = useFont() const {} = useGrid() const {} = useRoof() - const { drawDirectionArrow } = usePolygon() + const { drawDirectionArrow, addLengthText } = usePolygon() useEffect(() => { if (!canvas) return @@ -160,11 +160,15 @@ export function useCanvasConfigInitialize() { const objectsParentId = canvas.getObjects().filter((obj) => obj.groupId === id || obj.id === id)[0].parentId let objectArray = [] + let groupPoints = [] //그룹객체가 있으면 배열에 추가함 if (groupObjects) { groupObjects.forEach((obj) => { objectArray.push(obj) + if (obj.groupPoints) { + groupPoints = obj.groupPoints + } }) } @@ -187,9 +191,21 @@ export function useCanvasConfigInitialize() { }) canvas.add(group) + //도머등 그룹에 포인트가 있는애들한테 다시 넣어준다 + if (groupPoints.length > 0) { + group.set({ + groupPoints: groupPoints, + }) + } + //그룹 객체 재그룹 완료 group.getObjects().forEach((obj) => { obj.fire('modified') + if (obj.texts) { + obj.texts.forEach((text) => { + text.bringToFront() + }) + } }) }) } diff --git a/src/hooks/common/useCommonUtils.js b/src/hooks/common/useCommonUtils.js index dbad7a88..85cbc2bd 100644 --- a/src/hooks/common/useCommonUtils.js +++ b/src/hooks/common/useCommonUtils.js @@ -10,6 +10,7 @@ import { v4 as uuidv4 } from 'uuid' import { usePopup } from '@/hooks/usePopup' import Distance from '@/components/floor-plan/modal/distance/Distance' import { usePolygon } from '@/hooks/usePolygon' +import { useObjectBatch } from '@/hooks/object/useObjectBatch' export function useCommonUtils() { const canvas = useRecoilValue(canvasState) @@ -21,6 +22,7 @@ export function useCommonUtils() { const [commonUtils, setCommonUtilsState] = useRecoilState(commonUtilsState) const { addPopup } = usePopup() const { drawDirectionArrow, addLengthText } = usePolygon() + const { applyDormers } = useObjectBatch({}) useEffect(() => { if (commonUtils.text) { @@ -557,58 +559,76 @@ export function useCommonUtils() { const commonCopyObject = (obj) => { if (obj) { - let clonedObj = null + if (obj.name.indexOf('triangleDormer') || obj.name.indexOf('pentagonDormer')) { + const dormerAttributes = obj._objects[0].dormerAttributes + const dormerName = obj._objects[0].name - obj.clone((cloned) => { - clonedObj = cloned - }) - - addCanvasMouseEventListener('mouse:move', (e) => { - const pointer = canvas?.getPointer(e.e) - if (!clonedObj) return - - canvas - .getObjects() - .filter((obj) => obj.name === 'clonedObj') - .forEach((obj) => canvas?.remove(obj)) - - clonedObj.set({ - left: pointer.x, - top: pointer.y, - name: 'clonedObj', - }) - canvas.add(clonedObj) - }) - - addCanvasMouseEventListener('mouse:down', (e) => { - clonedObj.set({ - lockMovementX: true, - lockMovementY: true, - name: obj.name, - editable: false, - id: uuidv4(), //복사된 객체라 새로 따준다 - }) - - //객체가 그룹일 경우에는 그룹 아이디를 따로 넣어준다 - if (clonedObj.type === 'group') clonedObj.set({ groupId: uuidv4() }) - - //배치면일 경우 - if (obj.name === 'roof') { - clonedObj.setCoords() - clonedObj.fire('polygonMoved') - clonedObj.set({ direction: obj.direction, directionText: obj.directionText, roofMaterial: obj.roofMaterial }) - - obj.lines.forEach((line, index) => { - clonedObj.lines[index].set({ attributes: line.attributes }) - }) - - canvas.renderAll() - addLengthText(clonedObj) //수치 추가 - drawDirectionArrow(clonedObj) //방향 화살표 추가 + const dormerParams = { + height: dormerAttributes.height, + width: dormerAttributes.width, + pitch: dormerAttributes.pitch, + offsetRef: dormerAttributes.offsetRef, + offsetWidthRef: dormerAttributes.offsetWidthRef, + directionRef: dormerAttributes.directionRef, } - initEvent() - }) + const buttonAct = dormerName == 'triangleDormer' ? 3 : 4 + + applyDormers(dormerParams, buttonAct) + } else { + let clonedObj = null + + obj.clone((cloned) => { + clonedObj = cloned + }) + + addCanvasMouseEventListener('mouse:move', (e) => { + const pointer = canvas?.getPointer(e.e) + if (!clonedObj) return + + canvas + .getObjects() + .filter((obj) => obj.name === 'clonedObj') + .forEach((obj) => canvas?.remove(obj)) + + clonedObj.set({ + left: pointer.x, + top: pointer.y, + name: 'clonedObj', + }) + canvas.add(clonedObj) + }) + + addCanvasMouseEventListener('mouse:down', (e) => { + clonedObj.set({ + lockMovementX: true, + lockMovementY: true, + name: obj.name, + editable: false, + id: uuidv4(), //복사된 객체라 새로 따준다 + }) + + //객체가 그룹일 경우에는 그룹 아이디를 따로 넣어준다 + if (clonedObj.type === 'group') clonedObj.set({ groupId: uuidv4() }) + + //배치면일 경우 + if (obj.name === 'roof') { + clonedObj.setCoords() + clonedObj.fire('polygonMoved') + clonedObj.set({ direction: obj.direction, directionText: obj.directionText, roofMaterial: obj.roofMaterial }) + + obj.lines.forEach((line, index) => { + clonedObj.lines[index].set({ attributes: line.attributes }) + }) + + canvas.renderAll() + addLengthText(clonedObj) //수치 추가 + drawDirectionArrow(clonedObj) //방향 화살표 추가 + } + + initEvent() + }) + } } } diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index a7a03c42..37d8dc1d 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -391,11 +391,11 @@ export function useModuleBasicSetting(tabNum) { //모듈,회로에서 다른메뉴 -> 배치면으로 갈 경수 초기화 const restoreModuleInstArea = () => { //설치면 삭제 - const setupArea = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) + const setupArea = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE || obj.name === POLYGON_TYPE.OBJECT_SURFACE) //모듈 삭제 및 초기화 setupArea.forEach((obj) => { - if (obj.modules.length > 0) { + if (isObjectNotEmpty(obj.modules) && obj.modules.length > 0) { obj.modules.forEach((module) => { canvas.remove(module) }) diff --git a/src/hooks/object/useObjectBatch.js b/src/hooks/object/useObjectBatch.js index 231f422c..ff9bf24d 100644 --- a/src/hooks/object/useObjectBatch.js +++ b/src/hooks/object/useObjectBatch.js @@ -1,11 +1,11 @@ 'use client' -import { useEffect } from 'react' +import { useEffect, useRef } from 'react' import { useMessage } from '@/hooks/useMessage' import { useRecoilValue } from 'recoil' import { canvasState } from '@/store/canvasAtom' import { BATCH_TYPE, INPUT_TYPE, POLYGON_TYPE } from '@/common/common' import { useEvent } from '@/hooks/useEvent' -import { pointsToTurfPolygon, polygonToTurfPolygon, rectToPolygon, triangleToPolygon } from '@/util/canvas-util' +import { pointsToTurfPolygon, polygonToTurfPolygon, rectToPolygon, triangleToPolygon, toFixedWithoutRounding } from '@/util/canvas-util' import { useSwal } from '@/hooks/useSwal' import * as turf from '@turf/turf' import { usePolygon } from '@/hooks/usePolygon' @@ -71,13 +71,15 @@ export function useObjectBatch({ isHidden, setIsHidden }) { } } - const applyOpeningAndShadow = (objectPlacement, buttonAct, surfaceShapePolygons) => { + const applyOpeningAndShadow = (objectPlacement, buttonAct) => { const selectedType = objectPlacement.typeRef.current.find((radio) => radio.checked).value const isCrossChecked = buttonAct === 1 ? objectPlacement.isCrossRef.current.checked : false const objName = buttonAct === 1 ? BATCH_TYPE.OPENING : BATCH_TYPE.SHADOW + const surfaceShapePolygons = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) const objTempName = buttonAct === 1 ? BATCH_TYPE.OPENING_TEMP : BATCH_TYPE.SHADOW_TEMP let rect, isDown, origX, origY + let selectedSurface //프리입력 @@ -267,26 +269,14 @@ export function useObjectBatch({ isHidden, setIsHidden }) { * @param {*} surfaceShapePolygons * @returns */ - const applyDormers = (dormerPlacement, buttonAct, surfaceShapePolygons) => { + const applyDormers = ({ height, width, pitch, offsetRef, offsetWidthRef, directionRef }, buttonAct) => { const dormerName = buttonAct === 3 ? BATCH_TYPE.TRIANGLE_DORMER : BATCH_TYPE.PENTAGON_DORMER const dormerTempName = buttonAct === 3 ? BATCH_TYPE.TRIANGLE_DORMER_TEMP : BATCH_TYPE.PENTAGON_DORMER_TEMP - const height = dormerPlacement.heightRef.current !== null ? dormerPlacement.heightRef.current.value / 10 : 0 - const width = dormerPlacement.widthRef.current !== null ? dormerPlacement.widthRef.current.value / 10 : 0 //triangle일때는 없음 - const pitch = dormerPlacement.pitchRef.current !== null ? dormerPlacement.pitchRef.current.value : 0 - const offsetRef = - dormerPlacement.offsetRef.current !== null - ? dormerPlacement.offsetRef.current.value === '' - ? 0 - : parseInt(dormerPlacement.offsetRef.current.value) / 10 - : 0 - const offsetWidthRef = - dormerPlacement.offsetWidthRef.current !== null - ? dormerPlacement.offsetWidthRef.current.value === '' - ? 0 - : parseInt(dormerPlacement.offsetWidthRef.current.value) / 10 - : 0 - const directionRef = dormerPlacement.directionRef.current + let dormer, dormerOffset, isDown, selectedSurface, pentagonPoints, pentagonOffsetPoints + + const surfaceShapePolygons = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) + const id = uuidv4() if (height === '' || pitch === '' || height <= 0 || pitch <= 0) { @@ -296,8 +286,9 @@ export function useObjectBatch({ isHidden, setIsHidden }) { //삼각형 도머 if (buttonAct === 3) { - const bottomLength = height / (pitch * 0.25) - const bottomOffsetLength = (height + offsetRef) / (pitch * 0.25) + const bottomLength = Math.floor((height / Math.cos(Math.atan(pitch / 10))) * 10) / 10 + const bottomOffsetLength = Math.floor(((height + offsetRef) / Math.cos(Math.atan(pitch / 10))) * 10) / 10 + let groupDormerPoints = [] //나중에 offset을 위한 포인트 저장용 addCanvasMouseEventListener('mouse:move', (e) => { @@ -313,6 +304,8 @@ export function useObjectBatch({ isHidden, setIsHidden }) { } }) + console.log('selectedSurface', selectedSurface) + let angle = 0 if (directionRef === 'left') { //서 @@ -433,6 +426,15 @@ export function useObjectBatch({ isHidden, setIsHidden }) { fontSize: lengthTextFont.fontSize.value, fontStyle: lengthTextFont.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal', fontWeight: lengthTextFont.fontWeight.value, + groupPoints: groupPoints, + dormerAttributes: { + height: height, + width: width, + pitch: pitch, + offsetRef: offsetRef, + offsetWidthRef: offsetWidthRef, + directionRef: directionRef, + }, }) const rightTriangle = new QPolygon(rightPoints, { @@ -452,6 +454,15 @@ export function useObjectBatch({ isHidden, setIsHidden }) { fontSize: lengthTextFont.fontSize.value, fontStyle: lengthTextFont.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal', fontWeight: lengthTextFont.fontWeight.value, + groupPoints: groupPoints, + dormerAttributes: { + height: height, + width: width, + pitch: pitch, + offsetRef: offsetRef, + offsetWidthRef: offsetWidthRef, + directionRef: directionRef, + }, }) // canvas?.add(leftTriangle) @@ -489,6 +500,15 @@ export function useObjectBatch({ isHidden, setIsHidden }) { fontStyle: lengthTextFont.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal', fontWeight: lengthTextFont.fontWeight.value, angle: originAngle, + pitch: pitch, + dormerAttributes: { + height: height, + width: width, + pitch: pitch, + offsetRef: offsetRef, + offsetWidthRef: offsetWidthRef, + directionRef: directionRef, + }, }) } @@ -528,8 +548,6 @@ export function useObjectBatch({ isHidden, setIsHidden }) { //(동의길이 깊이)+출폭(깊이)-[(입력한 폭값)/2+출폭(폭)]*(0.25*입력한 寸) const heightOffsetLength = height + offsetRef - (width / 2 + offsetWidthRef) * (pitch * 0.25) - let groupDormerPoints = [] - addCanvasMouseEventListener('mouse:move', (e) => { isDown = true if (!isDown) return @@ -672,6 +690,15 @@ export function useObjectBatch({ isHidden, setIsHidden }) { originY: 'center', name: dormerName, pitch: pitch, + groupPoints: groupPoints, + dormerAttributes: { + height: height, + width: width, + pitch: pitch, + offsetRef: offsetRef, + offsetWidthRef: offsetWidthRef, + directionRef: directionRef, + }, }) const rightPentagon = new QPolygon(rightPoints, { @@ -689,6 +716,15 @@ export function useObjectBatch({ isHidden, setIsHidden }) { originY: 'center', name: dormerName, pitch: pitch, + groupPoints: groupPoints, + dormerAttributes: { + height: height, + width: width, + pitch: pitch, + offsetRef: offsetRef, + offsetWidthRef: offsetWidthRef, + directionRef: directionRef, + }, }) // canvas?.add(leftPentagon) @@ -703,8 +739,6 @@ export function useObjectBatch({ isHidden, setIsHidden }) { let offsetPolygon - groupDormerPoints = groupPoints - if (offsetRef > 0) { canvas?.remove(dormer) @@ -725,6 +759,15 @@ export function useObjectBatch({ isHidden, setIsHidden }) { fontStyle: lengthTextFont.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal', fontWeight: lengthTextFont.fontWeight.value, angle: originAngle, + groupPoints: groupPoints, + dormerAttributes: { + height: height, + width: width, + pitch: pitch, + offsetRef: offsetRef, + offsetWidthRef: offsetWidthRef, + directionRef: directionRef, + }, }) } @@ -738,7 +781,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) { groupYn: true, originX: 'center', originY: 'center', - groupPoints: groupDormerPoints, + groupPoints: groupPoints, }) canvas?.add(objectGroup) @@ -1191,6 +1234,26 @@ export function useObjectBatch({ isHidden, setIsHidden }) { } } + const dormerPlacement = { + widthRef: useRef(null), + heightRef: useRef(null), + pitchRef: useRef(null), + offsetRef: useRef(null), + offsetWidthRef: useRef(null), + directionRef: useRef(null), + } + + const copyOjbectDormer = () => { + const obj = canvas.getActiveObject() + if (obj) { + if (obj.name === 'triangleDormer') { + const offset = obj._objects.filter((item) => item.name === 'triangleDormerOffset') + } else { + //오각도머 + } + } + } + const dormerOffsetKeyEvent = (setArrow1, setArrow2) => { addDocumentEventListener('keydown', document, (e) => { if (e.key === 'ArrowDown' || e.key === 'ArrowUp') { diff --git a/src/util/canvas-util.js b/src/util/canvas-util.js index 83f604ec..66116af8 100644 --- a/src/util/canvas-util.js +++ b/src/util/canvas-util.js @@ -1035,3 +1035,8 @@ export function calculateVisibleModuleHeight(sourceWidth, sourceHeight, angle, d height: Number(visibleHeight.toFixed(1)), // 소수점 두 자리로 고정 } } + +//숫자, 몇자리수 +export function toFixedWithoutRounding(number, decimals) { + return Math.floor(number * Math.pow(10, decimals)) / Math.pow(10, decimals) +} From 6b3d0ea6ffcb537e5ab0a03957375c74f575b59d Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 5 Mar 2025 13:31:03 +0900 Subject: [PATCH 225/352] =?UTF-8?q?=ED=9A=8C=EB=A1=9C=EA=B5=AC=EC=84=B1?= =?UTF-8?q?=EC=9D=B4=20=EC=99=84=EB=A3=8C=EB=90=98=EB=A9=B4=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99,=20=EB=B3=B5=EC=82=AC=20=EB=B0=8F=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=EA=B0=80=20=EC=95=88=EB=90=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModule.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/hooks/module/useModule.js b/src/hooks/module/useModule.js index 0896fe04..c6ca9ba3 100644 --- a/src/hooks/module/useModule.js +++ b/src/hooks/module/useModule.js @@ -412,6 +412,9 @@ export function useModule() { } const moduleColumnRemove = (type) => { + if (isFixedModule()) { + return + } const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0] if (activeModule.circuit) { swalFire({ @@ -535,6 +538,9 @@ export function useModule() { } const moduleRowRemove = (type) => { + if (isFixedModule()) { + return + } const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0] const rowModules = getRowModules(activeModule) const otherModules = getOtherModules(rowModules) @@ -651,6 +657,9 @@ export function useModule() { } const moduleColumnInsert = (type) => { + if (isFixedModule()) { + return + } const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0] const columnModules = getColumnModules(activeModule) let otherModules = getOtherModules(columnModules) @@ -750,7 +759,25 @@ export function useModule() { setModuleStatisticsData() } + const isFixedModule = () => { + const completeSurfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.isComplete) + + if (completeSurfaces.length > 0) { + swalFire({ + title: getMessage('modal.module.can.not.edit'), + type: 'alert', + icon: 'error', + }) + return true + } + + return false + } + const muduleRowInsert = (type) => { + if (isFixedModule()) { + return + } const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0] const rowModules = getRowModules(activeModule) let otherModules = getOtherModules(rowModules) From 6a18c93fbcd5dc0f5b6cb9359b907ff40815c534 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 5 Mar 2025 14:14:55 +0900 Subject: [PATCH 226/352] =?UTF-8?q?=EC=B9=98=EC=88=98=EC=84=A0=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=EA=B3=84=EC=82=B0=EC=8B=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/dimensionLine/DimensionLineSetting.jsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/floor-plan/modal/dimensionLine/DimensionLineSetting.jsx b/src/components/floor-plan/modal/dimensionLine/DimensionLineSetting.jsx index e08bc839..e4807c36 100644 --- a/src/components/floor-plan/modal/dimensionLine/DimensionLineSetting.jsx +++ b/src/components/floor-plan/modal/dimensionLine/DimensionLineSetting.jsx @@ -9,7 +9,7 @@ import { canvasState, pitchTextSelector } from '@/store/canvasAtom' import { defaultSlope } from '@/store/commonAtom' import { re } from 'mathjs' import { basicSettingState } from '@/store/settingAtom' -import { getChonByDegree } from '@/util/canvas-util' +import { getChonByDegree, getDegreeByChon } from '@/util/canvas-util' export default function DimensionLineSetting(props) { const contextPopupPosition = useRecoilValue(contextPopupPositionState) @@ -106,14 +106,14 @@ export default function DimensionLineSetting(props) { } const calculateLength = (originalLength, angle, angle1) => { - const slope1 = basicSetting.roofAngleSet !== 'slope' ? getChonByDegree(angle) : angle - const slope2 = basicSetting.roofAngleSet !== 'slope' ? getChonByDegree(angle1 ?? 0) : angle1 if (!angle1) { - const angleInRadians = slope1 * (Math.PI / 180) - const result = Math.sqrt(Math.pow(originalLength * Math.tan(angleInRadians), 2) + Math.pow(originalLength, 2)) - console.log(angleInRadians, result) + const slope1 = basicSetting.roofAngleSet !== 'slope' ? getDegreeByChon(angle) : angle + const result = Math.sqrt(Math.pow(originalLength * Math.tan((getDegreeByChon(slope1) * Math.PI) / 180), 2) + Math.pow(originalLength, 2)) + console.log(result) return result } else { + const slope1 = basicSetting.roofAngleSet !== 'slope' ? getChonByDegree(angle) : angle + const slope2 = basicSetting.roofAngleSet !== 'slope' ? getChonByDegree(angle1 ?? 0) : angle1 const numerator = Math.sqrt(Math.pow(slope1, 2) + 100 + Math.pow((10 * slope1) / slope2, 2)) * originalLength const denominator = Math.sqrt(Math.pow((10 * slope1) / slope2, 2) + 100) const result = numerator / denominator From 74d5db411de57c5e07a6ce2c5c1630f57cc0ada1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 5 Mar 2025 14:15:54 +0900 Subject: [PATCH 227/352] =?UTF-8?q?plans=202=EA=B0=9C=20=EC=9D=B4=EC=83=81?= =?UTF-8?q?=EC=9D=BC=EB=95=8C=20plan1=20=EC=82=AD=EC=A0=9C=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasLayout.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/floor-plan/CanvasLayout.jsx b/src/components/floor-plan/CanvasLayout.jsx index 22215fd2..43e4388a 100644 --- a/src/components/floor-plan/CanvasLayout.jsx +++ b/src/components/floor-plan/CanvasLayout.jsx @@ -39,7 +39,7 @@ export default function CanvasLayout({ children }) { onClick={() => handleCurrentPlan(plan.id)} > {`Plan ${plan.planNo}`} - {index !== 0 && !pathname.includes('/estimate') && !pathname.includes('/simulator') && ( + {plans.length > 1 && !pathname.includes('/estimate') && !pathname.includes('/simulator') && ( { From 7b7b85dddc714ab609123f256c95dde05c6fa48a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 5 Mar 2025 14:16:11 +0900 Subject: [PATCH 228/352] =?UTF-8?q?Color=20Picker=20Title=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/color-picker/ColorPickerModal.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/common/color-picker/ColorPickerModal.jsx b/src/components/common/color-picker/ColorPickerModal.jsx index 729402a7..94f24f42 100644 --- a/src/components/common/color-picker/ColorPickerModal.jsx +++ b/src/components/common/color-picker/ColorPickerModal.jsx @@ -54,7 +54,6 @@ export default function ColorPickerModal(props) {
-
COLOR PICKER
From eb928fc4f2afb0c5a561b03789a56af00efd94b1 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 5 Mar 2025 14:16:19 +0900 Subject: [PATCH 229/352] =?UTF-8?q?length1Ref=20current=EA=B0=80=20?= =?UTF-8?q?=EC=97=86=EC=9D=84=20=EA=B2=BD=EC=9A=B0=EB=8A=94=20=EC=8B=A4?= =?UTF-8?q?=ED=96=89=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/surface/usePlacementShapeDrawing.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hooks/surface/usePlacementShapeDrawing.js b/src/hooks/surface/usePlacementShapeDrawing.js index 50f61172..983583ba 100644 --- a/src/hooks/surface/usePlacementShapeDrawing.js +++ b/src/hooks/surface/usePlacementShapeDrawing.js @@ -688,8 +688,9 @@ export function usePlacementShapeDrawing(id) { } // 포커스가 length1에 있지 않으면 length1에 포커스를 줌 const activeElem = document.activeElement + if (activeElem !== length1Ref.current) { - length1Ref.current.focus() + length1Ref.current?.focus() } const key = e.key @@ -698,7 +699,7 @@ export function usePlacementShapeDrawing(id) { return } - const lengthNum = Number(length1Ref.current.value) / 10 + const lengthNum = Number(length1Ref.current?.value) / 10 if (lengthNum === 0) { return } From e0219bf2ecf8679aa5e03aa71dc7aed099b09717 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 5 Mar 2025 14:28:06 +0900 Subject: [PATCH 230/352] =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=A9=B4=20=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=EC=84=A4=EC=A0=95=EC=97=90=EC=84=9C=20=EA=B7=B8?= =?UTF-8?q?=EB=A6=AC=EB=93=9C=20=EA=B4=80=EB=A0=A8=20contextmenu=20?= =?UTF-8?q?=EB=82=98=EC=98=A4=EB=8A=94=20=EB=B2=84=EA=B7=B8=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useContextMenu.js | 43 ------------------------------------- 1 file changed, 43 deletions(-) diff --git a/src/hooks/useContextMenu.js b/src/hooks/useContextMenu.js index 97e9cf6c..144272f8 100644 --- a/src/hooks/useContextMenu.js +++ b/src/hooks/useContextMenu.js @@ -76,50 +76,7 @@ export function useContextMenu() { const currentMenuSetting = () => { switch (selectedMenu) { - case 'placement': - setContextMenu([ - [ - { - id: 'gridMove', - name: getMessage('modal.grid.move'), - component: , - }, - { - id: 'gridCopy', - name: getMessage('modal.grid.copy'), - component: , - }, - { - id: 'gridColorEdit', - name: getMessage('modal.grid.color.edit'), - component: ( - - ), - }, - { - id: 'remove', - name: getMessage('delete'), - }, - { - id: 'removeAll', - name: getMessage('delete.all'), - fn: () => { - removeGrid() - removeAdsorptionPoint() - }, - }, - ], - ]) - break case 'outline': - if (['roof', 'auxiliaryLine'].includes(currentObject?.name)) { - } break default: setContextMenu([]) From ff34dbd28636762be169ed79a559e7243f8f40d9 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 5 Mar 2025 14:29:56 +0900 Subject: [PATCH 231/352] =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=A9=B4=20=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=EC=84=A4=EC=A0=95=20=EA=B2=BD=EC=82=AC=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EC=8B=9C=20=EB=B0=98=EC=98=81=EB=90=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/placementShape/PlacementShapeSetting.jsx | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx index ccf6ed4b..d836147c 100644 --- a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx @@ -16,6 +16,8 @@ import { globalLocaleStore } from '@/store/localeAtom' import { onlyNumberInputChange } from '@/util/input-utils' import { getChonByDegree, getDegreeByChon } from '@/util/canvas-util' +import { usePolygon } from '@/hooks/usePolygon' +import { canvasState } from '@/store/canvasAtom' /** * 지붕 레이아웃 @@ -38,6 +40,8 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla const [raftCodes, setRaftCodes] = useState([]) /** 서까래 정보 */ const [currentRoof, setCurrentRoof] = useState(null) /** 현재 선택된 지붕재 정보 */ const { closePopup } = usePopup() /** usePopup에서 closePopup 함수 가져오기 */ + const { drawDirectionArrow } = usePolygon() + const canvas = useRecoilValue(canvasState) const roofRef = { roofCd: useRef(null), @@ -236,6 +240,13 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla }, }) + const roofs = canvas.getObjects().filter((obj) => obj.roofMaterial?.index === 0) + + roofs.forEach((roof) => { + roof.roofMaterial = { ...roofInfo } + drawDirectionArrow(roof) + }) + /* 저장 후 화면 닫기 */ closePopup(id) } From d6031ccb98baa93af0ee179ae1ad327a78de8e2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 5 Mar 2025 14:30:21 +0900 Subject: [PATCH 232/352] =?UTF-8?q?module=20copy=20=EB=B2=84=EA=B7=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModule.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hooks/module/useModule.js b/src/hooks/module/useModule.js index c6ca9ba3..e4e783e9 100644 --- a/src/hooks/module/useModule.js +++ b/src/hooks/module/useModule.js @@ -362,7 +362,7 @@ export function useModule() { } modules.forEach((module) => { - const { top, left } = getPosotion(module, direction, Number(length) + Number(moduleLength), false) + const { top, left } = getPosotion(module, direction, Number(length) + Number(moduleLength), true) module.clone((obj) => { obj.set({ parentId: module.parentId, @@ -689,7 +689,7 @@ export function useModule() { targetModules.forEach((module) => { if (width === -1) width = type === MODULE_INSERT_TYPE.LEFT ? Number(activeModule.left) - Number(module.left) : Number(module.left) - Number(activeModule.left) - const { top, left } = getPosotion(module, type, module.width, false) + const { top, left } = getPosotion(module, type, module.width, true) module.originPos = { left: module.left, top: module.top, @@ -706,7 +706,7 @@ export function useModule() { canvas.renderAll() otherModules = getOtherModules(columnModules) columnModules.forEach((module) => { - const { top, left } = getPosotion(module, type, module.width, false) + const { top, left } = getPosotion(module, type, module.width, true) let copyModule = null module.clone((obj) => { obj.set({ @@ -807,7 +807,7 @@ export function useModule() { targetModules.forEach((module) => { if (height === -1) height = type === MODULE_INSERT_TYPE.TOP ? Number(activeModule.top) - Number(module.top) : Number(module.top) - Number(activeModule.top) - const { top, left } = getPosotion(module, type, activeModule.height, false) + const { top, left } = getPosotion(module, type, activeModule.height, true) module.originPos = { left: module.left, top: module.top, @@ -823,7 +823,7 @@ export function useModule() { canvas.renderAll() otherModules = getOtherModules(rowModules) rowModules.forEach((module) => { - const { top, left } = getPosotion(module, type, activeModule.height, false) + const { top, left } = getPosotion(module, type, activeModule.height, true) let copyModule = null module.clone((obj) => { obj.set({ From 0582dcc8663eb79bcfb833644f054eb7d223bc23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 5 Mar 2025 15:11:23 +0900 Subject: [PATCH 233/352] =?UTF-8?q?plan=20=EC=98=AE=EA=B2=BC=EC=9D=84=20?= =?UTF-8?q?=EB=95=8C=20module=20=EC=A1=B4=EC=9E=AC=ED=95=98=EB=A9=B4=20mod?= =?UTF-8?q?ule=20=EB=A9=94=EB=89=B4=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasFrame.jsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/components/floor-plan/CanvasFrame.jsx b/src/components/floor-plan/CanvasFrame.jsx index 6e302fa1..7144a920 100644 --- a/src/components/floor-plan/CanvasFrame.jsx +++ b/src/components/floor-plan/CanvasFrame.jsx @@ -13,7 +13,7 @@ import { useContextMenu } from '@/hooks/useContextMenu' import { useCanvasConfigInitialize } from '@/hooks/common/useCanvasConfigInitialize' import { currentMenuState } from '@/store/canvasAtom' import { totalDisplaySelector } from '@/store/settingAtom' -import { MENU } from '@/common/common' +import { MENU, POLYGON_TYPE } from '@/common/common' import { FloorPlanContext } from '@/app/floor-plan/FloorPlanProvider' import { QcastContext } from '@/app/QcastProvider' import { @@ -27,6 +27,7 @@ import { } from '@/store/circuitTrestleAtom' import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController' import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' +import { useCanvasMenu } from '@/hooks/common/useCanvasMenu' export default function CanvasFrame() { const canvasRef = useRef(null) @@ -47,6 +48,7 @@ export default function CanvasFrame() { const resetPcsCheckState = useResetRecoilState(pcsCheckState) const { handleModuleSelectionTotal } = useCanvasPopupStatusController() const { fetchBasicSettings } = useCanvasSetting() + const { setSelectedMenu } = useCanvasMenu() const loadCanvas = () => { if (!canvas) return @@ -58,6 +60,10 @@ export default function CanvasFrame() { canvas?.loadFromJSON(JSON.parse(plan.canvasStatus), function () { canvasLoadInit() //config된 상태로 캔버스 객체를 그린다 canvas?.renderAll() // 캔버스를 다시 그립니다. + + if (canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE).length > 0) { + setSelectedMenu('module') + } }) } } From e9a4b04c7339fd4a1d3404d6ae1fe7b896ba665e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 5 Mar 2025 15:11:49 +0900 Subject: [PATCH 234/352] =?UTF-8?q?'=EC=A7=80=EB=B6=95=EC=9E=AC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80'=20=EB=AC=B8=EA=B5=AC=20=EB=B3=80=EA=B2=BD?= =?UTF-8?q?=20=EB=B0=8F=20=EB=8B=A4=EA=B5=AD=EC=96=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/roofAllocation/ContextRoofAllocationSetting.jsx | 2 +- .../floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx | 2 +- src/locales/ja.json | 1 + src/locales/ko.json | 1 + 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx b/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx index 37fc53bc..30e56c0e 100644 --- a/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx +++ b/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx @@ -85,7 +85,7 @@ export default function ContextRoofAllocationSetting(props) { }} > - {getMessage('modal.common.add')} + {getMessage('modal.roof.alloc.add.roof.material')}
diff --git a/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx b/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx index 7723b9de..3dd03385 100644 --- a/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx +++ b/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx @@ -85,7 +85,7 @@ export default function RoofAllocationSetting(props) { }} > - {getMessage('modal.common.add')} + {getMessage('modal.roof.alloc.add.roof.material')}
diff --git a/src/locales/ja.json b/src/locales/ja.json index 76f16b36..64b2f0f4 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -174,6 +174,7 @@ "modal.roof.alloc.info": "※配置面初期設定で保存した[基本屋根材]を変更したり、屋根材を追加して割り当てることができます。", "modal.roof.alloc.default.roof.material": "基本屋根材", "modal.roof.alloc.select.roof.material": "屋根材の選択", + "modal.roof.alloc.add.roof.material": "지붕재 추가(JA)", "modal.roof.alloc.select.parallel": "筋配置", "modal.roof.alloc.select.stairs": "千鳥配置", "modal.roof.alloc.apply": "選択した屋根材として割り当て", diff --git a/src/locales/ko.json b/src/locales/ko.json index 0a1119d0..9252ac19 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -174,6 +174,7 @@ "modal.roof.alloc.info": "※ 배치면 초기설정에서 저장한 [기본 지붕재]를 변경하거나 지붕재를 추가하여 할당할 수 있습니다.", "modal.roof.alloc.default.roof.material": "기본 지붕재", "modal.roof.alloc.select.roof.material": "지붕재 선택", + "modal.roof.alloc.add.roof.material": "지붕재 추가", "modal.roof.alloc.select.parallel": "병렬식", "modal.roof.alloc.select.stairs": "계단식", "modal.roof.alloc.apply": "선택한 지붕재로 할당", From f061f88c233c10e7b3586d2416e01908cb2cfe42 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 5 Mar 2025 15:18:53 +0900 Subject: [PATCH 235/352] =?UTF-8?q?initRoofs=20=EB=88=84=EB=9D=BD=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 66d13c88..ebb31fa6 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -186,6 +186,7 @@ export default function CanvasMenu(props) { const modules = canvas .getObjects() .filter((obj) => [POLYGON_TYPE.MODULE_SETUP_SURFACE, POLYGON_TYPE.MODULE, POLYGON_TYPE.OBJECT_SURFACE].includes(obj.name)) + initRoofs() if (modules.length > 0) { swalFire({ From 316dc2c4ff300bf709eabb131eba1ba2726b0403 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 5 Mar 2025 15:33:28 +0900 Subject: [PATCH 236/352] =?UTF-8?q?group=20=EB=82=B4=EB=B6=80=20lengthText?= =?UTF-8?q?=EB=8F=84=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/option/useCanvasSetting.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js index 6567838f..5219a6a5 100644 --- a/src/hooks/option/useCanvasSetting.js +++ b/src/hooks/option/useCanvasSetting.js @@ -221,6 +221,14 @@ export function useCanvasSetting(executeEffect = true) { } const { column } = corridorDimension const lengthTexts = canvas.getObjects().filter((obj) => obj.name === 'lengthText') + const group = canvas.getObjects().filter((obj) => obj.type === 'group') + group.forEach((obj) => { + obj._objects + .filter((obj2) => obj2.name === 'lengthText') + .forEach((obj3) => { + lengthTexts.push(obj3) + }) + }) switch (column) { case 'corridorDimension': From c8e18bee17630f692655148f8a7863ba4ca2d428 Mon Sep 17 00:00:00 2001 From: basssy Date: Wed, 5 Mar 2025 16:27:41 +0900 Subject: [PATCH 237/352] alert => swalFire --- src/components/estimate/Estimate.jsx | 8 ++------ src/components/main/ChangePasswordPop.jsx | 6 +++++- src/components/management/Stuff.jsx | 5 ++++- src/components/management/StuffDetail.jsx | 5 ----- src/components/management/StuffHeader.jsx | 11 ++++++++--- src/components/management/StuffSearchCondition.jsx | 12 ++++++++++-- 6 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index da241db1..b6bdbfef 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -46,7 +46,6 @@ export default function Estimate({}) { const [selection, setSelection] = useState(new Set()) //견적특이사항 접고 펼치기 - // const [hidden, setHidden] = useState(false) const [hidden, setHidden] = useState(true) //아이템 자동완성 리스트 @@ -569,7 +568,7 @@ export default function Estimate({}) { return selection.size === getAbledItems(estimateContextState.itemList).length } - //row 체크박스 컨트롤 + //아이템row 체크박스 컨트롤 const onChangeSelect = (dispOrder) => { const newSelection = new Set(selection) if (newSelection.has(dispOrder)) { @@ -581,10 +580,6 @@ export default function Estimate({}) { setSelection(newSelection) } - function formatNumberWithComma(number) { - return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') - } - //주택PKG input 변경 const onChangePkgAsp = (value) => { if (estimateContextState.estimateType === 'YJSS') { @@ -1140,6 +1135,7 @@ export default function Estimate({}) { } } }, [estimateContextState]) + return (
diff --git a/src/components/main/ChangePasswordPop.jsx b/src/components/main/ChangePasswordPop.jsx index dbc9d6e4..54075153 100644 --- a/src/components/main/ChangePasswordPop.jsx +++ b/src/components/main/ChangePasswordPop.jsx @@ -119,7 +119,11 @@ export default function ChangePasswordPop(props) { }, }) } else { - alert(res?.result?.resultMsg) + swalFire({ + text: getMessage(res?.result?.resultMsg), + type: 'alert', + icon: 'error', + }) } } else { setIsGlobalLoading(false) diff --git a/src/components/management/Stuff.jsx b/src/components/management/Stuff.jsx index 0a3be3ee..43446209 100644 --- a/src/components/management/Stuff.jsx +++ b/src/components/management/Stuff.jsx @@ -75,7 +75,10 @@ export default function Stuff() { type: 'alert', }) } catch (err) { - alert(getMessage('stuff.detail.header.failCopy')) + swalFire({ + text: getMessage('stuff.detail.header.failCopy'), + type: 'alert', + }) } finally { textArea.remove() } diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index f4d7fbd4..266f1779 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -107,7 +107,6 @@ export default function StuffDetail() { const [areaIdList, setAreaIdList] = useState([]) //발전시뮬레이션 리스트 - const [isFormValid, setIsFormValid] = useState(false) //임시저장, 진짜저장 버튼 컨트롤 const [showAddressButtonValid, setShowAddressButtonValid] = useState(false) //주소검색팝업 활성화 컨트롤 const [showDesignRequestButtonValid, setShowDesignRequestButtonValid] = useState(false) //설계의뢰팝업 활성화 컨트롤 const [showWindSpeedButtonValid, setShowWindSpeedButtonValid] = useState(false) //풍속선택팝업 활성화 컨트롤 @@ -1094,8 +1093,6 @@ export default function StuffDetail() { if (!formData.installHeight) { errors.installHeight = true } - - setIsFormValid(Object.keys(errors).length === 0 ? true : false) } else { //상세일떄 폼체크 const formData = form.getValues() @@ -1140,8 +1137,6 @@ export default function StuffDetail() { if (!formData.installHeight) { errors.installHeight = true } - - setIsFormValid(Object.keys(errors).length === 0 ? true : false) } }, [ _receiveUser, diff --git a/src/components/management/StuffHeader.jsx b/src/components/management/StuffHeader.jsx index d669ad7a..1f68d68a 100644 --- a/src/components/management/StuffHeader.jsx +++ b/src/components/management/StuffHeader.jsx @@ -4,7 +4,6 @@ import { useContext, useEffect } from 'react' import { useMessage } from '@/hooks/useMessage' import dayjs from 'dayjs' import { GlobalDataContext } from '@/app/GlobalDataProvider' -// import { ManagementContext } from '@/app/management/ManagementProvider' import { useSwal } from '@/hooks/useSwal' export default function StuffHeader() { const { getMessage } = useMessage() @@ -23,7 +22,10 @@ export default function StuffHeader() { }) }) .catch(() => { - alert(getMessage('stuff.detail.header.failCopy')) + swalFire({ + text: getMessage('stuff.detail.header.failCopy'), + type: 'alert', + }) }) } else { // Use the 'out of viewport hidden text area' trick @@ -44,7 +46,10 @@ export default function StuffHeader() { type: 'alert', }) } catch (err) { - alert(getMessage('stuff.detail.header.failCopy')) + swalFire({ + text: getMessage('stuff.detail.header.failCopy'), + type: 'alert', + }) } finally { textArea.remove() } diff --git a/src/components/management/StuffSearchCondition.jsx b/src/components/management/StuffSearchCondition.jsx index 05c00a13..c00e8bd6 100644 --- a/src/components/management/StuffSearchCondition.jsx +++ b/src/components/management/StuffSearchCondition.jsx @@ -18,6 +18,7 @@ import { isObjectNotEmpty } from '@/util/common-utils' import { SessionContext } from '@/app/SessionProvider' import { QcastContext } from '@/app/QcastProvider' +import { useSwal } from '@/hooks/useSwal' export default function StuffSearchCondition() { const router = useRouter() @@ -73,17 +74,24 @@ export default function StuffSearchCondition() { const [otherSaleStoreId, setOtherSaleStoreId] = useState('') const { setIsGlobalLoading } = useContext(QcastContext) + const { swalFire } = useSwal() // 조회 const onSubmit = () => { let diff = dayjs(endDate).diff(startDate, 'day') if (diff > 366) { - return alert(getMessage('stuff.message.periodError')) + return swalFire({ + text: getMessage('stuff.message.periodError'), + type: 'alert', + }) } if (isNaN(diff)) { - return alert(getMessage('stuff.message.periodError')) + return swalFire({ + text: getMessage('stuff.message.periodError'), + type: 'alert', + }) } setIsGlobalLoading(true) From 11d9d16ff89cc158400fe62982ede84c4bd92768 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 5 Mar 2025 16:29:34 +0900 Subject: [PATCH 238/352] =?UTF-8?q?texts=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/usePolygon.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hooks/usePolygon.js b/src/hooks/usePolygon.js index 04507c17..c9528e72 100644 --- a/src/hooks/usePolygon.js +++ b/src/hooks/usePolygon.js @@ -48,6 +48,7 @@ export const usePolygon = () => { canvas.remove(text) }) const lines = polygon.lines + polygon.texts = [] lines.forEach((line, i) => { const length = line.getLength() @@ -102,7 +103,7 @@ export const usePolygon = () => { parent: polygon, name: 'lengthText', }) - + polygon.texts.push(text) canvas.add(text) }) From 8fb523cf3dafad4862d6bf540970664e2f514b1b Mon Sep 17 00:00:00 2001 From: yjnoh Date: Wed, 5 Mar 2025 17:14:03 +0900 Subject: [PATCH 239/352] =?UTF-8?q?=20=EC=82=BC=EA=B0=81=EB=8F=84=EB=A8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/object/useObjectBatch.js | 364 ++++++++++++++-------- src/hooks/surface/useSurfaceShapeBatch.js | 4 +- src/hooks/usePolygon.js | 6 +- 3 files changed, 242 insertions(+), 132 deletions(-) diff --git a/src/hooks/object/useObjectBatch.js b/src/hooks/object/useObjectBatch.js index 61a785bc..de4671dc 100644 --- a/src/hooks/object/useObjectBatch.js +++ b/src/hooks/object/useObjectBatch.js @@ -5,7 +5,14 @@ import { useRecoilValue } from 'recoil' import { canvasState } from '@/store/canvasAtom' import { BATCH_TYPE, INPUT_TYPE, POLYGON_TYPE } from '@/common/common' import { useEvent } from '@/hooks/useEvent' -import { pointsToTurfPolygon, polygonToTurfPolygon, rectToPolygon, triangleToPolygon, getDegreeByChon } from '@/util/canvas-util' +import { + pointsToTurfPolygon, + polygonToTurfPolygon, + rectToPolygon, + triangleToPolygon, + getDegreeByChon, + toFixedWithoutRounding, +} from '@/util/canvas-util' import { useSwal } from '@/hooks/useSwal' import * as turf from '@turf/turf' import { usePolygon } from '@/hooks/usePolygon' @@ -13,6 +20,7 @@ import { QPolygon } from '@/components/fabric/QPolygon' import { v4 as uuidv4 } from 'uuid' import { fontSelector } from '@/store/fontAtom' import { useRoofFn } from '@/hooks/common/useRoofFn' +import { roofDisplaySelector } from '@/store/settingAtom' export function useObjectBatch({ isHidden, setIsHidden }) { const { getMessage } = useMessage() @@ -23,6 +31,9 @@ export function useObjectBatch({ isHidden, setIsHidden }) { const { drawDirectionArrow } = usePolygon() const { setSurfaceShapePattern } = useRoofFn() const lengthTextFont = useRecoilValue(fontSelector('lengthText')) + const roofDisplay = useRecoilValue(roofDisplaySelector) + + const { addPolygon } = usePolygon() useEffect(() => { if (canvas) { @@ -293,6 +304,15 @@ export function useObjectBatch({ isHidden, setIsHidden }) { if (buttonAct === 3) { let groupDormerPoints = [] //나중에 offset을 위한 포인트 저장용 + let bottomLength = 0, + bottomOffsetLength = 0, + planeHypotenuse = 0, + planeOffsetHypotenuse = 0, + actualBottomLength = 0, + actualBottomOffsetLength = 0, + actualHypotenuse = 0, + actualOffsetHypotenuse = 0 + addCanvasMouseEventListener('mouse:move', (e) => { isDown = true if (!isDown) return @@ -306,57 +326,51 @@ export function useObjectBatch({ isHidden, setIsHidden }) { } }) - console.log('selectedSurface', selectedSurface) + if (selectedSurface) { + const roofAngle = selectedSurface.roofMaterial.angle - const roofAngle = selectedSurface.roofMaterial.angle + theta = Math.atan(Math.tan((roofAngle * Math.PI) / 180) / Math.tan((dormerAngle * Math.PI) / 180)) - theta = Math.atan(Math.tan((roofAngle * Math.PI) / 180) / Math.tan((dormerAngle * Math.PI) / 180)) + //센터 삼각형용 + bottomLength = Number((Math.tan(theta) * height).toFixed()) - const bottomLength = Number((Math.tan(theta) * height).toFixed()) - const bottomOffsetLength = Number((Math.tan(theta) * (height + offsetRef)).toFixed()) + //좌우 삼각형용 + bottomOffsetLength = Number((Math.tan(theta) * (height + offsetRef)).toFixed()) - let angle = 0 - if (directionRef === 'left') { - //서 - angle = 90 - } else if (directionRef === 'right') { - //동 - angle = 270 - } else if (directionRef === 'up') { - //북 - angle = 180 - } + planeHypotenuse = Math.sqrt(Math.pow(height, 2) + Math.pow(bottomLength, 2)) - dormer = new fabric.Triangle({ - fill: 'white', - stroke: 'red', - strokeDashArray: [5, 5], - strokeWidth: 1, - width: bottomLength * 2, - height: height, - left: pointer.x, - top: pointer.y, - selectable: true, - lockMovementX: true, - lockMovementY: true, - lockRotation: true, - lockScalingX: true, - lockScalingY: true, - name: dormerTempName, - originX: 'center', - originY: 'top', - angle: angle, - }) - canvas?.add(dormer) + actualBottomLength = Math.sqrt( + Math.pow(Math.tan(theta) * height, 2) + Math.pow(Math.tan(theta) * height * Math.tan((dormerAngle * Math.PI) / 180), 2), + ) + actualHypotenuse = Math.sqrt(Math.pow(height, 2) + Math.pow(actualBottomLength, 2)) - if (offsetRef > 0) { - dormerOffset = new fabric.Triangle({ - fill: 'gray', + actualBottomOffsetLength = Math.sqrt( + Math.pow(Math.tan(theta) * (height + offsetRef), 2) + + Math.pow(Math.tan(theta) * (height + offsetRef) * Math.tan((dormerAngle * Math.PI) / 180), 2), + ) + + planeOffsetHypotenuse = Math.sqrt(Math.pow(height + offsetRef, 2) + Math.pow(bottomOffsetLength, 2)) + actualOffsetHypotenuse = Math.sqrt(Math.pow(height + offsetRef, 2) + Math.pow(actualBottomOffsetLength, 2)) + + let angle = 0 + if (directionRef === 'left') { + //서 + angle = 90 + } else if (directionRef === 'right') { + //동 + angle = 270 + } else if (directionRef === 'up') { + //북 + angle = 180 + } + + dormer = new fabric.Triangle({ + fill: 'white', stroke: 'red', strokeDashArray: [5, 5], strokeWidth: 1, - width: bottomOffsetLength * 2, - height: height + offsetRef, + width: bottomLength * 2, + height: height, left: pointer.x, top: pointer.y, selectable: true, @@ -369,9 +383,33 @@ export function useObjectBatch({ isHidden, setIsHidden }) { originX: 'center', originY: 'top', angle: angle, - objectId: id, }) - canvas?.add(dormerOffset) + canvas?.add(dormer) + + if (offsetRef > 0) { + dormerOffset = new fabric.Triangle({ + fill: 'gray', + stroke: 'red', + strokeDashArray: [5, 5], + strokeWidth: 1, + width: bottomOffsetLength * 2, + height: height + offsetRef, + left: pointer.x, + top: pointer.y, + selectable: true, + lockMovementX: true, + lockMovementY: true, + lockRotation: true, + lockScalingX: true, + lockScalingY: true, + name: dormerTempName, + originX: 'center', + originY: 'top', + angle: angle, + objectId: id, + }) + canvas?.add(dormerOffset) + } } }) @@ -418,68 +456,120 @@ export function useObjectBatch({ isHidden, setIsHidden }) { strokeDashArray: [0], }) //오프셋이 있을땐 같이 도머로 만든다 - const leftTriangle = new QPolygon(leftPoints, { - fill: 'white', - stroke: 'black', - strokeWidth: 1, - selectable: true, - lockMovementX: true, // X 축 이동 잠금 - lockMovementY: true, // Y 축 이동 잠금 - lockRotation: true, // 회전 잠금 - viewLengthText: true, - // direction: direction, - originX: 'center', - originY: 'center', - name: dormerName, - pitch: pitch, - fontSize: lengthTextFont.fontSize.value, - fontStyle: lengthTextFont.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal', - fontWeight: lengthTextFont.fontWeight.value, - groupPoints: groupPoints, - dormerAttributes: { - height: height, - width: width, + const leftTriangle = addPolygon( + leftPoints, + { + fill: 'white', + stroke: 'black', + strokeWidth: 1, + selectable: true, + lockMovementX: true, // X 축 이동 잠금 + lockMovementY: true, // Y 축 이동 잠금 + lockRotation: true, // 회전 잠금 + viewLengthText: true, + // direction: direction, + originX: 'center', + originY: 'center', + name: dormerName, pitch: pitch, - offsetRef: offsetRef, - offsetWidthRef: offsetWidthRef, - directionRef: directionRef, + fontSize: lengthTextFont.fontSize.value, + fontStyle: lengthTextFont.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal', + fontWeight: lengthTextFont.fontWeight.value, + groupPoints: groupPoints, + dormerAttributes: { + height: height, + width: width, + pitch: pitch, + offsetRef: offsetRef, + offsetWidthRef: offsetWidthRef, + directionRef: directionRef, + }, + lines: [ + { + attributes: { + planeSize: toFixedWithoutRounding(planeOffsetHypotenuse, 1) * 10, + actualSize: toFixedWithoutRounding(actualOffsetHypotenuse, 1) * 10, + }, + }, + { + attributes: { + planeSize: toFixedWithoutRounding(bottomOffsetLength, 1) * 10, + actualSize: toFixedWithoutRounding(actualBottomOffsetLength, 1) * 10, + }, + }, + { + attributes: { + planeSize: toFixedWithoutRounding(height + offsetRef, 1) * 10, + actualSize: toFixedWithoutRounding(height + offsetRef, 1) * 10, + }, + }, + ], }, + false, + ) + + leftTriangle.texts.forEach((text) => { + text.bringToFront() }) - const rightTriangle = new QPolygon(rightPoints, { - fill: 'white', - stroke: 'black', - strokeWidth: 1, - selectable: true, - lockMovementX: true, // X 축 이동 잠금 - lockMovementY: true, // Y 축 이동 잠금 - lockRotation: true, // 회전 잠금 - viewLengthText: true, - // direction: direction, - originX: 'center', - originY: 'center', - name: dormerName, - pitch: pitch, - fontSize: lengthTextFont.fontSize.value, - fontStyle: lengthTextFont.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal', - fontWeight: lengthTextFont.fontWeight.value, - groupPoints: groupPoints, - dormerAttributes: { - height: height, - width: width, + const rightTriangle = addPolygon( + rightPoints, + { + fill: 'white', + stroke: 'black', + strokeWidth: 1, + selectable: true, + lockMovementX: true, // X 축 이동 잠금 + lockMovementY: true, // Y 축 이동 잠금 + lockRotation: true, // 회전 잠금 + viewLengthText: true, + // direction: direction, + originX: 'center', + originY: 'center', + name: dormerName, pitch: pitch, - offsetRef: offsetRef, - offsetWidthRef: offsetWidthRef, - directionRef: directionRef, + fontSize: lengthTextFont.fontSize.value, + fontStyle: lengthTextFont.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal', + fontWeight: lengthTextFont.fontWeight.value, + groupPoints: groupPoints, + dormerAttributes: { + height: height, + width: width, + pitch: pitch, + offsetRef: offsetRef, + offsetWidthRef: offsetWidthRef, + directionRef: directionRef, + }, + lines: [ + { + attributes: { + planeSize: toFixedWithoutRounding(height + offsetRef, 1) * 10, + actualSize: toFixedWithoutRounding(height + offsetRef, 1) * 10, + }, + }, + { + attributes: { + planeSize: toFixedWithoutRounding(bottomOffsetLength, 1) * 10, + actualSize: toFixedWithoutRounding(actualBottomOffsetLength, 1) * 10, + }, + }, + { + attributes: { + planeSize: toFixedWithoutRounding(planeOffsetHypotenuse, 1) * 10, + actualSize: toFixedWithoutRounding(actualOffsetHypotenuse, 1) * 10, + }, + }, + ], }, - }) + false, + ) // canvas?.add(leftTriangle) // canvas?.add(rightTriangle) //패턴 - setSurfaceShapePattern(leftTriangle) - setSurfaceShapePattern(rightTriangle) + setSurfaceShapePattern(leftTriangle, roofDisplay.column, false, selectedSurface.roofMaterial, true) + setSurfaceShapePattern(rightTriangle, roofDisplay.column, false, selectedSurface.roofMaterial, true) //방향 // drawDirectionArrow(leftTriangle) @@ -492,33 +582,57 @@ export function useObjectBatch({ isHidden, setIsHidden }) { if (offsetRef > 0) { canvas?.remove(dormer) - offsetPolygon = new QPolygon(triangleToPolygon(dormer), { - selectable: true, - lockMovementX: true, // X 축 이동 잠금 - lockMovementY: true, // Y 축 이동 잠금 - lockRotation: true, // 회전 잠금 - viewLengthText: true, - name: 'triangleDormerOffset', - id: id, - fill: 'rgba(255, 255, 255, 0.6)', - stroke: 'black', - strokeWidth: 1, - originX: 'center', - originY: 'top', - fontSize: lengthTextFont.fontSize.value, - fontStyle: lengthTextFont.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal', - fontWeight: lengthTextFont.fontWeight.value, - angle: originAngle, - pitch: pitch, - dormerAttributes: { - height: height, - width: width, + offsetPolygon = addPolygon( + triangleToPolygon(dormer), + { + selectable: true, + lockMovementX: true, // X 축 이동 잠금 + lockMovementY: true, // Y 축 이동 잠금 + lockRotation: true, // 회전 잠금 + viewLengthText: true, + name: 'triangleDormerOffset', + id: id, + fill: 'rgba(255, 255, 255, 0.6)', + stroke: 'black', + strokeWidth: 1, + originX: 'center', + originY: 'top', + fontSize: lengthTextFont.fontSize.value, + fontStyle: lengthTextFont.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal', + fontWeight: lengthTextFont.fontWeight.value, + angle: originAngle, pitch: pitch, - offsetRef: offsetRef, - offsetWidthRef: offsetWidthRef, - directionRef: directionRef, + dormerAttributes: { + height: height, + width: width, + pitch: pitch, + offsetRef: offsetRef, + offsetWidthRef: offsetWidthRef, + directionRef: directionRef, + }, + lines: [ + { + attributes: { + planeSize: toFixedWithoutRounding(planeHypotenuse, 1) * 10, + actualSize: toFixedWithoutRounding(actualHypotenuse, 1) * 10, + }, + }, + { + attributes: { + planeSize: toFixedWithoutRounding(bottomLength * 2, 1) * 10, + actualSize: toFixedWithoutRounding(bottomLength * 2, 1) * 10, + }, + }, + { + attributes: { + planeSize: toFixedWithoutRounding(planeHypotenuse, 1) * 10, + actualSize: toFixedWithoutRounding(actualHypotenuse, 1) * 10, + }, + }, + ], }, - }) + false, + ) } const groupPolygon = offsetPolygon ? [leftTriangle, rightTriangle, offsetPolygon] : [leftTriangle, rightTriangle] @@ -534,10 +648,6 @@ export function useObjectBatch({ isHidden, setIsHidden }) { }) canvas?.add(objectGroup) - objectGroup.getObjects().forEach((obj, index) => { - console.log(`최초 pathOffset ${index}`, obj.get('pathOffset')) - }) - objectGroup._objects.forEach((obj) => { if (obj.hasOwnProperty('texts')) { obj.texts.forEach((text) => { @@ -548,7 +658,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) { isDown = false initEvent() - dbClickEvent() + // dbClickEvent() if (setIsHidden) setIsHidden(false) } }) @@ -805,7 +915,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) { isDown = false initEvent() - dbClickEvent() + // dbClickEvent() } }) } diff --git a/src/hooks/surface/useSurfaceShapeBatch.js b/src/hooks/surface/useSurfaceShapeBatch.js index 07532422..2bfcde38 100644 --- a/src/hooks/surface/useSurfaceShapeBatch.js +++ b/src/hooks/surface/useSurfaceShapeBatch.js @@ -26,7 +26,7 @@ import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { const { getMessage } = useMessage() - const { drawDirectionArrow } = usePolygon() + const { drawDirectionArrow, addPolygon } = usePolygon() const lengthTextFont = useRecoilValue(fontSelector('lengthText')) const resetOuterLinePoints = useResetRecoilState(outerLinePointsState) const resetPlacementShapeDrawingPoints = useResetRecoilState(placementShapeDrawingPointsState) @@ -178,7 +178,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { } //회전, flip등이 먹은 기준으로 새로생성 - const batchSurface = new QPolygon(obj.getCurrentPoints(), { + const batchSurface = addPolygon(obj.getCurrentPoints(), { fill: 'transparent', stroke: 'red', strokeWidth: 3, diff --git a/src/hooks/usePolygon.js b/src/hooks/usePolygon.js index c9528e72..54de877b 100644 --- a/src/hooks/usePolygon.js +++ b/src/hooks/usePolygon.js @@ -17,16 +17,16 @@ export const usePolygon = () => { const currentAngleType = useRecoilValue(currentAngleTypeSelector) const pitchText = useRecoilValue(pitchTextSelector) - const addPolygon = (points, options) => { + const addPolygon = (points, options, isAddCanvas = true) => { const polygon = new QPolygon(points, { ...options, fontSize: lengthTextFontOptions.fontSize.value, fill: options.fill || 'transparent', stroke: options.stroke || '#000000', - selectable: true, + // selectable: true, }) - canvas?.add(polygon) + if (isAddCanvas) canvas?.add(polygon) addLengthText(polygon) return polygon From 659691b7508db917baea6a43481e121a385e1f09 Mon Sep 17 00:00:00 2001 From: basssy Date: Wed, 5 Mar 2025 17:29:16 +0900 Subject: [PATCH 240/352] =?UTF-8?q?=EB=AC=BC=EA=B1=B4=EC=83=81=EC=84=B8=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=EC=97=90=EC=84=9C=20=EB=8F=84=EB=A9=B4?= =?UTF-8?q?=EC=9E=91=EC=84=B1=20=EC=9D=B4=EB=8F=99=EC=8B=9C.=20=ED=94=8C?= =?UTF-8?q?=EB=9E=9C2=EA=B0=9C=EC=9D=B4=EC=83=81=EC=9D=BC=EB=95=8C=20?= =?UTF-8?q?=EC=B2=AB=EB=B2=88=EC=A7=B8=20=ED=94=8C=EB=9E=9C=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=EA=B0=80=EB=8A=A5=20=EB=B3=80=EA=B2=BD=EA=B1=B4=20?= =?UTF-8?q?=EB=8C=80=EC=9D=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/management/StuffSubHeader.jsx | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/components/management/StuffSubHeader.jsx b/src/components/management/StuffSubHeader.jsx index c22f4cb8..f35c6c53 100644 --- a/src/components/management/StuffSubHeader.jsx +++ b/src/components/management/StuffSubHeader.jsx @@ -49,20 +49,18 @@ export default function StuffSubHeader({ type }) { const searchParams = useSearchParams() const objectNo = searchParams.get('objectNo') //url에서 물건번호 꺼내서 바로 set - // url에 물건번호로 도면작성화면으로 이동 + /** + * 도면작성은 플랜1번의 도면작성화면으로 이동하기 때문에 -> 플랜1번이 삭제가능으로 변경되서 planList의 0번째로! + * 1.물건작성하고 바로 -> planList 생성전. surface + * 2.물건이 여러건있을때 1번 플랜의 estimateDate 여부로 selectedMenu 셋팅 + */ const moveFloorPlan = () => { setFloorPlanObjectNo({ floorPlanObjectNo: objectNo }) - const param = { - pid: '1', + pid: managementState?.planList?.length === 0 ? '1' : managementState?.planList[0].planNo, objectNo: objectNo, } - /** - * 도면작성은 플랜1번의 도면작성화면으로 이동하기 때문에 - * 1.물건작성하고 바로 -> planList 생성전. surface - * 2.물건이 여러건있을때 1번 플랜의 estimateDate 여부로 selectedMenu 셋팅 - */ if (managementState?.planList?.length === 0) { setSelectedMenu('surface') } else { @@ -72,6 +70,7 @@ export default function StuffSubHeader({ type }) { setSelectedMenu('surface') } } + const url = `/floor-plan?${queryStringFormatter(param)}` router.push(url) From e32d23b5d78444fd8ddd1d666ef41a725dfef862 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Wed, 5 Mar 2025 18:25:16 +0900 Subject: [PATCH 241/352] =?UTF-8?q?=F0=9F=93=8Cfix:=20=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=95=84=EC=9B=83=20=EC=B2=98=EB=A6=AC=ED=9B=84=20=EB=9D=BC?= =?UTF-8?q?=EC=9A=B0=ED=84=B0=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/header/Header.jsx | 4 +++- src/lib/authActions.js | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/header/Header.jsx b/src/components/header/Header.jsx index ab6b74b7..3e3eabb3 100644 --- a/src/components/header/Header.jsx +++ b/src/components/header/Header.jsx @@ -2,7 +2,7 @@ import { Fragment, useCallback, useContext, useEffect, useState } from 'react' import Link from 'next/link' -import { usePathname } from 'next/navigation' +import { usePathname, useRouter } from 'next/navigation' import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil' import { dimmedStore, sessionStore } from '@/store/commonAtom' @@ -38,6 +38,7 @@ export const ToggleonMouse = (e, act, target) => { export default function Header(props) { const [userInfoModal, setUserInfoModal] = useState(false) + const router = useRouter() const [stuffSearch, setStuffSearch] = useRecoilState(stuffSearchState) @@ -265,6 +266,7 @@ export default function Header(props) { code: 'DELETE', }) logout() + router.replace('/login') }} > {getMessage('header.logout')} diff --git a/src/lib/authActions.js b/src/lib/authActions.js index 68dab9f7..5a63d684 100644 --- a/src/lib/authActions.js +++ b/src/lib/authActions.js @@ -9,7 +9,7 @@ import { sessionOptions } from './session' export async function logout() { const session = await getSession() session.destroy() - redirect('/login') + // redirect('/login') } export async function getSession() { From 6bdfac04e759a15617c47d32420dc857f8f798f8 Mon Sep 17 00:00:00 2001 From: basssy Date: Thu, 6 Mar 2025 09:19:51 +0900 Subject: [PATCH 242/352] =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=ED=9B=84?= =?UTF-8?q?=20=EB=8B=A4=EB=A5=B8=20=EB=A9=94=EB=93=80=20=EC=9D=B4=EB=8F=99?= =?UTF-8?q?=ED=9B=84=20=EB=A1=9C=EA=B7=B8=EC=95=84=EC=9B=83.=20=EB=92=A4?= =?UTF-8?q?=EB=A1=9C=EA=B0=80=EA=B8=B0=ED=95=98=EB=A9=B4=20=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=EC=9C=BC=EB=A1=9C=20=EC=9D=B4=EB=8F=99=EB=90=98?= =?UTF-8?q?=EB=8A=94=20=ED=98=84=EC=83=81=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/main/useMainContentsController.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/hooks/main/useMainContentsController.js b/src/hooks/main/useMainContentsController.js index 09b4fc0c..46c9ef8a 100644 --- a/src/hooks/main/useMainContentsController.js +++ b/src/hooks/main/useMainContentsController.js @@ -4,13 +4,22 @@ import { useContext, useEffect } from 'react' import { useAxios } from '../useAxios' import { SessionContext } from '@/app/SessionProvider' import { QcastContext } from '@/app/QcastProvider' +import { checkSession } from '@/lib/authActions' +import { useRouter } from 'next/navigation' export const useMainContentsController = () => { const { session } = useContext(SessionContext) const { promiseGet } = useAxios() const { setQcastState, setIsGlobalLoading } = useContext(QcastContext) + const router = useRouter() useEffect(() => { + console.log('111111111111111111111111111111') + checkSession().then((res) => { + if (!res) { + router.replace('/login') + } + }) setIsGlobalLoading(true) }, []) From c5ea37acff33176bd47204c350ad1c25e5139c29 Mon Sep 17 00:00:00 2001 From: basssy Date: Thu, 6 Mar 2025 09:20:42 +0900 Subject: [PATCH 243/352] =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=ED=9B=84=20?= =?UTF-8?q?=EB=8B=A4=EB=A5=B8=EB=A9=94=EB=89=B4=20=EC=9D=B4=EB=8F=99=20?= =?UTF-8?q?=ED=9B=84=20=EB=A1=9C=EA=B7=B8=EC=95=84=EC=9B=83.=20=EB=92=A4?= =?UTF-8?q?=EB=A1=9C=EA=B0=80=EA=B8=B0=ED=95=98=EB=A9=B4=20=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=EC=9C=BC=EB=A1=9C=20=EC=9D=B4=EB=8F=99=EB=90=98?= =?UTF-8?q?=EB=8A=94=20=ED=98=84=EC=83=81=20=EB=8C=80=EC=9D=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/main/useMainContentsController.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hooks/main/useMainContentsController.js b/src/hooks/main/useMainContentsController.js index 46c9ef8a..5b620475 100644 --- a/src/hooks/main/useMainContentsController.js +++ b/src/hooks/main/useMainContentsController.js @@ -14,7 +14,6 @@ export const useMainContentsController = () => { const router = useRouter() useEffect(() => { - console.log('111111111111111111111111111111') checkSession().then((res) => { if (!res) { router.replace('/login') From e32a4d7a33c346e308739b2acc3dc0c4fb2951fb Mon Sep 17 00:00:00 2001 From: yjnoh Date: Thu, 6 Mar 2025 10:14:04 +0900 Subject: [PATCH 244/352] =?UTF-8?q?=EC=98=A4=EA=B0=81=ED=98=95=20=EB=8F=84?= =?UTF-8?q?=EB=A8=B8=20=EC=8B=A4=EC=B8=A1=EC=B9=98=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/object/useObjectBatch.js | 392 +++++++++++++++++++---------- 1 file changed, 257 insertions(+), 135 deletions(-) diff --git a/src/hooks/object/useObjectBatch.js b/src/hooks/object/useObjectBatch.js index de4671dc..8a6c797a 100644 --- a/src/hooks/object/useObjectBatch.js +++ b/src/hooks/object/useObjectBatch.js @@ -300,19 +300,23 @@ export function useObjectBatch({ isHidden, setIsHidden }) { let theta = 0 + let bottomLength = 0, + bottomOffsetLength = 0, + planeHypotenuse = 0, + planeOffsetHypotenuse = 0, + actualBottomLength = 0, + actualBottomOffsetLength = 0, + actualHypotenuse = 0, + actualOffsetHypotenuse = 0, + shortHeight = 0, + shortOffsetHeight = 0, + extraHeight = 0, + extraOffsetHeight = 0 + //삼각형 도머 if (buttonAct === 3) { let groupDormerPoints = [] //나중에 offset을 위한 포인트 저장용 - let bottomLength = 0, - bottomOffsetLength = 0, - planeHypotenuse = 0, - planeOffsetHypotenuse = 0, - actualBottomLength = 0, - actualBottomOffsetLength = 0, - actualHypotenuse = 0, - actualOffsetHypotenuse = 0 - addCanvasMouseEventListener('mouse:move', (e) => { isDown = true if (!isDown) return @@ -664,7 +668,6 @@ export function useObjectBatch({ isHidden, setIsHidden }) { }) } else if (buttonAct === 4) { const heightLength = height - (width / 2) * (pitch * 0.25) - //(동의길이 깊이)+출폭(깊이)-[(입력한 폭값)/2+출폭(폭)]*(0.25*입력한 寸) const heightOffsetLength = height + offsetRef - (width / 2 + offsetWidthRef) * (pitch * 0.25) addCanvasMouseEventListener('mouse:move', (e) => { @@ -680,55 +683,57 @@ export function useObjectBatch({ isHidden, setIsHidden }) { } }) - let angle = 0 - if (directionRef === 'left') { - //서 - angle = 90 - } else if (directionRef === 'right') { - //동 - angle = 270 - } else if (directionRef === 'up') { - //북 - angle = 180 - } + if (selectedSurface) { + const roofAngle = selectedSurface.roofMaterial.angle - pentagonPoints = [ - { x: pointer.x, y: pointer.y }, - { x: pointer.x - width / 2, y: pointer.y + (height - heightLength) }, - { x: pointer.x - width / 2, y: pointer.y + height }, - { x: pointer.x + width / 2, y: pointer.y + height }, - { x: pointer.x + width / 2, y: pointer.y + (height - heightLength) }, - ] + theta = Math.atan(Math.tan((roofAngle * Math.PI) / 180) / Math.tan((dormerAngle * Math.PI) / 180)) - pentagonOffsetPoints = [ - { x: pointer.x, y: pointer.y }, - { x: pointer.x - width / 2 - offsetWidthRef, y: pointer.y + height + offsetRef - heightOffsetLength }, - { x: pointer.x - width / 2 - offsetWidthRef, y: pointer.y + height + offsetRef }, - { x: pointer.x + width / 2 + offsetWidthRef, y: pointer.y + height + offsetRef }, - { x: pointer.x + width / 2 + offsetWidthRef, y: pointer.y + height + offsetRef - heightOffsetLength }, - ] + //5각형중에 3각형의 높이 작은영역 + shortHeight = width / 2 / Math.tan(theta) + extraHeight = height - shortHeight + planeHypotenuse = Math.sqrt(Math.pow(shortHeight, 2) + Math.pow(width / 2, 2)) + actualBottomLength = Math.sqrt(Math.pow((width / 2) * Math.tan((dormerAngle * Math.PI) / 180), 2) + Math.pow(width / 2, 2)) + actualHypotenuse = Math.sqrt(Math.pow(actualBottomLength, 2) + Math.pow(shortHeight, 2)) - dormer = new QPolygon(pentagonPoints, { - fill: 'white', - stroke: 'red', - strokeDashArray: [5, 5], - strokeWidth: 1, - selectable: true, - lockMovementX: true, - lockMovementY: true, - lockRotation: true, - lockScalingX: true, - lockScalingY: true, - name: dormerTempName, - originX: 'center', - originY: 'top', - angle: angle, - }) - canvas?.add(dormer) + //큰영역 + shortOffsetHeight = (width / 2 + offsetWidthRef) / Math.tan(theta) + extraOffsetHeight = height + offsetRef - shortOffsetHeight + planeOffsetHypotenuse = Math.sqrt(Math.pow(shortOffsetHeight, 2) + Math.pow(width / 2 + offsetWidthRef, 2)) + actualBottomOffsetLength = Math.sqrt( + Math.pow((width / 2 + offsetWidthRef) * Math.tan((dormerAngle * Math.PI) / 180), 2) + Math.pow(width / 2 + +offsetWidthRef, 2), + ) + actualOffsetHypotenuse = Math.sqrt(Math.pow(actualBottomOffsetLength, 2) + Math.pow(shortOffsetHeight, 2)) - if (offsetRef > 0 || offsetWidthRef > 0) { - dormerOffset = new QPolygon(pentagonOffsetPoints, { - fill: 'gray', + let angle = 0 + if (directionRef === 'left') { + //서 + angle = 90 + } else if (directionRef === 'right') { + //동 + angle = 270 + } else if (directionRef === 'up') { + //북 + angle = 180 + } + + pentagonPoints = [ + { x: pointer.x, y: pointer.y }, + { x: pointer.x - width / 2, y: pointer.y + (height - extraHeight) }, + { x: pointer.x - width / 2, y: pointer.y + height }, + { x: pointer.x + width / 2, y: pointer.y + height }, + { x: pointer.x + width / 2, y: pointer.y + (height - extraHeight) }, + ] + + pentagonOffsetPoints = [ + { x: pointer.x, y: pointer.y }, + { x: pointer.x - width / 2 - offsetWidthRef, y: pointer.y + height + offsetRef - extraOffsetHeight }, + { x: pointer.x - width / 2 - offsetWidthRef, y: pointer.y + height + offsetRef }, + { x: pointer.x + width / 2 + offsetWidthRef, y: pointer.y + height + offsetRef }, + { x: pointer.x + width / 2 + offsetWidthRef, y: pointer.y + height + offsetRef - extraOffsetHeight }, + ] + + dormer = new QPolygon(pentagonPoints, { + fill: 'white', stroke: 'red', strokeDashArray: [5, 5], strokeWidth: 1, @@ -743,7 +748,27 @@ export function useObjectBatch({ isHidden, setIsHidden }) { originY: 'top', angle: angle, }) - canvas?.add(dormerOffset) + canvas?.add(dormer) + + if (offsetRef > 0 || offsetWidthRef > 0) { + dormerOffset = new QPolygon(pentagonOffsetPoints, { + fill: 'gray', + stroke: 'red', + strokeDashArray: [5, 5], + strokeWidth: 1, + selectable: true, + lockMovementX: true, + lockMovementY: true, + lockRotation: true, + lockScalingX: true, + lockScalingY: true, + name: dormerTempName, + originX: 'center', + originY: 'top', + angle: angle, + }) + canvas?.add(dormerOffset) + } } }) @@ -794,90 +819,23 @@ export function useObjectBatch({ isHidden, setIsHidden }) { strokeDashArray: [0], }) //오프셋이 있을땐 같이 도머로 만든다 - const leftPentagon = new QPolygon(leftPoints, { - fill: 'transparent', - stroke: 'red', - strokeWidth: 1, - selectable: true, - lockMovementX: true, // X 축 이동 잠금 - lockMovementY: true, // Y 축 이동 잠금 - lockRotation: true, // 회전 잠금 - viewLengthText: true, - fontSize: 14, - // direction: direction, - originX: 'center', - originY: 'center', - name: dormerName, - pitch: pitch, - groupPoints: groupPoints, - dormerAttributes: { - height: height, - width: width, - pitch: pitch, - offsetRef: offsetRef, - offsetWidthRef: offsetWidthRef, - directionRef: directionRef, - }, - }) - - const rightPentagon = new QPolygon(rightPoints, { - fill: 'transparent', - stroke: 'red', - strokeWidth: 1, - selectable: true, - lockMovementX: true, // X 축 이동 잠금 - lockMovementY: true, // Y 축 이동 잠금 - lockRotation: true, // 회전 잠금 - viewLengthText: true, - fontSize: 14, - // direction: direction, - originX: 'center', - originY: 'center', - name: dormerName, - pitch: pitch, - groupPoints: groupPoints, - dormerAttributes: { - height: height, - width: width, - pitch: pitch, - offsetRef: offsetRef, - offsetWidthRef: offsetWidthRef, - directionRef: directionRef, - }, - }) - - // canvas?.add(leftPentagon) - // canvas?.add(rightPentagon) - - //패턴 - setSurfaceShapePattern(leftPentagon) - setSurfaceShapePattern(rightPentagon) - //방향 - // drawDirectionArrow(leftPentagon) - // drawDirectionArrow(rightPentagon) - - let offsetPolygon - - if (offsetRef > 0) { - canvas?.remove(dormer) - - offsetPolygon = new QPolygon(dormer.points, { + const leftPentagon = addPolygon( + leftPoints, + { + fill: 'transparent', + stroke: 'red', + strokeWidth: 1, selectable: true, lockMovementX: true, // X 축 이동 잠금 lockMovementY: true, // Y 축 이동 잠금 lockRotation: true, // 회전 잠금 viewLengthText: true, - name: 'pentagonDormerOffset', - id: id, - fill: 'rgba(255, 255, 255, 0.6)', - stroke: 'black', - strokeWidth: 1, + fontSize: 14, + // direction: direction, originX: 'center', - originY: 'top', - fontSize: lengthTextFont.fontSize.value, - fontStyle: lengthTextFont.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal', - fontWeight: lengthTextFont.fontWeight.value, - angle: originAngle, + originY: 'center', + name: dormerName, + pitch: pitch, groupPoints: groupPoints, dormerAttributes: { height: height, @@ -887,7 +845,171 @@ export function useObjectBatch({ isHidden, setIsHidden }) { offsetWidthRef: offsetWidthRef, directionRef: directionRef, }, - }) + lines: [ + { + attributes: { + planeSize: toFixedWithoutRounding(planeOffsetHypotenuse, 1) * 10, + actualSize: toFixedWithoutRounding(actualOffsetHypotenuse, 1) * 10, + }, + }, + { + attributes: { + planeSize: toFixedWithoutRounding(extraOffsetHeight, 1) * 10, + actualSize: toFixedWithoutRounding(extraOffsetHeight, 1) * 10, + }, + }, + { + attributes: { + planeSize: toFixedWithoutRounding(width / 2 + offsetWidthRef, 1) * 10, + actualSize: toFixedWithoutRounding(actualBottomOffsetLength, 1) * 10, + }, + }, + { + attributes: { + planeSize: toFixedWithoutRounding(height + offsetRef, 1) * 10, + actualSize: toFixedWithoutRounding(height + offsetRef, 1) * 10, + }, + }, + ], + }, + false, + ) + + const rightPentagon = addPolygon( + rightPoints, + { + fill: 'transparent', + stroke: 'red', + strokeWidth: 1, + selectable: true, + lockMovementX: true, // X 축 이동 잠금 + lockMovementY: true, // Y 축 이동 잠금 + lockRotation: true, // 회전 잠금 + viewLengthText: true, + fontSize: 14, + // direction: direction, + originX: 'center', + originY: 'center', + name: dormerName, + pitch: pitch, + groupPoints: groupPoints, + dormerAttributes: { + height: height, + width: width, + pitch: pitch, + offsetRef: offsetRef, + offsetWidthRef: offsetWidthRef, + directionRef: directionRef, + }, + lines: [ + { + attributes: { + planeSize: toFixedWithoutRounding(height + offsetRef, 1) * 10, + actualSize: toFixedWithoutRounding(height + offsetRef, 1) * 10, + }, + }, + { + attributes: { + planeSize: toFixedWithoutRounding(width / 2 + offsetWidthRef, 1) * 10, + actualSize: toFixedWithoutRounding(actualBottomOffsetLength, 1) * 10, + }, + }, + { + attributes: { + planeSize: toFixedWithoutRounding(extraOffsetHeight, 1) * 10, + actualSize: toFixedWithoutRounding(extraOffsetHeight, 1) * 10, + }, + }, + { + attributes: { + planeSize: toFixedWithoutRounding(planeOffsetHypotenuse, 1) * 10, + actualSize: toFixedWithoutRounding(actualOffsetHypotenuse, 1) * 10, + }, + }, + ], + }, + false, + ) + + // canvas?.add(leftPentagon) + // canvas?.add(rightPentagon) + + //패턴 + + setSurfaceShapePattern(leftPentagon, roofDisplay.column, false, selectedSurface.roofMaterial, true) + setSurfaceShapePattern(rightPentagon, roofDisplay.column, false, selectedSurface.roofMaterial, true) + //방향 + // drawDirectionArrow(leftPentagon) + // drawDirectionArrow(rightPentagon) + + let offsetPolygon + + if (offsetRef > 0) { + canvas?.remove(dormer) + + offsetPolygon = addPolygon( + dormer.points, + { + selectable: true, + lockMovementX: true, // X 축 이동 잠금 + lockMovementY: true, // Y 축 이동 잠금 + lockRotation: true, // 회전 잠금 + viewLengthText: true, + name: 'pentagonDormerOffset', + id: id, + fill: 'rgba(255, 255, 255, 0.6)', + stroke: 'black', + strokeWidth: 1, + originX: 'center', + originY: 'top', + fontSize: lengthTextFont.fontSize.value, + fontStyle: lengthTextFont.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal', + fontWeight: lengthTextFont.fontWeight.value, + angle: originAngle, + groupPoints: groupPoints, + dormerAttributes: { + height: height, + width: width, + pitch: pitch, + offsetRef: offsetRef, + offsetWidthRef: offsetWidthRef, + directionRef: directionRef, + }, + lines: [ + { + attributes: { + planeSize: toFixedWithoutRounding(planeHypotenuse, 1) * 10, + actualSize: toFixedWithoutRounding(actualHypotenuse, 1) * 10, + }, + }, + { + attributes: { + planeSize: toFixedWithoutRounding(extraHeight, 1) * 10, + actualSize: toFixedWithoutRounding(extraHeight, 1) * 10, + }, + }, + { + attributes: { + planeSize: toFixedWithoutRounding(width, 1) * 10, + actualSize: toFixedWithoutRounding(actualBottomLength * 2, 1) * 10, + }, + }, + { + attributes: { + planeSize: toFixedWithoutRounding(extraHeight, 1) * 10, + actualSize: toFixedWithoutRounding(extraHeight, 1) * 10, + }, + }, + { + attributes: { + planeSize: toFixedWithoutRounding(planeHypotenuse, 1) * 10, + actualSize: toFixedWithoutRounding(actualHypotenuse, 1) * 10, + }, + }, + ], + }, + false, + ) } const groupPolygon = offsetPolygon ? [leftPentagon, rightPentagon, offsetPolygon] : [leftPentagon, rightPentagon] From 809673125e616e3a52af715e7850a83dbf26444f Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 6 Mar 2025 10:17:31 +0900 Subject: [PATCH 245/352] =?UTF-8?q?=EA=B0=80=EB=8C=80=20=EC=84=A4=EC=B9=98?= =?UTF-8?q?=20=EC=99=84=EB=A3=8C=20=EC=A0=84=20=ED=9B=84=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20=EC=B6=94=EA=B0=80=20-=20surface=20isComplete=20?= =?UTF-8?q?=EC=86=8D=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/circuitTrestle/CircuitTrestleSetting.jsx | 6 +++++- src/hooks/common/useMenu.js | 3 ++- src/hooks/module/useTrestle.js | 12 ++++++++++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index e0d32bbc..9eaeee89 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -33,7 +33,7 @@ const ALLOCATION_TYPE = { export default function CircuitTrestleSetting({ id }) { const { getMessage } = useMessage() const { closePopup } = usePopup() - const { apply, setViewCircuitNumberTexts, getEstimateData, clear: clearTrestle } = useTrestle() + const { apply, setViewCircuitNumberTexts, getEstimateData, clear: clearTrestle, setAllModuleSurfaceIsComplete } = useTrestle() const { swalFire } = useSwal() const { saveEstimate } = useEstimate() const canvas = useRecoilValue(canvasState) @@ -330,6 +330,8 @@ export default function CircuitTrestleSetting({ id }) { // 회로할당(승압설정) 저장 버튼 클릭 시 const onApply = async () => { + setAllSurfaceIsComplete(false) + setIsGlobalLoading(true) canvas .getObjects() @@ -363,9 +365,11 @@ export default function CircuitTrestleSetting({ id }) { await saveCanvas(false) // 견적서 저장 await saveEstimate(result) + setAllSurfaceIsComplete(true) } else { setIsGlobalLoading(false) } + // removeNotAllocationModules() } diff --git a/src/hooks/common/useMenu.js b/src/hooks/common/useMenu.js index d65611b5..7fdd6a31 100644 --- a/src/hooks/common/useMenu.js +++ b/src/hooks/common/useMenu.js @@ -34,7 +34,7 @@ export default function useMenu() { const [popupId, setPopupId] = useState(uuidv4()) const { addPopup } = usePopup() const { deleteAllSurfacesAndObjects } = useSurfaceShapeBatch({}) - const { clear: trestleClear } = useTrestle() + const { clear: trestleClear, setAllModuleSurfaceIsComplete } = useTrestle() const { nextStep } = useOrientation() const handleMenu = (type) => { if (type === 'outline') { @@ -90,6 +90,7 @@ export default function useMenu() { switch (currentMenu) { case MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING: trestleClear() + setAllModuleSurfaceIsComplete(false) addPopup(popupId, 1, ) break case MENU.MODULE_CIRCUIT_SETTING.CIRCUIT_TRESTLE_SETTING: diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index b122a19e..0240f519 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -602,7 +602,7 @@ export const useTrestle = () => { const quotationParam = getTrestleParams(surface, exposedBottomModules) - surface.set({ quotationParam, isComplete: true }) + surface.set({ quotationParam }) }) return true @@ -2789,5 +2789,13 @@ export const useTrestle = () => { canvas.renderAll() } - return { apply, getTrestleParams, clear, setViewCircuitNumberTexts, getEstimateData } + // 가대 설치 완료 전,후 모든 surface의 isComplete를 변경 + const setAllModuleSurfaceIsComplete = (bool) => { + const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) + surfaces.forEach((surface) => { + surface.isComplete = bool + }) + } + + return { apply, getTrestleParams, clear, setViewCircuitNumberTexts, getEstimateData, setAllModuleSurfaceIsComplete } } From 85e2d5b2f0bbd5daa63c6fdf9d66a6d8daee712f Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 6 Mar 2025 10:23:54 +0900 Subject: [PATCH 246/352] =?UTF-8?q?=ED=95=A8=EC=88=98=EB=AA=85=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index 9eaeee89..cf238166 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -330,7 +330,7 @@ export default function CircuitTrestleSetting({ id }) { // 회로할당(승압설정) 저장 버튼 클릭 시 const onApply = async () => { - setAllSurfaceIsComplete(false) + setAllModuleSurfaceIsComplete(false) setIsGlobalLoading(true) canvas @@ -365,7 +365,7 @@ export default function CircuitTrestleSetting({ id }) { await saveCanvas(false) // 견적서 저장 await saveEstimate(result) - setAllSurfaceIsComplete(true) + setAllModuleSurfaceIsComplete(true) } else { setIsGlobalLoading(false) } From 9b942fe294be970180981d645969d59a9e00facb Mon Sep 17 00:00:00 2001 From: yjnoh Date: Thu, 6 Mar 2025 10:30:50 +0900 Subject: [PATCH 247/352] =?UTF-8?q?=EB=A9=94=EB=89=B4=20=EB=B0=B0=EC=B9=98?= =?UTF-8?q?=EB=A9=B4=20=ED=81=B4=EB=A6=AD=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index ebb31fa6..4a8714d5 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -186,7 +186,6 @@ export default function CanvasMenu(props) { const modules = canvas .getObjects() .filter((obj) => [POLYGON_TYPE.MODULE_SETUP_SURFACE, POLYGON_TYPE.MODULE, POLYGON_TYPE.OBJECT_SURFACE].includes(obj.name)) - initRoofs() if (modules.length > 0) { swalFire({ @@ -205,6 +204,7 @@ export default function CanvasMenu(props) { canvas.remove(moduleSurface) }) + initRoofs() canvas.renderAll() onClickNav(menu) } From 2e115887c280c55849b5e180b7930aa1f6900109 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 6 Mar 2025 10:51:09 +0900 Subject: [PATCH 248/352] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=88=9C?= =?UTF-8?q?=EC=84=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/circuitTrestle/CircuitTrestleSetting.jsx | 5 +---- src/hooks/useEstimate.js | 11 ++++++++++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index cf238166..92bc7f3c 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -54,7 +54,7 @@ export default function CircuitTrestleSetting({ id }) { const [seletedOption, setSeletedOption] = useState(null) const { setModuleStatisticsData } = useCircuitTrestle() const { handleCanvasToPng } = useImgLoader() - const { saveCanvas } = usePlan() + const passivityCircuitAllocationRef = useRef() const { setIsGlobalLoading } = useContext(QcastContext) @@ -361,11 +361,8 @@ export default function CircuitTrestleSetting({ id }) { if (result) { handleCanvasToPng(2) - // 캔버스 저장 - await saveCanvas(false) // 견적서 저장 await saveEstimate(result) - setAllModuleSurfaceIsComplete(true) } else { setIsGlobalLoading(false) } diff --git a/src/hooks/useEstimate.js b/src/hooks/useEstimate.js index a535de49..ac1f5c07 100644 --- a/src/hooks/useEstimate.js +++ b/src/hooks/useEstimate.js @@ -9,6 +9,8 @@ import { GlobalDataContext } from '@/app/GlobalDataProvider' import { QcastContext } from '@/app/QcastProvider' import { currentCanvasPlanState } from '@/store/canvasAtom' import { loginUserStore } from '@/store/commonAtom' +import { useTrestle } from '@/hooks/module/useTrestle' +import { usePlan } from '@/hooks/usePlan' export function useEstimate() { const { managementStateLoaded } = useContext(GlobalDataContext) @@ -20,13 +22,15 @@ export function useEstimate() { const { promisePost } = useAxios() const { swalFire } = useSwal() + const { setAllModuleSurfaceIsComplete } = useTrestle() + const { saveCanvas } = usePlan() + /** * 도면 견적서 저장 * * @param {Object} estimateParam - 견적서 저장 데이터 */ const saveEstimate = async (estimateParam) => { - const userId = loginUserState.userId const saleStoreId = managementStateLoaded.saleStoreId const objectNo = currentCanvasPlan.objectNo @@ -56,6 +60,11 @@ export function useEstimate() { await promisePost({ url: '/api/estimate/save-estimate', data: saveEstimateData }) .then(async () => { + setAllModuleSurfaceIsComplete(true) + + // 캔버스 저장 + await saveCanvas(false) + /* 견적서 저장이 완료되면 견적서 페이지로 이동 */ moveEstimate(planNo, objectNo) }) From 724d6d508805d71a9698ce951ac8ed71dd37559a Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 6 Mar 2025 11:05:13 +0900 Subject: [PATCH 249/352] =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=A9=B4=20=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=EC=84=A4=EC=A0=95=20=EC=8B=9C=20=ED=8C=A8=ED=84=B4=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/placementShape/PlacementShapeSetting.jsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx index d836147c..127e7742 100644 --- a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx @@ -9,7 +9,7 @@ import WithDraggable from '@/components/common/draggable/WithDraggable' import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' import { useRecoilState, useRecoilValue } from 'recoil' -import { addedRoofsState, roofMaterialsAtom } from '@/store/settingAtom' +import { addedRoofsState, roofDisplaySelector, roofMaterialsAtom } from '@/store/settingAtom' import { useCommonCode } from '@/hooks/common/useCommonCode' import QSelectBox from '@/components/common/select/QSelectBox' import { globalLocaleStore } from '@/store/localeAtom' @@ -18,6 +18,7 @@ import { onlyNumberInputChange } from '@/util/input-utils' import { getChonByDegree, getDegreeByChon } from '@/util/canvas-util' import { usePolygon } from '@/hooks/usePolygon' import { canvasState } from '@/store/canvasAtom' +import { useRoofFn } from '@/hooks/common/useRoofFn' /** * 지붕 레이아웃 @@ -41,7 +42,9 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla const [currentRoof, setCurrentRoof] = useState(null) /** 현재 선택된 지붕재 정보 */ const { closePopup } = usePopup() /** usePopup에서 closePopup 함수 가져오기 */ const { drawDirectionArrow } = usePolygon() + const { setSurfaceShapePattern } = useRoofFn() const canvas = useRecoilValue(canvasState) + const roofDisplay = useRecoilValue(roofDisplaySelector) const roofRef = { roofCd: useRef(null), @@ -243,6 +246,8 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla const roofs = canvas.getObjects().filter((obj) => obj.roofMaterial?.index === 0) roofs.forEach((roof) => { + /** 모양 패턴 설정 */ + setSurfaceShapePattern(roof, roofDisplay.column, false, { ...roofInfo }) roof.roofMaterial = { ...roofInfo } drawDirectionArrow(roof) }) From 7dca1aaf4ad499cb2870cee882a136a6f9332686 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 6 Mar 2025 11:05:26 +0900 Subject: [PATCH 250/352] =?UTF-8?q?=EC=9D=BC=EB=B3=B8=EC=96=B4=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/locales/ja.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/locales/ja.json b/src/locales/ja.json index 64b2f0f4..e65051ee 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -293,10 +293,10 @@ "modal.object.setting.height": "縦長", "modal.object.setting.area.cross": "エリア交差", "modal.object.setting.size.setting": "サイズ設定", - "modal.object.setting.agreement.depth": "棟の長さ・深さ", - "modal.object.setting.offset.depth": "出幅(深さ)", + "modal.object.setting.agreement.depth": "棟の長さ", + "modal.object.setting.offset.depth": "棟の出幅", "modal.object.setting.size.width": "幅", - "modal.object.setting.offset.width": "出幅(幅)", + "modal.object.setting.offset.width": "幅の出幅", "modal.object.setting.offset.slope": "勾配", "modal.object.setting.direction.select": "方向の選択", "modal.placement.surface.setting.info": "ⓘ①の長さ入力後、対角線長を入力すると②の長さを自動計算します。", From 2c25c68bab9ba2921e9f0e33b29b7616feebfc0f Mon Sep 17 00:00:00 2001 From: yjnoh Date: Thu, 6 Mar 2025 11:09:33 +0900 Subject: [PATCH 251/352] =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EB=A7=88=EC=A7=84?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 37d8dc1d..44a0d02e 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -943,13 +943,13 @@ export function useModuleBasicSetting(tabNum) { const moduleArray = [] let calcAreaWidth = Math.abs(flowLines.right.x1 - flowLines.left.x1) //오른쪽 x에서 왼쪽 x를 뺀 가운데를 찾는 로직 - let calcModuleWidthCount = calcAreaWidth / (width + intvHor) //뺀 공간에서 모듈을 몇개를 넣을수 있는지 확인하는 로직 + let calcModuleWidthCount = calcAreaWidth / (width + intvHor + 1) //뺀 공간에서 모듈을 몇개를 넣을수 있는지 확인하는 로직 let calcMaxModuleWidthCount = calcModuleWidthCount > moduleMaxCols ? moduleMaxCols : calcModuleWidthCount //최대 모듈 단수가 있기 때문에 최대 단수보다 카운트가 크면 최대 단수로 씀씀 let totalModuleWidthCount = Math.floor(calcMaxModuleWidthCount) //치조배치일경우는 한개 더 넣는다 let calcAreaHeight = flowLines.bottom.y1 - flowLines.top.y1 - let calcModuleHeightCount = calcAreaHeight / (height + intvVer) + let calcModuleHeightCount = calcAreaHeight / (height + intvVer + 1) let calcStartPoint = flowLines.right.type === 'flat' ? (calcAreaWidth - totalModuleWidthCount * width) / 2 : 0 //반씩 나눠서 중앙에 맞춤 bottom 기준으로 양변이 직선일때만 가운데 정렬 let startPointX = flowLines.left.x1 + calcStartPoint //시작점을 만든다 @@ -1085,13 +1085,13 @@ export function useModuleBasicSetting(tabNum) { const moduleArray = [] let calcAreaWidth = flowLines.right.x1 - flowLines.left.x1 //오른쪽 x에서 왼쪽 x를 뺀 가운데를 찾는 로직 - let calcModuleWidthCount = calcAreaWidth / (width + intvHor) //뺀 공간에서 모듈을 몇개를 넣을수 있는지 확인하는 로직 + let calcModuleWidthCount = calcAreaWidth / (width + intvHor + 1) //뺀 공간에서 모듈을 몇개를 넣을수 있는지 확인하는 로직 let calcMaxModuleWidthCount = calcModuleWidthCount > moduleMaxCols ? moduleMaxCols : calcModuleWidthCount //최대 모듈 단수가 있기 때문에 최대 단수보다 카운트가 크면 최대 단수로 씀씀 // let totalModuleWidthCount = isChidori ? Math.abs(calcMaxModuleWidthCount) : Math.floor(calcMaxModuleWidthCount) //치조배치일경우는 한개 더 넣는다 //??어쩔때는 붙고 어쩔때는 안붙고 멋대로??? let totalModuleWidthCount = Math.floor(calcMaxModuleWidthCount) //치조배치일경우는 한개 더 넣는다 let calcAreaHeight = flowLines.bottom.y1 - flowLines.top.y1 - let calcModuleHeightCount = calcAreaHeight / (height + intvVer) + let calcModuleHeightCount = calcAreaHeight / (height + intvVer + 1) let calcStartPoint = flowLines.left.type === 'flat' ? (calcAreaWidth - totalModuleWidthCount * width) / 2 : 0 //반씩 나눠서 중앙에 맞춤 bottom 기준으로 양변이 직선일때만 가운데 정렬 let startPointX = flowLines.right.x1 - calcStartPoint //시작점을 만든다 @@ -1222,13 +1222,13 @@ export function useModuleBasicSetting(tabNum) { const moduleArray = [] let calcAreaWidth = flowLines.bottom.y1 - flowLines.top.y1 //아래에서 y에서 위를 y를 뺀 가운데를 찾는 로직 - let calcModuleWidthCount = calcAreaWidth / (height + intvHor) //뺀 공간에서 모듈을 몇개를 넣을수 있는지 확인하는 로직 + let calcModuleWidthCount = calcAreaWidth / (height + intvHor + 1) //뺀 공간에서 모듈을 몇개를 넣을수 있는지 확인하는 로직 let calcMaxModuleWidthCount = calcModuleWidthCount > moduleMaxCols ? moduleMaxCols : calcModuleWidthCount //최대 모듈 단수가 있기 때문에 최대 단수보다 카운트가 크면 최대 단수로 씀씀 // let totalModuleWidthCount = isChidori ? Math.abs(calcMaxModuleWidthCount) : Math.floor(calcMaxModuleWidthCount) //치조배치일경우는 한개 더 넣는다 let totalModuleWidthCount = Math.floor(calcMaxModuleWidthCount) //치조배치일경우는 한개 더 넣는다 let calcAreaHeight = flowLines.right.x1 - flowLines.left.x1 - let calcModuleHeightCount = calcAreaHeight / (width + intvVer) + let calcModuleHeightCount = calcAreaHeight / (width + intvVer + 1) let calcStartPoint = flowLines.bottom.type === 'flat' ? (calcAreaWidth - totalModuleWidthCount * height) / 2 : 0 //반씩 나눠서 중앙에 맞춤 left 높이 기준으로 양변이 직선일때만 가운데 정렬 let startPointX = flowLines.top.y1 + calcStartPoint //시작점을 만든다 @@ -1358,13 +1358,13 @@ export function useModuleBasicSetting(tabNum) { const moduleArray = [] let calcAreaWidth = flowLines.bottom.y1 - flowLines.top.y1 //아래에서 y에서 위를 y를 뺀 가운데를 찾는 로직 - let calcModuleWidthCount = calcAreaWidth / (height + intvHor) //뺀 공간에서 모듈을 몇개를 넣을수 있는지 확인하는 로직 + let calcModuleWidthCount = calcAreaWidth / (height + intvHor + 1) //뺀 공간에서 모듈을 몇개를 넣을수 있는지 확인하는 로직 let calcMaxModuleWidthCount = calcModuleWidthCount > moduleMaxCols ? moduleMaxCols : calcModuleWidthCount //최대 모듈 단수가 있기 때문에 최대 단수보다 카운트가 크면 최대 단수로 씀씀 // let totalModuleWidthCount = isChidori ? Math.abs(calcMaxModuleWidthCount) : Math.floor(calcMaxModuleWidthCount) //치조배치일경우는 한개 더 넣는다 let totalModuleWidthCount = Math.floor(calcMaxModuleWidthCount) //치조배치일경우는 한개 더 넣는다 let calcAreaHeight = flowLines.right.x1 - flowLines.left.x1 - let calcModuleHeightCount = calcAreaHeight / (width + intvVer) + let calcModuleHeightCount = calcAreaHeight / (width + intvVer + 1) let calcStartPoint = flowLines.top.type === 'flat' ? (calcAreaWidth - totalModuleWidthCount * height) / 2 : 0 //반씩 나눠서 중앙에 맞춤 left 높이 기준으로 양변이 직선일때만 가운데 정렬 let startPointX = flowLines.bottom.y2 - calcStartPoint //시작점을 만든다 From 4bab88e272a664a3ff2705a975c22c80e9f2ce64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 6 Mar 2025 11:11:37 +0900 Subject: [PATCH 252/352] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=EC=97=90?= =?UTF-8?q?=EC=84=9C=20floor-plan=20=EB=93=A4=EC=96=B4=EC=99=94=EC=9D=84?= =?UTF-8?q?=EB=95=8C=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20=EC=B4=88=EA=B8=B0?= =?UTF-8?q?=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasFrame.jsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/floor-plan/CanvasFrame.jsx b/src/components/floor-plan/CanvasFrame.jsx index 7144a920..de3674db 100644 --- a/src/components/floor-plan/CanvasFrame.jsx +++ b/src/components/floor-plan/CanvasFrame.jsx @@ -28,6 +28,7 @@ import { import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController' import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' import { useCanvasMenu } from '@/hooks/common/useCanvasMenu' +import { useEvent } from '@/hooks/useEvent' export default function CanvasFrame() { const canvasRef = useRef(null) @@ -49,6 +50,7 @@ export default function CanvasFrame() { const { handleModuleSelectionTotal } = useCanvasPopupStatusController() const { fetchBasicSettings } = useCanvasSetting() const { setSelectedMenu } = useCanvasMenu() + const { initEvent } = useEvent() const loadCanvas = () => { if (!canvas) return @@ -64,6 +66,7 @@ export default function CanvasFrame() { if (canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE).length > 0) { setSelectedMenu('module') } + initEvent() }) } } From 037fff7c4a55bdba20c34b19356e236daf52e086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 6 Mar 2025 11:12:16 +0900 Subject: [PATCH 253/352] =?UTF-8?q?=EA=B0=80=EB=8C=80=20=EC=97=86=EC=9D=B4?= =?UTF-8?q?=20=ED=9A=8C=EB=A1=9C=EB=A7=8C=20=ED=95=A0=EB=8B=B9=20=ED=9B=84?= =?UTF-8?q?=20modal=20=EB=8B=AB=EC=9D=84=EB=95=8C=20=ED=9A=8C=EB=A1=9C=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../circuitTrestle/CircuitTrestleSetting.jsx | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index 92bc7f3c..f9f97833 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -503,19 +503,25 @@ export default function CircuitTrestleSetting({ id }) { // 닫기 버튼 클릭 시 처리하는 함수 추가 const handleClose = () => { // // 회로 번호 텍스트 제거 - // const circuitTexts = canvas.getObjects().filter((obj) => obj.name === 'circuitNumber') - // canvas.remove(...circuitTexts) - // // 모듈의 회로 정보 초기화 - // canvas - // .getObjects() - // .filter((obj) => obj.name === POLYGON_TYPE.MODULE) - // .forEach((obj) => { - // obj.circuit = null - // obj.pcsItemId = null - // obj.circuitNumber = null - // }) + if ( + canvas + .getObjects() + .filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) + .some((surface) => !surface.isComplete) + ) { + canvas.remove(...canvas.getObjects().filter((obj) => obj.name === 'circuitNumber')) + canvas + .getObjects() + .filter((obj) => obj.name === POLYGON_TYPE.MODULE) + .forEach((obj) => { + obj.circuit = null + obj.pcsItemId = null + obj.circuitNumber = null + }) + + canvas.renderAll() + } - // canvas.renderAll() closePopup(id) } From 927b6265bc3b6d9c86bf28ed7c5c467463fdbfa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 6 Mar 2025 11:13:04 +0900 Subject: [PATCH 254/352] =?UTF-8?q?useCanvasSetting=EC=97=90=20executeEffe?= =?UTF-8?q?ct=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/FloorPlan.jsx | 2 +- src/hooks/useContextMenu.js | 2 +- src/hooks/usePlan.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/floor-plan/FloorPlan.jsx b/src/components/floor-plan/FloorPlan.jsx index 18f3ea0d..775d7678 100644 --- a/src/components/floor-plan/FloorPlan.jsx +++ b/src/components/floor-plan/FloorPlan.jsx @@ -18,7 +18,7 @@ export default function FloorPlan({ children }) { const { closeAll } = usePopup() const { selectedMenu, setSelectedMenu } = useCanvasMenu() - const { fetchSettings } = useCanvasSetting() + const { fetchSettings } = useCanvasSetting(false) const resetCurrentMenu = useResetRecoilState(currentMenuState) useEffect(() => { return () => { diff --git a/src/hooks/useContextMenu.js b/src/hooks/useContextMenu.js index 144272f8..df291c51 100644 --- a/src/hooks/useContextMenu.js +++ b/src/hooks/useContextMenu.js @@ -68,7 +68,7 @@ export function useContextMenu() { const { removeGrid } = useGrid() const { removeAdsorptionPoint } = useAdsorptionPoint() const commonTextFont = useRecoilValue(fontSelector('commonText')) - const { settingsData, setSettingsDataSave } = useCanvasSetting() + const { settingsData, setSettingsDataSave } = useCanvasSetting(false) const { swalFire } = useSwal() const { alignModule, modulesRemove, moduleRoofRemove } = useModule() const { removeRoofMaterial, removeAllRoofMaterial, moveRoofMaterial, removeOuterLines } = useRoofFn() diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js index f7fa7508..ee3f0aa8 100644 --- a/src/hooks/usePlan.js +++ b/src/hooks/usePlan.js @@ -49,7 +49,7 @@ export function usePlan(params = {}) { const resetOuterLinePoints = useResetRecoilState(outerLinePointsState) const resetPlacementShapeDrawingPoints = useResetRecoilState(placementShapeDrawingPointsState) - const { fetchBasicSettings, basicSettingCopySave } = useCanvasSetting() + const { fetchBasicSettings, basicSettingCopySave } = useCanvasSetting(false) const [canvasSetting, setCanvasSetting] = useRecoilState(canvasSettingState) /** From 044f3024619fdd2d3493f9fa7c8933dc1f1bcc2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 6 Mar 2025 11:13:20 +0900 Subject: [PATCH 255/352] =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EB=B3=B5=EC=82=AC?= =?UTF-8?q?=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModule.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/hooks/module/useModule.js b/src/hooks/module/useModule.js index e4e783e9..c21dab89 100644 --- a/src/hooks/module/useModule.js +++ b/src/hooks/module/useModule.js @@ -226,7 +226,7 @@ export function useModule() { } modules.forEach((module) => { - const { top, left } = getPosotion(module, direction, Number(length) + Number(moduleLength), false) + const { top, left } = getPosotion(module, direction, Number(length) + Number(moduleLength), true) module.clone((obj) => { obj.set({ parentId: module.parentId, @@ -677,6 +677,7 @@ export function useModule() { } let width = -1 let isWarning = false + const { moduleIntvlHor, moduleIntvlVer } = moduleSetupSurface.trestleDetail if (targetModules.length === 0) { swalFire({ title: '마지막 모듈입니다.', @@ -706,7 +707,7 @@ export function useModule() { canvas.renderAll() otherModules = getOtherModules(columnModules) columnModules.forEach((module) => { - const { top, left } = getPosotion(module, type, module.width, true) + const { top, left } = getPosotion(module, type, module.width + moduleIntvlHor, true) let copyModule = null module.clone((obj) => { obj.set({ @@ -803,11 +804,12 @@ export function useModule() { } let height = -1 let isWarning = false + const { moduleIntvlHor, moduleIntvlVer } = moduleSetupSurface.trestleDetail canvas.discardActiveObject() targetModules.forEach((module) => { if (height === -1) height = type === MODULE_INSERT_TYPE.TOP ? Number(activeModule.top) - Number(module.top) : Number(module.top) - Number(activeModule.top) - const { top, left } = getPosotion(module, type, activeModule.height, true) + const { top, left } = getPosotion(module, type, activeModule.height + moduleIntvlVer, true) module.originPos = { left: module.left, top: module.top, @@ -823,7 +825,7 @@ export function useModule() { canvas.renderAll() otherModules = getOtherModules(rowModules) rowModules.forEach((module) => { - const { top, left } = getPosotion(module, type, activeModule.height, true) + const { top, left } = getPosotion(module, type, activeModule.height + moduleIntvlVer, true) let copyModule = null module.clone((obj) => { obj.set({ From 125eb3213b04e20b53534b673274a40e5fa0e0d2 Mon Sep 17 00:00:00 2001 From: basssy Date: Thu, 6 Mar 2025 13:50:47 +0900 Subject: [PATCH 256/352] =?UTF-8?q?=EB=AC=BC=EA=B1=B4=EC=83=81=EC=84=B8=20?= =?UTF-8?q?2=EC=B0=A8=EC=A0=90=20=EC=A6=90=EA=B2=A8=EC=B0=BE=EA=B8=B0=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/management/StuffDetail.jsx | 11 +++++------ src/components/management/StuffSubHeader.jsx | 4 ++-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index 266f1779..6ececba1 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -528,12 +528,12 @@ export default function StuffDetail() { } get({ url: url }).then((res) => { if (!isEmptyArray(res)) { + //즐겨찾기 구분 추가 + res.map((row) => { + row.value = row.saleStoreId + row.label = row.saleStoreName + }) if (session?.storeId === 'T01') { - //즐겨찾기 구분 추가 - res.map((row) => { - row.value = row.saleStoreId - row.label = row.saleStoreName - }) firstList = res.filter((row) => row.saleStoreLevel === '1') firstList.sort((a, b) => (a.saleStoreId !== 'T01') - (b.saleStoreId !== 'T01') || a.saleStoreId - b.saleStoreId) favList = firstList.filter((row) => row.saleStoreId === 'T01' || row.priority !== 'B') @@ -553,7 +553,6 @@ export default function StuffDetail() { let data = managementState?.firstAgentId ? managementState.firstAgentId : managementState.saleStoreId url = `/api/object/saleStore/${data}/list?firstFlg=0&userId=${session?.userId}` - get({ url: url }).then((res) => { if (!isEmptyArray(res)) { res.map((row) => { diff --git a/src/components/management/StuffSubHeader.jsx b/src/components/management/StuffSubHeader.jsx index f35c6c53..fccafbdc 100644 --- a/src/components/management/StuffSubHeader.jsx +++ b/src/components/management/StuffSubHeader.jsx @@ -23,7 +23,7 @@ export default function StuffSubHeader({ type }) { const setFloorPlanObjectNo = useSetRecoilState(floorPlanObjectState) - const { managementState, setManagementState } = useContext(GlobalDataContext) + const { managementState } = useContext(GlobalDataContext) const [buttonStyle, setButtonStyle] = useState('') @@ -31,11 +31,11 @@ export default function StuffSubHeader({ type }) { useEffect(() => { window.scrollTo(0, 0) - setManagementState({}) }, []) useEffect(() => { if (type === 'detail') { + setButtonStyle('') if (isObjectNotEmpty(managementState)) { if (managementState?.createSaleStoreId === 'T01') { if (session?.storeId !== 'T01') { From fb877470fef2bbca52d45e132e5c7ed4a53d7753 Mon Sep 17 00:00:00 2001 From: basssy Date: Thu, 6 Mar 2025 15:42:21 +0900 Subject: [PATCH 257/352] =?UTF-8?q?QPagination=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EC=97=86=EC=9D=84=EB=95=8C=20disabled?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/pagination/QPagination.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/common/pagination/QPagination.jsx b/src/components/common/pagination/QPagination.jsx index 8c6032b7..1d5aa7d3 100644 --- a/src/components/common/pagination/QPagination.jsx +++ b/src/components/common/pagination/QPagination.jsx @@ -42,7 +42,7 @@ export default function QPagination(props) { >
  • - +
  • ) From 01134ccf3528f51d2fbdbca552f274923c776a98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 6 Mar 2025 15:45:32 +0900 Subject: [PATCH 258/352] =?UTF-8?q?=EB=B6=88=ED=95=84=EC=9A=94=20=EC=A3=BC?= =?UTF-8?q?=EC=84=9D=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/modal/module/column/ColumnRemove.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/floor-plan/modal/module/column/ColumnRemove.jsx b/src/components/floor-plan/modal/module/column/ColumnRemove.jsx index a7ad2044..66351d35 100644 --- a/src/components/floor-plan/modal/module/column/ColumnRemove.jsx +++ b/src/components/floor-plan/modal/module/column/ColumnRemove.jsx @@ -21,7 +21,6 @@ export default function ColumnRemove(props) { { name: getMessage('modal.panel.column.remove.type.none'), value: MODULE_REMOVE_TYPE.NONE }, ] const handleApply = () => { - // if (apply) apply() moduleColumnRemove(selectedType) closePopup(id) } From 72f73cff2a0e2690ad9a14e8217ae58520882796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 6 Mar 2025 15:45:59 +0900 Subject: [PATCH 259/352] =?UTF-8?q?=ED=9A=8C=EB=A1=9C=20=EC=A0=95=EB=B3=B4?= =?UTF-8?q?=20=EC=B4=88=EA=B8=B0=ED=99=94=20=ED=95=A8=EC=88=98=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useCirCuitTrestle.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/hooks/useCirCuitTrestle.js b/src/hooks/useCirCuitTrestle.js index 8e73d59d..1d3a1b2e 100644 --- a/src/hooks/useCirCuitTrestle.js +++ b/src/hooks/useCirCuitTrestle.js @@ -288,6 +288,22 @@ export function useCircuitTrestle() { setModuleStatistics({ header: tempHeader, rows: tempRows.filter((row) => row.wpOut !== 0), footer: tempFooter }) } + const resetCircuits = () => { + const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) + const circuitTexts = canvas.getObjects().filter((obj) => obj.name === 'circuitNumber') + + surfaces.forEach((surface) => { + surface.modules.forEach((module) => { + module.circuit = null + module.pcsItemId = null + module.circuitNumber = null + }) + surface.isComplete = false + }) + if (circuitTexts.length > 0) canvas.remove(...circuitTexts) + canvas.renderAll() + } + return { makers, setMakers, @@ -309,5 +325,6 @@ export function useCircuitTrestle() { getModuleList, removeNotAllocationModules, setModuleStatisticsData, + resetCircuits, } } From 187bdbcbac58b7d702ac2be2034ed88d14f0dd1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 6 Mar 2025 15:46:16 +0900 Subject: [PATCH 260/352] =?UTF-8?q?=EB=8F=84=EB=A8=B8=20=EC=A7=80=EB=B6=95?= =?UTF-8?q?=EC=9E=AC=20=EB=B3=80=EA=B2=BD=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useContextMenu.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/hooks/useContextMenu.js b/src/hooks/useContextMenu.js index df291c51..8845d3b7 100644 --- a/src/hooks/useContextMenu.js +++ b/src/hooks/useContextMenu.js @@ -151,11 +151,6 @@ export function useContextMenu() { name: `${getMessage('contextmenu.copy')}(C)`, fn: () => copyObject(), }, - { - id: 'roofMaterialEdit', - name: getMessage('contextmenu.roof.material.edit'), - component: , - }, { id: 'dormerOffset', name: getMessage('contextmenu.dormer.offset'), From 4cb865ba32d0ea83431209314aa0d94dfb112c5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 6 Mar 2025 15:46:52 +0900 Subject: [PATCH 261/352] =?UTF-8?q?=EA=B0=80=EB=B0=B0=20=EC=84=A4=EC=B9=98?= =?UTF-8?q?=20=ED=9B=84=20=EB=AA=A8=EB=93=88=20=EC=9D=B4=EB=8F=99,=20?= =?UTF-8?q?=EB=B3=B5=EC=82=AC=EC=8B=9C=20=ED=9A=8C=EB=A1=9C=20=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModule.js | 111 +++++++++++++++------------------ src/hooks/module/useTrestle.js | 2 + 2 files changed, 54 insertions(+), 59 deletions(-) diff --git a/src/hooks/module/useModule.js b/src/hooks/module/useModule.js index c21dab89..24cd9ae8 100644 --- a/src/hooks/module/useModule.js +++ b/src/hooks/module/useModule.js @@ -1,4 +1,4 @@ -import { BATCH_TYPE, POLYGON_TYPE } from '@/common/common' +import { BATCH_TYPE, POLYGON_TYPE, TRESTLE_MATERIAL } from '@/common/common' import { canvasState } from '@/store/canvasAtom' import { isOverlap, polygonToTurfPolygon, rectToPolygon } from '@/util/canvas-util' import { useRecoilValue, useSetRecoilState } from 'recoil' @@ -10,6 +10,7 @@ import { useMessage } from '../useMessage' import { selectedModuleState } from '@/store/selectedModuleOptions' import { moduleStatisticsState } from '@/store/circuitTrestleAtom' import { useCircuitTrestle } from '../useCirCuitTrestle' +import { useTrestle } from './useTrestle' export const MODULE_REMOVE_TYPE = { LEFT: 'left', @@ -39,7 +40,8 @@ export function useModule() { const { getMessage } = useMessage() const { checkModuleDisjointObjects } = useModuleBasicSetting() const selectedModules = useRecoilValue(selectedModuleState) - const { setModuleStatisticsData } = useCircuitTrestle() + const { setModuleStatisticsData, resetCircuits } = useCircuitTrestle() + const { clear: removeTrestleMaterials } = useTrestle() const moduleMove = (length, direction) => { const selectedObj = canvas.getActiveObjects() //선택된 객체들을 가져옴 @@ -56,9 +58,7 @@ export function useModule() { const isSetupModules = getOtherModules(selectedObj) const selectedModules = canvas.getObjects().filter((obj) => selectedIds.includes(obj.id) && obj.name === 'module') //선택했던 객체들만 가져옴 - const setupSurface = canvas - .getObjects() - .filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === selectedModules[0].surfaceId)[0] + const setupSurface = canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === selectedModules[0].surfaceId) let isWarning = false const objects = getObjects() @@ -107,7 +107,7 @@ export function useModule() { canvas.discardActiveObject() return } - const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0] + const activeModule = canvas.getObjects().find((obj) => canvas.getActiveObjects()[0].id === obj.id) if (activeModule.circuit) { swalFire({ title: getMessage('can.not.move.module'), @@ -119,9 +119,7 @@ export function useModule() { const modules = type === 'row' ? getRowModules(activeModule) : getColumnModules(activeModule) const otherModules = getOtherModules(modules) const objects = getObjects() - const moduleSetupSurface = canvas - .getObjects() - .filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0] + const moduleSetupSurface = canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId) let isWarning = false modules.forEach((module) => { @@ -275,9 +273,7 @@ export function useModule() { const modules = canvas.getObjects().filter((obj) => activeModuleIds.includes(obj.id)) const objects = getObjects() const otherModules = canvas.getObjects().filter((obj) => obj.surfaceId === modules[0].surfaceId && obj.name === POLYGON_TYPE.MODULE) - const moduleSetupSurface = canvas - .getObjects() - .filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === modules[0].surfaceId)[0] + const moduleSetupSurface = canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === modules[0].surfaceId) let isWarning = false let copyModules = [] let copyModule = null @@ -344,15 +340,21 @@ export function useModule() { canvas.discardActiveObject() return } - const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0] + const activeModule = canvas.getObjects().find((obj) => canvas.getActiveObjects()[0].id === obj.id) + if (activeModule.circuit) { + swalFire({ + title: getMessage('can.not.copy.module'), + icon: 'error', + type: 'alert', + }) + return + } const modules = type === 'row' ? getRowModules(activeModule) : getColumnModules(activeModule) const otherModules = canvas.getObjects().filter((obj) => obj.surfaceId === modules[0].surfaceId && obj.name === POLYGON_TYPE.MODULE) const objects = getObjects() const copyModules = [] let copyModule = null - const moduleSetupSurface = canvas - .getObjects() - .filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === modules[0].surfaceId)[0] + const moduleSetupSurface = canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === modules[0].surfaceId) let isWarning = false let moduleLength = 0 if (['up', 'down'].includes(direction)) { @@ -415,15 +417,7 @@ export function useModule() { if (isFixedModule()) { return } - const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0] - if (activeModule.circuit) { - swalFire({ - title: getMessage('can.not.move.module'), - icon: 'error', - type: 'alert', - }) - return - } + const activeModule = canvas.getObjects().find((obj) => canvas.getActiveObjects()[0].id === obj.id) const columnModules = getColumnModules(activeModule) const otherModules = getOtherModules(columnModules) const objects = getObjects() @@ -431,10 +425,11 @@ export function useModule() { const rightModules = otherModules.filter((module) => activeModule.left < module.left).sort((a, b) => a.left - b.left) const leftModules = otherModules.filter((module) => activeModule.left > module.left).sort((a, b) => b.left - a.left) let width = -1 - const moduleSetupSurface = canvas - .getObjects() - .filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0] + const moduleSetupSurface = canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId) let isWarning = false + if (moduleSetupSurface.isComplete) { + resetSurface() + } canvas.discardActiveObject() moduleSetupSurface.set({ modules: otherModules }) canvas.remove(...columnModules) @@ -538,10 +533,10 @@ export function useModule() { } const moduleRowRemove = (type) => { - if (isFixedModule()) { - return - } - const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0] + // if (isFixedModule()) { + // return + // } + const activeModule = canvas.getObjects().find((obj) => canvas.getActiveObjects()[0].id === obj.id) const rowModules = getRowModules(activeModule) const otherModules = getOtherModules(rowModules) const objects = getObjects() @@ -549,11 +544,11 @@ export function useModule() { const topModules = otherModules.filter((module) => activeModule.top > module.top).sort((a, b) => b.top - a.top) const bottomModules = otherModules.filter((module) => activeModule.top < module.top).sort((a, b) => a.top - b.top) let height = -1 - const moduleSetupSurface = canvas - .getObjects() - .filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0] + const moduleSetupSurface = canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId) let isWarning = false - + if (moduleSetupSurface.isComplete) { + resetSurface() + } canvas.discardActiveObject() moduleSetupSurface.set({ modules: otherModules }) canvas.remove(...rowModules) @@ -660,7 +655,7 @@ export function useModule() { if (isFixedModule()) { return } - const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0] + const activeModule = canvas.getObjects().find((obj) => canvas.getActiveObjects()[0].id === obj.id) const columnModules = getColumnModules(activeModule) let otherModules = getOtherModules(columnModules) const targetModules = @@ -669,11 +664,9 @@ export function useModule() { : otherModules.filter((module) => module.left > activeModule.left).sort((a, b) => a.left - b.left) const objects = getObjects() const copyModules = [] - const moduleSetupSurface = canvas - .getObjects() - .filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0] - if (moduleSetupSurface.modules.filter((module) => module.circuit).length > 0) { - return + const moduleSetupSurface = canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId) + if (moduleSetupSurface.isComplete) { + resetSurface() } let width = -1 let isWarning = false @@ -779,7 +772,7 @@ export function useModule() { if (isFixedModule()) { return } - const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0] + const activeModule = canvas.getObjects().find((obj) => canvas.getActiveObjects()[0].id === obj.id) const rowModules = getRowModules(activeModule) let otherModules = getOtherModules(rowModules) const targetModules = @@ -796,15 +789,14 @@ export function useModule() { } const objects = getObjects() const copyModules = [] - const moduleSetupSurface = canvas - .getObjects() - .filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0] - if (moduleSetupSurface.modules.filter((module) => module.circuit).length > 0) { - return - } + const moduleSetupSurface = canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId) let height = -1 let isWarning = false const { moduleIntvlHor, moduleIntvlVer } = moduleSetupSurface.trestleDetail + + if (surface.isComplete) { + resetSurface() + } canvas.discardActiveObject() targetModules.forEach((module) => { if (height === -1) @@ -940,19 +932,15 @@ export function useModule() { } const modulesRemove = () => { - const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0] - if (activeModule.circuit) { - swalFire({ - title: getMessage('can.not.move.module'), - icon: 'error', - type: 'alert', - }) - return - } + const activeModule = canvas.getObjects().find((obj) => canvas.getActiveObjects()[0].id === obj.id) const modules = canvas .getObjects() .filter((obj) => obj.surfaceId === activeModule.surfaceId && obj.name === POLYGON_TYPE.MODULE && activeModule.id !== obj.id) - const surface = canvas.getObjects().filter((obj) => obj.id === activeModule.surfaceId && obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)[0] + const surface = canvas.getObjects().find((obj) => obj.id === activeModule.surfaceId && obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) + if (surface.isComplete) { + resetSurface() + } + surface.set({ modules: modules }) canvas.remove(activeModule) canvas.renderAll() @@ -1042,6 +1030,11 @@ export function useModule() { .filter((obj) => [BATCH_TYPE.OPENING, BATCH_TYPE.TRIANGLE_DORMER, BATCH_TYPE.PENTAGON_DORMER, BATCH_TYPE.SHADOW].includes(obj.name)) } + const resetSurface = () => { + resetCircuits() + removeTrestleMaterials() + } + return { moduleMove, moduleMultiMove, diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index 0240f519..d507ab9c 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -25,6 +25,7 @@ export const useTrestle = () => { const { setIsGlobalLoading } = useContext(QcastContext) const { getSelectedPcsItemList } = useCircuitTrestle() + const { resetCircuits } = useCircuitTrestle() const apply = () => { const notAllocationModules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE && !obj.circuit) @@ -2777,6 +2778,7 @@ export const useTrestle = () => { canvas.remove(obj) } }) + resetCircuits() } // 전모듈 의 회로번호 visible false 처리 From d140c1298ca716a4f30e0f23aabac6100d14b924 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Thu, 6 Mar 2025 15:55:50 +0900 Subject: [PATCH 262/352] =?UTF-8?q?=EB=8B=A4=EA=B5=AD=EC=96=B4=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EB=B0=8F=20=EB=AA=A8=EB=93=88=20=EC=9D=B4=EB=8F=99?= =?UTF-8?q?=20=EB=8B=A4=EA=B5=AD=EC=96=B4=20=EC=98=A4=EB=A5=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/modal/module/PanelEdit.jsx | 12 ++++++++++-- src/locales/ja.json | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/components/floor-plan/modal/module/PanelEdit.jsx b/src/components/floor-plan/modal/module/PanelEdit.jsx index 4d3c5a22..eafe159a 100644 --- a/src/components/floor-plan/modal/module/PanelEdit.jsx +++ b/src/components/floor-plan/modal/module/PanelEdit.jsx @@ -97,7 +97,11 @@ export default function PanelEdit(props) {

    - {getMessage([PANEL_EDIT_TYPE.MOVE, PANEL_EDIT_TYPE.COLUMN_MOVE].includes(type) ? 'modal.move.setting' : 'modal.copy.setting')}{' '} + {getMessage( + [PANEL_EDIT_TYPE.MOVE, PANEL_EDIT_TYPE.MOVE_ALL, PANEL_EDIT_TYPE.COLUMN_MOVE].includes(type) + ? 'modal.move.setting' + : 'modal.copy.setting', + )}{' '}

    - + + +
    @@ -2003,9 +2010,9 @@ export default function StuffDetail() {
    - +
    {getMessage('stuff.detail.btn.addressPop.guide')}
    @@ -2093,9 +2100,9 @@ export default function StuffDetail() { >
    {getMessage('stuff.detail.standardWindSpeedIdSpan')} - +
    @@ -2206,12 +2213,12 @@ export default function StuffDetail() {
    - - + + - - + +
    ) : ( <>
    - - + + + ) : null}
    @@ -2565,9 +2572,9 @@ export default function StuffDetail() {
    - +
    {getMessage('stuff.detail.btn.addressPop.guide')}
    @@ -2660,9 +2667,9 @@ export default function StuffDetail() { >
    {getMessage('stuff.detail.standardWindSpeedIdSpan')} - +
    @@ -2825,23 +2832,23 @@ export default function StuffDetail() { > {getMessage('stuff.detail.btn.moveList')} - - + +
    ) : ( <>
    - - + +
    {managementState?.tempFlg === '1' ? ( <> - From 9a47549716c1ad279a28ae6d1831ede4c207f819 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Fri, 7 Mar 2025 10:31:53 +0900 Subject: [PATCH 273/352] =?UTF-8?q?-=20canvas=20load=EC=8B=9C=20canvasZoom?= =?UTF-8?q?=20reset?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useCanvas.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/hooks/useCanvas.js b/src/hooks/useCanvas.js index 2afbe126..f1451bd1 100644 --- a/src/hooks/useCanvas.js +++ b/src/hooks/useCanvas.js @@ -3,8 +3,8 @@ import { fabric } from 'fabric' import { actionHandler, anchorWrapper, polygonPositionHandler } from '@/util/canvas-util' -import { useRecoilState, useRecoilValue } from 'recoil' -import { canvasSizeState, canvasState, fontSizeState } from '@/store/canvasAtom' +import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil' +import { canvasSizeState, canvasState, canvasZoomState, fontSizeState } from '@/store/canvasAtom' import { QLine } from '@/components/fabric/QLine' import { QPolygon } from '@/components/fabric/QPolygon' import { defineQLine } from '@/util/qline-utils' @@ -27,6 +27,7 @@ export function useCanvas(id) { const { setCanvasForEvent, attachDefaultEventOnCanvas } = useCanvasEvent() const isImageDisplay = useRecoilValue(imageDisplaySelector) const {} = useFont() + const resetCanvasZoom = useResetRecoilState(canvasZoomState) /** * 처음 셋팅 @@ -43,7 +44,7 @@ export function useCanvas(id) { setCanvas(c) setCanvasForEvent(c) attachDefaultEventOnCanvas() - + resetCanvasZoom() return () => { // c.dispose() c.clear() From 33d66cce8b19d7763752da05a83f0461accde4d1 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Fri, 7 Mar 2025 11:05:29 +0900 Subject: [PATCH 274/352] =?UTF-8?q?=EC=A7=80=EC=A7=80=EA=B8=88=EA=B5=AC=20?= =?UTF-8?q?=EC=84=A4=EC=B9=98=20=EC=8B=9C=20=EA=B0=84=EA=B2=A9=20=EC=A1=B0?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useTrestle.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index d507ab9c..9b17d5b9 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -1665,13 +1665,13 @@ export const useTrestle = () => { canvas.add(bracket) canvas.renderAll() if (direction === 'south') { - startPointY -= height + startPointY -= height - moduleIntvlVer / 10 } else if (direction === 'north') { - startPointY += height + startPointY += height + moduleIntvlVer / 10 } else if (direction === 'east') { - startPointX -= width + startPointX -= width - moduleIntvlHor / 10 } else if (direction === 'west') { - startPointX += width + startPointX += width + moduleIntvlHor / 10 } } } From 74823bcd1cd74e837eea23170c8e17421a011e04 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Fri, 7 Mar 2025 11:24:18 +0900 Subject: [PATCH 275/352] =?UTF-8?q?fix:=20router=20push=20->=20replace?= =?UTF-8?q?=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- next.config.mjs | 7 +++++++ src/components/auth/Login.jsx | 16 +++++++++------- src/components/header/Header.jsx | 6 ++++-- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/next.config.mjs b/next.config.mjs index d4759fb3..c940dbf8 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -15,6 +15,13 @@ const nextConfig = { sassOptions: { includePaths: ['./src/styles'], }, + experimental: { + staleTimes: { + dynamic: 0, + dynamicSWR: 0, + dynamicSSR: 0, + }, + }, } export default nextConfig diff --git a/src/components/auth/Login.jsx b/src/components/auth/Login.jsx index b23f9c53..85e342d4 100644 --- a/src/components/auth/Login.jsx +++ b/src/components/auth/Login.jsx @@ -9,7 +9,7 @@ import { setSession, login, checkSession } from '@/lib/authActions' import { useMessage } from '@/hooks/useMessage' import { globalLocaleStore } from '@/store/localeAtom' import { sessionStore } from '@/store/commonAtom' -import { useRouter } from 'next/navigation' +import { redirect, useRouter } from 'next/navigation' import { useSearchParams } from 'next/navigation' import GlobalSpinner from '@/components/common/spinner/GlobalSpinner' @@ -28,11 +28,13 @@ export default function Login() { autoLoginProcess(autoLoginParam) } - checkSession().then((res) => { - if (res) { - login() - } - }) + // console.log('🚀 ~ checkSession ~ checkSession():', checkSession()) + // checkSession().then((res) => { + // console.log('🚀 ~ checkSession ~ res:', res) + // if (res) { + // login() + // } + // }) }, []) const autoLoginProcess = async (autoLoginParam) => { @@ -49,7 +51,7 @@ export default function Login() { setSessionState(result) login() } else { - router.push('/login') + router.push('/login', undefined, { shallow: true }) } }) } diff --git a/src/components/header/Header.jsx b/src/components/header/Header.jsx index 3e3eabb3..f524f8cd 100644 --- a/src/components/header/Header.jsx +++ b/src/components/header/Header.jsx @@ -8,7 +8,7 @@ import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil' import { dimmedStore, sessionStore } from '@/store/commonAtom' import { useMessage } from '@/hooks/useMessage' -import { logout } from '@/lib/authActions' +import { checkSession, logout } from '@/lib/authActions' import QSelectBox from '@/components/common/select/QSelectBox' @@ -178,6 +178,7 @@ export default function Header(props) { { // moveHome() removeStuffRecoil(menu) @@ -203,6 +204,7 @@ export default function Header(props) { { removeStuffRecoil(m) }} @@ -266,7 +268,7 @@ export default function Header(props) { code: 'DELETE', }) logout() - router.replace('/login') + router.replace('/login', undefined, { shallow: true }) }} > {getMessage('header.logout')} From b69c9953c74bccdacd593a1674e74485cfe95bf0 Mon Sep 17 00:00:00 2001 From: basssy Date: Fri, 7 Mar 2025 12:30:41 +0900 Subject: [PATCH 276/352] =?UTF-8?q?=EB=AC=BC=EA=B1=B4=EC=83=81=EC=84=B8?= =?UTF-8?q?=ED=99=94=EB=A9=B4=EC=97=90=EC=84=9C=20=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=95=84=EC=9B=83=20->=20=EB=92=A4=EB=A1=9C=EA=B0=80=EA=B8=B0?= =?UTF-8?q?=20..=20=EC=B2=98=EB=A6=AC=EC=88=98=EC=A0=95=20Header.jsx?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/main/useMainContentsController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/main/useMainContentsController.js b/src/hooks/main/useMainContentsController.js index 5b620475..f065c90f 100644 --- a/src/hooks/main/useMainContentsController.js +++ b/src/hooks/main/useMainContentsController.js @@ -16,7 +16,7 @@ export const useMainContentsController = () => { useEffect(() => { checkSession().then((res) => { if (!res) { - router.replace('/login') + router.replace('/login', undefined, { shallow: true }) } }) setIsGlobalLoading(true) From 95a817328840de5992113d8e3ad375e8edebae86 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Fri, 7 Mar 2025 12:31:12 +0900 Subject: [PATCH 277/352] =?UTF-8?q?=EB=8F=84=EB=A8=B8=20=EC=98=A4=EB=A5=98?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/object/useObjectBatch.js | 154 +++++++++++++++++++++-------- src/util/canvas-util.js | 14 +++ 2 files changed, 127 insertions(+), 41 deletions(-) diff --git a/src/hooks/object/useObjectBatch.js b/src/hooks/object/useObjectBatch.js index 8a6c797a..2671ed77 100644 --- a/src/hooks/object/useObjectBatch.js +++ b/src/hooks/object/useObjectBatch.js @@ -12,6 +12,7 @@ import { triangleToPolygon, getDegreeByChon, toFixedWithoutRounding, + getTrianglePoints, } from '@/util/canvas-util' import { useSwal } from '@/hooks/useSwal' import * as turf from '@turf/turf' @@ -28,13 +29,11 @@ export function useObjectBatch({ isHidden, setIsHidden }) { const { addCanvasMouseEventListener, initEvent, addDocumentEventListener } = useEvent() // const { addCanvasMouseEventListener, initEvent, addDocumentEventListener } = useContext(EventContext) const { swalFire } = useSwal() - const { drawDirectionArrow } = usePolygon() + const { drawDirectionArrow, addPolygon, addLengthText } = usePolygon() const { setSurfaceShapePattern } = useRoofFn() const lengthTextFont = useRecoilValue(fontSelector('lengthText')) const roofDisplay = useRecoilValue(roofDisplaySelector) - const { addPolygon } = usePolygon() - useEffect(() => { if (canvas) { // dbClickEvent() @@ -419,7 +418,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) { addCanvasMouseEventListener('mouse:up', (e) => { if (dormer) { - const trianglePolygon = pointsToTurfPolygon(triangleToPolygon(dormer)) + const trianglePolygon = pointsToTurfPolygon(offsetRef > 0 ? getTrianglePoints(dormerOffset) : getTrianglePoints(dormer)) const selectedSurfacePolygon = polygonToTurfPolygon(selectedSurface) //지붕 밖으로 그렸을때 @@ -448,8 +447,8 @@ export function useObjectBatch({ isHidden, setIsHidden }) { direction = 'north' } - let { leftPoints, rightPoints, groupPoints } = - offsetRef > 0 ? splitDormerTriangle(dormerOffset, directionRef) : splitDormerTriangle(dormer, directionRef) + let { leftPoints, rightPoints, groupPoints, dormerPoints } = + offsetRef > 0 ? splitDormerTriangle(dormerOffset, directionRef, dormer) : splitDormerTriangle(dormer, directionRef) canvas?.remove(offsetRef > 0 ? dormerOffset : dormer) if (offsetRef > 0) @@ -512,10 +511,6 @@ export function useObjectBatch({ isHidden, setIsHidden }) { false, ) - leftTriangle.texts.forEach((text) => { - text.bringToFront() - }) - const rightTriangle = addPolygon( rightPoints, { @@ -587,7 +582,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) { canvas?.remove(dormer) offsetPolygon = addPolygon( - triangleToPolygon(dormer), + dormerPoints, { selectable: true, lockMovementX: true, // X 축 이동 잠금 @@ -604,7 +599,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) { fontSize: lengthTextFont.fontSize.value, fontStyle: lengthTextFont.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal', fontWeight: lengthTextFont.fontWeight.value, - angle: originAngle, + // angle: originAngle, pitch: pitch, dormerAttributes: { height: height, @@ -639,6 +634,10 @@ export function useObjectBatch({ isHidden, setIsHidden }) { ) } + addLengthText(leftTriangle) + addLengthText(rightTriangle) + addLengthText(offsetPolygon) + const groupPolygon = offsetPolygon ? [leftTriangle, rightTriangle, offsetPolygon] : [leftTriangle, rightTriangle] const objectGroup = new fabric.Group(groupPolygon, { @@ -667,9 +666,6 @@ export function useObjectBatch({ isHidden, setIsHidden }) { } }) } else if (buttonAct === 4) { - const heightLength = height - (width / 2) * (pitch * 0.25) - const heightOffsetLength = height + offsetRef - (width / 2 + offsetWidthRef) * (pitch * 0.25) - addCanvasMouseEventListener('mouse:move', (e) => { isDown = true if (!isDown) return @@ -774,7 +770,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) { addCanvasMouseEventListener('mouse:up', (e) => { if (dormer) { - const pentagonPolygon = pointsToTurfPolygon(dormer.points) + const pentagonPolygon = pointsToTurfPolygon(offsetRef > 0 ? dormerOffset.getCurrentPoints() : dormer.getCurrentPoints()) const selectedSurfacePolygon = polygonToTurfPolygon(selectedSurface) //지붕 밖으로 그렸을때 @@ -804,11 +800,8 @@ export function useObjectBatch({ isHidden, setIsHidden }) { direction = 'north' } - const offsetMode = offsetRef > 0 || offsetWidthRef > 0 ? 'offset' : 'normal' let { leftPoints, rightPoints, groupPoints } = - offsetRef > 0 || offsetWidthRef > 0 - ? splitDormerPentagon(dormerOffset, directionRef, offsetMode) - : splitDormerPentagon(dormer, directionRef, offsetMode) + offsetRef > 0 || offsetWidthRef > 0 ? splitDormerPentagon(dormerOffset, directionRef) : splitDormerPentagon(dormer, directionRef) canvas?.remove(offsetRef > 0 || offsetWidthRef > 0 ? dormerOffset : dormer) if (offsetRef > 0) @@ -948,7 +941,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) { canvas?.remove(dormer) offsetPolygon = addPolygon( - dormer.points, + dormer.getCurrentPoints(), { selectable: true, lockMovementX: true, // X 축 이동 잠금 @@ -965,7 +958,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) { fontSize: lengthTextFont.fontSize.value, fontStyle: lengthTextFont.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal', fontWeight: lengthTextFont.fontWeight.value, - angle: originAngle, + // angle: originAngle, groupPoints: groupPoints, dormerAttributes: { height: height, @@ -1012,6 +1005,10 @@ export function useObjectBatch({ isHidden, setIsHidden }) { ) } + addLengthText(leftPentagon) + addLengthText(rightPentagon) + addLengthText(offsetPolygon) + const groupPolygon = offsetPolygon ? [leftPentagon, rightPentagon, offsetPolygon] : [leftPentagon, rightPentagon] const objectGroup = new fabric.Group(groupPolygon, { @@ -1058,13 +1055,18 @@ export function useObjectBatch({ isHidden, setIsHidden }) { if (setIsHidden) setIsHidden(false) } - const splitDormerTriangle = (triangle, direction) => { + const splitDormerTriangle = (triangle, direction, dormer = null) => { const halfWidth = triangle.width / 2 + let dormerPoints = [] let leftPoints = [] let rightPoints = [] let groupPoints = [] + if (dormer) { + dormerPoints = getTrianglePoints(dormer) + } + if (direction === 'down') { leftPoints = [ { x: triangle.left, y: triangle.top }, @@ -1122,23 +1124,23 @@ export function useObjectBatch({ isHidden, setIsHidden }) { } else if (direction === 'right') { leftPoints = [ { x: triangle.left, y: triangle.top }, + { x: triangle.left + triangle.height, y: triangle.top + halfWidth }, { x: triangle.left + triangle.height, y: triangle.top }, - { x: triangle.left + triangle.height, y: triangle.top + triangle.height }, ] rightPoints = [ { x: triangle.left, y: triangle.top }, - { x: triangle.left + triangle.height, y: triangle.top + triangle.height }, - { x: triangle.left + triangle.height, y: triangle.top - triangle.height }, + { x: triangle.left + triangle.height, y: triangle.top }, + { x: triangle.left + triangle.height, y: triangle.top - halfWidth }, ] groupPoints = [ { x: triangle.left, y: triangle.top }, - { x: triangle.left + triangle.height, y: triangle.top + triangle.height }, - { x: triangle.left + triangle.height, y: triangle.top - triangle.height }, + { x: triangle.left + triangle.height, y: triangle.top + halfWidth }, + { x: triangle.left + triangle.height, y: triangle.top - halfWidth }, ] } - return { leftPoints, rightPoints, groupPoints } + return { leftPoints, rightPoints, groupPoints, dormerPoints } } const splitDormerPentagon = (pentagon, direction, offsetMode) => { @@ -1326,15 +1328,24 @@ export function useObjectBatch({ isHidden, setIsHidden }) { const reGroupObject = (groupObj) => { groupObj._restoreObjectsState() //이건 실행만 되도 그룹이 변경됨 + + console.log('groupObj', groupObj) + const reGroupObjects = [] groupObj._objects.forEach((obj) => { - const newObj = new QPolygon(obj.getCurrentPoints(), { - ...obj, - points: obj.getCurrentPoints(), - scaleX: 1, - scaleY: 1, - texts: [], - }) + const newObj = addPolygon( + obj.getCurrentPoints(), + { + ...obj, + points: obj.getCurrentPoints(), + scaleX: 1, + scaleY: 1, + lines: obj.lines ?? [], + groupPoints: groupObj.groupPoints ?? [], + groupId: groupObj.groupId ?? '', + }, + false, + ) reGroupObjects.push(newObj) canvas.remove(obj) if (newObj.direction) { @@ -1342,6 +1353,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) { } newObj.fire('modified') }) + const reGroup = new fabric.Group(reGroupObjects, { subTargetCheck: true, name: groupObj.name, @@ -1350,10 +1362,20 @@ export function useObjectBatch({ isHidden, setIsHidden }) { parentId: groupObj.parentId, originX: 'center', originY: 'center', + groupPoints: groupObj.groupPoints ?? [], + groupId: groupObj.groupId ?? '', }) canvas?.add(reGroup) canvas?.remove(groupObj) + reGroup._objects.forEach((obj) => { + if (obj.hasOwnProperty('texts')) { + obj.texts.forEach((text) => { + text.bringToFront() + }) + } + }) + return reGroup } @@ -1368,6 +1390,10 @@ export function useObjectBatch({ isHidden, setIsHidden }) { }) const originObj = { ...obj } + const turfSurface = pointsToTurfPolygon(parentSurface.points) + const originLeft = obj.left + const originTop = obj.top + addCanvasMouseEventListener('mouse:up', (e) => { //개구, 그림자 타입일 경우 폴리곤 타입 변경 if (BATCH_TYPE.OPENING === obj.name || BATCH_TYPE.SHADOW === obj.name) { @@ -1375,7 +1401,6 @@ export function useObjectBatch({ isHidden, setIsHidden }) { points: rectToPolygon(obj), }) - const turfSurface = pointsToTurfPolygon(parentSurface.points) const turfObject = pointsToTurfPolygon(obj.points) if (turf.booleanWithin(turfObject, turfSurface)) { @@ -1398,8 +1423,36 @@ export function useObjectBatch({ isHidden, setIsHidden }) { lockMovementY: true, }) - if (obj.type === 'group') reGroupObject(obj) - obj.setCoords() + if (obj.name === BATCH_TYPE.TRIANGLE_DORMER || obj.name === BATCH_TYPE.PENTAGON_DORMER) { + const calcLeft = obj.left - originLeft + const calcTop = obj.top - originTop + + const currentDormerPoints = obj.groupPoints.map((item) => { + return { + x: item.x + calcLeft, + y: item.y + calcTop, + } + }) + + const turfObject = pointsToTurfPolygon(currentDormerPoints) + + if (turf.booleanWithin(turfObject, turfSurface)) { + obj.set({ + lockMovementX: true, + lockMovementY: true, + groupPoints: currentDormerPoints, + }) + + if (obj.type === 'group') reGroupObject(obj) + obj.setCoords() + } else { + swalFire({ + title: getMessage('batch.object.outside.roof'), + icon: 'warning', + }) + obj.set({ ...originObj, lockMovementX: true, lockMovementY: true }) + } + } } canvas.discardActiveObject() initEvent() @@ -1512,8 +1565,27 @@ export function useObjectBatch({ isHidden, setIsHidden }) { length2 = parseInt(length2) / 10 const dormer = canvas.getActiveObject() - if (length1) dormer.top = arrow1 === 'down' ? dormer.top + length1 : dormer.top - length1 - if (length2) dormer.left = arrow2 === 'left' ? dormer.left - length2 : dormer.left + length2 + if (length1) { + if (!arrow1) { + swalFire({ + title: getMessage('length.direction.is.required'), + icon: 'warning', + }) + } else { + dormer.top = arrow1 === 'down' ? dormer.top + length1 : dormer.top - length1 + } + } + + if (length2) { + if (!arrow2) { + swalFire({ + title: getMessage('length.direction.is.required'), + icon: 'warning', + }) + } else { + dormer.left = arrow2 === 'left' ? dormer.left - length2 : dormer.left + length2 + } + } if (dormer.type === 'group') { const newDormer = reGroupObject(dormer) diff --git a/src/util/canvas-util.js b/src/util/canvas-util.js index 66116af8..935097b0 100644 --- a/src/util/canvas-util.js +++ b/src/util/canvas-util.js @@ -1040,3 +1040,17 @@ export function calculateVisibleModuleHeight(sourceWidth, sourceHeight, angle, d export function toFixedWithoutRounding(number, decimals) { return Math.floor(number * Math.pow(10, decimals)) / Math.pow(10, decimals) } + +export function getTrianglePoints(triangle) { + const matrix = triangle.calcTransformMatrix() + const w = triangle.width / 2 + const h = triangle.height / 2 + + const points = [ + { x: 0, y: -h }, + { x: -w, y: h }, + { x: w, y: h }, + ] + + return points.map((point) => fabric.util.transformPoint(point, matrix)) +} From 29378cbe7247bd7229249d55cf618486d04bb3c5 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Fri, 7 Mar 2025 12:39:14 +0900 Subject: [PATCH 278/352] =?UTF-8?q?=F0=9F=93=8Cfix:=20nextui=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=20=EB=B0=8F=20=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 - src/app/UIProvider.js | 5 -- .../floor-plan/modal/module/PanelEdit.jsx | 1 - src/components/ui/ObjectPlacement.jsx | 25 ++++---- src/components/ui/SurfaceShape.jsx | 63 +++++++++---------- src/components/ui/ThumbnailLIst.jsx | 38 ----------- tailwind.config.js | 7 +-- 7 files changed, 45 insertions(+), 95 deletions(-) delete mode 100644 src/app/UIProvider.js delete mode 100644 src/components/ui/ThumbnailLIst.jsx diff --git a/package.json b/package.json index 84099e97..bf52888e 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,6 @@ "serve": "node server.js" }, "dependencies": { - "@nextui-org/react": "^2.4.2", "ag-grid-react": "^32.0.2", "axios": "^1.7.8", "big.js": "^6.2.2", diff --git a/src/app/UIProvider.js b/src/app/UIProvider.js deleted file mode 100644 index 02a21441..00000000 --- a/src/app/UIProvider.js +++ /dev/null @@ -1,5 +0,0 @@ -import { NextUIProvider } from '@nextui-org/react' - -export default function UIProvider({ children }) { - return {children} -} diff --git a/src/components/floor-plan/modal/module/PanelEdit.jsx b/src/components/floor-plan/modal/module/PanelEdit.jsx index eafe159a..6ebb14f2 100644 --- a/src/components/floor-plan/modal/module/PanelEdit.jsx +++ b/src/components/floor-plan/modal/module/PanelEdit.jsx @@ -9,7 +9,6 @@ import { deepCopyArray } from '@/util/common-utils' import { canvasState } from '@/store/canvasAtom' import * as turf from '@turf/turf' import { POLYGON_TYPE } from '@/common/common' -import { useModal } from '@nextui-org/react' import { useModule } from '@/hooks/module/useModule' import { useSwal } from '@/hooks/useSwal' diff --git a/src/components/ui/ObjectPlacement.jsx b/src/components/ui/ObjectPlacement.jsx index f7a73a5c..d03f2a1e 100644 --- a/src/components/ui/ObjectPlacement.jsx +++ b/src/components/ui/ObjectPlacement.jsx @@ -1,5 +1,4 @@ import React, { useCallback, useEffect, useRef, useState } from 'react' -import { Button, Input } from '@nextui-org/react' import { useRecoilState, useSetRecoilState } from 'recoil' import { modalState } from '@/store/modalAtom' import { fabric } from 'fabric' @@ -19,7 +18,7 @@ const ObjectPlacement = ({ canvas }) => { const [batchType, setBatchType] = useState(BATCH_TYPE.OPENING) // free or dimension 프리 / 치수 - const [inputType, setInputType] = useState(INPUT_TYPE.FREE) + const [inputType, setinputType] = useState(INPUT_TYPE.FREE) const handleSave = () => { setMode(batchType) @@ -38,7 +37,7 @@ const ObjectPlacement = ({ canvas }) => {
    - - +
    @@ -64,7 +63,7 @@ const ObjectPlacement = ({ canvas }) => {
    diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index 8d737c2d..f9f97833 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -52,7 +52,7 @@ export default function CircuitTrestleSetting({ id }) { // const [stepUpListData, setStepUpListData] = useRecoilState(stepUpListDataState) const [stepUpListData, setStepUpListData] = useState([]) const [seletedOption, setSeletedOption] = useState(null) - const { setModuleStatisticsData, resetCircuits } = useCircuitTrestle() + const { setModuleStatisticsData } = useCircuitTrestle() const { handleCanvasToPng } = useImgLoader() const passivityCircuitAllocationRef = useRef() @@ -92,17 +92,6 @@ export default function CircuitTrestleSetting({ id }) { // selectedModels, // pcsCheck, // }) - - return () => { - if ( - canvas - .getObjects() - .filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) - .some((surface) => !surface.isComplete) - ) { - resetCircuits() - } - } }, []) // 수동할당 시 모듈 삭제 diff --git a/src/components/floor-plan/modal/panelBatch/PanelBatchStatistics.jsx b/src/components/floor-plan/modal/panelBatch/PanelBatchStatistics.jsx index 8cd0de0e..67b5efd0 100644 --- a/src/components/floor-plan/modal/panelBatch/PanelBatchStatistics.jsx +++ b/src/components/floor-plan/modal/panelBatch/PanelBatchStatistics.jsx @@ -21,7 +21,7 @@ export default function PanelBatchStatistics() { }) const canvas = useRecoilValue(canvasState) const { header, rows, footer } = useRecoilValue(moduleStatisticsState) - const { setModuleStatisticsData } = useCircuitTrestle() + const { setModuleStatisticsData } = useCircuitTrestle(true) const [moduleSelectionDataStore, setModuleSelectionDataStore] = useRecoilState(moduleSelectionDataState) useEffect(() => { diff --git a/src/hooks/common/useCanvasConfigInitialize.js b/src/hooks/common/useCanvasConfigInitialize.js index 19736e81..91d65edb 100644 --- a/src/hooks/common/useCanvasConfigInitialize.js +++ b/src/hooks/common/useCanvasConfigInitialize.js @@ -9,6 +9,7 @@ import { globalFontAtom } from '@/store/fontAtom' import { useRoof } from '@/hooks/common/useRoof' import { usePolygon } from '@/hooks/usePolygon' import { useRoofFn } from '@/hooks/common/useRoofFn' +import { POLYGON_TYPE } from '@/common/common' export function useCanvasConfigInitialize() { const canvas = useRecoilValue(canvasState) @@ -211,17 +212,20 @@ export function useCanvasConfigInitialize() { } const moduleInit = () => { - canvas - .getObjects() - .filter((obj) => obj.name === 'module') - .forEach((obj) => { - obj.set({ - selectable: true, - lockMovementX: true, - lockMovementY: true, - }) - obj.setViewLengthText(false) + const roofSurfaceList = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) + const modules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE) + roofSurfaceList.forEach((surface) => { + surface.modules = modules.filter((module) => module.surfaceId === surface.id) + }) + modules.forEach((obj) => { + console.log(obj) + obj.set({ + selectable: true, + lockMovementX: true, + lockMovementY: true, }) + obj.setViewLengthText(false) + }) } return { canvasLoadInit, gridInit } diff --git a/src/hooks/common/useCanvasPopupStatusController.js b/src/hooks/common/useCanvasPopupStatusController.js index b0c0f6f8..a31bd0ed 100644 --- a/src/hooks/common/useCanvasPopupStatusController.js +++ b/src/hooks/common/useCanvasPopupStatusController.js @@ -8,6 +8,8 @@ import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedM import { compasDegAtom } from '@/store/orientationAtom' import { canvasState, currentCanvasPlanState } from '@/store/canvasAtom' import { POLYGON_TYPE } from '@/common/common' +import { useCircuitTrestle } from '../useCirCuitTrestle' +import { useEffect } from 'react' /** * 캔버스 팝업 상태 관리 @@ -58,13 +60,12 @@ export function useCanvasPopupStatusController(param = 1) { } else if (i === 2) { const data = JSON.parse(unescapeString(result.popupStatus)) setModuleSelectionDataStore(data) - if (data.module) setSelectedModules(data.module) - const roofSurfaceList = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) const modules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE) roofSurfaceList.forEach((surface) => { surface.modules = modules.filter((module) => module.surfaceId === surface.id) }) + if (data.module) setSelectedModules(data.module) } } } diff --git a/src/hooks/useCirCuitTrestle.js b/src/hooks/useCirCuitTrestle.js index 74675ecb..027b965a 100644 --- a/src/hooks/useCirCuitTrestle.js +++ b/src/hooks/useCirCuitTrestle.js @@ -11,13 +11,12 @@ import { seriesState, } from '@/store/circuitTrestleAtom' import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions' -import { useContext } from 'react' -import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' +import { useContext, useEffect } from 'react' +import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil' import { useMessage } from './useMessage' -import { useCanvasPopupStatusController } from './common/useCanvasPopupStatusController' import Big from 'big.js' -export function useCircuitTrestle() { +export function useCircuitTrestle(executeEffect = false) { const [makers, setMakers] = useRecoilState(makersState) const [selectedMaker, setSelectedMaker] = useRecoilState(selectedMakerState) const [series, setSeries] = useRecoilState(seriesState) @@ -27,10 +26,14 @@ export function useCircuitTrestle() { const selectedModules = useRecoilValue(selectedModuleState) const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext) const canvas = useRecoilValue(canvasState) - const { trigger: moduleSelectedDataTrigger } = useCanvasPopupStatusController(2) - const [moduleSelectionData, setModuleSelectionData] = useRecoilState(moduleSelectionDataState) const setModuleStatistics = useSetRecoilState(moduleStatisticsState) + const resetModuleStatistics = useResetRecoilState(moduleStatisticsState) const { getMessage } = useMessage() + + useEffect(() => { + if (Object.keys(selectedModules).length > 0 && executeEffect) setModuleStatisticsData() + }, [selectedModules]) + const getOptYn = () => { return { maxConnYn: pcsCheck.max ? 'Y' : 'N', @@ -178,7 +181,15 @@ export function useCircuitTrestle() { const setModuleStatisticsData = () => { console.log('selectedModules', selectedModules) - if (!selectedModules || !selectedModules?.itemList || selectedModules?.itemList?.length === 0) return + if ( + !selectedModules || + !selectedModules?.itemList || + selectedModules?.itemList?.length === 0 || + canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE).length === 0 + ) { + resetModuleStatistics() + return + } const tempHeader = [ { name: getMessage('simulator.table.sub1'), prop: 'name' }, { name: getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity.circuit'), prop: 'circuit' }, diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js index ee3f0aa8..99435d3e 100644 --- a/src/hooks/usePlan.js +++ b/src/hooks/usePlan.js @@ -282,12 +282,6 @@ export function usePlan(params = {}) { /** 리코일 세팅 */ setModuleSelectionDataStore(copyData) if (copyData.module) setSelectedModules(copyData.module) - const roofSurfaceList = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) - const modules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE) - roofSurfaceList.forEach((surface) => { - surface.modules = modules.filter((module) => module.surfaceId === surface.id) - }) - setSelectedMenu(currentSelectedMenu) } else { setSelectedMenu('placement') From b4cbd9345e081f196d9e7be8dbf493664b2f4e21 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Mon, 10 Mar 2025 15:15:34 +0900 Subject: [PATCH 298/352] =?UTF-8?q?zoom=20=EB=B2=84=ED=8A=BC=20=EA=B0=80?= =?UTF-8?q?=EB=8A=A5=20=EB=B2=94=EC=9C=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useCanvasEvent.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/hooks/useCanvasEvent.js b/src/hooks/useCanvasEvent.js index 9076bbc8..c72b8c36 100644 --- a/src/hooks/useCanvasEvent.js +++ b/src/hooks/useCanvasEvent.js @@ -397,8 +397,16 @@ export function useCanvasEvent() { const handleZoom = (isZoom) => { if (isZoom) { + const zoom = canvasZoom + 10 + if (zoom > 500) { + return + } setCanvasZoom(canvasZoom + 10) } else { + const zoom = canvasZoom - 10 + if (zoom < 50) { + return + } setCanvasZoom(canvasZoom - 10) } } From 8ccef01e7dbc8e545958f8526af84fc4f241d427 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Mon, 10 Mar 2025 16:33:41 +0900 Subject: [PATCH 299/352] =?UTF-8?q?zoom=20=EB=B2=84=ED=8A=BC=20=EA=B0=80?= =?UTF-8?q?=EB=8A=A5=20=EB=B2=94=EC=9C=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useCanvasEvent.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/hooks/useCanvasEvent.js b/src/hooks/useCanvasEvent.js index c72b8c36..ed24387e 100644 --- a/src/hooks/useCanvasEvent.js +++ b/src/hooks/useCanvasEvent.js @@ -396,19 +396,20 @@ export function useCanvasEvent() { } const handleZoom = (isZoom) => { + let zoom if (isZoom) { - const zoom = canvasZoom + 10 + zoom = canvasZoom + 10 if (zoom > 500) { return } - setCanvasZoom(canvasZoom + 10) } else { - const zoom = canvasZoom - 10 + zoom = canvasZoom - 10 if (zoom < 50) { return } - setCanvasZoom(canvasZoom - 10) } + + setCanvasZoom(zoom) } const handleZoomClear = () => { From 0854efd4a50a3431ed9b3e6776e71fd772dfcfaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Mon, 10 Mar 2025 17:03:47 +0900 Subject: [PATCH 300/352] =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EC=97=86=EC=9D=84?= =?UTF-8?q?=EB=95=8C=20=EB=B0=B0=EC=B9=98=EB=A9=B4=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=A9=94=EB=89=B4=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasFrame.jsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/floor-plan/CanvasFrame.jsx b/src/components/floor-plan/CanvasFrame.jsx index 002c9c13..68e5cf7a 100644 --- a/src/components/floor-plan/CanvasFrame.jsx +++ b/src/components/floor-plan/CanvasFrame.jsx @@ -48,10 +48,9 @@ export default function CanvasFrame() { const resetSelectedModelsState = useResetRecoilState(selectedModelsState) const resetPcsCheckState = useResetRecoilState(pcsCheckState) const { handleModuleSelectionTotal } = useCanvasPopupStatusController() - const { fetchBasicSettings } = useCanvasSetting() + const { basicSetting, fetchBasicSettings } = useCanvasSetting() const { selectedMenu, setSelectedMenu } = useCanvasMenu() const { initEvent } = useEvent() - const loadCanvas = () => { if (!canvas) return @@ -65,6 +64,8 @@ export default function CanvasFrame() { if (canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE).length > 0) { setSelectedMenu('module') + } else { + setSelectedMenu('surface') } initEvent() }) From 74ab798f14b6b2b18ea9bd54521303825d7a2155 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Mon, 10 Mar 2025 17:54:33 +0900 Subject: [PATCH 301/352] =?UTF-8?q?=EB=B2=88=EC=97=AD=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/locales/ja.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/locales/ja.json b/src/locales/ja.json index 1e3ba842..337cdc5f 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -271,9 +271,9 @@ "modal.canvas.setting.wallline.properties.setting.eaves": "軒で設定", "modal.canvas.setting.wallline.properties.setting.edge": "ケラバに設定", "modal.canvas.setting.wallline.properties.setting.ridge": "棟に設定", - "modal.canvas.setting.roofline.properties.setting": "屋根線の属性設定", + "modal.canvas.setting.roofline.properties.setting": "屋根線属性設定", "modal.canvas.setting.roofline.properties.setting.info": "※ 属性を変更する配置面の線を選択し、軒線の設定 けらば線の設定\n 棟線の設定ボタンをクリックして設定値を適用してください。", - "modal.canvas.setting.roofline.properties.setting.not.setting": "未設定の線が存在します。", + "modal.canvas.setting.roofline.properties.setting.not.setting": "設定していないラインが存在します。", "modal.eaves.gable.edit": "軒/ケラバ変更", "modal.eaves.gable.edit.basic": "通常", "modal.eaves.gable.edit.wall.merge.info": "下屋などの壁に面する屋根を作成します。", From 371a9dd613fab069a8961ce55bd42b80556b7b04 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Tue, 11 Mar 2025 10:48:50 +0900 Subject: [PATCH 302/352] =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EC=84=A0=ED=83=9D?= =?UTF-8?q?=20=EC=B4=88=EA=B8=B0=ED=99=94=20=EA=B8=B0=EB=8A=A5=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleTabContents.js | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/hooks/module/useModuleTabContents.js b/src/hooks/module/useModuleTabContents.js index a7516cf1..f6c46314 100644 --- a/src/hooks/module/useModuleTabContents.js +++ b/src/hooks/module/useModuleTabContents.js @@ -1,5 +1,5 @@ import { useEffect, useState, useRef } from 'react' -import { useRecoilValue, useRecoilState } from 'recoil' +import { useRecoilValue, useRecoilState, useResetRecoilState } from 'recoil' import { pitchTextSelector } from '@/store/canvasAtom' import { useMasterController } from '@/hooks/common/useMasterController' import { useCommonCode } from '@/hooks/common/useCommonCode' @@ -53,8 +53,6 @@ export function useModuleTabContents({ tabIndex, addRoof, setAddedRoofs, roofTab const hajebichiRef = useRef() const lengthRef = useRef() - const [isChangeInitData, setIsChangeInitData] = useState(false) - //서까래간격 변경 const handleChangeRaftBase = (option) => { setSelectedRaftBase({ raftBaseCd: option.clCode, clCode: option.clCode }) @@ -419,12 +417,6 @@ export function useModuleTabContents({ tabIndex, addRoof, setAddedRoofs, roofTab //공법 리스트 초기화 setConstructionList([]) - // 기본 정보 초기화 - setModuleSelectionData({ - ...moduleSelectionData, - roofConstructions: [], - }) - // 선택 데이터 초 기화 setModuleConstructionSelectionData({ addRoof: addRoof, @@ -437,14 +429,13 @@ export function useModuleTabContents({ tabIndex, addRoof, setAddedRoofs, roofTab //임시 데이터 초기화 setTempModuleSelectionData({ ...moduleSelectionData, - roofConstructions: tempRoofConstructions, + roofConstructions: num === 2 ? [] : tempRoofConstructions, }) //처마커버 해제 setCvrChecked(false) //눈막이금구 해제 setSnowGdChecked(false) - // 데이터 없음으로 변경 setIsExistData(false) From b923998d64b9a3d8d9b97d11e081958d94e17fff Mon Sep 17 00:00:00 2001 From: basssy Date: Tue, 11 Mar 2025 13:14:02 +0900 Subject: [PATCH 303/352] =?UTF-8?q?#881=20=EC=9D=BC=EB=B3=B8=EC=96=B4=20?= =?UTF-8?q?=EB=B2=88=EC=97=AD=EB=B3=B8=20=EB=AC=BC=EA=B1=B4=ED=99=94?= =?UTF-8?q?=EB=A9=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/pagination/QPagination.jsx | 2 +- .../management/StuffSearchCondition.jsx | 5 ----- .../management/popup/FindAddressPop.jsx | 1 - .../management/popup/PlanRequestPop.jsx | 1 - src/hooks/usePagination.js | 4 +++- src/locales/ja.json | 16 ++++++++-------- 6 files changed, 12 insertions(+), 17 deletions(-) diff --git a/src/components/common/pagination/QPagination.jsx b/src/components/common/pagination/QPagination.jsx index 1d5aa7d3..3b0fe205 100644 --- a/src/components/common/pagination/QPagination.jsx +++ b/src/components/common/pagination/QPagination.jsx @@ -26,7 +26,7 @@ export default function QPagination(props) { {pageRange.map((page) => (
  • -
  • diff --git a/src/components/management/StuffSearchCondition.jsx b/src/components/management/StuffSearchCondition.jsx index c00e8bd6..3774fbfe 100644 --- a/src/components/management/StuffSearchCondition.jsx +++ b/src/components/management/StuffSearchCondition.jsx @@ -950,11 +950,6 @@ export default function StuffSearchCondition() {

    {getMessage('stuff.search.title')}

    - {/* - - */} + */} - + */}
    -
    +
    {type === OUTER_LINE_TYPE.OUTER_LINE ? ( ) : type === OUTER_LINE_TYPE.RIGHT_ANGLE ? ( From aeca8261a81fbee2c0ee068ef28f3225d1032f1e Mon Sep 17 00:00:00 2001 From: LEEYONGJAE Date: Wed, 12 Mar 2025 11:31:48 +0900 Subject: [PATCH 305/352] =?UTF-8?q?=EC=9E=90=EB=8F=99=20=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=9D=B8=20url=20=EC=88=98=EC=A0=95=20>=20=EA=B7=B8=EB=9E=9C?= =?UTF-8?q?=EB=93=9C=20=EC=98=A4=ED=94=88=20=EC=A0=84=EA=B9=8C=EC=A7=80?= =?UTF-8?q?=EB=8A=94=20=EC=8A=A4=ED=85=8C=EC=9D=B4=EC=A7=95=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.production | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.env.production b/.env.production index 990adb32..09bb27d3 100644 --- a/.env.production +++ b/.env.production @@ -7,5 +7,7 @@ SESSION_SECRET="i3iHH1yp2/2SpQSIySQ4bpyc4g0D+zCF9FAn5xUG0+Y=" # NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_bV5zuYMyyIYFlOb3" NEXT_PUBLIC_CONVERTER_API_URL="https://v2.convertapi.com/convert/dwg/to/png?Secret=secret_yAS4QDalL9jgQ7vS" -NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL="https://q-order.q-cells.jp/eos/login/autoLogin" -NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL="https://q-musubi.q-cells.jp/qm/login/autoLogin" \ No newline at end of file +# NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL="https://q-order.q-cells.jp/eos/login/autoLogin" +# NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL="https://q-musubi.q-cells.jp/qm/login/autoLogin" +NEXT_PUBLIC_Q_ORDER_AUTO_LOGIN_URL="http://q-order-stg.q-cells.jp:8120/eos/login/autoLogin" +NEXT_PUBLIC_Q_MUSUBI_AUTO_LOGIN_URL="http://q-musubi-stg.q-cells.jp:8120/qm/login/autoLogin" \ No newline at end of file From 156256c4ea2490c410c458581a7c4cf940754a52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 12 Mar 2025 12:59:22 +0900 Subject: [PATCH 306/352] =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EC=9D=B4=EB=8F=99?= =?UTF-8?q?=20=ED=9B=84=20=EC=88=98=EB=8F=99=EB=B0=B0=EC=B9=98=20=EC=8B=9C?= =?UTF-8?q?=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95=20=EC=9C=A1=EC=A7=80?= =?UTF-8?q?=EB=B6=95=EC=9D=BC=20=EA=B2=BD=EC=9A=B0=20=EC=88=98=EB=8F=99?= =?UTF-8?q?=EB=B0=B0=EC=B9=98=EC=8B=9C=20moduleInfo=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 63 ++--------------------- 1 file changed, 4 insertions(+), 59 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 44a0d02e..355fedc2 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -730,7 +730,7 @@ export function useModuleBasicSetting(tabNum) { tempModule.setCoords() //좌표 재정렬 if (turf.booleanContains(turfPolygon, tempTurfModule) || turf.booleanWithin(tempTurfModule, turfPolygon)) { //마우스 클릭시 set으로 해당 위치에 셀을 넣음 - const isOverlap = manualDrawModules.some((module) => turf.booleanOverlap(tempTurfModule, polygonToTurfPolygon(module))) //겹치는지 확인 + const isOverlap = manualDrawModules.some((module) => turf.booleanOverlap(tempTurfModule, polygonToTurfPolygon(module, true))) //겹치는지 확인 if (!isOverlap) { canvas?.remove(tempModule) @@ -2205,12 +2205,13 @@ export function useModuleBasicSetting(tabNum) { if (turf.booleanWithin(tempTurfModule, turfPolygon)) { //마우스 클릭시 set으로 해당 위치에 셀을 넣음 - const isOverlap = manualDrawModules.some((module) => turf.booleanOverlap(tempTurfModule, polygonToTurfPolygon(module))) //겹치는지 확인 + const isOverlap = manualDrawModules.some((module) => turf.booleanOverlap(tempTurfModule, polygonToTurfPolygon(module, true))) //겹치는지 확인 if (!isOverlap) { moduleOptions.surfaceId = trestlePolygon.id let manualModule = new QPolygon(tempModule.points, { ...moduleOptions, moduleInfo: checkedModule[0] }) canvas?.add(manualModule) - manualDrawModules.push(tempModule) + manualDrawModules.push(manualModule) + setModuleStatisticsData() } else { swalFire({ text: getMessage('module.place.overlab') }) } @@ -2626,62 +2627,6 @@ export function useModuleBasicSetting(tabNum) { return isDisjoint } - const getModuleStatistics = () => { - const surfaces = canvas.getObjects().filter((obj) => POLYGON_TYPE.MODULE_SETUP_SURFACE === obj.name) - // console.log('🚀 ~ getModuleStatistics ~ surfaces:', surfaces) - let totalWpout = 0 - let moduleInfo = {} - const rows = surfaces.map((surface) => { - let wpOut = 0 - moduleInfo = {} - surface.modules.forEach((module) => { - if (!moduleInfo[module.moduleInfo.itemId]) { - moduleInfo[module.moduleInfo.itemId] = { name: module.moduleInfo.itemNm, amount: 0, id: module.moduleInfo.itemId } - } - wpOut += +module.moduleInfo.wpOut - - moduleInfo[module.moduleInfo.itemId].amount++ - }) - totalWpout += wpOut - // console.log('🚀 ~ moduleData.rows=surfaces.map ~ module:', module) - const rowObject = {} - Object.keys(moduleInfo).forEach((key) => { - rowObject[key] = moduleInfo[key].amount - }) - return { - ...rowObject, // 총 발전량 = 발전량 * 모듈 개수 - ...surface, - name: canvas.getObjects().filter((obj) => obj.id === surface.parentId)[0].directionText, // 지붕면 - // powerGeneration: wpOut.toLocaleString('ko-KR', { maximumFractionDigits: 4 }), - wpOut: (wpOut / 1000).toFixed(3), - } - }) - - // console.log('🚀 ~ getModuleStatistics ~ rows:', rows) - // console.log('🚀 ~ getModuleStatistics ~ moduleInfo:', moduleInfo) - const header = [ - { name: getMessage('modal.panel.batch.statistic.roof.shape'), prop: 'name' }, - ...Object.keys(moduleInfo).map((key) => { - return { name: moduleInfo[key].name, prop: key } - }), - { name: `${getMessage('modal.panel.batch.statistic.power.generation.amount')}(kW)`, prop: 'wpOut' }, - ] - let footer = [getMessage('modal.panel.batch.statistic.total')] - let footerData = {} - rows.forEach((row) => { - Object.keys(moduleInfo).map((key) => { - if (!footerData[key]) footerData[key] = 0 - footerData[key] += row[key] - }) - }) - Object.keys(footerData).forEach((key) => { - footer.push(footerData[key]) - }) - footer.push((totalWpout / 1000).toFixed(3)) - // console.log({ header: header, rows, footer: footer }) - setModuleStatistics({ header: header, rows, footer: footer }) - } - /** * 모듈의 너비와 높이를 계산하는 함수 * @param {object} maxLengthLine 최대 길이 라인 From c3a6c121cae5946e135996393ec2144ee16c82ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Wed, 12 Mar 2025 14:06:02 +0900 Subject: [PATCH 307/352] =?UTF-8?q?resetRecoilData=EC=97=90=20CompassDeg?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasFrame.jsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/floor-plan/CanvasFrame.jsx b/src/components/floor-plan/CanvasFrame.jsx index 68e5cf7a..ddce32a6 100644 --- a/src/components/floor-plan/CanvasFrame.jsx +++ b/src/components/floor-plan/CanvasFrame.jsx @@ -29,6 +29,7 @@ import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupSta import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' import { useCanvasMenu } from '@/hooks/common/useCanvasMenu' import { useEvent } from '@/hooks/useEvent' +import { compasDegAtom } from '@/store/orientationAtom' export default function CanvasFrame() { const canvasRef = useRef(null) @@ -45,6 +46,7 @@ export default function CanvasFrame() { const resetSelectedMakerState = useResetRecoilState(selectedMakerState) const resetSeriesState = useResetRecoilState(seriesState) const resetModelsState = useResetRecoilState(modelsState) + const resetCompasDeg = useResetRecoilState(compasDegAtom) const resetSelectedModelsState = useResetRecoilState(selectedModelsState) const resetPcsCheckState = useResetRecoilState(pcsCheckState) const { handleModuleSelectionTotal } = useCanvasPopupStatusController() @@ -103,6 +105,7 @@ export default function CanvasFrame() { resetSelectedMakerState() resetSeriesState() resetModelsState() + resetCompasDeg() resetSelectedModelsState() resetPcsCheckState() } From cbcf8aa837511cb96637ba5bd83445991c8dc571 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Wed, 12 Mar 2025 14:40:06 +0900 Subject: [PATCH 308/352] =?UTF-8?q?smartRack=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useTrestle.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index 8abbae3c..da4e8a30 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -2157,6 +2157,18 @@ export const useTrestle = () => { rackRows: rack.rackRowsCd, } }) + + let smartRackParams = Object.values(smartRackGroup).map((smartRack, index) => { + return { + seq: index, + itemId: smartRack[0].rackId, + rackFittingCnt: smartRack[0].supFitQty, + rackRows: smartRack[0].rackRowsCd, + } + }) + + rackParams = [...rackParams, ...smartRackParams] + const parent = canvas.getObjects().find((obj) => obj.id === surface.parentId) const roofMaterialIndex = parent.roofMaterial.index const moduleSelection = moduleSelectionData?.roofConstructions?.find((construction) => construction.roofIndex === roofMaterialIndex) From 6c701c23df0a62174ec4899784b68a17d047ed96 Mon Sep 17 00:00:00 2001 From: basssy Date: Wed, 12 Mar 2025 16:54:11 +0900 Subject: [PATCH 309/352] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=9E=90?= =?UTF-8?q?=EB=8F=99=EC=99=84=EC=84=B1=20=EC=9C=84=EB=A1=9C=20=EC=97=B4?= =?UTF-8?q?=EB=A6=AC=EB=8A=94=20=EC=98=B5=EC=85=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index b6bdbfef..c9a38727 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -1780,7 +1780,7 @@ export default function Estimate({}) { onChangeDisplayItem(e.itemId, item.dispOrder, index) } }} - // defaultInputValue={item.itemName} + menuPlacement={'auto'} getOptionLabel={(x) => x.itemName} getOptionValue={(x) => x.itemId} isClearable={false} From 7c48433082870da84c776e381edc9937723c4689 Mon Sep 17 00:00:00 2001 From: basssy Date: Wed, 12 Mar 2025 17:16:40 +0900 Subject: [PATCH 310/352] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=ED=99=94=EB=A9=B4=20=EB=B2=88=EC=97=AD=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/locales/ja.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/locales/ja.json b/src/locales/ja.json index 927287e8..a42f9cec 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -907,7 +907,7 @@ "estimate.detail.header.specialEstimateProductInfo": "製品情報", "estimate.detail.sepcialEstimateProductInfo.totAmount": "数量(PCS)", "estimate.detail.sepcialEstimateProductInfo.totVolKw": "容量(kW)", - "estimate.detail.sepcialEstimateProductInfo.supplyPrice": "供給価格", + "estimate.detail.sepcialEstimateProductInfo.supplyPrice": "見積価格", "estimate.detail.sepcialEstimateProductInfo.vatPrice": "税(10%)", "estimate.detail.sepcialEstimateProductInfo.totPrice": "総額", "estimate.detail.sepcialEstimateProductInfo.pkgUnitPrice": "住宅PKG単価(W)", @@ -920,7 +920,7 @@ "estimate.detail.showPrice.description1": "製品価格OPEN", "estimate.detail.showPrice.description2": "追加の変更品目", "estimate.detail.showPrice.description3": "添付必須", - "estimate.detail.showPrice.description4": "クリックして製品の特異性を確認する", + "estimate.detail.showPrice.description4": "クリックで製品特記事項を確認できます", "estimate.detail.showPrice.addItem": "製品追加", "estimate.detail.showPrice.delItem": "製品の削除", "estimate.detail.itemTableHeader.dispOrder": "アイテム", From 3026cecaa0fed57c7f42f6716dae42a1e00692ea Mon Sep 17 00:00:00 2001 From: basssy Date: Wed, 12 Mar 2025 17:49:48 +0900 Subject: [PATCH 311/352] =?UTF-8?q?=EB=A9=94=EC=9D=B8=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?&=20=ED=97=A4=EB=8D=94=EB=A9=94=EB=85=80=20=EC=9E=90=EB=A3=8C?= =?UTF-8?q?=EB=8B=A4=EC=9A=B4=EB=A1=9C=EB=93=9C=20=EB=B2=88=EC=97=AD?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/main/MainContents.jsx | 2 +- src/locales/ja.json | 5 +++-- src/locales/ko.json | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/components/main/MainContents.jsx b/src/components/main/MainContents.jsx index 0d9a315f..6d6ccd82 100644 --- a/src/components/main/MainContents.jsx +++ b/src/components/main/MainContents.jsx @@ -199,7 +199,7 @@ export default function MainContents({ setFaqOpen, setFaqModalNoticeNo }) {
    )} - + {fileList.length > 0 ? (
    {fileList?.map((file) => ( diff --git a/src/locales/ja.json b/src/locales/ja.json index a42f9cec..f15d548e 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -9,7 +9,7 @@ "header.menus.community": "コミュニティ", "header.menus.community.notice": "お知らせ", "header.menus.community.faq": "FAQ", - "header.menus.community.archive": "見積書出力", + "header.menus.community.archive": "各種資料ダウンロード", "header.logout": "ログアウト", "header.go": "移動", "header.online.warranty.system": "オンライン保証システム", @@ -849,9 +849,10 @@ "main.storeName": "販売店名", "main.objectNo": "物件番号", "main.faq": "FAQ", + "main.archive": "各種資料ダウンロード", "main.content.objectList.noData1": "登録された商品情報はありません。", "main.content.objectList.noData2": "下のボタンをクリックして商品情報を登録してください。", - "main.content.objectList": "最近の更新物件一覧", + "main.content.objectList": "直近の見積書一覧", "main.content.notice": "お知らせ", "main.content.download1": "操作マニュアル", "main.content.download2": "屋根の説明書", diff --git a/src/locales/ko.json b/src/locales/ko.json index 5c5dfe03..ef3f8a87 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -9,7 +9,7 @@ "header.menus.community": "커뮤니티", "header.menus.community.notice": "공지사항", "header.menus.community.faq": "FAQ", - "header.menus.community.archive": "문서다운로드", + "header.menus.community.archive": "각종 자료 다운로드", "header.logout": "로그아웃", "header.go": "이동", "header.online.warranty.system": "온라인보증시스템", @@ -849,6 +849,7 @@ "main.storeName": "판매점명", "main.objectNo": "물건번호", "main.faq": "FAQ", + "main.archive": "각종 자료 다운로드", "main.content.objectList.noData1": "등록된 물건정보가 없습니다.", "main.content.objectList.noData2": "아래 버튼을 클릭하여 물건정보를 등록하십시오.", "main.content.objectList": "최근 갱신 물건목록", From 66f5613e02328dae8f425b7ff30f884426aef85f Mon Sep 17 00:00:00 2001 From: basssy Date: Thu, 13 Mar 2025 09:10:30 +0900 Subject: [PATCH 312/352] =?UTF-8?q?=EC=9E=90=EB=A3=8C=EB=8B=A4=EC=9A=B4?= =?UTF-8?q?=EB=A1=9C=EB=93=9C=20->=EA=B0=81=EC=A2=85=20=EC=9E=90=EB=A3=8C?= =?UTF-8?q?=20=EB=8B=A4=EC=9A=B4=EB=A1=9C=EB=93=9C=20=EC=9D=BC=EB=B3=B8?= =?UTF-8?q?=EC=96=B4=EB=9E=91=20=EB=A7=9E=EC=B6=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/locales/ja.json | 2 +- src/locales/ko.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/locales/ja.json b/src/locales/ja.json index f15d548e..8a0bfd0c 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -557,7 +557,7 @@ "board.notice.sub.title": "お知らせ一覧", "board.faq.title": "FAQ", "board.faq.sub.title": "FAQリスト", - "board.archive.title": "資料のダウンロード", + "board.archive.title": "各種資料ダウンロード", "board.archive.sub.title": "見積書一覧", "board.list.header.rownum": "番号", "board.list.header.title": "タイトル", diff --git a/src/locales/ko.json b/src/locales/ko.json index ef3f8a87..0d00105b 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -557,7 +557,7 @@ "board.notice.sub.title": "공지사항 목록", "board.faq.title": "FAQ", "board.faq.sub.title": "FAQ 목록", - "board.archive.title": "자료 다운로드", + "board.archive.title": "각종 자료 다운로드", "board.archive.sub.title": "문서 목록", "board.list.header.rownum": "번호", "board.list.header.title": "제목", From c75d3259c73e7649cd7bf286c452a8a0fb09bc65 Mon Sep 17 00:00:00 2001 From: basssy Date: Thu, 13 Mar 2025 09:46:51 +0900 Subject: [PATCH 313/352] =?UTF-8?q?#884=20=EA=B2=AC=EC=A0=81=EC=84=9C=20?= =?UTF-8?q?=EC=9E=90=EB=8F=99=EC=99=84=EC=84=B1=20=EC=95=84=EC=9D=B4?= =?UTF-8?q?=ED=85=9C=20=EA=B2=80=EC=83=89=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index c9a38727..4e331009 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -1782,11 +1782,15 @@ export default function Estimate({}) { }} menuPlacement={'auto'} getOptionLabel={(x) => x.itemName} - getOptionValue={(x) => x.itemId} + getOptionValue={(x) => x.itemNo} isClearable={false} isDisabled={!!item?.paDispOrder} value={displayItemList.filter(function (option) { - return option.itemId === item.itemId + if (item.itemNo === '') { + return false + } else { + return option.itemId === item.itemId + } })} />
    From ab5372b86758953249e450777249fb6282528ee1 Mon Sep 17 00:00:00 2001 From: basssy Date: Thu, 13 Mar 2025 10:13:28 +0900 Subject: [PATCH 314/352] =?UTF-8?q?#886=20=EB=B4=84=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EC=98=A4=ED=94=88=20=ED=94=8C=EB=9E=98?= =?UTF-8?q?=EA=B7=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 1 + src/hooks/floorPlan/estimate/useEstimateController.js | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 4e331009..3126f5bc 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -782,6 +782,7 @@ export default function Estimate({}) { bomItem.objectNo = objectNo bomItem.planNo = planNo bomItem.addFlg = true //봄 추가시도 addFlg + bomItem.openFlg = '0' //봄 컴포넌트는 무조건 0으로 }) updateList = updateList.filter((item) => item.delFlg === '0') diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index 9c00d5bb..3a73c038 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -298,6 +298,9 @@ export const useEstimateController = (planNo, flag) => { } } } + } else { + //봄 컴포넌트 제품은 0으로 + item.openFlg = '0' } } }) From 6105d3a1bf936f791c581b0461c5e671a1a628d1 Mon Sep 17 00:00:00 2001 From: LEEYONGJAE Date: Thu, 13 Mar 2025 11:16:55 +0900 Subject: [PATCH 315/352] =?UTF-8?q?=EB=B0=9C=EC=A0=84=20=EC=8B=9C=EB=AE=AC?= =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=85=98=20excel/pdf=20=EB=8B=A4=EC=9A=B4=20?= =?UTF-8?q?api=20url=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 4a8714d5..66dbf43a 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -111,7 +111,7 @@ export default function CanvasMenu(props) { //임시 const { selectedPlan } = usePlan() const handleExcelPdfFileDown = async (donwloadType, drawingFlg) => { - const url = '/api/estimate/excel-download' + const url = '/api/pwrGnrSimulation/excel-download' const params = { objectNo: objectNo, From d60a38594c7d6baae36c5fd261ba7db771ecaf21 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 13 Mar 2025 11:21:11 +0900 Subject: [PATCH 316/352] =?UTF-8?q?=EA=B0=80=EB=8C=80=20=EC=84=A4=EC=B9=98?= =?UTF-8?q?=20=EA=B3=84=EC=82=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useTrestle.js | 40 +++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index da4e8a30..b4f06250 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -1730,7 +1730,7 @@ export const useTrestle = () => { const { width, height } = { ...module } widthArr.push(width) heightArr.push(height) - centerPoints.push({ x, y, width: Math.floor(width), height: Math.floor(height), index, moduleInfo: module.moduleInfo }) + centerPoints.push({ x, y, width: Math.floor(width), height: Math.floor(height), index, moduleInfo: module.moduleInfo, module }) }) //widthArr 중복 제거 1이상 차이가 나지 않으면 같은 너비로 간주 @@ -1804,7 +1804,13 @@ export const useTrestle = () => { let rightExposedHalfTopPoints = [] centerPoints.forEach((centerPoint, index) => { - let { x, y, width, height, widthArr, heightArr } = { ...centerPoint } + let { x, y, width, height, widthArr, heightArr, module } = { ...centerPoint } + + /* 디버깅용 + const originFill = module.fill + module.set('fill', 'red') + canvas.renderAll()*/ + // centerPoints중에 현재 centerPoint와 x값이 같고, y값이 y-height값과 같은 centerPoint가 있는지 확인 let bottomCell let bottomLeftPoint @@ -1894,7 +1900,12 @@ export const useTrestle = () => { break } + /** + * 디버깅용 + module.set('fill', originFill) + canvas.renderAll() + */ if (bottomCell) { return } @@ -1911,13 +1922,18 @@ export const useTrestle = () => { } } else if (leftBottomCnt + rightBottomCnt === 0) { exposedBottomPoints.push(centerPoint) + } else if (leftBottomCnt + rightBottomCnt === 2) { + touchDimension++ } }) // 노출상면 및 접면 체크 centerPoints.forEach((centerPoint, index) => { - let { x, y, width, height, widthArr, heightArr } = { ...centerPoint } - + let { x, y, width, height, widthArr, heightArr, module } = { ...centerPoint } + const originFill = module.fill + /* 디버깅용 + module.set('fill', 'blue') + canvas.renderAll()*/ let topCell let topLeftPoint let topRightPoint @@ -1930,7 +1946,8 @@ export const useTrestle = () => { height = height + vertical heightArr.forEach((h) => { if (topCell) return - topCell = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y + h)) < maxY) + topCell = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y - h)) < maxY) + if (leftTopCnt === 0) { topLeftPoint = { x: x - width / 2, y: y - h } leftTopCnt = centerPoints.filter( @@ -1949,7 +1966,7 @@ export const useTrestle = () => { height = height + vertical heightArr.forEach((h) => { if (topCell) return - topCell = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y - h)) < maxY) + topCell = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y + h)) < maxY) if (leftTopCnt === 0) { topLeftPoint = { x: x + width / 2, y: y + h } leftTopCnt = centerPoints.filter( @@ -1968,7 +1985,7 @@ export const useTrestle = () => { width = width + horizontal widthArr.forEach((w) => { if (topCell) return - topCell = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x + w)) < maxX && Math.abs(centerPoint.y - y) < maxY) + topCell = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x - w)) < maxX && Math.abs(centerPoint.y - y) < maxY) if (leftTopCnt === 0) { topLeftPoint = { x: x - w, y: y + height / 2 } leftTopCnt = centerPoints.filter( @@ -1988,7 +2005,7 @@ export const useTrestle = () => { width = width + horizontal widthArr.forEach((w) => { if (topCell) return - topCell = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x - w)) < maxX && Math.abs(centerPoint.y - y) < maxY) + topCell = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x + w)) < maxX && Math.abs(centerPoint.y - y) < maxY) if (leftTopCnt === 0) { topLeftPoint = { x: x + w, y: y - height / 2 } leftTopCnt = centerPoints.filter( @@ -2010,6 +2027,13 @@ export const useTrestle = () => { return } + /** + * 디버깅 용 + + module.set('fill', originFill) + canvas.renderAll() + */ + if (leftTopCnt + rightTopCnt === 2) { touchDimension++ return From aad5c42b25acd1cf36849412f75464c1f0b21279 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 13 Mar 2025 12:28:17 +0900 Subject: [PATCH 317/352] =?UTF-8?q?=EB=B0=B0=EC=97=B4=20sort=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useTrestle.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index b4f06250..3ef6d335 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -619,6 +619,9 @@ export const useTrestle = () => { //module Rack 정보를 얻기위한 데이터 가공 function moduleTransformData(arr) { + //arr의 moduleTpCd를 이용하여 정렬 + arr = arr.sort((a, b) => a.moduleTpCd.localeCompare(b.moduleTpCd)) + let counts = {} arr.forEach((item) => { From 22ca59e9b9538741f722ee82fc9fb73b0320d089 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 13 Mar 2025 13:26:32 +0900 Subject: [PATCH 318/352] =?UTF-8?q?=EB=9E=99=EC=97=86=EC=9D=8C=EC=9D=98=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=20=EC=A7=80=EC=A7=80=EA=B8=88=EA=B5=AC=20?= =?UTF-8?q?=EC=84=A4=EC=B9=98=20=EC=A2=8C=ED=91=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useTrestle.js | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index 3ef6d335..50d11cb9 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -1652,10 +1652,29 @@ export const useTrestle = () => { } } + switch (direction) { + case 'south': { + startPointY -= 5 + break + } + case 'east': { + startPointX -= 5 + break + } + case 'west': { + startPointX += 5 + break + } + case 'north': { + startPointY += 5 + break + } + } + for (let i = 0; i < count; i++) { const bracket = new fabric.Rect({ - left: startPointX - 5, - top: startPointY - 5, + left: startPointX, + top: startPointY, fill: 'green', name: TRESTLE_MATERIAL.BRACKET, parentId: module.id, @@ -1668,7 +1687,7 @@ export const useTrestle = () => { canvas.add(bracket) canvas.renderAll() if (direction === 'south') { - startPointY -= height - moduleIntvlVer / 10 + startPointY -= height + moduleIntvlVer / 10 } else if (direction === 'north') { startPointY += height + moduleIntvlVer / 10 } else if (direction === 'east') { From 886ac38d34c899868066f617b93cde6037530a87 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Thu, 13 Mar 2025 13:50:54 +0900 Subject: [PATCH 319/352] =?UTF-8?q?fix:=20=ED=8C=9D=EC=97=85=EC=9A=A9=20?= =?UTF-8?q?=EC=8A=A4=ED=94=BC=EB=84=88=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/spinner/PopSpinner.jsx | 7 + src/styles/_modal.scss | 4433 ++++++++++-------- 2 files changed, 2380 insertions(+), 2060 deletions(-) create mode 100644 src/components/common/spinner/PopSpinner.jsx diff --git a/src/components/common/spinner/PopSpinner.jsx b/src/components/common/spinner/PopSpinner.jsx new file mode 100644 index 00000000..56b54b76 --- /dev/null +++ b/src/components/common/spinner/PopSpinner.jsx @@ -0,0 +1,7 @@ +export default function PopSpinner() { + return ( +
    + +
    + ) +} diff --git a/src/styles/_modal.scss b/src/styles/_modal.scss index 9ec806ef..35c843e7 100644 --- a/src/styles/_modal.scss +++ b/src/styles/_modal.scss @@ -4,531 +4,550 @@ $pop-bold-weight: 500; $pop-normal-size: 12px; $alert-color: #101010; -@keyframes mountpop{ - from{opacity: 0; scale: 0.95;} - to{opacity: 1; scale: 1;} +@keyframes mountpop { + from { + opacity: 0; + scale: 0.95; + } + to { + opacity: 1; + scale: 1; + } } -@keyframes unmountpop{ - from{opacity: 1; scale: 1;} - to{opacity: 0; scale: 0.95;} +@keyframes unmountpop { + from { + opacity: 1; + scale: 1; + } + to { + opacity: 0; + scale: 0.95; + } } -.normal-font{ - font-size: 12px; - font-weight: 400; - color: #fff; +.normal-font { + font-size: 12px; + font-weight: 400; + color: #fff; } -.bold-font{ - font-size: 12px; - font-weight: 500; - color: #fff; +.bold-font { + font-size: 12px; + font-weight: 500; + color: #fff; } -.modal-pop-wrap{ - position: fixed; +.modal-pop-wrap { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: -webkit-fit-content; + height: -moz-fit-content; + height: fit-content; + border: 1px solid #000; + border-radius: 4px; + background-color: #272727; + z-index: 100000; + &.xsm { + width: 200px; + } + &.xxxm { + width: 240px; + } + &.xxm { + width: 270px; + } + &.xm { + width: 300px; + } + &.ssm { + width: 380px; + } + &.sm { + width: 580px; + } + &.r { + width: 400px; + } + &.lr { + width: 440px; + } + &.lr-2 { + width: 450px; + } + &.lrr { + width: 480px; + } + &.ml { + width: 530px; + } + &.l-2 { + width: 640px; + } + &.lx-2 { + width: 740px; + } + &.lx { + width: 770px; + } + &.l { + width: 800px; + } + &.ll { + width: 900px; + } + &.mount { + animation: mountpop 0.17s ease-in-out forwards; + } + &.unmount { + animation: unmountpop 0.17s ease-in-out forwards; + } + &.alert { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background-color: transparent; + border: none; + .modal-head { + background-color: transparent; + padding: 0 0 8px; + .modal-close { + width: 20px; + height: 20px; + background: url(../../public/static/images/canvas/alert_close.svg) no-repeat center; + } + } + .modal-body { + background-color: #fff; + padding: 22px; + border-radius: 4px; + border: 1px solid #101010; + color: $alert-color; + .alert-title { + font-size: 13px; + font-weight: 700; + color: $alert-color; + margin-bottom: 15px; + } + } + } +} +.modal-head { + display: flex; + align-items: center; + padding: 10px 24px; + background-color: #000; + // overflow: hidden; + cursor: pointer; + h1.title { + font-size: 13px; + color: $pop-color; + font-weight: 700; + } + .modal-close { + margin-left: auto; + color: transparent; + font-size: 0; + width: 10px; + height: 10px; + background: url(../../public/static/images/canvas/modal_close.svg) no-repeat center; + } +} + +.modal-body { + position: relative; + padding: 24px; + .left-bar { + position: absolute; top: 0; left: 0; - width: 100%; - height: -webkit-fit-content; - height: -moz-fit-content; - height: fit-content; - border: 1px solid #000; - border-radius: 4px; - background-color: #272727; - z-index: 100000; - &.xsm{ - width: 200px; - } - &.xxxm{ - width: 240px; - } - &.xxm{ - width: 270px; - } - &.xm{ - width: 300px; - } - &.ssm{ - width: 380px; - } - &.sm{ - width: 580px; - } - &.r{ - width: 400px; - } - &.lr{ - width: 440px; - } - &.lr-2{ - width: 450px; - } - &.lrr{ - width: 480px; - } - &.ml{ - width: 530px; - } - &.l-2{ - width: 640px; - } - &.lx-2{ - width: 740px; - } - &.lx{ - width: 770px; - } - &.l{ - width: 800px; - } - &.ll{ - width: 900px; - } - &.mount{ - animation: mountpop .17s ease-in-out forwards; - } - &.unmount{ - animation: unmountpop .17s ease-in-out forwards; - } - &.alert{ - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - background-color: transparent; - border: none; - .modal-head{ - background-color: transparent; - padding: 0 0 8px; - .modal-close{ - width: 20px; - height: 20px; - background: url(../../public/static/images/canvas/alert_close.svg)no-repeat center; - } - } - .modal-body{ - background-color: #fff; - padding: 22px; - border-radius: 4px; - border: 1px solid #101010; - color: $alert-color; - .alert-title{ - font-size: 13px; - font-weight: 700; - color: $alert-color; - margin-bottom: 15px; - } - } - } -} -.modal-head{ + width: 5px; + height: 100%; + background-color: #000; + cursor: pointer; + } + .right-bar { + position: absolute; + top: 0; + right: 0; + width: 5px; + height: 100%; + background-color: #000; + cursor: pointer; + } + .modal-btn-wrap { display: flex; align-items: center; - padding: 10px 24px; - background-color: #000; - // overflow: hidden; - cursor: pointer; - h1.title{ - font-size: 13px; - color: $pop-color; - font-weight: 700; + gap: 5px; + button { + flex: 1; } - .modal-close{ - margin-left: auto; - color: transparent; - font-size: 0; - width: 10px; - height: 10px; - background: url(../../public/static/images/canvas/modal_close.svg)no-repeat center; + &.sub { + button { + flex: 1 1 auto; + padding: 0; + } + margin-bottom: 14px; } -} - -.modal-body{ - position: relative; - padding: 24px; - .left-bar{ - position: absolute; - top: 0; - left: 0; - width: 5px; - height: 100%; - background-color: #000; - cursor: pointer; - } - .right-bar{ - position: absolute; - top: 0; - right: 0; - width: 5px; - height: 100%; - background-color: #000; - cursor: pointer; - } - .modal-btn-wrap{ - display: flex; - align-items: center; - gap: 5px; - button{ - flex: 1; - } - &.sub{ - button{ - flex: 1 1 auto; - padding: 0; - } - margin-bottom: 14px; - } - } - .modal-check-btn-wrap{ - margin-top: 15px; - .check-wrap-title{ - font-size: $pop-normal-size; - color: $pop-color; - font-weight: 600; - &.light{ - font-weight: $pop-normal-weight; - } - } - .flex-check-box{ - display: flex; - flex-wrap: wrap; - gap: 10px; - margin-top: 15px; - &.for2{ - justify-content: flex-end; - button{ - width: calc(50% - 5px); - } - &.btn{ - gap: 5px; - button{ - width: calc(50% - 2.5px); - } - } - } - &.for-line{ - button{ - flex: 1; - } - } - } - } - .outer-line-wrap{ - border-top: 1px solid #3C3C3C; - margin-top: 10px; - padding-top: 15px; - margin-bottom: 15px; - > div{ - margin-bottom: 15px; - &:last-child{ - margin-bottom: 0; - } - } - } - .modal-guide{ - display: block; - font-size: $pop-normal-size; - color: $alert-color; + } + .modal-check-btn-wrap { + margin-top: 15px; + .check-wrap-title { + font-size: $pop-normal-size; + color: $pop-color; + font-weight: 600; + &.light { font-weight: $pop-normal-weight; + } } -} -.modal-foot{ + .flex-check-box { + display: flex; + flex-wrap: wrap; + gap: 10px; + margin-top: 15px; + &.for2 { + justify-content: flex-end; + button { + width: calc(50% - 5px); + } + &.btn { + gap: 5px; + button { + width: calc(50% - 2.5px); + } + } + } + &.for-line { + button { + flex: 1; + } + } + } + } + .outer-line-wrap { + border-top: 1px solid #3c3c3c; + margin-top: 10px; + padding-top: 15px; + margin-bottom: 15px; + > div { + margin-bottom: 15px; + &:last-child { + margin-bottom: 0; + } + } + } + .modal-guide { display: block; - width: 100%; - padding: 5px 0; - background-color: #000; - cursor: pointer; + font-size: $pop-normal-size; + color: $alert-color; + font-weight: $pop-normal-weight; + } +} +.modal-foot { + display: block; + width: 100%; + padding: 5px 0; + background-color: #000; + cursor: pointer; } -.adsorption-point{ +.adsorption-point { + display: flex; + align-items: center; + background-color: #3a3a3a; + border-radius: 3px; + padding-left: 11px; + overflow: hidden; + transition: all 0.17s ease-in-out; + span { + font-size: $pop-normal-size; + color: #898989; + } + i { display: flex; align-items: center; - background-color: #3A3A3A; - border-radius: 3px; - padding-left: 11px; - overflow: hidden; - transition: all 0.17s ease-in-out; - span{ - font-size: $pop-normal-size; - color: #898989; - } - i{ - display: flex; - align-items: center; - padding: 0 7px; - margin-left: auto; - height: 100%; - font-size: 13px; - color: #898989; - } - &.act{ - i{ - color: $pop-color; - background-color: #1083E3; - } + padding: 0 7px; + margin-left: auto; + height: 100%; + font-size: 13px; + color: #898989; + } + &.act { + i { + color: $pop-color; + background-color: #1083e3; } + } } // grid-option -.grid-check-form{ +.grid-check-form { + display: flex; + align-items: center; + gap: 15px; + padding-bottom: 15px; + &.border { + border-bottom: 1px solid #424242; + } +} +.grid-check-form-block { + display: block; + > div { + margin-bottom: 10px; + } +} +.grid-option-overflow { + max-height: 350px; + overflow-y: auto; + &::-webkit-scrollbar { + width: 4px; + background-color: transparent; + } + &::-webkit-scrollbar-thumb { + background-color: #d9d9d9; + } + &::-webkit-scrollbar-track { + background-color: transparent; + } +} +.grid-option-wrap { + .grid-option-box { display: flex; align-items: center; - gap: 15px; - padding-bottom: 15px; - &.border{ - border-bottom: 1px solid #424242; - } -} -.grid-check-form-block{ - display: block; - > div{ - margin-bottom: 10px; - } -} -.grid-option-overflow{ - max-height: 350px; - overflow-y: auto; - &::-webkit-scrollbar { - width: 4px; - background-color: transparent; - } - &::-webkit-scrollbar-thumb { - background-color: #D9D9D9; - } - &::-webkit-scrollbar-track { - background-color: transparent; - } -} -.grid-option-wrap{ - .grid-option-box{ - display: flex; - align-items: center; - background-color: transparent; - border: 1px solid #3D3D3D; - border-radius: 2px; - padding: 15px 10px; - gap: 20px; - margin-bottom: 10px; - .grid-input-form{ - display: flex; - align-items: center; - span{ - flex: none; - font-size: $pop-normal-size; - color: $pop-color; - font-weight: $pop-bold-weight; - } - .input-grid{ - width: 54px; - input{ - width: 100%; - } - } - } - &:last-child{ - margin-bottom: 0; - } - } - .grid-option-block-form{ - flex: 1; - .flex-ment{ - position: relative; - padding-right: 70px; - flex: 1 1 auto; - span{ - width: 70px; - &.absol{ - width: fit-content; - position: absolute; - top: 50%; - right: 0; - transform: translateY(-50%); - - } - } - .input-grid{ - flex: 1; - } - } - } -} -.select-form{ - .sort-select{width: 100%;} -} -.grid-select{ - flex: 1; - height: 30px; - &.no-flx{ - flex: unset; - } - .sort-select{ - width: 100%; - background-color: #313131; - min-width: auto; - font-size: 12px; - border: none; - p{ - font-size: 12px; - } - > ul{ - border: none; - } - } - &.right{ - p{ - text-align: right; - } - ul{ - li{ - justify-content: flex-end; - } - } - } -} -.grid-btn-wrap{ - padding-top: 15px; - text-align: right; - button{ - padding: 0 10px; - } -} - -// grid copy -.grid-option-tit{ - font-size: $pop-normal-size; - color: $pop-color; - font-weight: $pop-normal-weight; - padding-bottom: 15px; - -} -.grid-direction{ - display: flex; - align-items: center; - gap: 5px; - flex: 1; -} -.direction{ - width: 22px; - height: 22px; - background-color: #757575; - background-image: url(../../public/static/images/canvas/grid_option_arr.svg); - background-repeat: no-repeat; - background-position: center; - background-size: 16px 15px; - border-radius: 50%; - transition: all .15s ease-in-out; - opacity: 0.6; - &.down{transform: rotate(180deg);} - &.left{transform: rotate(-90deg);} - &.right{transform: rotate(90deg);} - &:hover, - &.act{ - opacity: 1; - } -} - -// grid-move -.move-form{ - width: 100%; - p{ + background-color: transparent; + border: 1px solid #3d3d3d; + border-radius: 2px; + padding: 15px 10px; + gap: 20px; + margin-bottom: 10px; + .grid-input-form { + display: flex; + align-items: center; + span { + flex: none; font-size: $pop-normal-size; color: $pop-color; font-weight: $pop-bold-weight; - } -} -.input-move-wrap{ - display: flex; - align-items: center; - gap: 5px; - span{ - color: $pop-color; - font-size: $pop-normal-size; - } - .input-move{ - width: 130px; - input{ - width: 100%; + } + .input-grid { + width: 54px; + input { + width: 100%; } + } } + &:last-child { + margin-bottom: 0; + } + } + .grid-option-block-form { + flex: 1; + .flex-ment { + position: relative; + padding-right: 70px; + flex: 1 1 auto; + span { + width: 70px; + &.absol { + width: fit-content; + position: absolute; + top: 50%; + right: 0; + transform: translateY(-50%); + } + } + .input-grid { + flex: 1; + } + } + } } -.direction-move-wrap{ - flex: none; - display: grid; - grid-template-columns: 1fr 1fr; - gap: 5px; - margin-left: auto; +.select-form { + .sort-select { + width: 100%; + } +} +.grid-select { + flex: 1; + height: 30px; + &.no-flx { + flex: unset; + } + .sort-select { + width: 100%; + background-color: #313131; + min-width: auto; + font-size: 12px; + border: none; + p { + font-size: 12px; + } + > ul { + border: none; + } + } + &.right { + p { + text-align: right; + } + ul { + li { + justify-content: flex-end; + } + } + } +} +.grid-btn-wrap { + padding-top: 15px; + text-align: right; + button { + padding: 0 10px; + } +} + +// grid copy +.grid-option-tit { + font-size: $pop-normal-size; + color: $pop-color; + font-weight: $pop-normal-weight; + padding-bottom: 15px; +} +.grid-direction { + display: flex; + align-items: center; + gap: 5px; + flex: 1; +} +.direction { + width: 22px; + height: 22px; + background-color: #757575; + background-image: url(../../public/static/images/canvas/grid_option_arr.svg); + background-repeat: no-repeat; + background-position: center; + background-size: 16px 15px; + border-radius: 50%; + transition: all 0.15s ease-in-out; + opacity: 0.6; + &.down { + transform: rotate(180deg); + } + &.left { + transform: rotate(-90deg); + } + &.right { + transform: rotate(90deg); + } + &:hover, + &.act { + opacity: 1; + } +} + +// grid-move +.move-form { + width: 100%; + p { + font-size: $pop-normal-size; + color: $pop-color; + font-weight: $pop-bold-weight; + } +} +.input-move-wrap { + display: flex; + align-items: center; + gap: 5px; + span { + color: $pop-color; + font-size: $pop-normal-size; + } + .input-move { + width: 130px; + input { + width: 100%; + } + } +} +.direction-move-wrap { + flex: none; + display: grid; + grid-template-columns: 1fr 1fr; + gap: 5px; + margin-left: auto; } // 배치면 초기 설정 -.placement-table{ - table{ - table-layout: fixed; - tr{ - th{ - font-size: $pop-normal-size; - color: $pop-color; - font-weight: $pop-bold-weight; - padding: 18px 0; - border-bottom: 1px solid #424242; - vertical-align: middle; - .tip-wrap{ - display: flex; - align-items: center; - } - } - td{ - font-size: $pop-normal-size; - color: $pop-color; - border-bottom: 1px solid #424242; - padding: 18px 0 18px 20px; - vertical-align: middle; - .flex-box{ - display: flex; - align-items: center; - } - } - &:first-child{ - td, - th{ - padding-top: 0; - } - } +.placement-table { + table { + table-layout: fixed; + tr { + th { + font-size: $pop-normal-size; + color: $pop-color; + font-weight: $pop-bold-weight; + padding: 18px 0; + border-bottom: 1px solid #424242; + vertical-align: middle; + .tip-wrap { + display: flex; + align-items: center; } + } + td { + font-size: $pop-normal-size; + color: $pop-color; + border-bottom: 1px solid #424242; + padding: 18px 0 18px 20px; + vertical-align: middle; + .flex-box { + display: flex; + align-items: center; + } + } + &:first-child { + td, + th { + padding-top: 0; + } + } } - .tooltip{ - position: relative; - display: block; - width: 15px; - height: 15px; - margin-left: 5px; - background: url(../../public/static/images/canvas/pop_tip.svg)no-repeat center; - background-size: cover; + } + .tooltip { + position: relative; + display: block; + width: 15px; + height: 15px; + margin-left: 5px; + background: url(../../public/static/images/canvas/pop_tip.svg) no-repeat center; + background-size: cover; + } + &.light { + padding: 0; + th, + td { + color: $alert-color; + border-bottom: none; + border-top: 1px solid #efefef; } - &.light{ - padding: 0; - th,td{ - color: $alert-color; - border-bottom: none; - border-top: 1px solid #EFEFEF; - } - th{ - padding: 14px 0; - } - tr{ - &:first-child{ - td, - th{ - padding-top: 14px; - } - } - &:last-child{ - td, - th{ - padding-bottom: 0px; - } - } - } + th { + padding: 14px 0; } + tr { + &:first-child { + td, + th { + padding-top: 14px; + } + } + &:last-child { + td, + th { + padding-bottom: 0px; + } + } + } + } } // 2024-12-11 @@ -539,1688 +558,1982 @@ $alert-color: #101010; // max-width: 250px; // } -.pop-form-radio{ - display: flex; - align-items: center; - gap: 10px; - &.place{ - gap: 33px; - .outline-form{ - span{ - width: fit-content; - } - .input-grid{ - width: 80px; - } - } +.pop-form-radio { + display: flex; + align-items: center; + gap: 10px; + &.place { + gap: 33px; + .outline-form { + span { + width: fit-content; + } + .input-grid { + width: 80px; + } } + } } -.placement-option{ - display: flex; - align-items: center; - gap: 20px; +.placement-option { + display: flex; + align-items: center; + gap: 20px; } -.select-wrap{ - .sort-select{ - width: 100%; - } -} -.flex-ment{ - display: flex; - align-items: center; - gap: 5px; - span{ - font-size: $pop-normal-size; - color: $pop-color; - font-weight: $pop-normal-weight; - } - -} - -.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; - cursor: pointer; - 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; +.select-wrap { + .sort-select { 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); - } + } +} +.flex-ment { + display: flex; + align-items: center; + gap: 5px; + span { + font-size: $pop-normal-size; + color: $pop-color; + font-weight: $pop-normal-weight; + } } -.for-address{ - input{ - flex: 1; +.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; + cursor: pointer; + transition: all 0.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; } - .check-address{ - flex: none; - width: 18px; - height: 18px; - margin-left: 5px; - background-repeat: no-repeat; - background-position: center; - background-size: cover; - &.fail{background-image: url(../../public/static/images/canvas/img_check_fail.svg);} - &.success{background-image: url(../../public/static/images/canvas/img_check_success.svg);} + &: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); + } +} + +.for-address { + input { + flex: 1; + } + .check-address { + flex: none; + width: 18px; + height: 18px; + margin-left: 5px; + background-repeat: no-repeat; + background-position: center; + background-size: cover; + &.fail { + background-image: url(../../public/static/images/canvas/img_check_fail.svg); + } + &.success { + background-image: url(../../public/static/images/canvas/img_check_success.svg); + } + } } // 외벽선 그리기 -.outline-wrap{ - padding: 24px 0; - border-top: 1px solid #424242; - - .outline-inner{ - display: flex; - align-items: center; - margin-bottom: 14px; - &:last-child{ - margin-bottom: 0; - } - .outline-form{ - // width: 50%; - margin-right: 15px; - } - } - &:last-child{ - border-bottom: 1px solid #424242; - } -} -.outline-form{ +.outline-wrap { + padding: 24px 0; + border-top: 1px solid #424242; + + .outline-inner { display: flex; align-items: center; - - span{ - width: 60px; - flex: none; - font-size: $pop-normal-size; - font-weight: $pop-bold-weight; - color: $pop-color; - margin-right: 10px; - &.thin{ - width: auto; - font-weight: $pop-normal-weight; - margin-right: 0; - } + margin-bottom: 14px; + &:last-child { + margin-bottom: 0; } + .outline-form { + // width: 50%; + margin-right: 15px; + } + } + &:last-child { + border-bottom: 1px solid #424242; + } +} +.outline-form { + display: flex; + align-items: center; - .reset-btn{ - flex: none; - width: 30px; - height: 30px; - background: transparent; - border: 1px solid #484848; - border-radius: 2px; - margin-left: 5px; - background-image: url(../../public/static/images/canvas/reset_ico.svg); - background-repeat: no-repeat; - background-size: 12px 12px; - background-position: center; - } - &:last-child{ - margin-right: 0; + span { + width: 60px; + flex: none; + font-size: $pop-normal-size; + font-weight: $pop-bold-weight; + color: $pop-color; + margin-right: 10px; + &.thin { + width: auto; + font-weight: $pop-normal-weight; + margin-right: 0; } + } + + .reset-btn { + flex: none; + width: 30px; + height: 30px; + background: transparent; + border: 1px solid #484848; + border-radius: 2px; + margin-left: 5px; + background-image: url(../../public/static/images/canvas/reset_ico.svg); + background-repeat: no-repeat; + background-size: 12px 12px; + background-position: center; + } + &:last-child { + margin-right: 0; + } } -.cul-wrap{ +.cul-wrap { + display: flex; + .outline-box { + width: 50%; + margin-right: 15px; + .outline-form { + width: 100%; + margin-bottom: 14px; + margin-right: 0; + &:last-child { + margin-bottom: 0; + } + } + } + .cul-box { display: flex; - .outline-box{ - width: 50%; - margin-right: 15px; - .outline-form{ - width: 100%; - margin-bottom: 14px; - margin-right: 0; - &:last-child{ - margin-bottom: 0; - } - } - } - .cul-box{ - display: flex; - align-items: center; - justify-content: center; - width: 50%; - background-color: #3D3D3D; - border-radius: 2px ; - } + align-items: center; + justify-content: center; + width: 50%; + background-color: #3d3d3d; + border-radius: 2px; + } } // 외벽선 속성 설정 -.properties-guide{ - font-size: $pop-normal-size; - color: #AAA; - font-weight: $pop-normal-weight; - margin-bottom: 14px; +.properties-guide { + font-size: $pop-normal-size; + color: #aaa; + font-weight: $pop-normal-weight; + margin-bottom: 14px; } -.setting-tit{ - font-size: 13px; - color: $pop-color; - font-weight: $pop-bold-weight; - margin-bottom: 10px; +.setting-tit { + font-size: 13px; + color: $pop-color; + font-weight: $pop-bold-weight; + margin-bottom: 10px; } -.properties-setting-wrap{ - &.outer{ - margin-top: 24px; - } - .setting-btn-wrap{ - display: flex; - align-items: center; - padding: 14px 0; - border-top: 1px solid #424242; - border-bottom: 1px solid #424242; - .setting-btn{ - display: block; - width: 100%; - height: 40px; - font-size: 13px; - color: #fff; - font-weight: 700; - border-radius: 2px; - transition: all .15s ease-in-out; - &.green{ - background-color: #305941; - border: 1px solid #45CD7D; - &:hover{ - background-color: #3a6b4e; - } - } - &.blue{ - background-color: #2E5360; - border: 1px solid #3FBAE6; - &:hover{ - background-color: #365f6e; - } - } - &.gray{ - background-color: #535353; - border: 1px solid #9e9e9e; - &:hover{ - background-color: #6b6b6b; - } - } - } - } -} - -// 지붕형상 설정 -.roof-shape-menu{ - display: grid; - grid-template-columns: 1fr 1fr 1fr 1fr; - grid-template-rows: 1fr 1fr; - gap: 24px 10px; - margin-bottom: 24px; - .shape-box{ - display: flex; - align-items: center; - justify-content: center; - width: 100%; - padding: 13px; - background-color: #3D3D3D; - transition: background .15s ease-in-out; - img{ - max-width: 100%; - } - } - .shape-title{ - font-size: $pop-normal-size; - font-weight: $pop-bold-weight; - color: $pop-color; - margin-top: 10px; - text-align: center; - transition: color .15s ease-in-out; - } - .shape-menu-box{ - &.act, - &:hover{ - .shape-box{background-color: #008BFF;} - .shape-title{color: #008BFF;} - } - } -} - -.setting-box{ +.properties-setting-wrap { + &.outer { + margin-top: 24px; + } + .setting-btn-wrap { + display: flex; + align-items: center; padding: 14px 0; border-top: 1px solid #424242; border-bottom: 1px solid #424242; -} -.padding-form{ - padding-left: 23px; -} -.discrimination-box{ - padding: 16px 12px; - border: 1px solid #3D3D3D; - border-radius: 2px; + .setting-btn { + display: block; + width: 100%; + height: 40px; + font-size: 13px; + color: #fff; + font-weight: 700; + border-radius: 2px; + transition: all 0.15s ease-in-out; + &.green { + background-color: #305941; + border: 1px solid #45cd7d; + &:hover { + background-color: #3a6b4e; + } + } + &.blue { + background-color: #2e5360; + border: 1px solid #3fbae6; + &:hover { + background-color: #365f6e; + } + } + &.gray { + background-color: #535353; + border: 1px solid #9e9e9e; + &:hover { + background-color: #6b6b6b; + } + } + } + } } -.modal-bottom-border-bx{ - margin-top: 24px; - padding-bottom: 14px; - border-bottom: 1px solid #424242; +// 지붕형상 설정 +.roof-shape-menu { + display: grid; + grid-template-columns: 1fr 1fr 1fr 1fr; + grid-template-rows: 1fr 1fr; + gap: 24px 10px; + margin-bottom: 24px; + .shape-box { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + padding: 13px; + background-color: #3d3d3d; + transition: background 0.15s ease-in-out; + img { + max-width: 100%; + } + } + .shape-title { + font-size: $pop-normal-size; + font-weight: $pop-bold-weight; + color: $pop-color; + margin-top: 10px; + text-align: center; + transition: color 0.15s ease-in-out; + } + .shape-menu-box { + &.act, + &:hover { + .shape-box { + background-color: #008bff; + } + .shape-title { + color: #008bff; + } + } + } +} + +.setting-box { + padding: 14px 0; + border-top: 1px solid #424242; + border-bottom: 1px solid #424242; +} +.padding-form { + padding-left: 23px; +} +.discrimination-box { + padding: 16px 12px; + border: 1px solid #3d3d3d; + border-radius: 2px; +} + +.modal-bottom-border-bx { + margin-top: 24px; + padding-bottom: 14px; + border-bottom: 1px solid #424242; } // 처마∙케라바 변경 -.eaves-keraba-table{ - display: table; - border-collapse: collapse; - .eaves-keraba-item{ - display: table-row; - .eaves-keraba-th, - .eaves-keraba-td{ - font-size: $pop-normal-size; - color: $pop-color; - font-weight: $pop-normal-weight; - display: table-cell; - vertical-align: middle; - padding-bottom: 14px; - } - .eaves-keraba-td{ - padding-left: 10px; - } - .eaves-keraba-ico{ - display: flex; - align-items: center; - justify-content: center; - padding: 5px; - background-color: #3D3D3D; - border: 1px solid #3D3D3D; - border-radius: 2px; - cursor: pointer; - &.act{ - border: 1px solid #ED0004; - } - } - &:last-child{ - .eaves-keraba-th, - .eaves-keraba-td{ - padding-bottom: 0; - } - } +.eaves-keraba-table { + display: table; + border-collapse: collapse; + .eaves-keraba-item { + display: table-row; + .eaves-keraba-th, + .eaves-keraba-td { + font-size: $pop-normal-size; + color: $pop-color; + font-weight: $pop-normal-weight; + display: table-cell; + vertical-align: middle; + padding-bottom: 14px; } + .eaves-keraba-td { + padding-left: 10px; + } + .eaves-keraba-ico { + display: flex; + align-items: center; + justify-content: center; + padding: 5px; + background-color: #3d3d3d; + border: 1px solid #3d3d3d; + border-radius: 2px; + cursor: pointer; + &.act { + border: 1px solid #ed0004; + } + } + &:last-child { + .eaves-keraba-th, + .eaves-keraba-td { + padding-bottom: 0; + } + } + } } -.guide{ - font-size: $pop-normal-size; - font-weight: $pop-normal-weight; - color: $pop-color; - margin-bottom: 24px; - &.sm{ - margin-bottom: 15px; - } - span{ - display: block; - } +.guide { + font-size: $pop-normal-size; + font-weight: $pop-normal-weight; + color: $pop-color; + margin-bottom: 24px; + &.sm { + margin-bottom: 15px; + } + span { + display: block; + } } // 지붕면 할당 -.allocation-select-wrap{ +.allocation-select-wrap { + display: flex; + align-items: center; + padding-bottom: 14px; + border-bottom: 1px solid #424242; + margin-bottom: 14px; + span { + font-size: $pop-normal-size; + color: $pop-color; + font-weight: $pop-bold-weight; + margin-right: 10px; + } + .allocation-edit { display: flex; align-items: center; - padding-bottom: 14px; - border-bottom: 1px solid #424242; - margin-bottom: 14px; - span{ - font-size: $pop-normal-size; - color: $pop-color; - font-weight: $pop-bold-weight; - margin-right: 10px; - } - .allocation-edit{ - display: flex; - align-items: center; - justify-content: center; - width: 100%; - height: 30px; - padding: 0 10px; - margin-left: 5px; - font-size: $pop-normal-size; - color: $pop-color; - font-weight: $pop-normal-weight; - border: 1px solid #484848; - background-color: #323234; - transition: background-color .13s ease-in-out; - i{ - display: block; - width: 12px; - height: 12px; - margin-right: 5px; - background: url(../../public/static/images/canvas/allocation_edit.svg)no-repeat center; - background-size: cover; - } - &:hover{ - background-color: #464545; - } - } -} - -.block-box{ - display: flex; - align-items: center; - gap: 10px; - margin-bottom: 10px; - .flex-ment{ - gap: 10px; - .dec{ - text-decoration: underline; - } - .delete{ - display: block; - width: 15px; - height: 15px; - background: url(../../public/static/images/canvas/allocation_delete.svg)no-repeat center; - background-size: cover; - } - } - &:last-child{ - margin-bottom: 0; - } -} - -.icon-btn-wrap{ - flex: 1; - display: flex; - align-items: center; - gap: 5px; - button{ - display: flex; - align-items: center; - justify-content: center; - width: 100%; - height: 30px; - font-size: $pop-normal-size; - font-weight: $pop-normal-weight; - color: $pop-color; - border: 1px solid #646464; - border-radius: 2px; - padding: 0 10px; - transition: all .15s ease-in-out; - i{ - height: 15px; - display: block; - margin-left: 10px; - background-repeat: no-repeat; - background-position: center; - background-size: cover; - transition: all .15s ease-in-out; - &.allocation01{ - background-image: url(../../public/static/images/canvas/allocation_icon01_white.svg); - width: 15px; - } - &.allocation02{ - background-image: url(../../public/static/images/canvas/allocation_icon02_white.svg); - width: 18px; - } - } - &.act, - &:hover{ - color: #101010; - border: 1px solid #101010; - background-color: #fff; - i{ - &.allocation01{ - background-image: url(../../public/static/images/canvas/allocation_icon01_black.svg); - } - &.allocation02{ - background-image: url(../../public/static/images/canvas/allocation_icon02_black.svg); - } - } - } - &:disabled{ - color: $pop-color; - border: 1px solid #646464; - background-color: transparent; - opacity: 0.5; - &.act, - &:hover{ - color: $pop-color; - border: 1px solid #646464; - background-color: transparent; - i{ - &.allocation01{ - background-image: url(../../public/static/images/canvas/allocation_icon01_white.svg); - } - &.allocation02{ - background-image: url(../../public/static/images/canvas/allocation_icon02_white.svg); - } - } - } - } - } -} - -// 경사설정 -.slope-wrap{ - padding-bottom: 24px; - border-bottom: 1px solid #424242; -} - -// 면형상 배치 -.plane-frame-wrap{ - display: flex; - gap: 10px; - .plane-shape-wrap{ - flex: none; - width: 73px; - } -} - -.plane-shape-menu{ - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 5px; - .shape-menu-box{ - border-radius: 2px; - width: 34px; - height: 34px; - background-color: #373737; - border: 1px solid #676767; - transition: background .15s ease-in-out, border .15s ease-in-out; - .shape-box{ - display: flex; - justify-content: center; - align-items: center; - position: relative; - width: 100%; - height: 100%; - border-radius: 2px; - } - &.act, - &:hover{ - border-color: #008BFF; - background-color: #008BFF; - } - } -} - -.shape-library{ - display: flex; - flex-direction: column; - align-items: center; justify-content: center; - gap: 5px; - padding-top: 5px; - .library-btn{ - width: 100%; - height: 34px; - border: 1px solid #6C6C6C; - border-radius: 2px; - background-color: #373737; - background-repeat: no-repeat; - background-position: center; - transition: all .15s ease-in-out; - &.ico01{background-image: url(../../public/static/images/canvas/shape_labrary01.svg); background-size: 19px 18px;} - &.ico02{background-image: url(../../public/static/images/canvas/shape_labrary02.svg); background-size: 15px 20px;} - &.ico03{background-image: url(../../public/static/images/canvas/shape_labrary03.svg); background-size: 19px 16px;} - &:hover{ - border-color: #1083E3; - background-color: #1083E3; - } + width: 100%; + height: 30px; + padding: 0 10px; + margin-left: 5px; + font-size: $pop-normal-size; + color: $pop-color; + font-weight: $pop-normal-weight; + border: 1px solid #484848; + background-color: #323234; + transition: background-color 0.13s ease-in-out; + i { + display: block; + width: 12px; + height: 12px; + margin-right: 5px; + background: url(../../public/static/images/canvas/allocation_edit.svg) no-repeat center; + background-size: cover; } + &:hover { + background-color: #464545; + } + } } -.plane-detail-wrap{ - display: flex; - flex-direction: column; - flex: 1; -} -.plane-shape-wrapper{ - flex: 1; - display: flex; - flex-direction: column; +.block-box { + display: flex; + align-items: center; + gap: 10px; + margin-bottom: 10px; + .flex-ment { gap: 10px; - .plane-box{ - width: 100%; - padding: 10px 18px; - border-radius: 2px; - background-color: #313131; - border: 1px solid #484848; - .plane-box-tit{ - font-size: $pop-normal-size; - font-weight: 600; - color: $pop-color; - margin-bottom: 10px; - } - &.shape-box{ - .shape-box-inner{ - display: flex; - gap:15px; - min-height: 140px; - .shape-img{ - position: relative; - flex: none; - width: 150px; - background-color: #fff; - border-radius: 2px; - img{ - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - } - } - .shape-data{ - flex: 1; - .eaves-keraba-table{ - .eaves-keraba-item{ - .eaves-keraba-th, - .eaves-keraba-td{ - padding-bottom: 10px; - } - &:last-child{ - .eaves-keraba-th, - .eaves-keraba-td{ - padding-bottom: 0px; - } - } - } - } - } - } - } - &.direction-box{ - flex: 1; - display: flex; - flex-direction: column; - .plane-direction-box{ - flex: 1; - display: flex; - align-items: center; - justify-content: center; - width: 100%; - } - } + .dec { + text-decoration: underline; } -} -.plane-direction{ - width: 150px; - position: relative; - height: 120px; - span{ - position: absolute; - font-size: 12px; - font-weight: 500; - color: #B1B1B1; - &.top{top: 0; left: 50%; transform: translateX(-50%);} - &.right{top: 50%; right: 0; transform: translateY(-50%);} - &.bottom{bottom: 0; left: 50%; transform: translateX(-50%);} - &.left{top: 50%; left: 0; transform: translateY(-50%);} - } - .plane-btn{ - position: absolute; - width: 28px; - height: 28px; - background-color: #777777; - background-image: url(../../public/static/images/canvas/plane_arr.svg); - background-size: 12px 13px; - background-repeat: no-repeat; - background-position: center; - border-radius: 50%; - transition: all .15s ease-in-out; - &.up{top: 22px; left: 50%; transform: translateX(-50%);} - &.right{top: 50%; right: 32px; transform: translateY(-50%) rotate(90deg);} - &.down{bottom: 22px; left: 50%; transform: translateX(-50%) rotate(180deg);} - &.left{top: 50%; left: 32px; transform: translateY(-50%) rotate(270deg);} - &:hover, - &.act{ - background-color: #fff; - background-image: url(../../public/static/images/canvas/plane_arr_act.svg); - } + .delete { + display: block; + width: 15px; + height: 15px; + background: url(../../public/static/images/canvas/allocation_delete.svg) no-repeat center; + background-size: cover; } + } + &:last-child { + margin-bottom: 0; + } } -.plane-tab-guide{ +.icon-btn-wrap { + flex: 1; + display: flex; + align-items: center; + gap: 5px; + button { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 30px; font-size: $pop-normal-size; font-weight: $pop-normal-weight; color: $pop-color; - margin-top: 10px; -} -.plane-shape-btn{ - padding-top: 10px; - margin-top: auto; - button{ - display: block; - width: 100%; + border: 1px solid #646464; + border-radius: 2px; + padding: 0 10px; + transition: all 0.15s ease-in-out; + i { + height: 15px; + display: block; + margin-left: 10px; + background-repeat: no-repeat; + background-position: center; + background-size: cover; + transition: all 0.15s ease-in-out; + &.allocation01 { + background-image: url(../../public/static/images/canvas/allocation_icon01_white.svg); + width: 15px; + } + &.allocation02 { + background-image: url(../../public/static/images/canvas/allocation_icon02_white.svg); + width: 18px; + } } + &.act, + &:hover { + color: #101010; + border: 1px solid #101010; + background-color: #fff; + i { + &.allocation01 { + background-image: url(../../public/static/images/canvas/allocation_icon01_black.svg); + } + &.allocation02 { + background-image: url(../../public/static/images/canvas/allocation_icon02_black.svg); + } + } + } + &:disabled { + color: $pop-color; + border: 1px solid #646464; + background-color: transparent; + opacity: 0.5; + &.act, + &:hover { + color: $pop-color; + border: 1px solid #646464; + background-color: transparent; + i { + &.allocation01 { + background-image: url(../../public/static/images/canvas/allocation_icon01_white.svg); + } + &.allocation02 { + background-image: url(../../public/static/images/canvas/allocation_icon02_white.svg); + } + } + } + } + } } -// 오브젝트 배치 -.mb-box{ - margin-bottom: 24px; +// 경사설정 +.slope-wrap { + padding-bottom: 24px; + border-bottom: 1px solid #424242; } -.object-direction-wrap{ - display: flex; - align-items: center; - justify-content: center; -} -.discrimination-tit{ - font-size: 13px; - color: #fff; - font-weight: 500; +// 면형상 배치 +.plane-frame-wrap { + display: flex; + gap: 10px; + .plane-shape-wrap { + flex: none; + width: 73px; + } } -.object-size-wrap{ - display: flex; - min-height: 206px; - margin-top: 14px; - .object-size-img{ - position: relative; - flex: none; - width: 200px; - background-color: #fff; - img{ +.plane-shape-menu { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 5px; + .shape-menu-box { + border-radius: 2px; + width: 34px; + height: 34px; + background-color: #373737; + border: 1px solid #676767; + transition: + background 0.15s ease-in-out, + border 0.15s ease-in-out; + .shape-box { + display: flex; + justify-content: center; + align-items: center; + position: relative; + width: 100%; + height: 100%; + border-radius: 2px; + } + &.act, + &:hover { + border-color: #008bff; + background-color: #008bff; + } + } +} + +.shape-library { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 5px; + padding-top: 5px; + .library-btn { + width: 100%; + height: 34px; + border: 1px solid #6c6c6c; + border-radius: 2px; + background-color: #373737; + background-repeat: no-repeat; + background-position: center; + transition: all 0.15s ease-in-out; + &.ico01 { + background-image: url(../../public/static/images/canvas/shape_labrary01.svg); + background-size: 19px 18px; + } + &.ico02 { + background-image: url(../../public/static/images/canvas/shape_labrary02.svg); + background-size: 15px 20px; + } + &.ico03 { + background-image: url(../../public/static/images/canvas/shape_labrary03.svg); + background-size: 19px 16px; + } + &:hover { + border-color: #1083e3; + background-color: #1083e3; + } + } +} + +.plane-detail-wrap { + display: flex; + flex-direction: column; + flex: 1; +} +.plane-shape-wrapper { + flex: 1; + display: flex; + flex-direction: column; + gap: 10px; + .plane-box { + width: 100%; + padding: 10px 18px; + border-radius: 2px; + background-color: #313131; + border: 1px solid #484848; + .plane-box-tit { + font-size: $pop-normal-size; + font-weight: 600; + color: $pop-color; + margin-bottom: 10px; + } + &.shape-box { + .shape-box-inner { + display: flex; + gap: 15px; + min-height: 140px; + .shape-img { + position: relative; + flex: none; + width: 150px; + background-color: #fff; + border-radius: 2px; + img { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); + } } - } - .object-size-input{ - margin-left: auto; - .eaves-keraba-th{ - position: relative; - .object-input-num{ - position: absolute; - top: 7px; - left: -20px; - font-size: 13px; - } - } - } -} - -// 표시변경 -.display-change-wrap{ - margin: 24px 0; -} -.warning{ - font-size: $pop-normal-size; - font-weight: $pop-normal-weight; - color: #FFAFAF; -} - -// 각 변 속성 변경 -.radio-grid-wrap{ - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 24px 15px; -} - -// 면 흐름 설정 -.drawing-flow-wrap{ - display: flex; - gap: 10px; - .discrimination-box{ - flex: 1; - display: flex; - flex-direction: column; - .object-direction-wrap{ - flex: 1; - } - &:first-child{ - flex: none; - width: 195px; - } - } -} - -.compas-box{ - display: flex; - align-items: center; - justify-content: center; -} -.compas-box-inner { - position: relative; - width: 200px; - height: 200px; - border-radius: 50%; - - .circle { - position: absolute; - width: 12px; - height: 12px; - border: 1px solid #fff; - border-radius: 50%; - top: 95%; - left: 50%; - transform-origin: 0 -90px; /* 중심에서 반지름 거리만큼 떨어져 위치 */ - cursor:pointer; - z-index: 3; - /* 0번을 180도 위치(아래)에, 13번을 0도 위치(위)에 배치 */ - i{ - position: absolute; - top: 12.5px; - left: 50%; - font-size: 11px; - color: #8B8B8B; - font-weight: 500; - -webkit-user-select: none; - -moz-user-select: none; - -ms-use-select: none; - user-select: none; - } - &:nth-child(1) { transform: rotate(180deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(180deg);}} - &:nth-child(2) { transform: rotate(195deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(165deg);}} - &:nth-child(3) { transform: rotate(210deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(150deg);}} - &:nth-child(4) { transform: rotate(225deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(135deg);}} - &:nth-child(5) { transform: rotate(240deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(120deg);}} - &:nth-child(6) { transform: rotate(255deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(105deg);}} - &:nth-child(7) { transform: rotate(270deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(90deg);}} - &:nth-child(8) { transform: rotate(285deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(75deg);}} - &:nth-child(9) { transform: rotate(300deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(60deg);}} - &:nth-child(10) { transform: rotate(315deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(45deg);}} - &:nth-child(11) { transform: rotate(330deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(30deg);}} - &:nth-child(12) { transform: rotate(345deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(15deg);}} - &:nth-child(13) { transform: rotate(0deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(0deg);}} - &:nth-child(14) { transform: rotate(15deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(-15deg);}} - &:nth-child(15) { transform: rotate(30deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(-30deg);}} - &:nth-child(16) { transform: rotate(45deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(-45deg);}} - &:nth-child(17) { transform: rotate(60deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(-60deg);}} - &:nth-child(18) { transform: rotate(75deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(-75deg);}} - &:nth-child(19) { transform: rotate(90deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(-90deg);}} - &:nth-child(20) { transform: rotate(105deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(-105deg);}} - &:nth-child(21) { transform: rotate(120deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(-120deg);}} - &:nth-child(22) { transform: rotate(135deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(-135deg);}} - &:nth-child(23) { transform: rotate(150deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(-150deg);}} - &:nth-child(24) { transform: rotate(165deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(-165deg);}} - &.act{ - &::after{ - content: ''; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - width: 5px; - height: 5px; - background-color: #fff; - border-radius: 50%; - } - i{ - color: #fff; - } - } - } - .compas{ - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - width: 148px; - height: 148px; - border: 4px solid #fff; - border-radius: 50%; - .compas-arr{ - width: 100%; - height: 100%; - background: url(../../public/static/images/canvas/compas.svg)no-repeat center; - background-size: 122px 122px; - } - } -} - -.draw-flow-wrap{ - margin: 10px 0; -} - -// 지붕모듈선택 -.roof-module-tab{ - display: flex; - align-items: center; - gap: 10px; - margin-bottom: 14px; - .module-tab-bx{ - flex: 1; - height: 34px; - line-height: 31px; - border: 1px solid #484848; - border-radius: 2px; - background-color: transparent; - font-size: 12px; - color: #AAA; - text-align: center; - cursor: default; - transition: all .15s ease-in-out; - &.act{ - background-color: #1083E3; - border: 1px solid #1083E3; - color: #fff; - font-weight: 500; - } - } - .tab-arr{ - display: block; - width: 9px; - height: 14px; - background-repeat: no-repeat; - background-position: center; - background-size: cover; - background-image: url(../../public/static/images/canvas/module_tab_arr.svg); - transition: all .15s ease-in-out; - &.act{ - background-image: url(../../public/static/images/canvas/module_tab_arr_white.svg); - } - } -} - -.roof-module-compas{ - margin-bottom: 24px; - .compas-box-inner{ - width: 280px; - height: 253px; - .circle{ - top: 86%; - // &:nth-child(1), - // &:nth-child(7), - // &:nth-child(13), - // &:nth-child(19){ - // &::before{ - // content: ''; - // position: absolute; - // top: 20px; - // left: 50%; - // transform: translateX(-50%); - // width: 1px; - // height: 6px; - // background-color: #8B8B8B; - // } - // } - i{ - top: 22px; - } - &.act{ - i{color: #8B8B8B;} - } - } - } -} -.center-wrap{ - display: flex; - flex-direction: column; - align-items: center; - gap: 20px; -} - -.module-table-flex-wrap{ - display: flex; - gap: 10px; - .outline-form{ - flex: 1; - } -} - -.module-box-tab{ - display: flex; - .module-btn{ - flex: 1; - border-top: 1px solid #505050; - border-bottom: 1px solid #505050; - border-right: 1px solid #505050; - background-color: #454545; - color: #fff; - height: 30px; - font-size: 12px; - font-weight: 400; - transition: all .15s ease-in-out; - &:first-child{ - border-left: 1px solid #505050; - } - &.act{ - border-color: #fff; - background-color: #fff; - color: #101010; - } - } -} - -.module-table-box{ - flex: 1; - background-color: #3D3D3D; - border-radius: 2px; - .module-table-inner{ - padding: 10px; - .outline-form{ - span{ - width: auto; - } - } - .module-table-tit{ - padding: 10px 0; - font-size: 12px; - color: #fff; - border-bottom: 1px solid #4D4D4D; - } - .eaves-keraba-table{ - width: 100%; - margin-top: 15px; - .eaves-keraba-th{ - width: 72px; - } - .eaves-keraba-th, - .eaves-keraba-td{ - padding-bottom: 5px; - } - } - .self-table-tit{ - font-size: 12px; - font-weight: 500; - color: #fff; - padding-bottom: 15px; - } - } - .warning-guide{ - padding: 20px; - .warning{ - color: #FFCACA; - max-height: 55px; - overflow-y: auto; - padding-right: 30px; - &::-webkit-scrollbar { - width: 4px; - background-color: transparent; - } - &::-webkit-scrollbar-thumb { - background-color: #D9D9D9; - } - &::-webkit-scrollbar-track { - background-color: transparent; - } - } - } -} - -.module-self-table{ - display: table; - border-top: 1px solid #4D4D4D; - border-collapse: collapse; - width: 100%; - .self-table-item{ - display: table-row; - .self-item-td, - .self-item-th{ - display: table-cell; - vertical-align: middle; - border-bottom: 1px solid #4D4D4D; - } - .self-item-th{ - width: 60px; - font-size: 12px; - font-weight: 500; - color: #fff; - } - .self-item-td{ - font-size: 12px; - font-weight: 400; - color: #fff; - padding: 15px 20px; - } - } -} - -.self-table-flx{ - display: flex; - align-items: center; - margin-top: 15px; - button{ - margin-left: auto; - } -} -.hexagonal-wrap{ - .hexagonal-item{ - padding: 15px 0; - border-bottom: 1px solid #4D4D4D; - &:first-child{ - padding-top: 0; - } - &:last-child{ - padding-bottom: 0; - border: none; - } - .hexagonal-flx-auto{ - display: flex; - justify-content: space-between; - } - .hexagonal-flx{ - display: flex; - align-items: center; - button{ - margin-left: auto; - } - } - } -} - -// 회로 및 가대설정 -.circuit-check-inner{ - padding: 5px 0; - &.overflow{ - overflow-y: auto; - max-height: 100px; - min-height: 60px; - &::-webkit-scrollbar { - width: 4px; - background-color: transparent; - } - &::-webkit-scrollbar-thumb { - background-color: #D9D9D9; - } - &::-webkit-scrollbar-track { - background-color: transparent; - } - } - .d-check-box{ - margin-bottom: 15px; - &:last-child{ - margin-bottom: 0; - } - } -} - -.x-scroll-table{ - overflow: auto; - padding-bottom: 5px; - background-color: transparent; - max-height: 170px; - .roof-module-table{ - min-width: 1200px; - } - &::-webkit-scrollbar { - width: 4px; - height: 4px; - background-color: transparent; - } - &::-webkit-scrollbar-thumb { - background-color: #b4b4b4; - } - &::-webkit-scrollbar-track { - background-color: transparent; - } - &::-webkit-scrollbar-corner{ - background-color: transparent; - } -} - -.circuit-right-wrap{ - display: flex; - justify-content: flex-end; -} - -.circuit-data-form{ - display: flex; - flex-direction: column; - gap: 5px; - min-height: 60px; - padding: 12px; - border: 1px solid rgba(255, 255, 255, 0.20); - span{ - display: inline-flex; - align-items: center; - .del{ - display: block; - margin-left: 10px; - width: 15px; - height: 15px; - background: url(../../public/static/images/canvas/circuit_del.svg)no-repeat center; - background-size: cover; - } - } -} -.circuit-table-tit{ - color: #fff; - font-size: 12px; - font-weight: 600; - padding: 11px 10px; - background-color: #474747; - border: 1px solid #505050; - border-bottom: none; -} - -.circuit-overflow{ - overflow-x: auto; - &::-webkit-scrollbar { - height: 4px; - background-color: transparent; - } - &::-webkit-scrollbar-thumb { - background-color: #D9D9D9; - } - &::-webkit-scrollbar-track { - background-color: transparent; - } - .module-table-box{ - display: flex; - &.by-max{ - min-width: 886px; - } - } -} -.circuit-title-sel{ - padding-bottom: 14px; - .outline-form{ - span{ - color: #62C207; - } - .grid-select{ - .sort-select{ - border: 1px solid #4E9E04; - background-color: #1A3104; - p{ - line-height: 27px; - } - .select-item-wrap{ - background-color: #1A3104; - border: 1px solid #4E9E04; - .select-item:hover{ - background-color: #294e07; - } - &::-webkit-scrollbar { - width: 2px; - background-color: transparent; - - } - &::-webkit-scrollbar-thumb { - background-color: #fff; - border-radius: 10px; - } - &::-webkit-scrollbar-track { - background-color: transparent; - } + .shape-data { + flex: 1; + .eaves-keraba-table { + .eaves-keraba-item { + .eaves-keraba-th, + .eaves-keraba-td { + padding-bottom: 10px; + } + &:last-child { + .eaves-keraba-th, + .eaves-keraba-td { + padding-bottom: 0px; } + } } - } + } + } + } } -} - -.circuit-table-flx-wrap{ - display: flex; - gap: 10px; - margin-bottom: 10px; - .circuit-table-flx-box{ + &.direction-box { + flex: 1; + display: flex; + flex-direction: column; + .plane-direction-box { flex: 1; - display: flex; - flex-direction: column; - .bottom-wrap{ - margin-top: auto; - } - .roof-module-table{ - table{ - table-layout: fixed; - } - } - } -} - -.circuit-count-input{ - display: flex; - align-items: center; - gap: 10px; -} - -// 모듈부가기능 -.additional-radio-wrap{ - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 15px 0; - margin-bottom: 24px; -} -.additional-wrap{ - padding: 24px 0; - border-top: 1px solid #424242; -} - -.additional-color-wrap{ - display: flex; - align-items: center; - padding: 5px 0; - gap: 15px; - .additional-color-box{ - display: flex; - align-items: center; - gap: 8px; - .additional-color{ - display: block; - width: 16px; - height: 16px; - &.pink{ - border: 2px solid #ce1c9c; - background-color: #16417D; - } - &.white{ - border: 2px solid #FFF; - background-color: #001027; - } - } - } -} - -// color setting -.color-setting-wrap{ - padding-bottom: 15px; - border-bottom: 1px solid #424242; - .color-tit{ - font-size: 13px; - font-weight: 500; - color: #ffffff; - margin-bottom: 10px; - } - .color-picker{ - .react-colorful{ - width: 100%; - height: auto; - gap: 20px; - .react-colorful__pointer{ - width: 15px; - height: 15px; - border: 4px solid #Fff; - } - .react-colorful__saturation{ - border-radius: 2px; - height: 200px; - border-bottom: 5px solid #000; - } - .react-colorful__last-control{ - border-radius: 2px; - height: 10px; - } - } - .hex-color-box{ - display: flex; - align-items: center; - margin-top: 15px; - .color-box-tit{ - font-size: 12px; - color: #fff; - font-weight: 500; - margin-right: 10px; - } - .color-hex-input{ - width: 150px; - margin-right: 5px; - input{ - width: 100%; - } - } - .color-box{ - display: block; - width: 30px; - height: 30px; - border-radius: 4px; - } - } - .default-color-wrap{ - margin-top: 25px; - .default-tit{ - font-size: 12px; - font-weight: 500; - color: #fff; - margin-bottom: 10px; - } - .color-button-wrap{ - display: grid; - grid-template-columns: repeat(8, 1fr); - gap: 21px; - .default-color{ - display: block; - width: 100%; - height: 30px; - border-radius: 4px; - } - } - } - } -} - -// 글꼴 설정 팝업 -.font-option-warp{ - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 15px 5px; - margin-bottom: 15px; - .font-option-item{ - .option-item-tit{ - font-size: 12px; - font-weight: 500; - color: #fff; - margin-bottom: 10px; - } - } -} -.font-ex-wrap{ - margin-bottom: 15px; - .font-ex-tit{ - font-size: 12px; - font-weight: 500; - color: #fff; - margin-bottom: 10px; - } - .font-ex-box{ display: flex; align-items: center; justify-content: center; width: 100%; - min-height: 80px; - background-color: #fff; + } } - + } } - -// 치수선 설정 -.font-btn-wrap{ - margin-bottom: 15px; - button{ - width: 100%; - height: 30px; - line-height: 28px; +.plane-direction { + width: 150px; + position: relative; + height: 120px; + span { + position: absolute; + font-size: 12px; + font-weight: 500; + color: #b1b1b1; + &.top { + top: 0; + left: 50%; + transform: translateX(-50%); } -} - -.line-color-wrap{ - margin-bottom: 15px; - .color-btn{ - display: block; - width: 100%; - height: 30px; - border-radius: 2px; + &.right { + top: 50%; + right: 0; + transform: translateY(-50%); } -} - -.form-box{ - width: 100%; - background-color: #fff; - padding: 10px 15px 20px; - .line-form{ - position: relative; - display: flex; - flex-direction: column; - justify-content: flex-end; - min-width: 102px; - min-height: 40px; - margin: 0 auto; - - &::before{ - content: ''; - position: absolute; - bottom: 0px; - left: 0; - width: 100%; - height: 40px; - border-left: 1px dashed #101010; - border-right: 1px dashed #101010; - } - .line-font-box{ - .font{ - display: block; - padding-bottom: 15px; - color: #101010; - text-align: center; - line-height: 1; - } - .line{ - position: relative; - display: block; - width: 100%; - height: 1px; - border-radius: 30px; - &::before{ - content: ''; - position: absolute; - top: 50%; - transform: translateY(-50%) rotate(45deg); - left: 1px; - width: 9px; - height:+ 9px; - border: 1px solid; - border-color: inherit; - border-top: none; - border-right: none; - } - &::after{ - content: ''; - position: absolute; - top: 50%; - transform: translateY(-50%) rotate(45deg); - right: 1px; - width: 9px; - height: 9px; - border: 1px solid; - border-color: inherit; - border-bottom: none; - border-left: none; - } - } - } + &.bottom { + bottom: 0; + left: 50%; + transform: translateX(-50%); } + &.left { + top: 50%; + left: 0; + transform: translateY(-50%); + } + } + .plane-btn { + position: absolute; + width: 28px; + height: 28px; + background-color: #777777; + background-image: url(../../public/static/images/canvas/plane_arr.svg); + background-size: 12px 13px; + background-repeat: no-repeat; + background-position: center; + border-radius: 50%; + transition: all 0.15s ease-in-out; + &.up { + top: 22px; + left: 50%; + transform: translateX(-50%); + } + &.right { + top: 50%; + right: 32px; + transform: translateY(-50%) rotate(90deg); + } + &.down { + bottom: 22px; + left: 50%; + transform: translateX(-50%) rotate(180deg); + } + &.left { + top: 50%; + left: 32px; + transform: translateY(-50%) rotate(270deg); + } + &:hover, + &.act { + background-color: #fff; + background-image: url(../../public/static/images/canvas/plane_arr_act.svg); + } + } } -// 사이즈 변경 -.size-inner-warp{ - position: relative; +.plane-tab-guide { + font-size: $pop-normal-size; + font-weight: $pop-normal-weight; + color: $pop-color; + margin-top: 10px; } -.size-check-wrap{ - position: relative; +.plane-shape-btn { + padding-top: 10px; + margin-top: auto; + button { display: block; - width: 132px; - height: 132px; - margin: 0 auto; - .size-btn{ - position: absolute; - width: 16px; - height: 16px; - border: 1px solid #fff; - border-radius: 50%; - &.act{ - &::after{ - content: ''; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - width: 8px; - height: 8px; - background-color: #fff; - border-radius: 50%; - } - } - &:nth-child(1){ top: 0; left: 0; } - &:nth-child(2){ top: 0; right: 0; } - &:nth-child(3){ bottom: 0; left: 0; } - &:nth-child(4){ bottom: 0; right: 0; } + width: 100%; + } +} + +// 오브젝트 배치 +.mb-box { + margin-bottom: 24px; +} + +.object-direction-wrap { + display: flex; + align-items: center; + justify-content: center; +} +.discrimination-tit { + font-size: 13px; + color: #fff; + font-weight: 500; +} + +.object-size-wrap { + display: flex; + min-height: 206px; + margin-top: 14px; + .object-size-img { + position: relative; + flex: none; + width: 200px; + background-color: #fff; + img { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); } - .size-box{ + } + .object-size-input { + margin-left: auto; + .eaves-keraba-th { + position: relative; + .object-input-num { + position: absolute; + top: 7px; + left: -20px; + font-size: 13px; + } + } + } +} + +// 표시변경 +.display-change-wrap { + margin: 24px 0; +} +.warning { + font-size: $pop-normal-size; + font-weight: $pop-normal-weight; + color: #ffafaf; +} + +// 각 변 속성 변경 +.radio-grid-wrap { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 24px 15px; +} + +// 면 흐름 설정 +.drawing-flow-wrap { + display: flex; + gap: 10px; + .discrimination-box { + flex: 1; + display: flex; + flex-direction: column; + .object-direction-wrap { + flex: 1; + } + &:first-child { + flex: none; + width: 195px; + } + } +} + +.compas-box { + display: flex; + align-items: center; + justify-content: center; +} +.compas-box-inner { + position: relative; + width: 200px; + height: 200px; + border-radius: 50%; + + .circle { + position: absolute; + width: 12px; + height: 12px; + border: 1px solid #fff; + border-radius: 50%; + top: 95%; + left: 50%; + transform-origin: 0 -90px; /* 중심에서 반지름 거리만큼 떨어져 위치 */ + cursor: pointer; + z-index: 3; + /* 0번을 180도 위치(아래)에, 13번을 0도 위치(위)에 배치 */ + i { + position: absolute; + top: 12.5px; + left: 50%; + font-size: 11px; + color: #8b8b8b; + font-weight: 500; + -webkit-user-select: none; + -moz-user-select: none; + -ms-use-select: none; + user-select: none; + } + &:nth-child(1) { + transform: rotate(180deg) translate(-50%, -50%); + i { + transform: translateX(-50%) rotate(180deg); + } + } + &:nth-child(2) { + transform: rotate(195deg) translate(-50%, -50%); + i { + transform: translateX(-50%) rotate(165deg); + } + } + &:nth-child(3) { + transform: rotate(210deg) translate(-50%, -50%); + i { + transform: translateX(-50%) rotate(150deg); + } + } + &:nth-child(4) { + transform: rotate(225deg) translate(-50%, -50%); + i { + transform: translateX(-50%) rotate(135deg); + } + } + &:nth-child(5) { + transform: rotate(240deg) translate(-50%, -50%); + i { + transform: translateX(-50%) rotate(120deg); + } + } + &:nth-child(6) { + transform: rotate(255deg) translate(-50%, -50%); + i { + transform: translateX(-50%) rotate(105deg); + } + } + &:nth-child(7) { + transform: rotate(270deg) translate(-50%, -50%); + i { + transform: translateX(-50%) rotate(90deg); + } + } + &:nth-child(8) { + transform: rotate(285deg) translate(-50%, -50%); + i { + transform: translateX(-50%) rotate(75deg); + } + } + &:nth-child(9) { + transform: rotate(300deg) translate(-50%, -50%); + i { + transform: translateX(-50%) rotate(60deg); + } + } + &:nth-child(10) { + transform: rotate(315deg) translate(-50%, -50%); + i { + transform: translateX(-50%) rotate(45deg); + } + } + &:nth-child(11) { + transform: rotate(330deg) translate(-50%, -50%); + i { + transform: translateX(-50%) rotate(30deg); + } + } + &:nth-child(12) { + transform: rotate(345deg) translate(-50%, -50%); + i { + transform: translateX(-50%) rotate(15deg); + } + } + &:nth-child(13) { + transform: rotate(0deg) translate(-50%, -50%); + i { + transform: translateX(-50%) rotate(0deg); + } + } + &:nth-child(14) { + transform: rotate(15deg) translate(-50%, -50%); + i { + transform: translateX(-50%) rotate(-15deg); + } + } + &:nth-child(15) { + transform: rotate(30deg) translate(-50%, -50%); + i { + transform: translateX(-50%) rotate(-30deg); + } + } + &:nth-child(16) { + transform: rotate(45deg) translate(-50%, -50%); + i { + transform: translateX(-50%) rotate(-45deg); + } + } + &:nth-child(17) { + transform: rotate(60deg) translate(-50%, -50%); + i { + transform: translateX(-50%) rotate(-60deg); + } + } + &:nth-child(18) { + transform: rotate(75deg) translate(-50%, -50%); + i { + transform: translateX(-50%) rotate(-75deg); + } + } + &:nth-child(19) { + transform: rotate(90deg) translate(-50%, -50%); + i { + transform: translateX(-50%) rotate(-90deg); + } + } + &:nth-child(20) { + transform: rotate(105deg) translate(-50%, -50%); + i { + transform: translateX(-50%) rotate(-105deg); + } + } + &:nth-child(21) { + transform: rotate(120deg) translate(-50%, -50%); + i { + transform: translateX(-50%) rotate(-120deg); + } + } + &:nth-child(22) { + transform: rotate(135deg) translate(-50%, -50%); + i { + transform: translateX(-50%) rotate(-135deg); + } + } + &:nth-child(23) { + transform: rotate(150deg) translate(-50%, -50%); + i { + transform: translateX(-50%) rotate(-150deg); + } + } + &:nth-child(24) { + transform: rotate(165deg) translate(-50%, -50%); + i { + transform: translateX(-50%) rotate(-165deg); + } + } + &.act { + &::after { + content: ''; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); - width: 100px; - height: 100px; + width: 5px; + height: 5px; background-color: #fff; + border-radius: 50%; + } + i { + color: #fff; + } } -} - -.size-option-top{ - margin-bottom: 15px; -} -.size-option-side{ + } + .compas { position: absolute; top: 50%; - left: 0; - transform: translateY(-50%); -} -.size-option-wrap{ - width: 88px; - margin: 0 auto; - .size-option{ - display: flex; - align-items: center; - input{ - width: 100%; - flex: 1; - } - span{ - flex: none; - } + left: 50%; + transform: translate(-50%, -50%); + width: 148px; + height: 148px; + border: 4px solid #fff; + border-radius: 50%; + .compas-arr { + width: 100%; + height: 100%; + background: url(../../public/static/images/canvas/compas.svg) no-repeat center; + background-size: 122px 122px; } + } +} + +.draw-flow-wrap { + margin: 10px 0; +} + +// 지붕모듈선택 +.roof-module-tab { + display: flex; + align-items: center; + gap: 10px; + margin-bottom: 14px; + .module-tab-bx { + flex: 1; + height: 34px; + line-height: 31px; + border: 1px solid #484848; + border-radius: 2px; + background-color: transparent; + font-size: 12px; + color: #aaa; + text-align: center; + cursor: default; + transition: all 0.15s ease-in-out; + &.act { + background-color: #1083e3; + border: 1px solid #1083e3; + color: #fff; + font-weight: 500; + } + } + .tab-arr { + display: block; + width: 9px; + height: 14px; + background-repeat: no-repeat; + background-position: center; + background-size: cover; + background-image: url(../../public/static/images/canvas/module_tab_arr.svg); + transition: all 0.15s ease-in-out; + &.act { + background-image: url(../../public/static/images/canvas/module_tab_arr_white.svg); + } + } +} + +.roof-module-compas { + margin-bottom: 24px; + .compas-box-inner { + width: 280px; + height: 253px; + .circle { + top: 86%; + // &:nth-child(1), + // &:nth-child(7), + // &:nth-child(13), + // &:nth-child(19){ + // &::before{ + // content: ''; + // position: absolute; + // top: 20px; + // left: 50%; + // transform: translateX(-50%); + // width: 1px; + // height: 6px; + // background-color: #8B8B8B; + // } + // } + i { + top: 22px; + } + &.act { + i { + color: #8b8b8b; + } + } + } + } +} +.center-wrap { + display: flex; + flex-direction: column; + align-items: center; + gap: 20px; +} + +.module-table-flex-wrap { + display: flex; + gap: 10px; + .outline-form { + flex: 1; + } +} + +.module-box-tab { + display: flex; + .module-btn { + flex: 1; + border-top: 1px solid #505050; + border-bottom: 1px solid #505050; + border-right: 1px solid #505050; + background-color: #454545; + color: #fff; + height: 30px; + font-size: 12px; + font-weight: 400; + transition: all 0.15s ease-in-out; + &:first-child { + border-left: 1px solid #505050; + } + &.act { + border-color: #fff; + background-color: #fff; + color: #101010; + } + } +} + +.module-table-box { + flex: 1; + background-color: #3d3d3d; + border-radius: 2px; + .module-table-inner { + padding: 10px; + .outline-form { + span { + width: auto; + } + } + .module-table-tit { + padding: 10px 0; + font-size: 12px; + color: #fff; + border-bottom: 1px solid #4d4d4d; + } + .eaves-keraba-table { + width: 100%; + margin-top: 15px; + .eaves-keraba-th { + width: 72px; + } + .eaves-keraba-th, + .eaves-keraba-td { + padding-bottom: 5px; + } + } + .self-table-tit { + font-size: 12px; + font-weight: 500; + color: #fff; + padding-bottom: 15px; + } + } + .warning-guide { + padding: 20px; + .warning { + color: #ffcaca; + max-height: 55px; + overflow-y: auto; + padding-right: 30px; + &::-webkit-scrollbar { + width: 4px; + background-color: transparent; + } + &::-webkit-scrollbar-thumb { + background-color: #d9d9d9; + } + &::-webkit-scrollbar-track { + background-color: transparent; + } + } + } +} + +.module-self-table { + display: table; + border-top: 1px solid #4d4d4d; + border-collapse: collapse; + width: 100%; + .self-table-item { + display: table-row; + .self-item-td, + .self-item-th { + display: table-cell; + vertical-align: middle; + border-bottom: 1px solid #4d4d4d; + } + .self-item-th { + width: 60px; + font-size: 12px; + font-weight: 500; + color: #fff; + } + .self-item-td { + font-size: 12px; + font-weight: 400; + color: #fff; + padding: 15px 20px; + } + } +} + +.self-table-flx { + display: flex; + align-items: center; + margin-top: 15px; + button { + margin-left: auto; + } +} +.hexagonal-wrap { + .hexagonal-item { + padding: 15px 0; + border-bottom: 1px solid #4d4d4d; + &:first-child { + padding-top: 0; + } + &:last-child { + padding-bottom: 0; + border: none; + } + .hexagonal-flx-auto { + display: flex; + justify-content: space-between; + } + .hexagonal-flx { + display: flex; + align-items: center; + button { + margin-left: auto; + } + } + } +} + +// 회로 및 가대설정 +.circuit-check-inner { + padding: 5px 0; + &.overflow { + overflow-y: auto; + max-height: 100px; + min-height: 60px; + &::-webkit-scrollbar { + width: 4px; + background-color: transparent; + } + &::-webkit-scrollbar-thumb { + background-color: #d9d9d9; + } + &::-webkit-scrollbar-track { + background-color: transparent; + } + } + .d-check-box { + margin-bottom: 15px; + &:last-child { + margin-bottom: 0; + } + } +} + +.x-scroll-table { + overflow: auto; + padding-bottom: 5px; + background-color: transparent; + max-height: 170px; + .roof-module-table { + min-width: 1200px; + } + &::-webkit-scrollbar { + width: 4px; + height: 4px; + background-color: transparent; + } + &::-webkit-scrollbar-thumb { + background-color: #b4b4b4; + } + &::-webkit-scrollbar-track { + background-color: transparent; + } + &::-webkit-scrollbar-corner { + background-color: transparent; + } +} + +.circuit-right-wrap { + display: flex; + justify-content: flex-end; +} + +.circuit-data-form { + display: flex; + flex-direction: column; + gap: 5px; + min-height: 60px; + padding: 12px; + border: 1px solid rgba(255, 255, 255, 0.2); + span { + display: inline-flex; + align-items: center; + .del { + display: block; + margin-left: 10px; + width: 15px; + height: 15px; + background: url(../../public/static/images/canvas/circuit_del.svg) no-repeat center; + background-size: cover; + } + } +} +.circuit-table-tit { + color: #fff; + font-size: 12px; + font-weight: 600; + padding: 11px 10px; + background-color: #474747; + border: 1px solid #505050; + border-bottom: none; +} + +.circuit-overflow { + overflow-x: auto; + &::-webkit-scrollbar { + height: 4px; + background-color: transparent; + } + &::-webkit-scrollbar-thumb { + background-color: #d9d9d9; + } + &::-webkit-scrollbar-track { + background-color: transparent; + } + .module-table-box { + display: flex; + &.by-max { + min-width: 886px; + } + } +} +.circuit-title-sel { + padding-bottom: 14px; + .outline-form { + span { + color: #62c207; + } + .grid-select { + .sort-select { + border: 1px solid #4e9e04; + background-color: #1a3104; + p { + line-height: 27px; + } + .select-item-wrap { + background-color: #1a3104; + border: 1px solid #4e9e04; + .select-item:hover { + background-color: #294e07; + } + &::-webkit-scrollbar { + width: 2px; + background-color: transparent; + } + &::-webkit-scrollbar-thumb { + background-color: #fff; + border-radius: 10px; + } + &::-webkit-scrollbar-track { + background-color: transparent; + } + } + } + } + } +} + +.circuit-table-flx-wrap { + display: flex; + gap: 10px; + margin-bottom: 10px; + .circuit-table-flx-box { + flex: 1; + display: flex; + flex-direction: column; + .bottom-wrap { + margin-top: auto; + } + .roof-module-table { + table { + table-layout: fixed; + } + } + } +} + +.circuit-count-input { + display: flex; + align-items: center; + gap: 10px; +} + +// 모듈부가기능 +.additional-radio-wrap { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 15px 0; + margin-bottom: 24px; +} +.additional-wrap { + padding: 24px 0; + border-top: 1px solid #424242; +} + +.additional-color-wrap { + display: flex; + align-items: center; + padding: 5px 0; + gap: 15px; + .additional-color-box { + display: flex; + align-items: center; + gap: 8px; + .additional-color { + display: block; + width: 16px; + height: 16px; + &.pink { + border: 2px solid #ce1c9c; + background-color: #16417d; + } + &.white { + border: 2px solid #fff; + background-color: #001027; + } + } + } +} + +// color setting +.color-setting-wrap { + padding-bottom: 15px; + border-bottom: 1px solid #424242; + .color-tit { + font-size: 13px; + font-weight: 500; + color: #ffffff; + margin-bottom: 10px; + } + .color-picker { + .react-colorful { + width: 100%; + height: auto; + gap: 20px; + .react-colorful__pointer { + width: 15px; + height: 15px; + border: 4px solid #fff; + } + .react-colorful__saturation { + border-radius: 2px; + height: 200px; + border-bottom: 5px solid #000; + } + .react-colorful__last-control { + border-radius: 2px; + height: 10px; + } + } + .hex-color-box { + display: flex; + align-items: center; + margin-top: 15px; + .color-box-tit { + font-size: 12px; + color: #fff; + font-weight: 500; + margin-right: 10px; + } + .color-hex-input { + width: 150px; + margin-right: 5px; + input { + width: 100%; + } + } + .color-box { + display: block; + width: 30px; + height: 30px; + border-radius: 4px; + } + } + .default-color-wrap { + margin-top: 25px; + .default-tit { + font-size: 12px; + font-weight: 500; + color: #fff; + margin-bottom: 10px; + } + .color-button-wrap { + display: grid; + grid-template-columns: repeat(8, 1fr); + gap: 21px; + .default-color { + display: block; + width: 100%; + height: 30px; + border-radius: 4px; + } + } + } + } +} + +// 글꼴 설정 팝업 +.font-option-warp { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 15px 5px; + margin-bottom: 15px; + .font-option-item { + .option-item-tit { + font-size: 12px; + font-weight: 500; + color: #fff; + margin-bottom: 10px; + } + } +} +.font-ex-wrap { + margin-bottom: 15px; + .font-ex-tit { + font-size: 12px; + font-weight: 500; + color: #fff; + margin-bottom: 10px; + } + .font-ex-box { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + min-height: 80px; + background-color: #fff; + } +} + +// 치수선 설정 +.font-btn-wrap { + margin-bottom: 15px; + button { + width: 100%; + height: 30px; + line-height: 28px; + } +} + +.line-color-wrap { + margin-bottom: 15px; + .color-btn { + display: block; + width: 100%; + height: 30px; + border-radius: 2px; + } +} + +.form-box { + width: 100%; + background-color: #fff; + padding: 10px 15px 20px; + .line-form { + position: relative; + display: flex; + flex-direction: column; + justify-content: flex-end; + min-width: 102px; + min-height: 40px; + margin: 0 auto; + + &::before { + content: ''; + position: absolute; + bottom: 0px; + left: 0; + width: 100%; + height: 40px; + border-left: 1px dashed #101010; + border-right: 1px dashed #101010; + } + .line-font-box { + .font { + display: block; + padding-bottom: 15px; + color: #101010; + text-align: center; + line-height: 1; + } + .line { + position: relative; + display: block; + width: 100%; + height: 1px; + border-radius: 30px; + &::before { + content: ''; + position: absolute; + top: 50%; + transform: translateY(-50%) rotate(45deg); + left: 1px; + width: 9px; + height: +9px; + border: 1px solid; + border-color: inherit; + border-top: none; + border-right: none; + } + &::after { + content: ''; + position: absolute; + top: 50%; + transform: translateY(-50%) rotate(45deg); + right: 1px; + width: 9px; + height: 9px; + border: 1px solid; + border-color: inherit; + border-bottom: none; + border-left: none; + } + } + } + } +} + +// 사이즈 변경 +.size-inner-warp { + position: relative; +} +.size-check-wrap { + position: relative; + display: block; + width: 132px; + height: 132px; + margin: 0 auto; + .size-btn { + position: absolute; + width: 16px; + height: 16px; + border: 1px solid #fff; + border-radius: 50%; + &.act { + &::after { + content: ''; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 8px; + height: 8px; + background-color: #fff; + border-radius: 50%; + } + } + &:nth-child(1) { + top: 0; + left: 0; + } + &:nth-child(2) { + top: 0; + right: 0; + } + &:nth-child(3) { + bottom: 0; + left: 0; + } + &:nth-child(4) { + bottom: 0; + right: 0; + } + } + .size-box { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 100px; + height: 100px; + background-color: #fff; + } +} + +.size-option-top { + margin-bottom: 15px; +} +.size-option-side { + position: absolute; + top: 50%; + left: 0; + transform: translateY(-50%); +} +.size-option-wrap { + width: 88px; + margin: 0 auto; + .size-option { + display: flex; + align-items: center; + input { + width: 100%; + flex: 1; + } + span { + 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; - } +.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; + } } // 이미지 불러오기 -.img-flex-box{ - display: flex; - align-items: center; +.img-flex-box { + display: flex; + align-items: center; } -.img-load-from{ - margin-top: 20px; - .img-load-item{ - border-top: 1px solid #424242; - padding: 18px 0; - .d-check-radio{ - margin-bottom: 20px; - } +.img-load-from { + margin-top: 20px; + .img-load-item { + border-top: 1px solid #424242; + padding: 18px 0; + .d-check-radio { + margin-bottom: 20px; } - border-bottom: 1px solid #424242; + } + border-bottom: 1px solid #424242; } // 지붕모듈선택 변경 -.module-table-box{ - &.none-flex{ +.module-table-box { + &.none-flex { + flex: none; + width: 230px; + .outline-form { + .grid-select { flex: none; - width: 230px; - .outline-form{ - .grid-select{ - flex: none; - width: 95.77px; - } - .thin{ - margin-left: 0; - } - } + width: 95.77px; + } + .thin { + margin-left: 0; + } } + } } -.roof-module-tab2-overflow{ - max-height: 650px; - overflow-y: auto; - padding-bottom: 15px; - border-bottom: 1px solid #4D4D4D; - &::-webkit-scrollbar { - width: 4px; - background-color: transparent; - } - &::-webkit-scrollbar-thumb { - background-color: #D9D9D9; - } - &::-webkit-scrollbar-track { - background-color: transparent; - } +.roof-module-tab2-overflow { + max-height: 650px; + overflow-y: auto; + padding-bottom: 15px; + border-bottom: 1px solid #4d4d4d; + &::-webkit-scrollbar { + width: 4px; + background-color: transparent; + } + &::-webkit-scrollbar-thumb { + background-color: #d9d9d9; + } + &::-webkit-scrollbar-track { + background-color: transparent; + } } -.module-table-flex-wrap{ - &.tab2{ - margin-top: 10px; - gap: 15px; - +.module-table-flex-wrap { + &.tab2 { + margin-top: 10px; + gap: 15px; + } + .module-flex-item { + flex: 1; + .module-flex-item-tit { + font-size: 12px; + font-weight: 500; + color: #fff; + padding-bottom: 10px; + border-bottom: 1px solid #4d4d4d; } - .module-flex-item{ - flex: 1; - .module-flex-item-tit{ - font-size: 12px; - font-weight: 500; - color: #fff; - padding-bottom: 10px; - border-bottom: 1px solid #4D4D4D; - } - .flex-item-btn-wrap{ - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 8px; - margin-bottom: 24px; - } - &.non-flex{ - display: flex; - flex-direction: column; - justify-content: flex-start; - flex: none; - padding-top: 27.5px; - width: 260px; - } + .flex-item-btn-wrap { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 8px; + margin-bottom: 24px; } + &.non-flex { + display: flex; + flex-direction: column; + justify-content: flex-start; + flex: none; + padding-top: 27.5px; + width: 260px; + } + } } -.module-table-box{ - .module-table-inner{ - .module-table-flex-wrap{ - &.tab2{ - .eaves-keraba-table{ - .eaves-keraba-th{ - width: 90px; - } - .eaves-keraba-td{ - padding-left: 0; - padding-bottom: 5px; - } - } - } - } - } -} -.keraba-flex{ - display: flex; - align-items: center; - .grid-select{ - flex: none; - width: 110px; - } - .outline-form{ - justify-content: flex-end; +.module-table-box { + .module-table-inner { + .module-table-flex-wrap { + &.tab2 { + .eaves-keraba-table { + .eaves-keraba-th { + width: 90px; + } + .eaves-keraba-td { + padding-left: 0; + padding-bottom: 5px; + } + } + } } + } +} +.keraba-flex { + display: flex; + align-items: center; + .grid-select { + flex: none; + width: 110px; + } + .outline-form { + justify-content: flex-end; + } +} + +.pop-spinner { + position: absolute; + bottom: 10px; + left: 5px; + width: calc(100% - 10px); + height: calc(100% - 49px); + display: flex; + align-items: center; + justify-content: center; + background-color: rgba($color: #101010, $alpha: 0.5); + z-index: 2000000; + .loader { + font-size: 10px; + width: 1.2em; + height: 1.2em; + border-radius: 50%; + position: relative; + text-indent: -9999em; + animation: mulShdSpin 1.1s infinite ease; + transform: translateZ(0); + } + @keyframes mulShdSpin { + 0%, + 100% { + box-shadow: + 0em -2.6em 0em 0em #fff, + 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), + 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), + 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), + 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), + -1.8em 1.8em 0 0em rgba(0, 0, 0, 0.2), + -2.6em 0em 0 0em rgba(255, 255, 255, 0.5), + -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.7); + } + 12.5% { + box-shadow: + 0em -2.6em 0em 0em rgba(255, 255, 255, 0.7), + 1.8em -1.8em 0 0em #fff, + 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), + 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), + 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), + -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), + -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), + -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.5); + } + 25% { + box-shadow: + 0em -2.6em 0em 0em rgba(255, 255, 255, 0.5), + 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.7), + 2.5em 0em 0 0em #fff, + 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), + 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), + -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), + -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), + -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2); + } + 37.5% { + box-shadow: + 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), + 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.5), + 2.5em 0em 0 0em rgba(255, 255, 255, 0.7), + 1.75em 1.75em 0 0em #fff, + 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), + -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), + -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), + -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2); + } + 50% { + box-shadow: + 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), + 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), + 2.5em 0em 0 0em rgba(255, 255, 255, 0.5), + 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.7), + 0em 2.5em 0 0em #fff, + -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), + -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), + -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2); + } + 62.5% { + box-shadow: + 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), + 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), + 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), + 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.5), + 0em 2.5em 0 0em rgba(255, 255, 255, 0.7), + -1.8em 1.8em 0 0em #fff, + -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), + -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2); + } + 75% { + box-shadow: + 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), + 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), + 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), + 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), + 0em 2.5em 0 0em rgba(255, 255, 255, 0.5), + -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.7), + -2.6em 0em 0 0em #fff, + -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2); + } + 87.5% { + box-shadow: + 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), + 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), + 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), + 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), + 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), + -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.5), + -2.6em 0em 0 0em rgba(255, 255, 255, 0.7), + -1.8em -1.8em 0 0em #fff; + } + } } From f04f7570cc7d468cc586d0a8d5a5c03b611d42c6 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 13 Mar 2025 13:53:21 +0900 Subject: [PATCH 320/352] =?UTF-8?q?=EB=8F=99=EC=84=9C=EB=82=A8=EB=B6=81=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useTrestle.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index 50d11cb9..4f0bb116 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -1662,11 +1662,11 @@ export const useTrestle = () => { break } case 'west': { - startPointX += 5 + startPointX -= 5 break } case 'north': { - startPointY += 5 + startPointY -= 5 break } } @@ -1686,14 +1686,15 @@ export const useTrestle = () => { }) canvas.add(bracket) canvas.renderAll() + const maxIntvl = Math.max(moduleIntvlHor, moduleIntvlVer) if (direction === 'south') { - startPointY -= height + moduleIntvlVer / 10 + startPointY -= height + maxIntvl / 10 } else if (direction === 'north') { - startPointY += height + moduleIntvlVer / 10 + startPointY += height + maxIntvl / 10 } else if (direction === 'east') { - startPointX -= width - moduleIntvlHor / 10 + startPointX -= width + maxIntvl / 10 } else if (direction === 'west') { - startPointX += width + moduleIntvlHor / 10 + startPointX += width + maxIntvl / 10 } } } From 2dc590cbee570734fe4508f2eb28ae13981b4c89 Mon Sep 17 00:00:00 2001 From: basssy Date: Thu, 13 Mar 2025 14:45:14 +0900 Subject: [PATCH 321/352] =?UTF-8?q?#746=20=EA=B2=AC=EC=A0=81=EC=84=9C=20?= =?UTF-8?q?=EC=BC=80=EC=9D=B4=EB=B8=94=20=EC=A0=9C=ED=92=88=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 126 ++++++++++++++---- src/hooks/common/useCommonCode.js | 2 + .../estimate/useEstimateController.js | 1 + 3 files changed, 102 insertions(+), 27 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 3126f5bc..bd2c202a 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -58,6 +58,9 @@ export default function Estimate({}) { const [storePriceList, setStorePriceList] = useState([]) //가격표시 option + const [cableItemList, setCableItemList] = useState([]) //케이블 리스트 + const [cableItem, setCableItem] = useState('') //케이블 선택값 + const [startDate, setStartDate] = useState(new Date()) const singleDatePickerProps = { startDate, @@ -96,6 +99,7 @@ export default function Estimate({}) { const initEstimate = (currPid = currentPid) => { console.log('🚀 ~ initEstimate ~ currPid:', currPid) + setCableItem('') closeAll() setObjectNo(objectRecoil.floorPlanObjectNo) @@ -107,6 +111,16 @@ export default function Estimate({}) { setHonorificCodeList(code1) } + // 케이블제품 공통코드 + const code2 = findCommonCode(117900) + if (code2 != null) { + code2.map((item) => { + item.value = item.clRefChr1 + item.label = item.clRefChr2 + }) + setCableItemList(code2) + } + //아이템 자동완성 목록 가져오기 const param = { saleStoreId: session.storeId, @@ -551,7 +565,7 @@ export default function Estimate({}) { } const getAbledItems = (items) => { - return items.filter((items) => items.paDispOrder === null) + return items.filter((items) => items.dispCableFlg !== '1' && items.paDispOrder === null) } const onChangeSelectAll = (e) => { @@ -684,6 +698,22 @@ export default function Estimate({}) { setItemChangeYn(true) } + /* 케이블 select 변경시 */ + const onChangeDisplayCableItem = (value, itemList) => { + //todo: 추후 YJSS가 다시 나타날 경우 아래 swalFire 제거 필요 + if (estimateContextState.estimateType === 'YJSS') { + return swalFire({ text: getMessage('estimate.detail.save.requiredEstimateType'), type: 'alert', icon: 'warning' }) + } + itemList.map((item, index) => { + if (item.dispCableFlg === '1') { + if (value !== '') { + onChangeDisplayItem(value, item.dispOrder, index) + } + } + }) + setCableItem(value) + } + // 아이템 자동완성 검색시 아이템 추가/변경시 const onChangeDisplayItem = (itemId, dispOrder, index) => { //todo: 추후 YJSS가 다시 나타날 경우 아래 swalFire 제거 필요 @@ -1679,6 +1709,25 @@ export default function Estimate({}) { {getMessage('estimate.detail.showPrice.pricingBtn')}
    +
    +
    + +
    +
    • @@ -1758,7 +1807,7 @@ export default function Estimate({}) { onChangeSelect(item.dispOrder)} checked={!!selection.has(item.dispOrder)} /> @@ -1769,31 +1818,54 @@ export default function Estimate({}) {
      - { + if (isObjectNotEmpty(e)) { + onChangeDisplayItem(e.itemId, item.dispOrder, index) + } + }} + menuPlacement={'auto'} + getOptionLabel={(x) => x.itemName} + getOptionValue={(x) => x.itemNo} + isClearable={false} + isDisabled={!!item?.paDispOrder} + value={displayItemList.filter(function (option) { + if (item.itemNo === '') { + return false + } else { + return option.itemId === item.itemId + } + })} + /> + ) : ( + setFloorPlanState({ ...floorPlanState, toggleRotate: e.target.checked })} + /> + +
      -
      -
      -
      -
      - {getMessage('modal.image.load.size.rotate')} - -
      -
      -
      -
      - handleRefFileMethod(e)} checked={refFileMethod === '1'} /> - -
      -
      -
      - - handleRefFile(e.target.files[0]) : () => {}} - /> -
      -
      - - {refImage && } -
      -
      +
      +
      +
      + handleRefFileMethod(e)} checked={refFileMethod === '1'} /> +
      -
      -
      - handleRefFileMethod(e)} checked={refFileMethod === '2'} /> - +
      +
      + + handleRefFile(e.target.files[0]) : () => {}} + />
      -
      +
      setMapPositionAddress(e.target.value)} + className="input-origin al-l" + value={refImage ? (refImage?.name ?? '') : (currentCanvasPlan?.bgImageName ?? '')} + readOnly /> -
      - -
      - {mapPositionAddress && } - {/* */} + {refImage && }
      -
      - - {/* */} +
      +
      + handleRefFileMethod(e)} checked={refFileMethod === '2'} /> + +
      +
      + setMapPositionAddress(e.target.value)} + /> +
      + +
      + {mapPositionAddress && } + {/* */} +
      -
      -
      +
      + + {/* */} +
      + ) } diff --git a/src/components/floor-plan/modal/Slope.jsx b/src/components/floor-plan/modal/Slope.jsx index e867dcab..df4a25d7 100644 --- a/src/components/floor-plan/modal/Slope.jsx +++ b/src/components/floor-plan/modal/Slope.jsx @@ -13,42 +13,32 @@ export default function Slope({ id, pos = { x: 50, y: 230 } }) { const inputRef = useRef() return ( - -
      -
      -

      {getMessage('plan.menu.placement.surface.slope.setting')}

      -
      -
      -
      -
      -
      -
      - - {getMessage('slope')} - -
      - -
      - {pitchText} -
      -
      -
      - -
      -
      -
      -
      +
      ) } diff --git a/src/components/floor-plan/modal/auxiliary/AuxiliaryDrawing.jsx b/src/components/floor-plan/modal/auxiliary/AuxiliaryDrawing.jsx index 3a9d64d6..1417b501 100644 --- a/src/components/floor-plan/modal/auxiliary/AuxiliaryDrawing.jsx +++ b/src/components/floor-plan/modal/auxiliary/AuxiliaryDrawing.jsx @@ -124,46 +124,36 @@ export default function AuxiliaryDrawing({ id, pos = { x: 50, y: 230 } }) { setType(button.type) } return ( - -
      -
      -

      {getMessage('modal.auxiliary.drawing')}

      - + ))} +
      +
      +
      {getMessage('setting')}
      + {buttonAct === 1 && } + {buttonAct === 2 && } + {buttonAct === 3 && } + {buttonAct === 4 && } + {buttonAct === 5 && } +
      +
      + + +
      -
      -
      -
      -
      - {types.map((type, idx) => ( - - ))} -
      -
      -
      {getMessage('setting')}
      - {buttonAct === 1 && } - {buttonAct === 2 && } - {buttonAct === 3 && } - {buttonAct === 4 && } - {buttonAct === 5 && } -
      -
      - - - -
      -
      -
      -
      +
      ) } diff --git a/src/components/floor-plan/modal/auxiliary/AuxiliaryEdit.jsx b/src/components/floor-plan/modal/auxiliary/AuxiliaryEdit.jsx index c8e7b95a..744b3387 100644 --- a/src/components/floor-plan/modal/auxiliary/AuxiliaryEdit.jsx +++ b/src/components/floor-plan/modal/auxiliary/AuxiliaryEdit.jsx @@ -55,77 +55,67 @@ export default function AuxiliaryEdit(props) { closePopup(id) } return ( - -
      -
      -

      {getMessage(type === 'copy' ? 'modal.auxiliary.copy' : 'modal.auxiliary.move')}

      - -
      -
      -
      -
      -
      {getMessage(type === 'copy' ? 'modal.auxiliary.copy.info' : 'modal.auxiliary.move.info')}
      -
      -
      -
      -

      {getMessage('length')}

      -
      -
      - setVerticalSize(e.target.value)} /> -
      - mm -
      - - -
      + + closePopup(id)} /> + +
      {getMessage(type === 'copy' ? 'modal.auxiliary.copy.info' : 'modal.auxiliary.move.info')}
      +
      +
      +
      +

      {getMessage('length')}

      +
      +
      + setVerticalSize(e.target.value)} />
      -
      -
      - setHorizonSize(e.target.value)} /> -
      - mm -
      - - -
      + mm +
      + + +
      +
      +
      +
      + setHorizonSize(e.target.value)} /> +
      + mm +
      + +
      -
      - -
      -
      -
      +
      + +
      +
      ) } diff --git a/src/components/floor-plan/modal/auxiliary/AuxiliarySize.jsx b/src/components/floor-plan/modal/auxiliary/AuxiliarySize.jsx index a9f7fc82..3bb94a4f 100644 --- a/src/components/floor-plan/modal/auxiliary/AuxiliarySize.jsx +++ b/src/components/floor-plan/modal/auxiliary/AuxiliarySize.jsx @@ -111,63 +111,53 @@ export default function AuxiliarySize(props) { closePopup(id) } return ( - -
      -
      -

      {getMessage('modal.auxiliary.size.edit')}

      -
      -
      -
      -
      -
      -
      - setCheckedRadio(1)} /> - -
      -
      -
      - -
      - mm -
      -
      - {getMessage('length')} -
      - -
      - mm -
      -
      -
      -
      - setCheckedRadio(2)} /> - -
      -
      -
      - -
      - mm -
      -
      - {getMessage('length')} -
      - -
      - mm -
      -
      -
      - -
      -
      -
      -
      +
      ) } diff --git a/src/components/floor-plan/modal/basic/BasicSetting.jsx b/src/components/floor-plan/modal/basic/BasicSetting.jsx index 291ef086..ada6acba 100644 --- a/src/components/floor-plan/modal/basic/BasicSetting.jsx +++ b/src/components/floor-plan/modal/basic/BasicSetting.jsx @@ -135,76 +135,66 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) { }, [isManualModuleSetup, isClosePopup]) return ( - -
      -
      -

      {getMessage('plan.menu.module.circuit.setting.default')}

      - + + handleClosePopup(id)} /> + +
      +
      {getMessage('modal.module.basic.setting.orientation.setting')}
      + +
      {getMessage('modal.module.basic.setting.module.setting')}
      + +
      {getMessage('modal.module.basic.setting.module.placement')}
      -
      -
      -
      -
      -
      {getMessage('modal.module.basic.setting.orientation.setting')}
      - -
      {getMessage('modal.module.basic.setting.module.setting')}
      - -
      {getMessage('modal.module.basic.setting.module.placement')}
      -
      - {tabNum === 1 && } - {/*배치면 초기설정 - 입력방법: 복시도 입력 || 실측값 입력*/} - {basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && tabNum === 2 && } - {basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && tabNum === 3 && } + {tabNum === 1 && } + {/*배치면 초기설정 - 입력방법: 복시도 입력 || 실측값 입력*/} + {basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && tabNum === 2 && } + {basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && tabNum === 3 && } - {/*배치면 초기설정 - 입력방법: 육지붕*/} - {basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && tabNum === 2 && } - {basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && tabNum === 3 && ( - + {/*배치면 초기설정 - 입력방법: 육지붕*/} + {basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && tabNum === 2 && } + {basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && tabNum === 3 && ( + + )} + +
      + {tabNum !== 1 && ( + + )} + {/*{tabNum !== 3 && }*/} + {tabNum !== 3 && ( + )} -
      - {tabNum !== 1 && ( - - )} - {/*{tabNum !== 3 && }*/} - {tabNum !== 3 && ( - - )} - - {tabNum === 3 && ( - <> - {basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && ( - <> - - - - )} - {basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && ( - <> - - - - )} - - )} -
      + {tabNum === 3 && ( + <> + {basicSetting.roofSizeSet && basicSetting.roofSizeSet != '3' && ( + <> + + + + )} + {basicSetting.roofSizeSet && basicSetting.roofSizeSet == '3' && ( + <> + + + + )} + + )}
      -
      -
      +
      ) } diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index f9f97833..53461f77 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -612,64 +612,53 @@ export default function CircuitTrestleSetting({ id }) { } return ( - -
      -
      -

      {getMessage('modal.circuit.trestle.setting')}

      - {/* -
      -
      -
      -
      -
      -
      {getMessage('modal.circuit.trestle.setting.power.conditional.select')}
      - -
      - {getMessage('modal.circuit.trestle.setting.circuit.allocation')}({getMessage('modal.circuit.trestle.setting.step.up.allocation')}) -
      + + handleClose()} /> + +
      +
      {getMessage('modal.circuit.trestle.setting.power.conditional.select')}
      + +
      + {getMessage('modal.circuit.trestle.setting.circuit.allocation')}({getMessage('modal.circuit.trestle.setting.step.up.allocation')})
      - {tabNum === 1 && allocationType === ALLOCATION_TYPE.AUTO && } - {tabNum === 1 && allocationType === ALLOCATION_TYPE.PASSIVITY && ( - - )} - {tabNum === 2 && } - {tabNum === 1 && allocationType === ALLOCATION_TYPE.AUTO && ( -
      - - -
      - )} - {tabNum === 1 && allocationType === ALLOCATION_TYPE.PASSIVITY && ( -
      - - -
      - )} - {tabNum === 2 && ( -
      - - {/* -
      - )}
      -
      -
      + {tabNum === 1 && allocationType === ALLOCATION_TYPE.AUTO && } + {tabNum === 1 && allocationType === ALLOCATION_TYPE.PASSIVITY && ( + + )} + {tabNum === 2 && } + {tabNum === 1 && allocationType === ALLOCATION_TYPE.AUTO && ( +
      + + +
      + )} + {tabNum === 1 && allocationType === ALLOCATION_TYPE.PASSIVITY && ( +
      + + +
      + )} + {tabNum === 2 && ( +
      + + {/* +
      + )} + ) } diff --git a/src/components/floor-plan/modal/dimensionLine/DimensionLineSetting.jsx b/src/components/floor-plan/modal/dimensionLine/DimensionLineSetting.jsx index e4807c36..c2acc12d 100644 --- a/src/components/floor-plan/modal/dimensionLine/DimensionLineSetting.jsx +++ b/src/components/floor-plan/modal/dimensionLine/DimensionLineSetting.jsx @@ -122,95 +122,85 @@ export default function DimensionLineSetting(props) { } return ( - -
      -
      -

      {getMessage('contextmenu.display.edit')}

      -
      -
      -
      -
      -
      {getMessage('modal.display.edit.info')}
      -
      -
      -
      - {getMessage('modal.display.edit.before.length')} -
      - -
      -
      -
      -
      - {getMessage('modal.display.edit.after.length')} -
      - { - console.log(e.target) - setChangeLength(e.target.value) - }} - /> -
      -
      -
      -
      - setSlopeAble(!slopeAble)} /> - -
      -
      -
      -
      -
      {getMessage('modal.display.edit.input.slope')}
      -
      -
      - {getMessage('slope')} -
      - setSelectedSlope1(e)} - showKey={'name'} - sourceKey={'value'} - targetKey={'value'} - /> -
      - {pitchText} -
      -
      - {getMessage('slope')} -
      - setSelectedSlope2(e)} - showKey={'name'} - sourceKey={'value'} - targetKey={'value'} - /> -
      - {pitchText} -
      -
      -
      {getMessage('modal.display.edit.input.slope.info')}
      -
      -
      - -
      -
      -
      -
      +
      ) } diff --git a/src/components/floor-plan/modal/distance/Distance.jsx b/src/components/floor-plan/modal/distance/Distance.jsx index e9c175d3..8ec3aed2 100644 --- a/src/components/floor-plan/modal/distance/Distance.jsx +++ b/src/components/floor-plan/modal/distance/Distance.jsx @@ -16,62 +16,52 @@ export default function Distance(props) { } return ( - -
      -
      -

      {getMessage('modal.distance')}

      - -
      -
      -
      -
      -
      -
      -
      -
      {getMessage('modal.distance.dual.point')}
      -
      -
      -
      - -
      - mm + + closePopup(id)} /> + +
      +
      +
      +
      {getMessage('modal.distance.dual.point')}
      +
      +
      +
      +
      + mm
      -
      -
      {getMessage('modal.distance.horizon')}
      -
      -
      -
      - -
      - mm +
      +
      +
      {getMessage('modal.distance.horizon')}
      +
      +
      +
      +
      + mm
      -
      -
      {getMessage('modal.distance.vertical')}
      -
      -
      -
      - -
      - mm +
      +
      +
      {getMessage('modal.distance.vertical')}
      +
      +
      +
      +
      + mm
      -
      - -
      -
      -
      +
      + +
      + ) } diff --git a/src/components/floor-plan/modal/eavesGable/EavesGableEdit.jsx b/src/components/floor-plan/modal/eavesGable/EavesGableEdit.jsx index c3975543..a59f8f27 100644 --- a/src/components/floor-plan/modal/eavesGable/EavesGableEdit.jsx +++ b/src/components/floor-plan/modal/eavesGable/EavesGableEdit.jsx @@ -38,34 +38,24 @@ export default function EavesGableEdit({ id, pos = { x: 50, y: 230 } }) { } return ( - -
      -
      -

      {getMessage('modal.eaves.gable.edit')}

      - + + closePopup(id)} /> + +
      + {buttonMenu.map((item) => ( + + ))}
      -
      -
      -
      -
      - {buttonMenu.map((item) => ( - - ))} -
      -
      -
      {getMessage('setting')}
      - {type === TYPES.EAVES && } - {type === TYPES.GABLE && } - {type === TYPES.WALL_MERGE && } - {type === TYPES.SHED && } -
      +
      +
      {getMessage('setting')}
      + {type === TYPES.EAVES && } + {type === TYPES.GABLE && } + {type === TYPES.WALL_MERGE && } + {type === TYPES.SHED && }
      -
      -
      +
      ) } diff --git a/src/components/floor-plan/modal/flowDirection/FlowDirectionSetting.jsx b/src/components/floor-plan/modal/flowDirection/FlowDirectionSetting.jsx index df8525cc..910a2f02 100644 --- a/src/components/floor-plan/modal/flowDirection/FlowDirectionSetting.jsx +++ b/src/components/floor-plan/modal/flowDirection/FlowDirectionSetting.jsx @@ -63,123 +63,113 @@ export default function FlowDirectionSetting(props) { ) return ( - -
      -
      -

      {getMessage('modal.shape.flow.direction.setting')}

      - -
      -
      -
      -
      -
      -
      -
      {getMessage('modal.flow.direction.setting')}
      -
      {getMessage('modal.flow.direction.setting.info')}
      -
      -
      - {getMessage('commons.north')} - - {getMessage('commons.east')} - - {getMessage('commons.south')} - - {getMessage('commons.west')} - -
      + + closePopup(id)} /> + +
      +
      +
      {getMessage('modal.flow.direction.setting')}
      +
      {getMessage('modal.flow.direction.setting.info')}
      +
      +
      + {getMessage('commons.north')} + + {getMessage('commons.east')} + + {getMessage('commons.south')} + + {getMessage('commons.west')} +
      -
      -
      {getMessage('modal.module.basic.setting.orientation.setting')}
      -
      {getMessage('modal.shape.flow.direction.setting.orientation.setting.info')}
      -
      -
      - { - setCompasDeg(0) - setType(FLOW_DIRECTION_TYPE.EIGHT_AZIMUTH) - }} - /> - -
      -
      - { - setType(FLOW_DIRECTION_TYPE.EIGHT_AZIMUTH) - setSelectedOrientation(e) - setCompasDeg(e.value) - }} - showKey={'name'} - targetKey={'value'} - sourceKey={'value'} - /> -
      +
      +
      +
      {getMessage('modal.module.basic.setting.orientation.setting')}
      +
      {getMessage('modal.shape.flow.direction.setting.orientation.setting.info')}
      +
      +
      + { + setCompasDeg(0) + setType(FLOW_DIRECTION_TYPE.EIGHT_AZIMUTH) + }} + /> +
      -
      -
      - { - setType(FLOW_DIRECTION_TYPE.TWENTY_FOUR_AZIMUTH) - }} - /> - -
      +
      + { + setType(FLOW_DIRECTION_TYPE.EIGHT_AZIMUTH) + setSelectedOrientation(e) + setCompasDeg(e.value) + }} + showKey={'name'} + targetKey={'value'} + sourceKey={'value'} + />
      -
      -
      -
      - {Array.from({ length: 180 / 15 + 1 }).map((dot, index) => ( -
      { - setType(FLOW_DIRECTION_TYPE.TWENTY_FOUR_AZIMUTH) - setCompasDeg(15 * (12 + index)) - }} - >
      - ))} - {Array.from({ length: 180 / 15 - 1 }).map((dot, index) => ( -
      { - setType(FLOW_DIRECTION_TYPE.TWENTY_FOUR_AZIMUTH) - setCompasDeg(15 * (index + 1)) - }} - >
      - ))} -
      -
      -
      +
      +
      +
      + { + setType(FLOW_DIRECTION_TYPE.TWENTY_FOUR_AZIMUTH) + }} + /> + +
      +
      +
      +
      +
      + {Array.from({ length: 180 / 15 + 1 }).map((dot, index) => ( +
      { + setType(FLOW_DIRECTION_TYPE.TWENTY_FOUR_AZIMUTH) + setCompasDeg(15 * (12 + index)) + }} + >
      + ))} + {Array.from({ length: 180 / 15 - 1 }).map((dot, index) => ( +
      { + setType(FLOW_DIRECTION_TYPE.TWENTY_FOUR_AZIMUTH) + setCompasDeg(15 * (index + 1)) + }} + >
      + ))} +
      +
      -
      - -
      -
      -
      +
      + +
      + ) } diff --git a/src/components/floor-plan/modal/grid/DotLineGrid.jsx b/src/components/floor-plan/modal/grid/DotLineGrid.jsx index 853d27c1..d118188d 100644 --- a/src/components/floor-plan/modal/grid/DotLineGrid.jsx +++ b/src/components/floor-plan/modal/grid/DotLineGrid.jsx @@ -177,125 +177,115 @@ export default function DotLineGrid(props) { } return ( - -
      -
      -

      {getMessage('modal.canvas.setting.grid.dot.line.setting')}

      - +
      -
      -
      -
      -
      -
      - - -
      -
      - - -
      -
      -
      -
      -
      - - -
      -
      - {getMessage('modal.canvas.setting.grid.dot.line.setting.horizon')} -
      - onlyNumberInputChange(e, changeInput)} - /> -
      - mm -
      -
      - {getMessage('modal.canvas.setting.grid.dot.line.setting.vertical')} -
      - onlyNumberInputChange(e, changeInput)} - /> -
      - mm -
      -
      -
      -
      - - -
      -
      - {getMessage('modal.canvas.setting.grid.dot.line.setting.ratio')} -
      - onlyNumberInputChange(e, changeInput)} - /> -
      - mm -
      -
      - {selectOption && ( - - )} -
      -
      -
      -
      - - -
      -
      -
      -
      +
      ) } diff --git a/src/components/floor-plan/modal/grid/GridCopy.jsx b/src/components/floor-plan/modal/grid/GridCopy.jsx index fa0b0ba8..e1a6f9f9 100644 --- a/src/components/floor-plan/modal/grid/GridCopy.jsx +++ b/src/components/floor-plan/modal/grid/GridCopy.jsx @@ -20,67 +20,57 @@ export default function GridCopy(props) { copy(currentObject, ['↑', '←'].includes(arrow) ? +length * -1 : +length) } return ( - -
      -
      -

      {getMessage('modal.grid.copy')}

      - -
      -
      -
      -
      -
      {getMessage('modal.grid.copy.info')}
      -
      -
      -
      - {getMessage('modal.grid.copy.length')} -
      - setLength(e.target.value)} /> -
      - mm -
      -
      - - - - + + closePopup(id)} /> + +
      {getMessage('modal.grid.copy.info')}
      +
      +
      +
      + {getMessage('modal.grid.copy.length')} +
      + setLength(e.target.value)} />
      + mm +
      +
      + + + +
      -
      - -
      -
      -
      +
      + +
      + ) } diff --git a/src/components/floor-plan/modal/grid/GridMove.jsx b/src/components/floor-plan/modal/grid/GridMove.jsx index dbf15206..4aa27851 100644 --- a/src/components/floor-plan/modal/grid/GridMove.jsx +++ b/src/components/floor-plan/modal/grid/GridMove.jsx @@ -73,93 +73,83 @@ export default function GridMove(props) { closePopup(id) } return ( - -
      -
      -

      {getMessage('modal.grid.move')}

      - -
      -
      -
      -
      -
      {getMessage('modal.grid.move.info')}
      -
      -
      - setIsAll(!isAll)} /> - -
      -
      -
      -

      {getMessage('modal.grid.move.length')}

      -
      -
      - setVerticalSize(e.target.value)} - readOnly={!isAll && currentObject?.direction === 'vertical'} - /> -
      - mm -
      - - -
      + + handleClose()} /> + +
      {getMessage('modal.grid.move.info')}
      +
      +
      + setIsAll(!isAll)} /> + +
      +
      +
      +

      {getMessage('modal.grid.move.length')}

      +
      +
      + setVerticalSize(e.target.value)} + readOnly={!isAll && currentObject?.direction === 'vertical'} + />
      -
      -
      - setHorizonSize(e.target.value)} - readOnly={!isAll && currentObject?.direction === 'horizontal'} - /> -
      - mm -
      - - -
      + mm +
      + + +
      +
      +
      +
      + setHorizonSize(e.target.value)} + readOnly={!isAll && currentObject?.direction === 'horizontal'} + /> +
      + mm +
      + +
      -
      - -
      -
      -
      +
      + +
      +
      ) } diff --git a/src/components/floor-plan/modal/lineProperty/LinePropertySetting.jsx b/src/components/floor-plan/modal/lineProperty/LinePropertySetting.jsx index e309646a..049c2e40 100644 --- a/src/components/floor-plan/modal/lineProperty/LinePropertySetting.jsx +++ b/src/components/floor-plan/modal/lineProperty/LinePropertySetting.jsx @@ -50,51 +50,41 @@ export default function LinePropertySetting(props) { } return ( - -
      -
      -

      {getMessage('contextmenu.line.property.edit')}

      - + + handleClosePopup()} /> + +
      + {getMessage('modal.line.property.edit.info')} + + {getMessage('modal.line.property.edit.selected')} [ {selectedProperty?.name} ] +
      -
      -
      -
      -
      - {getMessage('modal.line.property.edit.info')} - - {getMessage('modal.line.property.edit.selected')} [ {selectedProperty?.name} ] - -
      -
      -
      {getMessage('setting')}
      -
      -
      - {properties.map((property, index) => { - return ( -
      - = 10 ? index + 1 : `0${index + 1}`)} - onChange={(e) => setSelectedProperty(property)} - /> - -
      - ) - })} -
      +
      +
      {getMessage('setting')}
      +
      +
      + {properties.map((property, index) => { + return ( +
      + = 10 ? index + 1 : `0${index + 1}`)} + onChange={(e) => setSelectedProperty(property)} + /> + +
      + ) + })}
      -
      - -
      -
      -
      +
      + +
      + ) } diff --git a/src/components/floor-plan/modal/module/CircuitNumberEdit.jsx b/src/components/floor-plan/modal/module/CircuitNumberEdit.jsx index 50c819ed..1e1b2f2f 100644 --- a/src/components/floor-plan/modal/module/CircuitNumberEdit.jsx +++ b/src/components/floor-plan/modal/module/CircuitNumberEdit.jsx @@ -14,38 +14,28 @@ export default function CircuitNumberEdit(props) { closePopup(id) } return ( - -
      -
      -

      {getMessage('modal.module.circuit.number.edit')}

      - -
      -
      -
      -
      -
      {getMessage('modal.module.circuit.number.edit.info')}
      -
      -
      -
      - - {getMessage('modal.module.circuit.number')} - -
      - -
      + + closePopup(id)} /> + +
      {getMessage('modal.module.circuit.number.edit.info')}
      +
      +
      +
      + + {getMessage('modal.module.circuit.number')} + +
      +
      -
      - -
      -
      -
      +
      + +
      + ) } diff --git a/src/components/floor-plan/modal/module/PanelEdit.jsx b/src/components/floor-plan/modal/module/PanelEdit.jsx index ea671881..2a06e062 100644 --- a/src/components/floor-plan/modal/module/PanelEdit.jsx +++ b/src/components/floor-plan/modal/module/PanelEdit.jsx @@ -91,75 +91,64 @@ export default function PanelEdit(props) { } return ( - -
      -
      -

      - {getMessage( - [PANEL_EDIT_TYPE.MOVE, PANEL_EDIT_TYPE.MOVE_ALL, PANEL_EDIT_TYPE.COLUMN_MOVE].includes(type) - ? 'modal.move.setting' - : 'modal.copy.setting', - )}{' '} -

      - + + closePopup(id)} + /> + +
      + {getMessage( + [PANEL_EDIT_TYPE.MOVE, PANEL_EDIT_TYPE.MOVE_ALL, PANEL_EDIT_TYPE.COLUMN_MOVE].includes(type) + ? 'modal.move.setting.info' + : 'modal.copy.setting.info', + )}
      -
      -
      -
      -
      - {getMessage( - [PANEL_EDIT_TYPE.MOVE, PANEL_EDIT_TYPE.MOVE_ALL, PANEL_EDIT_TYPE.COLUMN_MOVE].includes(type) - ? 'modal.move.setting.info' - : 'modal.copy.setting.info', - )} -
      -
      -
      -
      - {getMessage('margin')} -
      - setLength(e.target.value)} /> -
      - mm -
      -
      - - - - +
      +
      +
      + {getMessage('margin')} +
      + setLength(e.target.value)} />
      + mm +
      +
      + + + +
      -
      - -
      -
      -
      +
      + +
      + ) } diff --git a/src/components/floor-plan/modal/module/column/ColumnInsert.jsx b/src/components/floor-plan/modal/module/column/ColumnInsert.jsx index e42d2ca3..0c160656 100644 --- a/src/components/floor-plan/modal/module/column/ColumnInsert.jsx +++ b/src/components/floor-plan/modal/module/column/ColumnInsert.jsx @@ -24,91 +24,69 @@ export default function ColumnInsert(props) { } return ( - -
      -
      -

      {getMessage('modal.panel.column.insert')}

      -
      -
      -
      -
      -
      -
      {getMessage('modal.panel.column.insert.info')}
      -
      -
      -
      - - -
      -
      - - -
      -
      -
      - {selectedType === MODULE_INSERT_TYPE.LEFT && ( - react - )} - {selectedType === MODULE_INSERT_TYPE.RIGHT && ( - react - )} -
      -
      -
      -
      -
      {getMessage('legend')}
      -
      -
      -
      -
      - - {getMessage('modal.panel.select.column')} -
      -
      - - {getMessage('modal.panel.insert.column')} -
      -
      -
      -
      -
      -
      - -
      -
      -
      -
      +
      ) } diff --git a/src/components/floor-plan/modal/module/column/ColumnRemove.jsx b/src/components/floor-plan/modal/module/column/ColumnRemove.jsx index 66351d35..b9079642 100644 --- a/src/components/floor-plan/modal/module/column/ColumnRemove.jsx +++ b/src/components/floor-plan/modal/module/column/ColumnRemove.jsx @@ -26,98 +26,64 @@ export default function ColumnRemove(props) { } return ( - -
      -
      -

      {getMessage('modal.panel.column.remove')}

      - -
      -
      -
      -
      -
      -
      {getMessage('modal.panel.column.remove.info')}
      -
      -
      - {types.map((type, index) => { - return ( -
      - setSelectedType(e.target.value)} - value={type.value} - checked={selectedType === type.value} - /> - -
      - ) - })} -
      -
      - {selectedType === MODULE_REMOVE_TYPE.LEFT && ( - react - )} - {selectedType === MODULE_REMOVE_TYPE.RIGHT && ( - react - )} - {selectedType === MODULE_REMOVE_TYPE.HORIZONTAL_SIDE && ( - react - )} - {selectedType === MODULE_REMOVE_TYPE.NONE && ( - react - )} -
      + + closePopup(id)} /> + +
      +
      {getMessage('modal.panel.column.remove.info')}
      +
      +
      + {types.map((type, index) => { + return ( +
      + setSelectedType(e.target.value)} + value={type.value} + checked={selectedType === type.value} + /> + +
      + ) + })} +
      +
      + {selectedType === MODULE_REMOVE_TYPE.LEFT && ( + react + )} + {selectedType === MODULE_REMOVE_TYPE.RIGHT && ( + react + )} + {selectedType === MODULE_REMOVE_TYPE.HORIZONTAL_SIDE && ( + react + )} + {selectedType === MODULE_REMOVE_TYPE.NONE && ( + react + )}
      -
      -
      {getMessage('legend')}
      -
      -
      -
      -
      - - {getMessage('modal.panel.select.column')} -
      +
      +
      +
      {getMessage('legend')}
      +
      +
      +
      +
      + + {getMessage('modal.panel.select.column')}
      -
      - -
      -
      -
      +
      + +
      + ) } diff --git a/src/components/floor-plan/modal/module/row/RowInsert.jsx b/src/components/floor-plan/modal/module/row/RowInsert.jsx index 9b558706..e9fb799c 100644 --- a/src/components/floor-plan/modal/module/row/RowInsert.jsx +++ b/src/components/floor-plan/modal/module/row/RowInsert.jsx @@ -24,91 +24,82 @@ export default function RowInsert(props) { } return ( - -
      -
      -

      {getMessage('modal.row.insert')}

      -
      -
      -
      -
      -
      -
      {getMessage('modal.row.insert.info')}
      -
      -
      -
      - - -
      -
      - - -
      -
      -
      - {selectedType === MODULE_INSERT_TYPE.TOP && ( - react - )} - {selectedType === MODULE_INSERT_TYPE.BOTTOM && ( - react - )} -
      -
      -
      -
      -
      {getMessage('legend')}
      -
      -
      -
      -
      - - {getMessage('modal.panel.select.row')} -
      -
      - - {getMessage('modal.panel.insert.row')} -
      -
      -
      -
      -
      -
      - -
      -
      -
      +
      ) } diff --git a/src/components/floor-plan/modal/module/row/RowRemove.jsx b/src/components/floor-plan/modal/module/row/RowRemove.jsx index 500fbfb3..5cf95b3f 100644 --- a/src/components/floor-plan/modal/module/row/RowRemove.jsx +++ b/src/components/floor-plan/modal/module/row/RowRemove.jsx @@ -27,98 +27,88 @@ export default function RowRemove(props) { } return ( - -
      -
      -

      {getMessage('modal.row.remove')}

      - -
      -
      -
      -
      -
      -
      {getMessage('modal.row.remove.info')}
      -
      -
      - {types.map((type, index) => { - return ( -
      - setSelectedType(e.target.value)} - value={type.value} - checked={selectedType === type.value} - /> - -
      - ) - })} -
      -
      - {selectedType === MODULE_REMOVE_TYPE.TOP && ( - react - )} - {selectedType === MODULE_REMOVE_TYPE.BOTTOM && ( - react - )} - {selectedType === MODULE_REMOVE_TYPE.VERTICAL_SIDE && ( - react - )} - {selectedType === MODULE_REMOVE_TYPE.NONE && ( - react - )} -
      + + closePopup(id)} /> + +
      +
      {getMessage('modal.row.remove.info')}
      +
      +
      + {types.map((type, index) => { + return ( +
      + setSelectedType(e.target.value)} + value={type.value} + checked={selectedType === type.value} + /> + +
      + ) + })} +
      +
      + {selectedType === MODULE_REMOVE_TYPE.TOP && ( + react + )} + {selectedType === MODULE_REMOVE_TYPE.BOTTOM && ( + react + )} + {selectedType === MODULE_REMOVE_TYPE.VERTICAL_SIDE && ( + react + )} + {selectedType === MODULE_REMOVE_TYPE.NONE && ( + react + )}
      -
      -
      {getMessage('legend')}
      -
      -
      -
      -
      - - {getMessage('modal.panel.select.row')} -
      +
      +
      +
      {getMessage('legend')}
      +
      +
      +
      +
      + + {getMessage('modal.panel.select.row')}
      -
      - -
      -
      -
      +
      + +
      + ) } diff --git a/src/components/floor-plan/modal/movement/MovementSetting.jsx b/src/components/floor-plan/modal/movement/MovementSetting.jsx index 916a40bd..46464538 100644 --- a/src/components/floor-plan/modal/movement/MovementSetting.jsx +++ b/src/components/floor-plan/modal/movement/MovementSetting.jsx @@ -16,36 +16,26 @@ export default function MovementSetting({ id, pos = { x: 50, y: 230 } }) { } return ( - -
      -
      -

      {getMessage('plan.menu.roof.cover.movement.shape.updown')}

      - + ))} +
      +
      + {type === TYPE.FLOW_LINE && } + {type === TYPE.UP_DOWN && } +
      +
      +
      -
      -
      -
      -
      - {buttonType.map((item) => ( - - ))} -
      -
      - {type === TYPE.FLOW_LINE && } - {type === TYPE.UP_DOWN && } -
      -
      - -
      -
      -
      -
      +
      ) } diff --git a/src/components/floor-plan/modal/object/DormerOffset.jsx b/src/components/floor-plan/modal/object/DormerOffset.jsx index d13533f9..af0ee8e0 100644 --- a/src/components/floor-plan/modal/object/DormerOffset.jsx +++ b/src/components/floor-plan/modal/object/DormerOffset.jsx @@ -40,73 +40,63 @@ export default function DormerOffset(props) { // closePopup(id) } return ( - -
      -
      -

      {title}

      - -
      -
      -
      -
      -
      {getMessage('modal.dormer.offset.info')}
      -
      -
      -
      -

      {getMessage('length')}

      -
      -
      - -
      - mm -
      - - -
      + + closePopup(id)} /> + +
      {getMessage('modal.dormer.offset.info')}
      +
      +
      +
      +

      {getMessage('length')}

      +
      +
      +
      -
      -
      - -
      - mm -
      - - -
      + mm +
      + + +
      +
      +
      +
      + +
      + mm +
      + +
      -
      - -
      -
      -
      +
      + +
      +
      ) } diff --git a/src/components/floor-plan/modal/object/ObjectSetting.jsx b/src/components/floor-plan/modal/object/ObjectSetting.jsx index b602f163..1bbddfe6 100644 --- a/src/components/floor-plan/modal/object/ObjectSetting.jsx +++ b/src/components/floor-plan/modal/object/ObjectSetting.jsx @@ -100,43 +100,33 @@ export default function ObjectSetting({ id, pos = { x: 50, y: 230 } }) { ] return ( - -
      -
      -

      {getMessage('plan.menu.placement.surface.object')}

      - + ))} +
      +
      + {buttonAct === 1 && } + {buttonAct === 2 && } + {buttonAct === 3 && } + {buttonAct === 4 && } +
      +
      +
      -
      -
      -
      -
      - {buttonMenu.map((item) => ( - - ))} -
      -
      - {buttonAct === 1 && } - {buttonAct === 2 && } - {buttonAct === 3 && } - {buttonAct === 4 && } -
      -
      - -
      -
      -
      -
      +
      ) } diff --git a/src/components/floor-plan/modal/object/RoofMaterialSetting.jsx b/src/components/floor-plan/modal/object/RoofMaterialSetting.jsx index fdca3518..27c06593 100644 --- a/src/components/floor-plan/modal/object/RoofMaterialSetting.jsx +++ b/src/components/floor-plan/modal/object/RoofMaterialSetting.jsx @@ -21,28 +21,18 @@ export default function RoofMaterialSetting(props) { ] return ( - -
      -
      -

      {getMessage('modal.roof.material.edit')}

      - -
      -
      -
      -
      -
      -
      - -
      -
      -
      - + + closePopup(id)} /> + +
      +
      +
      -
      -
      +
      + +
      + ) } diff --git a/src/components/floor-plan/modal/object/SizeSetting.jsx b/src/components/floor-plan/modal/object/SizeSetting.jsx index 34e86ed8..c5873006 100644 --- a/src/components/floor-plan/modal/object/SizeSetting.jsx +++ b/src/components/floor-plan/modal/object/SizeSetting.jsx @@ -40,60 +40,50 @@ export default function SizeSetting(props) { } return ( - -
      -
      -

      {getMessage('modal.size.setting')}

      - -
      -
      -
      -
      -
      -
      + + closePopup(id)} /> + +
      +
      +
      +
      + + mm +
      +
      + + mm +
      +
      +
      +
      +
      - + mm
      - + mm
      -
      -
      -
      -
      - - mm -
      -
      - - mm -
      -
      -
      -
      - - - - -
      -
      +
      + + + + +
      -
      - -
      -
      -
      +
      + +
      +
      ) } diff --git a/src/components/floor-plan/modal/outerlinesetting/PropertiesSetting.jsx b/src/components/floor-plan/modal/outerlinesetting/PropertiesSetting.jsx index c57eabfa..18b82edf 100644 --- a/src/components/floor-plan/modal/outerlinesetting/PropertiesSetting.jsx +++ b/src/components/floor-plan/modal/outerlinesetting/PropertiesSetting.jsx @@ -8,40 +8,30 @@ export default function PropertiesSetting(props) { const { handleSetEaves, handleSetGable, handleRollback, handleFix, closeModal } = usePropertiesSetting(id) return ( - -
      -
      -

      {getMessage('modal.canvas.setting.wallline.properties.setting')}

      - + +
      +
      +
      + +
      -
      -
      -
      -
      {getMessage('modal.canvas.setting.wallline.properties.setting.info')}
      -
      -
      {getMessage('setting')}
      -
      - - -
      -
      -
      - - -
      -
      -
      -
      + ) } diff --git a/src/components/floor-plan/modal/outerlinesetting/WallLineSetting.jsx b/src/components/floor-plan/modal/outerlinesetting/WallLineSetting.jsx index 409d7550..36d79cb6 100644 --- a/src/components/floor-plan/modal/outerlinesetting/WallLineSetting.jsx +++ b/src/components/floor-plan/modal/outerlinesetting/WallLineSetting.jsx @@ -114,24 +114,18 @@ export default function WallLineSetting(props) { } return ( - -
      -
      -

      {getMessage('modal.cover.outline.drawing')}

      - -
      -
      -
      -
      -
      - {/**/} - {/* */} -
      -
      - {type === OUTER_LINE_TYPE.OUTER_LINE ? ( - - ) : type === OUTER_LINE_TYPE.RIGHT_ANGLE ? ( - - ) : type === OUTER_LINE_TYPE.DOUBLE_PITCH ? ( - - ) : type === OUTER_LINE_TYPE.ANGLE ? ( - - ) : type === OUTER_LINE_TYPE.DIAGONAL_LINE ? ( - - ) : ( - <> - )} -
      -
      - - -
      -
      -
      +
      + {type === OUTER_LINE_TYPE.OUTER_LINE ? ( + + ) : type === OUTER_LINE_TYPE.RIGHT_ANGLE ? ( + + ) : type === OUTER_LINE_TYPE.DOUBLE_PITCH ? ( + + ) : type === OUTER_LINE_TYPE.ANGLE ? ( + + ) : type === OUTER_LINE_TYPE.DIAGONAL_LINE ? ( + + ) : ( + <> + )} +
      +
      + + +
      +
      ) } diff --git a/src/components/floor-plan/modal/panelBatch/PanelBatchStatistics.jsx b/src/components/floor-plan/modal/panelBatch/PanelBatchStatistics.jsx index 67b5efd0..e789bc4a 100644 --- a/src/components/floor-plan/modal/panelBatch/PanelBatchStatistics.jsx +++ b/src/components/floor-plan/modal/panelBatch/PanelBatchStatistics.jsx @@ -29,40 +29,42 @@ export default function PanelBatchStatistics() { }, []) return ( - -
      -

      {getMessage('modal.panel.batch.statistic')}

      - -
      - - - - {header.map((item, index) => ( - - ))} - - - - {rows.map((row, index) => ( - - {header.map((item, i) => ( - + + +
      +

      {getMessage('modal.panel.batch.statistic')}

      + +
      +
      {item.name}
      {row[item.prop] ?? 0}
      + + + {header.map((item, index) => ( + ))} - ))} - - {header.map((header, index) => ( - + + + {rows.map((row, index) => ( + + {header.map((item, i) => ( + + ))} + ))} - - -
      {item.name}
      - {typeof footer[header.prop] === 'number' - ? footer[header.prop].toLocaleString('ko-KR', { maximumFractionDigits: 4 }) - : footer[header.prop]} -
      {row[item.prop] ?? 0}
      + + {header.map((header, index) => ( + + {typeof footer[header.prop] === 'number' + ? footer[header.prop].toLocaleString('ko-KR', { maximumFractionDigits: 4 }) + : footer[header.prop]} + + ))} + + + +
      -
      + ) } diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeDrawing.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeDrawing.jsx index 72cf2c21..04b63f1d 100644 --- a/src/components/floor-plan/modal/placementShape/PlacementShapeDrawing.jsx +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeDrawing.jsx @@ -121,47 +121,33 @@ export default function PlacementShapeDrawing({ id, pos = { x: 50, y: 230 } }) { setType(button.type) } return ( - -
      -
      -

      {getMessage('plan.menu.placement.surface.drawing')}

      - + ))} +
      +
      + {buttonAct === 1 && } + {buttonAct === 2 && } + {buttonAct === 3 && } + {buttonAct === 4 && } + {buttonAct === 5 && } +
      + +
      + +
      -
      -
      -
      -
      - {types.map((type, idx) => ( - - ))} -
      -
      - {buttonAct === 1 && } - {buttonAct === 2 && } - {buttonAct === 3 && } - {buttonAct === 4 && } - {buttonAct === 5 && } -
      - -
      - - -
      -
      -
      -
      +
      ) } diff --git a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx index 127e7742..a70a8c65 100644 --- a/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx +++ b/src/components/floor-plan/modal/placementShape/PlacementShapeSetting.jsx @@ -257,194 +257,191 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla } return ( - -
      -
      -

      {getMessage('plan.menu.placement.surface.initial.setting')}

      -
      -
      -
      -
      -
      - - - - - - - - - - - - - - - - - + + +
      {getMessage('modal.placement.initial.setting.plan.drawing')}{getMessage('modal.placement.initial.setting.plan.drawing.size.stuff')}
      -
      - {getMessage('modal.placement.initial.setting.size')} - -
      -
      -
      - {currentRoof && - roofSizeSetArray.map((item) => ( -
      - setCurrentRoof({ ...currentRoof, roofSizeSet: e.target.value })} - /> - -
      - ))} -
      -
      {getMessage('modal.placement.initial.setting.roof.angle.setting')} -
      - {currentRoof && - roofAngleSetArray.map((item, index) => ( -
      - -
      - setCurrentRoof({ ...currentRoof, roofAngleSet: e.target.value })} - /> - -
      -
      -
      + + + +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + - - - - - - -
      {getMessage('modal.placement.initial.setting.plan.drawing')}{getMessage('modal.placement.initial.setting.plan.drawing.size.stuff')}
      +
      + {getMessage('modal.placement.initial.setting.size')} + +
      +
      +
      + {currentRoof && + roofSizeSetArray.map((item) => ( +
      + setCurrentRoof({ ...currentRoof, roofSizeSet: e.target.value })} + /> + +
      + ))} +
      +
      {getMessage('modal.placement.initial.setting.roof.angle.setting')} +
      + {currentRoof && + roofAngleSetArray.map((item, index) => ( +
      + +
      - index === 0 - ? setCurrentRoof({ ...currentRoof, pitch: e.target.value, angle: getDegreeByChon(e.target.value) }) - : setCurrentRoof({ ...currentRoof, pitch: getChonByDegree(e.target.value), angle: e.target.value }) - } + type="radio" + id={item.id} + name={item.name} + value={item.value} + checked={String(currentRoof?.roofAngleSet) === item.value} + onChange={(e) => setCurrentRoof({ ...currentRoof, roofAngleSet: e.target.value })} /> +
      - {index === 0 ? '寸' : '度'} +
      +
      + + index === 0 + ? setCurrentRoof({ ...currentRoof, pitch: e.target.value, angle: getDegreeByChon(e.target.value) }) + : setCurrentRoof({ ...currentRoof, pitch: getChonByDegree(e.target.value), angle: e.target.value }) + } + />
      - ))} + {index === 0 ? '寸' : '度'} +
      + ))} +
      +
      +
      + {getMessage('modal.placement.initial.setting.roof.material')} + +
      +
      +
      +
      + { + return { ...roof, name: globalLocale === 'ko' ? roof.roofMatlNm : roof.roofMatlNmJp } + })} + value={currentRoof?.roofSizeSet === '3' ? null : currentRoof?.roofMatlCd} + onChange={(e) => handleRoofTypeChange(e.roofMatlCd)} + sourceKey="id" + targetKey="id" + showKey="name" + disabled={currentRoof?.roofSizeSet === '3'} + />
      -
      -
      - {getMessage('modal.placement.initial.setting.roof.material')} - -
      -
      -
      -
      - { - return { ...roof, name: globalLocale === 'ko' ? roof.roofMatlNm : roof.roofMatlNmJp } - })} - value={currentRoof?.roofSizeSet === '3' ? null : currentRoof?.roofMatlCd} - onChange={(e) => handleRoofTypeChange(e.roofMatlCd)} - sourceKey="id" - targetKey="id" - showKey="name" - disabled={currentRoof?.roofSizeSet === '3'} - /> + {currentRoof && ['R', 'C'].includes(currentRoof.widAuth) && ( +
      + W +
      + onlyNumberInputChange(e, changeInput)} + readOnly={currentRoof?.widAuth === 'R'} + disabled={currentRoof?.roofSizeSet === '3'} + /> +
      - {currentRoof && ['R', 'C'].includes(currentRoof.widAuth) && ( -
      - W -
      - onlyNumberInputChange(e, changeInput)} - readOnly={currentRoof?.widAuth === 'R'} + )} + {currentRoof && ['R', 'C'].includes(currentRoof.lenAuth) && ( +
      + L +
      + onlyNumberInputChange(e, changeInput)} + readOnly={currentRoof?.lenAuth === 'R'} + disabled={currentRoof?.roofSizeSet === '3'} + /> +
      +
      + )} + {currentRoof && ['C', 'R'].includes(currentRoof.raftAuth) && ( +
      + {getMessage('modal.placement.initial.setting.rafter')} + {raftCodes?.length > 0 && ( +
      + r.clCode === (currentRoof?.raft === undefined ? currentRoof?.raftBaseCd : currentRoof?.raft)) + .clCodeNm + } + value={currentRoof?.raft === undefined ? currentRoof?.raftBaseCd : currentRoof?.raft} + onChange={(e) => handleRafterChange(e.clCode)} + sourceKey="clCode" + targetKey={currentRoof?.raft ? 'raft' : 'raftBaseCd'} + showKey="clCodeNm" disabled={currentRoof?.roofSizeSet === '3'} />
      + )} +
      + )} + {currentRoof && ['C', 'R'].includes(currentRoof?.roofPchAuth) && ( +
      + {getMessage('hajebichi')} +
      + onlyNumberInputChange(e, changeInput)} + readOnly={currentRoof?.roofPchAuth === 'R'} + disabled={currentRoof?.roofSizeSet === '3'} + />
      - )} - {currentRoof && ['R', 'C'].includes(currentRoof.lenAuth) && ( -
      - L -
      - onlyNumberInputChange(e, changeInput)} - readOnly={currentRoof?.lenAuth === 'R'} - disabled={currentRoof?.roofSizeSet === '3'} - /> -
      -
      - )} - {currentRoof && ['C', 'R'].includes(currentRoof.raftAuth) && ( -
      - {getMessage('modal.placement.initial.setting.rafter')} - {raftCodes?.length > 0 && ( -
      - r.clCode === (currentRoof?.raft === undefined ? currentRoof?.raftBaseCd : currentRoof?.raft)) - .clCodeNm - } - value={currentRoof?.raft === undefined ? currentRoof?.raftBaseCd : currentRoof?.raft} - onChange={(e) => handleRafterChange(e.clCode)} - sourceKey="clCode" - targetKey={currentRoof?.raft ? 'raft' : 'raftBaseCd'} - showKey="clCodeNm" - disabled={currentRoof?.roofSizeSet === '3'} - /> -
      - )} -
      - )} - {currentRoof && ['C', 'R'].includes(currentRoof?.roofPchAuth) && ( -
      - {getMessage('hajebichi')} -
      - onlyNumberInputChange(e, changeInput)} - readOnly={currentRoof?.roofPchAuth === 'R'} - disabled={currentRoof?.roofSizeSet === '3'} - /> -
      -
      - )} -
      - {/* {currentRoof && ( +
      + )} +
      + {/* {currentRoof && (
      )} */} -
      -
      -
      - -
      +
      - {showSizeGuideModal && } - {showMaterialGuideModal && } -
      -
      +
      + +
      + + {showSizeGuideModal && } + {showMaterialGuideModal && } ) } diff --git a/src/components/floor-plan/modal/placementShape/PlacementSurfaceLineProperty.jsx b/src/components/floor-plan/modal/placementShape/PlacementSurfaceLineProperty.jsx index bc532242..34cf8c1e 100644 --- a/src/components/floor-plan/modal/placementShape/PlacementSurfaceLineProperty.jsx +++ b/src/components/floor-plan/modal/placementShape/PlacementSurfaceLineProperty.jsx @@ -41,43 +41,33 @@ export default function PlacementSurfaceLineProperty(props) { } return ( - -
      -
      -

      {getMessage('modal.canvas.setting.roofline.properties.setting')}

      - + + +
      +
      +
      + +
      -
      -
      -
      -
      {getMessage('modal.canvas.setting.roofline.properties.setting.info')}
      -
      -
      {getMessage('setting')}
      -
      - - - -
      -
      -
      - - -
      -
      -
      -
      +
      ) } diff --git a/src/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting.jsx b/src/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting.jsx index 967d849e..ae29b778 100644 --- a/src/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting.jsx +++ b/src/components/floor-plan/modal/placementSurface/PlacementSurfaceSetting.jsx @@ -256,63 +256,49 @@ export default function PlacementSurfaceSetting({ id, pos = { x: 50, y: 230 } }) }, []) return ( - -
      -
      -

      {getMessage('plan.menu.placement.surface.arrangement')}

      - -
      -
      -
      -
      -
      -
      -
      - {types.map((type) => ( - - ))} -
      -
      - - {/* */} - {/* - */} - - -
      -
      -
      - -
      - -
      + ))} +
      +
      + + {/* */} + {/* + */} + + +
      +
      +
      + +
      +
      -
      -
      +
      ) } diff --git a/src/components/floor-plan/modal/roofAllocation/ActualSizeSetting.jsx b/src/components/floor-plan/modal/roofAllocation/ActualSizeSetting.jsx index 0af71db1..c91325c0 100644 --- a/src/components/floor-plan/modal/roofAllocation/ActualSizeSetting.jsx +++ b/src/components/floor-plan/modal/roofAllocation/ActualSizeSetting.jsx @@ -61,65 +61,50 @@ export default function ActualSizeSetting(props) { } return ( - -
      -
      -

      {getMessage('modal.actual.size.setting')}

      - + + closePopup(id)} /> + +
      + {getMessage('modal.actual.size.setting.info')}
      -
      -
      -
      -
      - {getMessage('modal.actual.size.setting.info')} -
      -
      -
      {getMessage('setting')}
      -
      -
      -
      -
      {getMessage('modal.actual.size.setting.plane.size.length')}
      -
      -
      -
      - -
      - mm +
      +
      {getMessage('setting')}
      +
      +
      +
      +
      {getMessage('modal.actual.size.setting.plane.size.length')}
      +
      +
      +
      +
      + mm
      -
      -
      {getMessage('modal.actual.size.setting.actual.size.length')}
      -
      -
      -
      - setActualSize(Number(e.target.value))} - /> -
      - mm +
      +
      +
      {getMessage('modal.actual.size.setting.actual.size.length')}
      +
      +
      +
      + setActualSize(Number(e.target.value))} />
      + mm
      -
      - - -
      -
      -
      +
      + + +
      + ) } diff --git a/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx b/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx index 30e56c0e..dd8b7003 100644 --- a/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx +++ b/src/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting.jsx @@ -47,22 +47,13 @@ export default function ContextRoofAllocationSetting(props) { }, []) return ( - -
      - {currentRoofList && ( - <> -
      -

      {getMessage('plan.menu.estimate.roof.alloc')}

      - -
      -
      -
      -
      -
      {getMessage('modal.roof.alloc.info')}
      -
      - {/* {getMessage('modal.roof.alloc.select.roof.material')} + + closePopup(id)} /> + {currentRoofList && ( + +
      {getMessage('modal.roof.alloc.info')}
      +
      + {/* {getMessage('modal.roof.alloc.select.roof.material')}
      { @@ -78,165 +69,162 @@ export default function ContextRoofAllocationSetting(props) { targetKey={'roofMatlCd'} />
      */} - -
      -
      -
      - {currentRoofList.map((roof, index) => { - return ( -
      -
      - - + +
      +
      +
      + {currentRoofList.map((roof, index) => { + return ( +
      +
      + + +
      +
      +
      +
      +
      + { + return { ...roof2, name: globalLocale === 'ko' ? roof2.roofMatlNm : roof2.roofMatlNmJp } + })} + value={roof} + //showKey={'roofMatlNm'} + showKey="name" + sourceKey={'roofMatlCd'} + targetKey={'roofMatlCd'} + onChange={(e) => handleChangeRoofMaterial(e, index)} + /> +
      + {index === 0 && {getMessage('modal.roof.alloc.default.roof.material')}} + {index !== 0 && ( + + + + )}
      -
      -
      -
      +
      + {roof.raftAuth && ( +
      +
      + {getMessage('modal.placement.initial.setting.rafter')} + {raftCodes.length > 0 && (
      { - return { ...roof2, name: globalLocale === 'ko' ? roof2.roofMatlNm : roof2.roofMatlNmJp } - })} + options={raftCodes} value={roof} - //showKey={'roofMatlNm'} - showKey="name" - sourceKey={'roofMatlCd'} - targetKey={'roofMatlCd'} - onChange={(e) => handleChangeRoofMaterial(e, index)} + showKey={'clCodeNm'} + sourceKey={'clCode'} + targetKey={roof.raft ? 'raft' : 'raftBaseCd'} + onChange={(e) => handleChangeRaft(e, index)} />
      - {index === 0 && {getMessage('modal.roof.alloc.default.roof.material')}} - {index !== 0 && ( - - - - )} -
      + )}
      - {roof.raftAuth && ( -
      -
      - {getMessage('modal.placement.initial.setting.rafter')} - {raftCodes.length > 0 && ( -
      - handleChangeRaft(e, index)} - /> -
      - )} -
      -
      - )} +
      + )} - {(roof.widAuth || roof.lenAuth) && ( - <> - {roof.widAuth && ( -
      -
      - W -
      - { - handleChangeInput(e, 'width', index) - }} - /> -
      -
      -
      - )} - {roof.lenAuth && ( -
      -
      - L -
      - { - handleChangeInput(e, 'length', index) - }} - /> -
      -
      -
      - )} - - )} - {roof.roofPchAuth && ( + {(roof.widAuth || roof.lenAuth) && ( + <> + {roof.widAuth && (
      - {getMessage('hajebichi')} + W
      handleChangeInput(e, 'hajebichi', index)} + defaultValue={roof.width} + readOnly={roof.widAuth === 'R'} + onChange={(e) => { + handleChangeInput(e, 'width', index) + }} />
      )} -
      -
      - {getMessage('modal.object.setting.offset.slope')} -
      - { - // handleChangeInput(e, currentAngleType === 'slope' ? 'pitch' : 'angle', index) - handleChangePitch(e, index) - }} - value={currentAngleType === 'slope' ? roof.pitch : roof.angle} - defaultValue={currentAngleType === 'slope' ? roof.pitch : roof.angle} - /> + {roof.lenAuth && ( +
      +
      + L +
      + { + handleChangeInput(e, 'length', index) + }} + /> +
      - {pitchText} +
      + )} + + )} + {roof.roofPchAuth && ( +
      +
      + {getMessage('hajebichi')} +
      + handleChangeInput(e, 'hajebichi', index)} + />
      + )} +
      +
      + {getMessage('modal.object.setting.offset.slope')} +
      + { + // handleChangeInput(e, currentAngleType === 'slope' ? 'pitch' : 'angle', index) + handleChangePitch(e, index) + }} + value={currentAngleType === 'slope' ? roof.pitch : roof.angle} + defaultValue={currentAngleType === 'slope' ? roof.pitch : roof.angle} + /> +
      + {pitchText} +
      - ) - })} -
      -
      -
      - -
      +
      +
      + ) + })}
      - - )} -
      -
      +
      +
      + +
      + + )} ) } diff --git a/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx b/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx index 3dd03385..0603ed96 100644 --- a/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx +++ b/src/components/floor-plan/modal/roofAllocation/RoofAllocationSetting.jsx @@ -47,22 +47,14 @@ export default function RoofAllocationSetting(props) { }, []) return ( - -
      + + closePopup(id)} /> + {currentRoofList && ( <> -
      -

      {getMessage('plan.menu.estimate.roof.alloc')}

      - -
      -
      -
      -
      -
      {getMessage('modal.roof.alloc.info')}
      -
      - {/* {getMessage('modal.roof.alloc.select.roof.material')} +
      {getMessage('modal.roof.alloc.info')}
      +
      + {/* {getMessage('modal.roof.alloc.select.roof.material')}
      { @@ -78,146 +70,146 @@ export default function RoofAllocationSetting(props) { targetKey={'roofMatlCd'} />
      */} - -
      -
      -
      - {currentRoofList.map((roof, index) => { - return ( -
      -
      - - + +
      +
      +
      + {currentRoofList.map((roof, index) => { + return ( +
      +
      + + +
      +
      +
      +
      +
      + { + return { ...roof2, name: globalLocale === 'ko' ? roof2.roofMatlNm : roof2.roofMatlNmJp } + })} + value={roof} + //showKey={'roofMatlNm'} + showKey="name" + sourceKey={'roofMatlCd'} + targetKey={'roofMatlCd'} + onChange={(e) => handleChangeRoofMaterial(e, index)} + /> +
      + {index === 0 && {getMessage('modal.roof.alloc.default.roof.material')}} + {index !== 0 && ( + + + + )} +
      -
      + + {roof.raftAuth && (
      -
      - { - return { ...roof2, name: globalLocale === 'ko' ? roof2.roofMatlNm : roof2.roofMatlNmJp } - })} - value={roof} - //showKey={'roofMatlNm'} - showKey="name" - sourceKey={'roofMatlCd'} - targetKey={'roofMatlCd'} - onChange={(e) => handleChangeRoofMaterial(e, index)} - /> -
      - {index === 0 && {getMessage('modal.roof.alloc.default.roof.material')}} - {index !== 0 && ( - - - + {getMessage('modal.placement.initial.setting.rafter')} + {raftCodes.length > 0 && ( +
      + handleChangeRaft(e, index)} + /> +
      )}
      + )} - {roof.raftAuth && ( -
      -
      - {getMessage('modal.placement.initial.setting.rafter')} - {raftCodes.length > 0 && ( -
      - handleChangeRaft(e, index)} + {(roof.widAuth || roof.lenAuth) && ( + <> + {roof.widAuth && ( +
      +
      + W +
      + handleChangeInput(e, 'width', index)} + readOnly={roof.widAuth === 'R'} />
      - )} -
      -
      - )} - - {(roof.widAuth || roof.lenAuth) && ( - <> - {roof.widAuth && ( -
      -
      - W -
      - handleChangeInput(e, 'width', index)} - readOnly={roof.widAuth === 'R'} - /> -
      -
      -
      - )} - {roof.lenAuth && ( -
      -
      - L -
      - handleChangeInput(e, 'length', index)} - readOnly={roof.lenAuth === 'R'} - /> -
      -
      -
      - )} - - )} - {roof.roofPchAuth && ( -
      -
      - {getMessage('hajebichi')} -
      - handleChangeInput(e, 'hajebichi', index)} - value={parseInt(roof.hajebichi)} - readOnly={roof.roofPchAuth === 'R'} - />
      -
      - )} + )} + {roof.lenAuth && ( +
      +
      + L +
      + handleChangeInput(e, 'length', index)} + readOnly={roof.lenAuth === 'R'} + /> +
      +
      +
      + )} + + )} + {roof.roofPchAuth && (
      - {getMessage('modal.object.setting.offset.slope')} + {getMessage('hajebichi')}
      { - handleChangePitch(e, index) - }} - value={currentAngleType === 'slope' ? roof.pitch : roof.angle} - defaultValue={currentAngleType === 'slope' ? roof.pitch : roof.angle} + onChange={(e) => handleChangeInput(e, 'hajebichi', index)} + value={parseInt(roof.hajebichi)} + readOnly={roof.roofPchAuth === 'R'} />
      - {pitchText}
      - {/*
      + )} +
      +
      + {getMessage('modal.object.setting.offset.slope')} +
      + { + handleChangePitch(e, index) + }} + value={currentAngleType === 'slope' ? roof.pitch : roof.angle} + defaultValue={currentAngleType === 'slope' ? roof.pitch : roof.angle} + /> +
      + {pitchText} +
      +
      + {/*
      */} -
      - ) - })} -
      -
      -
      - +
      + ) + })}
      +
      + +
      )} -
      -
      + ) } diff --git a/src/components/floor-plan/modal/roofShape/RoofShapePassivitySetting.jsx b/src/components/floor-plan/modal/roofShape/RoofShapePassivitySetting.jsx index 44152cf8..7530bcdd 100644 --- a/src/components/floor-plan/modal/roofShape/RoofShapePassivitySetting.jsx +++ b/src/components/floor-plan/modal/roofShape/RoofShapePassivitySetting.jsx @@ -29,48 +29,38 @@ export default function RoofShapePassivitySetting({ id, pos = { x: 50, y: 230 } } return ( - -
      -
      -

      {getMessage('plan.menu.roof.cover.roof.shape.passivity.setting')}

      - + + closePopup(id)} /> + +
      + {buttons.map((button) => ( + + ))}
      -
      -
      -
      -
      - {buttons.map((button) => ( - - ))} -
      -
      -
      {getMessage('setting')}
      -
      - {type === TYPES.EAVES && } - {type === TYPES.GABLE && } - {type === TYPES.SHED && } -
      -
      - - -
      +
      +
      {getMessage('setting')}
      +
      + {type === TYPES.EAVES && } + {type === TYPES.GABLE && } + {type === TYPES.SHED && }
      - +
      -
      -
      +
      + +
      + ) } diff --git a/src/components/floor-plan/modal/roofShape/RoofShapeSetting.jsx b/src/components/floor-plan/modal/roofShape/RoofShapeSetting.jsx index 64ac905c..73ccc348 100644 --- a/src/components/floor-plan/modal/roofShape/RoofShapeSetting.jsx +++ b/src/components/floor-plan/modal/roofShape/RoofShapeSetting.jsx @@ -88,41 +88,31 @@ export default function RoofShapeSetting({ id, pos = { x: 50, y: 230 } }) { } return ( - -
      -
      -

      {getMessage('modal.roof.shape.setting')}

      - + ))} +
      +
      + {shapeNum === 1 && } + {(shapeNum === 2 || shapeNum === 3) && } + {shapeNum === 4 && } + {(shapeNum === 5 || shapeNum === 6 || shapeNum === 7 || shapeNum === 8) && } +
      +
      +
      -
      -
      -
      -
      - {shapeMenu.map((item) => ( - - ))} -
      -
      - {shapeNum === 1 && } - {(shapeNum === 2 || shapeNum === 3) && } - {shapeNum === 4 && } - {(shapeNum === 5 || shapeNum === 6 || shapeNum === 7 || shapeNum === 8) && } -
      -
      - -
      -
      -
      -
      +
      ) } diff --git a/src/components/floor-plan/modal/setting01/SettingModal01.jsx b/src/components/floor-plan/modal/setting01/SettingModal01.jsx index 36691d62..4e6f91ea 100644 --- a/src/components/floor-plan/modal/setting01/SettingModal01.jsx +++ b/src/components/floor-plan/modal/setting01/SettingModal01.jsx @@ -72,39 +72,27 @@ export default function SettingModal01(props) { } return ( - <> - -
      -
      -

      {getMessage('modal.canvas.setting')}

      - -
      -
      -
      -
      -
      - + + closePopup(id, true)} /> + +
      + - - {canGridOptionSeletorValue && ( - - )} -
      - {buttonAct === 1 && } - {buttonAct === 2 && } - {buttonAct === 3 && } -
      -
      + + {canGridOptionSeletorValue && ( + + )}
      - - + {buttonAct === 1 && } + {buttonAct === 2 && } + {buttonAct === 3 && } + + ) } diff --git a/src/components/floor-plan/modal/setting01/dimensionLine/DimensionLineSetting.jsx b/src/components/floor-plan/modal/setting01/dimensionLine/DimensionLineSetting.jsx index 7fcbe45a..8bdecff8 100644 --- a/src/components/floor-plan/modal/setting01/dimensionLine/DimensionLineSetting.jsx +++ b/src/components/floor-plan/modal/setting01/dimensionLine/DimensionLineSetting.jsx @@ -190,78 +190,68 @@ export default function DimensionLineSetting(props) { } return ( - -
      -
      -

      {getMessage('modal.canvas.setting.font.plan.absorption.dimension.line')}

      -
      -
      -
      -
      -
      - -
      -
      -
      - {getMessage('modal.canvas.setting.font.plan.absorption.dimension.line.font.size')} -
      - setOriginPixel(e)} /> -
      - pixel -
      -
      - {getMessage('modal.canvas.setting.font.plan.absorption.dimension.line.color')} - +
      +
      + {getMessage('modal.canvas.setting.font.plan.absorption.dimension.line.font.size')} +
      + setOriginPixel(e)} />
      + pixel
      -
      -
      {getMessage('modal.canvas.setting.font.plan.absorption.dimension.display')}
      -
      -
      -
      - - 9,999 - - -
      -
      -
      -
      -
      - +
      + {getMessage('modal.canvas.setting.font.plan.absorption.dimension.line.color')} +
      -
      -
      +
      +
      {getMessage('modal.canvas.setting.font.plan.absorption.dimension.display')}
      +
      +
      +
      + + 9,999 + + +
      +
      +
      +
      +
      + +
      + ) } diff --git a/src/components/floor-plan/modal/setting01/planSize/PlanSizeSetting.jsx b/src/components/floor-plan/modal/setting01/planSize/PlanSizeSetting.jsx index 7bdf05ba..1d4b1e58 100644 --- a/src/components/floor-plan/modal/setting01/planSize/PlanSizeSetting.jsx +++ b/src/components/floor-plan/modal/setting01/planSize/PlanSizeSetting.jsx @@ -55,59 +55,49 @@ export default function PlanSizeSetting(props) { } return ( - -
      -
      -

      {getMessage('modal.canvas.setting.font.plan.absorption.plan.size.setting')}

      -
      -
      -
      -
      -
      -
      - {getMessage('common.horizon')} -
      - onlyNumberInputChange(e, changeInput)} - /> -
      - mm -
      -
      - {getMessage('common.vertical')} -
      - onlyNumberInputChange(e, changeInput)} - /> -
      - mm -
      -
      -
      - -
      -
      -
      -
      +
      ) } diff --git a/src/components/floor-plan/modal/wallLineOffset/WallLineOffsetSetting.jsx b/src/components/floor-plan/modal/wallLineOffset/WallLineOffsetSetting.jsx index 60bab5b7..09c847e7 100644 --- a/src/components/floor-plan/modal/wallLineOffset/WallLineOffsetSetting.jsx +++ b/src/components/floor-plan/modal/wallLineOffset/WallLineOffsetSetting.jsx @@ -39,37 +39,27 @@ export default function WallLineOffsetSetting({ id, pos = { x: 50, y: 230 } }) { } return ( - -
      -
      -

      {getMessage('modal.wallline.offset.setting')}

      - + ))} +
      +
      +
      {getMessage('setting')}
      + {type === TYPES.WALL_LINE_EDIT && } + {type === TYPES.OFFSET && } +
      +
      +
      -
      -
      -
      -
      - {buttonMenu.map((item) => ( - - ))} -
      -
      -
      {getMessage('setting')}
      - {type === TYPES.WALL_LINE_EDIT && } - {type === TYPES.OFFSET && } -
      -
      - -
      -
      -
      -
      +
      ) } From e17f0e0dba354ac420c0deba092080470e66993c Mon Sep 17 00:00:00 2001 From: basssy Date: Thu, 13 Mar 2025 16:14:16 +0900 Subject: [PATCH 323/352] =?UTF-8?q?=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=BC=80?= =?UTF-8?q?=EC=9D=B4=EB=B8=94=20=EA=B4=80=EB=A0=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/estimate/Estimate.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index bd2c202a..8b8b38bc 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -1718,7 +1718,7 @@ export default function Estimate({}) { }} value={cableItem} > - + {/* */} {cableItemList.length > 0 && cableItemList.map((row) => (
      diff --git a/src/hooks/option/useCanvasSetting.js b/src/hooks/option/useCanvasSetting.js index 539c43ec..76f42075 100644 --- a/src/hooks/option/useCanvasSetting.js +++ b/src/hooks/option/useCanvasSetting.js @@ -612,6 +612,9 @@ export function useCanvasSetting(executeEffect = true) { /** 도면크기 설정 */ setPlanSizeSettingMode({ ...planSizeSettingMode, originHorizon: res.originHorizon, originVertical: res.originVertical }) + canvas.setWidth(res.originHorizon) + canvas.setHeight(res.originVertical) + canvas.renderAll() /** 데이터 설정 */ setSettingModalFirstOptions({ diff --git a/src/store/canvasAtom.js b/src/store/canvasAtom.js index 772e55be..ddeed03d 100644 --- a/src/store/canvasAtom.js +++ b/src/store/canvasAtom.js @@ -43,7 +43,7 @@ export const fontSizeState = atom({ export const canvasSizeState = atom({ key: 'canvasSize', default: { - vertical: 1000, + vertical: 1600, horizontal: 1600, }, }) From 20b90d0df66f44025b66225cb714e12140302c85 Mon Sep 17 00:00:00 2001 From: basssy Date: Fri, 14 Mar 2025 17:26:59 +0900 Subject: [PATCH 341/352] #900 YJSS --- src/components/estimate/Estimate.jsx | 39 +++++-------------- src/components/floor-plan/CanvasMenu.jsx | 5 --- src/components/management/StuffDetail.jsx | 2 + .../estimate/useEstimateController.js | 25 +++++++----- 4 files changed, 26 insertions(+), 45 deletions(-) diff --git a/src/components/estimate/Estimate.jsx b/src/components/estimate/Estimate.jsx index 38ff2289..a44af878 100644 --- a/src/components/estimate/Estimate.jsx +++ b/src/components/estimate/Estimate.jsx @@ -480,10 +480,6 @@ export default function Estimate({}) { //Pricing 버튼 const handlePricing = async (showPriceCd) => { - //todo: 추후 YJSS가 다시 나타날 경우 아래 swalFire 제거 필요 - if (estimateContextState.estimateType === 'YJSS') { - return swalFire({ text: getMessage('estimate.detail.save.requiredEstimateType'), type: 'alert', icon: 'warning' }) - } const param = { saleStoreId: session.storeId, sapSalesStoreCd: session.custCd, @@ -699,14 +695,10 @@ export default function Estimate({}) { /* 케이블 select 변경시 */ const onChangeDisplayCableItem = (value, itemList) => { - //todo: 추후 YJSS가 다시 나타날 경우 아래 swalFire 제거 필요 - if (estimateContextState.estimateType === 'YJSS') { - return swalFire({ text: getMessage('estimate.detail.save.requiredEstimateType'), type: 'alert', icon: 'warning' }) - } itemList.map((item, index) => { if (item.dispCableFlg === '1') { if (value !== '') { - onChangeDisplayItem(value, item.dispOrder, index) + onChangeDisplayItem(value, item.dispOrder, index, true) } } }) @@ -714,11 +706,7 @@ export default function Estimate({}) { } // 아이템 자동완성 검색시 아이템 추가/변경시 - const onChangeDisplayItem = (itemId, dispOrder, index) => { - //todo: 추후 YJSS가 다시 나타날 경우 아래 swalFire 제거 필요 - if (estimateContextState.estimateType === 'YJSS') { - return swalFire({ text: getMessage('estimate.detail.save.requiredEstimateType'), type: 'alert', icon: 'warning' }) - } + const onChangeDisplayItem = (itemId, dispOrder, index, flag) => { const param = { itemId: itemId, coldZoneFlg: estimateContextState?.coldRegionFlg, @@ -748,7 +736,7 @@ export default function Estimate({}) { updates.itemGroup = res.itemGroup updates.delFlg = '0' // 삭제플래그 0 updates.saleTotPrice = (res.salePrice * estimateContextState.itemList[index].amount).toString() - updates.amount = '' + updates.amount = flag ? estimateContextState.itemList[index].amount : '' updates.openFlg = res.openFlg if (estimateContextState.estimateType === 'YJSS') { @@ -1032,7 +1020,6 @@ export default function Estimate({}) { }) let dispCableFlgCnt = 0 estimateContextState.itemList.forEach((item) => { - // console.log('YJSS::::::::', item) if (item.delFlg === '0') { let amount = Number(item.amount?.replace(/[^0-9]/g, '').replaceAll(',', '')) || 0 let salePrice @@ -1068,7 +1055,6 @@ export default function Estimate({}) { } if (item.dispCableFlg === '1') { - // console.log('YJSS22222::::::::', item) dispCableFlgCnt++ setCableItem(item.itemId) } @@ -1356,7 +1342,7 @@ export default function Estimate({}) {
      - {/*
      +
      -
      */} +
      { - //todo: 추후 YJSS가 다시 나타날 경우 아래 주석풀기 - // setHandlePricingFlag(true) + setHandlePricingFlag(true) setEstimateContextState({ estimateType: e.target.value }) }} /> @@ -1677,9 +1662,8 @@ export default function Estimate({}) {
      - {/* //todo: 추후 YJSS가 다시 나타날 경우 주석 풀기 */} {/* YJOD면 아래영역 숨김 */} - {/*
      +
      @@ -1714,7 +1698,7 @@ export default function Estimate({}) {
      -
      */} +
      {/* 제품정보 끝 */} {/* 가격표시영역시작 */}
      @@ -1871,7 +1855,7 @@ export default function Estimate({}) { options={originDisplayItemList} onChange={(e) => { if (isObjectNotEmpty(e)) { - onChangeDisplayItem(e.itemId, item.dispOrder, index) + onChangeDisplayItem(e.itemId, item.dispOrder, index, false) } }} menuPlacement={'auto'} @@ -1895,11 +1879,6 @@ export default function Estimate({}) { classNamePrefix="custom" placeholder="Select" options={cableItemList} - onChange={(e) => { - if (isObjectNotEmpty(e)) { - onChangeDisplayItem(e.clRefChr1, item.dispOrder, index) - } - }} menuPlacement={'auto'} getOptionLabel={(x) => x.clRefChr3} getOptionValue={(x) => x.clRefChr1} diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index 66dbf43a..e10d9ebc 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -365,11 +365,6 @@ export default function CanvasMenu(props) { // 견적서 초기화 버튼 const handleEstimateReset = () => { - //todo: 추후 YJSS가 다시 나타날 경우 아래 swalFire 제거 필요 - if (estimateRecoilState.estimateType === 'YJSS') { - return swalFire({ text: getMessage('estimate.detail.save.requiredEstimateType'), type: 'alert', icon: 'warning' }) - } - swalFire({ text: getMessage('estimate.detail.reset.confirmMsg'), type: 'confirm', diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index b3e73597..b5020d5b 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -371,6 +371,7 @@ export default function StuffDetail() { swalFire({ text: getMessage('stuff.detail.header.notExistObjectNo'), type: 'alert', + icon: 'error', confirmFn: () => { router.push('/management/stuff', { scroll: false }) }, @@ -388,6 +389,7 @@ export default function StuffDetail() { swalFire({ text: getMessage('stuff.detail.header.notExistObjectNo'), type: 'alert', + icon: 'error', confirmFn: () => { router.push('/management/stuff', { scroll: false }) }, diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index 1b957e0a..c326a964 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -166,11 +166,6 @@ export const useEstimateController = (planNo, flag) => { //견적서 저장 const handleEstimateSubmit = async () => { - //todo: 추후 YJSS가 다시 나타날 경우 아래 swalFire 제거 필요 - if (estimateData.estimateType === 'YJSS') { - return swalFire({ text: getMessage('estimate.detail.save.requiredEstimateType'), type: 'alert', icon: 'warning' }) - } - //0. 필수체크 let flag = true let originFileFlg = false @@ -300,6 +295,19 @@ export const useEstimateController = (planNo, flag) => { } } } else { + //견적서를 복사하면 API에서 봄컴포넌트는 salePrice, unitPrice를 0으로 내려옴..front에서 처리 + if (item.salePrice === null) { + item.salePrice = '0' + } else if (isNaN(item.salePrice)) { + item.salePrice = '0' + } + + if (item.unitPrice === null) { + item.unitPrice = '0' + } else if (isNaN(item.unitPrice)) { + item.unitPrice = '0' + } + //봄 컴포넌트 제품은 0으로 item.openFlg = '0' } @@ -386,6 +394,7 @@ export const useEstimateController = (planNo, flag) => { estimateData.estimateOption = estimateOptions // console.log('최종아이템:::', estimateData.itemList) + if (fileList?.length > 0) { estimateData.fileList = fileList } else { @@ -413,7 +422,7 @@ export const useEstimateController = (planNo, flag) => { }) } catch (e) { setIsGlobalLoading(false) - console.log('error::::::::::::', e.response.data.message) + console.error('error::::::::::::', e.response.data.message) } } @@ -423,10 +432,6 @@ export const useEstimateController = (planNo, flag) => { * T01관리자 계정 및 1차판매점에게만 제공 */ const handleEstimateCopy = async (sendPlanNo, copyReceiveUser, saleStoreId, otherSaleStoreId, setEstimateCopyPopupOpen) => { - //todo: 추후 YJSS가 다시 나타날 경우 아래 swalFire 제거 필요 - if (estimateData.estimateType === 'YJSS') { - return swalFire({ text: getMessage('estimate.detail.save.requiredEstimateType'), type: 'alert', icon: 'warning' }) - } if (saleStoreId === '') { return swalFire({ text: getMessage('estimate.detail.productFeaturesPopup.requiredStoreId'), From 0956bcc4ad6f8ddd9bd7aca8be39dac931535829 Mon Sep 17 00:00:00 2001 From: basssy Date: Fri, 14 Mar 2025 17:55:58 +0900 Subject: [PATCH 342/352] =?UTF-8?q?=EC=A3=BC=EC=84=9D=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/floorPlan/estimate/useEstimateController.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hooks/floorPlan/estimate/useEstimateController.js b/src/hooks/floorPlan/estimate/useEstimateController.js index c326a964..d509a1e0 100644 --- a/src/hooks/floorPlan/estimate/useEstimateController.js +++ b/src/hooks/floorPlan/estimate/useEstimateController.js @@ -295,7 +295,6 @@ export const useEstimateController = (planNo, flag) => { } } } else { - //견적서를 복사하면 API에서 봄컴포넌트는 salePrice, unitPrice를 0으로 내려옴..front에서 처리 if (item.salePrice === null) { item.salePrice = '0' } else if (isNaN(item.salePrice)) { From 69e56a7297dc2ca6125f9372ca0e705d96bdaf61 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Fri, 14 Mar 2025 18:18:58 +0900 Subject: [PATCH 343/352] =?UTF-8?q?=EB=AA=A8=EB=93=88=EC=88=98=EB=8F=99?= =?UTF-8?q?=EC=84=A4=EC=B9=98=20=ED=9D=A1=EC=B0=A9=EC=A0=90=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 139 +++++++++++++--------- 1 file changed, 83 insertions(+), 56 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 3d90038e..5db1963e 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -1,7 +1,7 @@ import { useState } from 'react' import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' import { canvasSettingState, canvasState, checkedModuleState, currentObjectState, isManualModuleSetupState } from '@/store/canvasAtom' -import { rectToPolygon, polygonToTurfPolygon, calculateVisibleModuleHeight, getDegreeByChon } from '@/util/canvas-util' +import { rectToPolygon, polygonToTurfPolygon, calculateVisibleModuleHeight, getDegreeByChon, toFixedWithoutRounding } from '@/util/canvas-util' import { basicSettingState, roofDisplaySelector } from '@/store/settingAtom' import offsetPolygon, { calculateAngle, createLinesFromPolygon } from '@/util/qpolygon-utils' import { QPolygon } from '@/components/fabric/QPolygon' @@ -424,6 +424,8 @@ export function useModuleBasicSetting(tabNum) { * 확인 후 셀을 이동시킴 */ const manualModuleSetup = (placementRef) => { + console.log('isManualModuleSetup', isManualModuleSetup) + const moduleSetupSurfaces = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE) //모듈설치면를 가져옴 if (isManualModuleSetup) { @@ -493,20 +495,20 @@ export function useModuleBasicSetting(tabNum) { const points = [ { - x: Number(mousePoint.x.toFixed(1)) + Number((width / 2).toFixed(1)), - y: Number(mousePoint.y.toFixed(1)) - Number((height / 2).toFixed(1)), + x: toFixedWithoutRounding(mousePoint.x, 2) + toFixedWithoutRounding(width / 2, 2), + y: toFixedWithoutRounding(mousePoint.y, 2) - toFixedWithoutRounding(height / 2, 2), }, { - x: Number(mousePoint.x.toFixed(1)) + Number((width / 2).toFixed(1)), - y: Number(mousePoint.y.toFixed(1)) + Number((height / 2).toFixed(1)), + x: toFixedWithoutRounding(mousePoint.x, 2) + toFixedWithoutRounding(width / 2, 2), + y: toFixedWithoutRounding(mousePoint.y, 2) + toFixedWithoutRounding(height / 2, 2), }, { - x: Number(mousePoint.x.toFixed(1)) - Number((width / 2).toFixed(1)), - y: Number(mousePoint.y.toFixed(1)) - Number((height / 2).toFixed(1)), + x: toFixedWithoutRounding(mousePoint.x, 2) - toFixedWithoutRounding(width / 2, 2), + y: toFixedWithoutRounding(mousePoint.y, 2) - toFixedWithoutRounding(height / 2, 2), }, { - x: Number(mousePoint.x.toFixed(1)) - Number((width / 2).toFixed(1)), - y: Number(mousePoint.y.toFixed(1)) + Number((height / 2).toFixed(1)), + x: toFixedWithoutRounding(mousePoint.x, 2) - toFixedWithoutRounding(width / 2, 2), + y: toFixedWithoutRounding(mousePoint.y, 2) + toFixedWithoutRounding(height / 2, 2), }, ] @@ -522,10 +524,10 @@ export function useModuleBasicSetting(tabNum) { fill: 'white', stroke: 'black', strokeWidth: 0.3, - width: Number(width.toFixed(1)), - height: Number(height.toFixed(1)), - left: Number(mousePoint.x.toFixed(1) - Number((width / 2).toFixed(1))), - top: Number(mousePoint.y.toFixed(1) - Number((height / 2).toFixed(1))), + width: toFixedWithoutRounding(width, 2), + height: toFixedWithoutRounding(height, 2), + left: toFixedWithoutRounding(mousePoint.x, 2) - toFixedWithoutRounding(width / 2, 2), + top: toFixedWithoutRounding(mousePoint.y, 2) - toFixedWithoutRounding(height / 2, 2), selectable: false, lockMovementX: true, lockMovementY: true, @@ -546,7 +548,7 @@ export function useModuleBasicSetting(tabNum) { /** * 스냅기능 */ - let snapDistance = flowDirection === 'south' || flowDirection === 'north' ? 5 : 5 + let snapDistance = flowDirection === 'south' || flowDirection === 'north' ? 70 : 40 let trestleSnapDistance = 15 let intvHor = @@ -558,67 +560,84 @@ export function useModuleBasicSetting(tabNum) { ? moduleSetupSurfaces[i].trestleDetail.moduleIntvlVer / 10 : moduleSetupSurfaces[i].trestleDetail.moduleIntvlHor / 10 - const trestleLeft = Number(moduleSetupSurfaces[i].left.toFixed(1)) - Number((moduleSetupSurfaces[i].width / 2).toFixed(1)) - const trestleTop = Number(moduleSetupSurfaces[i].top.toFixed(1)) - Number((moduleSetupSurfaces[i].height / 2).toFixed(1)) - const trestleRight = Number(moduleSetupSurfaces[i].left.toFixed(1)) + Number((moduleSetupSurfaces[i].width / 2).toFixed(1)) - const trestleBottom = Number(moduleSetupSurfaces[i].top.toFixed(1)) + Number((moduleSetupSurfaces[i].height / 2).toFixed(1)) + const trestleLeft = toFixedWithoutRounding(moduleSetupSurfaces[i].left, 2) - toFixedWithoutRounding(moduleSetupSurfaces[i].width / 2, 2) + const trestleTop = toFixedWithoutRounding(moduleSetupSurfaces[i].top, 2) - toFixedWithoutRounding(moduleSetupSurfaces[i].height / 2, 2) + const trestleRight = + toFixedWithoutRounding(moduleSetupSurfaces[i].left, 2) + toFixedWithoutRounding(moduleSetupSurfaces[i].width / 2, 2) + const trestleBottom = + toFixedWithoutRounding(moduleSetupSurfaces[i].top, 2) + toFixedWithoutRounding(moduleSetupSurfaces[i].height / 2, 2) const bigCenterY = (trestleTop + trestleTop + moduleSetupSurfaces[i].height) / 2 // 이동하는 모듈의 경계 좌표 - const smallLeft = Number(tempModule.left.toFixed(1)) - const smallTop = Number(tempModule.top.toFixed(1)) - const smallRight = smallLeft + Number(tempModule.width.toFixed(1)) - const smallBottom = smallTop + Number(tempModule.height.toFixed(1)) - const smallCenterX = smallLeft + Number((tempModule.width / 2).toFixed(1)) - const smallCenterY = smallTop + Number((tempModule.height / 2).toFixed(1)) + const smallLeft = toFixedWithoutRounding(tempModule.left, 2) + const smallTop = toFixedWithoutRounding(tempModule.top, 2) + const smallRight = smallLeft + toFixedWithoutRounding(tempModule.width, 2) + const smallBottom = smallTop + toFixedWithoutRounding(tempModule.height, 2) + const smallCenterX = smallLeft + toFixedWithoutRounding(tempModule.width / 2, 2) + const smallCenterY = smallTop + toFixedWithoutRounding(tempModule.height / 2, 2) /** * 미리 깔아놓은 셀이 있을때 셀에 흡착됨 */ if (manualDrawModules) { manualDrawModules.forEach((cell) => { - const holdCellLeft = cell.left - const holdCellTop = cell.top - const holdCellRight = holdCellLeft + Number(cell.width.toFixed(1)) - const holdCellBottom = holdCellTop + Number(cell.height.toFixed(1)) - const holdCellCenterX = holdCellLeft + Number((cell.width / 2).toFixed(1)) - const holdCellCenterY = holdCellTop + Number((cell.height / 2).toFixed(1)) + const holdCellLeft = toFixedWithoutRounding(cell.left, 2) + const holdCellTop = toFixedWithoutRounding(cell.top, 2) + const holdCellRight = holdCellLeft + toFixedWithoutRounding(cell.width, 2) + const holdCellBottom = holdCellTop + toFixedWithoutRounding(cell.height, 2) + const holdCellCenterX = holdCellLeft + toFixedWithoutRounding(cell.width / 2, 2) + const holdCellCenterY = holdCellTop + toFixedWithoutRounding(cell.height / 2, 2) + + //가운데 -> 가운대 + if (Math.abs(smallCenterX - holdCellCenterX) < snapDistance) { + tempModule.left = holdCellCenterX - toFixedWithoutRounding(width / 2, 2) + } + + //왼쪽 -> 가운데 + if (Math.abs(smallLeft - holdCellCenterX) < snapDistance) { + // console.log('holdCellCenterX', holdCellCenterX) + // console.log('smallLeft', smallLeft) + + // console.log('모듈 센터에 스냅') + tempModule.left = holdCellCenterX + intvHor / 2 + + // console.log('tempModule.left', tempModule.left) + } + // 오른쪽 -> 가운데 + if (Math.abs(smallRight - holdCellCenterX) < snapDistance) { + tempModule.left = holdCellCenterX - width - intvHor / 2 + } //설치된 셀에 좌측에 스냅 if (Math.abs(smallRight - holdCellLeft) < snapDistance) { + // console.log('모듈 좌측 스냅') tempModule.left = holdCellLeft - width - intvHor } //설치된 셀에 우측에 스냅 if (Math.abs(smallLeft - holdCellRight) < snapDistance) { + // console.log('모듈 우측 스냅') tempModule.left = holdCellRight + intvHor } - //설치된 셀에 위쪽에 스냅 - if (Math.abs(smallBottom - holdCellTop) < snapDistance) { + if (Math.abs(smallBottom - holdCellTop) < 10) { tempModule.top = holdCellTop - height - intvVer } //설치된 셀에 밑쪽에 스냅 - if (Math.abs(smallTop - holdCellBottom) < snapDistance) { + if (Math.abs(smallTop - holdCellBottom) < 10) { tempModule.top = holdCellBottom + intvVer } - //가운데 -> 가운데 - if (Math.abs(smallCenterX - holdCellCenterX) < snapDistance) { - tempModule.left = holdCellCenterX - Number((width / 2).toFixed(1)) - } - //왼쪽 -> 가운데 - if (Math.abs(smallLeft - holdCellCenterX) < snapDistance) { - tempModule.left = holdCellCenterX + intvHor - } - // 오른쪽 -> 가운데 - if (Math.abs(smallRight - holdCellCenterX) < snapDistance) { - tempModule.left = holdCellCenterX - width - intvHor + + //설치된 셀에 윗쪽에 스냅 + if (Math.abs(smallTop - holdCellTop) < 10) { + tempModule.top = holdCellTop } + //세로 가운데 -> 가운데 - if (Math.abs(smallCenterY - holdCellCenterY) < snapDistance) { - tempModule.top = holdCellCenterY - Number((height / 2).toFixed(1)) - } + // if (Math.abs(smallCenterY - holdCellCenterY) < snapDistance) { + // tempModule.top = holdCellCenterY - toFixedWithoutRounding(height / 2, 1) + // } // //위쪽 -> 가운데 // if (Math.abs(smallTop - holdCellCenterY) < cellSnapDistance) { // tempModule.top = holdCellCenterY @@ -700,13 +719,19 @@ export function useModuleBasicSetting(tabNum) { if (!inside) return if (tempModule) { const rectPoints = [ - { x: Number(tempModule.left.toFixed(1)), y: Number(tempModule.top.toFixed(1)) }, - { x: Number(tempModule.left.toFixed(1)) + Number(tempModule.width.toFixed(1)), y: Number(tempModule.top.toFixed(1)) }, + { x: toFixedWithoutRounding(tempModule.left, 2), y: toFixedWithoutRounding(tempModule.top, 2) }, { - x: Number(tempModule.left.toFixed(1)) + Number(tempModule.width.toFixed(1)), - y: Number(tempModule.top.toFixed(1)) + Number(tempModule.height.toFixed(1)), + x: toFixedWithoutRounding(tempModule.left, 2) + toFixedWithoutRounding(tempModule.width, 2), + y: toFixedWithoutRounding(tempModule.top, 2), + }, + { + x: toFixedWithoutRounding(tempModule.left, 2) + toFixedWithoutRounding(tempModule.width, 2), + y: toFixedWithoutRounding(tempModule.top, 2) + toFixedWithoutRounding(tempModule.height, 2), + }, + { + x: toFixedWithoutRounding(tempModule.left, 2), + y: toFixedWithoutRounding(tempModule.top, 2) + toFixedWithoutRounding(tempModule.height, 2), }, - { x: Number(tempModule.left.toFixed(1)), y: Number(tempModule.top.toFixed(1)) + Number(tempModule.height.toFixed(1)) }, ] tempModule.set({ points: rectPoints }) @@ -743,11 +768,13 @@ export function useModuleBasicSetting(tabNum) { let manualModule = new QPolygon(tempModule.points, { ...moduleOptions, moduleInfo: checkedModule[0], - left: Number(tempModule.left.toFixed(1)), - top: Number(tempModule.top.toFixed(1)), - width: Number(tempModule.width.toFixed(1)), - height: Number(tempModule.height.toFixed(1)), + left: toFixedWithoutRounding(tempModule.left, 2), + top: toFixedWithoutRounding(tempModule.top, 2), + width: toFixedWithoutRounding(tempModule.width, 2), + height: toFixedWithoutRounding(tempModule.height, 2), + toFixed: 2, }) + canvas?.add(manualModule) manualDrawModules.push(manualModule) setModuleStatisticsData() From 222dca6d14a4347ea7348c289196cd9c6d272931 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Fri, 14 Mar 2025 18:21:00 +0900 Subject: [PATCH 344/352] =?UTF-8?q?=EB=A7=A5=EC=8A=A4=2010=EB=A7=8C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../floor-plan/modal/setting01/planSize/PlanSizeSetting.jsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/floor-plan/modal/setting01/planSize/PlanSizeSetting.jsx b/src/components/floor-plan/modal/setting01/planSize/PlanSizeSetting.jsx index 10f9adc1..629b45d0 100644 --- a/src/components/floor-plan/modal/setting01/planSize/PlanSizeSetting.jsx +++ b/src/components/floor-plan/modal/setting01/planSize/PlanSizeSetting.jsx @@ -46,6 +46,10 @@ export default function PlanSizeSetting(props) { const changeInput = (value, e) => { const { name } = e.target + if (Number(value) > 100000) { + value = 100000 + } + setPlanSizeSettingMode((prev) => { return { ...prev, From a18ae6518d178d0bb176ca26bb28c85417dcf0e5 Mon Sep 17 00:00:00 2001 From: basssy Date: Mon, 17 Mar 2025 10:30:38 +0900 Subject: [PATCH 345/352] =?UTF-8?q?=EB=AC=BC=EA=B1=B4=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=20&=20=EA=B2=AC=EC=A0=81=EC=84=9C=20=EC=83=81=EC=84=B8=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=EB=AA=85=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/floor-plan/CanvasMenu.jsx | 59 ++++++++++++----------- src/components/management/StuffDetail.jsx | 16 +++--- 2 files changed, 40 insertions(+), 35 deletions(-) diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx index e10d9ebc..0d9ddc0a 100644 --- a/src/components/floor-plan/CanvasMenu.jsx +++ b/src/components/floor-plan/CanvasMenu.jsx @@ -89,11 +89,11 @@ export default function CanvasMenu(props) { const selectedRoofMaterial = useRecoilValue(selectedRoofMaterialSelector) //견적서버튼 노출용 - const [buttonStyle1, setButtonStyle1] = useState('') //문서 다운로드 버튼 - const [buttonStyle2, setButtonStyle2] = useState('') //저장 버튼 - const [buttonStyle3, setButtonStyle3] = useState('') //초기화 버튼 - const [buttonStyle4, setButtonStyle4] = useState('') //견적서 복사 버튼 - const [buttonStyle5, setButtonStyle5] = useState('') //잠금 버튼 + const [docDownButtonStyle, setDocDownButtonStyle] = useState('') //문서 다운로드 버튼 + const [saveButtonStyle, setSaveButtonStyle] = useState('') //저장 버튼 + const [resetButtonStyle, setResetButtonStyle] = useState('') //초기화 버튼 + const [copyButtonStyle, setCopyButtonStyle] = useState('') //견적서 복사 버튼 + const [lockButtonStyle, setLockButtonStyle] = useState('') //잠금 버튼 const setFloorPlanObjectNo = useSetRecoilState(floorPlanObjectState) //견적서 화면용 물건번호리코일 @@ -442,28 +442,28 @@ export default function CanvasMenu(props) { }, [estimateContextState?.createUser, estimateContextState?.tempFlg, estimateContextState?.lockFlg, estimateContextState.docNo]) const setAllButtonStyles = (style) => { - setButtonStyle1(style) - setButtonStyle2(style) - setButtonStyle3(style) - setButtonStyle4(style) - setButtonStyle5(style) + setDocDownButtonStyle(style) + setSaveButtonStyle(style) + setResetButtonStyle(style) + setCopyButtonStyle(style) + setLockButtonStyle(style) } const handleButtonStyles = (tempFlg, lockFlg, docNo) => { if (tempFlg === '1') { setAllButtonStyles('none') - setButtonStyle2('') + setSaveButtonStyle('') } else if (tempFlg === '0' && lockFlg === '0') { setAllButtonStyles('') } else { - setButtonStyle1('') - setButtonStyle2('none') - setButtonStyle3('none') - setButtonStyle4('') - setButtonStyle5('') + setDocDownButtonStyle('') + setSaveButtonStyle('none') + setResetButtonStyle('none') + setCopyButtonStyle('') + setLockButtonStyle('') } if (!docNo) { - setButtonStyle1('none') + setDocDownButtonStyle('none') } } @@ -513,11 +513,11 @@ export default function CanvasMenu(props) { // 문서다운로드 팝업에서 다운로드 하면 문서 잠금 const docDownPopLockFlg = () => { - setButtonStyle1('') - setButtonStyle2('none') - setButtonStyle3('none') - setButtonStyle4('') - setButtonStyle5('') + setDocDownButtonStyle('') + setSaveButtonStyle('none') + setResetButtonStyle('none') + setCopyButtonStyle('') + setLockButtonStyle('') } return ( @@ -627,17 +627,22 @@ export default function CanvasMenu(props) { > {getMessage('stuff.search.btn.register')} - - +
      +
      +
      +
      +
      + +
      + +
      + ) +} diff --git a/src/store/popupAtom.js b/src/store/popupAtom.js index 8cba0bdc..72acaee5 100644 --- a/src/store/popupAtom.js +++ b/src/store/popupAtom.js @@ -27,3 +27,15 @@ export const contextPopupPositionState = atom({ }, dangerouslyAllowMutability: true, }) + +/** 팝업 스피너 상태 */ +export const popSpinnerState = atom({ + key: 'popSpinnerStore', + default: false, +}) + +/** 프로미스 팝업 상태 - 테스트용(삭제 예정) */ +export const promisePopupState = atom({ + key: 'promisePopupStore', + default: false, +}) From 4d19788c52e6a2bd45e76c3424c05d5de1af11eb Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Mon, 17 Mar 2025 11:10:13 +0900 Subject: [PATCH 347/352] =?UTF-8?q?#909=20-=20=EA=B0=80=EB=8C=80=20?= =?UTF-8?q?=EC=84=A4=EC=B9=98=20=ED=9B=84=20=EA=B2=AC=EC=A0=81=EC=84=9C=20?= =?UTF-8?q?=EB=B0=94=EB=A1=9C=EA=B0=80=EA=B8=B0=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useEstimate.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hooks/useEstimate.js b/src/hooks/useEstimate.js index ac1f5c07..fae0b558 100644 --- a/src/hooks/useEstimate.js +++ b/src/hooks/useEstimate.js @@ -64,9 +64,10 @@ export function useEstimate() { // 캔버스 저장 await saveCanvas(false) + setIsGlobalLoading(false) /* 견적서 저장이 완료되면 견적서 페이지로 이동 */ - moveEstimate(planNo, objectNo) + // moveEstimate(planNo, objectNo) }) .catch((error) => { setIsGlobalLoading(false) From ec483a8bb8705bd364d1124efe4f03e016d71934 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Mon, 17 Mar 2025 14:11:19 +0900 Subject: [PATCH 348/352] =?UTF-8?q?=F0=9F=9A=A8chore:=20Sync=20Sass?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/styles/_modal.scss | 4305 +++++++++++++++++++--------------------- 1 file changed, 1998 insertions(+), 2307 deletions(-) diff --git a/src/styles/_modal.scss b/src/styles/_modal.scss index 58c6bc87..65b104b7 100644 --- a/src/styles/_modal.scss +++ b/src/styles/_modal.scss @@ -4,550 +4,531 @@ $pop-bold-weight: 500; $pop-normal-size: 12px; $alert-color: #101010; -@keyframes mountpop { - from { - opacity: 0; - scale: 0.95; - } - to { - opacity: 1; - scale: 1; - } +@keyframes mountpop{ + from{opacity: 0; scale: 0.95;} + to{opacity: 1; scale: 1;} } -@keyframes unmountpop { - from { - opacity: 1; - scale: 1; - } - to { - opacity: 0; - scale: 0.95; - } +@keyframes unmountpop{ + from{opacity: 1; scale: 1;} + to{opacity: 0; scale: 0.95;} } -.normal-font { - font-size: 12px; - font-weight: 400; - color: #fff; +.normal-font{ + font-size: 12px; + font-weight: 400; + color: #fff; } -.bold-font { - font-size: 12px; - font-weight: 500; - color: #fff; +.bold-font{ + font-size: 12px; + font-weight: 500; + color: #fff; } -.modal-pop-wrap { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: -webkit-fit-content; - height: -moz-fit-content; - height: fit-content; - border: 1px solid #000; - border-radius: 4px; - background-color: #272727; - z-index: 100000; - &.xsm { - width: 200px; - } - &.xxxm { - width: 240px; - } - &.xxm { - width: 270px; - } - &.xm { - width: 300px; - } - &.ssm { - width: 380px; - } - &.sm { - width: 580px; - } - &.r { - width: 400px; - } - &.lr { - width: 440px; - } - &.lr-2 { - width: 450px; - } - &.lrr { - width: 480px; - } - &.ml { - width: 530px; - } - &.l-2 { - width: 640px; - } - &.lx-2 { - width: 740px; - } - &.lx { - width: 770px; - } - &.l { - width: 800px; - } - &.ll { - width: 900px; - } - &.mount { - animation: mountpop 0.17s ease-in-out forwards; - } - &.unmount { - animation: unmountpop 0.17s ease-in-out forwards; - } - &.alert { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - background-color: transparent; - border: none; - .modal-head { - background-color: transparent; - padding: 0 0 8px; - .modal-close { - width: 20px; - height: 20px; - background: url(../../public/static/images/canvas/alert_close.svg) no-repeat center; - } - } - .modal-body { - background-color: #fff; - padding: 22px; - border-radius: 4px; - border: 1px solid #101010; - color: $alert-color; - .alert-title { - font-size: 13px; - font-weight: 700; - color: $alert-color; - margin-bottom: 15px; - } - } - } -} -.modal-head { - display: flex; - align-items: center; - padding: 10px 24px; - background-color: #000; - // overflow: hidden; - cursor: pointer; - h1.title { - font-size: 13px; - color: $pop-color; - font-weight: 700; - } - .modal-close { - margin-left: auto; - color: transparent; - font-size: 0; - width: 10px; - height: 10px; - background: url(../../public/static/images/canvas/modal_close.svg) no-repeat center; - } -} - -.modal-body { - position: relative; - padding: 24px; - .left-bar { - position: absolute; +.modal-pop-wrap{ + position: fixed; top: 0; left: 0; - width: 5px; - height: 100%; - background-color: #000; - cursor: pointer; - } - .right-bar { - position: absolute; - top: 0; - right: 0; - width: 5px; - height: 100%; - background-color: #000; - cursor: pointer; - } - .modal-btn-wrap { + width: 100%; + height: -webkit-fit-content; + height: -moz-fit-content; + height: fit-content; + border: 1px solid #000; + border-radius: 4px; + background-color: #272727; + z-index: 100000; + &.xsm{ + width: 200px; + } + &.xxxm{ + width: 240px; + } + &.xxm{ + width: 270px; + } + &.xm{ + width: 300px; + } + &.ssm{ + width: 380px; + } + &.sm{ + width: 580px; + } + &.r{ + width: 400px; + } + &.lr{ + width: 440px; + } + &.lr-2{ + width: 450px; + } + &.lrr{ + width: 480px; + } + &.ml{ + width: 530px; + } + &.l-2{ + width: 640px; + } + &.lx-2{ + width: 740px; + } + &.lx{ + width: 770px; + } + &.l{ + width: 800px; + } + &.ll{ + width: 900px; + } + &.mount{ + animation: mountpop .17s ease-in-out forwards; + } + &.unmount{ + animation: unmountpop .17s ease-in-out forwards; + } + &.alert{ + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background-color: transparent; + border: none; + .modal-head{ + background-color: transparent; + padding: 0 0 8px; + .modal-close{ + width: 20px; + height: 20px; + background: url(../../public/static/images/canvas/alert_close.svg)no-repeat center; + } + } + .modal-body{ + background-color: #fff; + padding: 22px; + border-radius: 4px; + border: 1px solid #101010; + color: $alert-color; + .alert-title{ + font-size: 13px; + font-weight: 700; + color: $alert-color; + margin-bottom: 15px; + } + } + } +} +.modal-head{ display: flex; align-items: center; - gap: 5px; - button { - flex: 1; + padding: 10px 24px; + background-color: #000; + // overflow: hidden; + cursor: pointer; + h1.title{ + font-size: 13px; + color: $pop-color; + font-weight: 700; } - &.sub { - button { - flex: 1 1 auto; - padding: 0; - } - margin-bottom: 14px; + .modal-close{ + margin-left: auto; + color: transparent; + font-size: 0; + width: 10px; + height: 10px; + background: url(../../public/static/images/canvas/modal_close.svg)no-repeat center; } - } - .modal-check-btn-wrap { - margin-top: 15px; - .check-wrap-title { - font-size: $pop-normal-size; - color: $pop-color; - font-weight: 600; - &.light { - font-weight: $pop-normal-weight; - } - } - .flex-check-box { - display: flex; - flex-wrap: wrap; - gap: 10px; - margin-top: 15px; - &.for2 { - justify-content: flex-end; - button { - width: calc(50% - 5px); - } - &.btn { - gap: 5px; - button { - width: calc(50% - 2.5px); - } - } - } - &.for-line { - button { - flex: 1; - } - } - } - } - .outer-line-wrap { - border-top: 1px solid #3c3c3c; - margin-top: 10px; - padding-top: 15px; - margin-bottom: 15px; - > div { - margin-bottom: 15px; - &:last-child { - margin-bottom: 0; - } - } - } - .modal-guide { - display: block; - font-size: $pop-normal-size; - color: $alert-color; - font-weight: $pop-normal-weight; - } -} -.modal-foot { - display: block; - width: 100%; - padding: 5px 0; - background-color: #000; - cursor: pointer; } -.adsorption-point { - display: flex; - align-items: center; - background-color: #3a3a3a; - border-radius: 3px; - padding-left: 11px; - overflow: hidden; - transition: all 0.17s ease-in-out; - span { - font-size: $pop-normal-size; - color: #898989; - } - i { +.modal-body{ + position: relative; + padding: 24px; + .left-bar{ + position: absolute; + top: 0; + left: 0; + width: 5px; + height: 100%; + background-color: #000; + cursor: pointer; + } + .right-bar{ + position: absolute; + top: 0; + right: 0; + width: 5px; + height: 100%; + background-color: #000; + cursor: pointer; + } + .modal-btn-wrap{ + display: flex; + align-items: center; + gap: 5px; + button{ + flex: 1; + } + &.sub{ + button{ + flex: 1 1 auto; + padding: 0; + } + margin-bottom: 14px; + } + } + .modal-check-btn-wrap{ + margin-top: 15px; + .check-wrap-title{ + font-size: $pop-normal-size; + color: $pop-color; + font-weight: 600; + &.light{ + font-weight: $pop-normal-weight; + } + } + .flex-check-box{ + display: flex; + flex-wrap: wrap; + gap: 10px; + margin-top: 15px; + &.for2{ + justify-content: flex-end; + button{ + width: calc(50% - 5px); + } + &.btn{ + gap: 5px; + button{ + width: calc(50% - 2.5px); + } + } + } + &.for-line{ + button{ + flex: 1; + } + } + } + } + .outer-line-wrap{ + border-top: 1px solid #3C3C3C; + margin-top: 10px; + padding-top: 15px; + margin-bottom: 15px; + > div{ + margin-bottom: 15px; + &:last-child{ + margin-bottom: 0; + } + } + } + .modal-guide{ + display: block; + font-size: $pop-normal-size; + color: $alert-color; + font-weight: $pop-normal-weight; + } +} +.modal-foot{ + display: block; + width: 100%; + padding: 5px 0; + background-color: #000; + cursor: pointer; +} + +.adsorption-point{ display: flex; align-items: center; - padding: 0 7px; - margin-left: auto; - height: 100%; - font-size: 13px; - color: #898989; - } - &.act { - i { - color: $pop-color; - background-color: #1083e3; + background-color: #3A3A3A; + border-radius: 3px; + padding-left: 11px; + overflow: hidden; + transition: all 0.17s ease-in-out; + span{ + font-size: $pop-normal-size; + color: #898989; + } + i{ + display: flex; + align-items: center; + padding: 0 7px; + margin-left: auto; + height: 100%; + font-size: 13px; + color: #898989; + } + &.act{ + i{ + color: $pop-color; + background-color: #1083E3; + } } - } } // grid-option -.grid-check-form { - display: flex; - align-items: center; - gap: 15px; - padding-bottom: 15px; - &.border { - border-bottom: 1px solid #424242; - } -} -.grid-check-form-block { - display: block; - > div { - margin-bottom: 10px; - } -} -.grid-option-overflow { - max-height: 350px; - overflow-y: auto; - &::-webkit-scrollbar { - width: 4px; - background-color: transparent; - } - &::-webkit-scrollbar-thumb { - background-color: #d9d9d9; - } - &::-webkit-scrollbar-track { - background-color: transparent; - } -} -.grid-option-wrap { - .grid-option-box { +.grid-check-form{ display: flex; align-items: center; - background-color: transparent; - border: 1px solid #3d3d3d; - border-radius: 2px; - padding: 15px 10px; - gap: 20px; - margin-bottom: 10px; - .grid-input-form { - display: flex; - align-items: center; - span { - flex: none; - font-size: $pop-normal-size; - color: $pop-color; - font-weight: $pop-bold-weight; - } - .input-grid { - width: 54px; - input { - width: 100%; - } - } + gap: 15px; + padding-bottom: 15px; + &.border{ + border-bottom: 1px solid #424242; } - &:last-child { - margin-bottom: 0; +} +.grid-check-form-block{ + display: block; + > div{ + margin-bottom: 10px; } - } - .grid-option-block-form { - flex: 1; - .flex-ment { - position: relative; - padding-right: 70px; - flex: 1 1 auto; - span { - width: 70px; - &.absol { - width: fit-content; - position: absolute; - top: 50%; - right: 0; - transform: translateY(-50%); +} +.grid-option-overflow{ + max-height: 350px; + overflow-y: auto; + &::-webkit-scrollbar { + width: 4px; + background-color: transparent; + } + &::-webkit-scrollbar-thumb { + background-color: #D9D9D9; + } + &::-webkit-scrollbar-track { + background-color: transparent; + } +} +.grid-option-wrap{ + .grid-option-box{ + display: flex; + align-items: center; + background-color: transparent; + border: 1px solid #3D3D3D; + border-radius: 2px; + padding: 15px 10px; + gap: 20px; + margin-bottom: 10px; + .grid-input-form{ + display: flex; + align-items: center; + span{ + flex: none; + font-size: $pop-normal-size; + color: $pop-color; + font-weight: $pop-bold-weight; + } + .input-grid{ + width: 54px; + input{ + width: 100%; + } + } } - } - .input-grid { + &:last-child{ + margin-bottom: 0; + } + } + .grid-option-block-form{ flex: 1; - } + .flex-ment{ + position: relative; + padding-right: 70px; + flex: 1 1 auto; + span{ + width: 70px; + &.absol{ + width: fit-content; + position: absolute; + top: 50%; + right: 0; + transform: translateY(-50%); + + } + } + .input-grid{ + flex: 1; + } + } } - } } -.select-form { - .sort-select { - width: 100%; - } +.select-form{ + .sort-select{width: 100%;} } -.grid-select { - flex: 1; - height: 30px; - &.no-flx { - flex: unset; - } - .sort-select { - width: 100%; - background-color: #313131; - min-width: auto; - font-size: 12px; - border: none; - p { - font-size: 12px; +.grid-select{ + flex: 1; + height: 30px; + &.no-flx{ + flex: unset; } - > ul { - border: none; + .sort-select{ + width: 100%; + background-color: #313131; + min-width: auto; + font-size: 12px; + border: none; + p{ + font-size: 12px; + } + > ul{ + border: none; + } } - } - &.right { - p { - text-align: right; + &.right{ + p{ + text-align: right; + } + ul{ + li{ + justify-content: flex-end; + } + } } - ul { - li { - justify-content: flex-end; - } - } - } } -.grid-btn-wrap { - padding-top: 15px; - text-align: right; - button { - padding: 0 10px; - } +.grid-btn-wrap{ + padding-top: 15px; + text-align: right; + button{ + padding: 0 10px; + } } // grid copy -.grid-option-tit { - font-size: $pop-normal-size; - color: $pop-color; - font-weight: $pop-normal-weight; - padding-bottom: 15px; +.grid-option-tit{ + font-size: $pop-normal-size; + color: $pop-color; + font-weight: $pop-normal-weight; + padding-bottom: 15px; + } -.grid-direction { - display: flex; - align-items: center; - gap: 5px; - flex: 1; +.grid-direction{ + display: flex; + align-items: center; + gap: 5px; + flex: 1; } -.direction { - width: 22px; - height: 22px; - background-color: #757575; - background-image: url(../../public/static/images/canvas/grid_option_arr.svg); - background-repeat: no-repeat; - background-position: center; - background-size: 16px 15px; - border-radius: 50%; - transition: all 0.15s ease-in-out; - opacity: 0.6; - &.down { - transform: rotate(180deg); - } - &.left { - transform: rotate(-90deg); - } - &.right { - transform: rotate(90deg); - } - &:hover, - &.act { - opacity: 1; - } +.direction{ + width: 22px; + height: 22px; + background-color: #757575; + background-image: url(../../public/static/images/canvas/grid_option_arr.svg); + background-repeat: no-repeat; + background-position: center; + background-size: 16px 15px; + border-radius: 50%; + transition: all .15s ease-in-out; + opacity: 0.6; + &.down{transform: rotate(180deg);} + &.left{transform: rotate(-90deg);} + &.right{transform: rotate(90deg);} + &:hover, + &.act{ + opacity: 1; + } } // grid-move -.move-form { - width: 100%; - p { - font-size: $pop-normal-size; - color: $pop-color; - font-weight: $pop-bold-weight; - } -} -.input-move-wrap { - display: flex; - align-items: center; - gap: 5px; - span { - color: $pop-color; - font-size: $pop-normal-size; - } - .input-move { - width: 130px; - input { - width: 100%; - } - } -} -.direction-move-wrap { - flex: none; - display: grid; - grid-template-columns: 1fr 1fr; - gap: 5px; - margin-left: auto; -} - -// 배치면 초기 설정 -.placement-table { - table { - table-layout: fixed; - tr { - th { +.move-form{ + width: 100%; + p{ font-size: $pop-normal-size; color: $pop-color; font-weight: $pop-bold-weight; - padding: 18px 0; - border-bottom: 1px solid #424242; - vertical-align: middle; - .tip-wrap { - display: flex; - align-items: center; - } - } - td { - font-size: $pop-normal-size; + } +} +.input-move-wrap{ + display: flex; + align-items: center; + gap: 5px; + span{ color: $pop-color; - border-bottom: 1px solid #424242; - padding: 18px 0 18px 20px; - vertical-align: middle; - .flex-box { - display: flex; - align-items: center; - } - } - &:first-child { - td, - th { - padding-top: 0; - } - } + font-size: $pop-normal-size; } - } - .tooltip { - position: relative; - display: block; - width: 15px; - height: 15px; - margin-left: 5px; - background: url(../../public/static/images/canvas/pop_tip.svg) no-repeat center; - background-size: cover; - } - &.light { - padding: 0; - th, - td { - color: $alert-color; - border-bottom: none; - border-top: 1px solid #efefef; - } - th { - padding: 14px 0; - } - tr { - &:first-child { - td, - th { - padding-top: 14px; + .input-move{ + width: 130px; + input{ + width: 100%; + } + } +} +.direction-move-wrap{ + flex: none; + display: grid; + grid-template-columns: 1fr 1fr; + gap: 5px; + margin-left: auto; +} + +// 배치면 초기 설정 +.placement-table{ + table{ + table-layout: fixed; + tr{ + th{ + font-size: $pop-normal-size; + color: $pop-color; + font-weight: $pop-bold-weight; + padding: 18px 0; + border-bottom: 1px solid #424242; + vertical-align: middle; + .tip-wrap{ + display: flex; + align-items: center; + } + } + td{ + font-size: $pop-normal-size; + color: $pop-color; + border-bottom: 1px solid #424242; + padding: 18px 0 18px 20px; + vertical-align: middle; + .flex-box{ + display: flex; + align-items: center; + } + } + &:first-child{ + td, + th{ + padding-top: 0; + } + } + } + } + .tooltip{ + position: relative; + display: block; + width: 15px; + height: 15px; + margin-left: 5px; + background: url(../../public/static/images/canvas/pop_tip.svg)no-repeat center; + background-size: cover; + } + &.light{ + padding: 0; + th,td{ + color: $alert-color; + border-bottom: none; + border-top: 1px solid #EFEFEF; + } + th{ + padding: 14px 0; + } + tr{ + &:first-child{ + td, + th{ + padding-top: 14px; + } + } + &:last-child{ + td, + th{ + padding-bottom: 0px; + } + } } - } - &:last-child { - td, - th { - padding-bottom: 0px; - } - } } - } } // 2024-12-11 @@ -558,1984 +539,1694 @@ $alert-color: #101010; // max-width: 250px; // } -.pop-form-radio { - display: flex; - align-items: center; - gap: 10px; - &.place { - gap: 33px; - .outline-form { - span { - width: fit-content; - } - .input-grid { - width: 80px; - } - } - } -} -.placement-option { - display: flex; - align-items: center; - gap: 20px; -} -.select-wrap { - .sort-select { - width: 100%; - } -} -.flex-ment { - display: flex; - align-items: center; - gap: 5px; - span { - font-size: $pop-normal-size; - color: $pop-color; - font-weight: $pop-normal-weight; - } -} - -.img-edit-wrap { - flex: none; - .img-edit-btn { +.pop-form-radio{ display: flex; align-items: center; - height: 30px; - padding: 0 10px; - font-size: 12px; - font-weight: 400; - color: #101010; - background-color: #fff; - border-radius: 2px; - cursor: pointer; - transition: all 0.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; + gap: 10px; + &.place{ + gap: 33px; + .outline-form{ + span{ + width: fit-content; + } + .input-grid{ + width: 80px; + } + } } - &: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); - } +.placement-option{ + display: flex; + align-items: center; + gap: 20px; +} +.select-wrap{ + .sort-select{ + width: 100%; + } +} +.flex-ment{ + display: flex; + align-items: center; + gap: 5px; + span{ + font-size: $pop-normal-size; + color: $pop-color; + font-weight: $pop-normal-weight; + } + } -.for-address { - input { - flex: 1; - } - .check-address { +.img-edit-wrap{ flex: none; - width: 18px; - height: 18px; - margin-left: 5px; - background-repeat: no-repeat; - background-position: center; - background-size: cover; - &.fail { - background-image: url(../../public/static/images/canvas/img_check_fail.svg); + .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; + cursor: pointer; + 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; + } } - &.success { - background-image: url(../../public/static/images/canvas/img_check_success.svg); +} +.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); + } +} + +.for-address{ + input{ + flex: 1; + } + .check-address{ + flex: none; + width: 18px; + height: 18px; + margin-left: 5px; + background-repeat: no-repeat; + background-position: center; + background-size: cover; + &.fail{background-image: url(../../public/static/images/canvas/img_check_fail.svg);} + &.success{background-image: url(../../public/static/images/canvas/img_check_success.svg);} } - } } // 외벽선 그리기 -.outline-wrap { - padding: 24px 0; - border-top: 1px solid #424242; - - .outline-inner { +.outline-wrap{ + padding: 24px 0; + border-top: 1px solid #424242; + + .outline-inner{ + display: flex; + align-items: center; + margin-bottom: 14px; + &:last-child{ + margin-bottom: 0; + } + .outline-form{ + // width: 50%; + margin-right: 15px; + } + } + &:last-child{ + border-bottom: 1px solid #424242; + } +} +.outline-form{ display: flex; align-items: center; - margin-bottom: 14px; - &:last-child { - margin-bottom: 0; + + span{ + width: 60px; + flex: none; + font-size: $pop-normal-size; + font-weight: $pop-bold-weight; + color: $pop-color; + margin-right: 10px; + &.thin{ + width: auto; + font-weight: $pop-normal-weight; + margin-right: 0; + } } - .outline-form { - // width: 50%; - margin-right: 15px; - } - } - &:last-child { - border-bottom: 1px solid #424242; - } -} -.outline-form { - display: flex; - align-items: center; - span { - width: 60px; - flex: none; - font-size: $pop-normal-size; - font-weight: $pop-bold-weight; - color: $pop-color; - margin-right: 10px; - &.thin { - width: auto; - font-weight: $pop-normal-weight; - margin-right: 0; + .reset-btn{ + flex: none; + width: 30px; + height: 30px; + background: transparent; + border: 1px solid #484848; + border-radius: 2px; + margin-left: 5px; + background-image: url(../../public/static/images/canvas/reset_ico.svg); + background-repeat: no-repeat; + background-size: 12px 12px; + background-position: center; + } + &:last-child{ + margin-right: 0; } - } - - .reset-btn { - flex: none; - width: 30px; - height: 30px; - background: transparent; - border: 1px solid #484848; - border-radius: 2px; - margin-left: 5px; - background-image: url(../../public/static/images/canvas/reset_ico.svg); - background-repeat: no-repeat; - background-size: 12px 12px; - background-position: center; - } - &:last-child { - margin-right: 0; - } } -.cul-wrap { - display: flex; - .outline-box { - width: 50%; - margin-right: 15px; - .outline-form { - width: 100%; - margin-bottom: 14px; - margin-right: 0; - &:last-child { - margin-bottom: 0; - } - } - } - .cul-box { +.cul-wrap{ display: flex; - align-items: center; - justify-content: center; - width: 50%; - background-color: #3d3d3d; - border-radius: 2px; - } + .outline-box{ + width: 50%; + margin-right: 15px; + .outline-form{ + width: 100%; + margin-bottom: 14px; + margin-right: 0; + &:last-child{ + margin-bottom: 0; + } + } + } + .cul-box{ + display: flex; + align-items: center; + justify-content: center; + width: 50%; + background-color: #3D3D3D; + border-radius: 2px ; + } } // 외벽선 속성 설정 -.properties-guide { - font-size: $pop-normal-size; - color: #aaa; - font-weight: $pop-normal-weight; - margin-bottom: 14px; +.properties-guide{ + font-size: $pop-normal-size; + color: #AAA; + font-weight: $pop-normal-weight; + margin-bottom: 14px; } -.setting-tit { - font-size: 13px; - color: $pop-color; - font-weight: $pop-bold-weight; - margin-bottom: 10px; +.setting-tit{ + font-size: 13px; + color: $pop-color; + font-weight: $pop-bold-weight; + margin-bottom: 10px; } -.properties-setting-wrap { - &.outer { - margin-top: 24px; - } - .setting-btn-wrap { - display: flex; - align-items: center; - padding: 14px 0; - border-top: 1px solid #424242; - border-bottom: 1px solid #424242; - .setting-btn { - display: block; - width: 100%; - height: 40px; - font-size: 13px; - color: #fff; - font-weight: 700; - border-radius: 2px; - transition: all 0.15s ease-in-out; - &.green { - background-color: #305941; - border: 1px solid #45cd7d; - &:hover { - background-color: #3a6b4e; - } - } - &.blue { - background-color: #2e5360; - border: 1px solid #3fbae6; - &:hover { - background-color: #365f6e; - } - } - &.gray { - background-color: #535353; - border: 1px solid #9e9e9e; - &:hover { - background-color: #6b6b6b; - } - } +.properties-setting-wrap{ + &.outer{ + margin-top: 24px; + } + .setting-btn-wrap{ + display: flex; + align-items: center; + padding: 14px 0; + border-top: 1px solid #424242; + border-bottom: 1px solid #424242; + .setting-btn{ + display: block; + width: 100%; + height: 40px; + font-size: 13px; + color: #fff; + font-weight: 700; + border-radius: 2px; + transition: all .15s ease-in-out; + &.green{ + background-color: #305941; + border: 1px solid #45CD7D; + &:hover{ + background-color: #3a6b4e; + } + } + &.blue{ + background-color: #2E5360; + border: 1px solid #3FBAE6; + &:hover{ + background-color: #365f6e; + } + } + &.gray{ + background-color: #535353; + border: 1px solid #9e9e9e; + &:hover{ + background-color: #6b6b6b; + } + } + } } - } } // 지붕형상 설정 -.roof-shape-menu { - display: grid; - grid-template-columns: 1fr 1fr 1fr 1fr; - grid-template-rows: 1fr 1fr; - gap: 24px 10px; - margin-bottom: 24px; - .shape-box { - display: flex; - align-items: center; - justify-content: center; - width: 100%; - padding: 13px; - background-color: #3d3d3d; - transition: background 0.15s ease-in-out; - img { - max-width: 100%; - } - } - .shape-title { - font-size: $pop-normal-size; - font-weight: $pop-bold-weight; - color: $pop-color; - margin-top: 10px; - text-align: center; - transition: color 0.15s ease-in-out; - } - .shape-menu-box { - &.act, - &:hover { - .shape-box { - background-color: #008bff; - } - .shape-title { - color: #008bff; - } - } - } -} - -.setting-box { - padding: 14px 0; - border-top: 1px solid #424242; - border-bottom: 1px solid #424242; -} -.padding-form { - padding-left: 23px; -} -.discrimination-box { - padding: 16px 12px; - border: 1px solid #3d3d3d; - border-radius: 2px; -} - -.modal-bottom-border-bx { - margin-top: 24px; - padding-bottom: 14px; - border-bottom: 1px solid #424242; -} - -// 처마∙케라바 변경 -.eaves-keraba-table { - display: table; - border-collapse: collapse; - .eaves-keraba-item { - display: table-row; - .eaves-keraba-th, - .eaves-keraba-td { - font-size: $pop-normal-size; - color: $pop-color; - font-weight: $pop-normal-weight; - display: table-cell; - vertical-align: middle; - padding-bottom: 14px; - } - .eaves-keraba-td { - padding-left: 10px; - } - .eaves-keraba-ico { - display: flex; - align-items: center; - justify-content: center; - padding: 5px; - background-color: #3d3d3d; - border: 1px solid #3d3d3d; - border-radius: 2px; - cursor: pointer; - &.act { - border: 1px solid #ed0004; - } - } - &:last-child { - .eaves-keraba-th, - .eaves-keraba-td { - padding-bottom: 0; - } - } - } -} -.guide { - font-size: $pop-normal-size; - font-weight: $pop-normal-weight; - color: $pop-color; - margin-bottom: 24px; - &.sm { - margin-bottom: 15px; - } - span { - display: block; - } -} - -// 지붕면 할당 -.allocation-select-wrap { - display: flex; - align-items: center; - padding-bottom: 14px; - border-bottom: 1px solid #424242; - margin-bottom: 14px; - span { - font-size: $pop-normal-size; - color: $pop-color; - font-weight: $pop-bold-weight; - margin-right: 10px; - } - .allocation-edit { - display: flex; - align-items: center; - justify-content: center; - width: 100%; - height: 30px; - padding: 0 10px; - margin-left: 5px; - font-size: $pop-normal-size; - color: $pop-color; - font-weight: $pop-normal-weight; - border: 1px solid #484848; - background-color: #323234; - transition: background-color 0.13s ease-in-out; - i { - display: block; - width: 12px; - height: 12px; - margin-right: 5px; - background: url(../../public/static/images/canvas/allocation_edit.svg) no-repeat center; - background-size: cover; - } - &:hover { - background-color: #464545; - } - } -} - -.block-box { - display: flex; - align-items: center; - gap: 10px; - margin-bottom: 10px; - .flex-ment { - gap: 10px; - .dec { - text-decoration: underline; - } - .delete { - display: block; - width: 15px; - height: 15px; - background: url(../../public/static/images/canvas/allocation_delete.svg) no-repeat center; - background-size: cover; - } - } - &:last-child { - margin-bottom: 0; - } -} - -.icon-btn-wrap { - flex: 1; - display: flex; - align-items: center; - gap: 5px; - button { - display: flex; - align-items: center; - justify-content: center; - width: 100%; - height: 30px; - font-size: $pop-normal-size; - font-weight: $pop-normal-weight; - color: $pop-color; - border: 1px solid #646464; - border-radius: 2px; - padding: 0 10px; - transition: all 0.15s ease-in-out; - i { - height: 15px; - display: block; - margin-left: 10px; - background-repeat: no-repeat; - background-position: center; - background-size: cover; - transition: all 0.15s ease-in-out; - &.allocation01 { - background-image: url(../../public/static/images/canvas/allocation_icon01_white.svg); - width: 15px; - } - &.allocation02 { - background-image: url(../../public/static/images/canvas/allocation_icon02_white.svg); - width: 18px; - } - } - &.act, - &:hover { - color: #101010; - border: 1px solid #101010; - background-color: #fff; - i { - &.allocation01 { - background-image: url(../../public/static/images/canvas/allocation_icon01_black.svg); - } - &.allocation02 { - background-image: url(../../public/static/images/canvas/allocation_icon02_black.svg); - } - } - } - &:disabled { - color: $pop-color; - border: 1px solid #646464; - background-color: transparent; - opacity: 0.5; - &.act, - &:hover { - color: $pop-color; - border: 1px solid #646464; - background-color: transparent; - i { - &.allocation01 { - background-image: url(../../public/static/images/canvas/allocation_icon01_white.svg); - } - &.allocation02 { - background-image: url(../../public/static/images/canvas/allocation_icon02_white.svg); - } - } - } - } - } -} - -// 경사설정 -.slope-wrap { - padding-bottom: 24px; - border-bottom: 1px solid #424242; -} - -// 면형상 배치 -.plane-frame-wrap { - display: flex; - gap: 10px; - .plane-shape-wrap { - flex: none; - width: 73px; - } -} - -.plane-shape-menu { - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 5px; - .shape-menu-box { - border-radius: 2px; - width: 34px; - height: 34px; - background-color: #373737; - border: 1px solid #676767; - transition: - background 0.15s ease-in-out, - border 0.15s ease-in-out; - .shape-box { - display: flex; - justify-content: center; - align-items: center; - position: relative; - width: 100%; - height: 100%; - border-radius: 2px; - } - &.act, - &:hover { - border-color: #008bff; - background-color: #008bff; - } - } -} - -.shape-library { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - gap: 5px; - padding-top: 5px; - .library-btn { - width: 100%; - height: 34px; - border: 1px solid #6c6c6c; - border-radius: 2px; - background-color: #373737; - background-repeat: no-repeat; - background-position: center; - transition: all 0.15s ease-in-out; - &.ico01 { - background-image: url(../../public/static/images/canvas/shape_labrary01.svg); - background-size: 19px 18px; - } - &.ico02 { - background-image: url(../../public/static/images/canvas/shape_labrary02.svg); - background-size: 15px 20px; - } - &.ico03 { - background-image: url(../../public/static/images/canvas/shape_labrary03.svg); - background-size: 19px 16px; - } - &:hover { - border-color: #1083e3; - background-color: #1083e3; - } - } -} - -.plane-detail-wrap { - display: flex; - flex-direction: column; - flex: 1; -} -.plane-shape-wrapper { - flex: 1; - display: flex; - flex-direction: column; - gap: 10px; - .plane-box { - width: 100%; - padding: 10px 18px; - border-radius: 2px; - background-color: #313131; - border: 1px solid #484848; - .plane-box-tit { - font-size: $pop-normal-size; - font-weight: 600; - color: $pop-color; - margin-bottom: 10px; - } - &.shape-box { - .shape-box-inner { - display: flex; - gap: 15px; - min-height: 140px; - .shape-img { - position: relative; - flex: none; - width: 150px; - background-color: #fff; - border-radius: 2px; - img { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - } - } - .shape-data { - flex: 1; - .eaves-keraba-table { - .eaves-keraba-item { - .eaves-keraba-th, - .eaves-keraba-td { - padding-bottom: 10px; - } - &:last-child { - .eaves-keraba-th, - .eaves-keraba-td { - padding-bottom: 0px; - } - } - } - } - } - } - } - &.direction-box { - flex: 1; - display: flex; - flex-direction: column; - .plane-direction-box { - flex: 1; +.roof-shape-menu{ + display: grid; + grid-template-columns: 1fr 1fr 1fr 1fr; + grid-template-rows: 1fr 1fr; + gap: 24px 10px; + margin-bottom: 24px; + .shape-box{ display: flex; align-items: center; justify-content: center; width: 100%; - } + padding: 13px; + background-color: #3D3D3D; + transition: background .15s ease-in-out; + img{ + max-width: 100%; + } } - } -} -.plane-direction { - width: 150px; - position: relative; - height: 120px; - span { - position: absolute; - font-size: 12px; - font-weight: 500; - color: #b1b1b1; - &.top { - top: 0; - left: 50%; - transform: translateX(-50%); + .shape-title{ + font-size: $pop-normal-size; + font-weight: $pop-bold-weight; + color: $pop-color; + margin-top: 10px; + text-align: center; + transition: color .15s ease-in-out; } - &.right { - top: 50%; - right: 0; - transform: translateY(-50%); + .shape-menu-box{ + &.act, + &:hover{ + .shape-box{background-color: #008BFF;} + .shape-title{color: #008BFF;} + } } - &.bottom { - bottom: 0; - left: 50%; - transform: translateX(-50%); - } - &.left { - top: 50%; - left: 0; - transform: translateY(-50%); - } - } - .plane-btn { - position: absolute; - width: 28px; - height: 28px; - background-color: #777777; - background-image: url(../../public/static/images/canvas/plane_arr.svg); - background-size: 12px 13px; - background-repeat: no-repeat; - background-position: center; - border-radius: 50%; - transition: all 0.15s ease-in-out; - &.up { - top: 22px; - left: 50%; - transform: translateX(-50%); - } - &.right { - top: 50%; - right: 32px; - transform: translateY(-50%) rotate(90deg); - } - &.down { - bottom: 22px; - left: 50%; - transform: translateX(-50%) rotate(180deg); - } - &.left { - top: 50%; - left: 32px; - transform: translateY(-50%) rotate(270deg); - } - &:hover, - &.act { - background-color: #fff; - background-image: url(../../public/static/images/canvas/plane_arr_act.svg); - } - } } -.plane-tab-guide { - font-size: $pop-normal-size; - font-weight: $pop-normal-weight; - color: $pop-color; - margin-top: 10px; +.setting-box{ + padding: 14px 0; + border-top: 1px solid #424242; + border-bottom: 1px solid #424242; } -.plane-shape-btn { - padding-top: 10px; - margin-top: auto; - button { - display: block; - width: 100%; - } +.padding-form{ + padding-left: 23px; +} +.discrimination-box{ + padding: 16px 12px; + border: 1px solid #3D3D3D; + border-radius: 2px; } -// 오브젝트 배치 -.mb-box { - margin-bottom: 24px; +.modal-bottom-border-bx{ + margin-top: 24px; + padding-bottom: 14px; + border-bottom: 1px solid #424242; } -.object-direction-wrap { - display: flex; - align-items: center; - justify-content: center; -} -.discrimination-tit { - font-size: 13px; - color: #fff; - font-weight: 500; -} - -.object-size-wrap { - display: flex; - min-height: 206px; - margin-top: 14px; - .object-size-img { - position: relative; - flex: none; - width: 200px; - background-color: #fff; - img { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); +// 처마∙케라바 변경 +.eaves-keraba-table{ + display: table; + border-collapse: collapse; + .eaves-keraba-item{ + display: table-row; + .eaves-keraba-th, + .eaves-keraba-td{ + font-size: $pop-normal-size; + color: $pop-color; + font-weight: $pop-normal-weight; + display: table-cell; + vertical-align: middle; + padding-bottom: 14px; + } + .eaves-keraba-td{ + padding-left: 10px; + } + .eaves-keraba-ico{ + display: flex; + align-items: center; + justify-content: center; + padding: 5px; + background-color: #3D3D3D; + border: 1px solid #3D3D3D; + border-radius: 2px; + cursor: pointer; + &.act{ + border: 1px solid #ED0004; + } + } + &:last-child{ + .eaves-keraba-th, + .eaves-keraba-td{ + padding-bottom: 0; + } + } } - } - .object-size-input { - margin-left: auto; - .eaves-keraba-th { - position: relative; - .object-input-num { - position: absolute; - top: 7px; - left: -20px; - font-size: 13px; - } +} +.guide{ + font-size: $pop-normal-size; + font-weight: $pop-normal-weight; + color: $pop-color; + margin-bottom: 24px; + &.sm{ + margin-bottom: 15px; + } + span{ + display: block; } - } } -// 표시변경 -.display-change-wrap { - margin: 24px 0; -} -.warning { - font-size: $pop-normal-size; - font-weight: $pop-normal-weight; - color: #ffafaf; +// 지붕면 할당 +.allocation-select-wrap{ + display: flex; + align-items: center; + padding-bottom: 14px; + border-bottom: 1px solid #424242; + margin-bottom: 14px; + span{ + font-size: $pop-normal-size; + color: $pop-color; + font-weight: $pop-bold-weight; + margin-right: 10px; + } + .allocation-edit{ + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 30px; + padding: 0 10px; + margin-left: 5px; + font-size: $pop-normal-size; + color: $pop-color; + font-weight: $pop-normal-weight; + border: 1px solid #484848; + background-color: #323234; + transition: background-color .13s ease-in-out; + i{ + display: block; + width: 12px; + height: 12px; + margin-right: 5px; + background: url(../../public/static/images/canvas/allocation_edit.svg)no-repeat center; + background-size: cover; + } + &:hover{ + background-color: #464545; + } + } } -// 각 변 속성 변경 -.radio-grid-wrap { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 24px 15px; +.block-box{ + display: flex; + align-items: center; + gap: 10px; + margin-bottom: 10px; + .flex-ment{ + gap: 10px; + .dec{ + text-decoration: underline; + } + .delete{ + display: block; + width: 15px; + height: 15px; + background: url(../../public/static/images/canvas/allocation_delete.svg)no-repeat center; + background-size: cover; + } + } + &:last-child{ + margin-bottom: 0; + } } -// 면 흐름 설정 -.drawing-flow-wrap { - display: flex; - gap: 10px; - .discrimination-box { +.icon-btn-wrap{ + flex: 1; + display: flex; + align-items: center; + gap: 5px; + button{ + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 30px; + font-size: $pop-normal-size; + font-weight: $pop-normal-weight; + color: $pop-color; + border: 1px solid #646464; + border-radius: 2px; + padding: 0 10px; + transition: all .15s ease-in-out; + i{ + height: 15px; + display: block; + margin-left: 10px; + background-repeat: no-repeat; + background-position: center; + background-size: cover; + transition: all .15s ease-in-out; + &.allocation01{ + background-image: url(../../public/static/images/canvas/allocation_icon01_white.svg); + width: 15px; + } + &.allocation02{ + background-image: url(../../public/static/images/canvas/allocation_icon02_white.svg); + width: 18px; + } + } + &.act, + &:hover{ + color: #101010; + border: 1px solid #101010; + background-color: #fff; + i{ + &.allocation01{ + background-image: url(../../public/static/images/canvas/allocation_icon01_black.svg); + } + &.allocation02{ + background-image: url(../../public/static/images/canvas/allocation_icon02_black.svg); + } + } + } + &:disabled{ + color: $pop-color; + border: 1px solid #646464; + background-color: transparent; + opacity: 0.5; + &.act, + &:hover{ + color: $pop-color; + border: 1px solid #646464; + background-color: transparent; + i{ + &.allocation01{ + background-image: url(../../public/static/images/canvas/allocation_icon01_white.svg); + } + &.allocation02{ + background-image: url(../../public/static/images/canvas/allocation_icon02_white.svg); + } + } + } + } + } +} + +// 경사설정 +.slope-wrap{ + padding-bottom: 24px; + border-bottom: 1px solid #424242; +} + +// 면형상 배치 +.plane-frame-wrap{ + display: flex; + gap: 10px; + .plane-shape-wrap{ + flex: none; + width: 73px; + } +} + +.plane-shape-menu{ + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 5px; + .shape-menu-box{ + border-radius: 2px; + width: 34px; + height: 34px; + background-color: #373737; + border: 1px solid #676767; + transition: background .15s ease-in-out, border .15s ease-in-out; + .shape-box{ + display: flex; + justify-content: center; + align-items: center; + position: relative; + width: 100%; + height: 100%; + border-radius: 2px; + } + &.act, + &:hover{ + border-color: #008BFF; + background-color: #008BFF; + } + } +} + +.shape-library{ + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 5px; + padding-top: 5px; + .library-btn{ + width: 100%; + height: 34px; + border: 1px solid #6C6C6C; + border-radius: 2px; + background-color: #373737; + background-repeat: no-repeat; + background-position: center; + transition: all .15s ease-in-out; + &.ico01{background-image: url(../../public/static/images/canvas/shape_labrary01.svg); background-size: 19px 18px;} + &.ico02{background-image: url(../../public/static/images/canvas/shape_labrary02.svg); background-size: 15px 20px;} + &.ico03{background-image: url(../../public/static/images/canvas/shape_labrary03.svg); background-size: 19px 16px;} + &:hover{ + border-color: #1083E3; + background-color: #1083E3; + } + } +} + +.plane-detail-wrap{ + display: flex; + flex-direction: column; + flex: 1; +} +.plane-shape-wrapper{ flex: 1; display: flex; flex-direction: column; - .object-direction-wrap { - flex: 1; + gap: 10px; + .plane-box{ + width: 100%; + padding: 10px 18px; + border-radius: 2px; + background-color: #313131; + border: 1px solid #484848; + .plane-box-tit{ + font-size: $pop-normal-size; + font-weight: 600; + color: $pop-color; + margin-bottom: 10px; + } + &.shape-box{ + .shape-box-inner{ + display: flex; + gap:15px; + min-height: 140px; + .shape-img{ + position: relative; + flex: none; + width: 150px; + background-color: #fff; + border-radius: 2px; + img{ + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + } + } + .shape-data{ + flex: 1; + .eaves-keraba-table{ + .eaves-keraba-item{ + .eaves-keraba-th, + .eaves-keraba-td{ + padding-bottom: 10px; + } + &:last-child{ + .eaves-keraba-th, + .eaves-keraba-td{ + padding-bottom: 0px; + } + } + } + } + } + } + } + &.direction-box{ + flex: 1; + display: flex; + flex-direction: column; + .plane-direction-box{ + flex: 1; + display: flex; + align-items: center; + justify-content: center; + width: 100%; + } + } } - &:first-child { - flex: none; - width: 195px; +} +.plane-direction{ + width: 150px; + position: relative; + height: 120px; + span{ + position: absolute; + font-size: 12px; + font-weight: 500; + color: #B1B1B1; + &.top{top: 0; left: 50%; transform: translateX(-50%);} + &.right{top: 50%; right: 0; transform: translateY(-50%);} + &.bottom{bottom: 0; left: 50%; transform: translateX(-50%);} + &.left{top: 50%; left: 0; transform: translateY(-50%);} + } + .plane-btn{ + position: absolute; + width: 28px; + height: 28px; + background-color: #777777; + background-image: url(../../public/static/images/canvas/plane_arr.svg); + background-size: 12px 13px; + background-repeat: no-repeat; + background-position: center; + border-radius: 50%; + transition: all .15s ease-in-out; + &.up{top: 22px; left: 50%; transform: translateX(-50%);} + &.right{top: 50%; right: 32px; transform: translateY(-50%) rotate(90deg);} + &.down{bottom: 22px; left: 50%; transform: translateX(-50%) rotate(180deg);} + &.left{top: 50%; left: 32px; transform: translateY(-50%) rotate(270deg);} + &:hover, + &.act{ + background-color: #fff; + background-image: url(../../public/static/images/canvas/plane_arr_act.svg); + } } - } } -.compas-box { - display: flex; - align-items: center; - justify-content: center; +.plane-tab-guide{ + font-size: $pop-normal-size; + font-weight: $pop-normal-weight; + color: $pop-color; + margin-top: 10px; +} +.plane-shape-btn{ + padding-top: 10px; + margin-top: auto; + button{ + display: block; + width: 100%; + } +} + +// 오브젝트 배치 +.mb-box{ + margin-bottom: 24px; +} + +.object-direction-wrap{ + display: flex; + align-items: center; + justify-content: center; +} +.discrimination-tit{ + font-size: 13px; + color: #fff; + font-weight: 500; +} + +.object-size-wrap{ + display: flex; + min-height: 206px; + margin-top: 14px; + .object-size-img{ + position: relative; + flex: none; + width: 200px; + background-color: #fff; + img{ + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + } + } + .object-size-input{ + margin-left: auto; + .eaves-keraba-th{ + position: relative; + .object-input-num{ + position: absolute; + top: 7px; + left: -20px; + font-size: 13px; + } + } + } +} + +// 표시변경 +.display-change-wrap{ + margin: 24px 0; +} +.warning{ + font-size: $pop-normal-size; + font-weight: $pop-normal-weight; + color: #FFAFAF; +} + +// 각 변 속성 변경 +.radio-grid-wrap{ + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 24px 15px; +} + +// 면 흐름 설정 +.drawing-flow-wrap{ + display: flex; + gap: 10px; + .discrimination-box{ + flex: 1; + display: flex; + flex-direction: column; + .object-direction-wrap{ + flex: 1; + } + &:first-child{ + flex: none; + width: 195px; + } + } +} + +.compas-box{ + display: flex; + align-items: center; + justify-content: center; } .compas-box-inner { - position: relative; - width: 200px; - height: 200px; - border-radius: 50%; - - .circle { - position: absolute; - width: 12px; - height: 12px; - border: 1px solid #fff; + position: relative; + width: 200px; + height: 200px; border-radius: 50%; - top: 95%; - left: 50%; - transform-origin: 0 -90px; /* 중심에서 반지름 거리만큼 떨어져 위치 */ - cursor: pointer; - z-index: 3; - /* 0번을 180도 위치(아래)에, 13번을 0도 위치(위)에 배치 */ - i { - position: absolute; - top: 12.5px; - left: 50%; - font-size: 11px; - color: #8b8b8b; - font-weight: 500; - -webkit-user-select: none; - -moz-user-select: none; - -ms-use-select: none; - user-select: none; + + .circle { + position: absolute; + width: 12px; + height: 12px; + border: 1px solid #fff; + border-radius: 50%; + top: 95%; + left: 50%; + transform-origin: 0 -90px; /* 중심에서 반지름 거리만큼 떨어져 위치 */ + cursor:pointer; + z-index: 3; + /* 0번을 180도 위치(아래)에, 13번을 0도 위치(위)에 배치 */ + i{ + position: absolute; + top: 12.5px; + left: 50%; + font-size: 11px; + color: #8B8B8B; + font-weight: 500; + -webkit-user-select: none; + -moz-user-select: none; + -ms-use-select: none; + user-select: none; + } + &:nth-child(1) { transform: rotate(180deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(180deg);}} + &:nth-child(2) { transform: rotate(195deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(165deg);}} + &:nth-child(3) { transform: rotate(210deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(150deg);}} + &:nth-child(4) { transform: rotate(225deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(135deg);}} + &:nth-child(5) { transform: rotate(240deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(120deg);}} + &:nth-child(6) { transform: rotate(255deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(105deg);}} + &:nth-child(7) { transform: rotate(270deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(90deg);}} + &:nth-child(8) { transform: rotate(285deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(75deg);}} + &:nth-child(9) { transform: rotate(300deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(60deg);}} + &:nth-child(10) { transform: rotate(315deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(45deg);}} + &:nth-child(11) { transform: rotate(330deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(30deg);}} + &:nth-child(12) { transform: rotate(345deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(15deg);}} + &:nth-child(13) { transform: rotate(0deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(0deg);}} + &:nth-child(14) { transform: rotate(15deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(-15deg);}} + &:nth-child(15) { transform: rotate(30deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(-30deg);}} + &:nth-child(16) { transform: rotate(45deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(-45deg);}} + &:nth-child(17) { transform: rotate(60deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(-60deg);}} + &:nth-child(18) { transform: rotate(75deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(-75deg);}} + &:nth-child(19) { transform: rotate(90deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(-90deg);}} + &:nth-child(20) { transform: rotate(105deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(-105deg);}} + &:nth-child(21) { transform: rotate(120deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(-120deg);}} + &:nth-child(22) { transform: rotate(135deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(-135deg);}} + &:nth-child(23) { transform: rotate(150deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(-150deg);}} + &:nth-child(24) { transform: rotate(165deg) translate(-50%, -50%); i{transform: translateX(-50%) rotate(-165deg);}} + &.act{ + &::after{ + content: ''; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 5px; + height: 5px; + background-color: #fff; + border-radius: 50%; + } + i{ + color: #fff; + } + } } - &:nth-child(1) { - transform: rotate(180deg) translate(-50%, -50%); - i { - transform: translateX(-50%) rotate(180deg); - } - } - &:nth-child(2) { - transform: rotate(195deg) translate(-50%, -50%); - i { - transform: translateX(-50%) rotate(165deg); - } - } - &:nth-child(3) { - transform: rotate(210deg) translate(-50%, -50%); - i { - transform: translateX(-50%) rotate(150deg); - } - } - &:nth-child(4) { - transform: rotate(225deg) translate(-50%, -50%); - i { - transform: translateX(-50%) rotate(135deg); - } - } - &:nth-child(5) { - transform: rotate(240deg) translate(-50%, -50%); - i { - transform: translateX(-50%) rotate(120deg); - } - } - &:nth-child(6) { - transform: rotate(255deg) translate(-50%, -50%); - i { - transform: translateX(-50%) rotate(105deg); - } - } - &:nth-child(7) { - transform: rotate(270deg) translate(-50%, -50%); - i { - transform: translateX(-50%) rotate(90deg); - } - } - &:nth-child(8) { - transform: rotate(285deg) translate(-50%, -50%); - i { - transform: translateX(-50%) rotate(75deg); - } - } - &:nth-child(9) { - transform: rotate(300deg) translate(-50%, -50%); - i { - transform: translateX(-50%) rotate(60deg); - } - } - &:nth-child(10) { - transform: rotate(315deg) translate(-50%, -50%); - i { - transform: translateX(-50%) rotate(45deg); - } - } - &:nth-child(11) { - transform: rotate(330deg) translate(-50%, -50%); - i { - transform: translateX(-50%) rotate(30deg); - } - } - &:nth-child(12) { - transform: rotate(345deg) translate(-50%, -50%); - i { - transform: translateX(-50%) rotate(15deg); - } - } - &:nth-child(13) { - transform: rotate(0deg) translate(-50%, -50%); - i { - transform: translateX(-50%) rotate(0deg); - } - } - &:nth-child(14) { - transform: rotate(15deg) translate(-50%, -50%); - i { - transform: translateX(-50%) rotate(-15deg); - } - } - &:nth-child(15) { - transform: rotate(30deg) translate(-50%, -50%); - i { - transform: translateX(-50%) rotate(-30deg); - } - } - &:nth-child(16) { - transform: rotate(45deg) translate(-50%, -50%); - i { - transform: translateX(-50%) rotate(-45deg); - } - } - &:nth-child(17) { - transform: rotate(60deg) translate(-50%, -50%); - i { - transform: translateX(-50%) rotate(-60deg); - } - } - &:nth-child(18) { - transform: rotate(75deg) translate(-50%, -50%); - i { - transform: translateX(-50%) rotate(-75deg); - } - } - &:nth-child(19) { - transform: rotate(90deg) translate(-50%, -50%); - i { - transform: translateX(-50%) rotate(-90deg); - } - } - &:nth-child(20) { - transform: rotate(105deg) translate(-50%, -50%); - i { - transform: translateX(-50%) rotate(-105deg); - } - } - &:nth-child(21) { - transform: rotate(120deg) translate(-50%, -50%); - i { - transform: translateX(-50%) rotate(-120deg); - } - } - &:nth-child(22) { - transform: rotate(135deg) translate(-50%, -50%); - i { - transform: translateX(-50%) rotate(-135deg); - } - } - &:nth-child(23) { - transform: rotate(150deg) translate(-50%, -50%); - i { - transform: translateX(-50%) rotate(-150deg); - } - } - &:nth-child(24) { - transform: rotate(165deg) translate(-50%, -50%); - i { - transform: translateX(-50%) rotate(-165deg); - } - } - &.act { - &::after { - content: ''; + .compas{ position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); - width: 5px; - height: 5px; - background-color: #fff; + width: 148px; + height: 148px; + border: 4px solid #fff; border-radius: 50%; - } - i { - color: #fff; - } + .compas-arr{ + width: 100%; + height: 100%; + background: url(../../public/static/images/canvas/compas.svg)no-repeat center; + background-size: 122px 122px; + } } - } - .compas { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - width: 148px; - height: 148px; - border: 4px solid #fff; - border-radius: 50%; - .compas-arr { - width: 100%; - height: 100%; - background: url(../../public/static/images/canvas/compas.svg) no-repeat center; - background-size: 122px 122px; - } - } } -.draw-flow-wrap { - margin: 10px 0; +.draw-flow-wrap{ + margin: 10px 0; } // 지붕모듈선택 -.roof-module-tab { - display: flex; - align-items: center; - gap: 10px; - margin-bottom: 14px; - .module-tab-bx { - flex: 1; - height: 34px; - line-height: 31px; - border: 1px solid #484848; - border-radius: 2px; - background-color: transparent; - font-size: 12px; - color: #aaa; - text-align: center; - cursor: default; - transition: all 0.15s ease-in-out; - &.act { - background-color: #1083e3; - border: 1px solid #1083e3; - color: #fff; - font-weight: 500; - } - } - .tab-arr { - display: block; - width: 9px; - height: 14px; - background-repeat: no-repeat; - background-position: center; - background-size: cover; - background-image: url(../../public/static/images/canvas/module_tab_arr.svg); - transition: all 0.15s ease-in-out; - &.act { - background-image: url(../../public/static/images/canvas/module_tab_arr_white.svg); - } - } -} - -.roof-module-compas { - margin-bottom: 24px; - .compas-box-inner { - width: 280px; - height: 253px; - .circle { - top: 86%; - // &:nth-child(1), - // &:nth-child(7), - // &:nth-child(13), - // &:nth-child(19){ - // &::before{ - // content: ''; - // position: absolute; - // top: 20px; - // left: 50%; - // transform: translateX(-50%); - // width: 1px; - // height: 6px; - // background-color: #8B8B8B; - // } - // } - i { - top: 22px; - } - &.act { - i { - color: #8b8b8b; +.roof-module-tab{ + display: flex; + align-items: center; + gap: 10px; + margin-bottom: 14px; + .module-tab-bx{ + flex: 1; + height: 34px; + line-height: 31px; + border: 1px solid #484848; + border-radius: 2px; + background-color: transparent; + font-size: 12px; + color: #AAA; + text-align: center; + cursor: default; + transition: all .15s ease-in-out; + &.act{ + background-color: #1083E3; + border: 1px solid #1083E3; + color: #fff; + font-weight: 500; + } + } + .tab-arr{ + display: block; + width: 9px; + height: 14px; + background-repeat: no-repeat; + background-position: center; + background-size: cover; + background-image: url(../../public/static/images/canvas/module_tab_arr.svg); + transition: all .15s ease-in-out; + &.act{ + background-image: url(../../public/static/images/canvas/module_tab_arr_white.svg); } - } } - } -} -.center-wrap { - display: flex; - flex-direction: column; - align-items: center; - gap: 20px; } -.module-table-flex-wrap { - display: flex; - gap: 10px; - .outline-form { +.roof-module-compas{ + margin-bottom: 24px; + .compas-box-inner{ + width: 280px; + height: 253px; + .circle{ + top: 86%; + // &:nth-child(1), + // &:nth-child(7), + // &:nth-child(13), + // &:nth-child(19){ + // &::before{ + // content: ''; + // position: absolute; + // top: 20px; + // left: 50%; + // transform: translateX(-50%); + // width: 1px; + // height: 6px; + // background-color: #8B8B8B; + // } + // } + i{ + top: 22px; + } + &.act{ + i{color: #8B8B8B;} + } + } + } +} +.center-wrap{ + display: flex; + flex-direction: column; + align-items: center; + gap: 20px; +} + +.module-table-flex-wrap{ + display: flex; + gap: 10px; + .outline-form{ + flex: 1; + } +} + +.module-box-tab{ + display: flex; + .module-btn{ + flex: 1; + border-top: 1px solid #505050; + border-bottom: 1px solid #505050; + border-right: 1px solid #505050; + background-color: #454545; + color: #fff; + height: 30px; + font-size: 12px; + font-weight: 400; + transition: all .15s ease-in-out; + &:first-child{ + border-left: 1px solid #505050; + } + &.act{ + border-color: #fff; + background-color: #fff; + color: #101010; + } + } +} + +.module-table-box{ flex: 1; - } + background-color: #3D3D3D; + border-radius: 2px; + .module-table-inner{ + padding: 10px; + .outline-form{ + span{ + width: auto; + } + } + .module-table-tit{ + padding: 10px 0; + font-size: 12px; + color: #fff; + border-bottom: 1px solid #4D4D4D; + } + .eaves-keraba-table{ + width: 100%; + margin-top: 15px; + .eaves-keraba-th{ + width: 72px; + } + .eaves-keraba-th, + .eaves-keraba-td{ + padding-bottom: 5px; + } + } + .self-table-tit{ + font-size: 12px; + font-weight: 500; + color: #fff; + padding-bottom: 15px; + } + } + .warning-guide{ + padding: 20px; + .warning{ + color: #FFCACA; + max-height: 55px; + overflow-y: auto; + padding-right: 30px; + &::-webkit-scrollbar { + width: 4px; + background-color: transparent; + } + &::-webkit-scrollbar-thumb { + background-color: #D9D9D9; + } + &::-webkit-scrollbar-track { + background-color: transparent; + } + } + } } -.module-box-tab { - display: flex; - .module-btn { - flex: 1; - border-top: 1px solid #505050; - border-bottom: 1px solid #505050; - border-right: 1px solid #505050; - background-color: #454545; - color: #fff; - height: 30px; - font-size: 12px; - font-weight: 400; - transition: all 0.15s ease-in-out; - &:first-child { - border-left: 1px solid #505050; +.module-self-table{ + display: table; + border-top: 1px solid #4D4D4D; + border-collapse: collapse; + width: 100%; + .self-table-item{ + display: table-row; + .self-item-td, + .self-item-th{ + display: table-cell; + vertical-align: middle; + border-bottom: 1px solid #4D4D4D; + } + .self-item-th{ + width: 60px; + font-size: 12px; + font-weight: 500; + color: #fff; + } + .self-item-td{ + font-size: 12px; + font-weight: 400; + color: #fff; + padding: 15px 20px; + } } - &.act { - border-color: #fff; - background-color: #fff; - color: #101010; - } - } } -.module-table-box { - flex: 1; - background-color: #3d3d3d; - border-radius: 2px; - .module-table-inner { - padding: 10px; - .outline-form { - span { - width: auto; - } - } - .module-table-tit { - padding: 10px 0; - font-size: 12px; - color: #fff; - border-bottom: 1px solid #4d4d4d; - } - .eaves-keraba-table { - width: 100%; - margin-top: 15px; - .eaves-keraba-th { - width: 72px; - } - .eaves-keraba-th, - .eaves-keraba-td { - padding-bottom: 5px; - } - } - .self-table-tit { - font-size: 12px; - font-weight: 500; - color: #fff; - padding-bottom: 15px; - } - } - .warning-guide { - padding: 20px; - .warning { - color: #ffcaca; - max-height: 55px; - overflow-y: auto; - padding-right: 30px; - &::-webkit-scrollbar { - width: 4px; - background-color: transparent; - } - &::-webkit-scrollbar-thumb { - background-color: #d9d9d9; - } - &::-webkit-scrollbar-track { - background-color: transparent; - } - } - } -} - -.module-self-table { - display: table; - border-top: 1px solid #4d4d4d; - border-collapse: collapse; - width: 100%; - .self-table-item { - display: table-row; - .self-item-td, - .self-item-th { - display: table-cell; - vertical-align: middle; - border-bottom: 1px solid #4d4d4d; - } - .self-item-th { - width: 60px; - font-size: 12px; - font-weight: 500; - color: #fff; - } - .self-item-td { - font-size: 12px; - font-weight: 400; - color: #fff; - padding: 15px 20px; - } - } -} - -.self-table-flx { - display: flex; - align-items: center; - margin-top: 15px; - button { - margin-left: auto; - } -} -.hexagonal-wrap { - .hexagonal-item { - padding: 15px 0; - border-bottom: 1px solid #4d4d4d; - &:first-child { - padding-top: 0; - } - &:last-child { - padding-bottom: 0; - border: none; - } - .hexagonal-flx-auto { - display: flex; - justify-content: space-between; - } - .hexagonal-flx { - display: flex; - align-items: center; - button { +.self-table-flx{ + display: flex; + align-items: center; + margin-top: 15px; + button{ margin-left: auto; - } } - } +} +.hexagonal-wrap{ + .hexagonal-item{ + padding: 15px 0; + border-bottom: 1px solid #4D4D4D; + &:first-child{ + padding-top: 0; + } + &:last-child{ + padding-bottom: 0; + border: none; + } + .hexagonal-flx-auto{ + display: flex; + justify-content: space-between; + } + .hexagonal-flx{ + display: flex; + align-items: center; + button{ + margin-left: auto; + } + } + } } // 회로 및 가대설정 -.circuit-check-inner { - padding: 5px 0; - &.overflow { - overflow-y: auto; - max-height: 100px; - min-height: 60px; +.circuit-check-inner{ + padding: 5px 0; + &.overflow{ + overflow-y: auto; + max-height: 100px; + min-height: 60px; + &::-webkit-scrollbar { + width: 4px; + background-color: transparent; + } + &::-webkit-scrollbar-thumb { + background-color: #D9D9D9; + } + &::-webkit-scrollbar-track { + background-color: transparent; + } + } + .d-check-box{ + margin-bottom: 15px; + &:last-child{ + margin-bottom: 0; + } + } +} + +.x-scroll-table{ + overflow: auto; + padding-bottom: 5px; + background-color: transparent; + max-height: 170px; + .roof-module-table{ + min-width: 1200px; + } &::-webkit-scrollbar { - width: 4px; - background-color: transparent; + width: 4px; + height: 4px; + background-color: transparent; } &::-webkit-scrollbar-thumb { - background-color: #d9d9d9; + background-color: #b4b4b4; } &::-webkit-scrollbar-track { - background-color: transparent; + background-color: transparent; } - } - .d-check-box { - margin-bottom: 15px; - &:last-child { - margin-bottom: 0; + &::-webkit-scrollbar-corner{ + background-color: transparent; } - } } -.x-scroll-table { - overflow: auto; - padding-bottom: 5px; - background-color: transparent; - max-height: 170px; - .roof-module-table { - min-width: 1200px; - } - &::-webkit-scrollbar { - width: 4px; - height: 4px; - background-color: transparent; - } - &::-webkit-scrollbar-thumb { - background-color: #b4b4b4; - } - &::-webkit-scrollbar-track { - background-color: transparent; - } - &::-webkit-scrollbar-corner { - background-color: transparent; - } -} - -.circuit-right-wrap { - display: flex; - justify-content: flex-end; -} - -.circuit-data-form { - display: flex; - flex-direction: column; - gap: 5px; - min-height: 60px; - padding: 12px; - border: 1px solid rgba(255, 255, 255, 0.2); - span { - display: inline-flex; - align-items: center; - .del { - display: block; - margin-left: 10px; - width: 15px; - height: 15px; - background: url(../../public/static/images/canvas/circuit_del.svg) no-repeat center; - background-size: cover; - } - } -} -.circuit-table-tit { - color: #fff; - font-size: 12px; - font-weight: 600; - padding: 11px 10px; - background-color: #474747; - border: 1px solid #505050; - border-bottom: none; -} - -.circuit-overflow { - overflow-x: auto; - &::-webkit-scrollbar { - height: 4px; - background-color: transparent; - } - &::-webkit-scrollbar-thumb { - background-color: #d9d9d9; - } - &::-webkit-scrollbar-track { - background-color: transparent; - } - .module-table-box { +.circuit-right-wrap{ display: flex; - &.by-max { - min-width: 886px; - } - } -} -.circuit-title-sel { - padding-bottom: 14px; - .outline-form { - span { - color: #62c207; - } - .grid-select { - .sort-select { - border: 1px solid #4e9e04; - background-color: #1a3104; - p { - line-height: 27px; - } - .select-item-wrap { - background-color: #1a3104; - border: 1px solid #4e9e04; - .select-item:hover { - background-color: #294e07; - } - &::-webkit-scrollbar { - width: 2px; - background-color: transparent; - } - &::-webkit-scrollbar-thumb { - background-color: #fff; - border-radius: 10px; - } - &::-webkit-scrollbar-track { - background-color: transparent; - } - } - } - } - } + justify-content: flex-end; } -.circuit-table-flx-wrap { - display: flex; - gap: 10px; - margin-bottom: 10px; - .circuit-table-flx-box { - flex: 1; +.circuit-data-form{ display: flex; flex-direction: column; - .bottom-wrap { - margin-top: auto; + gap: 5px; + min-height: 60px; + padding: 12px; + border: 1px solid rgba(255, 255, 255, 0.20); + span{ + display: inline-flex; + align-items: center; + .del{ + display: block; + margin-left: 10px; + width: 15px; + height: 15px; + background: url(../../public/static/images/canvas/circuit_del.svg)no-repeat center; + background-size: cover; + } } - .roof-module-table { - table { - table-layout: fixed; - } - } - } +} +.circuit-table-tit{ + color: #fff; + font-size: 12px; + font-weight: 600; + padding: 11px 10px; + background-color: #474747; + border: 1px solid #505050; + border-bottom: none; } -.circuit-count-input { - display: flex; - align-items: center; - gap: 10px; +.circuit-overflow{ + overflow-x: auto; + &::-webkit-scrollbar { + height: 4px; + background-color: transparent; + } + &::-webkit-scrollbar-thumb { + background-color: #D9D9D9; + } + &::-webkit-scrollbar-track { + background-color: transparent; + } + .module-table-box{ + display: flex; + &.by-max{ + min-width: 886px; + } + } +} +.circuit-title-sel{ + padding-bottom: 14px; + .circuit-title{ + font-size: 12px; + color: #62C207; + margin-bottom: 5px; + } + .circuit-sel-wrap{ + display: flex; + align-items: center; + .grid-select{ + .sort-select{ + border: 1px solid #4E9E04; + background-color: #1A3104; + p{ + line-height: 27px; + } + .select-item-wrap{ + background-color: #1A3104; + border: 1px solid #4E9E04; + .select-item:hover{ + background-color: #294e07; + } + &::-webkit-scrollbar { + width: 2px; + background-color: transparent; + + } + &::-webkit-scrollbar-thumb { + background-color: #fff; + border-radius: 10px; + } + &::-webkit-scrollbar-track { + background-color: transparent; + } + } + } + } + } +} + +.circuit-table-flx-wrap{ + display: flex; + gap: 10px; + margin-bottom: 10px; + .circuit-table-flx-box{ + flex: 1; + display: flex; + flex-direction: column; + .bottom-wrap{ + margin-top: auto; + } + .roof-module-table{ + table{ + table-layout: fixed; + } + } + } +} + +.circuit-count-input{ + display: flex; + align-items: center; + gap: 10px; } // 모듈부가기능 -.additional-radio-wrap { - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 15px 0; - margin-bottom: 24px; +.additional-radio-wrap{ + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 15px 0; + margin-bottom: 24px; } -.additional-wrap { - padding: 24px 0; - border-top: 1px solid #424242; +.additional-wrap{ + padding: 24px 0; + border-top: 1px solid #424242; } -.additional-color-wrap { - display: flex; - align-items: center; - padding: 5px 0; - gap: 15px; - .additional-color-box { +.additional-color-wrap{ display: flex; align-items: center; - gap: 8px; - .additional-color { - display: block; - width: 16px; - height: 16px; - &.pink { - border: 2px solid #ce1c9c; - background-color: #16417d; - } - &.white { - border: 2px solid #fff; - background-color: #001027; - } + padding: 5px 0; + gap: 15px; + .additional-color-box{ + display: flex; + align-items: center; + gap: 8px; + .additional-color{ + display: block; + width: 16px; + height: 16px; + &.pink{ + border: 2px solid #ce1c9c; + background-color: #16417D; + } + &.white{ + border: 2px solid #FFF; + background-color: #001027; + } + } } - } } // color setting -.color-setting-wrap { - padding-bottom: 15px; - border-bottom: 1px solid #424242; - .color-tit { - font-size: 13px; - font-weight: 500; - color: #ffffff; - margin-bottom: 10px; - } - .color-picker { - .react-colorful { - width: 100%; - height: auto; - gap: 20px; - .react-colorful__pointer { - width: 15px; - height: 15px; - border: 4px solid #fff; - } - .react-colorful__saturation { - border-radius: 2px; - height: 200px; - border-bottom: 5px solid #000; - } - .react-colorful__last-control { - border-radius: 2px; - height: 10px; - } - } - .hex-color-box { - display: flex; - align-items: center; - margin-top: 15px; - .color-box-tit { - font-size: 12px; - color: #fff; +.color-setting-wrap{ + padding-bottom: 15px; + border-bottom: 1px solid #424242; + .color-tit{ + font-size: 13px; font-weight: 500; - margin-right: 10px; - } - .color-hex-input { - width: 150px; - margin-right: 5px; - input { - width: 100%; - } - } - .color-box { - display: block; - width: 30px; - height: 30px; - border-radius: 4px; - } + color: #ffffff; + margin-bottom: 10px; } - .default-color-wrap { - margin-top: 25px; - .default-tit { + .color-picker{ + .react-colorful{ + width: 100%; + height: auto; + gap: 20px; + .react-colorful__pointer{ + width: 15px; + height: 15px; + border: 4px solid #Fff; + } + .react-colorful__saturation{ + border-radius: 2px; + height: 200px; + border-bottom: 5px solid #000; + } + .react-colorful__last-control{ + border-radius: 2px; + height: 10px; + } + } + .hex-color-box{ + display: flex; + align-items: center; + margin-top: 15px; + .color-box-tit{ + font-size: 12px; + color: #fff; + font-weight: 500; + margin-right: 10px; + } + .color-hex-input{ + width: 150px; + margin-right: 5px; + input{ + width: 100%; + } + } + .color-box{ + display: block; + width: 30px; + height: 30px; + border-radius: 4px; + } + } + .default-color-wrap{ + margin-top: 25px; + .default-tit{ + font-size: 12px; + font-weight: 500; + color: #fff; + margin-bottom: 10px; + } + .color-button-wrap{ + display: grid; + grid-template-columns: repeat(8, 1fr); + gap: 21px; + .default-color{ + display: block; + width: 100%; + height: 30px; + border-radius: 4px; + } + } + } + } +} + +// 글꼴 설정 팝업 +.font-option-warp{ + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 15px 5px; + margin-bottom: 15px; + .font-option-item{ + .option-item-tit{ + font-size: 12px; + font-weight: 500; + color: #fff; + margin-bottom: 10px; + } + } +} +.font-ex-wrap{ + margin-bottom: 15px; + .font-ex-tit{ font-size: 12px; font-weight: 500; color: #fff; margin-bottom: 10px; - } - .color-button-wrap { - display: grid; - grid-template-columns: repeat(8, 1fr); - gap: 21px; - .default-color { - display: block; - width: 100%; - height: 30px; - border-radius: 4px; - } - } } - } -} - -// 글꼴 설정 팝업 -.font-option-warp { - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 15px 5px; - margin-bottom: 15px; - .font-option-item { - .option-item-tit { - font-size: 12px; - font-weight: 500; - color: #fff; - margin-bottom: 10px; + .font-ex-box{ + display: flex; + align-items: center; + justify-content: center; + width: 100%; + min-height: 80px; + background-color: #fff; } - } -} -.font-ex-wrap { - margin-bottom: 15px; - .font-ex-tit { - font-size: 12px; - font-weight: 500; - color: #fff; - margin-bottom: 10px; - } - .font-ex-box { - display: flex; - align-items: center; - justify-content: center; - width: 100%; - min-height: 80px; - background-color: #fff; - } + } // 치수선 설정 -.font-btn-wrap { - margin-bottom: 15px; - button { - width: 100%; - height: 30px; - line-height: 28px; - } -} - -.line-color-wrap { - margin-bottom: 15px; - .color-btn { - display: block; - width: 100%; - height: 30px; - border-radius: 2px; - } -} - -.form-box { - width: 100%; - background-color: #fff; - padding: 10px 15px 20px; - .line-form { - position: relative; - display: flex; - flex-direction: column; - justify-content: flex-end; - min-width: 102px; - min-height: 40px; - margin: 0 auto; - - &::before { - content: ''; - position: absolute; - bottom: 0px; - left: 0; - width: 100%; - height: 40px; - border-left: 1px dashed #101010; - border-right: 1px dashed #101010; +.font-btn-wrap{ + margin-bottom: 15px; + button{ + width: 100%; + height: 30px; + line-height: 28px; } - .line-font-box { - .font { - display: block; - padding-bottom: 15px; - color: #101010; - text-align: center; - line-height: 1; - } - .line { - position: relative; +} + +.line-color-wrap{ + margin-bottom: 15px; + .color-btn{ display: block; width: 100%; - height: 1px; - border-radius: 30px; - &::before { - content: ''; - position: absolute; - top: 50%; - transform: translateY(-50%) rotate(45deg); - left: 1px; - width: 9px; - height: +9px; - border: 1px solid; - border-color: inherit; - border-top: none; - border-right: none; - } - &::after { - content: ''; - position: absolute; - top: 50%; - transform: translateY(-50%) rotate(45deg); - right: 1px; - width: 9px; - height: 9px; - border: 1px solid; - border-color: inherit; - border-bottom: none; - border-left: none; - } - } + height: 30px; + border-radius: 2px; + } +} + +.form-box{ + width: 100%; + background-color: #fff; + padding: 10px 15px 20px; + .line-form{ + position: relative; + display: flex; + flex-direction: column; + justify-content: flex-end; + min-width: 102px; + min-height: 40px; + margin: 0 auto; + + &::before{ + content: ''; + position: absolute; + bottom: 0px; + left: 0; + width: 100%; + height: 40px; + border-left: 1px dashed #101010; + border-right: 1px dashed #101010; + } + .line-font-box{ + .font{ + display: block; + padding-bottom: 15px; + color: #101010; + text-align: center; + line-height: 1; + } + .line{ + position: relative; + display: block; + width: 100%; + height: 1px; + border-radius: 30px; + &::before{ + content: ''; + position: absolute; + top: 50%; + transform: translateY(-50%) rotate(45deg); + left: 1px; + width: 9px; + height:+ 9px; + border: 1px solid; + border-color: inherit; + border-top: none; + border-right: none; + } + &::after{ + content: ''; + position: absolute; + top: 50%; + transform: translateY(-50%) rotate(45deg); + right: 1px; + width: 9px; + height: 9px; + border: 1px solid; + border-color: inherit; + border-bottom: none; + border-left: none; + } + } + } } - } } // 사이즈 변경 -.size-inner-warp { - position: relative; +.size-inner-warp{ + position: relative; } -.size-check-wrap { - position: relative; - display: block; - width: 132px; - height: 132px; - margin: 0 auto; - .size-btn { - position: absolute; - width: 16px; - height: 16px; - border: 1px solid #fff; - border-radius: 50%; - &.act { - &::after { - content: ''; +.size-check-wrap{ + position: relative; + display: block; + width: 132px; + height: 132px; + margin: 0 auto; + .size-btn{ + position: absolute; + width: 16px; + height: 16px; + border: 1px solid #fff; + border-radius: 50%; + &.act{ + &::after{ + content: ''; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 8px; + height: 8px; + background-color: #fff; + border-radius: 50%; + } + } + &:nth-child(1){ top: 0; left: 0; } + &:nth-child(2){ top: 0; right: 0; } + &:nth-child(3){ bottom: 0; left: 0; } + &:nth-child(4){ bottom: 0; right: 0; } + } + .size-box{ position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); - width: 8px; - height: 8px; + width: 100px; + height: 100px; background-color: #fff; - border-radius: 50%; - } } - &:nth-child(1) { - top: 0; - left: 0; - } - &:nth-child(2) { - top: 0; - right: 0; - } - &:nth-child(3) { - bottom: 0; - left: 0; - } - &:nth-child(4) { - bottom: 0; - right: 0; - } - } - .size-box { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - width: 100px; - height: 100px; - background-color: #fff; - } } -.size-option-top { - margin-bottom: 15px; +.size-option-top{ + margin-bottom: 15px; } -.size-option-side { - position: absolute; - top: 50%; - left: 0; - transform: translateY(-50%); +.size-option-side{ + position: absolute; + top: 50%; + left: 0; + transform: translateY(-50%); } -.size-option-wrap { - width: 88px; - margin: 0 auto; - .size-option { - display: flex; - align-items: center; - input { - width: 100%; - flex: 1; +.size-option-wrap{ + width: 88px; + margin: 0 auto; + .size-option{ + display: flex; + align-items: center; + input{ + width: 100%; + flex: 1; + } + span{ + flex: none; + } } - span { - 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; - } +.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; + } } // 이미지 불러오기 -.img-flex-box { - display: flex; - align-items: center; +.img-flex-box{ + display: flex; + align-items: center; } -.img-load-from { - margin-top: 20px; - .img-load-item { - border-top: 1px solid #424242; - padding: 18px 0; - .d-check-radio { - margin-bottom: 20px; +.img-load-from{ + margin-top: 20px; + .img-load-item{ + border-top: 1px solid #424242; + padding: 18px 0; + .d-check-radio{ + margin-bottom: 20px; + } } - } - border-bottom: 1px solid #424242; + border-bottom: 1px solid #424242; } // 지붕모듈선택 변경 -.module-table-box { - &.none-flex { - flex: none; - width: 230px; - .outline-form { - .grid-select { +.module-table-box{ + &.none-flex{ flex: none; - width: 95.77px; - } - .thin { - margin-left: 0; - } - } - } -} -.roof-module-tab2-overflow { - max-height: 650px; - overflow-y: auto; - padding-bottom: 15px; - border-bottom: 1px solid #4d4d4d; - &::-webkit-scrollbar { - width: 4px; - background-color: transparent; - } - &::-webkit-scrollbar-thumb { - background-color: #d9d9d9; - } - &::-webkit-scrollbar-track { - background-color: transparent; - } -} -.module-table-flex-wrap { - &.tab2 { - margin-top: 10px; - gap: 15px; - } - .module-flex-item { - flex: 1; - .module-flex-item-tit { - font-size: 12px; - font-weight: 500; - color: #fff; - padding-bottom: 10px; - border-bottom: 1px solid #4d4d4d; - } - .flex-item-btn-wrap { - display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 8px; - margin-bottom: 24px; - } - &.non-flex { - display: flex; - flex-direction: column; - justify-content: flex-start; - flex: none; - padding-top: 27.5px; - width: 260px; - } - } -} - -.module-table-box { - .module-table-inner { - .module-table-flex-wrap { - &.tab2 { - .eaves-keraba-table { - .eaves-keraba-th { - width: 90px; - } - .eaves-keraba-td { - padding-left: 0; - padding-bottom: 5px; - } + width: 230px; + .outline-form{ + .grid-select{ + flex: none; + width: 95.77px; + } + .thin{ + margin-left: 0; + } } - } } - } } -.keraba-flex { - display: flex; - align-items: center; - .grid-select { - flex: none; - width: 110px; - } - .outline-form { - justify-content: flex-end; - } +.roof-module-tab2-overflow{ + max-height: 650px; + overflow-y: auto; + padding-bottom: 15px; + border-bottom: 1px solid #4D4D4D; + &::-webkit-scrollbar { + width: 4px; + background-color: transparent; + } + &::-webkit-scrollbar-thumb { + background-color: #D9D9D9; + } + &::-webkit-scrollbar-track { + background-color: transparent; + } +} +.module-table-flex-wrap{ + &.tab2{ + margin-top: 10px; + gap: 15px; + + } + .module-flex-item{ + flex: 1; + .module-flex-item-tit{ + font-size: 12px; + font-weight: 500; + color: #fff; + padding-bottom: 10px; + border-bottom: 1px solid #4D4D4D; + } + .flex-item-btn-wrap{ + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 8px; + margin-bottom: 24px; + } + &.non-flex{ + display: flex; + flex-direction: column; + justify-content: flex-start; + flex: none; + padding-top: 27.5px; + width: 260px; + } + } } -.pop-spinner { - position: absolute; - bottom: 10px; - left: 5px; - width: calc(100% - 10px); - height: calc(100% - 49px); - display: flex; - align-items: center; - justify-content: center; - background-color: rgba($color: #101010, $alpha: 0.5); - z-index: 2000000; - .loader { - font-size: 10px; - width: 1.2em; - height: 1.2em; - border-radius: 50%; - position: relative; - text-indent: -9999em; - animation: mulShdSpin 1.1s infinite ease; - transform: translateZ(0); - } - @keyframes mulShdSpin { - 0%, - 100% { - box-shadow: - 0em -2.6em 0em 0em #fff, - 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), - 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), - 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), - 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), - -1.8em 1.8em 0 0em rgba(0, 0, 0, 0.2), - -2.6em 0em 0 0em rgba(255, 255, 255, 0.5), - -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.7); +.module-table-box{ + .module-table-inner{ + .module-table-flex-wrap{ + &.tab2{ + .eaves-keraba-table{ + .eaves-keraba-th{ + width: 90px; + } + .eaves-keraba-td{ + padding-left: 0; + padding-bottom: 5px; + } + } + } + } + } +} +.keraba-flex{ + display: flex; + align-items: center; + .grid-select{ + flex: none; + width: 110px; } - 12.5% { - box-shadow: - 0em -2.6em 0em 0em rgba(255, 255, 255, 0.7), - 1.8em -1.8em 0 0em #fff, - 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), - 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), - 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), - -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), - -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), - -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.5); + .outline-form{ + justify-content: flex-end; } - 25% { - box-shadow: - 0em -2.6em 0em 0em rgba(255, 255, 255, 0.5), - 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.7), - 2.5em 0em 0 0em #fff, - 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), - 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), - -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), - -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), - -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2); - } - 37.5% { - box-shadow: - 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), - 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.5), - 2.5em 0em 0 0em rgba(255, 255, 255, 0.7), - 1.75em 1.75em 0 0em #fff, - 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), - -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), - -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), - -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2); - } - 50% { - box-shadow: - 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), - 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), - 2.5em 0em 0 0em rgba(255, 255, 255, 0.5), - 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.7), - 0em 2.5em 0 0em #fff, - -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2), - -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), - -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2); - } - 62.5% { - box-shadow: - 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), - 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), - 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), - 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.5), - 0em 2.5em 0 0em rgba(255, 255, 255, 0.7), - -1.8em 1.8em 0 0em #fff, - -2.6em 0em 0 0em rgba(255, 255, 255, 0.2), - -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2); - } - 75% { - box-shadow: - 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), - 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), - 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), - 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), - 0em 2.5em 0 0em rgba(255, 255, 255, 0.5), - -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.7), - -2.6em 0em 0 0em #fff, - -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2); - } - 87.5% { - box-shadow: - 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2), - 1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2), - 2.5em 0em 0 0em rgba(255, 255, 255, 0.2), - 1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2), - 0em 2.5em 0 0em rgba(255, 255, 255, 0.2), - -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.5), - -2.6em 0em 0 0em rgba(255, 255, 255, 0.7), - -1.8em -1.8em 0 0em #fff; - } - } } .pop-spinner{ From 9c6b96efa12e1a43977061b4e91eaaeeefc119b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Mon, 17 Mar 2025 14:12:04 +0900 Subject: [PATCH 349/352] =?UTF-8?q?Option=20=EA=B5=AC=EC=A1=B0=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../circuitTrestle/CircuitTrestleSetting.jsx | 16 +- .../step/PowerConditionalSelect.jsx | 2 +- .../modal/circuitTrestle/step/StepUp.jsx | 158 ++++++++++++------ 3 files changed, 121 insertions(+), 55 deletions(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index bc31465a..00f3598f 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -51,7 +51,8 @@ export default function CircuitTrestleSetting({ id }) { // const { trigger: setCircuitData } = useCanvasPopupStatusController(4) // const [stepUpListData, setStepUpListData] = useRecoilState(stepUpListDataState) const [stepUpListData, setStepUpListData] = useState([]) - const [seletedOption, setSeletedOption] = useState(null) + const [seletedMainOption, setSeletedMainOption] = useState(null) + const [seletedSubOption, setSeletedSubOption] = useState(null) const { setModuleStatisticsData } = useCircuitTrestle() const { handleCanvasToPng } = useImgLoader() @@ -453,6 +454,7 @@ export default function CircuitTrestleSetting({ id }) { allocationType, circuitAllocationType, setCircuitAllocationType, + selectedMaker, selectedModels, setSelectedModels, getSelectedPcsItemList, @@ -463,8 +465,10 @@ export default function CircuitTrestleSetting({ id }) { onValuesSelected: handleStepUpValuesSelected, // 선택된 값들을 처리하는 함수 stepUpListData, setStepUpListData, - seletedOption, - setSeletedOption, + seletedMainOption, + setSeletedMainOption, + seletedSubOption, + setSeletedSubOption, getModuleList, setModuleStatisticsData, } @@ -474,12 +478,12 @@ export default function CircuitTrestleSetting({ id }) { return stepUpListData[0].pcsItemList.map((item) => { return item.serQtyList .filter((serQty) => serQty.selected) - .map((serQty) => { + .map((serQty, index) => { return { pcsMkrCd: item.pcsMkrCd, pcsSerCd: item.pcsSerCd, pcsItemId: item.itemId, - pscOptCd: seletedOption.code, + pscOptCd: index === 0 ? seletedMainOption.code : seletedSubOption.code, paralQty: serQty.paralQty, connections: item.connList?.length ? [ @@ -489,7 +493,7 @@ export default function CircuitTrestleSetting({ id }) { ] : [], } - })[0] + }) }) } diff --git a/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx b/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx index b48ecffd..f8d1d530 100644 --- a/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect.jsx @@ -13,7 +13,7 @@ import { useRecoilState } from 'recoil' import { useRecoilValue } from 'recoil' import { v4 as uuidv4 } from 'uuid' -const PCS_MKR_MULTI_TYPE = { +export const PCS_MKR_MULTI_TYPE = { MULTI: 'MULTI', SINGLE_P: 'SINGLE-P', SINGLE_N: 'SINGLE-N', diff --git a/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx b/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx index 71691717..d776476b 100644 --- a/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/step/StepUp.jsx @@ -15,6 +15,7 @@ import { POLYGON_TYPE } from '@/common/common' import { useSwal } from '@/hooks/useSwal' import { circuitNumDisplaySelector } from '@/store/settingAtom' import { fontSelector } from '@/store/fontAtom' +import { PCS_MKR_MULTI_TYPE } from './PowerConditionalSelect' export default function StepUp(props) { const { @@ -22,8 +23,11 @@ export default function StepUp(props) { allocationType, stepUpListData, setStepUpListData, - seletedOption, - setSeletedOption, + seletedMainOption, + setSeletedMainOption, + seletedSubOption, + setSeletedSubOption, + selectedMaker, selectedModels, setSelectedModels, getSelectedPcsItemList, @@ -42,17 +46,14 @@ export default function StepUp(props) { const canvas = useRecoilValue(canvasState) const selectedModules = useRecoilValue(selectedModuleState) const [optCodes, setOptCodes] = useState([]) + const [mainOptions, setMainOptions] = useState([]) + const [subOptions, setSubOptions] = useState([]) const [selectedRows, setSelectedRows] = useState({}) const [isManualSelection, setIsManualSelection] = useState({}) const isDisplayCircuitNumber = useRecoilValue(circuitNumDisplaySelector) const circuitNumberText = useRecoilValue(fontSelector('circuitNumberText')) - // useCanvasPopupStatusController(6) - // const canvasPopupStatusState = useRecoilValue(canvasPopupStatusStore) - // if (Object.keys(canvasPopupStatusState[6]).length !== 0) { - // console.log('🚀 ~ useEffect ~ canvasPopupStatusState :', canvasPopupStatusState) - // } useEffect(() => { if (allocationType === 'auto') { @@ -79,6 +80,11 @@ export default function StepUp(props) { /** * PCS 자동 승압설정 정보 조회 */ + + const isMultiOptions = () => { + return selectedModels.some((model) => model.pcsSerParallelYn === 'Y') + } + const fetchAutoStepUpData = async () => { try { const params = { @@ -87,7 +93,6 @@ export default function StepUp(props) { roofSurfaceList: props.getRoofSurfaceList() /** 지붕면 목록 */, pcsItemList: props.getSelectedPcsItemList() /** PCS 아이템 목록 */, } - /** 회로 구성 가능 여부 체크 통과 시 승압설정 정보 조회 */ getPcsVoltageStepUpList(params).then((res) => { if (res?.result.resultCode === 'S' && res?.data) { @@ -98,12 +103,29 @@ export default function StepUp(props) { setStepUpListData(stepUpListData) /** PCS 옵션 조회 */ - const formattedOptCodes = formatOptionCodes(res.data.optionList) - setOptCodes(formattedOptCodes) - setSeletedOption(formattedOptCodes[0]) + // const formattedOptCodes = formatOptionCodes(res.data.optionList) + // setOptCodes(formattedOptCodes) + // setSeletedOption(formattedOptCodes[0]) /** 캔버스에 회로 정보 적용 */ - stepUpListData[0].pcsItemList.forEach((pcsItem) => { + // 병설일때 pcs 있으면 setSubOpsions, 없으면 setMainOptions + console.log('stepUpListData', stepUpListData) + stepUpListData[0].pcsItemList.forEach((pcsItem, index) => { + const optionList = formatOptionCodes(pcsItem.optionList) + if (isMultiOptions()) { + if (index === 0) { + setMainOptions(optionList) + setSeletedMainOption(optionList[0]) + } else { + setSubOptions(optionList) + setSeletedSubOption(optionList[0]) + } + } else { + if (index === 0) { + setMainOptions(optionList) + setSeletedMainOption(optionList[0]) + } + } const selectedSerQty = pcsItem.serQtyList.find((serQty) => serQty.selected) if (selectedSerQty) { selectedSerQty.roofSurfaceList.forEach((roofSurface) => { @@ -165,12 +187,6 @@ export default function StepUp(props) { */ const fetchPassiStepUpData = async () => { try { - // 1-1 2-2 - // canvas - // .getObjects() - // .filter((obj) => obj.name === POLYGON_TYPE.MODULE && obj.circuit) - // .map((module) => module.circuitNumber) - /** 모듈 데이터 가져오기 */ const modules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE) @@ -208,6 +224,21 @@ export default function StepUp(props) { const pcsItemListWithSerQty = res.data.pcsItemList.map((pcsItem, index) => { const pcsData = pcsSummary[selectedModels[index].id] || { circuits: {}, totalModules: 0 } const circuitCounts = Object.values(pcsData.circuits) + const optionList = formatOptionCodes(pcsItem.optionList) + if (isMultiOptions()) { + if (index === 0) { + setMainOptions(optionList) + setSeletedMainOption(optionList[0]) + } else { + setSubOptions(optionList) + setSeletedSubOption(optionList[0]) + } + } else { + if (index === 0) { + setMainOptions(optionList) + setSeletedMainOption(optionList[0]) + } + } return { ...pcsItem, serQtyList: [ @@ -234,9 +265,9 @@ export default function StepUp(props) { setStepUpListData(stepUpListData) /** PCS 옵션 조회 */ - const formattedOptCodes = formatOptionCodes(res.data.optionList) - setOptCodes(formattedOptCodes) - setSeletedOption(formattedOptCodes[0]) + // const formattedOptCodes = formatOptionCodes(res.data.optionList) + // setOptCodes(formattedOptCodes) + // setSeletedOption(formattedOptCodes[0]) } }) } catch (error) { @@ -249,9 +280,9 @@ export default function StepUp(props) { */ const formatOptionCodes = (optionList = []) => { return optionList?.map((opt) => ({ - code: opt.pcsOptCd ? opt.pcsOptCd : '', - name: opt.pcsOptNm ? opt.pcsOptNm : '', - nameJp: opt.pcsOptNmJp ? opt.pcsOptNmJp : '', + code: opt.pcsOptCd ?? '', + name: opt.pcsOptNm ?? '', + nameJp: opt.pcsOptNmJp ?? '', })) } @@ -274,9 +305,9 @@ export default function StepUp(props) { */ const formatOptionList = (optionList = []) => { return optionList?.map((option) => ({ - pcsOptCd: option.pcsOptCd ? option.pcsOptCd : '', - pcsOptNm: option.pcsOptNm ? option.pcsOptNm : '', - pcsOptNmJp: option.pcsOptNmJp ? option.pcsOptNmJp : '', + pcsOptCd: option.pcsOptCd ?? '', + pcsOptNm: option.pcsOptNm ?? '', + pcsOptNmJp: option.pcsOptNmJp ?? '', })) } @@ -293,6 +324,7 @@ export default function StepUp(props) { uniqueIndex: `${item.itemId}_${index}`, // 고유 식별자 추가(동일한 PCS를 구분) connList: formatConnList(item.connList), serQtyList: formatSerQtyList(item.serQtyList), + optionList: item.optionList ?? [], })) } @@ -303,12 +335,12 @@ export default function StepUp(props) { if (!connList) return [] // null인 경우 빈 배열 반환 return connList?.map((conn) => ({ - connAllowCur: conn.connAllowCur ? conn.connAllowCur : 0, - connMaxParalCnt: conn.connMaxParalCnt ? conn.connMaxParalCnt : 0, - goodsNo: conn.goodsNo ? conn.goodsNo : '', - itemId: conn.itemId ? conn.itemId : '', - itemNm: conn.itemNm ? conn.itemNm : '', - vstuParalCnt: conn.vstuParalCnt ? conn.vstuParalCnt : 0, + connAllowCur: conn.connAllowCur ?? 0, + connMaxParalCnt: conn.connMaxParalCnt ?? 0, + goodsNo: conn.goodsNo ?? '', + itemId: conn.itemId ?? '', + itemNm: conn.itemNm ?? '', + vstuParalCnt: conn.vstuParalCnt ?? 0, })) } @@ -318,10 +350,10 @@ export default function StepUp(props) { const formatSerQtyList = (serQtyList = []) => { return serQtyList?.map((qty) => ({ code: uuidv4(), - serQty: qty.serQty ? qty.serQty : 0, - paralQty: qty.paralQty ? qty.paralQty : 0, - rmdYn: qty.rmdYn ? qty.rmdYn : 'N', - usePossYn: qty.usePossYn ? qty.usePossYn : 'Y', + serQty: qty.serQty ?? 0, + paralQty: qty.paralQty ?? 0, + rmdYn: qty.rmdYn ?? 'N', + usePossYn: qty.usePossYn ?? 'Y', roofSurfaceList: formatRoofSurfaceList(qty.roofSurfaceList), selected: qty.rmdYn === 'Y', })) @@ -333,8 +365,8 @@ export default function StepUp(props) { const formatRoofSurfaceList = (roofSurfaceList = []) => { return roofSurfaceList?.map((rsf) => ({ moduleList: formatModuleList(rsf.moduleList), - roofSurface: rsf.roofSurface ? rsf.roofSurface : '', - roofSurfaceId: rsf.roofSurfaceId ? rsf.roofSurfaceId : '', + roofSurface: rsf.roofSurface ?? '', + roofSurfaceId: rsf.roofSurfaceId ?? '', roofSurfaceIncl: rsf.roofSurfaceIncl ? +rsf.roofSurfaceIncl : '', })) } @@ -344,10 +376,10 @@ export default function StepUp(props) { */ const formatModuleList = (moduleList = []) => { return moduleList?.map((module) => ({ - circuit: module.circuit ? module.circuit : '', - itemId: module.itemId ? module.itemId : '', - pcsItemId: module.pcsItemId ? module.pcsItemId : '', - uniqueId: module.uniqueId ? module.uniqueId : '', + circuit: module.circuit ?? '', + itemId: module.itemId ?? '', + pcsItemId: module.pcsItemId ?? '', + uniqueId: module.uniqueId ?? '', })) } @@ -416,9 +448,9 @@ export default function StepUp(props) { setStepUpListData(stepUpListData) /** PCS 옵션 조회 */ - const formattedOptCodes = formatOptionCodes(res.data.optionList) - setOptCodes(formattedOptCodes) - setSeletedOption(formattedOptCodes[0]) + // const formattedOptCodes = formatOptionCodes(res.data.optionList) + // setOptCodes(formattedOptCodes) + // setSeletedOption(formattedOptCodes[0]) } else { swalFire({ text: getMessage('common.message.send.error') }) } @@ -532,7 +564,37 @@ export default function StepUp(props) { <>
      -
      +

      {getMessage('modal.circuit.trestle.setting.step.up.allocation.select.monitor')}

      +
      +
      + {mainOptions.length > 0 && ( + setSeletedMainOption(e)} + /> + )} +
      + {isMultiOptions() && selectedModels.length === 2 && ( +
      + {subOptions.length > 0 && ( + setSeletedSubOption(e)} + /> + )} +
      + )} +
      + + {/*
      {getMessage('modal.circuit.trestle.setting.step.up.allocation.select.monitor')} @@ -551,7 +613,7 @@ export default function StepUp(props) { />
      )} -
      +
      */}
      From 55067cb4f8a4b9144041e88099d8dcd6e6c7bcca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Mon, 17 Mar 2025 14:38:11 +0900 Subject: [PATCH 350/352] =?UTF-8?q?Option=20=EA=B5=AC=EC=A1=B0=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../circuitTrestle/CircuitTrestleSetting.jsx | 46 +++++++++++++++++-- src/hooks/module/useTrestle.js | 14 +++--- 2 files changed, 48 insertions(+), 12 deletions(-) diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index 00f3598f..618a65d2 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -475,15 +475,17 @@ export default function CircuitTrestleSetting({ id }) { // 승압설정 목록 조회 const getStepUpListData = () => { - return stepUpListData[0].pcsItemList.map((item) => { + const pcs = [] + console.log(stepUpListData) + stepUpListData[0].pcsItemList.map((item, index) => { return item.serQtyList .filter((serQty) => serQty.selected) - .map((serQty, index) => { - return { + .forEach((serQty) => { + pcs.push({ pcsMkrCd: item.pcsMkrCd, pcsSerCd: item.pcsSerCd, pcsItemId: item.itemId, - pscOptCd: index === 0 ? seletedMainOption.code : seletedSubOption.code, + pscOptCd: getPcsOptCd(index), paralQty: serQty.paralQty, connections: item.connList?.length ? [ @@ -492,9 +494,43 @@ export default function CircuitTrestleSetting({ id }) { }, ] : [], - } + }) + // return { + // pcsMkrCd: item.pcsMkrCd, + // pcsSerCd: item.pcsSerCd, + // pcsItemId: item.itemId, + // pscOptCd: getPcsOptCd(index), + // paralQty: serQty.paralQty, + // connections: item.connList?.length + // ? [ + // { + // connItemId: item.connList[0].itemId, + // }, + // ] + // : [], + // } }) }) + return pcs + } + + const getPcsOptCd = (index) => { + console.log(selectedModels) + console.log(seletedMainOption) + console.log(seletedSubOption) + if (selectedModels.some((model) => model.pcsSerParallelYn === 'Y')) { + if (selectedModels.length > 1) { + if (index === 0) { + return seletedMainOption.code + } else { + return seletedSubOption.code + } + } else { + return seletedMainOption.code + } + } else { + return seletedMainOption.code + } } const handleStepUp = () => { diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index 4f0bb116..48ad5913 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -640,13 +640,13 @@ export const useTrestle = () => { //surfaces.pcses들을 배열로 묶는다 const pcses = surfaces[0].pcses.filter((pcs) => pcs !== null && pcs !== undefined) - surfaces.forEach((surface, index) => { - if (index !== 0) { - if (surface.pcses) { - pcses.concat(surface.pcses) - } - } - }) + // surfaces.forEach((surface, index) => { + // if (index !== 0) { + // if (surface.pcses) { + // pcses.concat(surface.pcses) + // } + // } + // }) const allModules = surfaces.map((surface) => surface.modules).flat() // 모듈 파라미터 생성 From 100744ad9df5f5d9ac0d771c54b10d8e287b05ea Mon Sep 17 00:00:00 2001 From: yjnoh Date: Mon, 17 Mar 2025 15:02:58 +0900 Subject: [PATCH 351/352] =?UTF-8?q?QPOLYGON=20=EA=B7=B8=EB=A3=B9=EA=B0=9D?= =?UTF-8?q?=EC=B2=B4=20=EC=B9=98=EC=88=98=20=EC=82=AD=EC=A0=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/fabric/QPolygon.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/components/fabric/QPolygon.js b/src/components/fabric/QPolygon.js index 85bb03dd..f19687aa 100644 --- a/src/components/fabric/QPolygon.js +++ b/src/components/fabric/QPolygon.js @@ -136,8 +136,20 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, { this.on('removed', () => { // const children = getAllRelatedObjects(this.id, this.canvas) const children = this.canvas.getObjects().filter((obj) => obj.parentId === this.id) + children.forEach((child) => { this.canvas.remove(child) + + //그룹일때 + if (child.hasOwnProperty('_objects')) { + child._objects.forEach((obj) => { + if (obj.hasOwnProperty('texts')) { + obj.texts.forEach((text) => { + this.canvas?.remove(text) + }) + } + }) + } }) }) From 690ab8454f093c30e050e90b47789502c5771716 Mon Sep 17 00:00:00 2001 From: basssy Date: Mon, 17 Mar 2025 15:20:18 +0900 Subject: [PATCH 352/352] =?UTF-8?q?=EB=AC=BC=EA=B1=B4=20=EB=AA=A9=EB=A1=9D?= =?UTF-8?q?=20=EC=A0=95=EB=A0=AC*?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/management/Stuff.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/management/Stuff.jsx b/src/components/management/Stuff.jsx index 43446209..c1835874 100644 --- a/src/components/management/Stuff.jsx +++ b/src/components/management/Stuff.jsx @@ -301,7 +301,6 @@ export default function Stuff() { } else if (stuffSearchParams?.code === 'E') { stuffSearchParams.startRow = (stuffSearch.pageNo - 1) * stuffSearchParams.pageSize + 1 stuffSearchParams.endRow = stuffSearchParams.pageNo * stuffSearchParams.pageSize - stuffSearchParams.schSortType = defaultSortType stuffSearchParams.pageNo = stuffSearchParams.pageNo if (!stuffSearchParams.saleStoreId) {