Merge branch 'master' of http://192.168.0.25:9001/r/owl-kisa
| | |
| | | public static final String API_PARAMETER_ERROR = "API_PARAMETER_ERROR"; // api 파라미터 오류 |
| | | public static final String API_USER_ERROR = "API_USER_ERROR"; // api 사용자 오류 |
| | | public static final String API_OVERLAP_ERROR = "API_OVERLAP_ERROR"; // API 중복된 상위 이슈가 여러개일 경우 |
| | | public static final String API_OVERLAP_SETTING_NOT_EXIST = "API_OVERLAP_SETTING_NOT_EXIST"; // API 중복된 설정이 안되어 있을 경우 |
| | | public static final String API_ISSUE_NOT_EXIST = "API_ISSUE_NOT_EXIST"; // 수정할 이슈를 찾을수 없습니다. |
| | | public static final String API_COMPLETE_ISSUE_STATUS_NOT_EXIST = "API_COMPLETE_ISSUE_STATUS_NOT_EXIST"; // 자동 종료 처리할 상태가 설정되지 않았습니다. |
| | | } |
| | |
| | | private String url; |
| | | private String email; |
| | | private String memo; |
| | | private Long ispId; |
| | | private Long hostingId; |
| | | |
| | | public CompanyField() {} |
| | | |
| | |
| | | public void setUrl(String url) { |
| | | this.url = url; |
| | | } |
| | | |
| | | public Long getIspId() { |
| | | return ispId; |
| | | } |
| | | |
| | | public void setIspId(Long ispId) { |
| | | this.ispId = ispId; |
| | | } |
| | | |
| | | public Long getHostingId() { |
| | | return hostingId; |
| | | } |
| | | |
| | | public void setHostingId(Long hostingId) { |
| | | this.hostingId = hostingId; |
| | | } |
| | | } |
| | |
| | | |
| | | List<Issue> modifyIssue(IssueApiForm issueApiForm, List<MultipartFile> files); |
| | | |
| | | List<IssueVo> findIssue(IssueApiForm issueApiform); |
| | | List<Issue> findIssue(IssueApiForm issueApiform); |
| | | |
| | | |
| | | List<IssueVo> findIssue(Map<String, Object> resJsonData, |
| | | IssueCondition condition, Pageable pageable); |
| | |
| | | import kr.wisestone.owl.domain.IspField; |
| | | import kr.wisestone.owl.repository.HostingFieldRepository; |
| | | import kr.wisestone.owl.repository.IspFieldRepository; |
| | | import kr.wisestone.owl.service.UserService; |
| | | import kr.wisestone.owl.service.*; |
| | | import kr.wisestone.owl.web.condition.CompanyFieldCondition; |
| | | import kr.wisestone.owl.web.form.CompanyFieldForm; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.ui.Model; |
| | | import com.google.common.collect.Lists; |
| | | import kr.wisestone.owl.common.ExcelConditionCheck; |
| | |
| | | import kr.wisestone.owl.exception.OwlRuntimeException; |
| | | import kr.wisestone.owl.mapper.CompanyFieldMapper; |
| | | import kr.wisestone.owl.repository.CompanyFieldRepository; |
| | | import kr.wisestone.owl.service.CompanyFieldService; |
| | | import kr.wisestone.owl.service.WorkspaceService; |
| | | import kr.wisestone.owl.util.ConvertUtil; |
| | | import kr.wisestone.owl.vo.*; |
| | | import kr.wisestone.owl.web.view.ExcelView; |
| | |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Optional; |
| | | |
| | | @Service |
| | | public class CompanyFieldServiceImpl extends AbstractServiceImpl<CompanyField, Long, JpaRepository<CompanyField, Long>> implements CompanyFieldService { |
| | |
| | | |
| | | @Autowired |
| | | private HostingFieldRepository hostingFieldRepository; |
| | | |
| | | @Autowired |
| | | private IspFieldService ispFieldService; |
| | | |
| | | @Autowired |
| | | private HostingFieldService hostingFieldService; |
| | | |
| | | @Autowired |
| | | private UserService userService; |
| | |
| | | |
| | | // 업체 상세 조회한다. |
| | | @Override |
| | | @Transactional |
| | | public void detailCompany(Map<String, Object> resJsonData, CompanyFieldCondition companyFieldCondition) { |
| | | CompanyFieldVo companyFieldVo = new CompanyFieldVo(); |
| | | IspFieldVo ispFieldVo = new IspFieldVo(); |
| | | HostingFieldVo hostingFieldVo = new HostingFieldVo(); |
| | | |
| | | IspField ispField = new IspField(); |
| | | HostingField hostingField = new HostingField(); |
| | | |
| | | Long companyId = companyFieldCondition.getId(); |
| | | if (companyId != null) { |
| | | CompanyField companyField = this.getCompany(companyId); |
| | | if(companyField.getIspId() != null){ |
| | | ispField = this.ispFieldRepository.getOne(companyField.getIspId()); |
| | | } |
| | | if(companyField.getHostingId() != null){ |
| | | hostingField = this.hostingFieldRepository.getOne(companyField.getHostingId()); |
| | | } |
| | | companyFieldVo = ConvertUtil.copyProperties(companyField, CompanyFieldVo.class); |
| | | ispFieldVo = ConvertUtil.copyProperties(ispField, IspFieldVo.class); |
| | | hostingFieldVo = ConvertUtil.copyProperties(hostingField, HostingFieldVo.class); |
| | | |
| | | companyFieldVo.setIspFieldVo(ispFieldVo); |
| | | companyFieldVo.setHostingFieldVo(hostingFieldVo); |
| | | } |
| | | resJsonData.put(Constants.REQ_KEY_CONTENT, companyFieldVo); |
| | | } |
| | |
| | | // 검색 결과를 CompanyFieldVo 로 변환한다. |
| | | private List<CompanyFieldVo> convertCompanyVoToMap(List<Map<String, Object>> results, Long totalCompanyCount, Pageable pageable, Map<String, Object> resJsonData) { |
| | | List<CompanyFieldVo> companyFieldVos = Lists.newArrayList(); |
| | | List<IspFieldVo> ispFieldVos = Lists.newArrayList(); |
| | | List<HostingFieldVo> hostingFieldVos = Lists.newArrayList(); |
| | | |
| | | for (Map<String, Object> result : results) { |
| | | CompanyFieldVo companyFieldVo = ConvertUtil.convertMapToClass(result, CompanyFieldVo.class); |
| | | |
| | | String url = companyFieldVo.getUrl(); |
| | | |
| | | IspField ispField = this.ispFieldRepository.findByUrl(url); |
| | | if(ispField != null){ |
| | | IspFieldVo ispFieldVo = ConvertUtil.copyProperties(ispField, IspFieldVo.class); |
| | | ispFieldVos.add(ispFieldVo); |
| | | if(companyFieldVo.getIspId() != null && companyFieldVo.getIspId() != -1){ |
| | | //IspField ispField = this.ispFieldRepository.getOne(companyFieldVo.getIspId()); |
| | | IspField ispField = this.ispFieldService.getIsp(companyFieldVo.getIspId()); |
| | | if(ispField != null){ |
| | | IspFieldVo ispFieldVo = ConvertUtil.copyProperties(ispField, IspFieldVo.class); |
| | | companyFieldVo.setIspFieldVo(ispFieldVo); |
| | | } |
| | | } |
| | | companyFieldVo.setIspFieldVos(ispFieldVos); |
| | | |
| | | HostingField hostingField = this.hostingFieldRepository.findByUrl(url); |
| | | if(hostingField != null){ |
| | | HostingFieldVo hostingFieldVo = ConvertUtil.copyProperties(hostingField, HostingFieldVo.class); |
| | | hostingFieldVos.add(hostingFieldVo); |
| | | if(companyFieldVo.getHostingId() != null && companyFieldVo.getIspId() != -1){ |
| | | //HostingField hostingField = this.hostingFieldRepository.getOne(companyFieldVo.getHostingId()); |
| | | HostingField hostingField = this.hostingFieldService.getHosting(companyFieldVo.getHostingId()); |
| | | if(hostingField != null){ |
| | | HostingFieldVo hostingFieldVo = ConvertUtil.copyProperties(hostingField, HostingFieldVo.class); |
| | | companyFieldVo.setHostingFieldVo(hostingFieldVo); |
| | | } |
| | | } |
| | | companyFieldVo.setHostingFieldVos(hostingFieldVos); |
| | | |
| | | companyFieldVos.add(companyFieldVo); |
| | | } |
| | | |
| | |
| | | // Hosting 추가 |
| | | @Override |
| | | public HostingField add(HostingFieldForm HostingFieldForm) { |
| | | if(HostingFieldForm.getUrl() != null){ |
| | | // url 유효성 체크 |
| | | this.verifyUrl(HostingFieldForm.getUrl(), null); |
| | | } |
| | | |
| | | HostingField HostingField = ConvertUtil.copyProperties(HostingFieldForm, HostingField.class); |
| | | hostingFieldRepository.saveAndFlush(HostingField); |
| | | return HostingField; |
| | | } |
| | | |
| | | // url 유효성 체크 |
| | | private void verifyUrl(String url, Long id) { |
| | | HostingField hostingField; |
| | | |
| | | if(id == null){ |
| | | hostingField = this.hostingFieldRepository.findByUrl(url); |
| | | } else { |
| | | hostingField = this.hostingFieldRepository.findByUrlAndIdNot(url,id); |
| | | } |
| | | |
| | | if (hostingField != null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.COMPANYFIELD_USED_URL)); |
| | | } |
| | | } |
| | | |
| | | // Hosting 목록을 가져온다. |
| | |
| | | // Hosting 정로를 수정한다. |
| | | @Override |
| | | public void modify(HostingFieldForm HostingFieldForm) { |
| | | // url 유효성 체크 |
| | | if(HostingFieldForm.getUrl() != null){ |
| | | this.verifyUrl(HostingFieldForm.getUrl(), HostingFieldForm.getId()); |
| | | } |
| | | |
| | | HostingField HostingField = ConvertUtil.copyProperties(HostingFieldForm, HostingField.class); |
| | | hostingFieldRepository.saveAndFlush(HostingField); |
| | | } |
| | | |
| | | |
| | | // Hosting를 삭제한다. |
| | | @Override |
| | |
| | | // Isp 추가 |
| | | @Override |
| | | public IspField add(IspFieldForm IspFieldForm) { |
| | | // url 유효성 체크 |
| | | if(IspFieldForm.getUrl() != null){ |
| | | this.verifyUrl(IspFieldForm.getUrl(), null); |
| | | } |
| | | |
| | | IspField IspField = ConvertUtil.copyProperties(IspFieldForm, IspField.class); |
| | | ispFieldRepository.saveAndFlush(IspField); |
| | | return IspField; |
| | |
| | | return this.convertIspVoToMap(results, totalIspCount, pageable, resJsonData); |
| | | } |
| | | |
| | | // url 유효성 체크 |
| | | private void verifyUrl(String url, Long id) { |
| | | IspField ispField; |
| | | |
| | | if(id == null){ |
| | | ispField = this.ispFieldRepository.findByUrl(url); |
| | | } else { |
| | | ispField = this.ispFieldRepository.findByUrlAndIdNot(url,id); |
| | | } |
| | | |
| | | if (ispField != null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.COMPANYFIELD_USED_URL)); |
| | | } |
| | | } |
| | | |
| | | |
| | | // Isp 상세 조회한다. |
| | | @Override |
| | | public void detail(Map<String, Object> resJsonData, IspFieldCondition ispFieldCondition) { |
| | |
| | | @Override |
| | | public void modify(IspFieldForm IspFieldForm) { |
| | | if(IspFieldForm.getUrl() != null){ |
| | | // url 유효성 체크 |
| | | this.verifyUrl(IspFieldForm.getUrl(), IspFieldForm.getId()); |
| | | } |
| | | |
| | | IspField IspField = ConvertUtil.copyProperties(IspFieldForm, IspField.class); |
| | |
| | | // 연관 일감 가져오기 |
| | | @Override |
| | | public List<IssueVo> findRelationIssue(Map<String, Object> resJsonData, IssueRelationCondition condition, Pageable pageable) { |
| | | List<IssueRelation> issueRelations = issueRelationRepository.findAllByIssueId(condition.getIssueId()); |
| | | List<IssueVo> issueVos = new ArrayList<>(); |
| | | List<IssueVo> issueVos = findRelationIssue(condition.getIssueId()); |
| | | |
| | | if (issueRelations != null) { |
| | | for (IssueRelation issueRelation : issueRelations) { |
| | | issueVos.add(ConvertUtil.copyProperties(issueRelation.getRelationIssue(), IssueVo.class)); |
| | | } |
| | | |
| | | int totalCount = issueVos.size(); |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, issueVos); |
| | | resJsonData.put(Constants.REQ_KEY_PAGE_VO, new ResPage(pageable.getPageNumber(), pageable.getPageSize(), |
| | | 1, totalCount)); |
| | | } |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, issueVos); |
| | | resJsonData.put(Constants.REQ_KEY_PAGE_VO, new ResPage(pageable.getPageNumber(), pageable.getPageSize(), |
| | | 1, issueVos.size())); |
| | | |
| | | return issueVos; |
| | | } |
| | | |
| | | |
| | | // 연관 일감 가져오기 |
| | | @Override |
| | | public List<IssueVo> findRelationIssue(Long issueId) { |
| | |
| | | |
| | | // 상위일감에 사용할 중복값 설정 |
| | | List<CustomFieldApiOverlap> customFieldApiOverlaps = this.customFieldApiOverlapService.find(user.getId(), issueApiForm.getIssueTypeId()); |
| | | if (customFieldApiOverlaps == null || customFieldApiOverlaps.size() == 0){ |
| | | throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.API_OVERLAP_SETTING_NOT_EXIST)); |
| | | } |
| | | for(int i=0; i < customFieldApiOverlaps.size() ; i++ ){ |
| | | CustomFieldApiOverlap customFieldApiOverlap = customFieldApiOverlaps.get(i); |
| | | issueApiForm.addUseIssueCustomFieldId(customFieldApiOverlap.getCustomField().getId()); |
| | | } |
| | | |
| | | List<IssueVo> issueVos = this.findIssue(issueApiForm, customFieldApiOverlaps, user.getId()); |
| | | int size = issueVos.size(); |
| | | // 중복된 이슈검색 |
| | | List<Issue> issues = this.findIssue(issueApiForm, customFieldApiOverlaps, user.getId()); |
| | | int size = issues.size(); |
| | | if (size > 0) { |
| | | issueForm.setParentIssueId(issueVos.get(0).getId()); |
| | | Issue targetIssue = issues.get(0); |
| | | if (targetIssue.getParentIssue() != null) { |
| | | issueForm.setParentIssueId(targetIssue.getParentIssue().getId()); |
| | | } else { |
| | | issueForm.setParentIssueId(targetIssue.getId()); |
| | | } |
| | | } |
| | | |
| | | issueForm.setIsApi(Issue.IS_API_YES); |
| | |
| | | } |
| | | |
| | | // 중복된 상위 이슈 검색 |
| | | private List<IssueVo> findIssue(IssueApiForm issueApiform, List<CustomFieldApiOverlap> customFieldApiOverlaps, Long userId) { |
| | | private List<Issue> findIssue(IssueApiForm issueApiform, List<CustomFieldApiOverlap> customFieldApiOverlaps, Long userId) { |
| | | List<IssueCustomFieldValueForm> issueCustomFieldValueForms = issueApiform.getIssueCustomFieldValues(); |
| | | List<IssueVo> resultIssueVos = Lists.newArrayList(); |
| | | List<Issue> resultIssueVos = Lists.newArrayList(); |
| | | String comma = ","; |
| | | |
| | | if (issueCustomFieldValueForms.size() > 0) { |
| | |
| | | |
| | | IssueCustomFieldValueCondition issueCustomFieldValueCondition = new IssueCustomFieldValueCondition(); |
| | | issueCustomFieldValueCondition.setUseValue(concatUseValue); |
| | | issueCustomFieldValueCondition.setIssueTypeId(issueApiform.getIssueTypeId()); |
| | | 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)); |
| | | resultIssueVos.add(this.getIssue(MapUtil.getLong(result, "id"))); |
| | | } |
| | | } |
| | | } |
| | |
| | | public List<IssueVo> findIssue(Map<String, Object> resJsonData, IssueCondition issueCondition, Pageable pageable) { |
| | | |
| | | // 검색 조건을 만든다 |
| | | /*if (!this.makeIssueSearchCondition(issueCondition, Lists.newArrayList("01", "02", "03"), pageable)) { |
| | | if (!this.makeIssueSearchCondition(issueCondition, Lists.newArrayList("01", "02", "03"), pageable)) { |
| | | // 이슈 목록을 찾지 못할 경우 기본 정보로 리턴한다. |
| | | this.notFoundIssueList(resJsonData, pageable); |
| | | return Lists.newArrayList(); |
| | | }*/ |
| | | } |
| | | |
| | | Set<String> issueIds = new HashSet<>(); // 사용자 정의 필드 검색시 나오는 이슈 아이디 저장 컬렉션 |
| | | |
| | |
| | | |
| | | 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); |
| | | |
| | | if (issueCondition.getTree()) { |
| | | this.setDownIssues(issueVos); |
| | | this.setRelationIssues(issueVos); |
| | | } |
| | | this.setCountDownIssues(results, issueVos); |
| | | |
| | | this.SetWorkflowDepartment(issueVos); //워크플로우에 설정한 담당부서 가져오기 |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, issueVos); |
| | |
| | | // 사용자 시스템 기능 사용 정보 수집 |
| | | log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(this.webAppUtil.getLoginUser(), ElasticSearchConstants.ISSUE_FIND)); |
| | | return issueVos; |
| | | } |
| | | |
| | | |
| | | // 하위 이슈 세팅 |
| | | private void setDownIssues(List<IssueVo> issueVos) { |
| | | for(IssueVo issueVo : issueVos) { |
| | | List<Issue> downIssues = this.issueRepository.findByParentIssueId(issueVo.getId()); |
| | | for(Issue downIssue : downIssues){ |
| | | issueVo.addIssueDownVo(ConvertUtil.copyProperties(downIssue, IssueVo.class)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 연관 이슈 세팅 |
| | | private void setRelationIssues(List<IssueVo> issueVos) { |
| | | for(IssueVo issueVo : issueVos) { |
| | | List<IssueVo> relationIssues = this.issueRelationService.findRelationIssue(issueVo.getId()); |
| | | for(IssueVo relationIssue : relationIssues){ |
| | | issueVo.addRelationIssueVo(ConvertUtil.copyProperties(relationIssue, IssueVo.class)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Override |
| | |
| | | condition.setWorkspaceId(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | projectCondition.setWorkspaceId(condition.getWorkspaceId()); |
| | | |
| | | |
| | | // 프로젝트 키가 존재할 경우 프로젝트 키에 해당하는 프로젝트를 조회하고 검색 조건에 셋팅한다. |
| | | if (!this.getProjectByProjectKey(condition.getProjectKey(), condition)) { |
| | | return false; |
| | |
| | | // 프로젝트를 선택하지 않았으면 해당 업무 공간에서 참여하고 있는 프로젝트를 찾는다. |
| | | if (condition.getProjectIds().size() < 1) { |
| | | List<Map<String, Object>> projects = null; |
| | | UserLevel userLevel = this.userLevelService.getUserLevel(user.getUserLevel().getId()); |
| | | if (this.userWorkspaceService.checkWorkspaceManager(user) |
| | | || MngPermission.checkMngPermission(userLevel.getPermission(), MngPermission.USER_PERMISSION_MNG_ISSUE_PROJECT_ALL)) { |
| | | if (this.userWorkspaceService.checkWorkspaceManager(user)) { |
| | | projects = this.projectMapper.findByWorkspaceManagerAll(projectCondition); |
| | | } else { |
| | | projects = this.projectService.findByWorkspaceIdAndIncludeProjectAll(projectCondition); |
| | |
| | | // 하위 이슈 정보를 셋팅한다 |
| | | private void setDownIssues(Issue issue, IssueVo issueVo) { |
| | | List<Issue> downIssues = this.issueRepository.findByParentIssueId(issue.getId()); |
| | | if(downIssues != null && downIssues.size()>0){ |
| | | List<IssueVo> resultList = new ArrayList<>(); |
| | | for(Issue downIssue : downIssues){ |
| | | IssueVo downIssueVo = ConvertUtil.copyProperties(downIssue, IssueVo.class); |
| | | downIssueVo.setIssueTypeVo(ConvertUtil.copyProperties(downIssue.getIssueType(), IssueTypeVo.class)); |
| | | downIssueVo.setPriorityVo(ConvertUtil.copyProperties(downIssue.getPriority(), PriorityVo.class)); |
| | | downIssueVo.setSeverityVo(ConvertUtil.copyProperties(downIssue.getSeverity(), SeverityVo.class)); |
| | | //이슈 상태 추가 |
| | | IssueStatusVo issueStatusVo = ConvertUtil.copyProperties(downIssue.getIssueStatus(), IssueStatusVo.class, "issueStatusType"); |
| | | issueStatusVo.setIssueStatusType(downIssue.getIssueStatus().getIssueStatusType().toString()); |
| | | downIssueVo.setIssueStatusVo(issueStatusVo); |
| | | if(downIssues != null && downIssues.size()>0){ |
| | | List<IssueVo> resultList = new ArrayList<>(); |
| | | for(Issue downIssue : downIssues){ |
| | | IssueVo downIssueVo = ConvertUtil.copyProperties(downIssue, IssueVo.class); |
| | | downIssueVo.setIssueTypeVo(ConvertUtil.copyProperties(downIssue.getIssueType(), IssueTypeVo.class)); |
| | | downIssueVo.setPriorityVo(ConvertUtil.copyProperties(downIssue.getPriority(), PriorityVo.class)); |
| | | downIssueVo.setSeverityVo(ConvertUtil.copyProperties(downIssue.getSeverity(), SeverityVo.class)); |
| | | //이슈 상태 추가 |
| | | IssueStatusVo issueStatusVo = ConvertUtil.copyProperties(downIssue.getIssueStatus(), IssueStatusVo.class, "issueStatusType"); |
| | | issueStatusVo.setIssueStatusType(downIssue.getIssueStatus().getIssueStatusType().toString()); |
| | | downIssueVo.setIssueStatusVo(issueStatusVo); |
| | | |
| | | this.setRegister(downIssue, downIssueVo); // 등록자 |
| | | this.setIssueDepartment(downIssue, downIssueVo); // 담당부서 정보 셋팅 |
| | | this.setIssueCustomFields(downIssue, downIssueVo); // 사용자정의필드 정보 세팅 |
| | | this.setRegister(downIssue, downIssueVo); // 등록자 |
| | | this.setIssueDepartment(downIssue, downIssueVo); // 담당부서 정보 셋팅 |
| | | this.setIssueCustomFields(downIssue, downIssueVo); // 사용자정의필드 정보 세팅 |
| | | |
| | | resultList.add(downIssueVo); |
| | | } |
| | | issueVo.setIssueDownVos(resultList); |
| | | resultList.add(downIssueVo); |
| | | } |
| | | issueVo.setIssueDownVos(resultList); |
| | | } |
| | | } |
| | | |
| | | // 이슈 상세 정보를 셋팅한다. |
| | |
| | | // 사용자 정의 필드 값이 같은 이슈 찾기 |
| | | @Override |
| | | @Transactional |
| | | public List<IssueVo> findIssue(IssueApiForm issueApiform) { |
| | | public List<Issue> findIssue(IssueApiForm issueApiform) { |
| | | |
| | | List<IssueCustomFieldValueForm> issueCustomFieldValueForms = issueApiform.getIssueCustomFieldValues(); |
| | | List<IssueVo> resultIssueVos = Lists.newArrayList(); |
| | | List<Issue> resultIssueVos = Lists.newArrayList(); |
| | | String comma = ","; |
| | | |
| | | if (issueCustomFieldValueForms.size() > 0) { |
| | |
| | | |
| | | IssueCustomFieldValueCondition issueCustomFieldValueCondition = new IssueCustomFieldValueCondition(); |
| | | issueCustomFieldValueCondition.setUseValue(concatUseValue); |
| | | issueCustomFieldValueCondition.setIssueTypeId(issueApiform.getIssueTypeId()); |
| | | 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)); |
| | | resultIssueVos.add(this.getIssue(MapUtil.getLong(result, "id"))); |
| | | } |
| | | } |
| | | } |
| | |
| | | User user = this.convertToUser(issueApiForm.getToken()); |
| | | IssueForm issueForm = this.convertToIssueForm(issueApiForm, user); |
| | | |
| | | List<IssueVo> issueVos = this.findIssue(issueApiForm); |
| | | if (issueVos != null && issueVos.size() > 0) { |
| | | List<Issue> issue = Lists.newArrayList(); |
| | | for (IssueVo issueVo : issueVos) { |
| | | IssueVo parentIssueVo = issueVo.getParentIssueVo(); |
| | | List<Issue> issue = this.findIssue(issueApiForm); |
| | | if (issue != null && issue.size() > 0) { |
| | | List<Issue> issues = Lists.newArrayList(); |
| | | for (Issue issueVo : issue) { |
| | | issueForm.setId(issueVo.getId()); |
| | | |
| | | // 자동 종료 상태 설정이 되어 있지 않으면 오류발생 |
| | |
| | | } |
| | | } |
| | | |
| | | issue.add(modifyIssue); |
| | | issues.add(modifyIssue); |
| | | } |
| | | return issue; |
| | | return issues; |
| | | } else { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.API_ISSUE_NOT_EXIST)); |
| | |
| | | //hasPermission = this.checkIssueModifyPermission(hasPermission, Issue.ASSIGNEE, issueVo, issueUserVos); |
| | | // 담당자가 없으면 모든 사용자가 수정 권한을 갖는다. |
| | | |
| | | hasPermission = this.checkIssueModifyPermission(hasPermission, Issue.ALL_ISSUE_MANAGER, issueVo, null, null, user); |
| | | hasPermission = this.checkIssueModifyPermission(hasPermission, Issue.ALL_PROJECT_MANAGER, issueVo, null, null, user); |
| | | //hasPermission = this.checkIssueModifyPermission(hasPermission, Issue.ALL_ISSUE_MANAGER, issueVo, null, null, user); |
| | | //hasPermission = this.checkIssueModifyPermission(hasPermission, Issue.ALL_PROJECT_MANAGER, issueVo, null, null, user); |
| | | |
| | | return hasPermission; |
| | | } |
| | |
| | | } |
| | | |
| | | private Issue issueRemoves(Long issueId, User user) { |
| | | Issue issue = this.findOne(issueId); |
| | | if(issue != null){ |
| | | // 이슈 수정 권한을 갖고 있는지 확인 |
| | | this.verifyIssueModifyPermission(issue, user); |
| | | |
| | | // 이슈 첨부 파일을 삭제한다. |
| | | if (issue.getAttachedFiles().size() > 0) { |
| | | List<Long> attachedFileIds = Lists.newArrayList(); |
| | | |
| | | for (AttachedFile attachedFile : issue.getAttachedFiles()) { |
| | | attachedFileIds.add(attachedFile.getId()); |
| | | } |
| | | // 첨부파일 삭제 |
| | | this.attachedFileService.removeAttachedFiles(attachedFileIds); |
| | | } |
| | | |
| | | // 지울 이슈가 연관이슈인지 체크 후 연관이슈 테이블에서도 삭제한다. |
| | | List<IssueRelation> issueRelationList = this.issueRelationRepository.findByRelationIssueId(issueId); |
| | | if (issueRelationList != null && issueRelationList.size() > 0) { |
| | | for(IssueRelation issueRelation : issueRelationList){ |
| | | StringBuilder sb = new StringBuilder(); |
| | | issueHistoryService.detectRelationIssue(IssueHistoryType.DELETE, issueRelation, sb); |
| | | issueHistoryService.addIssueHistory(issueRelation.getIssue(), IssueHistoryType.MODIFY, sb.toString()); |
| | | this.issueRelationRepository.delete(issueRelation); |
| | | } |
| | | } |
| | | |
| | | // 이슈 생성, 삭제시 예약 이메일에 등록해놓는다. |
| | | this.reservationIssueEmail(issue, EmailType.ISSUE_REMOVE); |
| | | // 이슈 삭제 |
| | | this.issueRepository.delete(issue); |
| | | Issue issue = null; |
| | | if(issueId != null){ |
| | | issue = this.getIssue(issueId); |
| | | } |
| | | // 이슈 수정 권한을 갖고 있는지 확인 |
| | | this.verifyIssueModifyPermission(issue, user); |
| | | |
| | | // 이슈 첨부 파일을 삭제한다. |
| | | if (issue.getAttachedFiles().size() > 0) { |
| | | List<Long> attachedFileIds = Lists.newArrayList(); |
| | | |
| | | for (AttachedFile attachedFile : issue.getAttachedFiles()) { |
| | | attachedFileIds.add(attachedFile.getId()); |
| | | } |
| | | // 첨부파일 삭제 |
| | | this.attachedFileService.removeAttachedFiles(attachedFileIds); |
| | | } |
| | | |
| | | // 지울 이슈가 연관이슈인지 체크 후 연관이슈 테이블에서도 삭제한다. |
| | | List<IssueRelation> issueRelationList = this.issueRelationRepository.findByRelationIssueId(issueId); |
| | | if (issueRelationList != null && issueRelationList.size() > 0) { |
| | | for(IssueRelation issueRelation : issueRelationList){ |
| | | StringBuilder sb = new StringBuilder(); |
| | | issueHistoryService.detectRelationIssue(IssueHistoryType.DELETE, issueRelation, sb); |
| | | issueHistoryService.addIssueHistory(issueRelation.getIssue(), IssueHistoryType.MODIFY, sb.toString()); |
| | | this.issueRelationRepository.delete(issueRelation); |
| | | } |
| | | } |
| | | |
| | | // 이슈 생성, 삭제시 예약 이메일에 등록해놓는다. |
| | | this.reservationIssueEmail(issue, EmailType.ISSUE_REMOVE); |
| | | // 이슈 삭제 |
| | | this.issueRepository.delete(issue); |
| | | |
| | | return issue; |
| | | } |
| | |
| | | } |
| | | this.issueHistoryService.addIssueHistory(parentIssue, IssueHistoryType.MODIFY, sb.toString()); //parentIssue = myIssue(기록은 현재 상세페이지에 해야하니까) |
| | | this.issueRepository.saveAndFlush(issue); |
| | | |
| | | } |
| | | |
| | | @Override |
| | |
| | | private String email; |
| | | private String url; |
| | | private String memo; |
| | | private Long ispId; |
| | | private Long hostingId; |
| | | |
| | | private List<IspFieldVo> ispFieldVos = Lists.newArrayList(); |
| | | private List<HostingFieldVo> hostingFieldVos = Lists.newArrayList(); |
| | | private IspFieldVo ispFieldVo; |
| | | private HostingFieldVo hostingFieldVo; |
| | | |
| | | public CompanyFieldVo() {} |
| | | |
| | | public CompanyFieldVo(String manager, String tel, String email, String memo) { |
| | | |
| | | this.manager = manager; |
| | | this.tel = tel; |
| | | this.email = email; |
| | |
| | | this.url = url; |
| | | } |
| | | |
| | | public List<IspFieldVo> getIspFieldVos() { |
| | | return ispFieldVos; |
| | | public IspFieldVo getIspFieldVo() { |
| | | return ispFieldVo; |
| | | } |
| | | |
| | | public void setIspFieldVos(List<IspFieldVo> ispFieldVos) { |
| | | this.ispFieldVos = ispFieldVos; |
| | | public void setIspFieldVo(IspFieldVo ispFieldVo) { |
| | | this.ispFieldVo = ispFieldVo; |
| | | } |
| | | |
| | | public List<HostingFieldVo> getHostingFieldVos() { |
| | | return hostingFieldVos; |
| | | public HostingFieldVo getHostingFieldVo() { |
| | | return hostingFieldVo; |
| | | } |
| | | |
| | | public void setHostingFieldVos(List<HostingFieldVo> hostingFieldVos) { |
| | | this.hostingFieldVos = hostingFieldVos; |
| | | public void setHostingFieldVo(HostingFieldVo hostingFieldVo) { |
| | | this.hostingFieldVo = hostingFieldVo; |
| | | } |
| | | |
| | | public Long getIspId() { |
| | | return ispId; |
| | | } |
| | | |
| | | public void setIspId(Long ispId) { |
| | | this.ispId = ispId; |
| | | } |
| | | |
| | | public Long getHostingId() { |
| | | return hostingId; |
| | | } |
| | | |
| | | public void setHostingId(Long hostingId) { |
| | | this.hostingId = hostingId; |
| | | } |
| | | } |
| | |
| | | this.issueRelations.add(issueRelationVo); |
| | | } |
| | | |
| | | public void addRelationIssueVo(IssueVo issueVo) { |
| | | if (this.issueRelationVos != null) { |
| | | this.issueRelationVos.add(issueVo); |
| | | } |
| | | } |
| | | |
| | | /*public void addIssueDownVo(IssueDownVo issueDownVo) { |
| | | if (this.issueDownVos == null){ |
| | | this.issueDownVos = new ArrayList<>(); |
| | |
| | | this.issueDownVos = issueDownVos; |
| | | } |
| | | |
| | | public void addIssueDownVo(IssueVo issueVo) { |
| | | if (this.issueDownVos != null) { |
| | | this.issueDownVos.add(issueVo); |
| | | } |
| | | } |
| | | |
| | | public IssueVo getParentIssueVo() { |
| | | return parentIssueVo; |
| | | } |
| | |
| | | private String email; |
| | | private String url; |
| | | private String memo; |
| | | private Long ispId; |
| | | private Long hostingId; |
| | | |
| | | private Integer Page; |
| | | private Integer PageSize; |
| | |
| | | public void setUrl(String url) { |
| | | this.url = url; |
| | | } |
| | | |
| | | public Long getIspId() { |
| | | return ispId; |
| | | } |
| | | |
| | | public void setIspId(Long ispId) { |
| | | this.ispId = ispId; |
| | | } |
| | | |
| | | public Long getHostingId() { |
| | | return hostingId; |
| | | } |
| | | |
| | | public void setHostingId(Long hostingId) { |
| | | this.hostingId = hostingId; |
| | | } |
| | | } |
| | |
| | | private List<Long> excludeIds = Lists.newArrayList(); |
| | | private List<Long> myDepartmentIds; // 내가 속해있는 부서 ID |
| | | private Boolean hideIssue; |
| | | private Boolean isTree; // 트리구조 모드 일때 |
| | | |
| | | public IssueCondition(){} |
| | | |
| | |
| | | |
| | | if (MapUtil.getBoolean(conditions, "hideIssue") != null) { |
| | | condition.setHideIssue(MapUtil.getBoolean(conditions, "hideIssue")); |
| | | } |
| | | |
| | | if (MapUtil.getBoolean(conditions, "isTree") != null) { |
| | | condition.setTree(MapUtil.getBoolean(conditions, "isTree")); |
| | | } |
| | | |
| | | return condition; |
| | |
| | | public void setHideIssue(Boolean hideIssue) { |
| | | this.hideIssue = hideIssue; |
| | | } |
| | | |
| | | public Boolean getTree() { |
| | | return isTree; |
| | | } |
| | | |
| | | public void setTree(Boolean tree) { |
| | | isTree = tree; |
| | | } |
| | | } |
| | |
| | | * Created by wisestone on 2018-06-07. |
| | | */ |
| | | public class IssueCustomFieldValueCondition { |
| | | private Long issueTypeId; |
| | | private Long workspaceId; |
| | | private Long customFieldId; |
| | | private String customFieldType; |
| | |
| | | return condition; |
| | | } |
| | | |
| | | public Long getIssueTypeId() { |
| | | return issueTypeId; |
| | | } |
| | | |
| | | public void setIssueTypeId(Long issueTypeId) { |
| | | this.issueTypeId = issueTypeId; |
| | | } |
| | | |
| | | public Long getWorkspaceId() { |
| | | return workspaceId; |
| | | } |
| | |
| | | Pageable pageable = this.pageUtil.convertPageable(this.getPageVo(params)); |
| | | |
| | | // todo |
| | | |
| | | return this.setSuccessMessage(resJsonData); |
| | | } |
| | | } |
| | |
| | | private String tel; |
| | | private String url; |
| | | private String memo; |
| | | private Long ispId; |
| | | private Long hostingId; |
| | | |
| | | private List<Long> removeIds = Lists.newArrayList(); |
| | | |
| | | public CompanyFieldForm() { |
| | |
| | | this.memo = memo; |
| | | } |
| | | |
| | | public Long getIspId() { |
| | | return ispId; |
| | | } |
| | | |
| | | public void setIspId(Long ispId) { |
| | | this.ispId = ispId; |
| | | } |
| | | |
| | | public Long getHostingId() { |
| | | return hostingId; |
| | | } |
| | | |
| | | public void setHostingId(Long hostingId) { |
| | | this.hostingId = hostingId; |
| | | } |
| | | |
| | | public List<Long> getRemoveIds() { |
| | | return removeIds; |
| | | } |
| | |
| | | package kr.wisestone.owl.web.form; |
| | | |
| | | public class IssueCustomFieldValueForm { |
| | | private Long issueTypeId; |
| | | private Long customFieldId; |
| | | private String useValue; |
| | | |
| | | public IssueCustomFieldValueForm(){} |
| | | |
| | | public Long getIssueTypeId() { |
| | | return issueTypeId; |
| | | } |
| | | |
| | | public void setIssueTypeId(Long issueTypeId) { |
| | | this.issueTypeId = issueTypeId; |
| | | } |
| | | |
| | | public Long getCustomFieldId() { |
| | | return customFieldId; |
| | | } |
| | |
| | | |
| | | -- 업체의 url 컬럼 INDEX 추가 |
| | | ALTER TABLE `company_field` ADD INDEX `urlIndex`(`url`); |
| | | |
| | | ALTER TABLE `company_field` ADD COLUMN `isp_id` bigint(20) DEFAULT NULL; |
| | | ALTER TABLE `company_field` ADD COLUMN `hosting_id` bigint(20) DEFAULT NULL; |
| | | |
| | | ALTER TABLE `company_field` ADD INDEX `ispIdIndex`(`isp_id`); |
| | | ALTER TABLE `company_field` ADD INDEX `hostingIdIndex`(`hosting_id`); |
| | | |
| | | |
| | | |
| | | |
| | |
| | | cf.tel as tel, |
| | | cf.email as email, |
| | | cf.url as url, |
| | | cf.memo as memo |
| | | cf.memo as memo, |
| | | cf.isp_id as ispId, |
| | | cf.hosting_id as hostingId |
| | | FROM |
| | | company_field cf |
| | | WHERE 1=1 |
| | |
| | | AND issue.reverse_index <![CDATA[ < ]]> 0 |
| | | AND workspace.id = #{workspaceId} |
| | | GROUP BY issue.id |
| | | ORDER BY issue.register_date DESC |
| | | ORDER BY issue.modify_date DESC |
| | | <if test="page != null and !page.equals('')"> |
| | | limit #{pageSize} offset #{page}; |
| | | </if> |
| | |
| | | LEFT OUTER JOIN (SELECT issue_id, COUNT(id) as issueCommentCount FROM issue_comment GROUP BY issue_id) |
| | | temp_issue_comment on (temp_issue_comment.issue_id = issue.id) |
| | | WHERE 1=1 |
| | | <if test="keyWord != null and !keyWord.equals('') "> |
| | | <if test="keyWord != null and !keyWord.equals('') and myDepartmentIds.size != 0"> |
| | | AND issue.title like CONCAT('%',#{keyWord},'%') |
| | | OR issue.description like CONCAT('%',#{keyWord},'%') |
| | | OR issue.start_date like CONCAT('%',#{keyWord},'%') |
| | |
| | | AND issue.reverse_index <![CDATA[ < ]]> 0 |
| | | AND workspace.id = #{workspaceId} |
| | | GROUP BY issue.id |
| | | ORDER BY issue.register_date DESC |
| | | ORDER BY issue.modify_date DESC |
| | | <if test="page != null and !page.equals('')"> |
| | | limit #{pageSize} offset #{page}; |
| | | </if> |
| | |
| | | <select id="findByIssueTypeId" resultType="java.util.HashMap" |
| | | parameterType="java.lang.Long"> |
| | | SELECT |
| | | i.id as issueId, |
| | | iss.id as issueStatusId, |
| | | iss.name as issueStatusName |
| | | i.id as issueId, |
| | | iss.id as issueStatusId, |
| | | iss.name as issueStatusName |
| | | FROM issue i |
| | | INNER JOIN issue_status iss on iss.id = i.issue_status_id |
| | | INNER JOIN issue_status iss on iss.id = i.issue_status_id |
| | | WHERE i.issue_type_id = #{issueTypeId} |
| | | </select> |
| | | |
| | |
| | | <select id="findByProjectId" resultType="java.util.HashMap" |
| | | parameterType="kr.wisestone.owl.web.condition.IssueCondition"> |
| | | SELECT |
| | | id |
| | | id |
| | | FROM issue |
| | | WHERE project_id = #{projectId} |
| | | </select> |
| | |
| | | |
| | | <!-- 이슈 유형을 사용하는 이슈 갯수를 조회한다 --> |
| | | <select id="countByIssueTypeId" resultType="java.lang.Long" parameterType="java.lang.Long"> |
| | | SELECT COUNT(DISTINCT id) FROM |
| | | issue WHERE issue_type_id = #{issueTypeId}; |
| | | SELECT COUNT(DISTINCT id) FROM |
| | | issue WHERE issue_type_id = #{issueTypeId}; |
| | | </select> |
| | | |
| | | <!-- 이슈 유형을 사용하는 이슈 갯수를 조회한다(기간) --> |
| | | <select id="countByIssueTypeIdAndDate" resultType="java.lang.Long" parameterType="kr.wisestone.owl.web.condition.IssueTypeCondition"> |
| | | SELECT |
| | | COUNT(DISTINCT id) |
| | | COUNT(DISTINCT id) |
| | | FROM issue |
| | | WHERE issue_type_id = #{id} |
| | | AND register_date BETWEEN #{startDate} AND #{endDate} |
| | | AND is_api = #{isApi}; |
| | | AND register_date BETWEEN #{startDate} AND #{endDate} |
| | | AND is_api = #{isApi}; |
| | | </select> |
| | | |
| | | <!-- 이슈 상태를 사용하는 이슈 갯수를 조회한다. --> |
| | | <select id="countByIssueStatusId" resultType="java.lang.Long" parameterType="java.lang.Long"> |
| | | SELECT COUNT(DISTINCT id) FROM |
| | | issue WHERE issue_status_id = #{issueStatusId}; |
| | | issue WHERE issue_status_id = #{issueStatusId}; |
| | | </select> |
| | | |
| | | |
| | |
| | | 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 ( |
| | | 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' |
| | | AND issue.issue_type_id = #{issueTypeId} |
| | | GROUP BY issue.id |
| | | HAVING concatUseValue LIKE CONCAT('%', #{useValue}, '%') |
| | | </select> |
| | |
| | | <!-- 종료 안된 하위 이슈 가져오기 --> |
| | | <select id="findNotCompleteByParentIssueId" resultType="java.util.HashMap" parameterType="kr.wisestone.owl.web.condition.IssueCondition"> |
| | | SELECT |
| | | iss.id as id, |
| | | iss.title as title |
| | | iss.id as id, |
| | | iss.title as title |
| | | FROM issue iss |
| | | INNER JOIN issue_status issueStatus on iss.issue_status_id = issueStatus.id |
| | | 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' |
| | | AND iss.id != #{id} |
| | | AND issueStatus.issue_status_type != 'CLOSE' |
| | | </select> |
| | | </mapper> |
New file |
| | |
| | | 'use strict'; |
| | | |
| | | define(['app'], |
| | | function (app) { |
| | | app.directive('jsTree', ['$log', |
| | | function ($log) { |
| | | return { |
| | | restrict : 'E', |
| | | scope : { |
| | | event : '=', |
| | | data : '=', |
| | | tableConfigs : '=', |
| | | useSort : '=', // 정령 기능 사용 여부 |
| | | detailView : "=" // 이슈 목록 상세형 변경을 위해 사용. 다른 화면은 사용하지 않음. |
| | | }, |
| | | replace : true, |
| | | templateUrl : '/custom_components/js-tree/js-tree.html', |
| | | controller : function ($scope, $element, $attrs) { |
| | | $scope.fn = { |
| | | getResponseData : getResponseData |
| | | } |
| | | |
| | | // 테이블 정보 가져오기 |
| | | function getResponseData() { |
| | | return $scope.data; |
| | | } |
| | | }, |
| | | link : function (scope, element, attrs) { |
| | | |
| | | }, |
| | | |
| | | }; |
| | | }]) |
| | | }); |
| | | |
| | | |
New file |
| | |
| | | <ul> |
| | | <li ng-repeat="row in fn.getResponseData()"> |
| | | <span>{{row.title}}</span> |
| | | <ul> |
| | | <li ng-repeat="downRow in row.issueDownVos"> |
| | | |
| | | |
| | | <span>{{downRow.title}}</span> |
| | | </li> |
| | | </ul> |
| | | </li> |
| | | |
| | | <li ng-if="fn.getResponseData().length == 0"> |
| | | <span translate="common.noData">데이터가 없습니다.</span> |
| | | </li> |
| | | </ul> |
New file |
| | |
| | | 'use strict'; |
| | | |
| | | define(['app', 'angular'], |
| | | function (app, angular) { |
| | | app.provider("$treeProvider", function () { |
| | | return { |
| | | $get : function ($log) { |
| | | return { |
| | | config : function () { |
| | | var tableConfig = { |
| | | hName : "", // 헤더 이름 |
| | | hWidth : "", // 칼럼 길이 |
| | | hChecked : false, // 체크 박스 선택 여부 |
| | | hAlign : "text-center", // 헤더 정렬 기준 |
| | | hSort : true, // 정렬 가능 여부 |
| | | dName : "", // 데이터 이름 |
| | | dAlign : "text-left", // 데이터 정렬 기준 |
| | | dRenderer : "", // 렌더러 여부 |
| | | dVisible : "", // bootstrap 반응형 컬럼 표시 여부 |
| | | dType : "none", // 태그 타입 |
| | | dDateFormat : "", // 날짜 형식 |
| | | rowSpan : 0, // rowspan 을 지원한다. |
| | | colSpan : 0, // colspan 을 지원한다. |
| | | subHead : false, // 만약 rowspan, colspan 을 사용하게 되면 true 로 셋팅. |
| | | columnHint : "", // 컬럼 정보를 추출하기 위한 힌트 정보를 준다 - tableColumnGenerator 의 사용자 정의 필드 부분에서 사용 |
| | | setHName : function (hName) { |
| | | this.hName = hName; |
| | | return this; |
| | | }, |
| | | setHWidth : function (hWidth) { |
| | | this.hWidth = hWidth; |
| | | return this; |
| | | }, |
| | | setHChecked : function (hChecked) { |
| | | this.hChecked = hChecked; |
| | | return this; |
| | | }, |
| | | setHAlign : function (hAlign) { |
| | | this.hAlign = hAlign; |
| | | return this; |
| | | }, |
| | | setHSort : function (hSort) { |
| | | this.hSort = hSort; |
| | | return this; |
| | | }, |
| | | setDName : function (dName) { |
| | | this.dName = dName; |
| | | return this; |
| | | }, |
| | | setDAlign : function (dAlign) { |
| | | this.dAlign = dAlign; |
| | | return this; |
| | | }, |
| | | setDRenderer : function (dRenderer) { |
| | | this.dRenderer = dRenderer; |
| | | return this; |
| | | }, |
| | | setDVisible : function (dVisible) { |
| | | this.dVisible = dVisible; |
| | | return this; |
| | | }, |
| | | setDType : function (dType) { |
| | | this.dType = dType; |
| | | return this; |
| | | }, |
| | | setDDateFormat : function (dDateFormat) { |
| | | this.dDateFormat = dDateFormat; |
| | | return this; |
| | | }, |
| | | setRowSpan : function (dRowSpan) { |
| | | this.rowSpan = dRowSpan; |
| | | return this; |
| | | }, |
| | | setColSpan : function (dColSpan) { |
| | | this.colSpan = dColSpan; |
| | | return this; |
| | | }, |
| | | setSubHead : function (dSubHead) { |
| | | this.subHead = dSubHead; |
| | | return this; |
| | | }, |
| | | setColumnHint : function (dColumnHint) { |
| | | this.columnHint = dColumnHint; |
| | | return this; |
| | | } |
| | | }; |
| | | |
| | | return tableConfig; |
| | | }, |
| | | toggleChecked : function (checkStatus, datas) { |
| | | // 전체 선택 체크 박스를 클릭했을 경우 |
| | | angular.forEach(datas, function (data) { |
| | | if (angular.isDefined(data.defaultYn)) { |
| | | if (!data.defaultYn) { |
| | | data.checked = checkStatus; |
| | | } |
| | | } |
| | | else { |
| | | data.checked = checkStatus; |
| | | } |
| | | }); |
| | | }, |
| | | radioChecked : function (target, datas) { |
| | | // 해당 row 가 라디오 버튼일 경우 |
| | | angular.forEach(datas, function (data) { |
| | | if (target.id == data.id) { |
| | | data.checked = true; |
| | | } |
| | | else { |
| | | data.checked = false; |
| | | } |
| | | }); |
| | | }, |
| | | rowChecked : function (tableConfig, target, datas) { |
| | | // 각 row 의 체크박스/라디오 버튼을 클릭했을 경우 |
| | | if (tableConfig[0].dType == "checkbox") { |
| | | target.checked = !target.checked; |
| | | |
| | | for (var data in datas) { |
| | | if (!data.checked) { |
| | | this.hChecked = false; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | else if (tableConfig[0].dType == "radio") { |
| | | this.radioChecked(target, datas); |
| | | } |
| | | }, |
| | | orderByColumn : "", // table order By column name |
| | | reverse : true, |
| | | setOrderByColumn : function (column) { |
| | | if (column == "") { |
| | | return; |
| | | } |
| | | |
| | | if (this.orderByColumn == column) { |
| | | this.reverse = !this.reverse; |
| | | } |
| | | else { |
| | | this.reverse = true; |
| | | } |
| | | |
| | | this.orderByColumn = column; |
| | | return this; |
| | | }, |
| | | getDateFormat : function (formatType, date) { |
| | | if (formatType == "" || formatType == null) { |
| | | formatType = "01"; |
| | | } |
| | | Date.prototype.format = function (f) { |
| | | if (!this.valueOf()) { |
| | | return " "; |
| | | } |
| | | var weekName = ["일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"]; |
| | | var d = this; |
| | | |
| | | return f.replace(/(yyyy|yy|MM|dd|E|hh|mm|ss|a\/p)/gi, function ($1) { |
| | | switch ($1) { |
| | | case "yyyy": |
| | | return d.getFullYear(); |
| | | case "yy": |
| | | return (d.getFullYear() % 1000).zf(2); |
| | | case "MM": |
| | | return (d.getMonth() + 1).zf(2); |
| | | case "dd": |
| | | return d.getDate().zf(2); |
| | | case "E": |
| | | return weekName[d.getDay()]; |
| | | case "HH": |
| | | return d.getHours().zf(2); |
| | | case "hh": |
| | | var h = d.getHours(); |
| | | return ((h = d.getHours() % 12) ? h : 12).zf(2); |
| | | case "mm": |
| | | return d.getMinutes().zf(2); |
| | | case "ss": |
| | | return d.getSeconds().zf(2); |
| | | case "a/p": |
| | | return d.getHours() < 12 ? "오전" : "오후"; |
| | | default: |
| | | return $1; |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | String.prototype.string = function (len) { |
| | | var s = '', i = 0; |
| | | while (i++ < len) { |
| | | s += this; |
| | | } |
| | | return s; |
| | | }; |
| | | String.prototype.zf = function (len) { |
| | | return "0".string(len - this.length) + this; |
| | | }; |
| | | Number.prototype.zf = function (len) { |
| | | return this.toString().zf(len); |
| | | }; |
| | | |
| | | var dateFormat = ""; |
| | | var dynamicTime = false; |
| | | var today = new Date().format("yyyy-MM-dd"); |
| | | var compareDate = new Date(date).format("yyyy-MM-dd"); |
| | | |
| | | if (today == compareDate) { |
| | | dynamicTime = true; |
| | | } |
| | | |
| | | switch (formatType) { |
| | | case "01": // 날짜 |
| | | dateFormat = "yyyy-MM-dd"; |
| | | break; |
| | | case "02": // 날짜 + 시간 |
| | | dateFormat = "yyyy-MM-dd HH:mm"; |
| | | break; |
| | | case "03": // 유동적 표시 |
| | | if (dynamicTime) { |
| | | dateFormat = "HH:mm"; |
| | | } |
| | | else { |
| | | dateFormat = "yyyy-MM-dd HH:mm"; |
| | | } |
| | | |
| | | break; |
| | | } |
| | | |
| | | return dateFormat; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | }); |
| | | }); |
New file |
| | |
| | | 'use strict'; |
| | | |
| | | define(['app', 'angular'], |
| | | function (app, angular) { |
| | | |
| | | app.directive('treeColumnGenerator', ['$compile', '$log', '$rootScope', '$tableProvider', '$filter', |
| | | function ($compile, $log, $rootScope, $tableProvider, $filter) { |
| | | return { |
| | | restrict : "A", |
| | | compile : function (tElement, tAttrs) { |
| | | return function (scope, element, attrs) { |
| | | scope.data = scope[attrs["treeColumnGenerator"]]; |
| | | |
| | | var makeTag = ""; |
| | | var treeStartToken = "└"; |
| | | |
| | | scope.tableConfigs.forEach(function (tableConfig, index) { |
| | | |
| | | if (tableConfig.colSpan > 0) { |
| | | return; |
| | | } |
| | | |
| | | makeTag = '<li class="' + tableConfig.dAlign + ' ' + tableConfig.dVisible + '">'; |
| | | |
| | | if (tableConfig.dType === "checkbox") { |
| | | // 체크 박스일때 |
| | | if (scope.data.defaultYn) { |
| | | makeTag += '<input type="checkbox" ng-checked="data.checked == true ? true : false" disabled ng-click="$root.$tableProvider.rowChecked(tableConfigs, data, fn.getResponseData())">'; |
| | | } |
| | | else { |
| | | makeTag += '<input type="checkbox" ng-checked="data.checked == true ? true : false" ng-click="$root.$tableProvider.rowChecked(tableConfigs, data, fn.getResponseData())">'; |
| | | } |
| | | |
| | | tableConfig.hChecked = false; |
| | | } |
| | | else if (tableConfig.dType === "radio") { |
| | | // 라디오 버튼일때 |
| | | makeTag += '<input type="radio" ng-checked="data.checked == true ? true : false" ng-click="$root.$tableProvider.rowChecked(tableConfigs, data, fn.getResponseData())">'; |
| | | } |
| | | else if (tableConfig.dType === "date") { |
| | | makeTag += $filter('date')(scope.data[tableConfig.dName], $tableProvider.getDateFormat(tableConfig.dDateFormat, scope.data[tableConfig.dName])); |
| | | } |
| | | else { |
| | | if (angular.isDefined(scope.data[tableConfig.dName]) && scope.data[tableConfig.dName] != null) { |
| | | makeTag += '<span>' + scope.data[tableConfig.dName] + '</span>'; |
| | | } |
| | | else { |
| | | makeTag += '<span></span>'; |
| | | } |
| | | } |
| | | |
| | | makeTag += '</li>'; |
| | | |
| | | var linkFn = $compile(makeTag); |
| | | var content = linkFn(scope); |
| | | |
| | | element.append(content); |
| | | |
| | | }); |
| | | } |
| | | } |
| | | } |
| | | }]); |
| | | }); |
| | |
| | | }, |
| | | "ispField" : { |
| | | "info": "ISP정보", |
| | | "select": "ISP 선택", |
| | | "add" : "ISP생성", |
| | | "name" : "ISP이름", |
| | | "ispName" : "ISP명", |
| | |
| | | }, |
| | | "hostingField" : { |
| | | "info": "호스팅정보", |
| | | "select": "호스팅 선택", |
| | | "add" : "호스팅생성", |
| | | "name" : "호스팅이름", |
| | | "manager" : "호스팅이름", |
| | |
| | | $scope.vm = { |
| | | form : { |
| | | name : "", //업체명 |
| | | ispId : "", |
| | | ispName : "", |
| | | hostingName : "", |
| | | //companyType : "", //업체분류 |
| | | //profitYN : "", //영리/비영리 |
| | | //industry : "", //산업분류 |
| | | //domain : "", //도메인 |
| | | hostingId : "", |
| | | manager : "", //담당자 |
| | | tel : "", //전화번호 |
| | | email : "", //이메일 |
| | |
| | | } |
| | | } |
| | | }; |
| | | |
| | | |
| | | angular.extend(this, $controller('autoCompleteController', {$scope : $scope, $injector : $injector})); |
| | | |
| | |
| | | return false; |
| | | } |
| | | |
| | | $scope.$on("ispFieldEvent", function (event, result) { |
| | | $scope.vm.form.ispId = result[0].id; |
| | | }); |
| | | |
| | | $scope.$on("hostingFieldEvent", function (event, result) { |
| | | $scope.vm.form.hostingId = result[0].id; |
| | | }); |
| | | |
| | | // 폼 전송 |
| | | function formSubmit(condition) { |
| | | $rootScope.spinner = true; |
| | | |
| | | var content = { |
| | | name : $rootScope.preventXss($scope.vm.form.name), // 업체명 |
| | | ispName : $rootScope.preventXss($scope.vm.form.ispName), // 업체명 |
| | | hostingName : $rootScope.preventXss($scope.vm.form.hostingName), // 업체명 |
| | | //companyType : $scope.vm.form.companyType, //업체분류 |
| | | //profitYN : $scope.vm.form.profitYN, //영리/비영리 |
| | | //industry : $scope.vm.form.industry, //산업분류 |
| | | //domain : $scope.vm.form.domain, //도메인 |
| | | ispId : (function () { // ISP 아이디 |
| | | var ispId = -1; |
| | | if ($scope.vm.form.issueIspFields != null) { |
| | | ispId = $scope.vm.form.ispId; |
| | | } |
| | | return ispId; |
| | | })(), |
| | | hostingId : (function () { // Hosting 아이디 |
| | | var hostingId = -1; |
| | | if ($scope.vm.form.issueHostingFields != null) { |
| | | hostingId = $scope.vm.form.hostingId; |
| | | } |
| | | return hostingId; |
| | | })(), |
| | | manager : $scope.vm.form.manager, //담당자 |
| | | tel : $scope.vm.form.tel, //전화번호 |
| | | email : $scope.vm.form.email, //이메일 |
| | |
| | | 'angular' |
| | | ], |
| | | function (app, angular) { |
| | | app.controller('companyFieldModifyController', ['$scope', '$rootScope', '$log', '$resourceProvider', '$uibModalInstance', 'CompanyField', 'parameter', 'SweetAlert', '$filter', '$q', |
| | | function ($scope, $rootScope, $log, $resourceProvider, $uibModalInstance, CompanyField, parameter, SweetAlert, $filter, $q) { |
| | | app.controller('companyFieldModifyController', ['$scope', '$rootScope', '$log', '$resourceProvider', '$uibModalInstance', 'CompanyField', 'parameter', 'SweetAlert', '$filter', '$q', '$injector','$controller', |
| | | function ($scope, $rootScope, $log, $resourceProvider, $uibModalInstance, CompanyField, parameter, SweetAlert, $filter, $q, $injector, $controller) { |
| | | |
| | | $scope.fn = { |
| | | detail : detail, // 상세 조회 |
| | | cancel : cancel, // 팝업 창 닫기 |
| | | formSubmit : formSubmit, // 폼 전송 |
| | | formCheck : formCheck, // 폼 체크 |
| | | getIssueIspFieldListCallBack : getIssueIspFieldListCallBack, |
| | | getIssueHostingFieldListCallBack : getIssueHostingFieldListCallBack |
| | | }; |
| | | |
| | | $scope.vm = { |
| | | id : parameter.id, |
| | | form : { |
| | | name : "", //업체명 |
| | | ispId : "", |
| | | ispName : "", |
| | | hostingName : "", |
| | | hostingId : "", |
| | | manager : "", //담당자 |
| | | tel : "", //전화번호 |
| | | email : "", //이메일 |
| | | url : "", // url |
| | | memo : "" //메모(비고) |
| | | }, |
| | | autoCompletePage : { |
| | | ispField : { |
| | | page : 0, |
| | | totalPage : 0 |
| | | }, |
| | | hostingField : { |
| | | page : 0, |
| | | totalPage : 0 |
| | | } |
| | | } |
| | | }; |
| | | |
| | | angular.extend(this, $controller('autoCompleteController', {$scope : $scope, $injector : $injector})); |
| | | |
| | | |
| | | // ISP정보 autocomplete page 업데이트 |
| | | function getIssueIspFieldListCallBack(result) { |
| | | $scope.vm.autoCompletePage.ispField.totalPage = result.data.page.totalPage; |
| | | } |
| | | |
| | | // 호스팅정보 autocomplete page 업데이트 |
| | | function getIssueHostingFieldListCallBack(result) { |
| | | $scope.vm.autoCompletePage.hostingField.totalPage = result.data.page.totalPage; |
| | | } |
| | | |
| | | function formCheck(formInvalid) { |
| | | if (formInvalid) { |
| | |
| | | return false; |
| | | } |
| | | |
| | | $scope.$on("ispFieldEvent", function (event, result) { |
| | | $scope.vm.form.ispId = result[0].id; |
| | | }); |
| | | |
| | | $scope.$on("hostingFieldEvent", function (event, result) { |
| | | $scope.vm.form.hostingId = result[0].id; |
| | | }); |
| | | |
| | | // 폼 전송 |
| | | function formSubmit() { |
| | | $rootScope.spinner = true; |
| | |
| | | var content = { |
| | | id : parameter.id, |
| | | name : $rootScope.preventXss($scope.vm.form.name), |
| | | /*companyType : $rootScope.preventXss($scope.vm.form.companyType), |
| | | profitYN : $rootScope.preventXss($scope.vm.form.profitYN), |
| | | industry : $rootScope.preventXss($scope.vm.form.industry), |
| | | domain : $rootScope.preventXss($scope.vm.form.domain),*/ |
| | | ispId : (function () { // ISP 아이디 |
| | | var ispId = -1; |
| | | if ($scope.vm.form.issueIspFields.length > 0) { |
| | | ispId = $scope.vm.form.ispId; |
| | | } |
| | | return ispId; |
| | | })(), |
| | | hostingId : (function () { // Hosting 아이디 |
| | | var hostingId = -1; |
| | | if ($scope.vm.form.issueHostingFields.length > 0) { |
| | | hostingId = $scope.vm.form.hostingId; |
| | | } |
| | | return hostingId; |
| | | })(), |
| | | manager : $rootScope.preventXss($scope.vm.form.manager), |
| | | tel : $rootScope.preventXss($scope.vm.form.tel), |
| | | email : $rootScope.preventXss($scope.vm.form.email), |
| | |
| | | $scope.vm.form.tel = result.data.content.tel; |
| | | $scope.vm.form.url = result.data.content.url; |
| | | $scope.vm.form.memo = result.data.content.memo; |
| | | if(result.data.content.ispFieldVo != null){ |
| | | $scope.vm.form.ispName = result.data.content.ispFieldVo.name; |
| | | } |
| | | if(result.data.content.hostingFieldVo != null){ |
| | | $scope.vm.form.hostingName = result.data.content.hostingFieldVo.name; |
| | | } |
| | | } |
| | | } |
| | | else { |
| | |
| | | var deferred = $q.defer(); |
| | | require([ |
| | | 'issueListTimelineController', 'issueManagerController', 'issueListController', 'issueAddController', 'issueModifyController', 'issueDetailController', 'issueAddRelationController', 'issueImportExcelController', |
| | | 'chartLoader', 'jsTable', 'tableColumnGenerator', 'modalFormAutoScroll', 'summerNote', 'summerNote-ko-KR', 'fullScroll', 'workflowService', 'priorityService', 'issueSearchService', 'issueTableConfigService', 'inputRegex', |
| | | 'chartLoader', 'jsTable', 'jsTree', 'tableColumnGenerator', 'treeColumnGenerator', 'modalFormAutoScroll', 'summerNote', 'summerNote-ko-KR', 'fullScroll', 'workflowService', 'priorityService', 'issueSearchService', 'issueTableConfigService', 'inputRegex', |
| | | 'severityService', 'issueTypeService', 'issueTypeCustomFieldService', 'issueService', 'issueStatusService', 'issueUserService','issueDepartmentService','issueModifyUserController', 'issueModifyDepartmentController', 'customFieldService', 'issueSearchFieldKeyViewElement', |
| | | 'issueSearchCustomFieldViewElement', 'tableUserImage', 'fullScroll', 'issueCommentService', 'detectIssueEditor', 'formSubmit', 'issueModifyStatusController', 'downIssueModifyStatusController', 'jsShortCut', |
| | | 'issueAddTableConfigController','issueAddRelationTableConfigController','issueAddDownTableConfigController','domAppend', 'issueDetailImagePreview', 'issueSendMailPartnersController', 'htmlDiff', 'issueVersionViewController', 'issueVersionService', |
| | |
| | | |
| | | // 업체정보 결과 값 Event 처리(set) |
| | | $scope.$on("companyFieldEvent", function (event, result) { |
| | | var ispFieldVos = result[0].ispFieldVos[0]; |
| | | var hostingFieldVos = result[0].hostingFieldVos[0]; |
| | | var ispFieldVo = result[0].ispFieldVo; |
| | | var hostingFieldVo = result[0].hostingFieldVo; |
| | | |
| | | $scope.vm.companyId = result[0].id; |
| | | $scope.vm.companyName = result[0].name; |
| | |
| | | $scope.vm.companyUrl = result[0].url; |
| | | $scope.vm.companyMemo = result[0].memo; |
| | | |
| | | $scope.vm.ispName = ispFieldVos.name; |
| | | $scope.vm.ispCode = ispFieldVos.code; |
| | | $scope.vm.ispManager = ispFieldVos.manager; |
| | | $scope.vm.ispTel = ispFieldVos.tel; |
| | | $scope.vm.ispEmail = ispFieldVos.email; |
| | | $scope.vm.ispUrl = ispFieldVos.url; |
| | | $scope.vm.ispMemo = ispFieldVos.memo; |
| | | $scope.vm.ispName = ispFieldVo.name; |
| | | $scope.vm.ispCode = ispFieldVo.code; |
| | | $scope.vm.ispManager = ispFieldVo.manager; |
| | | $scope.vm.ispTel = ispFieldVo.tel; |
| | | $scope.vm.ispEmail = ispFieldVo.email; |
| | | $scope.vm.ispUrl = ispFieldVo.url; |
| | | $scope.vm.ispMemo = ispFieldVo.memo; |
| | | |
| | | $scope.vm.hostingName = hostingFieldVos.name; |
| | | $scope.vm.hostingCode = hostingFieldVos.code; |
| | | $scope.vm.hostingManager = hostingFieldVos.manager; |
| | | $scope.vm.hostingTel = hostingFieldVos.tel; |
| | | $scope.vm.hostingEmail = hostingFieldVos.email; |
| | | $scope.vm.hostingUrl = hostingFieldVos.url; |
| | | $scope.vm.hostingMemo = hostingFieldVos.memo; |
| | | $scope.vm.hostingName = hostingFieldVo.name; |
| | | $scope.vm.hostingCode = hostingFieldVo.code; |
| | | $scope.vm.hostingManager = hostingFieldVo.manager; |
| | | $scope.vm.hostingTel = hostingFieldVo.tel; |
| | | $scope.vm.hostingEmail = hostingFieldVo.email; |
| | | $scope.vm.hostingUrl = hostingFieldVo.url; |
| | | $scope.vm.hostingMemo = hostingFieldVo.memo; |
| | | }); |
| | | |
| | | // ISP정보 결과 값 Event 처리(set) |
| | | // $scope.$on("ispFieldEvent", function (event, result) { |
| | | // $scope.vm.ispId = result[0].id; |
| | | // $scope.vm.ispName = result[0].name; |
| | | // $scope.vm.ispCode = result[0].code; |
| | | // $scope.vm.ispManager = result[0].manager; |
| | | // $scope.vm.ispTel = result[0].tel; |
| | | // $scope.vm.ispEmail = result[0].email; |
| | | // $scope.vm.ispUrl = result[0].url; |
| | | // $scope.vm.ispMemo = result[0].memo; |
| | | // }); |
| | | //ISP정보 결과 값 Event 처리(set) |
| | | $scope.$on("ispFieldEvent", function (event, result) { |
| | | $scope.vm.ispId = result[0].id; |
| | | $scope.vm.ispName = result[0].name; |
| | | $scope.vm.ispCode = result[0].code; |
| | | $scope.vm.ispManager = result[0].manager; |
| | | $scope.vm.ispTel = result[0].tel; |
| | | $scope.vm.ispEmail = result[0].email; |
| | | $scope.vm.ispUrl = result[0].url; |
| | | $scope.vm.ispMemo = result[0].memo; |
| | | }); |
| | | |
| | | // 호스팅정보 결과 값 Event 처리(set) |
| | | $scope.$on("hostingFieldEvent", function (event, result) { |
| | |
| | | 'angular' |
| | | ], |
| | | function (app, angular) { |
| | | app.controller('issueListController', ['$scope', '$rootScope', '$log', '$resourceProvider', '$tableProvider', '$state', '$uibModal', '$q', |
| | | app.controller('issueListController', ['$scope', '$rootScope', '$log', '$resourceProvider', '$tableProvider', '$treeProvider', '$state', '$uibModal', '$q', |
| | | '$controller', '$injector', 'SweetAlert', 'Issue', 'IssueType', 'Priority', 'Severity', 'IssueStatus', 'CustomField', 'IssueSearch', 'IssueTableConfig', '$timeout', '$filter', |
| | | function ($scope, $rootScope, $log, $resourceProvider, $tableProvider, $state, $uibModal, $q, $controller, $injector, SweetAlert, Issue, IssueType, Priority, Severity, IssueStatus, CustomField, |
| | | function ($scope, $rootScope, $log, $resourceProvider, $tableProvider, $treeProvider, $state, $uibModal, $q, $controller, $injector, SweetAlert, Issue, IssueType, Priority, Severity, IssueStatus, CustomField, |
| | | IssueSearch, IssueTableConfig, $timeout, $filter) { |
| | | |
| | | // 함수 |
| | |
| | | changePageRowCount : changePageRowCount, // 페이지 변경 |
| | | makeTableConfigs : makeTableConfigs, // 테이블 설정 |
| | | setTableColumn : setTableColumn, // 테이블의 컬럼을 만들어준다. |
| | | setTreeColumn : setTreeColumn, |
| | | add : add, // 이슈 생성 |
| | | modify : modify, // 이슈 수정 |
| | | addRelationIssueForm : addRelationIssueForm, // 연관 이슈 추가 |
| | |
| | | makeSearchConditions : makeSearchConditions, // 검색 조건을 만든다. |
| | | getIssueTableConfigs : getIssueTableConfigs, // 사용자 이슈 목록 테이블 설정 값을 가져와서 적용한다. |
| | | startExecute : startExecute, // 컨트롤 로딩시 처음으로 시작되는 함수 |
| | | getResponseData : getResponseData // 컨트롤 로딩시 처음으로 시작되는 함수 |
| | | getResponseData : getResponseData, // 컨트롤 로딩시 처음으로 시작되는 함수 |
| | | onClickListMode : onClickListMode // 리스트 모드 변경시 실행되는 함수 |
| | | }; |
| | | |
| | | // 변수 |
| | |
| | | selectedPageRowCount : String(10) |
| | | }, |
| | | tableConfigs : [], // 테이블 셋팅 정보 |
| | | treeConfigs : [], // 트리 셋팅 정보 |
| | | responseData : { |
| | | data : [] |
| | | }, |
| | |
| | | customFields : [], // 사용자 정의 필드 |
| | | issueTableConfigs : [], // 이슈 테이블 설정 |
| | | parentIssueId : "", |
| | | hideIssue : false |
| | | hideIssue : false, |
| | | listMode : 0, // 목록 모드 0:기본 리스트 1:트리구조 리스트 |
| | | }; |
| | | |
| | | // 테이블 이벤트 |
| | |
| | | if (issueTableConfig.display) { |
| | | // 테이블의 컬럼을 만들어준다. |
| | | $scope.fn.setTableColumn(issueTableConfig); |
| | | $scope.fn.setTreeColumn(issueTableConfig); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | // 트리 컬럼을 만들어준다. |
| | | function setTreeColumn(issueTableConfig) { |
| | | |
| | | // 일반 컬럼 |
| | | switch(issueTableConfig.key) { |
| | | case "ISSUE_TITLE" : // 이슈 제목 |
| | | $scope.vm.treeConfigs.push($treeProvider.config() |
| | | .setHName("issue.issueTitle") |
| | | .setDType("renderer") |
| | | .setHWidth("bold " + issueTableConfig.width) |
| | | .setDAlign("text-center") |
| | | .setDRenderer("ISSUE_TITLE")); |
| | | break; |
| | | |
| | | case "PRIORITY" : // 우선순위 |
| | | $scope.vm.treeConfigs.push($treeProvider.config() |
| | | .setHName("common.priority") |
| | | .setDName("priorityName") |
| | | .setDType("renderer") |
| | | .setHWidth("bold " + issueTableConfig.width) |
| | | .setDAlign("text-center") |
| | | .setDRenderer("COMMON_PRIORITY")); |
| | | break; |
| | | case "SEVERITY" : // 중요도 |
| | | $scope.vm.treeConfigs.push($treeProvider.config() |
| | | .setHName("common.importance") |
| | | .setDName("severityName") |
| | | .setDType("renderer") |
| | | .setHWidth("bold " + issueTableConfig.width) |
| | | .setDAlign("text-center") |
| | | .setDRenderer("COMMON_SEVERITY")); |
| | | break; |
| | | case "ISSUE_TYPE" : // 이슈 타입 |
| | | $scope.vm.treeConfigs.push($treeProvider.config() |
| | | .setHName("issue.issueType") |
| | | .setHWidth("bold " + issueTableConfig.width) |
| | | .setDAlign("text-center") |
| | | .setDName("issueTypeName")); |
| | | break; |
| | | case "ASSIGNEE_TEAM" : // 담당부서 |
| | | $scope.vm.treeConfigs.push($treeProvider.config() |
| | | .setHName("common.assigneeTeam") |
| | | .setDType("renderer") |
| | | .setHWidth("bold " + issueTableConfig.width) |
| | | .setDAlign("text-center") |
| | | .setDRenderer("ISSUE_DEPARTMENT")); |
| | | break; |
| | | case "REGISTER" : // 등록자 |
| | | $scope.vm.treeConfigs.push($treeProvider.config() |
| | | .setHName("common.register") |
| | | .setDType("renderer") |
| | | .setHWidth("bold " + issueTableConfig.width) |
| | | .setDAlign("text-center") |
| | | .setDRenderer("REGISTER")); |
| | | break; |
| | | case "PERIOD" : // 기간 |
| | | $scope.vm.treeConfigs.push($treeProvider.config() |
| | | .setHName("common.period") |
| | | .setDType("renderer") |
| | | .setHWidth("bold " + issueTableConfig.width) |
| | | .setDAlign("text-center") |
| | | .setDRenderer("ISSUE_DUE_DATE")); |
| | | break; |
| | | case "MODIFY_DATE" : // 최근 변경일 |
| | | $scope.vm.treeConfigs.push($treeProvider.config() |
| | | .setHName("common.lastChangeDate") |
| | | .setHWidth("bold " + issueTableConfig.width) |
| | | .setDAlign("text-center") |
| | | .setDName("modifyDate")); |
| | | break; |
| | | case "COUNT_DOWN_ISSUE" : // 하위 이슈 개수 |
| | | $scope.vm.treeConfigs.push($treeProvider.config() |
| | | .setHName("common.countDownIssue") |
| | | .setDType("renderer") |
| | | .setHWidth("bold " + issueTableConfig.width) |
| | | .setDAlign("text-center") |
| | | .setDRenderer("DOWN_ISSUE_COUNT")); |
| | | break; |
| | | } |
| | | |
| | | // 사용자 정의 필드 컬럼 |
| | | if (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.treeConfigs.push($treeProvider.config() |
| | | .setHName(customField.name) |
| | | .setDType("renderer") |
| | | .setHWidth("bold " + issueTableConfig.width) |
| | | .setDAlign("text-center") |
| | | .setColumnHint(customField) |
| | | .setDRenderer("ISSUE_CUSTOM_FIELD_VALUE_VIEW")); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 테이블의 컬럼을 만들어준다. |
| | |
| | | beginCompleteDate : "", |
| | | endCompleteDate : "", |
| | | hideIssue : $scope.vm.hideIssue, |
| | | isTree : $scope.vm.listMode === 1, |
| | | projectIds : (function () { |
| | | var projectIds = []; |
| | | |
| | |
| | | } |
| | | |
| | | return conditions; |
| | | } |
| | | |
| | | function getTreeList() { |
| | | |
| | | } |
| | | |
| | | // 이슈 목록을 조회한다. |
| | |
| | | return deferred.promise; |
| | | } |
| | | |
| | | // 리스트 모드 변경시 실행 |
| | | function onClickListMode(listMode) { |
| | | if ($scope.vm.listMode !== listMode) { |
| | | $scope.vm.listMode = listMode; |
| | | |
| | | if ($scope.vm.listMode === 0) { |
| | | $scope.fn.getPageList(0); |
| | | } else { |
| | | $scope.fn.getPageList(0); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 최초 실행 |
| | | function startExecute() { |
| | | // 파라미터 읽기 |
| | |
| | | 'angularTranslate' : '../custom_components/angular-translate/angular-translate', // 다국어 처리에 사용 |
| | | 'commonController' : 'app/common/common.controller', // 공통 컨트롤러 |
| | | 'tableProvider' : '../custom_components/js-table/table.provider', // 테이블 속성 값을 관리한다. |
| | | 'treeProvider' : '../custom_components/js-tree/tree.provider', // 트리 속성 값을 관리한다. |
| | | 'resourceProvider' : 'components/utils/resource.provider', // 공통적으로 서버 json 전송에 사용 |
| | | 'lodash' : '../bower_components/lodash/lodash.min', // 멀티 셀렉트, auto complete 컴포넌트들에서 사용 |
| | | 'angularDropMultiSelect' : '../custom_components/angular-multi-select/angularjs-dropdown-multiselect', // 멀티 셀렉트 컴포넌트 |
| | | 'jsTable' : '../custom_components/js-table/js-table.directive', // 목록 화면에서 사용되는 테이블을 호출한다. |
| | | 'jsTreeTable' : '../custom_components/js-table/js-tree-table.directive', // 목록 화면에서 사용되는 테이블(트리구조)을 호출한다. |
| | | 'jsTree' : '../custom_components/js-tree/js-tree.directive', // 목록 화면에서 사용되는 테이블(트리구조)을 호출한다. |
| | | 'tableColumnGenerator' : '../custom_components/js-table/tableColumnGenerator.directive', // 테이블 랜더러를 담당한다. |
| | | 'treeColumnGenerator' : '../custom_components/js-tree/treeColumnGenerator.directive', // 테이블 랜더러를 담당한다. |
| | | 'jsAutoCompleteMulti' : '../custom_components/js-autocomplete-multi/js-autocomplete-multi', // 다중 선택이 가능한 autoComplete 컴포넌트 |
| | | 'jsInputAutoComplete' : '../custom_components/js-input-autocomplete/js-input-autocomplete', // input 박스에 autoComplete 기능이 붙은 컴포넌트 |
| | | 'jsAutoCompleteSingle' : '../custom_components/js-autocomplete-single/js-autocomplete-single', // input 박스에 한개의 대상만 선택 가능할수 있는 autoComplete 기능이 붙은 컴포넌트 |
| | |
| | | 'jsTable' : { |
| | | deps : ['app'] |
| | | }, |
| | | 'jsTreeTable' : { |
| | | 'jsTree' : { |
| | | deps : ['app'] |
| | | }, |
| | | 'tableColumnGenerator' : { |
| | | deps : ['app'] |
| | | }, |
| | | 'treeColumnGenerator' : { |
| | | deps : ['app'] |
| | | }, |
| | | 'ngStomp' : { |
| | |
| | | 'authInterceptor', |
| | | 'resourceProvider', |
| | | 'tableProvider', |
| | | 'treeProvider', |
| | | 'permissionService', |
| | | 'authService', |
| | | 'userInviteService', |
| | |
| | | |
| | | <div class="form-group"> |
| | | <label class="issue-label"> |
| | | <span translate="ispField.name">ISP 이름</span> |
| | | <span translate="ispField.select">ISP 선택</span> |
| | | </label> |
| | | <js-autocomplete-single data-input-name="ispField" |
| | | selected-model="vm.form.issueIspFields" |
| | | ng-model="vm.form.ispName" |
| | | search="vm.form.ispName" |
| | | source="fn.getIssueIspFieldList(vm.ispName, vm.form.issueIspFields, vm.autoCompletePage.issueIspFields.page, fn.getIssueIspFieldListCallBack)" |
| | | page="vm.autoCompletePage.IspField.page" |
| | | total-page="vm.autoCompletePage.IspField.totalPage" |
| | | page="vm.autoCompletePage.ispField.page" |
| | | total-page="vm.autoCompletePage.ispField.totalPage" |
| | | input-disabled="false" |
| | | translation-texts="{ empty : 'common.emptyHosting' }" |
| | | broad-cast="ispFieldEvent" |
| | |
| | | |
| | | <div class="form-group"> |
| | | <label class="issue-label"> |
| | | <span translate="hostingField.name">호스팅 이름</span> |
| | | <span translate="hostingField.select">호스팅 선택</span> |
| | | </label> |
| | | <js-autocomplete-single data-input-name="hostingField" |
| | | selected-model="vm.form.issueHostingFields" |
| | |
| | | required> |
| | | <small translate="companyField.enterSpecialCharacters">업체 이름에는 특수 문자를 입력 할수 없습니다.</small> |
| | | </div> |
| | | <div class="form-group"> |
| | | <label class="issue-label"> |
| | | <span translate="ispField.select">ISP 선택</span> |
| | | </label> |
| | | <js-autocomplete-single data-input-name="ispField" |
| | | selected-model="vm.form.issueIspFields" |
| | | ng-model="vm.form.ispName" |
| | | search="vm.form.ispName" |
| | | source="fn.getIssueIspFieldList(vm.ispName, vm.form.issueIspFields, vm.autoCompletePage.issueIspFields.page, fn.getIssueIspFieldListCallBack)" |
| | | page="vm.autoCompletePage.ispField.page" |
| | | total-page="vm.autoCompletePage.ispField.totalPage" |
| | | input-disabled="false" |
| | | translation-texts="{ empty : 'common.emptyHosting' }" |
| | | broad-cast="ispFieldEvent" |
| | | extra-settings="{ displayProp : 'name' , idProp : 'id', imageable : false, imagePathProp : '', |
| | | type : '', maxlength : 200, autoResize : false, stopRemoveBodyEvent : true }"></js-autocomplete-single> |
| | | </div> |
| | | |
| | | <div class="form-group"> |
| | | <label class="issue-label"> |
| | | <span translate="hostingField.select">호스팅 선택</span> |
| | | </label> |
| | | <js-autocomplete-single data-input-name="hostingField" |
| | | selected-model="vm.form.issueHostingFields" |
| | | ng-model="vm.form.hostingName" |
| | | search="vm.form.hostingName" |
| | | source="fn.getIssueHostingFieldList(vm.hostingName, vm.form.issueHostingFields, vm.autoCompletePage.hostingField.page, fn.getIssueHostingFieldListCallBack)" |
| | | page="vm.autoCompletePage.hostingField.page" |
| | | total-page="vm.autoCompletePage.hostingField.totalPage" |
| | | input-disabled="false" |
| | | translation-texts="{ empty : 'common.emptyHosting' }" |
| | | broad-cast="hostingFieldEvent" |
| | | extra-settings="{ displayProp : 'name' , idProp : 'id', imageable : false, imagePathProp : '', |
| | | type : '', maxlength : 200, autoResize : false, stopRemoveBodyEvent : true }"></js-autocomplete-single> |
| | | </div> |
| | | <div> |
| | | <div class="form-group"> |
| | | <label for="companyFieldAddForm10" class="issue-label"> |
| | |
| | | <div class="col-lg-8 fontcolor_green"> |
| | | <label class="issue-label"><span class="fontcolor_green" translate="companyField.info">업체정보</span> |
| | | <span class="select3-selection__choice" style="position: relative; bottom: 2px;"><code class="highlighter-rouge">*</code> |
| | | 업체 이름 클릭시 선택된 이름의 업체 정보가 조회되며, 같은 url을 가지고있는 ISP, 호스팅 정보를 불러옵니다.</span> |
| | | 업체 이름 클릭시 선택된 이름의 업체 정보가 조회되며, 업체정보에서 추가한 ISP, 호스팅 정보를 불러옵니다.</span> |
| | | </label> |
| | | </div> |
| | | </div> |
| | |
| | | <div class="col-sm-12" > |
| | | <div class="element-wrapper" ng-if="!vm.detailView"> |
| | | <div class="element-box"> |
| | | <div class="row" > |
| | | <div class="col-sm-12"> |
| | | <div class="searchdiv"> |
| | | <form name="issueSearchForm" role="form" ng-enter="fn.getPageList(0)"> |
| | | <div class="row"> |
| | | <div class="col-sm-6"> |
| | | <div class="input-group"> |
| | | <input class="form-control" |
| | | type="text" |
| | | tabindex="-1" |
| | | maxlength="300" |
| | | kr-input |
| | | owl-auto-focus |
| | | ng-model="vm.search.keyWord" |
| | | placeholder="{{'issue.pleaseEnterIssueKeyWord' | translate}}"> |
| | | <div class="input-group-prepend ml-10"> |
| | | <button class="btn btn-navy" ng-click="fn.getPageList(0)"> <span translate="common.search">검색</span></button> |
| | | <div class="row" > |
| | | <div class="col-sm-12"> |
| | | <div class="searchdiv"> |
| | | <form name="issueSearchForm" role="form" ng-enter="fn.getPageList(0)"> |
| | | <div class="row"> |
| | | <div class="col-sm-6"> |
| | | <div class="input-group"> |
| | | <input class="form-control" |
| | | type="text" |
| | | tabindex="-1" |
| | | maxlength="300" |
| | | kr-input |
| | | owl-auto-focus |
| | | ng-model="vm.search.keyWord" |
| | | placeholder="{{'issue.pleaseEnterIssueKeyWord' | translate}}"> |
| | | <div class="input-group-prepend ml-10"> |
| | | <button class="btn btn-navy" ng-click="fn.getPageList(0)"> <span translate="common.search">검색</span></button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="row"> |
| | | <div class="col-sm-12"> |
| | | <div class="tabfilter"> |
| | | <div translate="common.selectedSearchCriteria">선택한 검색 조건</div> |
| | | <!-- 이슈 제목 --> |
| | | <p ng-if="$root.isDefined(vm.search.title)"> |
| | | {{vm.search.title}} |
| | | <span ng-click="vm.search.title = ''">×</span> |
| | | </p> |
| | | <div class="row"> |
| | | <div class="col-sm-12"> |
| | | <div class="tabfilter"> |
| | | <div translate="common.selectedSearchCriteria">선택한 검색 조건</div> |
| | | <!-- 이슈 제목 --> |
| | | <p ng-if="$root.isDefined(vm.search.title)"> |
| | | {{vm.search.title}} |
| | | <span ng-click="vm.search.title = ''">×</span> |
| | | </p> |
| | | |
| | | <!-- 프로젝트 --> |
| | | <issue-search-array-view-element lists="vm.projects" |
| | | type="'project'"></issue-search-array-view-element> |
| | | <!-- 프로젝트 --> |
| | | <issue-search-array-view-element lists="vm.projects" |
| | | type="'project'"></issue-search-array-view-element> |
| | | |
| | | <!-- 이슈 타입 --> |
| | | <issue-search-field-key-view-element lists="vm.issueTypes" |
| | | keys="vm.search.issueTypeIds"></issue-search-field-key-view-element> |
| | | <!-- 이슈 타입 --> |
| | | <issue-search-field-key-view-element lists="vm.issueTypes" |
| | | keys="vm.search.issueTypeIds"></issue-search-field-key-view-element> |
| | | |
| | | <!-- 이슈 상태 --> |
| | | <issue-search-field-key-view-element lists="vm.issueStatuses" |
| | | keys="vm.search.issueStatusIds"></issue-search-field-key-view-element> |
| | | <!-- 이슈 상태 --> |
| | | <issue-search-field-key-view-element lists="vm.issueStatuses" |
| | | keys="vm.search.issueStatusIds"></issue-search-field-key-view-element> |
| | | |
| | | <!-- 이슈 내용 --> |
| | | <p ng-if="$root.isDefined(vm.search.description)"> |
| | | {{vm.search.description}} |
| | | <span ng-click="vm.search.description = ''">×</span> |
| | | </p> |
| | | <!-- 이슈 내용 --> |
| | | <p ng-if="$root.isDefined(vm.search.description)"> |
| | | {{vm.search.description}} |
| | | <span ng-click="vm.search.description = ''">×</span> |
| | | </p> |
| | | |
| | | <!-- 우선 순위 --> |
| | | <issue-search-field-key-view-element lists="vm.priorities" |
| | | keys="vm.search.priorityIds"></issue-search-field-key-view-element> |
| | | <!-- 우선 순위 --> |
| | | <issue-search-field-key-view-element lists="vm.priorities" |
| | | keys="vm.search.priorityIds"></issue-search-field-key-view-element> |
| | | |
| | | <!-- 중요도 --> |
| | | <issue-search-field-key-view-element lists="vm.severities" |
| | | keys="vm.search.severityIds"></issue-search-field-key-view-element> |
| | | <!-- 중요도 --> |
| | | <issue-search-field-key-view-element lists="vm.severities" |
| | | keys="vm.search.severityIds"></issue-search-field-key-view-element> |
| | | |
| | | <!-- 담당자 --> |
| | | <issue-search-array-view-element lists="vm.users" |
| | | type="'user'"></issue-search-array-view-element> |
| | | <!-- 담당자 --> |
| | | <issue-search-array-view-element lists="vm.users" |
| | | type="'user'"></issue-search-array-view-element> |
| | | |
| | | <!-- 등록자 --> |
| | | <issue-search-array-view-element lists="vm.registers" |
| | | type="'user'"></issue-search-array-view-element> |
| | | <!-- 등록자 --> |
| | | <issue-search-array-view-element lists="vm.registers" |
| | | type="'user'"></issue-search-array-view-element> |
| | | |
| | | <!-- 시작일 --> |
| | | <p ng-if="$root.isDefined(vm.search.startDateRange)"> |
| | | {{vm.search.startDateRange}} |
| | | <span ng-click="vm.search.startDateRange = ''">×</span> |
| | | </p> |
| | | <!-- 시작일 --> |
| | | <p ng-if="$root.isDefined(vm.search.startDateRange)"> |
| | | {{vm.search.startDateRange}} |
| | | <span ng-click="vm.search.startDateRange = ''">×</span> |
| | | </p> |
| | | |
| | | <!-- 종료일 --> |
| | | <p ng-if="$root.isDefined(vm.search.completeDateRange)"> |
| | | {{vm.search.completeDateRange}} |
| | | <span ng-click="vm.search.completeDateRange = ''">×</span> |
| | | </p> |
| | | <!-- 종료일 --> |
| | | <p ng-if="$root.isDefined(vm.search.completeDateRange)"> |
| | | {{vm.search.completeDateRange}} |
| | | <span ng-click="vm.search.completeDateRange = ''">×</span> |
| | | </p> |
| | | |
| | | <!-- 등록일 --> |
| | | <p ng-if="$root.isDefined(vm.search.registerDateRange)"> |
| | | {{vm.search.registerDateRange}} |
| | | <span ng-click="vm.search.registerDateRange = ''">×</span> |
| | | </p> |
| | | <!-- 등록일 --> |
| | | <p ng-if="$root.isDefined(vm.search.registerDateRange)"> |
| | | {{vm.search.registerDateRange}} |
| | | <span ng-click="vm.search.registerDateRange = ''">×</span> |
| | | </p> |
| | | |
| | | <!-- 텍스트 입력 필드 --> |
| | | <issue-search-custom-field-view-element |
| | | custom-fields="vm.customFields"></issue-search-custom-field-view-element> |
| | | <!-- 텍스트 입력 필드 --> |
| | | <issue-search-custom-field-view-element |
| | | custom-fields="vm.customFields"></issue-search-custom-field-view-element> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | |
| | | <div class=""> |
| | | <label class="issue-search-label" ng-class="{ 'icon-reverse' : vm.searchView }" |
| | | ng-click="vm.searchView = !vm.searchView"> |
| | | <span translate="common.detailedSearch">상세검색</span> |
| | | </label> |
| | | <div ng-if="vm.searchView"> |
| | | <div class="row"> |
| | | <div class="col-lg-3"> |
| | | <div class="form-group"> |
| | | <label> <span translate="issue.issueTitle">이슈 제목</span></label> |
| | | <input type="text" |
| | | name="title" |
| | | class="form-control input-sm" |
| | | kr-input |
| | | maxlength="20" |
| | | autocomplete="off" |
| | | ng-model="vm.search.title"> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="col-lg-3"> |
| | | <div class="form-group"> |
| | | <label> <span translate="common.project">프로젝트</span></label> |
| | | <js-autocomplete-multi data-input-name="projects" |
| | | selected-model="vm.projects" |
| | | search="vm.projectName" |
| | | input-disabled="false" |
| | | translation-texts="{ empty : 'common.emptyProject', selectList : 'common.' }" |
| | | source="fn.getProjectList(vm.projectName, vm.projects, null, null, ['01', '02', '03'])" |
| | | extra-settings="{ displayProp : 'name' , idProp : 'id', imageable : false, imagePathProp : '', type : '', maxlength : 100}"></js-autocomplete-multi> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="col-lg-3"> |
| | | <div class="form-group"> |
| | | <label> <span translate="issue.issueType">이슈 타입</span></label> |
| | | <ng-dropdown-multiselect class="multiSelect cursor" |
| | | data-input-name="issueStatuses" |
| | | selected-model="vm.search.issueTypeIds" |
| | | options="::vm.issueTypes"></ng-dropdown-multiselect> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="col-lg-3"> |
| | | <div class="form-group"> |
| | | <label> <span translate="issue.issueStatus">이슈 상태</span></label> |
| | | <ng-dropdown-multiselect class="multiSelect cursor" |
| | | data-input-name="issueStatuses" |
| | | selected-model="vm.search.issueStatusIds" |
| | | options="::vm.issueStatuses"></ng-dropdown-multiselect> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="row"> |
| | | <div class="col-lg-3"> |
| | | <div class="form-group"> |
| | | <label> <span translate="issue.issueNumber">이슈 번호</span></label> |
| | | <input type="text" |
| | | name="name" |
| | | class="form-control input-sm" |
| | | autocomplete="off" |
| | | kr-input |
| | | maxlength="20" |
| | | ng-model="vm.search.combinationIssueNumber"> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="col-lg-3"> |
| | | <div class="form-group"> |
| | | <label> <span translate="issue.issueContent">이슈 내용</span></label> |
| | | <input type="text" |
| | | name="description" |
| | | class="form-control input-sm" |
| | | kr-input |
| | | maxlength="20" |
| | | autocomplete="off" |
| | | ng-model="vm.search.description"> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="col-lg-3"> |
| | | <div class="form-group"> |
| | | <label> <span translate="common.priority">우선 순위</span></label> |
| | | <ng-dropdown-multiselect class="multiSelect cursor" |
| | | data-input-name="priorities" |
| | | selected-model="vm.search.priorityIds" |
| | | options="::vm.priorities"></ng-dropdown-multiselect> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="col-lg-3"> |
| | | <div class="form-group"> |
| | | <label> <span translate="common.importance">중요도</span></label> |
| | | <ng-dropdown-multiselect class="multiSelect cursor" |
| | | data-input-name="severities" |
| | | selected-model="vm.search.severityIds" |
| | | options="::vm.severities"></ng-dropdown-multiselect> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="row"> |
| | | <div class="col-lg-3"> |
| | | <div class="form-group"> |
| | | <label> <span translate="common.register">등록자</span></label> |
| | | <js-autocomplete-multi data-input-name="registers" |
| | | selected-model="vm.registers" |
| | | search="vm.registerName" |
| | | input-disabled="false" |
| | | source="fn.getUserList(vm.registerName, vm.registers)" |
| | | translation-texts="{ count : 'common.userNum', empty : 'common.emptyUser' }" |
| | | extra-settings="{ displayProp : 'byName' , idProp : 'id', widthable : false, width : '', imageable : true, imagePathProp : 'profile', type : 'user', maxlength : 100 }"> |
| | | </js-autocomplete-multi> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="col-lg-3"> |
| | | <div class="form-group"> |
| | | <label> <span translate="common.registrationDate">등록일</span></label> |
| | | <input type="text" |
| | | readonly |
| | | class="form-control input-sm input-readonly" |
| | | ng-model="vm.search.registerDateRange" |
| | | modal-form-auto-scroll |
| | | date-format="YY-MM-DD" |
| | | parent-el="'#createdWidget'" |
| | | date-range-picker> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="col-lg-3"> |
| | | <div class="form-group"> |
| | | <label> <span translate="common.startDate">시작일</span></label> |
| | | <input type="text" |
| | | readonly |
| | | class="form-control input-sm input-readonly" |
| | | ng-model="vm.search.startDateRange" |
| | | date-format="YY-MM-DD" |
| | | parent-el="'#createdWidget'" |
| | | date-range-picker> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="col-lg-3"> |
| | | <div class="form-group"> |
| | | <label> <span translate="common.endDate">종료일</span></label> |
| | | <input type="text" |
| | | readonly |
| | | class="form-control input-sm input-readonly" |
| | | ng-model="vm.search.completeDateRange" |
| | | modal-form-auto-scroll |
| | | date-format="YY-MM-DD" |
| | | parent-el="'#createdWidget'" |
| | | date-range-picker> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="col-lg-3"> |
| | | <div class="form-group"> |
| | | <label> <span translate="common.assigneeTeam">담당부서</span></label> |
| | | <js-autocomplete-multi data-input-name="departments" |
| | | selected-model="vm.departments" |
| | | search="vm.departmentName" |
| | | input-disabled="false" |
| | | source="fn.getUserDepartmentList(vm.departmentName, vm.departments)" |
| | | translation-texts="{ count : 'common.userNum', empty : 'common.emptyProjectDepartment' }" |
| | | extra-settings="{ displayProp : 'byName' , idProp : 'id', widthable : false, width : '', imageable : true, imagePathProp : 'profile', type : 'department', maxlength : 100 }"> |
| | | </js-autocomplete-multi> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="col-lg-3" ng-repeat="customField in vm.customFields"> |
| | | <label>{{::customField.name}}</label> |
| | | |
| | | <div ng-switch on="customField.customFieldType"> |
| | | <div ng-switch-when="INPUT"> |
| | | <input type="text" class="form-control input-sm" |
| | | ng-model="customField.useValues" |
| | | maxlength="100"> |
| | | <div class=""> |
| | | <label class="issue-search-label" ng-class="{ 'icon-reverse' : vm.searchView }" |
| | | ng-click="vm.searchView = !vm.searchView"> |
| | | <span translate="common.detailedSearch">상세검색</span> |
| | | </label> |
| | | <div ng-if="vm.searchView"> |
| | | <div class="row"> |
| | | <div class="col-lg-3"> |
| | | <div class="form-group"> |
| | | <label> <span translate="issue.issueTitle">이슈 제목</span></label> |
| | | <input type="text" |
| | | name="title" |
| | | class="form-control input-sm" |
| | | kr-input |
| | | maxlength="20" |
| | | autocomplete="off" |
| | | ng-model="vm.search.title"> |
| | | </div> |
| | | </div> |
| | | |
| | | <div ng-switch-default> |
| | | <div class="col-lg-3"> |
| | | <div class="form-group"> |
| | | <label> <span translate="common.project">프로젝트</span></label> |
| | | <js-autocomplete-multi data-input-name="projects" |
| | | selected-model="vm.projects" |
| | | search="vm.projectName" |
| | | input-disabled="false" |
| | | translation-texts="{ empty : 'common.emptyProject', selectList : 'common.' }" |
| | | source="fn.getProjectList(vm.projectName, vm.projects, null, null, ['01', '02', '03'])" |
| | | extra-settings="{ displayProp : 'name' , idProp : 'id', imageable : false, imagePathProp : '', type : '', maxlength : 100}"></js-autocomplete-multi> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="col-lg-3"> |
| | | <div class="form-group"> |
| | | <label> <span translate="issue.issueType">이슈 타입</span></label> |
| | | <ng-dropdown-multiselect class="multiSelect cursor" |
| | | data-input-name="customField.name" |
| | | selected-model="customField.useValues" |
| | | extra-settings="{ 'idProp' : 'value', 'externalIdProp' : 'value', 'displayProp' : 'value', 'stringTypeOption' : 'true', 'stopRemoveBodyEvent' : 'true' }" |
| | | options="::customField.customFieldValueVos"></ng-dropdown-multiselect> |
| | | data-input-name="issueStatuses" |
| | | selected-model="vm.search.issueTypeIds" |
| | | options="::vm.issueTypes"></ng-dropdown-multiselect> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="col-lg-3"> |
| | | <div class="form-group"> |
| | | <label> <span translate="issue.issueStatus">이슈 상태</span></label> |
| | | <ng-dropdown-multiselect class="multiSelect cursor" |
| | | data-input-name="issueStatuses" |
| | | selected-model="vm.search.issueStatusIds" |
| | | options="::vm.issueStatuses"></ng-dropdown-multiselect> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | </div> |
| | | <div class="row"> |
| | | <div class="col-lg-3"> |
| | | <div class="form-group"> |
| | | <label> <span translate="issue.issueNumber">이슈 번호</span></label> |
| | | <input type="text" |
| | | name="name" |
| | | class="form-control input-sm" |
| | | autocomplete="off" |
| | | kr-input |
| | | maxlength="20" |
| | | ng-model="vm.search.combinationIssueNumber"> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="row"> |
| | | <div class="col-sm-12"> |
| | | <div class="form-buttons-w text-center mb-20"> |
| | | <button class="btn btn-xlg btn-navy" ng-click="fn.getPageList(0)"> |
| | | <i class="os-icon os-icon-ui-37"></i> |
| | | <span translate="common.search">검색</span> |
| | | </button> |
| | | <button class="btn btn-xlg btn-white" ng-click="fn.initSearch()"> |
| | | <i class="os-icon os-icon-grid-18"></i> |
| | | <span translate="common.reset">초기화</span> |
| | | </button> |
| | | <div class="col-lg-3"> |
| | | <div class="form-group"> |
| | | <label> <span translate="issue.issueContent">이슈 내용</span></label> |
| | | <input type="text" |
| | | name="description" |
| | | class="form-control input-sm" |
| | | kr-input |
| | | maxlength="20" |
| | | autocomplete="off" |
| | | ng-model="vm.search.description"> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="col-lg-3"> |
| | | <div class="form-group"> |
| | | <label> <span translate="common.priority">우선 순위</span></label> |
| | | <ng-dropdown-multiselect class="multiSelect cursor" |
| | | data-input-name="priorities" |
| | | selected-model="vm.search.priorityIds" |
| | | options="::vm.priorities"></ng-dropdown-multiselect> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="col-lg-3"> |
| | | <div class="form-group"> |
| | | <label> <span translate="common.importance">중요도</span></label> |
| | | <ng-dropdown-multiselect class="multiSelect cursor" |
| | | data-input-name="severities" |
| | | selected-model="vm.search.severityIds" |
| | | options="::vm.severities"></ng-dropdown-multiselect> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="row"> |
| | | <div class="col-lg-3"> |
| | | <div class="form-group"> |
| | | <label> <span translate="common.register">등록자</span></label> |
| | | <js-autocomplete-multi data-input-name="registers" |
| | | selected-model="vm.registers" |
| | | search="vm.registerName" |
| | | input-disabled="false" |
| | | source="fn.getUserList(vm.registerName, vm.registers)" |
| | | translation-texts="{ count : 'common.userNum', empty : 'common.emptyUser' }" |
| | | extra-settings="{ displayProp : 'byName' , idProp : 'id', widthable : false, width : '', imageable : true, imagePathProp : 'profile', type : 'user', maxlength : 100 }"> |
| | | </js-autocomplete-multi> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="col-lg-3"> |
| | | <div class="form-group"> |
| | | <label> <span translate="common.registrationDate">등록일</span></label> |
| | | <input type="text" |
| | | readonly |
| | | class="form-control input-sm input-readonly" |
| | | ng-model="vm.search.registerDateRange" |
| | | modal-form-auto-scroll |
| | | date-format="YY-MM-DD" |
| | | parent-el="'#createdWidget'" |
| | | date-range-picker> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="col-lg-3"> |
| | | <div class="form-group"> |
| | | <label> <span translate="common.startDate">시작일</span></label> |
| | | <input type="text" |
| | | readonly |
| | | class="form-control input-sm input-readonly" |
| | | ng-model="vm.search.startDateRange" |
| | | date-format="YY-MM-DD" |
| | | parent-el="'#createdWidget'" |
| | | date-range-picker> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="col-lg-3"> |
| | | <div class="form-group"> |
| | | <label> <span translate="common.endDate">종료일</span></label> |
| | | <input type="text" |
| | | readonly |
| | | class="form-control input-sm input-readonly" |
| | | ng-model="vm.search.completeDateRange" |
| | | modal-form-auto-scroll |
| | | date-format="YY-MM-DD" |
| | | parent-el="'#createdWidget'" |
| | | date-range-picker> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="col-lg-3"> |
| | | <div class="form-group"> |
| | | <label> <span translate="common.assigneeTeam">담당부서</span></label> |
| | | <js-autocomplete-multi data-input-name="departments" |
| | | selected-model="vm.departments" |
| | | search="vm.departmentName" |
| | | input-disabled="false" |
| | | source="fn.getUserDepartmentList(vm.departmentName, vm.departments)" |
| | | translation-texts="{ count : 'common.userNum', empty : 'common.emptyProjectDepartment' }" |
| | | extra-settings="{ displayProp : 'byName' , idProp : 'id', widthable : false, width : '', imageable : true, imagePathProp : 'profile', type : 'department', maxlength : 100 }"> |
| | | </js-autocomplete-multi> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="col-lg-3" ng-repeat="customField in vm.customFields"> |
| | | <label>{{::customField.name}}</label> |
| | | |
| | | <div ng-switch on="customField.customFieldType"> |
| | | <div ng-switch-when="INPUT"> |
| | | <input type="text" class="form-control input-sm" |
| | | ng-model="customField.useValues" |
| | | maxlength="100"> |
| | | </div> |
| | | |
| | | <div ng-switch-default> |
| | | <ng-dropdown-multiselect class="multiSelect cursor" |
| | | data-input-name="customField.name" |
| | | selected-model="customField.useValues" |
| | | extra-settings="{ 'idProp' : 'value', 'externalIdProp' : 'value', 'displayProp' : 'value', 'stringTypeOption' : 'true', 'stopRemoveBodyEvent' : 'true' }" |
| | | options="::customField.customFieldValueVos"></ng-dropdown-multiselect> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | </div> |
| | | |
| | | <div class="row"> |
| | | <div class="col-sm-12"> |
| | | <div class="form-buttons-w text-center mb-20"> |
| | | <button class="btn btn-xlg btn-navy" ng-click="fn.getPageList(0)"> |
| | | <i class="os-icon os-icon-ui-37"></i> |
| | | <span translate="common.search">검색</span> |
| | | </button> |
| | | <button class="btn btn-xlg btn-white" ng-click="fn.initSearch()"> |
| | | <i class="os-icon os-icon-grid-18"></i> |
| | | <span translate="common.reset">초기화</span> |
| | | </button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </form> |
| | | </form> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="controls-above-table mt-30"> |
| | | <div class="row"> |
| | | <!-- 좌측 --> |
| | |
| | | </select> {{vm.page.selectedPage}}-{{vm.responseData.page.totalPage}} / |
| | | {{vm.responseData.page.totalCount | number}}<span translate="common.few">건</span> |
| | | </label> |
| | | <div class="btn-group ml-2" role="group" aria-label="list-group"> |
| | | <button class="btn" ng-class="{'btn-info': vm.listMode === 0, 'btn-light': vm.listMode !== 0}" ng-click="fn.onClickListMode(0)">List</button> |
| | | <button class="btn" ng-class="{'btn-info': vm.listMode === 1, 'btn-light': vm.listMode !== 1}" ng-click="fn.onClickListMode(1)">Tree</button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <!-- 우측 --> |
| | | <div class="col-5 " > |
| | | <span class="issue-detail-label" style="position: relative; left: 18.8rem; bottom: 5px"><span style="color: #0a7cf8">◆</span> 완료 이슈 숨기기</span> |
| | | <label class='switch' style="left: 19.3rem"><input type='checkbox' ng-model='vm.hideIssue' ng-click='fn.getPageList(0)'> |
| | | <span class='slider round'></span> |
| | | </label> |
| | | |
| | | |
| | | <!-- 우측 --> |
| | | <div class="col-5" > |
| | | <span class="issue-detail-label" style="position: relative; left: 18.8rem; bottom: 5px"><span style="color: #0a7cf8">◆</span> 완료 이슈 숨기기</span> |
| | | <label class='switch' style="left: 19.3rem"><input type='checkbox' ng-model='vm.hideIssue' ng-click='fn.getPageList(0)'> |
| | | <span class='slider round'></span> |
| | | </label> |
| | | <form class="form-inline justify-content-sm-end pull-right" method="post" action="/issue/downloadExcel" name="issueListForm" > |
| | | <!--span class="badge-tip" function-tool-tip data-placement="top" data-toggle="tooltip" data-original-title="엑셀 다운로드, 일괄 변경 등 다양한 기능을 제공합니다.">?</span--> |
| | | <input type="hidden" name="conditions"> |
| | |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="table-responsive"> |
| | | <js-table data="vm.responseData.data" table-configs="vm.tableConfigs" |
| | | <div class="table-responsive" > |
| | | <js-table ng-if="vm.listMode === 0" |
| | | data="vm.responseData.data" table-configs="vm.tableConfigs" |
| | | event="tableEvent" detail-view="vm.detailView"></js-table> |
| | | |
| | | <js-tree ng-if="vm.listMode === 1" |
| | | data="vm.responseData.data" table-configs="vm.tableConfigs" |
| | | event="tableEvent" detail-view="vm.detailView"></js-tree> |
| | | </div> |
| | | <div class="controls-below-table text-center"> |
| | | <ul uib-pagination |
| | | boundary-links-numbes="true" |
| | | items-per-page="vm.page.selectedPageRowCount" |
| | | total-items="vm.responseData.page.totalCount" |
| | | ng-model="vm.page.selectedPage" |
| | | max-size="10" |
| | | ng-click="fn.getPageList(vm.page.selectedPage - 1)" |
| | | class="pagination pagination-sm" |
| | | previous-text="<" |
| | | next-text=">" |
| | | first-text="" |
| | | last-text=""> |
| | | </ul> |
| | | <div class="controls-below-table text-center"> |
| | | <ul uib-pagination |
| | | boundary-links-numbes="true" |
| | | items-per-page="vm.page.selectedPageRowCount" |
| | | total-items="vm.responseData.page.totalCount" |
| | | ng-model="vm.page.selectedPage" |
| | | max-size="10" |
| | | ng-click="fn.getPageList(vm.page.selectedPage - 1)" |
| | | class="pagination pagination-sm" |
| | | previous-text="<" |
| | | next-text=">" |
| | | first-text="" |
| | | last-text=""> |
| | | </ul> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |