OWL ITS + 탐지시스템(인터넷 진흥원)
이민희
2021-11-25 2473c035d63bc0f27b329eba7dccda33e5837d62
Merge branch 'master' of http://192.168.0.25:9001/r/owl-kisa
16개 파일 변경됨
406 ■■■■■ 파일 변경됨
src/main/java/kr/wisestone/owl/service/WorkflowDepartmentService.java 1 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java 8 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/service/impl/IssueStatusServiceImpl.java 10 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/service/impl/WorkflowDepartmentServiceImpl.java 9 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/service/impl/WorkflowServiceImpl.java 9 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/bower_components/ng-image-gallery/dist/ng-image-gallery.js 2 ●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/bower_components/ng-image-gallery/src/js/directive.js 2 ●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/custom_components/js-table/tableColumnGenerator.directive.js 128 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/i18n/ko/global.json 1 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/scripts/app/issue/issueAddDownTableConfig.controller.js 16 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/scripts/app/issue/issueAddRelationTableConfig.controller.js 2 ●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/scripts/app/issue/issueDetail.controller.js 87 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/scripts/app/issue/issueModifyStatus.controller.js 58 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/scripts/app/issueType/issueTypeAdd.controller.js 35 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/views/issue/issueDetail.html 20 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/views/issue/issueModifyStatus.html 18 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/service/WorkflowDepartmentService.java
@@ -21,6 +21,7 @@
    WorkflowDepartment getWorkflowDepartment(Long id);
    List<WorkflowDepartmentVo> find(WorkflowDepartmentCondition condition);
    List<WorkflowDepartmentVo> find(Long workflowId, Long issueStatusId);
    void modify(Workflow workflow, List<IssueStatusVo> issueStatusVos);
    void remove(Long workflowId);
}
src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java
@@ -1783,6 +1783,14 @@
            //  이슈 상태 변경
            this.modifyIssueStatus(issueForm);
        }
        // 담당 부서 수정
        if (issueForm.getDepartmentIds().size() > 0) {
            Issue issue = this.getIssue(issueForm.getId());
            Project project = this.projectService.getProject(issueForm.getProjectId());
            this.issueDepartmentService.modifyIssueDepartment(issue, project.getWorkspace(), issueForm.getDepartmentIds());
        }
    }
    //  이슈 Import 용 엑셀 템플릿 다운로드
src/main/java/kr/wisestone/owl/service/impl/IssueStatusServiceImpl.java
@@ -45,6 +45,9 @@
    private WorkflowTransitionService workflowTransitionService;
    @Autowired
    private WorkflowDepartmentService workflowDepartmentService;
    @Autowired
    private IssueTypeService issueTypeService;
    @Autowired
@@ -545,12 +548,18 @@
                if (count < 1) {
                    IssueStatusVo issueStatusVo = new IssueStatusVo(workflowTransitionVo.getTargetStatusId(), workflowTransitionVo.getTargetStatusName());
                    issueStatusVos.add(issueStatusVo);
                    List<WorkflowDepartmentVo> workflowDepartments = this.workflowDepartmentService.find(workflow.getId(), issueStatusVo.getId());
                    issueStatusVo.setWorkflowDepartmentVos(workflowDepartments);
                }
                else {
                    //  두번째 이슈부터 첫번째 이슈에서 이동 가능했던 상태 중 없는 대상을 찾는다.
                    for (IssueStatusVo issueStatusVo : issueStatusVos) {
                        if (issueStatusVo.getId().equals(workflowTransitionVo.getTargetStatusId())) {
                            tempIssueStatusVos.add(issueStatusVo);
                            List<WorkflowDepartmentVo> workflowDepartments = this.workflowDepartmentService.find(workflow.getId(), issueStatusVo.getId());
                            issueStatusVo.setWorkflowDepartmentVos(workflowDepartments);
                        }
                    }
                }
@@ -566,5 +575,4 @@
        resJsonData.put(Constants.RES_KEY_CONTENTS, issueStatusVos);
    }
}
src/main/java/kr/wisestone/owl/service/impl/WorkflowDepartmentServiceImpl.java
@@ -66,6 +66,15 @@
    }
    // 담당 부서정보를 조회한다.
    public List<WorkflowDepartmentVo> find(Long workflowId, Long issueStatusId) {
        WorkflowDepartmentCondition condition = new WorkflowDepartmentCondition();
        condition.setWorkflowId(workflowId);
        condition.setIssueStatusId(issueStatusId);
        return find(condition);
    }
    // 담당 부서정보를 조회한다.
    @Transactional(readOnly = true)
    @Override
    public List<WorkflowDepartmentVo> find(WorkflowDepartmentCondition condition) {
src/main/java/kr/wisestone/owl/service/impl/WorkflowServiceImpl.java
@@ -200,9 +200,7 @@
        for (WorkflowVo workflowVo : workflowVos) {
            Workflow workflow = this.getWorkflow(workflowVo.getId());
            WorkflowDepartmentCondition condition = new WorkflowDepartmentCondition();
            condition.setWorkflowId(workflow.getId());
            List<WorkflowDepartmentVo> workflowDepartmentVos = this.workflowDepartmentService.find(condition);
            List<WorkflowDepartmentVo> workflowDepartmentVos = this.workflowDepartmentService.find(workflow.getId(), null);
            if (workflowDepartmentVos != null && workflowDepartmentVos.size() > 0) {
                IssueStatusVo issueStatusVo = new IssueStatusVo();
                issueStatusVo.setWorkflowDepartmentVos(workflowDepartmentVos);
@@ -225,10 +223,7 @@
                case "01" : //  연관된 이슈 상태와 전이선 정보를 가져온다.
                    List<IssueStatusVo> issueStatusVos = this.issueStatusService.findByWorkflowId(workflowCondition.getId());
                    for (IssueStatusVo issueStatusVo : issueStatusVos) {
                        WorkflowDepartmentCondition condition = new WorkflowDepartmentCondition();
                        condition.setWorkflowId(workflowVo.getId());
                        condition.setIssueStatusId(issueStatusVo.getId());
                        List<WorkflowDepartmentVo> workflowDepartmentVos = this.workflowDepartmentService.find(condition);
                        List<WorkflowDepartmentVo> workflowDepartmentVos = this.workflowDepartmentService.find(workflowVo.getId(), issueStatusVo.getId());
                        issueStatusVo.setWorkflowDepartmentVos(workflowDepartmentVos);
                    }
                    workflowVo.setIssueStatusVos(issueStatusVos);
src/main/webapp/bower_components/ng-image-gallery/dist/ng-image-gallery.js
@@ -14,7 +14,7 @@
    .provider('ngImageGalleryOpts', function(){
        var defOpts = {
            thumbnails      :   true,
            thumbSize        :     80,
            thumbSize        :     60,
            inline          :   false,
            bubbles         :   true,
            bubbleSize        :     20,
src/main/webapp/bower_components/ng-image-gallery/src/js/directive.js
@@ -14,7 +14,7 @@
    .provider('ngImageGalleryOpts', function(){
        var defOpts = {
            thumbnails      :   true,
            thumbSize        :     80,
            thumbSize        :     60,
            inline          :   false,
            bubbles         :   true,
            bubbleSize        :     20,
src/main/webapp/custom_components/js-table/tableColumnGenerator.directive.js
@@ -219,54 +219,14 @@
                                            makeTag += "<span class=\"titlename cursor text-center\" ng-click=\"event.changeDetailView(data.issueRelation)\">" + scope.data.title + "</span></a>";
                                            break;
                                        // 하위 이슈 이동(제목)
                                        case "ISSUE_DOWN_MOVE" :
                                            makeTag += "<span class=\"titlename cursor\" ng-click=\"event.changeDetailView(data.id)\">" + scope.data.title + "</span></a>";
                                            break;
                                        // 연관이슈 구분
                                        case "ISSUE_RELATION_TYPE":
                                            makeTag += "<span>" + scope.data.relationIssueTypeName + "</span>";
                                            break;
                                            // 연관이슈 삭제
                                        // 연관이슈 삭제
                                        case "ISSUE_RELATION_DELETE":
                                            makeTag += '<img class="cursor" src="/assets/images/delete-icon.png" ng-click="event.removeRelationIssue(data.id)">';
                                            break;
                                        // 하위 이슈 삭제
                                        case "ISSUE_DOWN_DELETE":
                                            makeTag += '<img class="cursor" src="/assets/images/delete-icon.png" ng-click="event.removeDownIssue(data.id)">';
                                            break;
                                        //  이름을 클릭하면 수정 팝업 표시
                                        case "COMMON_MODIFY" :
                                            if (scope.data.modifyPermissionCheck) {
                                                makeTag += "<span class='titlename cursor table-word-break-all' ng-click='event.modify(data.id)'>" + scope.data.name.replace(/</gi, '&lt;') + "</span>";
                                            }
                                            else {
                                                makeTag += "<span class='titlename not-modify table-word-break-all'>" + scope.data.name + "</span>";
                                            }
                                            break;
                                        //  설정 버튼 클릭하면 수정 팝업 표시
                                        case "BUTTON_MODIFY" :
                                                makeTag += '<button class="btn btn-info" ng-if="data.modifyPermissionCheck" ng-click="event.modify(data.id)"><i class="os-icon os-icon-ui-46" uib-tooltip="프로젝트 설정"></i></button>';
                                            break;
                                        //  사용자 정의 필드 옵션 표시
                                        case "CUSTOM_FIELD_OPTION" :
                                            switch (scope.data.customFieldType) {
                                                case "INPUT" :
                                                    makeTag += "<span translate='common.stringField'>문자열 필드</span>";
                                                    break;
                                                case "MULTI_SELECT" :
                                                    makeTag += "<span translate='common.multipleSelectionField'>다중 선택 필드</span>";
                                                    break;
                                                case "SINGLE_SELECT" :
                                                    makeTag += "<span translate='common.singleSelectionField'>단일 선택 필드</span>";
                                                    break;
                                            }
                                            break;
                                        // 연관 이슈 우선순위
@@ -279,6 +239,7 @@
                                            makeTag += "<span class='badge' ng-style='{ \"background-color\" : \"" + scope.data.severityVo.color + "\"," + "\"border-color\"" + " : \"" + scope.data.severityVo.color + "\", \"color\": \"#FFFFFF\" }' translate='" + scope.data.severityVo.name + "'></span>";
                                            break;
                                        // 연관 이슈 등록자
                                        case "REL_REGISTER":
                                            scope.data.registerVos = [scope.data.issueRelation.registerVo];
                                            makeTag += '<div owl-profile-over class="" table-user-image="data" target="registerVos"></div>';
@@ -286,6 +247,7 @@
                                            break;
                                        // 연관 이슈 담당부서
                                        case "REL_ISSUE_DEPARTMENT" :
                                            makeTag += "<ul class='ul-not-comma'>";
                                            makeTag += "<div style='color: #000000'>";
@@ -306,14 +268,44 @@
                                            }
                                            break;
                                        // 연관 이슈 사용자 정의 필드
                                        case "REL_ISSUE_CUSTOM_FIELD_VALUE_VIEW" :
                                            var values = [];
                                            for (var count in scope.data.issueRelation.issueCustomFieldValueVos) {
                                                var issueCustomFieldValueVo = scope.data.issueRelation.issueCustomFieldValueVos[count];
                                                //  테이블 설정에서 dName 부분에 사용자 정의 필드 id 를 넣고 해당 값을 추출한다.
                                                if (tableConfig.columnHint.id == issueCustomFieldValueVo.customFieldVo.id) {
                                                    values.push(issueCustomFieldValueVo.useValue);
                                                }
                                            }
                                            angular.forEach(values, function (value) {
                                                makeTag += '<span class="table-word-break-all">' + value + '<span><br>';
                                            });
                                            break;
                                        // 하위 이슈 이동(제목)
                                        case "ISSUE_DOWN_MOVE" :
                                            makeTag += "<span class=\"titlename cursor\" ng-click=\"event.changeDetailView(data.id)\">" + scope.data.title + "</span></a>";
                                            break;
                                        // 하위 이슈 삭제
                                        case "ISSUE_DOWN_DELETE":
                                            makeTag += '<img class="cursor" src="/assets/images/delete-icon.png" ng-click="event.removeDownIssue(data.id)">';
                                            break;
                                        // 하위 이슈 우선 순위
                                        case "DOWN_COMMON_PRIORITY" :
                                            makeTag += "<span class='badge' ng-style='{ \"background-color\" : \"" + scope.data.priorityVo.color + "\"," + "\"border-color\"" + " : \"" + scope.data.priorityVo.color + "\", \"color\": \"#FFFFFF\" }' translate='" + scope.data.priorityVo.name + "'></span>";
                                            break;
                                        // 하위 이슈 중요도
                                        case "DOWN_COMMON_SEVERITY" :
                                            makeTag += "<span class='badge' ng-style='{ \"background-color\" : \"" + scope.data.severityVo.color + "\"," + "\"border-color\"" + " : \"" + scope.data.severityVo.color + "\", \"color\": \"#FFFFFF\" }' translate='" + scope.data.severityVo.name + "'></span>";
                                            break;
                                        // 하위 이슈 담당부서
                                        case "DOWN_ISSUE_DEPARTMENT" :
                                            makeTag += "<ul class='ul-not-comma'>";
                                            makeTag += "<div style='color: #000000'>";
@@ -324,11 +316,13 @@
                                            makeTag += "</ul>";
                                            break;
                                        // 하위 이슈 등록자
                                        case "DOWN_REGISTER":
                                            scope.data.registerVos = [scope.data.registerVo];
                                            makeTag += '<div owl-profile-over class="" table-user-image="data" target="registerVos"></div>';
                                            break;
                                        // 하위 이슈 기간
                                        case "DOWN_ISSUE_DUE_DATE" :
                                            if (!$rootScope.isDefined(scope.data.startDate) && !$rootScope.isDefined(scope.data.completeDate)) {
                                                makeTag += "<span translate='common.noDate'>기간 없음</span>";
@@ -338,14 +332,64 @@
                                            }
                                            break;
                                        // 하위 이슈 사용자 정의 필드
                                        case "DOWN_ISSUE_CUSTOM_FIELD_VALUE_VIEW" :
                                            var values = [];
                                            for (var count in scope.data.issueCustomFieldValueVos) {
                                                var issueCustomFieldValueVo = scope.data.issueCustomFieldValueVos[count];
                                                //  테이블 설정에서 dName 부분에 사용자 정의 필드 id 를 넣고 해당 값을 추출한다.
                                                if (tableConfig.columnHint.id == issueCustomFieldValueVo.customFieldVo.id) {
                                                    values.push(issueCustomFieldValueVo.useValue);
                                                }
                                            }
                                            angular.forEach(values, function (value) {
                                                makeTag += '<span class="table-word-break-all">' + value + '<span><br>';
                                            });
                                            break;
                                        //  이름을 클릭하면 수정 팝업 표시
                                        case "COMMON_MODIFY" :
                                            if (scope.data.modifyPermissionCheck) {
                                                makeTag += "<span class='titlename cursor table-word-break-all' ng-click='event.modify(data.id)'>" + scope.data.name.replace(/</gi, '&lt;') + "</span>";
                                            }
                                            else {
                                                makeTag += "<span class='titlename not-modify table-word-break-all'>" + scope.data.name + "</span>";
                                            }
                                            break;
                                        //  설정 버튼 클릭하면 수정 팝업 표시
                                        case "BUTTON_MODIFY" :
                                                makeTag += '<button class="btn btn-info" ng-if="data.modifyPermissionCheck" ng-click="event.modify(data.id)"><i class="os-icon os-icon-ui-46" uib-tooltip="프로젝트 설정"></i></button>';
                                            break;
                                        //  사용자 정의 필드 옵션 표시
                                        case "CUSTOM_FIELD_OPTION" :
                                            switch (scope.data.customFieldType) {
                                                case "INPUT" :
                                                    makeTag += "<span translate='common.stringField'>문자열 필드</span>";
                                                    break;
                                                case "MULTI_SELECT" :
                                                    makeTag += "<span translate='common.multipleSelectionField'>다중 선택 필드</span>";
                                                    break;
                                                case "SINGLE_SELECT" :
                                                    makeTag += "<span translate='common.singleSelectionField'>단일 선택 필드</span>";
                                                    break;
                                            }
                                            break;
                                        // 우선 순위
                                        case "COMMON_PRIORITY" :
                                            makeTag += "<span class='badge' ng-style='{ \"background-color\" : \"" + scope.data.priorityColor + "\"," + "\"border-color\"" + " : \"" + scope.data.priorityColor + "\", \"color\": \"#FFFFFF\" }' translate='" + scope.data.priorityName + "'></span>";
                                            break;
                                        // 중요도
                                        case "COMMON_SEVERITY" :
                                            makeTag += "<span class='badge' ng-style='{ \"background-color\" : \"" + scope.data.severityColor + "\"," + "\"border-color\"" + " : \"" + scope.data.severityColor + "\", \"color\": \"#FFFFFF\" }' translate='" + scope.data.severityName + "'></span>";
                                            break;
                                        // 담당 부서
                                        case "ISSUE_DEPARTMENT" :
                                            makeTag += "<ul class='ul-not-comma'>";
                                                makeTag += "<div style='color: #000000'>";
@@ -356,10 +400,12 @@
                                            makeTag += "</ul>";
                                            break;
                                        // 담당자
                                        case "ISSUE_USER" :
                                            makeTag += '<div owl-profile-over class="" table-user-image="data" target="userVos"></div>';
                                            break;
                                        // 등록자
                                        case "REGISTER" :
                                            scope.data.registerVos = [scope.data.registerVo];
                                            makeTag += '<div owl-profile-over class="" table-user-image="data" target="registerVos"></div>';
src/main/webapp/i18n/ko/global.json
@@ -251,6 +251,7 @@
        "applyTemplate": "템플릿 적용하기",
        "issueContentIsWrittenApplyTheTemplate": "이슈 내용이 작성되어 있습니다. 템플릿을 적용하겠습니까? 템플릿이 적용되면 이미 작성된 내용이 사라집니다.",
        "failedIssueStatusCheck": "이동 가능한 이슈 상태 조회 실패",
        "failedIssueStatusWorkflowDepartmentCheck": "이슈 상태 담당 부서 조회 실패",
        "failedToChangeMultipleIssueStatus": "다중 이슈 상태 변경 실패",
        "completedSavingIssueTable": "이슈 테이블 설정 저장 완료",
        "saveIssueTableSettingsInformation": "이슈 테이블 설정 정보가 저장되었습니다.",
src/main/webapp/scripts/app/issue/issueAddDownTableConfig.controller.js
@@ -128,25 +128,13 @@
                //  이슈 목록 테이블 설정 정보를 가져온다.
                function getDownIssueTableConfigs() {
                    var deferred = $q.defer();
                    var content = {
                        issueId : $rootScope.currentDetailIssueId,
                        delValue : $scope.vm.issueDownTableConfigs.splice(6,1),
                        issueTableConfigs : JSON.stringify($scope.vm.issueDownTableConfigs)
                    };
                    // angular.forEach($scope.vm.issueDownTableConfigs, function (delVaue) {
                    //     if ($scope.vm.issueDownTableConfigs.indexOf(delVaue.name) === "") {
                    //         $scope.vm.issueDownTableConfigs.splice(delVaue,1);
                    //     }
                    //
                    // })
                    // for (var i = 0; i < $scope.vm.issueDownTableConfigs; i++) {
                    //     if ($scope.vm.issueDownTableConfigs == "") {
                    //         $scope.vm.issueDownTableConfigs.splice(i,1);
                    //         i--;
                    //     }
                    // }
                    IssueTableConfig.downDetail($resourceProvider.getContent(content,
                        $resourceProvider.getPageContent(0, 1000))).then(function (result) {
                        if (result.data.message.status !== "success") {
@@ -161,7 +149,7 @@
                //  사용자 정의 필드를 조회한 후 표시할 이슈 테이블 컬럼을 준비한다.
                $scope.fn.getCustomFields().then(function (result) {
                    var count = 8;
                    var count = 6;
                    angular.forEach(result, function (customField) {
                        $scope.vm.issueDownTableConfigs.push({
                            name : customField.name,
src/main/webapp/scripts/app/issue/issueAddRelationTableConfig.controller.js
@@ -151,7 +151,7 @@
                //  사용자 정의 필드를 조회한 후 표시할 이슈 테이블 컬럼을 준비한다.
                $scope.fn.getCustomFields().then(function (result) {
                    var count = 8;
                    var count = 6;
                    angular.forEach(result, function (customField) {
                        $scope.vm.issueRelTableConfigs.push({
                            name : customField.name,
src/main/webapp/scripts/app/issue/issueDetail.controller.js
@@ -205,10 +205,10 @@
                }
                //  테이블의 연관 이슈 컬럼을 만들어준다.
                function setRelTableColumn(issueTableConfig) {
                function setRelTableColumn(Rel_issueTableConfig) {
                    //  연관 이슈 컬럼
                    switch(issueTableConfig.key) {
                    switch(Rel_issueTableConfig.key) {
                        // 연관 이슈 구분
                        case "RELATION_ISSUE_TYPE" :
@@ -233,7 +233,7 @@
                                .setHName("common.priority")
                                .setDName("priorityName")
                                .setDType("renderer")
                                .setHWidth("bold " + issueTableConfig.width)
                                .setHWidth("bold " + Rel_issueTableConfig.width)
                                .setDAlign("text-center")
                                .setDRenderer("REL_COMMON_PRIORITY"));
                            break;
@@ -242,7 +242,7 @@
                                .setHName("common.importance")
                                .setDName("severityName")
                                .setDType("renderer")
                                .setHWidth("bold " + issueTableConfig.width)
                                .setHWidth("bold " + Rel_issueTableConfig.width)
                                .setDAlign("text-center")
                                .setDRenderer("REL_COMMON_SEVERITY"));
                            break;
@@ -250,7 +250,7 @@
                            $scope.vm.relTableConfigs.push($tableProvider.config()
                                .setHName("common.assigneeTeam")
                                .setDType("renderer")
                                .setHWidth("bold " + issueTableConfig.width)
                                .setHWidth("bold " + Rel_issueTableConfig.width)
                                .setDAlign("text-center")
                                .setDRenderer("REL_ISSUE_DEPARTMENT"));
                            break;
@@ -259,7 +259,7 @@
                            $scope.vm.relTableConfigs.push($tableProvider.config()
                                .setHName("common.register")
                                .setDType("renderer")
                                .setHWidth("bold " + issueTableConfig.width)
                                .setHWidth("bold " + Rel_issueTableConfig.width)
                                .setDAlign("text-center")
                                .setDRenderer("REL_REGISTER"));
                            break;
@@ -267,14 +267,14 @@
                            $scope.vm.relTableConfigs.push($tableProvider.config()
                                .setHName("common.period")
                                .setDType("renderer")
                                .setHWidth("bold " + issueTableConfig.width)
                                .setHWidth("bold " + Rel_issueTableConfig.width)
                                .setDAlign("text-center")
                                .setDRenderer("REL_ISSUE_DUE_DATE"));
                            break;
                        case "MODIFY_DATE" : // 연관 이슈  최근 변경일
                            $scope.vm.relTableConfigs.push($tableProvider.config()
                                .setHName("common.lastChangeDate")
                                .setHWidth("bold " + issueTableConfig.width)
                                .setHWidth("bold " + Rel_issueTableConfig.width)
                                .setDAlign("text-center")
                                .setDName("modifyDate"));
                            break;
@@ -289,19 +289,19 @@
                    }
                    //  사용자 정의 필드 컬럼
                    if (issueTableConfig.key.indexOf("CUSTOM_FIELD_") !== -1) {
                    if (Rel_issueTableConfig.key.indexOf("CUSTOM_FIELD_") !== -1) {
                        //  만약 이슈 테이블 컬럼명이 표시되지 않으면 이쪽이 문제
                        for (var count in $scope.vm.customFields) {
                            var customField = $scope.vm.customFields[count];
                            if (customField.id === Number(issueTableConfig.key.substring(13))) {
                                $scope.vm.tableConfigs.push($tableProvider.config()
                            if (customField.id === Number(Rel_issueTableConfig.key.substring(13))) {
                                $scope.vm.relTableConfigs.push($tableProvider.config()
                                    .setHName(customField.name)
                                    .setDType("renderer")
                                    .setHWidth("bold " + issueTableConfig.width)
                                    .setHWidth("bold " + Rel_issueTableConfig.width)
                                    .setDAlign("text-center")
                                    .setColumnHint(customField)
                                    .setDRenderer("ISSUE_CUSTOM_FIELD_VALUE_VIEW"));
                                    .setDRenderer("REL_ISSUE_CUSTOM_FIELD_VALUE_VIEW"));
                                break;
                            }
                        }
@@ -310,17 +310,17 @@
                //  테이블의 하위 이슈 컬럼을 만들어준다.
                function setDownTableColumn(issueTableConfig) {
                function setDownTableColumn(Down_issueTableConfig) {
                    // if (issueTableConfig == null) return;
                    //  하위 이슈 컬럼
                    switch(issueTableConfig.key) {
                    switch(Down_issueTableConfig.key) {
                        //  하위 이슈 제목
                        case "DOWN_ISSUE_TITLE" :
                            $scope.vm.downTableConfigs.push($tableProvider.config()
                                .setHName("issue.downIssueTitle")
                                .setDType("renderer")
                                .setHWidth("bold " + issueTableConfig.width)
                                .setHWidth("bold " + Down_issueTableConfig.width)
                                .setDAlign("text-center")
                                .setDRenderer("ISSUE_DOWN_MOVE"));
                            break;
@@ -329,7 +329,7 @@
                                .setHName("common.priority")
                                .setDName("priorityName")
                                .setDType("renderer")
                                .setHWidth("bold " + issueTableConfig.width)
                                .setHWidth("bold " + Down_issueTableConfig.width)
                                .setDAlign("text-center")
                                .setDRenderer("DOWN_COMMON_PRIORITY"));
                            break;
@@ -338,7 +338,7 @@
                                .setHName("common.importance")
                                .setDName("severityName")
                                .setDType("renderer")
                                .setHWidth("bold " + issueTableConfig.width)
                                .setHWidth("bold " + Down_issueTableConfig.width)
                                .setDAlign("text-center")
                                .setDRenderer("DOWN_COMMON_SEVERITY"));
                            break;
@@ -346,7 +346,7 @@
                            $scope.vm.downTableConfigs.push($tableProvider.config()
                                .setHName("common.assigneeTeam")
                                .setDType("renderer")
                                .setHWidth("bold " + issueTableConfig.width)
                                .setHWidth("bold " + Down_issueTableConfig.width)
                                .setDAlign("text-center")
                                .setDRenderer("DOWN_ISSUE_DEPARTMENT"));
                            break;
@@ -354,7 +354,7 @@
                            $scope.vm.downTableConfigs.push($tableProvider.config()
                                .setHName("common.register")
                                .setDType("renderer")
                                .setHWidth("bold " + issueTableConfig.width)
                                .setHWidth("bold " + Down_issueTableConfig.width)
                                .setDAlign("text-center")
                                .setDRenderer("DOWN_REGISTER"));
                            break;
@@ -362,33 +362,33 @@
                            $scope.vm.downTableConfigs.push($tableProvider.config()
                                .setHName("common.period")
                                .setDType("renderer")
                                .setHWidth("bold " + issueTableConfig.width)
                                .setHWidth("bold " + Down_issueTableConfig.width)
                                .setDAlign("text-center")
                                .setDRenderer("DOWN_ISSUE_DUE_DATE"));
                            break;
                        case "MODIFY_DATE" : //  최근 변경일
                            $scope.vm.downTableConfigs.push($tableProvider.config()
                                .setHName("common.lastChangeDate")
                                .setHWidth("bold " + issueTableConfig.width)
                                .setHWidth("bold " + Down_issueTableConfig.width)
                                .setDAlign("text-center")
                                .setDName("modifyDate"));
                            break;
                    }
                    //  사용자 정의 필드 컬럼
                    if (issueTableConfig.key.indexOf("CUSTOM_FIELD_") === -1) {
                    if (Down_issueTableConfig.key.indexOf("CUSTOM_FIELD_") !== -1) {
                        //  만약 이슈 테이블 컬럼명이 표시되지 않으면 이쪽이 문제
                        for (var count in $scope.vm.customFields) {
                            var customField = $scope.vm.customFields[count];
                            if (customField.id === Number(issueTableConfig.key.substring(13))) {
                            if (customField.id === Number(Down_issueTableConfig.key.substring(13))) {
                                $scope.vm.downTableConfigs.push($tableProvider.config()
                                    .setHName(customField.name)
                                    .setDType("renderer")
                                    .setHWidth("bold " + issueTableConfig.width)
                                    .setHWidth("bold " + Down_issueTableConfig.width)
                                    .setDAlign("text-center")
                                    .setColumnHint(customField)
                                    .setDRenderer("ISSUE_CUSTOM_FIELD_VALUE_VIEW"));
                                    .setDRenderer("DOWN_ISSUE_CUSTOM_FIELD_VALUE_VIEW"));
                                break;
                            }
                        }
@@ -422,11 +422,11 @@
                        .setHSort(false)
                        .setDAlign("text-center"))
                    angular.forEach($scope.vm.relTableConfigs, function (issueTableConfig) {
                    angular.forEach($scope.vm.relTableConfigs, function (Rel_issueTableConfig) {
                        //  표시 대상인 컬럼만 화면에 그려준다.
                        if (issueTableConfig.display) {
                        if (Rel_issueTableConfig.display) {
                            //  테이블의 컬럼을 만들어준다.
                            $scope.fn.setRelTableColumn(issueTableConfig);
                            $scope.fn.setRelTableColumn(Rel_issueTableConfig);
                        }
                    });
                }
@@ -450,11 +450,11 @@
                        .setHSort(false)
                        .setDAlign("text-center"))
                    angular.forEach($scope.vm.downTableConfigs, function (issueTableConfig) {
                    angular.forEach($scope.vm.downTableConfigs, function (Down_issueTableConfig) {
                        //  표시 대상인 컬럼만 화면에 그려준다.
                        if (issueTableConfig.display) {
                        if (Down_issueTableConfig.display) {
                            //  테이블의 컬럼을 만들어준다.
                            $scope.fn.setDownTableColumn(issueTableConfig);
                            $scope.fn.setDownTableColumn(Down_issueTableConfig);
                        }
                    });
                }
@@ -497,11 +497,11 @@
                                    .setHWidth("width-60-p bold")
                                    .setHSort(false)
                                    .setDRenderer("ISSUE_RELATION_MOVE"))
                                angular.forEach($scope.vm.issueRelTableConfigs, function (issueTableConfig) {
                                angular.forEach($scope.vm.issueRelTableConfigs, function (Rel_issueTableConfig) {
                                    //  표시 대상인 컬럼만 화면에 그려준다.
                                    if (issueTableConfig.display) {
                                    if (Rel_issueTableConfig.display) {
                                        //  테이블의 컬럼을 만들어준다.
                                        $scope.fn.setRelTableColumn(issueTableConfig);
                                        $scope.fn.setRelTableColumn(Rel_issueTableConfig);
                                    }
                                });
@@ -552,11 +552,11 @@
                                    .setHWidth("width-60-p bold")
                                    .setHSort(false)
                                    .setDRenderer("ISSUE_DOWN_MOVE"))
                                angular.forEach($scope.vm.issueDownTableConfigs, function (issueTableConfig) {
                                angular.forEach($scope.vm.issueDownTableConfigs, function (Down_issueTableConfig) {
                                    //  표시 대상인 컬럼만 화면에 그려준다.
                                    if (issueTableConfig.display) {
                                    if (Down_issueTableConfig.display) {
                                        //  테이블의 컬럼을 만들어준다.
                                        $scope.fn.setDownTableColumn(issueTableConfig);
                                        $scope.fn.setDownTableColumn(Down_issueTableConfig);
                                    }
                                });
                                $scope.vm.downTableConfigs.push($tableProvider.config()
@@ -668,7 +668,8 @@
                        resolve : {
                            parameter : function () {
                                return {
                                    issueIds : [$scope.vm.viewer.id]
                                    issueIds : [$scope.vm.viewer.id],
                                    projectId : $scope.vm.viewer.projectVo.id
                                };
                            }
                        }
@@ -793,7 +794,6 @@
                                //  이슈에서 사용자가 선택한 사용자 정의 필드 값을 입력 폼에 셋팅한다.
                                $scope.fn.setUseValueByIssueTypeCustomFields(result.data.data.issueCustomFieldValueVos);
                                // 연관 일감
                                $scope.vm.issueName = "";
                                $scope.vm.form.issues = [];
@@ -811,13 +811,6 @@
                                angular.forEach(result.data.data.issueDownVos, function (issueDownVo){
                                    $scope.vm.form.issuesDown.push(issueDownVo.issue);
                                });
                                // // wyu
                                // angular.forEach(result.data.data.issueRelationVos, function (issueRelationColum){
                                //     issueRelationColum.issueRelation = $scope.vm.issueRelation;
                                //     $scope.vm.form.issues.push(issueRelationColum.issueRelation);
                                // });
                                $scope.vm.viewer.issueRelationVos = result.data.data.issueRelationVos;
                                $scope.vm.viewer.issueDownVos = result.data.data.issueDownVos;
src/main/webapp/scripts/app/issue/issueModifyStatus.controller.js
@@ -8,25 +8,60 @@
    ],
    function (app) {
        app.controller('issueModifyStatusController', ['$scope', '$rootScope', '$log', '$resourceProvider', '$uibModalInstance', 'SweetAlert', '$timeout', '$stateParams', 'parameter',
            'Issue', 'IssueStatus', '$filter',
            function ($scope, $rootScope, $log, $resourceProvider, $uibModalInstance, SweetAlert, $timeout, $stateParams, parameter, Issue, IssueStatus, $filter) {
            'Issue', 'IssueStatus', '$filter', '$injector', '$controller',
            function ($scope, $rootScope, $log, $resourceProvider, $uibModalInstance, SweetAlert, $timeout, $stateParams, parameter, Issue, IssueStatus, $filter, $injector, $controller) {
                //  함수 모음
                $scope.fn = {
                    cancel: cancel,    //  팝업 창 닫기
                    formSubmit: formSubmit,    //  폼 전송
                    formCheck: formCheck,  //  폼 체크
                    findNextMultiIssueStatus: findNextMultiIssueStatus  //  이동 가능한 이슈 상태를 찾는다.
                    findNextMultiIssueStatus: findNextMultiIssueStatus,  //  이동 가능한 이슈 상태를 찾는다.
                    removeDepartment : removeDepartment,     // 담당부서 삭제
                };
                //  변수 모음
                $scope.vm = {
                    issueStatusList: [],   //  변경 가능한 상태 목록
                    form: {
                        issueStatusId: "",
                        departments: [],    // 담당 부서 선택 목록
                        issueStatusId: undefined,
                        comment: ""
                    }
                    },
                    departmentName : ""
                };
                angular.extend(this, $controller('autoCompleteController', {$scope : $scope, $injector : $injector}));
                // 담당부서 삭제
                function removeDepartment(index) {
                    $scope.vm.form.departments.splice(index, 1);
                }
                $scope.$watch("vm.form.issueStatusId", function (newValue) {
                    // 이슈 상태별 담당부서 표시
                    let selectIssueStatusId = $scope.vm.form.issueStatusId;
                    let issueStatusList = $scope.vm.issueStatusList;
                    $scope.vm.form.departments = [];
                    if (issueStatusList != null && $scope.vm.issueStatusList.length > 0 && selectIssueStatusId !== "") {
                        for (let i = 0; i < issueStatusList.length; i++) {
                            if (issueStatusList[i].id.toString() === selectIssueStatusId) {
                                let workflowDepartments = issueStatusList[i].workflowDepartmentVos;
                                workflowDepartments.forEach(function (workflowDepartment) {
                                    $scope.vm.form.departments.push(workflowDepartment.departmentVo);
                                });
                                break;
                            }
                        }
                        $scope.vm.issueStatusList.forEach(function (issueStatus) {
                            if (issueStatus.id === $scope.vm.form.issueStatusId) {
                            }
                        });
                    }
                });
                //  이동 가능한 이슈 상태를 찾는다.
                function findNextMultiIssueStatus() {
@@ -38,6 +73,7 @@
                        if (result.data.message.status === "success") {
                            $scope.vm.issueStatusList = result.data.data;
                        } else {
                            SweetAlert.swal($filter("translate")("issue.failedIssueStatusCheck"), result.data.message.message, "error"); // 이동 가능한 이슈 상태 조회 실패
                        }
@@ -62,7 +98,17 @@
                    var content = {
                        ids: parameter.issueIds,
                        issueStatusId: $scope.vm.form.issueStatusId,
                        comment: $scope.vm.form.comment
                        comment: $scope.vm.form.comment,
                        projectId : parameter.projectId,
                        departmentIds : (function () {
                            var departmentIds = [];
                            angular.forEach($scope.vm.form.departments, function (department) {
                                departmentIds.push(department.id);
                            });
                            return departmentIds;
                        })(),
                    };
                    Issue.modifyMultiIssueStatus($resourceProvider.getContent(content,
src/main/webapp/scripts/app/issueType/issueTypeAdd.controller.js
@@ -25,8 +25,14 @@
                        workflows : [],    //  워크플로우
                        projects : [],      // 프로젝트
                        description : "",  //  설명
                        color : "#febd35" //  색상
                        color : "#febd35", //  색상
                        companyFields : [], // 업체정보
                        ispFields : [], // ISP 정보
                        hostingFields : [] // 호스팅정보
                    },
                    companyName : "",
                    ispId : "",
                    hostingId : "",
                    projectName : "",
                    workflowName : "",
                    autoCompletePage : {
@@ -140,6 +146,33 @@
                            return projectId;
                        })(),
                        companyId : (function () {
                            var companyId = "";
                            if ($scope.vm.form.companyFields.length > 0) {
                                companyId = $scope.vm.form.companyFields[0].id;
                            }
                            return companyId;
                        }),
                        ispId : (function () {
                            var ispId = "";
                            if ($scope.vm.form.ispFields.length > 0) {
                                ispId = $scope.vm.form.ispFields[0].id;
                            }
                            return ispId;
                        }),
                        hostingId : (function () {
                            var hostingId = "";
                            if ($scope.vm.form.hostingFields.length > 0) {
                                hostingId = $scope.vm.form.hostingFields[0].id;
                            }
                            return hostingId;
                        }),
                        name : $rootScope.preventXss($scope.vm.form.name),
                        description : $rootScope.preventXss($scope.vm.form.description),
                        color : $scope.vm.form.color
src/main/webapp/views/issue/issueDetail.html
@@ -219,6 +219,12 @@
                            </div>
                        </div>
                    </div>
                    <div class="pdt0" style="position: relative; bottom: 1rem">
                        <issue-detail-image-preview images="vm.images"></issue-detail-image-preview>
                    </div>
                    <div ng-show="vm.images.length < 1" class="detail-not-elements width-100">
                        <span></span>
                    </div>
                </div>
                           <!-- <div class="">
@@ -534,20 +540,6 @@
                    <div ng-show="vm.viewer.attachedFileVos.length < 1" class="detail-not-elements">
                        <span translate="common.noAttachedFile">첨부된 파일이 없습니다.</span>
                    </div>
                </div>
                <div class="row">
                    <div class="col-sm-12">
                        <h6 class="todo-content-subheader mt-20"><span translate="issue.previewImage">이미지 미리 보기</span>
                        </h6>
                        <div class="pdt10">
                            <issue-detail-image-preview images="vm.images"></issue-detail-image-preview>
                        </div>
                    </div>
                    <div ng-show="vm.images.length < 1" class="detail-not-elements width-100">
                        <span translate="common.noImage">첨부된 이미지가 없습니다.</span>
                    </div>
                </div>
                <!--    활동 내역   -->
src/main/webapp/views/issue/issueModifyStatus.html
@@ -30,6 +30,24 @@
                </div>
            </div>
            <div class="form-group mgb5" ng-if="vm.form.issueStatusId !== undefined">
                <label class="issue-label"> <span translate="common.assigneeTeam">담당부서</span> </label>
                <js-autocomplete-multi data-input-name="departments"
                                       selected-model="vm.form.departments"
                                       search="vm.departmentName"
                                       source="fn.getUserDepartmentList(vm.departmentName, vm.form.departments)"
                                       input-disabled="false"
                                       translation-texts="{ count : 'common.userNum', empty : 'common.emptyUser' }"
                                       extra-settings="{ displayProp : 'byName' , idProp : 'id', imageable : false, maxlength : 100, autoResize : true }"></js-autocomplete-multi>
                <div class="select3-selection__choicediv mt-10">
                            <span class="select3-selection__choice" ng-repeat="department in vm.form.departments">
                                <span>{{department.byName}}</span> <!--사용자가 속해 있는 부서 이름 출력-->
                                <span class="select3-selection__choice__remove" ng-click="fn.removeDepartment($index)">×</span>
                            </span>
                </div>
            </div>
            <div class="form-group">
                <label for="issueMultiStatusModifyForm2"><span translate="common.changeReason">변경 사유</span> </label>
                <input class="form-control input-sm"