Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Milestone Picker #5

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
d775202
Initial version of milestone picker
m133225 Feb 3, 2016
d3cc6c4
Removed leftover debug statement.
m133225 Feb 3, 2016
0ed1596
Removed debug statements for testing github's api
m133225 Feb 4, 2016
30229d3
Fixed comparing the milestones based on the description instead of it…
m133225 Feb 4, 2016
148dd7a
Allow user to unselect a label by clicking on it (again). Modified Ch…
m133225 Feb 4, 2016
2717d08
Changed keyboard shortcut M to show the milestone picker instead of u…
m133225 Feb 4, 2016
239fd38
Fixed initial highlight not prioritising an already-selected label. F…
m133225 Feb 5, 2016
29661c2
LEFT and RIGHT arrows are used to move the highlighted on the milesto…
m133225 Feb 5, 2016
1e952cc
Extracted helper functions that involve finding or getting the highli…
m133225 Feb 5, 2016
de1c85e
Added vertical gap in between milestones in a milestone group. Made P…
m133225 Feb 5, 2016
a297933
Refactoring in classes related to milestone picker.
m133225 Feb 5, 2016
cd14bfa
Merge branch 'master' into m133225-milestone-picker
m133225 Feb 5, 2016
7a4d5db
Added milestone picker logic which relies on text input. Clicking of …
m133225 Feb 14, 2016
647031f
Implemented setMilestone method in DummyRepoState. Modified Logic's r…
m133225 Feb 17, 2016
3b8e1a9
Extracted logic and state of MilestonePicker into MilestonePickerStat…
m133225 Feb 17, 2016
b8349eb
Removed dependency on dialog for PickerMilestone for easier testing. …
m133225 Feb 17, 2016
de6a821
Fixed dialog not updated when there is a changed made by mouse clicks.
m133225 Feb 17, 2016
3bd184a
Fixed incorrect handling of unassigning milestones.
m133225 Feb 18, 2016
6374f24
Some method name changes and refactoring. More test cases added.
m133225 Feb 20, 2016
a8b5ede
Minor refactoring in MilestonePickerDialog and MilestonePickerState.
m133225 Feb 23, 2016
4d08c40
Moved processInput into a new MilestonePickerState constructor. Refac…
m133225 Feb 23, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/main/java/backend/Logic.java
Original file line number Diff line number Diff line change
@@ -215,6 +215,22 @@ public CompletableFuture<Boolean> replaceIssueLabels(TurboIssue issue, List<Stri
.exceptionally(Futures.withResult(false));
}

public CompletableFuture<Boolean> replaceIssueMilestone(TurboIssue issue, Integer milestone) {
logger.info("Changing milestone for " + issue + " on GitHub");
return repoIO.replaceIssueMilestone(issue, milestone)
.thenApply(resultingIssue -> {
logger.info("Changing milestone for " + issue + " on UI");
if (resultingIssue.getMilestone() != null) {
issue.setMilestoneById(resultingIssue.getMilestone().getNumber());
} else {
issue.setMilestoneById(null);
}
refreshUI();
return true;
})
.exceptionally(Futures.withResult(false));
}

/**
* Determines data to be sent to the GUI to refresh the entire GUI with the current model in Logic,
* and then sends the data to the GUI.
6 changes: 6 additions & 0 deletions src/main/java/backend/RepoIO.java
Original file line number Diff line number Diff line change
@@ -6,9 +6,11 @@
import backend.json.JSONStore;
import backend.resource.Model;
import backend.resource.TurboIssue;
import backend.resource.TurboMilestone;
import backend.resource.serialization.SerializableModel;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.logging.log4j.Logger;
import org.eclipse.egit.github.core.Issue;
import ui.UI;
import util.HTLog;
import util.events.ShowErrorDialogEvent;
@@ -164,6 +166,10 @@ public CompletableFuture<List<String>> replaceIssueLabels(TurboIssue issue, List
return repoSource.replaceIssueLabels(issue, labels);
}

public CompletableFuture<Issue> replaceIssueMilestone(TurboIssue issue, Integer milestone) {
return repoSource.replaceIssueMilestone(issue, milestone);
}

public CompletableFuture<ImmutablePair<Integer, Long>> getRateLimitResetTime() {
return repoSource.getRateLimitResetTime();
}
19 changes: 19 additions & 0 deletions src/main/java/backend/github/GitHubRepo.java
Original file line number Diff line number Diff line change
@@ -13,6 +13,8 @@
import org.apache.logging.log4j.Logger;
import org.eclipse.egit.github.core.*;
import org.eclipse.egit.github.core.client.*;
import org.eclipse.egit.github.core.Issue;
import org.eclipse.egit.github.core.Milestone;
import org.eclipse.egit.github.core.service.CollaboratorService;
import org.eclipse.egit.github.core.service.IssueService;
import org.eclipse.egit.github.core.service.MilestoneService;
@@ -259,6 +261,23 @@ public List<Label> setLabels(String repoId, int issueId, List<String> labels) th
);
}


@Override
public Issue setMilestone(String repoId, int issueId, String issueTitle, Integer issueMilestone) throws IOException {
Milestone gitHubMilestone = new Milestone();
if (issueMilestone != null) {
gitHubMilestone.setNumber(issueMilestone);
}

// github api requires at least id and title
Issue createdIssue = new Issue();
createdIssue.setNumber(issueId);
createdIssue.setTitle(issueTitle);
createdIssue.setMilestone(gitHubMilestone);

return issueService.editIssue(RepositoryId.createFromId(repoId), createdIssue);
}

@Override
public boolean isRepositoryValid(String repoId) {
String repoURL = SEGMENT_REPOS + "/" + repoId;
8 changes: 8 additions & 0 deletions src/main/java/backend/github/GitHubSource.java
Original file line number Diff line number Diff line change
@@ -6,8 +6,10 @@
import backend.interfaces.RepoSource;
import backend.resource.Model;
import backend.resource.TurboIssue;
import backend.resource.TurboMilestone;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.logging.log4j.Logger;
import org.eclipse.egit.github.core.Issue;
import util.HTLog;

import java.util.List;
@@ -64,6 +66,12 @@ public CompletableFuture<List<String>> replaceIssueLabels(TurboIssue issue, List
return addTask(new ReplaceIssueLabelsTask(this, gitHub, issue.getRepoId(), issue.getId(), labels)).response;
}

@Override
public CompletableFuture<Issue> replaceIssueMilestone(TurboIssue issue, Integer milestone) {
return addTask(new ReplaceIssueMilestoneTask(this, gitHub, issue.getRepoId(), issue.getId(), issue.getTitle(),
milestone)).response;
}

@Override
public CompletableFuture<ImmutablePair<Integer, Long>> getRateLimitResetTime() {
return addTask(new CheckRateLimitTask(this, gitHub)).response;
34 changes: 34 additions & 0 deletions src/main/java/backend/github/ReplaceIssueMilestoneTask.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package backend.github;

import backend.interfaces.Repo;
import backend.interfaces.TaskRunner;
import org.eclipse.egit.github.core.Issue;

import java.io.IOException;

public class ReplaceIssueMilestoneTask extends GitHubRepoTask<Issue> {
private final String repoId;
private final int issueId;
private final String issueTitle;
private final Integer issueMilestone;

public ReplaceIssueMilestoneTask(TaskRunner taskRunner, Repo repo, String repoId, int issueId, String issueTitle,
Integer issueMilestone) {
super(taskRunner, repo);
this.repoId = repoId;
this.issueId = issueId;
this.issueMilestone = issueMilestone;
this.issueTitle = issueTitle;
}

@Override
public void run() {
try {
response.complete(
repo.setMilestone(repoId, issueId, issueTitle, issueMilestone)
);
} catch (IOException e) {
response.completeExceptionally(e);
}
}
}
3 changes: 3 additions & 0 deletions src/main/java/backend/interfaces/Repo.java
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.ImmutableTriple;
import org.eclipse.egit.github.core.Comment;
import org.eclipse.egit.github.core.Issue;
import org.eclipse.egit.github.core.Label;
import org.eclipse.egit.github.core.PullRequest;

@@ -41,6 +42,8 @@ public interface Repo {

boolean isRepositoryValid(String repoId);
List<Label> setLabels(String repoId, int issueId, List<String> labels) throws IOException;

Issue setMilestone(String repoId, int issueId, String issueTitle, Integer issueMilestone) throws IOException;
ImmutablePair<Integer, Long> getRateLimitResetTime() throws IOException;

}
4 changes: 4 additions & 0 deletions src/main/java/backend/interfaces/RepoSource.java
Original file line number Diff line number Diff line change
@@ -4,7 +4,9 @@
import backend.UserCredentials;
import backend.resource.Model;
import backend.resource.TurboIssue;
import backend.resource.TurboMilestone;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.eclipse.egit.github.core.Issue;

import java.util.List;
import java.util.Map;
@@ -42,6 +44,8 @@ public void execute(Runnable r) {

public abstract CompletableFuture<List<String>> replaceIssueLabels(TurboIssue issue, List<String> labels);

public abstract CompletableFuture<Issue> replaceIssueMilestone(TurboIssue issue, Integer milestone);

public abstract CompletableFuture<ImmutablePair<Integer, Long>> getRateLimitResetTime();

}
6 changes: 3 additions & 3 deletions src/main/java/backend/resource/TurboIssue.java
Original file line number Diff line number Diff line change
@@ -372,11 +372,11 @@ public void addLabel(TurboLabel label) {
public Optional<Integer> getMilestone() {
return milestone;
}
public void setMilestone(Integer milestone) {
this.milestone = Optional.of(milestone);
public void setMilestoneById(Integer milestone) {
this.milestone = (milestone == null) ? Optional.empty() : Optional.of(milestone);
}
public void setMilestone(TurboMilestone milestone) {
setMilestone(milestone.getId());
setMilestoneById(milestone.getId());
}
public IssueMetadata getMetadata() {
return metadata;
6 changes: 6 additions & 0 deletions src/main/java/backend/stub/DummyRepo.java
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.ImmutableTriple;
import org.eclipse.egit.github.core.Comment;
import org.eclipse.egit.github.core.Issue;
import org.eclipse.egit.github.core.Label;
import org.eclipse.egit.github.core.PullRequest;
import ui.UI;
@@ -182,6 +183,11 @@ public List<Label> setLabels(String repoId, int issueId, List<String> labels) {
return getRepoState(repoId).setLabels(issueId, labels);
}

@Override
public Issue setMilestone(String repoId, int issueId, String issueTitle, Integer issueMilestone) {
return getRepoState(repoId).setMilestone(issueId, issueMilestone);
}

@Override
public boolean isRepositoryValid(String repoId) {
return true;
30 changes: 27 additions & 3 deletions src/main/java/backend/stub/DummyRepoState.java
Original file line number Diff line number Diff line change
@@ -9,9 +9,7 @@
import github.TurboIssueEvent;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.ImmutableTriple;
import org.eclipse.egit.github.core.Comment;
import org.eclipse.egit.github.core.Label;
import org.eclipse.egit.github.core.User;
import org.eclipse.egit.github.core.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
@@ -387,6 +385,32 @@ protected final List<Label> setLabels(int issueId, List<String> newLabels) {
return newLabels.stream().map(new Label()::setName).collect(Collectors.toList());
}

protected final Issue setMilestone(int issueId, Integer milestone) {
ImmutablePair<TurboIssue, IssueMetadata> mutables = produceMutables(issueId);
TurboIssue toSet = mutables.getLeft();
IssueMetadata metadataOfIssue = mutables.getRight();
List<TurboIssueEvent> eventsOfIssue = metadataOfIssue.getEvents();

if (toSet.getMilestone().isPresent()) {
int milestoneOfIssue = toSet.getMilestone().get();
eventsOfIssue.add(new TurboIssueEvent(new User().setLogin("test"),
IssueEventType.Demilestoned,
new Date()).setMilestoneTitle(milestones.get(milestoneOfIssue).getTitle()));
}

eventsOfIssue.add(new TurboIssueEvent(new User().setLogin("test"),
IssueEventType.Milestoned,
new Date()).setMilestoneTitle(milestones.get(milestone).getTitle()));
toSet.setMilestoneById(milestone);
toSet.setUpdatedAt(LocalDateTime.now());

markUpdatedEvents(toSet, IssueMetadata.intermediate(eventsOfIssue, metadataOfIssue.getComments(), "", ""));

Issue newIssue = new Issue();
newIssue.setMilestone(new Milestone().setNumber(milestone));
return newIssue;
}

protected TurboIssue commentOnIssue(String author, String commentText, int issueId) {
// Get copies of issue itself and its metadata
ImmutablePair<TurboIssue, IssueMetadata> mutables = produceMutables(issueId);
7 changes: 7 additions & 0 deletions src/main/java/backend/stub/DummySource.java
Original file line number Diff line number Diff line change
@@ -9,7 +9,9 @@
import backend.interfaces.RepoSource;
import backend.resource.Model;
import backend.resource.TurboIssue;
import backend.resource.TurboMilestone;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.eclipse.egit.github.core.Issue;
import util.Futures;

import java.util.List;
@@ -53,6 +55,11 @@ public CompletableFuture<List<String>> replaceIssueLabels(TurboIssue issue, List
return addTask(new ReplaceIssueLabelsTask(this, dummy, issue.getRepoId(), issue.getId(), labels)).response;
}

@Override
public CompletableFuture<Issue> replaceIssueMilestone(TurboIssue issue, Integer milestone) {
return null;
}

@Override
public CompletableFuture<Boolean> isRepositoryValid(String repoId) {
return Futures.unit(true);
3 changes: 2 additions & 1 deletion src/main/java/github/TurboIssueEvent.java
Original file line number Diff line number Diff line change
@@ -90,9 +90,10 @@ public String getMilestoneTitle() {
assert type == IssueEventType.Milestoned || type == IssueEventType.Demilestoned;
return milestoneTitle;
}
public void setMilestoneTitle(String milestoneTitle) {
public TurboIssueEvent setMilestoneTitle(String milestoneTitle) {
assert type == IssueEventType.Milestoned || type == IssueEventType.Demilestoned;
this.milestoneTitle = milestoneTitle;
return this;
}
public String getRenamedFrom() {
assert type == IssueEventType.Renamed;
2 changes: 2 additions & 0 deletions src/main/java/ui/UI.java
Original file line number Diff line number Diff line change
@@ -32,6 +32,7 @@
import ui.components.KeyboardShortcuts;
import ui.components.StatusUI;
import ui.components.pickers.LabelPicker;
import ui.components.pickers.MilestonePicker;
import ui.issuepanel.PanelControl;
import undo.UndoController;
import util.*;
@@ -178,6 +179,7 @@ private void showMainWindow(String repoId) {

private void initialisePickers() {
new LabelPicker(this, mainStage);
new MilestonePicker(this, mainStage);
}

protected void registerTestEvents() {
45 changes: 45 additions & 0 deletions src/main/java/ui/components/pickers/MilestonePicker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package ui.components.pickers;

import backend.resource.TurboIssue;
import backend.resource.TurboMilestone;
import backend.resource.TurboUser;
import javafx.application.Platform;
import javafx.scene.control.ButtonType;
import javafx.stage.Stage;
import javafx.util.Pair;
import ui.UI;
import undo.actions.ChangeLabelsAction;
import undo.actions.ChangeMilestoneAction;
import util.events.ShowMilestonePickerEvent;
import util.events.ShowMilestonePickerEventHandler;

import java.util.List;
import java.util.Optional;

public class MilestonePicker {
UI ui;
Stage stage;

public MilestonePicker(UI ui, Stage mainStage) {
this.ui = ui;
this.stage = mainStage;
ui.registerEvent((ShowMilestonePickerEventHandler) e -> Platform.runLater(() -> showMilestonePicker(e.issue)));
}

private void showMilestonePicker(TurboIssue issue) {
List<TurboMilestone> milestoneList = ui.logic.getRepo(issue.getRepoId()).getMilestones();
MilestonePickerDialog dialog = new MilestonePickerDialog(stage, issue, milestoneList);
Optional<Pair<ButtonType, Integer>> milestoneDialogResponse = dialog.showAndWait();

if (!milestoneDialogResponse.isPresent() ||
milestoneDialogResponse.get().getKey().equals(ButtonType.CANCEL)) return;

Optional<Integer> newlyAssignedMilestone = Optional.ofNullable(milestoneDialogResponse.get().getValue());

if (!issue.getMilestone().equals(newlyAssignedMilestone)) {
ui.undoController.addAction(issue, new ChangeMilestoneAction(ui.logic, issue.getMilestone(),
newlyAssignedMilestone));
}
}

}
Loading