diff --git a/frontend/src/components/view/admin/pgBoard/SampleBoardPage.vue b/frontend/src/components/view/admin/pgBoard/SampleBoardPage.vue index 5fe372b..11b4fea 100644 --- a/frontend/src/components/view/admin/pgBoard/SampleBoardPage.vue +++ b/frontend/src/components/view/admin/pgBoard/SampleBoardPage.vue @@ -4,20 +4,85 @@
- -
- - Total {{ $filters.numberFormat(boardList.length) }} - -
- - + + + +
@@ -157,6 +167,29 @@ export default { }, }; }, + // 화면 파생 상태를 계산한다. + computed: { + // 현재 상세 화면 여부를 반환한다. + isDetailView() { + // 상세 조회 또는 등록 요청 여부를 반환한다. + return Boolean(this.getRouteDetailId()) || this.$route.query.mode === 'create'; + }, + }, + // 라우트 쿼리 변경을 감시한다. + watch: { + // 상세 화면 전환을 처리한다. + '$route.query': { + // 쿼리가 바뀔 때마다 화면 상태를 동기화한다. + handler() { + // 현재 라우트 상태에 맞춰 화면을 전환한다. + this.syncRouteState(); + }, + // 컴포넌트 초기 진입 시에도 즉시 실행한다. + immediate: false, + // 중첩된 쿼리 변경도 감시한다. + deep: true, + }, + }, // 화면 동작 메서드를 정의한다. methods: { // 빈 입력 폼 객체를 생성한다. @@ -179,6 +212,41 @@ export default { init() { // 목록을 먼저 조회한다. this.fetchBoardList(); + // 현재 라우트 상태를 화면에 반영한다. + this.syncRouteState(); + }, + // 라우트 쿼리에서 상세 식별자를 추출한다. + getRouteDetailId() { + // 상세 식별자 원본 값을 읽는다. + const detailId = Number(this.$route.query.detailId); + // 상세 식별자가 없거나 숫자가 아니면 null을 반환한다. + if (!this.$route.query.detailId || Number.isNaN(detailId)) { + // 유효한 상세 식별자가 없음을 반환한다. + return null; + } + // 숫자로 변환된 상세 식별자를 반환한다. + return detailId; + }, + // 현재 라우트 상태에 맞는 화면을 구성한다. + syncRouteState() { + // 라우트에서 상세 식별자를 읽는다. + const detailId = this.getRouteDetailId(); + // 상세 식별자가 있으면 상세 데이터를 조회한다. + if (detailId) { + // 상세 조회를 수행한다. + this.selectBoard(detailId); + // 상세 화면 처리 후 메서드를 종료한다. + return; + } + // 등록 화면 요청이면 빈 폼으로 초기화한다. + if (this.$route.query.mode === 'create') { + // 등록용 폼으로 초기화한다. + this.resetForm(); + // 등록 화면 처리 후 메서드를 종료한다. + return; + } + // 목록 화면이면 폼 상태를 기본값으로 되돌린다. + this.resetForm(); }, // 게시글 목록을 조회한다. async fetchBoardList() { @@ -199,6 +267,11 @@ export default { }, // 게시글 상세를 조회한다. async selectBoard(id) { + // 식별자가 없으면 함수 실행을 종료한다. + if (!id) { + // 함수 실행을 종료한다. + return; + } // 로딩 바를 표시한다. SDLUtil.showLoadingBar(true); try { @@ -227,6 +300,45 @@ export default { SDLUtil.showLoadingBar(false); } }, + // 상세 화면으로 이동한다. + openBoardDetail(id) { + // 이동할 식별자가 없으면 종료한다. + if (!id) { + // 함수 실행을 종료한다. + return; + } + // 이미 같은 상세 화면이면 중복 이동을 생략한다. + if (this.getRouteDetailId() === id) { + // 함수 실행을 종료한다. + return; + } + // 상세 화면 쿼리로 이동한다. + this.$router.push({ path: this.$route.path, query: { detailId: id } }); + }, + // 신규 등록 상세 화면으로 이동한다. + moveToCreate() { + // 이미 등록 화면이면 중복 이동을 생략한다. + if (this.$route.query.mode === 'create') { + // 폼만 다시 초기화한다. + this.resetForm(); + // 함수 실행을 종료한다. + return; + } + // 등록 화면 쿼리로 이동한다. + this.$router.push({ path: this.$route.path, query: { mode: 'create' } }); + }, + // 목록 화면으로 이동한다. + moveToList() { + // 이미 목록 화면이면 폼만 초기화한다. + if (Object.keys(this.$route.query).length === 0) { + // 폼 상태를 초기화한다. + this.resetForm(); + // 함수 실행을 종료한다. + return; + } + // 목록 화면 쿼리로 이동한다. + this.$router.push({ path: this.$route.path, query: {} }); + }, // 입력 폼을 신규 등록 상태로 초기화한다. resetForm() { // 모드를 등록으로 변경한다. @@ -295,10 +407,25 @@ export default { } // 저장 후 목록을 새로 조회한다. await this.fetchBoardList(); - // 저장된 게시글이 있으면 상세를 다시 로드한다. + // 저장된 게시글이 있으면 상세 화면 상태를 유지한다. if (savedData && savedData.id) { - // 저장된 게시글 상세를 선택한다. - await this.selectBoard(savedData.id); + // 저장된 결과를 현재 폼에 반영한다. + this.form = { + // 게시글 번호를 반영한다. + id: savedData.id, + // 제목을 반영한다. + title: savedData.title, + // 내용을 반영한다. + content: savedData.content, + // 작성자를 반영한다. + author: savedData.author, + // 등록일을 반영한다. + createdAt: savedData.createdAt, + }; + // 수정 모드로 전환한다. + this.mode = 'EDIT'; + // 저장된 게시글 상세 화면으로 주소를 동기화한다. + this.$router.replace({ path: this.$route.path, query: { detailId: savedData.id } }); } // 저장 완료 알림을 출력한다. SDLUtil.alert('저장되었습니다.'); @@ -337,8 +464,8 @@ export default { await axios.delete(`${SDLUtil.API_URL}/pg-board/samples/${id}`); // 삭제 후 목록을 새로 조회한다. await this.fetchBoardList(); - // 삭제 후 폼을 초기화한다. - this.resetForm(); + // 삭제 후 목록 화면으로 이동한다. + this.moveToList(); // 삭제 완료 알림을 출력한다. SDLUtil.alert('삭제되었습니다.'); } catch (err) { @@ -373,9 +500,11 @@ export default {