Commit 190e483fb4b5edb6d8dfa71b67dc52da402ddab9
1 parent
b01f8b63
Exists in
master
and in
4 other branches
Rework of milestones
Showing
8 changed files
with
72 additions
and
34 deletions
Show diff stats
app/assets/stylesheets/common.scss
@@ -531,9 +531,14 @@ pre { | @@ -531,9 +531,14 @@ pre { | ||
531 | } | 531 | } |
532 | } | 532 | } |
533 | 533 | ||
534 | -.milestone .progress { | ||
535 | - margin-bottom: 0; | ||
536 | - margin-top: 4px; | 534 | +.milestone { |
535 | + &.milestone-closed { | ||
536 | + background: #eee; | ||
537 | + } | ||
538 | + .progress { | ||
539 | + margin-bottom: 0; | ||
540 | + margin-top: 4px; | ||
541 | + } | ||
537 | } | 542 | } |
538 | 543 | ||
539 | .float-link { | 544 | .float-link { |
app/controllers/milestones_controller.rb
@@ -12,11 +12,12 @@ class MilestonesController < ProjectResourceController | @@ -12,11 +12,12 @@ class MilestonesController < ProjectResourceController | ||
12 | 12 | ||
13 | def index | 13 | def index |
14 | @milestones = case params[:f] | 14 | @milestones = case params[:f] |
15 | - when 'all'; @project.milestones | ||
16 | - else @project.milestones.active | 15 | + when 'all'; @project.milestones.order("closed, due_date DESC") |
16 | + when 'closed'; @project.milestones.closed.order("due_date DESC") | ||
17 | + else @project.milestones.active.order("due_date ASC") | ||
17 | end | 18 | end |
18 | 19 | ||
19 | - @milestones = @milestones.includes(:project).order("due_date") | 20 | + @milestones = @milestones.includes(:project) |
20 | @milestones = @milestones.page(params[:page]).per(20) | 21 | @milestones = @milestones.page(params[:page]).per(20) |
21 | end | 22 | end |
22 | 23 |
app/models/milestone.rb
@@ -19,12 +19,19 @@ class Milestone < ActiveRecord::Base | @@ -19,12 +19,19 @@ class Milestone < ActiveRecord::Base | ||
19 | has_many :issues | 19 | has_many :issues |
20 | has_many :merge_requests | 20 | has_many :merge_requests |
21 | 21 | ||
22 | + scope :active, where(closed: false) | ||
23 | + scope :closed, where(closed: true) | ||
24 | + | ||
22 | validates :title, presence: true | 25 | validates :title, presence: true |
23 | validates :project, presence: true | 26 | validates :project, presence: true |
24 | validates :closed, inclusion: { in: [true, false] } | 27 | validates :closed, inclusion: { in: [true, false] } |
25 | 28 | ||
26 | - def self.active | ||
27 | - where("due_date > ? OR due_date IS NULL", Date.today) | 29 | + def expired? |
30 | + if due_date | ||
31 | + due_date < Date.today | ||
32 | + else | ||
33 | + false | ||
34 | + end | ||
28 | end | 35 | end |
29 | 36 | ||
30 | def participants | 37 | def participants |
@@ -52,4 +59,12 @@ class Milestone < ActiveRecord::Base | @@ -52,4 +59,12 @@ class Milestone < ActiveRecord::Base | ||
52 | def expires_at | 59 | def expires_at |
53 | "expires at #{due_date.stamp("Aug 21, 2011")}" if due_date | 60 | "expires at #{due_date.stamp("Aug 21, 2011")}" if due_date |
54 | end | 61 | end |
62 | + | ||
63 | + def can_be_closed? | ||
64 | + issues.count > 0 && open? && issues.opened.count.zero? | ||
65 | + end | ||
66 | + | ||
67 | + def open? | ||
68 | + !closed | ||
69 | + end | ||
55 | end | 70 | end |
app/models/snippet.rb
@@ -22,7 +22,7 @@ class Snippet < ActiveRecord::Base | @@ -22,7 +22,7 @@ class Snippet < ActiveRecord::Base | ||
22 | belongs_to :author, class_name: "User" | 22 | belongs_to :author, class_name: "User" |
23 | has_many :notes, as: :noteable, dependent: :destroy | 23 | has_many :notes, as: :noteable, dependent: :destroy |
24 | 24 | ||
25 | - delegate :name, :email, to: :author, prefix: true | 25 | + delegate :name, :email, to: :author, prefix: true, allow_nil: true |
26 | 26 | ||
27 | validates :author, presence: true | 27 | validates :author, presence: true |
28 | validates :project, presence: true | 28 | validates :project, presence: true |
app/views/issues/_show.html.haml
@@ -28,7 +28,7 @@ | @@ -28,7 +28,7 @@ | ||
28 | %p= link_to_gfm truncate(issue.title, length: 100), project_issue_path(issue.project, issue), class: "row_title" | 28 | %p= link_to_gfm truncate(issue.title, length: 100), project_issue_path(issue.project, issue), class: "row_title" |
29 | 29 | ||
30 | %span.update-author | 30 | %span.update-author |
31 | - %small.cdark= "##{issue.id}" | 31 | + %span.cdark= "##{issue.id}" |
32 | - if issue.assignee | 32 | - if issue.assignee |
33 | assigned to #{issue.assignee_name} | 33 | assigned to #{issue.assignee_name} |
34 | - else | 34 | - else |
app/views/milestones/_milestone.html.haml
1 | -%li{class: "milestone", id: dom_id(milestone) } | 1 | +%li{class: "milestone milestone-#{milestone.closed ? 'closed' : 'open'}", id: dom_id(milestone) } |
2 | .right | 2 | .right |
3 | - - if can? current_user, :admin_milestone, milestone.project | 3 | + - if can?(current_user, :admin_milestone, milestone.project) and milestone.open? |
4 | = link_to edit_project_milestone_path(milestone.project, milestone), class: "btn small edit-milestone-link grouped" do | 4 | = link_to edit_project_milestone_path(milestone.project, milestone), class: "btn small edit-milestone-link grouped" do |
5 | %i.icon-edit | 5 | %i.icon-edit |
6 | Edit | 6 | Edit |
7 | %h4 | 7 | %h4 |
8 | = link_to_gfm truncate(milestone.title, length: 100), project_milestone_path(milestone.project, milestone) | 8 | = link_to_gfm truncate(milestone.title, length: 100), project_milestone_path(milestone.project, milestone) |
9 | + - if milestone.expired? and not milestone.closed | ||
10 | + %span.cred (Expired) | ||
9 | %small | 11 | %small |
10 | = milestone.expires_at | 12 | = milestone.expires_at |
11 | .row | 13 | .row |
app/views/milestones/index.html.haml
@@ -11,6 +11,9 @@ | @@ -11,6 +11,9 @@ | ||
11 | %li{class: ("active" if (params[:f] == "active" || !params[:f]))} | 11 | %li{class: ("active" if (params[:f] == "active" || !params[:f]))} |
12 | = link_to project_milestones_path(@project, f: "active") do | 12 | = link_to project_milestones_path(@project, f: "active") do |
13 | Active | 13 | Active |
14 | + %li{class: ("active" if params[:f] == "closed")} | ||
15 | + = link_to project_milestones_path(@project, f: "closed") do | ||
16 | + Closed | ||
14 | %li{class: ("active" if params[:f] == "all")} | 17 | %li{class: ("active" if params[:f] == "all")} |
15 | = link_to project_milestones_path(@project, f: "all") do | 18 | = link_to project_milestones_path(@project, f: "all") do |
16 | All | 19 | All |
@@ -19,7 +22,7 @@ | @@ -19,7 +22,7 @@ | ||
19 | = render @milestones | 22 | = render @milestones |
20 | 23 | ||
21 | - if @milestones.present? | 24 | - if @milestones.present? |
22 | - %li.bottom= paginate @milestones, remote: true, theme: "gitlab" | 25 | + %li.bottom= paginate @milestones, theme: "gitlab" |
23 | - else | 26 | - else |
24 | %li | 27 | %li |
25 | %h3.nothing_here_message Nothing to show here | 28 | %h3.nothing_here_message Nothing to show here |
app/views/milestones/show.html.haml
1 | -%h3.page_title | ||
2 | - Milestone ##{@milestone.id} | ||
3 | - %small | ||
4 | - = @milestone.expires_at | 1 | +.row |
2 | + .span6 | ||
3 | + %h3.page_title | ||
4 | + Milestone ##{@milestone.id} | ||
5 | + %small | ||
6 | + = @milestone.expires_at | ||
7 | + .back_link | ||
8 | + = link_to project_milestones_path(@project) do | ||
9 | + ← To milestones list | ||
10 | + .span6 | ||
11 | + .right | ||
12 | + - unless @milestone.closed | ||
13 | + = link_to new_project_issue_path(@project, issue: { milestone_id: @milestone.id }), class: "btn small grouped", title: "New Issue" do | ||
14 | + %i.icon-plus | ||
15 | + New Issue | ||
16 | + = link_to 'Browse Issues', project_issues_path(@milestone.project, milestone_id: @milestone.id), class: "btn edit-milestone-link small grouped" | ||
17 | + - if can?(current_user, :admin_milestone, @project) | ||
18 | + = link_to edit_project_milestone_path(@project, @milestone), class: "btn small grouped" do | ||
19 | + %i.icon-edit | ||
20 | + Edit | ||
5 | 21 | ||
6 | - %span.right | ||
7 | - = link_to new_project_issue_path(@project, issue: { milestone_id: @milestone.id }), class: "btn small grouped", title: "New Issue" do | ||
8 | - %i.icon-plus | ||
9 | - New Issue | ||
10 | - = link_to 'Browse Issues', project_issues_path(@milestone.project, milestone_id: @milestone.id), class: "btn edit-milestone-link small grouped" | ||
11 | - - if can?(current_user, :admin_milestone, @project) | ||
12 | - = link_to edit_project_milestone_path(@project, @milestone), class: "btn small grouped" do | ||
13 | - %i.icon-edit | ||
14 | - Edit | ||
15 | 22 | ||
16 | -.back_link | ||
17 | - = link_to project_milestones_path(@project) do | ||
18 | - ← To milestones list | 23 | + |
24 | +- if @milestone.can_be_closed? | ||
25 | + %hr | ||
26 | + %p | ||
27 | + %span All issues for this milestone are closed. You may close milestone now. | ||
28 | + = link_to 'Close Milestone', project_milestone_path(@project, @milestone, milestone: {closed: true }), method: :put, class: "btn small danger" | ||
19 | 29 | ||
20 | .main_box | 30 | .main_box |
21 | .top_box_content | 31 | .top_box_content |
22 | - %h5 | 32 | + %h4.box-title |
23 | - if @milestone.closed | 33 | - if @milestone.closed |
24 | - .alert-message.error.status_info Closed | ||
25 | - - else | ||
26 | - .alert-message.success.status_info Open | 34 | + .error.status_info Closed |
35 | + - elsif @milestone.expired? | ||
36 | + .error.status_info Expired | ||
37 | + | ||
27 | = gfm escape_once(@milestone.title) | 38 | = gfm escape_once(@milestone.title) |
28 | - %small.right= @milestone.expires_at | ||
29 | 39 | ||
30 | .middle_box_content | 40 | .middle_box_content |
31 | %h5 | 41 | %h5 |
@@ -34,6 +44,7 @@ | @@ -34,6 +44,7 @@ | ||
34 | #{@milestone.closed_items_count} closed | 44 | #{@milestone.closed_items_count} closed |
35 | – | 45 | – |
36 | #{@milestone.open_items_count} open | 46 | #{@milestone.open_items_count} open |
47 | + %span.right= @milestone.expires_at | ||
37 | .progress.progress-info | 48 | .progress.progress-info |
38 | .bar{style: "width: #{@milestone.percent_complete}%;"} | 49 | .bar{style: "width: #{@milestone.percent_complete}%;"} |
39 | 50 | ||
@@ -43,6 +54,7 @@ | @@ -43,6 +54,7 @@ | ||
43 | = preserve do | 54 | = preserve do |
44 | = markdown @milestone.description | 55 | = markdown @milestone.description |
45 | 56 | ||
57 | + | ||
46 | .row | 58 | .row |
47 | .span6 | 59 | .span6 |
48 | %table.milestone-issue-filter | 60 | %table.milestone-issue-filter |