var selectedPdServiceId; // 제품(서비스) 아이디
var selectedVersionIds; // 선택된 버전 아이디
var selectedAlmProjectIds; // 선택된 ALM Project 아이디
var selectedAssigneeEmails; // 선택된 담당자 아이디
var previousStartDate = null;
var previousEndDate = null;
var pdServiceListData;
var versionListData;
var selectedIndex; // 데이터테이블 선택한 인덱스
var selectedPage; // 데이터테이블 선택한 인덱스
var searchOptionalParam;
var currentDate;
let fullCalendar = null;
let fullTimeLine = null;
let userLocale = navigator.language || "en";
////////////////////////////////////////////////////////////////////////////////////////
//Document Ready
////////////////////////////////////////////////////////////////////////////////////////
function execDocReady() {
var pluginGroups = [
[
"../reference/light-blue/lib/vendor/jquery.ui.widget.js",
"../reference/light-blue/lib/vendor/http_blueimp.github.io_JavaScript-Templates_js_tmpl.js",
"../reference/light-blue/lib/vendor/http_blueimp.github.io_JavaScript-Load-Image_js_load-image.js",
"../reference/light-blue/lib/vendor/http_blueimp.github.io_JavaScript-Canvas-to-Blob_js_canvas-to-blob.js",
"../reference/light-blue/lib/jquery.iframe-transport.js",
"../reference/light-blue/lib/jquery.fileupload.js",
"../reference/light-blue/lib/jquery.fileupload-fp.js",
"../reference/light-blue/lib/jquery.fileupload-ui.js",
"../reference/lightblue4/docs/lib/widgster/widgster.js",
"../reference/lightblue4/docs/lib/slimScroll/jquery.slimscroll.min.js",
"../reference/jquery-plugins/timerStyles.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/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"
],
[ // lightblue4
"../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.rowsGroup.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"
],
[
"../reference/jquery-plugins/jspreadsheet-ce-4.13.1/dist/jsuites.js",
"../reference/jquery-plugins/jspreadsheet-ce-4.13.1/dist/index.js",
"../reference/jquery-plugins/jspreadsheet-ce-4.13.1/dist/jsuites.css",
"../reference/jquery-plugins/jspreadsheet-ce-4.13.1/dist/jspreadsheet.css",
"../reference/jquery-plugins/jspreadsheet-ce-4.13.1/dist/jspreadsheet.datatables.css",
"../reference/jquery-plugins/jspreadsheet-ce-4.13.1/dist/jspreadsheet.theme.css",
"../reference/jquery-plugins/fullcalendar-6.1.15/dist/index.global.js",
"./js/common/jspreadsheet/spreadsheet.js",
"./css/jspreadsheet/custom_sheet.css",
//chart Colors
"./js/common/colorPalette.js"
// 추가적인 플러그인 그룹들을 이곳에 추가하면 됩니다.(그룹 최대 4개)
]
];
loadPluginGroupsParallelAndSequential(pluginGroups)
.then(function() {
console.log('모든 플러그인 로드 완료');
//사이드 메뉴 처리
$('.widget').widgster();
setSideMenu("sidebar_menu_report", "sidebar_menu_report_full_data");
//제품(서비스) 셀렉트 박스 이니시에이터
makePdServiceSelectBox();
//버전 멀티 셀렉트 박스 이니시에이터
makeVersionMultiSelectBox();
// 작업자 목록 멀티 셀렉트 박스 이니시에이터
makeAssigneesMultiSelectBox();
// ALM 프로젝트 멀티 셀렉트 박스 이니시에이터
makeProjectMultiSelectBox();
//날짜
dateTimePicker();
// 제품 서비스 검색 필터 초기화
pdServiceFilterClear();
// 높이 조정
$('.top-menu-div').matchHeight({
target: $('.top-menu-div-default')
});
// 오늘 날짜 설정
currentDate = getCurrentDate();
// 테이블 초기화
fetchJiraProjects();
fetchAssignees();
fetchExcelData();
})
.catch(function(e) {
console.error('플러그인 로드 중 오류 발생');
console.error(e);
});
}//.execDocReady
///////////////////////
// 제품 서비스 검색 필터 초기화
//////////////////////
function pdServiceFilterClear() {
$("#pdservice_filter_clear").on("click", function() {
$("#selected_pdService").val(null).trigger("change");
$("#multiple-version option").remove();
$("#multiple-version").multipleSelect("refresh");
selectedPdServiceId = null;
selectedVersionIds = null;
let optionalParams = setOptionalParams();
if (!isAllAssigneesSelected()) {
optionalParams.emailAddress = selectedAssigneeEmails;
}
fetchExcelData(undefined, optionalParams);
});
}
///////////////////////
//제품 서비스 셀렉트 박스
//////////////////////
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("[fullDataSheet :: 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();
//refreshDetailChart(); 변수값_초기화();
// 제품( 서비스 ) 선택했으니까 자동으로 버전을 선택할 수 있게 유도
// 디폴트는 base version 을 선택하게 하고 ( select all )
//~> 이벤트 연계 함수 :: Version 표시 jsTree 빌드
bind_VersionData_By_PdService();
});
} // end makePdServiceSelectBox()
function bind_VersionData_By_PdService() {
$("#multiple-version 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({"c_id" : obj.c_id, "c_title" : obj.c_title,
"start_date" : obj.c_pds_version_start_date,
"end_date" : obj.c_pds_version_end_date});
var newOption = new Option(obj.c_title, obj.c_id, true, false);
$("#multiple-version").append(newOption);
}
selectedVersionIds = pdServiceVersionIds.join(",");
$("#multiple-version")
.multipleSelect("refresh")
.multipleSelect("checkAll");
// 시작일 종료일 세팅(datetimepicker)
setEdgeDateRange(versionListData);
let optionalParams = setOptionalParams();
if (!isAllAssigneesSelected()) {
optionalParams.emailAddress = selectedAssigneeEmails;
}
fetchExcelData(selectedPdServiceId, optionalParams);
if (data.length > 0) {
console.log("display 재설정.");
}
}
}
});
}
////////////////////////////////////////
//버전 멀티 셀렉트 박스
////////////////////////////////////////
function makeVersionMultiSelectBox() {
//버전 선택시 셀렉트 박스 이니시에이터
$("#multiple-version").multipleSelect({
filter: true,
// selectBox 닫혔을 때
onClose: function() {
var versionTag = $("#multiple-version").val();
console.log("[ fullDataSheet :: makeVersionMultiSelectBox ] :: versionTag");
console.log(versionTag);
selectedVersionIds = versionTag.join(",");
if (versionTag === null || versionTag == "") {
alert("버전이 선택되지 않았습니다.");
$("#multiple-version").siblings(".ms-parent").css("z-index", 1000);
return;
}
let filteredVersionData = versionListData.filter(item => versionTag.includes(item.c_id.toString()));
// 시작일 종료일 세팅(datetimepicker)
setEdgeDateRange(filteredVersionData);
let optionalParams = setOptionalParams();
$("#multiple-version").siblings(".ms-parent").css("z-index", 1000);
if (!isAllAssigneesSelected()) {
optionalParams.emailAddress = selectedAssigneeEmails;
}
fetchExcelData(selectedPdServiceId, optionalParams);
},
// selectBox 열렸을 때
onOpen: function() {
$("#multiple-version").siblings(".ms-parent").css("z-index", 9999);
}
});
}
////////////////////////////////////////
// 작업자 select 이벤트 핸들링
////////////////////////////////////////
function makeAssigneesMultiSelectBox () {
// ALM 프로젝트 선택 시 셀렉트 박스 이니시에이터
$("#multiple-assignees").multipleSelect({
filter: true,
onClose: function() {
let assigneesArray = $("#multiple-assignees").val();
let assigneesString = assigneesArray.join(",");
if(assigneesString === selectedAssigneeEmails) {
return false;
} else {
selectedAssigneeEmails = assigneesString;
}
let optionalParams = setOptionalParams();
if (!isAllAssigneesSelected()) {
optionalParams.emailAddress = selectedAssigneeEmails;
}
fetchExcelData(selectedPdServiceId, optionalParams);
$("#multiple-assignees").siblings(".ms-parent").css("z-index", 1000);
},
onOpen: function() {
$("#multiple-assignees").siblings(".ms-parent").css("z-index", 9999);
}
});
}
////////////////////////////////////////
// ALM 프로젝트 select 이벤트 핸들링
////////////////////////////////////////
function makeProjectMultiSelectBox () {
// ALM 프로젝트 선택 시 셀렉트 박스 이니시에이터
$("#multiple-alm-project").multipleSelect({
filter: true,
onClose: function() {
let projectIds = $("#multiple-alm-project").val();
selectedAlmProjectIds = projectIds.join(",");
let optionalParams = setOptionalParams();
if (!isAllAssigneesSelected()) {
optionalParams.emailAddress = selectedAssigneeEmails;
}
fetchExcelData(selectedPdServiceId, optionalParams);
$("#multiple-alm-project").siblings(".ms-parent").css("z-index", 1000);
},
onOpen: function() {
$("#multiple-alm-project").siblings(".ms-parent").css("z-index", 9999);
}
});
}
////////////////////////////////////////
// 검색 조건을 선택하여 API 호출 시, 제품 버전이 모두 선택되어 있는지 체크하는 함수
// 모두 선택 된 경우, query param 으로 보낼 필요가 없기 때문
////////////////////////////////////////
function isAllVersionsSelected() {
if (!selectedVersionIds) {
return false;
}
return $("#multiple-version option").length === selectedVersionIds.split(",").length;
}
////////////////////////////////////////
// 검색 조건을 선택하여 API 호출 시, 작업자가 모두 선택되어 있는지 체크하는 함수
// 모두 선택 된 경우, query param 으로 보낼 필요가 없기 때문
////////////////////////////////////////
function isAllAssigneesSelected() {
if (!selectedAssigneeEmails) {
return false;
}
return $("#multiple-assignees option").length === selectedAssigneeEmails.split(",").length;
}
////////////////////////////////////////
// 선택 된 제품, 제품 버전 ID 값을 서버에 전달하여 관련 ALM 프로젝트 목록 조회
////////////////////////////////////////
function fetchJiraProjects() {
$("#multiple-alm-project option").remove();
$.ajax({
url: "/auth-user/api/arms/jiraProjectPure/getJiraProjects.do",
type: "GET",
dataType: "json",
success: function(data) {
console.log("[Jira Projects] Data:", data);
for (var k in data.response) {
let obj = data.response[k];
let newOption = new Option(obj.c_title, obj.c_id, true, false);
$("#multiple-alm-project").append(newOption);
}
$("#multiple-alm-project").multipleSelect("refresh");
},
error: function(xhr, status, error) {
console.error("[Jira Projects] Error:", error);
}
});
}
////////////////////////////////////////
// 모든 검색 필터(제품, 제품 버전, ALM 프로젝트, 날짜 등) 선택이 완료 된 경우, 데이터를 조회한다.
////////////////////////////////////////
function fetchAssignees(pdServiceId, optionalParams = {}) {
$("#multiple-assignees option").remove();
let urlBuilder = new UrlBuilder()
.setBaseUrl('/auth-user/api/arms/report/full-data/assignee-list');
const { pdServiceVersionIds = null, almProjectIds = null, startDate = null, endDate = null, emailAddress = null } = optionalParams;
const optionalQueryParams = { pdServiceVersionIds, almProjectIds, startDate, endDate, emailAddress };
Object.entries(optionalQueryParams).forEach(([key, value]) => {
if (value) {
urlBuilder.addQueryParam(key, value);
}
});
const url = urlBuilder.build();
$.ajax({
url: url,
type: "GET",
dataType: "json",
success: function(data) {
console.log(data.response);
for (var k in data.response) {
let obj = data.response[k];
let displayName = obj.displayName + "(" + obj.emailAddress + ")";
let newOption = new Option(displayName, obj.emailAddress, true, false);
$("#multiple-assignees").append(newOption);
}
$("#multiple-assignees").multipleSelect("refresh");
},
error: function(xhr, status, error) {
console.error("[GET Assignees] Error:", error);
}
});
}
function fetchExcelData(pdServiceId, optionalParams = {}) {
let urlBuilder = new UrlBuilder()
.setBaseUrl('/auth-user/api/arms/report/full-data/excel-data');
if (pdServiceId !== undefined) {
urlBuilder.addQueryParam("pdServiceId", pdServiceId);
}
const { pdServiceVersionIds = null, almProjectIds = null, startDate = null, endDate = null, emailAddress = null } = optionalParams;
const optionalQueryParams = { pdServiceVersionIds, almProjectIds, startDate, endDate, emailAddress };
Object.entries(optionalQueryParams).forEach(([key, value]) => {
if (value) {
urlBuilder.addQueryParam(key, value);
}
});
searchOptionalParam = optionalQueryParams;
const url = urlBuilder.build();
console.log("[ reportFullData :: fetchExcelData ] ::requestURL => ", url);
$.ajax({
url: url,
type: "GET",
dataType: "json",
success: function(data) {
console.log("[ reportFullData :: fetchExcelData ] :: excelData.legnth => ", data !== null ? data.response.length : 0);
drawExcel("spreadsheet", data.response);
let sortedData = [...data.response].sort((a, b) => new Date(a.createDate) - new Date(b.createDate));
drawCalendar(sortedData);
},
error: function(xhr, status, error) {
console.error(error);
}
});
}
function updateHeaderTextStyle() {
//$("#spreadsheet")[0]
const headers = $("#spreadsheet")[0].querySelectorAll(".jexcel > thead > tr > td");
// 특정 헤더 값을 수정하고 스타일 적용
headers.forEach((header) => {
const title = header.innerText;
if (title.includes("요구사항")) {
let updatedReqHTML = title.replace(
"요구사항",
'요구사항'
);
header.innerHTML = updatedReqHTML;
} else if (title.includes("이슈")) {
let updatedIssueHTML = title.replace(
"이슈",
'이슈'
);
header.innerHTML = updatedIssueHTML;
}
});
}
////////////////////////////////////////
// 기간 설정 세팅
////////////////////////////////////////
function dateTimePicker() {
$('#date_timepicker_start').datetimepicker({
format: 'Y-m-d',
formatDate: 'Y/m/d',
timepicker: false,
theme: 'dark',
lang: "kr",
onShow: function(ct) {
this.setOptions({
maxDate: $('#date_timepicker_end').val() ? $('#date_timepicker_end').val() : false
});
},
onClose: function(dp, $input) { // 달력이 닫힐 때만 API 호출
let newStartDate = $input.val();
if (previousStartDate !== newStartDate && newStartDate) {
previousStartDate = newStartDate;
let optionalParams = setOptionalParams();
if (!isAllAssigneesSelected()) {
optionalParams.emailAddress = selectedAssigneeEmails;
}
fetchExcelData(selectedPdServiceId, optionalParams);
}
}
});
$('#date_timepicker_end').datetimepicker({
format: 'Y-m-d',
formatDate: 'Y/m/d',
timepicker: false,
theme: 'dark',
lang: "kr",
onShow: function(ct) {
this.setOptions({
minDate: $('#date_timepicker_start').val() ? $('#date_timepicker_start').val() : false
});
},
onClose: function(dp, $input) {
let newEndDate = $input.val();
if (previousEndDate !== newEndDate && newEndDate) {
previousEndDate = newEndDate;
let optionalParams = setOptionalParams();
if (!isAllAssigneesSelected()) {
optionalParams.emailAddress = selectedAssigneeEmails;
}
fetchExcelData(selectedPdServiceId, optionalParams);
}
}
});
}
////////////////////////////////////////
// 선택한 버전 - min,max 날짜 세팅
////////////////////////////////////////
function setEdgeDateRange(versionData) {
if (!versionData || Object.keys(versionData).length === 0) {
console.log("[ fullDataSheet :: setEdgeDateRange ] :: versionData 가 없습니다.");
return false;
}
let minMaxDate = versionData.reduce((acc, curr) => {
const startDate = new Date(curr.start_date);
const endDate = new Date(curr.end_date);
if (!acc.min || startDate < acc.min) {
acc.min = startDate;
}
if (!acc.max || endDate > acc.max) {
acc.max = endDate;
}
return acc;
}, { min: null, max: null });
console.log("[ fullDataSheet :: setEdgeDateRange ] :: " +
"minMaxDate.min => " + minMaxDate.min+ ", minMaxDate.max => " +minMaxDate.max);
const oneMonthAgo = new Date(minMaxDate.max);
oneMonthAgo.setMonth(oneMonthAgo.getMonth() - 1);
if (oneMonthAgo > minMaxDate.min) {
oneMonthAgo.setTime(minMaxDate.min.getTime());
}
$('#date_timepicker_start').datetimepicker('setOptions', {
value: oneMonthAgo
});
$('#date_timepicker_end').datetimepicker('setOptions', {
value: minMaxDate.max
});
}
// -------------------- 데이터 테이블을 만드는 템플릿으로 쓰기에 적당하게 리팩토링 함. ------------------ //
// 데이터 테이블 구성 이후 꼭 구현해야 할 메소드 : 열 클릭시 이벤트
function dataTableClick(tempDataTable, selectedData) {
console.log(selectedData);
}
// 데이터 테이블 데이터 렌더링 이후 콜백 함수.
function dataTableCallBack(settings, json) {
console.log("check");
}
function dataTableDrawCallback(tableInfo) {
console.log(tableInfo);
}
/////////////////////////////////////////////////
// 엑셀 그리기
/////////////////////////////////////////////////
function drawExcel(target, data) {
var columnList = [
{ readOnly: true, type: "text", name:"pdServiceName", title: "제품(서비스)", wRatio: 0.1 }, //0
{ readOnly: true, type: "text", name:"pdServiceVersionNames", title: "버전(일정)", wRatio: 0.1 }, //1 버전(시작일 ~ 종료일)
{ readOnly: true, type: "text", name:"almProjectName", title: "ALM Project", wRatio: 0.1 }, //2 ALM Project
{ readOnly: true, type: "text", name:"isReqName", title: "ALM 이슈 구분", wRatio: 0.1 }, //3 요구사항 이슈, 연결이슈, 하위이슈
{ readOnly: true, type: "text", name: "key", title: "ALM 이슈 키", wRatio: 0.1 }, //4 (필수)
{ readOnly: true, type: "text", name:"reqTitle", title: "A-RMS 요구사항", wRatio: 0.2 }, //5 암스가 생성한 요구사항
{ readOnly: true, type: "text", name:"reqState", title: "A-RMS 요구사항 상태", wRatio: 0.1 }, //6 암스 요구사항 상태
{ readOnly: true, type: "text", name:"issueTitle", title: "ALM 이슈 제목", wRatio: 0.2 }, //7
{ readOnly: true, type: "text", name:"issueStatus", title: "ALM 이슈 상태", wRatio: 0.1 }, //8
{ readOnly: true, type: "text", name:"assigneeName", title: "ALM 이슈 담당자", wRatio: 0.1 }, //9
{ readOnly: true, type: "calendar", options: {format: "YYYY/MM/DD"}, name: "createDate", title: "ALM 이슈 생성일", wRatio: 0.1 }, //10
{ readOnly: true, type: "calendar", options: {format: "YYYY/MM/DD"}, name: "updatedDate", title: "ALM 이슈 수정일", wRatio: 0.1 }, //11
{ readOnly: true, type: "calendar", options: {format: "YYYY/MM/DD"}, name: "resolutionDate", title: "ALM 이슈 해결일", wRatio: 0.1 }, //12 해결된 날짜 또는 닫힌 날짜
{ readOnly: true, type: "hidden", name: "pdServiceVersions", title: "버전키", wRatio: 0.1 }, //13 (필수X)
{ readOnly: true, type: "hidden", name: "pdServiceId", title: "제품서비스키", wRatio: 0.1 }, //14 (필수X)
{ readOnly: true, type: "hidden", name: "assigneeEmail", title: "담당자메일", wRatio: 0.1 }, //15 (필수X)
{ readOnly: true, type: "hidden", name: "upperKey", title: "upperKey", wRatio: 0.1 }, //16 (필수X)
{ readOnly: true, type: "hidden", name: "issueID", title: "issueID", wRatio: 0.1 }, //17 (필수X)
{ readOnly: true, type: "hidden", name: "parentReqKey", title: "parentReqKey", wRatio: 0.1 }, //18 (필수X)
{ readOnly: true, type: "hidden", name: "etc", title: "etc", wRatio: 0.1 }, //19 (필수X)
{ readOnly: true, type: "hidden", name: "isReq", title: "isReq", wRatio: 0.1 }, //20 (필수X)
{ readOnly: true, type: "hidden", name: "creqLink", title: "cReqLink", wRatio: 0.1 }, //21 (필수X)
{ readOnly: true, type: "hidden", name: "deletedDate", title: "deletedDate", wRatio: 0.1 }, //22 (필수X)
{ readOnly: true, type: "hidden", name: "dummy", title: "dummy", wRatio: 0.1 } //22 (필수X)
];
var customOption = {
toolbar: toolbarCustom,
pagination: 30,
contextMenu: [],
search: true,
allowInsertRow: false,
allowInsertColumn: false,
columnSorting: false,
onload: function (element) {
var $jexcel = $(element);
var $searchInput =
$('' +
' ' +
'');
$jexcel.find(".jexcel_toolbar_item[data-k='undo']").addClass("fa fa-mail-reply ");
$jexcel.find(".jexcel_toolbar_item[data-k='redo']").addClass("fa fa-mail-forward ");
$jexcel.find(".jexcel_toolbar_item[data-k='save']").addClass("fa fa-save");
$jexcel.find(".jexcel_toolbar_item[data-k='text-align'][data-v='left']").addClass("fa fa-align-left fa-flip-vertical");
$jexcel.find(".jexcel_toolbar_item[data-k='text-align'][data-v='center']").addClass("fa fa-align-center fa-flip-vertical");
$jexcel.find(".jexcel_toolbar_item[data-k='text-align'][data-v='right']").addClass("fa fa-align-right fa-flip-vertical");
$jexcel.find(".jexcel_toolbar_item[data-k='font-weight'][data-v='bold']").addClass("fa fa-bold");
$jexcel.find(".jexcel_toolbar_item[data-k='font-style'][data-v='italic']").addClass("fa fa-italic");
$jexcel.find(".jexcel_toolbar_item[data-k='text-decoration'][data-v='underline']").addClass("fa fa-underline");
$jexcel.find(".jexcel_toolbar_item[data-k='text-decoration'][data-v='line-through']").addClass("fa fa-strikethrough");
$jexcel.find(".jexcel_toolbar_item[data-k='color']").addClass("fa fa-font");
$jexcel.find(".jexcel_toolbar_item[data-k='background-color']").addClass("fa fa-font fa-background");
$jexcel.find(".jexcel_filter").addClass("hidden");
$jexcel.find(".jexcel_toolbar_item[data-k='search-box']").addClass("search-box").append($searchInput);
// 검색 input 에 focus 일때, 선택 초기화
var $inputField = $searchInput.find('input.jexcel_search');
if ($inputField.length) {
$inputField.on('focus', function() {
if (element.jexcel) {
element.jexcel.resetSelection();
}
});
}
// 헤더 텍스트 스타일 업데이트(요구사항, 이슈)
updateHeaderTextStyle();
},
updateTable: function(instace, cell, col, row, val, id) {
cell.style.whiteSpace = "normal";
cell.style.textAlign = "left";
cell.style.color = "#a4c6ff";
if (col === 20 && val !== true) {
// 현재 행(row)에 해당하는 모든 셀 가져오기
let rowCells = cell.parentElement.children;
// 해당 행의 모든 셀의 글꼴 색상을 red로 변경
for (let i = 0; i < 14; i++) {
rowCells[i].style.color = "#f8f8f8";
}
}
}
};
SpreadsheetFunctions.setTargetId(target);
SpreadsheetFunctions.setDefaultTargetRect();
SpreadsheetFunctions.setColumns(columnList);
SpreadsheetFunctions.setColumnWidth(SpreadsheetFunctions.getTargetRect("width"));
SpreadsheetFunctions.setOptions(customOption);
SpreadsheetFunctions.startObserver();
SpreadsheetFunctions.setExcelData(data);
SpreadsheetFunctions.drawExcel(SpreadsheetFunctions.getTargetId());
}
var SpreadsheetFunctions = (function () {
let targetId = { "v" : "", "jq" : ""};
let targetRect = {"width" : 0, "height" : 0};
let excelData; // 엑셀 데이터
let excelColumns; // 엑셀 컬럼
let customOptions;// 엑셀 커스텀 옵션들 :: 정의 안할 경우 default
var setDefaultTargetRect = function () {
let defaultWidth = $(getTargetId("jq")).width();
let defaultHeight = $(getTargetId("jq")).height();
setTargetRect(defaultWidth, defaultHeight);
};
var setTargetRect = function(width, height) {
targetRect.width = width;
targetRect.height = height;
};
var getTargetRect = function (type) {
if (type === "width") {
return targetRect.width;
} else if (type === "height") {
return targetRect.height;
} else {
return targetRect;
}
};
var setTargetId = function (target) {
targetId.v = target;
targetId.jq = "#"+target;
};
var getTargetId = function (type) {
if (type === "jq") {
return targetId.jq;
} else {
return targetId.v;
}
};
var setExcelData = function(data) {
excelData = data;
};
var getExcelData = function () {
return excelData;
};
var setColumns = function(columns) {
excelColumns = columns;
};
var getColumns = function () {
return excelColumns;
};
var setColumnWidth = function (width) {
if (excelColumns) {
excelColumns = excelColumns.map(column => ({
...column, width: (width * column.wRatio) -1
}));
}
};
function setColumnWidthAsync(width) {
return new Promise((resolve) => {
if (excelColumns) {
excelColumns = excelColumns.map(column => ({
...column, width: (width * column.wRatio) - 1
}));
}
resolve(); // 컬럼 너비 설정이 완료된 후 resolve 호출
});
}
var setOptions = function(options) {
customOptions = options;
};
var getOptions = function() {
return customOptions ? customOptions : null;
};
var resizeObserver = new ResizeObserver(function(entries) {
for (let entry of entries) {
setTargetRect(entry.contentRect.width, entry.contentRect.height);
handleResize(entry.target.id, getTargetRect("width"), getTargetRect("height"));
}
});
// 모달요소 크기 변화 관찰(Observer)
function startObserver() {
resizeObserver.observe($(getTargetId("jq"))[0]);
}
function handleResize(id, width, height) {
if (id === getTargetId() && height !== 0) {
if (excelData) {
drawResizedExcel(getTargetId());
} else {
console.log("Spreadsheet.handleResize :: 엑셀 데이터 없음");
}
} else {
console.log("Spreadsheet.handleResize :: id 불일치 또는 height 가 0 입니다.");
}
}
function drawResizedExcel(target) {
let $targetId = "#"+target;
if($($targetId).length > 0 && $($targetId)[0].jexcel) {
$($targetId)[0].jexcel.destroy();
}
setColumnWidthAsync(getTargetRect("width") - 50).then(() => {
$($targetId).spreadsheet($.extend({}, {
columns: getColumns(),
data: getExcelData()
}, getOptions()));
let jexcel_content_height = getTargetRect("height") - 40 - 30 - 35 - 34;
$($targetId + " .jexcel_content").css("max-height", jexcel_content_height);
$($targetId + " .jexcel_content").css("width", "100%");
});
}
function drawExcel(target) {
let $targetId = "#"+target;
if($($targetId).length > 0 && $($targetId)[0].jexcel) {
$($targetId)[0].jexcel.destroy();
}
$($targetId).spreadsheet($.extend({}, {
columns: getColumns(),
data: getExcelData()
}, getOptions()));
let jexcel_content_height = getTargetRect("height") - 40 - 30 - 35 - 34;
$($targetId + " .jexcel_content").css("max-height", jexcel_content_height);
$($targetId + " .jexcel_content").css("width", "100%");
}
return {
setTargetId, getTargetId,
setTargetRect, getTargetRect, setDefaultTargetRect,
setExcelData, getExcelData,
setColumns, getColumns, setColumnWidth,
setOptions, getOptions,
startObserver, drawExcel
};
})();
///////////////////////////////////////////////////
// 엑셀데이터 Export (JSON)
/////////////////////////////////////////////////
function jsonExport() {
let csvDataList = $(SpreadsheetFunctions.getTargetId("jq"))[0].jexcel.getData();
if (csvDataList.length === 0) {
console.log("[ reportFullData :: jsonExport ] :: excelData 가 없습니다.");
return false;
}
const jsonArray = csvDataList.map(row => {
const jsonObject = {};
SpreadsheetFunctions.getColumns().forEach((column,index) => {
jsonObject[column.title] = row[index];
});
return jsonObject;
});
//let jsonResult = [jsonArray];
let currentDate = date_YYMMDD();
let fileName = "fullData_" + currentDate;
downloadJSON(fileName, jsonArray);
}
function downloadJSON(filename, jsonObject) {
const jsonData = JSON.stringify(jsonObject, null, 2);
const blob = new Blob([jsonData], { type: 'application/json' });
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = filename;
link.click();
URL.revokeObjectURL(link.href);
}
///////////////////////////////////////////////////
// 엑셀데이터 Export (CSV)
/////////////////////////////////////////////////
function csvExport() {
$(".jexcel_toolbar_item.material-icons.fa.fa-save").click();
}
function excelExport() {
let urlBuilder = new UrlBuilder()
.setBaseUrl('/auth-user/api/arms/report/full-data/excel-data-down');
if (selectedPdServiceId) {
urlBuilder.addQueryParam("pdServiceId", selectedPdServiceId);
}
if (selectedVersionIds) {
urlBuilder.addQueryParam("pdServiceVersionIds", selectedVersionIds);
}
Object.entries(searchOptionalParam).forEach(([key, value]) => {
if (value) {
urlBuilder.addQueryParam(key, value);
}
});
let fileName = "ARMS_FULL_DATA_SEARCH_"+currentDate;
urlBuilder.addQueryParam("fileName",fileName);
const url = urlBuilder.build();
$.ajax({
url: url,
type: "GET",
xhrFields: {
responseType: 'blob' // 바이너리 데이터를 받을 수 있도록 설정
},
success: function(data, status, xhr) {
// 서버에서 받은 blob 데이터를 사용하여 파일 다운로드 처리
const blob = new Blob([data], { type: 'application/octet-stream' });
const link = document.createElement('a');
const url = window.URL.createObjectURL(blob);
// 파일 이름이 Content-Disposition 헤더에서 제공된 경우 이를 사용
const contentDisposition = xhr.getResponseHeader('Content-Disposition');
let downLoadfileName = fileName+'.xlsx'; //기본 파일명
if (contentDisposition && contentDisposition.indexOf('attachment') !== -1) {
const fileNameMatch = contentDisposition.match(/filename="(.+)"/);
if (fileNameMatch != null && fileNameMatch.length === 2) {
downLoadfileName = fileNameMatch[1];
}
}
link.href = url;
link.setAttribute('download', downLoadfileName); // 파일 이름 설정
document.body.appendChild(link);
link.click();
link.parentNode.removeChild(link);
},
error: function(xhr, status, error) {
console.error(error);
}
});
}
let date_YYMMDD = function () {
let date = new Date();
let year = String(date.getFullYear()).slice(2);
let month = String(date.getMonth() + 1).padStart(2, '0');
let day = String(date.getDate()).padStart(2, '0');
return year + month + day;
}
///////////////////////////////////////////////////
// fetchExcelData API 콜 이전 선택 인자들 값 세팅
/////////////////////////////////////////////////
function setOptionalParams() {
let optionalParams = {};
if (!isEmpty($("#date_timepicker_start").val())) {
optionalParams.startDate = $("#date_timepicker_start").val();
}
if (!isEmpty($("#date_timepicker_end").val())) {
optionalParams.endDate = $("#date_timepicker_end").val();
}
if (!isAllVersionsSelected()) {
optionalParams.pdServiceVersionIds = selectedVersionIds;
}
if (!isEmpty(selectedAlmProjectIds)) {
optionalParams.almProjectIds = selectedAlmProjectIds;
}
return optionalParams;
}
var getCurrentDate = function () {
let today = new Date();
let year = today.getFullYear().toString();
let month = (today.getMonth() + 1).toString().padStart(2, "0");
let day = today.getDate().toString().padStart(2, "0");
return year+month+day;
};
let toolbarCustom = [
{
type: "i",
k: "undo",
onclick: function () {
spreadsheet.undo();
}
},
{
type: "i",
k: "redo",
onclick: function () {
spreadsheet.redo();
}
},
{
type: "i",
k: "save",
onclick: function () {
excelExport();
}
},
{
type: "select",
k: "font-family",
v: ["Arial", "Verdana"]
},
{
type: "select",
k: "font-size",
v: ["9px", "10px", "11px", "12px", "13px", "14px", "15px", "16px", "17px", "18px", "19px", "20px"]
},
{
type: "i",
k: "text-align",
v: "left"
},
{
type: "i",
k: "text-align",
v: "center"
},
{
type: "i",
k: "text-align",
v: "right"
},
{
type: "i",
k: "font-weight",
v: "bold"
},
{
type: "i",
k: "font-style",
v: "italic"
},
{
type: "i",
k: "text-decoration",
v: "underline"
},
{
type: "i",
k: "text-decoration",
v: "line-through"
},
{
type: "color",
k: "color"
},
{
type: "color",
k: "background-color"
},
{
type: "i",
k: "search-box",
v: []
}
];
function getRandomColor() {
const letters = "0123456789ABCDEF";
let color = "#";
for (let i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
function drawCalendar(data) {
let Issue = data.filter(item => item.isReq === true);
let childIssue = data.filter(item => item.isReq === false);
let events = [];
let groupColors = {};
Issue.forEach(item => {
let groupId = item.key;
if (!groupColors[groupId]) {
groupColors[groupId] = getRandomColor(groupId);
}
events.push({
groupId: groupId,
title: `[ ${item.key} ] - ${item.issueTitle}`,
start: new Date(item.createDate),
end: item.resolutionDate ? new Date(item.resolutionDate) : new Date(item.updatedDate),
color: groupColors[groupId]
});
childIssue.forEach(child => {
if (child.parentReqKey === item.key) {
events.push({
groupId: groupId,
title: `[ ${item.key} - Sub ] - ${child.issueTitle}`,
start: new Date(child.createDate),
end: child.resolutionDate ? new Date(child.resolutionDate) : new Date(child.updatedDate),
color: groupColors[groupId]
});
}
});
});
if (!fullCalendar) {
let calendarEl = document.getElementById("full-data-calendar-req");
fullCalendar = new FullCalendar.Calendar(calendarEl, {
headerToolbar: {
left: "prevYear,prev,next,nextYear today",
center: "title",
right: "multiMonthYear,dayGridMonth,dayGridWeek,dayGridDay"
},
editable: false,
eventStartEditable: false,
eventDurationEditable: false,
timeZone: "local",
locale: userLocale,
dateClick: function(arg) {
console.log(arg);
},
eventMouseEnter: function(info) {
let tooltip = createTooltip(info);
document.body.appendChild(tooltip);
info.el.addEventListener("mouseleave", () => {
tooltip.remove();
});
},
initialDate: new Date().toISOString().split("T")[0],
navLinks: true,
editable: true,
dayMaxEvents: true,
initialView: "dayGridMonth",
eventClick: function(info) {
let eventObj = info.event;
alert(
"Event: " + eventObj.title + "\n" +
"Start: " + eventObj.start.toLocaleString() + "\n" +
"End: " + (eventObj.end ? eventObj.end.toLocaleString() : "Not set") + "\n"
);
info.jsEvent.preventDefault(); // 기본 동작 방지
}
});
fullCalendar.render();
} else {
fullCalendar.removeAllEventSources();
}
fullCalendar.addEventSource(events);
}
function createTooltip(info) {
let tooltip = document.createElement("div");
tooltip.classList.add("fc-tooltip");
tooltip.style.position = "absolute";
tooltip.style.background = "#333";
tooltip.style.color = "#fff";
tooltip.style.padding = "5px";
tooltip.style.borderRadius = "3px";
tooltip.style.pointerEvents = "none";
tooltip.style.zIndex = 9999;
tooltip.innerText = info.event.title;
document.body.appendChild(tooltip);
let rect = tooltip.getBoundingClientRect();
let pageX = info.jsEvent.pageX;
let pageY = info.jsEvent.pageY;
if (pageX + rect.width > window.innerWidth) {
pageX -= rect.width + 20;
}
if (pageY + rect.height > window.innerHeight) {
pageY -= rect.height + 20;
}
tooltip.style.top = `${pageY + 10}px`;
tooltip.style.left = `${pageX + 10}px`;
return tooltip;
}