@@ -643,7 +643,7 @@ public abstract class ITicketService { | |||
public synchronized boolean renameMilestone(RepositoryModel repository, String oldName, String newName, String createdBy) { | |||
return renameMilestone(repository, oldName, newName, createdBy, true); | |||
} | |||
/** | |||
* Renames a milestone. | |||
* | |||
@@ -714,6 +714,7 @@ public abstract class ITicketService { | |||
} | |||
Repository db = null; | |||
try { | |||
TicketMilestone tm = getMilestone(repository, milestone); | |||
db = repositoryManager.getRepository(repository.name); | |||
StoredConfig config = db.getConfig(); | |||
config.unsetSection(MILESTONE, milestone); | |||
@@ -721,6 +722,14 @@ public abstract class ITicketService { | |||
milestonesCache.remove(repository.name); | |||
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); | |||
} | |||
} | |||
return true; | |||
} catch (IOException e) { | |||
log.error("failed to delete milestone " + milestone + " in " + repository, e); |
@@ -74,6 +74,14 @@ public class QueryResult implements Serializable { | |||
return type != null && Type.Proposal == type; | |||
} | |||
public boolean isOpen() { | |||
return !status.isClosed(); | |||
} | |||
public boolean isClosed() { | |||
return status.isClosed(); | |||
} | |||
public boolean isMerged() { | |||
return Status.Merged == status && !StringUtils.isEmpty(mergeSha); | |||
} |
@@ -27,7 +27,7 @@ | |||
<div class="row"> | |||
<div class="span12"> | |||
<div class="form-actions"><input class="btn btn-appmenu" type="submit" value="Save" wicket:message="value:gb.save" wicket:id="save" /> <input class="btn" type="submit" value="Cancel" wicket:message="value:gb.cancel" wicket:id="cancel" /></div> | |||
<div class="form-actions"><input class="btn btn-appmenu" type="submit" value="Save" wicket:message="value:gb.save" wicket:id="save" /> <input class="btn" type="submit" value="Cancel" wicket:message="value:gb.cancel" wicket:id="cancel" /> <input class="btn btn-danger" type="submit" value="Delete" wicket:message="value:gb.delete" wicket:id="delete" /></div> | |||
</div> | |||
</div> | |||
</form> |
@@ -28,13 +28,13 @@ import org.apache.wicket.markup.html.form.Form; | |||
import org.apache.wicket.markup.html.form.TextField; | |||
import org.apache.wicket.model.IModel; | |||
import org.apache.wicket.model.Model; | |||
import org.parboiled.common.StringUtils; | |||
import com.gitblit.models.RepositoryModel; | |||
import com.gitblit.models.TicketModel; | |||
import com.gitblit.models.TicketModel.Status; | |||
import com.gitblit.models.UserModel; | |||
import com.gitblit.tickets.TicketMilestone; | |||
import com.gitblit.utils.StringUtils; | |||
import com.gitblit.wicket.GitBlitWebSession; | |||
import com.gitblit.wicket.WicketUtils; | |||
@@ -47,13 +47,13 @@ import com.gitblit.wicket.WicketUtils; | |||
public class EditMilestonePage extends RepositoryPage { | |||
private final String oldName; | |||
private IModel<String> nameModel; | |||
private IModel<Date> dueModel; | |||
private IModel<Status> statusModel; | |||
private IModel<Boolean> notificationModel; | |||
public EditMilestonePage(PageParameters params) { | |||
@@ -64,7 +64,7 @@ public class EditMilestonePage extends RepositoryPage { | |||
// ticket service is read-only | |||
throw new RestartResponseException(TicketsPage.class, WicketUtils.newRepositoryParameter(repositoryName)); | |||
} | |||
UserModel currentUser = GitBlitWebSession.get().getUser(); | |||
if (currentUser == null) { | |||
currentUser = UserModel.ANONYMOUS; | |||
@@ -74,13 +74,13 @@ public class EditMilestonePage extends RepositoryPage { | |||
// administration prohibited | |||
throw new RestartResponseException(TicketsPage.class, WicketUtils.newRepositoryParameter(repositoryName)); | |||
} | |||
oldName = WicketUtils.getObject(params); | |||
if (StringUtils.isEmpty(oldName)) { | |||
// milestone not specified | |||
throw new RestartResponseException(TicketsPage.class, WicketUtils.newRepositoryParameter(repositoryName)); | |||
} | |||
TicketMilestone tm = app().tickets().getMilestone(getRepositoryModel(), oldName); | |||
if (tm == null) { | |||
// milestone does not exist | |||
@@ -96,30 +96,30 @@ public class EditMilestonePage extends RepositoryPage { | |||
@Override | |||
protected void onSubmit() { | |||
String name = nameModel.getObject(); | |||
if (StringUtils.isEmpty(name)) { | |||
return; | |||
} | |||
Date due = dueModel.getObject(); | |||
Status status = statusModel.getObject(); | |||
boolean rename = !name.equals(oldName); | |||
boolean notify = notificationModel.getObject(); | |||
UserModel currentUser = GitBlitWebSession.get().getUser(); | |||
String createdBy = currentUser.username; | |||
TicketMilestone tm = app().tickets().getMilestone(getRepositoryModel(), oldName); | |||
tm.setName(name); | |||
tm.setDue(due); | |||
tm.status = status; | |||
boolean success = true; | |||
if (rename) { | |||
success = app().tickets().renameMilestone(getRepositoryModel(), oldName, name, createdBy, notify); | |||
} | |||
if (success && app().tickets().updateMilestone(getRepositoryModel(), tm, createdBy)) { | |||
setResponsePage(TicketsPage.class, WicketUtils.newRepositoryParameter(getRepositoryModel().name)); | |||
} else { | |||
@@ -133,7 +133,7 @@ public class EditMilestonePage extends RepositoryPage { | |||
dueModel = Model.of(tm.due); | |||
statusModel = Model.of(tm.status); | |||
notificationModel = Model.of(true); | |||
form.add(new TextField<String>("name", nameModel)); | |||
form.add(new DateTextField("due", dueModel, "yyyy-MM-dd")); | |||
@@ -152,6 +152,23 @@ public class EditMilestonePage extends RepositoryPage { | |||
cancel.setDefaultFormProcessing(false); | |||
form.add(cancel); | |||
Button delete = new Button("delete") { | |||
private static final long serialVersionUID = 1L; | |||
@Override | |||
public void onSubmit() { | |||
UserModel currentUser = GitBlitWebSession.get().getUser(); | |||
String createdBy = currentUser.username; | |||
if (app().tickets().deleteMilestone(getRepositoryModel(), oldName, createdBy)) { | |||
setResponsePage(TicketsPage.class, WicketUtils.newRepositoryParameter(repositoryName)); | |||
} else { | |||
// TODO error processing | |||
} | |||
} | |||
}; | |||
delete.setDefaultFormProcessing(false); | |||
form.add(delete); | |||
} | |||
@Override |
@@ -29,6 +29,8 @@ import org.apache.wicket.model.Model; | |||
import com.gitblit.models.RepositoryModel; | |||
import com.gitblit.models.UserModel; | |||
import com.gitblit.tickets.TicketMilestone; | |||
import com.gitblit.utils.StringUtils; | |||
import com.gitblit.utils.TimeUtils; | |||
import com.gitblit.wicket.GitBlitWebSession; | |||
import com.gitblit.wicket.WicketUtils; | |||
@@ -43,7 +45,7 @@ public class NewMilestonePage extends RepositoryPage { | |||
private IModel<String> nameModel; | |||
private IModel<Date> dueModel; | |||
public NewMilestonePage(PageParameters params) { | |||
super(params); | |||
@@ -52,7 +54,7 @@ public class NewMilestonePage extends RepositoryPage { | |||
// ticket service is read-only | |||
throw new RestartResponseException(TicketsPage.class, WicketUtils.newRepositoryParameter(repositoryName)); | |||
} | |||
UserModel currentUser = GitBlitWebSession.get().getUser(); | |||
if (currentUser == null) { | |||
currentUser = UserModel.ANONYMOUS; | |||
@@ -72,13 +74,17 @@ public class NewMilestonePage extends RepositoryPage { | |||
@Override | |||
protected void onSubmit() { | |||
String name = nameModel.getObject(); | |||
if (StringUtils.isEmpty(name)) { | |||
return; | |||
} | |||
Date due = dueModel.getObject(); | |||
UserModel currentUser = GitBlitWebSession.get().getUser(); | |||
String createdBy = currentUser.username; | |||
TicketMilestone milestone = app().tickets().createMilestone(getRepositoryModel(), name, createdBy); | |||
if (milestone != null) { | |||
milestone.due = due; | |||
@@ -92,8 +98,8 @@ public class NewMilestonePage extends RepositoryPage { | |||
add(form); | |||
nameModel = Model.of(""); | |||
dueModel = Model.of(new Date()); | |||
dueModel = Model.of(new Date(System.currentTimeMillis() + TimeUtils.ONEDAY)); | |||
form.add(new TextField<String>("name", nameModel)); | |||
form.add(new DateTextField("due", dueModel, "yyyy-MM-dd")); | |||