[UX] #577 simplify VPD product forms

This commit is contained in:
devmrko
2026-07-01 10:35:21 +09:00
parent 699909212f
commit f15b453aad
9 changed files with 128 additions and 81 deletions

View File

@@ -22,11 +22,11 @@
<p class="section-description">저장 전 적용 대상과 행 범위를 검토한 뒤 VPD 권한을 반영합니다.</p>
</div>
<div class="wizard-progress" aria-label="권한 추가 단계">
<button class="wizard-step-indicator active" type="button" data-wizard-target="1">1 역할</button>
<button class="wizard-step-indicator" type="button" data-wizard-target="2">2 객체</button>
<button class="wizard-step-indicator" type="button" data-wizard-target="3">3 행 규칙</button>
<button class="wizard-step-indicator" type="button" data-wizard-target="4">4 컬럼</button>
<button class="wizard-step-indicator" type="button" data-wizard-target="5">5 검토</button>
<button class="wizard-step-indicator active" type="button" data-wizard-target="1">역할</button>
<button class="wizard-step-indicator" type="button" data-wizard-target="2">대상</button>
<button class="wizard-step-indicator" type="button" data-wizard-target="3">접근 범위</button>
<button class="wizard-step-indicator" type="button" data-wizard-target="4">표시 예외</button>
<button class="wizard-step-indicator" type="button" data-wizard-target="5">검토</button>
</div>
</div>
<form method="post" action="/permissions" class="permission-wizard" data-permission-wizard>
@@ -61,7 +61,6 @@
<div class="wizard-panel active" data-wizard-step="1">
<div class="wizard-panel-heading">
<span class="wizard-step-number">1</span>
<div>
<h3>역할 선택</h3>
<p>권한을 부여하거나 거부할 역할을 선택합니다.</p>
@@ -96,7 +95,6 @@
<div class="wizard-panel" data-wizard-step="2">
<div class="wizard-panel-heading">
<span class="wizard-step-number">2</span>
<div>
<h3>보호 객체 선택</h3>
<p>등록된 보호 객체 또는 DB 스키마 객체를 선택합니다.</p>
@@ -138,7 +136,6 @@
<div class="wizard-panel" data-wizard-step="3">
<div class="wizard-panel-heading">
<span class="wizard-step-number">3</span>
<div>
<h3>권한 효과와 행 규칙</h3>
<p>허용/거부 방향과 VPD 행 필터 조건을 설정합니다.</p>
@@ -186,7 +183,6 @@
<div class="wizard-panel" data-wizard-step="4">
<div class="wizard-panel-heading">
<span class="wizard-step-number">4</span>
<div>
<h3>권한별 원문 표시 예외</h3>
<p>이 역할이 이미 볼 수 있는 행에서 마스킹을 제외할 컬럼을 여러 개 선택합니다.</p>
@@ -211,7 +207,6 @@
<div class="wizard-panel" data-wizard-step="5">
<div class="wizard-panel-heading">
<span class="wizard-step-number">5</span>
<div>
<h3>저장 전 검토</h3>
<p>저장될 권한과 예상 effective policy를 확인합니다.</p>
@@ -245,56 +240,52 @@
<section class="content-band">
<h2>접근 규칙 목록</h2>
<div class="table-responsive">
<table class="table table-sm align-middle">
<table class="table table-sm align-middle permission-list-table">
<thead>
<tr>
<th>ID</th>
<th>역할</th>
<th>테이블/뷰</th>
<th>Action</th>
<th>Effect</th>
<th>행 규칙</th>
<th>적용 필터</th>
<th>원문 표시 허용 컬럼(여러 개)</th>
<th>삭제 영향</th>
<th></th>
<th>보호 대상</th>
<th>효과</th>
<th>접근 범위</th>
<th>표시 예외</th>
<th>관리</th>
</tr>
</thead>
<tbody>
<tr th:each="permission : ${permissions}"
th:with="lastPermission=${lastPermissionByPermissionId[permission.permissionId()]}">
<td th:text="${permission.permissionId()}">100</td>
<td th:text="${permission.roleName()}">HR_DEPT_ROLE</td>
<td th:text="${permission.objectName()}">CB_V_SEARCH_DOCUMENTS</td>
<td th:text="${permission.action()}">SELECT</td>
<td>
<span class="badge"
th:classappend="${permission.permissionEffect() == 'DENY'} ? ' text-bg-danger' : ' text-bg-success'"
th:text="${permission.permissionEffect()}">ALLOW</span>
</td>
<td th:text="${permission.rules()} ?: '-'">ALL</td>
<td><pre class="table-pre" th:text="${permission.filterPreview()} ?: '-'">ALL ROWS</pre></td>
<td><pre class="table-pre" th:text="${permission.filterPreview()} ?: ${permission.rules()} ?: '-'">ALL ROWS</pre></td>
<td th:text="${permission.visibleColumns()} ?: '-'">CONTENTS</td>
<td class="delete-impact">
<span>역할이 이 TABLE/VIEW의 SELECT 권한을 잃습니다.</span>
<strong th:text="${permission.roleName() + ' -> ' + permission.objectName()}">ROLE -> OBJECT</strong>
<small th:if="${lastPermission}" class="text-danger">이 객체의 마지막 권한입니다. 삭제 후 보호 객체가 비활성화됩니다.</small>
<small th:unless="${lastPermission}">같은 객체에 다른 역할 권한이 남아 있습니다.</small>
</td>
<td>
<form method="post" action="/permissions/delete" class="inline-form">
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}">
<input type="hidden" name="permissionId" th:value="${permission.permissionId()}">
<label class="delete-confirm">
<input type="checkbox" name="confirmImpact" value="true" required>
영향 확인
</label>
<button class="btn btn-sm btn-outline-danger" type="submit">삭제</button>
</form>
<details class="row-management">
<summary>관리</summary>
<div class="delete-impact">
<span>이 역할은 이 대상의 SELECT 권한을 잃습니다.</span>
<strong th:text="${permission.roleName() + ' → ' + permission.objectName()}">ROLE → OBJECT</strong>
<small th:if="${lastPermission}" class="text-danger">마지막 권한입니다. 삭제 후 보호 대상이 비활성화될 수 있습니다.</small>
<small th:unless="${lastPermission}">같은 대상에 다른 역할 권한이 남아 있습니다.</small>
</div>
<form method="post" action="/permissions/delete" class="inline-form mt-2">
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}">
<input type="hidden" name="permissionId" th:value="${permission.permissionId()}">
<label class="delete-confirm">
<input type="checkbox" name="confirmImpact" value="true" required>
영향 확인
</label>
<button class="btn btn-sm btn-outline-danger" type="submit">삭제</button>
</form>
</details>
</td>
</tr>
<tr th:if="${#lists.isEmpty(permissions)}">
<td colspan="10" class="text-muted">등록된 권한이 없습니다.</td>
<td colspan="6" class="text-muted">등록된 접근 규칙이 없습니다.</td>
</tr>
</tbody>
</table>