Files
PM_test/통합관리자대시보드_화면설계서.html
2026-06-12 17:14:03 +09:00

587 lines
27 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PM_ver4 통합 관리자 어플리케이션 화면설계서</title>
<!-- Google Fonts - Inter & Noto Sans KR -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Noto+Sans+KR:wght@300;400;500;700&display=swap" rel="stylesheet">
<style>
:root {
--primary: #1e5149;
--primary-dark: #142e29;
--primary-soft: #e9eeed;
--border: #d2dcdb;
--accent: #4db251;
--bg: #f4f7f6;
--card-bg: #ffffff;
--text-main: #1f2937;
--text-muted: #4b5563;
--shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -2px rgba(0, 0, 0, 0.05);
--sidebar-width: 280px;
/* UI Status Colors */
--color-active: #4db251;
--bg-active: #eef8ee;
--color-inactive: #a5b9b6;
--bg-inactive: #f1f5f9;
--color-danger: #ef4444;
--bg-danger: #fee2e2;
--color-warning: #ff9800;
--bg-warning: #fff5e6;
}
* {
box-sizing: border-box;
}
body {
font-family: 'Inter', 'Noto Sans KR', sans-serif;
background-color: var(--bg);
color: var(--text-main);
line-height: 1.7;
margin: 0;
padding: 0;
display: flex;
}
/* Sidebar Navigation */
aside {
width: var(--sidebar-width);
background: linear-gradient(180deg, var(--primary-dark) 0%, #0c1a18 100%);
color: #ffffff;
height: 100vh;
position: fixed;
top: 0;
left: 0;
overflow-y: auto;
border-right: 1px solid rgba(255, 255, 255, 0.1);
padding: 24px;
z-index: 100;
}
aside h2 {
font-size: 1.15rem;
font-weight: 700;
margin-bottom: 24px;
color: var(--accent);
display: flex;
align-items: center;
gap: 8px;
border-bottom: 1px solid rgba(255, 255, 255, 0.15);
padding-bottom: 12px;
}
aside ul {
list-style: none;
padding: 0;
margin: 0;
}
aside li {
margin-bottom: 8px;
}
aside a {
color: #b3c5c2;
text-decoration: none;
font-size: 0.9rem;
display: block;
padding: 8px 12px;
border-radius: 6px;
transition: all 0.2s ease;
}
aside a:hover, aside li.active a {
color: #ffffff;
background-color: rgba(255, 255, 255, 0.08);
padding-left: 16px;
}
aside .category-title {
font-size: 0.75rem;
text-transform: uppercase;
letter-spacing: 0.05em;
color: #628781;
margin: 16px 0 8px 12px;
font-weight: 700;
}
/* Main Content */
main {
margin-left: var(--sidebar-width);
flex-grow: 1;
padding: 40px 50px;
max-width: 1000px;
}
header {
border-bottom: 2px solid var(--border);
padding-bottom: 24px;
margin-bottom: 40px;
}
header h1 {
font-size: 2.2rem;
font-weight: 700;
margin: 0 0 10px 0;
color: var(--primary);
}
header .subtitle {
font-size: 1.1rem;
color: var(--text-muted);
margin: 0;
}
/* Content Sections */
section {
background-color: var(--card-bg);
border-radius: 12px;
padding: 30px;
margin-bottom: 30px;
box-shadow: var(--shadow);
border: 1px solid var(--border);
}
h2.section-title {
font-size: 1.4rem;
font-weight: 700;
color: var(--primary);
margin-top: 0;
margin-bottom: 20px;
border-left: 4px solid var(--accent);
padding-left: 12px;
}
h3 {
font-size: 1.2rem;
font-weight: 600;
color: var(--primary-dark);
margin-top: 24px;
margin-bottom: 12px;
border-bottom: 1px solid #f1f5f9;
padding-bottom: 8px;
}
h4 {
font-size: 1.05rem;
font-weight: 600;
color: var(--primary);
margin-top: 16px;
margin-bottom: 8px;
}
p {
margin: 0 0 16px 0;
color: var(--text-main);
}
/* Color Chips */
.color-palette {
display: flex;
flex-wrap: wrap;
gap: 16px;
margin: 20px 0;
}
.color-chip {
flex: 1 1 200px;
border: 1px solid var(--border);
border-radius: 8px;
overflow: hidden;
background-color: #ffffff;
box-shadow: var(--shadow);
}
.color-box {
height: 60px;
width: 100%;
}
.color-details {
padding: 10px 12px;
}
.color-name {
font-weight: 700;
font-size: 0.85rem;
margin-bottom: 2px;
}
.color-value {
font-family: monospace;
font-size: 0.8rem;
color: var(--text-muted);
}
/* Layout Preview map */
.layout-preview {
background-color: #1e293b;
color: #cbd5e1;
padding: 20px;
border-radius: 8px;
font-family: monospace;
font-size: 0.8rem;
white-space: pre;
overflow-x: auto;
margin: 20px 0;
line-height: 1.4;
}
/* Status Badge */
.status-badge {
display: inline-block;
padding: 2px 8px;
border-radius: 4px;
font-size: 0.8rem;
font-weight: 600;
}
.status-badge-active { background-color: var(--bg-active); color: var(--color-active); }
.status-badge-inactive { background-color: var(--bg-inactive); color: var(--color-inactive); }
.status-badge-danger { background-color: var(--bg-danger); color: var(--color-danger); }
.status-badge-warning { background-color: var(--bg-warning); color: var(--color-warning); }
/* Tables */
table {
width: 100%;
border-collapse: collapse;
margin: 16px 0;
font-size: 0.88rem;
border-radius: 8px;
overflow: hidden;
border: 1px solid var(--border);
}
th {
background-color: var(--primary-soft);
color: var(--primary-dark);
font-weight: 600;
text-align: left;
padding: 10px 14px;
border-bottom: 2px solid var(--border);
}
td {
padding: 10px 14px;
border-bottom: 1px solid var(--border);
color: var(--text-main);
}
tr:last-child td {
border-bottom: none;
}
/* Lists */
ul {
padding-left: 20px;
margin-bottom: 16px;
}
li {
margin-bottom: 6px;
}
.spec-card {
border: 1px solid var(--border);
border-radius: 8px;
padding: 16px;
margin-bottom: 16px;
background-color: #f9fafb;
}
</style>
</head>
<body>
<!-- Sidebar Navigation -->
<aside>
<h2>📁 PM_ver4 Spec</h2>
<ul>
<li><a href="#overview">설계서 소개</a></li>
</ul>
<div class="category-title">01. 디자인 시스템</div>
<ul>
<li><a href="#design-system">디자인 가이드라인</a></li>
</ul>
<div class="category-title">02. 공통 프레임</div>
<ul>
<li><a href="#layout">App Frame 레이아웃</a></li>
</ul>
<div class="category-title">03. 화면별 UI/UX 명세</div>
<ul>
<li><a href="#screen-dashboard">📊 종합 용량 및 접속자</a></li>
<li><a href="#screen-project">🏗️ 프로젝트 관리</a></li>
<li><a href="#screen-banner">📢 실시간 배너 공지</a></li>
<li><a href="#screen-user">👥 사용자 관리</a></li>
<li><a href="#screen-audit">🔎 감사 로그 조회</a></li>
<li><a href="#screen-policy">⚙️ 보관 및 삭제 설정</a></li>
<li><a href="#screen-codes">🔑 공통 코드 관리</a></li>
</ul>
</aside>
<!-- Main Content -->
<main>
<header id="overview">
<h1>PM_ver4 통합 관리자 어플리케이션 화면설계서</h1>
<p class="subtitle">UI/UX Specification - 대시보드 및 관리자 화면 기능 명세서</p>
</header>
<!-- Section 1 -->
<section id="design-system">
<h2 class="section-title">1. 공통 UI 가이드라인 및 디자인 시스템</h2>
<p>관리자 패널의 모든 화면 레이아웃, 컴포넌트 명세, 사용자 액션 및 데이터 정합성 검증 규칙은 본 시스템의 디자인 규칙을 준수합니다.</p>
<h3>① 색상 토큰 (Color Tokens)</h3>
<div class="color-palette">
<div class="color-chip">
<div class="color-box" style="background-color: #1e5149;"></div>
<div class="color-details">
<div class="color-name">Primary Forest Green</div>
<div class="color-value">#1e5149</div>
</div>
</div>
<div class="color-chip">
<div class="color-box" style="background-color: #142e29;"></div>
<div class="color-details">
<div class="color-name">Dark Teal Sidebar</div>
<div class="color-value">#142e29</div>
</div>
</div>
<div class="color-chip">
<div class="color-box" style="background-color: #d2dcdb;"></div>
<div class="color-details">
<div class="color-name">Light Green Gray Border</div>
<div class="color-value">#d2dcdb</div>
</div>
</div>
<div class="color-chip">
<div class="color-box" style="background-color: #e9eeed;"></div>
<div class="color-details">
<div class="color-name">Soft Accent Green BG</div>
<div class="color-value">#e9eeed</div>
</div>
</div>
</div>
<h3>② 서체 (Typography)</h3>
<ul>
<li><strong>서체 패밀리</strong>: <code>'Pretendard Variable', 'Pretendard', 'Inter', 'Noto Sans KR', sans-serif</code></li>
<li><strong>글꼴 크기 명세</strong>:
<ul>
<li>페이지 메인 타이틀: <code>1.25rem</code> (700 Bold)</li>
<li>카드 타이틀: <code>1.05rem</code> (700 Bold)</li>
<li>일반 본문 및 테이블 데이터: <code>0.875rem</code> (500 Medium / 600 Semi-Bold)</li>
<li>Muted 보조 텍스트: <code>0.8rem</code> / <code>0.75rem</code></li>
</ul>
</li>
</ul>
<h3>③ 공통 그리드 & 테이블 (Table Grid Rules)</h3>
<ul>
<li><strong>순번 표시 (NO)</strong>: 모든 테이블 그리드의 1열은 데이터 인덱스 번호(<code>NO</code>)를 필수 노출합니다.</li>
<li><strong>가로 구분선</strong>: 답답한 디자인을 방지하기 위해 세로 테두리(Vertical Borders)는 일절 노출하지 않으며, 가로 행 구분선만 노출합니다.</li>
<li><strong>행 선택 인터랙션</strong>: 마우스 호버 시 <code>var(--primary-soft)</code> 배경색을 지정하며, 클릭 행 활성화 시 텍스트 두께 변경으로 인한 줄높이 왜곡이 없도록 패딩 상속(inherit) 속성을 적용하여 균일한 행 높이를 유지합니다.</li>
</ul>
<h3>④ 공통 모달 팝업 (Modal Overlay Rules)</h3>
<ul>
<li><strong>백드롭</strong>: <code>rgba(20, 30, 29, 0.6)</code> 반투명 딤 및 <code>backdrop-filter: blur(4px)</code> 효과로 모달 포커스를 고정합니다.</li>
<li><strong>트랜지션</strong>: <code>fade-in</code><code>slide-up (translateY 30px to 0)</code>이 일괄 적용되어 매끄러운 팝업 동작을 보장합니다.</li>
</ul>
</section>
<!-- Section 2 -->
<section id="layout">
<h2 class="section-title">2. 레이아웃 구조 설계 (App Frame Layout)</h2>
<p>LNB, 상단 헤더, 그리고 메인 콘텐츠 탭 영역의 수평/수직 분할 아키텍처는 다음과 같습니다.</p>
<div class="layout-preview">
+-------------------------------------------------------------------------+
| LNB (좌측 사이드바) | Main Header (상단 헤더) |
| 📁 PM_ver4 Admin | [Header Title] [Admin Profile] |
|-------------------------+-----------------------------------------------|
| - Dashboards | Main Content (메인 콘텐츠 탭 영역) |
| 📊 종합 용량/접속자 | |
| - 프로젝트 관리 | +-----------------------------------------+ |
| 🏗️ 프로젝트 관리 | | 카드 1 (필터 / 테이블 리스트) | |
| 📢 실시간 배너 공지 | +-----------------------------------------+ |
| - 사용자 및 권한 | | 카드 2 (상세정보 뷰 / 팝업 연동 리스트) | |
| 👥 사용자 관리 | +-----------------------------------------+ |
| - 시스템 감사 및 환경 | |
| 🔎 감사 로그 조회 | |
| ⚙️ 자동 삭제 설정 | |
| 🔑 공통 코드 관리 | |
+-------------------------------------------------------------------------+</div>
</section>
<!-- Section 3 -->
<section id="screen-dashboard">
<h2 class="section-title">3. 화면별 상세 UI 및 기능 설계</h2>
<h3>📊 화면 1: 종합 용량 및 접속자 현황 (Dashboard)</h3>
<p>상단 3열 KPI 요약 카드와 하단 스토리지 프로그레스바 및 실시간 소켓 접속자 테이블 구조입니다.</p>
<div class="spec-card">
<h4>① 주요 UI 컴포넌트</h4>
<ul>
<li><strong>스토리지 KPI 카드</strong>: 전체 현장의 총 한도 용량 대비 누적 사용 용량 실시간 합산 표시 (예: <code>💾 9.70 GB / 20 GB</code>).</li>
<li><strong>접속자 KPI 카드</strong>: 현재 소켓 서버 연결 세션 수 노출.</li>
<li><strong>압축작업 KPI 카드</strong>: Redis(BullMQ) 내 대기중인 압축 건수.</li>
<li><strong>현장별 스토리지 사용 현황</strong>: 각 프로젝트 ID/명칭, 게이지바 및 사용량 정보(GB / 백분율% / 파일수량개) 동시 렌더링.</li>
</ul>
<h4>② 실시간 접속 현황 테이블 사양</h4>
<table>
<thead>
<tr>
<th style="width: 10%;">NO</th>
<th style="width: 25%;">사용자 ID</th>
<th style="width: 25%;">접속 IP</th>
<th style="width: 25%;">현재 조회 경로</th>
<th style="width: 15%;">작업</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>admin_test</td>
<td>127.0.0.1</td>
<td><code>/PM_TEST_01/archive</code></td>
<td><span class="status-badge status-badge-danger" style="cursor: pointer;">강제퇴장</span></td>
</tr>
</tbody>
</table>
</div>
</section>
<section id="screen-project">
<h3>🏗️ 화면 2: 프로젝트 관리 (Project Management)</h3>
<p>좌측 프로젝트 목록 그리드와 우측 프로젝트별 참여자 및 배정 통제 그리드 구조입니다.</p>
<div class="spec-card">
<h4>① 프로젝트 목록 테이블 사양 (좌측 카드)</h4>
<p>출력 컬럼: <code>NO</code> | <code>프로젝트 ID</code> | <code>현장명</code> | <code>카테고리</code> | <code>용량 제한(GB)</code> | <code>상태</code> | <code>관리(수정/삭제)</code></p>
<ul>
<li>행 클릭 시, 우측의 '참여 권한 사용자 목록'이 해당 프로젝트 정보로 자동 리바인딩됩니다.</li>
<li><strong>삭제 제한</strong>: 관련 테이블(tb_data, tb_official_doc_file, tb_banner_notice 등)에 현장 ID 사용 이력이 있으면 삭제 불가능하며 경고 메시지가 발생합니다.</li>
<li><strong>신규 프로젝트 등록 및 수정 모달 (projectModalOverlay)</strong>: 프로젝트 ID(수정 시 Readonly), 프로젝트명, 단축명, 카테고리 Select, 스토리지 제한(GB), 상태를 편집합니다.</li>
</ul>
<h4>② 참여 권한 사용자 목록 (우측 카드 - 병합 영역)</h4>
<p>출력 컬럼: <code>NO</code> | <code>사용자 ID</code> | <code>이름</code> | <code>부서/직급</code> | <code>권한 등급</code> | <code>작업(배정제외)</code></p>
<ul>
<li><strong>권한 등급 변경</strong>: 인라인 셀렉터(Admin, Sub-Master, Worker, Viewer)로 권한 레벨 즉시 업데이트.</li>
<li><strong>사용자 배정 추가 팝업 모달 (assignModalOverlay)</strong>: 현재 현장에 미배정된 사용자들을 체크박스로 다중 선택하여 일괄 추가합니다. 또한 목록 선택식을 지원하기 위해 우측 하단 배정 대기 목록에서도 '즉시 배정' 단축 버튼을 제공합니다.</li>
</ul>
</div>
</section>
<section id="screen-banner">
<h3>📢 화면 3: 실시간 배너 공지 (Banner Notice)</h3>
<p>상단 배너 등록 폼 카드 및 하단 이력 검색 조건 필터와 이력 목록 그리드 구조입니다.</p>
<div class="spec-card">
<h4>① 배너 공지 등록 폼</h4>
<ul>
<li>입력 필드: 대상 프로젝트 선택(특정 현장 또는 전체 현장 'all' 매핑), 등록일(임의 편집 지원), 시작일, 종료일, 공지 자막 텍스트.</li>
<li>송출 등록 제출 시, 오늘 일자와 비교하여 즉시 이력에 추가되고 상태 배지가 실시간 부여됩니다.</li>
</ul>
<h4>② 이력 목록 필터 및 이력 테이블</h4>
<ul>
<li><strong>검색 필터</strong>: 송출 상태(전체, 송출중, 예약됨, 만료) 및 등록일(from ~ to) 날짜 범위 지정 검색.</li>
<li><strong>테이블 명세</strong>: <code>NO</code> | <code>등록일</code> | <code>대상 프로젝트</code> | <code>공지 내용</code> | <code>시작일</code> | <code>종료일</code> | <code>송출 상태</code> | <code>작업</code></li>
<li><strong>송출 중지 통제</strong>: 아직 기간이 유효한 행(송출중, 예약됨)에만 <code>[송출 중지]</code> 버튼이 노출 및 활성화되며, 이미 만료된 이력은 <code>[중지 완료]</code> 비활성 텍스트로 대체하여 이중 제어를 차단합니다.</li>
</ul>
</div>
</section>
<section id="screen-user">
<h3>👥 화면 4: 사용자 관리 (User Management)</h3>
<p>좌측 사용자 마스터 리스트 및 우측 선택된 사용자의 참여 권한 프로젝트 리스트업 구조입니다.</p>
<div class="spec-card">
<h4>① 사용자 계정 목록 (좌측 카드)</h4>
<p>출력 컬럼: <code>NO</code> | <code>아이디</code> | <code>이름</code> | <code>소속/직급</code> | <code>그룹</code> | <code>상태</code> | <code>관리(수정/삭제)</code></p>
<ul>
<li>행 클릭 시, 해당 사용자가 참여하고 있는 프로젝트 리스트가 우측 카드에 즉시 바인딩됩니다.</li>
<li><strong>삭제 제한</strong>: 권한 테이블(tb_permission)에 현장 배정/참여 권한 정보가 등록되어 있으면 삭제가 불가능하며 경고 메시지가 발생합니다.</li>
<li><strong>사용자 등록 및 수정 모달 (userModalOverlay)</strong>: 아이디(수정 시 Readonly), 패스워드, 이름, 회사명, 부서, 직급, 권한 그룹 지정 select, 재직 상태(재직/퇴직잠금) 지정.</li>
</ul>
<h4>② 권한부여 프로젝트 목록 (우측 카드)</h4>
<p>출력 컬럼: <code>NO</code> | <code>프로젝트 ID</code> | <code>프로젝트명</code> | <code>부여 권한 등급</code></p>
</div>
</section>
<section id="screen-audit">
<h3>🔎 화면 5: 감사 로그 조회 (Audit Logs)</h3>
<p>파일 조작 중요 이벤트(삭제, 이동, 다운로드) 목록 및 검색 조회 화면입니다.</p>
<div class="spec-card">
<h4>① 감사 로그 목록 사양</h4>
<p>출력 컬럼: <code>NO</code> | <code>일시</code> | <code>프로젝트</code> | <code>사용자 ID</code> | <code>접속 IP</code> | <code>조작 액션</code> | <code>조작 대상 경로(코드박스 스타일)</code></p>
<ul>
<li>필터링 항목: 사용자 ID 검색 입력란, 조작 액션 Dropdown, 검색 기능.</li>
</ul>
</div>
</section>
<section id="screen-policy">
<h3>⚙️ 화면 6: 자동 보관 및 파일 삭제 정책 설정 (Delete Policy)</h3>
<p>시스템 글로벌 일괄 정책 설정 영역, 실시간 예정 시나리오 요약, 그리고 배치 처리 이력 구조입니다.</p>
<div class="spec-card">
<h4>① 시스템 공통 자동 삭제 정책 설정 폼 [글로벌 정책 공통화]</h4>
<ul>
<li><strong>입력 필드</strong>: 정책 활성화 여부(Toggle/Select), 최소 유지 파일 개수 기준(숫자 입력), 자동 삭제 제한 기한(일) (숫자 입력).</li>
<li><strong>글로벌 통합</strong>: 기존의 프로젝트 개별 Dropdown은 완전히 배제하고, 전체 현장에 동일하게 일괄 반영합니다.</li>
</ul>
<h4>② 보존 정책 실시간 요약 (Dynamic Summary)</h4>
<ul>
<li>폼의 입력값을 변경하는 즉시 요약 영역 텍스트가 시나리오 문구로 동적 조합되어 나타납니다.</li>
<li>예: <code>"현재 전체 공통 설정에 따라, 각 현장의 보관 파일 수가 100개 미만이고 30일이 지나면 자동 삭제 배치 스케줄러가 작동합니다."</code></li>
</ul>
<h4>③ 자동 삭제 처리 이력 테이블 사양</h4>
<p>출력 컬럼: <code>NO</code> | <code>자동 처리 일자</code> | <code>프로젝트 ID</code> | <code>삭제 처리 폴더 경로</code> | <code>적용 기준</code> | <code>처리 결과(성공 배지)</code></p>
<ul>
<li>정책 값 저장 완료 시 이력 로그의 대상 프로젝트 ID 자리에는 <code>'SYSTEM'</code>이 기입됩니다.</li>
</ul>
</div>
</section>
<section id="screen-codes">
<h3>🔑 화면 7: 공통 코드 관리 (Common Code Management)</h3>
<p>대분류 마스터 및 세부 코드 리스트가 배치되는 상하 2단 수직 정렬 레이아웃 구조입니다.</p>
<div class="spec-card">
<h4>① 대분류 코드 마스터 (상단 카드)</h4>
<p>출력 컬럼: <code>NO</code> | <code>대분류 코드</code> | <code>대분류 코드명</code> | <code>사용</code> | <code>관리(수정/삭제)</code></p>
<ul>
<li>행을 선택(click)하면 해당 행이 하이라이트(selected)되며, 하단의 세부 코드 그리드가 동적으로 새로고침됩니다.</li>
<li><strong>대분류 등록 및 수정 모달 (codeMasterModalOverlay)</strong>: 대분류 코드, 명칭, 사용여부, 비고 설명 입력.</li>
</ul>
<h4>② 세부 소분류 코드 목록 (하단 카드)</h4>
<p>출력 컬럼: <code>NO</code> | <code>소분류 코드</code> | <code>조합 코드 (base_code)</code> | <code>코드 명칭</code> | <code>정렬 순서</code> | <code>사용</code> | <code>관리(수정/삭제)</code></p>
<ul>
<li><strong>유효성 방어 차단</strong>: 상단 대분류 테이블에서 행을 클릭하여 선택하지 않은 상태에서는 하단의 <code>[ 세부코드 등록]</code> 버튼이 강제 비활성화(disabled)되며, 팝업 접근 시 안내 팝업 및 경고 텍스트(<code>"상단에서 대분류 코드를 선택해 주세요."</code>)를 노출합니다.</li>
<li><strong>조합 코드(base_code)</strong>: 소분류 생성 완료 제출 시, <code>대분류코드_소분류코드</code> 형태로 자동 결합되어 저장됩니다.</li>
<li><strong>삭제 제한 (RESTRICT)</strong>: 마스터 대분류 코드를 삭제할 경우, 하위 세부 코드(code_detail)가 존재하면 대분류 삭제가 차단되고 경고 메시지를 노출합니다. (세부 코드가 먼저 삭제되어 비어있을 때만 대분류 삭제 가능)</li>
</ul>
</div>
</section>
</main>
</body>
</html>