Merged #157 "Add Priority & Severity fields to the ticket model"
1 files added
19 files modified
| | |
| | | |
| | | public Integer deletions; |
| | | |
| | | public Priority priority; |
| | | |
| | | public Severity severity; |
| | | |
| | | /** |
| | | * Builds an effective ticket from the collection of changes. A change may |
| | | * Add or Subtract information from a ticket, but the collection of changes |
| | |
| | | changes = new ArrayList<Change>(); |
| | | status = Status.New; |
| | | type = Type.defaultType; |
| | | priority = Priority.defaultPriority; |
| | | severity = Severity.defaultSeverity; |
| | | } |
| | | |
| | | public boolean isOpen() { |
| | |
| | | break; |
| | | case mergeSha: |
| | | mergeSha = toString(value); |
| | | break; |
| | | case priority: |
| | | priority = TicketModel.Priority.fromObject(value, priority); |
| | | break; |
| | | case severity: |
| | | severity = TicketModel.Severity.fromObject(value, severity); |
| | | break; |
| | | default: |
| | | // unknown |
| | |
| | | |
| | | public static enum Field { |
| | | title, body, responsible, type, status, milestone, mergeSha, mergeTo, |
| | | topic, labels, watchers, reviewers, voters, mentions; |
| | | topic, labels, watchers, reviewers, voters, mentions, priority, severity; |
| | | } |
| | | |
| | | public static enum Type { |
| | |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | public static enum Priority { |
| | | Low(-1), Normal(0), High(1), Urgent(2); |
| | | |
| | | public static Priority defaultPriority = Normal; |
| | | |
| | | final int value; |
| | | |
| | | Priority(int value) { |
| | | this.value = value; |
| | | } |
| | | |
| | | public int getValue() { |
| | | return value; |
| | | } |
| | | |
| | | public static Priority [] choices() { |
| | | return new Priority [] { Urgent, High, Normal, Low }; |
| | | } |
| | | |
| | | @Override |
| | | public String toString() { |
| | | return name().toLowerCase().replace('_', ' '); |
| | | } |
| | | |
| | | public static Priority fromObject(Object o, Priority defaultPriority) { |
| | | if (o instanceof Priority) { |
| | | // cast and return |
| | | return (Priority) o; |
| | | } else if (o instanceof String) { |
| | | // find by name |
| | | for (Priority priority : values()) { |
| | | String str = o.toString(); |
| | | if (priority.name().equalsIgnoreCase(str) |
| | | || priority.toString().equalsIgnoreCase(str)) { |
| | | return priority; |
| | | } |
| | | } |
| | | } else if (o instanceof Number) { |
| | | |
| | | switch (((Number) o).intValue()) { |
| | | case -1: return Priority.Low; |
| | | case 0: return Priority.Normal; |
| | | case 1: return Priority.High; |
| | | case 2: return Priority.Urgent; |
| | | default: return Priority.Normal; |
| | | } |
| | | } |
| | | |
| | | return defaultPriority; |
| | | } |
| | | } |
| | | |
| | | public static enum Severity { |
| | | Unrated(-1), Negligible(1), Minor(2), Serious(3), Critical(4), Catastrophic(5); |
| | | |
| | | public static Severity defaultSeverity = Unrated; |
| | | |
| | | final int value; |
| | | |
| | | Severity(int value) { |
| | | this.value = value; |
| | | } |
| | | |
| | | public int getValue() { |
| | | return value; |
| | | } |
| | | |
| | | public static Severity [] choices() { |
| | | return new Severity [] { Unrated, Negligible, Minor, Serious, Critical, Catastrophic }; |
| | | } |
| | | |
| | | @Override |
| | | public String toString() { |
| | | return name().toLowerCase().replace('_', ' '); |
| | | } |
| | | |
| | | public static Severity fromObject(Object o, Severity defaultSeverity) { |
| | | if (o instanceof Severity) { |
| | | // cast and return |
| | | return (Severity) o; |
| | | } else if (o instanceof String) { |
| | | // find by name |
| | | for (Severity severity : values()) { |
| | | String str = o.toString(); |
| | | if (severity.name().equalsIgnoreCase(str) |
| | | || severity.toString().equalsIgnoreCase(str)) { |
| | | return severity; |
| | | } |
| | | } |
| | | } else if (o instanceof Number) { |
| | | |
| | | switch (((Number) o).intValue()) { |
| | | case -1: return Severity.Unrated; |
| | | case 1: return Severity.Negligible; |
| | | case 2: return Severity.Minor; |
| | | case 3: return Severity.Serious; |
| | | case 4: return Severity.Critical; |
| | | case 5: return Severity.Catastrophic; |
| | | default: return Severity.Unrated; |
| | | } |
| | | } |
| | | |
| | | return defaultSeverity; |
| | | } |
| | | } |
| | | } |
| | |
| | | import com.gitblit.models.TicketModel.Patchset; |
| | | import com.gitblit.models.TicketModel.Status; |
| | | import com.gitblit.models.TicketModel.Type; |
| | | import com.gitblit.models.TicketModel.Priority; |
| | | import com.gitblit.models.TicketModel.Severity; |
| | | import com.gitblit.utils.StringUtils; |
| | | |
| | | /** |
| | |
| | | public int commentsCount; |
| | | public int votesCount; |
| | | public int approvalsCount; |
| | | public Priority priority; |
| | | public Severity severity; |
| | | |
| | | public int docId; |
| | | public int totalResults; |
| | |
| | | mergesha(Type.STRING), |
| | | mergeto(Type.STRING), |
| | | patchsets(Type.INT), |
| | | votes(Type.INT); |
| | | votes(Type.INT), |
| | | //NOTE: Indexing on the underlying value to allow flexibility on naming |
| | | priority(Type.INT), |
| | | severity(Type.INT); |
| | | |
| | | final Type fieldType; |
| | | |
| | |
| | | toDocField(doc, Lucene.watchedby, StringUtils.flattenStrings(ticket.getWatchers(), ";").toLowerCase()); |
| | | toDocField(doc, Lucene.mentions, StringUtils.flattenStrings(ticket.getMentions(), ";").toLowerCase()); |
| | | toDocField(doc, Lucene.votes, ticket.getVoters().size()); |
| | | toDocField(doc, Lucene.priority, ticket.priority.getValue()); |
| | | toDocField(doc, Lucene.severity, ticket.severity.getValue()); |
| | | |
| | | List<String> attachments = new ArrayList<String>(); |
| | | for (Attachment attachment : ticket.getAttachments()) { |
| | |
| | | result.participants = unpackStrings(doc, Lucene.participants); |
| | | result.watchedby = unpackStrings(doc, Lucene.watchedby); |
| | | result.mentions = unpackStrings(doc, Lucene.mentions); |
| | | result.priority = TicketModel.Priority.fromObject(unpackInt(doc, Lucene.priority), TicketModel.Priority.defaultPriority); |
| | | result.severity = TicketModel.Severity.fromObject(unpackInt(doc, Lucene.severity), TicketModel.Severity.defaultSeverity); |
| | | |
| | | if (!StringUtils.isEmpty(doc.get(Lucene.patchset.name()))) { |
| | | // unpack most recent patchset |
| | |
| | | gb.permission = Permission |
| | | gb.sshKeyPermissionDescription = Specify the access permission for the SSH key |
| | | gb.transportPreference = Transport Preference |
| | | gb.transportPreferenceDescription = Set the transport that you prefer to use for cloning |
| | | gb.transportPreferenceDescription = Set the transport that you prefer to use for cloning |
| | | gb.priority = priority |
| | | gb.severity = severity |
| | | gb.sortHighestPriority = highest priority |
| | | gb.sortLowestPriority = lowest priority |
| | | gb.sortHighestSeverity = highest severity |
| | | gb.sortLowestSeverity = lowest severity |
| | |
| | | import org.apache.wicket.markup.html.basic.Label; |
| | | |
| | | import com.gitblit.models.TicketModel; |
| | | import com.gitblit.models.TicketModel.Priority; |
| | | import com.gitblit.models.TicketModel.Severity; |
| | | import com.gitblit.models.TicketModel.Status; |
| | | import com.gitblit.models.TicketModel.Type; |
| | | import com.gitblit.utils.StringUtils; |
| | |
| | | public static final String [] closedStatii = new String [] { "!" + Status.New.name().toLowerCase(), "!" + Status.Open.name().toLowerCase() }; |
| | | |
| | | public static Label getStateIcon(String wicketId, TicketModel ticket) { |
| | | return getStateIcon(wicketId, ticket.type, ticket.status); |
| | | return getStateIcon(wicketId, ticket.type, ticket.status, ticket.severity); |
| | | } |
| | | |
| | | public static Label getStateIcon(String wicketId, Type type, Status state) { |
| | | public static Label getStateIcon(String wicketId, Type type, Status state, Severity severity) { |
| | | Label label = new Label(wicketId); |
| | | if (type == null) { |
| | | type = Type.defaultType; |
| | | } |
| | | switch (type) { |
| | | case Proposal: |
| | | WicketUtils.setCssClass(label, "fa fa-code-fork"); |
| | | WicketUtils.setCssClass(label, "fa fa-code-fork fa-fw"); |
| | | break; |
| | | case Bug: |
| | | WicketUtils.setCssClass(label, "fa fa-bug"); |
| | | WicketUtils.setCssClass(label, "fa fa-bug fa-fw"); |
| | | break; |
| | | case Enhancement: |
| | | WicketUtils.setCssClass(label, "fa fa-magic"); |
| | | WicketUtils.setCssClass(label, "fa fa-magic fa-fw"); |
| | | break; |
| | | case Question: |
| | | WicketUtils.setCssClass(label, "fa fa-question"); |
| | | WicketUtils.setCssClass(label, "fa fa-question fa-fw"); |
| | | break; |
| | | case Maintenance: |
| | | WicketUtils.setCssClass(label, "fa fa-cogs"); |
| | | WicketUtils.setCssClass(label, "fa fa-cogs fa-fw"); |
| | | break; |
| | | default: |
| | | // standard ticket |
| | | WicketUtils.setCssClass(label, "fa fa-ticket"); |
| | | WicketUtils.setCssClass(label, "fa fa-ticket fa-fw"); |
| | | } |
| | | WicketUtils.setHtmlTooltip(label, getTypeState(type, state)); |
| | | WicketUtils.setHtmlTooltip(label, getTypeState(type, state, severity)); |
| | | |
| | | return label; |
| | | } |
| | | |
| | | public static String getTypeState(Type type, Status state) { |
| | | return state.toString() + " " + type.toString(); |
| | | public static Label getPriorityIcon(String wicketId, Priority priority) { |
| | | Label label = new Label(wicketId); |
| | | if (priority == null) { |
| | | priority = Priority.defaultPriority; |
| | | } |
| | | switch (priority) { |
| | | case Urgent: |
| | | WicketUtils.setCssClass(label, "fa fa-step-forward fa-rotate-270"); |
| | | break; |
| | | case High: |
| | | WicketUtils.setCssClass(label, "fa fa-caret-up fa-lg"); |
| | | break; |
| | | case Low: |
| | | WicketUtils.setCssClass(label, "fa fa-caret-down fa-lg"); |
| | | break; |
| | | default: |
| | | } |
| | | WicketUtils.setHtmlTooltip(label, priority.toString()); |
| | | |
| | | return label; |
| | | } |
| | | |
| | | public static String getPriorityClass(Priority priority) { |
| | | return String.format("priority-%s", priority); |
| | | } |
| | | |
| | | public static String getSeverityClass(Severity severity) { |
| | | return String.format("severity-%s", severity); |
| | | } |
| | | |
| | | public static String getTypeState(Type type, Status state, Severity severity) { |
| | | if (Severity.Unrated == severity) { |
| | | return state.toString() + " " + type.toString(); |
| | | } |
| | | return state.toString() + " " + type.toString() + ", " + severity.toString(); |
| | | } |
| | | |
| | | public static String getLozengeClass(Status status, boolean subtle) { |
| | |
| | | import org.apache.wicket.Component;
|
| | | import org.apache.wicket.PageParameters;
|
| | | import org.apache.wicket.Request;
|
| | | import org.apache.wicket.behavior.AttributeAppender;
|
| | | import org.apache.wicket.behavior.HeaderContributor;
|
| | | import org.apache.wicket.behavior.SimpleAttributeModifier;
|
| | | import org.apache.wicket.markup.html.IHeaderContributor;
|
| | | import org.apache.wicket.markup.html.IHeaderResponse;
|
| | | import org.apache.wicket.markup.html.basic.Label;
|
| | | import org.apache.wicket.markup.html.image.ContextImage;
|
| | | import org.apache.wicket.model.Model;
|
| | | import org.apache.wicket.protocol.http.WebRequest;
|
| | | import org.apache.wicket.resource.ContextRelativeResource;
|
| | | import org.eclipse.jgit.diff.DiffEntry.ChangeType;
|
| | |
| | | container.add(new SimpleAttributeModifier("class", value));
|
| | | }
|
| | |
|
| | | public static void addCssClass(Component container, String value) {
|
| | | container.add(new AttributeAppender("class", new Model<String>(value), " "));
|
| | | }
|
| | | |
| | | public static void setCssStyle(Component container, String value) {
|
| | | container.add(new SimpleAttributeModifier("style", value));
|
| | | }
|
| | |
| | | <tr wicket:id="status"></tr>
|
| | | <tr wicket:id="responsible"></tr>
|
| | | <tr wicket:id="milestone"></tr>
|
| | | <tr><th><wicket:message key="gb.priority"></wicket:message></th><td class="edit"><select class="input-large" wicket:id="priority"></select></td></tr>
|
| | | <tr><th><wicket:message key="gb.severity"></wicket:message></th><td class="edit"><select class="input-large" wicket:id="severity"></select></td></tr>
|
| | | <tr wicket:id="mergeto"></tr>
|
| | | </table>
|
| | | </div>
|
| | |
| | | private IModel<TicketMilestone> milestoneModel;
|
| | |
|
| | | private Label descriptionPreview;
|
| | | |
| | | private IModel<TicketModel.Priority> priorityModel;
|
| | | |
| | | private IModel<TicketModel.Severity> severityModel;
|
| | |
|
| | | public EditTicketPage(PageParameters params) {
|
| | | super(params);
|
| | |
| | | milestoneModel = Model.of();
|
| | | mergeToModel = Model.of(ticket.mergeTo == null ? getRepositoryModel().mergeTo : ticket.mergeTo);
|
| | | statusModel = Model.of(ticket.status);
|
| | | priorityModel = Model.of(ticket.priority);
|
| | | severityModel = Model.of(ticket.severity);
|
| | |
|
| | | setStatelessHint(false);
|
| | | setOutputMarkupId(true);
|
| | |
| | | milestone.add(new DropDownChoice<TicketMilestone>("milestone", milestoneModel, milestones));
|
| | | form.add(milestone.setVisible(!milestones.isEmpty()));
|
| | |
|
| | | // priority
|
| | | List<TicketModel.Priority> priorityChoices = Arrays.asList(TicketModel.Priority.choices());
|
| | | form.add(new DropDownChoice<TicketModel.Priority>("priority", priorityModel, priorityChoices));
|
| | | |
| | | // severity
|
| | | List<TicketModel.Severity> severityChoices = Arrays.asList(TicketModel.Severity.choices());
|
| | | form.add(new DropDownChoice<TicketModel.Severity>("severity", severityModel, severityChoices));
|
| | | |
| | | // mergeTo (integration branch)
|
| | | List<String> branches = new ArrayList<String>();
|
| | | for (String branch : getRepositoryModel().getLocalBranches()) {
|
| | |
| | | change.setField(Field.milestone, milestone.name);
|
| | | }
|
| | | }
|
| | | |
| | | TicketModel.Priority priority = priorityModel.getObject();
|
| | | if (!ticket.priority.equals(priority))
|
| | | {
|
| | | change.setField(Field.priority, priority);
|
| | | }
|
| | |
|
| | | TicketModel.Severity severity = severityModel.getObject();
|
| | | if (!ticket.severity.equals(severity))
|
| | | {
|
| | | change.setField(Field.severity, severity);
|
| | | }
|
| | | |
| | | String mergeTo = mergeToModel.getObject();
|
| | | if ((StringUtils.isEmpty(ticket.mergeTo) && !StringUtils.isEmpty(mergeTo))
|
| | | || (!StringUtils.isEmpty(mergeTo) && !mergeTo.equals(ticket.mergeTo))) {
|
| | |
| | | sortChoices.add(new TicketSort(getString("gb.sortLeastPatchsetRevisions"), Lucene.patchsets.name(), false)); |
| | | sortChoices.add(new TicketSort(getString("gb.sortMostVotes"), Lucene.votes.name(), true)); |
| | | sortChoices.add(new TicketSort(getString("gb.sortLeastVotes"), Lucene.votes.name(), false)); |
| | | sortChoices.add(new TicketSort(getString("gb.sortHighestPriority"), Lucene.priority.name(), true)); |
| | | sortChoices.add(new TicketSort(getString("gb.sortLowestPriority"), Lucene.priority.name(), false)); |
| | | sortChoices.add(new TicketSort(getString("gb.sortHighestSeverity"), Lucene.severity.name(), true)); |
| | | sortChoices.add(new TicketSort(getString("gb.sortLowestSeverity"), Lucene.severity.name(), false)); |
| | | |
| | | TicketSort currentSort = sortChoices.get(0); |
| | | for (TicketSort ts : sortChoices) { |
| | |
| | | <tr><th><wicket:message key="gb.type"></wicket:message><span style="color:red;">*</span></th><td class="edit"><select class="input-large" wicket:id="type"></select></td></tr>
|
| | | <tr wicket:id="responsible"></tr>
|
| | | <tr wicket:id="milestone"></tr>
|
| | | <tr><th><wicket:message key="gb.priority"></wicket:message></th><td class="edit"><select class="input-large" wicket:id="priority"></select></td></tr>
|
| | | <tr><th><wicket:message key="gb.severity"></wicket:message></th><td class="edit"><select class="input-large" wicket:id="severity"></select></td></tr>
|
| | | <tr wicket:id="mergeto"></tr>
|
| | | </table>
|
| | | </div>
|
| | |
| | | private IModel<TicketMilestone> milestoneModel;
|
| | |
|
| | | private Label descriptionPreview;
|
| | | |
| | | private IModel<TicketModel.Priority> priorityModel;
|
| | | |
| | | private IModel<TicketModel.Severity> severityModel;
|
| | |
|
| | | public NewTicketPage(PageParameters params) {
|
| | | super(params);
|
| | |
| | | mergeToModel = Model.of(Repository.shortenRefName(getRepositoryModel().mergeTo));
|
| | | responsibleModel = Model.of();
|
| | | milestoneModel = Model.of();
|
| | | severityModel = Model.of(TicketModel.Severity.defaultSeverity);
|
| | | priorityModel = Model.of(TicketModel.Priority.defaultPriority);
|
| | |
|
| | | setStatelessHint(false);
|
| | | setOutputMarkupId(true);
|
| | |
| | | milestone.add(new DropDownChoice<TicketMilestone>("milestone", milestoneModel, milestones));
|
| | | form.add(milestone.setVisible(!milestones.isEmpty()));
|
| | |
|
| | | // priority
|
| | | form.add(new DropDownChoice<TicketModel.Priority>("priority", priorityModel, Arrays.asList(TicketModel.Priority.choices())));
|
| | | |
| | | //severity
|
| | | form.add(new DropDownChoice<TicketModel.Severity>("severity", severityModel, Arrays.asList(TicketModel.Severity.choices())));
|
| | | |
| | | // integration branch
|
| | | List<String> branches = new ArrayList<String>();
|
| | | for (String branch : getRepositoryModel().getLocalBranches()) {
|
| | |
| | | if (milestone != null) {
|
| | | change.setField(Field.milestone, milestone.name);
|
| | | }
|
| | | |
| | | // severity
|
| | | TicketModel.Severity severity = TicketModel.Severity.defaultSeverity;
|
| | | if (severityModel.getObject() != null) {
|
| | | severity = severityModel.getObject();
|
| | | }
|
| | | change.setField(Field.severity, severity);
|
| | | |
| | | // priority
|
| | | TicketModel.Priority priority = TicketModel.Priority.defaultPriority;
|
| | | if (priorityModel.getObject() != null) {
|
| | | priority = priorityModel.getObject();
|
| | | }
|
| | | change.setField(Field.priority, priority);
|
| | |
|
| | | // integration branch
|
| | | String mergeTo = mergeToModel.getObject();
|
| | |
| | | <div style="border: 1px solid #ccc;padding: 10px;margin: 5px 0px;">
|
| | | <table class="summary" style="width: 100%">
|
| | | <tr><th><wicket:message key="gb.type"></wicket:message></th><td><span wicket:id="ticketType">[type]</span></td></tr>
|
| | | <tr><th><wicket:message key="gb.priority"></wicket:message></th><td><span wicket:id="priority">[priority]</span></td></tr>
|
| | | <tr><th><wicket:message key="gb.severity"></wicket:message></th><td><span wicket:id="severity">[severity]</span></td></tr>
|
| | | <tr><th><wicket:message key="gb.topic"></wicket:message></th><td><span wicket:id="ticketTopic">[topic]</span></td></tr>
|
| | | <tr><th><wicket:message key="gb.responsible"></wicket:message></th><td><span wicket:id="responsible">[responsible]</span></td></tr>
|
| | | <tr><th><wicket:message key="gb.milestone"></wicket:message></th><td><span wicket:id="milestone">[milestone]</span></td></tr>
|
| | |
| | | * TICKET METADATA
|
| | | */
|
| | | add(new Label("ticketType", ticket.type.toString()));
|
| | | |
| | | add(new Label("priority", ticket.priority.toString()));
|
| | | add(new Label("severity", ticket.severity.toString()));
|
| | | |
| | | if (StringUtils.isEmpty(ticket.topic)) {
|
| | | add(new Label("ticketTopic").setVisible(false));
|
| | | } else {
|
| | |
| | | String safeTopic = app().xssFilter().relaxed(topic);
|
| | | add(new Label("ticketTopic", safeTopic).setEscapeModelStrings(false));
|
| | | }
|
| | | |
| | | |
| | |
|
| | |
|
| | | /*
|
| | |
| | | sortChoices.add(new TicketSort(getString("gb.sortLeastPatchsetRevisions"), Lucene.patchsets.name(), false));
|
| | | sortChoices.add(new TicketSort(getString("gb.sortMostVotes"), Lucene.votes.name(), true));
|
| | | sortChoices.add(new TicketSort(getString("gb.sortLeastVotes"), Lucene.votes.name(), false));
|
| | |
|
| | | sortChoices.add(new TicketSort(getString("gb.sortHighestPriority"), Lucene.priority.name(), true));
|
| | | sortChoices.add(new TicketSort(getString("gb.sortLowestPriority"), Lucene.priority.name(), false));
|
| | | sortChoices.add(new TicketSort(getString("gb.sortHighestSeverity"), Lucene.severity.name(), true));
|
| | | sortChoices.add(new TicketSort(getString("gb.sortLowestSeverity"), Lucene.severity.name(), false));
|
| | | |
| | | TicketSort currentSort = sortChoices.get(0);
|
| | | for (TicketSort ts : sortChoices) {
|
| | | if (ts.sortBy.equals(sortBy) && desc == ts.desc) {
|
| | |
| | | <td class="hidden-phone ticket-list-state">
|
| | | <i wicket:message="title:gb.watching" style="color:#888;" class="fa fa-eye" wicket:id="watching"></i>
|
| | | </td>
|
| | | <td class="ticket-list-priority">
|
| | | <div wicket:id="priority"></div>
|
| | | </td>
|
| | | <td class="ticket-list-state">
|
| | | <div wicket:id="status"></div>
|
| | | </td>
|
| | |
| | | item.add(new Label("ticketsLink").setVisible(false)); |
| | | } |
| | | |
| | | item.add(TicketsUI.getStateIcon("state", ticket.type, ticket.status)); |
| | | Label icon = TicketsUI.getStateIcon("state", ticket.type, ticket.status, ticket.severity); |
| | | WicketUtils.addCssClass(icon, TicketsUI.getSeverityClass(ticket.severity)); |
| | | item.add(icon); |
| | | |
| | | item.add(new Label("id", "" + ticket.number)); |
| | | UserModel creator = app().users().getUserModel(ticket.createdBy); |
| | | if (creator != null) { |
| | |
| | | // watching indicator |
| | | item.add(new Label("watching").setVisible(ticket.isWatching(GitBlitWebSession.get().getUsername()))); |
| | | |
| | | // priority indicator |
| | | Label priorityIcon = TicketsUI.getPriorityIcon("priority", ticket.priority); |
| | | WicketUtils.addCssClass(priorityIcon, TicketsUI.getPriorityClass(ticket.priority)); |
| | | item.add(priorityIcon.setVisible(true)); |
| | | |
| | | // status indicator |
| | | String css = TicketsUI.getLozengeClass(ticket.status, true); |
| | | Label l = new Label("status", ticket.status.toString()); |
| | |
| | | |
| | | td.ticket-list-state { |
| | | vertical-align: middle; |
| | | }
|
| | |
|
| | | td.ticket-list-priority {
|
| | | vertical-align: middle;
|
| | | } |
| | | |
| | | .ticket-list-details { |
| | |
| | | background-color: #fff; |
| | | border-color: #ece7e2; |
| | | color: #815b3a; |
| | | } |
| | | }
|
| | | .severity-catastrophic {
|
| | | color:#D51900;
|
| | | }
|
| | | .severity-catastrophic:after {
|
| | | font-family: Helvetica,arial,freesans,clean,sans-serif ;
|
| | | content: "●●●●●";
|
| | | font-weight:900;
|
| | | font-size:.45em; |
| | | font-variant:small-caps;
|
| | | display:flex;
|
| | | white-space: pre;
|
| | | }
|
| | | .severity-critical {
|
| | | color:#D55900;
|
| | | }
|
| | | .severity-critical:after {
|
| | | font-family: Helvetica,arial,freesans,clean,sans-serif ;
|
| | | content: "●●●●";
|
| | | font-weight:900;
|
| | | font-size:.45em; |
| | | font-variant:small-caps;
|
| | | display:flex;
|
| | | white-space: pre;
|
| | | }
|
| | | .severity-serious {
|
| | | color:#E69F00;
|
| | | }
|
| | | .severity-serious:after {
|
| | | font-family: Helvetica,arial,freesans,clean,sans-serif ;
|
| | | content: " ●●●";
|
| | | font-weight:900;
|
| | | font-size:.45em; |
| | | font-variant:small-caps;
|
| | | display:flex;
|
| | | white-space: pre;
|
| | | }
|
| | | .severity-minor {
|
| | | color:#009E73;
|
| | | }
|
| | | .severity-minor:after {
|
| | | font-family: Helvetica,arial,freesans,clean,sans-serif ;
|
| | | content: " ●●";
|
| | | font-weight:900;
|
| | | font-size:.45em; |
| | | font-variant:small-caps;
|
| | | display:flex;
|
| | | white-space: pre;
|
| | | }
|
| | | .severity-negligible {
|
| | | color:#0072B2;
|
| | | }
|
| | | .severity-negligible:after {
|
| | | font-family: Helvetica,arial,freesans,clean,sans-serif ;
|
| | | content: " ●";
|
| | | font-weight:900;
|
| | | font-size:.45em; |
| | | font-variant:small-caps;
|
| | | display:flex;
|
| | | white-space: pre;
|
| | | }
|
| | | .severity-unrated {
|
| | | }
|
| | | .priority-urgent {
|
| | | color:#D51900;
|
| | | }
|
| | | .priority-high {
|
| | | color:#D55900;
|
| | | }
|
| | | .priority-normal {
|
| | | }
|
| | | .priority-low {
|
| | | color:#0072B2;
|
| | | }
|
| | |
| | | FanoutServiceTest.class, Issue0259Test.class, Issue0271Test.class, HtpasswdAuthenticationTest.class,
|
| | | ModelUtilsTest.class, JnaUtilsTest.class, LdapSyncServiceTest.class, FileTicketServiceTest.class, |
| | | BranchTicketServiceTest.class, RedisTicketServiceTest.class, AuthenticationManagerTest.class,
|
| | | SshKeysDispatcherTest.class }) |
| | | SshKeysDispatcherTest.class, UITicketTest.class }) |
| | | public class GitBlitSuite {
|
| | |
|
| | | public static final File BASEFOLDER = new File("data");
|
| | |
| | | assertTrue("failed to delete label " + label.name, service.deleteLabel(getRepository(), label.name, "lucifer"));
|
| | | }
|
| | | }
|
| | |
|
| | |
|
| | |
|
| | | |
| | | @Test
|
| | | public void testPriorityAndSeverity() throws Exception {
|
| | | // C1: create and insert a ticket
|
| | | Change c1 = newChange("testPriorityAndSeverity() " + Long.toHexString(System.currentTimeMillis()));
|
| | | TicketModel ticket = service.createTicket(getRepository(), c1);
|
| | | assertTrue(ticket.number > 0);
|
| | | assertEquals(TicketModel.Priority.Normal, ticket.priority);
|
| | | assertEquals(TicketModel.Severity.Unrated, ticket.severity);
|
| | | |
| | | TicketModel constructed = service.getTicket(getRepository(), ticket.number);
|
| | | compare(ticket, constructed);
|
| | | |
| | | // C2: Change Priority max
|
| | | Change c2 = new Change("C2");
|
| | | c2.setField(Field.priority, TicketModel.Priority.Urgent);
|
| | | constructed = service.updateTicket(getRepository(), ticket.number, c2);
|
| | | assertNotNull(constructed);
|
| | | assertEquals(2, constructed.changes.size());
|
| | | assertEquals(TicketModel.Priority.Urgent, constructed.priority);
|
| | | assertEquals(TicketModel.Severity.Unrated, constructed.severity);
|
| | | |
| | | // C3: Change Severity max
|
| | | Change c3 = new Change("C3");
|
| | | c3.setField(Field.severity, TicketModel.Severity.Catastrophic);
|
| | | constructed = service.updateTicket(getRepository(), ticket.number, c3);
|
| | | assertNotNull(constructed);
|
| | | assertEquals(3, constructed.changes.size());
|
| | | assertEquals(TicketModel.Priority.Urgent, constructed.priority);
|
| | | assertEquals(TicketModel.Severity.Catastrophic, constructed.severity);
|
| | | |
| | | // C4: Change Priority min
|
| | | Change c4 = new Change("C3");
|
| | | c4.setField(Field.priority, TicketModel.Priority.Low);
|
| | | constructed = service.updateTicket(getRepository(), ticket.number, c4);
|
| | | assertNotNull(constructed);
|
| | | assertEquals(4, constructed.changes.size());
|
| | | assertEquals(TicketModel.Priority.Low, constructed.priority);
|
| | | assertEquals(TicketModel.Severity.Catastrophic, constructed.severity);
|
| | | }
|
| | | |
| | | private Change newChange(String summary) {
|
| | | Change change = new Change("C1");
|
| | | change.setField(Field.title, summary);
|
New file |
| | |
| | | /* |
| | | * Copyright 2014 gitblit.com. |
| | | * |
| | | * Licensed under the Apache License, Version 2.0 (the "License"); |
| | | * you may not use this file except in compliance with the License. |
| | | * You may obtain a copy of the License at |
| | | * |
| | | * http://www.apache.org/licenses/LICENSE-2.0 |
| | | * |
| | | * Unless required by applicable law or agreed to in writing, software |
| | | * distributed under the License is distributed on an "AS IS" BASIS, |
| | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| | | * See the License for the specific language governing permissions and |
| | | * limitations under the License. |
| | | */ |
| | | package com.gitblit.tests; |
| | | |
| | | import java.io.File; |
| | | import java.util.Date; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | import org.apache.commons.io.FileUtils; |
| | | import org.bouncycastle.util.Arrays; |
| | | import org.eclipse.jgit.lib.Repository; |
| | | import org.junit.After; |
| | | import org.junit.Before; |
| | | import org.junit.Test; |
| | | |
| | | import com.gitblit.IStoredSettings; |
| | | import com.gitblit.Keys; |
| | | import com.gitblit.manager.INotificationManager; |
| | | import com.gitblit.manager.IPluginManager; |
| | | import com.gitblit.manager.IRepositoryManager; |
| | | import com.gitblit.manager.IRuntimeManager; |
| | | import com.gitblit.manager.IUserManager; |
| | | import com.gitblit.manager.NotificationManager; |
| | | import com.gitblit.manager.PluginManager; |
| | | import com.gitblit.manager.RepositoryManager; |
| | | import com.gitblit.manager.RuntimeManager; |
| | | import com.gitblit.manager.UserManager; |
| | | import com.gitblit.models.Mailing; |
| | | import com.gitblit.models.RepositoryModel; |
| | | import com.gitblit.models.TicketModel; |
| | | import com.gitblit.models.TicketModel.Attachment; |
| | | import com.gitblit.models.TicketModel.Change; |
| | | import com.gitblit.models.TicketModel.Field; |
| | | import com.gitblit.models.TicketModel.Patchset; |
| | | import com.gitblit.models.TicketModel.Priority; |
| | | import com.gitblit.models.TicketModel.Severity; |
| | | import com.gitblit.models.TicketModel.Status; |
| | | import com.gitblit.models.TicketModel.Type; |
| | | import com.gitblit.tests.mock.MemorySettings; |
| | | import com.gitblit.tickets.ITicketService; |
| | | import com.gitblit.tickets.ITicketService.TicketFilter; |
| | | import com.gitblit.tickets.QueryResult; |
| | | import com.gitblit.tickets.TicketIndexer.Lucene; |
| | | import com.gitblit.tickets.BranchTicketService; |
| | | import com.gitblit.tickets.TicketLabel; |
| | | import com.gitblit.tickets.TicketMilestone; |
| | | import com.gitblit.tickets.TicketNotifier; |
| | | import com.gitblit.utils.JGitUtils; |
| | | import com.gitblit.utils.XssFilter; |
| | | import com.gitblit.utils.XssFilter.AllowXssFilter; |
| | | |
| | | /** |
| | | * Generates the range of tickets to ease testing of the look and feel of tickets |
| | | */ |
| | | public class UITicketTest extends GitblitUnitTest { |
| | | |
| | | private ITicketService service; |
| | | final String repoName = "UITicketTest.git"; |
| | | final RepositoryModel repo = new RepositoryModel(repoName, null, null, null); |
| | | |
| | | protected ITicketService getService(boolean deleteAll) throws Exception { |
| | | |
| | | IStoredSettings settings = getSettings(deleteAll); |
| | | XssFilter xssFilter = new AllowXssFilter(); |
| | | IRuntimeManager runtimeManager = new RuntimeManager(settings, xssFilter).start(); |
| | | IPluginManager pluginManager = new PluginManager(runtimeManager).start(); |
| | | INotificationManager notificationManager = new NotificationManager(settings).start(); |
| | | IUserManager userManager = new UserManager(runtimeManager, pluginManager).start(); |
| | | IRepositoryManager repositoryManager = new RepositoryManager(runtimeManager, pluginManager, userManager).start(); |
| | | |
| | | BranchTicketService service = new BranchTicketService( |
| | | runtimeManager, |
| | | pluginManager, |
| | | notificationManager, |
| | | userManager, |
| | | repositoryManager).start(); |
| | | |
| | | if (deleteAll) { |
| | | service.deleteAll(repo); |
| | | } |
| | | return service; |
| | | } |
| | | |
| | | protected IStoredSettings getSettings(boolean deleteAll) throws Exception { |
| | | File dir = new File(GitBlitSuite.REPOSITORIES, repoName); |
| | | if (deleteAll) { |
| | | FileUtils.deleteDirectory(dir); |
| | | JGitUtils.createRepository(GitBlitSuite.REPOSITORIES, repoName).close(); |
| | | } |
| | | |
| | | File luceneDir = new File(dir, "tickets/lucene"); |
| | | luceneDir.mkdirs(); |
| | | |
| | | Map<String, Object> map = new HashMap<String, Object>(); |
| | | map.put(Keys.git.repositoriesFolder, GitBlitSuite.REPOSITORIES.getAbsolutePath()); |
| | | map.put(Keys.tickets.indexFolder, luceneDir.getAbsolutePath()); |
| | | |
| | | IStoredSettings settings = new MemorySettings(map); |
| | | return settings; |
| | | } |
| | | |
| | | @Before |
| | | public void setup() throws Exception { |
| | | service = getService(true); |
| | | } |
| | | |
| | | @After |
| | | public void cleanup() { |
| | | service.stop(); |
| | | } |
| | | |
| | | @Test |
| | | public void UITicketOptions() throws Exception { |
| | | |
| | | for (TicketModel.Type t : TicketModel.Type.values()) |
| | | { |
| | | for (TicketModel.Priority p : TicketModel.Priority.values()) |
| | | { |
| | | for (TicketModel.Severity s : TicketModel.Severity.values()) |
| | | { |
| | | assertNotNull(service.createTicket(repo, newChange(t, p, s))); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | private Change newChange(Type type, Priority priority, Severity severity) { |
| | | Change change = new Change("JUnit"); |
| | | change.setField(Field.title, String.format("Type: %s | Priority: %s | Severity: %s", type, priority, severity)); |
| | | change.setField(Field.type, type); |
| | | change.setField(Field.severity, severity); |
| | | change.setField(Field.priority, priority); |
| | | return change; |
| | | } |
| | | |
| | | } |