package scrum.client.issues;
import ilarkesto.core.base.Str;
import ilarkesto.gwt.client.AMultiSelectionViewEditWidget;
import ilarkesto.gwt.client.AOutputViewEditWidget;
import ilarkesto.gwt.client.ButtonWidget;
import ilarkesto.gwt.client.Gwt;
import ilarkesto.gwt.client.TableBuilder;
import ilarkesto.gwt.client.editor.AEditorModel;
import ilarkesto.gwt.client.editor.DropdownEditorWidget;
import ilarkesto.gwt.client.editor.TextOutputWidget;
import java.util.Collections;
import java.util.List;
import scrum.client.ScrumGwt;
import scrum.client.collaboration.CommentsWidget;
import scrum.client.collaboration.EmoticonSelectorWidget;
import scrum.client.common.AScrumWidget;
import scrum.client.journal.ChangeHistoryWidget;
import scrum.client.release.Release;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;
public class IssueWidget extends AScrumWidget {
private Issue issue;
private boolean fixedOnInitialization;
public IssueWidget(Issue issue) {
super();
this.issue = issue;
}
@Override
protected Widget onInitialization() {
fixedOnInitialization = issue.isFixed();
TableBuilder left = ScrumGwt.createFieldTable();
left.addFieldRow("Label", issue.getLabelModel());
if (issue.isBug()) {
left.addFieldRow("Severity", new DropdownEditorWidget<Integer>(issue.getSeverityModel(),
Issue.SEVERITY_LABELS));
}
left.addFieldRow("Description", issue.getDescriptionModel());
left.addFieldRow("Issuer", new TextOutputWidget(new AEditorModel<String>() {
@Override
public String getValue() {
return issue.getIssuer();
}
@Override
public void setValue(String value) {}
@Override
public String getTooltip() {
return "Person who created this issue.";
}
}));
left.addFieldRow("Statement", issue.getStatementModel());
left.addFieldRow("Affected releases", new AMultiSelectionViewEditWidget<Release>() {
@Override
protected void onViewerUpdate() {
setViewerItems(issue.getAffectedReleases());
}
@Override
protected void onEditorUpdate() {
List<Release> releases = issue.getProject().getReleasedReleases();
Collections.sort(releases, Release.DATE_REVERSE_COMPARATOR);
setEditorItems(releases);
setEditorSelectedItems(issue.getAffectedReleases());
}
@Override
protected void onEditorSubmit() {
issue.setAffectedReleases(getEditorSelectedItems());
}
@Override
public boolean isEditable() {
return true;
}
@Override
public String getTooltip() {
return "Releases on which this issue is related to. This could be the release, where the issue was discovered.";
}
});
left.addFieldRow("Fix releases", new AMultiSelectionViewEditWidget<Release>() {
@Override
protected void onViewerUpdate() {
setViewerItems(issue.getFixReleases());
}
@Override
protected void onEditorUpdate() {
List<Release> releases = issue.getProject().getReleases();
Collections.sort(releases, Release.DATE_REVERSE_COMPARATOR);
setEditorItems(releases);
setEditorSelectedItems(issue.getFixReleases());
}
@Override
protected void onEditorSubmit() {
issue.setFixReleases(getEditorSelectedItems());
}
@Override
public boolean isEditable() {
return true;
}
@Override
public String getTooltip() {
return "Releases to which this issue is or will be fixed.";
}
});
if (issue.getProject().getHomepageDir() != null) {
left.addFieldRow("Published", new AOutputViewEditWidget() {
@Override
protected void onViewerUpdate() {
if (issue.isPublished()) {
String url = issue.getProject().getHomepageUrl();
if (Str.isBlank(url)) {
setViewer(new Label("Yes"));
} else {
if (!url.endsWith("/")) url += "/";
url += issue.getReference() + ".html";
setViewer(new HTML("<a href=\"" + url + "\" target=\"_blank\">" + url + "</a>"));
}
} else {
setViewer(new Label("No"));
}
}
});
}
left.addRow(new ChangeHistoryWidget(issue), 2);
TableBuilder right = ScrumGwt.createFieldTable();
if (issue.isOpen() && issue.getProject().isProductOwner(getCurrentUser())) {
right.addRow(createActionsPanelForOpenIssue(), 2);
right.addRow(ScrumGwt.createSpacer(1, 10), 2);
} else if (issue.isBug() && issue.isFixed() && issue.getProject().isProductOwner(getCurrentUser())) {
right.addRow(createActionsPanelForFixedIssue(), 2);
right.addRow(ScrumGwt.createSpacer(1, 10), 2);
}
right.addFieldRow("My emoticon", new EmoticonSelectorWidget(issue));
right.addRow(new CommentsWidget(issue), 2);
return TableBuilder.row(20, left.createTable(), right.createTable());
}
@Override
protected boolean isResetRequired() {
return fixedOnInitialization && !issue.isFixed();
}
private Widget createActionsPanelForOpenIssue() {
TableBuilder tb = new TableBuilder();
tb.setWidth(null);
tb.setColumnWidths("30%", "10", "30%", "10", "30%");
tb.addRow(new Label("This issue is open. As Product Owner, you have to decide:"), 5);
tb.addRow(Gwt.createSpacer(1, 10));
tb.add(new ButtonWidget(new AcceptIssueAsIdeaAction(issue)));
tb.add(Gwt.createSpacer(10, 1));
tb.add(new ButtonWidget(new AcceptIssueAsBugAction(issue)));
tb.add(Gwt.createSpacer(10, 1));
tb.add(new ButtonWidget(new CloseIssueAction(issue)));
tb.nextRow();
tb.addRow(Gwt.createSpacer(1, 10));
tb.add(new Label("If this Issue is an idea, which needs to by converted to a Story by the Product Owner."));
tb.add(Gwt.createSpacer(10, 1));
tb.add(new Label("If this Issue is a bug, which needs to be fixed by the Team."));
tb.add(Gwt.createSpacer(10, 1));
tb.add(new Label("If this Issue makes no sense, is a duplicate or is already fixed."));
return ScrumGwt.createActionsPanel(tb.createTable());
}
private Widget createActionsPanelForFixedIssue() {
TableBuilder tb = new TableBuilder();
tb.setWidth(null);
tb.setColumnWidths("48%", "10", "48%");
tb.addRow(new Label("This issue is fixed. As Product Owner, you have to decide:"), 3);
tb.addRow(Gwt.createSpacer(1, 10));
tb.add(new ButtonWidget(new CloseIssueAction(issue)));
tb.add(Gwt.createSpacer(10, 1));
tb.add(new ButtonWidget(new RejectFixIssueAction(issue)));
tb.nextRow();
tb.addRow(Gwt.createSpacer(1, 10));
tb.add(new Label("If this issue is fixed sufficiently."));
tb.add(Gwt.createSpacer(10, 1));
tb.add(new Label("If this issue is fixed insufficient. Please provide a comment in this case."));
return ScrumGwt.createActionsPanel(tb.createTable());
}
}