diff --git a/readme.md b/readme.md index 7bec430a3c..0b06f40d20 100644 --- a/readme.md +++ b/readme.md @@ -60,7 +60,7 @@ files in certain branches. Move tasks manually in Kanban, or define rules to move them automatically when related work is committed/tested/released/deployed. -[**See It In Action**](https://code.onedev.io/onedev/server/~boards/State?milestone=4.2.0&backlog=true) +[**See It In Action**](https://code.onedev.io/onedev/server/~boards/State?iteration=4.2.0&backlog=true) ![issue board](./doc/images/issue-board.png) diff --git a/server-core/src/main/java/io/onedev/server/CoreModule.java b/server-core/src/main/java/io/onedev/server/CoreModule.java index 3bfbdf0d13..e5e4a57f00 100644 --- a/server-core/src/main/java/io/onedev/server/CoreModule.java +++ b/server-core/src/main/java/io/onedev/server/CoreModule.java @@ -253,7 +253,7 @@ public class CoreModule extends AbstractPluginModule { bind(IssueChangeManager.class).to(DefaultIssueChangeManager.class); bind(IssueVoteManager.class).to(DefaultIssueVoteManager.class); bind(IssueWorkManager.class).to(DefaultIssueWorkManager.class); - bind(MilestoneManager.class).to(DefaultMilestoneManager.class); + bind(IterationManager.class).to(DefaultIterationManager.class); bind(IssueCommentManager.class).to(DefaultIssueCommentManager.class); bind(IssueQueryPersonalizationManager.class).to(DefaultIssueQueryPersonalizationManager.class); bind(PullRequestQueryPersonalizationManager.class).to(DefaultPullRequestQueryPersonalizationManager.class); diff --git a/server-core/src/main/java/io/onedev/server/annotation/MilestoneChoice.java b/server-core/src/main/java/io/onedev/server/annotation/IterationChoice.java similarity index 89% rename from server-core/src/main/java/io/onedev/server/annotation/MilestoneChoice.java rename to server-core/src/main/java/io/onedev/server/annotation/IterationChoice.java index 21261c5b6c..227f69ddfc 100644 --- a/server-core/src/main/java/io/onedev/server/annotation/MilestoneChoice.java +++ b/server-core/src/main/java/io/onedev/server/annotation/IterationChoice.java @@ -7,6 +7,6 @@ import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) -public @interface MilestoneChoice { +public @interface IterationChoice { String value() default ""; } diff --git a/server-core/src/main/java/io/onedev/server/buildspec/BuildSpec.java b/server-core/src/main/java/io/onedev/server/buildspec/BuildSpec.java index 0eaa023c07..3ab66e3c72 100644 --- a/server-core/src/main/java/io/onedev/server/buildspec/BuildSpec.java +++ b/server-core/src/main/java/io/onedev/server/buildspec/BuildSpec.java @@ -2075,5 +2075,53 @@ public class BuildSpec implements Serializable, Validatable { } } }); - } + } + + private void migrateParamSpecs(VersionedYamlDoc doc, Stack versions, + Consumer paramSpecMigrator) { + for (NodeTuple specTuple: doc.getValue()) { + String specObjectKey = ((ScalarNode)specTuple.getKeyNode()).getValue(); + if (specObjectKey.equals("jobs")) { + SequenceNode jobsNode = (SequenceNode) specTuple.getValueNode(); + for (Node jobsNodeItem: jobsNode.getValue()) { + MappingNode jobNode = (MappingNode) jobsNodeItem; + for (NodeTuple jobTuple: jobNode.getValue()) { + String jobTupleKey = ((ScalarNode)jobTuple.getKeyNode()).getValue(); + if (jobTupleKey.equals("paramSpecs")) + paramSpecMigrator.accept((SequenceNode) jobTuple.getValueNode()); + } + } + } else if (specObjectKey.equals("stepTemplates")) { + SequenceNode stepTemplatesNode = (SequenceNode) specTuple.getValueNode(); + for (Node stepTemplatesNodeItem: stepTemplatesNode.getValue()) { + MappingNode stepTemplateNode = (MappingNode) stepTemplatesNodeItem; + for (NodeTuple stepTemplateTuple: stepTemplateNode.getValue()) { + String stepTemplateTupleKey = ((ScalarNode)stepTemplateTuple.getKeyNode()).getValue(); + if (stepTemplateTupleKey.equals("paramSpecs")) + paramSpecMigrator.accept((SequenceNode)stepTemplateTuple.getValueNode()); + } + } + } + } + } + + private void migrate34(VersionedYamlDoc doc, Stack versions) { + migrateSteps(doc, versions, stepsNode -> { + for (var itStepNode = stepsNode.getValue().iterator(); itStepNode.hasNext();) { + MappingNode stepNode = (MappingNode) itStepNode.next(); + var stepType = stepNode.getTag().getValue(); + if (stepType.equals("!CloseMilestoneStep")) + stepNode.setTag(new Tag("!CloseIterationStep")); + } + }); + migrateParamSpecs(doc, versions, paramSpecsNode -> { + for (var itParamSpecNode = paramSpecsNode.getValue().iterator(); itParamSpecNode.hasNext();) { + MappingNode paramSpecNode = (MappingNode) itParamSpecNode.next(); + var paramSpecType = paramSpecNode.getTag().getValue(); + if (paramSpecType.equals("!MilestoneChoiceParam")) + paramSpecNode.setTag(new Tag("!IterationChoiceParam")); + } + }); + } + } diff --git a/server-core/src/main/java/io/onedev/server/buildspec/param/spec/MilestoneChoiceParam.java b/server-core/src/main/java/io/onedev/server/buildspec/param/spec/IterationChoiceParam.java similarity index 57% rename from server-core/src/main/java/io/onedev/server/buildspec/param/spec/MilestoneChoiceParam.java rename to server-core/src/main/java/io/onedev/server/buildspec/param/spec/IterationChoiceParam.java index d1a6d75155..605f31c159 100644 --- a/server-core/src/main/java/io/onedev/server/buildspec/param/spec/MilestoneChoiceParam.java +++ b/server-core/src/main/java/io/onedev/server/buildspec/param/spec/IterationChoiceParam.java @@ -3,33 +3,33 @@ package io.onedev.server.buildspec.param.spec; import java.util.List; import java.util.Map; -import io.onedev.server.buildspecmodel.inputspec.MilestoneChoiceInput; +import io.onedev.server.buildspecmodel.inputspec.IterationChoiceInput; import io.onedev.server.annotation.Editable; -@Editable(order=1110, name=ParamSpec.MILESTONE) -public class MilestoneChoiceParam extends ParamSpec { +@Editable(order=1110, name=ParamSpec.ITERATION) +public class IterationChoiceParam extends ParamSpec { private static final long serialVersionUID = 1L; @Override public String getPropertyDef(Map indexes) { - return MilestoneChoiceInput.getPropertyDef(this, indexes); + return IterationChoiceInput.getPropertyDef(this, indexes); } @Override public Object convertToObject(List strings) { - return MilestoneChoiceInput.convertToObject(this, strings); + return IterationChoiceInput.convertToObject(this, strings); } @Override public List convertToStrings(Object value) { - return MilestoneChoiceInput.convertToStrings(this, value); + return IterationChoiceInput.convertToStrings(this, value); } @Override public long getOrdinal(String fieldValue) { if (fieldValue != null) - return MilestoneChoiceInput.getOrdinal(fieldValue); + return IterationChoiceInput.getOrdinal(fieldValue); else return super.getOrdinal(fieldValue); } diff --git a/server-core/src/main/java/io/onedev/server/buildspec/step/CloseMilestoneStep.java b/server-core/src/main/java/io/onedev/server/buildspec/step/CloseIterationStep.java similarity index 67% rename from server-core/src/main/java/io/onedev/server/buildspec/step/CloseMilestoneStep.java rename to server-core/src/main/java/io/onedev/server/buildspec/step/CloseIterationStep.java index 2d72776792..4ca4dba215 100644 --- a/server-core/src/main/java/io/onedev/server/buildspec/step/CloseMilestoneStep.java +++ b/server-core/src/main/java/io/onedev/server/buildspec/step/CloseIterationStep.java @@ -9,8 +9,8 @@ import io.onedev.server.annotation.Editable; import io.onedev.server.annotation.Interpolative; import io.onedev.server.buildspec.BuildSpec; import io.onedev.server.entitymanager.BuildManager; -import io.onedev.server.entitymanager.MilestoneManager; -import io.onedev.server.model.Milestone; +import io.onedev.server.entitymanager.IterationManager; +import io.onedev.server.model.Iteration; import io.onedev.server.model.Project; import io.onedev.server.persistence.TransactionManager; @@ -19,24 +19,24 @@ import java.io.File; import java.util.List; import java.util.stream.Collectors; -@Editable(name="Close Milestone", order=400) -public class CloseMilestoneStep extends ServerSideStep { +@Editable(name="Close Iteration", order=400) +public class CloseIterationStep extends ServerSideStep { private static final long serialVersionUID = 1L; - private String milestoneName; + private String iterationName; private String accessTokenSecret; - @Editable(order=1000, description="Specify name of the milestone") + @Editable(order=1000, description="Specify name of the iteration") @Interpolative(variableSuggester="suggestVariables") @NotEmpty - public String getMilestoneName() { - return milestoneName; + public String getIterationName() { + return iterationName; } - public void setMilestoneName(String milestoneName) { - this.milestoneName = milestoneName; + public void setIterationName(String iterationName) { + this.iterationName = iterationName; } @SuppressWarnings("unused") @@ -66,19 +66,19 @@ public class CloseMilestoneStep extends ServerSideStep { return OneDev.getInstance(TransactionManager.class).call(() -> { var build = OneDev.getInstance(BuildManager.class).load(buildId); Project project = build.getProject(); - String milestoneName = getMilestoneName(); - MilestoneManager milestoneManager = OneDev.getInstance(MilestoneManager.class); - Milestone milestone = milestoneManager.findInHierarchy(project, milestoneName); - if (milestone != null) { - if (build.canCloseMilestone(getAccessTokenSecret())) { - milestone.setClosed(true); - milestoneManager.createOrUpdate(milestone); + String iterationName = getIterationName(); + IterationManager iterationManager = OneDev.getInstance(IterationManager.class); + Iteration iteration = iterationManager.findInHierarchy(project, iterationName); + if (iteration != null) { + if (build.canCloseIteration(getAccessTokenSecret())) { + iteration.setClosed(true); + iterationManager.createOrUpdate(iteration); } else { - logger.error("This build is not authorized to close milestone '" + milestoneName + "'"); + logger.error("This build is not authorized to close iteration '" + iterationName + "'"); return new ServerStepResult(false); } } else { - logger.warning("Unable to find milestone '" + milestoneName + "' to close. Ignored."); + logger.warning("Unable to find iteration '" + iterationName + "' to close. Ignored."); } return new ServerStepResult(true); }); diff --git a/server-core/src/main/java/io/onedev/server/buildspecmodel/inputspec/InputSpec.java b/server-core/src/main/java/io/onedev/server/buildspecmodel/inputspec/InputSpec.java index a326f5c503..065ba798dc 100644 --- a/server-core/src/main/java/io/onedev/server/buildspecmodel/inputspec/InputSpec.java +++ b/server-core/src/main/java/io/onedev/server/buildspecmodel/inputspec/InputSpec.java @@ -54,7 +54,7 @@ public abstract class InputSpec implements Serializable { public static final String ISSUE = "Issue"; - public static final String MILESTONE = "Milestone"; + public static final String ITERATION = "Iteration"; public static final String BUILD = "Build"; diff --git a/server-core/src/main/java/io/onedev/server/buildspecmodel/inputspec/MilestoneChoiceInput.java b/server-core/src/main/java/io/onedev/server/buildspecmodel/inputspec/IterationChoiceInput.java similarity index 81% rename from server-core/src/main/java/io/onedev/server/buildspecmodel/inputspec/MilestoneChoiceInput.java rename to server-core/src/main/java/io/onedev/server/buildspecmodel/inputspec/IterationChoiceInput.java index d9f4635042..ecacd6526c 100644 --- a/server-core/src/main/java/io/onedev/server/buildspecmodel/inputspec/MilestoneChoiceInput.java +++ b/server-core/src/main/java/io/onedev/server/buildspecmodel/inputspec/IterationChoiceInput.java @@ -7,10 +7,10 @@ import java.util.Map; import javax.validation.ValidationException; import edu.emory.mathcs.backport.java.util.Collections; -import io.onedev.server.model.Milestone; +import io.onedev.server.model.Iteration; import io.onedev.server.model.Project; -public class MilestoneChoiceInput { +public class IterationChoiceInput { public static String getPropertyDef(InputSpec inputSpec, Map indexes) { int index = indexes.get(inputSpec.getName()); @@ -19,12 +19,12 @@ public class MilestoneChoiceInput { inputSpec.appendCommonAnnotations(buffer, index); if (!inputSpec.isAllowEmpty()) { if (inputSpec.isAllowMultiple()) - buffer.append(" @Size(min=1, message=\"At least one milestone needs to be selected\")\n"); + buffer.append(" @Size(min=1, message=\"At least one iteration needs to be selected\")\n"); else buffer.append(" @NotEmpty\n"); } - buffer.append(" @MilestoneChoice\n"); + buffer.append(" @IterationChoice\n"); if (inputSpec.isAllowMultiple()) inputSpec.appendMethods(buffer, index, "List", null, null); @@ -62,11 +62,11 @@ public class MilestoneChoiceInput { int ordinal = -1; Project project = Project.get(); if (project != null) { - List milestones = new ArrayList<>(project.getHierarchyMilestones()); - Collections.sort(milestones); - for (Milestone milestone: milestones) { + List iterations = new ArrayList<>(project.getHierarchyIterations()); + Collections.sort(iterations); + for (Iteration iteration: iterations) { ordinal++; - if (milestone.getName().equals(fieldValue)) + if (iteration.getName().equals(fieldValue)) break; } } diff --git a/server-core/src/main/java/io/onedev/server/data/migration/DataMigrator.java b/server-core/src/main/java/io/onedev/server/data/migration/DataMigrator.java index d7effc13d5..4a0cdf2833 100644 --- a/server-core/src/main/java/io/onedev/server/data/migration/DataMigrator.java +++ b/server-core/src/main/java/io/onedev/server/data/migration/DataMigrator.java @@ -6443,6 +6443,107 @@ public class DataMigrator { } } } + + private void migrate167(File dataDir, Stack versions) { + for (File file : dataDir.listFiles()) { + if (file.getName().startsWith("Milestones.xml")) { + File renamedFile = new File(dataDir, file.getName().replace("Milestones.xml", "Iterations.xml")); + try { + FileUtils.moveFile(file, renamedFile); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + for (File file : dataDir.listFiles()) { + if (file.getName().startsWith("Iterations.xml")) { + VersionedXmlDoc dom = VersionedXmlDoc.fromFile(file); + for (Element element : dom.getRootElement().elements()) + element.setName("io.onedev.server.model.Iteration"); + dom.writeToFile(file, false); + } else if (file.getName().startsWith("Settings.xml")) { + VersionedXmlDoc dom = VersionedXmlDoc.fromFile(file); + for (Element element : dom.getRootElement().elements()) { + String key = element.elementTextTrim("key"); + if (key.equals("ISSUE")) { + for (var fieldSpecElement: element.element("value").element("fieldSpecs").elements()) { + if (fieldSpecElement.getName().contains("MilestoneChoiceField")) + fieldSpecElement.setName("io.onedev.server.model.support.issue.field.spec.IterationChoiceField"); + } + } + } + dom.writeToFile(file, false); + } else if (file.getName().startsWith("IssueSchedules.xml")) { + VersionedXmlDoc dom = VersionedXmlDoc.fromFile(file); + for (Element element : dom.getRootElement().elements()) + element.element("milestone").setName("iteration"); + dom.writeToFile(file, false); + } else if (file.getName().startsWith("Dashboards.xml")) { + VersionedXmlDoc dom = VersionedXmlDoc.fromFile(file); + for (Node node : dom.selectNodes("//io.onedev.server.ee.dashboard.widgets.MilestoneListWidget")) { + if (node instanceof Element) { + Element element = (Element) node; + element.setName("io.onedev.server.ee.dashboard.widgets.IterationListWidget"); + } + } + for (Node node : dom.selectNodes("//io.onedev.server.ee.dashboard.widgets.BurnDownChartWidget")) { + if (node instanceof Element) { + Element element = (Element) node; + var milestoneNameElement = element.element("milestoneName"); + if (milestoneNameElement != null) + milestoneNameElement.setName("iterationName"); + } + } + dom.writeToFile(file, false); + } else if (file.getName().startsWith("IssueFields.xml")) { + VersionedXmlDoc dom = VersionedXmlDoc.fromFile(file); + for (Element element : dom.getRootElement().elements()) { + var typeElement = element.element("type"); + if (typeElement.getTextTrim().equals("Milestone")) + typeElement.setText("Iteration"); + } + dom.writeToFile(file, false); + } else if (file.getName().startsWith("IssueChanges.xml")) { + VersionedXmlDoc dom = VersionedXmlDoc.fromFile(file); + for (Element element : dom.getRootElement().elements()) { + var dataElement = element.element("data"); + if (dataElement.attributeValue("class").contains("IssueMilestoneAddData")) + dataElement.addAttribute("class", "io.onedev.server.model.support.issue.changedata.IssueIterationAddData"); + else if (dataElement.attributeValue("class").contains("IssueMilestoneRemoveData")) + dataElement.addAttribute("class", "io.onedev.server.model.support.issue.changedata.IssueIterationRemoveData"); + else if (dataElement.attributeValue("class").contains("IssueMilestoneChangeData")) + dataElement.addAttribute("class", "io.onedev.server.model.support.issue.changedata.IssueIterationChangeData"); + var milestoneElement = dataElement.element("milestone"); + if (milestoneElement != null) + milestoneElement.setName("iteration"); + var oldMilestonesElement = dataElement.element("oldMilestones"); + if (oldMilestonesElement != null) + oldMilestonesElement.setName("oldIterations"); + var newMilestonesElement = dataElement.element("newMilestones"); + if (newMilestonesElement != null) + newMilestonesElement.setName("newIterations"); + } + dom.writeToFile(file, false); + } + } + + for (File file : dataDir.listFiles()) { + try { + String content = FileUtils.readFileToString(file, UTF_8); + content = StringUtils.replace(content, + "\"Milestone\" is", "\"Iteration\" is"); + content = StringUtils.replace(content, + "\"Milestone\" is", "\"Iteration\" is"); + content = StringUtils.replace(content, + "\"Milestone\" is", "\"Iteration\" is"); + content = StringUtils.replace(content, + "\"Milestone\" is", "\"Iteration\" is"); + FileUtils.writeStringToFile(file, content, UTF_8); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } } \ No newline at end of file diff --git a/server-core/src/main/java/io/onedev/server/entitymanager/IssueChangeManager.java b/server-core/src/main/java/io/onedev/server/entitymanager/IssueChangeManager.java index a8baf5a89e..2377c986cd 100644 --- a/server-core/src/main/java/io/onedev/server/entitymanager/IssueChangeManager.java +++ b/server-core/src/main/java/io/onedev/server/entitymanager/IssueChangeManager.java @@ -3,7 +3,7 @@ package io.onedev.server.entitymanager; import io.onedev.server.model.Issue; import io.onedev.server.model.IssueChange; import io.onedev.server.model.LinkSpec; -import io.onedev.server.model.Milestone; +import io.onedev.server.model.Iteration; import io.onedev.server.persistence.dao.EntityManager; import javax.annotation.Nullable; @@ -36,19 +36,19 @@ public interface IssueChangeManager extends EntityManager { void changeFields(Issue issue, Map fieldValues); - void changeMilestones(Issue issue, Collection milestones); + void changeIterations(Issue issue, Collection iterations); void create(IssueChange change, @Nullable String note); - void addSchedule(Issue issue, Milestone milestone); + void addSchedule(Issue issue, Iteration iteration); - void removeSchedule(Issue issue, Milestone milestone); + void removeSchedule(Issue issue, Iteration iteration); void changeState(Issue issue, String state, Map fieldValues, Collection removeFields, @Nullable String comment); void batchUpdate(Iterator issues, @Nullable String state, @Nullable Boolean confidential, - @Nullable Collection milestone, Map fieldValues, @Nullable String comment); + @Nullable Collection iterations, Map fieldValues, @Nullable String comment); List queryAfter(Long projectId, Long afterChangeId, int count); diff --git a/server-core/src/main/java/io/onedev/server/entitymanager/IssueManager.java b/server-core/src/main/java/io/onedev/server/entitymanager/IssueManager.java index 7881af8498..011eeeb049 100644 --- a/server-core/src/main/java/io/onedev/server/entitymanager/IssueManager.java +++ b/server-core/src/main/java/io/onedev/server/entitymanager/IssueManager.java @@ -1,13 +1,13 @@ package io.onedev.server.entitymanager; import io.onedev.server.model.Issue; -import io.onedev.server.model.Milestone; +import io.onedev.server.model.Iteration; import io.onedev.server.model.Project; import io.onedev.server.persistence.dao.EntityManager; import io.onedev.server.search.entity.EntityQuery; import io.onedev.server.search.entity.EntitySort; import io.onedev.server.util.IssueTimes; -import io.onedev.server.util.MilestoneAndIssueState; +import io.onedev.server.util.IterationAndIssueState; import io.onedev.server.util.ProjectIssueStats; import io.onedev.server.util.ProjectScope; import io.onedev.server.util.criteria.Criteria; @@ -81,13 +81,13 @@ public interface IssueManager extends EntityManager { void delete(Collection issues, Project project); - Collection queryMilestoneAndIssueStates(Project project, Collection milestones); + Collection queryIterationAndIssueStates(Project project, Collection iterations); List queryStats(Collection projects); - Collection queryUsedMilestones(Project project); + Collection queryUsedIterations(Project project); - void clearSchedules(Project project, Collection milestones); + void clearSchedules(Project project, Collection iterations); List queryAfter(Long projectId, Long afterIssueId, int count); diff --git a/server-core/src/main/java/io/onedev/server/entitymanager/IssueScheduleManager.java b/server-core/src/main/java/io/onedev/server/entitymanager/IssueScheduleManager.java index 69c0ae6669..78d48aa808 100644 --- a/server-core/src/main/java/io/onedev/server/entitymanager/IssueScheduleManager.java +++ b/server-core/src/main/java/io/onedev/server/entitymanager/IssueScheduleManager.java @@ -4,12 +4,12 @@ import java.util.Collection; import io.onedev.server.model.Issue; import io.onedev.server.model.IssueSchedule; -import io.onedev.server.model.Milestone; +import io.onedev.server.model.Iteration; import io.onedev.server.persistence.dao.EntityManager; public interface IssueScheduleManager extends EntityManager { - void syncMilestones(Issue issue, Collection milestones); + void syncIterations(Issue issue, Collection iterations); void create(IssueSchedule schedule); } \ No newline at end of file diff --git a/server-core/src/main/java/io/onedev/server/entitymanager/IterationManager.java b/server-core/src/main/java/io/onedev/server/entitymanager/IterationManager.java new file mode 100644 index 0000000000..9fd1325f74 --- /dev/null +++ b/server-core/src/main/java/io/onedev/server/entitymanager/IterationManager.java @@ -0,0 +1,20 @@ +package io.onedev.server.entitymanager; + +import io.onedev.server.model.Iteration; +import io.onedev.server.model.Project; +import io.onedev.server.persistence.dao.EntityManager; + +import javax.annotation.Nullable; + +public interface IterationManager extends EntityManager { + + @Nullable + Iteration findInHierarchy(Project project, String name); + + void delete(Iteration iteration); + + Iteration findInHierarchy(String iterationFQN); + + void createOrUpdate(Iteration iteration); + +} \ No newline at end of file diff --git a/server-core/src/main/java/io/onedev/server/entitymanager/MilestoneManager.java b/server-core/src/main/java/io/onedev/server/entitymanager/MilestoneManager.java deleted file mode 100644 index 878f3dd8ae..0000000000 --- a/server-core/src/main/java/io/onedev/server/entitymanager/MilestoneManager.java +++ /dev/null @@ -1,20 +0,0 @@ -package io.onedev.server.entitymanager; - -import io.onedev.server.model.Milestone; -import io.onedev.server.model.Project; -import io.onedev.server.persistence.dao.EntityManager; - -import javax.annotation.Nullable; - -public interface MilestoneManager extends EntityManager { - - @Nullable - Milestone findInHierarchy(Project project, String name); - - void delete(Milestone milestone); - - Milestone findInHierarchy(String milestoneFQN); - - void createOrUpdate(Milestone milestone); - -} \ No newline at end of file diff --git a/server-core/src/main/java/io/onedev/server/entitymanager/impl/DefaultIssueChangeManager.java b/server-core/src/main/java/io/onedev/server/entitymanager/impl/DefaultIssueChangeManager.java index 5320b76d4f..960aa6ee43 100644 --- a/server-core/src/main/java/io/onedev/server/entitymanager/impl/DefaultIssueChangeManager.java +++ b/server-core/src/main/java/io/onedev/server/entitymanager/impl/DefaultIssueChangeManager.java @@ -243,25 +243,25 @@ public class DefaultIssueChangeManager extends BaseEntityManager @Transactional @Override - public void addSchedule(Issue issue, Milestone milestone) { - issueScheduleManager.create(issue.addSchedule(milestone)); + public void addSchedule(Issue issue, Iteration iteration) { + issueScheduleManager.create(issue.addSchedule(iteration)); IssueChange change = new IssueChange(); change.setIssue(issue); - change.setData(new IssueMilestoneAddData(milestone.getName())); + change.setData(new IssueIterationAddData(iteration.getName())); change.setUser(SecurityUtils.getUser()); create(change, null); } @Transactional @Override - public void removeSchedule(Issue issue, Milestone milestone) { - IssueSchedule schedule = issue.removeSchedule(milestone); + public void removeSchedule(Issue issue, Iteration iteration) { + IssueSchedule schedule = issue.removeSchedule(iteration); if (schedule != null) { issueScheduleManager.delete(schedule); IssueChange change = new IssueChange(); change.setIssue(issue); - change.setData(new IssueMilestoneRemoveData(milestone.getName())); + change.setData(new IssueIterationRemoveData(iteration.getName())); change.setUser(SecurityUtils.getUser()); create(change, null); } @@ -307,12 +307,12 @@ public class DefaultIssueChangeManager extends BaseEntityManager @Transactional @Override public void batchUpdate(Iterator issues, @Nullable String state, @Nullable Boolean confidential, - @Nullable Collection milestones, Map fieldValues, @Nullable String comment) { + @Nullable Collection iterations, Map fieldValues, @Nullable String comment) { while (issues.hasNext()) { Issue issue = issues.next(); String prevState = issue.getState(); boolean prevConfidential = issue.isConfidential(); - Collection prevMilestones = issue.getMilestones(); + Collection prevIterations = issue.getIterations(); Map prevFields = issue.getFieldInputs(); if (state != null) issue.setState(state); @@ -320,8 +320,8 @@ public class DefaultIssueChangeManager extends BaseEntityManager if (confidential != null) issue.setConfidential(confidential); - if (milestones != null) - issueScheduleManager.syncMilestones(issue, milestones); + if (iterations != null) + issueScheduleManager.syncIterations(issue, iterations); issue.setFieldValues(fieldValues); issueFieldManager.saveFields(issue); @@ -329,18 +329,18 @@ public class DefaultIssueChangeManager extends BaseEntityManager if (!prevState.equals(issue.getState()) || prevConfidential != issue.isConfidential() || !prevFields.equals(issue.getFieldInputs()) - || !new HashSet<>(prevMilestones).equals(new HashSet<>(issue.getMilestones()))) { + || !new HashSet<>(prevIterations).equals(new HashSet<>(issue.getIterations()))) { IssueChange change = new IssueChange(); change.setIssue(issue); change.setUser(SecurityUtils.getUser()); - List prevMilestoneList = new ArrayList<>(prevMilestones); - prevMilestoneList.sort(new Milestone.DatesAndStatusComparator()); - List currentMilestoneList = new ArrayList<>(issue.getMilestones()); - currentMilestoneList.sort(new Milestone.DatesAndStatusComparator()); + List prevIterationList = new ArrayList<>(prevIterations); + prevIterationList.sort(new Iteration.DatesAndStatusComparator()); + List currentIterationList = new ArrayList<>(issue.getIterations()); + currentIterationList.sort(new Iteration.DatesAndStatusComparator()); change.setData(new IssueBatchUpdateData(prevState, issue.getState(), - prevConfidential, issue.isConfidential(), prevMilestoneList, - currentMilestoneList, prevFields, issue.getFieldInputs())); + prevConfidential, issue.isConfidential(), prevIterationList, + currentIterationList, prevFields, issue.getFieldInputs())); create(change, comment); } } @@ -660,19 +660,19 @@ public class DefaultIssueChangeManager extends BaseEntityManager @Transactional @Override - public void changeMilestones(Issue issue, Collection milestones) { - Collection prevMilestones = new HashSet<>(issue.getMilestones()); - if (!prevMilestones.equals(new HashSet<>(milestones))) { - issueScheduleManager.syncMilestones(issue, milestones); + public void changeIterations(Issue issue, Collection iterations) { + Collection prevIterations = new HashSet<>(issue.getIterations()); + if (!prevIterations.equals(new HashSet<>(iterations))) { + issueScheduleManager.syncIterations(issue, iterations); IssueChange change = new IssueChange(); change.setIssue(issue); change.setUser(SecurityUtils.getUser()); - List prevMilestoneList = new ArrayList<>(prevMilestones); - prevMilestoneList.sort(new Milestone.DatesAndStatusComparator()); - List currentMilestoneList = new ArrayList<>(milestones); - currentMilestoneList.sort(new Milestone.DatesAndStatusComparator()); - change.setData(new IssueMilestoneChangeData(prevMilestoneList, currentMilestoneList)); + List prevIterationList = new ArrayList<>(prevIterations); + prevIterationList.sort(new Iteration.DatesAndStatusComparator()); + List currentIterationList = new ArrayList<>(iterations); + currentIterationList.sort(new Iteration.DatesAndStatusComparator()); + change.setData(new IssueIterationChangeData(prevIterationList, currentIterationList)); create(change, null); } diff --git a/server-core/src/main/java/io/onedev/server/entitymanager/impl/DefaultIssueManager.java b/server-core/src/main/java/io/onedev/server/entitymanager/impl/DefaultIssueManager.java index 7899f029da..76a47ea85a 100644 --- a/server-core/src/main/java/io/onedev/server/entitymanager/impl/DefaultIssueManager.java +++ b/server-core/src/main/java/io/onedev/server/entitymanager/impl/DefaultIssueManager.java @@ -39,7 +39,7 @@ import io.onedev.server.search.entity.issue.IssueQueryUpdater; import io.onedev.server.security.SecurityUtils; import io.onedev.server.security.permission.AccessProject; import io.onedev.server.util.IssueTimes; -import io.onedev.server.util.MilestoneAndIssueState; +import io.onedev.server.util.IterationAndIssueState; import io.onedev.server.util.ProjectIssueStats; import io.onedev.server.util.ProjectScope; import io.onedev.server.util.criteria.Criteria; @@ -885,33 +885,33 @@ public class DefaultIssueManager extends BaseEntityManager implements Iss @Sessional @Override - public Collection queryMilestoneAndIssueStates(Project project, Collection milestones) { + public Collection queryIterationAndIssueStates(Project project, Collection iterations) { CriteriaBuilder builder = getSession().getCriteriaBuilder(); - CriteriaQuery criteriaQuery = builder.createQuery(MilestoneAndIssueState.class); + CriteriaQuery criteriaQuery = builder.createQuery(IterationAndIssueState.class); Root root = criteriaQuery.from(IssueSchedule.class); Join issueJoin = root.join(IssueSchedule.PROP_ISSUE, JoinType.INNER); criteriaQuery.multiselect( - root.get(IssueSchedule.PROP_MILESTONE).get(Milestone.PROP_ID), + root.get(IssueSchedule.PROP_ITERATION).get(Iteration.PROP_ID), issueJoin.get(Issue.PROP_STATE)); - List milestonePredicates = new ArrayList<>(); - for (Milestone milestone: milestones) - milestonePredicates.add(builder.equal(root.get(IssueSchedule.PROP_MILESTONE), milestone)); + List iterationPredicates = new ArrayList<>(); + for (Iteration iteration: iterations) + iterationPredicates.add(builder.equal(root.get(IssueSchedule.PROP_ITERATION), iteration)); criteriaQuery.where(builder.and( buildSubtreePredicate(builder, issueJoin.get(Issue.PROP_PROJECT), project), - builder.or(milestonePredicates.toArray(new Predicate[0])))); + builder.or(iterationPredicates.toArray(new Predicate[0])))); return getSession().createQuery(criteriaQuery).getResultList(); } @Sessional @Override - public Collection queryUsedMilestones(Project project) { + public Collection queryUsedIterations(Project project) { CriteriaBuilder builder = getSession().getCriteriaBuilder(); - CriteriaQuery criteriaQuery = builder.createQuery(Milestone.class); + CriteriaQuery criteriaQuery = builder.createQuery(Iteration.class); Root root = criteriaQuery.from(IssueSchedule.class); - criteriaQuery.select(root.get(IssueSchedule.PROP_MILESTONE)); + criteriaQuery.select(root.get(IssueSchedule.PROP_ITERATION)); Path projectPath = root .join(IssueSchedule.PROP_ISSUE, JoinType.INNER) @@ -1044,8 +1044,8 @@ public class DefaultIssueManager extends BaseEntityManager implements Iss numberMapping.put(oldNumber, nextNumber); for (IssueSchedule schedule: issue.getSchedules()) { - if (schedule.getMilestone() != null - && !schedule.getMilestone().getProject().isSelfOrAncestorOf(targetProject)) { + if (schedule.getIteration() != null + && !schedule.getIteration().getProject().isSelfOrAncestorOf(targetProject)) { dao.remove(schedule); } } @@ -1086,21 +1086,21 @@ public class DefaultIssueManager extends BaseEntityManager implements Iss @Transactional @Override - public void clearSchedules(Project project, Collection milestones) { + public void clearSchedules(Project project, Collection iterations) { CriteriaBuilder builder = getSession().getCriteriaBuilder(); CriteriaQuery criteriaQuery = builder.createQuery(IssueSchedule.class); Root root = criteriaQuery.from(IssueSchedule.class); - List milestonePredicates = new ArrayList<>(); - for (Milestone milestone: milestones) - milestonePredicates.add(builder.equal(root.get(IssueSchedule.PROP_MILESTONE), milestone)); + List iterationPredicates = new ArrayList<>(); + for (Iteration iteration: iterations) + iterationPredicates.add(builder.equal(root.get(IssueSchedule.PROP_ITERATION), iteration)); Path projectPath = root .join(IssueSchedule.PROP_ISSUE, JoinType.INNER) .get(Issue.PROP_PROJECT); criteriaQuery.where(builder.and( buildSubtreePredicate(builder, projectPath, project), - builder.or(milestonePredicates.toArray(new Predicate[0])))); + builder.or(iterationPredicates.toArray(new Predicate[0])))); for (IssueSchedule schedule: getSession().createQuery(criteriaQuery).getResultList()) dao.remove(schedule); diff --git a/server-core/src/main/java/io/onedev/server/entitymanager/impl/DefaultIssueScheduleManager.java b/server-core/src/main/java/io/onedev/server/entitymanager/impl/DefaultIssueScheduleManager.java index 301e4a9699..fa79e22821 100644 --- a/server-core/src/main/java/io/onedev/server/entitymanager/impl/DefaultIssueScheduleManager.java +++ b/server-core/src/main/java/io/onedev/server/entitymanager/impl/DefaultIssueScheduleManager.java @@ -10,7 +10,7 @@ import com.google.common.base.Preconditions; import io.onedev.server.entitymanager.IssueScheduleManager; import io.onedev.server.model.Issue; import io.onedev.server.model.IssueSchedule; -import io.onedev.server.model.Milestone; +import io.onedev.server.model.Iteration; import io.onedev.server.persistence.annotation.Transactional; import io.onedev.server.persistence.dao.BaseEntityManager; import io.onedev.server.persistence.dao.Dao; @@ -26,19 +26,19 @@ public class DefaultIssueScheduleManager extends BaseEntityManager milestones) { + public void syncIterations(Issue issue, Collection iterations) { for (Iterator it = issue.getSchedules().iterator(); it.hasNext();) { IssueSchedule schedule = it.next(); - if (!milestones.contains(schedule.getMilestone())) { + if (!iterations.contains(schedule.getIteration())) { dao.remove(schedule); it.remove(); } } - for (Milestone milestone: milestones) { - if (!issue.getMilestones().contains(milestone)) { + for (Iteration iteration: iterations) { + if (!issue.getIterations().contains(iteration)) { IssueSchedule schedule = new IssueSchedule(); schedule.setIssue(issue); - schedule.setMilestone(milestone); + schedule.setIteration(iteration); issue.getSchedules().add(schedule); dao.persist(schedule); } diff --git a/server-core/src/main/java/io/onedev/server/entitymanager/impl/DefaultMilestoneManager.java b/server-core/src/main/java/io/onedev/server/entitymanager/impl/DefaultIterationManager.java similarity index 62% rename from server-core/src/main/java/io/onedev/server/entitymanager/impl/DefaultMilestoneManager.java rename to server-core/src/main/java/io/onedev/server/entitymanager/impl/DefaultIterationManager.java index c5f1e9e6e8..2957e940fb 100644 --- a/server-core/src/main/java/io/onedev/server/entitymanager/impl/DefaultMilestoneManager.java +++ b/server-core/src/main/java/io/onedev/server/entitymanager/impl/DefaultIterationManager.java @@ -1,9 +1,9 @@ package io.onedev.server.entitymanager.impl; import io.onedev.commons.utils.StringUtils; -import io.onedev.server.entitymanager.MilestoneManager; +import io.onedev.server.entitymanager.IterationManager; import io.onedev.server.entitymanager.ProjectManager; -import io.onedev.server.model.Milestone; +import io.onedev.server.model.Iteration; import io.onedev.server.model.Project; import io.onedev.server.persistence.annotation.Sessional; import io.onedev.server.persistence.annotation.Transactional; @@ -17,26 +17,26 @@ import javax.inject.Singleton; import java.util.List; @Singleton -public class DefaultMilestoneManager extends BaseEntityManager implements MilestoneManager { +public class DefaultIterationManager extends BaseEntityManager implements IterationManager { private final ProjectManager projectManager; @Inject - public DefaultMilestoneManager(Dao dao, ProjectManager projectManager) { + public DefaultIterationManager(Dao dao, ProjectManager projectManager) { super(dao); this.projectManager = projectManager; } @Sessional @Override - public Milestone findInHierarchy(String milestoneFQN) { - String projectName = StringUtils.substringBefore(milestoneFQN, ":"); + public Iteration findInHierarchy(String iterationFQN) { + String projectName = StringUtils.substringBefore(iterationFQN, ":"); Project project = projectManager.findByPath(projectName); if (project != null) { - String milestoneName = StringUtils.substringAfter(milestoneFQN, ":"); - EntityCriteria criteria = EntityCriteria.of(Milestone.class); + String iterationName = StringUtils.substringAfter(iterationFQN, ":"); + EntityCriteria criteria = EntityCriteria.of(Iteration.class); criteria.add(Restrictions.in("project", project.getSelfAndAncestors())); - criteria.add(Restrictions.eq("name", milestoneName)); + criteria.add(Restrictions.eq("name", iterationName)); criteria.setCacheable(true); return find(criteria); } else { @@ -46,8 +46,8 @@ public class DefaultMilestoneManager extends BaseEntityManager implem @Sessional @Override - public Milestone findInHierarchy(Project project, String name) { - EntityCriteria criteria = EntityCriteria.of(Milestone.class); + public Iteration findInHierarchy(Project project, String name) { + EntityCriteria criteria = EntityCriteria.of(Iteration.class); criteria.add(Restrictions.in("project", project.getSelfAndAncestors())); criteria.add(Restrictions.eq("name", name)); criteria.setCacheable(true); @@ -55,7 +55,7 @@ public class DefaultMilestoneManager extends BaseEntityManager implem } @Override - public List query() { + public List query() { return query(true); } @@ -66,8 +66,8 @@ public class DefaultMilestoneManager extends BaseEntityManager implem @Transactional @Override - public void createOrUpdate(Milestone milestone) { - dao.persist(milestone); + public void createOrUpdate(Iteration iteration) { + dao.persist(iteration); } } diff --git a/server-core/src/main/java/io/onedev/server/entitymanager/impl/DefaultProjectManager.java b/server-core/src/main/java/io/onedev/server/entitymanager/impl/DefaultProjectManager.java index 945080702e..62d1a57db4 100644 --- a/server-core/src/main/java/io/onedev/server/entitymanager/impl/DefaultProjectManager.java +++ b/server-core/src/main/java/io/onedev/server/entitymanager/impl/DefaultProjectManager.java @@ -268,14 +268,14 @@ public class DefaultProjectManager extends BaseEntityManager } dao.persist(project); if (oldPath != null && !oldPath.equals(project.getPath())) { - Collection milestones = new ArrayList<>(); - for (Milestone milestone : issueManager.queryUsedMilestones(project)) { - if (!project.isSelfOrAncestorOf(milestone.getProject()) - && !milestone.getProject().isSelfOrAncestorOf(project)) { - milestones.add(milestone); + Collection iterations = new ArrayList<>(); + for (Iteration iteration : issueManager.queryUsedIterations(project)) { + if (!project.isSelfOrAncestorOf(iteration.getProject()) + && !iteration.getProject().isSelfOrAncestorOf(project)) { + iterations.add(iteration); } } - issueManager.clearSchedules(project, milestones); + issueManager.clearSchedules(project, iterations); settingManager.onMoveProject(oldPath, project.getPath()); for (LinkSpec link : linkSpecManager.query()) { diff --git a/server-core/src/main/java/io/onedev/server/model/Build.java b/server-core/src/main/java/io/onedev/server/model/Build.java index 50d9bb3c26..6cd6ef5b3c 100644 --- a/server-core/src/main/java/io/onedev/server/model/Build.java +++ b/server-core/src/main/java/io/onedev/server/model/Build.java @@ -945,7 +945,7 @@ public class Build extends ProjectBelonging return accessToken; } - public boolean canCloseMilestone(@Nullable String accessTokenSecret) { + public boolean canCloseIteration(@Nullable String accessTokenSecret) { var project = getProject(); return project.isCommitOnBranch(getCommitId(), project.getDefaultBranch()) || accessTokenSecret != null && SecurityUtils.canManageIssues(getAccessToken(accessTokenSecret).asSubject(), project); diff --git a/server-core/src/main/java/io/onedev/server/model/Issue.java b/server-core/src/main/java/io/onedev/server/model/Issue.java index 2f0f426f26..dbe34043e6 100644 --- a/server-core/src/main/java/io/onedev/server/model/Issue.java +++ b/server-core/src/main/java/io/onedev/server/model/Issue.java @@ -29,7 +29,7 @@ import io.onedev.server.util.ProjectScopedCommit; import io.onedev.server.util.facade.IssueFacade; import io.onedev.server.web.UrlManager; import io.onedev.server.web.asset.emoji.Emojis; -import io.onedev.server.web.component.milestone.burndown.BurndownIndicators; +import io.onedev.server.web.component.iteration.burndown.BurndownIndicators; import io.onedev.server.web.editable.BeanDescriptor; import io.onedev.server.web.editable.PropertyDescriptor; import io.onedev.server.web.util.IssueAware; @@ -52,7 +52,7 @@ import java.util.stream.Collectors; import static io.onedev.server.model.AbstractEntity.PROP_NUMBER; import static io.onedev.server.model.Issue.*; -import static io.onedev.server.model.IssueSchedule.NAME_MILESTONE; +import static io.onedev.server.model.IssueSchedule.NAME_ITERATION; import static java.util.Comparator.comparing; import static java.util.Comparator.comparingInt; @@ -153,7 +153,7 @@ public class Issue extends ProjectBelonging implements AttachmentStorageSupport public static final Set ALL_FIELDS = Sets.newHashSet( NAME_PROJECT, NAME_NUMBER, NAME_STATE, NAME_TITLE, NAME_SUBMITTER, NAME_DESCRIPTION, NAME_COMMENT, NAME_SUBMIT_DATE, NAME_LAST_ACTIVITY_DATE, - NAME_VOTE_COUNT, NAME_COMMENT_COUNT, NAME_MILESTONE, + NAME_VOTE_COUNT, NAME_COMMENT_COUNT, NAME_ITERATION, NAME_ESTIMATED_TIME, NAME_SPENT_TIME, NAME_PROGRESS, BurndownIndicators.ISSUE_COUNT, BurndownIndicators.REMAINING_TIME); @@ -161,7 +161,7 @@ public class Issue extends ProjectBelonging implements AttachmentStorageSupport NAME_PROJECT, NAME_NUMBER, NAME_STATE, NAME_TITLE, NAME_DESCRIPTION, NAME_ESTIMATED_TIME, NAME_SPENT_TIME, NAME_PROGRESS, NAME_COMMENT, NAME_SUBMIT_DATE, NAME_LAST_ACTIVITY_DATE, NAME_VOTE_COUNT, - NAME_COMMENT_COUNT, NAME_MILESTONE); + NAME_COMMENT_COUNT, NAME_ITERATION); public static final Map> ORDER_FIELDS = new LinkedHashMap<>(); @@ -924,23 +924,23 @@ public class Issue extends ProjectBelonging implements AttachmentStorageSupport return OneDev.getInstance(UrlManager.class).urlFor(this); } - public Collection getMilestones() { - return getSchedules().stream().map(it->it.getMilestone()).collect(Collectors.toList()); + public Collection getIterations() { + return getSchedules().stream().map(it->it.getIteration()).collect(Collectors.toList()); } - public IssueSchedule addSchedule(Milestone milestone) { + public IssueSchedule addSchedule(Iteration iteration) { IssueSchedule schedule = new IssueSchedule(); schedule.setIssue(this); - schedule.setMilestone(milestone); + schedule.setIteration(iteration); getSchedules().add(schedule); return schedule; } @Nullable - public IssueSchedule removeSchedule(Milestone milestone) { + public IssueSchedule removeSchedule(Iteration iteration) { for (Iterator it = getSchedules().iterator(); it.hasNext();) { IssueSchedule schedule = it.next(); - if (schedule.getMilestone().equals(milestone)) { + if (schedule.getIteration().equals(iteration)) { it.remove(); return schedule; } diff --git a/server-core/src/main/java/io/onedev/server/model/IssueSchedule.java b/server-core/src/main/java/io/onedev/server/model/IssueSchedule.java index 8726b25023..500a41fcd7 100644 --- a/server-core/src/main/java/io/onedev/server/model/IssueSchedule.java +++ b/server-core/src/main/java/io/onedev/server/model/IssueSchedule.java @@ -15,8 +15,8 @@ import org.hibernate.annotations.CacheConcurrencyStrategy; @Entity @Table( - indexes={@Index(columnList="o_issue_id"), @Index(columnList="o_milestone_id")}, - uniqueConstraints={@UniqueConstraint(columnNames={"o_issue_id", "o_milestone_id"}) + indexes={@Index(columnList="o_issue_id"), @Index(columnList="o_iteration_id")}, + uniqueConstraints={@UniqueConstraint(columnNames={"o_issue_id", "o_iteration_id"}) }) @Cache(usage=CacheConcurrencyStrategy.READ_WRITE) public class IssueSchedule extends AbstractEntity { @@ -25,9 +25,9 @@ public class IssueSchedule extends AbstractEntity { public static String PROP_ISSUE = "issue"; - public static String NAME_MILESTONE = "Milestone"; + public static String NAME_ITERATION = "Iteration"; - public static String PROP_MILESTONE = "milestone"; + public static String PROP_ITERATION = "iteration"; public static String PROP_DATE = "date"; @@ -37,7 +37,7 @@ public class IssueSchedule extends AbstractEntity { @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(nullable=false) - private Milestone milestone; + private Iteration iteration; private Date date = new Date(); @@ -49,12 +49,12 @@ public class IssueSchedule extends AbstractEntity { this.issue = issue; } - public Milestone getMilestone() { - return milestone; + public Iteration getIteration() { + return iteration; } - public void setMilestone(Milestone milestone) { - this.milestone = milestone; + public void setIteration(Iteration iteration) { + this.iteration = iteration; } public Date getDate() { diff --git a/server-core/src/main/java/io/onedev/server/model/Milestone.java b/server-core/src/main/java/io/onedev/server/model/Iteration.java similarity index 92% rename from server-core/src/main/java/io/onedev/server/model/Milestone.java rename to server-core/src/main/java/io/onedev/server/model/Iteration.java index 5e1cebea57..7c3fa58b31 100644 --- a/server-core/src/main/java/io/onedev/server/model/Milestone.java +++ b/server-core/src/main/java/io/onedev/server/model/Iteration.java @@ -12,10 +12,10 @@ import java.util.*; @Entity @Table( indexes={@Index(columnList="o_project_id")}, - uniqueConstraints={@UniqueConstraint(columnNames={"o_project_id", Milestone.PROP_NAME})} + uniqueConstraints={@UniqueConstraint(columnNames={"o_project_id", Iteration.PROP_NAME})} ) @Cache(usage=CacheConcurrencyStrategy.READ_WRITE) -public class Milestone extends AbstractEntity { +public class Iteration extends AbstractEntity { private static final long serialVersionUID = 1L; @@ -48,7 +48,7 @@ public class Milestone extends AbstractEntity { private boolean closed; - @OneToMany(mappedBy="milestone", cascade=CascadeType.REMOVE) + @OneToMany(mappedBy= "iteration", cascade=CascadeType.REMOVE) private Collection schedules = new ArrayList<>(); public Project getProject() { @@ -131,7 +131,7 @@ public class Milestone extends AbstractEntity { public static class DatesAndStatusComparator extends DatesComparator { @Override - public int compare(Milestone o1, Milestone o2) { + public int compare(Iteration o1, Iteration o2) { if (o1.isClosed()) { if (o2.isClosed()) return super.compare(o1, o2) * -1; @@ -146,10 +146,10 @@ public class Milestone extends AbstractEntity { } - public static class DatesComparator implements Comparator { + public static class DatesComparator implements Comparator { @Override - public int compare(Milestone o1, Milestone o2) { + public int compare(Iteration o1, Iteration o2) { if (o1.getStartDate() != null) { if (o2.getStartDate() != null) return o1.getStartDate().compareTo(o2.getStartDate()); diff --git a/server-core/src/main/java/io/onedev/server/model/Project.java b/server-core/src/main/java/io/onedev/server/model/Project.java index 3e43d5e09f..53e8260c80 100644 --- a/server-core/src/main/java/io/onedev/server/model/Project.java +++ b/server-core/src/main/java/io/onedev/server/model/Project.java @@ -326,7 +326,7 @@ public class Project extends AbstractEntity implements LabelSupport milestones = new ArrayList<>(); + private Collection iterations = new ArrayList<>(); private boolean codeManagement = true; @@ -411,7 +411,7 @@ public class Project extends AbstractEntity implements LabelSupport commitQueryPersonalizationOfCurrentUserHolder; - private transient List sortedHierarchyMilestones; + private transient List sortedHierarchyIterations; private transient Optional activeServer; @@ -1283,27 +1283,27 @@ public class Project extends AbstractEntity implements LabelSupport getMilestones() { - return milestones; + public Collection getIterations() { + return iterations; } - public Collection getHierarchyMilestones() { - Collection milestones = new ArrayList<>(getMilestones()); + public Collection getHierarchyIterations() { + Collection iterations = new ArrayList<>(getIterations()); if (getParent() != null) - milestones.addAll(getParent().getHierarchyMilestones()); - return milestones; + iterations.addAll(getParent().getHierarchyIterations()); + return iterations; } - public void setMilestones(Collection milestones) { - this.milestones = milestones; + public void setIterations(Collection iterations) { + this.iterations = iterations; } - public List getSortedHierarchyMilestones() { - if (sortedHierarchyMilestones == null) { - sortedHierarchyMilestones = new ArrayList<>(getHierarchyMilestones()); - sortedHierarchyMilestones.sort(new Milestone.DatesAndStatusComparator()); + public List getSortedHierarchyIterations() { + if (sortedHierarchyIterations == null) { + sortedHierarchyIterations = new ArrayList<>(getHierarchyIterations()); + sortedHierarchyIterations.sort(new Iteration.DatesAndStatusComparator()); } - return sortedHierarchyMilestones; + return sortedHierarchyIterations; } @Editable @@ -1494,19 +1494,19 @@ public class Project extends AbstractEntity implements LabelSupport undefinedFields = new HashSet<>(); for (String fieldName: getListFields()) { if (!fieldName.equals(Issue.NAME_STATE) - && !fieldName.equals(IssueSchedule.NAME_MILESTONE) + && !fieldName.equals(IssueSchedule.NAME_ITERATION) && getFieldSpec(fieldName) == null) { undefinedFields.add(fieldName); } diff --git a/server-core/src/main/java/io/onedev/server/model/support/issue/BoardSpec.java b/server-core/src/main/java/io/onedev/server/model/support/issue/BoardSpec.java index 48a02fcdd7..40bd33be38 100644 --- a/server-core/src/main/java/io/onedev/server/model/support/issue/BoardSpec.java +++ b/server-core/src/main/java/io/onedev/server/model/support/issue/BoardSpec.java @@ -61,9 +61,9 @@ public class BoardSpec implements Serializable { private List columns = new ArrayList<>(); - private String milestonePrefix; + private String iterationPrefix; - private List displayFields = Lists.newArrayList(Issue.NAME_STATE, IssueSchedule.NAME_MILESTONE); + private List displayFields = Lists.newArrayList(Issue.NAME_STATE, IssueSchedule.NAME_ITERATION); private List displayLinks = new ArrayList<>(); @@ -92,7 +92,7 @@ public class BoardSpec implements Serializable { } @Editable(order=250, placeholder="Not specified", description="Optionally specify a base query to filter/order issues in backlog. " - + "Backlog issues are those not associating with current milestone") + + "Backlog issues are those not associating with current iteration") @IssueQuery(withCurrentUserCriteria = true, withCurrentProjectCriteria = true, withOrder = false) @Nullable public String getBacklogBaseQuery() { @@ -152,15 +152,13 @@ public class BoardSpec implements Serializable { return displayColumns; } - @Editable(order=450, description = "" + - "If specified, OneDev will only display milestones with this prefix, and the prefix will be stripped " + - "for brevity. Also milestones created from this board will get this prefix automatically") - public String getMilestonePrefix() { - return milestonePrefix; + @Editable(order=450, description = "If specified, OneDev will only display iterations with this prefix") + public String getIterationPrefix() { + return iterationPrefix; } - public void setMilestonePrefix(String milestonePrefix) { - this.milestonePrefix = milestonePrefix; + public void setIterationPrefix(String iterationPrefix) { + this.iterationPrefix = iterationPrefix; } @Editable(order=500, placeholder="Not displaying any fields", description="Specify fields to display in board card") @@ -213,7 +211,7 @@ public class BoardSpec implements Serializable { for (FieldSpec fieldSpec: getIssueSetting().getFieldSpecs()) { choices.add(fieldSpec.getName()); } - choices.add(IssueSchedule.NAME_MILESTONE); + choices.add(IssueSchedule.NAME_ITERATION); return choices; } @@ -282,7 +280,7 @@ public class BoardSpec implements Serializable { undefinedFields.add(getIdentifyField()); } for (String displayField: getDisplayFields()) { - if (!Issue.NAME_STATE.equals(displayField) && !IssueSchedule.NAME_MILESTONE.equals(displayField)) { + if (!Issue.NAME_STATE.equals(displayField) && !IssueSchedule.NAME_ITERATION.equals(displayField)) { FieldSpec fieldSpec = getIssueSetting().getFieldSpec(displayField); if (fieldSpec == null) undefinedFields.add(displayField); diff --git a/server-core/src/main/java/io/onedev/server/model/support/issue/ProjectIssueSetting.java b/server-core/src/main/java/io/onedev/server/model/support/issue/ProjectIssueSetting.java index ee4abbed63..efd47fa14e 100644 --- a/server-core/src/main/java/io/onedev/server/model/support/issue/ProjectIssueSetting.java +++ b/server-core/src/main/java/io/onedev/server/model/support/issue/ProjectIssueSetting.java @@ -150,7 +150,7 @@ public class ProjectIssueSetting implements Serializable { if (listFields != null) { for (String fieldName: listFields) { if (!fieldName.equals(Issue.NAME_STATE) - && !fieldName.equals(IssueSchedule.NAME_MILESTONE) + && !fieldName.equals(IssueSchedule.NAME_ITERATION) && getGlobalSetting().getFieldSpec(fieldName) == null) { undefinedFields.add(fieldName); } diff --git a/server-core/src/main/java/io/onedev/server/model/support/issue/changedata/IssueBatchUpdateData.java b/server-core/src/main/java/io/onedev/server/model/support/issue/changedata/IssueBatchUpdateData.java index 80b6b7dae0..3b61c3eb99 100644 --- a/server-core/src/main/java/io/onedev/server/model/support/issue/changedata/IssueBatchUpdateData.java +++ b/server-core/src/main/java/io/onedev/server/model/support/issue/changedata/IssueBatchUpdateData.java @@ -6,7 +6,7 @@ import java.util.Map; import java.util.stream.Collectors; import io.onedev.commons.utils.StringUtils; -import io.onedev.server.model.Milestone; +import io.onedev.server.model.Iteration; import io.onedev.server.util.Input; public class IssueBatchUpdateData extends IssueFieldChangeData { @@ -21,21 +21,21 @@ public class IssueBatchUpdateData extends IssueFieldChangeData { private final boolean newConfidential; - private final List oldMilestones; + private final List oldIterations; - private final List newMilestones; + private final List newIterations; - public IssueBatchUpdateData(String oldState, String newState, - boolean oldConfidential, boolean newConfidential, - List oldMilestones, List newMilestones, - Map oldFields, Map newFields) { + public IssueBatchUpdateData(String oldState, String newState, + boolean oldConfidential, boolean newConfidential, + List oldIterations, List newIterations, + Map oldFields, Map newFields) { super(oldFields, newFields); this.oldState = oldState; this.newState = newState; this.oldConfidential = oldConfidential; this.newConfidential = newConfidential; - this.oldMilestones = oldMilestones.stream().map(it->it.getName()).collect(Collectors.toList()); - this.newMilestones = newMilestones.stream().map(it->it.getName()).collect(Collectors.toList()); + this.oldIterations = oldIterations.stream().map(it->it.getName()).collect(Collectors.toList()); + this.newIterations = newIterations.stream().map(it->it.getName()).collect(Collectors.toList()); } @Override @@ -43,8 +43,8 @@ public class IssueBatchUpdateData extends IssueFieldChangeData { Map oldFieldValues = new LinkedHashMap<>(); oldFieldValues.put("State", oldState); oldFieldValues.put("Confidential", String.valueOf(oldConfidential)); - if (!oldMilestones.isEmpty()) - oldFieldValues.put("Milestones", StringUtils.join(oldMilestones)); + if (!oldIterations.isEmpty()) + oldFieldValues.put("Iterations", StringUtils.join(oldIterations)); oldFieldValues.putAll(super.getOldFieldValues()); return oldFieldValues; } @@ -54,8 +54,8 @@ public class IssueBatchUpdateData extends IssueFieldChangeData { Map newFieldValues = new LinkedHashMap<>(); newFieldValues.put("State", newState); newFieldValues.put("Confidential", String.valueOf(newConfidential)); - if (!newMilestones.isEmpty()) - newFieldValues.put("Milestones", StringUtils.join(newMilestones)); + if (!newIterations.isEmpty()) + newFieldValues.put("Iterations", StringUtils.join(newIterations)); newFieldValues.putAll(super.getNewFieldValues()); return newFieldValues; } @@ -76,12 +76,12 @@ public class IssueBatchUpdateData extends IssueFieldChangeData { return newConfidential; } - public List getOldMilestones() { - return oldMilestones; + public List getOldIterations() { + return oldIterations; } - public List getNewMilestones() { - return newMilestones; + public List getNewIterations() { + return newIterations; } @Override diff --git a/server-core/src/main/java/io/onedev/server/model/support/issue/changedata/IssueMilestoneAddData.java b/server-core/src/main/java/io/onedev/server/model/support/issue/changedata/IssueIterationAddData.java similarity index 71% rename from server-core/src/main/java/io/onedev/server/model/support/issue/changedata/IssueMilestoneAddData.java rename to server-core/src/main/java/io/onedev/server/model/support/issue/changedata/IssueIterationAddData.java index 4824d3531f..e9d6856460 100644 --- a/server-core/src/main/java/io/onedev/server/model/support/issue/changedata/IssueMilestoneAddData.java +++ b/server-core/src/main/java/io/onedev/server/model/support/issue/changedata/IssueIterationAddData.java @@ -7,19 +7,19 @@ import java.util.Map; import io.onedev.server.model.Group; import io.onedev.server.model.User; -public class IssueMilestoneAddData extends IssueChangeData { +public class IssueIterationAddData extends IssueChangeData { private static final long serialVersionUID = 1L; - private final String milestone; + private final String iteration; - public IssueMilestoneAddData(String milestone) { - this.milestone = milestone; + public IssueIterationAddData(String iteration) { + this.iteration = iteration; } @Override public String getActivity() { - return "added to milestone \"" + milestone + "\""; + return "added to iteration \"" + iteration + "\""; } @Override diff --git a/server-core/src/main/java/io/onedev/server/model/support/issue/changedata/IssueMilestoneChangeData.java b/server-core/src/main/java/io/onedev/server/model/support/issue/changedata/IssueIterationChangeData.java similarity index 59% rename from server-core/src/main/java/io/onedev/server/model/support/issue/changedata/IssueMilestoneChangeData.java rename to server-core/src/main/java/io/onedev/server/model/support/issue/changedata/IssueIterationChangeData.java index 74a1c002a0..01d2d684ae 100644 --- a/server-core/src/main/java/io/onedev/server/model/support/issue/changedata/IssueMilestoneChangeData.java +++ b/server-core/src/main/java/io/onedev/server/model/support/issue/changedata/IssueIterationChangeData.java @@ -8,34 +8,34 @@ import java.util.stream.Collectors; import io.onedev.commons.utils.StringUtils; import io.onedev.server.model.Group; -import io.onedev.server.model.Milestone; +import io.onedev.server.model.Iteration; import io.onedev.server.model.User; import io.onedev.server.notification.ActivityDetail; -public class IssueMilestoneChangeData extends IssueChangeData { +public class IssueIterationChangeData extends IssueChangeData { private static final long serialVersionUID = 1L; - private final List oldMilestones; + private final List oldIterations; - private final List newMilestones; + private final List newIterations; - public IssueMilestoneChangeData(List oldMilestones, List newMilestones) { - this.oldMilestones = oldMilestones.stream().map(it->it.getName()).collect(Collectors.toList()); - this.newMilestones = newMilestones.stream().map(it->it.getName()).collect(Collectors.toList()); + public IssueIterationChangeData(List oldIterations, List newIterations) { + this.oldIterations = oldIterations.stream().map(it->it.getName()).collect(Collectors.toList()); + this.newIterations = newIterations.stream().map(it->it.getName()).collect(Collectors.toList()); } - public List getOldMilestones() { - return oldMilestones; + public List getOldIterations() { + return oldIterations; } - public List getNewMilestones() { - return newMilestones; + public List getNewIterations() { + return newIterations; } @Override public String getActivity() { - return "changed milestones"; + return "changed iterations"; } @Override @@ -56,9 +56,9 @@ public class IssueMilestoneChangeData extends IssueChangeData { @Override public ActivityDetail getActivityDetail() { Map oldFieldValues = new HashMap<>(); - oldFieldValues.put("Milestones", StringUtils.join(oldMilestones)); + oldFieldValues.put("Iterations", StringUtils.join(oldIterations)); Map newFieldValues = new HashMap<>(); - newFieldValues.put("Milestones", StringUtils.join(newMilestones)); + newFieldValues.put("Iterations", StringUtils.join(newIterations)); return ActivityDetail.compare(oldFieldValues, newFieldValues, true); } diff --git a/server-core/src/main/java/io/onedev/server/model/support/issue/changedata/IssueMilestoneRemoveData.java b/server-core/src/main/java/io/onedev/server/model/support/issue/changedata/IssueIterationRemoveData.java similarity index 70% rename from server-core/src/main/java/io/onedev/server/model/support/issue/changedata/IssueMilestoneRemoveData.java rename to server-core/src/main/java/io/onedev/server/model/support/issue/changedata/IssueIterationRemoveData.java index 5013e36d3c..9f9784b6d7 100644 --- a/server-core/src/main/java/io/onedev/server/model/support/issue/changedata/IssueMilestoneRemoveData.java +++ b/server-core/src/main/java/io/onedev/server/model/support/issue/changedata/IssueIterationRemoveData.java @@ -7,19 +7,19 @@ import java.util.Map; import io.onedev.server.model.Group; import io.onedev.server.model.User; -public class IssueMilestoneRemoveData extends IssueChangeData { +public class IssueIterationRemoveData extends IssueChangeData { private static final long serialVersionUID = 1L; - private final String milestone; + private final String iteration; - public IssueMilestoneRemoveData(String milestone) { - this.milestone = milestone; + public IssueIterationRemoveData(String iteration) { + this.iteration = iteration; } @Override public String getActivity() { - return "removed from milestone \"" + milestone + "\""; + return "removed from iteration \"" + iteration + "\""; } @Override diff --git a/server-core/src/main/java/io/onedev/server/model/support/issue/field/spec/MilestoneChoiceField.java b/server-core/src/main/java/io/onedev/server/model/support/issue/field/spec/IterationChoiceField.java similarity index 59% rename from server-core/src/main/java/io/onedev/server/model/support/issue/field/spec/MilestoneChoiceField.java rename to server-core/src/main/java/io/onedev/server/model/support/issue/field/spec/IterationChoiceField.java index ba9c610216..2f5d707e8b 100644 --- a/server-core/src/main/java/io/onedev/server/model/support/issue/field/spec/MilestoneChoiceField.java +++ b/server-core/src/main/java/io/onedev/server/model/support/issue/field/spec/IterationChoiceField.java @@ -3,33 +3,33 @@ package io.onedev.server.model.support.issue.field.spec; import java.util.List; import java.util.Map; -import io.onedev.server.buildspecmodel.inputspec.MilestoneChoiceInput; +import io.onedev.server.buildspecmodel.inputspec.IterationChoiceInput; import io.onedev.server.annotation.Editable; -@Editable(order=1110, name=FieldSpec.MILESTONE) -public class MilestoneChoiceField extends FieldSpec { +@Editable(order=1110, name=FieldSpec.ITERATION) +public class IterationChoiceField extends FieldSpec { private static final long serialVersionUID = 1L; @Override public String getPropertyDef(Map indexes) { - return MilestoneChoiceInput.getPropertyDef(this, indexes); + return IterationChoiceInput.getPropertyDef(this, indexes); } @Override public Object convertToObject(List strings) { - return MilestoneChoiceInput.convertToObject(this, strings); + return IterationChoiceInput.convertToObject(this, strings); } @Override public List convertToStrings(Object value) { - return MilestoneChoiceInput.convertToStrings(this, value); + return IterationChoiceInput.convertToStrings(this, value); } @Override public long getOrdinal(String fieldValue) { if (fieldValue != null) - return MilestoneChoiceInput.getOrdinal(fieldValue); + return IterationChoiceInput.getOrdinal(fieldValue); else return super.getOrdinal(fieldValue); } diff --git a/server-core/src/main/java/io/onedev/server/persistence/dao/BaseEntityManager.java b/server-core/src/main/java/io/onedev/server/persistence/dao/BaseEntityManager.java index f28070aea8..9db946c177 100644 --- a/server-core/src/main/java/io/onedev/server/persistence/dao/BaseEntityManager.java +++ b/server-core/src/main/java/io/onedev/server/persistence/dao/BaseEntityManager.java @@ -36,8 +36,8 @@ public abstract class BaseEntityManager implements Ent } @Override - public void delete(T entity) { - dao.remove(entity); + public void delete(T iteration) { + dao.remove(iteration); } @Override diff --git a/server-core/src/main/java/io/onedev/server/rest/resource/IssueResource.java b/server-core/src/main/java/io/onedev/server/rest/resource/IssueResource.java index 4202259ff7..8a896ed714 100644 --- a/server-core/src/main/java/io/onedev/server/rest/resource/IssueResource.java +++ b/server-core/src/main/java/io/onedev/server/rest/resource/IssueResource.java @@ -44,7 +44,7 @@ public class IssueResource { private final IssueChangeManager issueChangeManager; - private final MilestoneManager milestoneManager; + private final IterationManager iterationManager; private final ProjectManager projectManager; @@ -52,12 +52,12 @@ public class IssueResource { @Inject public IssueResource(SettingManager settingManager, IssueManager issueManager, - IssueChangeManager issueChangeManager, MilestoneManager milestoneManager, + IssueChangeManager issueChangeManager, IterationManager iterationManager, ProjectManager projectManager, ObjectMapper objectMapper) { this.settingManager = settingManager; this.issueManager = issueManager; this.issueChangeManager = issueChangeManager; - this.milestoneManager = milestoneManager; + this.iterationManager = iterationManager; this.projectManager = projectManager; this.objectMapper = objectMapper; } @@ -123,13 +123,13 @@ public class IssueResource { } @Api(order=450) - @Path("/{issueId}/milestones") + @Path("/{issueId}/iterations") @GET - public Collection getMilestones(@PathParam("issueId") Long issueId) { + public Collection getIterations(@PathParam("issueId") Long issueId) { Issue issue = issueManager.load(issueId); if (!SecurityUtils.canAccessIssue(issue)) throw new UnauthorizedException(); - return issue.getMilestones(); + return issue.getIterations(); } @Api(order=500) @@ -237,7 +237,7 @@ public class IssueResource { if (!SecurityUtils.canAccessProject(project)) throw new UnauthorizedException(); - if (!data.getMilestoneIds().isEmpty() && !SecurityUtils.canScheduleIssues(project)) + if (!data.getIterationIds().isEmpty() && !SecurityUtils.canScheduleIssues(project)) throw new UnauthorizedException("No permission to schedule issue"); var issueSetting = settingManager.getIssueSetting(); @@ -252,13 +252,13 @@ public class IssueResource { issue.setState(issueSetting.getInitialStateSpec().getName()); issue.setOwnEstimatedTime(data.getOwnEstimatedTime()); - for (Long milestoneId : data.getMilestoneIds()) { - Milestone milestone = milestoneManager.load(milestoneId); - if (!milestone.getProject().isSelfOrAncestorOf(project)) - throw new BadRequestException("Milestone is not defined in project hierarchy of the issue"); + for (Long iterationId : data.getIterationIds()) { + Iteration iteration = iterationManager.load(iterationId); + if (!iteration.getProject().isSelfOrAncestorOf(project)) + throw new BadRequestException("Iteration is not defined in project hierarchy of the issue"); IssueSchedule schedule = new IssueSchedule(); schedule.setIssue(issue); - schedule.setMilestone(milestone); + schedule.setIteration(iteration); issue.getSchedules().add(schedule); } @@ -311,23 +311,23 @@ public class IssueResource { return Response.ok().build(); } - @Api(order=1300, description="Schedule issue into specified milestones with list of milestone id") - @Path("/{issueId}/milestones") + @Api(order=1300, description="Schedule issue into specified iterations with list of iteration id") + @Path("/{issueId}/iterations") @POST - public Response setMilestones(@PathParam("issueId") Long issueId, List milestoneIds) { + public Response setIterations(@PathParam("issueId") Long issueId, List iterationIds) { Issue issue = issueManager.load(issueId); if (!SecurityUtils.canScheduleIssues(issue.getProject())) throw new UnauthorizedException("No permission to schedule issue"); - Collection milestones = new HashSet<>(); - for (Long milestoneId: milestoneIds) { - Milestone milestone = milestoneManager.load(milestoneId); - if (!milestone.getProject().isSelfOrAncestorOf(issue.getProject())) - throw new InvalidParamException("Milestone is not defined in project hierarchy of the issue"); - milestones.add(milestone); + Collection iterations = new HashSet<>(); + for (Long iterationId: iterationIds) { + Iteration iteration = iterationManager.load(iterationId); + if (!iteration.getProject().isSelfOrAncestorOf(issue.getProject())) + throw new InvalidParamException("Iteration is not defined in project hierarchy of the issue"); + iterations.add(iteration); } - issueChangeManager.changeMilestones(issue, milestones); + issueChangeManager.changeIterations(issue, iterations); return Response.ok().build(); } @@ -434,7 +434,7 @@ public class IssueResource { private int ownEstimatedTime; @Api(order=500) - private List milestoneIds = new ArrayList<>(); + private List iterationIds = new ArrayList<>(); @Api(order=600, exampleProvider = "getFieldsExample") private Map fields = new HashMap<>(); @@ -481,12 +481,12 @@ public class IssueResource { this.ownEstimatedTime = ownEstimatedTime; } - public List getMilestoneIds() { - return milestoneIds; + public List getIterationIds() { + return iterationIds; } - public void setMilestoneIds(List milestoneIds) { - this.milestoneIds = milestoneIds; + public void setIterationIds(List iterationIds) { + this.iterationIds = iterationIds; } @NotNull diff --git a/server-core/src/main/java/io/onedev/server/rest/resource/IterationResource.java b/server-core/src/main/java/io/onedev/server/rest/resource/IterationResource.java new file mode 100644 index 0000000000..5beaa1c5ad --- /dev/null +++ b/server-core/src/main/java/io/onedev/server/rest/resource/IterationResource.java @@ -0,0 +1,77 @@ +package io.onedev.server.rest.resource; + +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.validation.constraints.NotNull; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.apache.shiro.authz.UnauthorizedException; + +import io.onedev.server.entitymanager.IterationManager; +import io.onedev.server.model.Iteration; +import io.onedev.server.rest.annotation.Api; +import io.onedev.server.security.SecurityUtils; + +@Api(order=2500) +@Path("/iterations") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +@Singleton +public class IterationResource { + + private final IterationManager iterationManager; + + @Inject + public IterationResource(IterationManager iterationManager) { + this.iterationManager = iterationManager; + } + + @Api(order=100) + @Path("/{iterationId}") + @GET + public Iteration get(@PathParam("iterationId") Long iterationId) { + Iteration iteration = iterationManager.load(iterationId); + if (!SecurityUtils.canAccessProject(iteration.getProject())) + throw new UnauthorizedException(); + return iteration; + } + + @Api(order=200, description="Create new iteration") + @POST + public Long create(@NotNull Iteration iteration) { + if (!SecurityUtils.canManageIssues(iteration.getProject())) + throw new UnauthorizedException(); + iterationManager.createOrUpdate(iteration); + return iteration.getId(); + } + + @Api(order=250, description="Update iteration of specified id") + @Path("/{iterationId}") + @POST + public Long update(@PathParam("iterationId") Long iterationId, @NotNull Iteration iteration) { + if (!SecurityUtils.canManageIssues(iteration.getProject())) + throw new UnauthorizedException(); + iterationManager.createOrUpdate(iteration); + return iteration.getId(); + } + + @Api(order=300) + @Path("/{iterationId}") + @DELETE + public Response delete(@PathParam("iterationId") Long iterationId) { + Iteration iteration = iterationManager.load(iterationId); + if (!SecurityUtils.canManageIssues(iteration.getProject())) + throw new UnauthorizedException(); + iterationManager.delete(iteration); + return Response.ok().build(); + } + +} diff --git a/server-core/src/main/java/io/onedev/server/rest/resource/MilestoneResource.java b/server-core/src/main/java/io/onedev/server/rest/resource/MilestoneResource.java deleted file mode 100644 index 82b9e1f395..0000000000 --- a/server-core/src/main/java/io/onedev/server/rest/resource/MilestoneResource.java +++ /dev/null @@ -1,77 +0,0 @@ -package io.onedev.server.rest.resource; - -import javax.inject.Inject; -import javax.inject.Singleton; -import javax.validation.constraints.NotNull; -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import org.apache.shiro.authz.UnauthorizedException; - -import io.onedev.server.entitymanager.MilestoneManager; -import io.onedev.server.model.Milestone; -import io.onedev.server.rest.annotation.Api; -import io.onedev.server.security.SecurityUtils; - -@Api(order=2500) -@Path("/milestones") -@Consumes(MediaType.APPLICATION_JSON) -@Produces(MediaType.APPLICATION_JSON) -@Singleton -public class MilestoneResource { - - private final MilestoneManager milestoneManager; - - @Inject - public MilestoneResource(MilestoneManager milestoneManager) { - this.milestoneManager = milestoneManager; - } - - @Api(order=100) - @Path("/{milestoneId}") - @GET - public Milestone get(@PathParam("milestoneId") Long milestoneId) { - Milestone milestone = milestoneManager.load(milestoneId); - if (!SecurityUtils.canAccessProject(milestone.getProject())) - throw new UnauthorizedException(); - return milestone; - } - - @Api(order=200, description="Create new milestone") - @POST - public Long create(@NotNull Milestone milestone) { - if (!SecurityUtils.canManageIssues(milestone.getProject())) - throw new UnauthorizedException(); - milestoneManager.createOrUpdate(milestone); - return milestone.getId(); - } - - @Api(order=250, description="Update milestone of specified id") - @Path("/{milestoneId}") - @POST - public Long update(@PathParam("milestoneId") Long milestoneId, @NotNull Milestone milestone) { - if (!SecurityUtils.canManageIssues(milestone.getProject())) - throw new UnauthorizedException(); - milestoneManager.createOrUpdate(milestone); - return milestone.getId(); - } - - @Api(order=300) - @Path("/{milestoneId}") - @DELETE - public Response delete(@PathParam("milestoneId") Long milestoneId) { - Milestone milestone = milestoneManager.load(milestoneId); - if (!SecurityUtils.canManageIssues(milestone.getProject())) - throw new UnauthorizedException(); - milestoneManager.delete(milestone); - return Response.ok().build(); - } - -} diff --git a/server-core/src/main/java/io/onedev/server/rest/resource/ProjectResource.java b/server-core/src/main/java/io/onedev/server/rest/resource/ProjectResource.java index c593b0f61d..5eff924c5c 100644 --- a/server-core/src/main/java/io/onedev/server/rest/resource/ProjectResource.java +++ b/server-core/src/main/java/io/onedev/server/rest/resource/ProjectResource.java @@ -2,7 +2,7 @@ package io.onedev.server.rest.resource; import com.google.common.collect.Sets; import io.onedev.commons.utils.ExplicitException; -import io.onedev.server.entitymanager.MilestoneManager; +import io.onedev.server.entitymanager.IterationManager; import io.onedev.server.entitymanager.ProjectManager; import io.onedev.server.model.support.pack.ProjectPackSetting; import io.onedev.server.web.UrlManager; @@ -53,17 +53,17 @@ public class ProjectResource { private final ProjectManager projectManager; - private final MilestoneManager milestoneManager; + private final IterationManager iterationManager; private final CommitInfoManager commitInfoManager; private final UrlManager urlManager; @Inject - public ProjectResource(ProjectManager projectManager, MilestoneManager milestoneManager, + public ProjectResource(ProjectManager projectManager, IterationManager iterationManager, CommitInfoManager commitInfoManager, UrlManager urlManager) { this.projectManager = projectManager; - this.milestoneManager = milestoneManager; + this.iterationManager = iterationManager; this.commitInfoManager = commitInfoManager; this.urlManager = urlManager; } @@ -186,15 +186,15 @@ public class ProjectResource { } @Api(order=750) - @Path("/{projectId}/milestones") + @Path("/{projectId}/iterations") @GET - public List queryMilestones(@PathParam("projectId") Long projectId, @QueryParam("name") String name, - @QueryParam("startBefore") @Api(exampleProvider="getDateExample", description="ISO 8601 date") String startBefore, - @QueryParam("startAfter") @Api(exampleProvider="getDateExample", description="ISO 8601 date") String startAfter, - @QueryParam("dueBefore") @Api(exampleProvider="getDateExample", description="ISO 8601 date") String dueBefore, - @QueryParam("dueAfter") @Api(exampleProvider="getDateExample", description="ISO 8601 date") String dueAfter, - @QueryParam("closed") Boolean closed, @QueryParam("offset") @Api(example="0") int offset, - @QueryParam("count") @Api(example="100") int count) { + public List queryIterations(@PathParam("projectId") Long projectId, @QueryParam("name") String name, + @QueryParam("startBefore") @Api(exampleProvider="getDateExample", description="ISO 8601 date") String startBefore, + @QueryParam("startAfter") @Api(exampleProvider="getDateExample", description="ISO 8601 date") String startAfter, + @QueryParam("dueBefore") @Api(exampleProvider="getDateExample", description="ISO 8601 date") String dueBefore, + @QueryParam("dueAfter") @Api(exampleProvider="getDateExample", description="ISO 8601 date") String dueAfter, + @QueryParam("closed") Boolean closed, @QueryParam("offset") @Api(example="0") int offset, + @QueryParam("count") @Api(example="100") int count) { Project project = projectManager.load(projectId); if (!SecurityUtils.canAccessProject(project)) throw new UnauthorizedException(); @@ -202,22 +202,22 @@ public class ProjectResource { if (count > RestConstants.MAX_PAGE_SIZE) throw new InvalidParamException("Count should not be greater than " + RestConstants.MAX_PAGE_SIZE); - EntityCriteria criteria = EntityCriteria.of(Milestone.class); - criteria.add(Restrictions.in(Milestone.PROP_PROJECT, project.getSelfAndAncestors())); + EntityCriteria criteria = EntityCriteria.of(Iteration.class); + criteria.add(Restrictions.in(Iteration.PROP_PROJECT, project.getSelfAndAncestors())); if (name != null) - criteria.add(Restrictions.ilike(Milestone.PROP_NAME, name.replace('%', '*'))); + criteria.add(Restrictions.ilike(Iteration.PROP_NAME, name.replace('%', '*'))); if (startBefore != null) - criteria.add(Restrictions.le(Milestone.PROP_START_DATE, DateUtils.parseISO8601Date(startBefore))); + criteria.add(Restrictions.le(Iteration.PROP_START_DATE, DateUtils.parseISO8601Date(startBefore))); if (startAfter != null) - criteria.add(Restrictions.ge(Milestone.PROP_START_DATE, DateUtils.parseISO8601Date(startAfter))); + criteria.add(Restrictions.ge(Iteration.PROP_START_DATE, DateUtils.parseISO8601Date(startAfter))); if (dueBefore != null) - criteria.add(Restrictions.le(Milestone.PROP_DUE_DATE, DateUtils.parseISO8601Date(dueBefore))); + criteria.add(Restrictions.le(Iteration.PROP_DUE_DATE, DateUtils.parseISO8601Date(dueBefore))); if (dueAfter != null) - criteria.add(Restrictions.ge(Milestone.PROP_DUE_DATE, DateUtils.parseISO8601Date(dueAfter))); + criteria.add(Restrictions.ge(Iteration.PROP_DUE_DATE, DateUtils.parseISO8601Date(dueAfter))); if (closed != null) - criteria.add(Restrictions.eq(Milestone.PROP_CLOSED, closed)); + criteria.add(Restrictions.eq(Iteration.PROP_CLOSED, closed)); - return milestoneManager.query(criteria, offset, count); + return iterationManager.query(criteria, offset, count); } @Api(order=760, description="Get top contributors on default branch") diff --git a/server-core/src/main/java/io/onedev/server/search/entity/EntityQuery.java b/server-core/src/main/java/io/onedev/server/search/entity/EntityQuery.java index bbe1a6fb4c..0864d8a193 100644 --- a/server-core/src/main/java/io/onedev/server/search/entity/EntityQuery.java +++ b/server-core/src/main/java/io/onedev/server/search/entity/EntityQuery.java @@ -156,14 +156,14 @@ public abstract class EntityQuery implements Serializa throw new ExplicitException("Unable to find build: " + value); } - public static Milestone getMilestone(@Nullable Project project, String value) { + public static Iteration getIteration(@Nullable Project project, String value) { if (project != null && !value.contains(":")) value = project.getPath() + ":" + value; - Milestone milestone = OneDev.getInstance(MilestoneManager.class).findInHierarchy(value); - if (milestone != null) - return milestone; + Iteration iteration = OneDev.getInstance(IterationManager.class).findInHierarchy(value); + if (iteration != null) + return iteration; else - throw new ExplicitException("Unable to find milestone: " + value); + throw new ExplicitException("Unable to find iteration: " + value); } public boolean matches(T entity) { diff --git a/server-core/src/main/java/io/onedev/server/search/entity/issue/IssueQuery.java b/server-core/src/main/java/io/onedev/server/search/entity/issue/IssueQuery.java index 56467a6807..3a6b95c82e 100644 --- a/server-core/src/main/java/io/onedev/server/search/entity/issue/IssueQuery.java +++ b/server-core/src/main/java/io/onedev/server/search/entity/issue/IssueQuery.java @@ -154,8 +154,8 @@ public class IssueQuery extends EntityQuery implements Comparator checkField(fieldName, operator, option); if (fieldName.equals(NAME_PROJECT)) { return new ProjectIsCurrentCriteria(); - } else if (fieldName.equals(IssueSchedule.NAME_MILESTONE)) { - return new MilestoneEmptyCriteria(operator); + } else if (fieldName.equals(IssueSchedule.NAME_ITERATION)) { + return new IterationEmptyCriteria(operator); } else { FieldSpec fieldSpec = getGlobalIssueSetting().getFieldSpec(fieldName); if (fieldSpec != null) @@ -246,8 +246,8 @@ public class IssueQuery extends EntityQuery implements Comparator case IssueQueryLexer.IsNot: if (fieldName.equals(NAME_PROJECT)) { return new ProjectCriteria(value, operator); - } else if (fieldName.equals(IssueSchedule.NAME_MILESTONE)) { - return new MilestoneCriteria(value, operator); + } else if (fieldName.equals(IssueSchedule.NAME_ITERATION)) { + return new IterationCriteria(value, operator); } else if (fieldName.equals(NAME_STATE)) { return new StateCriteria(value, operator); } else if (fieldName.equals(NAME_VOTE_COUNT)) { @@ -357,7 +357,7 @@ public class IssueQuery extends EntityQuery implements Comparator FieldSpec fieldSpec = getGlobalIssueSetting().getFieldSpec(fieldName); if (validate && !(fieldSpec instanceof ChoiceField) && !(fieldSpec instanceof DateField) && !(fieldSpec instanceof DateTimeField) && !(fieldSpec instanceof IntegerField) - && !(fieldSpec instanceof MilestoneChoiceField)) { + && !(fieldSpec instanceof IterationChoiceField)) { throw new ExplicitException("Can not order by field: " + fieldName); } } @@ -396,7 +396,7 @@ public class IssueQuery extends EntityQuery implements Comparator case IssueQueryLexer.IsEmpty: case IssueQueryLexer.IsNotEmpty: if (Issue.QUERY_FIELDS.contains(fieldName) - && !fieldName.equals(IssueSchedule.NAME_MILESTONE)) { + && !fieldName.equals(IssueSchedule.NAME_ITERATION)) { throw newOperatorException(fieldName, operator); } break; @@ -442,7 +442,7 @@ public class IssueQuery extends EntityQuery implements Comparator && !fieldName.equals(Issue.NAME_VOTE_COUNT) && !fieldName.equals(Issue.NAME_COMMENT_COUNT) && !fieldName.equals(Issue.NAME_NUMBER) - && !fieldName.equals(IssueSchedule.NAME_MILESTONE) + && !fieldName.equals(IssueSchedule.NAME_ITERATION) && !(fieldSpec instanceof IssueChoiceField) && !(fieldSpec instanceof PullRequestChoiceField) && !(fieldSpec instanceof BuildChoiceField) diff --git a/server-core/src/main/java/io/onedev/server/search/entity/issue/MilestoneCriteria.java b/server-core/src/main/java/io/onedev/server/search/entity/issue/IterationCriteria.java similarity index 70% rename from server-core/src/main/java/io/onedev/server/search/entity/issue/MilestoneCriteria.java rename to server-core/src/main/java/io/onedev/server/search/entity/issue/IterationCriteria.java index a6d6572b4a..e105c85794 100644 --- a/server-core/src/main/java/io/onedev/server/search/entity/issue/MilestoneCriteria.java +++ b/server-core/src/main/java/io/onedev/server/search/entity/issue/IterationCriteria.java @@ -11,20 +11,20 @@ import javax.persistence.criteria.Subquery; import io.onedev.server.model.Issue; import io.onedev.server.model.IssueSchedule; -import io.onedev.server.model.Milestone; +import io.onedev.server.model.Iteration; import io.onedev.server.util.criteria.Criteria; import io.onedev.commons.utils.match.WildcardUtils; -public class MilestoneCriteria extends Criteria { +public class IterationCriteria extends Criteria { private static final long serialVersionUID = 1L; - private final String milestoneName; + private final String iterationName; private final int operator; - public MilestoneCriteria(String milestoneName, int operator) { - this.milestoneName = milestoneName; + public IterationCriteria(String iterationName, int operator) { + this.iterationName = iterationName; this.operator = operator; } @@ -33,10 +33,10 @@ public class MilestoneCriteria extends Criteria { Subquery scheduleQuery = query.subquery(IssueSchedule.class); Root schedule = scheduleQuery.from(IssueSchedule.class); scheduleQuery.select(schedule); - Join milestoneJoin = schedule.join(IssueSchedule.PROP_MILESTONE, JoinType.INNER); + Join iterationJoin = schedule.join(IssueSchedule.PROP_ITERATION, JoinType.INNER); scheduleQuery.where(builder.and( builder.equal(schedule.get(IssueSchedule.PROP_ISSUE), from), - builder.like(milestoneJoin.get(Milestone.PROP_NAME), milestoneName.replace("*", "%")))); + builder.like(iterationJoin.get(Iteration.PROP_NAME), iterationName.replace("*", "%")))); var predicate = builder.exists(scheduleQuery); if (operator == IssueQueryLexer.IsNot) predicate = builder.not(predicate); @@ -46,7 +46,7 @@ public class MilestoneCriteria extends Criteria { @Override public boolean matches(Issue issue) { var matches = issue.getSchedules().stream() - .anyMatch(it->WildcardUtils.matchString(milestoneName, it.getMilestone().getName())); + .anyMatch(it->WildcardUtils.matchString(iterationName, it.getIteration().getName())); if (operator == IssueQueryLexer.IsNot) matches = !matches; return matches; @@ -54,19 +54,19 @@ public class MilestoneCriteria extends Criteria { @Override public String toStringWithoutParens() { - return quote(IssueSchedule.NAME_MILESTONE) + " " + return quote(IssueSchedule.NAME_ITERATION) + " " + IssueQuery.getRuleName(operator) + " " - + quote(milestoneName); + + quote(iterationName); } @Override public void fill(Issue issue) { if (operator == IssueQueryLexer.Is) { - Milestone milestone = issue.getProject().getHierarchyMilestone(milestoneName); - if (milestone != null) { + Iteration iteration = issue.getProject().getHierarchyIteration(iterationName); + if (iteration != null) { IssueSchedule schedule = new IssueSchedule(); schedule.setIssue(issue); - schedule.setMilestone(milestone); + schedule.setIteration(iteration); issue.getSchedules().add(schedule); } } diff --git a/server-core/src/main/java/io/onedev/server/search/entity/issue/MilestoneEmptyCriteria.java b/server-core/src/main/java/io/onedev/server/search/entity/issue/IterationEmptyCriteria.java similarity index 85% rename from server-core/src/main/java/io/onedev/server/search/entity/issue/MilestoneEmptyCriteria.java rename to server-core/src/main/java/io/onedev/server/search/entity/issue/IterationEmptyCriteria.java index 7b7d14ed60..3e631af775 100644 --- a/server-core/src/main/java/io/onedev/server/search/entity/issue/MilestoneEmptyCriteria.java +++ b/server-core/src/main/java/io/onedev/server/search/entity/issue/IterationEmptyCriteria.java @@ -9,13 +9,13 @@ import io.onedev.server.model.Issue; import io.onedev.server.model.IssueSchedule; import io.onedev.server.util.criteria.Criteria; -public class MilestoneEmptyCriteria extends Criteria { +public class IterationEmptyCriteria extends Criteria { private static final long serialVersionUID = 1L; private final int operator; - public MilestoneEmptyCriteria(int operator) { + public IterationEmptyCriteria(int operator) { this.operator = operator; } @@ -37,7 +37,7 @@ public class MilestoneEmptyCriteria extends Criteria { @Override public String toStringWithoutParens() { - return quote(IssueSchedule.NAME_MILESTONE) + " " + IssueQuery.getRuleName(operator); + return quote(IssueSchedule.NAME_ITERATION) + " " + IssueQuery.getRuleName(operator); } } diff --git a/server-core/src/main/java/io/onedev/server/util/MilestoneAndIssueState.java b/server-core/src/main/java/io/onedev/server/util/IterationAndIssueState.java similarity index 51% rename from server-core/src/main/java/io/onedev/server/util/MilestoneAndIssueState.java rename to server-core/src/main/java/io/onedev/server/util/IterationAndIssueState.java index 767d885f8a..079f9c91b9 100644 --- a/server-core/src/main/java/io/onedev/server/util/MilestoneAndIssueState.java +++ b/server-core/src/main/java/io/onedev/server/util/IterationAndIssueState.java @@ -2,21 +2,21 @@ package io.onedev.server.util; import java.io.Serializable; -public class MilestoneAndIssueState implements Serializable { +public class IterationAndIssueState implements Serializable { private static final long serialVersionUID = 1L; - private final Long milestoneId; + private final Long iterationId; private final String issueState; - public MilestoneAndIssueState(Long milestoneId, String issueState) { - this.milestoneId = milestoneId; + public IterationAndIssueState(Long iterationId, String issueState) { + this.iterationId = iterationId; this.issueState = issueState; } - public Long getMilestoneId() { - return milestoneId; + public Long getIterationId() { + return iterationId; } public String getIssueState() { diff --git a/server-core/src/main/java/io/onedev/server/util/MilestoneSort.java b/server-core/src/main/java/io/onedev/server/util/IterationSort.java similarity index 73% rename from server-core/src/main/java/io/onedev/server/util/MilestoneSort.java rename to server-core/src/main/java/io/onedev/server/util/IterationSort.java index 31299f059b..8d97fdc6e5 100644 --- a/server-core/src/main/java/io/onedev/server/util/MilestoneSort.java +++ b/server-core/src/main/java/io/onedev/server/util/IterationSort.java @@ -3,14 +3,14 @@ package io.onedev.server.util; import org.eclipse.jgit.util.StringUtils; import org.hibernate.criterion.Order; -import io.onedev.server.model.Milestone; +import io.onedev.server.model.Iteration; -public enum MilestoneSort { +public enum IterationSort { CLOSEST_DUE_DATE { @Override public Order getOrder(boolean closed) { - return closed?Order.desc(Milestone.PROP_DUE_DATE):Order.asc(Milestone.PROP_DUE_DATE); + return closed?Order.desc(Iteration.PROP_DUE_DATE):Order.asc(Iteration.PROP_DUE_DATE); } }, @@ -18,7 +18,7 @@ public enum MilestoneSort { @Override public Order getOrder(boolean closed) { - return closed?Order.asc(Milestone.PROP_DUE_DATE):Order.desc(Milestone.PROP_DUE_DATE); + return closed?Order.asc(Iteration.PROP_DUE_DATE):Order.desc(Iteration.PROP_DUE_DATE); } }, diff --git a/server-core/src/main/java/io/onedev/server/web/asset/icon/iteration.svg b/server-core/src/main/java/io/onedev/server/web/asset/icon/iteration.svg new file mode 100644 index 0000000000..57cede30aa --- /dev/null +++ b/server-core/src/main/java/io/onedev/server/web/asset/icon/iteration.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/server-core/src/main/java/io/onedev/server/web/asset/icon/milestone.svg b/server-core/src/main/java/io/onedev/server/web/asset/icon/milestone.svg deleted file mode 100644 index 6d42358df6..0000000000 --- a/server-core/src/main/java/io/onedev/server/web/asset/icon/milestone.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/server-core/src/main/java/io/onedev/server/web/behavior/IssueQueryBehavior.java b/server-core/src/main/java/io/onedev/server/web/behavior/IssueQueryBehavior.java index a5ceb5a51b..c93026dd88 100644 --- a/server-core/src/main/java/io/onedev/server/web/behavior/IssueQueryBehavior.java +++ b/server-core/src/main/java/io/onedev/server/web/behavior/IssueQueryBehavior.java @@ -141,7 +141,7 @@ public class IssueQueryBehavior extends ANTLRAssistBehavior { for (FieldSpec field: issueSetting.getFieldSpecs()) { if (field instanceof IntegerField || field instanceof ChoiceField || field instanceof DateField || field instanceof DateTimeField - || field instanceof MilestoneChoiceField) { + || field instanceof IterationChoiceField) { candidates.put(field.getName(), null); } } @@ -227,9 +227,9 @@ public class IssueQueryBehavior extends ANTLRAssistBehavior { } } else if (fieldName.equals(NAME_NUMBER)) { return SuggestionUtils.suggestIssues(project, matchWith, InputAssistBehavior.MAX_SUGGESTIONS); - } else if (fieldName.equals(IssueSchedule.NAME_MILESTONE)) { + } else if (fieldName.equals(IssueSchedule.NAME_ITERATION)) { if (project != null && !matchWith.contains("*")) - return SuggestionUtils.suggestMilestones(project, matchWith); + return SuggestionUtils.suggestIterations(project, matchWith); else return null; } else if (fieldName.equals(NAME_ESTIMATED_TIME) || fieldName.equals(NAME_SPENT_TIME)) { @@ -328,7 +328,7 @@ public class IssueQueryBehavior extends ANTLRAssistBehavior { } else if (fieldName.equals(Issue.NAME_TITLE) || fieldName.equals(Issue.NAME_DESCRIPTION) || fieldName.equals(Issue.NAME_COMMENT) - || fieldName.equals(IssueSchedule.NAME_MILESTONE)) { + || fieldName.equals(IssueSchedule.NAME_ITERATION)) { hints.add("Use '*' for wildcard match"); hints.add("Use '\\' to escape quotes"); } diff --git a/server-core/src/main/java/io/onedev/server/web/component/commandpalette/CommandPalettePanel.java b/server-core/src/main/java/io/onedev/server/web/component/commandpalette/CommandPalettePanel.java index 486a86fced..a33245ff09 100644 --- a/server-core/src/main/java/io/onedev/server/web/component/commandpalette/CommandPalettePanel.java +++ b/server-core/src/main/java/io/onedev/server/web/component/commandpalette/CommandPalettePanel.java @@ -59,7 +59,7 @@ public abstract class CommandPalettePanel extends Panel { "~test/** ~errors/** ~sso/** ~oauth/** ~verify-email-address/** ~create-user-from-invitation/** " + "~reset-password/** ~signup/** ~logout/** ~login/** ~loading/** ~init/** ~help/** **/invalid " + "**/${issue}/** -**/${issue} **/${request}/** -**/${request} **/${build}/** -**/${build} " + - "**/${milestone}/** -**/${milestone} **/${agent}/** -**/${agent} **/${group}/** -**/${group} " + + "**/${iteration}/** -**/${iteration} **/${agent}/** -**/${agent} **/${group}/** -**/${group} " + "projects/**"); private static final PatternSet eeUrlPatterns = PatternSet.parse("" + diff --git a/server-core/src/main/java/io/onedev/server/web/component/commandpalette/IterationParam.java b/server-core/src/main/java/io/onedev/server/web/component/commandpalette/IterationParam.java new file mode 100644 index 0000000000..425888eccf --- /dev/null +++ b/server-core/src/main/java/io/onedev/server/web/component/commandpalette/IterationParam.java @@ -0,0 +1,43 @@ +package io.onedev.server.web.component.commandpalette; + +import java.util.LinkedHashMap; +import java.util.Map; + +import io.onedev.server.OneDev; +import io.onedev.server.entitymanager.IterationManager; +import io.onedev.server.model.Iteration; +import io.onedev.server.web.page.project.issues.iteration.IterationDetailPage; + +public class IterationParam extends ParamSegment { + + private static final long serialVersionUID = 1L; + + public IterationParam(boolean optional) { + super(IterationDetailPage.PARAM_ITERATION, optional); + } + + @Override + public Map suggest(String matchWith, Map paramValues, int count) { + Map suggestions = new LinkedHashMap<>(); + for (Iteration iteration: ParsedUrl.getProject(paramValues).getSortedHierarchyIterations()) { + if (iteration.getName().toLowerCase().contains(matchWith)) { + suggestions.put(iteration.getName(), String.valueOf(iteration.getId())); + if (--count == 0) + break; + } + } + return suggestions; + } + + @Override + public boolean isExactMatch(String matchWith, Map paramValues) { + try { + Long iterationId = Long.valueOf(matchWith); + if (OneDev.getInstance(IterationManager.class).get(iterationId) != null) + return true; + } catch (NumberFormatException e) { + } + return false; + } + +} diff --git a/server-core/src/main/java/io/onedev/server/web/component/commandpalette/MilestoneParam.java b/server-core/src/main/java/io/onedev/server/web/component/commandpalette/MilestoneParam.java deleted file mode 100644 index eb8906df46..0000000000 --- a/server-core/src/main/java/io/onedev/server/web/component/commandpalette/MilestoneParam.java +++ /dev/null @@ -1,43 +0,0 @@ -package io.onedev.server.web.component.commandpalette; - -import java.util.LinkedHashMap; -import java.util.Map; - -import io.onedev.server.OneDev; -import io.onedev.server.entitymanager.MilestoneManager; -import io.onedev.server.model.Milestone; -import io.onedev.server.web.page.project.issues.milestones.MilestoneDetailPage; - -public class MilestoneParam extends ParamSegment { - - private static final long serialVersionUID = 1L; - - public MilestoneParam(boolean optional) { - super(MilestoneDetailPage.PARAM_MILESTONE, optional); - } - - @Override - public Map suggest(String matchWith, Map paramValues, int count) { - Map suggestions = new LinkedHashMap<>(); - for (Milestone milestone: ParsedUrl.getProject(paramValues).getSortedHierarchyMilestones()) { - if (milestone.getName().toLowerCase().contains(matchWith)) { - suggestions.put(milestone.getName(), String.valueOf(milestone.getId())); - if (--count == 0) - break; - } - } - return suggestions; - } - - @Override - public boolean isExactMatch(String matchWith, Map paramValues) { - try { - Long milestoneId = Long.valueOf(matchWith); - if (OneDev.getInstance(MilestoneManager.class).get(milestoneId) != null) - return true; - } catch (NumberFormatException e) { - } - return false; - } - -} diff --git a/server-core/src/main/java/io/onedev/server/web/component/commandpalette/ParsedUrl.java b/server-core/src/main/java/io/onedev/server/web/component/commandpalette/ParsedUrl.java index f453561928..cffd4dcd6b 100644 --- a/server-core/src/main/java/io/onedev/server/web/component/commandpalette/ParsedUrl.java +++ b/server-core/src/main/java/io/onedev/server/web/component/commandpalette/ParsedUrl.java @@ -33,7 +33,7 @@ import io.onedev.server.web.page.project.builds.detail.BuildDetailPage; import io.onedev.server.web.page.project.commits.CommitDetailPage; import io.onedev.server.web.page.project.issues.boards.IssueBoardsPage; import io.onedev.server.web.page.project.issues.detail.IssueDetailPage; -import io.onedev.server.web.page.project.issues.milestones.MilestoneDetailPage; +import io.onedev.server.web.page.project.issues.iteration.IterationDetailPage; import io.onedev.server.web.page.project.pullrequests.detail.PullRequestDetailPage; public abstract class ParsedUrl implements Serializable { @@ -88,8 +88,8 @@ public abstract class ParsedUrl implements Serializable { case AgentDetailPage.PARAM_AGENT: parsedSegments.add(new AgentParam(optional)); break; - case MilestoneDetailPage.PARAM_MILESTONE: - parsedSegments.add(new MilestoneParam(optional)); + case IterationDetailPage.PARAM_ITERATION: + parsedSegments.add(new IterationParam(optional)); break; case ServerDetailPage.PARAM_SERVER: if (getServers().size() > 1) @@ -147,7 +147,7 @@ public abstract class ParsedUrl implements Serializable { case "~boards": case "~issues": return project.isIssueManagement(); - case "~milestones": + case "~iterations": if (project.isIssueManagement()) { if (segment2.equals("new")) return SecurityUtils.canManageIssues(project); diff --git a/server-core/src/main/java/io/onedev/server/web/component/issue/create/NewIssueEditor.html b/server-core/src/main/java/io/onedev/server/web/component/issue/create/NewIssueEditor.html index 96cb2102ee..aff8c9e9ab 100644 --- a/server-core/src/main/java/io/onedev/server/web/component/issue/create/NewIssueEditor.html +++ b/server-core/src/main/java/io/onedev/server/web/component/issue/create/NewIssueEditor.html @@ -27,10 +27,10 @@ - +
- - + +
diff --git a/server-core/src/main/java/io/onedev/server/web/component/issue/create/NewIssueEditor.java b/server-core/src/main/java/io/onedev/server/web/component/issue/create/NewIssueEditor.java index cc9108115e..a4c24a1cb1 100644 --- a/server-core/src/main/java/io/onedev/server/web/component/issue/create/NewIssueEditor.java +++ b/server-core/src/main/java/io/onedev/server/web/component/issue/create/NewIssueEditor.java @@ -9,7 +9,7 @@ import io.onedev.server.buildspecmodel.inputspec.InputSpec; import io.onedev.server.entitymanager.SettingManager; import io.onedev.server.model.Issue; import io.onedev.server.model.IssueSchedule; -import io.onedev.server.model.Milestone; +import io.onedev.server.model.Iteration; import io.onedev.server.model.Project; import io.onedev.server.model.support.administration.GlobalIssueSetting; import io.onedev.server.model.support.issue.IssueTemplate; @@ -27,7 +27,7 @@ import io.onedev.server.web.behavior.ReferenceInputBehavior; import io.onedev.server.web.component.comment.CommentInput; import io.onedev.server.web.component.issue.IssueStateBadge; import io.onedev.server.web.component.issue.title.IssueTitlePanel; -import io.onedev.server.web.component.milestone.choice.MilestoneMultiChoice; +import io.onedev.server.web.component.iteration.choice.IterationMultiChoice; import io.onedev.server.web.component.modal.confirm.ConfirmModalPanel; import io.onedev.server.web.editable.BeanContext; import io.onedev.server.web.editable.BeanEditor; @@ -76,7 +76,7 @@ public abstract class NewIssueEditor extends FormComponentPanel implement private CheckBox confidentialInput; - private MilestoneMultiChoice milestoneChoice; + private IterationMultiChoice iterationChoice; private BeanEditor fieldEditor; @@ -211,20 +211,20 @@ public abstract class NewIssueEditor extends FormComponentPanel implement add(confidentialInput = new CheckBox("confidential", Model.of(false))); - Collection milestones = issue.getMilestones(); - milestoneChoice = new MilestoneMultiChoice("milestones", Model.of(milestones), - new LoadableDetachableModel>() { + Collection iterations = issue.getIterations(); + iterationChoice = new IterationMultiChoice("iterations", Model.of(iterations), + new LoadableDetachableModel>() { @Override - protected Collection load() { - return getProject().getSortedHierarchyMilestones(); + protected Collection load() { + return getProject().getSortedHierarchyIterations(); } }); - milestoneChoice.setVisible(SecurityUtils.canScheduleIssues(getProject())); - milestoneChoice.setRequired(false); + iterationChoice.setVisible(SecurityUtils.canScheduleIssues(getProject())); + iterationChoice.setRequired(false); - add(milestoneChoice); + add(iterationChoice); Collection properties = FieldUtils.getEditablePropertyNames(getProject(), fieldBeanClass, fieldNames); @@ -411,12 +411,12 @@ public abstract class NewIssueEditor extends FormComponentPanel implement issue.setFieldValues(FieldUtils.getFieldValues(fieldEditor.newComponentContext(), fieldEditor.getConvertedInput(), fieldNames)); - milestoneChoice.convertInput(); + iterationChoice.convertInput(); issue.getSchedules().clear(); - for (Milestone milestone: milestoneChoice.getConvertedInput()) { + for (Iteration iteration: iterationChoice.getConvertedInput()) { IssueSchedule schedule = new IssueSchedule(); schedule.setIssue(issue); - schedule.setMilestone(milestone); + schedule.setIteration(iteration); issue.getSchedules().add(schedule); } diff --git a/server-core/src/main/java/io/onedev/server/web/component/issue/fieldvalues/FieldValuesPanel.java b/server-core/src/main/java/io/onedev/server/web/component/issue/fieldvalues/FieldValuesPanel.java index 262029dc00..4763f56894 100644 --- a/server-core/src/main/java/io/onedev/server/web/component/issue/fieldvalues/FieldValuesPanel.java +++ b/server-core/src/main/java/io/onedev/server/web/component/issue/fieldvalues/FieldValuesPanel.java @@ -34,7 +34,7 @@ import io.onedev.server.web.page.base.BasePage; import io.onedev.server.web.page.project.builds.detail.dashboard.BuildDashboardPage; import io.onedev.server.web.page.project.commits.CommitDetailPage; import io.onedev.server.web.page.project.issues.detail.IssueActivitiesPage; -import io.onedev.server.web.page.project.issues.milestones.MilestoneIssuesPage; +import io.onedev.server.web.page.project.issues.iteration.IterationIssuesPage; import io.onedev.server.web.page.project.pullrequests.detail.activities.PullRequestActivitiesPage; import io.onedev.server.web.util.ProjectAware; import org.apache.wicket.Component; @@ -280,14 +280,14 @@ public abstract class FieldValuesPanel extends Panel implements EditContext, Pro } else { valueContainer.add(new Label("value", "Not Found").setEscapeModelStrings(false)); } - } else if (getField().getType().equals(FieldSpec.MILESTONE)) { - Milestone milestone = OneDev.getInstance(MilestoneManager.class).findInHierarchy(getIssue().getProject(), value); - if (milestone != null) { + } else if (getField().getType().equals(FieldSpec.ITERATION)) { + Iteration iteration = OneDev.getInstance(IterationManager.class).findInHierarchy(getIssue().getProject(), value); + if (iteration != null) { Fragment linkFrag = new Fragment("value", "linkFrag", FieldValuesPanel.this); - Link milestoneLink = new BookmarkablePageLink("link", MilestoneIssuesPage.class, - MilestoneIssuesPage.paramsOf(getIssue().getProject(), milestone)); - milestoneLink.add(new Label("label", milestone.getName())); - linkFrag.add(milestoneLink); + Link iterationLink = new BookmarkablePageLink("link", IterationIssuesPage.class, + IterationIssuesPage.paramsOf(getIssue().getProject(), iteration)); + iterationLink.add(new Label("label", iteration.getName())); + linkFrag.add(iterationLink); valueContainer.add(linkFrag); } else { valueContainer.add(new Label("value", "Not Found").setEscapeModelStrings(false)); diff --git a/server-core/src/main/java/io/onedev/server/web/component/issue/iteration/IterationCrumbCssResourceReference.java b/server-core/src/main/java/io/onedev/server/web/component/issue/iteration/IterationCrumbCssResourceReference.java new file mode 100644 index 0000000000..d54a15e33b --- /dev/null +++ b/server-core/src/main/java/io/onedev/server/web/component/issue/iteration/IterationCrumbCssResourceReference.java @@ -0,0 +1,13 @@ +package io.onedev.server.web.component.issue.iteration; + +import io.onedev.server.web.page.base.BaseDependentCssResourceReference; + +public class IterationCrumbCssResourceReference extends BaseDependentCssResourceReference { + + private static final long serialVersionUID = 1L; + + public IterationCrumbCssResourceReference() { + super(IterationCrumbCssResourceReference.class, "iteration-crumb.css"); + } + +} diff --git a/server-core/src/main/java/io/onedev/server/web/component/issue/iteration/IterationCrumbPanel.html b/server-core/src/main/java/io/onedev/server/web/component/issue/iteration/IterationCrumbPanel.html new file mode 100644 index 0000000000..fd60a2325a --- /dev/null +++ b/server-core/src/main/java/io/onedev/server/web/component/issue/iteration/IterationCrumbPanel.html @@ -0,0 +1,8 @@ + + + \ No newline at end of file diff --git a/server-core/src/main/java/io/onedev/server/web/component/issue/milestone/MilestoneCrumbPanel.java b/server-core/src/main/java/io/onedev/server/web/component/issue/iteration/IterationCrumbPanel.java similarity index 67% rename from server-core/src/main/java/io/onedev/server/web/component/issue/milestone/MilestoneCrumbPanel.java rename to server-core/src/main/java/io/onedev/server/web/component/issue/iteration/IterationCrumbPanel.java index d16a1528d8..2eb3f756fe 100644 --- a/server-core/src/main/java/io/onedev/server/web/component/issue/milestone/MilestoneCrumbPanel.java +++ b/server-core/src/main/java/io/onedev/server/web/component/issue/iteration/IterationCrumbPanel.java @@ -1,4 +1,4 @@ -package io.onedev.server.web.component.issue.milestone; +package io.onedev.server.web.component.issue.iteration; import io.onedev.server.OneDev; import io.onedev.server.entitymanager.IssueChangeManager; @@ -8,7 +8,7 @@ import io.onedev.server.security.SecurityUtils; import io.onedev.server.web.component.floating.FloatingPanel; import io.onedev.server.web.editable.InplacePropertyEditLink; import io.onedev.server.web.page.base.BasePage; -import io.onedev.server.web.page.project.issues.milestones.MilestoneIssuesPage; +import io.onedev.server.web.page.project.issues.iteration.IterationIssuesPage; import org.apache.wicket.Component; import org.apache.wicket.core.request.handler.IPartialPageRequestHandler; import org.apache.wicket.markup.head.CssHeaderItem; @@ -22,9 +22,9 @@ import java.io.Serializable; import static java.util.stream.Collectors.toList; -public abstract class MilestoneCrumbPanel extends Panel { +public abstract class IterationCrumbPanel extends Panel { - public MilestoneCrumbPanel(String id) { + public IterationCrumbPanel(String id) { super(id); } @@ -45,25 +45,25 @@ public abstract class MilestoneCrumbPanel extends Panel { @Override protected Serializable getBean() { - var bean = new MilestonesBean(); - bean.setMilestoneNames(getIssue().getSchedules().stream() - .map(it -> it.getMilestone().getName()).collect(toList())); + var bean = new IterationsBean(); + bean.setIterationNames(getIssue().getSchedules().stream() + .map(it -> it.getIteration().getName()).collect(toList())); return bean; } @Override protected String getPropertyName() { - return "milestoneNames"; + return "iterationNames"; } @Override protected void onUpdated(IPartialPageRequestHandler handler, Serializable bean, String propertyName) { - var milestonesBean = (MilestonesBean) bean; + var iterationsBean = (IterationsBean) bean; var issue = getIssue(); - var milestones = milestonesBean.getMilestoneNames().stream() - .map(it -> issue.getProject().getHierarchyMilestone(it)) + var iterations = iterationsBean.getIterationNames().stream() + .map(it -> issue.getProject().getHierarchyIteration(it)) .collect(toList()); - OneDev.getInstance(IssueChangeManager.class).changeMilestones(issue, milestones); + OneDev.getInstance(IssueChangeManager.class).changeIterations(issue, iterations); ((BasePage) getPage()).notifyObservablesChange(handler, issue.getChangeObservables(true)); } @@ -75,15 +75,15 @@ public abstract class MilestoneCrumbPanel extends Panel { }; add(editLink); - var milestonesView = new RepeatingView("milestones"); + var iterationsView = new RepeatingView("iterations"); for (var schedule: getIssue().getSchedules()) { - var child = new BookmarkablePageLink(milestonesView.newChildId(), - MilestoneIssuesPage.class, - MilestoneIssuesPage.paramsOf(getIssue().getProject(), schedule.getMilestone())); - milestonesView.add(child); - child.add(new Label("name", schedule.getMilestone().getName())); + var child = new BookmarkablePageLink(iterationsView.newChildId(), + IterationIssuesPage.class, + IterationIssuesPage.paramsOf(getIssue().getProject(), schedule.getIteration())); + iterationsView.add(child); + child.add(new Label("name", schedule.getIteration().getName())); } - editLink.add(milestonesView); + editLink.add(iterationsView); } @Override @@ -95,7 +95,7 @@ public abstract class MilestoneCrumbPanel extends Panel { @Override public void renderHead(IHeaderResponse response) { super.renderHead(response); - response.render(CssHeaderItem.forReference(new MilestoneCrumbCssResourceReference())); + response.render(CssHeaderItem.forReference(new IterationCrumbCssResourceReference())); } protected abstract Issue getIssue(); diff --git a/server-core/src/main/java/io/onedev/server/web/component/issue/iteration/IterationsBean.java b/server-core/src/main/java/io/onedev/server/web/component/issue/iteration/IterationsBean.java new file mode 100644 index 0000000000..5ab64379b4 --- /dev/null +++ b/server-core/src/main/java/io/onedev/server/web/component/issue/iteration/IterationsBean.java @@ -0,0 +1,24 @@ +package io.onedev.server.web.component.issue.iteration; + +import io.onedev.server.annotation.Editable; +import io.onedev.server.annotation.IterationChoice; + +import java.io.Serializable; +import java.util.List; + +@Editable +public class IterationsBean implements Serializable { + + private List iterationNames; + + @Editable + @IterationChoice + public List getIterationNames() { + return iterationNames; + } + + public void setIterationNames(List iterationNames) { + this.iterationNames = iterationNames; + } + +} diff --git a/server-core/src/main/java/io/onedev/server/web/component/issue/milestone/milestone-crumb.css b/server-core/src/main/java/io/onedev/server/web/component/issue/iteration/iteration-crumb.css similarity index 73% rename from server-core/src/main/java/io/onedev/server/web/component/issue/milestone/milestone-crumb.css rename to server-core/src/main/java/io/onedev/server/web/component/issue/iteration/iteration-crumb.css index e97929e8d9..6f46484d25 100644 --- a/server-core/src/main/java/io/onedev/server/web/component/issue/milestone/milestone-crumb.css +++ b/server-core/src/main/java/io/onedev/server/web/component/issue/iteration/iteration-crumb.css @@ -1,8 +1,8 @@ -.milestone-crumb { +.iteration-crumb { cursor: pointer; border-bottom: 2px dotted transparent; padding: 0 0.5rem 0.5rem 0; } -.milestone-crumb:hover { +.iteration-crumb:hover { border-color: var(--gray); } diff --git a/server-core/src/main/java/io/onedev/server/web/component/issue/list/BatchEditPanel.html b/server-core/src/main/java/io/onedev/server/web/component/issue/list/BatchEditPanel.html index 71cc99aa19..62060aeb29 100644 --- a/server-core/src/main/java/io/onedev/server/web/component/issue/list/BatchEditPanel.html +++ b/server-core/src/main/java/io/onedev/server/web/component/issue/list/BatchEditPanel.html @@ -20,7 +20,7 @@ Confidential
-
-
Milestones
+
+
Iterations
    -
  • +
  • - +
    diff --git a/server-core/src/main/java/io/onedev/server/web/component/issue/side/IssueSidePanel.java b/server-core/src/main/java/io/onedev/server/web/component/issue/side/IssueSidePanel.java index 7cbe3254d7..9bd022f64d 100644 --- a/server-core/src/main/java/io/onedev/server/web/component/issue/side/IssueSidePanel.java +++ b/server-core/src/main/java/io/onedev/server/web/component/issue/side/IssueSidePanel.java @@ -31,9 +31,9 @@ import io.onedev.server.web.component.issue.fieldvalues.FieldValuesPanel; import io.onedev.server.web.component.issue.operation.TransitionMenuLink; import io.onedev.server.web.component.issue.statestats.StateStatsBar; import io.onedev.server.web.component.link.ViewStateAwarePageLink; -import io.onedev.server.web.component.milestone.MilestoneStatusLabel; -import io.onedev.server.web.component.milestone.choice.AbstractMilestoneChoiceProvider; -import io.onedev.server.web.component.milestone.choice.MilestoneChoiceResourceReference; +import io.onedev.server.web.component.iteration.IterationStatusLabel; +import io.onedev.server.web.component.iteration.choice.AbstractIterationChoiceProvider; +import io.onedev.server.web.component.iteration.choice.IterationChoiceResourceReference; import io.onedev.server.web.component.modal.ModalLink; import io.onedev.server.web.component.modal.ModalPanel; import io.onedev.server.web.component.select2.Response; @@ -45,7 +45,7 @@ import io.onedev.server.web.component.user.list.SimpleUserListLink; import io.onedev.server.web.editable.InplacePropertyEditLink; import io.onedev.server.web.page.base.BasePage; import io.onedev.server.web.page.project.issues.detail.IssueActivitiesPage; -import io.onedev.server.web.page.project.issues.milestones.MilestoneIssuesPage; +import io.onedev.server.web.page.project.issues.iteration.IterationIssuesPage; import io.onedev.server.web.page.simple.security.LoginPage; import org.apache.wicket.Component; import org.apache.wicket.RestartResponseAtInterceptPageException; @@ -111,7 +111,7 @@ public abstract class IssueSidePanel extends Panel { protected void onBeforeRender() { addOrReplace(newFieldsContainer()); addOrReplace(newConfidentialContainer()); - addOrReplace(newMilestonesContainer()); + addOrReplace(newIterationsContainer()); addOrReplace(newLinksContainer()); addOrReplace(newVotesContainer()); @@ -593,8 +593,8 @@ public abstract class IssueSidePanel extends Panel { } } - private Component newMilestonesContainer() { - WebMarkupContainer container = new WebMarkupContainer("milestones") { + private Component newIterationsContainer() { + WebMarkupContainer container = new WebMarkupContainer("iterations") { @Override protected void onConfigure() { @@ -604,24 +604,24 @@ public abstract class IssueSidePanel extends Panel { }; - container.add(new ListView("milestones", new AbstractReadOnlyModel>() { + container.add(new ListView("iterations", new AbstractReadOnlyModel>() { @Override - public List getObject() { - return getIssue().getMilestones().stream() - .sorted(new Milestone.DatesAndStatusComparator()) + public List getObject() { + return getIssue().getIterations().stream() + .sorted(new Iteration.DatesAndStatusComparator()) .collect(Collectors.toList()); } }) { @Override - protected void populateItem(ListItem item) { - Milestone milestone = item.getModelObject(); + protected void populateItem(ListItem item) { + Iteration iteration = item.getModelObject(); - Link link = new BookmarkablePageLink("link", MilestoneIssuesPage.class, - MilestoneIssuesPage.paramsOf(getIssue().getProject(), milestone, null)); - link.add(new Label("label", milestone.getName())); + Link link = new BookmarkablePageLink("link", IterationIssuesPage.class, + IterationIssuesPage.paramsOf(getIssue().getProject(), iteration, null)); + link.add(new Label("label", iteration.getName())); item.add(link); item.add(new StateStatsBar("progress", new AbstractReadOnlyModel>() { @@ -636,16 +636,16 @@ public abstract class IssueSidePanel extends Panel { @Override protected Link newStateLink(String componentId, String state) { String query = new IssueQuery(new StateCriteria(state, IssueQueryLexer.Is)).toString(); - PageParameters params = MilestoneIssuesPage.paramsOf(getIssue().getProject(), + PageParameters params = IterationIssuesPage.paramsOf(getIssue().getProject(), item.getModelObject(), query); - return new ViewStateAwarePageLink(componentId, MilestoneIssuesPage.class, params); + return new ViewStateAwarePageLink(componentId, IterationIssuesPage.class, params); } }); - item.add(new MilestoneStatusLabel("status", new AbstractReadOnlyModel() { + item.add(new IterationStatusLabel("status", new AbstractReadOnlyModel() { @Override - public Milestone getObject() { + public Iteration getObject() { return item.getModelObject(); } @@ -658,7 +658,7 @@ public abstract class IssueSidePanel extends Panel { super.updateAjaxAttributes(attributes); if (!getIssue().isNew()) { attributes.getAjaxCallListeners().add(new ConfirmClickListener("Do you really want to " - + "remove the issue from milestone '" + item.getModelObject().getName() + "'?")); + + "remove the issue from iteration '" + item.getModelObject().getName() + "'?")); } } @@ -679,22 +679,22 @@ public abstract class IssueSidePanel extends Panel { }); - container.add(new SelectToActChoice("add", new AbstractMilestoneChoiceProvider() { + container.add(new SelectToActChoice("add", new AbstractIterationChoiceProvider() { @Override - public void query(String term, int page, Response response) { - List milestones = getProject().getSortedHierarchyMilestones(); - milestones.removeAll(getIssue().getMilestones()); + public void query(String term, int page, Response response) { + List iterations = getProject().getSortedHierarchyIterations(); + iterations.removeAll(getIssue().getIterations()); - milestones = new Similarities(milestones) { + iterations = new Similarities(iterations) { @Override - public double getSimilarScore(Milestone object) { + public double getSimilarScore(Iteration object) { return Similarities.getSimilarScore(object.getName(), term); } }; - new ResponseFiller<>(response).fill(milestones, page, WebConstants.PAGE_SIZE); + new ResponseFiller<>(response).fill(iterations, page, WebConstants.PAGE_SIZE); } }) { @@ -703,10 +703,10 @@ public abstract class IssueSidePanel extends Panel { protected void onInitialize() { super.onInitialize(); - getSettings().setPlaceholder("Add to milestone..."); - getSettings().setFormatResult("onedev.server.milestoneChoiceFormatter.formatResult"); - getSettings().setFormatSelection("onedev.server.milestoneChoiceFormatter.formatSelection"); - getSettings().setEscapeMarkup("onedev.server.milestoneChoiceFormatter.escapeMarkup"); + getSettings().setPlaceholder("Add to iteration..."); + getSettings().setFormatResult("onedev.server.iterationChoiceFormatter.formatResult"); + getSettings().setFormatSelection("onedev.server.iterationChoiceFormatter.formatSelection"); + getSettings().setEscapeMarkup("onedev.server.iterationChoiceFormatter.escapeMarkup"); } @Override @@ -718,12 +718,12 @@ public abstract class IssueSidePanel extends Panel { @Override public void renderHead(IHeaderResponse response) { super.renderHead(response); - response.render(JavaScriptHeaderItem.forReference(new MilestoneChoiceResourceReference())); + response.render(JavaScriptHeaderItem.forReference(new IterationChoiceResourceReference())); } @Override - protected void onSelect(AjaxRequestTarget target, Milestone milestone) { - getIssueChangeManager().addSchedule(getIssue(), milestone); + protected void onSelect(AjaxRequestTarget target, Iteration iteration) { + getIssueChangeManager().addSchedule(getIssue(), iteration); notifyIssueChange(target, getIssue()); } diff --git a/server-core/src/main/java/io/onedev/server/web/component/issue/side/issue-side.css b/server-core/src/main/java/io/onedev/server/web/component/issue/side/issue-side.css index 48cf6408b7..3cdcda6f50 100644 --- a/server-core/src/main/java/io/onedev/server/web/component/issue/side/issue-side.css +++ b/server-core/src/main/java/io/onedev/server/web/component/issue/side/issue-side.css @@ -58,7 +58,7 @@ .issue-side>.fields .field-values.editable { border-color: transparent; } -.issue-side>.milestones li+li, .issue-side>.links li+li { +.issue-side>.iterations li+li, .issue-side>.links li+li { margin-top: 1.2rem; } diff --git a/server-core/src/main/java/io/onedev/server/web/component/issue/statestats/StateStatsBar.java b/server-core/src/main/java/io/onedev/server/web/component/issue/statestats/StateStatsBar.java index 64daa72006..9c63d03d5c 100644 --- a/server-core/src/main/java/io/onedev/server/web/component/issue/statestats/StateStatsBar.java +++ b/server-core/src/main/java/io/onedev/server/web/component/issue/statestats/StateStatsBar.java @@ -56,7 +56,7 @@ public abstract class StateStatsBar extends GenericPanel> { }.setEscapeModelStrings(false)); - add(AttributeAppender.append("title", "No issues in milestone")); + add(AttributeAppender.append("title", "No issues in iteration")); } setOutputMarkupId(true); diff --git a/server-core/src/main/java/io/onedev/server/web/component/milestone/MilestoneDateLabel.java b/server-core/src/main/java/io/onedev/server/web/component/iteration/IterationDateLabel.java similarity index 50% rename from server-core/src/main/java/io/onedev/server/web/component/milestone/MilestoneDateLabel.java rename to server-core/src/main/java/io/onedev/server/web/component/iteration/IterationDateLabel.java index 655650c783..2d30aa71ad 100644 --- a/server-core/src/main/java/io/onedev/server/web/component/milestone/MilestoneDateLabel.java +++ b/server-core/src/main/java/io/onedev/server/web/component/iteration/IterationDateLabel.java @@ -1,4 +1,4 @@ -package io.onedev.server.web.component.milestone; +package io.onedev.server.web.component.iteration; import java.util.Date; @@ -7,43 +7,43 @@ import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.model.IModel; import org.apache.wicket.model.LoadableDetachableModel; -import io.onedev.server.model.Milestone; +import io.onedev.server.model.Iteration; import io.onedev.server.util.DateUtils; import io.onedev.server.web.component.svg.SpriteImage; @SuppressWarnings("serial") -public class MilestoneDateLabel extends Label { +public class IterationDateLabel extends Label { - private final IModel milestoneModel; + private final IModel iterationIModel; - public MilestoneDateLabel(String id, IModel milestoneModel) { + public IterationDateLabel(String id, IModel iterationIModel) { super(id, new LoadableDetachableModel() { @Override protected String load() { String arrow = ""; - Milestone milestone = milestoneModel.getObject(); - if (milestone.getStartDate() != null && milestone.getDueDate() != null) { + Iteration iteration = iterationIModel.getObject(); + if (iteration.getStartDate() != null && iteration.getDueDate() != null) { return "" - + "" + DateUtils.formatDate(milestone.getStartDate()) + "" + + "" + DateUtils.formatDate(iteration.getStartDate()) + "" + " " + arrow + " " - + "" + DateUtils.formatDate(milestone.getDueDate()) + ""; - } else if (milestone.getStartDate() != null) { - return "" + DateUtils.formatDate(milestone.getStartDate()) + " " + arrow; - } else if (milestone.getDueDate() != null) { - return arrow + " " + DateUtils.formatDate(milestone.getDueDate()) + ""; + + "" + DateUtils.formatDate(iteration.getDueDate()) + ""; + } else if (iteration.getStartDate() != null) { + return "" + DateUtils.formatDate(iteration.getStartDate()) + " " + arrow; + } else if (iteration.getDueDate() != null) { + return arrow + " " + DateUtils.formatDate(iteration.getDueDate()) + ""; } else { return " No Start/Due Date"; } } }); - this.milestoneModel = milestoneModel; + this.iterationIModel = iterationIModel; } @Override protected void onDetach() { - milestoneModel.detach(); + iterationIModel.detach(); super.onDetach(); } @@ -55,23 +55,23 @@ public class MilestoneDateLabel extends Label { @Override protected String load() { - Milestone milestone = milestoneModel.getObject(); - if (!milestone.isClosed()) { + Iteration iteration = iterationIModel.getObject(); + if (!iteration.isClosed()) { Date now = new Date(); - if (milestone.getStartDate() != null && milestone.getDueDate() != null) { - if (now.before(milestone.getStartDate())) + if (iteration.getStartDate() != null && iteration.getDueDate() != null) { + if (now.before(iteration.getStartDate())) return "text-info"; - else if (now.after(milestone.getStartDate()) && now.before(milestone.getDueDate())) + else if (now.after(iteration.getStartDate()) && now.before(iteration.getDueDate())) return "text-warning"; else return "text-danger"; - } else if (milestone.getStartDate() != null) { - if (now.before(milestone.getStartDate())) + } else if (iteration.getStartDate() != null) { + if (now.before(iteration.getStartDate())) return "text-info"; else return "text-warning"; - } else if (milestone.getDueDate() != null) { - if (now.before(milestone.getDueDate())) + } else if (iteration.getDueDate() != null) { + if (now.before(iteration.getDueDate())) return "text-info"; else return "text-danger"; diff --git a/server-core/src/main/java/io/onedev/server/web/component/milestone/MilestoneStatusLabel.java b/server-core/src/main/java/io/onedev/server/web/component/iteration/IterationStatusLabel.java similarity index 60% rename from server-core/src/main/java/io/onedev/server/web/component/milestone/MilestoneStatusLabel.java rename to server-core/src/main/java/io/onedev/server/web/component/iteration/IterationStatusLabel.java index 5623ea220c..0d1993a61f 100644 --- a/server-core/src/main/java/io/onedev/server/web/component/milestone/MilestoneStatusLabel.java +++ b/server-core/src/main/java/io/onedev/server/web/component/iteration/IterationStatusLabel.java @@ -1,4 +1,4 @@ -package io.onedev.server.web.component.milestone; +package io.onedev.server.web.component.iteration; import org.apache.wicket.behavior.AttributeAppender; import org.apache.wicket.markup.html.basic.Label; @@ -6,28 +6,28 @@ import org.apache.wicket.model.AbstractReadOnlyModel; import org.apache.wicket.model.IModel; import org.apache.wicket.model.LoadableDetachableModel; -import io.onedev.server.model.Milestone; +import io.onedev.server.model.Iteration; @SuppressWarnings("serial") -public class MilestoneStatusLabel extends Label { +public class IterationStatusLabel extends Label { - private final IModel milestoneModel; + private final IModel iterationModel; - public MilestoneStatusLabel(String id, IModel milestoneModel) { + public IterationStatusLabel(String id, IModel iterationModel) { super(id, new LoadableDetachableModel() { @Override protected String load() { - return milestoneModel.getObject().getStatusName(); + return iterationModel.getObject().getStatusName(); } }); - this.milestoneModel = milestoneModel; + this.iterationModel = iterationModel; } @Override protected void onDetach() { - milestoneModel.detach(); + iterationModel.detach(); super.onDetach(); } @@ -38,7 +38,7 @@ public class MilestoneStatusLabel extends Label { @Override public String getObject() { - return "badge badge-" + (milestoneModel.getObject().isClosed()? "success": "warning"); + return "badge badge-" + (iterationModel.getObject().isClosed()? "success": "warning"); } })); diff --git a/server-core/src/main/java/io/onedev/server/web/component/iteration/actions/IterationActionsPanel.html b/server-core/src/main/java/io/onedev/server/web/component/iteration/actions/IterationActionsPanel.html new file mode 100644 index 0000000000..4a13abb95d --- /dev/null +++ b/server-core/src/main/java/io/onedev/server/web/component/iteration/actions/IterationActionsPanel.html @@ -0,0 +1,10 @@ + + + Reopen + Close + + Edit + + Delete + + \ No newline at end of file diff --git a/server-core/src/main/java/io/onedev/server/web/component/milestone/actions/MilestoneActionsPanel.java b/server-core/src/main/java/io/onedev/server/web/component/iteration/actions/IterationActionsPanel.java similarity index 54% rename from server-core/src/main/java/io/onedev/server/web/component/milestone/actions/MilestoneActionsPanel.java rename to server-core/src/main/java/io/onedev/server/web/component/iteration/actions/IterationActionsPanel.java index b0371d7897..02fff7d705 100644 --- a/server-core/src/main/java/io/onedev/server/web/component/milestone/actions/MilestoneActionsPanel.java +++ b/server-core/src/main/java/io/onedev/server/web/component/iteration/actions/IterationActionsPanel.java @@ -1,4 +1,4 @@ -package io.onedev.server.web.component.milestone.actions; +package io.onedev.server.web.component.iteration.actions; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.attributes.AjaxRequestAttributes; @@ -8,19 +8,19 @@ import org.apache.wicket.markup.html.panel.GenericPanel; import org.apache.wicket.model.IModel; import io.onedev.server.OneDev; -import io.onedev.server.entitymanager.MilestoneManager; -import io.onedev.server.model.Milestone; +import io.onedev.server.entitymanager.IterationManager; +import io.onedev.server.model.Iteration; import io.onedev.server.web.ajaxlistener.ConfirmClickListener; -import io.onedev.server.web.page.project.issues.milestones.MilestoneEditPage; +import io.onedev.server.web.page.project.issues.iteration.IterationEditPage; @SuppressWarnings("serial") -public abstract class MilestoneActionsPanel extends GenericPanel { +public abstract class IterationActionsPanel extends GenericPanel { - public MilestoneActionsPanel(String id, IModel model) { + public IterationActionsPanel(String id, IModel model) { super(id, model); } - private Milestone getMilestone() { + private Iteration getIteration() { return getModelObject(); } @@ -32,17 +32,17 @@ public abstract class MilestoneActionsPanel extends GenericPanel { @Override public void onClick(AjaxRequestTarget target) { - getMilestone().setClosed(false); - getMilestoneManager().createOrUpdate(getMilestone()); - target.add(MilestoneActionsPanel.this); + getIteration().setClosed(false); + getIterationManager().createOrUpdate(getIteration()); + target.add(IterationActionsPanel.this); onUpdated(target); - getSession().success("Milestone '" + getMilestone().getName() + "' reopened"); + getSession().success("Iteratioin '" + getIteration().getName() + "' reopened"); } @Override protected void onConfigure() { super.onConfigure(); - setVisible(getMilestone().isClosed()); + setVisible(getIteration().isClosed()); } }); @@ -52,22 +52,22 @@ public abstract class MilestoneActionsPanel extends GenericPanel { @Override protected void onConfigure() { super.onConfigure(); - setVisible(!getMilestone().isClosed()); + setVisible(!getIteration().isClosed()); } @Override public void onClick(AjaxRequestTarget target) { - getMilestone().setClosed(true); - getMilestoneManager().createOrUpdate(getMilestone()); - target.add(MilestoneActionsPanel.this); + getIteration().setClosed(true); + getIterationManager().createOrUpdate(getIteration()); + target.add(IterationActionsPanel.this); onUpdated(target); - getSession().success("Milestone '" + getMilestone().getName() + "' closed"); + getSession().success("Iteration '" + getIteration().getName() + "' closed"); } }); - add(new BookmarkablePageLink("edit", MilestoneEditPage.class, - MilestoneEditPage.paramsOf(getMilestone()))); + add(new BookmarkablePageLink("edit", IterationEditPage.class, + IterationEditPage.paramsOf(getIteration()))); add(new AjaxLink("delete") { @@ -75,15 +75,15 @@ public abstract class MilestoneActionsPanel extends GenericPanel { protected void updateAjaxAttributes(AjaxRequestAttributes attributes) { super.updateAjaxAttributes(attributes); attributes.getAjaxCallListeners().add(new ConfirmClickListener( - "Do you really want to delete milestone '" + getMilestone().getName() + "'?")); + "Do you really want to delete iteration '" + getIteration().getName() + "'?")); } @Override public void onClick(AjaxRequestTarget target) { - getMilestoneManager().delete(getMilestone()); - target.add(MilestoneActionsPanel.this); + getIterationManager().delete(getIteration()); + target.add(IterationActionsPanel.this); onDeleted(target); - getSession().success("Milestone '" + getMilestone().getName() + "' deleted"); + getSession().success("Iteration '" + getIteration().getName() + "' deleted"); } }); @@ -91,8 +91,8 @@ public abstract class MilestoneActionsPanel extends GenericPanel { setOutputMarkupId(true); } - private MilestoneManager getMilestoneManager() { - return OneDev.getInstance(MilestoneManager.class); + private IterationManager getIterationManager() { + return OneDev.getInstance(IterationManager.class); } protected abstract void onDeleted(AjaxRequestTarget target); diff --git a/server-core/src/main/java/io/onedev/server/web/component/milestone/burndown/BurndownIndicators.java b/server-core/src/main/java/io/onedev/server/web/component/iteration/burndown/BurndownIndicators.java similarity index 96% rename from server-core/src/main/java/io/onedev/server/web/component/milestone/burndown/BurndownIndicators.java rename to server-core/src/main/java/io/onedev/server/web/component/iteration/burndown/BurndownIndicators.java index 225b5bbae0..c4aa58cd02 100644 --- a/server-core/src/main/java/io/onedev/server/web/component/milestone/burndown/BurndownIndicators.java +++ b/server-core/src/main/java/io/onedev/server/web/component/iteration/burndown/BurndownIndicators.java @@ -1,4 +1,4 @@ -package io.onedev.server.web.component.milestone.burndown; +package io.onedev.server.web.component.iteration.burndown; import io.onedev.server.OneDev; import io.onedev.server.buildspecmodel.inputspec.InputSpec; diff --git a/server-core/src/main/java/io/onedev/server/web/component/milestone/burndown/MilestoneBurndownPanel.html b/server-core/src/main/java/io/onedev/server/web/component/iteration/burndown/IterationBurndownPanel.html similarity index 100% rename from server-core/src/main/java/io/onedev/server/web/component/milestone/burndown/MilestoneBurndownPanel.html rename to server-core/src/main/java/io/onedev/server/web/component/iteration/burndown/IterationBurndownPanel.html diff --git a/server-core/src/main/java/io/onedev/server/web/component/milestone/burndown/MilestoneBurndownPanel.java b/server-core/src/main/java/io/onedev/server/web/component/iteration/burndown/IterationBurndownPanel.java similarity index 85% rename from server-core/src/main/java/io/onedev/server/web/component/milestone/burndown/MilestoneBurndownPanel.java rename to server-core/src/main/java/io/onedev/server/web/component/iteration/burndown/IterationBurndownPanel.java index 78d6d4e712..c5f0a999da 100644 --- a/server-core/src/main/java/io/onedev/server/web/component/milestone/burndown/MilestoneBurndownPanel.java +++ b/server-core/src/main/java/io/onedev/server/web/component/iteration/burndown/IterationBurndownPanel.java @@ -1,18 +1,17 @@ -package io.onedev.server.web.component.milestone.burndown; +package io.onedev.server.web.component.iteration.burndown; import io.onedev.server.OneDev; import io.onedev.server.xodus.IssueInfoManager; import io.onedev.server.entitymanager.SettingManager; import io.onedev.server.model.Issue; import io.onedev.server.model.IssueSchedule; -import io.onedev.server.model.Milestone; +import io.onedev.server.model.Iteration; import io.onedev.server.model.support.administration.GlobalIssueSetting; import io.onedev.server.model.support.issue.StateSpec; import io.onedev.server.model.support.issue.field.spec.WorkingPeriodField; import io.onedev.server.web.component.chart.line.Line; import io.onedev.server.web.component.chart.line.LineChartPanel; import io.onedev.server.web.component.chart.line.LineSeries; -import org.apache.wicket.behavior.AttributeAppender; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.panel.Fragment; import org.apache.wicket.markup.html.panel.GenericPanel; @@ -25,16 +24,16 @@ import java.time.LocalDate; import java.util.*; import static io.onedev.server.util.DateUtils.toLocalDate; -import static io.onedev.server.web.component.milestone.burndown.BurndownIndicators.*; +import static io.onedev.server.web.component.iteration.burndown.BurndownIndicators.*; -public class MilestoneBurndownPanel extends GenericPanel { +public class IterationBurndownPanel extends GenericPanel { private static final int MAX_DAYS = 365; private final String indicator; - public MilestoneBurndownPanel(String id, IModel milestoneModel, @Nullable String indicator) { - super(id, milestoneModel); + public IterationBurndownPanel(String id, IModel iterationModel, @Nullable String indicator) { + super(id, iterationModel); this.indicator = indicator; } @@ -47,17 +46,17 @@ public class MilestoneBurndownPanel extends GenericPanel { super.onInitialize(); String message = null; - if (getMilestone().getStartDate() != null && getMilestone().getDueDate() != null) { - if (getMilestone().getStartDate().before(getMilestone().getDueDate())) { - long startDay = toLocalDate(getMilestone().getStartDate()).toEpochDay(); - long dueDay = toLocalDate(getMilestone().getDueDate()).toEpochDay(); + if (getIteration().getStartDate() != null && getIteration().getDueDate() != null) { + if (getIteration().getStartDate().before(getIteration().getDueDate())) { + long startDay = toLocalDate(getIteration().getStartDate()).toEpochDay(); + long dueDay = toLocalDate(getIteration().getDueDate()).toEpochDay(); if (dueDay - startDay >= MAX_DAYS) - message = "Milestone spans too long to show burndown chart"; + message = "Iteration spans too long to show burndown chart"; } else { - message = "Milestone start date should be before due date"; + message = "Iteration start date should be before due date"; } } else { - message = "Milestone start and due date should be specified to show burndown chart"; + message = "Iteration start and due date should be specified to show burndown chart"; } if (message != null) { var fragment = new Fragment("content", "messageFrag", this); @@ -73,11 +72,11 @@ public class MilestoneBurndownPanel extends GenericPanel { @Override protected LineSeries load() { - long startDay = toLocalDate(getMilestone().getStartDate()).toEpochDay(); - long dueDay = toLocalDate(getMilestone().getDueDate()).toEpochDay(); + long startDay = toLocalDate(getIteration().getStartDate()).toEpochDay(); + long dueDay = toLocalDate(getIteration().getDueDate()).toEpochDay(); Map> dailyStateMetrics = new LinkedHashMap<>(); - for (IssueSchedule schedule : getMilestone().getSchedules()) { + for (IssueSchedule schedule : getIteration().getSchedules()) { Issue issue = schedule.getIssue(); long scheduleDay = toLocalDate(schedule.getDate()).toEpochDay(); @@ -186,7 +185,7 @@ public class MilestoneBurndownPanel extends GenericPanel { if (indicator != null) return indicator; else - return getDefault(getMilestone().getProject()); + return getDefault(getIteration().getProject()); } private int getIndicatorValue(Issue issue) { @@ -207,7 +206,7 @@ public class MilestoneBurndownPanel extends GenericPanel { } } - private Milestone getMilestone() { + private Iteration getIteration() { return getModelObject(); } diff --git a/server-core/src/main/java/io/onedev/server/web/component/milestone/choice/AbstractMilestoneChoiceProvider.java b/server-core/src/main/java/io/onedev/server/web/component/iteration/choice/AbstractIterationChoiceProvider.java similarity index 53% rename from server-core/src/main/java/io/onedev/server/web/component/milestone/choice/AbstractMilestoneChoiceProvider.java rename to server-core/src/main/java/io/onedev/server/web/component/iteration/choice/AbstractIterationChoiceProvider.java index 6124d8df9d..6e8cfe3d21 100644 --- a/server-core/src/main/java/io/onedev/server/web/component/milestone/choice/AbstractMilestoneChoiceProvider.java +++ b/server-core/src/main/java/io/onedev/server/web/component/iteration/choice/AbstractIterationChoiceProvider.java @@ -1,4 +1,4 @@ -package io.onedev.server.web.component.milestone.choice; +package io.onedev.server.web.component.iteration.choice; import java.util.Collection; import java.util.List; @@ -11,16 +11,16 @@ import org.unbescape.html.HtmlEscape; import com.google.common.collect.Lists; import io.onedev.server.OneDev; -import io.onedev.server.entitymanager.MilestoneManager; -import io.onedev.server.model.Milestone; +import io.onedev.server.entitymanager.IterationManager; +import io.onedev.server.model.Iteration; import io.onedev.server.web.component.select2.ChoiceProvider; -public abstract class AbstractMilestoneChoiceProvider extends ChoiceProvider { +public abstract class AbstractIterationChoiceProvider extends ChoiceProvider { private static final long serialVersionUID = 1L; @Override - public void toJson(Milestone choice, JSONWriter writer) throws JSONException { + public void toJson(Iteration choice, JSONWriter writer) throws JSONException { writer.key("id").value(choice.getId()).key("name").value(HtmlEscape.escapeHtml5(choice.getName())); writer.key("statusName").value(choice.getStatusName()); if (choice.isClosed()) @@ -30,16 +30,16 @@ public abstract class AbstractMilestoneChoiceProvider extends ChoiceProvider toChoices(Collection ids) { - List milestones = Lists.newArrayList(); - MilestoneManager milestoneManager = OneDev.getInstance(MilestoneManager.class); + public Collection toChoices(Collection ids) { + List iterations = Lists.newArrayList(); + IterationManager iterationManager = OneDev.getInstance(IterationManager.class); for (String each : ids) { - Milestone milestone = milestoneManager.load(Long.valueOf(each)); - Hibernate.initialize(milestone); - milestones.add(milestone); + Iteration iteration = iterationManager.load(Long.valueOf(each)); + Hibernate.initialize(iteration); + iterations.add(iteration); } - return milestones; + return iterations; } } \ No newline at end of file diff --git a/server-core/src/main/java/io/onedev/server/web/component/milestone/choice/MilestoneChoiceProvider.java b/server-core/src/main/java/io/onedev/server/web/component/iteration/choice/IterationChoiceProvider.java similarity index 57% rename from server-core/src/main/java/io/onedev/server/web/component/milestone/choice/MilestoneChoiceProvider.java rename to server-core/src/main/java/io/onedev/server/web/component/iteration/choice/IterationChoiceProvider.java index cfba75fd59..4a8a22afbc 100644 --- a/server-core/src/main/java/io/onedev/server/web/component/milestone/choice/MilestoneChoiceProvider.java +++ b/server-core/src/main/java/io/onedev/server/web/component/iteration/choice/IterationChoiceProvider.java @@ -1,23 +1,23 @@ -package io.onedev.server.web.component.milestone.choice; +package io.onedev.server.web.component.iteration.choice; import java.util.Collection; import java.util.List; import org.apache.wicket.model.IModel; -import io.onedev.server.model.Milestone; +import io.onedev.server.model.Iteration; import io.onedev.server.util.Similarities; import io.onedev.server.web.WebConstants; import io.onedev.server.web.component.select2.Response; import io.onedev.server.web.component.select2.ResponseFiller; -public class MilestoneChoiceProvider extends AbstractMilestoneChoiceProvider { +public class IterationChoiceProvider extends AbstractIterationChoiceProvider { private static final long serialVersionUID = 1L; - private final IModel> choicesModel; + private final IModel> choicesModel; - public MilestoneChoiceProvider(IModel> choicesModel) { + public IterationChoiceProvider(IModel> choicesModel) { this.choicesModel = choicesModel; } @@ -28,18 +28,18 @@ public class MilestoneChoiceProvider extends AbstractMilestoneChoiceProvider { } @Override - public void query(String term, int page, Response response) { - List milestones = new Similarities(choicesModel.getObject()) { + public void query(String term, int page, Response response) { + List iterations = new Similarities(choicesModel.getObject()) { private static final long serialVersionUID = 1L; @Override - public double getSimilarScore(Milestone object) { + public double getSimilarScore(Iteration object) { return Similarities.getSimilarScore(object.getName(), term); } }; - new ResponseFiller(response).fill(milestones, page, WebConstants.PAGE_SIZE); + new ResponseFiller(response).fill(iterations, page, WebConstants.PAGE_SIZE); } } \ No newline at end of file diff --git a/server-core/src/main/java/io/onedev/server/web/component/milestone/choice/MilestoneChoiceResourceReference.java b/server-core/src/main/java/io/onedev/server/web/component/iteration/choice/IterationChoiceResourceReference.java similarity index 62% rename from server-core/src/main/java/io/onedev/server/web/component/milestone/choice/MilestoneChoiceResourceReference.java rename to server-core/src/main/java/io/onedev/server/web/component/iteration/choice/IterationChoiceResourceReference.java index fce0bead40..e16005ce53 100644 --- a/server-core/src/main/java/io/onedev/server/web/component/milestone/choice/MilestoneChoiceResourceReference.java +++ b/server-core/src/main/java/io/onedev/server/web/component/iteration/choice/IterationChoiceResourceReference.java @@ -1,4 +1,4 @@ -package io.onedev.server.web.component.milestone.choice; +package io.onedev.server.web.component.iteration.choice; import java.util.List; @@ -8,19 +8,19 @@ import org.apache.wicket.request.resource.CssResourceReference; import io.onedev.server.web.page.base.BaseDependentResourceReference; -public class MilestoneChoiceResourceReference extends BaseDependentResourceReference { +public class IterationChoiceResourceReference extends BaseDependentResourceReference { private static final long serialVersionUID = 1L; - public MilestoneChoiceResourceReference() { - super(MilestoneChoiceResourceReference.class, "milestone-choice.js"); + public IterationChoiceResourceReference() { + super(IterationChoiceResourceReference.class, "iteration-choice.js"); } @Override public List getDependencies() { List dependencies = super.getDependencies(); dependencies.add(CssHeaderItem.forReference( - new CssResourceReference(MilestoneChoiceResourceReference.class, "milestone-choice.css"))); + new CssResourceReference(IterationChoiceResourceReference.class, "iteration-choice.css"))); return dependencies; } diff --git a/server-core/src/main/java/io/onedev/server/web/component/iteration/choice/IterationMultiChoice.java b/server-core/src/main/java/io/onedev/server/web/component/iteration/choice/IterationMultiChoice.java new file mode 100644 index 0000000000..873b0d9a32 --- /dev/null +++ b/server-core/src/main/java/io/onedev/server/web/component/iteration/choice/IterationMultiChoice.java @@ -0,0 +1,40 @@ +package io.onedev.server.web.component.iteration.choice; + +import java.util.Collection; + +import org.apache.wicket.markup.head.IHeaderResponse; +import org.apache.wicket.markup.head.JavaScriptHeaderItem; +import org.apache.wicket.model.IModel; + +import io.onedev.server.model.Iteration; +import io.onedev.server.web.component.select2.Select2MultiChoice; + +public class IterationMultiChoice extends Select2MultiChoice { + + private static final long serialVersionUID = 1L; + + public IterationMultiChoice(String id, IModel> selectionsModel, IModel>choicesModel) { + super(id, selectionsModel, new IterationChoiceProvider(choicesModel)); + } + + @Override + protected void onInitialize() { + super.onInitialize(); + if (isRequired()) + getSettings().setPlaceholder("Choose iterations..."); + else + getSettings().setPlaceholder("Not specified"); + getSettings().setFormatResult("onedev.server.iterationChoiceFormatter.formatResult"); + getSettings().setFormatSelection("onedev.server.iterationChoiceFormatter.formatSelection"); + getSettings().setEscapeMarkup("onedev.server.iterationChoiceFormatter.escapeMarkup"); + setConvertEmptyInputStringToNull(true); + } + + @Override + public void renderHead(IHeaderResponse response) { + super.renderHead(response); + + response.render(JavaScriptHeaderItem.forReference(new IterationChoiceResourceReference())); + } + +} diff --git a/server-core/src/main/java/io/onedev/server/web/component/iteration/choice/IterationSingleChoice.java b/server-core/src/main/java/io/onedev/server/web/component/iteration/choice/IterationSingleChoice.java new file mode 100644 index 0000000000..9eb0e6d0c3 --- /dev/null +++ b/server-core/src/main/java/io/onedev/server/web/component/iteration/choice/IterationSingleChoice.java @@ -0,0 +1,41 @@ +package io.onedev.server.web.component.iteration.choice; + +import java.util.Collection; + +import org.apache.wicket.markup.head.IHeaderResponse; +import org.apache.wicket.markup.head.JavaScriptHeaderItem; +import org.apache.wicket.model.IModel; + +import io.onedev.server.model.Iteration; +import io.onedev.server.web.component.select2.Select2Choice; + +@SuppressWarnings("serial") +public class IterationSingleChoice extends Select2Choice { + + public IterationSingleChoice(String id, IModel selectionModel, IModel> iterationsModel) { + super(id, selectionModel, new IterationChoiceProvider(iterationsModel)); + } + + @Override + protected void onInitialize() { + super.onInitialize(); + + getSettings().setAllowClear(!isRequired()); + if (isRequired()) + getSettings().setPlaceholder("Choose iteration..."); + else + getSettings().setPlaceholder("Not specified"); + getSettings().setFormatResult("onedev.server.iterationChoiceFormatter.formatResult"); + getSettings().setFormatSelection("onedev.server.iterationChoiceFormatter.formatSelection"); + getSettings().setEscapeMarkup("onedev.server.iterationChoiceFormatter.escapeMarkup"); + setConvertEmptyInputStringToNull(true); + } + + @Override + public void renderHead(IHeaderResponse response) { + super.renderHead(response); + + response.render(JavaScriptHeaderItem.forReference(new IterationChoiceResourceReference())); + } + +} diff --git a/server-core/src/main/java/io/onedev/server/web/component/iteration/choice/iteration-choice.css b/server-core/src/main/java/io/onedev/server/web/component/iteration/choice/iteration-choice.css new file mode 100644 index 0000000000..7513d746dd --- /dev/null +++ b/server-core/src/main/java/io/onedev/server/web/component/iteration/choice/iteration-choice.css @@ -0,0 +1,3 @@ +.select2-results .iteration .label { + margin-left: 6px; +} diff --git a/server-core/src/main/java/io/onedev/server/web/component/iteration/choice/iteration-choice.js b/server-core/src/main/java/io/onedev/server/web/component/iteration/choice/iteration-choice.js new file mode 100644 index 0000000000..53236fbf4e --- /dev/null +++ b/server-core/src/main/java/io/onedev/server/web/component/iteration/choice/iteration-choice.js @@ -0,0 +1,14 @@ +onedev.server.iterationChoiceFormatter = { + formatSelection: function(iteration) { + return iteration.name; + }, + + formatResult: function(iteration) { + return "" + iteration.name + " " + iteration.statusName + ""; + }, + + escapeMarkup: function(m) { + return m; + }, + +}; diff --git a/server-core/src/main/java/io/onedev/server/web/component/milestone/list/MilestoneListPanel.html b/server-core/src/main/java/io/onedev/server/web/component/iteration/list/IterationListPanel.html similarity index 85% rename from server-core/src/main/java/io/onedev/server/web/component/milestone/list/MilestoneListPanel.html rename to server-core/src/main/java/io/onedev/server/web/component/iteration/list/IterationListPanel.html index 570c2cd5dc..db24c10133 100644 --- a/server-core/src/main/java/io/onedev/server/web/component/milestone/list/MilestoneListPanel.html +++ b/server-core/src/main/java/io/onedev/server/web/component/iteration/list/IterationListPanel.html @@ -1,5 +1,5 @@ -
    +
    @@ -9,9 +9,9 @@ - +
    -
    +
    diff --git a/server-core/src/main/java/io/onedev/server/web/component/milestone/list/MilestoneListPanel.java b/server-core/src/main/java/io/onedev/server/web/component/iteration/list/IterationListPanel.java similarity index 66% rename from server-core/src/main/java/io/onedev/server/web/component/milestone/list/MilestoneListPanel.java rename to server-core/src/main/java/io/onedev/server/web/component/iteration/list/IterationListPanel.java index a296e494a4..0922796de0 100644 --- a/server-core/src/main/java/io/onedev/server/web/component/milestone/list/MilestoneListPanel.java +++ b/server-core/src/main/java/io/onedev/server/web/component/iteration/list/IterationListPanel.java @@ -1,9 +1,9 @@ -package io.onedev.server.web.component.milestone.list; +package io.onedev.server.web.component.iteration.list; import io.onedev.server.OneDev; import io.onedev.server.entitymanager.IssueManager; -import io.onedev.server.entitymanager.MilestoneManager; -import io.onedev.server.model.Milestone; +import io.onedev.server.entitymanager.IterationManager; +import io.onedev.server.model.Iteration; import io.onedev.server.model.Project; import io.onedev.server.persistence.dao.Dao; import io.onedev.server.persistence.dao.EntityCriteria; @@ -11,8 +11,8 @@ import io.onedev.server.search.entity.issue.IssueQuery; import io.onedev.server.search.entity.issue.IssueQueryLexer; import io.onedev.server.search.entity.issue.StateCriteria; import io.onedev.server.security.SecurityUtils; -import io.onedev.server.util.MilestoneAndIssueState; -import io.onedev.server.util.MilestoneSort; +import io.onedev.server.util.IterationAndIssueState; +import io.onedev.server.util.IterationSort; import io.onedev.server.web.WebConstants; import io.onedev.server.web.WebSession; import io.onedev.server.web.component.datatable.DefaultDataTable; @@ -22,10 +22,10 @@ import io.onedev.server.web.component.link.ActionablePageLink; import io.onedev.server.web.component.link.ViewStateAwarePageLink; import io.onedev.server.web.component.menu.MenuItem; import io.onedev.server.web.component.menu.MenuLink; -import io.onedev.server.web.component.milestone.MilestoneDateLabel; -import io.onedev.server.web.component.milestone.actions.MilestoneActionsPanel; -import io.onedev.server.web.page.project.issues.milestones.MilestoneIssuesPage; -import io.onedev.server.web.page.project.issues.milestones.NewMilestonePage; +import io.onedev.server.web.component.iteration.IterationDateLabel; +import io.onedev.server.web.component.iteration.actions.IterationActionsPanel; +import io.onedev.server.web.page.project.issues.iteration.IterationIssuesPage; +import io.onedev.server.web.page.project.issues.iteration.NewIterationPage; import io.onedev.server.web.util.LoadableDetachableDataProvider; import io.onedev.server.web.util.PagingHistorySupport; import org.apache.wicket.Component; @@ -56,40 +56,40 @@ import javax.annotation.Nullable; import java.util.*; @SuppressWarnings("serial") -public class MilestoneListPanel extends GenericPanel { +public class IterationListPanel extends GenericPanel { private boolean closed; - private MilestoneSort sort; + private IterationSort sort; private final PagingHistorySupport pagingHistorySupport; - private final IModel> milestoneAndStatesModel = + private final IModel> iterationAndStatesModel = new LoadableDetachableModel<>() { @Override - protected Collection load() { - List milestones = new ArrayList<>(); - for (Component row : (WebMarkupContainer) milestonesTable.get("body").get("rows")) { - Milestone milestone = (Milestone) row.getDefaultModelObject(); - milestones.add(milestone); + protected Collection load() { + List iterations = new ArrayList<>(); + for (Component row : (WebMarkupContainer) iterationsTable.get("body").get("rows")) { + Iteration iteration = (Iteration) row.getDefaultModelObject(); + iterations.add(iteration); } - return OneDev.getInstance(IssueManager.class).queryMilestoneAndIssueStates(getProject(), milestones); + return OneDev.getInstance(IssueManager.class).queryIterationAndIssueStates(getProject(), iterations); } }; - private DataTable milestonesTable; + private DataTable iterationsTable; - private EntityCriteria getCriteria(boolean closed) { - EntityCriteria criteria = EntityCriteria.of(Milestone.class); + private EntityCriteria getCriteria(boolean closed) { + EntityCriteria criteria = EntityCriteria.of(Iteration.class); criteria.add(Restrictions.in("project", getProject().getSelfAndAncestors())); criteria.add(Restrictions.eq("closed", closed)); return criteria; } - public MilestoneListPanel(String id, IModel model, boolean closed, MilestoneSort sort, - @Nullable PagingHistorySupport pagingHistorySupport) { + public IterationListPanel(String id, IModel model, boolean closed, IterationSort sort, + @Nullable PagingHistorySupport pagingHistorySupport) { super(id, model); this.closed = closed; @@ -111,7 +111,7 @@ public class MilestoneListPanel extends GenericPanel { public void onClick(AjaxRequestTarget target) { closed = false; target.add(statesContainer); - target.add(milestonesTable); + target.add(iterationsTable); onStateChanged(target, closed); } @@ -132,7 +132,7 @@ public class MilestoneListPanel extends GenericPanel { public void onClick(AjaxRequestTarget target) { closed = true; target.add(statesContainer); - target.add(milestonesTable); + target.add(iterationsTable); onStateChanged(target, closed); } @@ -152,7 +152,7 @@ public class MilestoneListPanel extends GenericPanel { @Override protected List getMenuItems(FloatingPanel dropdown) { List menuItems = new ArrayList<>(); - for (MilestoneSort sort: MilestoneSort.values()) { + for (IterationSort sort: IterationSort.values()) { menuItems.add(new MenuItem() { @Override @@ -162,7 +162,7 @@ public class MilestoneListPanel extends GenericPanel { @Override public String getIconHref() { - if (sort == MilestoneListPanel.this.sort) + if (sort == IterationListPanel.this.sort) return "tick"; else return null; @@ -175,14 +175,14 @@ public class MilestoneListPanel extends GenericPanel { @Override public void onClick(AjaxRequestTarget target) { dropdown.close(); - target.add(milestonesTable); - MilestoneListPanel.this.sort = sort; + target.add(iterationsTable); + IterationListPanel.this.sort = sort; onSortChanged(target, sort); } }; - link.add(AttributeAppender.append("class", "milestone-sort")); - if (sort == MilestoneListPanel.this.sort) + link.add(AttributeAppender.append("class", "iteration-sort")); + if (sort == IterationListPanel.this.sort) link.add(AttributeAppender.append("class", "active")); return link; } @@ -194,7 +194,7 @@ public class MilestoneListPanel extends GenericPanel { }); - add(new BookmarkablePageLink("newMilestone", NewMilestonePage.class, NewMilestonePage.paramsOf(getProject())) { + add(new BookmarkablePageLink("newIteration", NewIterationPage.class, NewIterationPage.paramsOf(getProject())) { @Override protected void onConfigure() { @@ -204,7 +204,7 @@ public class MilestoneListPanel extends GenericPanel { }); - List> columns = new ArrayList<>(); + List> columns = new ArrayList<>(); columns.add(new AbstractColumn<>(Model.of("Name")) { @@ -214,22 +214,22 @@ public class MilestoneListPanel extends GenericPanel { } @Override - public void populateItem(Item> cellItem, String componentId, - IModel rowModel) { - Milestone milestone = rowModel.getObject(); - Fragment fragment = new Fragment(componentId, "nameFrag", MilestoneListPanel.this); - WebMarkupContainer link = new ActionablePageLink("link", MilestoneIssuesPage.class, - MilestoneIssuesPage.paramsOf(getProject(), milestone, null)) { + public void populateItem(Item> cellItem, String componentId, + IModel rowModel) { + Iteration iteration = rowModel.getObject(); + Fragment fragment = new Fragment(componentId, "nameFrag", IterationListPanel.this); + WebMarkupContainer link = new ActionablePageLink("link", IterationIssuesPage.class, + IterationIssuesPage.paramsOf(getProject(), iteration, null)) { @Override protected void doBeforeNav(AjaxRequestTarget target) { String redirectUrlAfterDelete = RequestCycle.get().urlFor( getPage().getClass(), getPage().getPageParameters()).toString(); - WebSession.get().setRedirectUrlAfterDelete(Milestone.class, redirectUrlAfterDelete); + WebSession.get().setRedirectUrlAfterDelete(Iteration.class, redirectUrlAfterDelete); } }; - link.add(new Label("label", milestone.getName())); + link.add(new Label("label", iteration.getName())); fragment.add(link); fragment.add(new WebMarkupContainer("inherited") { @@ -253,9 +253,9 @@ public class MilestoneListPanel extends GenericPanel { } @Override - public void populateItem(Item> cellItem, String componentId, - IModel rowModel) { - cellItem.add(new MilestoneDateLabel(componentId, rowModel)); + public void populateItem(Item> cellItem, String componentId, + IModel rowModel) { + cellItem.add(new IterationDateLabel(componentId, rowModel)); } }); @@ -268,29 +268,29 @@ public class MilestoneListPanel extends GenericPanel { } @Override - public void populateItem(Item> cellItem, String componentId, - IModel rowModel) { - Fragment fragment = new Fragment(componentId, "issueStatsFrag", MilestoneListPanel.this) { + public void populateItem(Item> cellItem, String componentId, + IModel rowModel) { + Fragment fragment = new Fragment(componentId, "issueStatsFrag", IterationListPanel.this) { @Override protected void onBeforeRender() { /* - * Create StateStatsBar here as it requires to access the milestoneAndStatsModel which can - * only be calculated correctly after the milestone table is initialized + * Create StateStatsBar here as it requires to access the iterationAndStatsModel which can + * only be calculated correctly after the iteration table is initialized */ addOrReplace(new StateStatsBar("content", new LoadableDetachableModel>() { @Override protected Map load() { Map stateStats = new HashMap<>(); - for (MilestoneAndIssueState milestoneAndState : milestoneAndStatesModel.getObject()) { - if (milestoneAndState.getMilestoneId().equals(rowModel.getObject().getId())) { - Integer count = stateStats.get(milestoneAndState.getIssueState()); + for (IterationAndIssueState iterationAndState : iterationAndStatesModel.getObject()) { + if (iterationAndState.getIterationId().equals(rowModel.getObject().getId())) { + Integer count = stateStats.get(iterationAndState.getIssueState()); if (count != null) count++; else count = 1; - stateStats.put(milestoneAndState.getIssueState(), count); + stateStats.put(iterationAndState.getIssueState(), count); } } return stateStats; @@ -301,8 +301,8 @@ public class MilestoneListPanel extends GenericPanel { @Override protected Link newStateLink(String componentId, String state) { String query = new IssueQuery(new StateCriteria(state, IssueQueryLexer.Is)).toString(); - PageParameters params = MilestoneIssuesPage.paramsOf(getProject(), rowModel.getObject(), query); - return new ViewStateAwarePageLink(componentId, MilestoneIssuesPage.class, params); + PageParameters params = IterationIssuesPage.paramsOf(getProject(), rowModel.getObject(), query); + return new ViewStateAwarePageLink(componentId, IterationIssuesPage.class, params); } }); @@ -324,19 +324,19 @@ public class MilestoneListPanel extends GenericPanel { } @Override - public void populateItem(Item> cellItem, String componentId, - IModel rowModel) { + public void populateItem(Item> cellItem, String componentId, + IModel rowModel) { if (rowModel.getObject().getProject().equals(getProject())) { - cellItem.add(new MilestoneActionsPanel(componentId, rowModel) { + cellItem.add(new IterationActionsPanel(componentId, rowModel) { @Override protected void onUpdated(AjaxRequestTarget target) { - target.add(milestonesTable); + target.add(iterationsTable); } @Override protected void onDeleted(AjaxRequestTarget target) { - target.add(milestonesTable); + target.add(iterationsTable); } }); @@ -348,11 +348,11 @@ public class MilestoneListPanel extends GenericPanel { }); } - SortableDataProvider dataProvider = new LoadableDetachableDataProvider<>() { + SortableDataProvider dataProvider = new LoadableDetachableDataProvider<>() { @Override - public Iterator iterator(long first, long count) { - EntityCriteria criteria = getCriteria(closed); + public Iterator iterator(long first, long count) { + EntityCriteria criteria = getCriteria(closed); criteria.addOrder(sort.getOrder(closed)); return OneDev.getInstance(Dao.class).query(criteria, (int) first, (int) count).iterator(); } @@ -363,27 +363,27 @@ public class MilestoneListPanel extends GenericPanel { } @Override - public IModel model(Milestone object) { + public IModel model(Iteration object) { Long id = object.getId(); return new LoadableDetachableModel<>() { @Override - protected Milestone load() { - return OneDev.getInstance(MilestoneManager.class).load(id); + protected Iteration load() { + return OneDev.getInstance(IterationManager.class).load(id); } }; } }; - add(milestonesTable = new DefaultDataTable<>("milestones", columns, dataProvider, + add(iterationsTable = new DefaultDataTable<>("iterations", columns, dataProvider, WebConstants.PAGE_SIZE, pagingHistorySupport)); - milestonesTable.setOutputMarkupId(true); + iterationsTable.setOutputMarkupId(true); } @Override protected void onDetach() { - milestoneAndStatesModel.detach(); + iterationAndStatesModel.detach(); super.onDetach(); } @@ -391,7 +391,7 @@ public class MilestoneListPanel extends GenericPanel { return getModelObject(); } - protected void onSortChanged(AjaxRequestTarget target, MilestoneSort sort) { + protected void onSortChanged(AjaxRequestTarget target, IterationSort sort) { } protected void onStateChanged(AjaxRequestTarget target, boolean closed) { diff --git a/server-core/src/main/java/io/onedev/server/web/component/milestone/actions/MilestoneActionsPanel.html b/server-core/src/main/java/io/onedev/server/web/component/milestone/actions/MilestoneActionsPanel.html deleted file mode 100644 index f6ac2be705..0000000000 --- a/server-core/src/main/java/io/onedev/server/web/component/milestone/actions/MilestoneActionsPanel.html +++ /dev/null @@ -1,10 +0,0 @@ - - - Reopen - Close - - Edit - - Delete - - \ No newline at end of file diff --git a/server-core/src/main/java/io/onedev/server/web/component/milestone/choice/MilestoneMultiChoice.java b/server-core/src/main/java/io/onedev/server/web/component/milestone/choice/MilestoneMultiChoice.java deleted file mode 100644 index ce01fd89c1..0000000000 --- a/server-core/src/main/java/io/onedev/server/web/component/milestone/choice/MilestoneMultiChoice.java +++ /dev/null @@ -1,40 +0,0 @@ -package io.onedev.server.web.component.milestone.choice; - -import java.util.Collection; - -import org.apache.wicket.markup.head.IHeaderResponse; -import org.apache.wicket.markup.head.JavaScriptHeaderItem; -import org.apache.wicket.model.IModel; - -import io.onedev.server.model.Milestone; -import io.onedev.server.web.component.select2.Select2MultiChoice; - -public class MilestoneMultiChoice extends Select2MultiChoice { - - private static final long serialVersionUID = 1L; - - public MilestoneMultiChoice(String id, IModel> selectionsModel, IModel>choicesModel) { - super(id, selectionsModel, new MilestoneChoiceProvider(choicesModel)); - } - - @Override - protected void onInitialize() { - super.onInitialize(); - if (isRequired()) - getSettings().setPlaceholder("Choose milestones..."); - else - getSettings().setPlaceholder("Not specified"); - getSettings().setFormatResult("onedev.server.milestoneChoiceFormatter.formatResult"); - getSettings().setFormatSelection("onedev.server.milestoneChoiceFormatter.formatSelection"); - getSettings().setEscapeMarkup("onedev.server.milestoneChoiceFormatter.escapeMarkup"); - setConvertEmptyInputStringToNull(true); - } - - @Override - public void renderHead(IHeaderResponse response) { - super.renderHead(response); - - response.render(JavaScriptHeaderItem.forReference(new MilestoneChoiceResourceReference())); - } - -} diff --git a/server-core/src/main/java/io/onedev/server/web/component/milestone/choice/MilestoneSingleChoice.java b/server-core/src/main/java/io/onedev/server/web/component/milestone/choice/MilestoneSingleChoice.java deleted file mode 100644 index 988f398161..0000000000 --- a/server-core/src/main/java/io/onedev/server/web/component/milestone/choice/MilestoneSingleChoice.java +++ /dev/null @@ -1,41 +0,0 @@ -package io.onedev.server.web.component.milestone.choice; - -import java.util.Collection; - -import org.apache.wicket.markup.head.IHeaderResponse; -import org.apache.wicket.markup.head.JavaScriptHeaderItem; -import org.apache.wicket.model.IModel; - -import io.onedev.server.model.Milestone; -import io.onedev.server.web.component.select2.Select2Choice; - -@SuppressWarnings("serial") -public class MilestoneSingleChoice extends Select2Choice { - - public MilestoneSingleChoice(String id, IModel selectionModel, IModel> milestonesModel) { - super(id, selectionModel, new MilestoneChoiceProvider(milestonesModel)); - } - - @Override - protected void onInitialize() { - super.onInitialize(); - - getSettings().setAllowClear(!isRequired()); - if (isRequired()) - getSettings().setPlaceholder("Choose milestone..."); - else - getSettings().setPlaceholder("Not specified"); - getSettings().setFormatResult("onedev.server.milestoneChoiceFormatter.formatResult"); - getSettings().setFormatSelection("onedev.server.milestoneChoiceFormatter.formatSelection"); - getSettings().setEscapeMarkup("onedev.server.milestoneChoiceFormatter.escapeMarkup"); - setConvertEmptyInputStringToNull(true); - } - - @Override - public void renderHead(IHeaderResponse response) { - super.renderHead(response); - - response.render(JavaScriptHeaderItem.forReference(new MilestoneChoiceResourceReference())); - } - -} diff --git a/server-core/src/main/java/io/onedev/server/web/component/milestone/choice/milestone-choice.css b/server-core/src/main/java/io/onedev/server/web/component/milestone/choice/milestone-choice.css deleted file mode 100644 index 1503cc0836..0000000000 --- a/server-core/src/main/java/io/onedev/server/web/component/milestone/choice/milestone-choice.css +++ /dev/null @@ -1,3 +0,0 @@ -.select2-results .milestone .label { - margin-left: 6px; -} diff --git a/server-core/src/main/java/io/onedev/server/web/component/milestone/choice/milestone-choice.js b/server-core/src/main/java/io/onedev/server/web/component/milestone/choice/milestone-choice.js deleted file mode 100644 index 8fe6baded4..0000000000 --- a/server-core/src/main/java/io/onedev/server/web/component/milestone/choice/milestone-choice.js +++ /dev/null @@ -1,14 +0,0 @@ -onedev.server.milestoneChoiceFormatter = { - formatSelection: function(milestone) { - return milestone.name; - }, - - formatResult: function(milestone) { - return "" + milestone.name + " " + milestone.statusName + ""; - }, - - escapeMarkup: function(m) { - return m; - }, - -}; diff --git a/server-core/src/main/java/io/onedev/server/web/editable/milestonechoice/MilestoneChoiceEditSupport.java b/server-core/src/main/java/io/onedev/server/web/editable/iterationchoice/IterationChoiceEditSupport.java similarity index 80% rename from server-core/src/main/java/io/onedev/server/web/editable/milestonechoice/MilestoneChoiceEditSupport.java rename to server-core/src/main/java/io/onedev/server/web/editable/iterationchoice/IterationChoiceEditSupport.java index 19a72b71f2..b23e69ca8c 100644 --- a/server-core/src/main/java/io/onedev/server/web/editable/milestonechoice/MilestoneChoiceEditSupport.java +++ b/server-core/src/main/java/io/onedev/server/web/editable/iterationchoice/IterationChoiceEditSupport.java @@ -1,4 +1,4 @@ -package io.onedev.server.web.editable.milestonechoice; +package io.onedev.server.web.editable.iterationchoice; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Method; @@ -16,16 +16,16 @@ import io.onedev.server.web.editable.PropertyContext; import io.onedev.server.web.editable.PropertyDescriptor; import io.onedev.server.web.editable.PropertyEditor; import io.onedev.server.web.editable.PropertyViewer; -import io.onedev.server.annotation.MilestoneChoice; +import io.onedev.server.annotation.IterationChoice; @SuppressWarnings("serial") -public class MilestoneChoiceEditSupport implements EditSupport { +public class IterationChoiceEditSupport implements EditSupport { @Override public PropertyContext getEditContext(PropertyDescriptor descriptor) { Method propertyGetter = descriptor.getPropertyGetter(); - MilestoneChoice milestoneChoice = propertyGetter.getAnnotation(MilestoneChoice.class); - if (milestoneChoice != null) { + IterationChoice iterationChoice = propertyGetter.getAnnotation(IterationChoice.class); + if (iterationChoice != null) { if (List.class.isAssignableFrom(propertyGetter.getReturnType()) && ReflectionUtils.getCollectionElementClass(propertyGetter.getGenericReturnType()) == String.class) { return new PropertyContext>(descriptor) { @@ -36,9 +36,9 @@ public class MilestoneChoiceEditSupport implements EditSupport { @Override protected Component newContent(String id, PropertyDescriptor propertyDescriptor) { - List milestoneNames = model.getObject(); - if (milestoneNames != null && !milestoneNames.isEmpty()) { - return new Label(id, StringUtils.join(milestoneNames, ", " )); + List iterationNames = model.getObject(); + if (iterationNames != null && !iterationNames.isEmpty()) { + return new Label(id, StringUtils.join(iterationNames, ", " )); } else { return new EmptyValueLabel(id) { @@ -56,7 +56,7 @@ public class MilestoneChoiceEditSupport implements EditSupport { @Override public PropertyEditor> renderForEdit(String componentId, IModel> model) { - return new MilestoneMultiChoiceEditor(componentId, descriptor, model); + return new IterationMultiChoiceEditor(componentId, descriptor, model); } }; @@ -88,12 +88,12 @@ public class MilestoneChoiceEditSupport implements EditSupport { @Override public PropertyEditor renderForEdit(String componentId, IModel model) { - return new MilestoneSingleChoiceEditor(componentId, descriptor, model); + return new IterationSingleChoiceEditor(componentId, descriptor, model); } }; } else { - throw new RuntimeException("Annotation 'MilestoneChoice' should be applied to property with type 'String' or 'List'"); + throw new RuntimeException("Annotation 'IterationChoice' should be applied to property with type 'String' or 'List'"); } } else { return null; diff --git a/server-core/src/main/java/io/onedev/server/web/editable/milestonechoice/MilestoneMultiChoiceEditor.html b/server-core/src/main/java/io/onedev/server/web/editable/iterationchoice/IterationMultiChoiceEditor.html similarity index 100% rename from server-core/src/main/java/io/onedev/server/web/editable/milestonechoice/MilestoneMultiChoiceEditor.html rename to server-core/src/main/java/io/onedev/server/web/editable/iterationchoice/IterationMultiChoiceEditor.html diff --git a/server-core/src/main/java/io/onedev/server/web/editable/milestonechoice/MilestoneMultiChoiceEditor.java b/server-core/src/main/java/io/onedev/server/web/editable/iterationchoice/IterationMultiChoiceEditor.java similarity index 52% rename from server-core/src/main/java/io/onedev/server/web/editable/milestonechoice/MilestoneMultiChoiceEditor.java rename to server-core/src/main/java/io/onedev/server/web/editable/iterationchoice/IterationMultiChoiceEditor.java index d959ff5bba..1affdc88be 100644 --- a/server-core/src/main/java/io/onedev/server/web/editable/milestonechoice/MilestoneMultiChoiceEditor.java +++ b/server-core/src/main/java/io/onedev/server/web/editable/iterationchoice/IterationMultiChoiceEditor.java @@ -1,36 +1,32 @@ -package io.onedev.server.web.editable.milestonechoice; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; +package io.onedev.server.web.editable.iterationchoice; +import com.google.common.base.Preconditions; +import io.onedev.server.annotation.IterationChoice; +import io.onedev.server.model.Iteration; +import io.onedev.server.model.Project; +import io.onedev.server.util.ComponentContext; +import io.onedev.server.util.ReflectionUtils; +import io.onedev.server.web.component.iteration.choice.IterationMultiChoice; +import io.onedev.server.web.editable.PropertyDescriptor; +import io.onedev.server.web.editable.PropertyEditor; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; import org.apache.wicket.util.convert.ConversionException; -import com.google.common.base.Preconditions; - -import io.onedev.server.OneDev; -import io.onedev.server.entitymanager.MilestoneManager; -import io.onedev.server.model.Milestone; -import io.onedev.server.model.Project; -import io.onedev.server.util.ComponentContext; -import io.onedev.server.util.ReflectionUtils; -import io.onedev.server.web.component.milestone.choice.MilestoneMultiChoice; -import io.onedev.server.web.editable.PropertyDescriptor; -import io.onedev.server.web.editable.PropertyEditor; -import io.onedev.server.annotation.MilestoneChoice; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; @SuppressWarnings("serial") -public class MilestoneMultiChoiceEditor extends PropertyEditor> { +public class IterationMultiChoiceEditor extends PropertyEditor> { - private MilestoneMultiChoice input; + private IterationMultiChoice input; - public MilestoneMultiChoiceEditor(String id, PropertyDescriptor propertyDescriptor, - IModel> propertyModel) { + public IterationMultiChoiceEditor(String id, PropertyDescriptor propertyDescriptor, + IModel> propertyModel) { super(id, propertyDescriptor, propertyModel); } @@ -39,34 +35,30 @@ public class MilestoneMultiChoiceEditor extends PropertyEditor> { protected void onInitialize() { super.onInitialize(); - List choices = new ArrayList<>(); - List selections = new ArrayList<>(); + List choices = new ArrayList<>(); + List selections = new ArrayList<>(); ComponentContext componentContext = new ComponentContext(this); ComponentContext.push(componentContext); try { - MilestoneChoice milestoneChoice = descriptor.getPropertyGetter().getAnnotation(MilestoneChoice.class); - Preconditions.checkNotNull(milestoneChoice); - if (milestoneChoice.value().length() != 0) { - choices.addAll((List)ReflectionUtils - .invokeStaticMethod(descriptor.getBeanClass(), milestoneChoice.value())); + IterationChoice iterationChoice = descriptor.getPropertyGetter().getAnnotation(IterationChoice.class); + Preconditions.checkNotNull(iterationChoice); + if (iterationChoice.value().length() != 0) { + choices.addAll((List)ReflectionUtils + .invokeStaticMethod(descriptor.getBeanClass(), iterationChoice.value())); } else if (Project.get() != null) { - choices.addAll(Project.get().getSortedHierarchyMilestones()); + choices.addAll(Project.get().getSortedHierarchyIterations()); } - if (getModelObject() != null && Project.get() != null) { - MilestoneManager milestoneManager = OneDev.getInstance(MilestoneManager.class); - for (String milestoneName: getModelObject()) { - Milestone milestone = milestoneManager.findInHierarchy(Project.get(), milestoneName); - if (milestone != null && choices.contains(milestone)) - selections.add(milestone); - } - } + for (var choice: choices) { + if (getModelObject() != null && getModelObject().contains(choice.getName())) + selections.add(choice); + } } finally { ComponentContext.pop(); } - input = new MilestoneMultiChoice("input", Model.of(selections), Model.of(choices)) { + input = new IterationMultiChoice("input", Model.of(selections), Model.of(choices)) { @Override protected void onInitialize() { @@ -92,9 +84,9 @@ public class MilestoneMultiChoiceEditor extends PropertyEditor> { @Override protected List convertInputToValue() throws ConversionException { - Collection milestones = input.getConvertedInput(); - if (milestones != null) - return milestones.stream().map(it->it.getName()).collect(Collectors.toList()); + Collection iterations = input.getConvertedInput(); + if (iterations != null) + return iterations.stream().map(it->it.getName()).collect(Collectors.toList()); else return new ArrayList<>(); } diff --git a/server-core/src/main/java/io/onedev/server/web/editable/milestonechoice/MilestoneSingleChoiceEditor.html b/server-core/src/main/java/io/onedev/server/web/editable/iterationchoice/IterationSingleChoiceEditor.html similarity index 100% rename from server-core/src/main/java/io/onedev/server/web/editable/milestonechoice/MilestoneSingleChoiceEditor.html rename to server-core/src/main/java/io/onedev/server/web/editable/iterationchoice/IterationSingleChoiceEditor.html diff --git a/server-core/src/main/java/io/onedev/server/web/editable/milestonechoice/MilestoneSingleChoiceEditor.java b/server-core/src/main/java/io/onedev/server/web/editable/iterationchoice/IterationSingleChoiceEditor.java similarity index 57% rename from server-core/src/main/java/io/onedev/server/web/editable/milestonechoice/MilestoneSingleChoiceEditor.java rename to server-core/src/main/java/io/onedev/server/web/editable/iterationchoice/IterationSingleChoiceEditor.java index a9760d277b..3e7a9a77a9 100644 --- a/server-core/src/main/java/io/onedev/server/web/editable/milestonechoice/MilestoneSingleChoiceEditor.java +++ b/server-core/src/main/java/io/onedev/server/web/editable/iterationchoice/IterationSingleChoiceEditor.java @@ -1,32 +1,30 @@ -package io.onedev.server.web.editable.milestonechoice; - -import java.util.ArrayList; -import java.util.List; +package io.onedev.server.web.editable.iterationchoice; +import com.google.common.base.Preconditions; +import io.onedev.server.annotation.IterationChoice; +import io.onedev.server.model.Iteration; +import io.onedev.server.model.Project; +import io.onedev.server.util.ComponentContext; +import io.onedev.server.util.ReflectionUtils; +import io.onedev.server.web.component.iteration.choice.IterationSingleChoice; +import io.onedev.server.web.editable.PropertyDescriptor; +import io.onedev.server.web.editable.PropertyEditor; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; import org.apache.wicket.util.convert.ConversionException; -import com.google.common.base.Preconditions; - -import io.onedev.server.model.Milestone; -import io.onedev.server.model.Project; -import io.onedev.server.util.ComponentContext; -import io.onedev.server.util.ReflectionUtils; -import io.onedev.server.web.component.milestone.choice.MilestoneSingleChoice; -import io.onedev.server.web.editable.PropertyDescriptor; -import io.onedev.server.web.editable.PropertyEditor; -import io.onedev.server.annotation.MilestoneChoice; +import java.util.ArrayList; +import java.util.List; @SuppressWarnings("serial") -public class MilestoneSingleChoiceEditor extends PropertyEditor { +public class IterationSingleChoiceEditor extends PropertyEditor { - private MilestoneSingleChoice input; + private IterationSingleChoice input; - public MilestoneSingleChoiceEditor(String id, PropertyDescriptor propertyDescriptor, - IModel propertyModel) { + public IterationSingleChoiceEditor(String id, PropertyDescriptor propertyDescriptor, + IModel propertyModel) { super(id, propertyDescriptor, propertyModel); } @@ -35,33 +33,32 @@ public class MilestoneSingleChoiceEditor extends PropertyEditor { protected void onInitialize() { super.onInitialize(); - List choices = new ArrayList<>(); - Milestone selection; + List choices = new ArrayList<>(); + Iteration selection = null; ComponentContext componentContext = new ComponentContext(this); ComponentContext.push(componentContext); try { - MilestoneChoice milestoneChoice = descriptor.getPropertyGetter().getAnnotation(MilestoneChoice.class); - Preconditions.checkNotNull(milestoneChoice); - if (milestoneChoice.value().length() != 0) { - choices.addAll((List)ReflectionUtils - .invokeStaticMethod(descriptor.getBeanClass(), milestoneChoice.value())); + IterationChoice iterationChoice = descriptor.getPropertyGetter().getAnnotation(IterationChoice.class); + Preconditions.checkNotNull(iterationChoice); + if (iterationChoice.value().length() != 0) { + choices.addAll((List)ReflectionUtils + .invokeStaticMethod(descriptor.getBeanClass(), iterationChoice.value())); } else if (Project.get() != null) { - choices.addAll(Project.get().getSortedHierarchyMilestones()); + choices.addAll(Project.get().getSortedHierarchyIterations()); + } + + for (var choice: choices) { + if (choice.getName().equals(getModelObject())) { + selection = choice; + break; + } } - - if (Project.get() != null && getModelObject() != null) - selection = Project.get().getHierarchyMilestone(getModelObject()); - else - selection = null; - - if (selection != null && !choices.contains(selection)) - selection = null; } finally { ComponentContext.pop(); } - input = new MilestoneSingleChoice("input", Model.of(selection), Model.of(choices)) { + input = new IterationSingleChoice("input", Model.of(selection), Model.of(choices)) { @Override protected void onInitialize() { @@ -87,9 +84,9 @@ public class MilestoneSingleChoiceEditor extends PropertyEditor { @Override protected String convertInputToValue() throws ConversionException { - Milestone milestone = input.getConvertedInput(); - if (milestone != null) - return milestone.getName(); + Iteration iteration = input.getConvertedInput(); + if (iteration != null) + return iteration.getName(); else return null; } diff --git a/server-core/src/main/java/io/onedev/server/web/mapper/BaseUrlMapper.java b/server-core/src/main/java/io/onedev/server/web/mapper/BaseUrlMapper.java index e40ab57105..708790a9eb 100644 --- a/server-core/src/main/java/io/onedev/server/web/mapper/BaseUrlMapper.java +++ b/server-core/src/main/java/io/onedev/server/web/mapper/BaseUrlMapper.java @@ -97,7 +97,7 @@ import io.onedev.server.web.page.project.issues.create.NewIssuePage; import io.onedev.server.web.page.project.issues.detail.*; import io.onedev.server.web.page.project.issues.imports.IssueImportPage; import io.onedev.server.web.page.project.issues.list.ProjectIssueListPage; -import io.onedev.server.web.page.project.issues.milestones.*; +import io.onedev.server.web.page.project.issues.iteration.*; import io.onedev.server.web.page.project.packs.ProjectPacksPage; import io.onedev.server.web.page.project.packs.detail.PackDetailPage; import io.onedev.server.web.page.project.pullrequests.InvalidPullRequestPage; @@ -344,11 +344,11 @@ public class BaseUrlMapper extends CompoundRequestMapper { add(new ProjectPageMapper("${project}/~issues/${issue}/authorizations", IssueAuthorizationsPage.class)); add(new ProjectPageMapper("${project}/~issues/new", NewIssuePage.class)); add(new ProjectPageMapper("${project}/~issues/import/${importer}", IssueImportPage.class)); - add(new ProjectPageMapper("${project}/~milestones", MilestoneListPage.class)); - add(new ProjectPageMapper("${project}/~milestones/${milestone}", MilestoneIssuesPage.class)); - add(new ProjectPageMapper("${project}/~milestones/${milestone}/burndown", MilestoneBurndownPage.class)); - add(new ProjectPageMapper("${project}/~milestones/${milestone}/edit", MilestoneEditPage.class)); - add(new ProjectPageMapper("${project}/~milestones/new", NewMilestonePage.class)); + add(new ProjectPageMapper("${project}/~iterations", IterationListPage.class)); + add(new ProjectPageMapper("${project}/~iterations/${iteration}", IterationIssuesPage.class)); + add(new ProjectPageMapper("${project}/~iterations/${iteration}/burndown", IterationBurndownPage.class)); + add(new ProjectPageMapper("${project}/~iterations/${iteration}/edit", IterationEditPage.class)); + add(new ProjectPageMapper("${project}/~iterations/new", NewIterationPage.class)); add(new ProjectPageMapper("${project}/~builds", ProjectBuildsPage.class)); add(new ProjectPageMapper("${project}/~builds/${build}", BuildDashboardPage.class)); diff --git a/server-core/src/main/java/io/onedev/server/web/page/admin/administration.css b/server-core/src/main/java/io/onedev/server/web/page/admin/administration.css index d1486dc3e0..0e4746a06f 100644 --- a/server-core/src/main/java/io/onedev/server/web/page/admin/administration.css +++ b/server-core/src/main/java/io/onedev/server/web/page/admin/administration.css @@ -48,12 +48,6 @@ display: none; } -.milestone-type-management .drag-indicator, -.milestone-type-management th.property-id, -.milestone-type-management td.property-id { - display: none; -} - .branding-setting .logo-preview>div { background-color: white !important; } diff --git a/server-core/src/main/java/io/onedev/server/web/page/help/ResourceDetailPage.html b/server-core/src/main/java/io/onedev/server/web/page/help/ResourceDetailPage.html index 077fae621d..bb8c3ed48d 100644 --- a/server-core/src/main/java/io/onedev/server/web/page/help/ResourceDetailPage.html +++ b/server-core/src/main/java/io/onedev/server/web/page/help/ResourceDetailPage.html @@ -12,7 +12,7 @@ - + diff --git a/server-core/src/main/java/io/onedev/server/web/page/project/ProjectPage.java b/server-core/src/main/java/io/onedev/server/web/page/project/ProjectPage.java index 66a6573a52..6d4eb3b627 100644 --- a/server-core/src/main/java/io/onedev/server/web/page/project/ProjectPage.java +++ b/server-core/src/main/java/io/onedev/server/web/page/project/ProjectPage.java @@ -41,10 +41,10 @@ import io.onedev.server.web.page.project.issues.boards.IssueBoardsPage; import io.onedev.server.web.page.project.issues.create.NewIssuePage; import io.onedev.server.web.page.project.issues.detail.IssueDetailPage; import io.onedev.server.web.page.project.issues.list.ProjectIssueListPage; -import io.onedev.server.web.page.project.issues.milestones.MilestoneDetailPage; -import io.onedev.server.web.page.project.issues.milestones.MilestoneEditPage; -import io.onedev.server.web.page.project.issues.milestones.MilestoneListPage; -import io.onedev.server.web.page.project.issues.milestones.NewMilestonePage; +import io.onedev.server.web.page.project.issues.iteration.IterationDetailPage; +import io.onedev.server.web.page.project.issues.iteration.IterationEditPage; +import io.onedev.server.web.page.project.issues.iteration.IterationListPage; +import io.onedev.server.web.page.project.issues.iteration.NewIterationPage; import io.onedev.server.web.page.project.packs.ProjectPacksPage; import io.onedev.server.web.page.project.packs.detail.PackDetailPage; import io.onedev.server.web.page.project.pullrequests.InvalidPullRequestPage; @@ -218,9 +218,9 @@ public abstract class ProjectPage extends LayoutPage implements ProjectAware { Lists.newArrayList(NewIssuePage.class, IssueDetailPage.class))); issueMenuItems.add(new SidebarMenuItem.Page(null, "Boards", IssueBoardsPage.class, IssueBoardsPage.paramsOf(getProject()))); - issueMenuItems.add(new SidebarMenuItem.Page(null, "Milestones", - MilestoneListPage.class, MilestoneListPage.paramsOf(getProject(), false, null), - Lists.newArrayList(NewMilestonePage.class, MilestoneDetailPage.class, MilestoneEditPage.class))); + issueMenuItems.add(new SidebarMenuItem.Page(null, "Iterations", + IterationListPage.class, IterationListPage.paramsOf(getProject(), false, null), + Lists.newArrayList(NewIterationPage.class, IterationDetailPage.class, IterationEditPage.class))); if (getProject().isTimeTracking() && isSubscriptionActive()) issueMenuItems.add(OneDev.getInstance(TimeTrackingManager.class).newTimesheetsMenuItem(getProject())); menuItems.add(new SidebarMenuItem.SubMenu("bug", "Issues", issueMenuItems)); diff --git a/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/AbstractColumnPanel.java b/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/AbstractColumnPanel.java index e8fbe2d2ab..4323a4644f 100644 --- a/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/AbstractColumnPanel.java +++ b/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/AbstractColumnPanel.java @@ -89,9 +89,9 @@ abstract class AbstractColumnPanel extends Panel implements EditContext { protected abstract ProjectScope getProjectScope(); - protected abstract MilestoneSelection getMilestoneSelection(); + protected abstract IterationSelection getIterationSelection(); @Nullable - protected abstract String getMilestonePrefix(); + protected abstract String getIterationPrefix(); } diff --git a/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/BacklogColumnPanel.java b/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/BacklogColumnPanel.java index df67cfaa41..ab16de0084 100644 --- a/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/BacklogColumnPanel.java +++ b/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/BacklogColumnPanel.java @@ -3,8 +3,8 @@ package io.onedev.server.web.page.project.issues.boards; import io.onedev.server.model.Issue; import io.onedev.server.model.Project; import io.onedev.server.search.entity.issue.IssueQuery; -import io.onedev.server.search.entity.issue.MilestoneCriteria; -import io.onedev.server.search.entity.issue.MilestoneEmptyCriteria; +import io.onedev.server.search.entity.issue.IterationCriteria; +import io.onedev.server.search.entity.issue.IterationEmptyCriteria; import io.onedev.server.security.SecurityUtils; import io.onedev.server.util.ProjectScope; import io.onedev.server.util.criteria.Criteria; @@ -56,10 +56,10 @@ abstract class BacklogColumnPanel extends AbstractColumnPanel { List> criterias = new ArrayList<>(); if (backlogQuery.getCriteria() != null) criterias.add(backlogQuery.getCriteria()); - if (getMilestonePrefix() != null) - criterias.add(new MilestoneCriteria(getMilestonePrefix() + "*", IsNot)); + if (getIterationPrefix() != null) + criterias.add(new IterationCriteria(getIterationPrefix() + "*", IsNot)); else - criterias.add(new MilestoneEmptyCriteria(IsEmpty)); + criterias.add(new IterationEmptyCriteria(IsEmpty)); return new IssueQuery(Criteria.andCriterias(criterias), backlogQuery.getSorts()); } else { return null; @@ -164,7 +164,7 @@ abstract class BacklogColumnPanel extends AbstractColumnPanel { var card = cardListPanel.findCard(issueId); if (card == null) { // moved from other columns var issue = getIssueManager().load(issueId); - getIssueChangeManager().removeSchedule(issue, getMilestoneSelection().getMilestone()); + getIssueChangeManager().removeSchedule(issue, getIterationSelection().getIteration()); } cardListPanel.onCardDropped(target, issueId, cardIndex, true); } @@ -186,7 +186,7 @@ abstract class BacklogColumnPanel extends AbstractColumnPanel { Issue issue = issueDragging.getIssue(); if (SecurityUtils.canScheduleIssues(issue.getProject())) { issue = SerializationUtils.clone(issue); - issue.removeSchedule(getMilestoneSelection().getMilestone()); + issue.removeSchedule(getIterationSelection().getIteration()); issue.getLastActivity().setDate(new Date()); } if (getQuery().matches(issue)) { diff --git a/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/BoardCardPanel.java b/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/BoardCardPanel.java index f5124ff981..35169251fb 100644 --- a/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/BoardCardPanel.java +++ b/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/BoardCardPanel.java @@ -5,7 +5,7 @@ import io.onedev.server.entitymanager.IssueLinkManager; import io.onedev.server.entitymanager.IssueManager; import io.onedev.server.model.Issue; import io.onedev.server.model.IssueSchedule; -import io.onedev.server.model.Milestone; +import io.onedev.server.model.Iteration; import io.onedev.server.model.Project; import io.onedev.server.model.support.issue.BoardSpec; import io.onedev.server.model.support.issue.field.spec.FieldSpec; @@ -17,7 +17,7 @@ import io.onedev.server.web.behavior.AbstractPostAjaxBehavior; import io.onedev.server.web.component.issue.IssueStateBadge; import io.onedev.server.web.component.issue.fieldvalues.FieldValuesPanel; import io.onedev.server.web.component.issue.link.IssueLinksPanel; -import io.onedev.server.web.component.issue.milestone.MilestoneCrumbPanel; +import io.onedev.server.web.component.issue.iteration.IterationCrumbPanel; import io.onedev.server.web.component.issue.operation.TransitionMenuLink; import io.onedev.server.web.component.issue.progress.IssueProgressPanel; import io.onedev.server.web.component.issue.title.IssueTitlePanel; @@ -100,8 +100,8 @@ public abstract class BoardCardPanel extends GenericPanel { transitLink.add(new IssueStateBadge("state", issueModel)); stateFragment.add(transitLink); fieldsView.add(stateFragment.setOutputMarkupId(true)); - } else if (fieldName.equals(IssueSchedule.NAME_MILESTONE)) { - fieldsView.add(new MilestoneCrumbPanel(fieldsView.newChildId()) { + } else if (fieldName.equals(IssueSchedule.NAME_ITERATION)) { + fieldsView.add(new IterationCrumbPanel(fieldsView.newChildId()) { @Override protected Issue getIssue() { return issueModel.getObject(); @@ -340,8 +340,8 @@ public abstract class BoardCardPanel extends GenericPanel { Hibernate.initialize(issue.getTargetLinks()); Hibernate.initialize(issue.getSourceLinks()); Hibernate.initialize(issue.getMentions()); - for (Milestone milestone : issue.getMilestones()) - Hibernate.initialize(milestone); + for (Iteration iteration : issue.getIterations()) + Hibernate.initialize(iteration); send(getPage(), Broadcast.BREADTH, new IssueDragging(target, issue)); } else { Session.get().warn("Issue management permission required to move issues"); diff --git a/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/BoardColumnPanel.java b/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/BoardColumnPanel.java index 71f54bb9ff..1acb675e51 100644 --- a/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/BoardColumnPanel.java +++ b/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/BoardColumnPanel.java @@ -77,13 +77,13 @@ abstract class BoardColumnPanel extends AbstractColumnPanel { List> criterias = new ArrayList<>(); if (boardQuery.getCriteria() != null) criterias.add(boardQuery.getCriteria()); - if (getMilestoneSelection().getMilestone() != null) { - criterias.add(new MilestoneCriteria(getMilestoneSelection().getMilestone().getName(), Is)); - } else if (getMilestoneSelection() instanceof MilestoneSelection.Unscheduled) { - if (getMilestonePrefix() != null) - criterias.add(new MilestoneCriteria(getMilestonePrefix()+ "*", IsNot)); + if (getIterationSelection().getIteration() != null) { + criterias.add(new IterationCriteria(getIterationSelection().getIteration().getName(), Is)); + } else if (getIterationSelection() instanceof IterationSelection.Unscheduled) { + if (getIterationPrefix() != null) + criterias.add(new IterationCriteria(getIterationPrefix()+ "*", IsNot)); else - criterias.add(new MilestoneEmptyCriteria(IsEmpty)); + criterias.add(new IterationEmptyCriteria(IsEmpty)); } String identifyField = getBoard().getIdentifyField(); if (identifyField.equals(Issue.NAME_STATE)) { @@ -139,8 +139,8 @@ abstract class BoardColumnPanel extends AbstractColumnPanel { if (event.getPayload() instanceof IssueDragging && getQuery() != null) { IssueDragging issueDragging = (IssueDragging) event.getPayload(); Issue issue = issueDragging.getIssue(); - var milestone = getMilestoneSelection().getMilestone(); - if (milestone == null || issue.getMilestones().contains(milestone)) { + var iteration = getIterationSelection().getIteration(); + if (iteration == null || issue.getIterations().contains(iteration)) { // move issue between board columns String identifyField = getBoard().getIdentifyField(); if (identifyField.equals(Issue.NAME_STATE)) { @@ -166,7 +166,7 @@ abstract class BoardColumnPanel extends AbstractColumnPanel { issue.setProject(getProjectScope().getProject()); IssueSchedule schedule = new IssueSchedule(); schedule.setIssue(issue); - schedule.setMilestone(milestone); + schedule.setIteration(iteration); issue.getSchedules().add(schedule); issue.getLastActivity().setDate(new Date()); } @@ -352,9 +352,9 @@ abstract class BoardColumnPanel extends AbstractColumnPanel { } else { Issue issue = getIssueManager().load(issueId); String fieldName = getBoard().getIdentifyField(); - var milestone = getMilestoneSelection().getMilestone(); - if (milestone != null && !issue.getMilestones().contains(milestone)) { - getIssueChangeManager().addSchedule(issue, milestone); + var iteration = getIterationSelection().getIteration(); + if (iteration != null && !issue.getIterations().contains(iteration)) { + getIssueChangeManager().addSchedule(issue, iteration); cardListPanel.onCardDropped(target, issueId, cardIndex, true); } else if (fieldName.equals(Issue.NAME_STATE)) { AtomicReference transitionRef = new AtomicReference<>(null); diff --git a/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/IssueBoardsPage.html b/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/IssueBoardsPage.html index d023fbbe52..8f74a82879 100644 --- a/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/IssueBoardsPage.html +++ b/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/IssueBoardsPage.html @@ -9,9 +9,9 @@ - Backlog - - + Backlog + + @@ -60,11 +60,11 @@ Use Default Boards
    - - - + Close Reopen diff --git a/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/IssueBoardsPage.java b/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/IssueBoardsPage.java index 5fb3ea0bcd..c91614dea7 100644 --- a/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/IssueBoardsPage.java +++ b/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/IssueBoardsPage.java @@ -2,9 +2,9 @@ package io.onedev.server.web.page.project.issues.boards; import io.onedev.commons.utils.ExplicitException; import io.onedev.server.OneDev; -import io.onedev.server.entitymanager.MilestoneManager; +import io.onedev.server.entitymanager.IterationManager; import io.onedev.server.entitymanager.ProjectManager; -import io.onedev.server.model.Milestone; +import io.onedev.server.model.Iteration; import io.onedev.server.model.Project; import io.onedev.server.model.support.issue.BoardSpec; import io.onedev.server.search.entity.EntitySort; @@ -22,14 +22,14 @@ import io.onedev.server.web.component.floating.FloatingPanel; import io.onedev.server.web.component.issue.board.BoardEditPanel; import io.onedev.server.web.component.link.DropdownLink; import io.onedev.server.web.component.link.ViewStateAwarePageLink; -import io.onedev.server.web.component.milestone.MilestoneDateLabel; -import io.onedev.server.web.component.milestone.MilestoneStatusLabel; +import io.onedev.server.web.component.iteration.IterationDateLabel; +import io.onedev.server.web.component.iteration.IterationStatusLabel; import io.onedev.server.web.component.modal.ModalLink; import io.onedev.server.web.component.modal.ModalPanel; import io.onedev.server.web.page.project.dashboard.ProjectDashboardPage; import io.onedev.server.web.page.project.issues.ProjectIssuesPage; import io.onedev.server.web.util.ConfirmClickModifier; -import io.onedev.server.web.util.editbean.MilestoneEditBean; +import io.onedev.server.web.util.editbean.IterationEditBean; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.apache.wicket.Component; @@ -72,7 +72,7 @@ public class IssueBoardsPage extends ProjectIssuesPage { public static final String PARAM_BOARD = "board"; - private static final String PARAM_MILESTONE = "milestone"; + private static final String PARAM_ITERATION = "iteration"; private static final String PARAM_BACKLOG = "backlog"; @@ -80,15 +80,15 @@ public class IssueBoardsPage extends ProjectIssuesPage { private static final String PARAM_BACKLOG_QUERY = "backlog-query"; - private static final String MILESTONE_ALL = "all"; + private static final String ITERATION_ALL = "all"; - public static final String MILESTONE_UNSCHEDULED = "unscheduled"; + public static final String ITERATION_UNSCHEDULED = "unscheduled"; private List boards; private final int boardIndex; - private final IModel milestoneSelectionModel; + private final IModel iterationSelectionModel; private final boolean backlog; @@ -178,50 +178,50 @@ public class IssueBoardsPage extends ProjectIssuesPage { boardIndex = -1; } - var milestoneParam = params.get(PARAM_MILESTONE).toString(); - milestoneSelectionModel = new LoadableDetachableModel<>() { + var iterationParam = params.get(PARAM_ITERATION).toString(); + iterationSelectionModel = new LoadableDetachableModel<>() { - private MilestoneSelection getCurrentMilestone() { - if (!getMilestones().isEmpty()) { - var milestone = getMilestones().iterator().next(); - if (!milestone.isClosed()) - return new MilestoneSelection.Specified(milestone); + private IterationSelection getCurrentIteration() { + if (!getIterations().isEmpty()) { + var iteration = getIterations().iterator().next(); + if (!iteration.isClosed()) + return new IterationSelection.Specified(iteration); } - return new MilestoneSelection.Unscheduled(); + return new IterationSelection.Unscheduled(); } @Override - protected MilestoneSelection load() { - if (MILESTONE_UNSCHEDULED.equals(milestoneParam)) { - return new MilestoneSelection.Unscheduled(); - } else if (MILESTONE_ALL.equals(milestoneParam)) { - return new MilestoneSelection.All(); - } else if (NumberUtils.isDigits(milestoneParam)) { - var milestone = getMilestoneManager().load(Long.valueOf(milestoneParam)); - if (getBoard().getMilestonePrefix() != null && !milestone.getName().startsWith(getBoard().getMilestonePrefix()) - || !milestone.getProject().isSelfOrAncestorOf(getProject())) { - return getCurrentMilestone(); + protected IterationSelection load() { + if (ITERATION_UNSCHEDULED.equals(iterationParam)) { + return new IterationSelection.Unscheduled(); + } else if (ITERATION_ALL.equals(iterationParam)) { + return new IterationSelection.All(); + } else if (NumberUtils.isDigits(iterationParam)) { + var iteration = getIterationManager().load(Long.valueOf(iterationParam)); + if (getBoard().getIterationPrefix() != null && !iteration.getName().startsWith(getBoard().getIterationPrefix()) + || !iteration.getProject().isSelfOrAncestorOf(getProject())) { + return getCurrentIteration(); } else { - return new MilestoneSelection.Specified(milestone); + return new IterationSelection.Specified(iteration); } } else { - return getCurrentMilestone(); + return getCurrentIteration(); } } }; - backlog = params.get(PARAM_BACKLOG).toBoolean() && getMilestoneSelection().getMilestone() != null; + backlog = params.get(PARAM_BACKLOG).toBoolean() && getIterationSelection().getIteration() != null; queryString = params.get(PARAM_QUERY).toString(); backlogQueryString = params.get(PARAM_BACKLOG_QUERY).toString(); } - private MilestoneManager getMilestoneManager() { - return OneDev.getInstance(MilestoneManager.class); + private IterationManager getIterationManager() { + return OneDev.getInstance(IterationManager.class); } @Override protected void onDetach() { - milestoneSelectionModel.detach(); + iterationSelectionModel.detach(); queryModel.detach(); backlogQueryModel.detach(); super.onDetach(); @@ -235,8 +235,8 @@ public class IssueBoardsPage extends ProjectIssuesPage { return null; } - public MilestoneSelection getMilestoneSelection() { - return milestoneSelectionModel.getObject(); + public IterationSelection getIterationSelection() { + return iterationSelectionModel.getObject(); } private void doQuery(AjaxRequestTarget target) { @@ -249,7 +249,7 @@ public class IssueBoardsPage extends ProjectIssuesPage { } PageParameters params = IssueBoardsPage.paramsOf(getProject(), getBoard(), - getMilestoneSelection(), backlog, queryString, backlogQueryString); + getIterationSelection(), backlog, queryString, backlogQueryString); CharSequence url = RequestCycle.get().urlFor(IssueBoardsPage.class, params); pushState(target, url.toString(), queryInput.getModelObject()); @@ -305,7 +305,7 @@ public class IssueBoardsPage extends ProjectIssuesPage { item.add(new WebMarkupContainer("dragIndicator").setVisible(SecurityUtils.canManageIssues(getProject()))); PageParameters params = IssueBoardsPage.paramsOf( - getProject(), item.getModelObject(), getMilestoneSelection(), backlog, + getProject(), item.getModelObject(), getIterationSelection(), backlog, backlogQueryString, queryString); Link link = new BookmarkablePageLink("select", IssueBoardsPage.class, params); link.add(new Label("name", item.getModelObject().getName())); @@ -349,7 +349,7 @@ public class IssueBoardsPage extends ProjectIssuesPage { else nextBoard = currentBoard; PageParameters params = IssueBoardsPage.paramsOf(getProject(), - nextBoard, getMilestoneSelection(), backlog, queryString, + nextBoard, getIterationSelection(), backlog, queryString, backlogQueryString); setResponsePage(IssueBoardsPage.class, params); } @@ -406,7 +406,7 @@ public class IssueBoardsPage extends ProjectIssuesPage { @Override public void onClick(AjaxRequestTarget target) { - PageParameters params = paramsOf(getProject(), getBoard(), getMilestoneSelection(), + PageParameters params = paramsOf(getProject(), getBoard(), getIterationSelection(), !backlog, queryString, backlogQueryString); setResponsePage(IssueBoardsPage.class, params); } @@ -414,12 +414,12 @@ public class IssueBoardsPage extends ProjectIssuesPage { @Override protected void onConfigure() { super.onConfigure(); - setVisible(getMilestoneSelection().getMilestone() != null); + setVisible(getIterationSelection().getIteration() != null); } }); - form.add(new DropdownLink("milestone") { + form.add(new DropdownLink("iteration") { private boolean showClosed; @@ -427,20 +427,20 @@ public class IssueBoardsPage extends ProjectIssuesPage { protected void onInitialize() { super.onInitialize(); - if (getMilestoneSelection() instanceof MilestoneSelection.All) { + if (getIterationSelection() instanceof IterationSelection.All) { add(new Label("label", "All").setEscapeModelStrings(false)); add(AttributeAppender.append("class", "btn-outline-secondary btn-hover-primary")); - } else if (getMilestoneSelection() instanceof MilestoneSelection.Unscheduled) { + } else if (getIterationSelection() instanceof IterationSelection.Unscheduled) { add(new Label("label", "Unscheduled").setEscapeModelStrings(false)); add(AttributeAppender.append("class", "btn-outline-secondary btn-hover-primary")); } else { - var milestone = getMilestoneSelection().getMilestone(); - add(new Label("label", milestone.getName())); - if (milestone.getDueDate() != null - && milestone.getDueDate().before(new Date()) - && !milestone.isClosed()) { + var iteration = getIterationSelection().getIteration(); + add(new Label("label", iteration.getName())); + if (iteration.getDueDate() != null + && iteration.getDueDate().before(new Date()) + && !iteration.isClosed()) { add(AttributeAppender.append("class", "btn-danger")); - add(AttributeAppender.replace("title", "Milestone is due")); + add(AttributeAppender.replace("title", "Iteration is due")); } else { add(AttributeAppender.append("class", "btn-outline-secondary btn-hover-primary")); } @@ -449,53 +449,53 @@ public class IssueBoardsPage extends ProjectIssuesPage { @Override protected Component newContent(String id, FloatingPanel dropdown) { - Fragment menuFragment = new Fragment(id, "milestoneMenuFrag", IssueBoardsPage.this); + Fragment menuFragment = new Fragment(id, "iterationMenuFrag", IssueBoardsPage.this); if (SecurityUtils.canManageProject(getProject())) menuFragment.add(AttributeAppender.append("class", "administrative")); - menuFragment.add(new ListView("milestones", new LoadableDetachableModel<>() { + menuFragment.add(new ListView("iterations", new LoadableDetachableModel<>() { @Override - protected List load() { - List milestones = getMilestones() + protected List load() { + List iterationss = getIterations() .stream() .filter(it -> !it.isClosed()) .collect(toList()); - if (getMilestoneSelection().getMilestone() != null && getMilestoneSelection().getMilestone().isClosed() || showClosed) { - List closedMilestones = getMilestones() + if (getIterationSelection().getIteration() != null && getIterationSelection().getIteration().isClosed() || showClosed) { + List closedIterations = getIterations() .stream() .filter(it -> it.isClosed()) .collect(toList()); - milestones.addAll(closedMilestones); + iterationss.addAll(closedIterations); } - return milestones; + return iterationss; } }) { - private void toggleClose(Milestone milestone) { - milestone.setClosed(!milestone.isClosed()); - if (milestone.equals(getMilestoneSelection().getMilestone())) { - getMilestoneManager().createOrUpdate(milestone); + private void toggleClose(Iteration iteration) { + iteration.setClosed(!iteration.isClosed()); + if (iteration.equals(getIterationSelection().getIteration())) { + getIterationManager().createOrUpdate(iteration); setResponsePage(IssueBoardsPage.class, IssueBoardsPage.paramsOf(getProject(), getBoard(), - getMilestoneSelection(), backlog, queryString, backlogQueryString)); + getIterationSelection(), backlog, queryString, backlogQueryString)); } else { - getMilestoneManager().createOrUpdate(milestone); + getIterationManager().createOrUpdate(iteration); } dropdown.close(); - if (milestone.isClosed()) - Session.get().success("Milestone '" + milestone.getName() + "' is closed"); + if (iteration.isClosed()) + Session.get().success("Iteration '" + iteration.getName() + "' is closed"); else - Session.get().success("Milestone '" + milestone.getName() + "' is reopened"); + Session.get().success("Iteration '" + iteration.getName() + "' is reopened"); } @Override - protected void populateItem(ListItem item) { - Milestone milestone = item.getModelObject(); + protected void populateItem(ListItem item) { + Iteration iteration = item.getModelObject(); PageParameters params = IssueBoardsPage.paramsOf(getProject(), getBoard(), - new MilestoneSelection.Specified(milestone), backlog, queryString, backlogQueryString); + new IterationSelection.Specified(iteration), backlog, queryString, backlogQueryString); Link link = new BookmarkablePageLink("select", IssueBoardsPage.class, params); - link.add(new Label("name", milestone.getName())); + link.add(new Label("name", iteration.getName())); item.add(link); item.add(new WebMarkupContainer("inherited") { @@ -507,12 +507,12 @@ public class IssueBoardsPage extends ProjectIssuesPage { }); - item.add(new MilestoneStatusLabel("status", item.getModel())); - item.add(new MilestoneDateLabel("dueDate", item.getModel())); + item.add(new IterationStatusLabel("status", item.getModel())); + item.add(new IterationDateLabel("dueDate", item.getModel())); if (SecurityUtils.canManageIssues(getProject()) && item.getModelObject().getProject().equals(getProject())) { - Fragment fragment = new Fragment("actions", "milestoneActionsFrag", IssueBoardsPage.this); + Fragment fragment = new Fragment("actions", "iterationActionsFrag", IssueBoardsPage.this); fragment.add(new AjaxLink("close") { @@ -543,22 +543,22 @@ public class IssueBoardsPage extends ProjectIssuesPage { }); - var bean = MilestoneEditBean.of(item.getModelObject(), getBoard().getMilestonePrefix()); + var bean = IterationEditBean.of(item.getModelObject(), getBoard().getIterationPrefix()); fragment.add(new AjaxLink("edit") { @Override public void onClick(AjaxRequestTarget target) { dropdown.close(); - new BeanEditModalPanel<>(target, bean, "Edit Milestone") { + new BeanEditModalPanel<>(target, bean, "Edit Iteration") { @Override - protected void onSave(AjaxRequestTarget target, MilestoneEditBean bean) { - var milestone = item.getModelObject(); - bean.update(milestone); - getMilestoneManager().createOrUpdate(milestone); + protected void onSave(AjaxRequestTarget target, IterationEditBean bean) { + var iteration = item.getModelObject(); + bean.update(iteration); + getIterationManager().createOrUpdate(iteration); setResponsePage(IssueBoardsPage.class, IssueBoardsPage.paramsOf( - getProject(), getBoard(), new MilestoneSelection.Specified(milestone), + getProject(), getBoard(), new IterationSelection.Specified(iteration), backlog, queryString, backlogQueryString)); } }; @@ -571,23 +571,23 @@ public class IssueBoardsPage extends ProjectIssuesPage { protected void updateAjaxAttributes(AjaxRequestAttributes attributes) { super.updateAjaxAttributes(attributes); attributes.getAjaxCallListeners().add(new ConfirmClickListener( - "Do you really want to delete milestone '" + item.getModelObject().getName() + "'?")); + "Do you really want to delete iteration '" + item.getModelObject().getName() + "'?")); } @Override public void onClick(AjaxRequestTarget target) { dropdown.close(); - Milestone milestone = item.getModelObject(); - if (milestone.equals(getMilestoneSelection().getMilestone())) { - getMilestoneManager().delete(milestone); + Iteration iteration = item.getModelObject(); + if (iteration.equals(getIterationSelection().getIteration())) { + getIterationManager().delete(iteration); PageParameters params = IssueBoardsPage.paramsOf( - getProject(), getBoard(), new MilestoneSelection.Unscheduled(), + getProject(), getBoard(), new IterationSelection.Unscheduled(), backlog, queryString, backlogQueryString); setResponsePage(IssueBoardsPage.class, params); } else { - getMilestoneManager().delete(milestone); + getIterationManager().delete(iteration); } - Session.get().success("Milestone '" + milestone.getName() + "' deleted"); + Session.get().success("Iteration '" + iteration.getName() + "' deleted"); } }); @@ -618,42 +618,42 @@ public class IssueBoardsPage extends ProjectIssuesPage { protected void onConfigure() { super.onConfigure(); setVisible(!showClosed - && (getMilestoneSelection().getMilestone() == null || !getMilestoneSelection().getMilestone().isClosed()) - && getMilestones().stream().anyMatch(Milestone::isClosed)); + && (getIterationSelection().getIteration() == null || !getIterationSelection().getIteration().isClosed()) + && getIterations().stream().anyMatch(Iteration::isClosed)); } }); - PageParameters params = IssueBoardsPage.paramsOf(getProject(), getBoard(), new MilestoneSelection.Unscheduled(), + PageParameters params = IssueBoardsPage.paramsOf(getProject(), getBoard(), new IterationSelection.Unscheduled(), backlog, queryString, backlogQueryString); menuFragment.add(new BookmarkablePageLink("unscheduled", IssueBoardsPage.class, params)); - params = IssueBoardsPage.paramsOf(getProject(), getBoard(), new MilestoneSelection.All(), + params = IssueBoardsPage.paramsOf(getProject(), getBoard(), new IterationSelection.All(), backlog, queryString, backlogQueryString); menuFragment.add(new BookmarkablePageLink("all", IssueBoardsPage.class, params) { @Override protected void onConfigure() { super.onConfigure(); - setVisible(!getMilestones().isEmpty()); + setVisible(!getIterations().isEmpty()); } }); - menuFragment.add(new AjaxLink("newMilestone") { + menuFragment.add(new AjaxLink("newIteration") { @Override public void onClick(AjaxRequestTarget target) { dropdown.close(); - var bean = MilestoneEditBean.ofNew(getProject(), getBoard().getMilestonePrefix()); - new BeanEditModalPanel<>(target, bean, "Create Milestone") { + var bean = IterationEditBean.ofNew(getProject(), getBoard().getIterationPrefix()); + new BeanEditModalPanel<>(target, bean, "Create Iteration") { @Override - protected void onSave(AjaxRequestTarget target, MilestoneEditBean bean) { - var milestone = new Milestone(); - milestone.setProject(getProject()); - bean.update(milestone); - getMilestoneManager().createOrUpdate(milestone); + protected void onSave(AjaxRequestTarget target, IterationEditBean bean) { + var iteration = new Iteration(); + iteration.setProject(getProject()); + bean.update(iteration); + getIterationManager().createOrUpdate(iteration); setResponsePage(IssueBoardsPage.class, IssueBoardsPage.paramsOf( - getProject(), getBoard(), new MilestoneSelection.Specified(milestone), + getProject(), getBoard(), new IterationSelection.Specified(iteration), backlog, queryString, backlogQueryString)); } @@ -750,13 +750,13 @@ public class IssueBoardsPage extends ProjectIssuesPage { } @Override - protected MilestoneSelection getMilestoneSelection() { - return IssueBoardsPage.this.getMilestoneSelection(); + protected IterationSelection getIterationSelection() { + return IssueBoardsPage.this.getIterationSelection(); } @Override - protected String getMilestonePrefix() { - return getBoard().getMilestonePrefix(); + protected String getIterationPrefix() { + return getBoard().getIterationPrefix(); } }); @@ -776,13 +776,13 @@ public class IssueBoardsPage extends ProjectIssuesPage { } @Override - protected MilestoneSelection getMilestoneSelection() { - return IssueBoardsPage.this.getMilestoneSelection(); + protected IterationSelection getIterationSelection() { + return IssueBoardsPage.this.getIterationSelection(); } @Override - protected String getMilestonePrefix() { - return getBoard().getMilestonePrefix(); + protected String getIterationPrefix() { + return getBoard().getIterationPrefix(); } @Override @@ -854,24 +854,24 @@ public class IssueBoardsPage extends ProjectIssuesPage { target.add(contentFrag); } - private List getMilestones() { - return getProject().getSortedHierarchyMilestones().stream() - .filter(it -> getBoard().getMilestonePrefix() == null || it.getName().startsWith(getBoard().getMilestonePrefix())) + private List getIterations() { + return getProject().getSortedHierarchyIterations().stream() + .filter(it -> getBoard().getIterationPrefix() == null || it.getName().startsWith(getBoard().getIterationPrefix())) .collect(toList()); } public static PageParameters paramsOf(Project project, @Nullable BoardSpec board, - MilestoneSelection milestoneSelection, boolean backlog, + IterationSelection iterationSelectionSelection, boolean backlog, @Nullable String query, @Nullable String backlogQuery) { PageParameters params = paramsOf(project); if (board != null) params.add(PARAM_BOARD, board.getName()); - if (milestoneSelection instanceof MilestoneSelection.All) - params.add(PARAM_MILESTONE, MILESTONE_ALL); - else if (milestoneSelection instanceof MilestoneSelection.Unscheduled) - params.add(PARAM_MILESTONE, MILESTONE_UNSCHEDULED); + if (iterationSelectionSelection instanceof IterationSelection.All) + params.add(PARAM_ITERATION, ITERATION_ALL); + else if (iterationSelectionSelection instanceof IterationSelection.Unscheduled) + params.add(PARAM_ITERATION, ITERATION_UNSCHEDULED); else - params.add(PARAM_MILESTONE, milestoneSelection.getMilestone().getId()); + params.add(PARAM_ITERATION, iterationSelectionSelection.getIteration().getId()); params.add(PARAM_BACKLOG, backlog); if (query != null) params.add(PARAM_QUERY, query); @@ -898,7 +898,7 @@ public class IssueBoardsPage extends ProjectIssuesPage { @Override protected void onBoardCreated(AjaxRequestTarget target, BoardSpec board) { setResponsePage(IssueBoardsPage.class, IssueBoardsPage.paramsOf( - getProject(), board, getMilestoneSelection(), backlog, queryString, + getProject(), board, getIterationSelection(), backlog, queryString, backlogQueryString)); modal.close(); } @@ -931,7 +931,7 @@ public class IssueBoardsPage extends ProjectIssuesPage { getProject().getIssueSetting().setBoardSpecs(boards); OneDev.getInstance(ProjectManager.class).update(getProject()); setResponsePage(IssueBoardsPage.class, IssueBoardsPage.paramsOf( - getProject(), board, getMilestoneSelection(), backlog, queryString, + getProject(), board, getIterationSelection(), backlog, queryString, backlogQueryString)); } diff --git a/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/IterationSelection.java b/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/IterationSelection.java new file mode 100644 index 0000000000..74c84a8803 --- /dev/null +++ b/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/IterationSelection.java @@ -0,0 +1,39 @@ +package io.onedev.server.web.page.project.issues.boards; + +import io.onedev.server.model.Iteration; + +import javax.annotation.Nullable; + +public interface IterationSelection { + + @Nullable + Iteration getIteration(); + + class Specified implements IterationSelection { + + private final Iteration iteration; + + public Specified(Iteration iteration) { + this.iteration = iteration; + } + + @Override + public Iteration getIteration() { + return iteration; + } + } + + class Unscheduled implements IterationSelection { + @Override + public Iteration getIteration() { + return null; + } + } + + class All implements IterationSelection { + @Override + public Iteration getIteration() { + return null; + } + } +} diff --git a/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/MilestoneSelection.java b/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/MilestoneSelection.java deleted file mode 100644 index a413924be0..0000000000 --- a/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/MilestoneSelection.java +++ /dev/null @@ -1,39 +0,0 @@ -package io.onedev.server.web.page.project.issues.boards; - -import io.onedev.server.model.Milestone; - -import javax.annotation.Nullable; - -public interface MilestoneSelection { - - @Nullable - Milestone getMilestone(); - - class Specified implements MilestoneSelection { - - private final Milestone milestone; - - public Specified(Milestone milestone) { - this.milestone = milestone; - } - - @Override - public Milestone getMilestone() { - return milestone; - } - } - - class Unscheduled implements MilestoneSelection { - @Override - public Milestone getMilestone() { - return null; - } - } - - class All implements MilestoneSelection { - @Override - public Milestone getMilestone() { - return null; - } - } -} diff --git a/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/issue-boards.css b/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/issue-boards.css index b409c0bdea..88a498e11f 100644 --- a/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/issue-boards.css +++ b/server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/issue-boards.css @@ -41,16 +41,16 @@ margin-left: 0.5rem; min-width: 256px; } -.issue-boards>.head .milestone-selector.btn-danger { +.issue-boards>.head .iteration-selector.btn-danger { background-color: var(--danger) !important; border-color: var(--danger) !important; } -.issue-boards>.head .milestone-selector.btn-danger:hover, -.issue-boards>.head .milestone-selector.btn-danger:focus { +.issue-boards>.head .iteration-selector.btn-danger:hover, +.issue-boards>.head .iteration-selector.btn-danger:focus { background-color: #EE2D41 !important; border-color: #EE2D41 !important; } -.floating>.content>.milestone-menu>table>tbody>tr:first-child>td { +.floating>.content>.iteration-menu>table>tbody>tr:first-child>td { border-top: none; } diff --git a/server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneBurndownPage.html b/server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationBurndownPage.html similarity index 100% rename from server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneBurndownPage.html rename to server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationBurndownPage.html diff --git a/server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneBurndownPage.java b/server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationBurndownPage.java similarity index 75% rename from server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneBurndownPage.java rename to server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationBurndownPage.java index dd07aa1861..a25b8820f6 100644 --- a/server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneBurndownPage.java +++ b/server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationBurndownPage.java @@ -1,8 +1,8 @@ -package io.onedev.server.web.page.project.issues.milestones; +package io.onedev.server.web.page.project.issues.iteration; -import io.onedev.server.model.Milestone; +import io.onedev.server.model.Iteration; import io.onedev.server.model.Project; -import io.onedev.server.web.component.milestone.burndown.MilestoneBurndownPanel; +import io.onedev.server.web.component.iteration.burndown.IterationBurndownPanel; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.form.OnChangeAjaxBehavior; import org.apache.wicket.markup.html.form.DropDownChoice; @@ -15,11 +15,11 @@ import javax.annotation.Nullable; import java.io.Serializable; import java.util.List; -import static io.onedev.server.web.component.milestone.burndown.BurndownIndicators.getChoices; -import static io.onedev.server.web.component.milestone.burndown.BurndownIndicators.getDefault; +import static io.onedev.server.web.component.iteration.burndown.BurndownIndicators.getChoices; +import static io.onedev.server.web.component.iteration.burndown.BurndownIndicators.getDefault; @SuppressWarnings("serial") -public class MilestoneBurndownPage extends MilestoneDetailPage { +public class IterationBurndownPage extends IterationDetailPage { private static final String PARAM_INDICATOR = "indicator"; @@ -27,7 +27,7 @@ public class MilestoneBurndownPage extends MilestoneDetailPage { private DropDownChoice indicatorChoice; - public MilestoneBurndownPage(PageParameters params) { + public IterationBurndownPage(PageParameters params) { super(params); indicator = params.get(PARAM_INDICATOR).toOptionalString(); } @@ -76,7 +76,7 @@ public class MilestoneBurndownPage extends MilestoneDetailPage { @Override protected void onUpdate(AjaxRequestTarget target) { newBurndown(target); - var url = urlFor(MilestoneBurndownPage.class, paramsOf(getProject(), getMilestone(), indicator)); + var url = urlFor(IterationBurndownPage.class, paramsOf(getProject(), getIteration(), indicator)); pushState(target, url.toString(), indicator); } @@ -96,10 +96,10 @@ public class MilestoneBurndownPage extends MilestoneDetailPage { } private void newBurndown(@Nullable AjaxRequestTarget target) { - var burndown = new MilestoneBurndownPanel("burndown", new AbstractReadOnlyModel<>() { + var burndown = new IterationBurndownPanel("burndown", new AbstractReadOnlyModel<>() { @Override - public Milestone getObject() { - return getMilestone(); + public Iteration getObject() { + return getIteration(); } }, indicator); @@ -118,8 +118,8 @@ public class MilestoneBurndownPage extends MilestoneDetailPage { return getDefault(getProject()); } - private static PageParameters paramsOf(Project project, Milestone milestone, @Nullable String indicator) { - var params = paramsOf(project, milestone); + private static PageParameters paramsOf(Project project, Iteration iteration, @Nullable String indicator) { + var params = paramsOf(project, iteration); if (indicator != null) params.add(PARAM_INDICATOR, indicator); return params; diff --git a/server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationCssResourceReference.java b/server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationCssResourceReference.java new file mode 100644 index 0000000000..56bf8d5a78 --- /dev/null +++ b/server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationCssResourceReference.java @@ -0,0 +1,13 @@ +package io.onedev.server.web.page.project.issues.iteration; + +import io.onedev.server.web.page.base.BaseDependentCssResourceReference; + +public class IterationCssResourceReference extends BaseDependentCssResourceReference { + + private static final long serialVersionUID = 1L; + + public IterationCssResourceReference() { + super(IterationCssResourceReference.class, "iteration.css"); + } + +} diff --git a/server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneDetailPage.html b/server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationDetailPage.html similarity index 83% rename from server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneDetailPage.html rename to server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationDetailPage.html index 0c1eef050e..2356d0b8ab 100644 --- a/server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneDetailPage.html +++ b/server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationDetailPage.html @@ -11,16 +11,16 @@ Create
- +
- Milestones + Iterations - + \ No newline at end of file diff --git a/server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneDetailPage.java b/server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationDetailPage.java similarity index 58% rename from server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneDetailPage.java rename to server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationDetailPage.java index cfada908f0..8a58db40d4 100644 --- a/server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneDetailPage.java +++ b/server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationDetailPage.java @@ -1,16 +1,16 @@ -package io.onedev.server.web.page.project.issues.milestones; +package io.onedev.server.web.page.project.issues.iteration; import io.onedev.server.OneDev; -import io.onedev.server.entitymanager.MilestoneManager; -import io.onedev.server.model.Milestone; +import io.onedev.server.entitymanager.IterationManager; +import io.onedev.server.model.Iteration; import io.onedev.server.model.Project; import io.onedev.server.security.SecurityUtils; import io.onedev.server.web.WebSession; import io.onedev.server.web.component.MultilineLabel; import io.onedev.server.web.component.link.ViewStateAwarePageLink; -import io.onedev.server.web.component.milestone.MilestoneDateLabel; -import io.onedev.server.web.component.milestone.MilestoneStatusLabel; -import io.onedev.server.web.component.milestone.actions.MilestoneActionsPanel; +import io.onedev.server.web.component.iteration.IterationDateLabel; +import io.onedev.server.web.component.iteration.IterationStatusLabel; +import io.onedev.server.web.component.iteration.actions.IterationActionsPanel; import io.onedev.server.web.component.tabbable.PageTab; import io.onedev.server.web.component.tabbable.PageTabHead; import io.onedev.server.web.component.tabbable.Tab; @@ -39,51 +39,51 @@ import java.util.ArrayList; import java.util.List; @SuppressWarnings("serial") -public abstract class MilestoneDetailPage extends ProjectPage { +public abstract class IterationDetailPage extends ProjectPage { - public static final String PARAM_MILESTONE = "milestone"; + public static final String PARAM_ITERATION = "iteration"; - protected final IModel milestoneModel; + protected final IModel iterationModel; - public MilestoneDetailPage(PageParameters params) { + public IterationDetailPage(PageParameters params) { super(params); - String idString = params.get(PARAM_MILESTONE).toString(); + String idString = params.get(PARAM_ITERATION).toString(); if (StringUtils.isBlank(idString)) - throw new RestartResponseException(MilestoneListPage.class, MilestoneListPage.paramsOf(getProject(), false, null)); + throw new RestartResponseException(IterationListPage.class, IterationListPage.paramsOf(getProject(), false, null)); - Long milestoneId = Long.valueOf(idString); - milestoneModel = new LoadableDetachableModel() { + Long iterationId = Long.valueOf(idString); + iterationModel = new LoadableDetachableModel() { @Override - protected Milestone load() { - return OneDev.getInstance(MilestoneManager.class).load(milestoneId); + protected Iteration load() { + return OneDev.getInstance(IterationManager.class).load(iterationId); } }; } - protected Milestone getMilestone() { - return milestoneModel.getObject(); + protected Iteration getIteration() { + return iterationModel.getObject(); } @Override protected void onInitialize() { super.onInitialize(); - add(new Label("name", getMilestone().getName())); - add(new MilestoneStatusLabel("status", milestoneModel)); - add(new MilestoneDateLabel("dates", milestoneModel)); - add(new MilestoneActionsPanel("actions", milestoneModel) { + add(new Label("name", getIteration().getName())); + add(new IterationStatusLabel("status", iterationModel)); + add(new IterationDateLabel("dates", iterationModel)); + add(new IterationActionsPanel("actions", iterationModel) { @Override protected void onDeleted(AjaxRequestTarget target) { - String redirectUrlAfterDelete = WebSession.get().getRedirectUrlAfterDelete(Milestone.class); + String redirectUrlAfterDelete = WebSession.get().getRedirectUrlAfterDelete(Iteration.class); if (redirectUrlAfterDelete != null) throw new RedirectToUrlException(redirectUrlAfterDelete); else - setResponsePage(MilestoneListPage.class, MilestoneListPage.paramsOf(getProject())); + setResponsePage(IterationListPage.class, IterationListPage.paramsOf(getProject())); } @Override @@ -94,73 +94,73 @@ public abstract class MilestoneDetailPage extends ProjectPage { @Override protected void onConfigure() { super.onConfigure(); - setVisible(SecurityUtils.canManageIssues(getProject()) && getProject().equals(getMilestone().getProject())); + setVisible(SecurityUtils.canManageIssues(getProject()) && getProject().equals(getIteration().getProject())); } }); - add(new BookmarkablePageLink("create", NewMilestonePage.class, - NewMilestonePage.paramsOf(getProject()))); + add(new BookmarkablePageLink("create", NewIterationPage.class, + NewIterationPage.paramsOf(getProject()))); add(new WebMarkupContainer("inherited") { @Override protected void onConfigure() { super.onConfigure(); - setVisible(!getProject().equals(getMilestone().getProject())); + setVisible(!getProject().equals(getIteration().getProject())); } }); - add(new MultilineLabel("description", getMilestone().getDescription()) { + add(new MultilineLabel("description", getIteration().getDescription()) { @Override protected void onConfigure() { super.onConfigure(); - setVisible(getMilestone().getDescription() != null); + setVisible(getIteration().getDescription() != null); } }); List tabs = new ArrayList<>(); - tabs.add(new MilestoneTab("Issues", MilestoneIssuesPage.class)); - tabs.add(new MilestoneTab("Burndown", MilestoneBurndownPage.class)); + tabs.add(new IterationTab("Issues", IterationIssuesPage.class)); + tabs.add(new IterationTab("Burndown", IterationBurndownPage.class)); - add(new Tabbable("milestoneTabs", tabs).setOutputMarkupId(true)); + add(new Tabbable("iterationTabs", tabs).setOutputMarkupId(true)); } @Override protected void onDetach() { - milestoneModel.detach(); + iterationModel.detach(); super.onDetach(); } - public static PageParameters paramsOf(Project project, Milestone milestone) { + public static PageParameters paramsOf(Project project, Iteration iteration) { PageParameters params = paramsOf(project); - params.add(PARAM_MILESTONE, milestone.getId()); + params.add(PARAM_ITERATION, iteration.getId()); return params; } @Override public void renderHead(IHeaderResponse response) { super.renderHead(response); - response.render(CssHeaderItem.forReference(new MilestoneCssResourceReference())); + response.render(CssHeaderItem.forReference(new IterationCssResourceReference())); } @Override protected Component newProjectTitle(String componentId) { Fragment fragment = new Fragment(componentId, "projectTitleFrag", this); - fragment.add(new BookmarkablePageLink("milestones", MilestoneListPage.class, - MilestoneListPage.paramsOf(getProject()))); - fragment.add(new Label("milestoneName", getMilestone().getName())); + fragment.add(new BookmarkablePageLink("iterations", IterationListPage.class, + IterationListPage.paramsOf(getProject()))); + fragment.add(new Label("iterationName", getIteration().getName())); return fragment; } @Override protected String getPageTitle() { - return "Milestone " + getMilestone().getName() + " - " + getProject().getPath(); + return "Iteration " + getIteration().getName() + " - " + getProject().getPath(); } - private class MilestoneTab extends PageTab { + private class IterationTab extends PageTab { - public MilestoneTab(String title, Class pageClass) { + public IterationTab(String title, Class pageClass) { super(Model.of(title), pageClass); } @@ -170,7 +170,7 @@ public abstract class MilestoneDetailPage extends ProjectPage { @Override protected Link newLink(String linkId, Class pageClass) { - return new ViewStateAwarePageLink(linkId, pageClass, paramsOf(getProject(), getMilestone())); + return new ViewStateAwarePageLink(linkId, pageClass, paramsOf(getProject(), getIteration())); } }; @@ -181,7 +181,7 @@ public abstract class MilestoneDetailPage extends ProjectPage { @Override protected BookmarkablePageLink navToProject(String componentId, Project project) { if (project.isIssueManagement()) - return new ViewStateAwarePageLink(componentId, MilestoneListPage.class, MilestoneListPage.paramsOf(project, false, null)); + return new ViewStateAwarePageLink(componentId, IterationListPage.class, IterationListPage.paramsOf(project, false, null)); else return new ViewStateAwarePageLink(componentId, ProjectDashboardPage.class, ProjectDashboardPage.paramsOf(project)); } diff --git a/server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneEditPage.html b/server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationEditPage.html similarity index 83% rename from server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneEditPage.html rename to server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationEditPage.html index 3ebce862ca..987a408fb8 100644 --- a/server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneEditPage.html +++ b/server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationEditPage.html @@ -11,9 +11,9 @@ - Milestones + Iterations - + Edit diff --git a/server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneEditPage.java b/server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationEditPage.java similarity index 51% rename from server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneEditPage.java rename to server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationEditPage.java index a4dd2296f3..629342a7d3 100644 --- a/server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneEditPage.java +++ b/server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationEditPage.java @@ -1,8 +1,8 @@ -package io.onedev.server.web.page.project.issues.milestones; +package io.onedev.server.web.page.project.issues.iteration; import io.onedev.server.OneDev; -import io.onedev.server.entitymanager.MilestoneManager; -import io.onedev.server.model.Milestone; +import io.onedev.server.entitymanager.IterationManager; +import io.onedev.server.model.Iteration; import io.onedev.server.model.Project; import io.onedev.server.security.SecurityUtils; import io.onedev.server.web.component.link.ViewStateAwarePageLink; @@ -10,7 +10,7 @@ import io.onedev.server.web.editable.BeanContext; import io.onedev.server.web.editable.BeanEditor; import io.onedev.server.web.page.project.ProjectPage; import io.onedev.server.web.page.project.dashboard.ProjectDashboardPage; -import io.onedev.server.web.util.editbean.MilestoneEditBean; +import io.onedev.server.web.util.editbean.IterationEditBean; import org.apache.wicket.Component; import org.apache.wicket.Session; import org.apache.wicket.markup.html.basic.Label; @@ -22,35 +22,35 @@ import org.apache.wicket.model.IModel; import org.apache.wicket.model.LoadableDetachableModel; import org.apache.wicket.request.mapper.parameter.PageParameters; -public class MilestoneEditPage extends ProjectPage { +public class IterationEditPage extends ProjectPage { - private static final String PARAM_MILESTONE = "milestone"; + private static final String PARAM_ITERATION = "iteration"; - private final IModel milestoneModel; + private final IModel iterationIModel; - public MilestoneEditPage(PageParameters params) { + public IterationEditPage(PageParameters params) { super(params); - Long milestoneId = params.get(PARAM_MILESTONE).toLong(); - milestoneModel = new LoadableDetachableModel() { + Long iterationId = params.get(PARAM_ITERATION).toLong(); + iterationIModel = new LoadableDetachableModel() { @Override - protected Milestone load() { - return OneDev.getInstance(MilestoneManager.class).load(milestoneId); + protected Iteration load() { + return OneDev.getInstance(IterationManager.class).load(iterationId); } }; } - private Milestone getMilestone() { - return milestoneModel.getObject(); + private Iteration getIteration() { + return iterationIModel.getObject(); } @Override protected void onInitialize() { super.onInitialize(); - var bean = MilestoneEditBean.of(getMilestone(), ""); + var bean = IterationEditBean.of(getIteration(), ""); BeanEditor editor = BeanContext.edit("editor", bean); Form form = new Form("form") { @@ -58,11 +58,11 @@ public class MilestoneEditPage extends ProjectPage { protected void onSubmit() { super.onSubmit(); - bean.update(getMilestone()); - OneDev.getInstance(MilestoneManager.class).createOrUpdate(getMilestone()); - Session.get().success("Milestone saved"); - setResponsePage(MilestoneIssuesPage.class, - MilestoneIssuesPage.paramsOf(getMilestone().getProject(), getMilestone(), null)); + bean.update(getIteration()); + OneDev.getInstance(IterationManager.class).createOrUpdate(getIteration()); + Session.get().success("Iteration saved"); + setResponsePage(IterationIssuesPage.class, + IterationIssuesPage.paramsOf(getIteration().getProject(), getIteration(), null)); } @@ -73,13 +73,13 @@ public class MilestoneEditPage extends ProjectPage { @Override protected void onDetach() { - milestoneModel.detach(); + iterationIModel.detach(); super.onDetach(); } - public static PageParameters paramsOf(Milestone milestone) { - PageParameters params = paramsOf(milestone.getProject()); - params.add(PARAM_MILESTONE, milestone.getId()); + public static PageParameters paramsOf(Iteration iteration) { + PageParameters params = paramsOf(iteration.getProject()); + params.add(PARAM_ITERATION, iteration.getId()); return params; } @@ -91,11 +91,11 @@ public class MilestoneEditPage extends ProjectPage { @Override protected Component newProjectTitle(String componentId) { Fragment fragment = new Fragment(componentId, "projectTitleFrag", this); - fragment.add(new BookmarkablePageLink("milestones", MilestoneListPage.class, - MilestoneListPage.paramsOf(getProject()))); - Link link = new BookmarkablePageLink("milestone", MilestoneIssuesPage.class, - MilestoneIssuesPage.paramsOf(getMilestone().getProject(), getMilestone(), null)); - link.add(new Label("name", getMilestone().getName())); + fragment.add(new BookmarkablePageLink("iterations", IterationListPage.class, + IterationListPage.paramsOf(getProject()))); + Link link = new BookmarkablePageLink("iteration", IterationIssuesPage.class, + IterationIssuesPage.paramsOf(getIteration().getProject(), getIteration(), null)); + link.add(new Label("name", getIteration().getName())); fragment.add(link); return fragment; } @@ -103,7 +103,7 @@ public class MilestoneEditPage extends ProjectPage { @Override protected BookmarkablePageLink navToProject(String componentId, Project project) { if (project.isIssueManagement()) - return new ViewStateAwarePageLink(componentId, MilestoneListPage.class, MilestoneListPage.paramsOf(project, false, null)); + return new ViewStateAwarePageLink(componentId, IterationListPage.class, IterationListPage.paramsOf(project, false, null)); else return new ViewStateAwarePageLink(componentId, ProjectDashboardPage.class, ProjectDashboardPage.paramsOf(project)); } diff --git a/server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneIssuesPage.html b/server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationIssuesPage.html similarity index 82% rename from server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneIssuesPage.html rename to server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationIssuesPage.html index 617cf8a259..9dd74701c7 100644 --- a/server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneIssuesPage.html +++ b/server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationIssuesPage.html @@ -1,5 +1,5 @@ -
+
diff --git a/server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneIssuesPage.java b/server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationIssuesPage.java similarity index 75% rename from server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneIssuesPage.java rename to server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationIssuesPage.java index b3922c73f7..fb089b0cba 100644 --- a/server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneIssuesPage.java +++ b/server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationIssuesPage.java @@ -1,4 +1,4 @@ -package io.onedev.server.web.page.project.issues.milestones; +package io.onedev.server.web.page.project.issues.iteration; import java.io.Serializable; import java.util.ArrayList; @@ -13,11 +13,10 @@ import org.apache.wicket.model.LoadableDetachableModel; import org.apache.wicket.request.cycle.RequestCycle; import org.apache.wicket.request.mapper.parameter.PageParameters; -import io.onedev.server.model.Milestone; +import io.onedev.server.model.Iteration; import io.onedev.server.model.Project; import io.onedev.server.search.entity.issue.IssueQuery; -import io.onedev.server.search.entity.issue.IssueQueryLexer; -import io.onedev.server.search.entity.issue.MilestoneCriteria; +import io.onedev.server.search.entity.issue.IterationCriteria; import io.onedev.server.search.entity.issue.StateCriteria; import io.onedev.server.web.component.issue.list.IssueListPanel; import io.onedev.server.web.component.issue.statestats.StateStatsBar; @@ -27,7 +26,7 @@ import io.onedev.server.web.util.PagingHistorySupport; import static io.onedev.server.search.entity.issue.IssueQueryLexer.Is; @SuppressWarnings("serial") -public class MilestoneIssuesPage extends MilestoneDetailPage { +public class IterationIssuesPage extends IterationDetailPage { private static final String PARAM_QUERY = "query"; @@ -37,7 +36,7 @@ public class MilestoneIssuesPage extends MilestoneDetailPage { private IssueListPanel issueList; - public MilestoneIssuesPage(PageParameters params) { + public IterationIssuesPage(PageParameters params) { super(params); query = params.get(PARAM_QUERY).toString(); @@ -51,7 +50,7 @@ public class MilestoneIssuesPage extends MilestoneDetailPage { @Override protected Map load() { - return getMilestone().getStateStats(getProject()); + return getIteration().getStateStats(getProject()); } }) { @@ -59,8 +58,8 @@ public class MilestoneIssuesPage extends MilestoneDetailPage { @Override protected Link newStateLink(String componentId, String state) { String query = new IssueQuery(new StateCriteria(state, Is)).toString(); - PageParameters params = paramsOf(getProject(), getMilestone(), query); - return new ViewStateAwarePageLink(componentId, MilestoneIssuesPage.class, params); + PageParameters params = paramsOf(getProject(), getIteration(), query); + return new ViewStateAwarePageLink(componentId, IterationIssuesPage.class, params); } }); @@ -82,7 +81,7 @@ public class MilestoneIssuesPage extends MilestoneDetailPage { PageParameters params = getPageParameters(); params.set(PARAM_QUERY, query); params.remove(PARAM_PAGE); - CharSequence url = RequestCycle.get().urlFor(MilestoneIssuesPage.class, params); + CharSequence url = RequestCycle.get().urlFor(IterationIssuesPage.class, params); pushState(RequestCycle.get().find(AjaxRequestTarget.class), url.toString(), query); } @@ -90,7 +89,7 @@ public class MilestoneIssuesPage extends MilestoneDetailPage { @Override protected IssueQuery getBaseQuery() { - return new IssueQuery(new MilestoneCriteria(getMilestone().getName(), Is), new ArrayList<>()); + return new IssueQuery(new IterationCriteria(getIteration().getName(), Is), new ArrayList<>()); } @Override @@ -99,7 +98,7 @@ public class MilestoneIssuesPage extends MilestoneDetailPage { @Override public PageParameters newPageParameters(int currentPage) { - PageParameters params = paramsOf(getProject(), getMilestone(), query); + PageParameters params = paramsOf(getProject(), getIteration(), query); params.add(PARAM_PAGE, currentPage+1); return params; } @@ -114,7 +113,7 @@ public class MilestoneIssuesPage extends MilestoneDetailPage { @Override protected Project getProject() { - return MilestoneIssuesPage.this.getProject(); + return IterationIssuesPage.this.getProject(); } }); @@ -128,8 +127,8 @@ public class MilestoneIssuesPage extends MilestoneDetailPage { add(issueList); } - public static PageParameters paramsOf(Project project, Milestone milestone, @Nullable String query) { - PageParameters params = paramsOf(project, milestone); + public static PageParameters paramsOf(Project project, Iteration iteration, @Nullable String query) { + PageParameters params = paramsOf(project, iteration); if (query != null) params.add(PARAM_QUERY, query); return params; diff --git a/server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationListPage.html b/server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationListPage.html new file mode 100644 index 0000000000..1ae4b8a60c --- /dev/null +++ b/server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationListPage.html @@ -0,0 +1,3 @@ + +
+
diff --git a/server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneListPage.java b/server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationListPage.java similarity index 72% rename from server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneListPage.java rename to server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationListPage.java index 77b0966200..af08f9d61b 100644 --- a/server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneListPage.java +++ b/server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/IterationListPage.java @@ -1,4 +1,4 @@ -package io.onedev.server.web.page.project.issues.milestones; +package io.onedev.server.web.page.project.issues.iteration; import javax.annotation.Nullable; @@ -10,14 +10,14 @@ import org.apache.wicket.markup.html.link.BookmarkablePageLink; import org.apache.wicket.request.mapper.parameter.PageParameters; import io.onedev.server.model.Project; -import io.onedev.server.util.MilestoneSort; -import io.onedev.server.web.component.milestone.list.MilestoneListPanel; +import io.onedev.server.util.IterationSort; +import io.onedev.server.web.component.iteration.list.IterationListPanel; import io.onedev.server.web.page.project.ProjectPage; import io.onedev.server.web.page.project.dashboard.ProjectDashboardPage; import io.onedev.server.web.util.PagingHistorySupport; @SuppressWarnings("serial") -public class MilestoneListPage extends ProjectPage { +public class IterationListPage extends ProjectPage { private static final String PARAM_STATE = "state"; @@ -27,9 +27,9 @@ public class MilestoneListPage extends ProjectPage { private final boolean closed; - private final MilestoneSort sort; + private final IterationSort sort; - public MilestoneListPage(PageParameters params) { + public IterationListPage(PageParameters params) { super(params); String state = params.get(PARAM_STATE).toString(); @@ -40,9 +40,9 @@ public class MilestoneListPage extends ProjectPage { String sortString = params.get(PARAM_SORT).toString(); if (sortString != null) - sort = MilestoneSort.valueOf(sortString.toUpperCase()); + sort = IterationSort.valueOf(sortString.toUpperCase()); else - sort = MilestoneSort.CLOSEST_DUE_DATE; + sort = IterationSort.CLOSEST_DUE_DATE; } @Override @@ -64,22 +64,22 @@ public class MilestoneListPage extends ProjectPage { } }; - add(new MilestoneListPanel("milestones", projectModel, closed, sort, pagingHistorySupport) { + add(new IterationListPanel("iterations", projectModel, closed, sort, pagingHistorySupport) { @Override - protected void onSortChanged(AjaxRequestTarget target, MilestoneSort sort) { - setResponsePage(MilestoneListPage.class, paramsOf(getProject(), closed, sort)); + protected void onSortChanged(AjaxRequestTarget target, IterationSort sort) { + setResponsePage(IterationListPage.class, paramsOf(getProject(), closed, sort)); } @Override protected void onStateChanged(AjaxRequestTarget target, boolean closed) { - setResponsePage(MilestoneListPage.class, paramsOf(getProject(), closed, sort)); + setResponsePage(IterationListPage.class, paramsOf(getProject(), closed, sort)); } }); } - public static PageParameters paramsOf(Project project, boolean closed, @Nullable MilestoneSort sort) { + public static PageParameters paramsOf(Project project, boolean closed, @Nullable IterationSort sort) { PageParameters params = paramsOf(project); if (closed) params.add(PARAM_STATE, "closed"); @@ -93,18 +93,18 @@ public class MilestoneListPage extends ProjectPage { @Override protected Component newProjectTitle(String componentId) { - return new Label(componentId, "Milestones"); + return new Label(componentId, "Iterations"); } @Override protected String getPageTitle() { - return "Milestones - " + getProject().getPath(); + return "Iterations - " + getProject().getPath(); } @Override protected BookmarkablePageLink navToProject(String componentId, Project project) { if (project.isIssueManagement()) - return new ViewStateAwarePageLink(componentId, MilestoneListPage.class, MilestoneListPage.paramsOf(project, false, null)); + return new ViewStateAwarePageLink(componentId, IterationListPage.class, IterationListPage.paramsOf(project, false, null)); else return new ViewStateAwarePageLink(componentId, ProjectDashboardPage.class, ProjectDashboardPage.paramsOf(project.getId())); } diff --git a/server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/NewMilestonePage.html b/server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/NewIterationPage.html similarity index 100% rename from server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/NewMilestonePage.html rename to server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/NewIterationPage.html diff --git a/server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/NewMilestonePage.java b/server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/NewIterationPage.java similarity index 64% rename from server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/NewMilestonePage.java rename to server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/NewIterationPage.java index 4ecf588403..a16ee17783 100644 --- a/server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/NewMilestonePage.java +++ b/server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/NewIterationPage.java @@ -1,8 +1,8 @@ -package io.onedev.server.web.page.project.issues.milestones; +package io.onedev.server.web.page.project.issues.iteration; import io.onedev.server.OneDev; -import io.onedev.server.entitymanager.MilestoneManager; -import io.onedev.server.model.Milestone; +import io.onedev.server.entitymanager.IterationManager; +import io.onedev.server.model.Iteration; import io.onedev.server.model.Project; import io.onedev.server.security.SecurityUtils; import io.onedev.server.web.component.link.ViewStateAwarePageLink; @@ -10,7 +10,7 @@ import io.onedev.server.web.editable.BeanContext; import io.onedev.server.web.editable.BeanEditor; import io.onedev.server.web.page.project.ProjectPage; import io.onedev.server.web.page.project.dashboard.ProjectDashboardPage; -import io.onedev.server.web.util.editbean.MilestoneEditBean; +import io.onedev.server.web.util.editbean.IterationEditBean; import org.apache.wicket.Component; import org.apache.wicket.Session; import org.apache.wicket.markup.html.basic.Label; @@ -19,9 +19,9 @@ import org.apache.wicket.markup.html.link.BookmarkablePageLink; import org.apache.wicket.request.mapper.parameter.PageParameters; @SuppressWarnings("serial") -public class NewMilestonePage extends ProjectPage { +public class NewIterationPage extends ProjectPage { - public NewMilestonePage(PageParameters params) { + public NewIterationPage(PageParameters params) { super(params); } @@ -29,7 +29,7 @@ public class NewMilestonePage extends ProjectPage { protected void onInitialize() { super.onInitialize(); - var bean = MilestoneEditBean.ofNew(getProject(), ""); + var bean = IterationEditBean.ofNew(getProject(), ""); BeanEditor editor = BeanContext.edit("editor", bean); Form form = new Form("form") { @@ -37,12 +37,12 @@ public class NewMilestonePage extends ProjectPage { protected void onSubmit() { super.onSubmit(); - var milestone = new Milestone(); - milestone.setProject(getProject()); - bean.update(milestone); - OneDev.getInstance(MilestoneManager.class).createOrUpdate(milestone); - Session.get().success("New milestone created"); - setResponsePage(MilestoneIssuesPage.class, MilestoneIssuesPage.paramsOf(getProject(), milestone, null)); + var iteration = new Iteration(); + iteration.setProject(getProject()); + bean.update(iteration); + OneDev.getInstance(IterationManager.class).createOrUpdate(iteration); + Session.get().success("New iteration created"); + setResponsePage(IterationIssuesPage.class, IterationIssuesPage.paramsOf(getProject(), iteration, null)); } }; @@ -61,13 +61,13 @@ public class NewMilestonePage extends ProjectPage { @Override protected Component newProjectTitle(String componentId) { - return new Label(componentId, "Create Milestone"); + return new Label(componentId, "Create Iteration"); } @Override protected BookmarkablePageLink navToProject(String componentId, Project project) { if (project.isIssueManagement()) - return new ViewStateAwarePageLink(componentId, MilestoneListPage.class, MilestoneListPage.paramsOf(project, false, null)); + return new ViewStateAwarePageLink(componentId, IterationListPage.class, IterationListPage.paramsOf(project, false, null)); else return new ViewStateAwarePageLink(componentId, ProjectDashboardPage.class, ProjectDashboardPage.paramsOf(project)); } diff --git a/server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/iteration.css b/server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/iteration.css new file mode 100644 index 0000000000..7085461233 --- /dev/null +++ b/server-core/src/main/java/io/onedev/server/web/page/project/issues/iteration/iteration.css @@ -0,0 +1,3 @@ +.iteration-burndown .line-chart { + height: 480px; +} \ No newline at end of file diff --git a/server-core/src/main/java/io/onedev/server/web/page/project/issues/list/ProjectIssueListPage.java b/server-core/src/main/java/io/onedev/server/web/page/project/issues/list/ProjectIssueListPage.java index 974ec71334..bc75ec7bca 100644 --- a/server-core/src/main/java/io/onedev/server/web/page/project/issues/list/ProjectIssueListPage.java +++ b/server-core/src/main/java/io/onedev/server/web/page/project/issues/list/ProjectIssueListPage.java @@ -24,7 +24,7 @@ import io.onedev.server.web.component.issue.fieldvalues.FieldValuesPanel; import io.onedev.server.web.component.issue.link.IssueLinksPanel; import io.onedev.server.web.component.issue.list.IssueListPanel; import io.onedev.server.web.component.issue.list.IssuePinStatusChanged; -import io.onedev.server.web.component.issue.milestone.MilestoneCrumbPanel; +import io.onedev.server.web.component.issue.iteration.IterationCrumbPanel; import io.onedev.server.web.component.issue.operation.TransitionMenuLink; import io.onedev.server.web.component.issue.progress.IssueProgressPanel; import io.onedev.server.web.component.issue.title.IssueTitlePanel; @@ -152,8 +152,8 @@ public class ProjectIssueListPage extends ProjectIssuesPage { stateFragment.add(transitLink); fieldsView.add(stateFragment.setOutputMarkupId(true)); - } else if (fieldName.equals(IssueSchedule.NAME_MILESTONE)) { - fieldsView.add(new MilestoneCrumbPanel(fieldsView.newChildId()) { + } else if (fieldName.equals(IssueSchedule.NAME_ITERATION)) { + fieldsView.add(new IterationCrumbPanel(fieldsView.newChildId()) { @Override protected Issue getIssue() { return getIssueManager().load(issueId); diff --git a/server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneCssResourceReference.java b/server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneCssResourceReference.java deleted file mode 100644 index b630672f54..0000000000 --- a/server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneCssResourceReference.java +++ /dev/null @@ -1,13 +0,0 @@ -package io.onedev.server.web.page.project.issues.milestones; - -import io.onedev.server.web.page.base.BaseDependentCssResourceReference; - -public class MilestoneCssResourceReference extends BaseDependentCssResourceReference { - - private static final long serialVersionUID = 1L; - - public MilestoneCssResourceReference() { - super(MilestoneCssResourceReference.class, "milestone.css"); - } - -} diff --git a/server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneListPage.html b/server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneListPage.html deleted file mode 100644 index 96d4af4a23..0000000000 --- a/server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/MilestoneListPage.html +++ /dev/null @@ -1,3 +0,0 @@ - -
-
diff --git a/server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/milestone.css b/server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/milestone.css deleted file mode 100644 index deda3e6487..0000000000 --- a/server-core/src/main/java/io/onedev/server/web/page/project/issues/milestones/milestone.css +++ /dev/null @@ -1,3 +0,0 @@ -.milestone-burndown .line-chart { - height: 480px; -} \ No newline at end of file diff --git a/server-core/src/main/java/io/onedev/server/web/util/ProjectAware.java b/server-core/src/main/java/io/onedev/server/web/util/ProjectAware.java index 2f93094382..24b500f62c 100644 --- a/server-core/src/main/java/io/onedev/server/web/util/ProjectAware.java +++ b/server-core/src/main/java/io/onedev/server/web/util/ProjectAware.java @@ -2,8 +2,11 @@ package io.onedev.server.web.util; import io.onedev.server.model.Project; +import javax.annotation.Nullable; + public interface ProjectAware { + @Nullable Project getProject(); } diff --git a/server-core/src/main/java/io/onedev/server/web/util/SuggestionUtils.java b/server-core/src/main/java/io/onedev/server/web/util/SuggestionUtils.java index 833d15e6f3..b52d101077 100644 --- a/server-core/src/main/java/io/onedev/server/web/util/SuggestionUtils.java +++ b/server-core/src/main/java/io/onedev/server/web/util/SuggestionUtils.java @@ -475,13 +475,13 @@ public class SuggestionUtils { return sortAndTruncate(suggestions, matchWith); } - public static List suggestMilestones(Project project, String matchWith) { - List milestoneNames = project.getHierarchyMilestones() + public static List suggestIterations(Project project, String matchWith) { + List iterationNames = project.getHierarchyIterations() .stream() .map(it->it.getName()) .sorted() .collect(toList()); - return suggest(milestoneNames, matchWith); + return suggest(iterationNames, matchWith); } private static Set getChildren(List allApplied, String path) { diff --git a/server-core/src/main/java/io/onedev/server/web/util/editbean/MilestoneEditBean.java b/server-core/src/main/java/io/onedev/server/web/util/editbean/IterationEditBean.java similarity index 65% rename from server-core/src/main/java/io/onedev/server/web/util/editbean/MilestoneEditBean.java rename to server-core/src/main/java/io/onedev/server/web/util/editbean/IterationEditBean.java index 95ce0ed7b4..07dc847355 100644 --- a/server-core/src/main/java/io/onedev/server/web/util/editbean/MilestoneEditBean.java +++ b/server-core/src/main/java/io/onedev/server/web/util/editbean/IterationEditBean.java @@ -4,8 +4,8 @@ import io.onedev.server.OneDev; import io.onedev.server.annotation.ClassValidating; import io.onedev.server.annotation.Editable; import io.onedev.server.annotation.Multiline; -import io.onedev.server.entitymanager.MilestoneManager; -import io.onedev.server.model.Milestone; +import io.onedev.server.entitymanager.IterationManager; +import io.onedev.server.model.Iteration; import io.onedev.server.model.Project; import io.onedev.server.validation.Validatable; import org.joda.time.DateTime; @@ -22,7 +22,7 @@ import static java.util.stream.Collectors.toList; @Editable @ClassValidating -public class MilestoneEditBean implements Validatable, Serializable { +public class IterationEditBean implements Validatable, Serializable { private static final Pattern ENDS_WITH_DIGITS = Pattern.compile("(.*)(\\d+)"); @@ -94,41 +94,41 @@ public class MilestoneEditBean implements Validatable, Serializable { this.dueDate = dueDate; } - public void update(Milestone milestone) { - milestone.setName(getName()); - milestone.setDescription(getDescription()); - milestone.setStartDate(getStartDate()); - milestone.setDueDate(getDueDate()); + public void update(Iteration iteration) { + iteration.setName(getName()); + iteration.setDescription(getDescription()); + iteration.setStartDate(getStartDate()); + iteration.setDueDate(getDueDate()); } - public static MilestoneEditBean ofNew(Project project, @Nullable String namePrefix) { - var bean = new MilestoneEditBean(); + public static IterationEditBean ofNew(Project project, @Nullable String namePrefix) { + var bean = new IterationEditBean(); bean.namePrefix = namePrefix; - var milestones = project.getSortedHierarchyMilestones().stream() + var iterations = project.getSortedHierarchyIterations().stream() .filter(it -> (namePrefix == null || it.getName().startsWith(namePrefix))) .collect(toList()); - if (!milestones.isEmpty()) { - var lastMilestone = milestones.get(milestones.size()-1); - var matcher = ENDS_WITH_DIGITS.matcher(lastMilestone.getName()); + if (!iterations.isEmpty()) { + var lastIteration = iterations.get(iterations.size()-1); + var matcher = ENDS_WITH_DIGITS.matcher(lastIteration.getName()); if (matcher.matches()) bean.setName(matcher.group(1) + (parseInt(matcher.group(2)) + 1)); - if (lastMilestone.getStartDate() != null && lastMilestone.getDueDate() != null) { - bean.setStartDate(new DateTime(lastMilestone.getDueDate()).plusDays(1).toDate()); - var duration = lastMilestone.getDueDate().getTime() - lastMilestone.getStartDate().getTime(); + if (lastIteration.getStartDate() != null && lastIteration.getDueDate() != null) { + bean.setStartDate(new DateTime(lastIteration.getDueDate()).plusDays(1).toDate()); + var duration = lastIteration.getDueDate().getTime() - lastIteration.getStartDate().getTime(); bean.setDueDate(new DateTime(bean.getStartDate()).plusMillis((int) duration).toDate()); } } return bean; } - public static MilestoneEditBean of(Milestone milestone, @Nullable String namePrefix) { - var bean = new MilestoneEditBean(); - bean.oldName = milestone.getName(); + public static IterationEditBean of(Iteration iteration, @Nullable String namePrefix) { + var bean = new IterationEditBean(); + bean.oldName = iteration.getName(); bean.namePrefix = namePrefix; - bean.setName(milestone.getName()); - bean.setDescription(milestone.getDescription()); - bean.setStartDate(milestone.getStartDate()); - bean.setDueDate(milestone.getDueDate()); + bean.setName(iteration.getName()); + bean.setDescription(iteration.getDescription()); + bean.setStartDate(iteration.getStartDate()); + bean.setDueDate(iteration.getDueDate()); return bean; } @@ -140,11 +140,11 @@ public class MilestoneEditBean implements Validatable, Serializable { .addPropertyNode("name").addConstraintViolation(); return false; } - MilestoneManager milestoneManager = OneDev.getInstance(MilestoneManager.class); - Milestone milestoneWithSameName = milestoneManager.findInHierarchy(Project.get(), name); - if (milestoneWithSameName != null && (oldName == null || !oldName.equals(name))) { + IterationManager iterationManager = OneDev.getInstance(IterationManager.class); + Iteration iterationWithSameName = iterationManager.findInHierarchy(Project.get(), name); + if (iterationWithSameName != null && (oldName == null || !oldName.equals(name))) { context.disableDefaultConstraintViolation(); - var message = "Name has already been used by another milestone in the project hierarchy"; + var message = "Name has already been used by another iteration in the project hierarchy"; context.buildConstraintViolationWithTemplate(message) .addPropertyNode("name") .addConstraintViolation(); diff --git a/server-ee b/server-ee index 01ddd724ce..0f3a32877e 160000 --- a/server-ee +++ b/server-ee @@ -1 +1 @@ -Subproject commit 01ddd724ce3f7c1aebf4a596d97455ebcc503e23 +Subproject commit 0f3a32877eec5a7f0e9a90fe4c1d4de6b500c1f6 diff --git a/server-plugin/server-plugin-import-gitea/src/main/java/io/onedev/server/plugin/imports/gitea/ImportResult.java b/server-plugin/server-plugin-import-gitea/src/main/java/io/onedev/server/plugin/imports/gitea/ImportResult.java index 53a9c5cbbd..2bdbc9eeaa 100644 --- a/server-plugin/server-plugin-import-gitea/src/main/java/io/onedev/server/plugin/imports/gitea/ImportResult.java +++ b/server-plugin/server-plugin-import-gitea/src/main/java/io/onedev/server/plugin/imports/gitea/ImportResult.java @@ -6,7 +6,6 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import io.onedev.server.model.Issue; import org.unbescape.html.HtmlEscape; public class ImportResult { @@ -17,7 +16,7 @@ public class ImportResult { Set unmappedIssueLabels = new HashSet<>(); - Set nonExistentMilestones = new HashSet<>(); + Set nonExistentIterations = new HashSet<>(); boolean issuesImported; @@ -35,7 +34,7 @@ public class ImportResult { boolean hasNotice = false; - if (!nonExistentMilestones.isEmpty() || !unmappedIssueLabels.isEmpty() + if (!nonExistentIterations.isEmpty() || !unmappedIssueLabels.isEmpty() || !nonExistentLogins.isEmpty() || issuesImported) { hasNotice = true; } @@ -43,8 +42,8 @@ public class ImportResult { if (hasNotice) feedback.append("

NOTE:
    "); - if (!nonExistentMilestones.isEmpty()) - feedback.append(getEntryFeedback("Non existent milestones", nonExistentMilestones)); + if (!nonExistentIterations.isEmpty()) + feedback.append(getEntryFeedback("Non existent iterations", nonExistentIterations)); if (!unmappedIssueLabels.isEmpty()) feedback.append(getEntryFeedback("Gitea issue labels not mapped to OneDev custom field", unmappedIssueLabels)); if (!nonExistentLogins.isEmpty()) { diff --git a/server-plugin/server-plugin-import-gitea/src/main/java/io/onedev/server/plugin/imports/gitea/ImportServer.java b/server-plugin/server-plugin-import-gitea/src/main/java/io/onedev/server/plugin/imports/gitea/ImportServer.java index 141c1caf07..64aa24df24 100644 --- a/server-plugin/server-plugin-import-gitea/src/main/java/io/onedev/server/plugin/imports/gitea/ImportServer.java +++ b/server-plugin/server-plugin-import-gitea/src/main/java/io/onedev/server/plugin/imports/gitea/ImportServer.java @@ -217,12 +217,12 @@ public class ImportServer implements Serializable, Validatable { IssueManager issueManager = OneDev.getInstance(IssueManager.class); Client client = newClient(); try { - Set nonExistentMilestones = new HashSet<>(); + Set nonExistentIterations = new HashSet<>(); Set nonExistentLogins = new HashSet<>(); Set unmappedIssueLabels = new HashSet<>(); Map> labelMappings = new HashMap<>(); - Map milestoneMappings = new HashMap<>(); + Map iterationMappings = new HashMap<>(); for (IssueLabelMapping mapping: option.getIssueLabelMappings()) { String oneDevFieldName = StringUtils.substringBefore(mapping.getOneDevIssueField(), "::"); @@ -233,8 +233,8 @@ public class ImportServer implements Serializable, Validatable { labelMappings.put(mapping.getGiteaIssueLabel(), new Pair<>(fieldSpec, oneDevFieldValue)); } - for (Milestone milestone: oneDevProject.getMilestones()) - milestoneMappings.put(milestone.getName(), milestone); + for (Iteration iteration: oneDevProject.getIterations()) + iterationMappings.put(iteration.getName(), iteration); String initialIssueState = getIssueSetting().getInitialStateSpec().getName(); @@ -286,15 +286,15 @@ public class ImportServer implements Serializable, Validatable { if (issueNode.hasNonNull("milestone")) { String milestoneName = issueNode.get("milestone").get("title").asText(); - Milestone milestone = milestoneMappings.get(milestoneName); - if (milestone != null) { + Iteration iteration = iterationMappings.get(milestoneName); + if (iteration != null) { IssueSchedule schedule = new IssueSchedule(); schedule.setIssue(issue); - schedule.setMilestone(milestone); + schedule.setIteration(iteration); issue.getSchedules().add(schedule); } else { extraIssueInfo.put("Milestone", milestoneName); - nonExistentMilestones.add(milestoneName); + nonExistentIterations.add(milestoneName); } } @@ -459,7 +459,7 @@ public class ImportServer implements Serializable, Validatable { ImportResult result = new ImportResult(); result.nonExistentLogins.addAll(nonExistentLogins); - result.nonExistentMilestones.addAll(nonExistentMilestones); + result.nonExistentIterations.addAll(nonExistentIterations); result.unmappedIssueLabels.addAll(unmappedIssueLabels); result.issuesImported = !issues.isEmpty(); @@ -536,22 +536,22 @@ public class ImportServer implements Serializable, Validatable { apiEndpoint = getApiEndpoint("/repos/" + giteaRepository + "/milestones?state=all"); for (JsonNode milestoneNode : list(client, apiEndpoint, logger)) { String milestoneName = milestoneNode.get("title").asText(); - Milestone milestone = project.getMilestone(milestoneName); - if (milestone == null) { - milestone = new Milestone(); - milestone.setName(milestoneName); - milestone.setDescription(milestoneNode.get("description").asText(null)); - milestone.setProject(project); + Iteration iteration = project.getIteration(milestoneName); + if (iteration == null) { + iteration = new Iteration(); + iteration.setName(milestoneName); + iteration.setDescription(milestoneNode.get("description").asText(null)); + iteration.setProject(project); String dueDateString = milestoneNode.get("due_on").asText(null); if (dueDateString != null) - milestone.setDueDate(ISODateTimeFormat.dateTimeNoMillis().parseDateTime(dueDateString).toDate()); + iteration.setDueDate(ISODateTimeFormat.dateTimeNoMillis().parseDateTime(dueDateString).toDate()); if (milestoneNode.get("state").asText().equals("closed")) - milestone.setClosed(true); + iteration.setClosed(true); - project.getMilestones().add(milestone); + project.getIterations().add(iteration); if (!dryRun) - OneDev.getInstance(MilestoneManager.class).createOrUpdate(milestone); + OneDev.getInstance(IterationManager.class).createOrUpdate(iteration); } } @@ -559,7 +559,7 @@ public class ImportServer implements Serializable, Validatable { ImportResult currentResult = importIssues(giteaRepository, project, option.getIssueImportOption(), userIds, dryRun, logger); result.nonExistentLogins.addAll(currentResult.nonExistentLogins); - result.nonExistentMilestones.addAll(currentResult.nonExistentMilestones); + result.nonExistentIterations.addAll(currentResult.nonExistentIterations); result.unmappedIssueLabels.addAll(currentResult.unmappedIssueLabels); result.issuesImported = result.issuesImported || currentResult.issuesImported; } diff --git a/server-plugin/server-plugin-import-github/src/main/java/io/onedev/server/plugin/imports/github/ImportResult.java b/server-plugin/server-plugin-import-github/src/main/java/io/onedev/server/plugin/imports/github/ImportResult.java index 41142b5023..fb920fb1f7 100644 --- a/server-plugin/server-plugin-import-github/src/main/java/io/onedev/server/plugin/imports/github/ImportResult.java +++ b/server-plugin/server-plugin-import-github/src/main/java/io/onedev/server/plugin/imports/github/ImportResult.java @@ -6,7 +6,6 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import io.onedev.server.model.Issue; import org.unbescape.html.HtmlEscape; public class ImportResult { @@ -17,7 +16,7 @@ public class ImportResult { Set unmappedIssueLabels = new HashSet<>(); - Set nonExistentMilestones = new HashSet<>(); + Set nonExistentIterations = new HashSet<>(); boolean issuesImported; @@ -35,7 +34,7 @@ public class ImportResult { boolean hasNotice = false; - if (!nonExistentMilestones.isEmpty() || !unmappedIssueLabels.isEmpty() + if (!nonExistentIterations.isEmpty() || !unmappedIssueLabels.isEmpty() || !nonExistentLogins.isEmpty() || issuesImported) { hasNotice = true; } @@ -43,8 +42,8 @@ public class ImportResult { if (hasNotice) feedback.append("

    NOTE:
      "); - if (!nonExistentMilestones.isEmpty()) - feedback.append(getEntryFeedback("Non existent milestones", nonExistentMilestones)); + if (!nonExistentIterations.isEmpty()) + feedback.append(getEntryFeedback("Non existent iterations", nonExistentIterations)); if (!unmappedIssueLabels.isEmpty()) { feedback.append(getEntryFeedback("GitHub issue labels not mapped to OneDev custom field", unmappedIssueLabels)); diff --git a/server-plugin/server-plugin-import-github/src/main/java/io/onedev/server/plugin/imports/github/ImportServer.java b/server-plugin/server-plugin-import-github/src/main/java/io/onedev/server/plugin/imports/github/ImportServer.java index 435c5c4b2f..c18a14e568 100644 --- a/server-plugin/server-plugin-import-github/src/main/java/io/onedev/server/plugin/imports/github/ImportServer.java +++ b/server-plugin/server-plugin-import-github/src/main/java/io/onedev/server/plugin/imports/github/ImportServer.java @@ -210,12 +210,12 @@ public class ImportServer implements Serializable, Validatable { Client client = newClient(); IssueManager issueManager = OneDev.getInstance(IssueManager.class); try { - Set nonExistentMilestones = new HashSet<>(); + Set nonExistentIterations = new HashSet<>(); Set nonExistentLogins = new HashSet<>(); Set unmappedIssueLabels = new HashSet<>(); Map> labelMappings = new HashMap<>(); - Map milestoneMappings = new HashMap<>(); + Map iterationMappings = new HashMap<>(); for (IssueLabelMapping mapping: importOption.getIssueLabelMappings()) { String oneDevFieldName = StringUtils.substringBefore(mapping.getOneDevIssueField(), "::"); @@ -226,8 +226,8 @@ public class ImportServer implements Serializable, Validatable { labelMappings.put(mapping.getGitHubIssueLabel(), new Pair<>(fieldSpec, oneDevFieldValue)); } - for (Milestone milestone: oneDevProject.getMilestones()) - milestoneMappings.put(milestone.getName(), milestone); + for (Iteration iteration: oneDevProject.getIterations()) + iterationMappings.put(iteration.getName(), iteration); String initialIssueState = getIssueSetting().getInitialStateSpec().getName(); @@ -279,15 +279,15 @@ public class ImportServer implements Serializable, Validatable { if (issueNode.hasNonNull("milestone")) { String milestoneName = issueNode.get("milestone").get("title").asText(); - Milestone milestone = milestoneMappings.get(milestoneName); - if (milestone != null) { + Iteration iteration = iterationMappings.get(milestoneName); + if (iteration != null) { IssueSchedule schedule = new IssueSchedule(); schedule.setIssue(issue); - schedule.setMilestone(milestone); + schedule.setIteration(iteration); issue.getSchedules().add(schedule); } else { extraIssueInfo.put("Milestone", milestoneName); - nonExistentMilestones.add(milestoneName); + nonExistentIterations.add(milestoneName); } } @@ -434,7 +434,7 @@ public class ImportServer implements Serializable, Validatable { ImportResult result = new ImportResult(); result.nonExistentLogins.addAll(nonExistentLogins); - result.nonExistentMilestones.addAll(nonExistentMilestones); + result.nonExistentIterations.addAll(nonExistentIterations); result.unmappedIssueLabels.addAll(unmappedIssueLabels); result.issuesImported = !issues.isEmpty(); @@ -584,22 +584,22 @@ public class ImportServer implements Serializable, Validatable { apiEndpoint = getApiEndpoint("/repos/" + gitHubRepository + "/milestones?state=all"); for (JsonNode milestoneNode : list(client, apiEndpoint, logger)) { String milestoneName = milestoneNode.get("title").asText(); - Milestone milestone = project.getMilestone(milestoneName); - if (milestone == null) { - milestone = new Milestone(); - milestone.setName(milestoneName); - milestone.setDescription(milestoneNode.get("description").asText(null)); - milestone.setProject(project); + Iteration iteration = project.getIteration(milestoneName); + if (iteration == null) { + iteration = new Iteration(); + iteration.setName(milestoneName); + iteration.setDescription(milestoneNode.get("description").asText(null)); + iteration.setProject(project); String dueDateString = milestoneNode.get("due_on").asText(null); if (dueDateString != null) - milestone.setDueDate(ISODateTimeFormat.dateTimeNoMillis().parseDateTime(dueDateString).toDate()); + iteration.setDueDate(ISODateTimeFormat.dateTimeNoMillis().parseDateTime(dueDateString).toDate()); if (milestoneNode.get("state").asText().equals("closed")) - milestone.setClosed(true); + iteration.setClosed(true); - project.getMilestones().add(milestone); + project.getIterations().add(iteration); if (!dryRun) - OneDev.getInstance(MilestoneManager.class).createOrUpdate(milestone); + OneDev.getInstance(IterationManager.class).createOrUpdate(iteration); } } @@ -607,7 +607,7 @@ public class ImportServer implements Serializable, Validatable { ImportResult currentResult = importIssues(gitHubRepository, project, option.getIssueImportOption(), userIds, dryRun, logger); result.nonExistentLogins.addAll(currentResult.nonExistentLogins); - result.nonExistentMilestones.addAll(currentResult.nonExistentMilestones); + result.nonExistentIterations.addAll(currentResult.nonExistentIterations); result.unmappedIssueLabels.addAll(currentResult.unmappedIssueLabels); result.issuesImported = result.issuesImported || currentResult.issuesImported; } diff --git a/server-plugin/server-plugin-import-gitlab/src/main/java/io/onedev/server/plugin/imports/gitlab/ImportResult.java b/server-plugin/server-plugin-import-gitlab/src/main/java/io/onedev/server/plugin/imports/gitlab/ImportResult.java index 3fd7be7b23..1211955d2a 100644 --- a/server-plugin/server-plugin-import-gitlab/src/main/java/io/onedev/server/plugin/imports/gitlab/ImportResult.java +++ b/server-plugin/server-plugin-import-gitlab/src/main/java/io/onedev/server/plugin/imports/gitlab/ImportResult.java @@ -12,7 +12,7 @@ public class ImportResult { Set unmappedIssueLabels = new HashSet<>(); - Set nonExistentMilestones = new HashSet<>(); + Set nonExistentIterations = new HashSet<>(); Set tooLargeAttachments = new LinkedHashSet<>(); @@ -32,7 +32,7 @@ public class ImportResult { boolean hasNotice = false; - if (!nonExistentMilestones.isEmpty() || !unmappedIssueLabels.isEmpty() + if (!nonExistentIterations.isEmpty() || !unmappedIssueLabels.isEmpty() || !nonExistentLogins.isEmpty() || !tooLargeAttachments.isEmpty() || !errorAttachments.isEmpty()) { hasNotice = true; @@ -41,8 +41,8 @@ public class ImportResult { if (hasNotice) feedback.append("

      NOTE:
        "); - if (!nonExistentMilestones.isEmpty()) - feedback.append(getEntryFeedback("Non existent milestones", nonExistentMilestones)); + if (!nonExistentIterations.isEmpty()) + feedback.append(getEntryFeedback("Non existent iterations", nonExistentIterations)); if (!unmappedIssueLabels.isEmpty()) feedback.append(getEntryFeedback("GitLab issue labels not mapped to OneDev custom field", unmappedIssueLabels)); if (!nonExistentLogins.isEmpty()) { diff --git a/server-plugin/server-plugin-import-gitlab/src/main/java/io/onedev/server/plugin/imports/gitlab/ImportServer.java b/server-plugin/server-plugin-import-gitlab/src/main/java/io/onedev/server/plugin/imports/gitlab/ImportServer.java index 254359a800..c76e51f1aa 100644 --- a/server-plugin/server-plugin-import-gitlab/src/main/java/io/onedev/server/plugin/imports/gitlab/ImportServer.java +++ b/server-plugin/server-plugin-import-gitlab/src/main/java/io/onedev/server/plugin/imports/gitlab/ImportServer.java @@ -222,34 +222,34 @@ public class ImportServer implements Serializable, Validatable { return userIdOpt.orElse(null); } - private List getMilestones(String groupId, TaskLogger logger) { + private List getIterations(String groupId, TaskLogger logger) { Client client = newClient(); try { - List milestones = new ArrayList<>(); + List iterations = new ArrayList<>(); String apiEndpoint = getApiEndpoint("/groups/" + groupId + "/milestones"); for (JsonNode milestoneNode: list(client, apiEndpoint, logger)) - milestones.add(getMilestone(milestoneNode)); + iterations.add(getIteration(milestoneNode)); apiEndpoint = getApiEndpoint("/groups/" + groupId); JsonNode groupNode = JerseyUtils.get(client, apiEndpoint, logger); JsonNode parentIdNode = groupNode.get("parent_id"); if (parentIdNode != null && parentIdNode.asText(null) != null) - milestones.addAll(getMilestones(parentIdNode.asText(), logger)); - return milestones; + iterations.addAll(getIterations(parentIdNode.asText(), logger)); + return iterations; } finally { client.close(); } } - private Milestone getMilestone(JsonNode milestoneNode) { - Milestone milestone = new Milestone(); - milestone.setName(milestoneNode.get("title").asText()); - milestone.setDescription(milestoneNode.get("description").asText(null)); + private Iteration getIteration(JsonNode milestoneNode) { + Iteration iteration = new Iteration(); + iteration.setName(milestoneNode.get("title").asText()); + iteration.setDescription(milestoneNode.get("description").asText(null)); String dueDateString = milestoneNode.get("due_date").asText(null); if (dueDateString != null) - milestone.setDueDate(ISODateTimeFormat.date().parseDateTime(dueDateString).toDate()); + iteration.setDueDate(ISODateTimeFormat.date().parseDateTime(dueDateString).toDate()); if (milestoneNode.get("state").asText().equals("closed")) - milestone.setClosed(true); - return milestone; + iteration.setClosed(true); + return iteration; } TaskResult importProjects(ImportProjects projects, ProjectImportOption option, boolean dryRun, TaskLogger logger) { @@ -315,24 +315,24 @@ public class ImportServer implements Serializable, Validatable { } if (option.getIssueImportOption() != null) { - List milestones = new ArrayList<>(); + List iterations = new ArrayList<>(); logger.log("Importing milestones..."); apiEndpoint = getApiEndpoint("/projects/" + gitLabProject.replace("/", "%2F") + "/milestones"); for (JsonNode milestoneNode : list(client, apiEndpoint, logger)) - milestones.add(getMilestone(milestoneNode)); + iterations.add(getIteration(milestoneNode)); JsonNode namespaceNode = projectNode.get("namespace"); if (namespaceNode.get("kind").asText().equals("group")) { String groupId = namespaceNode.get("id").asText(); - milestones.addAll(getMilestones(groupId, logger)); + iterations.addAll(getIterations(groupId, logger)); } - for (Milestone milestone : milestones) { - if (project.getMilestone(milestone.getName()) == null) { - milestone.setProject(project); - project.getMilestones().add(milestone); + for (Iteration iteration : iterations) { + if (project.getIteration(iteration.getName()) == null) { + iteration.setProject(project); + project.getIterations().add(iteration); if (!dryRun) - OneDev.getInstance(MilestoneManager.class).createOrUpdate(milestone); + OneDev.getInstance(IterationManager.class).createOrUpdate(iteration); } } @@ -340,7 +340,7 @@ public class ImportServer implements Serializable, Validatable { ImportResult currentResult = importIssues(gitLabProject, project, option.getIssueImportOption(), userIds, dryRun, logger); result.nonExistentLogins.addAll(currentResult.nonExistentLogins); - result.nonExistentMilestones.addAll(currentResult.nonExistentMilestones); + result.nonExistentIterations.addAll(currentResult.nonExistentIterations); result.unmappedIssueLabels.addAll(currentResult.unmappedIssueLabels); result.tooLargeAttachments.addAll(currentResult.tooLargeAttachments); result.errorAttachments.addAll(currentResult.errorAttachments); @@ -361,14 +361,14 @@ public class ImportServer implements Serializable, Validatable { IssueManager issueManager = OneDev.getInstance(IssueManager.class); Client client = newClient(); try { - Set nonExistentMilestones = new HashSet<>(); + Set nonExistentIterations = new HashSet<>(); Set nonExistentLogins = new HashSet<>(); Set unmappedIssueLabels = new HashSet<>(); Set tooLargeAttachments = new LinkedHashSet<>(); Set errorAttachments = new HashSet<>(); Map> labelMappings = new HashMap<>(); - Map milestoneMappings = new HashMap<>(); + Map iterationMappings = new HashMap<>(); for (IssueLabelMapping mapping: option.getIssueLabelMappings()) { String oneDevFieldName = StringUtils.substringBefore(mapping.getOneDevIssueField(), "::"); @@ -379,8 +379,8 @@ public class ImportServer implements Serializable, Validatable { labelMappings.put(mapping.getGitLabIssueLabel(), new Pair<>(fieldSpec, oneDevFieldValue)); } - for (Milestone milestone: oneDevProject.getMilestones()) - milestoneMappings.put(milestone.getName(), milestone); + for (Iteration iteration: oneDevProject.getIterations()) + iterationMappings.put(iteration.getName(), iteration); String initialIssueState = getIssueSetting().getInitialStateSpec().getName(); var timeTrackingSetting = OneDev.getInstance(SettingManager.class).getIssueSetting().getTimeTrackingSetting(); @@ -470,15 +470,15 @@ public class ImportServer implements Serializable, Validatable { if (issueNode.hasNonNull("milestone")) { String milestoneName = issueNode.get("milestone").get("title").asText(); - Milestone milestone = milestoneMappings.get(milestoneName); - if (milestone != null) { + Iteration iteration = iterationMappings.get(milestoneName); + if (iteration != null) { IssueSchedule schedule = new IssueSchedule(); schedule.setIssue(issue); - schedule.setMilestone(milestone); + schedule.setIteration(iteration); issue.getSchedules().add(schedule); } else { extraIssueInfo.put("Milestone", milestoneName); - nonExistentMilestones.add(milestoneName); + nonExistentIterations.add(milestoneName); } } @@ -699,7 +699,7 @@ public class ImportServer implements Serializable, Validatable { ImportResult result = new ImportResult(); result.nonExistentLogins.addAll(nonExistentLogins); - result.nonExistentMilestones.addAll(nonExistentMilestones); + result.nonExistentIterations.addAll(nonExistentIterations); result.unmappedIssueLabels.addAll(unmappedIssueLabels); result.tooLargeAttachments.addAll(tooLargeAttachments); result.errorAttachments.addAll(errorAttachments);