Skip to content

Commit 6f7f75f

Browse files
committed
Merge branch 'next' before release v1.9.1
Reviewed-by: Suwon Chae Reviewed-by: Mijeong Park
2 parents 9e9f128 + 67d6c17 commit 6f7f75f

File tree

19 files changed

+290
-115
lines changed

19 files changed

+290
-115
lines changed

app/assets/stylesheets/less/_page.less

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2087,7 +2087,12 @@ label.inline-list {
20872087
}
20882088
.filters {
20892089
color:#666;
2090-
float: right; margin-top:5px;
2090+
float: right;
2091+
margin-top:5px;
2092+
border: 1px solid #ddd;
2093+
border-radius: 3px;
2094+
padding: 5px 10px;
2095+
20912096
.filter {
20922097
margin-right:10px;
20932098
&.active { font-weight:bold; color:@primary; }
@@ -7138,8 +7143,28 @@ div.diff-body[data-outdated="true"] tr:hover .icon-comment {
71387143
}
71397144

71407145
.sharer-list {
7141-
margin-top: 40px;
7142-
padding: 10px;
7146+
margin-top: -5px;
7147+
padding: 15px;
7148+
7149+
&.sharer-list-border {
7150+
border: 1px solid #ddd;
7151+
border-radius: 3px;
7152+
position: relative;
7153+
7154+
&:before {
7155+
position:absolute;
7156+
top: -9px;
7157+
left: 133px;
7158+
content: ' ';
7159+
width: 16px;
7160+
height: 16px;
7161+
border-width: 0 0 1px 1px;
7162+
border-style: solid;
7163+
border-color: #BDC3C7;
7164+
background-color: #fff;
7165+
.rotate(135deg);
7166+
}
7167+
}
71437168

71447169
.issue-share-title {
71457170
font-size: 16px;

app/controllers/ProjectApp.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1266,7 +1266,7 @@ public static Result newWebhook(String ownerId, String projectName) {
12661266

12671267
Webhook webhook = addWebhookForm.get();
12681268

1269-
Webhook.create(project.id, webhook.payloadUrl, webhook.secret,
1269+
Webhook.create(project.id, webhook.payloadUrl.trim(), webhook.secret,
12701270
BooleanUtils.toBooleanDefaultIfNull(webhook.gitPushOnly, false));
12711271

12721272
return redirect(routes.ProjectApp.webhooks(project.owner, project.name));

app/controllers/VoteApp.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import utils.RouteUtil;
3333

3434
import java.util.ArrayList;
35+
import java.util.Iterator;
3536
import java.util.List;
3637
import java.util.Set;
3738

@@ -119,16 +120,15 @@ public static Result unvoteComment(String user, String project, Long number, Lon
119120
}
120121

121122
public static List<User> getVotersForAvatar(Set<User> voters, int size){
122-
return getSubList(voters, 0, size);
123-
}
123+
List<User> userList = new ArrayList<>();
124+
Iterator<User> iterator = voters.iterator();
125+
int index = 0;
124126

125-
public static List<User> getVotersForName(Set<User> voters, int fromIndex, int size){
126-
return getSubList(voters, fromIndex, fromIndex + size);
127-
}
127+
while( index++ < size && iterator.hasNext() ) {
128+
userList.add(iterator.next());
129+
}
128130

129-
public static Set<User> getVotersExceptCurrentUser(Set<User> voters){
130-
voters.remove(UserApp.currentUser());
131-
return voters;
131+
return userList;
132132
}
133133

134134
/**

app/controllers/api/IssueApi.java

Lines changed: 88 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@
1717
import controllers.annotation.IsCreatable;
1818
import controllers.routes;
1919
import models.*;
20-
import models.enumeration.Operation;
21-
import models.enumeration.ResourceType;
22-
import models.enumeration.State;
23-
import models.enumeration.UserState;
20+
import models.enumeration.*;
2421
import org.apache.commons.lang3.StringUtils;
2522
import play.db.ebean.Transactional;
2623
import play.i18n.Messages;
@@ -367,6 +364,17 @@ private static ExpressionList<User> getUserExpressionList(String query, String s
367364
return el;
368365
}
369366

367+
private static ExpressionList<Project> getProjectExpressionList(String query, String searchType) {
368+
369+
ExpressionList<Project> el = Project.find.select("id, name").where()
370+
.eq("projectScope", ProjectScope.PUBLIC).disjunction();
371+
372+
el.icontains("name", query);
373+
el.endJunction();
374+
375+
return el;
376+
}
377+
370378
private static void addAuthorIfNotMe(Issue issue, List<ObjectNode> users, User issueAuthor) {
371379
if (!issue.getAuthor().loginId.equals(UserApp.currentUser().loginId)) {
372380
addUserToUsersWithCustomName(issueAuthor, users, Messages.get("issue.assignToAuthor"));
@@ -391,12 +399,25 @@ static void addUserToUsers(User user, List<ObjectNode> users) {
391399
userNode.put("loginId", user.loginId);
392400
userNode.put("name", user.getDisplayName());
393401
userNode.put("avatarUrl", user.avatarUrl());
402+
userNode.put("type", "user");
394403

395404
if(!users.contains(userNode)) {
396405
users.add(userNode);
397406
}
398407
}
399408

409+
static void addProjectToProjects(Project project, List<ObjectNode> projects) {
410+
ObjectNode projectNode = Json.newObject();
411+
projectNode.put("loginId", project.id);
412+
projectNode.put("name", project.owner + "/" + project.name);
413+
projectNode.put("avatarUrl", "");
414+
projectNode.put("type", "project");
415+
416+
if(!projects.contains(projectNode)) {
417+
projects.add(projectNode);
418+
}
419+
}
420+
400421
private static void addUserToUsersWithCustomName(User user, List<ObjectNode> users, String name) {
401422
ObjectNode userNode = Json.newObject();
402423
userNode.put("loginId", user.loginId);
@@ -580,21 +601,27 @@ public static Result findSharableUsers(String ownerName, String projectName, Lon
580601
return status(Http.Status.NOT_ACCEPTABLE);
581602
}
582603

583-
List<ObjectNode> users = new ArrayList<>();
604+
List<ObjectNode> results = new ArrayList<>();
584605

585-
ExpressionList<User> el = getUserExpressionList(query, request().getQueryString("type"));
606+
ExpressionList<User> userExpressionList = getUserExpressionList(query, request().getQueryString("type"));
607+
ExpressionList<Project> projectExpressionList = getProjectExpressionList(query, request().getQueryString("type"));
586608

587-
int total = el.findRowCount();
609+
int total = userExpressionList.findRowCount() + projectExpressionList.findRowCount();
588610
if (total > MAX_FETCH_USERS) {
589-
el.setMaxRows(MAX_FETCH_USERS);
611+
userExpressionList.setMaxRows(MAX_FETCH_USERS / 2);
612+
projectExpressionList.setMaxRows(MAX_FETCH_USERS / 2);
590613
response().setHeader("Content-Range", "items " + MAX_FETCH_USERS + "/" + total);
591614
}
592615

593-
for (User user :el.findList()) {
594-
addUserToUsers(user, users);
616+
for (User user :userExpressionList.findList()) {
617+
addUserToUsers(user, results);
595618
}
596619

597-
return ok(toJson(users));
620+
for (Project project: projectExpressionList.findList()) {
621+
addProjectToProjects(project, results);
622+
}
623+
624+
return ok(toJson(results));
598625
}
599626

600627
public static Result updateSharer(String owner, String projectName, Long number){
@@ -618,35 +645,73 @@ public static Result updateSharer(String owner, String projectName, Long number)
618645
final String action = json.findValue("action").asText();
619646

620647
ObjectNode result = changeSharer(sharer, issue, action);
621-
sendNotification(sharer, issue, action);
622648

623649
return ok(result);
624650
}
625651

626652
private static ObjectNode changeSharer(JsonNode sharer, Issue issue, String action) {
627653
ObjectNode result = Json.newObject();
628-
for (JsonNode sharerLoginId : sharer) {
654+
List<String> users = new ArrayList<>();
655+
656+
if(sharer.findValue("type").asText().equals("project")) {
657+
changeSharerByProject(sharer.findValue("loginId").asLong(), issue, action, result, users);
658+
} else {
659+
changeSharerByUser(sharer.findValue("loginId").asText(), issue, action, result, users);
660+
}
661+
662+
sendNotification(users, issue, action);
663+
return result;
664+
}
665+
666+
private static void changeSharerByUser(String loginId, Issue issue, String action, ObjectNode result, List<String> users) {
667+
if ("add".equalsIgnoreCase(action)) {
668+
addSharer(issue, loginId);
669+
} else if ("delete".equalsIgnoreCase(action)) {
670+
removeSharer(issue, loginId);
671+
} else {
672+
play.Logger.error("Unknown issue sharing action: " + issue + ":" + action + " by " + currentUser());
673+
}
674+
675+
users.add(loginId);
676+
setShareActionToResponse(action, result);
677+
result.put("sharer", User.findByLoginId(loginId).getDisplayName());
678+
}
679+
680+
private static void changeSharerByProject(Long projectId, Issue issue, String action, ObjectNode result, List<String> users) {
681+
List<ProjectUser> projectUsers = ProjectUser.findMemberListByProject(projectId);
682+
683+
for (ProjectUser projectUser: projectUsers) {
629684
if ("add".equalsIgnoreCase(action)) {
630-
addSharer(issue, sharerLoginId.asText());
631-
result.put("action", "added");
685+
addSharer(issue, projectUser.user.loginId);
632686
} else if ("delete".equalsIgnoreCase(action)) {
633-
result.put("action", "deleted");
634-
removeSharer(issue, sharerLoginId.asText());
687+
removeSharer(issue, projectUser.user.loginId);
635688
} else {
636689
play.Logger.error("Unknown issue sharing action: " + issue + ":" + action + " by " + currentUser());
637-
result.put("action", "Do nothing. Unsupported action: " + action);
638690
}
639-
result.put("sharer", User.findByLoginId(sharerLoginId.asText()).getDisplayName());
691+
users.add(projectUser.user.loginId);
692+
}
693+
694+
setShareActionToResponse(action, result);
695+
696+
result.put("sharer", Project.find.byId(projectId).name);
697+
}
698+
699+
private static void setShareActionToResponse(String action, ObjectNode result) {
700+
if ("add".equalsIgnoreCase(action)) {
701+
result.put("action", "added");
702+
} else if ("delete".equalsIgnoreCase(action)) {
703+
result.put("action", "deleted");
704+
} else {
705+
result.put("action", "Do nothing. Unsupported action: " + action);
640706
}
641-
return result;
642707
}
643708

644-
private static void sendNotification(JsonNode sharer, Issue issue, String action) {
709+
private static void sendNotification(List<String> users, Issue issue, String action) {
645710
Runnable preUpdateHook = new Runnable() {
646711
@Override
647712
public void run() {
648-
for(JsonNode sharerLoginId: sharer){
649-
addSharerChangedNotification(issue, sharerLoginId.asText(), action);
713+
for(String sharerLoginId: users){
714+
addSharerChangedNotification(issue, sharerLoginId, action);
650715
}
651716
}
652717
};

app/models/NotificationEvent.java

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -978,11 +978,28 @@ private static Set<User> getMandatoryReceivers(Issue issue, EventType eventType)
978978

979979
receivers.removeAll(findUnwatchers(issue.asResource()));
980980
receivers.removeAll(findEventUnwatchersByEventType(issue.project.id, eventType));
981-
receivers.remove(UserApp.currentUser());
981+
receivers.remove(findCurrentUserToBeExcluded(issue.authorId));
982982

983983
return receivers;
984984
}
985985

986+
private static User findCurrentUserToBeExcluded(Long authorId) {
987+
User currentUser;
988+
try {
989+
currentUser = UserApp.currentUser();
990+
} catch (RuntimeException re) {
991+
// expectation: "There is no HTTP Context available from here" runtime exception
992+
currentUser = User.anonymous;
993+
}
994+
995+
if (currentUser.isAnonymous()) {
996+
// It is assumed that it is called by author and processed by system.
997+
return User.find.byId(authorId);
998+
} else {
999+
return currentUser;
1000+
}
1001+
}
1002+
9861003
private static Set<User> getMandatoryReceivers(Posting posting, EventType eventType) {
9871004
Set<User> receivers = findWatchers(posting.asResource());
9881005
receivers.add(posting.getAuthor());
@@ -991,7 +1008,7 @@ private static Set<User> getMandatoryReceivers(Posting posting, EventType eventT
9911008

9921009
receivers.removeAll(findUnwatchers(posting.asResource()));
9931010
receivers.removeAll(findEventUnwatchersByEventType(posting.project.id, eventType));
994-
receivers.remove(UserApp.currentUser());
1011+
receivers.remove(findCurrentUserToBeExcluded(posting.authorId));
9951012

9961013
return receivers;
9971014
}
@@ -1006,16 +1023,16 @@ private static Set<User> getMandatoryReceivers(Comment comment, EventType eventT
10061023

10071024
receivers.removeAll(findUnwatchers(parent.asResource()));
10081025
receivers.removeAll(findEventUnwatchersByEventType(comment.projectId, eventType));
1009-
receivers.remove(UserApp.currentUser());
1026+
receivers.remove(findCurrentUserToBeExcluded(comment.authorId));
10101027

10111028
return receivers;
10121029
}
10131030

1014-
private static Set<User> getProjectCommitReceivers(Project project, EventType eventType) {
1031+
private static Set<User> getProjectCommitReceivers(Project project, EventType eventType, User sender) {
10151032
Set<User> receivers = findMembersOnlyFromWatchers(project);
10161033
receivers.removeAll(findUnwatchers(project.asResource()));
10171034
receivers.removeAll(findEventUnwatchersByEventType(project.id, eventType));
1018-
receivers.remove(UserApp.currentUser());
1035+
receivers.remove(sender);
10191036

10201037
return receivers;
10211038
}
@@ -1042,7 +1059,7 @@ private static Set<User> extractMembers(Project project) {
10421059
private static Set<User> getReceiversForIssueBodyChanged(String oldBody, Issue issue) {
10431060
Set<User> receivers = getMandatoryReceivers(issue, ISSUE_BODY_CHANGED);
10441061
receivers.addAll(getNewMentionedUsers(oldBody, issue.body));
1045-
receivers.remove(UserApp.currentUser());
1062+
receivers.remove(findCurrentUserToBeExcluded(issue.authorId));
10461063
return receivers;
10471064
}
10481065

@@ -1183,7 +1200,7 @@ public static void afterOrganizationMemberRequest(Organization organization, Use
11831200
public static void afterNewCommits(List<RevCommit> commits, List<String> refNames, Project project, User sender, String title) {
11841201
NotificationEvent notiEvent = createFrom(sender, project);
11851202
notiEvent.title = title;
1186-
notiEvent.receivers = getProjectCommitReceivers(project, NEW_COMMIT);
1203+
notiEvent.receivers = getProjectCommitReceivers(project, NEW_COMMIT, sender);
11871204
notiEvent.eventType = NEW_COMMIT;
11881205
notiEvent.oldValue = null;
11891206
notiEvent.newValue = newCommitsMessage(commits, refNames, project);

app/models/Project.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ public Set<User> findAuthorsAndWatchers() {
191191
}
192192

193193
private Set<User> getIssueUsers() {
194-
String issueSql = "SELECT distinct author_id id FROM ISSUE where project_id=" + this.id;
194+
String issueSql = "select distinct author_id id from issue where project_id=" + this.id;
195195
return User.find.setRawSql(RawSqlBuilder.parse(issueSql).create()).findSet();
196196
}
197197

app/models/ProjectUser.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,10 @@ public static void create(Long userId, Long projectId, Long roleId) {
6161
}
6262

6363
public static void delete(Long userId, Long projectId) {
64-
ProjectUser.findByIds(userId, projectId).delete();
64+
ProjectUser projectUser = ProjectUser.findByIds(userId, projectId);
65+
if (projectUser != null) {
66+
projectUser.delete();
67+
}
6568
}
6669

6770
public static void assignRole(Long userId, Long projectId, Long roleId) {
@@ -87,8 +90,12 @@ public static void assignRole(Long userId, Long projectId, RoleType roleType) {
8790
}
8891

8992
public static ProjectUser findByIds(Long userId, Long projectId) {
90-
return find.where().eq("user.id", userId).eq("project.id", projectId)
91-
.ne("role.id", RoleType.SITEMANAGER.roleType()).findUnique();
93+
List<ProjectUser> projectUsers = find.where().eq("user.id", userId).eq("project.id", projectId)
94+
.ne("role.id", RoleType.SITEMANAGER.roleType()).findList();
95+
if(projectUsers.size() > 0) {
96+
return projectUsers.get(0);
97+
}
98+
return null;
9299
}
93100

94101
public static List<ProjectUser> findMemberListByProject(Long projectId) {

app/models/User.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,6 +1052,10 @@ public String extractDepartmentPart(){
10521052
}
10531053

10541054
public String getDisplayName(){
1055+
if (UserApp.currentUser().isAnonymous()) {
1056+
return name;
1057+
}
1058+
10551059
if (StringUtils.isNotBlank(englishName) && lang != null && UserApp.currentUser().lang.startsWith("en")) {
10561060
return englishName + " " + extractDepartmentPart();
10571061
} else {

0 commit comments

Comments
 (0)