From c9d46d14e2f46adae0e6595aeeedd29e1a0ae94b Mon Sep 17 00:00:00 2001 From: Jungseok Sung <58401309+sakjung@users.noreply.github.com> Date: Thu, 7 Oct 2021 18:11:33 +0900 Subject: [PATCH 01/14] =?UTF-8?q?feat:=20=EC=BF=A0=EB=B2=84=EB=84=A4?= =?UTF-8?q?=ED=8B=B0=EC=8A=A4=EB=A5=BC=20=EC=A0=81=EC=9A=A9=ED=95=9C?= =?UTF-8?q?=EB=8B=A4=20(#620)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: k8s 준비물 추가 * refactor: dev dockerfile 삭제 --- backend/docker/main/Dockerfile | 17 +++++++++++++++++ backend/src/main/resources/config | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 backend/docker/main/Dockerfile diff --git a/backend/docker/main/Dockerfile b/backend/docker/main/Dockerfile new file mode 100644 index 000000000..568b00c7e --- /dev/null +++ b/backend/docker/main/Dockerfile @@ -0,0 +1,17 @@ +FROM ubuntu:18.04 + +LABEL email="ssangyu123@gmail.com" +LABEL name="sakjung" +LABEL description="zzimkkong main application" + +RUN apt-get -y update +RUN apt-get install -y openjdk-11-jdk + +# run application +WORKDIR /home/ubuntu +COPY build/libs/backend-0.0.1-SNAPSHOT.jar app.jar +RUN mkdir zzimkkong && mkdir zzimkkong/tmp + +EXPOSE 8080 + +ENTRYPOINT ["java", "-Dspring.profiles.active=prod", "-jar", "app.jar", "--spring.config.location=classpath:config/application-prod.properties"] diff --git a/backend/src/main/resources/config b/backend/src/main/resources/config index e19b72c42..08479c1a9 160000 --- a/backend/src/main/resources/config +++ b/backend/src/main/resources/config @@ -1 +1 @@ -Subproject commit e19b72c42d1fce11d89735f5abf41dd383abf628 +Subproject commit 08479c1a945ec35df0137239d90ea1c499a82e62 From ad7568f09e157abb9cefc2536c5ae98af8f002e7 Mon Sep 17 00:00:00 2001 From: Shim MunSeong Date: Fri, 8 Oct 2021 02:22:30 +0900 Subject: [PATCH 02/14] =?UTF-8?q?feat:=20=EC=98=88=EC=95=BD=20=EC=84=B1?= =?UTF-8?q?=EA=B3=B5=20=EC=8B=9C=20=EB=82=98=EC=98=A4=EB=8A=94=20=EB=A1=9C?= =?UTF-8?q?=EA=B3=A0=EB=A5=BC=20=EC=95=A0=EB=8B=88=EB=A9=94=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20=EB=A1=9C=EA=B3=A0=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?(#618)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 예약 성공 시 나오는 로고를 애니메이션 로고로 변경 * refactor: SVG 애니메이션 스타일 적용 방식 변경 - `createGlobalStyle` -> `` --- .../AnimatedLogo/AnimatedLogo.styles.ts | 106 ++++++++++++++++ .../components/AnimatedLogo/AnimatedLogo.tsx | 113 ++++++++++++++++++ .../GuestReservationSuccess.tsx | 3 +- 3 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 frontend/src/components/AnimatedLogo/AnimatedLogo.styles.ts create mode 100644 frontend/src/components/AnimatedLogo/AnimatedLogo.tsx diff --git a/frontend/src/components/AnimatedLogo/AnimatedLogo.styles.ts b/frontend/src/components/AnimatedLogo/AnimatedLogo.styles.ts new file mode 100644 index 000000000..4475ac252 --- /dev/null +++ b/frontend/src/components/AnimatedLogo/AnimatedLogo.styles.ts @@ -0,0 +1,106 @@ +import styled from 'styled-components'; + +export const AnimatedLogoSvg = styled.svg` + #e2duQ5ri1xy2 { + animation: e2duQ5ri1xy2_c_o 1000ms linear 1 normal forwards; + } + @keyframes e2duQ5ri1xy2_c_o { + 0% { + opacity: 0; + } + 24% { + opacity: 1; + } + 100% { + opacity: 1; + } + } + #e2duQ5ri1xy3_ts { + animation: e2duQ5ri1xy3_ts__ts 1000ms linear 1 normal forwards; + } + @keyframes e2duQ5ri1xy3_ts__ts { + 0% { + transform: translate(100.000001px, 100px) scale(1, 1); + } + 39% { + transform: translate(100.000001px, 100px) scale(1, 1); + animation-timing-function: cubic-bezier(0.445, 0.05, 0.55, 0.95); + } + 45% { + transform: translate(100.000001px, 100px) scale(1.03, 1.03); + animation-timing-function: cubic-bezier(0.445, 0.05, 0.55, 0.95); + } + 58% { + transform: translate(100.000001px, 100px) scale(1, 1); + } + 100% { + transform: translate(100.000001px, 100px) scale(1, 1); + } + } + #e2duQ5ri1xy9_to { + animation: e2duQ5ri1xy9_to__to 1000ms linear 1 normal forwards; + } + @keyframes e2duQ5ri1xy9_to__to { + 0% { + transform: translate(101.66951px, 22.56351px); + animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + } + 45% { + transform: translate(101.669503px, 104.796953px); + animation-timing-function: cubic-bezier(0.075, 0.82, 0.165, 1); + } + 77% { + transform: translate(101.669498px, 93.357506px); + } + 100% { + transform: translate(101.669498px, 93.357506px); + } + } + #e2duQ5ri1xy9 { + animation: e2duQ5ri1xy9_c_o 1000ms linear 1 normal forwards; + } + @keyframes e2duQ5ri1xy9_c_o { + 0% { + opacity: 0; + } + 24% { + opacity: 1; + } + 100% { + opacity: 1; + } + } + #e2duQ5ri1xy12_ts { + animation: e2duQ5ri1xy12_ts__ts 1000ms linear 1 normal forwards; + } + @keyframes e2duQ5ri1xy12_ts__ts { + 0% { + transform: translate(100.428007px, 191.346759px) scale(0.529702, 0.529702); + animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); + } + 45% { + transform: translate(100.428007px, 191.346759px) scale(1, 1); + animation-timing-function: cubic-bezier(0.075, 0.82, 0.165, 1); + } + 77% { + transform: translate(100.428007px, 191.346759px) scale(0.888878, 0.888878); + } + 100% { + transform: translate(100.428007px, 191.346759px) scale(0.888878, 0.888878); + } + } + #e2duQ5ri1xy12 { + animation: e2duQ5ri1xy12_c_o 1000ms linear 1 normal forwards; + } + @keyframes e2duQ5ri1xy12_c_o { + 0% { + opacity: 0; + } + 24% { + opacity: 0.6; + } + 100% { + opacity: 0.6; + } + } +`; diff --git a/frontend/src/components/AnimatedLogo/AnimatedLogo.tsx b/frontend/src/components/AnimatedLogo/AnimatedLogo.tsx new file mode 100644 index 000000000..7223d4609 --- /dev/null +++ b/frontend/src/components/AnimatedLogo/AnimatedLogo.tsx @@ -0,0 +1,113 @@ +import * as Styled from './AnimatedLogo.styles'; + +const AnimatedLogo = (): JSX.Element => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); + +export default AnimatedLogo; diff --git a/frontend/src/pages/GuestReservation/GuestReservationSuccess.tsx b/frontend/src/pages/GuestReservation/GuestReservationSuccess.tsx index 183957614..ac9541d21 100644 --- a/frontend/src/pages/GuestReservation/GuestReservationSuccess.tsx +++ b/frontend/src/pages/GuestReservation/GuestReservationSuccess.tsx @@ -1,5 +1,6 @@ import { Redirect, useLocation, useParams } from 'react-router'; import { ReactComponent as Logo } from 'assets/svg/logo.svg'; +import AnimatedLogo from 'components/AnimatedLogo/AnimatedLogo'; import Header from 'components/Header/Header'; import Layout from 'components/Layout/Layout'; import { HREF } from 'constants/path'; @@ -36,7 +37,7 @@ const GuestReservationSuccess = (): JSX.Element => {
- + 예약이 완료되었습니다! Date: Tue, 12 Oct 2021 13:15:57 +0900 Subject: [PATCH 03/14] =?UTF-8?q?fix:=20=EB=A7=B5=20=ED=8E=B8=EC=A7=91=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=EC=97=90=EC=84=9C=20=EC=84=A0?= =?UTF-8?q?=ED=83=9D=20=EB=AA=A8=EB=93=9C=EC=9D=BC=20=EB=95=8C,=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=20=ED=8F=BC=EC=9D=98=20=ED=85=8D=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EA=B0=80=20Delete,=20Backspace=20=ED=82=A4=EB=A1=9C?= =?UTF-8?q?=20=EC=82=AD=EC=A0=9C=EB=90=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=EC=88=98=EC=A0=95=20(#621)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: 맵 편집 시, 창을 다시 포커스했을 때 맵 이름과 보드 사이즈가 수정 전으로 돌아가는 문제 수정 * fix: 맵 편집 페이지에서 선택 모드일 때, 입력 폼의 텍스트가 Delete, Backspace 키로 삭제되지 않는 문제 수정 --- frontend/src/pages/ManagerMapEditor/ManagerMapEditor.tsx | 1 + frontend/src/pages/ManagerMapEditor/units/MapEditor.tsx | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/frontend/src/pages/ManagerMapEditor/ManagerMapEditor.tsx b/frontend/src/pages/ManagerMapEditor/ManagerMapEditor.tsx index 55260be39..c8ca4eb9d 100644 --- a/frontend/src/pages/ManagerMapEditor/ManagerMapEditor.tsx +++ b/frontend/src/pages/ManagerMapEditor/ManagerMapEditor.tsx @@ -60,6 +60,7 @@ const ManagerMapEditor = (): JSX.Element => { { mapId: Number(mapId) }, { enabled: isEdit, + refetchOnWindowFocus: false, onSuccess: ({ data }) => { const { mapName, mapDrawing } = data; diff --git a/frontend/src/pages/ManagerMapEditor/units/MapEditor.tsx b/frontend/src/pages/ManagerMapEditor/units/MapEditor.tsx index 429989c76..bfa7a81ff 100644 --- a/frontend/src/pages/ManagerMapEditor/units/MapEditor.tsx +++ b/frontend/src/pages/ManagerMapEditor/units/MapEditor.tsx @@ -170,14 +170,14 @@ const MapCreateEditor = ({ }, [deselectMapElements, selectedMapElements, setMapElements]); useEffect(() => { - if (mode !== MapEditorMode.Select) return; + if (!selectedMapElements.length) return; const isPressedDeleteKey = pressedKey === KEY.DELETE || pressedKey === KEY.BACK_SPACE; if (isPressedDeleteKey && selectedMapElements) { deleteMapElement(); } - }, [deleteMapElement, mode, pressedKey, selectedMapElements]); + }, [deleteMapElement, pressedKey, selectedMapElements]); return ( From 834bbd2da06f73d7afab6ca682eeb2cf5503b713 Mon Sep 17 00:00:00 2001 From: Jungseok Sung <58401309+sakjung@users.noreply.github.com> Date: Tue, 12 Oct 2021 13:16:45 +0900 Subject: [PATCH 04/14] =?UTF-8?q?feat:=20s3proxy=20pod=20=ED=99=94?= =?UTF-8?q?=EB=A5=BC=20=EC=9C=84=ED=95=9C=20dockerfile=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20(#625)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: k8s 준비물 추가 * refactor: dev dockerfile 삭제 * chore: dockerfile 경로 변경 --- s3proxy/docker/main/Dockerfile | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 s3proxy/docker/main/Dockerfile diff --git a/s3proxy/docker/main/Dockerfile b/s3proxy/docker/main/Dockerfile new file mode 100644 index 000000000..02320bc06 --- /dev/null +++ b/s3proxy/docker/main/Dockerfile @@ -0,0 +1,17 @@ +FROM ubuntu:18.04 + +LABEL email="ssangyu123@gmail.com" +LABEL name="sakjung" +LABEL description="zzimkkong s3proxy application" + +RUN apt-get -y update +RUN apt-get install -y openjdk-11-jdk + +# run application +WORKDIR /home/ubuntu +COPY build/libs/s3proxy-0.0.1-SNAPSHOT.jar app.jar +RUN mkdir zzimkkong && mkdir zzimkkong/tmp + +EXPOSE 8080 + +ENTRYPOINT ["java", "-Dspring.profiles.active=prod", "-jar", "app.jar", "--spring.config.location=classpath:s3proxy-config/application-prod.yml"] From a5d357867d22ffc37845e429ad681a02c24b12ec Mon Sep 17 00:00:00 2001 From: JO YUN HO Date: Tue, 12 Oct 2021 13:48:13 +0900 Subject: [PATCH 05/14] =?UTF-8?q?feat:=20=EB=8B=A4=EA=B0=81=ED=98=95?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EA=B3=B5=EA=B0=84=EC=9D=84=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20(#623)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: 메서드 이름 변경 * feat: 공간 생성 toolbar에 다각형 추가 * feat: AreaPolygon 타입 정의 및 기존 타입 선언 정리 * feat: 다각형 그리기 선택 시, 마우스 포인터가 원 모양으로 표시되는 기능 * feat: 다각형을 그리는 기능 * feat: 다각형 그리기 미리보기 시, 색상을 투명하게 변경 * feat: BoardSpace에서 polygon을 그리는 기능 * feat: GuestMap과 ManagerEditor에서 polygon을 그리는 기능 * refactor: polygon 로직을 hook으로 분리 * feat: 공간 생성 및 맵 로드 로직에서 polygon을 불러오는 기능 * fix: 예약자 맵 페이지에서 polygon의 색깔이 다르게 표시되는 오류 * refactor: BoardSpace 컴포넌트 조건식 변경 * fix: 맵 에디터에서 공간들이 표시되지 않던 오류 * fix: polygon의 텍스트가 가운데 오지 않는 오류 * refactor: PolygonPreview 컴포넌트 분리 * feat: polygon을 그릴 때 시작점을 표시하는 기능 * fix: 다각형을 그리다가 취소 후 남아있던 오류 * refactor: 매직 넘버 상수화 * refactor: import문 뒤에 개행 추가 * refactor: 템플릿 리터럴 내부 코드 정렬 * refactor: 매직넘버 상수화 * refactor: 상수 이름 변경 - POLYGON_PREVIEW -> POLYGON_PREVIEW_FILL * refactor: useEffect 내부에서 단축 연산자 대신 if문을 사용하도록 변경 * fix: GuestMap에서 텍스트가 제대로 표시되지 않던 오류 * refacotr: 삼항 연산자를 별도의 조건식으로 수정 * refactor: 매직 넘버 상수화 * refactor: 공통 로직을 하나의 함수에서 처리하도록 변경 * refactor: 중복된 조건 제거 * refactor: 값을 반환하지 않는 삼항연산자를 조건문으로 변경 --- frontend/src/constants/editor.ts | 3 + .../src/pages/GuestMap/GuestMap.styles.ts | 8 +- frontend/src/pages/GuestMap/GuestMap.tsx | 50 ++++++++---- .../ManagerMapEditor/ManagerMapEditor.tsx | 4 +- .../ManagerMapEditor/units/MapEditor.tsx | 70 +++++++++++----- .../ManagerSpaceEditor/ManagerSpaceEditor.tsx | 4 +- .../hooks/useDrawingPolygon.ts | 65 +++++++++++++++ .../units/BoardCursorDot.tsx | 20 +++++ .../units/BoardSpace.styles.ts | 9 +++ .../ManagerSpaceEditor/units/BoardSpace.tsx | 21 +++++ .../pages/ManagerSpaceEditor/units/Editor.tsx | 80 ++++++++++++++++--- .../units/PolygonPreview.tsx | 24 ++++++ .../units/PolygonStartPoint.tsx | 20 +++++ .../units/ShapeSelectToolbar.tsx | 8 ++ frontend/src/types/common.ts | 23 +++--- frontend/src/types/editor.ts | 1 + frontend/src/utils/editor.ts | 16 ++++ frontend/src/utils/generateSvg.ts | 17 +++- frontend/src/utils/map.ts | 17 +++- 19 files changed, 388 insertions(+), 72 deletions(-) create mode 100644 frontend/src/pages/ManagerSpaceEditor/hooks/useDrawingPolygon.ts create mode 100644 frontend/src/pages/ManagerSpaceEditor/units/BoardCursorDot.tsx create mode 100644 frontend/src/pages/ManagerSpaceEditor/units/PolygonPreview.tsx create mode 100644 frontend/src/pages/ManagerSpaceEditor/units/PolygonStartPoint.tsx create mode 100644 frontend/src/utils/editor.ts diff --git a/frontend/src/constants/editor.ts b/frontend/src/constants/editor.ts index 68da4dcdd..2e4998408 100644 --- a/frontend/src/constants/editor.ts +++ b/frontend/src/constants/editor.ts @@ -33,6 +33,8 @@ export const EDITOR = { MAX_SCALE: 3.0, STROKE_WIDTH: 3, STROKE_PREVIEW: PALETTE.OPACITY_BLACK[200], + POLYGON_PREVIEW_FILL: PALETTE.OPACITY_BLACK[200], + MIN_POLYGON_SIDES: 3, OPACITY: 1, OPACITY_DELETING: 0.3, TEXT_OPACITY: 0.3, @@ -40,6 +42,7 @@ export const EDITOR = { TEXT_FILL: PALETTE.BLACK[700], SPACE_OPACITY: 0.1, CIRCLE_CURSOR_RADIUS: 3, + CIRCLE_PREVIEW_RADIUS: 5, CIRCLE_CURSOR_FILL: PALETTE.OPACITY_BLACK[300], DRAG_SELECT_RECT_FILL: PALETTE.OPACITY_BLACK[200], SELECTED_GROUP_BBOX_STROKE_WIDTH: 2, diff --git a/frontend/src/pages/GuestMap/GuestMap.styles.ts b/frontend/src/pages/GuestMap/GuestMap.styles.ts index 062eb97f4..fcdf20b89 100644 --- a/frontend/src/pages/GuestMap/GuestMap.styles.ts +++ b/frontend/src/pages/GuestMap/GuestMap.styles.ts @@ -44,7 +44,13 @@ export const Space = styled.g` cursor: pointer; `; -export const SpaceArea = styled.rect` +export const SpaceRect = styled.rect` + &:hover { + opacity: 0.5; + } +`; + +export const SpacePolygon = styled.polygon` &:hover { opacity: 0.5; } diff --git a/frontend/src/pages/GuestMap/GuestMap.tsx b/frontend/src/pages/GuestMap/GuestMap.tsx index c210a62d0..069684e53 100644 --- a/frontend/src/pages/GuestMap/GuestMap.tsx +++ b/frontend/src/pages/GuestMap/GuestMap.tsx @@ -17,9 +17,11 @@ import useGuestMap from 'hooks/query/useGuestMap'; import useGuestSpaces from 'hooks/query/useGuestSpaces'; import useInput from 'hooks/useInput'; import { Area, MapDrawing, MapItem, Reservation, ScrollPosition, Space } from 'types/common'; +import { DrawingAreaShape } from 'types/editor'; import { GuestPageURLParams } from 'types/guest'; import { ErrorResponse } from 'types/response'; import { formatDate } from 'utils/datetime'; +import { getPolygonCenterPoint } from 'utils/editor'; import * as Styled from './GuestMap.styles'; import ReservationDrawer from './units/ReservationDrawer'; @@ -220,23 +222,39 @@ const GuestMap = (): JSX.Element => { data-testid={id} onClick={() => handleClickSpaceArea(id)} > - {area.shape === 'rect' && ( - + {area.shape === DrawingAreaShape.Rect && ( + <> + + + {name} + + + )} + {area.shape === DrawingAreaShape.Polygon && ( + <> + `${x},${y}`).join(' ')} + fill={color ?? PALETTE.RED[200]} + opacity="0.3" + /> + + {name} + + )} - - - {name} - ))} diff --git a/frontend/src/pages/ManagerMapEditor/ManagerMapEditor.tsx b/frontend/src/pages/ManagerMapEditor/ManagerMapEditor.tsx index c8ca4eb9d..70f0e3b62 100644 --- a/frontend/src/pages/ManagerMapEditor/ManagerMapEditor.tsx +++ b/frontend/src/pages/ManagerMapEditor/ManagerMapEditor.tsx @@ -13,7 +13,7 @@ import useManagerMap from 'hooks/query/useManagerMap'; import useManagerSpaces from 'hooks/query/useManagerSpaces'; import useInputs from 'hooks/useInputs'; import useListenManagerMainState from 'hooks/useListenManagerMainState'; -import { ManagerSpace, MapDrawing, MapElement, SpaceArea } from 'types/common'; +import { Area, ManagerSpace, MapDrawing, MapElement } from 'types/common'; import { ErrorResponse } from 'types/response'; import { createMapImageSvg } from 'utils/map'; import * as Styled from './ManagerMapEditor.styles'; @@ -48,7 +48,7 @@ const ManagerMapEditor = (): JSX.Element => { return ( managerSpaces.data?.data.spaces.map((space) => ({ ...space, - area: JSON.parse(space.area) as SpaceArea, + area: JSON.parse(space.area) as Area, })) ?? [] ); } catch (error) { diff --git a/frontend/src/pages/ManagerMapEditor/units/MapEditor.tsx b/frontend/src/pages/ManagerMapEditor/units/MapEditor.tsx index bfa7a81ff..d258ace8c 100644 --- a/frontend/src/pages/ManagerMapEditor/units/MapEditor.tsx +++ b/frontend/src/pages/ManagerMapEditor/units/MapEditor.tsx @@ -16,7 +16,8 @@ import useBoardMove from 'hooks/board/useBoardMove'; import useBoardStatus from 'hooks/board/useBoardStatus'; import useBoardZoom from 'hooks/board/useBoardZoom'; import { Color, DrawingStatus, ManagerSpace, MapElement } from 'types/common'; -import { MapElementType, MapEditorMode } from 'types/editor'; +import { MapElementType, MapEditorMode, DrawingAreaShape } from 'types/editor'; +import { getPolygonCenterPoint } from 'utils/editor'; import useBoardEraserTool from '../hooks/useBoardEraserTool'; import useBoardLineTool from '../hooks/useBoardLineTool'; import useBoardRectTool from '../hooks/useBoardRectTool'; @@ -240,27 +241,52 @@ const MapCreateEditor = ({ )} {spaces.map(({ id, color, area, name }) => ( - - - - {name} - - + <> + {area.shape === DrawingAreaShape.Rect && ( + + + + {name} + + + )} + + {area.shape === DrawingAreaShape.Polygon && ( + + `${x},${y}`).join(' ')} + fill={color} + opacity={EDITOR.SPACE_OPACITY} + /> + + {name} + + + )} + ))} {drawingStatus.start && mode === MapEditorMode.Line && ( diff --git a/frontend/src/pages/ManagerSpaceEditor/ManagerSpaceEditor.tsx b/frontend/src/pages/ManagerSpaceEditor/ManagerSpaceEditor.tsx index 65f1d64e7..d20cd6a70 100644 --- a/frontend/src/pages/ManagerSpaceEditor/ManagerSpaceEditor.tsx +++ b/frontend/src/pages/ManagerSpaceEditor/ManagerSpaceEditor.tsx @@ -18,7 +18,7 @@ import useBoardStatus from 'hooks/board/useBoardStatus'; import useManagerMap from 'hooks/query/useManagerMap'; import useManagerSpaces from 'hooks/query/useManagerSpaces'; import useListenManagerMainState from 'hooks/useListenManagerMainState'; -import { ManagerSpace, MapDrawing, SpaceArea } from 'types/common'; +import { Area, ManagerSpace, MapDrawing } from 'types/common'; import { SpaceEditorMode as Mode } from 'types/editor'; import { ErrorResponse } from 'types/response'; import * as Styled from './ManagerSpaceEditor.styles'; @@ -56,7 +56,7 @@ const ManagerSpaceEditor = (): JSX.Element => { return ( managerSpaces.data?.data.spaces.map((space) => ({ ...space, - area: JSON.parse(space.area) as SpaceArea, + area: JSON.parse(space.area) as Area, })) ?? [] ); } catch (error) { diff --git a/frontend/src/pages/ManagerSpaceEditor/hooks/useDrawingPolygon.ts b/frontend/src/pages/ManagerSpaceEditor/hooks/useDrawingPolygon.ts new file mode 100644 index 000000000..abe881795 --- /dev/null +++ b/frontend/src/pages/ManagerSpaceEditor/hooks/useDrawingPolygon.ts @@ -0,0 +1,65 @@ +import { useEffect, useState } from 'react'; +import { Area, Coordinate } from 'types/common'; +import { DrawingAreaShape, SpaceEditorMode as Mode } from 'types/editor'; + +interface Props { + coordinate: Coordinate; + mode: Mode; +} + +const useDrawingPolygon = ({ + coordinate, + mode, +}: Props): { + polygon: Area | null; + isDrawingPolygon: boolean; + startPoint: Coordinate | null; + points: Coordinate[]; + startDrawingPolygon: () => void; + updatePolygon: () => void; + endDrawingPolygon: () => void; +} => { + const [polygon, setPolygon] = useState(null); + const [isDrawingPolygon, setIsDrawingPolygon] = useState(false); + const [points, setPoints] = useState([]); + const [startPoint, setStartPoint] = useState(null); + + const startDrawingPolygon = () => { + setPoints([coordinate]); + setStartPoint(coordinate); + setIsDrawingPolygon(true); + }; + + const updatePolygon = () => { + setPoints([...points, coordinate]); + setPolygon({ + shape: DrawingAreaShape.Polygon, + points: [...points, coordinate], + }); + }; + + const endDrawingPolygon = () => { + setPoints([]); + setPolygon(null); + setStartPoint(null); + setIsDrawingPolygon(false); + }; + + useEffect(() => { + if (mode !== Mode.Polygon) { + endDrawingPolygon(); + } + }, [mode]); + + return { + polygon, + isDrawingPolygon, + startPoint, + points, + startDrawingPolygon, + updatePolygon, + endDrawingPolygon, + }; +}; + +export default useDrawingPolygon; diff --git a/frontend/src/pages/ManagerSpaceEditor/units/BoardCursorDot.tsx b/frontend/src/pages/ManagerSpaceEditor/units/BoardCursorDot.tsx new file mode 100644 index 000000000..3df07927b --- /dev/null +++ b/frontend/src/pages/ManagerSpaceEditor/units/BoardCursorDot.tsx @@ -0,0 +1,20 @@ +import { EDITOR } from 'constants/editor'; +import { Coordinate } from 'types/common'; + +interface Props { + coordinate: Coordinate; +} + +const BoardCursorDot = ({ coordinate }: Props): JSX.Element => { + return ( + + ); +}; + +export default BoardCursorDot; diff --git a/frontend/src/pages/ManagerSpaceEditor/units/BoardSpace.styles.ts b/frontend/src/pages/ManagerSpaceEditor/units/BoardSpace.styles.ts index 30d8d308a..73da74ba7 100644 --- a/frontend/src/pages/ManagerSpaceEditor/units/BoardSpace.styles.ts +++ b/frontend/src/pages/ManagerSpaceEditor/units/BoardSpace.styles.ts @@ -14,6 +14,15 @@ export const SpaceRect = styled.rect` } `; +export const SpacePolygon = styled.polygon` + opacity: ${({ selected }) => (selected ? '0.5' : '0.3')}; + cursor: ${({ disabled }) => (disabled ? 'default' : 'pointer')}; + + &:hover { + ${({ disabled }) => (disabled ? '' : 'opacity: 0.2;')} + } +`; + export const SpaceText = styled.text` dominant-baseline: middle; text-anchor: middle; diff --git a/frontend/src/pages/ManagerSpaceEditor/units/BoardSpace.tsx b/frontend/src/pages/ManagerSpaceEditor/units/BoardSpace.tsx index 8fa334f97..64f33eb88 100644 --- a/frontend/src/pages/ManagerSpaceEditor/units/BoardSpace.tsx +++ b/frontend/src/pages/ManagerSpaceEditor/units/BoardSpace.tsx @@ -1,5 +1,7 @@ import { ManagerSpace } from 'types/common'; +import { DrawingAreaShape } from 'types/editor'; import { WithOptional } from 'types/util'; +import { getPolygonCenterPoint } from 'utils/editor'; import * as Styled from './BoardSpace.styles'; interface Props { @@ -12,6 +14,25 @@ interface Props { const BoardSpace = ({ space, drawing, selected, onClick }: Props): JSX.Element => { const { color, area, name } = space; + if (area.shape === DrawingAreaShape.Polygon) { + const centerPoint = getPolygonCenterPoint(area.points); + + return ( + + `${x},${y}`).join(' ')} + fill={color} + onClick={onClick} + disabled={drawing || selected} + selected={selected} + /> + + {name} + + + ); + } + return ( >]; @@ -47,7 +51,11 @@ const Editor = ({ const [movable, setMovable] = useState(pressedKey === KEY.SPACE); const { values, updateWithSpace, updateArea } = useFormContext(SpaceFormContext); - const { stickyRectCoordinate, onMouseMove: updateCoordinate } = useBoardCoordinate(board); + const { + stickyDotCoordinate, + stickyRectCoordinate, + onMouseMove: updateCoordinate, + } = useBoardCoordinate(board); const { onWheel } = useBoardZoom(boardState); const { isMoving, onDragStart, onDrag, onDragEnd, onMouseOut } = useBoardMove( @@ -57,6 +65,18 @@ const Editor = ({ const { rect, startDrawingRect, updateRect, endDrawingRect } = useDrawingRect(stickyRectCoordinate); + const { + polygon, + isDrawingPolygon, + startPoint, + points, + startDrawingPolygon, + updatePolygon, + endDrawingPolygon, + } = useDrawingPolygon({ + coordinate: stickyDotCoordinate, + mode, + }); const [isDrawing, setIsDrawing] = useState(false); const isDrawingMode = useMemo(() => drawingModes.includes(mode) && !movable, [mode, movable]); @@ -79,13 +99,18 @@ const Editor = ({ [isDrawingMode, spaces, setSelectedSpaceId, updateWithSpace] ); - const handleDrawingStart = useCallback(() => { + const handleMouseDown = useCallback(() => { if (!isDrawingMode) return; setIsDrawing(true); - if (mode === Mode.Rect) startDrawingRect(); - }, [isDrawingMode, setIsDrawing, mode, startDrawingRect]); + if (mode === Mode.Rect) { + startDrawingRect(); + } else if (mode === Mode.Polygon) { + if (isDrawingPolygon) updatePolygon(); + else startDrawingPolygon(); + } + }, [isDrawingMode, mode, startDrawingRect, isDrawingPolygon, updatePolygon, startDrawingPolygon]); const handleMouseMove: MouseEventHandler = useCallback( (event) => { @@ -97,17 +122,42 @@ const Editor = ({ updateRect(); updateArea(rect as Area); } + + if (mode === Mode.Polygon) { + updateArea(polygon as Area); + } }, - [isDrawing, isDrawingMode, mode, rect, updateArea, updateRect, updateCoordinate] + [updateCoordinate, isDrawingMode, isDrawing, mode, updateRect, updateArea, rect, polygon] ); - const handleDrawingEnd = useCallback(() => { + const handleMouseUp = useCallback(() => { if (!isDrawingMode || !isDrawing) return; + if (mode === Mode.Rect) { + endDrawingRect(); + } else if (mode === Mode.Polygon) { + if (startPoint?.x !== stickyDotCoordinate.x || startPoint?.y !== stickyDotCoordinate.y) + return; + if (points.length < EDITOR.MIN_POLYGON_SIDES) return; + + endDrawingPolygon(); + } + setMode(Mode.Form); - endDrawingRect(); setIsDrawing(false); - }, [isDrawing, isDrawingMode, setMode, endDrawingRect]); + }, [ + isDrawingMode, + isDrawing, + mode, + setMode, + endDrawingRect, + startPoint?.x, + startPoint?.y, + stickyDotCoordinate.x, + stickyDotCoordinate.y, + points.length, + endDrawingPolygon, + ]); useEffect(() => { setMovable(pressedKey === KEY.SPACE); @@ -123,8 +173,8 @@ const Editor = ({ onDragEnd={onDragEnd} onMouseOut={onMouseOut} onMouseMove={handleMouseMove} - onMouseDown={handleDrawingStart} - onMouseUp={handleDrawingEnd} + onMouseDown={handleMouseDown} + onMouseUp={handleMouseUp} onWheel={onWheel} > {values.area && ( @@ -139,10 +189,18 @@ const Editor = ({ /> )} - {isDrawingMode && ( + {mode === Mode.Rect && ( )} + {mode === Mode.Polygon && ( + <> + {startPoint && } + + + + )} + {unSelectedSpaces?.map((space, index) => ( { + return ( + `${x},${y}`).join(' ') + + ` ${stickyDotCoordinate.x},${stickyDotCoordinate.y}` + } + stroke={EDITOR.STROKE_PREVIEW} + fill={EDITOR.POLYGON_PREVIEW_FILL} + strokeWidth={EDITOR.STROKE_WIDTH} + pointerEvents="none" + /> + ); +}; + +export default PolygonPreview; diff --git a/frontend/src/pages/ManagerSpaceEditor/units/PolygonStartPoint.tsx b/frontend/src/pages/ManagerSpaceEditor/units/PolygonStartPoint.tsx new file mode 100644 index 000000000..a46aaf5ef --- /dev/null +++ b/frontend/src/pages/ManagerSpaceEditor/units/PolygonStartPoint.tsx @@ -0,0 +1,20 @@ +import { EDITOR } from 'constants/editor'; +import { Coordinate } from 'types/common'; + +interface Props { + coordinate: Coordinate; +} + +const PolygonStartPoint = ({ coordinate }: Props): JSX.Element => { + return ( + + ); +}; + +export default PolygonStartPoint; diff --git a/frontend/src/pages/ManagerSpaceEditor/units/ShapeSelectToolbar.tsx b/frontend/src/pages/ManagerSpaceEditor/units/ShapeSelectToolbar.tsx index 082386a82..d41321baf 100644 --- a/frontend/src/pages/ManagerSpaceEditor/units/ShapeSelectToolbar.tsx +++ b/frontend/src/pages/ManagerSpaceEditor/units/ShapeSelectToolbar.tsx @@ -1,4 +1,5 @@ import { ReactComponent as CloseIcon } from 'assets/svg/close.svg'; +import { ReactComponent as PolygonIcon } from 'assets/svg/polygon.svg'; import { ReactComponent as RectIcon } from 'assets/svg/rect.svg'; import useFormContext from 'hooks/useFormContext'; import { SpaceEditorMode as Mode } from 'types/editor'; @@ -30,6 +31,13 @@ const ShapeSelectToolbar = ({ mode, setMode }: Props): JSX.Element => { > + setMode(Mode.Polygon)} + > + + ); }; diff --git a/frontend/src/types/common.ts b/frontend/src/types/common.ts index 9a2dd7a5d..7b5eec9f8 100644 --- a/frontend/src/types/common.ts +++ b/frontend/src/types/common.ts @@ -49,20 +49,27 @@ interface SpaceSetting { disabledWeekdays: string[]; } -export interface Area { - shape: DrawingAreaShape; +export interface AreaRect { + shape: DrawingAreaShape.Rect; width: number; height: number; x: number; y: number; } +export interface AreaPolygon { + shape: DrawingAreaShape.Polygon; + points: Coordinate[]; +} + +export type Area = AreaRect | AreaPolygon; + export interface Space { id: number; name: string; color: Color; description: string; - area: Area; + area: AreaRect | AreaPolygon; settings: SpaceSetting; } @@ -109,7 +116,7 @@ export interface ManagerSpace { name: string; color: Color; description: string; - area: SpaceArea; + area: Area; settings: ReservationSettings; } @@ -142,11 +149,3 @@ export interface EditorBoard { y: number; scale: number; } - -export interface SpaceArea { - shape: DrawingAreaShape; - x: number; - y: number; - width: number; - height: number; -} diff --git a/frontend/src/types/editor.ts b/frontend/src/types/editor.ts index 72888f796..796d6158a 100644 --- a/frontend/src/types/editor.ts +++ b/frontend/src/types/editor.ts @@ -19,6 +19,7 @@ export enum SpaceEditorMode { export enum MapElementType { Polyline = 'polyline', Rect = 'rect', + Polygon = 'polygon', } export enum DrawingAreaShape { diff --git a/frontend/src/utils/editor.ts b/frontend/src/utils/editor.ts new file mode 100644 index 000000000..600f99b9e --- /dev/null +++ b/frontend/src/utils/editor.ts @@ -0,0 +1,16 @@ +import { Coordinate } from 'types/common'; + +export const getPolygonCenterPoint = (coordinates: Coordinate[]): Coordinate => { + const x = coordinates.map((p) => p.x); + const y = coordinates.map((p) => p.y); + + const maxX = Math.max(...x); + const maxY = Math.max(...y); + const minX = Math.min(...x); + const minY = Math.min(...y); + + return { + x: (minX + maxX) / 2, + y: (minY + maxY) / 2, + }; +}; diff --git a/frontend/src/utils/generateSvg.ts b/frontend/src/utils/generateSvg.ts index 70a80ffb2..36e83df4d 100644 --- a/frontend/src/utils/generateSvg.ts +++ b/frontend/src/utils/generateSvg.ts @@ -1,4 +1,5 @@ import { EDITOR } from 'constants/editor'; +import { DrawingAreaShape, MapElementType } from 'types/editor'; import { WithOptional } from 'types/util'; import { MapElement, ManagerSpace } from './../types/common'; @@ -12,7 +13,7 @@ export interface MapSvgData { const generateMapSvg = (mapElements: MapSvgData['mapElements']): string => mapElements .map((element) => - element.type === 'polyline' + element.type === MapElementType.Polyline ? ` const generateSpaceSvg = (spaces: MapSvgData['spaces']) => spaces - .map( - ({ color, area }) => ` + .map(({ color, area }) => + area.shape === DrawingAreaShape.Rect + ? ` /> ` + : ` + + + + ` ) .join(''); diff --git a/frontend/src/utils/map.ts b/frontend/src/utils/map.ts index 7fa212633..7e8619e6f 100644 --- a/frontend/src/utils/map.ts +++ b/frontend/src/utils/map.ts @@ -1,5 +1,6 @@ import { EDITOR } from 'constants/editor'; import { ManagerSpace, MapElement } from 'types/common'; +import { DrawingAreaShape, MapElementType } from 'types/editor'; interface CreateMapImageSvgParams { mapElements: MapElement[]; @@ -23,8 +24,9 @@ export const createMapImageSvg = ({ viewBox='0 0 ${width} ${height}' > ${spaces - ?.map( - ({ color, area }) => ` + ?.map(({ color, area }) => + area.shape === DrawingAreaShape.Rect + ? ` ` + : ` + + + + ` ) .join('')} ${mapElements .map((element) => - element.type === 'polyline' + element.type === MapElementType.Polyline ? ` Date: Tue, 12 Oct 2021 14:21:12 +0900 Subject: [PATCH 06/14] =?UTF-8?q?feat:=20k8s=20cors=20=EA=B4=80=EB=A0=A8?= =?UTF-8?q?=20origin=20=EC=84=A4=EC=A0=95=20(#632)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: k8s 준비물 추가 * refactor: dev dockerfile 삭제 * chore: dockerfile 경로 변경 * refactor: pro properties cors 관련 설정 수정 --- backend/src/main/resources/config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/resources/config b/backend/src/main/resources/config index 08479c1a9..af007654b 160000 --- a/backend/src/main/resources/config +++ b/backend/src/main/resources/config @@ -1 +1 @@ -Subproject commit 08479c1a945ec35df0137239d90ea1c499a82e62 +Subproject commit af007654b477fddf1ab0b92dfc39f5083aa844c0 From c3d46ca0757e96ef171ebc633d3d432b1ff36b97 Mon Sep 17 00:00:00 2001 From: JO YUN HO Date: Tue, 12 Oct 2021 19:34:58 +0900 Subject: [PATCH 07/14] =?UTF-8?q?test:=20=EC=98=88=EC=95=BD=20=EB=9E=9C?= =?UTF-8?q?=EB=94=A9=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80=20(#628)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/jest.config.js | 1 + frontend/src/__mocks__/mockData.ts | 2 +- frontend/src/__tests__/reservation.test.tsx | 90 ++++++--------------- 3 files changed, 27 insertions(+), 66 deletions(-) diff --git a/frontend/jest.config.js b/frontend/jest.config.js index 6ec8ec7bf..e9b4cc34c 100644 --- a/frontend/jest.config.js +++ b/frontend/jest.config.js @@ -9,4 +9,5 @@ module.exports = { '/src/__mocks__/fileMock.ts', }, setupFilesAfterEnv: ['./src/__mocks__/setupTest.ts', '@testing-library/jest-dom/extend-expect'], + setupFiles: ['@testing-library/react/dont-cleanup-after-each'], }; diff --git a/frontend/src/__mocks__/mockData.ts b/frontend/src/__mocks__/mockData.ts index 3d2a47fab..9395ea7a4 100644 --- a/frontend/src/__mocks__/mockData.ts +++ b/frontend/src/__mocks__/mockData.ts @@ -27,7 +27,7 @@ interface Reservations { export const guestMaps: GuestMaps = { JMTGR: { mapId: 1, - mapName: 'guestMap-1', + mapName: 'GUEST_TEST_MAP', mapDrawing: '{"width":800,"height":600,"mapElements":[{"id":2,"type":"rect","stroke":"#333333","points":["210,90","650,230"]},{"id":3,"type":"rect","stroke":"#333333","width":440,"height":140,"x":210,"y":90,"points":["210, 90","650, 230"]}]}', mapImageUrl: '', diff --git a/frontend/src/__tests__/reservation.test.tsx b/frontend/src/__tests__/reservation.test.tsx index 17e26aaa2..cc4a5f8a0 100644 --- a/frontend/src/__tests__/reservation.test.tsx +++ b/frontend/src/__tests__/reservation.test.tsx @@ -6,8 +6,13 @@ import { PUBLIC_ROUTES } from 'constants/routes'; import { render, screen, waitFor, within } from 'test-utils'; import { formatDate } from 'utils/datetime'; -describe('예약 페이지 조회', () => { - beforeEach(() => { +describe('예약 페이지', () => { + const date = '2021-07-01'; + const nowDate = new Date(); + const spaceId = 1; + const reservationId = 2; + + beforeAll(() => { const sharingMapId = 'JMTGR'; render( @@ -24,60 +29,35 @@ describe('예약 페이지 조회', () => { }); it('예약 목록을 조회할 수 있다.', async () => { - const date = '2021-07-01'; - const spaceId = 1; - - const $targetSpace = await waitFor(() => screen.getByTestId(spaceId)); + const $targetSpace = await screen.findByTestId(spaceId); const $targetDateInput = screen.getByDisplayValue(formatDate(new Date())); userEvent.type($targetDateInput, date); userEvent.click($targetSpace); - const reservations = await waitFor(() => screen.getAllByRole('listitem')); + const reservations = await screen.findAllByRole('listitem'); expect(reservations).toHaveLength(2); }); -}); -describe('예약 추가', () => { - beforeAll(() => { - const sharingMapId = 'JMTGR'; + it('예약을 추가할 수 있다.', async () => { + const targetDate = formatDate(nowDate); - render( - - - {PUBLIC_ROUTES.map(({ path, component }) => ( - - {component} - - ))} - - - ); - }); - - it('예약페이지에 진입할 수 있다.', async () => { - const date = new Date(); - date.setDate(date.getDate() + 1); - const targetDate = formatDate(date); - const spaceId = 1; - - const $targetSpace = await waitFor(() => screen.getByTestId(spaceId)); - const $targetDateInput = screen.getByDisplayValue(formatDate(new Date())); + const $targetSpace = await screen.findByTestId(spaceId); + const $targetDateInput = screen.getByDisplayValue('2021-07-01'); userEvent.type($targetDateInput, targetDate); userEvent.click($targetSpace); - const $reservationButton = await waitFor(() => - screen.getByRole('button', { name: /예약하기/i }) - ); + const $reservationButton = await screen.findByRole('button', { name: /예약하기/i }); + userEvent.click($reservationButton); - const $pageTitle = await waitFor(() => screen.getByTestId(/spaceName/i)); + const $pageTitle = await screen.findByTestId(/spaceName/i); expect($pageTitle).toHaveTextContent('testSpace'); - const $nameInput = await waitFor(() => screen.getByRole('textbox', { name: /이름/i })); + const $nameInput = await screen.findByRole('textbox', { name: /이름/i }); const $descriptionInput = screen.getByRole('textbox', { name: /사용 목적/i }); const $startTimeInput = screen.getByLabelText(/시작 시간/i); const $endTimeInput = screen.getByLabelText(/종료 시간/i); @@ -91,42 +71,22 @@ describe('예약 추가', () => { userEvent.type($passwordInput, '1117'); userEvent.click($submitButton); - // TODO 예약 완료 랜딩 페이지 작성 후 추가 테스트 작성 - }); -}); + const $link = await screen.findByRole('link', { name: /맵으로 돌아가기/i }); -describe('예약 삭제', () => { - beforeAll(() => { - const sharingMapId = 'JMTGR'; + userEvent.click($link); - render( - - - {PUBLIC_ROUTES.map(({ path, component }) => ( - - {component} - - ))} - - - ); + const $heading = await screen.findByRole('heading', { name: /GUEST_TEST_MAP/i }); + expect($heading).toBeTruthy(); }); - it('특정 예약을 삭제할 수 있다.', async () => { - const date = '2021-07-01'; - const spaceId = 1; - const reservationId = 2; - - const $targetSpace = await waitFor(() => screen.getByTestId(spaceId)); - const $targetDateInput = screen.getByDisplayValue(formatDate(new Date())); + it('예약을 삭제할 수 있다.', async () => { + const $targetSpace = await screen.findByTestId(spaceId); + const $targetDateInput = screen.getByDisplayValue(formatDate(nowDate)); userEvent.type($targetDateInput, date); userEvent.click($targetSpace); - const $targetReservation = await waitFor(() => - screen.getByTestId(`reservation-${reservationId}`) - ); - + const $targetReservation = screen.getByTestId(`reservation-${reservationId}`); const $deleteButton = within($targetReservation).getByRole('button', { name: /삭제/i }); userEvent.click($deleteButton); From 879cd7e04acf52c0daaa5160fe7f4572ab859e6a Mon Sep 17 00:00:00 2001 From: xrabcde Date: Wed, 13 Oct 2021 13:50:47 +0900 Subject: [PATCH 08/14] =?UTF-8?q?feat:=20=EC=9A=B4=EC=98=81=EC=9A=A9/?= =?UTF-8?q?=EA=B0=9C=EB=B0=9C=EC=9A=A9=20=EC=8A=AC=EB=9E=99=20=EC=95=8C?= =?UTF-8?q?=EB=A6=BC=20=EB=B6=84=EB=A6=AC=20=EB=B0=8F=20=EB=B2=84=EA=B7=B8?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=20(#626)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 예약 생성 시와 예약자의 예약 생성/수정/삭제 시에도 슬랙 알림 가도록 수정 * feat: 서브모듈 slack 웹훅 추가 * fix: 테스트 시 슬랙 알림 가지 않도록 수정 * feat: 서브모듈 업데이트 --- .../zzimkkong/config/SlackConfig.java | 11 ++++++++-- .../GuestReservationController.java | 15 +++++++++++--- .../ManagerReservationController.java | 3 ++- .../ReservationCreateResponse.java | 8 ++++++-- .../zzimkkong/dto/slack/Attachments.java | 18 ++++++++++++++--- .../zzimkkong/service/ReservationService.java | 4 ++-- .../zzimkkong/service/SlackService.java | 20 +++++++++++-------- .../strategy/GuestReservationStrategy.java | 6 ------ .../strategy/ManagerReservationStrategy.java | 6 ------ .../service/strategy/ReservationStrategy.java | 2 -- .../controller/AdminControllerTest.java | 5 +++++ .../GuestReservationControllerTest.java | 5 +++++ 12 files changed, 68 insertions(+), 35 deletions(-) diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/config/SlackConfig.java b/backend/src/main/java/com/woowacourse/zzimkkong/config/SlackConfig.java index 1144946af..c5cc89b54 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/config/SlackConfig.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/config/SlackConfig.java @@ -12,8 +12,15 @@ @PropertySource("classpath:config/slack.properties") public class SlackConfig implements WebMvcConfigurer { @Bean - @Profile("!test") - public SlackUrl slackUrl( + @Profile("prod") + public SlackUrl slackUrlProd( + @Value("${slack.webhook.prod}") final String prodUrl) { + return new SlackUrl(prodUrl); + } + + @Bean + @Profile("{local, dev}") + public SlackUrl slackUrlDev( @Value("${slack.webhook.local}") final String devUrl) { return new SlackUrl(devUrl); } diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/controller/GuestReservationController.java b/backend/src/main/java/com/woowacourse/zzimkkong/controller/GuestReservationController.java index bf5490d42..d9364382a 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/controller/GuestReservationController.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/controller/GuestReservationController.java @@ -2,7 +2,9 @@ import com.woowacourse.zzimkkong.config.logaspect.LogMethodExecutionTime; import com.woowacourse.zzimkkong.dto.reservation.*; +import com.woowacourse.zzimkkong.dto.slack.SlackResponse; import com.woowacourse.zzimkkong.service.ReservationService; +import com.woowacourse.zzimkkong.service.SlackService; import com.woowacourse.zzimkkong.service.strategy.GuestReservationStrategy; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.http.ResponseEntity; @@ -18,10 +20,14 @@ @RestController @RequestMapping("/api/guests/maps/{mapId}/spaces") public class GuestReservationController { + private final SlackService slackService; private final ReservationService reservationService; private final GuestReservationStrategy guestReservationStrategy; - public GuestReservationController(final ReservationService reservationService) { + public GuestReservationController( + final SlackService slackService, + final ReservationService reservationService) { + this.slackService = slackService; this.reservationService = reservationService; this.guestReservationStrategy = new GuestReservationStrategy(); } @@ -36,6 +42,7 @@ public ResponseEntity create( spaceId, reservationCreateUpdateWithPasswordRequest); ReservationCreateResponse reservationCreateResponse = reservationService.saveReservation(reservationCreateDto, guestReservationStrategy); + slackService.sendCreateMessage(reservationCreateResponse.getSlackResponse()); return ResponseEntity .created(URI.create("/api/guests/maps/" + mapId + "/spaces/" + spaceId + "/reservations/" + reservationCreateResponse.getId())) .build(); @@ -92,7 +99,8 @@ public ResponseEntity update( spaceId, reservationId, reservationCreateUpdateWithPasswordRequest); - reservationService.updateReservation(reservationUpdateDto, guestReservationStrategy); + SlackResponse slackResponse = reservationService.updateReservation(reservationUpdateDto, guestReservationStrategy); + slackService.sendUpdateMessage(slackResponse); return ResponseEntity.ok().build(); } @@ -107,7 +115,8 @@ public ResponseEntity delete( spaceId, reservationId, reservationPasswordAuthenticationRequest); - reservationService.deleteReservation(reservationAuthenticationDto, guestReservationStrategy); + SlackResponse slackResponse = reservationService.deleteReservation(reservationAuthenticationDto, guestReservationStrategy); + slackService.sendDeleteMessage(slackResponse); return ResponseEntity.noContent().build(); } } diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/controller/ManagerReservationController.java b/backend/src/main/java/com/woowacourse/zzimkkong/controller/ManagerReservationController.java index 6a53bbe82..065302749 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/controller/ManagerReservationController.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/controller/ManagerReservationController.java @@ -47,6 +47,7 @@ public ResponseEntity create( reservationCreateUpdateWithPasswordRequest, loginEmailDto); ReservationCreateResponse reservationCreateResponse = reservationService.saveReservation(reservationCreateDto, managerReservationStrategy); + slackService.sendCreateMessage(reservationCreateResponse.getSlackResponse()); return ResponseEntity .created(URI.create("/api/managers/maps/" + mapId + "/spaces/" + spaceId + "/reservations/" + reservationCreateResponse.getId())) .build(); @@ -125,7 +126,7 @@ public ResponseEntity delete( reservationId, loginEmailDto); SlackResponse slackResponse = reservationService.deleteReservation(reservationAuthenticationDto, managerReservationStrategy); - slackService.sendUpdateMessage(slackResponse); + slackService.sendDeleteMessage(slackResponse); return ResponseEntity.noContent().build(); } } diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/dto/reservation/ReservationCreateResponse.java b/backend/src/main/java/com/woowacourse/zzimkkong/dto/reservation/ReservationCreateResponse.java index 3b41e406a..26dfd6ae7 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/dto/reservation/ReservationCreateResponse.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/dto/reservation/ReservationCreateResponse.java @@ -1,6 +1,7 @@ package com.woowacourse.zzimkkong.dto.reservation; import com.woowacourse.zzimkkong.domain.Reservation; +import com.woowacourse.zzimkkong.dto.slack.SlackResponse; import lombok.Getter; import lombok.NoArgsConstructor; @@ -8,12 +9,15 @@ @NoArgsConstructor public class ReservationCreateResponse { private Long id; + private SlackResponse slackResponse; - private ReservationCreateResponse(final Long id) { + private ReservationCreateResponse(final Long id, final SlackResponse slackResponse) { this.id = id; + this.slackResponse = slackResponse; } public static ReservationCreateResponse from(final Reservation reservation) { - return new ReservationCreateResponse(reservation.getId()); + SlackResponse slackResponse = SlackResponse.from(reservation); + return new ReservationCreateResponse(reservation.getId(), slackResponse); } } diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/dto/slack/Attachments.java b/backend/src/main/java/com/woowacourse/zzimkkong/dto/slack/Attachments.java index a930fafb9..edaf7a475 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/dto/slack/Attachments.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/dto/slack/Attachments.java @@ -10,7 +10,8 @@ @NoArgsConstructor public class Attachments { private static final String COLOR = "#FF7515"; - private static final String TITLE_LINK = "https://zzimkkong.o-r.kr/"; + private static final String TITLE_LINK_MESSAGE = "예약링크 바로가기"; + private static final String TITLE_LINK = "https://zzimkkong.com"; private List messageBody; @@ -18,12 +19,23 @@ private Attachments(final List messageBody) { this.messageBody = messageBody; } + public static Attachments createMessageFrom(final SlackResponse slackResponse) { + Attachment attachment = Attachment.of( + "🎉 예약 생성 알림 🎉", + COLOR, + "🎉 예약이 생성되었습니다.", + TITLE_LINK_MESSAGE, + TITLE_LINK, + slackResponse); + return Attachments.from(attachment); + } + public static Attachments updateMessageFrom(final SlackResponse slackResponse) { Attachment attachment = Attachment.of( "✏️ 예약 수정 알림 ✏️", COLOR, "✏️ 예약이 수정되었습니다.", - "변경된 예약내용", + TITLE_LINK_MESSAGE, TITLE_LINK, slackResponse); return Attachments.from(attachment); @@ -34,7 +46,7 @@ public static Attachments deleteMessageFrom(final SlackResponse slackResponse) { "🗑 예약 삭제 알림 🗑", COLOR, "🗑 예약이 삭제되었습니다.", - "삭제된 예약내용", + TITLE_LINK_MESSAGE, TITLE_LINK, slackResponse); return Attachments.from(attachment); diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/service/ReservationService.java b/backend/src/main/java/com/woowacourse/zzimkkong/service/ReservationService.java index dbd81fbd7..6bc4fa96d 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/service/ReservationService.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/service/ReservationService.java @@ -172,7 +172,7 @@ public SlackResponse updateReservation( reservation.update(updateReservation, space); - return reservationStrategy.createSlackResponse(reservation); + return SlackResponse.from(reservation); } public SlackResponse deleteReservation( @@ -196,7 +196,7 @@ public SlackResponse deleteReservation( reservationStrategy.checkCorrectPassword(reservation, password); reservations.delete(reservation); - return reservationStrategy.createSlackResponse(reservation); + return SlackResponse.from(reservation); } private void validateTime(final ReservationCreateDto reservationCreateDto) { diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/service/SlackService.java b/backend/src/main/java/com/woowacourse/zzimkkong/service/SlackService.java index 3c7c75faf..8f1b894a1 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/service/SlackService.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/service/SlackService.java @@ -15,16 +15,24 @@ @Transactional(readOnly = true) public class SlackService { private final SlackUrl slackUrl; + private final RestTemplate restTemplate; + private final HttpHeaders headers; public SlackService(final SlackUrl slackUrl) { this.slackUrl = slackUrl; + restTemplate = new RestTemplate(); + headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); } - public void sendUpdateMessage(SlackResponse slackResponse) { - RestTemplate restTemplate = new RestTemplate(); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); + public void sendCreateMessage(SlackResponse slackResponse) { + Attachments attachments = Attachments.createMessageFrom(slackResponse); + HttpEntity requestEntity = new HttpEntity<>(attachments.toString(), headers); + + restTemplate.exchange(slackUrl.getUrl(), HttpMethod.POST, requestEntity, String.class); + } + public void sendUpdateMessage(SlackResponse slackResponse) { Attachments attachments = Attachments.updateMessageFrom(slackResponse); HttpEntity requestEntity = new HttpEntity<>(attachments.toString(), headers); @@ -32,10 +40,6 @@ public void sendUpdateMessage(SlackResponse slackResponse) { } public void sendDeleteMessage(SlackResponse slackResponse) { - RestTemplate restTemplate = new RestTemplate(); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - Attachments attachments = Attachments.deleteMessageFrom(slackResponse); HttpEntity requestEntity = new HttpEntity<>(attachments.toString(), headers); diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/service/strategy/GuestReservationStrategy.java b/backend/src/main/java/com/woowacourse/zzimkkong/service/strategy/GuestReservationStrategy.java index d9992bdd4..a72231574 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/service/strategy/GuestReservationStrategy.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/service/strategy/GuestReservationStrategy.java @@ -2,7 +2,6 @@ import com.woowacourse.zzimkkong.domain.Map; import com.woowacourse.zzimkkong.domain.Reservation; -import com.woowacourse.zzimkkong.dto.slack.SlackResponse; import com.woowacourse.zzimkkong.exception.reservation.ReservationPasswordException; import com.woowacourse.zzimkkong.repository.MemberRepository; @@ -18,9 +17,4 @@ public void checkCorrectPassword(final Reservation reservation, final String pas throw new ReservationPasswordException(); } } - - @Override - public SlackResponse createSlackResponse(final Reservation reservation) { - return null; - } } diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/service/strategy/ManagerReservationStrategy.java b/backend/src/main/java/com/woowacourse/zzimkkong/service/strategy/ManagerReservationStrategy.java index 700ef0c5e..7d352f4e6 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/service/strategy/ManagerReservationStrategy.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/service/strategy/ManagerReservationStrategy.java @@ -3,7 +3,6 @@ import com.woowacourse.zzimkkong.domain.Map; import com.woowacourse.zzimkkong.domain.Member; import com.woowacourse.zzimkkong.domain.Reservation; -import com.woowacourse.zzimkkong.dto.slack.SlackResponse; import com.woowacourse.zzimkkong.exception.authorization.NoAuthorityOnMapException; import com.woowacourse.zzimkkong.exception.member.NoSuchMemberException; import com.woowacourse.zzimkkong.repository.MemberRepository; @@ -21,9 +20,4 @@ public void validateManagerOfMap(final Map map, final MemberRepository members, public void checkCorrectPassword(final Reservation reservation, final String password) { // manager는 비밀번호 확인과정이 없으므로 생략 } - - @Override - public SlackResponse createSlackResponse(final Reservation reservation) { - return SlackResponse.from(reservation); - } } diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/service/strategy/ReservationStrategy.java b/backend/src/main/java/com/woowacourse/zzimkkong/service/strategy/ReservationStrategy.java index 96581b47b..5cebe7856 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/service/strategy/ReservationStrategy.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/service/strategy/ReservationStrategy.java @@ -9,6 +9,4 @@ public interface ReservationStrategy { void validateManagerOfMap(final Map map, final MemberRepository members, final String loginEmail); void checkCorrectPassword(final Reservation reservation, final String password); - - SlackResponse createSlackResponse(final Reservation reservation); } diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/controller/AdminControllerTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/controller/AdminControllerTest.java index 2d51795b1..c63118ed4 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/controller/AdminControllerTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/controller/AdminControllerTest.java @@ -11,6 +11,7 @@ import com.woowacourse.zzimkkong.dto.space.SpaceFindDetailWithIdResponse; import com.woowacourse.zzimkkong.infrastructure.auth.AuthorizationExtractor; import com.woowacourse.zzimkkong.service.AdminService; +import com.woowacourse.zzimkkong.service.SlackService; import io.restassured.RestAssured; import io.restassured.response.ExtractableResponse; import io.restassured.response.Response; @@ -19,6 +20,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -34,6 +36,9 @@ import static org.mockito.Mockito.mock; class AdminControllerTest extends AcceptanceTest { + @MockBean + private SlackService slackService; + private static final Member POBI = new Member(memberSaveRequest.getEmail(), memberSaveRequest.getPassword(), memberSaveRequest.getOrganization()); private static final Map LUTHER = new Map(LUTHER_NAME, MAP_DRAWING_DATA, MAP_IMAGE_URL, POBI); private static final Setting BE_SETTING = Setting.builder() diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/controller/GuestReservationControllerTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/controller/GuestReservationControllerTest.java index b85270890..f515d721c 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/controller/GuestReservationControllerTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/controller/GuestReservationControllerTest.java @@ -2,12 +2,14 @@ import com.woowacourse.zzimkkong.domain.*; import com.woowacourse.zzimkkong.dto.reservation.*; +import com.woowacourse.zzimkkong.service.SlackService; import io.restassured.RestAssured; import io.restassured.response.ExtractableResponse; import io.restassured.response.Response; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -21,6 +23,9 @@ import static org.springframework.restdocs.restassured3.RestAssuredRestDocumentation.document; class GuestReservationControllerTest extends AcceptanceTest { + @MockBean + private SlackService slackService; + private ReservationCreateUpdateWithPasswordRequest reservationCreateUpdateWithPasswordRequest; private Reservation savedReservation; private String beReservationApi; From 1a2f4afccbb6bda34f1be9459322ff495414d749 Mon Sep 17 00:00:00 2001 From: Kimun Kim Date: Wed, 13 Oct 2021 13:51:07 +0900 Subject: [PATCH 09/14] =?UTF-8?q?feat:=20Logback=EA=B3=BC=20Kafka=EB=A5=BC?= =?UTF-8?q?=20=EC=97=B0=EB=8F=99=EC=8B=9C=ED=82=A8=EB=8B=A4.=20=20(#631)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: Logstash 기본 설정 * chore: logstash 버전 명시 * chore: logstash 로그 목적지 설정 * chore: Logstash 서버 설정 * chore: 서브모듈 최신화 * chore: elk-dev 서버 주소 변경 * refactor: ControllerAdvice의 logger를 Lombok을 이용해 사용 * chore: aop 의존성 추가 * feat: 클래스단위 어노테이션으로 모든 MethodCall을 로그로 남기는 기능 구현 * feat: 어노테이션을 통해 메소드의 실행 시간을 로깅하는 기능 구현 * feat: 로깅 어노테이션에 통계상 분류를 위한 group 필드 추가 * feat: 모든 컨트롤러 메소드의 호출 기록과 실행 시간을 로깅 * refactor: LogEveryMethodCall 어노테이션 삭제 LogMethodExecutionTime와의 중복으로 인해 제거합니다. * feat: Infrastructure, Repository 클래스들의 처리 시간 및 호출 로깅 * refactor: 코드 정렬 * refactor: LogAspect 코드 정리 * docs: API 문서 깃에서 삭제 * refactor: S3Uploader 파일 삭제 * chore: 인프라 관련 appender 서브 모듈 추가 * feat: kafka appender 설정 * fix: Kafka Appender 의존성 추가 * feat: prod kafka 설정 완료된 서브모듈 커밋으로 최신화 * fix: infra-appender 서브모듈 브랜치 명시 --- .gitmodules | 4 ++++ backend/build.gradle | 2 ++ backend/src/main/resources/infra-appender | 1 + backend/src/main/resources/logback-spring.xml | 9 ++++----- 4 files changed, 11 insertions(+), 5 deletions(-) create mode 160000 backend/src/main/resources/infra-appender diff --git a/.gitmodules b/.gitmodules index 94bc38746..d87c764b7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -6,3 +6,7 @@ path = s3proxy/src/main/resources/s3proxy-config url = git@github.com:zzimkkong/s3proxy-config.git branch = main +[submodule "backend/src/main/resources/infra-appender"] + path = backend/src/main/resources/infra-appender + url = git@github.com:zzimkkong/infra-appender.git + branch = main diff --git a/backend/build.gradle b/backend/build.gradle index bf8672ed7..dca8dcb96 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -68,6 +68,8 @@ dependencies { // Logstash implementation 'net.logstash.logback:logstash-logback-encoder:6.6' + // Kafka Appender + implementation 'com.github.danielwegener:logback-kafka-appender:0.2.0-RC2' } test { diff --git a/backend/src/main/resources/infra-appender b/backend/src/main/resources/infra-appender new file mode 160000 index 000000000..1a4ed48a7 --- /dev/null +++ b/backend/src/main/resources/infra-appender @@ -0,0 +1 @@ +Subproject commit 1a4ed48a7bb9a8c399c6bc8cb5f2111e9e3c2cb9 diff --git a/backend/src/main/resources/logback-spring.xml b/backend/src/main/resources/logback-spring.xml index 7d668e8ea..f98c27402 100644 --- a/backend/src/main/resources/logback-spring.xml +++ b/backend/src/main/resources/logback-spring.xml @@ -19,13 +19,12 @@ - - + @@ -33,7 +32,7 @@ - + @@ -43,14 +42,14 @@ - + - + From 0fe95d87776fa571619884a2b6862c0662cbbc18 Mon Sep 17 00:00:00 2001 From: JO YUN HO Date: Wed, 13 Oct 2021 14:18:28 +0900 Subject: [PATCH 10/14] chore: version 1.3.0 (#637) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: production url endpoint 변경 * chore: version 1.3.0 --- frontend/package.json | 2 +- frontend/src/constants/api.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index e8bb1eb7d..956c3f05f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "zzimkkong-frontend", - "version": "1.2.0", + "version": "1.3.0", "main": "src/index.tsx", "license": "MIT", "homepage": "https://github.com/woowacourse-teams/2021-zzimkkong", diff --git a/frontend/src/constants/api.ts b/frontend/src/constants/api.ts index 030ff2007..f15132b21 100644 --- a/frontend/src/constants/api.ts +++ b/frontend/src/constants/api.ts @@ -1,4 +1,4 @@ export const BASE_URL = { DEV: 'https://dev.zzimkkong-proxy.o-r.kr/api', - PROD: 'https://zzimkkong-proxy.o-r.kr/api', + PROD: 'https://k8s.zzimkkong.com/api', }; From 16b40d4c6d225ce31fa6ecd88108dda39c817aa1 Mon Sep 17 00:00:00 2001 From: Kimun Kim Date: Wed, 13 Oct 2021 15:59:28 +0900 Subject: [PATCH 11/14] =?UTF-8?q?fix:=20SlackUrl=EC=9D=B4=20dev,=20local?= =?UTF-8?q?=20=ED=94=84=EB=A1=9C=ED=8C=8C=EC=9D=BC=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=A0=9C=EB=8C=80=EB=A1=9C=20Configuration=EC=9D=B4=20?= =?UTF-8?q?=EB=90=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0=20(#642)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: SlackUrl이 dev, local 프로파일에서 제대로 Configuration이 되지 않는 문제 해결 * fix: 프로파일 오타 수정 --- .../main/java/com/woowacourse/zzimkkong/config/SlackConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/config/SlackConfig.java b/backend/src/main/java/com/woowacourse/zzimkkong/config/SlackConfig.java index c5cc89b54..82317f2bc 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/config/SlackConfig.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/config/SlackConfig.java @@ -19,7 +19,7 @@ public SlackUrl slackUrlProd( } @Bean - @Profile("{local, dev}") + @Profile({"local", "dev"}) public SlackUrl slackUrlDev( @Value("${slack.webhook.local}") final String devUrl) { return new SlackUrl(devUrl); From 3628bb8c4f87dd65305652e99840e2f6d0ebc8b1 Mon Sep 17 00:00:00 2001 From: Jungseok Sung <58401309+sakjung@users.noreply.github.com> Date: Wed, 13 Oct 2021 17:26:30 +0900 Subject: [PATCH 12/14] =?UTF-8?q?feat:=20=EB=A9=94=EC=9D=B8=20was=20docker?= =?UTF-8?q?file=20arg=20=EC=B6=94=EA=B0=80=20(#643)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: k8s 준비물 추가 * refactor: dev dockerfile 삭제 * chore: dockerfile 경로 변경 * refactor: pro properties cors 관련 설정 수정 * refactor: dockerfile arg cluster ip 추가 --- backend/docker/main/Dockerfile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/backend/docker/main/Dockerfile b/backend/docker/main/Dockerfile index 568b00c7e..6d61bfd43 100644 --- a/backend/docker/main/Dockerfile +++ b/backend/docker/main/Dockerfile @@ -14,4 +14,9 @@ RUN mkdir zzimkkong && mkdir zzimkkong/tmp EXPOSE 8080 -ENTRYPOINT ["java", "-Dspring.profiles.active=prod", "-jar", "app.jar", "--spring.config.location=classpath:config/application-prod.properties"] +# 빌드시 명령어에 옵션 추가: --build-arg CLUSTER_IP= +ARG CLUSTER_IP + +RUN echo "${CLUSTER_IP}" + +ENTRYPOINT ["java", "-Ds3proxy.server-uri=http://${CLUSTER_IP}", "-Dspring.profiles.active=prod", "-jar", "app.jar", "--spring.config.location=classpath:config/application-prod.properties"] From e9433773feece9a15426c7c7098293de3aa55120 Mon Sep 17 00:00:00 2001 From: Kimun Kim Date: Wed, 13 Oct 2021 18:19:37 +0900 Subject: [PATCH 13/14] =?UTF-8?q?refactor:=20=EC=9A=B4=EC=98=81=20?= =?UTF-8?q?=ED=99=98=EA=B2=BD=EC=9D=98=20=EB=A1=9C=EA=B9=85=20=EB=A0=88?= =?UTF-8?q?=EB=B2=A8=EC=9D=84=20INFO=EB=A1=9C=20=ED=95=98=ED=96=A5=20(#639?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/main/resources/logback-spring.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/resources/logback-spring.xml b/backend/src/main/resources/logback-spring.xml index f98c27402..66b6055d1 100644 --- a/backend/src/main/resources/logback-spring.xml +++ b/backend/src/main/resources/logback-spring.xml @@ -47,7 +47,7 @@ - + From 5433090caf24d95b221049bbfaf18f6ff91964eb Mon Sep 17 00:00:00 2001 From: Yeonwoo Cho Date: Wed, 13 Oct 2021 18:34:23 +0900 Subject: [PATCH 14/14] =?UTF-8?q?feat:=20dockerfile=20env=EB=A1=9C=20?= =?UTF-8?q?=EB=B0=9B=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95=20(#644)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: k8s 준비물 추가 * refactor: dev dockerfile 삭제 * chore: dockerfile 경로 변경 * refactor: pro properties cors 관련 설정 수정 * refactor: dockerfile arg cluster ip 추가 * fix: dockerfile arg대신 env로 clusterIP주입받도록 수정 Co-authored-by: sakjung --- backend/docker/main/Dockerfile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/backend/docker/main/Dockerfile b/backend/docker/main/Dockerfile index 6d61bfd43..21fbba87a 100644 --- a/backend/docker/main/Dockerfile +++ b/backend/docker/main/Dockerfile @@ -15,8 +15,6 @@ RUN mkdir zzimkkong && mkdir zzimkkong/tmp EXPOSE 8080 # 빌드시 명령어에 옵션 추가: --build-arg CLUSTER_IP= -ARG CLUSTER_IP - -RUN echo "${CLUSTER_IP}" +ENV CLUSTER_IP="IP" ENTRYPOINT ["java", "-Ds3proxy.server-uri=http://${CLUSTER_IP}", "-Dspring.profiles.active=prod", "-jar", "app.jar", "--spring.config.location=classpath:config/application-prod.properties"]