류윤주 류윤주 04-02
250402 류윤주 레이아웃 수정
@5fb75658da7b08798a45af628d7dd583ce2198bb
client/resources/scss/admin/content.scss
--- client/resources/scss/admin/content.scss
+++ client/resources/scss/admin/content.scss
@@ -7,8 +7,6 @@
         height: calc(100% - 140px);
         background-color: var(--tk-white);
         box-shadow: 0 0 1rem rgba(0, 0, 0, 0.02);
-        // padding: 3rem;
-        // @include radius(30);
 
         >.content {
             height: 100%;
@@ -20,7 +18,9 @@
 
         }
         &.full-page {
-            // height: 100%;
+            height: 100%;
+        }
+        &.sch-full{
             height: calc(100% - 70px);
         }
     }
client/resources/scss/admin/layout.scss
--- client/resources/scss/admin/layout.scss
+++ client/resources/scss/admin/layout.scss
@@ -60,29 +60,76 @@
         }
 
        
-        .menu-zone{
-            p{
-                font-size: var(--tk-fz-title-sm);
-                font-weight: 700;
-                text-align: center;
-                border-bottom: 3px solid var(--tk-gray-70);
-                padding: 1rem;
-            }
-            ul.side-menu {
-                li {
-                    cursor: pointer;
-                    padding: 1rem 2rem;
+        /* 메뉴 스타일 */
+        .main-menu {
+            .menu-item {
+                position: relative;
+                cursor: pointer;
+                padding: 0 1rem;
+
+                span{
+                    display: block;
+                    padding: 1rem 0;
+
+                    &.main-active{
+                        color: #008943;
+                        font-weight: 700;
+                    }
                 }
-    
-                li.sub-active {
-                    background-color: var(--tk-primary);
-                    color: var(--tk-white);
-                    font-weight: 700;
+
+                /* 서브메뉴 스타일 */
+                .sub-menu {
+                    padding: 1rem;
+                    background: var(--tk-white);
+                    border: 1px solid #ccc;
+                    @include radius(10);
+                    display: block;
+                    width: 100%;
+
+                    >li{
+                        padding: 0 1rem;
+                        cursor: pointer;
+
+
+                        &.only-second-depth{
+                            &.sub-active{
+                                background-color: #008943;
+                                color: var(--tk-white);
+                                font-weight: 700;
+                                @include radius(10);
+                            }
+                        }
+
+                        &.has-third-depth{
+                            &.sub-active{
+                                >span{
+                                    font-weight: 700;
+                                }
+                            }
+
+                            .ss-active{
+                                background-color: #008943;
+                                color: var(--tk-white);
+                                font-weight: 700;
+                                @include radius(10);
+                            }
+                        }
+
+                        .ssub-menu{
+                            padding: 1rem;
+                            background-color: var(--tk-gray-10);
+                            @include radius(10);
+                            li{
+                                span{
+                                    padding: 1rem;
+                                }
+                            }
+                        }
+                    }
                 }
+
             }
         }
-        
-
     }
 
     .main-wrap {
client/views/component/userInfo/UserInfoInsert.vue
--- client/views/component/userInfo/UserInfoInsert.vue
+++ client/views/component/userInfo/UserInfoInsert.vue
@@ -1,5 +1,5 @@
 <template>
-  <div class="content-zone">
+  <div class="content-zone  sch-full">
     <div class="content">
       <div class="scroll">
         <div class="form-box">
client/views/component/userInfo/UserInfoView.vue
--- client/views/component/userInfo/UserInfoView.vue
+++ client/views/component/userInfo/UserInfoView.vue
@@ -1,5 +1,5 @@
 <template>
-    <div class="content-zone">
+    <div class="content-zone  sch-full">
       <div class="content">
         <div class="scroll">
           <div class="form-box">
client/views/layout/AdminHeader.vue
--- client/views/layout/AdminHeader.vue
+++ client/views/layout/AdminHeader.vue
@@ -34,7 +34,7 @@
     data() {
         return {
             mbrNm: store.state.mbrNm,
-            pgNm: store.state.menu.menuNm,
+            pgNm: store.state.menu.menuNm ? store.state.menu.menuNm : "홈",
         }
     },
     created() {
client/views/layout/AdminMenu.vue
--- client/views/layout/AdminMenu.vue
+++ client/views/layout/AdminMenu.vue
@@ -7,18 +7,22 @@
             <ul class="main-menu">
                 <li v-for="(menu, idx) in menuList" :key="idx" class="menu-item"
                     @click.stop="toggleSubMenu(menu)">
-                    <span :class="{ 'main-active': checkMenu == menu.menuId }">
+                    <span :class="{ 'main-active': isActive(menu.menuId) }">
                         {{ menu.menuNm }}
                     </span>
-                    <!-- 드롭다운 메뉴 -->
                     <ul v-if="menu.isOpen" class="sub-menu">
-                        <li v-for="(subMenu, subIdx) in menu.childList" :key="subIdx"  :class="{ 'sub-active': isActive(subMenu.routerUrl) }"
-                        @click.stop="menuClick( subMenu.routerUrl != '' && subMenu.routerUrl != null ? subMenu : subMenu.childList[0])">
-                            {{ subMenu.menuNm }}
-                            <ul v-show="subMenu.childList.length > 0">
-                                <li v-for="(third, thirdIdx) in subMenu.childList" :key="thirdIdx" :class="{
-                                    'ss-active': isActive(third.routerUrl),
-                                }" @click.stop="menuClick(third)">
+                        <li v-for="(subMenu, subIdx) in menu.childList" :key="subIdx"
+                            :class="{ 
+                                'has-third-depth': subMenu.childList && subMenu.childList.length > 0, 
+                                'only-second-depth': !(subMenu.childList && subMenu.childList.length > 0),
+                                'sub-active': isActive(subMenu.menuId),
+                            }"
+                            @click.stop="toggleSubMenu(subMenu)">
+                            <span>{{ subMenu.menuNm }}</span>
+                            <ul v-if="subMenu.isOpen && subMenu.childList.length > 0" class="ssub-menu">
+                                <li v-for="(third, thirdIdx) in subMenu.childList" :key="thirdIdx"
+                                    :class="{ 'ss-active': isActive(third.menuId) }"
+                                    @click.stop="menuClick(third)">
                                     <span>{{ third.menuNm }}</span>
                                 </li>
                             </ul>
@@ -41,10 +45,11 @@
     mixins: [queryParams, cntnStatsSave],
     data() {
         return {
-            checkMenu: null,
+            // checkMenu: null,
             currentPath: this.$route.path,
             resetSearch: { ...defaultSearchParams },
             menuList: [],
+            activeMenus: [] // 현재 선택된 메뉴 및 부모 메뉴 ID 저장
         };
     },
     created() {
@@ -69,10 +74,16 @@
                     // `isOpen` 속성을 추가하여 초기 상태 설정
                     this.menuList = res.data.data.menuList.map(menu => ({
                         ...menu,
-                        isOpen: false,
+                        isOpen: false, // 1뎁스 닫힘
+                        childList: menu.childList.map(sub => ({
+                            ...sub,
+                            isOpen: false // 2뎁스도 닫힘
+                        }))
                     }));
                     // 전체 메뉴 트리 store에 저장
                     this.$store.commit('setMenuList', this.menuList);
+
+                    console.log("menulist",this.menuList)
                 }
             } catch (error) {
                 alert('에러가 발생했습니다.\n관리자에게 문의하세요.');
@@ -82,6 +93,9 @@
             this.saveQueryParams("queryParams", this.resetSearch); // 검색조건 초기화
             this.$store.commit('setMenu', menu);
             await this.cntnStatsSave(menu.menuId);
+
+            // 선택된 메뉴 및 부모 메뉴 추적
+            this.activeMenus = this.getParentMenus(menu);
             if (menu.linkType === "0") {
                 // 현재창
                 this.$router.push({
@@ -93,46 +107,46 @@
             }
         },
         toggleSubMenu(menu) {
-            menu.isOpen = !menu.isOpen;
-            this.checkMenu = menu.menuId;
-            // this.saveQueryParams('queryParams', this.resetSearch); // 검색조건 초기화
+            if (menu.childList && menu.childList.length > 0) {
+                // 부모 메뉴 클릭 시 펼치기만 함
+                menu.isOpen = !menu.isOpen;
+            } else {
+                // 2뎁스 또는 3뎁스 선택 시 menuClick 실행
+                this.menuClick(menu);
+            }
         },
 
-        isActive(subPath) {
-            const checkUrl = this.currentPath.substring(
-                0,
-                this.currentPath.lastIndexOf("/") + 1
-            );
-            return subPath.startsWith(checkUrl);
+        isActive(menuId) {
+            return this.activeMenus.includes(menuId);
         },
+
+        getParentMenus(menu) {
+            let parents = [];
+            while (menu) {
+                parents.push(menu.menuId);
+                menu = this.findParent(menu);
+            }
+            return parents;
+        },
+        findParent(menu) {
+            for (const parent of this.menuList) {
+                if (parent.childList && parent.childList.includes(menu)) {
+                    return parent;
+                }
+                for (const child of parent.childList || []) {
+                    if (child.childList && child.childList.includes(menu)) {
+                        return child;
+                    }
+                }
+            }
+            return null;
+        }
     },
     watch: {
-        // '$store.state.menu'(newValue) {
-        //     this.checkMenu = newValue ? newValue.menuId : null;
-        // },
         // 나중에 네비게이션 가드에서 form 받을 수 있으면 form adm/main으로 갈때 sotre.state값0로 바꿔주기
         $route(to) {
         this.currentPath = to.path;
         },
-        // async "$store.state.menu"(newVal) {
-        //     console.log(newVal)
-        //     if (newVal == null || newVal == "" || newVal == undefined) {
-        //         this.menuList = [];
-        //     } else {
-        //         this.menuList = newVal.childList;
-        //         if (newVal && this.menuList.length > 0) {
-        //         await this.cntnStatsSave(this.menuList[0].menuId);
-        //             if (
-        //                 newVal.menuId == "MENU_000000000000010" &&
-        //                 this.$store.state.path.includes("BBS_MNG_")
-        //             ) {
-        //                 return;
-        //             } else {
-        //                 this.$router.push(this.menuList[0].routerUrl);
-        //             }
-        //         }
-        //     }
-        // },
         "$store.state.mbrNm"(newVal) {
             this.mbrNm = newVal;
         },
@@ -140,38 +154,3 @@
 };
 </script>
 
-<style scoped>
-/* 메뉴 스타일 */
-.main-menu {
-    list-style: none;
-    padding: 0;
-    margin: 0;
-}
-
-.menu-item {
-    position: relative;
-    cursor: pointer;
-    padding: 10px;
-    border-bottom: 1px solid #ccc;
-}
-
-/* 서브메뉴 스타일 */
-.sub-menu {
-    list-style: none;
-    padding: 5px 0;
-    margin: 0;
-    background: white;
-    border: 1px solid #ccc;
-    display: block;
-    width: 100%;
-}
-
-.sub-menu li {
-    padding: 8px 15px;
-    cursor: pointer;
-}
-
-.sub-menu li:hover {
-    background-color: #f0f0f0;
-}
-</style>
client/views/pages/adm/authority/authority/AuthorityInsert.vue
--- client/views/pages/adm/authority/authority/AuthorityInsert.vue
+++ client/views/pages/adm/authority/authority/AuthorityInsert.vue
@@ -1,5 +1,5 @@
 <template>
-  <div class="content-zone">
+  <div class="content-zone sch-full">
     <div class="content">
       <div class="scroll">
         <div class="form-box">
client/views/pages/adm/authority/authority/AuthoritySelectListOne.vue
--- client/views/pages/adm/authority/authority/AuthoritySelectListOne.vue
+++ client/views/pages/adm/authority/authority/AuthoritySelectListOne.vue
@@ -1,5 +1,5 @@
 <template>
-  <div class="content-zone">
+  <div class="content-zone sch-full">
     <div class="content">
       <div class="scroll">
         <div class="form-box">
client/views/pages/adm/authority/menuAuthority/MenuAuthority.vue
--- client/views/pages/adm/authority/menuAuthority/MenuAuthority.vue
+++ client/views/pages/adm/authority/menuAuthority/MenuAuthority.vue
@@ -1,5 +1,5 @@
 <template>
-  <div class="content-zone">
+  <div class="content-zone  sch-full">
     <div class="content">
         <!-- <div class="scroll"> -->
           <div class="setting-box">
client/views/pages/adm/boardManagement/boardManagement/BoardManagementInsert.vue
--- client/views/pages/adm/boardManagement/boardManagement/BoardManagementInsert.vue
+++ client/views/pages/adm/boardManagement/boardManagement/BoardManagementInsert.vue
@@ -1,5 +1,5 @@
 <template>
-    <div class="content-zone">
+    <div class="content-zone  sch-full">
         <div class="content">
             <div class="scroll">
                 <div class="form-box">
client/views/pages/adm/boardManagement/boardManagement/BoardManagementSelectListOne.vue
--- client/views/pages/adm/boardManagement/boardManagement/BoardManagementSelectListOne.vue
+++ client/views/pages/adm/boardManagement/boardManagement/BoardManagementSelectListOne.vue
@@ -1,5 +1,5 @@
 <template>
-  <div class="content-zone">
+  <div class="content-zone  sch-full">
     <div class="content">
       <div class="scroll">
         <div class="form-box mb30">
client/views/pages/adm/boardManagement/template/commonTemplate/CommonInsert.vue
--- client/views/pages/adm/boardManagement/template/commonTemplate/CommonInsert.vue
+++ client/views/pages/adm/boardManagement/template/commonTemplate/CommonInsert.vue
@@ -37,7 +37,7 @@
 
     <!-- 관리자 -->
     <template v-else>
-      <div  class="content-zone">
+      <div  class="content-zone  sch-full">
         <div class="content">
           <div class="scroll">
             <div class="tbl-wrap">
client/views/pages/adm/boardManagement/template/commonTemplate/CommonSelectListOne.vue
--- client/views/pages/adm/boardManagement/template/commonTemplate/CommonSelectListOne.vue
+++ client/views/pages/adm/boardManagement/template/commonTemplate/CommonSelectListOne.vue
@@ -143,7 +143,7 @@
   </template>
   <!-- 관리자 -->
   <template v-else>
-    <div class="content-zone">
+    <div class="content-zone  sch-full">
       <div class="content">
         <div class="scroll">
           <div class="tbl-wrap">
client/views/pages/adm/boardManagement/template/galleryTemplate/GallerySelectList.vue
--- client/views/pages/adm/boardManagement/template/galleryTemplate/GallerySelectList.vue
+++ client/views/pages/adm/boardManagement/template/galleryTemplate/GallerySelectList.vue
@@ -53,6 +53,19 @@
         </div>
     </template>
     <template v-else>
+        <div class="search-bar">
+            <select name="" id="" class="form-select sm" v-model="search.searchType">
+                <option value="">전체</option>
+                <option v-for="(item, idx) in codeList" :key="idx" :value="item.cd">{{ item.cdNm }}</option>
+            </select>
+            <input type="text" class="form-control sm"
+                placeholder="검색어를 입력하세요." v-model="search.searchText" @keyup.enter="findAll">
+
+
+            <button @click="findAll">검색</button>
+    
+            <!-- <button class="large-btn darkg-border-btn" @click="fnSearchReset"><svg-icon type="mdi" :path="refreshPath"></svg-icon> 초기화</button> -->
+        </div>
         <div class="content-zone">
             <div class="content">
                 <div class="scroll">
@@ -60,19 +73,6 @@
                         <div  class="page-title">
                         <p>{{ bbsMng.bbsNm }}</p>
                         </div>
-                    </div>
-                    <div class="search-bar">
-                        <select name="" id="" class="form-select sm" v-model="search.searchType">
-                            <option value="">전체</option>
-                            <option v-for="(item, idx) in codeList" :key="idx" :value="item.cd">{{ item.cdNm }}</option>
-                        </select>
-                        <input type="text" class="form-control sm"
-                            placeholder="검색어를 입력하세요." v-model="search.searchText" @keyup.enter="findAll">
-
-
-                        <button @click="findAll">검색</button>
-                
-                        <!-- <button class="large-btn darkg-border-btn" @click="fnSearchReset"><svg-icon type="mdi" :path="refreshPath"></svg-icon> 초기화</button> -->
                     </div>
                     <div class="gall-content">
                         <div v-for="(item, idx) in list" :key="idx" @click="fnView(idx)" class="gall-item">
client/views/pages/adm/menuManagement/menuManagement/MenuManagement.vue
--- client/views/pages/adm/menuManagement/menuManagement/MenuManagement.vue
+++ client/views/pages/adm/menuManagement/menuManagement/MenuManagement.vue
@@ -1,5 +1,5 @@
 <template>
-  <div class="content-zone">
+  <div class="content-zone sch-full">
     <div class="content">
       <div class="setting-box">
           <div class="node-zone">
client/views/pages/adm/menuManagement/menuSatisfactionManagement/MenuSatisfactionSelectList.vue
--- client/views/pages/adm/menuManagement/menuSatisfactionManagement/MenuSatisfactionSelectList.vue
+++ client/views/pages/adm/menuManagement/menuSatisfactionManagement/MenuSatisfactionSelectList.vue
@@ -1,5 +1,5 @@
 <template>
-  <div class="content-zone">
+  <div class="content-zone sch-full">
     <div class="content">
       <div class="scroll">
         <div class="tbl-wrap">
@@ -26,7 +26,7 @@
   </div>
   <div class="btn-wrap">
       <div></div>
-        <PaginationButton :className="'admin-pagination'" />
+        <PaginationButton :className="'pagination'" />
       <div></div>
     </div>
   <Modal :showModal="satisfaction" :className="'large-modal'">
client/views/pages/adm/popup/PopupManagementInsert.vue
--- client/views/pages/adm/popup/PopupManagementInsert.vue
+++ client/views/pages/adm/popup/PopupManagementInsert.vue
@@ -1,5 +1,5 @@
 <template>
-  <div class="content-zone">
+  <div class="content-zone sch-full">
     <div class="content">
       <div class="scroll">
         <div class="form-box">
client/views/pages/adm/popup/PopupManagementSelectListOne.vue
--- client/views/pages/adm/popup/PopupManagementSelectListOne.vue
+++ client/views/pages/adm/popup/PopupManagementSelectListOne.vue
@@ -1,5 +1,5 @@
 <template>
-  <div class="content-zone">
+  <div class="content-zone sch-full">
     <div class="content">
       <div class="scroll">
         <div class="form-box">
client/views/pages/adm/preferences/commonCodeManagement/CommonCodeManagement.vue
--- client/views/pages/adm/preferences/commonCodeManagement/CommonCodeManagement.vue
+++ client/views/pages/adm/preferences/commonCodeManagement/CommonCodeManagement.vue
@@ -1,5 +1,5 @@
 <template>
-  <div class="content-zone">
+  <div class="content-zone sch-full">
     <div class="content">
       <div class="setting-box">
           <div class="node-zone">
client/views/pages/adm/preferences/contentTypeManagement/ContentTypeManagementInsert.vue
--- client/views/pages/adm/preferences/contentTypeManagement/ContentTypeManagementInsert.vue
+++ client/views/pages/adm/preferences/contentTypeManagement/ContentTypeManagementInsert.vue
@@ -1,5 +1,5 @@
 <template>
-  <div class="content-zone">
+  <div class="content-zone  sch-full">
     <div class="content">
       <div class="scroll">
         <div class="form-box">
client/views/pages/adm/preferences/contentTypeManagement/ContentTypeManagementSelectList.vue
--- client/views/pages/adm/preferences/contentTypeManagement/ContentTypeManagementSelectList.vue
+++ client/views/pages/adm/preferences/contentTypeManagement/ContentTypeManagementSelectList.vue
@@ -19,7 +19,7 @@
             :colgroup="colgroup"
             :thead="thead"
             :tbody="tbody"
-            :className="'data'"
+            :className="'data cursor'"
             @listClick="fnViewDetail"
           />
         </div>
client/views/pages/adm/preferences/contentTypeManagement/ContentTypeManagementSelectListOne.vue
--- client/views/pages/adm/preferences/contentTypeManagement/ContentTypeManagementSelectListOne.vue
+++ client/views/pages/adm/preferences/contentTypeManagement/ContentTypeManagementSelectListOne.vue
@@ -1,5 +1,5 @@
 <template>
-  <div class="content-zone">
+  <div class="content-zone sch-full">
     <div class="content">
       <div class="scroll">
         <div class="form-box">
client/views/pages/adm/statistics/BbsStatistics.vue
--- client/views/pages/adm/statistics/BbsStatistics.vue
+++ client/views/pages/adm/statistics/BbsStatistics.vue
@@ -46,7 +46,7 @@
         다운로드
       </button>
   </div>
-  <div class="content-zone full-page">
+  <div class="content-zone sch-full">
     <div class="content">
       <div class="scroll">
         <div class="chart-zone mb30" v-show="bbsCnt > 0">
client/views/pages/adm/statistics/MenuStatistics.vue
--- client/views/pages/adm/statistics/MenuStatistics.vue
+++ client/views/pages/adm/statistics/MenuStatistics.vue
@@ -46,7 +46,7 @@
         다운로드
       </button>
   </div>
-  <div class="content-zone full-page">
+  <div class="content-zone sch-full">
     <div class="content">
       <div class="scroll">
         <div class="chart-zone mb30" v-show="menuCnt > 0">
client/views/pages/adm/statistics/UserStatistics.vue
--- client/views/pages/adm/statistics/UserStatistics.vue
+++ client/views/pages/adm/statistics/UserStatistics.vue
@@ -50,7 +50,7 @@
     </button>
 
   </div>
-  <div class="content-zone full-page">
+  <div class="content-zone sch-full">
     <div class="content">
       <div class="scroll">
         <div class="chart-zone mb30">
client/views/pages/adm/system/LoginPolicy/LoginPolicy.vue
--- client/views/pages/adm/system/LoginPolicy/LoginPolicy.vue
+++ client/views/pages/adm/system/LoginPolicy/LoginPolicy.vue
@@ -1,5 +1,5 @@
 <template>
-  <div class="content-zone">
+  <div class="content-zone full-page">
     <div class="content">
       <div class="scroll">
         <div open class="form-box">
client/views/pages/adm/system/contextPath/ContextPathSelectList.vue
--- client/views/pages/adm/system/contextPath/ContextPathSelectList.vue
+++ client/views/pages/adm/system/contextPath/ContextPathSelectList.vue
@@ -1,20 +1,20 @@
 <template>
+  <div class="search-bar">
+    <input
+      type="text"
+      class="form-control sm"
+      placeholder="경로를 입력하세요."
+      v-model="search.searchText"
+      @keyup.enter="findAll"
+    />
+
+    <button class="btn sm ico-sch" @click="findAll">
+      검색
+    </button>
+  </div>
   <div class="content-zone">
     <div class="content">
       <div class="scroll">
-        <div class="search-bar ">
-                <input
-                  type="text"
-                  class="form-control sm"
-                  placeholder="경로를 입력하세요."
-                  v-model="search.searchText"
-                  @keyup.enter="findAll"
-                />
-
-              <button class="btn sm ico-sch" @click="findAll">
-                검색
-              </button>
-        </div>
         <div class="tbl-wrap">
           <ListTable
             :className="'data cursor'"
client/views/pages/adm/system/networkAccessControl/NetworkAccessControlInsert.vue
--- client/views/pages/adm/system/networkAccessControl/NetworkAccessControlInsert.vue
+++ client/views/pages/adm/system/networkAccessControl/NetworkAccessControlInsert.vue
@@ -1,5 +1,5 @@
 <template>
-    <div class="content-zone">
+    <div class="content-zone sch-full">
         <div class="content">
             <div class="scroll">
                 <div class="form-box">
client/views/pages/adm/system/networkAccessControl/NetworkAccessControlSelectListOne.vue
--- client/views/pages/adm/system/networkAccessControl/NetworkAccessControlSelectListOne.vue
+++ client/views/pages/adm/system/networkAccessControl/NetworkAccessControlSelectListOne.vue
@@ -1,5 +1,5 @@
 <template>
-  <div class="content-zone">
+  <div class="content-zone sch-full">
     <div class="content">
       <div class="scroll">
         <div open class="form-box">
Add a comment
List