summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorValery Sizov <valery@gitlab.com>2016-11-15 19:48:30 +0200
committerValery Sizov <valery@gitlab.com>2016-11-23 13:41:04 +0200
commit3789cfe056c1d8a5fb91267cc2b1dd0f9f5902a9 (patch)
tree45314bfcb16ba7095e209d3a1f3eb9be2016b2a6 /app
parentd7eeb6df51ffe2ad864ef49d0e465b88ab158520 (diff)
downloadgitlab-ce-3789cfe056c1d8a5fb91267cc2b1dd0f9f5902a9.tar.gz
Add a starting date to milestonesmilestone_start_date
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/due_date_select.js.es622
-rw-r--r--app/assets/stylesheets/framework/issue_box.scss4
-rw-r--r--app/controllers/groups/milestones_controller.rb2
-rw-r--r--app/controllers/projects/milestones_controller.rb2
-rw-r--r--app/helpers/issues_helper.rb2
-rw-r--r--app/helpers/milestones_helper.rb24
-rw-r--r--app/models/concerns/milestoneish.rb24
-rw-r--r--app/models/global_milestone.rb33
-rw-r--r--app/models/milestone.rb25
-rw-r--r--app/views/groups/milestones/new.html.haml13
-rw-r--r--app/views/projects/milestones/_form.html.haml7
-rw-r--r--app/views/projects/milestones/show.html.haml6
-rw-r--r--app/views/shared/_milestone_expired.html.haml6
-rw-r--r--app/views/shared/milestones/_form_dates.html.haml15
-rw-r--r--app/views/shared/milestones/_top.html.haml4
15 files changed, 108 insertions, 81 deletions
diff --git a/app/assets/javascripts/due_date_select.js.es6 b/app/assets/javascripts/due_date_select.js.es6
index fd7f961aab9..e84f5ac9183 100644
--- a/app/assets/javascripts/due_date_select.js.es6
+++ b/app/assets/javascripts/due_date_select.js.es6
@@ -145,25 +145,19 @@
class DueDateSelectors {
constructor() {
- this.initMilestoneDueDate();
+ this.initMilestoneDatePicker();
this.initIssuableSelect();
}
- initMilestoneDueDate() {
- const $datePicker = $('.datepicker');
+ initMilestoneDatePicker() {
+ $('.datepicker').datepicker({
+ dateFormat: 'yy-mm-dd'
+ });
- if ($datePicker.length) {
- const $dueDate = $('#milestone_due_date');
- $datePicker.datepicker({
- dateFormat: 'yy-mm-dd',
- onSelect: (dateText, inst) => {
- $dueDate.val(dateText);
- }
- }).datepicker('setDate', $.datepicker.parseDate('yy-mm-dd', $dueDate.val()));
- }
- $('.js-clear-due-date').on('click', (e) => {
+ $('.js-clear-due-date,.js-clear-start-date').on('click', (e) => {
e.preventDefault();
- $.datepicker._clearDate($datePicker);
+ const datepicker = $(e.target).siblings('.datepicker');
+ $.datepicker._clearDate(datepicker);
});
}
diff --git a/app/assets/stylesheets/framework/issue_box.scss b/app/assets/stylesheets/framework/issue_box.scss
index ba3930e03bd..ff6f316d576 100644
--- a/app/assets/stylesheets/framework/issue_box.scss
+++ b/app/assets/stylesheets/framework/issue_box.scss
@@ -39,4 +39,8 @@
&.status-box-expired {
background: #cea61b;
}
+
+ &.status-box-upcoming {
+ background: #8f8f8f;
+ }
}
diff --git a/app/controllers/groups/milestones_controller.rb b/app/controllers/groups/milestones_controller.rb
index 506484932cc..24ec4eec3f2 100644
--- a/app/controllers/groups/milestones_controller.rb
+++ b/app/controllers/groups/milestones_controller.rb
@@ -67,7 +67,7 @@ class Groups::MilestonesController < Groups::ApplicationController
end
def milestone_params
- params.require(:milestone).permit(:title, :description, :due_date, :state_event)
+ params.require(:milestone).permit(:title, :description, :start_date, :due_date, :state_event)
end
def milestone_path(title)
diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb
index ff63f22cb5b..be52b0fa7cf 100644
--- a/app/controllers/projects/milestones_controller.rb
+++ b/app/controllers/projects/milestones_controller.rb
@@ -112,6 +112,6 @@ class Projects::MilestonesController < Projects::ApplicationController
end
def milestone_params
- params.require(:milestone).permit(:title, :description, :due_date, :state_event)
+ params.require(:milestone).permit(:title, :description, :start_date, :due_date, :state_event)
end
end
diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb
index 1644c346dd8..a8a49e43b05 100644
--- a/app/helpers/issues_helper.rb
+++ b/app/helpers/issues_helper.rb
@@ -64,6 +64,8 @@ module IssuesHelper
'status-box-merged'
elsif item.closed?
'status-box-closed'
+ elsif item.respond_to?(:upcoming?) && item.upcoming?
+ 'status-box-upcoming'
else
'status-box-open'
end
diff --git a/app/helpers/milestones_helper.rb b/app/helpers/milestones_helper.rb
index 83a2a4ad3ec..729928ce1dd 100644
--- a/app/helpers/milestones_helper.rb
+++ b/app/helpers/milestones_helper.rb
@@ -86,6 +86,30 @@ module MilestonesHelper
days = milestone.remaining_days
content = content_tag(:strong, days)
content << " #{'day'.pluralize(days)} remaining"
+ elsif milestone.upcoming?
+ content_tag(:strong, 'Upcoming')
+ elsif milestone.start_date && milestone.start_date.past?
+ days = milestone.elapsed_days
+ content = content_tag(:strong, days)
+ content << " #{'day'.pluralize(days)} elapsed"
+ end
+ end
+
+ def milestone_date_range(milestone)
+ if milestone.start_date && milestone.due_date
+ "#{milestone.start_date.to_s(:medium)} - #{milestone.due_date.to_s(:medium)}"
+ elsif milestone.due_date
+ if milestone.due_date.past?
+ "expired on #{milestone.due_date.to_s(:medium)}"
+ else
+ "expires on #{milestone.due_date.to_s(:medium)}"
+ end
+ elsif milestone.start_date
+ if milestone.start_date.past?
+ "started on #{milestone.start_date.to_s(:medium)}"
+ else
+ "starts on #{milestone.start_date.to_s(:medium)}"
+ end
end
end
end
diff --git a/app/models/concerns/milestoneish.rb b/app/models/concerns/milestoneish.rb
index 7bcc78247ba..e65fc9eaa09 100644
--- a/app/models/concerns/milestoneish.rb
+++ b/app/models/concerns/milestoneish.rb
@@ -23,7 +23,31 @@ module Milestoneish
(due_date - Date.today).to_i
end
+ def elapsed_days
+ return 0 if !start_date || start_date.future?
+
+ (Date.today - start_date).to_i
+ end
+
def issues_visible_to_user(user = nil)
issues.visible_to_user(user)
end
+
+ def upcoming?
+ start_date && start_date.future?
+ end
+
+ def expires_at
+ if due_date
+ if due_date.past?
+ "expired on #{due_date.to_s(:medium)}"
+ else
+ "expires on #{due_date.to_s(:medium)}"
+ end
+ end
+ end
+
+ def expired?
+ due_date && due_date.past?
+ end
end
diff --git a/app/models/global_milestone.rb b/app/models/global_milestone.rb
index cde4a568577..b01607dcda9 100644
--- a/app/models/global_milestone.rb
+++ b/app/models/global_milestone.rb
@@ -28,26 +28,16 @@ class GlobalMilestone
@title.to_slug.normalize.to_s
end
- def expired?
- if due_date
- due_date.past?
- else
- false
- end
- end
-
def projects
@projects ||= Project.for_milestones(milestones.select(:id))
end
def state
- state = milestones.map { |milestone| milestone.state }
-
- if state.count('closed') == state.size
- 'closed'
- else
- 'active'
+ milestones.each do |milestone|
+ return 'active' if milestone.state != 'closed'
end
+
+ 'closed'
end
def active?
@@ -81,18 +71,15 @@ class GlobalMilestone
@due_date =
if @milestones.all? { |x| x.due_date == @milestones.first.due_date }
@milestones.first.due_date
- else
- nil
end
end
- def expires_at
- if due_date
- if due_date.past?
- "expired on #{due_date.to_s(:medium)}"
- else
- "expires on #{due_date.to_s(:medium)}"
+ def start_date
+ return @start_date if defined?(@start_date)
+
+ @start_date =
+ if @milestones.all? { |x| x.start_date == @milestones.first.start_date }
+ @milestones.first.start_date
end
- end
end
end
diff --git a/app/models/milestone.rb b/app/models/milestone.rb
index 23aecbfa3a6..c774e69080c 100644
--- a/app/models/milestone.rb
+++ b/app/models/milestone.rb
@@ -29,6 +29,7 @@ class Milestone < ActiveRecord::Base
validates :title, presence: true, uniqueness: { scope: :project_id }
validates :project, presence: true
+ validate :start_date_should_be_less_than_due_date, if: Proc.new { |m| m.start_date.present? && m.due_date.present? }
strip_attributes :title
@@ -131,24 +132,6 @@ class Milestone < ActiveRecord::Base
self.title
end
- def expired?
- if due_date
- due_date.past?
- else
- false
- end
- end
-
- def expires_at
- if due_date
- if due_date.past?
- "expired on #{due_date.to_s(:medium)}"
- else
- "expires on #{due_date.to_s(:medium)}"
- end
- end
- end
-
def can_be_closed?
active? && issues.opened.count.zero?
end
@@ -212,4 +195,10 @@ class Milestone < ActiveRecord::Base
def sanitize_title(value)
CGI.unescape_html(Sanitize.clean(value.to_s))
end
+
+ def start_date_should_be_less_than_due_date
+ if due_date <= start_date
+ errors.add(:start_date, "Can't be greater than due date")
+ end
+ end
end
diff --git a/app/views/groups/milestones/new.html.haml b/app/views/groups/milestones/new.html.haml
index 0dfaf743992..63cadfca530 100644
--- a/app/views/groups/milestones/new.html.haml
+++ b/app/views/groups/milestones/new.html.haml
@@ -36,19 +36,8 @@
= f.collection_select :project_ids, @group.projects.non_archived, :id, :name,
{ selected: @group.projects.non_archived.pluck(:id) }, required: true, multiple: true, class: 'select2'
- .col-md-6
- .form-group
- = f.label :due_date, "Due Date", class: "control-label"
- .col-sm-10
- = f.text_field :due_date, class: "datepicker form-control", placeholder: "Select due date"
+ = render "shared/milestones/form_dates", f: f
.form-actions
= f.submit 'Create Milestone', class: "btn-create btn"
= link_to "Cancel", group_milestones_path(@group), class: "btn btn-cancel"
-
-
-:javascript
- $(".datepicker").datepicker({
- dateFormat: "yy-mm-dd",
- onSelect: function(dateText, inst) { $("#milestone_due_date").val(dateText) }
- }).datepicker("setDate", $.datepicker.parseDate('yy-mm-dd', $('#milestone_due_date').val()));
diff --git a/app/views/projects/milestones/_form.html.haml b/app/views/projects/milestones/_form.html.haml
index cbf1ba04170..513710e8e66 100644
--- a/app/views/projects/milestones/_form.html.haml
+++ b/app/views/projects/milestones/_form.html.haml
@@ -14,12 +14,7 @@
= render 'projects/notes/hints'
.clearfix
.error-alert
- .col-md-6
- .form-group
- = f.label :due_date, "Due Date", class: "control-label"
- .col-sm-10
- = f.text_field :due_date, class: "datepicker form-control", placeholder: "Select due date"
- %a.inline.prepend-top-5.js-clear-due-date{ href: "#" } Clear due date
+ = render "shared/milestones/form_dates", f: f
.form-actions
- if @milestone.new_record?
diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml
index e01aca3dda6..c3a6096aa54 100644
--- a/app/views/projects/milestones/show.html.haml
+++ b/app/views/projects/milestones/show.html.haml
@@ -10,15 +10,17 @@
Closed
- elsif @milestone.expired?
Past due
+ - elsif @milestone.upcoming?
+ Upcoming
- else
Open
.header-text-content
%span.identifier
Milestone ##{@milestone.iid}
- - if @milestone.expires_at
+ - if @milestone.due_date || @milestone.start_date
%span.creator
&middot;
- = @milestone.expires_at
+ = milestone_date_range(@milestone)
.milestone-buttons
- if can?(current_user, :admin_milestone, @project)
- if @milestone.active?
diff --git a/app/views/shared/_milestone_expired.html.haml b/app/views/shared/_milestone_expired.html.haml
index b8eef15fbec..5e9007aaaac 100644
--- a/app/views/shared/_milestone_expired.html.haml
+++ b/app/views/shared/_milestone_expired.html.haml
@@ -1,5 +1,7 @@
- if milestone.expired? and not milestone.closed?
%span.cred (Expired)
-- if milestone.expires_at
+- if milestone.upcoming?
+ %span.clgray (Upcoming)
+- if milestone.due_date || milestone.start_date
%span
- = milestone.expires_at
+ = milestone_date_range(milestone)
diff --git a/app/views/shared/milestones/_form_dates.html.haml b/app/views/shared/milestones/_form_dates.html.haml
new file mode 100644
index 00000000000..748b10a1298
--- /dev/null
+++ b/app/views/shared/milestones/_form_dates.html.haml
@@ -0,0 +1,15 @@
+.col-md-6
+ .form-group
+ = f.label :start_date, "Start Date", class: "control-label"
+ .col-sm-10
+ = f.text_field :start_date, class: "datepicker form-control", placeholder: "Select start date"
+ %a.inline.prepend-top-5.js-clear-start-date{ href: "#" } Clear start date
+.col-md-6
+ .form-group
+ = f.label :due_date, "Due Date", class: "control-label"
+ .col-sm-10
+ = f.text_field :due_date, class: "datepicker form-control", placeholder: "Select due date"
+ %a.inline.prepend-top-5.js-clear-due-date{ href: "#" } Clear due date
+
+:javascript
+ new gl.DueDateSelectors();
diff --git a/app/views/shared/milestones/_top.html.haml b/app/views/shared/milestones/_top.html.haml
index 548215243db..497446c1ef3 100644
--- a/app/views/shared/milestones/_top.html.haml
+++ b/app/views/shared/milestones/_top.html.haml
@@ -12,10 +12,10 @@
Open
%span.identifier
Milestone #{milestone.title}
- - if milestone.expires_at
+ - if milestone.due_date || milestone.start_date
%span.creator
&middot;
- = milestone.expires_at
+ = milestone_date_range(milestone)
- if group
.pull-right
- if can?(current_user, :admin_milestones, group)