[Notice] Announcing the End of Demo Server [Read me]

fix a bug related to adding comment w/o contents and add isAuthorEditable option on project setting and apply it to issue
@8033200134f33da2423decdeab6927e2047c2a8b
--- app/controllers/IssueApp.java
+++ app/controllers/IssueApp.java
... | ... | @@ -5,36 +5,29 @@ |
5 | 5 |
package controllers; |
6 | 6 |
|
7 | 7 |
import java.io.File; |
8 |
-import java.util.List; |
|
9 |
- |
|
10 |
-import com.avaje.ebean.Page; |
|
11 | 8 |
|
12 | 9 |
import models.Issue; |
13 | 10 |
import models.IssueComment; |
14 |
-import models.Milestone; |
|
15 |
-import models.Post; |
|
16 |
-import models.User; |
|
17 | 11 |
import models.Project; |
18 | 12 |
import models.enumeration.Direction; |
19 | 13 |
import models.enumeration.IssueState; |
20 |
-import models.enumeration.PermissionOperation; |
|
21 |
-import models.enumeration.PermissionResource; |
|
22 | 14 |
import models.enumeration.StateType; |
23 | 15 |
import models.support.SearchCondition; |
24 |
-import utils.RoleCheck; |
|
25 |
-import play.Logger; |
|
26 | 16 |
import play.data.Form; |
27 | 17 |
import play.mvc.Controller; |
28 | 18 |
import play.mvc.Http.MultipartFormData; |
29 | 19 |
import play.mvc.Http.MultipartFormData.FilePart; |
30 | 20 |
import play.mvc.Http.Request; |
31 | 21 |
import play.mvc.Result; |
22 |
+import utils.Constants; |
|
32 | 23 |
import views.html.issue.editIssue; |
33 | 24 |
import views.html.issue.issue; |
25 |
+import views.html.issue.issueError; |
|
34 | 26 |
import views.html.issue.issueList; |
35 | 27 |
import views.html.issue.newIssue; |
36 | 28 |
import views.html.issue.notExistingPage; |
37 |
-import views.html.issue.issueError; |
|
29 |
+ |
|
30 |
+import com.avaje.ebean.Page; |
|
38 | 31 |
|
39 | 32 |
public class IssueApp extends Controller { |
40 | 33 |
|
... | ... | @@ -132,14 +125,15 @@ |
132 | 125 |
.bindFromRequest(); |
133 | 126 |
Project project = ProjectApp.getProject(userName, projectName); |
134 | 127 |
if (commentForm.hasErrors()) { |
135 |
- return TODO; |
|
128 |
+ flash(Constants.WARNING, "board.comment.empty"); |
|
129 |
+ return redirect(routes.IssueApp.issue(project.owner, project.name, issueId)); |
|
136 | 130 |
} else { |
137 | 131 |
IssueComment comment = commentForm.get(); |
138 | 132 |
comment.issue = Issue.findById(issueId); |
139 | 133 |
comment.authorId = UserApp.currentUser().id; |
140 | 134 |
comment.filePath = saveFile(request()); |
141 | 135 |
IssueComment.create(comment); |
142 |
-// Issue.updateNumOfComments(issueId); |
|
136 |
+ Issue.updateNumOfComments(issueId); |
|
143 | 137 |
return redirect(routes.IssueApp.issue(project.owner, project.name, issueId)); |
144 | 138 |
} |
145 | 139 |
} |
... | ... | @@ -163,7 +157,6 @@ |
163 | 157 |
issueParam.commentedCheck, issueParam.fileAttachedCheck); |
164 | 158 |
Issue.excelSave(issues.getList(), project.name + "_" + stateType + "_filter_" |
165 | 159 |
+ issueParam.filter + "_milestone_" + issueParam.milestone); |
166 |
- |
|
167 | 160 |
return ok(issueList.render("title.issueList", issues, issueParam, project)); |
168 | 161 |
} |
169 | 162 |
|
--- app/models/Issue.java
+++ app/models/Issue.java
... | ... | @@ -1,26 +1,6 @@ |
1 | 1 |
package models; |
2 | 2 |
|
3 |
-import com.avaje.ebean.Page; |
|
4 |
-import jxl.Workbook; |
|
5 |
-import jxl.format.Alignment; |
|
6 |
-import jxl.format.Border; |
|
7 |
-import jxl.format.BorderLineStyle; |
|
8 |
-import jxl.format.Colour; |
|
9 |
-import jxl.format.*; |
|
10 |
-import jxl.write.*; |
|
11 |
-import models.enumeration.*; |
|
12 |
-import models.support.FinderTemplate; |
|
13 |
-import models.support.OrderParams; |
|
14 |
-import models.support.SearchParams; |
|
15 |
-import play.data.format.Formats; |
|
16 |
-import play.data.validation.Constraints; |
|
17 |
-import play.db.ebean.Model; |
|
18 |
-import utils.JodaDateUtil; |
|
19 |
-import utils.RoleCheck; |
|
20 |
- |
|
21 |
-import javax.persistence.*; |
|
22 |
- |
|
23 |
-import org.joda.time.Duration; |
|
3 |
+import static models.enumeration.IssueState.ASSIGNED; |
|
24 | 4 |
|
25 | 5 |
import java.io.File; |
26 | 6 |
import java.io.IOException; |
... | ... | @@ -28,7 +8,41 @@ |
28 | 8 |
import java.util.Date; |
29 | 9 |
import java.util.List; |
30 | 10 |
|
31 |
-import static models.enumeration.IssueState.ASSIGNED; |
|
11 |
+import javax.persistence.CascadeType; |
|
12 |
+import javax.persistence.Entity; |
|
13 |
+import javax.persistence.Id; |
|
14 |
+import javax.persistence.ManyToOne; |
|
15 |
+import javax.persistence.OneToMany; |
|
16 |
+ |
|
17 |
+import jxl.Workbook; |
|
18 |
+import jxl.format.Alignment; |
|
19 |
+import jxl.format.Border; |
|
20 |
+import jxl.format.BorderLineStyle; |
|
21 |
+import jxl.format.Colour; |
|
22 |
+import jxl.format.ScriptStyle; |
|
23 |
+import jxl.format.UnderlineStyle; |
|
24 |
+import jxl.write.Label; |
|
25 |
+import jxl.write.WritableCellFormat; |
|
26 |
+import jxl.write.WritableFont; |
|
27 |
+import jxl.write.WritableSheet; |
|
28 |
+import jxl.write.WritableWorkbook; |
|
29 |
+import jxl.write.WriteException; |
|
30 |
+import models.enumeration.Direction; |
|
31 |
+import models.enumeration.IssueState; |
|
32 |
+import models.enumeration.Matching; |
|
33 |
+import models.enumeration.StateType; |
|
34 |
+import models.support.FinderTemplate; |
|
35 |
+import models.support.OrderParams; |
|
36 |
+import models.support.SearchParams; |
|
37 |
+ |
|
38 |
+import org.joda.time.Duration; |
|
39 |
+ |
|
40 |
+import play.data.format.Formats; |
|
41 |
+import play.data.validation.Constraints; |
|
42 |
+import play.db.ebean.Model; |
|
43 |
+import utils.JodaDateUtil; |
|
44 |
+ |
|
45 |
+import com.avaje.ebean.Page; |
|
32 | 46 |
|
33 | 47 |
/** |
34 | 48 |
* @author Taehyun Park |
... | ... | @@ -120,7 +134,7 @@ |
120 | 134 |
public int numOfComments; |
121 | 135 |
|
122 | 136 |
public Issue() { |
123 |
- this.date = JodaDateUtil.today(); |
|
137 |
+ this.date = JodaDateUtil.now(); |
|
124 | 138 |
} |
125 | 139 |
|
126 | 140 |
/** |
... | ... | @@ -237,7 +251,7 @@ |
237 | 251 |
public static Page<Issue> findFilteredIssues(String projectName, String filter, |
238 | 252 |
StateType state, boolean commentedCheck, boolean fileAttachedCheck) { |
239 | 253 |
return findIssues(projectName, FIRST_PAGE_NUMBER, state, DEFAULT_SORTER, Direction.DESC, |
240 |
- filter, null, commentedCheck, fileAttachedCheck); |
|
254 |
+ filter, null, commentedCheck, fileAttachedCheck); |
|
241 | 255 |
} |
242 | 256 |
|
243 | 257 |
/** |
... | ... | @@ -249,7 +263,7 @@ |
249 | 263 |
*/ |
250 | 264 |
public static Page<Issue> findCommentedIssues(String projectName, String filter) { |
251 | 265 |
return findIssues(projectName, FIRST_PAGE_NUMBER, StateType.ALL, DEFAULT_SORTER, |
252 |
- Direction.DESC, filter, null, true, false); |
|
266 |
+ Direction.DESC, filter, null, true, false); |
|
253 | 267 |
} |
254 | 268 |
|
255 | 269 |
/** |
... | ... | @@ -308,7 +322,7 @@ |
308 | 322 |
SearchParams searchParams = new SearchParams().add("project.name", projectName, |
309 | 323 |
Matching.EQUALS); |
310 | 324 |
|
311 |
- if(filter != null && !filter.isEmpty()) { |
|
325 |
+ if (filter != null && !filter.isEmpty()) { |
|
312 | 326 |
searchParams.add("title", filter, Matching.CONTAINS); |
313 | 327 |
} |
314 | 328 |
if (milestoneId != null) { |
... | ... | @@ -333,7 +347,7 @@ |
333 | 347 |
break; |
334 | 348 |
} |
335 | 349 |
return FinderTemplate.getPage(orderParams, searchParams, find, ISSUE_COUNT_PER_PAGE, |
336 |
- pageNumber); |
|
350 |
+ pageNumber); |
|
337 | 351 |
} |
338 | 352 |
|
339 | 353 |
public static Long findAssigneeIdByIssueId(String projectName, Long issueId) { |
... | ... | @@ -460,12 +474,13 @@ |
460 | 474 |
return (uId != null ? User.findNameById(uId) : TO_BE_ASSIGNED); |
461 | 475 |
} |
462 | 476 |
|
477 |
+ // FIXME 이것이 없이 테스트는 잘 작동하나, view에서 댓글이 달린 이슈들을 필터링하는 라디오버튼을 작동시에 이 메쏘드에서 |
|
478 |
+ // 시행하는 동기화 작업 없이는 작동을 하지 않는다. |
|
479 |
+ |
|
463 | 480 |
/** |
464 |
- * comment가 delete되거나 create될 때, numOfComment와 comment.size()를 동기화 시켜준다. 현재는 |
|
465 |
- * 이것이 없이도 동작하므로, 추후에 제거하겠음. |
|
481 |
+ * comment가 delete되거나 create될 때, numOfComment와 comment.size()를 동기화 시켜준다. |
|
466 | 482 |
* |
467 | 483 |
* @param id |
468 |
- * Issue Id |
|
469 | 484 |
*/ |
470 | 485 |
public static void updateNumOfComments(Long id) { |
471 | 486 |
|
... | ... | @@ -477,20 +492,15 @@ |
477 | 492 |
public boolean isAuthor(Long currentUserId, Long objectId, String projectName) { |
478 | 493 |
|
479 | 494 |
boolean authorIs; |
480 |
- if (currentUserId == findById(objectId).reporterId |
|
481 |
- || RoleCheck.roleCheck(currentUserId, project.id, |
|
482 |
- PermissionResource.PROJECT, |
|
483 |
- PermissionOperation.WRITE)) { |
|
495 |
+ if (currentUserId == findById(objectId).reporterId) { |
|
484 | 496 |
authorIs = true; |
485 | 497 |
} else { |
486 | 498 |
authorIs = false; |
487 | 499 |
} |
488 |
- |
|
489 | 500 |
return authorIs; |
490 |
- |
|
491 | 501 |
} |
492 |
- |
|
493 |
- public Duration ago(){ |
|
502 |
+ |
|
503 |
+ public Duration ago() { |
|
494 | 504 |
return JodaDateUtil.ago(this.date); |
495 | 505 |
} |
496 | 506 |
} |
--- app/models/IssueComment.java
+++ app/models/IssueComment.java
... | ... | @@ -4,12 +4,7 @@ |
4 | 4 |
|
5 | 5 |
package models; |
6 | 6 |
|
7 |
-import models.enumeration.PermissionOperation; |
|
8 |
-import models.enumeration.PermissionResource; |
|
9 |
-import play.data.validation.Constraints; |
|
10 |
-import play.db.ebean.Model; |
|
11 |
-import utils.JodaDateUtil; |
|
12 |
-import utils.RoleCheck; |
|
7 |
+import java.util.Date; |
|
13 | 8 |
|
14 | 9 |
import javax.persistence.Entity; |
15 | 10 |
import javax.persistence.Id; |
... | ... | @@ -17,7 +12,9 @@ |
17 | 12 |
|
18 | 13 |
import org.joda.time.Duration; |
19 | 14 |
|
20 |
-import java.util.Date; |
|
15 |
+import play.data.validation.Constraints; |
|
16 |
+import play.db.ebean.Model; |
|
17 |
+import utils.JodaDateUtil; |
|
21 | 18 |
|
22 | 19 |
@Entity |
23 | 20 |
public class IssueComment extends Model { |
... | ... | @@ -41,7 +38,7 @@ |
41 | 38 |
public Issue issue; |
42 | 39 |
|
43 | 40 |
public IssueComment() { |
44 |
- date = JodaDateUtil.today(); |
|
41 |
+ date = JodaDateUtil.now(); |
|
45 | 42 |
} |
46 | 43 |
|
47 | 44 |
public static IssueComment findById(Long id) { |
... | ... | @@ -60,19 +57,16 @@ |
60 | 57 |
public static void delete(Long id) { |
61 | 58 |
find.byId(id).delete(); |
62 | 59 |
} |
60 |
+ |
|
61 |
+ public boolean isAuthor(Long currentUserId, Long objectId, String projectName) { |
|
63 | 62 |
|
64 |
- public boolean isAuthor(Long currentUserId, String projectName) { |
|
65 |
- |
|
66 |
- Project project = Project.findByName(projectName); |
|
67 |
- return checkAuthor(currentUserId, project.id); |
|
68 |
- |
|
69 |
- } |
|
70 |
- |
|
71 |
- private boolean checkAuthor(Long currentUserId, Long projectId) { |
|
72 |
- return currentUserId.equals(this.id) |
|
73 |
- || RoleCheck.roleCheck(currentUserId, projectId, |
|
74 |
- PermissionResource.PROJECT, |
|
75 |
- PermissionOperation.WRITE); |
|
63 |
+ boolean authorIs; |
|
64 |
+ if (currentUserId == findById(objectId).authorId) { |
|
65 |
+ authorIs = true; |
|
66 |
+ } else { |
|
67 |
+ authorIs = false; |
|
68 |
+ } |
|
69 |
+ return authorIs; |
|
76 | 70 |
} |
77 | 71 |
|
78 | 72 |
public Duration ago(){ |
--- app/models/Project.java
+++ app/models/Project.java
... | ... | @@ -29,11 +29,13 @@ |
29 | 29 |
public String name; |
30 | 30 |
|
31 | 31 |
public String overview; |
32 |
- public boolean share_option; |
|
33 | 32 |
public String vcs; |
34 | 33 |
public String url; |
35 | 34 |
public String logoPath; |
36 | 35 |
public String owner; |
36 |
+ |
|
37 |
+ public boolean share_option; |
|
38 |
+ public boolean isAuthorEditable; |
|
37 | 39 |
|
38 | 40 |
@OneToMany(mappedBy = "project", cascade = CascadeType.ALL) |
39 | 41 |
public List<Issue> issues; |
--- app/views/issue/editIssue.scala.html
+++ app/views/issue/editIssue.scala.html
... | ... | @@ -3,11 +3,14 @@ |
3 | 3 |
@implicitFieldConstructor = @{ FieldConstructor(twitterBootstrapInput.render) } |
4 | 4 |
|
5 | 5 |
@main(Messages(title), project) { |
6 |
- |
|
7 |
- @form( action = routes.IssueApp.updateIssue(project.owner, project.name, issueId), |
|
6 |
+<!-- FIXEME |
|
7 |
+(1) 수정했을 시에, 수정시간으로 업데이트 되는 것이 아니라, 본 글이 원래 작성된 시간을 그대로 가지고 있을 것! |
|
8 |
+(2) 매니저 및 멤버가 해당 이슈를 수정시에, 작성자가 변하지 않아야 함. |
|
9 |
+--> |
|
10 |
+ @form(action = routes.IssueApp.updateIssue(project.owner, project.name, issueId), |
|
8 | 11 |
'enctype -> "multipart/form-data", |
9 | 12 |
'class -> "form-horizontal"){ |
10 |
- <fieldset> |
|
13 |
+ <fieldset> |
|
11 | 14 |
@inputText( |
12 | 15 |
issueForm("title"), |
13 | 16 |
'_showConstraints -> false, |
... | ... | @@ -21,10 +24,11 @@ |
21 | 24 |
@inputFile( |
22 | 25 |
issueForm("filePath")) |
23 | 26 |
@if(issueForm("filePath") != null) {<p>@issueForm("filePath")</p>} |
24 |
- </fieldset> |
|
27 |
+ </fieldset> |
|
25 | 28 |
</br></br> |
29 |
+ |
|
26 | 30 |
@if(ProjectUser.isMember(session.get("userId").toLong, project.id)){ |
27 |
- <fieldset> |
|
31 |
+ <fieldset> |
|
28 | 32 |
<div class="well"> |
29 | 33 |
<legend><b>@Messages("issue.new.detailInfo")</b></legend> |
30 | 34 |
<div class="well form-inline"> |
--- app/views/issue/issue.scala.html
+++ app/views/issue/issue.scala.html
... | ... | @@ -5,8 +5,10 @@ |
5 | 5 |
<div class="row"> |
6 | 6 |
<div class="span2 offset10"> |
7 | 7 |
<div id="board_btn_panel"> |
8 |
+ @if(issue.isAuthor(session.get("userId").toLong, issue.id, project.name) && project.isAuthorEditable){ |
|
8 | 9 |
<a class="btn btn-primary" href="@routes.IssueApp.editIssue(project.owner, project.name, issue.id)">@Messages("button.edit")</a> <a |
9 | 10 |
data-toggle="modal" href="#deleteIssueConfirm" class="btn">@Messages("button.delete")</a> |
11 |
+ } |
|
10 | 12 |
<a class="btn" href="@routes.IssueApp.issues(project.owner, project.name,"open")">@Messages("button.list")</a> |
11 | 13 |
</div> |
12 | 14 |
</div> |
... | ... | @@ -57,11 +59,11 @@ |
57 | 59 |
|
58 | 60 |
</div> |
59 | 61 |
|
60 |
- @if(ProjectUser.isMember(session.get("userId").toLong, project.id) || comment.isAuthor(session.get("userId").toLong, project.name)){ |
|
62 |
+ @if(comment.isAuthor(session.get("userId").toLong, comment.id, project.name)){ |
|
61 | 63 |
<div class="pull-right"> |
62 | 64 |
<a data-toggle="modal" href='#deleteCommentConfirm'><i class="icon-remove"> </i> |
63 | 65 |
</div> |
64 |
- |
|
66 |
+ } |
|
65 | 67 |
|
66 | 68 |
<div class="modal hide" id="deleteCommentConfirm"> |
67 | 69 |
<div class="modal-header"> |
... | ... | @@ -84,7 +86,7 @@ |
84 | 86 |
class="icon-download"> </i> @comment.filePath</a> |
85 | 87 |
</p> |
86 | 88 |
} |
87 |
- } |
|
89 |
+ |
|
88 | 90 |
</div> |
89 | 91 |
</div> |
90 | 92 |
} |
--- app/views/issue/issueError.scala.html
+++ app/views/issue/issueError.scala.html
... | ... | @@ -2,7 +2,7 @@ |
2 | 2 |
|
3 | 3 |
@main("Warnning!", project){ |
4 | 4 |
<div class="alert alert-error"> |
5 |
- @message |
|
5 |
+ @Messages(message) |
|
6 | 6 |
</div> |
7 | 7 |
<a class="btn" href="@returnURL">돌아가기</a> |
8 | 8 |
}(No newline at end of file) |
--- app/views/issue/issueList.scala.html
+++ app/views/issue/issueList.scala.html
... | ... | @@ -64,7 +64,7 @@ |
64 | 64 |
<!--FIXME view 전문가님이 아래의 if-else문 안의 중복된 코드를 업그레이드 해주시길 바랍니다. --> |
65 | 65 |
<label class="checkbox inline"> |
66 | 66 |
@if(param.commentedCheck==true){ |
67 |
- <input type="checkbox" name="commentedCheck" id="commentCheckId" value="1" checked="checked"> @Messages("checkbox.commented") |
|
67 |
+ <input type="checkbox" name="commentedCheck" id="commentCheckId" value="1" checked> @Messages("checkbox.commented") |
|
68 | 68 |
} else { |
69 | 69 |
<input type="checkbox" name="commentedCheck" id="commentCheckId" value="1"> @Messages("checkbox.commented") |
70 | 70 |
} |
... | ... | @@ -129,7 +129,7 @@ |
129 | 129 |
</div> |
130 | 130 |
} |
131 | 131 |
<script> |
132 |
- $("#checkboxForm").bind("change check", function(){ |
|
132 |
+ $("#checkboxForm").bind("change check uncheck", function(){ |
|
133 | 133 |
if($("#commentCheckId").is(":checked") && $("#fileAttachedCheckId").is(":checked")) { |
134 | 134 |
return $("form[id='checkboxForm']").submit(); |
135 | 135 |
} |
... | ... | @@ -165,7 +165,7 @@ |
165 | 165 |
$("pagination").click(function(){ |
166 | 166 |
|
167 | 167 |
}); |
168 |
- $("select[id='milestone']").change(function(){ |
|
168 |
+ $("select[id='milestone']").bind("change", function(){ |
|
169 | 169 |
$(this).parent("form[id='searchForm']").submit(); |
170 | 170 |
}); |
171 | 171 |
</script> |
--- app/views/project/newProject.scala.html
+++ app/views/project/newProject.scala.html
... | ... | @@ -42,8 +42,11 @@ |
42 | 42 |
options = options("false"->Messages("project.shareOption.private"), "true"->Messages("project.shareOption.public")), |
43 | 43 |
'_label -> Messages("project.shareOption") |
44 | 44 |
) |
45 |
- |
|
46 |
- |
|
45 |
+ @inputRadioGroup( |
|
46 |
+ newProjectForm("isAuthorEditable"), |
|
47 |
+ options = options("false"->Messages("project.isAuthorEditable.off"), "true"->Messages("project.isAuthorEditable.on")), |
|
48 |
+ '_label -> Messages("project.isAuthorEditable") |
|
49 |
+ ) |
|
47 | 50 |
@select( |
48 | 51 |
newProjectForm("vcs"), |
49 | 52 |
options=options("GIT"->"GIT", "Subversion"->"Subversion"), |
--- app/views/project/setting.scala.html
+++ app/views/project/setting.scala.html
... | ... | @@ -59,6 +59,11 @@ |
59 | 59 |
options = options("false"->Messages("project.shareOption.private"), "true"->Messages("project.shareOption.public")), |
60 | 60 |
'_label -> Messages("project.shareOption") |
61 | 61 |
) |
62 |
+ @inputRadioGroup( |
|
63 |
+ projectForm("isAuthorEditable"), |
|
64 |
+ options = options("false"->Messages("project.isAuthorEditable.off"), "true"->Messages("project.isAuthorEditable.on")), |
|
65 |
+ '_label -> Messages("project.isAuthorEditable") |
|
66 |
+ ) |
|
62 | 67 |
|
63 | 68 |
@inputText( |
64 | 69 |
projectForm("url"), |
--- conf/initial-data.yml
+++ conf/initial-data.yml
... | ... | @@ -35,6 +35,7 @@ |
35 | 35 |
vcs: GIT |
36 | 36 |
url: http://localhost:9000/nForge4java |
37 | 37 |
owner: hobi |
38 |
+ isAuthorEditable: true |
|
38 | 39 |
- !!models.Project |
39 | 40 |
name: Jindo |
40 | 41 |
overview: Jindo는 NHN에서 제작한 Javascript Library 이다. |
... | ... | @@ -42,6 +43,7 @@ |
42 | 43 |
vcs: Subversion |
43 | 44 |
url: http://localhost:9000/Jindo |
44 | 45 |
owner: k16wire |
46 |
+ isAuthorEditable: false |
|
45 | 47 |
- !!models.Project |
46 | 48 |
name: CUBRID |
47 | 49 |
overview: CUBRID는 엔터프라이즈급 오픈 소스 DBMS로서, 인터넷 서비스에 최적화된 DBMS를 지향하고 있습니다. |
--- conf/messages.en
+++ conf/messages.en
... | ... | @@ -124,6 +124,7 @@ |
124 | 124 |
issue.new.result.diagnosisResult.works4me= Works for Me |
125 | 125 |
issue.noAssignee = TBA |
126 | 126 |
issue.delete.window = Delete Issue |
127 |
+issue.comment.delete.window = Delete Issue Comment |
|
127 | 128 |
issue.new.selectDefault.milestone = --Select a Milestone-- |
128 | 129 |
issue.new.selectDefault.issueType = --Select a Type of Issue-- |
129 | 130 |
issue.new.selectDefault.assignee = --Select an Assignee -- |
... | ... | @@ -157,7 +158,10 @@ |
157 | 158 |
project.shareOption = Share Option |
158 | 159 |
project.shareOption.public = Public |
159 | 160 |
project.shareOption.private = Private |
160 |
-project.shareOption.private.description = Basic information (name, description, etc.) is exposed to all users, even thought it is a private project. |
|
161 |
+project.shareOption.private.description = Basic information (name, description, etc.) is exposed to all users, even thought it is a private project. |
|
162 |
+project.isAuthorEditable = Can the author do edit/delete his post/issue? |
|
163 |
+project.isAuthorEditable.on = Yes |
|
164 |
+project.isAuthorEditable.off = No |
|
161 | 165 |
project.vcs = Repository |
162 | 166 |
project.new.agreement = I read nForge4's user agreement and accept it. |
163 | 167 |
project.new.agreement.alert = You should agree with the user agreement. |
... | ... | @@ -226,4 +230,4 @@ |
226 | 230 |
board.post.new = New Post |
227 | 231 |
board.post.modify = Edit Post |
228 | 232 |
board.comment.empty = you have to write contents. |
229 |
-board.notAuthor = You are not author!(No newline at end of file) |
|
233 |
+board.notAuthor = You are not author! |
--- conf/messages.ko
+++ conf/messages.ko
... | ... | @@ -124,6 +124,7 @@ |
124 | 124 |
issue.new.result.diagnosisResult.works4me= 잘동작함 |
125 | 125 |
issue.noAssignee = 미배정 |
126 | 126 |
issue.delete.window = 이슈 삭제 |
127 |
+issue.comment.delete.window = 이슈 댓글 삭제 |
|
127 | 128 |
issue.new.selectDefault.milestone = --마일스톤 선택-- |
128 | 129 |
issue.new.selectDefault.issueType = --유형 선택-- |
129 | 130 |
issue.new.selectDefault.assignee = --담당자 선택-- |
... | ... | @@ -158,6 +159,9 @@ |
158 | 159 |
project.shareOption.public = 공개 |
159 | 160 |
project.shareOption.private = 비공개 |
160 | 161 |
project.shareOption.private.description = 비공개 프로젝트도 프로젝트 이름,설명,로고 등은 모든 사용자가 볼수 있습니다. |
162 |
+project.isAuthorEditable = 작성자 수정/삭제 권한 설정 |
|
163 |
+project.isAuthorEditable.on = 가능 |
|
164 |
+project.isAuthorEditable.off = 불가능 |
|
161 | 165 |
project.vcs = 코드관리시스템 |
162 | 166 |
project.new.agreement = 본인은 약관에 대한 안내를 읽었으며 동의합니다. |
163 | 167 |
project.new.agreement.alert = 이용 악관에 동의하여야 합니다. |
... | ... | @@ -226,4 +230,4 @@ |
226 | 230 |
board.post.new = 새 게시물 |
227 | 231 |
board.post.modify = 게시물 수정 |
228 | 232 |
board.comment.empty = 댓글내용은 반드시 쓰셔야 합니다. |
229 |
-board.notAuthor = 글쓴이가 아닙니다.(No newline at end of file) |
|
233 |
+board.notAuthor = 글쓴이가 아닙니다. |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?