//////////////////////////////////////////////////////////////////////////////////////// //Document Ready //////////////////////////////////////////////////////////////////////////////////////// var selectedPdServiceId; // 제품(서비스) 아이디 var selectedVersionId; // 선택된 버전 아이디 var reqStatusDataTable; var reqIssueAlongWithTable; var deletedIssueTable; var dataTableRef; var selectedIssue; //선택한 이슈 var pdServiceListData; var versionListData; var jiraServerTypeMap; function execDocReady() { var pluginGroups = [ [ "js/reqStatus/batchManualControlApi.js", "../reference/lightblue4/docs/lib/slimScroll/jquery.slimscroll.min.js", "../reference/lightblue4/docs/lib/widgster/widgster.js", //날짜 설정 "../reference/light-blue/lib/bootstrap-datepicker.js", "../reference/jquery-plugins/datetimepicker-2.5.20/build/jquery.datetimepicker.min.css", "../reference/jquery-plugins/datetimepicker-2.5.20/build/jquery.datetimepicker.full.min.js" ], [ "../reference/jquery-plugins/select2-4.0.2/dist/css/select2_lightblue4.css", "../reference/jquery-plugins/lou-multi-select-0.9.12/css/multiselect-lightblue4.css", "../reference/jquery-plugins/multiple-select-1.5.2/dist/multiple-select-bluelight.css", "../reference/jquery-plugins/select2-4.0.2/dist/js/select2.min.js", "../reference/jquery-plugins/lou-multi-select-0.9.12/js/jquery.quicksearch.js", "../reference/jquery-plugins/lou-multi-select-0.9.12/js/jquery.multi-select.js", "../reference/jquery-plugins/multiple-select-1.5.2/dist/multiple-select.min.js" ], [ "../reference/jquery-plugins/dataTables-1.10.16/media/css/jquery.dataTables_lightblue4.css", "../reference/jquery-plugins/dataTables-1.10.16/extensions/Responsive/css/responsive.dataTables_lightblue4.css", "../reference/jquery-plugins/dataTables-1.10.16/extensions/Select/css/select.dataTables_lightblue4.css", "../reference/jquery-plugins/dataTables-1.10.16/media/js/jquery.dataTables.min.js", "../reference/jquery-plugins/dataTables-1.10.16/extensions/Responsive/js/dataTables.responsive.min.js", "../reference/jquery-plugins/dataTables-1.10.16/extensions/Select/js/dataTables.select.min.js", "../reference/jquery-plugins/dataTables-1.10.16/extensions/RowGroup/js/dataTables.rowGroup.min.js", "../reference/jquery-plugins/dataTables-1.10.16/extensions/Buttons/js/dataTables.buttons.min.js", "../reference/jquery-plugins/dataTables-1.10.16/extensions/Buttons/js/buttons.html5.js", "../reference/jquery-plugins/dataTables-1.10.16/extensions/Buttons/js/buttons.print.js", "../reference/jquery-plugins/dataTables-1.10.16/extensions/Buttons/js/jszip.min.js", // table_new "./js/common/table_new.js" ] ]; loadPluginGroupsParallelAndSequential(pluginGroups) .then(function () { console.log("모든 플러그인 로드 완료"); //vfs_fonts 파일이 커서 defer 처리 함. setTimeout(function () { var script = document.createElement("script"); script.src = "../reference/jquery-plugins/dataTables-1.10.16/extensions/Buttons/js/vfs_fonts.js"; script.defer = true; // defer 속성 설정 document.head.appendChild(script); }, 5000); // 5초 후에 실행됩니다. //pdfmake 파일이 커서 defer 처리 함. setTimeout(function () { var script = document.createElement("script"); script.src = "../reference/jquery-plugins/dataTables-1.10.16/extensions/Buttons/js/pdfmake.min.js"; script.defer = true; // defer 속성 설정 document.head.appendChild(script); }, 5000); // 5초 후에 실행됩니다. // 높이 조정 $(".status-top").matchHeight({ target: $(".status-top-statistics") }); //사이드 메뉴 처리 $(".widget").widgster(); setSideMenu("sidebar_menu_requirement", "sidebar_menu_requirement_status"); BatchManualControlApi.stepEventListenerStart(); // 데이터 테이블 빈값으로 초기화 dataTableLoad([]); $(document).trigger($.Event("init.issueList2Table")); // issueList1, issueList2 tabClickEvent(); //제품(서비스) 셀렉트 박스 이니시에이터 makePdServiceSelectBox(); //버전 멀티 셀렉트 박스 이니시에이터 makeVersionMultiSelectBox(); getServerTypeMap(); reqIssueAndItsSubtasksEvent(); deleteWithdrawalButton(); //날짜 dateTimePicker(); baseDateReset(); $("#progress_status").slimScroll({ height: "195px", railVisible: true, railColor: "#222", railOpacity: 0.3, wheelStep: 10, allowPageScroll: false, disableFadeOut: false }); $("#assign_status").slimScroll({ height: "195px", railVisible: true, railColor: "#222", railOpacity: 0.3, wheelStep: 10, allowPageScroll: false, disableFadeOut: false }); }) .catch(function (e) { console.error("플러그인 로드 중 오류 발생 =>", e); }); } //////////////////////////////////////////////////////////////////////////////////////// //제품 서비스 셀렉트 박스 //////////////////////////////////////////////////////////////////////////////////////// function makePdServiceSelectBox() { //제품 서비스 셀렉트 박스 이니시에이터 $(".chzn-select").each(function () { $(this).select2($(this).data()); }); //제품 서비스 셀렉트 박스 데이터 바인딩 $.ajax({ url: "/auth-user/api/arms/pdServicePure/getPdServiceMonitor.do", type: "GET", contentType: "application/json;charset=UTF-8", dataType: "json", progress: true, statusCode: { 200: function (data) { ////////////////////////////////////////////////////////// pdServiceListData = []; for (var k in data.response) { var obj = data.response[k]; pdServiceListData.push({ pdServiceId: obj.c_id, pdServiceName: obj.c_title }); var newOption = new Option(obj.c_title, obj.c_id, false, false); $("#selected_pdService").append(newOption).trigger("change"); } ////////////////////////////////////////////////////////// console.log("[reqStatus :: makePdServiceSelectBox] :: pdServiceListData => "); console.table(pdServiceListData); } } }); $("#selected_pdService").on("select2:open", function () { //슬림스크롤 makeSlimScroll(".select2-results__options"); }); // --- select2 ( 제품(서비스) 검색 및 선택 ) 이벤트 --- // $("#selected_pdService").on("select2:select", function (e) { selectedPdServiceId = $("#selected_pdService").val(); // 제품( 서비스 ) 선택했으니까 자동으로 버전을 선택할 수 있게 유도 // 디폴트는 base version 을 선택하게 하고 ( select all ) //~> 이벤트 연계 함수 :: Version 표시 jsTree 빌드 bind_VersionData_By_PdService(); }); } // end makePdServiceSelectBox() function reqStatusDashboard(pdServiceId, pdServiceVersionLinks) { $.ajax({ url: `/auth-user/api/arms/reqStatus/T_ARMS_REQSTATUS_${pdServiceId}/reqStatus-dashboard`, type: "GET", data: { "pdServiceAndIsReq.pdServiceLink": pdServiceId, "pdServiceAndIsReq.pdServiceVersionLinks": pdServiceVersionLinks }, contentType: "application/json;charset=UTF-8", dataType: "json", progress: true, statusCode: { 200: function (result) { const almServerCount = result.serverCount; const almProjectCount = result.projectCount; const reqIssueCount = result.reqIssueCount; const notReqIssueCount = result.notReqIssueCount; $("#alm_server_count").text(almServerCount); // 서버 수 $("#alm_project_count").text(almProjectCount); // 연결된 프로젝트 수 $("#req_count").text(reqIssueCount); // 요구사항 이슈 개수 $("#alm_issue_count").text(notReqIssueCount); // 연결된 ALM 이슈 수 // progress Load const statusMap = result.statusCountMap; drawStatusIssueCount(statusMap); // resource Load const resourceMap = result.resourceIssueCountMap; drawResourceIssueCount(resourceMap); } } }); } function drawStatusIssueCount(statusMap) { $("#progress_status").empty(); // 모든 자식 요소 삭제 var noStatusHtml = null; for (var key in statusMap) { var value = statusMap[key]; // console.log(key + "=" + value); var html_piece = '
\n' + "✡ " + key + ' : ' + value + "\n" + "
"; if (key === "No Status") { noStatusHtml = html_piece; } else { // 일반적인 경우 그대로 append $("#progress_status").append(html_piece); } } // loop 마무리후 기입 if (noStatusHtml) { $("#progress_status").append(noStatusHtml); } } function drawResourceIssueCount(resourceMap) { $("#assign_status").empty(); // 모든 자식 요소 삭제 var notAssignedHtml = null; for (var key in resourceMap) { var value = resourceMap[key]; // console.log(key + "=" + value); var html_piece = '
\n' + "✡ " + key + ' : ' + value + "\n" + "
"; if (key === "Not Assigned") { notAssignedHtml = html_piece; } else { // 일반적인 경우 그대로 append $("#assign_status").append(html_piece); } } // loop 마무리후 기입 if (notAssignedHtml) { $("#assign_status").append(notAssignedHtml); } } function statisticsLoad(pdservice_id, pdservice_version_id) { //제품 서비스 셀렉트 박스 데이터 바인딩 $.ajax({ url: `/auth-user/api/arms/reqStatus/T_ARMS_REQSTATUS_${pdservice_id}/getStatistics.do?version=${pdservice_version_id}`, type: "GET", contentType: "application/json;charset=UTF-8", dataType: "json", progress: true, statusCode: { 200: function (data) { console.log("statisticsLoad :: data => ", data); for (var key in data) { var value = data[key]; } $("#version_count").text(data["version"]); // 버전수 } } }); } //////////////////////////////////////////////////////////////////////////////////////// //버전 멀티 셀렉트 박스 //////////////////////////////////////////////////////////////////////////////////////// function makeVersionMultiSelectBox() { //버전 선택 셀렉트 박스 이니시에이터 $(".multiple-select").multipleSelect({ filter: true, onClose: function () { console.log("onOpen event fire!\n"); var checked = $("#checkbox1").is(":checked"); var endPointUrl = ""; var versionTag = $(".multiple-select").val(); console.log("[ reqStatus :: makeVersionMultiSelectBox ] :: versionTag"); console.log(versionTag); selectedVersionId = versionTag.join(","); if (versionTag === null || versionTag == "") { jError("버전이 선택되지 않았습니다."); $(".ms-parent").css("z-index", 1000); return; } // 통계로드 statisticsLoad($("#selected_pdService").val(), selectedVersionId); // 진행상태, 작업자 로드 reqStatusDashboard($("#selected_pdService").val(), selectedVersionId); // active tab 확인 및 API 호출 callActiveTabApi(); $(".ms-parent").css("z-index", 1000); }, onOpen: function () { console.log("open event"); $(".ms-parent").css("z-index", 9999); } }); } function bind_VersionData_By_PdService() { $(".multiple-select option").remove(); $.ajax({ url: "/auth-user/api/arms/pdService/getVersionList?c_id=" + $("#selected_pdService").val(), type: "GET", dataType: "json", progress: true, statusCode: { 200: function (data) { ////////////////////////////////////////////////////////// var pdServiceVersionIds = []; versionListData = []; for (var k in data.response) { var obj = data.response[k]; pdServiceVersionIds.push(obj.c_id); versionListData.push(obj); var newOption = new Option(obj.c_title, obj.c_id, true, false); $(".multiple-select").append(newOption); } if (data.length > 0) { console.log("display 재설정."); } console.log(pdServiceVersionIds); selectedVersionId = pdServiceVersionIds.join(","); console.log("bind_VersionData_By_PdService :: selectedVersionId"); console.log(selectedVersionId); // 통계로드 (버전수) statisticsLoad($("#selected_pdService").val(), selectedVersionId); // 진행상태, 작업자 로드 reqStatusDashboard($("#selected_pdService").val(), selectedVersionId); var endPointUrl = ""; // issueList > issueList1 - click trigger // 버전 바인드 時 event trigger if ($("#nav-issueList1").hasClass("active")) { $('a[href="#issueList1"]').trigger("shown.bs.tab"); } else { $("#nav-issueList1>a").click(); } $("#deleted_issue_report_modal").on("shown.bs.modal", function (event) { endPointUrl = "/T_ARMS_REQSTATUS_" + $("#selected_pdService").val() + "/deletedIssueList?pdServiceVersionLinks=" + selectedVersionId; getDeletedIssueData($("#selected_pdService").val(), endPointUrl); }); $(".multiple-select").multipleSelect("refresh"); ////////////////////////////////////////////////////////// } } }); } //////////////////////////////////////////////////////////////////////////////////////// // issueList 가져오기 (Req - Subtask) //////////////////////////////////////////////////////////////////////////////////////// function getReqStatusTableData(pdServiceId, pdServiceVersionLinks) { let urlBuilder = new UrlBuilder().setBaseUrl( `/auth-user/api/arms/reqStatus/T_ARMS_REQSTATUS_${pdServiceId}/issue-list-by-updated` ); // getHierarchicalAlmIssues if (pdServiceVersionLinks !== undefined) { urlBuilder.addQueryParam("pdServiceVersionLinks", pdServiceVersionLinks); } const url = urlBuilder.build(); $.ajax({ url: url, type: "GET", contentType: "application/json;charset=UTF-8", dataType: "json", success: function (apiResponse) { let data = apiResponse; console.log("[ reqStatus :: getReqStatusTableData ] :: data => ", data); dataTableLoad(data.response); }, error: function (xhr, status, error) { console.error(error); } }); } //////////////////////////////////////////////////////////////////////////////////////// // issueList - (issueList order by created desc regardless isReq) //////////////////////////////////////////////////////////////////////////////////////// function getIssueList2TableData(pdServiceId, pdServiceVersionLinks) { $.ajax({ url: `/auth-user/api/arms/reqStatus/issue-list-by-updated-2nd`, type: "GET", data: { "pdServiceAndIsReq.pdServiceLink": pdServiceId, "pdServiceAndIsReq.pdServiceVersionLinks": pdServiceVersionLinks }, contentType: "application/json;charset=UTF-8", dataType: "json", success: function (apiResponse) { let data = apiResponse; console.log("[ reqStatus :: getIssueList2TableData ] :: data.length ===> ", data ? data.length : 0); $("#issueList2Table").table().reDraw(data); }, error: function (xhr, status, error) { console.error(error); } }); } function format() { return `
요구사항 구분 ALM Issue Key Version ALM Issue Title ALM project ALM Assignee ALM Issue Type ALM Priority ALM Status ALM Overall Update ALM Created ALM Updated ALM Resolution ALM Deleted
`; } function initializeChildTable(childrenData, container, upperIsReqName) { var columnList = [ { name: "icon", title: "", data: null, render: function (data, type, row) { console.log("upperIsReqName => ", upperIsReqName); if (upperIsReqName && upperIsReqName.includes(row.almIssue.key)) { console.log("상위 이슈의 키와 중복됩니다. 하위 표시X. 해당 이슈 키 =>", row.almIssue.key); return ""; } else if (row.subtaskCount > 0 || row.linkedIssueCount > 0) { return ""; } else { return ""; } }, className: "details-control", orderable: false, visible: true }, { name: "isReqName", title: "요구사항 구분", data: "isReqName", render: function (data, type, row) { var deletedDate = row.almIssue.deleted; if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = formatIsReqName(data); let color = "#f8f8f8"; // 기본 텍스트 색상 if (deletedDate && deletedDate !== "") { color = "#808080"; } return "
" + displayText + "
"; } }, className: "dt-body-left", orderable: false, visible: true }, { name: "key", title: "ALM Issue Key", data: "almIssue.key", render: function (data, type, row, meta) { var deletedDate = row.almIssue.deleted; if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = data; let color = "#f8f8f8"; // 기본 텍스트 색상 if (deletedDate && deletedDate !== "") { color = "#808080"; } return "
" + displayText + "
"; } }, className: "dt-body-left", orderable: false, visible: true }, { name: "pdServiceVersionNames", title: "Version", data: "pdServiceVersionNames", render: function (data, type, row) { var deletedDate = row.almIssue.deleted; if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let color = "#f8f8f8"; // 기본 텍스트 색상 if (deletedDate && deletedDate !== "") { color = "#808080"; } return "
" + data + "
"; } }, className: "dt-body-left", orderable: false, visible: true }, { name: "summary", title: "ALM Issue Title", data: "almIssue.summary", render: function (data, type, row, meta) { var deletedDate = row.almIssue.deleted; if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let color = "#f8f8f8"; // 기본 텍스트 색상 if (deletedDate && deletedDate !== "") { color = "#808080"; } return "
" + data + "
"; } }, className: "dt-body-left", orderable: false, visible: true }, { name: "project_name", title: "ALM project", data: "almIssue.project.project_name", render: function (data, type, row, meta) { var deletedDate = row.almIssue.deleted; if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = data; let color = "#f8f8f8"; // 기본 텍스트 색상 if (deletedDate && deletedDate !== "") { color = "#808080"; } return "
" + displayText + "
"; } }, className: "dt-body-left", orderable: false, visible: true }, { name: "assignee_displayName", title: "ALM Assignee", data: "almIssue.assignee.assignee_displayName", render: function (data, type, row, meta) { var deletedDate = row.almIssue.deleted; if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = data; let color = "#f8f8f8"; // 기본 텍스트 색상 if (deletedDate && deletedDate !== "") { color = "#808080"; } return "
" + displayText + "
"; } }, className: "dt-body-left", orderable: false, visible: true }, { name: "issuetype_name", title: "ALM Issue Type", data: "almIssue.issuetype.issuetype_name", render: function (data, type, row, meta) { var deletedDate = row.almIssue.deleted; if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = data; let color = "#f8f8f8"; // 기본 텍스트 색상 if (deletedDate && deletedDate !== "") { color = "#808080"; } return "
" + displayText + "
"; } }, className: "dt-body-left", orderable: false, visible: true }, { name: "priority_name", title: "ALM Priority", data: "almIssue.priority.priority_name", render: function (data, type, row, meta) { var deletedDate = row.almIssue.deleted; if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = data; let color = "#f8f8f8"; // 기본 텍스트 색상 if (deletedDate && deletedDate !== "") { color = "#808080"; } return "
" + displayText + "
"; } }, className: "dt-body-left", orderable: false, visible: true }, { name: "status_name", title: "ALM Status", data: "almIssue.status.status_name", render: function (data, type, row, meta) { var deletedDate = row.almIssue.deleted; if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = data; let color = "#f8f8f8"; // 기본 텍스트 색상 if (deletedDate && deletedDate !== "") { color = "#808080"; } return "
" + displayText + "
"; } }, className: "dt-body-left", orderable: false, visible: true }, { name: "overallUpdatedDate", title: "ALM Overall Update", data: "almIssue.overallUpdatedDate", render: function (data, type, row, meta) { var deletedDate = row.almIssue.deleted; if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = dateFormatSlash(data); let color = "#f8f8f8"; // 기본 텍스트 색상 if (deletedDate && deletedDate !== "") { color = "#808080"; } return "
" + displayText + "
"; } }, className: "dt-body-left", orderable: false, visible: false }, { name: "almIssue.created", title: "ALM Created", data: "almIssue.created", render: function (data, type, row, meta) { var deletedDate = row.almIssue.deleted; if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = dateFormatSlash(data); let color = "#f8f8f8"; // 기본 텍스트 색상 if (deletedDate && deletedDate !== "") { color = "#808080"; } return "
" + displayText + "
"; } }, className: "dt-body-left", orderable: false, visible: true }, { name: "almIssue.updated", title: "ALM Updated", data: "almIssue.updated", render: function (data, type, row, meta) { var deletedDate = row.almIssue.deleted; if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = dateFormatSlash(data); let color = "#f8f8f8"; // 기본 텍스트 색상 if (deletedDate && deletedDate !== "") { color = "#808080"; } return "
" + displayText + "
"; } return data; }, className: "dt-body-left", orderable: false, visible: true }, { name: "resolutiondate", title: "ALM Resolution", data: "almIssue.resolutiondate", render: function (data, type, row, meta) { var deletedDate = row.almIssue.deleted; if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = dateFormatSlash(data); let color = "#f8f8f8"; // 기본 텍스트 색상 if (deletedDate && deletedDate !== "") { color = "#808080"; } return "
" + displayText + "
"; } }, className: "dt-body-left", orderable: false, visible: true }, { name: "deleted", title: "ALM Deleted", data: "almIssue.deleted.deleted_date", render: function (data, type, row, meta) { if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = dateFormatSlash(data); let color = "#808080"; return "
" + displayText + "
"; } }, className: "dt-body-left", orderable: false, visible: true }, { name: "children", title: "자식 데이터", data: "children", render: function (data, type, row, meta) { if (row.children && row.children.length > 0) { // versionListData를 미리 매핑해놓은 객체 console.log("child data => ", data); return data; } else { return ""; } }, className: "dt-body-left", visible: false }, { name: "parentReqKey", title: "부모 요구사항 키", data: "almIssue.parentReqKey", visible: false }, { name: "isReq", title: "isReq", data: "almIssue.isReq", visible: false }, { name: "subtaskCount", title: "subtaskCount", data: "subtaskCount", visible: false }, { name: "linkedIssues", title: "linkedIssues", data: "almIssue.linkedIssues", visible: false }, { name: "linkedIssueCount", title: "linkedIssueCount", data: "linkedIssueCount", visible: false }, { name: "pdServiceVersions", title: "Version", data: "almIssue.pdServiceVersions", visible: false } ]; var columnDefList = [ { defaultContent: "
N/A
", targets: "_all" } ]; var orderList = []; var rowsGroupList = []; var buttonList = []; var childTable = container.find("table.child-table").DataTable({ data: childrenData, columns: columnList, columnDefs: columnDefList, order: orderList, rowsGroup: rowsGroupList, buttons: buttonList, paging: false, searching: false, info: false, responsive: { details: false // 기본 동작 비활성화 }, autoWidth: false }); container .find("tbody") .off("click", "tr, td.details-control") .on("click", "tr, td.details-control", function (event) { // 이벤트 전파 중지 event.stopPropagation(); var tr = $(this).closest("tr"); var row = childTable.row(tr); let rowData = row.data(); if (row.child.isShown()) { row.child.hide(); tr.removeClass("shown"); } else { let rowIsReqName = rowData.isReqName; if (row.data().children && row.data().children.length > 0) { row.child(format(row.data())).show(); tr.addClass("shown"); initializeChildTable(row.data().children, tr.next("tr").find("div.child-table-container"), rowIsReqName); } else { if (!row.data().fetchingChildren) { row.data().fetchingChildren = true; fetchChildren( rowData.almIssue.key, rowData.almIssue.parentReqKey ? rowData.almIssue.parentReqKey : "", rowData.almIssue.upperKey ? rowData.almIssue.upperKey : "", rowData.subtaskCount ? rowData.subtaskCount : 0, rowData.linkedIssueCount ? rowData.linkedIssueCount : 0, rowData.almIssue.linkedIssues ? rowData.almIssue.linkedIssues : null ) .then((children) => { row.data().fetchingChildren = false; // 가져온데이터를 row.data().children 에 추가(대입) row.data().children = children; // 데이터 랜더링 row.child(format(row.data())).show(); tr.addClass("shown"); initializeChildTable(children, tr.next("tr").find("div.child-table-container"), rowIsReqName); }) .catch((error) => { row.data().fetchingChildren = false; console.error("Failed to fetch children:", error); }); } } } }); } //////////////////////////////////////////////////////////////////////////////////////// //데이터 테이블 //////////////////////////////////////////////////////////////////////////////////////// // -------------------- 데이터 테이블을 만드는 템플릿으로 쓰기에 적당하게 리팩토링 함. ------------------ // function dataTableLoad(tableData) { var columnList = [ { name: "icon", title: "", data: null, render: function (data, type, row) { if (containsRequirement(row.isReqName)) { return ""; } else if (row.subtaskCount > 0 || row.linkedIssueCount > 0) { return ""; } else { return ""; } }, className: "details-control", orderable: false, visible: true }, { name: "isReqName", title: "요구사항 구분", data: "isReqName", render: function (data, type, row) { var isReqSort = row.almIssue.isReq; var deletedDate = row.almIssue.deleted; if (isEmpty(data)) { return "
N/A
"; } else { let displayText = data; let color; displayText = formatLinkIssue(displayText); if (data.endsWith("_link")) { color = "#f8f8f8"; // 기본 텍스트 색상 } else if (!isEmpty(isReqSort) && isReqSort === true) { color = "#a4c6ff"; } else { color = "#f8f8f8"; // 기본 텍스트 색상 } if (deletedDate && deletedDate !== "") { color = "#808080"; } return "
" + displayText + "
"; } }, className: "dt-body-left", orderable: false, visible: true }, { name: "key", title: "ALM Issue Key", data: "almIssue.key", render: function (data, type, row, meta) { var isReqSort = row.almIssue.isReq; var deletedDate = row.almIssue.deleted; if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = data; let color = textColor(row.isReqName, isReqSort); // 삭제 여부 if (deletedDate && deletedDate !== "") { color = "#808080"; } // 요구사항 이슈 여부 if (!isEmpty(isReqSort) && isReqSort) { let btn_data_row1 = { pdServiceVersions: row.almIssue.pdServiceVersions.join(","), cReqLink: row.almIssue.creqLink }; return ( "
" + displayText + $("
" ); } else { return "
" + displayText + "
"; } } return data; }, className: "dt-body-left", orderable: false, visible: true }, { name: "pdServiceVersionNames", title: "Version", data: "pdServiceVersionNames", render: function (data, type, row) { var isReqSort = row.almIssue.isReq; var deletedDate = row.almIssue.deleted; if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let color = textColor(row.isReqName, isReqSort); if (deletedDate && deletedDate !== "") { color = "#808080"; } return "
" + data + "
"; } return data; }, className: "dt-body-left", orderable: false, visible: true }, { name: "summary", title: "ALM Issue Title", data: "almIssue.summary", render: function (data, type, row, meta) { var isReqSort = row.almIssue.isReq; var deletedDate = row.almIssue.deleted; if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let color = textColor(row.isReqName, isReqSort); if (deletedDate && deletedDate !== "") { color = "#808080"; } return "
" + data + "
"; } return data; }, className: "dt-body-left", orderable: false, visible: true }, { name: "project_name", title: "ALM project", data: "almIssue.project.project_name", render: function (data, type, row) { var isReqSort = row.almIssue.isReq; var deletedDate = row.almIssue.deleted; if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let color = textColor(row.isReqName, isReqSort); if (deletedDate && deletedDate !== "") { color = "#808080"; } return "
" + data + "
"; } return data; }, className: "dt-body-left", orderable: false, visible: true }, { name: "assignee_displayName", title: "ALM Assignee", data: "almIssue.assignee.assignee_displayName", render: function (data, type, row) { var isReqSort = row.almIssue.isReq; var deletedDate = row.almIssue.deleted; if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let color = textColor(row.isReqName, isReqSort); if (deletedDate && deletedDate !== "") { color = "#808080"; } return "
" + data + "
"; } }, className: "dt-body-left", visible: true }, { name: "issuetype_name", title: "ALM Issue Type", data: "almIssue.issuetype.issuetype_name", render: function (data, type, row, meta) { var isReqSort = row.almIssue.isReq; var deletedDate = row.almIssue.deleted; if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let color = textColor(row.isReqName, isReqSort); if (deletedDate && deletedDate !== "") { color = "#808080"; } return "
" + data + "
"; } }, className: "dt-body-left", orderable: false, visible: true }, { name: "priority_name", title: "ALM Priority", data: "almIssue.priority.priority_name", render: function (data, type, row, meta) { var isReqSort = row.almIssue.isReq; var deletedDate = row.almIssue.deleted; if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let color = textColor(row.isReqName, isReqSort); if (deletedDate && deletedDate !== "") { color = "#808080"; } return "
" + data + "
"; } }, className: "dt-body-left", orderable: false, visible: true }, { name: "status_name", title: "ALM Status", data: "almIssue.status.status_name", render: function (data, type, row, meta) { var isReqSort = row.almIssue.isReq; var deletedDate = row.almIssue.deleted; if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let color = textColor(row.isReqName, isReqSort); if (deletedDate && deletedDate !== "") { color = "#808080"; } return "
" + data + "
"; } }, className: "dt-body-left", orderable: false, visible: true }, { name: "overallUpdatedDate", title: "ALM Overall Update", data: "almIssue.overallUpdatedDate", render: function (data, type, row, meta) { var isReqSort = row.almIssue.isReq; var deletedDate = row.almIssue.deleted; if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = dateFormatSlash(data); let color = textColor(row.isReqName, isReqSort); if (deletedDate && deletedDate !== "") { color = "#808080"; } return "
" + displayText + "
"; } }, className: "dt-body-left", orderable: false, visible: false }, { name: "created", title: "ALM Created", data: "almIssue.created", render: function (data, type, row, meta) { var isReqSort = row.almIssue.isReq; var deletedDate = row.almIssue.deleted; if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = dateFormatSlash(data); let color = textColor(row.isReqName, isReqSort); if (deletedDate && deletedDate !== "") { color = "#808080"; } return "
" + displayText + "
"; } }, className: "dt-body-left", orderable: false, visible: true }, { name: "updated", title: "ALM Updated", data: "almIssue.updated", render: function (data, type, row, meta) { var isReqSort = row.almIssue.isReq; var deletedDate = row.almIssue.deleted; if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = dateFormatSlash(data); let color = textColor(row.isReqName, isReqSort); if (deletedDate && deletedDate !== "") { color = "#808080"; } return "
" + displayText + "
"; } }, className: "dt-body-left", orderable: false, visible: true }, { name: "resolutiondate", title: "ALM Resolution", data: "almIssue.resolutiondate", render: function (data, type, row, meta) { var isReqSort = row.almIssue.isReq; var deletedDate = row.almIssue.deleted; if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = dateFormatSlash(data); let color = textColor(row.isReqName, isReqSort); if (deletedDate && deletedDate !== "") { color = "#808080"; } return "
" + displayText + "
"; } }, className: "dt-body-left", orderable: false, visible: true }, { name: "deleted", title: "ALM Deleted", data: "almIssue.deleted", render: function (data, type, row, meta) { if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = dateFormatSlash(data); let color = "#808080"; return "
" + displayText + "
"; } return data; }, className: "dt-body-left", orderable: false, visible: true }, { name: "children", title: "자식 데이터", data: "children", render: function (data, type, row, meta) { if (row.children && row.children.length > 0) { // versionListData를 미리 매핑해놓은 객체 console.log("child data => ", data); return data; } else { return ""; } }, className: "dt-body-left", visible: false }, { name: "parentReqKey", title: "부모 요구사항 키", data: "almIssue.parentReqKey", visible: false }, { name: "isReq", title: "isReq", data: "almIssue.isReq", visible: false }, { name: "subtaskCount", title: "subtaskCount", data: "subtaskCount", visible: false }, { name: "linkedIssues", title: "linkedIssues", data: "almIssue.linkedIssues", visible: false }, { name: "linkedIssueCount", title: "linkedIssueCount", data: "linkedIssueCount", visible: false }, { name: "pdServiceVersions", title: "Version", data: "almIssue.pdServiceVersions", visible: false } ]; var rowsGroupList = []; var columnDefList = [ { defaultContent: "
N/A
", targets: "_all" } ]; var orderList = []; var jquerySelector = "#reqstatustable"; var ajaxUrl = ""; var jsonRoot = ""; var buttonList = [ "copy", "excel", "print", { extend: "csv", text: "Export csv", charset: "utf-8", extension: ".csv", fieldSeparator: ",", fieldBoundary: "", bom: true }, { extend: "pdfHtml5", orientation: "landscape", pageSize: "LEGAL" } ]; var selectList = {}; var isServerSide = false; var isAjax = false; reqStatusDataTable = dataTable_build( jquerySelector, ajaxUrl, jsonRoot, columnList, rowsGroupList, columnDefList, selectList, orderList, buttonList, isServerSide, 700, tableData, isAjax ); reqStatusDataTable.columns.adjust(); } // 데이터 테이블 구성 이후 꼭 구현해야 할 메소드 : 열 클릭시 이벤트 function dataTableClick(tempDataTable, selectedData) { console.log(selectedData); selectedIssue = selectedData; } // 데이터 테이블 데이터 렌더링 이후 콜백 함수. function dataTableCallBack(settings, json) { console.log("check"); if (settings.nTable.id !== "reqstatustable") { return; } // 테이블 행 클릭 이벤트 (하위 이슈 조회) $("#reqstatustable tbody") .off("click", "td.details-control") .on("click", "td.details-control", function () { const tr = $(this).closest("tr"); const row = reqStatusDataTable.row(tr); console.log("tr => ", tr, ", row => ", row); console.log("클릭한 row.data() => ", row.data()); let rowData = row.data(); const icon = $(this).find("i"); if (icon.length === 0) { return; } console.log("테이블 행 클릭 이벤트"); if (row.child.isShown()) { console.log("테이블 행 클릭 이벤트 펼침 :: child 존재"); row.child.hide(); tr.removeClass("shown"); icon.removeClass("fa-angle-up").addClass("fa-angle-down"); } else { console.log("테이블 행 클릭 이벤트 펼침 :: child 없음"); let rowIsReqName = rowData.isReqName; if (row.data().children && row.data().children.length > 0) { row.child(format(row.data())).show(); tr.addClass("shown"); icon.removeClass("fa-angle-down").addClass("fa-angle-up"); initializeChildTable(row.data().children, tr.next("tr").find("div.child-table-container"), rowIsReqName); } else { console.log("rowData.almIssue.linkedIssues => ", rowData.almIssue.linkedIssues); fetchChildren( rowData.almIssue.key, rowData.almIssue.parentReqKey ? rowData.almIssue.parentReqKey : "", rowData.almIssue.upperKey ? rowData.almIssue.upperKey : "", rowData.subtaskCount ? rowData.subtaskCount : 0, rowData.linkedIssueCount ? rowData.linkedIssueCount : 0, rowData.almIssue.linkedIssues ? rowData.almIssue.linkedIssues : null ) .then((children) => { // 가져온데이터를 row.data().children 에 추가(대입) row.data().children = children; // 데이터 랜더링 row.child(format(row.data())).show(); tr.addClass("shown"); icon.removeClass("fa-angle-down").addClass("fa-angle-up"); initializeChildTable(children, tr.next("tr").find("div.child-table-container"), rowIsReqName); }) .catch((error) => { console.error("Failed to fetch children:", error); }); } /*row.child(format()).show(); tr.addClass("shown"); icon.removeClass("fa-angle-down").addClass("fa-angle-up"); initializeChildTable(row.data().children, tr.next("tr").find("div.child-table-container"));*/ } }); } function dataTableDrawCallback(tableInfo) { console.log("dataTableDrawCallback :: scrollPos => ", scrollPos); } $("#copychecker").on("click", function () { reqStatusDataTable.button(".buttons-copy").trigger(); }); $("#printchecker").on("click", function () { reqStatusDataTable.button(".buttons-print").trigger(); }); $("#csvchecker").on("click", function () { reqStatusDataTable.button(".buttons-csv").trigger(); }); $("#excelchecker").on("click", function () { reqStatusDataTable.button(".buttons-excel").trigger(); }); $("#pdfchecker").on("click", function () { reqStatusDataTable.button(".buttons-pdf").trigger(); }); function reqIssueAndItsSubtasksEvent() { let $modalBtn_alongWith; $("#reqIssue_alongWith_modal").on("shown.bs.modal", function (event) { $modalBtn_alongWith = $(event.relatedTarget); var selectedRow = $modalBtn_alongWith.data("row"); var endPointUrl = "/T_ARMS_REQSTATUS_" + selectedPdServiceId + "/reqIssues-created-together.do?" + "pdServiceVersions=" + selectedRow.pdServiceVersions + "&cReqLink=" + selectedRow.cReqLink; getReqIssuesCreatedTogether(endPointUrl); }); } function getReqIssuesCreatedTogether(endPointUrl) { var columnList = [ { name: "summary", title: "ALM Issue Title ", data: "summary", render: function (data, type, row, meta) { if (isEmpty(data) || data === "unknown") { return "
N/A
"; } else { return "
" + data + "
"; } return data; }, className: "dt-body-left", visible: true }, { name: "key", title: "ALM Issue Key", data: "key", render: function (data, type, row, meta) { if (isEmpty(data) || data === "unknown") { return "
N/A
"; } else { let serverType = getServerType(row.jira_server_id); console.log("serverType => " + serverType); let alm_link = makeALMIssueLink(serverType, row.self, data); return ( "
" + data + $("
" ); } return data; }, className: "dt-body-left", visible: true }, ///////////////// 지라프로젝트 정보 ///////////// { name: "project.project_name", title: "ALM Project", data: "project.project_name", render: function (data, type, row, meta) { if (isEmpty(data) || data === "false") { return "
N/A
"; } else { if (isEmpty(row.isReq) || row.isReq == false) { return "
" + data + "
"; } return "
" + data + "
"; } return data; }, className: "dt-body-left", visible: true }, { name: "parentReqKey", title: "부모이슈 키", data: function (row, type, set, meta) { return row.parentReqKey ? row.parentReqKey : null; }, render: function (data, type, row, meta) { if (isEmpty(data) || data === "unknown") { return "
N/A
"; } else { return "
" + data + "
"; } return data; }, className: "dt-body-left", visible: false }, { name: "issuetype.issuetype_name", title: "Issue Type", data: "issuetype.issuetype_name", render: function (data, type, row, meta) { if (isEmpty(data) || data === "false") { return "
N/A
"; } else { if (isEmpty(row.isReq) || row.isReq == false) { return "
" + data + "
"; } return "
" + data + "
"; } return data; }, className: "dt-body-left", visible: false }, { name: "status.status_name", title: "Issue Status", data: "status.status_name", render: function (data, type, row, meta) { if (isEmpty(data) || data === "unknown") { return "
N/A
"; } else { return "
" + data + "
"; } return data; }, className: "dt-body-left", visible: true }, { name: "priority", title: "Issue Priority", data: "priority.priority_name", render: function (data, type, row, meta) { if (isEmpty(data) || data === "unknown") { return "
N/A
"; } else { return "
" + data + "
"; } return data; }, className: "dt-body-left", visible: true }, { name: "assignee.assignee_displayName", title: "Issue Assignee", data: function (row, type, set, meta) { return row.assignee ? row.assignee.assignee_displayName : null; }, render: function (data, type, row, meta) { //if (isEmpty(data) || data === "unknown") { if ([null, undefined, ""].includes(data)) { return "
N/A
"; } else { return "
" + data + "
"; } return data; }, className: "dt-body-left", visible: true }, { name: "reporter.reporter_displayName", title: "Issue Reporter", data: "reporter.reporter_displayName", render: function (data, type, row, meta) { if (isEmpty(data) || data === "unknown") { return "
N/A
"; } else { return "
" + data + "
"; } return data; }, className: "dt-body-left", visible: true }, { name: "created", title: "ALM Created", data: "created", render: function (data, type, row, meta) { if (isEmpty(data) || data === "unknown") { return "
N/A
"; } else { return "
" + dateFormat(data) + "
"; } return data; }, className: "dt-body-left", visible: true }, { name: "updated", title: "ALM Updated", data: "updated", render: function (data, type, row, meta) { if (isEmpty(data) || data === "unknown") { return "
N/A
"; } else { return "
" + dateFormat(data) + "
"; } return data; }, className: "dt-body-left", visible: true }, { name: "isReq", title: "요구사항 구분", data: "isReq", render: function (data, type, row, meta) { if (isEmpty(data) || data == false) { return "
연결 이슈
"; } else { return "
요구사항 이슈
"; } return data; }, className: "dt-body-left", visible: false }, { name: "issueID", title: "이슈아이디", data: "issueID", render: function (data, type, row, meta) { if (isEmpty(data) || data === "unknown") { return "
N/A
"; } else { return "
" + data + "
"; } return data; }, className: "dt-body-left", visible: false } ]; var rowsGroupList = [0]; var columnDefList = []; var orderList = [[1, "asc"]]; var jquerySelector = "#reqIssue_alongWith_table"; var ajaxUrl = "/auth-user/api/arms/reqStatus" + endPointUrl; var jsonRoot = "response"; var buttonList = []; var selectList = {}; var isServerSide = false; var errorMode = false; reqIssueAlongWithTable = dataTable_build( jquerySelector, ajaxUrl, jsonRoot, columnList, rowsGroupList, columnDefList, selectList, orderList, buttonList, isServerSide, errorMode ); } function getDeletedIssueData(selectId, endPointUrl) { var columnList = [ { name: "select", title: "", // 전체 선택 체크박스 data: null, render: function (data, type, row, meta) { return ""; }, orderable: false, // 정렬 비활성화 className: "dt-body-center", visible: true }, { name: "isReq", title: "요구사항 구분", data: "isReq", render: function (data, type, row, meta) { if (isEmpty(data) || data == false) { return "
" + row.parentReqKey + "의 연결 이슈
"; } else { return "
" + row.key + "
"; } return data; }, className: "dt-body-left", visible: true }, { name: "key", title: "ALM Issue Key", data: "key", render: function (data, type, row, meta) { if (isEmpty(data) || data === "false") { return "
N/A
"; } else { if (isEmpty(row.isReq) || row.isReq == false) { return "
" + data + "
"; } return "
" + data + "
"; } return data; }, className: "dt-body-left", visible: true }, { name: "pdServiceVersions", title: "Version", data: "pdServiceVersions", render: function (data, type, row, meta) { if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let verNameList = []; let verHtml = ``; data.forEach((version_id) => { let versionInfo = versionListData.find((version) => version["c_id"] === version_id); if (versionInfo) { verNameList.push(versionInfo["c_title"]); verHtml += versionInfo["c_title"] + `
`; } }); if (isEmpty(row.isReq) || row.isReq == false) { return "
" + verHtml + "
"; } else { return "
" + verHtml + "
"; } } return data; }, className: "dt-body-left", visible: true }, { name: "summary", title: "ALM Issue Title", data: "summary", render: function (data, type, row, meta) { if (isEmpty(data) || data === "false") { return "
N/A
"; } else { if (isEmpty(row.isReq) || row.isReq == false) { return "
" + data + "
"; } return "
" + data + "
"; } return data; }, className: "dt-body-left", visible: true }, { name: "project.project_key", title: "ALM project", data: "project.project_name", render: function (data, type, row, meta) { if (isEmpty(data) || data === "false") { return "
N/A
"; } else { if (isEmpty(row.isReq) || row.isReq == false) { return "
" + data + "
"; } return "
" + data + "
"; } return data; }, className: "dt-body-left", visible: true }, { name: "assignee.assignee_displayName", title: "ALM Assignee", data: "assignee.assignee_displayName", render: function (data, type, row, meta) { if (isEmpty(data) || data === "false") { return "
N/A
"; } else { if (isEmpty(row.isReq) || row.isReq == false) { return "
" + data + "
"; } else { return "
" + data + "
"; } } }, className: "dt-body-left", visible: true }, { name: "deleted", title: "ALM Deleted", data: "deleted.deleted_date", render: function (data, type, row, meta) { if (isEmpty(data) || data === "false") { return "
N/A
"; } else { if (isEmpty(row.isReq) || row.isReq == false) { return "
" + data + "
"; } return "
" + data + "
"; } return data; }, className: "dt-body-left", visible: true }, { name: "deleted", title: "삭제 예정일", data: "deleted.deleted_date", render: function (data, type, row, meta) { if (isEmpty(data) || data === "false") { return "
N/A
"; } else { var date = new Date(data); date.setDate(date.getDate() + 2); let year = date.getFullYear(); let month = String(date.getMonth() + 1).padStart(2, "0"); let day = String(date.getDate()).padStart(2, "0"); let newDateString = `${year}-${month}-${day}`; if (isEmpty(row.isReq) || row.isReq == false) { return "
" + newDateString + "
"; } return "
" + newDateString + "
"; } return data; }, className: "dt-body-left", visible: true } ]; var rowsGroupList = []; var columnDefList = [ { defaultContent: "
N/A
", targets: "_all" } ]; var orderList = [[1, "asc"]]; var jquerySelector = "#deletedIssueTable"; var ajaxUrl = "/auth-user/api/arms/reqStatus" + endPointUrl; var jsonRoot = "response"; var buttonList = []; var selectList = {}; var isServerSide = false; deletedIssueTable = dataTable_build( jquerySelector, ajaxUrl, jsonRoot, columnList, rowsGroupList, columnDefList, selectList, orderList, buttonList, isServerSide ); } function toggleAll(source) { const checkboxes = document.querySelectorAll(".rowCheckbox"); checkboxes.forEach((checkbox) => { checkbox.checked = source.checked; }); } function getCheckedData() { const checkedData = []; const checkboxes = document.querySelectorAll(".rowCheckbox:checked"); checkboxes.forEach((checkbox) => { const rowData = deletedIssueTable.row(checkbox.closest("tr")).data(); checkedData.push(rowData); }); if (checkedData.length === 0) { jError("체크된 데이터가 없습니다."); } else { const confirmation = confirm("삭제를 철회하시겠습니까?"); if (confirmation) { deleteWithdrawal(checkedData); } } return checkedData; } function deleteWithdrawal(checkedData) { var data = removeKeysFromArray(checkedData, ["selectedIndex", "selectedPage"]); $.ajax({ url: "/auth-user/api/arms/reqStatus/deleteWithdrawal.do", type: "PUT", contentType: "application/json", data: JSON.stringify(checkedData), statusCode: { 200: function () { jSuccess("삭제가 철회되었습니다."); $("#deleted_issue_report_modal").modal("hide"); } } }); } function removeKeysFromArray(array, keys) { array.forEach((item) => { keys.forEach((key) => { delete item[key]; }); }); } // 버튼 클릭 이벤트 연결 function deleteWithdrawalButton() { document.getElementById("deleteWithdrawalButton").addEventListener("click", getCheckedData); } function getServerTypeMap() { $.ajax({ url: "/auth-user/api/arms/jiraServerPure/serverTypeMap.do", // 클라이언트가 HTTP 요청을 보낼 서버의 URL 주소 method: "GET", dataType: "json", // 서버에서 보내줄 데이터의 타입 success: function (response) { jiraServerTypeMap = response; } }); } var getServerType = function (server_id) { console.log("[ reqStatus :: getServerType ] :: server_id => " + server_id); if (jiraServerTypeMap.hasOwnProperty(server_id)) { let value = jiraServerTypeMap[server_id]; console.log("[ reqStatus :: getServerType ] :: value => " + value); return value; } else { return "NO-TYPE"; } }; var makeALMIssueLink = function (server_type, self_link, issue_key) { let alm_link = ""; switch (server_type) { case "클라우드": // JIRA // "https://ABCDEFG.ABCDEFG.net/rest/api/3/issue/10187" => "https://ABCDEFG.ABCDEFG.net" let match_jc = self_link.match(/^(https?:\/\/[^\/]+)/); if (match_jc) { match_jc[1]; alm_link = match_jc[1] + "/browse/" + issue_key; } else { console.log( "makeALMIssueLink[JIRA_CLOUD] :: 링크 형식이 올바르지 않습니다. " + "link => " + self_link + ", issue_key => " + issue_key ); } break; case "온프레미스": // JIRA // "http://www.ABCDEFG.co.kr/jira/rest/api/latest/issue/24708" => "www.ABCDEFG.co.kr/jira" let match_jop = self_link.match(/^(https?:\/\/)?(www\.[^\/]+\/jira)/); if (match_jop) { const firstJiraElement = match_jop.find((element) => element.includes("jira")); alm_link = firstJiraElement + "/browse/" + issue_key; } else { console.log( "makeALMIssueLink[JIRA_ON_PREMISE] :: 링크 형식이 올바르지 않습니다. " + "link => " + self_link + ", issue_key => " + issue_key ); } break; case "레드마인_온프레미스": alm_link = self_link.replace(/\.json$/, ""); break; case "NO-TYPE": console.log( "makeALMIssueLink[NO-TYPE] :: 서버 타입이 없습니다. link => " + self_link + ", issue_key => " + issue_key ); alm_link = ""; break; } console.log(alm_link); return alm_link; }; //////////////////////////////////////// // 기간 설정 세팅 //////////////////////////////////////// function dateTimePicker() { var yesterday = new Date(); yesterday.setDate(yesterday.getDate() - 0); var formattedYesterday = yesterday.toISOString().split("T")[0]; $("#date_timepicker_start").datetimepicker({ format: "Y-m-d", formatDate: "Y/m/d", timepicker: false, theme: "dark", lang: "kr", onShow: function (ct) { this.setOptions({ maxDate: formattedYesterday }); } }); $("#date_timepicker_end").datetimepicker({ format: "Y-m-d", formatDate: "Y/m/d", timepicker: false, theme: "dark", lang: "kr", onShow: function (ct) { this.setOptions({ maxDate: formattedYesterday, minDate: $("#date_timepicker_start").val() ? $("#date_timepicker_start").val() : false }); } }); } function formatDate(date) { var year = date.getFullYear(); var month = (date.getMonth() + 1).toString().padStart(2, "0"); var day = date.getDate().toString().padStart(2, "0"); return year + "-" + month + "-" + day; } function baseDateReset() { let today = new Date(); let yesterday = new Date(); yesterday.setDate(today.getDate() - 1); $("#date_timepicker_end").val(formatDate(yesterday)); $("#date_timepicker_start").val(formatDate(yesterday)); } //////////////////////////////////////////// // Tab Click Event //////////////////////////////////////////// function tabClickEvent() { $('a[data-toggle="tab"]').on("shown.bs.tab", function (e) { var target = $(e.target).attr("href"); // activated tab console.log("[ reqStatus :: tabEvent ] :: target => " + target); if (target === "#issueList1") { $(".tab-content .tab-pane").addClass("hidden"); $("#issueList1").removeClass("hidden"); if (!selectedPdServiceId) { jError("제품 서비스를 선택해주세요."); } if (!selectedVersionId) { jError("선택된 버전이 없습니다."); } // 이슈리스트1 데이터테이블 (계층) getReqStatusTableData(selectedPdServiceId, selectedVersionId); } else if (target === "#issueList2") { if (!selectedPdServiceId) { jError("제품 서비스를 선택해주세요."); } if (!selectedVersionId) { jError("선택된 버전이 없습니다."); } $(".tab-content .tab-pane").addClass("hidden"); $("#issueList2").removeClass("hidden"); // 이슈리스트2 데이터테이블 (계층X) getIssueList2TableData(selectedPdServiceId, selectedVersionId); } }); } //////////////////////////////////////////// // Check Active Tab //////////////////////////////////////////// function callActiveTabApi() { if ($("#nav-issueList1").hasClass("active")) { console.log("[ reqStatus :: callActiveTabApi ] :: #nav-issueList1 is active, calling getReqStatusTableData"); getReqStatusTableData(selectedPdServiceId, selectedVersionId); } else if ($("#nav-issueList2").hasClass("active")) { console.log("[ reqStatus :: callActiveTabApi ] :: #nav-issueList2 is active, calling getIssueList2TableData"); getIssueList2TableData(selectedPdServiceId, selectedVersionId); } } ///////////////////////////// // tab2 table ///////////////////////////// +(function ($) { let tab2columns = [ { name: "parentReqKey", title: "부모키", data: "parentReqKey", render: function (data, type, row) { if (isEmpty(data)) { return "
N/A
"; } else if (row.isReq === false) { let prk = row.parentReqKey; return "
" + data + "
"; } else if (row.isReq === true) { return "
" + data + "
"; } return data; }, className: "dt-body-left", orderable: false, visible: false }, { name: "isReq", title: "요구사항 구분", data: "isReq", render: function (data, type, row) { // 하위이슈, 하하위이슈, 연결이슈, 연결의 하위이슈 if (data === false) { let prkText = ""; if (row.parentReqKey) { prkText = row.parentReqKey + "의 하위이슈"; } else { if (row.linkedIssues && row.linkedIssues.length !== 0) { let linkedIssueKeys = extractIssueKeyFromLinkedIssues(row.linkedIssues); prkText = formatIssueString(linkedIssueKeys) } } return "
" + prkText + "
"; } // 요구사항 else if (data === true) { return "
요구사항
"; } return data; }, className: "dt-body-left", orderable: false, visible: true }, { name: "key", title: "ALM Issue Key", data: "key", render: function (data, type, row, meta) { if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = data; let color; if (!isEmpty(row.isReq) && row.isReq == true && !row.etc) { color = "#a4c6ff"; } else { color = "#f8f8f8"; // 기본 텍스트 색상 } // 삭제 여부 if (row.deletedDate && row.deletedDate !== "") { displayText = "" + data + ""; } // 요구사항 이슈 여부 if (!isEmpty(row.isReq) && row.isReq && !row.etc) { let btn_data_row1 = { pdServiceVersions: row.pdServiceVersions.join(","), cReqLink: row.creqLink }; return ( "
" + displayText + $("
" ); } else { return "
" + displayText + "
"; } } return data; }, className: "dt-body-left", orderable: false, visible: true }, { name: "pdServiceVersions", title: "Version", data: "pdServiceVersions", render: function (data, type, row, meta) { if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let verNameList = []; let verHtml = ``; data.forEach((version_id) => { let versionInfo = versionListData.find((version) => version["c_id"] === version_id); if (versionInfo) { verNameList.push(versionInfo["c_title"]); verHtml += versionInfo["c_title"] + `
`; } }); let color; if (!isEmpty(row.isReq) && row.isReq == true && !row.etc) { color = "#a4c6ff"; } else { color = "#f8f8f8"; // 기본 텍스트 색상 } if (row.deleted && row.deleted.deleted_isDeleted === true) { verHtml = "" + verHtml + ""; } else if (row.deleted && row.deleted.deleted_isDeleted === false) { color = "#808080"; } return "
" + verHtml + "
"; } return data; }, className: "dt-body-left", orderable: false, visible: true }, { name: "summary", title: "ALM Issue Title", data: "summary", render: function (data, type, row, meta) { if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = data; let color = "#f8f8f8"; // 기본 텍스트 색상 if (!isEmpty(row.isReq) && row.isReq == true && !row.etc) { color = "#a4c6ff"; } else { color = "#f8f8f8"; // 기본 텍스트 색상 } if (row.deleted && row.deleted.deleted_isDeleted === true) { displayText = "" + data + ""; } else if (row.deleted && row.deleted.deleted_isDeleted === false) { color = "#808080"; } return "
" + displayText + "
"; } return data; }, className: "dt-body-left", orderable: false, visible: true }, { name: "project.project_key", title: "ALM project", data: "project.project_key", render: function (data, type, row, meta) { if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = data; let color = "#f8f8f8"; // 기본 텍스트 색상 if (!isEmpty(row.isReq) && row.isReq == true && !row.etc) { color = "#a4c6ff"; } else { color = "#f8f8f8"; // 기본 텍스트 색상 } if (row.deleted && row.deleted.deleted_isDeleted === true) { displayText = "" + data + ""; } else if (row.deleted && row.deleted.deleted_isDeleted === false) { color = "#808080"; } return "
" + displayText + "
"; } return data; }, className: "dt-body-left", orderable: false, visible: true }, { name: "assignee.assignee_displayName", title: "ALM Assignee", data: "assignee.assignee_displayName", render: function (data, type, row) { if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = data; let color = "#f8f8f8"; // 기본 텍스트 색상 if (!isEmpty(row.isReq) && row.isReq == true && !row.etc) { color = "#a4c6ff"; } else { color = "#f8f8f8"; // 기본 텍스트 색상 } if (row.deleted && row.deleted.deleted_isDeleted === true) { displayText = "" + data + ""; } else if (row.deleted && row.deleted.deleted_isDeleted === false) { color = "#808080"; } return "
" + displayText + "
"; } }, className: "dt-body-left", visible: true }, { name: "issuetype.issuetype_name", title: "ALM Issue Type", data: "issuetype.issuetype_name", render: function (data, type, row, meta) { if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = data; let color = "#f8f8f8"; // 기본 텍스트 색상 if (!isEmpty(row.isReq) && row.isReq == true && !row.etc) { color = "#a4c6ff"; } else { color = "#f8f8f8"; // 기본 텍스트 색상 } if (row.deleted && row.deleted.deleted_isDeleted === true) { displayText = "" + data + ""; } else if (row.deleted && row.deleted.deleted_isDeleted === false) { color = "#808080"; } return "
" + displayText + "
"; } return data; }, className: "dt-body-left", orderable: false, visible: true }, { name: "status.status_name", title: "ALM Status", data: "status.status_name", render: function (data, type, row, meta) { if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = data; let color = "#f8f8f8"; // 기본 텍스트 색상 if (!isEmpty(row.isReq) && row.isReq == true && !row.etc) { color = "#a4c6ff"; } else { color = "#f8f8f8"; // 기본 텍스트 색상 } if (row.deleted && row.deleted.deleted_isDeleted === true) { displayText = "" + data + ""; } else if (row.deleted && row.deleted.deleted_isDeleted === false) { color = "#808080"; } return "
" + displayText + "
"; } return data; }, className: "dt-body-left", orderable: false, visible: true }, { name: "priority.priority_name", title: "ALM Priority", data: "priority.priority_name", render: function (data, type, row, meta) { if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = data; let color = "#f8f8f8"; // 기본 텍스트 색상 if (!isEmpty(row.isReq) && row.isReq == true && !row.etc) { color = "#a4c6ff"; } else { color = "#f8f8f8"; // 기본 텍스트 색상 } if (row.deleted && row.deleted.deleted_isDeleted === true) { displayText = "" + data + ""; } else if (row.deleted && row.deleted.deleted_isDeleted === false) { color = "#808080"; } return "
" + displayText + "
"; } return data; }, className: "dt-body-left", orderable: false, visible: true }, { name: "overallUpdatedDate", title: "ALM Overall Update", data: "overallUpdatedDate", render: function (data, type, row, meta) { if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = dateFormatSlash(data, "/"); let color = "#f8f8f8"; // 기본 텍스트 색상 if (!isEmpty(row.isReq) && row.isReq == true && !row.etc) { color = "#a4c6ff"; } else { color = "#f8f8f8"; // 기본 텍스트 색상 } if (row.deleted && row.deleted.deleted_isDeleted === true) { displayText = "" + dateFormat(data) + ""; } else if (row.deleted && row.deleted.deleted_isDeleted === false) { color = "#808080"; } return "
" + displayText + "
"; } return data; }, className: "dt-body-left", orderable: false, visible: false }, { name: "created", title: "ALM Created", data: "created", render: function (data, type, row, meta) { if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = dateFormatSlash(data); let color = "#f8f8f8"; // 기본 텍스트 색상 if (!isEmpty(row.isReq) && row.isReq == true && !row.etc) { color = "#a4c6ff"; } else { color = "#f8f8f8"; // 기본 텍스트 색상 } if (row.deleted && row.deleted.deleted_isDeleted === true) { displayText = "" + dateFormatSlash(data) + ""; } else if (row.deleted && row.deleted.deleted_isDeleted === false) { color = "#808080"; } return "
" + displayText + "
"; } return data; }, className: "dt-body-left", orderable: false, visible: true }, { name: "updated", title: "ALM Updated", data: "updated", render: function (data, type, row, meta) { if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = dateFormatSlash(data); let color = "#f8f8f8"; // 기본 텍스트 색상 if (!isEmpty(row.isReq) && row.isReq == true && !row.etc) { color = "#a4c6ff"; } else { color = "#f8f8f8"; // 기본 텍스트 색상 } if (row.deleted && row.deleted.deleted_isDeleted === true) { displayText = "" + dateFormatSlash(data) + ""; } else if (row.deleted && row.deleted.deleted_isDeleted === false) { color = "#808080"; } return "
" + displayText + "
"; } return data; }, className: "dt-body-left", orderable: false, visible: true }, { name: "resolutiondate", title: "ALM Resolution", data: "resolutiondate", render: function (data, type, row, meta) { if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = dateFormatSlash(data); let color = "#f8f8f8"; // 기본 텍스트 색상 if (!isEmpty(row.isReq) && row.isReq == true && !row.etc) { color = "#a4c6ff"; } else { color = "#f8f8f8"; // 기본 텍스트 색상 } if (row.deleted && row.deleted.deleted_isDeleted === true) { displayText = "" + displayText + ""; } else if (row.deleted && row.deleted.deleted_isDeleted === false) { displayText = "
" + displayText + "
"; } return "
" + displayText + "
"; } return data; }, className: "dt-body-left", orderable: false, visible: true }, { name: "deleted", title: "ALM Deleted", data: "deleted.deleted_date", render: function (data, type, row, meta) { if (isEmpty(data) || data === "false") { return "
N/A
"; } else { let displayText = dateFormatSlash(data); let color = "#f8f8f8"; // 기본 텍스트 색상 if (row.deleted && row.deleted.deleted_isDeleted === true) { displayText = "" + displayText + ""; } else if (row.deleted && row.deleted.deleted_isDeleted === false) { color = "#808080"; } return "
" + displayText + "
"; } return data; }, className: "dt-body-left", orderable: false, visible: true } ]; $(document).one("init.issueList2Table", function () { let lastScrollTop = 0; $("#issueList2Table") .on("length.dt", function () { lastScrollTop = $(window).scrollTop(); }) .on("page.dt", function () { console.log("workerStatusTable :: page.dt"); lastScrollTop = $(window).scrollTop(); }) .on("draw.dt", function () { $(window).scrollTop(lastScrollTop); }) .table({ order: [], columns: tab2columns, scrollCollapse: false, scrollY: "700px", data: [], drawCallback: function () { console.log("workerStatusTable :: drawCallback"); } }); }); })(jQuery); function fetchChildren(key, parentReqKey, upperKey, subtaskCount, linkedIssueCount, linkedIssues) { return new Promise((resolve, reject) => { $.ajax({ url: "/auth-user/api/arms/reqStatus/subtasks-and-linked-issues", method: "POST", contentType: "application/json", data: JSON.stringify({ // 데이터를 JSON 문자열로 변환 pdServiceId: selectedPdServiceId, key: key, parentReqKey: parentReqKey, upperKey: upperKey, subtaskCount: subtaskCount, linkedIssueCount: linkedIssueCount, linkedIssues: linkedIssues // DTO의 linkedIssues와 매핑 (배열) }), success: function (apiResponse) { let data = apiResponse; console.log("fetchChildren => ", data); // API 호출 성공 시 데이터를 resolve resolve(data.response); // 응답 데이터에 맞게 수정 (response.children) }, error: function (xhr, status, error) { // API 호출 실패 시 reject console.error("Failed to fetch children:", error); reject(error); } }); }); } /** * 문자열을 받아 특정 형식으로 변환하는 함수 * @param {string} isReqName - 입력 문자열 (예: "test_link") * @returns {string} 변환된 문자열 (예: "test 의 연결이슈") */ function formatLinkIssue(isReqName) { if (typeof isReqName === "string" && isReqName.endsWith("_link")) { // "_link"를 제거하고, 변환된 문자열을 반환 return `└ ${isReqName.replace("_link", "")}의 연결이슈`; } else if (isReqName === "요구사항") { // _link 형식이 아니고 "요구사항"일 때 return isReqName; } else { // 그외 하위이슈 return `└ ${isReqName}의 하위이슈`; } } function formatIsReqName(isReqName) { if (!isReqName) { // isReqName이 없는 경우("") 반환 return ""; } // 쉼표로 구분되어 있는 경우 처리 const elements = isReqName .split(", ") .map((item) => item.trim()) // 공백 제거 .filter((item) => item !== "") // 빈 항목 제거 .map((item) => { if (item === "요구사항") { return "요구사항"; } else if (typeof item === "string" && item.endsWith("_link")) { // "_link"를 제거하고 "의 연결이슈" 추가 return `${item.replace("_link", "")}의 연결이슈`; } else { // 나머지는 "의 하위이슈" 추가 return `${item}의 하위이슈`; } }); // 처리된 요소를 다시 쉼표로 연결하여 반환 return elements.join(", "); } function containsRequirement(text) { if (typeof text === "string") { return text.includes("요구사항"); } return false; } function textColor(isReqName, isReq) { if (!isEmpty(isReq) && isReq === true && !isReqName.endsWith("_link")) { return "#a4c6ff"; } else { return "#f8f8f8"; } } // linkedIssues 의 element 에서 issueKey 목록 추출 function extractIssueKeyFromLinkedIssues(linkedIssues) { // 배열이 아닌 경우 빈 배열 반환 (에러 방지) if (!Array.isArray(linkedIssues)) return []; const results = linkedIssues .filter(item => typeof item === 'string' && item) // 문자열 아이템만 필터 .map(item => { const parts = item.split('_'); return parts[parts.length - 1]; // 마지막 부분 반환 }); return results; } // 연결이슈 표현 생성 function formatIssueString(parsedStr) { if (!Array.isArray(parsedStr) || parsedStr.length === 0) { return ''; // 빈 배열이면 빈 문자열 반환 } // 각 요소에 "의 연결이슈" 추가하고 개행으로 연결 const formatted = parsedStr.map(item => `${item}의 연결이슈`); return formatted.join('\n'); }