새 컬렉션 추가, 로딩, 새 요청 추가

This commit is contained in:
현성필
2023-05-15 15:47:33 +09:00
parent f12352db52
commit 78277d271d
22 changed files with 653 additions and 87 deletions
@@ -16,14 +16,14 @@
<div class="d-flex" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item" sec:authorize="isAuthenticated()">
<a class="nav-link" href="/mgmt/routes/list_view.do">API 관리</a>
<a class="nav-link" href="/mgmt/routes/list_view.do">응답 관리</a>
</li>
<li class="nav-item" sec:authorize="isAuthenticated()">
<a class="nav-link" href="/mgmt/api_tester.do">API Tester</a>
<a class="nav-link" href="/mgmt/api_tester.do">Tester</a>
</li>
<li class="nav-item dropdown" sec:authorize="hasRole('ROLE_ADMIN')">
<a class="nav-link dropdown-toggle" 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>
@@ -15,35 +15,31 @@
</div>
</div>
<!-- new collection button -->
<div class="pt-new-collection p-1">
<div class="p-1">
<button type="button" class="btn btn-primary btn-sm" id="new_collection"><i class="fa fa-plus"></i>새 컬렉션</button>
<button type="button" class="btn btn-primary btn-sm" id="new_request"><i class="fa fa-plus"></i>새 요청</button>
</div>
<div class="collapse pt-links" id="side_menubar" aria-label="sidebar menu">
<ul class="list-unstyled mb-0 py-3 pt-md-1">
<li th:each="collection, status: *{collections}">
<a href="#" class="d-inline-flex align-items-center rounded">기본</a>
</li>
<div class="collapse pt-links" aria-label="sidebar menu">
<ul class="list-unstyled mb-0 py-3 pt-md-1" id="side_menubar">
</ul>
</div>
<div class="modal fade" id="new_collection_modal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal fade" id="new_collection_modal" tabindex="-1" aria-labelledby="new_collection_modal" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">새로운 컬렉션 추가</h5>
<h5 class="modal-title">새로운 컬렉션 추가</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<input type="text" class="form-control" placeholder="이름을 입력하세요" aria-label="이름을 입력하세요" aria-describedby="button-addon2" name="collection_name"/>
<input type="text" class="form-control" placeholder="이름을 입력하세요" aria-label="이름을 입력하세요" aria-describedby="button-addon2" name="collection_name" required/>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">닫기</button>
<button type="button" class="btn btn-primary">저장</button>
<button type="button" class="btn btn-primary save">저장</button>
</div>
</div>
</div>
</div>
</aside>
<!-- menu script -->
@@ -51,7 +47,8 @@
<script th:inline="javascript">
$(function () {
//when new_collection button clicked show modal popup for entering name
$('#new_collection').click(function () {
$('#new_collection').on('click', function () {
$('#new_collection_modal').find('input').val('');
$('#new_collection_modal').modal('show');
});
});
+190 -16
View File
@@ -25,6 +25,23 @@
<div class="tab-content" id="apiRequestTabContent">
</div>
</div>
<div class="modal fade" id="new_api_request_modal" tabindex="-1" aria-labelledby="new_api_request_modal" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">새로운 API 추가</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<select class="form-select" id="modal_collection"></select>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">닫기</button>
<button type="button" class="btn btn-primary add_new_request">추가</button>
</div>
</div>
</div>
</div>
<div id="apiRequestTemplate" style="display: none;">
<div class="tab-pane fade mt-1">
<div class="d-flex align-items-center">
@@ -208,6 +225,26 @@
</tbody>
</table>
</div>
<ul id="collectionTemplate" style="display: none;">
<li>
<div class="d-flex justify-content-between">
<button class="btn d-inline-flex align-items-center rounded new_collection" data-bs-toggle="collapse"
data-bs-target="" aria-expanded="false" aria-current="false">컬렉션
</button>
<button class="p-1 hover:text-white delete_collection"><i class="fa fa-trash-can"></i></button>
</div>
<div class="collapse">
<ul class="list-unstyled fw-normal pb-1 small">
</ul>
</div>
</li>
</ul>
<ul id="collectionApiTemplate" style="display: none;">
<li class="d-flex justify-content-between">
<a href="#" class="d-inline-flex align-items-center rounded"></a>
<button class="p-1 hover:text-white delete_api_request"><i class="fa fa-trash-can"></i></button>
</li>
</ul>
</section>
</body>
@@ -216,12 +253,14 @@
$(function () {
let apiRequests = [];
let collections = [];
let view = {
currentIdx: 0,
responses: [],
requests: [],
init: function () {
$("#cancel-ajax").on("click", function () {
if (controller.currentAjaxRequest) {
controller.currentAjaxRequest.abort();
@@ -230,12 +269,19 @@
});
$('#new_request').on('click', function () {
controller.addAPIRequest();
$('#new_api_request_modal').modal('show');
});
if (apiRequests.length === 0)
controller.addAPIRequest();
// this.render();
$('#new_api_request_modal').find('.add_new_request').on('click', function () {
controller.addAPIRequest($('#new_api_request_modal').find('select').val());
});
$('#new_collection_modal').find('.save').on('click', function () {
controller.addCollection($('#new_collection_modal').find('input').val());
});
controller.loadCollections();
},
renderParam: function (tabIdx) {
let target = $('#api_request_' + tabIdx);
@@ -397,7 +443,7 @@
target.find('.send').click(function () {
controller.send(idx);
});
var me = this;
let me = this;
require(['vs/editor/editor.main'], function() {
let requestBodyEditor = monaco.editor.create(target.find(".request_body")[0], {
@@ -470,6 +516,38 @@
target.find(".response_status").text("status: " + model.responseModel.status);
target.find(".response_time").text("time: " + model.responseModel.time + "ms");
target.find(".response_size").text("size: " + model.responseModel.size + "bytes");
},
renderCollections: function(){
let select = $('#modal_collection');
let sidemenu = $('#side_menubar');
select.empty();
sidemenu.empty();
for (let i = 0; i < collections.length; i++) {
let template = $('#collectionTemplate').children().clone();
template.find('button.new_collection').text(collections[i].name);
template.find('button').attr('data-bs-target', '#collection_' + i);
template.find('.collapse').attr('id', 'collection_' +i);
for (let j = 0; j < collections[i].apis.length; j++) {
let collectionApiTemplate = $('#collectionApiTemplate').children().clone();
let link = collectionApiTemplate.find('a');
link.text(collections[i].apis[j].name);
link.attr('data-collection', collections[i].id);
link.attr('data-id', collections[i].apis[j].id);
link.on('click', function(){
controller.openApiRequest($(this).attr('data-collection'),$(this).attr('data-id'));
})
template.find('.collapse ul').append(collectionApiTemplate);
}
let option = $('<option>');
option.attr('value', collections[i].id);
option.text(collections[i].name);
select.append(option);
sidemenu.append(template);
}
}
}
@@ -531,6 +609,25 @@
hideLoadingOverlay: function () {
$("#loading-overlay").hide();
},
openApiRequest: function(collectionId, apiId) {
let selectedApi = collections.filter(function (collection) {
return collection.id === collectionId;
})[0].apis.filter(function (api) {
return api.id === apiId;
})[0];
if (selectedApi !== undefined){
let tab = apiRequests.filter(function(api){
return api.id === selectedApi.id;
})[0];
if (tab === undefined){
apiRequests.push(selectedApi);
view.currentIdx = apiRequests.length - 1;
view.renderTabHeader();
view.renderTabContent(view.currentIdx);
}
}
},
send: function (tabIdx) {
let model = apiRequests[tabIdx];
let target = $('#api_request_' + tabIdx);
@@ -541,7 +638,7 @@
if (model.path !== '') {
controller.showLoadingOverlay();
this.currentAjaxRequest = $.ajax({
url: '/api/test.do',
url: '/mgmt/api/test.do',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(model),
@@ -564,15 +661,68 @@
});
}
},
addCollection: function () {
loadCollections: function(){
controller.showLoadingOverlay();
this.currentAjaxRequest = $.ajax({
url: '/mgmt/collections/list.do',
type: 'GET',
contentType: 'application/json',
success: function (data) {
collections = data;
},
error: function (jqXHR, textStatus, errorThrown) {
console.error(textStatus, errorThrown);
controller.hideLoadingOverlay();
},
complete: function () {
view.renderCollections();
controller.hideLoadingOverlay();
}
});
},
removeCollection: function () {
addCollection: function (collection) {
controller.showLoadingOverlay();
this.currentAjaxRequest = $.ajax({
url: '/mgmt/collections/create.do',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({name: collection}),
success: function (data) {
$('#new_collection_modal').modal('hide');
},
error: function (jqXHR, textStatus, errorThrown) {
console.error(textStatus, errorThrown);
controller.hideLoadingOverlay();
},
complete: function () {
controller.loadCollections();
controller.hideLoadingOverlay();
}
});
},
addAPIRequest: function () {
let name = 'New Request ' + (apiRequests.length + 1);
apiRequests.push({
removeCollection: function (id) {
controller.showLoadingOverlay();
this.currentAjaxRequest = $.ajax({
url: '/mgmt/collections/delete.do',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({id: id}),
success: function () {
},
error: function (jqXHR, textStatus, errorThrown) {
console.error(textStatus, errorThrown);
controller.hideLoadingOverlay();
},
complete: function () {
controller.loadCollections();
controller.hideLoadingOverlay();
}
});
},
addAPIRequest: function (collectionId) {
let name = 'New Request';
let newApi = {
id : '',
server: null,
method: 'GET',
name: name,
@@ -587,10 +737,34 @@
headers: [],
body: ''
}
};
this.currentAjaxRequest = $.ajax({
url: '/mgmt/collections/{id}/apis/save.do'.replace('{id}', collectionId),
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(newApi),
success: function (data) {
console.log(data);
newApi.id = data.id;
},
error: function (jqXHR, textStatus, errorThrown) {
console.error(textStatus, errorThrown);
controller.hideLoadingOverlay();
},
complete: function () {
controller.loadCollections();
controller.hideLoadingOverlay();
apiRequests.push(newApi);
view.currentIdx = apiRequests.length - 1;
view.renderTabHeader();
view.renderTabContent(view.currentIdx);
$('#new_api_request_modal').modal('hide');
controller.loadCollections();
}
});
view.currentIdx = apiRequests.length - 1;
view.renderTabHeader();
view.renderTabContent(view.currentIdx);
},
removeAPIRequest: function (idx) {
apiRequests.splice(idx, 1);
@@ -10,7 +10,7 @@
<div class="container">
<div class="card mt-1">
<div class="card-header">
<h1>API 목록</h1>
<h1>응답 API 목록</h1>
</div>
<div class="card-body">
<div class="d-flex justify-content-between">