src/main/java/kr/wisestone/owl/common/IssueCustomFieldValueFormComparator.java
New file @@ -0,0 +1,20 @@ package kr.wisestone.owl.common; import kr.wisestone.owl.web.form.IssueApiForm; import kr.wisestone.owl.web.form.IssueCustomFieldValueForm; import java.util.Comparator; public class IssueCustomFieldValueFormComparator implements Comparator<IssueCustomFieldValueForm> { @Override public int compare(IssueCustomFieldValueForm o1, IssueCustomFieldValueForm o2) { if (o1.getCustomFieldId() > o2.getCustomFieldId()) { return 1; } else if (o1.getCustomFieldId() < o2.getCustomFieldId()) { return -1; } else { return 0; } } } src/main/java/kr/wisestone/owl/mapper/IssueMapper.java
@@ -51,6 +51,6 @@ Long countByDepartment(IssueCondition issueCondition); List<Map<String, Object>> findNotCompleteByParentIssueId(Long parentIssueId); List<Map<String, Object>> findNotCompleteByParentIssueId(IssueCondition issueCondition); } src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java
@@ -3,6 +3,7 @@ import com.google.common.collect.Lists; import com.sun.org.apache.bcel.internal.generic.NEW; import kr.wisestone.owl.common.ExcelConditionCheck; import kr.wisestone.owl.common.IssueCustomFieldValueFormComparator; import kr.wisestone.owl.config.CommonConfiguration; import kr.wisestone.owl.constant.Constants; import kr.wisestone.owl.constant.ElasticSearchConstants; @@ -263,11 +264,8 @@ List<IssueVo> issueVos = this.findIssue(issueApiForm, customFieldApiOverlaps, user.getId()); int size = issueVos.size(); if (size == 1) { if (size > 0) { issueForm.setParentIssueId(issueVos.get(0).getId()); } else if (size > 1) { throw new OwlRuntimeException( this.messageAccessor.getMessage(MsgConstants.API_OVERLAP_ERROR)); } issueForm.setIsApi(Issue.IS_API_YES); @@ -328,39 +326,36 @@ } // 중복된 상위 이슈 검색 private List<IssueVo> findIssue(IssueApiForm issueApiForm, List<CustomFieldApiOverlap> customFieldApiOverlaps, Long userId) { private List<IssueVo> findIssue(IssueApiForm issueApiform, List<CustomFieldApiOverlap> customFieldApiOverlaps, Long userId) { List<IssueCustomFieldValueForm> issueCustomFieldValueForms = issueApiform.getIssueCustomFieldValues(); List<IssueVo> resultIssueVos = Lists.newArrayList(); String comma = ","; List<IssueVo> resultIssueVos = new ArrayList<>(); if (issueCustomFieldValueForms.size() > 0) { String concatUseValue = ""; int useIdx = 0; if (customFieldApiOverlaps != null && customFieldApiOverlaps.size() > 0) { for (CustomFieldApiOverlap customFieldApiOverlap : customFieldApiOverlaps) { for (IssueCustomFieldValueForm issueCustomFieldValue : issueApiForm.getIssueCustomFieldValues()) { IssueCustomFieldValueCondition issueCustomFieldValueCondition = new IssueCustomFieldValueCondition(); issueCustomFieldValueCondition.setUseParentIssueId(true); if (customFieldApiOverlap.getCustomField().getId().equals(issueCustomFieldValue.getCustomFieldId())) { issueCustomFieldValueCondition.setUseValue(issueCustomFieldValue.getUseValue()); IssueCustomFieldValueFormComparator comp = new IssueCustomFieldValueFormComparator(); Collections.sort(issueCustomFieldValueForms, comp); List<Map<String, Object>> results = this.issueMapper.findByCustomFieldValue(issueCustomFieldValueCondition); if (results != null && results.size() > 0) { List<IssueVo> findIssueVos = new ArrayList<>(); Collections.copy(resultIssueVos, findIssueVos); resultIssueVos.clear(); for (Map<String, Object> result : results) { IssueVo issueVo = ConvertUtil.convertMapToClass(result, IssueVo.class); if (findIssueVos.size() == 0) { resultIssueVos.add(issueVo); } else { IssueVo findIssueVo = findIssueVo(findIssueVos, issueVo.getId()); if (findIssueVo != null) { resultIssueVos.add(findIssueVo); } } } } else { resultIssueVos.clear(); return resultIssueVos; for (IssueCustomFieldValueForm issueCustomFieldValueForm : issueCustomFieldValueForms) { for(CustomFieldApiOverlap customFieldApiOverlap : customFieldApiOverlaps) { if (customFieldApiOverlap.getCustomField().getId().equals(issueCustomFieldValueForm.getCustomFieldId())) { if (useIdx > 0) { concatUseValue = concatUseValue.concat(comma); } concatUseValue = concatUseValue.concat(issueCustomFieldValueForm.getUseValue()); useIdx++; } } } IssueCustomFieldValueCondition issueCustomFieldValueCondition = new IssueCustomFieldValueCondition(); issueCustomFieldValueCondition.setUseValue(concatUseValue); List<Map<String, Object>> results = this.issueMapper.findByCustomFieldValue(issueCustomFieldValueCondition); if (results != null && results.size() > 0) { for (Map<String, Object> result : results) { resultIssueVos.add(ConvertUtil.convertMapToClass(result, IssueVo.class)); } } } @@ -773,6 +768,7 @@ int totalPage = (int) Math.ceil((totalCount - 1) / pageable.getPageSize()) + 1; // 이슈 아이디 초기화 issueCondition.setIsApi(issueCondition.getIsApi()); issueCondition.setIssueIds(Lists.newArrayList()); // Map 에 있는 데이터를 IssueVo 데이터로 변환한다. this.setMapToIssueVo(results, issueVos, issueCondition, user); @@ -1483,42 +1479,25 @@ public List<IssueVo> findIssue(IssueApiForm issueApiform) { List<IssueCustomFieldValueForm> issueCustomFieldValueForms = issueApiform.getIssueCustomFieldValues(); List<IssueVo> resultIssueVos = new ArrayList<>(); List<IssueVo> resultIssueVos = Lists.newArrayList(); String comma = ","; IssueCustomFieldValueCondition issueCustomFieldValueCondition = new IssueCustomFieldValueCondition(); issueCustomFieldValueCondition.setUseParentIssueId(false); if (issueCustomFieldValueForms.size() > 0) { for (IssueCustomFieldValueForm issueCustomFieldValueForm : issueCustomFieldValueForms) { CustomField customField = this.customFieldService.getCustomField(issueCustomFieldValueForm.getCustomFieldId()); CustomFieldType customFieldType = CustomFieldType.DATETIME; if (customFieldType.equals(customField.getCustomFieldType())) { continue; String concatUseValue = ""; for (int i = 0; i < issueCustomFieldValueForms.size(); i++) { IssueCustomFieldValueForm issueCustomFieldValueForm = issueCustomFieldValueForms.get(i); if (i > 0) { concatUseValue = concatUseValue.concat(comma); } // issueCustomFieldValueCondition.addUseValue(issueCustomFieldValueForm.getUseValue()); issueCustomFieldValueCondition.setUseValue(issueCustomFieldValueForm.getUseValue()); List<Map<String, Object>> results = this.issueMapper.findByCustomFieldValue(issueCustomFieldValueCondition); if (results != null && results.size() > 0) { List<IssueVo> findIssueVos = new ArrayList<>(); Collections.copy(resultIssueVos, findIssueVos); resultIssueVos.clear(); for (Map<String, Object> result : results) { IssueVo issueVo = ConvertUtil.convertMapToClass(result, IssueVo.class); concatUseValue = concatUseValue.concat(issueCustomFieldValueForm.getUseValue()); } issueVo.setParentIssueVo(this.getParentIssueVo(MapUtil.getLong(result, "parentIssueId"))); if (findIssueVos.size() == 0) { resultIssueVos.add(issueVo); } else { IssueVo findIssueVo = findIssueVo(findIssueVos, issueVo.getId()); if (findIssueVo != null) { resultIssueVos.add(findIssueVo); } } } } else { resultIssueVos.clear(); return resultIssueVos; IssueCustomFieldValueCondition issueCustomFieldValueCondition = new IssueCustomFieldValueCondition(); issueCustomFieldValueCondition.setUseValue(concatUseValue); List<Map<String, Object>> results = this.issueMapper.findByCustomFieldValue(issueCustomFieldValueCondition); if (results != null && results.size() > 0) { for (Map<String, Object> result : results) { resultIssueVos.add(ConvertUtil.convertMapToClass(result, IssueVo.class)); } } } @@ -1534,15 +1513,6 @@ } } return null; } // 하위 이슈가 모두 종료 처리 되었을 경우 상위이슈도 완료 처리 private void setParentIssueComplete(Issue parentIssue) { if (parentIssue != null) { this.issueMapper.findNotCompleteByParentIssueId(parentIssue.getId()); } } @@ -1570,10 +1540,12 @@ } if (parentIssue != null) { List<Map<String, Object>> results = this.issueMapper.findNotCompleteByParentIssueId(parentIssue.getId()); IssueCondition issueCondition = new IssueCondition(issueVo.getId(), parentIssue.getId()); List<Map<String, Object>> results = this.issueMapper.findNotCompleteByParentIssueId(issueCondition); // 하위 일감이 모두 종료 상태일때 상위 일감도 종료 처리 if (results == null || results.size() == 0) { parentIssue.setIssueStatus(issueType.getIssueStatus()); this.issueRepository.saveAndFlush(parentIssue); } } @@ -1660,6 +1632,7 @@ this.issueHistoryService.detectIssueStatus(issue, issueForm, detectIssueChange, oldIssueStatus, issueStatus); } // db에 저장 issue = this.saveIssue(issueForm, checkIssueData); // 이슈 이력 등록 src/main/java/kr/wisestone/owl/vo/IssueVo.java
@@ -31,6 +31,7 @@ private Long severityId; private String severityName; private String severityColor; private String isApi; private ProjectVo projectVo; // 이슈 상세에서 사용 private IssueStatusVo issueStatusVo; // 이슈 상세에서 사용 private IssueTypeVo issueTypeVo; // 이슈 상세에서 사용 @@ -231,6 +232,14 @@ this.severityColor = severityColor; } public String getIsApi() { return isApi; } public void setIsApi(String isApi) { this.isApi = isApi; } public Boolean getModifyPermissionCheck() { return modifyPermissionCheck; } src/main/java/kr/wisestone/owl/web/condition/IssueCondition.java
@@ -34,6 +34,7 @@ private Long workspaceId; private String projectType; private String deep; private String isApi; private Long parentIssueId; // 상위 일감 private String useValue; private List<Long> projectIds = Lists.newArrayList(); @@ -55,6 +56,11 @@ private Boolean hideIssue; public IssueCondition(){} public IssueCondition(Long issueId, Long parentIssueId){ this.id = issueId; this.parentIssueId = parentIssueId; } // 대시보드 위기관리 위젯에서 사용 public IssueCondition(List<String> issueIds){ this.issueIds = issueIds; @@ -301,6 +307,14 @@ this.deep = deep; } public String getIsApi() { return isApi; } public void setIsApi(String isApi) { this.isApi = isApi; } public List<Long> getProjectIds() { return projectIds; } src/main/resources/mybatis/query-template/issue-template.xml
@@ -15,6 +15,7 @@ issue.complete_date as completeDate, issue.issue_number as issueNumber, issue.register_date as registerDate, issue.is_api as isApi, SUBSTRING(issue.modify_date, 1, 19) as modifyDate, project.id as projectId, project.name as projectName, @@ -965,8 +966,6 @@ AND is_api = #{isApi}; </select> <!-- 이슈 상태를 사용하는 이슈 갯수를 조회한다. --> <select id="countByIssueStatusId" resultType="java.lang.Long" parameterType="java.lang.Long"> SELECT COUNT(DISTINCT id) FROM @@ -977,29 +976,32 @@ <!-- 특정 사용자 정의 필드 값이 같은 이슈를 조회 --> <select id="findByCustomFieldValue" resultType="java.util.HashMap" parameterType="kr.wisestone.owl.web.condition.IssueCustomFieldValueCondition"> SELECT issue_custom.issue_id as id, iss.parent_issue_id as parentIssueId FROM issue_custom_field_value issue_custom INNER JOIN issue iss ON iss.id = issue_custom.issue_id WHERE 1=1 AND issue_custom.use_value = #{useValue} <choose> <when test="useParentIssueId.equals(true)"> AND iss.parent_issue_id IS NULL </when> <otherwise> AND iss.parent_issue_id IS NOT NULL </otherwise> </choose> issue.id as id, issue.title as title, customFieldValue.customFieldType AS customFieldType, GROUP_CONCAT(customFieldValue.useValue) AS concatUseValue FROM issue issue FORCE INDEX(reverseIndex) INNER JOIN issue_status as issStatus ON issue.issue_status_id = issStatus.id LEFT OUTER JOIN ( SELECT cf.id AS customFieldId, cf.custom_field_type AS customFieldType, issue_custom.use_value AS useValue, issue_custom.issue_id AS issueId FROM issue_custom_field_value issue_custom INNER JOIN custom_field cf ON cf.id = issue_custom.custom_field_id ORDER BY issue_custom.id ASC) customFieldValue ON customFieldValue.issueId = issue.id WHERE issStatus.issue_status_type != 'CLOSE' GROUP BY issue.id HAVING concatUseValue LIKE CONCAT('%', #{useValue}, '%') </select> <!-- 종료 안된 하위 이슈 가져오기 --> <select id="findNotCompleteByParentIssueId" resultType="java.util.HashMap" parameterType="java.lang.Long"> <select id="findNotCompleteByParentIssueId" resultType="java.util.HashMap" parameterType="kr.wisestone.owl.web.condition.IssueCondition"> SELECT iss.id as id iss.id as id, iss.title as title FROM issue iss INNER JOIN issue_status issueStatus on iss.issue_status_id = issueStatus.id WHERE iss.parent_issue_id = #{parentIssueId} AND iss.id != #{id} AND issueStatus.issue_status_type != 'CLOSE' </select> </mapper> src/main/webapp/bower_components/bootstrap-daterangepicker/daterangepicker.js
@@ -108,7 +108,7 @@ '<i class="fa fa-calendar glyphicon glyphicon-calendar"></i>' + '<div class="calendar-time">' + '<div></div>' + '<i class="fa fa-clock-o glyphicon glyphicon-time"></i>' + '<i class="fa fa-clock-o glyphicon glyphicon-time" style="position: relative; left:12.3rem; bottom: 1.23rem "></i>' + '</div>' + '</div>' + '<div class="calendar-table"></div>' + src/main/webapp/custom_components/js-table/tableColumnGenerator.directive.js
@@ -75,13 +75,9 @@ // 프로젝트 이름(프로젝트 리스트에서 사용) case "PROJECT_NAME" : if ($rootScope.workProject != null && $rootScope.workProject.id == scope.data.id) { // makeTag += "<span class='titlenameSelect cursor table-word-break-all sub-line' ng-click='event.changeLastProject(data.id)'>" + myToken + scope.data.name.replace(/</gi, '<') + "</span>"; makeTag += "<span class='titlenameSelect cursor table-word-break-all sub-line' ng-click='event.moveIssue(data.id)'>" + myToken + scope.data.name.replace(/</gi, '<') + "</span>"; // makeTag += "<span class='titlenameSelect cursor table-word-break-all sub-line' ng-click='event.changeDetailView(data.id)'>" + myToken + scope.data.name.replace(/</gi, '<') + "</span>"; makeTag += "<span class='titlenameSelect cursor table-word-break-all sub-line' ng-click='event.changeLastProject(data.id)'>" + myToken + scope.data.name.replace(/</gi, '<') + "</span>"; } else { // makeTag += "<span class='titlename cursor table-word-break-all sub-line' ng-click='event.changeLastProject(data.id)'>" + myToken + scope.data.name.replace(/</gi, '<') + "</span>"; makeTag += "<span class='titlename cursor table-word-break-all sub-line' ng-click='event.moveIssue(data.id)'>" + myToken + scope.data.name.replace(/</gi, '<') + "</span>"; // makeTag += "<span class='titlename cursor table-word-break-all sub-line' ng-click='event.changeDetailView(data.id)'>" + myToken + scope.data.name.replace(/</gi, '<') + "</span>"; makeTag += "<span class='titlename cursor table-word-break-all sub-line' ng-click='event.changeLastProject(data.id)'>" + myToken + scope.data.name.replace(/</gi, '<') + "</span>"; } break; @@ -306,7 +302,6 @@ // 하위 이슈 이동(제목) case "ISSUE_DOWN_MOVE" : makeTag += "<span class=\"titlename cursor\" ng-click=\"event.changeDetailView(data)\">" + scope.data.title + "</span></a>"; break; @@ -429,8 +424,8 @@ makeTag += '<span class="number-tag">' + scope.data.projectKey + ' - ' + scope.data.issueNumber + '</span>'; makeTag += ' <span class="tag"> / </span> '; makeTag += "<span class='badge' ng-style='{ \"background-color\" : \"" + scope.data.issueStatusColor + "\"," + "\"border-color\"" + " : \"" + scope.data.issueStatusColor + "\", \"color\": \"#FFFFFF\" }'>" + scope.data.issueStatusName + "</span>"; // makeTag += ' <span class="tag"> / </span> '; // makeTag += '<span class="tag">' + scope.data.projectName + '</span>'; makeTag += '<span class="tag"> / </span> '; makeTag += '<span class="tag">' +'<span>API: </span>' + scope.data.isApi + '</span>'; makeTag += '</div>'; makeTag += '<div class="titlename cursor text-left" ng-click="event.changeDetailView(data.id)">' + scope.data.title.replace(/</gi, '<') + '</div>'; makeTag += '<div class="extra-infodiv text-left">'; src/main/webapp/i18n/ko/global.json
@@ -888,12 +888,13 @@ "failedToApiMonitor": "API 기록 조회 실패", "requestSample": "API 요청 샘플", "requestSampleAdd": "이슈 추가", "requestSampleModify": "이슈 수정", "requestSampleModify": "이슈 상태 수정", "downIssueOverlapSetting" : "하위 이슈 처리 기준 항목", "upIssueCompleteIssueStatus" : "상위 이슈 자동종료 이슈 상태 설정", "autoCompleteIssueStatus" : "자동 종료 설정할 이슈 상태", "successToApiAutoCompleteIssueStatus" : "자동 종료 이슈 상태 설정 완료", "failedToApiAutoCompleteIssueStatus" : "자동 종료 이슈 상태 설정 실패" "failedToApiAutoCompleteIssueStatus" : "자동 종료 이슈 상태 설정 실패", "requestSampleModifyDesc" : "(수정시 customField 항목은 검색 용도로 사용됨)" }, "companyField" : { "info": "업체정보", src/main/webapp/index.html
@@ -21,7 +21,7 @@ <meta name="google-site-verification" content="yhmSp9Zsw5oecXjp43Ndu0w9rBA3FNpnNZ8bQFA_iDA"/> <meta name="viewport" content="user-scalable=no,initial-scale=1,maximum-scale=1"> <title>OWL ITS</title> <title>탐지정보 통합관리</title> <link type="text/css" rel="stylesheet" href="bower_components/font-awesome/css/font-awesome.css"> <link type="text/css" rel="stylesheet" href="bower_components/jquery-ui/themes/base/jquery-ui.css"> src/main/webapp/scripts/app/issue/issueDetail.controller.js
@@ -50,6 +50,7 @@ $scope.fn.setDownTableConfigs = setDownTableConfigs; $scope.fn.containsPartner = containsPartner; $scope.fn.onActivate = onActivate; $scope.fn.issueBack = issueBack; // 이슈 목록 컨트롤러 vm, fn 상속 중 $scope.vm.viewer = {}; @@ -125,6 +126,12 @@ //$rootScope.$broadcast("makeIssueSearch",issue); $scope.$parent.tableEvent.changeDetailView(issue.id); $scope.fn.onActivate(); } // 상위 이슈 클릭시 상위 이슈로 이동 function issueBack() { $rootScope.currentDetailIssueId = $scope.vm.viewer.parentIssueVo.id $rootScope.$broadcast("getIssueDetail", {id: $rootScope.currentDetailIssueId}); } function onActivate() { @@ -490,6 +497,7 @@ // 연관 이슈 테이블 설정 function setRelTableConfigs(issueTableConfigVo) { if (issueTableConfigVo == null) return; var issueTableConfigs = issueTableConfigVo.issueTableConfigs; // 연관 슈 목록 테이블 설정 값을 가져와서 적용한다. @@ -541,6 +549,7 @@ // 하위 이슈 상세 조회 결과 설정 function setDownTableConfigs(issueTableConfigVo) { if (issueTableConfigVo == null) return; var issueTableConfigs = issueTableConfigVo.issueTableConfigs; // 연관 슈 목록 테이블 설정 값을 가져와서 적용한다. @@ -656,7 +665,6 @@ // $scope.fn.getIssueDetail(); // }); // todo 이건 또 뭐지 $scope.$watch(function() { return $rootScope.currentDetailIssueId; }, function() { @@ -889,11 +897,7 @@ angular.forEach(result.data.data.issueDownVos, function (issueDownVo){ //$scope.vm.form.issuesDown.push(issueDownVo.issueDown); $scope.vm.form.issuesDown.push(issueDownVo); // 간헐적인 하위 이슈 갱신 오류 방지 // $scope.$on("getIssueDetail", function (event, args) { // $scope.fn.getIssueDetail(); // }); }); } $scope.vm.viewer.issueRelationVos = result.data.data.issueRelationVos; src/main/webapp/scripts/app/project/projectList.controller.js
@@ -69,9 +69,7 @@ $scope.tableEvent = { modify : modify, projectCustomFieldConfig : projectCustomFieldConfig, changeLastProject : changeLastProject, moveIssue : moveIssue, changeDetailView : changeDetailView changeLastProject : changeLastProject }; angular.extend(this, $controller('autoCompleteController', {$scope : $scope, $injector : $injector})); @@ -363,22 +361,8 @@ } function changeLastProject(projectId) { $rootScope.changeLastProject(projectId); } function moveIssue(projectId) { // $rootScope.currentDetailIssueId = null; // 이슈 번호를 저장한 후 이슈 목록으로 이동한다. // $rootScope.$broadcast("makeIssueSearch", {id :$rootScope.currentDetailIssueId}); //$rootScope.$broadcast("makeIssueSearch", {id :$rootScope.issueTypeMenu.id}); $rootScope.$broadcast("makeIssueSearch",projectId); } function changeDetailView() { // $rootScope.$broadcast("getIssueDetail", {id: $rootScope.currentDetailIssueId}); //$scope.$broadcast("getIssueDetail", {id: $rootScope.currentDetailIssueId}); // $rootScope.$broadcast("getIssueDetail", {id :$rootScope.currentDetailIssueId}); //$rootScope.$broadcast("getIssueList", {id :$rootScope.issueTypeMenu.id}); //$rootScope.changeLastProject(projectId); $state.go("issues.list") } $scope.fn.makeTableConfigs(); src/main/webapp/scripts/components/utils/dateRangePicker.directive.js
@@ -77,7 +77,8 @@ }); } else if ($attrs["rangeType"] === "singleDate") { $($element).daterangepicker({ timePicker: false, timePicker: true, timePickerSeconds : true, autoUpdateInput: true, autoApply : true, singleDatePicker : true, @@ -85,7 +86,7 @@ //parentEl : $scope.parentEl !== undefined ? $scope.parentEl : "", locale: { format: 'YYYY-MM-DD', format: 'YYYY-MM-DD/hh-mm-ss A', applyLabel: options.applyLabel, cancelLabel: options.cancelLabel, daysOfWeek: options.daysOfWeek, src/main/webapp/views/api/apiSetting.html
@@ -1,13 +1,6 @@ <div class="row"> <div class="col-sm-12"> <div class="element-wrapper"> <div class="element-actions"> <button ng-click="fn.add()" class="btn btn-xlg btn-danger"><i class="os-icon os-icon-plus"></i> <span translate="api.addOverlapField">필드 만들기</span> </button> </div> <div class="element-actions" ng-if="$root.checkMngPermission('USER_PERMISSION_MNG_ISSUE_STATUS')"> </div> <h6 class="element-header" translate="api.setting"> src/main/webapp/views/api/apiSettingSpec.html
@@ -99,7 +99,7 @@ <div class="element-box"> <div class="row"> <div class="col-md-1"> <label for="issue-detectingInfo" class="issue-label"> <label class="issue-label"> <span translate="api.requestSampleAdd">이슈 추가</span> </label> </div> @@ -108,12 +108,17 @@ </div> <div class="col-md-1"></div> <div class="col-md-1"> <label for="issue-detectingInfo" class="issue-label"> <label class="issue-label"> <span translate="api.requestSampleModify">이슈 수정</span> </label> <label class="text-info"> <span translate="api.requestSampleModifyDesc">수정시</span> </label> </div> <div> <pre>{{vm.sampleJsonModify}}</pre> <div class="col-md-2"> <div> <pre>{{vm.sampleJsonModify}}</pre> </div> </div> </div> </div> src/main/webapp/views/issue/issueDetail.html
@@ -87,7 +87,7 @@ <div class="support-ticket-content-w" ng-controller="issueDetailController"> <div class="support-ticket-content"> <span ng-if="vm.viewer.parentIssueVo != null" class="badge" ng-style="{'background-color' : '#353535', 'border-color' : vm.viewer.issueStatusVo.color, 'color' : '#FFFFFF' }"> <span>상위 이슈:{{vm.viewer.parentIssueVo.title}}</span> <span class="cursor" ng-click="fn.issueBack()">상위 이슈:{{vm.viewer.parentIssueVo.title}}</span> </span> <div class=""> @@ -97,7 +97,7 @@ <span class="ticket-header"> <div class="tasks-header-w"> <span class="tags"> <span class="tag">{{vm.viewer.projectVo.projectKey}}-{{vm.viewer.issueNumber}} / {{vm.viewer.projectVo.name}}</span> <span class="tag">{{vm.viewer.projectVo.projectKey}}-{{vm.viewer.issueNumber}} / {{vm.viewer.projectVo.name}} / <span>API : {{vm.viewer.isApi}}</span></span> </span> </div> </span> src/main/webapp/views/login/login.html
@@ -1,23 +1,24 @@ <div class="content-i"> <div class="content-box"> <div class="row mt-30"> <div class="row mt-30" style="margin-right: 32rem"> <div class="m-0"> <div class="flex"> <div class="loginbackdiv"> <div class="loginback"> <img src="/assets/images/logo-kisa-vertical.png"/> <div class="stardiv"> <!-- <div class="stars"></div> <div class="twinkling"></div> </div> <div class="bgdiv"> </div> <div class="login-circle"> <div class="circle1"></div> <div class="circle2"></div> <div class="circle3"></div>--> </div> </div> <!-- <div class="loginback">--> <!-- <img src="/assets/images/logo-kisa-vertical.png"/>--> <!-- <div class="stardiv">--> <!-- <div class="stars"></div>--> <!-- <div class="twinkling"></div>--> <!-- </div>--> <!-- <div class="bgdiv">--> <!-- </div>--> <!-- <div class="login-circle">--> <!-- <div class="circle1"></div>--> <!-- <div class="circle2"></div>--> <!-- <div class="circle3"></div>--> <!-- </div>--> <!-- </div>--> <!-- </div>--> </div> <div class="logincont"> <div class="auth-box-w"> @@ -131,7 +132,7 @@ </div> --> <div class="footer-s" > <small>CopyRight WISESTONE All rights reserved.</small> <small style="margin-left: 8.8rem">CopyRight WISESTONE All rights reserved.</small> </div> </div> </div>