Files
eapim-admin/WebContent/jsp/onl/transaction/apim/apiInterfaceManDetail.jsp
T
2026-06-16 14:19:27 +09:00

2191 lines
110 KiB
Plaintext

<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ page import="java.io.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", "0");
%>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script defer src="<c:url value="/addon/alpinejs-3.14.3/alpinejs.min.js"/>"></script>
<jsp:include page="/jsp/common/include/css.jsp"/>
<jsp:include page="/jsp/common/include/script.jsp"/>
<link href="<c:url value="/addon/bootstrap-5.3.2/css/bootstrap.min.css"/>" rel="stylesheet" />
<script src="<c:url value="/addon/bootstrap-5.3.2/js/bootstrap.bundle.min.js"/>"></script>
<link href="<c:url value="/addon/select2-4.1.0/css/select2.min.css"/>" rel="stylesheet" />
<link href="<c:url value="/addon/select2-4.1.0/css/select2-bootstrap.min.css"/>" rel="stylesheet" />
<script src="<c:url value="/addon/select2-4.1.0/js/select2.min.js"/>"></script>
<link href="<c:url value="/addon/bootstrap5-toggle-5.0.6/css/bootstrap5-toggle.min.css"/>" rel="stylesheet" />
<script src="<c:url value="/addon/bootstrap5-toggle-5.0.6/js/bootstrap5-toggle.jquery.min.js"/>"></script>
<link href="<c:url value="/addon/bootstrap-icons-1.11.3/bootstrap-icons.min.css"/>" rel="stylesheet" />
<script src="<c:url value="/addon/jquery-validation-1.19.5/jquery.validate.min.js"/>"></script>
<script src="<c:url value="/addon/jquery-validation-1.19.5/localization/messages_ko.min.js"/>"></script>
<script src="<c:url value="/addon/jquery-confirm/jquery-confirm.min.js"/>"></script>
<link href="<c:url value="/addon/jquery-confirm/jquery-confirm.min.css"/>" rel="stylesheet" />
<style>
label{
color:#003c78
}
.tooltip-inner {
min-width: 300px; /* the minimum width */
}
.form-check-input{
margin-left: 0px;
}
.form-check-label{
margin-left: 1.25rem;
}
input[readonly] {
background-color: #eeeeee;
border-color: #cccccc;
}
/* input-group 안에서 invalid-feedback이 차지하는 공간 없애기, 유효성검사 할 때 현재 스타일 바뀌지않게 CSS 처리 */
.input-group > .invalid-feedback {
position: absolute;
top: 100%;
left: 0;
width: 100%;
margin-top: .25rem;
}
.input-group {
position: relative;
}
/* 어댑터, 메서드 select2 사용시 width 깨짐 방지 */
.select2-container {
width: 100% !important;
box-sizing: border-box;
}
/* 버튼 내용이 길어질 경우 말줄임표(...) 처리 */
.btn-ellipsis {
max-width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
vertical-align: middle;
}
</style>
<script language="javascript" >
var isDetail = false;
var url ='<c:url value="/onl/transaction/apim/apiInterfaceMan.json" />';
const url_excel ='<c:url value="/onl/transaction/apim/apiInterfaceMan.excel" />';
var url_spec = '<c:url value="/onl/transaction/apim/apiSpecMan.view"/>';
var returnUrl ;
let headerValues = [];
let headerNames = [];
let stdCommonFieldDefinitions = [];
let standardMessageItems = [];
let inboundResponseStandardMessageItems = [];
let currentStandardMessageType = ''; // 현재 다이얼로그가 처리하는 메시지 타입을 추적
let isHeaderRouting = false;
let fromAdapterMessageKeyMap ;
var jsonUrl ;
$.fn.select2.defaults.set( "theme", "bootstrap" );
document.addEventListener('alpine:init', () => {
Alpine.data('apiInterfaceManager', () => ({
// ApiInterfaceUI 데이터 모델
apiInterface: {
sevrLogLvelNo: null,
eaiBzwkDstcd: '',
sendRecvType: '',
inOutType: null,
eaiSvcDesc: '',
fromAdapter: '',
toAdapter: '',
inboundHttpMethod: '',
inboundRestPath: '',
outboundHttpMethod: '',
outboundRestPath: '',
inboundRequestLayout: '',
requestTransform: '',
outboundRequestLayout: '',
inboundResponseLayout: '',
responseTransform: '',
outboundResponseLayout: '',
eaiSvcName: '',
transformYn: 'N',
toutVal: null,
simYn: 'N',
apiEnabledYn: 'N',
authType: '',
isHeaderRouting: false,
standardMessageItems: [],
inboundResponseStandardMessageItems: [],
fromResponseAdapter: '',
toResponseAdapter: '',
inboundResponseHttpMethod: '',
inboundResponseRestPath: '',
outboundResponseHttpMethod: '',
outboundResponseRestPath: '',
syncAsyncType: 'sync',
wordType: '1',
requestType:'S'
},
// 컴퓨티드 프로퍼티
get showInboundResponse() {
return this.apiInterface.syncAsyncType === 'asyncSync';
},
// 컴퓨티드 프로퍼티
get showOutboundResponse() {
return this.apiInterface.syncAsyncType === 'syncAsync';
},
}));
// 요청/응답 disable 처리.
Alpine.store('formState', {
isReqResDisabled: false
});
});
// Alpine 컴포넌트 접근을 위한 유틸리티 함수
function getApiInterface() {
const form = document.querySelector('#ajaxForm');
const xDataObject = form._x_dataStack[0].apiInterface;
return xDataObject;
}
function init(url,key,callback){
$('#checkApiCacheUrlKey').on('click', function(e) {
e.preventDefault();
});
$.ajax({
type : "POST",
url:url,
dataType:"json",
data:{cmd: 'LIST_DETAIL_COMBO'},
success:function(json){
new makeOptions("BIZCODE","BIZNAME").setObj($("select[name=eaiBzwkDstcd]")).setData(json.bizList).setFormat(codeName3OptionFormat).rendering();
new makeOptions("BIZCODE","BIZNAME").setObj($("select[name=newBizCode]")).setData(json.bizList).setFormat(codeName3OptionFormat).rendering();
new makeOptions("ADPTRBZWKGROUPNAME","ADPTRBZWKGROUPDESC").setObj($("select[name=fromAdapter]")).setFormat(codeName3OptionFormat).setNoValueInclude(true).setAttr('std','ADPTRMSGPTRNCD').setData(json.fromList).rendering();
new makeOptions("ADPTRBZWKGROUPNAME","ADPTRBZWKGROUPDESC").setObj($("select[name=fromResponseAdapter]")).setFormat(codeName3OptionFormat).setNoValueInclude(true).setData(json.toList).rendering();
new makeOptions("ADPTRBZWKGROUPNAME","ADPTRBZWKGROUPDESC").setObj($("select[name=toAdapter]")).setFormat(codeName3OptionFormat).setNoValueInclude(true).setData(json.toList).rendering();
new makeOptions("ADPTRBZWKGROUPNAME","ADPTRBZWKGROUPDESC").setObj($("select[name=toResponseAdapter]")).setFormat(codeName3OptionFormat).setNoValueInclude(true).setData(json.fromList).rendering();
//if(key == "") setSearchable(selectName); // 콤보에 searchable 설정
if (typeof callback === 'function') {
callback(url,key);
}
$('#eaiBzwkDstcd').select2();
$('#fromAdapter').select2();
$('#toAdapter').select2();
$('#fromResponseAdapter').select2();
$('#toResponseAdapter').select2();
$('#inboundHttpMethod').select2();
$('#outboundHttpMethod').select2();
$('#newBizCode').select2({
dropdownParent: $('#cloneInterfaceModal'),
width: '100%'
});
$('#newInboundHttpMethod').select2({
dropdownParent: $('#cloneInterfaceModal'),
width: '100%'
});
fromAdapterMessageKeyMap = json.fromAdapterMessageKeyMap;
stdCommonFieldDefinitions = json.stdCommonFieldDefinitions;
initStdCommonFieldDefinitions(stdCommonFieldDefinitions);
},
error:function(e){
alert(e.responseText);
}
});
}
function getAdapterInfo(adapterGroupName){
return new Promise((resolve, reject) => {
$.ajax({
type: "POST",
url: jsonUrl,
dataType: "json",
data: { cmd: 'DETAIL_ADAPTER_INFO', adapterGroupName: adapterGroupName },
success: function(data) {
resolve(data);
},
error: function(e) {
reject(e);
}
});
});
}
function getAdapterMessageType(adapterGroupName){
let type;
$.ajax({
type : "POST",
url: jsonUrl,
dataType:"json",
async: false,
data:{cmd: 'DETAIL_ADAPTER_GROUP', adapterGroupName: adapterGroupName},
success:function(json){
switch (json.ADPTRMSGDSTCD) {
case 'UJN':
type = 'UJSON'; break;
case 'UXM':
type = 'UXML' ; break;
case 'JSN':
type = 'JSON'; break;
case 'ASC':
type = 'BYTES'; break;
default:
type = json.ADPTRMSGDSTCD; break;
}
},
});
return type;
}
// 어댑터 설정 정보 객체에 인바운드 응답 관련 설정 추가
const adapterConfig = {
inbound: {
ioType: 'inbound',
methodSelectId: '#inboundHttpMethod',
restPathInputId: '#inboundRestPath',
adapterUrlId: '#fromAdapterUrl',
},
outbound: {
ioType: 'outbound',
methodSelectId: '#outboundHttpMethod',
restPathInputId: '#outboundRestPath',
adapterUrlId: '#toAdapterUrl',
standardOptionsId: '#standardOutboundOptions',
commonFieldId: '#commonFieldPart'
},
inboundResponse: {
methodSelectId: '#inboundResponseHttpMethod',
restPathInputId: '#inboundResponseRestPath',
adapterUrlId: '#fromResponseAdapterUrl',
standardOptionsId: '#inboundResponseRestPart',
commonFieldId: '#inboundResponseCommonFieldPart'
},
outboundResponse: {
methodSelectId: '#outboundResponseHttpMethod',
restPathInputId: '#outboundResponseRestPath',
adapterUrlId: '#toResponseAdapterUrl',
standardOptionsId: '#outboundResponseRestPart'
}
};
// 어댑터 선택 변경 시 호출되는 함수 수정
async function adapterSelectChange(adapterType, adapterGroupName) {
const adapterSettings = adapterConfig[adapterType];
const adapterInfo = await getAdapterInfo(adapterGroupName);
const isStandardMessage = 'K' == adapterInfo.adapterMessageGroupType;
if(!isStandardMessage){
$(adapterSettings.adapterUrlId).text(adapterInfo.urlPath);
} else {
$(adapterSettings.methodSelectId).val('');
$(adapterSettings.restPathInputId).val('');
$(adapterSettings.adapterUrlId).text('');
}
$(adapterSettings.methodSelectId).prop('disabled', isStandardMessage);
$(adapterSettings.restPathInputId).prop('disabled', isStandardMessage);
// 표준전문 공통부 처리 (outbound와 inboundResponse에만 적용)
if (adapterType === 'outbound' || adapterType === 'inboundResponse') {
if(isStandardMessage) {
$(adapterSettings.standardOptionsId).hide();
$(adapterSettings.commonFieldId).show();
} else {
$(adapterSettings.standardOptionsId).show();
$(adapterSettings.commonFieldId).hide();
}
}
}
function setHeaderRoutingLabel(){
let label = headerNames.map(function(name, index) {
const value = headerValues[index];
return name + '=' + value;
}).join(';');
if(headerValues.length > 0){
$("#headerRoutingButton").text('MessageKey ['+label+']');
}else{
$("#headerRoutingButton").text('MessageKey 라우팅 정보 없음');
}
}
function setStandardMessageItemsLabel(items, buttonId) {
const label = items.map(function(item) {
return item.COLUMNNAME + '=' + item.COLUMNVALUE;
}).join(';');
const $btn = $('#' + buttonId);
if (items.length > 0) {
$btn.text('수정 [' + label + ']');
$btn.attr('title', '수정 [' + label + ']');
$btn.addClass('btn-ellipsis');
} else {
$btn.text('수정');
$btn.removeAttr('title');
$btn.removeClass('btn-ellipsis');
}
}
function setupStdCommonValueModal(type) {
currentStandardMessageType = type;
$('#stdCommonValuePairs input').val('');
const items = type === 'outbound' ? standardMessageItems : inboundResponseStandardMessageItems;
items.forEach(function(item) {
$('#stdCommonValuePairs input[columnname="'+item.COLUMNNAME+'"]').val(item.COLUMNVALUE);
});
}
function initStdCommonFieldDefinitions(stdCommonFieldDefinitions){
// 기존의 모든 헤더 항목을 제거합니다.
$('#stdCommonValuePairs').empty();
stdCommonFieldDefinitions.forEach(function(stdCommonFieldDefinition) {
addStdCommonFieldDefinitions(stdCommonFieldDefinition);
});
}
function addStdCommonFieldDefinitions(stdCommonFieldDefinition) {
let fieldName = stdCommonFieldDefinition.COLUMNNAME+' ['+stdCommonFieldDefinition.COLUMNDESC+']';
if('Y' === stdCommonFieldDefinition.ISKEY){
fieldName += '[*]'
}
const newPairHtml = '<div class="row align-items-center header-pair">' +
'<div class="col" style="text-align: right;">' +
'<label class="form-label">' + fieldName + '</label>' +
'</div>' +
'<div class="col">' +
'<input type="text" class="form-control mb-2" name="stdCommonFieldValue" columnname="'+stdCommonFieldDefinition.COLUMNNAME+'" placeholder="'+stdCommonFieldDefinition.COLUMNDESC+' 필드 값">' +
'</div>' +
'</div>';
$('#stdCommonValuePairs').append(newPairHtml);
}
function initHeaders(headerNames){
// 기존의 모든 헤더 항목을 제거합니다.
$('#headerPairs').empty();
headerNames.forEach(function(headerName) {
addHeader(headerName);
});
}
function addHeader(headerName) {
const newPairHtml = '<div class="row align-items-center header-pair">' +
'<div class="col" style="text-align: right;">' +
'<label class="form-label">' + headerName + '</label>' +
'</div>' +
'<div class="col">' +
'<input type="text" class="form-control mb-2" name="headerValue" placeholder="MessageKey 값">' +
'</div>' +
'</div>';
$('#headerPairs').append(newPairHtml);
}
function detail(url,key){
jsonUrl = url;
if (!isDetail)return;
// $("input[name='btnRadioSyncAsync']").attr('disabled', true);
$.ajax({
type : "POST",
url:url,
dataType:"json",
data:{cmd: 'DETAIL', eaiSvcName : key},
success:function(json){
var data = json;
// Alpine 데이터 모델 업데이트
const apiInterface = getApiInterface();
Object.assign(apiInterface, data);
// $("input[name='btnRadioSyncAsync']").attr('disabled', true);
$("input[name=eaiSvcName]").attr('readonly',true);
$("#ajaxForm input, #ajaxForm textarea").each(function(){
const name = $(this).attr("name");
const tag = $(this).prop("tagName").toLowerCase();
const type = $(this).prop("type").toLowerCase();
if(type === 'radio'){
return;
}
$(tag+"[name="+name+"]").val(data[name]);
});
if(data.standardMessageItems != null) {
standardMessageItems = data.standardMessageItems;
setStandardMessageItemsLabel(standardMessageItems, 'standardMessageItemsButton');
}
if(data.inboundResponseStandardMessageItems != null) {
inboundResponseStandardMessageItems = data.inboundResponseStandardMessageItems;
setStandardMessageItemsLabel(inboundResponseStandardMessageItems, 'inboundResponseStandardMessageItemsButton');
}
$("select[name=eaiBzwkDstcd]" ).val(data["eaiBzwkDstcd"]);//업무구분코드
$("select[name=fromAdapter]" ).val(data["fromAdapter"]);//fromAdapter
$("select[name=toAdapter]" ).val(data["toAdapter"]);//toAdapter
if(data["authType"] != null && data["authType"].trim() != ''){
$("select[name=authType]" ).val(data["authType"]);
}
$("select[name=fromResponseAdapter]" ).val(data["fromResponseAdapter"]);//fromResponseAdapter
$("select[name=toResponseAdapter]" ).val(data["toResponseAdapter"]);//toResponseAdapter
$('#inboundHttpMethod').val(data.inboundHttpMethod);
$('#outboundHttpMethod').val(data.outboundHttpMethod);
$('#inboundResponseHttpMethod').val(data.inboundResponseHttpMethod);
$('#outboundResponseHttpMethod').val(data.outboundResponseHttpMethod);
$('#svcLogLvelNo').val(data.svcLogLvelNo);
if(data['inboundRequestLayout']!=null && data['outboundRequestLayout']!=null){
$('#requestTransform').removeAttr('disabled');
}
if(data['inboundResponseLayout']!=null && data['outboundResponseLayout']!=null){
$('#responseTransform').removeAttr('disabled');
}
if('Y' == data.transformYn){
$('#toggleTransformYn').bootstrapToggle('on');
}
if('Y' == data.simYn){
$('#toggleSimYn').bootstrapToggle('on');
}
if('Y' == data.apiEnabledYn){
$('#toggleApiEnabledYn').bootstrapToggle('on');
}
if('Y' == data.apiCacheYn){
$('#toggleApiCacheYn').bootstrapToggle('on');
}
if(data.apiCacheType != null && data.apiCacheType.includes("P")){
$('#checkApiCacheParamKey').prop('checked', true);
}
if(data.errResponseTransform != null && data.errResponseTransform != '' && data.errTransformYn == 'Y') {
$('#toggleErrTransformYn').bootstrapToggle('on');
$('#rowErrResponseTransform').show();
} else {
$('#toggleErrTransformYn').bootstrapToggle('off');
$('#rowErrResponseTransform').hide();
}
$('#eaiBzwkDstcd').trigger('change');
transformSetStateChange();
const interfaceId = data['eaiSvcName'].slice(0, -2);
$('#eaiSvcName').val(interfaceId);
const sendRecvType = data['eaiSvcName'].slice(-2, -1);
$('#sendRecvType').val(sendRecvType);
const inOutType = data['eaiSvcName'].slice(-1);
$('#inOutType').val(inOutType);
$("input[name=btnRadioReqRes][value='" + sendRecvType + "']").prop("checked", true);
Alpine.store('formState').isReqResDisabled = true;
$("input[name=btnRadioInOut][value='" + inOutType + "']").prop("checked", true);
$("input[name=btnRadioInOut]").prop("disabled", true);
$('#eaiBzwkDstcd').attr("readonly", "readonly");
$('#eaiSvcName').attr("readonly", "readonly");
$('#sendRecvType').attr("readonly", "readonly");
$('#inOutType').attr("readonly", "readonly");
checkTagVariableUrl();
setInboundRoutingSlide();
if(json.headerValues != null){
headerValues = json.headerValues;
}
setHeaderRoutingLabel();
$("#fromAdapter").change();
$("#toAdapter").change();
const eaiSvcName = $('#eaiSvcName').val();
$('#cloneOrgInterfaceIdDesc').text(eaiSvcName);
$("#fromResponseAdapter").change();
$("#toResponseAdapter").change();
$("#apiFullPath").val(data["apiFullPath"]); // 스펙 전달용 값
$('#inboundHttpMethod').trigger('change');
$('#outboundHttpMethod').trigger('change');
},
error:function(e){
alert(e.responseText);
}
});
}
function layoutBtnStateChange(part){
const value = $('#'+part+'Layout').val();
if(value){
$('#'+part+'Button').text('수정');
}else{
$('#'+part+'Button').text('생성');
}
}
function mappingBtnStateChange(part){
const transformName = (part === 'ErrResponse' ? 'errResponse' : part.toLowerCase()) + 'Transform';
const inboundLayoutName = part === 'ErrResponse' ?
$('#inboundErrResponseLayout').val() :
$('#inbound'+part+'Layout').val();
const outboundLayoutName = part === 'ErrResponse' ?
$('#outboundErrResponseLayout').val() :
$('#outbound'+part+'Layout').val();
const value = $('#'+transformName).val();
if(value){
$('#'+transformName+'Button').text('수정');
}else{
$('#'+transformName+'Button').text('생성');
}
const isEnabled = value || (inboundLayoutName != null && inboundLayoutName != ''
&& outboundLayoutName != null && outboundLayoutName != '');
if(isEnabled && (part !== 'ErrResponse' || $('#toggleErrTransformYn').prop('checked'))){
$('#'+transformName+'Button').removeClass('btn-secondary').addClass('btn-primary');
$('#'+transformName+'ButtonTooltip').tooltip('disable');
$('#'+transformName+'Button').attr('disabled', false);
$('#'+transformName+'Button').css('pointer-events','all');
}else{
$('#'+transformName+'Button').removeClass('btn-primary').addClass('btn-secondary');
$('#'+transformName+'ButtonTooltip').tooltip('enable')
$('#'+transformName+'Button').css('pointer-events','none');
$('#'+transformName+'Button').attr('disabled', true);
}
}
function transformSetStateChange(){
layoutBtnStateChange('inboundRequest');
layoutBtnStateChange('outboundRequest');
layoutBtnStateChange('inboundResponse');
layoutBtnStateChange('outboundResponse');
mappingBtnStateChange('Request');
mappingBtnStateChange('Response');
layoutBtnStateChange('inboundErrResponse');
layoutBtnStateChange('outboundErrResponse');
mappingBtnStateChange('ErrResponse');
}
function addLayoutBtnEvent(part, desc, target){
$('#'+part+'Button').on("click", function(event) {
modifyLayout(''+part+'Layout', desc, target)
});
}
function openLayoutPopup(layoutPartName){
var isLayoutView = $('#toggleLayoutView').prop('checked');
const layoutName = $('#'+layoutPartName).val();
var args = {title:layoutName+' 수정', parent: true};
var url='<c:url value="/onl/admin/rule/layoutMan.view"/>';
url += '?cmd=DETAIL';
url += '&loutName='+layoutName;
url += '&layoutPartName='+layoutPartName;
url += '&pop=true';
url += '&isLayoutView=' + isLayoutView;
const width = parent.document.body.clientWidth - 30;
const height = parent.document.body.clientHeight - 30;
showModal(url,args,width,height,null,{fullScreenPopup:true});
}
function getFullSvcName(){
return $('#eaiSvcName').val()+$('#sendRecvType').val()+$('#inOutType').val();
}
function openTransformPopup(transformName, transformDesc){
const svcName = getFullSvcName();
const svcDesc = encodeURI(encodeURIComponent($('#eaiSvcDesc').val()));
const cnvsnDesc = encodeURI(encodeURIComponent(transformDesc));
var args = {title:transformName+' 수정', parent: true};
var url='<c:url value="/onl/admin/rule/transform2/transform2Man.view"/>';
url += '?cmd=DETAIL';
url += '&cnvsnName='+transformName;
url += '&eaiSvcName='+svcName;
url += '&eaiSvcDesc='+svcDesc;
url += '&cnvsnDesc='+cnvsnDesc;
url += '&pop=true';
const width = parent.document.body.clientWidth - 30;
const height = parent.document.body.clientHeight - 30;
showModal(url,args,width,height,null,{fullScreenPopup: true});
}
function afterCreatedApi(){
$("img[level='W'][status*=DETAIL]").show();
$("img[level='R'][status*=DETAIL]").show();
$("#btn_modify").attr('src',"<c:url value='/img/btn_modify.png'/>");
isDetail = true;
$("input[name=eaiSvcName]").attr('readonly',true);
}
function modifyLayout(layoutPartName, layoutPartDesc, layoutPostFix){
if(!isDetail){
function createApiAction(){
modifyApi(afterCreatedApi);
}
$.confirm({
title: 'API 저장',
columnClass: 'medium',
content: '레이아웃을 생성하기 전에 API를 저장해야 합니다. 저장하시겠습니까? <br> 업무코드['+$('#eaiBzwkDstcd').val()+'] API 명 ['+getFullSvcName()+']',
buttons: {
confirm: {
text: '저장',
btnClass: 'btn-blue',
action: createApiAction
},
cancel: {
text: '취소',
}
}
});
return;
}
const layoutName = $('#'+layoutPartName).val();
const bizCd = $('#eaiBzwkDstcd').val();
const svcName = getFullSvcName();
const layoutDesc = $('#eaiSvcDesc').val()+" ("+layoutPartDesc+")";
if(layoutName == null || layoutName == ''){
const newLayoutName = bizCd+'_'+svcName+'_'+layoutPostFix;
// 어댑터 선택 로직 수정
let adapterGroupName;
if(layoutPartName.startsWith('inbound')){
// asyncSync 타입일 때는 fromResponseAdapter 사용
if(getApiInterface().syncAsyncType === 'asyncSync' && layoutPartName.endsWith('ResponseLayout')){
adapterGroupName = $('#fromResponseAdapter').val();
} else {
adapterGroupName = $('#fromAdapter').val();
}
} else {
adapterGroupName = $('#toAdapter').val();
}
if(adapterGroupName == null || adapterGroupName == ""){
alert('어댑터가 선택되지 않았습니다. 확인하세요');
return;
}
const messageType = getAdapterMessageType(adapterGroupName);
function newLayoutAction(){
var args = new Object();
const layoutUrl ='<c:url value="/onl/admin/rule/layoutMan.json" />';
const postData = {
cmd: 'INSERT',
layoutItems: '[]',
loutPtrnName: messageType,
loutName: newLayoutName,
loutDesc: layoutDesc,
eaiBzwkDstcd: bizCd,
eaiSevrDstcd: 'A',
useYn: '1',
};
$.ajax({
type : "POST",
url: layoutUrl,
data: postData,
success:function(){
alert("생성완료");
$('#'+layoutPartName).val(newLayoutName);
transformSetStateChange();
openLayoutPopup(layoutPartName);
},
error:function(e){
alert(e.responseText);
}
});
}
$.confirm({
title: '신규 레이아웃 생성',
columnClass: 'medium',
content: layoutPartDesc+' 레이아웃을 생성하시겠습니까? <br> 생성 레이아웃 명 ['+newLayoutName+'] 타입['+messageType+']',
buttons: {
confirm: {
text: '생성',
btnClass: 'btn-blue',
action: newLayoutAction
},
cancel: {
text: '취소',
}
}
});
}else{
openLayoutPopup(layoutPartName);
}
}
function modifyTransform(reqResType){
if($('#'+reqResType+'TransformButton').attr('disabled')){
return;
}
const transformName = $('#'+reqResType+'Transform').val();
let transformDescSubfix;
let bizCd = $('#eaiBzwkDstcd').val();
let svcName = getFullSvcName();
let cnvsnType;
let srcLayoutName;
let tgtLayoutName;
// 오류변환과 일반변환 구분하여 설정
if(reqResType === 'errResponse') {
transformDescSubfix = '오류변환';
cnvsnType = 'ERR';
srcLayoutName = $('#outboundErrResponseLayout').val();
tgtLayoutName = $('#inboundErrResponseLayout').val();
} else {
transformDescSubfix = reqResType === 'request' ? '요청매핑' : '응답매핑';
cnvsnType = reqResType === 'request' ? 'REQ' : 'RES';
srcLayoutName = reqResType === 'request' ? $('#inboundRequestLayout').val() : $('#outboundResponseLayout').val();
tgtLayoutName = reqResType === 'request' ? $('#outboundRequestLayout').val() : $('#inboundResponseLayout').val();
}
const transformDesc = $('#eaiSvcDesc').val()+" ("+transformDescSubfix+")";
if(!transformName?.trim()){
const newTransformName = 'TRANSFORM_'+bizCd+'_'+svcName+'_'+cnvsnType;
function updateFirstLayout(newTransformName, transformDesc){
$.ajax({
type : "POST",
url: '<c:url value="/onl/admin/rule/transform2/transform2Man.json" />',
data: { cmd: 'UPDATE',
gridData: '[]',
eaiSvcName: svcName,
cnvsnName: newTransformName,
cnvsnDesc: transformDesc,
cnvsnType,
chkForce: false,
srcLayoutName,
tgtLayoutName,
},
success:function(){
openTransformPopup(newTransformName, transformDesc);
},
error:function(e){
alert(e.responseText);
}
});
}
function newTransformAction(){
var args = new Object();
const postData = {
cmd: 'INSERT',
gridData: '[]',
cnvsnType,
eaiSvcName: svcName,
cnvsnName: newTransformName,
cnvsnDesc: transformDesc
};
$.ajax({
type : "POST",
url: '<c:url value="/onl/admin/rule/transform2/transform2Man.json" />',
data: { cmd: 'INSERT',
gridData: '[]',
cnvsnType,
eaiSvcName: svcName,
cnvsnName: newTransformName,
cnvsnDesc: transformDesc
},
success:function(){
alert("생성완료");
$('#'+reqResType+'Transform').val(newTransformName);
transformSetStateChange();
updateFirstLayout(newTransformName, transformDesc);
},
error:function(e){
alert(e.responseText);
}
});
}
$.confirm({
title: '신규 '+transformDescSubfix+' 생성',
columnClass: 'medium',
content: transformDescSubfix+'을 생성하시겠습니까? <br> 생성 매핑 룰 명 ['+newTransformName+']',
buttons: {
confirm: {
text: '생성',
btnClass: 'btn-blue',
action: newTransformAction
},
cancel: {
text: '취소',
}
}
});
}else{
openTransformPopup(transformName, transformDesc);
}
}
function modifyApi(callback){
//if (!isValid())return;
//업무추출키 control
if(!$("#ajaxForm").valid()){
return;
}
if ($("select[name=fromAdapter] option:selected").attr("std") == "K"){
//표준일경우 업무추출키 삭제되어야 됨
$("input[name=bzwkSvcKeyName]").val("");
}else{
//표준이 아닐경우 업무추출키 셋팅되어야 됨
$("input[name=bzwkSvcKeyName]").val($("input[name=eaiTranName]").val());
}
// 사용자 편의를 위해 Path 앞에 "/" 는 제외, 복제도 포함.
$("input[name=inboundRestPath]").val(function(index, value) {
return value.replace(/^\/+/, "");
});
$("input[name=inboundResponseRestPath]").val(function(index, value) {
return value.replace(/^\/+/, "");
});
$("input[name=outboundRestPath]").val(function(index, value) {
return value.replace(/^\/+/, "");
});
$("input[name=outboundResponseRestPath]").val(function(index, value) {
return value.replace(/^\/+/, "");
});
var postData = $('#ajaxForm').serializeArray();
if (isDetail){
postData.push({ name: "cmd" , value:"UPDATE"});
}else{
postData.push({ name: "cmd" , value:"INSERT"});
}
postData.push({ name: "interfaceId" , value: $("input[name=eaiSvcName]").val()});
postData = postData.filter(obj => obj.name !== "eaiSvcName");
postData.push({ name: "eaiSvcName" , value: getFullSvcName()});
const apiEnabledYn = $('#toggleApiEnabledYn').prop('checked') ? 'Y' : 'N';
const transformYn = $('#toggleTransformYn').prop('checked') ? 'Y' : 'N';
const simYn = $('#toggleSimYn').prop('checked') ? 'Y' : 'N';
const apiCacheYn = $('#toggleApiCacheYn').prop('checked') ? 'Y' : 'N';
const errTransformYn = $('#toggleErrTransformYn').prop('checked') ? 'Y' : 'N';
const inboundMethod = $('#inboundHttpMethod').val();
const outboundMethod = $('#outboundHttpMethod').val();
if(apiCacheYn === 'Y'){
if(inboundMethod !== 'get'){
alert("인바운드 메소드가 GET 일 경우에만 API 캐시사용이 가능합니다.");
return;
}
if(outboundMethod !== 'get'){
alert("아웃바운드 메소드가 GET 일 경우에만 API 캐시사용이 가능합니다.");
return;
}
}
postData.push({ name: "apiEnabledYn" , value: apiEnabledYn});
postData.push({ name: "transformYn" , value: transformYn});
postData.push({ name: "errTransformYn" , value: errTransformYn}); // 추가
postData.push({ name: "simYn" , value: simYn});
postData.push({ name: "apiCacheYn" , value: apiCacheYn});
let apiCacheType = "U";
if($('#checkApiCacheParamKey').prop('checked')){
apiCacheType+="|P";
}
postData.push({ name: "apiCacheType" , value: apiCacheType});
postData.push({ name: "isHeaderRouting" , value: isHeaderRouting});
// postData.push({name: "headerRoutingPairs", value: JSON.stringify(headerRoutingPairs)})
headerValues.forEach(headerValue => {
postData.push({name: "headerValues[]", value: headerValue});
});
const syncAsyncType = getApiInterface().syncAsyncType;
postData.push({ name: "syncAsyncType" , value: syncAsyncType});
// standardMessageItems 배열 추가
for (let i = 0; i < standardMessageItems.length; i++) {
postData.push({ name: "standardMessageItems[" + i + "].columnname", value: standardMessageItems[i].COLUMNNAME });
postData.push({ name: "standardMessageItems[" + i + "].columnvalue", value: standardMessageItems[i].COLUMNVALUE });
}
// standardMessageItems 배열 추가
for (let i = 0; i < inboundResponseStandardMessageItems.length; i++) {
postData.push({ name: "inboundResponseStandardMessageItems[" + i + "].columnname", value: inboundResponseStandardMessageItems[i].COLUMNNAME });
postData.push({ name: "inboundResponseStandardMessageItems[" + i + "].columnvalue", value: inboundResponseStandardMessageItems[i].COLUMNVALUE });
}
$.ajax({
type: "POST",
url:url,
data: postData,
beforeSend: function() {
$("[id^='btn_']").prop("disabled", true);
$("#btn_modify").text("처리중 . . . . .");
},
success:function(message){
alert("저장 되었습니다. \n\n[실시간 반영 결과]\n"+JSON.stringify(message));
if (typeof callback === 'function') {
callback();
}else{
goNav(returnUrl);//LIST로 이동
}
},
error:function(xhr, status, errorMsg){
alert(JSON.parse(xhr.responseText).errorMsg);
},
complete: function() {
$("[id^='btn_']").prop("disabled", false);
$("#btn_modify").text("수정");
}
});
}
function setInboundRoutingSlide(){
const adapterGroupName = $("#fromAdapter").val();
const messageKeyList = fromAdapterMessageKeyMap[adapterGroupName]
if(messageKeyList != null && messageKeyList.length > 0){
headerNames = messageKeyList;
isHeaderRouting = true;
initHeaders(headerNames);
//$('#slideInboundRoutingRule').carousel(0);
$('#collapseInboundRoutingInfo').collapse('show')
setHeaderRoutingLabel();
}else{
isHeaderRouting = false;
$('#collapseInboundRoutingInfo').collapse('hide')
//$('#slideInboundRoutingRule').carousel(1);
}
}
function showApiSpecPopup() {
var eaiSvcName = getFullSvcName();
var eaiSvcDesc = $('#eaiSvcDesc').val();
var apipath = $('#apiFullPath').val();
var contentType = $('#contentType').val();
var args = {
title:'API 스펙 관리',
parent: true,
apipath : apipath,
eaiSvcDesc : eaiSvcDesc,
contentType : contentType
};
var popupUrl = url_spec + '?cmd=DETAIL&eaiSvcName=' + encodeURIComponent(eaiSvcName);
showModal(popupUrl, args, 1200, 800);
}
$(document).ready(function() {
makeValidate();
// var bootstrapButton = $.fn.button.noConflict()
// $.fn.bootstrapBtn = bootstrapButton;
returnUrl = getReturnUrlForReturn();
var key ="${param.eaiSvcName}";
key = decodeURIComponent(key);
if (key != "" && key !="null"){
isDetail = true;
}
init(url,key,detail);
$("#btn_api_spec").click(function() {
showApiSpecPopup();
});
$("#btn_modify").click(modifyApi);
$("#btn_delete").click(function(){
if(!confirm("삭제하시겠습니까?")){
return;
}
var postData = $('#ajaxForm').serializeArray();
postData.push({ name: "cmd" , value:"DELETE"});
// Alpine 컴포넌트에서 syncAsyncType 가져오기
const syncAsyncType = getApiInterface().syncAsyncType;
postData.push({ name: "syncAsyncType" , value: syncAsyncType});
postData = postData.filter(obj => obj.name !== "eaiSvcName");
postData.push({ name: "eaiSvcName" , value: getFullSvcName() });
$.ajax({
type : "POST",
url:url,
data:postData,
beforeSend: function() {
$("[id^='btn_']").prop("disabled", true);
$("#btn_delete").text("처리중 . . . . .");
},
success:function(args){
alert("삭제 되었습니다.");
goNav(returnUrl);//LIST로 이동
},
error:function(e){
alert(e.responseText);
},
complete: function() {
$("[id^='btn_']").prop("disabled", false);
$("#btn_delete").text("삭제");
}
});
});
$("#btn_previous").click(function(){
goNav(returnUrl);//LIST로 이동
});
function callDownload(cmd, targetName){
const fileName = targetName + '.txt';
const bzwkDstcd = $('#eaiBzwkDstcd').val();
const url = '<c:url value="/loader.do" />';
const postData = [];
postData.push({ name: "cmd" , value: cmd});
postData.push({ name: "control" , value:"download"});
postData.push({ name: "bzwkDstcd" , value: bzwkDstcd});
postData.push({ name: "fileName" , value: fileName});
return new Promise((resolve, reject) => {
$.ajax({
type: "POST",
url: url,
data: postData,
success: function (response) {
resolve(response);
},
error: function (error) {
reject(error);
}
});
});
}
async function doDownload(type, targetName){
if(targetName != null && targetName.trim() !== ''){
const response = await callDownload(type, targetName);
return '<br>'+targetName+".txt, msg: "+response.trim();
}
return '';
}
$("#btn_download").click(async function(){
try {
const interfaceId = getFullSvcName();
let response = await callDownload('interface', interfaceId);
let resultMessage = '[인터페이스]<br>'+interfaceId+".txt, msg: "+response.trim();
let layoutResultMessage = await doDownload('layout', $('#inboundRequestLayout').val());
layoutResultMessage += await doDownload('layout', $('#outboundRequestLayout').val());
layoutResultMessage += await doDownload('layout', $('#outboundResponseLayout').val());
layoutResultMessage += await doDownload('layout', $('#inboundResponseLayout').val());
if(layoutResultMessage != null && layoutResultMessage.trim() != ''){
resultMessage += '<br>[레이아웃]'+layoutResultMessage;
}
let transformResultMessage = await doDownload('transform', $('#requestTransform').val());
transformResultMessage += await doDownload('transform', $('#responseTransform').val());
if(transformResultMessage != null && transformResultMessage.trim() != ''){
resultMessage += '<br>[변환]'+transformResultMessage;
}
// alert(resultMessage);
// $.alert({
// columnClass: 'col-md-8',
// title: '다운로드 처리 결과',
// content: resultMessage,
// });
window.parent.callAlert('다운로드 처리 결과', resultMessage);
// 처리된 데이터로 무언가를 수행
} catch (error) {
console.error(error);
// 에러 처리
}
});
buttonControl(isDetail);
titleControl(isDetail);
$('#toggleApiCacheYn').change(function() {
if($(this).prop('checked')){
$('#collapseApiCache').collapse('show');
}else{
$('#collapseApiCache').collapse('hide');
}
})
$('#toggleTransformYn').change(function() {
if ($(this).prop('checked')) {
$('#toggleLayoutView').bootstrapToggle('off');
$('#toggleLayoutView').closest('.form-group').hide();
$('#collapseTransform').collapse('show');
$('#requestTransform').closest('.form-group').show();
$('#responseTransform').closest('.form-group').show();
} else {
$('#collapseTransform').collapse('hide');
$('#toggleLayoutView').closest('.form-group').show();
}
});
$('#toggleLayoutView').change(function() {
if ($('#toggleTransformYn').prop('checked')) {
return;
}
if ($(this).prop('checked')) {
$('#collapseTransform').collapse('show');
$('#requestTransform').closest('.form-group').hide();
$('#responseTransform').closest('.form-group').hide();
} else {
$('#collapseTransform').collapse('hide');
$('#requestTransform').closest('.form-group').show();
$('#responseTransform').closest('.form-group').show();
}
});
if ($('#toggleTransformYn').prop('checked')) {
$('#toggleLayoutView').closest('.form-group').hide();
} else {
$('#toggleLayoutView').closest('.form-group').show();
}
$('#toggleErrTransformYn').change(function() {
if($(this).prop('checked')){
$('#rowErrResponseTransform').show();
}else{
$('#rowErrResponseTransform').hide();
}
mappingBtnStateChange('ErrResponse');
});
$('#rowErrResponseTransform').hide();
$('#toggleSimYn').change(function() {
if($(this).prop('checked')){
$('#slideOutboundAdapter').carousel(0);
}else{
$('#slideOutboundAdapter').carousel(1);
}
});
$('[data-bs-toggle="tooltip"]').tooltip();
addLayoutBtnEvent('inboundRequest', '인바운드 요청', 'SRCS');
addLayoutBtnEvent('outboundRequest', '아웃바운드 요청', 'TGTS');
addLayoutBtnEvent('outboundResponse', '아웃바운드 응답', 'TGTR');
addLayoutBtnEvent('inboundResponse', '인바운드 응답', 'SRCR');
addLayoutBtnEvent('inboundErrResponse', '인바운드 오류', 'SRCE');
addLayoutBtnEvent('outboundErrResponse', '아웃바운드 오류', 'TGTE');
window.addEventListener('message', function(e) {
if (e.origin !== window.location.origin) return;
const popupMessage = e.data;
if (!popupMessage) return;
if ('DELETE' == popupMessage.cmd) {
if ('layout' == popupMessage.type) {
$('#' + popupMessage.layoutPartName).val('');
}
if ('transform' == popupMessage.type) {
const partName = popupMessage.transformName.endsWith('REQ') ? '#requestTransform' : '#responseTransform';
$(partName).val('');
}
transformSetStateChange();
return;
}
if(popupMessage.isLayoutView == "false") {
// 레이아웃 저장 후 변환 팝업 자동 실행 로직
if (popupMessage.action === 'LAYOUT_SAVED_OPEN_TRANSFORM') {
// 눈이 보이지않는 팝업창 popup창 닫기
if ($('.ui-dialog-content').length > 0) {
$('.ui-dialog-content').dialog('close');
}
const part = popupMessage.layoutPartName || "";
setTimeout(function() {
if (part.includes('Request')) {
modifyTransform('request');
} else if (part.includes('Response')) {
modifyTransform('response');
} else if (part.includes('ErrResponse')) {
modifyTransform('errResponse');
}
}, 300);
}
}
});
// modifyLayout('inboundRequestLayout', '인바운드 요청', 'CBSS')
$('#requestTransformButton').on("click", function(event) {
modifyTransform('request');
});
$('#responseTransformButton').on("click", function(event) {
modifyTransform('response');
});
$('#errResponseTransformButton').on("click", function(event) {
modifyTransform('errResponse');
});
// 함수 사용 예시에 인바운드 응답 처리 추가
$("#fromAdapter").change(function() {
const adapterGroupName = $(this).val();
adapterSelectChange('inbound', adapterGroupName);
setInboundRoutingSlide();
});
$("#toAdapter").change(function() {
const adapterGroupName = $(this).val();
adapterSelectChange('outbound', adapterGroupName);
});
$("#fromResponseAdapter").change(function() {
const alpineData = getApiInterface();
if (alpineData.syncAsyncType === 'asyncSync') {
const adapterGroupName = $(this).val();
adapterSelectChange('inboundResponse', adapterGroupName);
}
});
$("#toResponseAdapter").change(function() {
const alpineData = getApiInterface();
if (alpineData.syncAsyncType === 'syncAsync') {
const adapterGroupName = $(this).val();
adapterSelectChange('outboundResponse', adapterGroupName);
}
});
$('#outboundRestPath').on('input', function() {
checkTagVariableUrl();
});
function setupHeaderPairs() {
headerValues.forEach(function(header, index) {
$('#headerPairs .header-pair:eq(' + index + ') input[name="headerValue"]').val(header);
});
}
// 모달이 열릴 때마다 헤더 페어 설정
$('#routingModal').on('show.bs.modal', setupHeaderPairs);
// 저장 로직
$('#saveRouting').click(function() {
headerValues = [];
$('#headerPairs .header-pair').each(function() {
var headerValue = $(this).find('input[name="headerValue"]').val();
if (headerValue !== '') {
headerValues.push(headerValue);
}
});
setHeaderRoutingLabel();
// 모달 닫기
$('#routingModal').modal('hide');
});
function setupStdCommonValueModal(type) {
currentStandardMessageType = type;
$('#stdCommonValuePairs input').val('');
const items = type === 'outbound' ? standardMessageItems : inboundResponseStandardMessageItems;
items.forEach(function(item) {
$('#stdCommonValuePairs input[columnname="'+item.COLUMNNAME+'"]').val(item.COLUMNVALUE);
});
}
$('#saveStdCommonItems').click(function() {
const newItems = [];
$('#stdCommonValuePairs input').each(function() {
const inputVal = $(this).val();
const columnname = $(this).attr('columnname');
if (inputVal) {
newItems.push({
COLUMNNAME: columnname,
COLUMNVALUE: inputVal
});
}
});
if (currentStandardMessageType === 'outbound') {
standardMessageItems = newItems;
setStandardMessageItemsLabel(standardMessageItems, 'standardMessageItemsButton');
} else {
inboundResponseStandardMessageItems = newItems;
setStandardMessageItemsLabel(inboundResponseStandardMessageItems, 'inboundResponseStandardMessageItemsButton');
}
$('#stdCommonValueModal').modal('hide');
});
function setupCloneInterfaceModal(event) {
const eaiBzwkDstcd = $('#eaiBzwkDstcd').val();
const eaiSvcName = $('#eaiSvcName').val();
const eaiSvcDesc = $('#eaiSvcDesc').val();
const inOutType = $('#inOutType').val();
const sendRecvType = $('#sendRecvType').val();
const inboundHttpMethod = $('#inboundHttpMethod').val();
const inboundRestPath = $('#inboundRestPath').val();
$('#newBizCode').val(eaiBzwkDstcd).trigger('change');
$('#newSvcName').val(eaiSvcName);
$('#newInOutType').val(inOutType);
$('#newSendRecvType').val(sendRecvType);
$('#newSvcDesc').val(eaiSvcDesc);
$('#newInboundHttpMethod').val(inboundHttpMethod).trigger('change');
$('#newInboundRestPath').val(inboundRestPath);
if($('#inboundRestPath').prop('disabled')){
$('#newRoutingOptionGroup').css('display','none');
}else{
$('#newRoutingOptionGroup').css('display','block');
}
}
$('#cloneInterfaceModal').on('show.bs.modal', setupCloneInterfaceModal);
$('#doCloneInterfaceButton').click(function() {
const orgApiInterfaceId = getFullSvcName();
const newBizCode = $('#newBizCode').val();
const newSvcName = $('#newSvcName').val();
const newSvcDesc = $('#newSvcDesc').val();
const newSendRecvType = $('#newSendRecvType').val();
const newInOutType = $('#newInOutType').val();
const newApiInterfaceId = newSvcName+newSendRecvType+newInOutType;
const newInboundHttpMethod = $('#newInboundHttpMethod').val();
$("input[name=newInboundRestPath]").val(function(index, value) {
return value.replace(/^\/+/, "");
});
const newInboundRestPath = $('#newInboundRestPath').val();
$.ajax({
type: "POST",
url: jsonUrl,
data: {
cmd: 'CLONE',
orgApiInterfaceId,
newBizCode,
newSvcDesc,
newApiInterfaceId,
newInboundHttpMethod,
newInboundRestPath,
},
beforeSend: function() {
$("[id=doCloneInterfaceButton]").prop("disabled", true);
$("#doCloneInterfaceButton").text("처리중 . . . . .");
},
success: function () {
alert("["+orgApiInterfaceId+"] => ["+newBizCode+"]["+newApiInterfaceId+"] 복제 완료.");
$('#cloneInterfaceModal').modal('hide');
goNav(returnUrl);//LIST로 이동
},
error: function (e) {
alert(e.responseText);
},
complete: function() {
$("[id=doCloneInterfaceButton]").prop("disabled", false);
$("#doCloneInterfaceButton").text("복제");
}
});
});
// 25.11.25 엑셀다운로드 사용안함.
// $("#btn_excel_export").click(function () {
// const url = url_excel + '?cmd=DETAIL_EXPORT_TO_EXCEL';
// const params = new URLSearchParams();
// params.append('eaiSvcName', getFullSvcName());
// downloadFiles(url, params);
// return false;
// });
// JSON 다운로드
$("#btn_json_export").click(function () {
const uri = url + '?cmd=DETAIL_EXPORT_TO_JSON';
const params = new URLSearchParams();
params.append('eaiSvcName', getFullSvcName());
downloadFiles(uri, params);
return false;
});
// 이벤트 리스너 수정
$('#standardMessageItemsButton').click(function() {
setupStdCommonValueModal('outbound');
$('#stdCommonValueModalLabel').text('아웃바운드 표준 전문 공통부 값 수정');
$('#stdCommonValueModal').modal('show');
});
$('#inboundResponseStandardMessageItemsButton').click(function() {
setupStdCommonValueModal('inboundResponse');
$('#stdCommonValueModalLabel').text('인바운드 응답 표준 전문 공통부 값 수정');
$('#stdCommonValueModal').modal('show');
});
});
function checkTagVariableUrl(){
// 이벤트 처리 로직을 여기에 작성합니다.
const changedValue = $('#outboundRestPath').val();
const regex = /\{.*\}/;
if (regex.test(changedValue)) {
$('#tagVariableUrl').css('display', 'inline');
} else {
$('#tagVariableUrl').css('display', 'none');
}
}
function makeValidate(){
$.validator.addMethod("idRegex", function(value, element) {
return this.optional(element) || /^[a-z0-9\-_]+$/i.test(value);
}, "ID값은 영문자, 숫자, 대시(-), 언더바(_)만 허용됩니다.");
$("#ajaxForm").validate({
ignore: ":hidden, [readonly=readonly]",
rules: {
eaiSvcName: {required: true, idRegex: true}
},
//messages: {
// eaiSvcName: "API 명을 입력하세요."
//},
errorElement: "em",
errorPlacement: function ( error, element ) {
// Add the `invalid-feedback` class to the error element
error.addClass( "invalid-feedback" );
if ( element.prop( "type" ) === "checkbox" ) {
error.insertAfter( element.next( "label" ) );
} else {
if($(element).next() != null && 'input-group-prepend' == $(element).next().attr('class')){
error.insertAfter( $(element).next().get(0) );
}else{
error.insertAfter( element );
}
}
},
highlight: function ( element, errorClass, validClass ) {
$( element ).addClass( "is-invalid" ).removeClass( "is-valid" );
},
unhighlight: function (element, errorClass, validClass) {
$( element ).addClass( "is-valid" ).removeClass( "is-invalid" );
}
});
}
function displaySelectedValue() {
var selectedValue = document.querySelector('input[name="exampleRadios"]:checked').value;
document.getElementById('selectedValue').textContent = "Selected Value: " + selectedValue;
}
</script>
</head>
<body>
<div class="right_box">
<div class="content_top">
<ul class="path">
<li><a href="#">${rmsMenuPath}</a></li>
</ul>
</div><!-- end content_top -->
<div class="content_middle" style="margin-top: 40px">
<div class="search_wrap">
<button type="button" class="cssbtn" id="btn_clone" level="W" status="DETAIL" data-bs-toggle="modal" data-bs-target="#cloneInterfaceModal"><i class="material-icons">content_copy</i> <%=localeMessage.getString("button.clone2")%></button></button>
<button type="button" class="cssbtn" id="btn_json_export" level="R" status="DETAIL,NEW"><i class="material-icons">download</i> <%=localeMessage.getString("button.exportJson")%></button></button>
<button type="button" class="cssbtn" id="btn_delete" level="W" status="DETAIL"><i class="material-icons">delete</i> <%= localeMessage.getString("button.delete") %></button>
<button type="button" class="cssbtn" id="btn_modify" level="R" status="DETAIL,NEW"><i class="material-icons">save</i> <%= localeMessage.getString("button.modify") %></button>
<button type="button" class="cssbtn" id="btn_api_spec" level="R" status="DETAIL,NEW"><i class="material-icons">description</i> API 스펙</button>
<button type="button" class="cssbtn" id="btn_previous" level="R" status="DETAIL,NEW"><i class="material-icons">arrow_back</i> <%= localeMessage.getString("button.previous") %></button>
</div>
<div class="title" id="title" style="font-size:1.4em">${rmsMenuName}</div>
<form id="ajaxForm"
x-data="apiInterfaceManager">
<input type="hidden" name="sevrLogLvelNo" ></input>
<div class="row">
<div class="col-md-12">
<fieldset class="groupbox-border" style="margin-top:0px !important">
<legend class="groupbox-border">BASIC OPTIONS</legend>
<div class="row">
<div class="form-group col-md-2">
<label for="eaiBzwkDstcd"><span class="material-icons-outlined">work</span> 업무구분</label>
<select id="eaiBzwkDstcd" class="form-select" name="eaiBzwkDstcd" style="width: 100%">
</select>
</div>
<div class="form-group col-md-3">
<label for="eaiSvcName">
<span class="material-icons-outlined">badge</span> <%= localeMessage.getString("eaiMessage.eaiSvcName")%>
</label>
<div class="input-group">
<input type="text"
class="form-control"
id="eaiSvcName"
name="eaiSvcName"
required>
<span class="input-group-text" id="sendRecvTypeSpan" style="padding: 0; border: none;">
<input type="text" id="sendRecvType" name="sendRecvType"
class="ignore form-control"
readonly="readonly"
style="width: 40px; text-align: center; border-radius: 0; margin-left: -1px;"
:value="apiInterface.requestType">
</span>
<span class="input-group-text" id="inOutTypeSpan" style="padding: 0; border: none;">
<input type="text" id="inOutType" name="inOutType"
class="ignore form-control"
readonly="readonly"
style="width: 40px; text-align: center; border-radius: 0; margin-left: -1px;"
:value="apiInterface.wordType">
</span>
</div>
</div>
<div class="form-group col-md-4">
<label for="eaiSvcDesc"><span class="material-icons-outlined">chat</span> API 명</label>
<input type="text" class="form-control" id="eaiSvcDesc" name="eaiSvcDesc" required></input>
</div>
<div class="form-group col-md-1">
<label for="toggleTransformYn"><span class="material-icons">account_tree</span> 전문변환</label><br>
<input type="checkbox" name="toggleTransformYn" id="toggleTransformYn" data-toggle="toggle" data-onstyle="success" data-on="사용" data-off="미사용" data-width="100" data-offstyle="secondary" data-style="ios" />
</div>
<div class="form-group col-md-1">
<label for="toggleLayoutView"><span class="material-icons">visibility</span> 전문보기</label><br>
<input type="checkbox" id="toggleLayoutView" data-toggle="toggle" data-onstyle="info" data-on="보기" data-off="숨김" data-width="100" data-offstyle="secondary" data-style="ios" />
</div>
<div class="form-group col-md-1">
<label for="toggleSimYn"><span class="material-icons" >science</span> 가상응답</label><br>
<input type="checkbox" name="toggleSimYn" id="toggleSimYn" data-toggle="toggle" data-onstyle="success" data-on="사용" data-off="미사용" data-width="100" data-offstyle="secondary" data-style="ios"/>
</div>
</div>
</fieldset>
</div>
</div>
<div class="row">
<div class="col-md-12">
<!-- 기존 인터페이스 타입 영역을 Alpine 컴포넌트로 감싸기 -->
<fieldset class="groupbox-border">
<legend class="groupbox-border">INTERFACE TYPE</legend>
<div class="row">
<!-- <div class="form-group col-md-3">
<label for="eaiBzwkDstcd"><span class="material-icons-outlined">sync</span> Sync/Async 타입</label><br>
<div class="btn-group" id="btnGroupSyncAsync" role="group">
<input type="radio"
class="btn-check"
name="btnRadioSyncAsync"
id="btnTypeSync"
value="sync"
x-model="apiInterface.syncAsyncType">
<label class="btn btn-outline-primary" for="btnTypeSync">
<i class="bi bi-arrow-repeat"></i> Sync
</label>
<input type="radio"
class="btn-check"
name="btnRadioSyncAsync"
id="btnTypeAsync"
value="async"
x-model="apiInterface.syncAsyncType">
<label class="btn btn-outline-primary" for="btnTypeAsync">
<i class="bi bi-arrow-left-right"></i> Async
</label>
<input type="radio"
class="btn-check"
name="btnRadioSyncAsync"
id="btnTypeAsyncSync"
value="asyncSync"
x-model="apiInterface.syncAsyncType">
<label class="btn btn-outline-primary" for="btnTypeAsyncSync">
<i class="bi bi-arrow-return-left"></i> A > S
</label>
<input type="radio"
class="btn-check"
name="btnRadioSyncAsync"
id="btnTypeSyncAsync"
value="syncAsync"
x-model="apiInterface.syncAsyncType">
<label class="btn btn-outline-primary" for="btnTypeSyncAsync">
<i class="bi bi-share-fill"></i> S > A
</label>
</div>
</div> -->
<div class="form-group col-md-3">
<label for="eaiBzwkDstcd">요청/응답 구분</label><br>
<div class="btn-group" role="group" aria-label="Basic radio toggle button group"
x-effect="if (apiInterface.syncAsyncType !== 'async') apiInterface.requestType = 'S'">
<input type="radio" class="btn-check" name="btnRadioReqRes" id="btnTypeRequest"
x-model="apiInterface.requestType"
value="S" :disabled="$store.formState.isReqResDisabled">
<label class="btn btn-outline-primary" for="btnTypeRequest"><i class="bi bi-arrow-bar-right"></i> 요청</label>
<input type="radio" class="btn-check" name="btnRadioReqRes" id="btnTypeResponse"
x-model="apiInterface.requestType"
value="R" :disabled="$store.formState.isReqResDisabled">
<label class="btn btn-outline-primary" for="btnTypeResponse"><i class="bi bi-arrow-bar-left"></i> 응답</label>
</div>
</div>
<div class="form-group col-md-3">
<label for="eaiBzwkDstcd">당/타발 구분</label><br>
<div class="btn-group" role="group" aria-label="Basic radio toggle button group">
<input type="radio" class="btn-check" name="btnRadioInOut" id="btnTypeInword" value="1" x-model="apiInterface.wordType" checked>
<label class="btn btn-outline-primary" for="btnTypeInword"><i class="bi bi-arrow-right-circle"></i> 당발</label>
<input type="radio" class="btn-check" name="btnRadioInOut" id="btnTypeOutword" value="2" x-model="apiInterface.wordType">
<label class="btn btn-outline-primary" for="btnTypeOutword"><i class="bi bi-arrow-left-circle"></i> 타발</label>
</div>
</div>
<input type="hidden" id="apiFullPath" value="">
</div>
</fieldset>
</div>
<div class="col-md-10">
<fieldset class="groupbox-border">
<legend class="groupbox-border">TRANSACTION OPTIONS</legend>
<div class="row">
<div class="form-group col-md-2">
<label for="svcLogLvelNo"><span class="material-icons-outlined">assignment</span> 로그레벨</label>
<select id="svcLogLvelNo" class="form-select" name="svcLogLvelNo"></input>
<option value="0">[0]로그 OFF</option>
<option value="1">[1]오류 로그만(900)</option>
<option value="2">[2]인바운드(100,400)</option>
<option value="3" selected>[3]전체로그</option>
<option value="4">[4]업무데이터 제외</option>
</select>
</div>
<div class="form-group col-md-2">
<label for="toutVal"><span class="material-icons-outlined">timer</span> 타임아웃 값</label>
<input type="number" class="form-control" id="toutVal" name="toutVal" required></input>
</div>
<div class="form-group col-md-2" x-show="showInboundResponse">
<label for="toutVal"><span class="material-icons-outlined">timer</span> 타임아웃 값2</label>
<input type="number" class="form-control" id="toutVal2" name="toutVal2" required :disabled="!showInboundResponse"></input>
</div>
<div id="contentTypePart" class="form-group col-md-6">
<label for="contentType"><span class="material-icons-outlined">movie</span> Content-Type (기본값:application/json)</label>
<input type="text" class="form-control" id="contentType" name="restContentType"></input>
</div>
</div>
</fieldset>
</div>
<div class="col-md-2">
<fieldset class="groupbox-border">
<legend class="groupbox-border">AUTH</legend>
<div class="row">
<div class="form-group col-md-12">
<label for="authType"><span class="material-icons-outlined">vpn_key</span> 인증타입</label>
<select id="authType" class="form-select" name="authType"></input>
<option value="none" selected>NONE</option>
<option value="oauth">OAUTH</option>
<option value="api_key">API_KEY</option>
</select>
</div>
</div>
</fieldset>
</div>
</div>
<div class="row">
<div class="col-md-12">
<fieldset class="groupbox-border">
<legend class="groupbox-border">ADAPTERS</legend>
<div class="row">
<div class="form-group col-md-6">
<label for="fromAdapter"><span class="material-icons">login</span> INBOUND 어댑터</label>
<select id="fromAdapter" class="form-select" name="fromAdapter" required></select>
<small id="fromAdapterUrl" class="form-text text-muted" style="margin-bottom:-20px"></small>
</div>
<div class="form-group col-md-6">
<label for="toAdapter"><span class="material-icons">logout</span> OUTBOUND 어댑터</label>
<div id="slideOutboundAdapter" class="carousel slide" data-ride="carousel" data-interval="false">
<div class="carousel-inner" style="margin-bottom:-20px">
<div class="carousel-item" style="text-align: center;">
<h1 style="font-family: Righteous">USING SIMULATION ADAPTER</h1>
</div>
<div class="carousel-item active">
<select id="toAdapter" class="form-select" name="toAdapter" required></select>
<small id="toAdapterUrl" class="form-text text-muted"></small>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="form-group col-md-6">
<div x-show="showInboundResponse">
<label for="fromResponseAdapter">
<span class="material-icons">keyboard_return</span>
INBOUND (ASYNC) 응답 어댑터
</label>
<select id="fromResponseAdapter"
class="form-select"
name="fromResponseAdapter"
required
:disabled="!showInboundResponse">
</select>
<small id="fromResponseAdapterUrl" class="form-text text-muted"></small>
</div>
</div>
<div class="form-group col-md-6">
<!-- toAdapterUrl 겹치지 않도록 mt-3 속성 추가 -->
<div class="mt-3" x-show="showOutboundResponse">
<label for="toResponseAdapter">
<span class="material-icons">keyboard_return</span>
OUTBOUND (ASYNC) 응답 어댑터
</label>
<select id="toResponseAdapter"
class="form-select"
name="toResponseAdapter"
required
:disabled="!showOutboundResponse">
</select>
<small id="toResponseAdapterUrl" class="form-text text-muted"></small>
</div>
</div>
</div>
</fieldset>
</div>
</div>
<div class="row">
<div class="col-md-6">
<fieldset class="groupbox-border">
<legend class="groupbox-border">INBOUND ROUTING</legend>
<div class="row">
<div class="col-md-4">
<label for="inboundHttpMethod">
<span class="material-icons">http</span>
<%= localeMessage.getString("apiInterface.recvMethod") %>
</label>
<select id="inboundHttpMethod" class="form-select" name="inboundHttpMethod" disabled>
<option value="post">POST</option>
<option value="get">GET</option>
<option value="put">PUT</option>
<option value="patch">PATCH</option>
<option value="delete">DELETE</option>
</select>
</div>
<div class="form-group col-md-8">
<div id="slideInboundRoutingRule">
<div class="row">
<div class="col-md-12">
<label for="inboundRestPath">
<span class="material-icons">link</span>
수신 REST PATH(URL)
</label>
<input type="text" class="form-control" id="inboundRestPath"
name="inboundRestPath" disabled>
</div>
</div>
</div>
</div>
</div>
<div class="collapse mt-2" id="collapseInboundRoutingInfo">
<div class="form-group col-md-12">
<label>
<span class="material-icons justify-content-md-start">http</span>
수신 라우팅 정보
</label>
<div class="d-grid gap-2">
<button type="button" id="headerRoutingButton" class="btn btn-primary"
data-bs-toggle="modal" data-bs-target="#routingModal">
수정
</button>
</div>
</div>
</div>
<div id="inboundResponseMethodPathRow"
x-show="showInboundResponse">
<div id="inboundResponseRestPart" class="row">
<div class="form-group col-md-4">
<label for="inboundResponseHttpMethod">
<span class="material-icons">http</span>
응답 송신 메소드
</label>
<select id="inboundResponseHttpMethod"
class="form-select"
name="inboundResponseHttpMethod"
disabled>
<option value="post">POST</option>
<option value="get">GET</option>
<option value="put">PUT</option>
<option value="patch">PATCH</option>
<option value="delete">DELETE</option>
</select>
</div>
<div class="form-group col-md-8">
<label for="inboundResponseRestPath">
<span class="material-icons">link</span>
응답 송신 REST PATH(URL)
</label>
<input type="text"
class="form-control"
id="inboundResponseRestPath"
name="inboundResponseRestPath"
disabled>
</div>
</div>
<!-- 표준전문 공통부 값 -->
<div id="inboundResponseCommonFieldPart" class="row" style="display:none">
<div class="form-group col-md-12">
<label for="inboundResponseStandardMessageItemsButton">
<span class="material-icons-outlined">view_list</span>
표준전문 공통부 값
</label>
<div class="d-grid gap-2">
<button type="button"
id="inboundResponseStandardMessageItemsButton"
class="btn btn-primary"
data-bs-toggle="modal"
data-bs-target="#stdCommonValueModal">
수정
</button>
</div>
</div>
</div>
</div>
</fieldset>
</div>
<div class="col-md-6">
<fieldset class="groupbox-border">
<legend class="groupbox-border">OUTBOUND ROUTING</legend>
<div id="outboundRoutingContent">
<div class="row" id="standardOutboundOptions">
<div class="form-group col-md-4">
<label for="outboundHttpMethod">
<span class="material-icons">http</span>
송신 메소드
</label>
<select id="outboundHttpMethod" class="form-select" name="outboundHttpMethod" disabled>
<option value="post">POST</option>
<option value="get">GET</option>
<option value="put">PUT</option>
<option value="patch">PATCH</option>
<option value="delete">DELETE</option>
</select>
</div>
<div class="form-group col-md-8">
<label for="outboundRestPath">
<span class="material-icons">link</span>
<span class="badge badge-warning" id="tagVariableUrl" style="display: none">가변</span>
송신 REST PATH(URL)
</label>
<input type="text" class="form-control" id="outboundRestPath"
name="outboundRestPath" disabled>
</div>
</div>
<div id="commonFieldPart" class="row" style="display:none">
<div class="form-group col-md-12">
<label for="standardMessageItemsButton">
<span class="material-icons-outlined">view_list</span>
표준전문 공통부 값
</label>
<div class="d-grid gap-2">
<button type="button" id="standardMessageItemsButton" class="btn btn-primary"
data-bs-toggle="modal" data-bs-target="#stdCommonValueModal">
수정
</button>
</div>
</div>
</div>
<div id="outboundResponseMethodPathRow"
x-show="showOutboundResponse">
<div id="outboundResponseRestPart" class="row">
<div class="form-group col-md-4">
<label for="outboundResponseHttpMethod">
<span class="material-icons">http</span>
응답 수신 메소드
</label>
<select id="outboundResponseHttpMethod" class="form-select" name="outboundResponseHttpMethod" disabled>
<option value="post">POST</option>
<option value="get">GET</option>
<option value="put">PUT</option>
<option value="patch">PATCH</option>
<option value="delete">DELETE</option>
</select>
</div>
<div class="form-group col-md-8">
<label for="outboundResponseRestPath">
<span class="material-icons">link</span>
응답 수신 REST PATH(URL)
</label>
<input type="text" class="form-control" id="outboundResponseRestPath" name="outboundResponseRestPath" disabled>
</div>
</div>
<div id="outboundResponseCommonFieldPart" class="row" style="display:none">
<div class="form-group col-md-12">
<label for="standardMessageItemsButton">
<span class="material-icons-outlined">view_list</span>
표준전문 공통부 값
</label>
<div class="d-grid gap-2">
<button type="button" id="standardMessageItemsButton" class="btn btn-primary"
data-bs-toggle="modal" data-bs-target="#stdCommonValueModal">
수정
</button>
</div>
</div>
</div>
</div>
</div>
</fieldset>
</div>
</div>
<div class="collapse" id="collapseTransform">
<div class="row">
<div class="col-md-12">
<fieldset class="groupbox-border">
<div style="display: flex; align-items: center;">
<legend class="groupbox-border" style="display: contents">변환정보</legend>
</div>
<div class="row" id="rowRequestTransform">
<div class="form-group col-md-4">
<label for="inboundRequestLayout"><span class="material-icons-outlined">keyboard_double_arrow_right</span> 인바운드 요청</label>
<div class="input-group">
<input type="text" class="form-control" id="inboundRequestLayout" name="inboundRequestLayout" placeholder="인바운드 요청 레이아웃 없음" readonly>
<div class="input-group-append">
<button class="btn btn-info" id="inboundRequestButton" type="button" data-bs-toggle="tooltip">생성</button>
</div>
</div>
</div>
<div class="form-group col-md-4">
<label for="requestTransform"><span class="material-icons-outlined">keyboard_double_arrow_right</span> 요청변환</label>
<div class="input-group">
<input type="text" class="form-control" id="requestTransform" name="requestTransform" placeholder="요청 변환 없음" readonly>
<div class="input-group-append">
<span tabindex="0" id="requestTransformButtonTooltip" data-bs-toggle="tooltip" data-html="true" title="매핑룰을 등록할 수 없습니다. 우선 요청 레이아웃을 모두 등록하세요.">
<button class="btn btn-secondary" id="requestTransformButton" type="button" >생성</button>
</span>
</div>
</div>
</div>
<div class="form-group col-md-4">
<label for="outboundRequestLayout"><span class="material-icons-outlined">keyboard_double_arrow_right</span> 아웃바운드 요청</label>
<div class="input-group">
<input type="text" class="form-control" id="outboundRequestLayout" name="outboundRequestLayout" placeholder="아웃바운드 요청 레이아웃 없음" readonly>
<div class="input-group-append">
<button class="btn btn-info" id="outboundRequestButton" type="button" data-bs-toggle="tooltip">생성</button>
</div>
</div>
</div>
</div>
<div class="row" id="rowResponseTransform">
<div class="form-group col-md-4">
<label for="inboundResponseLayout"><span class="material-icons-outlined">keyboard_double_arrow_left</span> 인바운드 응답</label>
<div class="input-group">
<input type="text" class="form-control" id="inboundResponseLayout" name="inboundResponseLayout" placeholder="인바운드 응답 레이아웃 없음" readonly>
<div class="input-group-append">
<button class="btn btn-info" id="inboundResponseButton" type="button" data-bs-toggle="tooltip">생성</button>
</div>
</div>
</div>
<div class="form-group col-md-4">
<label for="responseTransform"><span class="material-icons-outlined">keyboard_double_arrow_left</span> 응답변환</label>
<div class="input-group">
<input type="text" class="form-control" id="responseTransform" name="responseTransform" placeholder="응답 변환 없음" readonly>
<div class="input-group-append">
<span tabindex="0" id="responseTransformButtonTooltip" data-bs-toggle="tooltip" data-html="true" title="매핑룰을 등록할 수 없습니다. 우선 응답 레이아웃을 모두 등록하세요.">
<button class="btn btn-secondary" id="responseTransformButton" type="button">생성</button>
</span>
</div>
</div>
</div>
<div class="form-group col-md-4">
<label for="outboundResponseLayout"><span class="material-icons-outlined">keyboard_double_arrow_left</span> 아웃바운드 응답</label>
<div class="input-group">
<input type="text" class="form-control" id="outboundResponseLayout" name="outboundResponseLayout" placeholder="아웃바운드 응답 레이아웃 없음" readonly>
<div class="input-group-append">
<button class="btn btn-info" id="outboundResponseButton" type="button" data-bs-toggle="tooltip">생성</button>
</div>
</div>
</div>
</div>
<div style="margin-top: 10px;">
<label for="toggleErrTransformYn"><span class="material-icons-outlined">error_outline</span> 오류 변환</label>
<input type="checkbox" name="toggleErrTransformYn" id="toggleErrTransformYn"
data-toggle="toggle" data-onstyle="success" data-offstyle="secondary"
data-height="1" data-width="40" data-size="xs"/>
</div>
<div class="row" id="rowErrResponseTransform">
<div class="form-group col-md-4">
<label for="inboundErrResponseLayout">
<span class="material-icons-outlined">keyboard_double_arrow_left</span> 인바운드 오류 응답
</label>
<div class="input-group">
<input type="text" class="form-control" id="inboundErrResponseLayout"
name="inboundErrResponseLayout" placeholder="인바운드 오류 레이아웃 없음" readonly>
<div class="input-group-append">
<button class="btn btn-info" id="inboundErrResponseButton"
type="button" data-bs-toggle="tooltip">생성</button>
</div>
</div>
</div>
<div class="form-group col-md-4">
<label for="errResponseTransform">
<span class="material-icons-outlined">error_outline</span> 오류 응답 변환
</label>
<div class="input-group">
<input type="text" class="form-control" id="errResponseTransform"
name="errResponseTransform" placeholder="오류 변환 없음" readonly>
<div class="input-group-append">
<span tabindex="0" id="errResponseTransformButtonTooltip"
data-bs-toggle="tooltip" data-html="true"
title="매핑룰을 등록할 수 없습니다. 우선 오류 레이아웃을 모두 등록하세요.">
<button class="btn btn-secondary" id="errResponseTransformButton"
type="button">생성</button>
</span>
</div>
</div>
</div>
<div class="form-group col-md-4">
<label for="outboundErrResponseLayout">
<span class="material-icons-outlined">keyboard_double_arrow_left</span> 아웃바운드 오류 응답
</label>
<div class="input-group">
<input type="text" class="form-control" id="outboundErrResponseLayout"
name="outboundErrResponseLayout" placeholder="아웃바운드 오류 레이아웃 없음" readonly>
<div class="input-group-append">
<button class="btn btn-info" id="outboundErrResponseButton"
type="button" data-bs-toggle="tooltip">생성</button>
</div>
</div>
</div>
</div>
</fieldset>
</div>
</div>
</div>
</form>
</div><!-- end content_middle -->
<div class="modal fade" id="routingModal" tabindex="-1" role="dialog" aria-labelledby="routingModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="routingModalLabel">MessageKey 기반 라우팅 수정</h5>
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<form id="routingForm">
<div id="headerPairs">
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">닫기</button>
<button type="button" class="btn btn-primary" id="saveRouting">적용</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="stdCommonValueModal" tabindex="-1" role="dialog" aria-labelledby="stdCommonValueModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="stdCommonValueModalLabel">표준 전문 공통부 값 수정</h5>
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<h6 class="modal-title">해당 값을 설정하면 표준전문 공통부에 설정됩니다.</h6>
<form id="stdCommonValueForm">
<div id="stdCommonValuePairs">
<!-- 동적으로 생성되는 필드들이 여기에 들어갑니다 -->
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">닫기</button>
<button type="button" class="btn btn-primary" id="saveStdCommonItems">적용</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="cloneInterfaceModal" tabindex="-1" role="dialog" aria-labelledby=cloneInterfaceModalLabel" aria-hidden="true">
<div class="modal-dialog modal-xl" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="cloneInterfaceModalLabel">API 인터페이스 복제</h5>
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<h6 class="modal-title mb-2">[<span id="cloneOrgInterfaceIdDesc" ></span>]에서 복제 할 업무코드, API ID, REST PATH 정보 입력하세요(저장 되어있는 API 기준으로 복제)</h6>
<form id="cloneInterfaceForm">
<fieldset class="groupbox-border" style="margin-top:0px !important">
<legend class="groupbox-border">BASIC</legend>
<div class="row">
<div class="form-group col-md-2">
<label for="newBizCode"><span class="material-icons-outlined">work</span> 업무구분</label>
<select id="newBizCode" class="form-select" name="newBizCode" style="width: 100%">
</select>
</div>
<div class="form-group col-md-6">
<label for="newSvcName"><span class="material-icons-outlined">badge</span> <%= localeMessage.getString("eaiMessage.eaiSvcName")%></label>
<div class="input-group">
<input type="text" class="form-control" id="newSvcName" name="newSvcName" required>
<span class="input-group-text" style="padding: 0; border: none;">
<input type="text" id="newSendRecvType" name="newSendRecvType" class="ignore form-control" readonly="readonly" style="width: 40px; text-align: center; border-radius: 0; margin-left: -1px;" value="S">
</span>
<span class="input-group-text" style="padding: 0; border: none;">
<input type="text" id="newInOutType" name="newInOutType" class="ignore form-control" readonly="readonly" style="width: 40px; text-align: center; border-radius: 0; margin-left: -1px;" value="1">
</span>
</div>
</div>
<div class="form-group col-md-4">
<label for="newSvcDesc"><span class="material-icons-outlined">badge</span> API 명</label>
<div class="input-group">
<input type="text" class="form-control" id="newSvcDesc" name="newSvcDesc">
</div>
</div>
</div>
</fieldset>
<fieldset id="newRoutingOptionGroup" class="groupbox-border">
<legend class="groupbox-border">ROUTING</legend>
<div class="row">
<div class="form-group col-md-4">
<label for="newInboundHttpMethod"><span class="material-icons">http</span> <%= localeMessage.getString("apiInterface.recvMethod") %></label>
<select id="newInboundHttpMethod" class="form-select" name="newInboundHttpMethod"></input>
<option value="post">POST</option>
<option value="get">GET</option>
<option value="put">PUT</option>
<option value="patch">PATCH</option>
<option value="delete">DELETE</option>
</select>
</div>
<div class="form-group col-md-8">
<label for="newInboundRestPath"><span class="material-icons">link</span> 수신 REST PATH(URL)</label>
<input type="text" class="form-control" id="newInboundRestPath" name="newInboundRestPath"></input>
</div>
</div>
</fieldset>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">닫기</button>
<button type="button" class="btn btn-primary" id="doCloneInterfaceButton">복제</button>
</div>
</div>
</div>
</div>
</div><!-- end right_box -->
</body>
</html>
</div>
</div>
</div>
</div>
</div><!-- end right_box -->
</body>
</html>