2018-08-18 11:19:57 +00:00
# frozen_string_literal: true
2020-05-27 18:08:14 +00:00
module TimeboxesHelper
2018-04-19 14:43:20 +00:00
include EntityDateHelper
2018-11-28 18:38:24 +00:00
include Gitlab :: Utils :: StrongMemoize
2018-04-19 14:43:20 +00:00
2019-11-07 21:06:14 +00: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 20:32:04 +00:00
def milestones_filter_path ( opts = { } )
if @project
2017-06-29 17:06:35 +00:00
project_milestones_path ( @project , opts )
2015-01-06 20:32:04 +00:00
elsif @group
group_milestones_path ( @group , opts )
2015-03-03 15:19:37 +00:00
else
dashboard_milestones_path ( opts )
2015-01-06 20:32:04 +00:00
end
end
2015-03-09 22:20:32 +00:00
2020-03-24 18:07:55 +00:00
def milestones_issues_path ( opts = { } )
2016-03-07 04:07:19 +00:00
if @project
2017-06-29 17:06:35 +00:00
project_issues_path ( @project , opts )
2016-03-07 04:07:19 +00:00
elsif @group
issues_group_path ( @group , opts )
else
issues_dashboard_path ( opts )
end
end
2017-03-24 19:41:08 +00:00
def milestones_browse_issuables_path ( milestone , state : nil , type : )
opts = { milestone_title : milestone . title , state : state }
2016-03-07 04:07:19 +00:00
if @project
2020-07-27 12:09:50 +00:00
polymorphic_path ( [ @project , type ] , opts )
2016-03-07 04:07:19 +00:00
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 16:39:26 +00:00
issues = milestone . issues . with_label ( label . title )
issues =
case state
when :opened
issues . opened
when :closed
issues . closed
else
2019-04-15 12:25:48 +00:00
raise ArgumentError , _ ( " invalid milestone state `%{state}` " ) % { state : state }
2017-08-10 16:39:26 +00:00
end
issues . size
2016-03-07 04:07:19 +00:00
end
2016-07-22 20:11:07 +00:00
# Returns count of milestones for different states
2016-08-24 17:29:27 +00:00
# Uses explicit hash keys as the 'opened' state URL params differs from the db value
2016-07-22 20:11:07 +00:00
# and we need to add the total
2018-08-27 15:31:01 +00:00
# rubocop: disable CodeReuse/ActiveRecord
2016-07-25 21:23:27 +00:00
def milestone_counts ( milestones )
counts = milestones . reorder ( nil ) . group ( :state ) . count
2016-08-24 17:29:27 +00:00
2016-07-22 20:11:07 +00:00
{
2016-08-24 17:29:27 +00:00
opened : counts [ 'active' ] || 0 ,
closed : counts [ 'closed' ] || 0 ,
all : counts . values . sum || 0
2016-07-22 20:11:07 +00:00
}
2016-07-22 09:18:38 +00:00
end
2018-08-27 15:31:01 +00:00
# rubocop: enable CodeReuse/ActiveRecord
2016-07-22 09:18:38 +00:00
2016-07-26 13:30:14 +00: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 22:58:28 +00:00
def milestone_class_for_state ( param , check , match_blank_param = false )
2016-07-26 13:30:14 +00:00
if match_blank_param
'active' if param . blank? || param == check
2017-07-07 15:08:49 +00:00
elsif param == check
'active'
2016-07-26 13:30:14 +00:00
else
2017-07-07 15:08:49 +00:00
check
2016-07-26 13:30:14 +00:00
end
end
2018-04-19 14:43:20 +00:00
def milestone_progress_tooltip_text ( milestone )
2020-03-07 00:08:25 +00:00
has_issues = milestone . total_issues_count > 0
2018-04-19 14:43:20 +00:00
if has_issues
[
_ ( 'Progress' ) ,
2020-03-07 00:08:25 +00:00
_ ( " %{percent}%% complete " ) % { percent : milestone . percent_complete }
2018-04-19 14:43:20 +00:00
] . join ( '<br />' )
else
_ ( 'Progress' )
end
end
2015-03-09 22:20:32 +00:00
def milestone_progress_bar ( milestone )
options = {
2018-04-09 19:31:01 +00:00
class : 'progress-bar bg-success' ,
2020-03-07 00:08:25 +00:00
style : " width: #{ milestone . percent_complete } %; "
2015-03-09 22:20:32 +00:00
}
content_tag :div , class : 'progress' do
content_tag :div , nil , options
end
end
2015-03-27 02:13:49 +00:00
2016-03-16 19:14:31 +00:00
def milestones_filter_dropdown_path
2016-07-16 08:41:55 +00:00
project = @target_project || @project
2016-07-18 16:43:00 +00:00
if project
2017-06-29 17:06:35 +00:00
project_milestones_path ( project , :json )
2017-06-22 07:25:56 +00:00
elsif @group
group_milestones_path ( @group , :json )
2016-03-16 19:14:31 +00:00
else
2016-03-22 18:19:53 +00:00
dashboard_milestones_path ( :json )
2016-03-16 19:14:31 +00:00
end
2015-03-27 02:13:49 +00:00
end
2016-02-25 20:23:34 +00:00
2018-04-19 14:43:20 +00:00
def milestone_time_for ( date , date_type )
title = date_type == :start ? " Start date " : " End date "
if date
2018-08-18 11:19:57 +00:00
time_ago = time_ago_in_words ( date ) . sub ( " about " , " " )
state = if date . past?
" ago "
else
" remaining "
end
2018-04-19 14:43:20 +00:00
content = [
title ,
" <br /> " ,
date . to_s ( :medium ) ,
2018-08-18 11:19:57 +00:00
" ( #{ time_ago } #{ state } ) "
2018-04-19 14:43:20 +00:00
] . join ( " " )
2017-03-24 16:43:52 +00:00
content . html_safe
2018-04-19 14:43:20 +00:00
else
title
end
end
def milestone_issues_tooltip_text ( milestone )
2020-03-07 00:08:25 +00:00
total = milestone . total_issues_count
opened = milestone . opened_issues_count
closed = milestone . closed_issues_count
2018-04-19 14:43:20 +00:00
2020-08-12 06:09:53 +00:00
return _ ( " Issues " ) if total == 0
2018-04-19 14:43:20 +00:00
content = [ ]
2020-03-05 00:07:49 +00:00
if opened > 0
content << n_ ( " 1 open issue " , " %{issues} open issues " , opened ) % { issues : opened }
2019-04-15 12:25:48 +00:00
end
2020-03-05 00:07:49 +00:00
if closed > 0
content << n_ ( " 1 closed issue " , " %{issues} closed issues " , closed ) % { issues : closed }
2019-04-15 12:25:48 +00:00
end
2018-04-19 14:43:20 +00: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 12:25:48 +00: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 14:43:20 +00:00
content . join ( '<br />' ) . html_safe
end
2019-11-06 15:06:23 +00:00
def milestone_releases_tooltip_text ( milestone )
count = milestone . releases . count
2020-08-12 06:09:53 +00:00
return _ ( " Releases " ) if count == 0
2019-11-06 15:06:23 +00:00
n_ ( " %{releases} release " , " %{releases} releases " , count ) % { releases : count }
end
2019-11-04 15:07:36 +00: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 14:43:20 +00:00
def milestone_tooltip_due_date ( milestone )
if milestone . due_date
2018-11-30 04:03:35 +00:00
" #{ milestone . due_date . to_s ( :medium ) } ( #{ remaining_days_in_words ( milestone . due_date , milestone . start_date ) } ) "
2018-04-20 00:16:25 +00:00
else
_ ( 'Milestone' )
2016-11-15 17:48:30 +00:00
end
end
2020-05-27 18:08:14 +00:00
def timebox_date_range ( timebox )
if timebox . start_date && timebox . due_date
" #{ timebox . start_date . to_s ( :medium ) } – #{ timebox . due_date . to_s ( :medium ) } "
elsif timebox . due_date
if timebox . due_date . past?
_ ( " expired on %{timebox_due_date} " ) % { timebox_due_date : timebox . due_date . to_s ( :medium ) }
2016-11-15 17:48:30 +00:00
else
2020-05-27 18:08:14 +00:00
_ ( " expires on %{timebox_due_date} " ) % { timebox_due_date : timebox . due_date . to_s ( :medium ) }
2016-11-15 17:48:30 +00:00
end
2020-05-27 18:08:14 +00:00
elsif timebox . start_date
if timebox . start_date . past?
_ ( " started on %{timebox_start_date} " ) % { timebox_start_date : timebox . start_date . to_s ( :medium ) }
2016-11-15 17:48:30 +00:00
else
2020-05-27 18:08:14 +00:00
_ ( " starts on %{timebox_start_date} " ) % { timebox_start_date : timebox . start_date . to_s ( :medium ) }
2016-11-15 17:48:30 +00:00
end
2016-02-25 20:23:34 +00:00
end
end
2020-05-27 18:08:14 +00:00
alias_method :milestone_date_range , :timebox_date_range
2017-04-25 14:25:20 +00:00
2020-09-18 18:10:26 +00:00
def milestone_tab_path ( milestone , tab , params = { } )
url_for ( params . merge ( action : tab , format : :json ) )
2017-04-25 14:25:20 +00:00
end
2019-11-07 21:06:14 +00:00
def update_milestone_path ( milestone , params = { } )
if milestone . project_milestone?
project_milestone_path ( milestone . project , milestone , milestone : params )
2017-06-08 16:43:05 +00:00
else
2019-11-07 21:06:14 +00:00
group_milestone_route ( milestone , params )
2017-04-25 14:25:20 +00:00
end
end
2017-07-07 15:08:49 +00:00
def group_milestone_route ( milestone , params = { } )
params = nil if params . empty?
2020-05-28 12:08:10 +00:00
group_milestone_path ( milestone . group , milestone . iid , milestone : params )
2017-07-07 15:08:49 +00:00
end
2018-08-03 19:52:37 +00:00
2018-12-20 11:14:33 +00: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 19:52:37 +00:00
end
2018-11-28 18:38:24 +00:00
2019-11-07 21:06:14 +00: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 18:38:24 +00: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 18:07:55 +00: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 20:32:04 +00:00
end
2019-09-13 13:26:31 +00:00
2020-05-27 18:08:14 +00:00
TimeboxesHelper . prepend_if_ee ( 'EE::TimeboxesHelper' )