기본 골격
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Error Page</title>
|
||||
<meta http-equiv="refresh" content="5;url=/">
|
||||
<style>
|
||||
.error-code {
|
||||
font-size: 100vh;
|
||||
font-weight: bold;
|
||||
color: #ff8484;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="error-code" th:text="${status}">400</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,10 +1,22 @@
|
||||
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
|
||||
<footer th:fragment="footerFragment" class="main-footer">
|
||||
<strong>Copyright © 2014-2021 <a
|
||||
href="https://adminlte.io">AdminLTE.io</a>.
|
||||
</strong> All rights reserved.
|
||||
<div class="float-right d-none d-sm-inline-block">
|
||||
<b>Version</b> 3.1.0
|
||||
<!doctype html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<footer th:fragment="footerFragment">
|
||||
<div class="container footer">
|
||||
<!-- <button type="button" id="top" class="scroll_top"></button>-->
|
||||
<div class="foot_info">
|
||||
<span>서울본사 : 서울특별시 영등포구 양평로 157, 1411호 (〒07207)</span><br/>
|
||||
<span>대전지사 : 대전광역시 유성구 온천로 60 사이언스타운 728호 (〒34187)</span><br/>
|
||||
<span>판교지사 : 경기도 성남시 분당구 삼평동 662 판교타워 506호 (〒13524)</span><br/>
|
||||
<span>TEL : (02) 6335-0010 FAX : (02) 6335-0707 E-mail : sales@eactive.co.kr</span><br/>
|
||||
<span>Copyright © 2020 (주)이액티브. All rights reserved.</span><br/>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</html>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
<!doctype html>
|
||||
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
|
||||
|
||||
<head th:fragment="headFragment">
|
||||
<meta charset="UTF-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<meta content="max-age=0, public" http-equiv="Cache-Control"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta content="index, follow" name="robots"/>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||
<meta content="https://www.eactive.co.kr/" property="og:url"/>
|
||||
<title th:text="#{title.html}">개발자 포털</title>
|
||||
<link href="/css/font.css" rel="stylesheet" type="text/css"/>
|
||||
<link rel="stylesheet" href="/css/fontawesome/css/all.min.css" type="text/css"/>
|
||||
<link href="/css/bootstrap/bootstrap.min.css" rel="stylesheet" type="text/css"/>
|
||||
<link href="/css/custom.css" rel="stylesheet" type="text/css"/>
|
||||
<link rel="stylesheet" href="/css/codemirror/codemirror.css" type="text/css"/>
|
||||
<link rel="stylesheet" href="/css/codemirror/theme/monokai.css" type="text/css"/>
|
||||
<link rel="stylesheet" href="/js/summernote/summernote-lite.min.css" type="text/css" />
|
||||
<link rel="stylesheet" href="/css/dataTables/datatables.min.css" />
|
||||
|
||||
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
||||
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
|
||||
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<script src="/js/jquery/jquery.min.js"></script>
|
||||
<script src="/js/bootstrap/bootstrap.bundle.min.js"></script>
|
||||
<script src="/js/underscore/underscore-min.js"></script>
|
||||
<script src="/js/lodash.js"></script>
|
||||
<script src="/js/util.js"></script>
|
||||
<script src="/js/http.js"></script>
|
||||
<script src="/js/jquery-serialize-object/jquery.serialize-object.js"></script>
|
||||
<script src="/js/jquery-validation/jquery.validate.min.js"></script>
|
||||
<script src="/js/jquery-validation/additional-methods.min.js"></script>
|
||||
<script src="/js/jquery-validation/localization/messages_ko.min.js"></script>
|
||||
<script src="/js/common.js"></script>
|
||||
<script src="/js/codemirror/codemirror.js"></script>
|
||||
<script src="/js/codemirror/mode/javascript/javascript.js"></script>
|
||||
<script src="/js/codemirror/addon/display/fullscreen.js"></script>
|
||||
<script src="/js/codemirror/addon/display/placeholder.js"></script>
|
||||
<script src="/js/summernote/summernote-lite.min.js"></script>
|
||||
<script src="/js/dataTables/datatables.min.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
</script>
|
||||
</head>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,78 @@
|
||||
<!doctype html>
|
||||
<html xmlns:th="http://www.thymeleaf.org"
|
||||
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header th:fragment="headerFragment" class="p-3 border-bottom" id="header">
|
||||
<div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
|
||||
<a href="/" class="d-flex align-items-center mb-3 mb-md-0 me-md-auto text-dark text-decoration-none">
|
||||
<span class="fs-4">API Simulator</span>
|
||||
</a>
|
||||
<div class="row container">
|
||||
<div class="col text-center">
|
||||
<div class="nav-item dropdown">
|
||||
<a class="dropdown-label" href="/mgmt/routes/list_view.do">API 관리</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<a class="dropdown-label" href="/mgmt/api_tester.do">API Tester</a>
|
||||
</div>
|
||||
<div class="col-md-6 d-flex justify-content-between">
|
||||
<div class="col text-center">
|
||||
<div sec:authorize="hasRole('ROLE_ADMIN')" class="nav-item dropdown">
|
||||
<a class="nav-link" href="#" id="mgmtDropDown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
관리
|
||||
</a>
|
||||
<ul class="dropdown-menu" aria-labelledby="mgmtDropDown">
|
||||
<li><a class="dropdown-item" href="/mgmt/users/list_view.do">사용자 관리</a></li>
|
||||
<li><a class="dropdown-item" href="/mgmt/servers/list_view.do">서버 관리</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col text-end">
|
||||
<ul sec:authorize="isAnonymous()" class="nav">
|
||||
<li class="nav-item"><a href="/login" class="nav-link">로그인</a></li>
|
||||
</ul>
|
||||
<ul sec:authorize="isAuthenticated()" class="nav">
|
||||
<li class="nav-item"><a href="/mypage.do" class="nav-link">비밀번호 변경</a></li>
|
||||
<li class="nav-item"><a href="/actionLogout.do" class="nav-link">로그 아웃</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<nav th:fragment="navFragment" class="d-flex flex-wrap align-items-center justify-content-center border-bottom" id="nav_bar">
|
||||
|
||||
</nav>
|
||||
|
||||
<!-- header script -->
|
||||
<th:block th:fragment="headerScript">
|
||||
<script th:inline="javascript">
|
||||
$(function () {
|
||||
$.ajaxSetup({
|
||||
beforeSend: function(xhr) {
|
||||
xhr.setRequestHeader("X-XSRF-TOKEN", /*[[${_csrf.token}]]*/ );
|
||||
}
|
||||
});
|
||||
$(window).scroll(function () {
|
||||
var offsetHeight = document.getElementById("header").offsetHeight;
|
||||
if ($(window).scrollTop() > offsetHeight) {
|
||||
$('#nav_bar').addClass('fixed_top');
|
||||
}
|
||||
|
||||
if ($(window).scrollTop() < offsetHeight) {
|
||||
$('#nav_bar').removeClass('fixed_top');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</th:block>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,46 @@
|
||||
<!doctype html>
|
||||
<html xmlns:th="http://www.thymeleaf.org"
|
||||
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<aside class="pt-sidebar" th:fragment="menuFragment">
|
||||
<div class="collapse pt-links" id="side_menubar" aria-label="sidebar menu">
|
||||
<ul class="list-unstyled mb-0 py-3 pt-md-1">
|
||||
|
||||
<li><a href="/mypage.do" class="d-inline-flex align-items-center rounded">내 정보 변경</a></li>
|
||||
<li><a href="/change_password.do" class="d-inline-flex align-items-center rounded">비밀번호 변경</a></li>
|
||||
<li><a href="/mgmt/routes/list_view.do" class="d-inline-flex align-items-center rounded">API 관리</a></li>
|
||||
<li><a href="/mgmt/api_tester.do" class="d-inline-flex align-items-center rounded">API 테스터</a></li>
|
||||
|
||||
<th:block sec:authorize="hasRole('ROLE_ADMIN')">
|
||||
<li class="mb-1">
|
||||
<button class="btn d-inline-flex align-items-center rounded" data-bs-toggle="collapse" data-bs-target="#system-collapse" aria-expanded="false" aria-current="false">
|
||||
시스템 관리
|
||||
</button>
|
||||
<div class="collapse" id="system-collapse">
|
||||
<ul class="list-unstyled fw-normal pb-1 small">
|
||||
<li><a href="/mgmt/users/list_view.do" class="d-inline-flex align-items-center rounded">사용자 관리</a></li>
|
||||
<li><a href="/mgmt/servers/list_view.do" class="d-inline-flex align-items-center rounded">서버 관리</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
</th:block>
|
||||
</ul>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- menu script -->
|
||||
<th:block th:fragment="menuScript">
|
||||
<script th:inline="javascript">
|
||||
|
||||
$(function () {
|
||||
});
|
||||
</script>
|
||||
</th:block>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,58 @@
|
||||
<!doctype html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div th:fragment="pagination">
|
||||
<nav aria-label="Page navigation">
|
||||
<ul class="pagination"
|
||||
th:with="index_diff=0,offset_minus2=${ page.getNumber() - 1}, offset_minus1=${ page.getNumber() }, current_page=${ page.getNumber() + 1 }, offset_plus1=${ page.getNumber() + 2 }, offset_plus2=${ page.getNumber() + 3}">
|
||||
<li class="page-item" th:classappend="${ current_page == 1}?'disabled'">
|
||||
<a class="page-link" href="#" th:attr="onclick=|${jsFunction}(1,${page.getSize()});|">
|
||||
<span aria-hidden="true">처음</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="page-item" th:if="${ offset_minus2 > 0}">
|
||||
<a class="page-link" href="#" th:attr="onclick=|${jsFunction}(${offset_minus2 - index_diff },${page.getSize()});|">
|
||||
<span aria-hidden="true" th:text="${offset_minus2}"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="page-item" th:if="${ offset_minus1 > 0}">
|
||||
<a class="page-link" href="#" th:attr="onclick=|${jsFunction}(${offset_minus1 - index_diff },${page.getSize()});|">
|
||||
<span aria-hidden="true" th:text="${offset_minus1 }"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="page-item disabled">
|
||||
<a class="page-link" style="font-weight: bold" th:text="${current_page}"></a>
|
||||
</li>
|
||||
<li class="page-item" th:if="${offset_plus1 <= page.getTotalPages()}">
|
||||
<a class="page-link" href="#" th:attr="onclick=|${jsFunction}(${offset_plus1 - index_diff },${page.getSize()});|">
|
||||
<span aria-hidden="true" th:text="${offset_plus1}"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="page-item" th:if="${offset_plus2 <= page.getTotalPages()}">
|
||||
<a class="page-link" href="#" th:attr="onclick=|${jsFunction}(${offset_plus2 - index_diff },${page.getSize()});|">
|
||||
<span aria-hidden="true" th:text="${offset_plus2}"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="page-item" th:classappend="${ (page.getTotalPages()) - current_page <= 0 } ? 'disabled'">
|
||||
<a class="page-link" href="#" th:attr="onclick=|${jsFunction}(${page.getTotalPages() - index_diff },${page.getSize()});|">
|
||||
<span aria-hidden="true">마지막</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div>
|
||||
[총 <span th:text="${page.getTotalElements()}"></span>건, <span th:text="${page.getNumber() + 1}"></span>/<span th:text="${page.getTotalPages()}"></span>페이지]
|
||||
</div>
|
||||
</nav>
|
||||
<script>
|
||||
|
||||
</script>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,28 @@
|
||||
<!doctype html>
|
||||
<html xmlns:th="http://www.thymeleaf.org"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
|
||||
|
||||
|
||||
<head th:replace="fragment/head :: headFragment">
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<!-- header -->
|
||||
<header th:replace="fragment/header :: headerFragment"></header>
|
||||
<th:block th:replace="fragment/header :: headerScript"></th:block>
|
||||
<nav th:replace="fragment/header :: navFragment"></nav>
|
||||
|
||||
<div>
|
||||
<section layout:fragment="contentFragment">
|
||||
</section>
|
||||
|
||||
<th:block layout:fragment="contentScript">
|
||||
</th:block>
|
||||
</div>
|
||||
|
||||
<footer th:replace="fragment/footer :: footerFragment"></footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,76 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko" xmlns:th="http://www.thymeleaf.org"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
|
||||
<head>
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Http Mock Server</title>
|
||||
<!doctype html>
|
||||
<html xmlns:th="http://www.thymeleaf.org"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
|
||||
|
||||
<th:block th:replace="fragment/config :: configFragment"></th:block>
|
||||
|
||||
<head th:replace="fragment/head :: headFragment">
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body class="hold-transition sidebar-mini">
|
||||
<div class="wrapper">
|
||||
<!-- partial:partials/_navbar.html -->
|
||||
<th:block th:replace="fragment/navbar :: navbarFragment"></th:block>
|
||||
|
||||
<!-- partial:partials/_sidebar.html -->
|
||||
<th:block th:replace="fragment/sidebar :: sidebarFragment"></th:block>
|
||||
<body>
|
||||
|
||||
<!-- content-wrapper-->
|
||||
<!-- content fragment(현재 layout을 사용하는 content fragment의 내용을 삽입) -->
|
||||
<th:block layout:fragment="content"></th:block>
|
||||
<!-- header -->
|
||||
<header th:replace="fragment/header :: headerFragment"></header>
|
||||
<th:block th:replace="fragment/header :: headerScript"></th:block>
|
||||
<nav th:replace="fragment/header :: navFragment"></nav>
|
||||
|
||||
<!-- partial:partials/_footer.html -->
|
||||
<th:block th:replace="fragment/footer :: footerFragment">
|
||||
</th:block>
|
||||
|
||||
<!-- Control Sidebar -->
|
||||
<aside class="control-sidebar control-sidebar-dark">
|
||||
<!-- Control sidebar content goes here -->
|
||||
</aside>
|
||||
<!-- /.control-sidebar -->
|
||||
</div>
|
||||
|
||||
<!-- jQuery -->
|
||||
<script th:src="@{/plugins/jquery/jquery.min.js}"></script>
|
||||
<!-- jQuery UI 1.11.4 -->
|
||||
<script th:src="@{/plugins/jquery-ui/jquery-ui.min.js}"></script>
|
||||
<!-- Resolve conflict in jQuery UI tooltip with Bootstrap tooltip -->
|
||||
<script>
|
||||
$.widget.bridge('uibutton', $.ui.button)
|
||||
</script>
|
||||
<!-- Bootstrap 4 -->
|
||||
<script th:src="@{/plugins/bootstrap/js/bootstrap.bundle.min.js}"></script>
|
||||
<!-- csrf -->
|
||||
<input id="csrf" type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}">
|
||||
<div class="">
|
||||
|
||||
<section class="" layout:fragment="contentFragment">
|
||||
</section>
|
||||
<th:block layout:fragment="contentScript">
|
||||
</th:block>
|
||||
|
||||
</div>
|
||||
|
||||
<footer th:replace="fragment/footer :: footerFragment"></footer>
|
||||
|
||||
<!-- AdminLTE App -->
|
||||
<script th:src="@{/dist/js/adminlte.js}"></script>
|
||||
<!-- AdminLTE for demo purposes -->
|
||||
<script th:src="@{/dist/js/demo.js}"></script>
|
||||
|
||||
<!-- Content Page의 script fragment 삽입 -->
|
||||
<th:block layout:fragment="script"></th:block>
|
||||
|
||||
<script>
|
||||
$(function () {
|
||||
var url = window.location;
|
||||
if (typeof urlForSidebar !== 'undefined') {
|
||||
url = window.location.protocol + '//' + window.location.host + urlForSidebar;
|
||||
}
|
||||
|
||||
// for single sidebar menu
|
||||
$('ul.nav-sidebar a').filter(function () {
|
||||
return this.href == url;
|
||||
}).addClass('active');
|
||||
|
||||
// for sidebar menu and treeview
|
||||
$('ul.nav-treeview a').filter(function () {
|
||||
return this.href == url;
|
||||
}).parentsUntil(".nav-sidebar > .nav-treeview")
|
||||
.css({'display': 'block'})
|
||||
.addClass('menu-open').prev('a')
|
||||
.addClass('active');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
<!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"
|
||||
layout:decorator="layout/default_layout">
|
||||
|
||||
<div class="content-wrapper" layout:fragment="content">
|
||||
<!-- Content Header (Page header) -->
|
||||
<section class="content-header">
|
||||
<div class="container-fluid">
|
||||
<div class="row mb-2">
|
||||
<div class="col-sm-6">
|
||||
<h1 th:if="${apiServiceKey.id == null}">API 서비스키 등록</h1>
|
||||
<h1 th:unless="${apiServiceKey.id == null}">API 서비스키 수정</h1>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<ol class="breadcrumb float-sm-right">
|
||||
<li class="breadcrumb-item"><a href="#">Home</a></li>
|
||||
<li class="breadcrumb-item active">API 관리</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
</section>
|
||||
|
||||
<!-- Main content -->
|
||||
<section class="content">
|
||||
<div class="container-fluid">
|
||||
<form class="inputForm" action="#" th:action="@{/manage/saveApiKey}"
|
||||
th:object="${apiServiceKey}" method="post">
|
||||
<div class="card card-default">
|
||||
<!--
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Basic Info</h3>
|
||||
</div>
|
||||
-->
|
||||
<div class="card-body">
|
||||
<div class="form-group">
|
||||
<label for="url">URL<small>(*)</small></label> <input type="text"
|
||||
th:field="*{url}" class="form-control"
|
||||
placeholder="ex) /mock-api/~~"> <span
|
||||
th:if="${#fields.hasErrors('url')}" th:errors="*{url}"
|
||||
class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="serviceType">서비스키타입<small>(*)</small></label> <select
|
||||
class="form-control" th:field="*{serviceType}">
|
||||
<option value="header">header</option>
|
||||
<option value="parameter">parameter</option>
|
||||
<option value="json-body">json-body</option>
|
||||
<option value="flat-data">flat-data(서비스키명:
|
||||
start-position, length)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="serviceKey">서비스키명<small>(*)</small></label> <input
|
||||
type="text" th:field="*{serviceKey}" class="form-control">
|
||||
<span th:if="${#fields.hasErrors('serviceKey')}"
|
||||
th:errors="*{serviceKey}" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" th:field="*{id}">
|
||||
<button type="submit" class="btn btn-primary mr-2">Submit</button>
|
||||
<button type="button" class="btn btn-secondary"
|
||||
onclick="history.go(-1);">Cancel</button>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<th:block layout:fragment="script">
|
||||
<script th:inline="javascript">
|
||||
var urlForSidebar = "/manage/findAllApiKeys";
|
||||
</script>
|
||||
</th:block>
|
||||
</html>
|
||||
@@ -1,308 +0,0 @@
|
||||
<!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"
|
||||
layout:decorator="layout/default_layout">
|
||||
|
||||
<div class="content-wrapper" layout:fragment="content">
|
||||
<!-- Content Header (Page header) -->
|
||||
<section class="content-header">
|
||||
<div class="container-fluid">
|
||||
<div class="row mb-2">
|
||||
<div class="col-sm-6">
|
||||
<h1 th:if="${apiInfo.id == null}">API 정보 등록</h1>
|
||||
<h1 th:unless="${apiInfo.id == null}">API 정보 수정</h1>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<ol class="breadcrumb float-sm-right">
|
||||
<li class="breadcrumb-item"><a href="#">Home</a></li>
|
||||
<li class="breadcrumb-item active">API 관리</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
</section>
|
||||
|
||||
<!-- Main content -->
|
||||
<section class="content" style="padding-bottom: 1rem;">
|
||||
<div class="container-fluid">
|
||||
<form id="form" class="inputForm" action="#" th:action="@{/manage/saveApi}"
|
||||
th:object="${apiInfo}" method="post">
|
||||
<div class="card card-primary">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Basic Info</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">API 그룹명<small>(*)</small></label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" th:field="*{apiGroupName}"
|
||||
class="form-control"> <span
|
||||
th:if="${#fields.hasErrors('apiGroupName')}"
|
||||
th:errors="*{apiGroupName}" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">API 명<small>(*)</small></label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" th:field="*{apiName}" class="form-control">
|
||||
<span th:if="${#fields.hasErrors('apiName')}"
|
||||
th:errors="*{apiName}" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">URL<small>(*)</small></label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" th:field="*{url}" class="form-control"
|
||||
placeholder="ex) /mock-api/~~"> <span
|
||||
th:if="${#fields.hasErrors('url')}" th:errors="*{url}"
|
||||
class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">Method<small>(*)</small></label>
|
||||
<div class="col-sm-2">
|
||||
<div class="form-radio">
|
||||
<label class="form-check-label"> <input type="radio"
|
||||
th:field="*{method}" class="form-check-input" value="POST">
|
||||
POST <i class="input-helper"></i></label>
|
||||
</div>
|
||||
<div class="form-radio">
|
||||
<label class="form-check-label"> <input type="radio"
|
||||
th:field="*{method}" class="form-check-input" value="">
|
||||
ALL <i class="input-helper"></i></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<div class="form-radio">
|
||||
<label class="form-check-label"> <input type="radio"
|
||||
th:field="*{method}" class="form-check-input" value="GET">
|
||||
GET <i class="input-helper"></i></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<div class="form-radio">
|
||||
<label class="form-check-label"> <input type="radio"
|
||||
th:field="*{method}" class="form-check-input" value="PUT">
|
||||
PUT <i class="input-helper"></i></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-3">
|
||||
<div class="form-radio">
|
||||
<label class="form-check-label"> <input type="radio"
|
||||
th:field="*{method}" class="form-check-input" value="DELETE">
|
||||
DELETE <i class="input-helper"></i></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">서비스코드</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" th:field="*{serviceValue}"
|
||||
class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card card-primary">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Response Info</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">Content Type</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" th:field="*{responseContentType}"
|
||||
class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">응답 Headers</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" th:field="*{responseHeaders}"
|
||||
class="form-control"
|
||||
placeholder="ex) api-code=A10,user-id=James,...">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">응답 Status Code</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" th:field="*{responseStatusCode}"
|
||||
class="form-control"> <span
|
||||
th:if="${#fields.hasErrors('responseStatusCode')}" th:errors="*{responseStatusCode}"
|
||||
class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">Sleep 타임(초)</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" th:field="*{sleepSeconds}"
|
||||
class="form-control"> <span
|
||||
th:if="${#fields.hasErrors('sleepSeconds')}" th:errors="*{sleepSeconds}"
|
||||
class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">스크립트 명</label>
|
||||
<div class="col-sm-9">
|
||||
<select class="form-control select2bs4" th:field="*{scriptName}" th:value="*{scriptName}"> style="width: 100%;" >
|
||||
<option value="">선택안함</option>
|
||||
<option th:each="scriptInfo : ${scriptInfos}" th:value="${scriptInfo.scriptName}" th:text="${scriptInfo.scriptName + '(' + scriptInfo.scriptDesc + ')'}"></option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">Syntax 응답 Body1</label>
|
||||
<div class="col-sm-9">
|
||||
<select class="form-control" th:field="*{syntaxResponseBody1}" th:value="*{syntaxResponseBody1}">
|
||||
<option th:value="'plaintext'" th:text="TEXT"></option>
|
||||
<option th:value="'json'" th:text="JSON"></option>
|
||||
<option th:value="'xml'" th:text="XML"></option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">Syntax 응답 Body2</label>
|
||||
<div class="col-sm-9">
|
||||
<select class="form-control" th:field="*{syntaxResponseBody2}" th:value="*{syntaxResponseBody2}">
|
||||
<option th:value="'plaintext'" th:text="TEXT"></option>
|
||||
<option th:value="'json'" th:text="JSON"></option>
|
||||
<option th:value="'xml'" th:text="XML"></option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">응답 Body1</label>
|
||||
<div class="col-sm-9">
|
||||
<div id="responseBody1" class="shadow-sm" style="height: 200px; border: 1px solid #ced4da; border-radius: .25rem;"></div>
|
||||
<!-- <textarea class="form-control" th:field="*{responseBody1}"-->
|
||||
<!-- rows="3"></textarea>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">응답 Body2</label>
|
||||
<div class="col-sm-9">
|
||||
<!-- <textarea class="form-control" th:field="*{responseBody2}"-->
|
||||
<!-- rows="3"></textarea>-->
|
||||
<div id="responseBody2" class="shadow-sm" style="height: 200px; border: 1px solid #ced4da; border-radius: .25rem;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" th:field="*{id}">
|
||||
<button type="submit" class="btn btn-primary mr-2">Submit</button>
|
||||
<button type="button" class="btn btn-secondary"
|
||||
onclick="history.go(-1);">Cancel</button>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<th:block layout:fragment="script">
|
||||
<link rel="stylesheet" data-name="vs/editor/editor.main"
|
||||
th:href="@{/plugins/vs/editor/editor.main.css}">
|
||||
|
||||
<link rel="stylesheet" th:href="@{/plugins/select2/css/select2.min.css}">
|
||||
<link rel="stylesheet" th:href="@{/plugins/select2-bootstrap4-theme/select2-bootstrap4.min.css}">
|
||||
|
||||
<script th:src="@{/plugins/select2/js/select2.full.js}"></script>
|
||||
|
||||
<script>var require = { paths: { 'vs': '../../plugins/vs' } };</script>
|
||||
|
||||
<script th:src="@{/plugins/vs/loader.js}"></script>
|
||||
<script th:src="@{/plugins/vs/editor/editor.main.nls.js}"></script>
|
||||
<script th:src="@{/plugins/vs/editor/editor.main.js}"></script>
|
||||
|
||||
<script th:inline="javascript">
|
||||
var urlForSidebar = "/manage/findAllApis";
|
||||
|
||||
//Initialize Select2 Elements
|
||||
$('.select2bs4').select2({
|
||||
theme: 'bootstrap4'
|
||||
})
|
||||
|
||||
function setMonaco(elementId, selectId, initValue){
|
||||
var targetDivElement = document.getElementById(elementId);
|
||||
var lang = $("#"+selectId+" option:selected").val();
|
||||
|
||||
var editor = monaco.editor.create(targetDivElement, {
|
||||
value: initValue,
|
||||
language: lang,
|
||||
minimap: {
|
||||
enabled: false
|
||||
},
|
||||
wordWrap: 'on',
|
||||
wrappingStrategy: 'simple',
|
||||
wordWrapBreakAfterCharacters: '',
|
||||
wordWrapBreakBeforeCharacters: '',
|
||||
wrappingIndent: 'none',
|
||||
automaticLayout: true
|
||||
});
|
||||
|
||||
$("#"+selectId).change(function(){
|
||||
var selectLang = $("#"+selectId+" option:selected").val();
|
||||
monaco.editor.setModelLanguage(editor.getModel(), selectLang);
|
||||
});
|
||||
|
||||
$('#form').submit(function(eventObj) {
|
||||
$("<input />").attr("type", "hidden")
|
||||
.attr("name", elementId)
|
||||
.attr("value", editor.getValue())
|
||||
.appendTo("#form");
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
setMonaco('responseBody1', 'syntaxResponseBody1', /*[[${apiInfo.responseBody1}]]*/);
|
||||
setMonaco('responseBody2', 'syntaxResponseBody2', /*[[${apiInfo.responseBody2}]]*/);
|
||||
</script>
|
||||
</th:block>
|
||||
</html>
|
||||
@@ -1,239 +0,0 @@
|
||||
<!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"
|
||||
layout:decorator="layout/default_layout">
|
||||
|
||||
<div class="content-wrapper" layout:fragment="content">
|
||||
<!-- Content Header (Page header) -->
|
||||
<section class="content-header">
|
||||
<div class="container-fluid">
|
||||
<div class="row mb-2">
|
||||
<div class="col-sm-6">
|
||||
<h1 th:if="${bytesMessageSpec.id == null}">Bytes Message 정보 등록</h1>
|
||||
<h1 th:unless="${bytesMessageSpec.id == null}">Bytes Message 정보 수정</h1>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<ol class="breadcrumb float-sm-right">
|
||||
<li class="breadcrumb-item"><a href="#">Home</a></li>
|
||||
<li class="breadcrumb-item active">Echo Socket</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
</section>
|
||||
|
||||
<!-- Main content -->
|
||||
<section class="content" style="padding-bottom: 1rem;">
|
||||
<div class="container-fluid">
|
||||
<form id="bytesMessageSpecForm" name="bytesMessageSpecForm" class="inputForm" action="#" th:action="@{/manage/saveBytesMessageSpec}"
|
||||
th:object="${bytesMessageSpec}" method="post">
|
||||
<div class="card card-primary">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Basic Info</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">Message명<small>(*)</small></label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" th:field="*{specName}"
|
||||
class="form-control"> <span
|
||||
th:if="${#fields.hasErrors('specName')}"
|
||||
th:errors="*{specName}" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">Encode</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" th:field="*{encode}" class="form-control" placeholder="EUC-KR">
|
||||
<span th:if="${#fields.hasErrors('encode')}"
|
||||
th:errors="*{encode}" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">LL길이<small>(*)</small></label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" th:field="*{llFieldLength}" class="form-control"> <span
|
||||
th:if="${#fields.hasErrors('llFieldLength')}" th:errors="*{llFieldLength}"
|
||||
class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">LL길이포함</label>
|
||||
<div class="col-sm-4">
|
||||
<div class="form-radio">
|
||||
<label class="form-check-label"> <input type="radio"
|
||||
th:field="*{llFieldLengthInclude}" class="form-check-input" value="Y">
|
||||
Y <i class="input-helper"></i></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-5">
|
||||
<div class="form-radio">
|
||||
<label class="form-check-label"> <input type="radio"
|
||||
th:field="*{llFieldLengthInclude}" class="form-check-input" value="N">
|
||||
N <i class="input-helper"></i></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">Port<small>(*)</small></label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" th:field="*{port}" class="form-control" placeholder="38181"> <span
|
||||
th:if="${#fields.hasErrors('port')}" th:errors="*{port}"
|
||||
class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">사용여부</label>
|
||||
<div class="col-sm-4">
|
||||
<div class="form-radio">
|
||||
<label class="form-check-label"> <input type="radio"
|
||||
th:field="*{useYn}" class="form-check-input" value="Y">
|
||||
Y <i class="input-helper"></i></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-5">
|
||||
<div class="form-radio">
|
||||
<label class="form-check-label"> <input type="radio"
|
||||
th:field="*{useYn}" class="form-check-input" value="N">
|
||||
N <i class="input-helper"></i></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card card-primary">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Response Message Info</h3>
|
||||
<br>
|
||||
<small> <font color="blue">- 응답 메시지를 입력할 경우 아래 Acho Message Info 정보는 무시 됩니다.</font></small>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="form-group">
|
||||
<label for="url">응답 메시지</label>
|
||||
<textarea class="form-control" th:field="*{responseBody}" rows="3"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card card-primary">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Acho Message Info</h3>
|
||||
|
||||
<button type="button" id="addReplaceRule" class="btn btn-sm btn-success float-right">
|
||||
<i class="fas fa-plus"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table id="replaceRuleTable" class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No.</th>
|
||||
<th>Replace 시작 Index</th>
|
||||
<th>Replace 스트링</th>
|
||||
<th>삭제</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="dynamicTableContents">
|
||||
<tr th:fragment="echoReplaceString"
|
||||
th:each="echoReplaceString,rowStat : ${bytesMessageSpec.getEchoReplaceStringList()}">
|
||||
<td th:text="${rowStat.count}">1</td>
|
||||
<td>
|
||||
<input type="hidden" th:field="${bytesMessageSpec.echoReplaceStringList[__${rowStat.index}__].id}">
|
||||
<input type="text" th:field="${bytesMessageSpec.echoReplaceStringList[__${rowStat.index}__].position}" class="form-control"> <span
|
||||
th:if="${#fields.hasErrors('${bytesMessageSpec.echoReplaceStringList[__${rowStat.index}__].position}')}"
|
||||
th:errors="${bytesMessageSpec.echoReplaceStringList[__${rowStat.index}__].position}"
|
||||
class="text-danger"></span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" th:field="${bytesMessageSpec.echoReplaceStringList[__${rowStat.index}__].replaceString}" class="form-control"> <span
|
||||
th:if="${#fields.hasErrors('echoReplaceStringList[__${rowStat.index}__].replaceString')}"
|
||||
th:errors="*{echoReplaceStringList[__${rowStat.index}__].replaceString}"
|
||||
class="text-danger"></span>
|
||||
</td>
|
||||
<td>
|
||||
<div class="btn-group">
|
||||
<button type="button" id="removeDynamicRow" class="btn btn-sm btn-danger">
|
||||
<i class="far fa-trash-alt"></i>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" th:field="*{id}">
|
||||
<button type="button" id="submitButton" class="btn btn-primary mr-2">Submit</button>
|
||||
<button type="button" class="btn btn-secondary"
|
||||
onclick="history.go(-1);">Cancel</button>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<th:block layout:fragment="script">
|
||||
<script th:inline="javascript">
|
||||
var urlForSidebar = "/manage/findAllBytesMessageSpecs";
|
||||
|
||||
$("#addReplaceRule").click(function() {
|
||||
var idx = $('#dynamicTableContents tr:last td:first').text();
|
||||
try {
|
||||
if (idx) {
|
||||
idx++;
|
||||
} else {
|
||||
idx = 1;
|
||||
}
|
||||
} catch (error) {}
|
||||
|
||||
var trStr = '<tr><td>' + idx + '</td>'
|
||||
+ '<td><input type="text" class="form-control"></td>'
|
||||
+ '<td><input type="text" class="form-control"></td>'
|
||||
+ '<td><div class="btn-group"><button type="button" id="removeDynamicRow" class="btn btn-sm btn-danger"><i class="far fa-trash-alt"></i></button></div></td></tr>';
|
||||
$("#dynamicTableContents").append(trStr);
|
||||
});
|
||||
|
||||
$("#replaceRuleTable").on("click", "#removeDynamicRow", function() {
|
||||
$(this).closest("tr").remove();
|
||||
});
|
||||
|
||||
$("#submitButton").click(function() {
|
||||
$('#dynamicTableContents > tr').each(function(index, tr) {
|
||||
var idValue = $(tr).find("td:eq(1) input[type=hidden]").val();
|
||||
if (idValue) {
|
||||
$(tr).find("td:eq(1) input[type=hidden]").attr('name', 'echoReplaceStringList[' + index + '].id');
|
||||
}
|
||||
$(tr).find("td:eq(1) input[type=text]").attr('name', 'echoReplaceStringList[' + index + '].position');
|
||||
|
||||
$(tr).find("td:eq(2) input[type=text]").attr('name', 'echoReplaceStringList[' + index + '].replaceString');
|
||||
});
|
||||
|
||||
$(this).css({'cursor':'wait'});
|
||||
$(this).attr('disabled', true);
|
||||
document.body.style.cursor = 'wait';
|
||||
document.bytesMessageSpecForm.submit();
|
||||
});
|
||||
</script>
|
||||
</th:block>
|
||||
</html>
|
||||
@@ -1,321 +0,0 @@
|
||||
<!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"
|
||||
layout:decorator="layout/default_layout">
|
||||
|
||||
<div class="content-wrapper" layout:fragment="content">
|
||||
<!-- Content Header (Page header) -->
|
||||
<section class="content-header">
|
||||
<div class="container-fluid">
|
||||
<div class="row mb-2">
|
||||
<div class="col-sm-6">
|
||||
<h1 th:if="${httpRequestInfo.id == null}">HTTP 요청 정보 등록</h1>
|
||||
<h1 th:unless="${httpRequestInfo.id == null}">HTTP 요청 정보 수정</h1>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<ol class="breadcrumb float-sm-right">
|
||||
<li class="breadcrumb-item"><a href="#">Home</a></li>
|
||||
<li class="breadcrumb-item active">부가 기능</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
</section>
|
||||
|
||||
<!-- Main content -->
|
||||
<section class="content" style="padding-bottom: 1rem;">
|
||||
<div class="container-fluid">
|
||||
<form id="form" class="inputForm" action="#" th:action="@{/manage/saveHttpRequestInfo}"
|
||||
th:object="${httpRequestInfo}" method="post">
|
||||
<div class="card card-primary">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Basic Info</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">요청 그룹명<small>(*)</small></label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" th:field="*{requestGroupName}"
|
||||
class="form-control"> <span
|
||||
th:if="${#fields.hasErrors('requestGroupName')}"
|
||||
th:errors="*{requestGroupName}" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">요청명<small>(*)</small></label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" th:field="*{requestName}" class="form-control">
|
||||
<span th:if="${#fields.hasErrors('requestName')}"
|
||||
th:errors="*{requestName}" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">URL<small>(*)</small></label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" th:field="*{url}" class="form-control"
|
||||
placeholder="ex) http://~~:8080/api/~~"> <span
|
||||
th:if="${#fields.hasErrors('url')}" th:errors="*{url}"
|
||||
class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">Method<small>(*)</small></label>
|
||||
<div class="col-sm-2">
|
||||
<div class="form-radio">
|
||||
<label class="form-check-label"> <input type="radio"
|
||||
th:field="*{method}" class="form-check-input" value="POST">
|
||||
POST <i class="input-helper"></i></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<div class="form-radio">
|
||||
<label class="form-check-label"> <input type="radio"
|
||||
th:field="*{method}" class="form-check-input" value="GET">
|
||||
GET <i class="input-helper"></i></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<div class="form-radio">
|
||||
<label class="form-check-label"> <input type="radio"
|
||||
th:field="*{method}" class="form-check-input" value="PUT">
|
||||
PUT <i class="input-helper"></i></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-3">
|
||||
<div class="form-radio">
|
||||
<label class="form-check-label"> <input type="radio"
|
||||
th:field="*{method}" class="form-check-input" value="DELETE">
|
||||
DELETE <i class="input-helper"></i></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">URL Query Params</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" th:field="*{queryParams}"
|
||||
class="form-control"
|
||||
placeholder="ex) apiCode=A10&userId=James&...">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="card card-primary">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Request Info</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">Content Type</label>
|
||||
<div class="col-sm-9">
|
||||
<select class="form-control" th:field="*{requestContentType}" th:value="*{requestContentType}">
|
||||
<option th:value="'application/json'" th:text="'application/json'"></option>
|
||||
<option th:value="'application/xml'" th:text="'application/xml'"></option>
|
||||
<option th:value="'application/x-www-form-urlencoded'" th:text="'application/x-www-form-urlencoded'"></option>
|
||||
<option th:value="'text/plain'" th:text="'text/plain'"></option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">Encode</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" th:field="*{encode}"
|
||||
class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">요청 Headers</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" th:field="*{requestHeaders}"
|
||||
class="form-control"
|
||||
placeholder="ex) api-code=A10,user-id=James,...">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">요청 Body</label>
|
||||
<div class="col-sm-9">
|
||||
<div id="requestBodyDiv" class="shadow-sm" style="height: 200px; border: 1px solid #ced4da; border-radius: .25rem;"></div>
|
||||
<input type="hidden" th:field="*{requestBody}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="card card-primary">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Response Data</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">응답 Status Code</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control" id="responseStatusCode" name="responseStatusCode">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">응답 Headers</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control" id="responseHeaders" name="responseHeaders">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" style="margin-top: 2em;">
|
||||
<label class="col-sm-3 col-form-label"> </label>
|
||||
<div class="col-sm-9">
|
||||
<button type="button" class="btn btn-default btn-sm" id="btn_json" style="float: right;">Format JSON</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">응답 Body</label>
|
||||
<div class="col-sm-9">
|
||||
<div id="responseBody" class="shadow-sm" style="height: 200px; border: 1px solid #ced4da; border-radius: .25rem;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" th:field="*{id}">
|
||||
<button type="submit" class="btn btn-primary mr-2">Submit</button>
|
||||
<button type="button" class="btn btn-secondary"
|
||||
onclick="history.go(-1);">Cancel</button>
|
||||
|
||||
<button type="button" class="btn btn-primary mr-2" id="execBtn" style="float: right;">Execute</button>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<th:block layout:fragment="script">
|
||||
<link rel="stylesheet" data-name="vs/editor/editor.main"
|
||||
th:href="@{/plugins/vs/editor/editor.main.css}">
|
||||
|
||||
<link rel="stylesheet" th:href="@{/plugins/select2/css/select2.min.css}">
|
||||
<link rel="stylesheet" th:href="@{/plugins/select2-bootstrap4-theme/select2-bootstrap4.min.css}">
|
||||
|
||||
<script th:src="@{/plugins/select2/js/select2.full.js}"></script>
|
||||
|
||||
<script>var require = { paths: { 'vs': '../../plugins/vs' } };</script>
|
||||
|
||||
<script th:src="@{/plugins/vs/loader.js}"></script>
|
||||
<script th:src="@{/plugins/vs/editor/editor.main.nls.js}"></script>
|
||||
<script th:src="@{/plugins/vs/editor/editor.main.js}"></script>
|
||||
|
||||
<script th:inline="javascript">
|
||||
var urlForSidebar = "/manage/findAllHttpRequestInfos";
|
||||
|
||||
//Initialize Select2 Elements
|
||||
$('.select2bs4').select2({
|
||||
theme: 'bootstrap4'
|
||||
})
|
||||
|
||||
$("#execBtn").click(function() {
|
||||
$("#requestBody").val(window.editor.getValue());
|
||||
var postData = $('#form').serializeArray();
|
||||
|
||||
$.ajax({
|
||||
url : "/manage/executeHttpRequest",
|
||||
data : postData,
|
||||
dataType : "json",
|
||||
type : "POST",
|
||||
success : function(raw) {
|
||||
$("#responseStatusCode").val(raw.statusCode);
|
||||
$("#responseHeaders").val(raw.headers);
|
||||
window.editor2.setValue(raw.body);
|
||||
},
|
||||
error : function(e) {
|
||||
alert("전송에 실패했습니다.\n" + e.responseText);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$("#btn_json").click(function() {
|
||||
try {
|
||||
var jsonObj = JSON.parse(window.editor2.getValue());
|
||||
window.editor2.setValue(JSON.stringify(jsonObj, null, 4));
|
||||
} catch (e) {}
|
||||
});
|
||||
|
||||
function setMonaco(elementId, selectId, initValue){
|
||||
var targetDivElement = document.getElementById(elementId);
|
||||
var lang = $("#"+selectId+" option:selected").val();
|
||||
|
||||
window.editor = monaco.editor.create(targetDivElement, {
|
||||
value: initValue,
|
||||
language: lang,
|
||||
minimap: {
|
||||
enabled: false
|
||||
},
|
||||
wordWrap: 'on',
|
||||
wrappingStrategy: 'simple',
|
||||
wordWrapBreakAfterCharacters: '',
|
||||
wordWrapBreakBeforeCharacters: '',
|
||||
wrappingIndent: 'none',
|
||||
automaticLayout: true
|
||||
});
|
||||
|
||||
$("#"+selectId).change(function(){
|
||||
var selectLang = $("#"+selectId+" option:selected").val();
|
||||
if (selectLang == "application/x-www-form-urlencoded") {
|
||||
alert("요청 Body에 'userId=aaa&userName=이링크' 형식으로 입력해야 합니다.");
|
||||
}
|
||||
monaco.editor.setModelLanguage(editor.getModel(), selectLang);
|
||||
});
|
||||
|
||||
$('#form').submit(function(eventObj) {
|
||||
$("#requestBody").val(window.editor.getValue());
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
function setMonaco2(elementId, selectId, initValue){
|
||||
var targetDivElement = document.getElementById(elementId);
|
||||
var lang = $("#"+selectId+" option:selected").val();
|
||||
|
||||
window.editor2 = monaco.editor.create(targetDivElement, {
|
||||
value: initValue,
|
||||
language: lang,
|
||||
minimap: {
|
||||
enabled: false
|
||||
},
|
||||
wordWrap: 'on',
|
||||
wrappingStrategy: 'simple',
|
||||
wordWrapBreakAfterCharacters: '',
|
||||
wordWrapBreakBeforeCharacters: '',
|
||||
wrappingIndent: 'none',
|
||||
automaticLayout: true
|
||||
});
|
||||
|
||||
$("#"+selectId).change(function(){
|
||||
var selectLang = $("#"+selectId+" option:selected").val();
|
||||
monaco.editor.setModelLanguage(window.editor2.getModel(), selectLang);
|
||||
});
|
||||
}
|
||||
|
||||
setMonaco('requestBodyDiv', 'requestContentType', /*[[${httpRequestInfo.requestBody}]]*/);
|
||||
setMonaco2('responseBody', 'requestContentType', "");
|
||||
</script>
|
||||
</th:block>
|
||||
</html>
|
||||
@@ -1,215 +0,0 @@
|
||||
<!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"
|
||||
layout:decorator="layout/default_layout">
|
||||
|
||||
<div class="content-wrapper" layout:fragment="content">
|
||||
<!-- Content Header (Page header) -->
|
||||
<section class="content-header">
|
||||
<div class="container-fluid">
|
||||
<div class="row mb-2">
|
||||
<div class="col-sm-6">
|
||||
<h1 th:if="${scriptInfo.id == null}">스크립트 정보 등록</h1>
|
||||
<h1 th:unless="${scriptInfo.id == null}">스크립트 정보 수정</h1>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<ol class="breadcrumb float-sm-right">
|
||||
<li class="breadcrumb-item"><a href="#">Home</a></li>
|
||||
<li class="breadcrumb-item active">스크립트 관리</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
</section>
|
||||
|
||||
<!-- Main content -->
|
||||
<section class="content" style="padding-bottom: 1rem;">
|
||||
<div class="container-fluid">
|
||||
<form id="form" class="inputForm" action="#" th:action="@{/manage/saveScriptInfo}"
|
||||
th:object="${scriptInfo}" method="post">
|
||||
<div class="card card-primary">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Basic Info</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">스크립트 명<small>(*)</small></label>
|
||||
<div class="col-sm-9">
|
||||
<input id="scriptName" type="text" th:field="*{scriptName}" class="form-control">
|
||||
<span th:if="${#fields.hasErrors('scriptName')}"
|
||||
th:errors="*{scriptName}" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">스크립트 설명<small>(*)</small></label>
|
||||
<div class="col-sm-9">
|
||||
<input id="scriptName" type="text" th:field="*{scriptDesc}" class="form-control">
|
||||
<span th:if="${#fields.hasErrors('scriptDesc')}"
|
||||
th:errors="*{scriptDesc}" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card card-primary">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Script Code</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-1 col-form-label">Script Editor</label>
|
||||
<div class="col-sm-11">
|
||||
<div id="scriptCode" class="shadow-sm" style="height:400px"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" th:field="*{id}">
|
||||
<button type="submit" class="btn btn-primary mr-2">Submit</button>
|
||||
<button type="button" class="btn btn-secondary"
|
||||
onclick="history.go(-1);">Cancel</button>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<th:block layout:fragment="script">
|
||||
<link rel="stylesheet" data-name="vs/editor/editor.main"
|
||||
th:href="@{/plugins/vs/editor/editor.main.css}">
|
||||
<link rel="stylesheet"
|
||||
th:href="@{/plugins/vs/plugin/constrained-editor-plugin/constrainedEditorPlugin.css}">
|
||||
<script th:src="@{/plugins/vs/plugin/constrained-editor-plugin/constrainedEditorPlugin.js}"></script>
|
||||
|
||||
<script>var require = { paths: { 'vs': '../../plugins/vs' } };</script>
|
||||
|
||||
<script th:src="@{/plugins/vs/loader.js}"></script>
|
||||
<script th:src="@{/plugins/vs/editor/editor.main.nls.js}"></script>
|
||||
<script th:src="@{/plugins/vs/editor/editor.main.js}"></script>
|
||||
<script th:inline="javascript">
|
||||
var urlForSidebar = "/manage/findAllScriptInfos";
|
||||
let editor;
|
||||
let constrainedInstance;
|
||||
|
||||
const isNew = /*[[${scriptInfo.id == null}]]*/ false;
|
||||
|
||||
function findLineNumberByText(text){
|
||||
const linesContent = editor.getModel().getLinesContent();
|
||||
for (let i = 0; i < linesContent.length; i++) {
|
||||
const lineText = linesContent[i].trim();
|
||||
|
||||
if(lineText.startsWith(text)){
|
||||
return i + 1
|
||||
}
|
||||
}
|
||||
return 14;
|
||||
}
|
||||
|
||||
function setMainRestrictions(isNew){
|
||||
const model = editor.getModel();
|
||||
let editableLine = findLineNumberByText('public String postProcess') + 1;
|
||||
const linesContent = editor.getModel().getLinesContent();
|
||||
const editableLineTextLength = linesContent[editableLine - 1].length + 1;
|
||||
const mainRestrictions = [{
|
||||
// range : [ startLine, startColumn, endLine, endColumn ]
|
||||
range: [3, 1, 3, 26], // Range of Util Variable name
|
||||
label: 'import',
|
||||
allowMultiline: true
|
||||
}, {
|
||||
range: [editableLine, 1, editableLine, editableLineTextLength], // Range of Function definition
|
||||
allowMultiline: true,
|
||||
label: 'funcDefinition'
|
||||
}]
|
||||
|
||||
if(isNew){
|
||||
constrainedInstance.addRestrictionsTo(model, mainRestrictions);
|
||||
}else{
|
||||
model.updateRestrictions(mainRestrictions);
|
||||
}
|
||||
}
|
||||
|
||||
function setMonaco(elementId, initValue){
|
||||
var targetDivElement = document.getElementById(elementId);
|
||||
editor = monaco.editor.create(targetDivElement, {
|
||||
value: initValue,
|
||||
language: 'java',
|
||||
minimap: {
|
||||
enabled: false
|
||||
},
|
||||
wordWrap: 'on',
|
||||
wrappingStrategy: 'simple',
|
||||
wordWrapBreakAfterCharacters: '',
|
||||
wordWrapBreakBeforeCharacters: '',
|
||||
wrappingIndent: 'none',
|
||||
automaticLayout: true
|
||||
});
|
||||
|
||||
constrainedInstance = constrainedEditor(monaco);
|
||||
constrainedInstance.initializeIn(editor);
|
||||
const model = editor.getModel();
|
||||
|
||||
setMainRestrictions(true);
|
||||
// model.toggleHighlightOfEditableAreas();
|
||||
|
||||
$('#form').submit(function(eventObj) {
|
||||
$('#scriptName').prop( "disabled", false );
|
||||
$("<input />").attr("type", "hidden")
|
||||
.attr("name", elementId)
|
||||
.attr("value", editor.getValue())
|
||||
.appendTo("#form");
|
||||
return true;
|
||||
});
|
||||
}
|
||||
setMonaco('scriptCode', /*[[${scriptInfo.scriptCode}]]*/);
|
||||
if(isNew == false){
|
||||
$('#scriptName').prop( "disabled", true );
|
||||
}
|
||||
$('#scriptName').on("change keyup paste", function(){
|
||||
const scriptName = $('#scriptName').val();
|
||||
const classLine = findLineNumberByText('public class')
|
||||
const model = editor.getModel();
|
||||
const linesContent = model.getLinesContent();
|
||||
const currentTextLength = linesContent[classLine - 1].length + 1;
|
||||
// model.toggleHighlightOfEditableAreas();
|
||||
model.updateRestrictions([
|
||||
{
|
||||
range: [classLine, 1, classLine, currentTextLength],
|
||||
label: "classLine"
|
||||
}
|
||||
]);
|
||||
|
||||
const newText = `public class ${scriptName} implements Script{`;
|
||||
editor.executeEdits("my-source", [{ range: new monaco.Range(classLine, 1, classLine, currentTextLength), text: newText, forceMoveMarkers: true }]);
|
||||
|
||||
setMainRestrictions(false);
|
||||
// model.toggleHighlightOfEditableAreas();
|
||||
|
||||
console.log(model.getCurrentEditableRanges());
|
||||
|
||||
|
||||
// constrainedInstance.addRestrictionsTo(model, [{
|
||||
// // range : [ startLine, startColumn, endLine, endColumn ]
|
||||
// range: [classLine, 1, classLine, currentTextLength], // Range of Util Variable name
|
||||
// label: 'className',
|
||||
// allowMultiline: false
|
||||
// }]);
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
</th:block>
|
||||
</html>
|
||||
@@ -0,0 +1,364 @@
|
||||
<!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" layout:decorate="~{/layout/default_layout}">
|
||||
<body>
|
||||
|
||||
<section layout:fragment="contentFragment">
|
||||
<div class="container mt-1">
|
||||
<div class="card col-md">
|
||||
<div class="card-header">
|
||||
<h3>API Tester</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="form-floating col-md-2 me-1">
|
||||
<select name="method" class="form-select" id="method">
|
||||
<option value="POST">POST</option>
|
||||
<option value="GET">GET</option>
|
||||
<option value="PUT">PUT</option>
|
||||
<option value="DELETE">DELETE</option>
|
||||
<option value="CONNECT">CONNECT</option>
|
||||
<option value="HEAD">HEAD</option>
|
||||
<option value="OPTIONS">OPTIONS</option>
|
||||
<option value="TRACE">TRACE</option>
|
||||
<option value="PATCH">PATCH</option>
|
||||
</select>
|
||||
<label for="method" class="form-label must">Method</label>
|
||||
</div>
|
||||
<div class="form-floating col-md-3 me-1">
|
||||
<select name="server" class="form-select">
|
||||
<option th:each="server : ${servers}" th:value="${server.id}"
|
||||
th:text="${server.name}"></option>
|
||||
</select>
|
||||
<label for="method" class="form-label must">Server</label>
|
||||
</div>
|
||||
<div class="input-group col-md">
|
||||
<div class="form-floating col-md">
|
||||
<input type="text" name="path" class="form-control" id="path" placeholder="호출할 경로 (/부터 입력)"
|
||||
required>
|
||||
<label for="path" class="must">Path</label>
|
||||
</div>
|
||||
<button class="btn btn-primary" id="send">Send</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4>요청</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Header 이름</th>
|
||||
<th scope="col">값</th>
|
||||
<th>
|
||||
<button type="button" class="btn btn-secondary btn-sm btn_add_header">추가
|
||||
</button>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="headers">
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table" id="requestMatcherParamTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Query 파라미터 이름</th>
|
||||
<th>값</th>
|
||||
<th>
|
||||
<button type="button" class="btn btn-secondary btn-sm btn_add_query">추가
|
||||
</button>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="queryParams">
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<label class="form-label must">Request Body</label>
|
||||
<div class="">
|
||||
<textarea class="form-control" style="height: 200px;" id="requestBody">
|
||||
</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4>응답</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Header 이름</th>
|
||||
<th scope="col">값</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="responseHeaders">
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<label class="form-label must">Response Body</label>
|
||||
<div class="form-floating">
|
||||
<textarea class="form-control" style="height: 200px;" id="responseBody"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="inputTemplate" style="visibility: hidden; height: 0;">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<input class="form-control" type="text" name="key"/>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" type="text" name="value"/>
|
||||
</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-secondary btn-sm btn_remove">제거</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div id="responseHeaderTemplate" style="visibility: hidden; height: 0;">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<input class="form-control" type="text" name="key"/>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" type="text" name="value"/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
</body>
|
||||
|
||||
<th:block layout:fragment="contentScript">
|
||||
<script>
|
||||
$(function () {
|
||||
let model = {
|
||||
server: null,
|
||||
method: 'POST',
|
||||
path: '',
|
||||
headers: [],
|
||||
queryParams: [],
|
||||
requestBody: ''
|
||||
};
|
||||
|
||||
let view = {
|
||||
init: function () {
|
||||
$('.btn_add_header').click(function () {
|
||||
controller.addHeader();
|
||||
});
|
||||
$('.btn_add_query').click(function () {
|
||||
controller.addQueryParam('','');
|
||||
});
|
||||
|
||||
$('#requestBody').on('input', function () {
|
||||
model.requestBody = $(this).val();
|
||||
})
|
||||
model.server = $('#server').val();
|
||||
model.method = $('#method').val();
|
||||
|
||||
$('#server').on('change', function(){
|
||||
model.server = $(this).val();
|
||||
});
|
||||
|
||||
$('#method').on('change', function(){
|
||||
model.method = $(this).val();
|
||||
});
|
||||
|
||||
$('#path').on('input', function(){
|
||||
model.path = $(this).val();
|
||||
//parse querystring from path and set to model.queryParams
|
||||
model.queryParams = [];
|
||||
let queryString = model.path.split('?')[1];
|
||||
if(queryString){
|
||||
let queryParamArray = queryString.split('&');
|
||||
for(let i = 0; i < queryParamArray.length; i++){
|
||||
let queryParam = queryParamArray[i].split('=');
|
||||
controller.addQueryParam(queryParam[0], queryParam[1]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('#headers').on('click', 'button', function () {
|
||||
if ($(this).hasClass('btn_remove')) {
|
||||
controller.removeHeader($(this).attr("data-id"));
|
||||
}
|
||||
});
|
||||
|
||||
$('#queryParams').on('click', 'button', function () {
|
||||
if ($(this).hasClass('btn_remove')) {
|
||||
controller.removeQueryParam($(this).attr("data-id"));
|
||||
}
|
||||
});
|
||||
|
||||
$('#send').click(function () {
|
||||
controller.send();
|
||||
});
|
||||
|
||||
this.render();
|
||||
},
|
||||
render: function () {
|
||||
$('#headers').empty();
|
||||
$('#queryParams').empty();
|
||||
|
||||
$('#path').val(model.path);
|
||||
|
||||
for (let i = 0; i < model.headers.length; i++) {
|
||||
let template = $('#inputTemplate').children().find('tr').clone();
|
||||
template.find('input[name="key"]').val(model.headers[i].key);
|
||||
template.find('input[name="value"]').val(model.headers[i].value);
|
||||
template.find('button').attr("data-id", i);
|
||||
|
||||
template.find('input[name="key"]').on('input', function () {
|
||||
model.headers[i].key = $(this).val();
|
||||
});
|
||||
template.find('input[name="value"]').on('input', function () {
|
||||
model.headers[i].value = $(this).val();
|
||||
});
|
||||
|
||||
$('#headers').append(template);
|
||||
}
|
||||
|
||||
for (let i = 0; i < model.queryParams.length; i++) {
|
||||
let template = $('#inputTemplate').children().find('tr').clone();
|
||||
template.find('input[name="key"]').val(model.queryParams[i].key);
|
||||
template.find('input[name="value"]').val(model.queryParams[i].value);
|
||||
template.find('button').attr("data-id", i);
|
||||
|
||||
template.find('input[name="key"]').on('input', function () {
|
||||
model.queryParams[i].key = $(this).val();
|
||||
controller.buildPath();
|
||||
});
|
||||
template.find('input[name="value"]').on('input', function () {
|
||||
model.queryParams[i].value = $(this).val();
|
||||
controller.buildPath();
|
||||
});
|
||||
|
||||
$('#queryParams').append(template);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
let controller = {
|
||||
init: function () {
|
||||
view.init();
|
||||
},
|
||||
addHeader: function () {
|
||||
model.headers.push({
|
||||
key: '',
|
||||
value: ''
|
||||
});
|
||||
console.log(model.headers);
|
||||
view.render();
|
||||
},
|
||||
removeHeader: function (idx) {
|
||||
model.headers.splice(idx, 1);
|
||||
view.render();
|
||||
},
|
||||
addQueryParam: function (key, value) {
|
||||
model.queryParams.push({
|
||||
key: key,
|
||||
value: value
|
||||
});
|
||||
view.render();
|
||||
},
|
||||
buildPath : function(){
|
||||
let queryString = model.path.split('?')[0];
|
||||
if (model.queryParams.length>0){
|
||||
queryString += '?';
|
||||
}
|
||||
for(let i = 0; i < model.queryParams.length; i++){
|
||||
queryString += model.queryParams[i].key + '=' + model.queryParams[i].value;
|
||||
if(i < model.queryParams.length - 1){
|
||||
queryString += '&';
|
||||
}
|
||||
}
|
||||
model.path = queryString;
|
||||
view.render();
|
||||
},
|
||||
removeQueryParam: function (idx) {
|
||||
model.queryParams.splice(idx, 1);
|
||||
this.buildPath();
|
||||
view.render();
|
||||
},
|
||||
send: function () {
|
||||
$('#responseHeaders').empty();
|
||||
$('#responseBody').val('');
|
||||
console.log(model);
|
||||
// $.ajax({
|
||||
// url: '/api/test',
|
||||
// type: 'POST',
|
||||
// contentType: 'application/json',
|
||||
// data: JSON.stringify(model),
|
||||
// success: function (data) {
|
||||
// console.log(data);
|
||||
// $('#responseBody').val(JSON.stringify(data, null, 4));
|
||||
// for (let key in data.headers) {
|
||||
// let template = $('#responseHeaderTemplate').children().find('tr').clone();
|
||||
// template.find('input[name="key"]').val(key);
|
||||
// template.find('input[name="value"]').val(data.headers[key]);
|
||||
// $('#responseHeaders').append(template);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
}
|
||||
}
|
||||
|
||||
controller.init();
|
||||
|
||||
CodeMirror.fromTextArea(document.getElementById('requestBody'), {
|
||||
lineNumbers: true,
|
||||
mode: "application/json",
|
||||
extraKeys: {
|
||||
"Ctrl-Enter": function (cm) {
|
||||
cm.setOption("fullScreen", !cm.getOption("fullScreen"));
|
||||
},
|
||||
"Esc": function (cm) {
|
||||
if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
CodeMirror.fromTextArea(document.getElementById('responseBody'), {
|
||||
lineNumbers: true,
|
||||
mode: "application/json",
|
||||
extraKeys: {
|
||||
"Ctrl-Enter": function (cm) {
|
||||
cm.setOption("fullScreen", !cm.getOption("fullScreen"));
|
||||
},
|
||||
"Esc": function (cm) {
|
||||
if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</th:block>
|
||||
</html>
|
||||
|
||||
@@ -1,149 +0,0 @@
|
||||
<!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"
|
||||
layout:decorator="layout/default_layout">
|
||||
|
||||
<th:block layout:fragment="css">
|
||||
<link rel="stylesheet"
|
||||
th:href="@{/plugins/datatables-bs4/css/dataTables.bootstrap4.min.css}">
|
||||
<link rel="stylesheet"
|
||||
th:href="@{/plugins/datatables-responsive/css/responsive.bootstrap4.min.css}">
|
||||
<link rel="stylesheet"
|
||||
th:href="@{/plugins/datatables-buttons/css/buttons.bootstrap4.min.css}">
|
||||
</th:block>
|
||||
|
||||
<div class="content-wrapper" layout:fragment="content">
|
||||
<!-- Content Header (Page header) -->
|
||||
<section class="content-header">
|
||||
<div class="container-fluid">
|
||||
<div class="row mb-2">
|
||||
<div class="col-sm-6">
|
||||
<h1>API 서비스키 관리</h1>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<ol class="breadcrumb float-sm-right">
|
||||
<li class="breadcrumb-item"><a href="/">Home</a></li>
|
||||
<li class="breadcrumb-item active">API 관리</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
</section>
|
||||
|
||||
<!-- Main content -->
|
||||
<section class="content">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">전달받은 메세지에서 서비스키를 확보 해야할 경우 추출룰을 관리합니다.</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table id="listApiKeyTable"
|
||||
class="table table-bordered table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>URL</th>
|
||||
<th>서비스키타입</th>
|
||||
<th>서비스키</th>
|
||||
<th>수정</th>
|
||||
<th>삭제</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
<!-- /.card-body -->
|
||||
</div>
|
||||
<!-- /.card -->
|
||||
</div>
|
||||
<!-- /.col -->
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<th:block layout:fragment="script">
|
||||
<script th:src="@{/plugins/datatables/jquery.dataTables.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-bs4/js/dataTables.bootstrap4.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-responsive/js/dataTables.responsive.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-responsive/js/responsive.bootstrap4.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-buttons/js/dataTables.buttons.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-buttons/js/buttons.bootstrap4.min.js}"></script>
|
||||
<script th:src="@{/plugins/jszip/jszip.min.js}"></script>
|
||||
<script th:src="@{/plugins/pdfmake/pdfmake.min.js}"></script>
|
||||
<script th:src="@{/plugins/pdfmake/vfs_fonts.js}"></script>
|
||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.html5.min.js}"></script>
|
||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.print.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-buttons/js/buttons.colVis.min.js}"></script>
|
||||
|
||||
<script th:inline="javascript">
|
||||
$.fn.dataTable.ext.buttons.new = {
|
||||
text: 'New',
|
||||
action: function ( e, dt, node, config ) {
|
||||
location.href = "/manage/getApiKeyForm";
|
||||
}
|
||||
};
|
||||
|
||||
var listApiKeyTable = $('#listApiKeyTable').DataTable({
|
||||
"responsive": true, "lengthChange": false, "autoWidth": false,
|
||||
"processing": true,
|
||||
"serverSide": true,
|
||||
"stateSave": true,
|
||||
"pageLength": 50,
|
||||
"searchDelay": 1200,
|
||||
"ajax": {
|
||||
"url": "/manage/rest/apiKeys",
|
||||
"type": "POST",
|
||||
"dataType": "json",
|
||||
"contentType": "application/json",
|
||||
"data": function (d) {
|
||||
return JSON.stringify(d);
|
||||
}
|
||||
},
|
||||
"columns": [
|
||||
{"data": "url"},
|
||||
{"data": "serviceType"},
|
||||
{"data": "serviceKey"},
|
||||
{"data": "id", "searchable": false, "orderable": false},
|
||||
{"data": "id", "searchable": false, "orderable": false}
|
||||
],
|
||||
"columnDefs": [
|
||||
{
|
||||
"render": function (data, type, row) {
|
||||
return '<a href="/manage/getApiKeyForm/' + row.id + '">' + data + '</a>';
|
||||
},
|
||||
"targets": 0
|
||||
},
|
||||
{
|
||||
"render": function (data, type, row) {
|
||||
return '<a href="/manage/getApiKeyForm/' + data + '" class="btn btn-primary"><i class="fas fa-edit"></i></a>';
|
||||
},
|
||||
"targets": -2
|
||||
},
|
||||
{
|
||||
"render": function (data, type, row) {
|
||||
var msg = "'정말로 데이터를 삭제 하시겠습니까?'";
|
||||
return '<a href="/manage/deleteApiKey/' + data + '" onclick="return confirm(' + msg +');" class="btn btn-primary"><i class="fas fa-trash"></i></a>';
|
||||
},
|
||||
"targets": -1
|
||||
}
|
||||
],
|
||||
"buttons": ["new", "excel"],
|
||||
"initComplete": function() {
|
||||
listApiKeyTable.buttons().container().appendTo('#listApiKeyTable_wrapper .col-md-6:eq(0)');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</th:block>
|
||||
</html>
|
||||
@@ -1,191 +0,0 @@
|
||||
<!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"
|
||||
layout:decorator="layout/default_layout">
|
||||
|
||||
<th:block layout:fragment="css">
|
||||
<link rel="stylesheet"
|
||||
th:href="@{/plugins/datatables-bs4/css/dataTables.bootstrap4.min.css}">
|
||||
<link rel="stylesheet"
|
||||
th:href="@{/plugins/datatables-responsive/css/responsive.bootstrap4.min.css}">
|
||||
<link rel="stylesheet"
|
||||
th:href="@{/plugins/datatables-buttons/css/buttons.bootstrap4.min.css}">
|
||||
|
||||
<style type="text/css" class="init">
|
||||
.search-ext {
|
||||
float:right;
|
||||
}
|
||||
</style>
|
||||
</th:block>
|
||||
|
||||
<div class="content-wrapper" layout:fragment="content">
|
||||
<!-- Content Header (Page header) -->
|
||||
<section class="content-header">
|
||||
<div class="container-fluid">
|
||||
<div class="row mb-2">
|
||||
<div class="col-sm-6">
|
||||
<h1>API 관리</h1>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<ol class="breadcrumb float-sm-right">
|
||||
<li class="breadcrumb-item"><a href="/">Home</a></li>
|
||||
<li class="breadcrumb-item active">API 관리</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
</section>
|
||||
|
||||
<!-- Main content -->
|
||||
<section class="content">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">하나의 URL로 여러개의 API를 사용할 경우 [서비스코드]가 필요하고, [API 서비스키 관리]에서 키추출 정보를 추가로 등록 해야함.</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table id="listApiTable"
|
||||
class="table table-bordered table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>API그룹</th>
|
||||
<th>API명</th>
|
||||
<th>URL</th>
|
||||
<th>서비스코드</th>
|
||||
<th>Method</th>
|
||||
<th>수정</th>
|
||||
<th>삭제</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
<!-- /.card-body -->
|
||||
</div>
|
||||
<!-- /.card -->
|
||||
</div>
|
||||
<!-- /.col -->
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
|
||||
<div id="api_search" style="display:none">
|
||||
<label>
|
||||
API그룹:
|
||||
<select id="searchApiGroupName" style="margin-left: 0.5em; height: calc(1.8125rem + 2px); border: 1px solid #ced4da; border-radius: 0.2rem;">
|
||||
<option value="">-- 선택 --</option>
|
||||
<option th:each="apiGroupName : ${apiGroupNameList}" th:value="${apiGroupName}" th:text="${apiGroupName}"></option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<th:block layout:fragment="script">
|
||||
<script th:src="@{/plugins/datatables/jquery.dataTables.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-bs4/js/dataTables.bootstrap4.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-responsive/js/dataTables.responsive.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-responsive/js/responsive.bootstrap4.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-buttons/js/dataTables.buttons.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-buttons/js/buttons.bootstrap4.min.js}"></script>
|
||||
<script th:src="@{/plugins/jszip/jszip.min.js}"></script>
|
||||
<script th:src="@{/plugins/pdfmake/pdfmake.min.js}"></script>
|
||||
<script th:src="@{/plugins/pdfmake/vfs_fonts.js}"></script>
|
||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.html5.min.js}"></script>
|
||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.print.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-buttons/js/buttons.colVis.min.js}"></script>
|
||||
|
||||
<script th:inline="javascript">
|
||||
$.fn.dataTable.ext.buttons.new = {
|
||||
text: 'New',
|
||||
action: function ( e, dt, node, config ) {
|
||||
location.href = "/manage/getApiForm";
|
||||
}
|
||||
};
|
||||
|
||||
var listApiTable = $("#listApiTable").DataTable({
|
||||
"responsive": true, "lengthChange": false, "autoWidth": false,
|
||||
"processing": true,
|
||||
"serverSide": true,
|
||||
"stateSave": true,
|
||||
"pageLength": 50,
|
||||
"searchDelay": 1200,
|
||||
"dom": '<"row"<"col-sm-12 col-md-6"B><"col-sm-12 col-md-6"<"search-ext">f>>rt<"row"<"col-sm-12 col-md-6"i><"col-sm-12 col-md-6"p>>',
|
||||
"ajax": {
|
||||
"url": "/manage/rest/apis",
|
||||
"type": "POST",
|
||||
"dataType": "json",
|
||||
"contentType": "application/json",
|
||||
"data": function (d) {
|
||||
return JSON.stringify(d);
|
||||
}
|
||||
},
|
||||
"columns": [
|
||||
{"data": "apiGroupName"},
|
||||
{"data": "apiName"},
|
||||
{"data": "url"},
|
||||
{"data": "serviceValue"},
|
||||
{"data": "method", "searchable": false, "orderable": false},
|
||||
{"data": "id", "searchable": false, "orderable": false},
|
||||
{"data": "id", "searchable": false, "orderable": false}
|
||||
],
|
||||
"columnDefs": [
|
||||
{
|
||||
"render": function (data, type, row) {
|
||||
return '<a href="/manage/getApiForm/' + row.id + '">' + data + '</a>';
|
||||
},
|
||||
"targets": 1
|
||||
},
|
||||
{
|
||||
"render": function (data, type, row) {
|
||||
return '<a href="/manage/getApiForm/' + data + '" class="btn btn-primary"><i class="fas fa-edit"></i></a>';
|
||||
},
|
||||
"targets": -2
|
||||
},
|
||||
{
|
||||
"render": function (data, type, row) {
|
||||
var msg = "'정말로 데이터를 삭제 하시겠습니까?'";
|
||||
return '<a href="/manage/deleteApi/' + data + '" onclick="return confirm(' + msg +');" class="btn btn-primary"><i class="fas fa-trash"></i></a>';
|
||||
},
|
||||
"targets": -1
|
||||
}
|
||||
],
|
||||
"buttons": ["new", "excel", "colvis"],
|
||||
"initComplete": function() {
|
||||
//listApiTable.buttons().container().appendTo('#listApiTable_wrapper .col-md-6:eq(0)');
|
||||
}
|
||||
});
|
||||
|
||||
$('.search-ext').html($('#api_search').html());
|
||||
|
||||
$("#searchApiGroupName").change(function(){
|
||||
listApiTable.columns(0).search(this.value).draw(); // apiGroupName
|
||||
});
|
||||
|
||||
/*
|
||||
$(".dataTables_filter input").unbind().bind("input", function(e) { // Bind our desired behavior
|
||||
// If the length is 3 or more characters, or the user pressed ENTER, search
|
||||
if(this.value.length >= 3 || e.keyCode == 13) {
|
||||
// Call the API search function
|
||||
listApiTable.search(this.value).draw();
|
||||
}
|
||||
// Ensure we clear the search if they backspace far enough
|
||||
if(this.value == "") {
|
||||
listApiTable.search("").draw();
|
||||
}
|
||||
return;
|
||||
});
|
||||
*/
|
||||
</script>
|
||||
</th:block>
|
||||
</html>
|
||||
@@ -1,168 +0,0 @@
|
||||
<!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"
|
||||
layout:decorator="layout/default_layout">
|
||||
|
||||
<th:block layout:fragment="css">
|
||||
<link rel="stylesheet"
|
||||
th:href="@{/plugins/datatables-bs4/css/dataTables.bootstrap4.min.css}">
|
||||
<link rel="stylesheet"
|
||||
th:href="@{/plugins/datatables-responsive/css/responsive.bootstrap4.min.css}">
|
||||
<link rel="stylesheet"
|
||||
th:href="@{/plugins/datatables-buttons/css/buttons.bootstrap4.min.css}">
|
||||
</th:block>
|
||||
|
||||
<div class="content-wrapper" layout:fragment="content">
|
||||
<!-- Content Header (Page header) -->
|
||||
<section class="content-header">
|
||||
<div class="container-fluid">
|
||||
<div class="row mb-2">
|
||||
<div class="col-sm-6">
|
||||
<h1>Bytes Message 관리</h1>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<ol class="breadcrumb float-sm-right">
|
||||
<li class="breadcrumb-item"><a href="/">Home</a></li>
|
||||
<li class="breadcrumb-item active">Echo Socket</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
</section>
|
||||
|
||||
<!-- Main content -->
|
||||
<section class="content">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">목록중 하나의 메세지만 사용할 수 있습니다.</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table id="listBytesMessageSpecTable"
|
||||
class="table table-bordered table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>메시지명</th>
|
||||
<th>LL길이</th>
|
||||
<th>LL길이포함</th>
|
||||
<th>Port</th>
|
||||
<th>사용여부</th>
|
||||
<th>수정</th>
|
||||
<th>삭제</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
<!-- /.card-body -->
|
||||
</div>
|
||||
<!-- /.card -->
|
||||
</div>
|
||||
<!-- /.col -->
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<th:block layout:fragment="script">
|
||||
<script th:src="@{/plugins/datatables/jquery.dataTables.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-bs4/js/dataTables.bootstrap4.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-responsive/js/dataTables.responsive.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-responsive/js/responsive.bootstrap4.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-buttons/js/dataTables.buttons.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-buttons/js/buttons.bootstrap4.min.js}"></script>
|
||||
<script th:src="@{/plugins/jszip/jszip.min.js}"></script>
|
||||
<script th:src="@{/plugins/pdfmake/pdfmake.min.js}"></script>
|
||||
<script th:src="@{/plugins/pdfmake/vfs_fonts.js}"></script>
|
||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.html5.min.js}"></script>
|
||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.print.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-buttons/js/buttons.colVis.min.js}"></script>
|
||||
|
||||
<script th:inline="javascript">
|
||||
$.fn.dataTable.ext.buttons.new = {
|
||||
text: 'New',
|
||||
action: function ( e, dt, node, config ) {
|
||||
location.href = "/manage/getBytesMessageSpecForm";
|
||||
}
|
||||
};
|
||||
|
||||
var listBytesMessageSpecTable = $("#listBytesMessageSpecTable").DataTable({
|
||||
"responsive": true, "lengthChange": false, "autoWidth": false,
|
||||
"processing": true,
|
||||
"serverSide": true,
|
||||
"stateSave": true,
|
||||
"pageLength": 50,
|
||||
"searchDelay": 1200,
|
||||
"ajax": {
|
||||
"url": "/manage/rest/bytesMessageSpecs",
|
||||
"type": "POST",
|
||||
"dataType": "json",
|
||||
"contentType": "application/json",
|
||||
"data": function (d) {
|
||||
return JSON.stringify(d);
|
||||
}
|
||||
},
|
||||
"columns": [
|
||||
{"data": "specName"},
|
||||
{"data": "llFieldLength", "searchable": false, "orderable": false},
|
||||
{"data": "llFieldLengthInclude", "searchable": false, "orderable": false},
|
||||
{"data": "port", "searchable": false, "orderable": false},
|
||||
{"data": "useYn", "searchable": false},
|
||||
{"data": "id", "searchable": false, "orderable": false},
|
||||
{"data": "id", "searchable": false, "orderable": false}
|
||||
],
|
||||
"columnDefs": [
|
||||
{
|
||||
"render": function (data, type, row) {
|
||||
return '<a href="/manage/getBytesMessageSpecForm/' + row.id + '">' + data + '</a>';
|
||||
},
|
||||
"targets": 0
|
||||
},
|
||||
{
|
||||
"render": function (data, type, row) {
|
||||
return '<a href="/manage/getBytesMessageSpecForm/' + data + '" class="btn btn-primary"><i class="fas fa-edit"></i></a>';
|
||||
},
|
||||
"targets": -2
|
||||
},
|
||||
{
|
||||
"render": function (data, type, row) {
|
||||
var msg = "'정말로 데이터를 삭제 하시겠습니까?'";
|
||||
return '<a href="/manage/deleteBytesMessageSpec/' + data + '" onclick="return confirm(' + msg +');" class="btn btn-primary"><i class="fas fa-trash"></i></a>';
|
||||
},
|
||||
"targets": -1
|
||||
}
|
||||
],
|
||||
"buttons": ["new", "excel", "colvis"],
|
||||
"initComplete": function() {
|
||||
listBytesMessageSpecTable.buttons().container().appendTo('#listBytesMessageSpecTable_wrapper .col-md-6:eq(0)');
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
$(".dataTables_filter input").unbind().bind("input", function(e) { // Bind our desired behavior
|
||||
// If the length is 3 or more characters, or the user pressed ENTER, search
|
||||
if(this.value.length >= 3 || e.keyCode == 13) {
|
||||
// Call the API search function
|
||||
listBytesMessageSpecTable.search(this.value).draw();
|
||||
}
|
||||
// Ensure we clear the search if they backspace far enough
|
||||
if(this.value == "") {
|
||||
listBytesMessageSpecTable.search("").draw();
|
||||
}
|
||||
return;
|
||||
});
|
||||
*/
|
||||
</script>
|
||||
</th:block>
|
||||
</html>
|
||||
@@ -1,166 +0,0 @@
|
||||
<!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"
|
||||
layout:decorator="layout/default_layout">
|
||||
|
||||
<th:block layout:fragment="css">
|
||||
<link rel="stylesheet"
|
||||
th:href="@{/plugins/datatables-bs4/css/dataTables.bootstrap4.min.css}">
|
||||
<link rel="stylesheet"
|
||||
th:href="@{/plugins/datatables-responsive/css/responsive.bootstrap4.min.css}">
|
||||
<link rel="stylesheet"
|
||||
th:href="@{/plugins/datatables-buttons/css/buttons.bootstrap4.min.css}">
|
||||
</th:block>
|
||||
|
||||
<div class="content-wrapper" layout:fragment="content">
|
||||
<!-- Content Header (Page header) -->
|
||||
<section class="content-header">
|
||||
<div class="container-fluid">
|
||||
<div class="row mb-2">
|
||||
<div class="col-sm-6">
|
||||
<h1>HTTP 요청 관리</h1>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<ol class="breadcrumb float-sm-right">
|
||||
<li class="breadcrumb-item"><a href="/">Home</a></li>
|
||||
<li class="breadcrumb-item active">부가 기능</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
</section>
|
||||
|
||||
<!-- Main content -->
|
||||
<section class="content">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">HTTP API 호출 테스트를 수행할 수 있다.</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table id="listHttpRequestInfoTable"
|
||||
class="table table-bordered table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>요청그룹</th>
|
||||
<th>요청명</th>
|
||||
<th>URL</th>
|
||||
<th>Method</th>
|
||||
<th>수정</th>
|
||||
<th>삭제</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
<!-- /.card-body -->
|
||||
</div>
|
||||
<!-- /.card -->
|
||||
</div>
|
||||
<!-- /.col -->
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<th:block layout:fragment="script">
|
||||
<script th:src="@{/plugins/datatables/jquery.dataTables.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-bs4/js/dataTables.bootstrap4.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-responsive/js/dataTables.responsive.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-responsive/js/responsive.bootstrap4.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-buttons/js/dataTables.buttons.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-buttons/js/buttons.bootstrap4.min.js}"></script>
|
||||
<script th:src="@{/plugins/jszip/jszip.min.js}"></script>
|
||||
<script th:src="@{/plugins/pdfmake/pdfmake.min.js}"></script>
|
||||
<script th:src="@{/plugins/pdfmake/vfs_fonts.js}"></script>
|
||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.html5.min.js}"></script>
|
||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.print.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-buttons/js/buttons.colVis.min.js}"></script>
|
||||
|
||||
<script th:inline="javascript">
|
||||
$.fn.dataTable.ext.buttons.new = {
|
||||
text: 'New',
|
||||
action: function ( e, dt, node, config ) {
|
||||
location.href = "/manage/getHttpRequestInfoForm";
|
||||
}
|
||||
};
|
||||
|
||||
var listHttpRequestInfoTable = $("#listHttpRequestInfoTable").DataTable({
|
||||
"responsive": true, "lengthChange": false, "autoWidth": false,
|
||||
"processing": true,
|
||||
"serverSide": true,
|
||||
"stateSave": true,
|
||||
"pageLength": 50,
|
||||
"searchDelay": 1200,
|
||||
"ajax": {
|
||||
"url": "/manage/rest/httpRequestInfos",
|
||||
"type": "POST",
|
||||
"dataType": "json",
|
||||
"contentType": "application/json",
|
||||
"data": function (d) {
|
||||
return JSON.stringify(d);
|
||||
}
|
||||
},
|
||||
"columns": [
|
||||
{"data": "requestGroupName"},
|
||||
{"data": "requestName"},
|
||||
{"data": "url"},
|
||||
{"data": "method", "searchable": false, "orderable": false},
|
||||
{"data": "id", "searchable": false, "orderable": false},
|
||||
{"data": "id", "searchable": false, "orderable": false}
|
||||
],
|
||||
"columnDefs": [
|
||||
{
|
||||
"render": function (data, type, row) {
|
||||
return '<a href="/manage/getHttpRequestInfoForm/' + row.id + '">' + data + '</a>';
|
||||
},
|
||||
"targets": 1
|
||||
},
|
||||
{
|
||||
"render": function (data, type, row) {
|
||||
return '<a href="/manage/getHttpRequestInfoForm/' + data + '" class="btn btn-primary"><i class="fas fa-edit"></i></a>';
|
||||
},
|
||||
"targets": -2
|
||||
},
|
||||
{
|
||||
"render": function (data, type, row) {
|
||||
var msg = "'정말로 데이터를 삭제 하시겠습니까?'";
|
||||
return '<a href="/manage/deleteHttpRequestInfo/' + data + '" onclick="return confirm(' + msg +');" class="btn btn-primary"><i class="fas fa-trash"></i></a>';
|
||||
},
|
||||
"targets": -1
|
||||
}
|
||||
],
|
||||
"buttons": ["new", "excel", "colvis"],
|
||||
"initComplete": function() {
|
||||
listHttpRequestInfoTable.buttons().container().appendTo('#listHttpRequestInfoTable_wrapper .col-md-6:eq(0)');
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
$(".dataTables_filter input").unbind().bind("input", function(e) { // Bind our desired behavior
|
||||
// If the length is 3 or more characters, or the user pressed ENTER, search
|
||||
if(this.value.length >= 3 || e.keyCode == 13) {
|
||||
// Call the API search function
|
||||
listHttpRequestInfoTable.search(this.value).draw();
|
||||
}
|
||||
// Ensure we clear the search if they backspace far enough
|
||||
if(this.value == "") {
|
||||
listHttpRequestInfoTable.search("").draw();
|
||||
}
|
||||
return;
|
||||
});
|
||||
*/
|
||||
</script>
|
||||
</th:block>
|
||||
</html>
|
||||
@@ -1,162 +0,0 @@
|
||||
<!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"
|
||||
layout:decorator="layout/default_layout">
|
||||
|
||||
<th:block layout:fragment="css">
|
||||
<link rel="stylesheet"
|
||||
th:href="@{/plugins/datatables-bs4/css/dataTables.bootstrap4.min.css}">
|
||||
<link rel="stylesheet"
|
||||
th:href="@{/plugins/datatables-responsive/css/responsive.bootstrap4.min.css}">
|
||||
<link rel="stylesheet"
|
||||
th:href="@{/plugins/datatables-buttons/css/buttons.bootstrap4.min.css}">
|
||||
</th:block>
|
||||
|
||||
<div class="content-wrapper" layout:fragment="content">
|
||||
<!-- Content Header (Page header) -->
|
||||
<section class="content-header">
|
||||
<div class="container-fluid">
|
||||
<div class="row mb-2">
|
||||
<div class="col-sm-6">
|
||||
<h1>스크립트 관리</h1>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<ol class="breadcrumb float-sm-right">
|
||||
<li class="breadcrumb-item"><a href="/">Home</a></li>
|
||||
<li class="breadcrumb-item active">부가 기능</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
</section>
|
||||
|
||||
<!-- Main content -->
|
||||
<section class="content">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">응답 송신 전 수행 할 스크립트, GUID 복제나 특정 예외전문등의 처리 수행 로직을 작성한다(java)</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table id="listApiTable"
|
||||
class="table table-bordered table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>스크립트 명</th>
|
||||
<th>스크립트 설명</th>
|
||||
<th>수정</th>
|
||||
<th>삭제</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
<!-- /.card-body -->
|
||||
</div>
|
||||
<!-- /.card -->
|
||||
</div>
|
||||
<!-- /.col -->
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<th:block layout:fragment="script">
|
||||
<script th:src="@{/plugins/datatables/jquery.dataTables.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-bs4/js/dataTables.bootstrap4.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-responsive/js/dataTables.responsive.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-responsive/js/responsive.bootstrap4.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-buttons/js/dataTables.buttons.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-buttons/js/buttons.bootstrap4.min.js}"></script>
|
||||
<script th:src="@{/plugins/jszip/jszip.min.js}"></script>
|
||||
<script th:src="@{/plugins/pdfmake/pdfmake.min.js}"></script>
|
||||
<script th:src="@{/plugins/pdfmake/vfs_fonts.js}"></script>
|
||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.html5.min.js}"></script>
|
||||
<script th:src="@{/plugins/datatables-buttons/js/buttons.print.min.js}"></script>
|
||||
<script
|
||||
th:src="@{/plugins/datatables-buttons/js/buttons.colVis.min.js}"></script>
|
||||
|
||||
<script th:inline="javascript">
|
||||
$.fn.dataTable.ext.buttons.new = {
|
||||
text: 'New',
|
||||
action: function ( e, dt, node, config ) {
|
||||
location.href = "/manage/getScriptInfoForm";
|
||||
}
|
||||
};
|
||||
|
||||
var listApiTable = $("#listApiTable").DataTable({
|
||||
"responsive": true, "lengthChange": false, "autoWidth": false,
|
||||
"processing": true,
|
||||
"serverSide": true,
|
||||
"stateSave": true,
|
||||
"pageLength": 50,
|
||||
"searchDelay": 1200,
|
||||
"ajax": {
|
||||
"url": "/manage/rest/scriptInfos",
|
||||
"type": "POST",
|
||||
"dataType": "json",
|
||||
"contentType": "application/json",
|
||||
"data": function (d) {
|
||||
return JSON.stringify(d);
|
||||
}
|
||||
},
|
||||
"columns": [
|
||||
{"data": "scriptName"},
|
||||
{"data": "scriptDesc"},
|
||||
{"data": "id", "searchable": false, "orderable": false},
|
||||
{"data": "id", "searchable": false, "orderable": false}
|
||||
],
|
||||
"columnDefs": [
|
||||
{
|
||||
"render": function (data, type, row) {
|
||||
return '<a href="/manage/getScriptInfoForm/' + row.id + '">' + data +'</a>';
|
||||
},
|
||||
"targets": 0
|
||||
},
|
||||
{
|
||||
"render": function (data, type, row) {
|
||||
return '<a href="/manage/getScriptInfoForm/' + data + '" class="btn btn-primary"><i class="fas fa-edit"></i></a>';
|
||||
},
|
||||
"targets": -2
|
||||
},
|
||||
{
|
||||
"render": function (data, type, row) {
|
||||
var msg = "'정말로 데이터를 삭제 하시겠습니까?'";
|
||||
return '<a href="/manage/deleteScriptInfo/' + data + '" onclick="return confirm(' + msg +');" class="btn btn-primary"><i class="fas fa-trash"></i></a>';
|
||||
},
|
||||
"targets": -1
|
||||
}
|
||||
],
|
||||
"buttons": ["new", "excel", "colvis"],
|
||||
"initComplete": function() {
|
||||
listApiTable.buttons().container().appendTo('#listApiTable_wrapper .col-md-6:eq(0)');
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
$(".dataTables_filter input").unbind().bind("input", function(e) { // Bind our desired behavior
|
||||
// If the length is 3 or more characters, or the user pressed ENTER, search
|
||||
if(this.value.length >= 3 || e.keyCode == 13) {
|
||||
// Call the API search function
|
||||
listApiTable.search(this.value).draw();
|
||||
}
|
||||
// Ensure we clear the search if they backspace far enough
|
||||
if(this.value == "") {
|
||||
listApiTable.search("").draw();
|
||||
}
|
||||
return;
|
||||
});
|
||||
*/
|
||||
</script>
|
||||
</th:block>
|
||||
</html>
|
||||
@@ -0,0 +1,144 @@
|
||||
<!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" layout:decorate="~{/layout/base_layout}">
|
||||
|
||||
|
||||
<body>
|
||||
|
||||
<section layout:fragment="contentFragment">
|
||||
<style>
|
||||
.form-signin {
|
||||
width: 100%;
|
||||
max-width: 330px;
|
||||
padding: 15px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.form-signin .checkbox {
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.form-signin .form-floating:focus-within {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.form-signin input[type="email"] {
|
||||
margin-bottom: -1px;
|
||||
border-bottom-right-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
.form-signin input[type="password"] {
|
||||
margin-bottom: 10px;
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
</style>
|
||||
<!-- javascript warning tag -->
|
||||
|
||||
<div class="container">
|
||||
<div class="mt-2">
|
||||
<h1 class="text-center">로그인</h1>
|
||||
</div>
|
||||
<main class="form-signin mt-2">
|
||||
<form role="form" name="loginForm" id="loginForm" th:action="@{/actionLogin.do}" method="post">
|
||||
<input type="hidden" id="message" name="message" th:value="${loginMessage}">
|
||||
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
|
||||
|
||||
<div class="form-floating">
|
||||
<input type="email" class="form-control" name="id" id="id" maxlength="20" required>
|
||||
<label for="id" class="form-label">이메일</label>
|
||||
</div>
|
||||
<div class="form-floating">
|
||||
<input type="password" class="form-control mb-3" name="password" id="password" minlength="8" maxlength="20" required>
|
||||
<label for="password" class="form-label">비밀번호</label>
|
||||
</div>
|
||||
<div class="checkbox mb-3">
|
||||
<input type="checkbox" class="form-check-input" name="checkId" id="checkId">
|
||||
<label class="form-check-label" for="checkId">아이디 저장</label>
|
||||
</div>
|
||||
<button class="w-100 btn btn-lg btn-primary" type="button" id="actionLogin" th:text="#{loginForm.login}">Sign in</button>
|
||||
</form>
|
||||
<div class="mt-2 text-center">
|
||||
<span class="text-muted"><a href="/forgot_password.do">비밀번호 초기화</a></span>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</section>
|
||||
</body>
|
||||
|
||||
|
||||
<th:block layout:fragment="contentScript">
|
||||
<script>
|
||||
function setCookie(name, value, expires) {
|
||||
let cookie = `${name}=${encodeURIComponent(value)}; path=/`;
|
||||
|
||||
if (expires instanceof Date) {
|
||||
cookie += `; expires=${expires.toUTCString()}`;
|
||||
}
|
||||
document.cookie = cookie;
|
||||
}
|
||||
|
||||
function getCookie(name) {
|
||||
let decodedCookie = decodeURIComponent(document.cookie);
|
||||
let ca = decodedCookie.split(';');
|
||||
for (let i = 0; i < ca.length; i++) {
|
||||
let c = ca[i];
|
||||
while (c.charAt(0) === ' ') {
|
||||
c = c.substring(1);
|
||||
}
|
||||
if (c.indexOf(name) === 0) {
|
||||
return c.substring(name.length + 1, c.length);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function getId(form) {
|
||||
form.checkId.checked = ((form.id.value = getCookie("saveid")) !== null);
|
||||
}
|
||||
|
||||
function fnInit() {
|
||||
getId(document.loginForm);
|
||||
|
||||
if (document.loginForm.message !== null && document.loginForm.message.value !== "") {
|
||||
alert(document.loginForm.message.value);
|
||||
}
|
||||
}
|
||||
|
||||
$(function () {
|
||||
fnInit();
|
||||
let actionLogin = function (event) {
|
||||
let form = document.loginForm;
|
||||
if ($('#checkId').is(':checked')) {
|
||||
setCookie("saveid", $('#id').val(), new Date(new Date().getTime() + 1000 * 3600 * 24 * 30));
|
||||
} else {
|
||||
setCookie("saveid", $('#id').val(), new Date(new Date().getTime() - 1));
|
||||
}
|
||||
|
||||
if (!form.checkValidity()) {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
} else {
|
||||
if (form.password.value.length < 8) {
|
||||
alert("[[#{validate.passLengthShort}]]");
|
||||
} else {
|
||||
form.submit();
|
||||
}
|
||||
}
|
||||
form.classList.add('was-validated');
|
||||
};
|
||||
|
||||
$('#actionLogin').on('click', actionLogin);
|
||||
$('#password').on("keydown", function (event) {
|
||||
if (event.key === "Enter" || event.keyCode === 13 || event.code === 'Enter') {
|
||||
event.preventDefault();
|
||||
actionLogin(event);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
</th:block>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,538 @@
|
||||
<!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" layout:decorate="~{/layout/default_layout}">
|
||||
<body>
|
||||
|
||||
<section layout:fragment="contentFragment">
|
||||
<div class="container mt-1">
|
||||
<form name="mockRouteForm" id="mockRouteForm"
|
||||
th:action="${mockRoute.id == null}?@{/mgmt/routes/register.do}:@{/mgmt/routes/update.do}"
|
||||
th:object='${mockRoute}' method="post">
|
||||
<div class="card col-md">
|
||||
<div class="card-header">
|
||||
<h3 th:if="${mockRoute.id == null}">API 정보 등록</h3>
|
||||
<h3 th:if="${mockRoute.id != null}">API 정보 수정</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}">
|
||||
<input type="hidden" name="id" th:value="${mockRoute.id}">
|
||||
<div class="form-floating mt-2">
|
||||
<input type="text" class="form-control"
|
||||
th:classappend="${#fields.hasErrors('name')}? 'is-invalid'" th:field="*{name}"
|
||||
name="username" id="name" required/>
|
||||
<label for="name" class="form-label must" th:text="#{name}">이름</label>
|
||||
<th:block th:each="err : ${#fields.errors('name')}">
|
||||
<div th:text="${err}" class="invalid-feedback"></div>
|
||||
</th:block>
|
||||
</div>
|
||||
<div class="d-flex align-items-center mt-2">
|
||||
<div class="form-floating col-md-1 me-2">
|
||||
<select name="method" class="form-select"
|
||||
th:classappend="${#fields.hasErrors('method')}? 'is-invalid'" id="method">
|
||||
<option th:selected="${mockRoute.method == 'POST'}" value="POST">POST</option>
|
||||
<option th:selected="${mockRoute.method == 'GET'}" value="GET">GET</option>
|
||||
<option th:selected="${mockRoute.method == 'PUT'}" value="PUT">PUT</option>
|
||||
<option th:selected="${mockRoute.method == 'DELETE'}" value="DELETE">DELETE</option>
|
||||
<option th:selected="${mockRoute.method == 'CONNECT'}" value="CONNECT">CONNECT</option>
|
||||
<option th:selected="${mockRoute.method == 'HEAD'}" value="HEAD">HEAD</option>
|
||||
<option th:selected="${mockRoute.method == 'OPTIONS'}" value="OPTIONS">OPTIONS</option>
|
||||
<option th:selected="${mockRoute.method == 'TRACE'}" value="TRACE">TRACE</option>
|
||||
<option th:selected="${mockRoute.method == 'PATCH'}" value="PATCH">PATCH</option>
|
||||
</select>
|
||||
<label for="method" class="form-label must">Method</label>
|
||||
</div>
|
||||
<div class="form-floating col-md">
|
||||
<input type="text" name="pathPattern" class="form-control" id="pathPattern"
|
||||
th:field="*{pathPattern}"
|
||||
placeholder="서버에 노출 되는 경로 (/부터 입력)" required>
|
||||
<label for="pathPattern" class="must">Path</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card mt-2">
|
||||
<div class="card-header">
|
||||
<div class="d-flex justify-content-between">
|
||||
<h3>응답</h3>
|
||||
<button type="button" class="btn btn-sm btn-primary btn_add_case"><i
|
||||
class="fa-sharp fa-solid fa-plus"></i>케이스 추가
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body" id="responses">
|
||||
<div class="card" th:each="response, status: *{responses}">
|
||||
<div class="card-header">
|
||||
<div class="d-flex justify-content-between">
|
||||
<span th:text="'조건 ' + ${status.index + 1}"></span>
|
||||
<button type="button" class="btn btn-secondary btn-sm btn_remove_case"
|
||||
th:data-id="${status.index+1}">제거
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="d-flex justify-content-between">
|
||||
<span>조건 항목</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">종류</th>
|
||||
<th scope="col">키</th>
|
||||
<th scope="col">값</th>
|
||||
<th>
|
||||
<button type="button" class="btn btn-secondary btn-sm">추가
|
||||
</button>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="response_conditions">
|
||||
<tr th:each="condition, status: *{responses[__${status.index}__].conditions}">
|
||||
<td>
|
||||
<select>
|
||||
<option value="query"
|
||||
th:selected="${condition.type == 'query'}">Query
|
||||
</option>
|
||||
<option value="header"
|
||||
th:selected="${condition.type == 'header'}">Header
|
||||
</option>
|
||||
<option value="path"
|
||||
th:selected="${condition.type == 'path'}">Path
|
||||
</option>
|
||||
<option value="jsonpath"
|
||||
th:selected="${condition.type == 'jsonpath'}">JSON
|
||||
Path
|
||||
</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" type="text" name="key"
|
||||
th:value="${condition.key}"/>
|
||||
</td>
|
||||
<td><input class="form-control" type="text" name="value"
|
||||
th:value="${condition.value}"/></td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-secondary btn-sm">제거
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<div class="card">
|
||||
<div class="card-header">응답 내용</div>
|
||||
<div class="card-body">
|
||||
<div class="form-floating mt-2">
|
||||
<input class="form-control" type="number"
|
||||
th:field="*{responses[__${status.index}__].statusCode}"
|
||||
required/>
|
||||
<label class="form-label must">Status</label>
|
||||
</div>
|
||||
<div class="form-floating mt-2">
|
||||
<input class="form-control" type="number"
|
||||
th:field="*{responses[__${status.index}__].delay}" required/>
|
||||
<label class="form-label must">응답 지연 시간(ms)</label>
|
||||
</div>
|
||||
<div class="form-floating mt-2">
|
||||
<textarea class="form-control" style="height: 200px;"
|
||||
th:field="*{responses[__${status.index}__].body}">
|
||||
</textarea>
|
||||
<label class="form-label must">응답 Body</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Header 이름</th>
|
||||
<th>값</th>
|
||||
<th>
|
||||
<button type="button" class="btn btn-secondary btn-sm">추가
|
||||
</button>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="response_headers">
|
||||
<tr th:each="header, status: *{responses[__${status.index}__].headers}">
|
||||
<td>
|
||||
<input class="form-control" type="text" name="key"
|
||||
th:value="${header.key}"/>
|
||||
</td>
|
||||
<td><input class="form-control" type="text" name="value"
|
||||
th:value="${header.value}"/></td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-secondary btn-sm">제거
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<button type="button" class="btn btn-primary btn_list"><i class="fa-solid fa-list"></i> 목록</button>
|
||||
<button type="button" class="btn btn-primary btn_register"><i
|
||||
class="fa-sharp fa-solid fa-floppy-disk"></i> 저장
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div id="template" style="visibility: hidden; height: 0;">
|
||||
<div class="card mt-1">
|
||||
<div class="card-header">
|
||||
<div class="d-flex justify-content-between">
|
||||
<span class="condition_name"></span>
|
||||
<button type="button" class="btn btn-secondary btn-sm btn_remove_case">제거</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="d-flex justify-content-between">
|
||||
<span>조건 항목</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">종류</th>
|
||||
<th scope="col">키</th>
|
||||
<th scope="col">값</th>
|
||||
<th>
|
||||
<button type="button" class="btn btn-secondary btn-sm btn_add_condition">추가</button>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="response_conditions">
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<div class="card">
|
||||
<div class="card-header">응답 내용</div>
|
||||
<div class="card-body">
|
||||
<div class="form-floating mt-1">
|
||||
<input class="form-control" type="number" name="statusCode" required/>
|
||||
<label class="form-label must">Status</label>
|
||||
</div>
|
||||
<div class="form-floating mt-1">
|
||||
<input class="form-control" type="number" name="delay" required/>
|
||||
<label class="form-label must">응답 지연 시간(ms)</label>
|
||||
</div>
|
||||
<div class="form-floating mt-1">
|
||||
<textarea class="form-control" style="height: 200px;" name="body">
|
||||
</textarea>
|
||||
<label class="form-label must">응답 Body</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Header 이름</th>
|
||||
<th>값</th>
|
||||
<th>
|
||||
<button type="button" class="btn btn-secondary btn-sm btn_add_header">추가</button>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="response_headers">
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="conditionTemplate" style="visibility: hidden; height: 0;">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<select class="form-select">
|
||||
<option value="query">Query</option>
|
||||
<option value="header">Header</option>
|
||||
<option value="path">Path</option>
|
||||
<option value="jsonpath">JSON Path</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" type="text" name="key"/>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" type="text" name="value"/>
|
||||
</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-secondary btn-sm btn_remove_condition">제거</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div id="responseHeaderTemplate" style="visibility: hidden; height: 0;">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<input class="form-control" type="text" name="key"/>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" type="text" name="value"/>
|
||||
</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-secondary btn-sm btn_remove_header">제거</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
</body>
|
||||
|
||||
<th:block layout:fragment="contentScript">
|
||||
<script>
|
||||
$(function () {
|
||||
let model = {
|
||||
name: '',
|
||||
method: '',
|
||||
pathPattern: '',
|
||||
responses: [
|
||||
]
|
||||
};
|
||||
|
||||
let view = {
|
||||
init: function () {
|
||||
$('.btn_add_case').on('click', function () {
|
||||
controller.addResponse();
|
||||
});
|
||||
|
||||
$('#responses').on('click', 'button', function () {
|
||||
if ($(this).hasClass('btn_remove_case')) {
|
||||
controller.removeResponse($(this).attr("data-id"));
|
||||
}
|
||||
if ($(this).hasClass('btn_add_condition')) {
|
||||
controller.addResponseCondition($(this).attr("data-id"));
|
||||
}
|
||||
|
||||
if ($(this).hasClass('btn_add_header')) {
|
||||
controller.addResponseHeader($(this).attr("data-id"));
|
||||
}
|
||||
|
||||
if ($(this).hasClass('btn_remove_condition')) {
|
||||
controller.removeResponseCondition($(this).attr("data-id"), $(this).attr("data-row"));
|
||||
}
|
||||
|
||||
if ($(this).hasClass('btn_remove_header')) {
|
||||
controller.removeResponseHeader($(this).attr("data-id"), $(this).attr("data-row"));
|
||||
}
|
||||
});
|
||||
|
||||
$('#responses').children().each(function(){
|
||||
let response = {
|
||||
conditions: [],
|
||||
headers: []
|
||||
};
|
||||
response.statusCode = $(this).find('input[name$="statusCode"]').val();
|
||||
response.delay = $(this).find('input[name$="delay"]').val();
|
||||
response.body = $(this).find('textarea[name$="body"]').val();
|
||||
|
||||
$(this).find('.response_conditions').children().each(function(){
|
||||
let condition = {
|
||||
type: $(this).find('select').val(),
|
||||
key: $(this).find('input[name$="key"]').val(),
|
||||
value: $(this).find('input[name$="value"]').val()
|
||||
};
|
||||
response.conditions.push(condition);
|
||||
});
|
||||
|
||||
model.responses.push(response);
|
||||
|
||||
$(this).find('.response_headers').children().each(function(){
|
||||
let header = {
|
||||
key: $(this).find('input[name$="key"]').val(),
|
||||
value: $(this).find('input[name$="value"]').val()
|
||||
};
|
||||
response.headers.push(header);
|
||||
});
|
||||
|
||||
});
|
||||
this.render();
|
||||
},
|
||||
render: function () {
|
||||
$('#responses').empty();
|
||||
for (let i = 0; i < model.responses.length; i++) {
|
||||
let nodeCopy = $('#template').children().clone();
|
||||
nodeCopy.find('.condition_name').text('조건 ' + (i + 1));
|
||||
nodeCopy.find('.btn_remove_case').attr("data-id", i);
|
||||
nodeCopy.find('.btn_add_condition').attr("data-id", i);
|
||||
nodeCopy.find('.btn_add_header').attr("data-id", i);
|
||||
nodeCopy.find('input[name="statusCode"]').attr('name', 'responses[' + i + '].statusCode');
|
||||
nodeCopy.find('input[name="delay"]').attr('name', 'responses[' + i + '].delay');
|
||||
nodeCopy.find('textarea[name="body"]').attr('name', 'responses[' + i + '].body');
|
||||
|
||||
nodeCopy.find('input[name="responses[' + i + '].statusCode"]').val(model.responses[i].statusCode);
|
||||
nodeCopy.find('input[name="responses[' + i + '].delay"]').val(model.responses[i].delay);
|
||||
nodeCopy.find('textarea[name="responses[' + i + '].body"]').val(model.responses[i].body);
|
||||
|
||||
nodeCopy.find('input[name="responses[' + i + '].statusCode"]').on('input', function() {
|
||||
model.responses[i].statusCode = $(this).val();
|
||||
});
|
||||
|
||||
nodeCopy.find('input[name="responses[' + i + '].delay"]').on('input', function() {
|
||||
model.responses[i].delay = $(this).val();
|
||||
});
|
||||
|
||||
nodeCopy.find('textarea[name="responses[' + i + '].body"]').on('input', function() {
|
||||
model.responses[i].body = $(this).val();
|
||||
});
|
||||
|
||||
let conditions = nodeCopy.find('.response_conditions');
|
||||
|
||||
for(let c = 0; c < model.responses[i].conditions.length; c++){
|
||||
let conditionTemplate = $('#conditionTemplate').children().find('tr').clone();
|
||||
conditionTemplate.find('select').attr('name', 'responses[' + i + '].conditions[' + c + '].type');
|
||||
conditionTemplate.find('input[name="key"]').attr('name', 'responses[' + i + '].conditions[' + c + '].key');
|
||||
conditionTemplate.find('input[name="value"]').attr('name', 'responses[' + i + '].conditions[' + c + '].value');
|
||||
conditionTemplate.find('button').attr("data-id", i);
|
||||
conditionTemplate.find('button').attr("data-row", c);
|
||||
|
||||
conditionTemplate.find('select').val(model.responses[i].conditions[c].type);
|
||||
conditionTemplate.find('input[name="responses[' + i + '].conditions[' + c + '].key"]').val(model.responses[i].conditions[c].key);
|
||||
conditionTemplate.find('input[name="responses[' + i + '].conditions[' + c + '].value"]').val(model.responses[i].conditions[c].value);
|
||||
|
||||
conditionTemplate.find('select').on('change', function() {
|
||||
model.responses[i].conditions[c].type = $(this).val();
|
||||
});
|
||||
|
||||
conditionTemplate.find('input[name="responses[' + i + '].conditions[' + c + '].key"]').on('input', function() {
|
||||
model.responses[i].conditions[c].key = $(this).val();
|
||||
});
|
||||
|
||||
conditionTemplate.find('input[name="responses[' + i + '].conditions[' + c + '].value"]').on('input', function() {
|
||||
model.responses[i].conditions[c].value = $(this).val();
|
||||
});
|
||||
|
||||
$(conditions).append(conditionTemplate);
|
||||
}
|
||||
|
||||
for(let j = 0; j < model.responses[i].headers.length; j++){
|
||||
let headerTemplate = $('#responseHeaderTemplate').children().find('tr').clone();
|
||||
headerTemplate.find('input[name="key"]').attr('name', 'responses[' + i + '].headers[' + j + '].key');
|
||||
headerTemplate.find('input[name="value"]').attr('name', 'responses[' + i + '].headers[' + j + '].value');
|
||||
headerTemplate.find('button').attr("data-id", i);
|
||||
headerTemplate.find('button').attr("data-row",j);
|
||||
|
||||
headerTemplate.find('input[name="responses[' + i + '].headers[' + j + '].key"]').val(model.responses[i].headers[j].key);
|
||||
headerTemplate.find('input[name="responses[' + i + '].headers[' + j + '].value"]').val(model.responses[i].headers[j].value);
|
||||
|
||||
headerTemplate.find('input[name="responses[' + i + '].headers[' + j + '].key"]').on('input', function() {
|
||||
model.responses[i].headers[j].key = $(this).val();
|
||||
});
|
||||
|
||||
headerTemplate.find('input[name="responses[' + i + '].headers[' + j + '].value"]').on('input', function() {
|
||||
model.responses[i].headers[j].value = $(this).val();
|
||||
});
|
||||
|
||||
$(nodeCopy).find('.response_headers').append(headerTemplate);
|
||||
}
|
||||
|
||||
$('#responses').append(nodeCopy);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
let controller = {
|
||||
init: function () {
|
||||
view.init();
|
||||
},
|
||||
addResponse: function () {
|
||||
model.responses.push({
|
||||
statusCode: 200,
|
||||
delay: 0,
|
||||
headers: [],
|
||||
body: '',
|
||||
conditions: [],
|
||||
});
|
||||
view.render();
|
||||
},
|
||||
removeResponse: function (idx) {
|
||||
if (model.responses.length === 1) {
|
||||
alert('최소 1개의 응답이 필요합니다.');
|
||||
return;
|
||||
}
|
||||
model.responses.splice(idx, 1);
|
||||
view.render();
|
||||
},
|
||||
addResponseCondition: function (idx) {
|
||||
model.responses[idx].conditions.push({
|
||||
type: 'query',
|
||||
key: '',
|
||||
value: ''
|
||||
});
|
||||
view.render();
|
||||
},
|
||||
removeResponseCondition: function (idx, conditionIdx) {
|
||||
model.responses[idx].conditions.splice(conditionIdx, 1);
|
||||
view.render();
|
||||
},
|
||||
addResponseHeader : function(idx) {
|
||||
model.responses[idx].headers.push({
|
||||
key: '',
|
||||
value: ''
|
||||
});
|
||||
view.render();
|
||||
},
|
||||
removeResponseHeader : function(idx, headerIdx) {
|
||||
model.responses[idx].headers.splice(headerIdx, 1);
|
||||
view.render();
|
||||
}
|
||||
}
|
||||
|
||||
controller.init();
|
||||
|
||||
let fnRegister = document.querySelector(".btn_register");
|
||||
|
||||
fnRegister.addEventListener("click", function (event) {
|
||||
let form = document.getElementById("mockRouteForm");
|
||||
if (!form.checkValidity()) {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
} else {
|
||||
form.submit();
|
||||
}
|
||||
form.classList.add('was-validated');
|
||||
});
|
||||
|
||||
let fnList = document.querySelector(".btn_list");
|
||||
|
||||
fnList.addEventListener("click", function () {
|
||||
location.href = "[[@{/mgmt/routes/list_view.do}]]";
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</th:block>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
<!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" layout:decorate="~{/layout/default_layout}">
|
||||
|
||||
|
||||
<body>
|
||||
|
||||
<section layout:fragment="contentFragment">
|
||||
|
||||
<div class="container">
|
||||
<div class="card mt-1">
|
||||
<div class="card-header">
|
||||
<h1>API 목록</h1>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between">
|
||||
<form role="form" name="searchForm" th:action="@{/mgmt/routes/list_view.do}" method="get" th:object="${modelSearch}">
|
||||
<input name="page" type="hidden" value="1"/>
|
||||
<div class="search_field">
|
||||
<div class="search_field_input">
|
||||
<input class="form-control" name="username" placeholder="이름" type="text" size="35" th:title="#{title.search}+ '' + #{input.input}"
|
||||
th:value="${modelSearch.name}"
|
||||
maxlength="255"/>
|
||||
</div>
|
||||
<div class="search_field_button">
|
||||
<button type="button" class="btn btn-primary btn_search" th:value="#{button.inquire}"><i class="fa-sharp fa-solid fa-magnifying-glass"></i> [[#{title.inquire}]]
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary btn_delete"><i class="fa-sharp fa-solid fa-trash"></i> [[#{title.delete}]]</button>
|
||||
<button type="button" class="btn btn-primary btn_add"><i class="fa-sharp fa-solid fa-plus"></i> [[#{button.create}]]</button><!-- 등록 -->
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card mt-2">
|
||||
<div class="card-body">
|
||||
<form name="listForm">
|
||||
<input name="id" type="hidden"/>
|
||||
<input name="checkedIdForDel" type="hidden"/>
|
||||
<input id="csrf" type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}">
|
||||
<table class="table table-hover pt-table">
|
||||
<colgroup>
|
||||
<col style="width: 5%;">
|
||||
<col style="width: 5%;">
|
||||
<col>
|
||||
<col>
|
||||
<col style="width: 7%;">
|
||||
<col>
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="no">번호</th>
|
||||
<th><input type="checkbox" name="checkAll" class="check2" onclick="fncCheckAll()" th:title="#{input.selectAll.title}"></th><!-- 전체선택 -->
|
||||
<th>method</th>
|
||||
<th>path</th>
|
||||
<th>이름</th>
|
||||
<th>비고</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="row, status : ${page.content}">
|
||||
<td class="no" th:text="${page.getTotalElements() - (page.getNumber() * page.getSize() + status.count ) + 1}"></td>
|
||||
<td>
|
||||
<input type="checkbox" name="checkField" class="check2" title="선택"/>
|
||||
<input name="checkId" type="hidden" th:value="${row.id}"/>
|
||||
</td>
|
||||
<td>
|
||||
<span th:text="${row.method}"></span>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<span th:text="${row.pathPattern}"></span>
|
||||
</td>
|
||||
<td>
|
||||
<span th:text="${row.name}"></span>
|
||||
</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-primary btn-sm" th:onclick="fnSelectItem([[${row.id}]])" th:value="#{button.update}"><i class="fa-sharp fa-solid fa-edit"></i>
|
||||
[[#{button.update}]]
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- 글이 없는 경우 -->
|
||||
<tr th:if="${page.content.size() == 0 }">
|
||||
<td colspan="6" th:text="#{common.nodata.msg}"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<div th:replace="~{fragment/pagination :: pagination(jsFunction='fn_select_page')}"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
</body>
|
||||
|
||||
|
||||
<th:block layout:fragment="contentScript">
|
||||
<script>
|
||||
function fn_select_page(pageNo) {
|
||||
document.searchForm.page.value = pageNo;
|
||||
document.searchForm.submit();
|
||||
}
|
||||
|
||||
function fnSelectItem(id) {
|
||||
location.href = "[[@{/mgmt/routes/update_view.do}]]" + "?id=" + id;
|
||||
}
|
||||
|
||||
$(function () {
|
||||
let fnSearch = document.querySelector(".btn_search");
|
||||
let fnDelete = document.querySelector(".btn_delete");
|
||||
let fnAdd = document.querySelector(".btn_add");
|
||||
|
||||
fnSearch.addEventListener("click", function () {
|
||||
document.searchForm.page.value = 1;
|
||||
document.searchForm.submit();
|
||||
});
|
||||
|
||||
fnDelete.addEventListener("click", function () {
|
||||
var checkField = document.listForm.checkField;
|
||||
var id = document.listForm.checkId;
|
||||
var checkedIds = "";
|
||||
var checkedCount = 0;
|
||||
if (checkField) {
|
||||
if (checkField.length > 1) {
|
||||
for (var i = 0; i < checkField.length; i++) {
|
||||
if (checkField[i].checked) {
|
||||
checkedIds += ((checkedCount == 0 ? "" : ",") + id[i].value);
|
||||
checkedCount++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (checkField.checked) {
|
||||
checkedIds = id.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (checkedIds.length > 0) {
|
||||
if (confirm("[[#{common.delete.msg}]]")) {
|
||||
document.listForm.checkedIdForDel.value = checkedIds;
|
||||
document.listForm.method = 'POST';
|
||||
document.listForm.action = '[[@{/mgmt/routes/delete.do}]]';
|
||||
document.listForm.submit();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
fnAdd.addEventListener("click", function () {
|
||||
location.href = '[[@{/mgmt/routes/create_view.do}]]';
|
||||
});
|
||||
})
|
||||
</script>
|
||||
|
||||
</th:block>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,80 @@
|
||||
<!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" layout:decorate="~{/layout/base_layout}">
|
||||
<body>
|
||||
|
||||
<section layout:fragment="contentFragment">
|
||||
<div class="container mt-2">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h1>최초 Admin 등록</h1>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form name="staffUserForm" id="staffUserForm" th:action="@{/admin_register.do}" th:object='${user}' method="post">
|
||||
<input id="csrf" type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}">
|
||||
<div class="form-floating mt-2">
|
||||
<input type="email" class="form-control" th:classappend="${#fields.hasErrors('userId')}? 'is-invalid'" th:field="*{userId}" name="userId" id="userId" required th:readonly="${user.esntlId != null}"/>
|
||||
<label for="userId" class="form-label must" th:text="#{email}">이메일</label>
|
||||
<th:block th:each="err : ${#fields.errors('userId')}">
|
||||
<div th:text="${err}" class="invalid-feedback"></div>
|
||||
</th:block>
|
||||
</div>
|
||||
<div class="form-floating mt-2" th:if="${user.esntlId == null}">
|
||||
<input type="password" class="form-control" th:classappend="${#fields.hasErrors('password')}? 'is-invalid'" th:field="*{password}" name="password" id="password" required/>
|
||||
<label for="password" class="form-label must" th:text="#{password}">비밀번호</label>
|
||||
<th:block th:each="err : ${#fields.errors('password')}">
|
||||
<div th:text="${err}" class="invalid-feedback"></div>
|
||||
</th:block>
|
||||
</div>
|
||||
<div class="form-floating mt-2" th:if="${user.esntlId == null}">
|
||||
<input type="password" class="form-control" th:classappend="${#fields.hasErrors('password2')}? 'is-invalid'" th:field="*{password2}" name="password2" id="password2" required/>
|
||||
<label for="password2" class="form-label must">비밀번호 확인</label>
|
||||
<th:block th:each="err : ${#fields.errors('password2')}">
|
||||
<div th:text="${err}" class="invalid-feedback"></div>
|
||||
</th:block>
|
||||
</div>
|
||||
|
||||
<div class="form-floating mt-2">
|
||||
<input type="text" class="form-control" th:classappend="${#fields.hasErrors('username')}? 'is-invalid'" th:field="*{username}" name="username" id="username" required/>
|
||||
<label for="username" class="form-label must" th:text="#{username}">이름</label>
|
||||
<th:block th:each="err : ${#fields.errors('username')}">
|
||||
<div th:text="${err}" class="invalid-feedback"></div>
|
||||
</th:block>
|
||||
</div>
|
||||
|
||||
<div class="form-floating mt-2">
|
||||
<input type="text" class="form-control" th:classappend="${#fields.hasErrors('mobilePhone')}? 'is-invalid'" th:field="*{mobilePhone}" name="mobilePhone" id="mobilePhone" required/>
|
||||
<label for="mobilePhone" class="form-label must" th:text="#{mobilePhone}">연락처</label>
|
||||
<th:block th:each="err : ${#fields.errors('mobilePhone')}">
|
||||
<div th:text="${err}" class="invalid-feedback"></div>
|
||||
</th:block>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<button type="button" class="btn btn-primary btn_register"><i class="fa-sharp fa-solid fa-floppy-disk"></i> 저장</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</body>
|
||||
|
||||
<th:block layout:fragment="contentScript">
|
||||
<script>
|
||||
$(function () {
|
||||
let fnRegister = document.querySelector(".btn_register");
|
||||
fnRegister.addEventListener("click", function (event) {
|
||||
let form = document.getElementById("staffUserForm");
|
||||
if (!form.checkValidity()) {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
} else {
|
||||
form.submit();
|
||||
}
|
||||
form.classList.add('was-validated');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</th:block>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
<!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" layout:decorate="~{/layout/default_layout}">
|
||||
<body>
|
||||
|
||||
<section layout:fragment="contentFragment">
|
||||
<div class="container m-0">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h1 th:if="${user.esntlId == null}">내부 사용자 등록</h1>
|
||||
<h1 th:if="${user.esntlId != null}">내부 사용자 수정</h1>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form name="staffUserForm" id="staffUserForm" th:action="${user.esntlId==null}?@{/mgmt/users/register.do}:@{/mgmt/users/update.do}" th:object='${user}' method="post">
|
||||
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}">
|
||||
<div th:if="${user.esntlId != null}" class="form-floating">
|
||||
<input type="text" class="form-control" th:classappend="${#fields.hasErrors('esntlId')}? 'is-invalid'" th:field="*{esntlId}" name="esntlId" id="esntlId" readonly/>
|
||||
<label for="esntlId" class="form-label must" th:text="#{esntlId}">고유ID</label>
|
||||
</div>
|
||||
<div class="form-floating mt-2">
|
||||
<input type="email" class="form-control" th:classappend="${#fields.hasErrors('userId')}? 'is-invalid'" th:field="*{userId}" name="userId" id="userId" required th:readonly="${user.esntlId != null}"/>
|
||||
<label for="userId" class="form-label must" th:text="#{email}">이메일</label>
|
||||
<th:block th:each="err : ${#fields.errors('userId')}">
|
||||
<div th:text="${err}" class="invalid-feedback"></div>
|
||||
</th:block>
|
||||
</div>
|
||||
<div class="form-floating mt-2" th:if="${user.esntlId == null}">
|
||||
<input type="password" class="form-control" th:classappend="${#fields.hasErrors('password')}? 'is-invalid'" th:field="*{password}" name="password" id="password" required/>
|
||||
<label for="password" class="form-label must" th:text="#{password}">비밀번호</label>
|
||||
<th:block th:each="err : ${#fields.errors('password')}">
|
||||
<div th:text="${err}" class="invalid-feedback"></div>
|
||||
</th:block>
|
||||
</div>
|
||||
<div class="form-floating mt-2" th:if="${user.esntlId == null}">
|
||||
<input type="password" class="form-control" th:classappend="${#fields.hasErrors('password2')}? 'is-invalid'" th:field="*{password2}" name="password2" id="password2" required/>
|
||||
<label for="password2" class="form-label must">비밀번호 확인</label>
|
||||
<th:block th:each="err : ${#fields.errors('password2')}">
|
||||
<div th:text="${err}" class="invalid-feedback"></div>
|
||||
</th:block>
|
||||
</div>
|
||||
|
||||
<div class="form-floating mt-2">
|
||||
<input type="text" class="form-control" th:classappend="${#fields.hasErrors('username')}? 'is-invalid'" th:field="*{username}" name="username" id="username" required/>
|
||||
<label for="username" class="form-label must" th:text="#{username}">이름</label>
|
||||
<th:block th:each="err : ${#fields.errors('username')}">
|
||||
<div th:text="${err}" class="invalid-feedback"></div>
|
||||
</th:block>
|
||||
</div>
|
||||
|
||||
<div class="form-floating mt-2">
|
||||
<input type="text" class="form-control" th:classappend="${#fields.hasErrors('mobilePhone')}? 'is-invalid'" th:field="*{mobilePhone}" name="mobilePhone" id="mobilePhone" required/>
|
||||
<label for="mobilePhone" class="form-label must" th:text="#{mobilePhone}">연락처</label>
|
||||
<th:block th:each="err : ${#fields.errors('mobilePhone')}">
|
||||
<div th:text="${err}" class="invalid-feedback"></div>
|
||||
</th:block>
|
||||
</div>
|
||||
|
||||
<div th:if="${user.esntlId != null}" class="form-floating mt-2">
|
||||
<select name="status" class="form-select" th:classappend="${#fields.hasErrors('status')}? 'is-invalid'" id="status">
|
||||
<option th:selected="${user.status.toString() == 'WAITING'}" value="WAITING">가입승인 대기</option>
|
||||
<option th:selected="${user.status.toString() == 'ACTIVE'}" value="ACTIVE">활성화</option>
|
||||
<option th:selected="${user.status.toString() == 'INACTIVE'}" value="INACTIVE">비활성화</option>
|
||||
<option th:selected="${user.status.toString() == 'LOCKED'}" value="LOCKED">잠김</option>
|
||||
</select>
|
||||
<label for="status" class="form-label must" th:text="#{status}">상태</label>
|
||||
</div>
|
||||
<div th:if="${user.esntlId != null}" class="form-floating mt-2">
|
||||
<select name="lockAt" class="form-select" th:classappend="${#fields.hasErrors('lockAt')}? 'is-invalid'" id="lockAt">
|
||||
<option th:selected="${user.lockAt.toString() == 'N'}" value="N">해제</option>
|
||||
<option th:selected="${user.lockAt.toString() == 'Y'}" value="Y">잠금</option>
|
||||
</select>
|
||||
<label for="lockAt" class="form-label must" th:text="#{lockAt}">잠금여부</label>
|
||||
</div>
|
||||
<div th:if="${user.esntlId != null}" class="form-floating mt-2">
|
||||
<input type="text" class="form-control" th:classappend="${#fields.hasErrors('lockCnt')}? 'is-invalid'" th:field="*{lockCnt}" name="lockCnt" id="lockCnt" readonly/>
|
||||
<label for="lockCnt" class="form-label must" th:text="#{lockCnt}">잠금 횟수</label>
|
||||
</div>
|
||||
<div th:if="${user.esntlId != null}" class="form-floating mt-2">
|
||||
<input type="text" class="form-control" th:classappend="${#fields.hasErrors('createdAt')}? 'is-invalid'" th:field="*{createdAt}" name="createdAt" id="createdAt" readonly/>
|
||||
<label for="createdAt" class="form-label must">등록 일시</label>
|
||||
</div>
|
||||
<div th:if="${user.esntlId != null}" class="form-floating mt-2">
|
||||
<input type="text" class="form-control" th:classappend="${#fields.hasErrors('lastLockDate')}? 'is-invalid'" th:field="*{lastLockDate}" name="lastLockDate"
|
||||
id="lastLockDate" readonly/>
|
||||
<label for="lastLockDate" class="form-label must" th:text="#{lastLockDate}">잠금최종시점</label>
|
||||
</div>
|
||||
<div th:if="${user.esntlId != null}" class="form-floating mt-2">
|
||||
<input type="text" class="form-control" th:classappend="${#fields.hasErrors('lastPasswordChangeDate')}? 'is-invalid'" th:field="*{lastPasswordChangeDate}"
|
||||
name="lastPasswordChangeDate"
|
||||
id="lastPasswordChangeDate" readonly/>
|
||||
<label for="lastPasswordChangeDate" class="form-label must" th:text="#{lastPasswordChangeDate}">비밀번호 변경일자</label>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<button type="button" class="btn btn-primary btn_list"><i class="fa-solid fa-list"></i> 목록</button>
|
||||
<button type="button" class="btn btn-primary btn_register"><i class="fa-sharp fa-solid fa-floppy-disk"></i> 저장</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</body>
|
||||
|
||||
<th:block layout:fragment="contentScript">
|
||||
<script>
|
||||
$(function () {
|
||||
let fnRegister = document.querySelector(".btn_register");
|
||||
fnRegister.addEventListener("click", function (event) {
|
||||
let form = document.getElementById("staffUserForm");
|
||||
if (!form.checkValidity()) {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
} else {
|
||||
form.submit();
|
||||
}
|
||||
form.classList.add('was-validated');
|
||||
});
|
||||
|
||||
let fnList = document.querySelector(".btn_list");
|
||||
|
||||
fnList.addEventListener("click", function () {
|
||||
location.href = "[[@{/mgmt/users/list_view.do}]]";
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</th:block>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
<!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" layout:decorate="~{/layout/default_layout}">
|
||||
|
||||
|
||||
<body>
|
||||
|
||||
<section layout:fragment="contentFragment">
|
||||
<div class="container">
|
||||
<div class="card mt-2">
|
||||
<div class="card-header">
|
||||
<h1>사용자 목록</h1>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between">
|
||||
<form role="form" name="searchForm" th:action="@{/mgmt/users/list_view.do}" method="get" th:object="${modelSearch}">
|
||||
<input name="page" type="hidden" value="1"/>
|
||||
<div class="search_field">
|
||||
<div class="search_field_input">
|
||||
<input class="form-control" name="username" placeholder="사용자 이름" type="text" size="35" th:title="#{title.search}+ '' + #{input.input}"
|
||||
th:value="${modelSearch.username}"
|
||||
maxlength="255"/>
|
||||
</div>
|
||||
<div class="search_field_button">
|
||||
<button type="button" class="btn btn-primary btn_search" th:value="#{button.inquire}"><i class="fa-sharp fa-solid fa-magnifying-glass"></i> [[#{title.inquire}]]
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary btn_delete"><i class="fa-sharp fa-solid fa-trash"></i> [[#{title.delete}]]</button>
|
||||
<button type="button" class="btn btn-primary btn_add"><i class="fa-sharp fa-solid fa-plus"></i> [[#{button.create}]]</button><!-- 등록 -->
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card mt-2">
|
||||
<div class="card-body">
|
||||
<form name="listForm">
|
||||
<input name="id" type="hidden"/>
|
||||
<input name="checkedIdForDel" type="hidden"/>
|
||||
<input id="csrf" type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}">
|
||||
<table class="table table-hover pt-table">
|
||||
<colgroup>
|
||||
<col style="width: 5%;">
|
||||
<col style="width: 5%;">
|
||||
<col>
|
||||
<col>
|
||||
<col style="width: 7%;">
|
||||
<col>
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="no">번호</th>
|
||||
<th><input type="checkbox" name="checkAll" class="check2" onclick="fncCheckAll()" th:title="#{input.selectAll.title}"></th><!-- 전체선택 -->
|
||||
<th>ID</th>
|
||||
<th>이름</th>
|
||||
<th>상태</th>
|
||||
<th>비고</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="row, status : ${page.content}">
|
||||
<td class="no" th:text="${page.getTotalElements() - (page.getNumber() * page.getSize() + status.count ) + 1}"></td>
|
||||
<td>
|
||||
<input type="checkbox" name="checkField" class="check2" title="선택"/>
|
||||
<input name="checkId" type="hidden" th:value="${row.esntlId}"/>
|
||||
</td>
|
||||
<td>
|
||||
<span th:text="${row.userId}"></span>
|
||||
</td>
|
||||
<td>
|
||||
<span th:text="${row.username}"></span>
|
||||
</td>
|
||||
<td>
|
||||
<span th:text="${row.status.toString()}"></span>
|
||||
</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-primary btn-sm" th:onclick="fnSelectItem([[${row.esntlId}]])" th:value="#{button.update}"><i class="fa-sharp fa-solid fa-edit"></i>
|
||||
[[#{button.update}]]
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- 글이 없는 경우 -->
|
||||
<tr th:if="${page.content.size() == 0 }">
|
||||
<td colspan="5" th:text="#{common.nodata.msg}"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<div th:replace="~{fragment/pagination :: pagination(jsFunction='fn_select_page')}"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
</body>
|
||||
|
||||
|
||||
<th:block layout:fragment="contentScript">
|
||||
<script>
|
||||
function fn_select_page(pageNo) {
|
||||
document.searchForm.page.value = pageNo;
|
||||
document.searchForm.submit();
|
||||
}
|
||||
|
||||
function fnSelectItem(id) {
|
||||
location.href = "[[@{/mgmt/users/update_view.do}]]" + "?userId=" + id;
|
||||
}
|
||||
$(function () {
|
||||
let fnSearch = document.querySelector(".btn_search");
|
||||
let fnDelete = document.querySelector(".btn_delete");
|
||||
let fnAdd = document.querySelector(".btn_add");
|
||||
|
||||
fnSearch.addEventListener("click", function () {
|
||||
document.searchForm.page.value = 1;
|
||||
document.searchForm.submit();
|
||||
});
|
||||
|
||||
fnDelete.addEventListener("click", function () {
|
||||
var checkField = document.listForm.checkField;
|
||||
var id = document.listForm.checkId;
|
||||
var checkedIds = "";
|
||||
var checkedCount = 0;
|
||||
if (checkField) {
|
||||
if (checkField.length > 1) {
|
||||
for (var i = 0; i < checkField.length; i++) {
|
||||
if (checkField[i].checked) {
|
||||
checkedIds += ((checkedCount == 0 ? "" : ",") + id[i].value);
|
||||
checkedCount++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (checkField.checked) {
|
||||
checkedIds = id.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (checkedIds.length > 0) {
|
||||
if (confirm("[[#{common.delete.msg}]]")) {
|
||||
document.listForm.checkedIdForDel.value = checkedIds;
|
||||
document.listForm.method = 'POST';
|
||||
document.listForm.action = '[[@{/mgmt/users/delete.do}]]';
|
||||
document.listForm.submit();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
fnAdd.addEventListener("click", function () {
|
||||
location.href = '[[@{/mgmt/users/create_view.do}]]';
|
||||
});
|
||||
})
|
||||
</script>
|
||||
|
||||
</th:block>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user