Parcourir la source

Overdue labeling, notify changed tickets control

tags/v1.6.0
James Moger il y a 10 ans
Parent
révision
667163976e

+ 29
- 9
src/main/java/com/gitblit/tickets/ITicketService.java Voir le fichier

@@ -651,11 +651,12 @@ public abstract class ITicketService {
* @param oldName
* @param newName
* @param createdBy
* @param send ticket notifications
* @param notifyOpenTickets
* @return true if successful
* @since 1.6.0
*/
public synchronized boolean renameMilestone(RepositoryModel repository, String oldName, String newName, String createdBy, boolean notify) {
public synchronized boolean renameMilestone(RepositoryModel repository, String oldName,
String newName, String createdBy, boolean notifyOpenTickets) {
if (StringUtils.isEmpty(newName)) {
throw new IllegalArgumentException("new milestone can not be empty!");
}
@@ -680,11 +681,11 @@ public abstract class ITicketService {
Change change = new Change(createdBy);
change.setField(Field.milestone, newName);
TicketModel ticket = updateTicket(repository, qr.number, change);
if (notify && ticket.isOpen()) {
if (notifyOpenTickets && ticket.isOpen()) {
notifier.queueMailing(ticket);
}
}
if (notify) {
if (notifyOpenTickets) {
notifier.sendAll();
}

@@ -709,6 +710,21 @@ public abstract class ITicketService {
* @since 1.4.0
*/
public synchronized boolean deleteMilestone(RepositoryModel repository, String milestone, String createdBy) {
return deleteMilestone(repository, milestone, createdBy, true);
}

/**
* Deletes a milestone.
*
* @param repository
* @param milestone
* @param createdBy
* @param notifyOpenTickets
* @return true if successful
* @since 1.6.0
*/
public synchronized boolean deleteMilestone(RepositoryModel repository, String milestone,
String createdBy, boolean notifyOpenTickets) {
if (StringUtils.isEmpty(milestone)) {
throw new IllegalArgumentException("milestone can not be empty!");
}
@@ -722,14 +738,18 @@ public abstract class ITicketService {

milestonesCache.remove(repository.name);

TicketNotifier notifier = createNotifier();
for (QueryResult qr : tm.tickets) {
if (qr.isOpen()) {
// reset the milestone only for open tickets
Change change = new Change(createdBy);
change.setField(Field.milestone, "");
TicketModel ticket = updateTicket(repository, qr.number, change);
Change change = new Change(createdBy);
change.setField(Field.milestone, "");
TicketModel ticket = updateTicket(repository, qr.number, change);
if (notifyOpenTickets && ticket.isOpen()) {
notifier.queueMailing(ticket);
}
}
if (notifyOpenTickets) {
notifier.sendAll();
}
return true;
} catch (IOException e) {
log.error("failed to delete milestone " + milestone + " in " + repository, e);

+ 9
- 1
src/main/java/com/gitblit/tickets/TicketMilestone.java Voir le fichier

@@ -37,7 +37,15 @@ public class TicketMilestone extends TicketLabel {
super(name);
status = Status.Open;
}

public boolean isOpen() {
return status == Status.Open;
}

public boolean isOverdue() {
return due == null ? false : System.currentTimeMillis() > due.getTime();
}

public void setDue(Date due) {
this.due = due;
}

+ 3
- 1
src/main/java/com/gitblit/wicket/GitBlitWebApp.properties Voir le fichier

@@ -673,4 +673,6 @@ gb.mergeToDescription = default integration branch for merging ticket patchsets
gb.anonymousCanNotPropose = Anonymous users can not propose patchsets.
gb.youDoNotHaveClonePermission = You are not permitted to clone this repository.
gb.newMilestone = new milestone
gb.editMilestone = edit milestone
gb.editMilestone = edit milestone
gb.notifyChangedOpenTickets = send notification for changed open tickets
gb.overdue = overdue

+ 2
- 1
src/main/java/com/gitblit/wicket/pages/EditMilestonePage.html Voir le fichier

@@ -19,8 +19,9 @@
<!-- Edit Milestone Table -->
<table class="ticket">
<tr><th><wicket:message key="gb.milestone"></wicket:message></th><td class="edit"><input class="input-large" type="text" wicket:id="name" id="name"></input></td></tr>
<tr><th><wicket:message key="gb.due"></wicket:message></th><td class="edit"><input class="input-large" type="text" wicket:id="due"></input></td></tr>
<tr><th><wicket:message key="gb.due"></wicket:message></th><td class="edit"><input class="input-large" type="text" wicket:id="due"></input> &nbsp;<span class="help-inline" wicket:id="dueFormat"></span></td></tr>
<tr><th><wicket:message key="gb.status"></wicket:message><span style="color:red;">*</span></th><td class="edit"><select class="input-large" wicket:id="status"></select></td></tr>
<tr><th></th><td class="edit"><label class="checkbox"><input type="checkbox" wicket:id="notify" /> &nbsp;<span class="help-inline"><wicket:message key="gb.notifyChangedOpenTickets"></wicket:message></span></label></td></tr>
</table>
</div>
</div>

+ 6
- 1
src/main/java/com/gitblit/wicket/pages/EditMilestonePage.java Voir le fichier

@@ -24,7 +24,9 @@ import org.apache.wicket.RestartResponseException;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.extensions.markup.html.form.DateTextField;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
@@ -102,6 +104,8 @@ public class EditMilestonePage extends RepositoryPage {
form.add(new TextField<String>("name", nameModel));
form.add(new DateTextField("due", dueModel, "yyyy-MM-dd"));
form.add(new Label("dueFormat", "yyyy-MM-dd"));
form.add(new CheckBox("notify", notificationModel));
List<Status> statusChoices = Arrays.asList(Status.Open, Status.Closed);
form.add(new DropDownChoice<TicketModel.Status>("status", statusModel, statusChoices));
@@ -160,8 +164,9 @@ public class EditMilestonePage extends RepositoryPage {
public void onSubmit() {
UserModel currentUser = GitBlitWebSession.get().getUser();
String createdBy = currentUser.username;
boolean notify = notificationModel.getObject();
if (app().tickets().deleteMilestone(getRepositoryModel(), oldName, createdBy)) {
if (app().tickets().deleteMilestone(getRepositoryModel(), oldName, createdBy, notify)) {
setResponsePage(TicketsPage.class, WicketUtils.newRepositoryParameter(repositoryName));
} else {
// TODO error processing

+ 1
- 1
src/main/java/com/gitblit/wicket/pages/NewMilestonePage.html Voir le fichier

@@ -19,7 +19,7 @@
<!-- New Milestone Table -->
<table class="ticket">
<tr><th><wicket:message key="gb.milestone"></wicket:message></th><td class="edit"><input class="input-large" type="text" wicket:id="name" id="name"></input></td></tr>
<tr><th><wicket:message key="gb.due"></wicket:message></th><td class="edit"><input class="input-large" type="text" wicket:id="due"></input></td></tr>
<tr><th><wicket:message key="gb.due"></wicket:message></th><td class="edit"><input class="input-large" type="text" wicket:id="due"></input> &nbsp;<span class="help-inline" wicket:id="dueFormat"></span></td></tr>
</table>
</div>
</div>

+ 10
- 1
src/main/java/com/gitblit/wicket/pages/NewMilestonePage.java Voir le fichier

@@ -22,6 +22,7 @@ import org.apache.wicket.RestartResponseException;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.extensions.markup.html.form.DateTextField;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
@@ -78,6 +79,7 @@ public class NewMilestonePage extends RepositoryPage {
form.add(new TextField<String>("name", nameModel));
form.add(new DateTextField("due", dueModel, "yyyy-MM-dd"));
form.add(new Label("dueFormat", "yyyy-MM-dd"));
form.add(new AjaxButton("create") {
@@ -87,6 +89,13 @@ public class NewMilestonePage extends RepositoryPage {
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
String name = nameModel.getObject();
if (StringUtils.isEmpty(name)) {
// invalid name
return;
}
TicketMilestone milestone = app().tickets().getMilestone(getRepositoryModel(), name);
if (milestone != null) {
// milestone already exists
return;
}
@@ -95,7 +104,7 @@ public class NewMilestonePage extends RepositoryPage {
UserModel currentUser = GitBlitWebSession.get().getUser();
String createdBy = currentUser.username;
TicketMilestone milestone = app().tickets().createMilestone(getRepositoryModel(), name, createdBy);
milestone = app().tickets().createMilestone(getRepositoryModel(), name, createdBy);
if (milestone != null) {
milestone.due = due;
app().tickets().updateMilestone(getRepositoryModel(), milestone, createdBy);

+ 22
- 4
src/main/java/com/gitblit/wicket/pages/TicketsPage.java Voir le fichier

@@ -20,6 +20,7 @@ import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
@@ -657,9 +658,20 @@ public class TicketsPage extends TicketBasePage {
} else {
add(new Label("newMilestone").setVisible(false));
}
// milestones list
List<TicketMilestone> allMilestones = app().tickets().getMilestones(repositoryModel);
List<TicketMilestone> allMilestones = new ArrayList<TicketMilestone>(app().tickets().getMilestones(repositoryModel));
Collections.sort(allMilestones, new Comparator<TicketMilestone>() {
@Override
public int compare(TicketMilestone o1, TicketMilestone o2) {
if (o2.isOpen() && !o1.isOpen()) {
return 1;
} else if (o1.isOpen() && !o2.isOpen()) {
return -1;
}
return o2.due.compareTo(o1.due);
}
});
ListDataProvider<TicketMilestone> allMilestonesDp = new ListDataProvider<TicketMilestone>(allMilestones);
DataView<TicketMilestone> milestonesList = new DataView<TicketMilestone>("milestoneList", allMilestonesDp) {
private static final long serialVersionUID = 1L;
@@ -671,15 +683,21 @@ public class TicketsPage extends TicketBasePage {
item.add(new LinkPanel("milestoneName", null, tm.name, TicketsPage.class, params).setRenderBodyOnly(true));
String css;
String status = tm.status.name();
switch (tm.status) {
case Open:
css = "aui-lozenge aui-lozenge-subtle";
if (tm.isOverdue()) {
css = "aui-lozenge aui-lozenge-subtle aui-lozenge-error";
status = "overdue";
} else {
css = "aui-lozenge aui-lozenge-subtle";
}
break;
default:
css = "aui-lozenge";
break;
}
Label stateLabel = new Label("milestoneState", tm.status.name());
Label stateLabel = new Label("milestoneState", status);
WicketUtils.setCssClass(stateLabel, css);
item.add(stateLabel);

Chargement…
Annuler
Enregistrer