You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

versions_controller.rb 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. # frozen_string_literal: true
  2. # Redmine - project management software
  3. # Copyright (C) 2006- Jean-Philippe Lang
  4. #
  5. # This program is free software; you can redistribute it and/or
  6. # modify it under the terms of the GNU General Public License
  7. # as published by the Free Software Foundation; either version 2
  8. # of the License, or (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. class VersionsController < ApplicationController
  19. menu_item :roadmap
  20. model_object Version
  21. before_action :find_model_object, :except => [:index, :new, :create, :close_completed]
  22. before_action :find_project_from_association, :except => [:index, :new, :create, :close_completed]
  23. before_action :find_project_by_project_id, :only => [:index, :new, :create, :close_completed]
  24. before_action :authorize
  25. accept_api_auth :index, :show, :create, :update, :destroy
  26. include VersionsHelper
  27. helper :custom_fields
  28. helper :projects
  29. def index
  30. respond_to do |format|
  31. format.html do
  32. @trackers = @project.trackers.sorted.to_a
  33. retrieve_selected_tracker_ids(@trackers, @trackers.select {|t| t.is_in_roadmap?})
  34. @with_subprojects = params[:with_subprojects].nil? ? Setting.display_subprojects_issues? : (params[:with_subprojects] == '1')
  35. project_ids = @with_subprojects ? @project.self_and_descendants.pluck(:id) : [@project.id]
  36. @versions = @project.shared_versions.preload(:custom_values)
  37. @versions += @project.rolled_up_versions.visible.preload(:custom_values) if @with_subprojects
  38. @versions = @versions.to_a.uniq.sort
  39. unless params[:completed]
  40. @completed_versions = @versions.select(&:completed?).reverse
  41. @versions -= @completed_versions
  42. end
  43. @issues_by_version = {}
  44. if @selected_tracker_ids.any? && @versions.any?
  45. issues = Issue.visible.
  46. includes(:project, :tracker).
  47. preload(:status, :priority, :fixed_version).
  48. where(:tracker_id => @selected_tracker_ids, :project_id => project_ids, :fixed_version_id => @versions.map(&:id)).
  49. order("#{Project.table_name}.lft, #{Tracker.table_name}.position, #{Issue.table_name}.id")
  50. @issues_by_version = issues.group_by(&:fixed_version)
  51. end
  52. @versions.reject! {|version| !project_ids.include?(version.project_id) && @issues_by_version[version].blank?}
  53. end
  54. format.api do
  55. @versions = @project.shared_versions.to_a
  56. end
  57. end
  58. end
  59. def show
  60. respond_to do |format|
  61. format.html do
  62. @issues = @version.fixed_issues.visible.
  63. includes(:status, :tracker, :priority).
  64. preload(:project).
  65. reorder("#{Tracker.table_name}.position, #{Issue.table_name}.id").
  66. to_a
  67. end
  68. format.api
  69. format.text do
  70. send_data(version_to_text(@version), type: 'text/plain', filename: "#{@version.name}.txt")
  71. end
  72. end
  73. end
  74. def new
  75. @version = @project.versions.build
  76. @version.safe_attributes = params[:version]
  77. respond_to do |format|
  78. format.html
  79. format.js
  80. end
  81. end
  82. def create
  83. @version = @project.versions.build
  84. if params[:version]
  85. attributes = params[:version].dup
  86. attributes.delete('sharing') unless attributes.nil? || @version.allowed_sharings.include?(attributes['sharing'])
  87. @version.safe_attributes = attributes
  88. end
  89. if request.post?
  90. if @version.save
  91. respond_to do |format|
  92. format.html do
  93. flash[:notice] = l(:notice_successful_create)
  94. redirect_back_or_default settings_project_path(@project, :tab => 'versions')
  95. end
  96. format.js
  97. format.api do
  98. render :action => 'show', :status => :created, :location => version_url(@version)
  99. end
  100. end
  101. else
  102. respond_to do |format|
  103. format.html {render :action => 'new'}
  104. format.js {render :action => 'new'}
  105. format.api {render_validation_errors(@version)}
  106. end
  107. end
  108. end
  109. end
  110. def edit
  111. end
  112. def update
  113. if params[:version]
  114. attributes = params[:version].dup
  115. attributes.delete('sharing') unless @version.allowed_sharings.include?(attributes['sharing'])
  116. @version.safe_attributes = attributes
  117. if @version.save
  118. respond_to do |format|
  119. format.html do
  120. flash[:notice] = l(:notice_successful_update)
  121. redirect_back_or_default settings_project_path(@project, :tab => 'versions')
  122. end
  123. format.api {render_api_ok}
  124. end
  125. else
  126. respond_to do |format|
  127. format.html {render :action => 'edit'}
  128. format.api {render_validation_errors(@version)}
  129. end
  130. end
  131. end
  132. end
  133. def close_completed
  134. if request.put?
  135. @project.close_completed_versions
  136. end
  137. redirect_to settings_project_path(@project, :tab => 'versions')
  138. end
  139. def destroy
  140. if @version.deletable?
  141. @version.destroy
  142. respond_to do |format|
  143. format.html {redirect_back_or_default settings_project_path(@project, :tab => 'versions')}
  144. format.api {render_api_ok}
  145. end
  146. else
  147. respond_to do |format|
  148. format.html do
  149. flash[:error] = l(:notice_unable_delete_version)
  150. redirect_to settings_project_path(@project, :tab => 'versions')
  151. end
  152. format.api {head :unprocessable_entity}
  153. end
  154. end
  155. end
  156. def status_by
  157. respond_to do |format|
  158. format.html {render :action => 'show'}
  159. format.js
  160. end
  161. end
  162. private
  163. def retrieve_selected_tracker_ids(selectable_trackers, default_trackers=nil)
  164. if ids = params[:tracker_ids]
  165. @selected_tracker_ids =
  166. if ids.is_a? Array
  167. ids.collect {|id| id.to_i.to_s}
  168. else
  169. ids.split('/').collect {|id| id.to_i.to_s}
  170. end
  171. else
  172. @selected_tracker_ids =
  173. (default_trackers || selectable_trackers).collect {|t| t.id.to_s}
  174. end
  175. end
  176. end