From 6adb341db180240e0af34ace40100912d4ed5257 Mon Sep 17 00:00:00 2001 From: 이민희 <mhlee@maprex.co.kr> Date: 목, 06 1월 2022 11:02:57 +0900 Subject: [PATCH] Merge branch 'master' of http://192.168.0.25:9001/r/owl-kisa --- src/main/webapp/scripts/app/project/projectModify.controller.js | 2 src/main/webapp/scripts/app/issue/issue.js | 4 src/main/java/kr/wisestone/owl/web/form/ApiTokenForm.java | 8 src/main/resources/mybatis/query-template/issue-template.xml | 8 src/main/java/kr/wisestone/owl/config/SwaggerConfig.java | 94 ++ src/main/java/kr/wisestone/owl/config/SecurityConfiguration.java | 2 pom.xml | 33 src/main/java/kr/wisestone/owl/web/condition/IssueCustomFieldValueCondition.java | 23 src/main/webapp/custom_components/js-rel/relColumnGenerator.directive.js | 142 +++ src/main/java/kr/wisestone/owl/web/form/ApiIssueAddForm.java | 53 + src/main/java/package-info.java | 4 src/main/webapp/scripts/components/auth/auth.interceptor.js | 10 src/main/webapp/custom_components/js-down/js-down.html | 47 + src/main/java/kr/wisestone/owl/web/controller/Api/ApiController.java | 98 ++ src/main/java/kr/wisestone/owl/web/controller/IssueController.java | 12 src/main/webapp/views/issue/issueSendMailPartners.html | 69 + src/main/webapp/custom_components/js-down/js-down.directive.js | 36 src/main/webapp/scripts/app/issue/issueSendMailPartners.controller.js | 21 src/main/webapp/scripts/main.js | 26 src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java | 36 src/main/java/kr/wisestone/owl/web/form/ApiIssueModifyForm.java | 63 + src/main/webapp/custom_components/js-rel/js-rel.directive.js | 36 src/main/webapp/custom_components/js-down/down.provider.js | 232 +++++ src/main/java/kr/wisestone/owl/web/form/EmailCommonForm.java | 55 + src/main/webapp/scripts/components/issue/issue.service.js | 6 src/main/java/kr/wisestone/owl/constant/MsgConstants.java | 61 + src/main/webapp/scripts/app/issue/issueDetail.controller.js | 202 ++-- src/main/resources/log4j2.xml | 8 src/main/webapp/assets/styles/main.css | 8 /dev/null | 71 - src/main/webapp/views/issue/issueCommonSendMail.html | 69 + src/main/webapp/scripts/app/issue/issueCommonSendMail.controller.js | 111 ++ src/main/webapp/scripts/config.js | 11 src/main/java/kr/wisestone/owl/service/IssueService.java | 3 src/main/java/kr/wisestone/owl/web/controller/ApiTokenController.java | 21 src/main/webapp/custom_components/js-rel/js-rel.html | 47 + src/main/java/kr/wisestone/owl/web/form/IssueApiForm.java | 65 src/main/webapp/scripts/app/issue/issueList.controller.js | 5 src/main/webapp/i18n/ko/global.json | 13 src/main/webapp/views/issue/issueDetail.html | 11 src/main/webapp/custom_components/js-down/downColumnGenerator.directive.js | 141 +++ src/main/webapp/custom_components/js-table/tableColumnGenerator.directive.js | 234 ++-- src/main/webapp/custom_components/js-rel/rel.provider.js | 239 +++++ 43 files changed, 2,048 insertions(+), 392 deletions(-) diff --git a/pom.xml b/pom.xml index 569ef29..b2bb567 100644 --- a/pom.xml +++ b/pom.xml @@ -48,7 +48,7 @@ <!-- Logging --> <slf4j.version>1.7.28</slf4j.version> - <log4j.version>2.12.1</log4j.version> + <log4j.version>2.17.1</log4j.version> <!-- Spring Session Redis --> <spring.session.version>2.1.8.RELEASE</spring.session.version> @@ -67,6 +67,9 @@ <!-- Elastic Search --> <elastic.search.version>7.3.0</elastic.search.version> + + <!-- jsoup --> + <jsoup.version>1.8.3</jsoup.version> <!-- Util --> <jackson.version>2.9.9</jackson.version> @@ -151,6 +154,11 @@ <version>${java.mail.version}</version> </dependency> + <dependency> + <groupId>javax.interceptor</groupId> + <artifactId>javax.interceptor-api</artifactId> + <version>1.2</version> + </dependency> <!-- Excel import --> <dependency> <groupId>org.apache.poi</groupId> @@ -255,6 +263,14 @@ <artifactId>commons-validator</artifactId> <version>${common.validator.version}</version> </dependency> + + <!-- jsoup --> + <dependency> + <groupId>org.jsoup</groupId> + <artifactId>jsoup</artifactId> + <version>${jsoup.version}</version> + </dependency> + <!-- spring --> <dependency> @@ -505,6 +521,17 @@ <version>0.9.1</version> </dependency> + <!-- Swagger(api 臾몄꽌�솕) --> + <dependency> + <groupId>io.springfox</groupId> + <artifactId>springfox-swagger2</artifactId> + <version>2.9.2</version> + </dependency> + <dependency> + <groupId>io.springfox</groupId> + <artifactId>springfox-swagger-ui</artifactId> + <version>2.9.2</version> + </dependency> </dependencies> <repositories> @@ -545,10 +572,6 @@ <url>https://maven.java.net/content/repositories/public/</url> </repository> - <repository> - <id>JBoss repository</id> - <url>http://repository.jboss.org/nexus/content/groups/public/</url> - </repository> </repositories> <build> diff --git a/src/main/java/kr/wisestone/owl/config/SecurityConfiguration.java b/src/main/java/kr/wisestone/owl/config/SecurityConfiguration.java index 62056ea..3df8251 100644 --- a/src/main/java/kr/wisestone/owl/config/SecurityConfiguration.java +++ b/src/main/java/kr/wisestone/owl/config/SecurityConfiguration.java @@ -145,7 +145,9 @@ .antMatchers("/language/change").permitAll() .antMatchers("/security/*").permitAll() .antMatchers("/api/issue").permitAll() + .antMatchers("/api/issue/*").permitAll() .antMatchers("/**/*").authenticated(); + // http.addFilter(new CustomAuthenticationFilter()); // http.addFilterBefore(new CustomAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); diff --git a/src/main/java/kr/wisestone/owl/config/SwaggerConfig.java b/src/main/java/kr/wisestone/owl/config/SwaggerConfig.java new file mode 100644 index 0000000..ab42cb3 --- /dev/null +++ b/src/main/java/kr/wisestone/owl/config/SwaggerConfig.java @@ -0,0 +1,94 @@ +package kr.wisestone.owl.config; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.Parameter; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +/** + * API 臾몄꽌 �젣�옉 �뙣�궎吏� Swagger �꽕�젙 �겢�옒�뒪 + */ +@Configuration +@EnableSwagger2 +public class SwaggerConfig { + + private static final String API_NAME = "OWL API"; + private static final String API_VERSION = "1.0.0"; + private static final String API_DESCRIPTION = "OWL API 紐낆꽭�꽌"; + + + /** + * API �꽕�젙 + * @return docket class + */ + @Bean + public Docket api() { +// Parameter parameterBuilder = new ParameterBuilder() +// .name(HttpHeaders.AUTHORIZATION) +// .description("Access Tocken") +// .modelRef(new ModelRef("string")) +// .parameterType("header") +// .required(false) +// .build(); + + List<Parameter> globalParameters = new ArrayList<>(); +// globalParameters.add(parameterBuilder); + + return new Docket(DocumentationType.SWAGGER_2) + .globalOperationParameters(globalParameters) + .consumes(getConsumeContentTypes()) + .produces(getProduceContentTypes()) + .apiInfo(apiInfo()) + .select() + .apis(RequestHandlerSelectors.basePackage("kr.wisestone.owl.web.controller.Api")) + .paths(PathSelectors.any()) + .build(); + } + + + /** + * API 臾몄꽌 ���씠��/踰꾩쟾/�꽕紐� �꽕�젙 + * @return ApiInfo �겢�옒�뒪 + */ + public ApiInfo apiInfo() { + return new ApiInfoBuilder() + .title(API_NAME) + .version(API_VERSION) + .description(API_DESCRIPTION) + .build(); + } + + + /** + * API 臾몄꽌 �뀒�뒪�듃 Request Content-Type �꽕�젙 異붽� + * @return consumes content-type 紐⑸줉 + */ + private Set<String> getConsumeContentTypes() { + Set<String> consumes = new HashSet<>(); + consumes.add("application/json;charset=UTF-8"); + consumes.add("application/x-www-form-urlencoded"); + return consumes; + } + + /** + * API 臾몄꽌 �뀒�뒪�듃 Response content-type �꽕�젙 異붽� + * @return produce content-type 紐⑸줉 + */ + private Set<String> getProduceContentTypes() { + Set<String> produces = new HashSet<>(); + produces.add("application/json;charset=UTF-8"); + return produces; + } +} \ No newline at end of file diff --git a/src/main/java/kr/wisestone/owl/constant/MsgConstants.java b/src/main/java/kr/wisestone/owl/constant/MsgConstants.java index e581672..b2f6bc2 100644 --- a/src/main/java/kr/wisestone/owl/constant/MsgConstants.java +++ b/src/main/java/kr/wisestone/owl/constant/MsgConstants.java @@ -1,6 +1,7 @@ package kr.wisestone.owl.constant; /** + * exception �슜 硫붿꽭吏� �겢�옒�뒪 * Created by jeong on 2017-08-02. */ public class MsgConstants { @@ -242,16 +243,52 @@ public static final String EMAIL_TEMPLATE_NOT_EXIST = "EMAIL_TEMPLATE_NOT_EXIST"; // �씠硫붿씪 �뀥�뵆由우쓣 李얠쓣�닔 �뾾�뒿�땲�떎. - public static final String API_PARAMETER_ISSUE_TYPE_ERROR = "API_PARAMETER_ISSUE_TYPE_ERROR"; // api �뙆�씪誘명꽣 �삤瑜�(�씠�뒋���엯) - public static final String API_PARAMETER_PROJECT_ERROR = "API_PARAMETER_PROJECT_ERROR"; // api �뙆�씪誘명꽣 �삤瑜�(�봽濡쒖젥�듃) - 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"; // �옄�룞 醫낅즺 泥섎━�븷 �긽�깭媛� �꽕�젙�릺吏� �븡�븯�뒿�땲�떎. - public static final String API_ISSUE_STATUS_NOT_EXIST = "API_ISSUE_STATUS_NOT_EXIST"; // �씠�뒋 �긽�깭瑜� 李얠쓣�닔 �뾾�뒿�땲�떎 - public static final String API_ISSUE_STATUS_IS_NULL = "API_ISSUE_STATUS_IS_NULL"; // �씠�뒋 �긽�깭 媛믪씠 �뾾�뒿�땲�떎. - public static final String API_CUSTOM_FIELD_NOT_EXIST = "API_CUSTOM_FIELD_NOT_EXIST"; // �궗�슜�옄 �젙�쓽 �븘�뱶瑜� 議댁옱�븯吏� �븡�뒿�땲�떎. - public static final String API_ISSUE_STATUS_NOT_IN_WORKFLOW = "API_ISSUE_STATUS_NOT_IN_WORKFLOW"; // �씠�뒋 �긽�깭媛� �썙�겕�뵆濡쒖슦�뿉 �룷�븿�릺�뼱 �엳吏� �븡�뒿�땲�떎 + /** + * api �뙆�씪誘명꽣 �삤瑜�(�씠�뒋���엯) + */ + public static final String API_PARAMETER_ISSUE_TYPE_ERROR = "API_PARAMETER_ISSUE_TYPE_ERROR"; + /** + * api �뙆�씪誘명꽣 �삤瑜�(�봽濡쒖젥�듃) + */ + public static final String API_PARAMETER_PROJECT_ERROR = "API_PARAMETER_PROJECT_ERROR"; + /** + * api �뙆�씪誘명꽣 �삤瑜� + */ + 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"; + /** + * �닔�젙�븷 �씠�뒋瑜� 李얠쓣�닔 �뾾�뒿�땲�떎. + */ + 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"; + /** + * �씠�뒋 �긽�깭瑜� 李얠쓣�닔 �뾾�뒿�땲�떎 + */ + public static final String API_ISSUE_STATUS_NOT_EXIST = "API_ISSUE_STATUS_NOT_EXIST"; + /** + * �씠�뒋 �긽�깭 媛믪씠 �뾾�뒿�땲�떎. + */ + public static final String API_ISSUE_STATUS_IS_NULL = "API_ISSUE_STATUS_IS_NULL"; + /** + * �궗�슜�옄 �젙�쓽 �븘�뱶瑜� 議댁옱�븯吏� �븡�뒿�땲�떎. + */ + public static final String API_CUSTOM_FIELD_NOT_EXIST = "API_CUSTOM_FIELD_NOT_EXIST"; + /** + * �씠�뒋 �긽�깭媛� �썙�겕�뵆濡쒖슦�뿉 �룷�븿�릺�뼱 �엳吏� �븡�뒿�땲�떎 + */ + public static final String API_ISSUE_STATUS_NOT_IN_WORKFLOW = "API_ISSUE_STATUS_NOT_IN_WORKFLOW"; } diff --git a/src/main/java/kr/wisestone/owl/service/IssueService.java b/src/main/java/kr/wisestone/owl/service/IssueService.java index caeca69..c47ce15 100644 --- a/src/main/java/kr/wisestone/owl/service/IssueService.java +++ b/src/main/java/kr/wisestone/owl/service/IssueService.java @@ -9,6 +9,7 @@ import kr.wisestone.owl.web.condition.DepartmentCondition; import kr.wisestone.owl.web.condition.IssueCondition; import kr.wisestone.owl.web.condition.ProjectCondition; +import kr.wisestone.owl.web.form.EmailCommonForm; import kr.wisestone.owl.web.form.EmailTemplateForm; import kr.wisestone.owl.web.form.IssueApiForm; import kr.wisestone.owl.web.form.IssueForm; @@ -112,4 +113,6 @@ void setCountDownIssues(List<IssueVo> issueVos); void makeIssueMapToIssue(Issue issue, Map<String, Object> issueMap); + + void sendCommonEmail(EmailCommonForm make); } diff --git a/src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java b/src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java index b4b9710..7be00d2 100644 --- a/src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java +++ b/src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java @@ -289,7 +289,7 @@ issueApiForm.addUseIssueCustomFieldId(customFieldApiOverlap.getCustomField().getId()); } - // 以묐났�맂 �씠�뒋寃��깋 + // 醫낅즺�긽�깭媛� �븘�땶 以묐났�맂 �긽�쐞 �씠�뒋寃��깋 List<Issue> issues = this.findIssue(issueApiForm, customFieldApiOverlaps, user.getId()); int size = issues.size(); if (size > 0) { @@ -446,6 +446,7 @@ issueCustomFieldValueCondition.setUseValue(concatUseValue); issueCustomFieldValueCondition.setUseValues(userValues); issueCustomFieldValueCondition.setIssueTypeId(issueApiform.getIssueTypeId()); + issueCustomFieldValueCondition.setIssueStatusType("CLOSE"); List<Map<String, Object>> results = this.issueMapper.findByCustomFieldValue(issueCustomFieldValueCondition); if (results != null && results.size() > 0) { for (Map<String, Object> result : results) { @@ -944,7 +945,7 @@ // if (!this.userWorkspaceService.checkWorkspaceManager(user) // && !MngPermission.checkMngPermission(userLevel.getPermission(), MngPermission.USER_PERMISSION_MNG_ISSUE)) { //理쒓퀬愿�由ъ옄 & �봽濡쒖젥�듃,�씠�뒋 愿�由ъ옄 �씪 寃쎌슦 紐⑤뱺 �씠�뒋 蹂닿린 // this.SetMyDepartmentId(issueCondition); - //this.SetAllDepartmentId(issueCondition); + //this.SetAllDepartmentId(issueCondition); // } /*else{ // results = this.issueMapper.findByDepartment(issueCondition); // totalCount = this.issueMapper.countByDepartment(issueCondition); @@ -3593,6 +3594,37 @@ this.issueHistoryService.addIssueHistory(issue, IssueHistoryType.SEND, sb.toString()); } + @Override + public void sendCommonEmail(EmailCommonForm emailCommonForm) { + if (emailCommonForm.getSendEmails().size() < 1) { + throw new OwlRuntimeException( + this.messageAccessor.getMessage(MsgConstants.ISSUE_NOT_SEND_USER)); + } else if (emailCommonForm.getIssueId() == null) { + throw new OwlRuntimeException( + this.messageAccessor.getMessage(MsgConstants.ISSUE_NOT_EXIST)); + } + + Issue issue = this.getIssue(emailCommonForm.getIssueId()); + + // 諛쒖떊�옄 �몴�떆 + User user = this.webAppUtil.getLoginUserObject(); + UserVo toUser = this.webAppUtil.getLoginUser(); + + // �궗�슜�옄 �떆�뒪�뀥 湲곕뒫 �궗�슜 �젙蹂� �닔吏� + log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(this.webAppUtil.getLoginUser(), ElasticSearchConstants.ISSUE_ANOTHER_USER_SEND_EMAIL)); + StringBuilder sb = new StringBuilder(); + + Locale locale = CommonUtil.getUserLanguage(user.getLanguage()); + String[] sendMails = ConvertUtil.ToArray(emailCommonForm.getSendEmails()); + for(int i=0; i < sendMails.length; i++) { + sendMails[i] = CommonUtil.decryptAES128(sendMails[i]); + } + this.systemEmailService.sendEmail(emailCommonForm.getTitle(), emailCommonForm.getDescription(), sendMails, null); + + this.issueHistoryService.detectSendIssueMail(IssueHistoryType.SEND, emailCommonForm.getSendEmails(), sb); + this.issueHistoryService.addIssueHistory(issue, IssueHistoryType.SEND, sb.toString()); + } + // �삁�빟 諛쒖깮 �씠�뒋瑜� �떎�뻾�븳�떎 @Override @Transactional diff --git a/src/main/java/kr/wisestone/owl/web/condition/IssueCustomFieldValueCondition.java b/src/main/java/kr/wisestone/owl/web/condition/IssueCustomFieldValueCondition.java index 063557f..5475ac0 100644 --- a/src/main/java/kr/wisestone/owl/web/condition/IssueCustomFieldValueCondition.java +++ b/src/main/java/kr/wisestone/owl/web/condition/IssueCustomFieldValueCondition.java @@ -10,6 +10,7 @@ import java.util.Map; /** + * �씠�뒋 �궗�슜�옄 �젙�쓽 �븘�뱶 媛� 寃��깋 議곌굔 �겢�옒�뒪 * Created by wisestone on 2018-06-07. */ public class IssueCustomFieldValueCondition { @@ -17,9 +18,19 @@ private Long workspaceId; private Long customFieldId; private String customFieldType; - private List<String> useValues = Lists.newArrayList(); // �떒�씪, �떎以� �씪�븣 寃��깋 媛� - private String useValue; // �뀓�뒪�듃 �븘�뱶�씪 �븣 寃��깋 媛� + /** + * �궗�슜�옄 �젙�쓽 �븘�뱶 �궗�슜 媛� + */ + private List<String> useValues = Lists.newArrayList(); + /** + * �뀓�뒪�듃 �븘�뱶�씪 �븣 寃��깋 媛� + */ + private String useValue; private boolean useParentIssueId = true; + /** + * �씠�뒋 �긽�깭 �쑀�삎(READY / OPEN / CLOSE) + */ + private String issueStatusType; public IssueCustomFieldValueCondition(){} @@ -62,6 +73,14 @@ return condition; } + public String getIssueStatusType() { + return issueStatusType; + } + + public void setIssueStatusType(String issueStatusType) { + this.issueStatusType = issueStatusType; + } + public Long getIssueTypeId() { return issueTypeId; } diff --git a/src/main/java/kr/wisestone/owl/web/controller/Api/ApiController.java b/src/main/java/kr/wisestone/owl/web/controller/Api/ApiController.java new file mode 100644 index 0000000..0fbbf81 --- /dev/null +++ b/src/main/java/kr/wisestone/owl/web/controller/Api/ApiController.java @@ -0,0 +1,98 @@ +package kr.wisestone.owl.web.controller.Api; + +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import kr.wisestone.owl.constant.MsgConstants; +import kr.wisestone.owl.domain.Issue; +import kr.wisestone.owl.exception.OwlRuntimeException; +import kr.wisestone.owl.service.IssueService; +import kr.wisestone.owl.util.ConvertUtil; +import kr.wisestone.owl.web.controller.BaseController; +import kr.wisestone.owl.web.form.ApiIssueAddForm; +import kr.wisestone.owl.web.form.ApiIssueModifyForm; +import kr.wisestone.owl.web.form.IssueApiForm; +import org.json.simple.parser.ParseException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * OWL-API 而⑦듃濡ㅻ윭 + */ +@Controller +@RequestMapping("/api") +public class ApiController extends BaseController { + + @Autowired + private IssueService issueService; + + + /** + * �씠�뒋 異붽� + * @param apiIssueAddForm �엯�젰 �뤌 �뜲�씠�꽣 + * @param files �뙆�씪 + * @return JSON + * @throws OwlRuntimeException �뙆�씪誘명꽣 �삤瑜섏떆 諛쒖깮 + * @throws CloneNotSupportedException �씠�뒋 蹂듭궗 �떆�뿉 諛쒖깮 + */ + @PostMapping(value = "/issue") + @ApiOperation(value = "�씠�뒋 異붽�", notes = "�깉濡쒖슫 �씠�뒋瑜� 異붽��븳�떎.") + @ApiImplicitParam(name = "files", required = false, dataType = "file") + public + @ResponseBody + Map<String, Object> addIssue(ApiIssueAddForm apiIssueAddForm, @RequestParam("files") List<MultipartFile> files) throws OwlRuntimeException, CloneNotSupportedException, ParseException { + Map<String, Object> resJsonData = new HashMap<>(); + + IssueApiForm issueApiForm = ConvertUtil.copyProperties(apiIssueAddForm, IssueApiForm.class); +// String str = request.getParameter(Constants.REQ_KEY_CONTENT); + issueApiForm.setMultipartFiles(files); + issueApiForm.parseCustomFields(apiIssueAddForm.getCustomFields()); + issueApiForm.setApiType(IssueApiForm.ApiType.add); + // �궗�슜�옄 �젙�쓽 �븘�뱶媛� �뾾�쓣 寃쎌슦 寃��깋�쓣 �븷 �닔 �뾾湲� �븣臾몄뿉 �삁�쇅泥섎━ + if (issueApiForm.getCustomFieldValues() == null || issueApiForm.getCustomFieldValues().size() == 0) { + throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.API_CUSTOM_FIELD_NOT_EXIST)); + } + + List<Issue> issues = this.issueService.addApiIssue(issueApiForm); + // 踰꾩쟾 �깮�꽦 + for (Issue issue : issues) { + this.issueService.addIssueVersion(issue.getId(), issue.getRegisterId()); + } + + return this.setSuccessMessage(resJsonData); + } + + /** + * �씠�뒋 �긽�깭 �닔�젙 + * @param apiIssueModifyForm �닔�젙 �뤌 �뜲�씠�꽣 + * @return JSON + * @throws OwlRuntimeException �뙆�씪誘명꽣 �삤瑜섏떆 諛쒖깮 + * @throws CloneNotSupportedException �씠�뒋 蹂듭궗 �떆�뿉 諛쒖깮 + */ + @PostMapping(value = "/issue/1") + @ApiOperation(value = "�씠�뒋 �긽�깭 �닔�젙", notes = "�궗�슜�옄 �젙�쓽 �븘�뱶媛� �룞�씪�븳 湲곗〈 �씠�뒋瑜� 蹂�寃쏀븳�떎.") + public + @ResponseBody + Map<String, Object> modifyIssue(ApiIssueModifyForm apiIssueModifyForm) throws OwlRuntimeException, CloneNotSupportedException, ParseException { + Map<String, Object> resJsonData = new HashMap<>(); + + IssueApiForm issueApiForm = ConvertUtil.copyProperties(apiIssueModifyForm, IssueApiForm.class); + issueApiForm.parseCustomFields(apiIssueModifyForm.getCustomFields()); + issueApiForm.setApiType(IssueApiForm.ApiType.add); + // �궗�슜�옄 �젙�쓽 �븘�뱶媛� �뾾�쓣 寃쎌슦 寃��깋�쓣 �븷 �닔 �뾾湲� �븣臾몄뿉 �삁�쇅泥섎━ + if (issueApiForm.getCustomFieldValues() == null || issueApiForm.getCustomFieldValues().size() == 0) { + throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.API_CUSTOM_FIELD_NOT_EXIST)); + } + + this.issueService.modifyIssue(issueApiForm, new ArrayList<>()); + + return this.setSuccessMessage(resJsonData); + } +} + diff --git a/src/main/java/kr/wisestone/owl/web/controller/ApiController.java b/src/main/java/kr/wisestone/owl/web/controller/ApiController.java deleted file mode 100644 index 5c13abc..0000000 --- a/src/main/java/kr/wisestone/owl/web/controller/ApiController.java +++ /dev/null @@ -1,71 +0,0 @@ -package kr.wisestone.owl.web.controller; - -import kr.wisestone.owl.constant.Constants; -import kr.wisestone.owl.constant.MsgConstants; -import kr.wisestone.owl.domain.Issue; -import kr.wisestone.owl.exception.OwlRuntimeException; -import kr.wisestone.owl.service.IssueService; -import kr.wisestone.owl.util.ConvertUtil; -import kr.wisestone.owl.web.form.IssueApiForm; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.multipart.MultipartHttpServletRequest; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@Controller -public class ApiController extends BaseController { - - @Autowired - private IssueService issueService; - - @RequestMapping(value = "api/issue", method = RequestMethod.POST) - public - @ResponseBody - Map<String, Object> addIssue(MultipartHttpServletRequest request) throws OwlRuntimeException, CloneNotSupportedException { - Map<String, Object> resJsonData = new HashMap<>(); - - String str = request.getParameter(Constants.REQ_KEY_CONTENT); - - IssueApiForm issueForm = IssueApiForm.make(ConvertUtil.convertJsonToMap(str), request.getFiles("file")); - if (issueForm == null) { - throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.API_PARAMETER_ERROR)); - } - // �궗�슜�옄 �젙�쓽 �븘�뱶媛� �뾾�쓣 寃쎌슦 寃��깋�쓣 �븷 �닔 �뾾湲� �븣臾몄뿉 �삁�쇅泥섎━ - else if (issueForm.getCustomFieldValues() == null || issueForm.getCustomFieldValues().size() == 0) { - throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.API_CUSTOM_FIELD_NOT_EXIST)); - } - - if (issueForm.getApiType() == IssueApiForm.ApiType.add) { - List<Issue> issues = this.issueService.addApiIssue(issueForm); - // 踰꾩쟾 �깮�꽦 - for (Issue issue : issues) { - this.issueService.addIssueVersion(issue.getId(), issue.getRegisterId()); - } - } else { - - - this.issueService.modifyIssue(issueForm, request.getFiles("file")); - } - - return this.setSuccessMessage(resJsonData); - } - - // �씠�뒋 議고쉶 -// @RequestMapping(value = "/api/issueList", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) -// public -// @ResponseBody -// Map<String, Object> find(@RequestBody Map<String, Map<String, Object>> params) { -// Map<String, Object> resJsonData = new HashMap<>(); -// Pageable pageable = this.pageUtil.convertPageable(this.getPageVo(params)); -// -// // todo -// return this.setSuccessMessage(resJsonData); -// } -} - diff --git a/src/main/java/kr/wisestone/owl/web/controller/ApiTokenController.java b/src/main/java/kr/wisestone/owl/web/controller/ApiTokenController.java index 6e45b8a..625f7c6 100644 --- a/src/main/java/kr/wisestone/owl/web/controller/ApiTokenController.java +++ b/src/main/java/kr/wisestone/owl/web/controller/ApiTokenController.java @@ -6,6 +6,7 @@ import kr.wisestone.owl.util.ConvertUtil; import kr.wisestone.owl.vo.ApiTokenVo; import kr.wisestone.owl.web.condition.ApiTokenCondition; +import kr.wisestone.owl.web.controller.BaseController; import kr.wisestone.owl.web.form.ApiTokenForm; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Pageable; @@ -20,13 +21,20 @@ import java.util.List; import java.util.Map; +/** + * API �넗�겙 而⑦듃濡ㅻ윭 �겢�옒�뒪 + */ @Controller public class ApiTokenController extends BaseController { @Autowired private ApiTokenService apiTokenService; - // �넗�겙 �깮�꽦 + /** + * �넗�겙 �깮�꽦 + * @param params �넗�겙 �깮�꽦�뿉 �븘�슂�븳 �뙆�씪誘명꽣 + * @return �깮�꽦 寃곌낵 Map<String, Object> + */ @RequestMapping(value = "/apiToken/add", produces = MediaType.APPLICATION_JSON_VALUE) public @ResponseBody @@ -41,6 +49,12 @@ return this.setSuccessMessage(resJsonData); } + + /** + * �넗�겙 議고쉶 + * @param params �넗�겙 議고쉶�뿉 �븘�슂�븳 �뙆�씪誘명꽣 + * @return 議고쉶 寃곌낵, Map<String, ApiTokenVo> + */ // �넗�겙 議고쉶 @RequestMapping(value = "/apiToken/find", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) public @@ -55,6 +69,11 @@ return this.setSuccessMessage(resJsonData); } + /** + * �넗�겙 �궘�젣 + * @param params �넗�겙 �궘�젣�뿉 �븘�슂�븳 �뙆�씪誘명꽣 + * @return �궘�젣 寃곌낵, Map<String, Object> + */ // �넗�겙 �궘�젣 @RequestMapping(value = "/apiToken/remove", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) public diff --git a/src/main/java/kr/wisestone/owl/web/controller/IssueController.java b/src/main/java/kr/wisestone/owl/web/controller/IssueController.java index dd0da5f..ff92657 100644 --- a/src/main/java/kr/wisestone/owl/web/controller/IssueController.java +++ b/src/main/java/kr/wisestone/owl/web/controller/IssueController.java @@ -7,6 +7,7 @@ import kr.wisestone.owl.web.condition.ApiMonitorCondition; import kr.wisestone.owl.web.condition.DepartmentCondition; import kr.wisestone.owl.web.condition.IssueCondition; +import kr.wisestone.owl.web.form.EmailCommonForm; import kr.wisestone.owl.web.form.EmailTemplateForm; import kr.wisestone.owl.web.form.IssueForm; import org.slf4j.Logger; @@ -248,6 +249,17 @@ } + // �씪諛� 硫붿씪 諛쒖넚 (�궗�슜�옄 吏곸젒 �옉�꽦) + @RequestMapping(value = "/issue/sendCommonEmail", produces = MediaType.APPLICATION_JSON_VALUE) + public + @ResponseBody + Map<String, Object> sendCommonEmail(@RequestBody Map<String, Map<String, Object>> params) { + Map<String, Object> resJsonData = new HashMap<>(); + this.issueService.sendCommonEmail(EmailCommonForm.make(params.get(Constants.REQ_KEY_CONTENT))); + return this.setSuccessMessage(resJsonData); + } + + // api 湲곕줉 議고쉶 @RequestMapping(value = "/api/findHistory", produces = MediaType.APPLICATION_JSON_VALUE) public diff --git a/src/main/java/kr/wisestone/owl/web/form/ApiIssueAddForm.java b/src/main/java/kr/wisestone/owl/web/form/ApiIssueAddForm.java new file mode 100644 index 0000000..9a8d273 --- /dev/null +++ b/src/main/java/kr/wisestone/owl/web/form/ApiIssueAddForm.java @@ -0,0 +1,53 @@ +package kr.wisestone.owl.web.form; + +import io.swagger.annotations.ApiParam; + + +/** + * API �씠�뒋 異붽��슜 Form class + */ +public class ApiIssueAddForm { + @ApiParam(value = "�궗�슜�옄 �넗�겙", required = true) + private String token; + @ApiParam(value = "�씠�뒋 �젣紐�") + private String title; + @ApiParam(value = "�씠�뒋 ���엯 ID", required = true) + private Long issueTypeId; + @ApiParam(value = "�궗�슜�옄 �젙�쓽 �븘�뱶", required = true) + private String customFields; + + public ApiIssueAddForm() { + } + + public String getCustomFields() { + return customFields; + } + + public void setCustomFields(String customFields) { + this.customFields = customFields; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public Long getIssueTypeId() { + return issueTypeId; + } + + public void setIssueTypeId(Long issueTypeId) { + this.issueTypeId = issueTypeId; + } +} diff --git a/src/main/java/kr/wisestone/owl/web/form/ApiIssueModifyForm.java b/src/main/java/kr/wisestone/owl/web/form/ApiIssueModifyForm.java new file mode 100644 index 0000000..4a3be36 --- /dev/null +++ b/src/main/java/kr/wisestone/owl/web/form/ApiIssueModifyForm.java @@ -0,0 +1,63 @@ +package kr.wisestone.owl.web.form; + +import io.swagger.annotations.ApiParam; + + +/** + * API �씠�뒋 �긽�깭 �닔�젙�슜 Form class + */ +public class ApiIssueModifyForm { + @ApiParam(value = "�궗�슜�옄 �넗�겙", required = true) + private String token; + @ApiParam(value = "�씠�뒋 ���엯 ID", required = true) + private Long issueTypeId; + @ApiParam(value = "�씠�뒋 �긽�깭 ID", required = true) + private Long issueStatusId; + @ApiParam(value = "�뙎湲�", required = true) + private String comment; + @ApiParam(value = "�궗�슜�옄 �젙�쓽 �븘�뱶", required = true) + private String customFields; + + public ApiIssueModifyForm() { + } + + public Long getIssueTypeId() { + return issueTypeId; + } + + public void setIssueTypeId(Long issueTypeId) { + this.issueTypeId = issueTypeId; + } + + public Long getIssueStatusId() { + return issueStatusId; + } + + public void setIssueStatusId(Long issueStatusId) { + this.issueStatusId = issueStatusId; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + public String getComment() { + return comment; + } + + public void setComment(String comment) { + this.comment = comment; + } + + public String getCustomFields() { + return customFields; + } + + public void setCustomFields(String customFields) { + this.customFields = customFields; + } +} diff --git a/src/main/java/kr/wisestone/owl/web/form/ApiTokenForm.java b/src/main/java/kr/wisestone/owl/web/form/ApiTokenForm.java index ab0b978..281ddea 100644 --- a/src/main/java/kr/wisestone/owl/web/form/ApiTokenForm.java +++ b/src/main/java/kr/wisestone/owl/web/form/ApiTokenForm.java @@ -1,13 +1,11 @@ package kr.wisestone.owl.web.form; -import com.google.common.collect.Lists; import kr.wisestone.owl.domain.User; -import kr.wisestone.owl.util.ConvertUtil; -import kr.wisestone.owl.util.MapUtil; -import java.util.List; -import java.util.Map; +/** + * API �넗�겙 Form class + */ public class ApiTokenForm { private Long id; private User user; diff --git a/src/main/java/kr/wisestone/owl/web/form/EmailCommonForm.java b/src/main/java/kr/wisestone/owl/web/form/EmailCommonForm.java new file mode 100644 index 0000000..bc7d803 --- /dev/null +++ b/src/main/java/kr/wisestone/owl/web/form/EmailCommonForm.java @@ -0,0 +1,55 @@ +package kr.wisestone.owl.web.form; + +import com.google.common.collect.Lists; +import kr.wisestone.owl.util.ConvertUtil; +import kr.wisestone.owl.util.MapUtil; + +import java.util.List; +import java.util.Map; + +public class EmailCommonForm { + private List<String> sendEmails = Lists.newArrayList(); + private String title; + private String description; + private Long issueId; + + public static EmailCommonForm make(Map<String, Object> params) { + EmailCommonForm emailCommonForm = ConvertUtil.convertMapToClass(params, EmailCommonForm.class); + if (MapUtil.getStrings(params, "sendEmails") != null) { + emailCommonForm.setSendEmails(MapUtil.getStrings(params, "sendEmails")); + } + return emailCommonForm; + } + + public List<String> getSendEmails() { + return sendEmails; + } + + public void setSendEmails(List<String> sendEmails) { + this.sendEmails = sendEmails; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Long getIssueId() { + return issueId; + } + + public void setIssueId(Long issueId) { + this.issueId = issueId; + } +} diff --git a/src/main/java/kr/wisestone/owl/web/form/IssueApiForm.java b/src/main/java/kr/wisestone/owl/web/form/IssueApiForm.java index aaab370..9ab2b02 100644 --- a/src/main/java/kr/wisestone/owl/web/form/IssueApiForm.java +++ b/src/main/java/kr/wisestone/owl/web/form/IssueApiForm.java @@ -4,10 +4,13 @@ import kr.wisestone.owl.util.ConvertUtil; import kr.wisestone.owl.util.MapUtil; import org.springframework.web.multipart.MultipartFile; - +import java.io.Serializable; import java.util.*; -public class IssueApiForm { +/** + * API �씠�뒋 異붽� / �닔�젙�슜 form class + */ +public class IssueApiForm implements Serializable { public enum ApiType { add, @@ -37,44 +40,30 @@ public IssueApiForm() { } - public static IssueApiForm make(Map<String, Object> content, List<MultipartFile> files) { - IssueApiForm form = ConvertUtil.convertMapToClass(content, IssueApiForm.class); - form.setMultipartFiles(files); - // api ���엯 - if (MapUtil.getString(content, "apiType") != null) { - try { - form.setApiType(ApiType.valueOf(MapUtil.getString(content, "apiType"))); - } catch (Exception ex) { - return null; - } + /** + * �궗�슜�옄 �젙�쓽 �븘�뱶 蹂��솚 + * @param customFieldJson �궗�슜�옄 �젙�쓽 �븘�뱶 json + */ + public void parseCustomFields(String customFieldJson) { + + Map<String, Object> json = ConvertUtil.convertJsonToMap(customFieldJson); + List<Map<String, Object>> customFields = (List) MapUtil.getObject(json, "customFields"); + for (Map<String, Object> customField : customFields) { + IssueCustomFieldValueForm issueCustomFieldValueForm = ConvertUtil.convertMapToClass(customField, IssueCustomFieldValueForm.class); + this.addIssueCustomFieldValue(issueCustomFieldValueForm); + + Map<String, Object> customFieldVo = new HashMap<>(); + customFieldVo.put("id", issueCustomFieldValueForm.getCustomFieldId()); + + customField.put("customFieldVo", customFieldVo); + + List<String> useValues = Lists.newArrayList(); + useValues.add(issueCustomFieldValueForm.getUseValue()); + customField.put("useValues", useValues); + + this.addCustomFieldValue(customField); } - - // �궗�슜�옄 �븘�뱶 �젙蹂� - if (MapUtil.getObject(content, "customFields") != null){ - List<Map<String, Object>> customFields = (List)MapUtil.getObject(content, "customFields"); - for (Map<String, Object> customField : customFields) { - IssueCustomFieldValueForm issueCustomFieldValueForm = ConvertUtil.convertMapToClass(customField, IssueCustomFieldValueForm.class); - form.addIssueCustomFieldValue(issueCustomFieldValueForm); - - Map<String, Object> customFieldVo = new HashMap<>(); - customFieldVo.put("id", issueCustomFieldValueForm.getCustomFieldId()); - - customField.put("customFieldVo", customFieldVo); - - List<String> useValues = Lists.newArrayList(); - useValues.add(issueCustomFieldValueForm.getUseValue()); - customField.put("useValues", useValues); - - form.addCustomFieldValue(customField); - } - } - - // 泥⑤� �뙆�씪 -// if (MapUtil.getObject(content, "files") != null){ -// form.setFiles((List)MapUtil.getObject(content, "files")); -// } - return form; } public String getToken() { diff --git a/src/main/java/package-info.java b/src/main/java/package-info.java new file mode 100644 index 0000000..dbb8cd6 --- /dev/null +++ b/src/main/java/package-info.java @@ -0,0 +1,4 @@ +/** + * OWL-ITS + */ +package kr.wisestone.owl; \ No newline at end of file diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml index e0dc65b..5f166fd 100644 --- a/src/main/resources/log4j2.xml +++ b/src/main/resources/log4j2.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<Configuration status="warn" name="owl-its" monitorInterval="600"> +<Configuration status="ERROR" name="owl-its" monitorInterval="600"> <Properties> <Property name="LOG_FORMAT">%d{yyyy-MM-dd HH:mm:ss} [%level] - %msg%n</Property> <Property name="BASE_DIR">/owl-enterprise-logs</Property> @@ -50,6 +50,12 @@ <AppenderRef ref="File"/> </Logger> + <!-- Crawling Logger --> + <Logger name="kr.wisestone.owl.crawling" level="debug" additivity="false"> + <AppenderRef ref="Console"/> + <AppenderRef ref="File"/> + </Logger> + <!-- Root Loggers --> <Root level="warn"> <AppenderRef ref="Console"/> diff --git a/src/main/resources/mybatis/query-template/issue-template.xml b/src/main/resources/mybatis/query-template/issue-template.xml index 6dc1b5a..8685b96 100644 --- a/src/main/resources/mybatis/query-template/issue-template.xml +++ b/src/main/resources/mybatis/query-template/issue-template.xml @@ -1115,8 +1115,12 @@ </when> </choose> ) customFieldValue ON customFieldValue.issueId = issue.id - WHERE issStatus.issue_status_type != 'CLOSE' - AND issue.issue_type_id = #{issueTypeId} + WHERE issue.issue_type_id = #{issueTypeId} + <choose> + <when test="issueStatusType != null"> + AND issStatus.issue_status_type != #{issueStatusType} + </when> + </choose> GROUP BY issue.id HAVING concatUseValue LIKE CONCAT('%', #{useValue}, '%') </select> diff --git a/src/main/webapp/assets/styles/main.css b/src/main/webapp/assets/styles/main.css index 98f700e..bedb35f 100644 --- a/src/main/webapp/assets/styles/main.css +++ b/src/main/webapp/assets/styles/main.css @@ -11310,6 +11310,14 @@ font-size: 0.79rem; } +.select3-selection__email__remove { + color: #0066ff; + margin-left: 8px; + margin-top: 7px; + cursor: pointer; + font-size: 0.79rem; +} + .select4-selection__choice { font-size: 0.66rem; letter-spacing: -0.01em; diff --git a/src/main/webapp/custom_components/js-down/down.provider.js b/src/main/webapp/custom_components/js-down/down.provider.js new file mode 100644 index 0000000..7eb0bf3 --- /dev/null +++ b/src/main/webapp/custom_components/js-down/down.provider.js @@ -0,0 +1,232 @@ +'use strict'; + +define(['app', 'angular'], + function (app, angular) { + app.provider("$downProvider", 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 : "", // 而щ읆 �젙蹂대�� 異붿텧�븯湲� �쐞�븳 �엺�듃 �젙蹂대�� 以��떎 - downColumnGenerator �쓽 �궗�슜�옄 �젙�쓽 �븘�뱶 遺�遺꾩뿉�꽌 �궗�슜 + columnTooltip : "", // hover �떆 �댋�똻 蹂댁뿬二쇨린 + 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; + }, + setColumnTooltip : function (hTooltip) { + this.columnTooltip = hTooltip; + return this; + } + }; + + return tableConfig; + }, + toggleChecked : function (checkStatus, datas) { + // �쟾泥� �꽑�깮 泥댄겕 諛뺤뒪瑜� �겢由��뻽�쓣 寃쎌슦 + angular.forEach(datas, function (data) { + 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; + } + } + } + } + }); + }); diff --git a/src/main/webapp/custom_components/js-down/downColumnGenerator.directive.js b/src/main/webapp/custom_components/js-down/downColumnGenerator.directive.js new file mode 100644 index 0000000..2d070fb --- /dev/null +++ b/src/main/webapp/custom_components/js-down/downColumnGenerator.directive.js @@ -0,0 +1,141 @@ +'use strict'; + +define(['app', 'angular'], + function (app, angular) { + + app.directive('downColumnGenerator', ['$compile', '$log', '$rootScope', '$downProvider', '$filter', + function ($compile, $log, $rootScope, $downProvider, $filter) { + return { + restrict : "A", + compile : function (tElement, tAttrs) { + return function (scope, element, attrs) { + scope.data = scope[attrs["downColumnGenerator"]]; + + var myData = scope.data; + var makeTag = ""; + + scope.tableConfigs.forEach(function (tableConfig, index) { + + if (tableConfig.colSpan > 0) { + return; + } + + // �븯�쐞 �떒怨� �몴�떆 異붽� + var myToken = ""; + if ( scope.data.depth > 0) { + for(var i=0; i<scope.data.depth; i++) { + if (i == scope.data.depth - 1) { + myToken += treeStartToken; + } else { + myToken += " "; + } + } + myToken += " "; + } + + makeTag = '<td 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.$downProvider.rowChecked(tableConfigs, data, fn.getResponseData())">'; + } + else {*/ + makeTag += '<input type="checkbox" ng-checked="data.checked == true ? true : false" ng-click="$root.$downProvider.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.$downProvider.rowChecked(tableConfigs, data, fn.getResponseData())">'; + } + else if (tableConfig.dType === "renderer") { + // �옖�뜑�윭 �씪�븣 + switch (tableConfig.dRenderer) { + + // �븯�쐞 �씠�뒋 �씠�룞(�젣紐�) + case "ISSUE_DOWN_MOVE" : + makeTag += "<span class=\"titlename cursor\" ng-click=\"event.changeDetailView(data)\">" + scope.data.title + "</span></a>"; + break; + + // �븯�쐞 �씠�뒋 ���엯 + case "ISSUE_DOWN_STATUS_TYPE" : + makeTag += "<span class='badge' ng-style='{ \"background-color\" : \"" + scope.data.issueStatusVo.color + "\"," + "\"border-color\"" + " : \"" + scope.data.issueStatusVo.color + "\", \"color\": \"#FFFFFF\" }'>" + scope.data.issueStatusVo.name + "</span>"; + break; + + // �븯�쐞 �씠�뒋 �궘�젣 + case "ISSUE_DOWN_DELETE": + if (scope.data.modifyPermissionCheck) { + makeTag += '<img class="cursor" src="/assets/images/delete-icon.png" ng-click="event.removeDownIssue(data.id)">'; + } + break; + + // �븯�쐞 �씠�뒋 �슦�꽑 �닚�쐞 + case "DOWN_COMMON_PRIORITY" : + makeTag += "<span class='badge' ng-style='{ \"background-color\" : \"" + scope.data.priorityVo.color + "\"," + "\"border-color\"" + " : \"" + scope.data.priorityVo.color + "\", \"color\": \"#FFFFFF\" }' translate='" + scope.data.priorityVo.name + "'></span>"; + break; + + // �븯�쐞 �씠�뒋 以묒슂�룄 + case "DOWN_COMMON_SEVERITY" : + makeTag += "<span class='badge' ng-style='{ \"background-color\" : \"" + scope.data.severityVo.color + "\"," + "\"border-color\"" + " : \"" + scope.data.severityVo.color + "\", \"color\": \"#FFFFFF\" }' translate='" + scope.data.severityVo.name + "'></span>"; + break; + + // �븯�쐞 �씠�뒋 �떞�떦遺��꽌 + case "DOWN_ISSUE_DEPARTMENT" : + makeTag += "<ul class='ul-not-comma'>"; + makeTag += "<div style='color: #000000'>"; + angular.forEach(scope.data.departmentVos, function (departments) { + makeTag += "<li>" + departments.departmentName + "</li>"; + }); + makeTag += "</div>"; + makeTag += "</ul>"; + break; + + // �븯�쐞 �씠�뒋 �벑濡앹옄 + case "DOWN_REGISTER": + scope.data.registerVos = [scope.data.registerVo]; + makeTag += '<div owl-profile-over class="" table-user-image="data" target="registerVos"></div>'; + break; + + // �븯�쐞 �씠�뒋 湲곌컙 + case "DOWN_ISSUE_DUE_DATE" : + if (!$rootScope.isDefined(scope.data.startDate) && !$rootScope.isDefined(scope.data.completeDate)) { + makeTag += "<span translate='common.noDate'>湲곌컙 �뾾�쓬</span>"; + } + else { + makeTag += "<span>" + scope.data.startDate + " ~ " + scope.data.completeDate + "</span>"; + } + break; + + // �븯�쐞 �씠�뒋 �궗�슜�옄 �젙�쓽 �븘�뱶 + case "DOWN_ISSUE_CUSTOM_FIELD_VALUE_VIEW" : + var values = []; + + for (var count in scope.data.issueCustomFieldValueVos) { + var issueCustomFieldValueVo = scope.data.issueCustomFieldValueVos[count]; + // �뀒�씠釉� �꽕�젙�뿉�꽌 dName 遺�遺꾩뿉 �궗�슜�옄 �젙�쓽 �븘�뱶 id 瑜� �꽔怨� �빐�떦 媛믪쓣 異붿텧�븳�떎. + if (tableConfig.columnHint.id == issueCustomFieldValueVo.customFieldVo.id) { + values.push(issueCustomFieldValueVo.useValue); + } + } + angular.forEach(values, function (value) { + makeTag += '<span class="table-word-break-all">' + value + '<span><br>'; + }); + + break; + } + } + + makeTag += '</td>'; + + var linkFn = $compile(makeTag); + var content = linkFn(scope); + + element.append(content); + }); + } + } + } + }]); + }); diff --git a/src/main/webapp/custom_components/js-down/js-down.directive.js b/src/main/webapp/custom_components/js-down/js-down.directive.js new file mode 100644 index 0000000..f456e55 --- /dev/null +++ b/src/main/webapp/custom_components/js-down/js-down.directive.js @@ -0,0 +1,36 @@ +'use strict'; + +define(['app'], + function (app) { + app.directive('jsDown', ['$log', + function ($log) { + return { + restrict : 'E', + scope : { + event : '=', + data : '=', + tableConfigs : '=', + hideHeader : '=', // �뿤�뜑 遺�遺� �닲源� �뿬遺� + useSort : '=', // �젙�졊 湲곕뒫 �궗�슜 �뿬遺� + detailView : "=" // �씠�뒋 紐⑸줉 �긽�꽭�삎 蹂�寃쎌쓣 �쐞�빐 �궗�슜. �떎瑜� �솕硫댁� �궗�슜�븯吏� �븡�쓬. + }, + replace : true, + templateUrl : '/custom_components/js-down/js-down.html', + controller : function ($scope, $element, $attrs) { + $scope.fn = { + getResponseData : getResponseData + }; + + // �뀒�씠釉� �젙蹂� 媛��졇�삤湲� + function getResponseData() { + return $scope.data; + } + }, + link : function (scope, element, attrs) { + + } + }; + }]) + }); + + diff --git a/src/main/webapp/custom_components/js-down/js-down.html b/src/main/webapp/custom_components/js-down/js-down.html new file mode 100644 index 0000000..4dbe056 --- /dev/null +++ b/src/main/webapp/custom_components/js-down/js-down.html @@ -0,0 +1,47 @@ +<table class="table table-striped table-layout-fixed" ng-class="{ 'width768' : !detailView }" bindonce> + <!-- �뀒�씠釉� 癒몃━ --> + <thead> + <tr ng-if="hideHeader != true"> + <th bindonce ng-repeat="tableConfig in tableConfigs" + bo-class="[tableConfig.hAlign, tableConfig.hWidth, tableConfig.dVisible]" + ng-click="$root.$downProvider.setOrderByColumn(tableConfig.dName)" + bo-style="{ 'cursor' : tableConfig.dName != '' ? 'pointer' : '' }" + rowspan="{{tableConfig.rowSpan}}" + colspan="{{tableConfig.colSpan}}" + ng-if="!tableConfig.subHead"> + <!-- 泥댄겕 諛뺤뒪�씪 寃쎌슦 --> + <div bo-switch="tableConfig.dType"> + <div bo-switch-when="checkbox"> + <input type="checkbox" tabindex="-1" ng-model="tableConfig.hChecked" ng-click="$root.$downProvider.toggleChecked(tableConfig.hChecked, fn.getResponseData())"> + </div> + <div bo-switch-default> + <span ng-if="tableConfig.columnTooltip != ''" function-tool-tip data-placement="top" data-toggle="tooltip" data-original-title="{{tableConfig.columnTooltip}}" + translate="{{tableConfig.hName}}"></span> + <span ng-if="tableConfig.columnTooltip == ''" translate="{{tableConfig.hName}}"></span> + <span ng-if="($root.$downProvider.orderByColumn == tableConfig.dName) && (tableConfig.dName != '')"><i class="fa fa-arrow-circle-down" ng-show="!$root.$downProvider.reverse"></i> + <i class="fa fa-arrow-circle-up" ng-show="$root.$downProvider.reverse"></i> + </span> + </div> + </div> + </th> + </tr> + </thead> + + <tbody> + <tr ng-if="useSort != false" ng-repeat="row in fn.getResponseData() | orderBy:$root.$downProvider.orderByColumn:$root.$downProvider.reverse" + bo-class="[row.checked == true ? 'table-active' : '', tableConfig.hWidth]" + down-column-generator="row"> + </tr> + + <tr ng-if="useSort == false" ng-repeat="row in fn.getResponseData()" + bo-class="[row.checked == true ? 'table-active' : '', tableConfig.hWidth]" + down-column-generator="row"> + </tr> + + <tr ng-if="fn.getResponseData().length == 0"> + <td colspan="{{tableConfigs.length}}"> + <span translate="common.noData">�뜲�씠�꽣媛� �뾾�뒿�땲�떎.</span> + </td> + </tr> + </tbody> +</table> diff --git a/src/main/webapp/custom_components/js-rel/js-rel.directive.js b/src/main/webapp/custom_components/js-rel/js-rel.directive.js new file mode 100644 index 0000000..e3f89eb --- /dev/null +++ b/src/main/webapp/custom_components/js-rel/js-rel.directive.js @@ -0,0 +1,36 @@ +'use strict'; + +define(['app'], + function (app) { + app.directive('jsRel', ['$log', + function ($log) { + return { + restrict : 'E', + scope : { + event : '=', + data : '=', + tableConfigs : '=', + hideHeader : '=', // �뿤�뜑 遺�遺� �닲源� �뿬遺� + useSort : '=', // �젙�졊 湲곕뒫 �궗�슜 �뿬遺� + detailView : "=" // �씠�뒋 紐⑸줉 �긽�꽭�삎 蹂�寃쎌쓣 �쐞�빐 �궗�슜. �떎瑜� �솕硫댁� �궗�슜�븯吏� �븡�쓬. + }, + replace : true, + templateUrl : '/custom_components/js-rel/js-rel.html', + controller : function ($scope, $element, $attrs) { + $scope.fn = { + getResponseData : getResponseData + }; + + // �뀒�씠釉� �젙蹂� 媛��졇�삤湲� + function getResponseData() { + return $scope.data; + } + }, + link : function (scope, element, attrs) { + + } + }; + }]) + }); + + diff --git a/src/main/webapp/custom_components/js-rel/js-rel.html b/src/main/webapp/custom_components/js-rel/js-rel.html new file mode 100644 index 0000000..090a59e --- /dev/null +++ b/src/main/webapp/custom_components/js-rel/js-rel.html @@ -0,0 +1,47 @@ +<table class="table table-striped table-layout-fixed" ng-class="{ 'width768' : !detailView }" bindonce> + <!-- �뀒�씠釉� 癒몃━ --> + <thead> + <tr ng-if="hideHeader != true"> + <th bindonce ng-repeat="tableConfig in tableConfigs" + bo-class="[tableConfig.hAlign, tableConfig.hWidth, tableConfig.dVisible]" + ng-click="$root.$relProvider.setOrderByColumn(tableConfig.dName)" + bo-style="{ 'cursor' : tableConfig.dName != '' ? 'pointer' : '' }" + rowspan="{{tableConfig.rowSpan}}" + colspan="{{tableConfig.colSpan}}" + ng-if="!tableConfig.subHead"> + <!-- 泥댄겕 諛뺤뒪�씪 寃쎌슦 --> + <div bo-switch="tableConfig.dType"> + <div bo-switch-when="checkbox"> + <input type="checkbox" tabindex="-1" ng-model="tableConfig.hChecked" ng-click="$root.$relProvider.toggleChecked(tableConfig.hChecked, fn.getResponseData())"> + </div> + <div bo-switch-default> + <span ng-if="tableConfig.columnTooltip != ''" function-tool-tip data-placement="top" data-toggle="tooltip" data-original-title="{{tableConfig.columnTooltip}}" + translate="{{tableConfig.hName}}"></span> + <span ng-if="tableConfig.columnTooltip == ''" translate="{{tableConfig.hName}}"></span> + <span ng-if="($root.$relProvider.orderByColumn == tableConfig.dName) && (tableConfig.dName != '')"><i class="fa fa-arrow-circle-down" ng-show="!$root.$relProvider.reverse"></i> + <i class="fa fa-arrow-circle-up" ng-show="$root.$relProvider.reverse"></i> + </span> + </div> + </div> + </th> + </tr> + </thead> + + <tbody> + <tr ng-if="useSort != false" ng-repeat="row in fn.getResponseData() | orderBy:$root.$relProvider.orderByColumn:$root.$relProvider.reverse" + bo-class="[row.checked == true ? 'table-active' : '', tableConfig.hWidth]" + rel-column-generator="row"> + </tr> + + <tr ng-if="useSort == false" ng-repeat="row in fn.getResponseData()" + bo-class="[row.checked == true ? 'table-active' : '', tableConfig.hWidth]" + rel-column-generator="row"> + </tr> + + <tr ng-if="fn.getResponseData().length == 0"> + <td colspan="{{tableConfigs.length}}"> + <span translate="common.noData">�뜲�씠�꽣媛� �뾾�뒿�땲�떎.</span> + </td> + </tr> + </tbody> +</table> diff --git a/src/main/webapp/custom_components/js-rel/rel.provider.js b/src/main/webapp/custom_components/js-rel/rel.provider.js new file mode 100644 index 0000000..8e7125e --- /dev/null +++ b/src/main/webapp/custom_components/js-rel/rel.provider.js @@ -0,0 +1,239 @@ +'use strict'; + +define(['app', 'angular'], + function (app, angular) { + app.provider("$relProvider", 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 : "", // 而щ읆 �젙蹂대�� 異붿텧�븯湲� �쐞�븳 �엺�듃 �젙蹂대�� 以��떎 - relColumnGenerator �쓽 �궗�슜�옄 �젙�쓽 �븘�뱶 遺�遺꾩뿉�꽌 �궗�슜 + columnTooltip : "", // hover �떆 �댋�똻 蹂댁뿬二쇨린 + 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; + }, + setColumnTooltip : function (hTooltip) { + this.columnTooltip = hTooltip; + 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; + } + } + } + } + }); + }); diff --git a/src/main/webapp/custom_components/js-rel/relColumnGenerator.directive.js b/src/main/webapp/custom_components/js-rel/relColumnGenerator.directive.js new file mode 100644 index 0000000..c7e184f --- /dev/null +++ b/src/main/webapp/custom_components/js-rel/relColumnGenerator.directive.js @@ -0,0 +1,142 @@ +'use strict'; + +define(['app', 'angular'], + function (app, angular) { + + app.directive('relColumnGenerator', ['$compile', '$log', '$rootScope', '$relProvider', '$filter', + function ($compile, $log, $rootScope, $relProvider, $filter) { + return { + restrict : "A", + compile : function (tElement, tAttrs) { + return function (scope, element, attrs) { + scope.data = scope[attrs["relColumnGenerator"]]; + + var myData = scope.data; + var makeTag = ""; + + scope.tableConfigs.forEach(function (tableConfig, index) { + + if (tableConfig.colSpan > 0) { + return; + } + + // �븯�쐞 �떒怨� �몴�떆 異붽� + var myToken = ""; + if ( scope.data.depth > 0) { + for(var i=0; i<scope.data.depth; i++) { + if (i == scope.data.depth - 1) { + myToken += treeStartToken; + } else { + myToken += " "; + } + } + myToken += " "; + } + + makeTag = '<td 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.$relProvider.rowChecked(tableConfigs, data, fn.getResponseData())">'; + } + else {*/ + makeTag += '<input type="checkbox" ng-checked="data.checked == true ? true : false" ng-click="$root.$relProvider.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.$relProvider.rowChecked(tableConfigs, data, fn.getResponseData())">'; + } + else if (tableConfig.dType === "renderer") { + // �옖�뜑�윭 �씪�븣 + switch (tableConfig.dRenderer) { + + // �뿰愿� �씠�뒋 �씠�룞(�젣紐�) + case "ISSUE_RELATION_MOVE" : + makeTag += "<span class=\"titlename cursor text-center\" ng-click=\"event.changeDetailView(data.issueRelation)\">" + scope.data.title + "</span></a>"; + break; + + // �뿰愿��씠�뒋 援щ텇 + case "ISSUE_RELATION_TYPE": + makeTag += "<span>" + scope.data.relationIssueTypeName + "</span>"; + break; + + // �뿰愿��씠�뒋 �궘�젣 + case "ISSUE_RELATION_DELETE": + if (scope.data.modifyPermissionCheck) { + makeTag += '<img class="cursor" src="/assets/images/delete-icon.png" ng-click="event.removeRelationIssue(data.id)">'; + } + break; + + // �뿰愿� �씠�뒋 �슦�꽑�닚�쐞 + case "REL_COMMON_PRIORITY" : + makeTag += "<span class='badge' ng-style='{ \"background-color\" : \"" + scope.data.priorityVo.color + "\"," + "\"border-color\"" + " : \"" + scope.data.priorityVo.color + "\", \"color\": \"#FFFFFF\" }' translate='" + scope.data.priorityVo.name + "'></span>"; + break; + + // �뿰愿� �씠�뒋 以묒슂�룄 + case "REL_COMMON_SEVERITY" : + makeTag += "<span class='badge' ng-style='{ \"background-color\" : \"" + scope.data.severityVo.color + "\"," + "\"border-color\"" + " : \"" + scope.data.severityVo.color + "\", \"color\": \"#FFFFFF\" }' translate='" + scope.data.severityVo.name + "'></span>"; + break; + + // �뿰愿� �씠�뒋 �벑濡앹옄 + case "REL_REGISTER": + scope.data.registerVos = [scope.data.issueRelation.registerVo]; + makeTag += '<div owl-profile-over class="" table-user-image="data" target="registerVos"></div>'; + break; + + break; + + // �뿰愿� �씠�뒋 �떞�떦遺��꽌 + case "REL_ISSUE_DEPARTMENT" : + makeTag += "<ul class='ul-not-comma'>"; + makeTag += "<div style='color: #000000'>"; + angular.forEach(scope.data.issueRelation.departmentVos, function (departments) { + makeTag += "<li>" + departments.departmentName + "</li>"; + }); + makeTag += "</div>"; + makeTag += "</ul>"; + break; + + // �뿰愿� �씠�뒋 紐⑸줉�뿉�꽌 湲곌컙 �몴�떆 + case "REL_ISSUE_DUE_DATE" : + if (!$rootScope.isDefined(scope.data.issueRelation.startDate) && !$rootScope.isDefined(scope.data.issueRelation.completeDate)) { + makeTag += "<span translate='common.noDate'>湲곌컙 �뾾�쓬</span>"; + } else { + makeTag += "<span>" + scope.data.issueRelation.startDate + " ~ " + scope.data.issueRelation.completeDate + "</span>"; + } + break; + + // �뿰愿� �씠�뒋 �궗�슜�옄 �젙�쓽 �븘�뱶 + case "REL_ISSUE_CUSTOM_FIELD_VALUE_VIEW" : + var values = []; + + for (var count in scope.data.issueRelation.issueCustomFieldValueVos) { + var issueCustomFieldValueVo = scope.data.issueRelation.issueCustomFieldValueVos[count]; + // �뀒�씠釉� �꽕�젙�뿉�꽌 dName 遺�遺꾩뿉 �궗�슜�옄 �젙�쓽 �븘�뱶 id 瑜� �꽔怨� �빐�떦 媛믪쓣 異붿텧�븳�떎. + if (tableConfig.columnHint.id == issueCustomFieldValueVo.customFieldVo.id) { + values.push(issueCustomFieldValueVo.useValue); + } + } + angular.forEach(values, function (value) { + makeTag += '<span class="table-word-break-all cursor">' + value + '<span><br>'; + }); + + break; + } + } + + makeTag += '</td>'; + + var linkFn = $compile(makeTag); + var content = linkFn(scope); + + element.append(content); + }); + } + } + } + }]); + }); diff --git a/src/main/webapp/custom_components/js-table/tableColumnGenerator.directive.js b/src/main/webapp/custom_components/js-table/tableColumnGenerator.directive.js index 7bc7528..cdbf380 100644 --- a/src/main/webapp/custom_components/js-table/tableColumnGenerator.directive.js +++ b/src/main/webapp/custom_components/js-table/tableColumnGenerator.directive.js @@ -235,148 +235,148 @@ break;*/ // �뿰愿� �씠�뒋 �씠�룞(�젣紐�) - case "ISSUE_RELATION_MOVE" : - makeTag += "<span class=\"titlename cursor text-center\" ng-click=\"event.changeDetailView(data.issueRelation)\">" + scope.data.title + "</span></a>"; - break; + // case "ISSUE_RELATION_MOVE" : + // makeTag += "<span class=\"titlename cursor text-center\" ng-click=\"event.changeDetailView(data.issueRelation)\">" + scope.data.title + "</span></a>"; + // break; // �뿰愿��씠�뒋 援щ텇 - case "ISSUE_RELATION_TYPE": - makeTag += "<span>" + scope.data.relationIssueTypeName + "</span>"; - break; + // case "ISSUE_RELATION_TYPE": + // makeTag += "<span>" + scope.data.relationIssueTypeName + "</span>"; + // break; // �뿰愿��씠�뒋 �궘�젣 - case "ISSUE_RELATION_DELETE": - if (scope.data.modifyPermissionCheck) { - makeTag += '<img class="cursor" src="/assets/images/delete-icon.png" ng-click="event.removeRelationIssue(data.id)">'; - } - break; + // case "ISSUE_RELATION_DELETE": + // if (scope.data.modifyPermissionCheck) { + // makeTag += '<img class="cursor" src="/assets/images/delete-icon.png" ng-click="event.removeRelationIssue(data.id)">'; + // } + // break; // �뿰愿� �씠�뒋 �슦�꽑�닚�쐞 - case "REL_COMMON_PRIORITY" : - makeTag += "<span class='badge' ng-style='{ \"background-color\" : \"" + scope.data.priorityVo.color + "\"," + "\"border-color\"" + " : \"" + scope.data.priorityVo.color + "\", \"color\": \"#FFFFFF\" }' translate='" + scope.data.priorityVo.name + "'></span>"; - break; + // case "REL_COMMON_PRIORITY" : + // makeTag += "<span class='badge' ng-style='{ \"background-color\" : \"" + scope.data.priorityVo.color + "\"," + "\"border-color\"" + " : \"" + scope.data.priorityVo.color + "\", \"color\": \"#FFFFFF\" }' translate='" + scope.data.priorityVo.name + "'></span>"; + // break; // �뿰愿� �씠�뒋 以묒슂�룄 - case "REL_COMMON_SEVERITY" : - makeTag += "<span class='badge' ng-style='{ \"background-color\" : \"" + scope.data.severityVo.color + "\"," + "\"border-color\"" + " : \"" + scope.data.severityVo.color + "\", \"color\": \"#FFFFFF\" }' translate='" + scope.data.severityVo.name + "'></span>"; - break; + // case "REL_COMMON_SEVERITY" : + // makeTag += "<span class='badge' ng-style='{ \"background-color\" : \"" + scope.data.severityVo.color + "\"," + "\"border-color\"" + " : \"" + scope.data.severityVo.color + "\", \"color\": \"#FFFFFF\" }' translate='" + scope.data.severityVo.name + "'></span>"; + // break; // �뿰愿� �씠�뒋 �벑濡앹옄 - case "REL_REGISTER": - scope.data.registerVos = [scope.data.issueRelation.registerVo]; - makeTag += '<div owl-profile-over class="" table-user-image="data" target="registerVos"></div>'; - break; - - break; + // case "REL_REGISTER": + // scope.data.registerVos = [scope.data.issueRelation.registerVo]; + // makeTag += '<div owl-profile-over class="" table-user-image="data" target="registerVos"></div>'; + // break; + // + // break; // �뿰愿� �씠�뒋 �떞�떦遺��꽌 - case "REL_ISSUE_DEPARTMENT" : - makeTag += "<ul class='ul-not-comma'>"; - makeTag += "<div style='color: #000000'>"; - angular.forEach(scope.data.issueRelation.departmentVos, function (departments) { - makeTag += "<li>" + departments.departmentName + "</li>"; - }); - makeTag += "</div>"; - makeTag += "</ul>"; - break; + // case "REL_ISSUE_DEPARTMENT" : + // makeTag += "<ul class='ul-not-comma'>"; + // makeTag += "<div style='color: #000000'>"; + // angular.forEach(scope.data.issueRelation.departmentVos, function (departments) { + // makeTag += "<li>" + departments.departmentName + "</li>"; + // }); + // makeTag += "</div>"; + // makeTag += "</ul>"; + // break; // �뿰愿� �씠�뒋 紐⑸줉�뿉�꽌 湲곌컙 �몴�떆 - case "REL_ISSUE_DUE_DATE" : - if (!$rootScope.isDefined(scope.data.issueRelation.startDate) && !$rootScope.isDefined(scope.data.issueRelation.completeDate)) { - makeTag += "<span translate='common.noDate'>湲곌컙 �뾾�쓬</span>"; - } - else { - makeTag += "<span>" + scope.data.issueRelation.startDate + " ~ " + scope.data.issueRelation.completeDate + "</span>"; - } - break; + // case "REL_ISSUE_DUE_DATE" : + // if (!$rootScope.isDefined(scope.data.issueRelation.startDate) && !$rootScope.isDefined(scope.data.issueRelation.completeDate)) { + // makeTag += "<span translate='common.noDate'>湲곌컙 �뾾�쓬</span>"; + // } + // else { + // makeTag += "<span>" + scope.data.issueRelation.startDate + " ~ " + scope.data.issueRelation.completeDate + "</span>"; + // } + // break; // �뿰愿� �씠�뒋 �궗�슜�옄 �젙�쓽 �븘�뱶 - case "REL_ISSUE_CUSTOM_FIELD_VALUE_VIEW" : - var values = []; - - for (var count in scope.data.issueRelation.issueCustomFieldValueVos) { - var issueCustomFieldValueVo = scope.data.issueRelation.issueCustomFieldValueVos[count]; - // �뀒�씠釉� �꽕�젙�뿉�꽌 dName 遺�遺꾩뿉 �궗�슜�옄 �젙�쓽 �븘�뱶 id 瑜� �꽔怨� �빐�떦 媛믪쓣 異붿텧�븳�떎. - if (tableConfig.columnHint.id == issueCustomFieldValueVo.customFieldVo.id) { - values.push(issueCustomFieldValueVo.useValue); - } - } - angular.forEach(values, function (value) { - makeTag += '<span class="table-word-break-all cursor">' + value + '<span><br>'; - }); - - break; + // case "REL_ISSUE_CUSTOM_FIELD_VALUE_VIEW" : + // var values = []; + // + // for (var count in scope.data.issueRelation.issueCustomFieldValueVos) { + // var issueCustomFieldValueVo = scope.data.issueRelation.issueCustomFieldValueVos[count]; + // // �뀒�씠釉� �꽕�젙�뿉�꽌 dName 遺�遺꾩뿉 �궗�슜�옄 �젙�쓽 �븘�뱶 id 瑜� �꽔怨� �빐�떦 媛믪쓣 異붿텧�븳�떎. + // if (tableConfig.columnHint.id == issueCustomFieldValueVo.customFieldVo.id) { + // values.push(issueCustomFieldValueVo.useValue); + // } + // } + // angular.forEach(values, function (value) { + // makeTag += '<span class="table-word-break-all cursor">' + value + '<span><br>'; + // }); + // + // break; // �븯�쐞 �씠�뒋 �씠�룞(�젣紐�) - case "ISSUE_DOWN_MOVE" : - makeTag += "<span class=\"titlename cursor\" ng-click=\"event.changeDetailView(data)\">" + scope.data.title + "</span></a>"; - break; - - // �븯�쐞 �씠�뒋 ���엯 - case "ISSUE_DOWN_STATUS_TYPE" : - makeTag += "<span class='badge' ng-style='{ \"background-color\" : \"" + scope.data.issueStatusVo.color + "\"," + "\"border-color\"" + " : \"" + scope.data.issueStatusVo.color + "\", \"color\": \"#FFFFFF\" }'>" + scope.data.issueStatusVo.name + "</span>"; - break; - + // case "ISSUE_DOWN_MOVE" : + // makeTag += "<span class=\"titlename cursor\" ng-click=\"event.changeDetailView(data)\">" + scope.data.title + "</span></a>"; + // break; + // + // // �븯�쐞 �씠�뒋 ���엯 + // case "ISSUE_DOWN_STATUS_TYPE" : + // makeTag += "<span class='badge' ng-style='{ \"background-color\" : \"" + scope.data.issueStatusVo.color + "\"," + "\"border-color\"" + " : \"" + scope.data.issueStatusVo.color + "\", \"color\": \"#FFFFFF\" }'>" + scope.data.issueStatusVo.name + "</span>"; + // break; + // // �븯�쐞 �씠�뒋 �궘�젣 - case "ISSUE_DOWN_DELETE": - if (scope.data.modifyPermissionCheck) { - makeTag += '<img class="cursor" src="/assets/images/delete-icon.png" ng-click="event.removeDownIssue(data.id)">'; - } - break; - + // case "ISSUE_DOWN_DELETE": + // if (scope.data.modifyPermissionCheck) { + // makeTag += '<img class="cursor" src="/assets/images/delete-icon.png" ng-click="event.removeDownIssue(data.id)">'; + // } + // break; + // // �븯�쐞 �씠�뒋 �슦�꽑 �닚�쐞 - case "DOWN_COMMON_PRIORITY" : - makeTag += "<span class='badge' ng-style='{ \"background-color\" : \"" + scope.data.priorityVo.color + "\"," + "\"border-color\"" + " : \"" + scope.data.priorityVo.color + "\", \"color\": \"#FFFFFF\" }' translate='" + scope.data.priorityVo.name + "'></span>"; - break; - + // case "DOWN_COMMON_PRIORITY" : + // makeTag += "<span class='badge' ng-style='{ \"background-color\" : \"" + scope.data.priorityVo.color + "\"," + "\"border-color\"" + " : \"" + scope.data.priorityVo.color + "\", \"color\": \"#FFFFFF\" }' translate='" + scope.data.priorityVo.name + "'></span>"; + // break; + // // �븯�쐞 �씠�뒋 以묒슂�룄 - case "DOWN_COMMON_SEVERITY" : - makeTag += "<span class='badge' ng-style='{ \"background-color\" : \"" + scope.data.severityVo.color + "\"," + "\"border-color\"" + " : \"" + scope.data.severityVo.color + "\", \"color\": \"#FFFFFF\" }' translate='" + scope.data.severityVo.name + "'></span>"; - break; - + // case "DOWN_COMMON_SEVERITY" : + // makeTag += "<span class='badge' ng-style='{ \"background-color\" : \"" + scope.data.severityVo.color + "\"," + "\"border-color\"" + " : \"" + scope.data.severityVo.color + "\", \"color\": \"#FFFFFF\" }' translate='" + scope.data.severityVo.name + "'></span>"; + // break; + // // �븯�쐞 �씠�뒋 �떞�떦遺��꽌 - case "DOWN_ISSUE_DEPARTMENT" : - makeTag += "<ul class='ul-not-comma'>"; - makeTag += "<div style='color: #000000'>"; - angular.forEach(scope.data.departmentVos, function (departments) { - makeTag += "<li>" + departments.departmentName + "</li>"; - }); - makeTag += "</div>"; - makeTag += "</ul>"; - break; - + // case "DOWN_ISSUE_DEPARTMENT" : + // makeTag += "<ul class='ul-not-comma'>"; + // makeTag += "<div style='color: #000000'>"; + // angular.forEach(scope.data.departmentVos, function (departments) { + // makeTag += "<li>" + departments.departmentName + "</li>"; + // }); + // makeTag += "</div>"; + // makeTag += "</ul>"; + // break; + // // �븯�쐞 �씠�뒋 �벑濡앹옄 - case "DOWN_REGISTER": - scope.data.registerVos = [scope.data.registerVo]; - makeTag += '<div owl-profile-over class="" table-user-image="data" target="registerVos"></div>'; - break; - + // case "DOWN_REGISTER": + // scope.data.registerVos = [scope.data.registerVo]; + // makeTag += '<div owl-profile-over class="" table-user-image="data" target="registerVos"></div>'; + // break; + // // �븯�쐞 �씠�뒋 湲곌컙 - case "DOWN_ISSUE_DUE_DATE" : - if (!$rootScope.isDefined(scope.data.startDate) && !$rootScope.isDefined(scope.data.completeDate)) { - makeTag += "<span translate='common.noDate'>湲곌컙 �뾾�쓬</span>"; - } - else { - makeTag += "<span>" + scope.data.startDate + " ~ " + scope.data.completeDate + "</span>"; - } - break; - + // case "DOWN_ISSUE_DUE_DATE" : + // if (!$rootScope.isDefined(scope.data.startDate) && !$rootScope.isDefined(scope.data.completeDate)) { + // makeTag += "<span translate='common.noDate'>湲곌컙 �뾾�쓬</span>"; + // } + // else { + // makeTag += "<span>" + scope.data.startDate + " ~ " + scope.data.completeDate + "</span>"; + // } + // break; + // // �븯�쐞 �씠�뒋 �궗�슜�옄 �젙�쓽 �븘�뱶 - case "DOWN_ISSUE_CUSTOM_FIELD_VALUE_VIEW" : - var values = []; - - for (var count in scope.data.issueCustomFieldValueVos) { - var issueCustomFieldValueVo = scope.data.issueCustomFieldValueVos[count]; - // �뀒�씠釉� �꽕�젙�뿉�꽌 dName 遺�遺꾩뿉 �궗�슜�옄 �젙�쓽 �븘�뱶 id 瑜� �꽔怨� �빐�떦 媛믪쓣 異붿텧�븳�떎. - if (tableConfig.columnHint.id == issueCustomFieldValueVo.customFieldVo.id) { - values.push(issueCustomFieldValueVo.useValue); - } - } - angular.forEach(values, function (value) { - makeTag += '<span class="table-word-break-all">' + value + '<span><br>'; - }); - - break; + // case "DOWN_ISSUE_CUSTOM_FIELD_VALUE_VIEW" : + // var values = []; + // + // for (var count in scope.data.issueCustomFieldValueVos) { + // var issueCustomFieldValueVo = scope.data.issueCustomFieldValueVos[count]; + // // �뀒�씠釉� �꽕�젙�뿉�꽌 dName 遺�遺꾩뿉 �궗�슜�옄 �젙�쓽 �븘�뱶 id 瑜� �꽔怨� �빐�떦 媛믪쓣 異붿텧�븳�떎. + // if (tableConfig.columnHint.id == issueCustomFieldValueVo.customFieldVo.id) { + // values.push(issueCustomFieldValueVo.useValue); + // } + // } + // angular.forEach(values, function (value) { + // makeTag += '<span class="table-word-break-all">' + value + '<span><br>'; + // }); + // + // break; // �씠由꾩쓣 �겢由��븯硫� �닔�젙 �뙘�뾽 �몴�떆 case "COMMON_MODIFY" : diff --git a/src/main/webapp/i18n/ko/global.json b/src/main/webapp/i18n/ko/global.json index fa6a8c1..860aabd 100644 --- a/src/main/webapp/i18n/ko/global.json +++ b/src/main/webapp/i18n/ko/global.json @@ -281,12 +281,16 @@ "setIssueRelationTableDisplay": "�뿰愿� �씠�뒋 �뀒�씠釉� �몴�떆 �꽕�젙", "setIssueDownTableDisplay": "�븯�쐞 �씠�뒋 �뀒�씠釉� �몴�떆 �꽕�젙", "columnName": "而щ읆紐�", + "selectPartners": "�뾽泥� �꽑�깮", + "partners" : "�뾽泥� �씠硫붿씪", "area": "�꼻�씠", "displayed": "�몴�떆 �뿬遺�", "sequence": "�닚�꽌", "cannotChangedIssueTitle": "�씠�뒋 �젣紐⑹� 蹂�寃쏀븷 �닔 �뾾�뒿�땲�떎.", "cannotChangedIssueType": "�씠�뒋 援щ텇�� 蹂�寃쏀븷 �닔 �뾾�뒿�땲�떎.", - "selectSendIssueMail": "�씠�뒋 硫붿씪 諛쒖넚 ���긽�옄 �꽑�깮", + "selectSendIssueMail": "�뾽泥� 硫붿씪 諛쒖넚", + "CommonSendIssueMail": "�씪諛� 硫붿씪 諛쒖넚", + "SendIssueMail": "硫붿씪 諛쒖넚 �엯�젰", "sendIssueSelectedUsers": "�봽濡쒖젥�듃�뿉 李몄뿬�븯怨� �엳�뒗 �떎瑜� �궗�슜�옄�뿉寃� �씠�뒋 �젙蹂대�� 蹂대깄�땲�떎.", "sendMail": "�씠硫붿씪 諛쒖넚", "changedHistory": "�씠�뒋 蹂�寃� �씠�젰 �긽�꽭�젙蹂�", @@ -327,6 +331,10 @@ "succeededIssueMail": "�씠�뒋 硫붿씪 諛쒖넚 �셿猷�", "sentToTheSelectedUser": "�꽑�깮�븳 �궗�슜�옄�뿉寃� �씠硫붿씪�씠 諛쒖넚�릺�뿀�뒿�땲�떎.", "failedIssueMail": "�씠�뒋 硫붿씪 諛쒖넚 �떎�뙣", + "selectedPartnersMail": "�뾽泥� �씠硫붿씪�쓣 �꽑�깮�븯�꽭�슂.", + "selectedPartnersTemplate": "�뾽泥� �씠硫붿씪 �뀥�뵆由우쓣 �꽑�깮�빐二쇱꽭�슂.", + "writeIssueMail": "�씠硫붿씪�쓣 �엯�젰�빐二쇱꽭�슂.", + "writeMail": "�씠硫붿씪�쓣 �엯�젰�븯�뀛�빞 異붽��븷�닔 �엳�뒿�땲�떎.", "issueVersionLookupFailed": "�씠�뒋 踰꾩쟾 議고쉶 �떎�뙣", "relationIssueType1" : "�떎�쓬 �씠�뒋�� 愿��젴�맖", "relationIssueType2" : "�떎�쓬 �씠�뒋�뿉 以묐났�맖", @@ -694,6 +702,8 @@ "checkAll": "�쟾泥� �꽑�깮", "unCheckAll": "�쟾泥� �빐�젣", "send": "蹂대궡湲�", + "emailExplain": "諛쏅뒗 �궗�엺�쓽 �씠硫붿씪 �삎�떇�쓣 �엯�젰�븯�뀛�빞 �빀�땲�떎.", + "sendToPerson" : "�떎瑜� �궗�슜�옄�뿉寃� 硫붿씪�쓣 蹂대깄�땲�떎.", "selected": "�꽑�깮�맖", "selectable": "�꽑�깮 媛��뒫", "password": "鍮꾨�踰덊샇", @@ -710,6 +720,7 @@ "priority": "�슦�꽑 �닚�쐞", "importance": "以묒슂�룄", "assignee": "�떞�떦�옄", + "toPerson": "諛쏅뒗 �궗�엺", "assigneeTeam" : "�떞�떦遺��꽌", "register": "�벑濡앹옄", "startDate": "�떆�옉�씪", diff --git a/src/main/webapp/scripts/app/issue/issue.js b/src/main/webapp/scripts/app/issue/issue.js index 81cc436..da32644 100644 --- a/src/main/webapp/scripts/app/issue/issue.js +++ b/src/main/webapp/scripts/app/issue/issue.js @@ -34,10 +34,10 @@ var deferred = $q.defer(); require([ 'issueListTimelineController', 'issueManagerController', 'issueListController', 'issueAddController', 'issueModifyController', 'issueDetailController', 'issueAddRelationController', 'issueAddDownController', 'issueImportExcelController', - 'chartLoader', 'jsTable', 'jsTree', 'tableColumnGenerator', 'treeColumnGenerator', 'modalFormAutoScroll', 'summerNote', 'summerNote-ko-KR', 'fullScroll', 'workflowService', 'priorityService', 'issueSearchService', 'issueTableConfigService', 'inputRegex', + 'chartLoader', 'jsTable', 'jsTree', 'jsRel', 'jsDown', 'tableColumnGenerator', 'treeColumnGenerator', 'relColumnGenerator', 'downColumnGenerator', 'modalFormAutoScroll', 'summerNote', 'summerNote-ko-KR', 'fullScroll', 'workflowService', 'priorityService', 'issueSearchService', 'issueTableConfigService', 'inputRegex', 'severityService', 'issueTypeService', 'issueTypeCustomFieldService', 'issueService', 'issueStatusService', 'emailTemplateService','issueUserService','issueDepartmentService','issueModifyUserController', 'issueModifyDepartmentController', 'customFieldService', 'issueSearchFieldKeyViewElement', 'issueSearchCustomFieldViewElement', 'tableUserImage', 'fullScroll', 'issueCommentService', 'detectIssueEditor', 'formSubmit', 'issueModifyStatusController', 'downIssueModifyStatusController', 'jsShortCut', - 'issueAddTableConfigController','issueAddRelationTableConfigController','issueAddDownTableConfigController','domAppend', 'issueDetailImagePreview', 'issueSendMailPartnersController', 'htmlDiff', 'issueVersionViewController', 'issueVersionService', + 'issueAddTableConfigController','issueAddRelationTableConfigController','issueAddDownTableConfigController','domAppend', 'issueDetailImagePreview', 'issueSendMailPartnersController', 'issueCommonSendMailController', 'htmlDiff', 'issueVersionViewController', 'issueVersionService', 'jsHtmlDiff', 'issueReservationController', 'issueReservationService', 'issueVersionService', 'issueStatusAutoFocus', 'issueRelationService' ], function () { deferred.resolve(); diff --git a/src/main/webapp/scripts/app/issue/issueCommonSendMail.controller.js b/src/main/webapp/scripts/app/issue/issueCommonSendMail.controller.js new file mode 100644 index 0000000..6440824 --- /dev/null +++ b/src/main/webapp/scripts/app/issue/issueCommonSendMail.controller.js @@ -0,0 +1,111 @@ +'use strict'; + +define([ + 'app' + ], + function (app) { + app.controller('issueCommonSendMailController', ['$scope', '$rootScope', '$state', '$log', '$resourceProvider', '$uibModalInstance', '$controller', '$injector', '$q','SweetAlert', '$filter', 'Issue', 'parameter', + function ($scope, $rootScope, $state, $log, $resourceProvider, $uibModalInstance, $controller, $injector, $q, SweetAlert, $filter, Issue, parameter) { + + $scope.fn = { + cancel : cancel, // �뙘�뾽 李� �떕湲� + formSubmit : formSubmit, // �뤌 �쟾�넚 + formCheck : formCheck, // �뤌 泥댄겕 + addInput : addInput, + removeInput : removeInput + }; + + $scope.vm = { + form : { + issueId : parameter.issueId, + title : "", + description: "", + inputs : [0], + emails : {}, // �엯�젰�맂 �궗�슜�옄 �씠硫붿씪 + }, + userName : "", + autoCompletePage : { + user : { + page : 0, + totalPage : 0 + } + } + }; + + // �뤌 泥댄겕 + function formCheck(formInvalid) { + if (formInvalid) { + return true; + } + return false; + } + + // 硫붿씪 二쇱냼 input 李� 異붽� 踰꾪듉 + function addInput() { + var arrayFull = true; // 諛곗뿴�씠 媛��뱷 李� �엳�뒗吏� �뿬遺� + var index = 0; + $scope.vm.form.inputs.forEach(function (email) { + if (!$rootScope.isDefined($scope.vm.form.emails[index])) { + arrayFull = false; + } + index++; + }); + + if (arrayFull) { + $scope.vm.form.inputs.push(index); + $scope.vm.form.emails[index] = "" + } else { + SweetAlert.warning($filter("translate")("issue.writeIssueMail"), $filter("translate")("issue.writeMail")); // 異붽�踰꾪듉 寃쎄퀬 + } + } + + // �뤌 �쟾�넚 + function formSubmit() { + $rootScope.spinner = true; + + var content = { + issueId : $scope.vm.form.issueId, + title : $scope.vm.form.title, + description : $scope.vm.form.description, + sendEmails : (function () { + var sendEmails = []; + var index = 0 + $scope.vm.form.inputs.forEach(function (email) { + if ($rootScope.isDefined($scope.vm.form.emails[index])) { + sendEmails.push($rootScope.encryption($scope.vm.form.emails[index])); // �씠硫붿씪二쇱냼 �븫�샇�솕 + } + index++; + }); + + return sendEmails; + })() + }; + + Issue.sendCommonEmail($resourceProvider.getContent( + content, + $resourceProvider.getPageContent(0, 10))).then(function (result) { + + if (result.data.message.status === "success") { + SweetAlert.success($filter("translate")("issue.succeededIssueMail"), $filter("translate")("issue.sentToTheSelectedUser")); // "�씠�뒋 硫붿씪 諛쒖넚 �셿猷�" + $scope.fn.cancel(); + } + else { + SweetAlert.error($filter("translate")("issue.failedIssueMail"), result.data.message.message); // "�씠�뒋 硫붿씪 諛쒖넚 �떎�뙣" + } + + $rootScope.spinner = false; + }); + } + + // �씠硫붿씪 二쇱냼 input �궘�젣 + function removeInput(index) { + $scope.vm.form.inputs.splice(index, 1); + } + + function cancel() { + $rootScope.$broadcast("closeLayer"); // �뙘�뾽�씠 �뿴由ш퀬 �굹�꽌 js-multi, js-single �벑�뿉�꽌 body �씠踰ㅽ듃媛� �궇�븘媛��뒗 �쁽�긽 �닔�젙 + $uibModalInstance.dismiss('cancel'); + $(document).unbind("keydown"); // �떒異뺥궎 �씠踰ㅽ듃 �젣嫄� + } + }]); + }); diff --git a/src/main/webapp/scripts/app/issue/issueDetail.controller.js b/src/main/webapp/scripts/app/issue/issueDetail.controller.js index e07ca8d..dab59ac 100644 --- a/src/main/webapp/scripts/app/issue/issueDetail.controller.js +++ b/src/main/webapp/scripts/app/issue/issueDetail.controller.js @@ -8,9 +8,9 @@ 'angular' ], function (app, angular) { - app.controller('issueDetailController', ['$scope', '$rootScope', '$log', '$resourceProvider', '$tableProvider', '$state', '$uibModal', '$q', + app.controller('issueDetailController', ['$scope', '$rootScope', '$log', '$resourceProvider', '$tableProvider', '$relProvider', '$downProvider', '$state', '$uibModal', '$q', '$controller', '$injector', 'SweetAlert', '$timeout', 'Issue', 'IssueComment', 'IssueRelation', 'AttachedFile', 'Priority', 'Severity','IssueStatus', 'IssueTableConfig', '$filter', - function ($scope, $rootScope, $log, $resourceProvider, $tableProvider, $state, $uibModal, $q, $controller, $injector, SweetAlert, $timeout, Issue, IssueComment, IssueRelation, AttachedFile, Priority, Severity, IssueStatus, IssueTableConfig, $filter) { + function ($scope, $rootScope, $log, $resourceProvider, $tableProvider, $relProvider, $downProvider, $state, $uibModal, $q, $controller, $injector, SweetAlert, $timeout, Issue, IssueComment, IssueRelation, AttachedFile, Priority, Severity, IssueStatus, IssueTableConfig, $filter) { // IssueListController vm, fn 蹂��닔 �긽�냽. @@ -54,6 +54,7 @@ $scope.fn.removeRelationIssue = removeRelationIssue; $scope.fn.removeDownIssue = removeDownIssue; $scope.fn.changeDetailPageRowCount = changeDetailPageRowCount; // �럹�씠吏� 蹂�寃� + $scope.fn.sendCommonMail = sendCommonMail; // �씠�뒋 紐⑸줉 而⑦듃濡ㅻ윭 vm, fn �긽�냽 以� $scope.vm.viewer = {}; // �쁽�옱 �씠�뒋 @@ -327,90 +328,98 @@ } // �뀒�씠釉붿쓽 �뿰愿� �씠�뒋 而щ읆�쓣 留뚮뱾�뼱以��떎. - function setRelTableColumn(Rel_issueTableConfig) { + function setRelTableColumn(issueTableConfig) { // �뿰愿� �씠�뒋 而щ읆 - switch(Rel_issueTableConfig.key) { + switch(issueTableConfig.key) { case "RELATION_ISSUE_TYPE" : // �뿰愿� �씠�뒋 援щ텇 - $scope.vm.relTableConfigs.push($tableProvider.config() + $scope.vm.relTableConfigs.push($relProvider.config() .setHName("issue.relationIssueType") + .setDName("relationIssueType") .setDType("renderer") .setDAlign("text-center") - .setHWidth("bold " + Rel_issueTableConfig.width) + .setHWidth("bold " + issueTableConfig.width) .setDRenderer("ISSUE_RELATION_TYPE")) /*.setHWidth("width-30 bold")*/ /*.setHSort(false)*/ break; case "RELATION_ISSUE_TITLE" : // �뿰愿� �씠�뒋 �젣紐� - $scope.vm.relTableConfigs.push($tableProvider.config() + $scope.vm.relTableConfigs.push($relProvider.config() .setHName("issue.relationIssueTitle") + .setDName("title") .setDType("renderer") .setDAlign("text-center") - .setHWidth("bold " + Rel_issueTableConfig.width) + .setHWidth("bold " + issueTableConfig.width) .setDRenderer("ISSUE_RELATION_MOVE")) /*.setHWidth("width-60 bold")*/ /*.setHSort(true)*/ break; case "RELATION_PRIORITY" : // �뿰愿� �씠�뒋 �슦�꽑�닚�쐞 - $scope.vm.relTableConfigs.push($tableProvider.config() + $scope.vm.relTableConfigs.push($relProvider.config() .setHName("common.priority") + .setDName("priorityVo.id") .setDType("renderer") - .setHWidth("bold " + Rel_issueTableConfig.width) + .setHWidth("bold " + issueTableConfig.width) .setDAlign("text-center") .setDRenderer("REL_COMMON_PRIORITY")); break; case "RELATION_SEVERITY" : // �뿰愿� �씠�뒋 以묒슂�룄 - $scope.vm.relTableConfigs.push($tableProvider.config() + $scope.vm.relTableConfigs.push($relProvider.config() .setHName("common.importance") + .setDName("severityVo.id") .setDType("renderer") - .setHWidth("bold " + Rel_issueTableConfig.width) + .setHWidth("bold " + issueTableConfig.width) .setDAlign("text-center") .setDRenderer("REL_COMMON_SEVERITY")); break; case "RELATION_ASSIGNEE_TEAM" : // �뿰愿� �씠�뒋 �떞�떦遺��꽌 - $scope.vm.relTableConfigs.push($tableProvider.config() + $scope.vm.relTableConfigs.push($relProvider.config() .setHName("common.assigneeTeam") + .setDName("departmentVos.departmentName") .setDType("renderer") - .setHWidth("bold " + Rel_issueTableConfig.width) + .setHWidth("bold " + issueTableConfig.width) .setDAlign("text-center") .setDRenderer("REL_ISSUE_DEPARTMENT")); break; - case "RELATION_REGISTER" : // �뿰愿� �씠�뒋 �벑濡앹옄 - $scope.vm.relTableConfigs.push($tableProvider.config() + case "RELATION_REGISTER" : // �뿰愿� �씠�뒋 �벑濡앹옄 + $scope.vm.relTableConfigs.push($relProvider.config() .setHName("common.register") + .setDName("registerVo.id") .setDType("renderer") - .setHWidth("bold " + Rel_issueTableConfig.width) + .setHWidth("bold " + issueTableConfig.width) .setDAlign("text-center") .setDRenderer("REL_REGISTER")); break; case "RELATION_PERIOD" : // �뿰愿� �씠�뒋 湲곌컙 - $scope.vm.relTableConfigs.push($tableProvider.config() + $scope.vm.relTableConfigs.push($relProvider.config() .setHName("common.period") .setDType("renderer") - .setHWidth("bold " + Rel_issueTableConfig.width) + .setHWidth("bold " + issueTableConfig.width) .setDAlign("text-center") .setDRenderer("REL_ISSUE_DUE_DATE")); break; - case "RELATION_MODIFY_DATE" : // �뿰愿� �씠�뒋 理쒓렐 蹂�寃쎌씪 - $scope.vm.relTableConfigs.push($tableProvider.config() + case "RELATION_MODIFY_DATE" : // �뿰愿� �씠�뒋 理쒓렐 蹂�寃쎌씪 + $scope.vm.relTableConfigs.push($relProvider.config() .setHName("common.lastChangeDate") - .setHWidth("bold " + Rel_issueTableConfig.width) - .setDAlign("text-center")); + .setHWidth("bold " + issueTableConfig.width) + .setDAlign("text-center") + .setDName("modifyDate")); break; } // �궗�슜�옄 �젙�쓽 �븘�뱶 而щ읆 - if (Rel_issueTableConfig.key.indexOf("CUSTOM_FIELD_") !== -1) { + if (issueTableConfig.key.indexOf("CUSTOM_FIELD_") !== -1) { // 留뚯빟 �씠�뒋 �뀒�씠釉� 而щ읆紐낆씠 �몴�떆�릺吏� �븡�쑝硫� �씠履쎌씠 臾몄젣 for (var count in $scope.vm.customFields) { var customField = $scope.vm.customFields[count]; - if (customField.id === Number(Rel_issueTableConfig.key.substring(13))) { - $scope.vm.relTableConfigs.push($tableProvider.config() + if (customField.id === Number(issueTableConfig.key.substring(13))) { + $scope.vm.relTableConfigs.push($relProvider.config() .setHName(customField.name) + .setDName("relCustomFieldName" + [count]) .setDType("renderer") - .setHWidth("bold " + Rel_issueTableConfig.width) + .setHWidth("bold " + issueTableConfig.width) .setDAlign("text-center") .setColumnHint(customField) .setDRenderer("REL_ISSUE_CUSTOM_FIELD_VALUE_VIEW")); @@ -422,88 +431,96 @@ // �뀒�씠釉붿쓽 �븯�쐞 �씠�뒋 而щ읆�쓣 留뚮뱾�뼱以��떎. - function setDownTableColumn(Down_issueTableConfig) { + function setDownTableColumn(issueTableConfig) { // if (issueTableConfig == null) return; // �븯�쐞 �씠�뒋 而щ읆 - switch(Down_issueTableConfig.key) { + switch(issueTableConfig.key) { case "DOWN_ISSUE_TITLE" : // �븯�쐞 �씠�뒋 �젣紐� - $scope.vm.downTableConfigs.push($tableProvider.config() + $scope.vm.downTableConfigs.push($downProvider.config() .setHName("issue.downIssueTitle") + .setDName("title") .setDType("renderer") - .setHWidth("bold " + Down_issueTableConfig.width) + .setHWidth("bold " + issueTableConfig.width) .setDAlign("text-center") .setDRenderer("ISSUE_DOWN_MOVE")); break; - case "ISSUE_DOWN_STATUS_TYPE" : // �씠�뒋 �긽�깭 - $scope.vm.downTableConfigs.push($tableProvider.config() + case "ISSUE_DOWN_STATUS_TYPE" : // �븯�쐞 �씠�뒋 �긽�깭 + $scope.vm.downTableConfigs.push($downProvider.config() .setHName("issue.issueStatus") + .setDName("issueStatusVo.id") .setDType("renderer") - .setHWidth("bold " + Down_issueTableConfig.width) + .setHWidth("bold " + issueTableConfig.width) .setDAlign("text-center") .setDRenderer("ISSUE_DOWN_STATUS_TYPE")); break; case "DOWN_PRIORITY" : // �븯�쐞 �씠�뒋 �슦�꽑�닚�쐞 - $scope.vm.downTableConfigs.push($tableProvider.config() + $scope.vm.downTableConfigs.push($downProvider.config() .setHName("common.priority") + .setDName("priorityVo.id") .setDType("renderer") - .setHWidth("bold " + Down_issueTableConfig.width) + .setHWidth("bold " + issueTableConfig.width) .setDAlign("text-center") .setDRenderer("DOWN_COMMON_PRIORITY")); break; - case "DOWN_SEVERITY" : // 以묒슂�룄 - $scope.vm.downTableConfigs.push($tableProvider.config() + case "DOWN_SEVERITY" : // �븯�쐞 �씠�뒋 以묒슂�룄 + $scope.vm.downTableConfigs.push($downProvider.config() .setHName("common.importance") + .setDName("severityVo.id") .setDType("renderer") - .setHWidth("bold " + Down_issueTableConfig.width) + .setHWidth("bold " + issueTableConfig.width) .setDAlign("text-center") .setDRenderer("DOWN_COMMON_SEVERITY")); break; - case "DOWN_ASSIGNEE_TEAM" : // �떞�떦遺��꽌 - $scope.vm.downTableConfigs.push($tableProvider.config() + case "DOWN_ASSIGNEE_TEAM" : // �븯�쐞 �씠�뒋 �떞�떦遺��꽌 + $scope.vm.downTableConfigs.push($downProvider.config() .setHName("common.assigneeTeam") + .setDName("departmentVos.departmentName") .setDType("renderer") - .setHWidth("bold " + Down_issueTableConfig.width) + .setHWidth("bold " + issueTableConfig.width) .setDAlign("text-center") .setDRenderer("DOWN_ISSUE_DEPARTMENT")); break; - case "DOWN_REGISTER" : // �벑濡앹옄 - $scope.vm.downTableConfigs.push($tableProvider.config() + case "DOWN_REGISTER" : // �븯�쐞 �씠�뒋 �벑濡앹옄 + $scope.vm.downTableConfigs.push($downProvider.config() .setHName("common.register") + .setDName("registerVo.id") .setDType("renderer") - .setHWidth("bold " + Down_issueTableConfig.width) + .setHWidth("bold " + issueTableConfig.width) .setDAlign("text-center") .setDRenderer("DOWN_REGISTER")); break; - case "DOWN_PERIOD" : // 湲곌컙 - $scope.vm.downTableConfigs.push($tableProvider.config() + case "DOWN_PERIOD" : // �븯�쐞 �씠�뒋 湲곌컙 + $scope.vm.downTableConfigs.push($downProvider.config() .setHName("common.period") .setDType("renderer") - .setHWidth("bold " + Down_issueTableConfig.width) + .setHWidth("bold " + issueTableConfig.width) .setDAlign("text-center") .setDRenderer("DOWN_ISSUE_DUE_DATE")); break; - case "DOWN_MODIFY_DATE" : // 理쒓렐 蹂�寃쎌씪 - $scope.vm.downTableConfigs.push($tableProvider.config() + case "DOWN_MODIFY_DATE" : // �븯�쐞 �씠�뒋 理쒓렐 蹂�寃쎌씪 + $scope.vm.downTableConfigs.push($downProvider.config() .setHName("common.lastChangeDate") - .setHWidth("bold " + Down_issueTableConfig.width) - .setDAlign("text-center")); + .setHWidth("bold " + issueTableConfig.width) + .setDAlign("text-center") + .setDName("modifyDate")); break; } // �궗�슜�옄 �젙�쓽 �븘�뱶 而щ읆 - if (Down_issueTableConfig.key.indexOf("CUSTOM_FIELD_") !== -1) { + if (issueTableConfig.key.indexOf("CUSTOM_FIELD_") !== -1) { // 留뚯빟 �씠�뒋 �뀒�씠釉� 而щ읆紐낆씠 �몴�떆�릺吏� �븡�쑝硫� �씠履쎌씠 臾몄젣 for (var count in $scope.vm.customFields) { var customField = $scope.vm.customFields[count]; - if (customField.id === Number(Down_issueTableConfig.key.substring(13))) { - $scope.vm.downTableConfigs.push($tableProvider.config() + if (customField.id === Number(issueTableConfig.key.substring(13))) { + $scope.vm.downTableConfigs.push($downProvider.config() .setHName(customField.name) + .setDName("downCustomFieldName" + [count]) .setDType("renderer") - .setHWidth("bold " + Down_issueTableConfig.width) + .setHWidth("bold " + issueTableConfig.width) .setDAlign("text-center") .setColumnHint(customField) .setDRenderer("DOWN_ISSUE_CUSTOM_FIELD_VALUE_VIEW")); @@ -517,18 +534,18 @@ // �뿰愿� �씠�뒋 �뀒�씠釉� �꽕�젙 function makeRelTableConfigs() { $scope.vm.relTableConfigs = []; - $scope.vm.relTableConfigs.push($tableProvider.config() + $scope.vm.relTableConfigs.push($relProvider.config() .setDType("checkbox") .setHWidth("width-20-p") .setDAlign("text-center")) - $scope.vm.relTableConfigs.push($tableProvider.config() + $scope.vm.relTableConfigs.push($relProvider.config() .setHName("issue.relationIssueType") .setDType("renderer") .setDAlign("text-center") .setHWidth("width-60-p bold") .setHSort(false) .setDRenderer("ISSUE_RELATION_TYPE")) - $scope.vm.relTableConfigs.push($tableProvider.config() + $scope.vm.relTableConfigs.push($relProvider.config() .setHName("issue.relationIssueTitle") .setDType("renderer") .setDAlign("text-center") @@ -536,7 +553,7 @@ .setHSort(false) .setDRenderer("ISSUE_RELATION_MOVE")) /*if($scope.vm.viewer.modifyPermissionCheck) { - $scope.vm.relTableConfigs.push($tableProvider.config() + $scope.vm.relTableConfigs.push($relProvider.config() .setHName("issue.relationIssueDelete") .setDType("renderer") .setDAlign("text-center") @@ -545,11 +562,11 @@ .setHSort(false) .setDAlign("text-center")) }*/ - angular.forEach($scope.vm.relTableConfigs, function (Rel_issueTableConfig) { + angular.forEach($scope.vm.relTableConfigs, function (issueTableConfig) { // �몴�떆 ���긽�씤 而щ읆留� �솕硫댁뿉 洹몃젮以��떎. - if (Rel_issueTableConfig.display) { + if (issueTableConfig.display) { // �뀒�씠釉붿쓽 而щ읆�쓣 留뚮뱾�뼱以��떎. - $scope.fn.setRelTableColumn(Rel_issueTableConfig); + $scope.fn.setRelTableColumn(issueTableConfig); } }); } @@ -557,11 +574,11 @@ // �븯�쐞 �씠�뒋 �뀒�씠釉� �꽕�젙 function makeDownTableConfigs() { $scope.vm.downTableConfigs = []; - $scope.vm.downTableConfigs.push($tableProvider.config() + $scope.vm.downTableConfigs.push($downProvider.config() .setDType("checkbox") .setHWidth("width-20-p") .setDAlign("text-center")) - $scope.vm.downTableConfigs.push($tableProvider.config() + $scope.vm.downTableConfigs.push($downProvider.config() .setHName("issue.downIssueTitle") .setDType("renderer") .setDAlign("text-center") @@ -569,7 +586,7 @@ .setHSort(false) .setDRenderer("ISSUE_DOWN_MOVE")) /*if($scope.vm.viewer.modifyPermissionCheck){ - $scope.vm.downTableConfigs.push($tableProvider.config() + $scope.vm.downTableConfigs.push($downProvider.config() .setHName("issue.relationIssueDelete") .setDType("renderer") .setDAlign("text-center") @@ -579,11 +596,11 @@ .setDAlign("text-center")) }*/ - angular.forEach($scope.vm.downTableConfigs, function (Down_issueTableConfig) { + angular.forEach($scope.vm.downTableConfigs, function (issueTableConfig) { // �몴�떆 ���긽�씤 而щ읆留� �솕硫댁뿉 洹몃젮以��떎. - if (Down_issueTableConfig.display) { + if (issueTableConfig.display) { // �뀒�씠釉붿쓽 而щ읆�쓣 留뚮뱾�뼱以��떎. - $scope.fn.setDownTableColumn(Down_issueTableConfig); + $scope.fn.setDownTableColumn(issueTableConfig); } }); } @@ -596,7 +613,7 @@ } var issueTableConfigs = issueTableConfigVo.issueTableConfigs; - // �뿰愿� �뒋 紐⑸줉 �뀒�씠釉� �꽕�젙 媛믪쓣 媛��졇���꽌 �쟻�슜�븳�떎. + // �뿰愿� �씠�뒋 紐⑸줉 �뀒�씠釉� �꽕�젙 媛믪쓣 媛��졇���꽌 �쟻�슜�븳�떎. if ($rootScope.isDefined(issueTableConfigs)) { // �씠�뒋 �뀒�씠釉� �꽕�젙 �젙蹂대�� ���옣 �븳�떎. @@ -607,34 +624,34 @@ }); $scope.vm.relTableConfigs = []; - /* $scope.vm.relTableConfigs.push($tableProvider.config() + /* $scope.vm.relTableConfigs.push($relProvider.config() .setHName("issue.relationIssueType") .setDType("renderer") .setDAlign("text-center") .setHWidth("width-30-p bold") .setHSort(false) .setDRenderer("ISSUE_RELATION_TYPE")) - $scope.vm.relTableConfigs.push($tableProvider.config() + $scope.vm.relTableConfigs.push($relProvider.config() .setHName("issue.relationIssueTitle") .setDType("renderer") .setDAlign("text-center") .setHWidth("width-60-p bold") .setHSort(false) .setDRenderer("ISSUE_RELATION_MOVE"))*/ - $scope.vm.relTableConfigs.push($tableProvider.config() + $scope.vm.relTableConfigs.push($relProvider.config() .setDType("checkbox") .setHWidth("width-20-p") .setDAlign("text-center")) - angular.forEach($scope.vm.issueRelTableConfigs, function (Rel_issueTableConfig) { + angular.forEach($scope.vm.issueRelTableConfigs, function (issueTableConfig) { // �몴�떆 ���긽�씤 而щ읆留� �솕硫댁뿉 洹몃젮以��떎. - if (Rel_issueTableConfig.display) { + if (issueTableConfig.display) { // �뀒�씠釉붿쓽 而щ읆�쓣 留뚮뱾�뼱以��떎. - $scope.fn.setRelTableColumn(Rel_issueTableConfig); + $scope.fn.setRelTableColumn(issueTableConfig); } }); /*if($scope.vm.viewer.modifyPermissionCheck) { - $scope.vm.relTableConfigs.push($tableProvider.config() + $scope.vm.relTableConfigs.push($relProvider.config() .setHName("issue.relationIssueDelete") .setDType("renderer") .setHWidth("width-40-p bold") @@ -653,7 +670,7 @@ if (issueTableConfigVo == null) return; var issueTableConfigs = issueTableConfigVo.issueTableConfigs; - // �뿰愿� �뒋 紐⑸줉 �뀒�씠釉� �꽕�젙 媛믪쓣 媛��졇���꽌 �쟻�슜�븳�떎. + // �뿰愿� �씠�뒋 紐⑸줉 �뀒�씠釉� �꽕�젙 媛믪쓣 媛��졇���꽌 �쟻�슜�븳�떎. if ($rootScope.isDefined(issueTableConfigs)) { // �씠�뒋 �뀒�씠釉� �꽕�젙 �젙蹂대�� ���옣 �븳�떎. $scope.vm.issueDownTableConfigs = []; @@ -662,26 +679,26 @@ return a.position < b.position ? -1 : a.position > b.position ? 1 : 0; }); $scope.vm.downTableConfigs = []; -/* $scope.vm.downTableConfigs.push($tableProvider.config() +/* $scope.vm.downTableConfigs.push($downProvider.config() .setHName("issue.downIssueTitle") .setDType("renderer") .setDAlign("text-center") .setHWidth("width-60-p bold") .setHSort(false) .setDRenderer("ISSUE_DOWN_MOVE"))*/ - $scope.vm.downTableConfigs.push($tableProvider.config() + $scope.vm.downTableConfigs.push($downProvider.config() .setDType("checkbox") .setHWidth("width-20-p") .setDAlign("text-center")) - angular.forEach($scope.vm.issueDownTableConfigs, function (Down_issueTableConfig) { + angular.forEach($scope.vm.issueDownTableConfigs, function (issueTableConfig) { // �몴�떆 ���긽�씤 而щ읆留� �솕硫댁뿉 洹몃젮以��떎. - if (Down_issueTableConfig.display) { + if (issueTableConfig.display) { // �뀒�씠釉붿쓽 而щ읆�쓣 留뚮뱾�뼱以��떎. - $scope.fn.setDownTableColumn(Down_issueTableConfig); + $scope.fn.setDownTableColumn(issueTableConfig); } }); /*if($scope.vm.viewer.modifyPermissionCheck) { - $scope.vm.downTableConfigs.push($tableProvider.config() + $scope.vm.downTableConfigs.push($downProvider.config() .setHName("issue.relationIssueDelete") .setDType("renderer") .setHWidth("width-40-p bold") @@ -1023,6 +1040,8 @@ $scope.vm.viewer.startDate = result.data.data.startDate == null ? "common.unspecified" : result.data.data.startDate; // 誘몄��젙 $scope.vm.viewer.completeDate = result.data.data.completeDate == null ? "common.unspecified" : result.data.data.completeDate; // 誘몄��젙 + $scope.vm.rangeDate = result.data.data.startDate + "~" + result.data.data.completeDate + // �씠�뒋 �쑀�삎�뿉 �뿰寃곕맂 �궗�슜�옄 �젙�쓽 �븘�뱶 �젙蹂대�� �엯�젰 �뤌�뿉�꽌 �궗�슜�븷 �닔 �엳寃� 媛�怨듯븳�떎. $scope.fn.setFormByIssueTypeCustomFields(result.data.data.issueTypeCustomFieldVos); // �씠�뒋�뿉�꽌 �궗�슜�옄媛� �꽑�깮�븳 �궗�슜�옄 �젙�쓽 �븘�뱶 媛믪쓣 �엯�젰 �뤌�뿉 �뀑�똿�븳�떎. @@ -1339,6 +1358,21 @@ }); } + // �씪諛� 硫붿씪 諛쒖넚 (�궗�슜�옄 吏곸젒 �옉�꽦) + function sendCommonMail() { + $uibModal.open({ + templateUrl : 'views/issue/issueCommonSendMail.html', + size : "md", + controller : 'issueCommonSendMailController', + backdrop : 'static', + resolve : { + parameter : { + issueId : $scope.vm.viewer.id, + } + } + }); + } + function getParametersAll() { var params = $scope.fn.getParameters(null, $scope.vm.viewer.issueCompanyVos); params = $scope.fn.getParameters(params, $scope.vm.viewer.issueIspVos); diff --git a/src/main/webapp/scripts/app/issue/issueList.controller.js b/src/main/webapp/scripts/app/issue/issueList.controller.js index 8f38e3d..5915af6 100644 --- a/src/main/webapp/scripts/app/issue/issueList.controller.js +++ b/src/main/webapp/scripts/app/issue/issueList.controller.js @@ -336,7 +336,7 @@ case "ISSUE_TITLE" : // �씠�뒋 �젣紐� $scope.vm.tableConfigs.push($tableProvider.config() .setHName("issue.issueTitle") - .setDName("issueNumber") /* todo �씠嫄� ���씠��濡� 蹂�寃쏀빐�빞�븯�뒗�뜲*/ + .setDName("issueTitle") .setDType("renderer") .setHWidth("bold " + issueTableConfig.width) .setDAlign("text-center") @@ -373,7 +373,7 @@ case "ASSIGNEE_TEAM" : // �떞�떦遺��꽌 $scope.vm.tableConfigs.push($tableProvider.config() .setHName("common.assigneeTeam") - .setDName("departmentName") /* todo 泥댄겕*/ + .setDName("departmentName") .setDType("renderer") .setHWidth("bold " + issueTableConfig.width) .setDAlign("text-center") @@ -391,7 +391,6 @@ case "PERIOD" : // 湲곌컙 $scope.vm.tableConfigs.push($tableProvider.config() .setHName("common.period") - .setDName("startDate") .setDType("renderer") .setHWidth("bold " + issueTableConfig.width) .setDAlign("text-center") diff --git a/src/main/webapp/scripts/app/issue/issueSendMailPartners.controller.js b/src/main/webapp/scripts/app/issue/issueSendMailPartners.controller.js index 9e8d0c7..32b7a6e 100644 --- a/src/main/webapp/scripts/app/issue/issueSendMailPartners.controller.js +++ b/src/main/webapp/scripts/app/issue/issueSendMailPartners.controller.js @@ -17,7 +17,6 @@ formCheck : formCheck, // �뤌 泥댄겕 onChangeEmailTemplate : onChangeEmailTemplate, // �씠硫붿씪 �뀥�뵆由� �꽑�깮�떆 �떎�뻾 getEmailTemplateList : getEmailTemplateList // �씠硫붿씪 �뀥�뵆由� 紐⑸줉 媛��졇�삤湲� - // showEmailTemplate : showEmailTemplate, }; $scope.vm = { @@ -26,6 +25,7 @@ hostingVos : parameter.hostingVos, partners : parameter.partnersAll.slice(), html : "", + tab : "SEND_TEMPLATE", form : { id : parameter.issueId, // �씠�뒋 踰덊샇 projects : [{ id : parameter.projectId}], // �봽濡쒖젥�듃 @@ -59,7 +59,8 @@ $scope.vm.html = result.data.data.template; } else { - SweetAlert.error($filter("translate")("issue.failedIssueMail"), result.data.message.message); // "�씠�뒋 硫붿씪 諛쒖넚 �떎�뙣" + $scope.vm.html = ""; + //SweetAlert.warning($filter("translate")("issue.selectedPartnersMail"),$filter("translate")("issue.selectedPartnersTemplate")); // option �꽑�깮 寃쎄퀬 } $rootScope.spinner = false; @@ -85,14 +86,13 @@ $scope.vm.emailTemplateId = 1; $scope.vm.emailTitle = ""; - $scope.vm.emailTemplates.forEach(function (emailTemplate) { - /*if (emailTemplate.id === $scope.vm.emailTemplateId) { - $scope.vm.emailTitle = emailTemplate.title; - }*/ - if (emailTemplate.templateType === $scope.vm.emailTemplateType) { - $scope.vm.emailTitle = emailTemplate.title; - } - }) + if ($rootScope.isDefined($scope.vm.emailTemplateType)) { + $scope.vm.emailTemplates.forEach(function (emailTemplate) { + if (emailTemplate.templateType === $scope.vm.emailTemplateType) { + $scope.vm.emailTitle = emailTemplate.title; + } + }) + } } @@ -182,6 +182,7 @@ } $scope.fn.getEmailTemplateList(); + }]); }); diff --git a/src/main/webapp/scripts/app/project/projectModify.controller.js b/src/main/webapp/scripts/app/project/projectModify.controller.js index 722b8ba..0abec6f 100644 --- a/src/main/webapp/scripts/app/project/projectModify.controller.js +++ b/src/main/webapp/scripts/app/project/projectModify.controller.js @@ -182,7 +182,7 @@ if (angular.isDefined(result.data.data)) { $scope.vm.form.name = result.data.data.name; $scope.vm.form.status = result.data.data.status; - if (result.data.data.startDate == "" && result.data.data.endDate == "") { + if (result.data.data.startDate == "" && result.data.data.endDate == "" || result.data.data.startDate == "null" && result.data.data.endDate == "null") { $scope.vm.form.startEndDateRange = "" } else { $scope.vm.form.startEndDateRange = result.data.data.startDate + " ~ " + result.data.data.endDate; diff --git a/src/main/webapp/scripts/components/auth/auth.interceptor.js b/src/main/webapp/scripts/components/auth/auth.interceptor.js index 632510c..26869c0 100644 --- a/src/main/webapp/scripts/components/auth/auth.interceptor.js +++ b/src/main/webapp/scripts/components/auth/auth.interceptor.js @@ -11,6 +11,16 @@ $tableProvider.setOrderByColumn(); $tableProvider.reverse = false; + // �뿰愿� �뀒�씠釉� 而щ읆 �젙�젹 珥덇린�솕 + var $relProvider = $injector.get('$relProvider'); + $relProvider.setOrderByColumn(); + $relProvider.reverse = false; + + // �븯�쐞 �뀒�씠釉� 而щ읆 �젙�젹 珥덇린�솕 + var $downProvider = $injector.get('$downProvider'); + $downProvider.setOrderByColumn(); + $downProvider.reverse = false; + if (angular.isDefined(config.data)) { $log.debug(config.url + " : ", config.data); } diff --git a/src/main/webapp/scripts/components/issue/issue.service.js b/src/main/webapp/scripts/components/issue/issue.service.js index 8290ed9..d9f9086 100644 --- a/src/main/webapp/scripts/components/issue/issue.service.js +++ b/src/main/webapp/scripts/components/issue/issue.service.js @@ -144,6 +144,12 @@ $log.debug("�씠�뒋 �씠硫붿씪 諛쒖넚 寃곌낵 : ", response); return response; }); + }, + sendCommonEmail : function (conditions) { + return $http.post("issue/sendCommonEmail", conditions).then(function (response) { + $log.debug("�씠�뒋 �씠硫붿씪 諛쒖넚 寃곌낵 : ", response); + return response; + }); } } } diff --git a/src/main/webapp/scripts/config.js b/src/main/webapp/scripts/config.js index be59c2b..4eb1604 100644 --- a/src/main/webapp/scripts/config.js +++ b/src/main/webapp/scripts/config.js @@ -35,7 +35,7 @@ // 濡쒓렇 �젣�뼱 $logProvider.debugEnabled(true); }) - .run(function ($rootScope, $state, $sce, $log, $injector, $translate, $tableProvider, Principal, Auth, Language, SweetAlert, $filter, Workspace, $resourceProvider, User, constants, Project) { + .run(function ($rootScope, $state, $sce, $log, $injector, $translate, $tableProvider, $relProvider, $downProvider, Principal, Auth, Language, SweetAlert, $filter, Workspace, $resourceProvider, User, constants, Project) { $rootScope.$state = $state; // html �깭洹� �쎒 蹂댁븞 �쟻�슜�븯�뿬 諛붿씤�뵫. @@ -117,6 +117,12 @@ // �뀒�씠釉� �꽕�젙 諛� 湲곕뒫�쓣 愿�由ы븯�뒗 �꽌鍮꾩뒪 $rootScope.$tableProvider = $tableProvider; + + // �뿰愿��뀒�씠釉� �꽕�젙 諛� 湲곕뒫 愿�由ы븯�뒗 �꽌鍮꾩뒪 + $rootScope.$relProvider = $relProvider; + + // �븯�쐞�뀒�씠釉� �꽕�젙 諛� 湲곕뒫 愿�由ы븯�뒗 �꽌鍮꾩뒪 + $rootScope.$downProvider = $downProvider; // html tag convert - �떊猶고븷 �닔 �엳�뒗 �엯�젰 媛믪씪 �븣留� �궗�슜, �궗�슜�옄媛� �벑濡앺븯�뒗 媛믪뿉�뒗 �궗�슜 湲덉� $rootScope.trustAsHtml = function (string) { @@ -568,6 +574,9 @@ // table orderBy column init setting $tableProvider.setOrderByColumn(); $tableProvider.reverse = false; + + $relProvider.setOrderByColumn(); + $relProvider.reverse = false; // �씠�뒋 紐⑸줉->�긽�꽭�솕硫댁뿉�꽌 留덉�留됱쑝濡� �젒洹쇳븳 �씠�뒋 �븘�씠�뵒 - �씪�슦�듃 �깉�븣留덈떎 珥덇린�솕 $rootScope.currentDetailIssueId = null; // �궗�슜�옄 �젙蹂대�� 媛��졇�삩�떎. diff --git a/src/main/webapp/scripts/main.js b/src/main/webapp/scripts/main.js index 20165a1..7e5677d 100644 --- a/src/main/webapp/scripts/main.js +++ b/src/main/webapp/scripts/main.js @@ -56,13 +56,19 @@ 'commonController' : 'app/common/common.controller', // 怨듯넻 而⑦듃濡ㅻ윭 'tableProvider' : '../custom_components/js-table/table.provider', // �뀒�씠釉� �냽�꽦 媛믪쓣 愿�由ы븳�떎. 'treeProvider' : '../custom_components/js-tree/tree.provider', // �듃由� �냽�꽦 媛믪쓣 愿�由ы븳�떎. + 'relProvider' : '../custom_components/js-rel/rel.provider', // �뿰愿� �뀒�씠釉� �냽�꽦 媛믪쓣 愿�由ы븳�떎. + 'downProvider' : '../custom_components/js-down/down.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', // 紐⑸줉 �솕硫댁뿉�꽌 �궗�슜�릺�뒗 �뀒�씠釉붿쓣 �샇異쒗븳�떎. 'jsTree' : '../custom_components/js-tree/js-tree.directive', // 紐⑸줉 �솕硫댁뿉�꽌 �궗�슜�릺�뒗 �뀒�씠釉�(�듃由ш뎄議�)�쓣 �샇異쒗븳�떎. + 'jsRel' : '../custom_components/js-rel/js-rel.directive', // �씠�뒋�긽�꽭 �솕硫댁뿉�꽌 �궗�슜�릺�뒗 �뿰愿� �뀒�씠釉붿쓣 �샇異쒗븳�떎. + 'jsDown' : '../custom_components/js-down/js-down.directive', // �씠�뒋�긽�꽭 �솕硫댁뿉�꽌 �궗�슜�릺�뒗 �븯�쐞 �뀒�씠釉붿쓣 �샇異쒗븳�떎. 'tableColumnGenerator' : '../custom_components/js-table/tableColumnGenerator.directive', // �뀒�씠釉� �옖�뜑�윭瑜� �떞�떦�븳�떎. - 'treeColumnGenerator' : '../custom_components/js-tree/treeColumnGenerator.directive', // �뀒�씠釉� �옖�뜑�윭瑜� �떞�떦�븳�떎. + 'treeColumnGenerator' : '../custom_components/js-tree/treeColumnGenerator.directive', // �씠�뒋由ъ뒪�듃 �듃由� �옖�뜑�윭瑜� �떞�떦�븳�떎. + 'relColumnGenerator' : '../custom_components/js-rel/relColumnGenerator.directive', // �씠�뒋�긽�꽭 �뿰愿� �옖�뜑�윭瑜� �떞�떦�븳�떎. + 'downColumnGenerator' : '../custom_components/js-down/downColumnGenerator.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 湲곕뒫�씠 遺숈� 而댄룷�꼳�듃 @@ -191,7 +197,8 @@ 'issueAddTableConfigController' : 'app/issue/issueAddTableConfig.controller', // �씠�뒋 �뀒�씠釉� �꽕�젙 而⑦듃濡ㅻ윭 'issueAddRelationTableConfigController' : 'app/issue/issueAddRelationTableConfig.controller', // �씠�뒋 �뀒�씠釉� �꽕�젙 而⑦듃濡ㅻ윭 'issueAddDownTableConfigController' : 'app/issue/issueAddDownTableConfig.controller', // �씠�뒋 �뀒�씠釉� �꽕�젙 而⑦듃濡ㅻ윭 - 'issueSendMailPartnersController' : 'app/issue/issueSendMailPartners.controller', // �씠�뒋 �씠硫붿씪 諛쒖넚 而⑦듃濡ㅻ윭 + 'issueSendMailPartnersController' : 'app/issue/issueSendMailPartners.controller', // �뾽泥� �씠硫붿씪 諛쒖넚 而⑦듃濡ㅻ윭 + 'issueCommonSendMailController' : 'app/issue/issueCommonSendMail.controller', // �씪諛� �씠硫붿씪 諛쒖넚 而⑦듃濡ㅻ윭 'issueVersionViewController' : 'app/issue/issueVersionView.controller', // �씠�뒋 踰꾩쟾 �솗�씤 而⑦듃濡ㅻ윭 'issueReservationController' : 'app/issue/issueReservation.controller', // �씠�뒋 諛쒖깮 �삁�빟 而⑦듃濡ㅻ윭 'issueModifyUserController' : 'app/issue/issueModifyUser.controller', // �씠�뒋 �떞�떦�옄 而⑦듃濡ㅻ윭 @@ -409,10 +416,22 @@ 'jsTree' : { deps : ['app'] }, + 'jsRel' : { + deps : ['app'] + }, + 'jsDown' : { + deps : ['app'] + }, 'tableColumnGenerator' : { deps : ['app'] }, 'treeColumnGenerator' : { + deps : ['app'] + }, + 'relColumnGenerator' : { + deps : ['app'] + }, + 'downColumnGenerator' : { deps : ['app'] }, 'ngStomp' : { @@ -506,6 +525,7 @@ 'config', // angularJs �꽕�젙 - route �씠�룞 愿��젴, �씠�룞�떆 珥덇린�솕 濡쒖쭅�씠 �뱾�뼱�엳�떎. - 吏곸젒 濡쒕뱶 'constants', 'commonController', + 'issueCommonSendMailController', 'autoCompleteController', 'userInviteController', 'issueAddController', // �씠�뒋 留뚮뱾湲곗뿉�꽌 �궗�슜 @@ -534,6 +554,8 @@ 'resourceProvider', 'tableProvider', 'treeProvider', + 'relProvider', + 'downProvider', 'permissionService', 'authService', 'userInviteService', diff --git a/src/main/webapp/views/issue/issueCommonSendMail.html b/src/main/webapp/views/issue/issueCommonSendMail.html new file mode 100644 index 0000000..c2f3ab4 --- /dev/null +++ b/src/main/webapp/views/issue/issueCommonSendMail.html @@ -0,0 +1,69 @@ +<div class="formModal"> + <div class="modal-header faded smaller"> + <div class="modal-title"> + <strong translate="issue.CommonSendIssueMail">�씪諛� 硫붿씪 諛쒖넚</strong> + </div> + <button aria-label="Close" class="close" type="button" ng-click="fn.cancel()"> + <span aria-hidden="true"> ×</span> + </button> + </div> + + <div class="modal-body"> + <form role="form" name="issueSendForm"> + <button type="button" class="btn btn-secondary mr-3 float-right mb-1" ng-click="fn.addInput()"> + <span translate="common.add">異붽�</span> + </button> + <div class="form-group"> + <label class="issue-label mt-2"><span translate="common.toPerson">諛쏅뒗 �궗�엺</span> <code class="highlighter-rouge">*</code></label> + <div class="input-group" ng-repeat="i in vm.form.inputs"> + <input type="text" + name="email" + class="form-control mt-1" + kr-input + ng-model="vm.form.emails[$index]" + ng-pattern="/^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/" + required + autocomplete="off"> + <span class="select3-selection__email__remove" ng-click="fn.removeInput($index)">횞</span> + </div> + <small translate="common.emailExplain">諛쏅뒗 �궗�엺�쓽 �씠硫붿씪 �삎�떇�쓣 �엯�젰�븯�뀛�빞 �빀�땲�떎.</small> + <div ng-if="issueSendForm.email.$error.pattern" class="help-block form-text text-danger" + translate="common.invalidEmailFormat">�씠硫붿씪 �삎�떇�씠 留욎� �븡�뒿�땲�떎. + </div> + </div> + + + <label class="issue-label"><span translate="common.title">�젣紐�</span></label> + <input id="title" + type="text" + name="title" + class="form-control mt-1" + kr-input + ng-model="vm.form.title" + autocomplete="off"> + + <div class="form-group mb10 mt-10"> + <label class="issue-label"><span translate="common.content">�궡�슜</span></label> + <summernote + class="summernote mt-1" + lang="ko-KR" + summer-note-auto-focus + ng-model="vm.form.description" + data-editor="vm.summerNote.editor" + data-editable="vm.summerNote.editable" + on-image-upload="fn.imageUpload(files)" + target=".note-editable"></summernote> + </div> + <small class="mt-1" translate="common.sendToPerson">�떎瑜� �궗�슜�옄�뿉寃� 硫붿씪�쓣 蹂대깄�땲�떎.</small> + </form> + </div> + + <div class="modal-footer buttons-on-right"> + <button type="button" class="btn btn-md btn-grey" ng-click="fn.cancel()"><span + translate="common.cancel">痍⑥냼</span></button> + <button type="button" class="btn btn-md btn-primary bold" + ng-disabled="fn.formCheck(issueSendForm.$invalid)" + ng-click="fn.formSubmit()"><span translate="issue.sendMail">�씠硫붿씪 諛쒖넚</span> + </button> + </div> +</div> diff --git a/src/main/webapp/views/issue/issueDetail.html b/src/main/webapp/views/issue/issueDetail.html index 2bbc36d..3d7c70e 100644 --- a/src/main/webapp/views/issue/issueDetail.html +++ b/src/main/webapp/views/issue/issueDetail.html @@ -102,7 +102,8 @@ </div> </span> <a class="show-ticket-info cursor"> - <i class="os-icon os-icon-email-forward mr-20" ng-if="vm.viewer.modifyPermissionCheck" ng-click="fn.sendMailAll()" data-toggle="tooltip" data-placement="right" title="�떎瑜� �궗�슜�옄�뿉寃� �씠�뒋 蹂대궡湲�"></i> + <i class="os-icon os-icon-email-2-at2 mr-20" ng-if="vm.viewer.modifyPermissionCheck" ng-click="fn.sendCommonMail()" data-toggle="tooltip" data-placement="right" title="吏곸젒 �옉�꽦�븳 硫붿씪 蹂대궡湲�"></i> + <i class="os-icon os-icon-email-forward mr-20" ng-if="vm.viewer.modifyPermissionCheck" ng-click="fn.sendMailAll()" data-toggle="tooltip" data-placement="right" title="�뾽泥� 硫붿씪 蹂대궡湲�"></i> <i class="os-icon os-icon-airplay mr-20" ng-click="fn.versionView(vm.viewer.id)" data-toggle="tooltip" data-placement="right" title="�씠�뒋 蹂�寃� �씠�젰 �긽�꽭 蹂닿린"></i> <i class="os-icon os-icon-calendar-time mr-20" ng-if="vm.viewer.modifyPermissionCheck" ng-click="fn.reservation(vm.viewer.id)" data-toggle="tooltip" data-placement="right" title="�씠�뒋 諛쒖깮 �삁�빟 �븯湲�"></i> @@ -524,8 +525,8 @@ <!-- �뿰愿� �씠�뒋 �뀒�씠釉� --> <div class="mt-10 issue-detail-word-break width-100"> - <js-table data="vm.viewer.issueRelationVos" table-configs="vm.relTableConfigs" - event="relTableEvent" detail-view="true" hide-header="false" use-sort="true"></js-table> + <js-rel data="vm.viewer.issueRelationVos" table-configs="vm.relTableConfigs" + event="relTableEvent" detail-view="true" hide-header="false" use-sort="true"></js-rel> <div class="row" ng-if="vm.viewer.modifyPermissionCheck"> <div class="col-sm-4"> @@ -625,8 +626,8 @@ <!-- �븯�쐞 �씠�뒋 �뀒�씠釉� --> <div class="mt-10 issue-detail-word-break width-100"> - <js-table data="vm.viewer.issueDownVos" table-configs="vm.downTableConfigs" - event="downTableEvent" detail-view="true" hide-header="false" use-sort="true"></js-table> + <js-down data="vm.viewer.issueDownVos" table-configs="vm.downTableConfigs" + event="downTableEvent" detail-view="true" hide-header="false" use-sort="true"></js-down> <div class="row" ng-if="vm.viewer.modifyPermissionCheck"> <div class="col-sm-6"> diff --git a/src/main/webapp/views/issue/issueSendMailPartners.html b/src/main/webapp/views/issue/issueSendMailPartners.html index 6fdc84d..40eb4af 100644 --- a/src/main/webapp/views/issue/issueSendMailPartners.html +++ b/src/main/webapp/views/issue/issueSendMailPartners.html @@ -1,7 +1,7 @@ <div class="formModal"> <div class="modal-header faded smaller"> <div class="modal-title"> - <strong translate="issue.selectSendIssueMail">�씠�뒋 硫붿씪 諛쒖넚 ���긽�옄 �꽑�깮</strong> + <strong translate="issue.selectSendIssueMail">�씠�뒋 硫붿씪 諛쒖넚</strong> </div> <button aria-label="Close" class="close" type="button" ng-click="fn.cancel()"> <span aria-hidden="true"> ×</span> @@ -20,6 +20,9 @@ </span> </div> + <label class="issue-label mt-10"> + <span translate="issue.selectPartners">�뾽泥� �꽑�깮</span> <code class="highlighter-rouge">*</code> + </label> <js-input-autocomplete data-input-name="mailUsers" owl-auto-focus target=".auto-complete-i0nput" @@ -29,38 +32,50 @@ page="vm.autoCompletePage.user.page" total-page="vm.autoCompletePage.user.totalPage" source="fn.getMailTargetAll(vm.form.mailUsers)" - translation-texts="{ empty : 'common.emptyUser'}" + translation-texts="{ empty : 'common.emptyCompanyPartners'}" input-disabled="vm.form.mailUsers == null" extra-settings="{ displayProp : 'name' , idProp : 'id', imageable : false, imagePathProp : 'profile', type : 'partner', maxlength : 100, autoResize : true, stopRemoveBodyEvent : true }"></js-input-autocomplete> - <div class="Template-area mt-20"> - <div class="form-group mb10"> - <label for="emailTemplateForm" class="issue-label"> - <span translate="common.emailTemplate">�씠硫붿씪 �뀥�뵆由�</span> - </label> - <select id="emailTemplateForm" - name="emailTemplate" - class="form-control input-sm issue-select-label" - ng-model="vm.emailTemplateType" - ng-change="fn.onChangeEmailTemplate()" - required> - <option ng-repeat="emailTemplate in vm.emailTemplates" - value="{{emailTemplate.templateType}}" - translate="{{emailTemplate.title}}"> - </option> - </select> - </div> - </div> - <summernote - class="summernote" - lang="ko-KR" - config="vm.options" - ng-model="vm.html" - target=".note-editable"></summernote> + + <div class="form-group mb10 mt-20"> + <label for="emailTemplateForm" class="issue-label"> + <span translate="issue.partners">�뾽泥� �씠硫붿씪</span> <code class="highlighter-rouge">*</code> + </label> + <select id="emailTemplateForm" + name="emailTemplate" + class="form-control input-sm issue-select-label" + ng-model="vm.emailTemplateType" + ng-change="fn.onChangeEmailTemplate()" + required> + <option value="" ng-selected="true">�꽑�깮�븯�꽭�슂</option> + <option ng-repeat="emailTemplate in vm.emailTemplates" + value="{{emailTemplate.templateType}}" + translate="{{emailTemplate.title}}"> + </option> + </select> + </div> + + <label class="issue-label"><span translate="common.title">�젣紐�</span></label> + <input id="title" + type="text" + name="title" + class="form-control" + kr-input + ng-model="vm.emailTitle" + autocomplete="off"> + + <div class="form-group mb10 mt-10"> + <label class="issue-label"><span translate="common.content">�궡�슜</span></label> + <summernote + class="summernote" + lang="ko-KR" + config="vm.options" + ng-model="vm.html" + target=".note-editable"></summernote> + </div> </div> </form> </div> - <div class="modal-footer buttons-on-right"> <button type="button" class="btn btn-md btn-grey" ng-click="fn.cancel()"><span -- Gitblit v1.8.0