var selectId; // 제품 아이디 var selectName; // 제품 이름 var selected_alm_server_id; var selected_alm_server_name; var alm_server_list = {}; var req_state_category_list = {}; //////////////////////////////////////////////////////////////////////////////////////// //Document Ready //////////////////////////////////////////////////////////////////////////////////////// function execDocReady() { let pluginGroups = [ [ "../reference/jquery-plugins/select2-4.0.2/dist/css/select2_lightblue4.css", "../reference/jquery-plugins/select2-4.0.2/dist/js/select2.min.js", "../reference/lightblue4/docs/lib/slimScroll/jquery.slimscroll.min.js", "../reference/lightblue4/docs/lib/widgster/widgster.js", "../reference/jquery-plugins/timerStyles.js" ], [ "../reference/jquery-plugins/jstree-v.pre1.0/_lib/jquery.cookie.js", "../reference/jquery-plugins/jstree-v.pre1.0/_lib/jquery.hotkeys.js", "../reference/jquery-plugins/jstree-v.pre1.0/jquery.jstree.js", "../reference/gojs/go-debug.js", "../arms/js/mapping/gojs_setup.js" ] ]; loadPluginGroupsParallelAndSequential(pluginGroups) .then(function () { //사이드 메뉴 처리 $(".widget").widgster(); setSideMenu("sidebar_menu_jira", "sidebar_menu_state_mapping"); //coming soon $("#count-down").TimeCircles( { circle_bg_color: "#f8f8f8", use_background: true, bg_width: .2, fg_width: 0.013, time: { Days: { color: "#f8f8f8" }, Hours: { color: "#f8f8f8" }, Minutes: { color: "#f8f8f8" }, Seconds: { color: "#f8f8f8" } } } ); //ALM 서버 셀렉트 박스 이니시에이터 make_alm_server_select_box(); gojs.init(); save_req_state_btn_click(); update_req_state_btn_click(); delete_req_state_btn_click(); preset_btn_click(); // --- 에디터 설정 --- // var waitCKEDITOR = setInterval(function () { try { if (window.CKEDITOR) { if (window.CKEDITOR.status === "loaded") { CKEDITOR.replace("popup_view_state_description_editor", { skin: "office2013" }); clearInterval(waitCKEDITOR); } } } catch (err) { console.log("CKEDITOR 로드가 완료되지 않아서 초기화 재시도 중..."); } }, 313 /*milli*/); $("#text").on("input", function () { var searchString = $(this).val(); $("#alm_server_tree").jstree("search", searchString); }); init_data_load(); }) .catch(function (e) { console.error("플러그인 로드 중 오류 발생"); console.error(e); }); } /////////////////////// // ALM 서버 셀렉트 박스 ////////////////////// function make_alm_server_select_box() { //제품 서비스 셀렉트 박스 이니시에이터 $(".chzn-select").each(function() { $(this).select2($(this).data()); }); //ALM 서버 셀렉트 박스 데이터 바인딩 $.ajax({ url: "/auth-user/api/arms/jiraServerPure/getNodesWithoutRoot.do", type: "GET", contentType: "application/json;charset=UTF-8", dataType: "json", progress: true, statusCode: { 200: function(data) { console.log(data.result); ////////////////////////////////////////////////////////// for (var k in data.result) { var obj = data.result[k]; alm_server_list[obj.c_id] = obj; var newOption = new Option(obj.c_title, obj.c_id, false, false); $("#selected_alm_server").append(newOption).trigger("change"); } jSuccess("ALM 서버 조회가 완료 되었습니다."); } }, error: function (e) { jError("ALM 서버 조회 중 에러가 발생했습니다. :: " + e); } }); $("#selected_alm_server").on("select2:open", function() { //슬림스크롤 makeSlimScroll(".select2-results__options"); }); // --- select2 ( 제품(서비스) 검색 및 선택 ) 이벤트 --- // $("#selected_alm_server").on("select2:select", function(e) { $("#preset").addClass("hidden"); $("#preset_message").addClass("hidden"); $("#cloud_project_tree").hide(); $("#select-project-div").hide(); $("#select-issuetype-div").hide(); $("#select-project").text("선택되지 않음"); $("#select-issuetype").text("선택되지 않음"); selected_alm_server_id = $("#selected_alm_server").val(); selected_alm_server_name = $("#selected_alm_server").select2("data")[0].text; $("#select-alm-server").text(selected_alm_server_name); let alm_server_data = alm_server_list[selected_alm_server_id]; let alm_server_type = alm_server_data.c_jira_server_type; if (alm_server_type === "클라우드") { $("#preset_message").removeClass("hidden"); $("#preset").removeClass("hidden"); $("#cloud_project_tree").show(); $("#select-project-div").show(); $("#select-issuetype-div").show(); build_alm_server_jstree(selected_alm_server_id); init_data_load(); } else { mapping_data_load(selected_alm_server_id, alm_server_type); } }); } // end make_alm_server_select_box() function init_data_load() { Promise.all([get_arms_state_category_list(), get_arms_state_list()]) .then(([arms_state_category_list, arms_state_list]) => { for (var k in arms_state_category_list) { var obj = arms_state_category_list[k]; req_state_category_list[obj.c_id] = obj; } console.log('ARMS Category State List:', req_state_category_list); console.log('ARMS State List:', arms_state_list); let data = generate_gojs_mapping_data(req_state_category_list, arms_state_list, null, null); gojs.load(data); }) .catch((error) => { console.error('Error fetching data:', error); }); } function mapping_data_load(almServerId, alm_server_type, project_id, issueTypeId) { if (!alm_server_type) { almServerId = almServerId || selected_alm_server_id; if (!almServerId) { alert("선택된 서버가 없습니다."); return; } let alm_server_data = alm_server_list[almServerId]; alm_server_type = alm_server_data.c_jira_server_type; } if (alm_server_type === "클라우드") { if (!project_id|| !issueTypeId) { alert("선택된 프로젝트 이슈유형이 없습니다."); return; } Promise.all([get_arms_state_list(), getIssueStatusListByIssueType(issueTypeId)]) .then(([arms_state_list, alm_status_list]) => { console.log('ARMS State List:', arms_state_list); console.log('ALM Status List:', alm_status_list); if (alm_status_list.length === 0) { alert("연결된 상태가 없습니다. 권한 확인이 필요합니다."); let data = {}; gojs.load(data); return; } let data = generate_gojs_mapping_data(req_state_category_list, arms_state_list, alm_status_list, alm_server_type); gojs.load(data); }) .catch((error) => { console.error('Error fetching data:', error); }); } else { Promise.all([get_arms_state_list(), getAlmIssueStatusList(almServerId)]) .then(([arms_state_list, alm_status_list]) => { console.log('ARMS State List:', arms_state_list); console.log('ALM Status List:', alm_status_list); let gojs_mapping_data = generate_gojs_mapping_data(req_state_category_list, arms_state_list, alm_status_list, alm_server_type); gojs.load(gojs_mapping_data); }) .catch((error) => { console.error('Error fetching data:', error); }); } } function generate_gojs_mapping_data(req_state_category_list, arms_state_list, alm_status_list, alm_server_type) { const node_data_array = []; const link_data_array = []; const category_x_position = 0; const arms_state_x_position = 300; const alm_status_x_position = 600; const y_spacing = 50; const category_y_spacing = 50; let category_y_position = 0; let arms_state_y_position = 0; let alm_status_y_position = 0; const category_nodes = {}; const arms_state_nodes = {}; let alm_status_nodes = {}; if (req_state_category_list && Array.isArray(Object.entries(req_state_category_list))) { Object.entries(req_state_category_list).forEach(([key, value]) => { const category_type = "arms-category"; const category_node_key = category_type+ "-"+key; const node = { key: category_node_key, text: `${value.c_title}`, type: category_type, c_id: key, category: 'Loading', loc: `${category_x_position} ${category_y_position}` }; node_data_array.push(node); category_nodes[key] = node; category_y_position += category_y_spacing; }); } if (arms_state_list && Array.isArray(Object.entries(arms_state_list))) { arms_state_list.forEach((state) => { const arms_state_type = "arms-state"; const arms_node_key = arms_state_type + "-" + state.c_id; const node = { key: arms_node_key, text: `${state.c_title}`, type: arms_state_type, c_id: state.c_id, c_check: state.c_check, category: 'NoAdd', loc: `${arms_state_x_position} ${arms_state_y_position}`, }; if (state.reqStateCategoryEntity) { node.mapping_id = state.reqStateCategoryEntity.c_id; } else { node.mapping_id = null; } node_data_array.push(node); arms_state_nodes[state.c_id] = node; arms_state_y_position += y_spacing; }); } if (alm_status_list && Array.isArray(alm_status_list)) { alm_status_list.forEach((status) => { const alm_status_type = "alm-status"; const alm_node_key = alm_status_type + "-" + status.c_id; const node = { key: alm_node_key, text: `${status.c_issue_status_name}`, server_type: alm_server_type, type: alm_status_type, c_id: status.c_id, mapping_id: status.c_req_state_mapping_link, category: 'End', loc: `${alm_status_x_position} ${alm_status_y_position}` }; node_data_array.push(node); alm_status_nodes[status.c_id] = node; alm_status_y_position += y_spacing; }); } // 링크 데이터 생성 node_data_array.forEach((node) => { if (node.type === 'arms-state' && node.mapping_id) { const fromNode = category_nodes[node.mapping_id]; if (fromNode) { link_data_array.push({ from: fromNode.key, to: node.key, fromNode: fromNode, toNode: node, oldFromNode: fromNode, oldToNode: node }); } } else if (node.type === 'alm-status' && node.mapping_id) { const fromNode = arms_state_nodes[node.mapping_id]; if (fromNode) { link_data_array.push({ from: fromNode.key, to: node.key, fromNode: fromNode, toNode: node, oldFromNode: fromNode, oldToNode: node }); } } }); // 암스 상태 노드 정렬 const sorted_arms_state_nodes = Object.values(arms_state_nodes).sort((a, b) => { const mappingAExists = a.mapping_id !== undefined && a.mapping_id !== null; const mappingBExists = b.mapping_id !== undefined && b.mapping_id !== null; // mapping_id가 없는 데이터는 아래쪽에 배치 if (!mappingAExists) return 1; if (!mappingBExists) return -1; // 매핑 기준 상태 카테고리 노드 조회 const category_node_a = category_nodes[a.mapping_id]; const category_node_b = category_nodes[b.mapping_id]; // 매핑된 상태 카테고리가 없으면 아래 쪽에 배치 if (category_node_a === undefined) return 1; if (category_node_b === undefined) return -1; // 상태 카테고리 y 좌표를 기준 정렬 return get_y_position(category_node_a) - get_y_position(category_node_b); }); arms_state_y_position = 0; if (sorted_arms_state_nodes && Array.isArray(sorted_arms_state_nodes)) { sorted_arms_state_nodes.forEach((node) => { node.loc = `${arms_state_x_position} ${arms_state_y_position}`; arms_state_y_position += y_spacing; }); } // ALM 상태 노드 ARMS에 매핑된 노드 기준으로 정렬 const sorted_alm_status_nodes = Object.values(alm_status_nodes).sort((a, b) => { const mappingAExists = a.mapping_id !== undefined && a.mapping_id !== null; const mappingBExists = b.mapping_id !== undefined && b.mapping_id !== null; // mapping_id가 없는 데이터는 아래쪽에 배치 if (!mappingAExists) return 1; if (!mappingBExists) return -1; // 매핑 기준 ARMS 상태 노드 조회 const state_node_a = arms_state_nodes[a.mapping_id]; const state_node_b = arms_state_nodes[b.mapping_id]; // 매핑된 ARMS 상태가 없으면 아래 쪽에 배치 if (state_node_a === undefined) return 1; if (state_node_b === undefined) return -1; // ARNS 상태 y 좌표를 기준 정렬 return get_y_position(state_node_a) - get_y_position(state_node_b); }); alm_status_y_position = 0; if (sorted_alm_status_nodes && Array.isArray(sorted_alm_status_nodes)) { sorted_alm_status_nodes.forEach((node) => { node.loc = `${alm_status_x_position} ${alm_status_y_position}`; alm_status_y_position += y_spacing; }); } return { class: 'GraphLinksModel', nodeDataArray: node_data_array, linkDataArray: link_data_array }; } // y 좌표를 추출하는 헬퍼 함수 function get_y_position(node) { return parseFloat(node.loc.split(" ")[1]); } function get_arms_state_list() { return new Promise((resolve, reject) => { $.ajax({ url: "/auth-user/api/arms/reqState/getNodesWithoutRoot.do", type: "GET", dataType: "json", progress: true, statusCode: { 200: function (data) { resolve(data.result); } }, error: function (e) { jError("ARMS 상태 조회 중 에러가 발생했습니다."); reject(e); } }); }); } function getAlmIssueStatusList(almServerId) { return new Promise((resolve, reject) => { $.ajax({ url: "/auth-user/api/arms/jiraServer/getIssueStatusList?c_id=" + almServerId, type: "GET", contentType: "application/json;charset=UTF-8", dataType: "json", progress: true, statusCode: { 200: function(result) { console.log(result); resolve(result.response); jSuccess("ALM 서버 상태 조회가 완료 되었습니다."); } }, error: function (e) { jError("ALM 서버 상태 조회 중 에러가 발생했습니다. :: " + e); reject(e); } }); }); } function getIssueStatusListByIssueType(issueTypeId) { return new Promise((resolve, reject) => { $.ajax({ url: "/auth-user/api/arms/jiraIssueType/getIssueStatusList?c_id=" + issueTypeId, type: "GET", contentType: "application/json;charset=UTF-8", dataType: "json", progress: true, statusCode: { 200: function(result) { console.log(result); resolve(result.response); jSuccess("ALM 프로젝트 상태 조회가 완료 되었습니다."); } }, error: function (e) { jError("ALM 프로젝트 상태 조회 중 에러가 발생했습니다. :: " + e); reject(e); } }); }); } function build_alm_server_jstree(selected_alm_server_id) { var jQueryElementID = "#alm_server_tree"; var serviceNameForURL = "/auth-user/api/arms/jiraServerProjectPure/getJiraProjectList.do?c_id=" + selected_alm_server_id; jstree_build(jQueryElementID, serviceNameForURL); } //////////////////////////////////////////////////////////////////////////////////////// // -- jstree build 설정 -- // //////////////////////////////////////////////////////////////////////////////////////// function jstree_build(jQueryElementID, serviceNameForURL) { console.log("mapping :: jstree_build : ( jQueryElementID ) → " + jQueryElementID); console.log("mapping :: jstree_build : ( serviceNameForURL ) → " + serviceNameForURL); console.log("mapping :: jstree_build : ( href ) → " + $(location).attr("href")); console.log("mapping :: jstree_build : ( protocol ) → " + $(location).attr("protocol")); console.log("mapping :: jstree_build : ( host ) → " + $(location).attr("host")); console.log("mapping :: jstree_build : ( pathname ) → " + $(location).attr("pathname")); console.log("mapping :: jstree_build : ( search ) → " + $(location).attr("search")); console.log("mapping :: jstree_build : ( hostname ) → " + $(location).attr("hostname")); console.log("mapping :: jstree_build : ( port ) → " + $(location).attr("port")); $(jQueryElementID) .jstree({ plugins: ["themes", "json_data", "ui", "crrm", "dnd", "search", "types"], themes: { theme: ["lightblue4"] }, json_data: { ajax: { url: serviceNameForURL, cache: false, data: function (n) { // the result is fed to the AJAX request `data` option console.log("[ common :: jsTreeBuild ] :: json data load = " + JSON.stringify(n)); return { c_id: n.attr ? n.attr("id").replace("node_", "").replace("copy_", "") : 1 }; }, success: function (n) { jSuccess("프로젝트 조회 완료"); n.forEach(project => { project.attr.rel = "project"; project.attr.title = project.c_title; project.children = []; project.jiraIssueTypePureEntities.forEach(issueType => { // 하위 작업 이슈유형 제거 처리 if (issueType.c_contents !== "-1" || issueType.c_desc !== "true") { project.children.push({ attr: { rel: "issueType", id: "issueType_" + issueType.c_id, title: issueType.c_issue_type_name }, data: [issueType.c_issue_type_name], text: issueType.c_issue_type_name, }); } }); }); $(jQueryElementID).jstree("search", $("#text").val()); } } }, search: { show_only_matches: true, search_callback: function (str, node) { return node.data().search(str); } }, types: { max_depth: -2, max_children: -2, valid_children: ["project"], types: { default: { // I want this type to have no children (so only leaf nodes) // In my case - those are files valid_children: "none", // If we specify an icon for the default type it WILL OVERRIDE the theme icons icon: { image: "../reference/jquery-plugins/jstree-v.pre1.0/themes/attibutes.png" } }, project: { valid_children: ["issueType"], icon: { image: "../reference/jquery-plugins/jstree-v.pre1.0/themes/ic_app.png" } }, issueType: { valid_children: "none", icon: { image: "../reference/jquery-plugins/jstree-v.pre1.0/themes/toolbar_new.png" } } } }, }) .bind("select_node.jstree", function (event, data) { if ($.isFunction(jstree_click)) { console.log("[ jstree_build :: select_node ] :: data.rslt.obj.data('id')" + data.rslt.obj.attr("id")); console.log("[ jstree_build :: select_node ] :: data.rslt.obj.data('rel')" + data.rslt.obj.attr("rel")); console.log("[ jstree_build :: select_node ] :: data.rslt.obj.data('class')" + data.rslt.obj.attr("class")); console.log("[ jstree_build :: select_node ] :: data.rslt.obj.children('a')" + data.rslt.obj.children("a")); console.log("[ jstree_build :: select_node ] :: data.rslt.obj.children('ul')" + data.rslt.obj.children("ul")); jstree_click(data.rslt.obj); } }) .bind("loaded.jstree", function (event, data) { $(jQueryElementID).slimscroll({ height: "200px" }); }); $("#mmenu input, #mmenu button").click(function () { switch (this.id) { case "add_default": case "add_folder": $(jQueryElementID).jstree("create", null, "last", { attr: { rel: this.id.toString().replace("add_", "") } }); break; case "search": $(jQueryElementID).jstree("search", document.getElementById("text").value); break; case "text": break; default: $(jQueryElementID).jstree(this.id); break; } }); $("#mmenu .form-search").submit(function (event) { event.preventDefault(); $(jQueryElementID).jstree("search", document.getElementById("text").value); }); } function jstree_click(data) { let rel = data.attr('rel'); if (rel === "project") { $(".jstree-clicked").removeClass("jstree-clicked"); console.log(rel); return; } else { let project_title = data.parent().parent().attr("title"); $("#select-project").text(project_title); let issueType_title = data.attr("title"); $("#select-issuetype").text(issueType_title); let project_c_id = data.parent().parent().attr("id").replace("node_", "").replace("copy_", ""); let issueType_c_id = data.attr("id").replace("issueType_", "").replace("copy_", ""); mapping_data_load(null, null, project_c_id, issueType_c_id); } } /////////////////////////////////// // 팝업 띄울 때, UI 일부 수정되도록 /////////////////////////////////// function popup_modal(popup_type, state_id, state_name) { $('#my_modal1').modal('show'); const container = $('#popup_view_state_category_div'); container.empty(); for (const key in req_state_category_list) { if (req_state_category_list.hasOwnProperty(key)) { const item = req_state_category_list[key]; const label = $('