2018-08-18 07:19:57 -04:00
# frozen_string_literal: true
2015-01-06 15:32:04 -05:00
module MilestonesHelper
2018-04-19 10:43:20 -04:00
include EntityDateHelper
2018-11-28 13:38:24 -05:00
include Gitlab :: Utils :: StrongMemoize
2018-04-19 10:43:20 -04:00
2019-11-07 16:06:14 -05:00
def milestone_status_string ( milestone )
if milestone . closed?
_ ( 'Closed' )
elsif milestone . expired?
_ ( 'Past due' )
elsif milestone . upcoming?
_ ( 'Upcoming' )
else
_ ( 'Open' )
end
end
2015-01-06 15:32:04 -05:00
def milestones_filter_path ( opts = { } )
if @project
2017-06-29 13:06:35 -04:00
project_milestones_path ( @project , opts )
2015-01-06 15:32:04 -05:00
elsif @group
group_milestones_path ( @group , opts )
2015-03-03 10:19:37 -05:00
else
dashboard_milestones_path ( opts )
2015-01-06 15:32:04 -05:00
end
end
2015-03-09 18:20:32 -04:00
2020-03-24 14:07:55 -04:00
def milestones_issues_path ( opts = { } )
2016-03-06 23:07:19 -05:00
if @project
2017-06-29 13:06:35 -04:00
project_issues_path ( @project , opts )
2016-03-06 23:07:19 -05:00
elsif @group
issues_group_path ( @group , opts )
else
issues_dashboard_path ( opts )
end
end
2017-03-24 15:41:08 -04:00
def milestones_browse_issuables_path ( milestone , state : nil , type : )
opts = { milestone_title : milestone . title , state : state }
2016-03-06 23:07:19 -05:00
if @project
polymorphic_path ( [ @project . namespace . becomes ( Namespace ) , @project , type ] , opts )
elsif @group
polymorphic_url ( [ type , @group ] , opts )
else
polymorphic_url ( [ type , :dashboard ] , opts )
end
end
def milestone_issues_by_label_count ( milestone , label , state : )
2017-08-10 12:39:26 -04:00
issues = milestone . issues . with_label ( label . title )
issues =
case state
when :opened
issues . opened
when :closed
issues . closed
else
2019-04-15 08:25:48 -04:00
raise ArgumentError , _ ( " invalid milestone state `%{state}` " ) % { state : state }
2017-08-10 12:39:26 -04:00
end
issues . size
2016-03-06 23:07:19 -05:00
end
2016-07-22 16:11:07 -04:00
# Returns count of milestones for different states
2016-08-24 13:29:27 -04:00
# Uses explicit hash keys as the 'opened' state URL params differs from the db value
2016-07-22 16:11:07 -04:00
# and we need to add the total
2018-08-27 11:31:01 -04:00
# rubocop: disable CodeReuse/ActiveRecord
2016-07-25 17:23:27 -04:00
def milestone_counts ( milestones )
counts = milestones . reorder ( nil ) . group ( :state ) . count
2016-08-24 13:29:27 -04:00
2016-07-22 16:11:07 -04:00
{
2016-08-24 13:29:27 -04:00
opened : counts [ 'active' ] || 0 ,
closed : counts [ 'closed' ] || 0 ,
all : counts . values . sum || 0
2016-07-22 16:11:07 -04:00
}
2016-07-22 05:18:38 -04:00
end
2018-08-27 11:31:01 -04:00
# rubocop: enable CodeReuse/ActiveRecord
2016-07-22 05:18:38 -04:00
2016-07-26 09:30:14 -04:00
# Show 'active' class if provided GET param matches check
# `or_blank` allows the function to return 'active' when given an empty param
# Could be refactored to be simpler but that may make it harder to read
2016-08-22 18:58:28 -04:00
def milestone_class_for_state ( param , check , match_blank_param = false )
2016-07-26 09:30:14 -04:00
if match_blank_param
'active' if param . blank? || param == check
2017-07-07 11:08:49 -04:00
elsif param == check
'active'
2016-07-26 09:30:14 -04:00
else
2017-07-07 11:08:49 -04:00
check
2016-07-26 09:30:14 -04:00
end
end
2018-04-19 10:43:20 -04:00
def milestone_progress_tooltip_text ( milestone )
2020-03-06 19:08:25 -05:00
has_issues = milestone . total_issues_count > 0
2018-04-19 10:43:20 -04:00
if has_issues
[
_ ( 'Progress' ) ,
2020-03-06 19:08:25 -05:00
_ ( " %{percent}%% complete " ) % { percent : milestone . percent_complete }
2018-04-19 10:43:20 -04:00
] . join ( '<br />' )
else
_ ( 'Progress' )
end
end
2015-03-09 18:20:32 -04:00
def milestone_progress_bar ( milestone )
options = {
2018-04-09 15:31:01 -04:00
class : 'progress-bar bg-success' ,
2020-03-06 19:08:25 -05:00
style : " width: #{ milestone . percent_complete } %; "
2015-03-09 18:20:32 -04:00
}
content_tag :div , class : 'progress' do
content_tag :div , nil , options
end
end
2015-03-26 22:13:49 -04:00
2016-03-16 15:14:31 -04:00
def milestones_filter_dropdown_path
2016-07-16 04:41:55 -04:00
project = @target_project || @project
2016-07-18 12:43:00 -04:00
if project
2017-06-29 13:06:35 -04:00
project_milestones_path ( project , :json )
2017-06-22 03:25:56 -04:00
elsif @group
group_milestones_path ( @group , :json )
2016-03-16 15:14:31 -04:00
else
2016-03-22 14:19:53 -04:00
dashboard_milestones_path ( :json )
2016-03-16 15:14:31 -04:00
end
2015-03-26 22:13:49 -04:00
end
2016-02-25 15:23:34 -05:00
2018-04-19 10:43:20 -04:00
def milestone_time_for ( date , date_type )
title = date_type == :start ? " Start date " : " End date "
if date
2018-08-18 07:19:57 -04:00
time_ago = time_ago_in_words ( date ) . sub ( " about " , " " )
state = if date . past?
" ago "
else
" remaining "
end
2018-04-19 10:43:20 -04:00
content = [
title ,
" <br /> " ,
date . to_s ( :medium ) ,
2018-08-18 07:19:57 -04:00
" ( #{ time_ago } #{ state } ) "
2018-04-19 10:43:20 -04:00
] . join ( " " )
2017-03-24 12:43:52 -04:00
content . html_safe
2018-04-19 10:43:20 -04:00
else
title
end
end
def milestone_issues_tooltip_text ( milestone )
2020-03-06 19:08:25 -05:00
total = milestone . total_issues_count
opened = milestone . opened_issues_count
closed = milestone . closed_issues_count
2018-04-19 10:43:20 -04:00
2020-03-04 19:07:49 -05:00
return _ ( " Issues " ) if total . zero?
2018-04-19 10:43:20 -04:00
content = [ ]
2020-03-04 19:07:49 -05:00
if opened > 0
content << n_ ( " 1 open issue " , " %{issues} open issues " , opened ) % { issues : opened }
2019-04-15 08:25:48 -04:00
end
2020-03-04 19:07:49 -05:00
if closed > 0
content << n_ ( " 1 closed issue " , " %{issues} closed issues " , closed ) % { issues : closed }
2019-04-15 08:25:48 -04:00
end
2018-04-19 10:43:20 -04:00
content . join ( '<br />' ) . html_safe
end
def milestone_merge_requests_tooltip_text ( milestone )
merge_requests = milestone . merge_requests
return _ ( " Merge requests " ) if merge_requests . empty?
content = [ ]
2019-04-15 08:25:48 -04:00
content << n_ ( " 1 open merge request " , " %{merge_requests} open merge requests " , merge_requests . opened . count ) % { merge_requests : merge_requests . opened . count } if merge_requests . opened . any?
content << n_ ( " 1 closed merge request " , " %{merge_requests} closed merge requests " , merge_requests . closed . count ) % { merge_requests : merge_requests . closed . count } if merge_requests . closed . any?
content << n_ ( " 1 merged merge request " , " %{merge_requests} merged merge requests " , merge_requests . merged . count ) % { merge_requests : merge_requests . merged . count } if merge_requests . merged . any?
2018-04-19 10:43:20 -04:00
content . join ( '<br />' ) . html_safe
end
2019-11-06 10:06:23 -05:00
def milestone_releases_tooltip_text ( milestone )
count = milestone . releases . count
return _ ( " Releases " ) if count . zero?
n_ ( " %{releases} release " , " %{releases} releases " , count ) % { releases : count }
end
2019-11-04 10:07:36 -05:00
def recent_releases_with_counts ( milestone )
total_count = milestone . releases . size
return [ [ ] , 0 , 0 ] if total_count == 0
recent_releases = milestone . releases . recent . to_a
more_count = total_count - recent_releases . size
[ recent_releases , total_count , more_count ]
end
2018-04-19 10:43:20 -04:00
def milestone_tooltip_due_date ( milestone )
if milestone . due_date
2018-11-29 23:03:35 -05:00
" #{ milestone . due_date . to_s ( :medium ) } ( #{ remaining_days_in_words ( milestone . due_date , milestone . start_date ) } ) "
2018-04-19 20:16:25 -04:00
else
_ ( 'Milestone' )
2016-11-15 12:48:30 -05:00
end
end
def milestone_date_range ( milestone )
if milestone . start_date && milestone . due_date
2017-01-26 12:54:50 -05:00
" #{ milestone . start_date . to_s ( :medium ) } – #{ milestone . due_date . to_s ( :medium ) } "
2016-11-15 12:48:30 -05:00
elsif milestone . due_date
if milestone . due_date . past?
2019-04-15 08:25:48 -04:00
_ ( " expired on %{milestone_due_date} " ) % { milestone_due_date : milestone . due_date . strftime ( '%b %-d, %Y' ) }
2016-11-15 12:48:30 -05:00
else
2019-04-15 08:25:48 -04:00
_ ( " expires on %{milestone_due_date} " ) % { milestone_due_date : milestone . due_date . strftime ( '%b %-d, %Y' ) }
2016-11-15 12:48:30 -05:00
end
elsif milestone . start_date
if milestone . start_date . past?
2019-04-15 08:25:48 -04:00
_ ( " started on %{milestone_start_date} " ) % { milestone_start_date : milestone . start_date . strftime ( '%b %-d, %Y' ) }
2016-11-15 12:48:30 -05:00
else
2019-04-15 08:25:48 -04:00
_ ( " starts on %{milestone_start_date} " ) % { milestone_start_date : milestone . start_date . strftime ( '%b %-d, %Y' ) }
2016-11-15 12:48:30 -05:00
end
2016-02-25 15:23:34 -05:00
end
end
2017-04-25 10:25:20 -04:00
2019-11-07 16:06:14 -05:00
def milestone_tab_path ( milestone , tab )
if milestone . global_milestone?
url_for ( action : tab , title : milestone . title , format : :json )
2017-06-08 12:43:05 -04:00
else
2019-11-07 16:06:14 -05:00
url_for ( action : tab , format : :json )
2017-04-25 10:25:20 -04:00
end
end
2019-11-07 16:06:14 -05:00
def update_milestone_path ( milestone , params = { } )
if milestone . project_milestone?
project_milestone_path ( milestone . project , milestone , milestone : params )
2017-06-08 12:43:05 -04:00
else
2019-11-07 16:06:14 -05:00
group_milestone_route ( milestone , params )
2017-04-25 10:25:20 -04:00
end
end
2017-07-07 11:08:49 -04:00
def group_milestone_route ( milestone , params = { } )
params = nil if params . empty?
2017-08-24 12:31:20 -04:00
if milestone . legacy_group_milestone?
2017-07-07 11:08:49 -04:00
group_milestone_path ( @group , milestone . safe_title , title : milestone . title , milestone : params )
else
group_milestone_path ( @group , milestone . iid , milestone : params )
end
end
2018-08-03 15:52:37 -04:00
2018-12-20 06:14:33 -05:00
def group_or_project_milestone_path ( milestone )
params =
if milestone . group_milestone?
{ milestone : { title : milestone . title } }
else
{ title : milestone . title }
end
milestone_path ( milestone . milestone , params )
2018-08-03 15:52:37 -04:00
end
2018-11-28 13:38:24 -05:00
2019-11-07 16:06:14 -05:00
def edit_milestone_path ( milestone )
if milestone . group_milestone?
edit_group_milestone_path ( milestone . group , milestone )
elsif milestone . project_milestone?
edit_project_milestone_path ( milestone . project , milestone )
end
end
2018-11-28 13:38:24 -05:00
def can_admin_project_milestones?
strong_memoize ( :can_admin_project_milestones ) do
can? ( current_user , :admin_milestone , @project )
end
end
def can_admin_group_milestones?
strong_memoize ( :can_admin_group_milestones ) do
can? ( current_user , :admin_milestone , @project . group )
end
end
2020-03-24 14:07:55 -04:00
def display_issues_count_warning? ( milestone )
milestone_visible_issues_count ( milestone ) > Milestone :: DISPLAY_ISSUES_LIMIT
end
def milestone_issues_count_message ( milestone )
total_count = milestone_visible_issues_count ( milestone )
limit = Milestone :: DISPLAY_ISSUES_LIMIT
link_options = { milestone_title : @milestone . title }
message = _ ( 'Showing %{limit} of %{total_count} issues. ' ) % { limit : limit , total_count : total_count }
message += link_to ( _ ( 'View all issues' ) , milestones_issues_path ( link_options ) )
message . html_safe
end
private
def milestone_visible_issues_count ( milestone )
@milestone_visible_issues_count || = milestone . issues_visible_to_user ( current_user ) . size
end
2015-01-06 15:32:04 -05:00
end
2019-09-13 09:26:31 -04:00
MilestonesHelper . prepend_if_ee ( 'EE::MilestonesHelper' )