147 lines
7.5 KiB
PHP
147 lines
7.5 KiB
PHP
<?php $CURRENT_SECTION = 'approval';
|
|
include '../inc/header.php';
|
|
$object = $_GET['object'] ?? 'LEAVE';
|
|
?>
|
|
<div class="container" style="max-width:1280px; margin-top:24px;">
|
|
<div class="row g-3">
|
|
<div class="col-md-4">
|
|
<div class="card shadow-sm">
|
|
<div class="card-header d-flex justify-content-between align-items-center">
|
|
<strong>결재 규칙 (<?= $object?>)</strong>
|
|
<button class="btn btn-sm btn-primary" id="btnAddRule">추가</button>
|
|
</div>
|
|
<div class="card-body">
|
|
<ul class="list-group" id="ruleList">
|
|
<li class="list-group-item active" data-id="1">연차 기본 규칙</li>
|
|
<li class="list-group-item" data-id="2">연차 간소화 규칙</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-8">
|
|
<div class="card shadow-sm">
|
|
<div class="card-header">결재선(트리)</div>
|
|
<div class="card-body">
|
|
<div class="alert alert-info small">
|
|
문서 생성 시 <b>포함된 승인자</b>가 자동으로 <b>1차 결재자(루트)</b>가 됩니다.
|
|
아래 트리는 <u>루트 이후 상위 결재자</u>를 parent_id로 연결합니다.
|
|
</div>
|
|
|
|
<div id="treeArea" class="border rounded p-3">
|
|
<!-- 샘플 트리 표현 (간단한 UL/LI) -->
|
|
<ul class="approval-tree">
|
|
<li>
|
|
<div class="node">
|
|
<span class="badge bg-dark">루트=문서 포함 승인자(동적)</span>
|
|
</div>
|
|
<ul>
|
|
<li>
|
|
<div class="node">
|
|
<span class="badge bg-secondary">개발팀</span>
|
|
<span class="text-muted ms-2">required: 1</span>
|
|
<button class="btn btn-sm btn-outline-danger ms-2 btnDelNode">삭제</button>
|
|
</div>
|
|
<ul>
|
|
<li>
|
|
<div class="node">
|
|
<span class="badge bg-info text-dark">일반관리자</span>
|
|
<span class="text-muted ms-2">required: 1</span>
|
|
<button class="btn btn-sm btn-outline-danger ms-2 btnDelNode">삭제</button>
|
|
</div>
|
|
</li>
|
|
<li>
|
|
<div class="node">
|
|
<span class="badge bg-dark">kevin</span>
|
|
<span class="text-muted ms-2">required: 1</span>
|
|
<button class="btn btn-sm btn-outline-danger ms-2 btnDelNode">삭제</button>
|
|
</div>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="d-flex gap-2 mt-3">
|
|
<select class="form-select" id="poolSelect" style="max-width:220px;">
|
|
<option value="d1" data-type="department">개발팀</option>
|
|
<option value="r2" data-type="role">일반관리자</option>
|
|
<option value="u9" data-type="user">kevin</option>
|
|
</select>
|
|
<input type="number" class="form-control" id="requiredCnt" value="1" style="max-width:120px;" placeholder="required">
|
|
<button class="btn btn-outline-primary" id="btnAddChild">선택 노드의 상위로 추가</button>
|
|
<button class="btn btn-primary" id="btnSave">저장</button>
|
|
</div>
|
|
|
|
<div class="small text-muted mt-2">* “상위 추가”는 현재 포커스 노드의 parent로 삽입하는 의미(=다음 결재자).</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
.approval-tree { list-style:none; padding-left:1rem; }
|
|
.approval-tree .node { padding:.25rem .5rem; border:1px solid #e5e8ef; border-radius:.5rem; display:inline-block; background:#f8fafc; }
|
|
.approval-tree ul { list-style:none; margin-left:1.25rem; padding-left:1rem; border-left:2px dashed #dde3f3; }
|
|
.approval-tree li { margin:.5rem 0; }
|
|
.node.focus { outline:2px solid #5b8bff; }
|
|
</style>
|
|
|
|
<script>
|
|
$(function(){
|
|
let focused = null;
|
|
|
|
// 노드 포커스
|
|
$(document).on('click', '.node', function(){
|
|
$('.node').removeClass('focus');
|
|
$(this).addClass('focus');
|
|
focused = this;
|
|
});
|
|
|
|
// 상위(부모) 노드 추가 (시각적 데모)
|
|
$('#btnAddChild').on('click', function(){
|
|
if (!focused) return alert('추가할 기준 노드를 선택하세요.');
|
|
const label = $('#poolSelect option:selected').text();
|
|
const req = $('#requiredCnt').val()||1;
|
|
|
|
// focused의 부모 <ul>을 찾고 그 위에 새 노드를 끼워 넣는 느낌 (데모)
|
|
const $li = $(focused).closest('li');
|
|
const $parentUl = $li.parent();
|
|
|
|
const html = `
|
|
<li>
|
|
<div class="node"><span class="badge bg-secondary">${label}</span>
|
|
<span class="text-muted ms-2">required: ${req}</span>
|
|
<button class="btn btn-sm btn-outline-danger ms-2 btnDelNode">삭제</button>
|
|
</div>
|
|
</li>`;
|
|
$parentUl.prepend(html);
|
|
});
|
|
|
|
$(document).on('click', '.btnDelNode', function(e){
|
|
e.stopPropagation();
|
|
$(this).closest('li').remove();
|
|
});
|
|
|
|
$('#btnSave').on('click', function(){
|
|
alert('저장(샘플) /api/approval/rule_save.php');
|
|
});
|
|
|
|
$('#btnAddRule').on('click', function(){
|
|
alert('규칙 추가(샘플) /api/approval/rule_add.php?object=<?= $object?>');
|
|
});
|
|
|
|
// 규칙 선택
|
|
$(document).on('click', '#ruleList .list-group-item', function(){
|
|
$('#ruleList .list-group-item').removeClass('active');
|
|
$(this).addClass('active');
|
|
// 선택 규칙의 트리 로드(샘플)
|
|
alert('규칙 로드(샘플) /api/approval/rule_get.php?id='+$(this).data('id'));
|
|
});
|
|
});
|
|
</script>
|
|
<?php include '../inc/footer.php'; ?>
|