src/main/java/kr/wisestone/owl/service/impl/IssueRelationServiceImpl.java | ●●●●● 패치 | 보기 | raw | blame | 히스토리 | |
src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java | ●●●●● 패치 | 보기 | raw | blame | 히스토리 | |
src/main/java/kr/wisestone/owl/web/condition/IssueRelationCondition.java | ●●●●● 패치 | 보기 | raw | blame | 히스토리 | |
src/main/webapp/custom_components/js-input-autocomplete/js-input-autocomplete.js | ●●●●● 패치 | 보기 | raw | blame | 히스토리 | |
src/main/webapp/i18n/ko/global.json | ●●●●● 패치 | 보기 | raw | blame | 히스토리 | |
src/main/webapp/scripts/app/issue/downIssueModifyStatus.controller.js | ●●●●● 패치 | 보기 | raw | blame | 히스토리 | |
src/main/webapp/scripts/app/issue/issueAddDown.controller.js | ●●●●● 패치 | 보기 | raw | blame | 히스토리 | |
src/main/webapp/scripts/app/issue/issueDetail.controller.js | ●●●●● 패치 | 보기 | raw | blame | 히스토리 | |
src/main/webapp/views/issue/issueDetail.html | ●●●●● 패치 | 보기 | raw | blame | 히스토리 |
src/main/java/kr/wisestone/owl/service/impl/IssueRelationServiceImpl.java
@@ -94,20 +94,21 @@ @Override @Transactional public boolean removeRelationIssue(Map<String, Object> resJsonData, IssueRelationCondition condition) { Long id = condition.getId(); if (id != null) { IssueRelation issueRelation = findOne(id); if (issueRelation != null) { StringBuilder sb = new StringBuilder(); issueHistoryService.detectRelationIssue(IssueHistoryType.DELETE, issueRelation, sb); issueHistoryService.addIssueHistory(issueRelation.getIssue(), IssueHistoryType.MODIFY, sb.toString()); //Long id = condition.getId(); List<Long> relRemoveIds = condition.getRemoveIds(); if (relRemoveIds != null && relRemoveIds.size() > 0) { for (Long relId : relRemoveIds) { IssueRelation issueRelation = findOne(relId); if (issueRelation != null) { StringBuilder sb = new StringBuilder(); issueHistoryService.detectRelationIssue(IssueHistoryType.DELETE, issueRelation, sb); issueHistoryService.addIssueHistory(issueRelation.getIssue(), IssueHistoryType.MODIFY, sb.toString()); this.issueRelationRepository.deleteById(id); return true; this.issueRelationRepository.deleteById(relId); } } return true; } return false; } } src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java
@@ -3718,28 +3718,31 @@ @Transactional @Override public void modifyParentIssue(IssueForm issueDownForm) { Issue issue = this.getIssue(issueDownForm.getId()); //하위 이슈 //Issue issue = this.getIssue(issueDownForm.getId()); //하위 이슈 Long newParentIssueId = issueDownForm.getParentIssueId(); //변경할 하위이슈의 상위이슈 StringBuilder sb = new StringBuilder(); Issue parentIssue = issue.getParentIssue(); //변경 전 하위이슈의 상위이슈 if(parentIssue != null && parentIssue.getId().equals(newParentIssueId)){ //변경 전 하위이슈의 상위이슈가 존재 할 경우 this.issueHistoryService.detectDownIssues(IssueHistoryType.DELETE, issue, sb); this.issueHistoryService.addIssueHistory(parentIssue, IssueHistoryType.MODIFY, sb.toString()); } for (Long downId : issueDownForm.getIds()) { Issue issue = this.getIssue(downId); if (newParentIssueId != null) { // 추가 할 경우 parentIssue = this.getIssue(newParentIssueId); //상위이슈(myIssue) issue.setParentIssue(parentIssue); //myIssue를 하위이슈의 상위이슈로 set this.issueHistoryService.detectDownIssues(IssueHistoryType.ADD, issue, sb); //issue = 하위이슈 } else{ // 삭제 할 경우 this.issueHistoryService.detectDownIssues(IssueHistoryType.DELETE, issue, sb); issue.setParentIssue(null); Issue parentIssue = issue.getParentIssue(); //변경 전 하위이슈의 상위이슈 if(parentIssue != null && parentIssue.getId().equals(newParentIssueId)){ //변경 전 하위이슈의 상위이슈가 존재 할 경우 this.issueHistoryService.detectDownIssues(IssueHistoryType.DELETE, issue, sb); this.issueHistoryService.addIssueHistory(parentIssue, IssueHistoryType.MODIFY, sb.toString()); } if (newParentIssueId != null) { // 추가 할 경우 parentIssue = this.getIssue(newParentIssueId); //상위이슈(myIssue) issue.setParentIssue(parentIssue); //myIssue를 하위이슈의 상위이슈로 set this.issueHistoryService.detectDownIssues(IssueHistoryType.ADD, issue, sb); //issue = 하위이슈 } else{ // 삭제 할 경우 this.issueHistoryService.detectDownIssues(IssueHistoryType.DELETE, issue, sb); issue.setParentIssue(null); } this.issueHistoryService.addIssueHistory(parentIssue, IssueHistoryType.MODIFY, sb.toString()); //parentIssue = myIssue(기록은 현재 상세페이지에 해야하니까) this.issueRepository.saveAndFlush(issue); } this.issueHistoryService.addIssueHistory(parentIssue, IssueHistoryType.MODIFY, sb.toString()); //parentIssue = myIssue(기록은 현재 상세페이지에 해야하니까) this.issueRepository.saveAndFlush(issue); } @Override src/main/java/kr/wisestone/owl/web/condition/IssueRelationCondition.java
@@ -1,7 +1,10 @@ package kr.wisestone.owl.web.condition; import com.google.common.collect.Lists; import kr.wisestone.owl.util.ConvertUtil; import kr.wisestone.owl.util.MapUtil; import java.util.List; import java.util.Map; /** @@ -13,10 +16,18 @@ private Long relationIssueId; private Long relationIssueType; private List<Long> removeIds = Lists.newArrayList(); public IssueRelationCondition() {} public static IssueRelationCondition make(Map<String, Object> params) { IssueRelationCondition condition = ConvertUtil.convertMapToClass(params, IssueRelationCondition.class); // 삭제 이슈 정보 if (MapUtil.getLongs(params, "removeIds") != null) { condition.setRemoveIds(MapUtil.getLongs(params, "removeIds")); } return condition; } @@ -51,4 +62,12 @@ public void setRelationIssueType(Long type) { this.relationIssueType = type; } public List<Long> getRemoveIds() { return removeIds; } public void setRemoveIds(List<Long> removeIds) { this.removeIds = removeIds; } } src/main/webapp/custom_components/js-input-autocomplete/js-input-autocomplete.js
@@ -23,6 +23,7 @@ page : "=", totalPage : "=", inputDisabled : "=", customInput : "=", }, templateUrl : "custom_components/js-input-autocomplete/js-input-autocomplete.html", link: function ($scope, $element, $attrs) { @@ -180,7 +181,9 @@ $scope.$apply(function () { $scope.open = false; $scope.page = 0; $scope.search = ""; if (!angular.isDefined($scope.customInput) && !$scope.customInput) { $scope.search = ""; } $scope.totalPage = 0; $scope.options = []; $scope.networkSuccess = false; @@ -301,7 +304,9 @@ switch (event.keyCode) { case 9 : // 탭키 닫기 $scope.open = false; $scope.search = ""; if (!angular.isDefined($scope.customInput) && !$scope.customInput) { $scope.search = ""; } $scope.page = 0; $scope.totalPage = 0; $scope.options = []; src/main/webapp/i18n/ko/global.json
@@ -222,8 +222,8 @@ "selectProjectAndIssueTypeDownloadExcel": "프로젝트, 이슈 유형을 선택하면 해당 하는 양식의 엑셀을 다운로드 할 수 있습니다.", "settingTableDisplay": "테이블 표시 설정", "deleteIssue": "이슈 삭제", "wantToDeleteSelectIssue": "선택한 이슈를 삭제하겠습니까? \n 사용자가 직접 삭제한 이슈는 어떠한 경우에도 복구가 불가능합니다.", "wantToDeleteSelectDownIssueInList": "선택한 하위 이슈를 하위 이슈 리스트에서 제외시키겠습니까?", "wantToDeleteSelectIssue": "선택한 이슈를 연관 이슈 리스트에서 제외시키겠습니까? \n 연관 이슈 리스트에서만 제외되며, 실제로 삭제되지 않습니다.", "wantToDeleteSelectDownIssueInList": "선택한 이슈를 하위 이슈 리스트에서 제외시키겠습니까? \n 하위 이슈 리스트에서만 제외되며, 실제로 삭제되지 않습니다.", "wantToDeleteOnlySelectIssue": "선택한 이슈만 삭제하겠습니까? \n 사용자가 직접 삭제한 이슈는 어떠한 경우에도 복구가 불가능합니다.", "wantToDeleteSelectDownIssue": "선택한 이슈의 하위 이슈가 존재 합니다. \n 선택한 이슈와 하위 이슈 모두 삭제하겠습니까? \n 사용자가 직접 삭제한 이슈는 어떠한 경우에도 복구가 불가능합니다.", "wantToDeleteSelectRelationIssue": "선택한 연관 이슈를 삭제하겠습니까? \n 사용자가 직접 삭제한 연관 이슈는 복구가 불가능합니다.", @@ -763,7 +763,7 @@ "updatableStatus": "변경 가능한 상태", "testCase": "테스트 케이스", "updateStatus": "상태 변경", "updateDownIssueAllStatus": "하위 이슈상태 전체 변경", "updateDownIssueStatus": "하위 이슈상태 변경", "tcmProject": "테스트 케이스 관리 프로젝트", "btsProject": "이슈 관리 프로젝트", "projectName": "프로젝트명", src/main/webapp/scripts/app/issue/downIssueModifyStatus.controller.js
@@ -72,7 +72,7 @@ var issueIds = []; angular.forEach(parameter.downIssues, function (downIssue) { issueIds.push(downIssue.id); issueIds.push(downIssue); }); return issueIds; @@ -112,7 +112,7 @@ var issueIds = []; angular.forEach(parameter.downIssues, function (downIssue) { issueIds.push(downIssue.id); issueIds.push(downIssue); }); return issueIds; src/main/webapp/scripts/app/issue/issueAddDown.controller.js
@@ -702,12 +702,16 @@ SweetAlert.error($filter("translate")("issue.errorSelectRelationIssue"), ""); return; }*/ var ids = []; if (downId != null) { ids.push(downId); } var contents = { //relationIssueType : $scope.vm.form.relationIssueTypeId, // issueId : $rootScope.currentDetailIssueId, issueId : parameter.id, id : downId, ids : ids, parentIssueId : parameter.id }; src/main/webapp/scripts/app/issue/issueDetail.controller.js
@@ -51,6 +51,8 @@ $scope.fn.containsPartner = containsPartner; $scope.fn.onActivate = onActivate; $scope.fn.issueBack = issueBack; $scope.fn.removeRelationIssue = removeRelationIssue; $scope.fn.removeDownIssue = removeDownIssue; // 이슈 목록 컨트롤러 vm, fn 상속 중 $scope.vm.viewer = {}; // 현재 이슈 @@ -110,7 +112,7 @@ $scope.vm.relTableConfigs = []; // 테이블 이벤트 $scope.relTableEvent = { removeRelationIssue : removeRelationIssue, // 연관 일감 삭제 //removeRelationIssue : removeRelationIssue, // 연관 일감 삭제 changeDetailView : changeDetailView }; @@ -118,7 +120,7 @@ $scope.vm.downTableConfigs = []; // 테이블 이벤트 $scope.downTableEvent = { removeDownIssue : removeDownIssue, // 연관 일감 삭제 //removeDownIssue : removeDownIssue, // 연관 일감 삭제 changeDetailView : changeDetailView }; @@ -152,7 +154,38 @@ }); // 하위 이슈 삭제 function removeDownIssue(id) { function removeDownIssue() { var removeIds = []; var removePermission = true; angular.forEach($scope.vm.viewer.issueDownVos, function (data) { if (data.checked && data.modifyPermissionCheck) { removeIds.push(data.id); } if (data.checked && !data.modifyPermissionCheck) { removePermission = false; } }); if (!removePermission) { SweetAlert.swal({ html : true, title : $filter("translate")("common.deleteFailed"), // 삭제 실패 text : $filter("translate")("project.notHaveDeletePermissionExistsProject"), // "삭제 권한이 없는 프로젝트가 존재합니다." type : "error" }); return; } if (removeIds.length < 1) { SweetAlert.swal({ title : $filter("translate")("common.checkPurgingTargets"), // 삭제 대상 확인 text : $filter("translate")("common.selectDestinationDeletion"), // 삭제 대상을 선택하세요. type : "warning" }); return; } // 삭제 알림 SweetAlert.swal({ title : $filter("translate")("issue.downIssueRemove"), // 하위 이슈 삭제 @@ -172,7 +205,7 @@ $rootScope.spinner = true; var contents = { id : id ids : removeIds }; Issue.modifyParentIssue($resourceProvider.getContent( @@ -194,7 +227,38 @@ } // 연관 이슈 삭제 function removeRelationIssue(id) { function removeRelationIssue() { var removeIds = []; var removePermission = true; angular.forEach($scope.vm.viewer.issueRelationVos, function (data) { if (data.checked && data.modifyPermissionCheck) { removeIds.push(data.id); } if (data.checked && !data.modifyPermissionCheck) { removePermission = false; } }); if (!removePermission) { SweetAlert.swal({ html : true, title : $filter("translate")("common.deleteFailed"), // 삭제 실패 text : $filter("translate")("issue.notHaveDeletePermissionExistsAnIssue"), // 삭제 권한이 없는 이슈가 존재합니다. type : "error" }); return; } if (removeIds.length < 1) { SweetAlert.swal({ title : $filter("translate")("common.checkPurgingTargets"), // 삭제 대상 확인 text : $filter("translate")("common.selectDestinationDeletion"), // 삭제 대상을 선택하세요. type : "warning" }); return; } // 삭제 알림 SweetAlert.swal({ title : $filter("translate")("issue.relationIssueRemove"), // 연관 이슈 삭제 @@ -214,7 +278,7 @@ $rootScope.spinner = true; var contents = { id : id removeIds : removeIds }; IssueRelation.delete($resourceProvider.getContent( @@ -436,6 +500,10 @@ function makeRelTableConfigs() { $scope.vm.relTableConfigs = []; $scope.vm.relTableConfigs.push($tableProvider.config() .setDType("checkbox") .setHWidth("width-20-p") .setDAlign("text-center")) $scope.vm.relTableConfigs.push($tableProvider.config() .setHName("issue.relationIssueType") .setDType("renderer") .setDAlign("text-center") @@ -449,7 +517,7 @@ .setHWidth("width-60-p bold") .setHSort(false) .setDRenderer("ISSUE_RELATION_MOVE")) if($scope.vm.viewer.modifyPermissionCheck) { /*if($scope.vm.viewer.modifyPermissionCheck) { $scope.vm.relTableConfigs.push($tableProvider.config() .setHName("issue.relationIssueDelete") .setDType("renderer") @@ -458,7 +526,7 @@ .setDRenderer("ISSUE_RELATION_DELETE") .setHSort(false) .setDAlign("text-center")) } }*/ angular.forEach($scope.vm.relTableConfigs, function (Rel_issueTableConfig) { // 표시 대상인 컬럼만 화면에 그려준다. if (Rel_issueTableConfig.display) { @@ -472,13 +540,17 @@ function makeDownTableConfigs() { $scope.vm.downTableConfigs = []; $scope.vm.downTableConfigs.push($tableProvider.config() .setDType("checkbox") .setHWidth("width-20-p") .setDAlign("text-center")) $scope.vm.downTableConfigs.push($tableProvider.config() .setHName("issue.downIssueTitle") .setDType("renderer") .setDAlign("text-center") .setHWidth("width-60-p bold") .setHSort(false) .setDRenderer("ISSUE_DOWN_MOVE")) if($scope.vm.viewer.modifyPermissionCheck){ /*if($scope.vm.viewer.modifyPermissionCheck){ $scope.vm.downTableConfigs.push($tableProvider.config() .setHName("issue.relationIssueDelete") .setDType("renderer") @@ -487,7 +559,7 @@ .setDRenderer("ISSUE_DOWN_DELETE") .setHSort(false) .setDAlign("text-center")) } }*/ angular.forEach($scope.vm.downTableConfigs, function (Down_issueTableConfig) { // 표시 대상인 컬럼만 화면에 그려준다. @@ -531,6 +603,10 @@ .setHWidth("width-60-p bold") .setHSort(false) .setDRenderer("ISSUE_RELATION_MOVE"))*/ $scope.vm.relTableConfigs.push($tableProvider.config() .setDType("checkbox") .setHWidth("width-20-p") .setDAlign("text-center")) angular.forEach($scope.vm.issueRelTableConfigs, function (Rel_issueTableConfig) { // 표시 대상인 컬럼만 화면에 그려준다. if (Rel_issueTableConfig.display) { @@ -539,7 +615,7 @@ } }); if($scope.vm.viewer.modifyPermissionCheck) { /*if($scope.vm.viewer.modifyPermissionCheck) { $scope.vm.relTableConfigs.push($tableProvider.config() .setHName("issue.relationIssueDelete") .setDType("renderer") @@ -547,7 +623,7 @@ .setDRenderer("ISSUE_RELATION_DELETE") .setHSort(false) .setDAlign("text-center")) } }*/ } else { makeRelTableConfigs(); } @@ -575,6 +651,10 @@ .setHWidth("width-60-p bold") .setHSort(false) .setDRenderer("ISSUE_DOWN_MOVE"))*/ $scope.vm.downTableConfigs.push($tableProvider.config() .setDType("checkbox") .setHWidth("width-20-p") .setDAlign("text-center")) angular.forEach($scope.vm.issueDownTableConfigs, function (Down_issueTableConfig) { // 표시 대상인 컬럼만 화면에 그려준다. if (Down_issueTableConfig.display) { @@ -582,7 +662,7 @@ $scope.fn.setDownTableColumn(Down_issueTableConfig); } }); if($scope.vm.viewer.modifyPermissionCheck) { /*if($scope.vm.viewer.modifyPermissionCheck) { $scope.vm.downTableConfigs.push($tableProvider.config() .setHName("issue.relationIssueDelete") .setDType("renderer") @@ -590,7 +670,7 @@ .setDRenderer("ISSUE_DOWN_DELETE") .setHSort(false) .setDAlign("text-center")) } }*/ } else { makeDownTableConfigs(); } @@ -632,9 +712,14 @@ return; } var ids = []; if ($scope.vm.form.issuesDown[0].id != null) { ids.push($scope.vm.form.issuesDown[0].id); } var contents = { issueId : $rootScope.currentDetailIssueId, id : $scope.vm.form.issuesDown[0].id, ids : ids, parentIssueId : $rootScope.currentDetailIssueId }; @@ -712,6 +797,20 @@ } function modifyDownIssueStatus() { var issueIds = []; angular.forEach($scope.vm.viewer.issueDownVos, function (data) { if (data.checked) { issueIds.push(data.id); //$scope.vm.projectId = data.projectId; } }); if (issueIds.length < 1) { SweetAlert.warning($filter("translate")("issue.selectionCheck"), $filter("translate")("issue.selectIssueToChangeStatus")); // 선택 대상 확인, 상태 변경할 이슈를 선택하세요. return; } $uibModal.open({ templateUrl : 'views/issue/downIssueModifyStatus.html', size : "md", @@ -722,7 +821,8 @@ return { issueTypeId : $scope.vm.viewer.issueTypeVo.id, issueIds : [$scope.vm.viewer.id], downIssues : $scope.vm.viewer.issueDownVos, //downIssues : $scope.vm.viewer.issueDownVos, downIssues : issueIds, projectId : $scope.vm.viewer.projectVo.id }; } src/main/webapp/views/issue/issueDetail.html
@@ -488,8 +488,21 @@ <div class="col-md-10"> <span class="info_detail_font h3" translate="issue.relationIssue">연관 이슈</span> </div> <div class="col-md-1"> <!--<div class="col-md-1"> <button class="btn btn-darkgrey offset-10" ng-click="fn.addRelationIssueTableConfig()" type="button"><span translate="issue.settingTableDisplay">테이블 표시 설정</span></button> </div>--> <div class="btn-group offset-11"> <button aria-expanded="false" aria-haspopup="true" tabindex="-1" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" type="button"><span translate="common.addFunction">추가기능</span> </button> <div aria-labelledby="dropdownMenuButton2" class="dropdown-menu left-menu" x-placement="bottom-start" > <!--<a class="dropdown-item cursor" form-submit="issueListForm" make-search-conditions="fn.makeSearchConditions()"> <span translate="common.allDownloadExcel">엑셀 다운로드</span></a>--> <a class="dropdown-item cursor" ng-click="fn.addRelationIssueTableConfig()"> <span translate="issue.settingTableDisplay">테이블 표시 설정</span></a> <a class="dropdown-item cursor" ng-click="fn.removeRelationIssue()"> <span translate="common.selectDelete">삭제</span></a> </div> </div> </div> @@ -538,7 +551,7 @@ <div class="col-md-8"> <span class="info_detail_font h3" translate="issue.downIssue">하위 이슈</span> </div> <div class="col-sm-2"> <!--<div class="col-sm-2"> <a><button type="button" class="btn btn-darkgrey offset-7" ng-if="vm.viewer.modifyPermissionCheck" ng-click="fn.modifyDownIssueStatus()"> <span ng-if="vm.viewer.modifyPermissionCheck" translate="common.updateDownIssueAllStatus">하위이슈 상태 전체 변경</span> @@ -546,6 +559,20 @@ </div> <div class="col-sm-1"> <button class="btn btn-darkgrey offset-10" ng-click="fn.addDownIssueTableConfig()" type="button"><span translate="issue.settingTableDisplay">테이블 표시 설정</span></button> </div>--> <div class="btn-group offset-11"> <button aria-expanded="false" aria-haspopup="true" tabindex="-1" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" type="button"><span translate="common.addFunction">추가기능</span> </button> <div aria-labelledby="dropdownMenuButton2" class="dropdown-menu left-menu" x-placement="bottom-start" > <!--<a class="dropdown-item cursor" form-submit="issueListForm" make-search-conditions="fn.makeSearchConditions()"> <span translate="common.allDownloadExcel">엑셀 다운로드</span></a>--> <a class="dropdown-item cursor" ng-if="vm.viewer.modifyPermissionCheck" ng-click="fn.modifyDownIssueStatus()"> <span translate="common.updateDownIssueStatus">하위이슈 상태 변경</span></a> <a class="dropdown-item cursor" ng-click="fn.addDownIssueTableConfig()"> <span translate="issue.settingTableDisplay">테이블 표시 설정</span></a> <a class="dropdown-item cursor" ng-click="fn.removeDownIssue()"> <span translate="common.selectDelete">삭제</span></a> </div> </div> </div>