응답 -> 탭 적용

This commit is contained in:
현성필
2023-05-08 14:27:33 +09:00
parent 2412d289c3
commit 488a832d27
6 changed files with 245 additions and 534 deletions
@@ -46,7 +46,9 @@ public class MockRouteMgmtController {
@GetMapping("/create_view.do")
public String createView(ModelMap model) {
MockRouteDTO defaultRoute = new MockRouteDTO();
defaultRoute.getResponses().add(new MockResponseDTO());
MockResponseDTO defaultResponse = new MockResponseDTO();
defaultResponse.setDefaultResponse(true);
defaultRoute.getResponses().add(defaultResponse);
model.addAttribute("mockRoute", defaultRoute);
return MOCK_ROUTE_EDIT;
}
@@ -55,7 +57,8 @@ public class MockRouteMgmtController {
public String updateView(ModelMap model, @RequestParam("id") Long id) {
MockRoute found = mockRouteService.findById(id);
model.addAttribute("mockRoute", found);
model.addAttribute("mockRoute", mockRouteMapper.map(found));
return MOCK_ROUTE_EDIT;
}
@@ -3,12 +3,11 @@ package com.eactive.httpmockserver.api.dto;
import javax.validation.constraints.Min;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class MockResponseDTO {
@Min(100)
private int statusCode = 100;
private int statusCode = 200;
private List<MockHeaderDTO> headers = new ArrayList<>();
@@ -16,6 +15,7 @@ public class MockResponseDTO {
private long delay = 0; //millisecond
private boolean defaultResponse = false;
private List<MockConditionDTO> conditions;
public int getStatusCode() {
@@ -57,4 +57,12 @@ public class MockResponseDTO {
public void setConditions(List<MockConditionDTO> conditions) {
this.conditions = conditions;
}
public boolean isDefaultResponse() {
return defaultResponse;
}
public void setDefaultResponse(boolean defaultResponse) {
this.defaultResponse = defaultResponse;
}
}
@@ -27,6 +27,9 @@ public class MockResponse {
private long delay = 0; //millisecond
@Column(name = "DEFAULT_RESPONSE", nullable = false, columnDefinition = "boolean default false")
private boolean defaultResponse = false;
@ManyToOne
@JoinColumn(name = "ROUTE_ID", nullable = false)
private MockRoute route;
@@ -89,4 +92,12 @@ public class MockResponse {
public void setConditions(List<MockCondition> conditions) {
this.conditions = conditions;
}
public boolean isDefaultResponse() {
return defaultResponse;
}
public void setDefaultResponse(boolean defaultResponse) {
this.defaultResponse = defaultResponse;
}
}
-273
View File
@@ -59,42 +59,7 @@ ul li {
border-color: #f5c08d;
}
/*메인페이지 뉴스 패널*/
.nav-tabs {
margin-top: 6px;
border-bottom: 0;
}
.nav-tabs > li.active > a, .nav-tabs > li.active > a:hover, .nav-tabs > li.active > a:focus {
border: 0px;
}
.nav-tabs > li > a {
height: 60px;
margin-right: 0;
font-size: 16px;
line-height: 2.5;
color: #888;
border-radius: 0;
border: 0px;
border-bottom: 2px solid #ddd;
box-shadow: inset 0px 2px 0px .0px rgba(0, 0, 0, .2);
}
.nav-tabs > li.active > a, .nav-tabs > li.active > a:hover, .nav-tabs > li.active > a:focus {
color: #222;
font-size: 17px;
font-weight: 600;
box-sizing: border-box;
border-bottom: 2px solid #222;
box-shadow: inset 0px 1.5px 0px .0px rgba(0, 0, 0, 1);
z-index: 999;
background: url(../img/bullet01.png) no-repeat 190px center;
}
.nav-tabs .active {
border: 0px;
}
/*사이트소개*/
.portal_main_head {
position: relative;
@@ -291,48 +256,11 @@ ul li {
margin-right: 10px;
}
div.calen-s {
display: inline-block;
position: relative;
margin-left: 10px;
vertical-align: middle;
}
div.calen-s span {
margin-right: 3px;
}
div.calen-s input[type="date"] {
display: block;
float: left;
width: 150px;
margin-right: 3px;
}
.signup .idsave {
margin: 10px 0 0 95px;
}
/*관리자 페이지 왼쪽 메뉴*/
.admin_menu {
display: block;
position: relative;
margin-left: 70px;
float: left;
top: 30px;
padding: 10px 20px 10px 20px;
width: 220px; /* box-shadow: 0px 0px 10px 2px rgba(0,0,0,0.08); */
border-radius: 10px;
background-color: #fff;
clear: both;
z-index: 100;
}
.admin_menu ul li div ul li:last-child a {
margin-bottom: 10px;
}
.b-example-divider {
flex-shrink: 0;
width: 1.5rem;
@@ -343,26 +271,6 @@ div.calen-s input[type="date"] {
box-shadow: inset 0 .5em 1.5em rgba(0, 0, 0, .1), inset 0 .125em .5em rgba(0, 0, 0, .15);
}
.btn-toggle {
display: inline-flex;
align-items: center;
width: 100%;
padding: 20px; /*margin: 10px 0 5px 0;*/
height: 30px;
background-color: /*transparent*/ #fff8eb;
border-radius: 4px;
border: 0;
font-weight: 500;
font-size: 16px;
color: #222;
}
.btn-toggle:hover,
.btn-toggle:focus {
color: rgba(0, 0, 0, .85);
background-color: #fff8eb;
}
/* 화면 스크롤 해도 nav_bar를 상단에 고정 */
.fixed_top {
position: fixed;
@@ -382,97 +290,14 @@ div.calen-s input[type="date"] {
display: block;
}
.btn-toggle[aria-expanded="true"] {
width: 100%;
color: #fff;
font-size: 16px;
font-weight: 500;
background-color: #fd9b00;
}
.btn-toggle[aria-expanded="true"]::before {
transform: rotate(90deg);
}
.btn-toggle-nav a {
display: inline-flex;
width: 100%;
padding: .1875rem .5rem;
margin-top: .125rem;
margin-left: 1.25rem;
text-decoration: none;
font-size: 15px;
font-weight: 400;
line-height: 1.5;
color: #222;
}
.scrollarea {
overflow-y: auto;
}
.admin_content {
display: block;
position: relative;
margin: 0 auto;
}
.has-error .form-control {
border-color: #dc312d;
}
.explan.error {
color: #dc312d;
}
/*테스트 등록*/
.testregister_wrap {
width: 100%;
padding: 0;
border-radius: 10px;
border: 1px solid #ddd;
margin: 20px 0 40px 0;
}
.testregister_top {
padding: 40px 60px 40px 60px;
}
.testregister_left, .testregister_right {
display: inline-block;
width: 49.8%;
padding: 40px 60px 60px 60px;
vertical-align: top;
}
.testregister_left {
border-right: 1px solid #e6e6e6;
}
.testregister_wrap h3 {
display: block;
float: left;
margin-top: 10px;
font-weight: 600;
margin-bottom: 20px;
}
.jg-regist {
display: block;
position: relative;
float: left;
width: 100%;
}
.jg-regist table tr {
height: 40px;
font-size: 14px;
border-bottom: 1px solid #ddd;
}
.jsgrid-table {
position: relative;
margin-left: 15px;
@@ -482,103 +307,6 @@ div.calen-s input[type="date"] {
width: 150px;
}
.testregister_wrap h3 span {
display: inline-block;
position: relative;
width: 26px;
height: 26px;
margin-right: 10px;
top: -2px;
background-color: #222;
border-radius: 50%;
text-align: center;
color: #fff;
font-weight: 400;
font-size: 16px;
line-height: 1.6;
}
.testregister_wrap hr {
display: block;
width: 100%;
margin: 0;
border-color: #ddd;
}
.testregister_result {
width: 100%;
border: 1px solid #ddd;
border-radius: 6px;
padding: 10px 0 10px 20px;
line-height: 1.7;
list-style: none;
}
.testregister_select_tit {
float: left;
width: 100%;
border: 1px solid #ddd;
border-radius: 6px;
padding: 15px 0 15px 20px;
line-height: 1.7;
list-style: none;
}
.testregister_select_tit li {
text-align: center;
}
.testregister_select {
float: left;
width: 100%;
border: 1px solid #ddd;
border-radius: 6px;
padding: 10px 20px;
background-color: #fafafa;
line-height: 1.7;
list-style: none;
}
.testregister_select li {
display: inline-block;
width: 100%;
height: 46px;
line-height: 2.8;
text-indent: 20px;
}
.testregister_select li:first-child {
border-bottom: 1px solid #ddd;
}
.testregister_select li:hover {
display: inline-block;
width: 100%;
background-color: #f1f1f1;
}
.testregister_result a, .testregister_select a {
color: #222;
}
.testregister_left .pagination {
margin-top: 15px;
}
.testregister_left .pagination ul li a,
.testregister_left .pagination ul li.on a,
.testregister_left .pagination ul li:hover a {
border-radius: 4px;
}
.testregister_detail {
padding: 40px 60px 40px 60px;
}
.testregister_detail label {
font-size: 20px;
}
.board_content {
padding: 10px;
line-height: 1.5;
@@ -1812,7 +1540,6 @@ figure div span {
}
.dev {
background-color : #f74140 !important;
color : white !important;
@@ -192,7 +192,6 @@
$('#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){
@@ -10,16 +10,15 @@
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>
<h5 th:if="${mockRoute.id == null}">API 정보 등록</h5>
<h5 th:if="${mockRoute.id != null}">API 정보 수정</h5>
</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/>
th:classappend="${#fields.hasErrors('name')}? 'is-invalid'" th:field="*{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>
@@ -53,134 +52,45 @@
<div class="card mt-2">
<div class="card-header">
<div class="d-flex justify-content-between">
<h3>응답</h3>
<h5>응답</h5>
<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 class="card-body" >
<div id="responses">
<div class="row" th:each="response, status: *{responses}">
<input type="number" th:field="*{responses[__${status.index}__].statusCode}" required/>
<textarea th:field="*{responses[__${status.index}__].body}"></textarea>
<input type="number" th:field="*{responses[__${status.index}__].delay}" required/>
<input type="text" th:field="*{responses[__${status.index}__].defaultResponse}" />
<ul class="response_conditions">
<li th:each="condition, status: *{responses[__${status.index}__].conditions}">
<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>
<input type="text" name="key" th:value="${condition.key}"/>
<input type="text" name="value" th:value="${condition.value}"/>
</li>
</ul>
<ul class="response_headers">
<li th:each="header, status: *{responses[__${status.index}__].headers}">
<input type="text" name="key" th:value="${header.key}"/>
<input type="text" name="value" th:value="${header.value}"/>
</li>
</ul>
</div>
</div>
<ul class="nav nav-tabs" id="responseTabTitle" role="tablist">
<li class="nav-item" role="presentation">
</li>
</ul>
<div class="tab-content" id="responseTabContent">
</div>
</div>
<div class="card-footer">
<button type="button" class="btn btn-primary btn_list"><i class="fa-solid fa-list"></i> 목록</button>
@@ -190,122 +100,129 @@
</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 id="template" style="visibility: hidden; height: 0;">
<div class="tab-pane" role="tabpanel">
<!-- <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>-->
<!-- </div>-->
<div class="row mt-1">
<div class="col-md">
<div class="card">
<div class="card-header">
<div class="d-flex justify-content-between">
<span>조건 항목</span>
</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">
<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>
<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 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>
<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 Variable</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>
@@ -318,20 +235,23 @@
name: '',
method: '',
pathPattern: '',
responses: [
]
responses: []
};
let view = {
currentIdx: 0,
init: function () {
$('.btn_add_case').on('click', function () {
controller.addResponse();
});
$('#responses').on('click', 'button', function () {
$('#responseTabTitle').on('click', 'button', function () {
if ($(this).hasClass('btn_remove_case')) {
controller.removeResponse($(this).attr("data-id"));
}
});
$('#responseTabContent').on('click', 'button', function () {
if ($(this).hasClass('btn_add_condition')) {
controller.addResponseCondition($(this).attr("data-id"));
}
@@ -349,16 +269,17 @@
}
});
$('#responses').children().each(function(){
$('#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.defaultResponse = $(this).find('input[name$="defaultResponse"]').val()==='true';
response.body = $(this).find('textarea[name$="body"]').val();
$(this).find('.response_conditions').children().each(function(){
$(this).find('.response_conditions').children().each(function () {
let condition = {
type: $(this).find('select').val(),
key: $(this).find('input[name$="key"]').val(),
@@ -369,7 +290,7 @@
model.responses.push(response);
$(this).find('.response_headers').children().each(function(){
$(this).find('.response_headers').children().each(function () {
let header = {
key: $(this).find('input[name$="key"]').val(),
value: $(this).find('input[name$="value"]').val()
@@ -378,13 +299,46 @@
});
});
$('#responses').empty();
this.render();
},
render: function () {
$('#responses').empty();
$('#responseTabTitle').empty();
$('#responseTabContent').empty();
for (let i = 0; i < model.responses.length; i++) {
let nodeCopy = $('#template').children().clone();
nodeCopy.find('.condition_name').text('조건 ' + (i + 1));
let tabButton = $('<a>').attr('class', 'nav-link'+ (model.responses[i].defaultResponse? ' active' : ''))
.attr('data-bs-toggle', 'tab')
.attr('type', 'button')
.attr('data-bs-target', '#response_tab_' + i)
.attr('role', 'tab')
.attr('aria-controls', 'response_tab_' + i)
.attr('aria-selected', 'false')
.text(model.responses[i].defaultResponse?'기본 응답':('조건 ' + (i + 1)));
// let minusButton = $('<button>').attr('class', 'btn btn-sm btn_remove_case')
// .attr('type', 'button')
// .attr('data-id', i)
// .html('<i class="fa fa-minus-circle"></i>');
let li = $('<li>').attr('class', 'nav-item')
.attr('role','presentation')
.append(tabButton);
// .append(minusButton);
$('#responseTabTitle').append(li);
nodeCopy.attr('id', 'response_tab_' + i);
nodeCopy.attr('aria-labelledby', 'response_tab_' + i);
nodeCopy.attr('tabindex', i);
nodeCopy.attr('class', 'tab-pane fade ' + (model.responses[i].defaultResponse? 'show active' : ''));
if (model.responses[i].defaultResponse) {
nodeCopy.find('.condition_name').text('기본 응답');
}else {
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);
@@ -396,21 +350,21 @@
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() {
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() {
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() {
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++){
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');
@@ -422,45 +376,49 @@
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() {
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() {
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() {
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++){
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('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() {
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() {
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);
}
$('#responseTabContent').append(nodeCopy);
}
console.log('#responseTabTitle li:eq(' + view.currentIdx + ') a');
console.log("render: " + view.currentIdx);
$('#responseTabTitle li:eq(' + view.currentIdx + ') a').tab('show');
// console.log(model);
}
};
@@ -479,11 +437,12 @@
view.render();
},
removeResponse: function (idx) {
if (model.responses.length === 1) {
alert('최소 1개의 응답이 필요합니다.');
if (model.responses[idx].defaultResponse) {
alert('기본 응답은 삭제할 수 없습니다.');
return;
}
model.responses.splice(idx, 1);
view.currentIdx = 0;
view.render();
},
addResponseCondition: function (idx) {
@@ -492,21 +451,25 @@
key: '',
value: ''
});
view.currentIdx = idx;
view.render();
},
removeResponseCondition: function (idx, conditionIdx) {
model.responses[idx].conditions.splice(conditionIdx, 1);
view.currentIdx = idx;
view.render();
},
addResponseHeader : function(idx) {
addResponseHeader: function (idx) {
model.responses[idx].headers.push({
key: '',
value: ''
});
view.currentIdx = idx;
view.render();
},
removeResponseHeader : function(idx, headerIdx) {
removeResponseHeader: function (idx, headerIdx) {
model.responses[idx].headers.splice(headerIdx, 1);
view.currentIdx = idx;
view.render();
}
}