시나리오 탭 처리

This commit is contained in:
현성필
2024-01-08 10:20:58 +09:00
parent b4c43a2138
commit 2861d3d393
7 changed files with 260 additions and 78 deletions
@@ -18,15 +18,48 @@
<!-- csrf -->
<input id="csrf" type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}">
<div class="pt-layout">
<aside th:replace="page/tester/apiCollection :: collectionFragment"></aside>
<th:block th:replace="page/tester/apiCollection :: collectionScript"></th:block>
<div class="api-tester-layout">
<div class="tester-toolbar">
<button type="button" class="btn btn-primary btn-sm" id="toggle_tester">시나리오 보기</button>
<button type="button" class="btn btn-primary btn-sm" id="new_collection"><i class="fa fa-plus"></i> 새 컬렉션
</button>
<button type="button" class="btn btn-primary btn-sm" id="new_request"><i class="fa fa-plus"></i> 새 요청</button>
<button type="button" class="btn btn-primary btn-sm" id="new_scenario"><i class="fa fa-plus"></i> 새로운 시나리오
</button>
<button type="button" class="btn btn-primary btn-sm" id="full_screen"><i class="fa-solid fa-display"></i> 전체화면</button>
</div>
<div class="tester">
<section th:replace="page/tester/apiScenario :: scenarioFragment">
</section>
<aside th:replace="page/tester/apiCollection :: collectionFragment"></aside>
<section class="api-tester" layout:fragment="contentFragment">
</section>
<section th:replace="page/tester/apiScenario :: scenarioScript">
</section>
</div>
<th:block th:replace="page/tester/apiCollection :: collectionScript">
<section class="pt-main order-1" layout:fragment="contentFragment">
</section>
<th:block layout:fragment="contentScript">
</th:block>
<th:block layout:fragment="contentScript">
</th:block>
<script>
$(function () {
const container = document.querySelector('.api-tester-layout');
$('#full_screen').on('click', function () {
container.classList.toggle('full-screen');
});
document.addEventListener('keydown', (event) => {
if (event.key === 'Escape') {
container.classList.remove('full-screen');
// layoutManager.resize();
}
});
});
</script>
</div>
<footer th:replace="fragment/footer :: footerFragment"></footer>
@@ -6,15 +6,31 @@
</head>
<body>
<aside class="pt-sidebar border" th:fragment="collectionFragment" style="min-width: 200px;">
<div class="p-1">
<button type="button" class="btn btn-primary btn-sm" id="new_collection"><i class="fa fa-plus"></i>새 컬렉션</button>
<button type="button" class="btn btn-primary btn-sm" id="new_request"><i class="fa fa-plus"></i>새 요청</button>
<aside class="api-catalog border" th:fragment="collectionFragment">
<div style="background: rgba(0,0,0,.03);">
API 목록
</div>
<div class="collapse pt-links" aria-label="sidebar menu">
<ul class="list-unstyled mb-0 py-3 pt-md-1" id="side_menubar">
<div class="pt-links" aria-label="sidebar menu">
<ul class="list-unstyled" id="side_menubar">
</ul>
</div>
<div class="modal fade" id="new_scenario_modal" tabindex="-1" aria-labelledby="new_scenario_modal" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">새로운 시나리오 추가</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<input type="text" id="new_scenario_name" class="form-control" placeholder="이름을 입력하세요" aria-label="이름을 입력하세요" name="scenario_name" required/>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">닫기</button>
<button type="button" class="btn btn-primary save_scenario">저장</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="new_collection_modal" tabindex="-1" aria-labelledby="new_collection_modal" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
@@ -49,6 +65,39 @@
</div>
</div>
</div>
<div id="loading-overlay" style="display: none;">
<div class="d-flex justify-content-center align-items-center"
style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); z-index: 9999;">
<div class="text-center">
<span class="sr-only">Loading...</span>
<br/>
<button id="cancel-ajax" class="btn btn-danger mt-3">Cancel</button>
</div>
</div>
</div>
<div class="modal fade" id="new_api_request_modal" tabindex="-1" aria-labelledby="new_api_request_modal"
aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">새로운 API 추가</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<select class="form-select" id="modal_collection"></select>
<div class="input-group mt-2">
<span class="input-group-text">API 이름</span>
<input type="text" class="form-control" id="new_api_name">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">닫기</button>
<button type="button" class="btn btn-primary add_new_request">추가</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="confirm_delete_modal" tabindex="-1" aria-labelledby="confirm_delete_modal" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
@@ -88,6 +137,38 @@
<!-- menu script -->
<th:block th:fragment="collectionScript">
<script th:inline="javascript">
$(document).ready(function () {
var showingScenario = true;
$('#toggle_tester').on('click', function () {
console.log(showingScenario);
showingScenario = !showingScenario;
if (showingScenario) {
// Move .api-scenario off-screen to the left
// $('.api-scenario').css('transform', 'translateX(0)');
$('.api-scenario').show();
$('.api-tester').hide();
$('#toggle_tester').text('테스터 보기');
} else {
// Bring .api-scenario into view
// $('.api-scenario').css('transform', 'translateX(-100%)');
$('#toggle_tester').text('시나리오 보기');
$('.api-scenario').hide();
$('.api-tester').show();
}
});
if (showingScenario){
$('.api-scenario').show();
$('.api-tester').hide();
}
else{
$('.api-scenario').hide();
$('.api-tester').show();
}
});
</script>
</th:block>
</body>
@@ -0,0 +1,64 @@
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<body>
<section th:fragment="scenarioFragment" class="api-scenario">
<div class="api-scenario-sidebar">
<div style="background: rgba(0,0,0,.03);">
시나리오 목록
</div>
<div class="pt-links ">
<ul class="list-unstyled api-scenario-list" id="scenario_menubar">
</ul>
</div>
</div>
<div class="api-scenario-view">
<div class="api-scenario-content">
<div class="api-scenario-editor">
<div class="api-scenario-editor-toolbar" style="height: 50px; border: 1px solid grey; padding: 5px;">
<button type="button" class="btn btn-primary btn-sm run_scenario_step">단계 별 실행</button>
<button type="button" class="btn btn-primary btn-sm run_scenario_all">전체 실행</button>
<button type="button" class="btn btn-primary btn-sm pause_scenario">일시 정지</button>
<button type="button" class="btn btn-primary btn-sm stop_scenario">정지</button>
<button type="button" class="btn btn-primary btn-sm save">저장</button>
<button type="button" class="btn btn-primary btn-sm export">내보내기</button>
<button type="button" class="btn btn-primary btn-sm clear">초기화</button>
<button type="button" class="btn btn-primary btn-sm add_start">시작 노드</button>
</div>
<div>시나리오 설명이 여기에 표시</div>
<div class="api-scenario-editor-body" style="display: flex; flex-direction: row; flex: 1; border: 1px solid grey; padding: 5px;">
<div class="scenario_editor">
<div class="drawflow" id="drawflow">
<!-- <div class="btn-lock">-->
<!-- <i id="lock" class="fas fa-lock lock"></i>-->
<!-- <i id="unlock" class="fas fa-lock-open unlock" style="display:none;"></i>-->
<!-- </div>-->
<!-- <div class="bar-zoom">-->
<!-- <i class="fas fa-search-minus zoom_out"></i>-->
<!-- <i class="fas fa-search zoom_reset"></i>-->
<!-- <i class="fas fa-search-plus zoom_in"></i>-->
<!-- </div>-->
</div>
</div>
</div>
</div>
<div class="api-scenario-output">
<div class="api-scenario-output-header">
<span>output</span>
<button type="button" class="btn btn-primary btn-sm toggle_output">숨기기</button>
</div>
<div class="api-scenario-output-body">
<div id="output" style="height: 100%"></div>
</div>
</div>
</div>
</div>
</section>
</body>
<th:block th:fragment="scenarioScript">
</th:block>
</html>
@@ -7,16 +7,6 @@
<script>
require.config({paths: {'vs': '/plugins/vs'}});
</script>
<div id="loading-overlay" style="display: none;">
<div class="d-flex justify-content-center align-items-center"
style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); z-index: 9999;">
<div class="text-center">
<span class="sr-only">Loading...</span>
<br/>
<button id="cancel-ajax" class="btn btn-danger mt-3">Cancel</button>
</div>
</div>
</div>
<div class="container-fluid mt-2">
<div class="toast" role="alert" aria-live="assertive" aria-atomic="true" style="position: absolute; bottom: 0; left: 0;">
<div class="toast-header">
@@ -38,28 +28,6 @@
</div>
</div>
</div>
<div class="modal fade" id="new_api_request_modal" tabindex="-1" aria-labelledby="new_api_request_modal"
aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">새로운 API 추가</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<select class="form-select" id="modal_collection"></select>
<div class="input-group mt-2">
<span class="input-group-text">API 이름</span>
<input type="text" class="form-control" id="new_api_name">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">닫기</button>
<button type="button" class="btn btn-primary add_new_request">추가</button>
</div>
</div>
</div>
</div>
<div style="display: none">
<ul id="servers">
<li th:each="server : ${servers}" th:data-id="${server.id}" th:data-name="${server.name}" th:data-path="${server.basePath}"></li>
@@ -71,8 +39,11 @@
</body>
<th:block layout:fragment="contentScript">
<script th:src="@{/js/APIClient.js}"></script>
<script th:src="@{/js/APITester.js}"></script>
<script th:src="@{/js/LayoutUtil.js}"></script>
<script th:src="@{/js/APIScenarioExecutor.js}"></script>
<script th:src="@{/js/APIScenario.js}"></script>
<script>
$(document).ajaxError(function(event, jqxhr, settings, exception) {
if (jqxhr.status === 401) {
@@ -80,7 +51,6 @@
}
});
$(function () {
//get servers from html convert to array
const servers = [];
$('#servers li').each(function () {
@@ -93,17 +63,8 @@
const apiTester = new APITester();
apiTester.init(servers);
// const timer = setInterval(function () {
// $.ajax({
// url: '/refreshSessionTimeout.do',
// type: 'GET',
// contentType: 'application/json',
// complete: function () {
// apiTester.hideLoadingOverlay();
// }
// });
// }, 60000);
const apiScenario = new APIScenario(apiTester);
apiScenario.init();
});
</script>