2018-12-05 23:21:45 +05:30
# frozen_string_literal: true
2015-04-26 12:48:37 +05:30
module MilestonesHelper
2018-10-15 14:42:47 +05:30
include EntityDateHelper
2018-11-29 20:51:05 +05:30
include Gitlab :: Utils :: StrongMemoize
2018-10-15 14:42:47 +05:30
2019-12-26 22:10:19 +05:30
def milestone_status_string ( milestone )
if milestone . closed?
_ ( 'Closed' )
elsif milestone . expired?
_ ( 'Past due' )
elsif milestone . upcoming?
_ ( 'Upcoming' )
else
_ ( 'Open' )
end
end
2015-04-26 12:48:37 +05:30
def milestones_filter_path ( opts = { } )
if @project
2017-09-10 17:25:29 +05:30
project_milestones_path ( @project , opts )
2015-04-26 12:48:37 +05:30
elsif @group
group_milestones_path ( @group , opts )
else
dashboard_milestones_path ( opts )
end
end
2016-06-02 11:05:42 +05:30
def milestones_label_path ( opts = { } )
if @project
2017-09-10 17:25:29 +05:30
project_issues_path ( @project , opts )
2016-06-02 11:05:42 +05:30
elsif @group
issues_group_path ( @group , opts )
else
issues_dashboard_path ( opts )
end
end
2017-08-17 22:00:37 +05:30
def milestones_browse_issuables_path ( milestone , state : nil , type : )
opts = { milestone_title : milestone . title , state : state }
2016-06-02 11:05:42 +05:30
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 : )
2018-03-17 18:26:18 +05:30
issues = milestone . issues . with_label ( label . title )
issues =
case state
when :opened
issues . opened
when :closed
issues . closed
else
2019-07-31 22:56:46 +05:30
raise ArgumentError , _ ( " invalid milestone state `%{state}` " ) % { state : state }
2018-03-17 18:26:18 +05:30
end
issues . size
2016-06-02 11:05:42 +05:30
end
2016-11-03 12:29:30 +05:30
# Returns count of milestones for different states
# Uses explicit hash keys as the 'opened' state URL params differs from the db value
# and we need to add the total
2018-12-05 23:21:45 +05:30
# rubocop: disable CodeReuse/ActiveRecord
2016-11-03 12:29:30 +05:30
def milestone_counts ( milestones )
counts = milestones . reorder ( nil ) . group ( :state ) . count
{
opened : counts [ 'active' ] || 0 ,
closed : counts [ 'closed' ] || 0 ,
all : counts . values . sum || 0
}
end
2018-12-05 23:21:45 +05:30
# rubocop: enable CodeReuse/ActiveRecord
2016-11-03 12:29:30 +05:30
# 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
def milestone_class_for_state ( param , check , match_blank_param = false )
if match_blank_param
'active' if param . blank? || param == check
2017-09-10 17:25:29 +05:30
elsif param == check
'active'
2016-11-03 12:29:30 +05:30
else
2017-09-10 17:25:29 +05:30
check
2016-11-03 12:29:30 +05:30
end
end
2018-10-15 14:42:47 +05:30
def milestone_progress_tooltip_text ( milestone )
has_issues = milestone . total_issues_count ( current_user ) > 0
if has_issues
[
_ ( 'Progress' ) ,
_ ( " %{percent}%% complete " ) % { percent : milestone . percent_complete ( current_user ) }
] . join ( '<br />' )
else
_ ( 'Progress' )
end
end
2015-04-26 12:48:37 +05:30
def milestone_progress_bar ( milestone )
options = {
2018-11-08 19:23:39 +05:30
class : 'progress-bar bg-success' ,
2016-06-02 11:05:42 +05:30
style : " width: #{ milestone . percent_complete ( current_user ) } %; "
2015-04-26 12:48:37 +05:30
}
content_tag :div , class : 'progress' do
content_tag :div , nil , options
end
end
2016-06-02 11:05:42 +05:30
def milestones_filter_dropdown_path
2016-11-03 12:29:30 +05:30
project = @target_project || @project
if project
2017-09-10 17:25:29 +05:30
project_milestones_path ( project , :json )
elsif @group
group_milestones_path ( @group , :json )
2016-06-02 11:05:42 +05:30
else
dashboard_milestones_path ( :json )
end
2015-04-26 12:48:37 +05:30
end
2016-04-02 18:10:28 +05:30
2018-10-15 14:42:47 +05:30
def milestone_time_for ( date , date_type )
title = date_type == :start ? " Start date " : " End date "
if date
2018-12-05 23:21:45 +05:30
time_ago = time_ago_in_words ( date ) . sub ( " about " , " " )
state = if date . past?
" ago "
else
" remaining "
end
2018-10-15 14:42:47 +05:30
content = [
title ,
" <br /> " ,
date . to_s ( :medium ) ,
2018-12-05 23:21:45 +05:30
" ( #{ time_ago } #{ state } ) "
2018-10-15 14:42:47 +05:30
] . join ( " " )
2017-08-17 22:00:37 +05:30
content . html_safe
2018-10-15 14:42:47 +05:30
else
title
end
end
def milestone_issues_tooltip_text ( milestone )
issues = milestone . count_issues_by_state ( current_user )
return _ ( " Issues " ) if issues . empty?
content = [ ]
2019-07-31 22:56:46 +05:30
if issues [ " opened " ]
content << n_ ( " 1 open issue " , " %{issues} open issues " , issues [ " opened " ] ) % { issues : issues [ " opened " ] }
end
if issues [ " closed " ]
content << n_ ( " 1 closed issue " , " %{issues} closed issues " , issues [ " closed " ] ) % { issues : issues [ " closed " ] }
end
2018-10-15 14:42:47 +05:30
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-07-31 22:56:46 +05:30
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-10-15 14:42:47 +05:30
content . join ( '<br />' ) . html_safe
end
2019-12-26 22:10:19 +05:30
def milestone_releases_tooltip_text ( milestone )
count = milestone . releases . count
return _ ( " Releases " ) if count . zero?
n_ ( " %{releases} release " , " %{releases} releases " , count ) % { releases : count }
end
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-10-15 14:42:47 +05:30
def milestone_tooltip_due_date ( milestone )
if milestone . due_date
2019-02-15 15:39:39 +05:30
" #{ milestone . due_date . to_s ( :medium ) } ( #{ remaining_days_in_words ( milestone . due_date , milestone . start_date ) } ) "
2018-11-08 19:23:39 +05:30
else
_ ( 'Milestone' )
2017-08-17 22:00:37 +05:30
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?
2019-07-31 22:56:46 +05:30
_ ( " expired on %{milestone_due_date} " ) % { milestone_due_date : milestone . due_date . strftime ( '%b %-d, %Y' ) }
2017-08-17 22:00:37 +05:30
else
2019-07-31 22:56:46 +05:30
_ ( " expires on %{milestone_due_date} " ) % { milestone_due_date : milestone . due_date . strftime ( '%b %-d, %Y' ) }
2017-08-17 22:00:37 +05:30
end
elsif milestone . start_date
if milestone . start_date . past?
2019-07-31 22:56:46 +05:30
_ ( " started on %{milestone_start_date} " ) % { milestone_start_date : milestone . start_date . strftime ( '%b %-d, %Y' ) }
2017-08-17 22:00:37 +05:30
else
2019-07-31 22:56:46 +05:30
_ ( " starts on %{milestone_start_date} " ) % { milestone_start_date : milestone . start_date . strftime ( '%b %-d, %Y' ) }
2017-08-17 22:00:37 +05:30
end
end
end
2019-12-26 22:10:19 +05:30
def milestone_tab_path ( milestone , tab )
if milestone . global_milestone?
url_for ( action : tab , title : milestone . title , format : :json )
2017-09-10 17:25:29 +05:30
else
2019-12-26 22:10:19 +05:30
url_for ( action : tab , format : :json )
2017-08-17 22:00:37 +05:30
end
end
2019-12-26 22:10:19 +05:30
def update_milestone_path ( milestone , params = { } )
if milestone . project_milestone?
project_milestone_path ( milestone . project , milestone , milestone : params )
2017-09-10 17:25:29 +05:30
else
2019-12-26 22:10:19 +05:30
group_milestone_route ( milestone , params )
2017-09-10 17:25:29 +05:30
end
end
def group_milestone_route ( milestone , params = { } )
params = nil if params . empty?
2018-03-17 18:26:18 +05:30
if milestone . legacy_group_milestone?
2017-09-10 17:25:29 +05:30
group_milestone_path ( @group , milestone . safe_title , title : milestone . title , milestone : params )
else
group_milestone_path ( @group , milestone . iid , milestone : params )
2016-04-02 18:10:28 +05:30
end
end
2018-11-18 11:00:15 +05:30
2019-02-15 15:39:39 +05:30
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-11-18 11:00:15 +05:30
end
2018-11-29 20:51:05 +05:30
2019-12-26 22:10:19 +05:30
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-29 20:51:05 +05:30
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
2015-04-26 12:48:37 +05:30
end
2019-12-04 20:38:33 +05:30
MilestonesHelper . prepend_if_ee ( 'EE::MilestonesHelper' )