##// END OF EJS Templates
Resourcified documents....
Jean-Philippe Lang -
r7890:c3c2a4afe008
parent child
Show More
@@ -1,79 +1,89
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class DocumentsController < ApplicationController
18 class DocumentsController < ApplicationController
19 default_search_scope :documents
19 default_search_scope :documents
20 model_object Document
20 model_object Document
21 before_filter :find_project_by_project_id, :only => [:index, :new]
21 before_filter :find_project_by_project_id, :only => [:index, :new, :create]
22 before_filter :find_model_object, :except => [:index, :new]
22 before_filter :find_model_object, :except => [:index, :new, :create]
23 before_filter :find_project_from_association, :except => [:index, :new]
23 before_filter :find_project_from_association, :except => [:index, :new, :create]
24 before_filter :authorize
24 before_filter :authorize
25
25
26 helper :attachments
26 helper :attachments
27
27
28 def index
28 def index
29 @sort_by = %w(category date title author).include?(params[:sort_by]) ? params[:sort_by] : 'category'
29 @sort_by = %w(category date title author).include?(params[:sort_by]) ? params[:sort_by] : 'category'
30 documents = @project.documents.find :all, :include => [:attachments, :category]
30 documents = @project.documents.find :all, :include => [:attachments, :category]
31 case @sort_by
31 case @sort_by
32 when 'date'
32 when 'date'
33 @grouped = documents.group_by {|d| d.updated_on.to_date }
33 @grouped = documents.group_by {|d| d.updated_on.to_date }
34 when 'title'
34 when 'title'
35 @grouped = documents.group_by {|d| d.title.first.upcase}
35 @grouped = documents.group_by {|d| d.title.first.upcase}
36 when 'author'
36 when 'author'
37 @grouped = documents.select{|d| d.attachments.any?}.group_by {|d| d.attachments.last.author}
37 @grouped = documents.select{|d| d.attachments.any?}.group_by {|d| d.attachments.last.author}
38 else
38 else
39 @grouped = documents.group_by(&:category)
39 @grouped = documents.group_by(&:category)
40 end
40 end
41 @document = @project.documents.build
41 @document = @project.documents.build
42 render :layout => false if request.xhr?
42 render :layout => false if request.xhr?
43 end
43 end
44
44
45 def show
45 def show
46 @attachments = @document.attachments.find(:all, :order => "created_on DESC")
46 @attachments = @document.attachments.find(:all, :order => "created_on DESC")
47 end
47 end
48
48
49 def new
49 def new
50 @document = @project.documents.build(params[:document])
50 @document = @project.documents.build(params[:document])
51 end
52
53 def create
54 @document = @project.documents.build(params[:document])
51 if request.post? and @document.save
55 if request.post? and @document.save
52 attachments = Attachment.attach_files(@document, params[:attachments])
56 attachments = Attachment.attach_files(@document, params[:attachments])
53 render_attachment_warning_if_needed(@document)
57 render_attachment_warning_if_needed(@document)
54 flash[:notice] = l(:notice_successful_create)
58 flash[:notice] = l(:notice_successful_create)
55 redirect_to :action => 'index', :project_id => @project
59 redirect_to :action => 'index', :project_id => @project
60 else
61 render :action => 'new'
56 end
62 end
57 end
63 end
58
64
59 def edit
65 def edit
60 @categories = DocumentCategory.active #TODO: use it in the views
66 end
61 if request.post? and @document.update_attributes(params[:document])
67
68 def update
69 if request.put? and @document.update_attributes(params[:document])
62 flash[:notice] = l(:notice_successful_update)
70 flash[:notice] = l(:notice_successful_update)
63 redirect_to :action => 'show', :id => @document
71 redirect_to :action => 'show', :id => @document
72 else
73 render :action => 'edit'
64 end
74 end
65 end
75 end
66
76
67 def destroy
77 def destroy
68 @document.destroy
78 @document.destroy if request.delete?
69 redirect_to :controller => 'documents', :action => 'index', :project_id => @project
79 redirect_to :controller => 'documents', :action => 'index', :project_id => @project
70 end
80 end
71
81
72 def add_attachment
82 def add_attachment
73 attachments = Attachment.attach_files(@document, params[:attachments])
83 attachments = Attachment.attach_files(@document, params[:attachments])
74 render_attachment_warning_if_needed(@document)
84 render_attachment_warning_if_needed(@document)
75
85
76 Mailer.deliver_attachments_added(attachments[:files]) if attachments.present? && attachments[:files].present? && Setting.notified_events.include?('document_added')
86 Mailer.deliver_attachments_added(attachments[:files]) if attachments.present? && attachments[:files].present? && Setting.notified_events.include?('document_added')
77 redirect_to :action => 'show', :id => @document
87 redirect_to :action => 'show', :id => @document
78 end
88 end
79 end
89 end
@@ -1,6 +1,6
1 <h4><%= link_to h(document.title), :controller => 'documents', :action => 'show', :id => document %></h4>
1 <h4><%= link_to h(document.title), document_path(document) %></h4>
2 <p><em><%= format_time(document.updated_on) %></em></p>
2 <p><em><%= format_time(document.updated_on) %></em></p>
3
3
4 <div class="wiki">
4 <div class="wiki">
5 <%= textilizable(truncate_lines(document.description), :object => document) %>
5 <%= textilizable(truncate_lines(document.description), :object => document) %>
6 </div>
6 </div>
@@ -1,15 +1,15
1 <%= error_messages_for 'document' %>
1 <%= f.error_messages %>
2 <div class="box">
3 <!--[form:document]-->
4 <p><label for="document_category_id"><%=l(:field_category)%></label>
5 <%= select('document', 'category_id', DocumentCategory.active.collect {|c| [c.name, c.id]}) %></p>
6
2
7 <p><label for="document_title"><%=l(:field_title)%> <span class="required">*</span></label>
3 <div class="box tabular">
8 <%= text_field 'document', 'title', :size => 60 %></p>
4 <p><%= f.select :category_id, DocumentCategory.active.collect {|c| [c.name, c.id]} %></p>
9
5 <p><%= f.text_field :title, :required => true, :size => 60 %></p>
10 <p><label for="document_description"><%=l(:field_description)%></label>
6 <p><%= f.text_area :description, :cols => 60, :rows => 15, :class => 'wiki-edit' %></p>
11 <%= text_area 'document', 'description', :cols => 60, :rows => 15, :class => 'wiki-edit' %></p>
12 <!--[eoform:document]-->
13 </div>
7 </div>
14
8
15 <%= wikitoolbar_for 'document_description' %>
9 <%= wikitoolbar_for 'document_description' %>
10
11 <% if @document.new_record? %>
12 <div class="box tabular">
13 <p><label><%=l(:label_attachment_plural)%></label><%= render :partial => 'attachments/form' %></p>
14 </div>
15 <% end %>
@@ -1,8 +1,8
1 <h2><%=l(:label_document)%></h2>
1 <h2><%=l(:label_document)%></h2>
2
2
3 <% form_tag({:action => 'edit', :id => @document}, :class => "tabular") do %>
3 <% labelled_form_for @document do |f| %>
4 <%= render :partial => 'form' %>
4 <%= render :partial => 'form', :locals => {:f => f} %>
5 <%= submit_tag l(:button_save) %>
5 <p><%= submit_tag l(:button_save) %></p>
6 <% end %>
6 <% end %>
7
7
8
8
@@ -1,39 +1,36
1 <div class="contextual">
1 <div class="contextual">
2 <%= link_to_if_authorized l(:label_document_new),
2 <%= link_to l(:label_document_new), new_project_document_path(@project), :class => 'icon icon-add',
3 {:controller => 'documents', :action => 'new', :project_id => @project},
3 :onclick => 'Element.show("add-document"); Form.Element.focus("document_title"); return false;' if User.current.allowed_to?(:manage_documents, @project) %>
4 :class => 'icon icon-add',
5 :onclick => 'Element.show("add-document"); Form.Element.focus("document_title"); return false;' %>
6 </div>
4 </div>
7
5
8 <div id="add-document" style="display:none;">
6 <div id="add-document" style="display:none;">
9 <h2><%=l(:label_document_new)%></h2>
7 <h2><%=l(:label_document_new)%></h2>
10 <% form_tag({:controller => 'documents', :action => 'new', :project_id => @project}, :class => "tabular", :multipart => true) do %>
8 <% labelled_form_for @document, :url => project_documents_path(@project), :html => {:multipart => true} do |f| %>
11 <%= render :partial => 'documents/form' %>
9 <%= render :partial => 'form', :locals => {:f => f} %>
12 <div class="box">
10 <p>
13 <p><label><%=l(:label_attachment_plural)%></label><%= render :partial => 'attachments/form' %></p>
14 </div>
15 <%= submit_tag l(:button_create) %>
11 <%= submit_tag l(:button_create) %>
16 <%= link_to l(:button_cancel), "#", :onclick => 'Element.hide("add-document")' %>
12 <%= link_to l(:button_cancel), "#", :onclick => 'Element.hide("add-document")' %>
13 </p>
17 <% end %>
14 <% end %>
18 </div>
15 </div>
19
16
20 <h2><%=l(:label_document_plural)%></h2>
17 <h2><%=l(:label_document_plural)%></h2>
21
18
22 <% if @grouped.empty? %><p class="nodata"><%= l(:label_no_data) %></p><% end %>
19 <% if @grouped.empty? %><p class="nodata"><%= l(:label_no_data) %></p><% end %>
23
20
24 <% @grouped.keys.sort.each do |group| %>
21 <% @grouped.keys.sort.each do |group| %>
25 <h3><%= group %></h3>
22 <h3><%= group %></h3>
26 <%= render :partial => 'documents/document', :collection => @grouped[group] %>
23 <%= render :partial => 'documents/document', :collection => @grouped[group] %>
27 <% end %>
24 <% end %>
28
25
29 <% content_for :sidebar do %>
26 <% content_for :sidebar do %>
30 <h3><%= l(:label_sort_by, '') %></h3>
27 <h3><%= l(:label_sort_by, '') %></h3>
31 <% form_tag({}, :method => :get) do %>
28 <% form_tag({}, :method => :get) do %>
32 <label><%= radio_button_tag 'sort_by', 'category', (@sort_by == 'category'), :onclick => 'this.form.submit();' %> <%= l(:field_category) %></label><br />
29 <label><%= radio_button_tag 'sort_by', 'category', (@sort_by == 'category'), :onclick => 'this.form.submit();' %> <%= l(:field_category) %></label><br />
33 <label><%= radio_button_tag 'sort_by', 'date', (@sort_by == 'date'), :onclick => 'this.form.submit();' %> <%= l(:label_date) %></label><br />
30 <label><%= radio_button_tag 'sort_by', 'date', (@sort_by == 'date'), :onclick => 'this.form.submit();' %> <%= l(:label_date) %></label><br />
34 <label><%= radio_button_tag 'sort_by', 'title', (@sort_by == 'title'), :onclick => 'this.form.submit();' %> <%= l(:field_title) %></label><br />
31 <label><%= radio_button_tag 'sort_by', 'title', (@sort_by == 'title'), :onclick => 'this.form.submit();' %> <%= l(:field_title) %></label><br />
35 <label><%= radio_button_tag 'sort_by', 'author', (@sort_by == 'author'), :onclick => 'this.form.submit();' %> <%= l(:field_author) %></label>
32 <label><%= radio_button_tag 'sort_by', 'author', (@sort_by == 'author'), :onclick => 'this.form.submit();' %> <%= l(:field_author) %></label>
36 <% end %>
33 <% end %>
37 <% end %>
34 <% end %>
38
35
39 <% html_title(l(:label_document_plural)) -%>
36 <% html_title(l(:label_document_plural)) -%>
@@ -1,13 +1,6
1 <h2><%=l(:label_document_new)%></h2>
1 <h2><%=l(:label_document_new)%></h2>
2
2
3 <% form_tag({:controller => 'documents', :action => 'new', :project_id => @project}, :class => "tabular", :multipart => true) do %>
3 <% labelled_form_for @document, :url => project_documents_path(@project), :html => {:multipart => true} do |f| %>
4 <%= render :partial => 'documents/form' %>
4 <%= render :partial => 'form', :locals => {:f => f} %>
5
5 <p><%= submit_tag l(:button_create) %></p>
6 <div class="box">
7 <p><label><%=l(:label_attachment_plural)%></label><%= render :partial => 'attachments/form' %></p>
8 </div>
9
10 <%= submit_tag l(:button_create) %>
11 <% end %>
6 <% end %>
12
13
@@ -1,32 +1,34
1 <div class="contextual">
1 <div class="contextual">
2 <%= link_to_if_authorized l(:button_edit), {:controller => 'documents', :action => 'edit', :id => @document}, :class => 'icon icon-edit', :accesskey => accesskey(:edit) %>
2 <% if User.current.allowed_to?(:manage_documents, @project) %>
3 <%= link_to_if_authorized l(:button_delete), {:controller => 'documents', :action => 'destroy', :id => @document}, :confirm => l(:text_are_you_sure), :method => :post, :class => 'icon icon-del' %>
3 <%= link_to l(:button_edit), edit_document_path(@document), :class => 'icon icon-edit', :accesskey => accesskey(:edit) %>
4 <%= link_to l(:button_delete), document_path(@document), :confirm => l(:text_are_you_sure), :method => :delete, :class => 'icon icon-del' %>
5 <% end %>
4 </div>
6 </div>
5
7
6 <h2><%=h @document.title %></h2>
8 <h2><%=h @document.title %></h2>
7
9
8 <p><em><%=h @document.category.name %><br />
10 <p><em><%=h @document.category.name %><br />
9 <%= format_date @document.created_on %></em></p>
11 <%= format_date @document.created_on %></em></p>
10 <div class="wiki">
12 <div class="wiki">
11 <%= textilizable @document.description, :attachments => @document.attachments %>
13 <%= textilizable @document.description, :attachments => @document.attachments %>
12 </div>
14 </div>
13
15
14 <h3><%= l(:label_attachment_plural) %></h3>
16 <h3><%= l(:label_attachment_plural) %></h3>
15 <%= link_to_attachments @document %>
17 <%= link_to_attachments @document %>
16
18
17 <% if authorize_for('documents', 'add_attachment') %>
19 <% if authorize_for('documents', 'add_attachment') %>
18 <p><%= link_to l(:label_attachment_new), {}, :onclick => "Element.show('add_attachment_form'); Element.hide(this); Element.scrollTo('add_attachment_form'); return false;",
20 <p><%= link_to l(:label_attachment_new), {}, :onclick => "Element.show('add_attachment_form'); Element.hide(this); Element.scrollTo('add_attachment_form'); return false;",
19 :id => 'attach_files_link' %></p>
21 :id => 'attach_files_link' %></p>
20 <% form_tag({ :controller => 'documents', :action => 'add_attachment', :id => @document }, :multipart => true, :id => "add_attachment_form", :style => "display:none;") do %>
22 <% form_tag({ :controller => 'documents', :action => 'add_attachment', :id => @document }, :multipart => true, :id => "add_attachment_form", :style => "display:none;") do %>
21 <div class="box">
23 <div class="box">
22 <p><%= render :partial => 'attachments/form' %></p>
24 <p><%= render :partial => 'attachments/form' %></p>
23 </div>
25 </div>
24 <%= submit_tag l(:button_add) %>
26 <%= submit_tag l(:button_add) %>
25 <% end %>
27 <% end %>
26 <% end %>
28 <% end %>
27
29
28 <% html_title @document.title -%>
30 <% html_title @document.title -%>
29
31
30 <% content_for :header_tags do %>
32 <% content_for :header_tags do %>
31 <%= stylesheet_link_tag 'scm' %>
33 <%= stylesheet_link_tag 'scm' %>
32 <% end %>
34 <% end %>
@@ -1,258 +1,245
1 ActionController::Routing::Routes.draw do |map|
1 ActionController::Routing::Routes.draw do |map|
2 # Add your own custom routes here.
2 # Add your own custom routes here.
3 # The priority is based upon order of creation: first created -> highest priority.
3 # The priority is based upon order of creation: first created -> highest priority.
4
4
5 # Here's a sample route:
5 # Here's a sample route:
6 # map.connect 'products/:id', :controller => 'catalog', :action => 'view'
6 # map.connect 'products/:id', :controller => 'catalog', :action => 'view'
7 # Keep in mind you can assign values other than :controller and :action
7 # Keep in mind you can assign values other than :controller and :action
8
8
9 map.home '', :controller => 'welcome'
9 map.home '', :controller => 'welcome'
10
10
11 map.signin 'login', :controller => 'account', :action => 'login'
11 map.signin 'login', :controller => 'account', :action => 'login'
12 map.signout 'logout', :controller => 'account', :action => 'logout'
12 map.signout 'logout', :controller => 'account', :action => 'logout'
13
13
14 map.connect 'roles/workflow/:id/:role_id/:tracker_id', :controller => 'roles', :action => 'workflow'
14 map.connect 'roles/workflow/:id/:role_id/:tracker_id', :controller => 'roles', :action => 'workflow'
15 map.connect 'help/:ctrl/:page', :controller => 'help'
15 map.connect 'help/:ctrl/:page', :controller => 'help'
16
16
17 map.with_options :controller => 'time_entry_reports', :action => 'report',:conditions => {:method => :get} do |time_report|
17 map.with_options :controller => 'time_entry_reports', :action => 'report',:conditions => {:method => :get} do |time_report|
18 time_report.connect 'projects/:project_id/issues/:issue_id/time_entries/report'
18 time_report.connect 'projects/:project_id/issues/:issue_id/time_entries/report'
19 time_report.connect 'projects/:project_id/issues/:issue_id/time_entries/report.:format'
19 time_report.connect 'projects/:project_id/issues/:issue_id/time_entries/report.:format'
20 time_report.connect 'projects/:project_id/time_entries/report'
20 time_report.connect 'projects/:project_id/time_entries/report'
21 time_report.connect 'projects/:project_id/time_entries/report.:format'
21 time_report.connect 'projects/:project_id/time_entries/report.:format'
22 time_report.connect 'time_entries/report'
22 time_report.connect 'time_entries/report'
23 time_report.connect 'time_entries/report.:format'
23 time_report.connect 'time_entries/report.:format'
24 end
24 end
25
25
26 map.bulk_edit_time_entry 'time_entries/bulk_edit',
26 map.bulk_edit_time_entry 'time_entries/bulk_edit',
27 :controller => 'timelog', :action => 'bulk_edit', :conditions => { :method => :get }
27 :controller => 'timelog', :action => 'bulk_edit', :conditions => { :method => :get }
28 map.bulk_update_time_entry 'time_entries/bulk_edit',
28 map.bulk_update_time_entry 'time_entries/bulk_edit',
29 :controller => 'timelog', :action => 'bulk_update', :conditions => { :method => :post }
29 :controller => 'timelog', :action => 'bulk_update', :conditions => { :method => :post }
30 map.time_entries_context_menu '/time_entries/context_menu',
30 map.time_entries_context_menu '/time_entries/context_menu',
31 :controller => 'context_menus', :action => 'time_entries'
31 :controller => 'context_menus', :action => 'time_entries'
32 # TODO: wasteful since this is also nested under issues, projects, and projects/issues
32 # TODO: wasteful since this is also nested under issues, projects, and projects/issues
33 map.resources :time_entries, :controller => 'timelog'
33 map.resources :time_entries, :controller => 'timelog'
34
34
35 map.connect 'projects/:id/wiki', :controller => 'wikis', :action => 'edit', :conditions => {:method => :post}
35 map.connect 'projects/:id/wiki', :controller => 'wikis', :action => 'edit', :conditions => {:method => :post}
36 map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :get}
36 map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :get}
37 map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :post}
37 map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :post}
38
38
39 map.with_options :controller => 'messages' do |messages_routes|
39 map.with_options :controller => 'messages' do |messages_routes|
40 messages_routes.with_options :conditions => {:method => :get} do |messages_views|
40 messages_routes.with_options :conditions => {:method => :get} do |messages_views|
41 messages_views.connect 'boards/:board_id/topics/new', :action => 'new'
41 messages_views.connect 'boards/:board_id/topics/new', :action => 'new'
42 messages_views.connect 'boards/:board_id/topics/:id', :action => 'show'
42 messages_views.connect 'boards/:board_id/topics/:id', :action => 'show'
43 messages_views.connect 'boards/:board_id/topics/:id/edit', :action => 'edit'
43 messages_views.connect 'boards/:board_id/topics/:id/edit', :action => 'edit'
44 end
44 end
45 messages_routes.with_options :conditions => {:method => :post} do |messages_actions|
45 messages_routes.with_options :conditions => {:method => :post} do |messages_actions|
46 messages_actions.connect 'boards/:board_id/topics/new', :action => 'new'
46 messages_actions.connect 'boards/:board_id/topics/new', :action => 'new'
47 messages_actions.connect 'boards/:board_id/topics/:id/replies', :action => 'reply'
47 messages_actions.connect 'boards/:board_id/topics/:id/replies', :action => 'reply'
48 messages_actions.connect 'boards/:board_id/topics/:id/:action', :action => /edit|destroy/
48 messages_actions.connect 'boards/:board_id/topics/:id/:action', :action => /edit|destroy/
49 end
49 end
50 end
50 end
51
51
52 map.with_options :controller => 'boards' do |board_routes|
52 map.with_options :controller => 'boards' do |board_routes|
53 board_routes.with_options :conditions => {:method => :get} do |board_views|
53 board_routes.with_options :conditions => {:method => :get} do |board_views|
54 board_views.connect 'projects/:project_id/boards', :action => 'index'
54 board_views.connect 'projects/:project_id/boards', :action => 'index'
55 board_views.connect 'projects/:project_id/boards/new', :action => 'new'
55 board_views.connect 'projects/:project_id/boards/new', :action => 'new'
56 board_views.connect 'projects/:project_id/boards/:id', :action => 'show'
56 board_views.connect 'projects/:project_id/boards/:id', :action => 'show'
57 board_views.connect 'projects/:project_id/boards/:id.:format', :action => 'show'
57 board_views.connect 'projects/:project_id/boards/:id.:format', :action => 'show'
58 board_views.connect 'projects/:project_id/boards/:id/edit', :action => 'edit'
58 board_views.connect 'projects/:project_id/boards/:id/edit', :action => 'edit'
59 end
59 end
60 board_routes.with_options :conditions => {:method => :post} do |board_actions|
60 board_routes.with_options :conditions => {:method => :post} do |board_actions|
61 board_actions.connect 'projects/:project_id/boards', :action => 'new'
61 board_actions.connect 'projects/:project_id/boards', :action => 'new'
62 board_actions.connect 'projects/:project_id/boards/:id/:action', :action => /edit|destroy/
62 board_actions.connect 'projects/:project_id/boards/:id/:action', :action => /edit|destroy/
63 end
63 end
64 end
64 end
65
65
66 map.with_options :controller => 'documents' do |document_routes|
67 document_routes.with_options :conditions => {:method => :get} do |document_views|
68 document_views.connect 'projects/:project_id/documents', :action => 'index'
69 document_views.connect 'projects/:project_id/documents/new', :action => 'new'
70 document_views.connect 'documents/:id', :action => 'show'
71 document_views.connect 'documents/:id/edit', :action => 'edit'
72 end
73 document_routes.with_options :conditions => {:method => :post} do |document_actions|
74 document_actions.connect 'projects/:project_id/documents', :action => 'new'
75 document_actions.connect 'documents/:id/:action', :action => /destroy|edit/
76 end
77 end
78
79 map.resources :issue_moves, :only => [:new, :create], :path_prefix => '/issues', :as => 'move'
66 map.resources :issue_moves, :only => [:new, :create], :path_prefix => '/issues', :as => 'move'
80 map.resources :queries, :except => [:show]
67 map.resources :queries, :except => [:show]
81
68
82 # Misc issue routes. TODO: move into resources
69 # Misc issue routes. TODO: move into resources
83 map.auto_complete_issues '/issues/auto_complete', :controller => 'auto_completes', :action => 'issues'
70 map.auto_complete_issues '/issues/auto_complete', :controller => 'auto_completes', :action => 'issues'
84 map.preview_issue '/issues/preview/:id', :controller => 'previews', :action => 'issue' # TODO: would look nicer as /issues/:id/preview
71 map.preview_issue '/issues/preview/:id', :controller => 'previews', :action => 'issue' # TODO: would look nicer as /issues/:id/preview
85 map.issues_context_menu '/issues/context_menu', :controller => 'context_menus', :action => 'issues'
72 map.issues_context_menu '/issues/context_menu', :controller => 'context_menus', :action => 'issues'
86 map.issue_changes '/issues/changes', :controller => 'journals', :action => 'index'
73 map.issue_changes '/issues/changes', :controller => 'journals', :action => 'index'
87 map.bulk_edit_issue 'issues/bulk_edit', :controller => 'issues', :action => 'bulk_edit', :conditions => { :method => :get }
74 map.bulk_edit_issue 'issues/bulk_edit', :controller => 'issues', :action => 'bulk_edit', :conditions => { :method => :get }
88 map.bulk_update_issue 'issues/bulk_edit', :controller => 'issues', :action => 'bulk_update', :conditions => { :method => :post }
75 map.bulk_update_issue 'issues/bulk_edit', :controller => 'issues', :action => 'bulk_update', :conditions => { :method => :post }
89 map.quoted_issue '/issues/:id/quoted', :controller => 'journals', :action => 'new', :id => /\d+/, :conditions => { :method => :post }
76 map.quoted_issue '/issues/:id/quoted', :controller => 'journals', :action => 'new', :id => /\d+/, :conditions => { :method => :post }
90 map.connect '/issues/:id/destroy', :controller => 'issues', :action => 'destroy', :conditions => { :method => :post } # legacy
77 map.connect '/issues/:id/destroy', :controller => 'issues', :action => 'destroy', :conditions => { :method => :post } # legacy
91
78
92 map.with_options :controller => 'gantts', :action => 'show' do |gantts_routes|
79 map.with_options :controller => 'gantts', :action => 'show' do |gantts_routes|
93 gantts_routes.connect '/projects/:project_id/issues/gantt'
80 gantts_routes.connect '/projects/:project_id/issues/gantt'
94 gantts_routes.connect '/projects/:project_id/issues/gantt.:format'
81 gantts_routes.connect '/projects/:project_id/issues/gantt.:format'
95 gantts_routes.connect '/issues/gantt.:format'
82 gantts_routes.connect '/issues/gantt.:format'
96 end
83 end
97
84
98 map.with_options :controller => 'calendars', :action => 'show' do |calendars_routes|
85 map.with_options :controller => 'calendars', :action => 'show' do |calendars_routes|
99 calendars_routes.connect '/projects/:project_id/issues/calendar'
86 calendars_routes.connect '/projects/:project_id/issues/calendar'
100 calendars_routes.connect '/issues/calendar'
87 calendars_routes.connect '/issues/calendar'
101 end
88 end
102
89
103 map.with_options :controller => 'reports', :conditions => {:method => :get} do |reports|
90 map.with_options :controller => 'reports', :conditions => {:method => :get} do |reports|
104 reports.connect 'projects/:id/issues/report', :action => 'issue_report'
91 reports.connect 'projects/:id/issues/report', :action => 'issue_report'
105 reports.connect 'projects/:id/issues/report/:detail', :action => 'issue_report_details'
92 reports.connect 'projects/:id/issues/report/:detail', :action => 'issue_report_details'
106 end
93 end
107
94
108 # Following two routes conflict with the resources because #index allows POST
95 # Following two routes conflict with the resources because #index allows POST
109 map.connect '/issues', :controller => 'issues', :action => 'index', :conditions => { :method => :post }
96 map.connect '/issues', :controller => 'issues', :action => 'index', :conditions => { :method => :post }
110 map.connect '/issues/create', :controller => 'issues', :action => 'index', :conditions => { :method => :post }
97 map.connect '/issues/create', :controller => 'issues', :action => 'index', :conditions => { :method => :post }
111
98
112 map.resources :issues, :member => { :edit => :post }, :collection => {} do |issues|
99 map.resources :issues, :member => { :edit => :post }, :collection => {} do |issues|
113 issues.resources :time_entries, :controller => 'timelog'
100 issues.resources :time_entries, :controller => 'timelog'
114 issues.resources :relations, :shallow => true, :controller => 'issue_relations', :only => [:index, :show, :create, :destroy]
101 issues.resources :relations, :shallow => true, :controller => 'issue_relations', :only => [:index, :show, :create, :destroy]
115 end
102 end
116
103
117 map.resources :issues, :path_prefix => '/projects/:project_id', :collection => { :create => :post } do |issues|
104 map.resources :issues, :path_prefix => '/projects/:project_id', :collection => { :create => :post } do |issues|
118 issues.resources :time_entries, :controller => 'timelog'
105 issues.resources :time_entries, :controller => 'timelog'
119 end
106 end
120
107
121 map.connect 'projects/:id/members/new', :controller => 'members', :action => 'new'
108 map.connect 'projects/:id/members/new', :controller => 'members', :action => 'new'
122
109
123 map.with_options :controller => 'users' do |users|
110 map.with_options :controller => 'users' do |users|
124 users.connect 'users/:id/edit/:tab', :action => 'edit', :tab => nil, :conditions => {:method => :get}
111 users.connect 'users/:id/edit/:tab', :action => 'edit', :tab => nil, :conditions => {:method => :get}
125
112
126 users.with_options :conditions => {:method => :post} do |user_actions|
113 users.with_options :conditions => {:method => :post} do |user_actions|
127 user_actions.connect 'users/:id/memberships', :action => 'edit_membership'
114 user_actions.connect 'users/:id/memberships', :action => 'edit_membership'
128 user_actions.connect 'users/:id/memberships/:membership_id', :action => 'edit_membership'
115 user_actions.connect 'users/:id/memberships/:membership_id', :action => 'edit_membership'
129 user_actions.connect 'users/:id/memberships/:membership_id/destroy', :action => 'destroy_membership'
116 user_actions.connect 'users/:id/memberships/:membership_id/destroy', :action => 'destroy_membership'
130 end
117 end
131 end
118 end
132
119
133 map.resources :users, :member => {
120 map.resources :users, :member => {
134 :edit_membership => :post,
121 :edit_membership => :post,
135 :destroy_membership => :post
122 :destroy_membership => :post
136 }
123 }
137
124
138 # For nice "roadmap" in the url for the index action
125 # For nice "roadmap" in the url for the index action
139 map.connect 'projects/:project_id/roadmap', :controller => 'versions', :action => 'index'
126 map.connect 'projects/:project_id/roadmap', :controller => 'versions', :action => 'index'
140
127
141 map.all_news 'news', :controller => 'news', :action => 'index'
128 map.all_news 'news', :controller => 'news', :action => 'index'
142 map.formatted_all_news 'news.:format', :controller => 'news', :action => 'index'
129 map.formatted_all_news 'news.:format', :controller => 'news', :action => 'index'
143 map.preview_news '/news/preview', :controller => 'previews', :action => 'news'
130 map.preview_news '/news/preview', :controller => 'previews', :action => 'news'
144 map.connect 'news/:id/comments', :controller => 'comments', :action => 'create', :conditions => {:method => :post}
131 map.connect 'news/:id/comments', :controller => 'comments', :action => 'create', :conditions => {:method => :post}
145 map.connect 'news/:id/comments/:comment_id', :controller => 'comments', :action => 'destroy', :conditions => {:method => :delete}
132 map.connect 'news/:id/comments/:comment_id', :controller => 'comments', :action => 'destroy', :conditions => {:method => :delete}
146
133
147 map.resources :projects, :member => {
134 map.resources :projects, :member => {
148 :copy => [:get, :post],
135 :copy => [:get, :post],
149 :settings => :get,
136 :settings => :get,
150 :modules => :post,
137 :modules => :post,
151 :archive => :post,
138 :archive => :post,
152 :unarchive => :post
139 :unarchive => :post
153 } do |project|
140 } do |project|
154 project.resource :project_enumerations, :as => 'enumerations', :only => [:update, :destroy]
141 project.resource :project_enumerations, :as => 'enumerations', :only => [:update, :destroy]
155 project.resources :files, :only => [:index, :new, :create]
142 project.resources :files, :only => [:index, :new, :create]
156 project.resources :versions, :shallow => true, :collection => {:close_completed => :put}, :member => {:status_by => :post}
143 project.resources :versions, :shallow => true, :collection => {:close_completed => :put}, :member => {:status_by => :post}
157 project.resources :news, :shallow => true
144 project.resources :news, :shallow => true
158 project.resources :time_entries, :controller => 'timelog', :path_prefix => 'projects/:project_id'
145 project.resources :time_entries, :controller => 'timelog', :path_prefix => 'projects/:project_id'
159 project.resources :queries, :only => [:new, :create]
146 project.resources :queries, :only => [:new, :create]
160 project.resources :issue_categories, :shallow => true
147 project.resources :issue_categories, :shallow => true
148 project.resources :documents, :shallow => true, :member => {:add_attachment => :post}
161
149
162 project.wiki_start_page 'wiki', :controller => 'wiki', :action => 'show', :conditions => {:method => :get}
150 project.wiki_start_page 'wiki', :controller => 'wiki', :action => 'show', :conditions => {:method => :get}
163 project.wiki_index 'wiki/index', :controller => 'wiki', :action => 'index', :conditions => {:method => :get}
151 project.wiki_index 'wiki/index', :controller => 'wiki', :action => 'index', :conditions => {:method => :get}
164 project.wiki_diff 'wiki/:id/diff/:version', :controller => 'wiki', :action => 'diff', :version => nil
152 project.wiki_diff 'wiki/:id/diff/:version', :controller => 'wiki', :action => 'diff', :version => nil
165 project.wiki_diff 'wiki/:id/diff/:version/vs/:version_from', :controller => 'wiki', :action => 'diff'
153 project.wiki_diff 'wiki/:id/diff/:version/vs/:version_from', :controller => 'wiki', :action => 'diff'
166 project.wiki_annotate 'wiki/:id/annotate/:version', :controller => 'wiki', :action => 'annotate'
154 project.wiki_annotate 'wiki/:id/annotate/:version', :controller => 'wiki', :action => 'annotate'
167 project.resources :wiki, :except => [:new, :create], :member => {
155 project.resources :wiki, :except => [:new, :create], :member => {
168 :rename => [:get, :post],
156 :rename => [:get, :post],
169 :history => :get,
157 :history => :get,
170 :preview => :any,
158 :preview => :any,
171 :protect => :post,
159 :protect => :post,
172 :add_attachment => :post
160 :add_attachment => :post
173 }, :collection => {
161 }, :collection => {
174 :export => :get,
162 :export => :get,
175 :date_index => :get
163 :date_index => :get
176 }
164 }
177
165
178 end
166 end
179
167
180 # Destroy uses a get request to prompt the user before the actual DELETE request
168 # Destroy uses a get request to prompt the user before the actual DELETE request
181 map.project_destroy_confirm 'projects/:id/destroy', :controller => 'projects', :action => 'destroy', :conditions => {:method => :get}
169 map.project_destroy_confirm 'projects/:id/destroy', :controller => 'projects', :action => 'destroy', :conditions => {:method => :get}
182
170
183 # TODO: port to be part of the resources route(s)
171 # TODO: port to be part of the resources route(s)
184 map.with_options :controller => 'projects' do |project_mapper|
172 map.with_options :controller => 'projects' do |project_mapper|
185 project_mapper.with_options :conditions => {:method => :get} do |project_views|
173 project_mapper.with_options :conditions => {:method => :get} do |project_views|
186 project_views.connect 'projects/:id/settings/:tab', :controller => 'projects', :action => 'settings'
174 project_views.connect 'projects/:id/settings/:tab', :controller => 'projects', :action => 'settings'
187 project_views.connect 'projects/:project_id/issues/:copy_from/copy', :controller => 'issues', :action => 'new'
175 project_views.connect 'projects/:project_id/issues/:copy_from/copy', :controller => 'issues', :action => 'new'
188 end
176 end
189 end
177 end
190
178
191 map.with_options :controller => 'activities', :action => 'index', :conditions => {:method => :get} do |activity|
179 map.with_options :controller => 'activities', :action => 'index', :conditions => {:method => :get} do |activity|
192 activity.connect 'projects/:id/activity'
180 activity.connect 'projects/:id/activity'
193 activity.connect 'projects/:id/activity.:format'
181 activity.connect 'projects/:id/activity.:format'
194 activity.connect 'activity', :id => nil
182 activity.connect 'activity', :id => nil
195 activity.connect 'activity.:format', :id => nil
183 activity.connect 'activity.:format', :id => nil
196 end
184 end
197
185
198 map.with_options :controller => 'repositories' do |repositories|
186 map.with_options :controller => 'repositories' do |repositories|
199 repositories.with_options :conditions => {:method => :get} do |repository_views|
187 repositories.with_options :conditions => {:method => :get} do |repository_views|
200 repository_views.connect 'projects/:id/repository', :action => 'show'
188 repository_views.connect 'projects/:id/repository', :action => 'show'
201 repository_views.connect 'projects/:id/repository/edit', :action => 'edit'
189 repository_views.connect 'projects/:id/repository/edit', :action => 'edit'
202 repository_views.connect 'projects/:id/repository/statistics', :action => 'stats'
190 repository_views.connect 'projects/:id/repository/statistics', :action => 'stats'
203 repository_views.connect 'projects/:id/repository/revisions', :action => 'revisions'
191 repository_views.connect 'projects/:id/repository/revisions', :action => 'revisions'
204 repository_views.connect 'projects/:id/repository/revisions.:format', :action => 'revisions'
192 repository_views.connect 'projects/:id/repository/revisions.:format', :action => 'revisions'
205 repository_views.connect 'projects/:id/repository/revisions/:rev', :action => 'revision'
193 repository_views.connect 'projects/:id/repository/revisions/:rev', :action => 'revision'
206 repository_views.connect 'projects/:id/repository/revisions/:rev/diff', :action => 'diff'
194 repository_views.connect 'projects/:id/repository/revisions/:rev/diff', :action => 'diff'
207 repository_views.connect 'projects/:id/repository/revisions/:rev/diff.:format', :action => 'diff'
195 repository_views.connect 'projects/:id/repository/revisions/:rev/diff.:format', :action => 'diff'
208 repository_views.connect 'projects/:id/repository/revisions/:rev/raw/*path', :action => 'entry', :format => 'raw', :requirements => { :rev => /[a-z0-9\.\-_]+/ }
196 repository_views.connect 'projects/:id/repository/revisions/:rev/raw/*path', :action => 'entry', :format => 'raw', :requirements => { :rev => /[a-z0-9\.\-_]+/ }
209 repository_views.connect 'projects/:id/repository/revisions/:rev/:action/*path', :requirements => { :rev => /[a-z0-9\.\-_]+/ }
197 repository_views.connect 'projects/:id/repository/revisions/:rev/:action/*path', :requirements => { :rev => /[a-z0-9\.\-_]+/ }
210 repository_views.connect 'projects/:id/repository/raw/*path', :action => 'entry', :format => 'raw'
198 repository_views.connect 'projects/:id/repository/raw/*path', :action => 'entry', :format => 'raw'
211 # TODO: why the following route is required?
199 # TODO: why the following route is required?
212 repository_views.connect 'projects/:id/repository/entry/*path', :action => 'entry'
200 repository_views.connect 'projects/:id/repository/entry/*path', :action => 'entry'
213 repository_views.connect 'projects/:id/repository/:action/*path'
201 repository_views.connect 'projects/:id/repository/:action/*path'
214 end
202 end
215
203
216 repositories.connect 'projects/:id/repository/:action', :conditions => {:method => :post}
204 repositories.connect 'projects/:id/repository/:action', :conditions => {:method => :post}
217 end
205 end
218
206
219 map.resources :attachments, :only => [:show, :destroy]
207 map.resources :attachments, :only => [:show, :destroy]
220 # additional routes for having the file name at the end of url
208 # additional routes for having the file name at the end of url
221 map.connect 'attachments/:id/:filename', :controller => 'attachments', :action => 'show', :id => /\d+/, :filename => /.*/
209 map.connect 'attachments/:id/:filename', :controller => 'attachments', :action => 'show', :id => /\d+/, :filename => /.*/
222 map.connect 'attachments/download/:id/:filename', :controller => 'attachments', :action => 'download', :id => /\d+/, :filename => /.*/
210 map.connect 'attachments/download/:id/:filename', :controller => 'attachments', :action => 'download', :id => /\d+/, :filename => /.*/
223
211
224 map.resources :groups, :member => {:autocomplete_for_user => :get}
212 map.resources :groups, :member => {:autocomplete_for_user => :get}
225 map.group_users 'groups/:id/users', :controller => 'groups', :action => 'add_users', :id => /\d+/, :conditions => {:method => :post}
213 map.group_users 'groups/:id/users', :controller => 'groups', :action => 'add_users', :id => /\d+/, :conditions => {:method => :post}
226 map.group_user 'groups/:id/users/:user_id', :controller => 'groups', :action => 'remove_user', :id => /\d+/, :conditions => {:method => :delete}
214 map.group_user 'groups/:id/users/:user_id', :controller => 'groups', :action => 'remove_user', :id => /\d+/, :conditions => {:method => :delete}
227
215
228 map.resources :trackers, :except => :show
216 map.resources :trackers, :except => :show
229 map.resources :issue_statuses, :except => :show, :collection => {:update_issue_done_ratio => :post}
217 map.resources :issue_statuses, :except => :show, :collection => {:update_issue_done_ratio => :post}
230
218
231 #left old routes at the bottom for backwards compat
219 #left old routes at the bottom for backwards compat
232 map.connect 'projects/:project_id/issues/:action', :controller => 'issues'
220 map.connect 'projects/:project_id/issues/:action', :controller => 'issues'
233 map.connect 'projects/:project_id/documents/:action', :controller => 'documents'
234 map.connect 'projects/:project_id/boards/:action/:id', :controller => 'boards'
221 map.connect 'projects/:project_id/boards/:action/:id', :controller => 'boards'
235 map.connect 'boards/:board_id/topics/:action/:id', :controller => 'messages'
222 map.connect 'boards/:board_id/topics/:action/:id', :controller => 'messages'
236 map.connect 'wiki/:id/:page/:action', :page => nil, :controller => 'wiki'
223 map.connect 'wiki/:id/:page/:action', :page => nil, :controller => 'wiki'
237 map.connect 'projects/:project_id/news/:action', :controller => 'news'
224 map.connect 'projects/:project_id/news/:action', :controller => 'news'
238 map.connect 'projects/:project_id/timelog/:action/:id', :controller => 'timelog', :project_id => /.+/
225 map.connect 'projects/:project_id/timelog/:action/:id', :controller => 'timelog', :project_id => /.+/
239 map.with_options :controller => 'repositories' do |omap|
226 map.with_options :controller => 'repositories' do |omap|
240 omap.repositories_show 'repositories/browse/:id/*path', :action => 'browse'
227 omap.repositories_show 'repositories/browse/:id/*path', :action => 'browse'
241 omap.repositories_changes 'repositories/changes/:id/*path', :action => 'changes'
228 omap.repositories_changes 'repositories/changes/:id/*path', :action => 'changes'
242 omap.repositories_diff 'repositories/diff/:id/*path', :action => 'diff'
229 omap.repositories_diff 'repositories/diff/:id/*path', :action => 'diff'
243 omap.repositories_entry 'repositories/entry/:id/*path', :action => 'entry'
230 omap.repositories_entry 'repositories/entry/:id/*path', :action => 'entry'
244 omap.repositories_entry 'repositories/annotate/:id/*path', :action => 'annotate'
231 omap.repositories_entry 'repositories/annotate/:id/*path', :action => 'annotate'
245 omap.connect 'repositories/revision/:id/:rev', :action => 'revision'
232 omap.connect 'repositories/revision/:id/:rev', :action => 'revision'
246 end
233 end
247
234
248 map.with_options :controller => 'sys' do |sys|
235 map.with_options :controller => 'sys' do |sys|
249 sys.connect 'sys/projects.:format', :action => 'projects', :conditions => {:method => :get}
236 sys.connect 'sys/projects.:format', :action => 'projects', :conditions => {:method => :get}
250 sys.connect 'sys/projects/:id/repository.:format', :action => 'create_project_repository', :conditions => {:method => :post}
237 sys.connect 'sys/projects/:id/repository.:format', :action => 'create_project_repository', :conditions => {:method => :post}
251 end
238 end
252
239
253 # Install the default route as the lowest priority.
240 # Install the default route as the lowest priority.
254 map.connect ':controller/:action/:id'
241 map.connect ':controller/:action/:id'
255 map.connect 'robots.txt', :controller => 'welcome', :action => 'robots'
242 map.connect 'robots.txt', :controller => 'welcome', :action => 'robots'
256 # Used for OpenID
243 # Used for OpenID
257 map.root :controller => 'account', :action => 'login'
244 map.root :controller => 'account', :action => 'login'
258 end
245 end
@@ -1,237 +1,237
1 require 'redmine/access_control'
1 require 'redmine/access_control'
2 require 'redmine/menu_manager'
2 require 'redmine/menu_manager'
3 require 'redmine/activity'
3 require 'redmine/activity'
4 require 'redmine/search'
4 require 'redmine/search'
5 require 'redmine/custom_field_format'
5 require 'redmine/custom_field_format'
6 require 'redmine/mime_type'
6 require 'redmine/mime_type'
7 require 'redmine/core_ext'
7 require 'redmine/core_ext'
8 require 'redmine/themes'
8 require 'redmine/themes'
9 require 'redmine/hook'
9 require 'redmine/hook'
10 require 'redmine/plugin'
10 require 'redmine/plugin'
11 require 'redmine/notifiable'
11 require 'redmine/notifiable'
12 require 'redmine/wiki_formatting'
12 require 'redmine/wiki_formatting'
13 require 'redmine/scm/base'
13 require 'redmine/scm/base'
14
14
15 begin
15 begin
16 require_library_or_gem 'RMagick' unless Object.const_defined?(:Magick)
16 require_library_or_gem 'RMagick' unless Object.const_defined?(:Magick)
17 rescue LoadError
17 rescue LoadError
18 # RMagick is not available
18 # RMagick is not available
19 end
19 end
20
20
21 if RUBY_VERSION < '1.9'
21 if RUBY_VERSION < '1.9'
22 require 'faster_csv'
22 require 'faster_csv'
23 else
23 else
24 require 'csv'
24 require 'csv'
25 FCSV = CSV
25 FCSV = CSV
26 end
26 end
27
27
28 Redmine::Scm::Base.add "Subversion"
28 Redmine::Scm::Base.add "Subversion"
29 Redmine::Scm::Base.add "Darcs"
29 Redmine::Scm::Base.add "Darcs"
30 Redmine::Scm::Base.add "Mercurial"
30 Redmine::Scm::Base.add "Mercurial"
31 Redmine::Scm::Base.add "Cvs"
31 Redmine::Scm::Base.add "Cvs"
32 Redmine::Scm::Base.add "Bazaar"
32 Redmine::Scm::Base.add "Bazaar"
33 Redmine::Scm::Base.add "Git"
33 Redmine::Scm::Base.add "Git"
34 Redmine::Scm::Base.add "Filesystem"
34 Redmine::Scm::Base.add "Filesystem"
35
35
36 Redmine::CustomFieldFormat.map do |fields|
36 Redmine::CustomFieldFormat.map do |fields|
37 fields.register Redmine::CustomFieldFormat.new('string', :label => :label_string, :order => 1)
37 fields.register Redmine::CustomFieldFormat.new('string', :label => :label_string, :order => 1)
38 fields.register Redmine::CustomFieldFormat.new('text', :label => :label_text, :order => 2)
38 fields.register Redmine::CustomFieldFormat.new('text', :label => :label_text, :order => 2)
39 fields.register Redmine::CustomFieldFormat.new('int', :label => :label_integer, :order => 3)
39 fields.register Redmine::CustomFieldFormat.new('int', :label => :label_integer, :order => 3)
40 fields.register Redmine::CustomFieldFormat.new('float', :label => :label_float, :order => 4)
40 fields.register Redmine::CustomFieldFormat.new('float', :label => :label_float, :order => 4)
41 fields.register Redmine::CustomFieldFormat.new('list', :label => :label_list, :order => 5)
41 fields.register Redmine::CustomFieldFormat.new('list', :label => :label_list, :order => 5)
42 fields.register Redmine::CustomFieldFormat.new('date', :label => :label_date, :order => 6)
42 fields.register Redmine::CustomFieldFormat.new('date', :label => :label_date, :order => 6)
43 fields.register Redmine::CustomFieldFormat.new('bool', :label => :label_boolean, :order => 7)
43 fields.register Redmine::CustomFieldFormat.new('bool', :label => :label_boolean, :order => 7)
44 fields.register Redmine::CustomFieldFormat.new('user', :label => :label_user, :only => %w(Issue TimeEntry Version Project), :edit_as => 'list', :order => 8)
44 fields.register Redmine::CustomFieldFormat.new('user', :label => :label_user, :only => %w(Issue TimeEntry Version Project), :edit_as => 'list', :order => 8)
45 fields.register Redmine::CustomFieldFormat.new('version', :label => :label_version, :only => %w(Issue TimeEntry Version Project), :edit_as => 'list', :order => 9)
45 fields.register Redmine::CustomFieldFormat.new('version', :label => :label_version, :only => %w(Issue TimeEntry Version Project), :edit_as => 'list', :order => 9)
46 end
46 end
47
47
48 # Permissions
48 # Permissions
49 Redmine::AccessControl.map do |map|
49 Redmine::AccessControl.map do |map|
50 map.permission :view_project, {:projects => [:show], :activities => [:index]}, :public => true
50 map.permission :view_project, {:projects => [:show], :activities => [:index]}, :public => true
51 map.permission :search_project, {:search => :index}, :public => true
51 map.permission :search_project, {:search => :index}, :public => true
52 map.permission :add_project, {:projects => [:new, :create]}, :require => :loggedin
52 map.permission :add_project, {:projects => [:new, :create]}, :require => :loggedin
53 map.permission :edit_project, {:projects => [:settings, :edit, :update]}, :require => :member
53 map.permission :edit_project, {:projects => [:settings, :edit, :update]}, :require => :member
54 map.permission :select_project_modules, {:projects => :modules}, :require => :member
54 map.permission :select_project_modules, {:projects => :modules}, :require => :member
55 map.permission :manage_members, {:projects => :settings, :members => [:new, :edit, :destroy, :autocomplete_for_member]}, :require => :member
55 map.permission :manage_members, {:projects => :settings, :members => [:new, :edit, :destroy, :autocomplete_for_member]}, :require => :member
56 map.permission :manage_versions, {:projects => :settings, :versions => [:new, :create, :edit, :update, :close_completed, :destroy]}, :require => :member
56 map.permission :manage_versions, {:projects => :settings, :versions => [:new, :create, :edit, :update, :close_completed, :destroy]}, :require => :member
57 map.permission :add_subprojects, {:projects => [:new, :create]}, :require => :member
57 map.permission :add_subprojects, {:projects => [:new, :create]}, :require => :member
58
58
59 map.project_module :issue_tracking do |map|
59 map.project_module :issue_tracking do |map|
60 # Issue categories
60 # Issue categories
61 map.permission :manage_categories, {:projects => :settings, :issue_categories => [:index, :show, :new, :create, :edit, :update, :destroy]}, :require => :member
61 map.permission :manage_categories, {:projects => :settings, :issue_categories => [:index, :show, :new, :create, :edit, :update, :destroy]}, :require => :member
62 # Issues
62 # Issues
63 map.permission :view_issues, {:issues => [:index, :show],
63 map.permission :view_issues, {:issues => [:index, :show],
64 :auto_complete => [:issues],
64 :auto_complete => [:issues],
65 :context_menus => [:issues],
65 :context_menus => [:issues],
66 :versions => [:index, :show, :status_by],
66 :versions => [:index, :show, :status_by],
67 :journals => [:index, :diff],
67 :journals => [:index, :diff],
68 :queries => :index,
68 :queries => :index,
69 :reports => [:issue_report, :issue_report_details]}
69 :reports => [:issue_report, :issue_report_details]}
70 map.permission :add_issues, {:issues => [:new, :create, :update_form]}
70 map.permission :add_issues, {:issues => [:new, :create, :update_form]}
71 map.permission :edit_issues, {:issues => [:edit, :update, :bulk_edit, :bulk_update, :update_form], :journals => [:new]}
71 map.permission :edit_issues, {:issues => [:edit, :update, :bulk_edit, :bulk_update, :update_form], :journals => [:new]}
72 map.permission :manage_issue_relations, {:issue_relations => [:index, :show, :create, :destroy]}
72 map.permission :manage_issue_relations, {:issue_relations => [:index, :show, :create, :destroy]}
73 map.permission :manage_subtasks, {}
73 map.permission :manage_subtasks, {}
74 map.permission :set_issues_private, {}
74 map.permission :set_issues_private, {}
75 map.permission :set_own_issues_private, {}, :require => :loggedin
75 map.permission :set_own_issues_private, {}, :require => :loggedin
76 map.permission :add_issue_notes, {:issues => [:edit, :update], :journals => [:new]}
76 map.permission :add_issue_notes, {:issues => [:edit, :update], :journals => [:new]}
77 map.permission :edit_issue_notes, {:journals => :edit}, :require => :loggedin
77 map.permission :edit_issue_notes, {:journals => :edit}, :require => :loggedin
78 map.permission :edit_own_issue_notes, {:journals => :edit}, :require => :loggedin
78 map.permission :edit_own_issue_notes, {:journals => :edit}, :require => :loggedin
79 map.permission :move_issues, {:issue_moves => [:new, :create]}, :require => :loggedin
79 map.permission :move_issues, {:issue_moves => [:new, :create]}, :require => :loggedin
80 map.permission :delete_issues, {:issues => :destroy}, :require => :member
80 map.permission :delete_issues, {:issues => :destroy}, :require => :member
81 # Queries
81 # Queries
82 map.permission :manage_public_queries, {:queries => [:new, :create, :edit, :update, :destroy]}, :require => :member
82 map.permission :manage_public_queries, {:queries => [:new, :create, :edit, :update, :destroy]}, :require => :member
83 map.permission :save_queries, {:queries => [:new, :create, :edit, :update, :destroy]}, :require => :loggedin
83 map.permission :save_queries, {:queries => [:new, :create, :edit, :update, :destroy]}, :require => :loggedin
84 # Watchers
84 # Watchers
85 map.permission :view_issue_watchers, {}
85 map.permission :view_issue_watchers, {}
86 map.permission :add_issue_watchers, {:watchers => :new}
86 map.permission :add_issue_watchers, {:watchers => :new}
87 map.permission :delete_issue_watchers, {:watchers => :destroy}
87 map.permission :delete_issue_watchers, {:watchers => :destroy}
88 end
88 end
89
89
90 map.project_module :time_tracking do |map|
90 map.project_module :time_tracking do |map|
91 map.permission :log_time, {:timelog => [:new, :create]}, :require => :loggedin
91 map.permission :log_time, {:timelog => [:new, :create]}, :require => :loggedin
92 map.permission :view_time_entries, :timelog => [:index, :show], :time_entry_reports => [:report]
92 map.permission :view_time_entries, :timelog => [:index, :show], :time_entry_reports => [:report]
93 map.permission :edit_time_entries, {:timelog => [:edit, :update, :destroy, :bulk_edit, :bulk_update]}, :require => :member
93 map.permission :edit_time_entries, {:timelog => [:edit, :update, :destroy, :bulk_edit, :bulk_update]}, :require => :member
94 map.permission :edit_own_time_entries, {:timelog => [:edit, :update, :destroy,:bulk_edit, :bulk_update]}, :require => :loggedin
94 map.permission :edit_own_time_entries, {:timelog => [:edit, :update, :destroy,:bulk_edit, :bulk_update]}, :require => :loggedin
95 map.permission :manage_project_activities, {:project_enumerations => [:update, :destroy]}, :require => :member
95 map.permission :manage_project_activities, {:project_enumerations => [:update, :destroy]}, :require => :member
96 end
96 end
97
97
98 map.project_module :news do |map|
98 map.project_module :news do |map|
99 map.permission :manage_news, {:news => [:new, :create, :edit, :update, :destroy], :comments => [:destroy]}, :require => :member
99 map.permission :manage_news, {:news => [:new, :create, :edit, :update, :destroy], :comments => [:destroy]}, :require => :member
100 map.permission :view_news, {:news => [:index, :show]}, :public => true
100 map.permission :view_news, {:news => [:index, :show]}, :public => true
101 map.permission :comment_news, {:comments => :create}
101 map.permission :comment_news, {:comments => :create}
102 end
102 end
103
103
104 map.project_module :documents do |map|
104 map.project_module :documents do |map|
105 map.permission :manage_documents, {:documents => [:new, :edit, :destroy, :add_attachment]}, :require => :loggedin
105 map.permission :manage_documents, {:documents => [:new, :create, :edit, :update, :destroy, :add_attachment]}, :require => :loggedin
106 map.permission :view_documents, :documents => [:index, :show, :download]
106 map.permission :view_documents, :documents => [:index, :show, :download]
107 end
107 end
108
108
109 map.project_module :files do |map|
109 map.project_module :files do |map|
110 map.permission :manage_files, {:files => [:new, :create]}, :require => :loggedin
110 map.permission :manage_files, {:files => [:new, :create]}, :require => :loggedin
111 map.permission :view_files, :files => :index, :versions => :download
111 map.permission :view_files, :files => :index, :versions => :download
112 end
112 end
113
113
114 map.project_module :wiki do |map|
114 map.project_module :wiki do |map|
115 map.permission :manage_wiki, {:wikis => [:edit, :destroy]}, :require => :member
115 map.permission :manage_wiki, {:wikis => [:edit, :destroy]}, :require => :member
116 map.permission :rename_wiki_pages, {:wiki => :rename}, :require => :member
116 map.permission :rename_wiki_pages, {:wiki => :rename}, :require => :member
117 map.permission :delete_wiki_pages, {:wiki => :destroy}, :require => :member
117 map.permission :delete_wiki_pages, {:wiki => :destroy}, :require => :member
118 map.permission :view_wiki_pages, :wiki => [:index, :show, :special, :date_index]
118 map.permission :view_wiki_pages, :wiki => [:index, :show, :special, :date_index]
119 map.permission :export_wiki_pages, :wiki => [:export]
119 map.permission :export_wiki_pages, :wiki => [:export]
120 map.permission :view_wiki_edits, :wiki => [:history, :diff, :annotate]
120 map.permission :view_wiki_edits, :wiki => [:history, :diff, :annotate]
121 map.permission :edit_wiki_pages, :wiki => [:edit, :update, :preview, :add_attachment]
121 map.permission :edit_wiki_pages, :wiki => [:edit, :update, :preview, :add_attachment]
122 map.permission :delete_wiki_pages_attachments, {}
122 map.permission :delete_wiki_pages_attachments, {}
123 map.permission :protect_wiki_pages, {:wiki => :protect}, :require => :member
123 map.permission :protect_wiki_pages, {:wiki => :protect}, :require => :member
124 end
124 end
125
125
126 map.project_module :repository do |map|
126 map.project_module :repository do |map|
127 map.permission :manage_repository, {:repositories => [:edit, :committers, :destroy]}, :require => :member
127 map.permission :manage_repository, {:repositories => [:edit, :committers, :destroy]}, :require => :member
128 map.permission :browse_repository, :repositories => [:show, :browse, :entry, :annotate, :changes, :diff, :stats, :graph]
128 map.permission :browse_repository, :repositories => [:show, :browse, :entry, :annotate, :changes, :diff, :stats, :graph]
129 map.permission :view_changesets, :repositories => [:show, :revisions, :revision]
129 map.permission :view_changesets, :repositories => [:show, :revisions, :revision]
130 map.permission :commit_access, {}
130 map.permission :commit_access, {}
131 end
131 end
132
132
133 map.project_module :boards do |map|
133 map.project_module :boards do |map|
134 map.permission :manage_boards, {:boards => [:new, :edit, :destroy]}, :require => :member
134 map.permission :manage_boards, {:boards => [:new, :edit, :destroy]}, :require => :member
135 map.permission :view_messages, {:boards => [:index, :show], :messages => [:show]}, :public => true
135 map.permission :view_messages, {:boards => [:index, :show], :messages => [:show]}, :public => true
136 map.permission :add_messages, {:messages => [:new, :reply, :quote]}
136 map.permission :add_messages, {:messages => [:new, :reply, :quote]}
137 map.permission :edit_messages, {:messages => :edit}, :require => :member
137 map.permission :edit_messages, {:messages => :edit}, :require => :member
138 map.permission :edit_own_messages, {:messages => :edit}, :require => :loggedin
138 map.permission :edit_own_messages, {:messages => :edit}, :require => :loggedin
139 map.permission :delete_messages, {:messages => :destroy}, :require => :member
139 map.permission :delete_messages, {:messages => :destroy}, :require => :member
140 map.permission :delete_own_messages, {:messages => :destroy}, :require => :loggedin
140 map.permission :delete_own_messages, {:messages => :destroy}, :require => :loggedin
141 end
141 end
142
142
143 map.project_module :calendar do |map|
143 map.project_module :calendar do |map|
144 map.permission :view_calendar, :calendars => [:show, :update]
144 map.permission :view_calendar, :calendars => [:show, :update]
145 end
145 end
146
146
147 map.project_module :gantt do |map|
147 map.project_module :gantt do |map|
148 map.permission :view_gantt, :gantts => [:show, :update]
148 map.permission :view_gantt, :gantts => [:show, :update]
149 end
149 end
150 end
150 end
151
151
152 Redmine::MenuManager.map :top_menu do |menu|
152 Redmine::MenuManager.map :top_menu do |menu|
153 menu.push :home, :home_path
153 menu.push :home, :home_path
154 menu.push :my_page, { :controller => 'my', :action => 'page' }, :if => Proc.new { User.current.logged? }
154 menu.push :my_page, { :controller => 'my', :action => 'page' }, :if => Proc.new { User.current.logged? }
155 menu.push :projects, { :controller => 'projects', :action => 'index' }, :caption => :label_project_plural
155 menu.push :projects, { :controller => 'projects', :action => 'index' }, :caption => :label_project_plural
156 menu.push :administration, { :controller => 'admin', :action => 'index' }, :if => Proc.new { User.current.admin? }, :last => true
156 menu.push :administration, { :controller => 'admin', :action => 'index' }, :if => Proc.new { User.current.admin? }, :last => true
157 menu.push :help, Redmine::Info.help_url, :last => true
157 menu.push :help, Redmine::Info.help_url, :last => true
158 end
158 end
159
159
160 Redmine::MenuManager.map :account_menu do |menu|
160 Redmine::MenuManager.map :account_menu do |menu|
161 menu.push :login, :signin_path, :if => Proc.new { !User.current.logged? }
161 menu.push :login, :signin_path, :if => Proc.new { !User.current.logged? }
162 menu.push :register, { :controller => 'account', :action => 'register' }, :if => Proc.new { !User.current.logged? && Setting.self_registration? }
162 menu.push :register, { :controller => 'account', :action => 'register' }, :if => Proc.new { !User.current.logged? && Setting.self_registration? }
163 menu.push :my_account, { :controller => 'my', :action => 'account' }, :if => Proc.new { User.current.logged? }
163 menu.push :my_account, { :controller => 'my', :action => 'account' }, :if => Proc.new { User.current.logged? }
164 menu.push :logout, :signout_path, :if => Proc.new { User.current.logged? }
164 menu.push :logout, :signout_path, :if => Proc.new { User.current.logged? }
165 end
165 end
166
166
167 Redmine::MenuManager.map :application_menu do |menu|
167 Redmine::MenuManager.map :application_menu do |menu|
168 # Empty
168 # Empty
169 end
169 end
170
170
171 Redmine::MenuManager.map :admin_menu do |menu|
171 Redmine::MenuManager.map :admin_menu do |menu|
172 menu.push :projects, {:controller => 'admin', :action => 'projects'}, :caption => :label_project_plural
172 menu.push :projects, {:controller => 'admin', :action => 'projects'}, :caption => :label_project_plural
173 menu.push :users, {:controller => 'users'}, :caption => :label_user_plural
173 menu.push :users, {:controller => 'users'}, :caption => :label_user_plural
174 menu.push :groups, {:controller => 'groups'}, :caption => :label_group_plural
174 menu.push :groups, {:controller => 'groups'}, :caption => :label_group_plural
175 menu.push :roles, {:controller => 'roles'}, :caption => :label_role_and_permissions
175 menu.push :roles, {:controller => 'roles'}, :caption => :label_role_and_permissions
176 menu.push :trackers, {:controller => 'trackers'}, :caption => :label_tracker_plural
176 menu.push :trackers, {:controller => 'trackers'}, :caption => :label_tracker_plural
177 menu.push :issue_statuses, {:controller => 'issue_statuses'}, :caption => :label_issue_status_plural,
177 menu.push :issue_statuses, {:controller => 'issue_statuses'}, :caption => :label_issue_status_plural,
178 :html => {:class => 'issue_statuses'}
178 :html => {:class => 'issue_statuses'}
179 menu.push :workflows, {:controller => 'workflows', :action => 'edit'}, :caption => :label_workflow
179 menu.push :workflows, {:controller => 'workflows', :action => 'edit'}, :caption => :label_workflow
180 menu.push :custom_fields, {:controller => 'custom_fields'}, :caption => :label_custom_field_plural,
180 menu.push :custom_fields, {:controller => 'custom_fields'}, :caption => :label_custom_field_plural,
181 :html => {:class => 'custom_fields'}
181 :html => {:class => 'custom_fields'}
182 menu.push :enumerations, {:controller => 'enumerations'}
182 menu.push :enumerations, {:controller => 'enumerations'}
183 menu.push :settings, {:controller => 'settings'}
183 menu.push :settings, {:controller => 'settings'}
184 menu.push :ldap_authentication, {:controller => 'ldap_auth_sources', :action => 'index'},
184 menu.push :ldap_authentication, {:controller => 'ldap_auth_sources', :action => 'index'},
185 :html => {:class => 'server_authentication'}
185 :html => {:class => 'server_authentication'}
186 menu.push :plugins, {:controller => 'admin', :action => 'plugins'}, :last => true
186 menu.push :plugins, {:controller => 'admin', :action => 'plugins'}, :last => true
187 menu.push :info, {:controller => 'admin', :action => 'info'}, :caption => :label_information_plural, :last => true
187 menu.push :info, {:controller => 'admin', :action => 'info'}, :caption => :label_information_plural, :last => true
188 end
188 end
189
189
190 Redmine::MenuManager.map :project_menu do |menu|
190 Redmine::MenuManager.map :project_menu do |menu|
191 menu.push :overview, { :controller => 'projects', :action => 'show' }
191 menu.push :overview, { :controller => 'projects', :action => 'show' }
192 menu.push :activity, { :controller => 'activities', :action => 'index' }
192 menu.push :activity, { :controller => 'activities', :action => 'index' }
193 menu.push :roadmap, { :controller => 'versions', :action => 'index' }, :param => :project_id,
193 menu.push :roadmap, { :controller => 'versions', :action => 'index' }, :param => :project_id,
194 :if => Proc.new { |p| p.shared_versions.any? }
194 :if => Proc.new { |p| p.shared_versions.any? }
195 menu.push :issues, { :controller => 'issues', :action => 'index' }, :param => :project_id, :caption => :label_issue_plural
195 menu.push :issues, { :controller => 'issues', :action => 'index' }, :param => :project_id, :caption => :label_issue_plural
196 menu.push :new_issue, { :controller => 'issues', :action => 'new' }, :param => :project_id, :caption => :label_issue_new,
196 menu.push :new_issue, { :controller => 'issues', :action => 'new' }, :param => :project_id, :caption => :label_issue_new,
197 :html => { :accesskey => Redmine::AccessKeys.key_for(:new_issue) }
197 :html => { :accesskey => Redmine::AccessKeys.key_for(:new_issue) }
198 menu.push :gantt, { :controller => 'gantts', :action => 'show' }, :param => :project_id, :caption => :label_gantt
198 menu.push :gantt, { :controller => 'gantts', :action => 'show' }, :param => :project_id, :caption => :label_gantt
199 menu.push :calendar, { :controller => 'calendars', :action => 'show' }, :param => :project_id, :caption => :label_calendar
199 menu.push :calendar, { :controller => 'calendars', :action => 'show' }, :param => :project_id, :caption => :label_calendar
200 menu.push :news, { :controller => 'news', :action => 'index' }, :param => :project_id, :caption => :label_news_plural
200 menu.push :news, { :controller => 'news', :action => 'index' }, :param => :project_id, :caption => :label_news_plural
201 menu.push :documents, { :controller => 'documents', :action => 'index' }, :param => :project_id, :caption => :label_document_plural
201 menu.push :documents, { :controller => 'documents', :action => 'index' }, :param => :project_id, :caption => :label_document_plural
202 menu.push :wiki, { :controller => 'wiki', :action => 'show', :id => nil }, :param => :project_id,
202 menu.push :wiki, { :controller => 'wiki', :action => 'show', :id => nil }, :param => :project_id,
203 :if => Proc.new { |p| p.wiki && !p.wiki.new_record? }
203 :if => Proc.new { |p| p.wiki && !p.wiki.new_record? }
204 menu.push :boards, { :controller => 'boards', :action => 'index', :id => nil }, :param => :project_id,
204 menu.push :boards, { :controller => 'boards', :action => 'index', :id => nil }, :param => :project_id,
205 :if => Proc.new { |p| p.boards.any? }, :caption => :label_board_plural
205 :if => Proc.new { |p| p.boards.any? }, :caption => :label_board_plural
206 menu.push :files, { :controller => 'files', :action => 'index' }, :caption => :label_file_plural, :param => :project_id
206 menu.push :files, { :controller => 'files', :action => 'index' }, :caption => :label_file_plural, :param => :project_id
207 menu.push :repository, { :controller => 'repositories', :action => 'show' },
207 menu.push :repository, { :controller => 'repositories', :action => 'show' },
208 :if => Proc.new { |p| p.repository && !p.repository.new_record? }
208 :if => Proc.new { |p| p.repository && !p.repository.new_record? }
209 menu.push :settings, { :controller => 'projects', :action => 'settings' }, :last => true
209 menu.push :settings, { :controller => 'projects', :action => 'settings' }, :last => true
210 end
210 end
211
211
212 Redmine::Activity.map do |activity|
212 Redmine::Activity.map do |activity|
213 activity.register :issues, :class_name => %w(Issue Journal)
213 activity.register :issues, :class_name => %w(Issue Journal)
214 activity.register :changesets
214 activity.register :changesets
215 activity.register :news
215 activity.register :news
216 activity.register :documents, :class_name => %w(Document Attachment)
216 activity.register :documents, :class_name => %w(Document Attachment)
217 activity.register :files, :class_name => 'Attachment'
217 activity.register :files, :class_name => 'Attachment'
218 activity.register :wiki_edits, :class_name => 'WikiContent::Version', :default => false
218 activity.register :wiki_edits, :class_name => 'WikiContent::Version', :default => false
219 activity.register :messages, :default => false
219 activity.register :messages, :default => false
220 activity.register :time_entries, :default => false
220 activity.register :time_entries, :default => false
221 end
221 end
222
222
223 Redmine::Search.map do |search|
223 Redmine::Search.map do |search|
224 search.register :issues
224 search.register :issues
225 search.register :news
225 search.register :news
226 search.register :documents
226 search.register :documents
227 search.register :changesets
227 search.register :changesets
228 search.register :wiki_pages
228 search.register :wiki_pages
229 search.register :messages
229 search.register :messages
230 search.register :projects
230 search.register :projects
231 end
231 end
232
232
233 Redmine::WikiFormatting.map do |format|
233 Redmine::WikiFormatting.map do |format|
234 format.register :textile, Redmine::WikiFormatting::Textile::Formatter, Redmine::WikiFormatting::Textile::Helper
234 format.register :textile, Redmine::WikiFormatting::Textile::Formatter, Redmine::WikiFormatting::Textile::Helper
235 end
235 end
236
236
237 ActionView::Template.register_template_handler :rsb, Redmine::Views::ApiTemplateHandler
237 ActionView::Template.register_template_handler :rsb, Redmine::Views::ApiTemplateHandler
@@ -1,144 +1,151
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../test_helper', __FILE__)
18 require File.expand_path('../../test_helper', __FILE__)
19
19
20 class DocumentsControllerTest < ActionController::TestCase
20 class DocumentsControllerTest < ActionController::TestCase
21 fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules, :documents, :enumerations
21 fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules, :documents, :enumerations
22
22
23 def setup
23 def setup
24 User.current = nil
24 User.current = nil
25 end
25 end
26
26
27 def test_index
27 def test_index
28 # Sets a default category
28 # Sets a default category
29 e = Enumeration.find_by_name('Technical documentation')
29 e = Enumeration.find_by_name('Technical documentation')
30 e.update_attributes(:is_default => true)
30 e.update_attributes(:is_default => true)
31
31
32 get :index, :project_id => 'ecookbook'
32 get :index, :project_id => 'ecookbook'
33 assert_response :success
33 assert_response :success
34 assert_template 'index'
34 assert_template 'index'
35 assert_not_nil assigns(:grouped)
35 assert_not_nil assigns(:grouped)
36
36
37 # Default category selected in the new document form
37 # Default category selected in the new document form
38 assert_tag :select, :attributes => {:name => 'document[category_id]'},
38 assert_tag :select, :attributes => {:name => 'document[category_id]'},
39 :child => {:tag => 'option', :attributes => {:selected => 'selected'},
39 :child => {:tag => 'option', :attributes => {:selected => 'selected'},
40 :content => 'Technical documentation'}
40 :content => 'Technical documentation'}
41
41
42 assert ! DocumentCategory.find(16).active?
42 assert ! DocumentCategory.find(16).active?
43 assert_no_tag :option, :attributes => {:value => '16'},
43 assert_no_tag :option, :attributes => {:value => '16'},
44 :parent => {:tag => 'select', :attributes => {:id => 'document_category_id'} }
44 :parent => {:tag => 'select', :attributes => {:id => 'document_category_id'} }
45 end
45 end
46
46
47 def test_index_grouped_by_date
47 def test_index_grouped_by_date
48 get :index, :project_id => 'ecookbook', :sort_by => 'date'
48 get :index, :project_id => 'ecookbook', :sort_by => 'date'
49 assert_response :success
49 assert_response :success
50 assert_tag 'h3', :content => '2007-02-12'
50 assert_tag 'h3', :content => '2007-02-12'
51 end
51 end
52
52
53 def test_index_grouped_by_title
53 def test_index_grouped_by_title
54 get :index, :project_id => 'ecookbook', :sort_by => 'title'
54 get :index, :project_id => 'ecookbook', :sort_by => 'title'
55 assert_response :success
55 assert_response :success
56 assert_tag 'h3', :content => 'T'
56 assert_tag 'h3', :content => 'T'
57 end
57 end
58
58
59 def test_index_grouped_by_author
59 def test_index_grouped_by_author
60 get :index, :project_id => 'ecookbook', :sort_by => 'author'
60 get :index, :project_id => 'ecookbook', :sort_by => 'author'
61 assert_response :success
61 assert_response :success
62 assert_tag 'h3', :content => 'John Smith'
62 assert_tag 'h3', :content => 'John Smith'
63 end
63 end
64
64
65 def test_index_with_long_description
65 def test_index_with_long_description
66 # adds a long description to the first document
66 # adds a long description to the first document
67 doc = documents(:documents_001)
67 doc = documents(:documents_001)
68 doc.update_attributes(:description => <<LOREM)
68 doc.update_attributes(:description => <<LOREM)
69 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut egestas, mi vehicula varius varius, ipsum massa fermentum orci, eget tristique ante sem vel mi. Nulla facilisi. Donec enim libero, luctus ac sagittis sit amet, vehicula sagittis magna. Duis ultrices molestie ante, eget scelerisque sem iaculis vitae. Etiam fermentum mauris vitae metus pharetra condimentum fermentum est pretium. Proin sollicitudin elementum quam quis pharetra. Aenean facilisis nunc quis elit volutpat mollis. Aenean eleifend varius euismod. Ut dolor est, congue eget dapibus eget, elementum eu odio. Integer et lectus neque, nec scelerisque nisi. EndOfLineHere
69 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut egestas, mi vehicula varius varius, ipsum massa fermentum orci, eget tristique ante sem vel mi. Nulla facilisi. Donec enim libero, luctus ac sagittis sit amet, vehicula sagittis magna. Duis ultrices molestie ante, eget scelerisque sem iaculis vitae. Etiam fermentum mauris vitae metus pharetra condimentum fermentum est pretium. Proin sollicitudin elementum quam quis pharetra. Aenean facilisis nunc quis elit volutpat mollis. Aenean eleifend varius euismod. Ut dolor est, congue eget dapibus eget, elementum eu odio. Integer et lectus neque, nec scelerisque nisi. EndOfLineHere
70
70
71 Vestibulum non velit mi. Aliquam scelerisque libero ut nulla fringilla a sollicitudin magna rhoncus. Praesent a nunc lorem, ac porttitor eros. Sed ac diam nec neque interdum adipiscing quis quis justo. Donec arcu nunc, fringilla eu dictum at, venenatis ac sem. Vestibulum quis elit urna, ac mattis sapien. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
71 Vestibulum non velit mi. Aliquam scelerisque libero ut nulla fringilla a sollicitudin magna rhoncus. Praesent a nunc lorem, ac porttitor eros. Sed ac diam nec neque interdum adipiscing quis quis justo. Donec arcu nunc, fringilla eu dictum at, venenatis ac sem. Vestibulum quis elit urna, ac mattis sapien. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
72 LOREM
72 LOREM
73
73
74 get :index, :project_id => 'ecookbook'
74 get :index, :project_id => 'ecookbook'
75 assert_response :success
75 assert_response :success
76 assert_template 'index'
76 assert_template 'index'
77
77
78 # should only truncate on new lines to avoid breaking wiki formatting
78 # should only truncate on new lines to avoid breaking wiki formatting
79 assert_select '.wiki p', :text => (doc.description.split("\n").first + '...')
79 assert_select '.wiki p', :text => (doc.description.split("\n").first + '...')
80 assert_select '.wiki p', :text => Regexp.new(Regexp.escape("EndOfLineHere..."))
80 assert_select '.wiki p', :text => Regexp.new(Regexp.escape("EndOfLineHere..."))
81 end
81 end
82
82
83 def test_show
83 def test_show
84 get :show, :id => 1
84 get :show, :id => 1
85 assert_response :success
85 assert_response :success
86 assert_template 'show'
86 assert_template 'show'
87 end
87 end
88
88
89 def test_new_with_one_attachment
89 def test_new
90 @request.session[:user_id] = 2
91 get :new, :project_id => 1
92 assert_response :success
93 assert_template 'new'
94 end
95
96 def test_create_with_one_attachment
90 ActionMailer::Base.deliveries.clear
97 ActionMailer::Base.deliveries.clear
91 Setting.notified_events << 'document_added'
98 Setting.notified_events << 'document_added'
92 @request.session[:user_id] = 2
99 @request.session[:user_id] = 2
93 set_tmp_attachments_directory
100 set_tmp_attachments_directory
94
101
95 post :new, :project_id => 'ecookbook',
102 post :create, :project_id => 'ecookbook',
96 :document => { :title => 'DocumentsControllerTest#test_post_new',
103 :document => { :title => 'DocumentsControllerTest#test_post_new',
97 :description => 'This is a new document',
104 :description => 'This is a new document',
98 :category_id => 2},
105 :category_id => 2},
99 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
106 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
100
107
101 assert_redirected_to '/projects/ecookbook/documents'
108 assert_redirected_to '/projects/ecookbook/documents'
102
109
103 document = Document.find_by_title('DocumentsControllerTest#test_post_new')
110 document = Document.find_by_title('DocumentsControllerTest#test_post_new')
104 assert_not_nil document
111 assert_not_nil document
105 assert_equal Enumeration.find(2), document.category
112 assert_equal Enumeration.find(2), document.category
106 assert_equal 1, document.attachments.size
113 assert_equal 1, document.attachments.size
107 assert_equal 'testfile.txt', document.attachments.first.filename
114 assert_equal 'testfile.txt', document.attachments.first.filename
108 assert_equal 1, ActionMailer::Base.deliveries.size
115 assert_equal 1, ActionMailer::Base.deliveries.size
109 end
116 end
110
117
111 def test_edit
118 def test_edit
112 @request.session[:user_id] = 2
119 @request.session[:user_id] = 2
113 get :edit, :id => 1
120 get :edit, :id => 1
114 assert_response :success
121 assert_response :success
115 assert_template 'edit'
122 assert_template 'edit'
116 end
123 end
117
124
118 def test_update
125 def test_update
119 @request.session[:user_id] = 2
126 @request.session[:user_id] = 2
120 post :edit, :id => 1, :document => {:title => 'test_update'}
127 put :update, :id => 1, :document => {:title => 'test_update'}
121 assert_redirected_to '/documents/1'
128 assert_redirected_to '/documents/1'
122 document = Document.find(1)
129 document = Document.find(1)
123 assert_equal 'test_update', document.title
130 assert_equal 'test_update', document.title
124 end
131 end
125
132
126 def test_destroy
133 def test_destroy
127 @request.session[:user_id] = 2
134 @request.session[:user_id] = 2
128 assert_difference 'Document.count', -1 do
135 assert_difference 'Document.count', -1 do
129 post :destroy, :id => 1
136 delete :destroy, :id => 1
130 end
137 end
131 assert_redirected_to '/projects/ecookbook/documents'
138 assert_redirected_to '/projects/ecookbook/documents'
132 assert_nil Document.find_by_id(1)
139 assert_nil Document.find_by_id(1)
133 end
140 end
134
141
135 def test_add_attachment
142 def test_add_attachment
136 @request.session[:user_id] = 2
143 @request.session[:user_id] = 2
137 assert_difference 'Attachment.count' do
144 assert_difference 'Attachment.count' do
138 post :add_attachment, :id => 1,
145 post :add_attachment, :id => 1,
139 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
146 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
140 end
147 end
141 attachment = Attachment.first(:order => 'id DESC')
148 attachment = Attachment.first(:order => 'id DESC')
142 assert_equal Document.find(1), attachment.container
149 assert_equal Document.find(1), attachment.container
143 end
150 end
144 end
151 end
General Comments 0
You need to be logged in to leave comments. Login now