##// END OF EJS Templates
Deprecated :confirm => 'Text' option....
Jean-Philippe Lang -
r9754:7b40767428ac
parent child
Show More
@@ -1,1214 +1,1224
1 # encoding: utf-8
1 # encoding: utf-8
2 #
2 #
3 # Redmine - project management software
3 # Redmine - project management software
4 # Copyright (C) 2006-2012 Jean-Philippe Lang
4 # Copyright (C) 2006-2012 Jean-Philippe Lang
5 #
5 #
6 # This program is free software; you can redistribute it and/or
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
9 # of the License, or (at your option) any later version.
10 #
10 #
11 # This program is distributed in the hope that it will be useful,
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
14 # GNU General Public License for more details.
15 #
15 #
16 # You should have received a copy of the GNU General Public License
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
19
20 require 'forwardable'
20 require 'forwardable'
21 require 'cgi'
21 require 'cgi'
22
22
23 module ApplicationHelper
23 module ApplicationHelper
24 include Redmine::WikiFormatting::Macros::Definitions
24 include Redmine::WikiFormatting::Macros::Definitions
25 include Redmine::I18n
25 include Redmine::I18n
26 include GravatarHelper::PublicMethods
26 include GravatarHelper::PublicMethods
27
27
28 extend Forwardable
28 extend Forwardable
29 def_delegators :wiki_helper, :wikitoolbar_for, :heads_for_wiki_formatter
29 def_delegators :wiki_helper, :wikitoolbar_for, :heads_for_wiki_formatter
30
30
31 # Return true if user is authorized for controller/action, otherwise false
31 # Return true if user is authorized for controller/action, otherwise false
32 def authorize_for(controller, action)
32 def authorize_for(controller, action)
33 User.current.allowed_to?({:controller => controller, :action => action}, @project)
33 User.current.allowed_to?({:controller => controller, :action => action}, @project)
34 end
34 end
35
35
36 # Display a link if user is authorized
36 # Display a link if user is authorized
37 #
37 #
38 # @param [String] name Anchor text (passed to link_to)
38 # @param [String] name Anchor text (passed to link_to)
39 # @param [Hash] options Hash params. This will checked by authorize_for to see if the user is authorized
39 # @param [Hash] options Hash params. This will checked by authorize_for to see if the user is authorized
40 # @param [optional, Hash] html_options Options passed to link_to
40 # @param [optional, Hash] html_options Options passed to link_to
41 # @param [optional, Hash] parameters_for_method_reference Extra parameters for link_to
41 # @param [optional, Hash] parameters_for_method_reference Extra parameters for link_to
42 def link_to_if_authorized(name, options = {}, html_options = nil, *parameters_for_method_reference)
42 def link_to_if_authorized(name, options = {}, html_options = nil, *parameters_for_method_reference)
43 link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for(options[:controller] || params[:controller], options[:action])
43 link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for(options[:controller] || params[:controller], options[:action])
44 end
44 end
45
45
46 # Display a link to remote if user is authorized
46 # Display a link to remote if user is authorized
47 def link_to_remote_if_authorized(name, options = {}, html_options = nil)
47 def link_to_remote_if_authorized(name, options = {}, html_options = nil)
48 url = options[:url] || {}
48 url = options[:url] || {}
49 link_to_remote(name, options, html_options) if authorize_for(url[:controller] || params[:controller], url[:action])
49 link_to_remote(name, options, html_options) if authorize_for(url[:controller] || params[:controller], url[:action])
50 end
50 end
51
51
52 # Displays a link to user's account page if active
52 # Displays a link to user's account page if active
53 def link_to_user(user, options={})
53 def link_to_user(user, options={})
54 if user.is_a?(User)
54 if user.is_a?(User)
55 name = h(user.name(options[:format]))
55 name = h(user.name(options[:format]))
56 if user.active?
56 if user.active?
57 link_to name, :controller => 'users', :action => 'show', :id => user
57 link_to name, :controller => 'users', :action => 'show', :id => user
58 else
58 else
59 name
59 name
60 end
60 end
61 else
61 else
62 h(user.to_s)
62 h(user.to_s)
63 end
63 end
64 end
64 end
65
65
66 # Displays a link to +issue+ with its subject.
66 # Displays a link to +issue+ with its subject.
67 # Examples:
67 # Examples:
68 #
68 #
69 # link_to_issue(issue) # => Defect #6: This is the subject
69 # link_to_issue(issue) # => Defect #6: This is the subject
70 # link_to_issue(issue, :truncate => 6) # => Defect #6: This i...
70 # link_to_issue(issue, :truncate => 6) # => Defect #6: This i...
71 # link_to_issue(issue, :subject => false) # => Defect #6
71 # link_to_issue(issue, :subject => false) # => Defect #6
72 # link_to_issue(issue, :project => true) # => Foo - Defect #6
72 # link_to_issue(issue, :project => true) # => Foo - Defect #6
73 #
73 #
74 def link_to_issue(issue, options={})
74 def link_to_issue(issue, options={})
75 title = nil
75 title = nil
76 subject = nil
76 subject = nil
77 if options[:subject] == false
77 if options[:subject] == false
78 title = truncate(issue.subject, :length => 60)
78 title = truncate(issue.subject, :length => 60)
79 else
79 else
80 subject = issue.subject
80 subject = issue.subject
81 if options[:truncate]
81 if options[:truncate]
82 subject = truncate(subject, :length => options[:truncate])
82 subject = truncate(subject, :length => options[:truncate])
83 end
83 end
84 end
84 end
85 s = link_to "#{h(issue.tracker)} ##{issue.id}", {:controller => "issues", :action => "show", :id => issue},
85 s = link_to "#{h(issue.tracker)} ##{issue.id}", {:controller => "issues", :action => "show", :id => issue},
86 :class => issue.css_classes,
86 :class => issue.css_classes,
87 :title => title
87 :title => title
88 s << h(": #{subject}") if subject
88 s << h(": #{subject}") if subject
89 s = h("#{issue.project} - ") + s if options[:project]
89 s = h("#{issue.project} - ") + s if options[:project]
90 s
90 s
91 end
91 end
92
92
93 # Generates a link to an attachment.
93 # Generates a link to an attachment.
94 # Options:
94 # Options:
95 # * :text - Link text (default to attachment filename)
95 # * :text - Link text (default to attachment filename)
96 # * :download - Force download (default: false)
96 # * :download - Force download (default: false)
97 def link_to_attachment(attachment, options={})
97 def link_to_attachment(attachment, options={})
98 text = options.delete(:text) || attachment.filename
98 text = options.delete(:text) || attachment.filename
99 action = options.delete(:download) ? 'download' : 'show'
99 action = options.delete(:download) ? 'download' : 'show'
100 opt_only_path = {}
100 opt_only_path = {}
101 opt_only_path[:only_path] = (options[:only_path] == false ? false : true)
101 opt_only_path[:only_path] = (options[:only_path] == false ? false : true)
102 options.delete(:only_path)
102 options.delete(:only_path)
103 link_to(h(text),
103 link_to(h(text),
104 {:controller => 'attachments', :action => action,
104 {:controller => 'attachments', :action => action,
105 :id => attachment, :filename => attachment.filename}.merge(opt_only_path),
105 :id => attachment, :filename => attachment.filename}.merge(opt_only_path),
106 options)
106 options)
107 end
107 end
108
108
109 # Generates a link to a SCM revision
109 # Generates a link to a SCM revision
110 # Options:
110 # Options:
111 # * :text - Link text (default to the formatted revision)
111 # * :text - Link text (default to the formatted revision)
112 def link_to_revision(revision, repository, options={})
112 def link_to_revision(revision, repository, options={})
113 if repository.is_a?(Project)
113 if repository.is_a?(Project)
114 repository = repository.repository
114 repository = repository.repository
115 end
115 end
116 text = options.delete(:text) || format_revision(revision)
116 text = options.delete(:text) || format_revision(revision)
117 rev = revision.respond_to?(:identifier) ? revision.identifier : revision
117 rev = revision.respond_to?(:identifier) ? revision.identifier : revision
118 link_to(
118 link_to(
119 h(text),
119 h(text),
120 {:controller => 'repositories', :action => 'revision', :id => repository.project, :repository_id => repository.identifier_param, :rev => rev},
120 {:controller => 'repositories', :action => 'revision', :id => repository.project, :repository_id => repository.identifier_param, :rev => rev},
121 :title => l(:label_revision_id, format_revision(revision))
121 :title => l(:label_revision_id, format_revision(revision))
122 )
122 )
123 end
123 end
124
124
125 # Generates a link to a message
125 # Generates a link to a message
126 def link_to_message(message, options={}, html_options = nil)
126 def link_to_message(message, options={}, html_options = nil)
127 link_to(
127 link_to(
128 h(truncate(message.subject, :length => 60)),
128 h(truncate(message.subject, :length => 60)),
129 { :controller => 'messages', :action => 'show',
129 { :controller => 'messages', :action => 'show',
130 :board_id => message.board_id,
130 :board_id => message.board_id,
131 :id => (message.parent_id || message.id),
131 :id => (message.parent_id || message.id),
132 :r => (message.parent_id && message.id),
132 :r => (message.parent_id && message.id),
133 :anchor => (message.parent_id ? "message-#{message.id}" : nil)
133 :anchor => (message.parent_id ? "message-#{message.id}" : nil)
134 }.merge(options),
134 }.merge(options),
135 html_options
135 html_options
136 )
136 )
137 end
137 end
138
138
139 # Generates a link to a project if active
139 # Generates a link to a project if active
140 # Examples:
140 # Examples:
141 #
141 #
142 # link_to_project(project) # => link to the specified project overview
142 # link_to_project(project) # => link to the specified project overview
143 # link_to_project(project, :action=>'settings') # => link to project settings
143 # link_to_project(project, :action=>'settings') # => link to project settings
144 # link_to_project(project, {:only_path => false}, :class => "project") # => 3rd arg adds html options
144 # link_to_project(project, {:only_path => false}, :class => "project") # => 3rd arg adds html options
145 # link_to_project(project, {}, :class => "project") # => html options with default url (project overview)
145 # link_to_project(project, {}, :class => "project") # => html options with default url (project overview)
146 #
146 #
147 def link_to_project(project, options={}, html_options = nil)
147 def link_to_project(project, options={}, html_options = nil)
148 if project.archived?
148 if project.archived?
149 h(project)
149 h(project)
150 else
150 else
151 url = {:controller => 'projects', :action => 'show', :id => project}.merge(options)
151 url = {:controller => 'projects', :action => 'show', :id => project}.merge(options)
152 link_to(h(project), url, html_options)
152 link_to(h(project), url, html_options)
153 end
153 end
154 end
154 end
155
155
156 def thumbnail_tag(attachment)
156 def thumbnail_tag(attachment)
157 link_to image_tag(url_for(:controller => 'attachments', :action => 'thumbnail', :id => attachment)),
157 link_to image_tag(url_for(:controller => 'attachments', :action => 'thumbnail', :id => attachment)),
158 {:controller => 'attachments', :action => 'show', :id => attachment, :filename => attachment.filename},
158 {:controller => 'attachments', :action => 'show', :id => attachment, :filename => attachment.filename},
159 :title => attachment.filename
159 :title => attachment.filename
160 end
160 end
161
161
162 def toggle_link(name, id, options={})
162 def toggle_link(name, id, options={})
163 onclick = "Element.toggle('#{id}'); "
163 onclick = "Element.toggle('#{id}'); "
164 onclick << (options[:focus] ? "Form.Element.focus('#{options[:focus]}'); " : "this.blur(); ")
164 onclick << (options[:focus] ? "Form.Element.focus('#{options[:focus]}'); " : "this.blur(); ")
165 onclick << "return false;"
165 onclick << "return false;"
166 link_to(name, "#", :onclick => onclick)
166 link_to(name, "#", :onclick => onclick)
167 end
167 end
168
168
169 def image_to_function(name, function, html_options = {})
169 def image_to_function(name, function, html_options = {})
170 html_options.symbolize_keys!
170 html_options.symbolize_keys!
171 tag(:input, html_options.merge({
171 tag(:input, html_options.merge({
172 :type => "image", :src => image_path(name),
172 :type => "image", :src => image_path(name),
173 :onclick => (html_options[:onclick] ? "#{html_options[:onclick]}; " : "") + "#{function};"
173 :onclick => (html_options[:onclick] ? "#{html_options[:onclick]}; " : "") + "#{function};"
174 }))
174 }))
175 end
175 end
176
176
177 def prompt_to_remote(name, text, param, url, html_options = {})
177 def prompt_to_remote(name, text, param, url, html_options = {})
178 html_options[:onclick] = "promptToRemote('#{text}', '#{param}', '#{url_for(url)}'); return false;"
178 html_options[:onclick] = "promptToRemote('#{text}', '#{param}', '#{url_for(url)}'); return false;"
179 link_to name, {}, html_options
179 link_to name, {}, html_options
180 end
180 end
181
181
182 def format_activity_title(text)
182 def format_activity_title(text)
183 h(truncate_single_line(text, :length => 100))
183 h(truncate_single_line(text, :length => 100))
184 end
184 end
185
185
186 def format_activity_day(date)
186 def format_activity_day(date)
187 date == User.current.today ? l(:label_today).titleize : format_date(date)
187 date == User.current.today ? l(:label_today).titleize : format_date(date)
188 end
188 end
189
189
190 def format_activity_description(text)
190 def format_activity_description(text)
191 h(truncate(text.to_s, :length => 120).gsub(%r{[\r\n]*<(pre|code)>.*$}m, '...')
191 h(truncate(text.to_s, :length => 120).gsub(%r{[\r\n]*<(pre|code)>.*$}m, '...')
192 ).gsub(/[\r\n]+/, "<br />").html_safe
192 ).gsub(/[\r\n]+/, "<br />").html_safe
193 end
193 end
194
194
195 def format_version_name(version)
195 def format_version_name(version)
196 if version.project == @project
196 if version.project == @project
197 h(version)
197 h(version)
198 else
198 else
199 h("#{version.project} - #{version}")
199 h("#{version.project} - #{version}")
200 end
200 end
201 end
201 end
202
202
203 def due_date_distance_in_words(date)
203 def due_date_distance_in_words(date)
204 if date
204 if date
205 l((date < Date.today ? :label_roadmap_overdue : :label_roadmap_due_in), distance_of_date_in_words(Date.today, date))
205 l((date < Date.today ? :label_roadmap_overdue : :label_roadmap_due_in), distance_of_date_in_words(Date.today, date))
206 end
206 end
207 end
207 end
208
208
209 def render_page_hierarchy(pages, node=nil, options={})
209 def render_page_hierarchy(pages, node=nil, options={})
210 content = ''
210 content = ''
211 if pages[node]
211 if pages[node]
212 content << "<ul class=\"pages-hierarchy\">\n"
212 content << "<ul class=\"pages-hierarchy\">\n"
213 pages[node].each do |page|
213 pages[node].each do |page|
214 content << "<li>"
214 content << "<li>"
215 content << link_to(h(page.pretty_title), {:controller => 'wiki', :action => 'show', :project_id => page.project, :id => page.title},
215 content << link_to(h(page.pretty_title), {:controller => 'wiki', :action => 'show', :project_id => page.project, :id => page.title},
216 :title => (options[:timestamp] && page.updated_on ? l(:label_updated_time, distance_of_time_in_words(Time.now, page.updated_on)) : nil))
216 :title => (options[:timestamp] && page.updated_on ? l(:label_updated_time, distance_of_time_in_words(Time.now, page.updated_on)) : nil))
217 content << "\n" + render_page_hierarchy(pages, page.id, options) if pages[page.id]
217 content << "\n" + render_page_hierarchy(pages, page.id, options) if pages[page.id]
218 content << "</li>\n"
218 content << "</li>\n"
219 end
219 end
220 content << "</ul>\n"
220 content << "</ul>\n"
221 end
221 end
222 content.html_safe
222 content.html_safe
223 end
223 end
224
224
225 # Renders flash messages
225 # Renders flash messages
226 def render_flash_messages
226 def render_flash_messages
227 s = ''
227 s = ''
228 flash.each do |k,v|
228 flash.each do |k,v|
229 s << content_tag('div', v.html_safe, :class => "flash #{k}", :id => "flash_#{k}")
229 s << content_tag('div', v.html_safe, :class => "flash #{k}", :id => "flash_#{k}")
230 end
230 end
231 s.html_safe
231 s.html_safe
232 end
232 end
233
233
234 # Renders tabs and their content
234 # Renders tabs and their content
235 def render_tabs(tabs)
235 def render_tabs(tabs)
236 if tabs.any?
236 if tabs.any?
237 render :partial => 'common/tabs', :locals => {:tabs => tabs}
237 render :partial => 'common/tabs', :locals => {:tabs => tabs}
238 else
238 else
239 content_tag 'p', l(:label_no_data), :class => "nodata"
239 content_tag 'p', l(:label_no_data), :class => "nodata"
240 end
240 end
241 end
241 end
242
242
243 # Renders the project quick-jump box
243 # Renders the project quick-jump box
244 def render_project_jump_box
244 def render_project_jump_box
245 return unless User.current.logged?
245 return unless User.current.logged?
246 projects = User.current.memberships.collect(&:project).compact.select(&:active?).uniq
246 projects = User.current.memberships.collect(&:project).compact.select(&:active?).uniq
247 if projects.any?
247 if projects.any?
248 options =
248 options =
249 ("<option value=''>#{ l(:label_jump_to_a_project) }</option>" +
249 ("<option value=''>#{ l(:label_jump_to_a_project) }</option>" +
250 '<option value="" disabled="disabled">---</option>').html_safe
250 '<option value="" disabled="disabled">---</option>').html_safe
251
251
252 options << project_tree_options_for_select(projects, :selected => @project) do |p|
252 options << project_tree_options_for_select(projects, :selected => @project) do |p|
253 { :value => project_path(:id => p, :jump => current_menu_item) }
253 { :value => project_path(:id => p, :jump => current_menu_item) }
254 end
254 end
255
255
256 select_tag('project_quick_jump_box', options, :onchange => 'if (this.value != \'\') { window.location = this.value; }')
256 select_tag('project_quick_jump_box', options, :onchange => 'if (this.value != \'\') { window.location = this.value; }')
257 end
257 end
258 end
258 end
259
259
260 def project_tree_options_for_select(projects, options = {})
260 def project_tree_options_for_select(projects, options = {})
261 s = ''
261 s = ''
262 project_tree(projects) do |project, level|
262 project_tree(projects) do |project, level|
263 name_prefix = (level > 0 ? '&nbsp;' * 2 * level + '&#187; ' : '').html_safe
263 name_prefix = (level > 0 ? '&nbsp;' * 2 * level + '&#187; ' : '').html_safe
264 tag_options = {:value => project.id}
264 tag_options = {:value => project.id}
265 if project == options[:selected] || (options[:selected].respond_to?(:include?) && options[:selected].include?(project))
265 if project == options[:selected] || (options[:selected].respond_to?(:include?) && options[:selected].include?(project))
266 tag_options[:selected] = 'selected'
266 tag_options[:selected] = 'selected'
267 else
267 else
268 tag_options[:selected] = nil
268 tag_options[:selected] = nil
269 end
269 end
270 tag_options.merge!(yield(project)) if block_given?
270 tag_options.merge!(yield(project)) if block_given?
271 s << content_tag('option', name_prefix + h(project), tag_options)
271 s << content_tag('option', name_prefix + h(project), tag_options)
272 end
272 end
273 s.html_safe
273 s.html_safe
274 end
274 end
275
275
276 # Yields the given block for each project with its level in the tree
276 # Yields the given block for each project with its level in the tree
277 #
277 #
278 # Wrapper for Project#project_tree
278 # Wrapper for Project#project_tree
279 def project_tree(projects, &block)
279 def project_tree(projects, &block)
280 Project.project_tree(projects, &block)
280 Project.project_tree(projects, &block)
281 end
281 end
282
282
283 def project_nested_ul(projects, &block)
283 def project_nested_ul(projects, &block)
284 s = ''
284 s = ''
285 if projects.any?
285 if projects.any?
286 ancestors = []
286 ancestors = []
287 projects.sort_by(&:lft).each do |project|
287 projects.sort_by(&:lft).each do |project|
288 if (ancestors.empty? || project.is_descendant_of?(ancestors.last))
288 if (ancestors.empty? || project.is_descendant_of?(ancestors.last))
289 s << "<ul>\n"
289 s << "<ul>\n"
290 else
290 else
291 ancestors.pop
291 ancestors.pop
292 s << "</li>"
292 s << "</li>"
293 while (ancestors.any? && !project.is_descendant_of?(ancestors.last))
293 while (ancestors.any? && !project.is_descendant_of?(ancestors.last))
294 ancestors.pop
294 ancestors.pop
295 s << "</ul></li>\n"
295 s << "</ul></li>\n"
296 end
296 end
297 end
297 end
298 s << "<li>"
298 s << "<li>"
299 s << yield(project).to_s
299 s << yield(project).to_s
300 ancestors << project
300 ancestors << project
301 end
301 end
302 s << ("</li></ul>\n" * ancestors.size)
302 s << ("</li></ul>\n" * ancestors.size)
303 end
303 end
304 s.html_safe
304 s.html_safe
305 end
305 end
306
306
307 def principals_check_box_tags(name, principals)
307 def principals_check_box_tags(name, principals)
308 s = ''
308 s = ''
309 principals.sort.each do |principal|
309 principals.sort.each do |principal|
310 s << "<label>#{ check_box_tag name, principal.id, false } #{h principal}</label>\n"
310 s << "<label>#{ check_box_tag name, principal.id, false } #{h principal}</label>\n"
311 end
311 end
312 s.html_safe
312 s.html_safe
313 end
313 end
314
314
315 # Returns a string for users/groups option tags
315 # Returns a string for users/groups option tags
316 def principals_options_for_select(collection, selected=nil)
316 def principals_options_for_select(collection, selected=nil)
317 s = ''
317 s = ''
318 if collection.include?(User.current)
318 if collection.include?(User.current)
319 s << content_tag('option', "<< #{l(:label_me)} >>".html_safe, :value => User.current.id)
319 s << content_tag('option', "<< #{l(:label_me)} >>".html_safe, :value => User.current.id)
320 end
320 end
321 groups = ''
321 groups = ''
322 collection.sort.each do |element|
322 collection.sort.each do |element|
323 selected_attribute = ' selected="selected"' if option_value_selected?(element, selected)
323 selected_attribute = ' selected="selected"' if option_value_selected?(element, selected)
324 (element.is_a?(Group) ? groups : s) << %(<option value="#{element.id}"#{selected_attribute}>#{h element.name}</option>)
324 (element.is_a?(Group) ? groups : s) << %(<option value="#{element.id}"#{selected_attribute}>#{h element.name}</option>)
325 end
325 end
326 unless groups.empty?
326 unless groups.empty?
327 s << %(<optgroup label="#{h(l(:label_group_plural))}">#{groups}</optgroup>)
327 s << %(<optgroup label="#{h(l(:label_group_plural))}">#{groups}</optgroup>)
328 end
328 end
329 s.html_safe
329 s.html_safe
330 end
330 end
331
331
332 # Truncates and returns the string as a single line
332 # Truncates and returns the string as a single line
333 def truncate_single_line(string, *args)
333 def truncate_single_line(string, *args)
334 truncate(string.to_s, *args).gsub(%r{[\r\n]+}m, ' ')
334 truncate(string.to_s, *args).gsub(%r{[\r\n]+}m, ' ')
335 end
335 end
336
336
337 # Truncates at line break after 250 characters or options[:length]
337 # Truncates at line break after 250 characters or options[:length]
338 def truncate_lines(string, options={})
338 def truncate_lines(string, options={})
339 length = options[:length] || 250
339 length = options[:length] || 250
340 if string.to_s =~ /\A(.{#{length}}.*?)$/m
340 if string.to_s =~ /\A(.{#{length}}.*?)$/m
341 "#{$1}..."
341 "#{$1}..."
342 else
342 else
343 string
343 string
344 end
344 end
345 end
345 end
346
346
347 def anchor(text)
347 def anchor(text)
348 text.to_s.gsub(' ', '_')
348 text.to_s.gsub(' ', '_')
349 end
349 end
350
350
351 def html_hours(text)
351 def html_hours(text)
352 text.gsub(%r{(\d+)\.(\d+)}, '<span class="hours hours-int">\1</span><span class="hours hours-dec">.\2</span>').html_safe
352 text.gsub(%r{(\d+)\.(\d+)}, '<span class="hours hours-int">\1</span><span class="hours hours-dec">.\2</span>').html_safe
353 end
353 end
354
354
355 def authoring(created, author, options={})
355 def authoring(created, author, options={})
356 l(options[:label] || :label_added_time_by, :author => link_to_user(author), :age => time_tag(created)).html_safe
356 l(options[:label] || :label_added_time_by, :author => link_to_user(author), :age => time_tag(created)).html_safe
357 end
357 end
358
358
359 def time_tag(time)
359 def time_tag(time)
360 text = distance_of_time_in_words(Time.now, time)
360 text = distance_of_time_in_words(Time.now, time)
361 if @project
361 if @project
362 link_to(text, {:controller => 'activities', :action => 'index', :id => @project, :from => User.current.time_to_date(time)}, :title => format_time(time))
362 link_to(text, {:controller => 'activities', :action => 'index', :id => @project, :from => User.current.time_to_date(time)}, :title => format_time(time))
363 else
363 else
364 content_tag('acronym', text, :title => format_time(time))
364 content_tag('acronym', text, :title => format_time(time))
365 end
365 end
366 end
366 end
367
367
368 def syntax_highlight_lines(name, content)
368 def syntax_highlight_lines(name, content)
369 lines = []
369 lines = []
370 syntax_highlight(name, content).each_line { |line| lines << line }
370 syntax_highlight(name, content).each_line { |line| lines << line }
371 lines
371 lines
372 end
372 end
373
373
374 def syntax_highlight(name, content)
374 def syntax_highlight(name, content)
375 Redmine::SyntaxHighlighting.highlight_by_filename(content, name)
375 Redmine::SyntaxHighlighting.highlight_by_filename(content, name)
376 end
376 end
377
377
378 def to_path_param(path)
378 def to_path_param(path)
379 str = path.to_s.split(%r{[/\\]}).select{|p| !p.blank?}.join("/")
379 str = path.to_s.split(%r{[/\\]}).select{|p| !p.blank?}.join("/")
380 str.blank? ? nil : str
380 str.blank? ? nil : str
381 end
381 end
382
382
383 def pagination_links_full(paginator, count=nil, options={})
383 def pagination_links_full(paginator, count=nil, options={})
384 page_param = options.delete(:page_param) || :page
384 page_param = options.delete(:page_param) || :page
385 per_page_links = options.delete(:per_page_links)
385 per_page_links = options.delete(:per_page_links)
386 url_param = params.dup
386 url_param = params.dup
387
387
388 html = ''
388 html = ''
389 if paginator.current.previous
389 if paginator.current.previous
390 # \xc2\xab(utf-8) = &#171;
390 # \xc2\xab(utf-8) = &#171;
391 html << link_to_content_update(
391 html << link_to_content_update(
392 "\xc2\xab " + l(:label_previous),
392 "\xc2\xab " + l(:label_previous),
393 url_param.merge(page_param => paginator.current.previous)) + ' '
393 url_param.merge(page_param => paginator.current.previous)) + ' '
394 end
394 end
395
395
396 html << (pagination_links_each(paginator, options) do |n|
396 html << (pagination_links_each(paginator, options) do |n|
397 link_to_content_update(n.to_s, url_param.merge(page_param => n))
397 link_to_content_update(n.to_s, url_param.merge(page_param => n))
398 end || '')
398 end || '')
399
399
400 if paginator.current.next
400 if paginator.current.next
401 # \xc2\xbb(utf-8) = &#187;
401 # \xc2\xbb(utf-8) = &#187;
402 html << ' ' + link_to_content_update(
402 html << ' ' + link_to_content_update(
403 (l(:label_next) + " \xc2\xbb"),
403 (l(:label_next) + " \xc2\xbb"),
404 url_param.merge(page_param => paginator.current.next))
404 url_param.merge(page_param => paginator.current.next))
405 end
405 end
406
406
407 unless count.nil?
407 unless count.nil?
408 html << " (#{paginator.current.first_item}-#{paginator.current.last_item}/#{count})"
408 html << " (#{paginator.current.first_item}-#{paginator.current.last_item}/#{count})"
409 if per_page_links != false && links = per_page_links(paginator.items_per_page, count)
409 if per_page_links != false && links = per_page_links(paginator.items_per_page, count)
410 html << " | #{links}"
410 html << " | #{links}"
411 end
411 end
412 end
412 end
413
413
414 html.html_safe
414 html.html_safe
415 end
415 end
416
416
417 def per_page_links(selected=nil, item_count=nil)
417 def per_page_links(selected=nil, item_count=nil)
418 values = Setting.per_page_options_array
418 values = Setting.per_page_options_array
419 if item_count && values.any?
419 if item_count && values.any?
420 if item_count > values.first
420 if item_count > values.first
421 max = values.detect {|value| value >= item_count} || item_count
421 max = values.detect {|value| value >= item_count} || item_count
422 else
422 else
423 max = item_count
423 max = item_count
424 end
424 end
425 values = values.select {|value| value <= max || value == selected}
425 values = values.select {|value| value <= max || value == selected}
426 end
426 end
427 if values.empty? || (values.size == 1 && values.first == selected)
427 if values.empty? || (values.size == 1 && values.first == selected)
428 return nil
428 return nil
429 end
429 end
430 links = values.collect do |n|
430 links = values.collect do |n|
431 n == selected ? n : link_to_content_update(n, params.merge(:per_page => n))
431 n == selected ? n : link_to_content_update(n, params.merge(:per_page => n))
432 end
432 end
433 l(:label_display_per_page, links.join(', '))
433 l(:label_display_per_page, links.join(', '))
434 end
434 end
435
435
436 def reorder_links(name, url, method = :post)
436 def reorder_links(name, url, method = :post)
437 link_to(image_tag('2uparrow.png', :alt => l(:label_sort_highest)),
437 link_to(image_tag('2uparrow.png', :alt => l(:label_sort_highest)),
438 url.merge({"#{name}[move_to]" => 'highest'}),
438 url.merge({"#{name}[move_to]" => 'highest'}),
439 :method => method, :title => l(:label_sort_highest)) +
439 :method => method, :title => l(:label_sort_highest)) +
440 link_to(image_tag('1uparrow.png', :alt => l(:label_sort_higher)),
440 link_to(image_tag('1uparrow.png', :alt => l(:label_sort_higher)),
441 url.merge({"#{name}[move_to]" => 'higher'}),
441 url.merge({"#{name}[move_to]" => 'higher'}),
442 :method => method, :title => l(:label_sort_higher)) +
442 :method => method, :title => l(:label_sort_higher)) +
443 link_to(image_tag('1downarrow.png', :alt => l(:label_sort_lower)),
443 link_to(image_tag('1downarrow.png', :alt => l(:label_sort_lower)),
444 url.merge({"#{name}[move_to]" => 'lower'}),
444 url.merge({"#{name}[move_to]" => 'lower'}),
445 :method => method, :title => l(:label_sort_lower)) +
445 :method => method, :title => l(:label_sort_lower)) +
446 link_to(image_tag('2downarrow.png', :alt => l(:label_sort_lowest)),
446 link_to(image_tag('2downarrow.png', :alt => l(:label_sort_lowest)),
447 url.merge({"#{name}[move_to]" => 'lowest'}),
447 url.merge({"#{name}[move_to]" => 'lowest'}),
448 :method => method, :title => l(:label_sort_lowest))
448 :method => method, :title => l(:label_sort_lowest))
449 end
449 end
450
450
451 def breadcrumb(*args)
451 def breadcrumb(*args)
452 elements = args.flatten
452 elements = args.flatten
453 elements.any? ? content_tag('p', (args.join(" \xc2\xbb ") + " \xc2\xbb ").html_safe, :class => 'breadcrumb') : nil
453 elements.any? ? content_tag('p', (args.join(" \xc2\xbb ") + " \xc2\xbb ").html_safe, :class => 'breadcrumb') : nil
454 end
454 end
455
455
456 def other_formats_links(&block)
456 def other_formats_links(&block)
457 concat('<p class="other-formats">'.html_safe + l(:label_export_to))
457 concat('<p class="other-formats">'.html_safe + l(:label_export_to))
458 yield Redmine::Views::OtherFormatsBuilder.new(self)
458 yield Redmine::Views::OtherFormatsBuilder.new(self)
459 concat('</p>'.html_safe)
459 concat('</p>'.html_safe)
460 end
460 end
461
461
462 def page_header_title
462 def page_header_title
463 if @project.nil? || @project.new_record?
463 if @project.nil? || @project.new_record?
464 h(Setting.app_title)
464 h(Setting.app_title)
465 else
465 else
466 b = []
466 b = []
467 ancestors = (@project.root? ? [] : @project.ancestors.visible.all)
467 ancestors = (@project.root? ? [] : @project.ancestors.visible.all)
468 if ancestors.any?
468 if ancestors.any?
469 root = ancestors.shift
469 root = ancestors.shift
470 b << link_to_project(root, {:jump => current_menu_item}, :class => 'root')
470 b << link_to_project(root, {:jump => current_menu_item}, :class => 'root')
471 if ancestors.size > 2
471 if ancestors.size > 2
472 b << "\xe2\x80\xa6"
472 b << "\xe2\x80\xa6"
473 ancestors = ancestors[-2, 2]
473 ancestors = ancestors[-2, 2]
474 end
474 end
475 b += ancestors.collect {|p| link_to_project(p, {:jump => current_menu_item}, :class => 'ancestor') }
475 b += ancestors.collect {|p| link_to_project(p, {:jump => current_menu_item}, :class => 'ancestor') }
476 end
476 end
477 b << h(@project)
477 b << h(@project)
478 b.join(" \xc2\xbb ").html_safe
478 b.join(" \xc2\xbb ").html_safe
479 end
479 end
480 end
480 end
481
481
482 def html_title(*args)
482 def html_title(*args)
483 if args.empty?
483 if args.empty?
484 title = @html_title || []
484 title = @html_title || []
485 title << @project.name if @project
485 title << @project.name if @project
486 title << Setting.app_title unless Setting.app_title == title.last
486 title << Setting.app_title unless Setting.app_title == title.last
487 title.select {|t| !t.blank? }.join(' - ')
487 title.select {|t| !t.blank? }.join(' - ')
488 else
488 else
489 @html_title ||= []
489 @html_title ||= []
490 @html_title += args
490 @html_title += args
491 end
491 end
492 end
492 end
493
493
494 # Returns the theme, controller name, and action as css classes for the
494 # Returns the theme, controller name, and action as css classes for the
495 # HTML body.
495 # HTML body.
496 def body_css_classes
496 def body_css_classes
497 css = []
497 css = []
498 if theme = Redmine::Themes.theme(Setting.ui_theme)
498 if theme = Redmine::Themes.theme(Setting.ui_theme)
499 css << 'theme-' + theme.name
499 css << 'theme-' + theme.name
500 end
500 end
501
501
502 css << 'controller-' + controller_name
502 css << 'controller-' + controller_name
503 css << 'action-' + action_name
503 css << 'action-' + action_name
504 css.join(' ')
504 css.join(' ')
505 end
505 end
506
506
507 def accesskey(s)
507 def accesskey(s)
508 Redmine::AccessKeys.key_for s
508 Redmine::AccessKeys.key_for s
509 end
509 end
510
510
511 # Formats text according to system settings.
511 # Formats text according to system settings.
512 # 2 ways to call this method:
512 # 2 ways to call this method:
513 # * with a String: textilizable(text, options)
513 # * with a String: textilizable(text, options)
514 # * with an object and one of its attribute: textilizable(issue, :description, options)
514 # * with an object and one of its attribute: textilizable(issue, :description, options)
515 def textilizable(*args)
515 def textilizable(*args)
516 options = args.last.is_a?(Hash) ? args.pop : {}
516 options = args.last.is_a?(Hash) ? args.pop : {}
517 case args.size
517 case args.size
518 when 1
518 when 1
519 obj = options[:object]
519 obj = options[:object]
520 text = args.shift
520 text = args.shift
521 when 2
521 when 2
522 obj = args.shift
522 obj = args.shift
523 attr = args.shift
523 attr = args.shift
524 text = obj.send(attr).to_s
524 text = obj.send(attr).to_s
525 else
525 else
526 raise ArgumentError, 'invalid arguments to textilizable'
526 raise ArgumentError, 'invalid arguments to textilizable'
527 end
527 end
528 return '' if text.blank?
528 return '' if text.blank?
529 project = options[:project] || @project || (obj && obj.respond_to?(:project) ? obj.project : nil)
529 project = options[:project] || @project || (obj && obj.respond_to?(:project) ? obj.project : nil)
530 only_path = options.delete(:only_path) == false ? false : true
530 only_path = options.delete(:only_path) == false ? false : true
531
531
532 text = Redmine::WikiFormatting.to_html(Setting.text_formatting, text, :object => obj, :attribute => attr)
532 text = Redmine::WikiFormatting.to_html(Setting.text_formatting, text, :object => obj, :attribute => attr)
533
533
534 @parsed_headings = []
534 @parsed_headings = []
535 @heading_anchors = {}
535 @heading_anchors = {}
536 @current_section = 0 if options[:edit_section_links]
536 @current_section = 0 if options[:edit_section_links]
537
537
538 parse_sections(text, project, obj, attr, only_path, options)
538 parse_sections(text, project, obj, attr, only_path, options)
539 text = parse_non_pre_blocks(text) do |text|
539 text = parse_non_pre_blocks(text) do |text|
540 [:parse_inline_attachments, :parse_wiki_links, :parse_redmine_links, :parse_macros].each do |method_name|
540 [:parse_inline_attachments, :parse_wiki_links, :parse_redmine_links, :parse_macros].each do |method_name|
541 send method_name, text, project, obj, attr, only_path, options
541 send method_name, text, project, obj, attr, only_path, options
542 end
542 end
543 end
543 end
544 parse_headings(text, project, obj, attr, only_path, options)
544 parse_headings(text, project, obj, attr, only_path, options)
545
545
546 if @parsed_headings.any?
546 if @parsed_headings.any?
547 replace_toc(text, @parsed_headings)
547 replace_toc(text, @parsed_headings)
548 end
548 end
549
549
550 text.html_safe
550 text.html_safe
551 end
551 end
552
552
553 def parse_non_pre_blocks(text)
553 def parse_non_pre_blocks(text)
554 s = StringScanner.new(text)
554 s = StringScanner.new(text)
555 tags = []
555 tags = []
556 parsed = ''
556 parsed = ''
557 while !s.eos?
557 while !s.eos?
558 s.scan(/(.*?)(<(\/)?(pre|code)(.*?)>|\z)/im)
558 s.scan(/(.*?)(<(\/)?(pre|code)(.*?)>|\z)/im)
559 text, full_tag, closing, tag = s[1], s[2], s[3], s[4]
559 text, full_tag, closing, tag = s[1], s[2], s[3], s[4]
560 if tags.empty?
560 if tags.empty?
561 yield text
561 yield text
562 end
562 end
563 parsed << text
563 parsed << text
564 if tag
564 if tag
565 if closing
565 if closing
566 if tags.last == tag.downcase
566 if tags.last == tag.downcase
567 tags.pop
567 tags.pop
568 end
568 end
569 else
569 else
570 tags << tag.downcase
570 tags << tag.downcase
571 end
571 end
572 parsed << full_tag
572 parsed << full_tag
573 end
573 end
574 end
574 end
575 # Close any non closing tags
575 # Close any non closing tags
576 while tag = tags.pop
576 while tag = tags.pop
577 parsed << "</#{tag}>"
577 parsed << "</#{tag}>"
578 end
578 end
579 parsed
579 parsed
580 end
580 end
581
581
582 def parse_inline_attachments(text, project, obj, attr, only_path, options)
582 def parse_inline_attachments(text, project, obj, attr, only_path, options)
583 # when using an image link, try to use an attachment, if possible
583 # when using an image link, try to use an attachment, if possible
584 if options[:attachments] || (obj && obj.respond_to?(:attachments))
584 if options[:attachments] || (obj && obj.respond_to?(:attachments))
585 attachments = options[:attachments] || obj.attachments
585 attachments = options[:attachments] || obj.attachments
586 text.gsub!(/src="([^\/"]+\.(bmp|gif|jpg|jpe|jpeg|png))"(\s+alt="([^"]*)")?/i) do |m|
586 text.gsub!(/src="([^\/"]+\.(bmp|gif|jpg|jpe|jpeg|png))"(\s+alt="([^"]*)")?/i) do |m|
587 filename, ext, alt, alttext = $1.downcase, $2, $3, $4
587 filename, ext, alt, alttext = $1.downcase, $2, $3, $4
588 # search for the picture in attachments
588 # search for the picture in attachments
589 if found = Attachment.latest_attach(attachments, filename)
589 if found = Attachment.latest_attach(attachments, filename)
590 image_url = url_for :only_path => only_path, :controller => 'attachments',
590 image_url = url_for :only_path => only_path, :controller => 'attachments',
591 :action => 'download', :id => found
591 :action => 'download', :id => found
592 desc = found.description.to_s.gsub('"', '')
592 desc = found.description.to_s.gsub('"', '')
593 if !desc.blank? && alttext.blank?
593 if !desc.blank? && alttext.blank?
594 alt = " title=\"#{desc}\" alt=\"#{desc}\""
594 alt = " title=\"#{desc}\" alt=\"#{desc}\""
595 end
595 end
596 "src=\"#{image_url}\"#{alt}"
596 "src=\"#{image_url}\"#{alt}"
597 else
597 else
598 m
598 m
599 end
599 end
600 end
600 end
601 end
601 end
602 end
602 end
603
603
604 # Wiki links
604 # Wiki links
605 #
605 #
606 # Examples:
606 # Examples:
607 # [[mypage]]
607 # [[mypage]]
608 # [[mypage|mytext]]
608 # [[mypage|mytext]]
609 # wiki links can refer other project wikis, using project name or identifier:
609 # wiki links can refer other project wikis, using project name or identifier:
610 # [[project:]] -> wiki starting page
610 # [[project:]] -> wiki starting page
611 # [[project:|mytext]]
611 # [[project:|mytext]]
612 # [[project:mypage]]
612 # [[project:mypage]]
613 # [[project:mypage|mytext]]
613 # [[project:mypage|mytext]]
614 def parse_wiki_links(text, project, obj, attr, only_path, options)
614 def parse_wiki_links(text, project, obj, attr, only_path, options)
615 text.gsub!(/(!)?(\[\[([^\]\n\|]+)(\|([^\]\n\|]+))?\]\])/) do |m|
615 text.gsub!(/(!)?(\[\[([^\]\n\|]+)(\|([^\]\n\|]+))?\]\])/) do |m|
616 link_project = project
616 link_project = project
617 esc, all, page, title = $1, $2, $3, $5
617 esc, all, page, title = $1, $2, $3, $5
618 if esc.nil?
618 if esc.nil?
619 if page =~ /^([^\:]+)\:(.*)$/
619 if page =~ /^([^\:]+)\:(.*)$/
620 link_project = Project.find_by_identifier($1) || Project.find_by_name($1)
620 link_project = Project.find_by_identifier($1) || Project.find_by_name($1)
621 page = $2
621 page = $2
622 title ||= $1 if page.blank?
622 title ||= $1 if page.blank?
623 end
623 end
624
624
625 if link_project && link_project.wiki
625 if link_project && link_project.wiki
626 # extract anchor
626 # extract anchor
627 anchor = nil
627 anchor = nil
628 if page =~ /^(.+?)\#(.+)$/
628 if page =~ /^(.+?)\#(.+)$/
629 page, anchor = $1, $2
629 page, anchor = $1, $2
630 end
630 end
631 anchor = sanitize_anchor_name(anchor) if anchor.present?
631 anchor = sanitize_anchor_name(anchor) if anchor.present?
632 # check if page exists
632 # check if page exists
633 wiki_page = link_project.wiki.find_page(page)
633 wiki_page = link_project.wiki.find_page(page)
634 url = if anchor.present? && wiki_page.present? && (obj.is_a?(WikiContent) || obj.is_a?(WikiContent::Version)) && obj.page == wiki_page
634 url = if anchor.present? && wiki_page.present? && (obj.is_a?(WikiContent) || obj.is_a?(WikiContent::Version)) && obj.page == wiki_page
635 "##{anchor}"
635 "##{anchor}"
636 else
636 else
637 case options[:wiki_links]
637 case options[:wiki_links]
638 when :local; "#{page.present? ? Wiki.titleize(page) : ''}.html" + (anchor.present? ? "##{anchor}" : '')
638 when :local; "#{page.present? ? Wiki.titleize(page) : ''}.html" + (anchor.present? ? "##{anchor}" : '')
639 when :anchor; "##{page.present? ? Wiki.titleize(page) : title}" + (anchor.present? ? "_#{anchor}" : '') # used for single-file wiki export
639 when :anchor; "##{page.present? ? Wiki.titleize(page) : title}" + (anchor.present? ? "_#{anchor}" : '') # used for single-file wiki export
640 else
640 else
641 wiki_page_id = page.present? ? Wiki.titleize(page) : nil
641 wiki_page_id = page.present? ? Wiki.titleize(page) : nil
642 parent = wiki_page.nil? && obj.is_a?(WikiContent) && obj.page && project == link_project ? obj.page.title : nil
642 parent = wiki_page.nil? && obj.is_a?(WikiContent) && obj.page && project == link_project ? obj.page.title : nil
643 url_for(:only_path => only_path, :controller => 'wiki', :action => 'show', :project_id => link_project,
643 url_for(:only_path => only_path, :controller => 'wiki', :action => 'show', :project_id => link_project,
644 :id => wiki_page_id, :anchor => anchor, :parent => parent)
644 :id => wiki_page_id, :anchor => anchor, :parent => parent)
645 end
645 end
646 end
646 end
647 link_to(title.present? ? title.html_safe : h(page), url, :class => ('wiki-page' + (wiki_page ? '' : ' new')))
647 link_to(title.present? ? title.html_safe : h(page), url, :class => ('wiki-page' + (wiki_page ? '' : ' new')))
648 else
648 else
649 # project or wiki doesn't exist
649 # project or wiki doesn't exist
650 all
650 all
651 end
651 end
652 else
652 else
653 all
653 all
654 end
654 end
655 end
655 end
656 end
656 end
657
657
658 # Redmine links
658 # Redmine links
659 #
659 #
660 # Examples:
660 # Examples:
661 # Issues:
661 # Issues:
662 # #52 -> Link to issue #52
662 # #52 -> Link to issue #52
663 # Changesets:
663 # Changesets:
664 # r52 -> Link to revision 52
664 # r52 -> Link to revision 52
665 # commit:a85130f -> Link to scmid starting with a85130f
665 # commit:a85130f -> Link to scmid starting with a85130f
666 # Documents:
666 # Documents:
667 # document#17 -> Link to document with id 17
667 # document#17 -> Link to document with id 17
668 # document:Greetings -> Link to the document with title "Greetings"
668 # document:Greetings -> Link to the document with title "Greetings"
669 # document:"Some document" -> Link to the document with title "Some document"
669 # document:"Some document" -> Link to the document with title "Some document"
670 # Versions:
670 # Versions:
671 # version#3 -> Link to version with id 3
671 # version#3 -> Link to version with id 3
672 # version:1.0.0 -> Link to version named "1.0.0"
672 # version:1.0.0 -> Link to version named "1.0.0"
673 # version:"1.0 beta 2" -> Link to version named "1.0 beta 2"
673 # version:"1.0 beta 2" -> Link to version named "1.0 beta 2"
674 # Attachments:
674 # Attachments:
675 # attachment:file.zip -> Link to the attachment of the current object named file.zip
675 # attachment:file.zip -> Link to the attachment of the current object named file.zip
676 # Source files:
676 # Source files:
677 # source:some/file -> Link to the file located at /some/file in the project's repository
677 # source:some/file -> Link to the file located at /some/file in the project's repository
678 # source:some/file@52 -> Link to the file's revision 52
678 # source:some/file@52 -> Link to the file's revision 52
679 # source:some/file#L120 -> Link to line 120 of the file
679 # source:some/file#L120 -> Link to line 120 of the file
680 # source:some/file@52#L120 -> Link to line 120 of the file's revision 52
680 # source:some/file@52#L120 -> Link to line 120 of the file's revision 52
681 # export:some/file -> Force the download of the file
681 # export:some/file -> Force the download of the file
682 # Forum messages:
682 # Forum messages:
683 # message#1218 -> Link to message with id 1218
683 # message#1218 -> Link to message with id 1218
684 #
684 #
685 # Links can refer other objects from other projects, using project identifier:
685 # Links can refer other objects from other projects, using project identifier:
686 # identifier:r52
686 # identifier:r52
687 # identifier:document:"Some document"
687 # identifier:document:"Some document"
688 # identifier:version:1.0.0
688 # identifier:version:1.0.0
689 # identifier:source:some/file
689 # identifier:source:some/file
690 def parse_redmine_links(text, project, obj, attr, only_path, options)
690 def parse_redmine_links(text, project, obj, attr, only_path, options)
691 text.gsub!(%r{([\s\(,\-\[\>]|^)(!)?(([a-z0-9\-_]+):)?(attachment|document|version|forum|news|message|project|commit|source|export)?(((#)|((([a-z0-9\-]+)\|)?(r)))((\d+)((#note)?-(\d+))?)|(:)([^"\s<>][^\s<>]*?|"[^"]+?"))(?=(?=[[:punct:]][^A-Za-z0-9_/])|,|\s|\]|<|$)}) do |m|
691 text.gsub!(%r{([\s\(,\-\[\>]|^)(!)?(([a-z0-9\-_]+):)?(attachment|document|version|forum|news|message|project|commit|source|export)?(((#)|((([a-z0-9\-]+)\|)?(r)))((\d+)((#note)?-(\d+))?)|(:)([^"\s<>][^\s<>]*?|"[^"]+?"))(?=(?=[[:punct:]][^A-Za-z0-9_/])|,|\s|\]|<|$)}) do |m|
692 leading, esc, project_prefix, project_identifier, prefix, repo_prefix, repo_identifier, sep, identifier, comment_suffix, comment_id = $1, $2, $3, $4, $5, $10, $11, $8 || $12 || $18, $14 || $19, $15, $17
692 leading, esc, project_prefix, project_identifier, prefix, repo_prefix, repo_identifier, sep, identifier, comment_suffix, comment_id = $1, $2, $3, $4, $5, $10, $11, $8 || $12 || $18, $14 || $19, $15, $17
693 link = nil
693 link = nil
694 if project_identifier
694 if project_identifier
695 project = Project.visible.find_by_identifier(project_identifier)
695 project = Project.visible.find_by_identifier(project_identifier)
696 end
696 end
697 if esc.nil?
697 if esc.nil?
698 if prefix.nil? && sep == 'r'
698 if prefix.nil? && sep == 'r'
699 if project
699 if project
700 repository = nil
700 repository = nil
701 if repo_identifier
701 if repo_identifier
702 repository = project.repositories.detect {|repo| repo.identifier == repo_identifier}
702 repository = project.repositories.detect {|repo| repo.identifier == repo_identifier}
703 else
703 else
704 repository = project.repository
704 repository = project.repository
705 end
705 end
706 # project.changesets.visible raises an SQL error because of a double join on repositories
706 # project.changesets.visible raises an SQL error because of a double join on repositories
707 if repository && (changeset = Changeset.visible.find_by_repository_id_and_revision(repository.id, identifier))
707 if repository && (changeset = Changeset.visible.find_by_repository_id_and_revision(repository.id, identifier))
708 link = link_to(h("#{project_prefix}#{repo_prefix}r#{identifier}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :repository_id => repository.identifier_param, :rev => changeset.revision},
708 link = link_to(h("#{project_prefix}#{repo_prefix}r#{identifier}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :repository_id => repository.identifier_param, :rev => changeset.revision},
709 :class => 'changeset',
709 :class => 'changeset',
710 :title => truncate_single_line(changeset.comments, :length => 100))
710 :title => truncate_single_line(changeset.comments, :length => 100))
711 end
711 end
712 end
712 end
713 elsif sep == '#'
713 elsif sep == '#'
714 oid = identifier.to_i
714 oid = identifier.to_i
715 case prefix
715 case prefix
716 when nil
716 when nil
717 if issue = Issue.visible.find_by_id(oid, :include => :status)
717 if issue = Issue.visible.find_by_id(oid, :include => :status)
718 anchor = comment_id ? "note-#{comment_id}" : nil
718 anchor = comment_id ? "note-#{comment_id}" : nil
719 link = link_to("##{oid}", {:only_path => only_path, :controller => 'issues', :action => 'show', :id => oid, :anchor => anchor},
719 link = link_to("##{oid}", {:only_path => only_path, :controller => 'issues', :action => 'show', :id => oid, :anchor => anchor},
720 :class => issue.css_classes,
720 :class => issue.css_classes,
721 :title => "#{truncate(issue.subject, :length => 100)} (#{issue.status.name})")
721 :title => "#{truncate(issue.subject, :length => 100)} (#{issue.status.name})")
722 end
722 end
723 when 'document'
723 when 'document'
724 if document = Document.visible.find_by_id(oid)
724 if document = Document.visible.find_by_id(oid)
725 link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document},
725 link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document},
726 :class => 'document'
726 :class => 'document'
727 end
727 end
728 when 'version'
728 when 'version'
729 if version = Version.visible.find_by_id(oid)
729 if version = Version.visible.find_by_id(oid)
730 link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
730 link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
731 :class => 'version'
731 :class => 'version'
732 end
732 end
733 when 'message'
733 when 'message'
734 if message = Message.visible.find_by_id(oid, :include => :parent)
734 if message = Message.visible.find_by_id(oid, :include => :parent)
735 link = link_to_message(message, {:only_path => only_path}, :class => 'message')
735 link = link_to_message(message, {:only_path => only_path}, :class => 'message')
736 end
736 end
737 when 'forum'
737 when 'forum'
738 if board = Board.visible.find_by_id(oid)
738 if board = Board.visible.find_by_id(oid)
739 link = link_to h(board.name), {:only_path => only_path, :controller => 'boards', :action => 'show', :id => board, :project_id => board.project},
739 link = link_to h(board.name), {:only_path => only_path, :controller => 'boards', :action => 'show', :id => board, :project_id => board.project},
740 :class => 'board'
740 :class => 'board'
741 end
741 end
742 when 'news'
742 when 'news'
743 if news = News.visible.find_by_id(oid)
743 if news = News.visible.find_by_id(oid)
744 link = link_to h(news.title), {:only_path => only_path, :controller => 'news', :action => 'show', :id => news},
744 link = link_to h(news.title), {:only_path => only_path, :controller => 'news', :action => 'show', :id => news},
745 :class => 'news'
745 :class => 'news'
746 end
746 end
747 when 'project'
747 when 'project'
748 if p = Project.visible.find_by_id(oid)
748 if p = Project.visible.find_by_id(oid)
749 link = link_to_project(p, {:only_path => only_path}, :class => 'project')
749 link = link_to_project(p, {:only_path => only_path}, :class => 'project')
750 end
750 end
751 end
751 end
752 elsif sep == ':'
752 elsif sep == ':'
753 # removes the double quotes if any
753 # removes the double quotes if any
754 name = identifier.gsub(%r{^"(.*)"$}, "\\1")
754 name = identifier.gsub(%r{^"(.*)"$}, "\\1")
755 case prefix
755 case prefix
756 when 'document'
756 when 'document'
757 if project && document = project.documents.visible.find_by_title(name)
757 if project && document = project.documents.visible.find_by_title(name)
758 link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document},
758 link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document},
759 :class => 'document'
759 :class => 'document'
760 end
760 end
761 when 'version'
761 when 'version'
762 if project && version = project.versions.visible.find_by_name(name)
762 if project && version = project.versions.visible.find_by_name(name)
763 link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
763 link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
764 :class => 'version'
764 :class => 'version'
765 end
765 end
766 when 'forum'
766 when 'forum'
767 if project && board = project.boards.visible.find_by_name(name)
767 if project && board = project.boards.visible.find_by_name(name)
768 link = link_to h(board.name), {:only_path => only_path, :controller => 'boards', :action => 'show', :id => board, :project_id => board.project},
768 link = link_to h(board.name), {:only_path => only_path, :controller => 'boards', :action => 'show', :id => board, :project_id => board.project},
769 :class => 'board'
769 :class => 'board'
770 end
770 end
771 when 'news'
771 when 'news'
772 if project && news = project.news.visible.find_by_title(name)
772 if project && news = project.news.visible.find_by_title(name)
773 link = link_to h(news.title), {:only_path => only_path, :controller => 'news', :action => 'show', :id => news},
773 link = link_to h(news.title), {:only_path => only_path, :controller => 'news', :action => 'show', :id => news},
774 :class => 'news'
774 :class => 'news'
775 end
775 end
776 when 'commit', 'source', 'export'
776 when 'commit', 'source', 'export'
777 if project
777 if project
778 repository = nil
778 repository = nil
779 if name =~ %r{^(([a-z0-9\-]+)\|)(.+)$}
779 if name =~ %r{^(([a-z0-9\-]+)\|)(.+)$}
780 repo_prefix, repo_identifier, name = $1, $2, $3
780 repo_prefix, repo_identifier, name = $1, $2, $3
781 repository = project.repositories.detect {|repo| repo.identifier == repo_identifier}
781 repository = project.repositories.detect {|repo| repo.identifier == repo_identifier}
782 else
782 else
783 repository = project.repository
783 repository = project.repository
784 end
784 end
785 if prefix == 'commit'
785 if prefix == 'commit'
786 if repository && (changeset = Changeset.visible.find(:first, :conditions => ["repository_id = ? AND scmid LIKE ?", repository.id, "#{name}%"]))
786 if repository && (changeset = Changeset.visible.find(:first, :conditions => ["repository_id = ? AND scmid LIKE ?", repository.id, "#{name}%"]))
787 link = link_to h("#{project_prefix}#{repo_prefix}#{name}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :repository_id => repository.identifier_param, :rev => changeset.identifier},
787 link = link_to h("#{project_prefix}#{repo_prefix}#{name}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :repository_id => repository.identifier_param, :rev => changeset.identifier},
788 :class => 'changeset',
788 :class => 'changeset',
789 :title => truncate_single_line(h(changeset.comments), :length => 100)
789 :title => truncate_single_line(h(changeset.comments), :length => 100)
790 end
790 end
791 else
791 else
792 if repository && User.current.allowed_to?(:browse_repository, project)
792 if repository && User.current.allowed_to?(:browse_repository, project)
793 name =~ %r{^[/\\]*(.*?)(@([0-9a-f]+))?(#(L\d+))?$}
793 name =~ %r{^[/\\]*(.*?)(@([0-9a-f]+))?(#(L\d+))?$}
794 path, rev, anchor = $1, $3, $5
794 path, rev, anchor = $1, $3, $5
795 link = link_to h("#{project_prefix}#{prefix}:#{repo_prefix}#{name}"), {:controller => 'repositories', :action => 'entry', :id => project, :repository_id => repository.identifier_param,
795 link = link_to h("#{project_prefix}#{prefix}:#{repo_prefix}#{name}"), {:controller => 'repositories', :action => 'entry', :id => project, :repository_id => repository.identifier_param,
796 :path => to_path_param(path),
796 :path => to_path_param(path),
797 :rev => rev,
797 :rev => rev,
798 :anchor => anchor,
798 :anchor => anchor,
799 :format => (prefix == 'export' ? 'raw' : nil)},
799 :format => (prefix == 'export' ? 'raw' : nil)},
800 :class => (prefix == 'export' ? 'source download' : 'source')
800 :class => (prefix == 'export' ? 'source download' : 'source')
801 end
801 end
802 end
802 end
803 repo_prefix = nil
803 repo_prefix = nil
804 end
804 end
805 when 'attachment'
805 when 'attachment'
806 attachments = options[:attachments] || (obj && obj.respond_to?(:attachments) ? obj.attachments : nil)
806 attachments = options[:attachments] || (obj && obj.respond_to?(:attachments) ? obj.attachments : nil)
807 if attachments && attachment = attachments.detect {|a| a.filename == name }
807 if attachments && attachment = attachments.detect {|a| a.filename == name }
808 link = link_to h(attachment.filename), {:only_path => only_path, :controller => 'attachments', :action => 'download', :id => attachment},
808 link = link_to h(attachment.filename), {:only_path => only_path, :controller => 'attachments', :action => 'download', :id => attachment},
809 :class => 'attachment'
809 :class => 'attachment'
810 end
810 end
811 when 'project'
811 when 'project'
812 if p = Project.visible.find(:first, :conditions => ["identifier = :s OR LOWER(name) = :s", {:s => name.downcase}])
812 if p = Project.visible.find(:first, :conditions => ["identifier = :s OR LOWER(name) = :s", {:s => name.downcase}])
813 link = link_to_project(p, {:only_path => only_path}, :class => 'project')
813 link = link_to_project(p, {:only_path => only_path}, :class => 'project')
814 end
814 end
815 end
815 end
816 end
816 end
817 end
817 end
818 (leading + (link || "#{project_prefix}#{prefix}#{repo_prefix}#{sep}#{identifier}#{comment_suffix}"))
818 (leading + (link || "#{project_prefix}#{prefix}#{repo_prefix}#{sep}#{identifier}#{comment_suffix}"))
819 end
819 end
820 end
820 end
821
821
822 HEADING_RE = /(<h(1|2|3|4)( [^>]+)?>(.+?)<\/h(1|2|3|4)>)/i unless const_defined?(:HEADING_RE)
822 HEADING_RE = /(<h(1|2|3|4)( [^>]+)?>(.+?)<\/h(1|2|3|4)>)/i unless const_defined?(:HEADING_RE)
823
823
824 def parse_sections(text, project, obj, attr, only_path, options)
824 def parse_sections(text, project, obj, attr, only_path, options)
825 return unless options[:edit_section_links]
825 return unless options[:edit_section_links]
826 text.gsub!(HEADING_RE) do
826 text.gsub!(HEADING_RE) do
827 heading = $1
827 heading = $1
828 @current_section += 1
828 @current_section += 1
829 if @current_section > 1
829 if @current_section > 1
830 content_tag('div',
830 content_tag('div',
831 link_to(image_tag('edit.png'), options[:edit_section_links].merge(:section => @current_section)),
831 link_to(image_tag('edit.png'), options[:edit_section_links].merge(:section => @current_section)),
832 :class => 'contextual',
832 :class => 'contextual',
833 :title => l(:button_edit_section)) + heading.html_safe
833 :title => l(:button_edit_section)) + heading.html_safe
834 else
834 else
835 heading
835 heading
836 end
836 end
837 end
837 end
838 end
838 end
839
839
840 # Headings and TOC
840 # Headings and TOC
841 # Adds ids and links to headings unless options[:headings] is set to false
841 # Adds ids and links to headings unless options[:headings] is set to false
842 def parse_headings(text, project, obj, attr, only_path, options)
842 def parse_headings(text, project, obj, attr, only_path, options)
843 return if options[:headings] == false
843 return if options[:headings] == false
844
844
845 text.gsub!(HEADING_RE) do
845 text.gsub!(HEADING_RE) do
846 level, attrs, content = $2.to_i, $3, $4
846 level, attrs, content = $2.to_i, $3, $4
847 item = strip_tags(content).strip
847 item = strip_tags(content).strip
848 anchor = sanitize_anchor_name(item)
848 anchor = sanitize_anchor_name(item)
849 # used for single-file wiki export
849 # used for single-file wiki export
850 anchor = "#{obj.page.title}_#{anchor}" if options[:wiki_links] == :anchor && (obj.is_a?(WikiContent) || obj.is_a?(WikiContent::Version))
850 anchor = "#{obj.page.title}_#{anchor}" if options[:wiki_links] == :anchor && (obj.is_a?(WikiContent) || obj.is_a?(WikiContent::Version))
851 @heading_anchors[anchor] ||= 0
851 @heading_anchors[anchor] ||= 0
852 idx = (@heading_anchors[anchor] += 1)
852 idx = (@heading_anchors[anchor] += 1)
853 if idx > 1
853 if idx > 1
854 anchor = "#{anchor}-#{idx}"
854 anchor = "#{anchor}-#{idx}"
855 end
855 end
856 @parsed_headings << [level, anchor, item]
856 @parsed_headings << [level, anchor, item]
857 "<a name=\"#{anchor}\"></a>\n<h#{level} #{attrs}>#{content}<a href=\"##{anchor}\" class=\"wiki-anchor\">&para;</a></h#{level}>"
857 "<a name=\"#{anchor}\"></a>\n<h#{level} #{attrs}>#{content}<a href=\"##{anchor}\" class=\"wiki-anchor\">&para;</a></h#{level}>"
858 end
858 end
859 end
859 end
860
860
861 MACROS_RE = /
861 MACROS_RE = /
862 (!)? # escaping
862 (!)? # escaping
863 (
863 (
864 \{\{ # opening tag
864 \{\{ # opening tag
865 ([\w]+) # macro name
865 ([\w]+) # macro name
866 (\(([^\}]*)\))? # optional arguments
866 (\(([^\}]*)\))? # optional arguments
867 \}\} # closing tag
867 \}\} # closing tag
868 )
868 )
869 /x unless const_defined?(:MACROS_RE)
869 /x unless const_defined?(:MACROS_RE)
870
870
871 # Macros substitution
871 # Macros substitution
872 def parse_macros(text, project, obj, attr, only_path, options)
872 def parse_macros(text, project, obj, attr, only_path, options)
873 text.gsub!(MACROS_RE) do
873 text.gsub!(MACROS_RE) do
874 esc, all, macro = $1, $2, $3.downcase
874 esc, all, macro = $1, $2, $3.downcase
875 args = ($5 || '').split(',').each(&:strip)
875 args = ($5 || '').split(',').each(&:strip)
876 if esc.nil?
876 if esc.nil?
877 begin
877 begin
878 exec_macro(macro, obj, args)
878 exec_macro(macro, obj, args)
879 rescue => e
879 rescue => e
880 "<div class=\"flash error\">Error executing the <strong>#{macro}</strong> macro (#{e})</div>"
880 "<div class=\"flash error\">Error executing the <strong>#{macro}</strong> macro (#{e})</div>"
881 end || all
881 end || all
882 else
882 else
883 all
883 all
884 end
884 end
885 end
885 end
886 end
886 end
887
887
888 TOC_RE = /<p>\{\{([<>]?)toc\}\}<\/p>/i unless const_defined?(:TOC_RE)
888 TOC_RE = /<p>\{\{([<>]?)toc\}\}<\/p>/i unless const_defined?(:TOC_RE)
889
889
890 # Renders the TOC with given headings
890 # Renders the TOC with given headings
891 def replace_toc(text, headings)
891 def replace_toc(text, headings)
892 text.gsub!(TOC_RE) do
892 text.gsub!(TOC_RE) do
893 if headings.empty?
893 if headings.empty?
894 ''
894 ''
895 else
895 else
896 div_class = 'toc'
896 div_class = 'toc'
897 div_class << ' right' if $1 == '>'
897 div_class << ' right' if $1 == '>'
898 div_class << ' left' if $1 == '<'
898 div_class << ' left' if $1 == '<'
899 out = "<ul class=\"#{div_class}\"><li>"
899 out = "<ul class=\"#{div_class}\"><li>"
900 root = headings.map(&:first).min
900 root = headings.map(&:first).min
901 current = root
901 current = root
902 started = false
902 started = false
903 headings.each do |level, anchor, item|
903 headings.each do |level, anchor, item|
904 if level > current
904 if level > current
905 out << '<ul><li>' * (level - current)
905 out << '<ul><li>' * (level - current)
906 elsif level < current
906 elsif level < current
907 out << "</li></ul>\n" * (current - level) + "</li><li>"
907 out << "</li></ul>\n" * (current - level) + "</li><li>"
908 elsif started
908 elsif started
909 out << '</li><li>'
909 out << '</li><li>'
910 end
910 end
911 out << "<a href=\"##{anchor}\">#{item}</a>"
911 out << "<a href=\"##{anchor}\">#{item}</a>"
912 current = level
912 current = level
913 started = true
913 started = true
914 end
914 end
915 out << '</li></ul>' * (current - root)
915 out << '</li></ul>' * (current - root)
916 out << '</li></ul>'
916 out << '</li></ul>'
917 end
917 end
918 end
918 end
919 end
919 end
920
920
921 # Same as Rails' simple_format helper without using paragraphs
921 # Same as Rails' simple_format helper without using paragraphs
922 def simple_format_without_paragraph(text)
922 def simple_format_without_paragraph(text)
923 text.to_s.
923 text.to_s.
924 gsub(/\r\n?/, "\n"). # \r\n and \r -> \n
924 gsub(/\r\n?/, "\n"). # \r\n and \r -> \n
925 gsub(/\n\n+/, "<br /><br />"). # 2+ newline -> 2 br
925 gsub(/\n\n+/, "<br /><br />"). # 2+ newline -> 2 br
926 gsub(/([^\n]\n)(?=[^\n])/, '\1<br />'). # 1 newline -> br
926 gsub(/([^\n]\n)(?=[^\n])/, '\1<br />'). # 1 newline -> br
927 html_safe
927 html_safe
928 end
928 end
929
929
930 def lang_options_for_select(blank=true)
930 def lang_options_for_select(blank=true)
931 (blank ? [["(auto)", ""]] : []) +
931 (blank ? [["(auto)", ""]] : []) +
932 valid_languages.collect{|lang| [ ll(lang.to_s, :general_lang_name), lang.to_s]}.sort{|x,y| x.last <=> y.last }
932 valid_languages.collect{|lang| [ ll(lang.to_s, :general_lang_name), lang.to_s]}.sort{|x,y| x.last <=> y.last }
933 end
933 end
934
934
935 def label_tag_for(name, option_tags = nil, options = {})
935 def label_tag_for(name, option_tags = nil, options = {})
936 label_text = l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) + (options.delete(:required) ? @template.content_tag("span", " *", :class => "required"): "")
936 label_text = l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) + (options.delete(:required) ? @template.content_tag("span", " *", :class => "required"): "")
937 content_tag("label", label_text)
937 content_tag("label", label_text)
938 end
938 end
939
939
940 def labelled_tabular_form_for(*args, &proc)
940 def labelled_tabular_form_for(*args, &proc)
941 ActiveSupport::Deprecation.warn "ApplicationHelper#labelled_tabular_form_for is deprecated and will be removed in Redmine 1.5. Use #labelled_form_for instead."
941 ActiveSupport::Deprecation.warn "ApplicationHelper#labelled_tabular_form_for is deprecated and will be removed in Redmine 1.5. Use #labelled_form_for instead."
942 args << {} unless args.last.is_a?(Hash)
942 args << {} unless args.last.is_a?(Hash)
943 options = args.last
943 options = args.last
944 options[:html] ||= {}
944 options[:html] ||= {}
945 options[:html][:class] = 'tabular' unless options[:html].has_key?(:class)
945 options[:html][:class] = 'tabular' unless options[:html].has_key?(:class)
946 options.merge!({:builder => Redmine::Views::LabelledFormBuilder})
946 options.merge!({:builder => Redmine::Views::LabelledFormBuilder})
947 form_for(*args, &proc)
947 form_for(*args, &proc)
948 end
948 end
949
949
950 def labelled_form_for(*args, &proc)
950 def labelled_form_for(*args, &proc)
951 args << {} unless args.last.is_a?(Hash)
951 args << {} unless args.last.is_a?(Hash)
952 options = args.last
952 options = args.last
953 if args.first.is_a?(Symbol)
953 if args.first.is_a?(Symbol)
954 options.merge!(:as => args.shift)
954 options.merge!(:as => args.shift)
955 end
955 end
956 options.merge!({:builder => Redmine::Views::LabelledFormBuilder})
956 options.merge!({:builder => Redmine::Views::LabelledFormBuilder})
957 form_for(*args, &proc)
957 form_for(*args, &proc)
958 end
958 end
959
959
960 def labelled_fields_for(*args, &proc)
960 def labelled_fields_for(*args, &proc)
961 args << {} unless args.last.is_a?(Hash)
961 args << {} unless args.last.is_a?(Hash)
962 options = args.last
962 options = args.last
963 options.merge!({:builder => Redmine::Views::LabelledFormBuilder})
963 options.merge!({:builder => Redmine::Views::LabelledFormBuilder})
964 fields_for(*args, &proc)
964 fields_for(*args, &proc)
965 end
965 end
966
966
967 def labelled_remote_form_for(*args, &proc)
967 def labelled_remote_form_for(*args, &proc)
968 args << {} unless args.last.is_a?(Hash)
968 args << {} unless args.last.is_a?(Hash)
969 options = args.last
969 options = args.last
970 options.merge!({:builder => Redmine::Views::LabelledFormBuilder, :remote => true})
970 options.merge!({:builder => Redmine::Views::LabelledFormBuilder, :remote => true})
971 form_for(*args, &proc)
971 form_for(*args, &proc)
972 end
972 end
973
973
974 def error_messages_for(*objects)
974 def error_messages_for(*objects)
975 html = ""
975 html = ""
976 objects = objects.map {|o| o.is_a?(String) ? instance_variable_get("@#{o}") : o}.compact
976 objects = objects.map {|o| o.is_a?(String) ? instance_variable_get("@#{o}") : o}.compact
977 errors = objects.map {|o| o.errors.full_messages}.flatten
977 errors = objects.map {|o| o.errors.full_messages}.flatten
978 if errors.any?
978 if errors.any?
979 html << "<div id='errorExplanation'><ul>\n"
979 html << "<div id='errorExplanation'><ul>\n"
980 errors.each do |error|
980 errors.each do |error|
981 html << "<li>#{h error}</li>\n"
981 html << "<li>#{h error}</li>\n"
982 end
982 end
983 html << "</ul></div>\n"
983 html << "</ul></div>\n"
984 end
984 end
985 html.html_safe
985 html.html_safe
986 end
986 end
987
987
988 def delete_link(url, options={})
989 options = {
990 :method => :delete,
991 :data => {:confirm => l(:text_are_you_sure)},
992 :class => 'icon icon-del'
993 }.merge(options)
994
995 link_to l(:button_delete), url, options
996 end
997
988 def back_url_hidden_field_tag
998 def back_url_hidden_field_tag
989 back_url = params[:back_url] || request.env['HTTP_REFERER']
999 back_url = params[:back_url] || request.env['HTTP_REFERER']
990 back_url = CGI.unescape(back_url.to_s)
1000 back_url = CGI.unescape(back_url.to_s)
991 hidden_field_tag('back_url', CGI.escape(back_url), :id => nil) unless back_url.blank?
1001 hidden_field_tag('back_url', CGI.escape(back_url), :id => nil) unless back_url.blank?
992 end
1002 end
993
1003
994 def check_all_links(form_name)
1004 def check_all_links(form_name)
995 link_to_function(l(:button_check_all), "checkAll('#{form_name}', true)") +
1005 link_to_function(l(:button_check_all), "checkAll('#{form_name}', true)") +
996 " | ".html_safe +
1006 " | ".html_safe +
997 link_to_function(l(:button_uncheck_all), "checkAll('#{form_name}', false)")
1007 link_to_function(l(:button_uncheck_all), "checkAll('#{form_name}', false)")
998 end
1008 end
999
1009
1000 def progress_bar(pcts, options={})
1010 def progress_bar(pcts, options={})
1001 pcts = [pcts, pcts] unless pcts.is_a?(Array)
1011 pcts = [pcts, pcts] unless pcts.is_a?(Array)
1002 pcts = pcts.collect(&:round)
1012 pcts = pcts.collect(&:round)
1003 pcts[1] = pcts[1] - pcts[0]
1013 pcts[1] = pcts[1] - pcts[0]
1004 pcts << (100 - pcts[1] - pcts[0])
1014 pcts << (100 - pcts[1] - pcts[0])
1005 width = options[:width] || '100px;'
1015 width = options[:width] || '100px;'
1006 legend = options[:legend] || ''
1016 legend = options[:legend] || ''
1007 content_tag('table',
1017 content_tag('table',
1008 content_tag('tr',
1018 content_tag('tr',
1009 (pcts[0] > 0 ? content_tag('td', '', :style => "width: #{pcts[0]}%;", :class => 'closed') : ''.html_safe) +
1019 (pcts[0] > 0 ? content_tag('td', '', :style => "width: #{pcts[0]}%;", :class => 'closed') : ''.html_safe) +
1010 (pcts[1] > 0 ? content_tag('td', '', :style => "width: #{pcts[1]}%;", :class => 'done') : ''.html_safe) +
1020 (pcts[1] > 0 ? content_tag('td', '', :style => "width: #{pcts[1]}%;", :class => 'done') : ''.html_safe) +
1011 (pcts[2] > 0 ? content_tag('td', '', :style => "width: #{pcts[2]}%;", :class => 'todo') : ''.html_safe)
1021 (pcts[2] > 0 ? content_tag('td', '', :style => "width: #{pcts[2]}%;", :class => 'todo') : ''.html_safe)
1012 ), :class => 'progress', :style => "width: #{width};").html_safe +
1022 ), :class => 'progress', :style => "width: #{width};").html_safe +
1013 content_tag('p', legend, :class => 'pourcent').html_safe
1023 content_tag('p', legend, :class => 'pourcent').html_safe
1014 end
1024 end
1015
1025
1016 def checked_image(checked=true)
1026 def checked_image(checked=true)
1017 if checked
1027 if checked
1018 image_tag 'toggle_check.png'
1028 image_tag 'toggle_check.png'
1019 end
1029 end
1020 end
1030 end
1021
1031
1022 def context_menu(url)
1032 def context_menu(url)
1023 unless @context_menu_included
1033 unless @context_menu_included
1024 content_for :header_tags do
1034 content_for :header_tags do
1025 javascript_include_tag('context_menu') +
1035 javascript_include_tag('context_menu') +
1026 stylesheet_link_tag('context_menu')
1036 stylesheet_link_tag('context_menu')
1027 end
1037 end
1028 if l(:direction) == 'rtl'
1038 if l(:direction) == 'rtl'
1029 content_for :header_tags do
1039 content_for :header_tags do
1030 stylesheet_link_tag('context_menu_rtl')
1040 stylesheet_link_tag('context_menu_rtl')
1031 end
1041 end
1032 end
1042 end
1033 @context_menu_included = true
1043 @context_menu_included = true
1034 end
1044 end
1035 javascript_tag "new ContextMenu('#{ url_for(url) }')"
1045 javascript_tag "new ContextMenu('#{ url_for(url) }')"
1036 end
1046 end
1037
1047
1038 def calendar_for(field_id)
1048 def calendar_for(field_id)
1039 include_calendar_headers_tags
1049 include_calendar_headers_tags
1040 image_tag("calendar.png", {:id => "#{field_id}_trigger",:class => "calendar-trigger"}) +
1050 image_tag("calendar.png", {:id => "#{field_id}_trigger",:class => "calendar-trigger"}) +
1041 javascript_tag("Calendar.setup({inputField : '#{field_id}', ifFormat : '%Y-%m-%d', button : '#{field_id}_trigger' });")
1051 javascript_tag("Calendar.setup({inputField : '#{field_id}', ifFormat : '%Y-%m-%d', button : '#{field_id}_trigger' });")
1042 end
1052 end
1043
1053
1044 def include_calendar_headers_tags
1054 def include_calendar_headers_tags
1045 unless @calendar_headers_tags_included
1055 unless @calendar_headers_tags_included
1046 @calendar_headers_tags_included = true
1056 @calendar_headers_tags_included = true
1047 content_for :header_tags do
1057 content_for :header_tags do
1048 start_of_week = case Setting.start_of_week.to_i
1058 start_of_week = case Setting.start_of_week.to_i
1049 when 1
1059 when 1
1050 'Calendar._FD = 1;' # Monday
1060 'Calendar._FD = 1;' # Monday
1051 when 7
1061 when 7
1052 'Calendar._FD = 0;' # Sunday
1062 'Calendar._FD = 0;' # Sunday
1053 when 6
1063 when 6
1054 'Calendar._FD = 6;' # Saturday
1064 'Calendar._FD = 6;' # Saturday
1055 else
1065 else
1056 '' # use language
1066 '' # use language
1057 end
1067 end
1058
1068
1059 javascript_include_tag('calendar/calendar') +
1069 javascript_include_tag('calendar/calendar') +
1060 javascript_include_tag("calendar/lang/calendar-#{current_language.to_s.downcase}.js") +
1070 javascript_include_tag("calendar/lang/calendar-#{current_language.to_s.downcase}.js") +
1061 javascript_tag(start_of_week) +
1071 javascript_tag(start_of_week) +
1062 javascript_include_tag('calendar/calendar-setup') +
1072 javascript_include_tag('calendar/calendar-setup') +
1063 stylesheet_link_tag('calendar')
1073 stylesheet_link_tag('calendar')
1064 end
1074 end
1065 end
1075 end
1066 end
1076 end
1067
1077
1068 # Overrides Rails' stylesheet_link_tag with themes and plugins support.
1078 # Overrides Rails' stylesheet_link_tag with themes and plugins support.
1069 # Examples:
1079 # Examples:
1070 # stylesheet_link_tag('styles') # => picks styles.css from the current theme or defaults
1080 # stylesheet_link_tag('styles') # => picks styles.css from the current theme or defaults
1071 # stylesheet_link_tag('styles', :plugin => 'foo) # => picks styles.css from plugin's assets
1081 # stylesheet_link_tag('styles', :plugin => 'foo) # => picks styles.css from plugin's assets
1072 #
1082 #
1073 def stylesheet_link_tag(*sources)
1083 def stylesheet_link_tag(*sources)
1074 options = sources.last.is_a?(Hash) ? sources.pop : {}
1084 options = sources.last.is_a?(Hash) ? sources.pop : {}
1075 plugin = options.delete(:plugin)
1085 plugin = options.delete(:plugin)
1076 sources = sources.map do |source|
1086 sources = sources.map do |source|
1077 if plugin
1087 if plugin
1078 "/plugin_assets/#{plugin}/stylesheets/#{source}"
1088 "/plugin_assets/#{plugin}/stylesheets/#{source}"
1079 elsif current_theme && current_theme.stylesheets.include?(source)
1089 elsif current_theme && current_theme.stylesheets.include?(source)
1080 current_theme.stylesheet_path(source)
1090 current_theme.stylesheet_path(source)
1081 else
1091 else
1082 source
1092 source
1083 end
1093 end
1084 end
1094 end
1085 super sources, options
1095 super sources, options
1086 end
1096 end
1087
1097
1088 # Overrides Rails' image_tag with themes and plugins support.
1098 # Overrides Rails' image_tag with themes and plugins support.
1089 # Examples:
1099 # Examples:
1090 # image_tag('image.png') # => picks image.png from the current theme or defaults
1100 # image_tag('image.png') # => picks image.png from the current theme or defaults
1091 # image_tag('image.png', :plugin => 'foo) # => picks image.png from plugin's assets
1101 # image_tag('image.png', :plugin => 'foo) # => picks image.png from plugin's assets
1092 #
1102 #
1093 def image_tag(source, options={})
1103 def image_tag(source, options={})
1094 if plugin = options.delete(:plugin)
1104 if plugin = options.delete(:plugin)
1095 source = "/plugin_assets/#{plugin}/images/#{source}"
1105 source = "/plugin_assets/#{plugin}/images/#{source}"
1096 elsif current_theme && current_theme.images.include?(source)
1106 elsif current_theme && current_theme.images.include?(source)
1097 source = current_theme.image_path(source)
1107 source = current_theme.image_path(source)
1098 end
1108 end
1099 super source, options
1109 super source, options
1100 end
1110 end
1101
1111
1102 # Overrides Rails' javascript_include_tag with plugins support
1112 # Overrides Rails' javascript_include_tag with plugins support
1103 # Examples:
1113 # Examples:
1104 # javascript_include_tag('scripts') # => picks scripts.js from defaults
1114 # javascript_include_tag('scripts') # => picks scripts.js from defaults
1105 # javascript_include_tag('scripts', :plugin => 'foo) # => picks scripts.js from plugin's assets
1115 # javascript_include_tag('scripts', :plugin => 'foo) # => picks scripts.js from plugin's assets
1106 #
1116 #
1107 def javascript_include_tag(*sources)
1117 def javascript_include_tag(*sources)
1108 options = sources.last.is_a?(Hash) ? sources.pop : {}
1118 options = sources.last.is_a?(Hash) ? sources.pop : {}
1109 if plugin = options.delete(:plugin)
1119 if plugin = options.delete(:plugin)
1110 sources = sources.map do |source|
1120 sources = sources.map do |source|
1111 if plugin
1121 if plugin
1112 "/plugin_assets/#{plugin}/javascripts/#{source}"
1122 "/plugin_assets/#{plugin}/javascripts/#{source}"
1113 else
1123 else
1114 source
1124 source
1115 end
1125 end
1116 end
1126 end
1117 end
1127 end
1118 super sources, options
1128 super sources, options
1119 end
1129 end
1120
1130
1121 def content_for(name, content = nil, &block)
1131 def content_for(name, content = nil, &block)
1122 @has_content ||= {}
1132 @has_content ||= {}
1123 @has_content[name] = true
1133 @has_content[name] = true
1124 super(name, content, &block)
1134 super(name, content, &block)
1125 end
1135 end
1126
1136
1127 def has_content?(name)
1137 def has_content?(name)
1128 (@has_content && @has_content[name]) || false
1138 (@has_content && @has_content[name]) || false
1129 end
1139 end
1130
1140
1131 def sidebar_content?
1141 def sidebar_content?
1132 has_content?(:sidebar) || view_layouts_base_sidebar_hook_response.present?
1142 has_content?(:sidebar) || view_layouts_base_sidebar_hook_response.present?
1133 end
1143 end
1134
1144
1135 def view_layouts_base_sidebar_hook_response
1145 def view_layouts_base_sidebar_hook_response
1136 @view_layouts_base_sidebar_hook_response ||= call_hook(:view_layouts_base_sidebar)
1146 @view_layouts_base_sidebar_hook_response ||= call_hook(:view_layouts_base_sidebar)
1137 end
1147 end
1138
1148
1139 def email_delivery_enabled?
1149 def email_delivery_enabled?
1140 !!ActionMailer::Base.perform_deliveries
1150 !!ActionMailer::Base.perform_deliveries
1141 end
1151 end
1142
1152
1143 # Returns the avatar image tag for the given +user+ if avatars are enabled
1153 # Returns the avatar image tag for the given +user+ if avatars are enabled
1144 # +user+ can be a User or a string that will be scanned for an email address (eg. 'joe <joe@foo.bar>')
1154 # +user+ can be a User or a string that will be scanned for an email address (eg. 'joe <joe@foo.bar>')
1145 def avatar(user, options = { })
1155 def avatar(user, options = { })
1146 if Setting.gravatar_enabled?
1156 if Setting.gravatar_enabled?
1147 options.merge!({:ssl => (request && request.ssl?), :default => Setting.gravatar_default})
1157 options.merge!({:ssl => (request && request.ssl?), :default => Setting.gravatar_default})
1148 email = nil
1158 email = nil
1149 if user.respond_to?(:mail)
1159 if user.respond_to?(:mail)
1150 email = user.mail
1160 email = user.mail
1151 elsif user.to_s =~ %r{<(.+?)>}
1161 elsif user.to_s =~ %r{<(.+?)>}
1152 email = $1
1162 email = $1
1153 end
1163 end
1154 return gravatar(email.to_s.downcase, options) unless email.blank? rescue nil
1164 return gravatar(email.to_s.downcase, options) unless email.blank? rescue nil
1155 else
1165 else
1156 ''
1166 ''
1157 end
1167 end
1158 end
1168 end
1159
1169
1160 def sanitize_anchor_name(anchor)
1170 def sanitize_anchor_name(anchor)
1161 anchor.gsub(%r{[^\w\s\-]}, '').gsub(%r{\s+(\-+\s*)?}, '-')
1171 anchor.gsub(%r{[^\w\s\-]}, '').gsub(%r{\s+(\-+\s*)?}, '-')
1162 end
1172 end
1163
1173
1164 # Returns the javascript tags that are included in the html layout head
1174 # Returns the javascript tags that are included in the html layout head
1165 def javascript_heads
1175 def javascript_heads
1166 tags = javascript_include_tag('prototype', 'effects', 'dragdrop', 'controls', 'rails', 'application')
1176 tags = javascript_include_tag('prototype', 'effects', 'dragdrop', 'controls', 'rails', 'application')
1167 unless User.current.pref.warn_on_leaving_unsaved == '0'
1177 unless User.current.pref.warn_on_leaving_unsaved == '0'
1168 tags << "\n".html_safe + javascript_tag("Event.observe(window, 'load', function(){ new WarnLeavingUnsaved('#{escape_javascript( l(:text_warn_on_leaving_unsaved) )}'); });")
1178 tags << "\n".html_safe + javascript_tag("Event.observe(window, 'load', function(){ new WarnLeavingUnsaved('#{escape_javascript( l(:text_warn_on_leaving_unsaved) )}'); });")
1169 end
1179 end
1170 tags
1180 tags
1171 end
1181 end
1172
1182
1173 def favicon
1183 def favicon
1174 "<link rel='shortcut icon' href='#{image_path('/favicon.ico')}' />".html_safe
1184 "<link rel='shortcut icon' href='#{image_path('/favicon.ico')}' />".html_safe
1175 end
1185 end
1176
1186
1177 def robot_exclusion_tag
1187 def robot_exclusion_tag
1178 '<meta name="robots" content="noindex,follow,noarchive" />'.html_safe
1188 '<meta name="robots" content="noindex,follow,noarchive" />'.html_safe
1179 end
1189 end
1180
1190
1181 # Returns true if arg is expected in the API response
1191 # Returns true if arg is expected in the API response
1182 def include_in_api_response?(arg)
1192 def include_in_api_response?(arg)
1183 unless @included_in_api_response
1193 unless @included_in_api_response
1184 param = params[:include]
1194 param = params[:include]
1185 @included_in_api_response = param.is_a?(Array) ? param.collect(&:to_s) : param.to_s.split(',')
1195 @included_in_api_response = param.is_a?(Array) ? param.collect(&:to_s) : param.to_s.split(',')
1186 @included_in_api_response.collect!(&:strip)
1196 @included_in_api_response.collect!(&:strip)
1187 end
1197 end
1188 @included_in_api_response.include?(arg.to_s)
1198 @included_in_api_response.include?(arg.to_s)
1189 end
1199 end
1190
1200
1191 # Returns options or nil if nometa param or X-Redmine-Nometa header
1201 # Returns options or nil if nometa param or X-Redmine-Nometa header
1192 # was set in the request
1202 # was set in the request
1193 def api_meta(options)
1203 def api_meta(options)
1194 if params[:nometa].present? || request.headers['X-Redmine-Nometa']
1204 if params[:nometa].present? || request.headers['X-Redmine-Nometa']
1195 # compatibility mode for activeresource clients that raise
1205 # compatibility mode for activeresource clients that raise
1196 # an error when unserializing an array with attributes
1206 # an error when unserializing an array with attributes
1197 nil
1207 nil
1198 else
1208 else
1199 options
1209 options
1200 end
1210 end
1201 end
1211 end
1202
1212
1203 private
1213 private
1204
1214
1205 def wiki_helper
1215 def wiki_helper
1206 helper = Redmine::WikiFormatting.helper_for(Setting.text_formatting)
1216 helper = Redmine::WikiFormatting.helper_for(Setting.text_formatting)
1207 extend helper
1217 extend helper
1208 return self
1218 return self
1209 end
1219 end
1210
1220
1211 def link_to_content_update(text, url_params = {}, html_options = {})
1221 def link_to_content_update(text, url_params = {}, html_options = {})
1212 link_to(text, url_params, html_options)
1222 link_to(text, url_params, html_options)
1213 end
1223 end
1214 end
1224 end
@@ -1,45 +1,45
1 <div class="contextual">
1 <div class="contextual">
2 <%= link_to l(:label_project_new), {:controller => 'projects', :action => 'new'}, :class => 'icon icon-add' %>
2 <%= link_to l(:label_project_new), {:controller => 'projects', :action => 'new'}, :class => 'icon icon-add' %>
3 </div>
3 </div>
4
4
5 <h2><%=l(:label_project_plural)%></h2>
5 <h2><%=l(:label_project_plural)%></h2>
6
6
7 <%= form_tag({}, :method => :get) do %>
7 <%= form_tag({}, :method => :get) do %>
8 <fieldset><legend><%= l(:label_filter_plural) %></legend>
8 <fieldset><legend><%= l(:label_filter_plural) %></legend>
9 <label for='status'><%= l(:field_status) %> :</label>
9 <label for='status'><%= l(:field_status) %> :</label>
10 <%= select_tag 'status', project_status_options_for_select(@status), :class => "small", :onchange => "this.form.submit(); return false;" %>
10 <%= select_tag 'status', project_status_options_for_select(@status), :class => "small", :onchange => "this.form.submit(); return false;" %>
11 <label for='name'><%= l(:label_project) %>:</label>
11 <label for='name'><%= l(:label_project) %>:</label>
12 <%= text_field_tag 'name', params[:name], :size => 30 %>
12 <%= text_field_tag 'name', params[:name], :size => 30 %>
13 <%= submit_tag l(:button_apply), :class => "small", :name => nil %>
13 <%= submit_tag l(:button_apply), :class => "small", :name => nil %>
14 <%= link_to l(:button_clear), {:controller => 'admin', :action => 'projects'}, :class => 'icon icon-reload' %>
14 <%= link_to l(:button_clear), {:controller => 'admin', :action => 'projects'}, :class => 'icon icon-reload' %>
15 </fieldset>
15 </fieldset>
16 <% end %>
16 <% end %>
17 &nbsp;
17 &nbsp;
18
18
19 <div class="autoscroll">
19 <div class="autoscroll">
20 <table class="list">
20 <table class="list">
21 <thead><tr>
21 <thead><tr>
22 <th><%=l(:label_project)%></th>
22 <th><%=l(:label_project)%></th>
23 <th><%=l(:field_is_public)%></th>
23 <th><%=l(:field_is_public)%></th>
24 <th><%=l(:field_created_on)%></th>
24 <th><%=l(:field_created_on)%></th>
25 <th></th>
25 <th></th>
26 </tr></thead>
26 </tr></thead>
27 <tbody>
27 <tbody>
28 <% project_tree(@projects) do |project, level| %>
28 <% project_tree(@projects) do |project, level| %>
29 <tr class="<%= cycle("odd", "even") %> <%= project.css_classes %> <%= level > 0 ? "idnt idnt-#{level}" : nil %>">
29 <tr class="<%= cycle("odd", "even") %> <%= project.css_classes %> <%= level > 0 ? "idnt idnt-#{level}" : nil %>">
30 <td class="name"><span><%= link_to_project(project, {:action => (project.active? ? 'settings' : 'show')}, :title => project.short_description) %></span></td>
30 <td class="name"><span><%= link_to_project(project, {:action => (project.active? ? 'settings' : 'show')}, :title => project.short_description) %></span></td>
31 <td align="center"><%= checked_image project.is_public? %></td>
31 <td align="center"><%= checked_image project.is_public? %></td>
32 <td align="center"><%= format_date(project.created_on) %></td>
32 <td align="center"><%= format_date(project.created_on) %></td>
33 <td class="buttons">
33 <td class="buttons">
34 <%= link_to(l(:button_archive), { :controller => 'projects', :action => 'archive', :id => project, :status => params[:status] }, :confirm => l(:text_are_you_sure), :method => :post, :class => 'icon icon-lock') unless project.archived? %>
34 <%= link_to(l(:button_archive), { :controller => 'projects', :action => 'archive', :id => project, :status => params[:status] }, :data => {:confirm => l(:text_are_you_sure)}, :method => :post, :class => 'icon icon-lock') unless project.archived? %>
35 <%= link_to(l(:button_unarchive), { :controller => 'projects', :action => 'unarchive', :id => project, :status => params[:status] }, :method => :post, :class => 'icon icon-unlock') if project.archived? && (project.parent.nil? || !project.parent.archived?) %>
35 <%= link_to(l(:button_unarchive), { :controller => 'projects', :action => 'unarchive', :id => project, :status => params[:status] }, :method => :post, :class => 'icon icon-unlock') if project.archived? && (project.parent.nil? || !project.parent.archived?) %>
36 <%= link_to(l(:button_copy), { :controller => 'projects', :action => 'copy', :id => project }, :class => 'icon icon-copy') %>
36 <%= link_to(l(:button_copy), { :controller => 'projects', :action => 'copy', :id => project }, :class => 'icon icon-copy') %>
37 <%= link_to(l(:button_delete), project_path(project), :method => :delete, :class => 'icon icon-del') %>
37 <%= link_to(l(:button_delete), project_path(project), :method => :delete, :class => 'icon icon-del') %>
38 </td>
38 </td>
39 </tr>
39 </tr>
40 <% end %>
40 <% end %>
41 </tbody>
41 </tbody>
42 </table>
42 </table>
43 </div>
43 </div>
44
44
45 <% html_title(l(:label_project_plural)) -%>
45 <% html_title(l(:label_project_plural)) -%>
@@ -1,33 +1,33
1 <div class="attachments">
1 <div class="attachments">
2 <% for attachment in attachments %>
2 <% for attachment in attachments %>
3 <p><%= link_to_attachment attachment, :class => 'icon icon-attachment', :download => true -%>
3 <p><%= link_to_attachment attachment, :class => 'icon icon-attachment', :download => true -%>
4 <% if attachment.is_text? %>
4 <% if attachment.is_text? %>
5 <%= link_to image_tag('magnifier.png'),
5 <%= link_to image_tag('magnifier.png'),
6 :controller => 'attachments', :action => 'show',
6 :controller => 'attachments', :action => 'show',
7 :id => attachment, :filename => attachment.filename %>
7 :id => attachment, :filename => attachment.filename %>
8 <% end %>
8 <% end %>
9 <%= h(" - #{attachment.description}") unless attachment.description.blank? %>
9 <%= h(" - #{attachment.description}") unless attachment.description.blank? %>
10 <span class="size">(<%= number_to_human_size attachment.filesize %>)</span>
10 <span class="size">(<%= number_to_human_size attachment.filesize %>)</span>
11 <% if options[:deletable] %>
11 <% if options[:deletable] %>
12 <%= link_to image_tag('delete.png'), attachment_path(attachment),
12 <%= link_to image_tag('delete.png'), attachment_path(attachment),
13 :confirm => l(:text_are_you_sure),
13 :data => {:confirm => l(:text_are_you_sure)},
14 :method => :delete,
14 :method => :delete,
15 :class => 'delete',
15 :class => 'delete',
16 :title => l(:button_delete) %>
16 :title => l(:button_delete) %>
17 <% end %>
17 <% end %>
18 <% if options[:author] %>
18 <% if options[:author] %>
19 <span class="author"><%= h(attachment.author) %>, <%= format_time(attachment.created_on) %></span>
19 <span class="author"><%= h(attachment.author) %>, <%= format_time(attachment.created_on) %></span>
20 <% end %>
20 <% end %>
21 </p>
21 </p>
22 <% end %>
22 <% end %>
23 <% if defined?(thumbnails) && thumbnails %>
23 <% if defined?(thumbnails) && thumbnails %>
24 <% images = attachments.select(&:thumbnailable?) %>
24 <% images = attachments.select(&:thumbnailable?) %>
25 <% if images.any? %>
25 <% if images.any? %>
26 <div class="thumbnails">
26 <div class="thumbnails">
27 <% images.each do |attachment| %>
27 <% images.each do |attachment| %>
28 <div><%= thumbnail_tag(attachment) %></div>
28 <div><%= thumbnail_tag(attachment) %></div>
29 <% end %>
29 <% end %>
30 </div>
30 </div>
31 <% end %>
31 <% end %>
32 <% end %>
32 <% end %>
33 </div>
33 </div>
@@ -1,35 +1,31
1 <div class="contextual">
1 <div class="contextual">
2 <%= link_to l(:label_auth_source_new), {:action => 'new'}, :class => 'icon icon-add' %>
2 <%= link_to l(:label_auth_source_new), {:action => 'new'}, :class => 'icon icon-add' %>
3 </div>
3 </div>
4
4
5 <h2><%=l(:label_auth_source_plural)%></h2>
5 <h2><%=l(:label_auth_source_plural)%></h2>
6
6
7 <table class="list">
7 <table class="list">
8 <thead><tr>
8 <thead><tr>
9 <th><%=l(:field_name)%></th>
9 <th><%=l(:field_name)%></th>
10 <th><%=l(:field_type)%></th>
10 <th><%=l(:field_type)%></th>
11 <th><%=l(:field_host)%></th>
11 <th><%=l(:field_host)%></th>
12 <th><%=l(:label_user_plural)%></th>
12 <th><%=l(:label_user_plural)%></th>
13 <th></th>
13 <th></th>
14 </tr></thead>
14 </tr></thead>
15 <tbody>
15 <tbody>
16 <% for source in @auth_sources %>
16 <% for source in @auth_sources %>
17 <tr id="auth-source-<%= source.id %>" class="<%= cycle("odd", "even") %>">
17 <tr id="auth-source-<%= source.id %>" class="<%= cycle("odd", "even") %>">
18 <td><%= link_to(h(source.name), :action => 'edit', :id => source)%></td>
18 <td><%= link_to(h(source.name), :action => 'edit', :id => source)%></td>
19 <td align="center"><%= h source.auth_method_name %></td>
19 <td align="center"><%= h source.auth_method_name %></td>
20 <td align="center"><%= h source.host %></td>
20 <td align="center"><%= h source.host %></td>
21 <td align="center"><%= h source.users.count %></td>
21 <td align="center"><%= h source.users.count %></td>
22 <td class="buttons">
22 <td class="buttons">
23 <%= link_to l(:button_test), {:action => 'test_connection', :id => source}, :class => 'icon icon-test' %>
23 <%= link_to l(:button_test), {:action => 'test_connection', :id => source}, :class => 'icon icon-test' %>
24 <%= link_to l(:button_delete), { :action => 'destroy', :id => source },
24 <%= delete_link auth_source_path(source) %>
25 :method => :delete,
26 :confirm => l(:text_are_you_sure),
27 :class => 'icon icon-del',
28 :disabled => source.users.any? %>
29 </td>
25 </td>
30 </tr>
26 </tr>
31 <% end %>
27 <% end %>
32 </tbody>
28 </tbody>
33 </table>
29 </table>
34
30
35 <p class="pagination"><%= pagination_links_full @auth_source_pages %></p>
31 <p class="pagination"><%= pagination_links_full @auth_source_pages %></p>
@@ -1,142 +1,142
1 <ul>
1 <ul>
2 <%= call_hook(:view_issues_context_menu_start, {:issues => @issues, :can => @can, :back => @back }) %>
2 <%= call_hook(:view_issues_context_menu_start, {:issues => @issues, :can => @can, :back => @back }) %>
3
3
4 <% if !@issue.nil? -%>
4 <% if !@issue.nil? -%>
5 <li><%= context_menu_link l(:button_edit), {:controller => 'issues', :action => 'edit', :id => @issue},
5 <li><%= context_menu_link l(:button_edit), {:controller => 'issues', :action => 'edit', :id => @issue},
6 :class => 'icon-edit', :disabled => !@can[:edit] %></li>
6 :class => 'icon-edit', :disabled => !@can[:edit] %></li>
7 <% else %>
7 <% else %>
8 <li><%= context_menu_link l(:button_edit), {:controller => 'issues', :action => 'bulk_edit', :ids => @issues.collect(&:id)},
8 <li><%= context_menu_link l(:button_edit), {:controller => 'issues', :action => 'bulk_edit', :ids => @issues.collect(&:id)},
9 :class => 'icon-edit', :disabled => !@can[:edit] %></li>
9 :class => 'icon-edit', :disabled => !@can[:edit] %></li>
10 <% end %>
10 <% end %>
11
11
12 <% if @allowed_statuses.present? %>
12 <% if @allowed_statuses.present? %>
13 <li class="folder">
13 <li class="folder">
14 <a href="#" class="submenu"><%= l(:field_status) %></a>
14 <a href="#" class="submenu"><%= l(:field_status) %></a>
15 <ul>
15 <ul>
16 <% @allowed_statuses.each do |s| -%>
16 <% @allowed_statuses.each do |s| -%>
17 <li><%= context_menu_link h(s.name), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {:status_id => s}, :back_url => @back}, :method => :post,
17 <li><%= context_menu_link h(s.name), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {:status_id => s}, :back_url => @back}, :method => :post,
18 :selected => (@issue && s == @issue.status), :disabled => !@can[:update] %></li>
18 :selected => (@issue && s == @issue.status), :disabled => !@can[:update] %></li>
19 <% end -%>
19 <% end -%>
20 </ul>
20 </ul>
21 </li>
21 </li>
22 <% end %>
22 <% end %>
23
23
24 <% unless @trackers.nil? %>
24 <% unless @trackers.nil? %>
25 <li class="folder">
25 <li class="folder">
26 <a href="#" class="submenu"><%= l(:field_tracker) %></a>
26 <a href="#" class="submenu"><%= l(:field_tracker) %></a>
27 <ul>
27 <ul>
28 <% @trackers.each do |t| -%>
28 <% @trackers.each do |t| -%>
29 <li><%= context_menu_link h(t.name), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'tracker_id' => t}, :back_url => @back}, :method => :post,
29 <li><%= context_menu_link h(t.name), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'tracker_id' => t}, :back_url => @back}, :method => :post,
30 :selected => (@issue && t == @issue.tracker), :disabled => !@can[:edit] %></li>
30 :selected => (@issue && t == @issue.tracker), :disabled => !@can[:edit] %></li>
31 <% end -%>
31 <% end -%>
32 </ul>
32 </ul>
33 </li>
33 </li>
34 <% end %>
34 <% end %>
35
35
36 <% if @safe_attributes.include?('priority_id') -%>
36 <% if @safe_attributes.include?('priority_id') -%>
37 <li class="folder">
37 <li class="folder">
38 <a href="#" class="submenu"><%= l(:field_priority) %></a>
38 <a href="#" class="submenu"><%= l(:field_priority) %></a>
39 <ul>
39 <ul>
40 <% @priorities.each do |p| -%>
40 <% @priorities.each do |p| -%>
41 <li><%= context_menu_link h(p.name), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'priority_id' => p}, :back_url => @back}, :method => :post,
41 <li><%= context_menu_link h(p.name), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'priority_id' => p}, :back_url => @back}, :method => :post,
42 :selected => (@issue && p == @issue.priority), :disabled => (!@can[:edit] || @issues.detect {|i| !i.leaf?}) %></li>
42 :selected => (@issue && p == @issue.priority), :disabled => (!@can[:edit] || @issues.detect {|i| !i.leaf?}) %></li>
43 <% end -%>
43 <% end -%>
44 </ul>
44 </ul>
45 </li>
45 </li>
46 <% end %>
46 <% end %>
47
47
48 <% #TODO: allow editing versions when multiple projects %>
48 <% #TODO: allow editing versions when multiple projects %>
49 <% if @safe_attributes.include?('fixed_version_id') && @project && @project.shared_versions.open.any? -%>
49 <% if @safe_attributes.include?('fixed_version_id') && @project && @project.shared_versions.open.any? -%>
50 <li class="folder">
50 <li class="folder">
51 <a href="#" class="submenu"><%= l(:field_fixed_version) %></a>
51 <a href="#" class="submenu"><%= l(:field_fixed_version) %></a>
52 <ul>
52 <ul>
53 <% @project.shared_versions.open.sort.each do |v| -%>
53 <% @project.shared_versions.open.sort.each do |v| -%>
54 <li><%= context_menu_link format_version_name(v), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'fixed_version_id' => v}, :back_url => @back}, :method => :post,
54 <li><%= context_menu_link format_version_name(v), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'fixed_version_id' => v}, :back_url => @back}, :method => :post,
55 :selected => (@issue && v == @issue.fixed_version), :disabled => !@can[:update] %></li>
55 :selected => (@issue && v == @issue.fixed_version), :disabled => !@can[:update] %></li>
56 <% end -%>
56 <% end -%>
57 <li><%= context_menu_link l(:label_none), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'fixed_version_id' => 'none'}, :back_url => @back}, :method => :post,
57 <li><%= context_menu_link l(:label_none), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'fixed_version_id' => 'none'}, :back_url => @back}, :method => :post,
58 :selected => (@issue && @issue.fixed_version.nil?), :disabled => !@can[:update] %></li>
58 :selected => (@issue && @issue.fixed_version.nil?), :disabled => !@can[:update] %></li>
59 </ul>
59 </ul>
60 </li>
60 </li>
61 <% end %>
61 <% end %>
62
62
63 <% if @safe_attributes.include?('assigned_to_id') && @assignables.present? -%>
63 <% if @safe_attributes.include?('assigned_to_id') && @assignables.present? -%>
64 <li class="folder">
64 <li class="folder">
65 <a href="#" class="submenu"><%= l(:field_assigned_to) %></a>
65 <a href="#" class="submenu"><%= l(:field_assigned_to) %></a>
66 <ul>
66 <ul>
67 <% if @assignables.include?(User.current) %>
67 <% if @assignables.include?(User.current) %>
68 <li><%= context_menu_link "<< #{l(:label_me)} >>", {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'assigned_to_id' => User.current}, :back_url => @back}, :method => :post,
68 <li><%= context_menu_link "<< #{l(:label_me)} >>", {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'assigned_to_id' => User.current}, :back_url => @back}, :method => :post,
69 :disabled => !@can[:update] %></li>
69 :disabled => !@can[:update] %></li>
70 <% end %>
70 <% end %>
71 <% @assignables.each do |u| -%>
71 <% @assignables.each do |u| -%>
72 <li><%= context_menu_link h(u.name), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'assigned_to_id' => u}, :back_url => @back}, :method => :post,
72 <li><%= context_menu_link h(u.name), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'assigned_to_id' => u}, :back_url => @back}, :method => :post,
73 :selected => (@issue && u == @issue.assigned_to), :disabled => !@can[:update] %></li>
73 :selected => (@issue && u == @issue.assigned_to), :disabled => !@can[:update] %></li>
74 <% end -%>
74 <% end -%>
75 <li><%= context_menu_link l(:label_nobody), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'assigned_to_id' => 'none'}, :back_url => @back}, :method => :post,
75 <li><%= context_menu_link l(:label_nobody), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'assigned_to_id' => 'none'}, :back_url => @back}, :method => :post,
76 :selected => (@issue && @issue.assigned_to.nil?), :disabled => !@can[:update] %></li>
76 :selected => (@issue && @issue.assigned_to.nil?), :disabled => !@can[:update] %></li>
77 </ul>
77 </ul>
78 </li>
78 </li>
79 <% end %>
79 <% end %>
80
80
81 <% if @safe_attributes.include?('category_id') && @project && @project.issue_categories.any? -%>
81 <% if @safe_attributes.include?('category_id') && @project && @project.issue_categories.any? -%>
82 <li class="folder">
82 <li class="folder">
83 <a href="#" class="submenu"><%= l(:field_category) %></a>
83 <a href="#" class="submenu"><%= l(:field_category) %></a>
84 <ul>
84 <ul>
85 <% @project.issue_categories.each do |u| -%>
85 <% @project.issue_categories.each do |u| -%>
86 <li><%= context_menu_link h(u.name), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'category_id' => u}, :back_url => @back}, :method => :post,
86 <li><%= context_menu_link h(u.name), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'category_id' => u}, :back_url => @back}, :method => :post,
87 :selected => (@issue && u == @issue.category), :disabled => !@can[:update] %></li>
87 :selected => (@issue && u == @issue.category), :disabled => !@can[:update] %></li>
88 <% end -%>
88 <% end -%>
89 <li><%= context_menu_link l(:label_none), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'category_id' => 'none'}, :back_url => @back}, :method => :post,
89 <li><%= context_menu_link l(:label_none), {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'category_id' => 'none'}, :back_url => @back}, :method => :post,
90 :selected => (@issue && @issue.category.nil?), :disabled => !@can[:update] %></li>
90 :selected => (@issue && @issue.category.nil?), :disabled => !@can[:update] %></li>
91 </ul>
91 </ul>
92 </li>
92 </li>
93 <% end -%>
93 <% end -%>
94
94
95 <% if @safe_attributes.include?('done_ratio') && Issue.use_field_for_done_ratio? %>
95 <% if @safe_attributes.include?('done_ratio') && Issue.use_field_for_done_ratio? %>
96 <li class="folder">
96 <li class="folder">
97 <a href="#" class="submenu"><%= l(:field_done_ratio) %></a>
97 <a href="#" class="submenu"><%= l(:field_done_ratio) %></a>
98 <ul>
98 <ul>
99 <% (0..10).map{|x|x*10}.each do |p| -%>
99 <% (0..10).map{|x|x*10}.each do |p| -%>
100 <li><%= context_menu_link "#{p}%", {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'done_ratio' => p}, :back_url => @back}, :method => :post,
100 <li><%= context_menu_link "#{p}%", {:controller => 'issues', :action => 'bulk_update', :ids => @issues.collect(&:id), :issue => {'done_ratio' => p}, :back_url => @back}, :method => :post,
101 :selected => (@issue && p == @issue.done_ratio), :disabled => (!@can[:edit] || @issues.detect {|i| !i.leaf?}) %></li>
101 :selected => (@issue && p == @issue.done_ratio), :disabled => (!@can[:edit] || @issues.detect {|i| !i.leaf?}) %></li>
102 <% end -%>
102 <% end -%>
103 </ul>
103 </ul>
104 </li>
104 </li>
105 <% end %>
105 <% end %>
106
106
107 <% @options_by_custom_field.each do |field, options| %>
107 <% @options_by_custom_field.each do |field, options| %>
108 <li class="folder">
108 <li class="folder">
109 <a href="#" class="submenu"><%= h(field.name) %></a>
109 <a href="#" class="submenu"><%= h(field.name) %></a>
110 <ul>
110 <ul>
111 <% options.each do |text, value| %>
111 <% options.each do |text, value| %>
112 <li><%= bulk_update_custom_field_context_menu_link(field, text, value || text) %></li>
112 <li><%= bulk_update_custom_field_context_menu_link(field, text, value || text) %></li>
113 <% end %>
113 <% end %>
114 <% unless field.is_required? %>
114 <% unless field.is_required? %>
115 <li><%= bulk_update_custom_field_context_menu_link(field, l(:label_none), '') %></li>
115 <li><%= bulk_update_custom_field_context_menu_link(field, l(:label_none), '') %></li>
116 <% end %>
116 <% end %>
117 </ul>
117 </ul>
118 </li>
118 </li>
119 <% end %>
119 <% end %>
120
120
121 <% if !@issue.nil? %>
121 <% if !@issue.nil? %>
122 <% if @can[:log_time] -%>
122 <% if @can[:log_time] -%>
123 <li><%= context_menu_link l(:button_log_time), {:controller => 'timelog', :action => 'new', :issue_id => @issue},
123 <li><%= context_menu_link l(:button_log_time), {:controller => 'timelog', :action => 'new', :issue_id => @issue},
124 :class => 'icon-time-add' %></li>
124 :class => 'icon-time-add' %></li>
125 <% end %>
125 <% end %>
126 <% if User.current.logged? %>
126 <% if User.current.logged? %>
127 <li><%= watcher_link(@issue, User.current) %></li>
127 <li><%= watcher_link(@issue, User.current) %></li>
128 <% end %>
128 <% end %>
129 <% end %>
129 <% end %>
130
130
131 <% if @issue.present? %>
131 <% if @issue.present? %>
132 <li><%= context_menu_link l(:button_copy), {:controller => 'issues', :action => 'new', :project_id => @project, :copy_from => @issue},
132 <li><%= context_menu_link l(:button_copy), {:controller => 'issues', :action => 'new', :project_id => @project, :copy_from => @issue},
133 :class => 'icon-copy', :disabled => !@can[:copy] %></li>
133 :class => 'icon-copy', :disabled => !@can[:copy] %></li>
134 <% else %>
134 <% else %>
135 <li><%= context_menu_link l(:button_copy), {:controller => 'issues', :action => 'bulk_edit', :ids => @issues.collect(&:id), :copy => '1'},
135 <li><%= context_menu_link l(:button_copy), {:controller => 'issues', :action => 'bulk_edit', :ids => @issues.collect(&:id), :copy => '1'},
136 :class => 'icon-copy', :disabled => !@can[:move] %></li>
136 :class => 'icon-copy', :disabled => !@can[:move] %></li>
137 <% end %>
137 <% end %>
138 <li><%= context_menu_link l(:button_delete), issues_path(:ids => @issues.collect(&:id), :back_url => @back),
138 <li><%= context_menu_link l(:button_delete), issues_path(:ids => @issues.collect(&:id), :back_url => @back),
139 :method => :delete, :confirm => issues_destroy_confirmation_message(@issues), :class => 'icon-del', :disabled => !@can[:delete] %></li>
139 :method => :delete, :data => {:confirm => issues_destroy_confirmation_message(@issues)}, :class => 'icon-del', :disabled => !@can[:delete] %></li>
140
140
141 <%= call_hook(:view_issues_context_menu_end, {:issues => @issues, :can => @can, :back => @back }) %>
141 <%= call_hook(:view_issues_context_menu_end, {:issues => @issues, :can => @can, :back => @back }) %>
142 </ul>
142 </ul>
@@ -1,33 +1,33
1 <ul>
1 <ul>
2 <% if !@time_entry.nil? -%>
2 <% if !@time_entry.nil? -%>
3 <li><%= context_menu_link l(:button_edit), {:controller => 'timelog', :action => 'edit', :id => @time_entry},
3 <li><%= context_menu_link l(:button_edit), {:controller => 'timelog', :action => 'edit', :id => @time_entry},
4 :class => 'icon-edit', :disabled => !@can[:edit] %></li>
4 :class => 'icon-edit', :disabled => !@can[:edit] %></li>
5 <% else %>
5 <% else %>
6 <li><%= context_menu_link l(:button_edit), {:controller => 'timelog', :action => 'bulk_edit', :ids => @time_entries.collect(&:id)},
6 <li><%= context_menu_link l(:button_edit), {:controller => 'timelog', :action => 'bulk_edit', :ids => @time_entries.collect(&:id)},
7 :class => 'icon-edit', :disabled => !@can[:edit] %></li>
7 :class => 'icon-edit', :disabled => !@can[:edit] %></li>
8 <% end %>
8 <% end %>
9
9
10 <%= call_hook(:view_time_entries_context_menu_start, {:time_entries => @time_entries, :can => @can, :back => @back }) %>
10 <%= call_hook(:view_time_entries_context_menu_start, {:time_entries => @time_entries, :can => @can, :back => @back }) %>
11
11
12 <% if @activities.present? -%>
12 <% if @activities.present? -%>
13 <li class="folder">
13 <li class="folder">
14 <a href="#" class="submenu"><%= l(:field_activity) %></a>
14 <a href="#" class="submenu"><%= l(:field_activity) %></a>
15 <ul>
15 <ul>
16 <% @activities.each do |u| -%>
16 <% @activities.each do |u| -%>
17 <li><%= context_menu_link h(u.name), {:controller => 'timelog', :action => 'bulk_update', :ids => @time_entries.collect(&:id), :time_entry => {'activity_id' => u}, :back_url => @back}, :method => :post,
17 <li><%= context_menu_link h(u.name), {:controller => 'timelog', :action => 'bulk_update', :ids => @time_entries.collect(&:id), :time_entry => {'activity_id' => u}, :back_url => @back}, :method => :post,
18 :selected => (@time_entry && u == @time_entry.activity), :disabled => !@can[:edit] %></li>
18 :selected => (@time_entry && u == @time_entry.activity), :disabled => !@can[:edit] %></li>
19 <% end -%>
19 <% end -%>
20 <li><%= context_menu_link l(:label_none), {:controller => 'timelog', :action => 'bulk_update', :ids => @time_entries.collect(&:id), :time_entry => {'activity_id' => 'none'}, :back_url => @back}, :method => :post,
20 <li><%= context_menu_link l(:label_none), {:controller => 'timelog', :action => 'bulk_update', :ids => @time_entries.collect(&:id), :time_entry => {'activity_id' => 'none'}, :back_url => @back}, :method => :post,
21 :selected => (@time_entry && @time_entry.activity.nil?), :disabled => !@can[:edit] %></li>
21 :selected => (@time_entry && @time_entry.activity.nil?), :disabled => !@can[:edit] %></li>
22 </ul>
22 </ul>
23 </li>
23 </li>
24 <% end %>
24 <% end %>
25
25
26 <%= call_hook(:view_time_entries_context_menu_end, {:time_entries => @time_entries, :can => @can, :back => @back }) %>
26 <%= call_hook(:view_time_entries_context_menu_end, {:time_entries => @time_entries, :can => @can, :back => @back }) %>
27
27
28 <li>
28 <li>
29 <%= context_menu_link l(:button_delete),
29 <%= context_menu_link l(:button_delete),
30 {:controller => 'timelog', :action => 'destroy', :ids => @time_entries.collect(&:id), :back_url => @back},
30 {:controller => 'timelog', :action => 'destroy', :ids => @time_entries.collect(&:id), :back_url => @back},
31 :method => :delete, :confirm => l(:text_time_entries_destroy_confirmation), :class => 'icon-del', :disabled => !@can[:delete] %>
31 :method => :delete, :data => {:confirm => l(:text_time_entries_destroy_confirmation)}, :class => 'icon-del', :disabled => !@can[:delete] %>
32 </li>
32 </li>
33 </ul>
33 </ul>
@@ -1,35 +1,32
1 <table class="list">
1 <table class="list">
2 <thead><tr>
2 <thead><tr>
3 <th width="30%"><%=l(:field_name)%></th>
3 <th width="30%"><%=l(:field_name)%></th>
4 <th><%=l(:field_field_format)%></th>
4 <th><%=l(:field_field_format)%></th>
5 <th><%=l(:field_is_required)%></th>
5 <th><%=l(:field_is_required)%></th>
6 <% if tab[:name] == 'IssueCustomField' %>
6 <% if tab[:name] == 'IssueCustomField' %>
7 <th><%=l(:field_is_for_all)%></th>
7 <th><%=l(:field_is_for_all)%></th>
8 <th><%=l(:label_used_by)%></th>
8 <th><%=l(:label_used_by)%></th>
9 <% end %>
9 <% end %>
10 <th><%=l(:button_sort)%></th>
10 <th><%=l(:button_sort)%></th>
11 <th width="10%"></th>
11 <th width="10%"></th>
12 </tr></thead>
12 </tr></thead>
13 <tbody>
13 <tbody>
14 <% (@custom_fields_by_type[tab[:name]] || []).sort.each do |custom_field| -%>
14 <% (@custom_fields_by_type[tab[:name]] || []).sort.each do |custom_field| -%>
15 <tr class="<%= cycle("odd", "even") %>">
15 <tr class="<%= cycle("odd", "even") %>">
16 <td><%= link_to h(custom_field.name), edit_custom_field_path(custom_field) %></td>
16 <td><%= link_to h(custom_field.name), edit_custom_field_path(custom_field) %></td>
17 <td align="center"><%= l(Redmine::CustomFieldFormat.label_for(custom_field.field_format)) %></td>
17 <td align="center"><%= l(Redmine::CustomFieldFormat.label_for(custom_field.field_format)) %></td>
18 <td align="center"><%= checked_image custom_field.is_required? %></td>
18 <td align="center"><%= checked_image custom_field.is_required? %></td>
19 <% if tab[:name] == 'IssueCustomField' %>
19 <% if tab[:name] == 'IssueCustomField' %>
20 <td align="center"><%= checked_image custom_field.is_for_all? %></td>
20 <td align="center"><%= checked_image custom_field.is_for_all? %></td>
21 <td align="center"><%= l(:label_x_projects, :count => custom_field.projects.count) if custom_field.is_a? IssueCustomField and !custom_field.is_for_all? %></td>
21 <td align="center"><%= l(:label_x_projects, :count => custom_field.projects.count) if custom_field.is_a? IssueCustomField and !custom_field.is_for_all? %></td>
22 <% end %>
22 <% end %>
23 <td align="center" style="width:15%;"><%= reorder_links('custom_field', {:action => 'update', :id => custom_field}, :put) %></td>
23 <td align="center" style="width:15%;"><%= reorder_links('custom_field', {:action => 'update', :id => custom_field}, :put) %></td>
24 <td class="buttons">
24 <td class="buttons">
25 <%= link_to(l(:button_delete), custom_field_path(custom_field),
25 <%= delete_link custom_field_path(custom_field) %>
26 :method => :delete,
27 :confirm => l(:text_are_you_sure),
28 :class => 'icon icon-del') %>
29 </td>
26 </td>
30 </tr>
27 </tr>
31 <% end; reset_cycle %>
28 <% end; reset_cycle %>
32 </tbody>
29 </tbody>
33 </table>
30 </table>
34
31
35 <p><%= link_to l(:label_custom_field_new), new_custom_field_path(:type => tab[:name]), :class => 'icon icon-add' %></p>
32 <p><%= link_to l(:label_custom_field_new), new_custom_field_path(:type => tab[:name]), :class => 'icon icon-add' %></p>
@@ -1,34 +1,34
1 <div class="contextual">
1 <div class="contextual">
2 <% if User.current.allowed_to?(:manage_documents, @project) %>
2 <% if User.current.allowed_to?(:manage_documents, @project) %>
3 <%= link_to l(:button_edit), edit_document_path(@document), :class => 'icon icon-edit', :accesskey => accesskey(:edit) %>
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' %>
4 <%= delete_link document_path(@document) %>
5 <% end %>
5 <% end %>
6 </div>
6 </div>
7
7
8 <h2><%=h @document.title %></h2>
8 <h2><%=h @document.title %></h2>
9
9
10 <p><em><%=h @document.category.name %><br />
10 <p><em><%=h @document.category.name %><br />
11 <%= format_date @document.created_on %></em></p>
11 <%= format_date @document.created_on %></em></p>
12 <div class="wiki">
12 <div class="wiki">
13 <%= textilizable @document.description, :attachments => @document.attachments %>
13 <%= textilizable @document.description, :attachments => @document.attachments %>
14 </div>
14 </div>
15
15
16 <h3><%= l(:label_attachment_plural) %></h3>
16 <h3><%= l(:label_attachment_plural) %></h3>
17 <%= link_to_attachments @document %>
17 <%= link_to_attachments @document %>
18
18
19 <% if authorize_for('documents', 'add_attachment') %>
19 <% if authorize_for('documents', 'add_attachment') %>
20 <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;",
21 :id => 'attach_files_link' %></p>
21 :id => 'attach_files_link' %></p>
22 <%= 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 %>
23 <div class="box">
23 <div class="box">
24 <p><%= render :partial => 'attachments/form' %></p>
24 <p><%= render :partial => 'attachments/form' %></p>
25 </div>
25 </div>
26 <%= submit_tag l(:button_add) %>
26 <%= submit_tag l(:button_add) %>
27 <% end %>
27 <% end %>
28 <% end %>
28 <% end %>
29
29
30 <% html_title @document.title -%>
30 <% html_title @document.title -%>
31
31
32 <% content_for :header_tags do %>
32 <% content_for :header_tags do %>
33 <%= stylesheet_link_tag 'scm' %>
33 <%= stylesheet_link_tag 'scm' %>
34 <% end %>
34 <% end %>
@@ -1,37 +1,34
1 <h2><%=l(:label_enumerations)%></h2>
1 <h2><%=l(:label_enumerations)%></h2>
2
2
3 <% Enumeration.get_subclasses.each do |klass| %>
3 <% Enumeration.get_subclasses.each do |klass| %>
4 <h3><%= l(klass::OptionName) %></h3>
4 <h3><%= l(klass::OptionName) %></h3>
5
5
6 <% enumerations = klass.shared %>
6 <% enumerations = klass.shared %>
7 <% if enumerations.any? %>
7 <% if enumerations.any? %>
8 <table class="list"><thead>
8 <table class="list"><thead>
9 <tr>
9 <tr>
10 <th><%= l(:field_name) %></th>
10 <th><%= l(:field_name) %></th>
11 <th style="width:15%;"><%= l(:field_is_default) %></th>
11 <th style="width:15%;"><%= l(:field_is_default) %></th>
12 <th style="width:15%;"><%= l(:field_active) %></th>
12 <th style="width:15%;"><%= l(:field_active) %></th>
13 <th style="width:15%;"></th>
13 <th style="width:15%;"></th>
14 <th align="center" style="width:10%;"> </th>
14 <th align="center" style="width:10%;"> </th>
15 </tr></thead>
15 </tr></thead>
16 <% enumerations.each do |enumeration| %>
16 <% enumerations.each do |enumeration| %>
17 <tr class="<%= cycle('odd', 'even') %>">
17 <tr class="<%= cycle('odd', 'even') %>">
18 <td><%= link_to h(enumeration), edit_enumeration_path(enumeration) %></td>
18 <td><%= link_to h(enumeration), edit_enumeration_path(enumeration) %></td>
19 <td class="center" style="width:15%;"><%= checked_image enumeration.is_default? %></td>
19 <td class="center" style="width:15%;"><%= checked_image enumeration.is_default? %></td>
20 <td class="center" style="width:15%;"><%= checked_image enumeration.active? %></td>
20 <td class="center" style="width:15%;"><%= checked_image enumeration.active? %></td>
21 <td style="width:15%;"><%= reorder_links('enumeration', {:action => 'update', :id => enumeration}, :put) %></td>
21 <td style="width:15%;"><%= reorder_links('enumeration', {:action => 'update', :id => enumeration}, :put) %></td>
22 <td class="buttons">
22 <td class="buttons">
23 <%= link_to l(:button_delete), enumeration_path(enumeration),
23 <%= delete_link enumeration_path(enumeration) %>
24 :method => :delete,
25 :confirm => l(:text_are_you_sure),
26 :class => 'icon icon-del' %>
27 </td>
24 </td>
28 </tr>
25 </tr>
29 <% end %>
26 <% end %>
30 </table>
27 </table>
31 <% reset_cycle %>
28 <% reset_cycle %>
32 <% end %>
29 <% end %>
33
30
34 <p><%= link_to l(:label_enumeration_new), new_enumeration_path(:type => klass.name) %></p>
31 <p><%= link_to l(:label_enumeration_new), new_enumeration_path(:type => klass.name) %></p>
35 <% end %>
32 <% end %>
36
33
37 <% html_title(l(:label_enumerations)) -%>
34 <% html_title(l(:label_enumerations)) -%>
@@ -1,46 +1,46
1 <div class="contextual">
1 <div class="contextual">
2 <%= link_to(l(:label_attachment_new), new_project_file_path(@project), :class => 'icon icon-add') if User.current.allowed_to?(:manage_files, @project) %>
2 <%= link_to(l(:label_attachment_new), new_project_file_path(@project), :class => 'icon icon-add') if User.current.allowed_to?(:manage_files, @project) %>
3 </div>
3 </div>
4
4
5 <h2><%=l(:label_attachment_plural)%></h2>
5 <h2><%=l(:label_attachment_plural)%></h2>
6
6
7 <% delete_allowed = User.current.allowed_to?(:manage_files, @project) %>
7 <% delete_allowed = User.current.allowed_to?(:manage_files, @project) %>
8
8
9 <table class="list files">
9 <table class="list files">
10 <thead><tr>
10 <thead><tr>
11 <%= sort_header_tag('filename', :caption => l(:field_filename)) %>
11 <%= sort_header_tag('filename', :caption => l(:field_filename)) %>
12 <%= sort_header_tag('created_on', :caption => l(:label_date), :default_order => 'desc') %>
12 <%= sort_header_tag('created_on', :caption => l(:label_date), :default_order => 'desc') %>
13 <%= sort_header_tag('size', :caption => l(:field_filesize), :default_order => 'desc') %>
13 <%= sort_header_tag('size', :caption => l(:field_filesize), :default_order => 'desc') %>
14 <%= sort_header_tag('downloads', :caption => l(:label_downloads_abbr), :default_order => 'desc') %>
14 <%= sort_header_tag('downloads', :caption => l(:label_downloads_abbr), :default_order => 'desc') %>
15 <th>MD5</th>
15 <th>MD5</th>
16 <th></th>
16 <th></th>
17 </tr></thead>
17 </tr></thead>
18 <tbody>
18 <tbody>
19 <% @containers.each do |container| %>
19 <% @containers.each do |container| %>
20 <% next if container.attachments.empty? -%>
20 <% next if container.attachments.empty? -%>
21 <% if container.is_a?(Version) -%>
21 <% if container.is_a?(Version) -%>
22 <tr>
22 <tr>
23 <th colspan="6" align="left">
23 <th colspan="6" align="left">
24 <%= link_to(h(container), {:controller => 'versions', :action => 'show', :id => container}, :class => "icon icon-package") %>
24 <%= link_to(h(container), {:controller => 'versions', :action => 'show', :id => container}, :class => "icon icon-package") %>
25 </th>
25 </th>
26 </tr>
26 </tr>
27 <% end -%>
27 <% end -%>
28 <% container.attachments.each do |file| %>
28 <% container.attachments.each do |file| %>
29 <tr class="file <%= cycle("odd", "even") %>">
29 <tr class="file <%= cycle("odd", "even") %>">
30 <td class="filename"><%= link_to_attachment file, :download => true, :title => file.description %></td>
30 <td class="filename"><%= link_to_attachment file, :download => true, :title => file.description %></td>
31 <td class="created_on"><%= format_time(file.created_on) %></td>
31 <td class="created_on"><%= format_time(file.created_on) %></td>
32 <td class="filesize"><%= number_to_human_size(file.filesize) %></td>
32 <td class="filesize"><%= number_to_human_size(file.filesize) %></td>
33 <td class="downloads"><%= file.downloads %></td>
33 <td class="downloads"><%= file.downloads %></td>
34 <td class="digest"><%= file.digest %></td>
34 <td class="digest"><%= file.digest %></td>
35 <td align="center">
35 <td align="center">
36 <%= link_to(image_tag('delete.png'), attachment_path(file),
36 <%= link_to(image_tag('delete.png'), attachment_path(file),
37 :confirm => l(:text_are_you_sure), :method => :delete) if delete_allowed %>
37 :data => {:confirm => l(:text_are_you_sure)}, :method => :delete) if delete_allowed %>
38 </td>
38 </td>
39 </tr>
39 </tr>
40 <% end
40 <% end
41 reset_cycle %>
41 reset_cycle %>
42 <% end %>
42 <% end %>
43 </tbody>
43 </tbody>
44 </table>
44 </table>
45
45
46 <% html_title(l(:label_attachment_plural)) -%>
46 <% html_title(l(:label_attachment_plural)) -%>
@@ -1,25 +1,25
1 <div class="contextual">
1 <div class="contextual">
2 <%= link_to l(:label_group_new), new_group_path, :class => 'icon icon-add' %>
2 <%= link_to l(:label_group_new), new_group_path, :class => 'icon icon-add' %>
3 </div>
3 </div>
4
4
5 <h2><%= l(:label_group_plural) %></h2>
5 <h2><%= l(:label_group_plural) %></h2>
6
6
7 <% if @groups.any? %>
7 <% if @groups.any? %>
8 <table class="list groups">
8 <table class="list groups">
9 <thead><tr>
9 <thead><tr>
10 <th><%=l(:label_group)%></th>
10 <th><%=l(:label_group)%></th>
11 <th><%=l(:label_user_plural)%></th>
11 <th><%=l(:label_user_plural)%></th>
12 <th></th>
12 <th></th>
13 </tr></thead>
13 </tr></thead>
14 <tbody>
14 <tbody>
15 <% @groups.each do |group| %>
15 <% @groups.each do |group| %>
16 <tr class="<%= cycle 'odd', 'even' %>">
16 <tr class="<%= cycle 'odd', 'even' %>">
17 <td><%= link_to h(group), edit_group_path(group) %></td>
17 <td><%= link_to h(group), edit_group_path(group) %></td>
18 <td align="center"><%= group.users.size %></td>
18 <td align="center"><%= group.users.size %></td>
19 <td class="buttons"><%= link_to l(:button_delete), group, :confirm => l(:text_are_you_sure), :method => :delete, :class => 'icon icon-del' %></td>
19 <td class="buttons"><%= delete_link group %></td>
20 </tr>
20 </tr>
21 <% end %>
21 <% end %>
22 </table>
22 </table>
23 <% else %>
23 <% else %>
24 <p class="nodata"><%= l(:label_no_data) %></p>
24 <p class="nodata"><%= l(:label_no_data) %></p>
25 <% end %>
25 <% end %>
@@ -1,42 +1,39
1 <div class="contextual">
1 <div class="contextual">
2 <%= link_to l(:label_issue_status_new), new_issue_status_path, :class => 'icon icon-add' %>
2 <%= link_to l(:label_issue_status_new), new_issue_status_path, :class => 'icon icon-add' %>
3 <%= link_to(l(:label_update_issue_done_ratios), update_issue_done_ratio_issue_statuses_path, :class => 'icon icon-multiple', :method => 'post', :confirm => l(:text_are_you_sure)) if Issue.use_status_for_done_ratio? %>
3 <%= link_to(l(:label_update_issue_done_ratios), update_issue_done_ratio_issue_statuses_path, :class => 'icon icon-multiple', :method => 'post', :data => {:confirm => l(:text_are_you_sure)}) if Issue.use_status_for_done_ratio? %>
4 </div>
4 </div>
5
5
6 <h2><%=l(:label_issue_status_plural)%></h2>
6 <h2><%=l(:label_issue_status_plural)%></h2>
7
7
8 <table class="list">
8 <table class="list">
9 <thead><tr>
9 <thead><tr>
10 <th><%=l(:field_status)%></th>
10 <th><%=l(:field_status)%></th>
11 <% if Issue.use_status_for_done_ratio? %>
11 <% if Issue.use_status_for_done_ratio? %>
12 <th><%=l(:field_done_ratio)%></th>
12 <th><%=l(:field_done_ratio)%></th>
13 <% end %>
13 <% end %>
14 <th><%=l(:field_is_default)%></th>
14 <th><%=l(:field_is_default)%></th>
15 <th><%=l(:field_is_closed)%></th>
15 <th><%=l(:field_is_closed)%></th>
16 <th><%=l(:button_sort)%></th>
16 <th><%=l(:button_sort)%></th>
17 <th></th>
17 <th></th>
18 </tr></thead>
18 </tr></thead>
19 <tbody>
19 <tbody>
20 <% for status in @issue_statuses %>
20 <% for status in @issue_statuses %>
21 <tr class="<%= cycle("odd", "even") %>">
21 <tr class="<%= cycle("odd", "even") %>">
22 <td><%= link_to h(status.name), edit_issue_status_path(status) %></td>
22 <td><%= link_to h(status.name), edit_issue_status_path(status) %></td>
23 <% if Issue.use_status_for_done_ratio? %>
23 <% if Issue.use_status_for_done_ratio? %>
24 <td align="center"><%= h status.default_done_ratio %></td>
24 <td align="center"><%= h status.default_done_ratio %></td>
25 <% end %>
25 <% end %>
26 <td align="center"><%= checked_image status.is_default? %></td>
26 <td align="center"><%= checked_image status.is_default? %></td>
27 <td align="center"><%= checked_image status.is_closed? %></td>
27 <td align="center"><%= checked_image status.is_closed? %></td>
28 <td align="center" style="width:15%;"><%= reorder_links('issue_status', {:action => 'update', :id => status}, :put) %></td>
28 <td align="center" style="width:15%;"><%= reorder_links('issue_status', {:action => 'update', :id => status}, :put) %></td>
29 <td class="buttons">
29 <td class="buttons">
30 <%= link_to(l(:button_delete), issue_status_path(status),
30 <%= delete_link issue_status_path(status) %>
31 :method => :delete,
32 :confirm => l(:text_are_you_sure),
33 :class => 'icon icon-del') %>
34 </td>
31 </td>
35 </tr>
32 </tr>
36 <% end %>
33 <% end %>
37 </tbody>
34 </tbody>
38 </table>
35 </table>
39
36
40 <p class="pagination"><%= pagination_links_full @issue_status_pages %></p>
37 <p class="pagination"><%= pagination_links_full @issue_status_pages %></p>
41
38
42 <% html_title(l(:label_issue_status_plural)) -%>
39 <% html_title(l(:label_issue_status_plural)) -%>
@@ -1,7 +1,7
1 <div class="contextual">
1 <div class="contextual">
2 <%= link_to_if_authorized(l(:button_update), {:controller => 'issues', :action => 'edit', :id => @issue }, :onclick => 'showAndScrollTo("update", "notes"); return false;', :class => 'icon icon-edit', :accesskey => accesskey(:edit)) %>
2 <%= link_to_if_authorized(l(:button_update), {:controller => 'issues', :action => 'edit', :id => @issue }, :onclick => 'showAndScrollTo("update", "notes"); return false;', :class => 'icon icon-edit', :accesskey => accesskey(:edit)) %>
3 <%= link_to l(:button_log_time), new_issue_time_entry_path(@issue), :class => 'icon icon-time-add' if User.current.allowed_to?(:log_time, @project) %>
3 <%= link_to l(:button_log_time), new_issue_time_entry_path(@issue), :class => 'icon icon-time-add' if User.current.allowed_to?(:log_time, @project) %>
4 <%= watcher_tag(@issue, User.current) %>
4 <%= watcher_tag(@issue, User.current) %>
5 <%= link_to_if_authorized l(:button_copy), {:controller => 'issues', :action => 'new', :project_id => @project, :copy_from => @issue}, :class => 'icon icon-copy' %>
5 <%= link_to_if_authorized l(:button_copy), {:controller => 'issues', :action => 'new', :project_id => @project, :copy_from => @issue}, :class => 'icon icon-copy' %>
6 <%= link_to l(:button_delete), issue_path(@issue), :confirm => issues_destroy_confirmation_message(@issue), :method => :delete, :class => 'icon icon-del' if User.current.allowed_to?(:delete_issues, @project) %>
6 <%= link_to l(:button_delete), issue_path(@issue), :data => {:confirm => issues_destroy_confirmation_message(@issue)}, :method => :delete, :class => 'icon icon-del' if User.current.allowed_to?(:delete_issues, @project) %>
7 </div>
7 </div>
@@ -1,43 +1,43
1 <div class="contextual">
1 <div class="contextual">
2 <% if User.current.allowed_to?(:manage_issue_relations, @project) %>
2 <% if User.current.allowed_to?(:manage_issue_relations, @project) %>
3 <%= toggle_link l(:button_add), 'new-relation-form', {:focus => 'relation_issue_to_id'} %>
3 <%= toggle_link l(:button_add), 'new-relation-form', {:focus => 'relation_issue_to_id'} %>
4 <% end %>
4 <% end %>
5 </div>
5 </div>
6
6
7 <p><strong><%=l(:label_related_issues)%></strong></p>
7 <p><strong><%=l(:label_related_issues)%></strong></p>
8
8
9 <% if @relations.present? %>
9 <% if @relations.present? %>
10 <form>
10 <form>
11 <table class="list issues">
11 <table class="list issues">
12 <% @relations.each do |relation| %>
12 <% @relations.each do |relation| %>
13 <tr class="issue hascontextmenu" id="relation-<%= relation.id %>">
13 <tr class="issue hascontextmenu" id="relation-<%= relation.id %>">
14 <td class="checkbox"><%= check_box_tag("ids[]", relation.other_issue(@issue).id, false, :id => nil) %></td>
14 <td class="checkbox"><%= check_box_tag("ids[]", relation.other_issue(@issue).id, false, :id => nil) %></td>
15 <td class="subject"><%= l(relation.label_for(@issue)) %> <%= "(#{l('datetime.distance_in_words.x_days', :count => relation.delay)})" if relation.delay && relation.delay != 0 %>
15 <td class="subject"><%= l(relation.label_for(@issue)) %> <%= "(#{l('datetime.distance_in_words.x_days', :count => relation.delay)})" if relation.delay && relation.delay != 0 %>
16 <%= h(relation.other_issue(@issue).project) + ' - ' if Setting.cross_project_issue_relations? %>
16 <%= h(relation.other_issue(@issue).project) + ' - ' if Setting.cross_project_issue_relations? %>
17 <%= link_to_issue(relation.other_issue(@issue), :truncate => 60) %>
17 <%= link_to_issue(relation.other_issue(@issue), :truncate => 60) %>
18 </td>
18 </td>
19 <td class="status"><%=h relation.other_issue(@issue).status.name %></td>
19 <td class="status"><%=h relation.other_issue(@issue).status.name %></td>
20 <td class="start_date"><%= format_date(relation.other_issue(@issue).start_date) %></td>
20 <td class="start_date"><%= format_date(relation.other_issue(@issue).start_date) %></td>
21 <td class="due_date"><%= format_date(relation.other_issue(@issue).due_date) %></td>
21 <td class="due_date"><%= format_date(relation.other_issue(@issue).due_date) %></td>
22 <td class="buttons"><%= link_to_remote(
22 <td class="buttons"><%= link_to_remote(
23 image_tag('link_break.png'),
23 image_tag('link_break.png'),
24 { :url => {:controller => 'issue_relations', :action => 'destroy', :id => relation},
24 { :url => {:controller => 'issue_relations', :action => 'destroy', :id => relation},
25 :method => :delete,
25 :method => :delete,
26 :confirm => l(:text_are_you_sure) },
26 :data => {:confirm => l(:text_are_you_sure)} },
27 :title => l(:label_relation_delete)
27 :title => l(:label_relation_delete)
28 ) if authorize_for('issue_relations', 'destroy') %></td>
28 ) if authorize_for('issue_relations', 'destroy') %></td>
29 </tr>
29 </tr>
30 <% end %>
30 <% end %>
31 </table>
31 </table>
32 </form>
32 </form>
33 <% end %>
33 <% end %>
34
34
35 <%= form_for @relation, {
35 <%= form_for @relation, {
36 :as => :relation, :remote => true,
36 :as => :relation, :remote => true,
37 :url => {:controller => 'issue_relations', :action => 'create', :issue_id => @issue},
37 :url => {:controller => 'issue_relations', :action => 'create', :issue_id => @issue},
38 :method => :post,
38 :method => :post,
39 :complete => "Form.Element.focus('relation_issue_to_id');",
39 :complete => "Form.Element.focus('relation_issue_to_id');",
40 :html => {:id => 'new-relation-form', :style => (@relation ? '' : 'display: none;')}
40 :html => {:id => 'new-relation-form', :style => (@relation ? '' : 'display: none;')}
41 } do |f| %>
41 } do |f| %>
42 <%= render :partial => 'issue_relations/form', :locals => {:f => f}%>
42 <%= render :partial => 'issue_relations/form', :locals => {:f => f}%>
43 <% end %>
43 <% end %>
@@ -1,105 +1,104
1 <div class="contextual">
1 <div class="contextual">
2 <% if !@query.new_record? && @query.editable_by?(User.current) %>
2 <% if !@query.new_record? && @query.editable_by?(User.current) %>
3 <%= link_to l(:button_edit), edit_query_path(@query), :class => 'icon icon-edit' %>
3 <%= link_to l(:button_edit), edit_query_path(@query), :class => 'icon icon-edit' %>
4 <%= link_to l(:button_delete), query_path(@query), :confirm => l(:text_are_you_sure),
4 <%= delete_link query_path(@query) %>
5 :method => :delete, :class => 'icon icon-del' %>
6 <% end %>
5 <% end %>
7 </div>
6 </div>
8
7
9 <h2><%= @query.new_record? ? l(:label_issue_plural) : h(@query.name) %></h2>
8 <h2><%= @query.new_record? ? l(:label_issue_plural) : h(@query.name) %></h2>
10 <% html_title(@query.new_record? ? l(:label_issue_plural) : @query.name) %>
9 <% html_title(@query.new_record? ? l(:label_issue_plural) : @query.name) %>
11
10
12 <%= form_tag({ :controller => 'issues', :action => 'index', :project_id => @project },
11 <%= form_tag({ :controller => 'issues', :action => 'index', :project_id => @project },
13 :method => :get, :id => 'query_form') do %>
12 :method => :get, :id => 'query_form') do %>
14 <%= hidden_field_tag 'set_filter', '1' %>
13 <%= hidden_field_tag 'set_filter', '1' %>
15 <div id="query_form_content" class="hide-when-print">
14 <div id="query_form_content" class="hide-when-print">
16 <fieldset id="filters" class="collapsible <%= @query.new_record? ? "" : "collapsed" %>">
15 <fieldset id="filters" class="collapsible <%= @query.new_record? ? "" : "collapsed" %>">
17 <legend onclick="toggleFieldset(this);"><%= l(:label_filter_plural) %></legend>
16 <legend onclick="toggleFieldset(this);"><%= l(:label_filter_plural) %></legend>
18 <div style="<%= @query.new_record? ? "" : "display: none;" %>">
17 <div style="<%= @query.new_record? ? "" : "display: none;" %>">
19 <%= render :partial => 'queries/filters', :locals => {:query => @query} %>
18 <%= render :partial => 'queries/filters', :locals => {:query => @query} %>
20 </div>
19 </div>
21 </fieldset>
20 </fieldset>
22 <fieldset class="collapsible collapsed">
21 <fieldset class="collapsible collapsed">
23 <legend onclick="toggleFieldset(this);"><%= l(:label_options) %></legend>
22 <legend onclick="toggleFieldset(this);"><%= l(:label_options) %></legend>
24 <div style="display: none;">
23 <div style="display: none;">
25 <table>
24 <table>
26 <tr>
25 <tr>
27 <td><%= l(:field_column_names) %></td>
26 <td><%= l(:field_column_names) %></td>
28 <td><%= render :partial => 'queries/columns', :locals => {:query => @query} %></td>
27 <td><%= render :partial => 'queries/columns', :locals => {:query => @query} %></td>
29 </tr>
28 </tr>
30 <tr>
29 <tr>
31 <td><label for='group_by'><%= l(:field_group_by) %></label></td>
30 <td><label for='group_by'><%= l(:field_group_by) %></label></td>
32 <td><%= select_tag('group_by',
31 <td><%= select_tag('group_by',
33 options_for_select(
32 options_for_select(
34 [[]] + @query.groupable_columns.collect {|c| [c.caption, c.name.to_s]},
33 [[]] + @query.groupable_columns.collect {|c| [c.caption, c.name.to_s]},
35 @query.group_by)
34 @query.group_by)
36 ) %></td>
35 ) %></td>
37 </tr>
36 </tr>
38 </table>
37 </table>
39 </div>
38 </div>
40 </fieldset>
39 </fieldset>
41 </div>
40 </div>
42 <p class="buttons hide-when-print">
41 <p class="buttons hide-when-print">
43
42
44 <%= link_to_function l(:button_apply), 'submit_query_form("query_form")', :class => 'icon icon-checked' %>
43 <%= link_to_function l(:button_apply), 'submit_query_form("query_form")', :class => 'icon icon-checked' %>
45 <%= link_to l(:button_clear), { :set_filter => 1, :project_id => @project }, :class => 'icon icon-reload' %>
44 <%= link_to l(:button_clear), { :set_filter => 1, :project_id => @project }, :class => 'icon icon-reload' %>
46 <% if @query.new_record? && User.current.allowed_to?(:save_queries, @project, :global => true) %>
45 <% if @query.new_record? && User.current.allowed_to?(:save_queries, @project, :global => true) %>
47 <%= link_to_function l(:button_save),
46 <%= link_to_function l(:button_save),
48 "$('query_form').action='#{ @project ? new_project_query_path(@project) : new_query_path }'; submit_query_form('query_form')",
47 "$('query_form').action='#{ @project ? new_project_query_path(@project) : new_query_path }'; submit_query_form('query_form')",
49 :class => 'icon icon-save' %>
48 :class => 'icon icon-save' %>
50 <% end %>
49 <% end %>
51 </p>
50 </p>
52 <% end %>
51 <% end %>
53
52
54 <%= error_messages_for 'query' %>
53 <%= error_messages_for 'query' %>
55 <% if @query.valid? %>
54 <% if @query.valid? %>
56 <% if @issues.empty? %>
55 <% if @issues.empty? %>
57 <p class="nodata"><%= l(:label_no_data) %></p>
56 <p class="nodata"><%= l(:label_no_data) %></p>
58 <% else %>
57 <% else %>
59 <%= render :partial => 'issues/list', :locals => {:issues => @issues, :query => @query} %>
58 <%= render :partial => 'issues/list', :locals => {:issues => @issues, :query => @query} %>
60 <p class="pagination"><%= pagination_links_full @issue_pages, @issue_count %></p>
59 <p class="pagination"><%= pagination_links_full @issue_pages, @issue_count %></p>
61 <% end %>
60 <% end %>
62
61
63 <% other_formats_links do |f| %>
62 <% other_formats_links do |f| %>
64 <%= f.link_to 'Atom', :url => params.merge(:key => User.current.rss_key) %>
63 <%= f.link_to 'Atom', :url => params.merge(:key => User.current.rss_key) %>
65 <%= f.link_to 'CSV', :url => params, :onclick => "showModal('csv-export-options', '330px'); return false;" %>
64 <%= f.link_to 'CSV', :url => params, :onclick => "showModal('csv-export-options', '330px'); return false;" %>
66 <%= f.link_to 'PDF', :url => params %>
65 <%= f.link_to 'PDF', :url => params %>
67 <% end %>
66 <% end %>
68
67
69 <div id="csv-export-options" style="display:none;">
68 <div id="csv-export-options" style="display:none;">
70 <h3 class="title"><%= l(:label_export_options, :export_format => 'CSV') %></h3>
69 <h3 class="title"><%= l(:label_export_options, :export_format => 'CSV') %></h3>
71 <%= form_tag(params.merge({:format => 'csv',:page=>nil}), :method => :get, :id => 'csv-export-form') do %>
70 <%= form_tag(params.merge({:format => 'csv',:page=>nil}), :method => :get, :id => 'csv-export-form') do %>
72 <p>
71 <p>
73 <label><%= radio_button_tag 'columns', '', true %> <%= l(:description_selected_columns) %></label><br />
72 <label><%= radio_button_tag 'columns', '', true %> <%= l(:description_selected_columns) %></label><br />
74 <label><%= radio_button_tag 'columns', 'all' %> <%= l(:description_all_columns) %></label>
73 <label><%= radio_button_tag 'columns', 'all' %> <%= l(:description_all_columns) %></label>
75 </p>
74 </p>
76 <p>
75 <p>
77 <label><%= check_box_tag 'description', '1' %> <%= l(:field_description) %></label>
76 <label><%= check_box_tag 'description', '1' %> <%= l(:field_description) %></label>
78 </p>
77 </p>
79 <p class="buttons">
78 <p class="buttons">
80 <%= submit_tag l(:button_export), :name => nil, :onclick => "hideModal(this);" %>
79 <%= submit_tag l(:button_export), :name => nil, :onclick => "hideModal(this);" %>
81 <%= submit_tag l(:button_cancel), :name => nil, :onclick => "hideModal(this);", :type => 'button' %>
80 <%= submit_tag l(:button_cancel), :name => nil, :onclick => "hideModal(this);", :type => 'button' %>
82 </p>
81 </p>
83 <% end %>
82 <% end %>
84 </div>
83 </div>
85
84
86 <% end %>
85 <% end %>
87 <%= call_hook(:view_issues_index_bottom, { :issues => @issues, :project => @project, :query => @query }) %>
86 <%= call_hook(:view_issues_index_bottom, { :issues => @issues, :project => @project, :query => @query }) %>
88
87
89 <% content_for :sidebar do %>
88 <% content_for :sidebar do %>
90 <%= render :partial => 'issues/sidebar' %>
89 <%= render :partial => 'issues/sidebar' %>
91 <% end %>
90 <% end %>
92
91
93 <% content_for :header_tags do %>
92 <% content_for :header_tags do %>
94 <%= auto_discovery_link_tag(:atom,
93 <%= auto_discovery_link_tag(:atom,
95 {:query_id => @query, :format => 'atom',
94 {:query_id => @query, :format => 'atom',
96 :page => nil, :key => User.current.rss_key},
95 :page => nil, :key => User.current.rss_key},
97 :title => l(:label_issue_plural)) %>
96 :title => l(:label_issue_plural)) %>
98 <%= auto_discovery_link_tag(:atom,
97 <%= auto_discovery_link_tag(:atom,
99 {:controller => 'journals', :action => 'index',
98 {:controller => 'journals', :action => 'index',
100 :query_id => @query, :format => 'atom',
99 :query_id => @query, :format => 'atom',
101 :page => nil, :key => User.current.rss_key},
100 :page => nil, :key => User.current.rss_key},
102 :title => l(:label_changes_details)) %>
101 :title => l(:label_changes_details)) %>
103 <% end %>
102 <% end %>
104
103
105 <%= context_menu issues_context_menu_path %>
104 <%= context_menu issues_context_menu_path %>
@@ -1,94 +1,94
1 <%= breadcrumb link_to(l(:label_board_plural), project_boards_path(@project)),
1 <%= breadcrumb link_to(l(:label_board_plural), project_boards_path(@project)),
2 link_to(h(@board.name), project_board_path(@project, @board)) %>
2 link_to(h(@board.name), project_board_path(@project, @board)) %>
3
3
4 <div class="contextual">
4 <div class="contextual">
5 <%= watcher_tag(@topic, User.current) %>
5 <%= watcher_tag(@topic, User.current) %>
6 <%= link_to_remote_if_authorized(
6 <%= link_to_remote_if_authorized(
7 l(:button_quote),
7 l(:button_quote),
8 { :url => {:action => 'quote', :id => @topic} },
8 { :url => {:action => 'quote', :id => @topic} },
9 :class => 'icon icon-comment'
9 :class => 'icon icon-comment'
10 ) unless @topic.locked? %>
10 ) unless @topic.locked? %>
11 <%= link_to(
11 <%= link_to(
12 l(:button_edit),
12 l(:button_edit),
13 {:action => 'edit', :id => @topic},
13 {:action => 'edit', :id => @topic},
14 :class => 'icon icon-edit'
14 :class => 'icon icon-edit'
15 ) if @message.editable_by?(User.current) %>
15 ) if @message.editable_by?(User.current) %>
16 <%= link_to(
16 <%= link_to(
17 l(:button_delete),
17 l(:button_delete),
18 {:action => 'destroy', :id => @topic},
18 {:action => 'destroy', :id => @topic},
19 :method => :post,
19 :method => :post,
20 :confirm => l(:text_are_you_sure),
20 :data => {:confirm => l(:text_are_you_sure)},
21 :class => 'icon icon-del'
21 :class => 'icon icon-del'
22 ) if @message.destroyable_by?(User.current) %>
22 ) if @message.destroyable_by?(User.current) %>
23 </div>
23 </div>
24
24
25 <h2><%= avatar(@topic.author, :size => "24") %><%=h @topic.subject %></h2>
25 <h2><%= avatar(@topic.author, :size => "24") %><%=h @topic.subject %></h2>
26
26
27 <div class="message">
27 <div class="message">
28 <p><span class="author"><%= authoring @topic.created_on, @topic.author %></span></p>
28 <p><span class="author"><%= authoring @topic.created_on, @topic.author %></span></p>
29 <div class="wiki">
29 <div class="wiki">
30 <%= textilizable(@topic, :content) %>
30 <%= textilizable(@topic, :content) %>
31 </div>
31 </div>
32 <%= link_to_attachments @topic, :author => false %>
32 <%= link_to_attachments @topic, :author => false %>
33 </div>
33 </div>
34 <br />
34 <br />
35
35
36 <% unless @replies.empty? %>
36 <% unless @replies.empty? %>
37 <h3 class="comments"><%= l(:label_reply_plural) %> (<%= @reply_count %>)</h3>
37 <h3 class="comments"><%= l(:label_reply_plural) %> (<%= @reply_count %>)</h3>
38 <% @replies.each do |message| %>
38 <% @replies.each do |message| %>
39 <div class="message reply" id="<%= "message-#{message.id}" %>">
39 <div class="message reply" id="<%= "message-#{message.id}" %>">
40 <div class="contextual">
40 <div class="contextual">
41 <%= link_to_remote_if_authorized(
41 <%= link_to_remote_if_authorized(
42 image_tag('comment.png'),
42 image_tag('comment.png'),
43 { :url => {:action => 'quote', :id => message} },
43 { :url => {:action => 'quote', :id => message} },
44 :title => l(:button_quote)
44 :title => l(:button_quote)
45 ) unless @topic.locked? %>
45 ) unless @topic.locked? %>
46 <%= link_to(
46 <%= link_to(
47 image_tag('edit.png'),
47 image_tag('edit.png'),
48 {:action => 'edit', :id => message},
48 {:action => 'edit', :id => message},
49 :title => l(:button_edit)
49 :title => l(:button_edit)
50 ) if message.editable_by?(User.current) %>
50 ) if message.editable_by?(User.current) %>
51 <%= link_to(
51 <%= link_to(
52 image_tag('delete.png'),
52 image_tag('delete.png'),
53 {:action => 'destroy', :id => message},
53 {:action => 'destroy', :id => message},
54 :method => :post,
54 :method => :post,
55 :confirm => l(:text_are_you_sure),
55 :data => {:confirm => l(:text_are_you_sure)},
56 :title => l(:button_delete)
56 :title => l(:button_delete)
57 ) if message.destroyable_by?(User.current) %>
57 ) if message.destroyable_by?(User.current) %>
58 </div>
58 </div>
59 <h4>
59 <h4>
60 <%= avatar(message.author, :size => "24") %>
60 <%= avatar(message.author, :size => "24") %>
61 <%= link_to h(message.subject), { :controller => 'messages', :action => 'show', :board_id => @board, :id => @topic, :r => message, :anchor => "message-#{message.id}" } %>
61 <%= link_to h(message.subject), { :controller => 'messages', :action => 'show', :board_id => @board, :id => @topic, :r => message, :anchor => "message-#{message.id}" } %>
62 -
62 -
63 <%= authoring message.created_on, message.author %>
63 <%= authoring message.created_on, message.author %>
64 </h4>
64 </h4>
65 <div class="wiki"><%= textilizable message, :content, :attachments => message.attachments %></div>
65 <div class="wiki"><%= textilizable message, :content, :attachments => message.attachments %></div>
66 <%= link_to_attachments message, :author => false %>
66 <%= link_to_attachments message, :author => false %>
67 </div>
67 </div>
68 <% end %>
68 <% end %>
69 <p class="pagination"><%= pagination_links_full @reply_pages, @reply_count, :per_page_links => false %></p>
69 <p class="pagination"><%= pagination_links_full @reply_pages, @reply_count, :per_page_links => false %></p>
70 <% end %>
70 <% end %>
71
71
72 <% if !@topic.locked? && authorize_for('messages', 'reply') %>
72 <% if !@topic.locked? && authorize_for('messages', 'reply') %>
73 <p><%= toggle_link l(:button_reply), "reply", :focus => 'message_content' %></p>
73 <p><%= toggle_link l(:button_reply), "reply", :focus => 'message_content' %></p>
74 <div id="reply" style="display:none;">
74 <div id="reply" style="display:none;">
75 <%= form_for @reply, :as => :reply, :url => {:action => 'reply', :id => @topic}, :html => {:multipart => true, :id => 'message-form'} do |f| %>
75 <%= form_for @reply, :as => :reply, :url => {:action => 'reply', :id => @topic}, :html => {:multipart => true, :id => 'message-form'} do |f| %>
76 <%= render :partial => 'form', :locals => {:f => f, :replying => true} %>
76 <%= render :partial => 'form', :locals => {:f => f, :replying => true} %>
77 <%= submit_tag l(:button_submit) %>
77 <%= submit_tag l(:button_submit) %>
78 <%= link_to_remote l(:label_preview),
78 <%= link_to_remote l(:label_preview),
79 { :url => { :controller => 'messages', :action => 'preview', :board_id => @board },
79 { :url => { :controller => 'messages', :action => 'preview', :board_id => @board },
80 :method => 'post',
80 :method => 'post',
81 :update => 'preview',
81 :update => 'preview',
82 :with => "Form.serialize('message-form')",
82 :with => "Form.serialize('message-form')",
83 :complete => "Element.scrollTo('preview')"
83 :complete => "Element.scrollTo('preview')"
84 }, :accesskey => accesskey(:preview) %>
84 }, :accesskey => accesskey(:preview) %>
85 <% end %>
85 <% end %>
86 <div id="preview" class="wiki"></div>
86 <div id="preview" class="wiki"></div>
87 </div>
87 </div>
88 <% end %>
88 <% end %>
89
89
90 <% content_for :header_tags do %>
90 <% content_for :header_tags do %>
91 <%= stylesheet_link_tag 'scm' %>
91 <%= stylesheet_link_tag 'scm' %>
92 <% end %>
92 <% end %>
93
93
94 <% html_title @topic.subject %>
94 <% html_title @topic.subject %>
@@ -1,52 +1,52
1 <h3><%=l(:label_spent_time)%> (<%= l(:label_last_n_days, 7) %>)</h3>
1 <h3><%=l(:label_spent_time)%> (<%= l(:label_last_n_days, 7) %>)</h3>
2 <%
2 <%
3 entries = TimeEntry.find(:all,
3 entries = TimeEntry.find(:all,
4 :conditions => ["#{TimeEntry.table_name}.user_id = ? AND #{TimeEntry.table_name}.spent_on BETWEEN ? AND ?", @user.id, Date.today - 6, Date.today],
4 :conditions => ["#{TimeEntry.table_name}.user_id = ? AND #{TimeEntry.table_name}.spent_on BETWEEN ? AND ?", @user.id, Date.today - 6, Date.today],
5 :include => [:activity, :project, {:issue => [:tracker, :status]}],
5 :include => [:activity, :project, {:issue => [:tracker, :status]}],
6 :order => "#{TimeEntry.table_name}.spent_on DESC, #{Project.table_name}.name ASC, #{Tracker.table_name}.position ASC, #{Issue.table_name}.id ASC")
6 :order => "#{TimeEntry.table_name}.spent_on DESC, #{Project.table_name}.name ASC, #{Tracker.table_name}.position ASC, #{Issue.table_name}.id ASC")
7 entries_by_day = entries.group_by(&:spent_on)
7 entries_by_day = entries.group_by(&:spent_on)
8 %>
8 %>
9
9
10 <div class="total-hours">
10 <div class="total-hours">
11 <p><%= l(:label_total) %>: <%= html_hours("%.2f" % entries.sum(&:hours).to_f) %></p>
11 <p><%= l(:label_total) %>: <%= html_hours("%.2f" % entries.sum(&:hours).to_f) %></p>
12 </div>
12 </div>
13
13
14 <% if entries.any? %>
14 <% if entries.any? %>
15 <table class="list time-entries">
15 <table class="list time-entries">
16 <thead><tr>
16 <thead><tr>
17 <th><%= l(:label_activity) %></th>
17 <th><%= l(:label_activity) %></th>
18 <th><%= l(:label_project) %></th>
18 <th><%= l(:label_project) %></th>
19 <th><%= l(:field_comments) %></th>
19 <th><%= l(:field_comments) %></th>
20 <th><%= l(:field_hours) %></th>
20 <th><%= l(:field_hours) %></th>
21 <th></th>
21 <th></th>
22 </tr></thead>
22 </tr></thead>
23 <tbody>
23 <tbody>
24 <% entries_by_day.keys.sort.reverse.each do |day| %>
24 <% entries_by_day.keys.sort.reverse.each do |day| %>
25 <tr class="odd">
25 <tr class="odd">
26 <td><strong><%= day == Date.today ? l(:label_today).titleize : format_date(day) %></strong></td>
26 <td><strong><%= day == Date.today ? l(:label_today).titleize : format_date(day) %></strong></td>
27 <td colspan="2"></td>
27 <td colspan="2"></td>
28 <td class="hours"><em><%= html_hours("%.2f" % entries_by_day[day].sum(&:hours).to_f) %></em></td>
28 <td class="hours"><em><%= html_hours("%.2f" % entries_by_day[day].sum(&:hours).to_f) %></em></td>
29 <td></td>
29 <td></td>
30 </tr>
30 </tr>
31 <% entries_by_day[day].each do |entry| -%>
31 <% entries_by_day[day].each do |entry| -%>
32 <tr class="time-entry" style="border-bottom: 1px solid #f5f5f5;">
32 <tr class="time-entry" style="border-bottom: 1px solid #f5f5f5;">
33 <td class="activity"><%=h entry.activity %></td>
33 <td class="activity"><%=h entry.activity %></td>
34 <td class="subject"><%=h entry.project %> <%= h(' - ') + link_to_issue(entry.issue, :truncate => 50) if entry.issue %></td>
34 <td class="subject"><%=h entry.project %> <%= h(' - ') + link_to_issue(entry.issue, :truncate => 50) if entry.issue %></td>
35 <td class="comments"><%=h entry.comments %></td>
35 <td class="comments"><%=h entry.comments %></td>
36 <td class="hours"><%= html_hours("%.2f" % entry.hours) %></td>
36 <td class="hours"><%= html_hours("%.2f" % entry.hours) %></td>
37 <td align="center">
37 <td align="center">
38 <% if entry.editable_by?(@user) -%>
38 <% if entry.editable_by?(@user) -%>
39 <%= link_to image_tag('edit.png'), {:controller => 'timelog', :action => 'edit', :id => entry},
39 <%= link_to image_tag('edit.png'), {:controller => 'timelog', :action => 'edit', :id => entry},
40 :title => l(:button_edit) %>
40 :title => l(:button_edit) %>
41 <%= link_to image_tag('delete.png'), {:controller => 'timelog', :action => 'destroy', :id => entry},
41 <%= link_to image_tag('delete.png'), {:controller => 'timelog', :action => 'destroy', :id => entry},
42 :confirm => l(:text_are_you_sure),
42 :data => {:confirm => l(:text_are_you_sure)},
43 :method => :delete,
43 :method => :delete,
44 :title => l(:button_delete) %>
44 :title => l(:button_delete) %>
45 <% end -%>
45 <% end -%>
46 </td>
46 </td>
47 </tr>
47 </tr>
48 <% end -%>
48 <% end -%>
49 <% end -%>
49 <% end -%>
50 </tbody>
50 </tbody>
51 </table>
51 </table>
52 <% end %>
52 <% end %>
@@ -1,71 +1,67
1 <div class="contextual">
1 <div class="contextual">
2 <%= watcher_tag(@news, User.current) %>
2 <%= watcher_tag(@news, User.current) %>
3 <%= link_to(l(:button_edit),
3 <%= link_to(l(:button_edit),
4 edit_news_path(@news),
4 edit_news_path(@news),
5 :class => 'icon icon-edit',
5 :class => 'icon icon-edit',
6 :accesskey => accesskey(:edit),
6 :accesskey => accesskey(:edit),
7 :onclick => 'Element.show("edit-news"); return false;') if User.current.allowed_to?(:manage_news, @project) %>
7 :onclick => 'Element.show("edit-news"); return false;') if User.current.allowed_to?(:manage_news, @project) %>
8 <%= link_to(l(:button_delete),
8 <%= delete_link news_path(@news) if User.current.allowed_to?(:manage_news, @project) %>
9 news_path(@news),
10 :confirm => l(:text_are_you_sure),
11 :method => :delete,
12 :class => 'icon icon-del') if User.current.allowed_to?(:manage_news, @project) %>
13 </div>
9 </div>
14
10
15 <h2><%= avatar(@news.author, :size => "24") %><%=h @news.title %></h2>
11 <h2><%= avatar(@news.author, :size => "24") %><%=h @news.title %></h2>
16
12
17 <% if authorize_for('news', 'edit') %>
13 <% if authorize_for('news', 'edit') %>
18 <div id="edit-news" style="display:none;">
14 <div id="edit-news" style="display:none;">
19 <%= labelled_form_for :news, @news, :url => news_path(@news),
15 <%= labelled_form_for :news, @news, :url => news_path(@news),
20 :html => { :id => 'news-form', :multipart => true, :method => :put } do |f| %>
16 :html => { :id => 'news-form', :multipart => true, :method => :put } do |f| %>
21 <%= render :partial => 'form', :locals => { :f => f } %>
17 <%= render :partial => 'form', :locals => { :f => f } %>
22 <%= submit_tag l(:button_save) %>
18 <%= submit_tag l(:button_save) %>
23 <%= link_to_remote l(:label_preview),
19 <%= link_to_remote l(:label_preview),
24 { :url => preview_news_path(:project_id => @project),
20 { :url => preview_news_path(:project_id => @project),
25 :method => 'get',
21 :method => 'get',
26 :update => 'preview',
22 :update => 'preview',
27 :with => "Form.serialize('news-form')"
23 :with => "Form.serialize('news-form')"
28 }, :accesskey => accesskey(:preview) %> |
24 }, :accesskey => accesskey(:preview) %> |
29 <%= link_to l(:button_cancel), "#", :onclick => 'Element.hide("edit-news"); return false;' %>
25 <%= link_to l(:button_cancel), "#", :onclick => 'Element.hide("edit-news"); return false;' %>
30 <% end %>
26 <% end %>
31 <div id="preview" class="wiki"></div>
27 <div id="preview" class="wiki"></div>
32 </div>
28 </div>
33 <% end %>
29 <% end %>
34
30
35 <p><% unless @news.summary.blank? %><em><%=h @news.summary %></em><br /><% end %>
31 <p><% unless @news.summary.blank? %><em><%=h @news.summary %></em><br /><% end %>
36 <span class="author"><%= authoring @news.created_on, @news.author %></span></p>
32 <span class="author"><%= authoring @news.created_on, @news.author %></span></p>
37 <div class="wiki">
33 <div class="wiki">
38 <%= textilizable(@news, :description) %>
34 <%= textilizable(@news, :description) %>
39 </div>
35 </div>
40 <%= link_to_attachments @news %>
36 <%= link_to_attachments @news %>
41 <br />
37 <br />
42
38
43 <div id="comments" style="margin-bottom:16px;">
39 <div id="comments" style="margin-bottom:16px;">
44 <h3 class="comments"><%= l(:label_comment_plural) %></h3>
40 <h3 class="comments"><%= l(:label_comment_plural) %></h3>
45 <% @comments.each do |comment| %>
41 <% @comments.each do |comment| %>
46 <% next if comment.new_record? %>
42 <% next if comment.new_record? %>
47 <div class="contextual">
43 <div class="contextual">
48 <%= link_to_if_authorized image_tag('delete.png'), {:controller => 'comments', :action => 'destroy', :id => @news, :comment_id => comment},
44 <%= link_to_if_authorized image_tag('delete.png'), {:controller => 'comments', :action => 'destroy', :id => @news, :comment_id => comment},
49 :confirm => l(:text_are_you_sure), :method => :delete, :title => l(:button_delete) %>
45 :data => {:confirm => l(:text_are_you_sure)}, :method => :delete, :title => l(:button_delete) %>
50 </div>
46 </div>
51 <h4><%= avatar(comment.author, :size => "24") %><%= authoring comment.created_on, comment.author %></h4>
47 <h4><%= avatar(comment.author, :size => "24") %><%= authoring comment.created_on, comment.author %></h4>
52 <%= textilizable(comment.comments) %>
48 <%= textilizable(comment.comments) %>
53 <% end if @comments.any? %>
49 <% end if @comments.any? %>
54 </div>
50 </div>
55
51
56 <% if @news.commentable? %>
52 <% if @news.commentable? %>
57 <p><%= toggle_link l(:label_comment_add), "add_comment_form", :focus => "comment_comments" %></p>
53 <p><%= toggle_link l(:label_comment_add), "add_comment_form", :focus => "comment_comments" %></p>
58 <%= form_tag({:controller => 'comments', :action => 'create', :id => @news}, :id => "add_comment_form", :style => "display:none;") do %>
54 <%= form_tag({:controller => 'comments', :action => 'create', :id => @news}, :id => "add_comment_form", :style => "display:none;") do %>
59 <div class="box">
55 <div class="box">
60 <%= text_area 'comment', 'comments', :cols => 80, :rows => 15, :class => 'wiki-edit' %>
56 <%= text_area 'comment', 'comments', :cols => 80, :rows => 15, :class => 'wiki-edit' %>
61 <%= wikitoolbar_for 'comment_comments' %>
57 <%= wikitoolbar_for 'comment_comments' %>
62 </div>
58 </div>
63 <p><%= submit_tag l(:button_add) %></p>
59 <p><%= submit_tag l(:button_add) %></p>
64 <% end %>
60 <% end %>
65 <% end %>
61 <% end %>
66
62
67 <% html_title @news.title -%>
63 <% html_title @news.title -%>
68
64
69 <% content_for :header_tags do %>
65 <% content_for :header_tags do %>
70 <%= stylesheet_link_tag 'scm' %>
66 <%= stylesheet_link_tag 'scm' %>
71 <% end %>
67 <% end %>
@@ -1,42 +1,42
1 <%= form_tag(project_enumerations_path(@project), :method => :put, :class => "tabular") do %>
1 <%= form_tag(project_enumerations_path(@project), :method => :put, :class => "tabular") do %>
2
2
3 <table class="list">
3 <table class="list">
4 <thead><tr>
4 <thead><tr>
5 <th><%= l(:field_name) %></th>
5 <th><%= l(:field_name) %></th>
6 <th><%= l(:enumeration_system_activity) %></th>
6 <th><%= l(:enumeration_system_activity) %></th>
7 <% TimeEntryActivity.new.available_custom_fields.each do |value| %>
7 <% TimeEntryActivity.new.available_custom_fields.each do |value| %>
8 <th><%= h value.name %></th>
8 <th><%= h value.name %></th>
9 <% end %>
9 <% end %>
10 <th style="width:15%;"><%= l(:field_active) %></th>
10 <th style="width:15%;"><%= l(:field_active) %></th>
11 </tr></thead>
11 </tr></thead>
12
12
13 <% @project.activities(true).each do |enumeration| %>
13 <% @project.activities(true).each do |enumeration| %>
14 <%= fields_for "enumerations[#{enumeration.id}]", enumeration do |ff| %>
14 <%= fields_for "enumerations[#{enumeration.id}]", enumeration do |ff| %>
15 <tr class="<%= cycle('odd', 'even') %>">
15 <tr class="<%= cycle('odd', 'even') %>">
16 <td>
16 <td>
17 <%= ff.hidden_field :parent_id, :value => enumeration.id unless enumeration.project %>
17 <%= ff.hidden_field :parent_id, :value => enumeration.id unless enumeration.project %>
18 <%= h(enumeration) %>
18 <%= h(enumeration) %>
19 </td>
19 </td>
20 <td align="center" style="width:15%;"><%= checked_image !enumeration.project %></td>
20 <td align="center" style="width:15%;"><%= checked_image !enumeration.project %></td>
21 <% enumeration.custom_field_values.each do |value| %>
21 <% enumeration.custom_field_values.each do |value| %>
22 <td align="center">
22 <td align="center">
23 <%= custom_field_tag "enumerations[#{enumeration.id}]", value %>
23 <%= custom_field_tag "enumerations[#{enumeration.id}]", value %>
24 </td>
24 </td>
25 <% end %>
25 <% end %>
26 <td align="center" style="width:15%;">
26 <td align="center" style="width:15%;">
27 <%= ff.check_box :active %>
27 <%= ff.check_box :active %>
28 </td>
28 </td>
29 </tr>
29 </tr>
30 <% end %>
30 <% end %>
31 <% end %>
31 <% end %>
32 </table>
32 </table>
33
33
34 <div class="contextual">
34 <div class="contextual">
35 <%= link_to(l(:button_reset), project_enumerations_path(@project),
35 <%= link_to(l(:button_reset), project_enumerations_path(@project),
36 :method => :delete,
36 :method => :delete,
37 :confirm => l(:text_are_you_sure),
37 :data => {:confirm => l(:text_are_you_sure)},
38 :class => 'icon icon-del') %>
38 :class => 'icon icon-del') %>
39 </div>
39 </div>
40
40
41 <%= submit_tag l(:button_save) %>
41 <%= submit_tag l(:button_save) %>
42 <% end %>
42 <% end %>
@@ -1,36 +1,36
1 <% if @project.boards.any? %>
1 <% if @project.boards.any? %>
2 <table class="list">
2 <table class="list">
3 <thead><tr>
3 <thead><tr>
4 <th><%= l(:label_board) %></th>
4 <th><%= l(:label_board) %></th>
5 <th><%= l(:field_description) %></th>
5 <th><%= l(:field_description) %></th>
6 <th></th>
6 <th></th>
7 <th></th>
7 <th></th>
8 </tr></thead>
8 </tr></thead>
9 <tbody>
9 <tbody>
10 <% @project.boards.each do |board|
10 <% @project.boards.each do |board|
11 next if board.new_record? %>
11 next if board.new_record? %>
12 <tr class="<%= cycle 'odd', 'even' %>">
12 <tr class="<%= cycle 'odd', 'even' %>">
13 <td><%=h board.name %></td>
13 <td><%=h board.name %></td>
14 <td><%=h board.description %></td>
14 <td><%=h board.description %></td>
15 <td align="center">
15 <td align="center">
16 <% if authorize_for("boards", "edit") %>
16 <% if authorize_for("boards", "edit") %>
17 <%= reorder_links('board', {:controller => 'boards', :action => 'update', :project_id => @project, :id => board}, :put) %>
17 <%= reorder_links('board', {:controller => 'boards', :action => 'update', :project_id => @project, :id => board}, :put) %>
18 <% end %>
18 <% end %>
19 </td>
19 </td>
20 <td class="buttons">
20 <td class="buttons">
21 <% if User.current.allowed_to?(:manage_boards, @project) %>
21 <% if User.current.allowed_to?(:manage_boards, @project) %>
22 <%= link_to l(:button_edit), edit_project_board_path(@project, board), :class => 'icon icon-edit' %>
22 <%= link_to l(:button_edit), edit_project_board_path(@project, board), :class => 'icon icon-edit' %>
23 <%= link_to l(:button_delete), project_board_path(@project, board), :confirm => l(:text_are_you_sure), :method => :delete, :class => 'icon icon-del' %>
23 <%= delete_link project_board_path(@project, board) %>
24 <% end %>
24 <% end %>
25 </td>
25 </td>
26 </tr>
26 </tr>
27 <% end %>
27 <% end %>
28 </tbody>
28 </tbody>
29 </table>
29 </table>
30 <% else %>
30 <% else %>
31 <p class="nodata"><%= l(:label_no_data) %></p>
31 <p class="nodata"><%= l(:label_no_data) %></p>
32 <% end %>
32 <% end %>
33
33
34 <% if User.current.allowed_to?(:manage_boards, @project) %>
34 <% if User.current.allowed_to?(:manage_boards, @project) %>
35 <p><%= link_to l(:label_board_new), new_project_board_path(@project), :class => 'icon icon-add' %></p>
35 <p><%= link_to l(:label_board_new), new_project_board_path(@project), :class => 'icon icon-add' %></p>
36 <% end %>
36 <% end %>
@@ -1,29 +1,29
1 <% if @project.issue_categories.any? %>
1 <% if @project.issue_categories.any? %>
2 <table class="list">
2 <table class="list">
3 <thead><tr>
3 <thead><tr>
4 <th><%= l(:label_issue_category) %></th>
4 <th><%= l(:label_issue_category) %></th>
5 <th><%= l(:field_assigned_to) %></th>
5 <th><%= l(:field_assigned_to) %></th>
6 <th></th>
6 <th></th>
7 </tr></thead>
7 </tr></thead>
8 <tbody>
8 <tbody>
9 <% for category in @project.issue_categories %>
9 <% for category in @project.issue_categories %>
10 <% unless category.new_record? %>
10 <% unless category.new_record? %>
11 <tr class="<%= cycle 'odd', 'even' %>">
11 <tr class="<%= cycle 'odd', 'even' %>">
12 <td><%=h(category.name) %></td>
12 <td><%=h(category.name) %></td>
13 <td><%=h(category.assigned_to.name) if category.assigned_to %></td>
13 <td><%=h(category.assigned_to.name) if category.assigned_to %></td>
14 <td class="buttons">
14 <td class="buttons">
15 <% if User.current.allowed_to?(:manage_categories, @project) %>
15 <% if User.current.allowed_to?(:manage_categories, @project) %>
16 <%= link_to l(:button_edit), edit_issue_category_path(category), :class => 'icon icon-edit' %>
16 <%= link_to l(:button_edit), edit_issue_category_path(category), :class => 'icon icon-edit' %>
17 <%= link_to l(:button_delete), issue_category_path(category), :confirm => l(:text_are_you_sure), :method => :delete, :class => 'icon icon-del' %>
17 <%= delete_link issue_category_path(category) %>
18 <% end %>
18 <% end %>
19 </td>
19 </td>
20 </tr>
20 </tr>
21 <% end %>
21 <% end %>
22 <% end %>
22 <% end %>
23 </tbody>
23 </tbody>
24 </table>
24 </table>
25 <% else %>
25 <% else %>
26 <p class="nodata"><%= l(:label_no_data) %></p>
26 <p class="nodata"><%= l(:label_no_data) %></p>
27 <% end %>
27 <% end %>
28
28
29 <p><%= link_to l(:label_issue_category_new), new_project_issue_category_path(@project), :class => 'icon icon-add' if User.current.allowed_to?(:manage_categories, @project) %></p>
29 <p><%= link_to l(:label_issue_category_new), new_project_issue_category_path(@project), :class => 'icon icon-add' if User.current.allowed_to?(:manage_categories, @project) %></p>
@@ -1,94 +1,94
1 <%= error_messages_for 'member' %>
1 <%= error_messages_for 'member' %>
2 <% roles = Role.find_all_givable
2 <% roles = Role.find_all_givable
3 members = @project.member_principals.find(:all, :include => [:roles, :principal]).sort %>
3 members = @project.member_principals.find(:all, :include => [:roles, :principal]).sort %>
4
4
5 <div class="splitcontentleft">
5 <div class="splitcontentleft">
6 <% if members.any? %>
6 <% if members.any? %>
7 <table class="list members">
7 <table class="list members">
8 <thead><tr>
8 <thead><tr>
9 <th><%= l(:label_user) %> / <%= l(:label_group) %></th>
9 <th><%= l(:label_user) %> / <%= l(:label_group) %></th>
10 <th><%= l(:label_role_plural) %></th>
10 <th><%= l(:label_role_plural) %></th>
11 <th style="width:15%"></th>
11 <th style="width:15%"></th>
12 <%= call_hook(:view_projects_settings_members_table_header, :project => @project) %>
12 <%= call_hook(:view_projects_settings_members_table_header, :project => @project) %>
13 </tr></thead>
13 </tr></thead>
14 <tbody>
14 <tbody>
15 <% members.each do |member| %>
15 <% members.each do |member| %>
16 <% next if member.new_record? %>
16 <% next if member.new_record? %>
17 <tr id="member-<%= member.id %>" class="<%= cycle 'odd', 'even' %> member">
17 <tr id="member-<%= member.id %>" class="<%= cycle 'odd', 'even' %> member">
18 <td class="<%= member.principal.class.name.downcase %>"><%= link_to_user member.principal %></td>
18 <td class="<%= member.principal.class.name.downcase %>"><%= link_to_user member.principal %></td>
19 <td class="roles">
19 <td class="roles">
20 <span id="member-<%= member.id %>-roles"><%=h member.roles.sort.collect(&:to_s).join(', ') %></span>
20 <span id="member-<%= member.id %>-roles"><%=h member.roles.sort.collect(&:to_s).join(', ') %></span>
21 <%= form_for(member, {:as => :membership, :remote => true, :url => membership_path(member),
21 <%= form_for(member, {:as => :membership, :remote => true, :url => membership_path(member),
22 :method => :put,
22 :method => :put,
23 :html => { :id => "member-#{member.id}-roles-form", :class => 'hol' }}
23 :html => { :id => "member-#{member.id}-roles-form", :class => 'hol' }}
24 ) do |f| %>
24 ) do |f| %>
25 <p><% roles.each do |role| %>
25 <p><% roles.each do |role| %>
26 <label><%= check_box_tag 'membership[role_ids][]', role.id, member.roles.include?(role),
26 <label><%= check_box_tag 'membership[role_ids][]', role.id, member.roles.include?(role),
27 :disabled => member.member_roles.detect {|mr| mr.role_id == role.id && !mr.inherited_from.nil?} %> <%=h role %></label><br />
27 :disabled => member.member_roles.detect {|mr| mr.role_id == role.id && !mr.inherited_from.nil?} %> <%=h role %></label><br />
28 <% end %></p>
28 <% end %></p>
29 <%= hidden_field_tag 'membership[role_ids][]', '' %>
29 <%= hidden_field_tag 'membership[role_ids][]', '' %>
30 <p><%= submit_tag l(:button_change), :class => "small" %>
30 <p><%= submit_tag l(:button_change), :class => "small" %>
31 <%= link_to_function l(:button_cancel),
31 <%= link_to_function l(:button_cancel),
32 "$('member-#{member.id}-roles').show(); $('member-#{member.id}-roles-form').hide(); return false;"
32 "$('member-#{member.id}-roles').show(); $('member-#{member.id}-roles-form').hide(); return false;"
33 %></p>
33 %></p>
34 <% end %>
34 <% end %>
35 </td>
35 </td>
36 <td class="buttons">
36 <td class="buttons">
37 <%= link_to_function l(:button_edit),
37 <%= link_to_function l(:button_edit),
38 "$('member-#{member.id}-roles').hide(); $('member-#{member.id}-roles-form').show(); return false;",
38 "$('member-#{member.id}-roles').hide(); $('member-#{member.id}-roles-form').show(); return false;",
39 :class => 'icon icon-edit' %>
39 :class => 'icon icon-edit' %>
40 <%= link_to_remote(
40 <%= link_to_remote(
41 l(:button_delete),
41 l(:button_delete),
42 { :url => membership_path(member),
42 { :url => membership_path(member),
43 :method => :delete,
43 :method => :delete,
44 :confirm => (!User.current.admin? && member.include?(User.current) ? l(:text_own_membership_delete_confirmation) : nil) },
44 :data => {:confirm => (!User.current.admin? && member.include?(User.current) ? l(:text_own_membership_delete_confirmation) : nil)} },
45 :title => l(:button_delete),
45 :title => l(:button_delete),
46 :class => 'icon icon-del'
46 :class => 'icon icon-del'
47 ) if member.deletable? %>
47 ) if member.deletable? %>
48 </td>
48 </td>
49 <%= call_hook(:view_projects_settings_members_table_row, { :project => @project, :member => member}) %>
49 <%= call_hook(:view_projects_settings_members_table_row, { :project => @project, :member => member}) %>
50 </tr>
50 </tr>
51 <% end; reset_cycle %>
51 <% end; reset_cycle %>
52 </tbody>
52 </tbody>
53 </table>
53 </table>
54 <% else %>
54 <% else %>
55 <p class="nodata"><%= l(:label_no_data) %></p>
55 <p class="nodata"><%= l(:label_no_data) %></p>
56 <% end %>
56 <% end %>
57 </div>
57 </div>
58
58
59 <% principals = Principal.active.not_member_of(@project).all(:limit => 100, :order => 'type, login, lastname ASC') %>
59 <% principals = Principal.active.not_member_of(@project).all(:limit => 100, :order => 'type, login, lastname ASC') %>
60
60
61 <div class="splitcontentright">
61 <div class="splitcontentright">
62 <% if roles.any? && principals.any? %>
62 <% if roles.any? && principals.any? %>
63 <%= form_for(@member, {:as => :membership, :remote => true,
63 <%= form_for(@member, {:as => :membership, :remote => true,
64 :url => project_memberships_path(@project), :method => :post,
64 :url => project_memberships_path(@project), :method => :post,
65 :loading => '$(\'member-add-submit\').disable();',
65 :loading => '$(\'member-add-submit\').disable();',
66 :complete => 'if($(\'member-add-submit\')) $(\'member-add-submit\').enable();'
66 :complete => 'if($(\'member-add-submit\')) $(\'member-add-submit\').enable();'
67 } ) do |f| %>
67 } ) do |f| %>
68 <fieldset><legend><%=l(:label_member_new)%></legend>
68 <fieldset><legend><%=l(:label_member_new)%></legend>
69
69
70 <p><%= label_tag "principal_search", l(:label_principal_search) %><%= text_field_tag 'principal_search', nil %></p>
70 <p><%= label_tag "principal_search", l(:label_principal_search) %><%= text_field_tag 'principal_search', nil %></p>
71 <%= observe_field(:principal_search,
71 <%= observe_field(:principal_search,
72 :frequency => 0.5,
72 :frequency => 0.5,
73 :update => :principals,
73 :update => :principals,
74 :url => autocomplete_project_memberships_path(@project),
74 :url => autocomplete_project_memberships_path(@project),
75 :method => :get,
75 :method => :get,
76 :before => '$("principal_search").addClassName("ajax-loading")',
76 :before => '$("principal_search").addClassName("ajax-loading")',
77 :complete => '$("principal_search").removeClassName("ajax-loading")',
77 :complete => '$("principal_search").removeClassName("ajax-loading")',
78 :with => 'q')
78 :with => 'q')
79 %>
79 %>
80
80
81 <div id="principals">
81 <div id="principals">
82 <%= principals_check_box_tags 'membership[user_ids][]', principals %>
82 <%= principals_check_box_tags 'membership[user_ids][]', principals %>
83 </div>
83 </div>
84
84
85 <p><%= l(:label_role_plural) %>:
85 <p><%= l(:label_role_plural) %>:
86 <% roles.each do |role| %>
86 <% roles.each do |role| %>
87 <label><%= check_box_tag 'membership[role_ids][]', role.id %> <%=h role %></label>
87 <label><%= check_box_tag 'membership[role_ids][]', role.id %> <%=h role %></label>
88 <% end %></p>
88 <% end %></p>
89
89
90 <p><%= submit_tag l(:button_add), :id => 'member-add-submit' %></p>
90 <p><%= submit_tag l(:button_add), :id => 'member-add-submit' %></p>
91 </fieldset>
91 </fieldset>
92 <% end %>
92 <% end %>
93 <% end %>
93 <% end %>
94 </div>
94 </div>
@@ -1,41 +1,38
1 <% if @project.repositories.any? %>
1 <% if @project.repositories.any? %>
2 <table class="list">
2 <table class="list">
3 <thead>
3 <thead>
4 <tr>
4 <tr>
5 <th><%= l(:label_scm) %></th>
5 <th><%= l(:label_scm) %></th>
6 <th><%= l(:field_identifier) %></th>
6 <th><%= l(:field_identifier) %></th>
7 <th><%= l(:field_repository_is_default) %></th>
7 <th><%= l(:field_repository_is_default) %></th>
8 <th><%= l(:label_repository) %></th>
8 <th><%= l(:label_repository) %></th>
9 <th></th>
9 <th></th>
10 </tr>
10 </tr>
11 </thead>
11 </thead>
12 <tbody>
12 <tbody>
13 <% @project.repositories.sort.each do |repository| %>
13 <% @project.repositories.sort.each do |repository| %>
14 <tr class="<%= cycle 'odd', 'even' %>">
14 <tr class="<%= cycle 'odd', 'even' %>">
15 <td><%=h repository.scm_name %></td>
15 <td><%=h repository.scm_name %></td>
16 <td><%=h repository.identifier %></td>
16 <td><%=h repository.identifier %></td>
17 <td align="center"><%= checked_image repository.is_default? %></td>
17 <td align="center"><%= checked_image repository.is_default? %></td>
18 <td><%=h repository.url %></td>
18 <td><%=h repository.url %></td>
19 <td class="buttons">
19 <td class="buttons">
20 <% if User.current.allowed_to?(:manage_repository, @project) %>
20 <% if User.current.allowed_to?(:manage_repository, @project) %>
21 <%= link_to(l(:label_user_plural), committers_repository_path(repository),
21 <%= link_to(l(:label_user_plural), committers_repository_path(repository),
22 :class => 'icon icon-user') %>
22 :class => 'icon icon-user') %>
23 <%= link_to(l(:button_edit), edit_repository_path(repository),
23 <%= link_to(l(:button_edit), edit_repository_path(repository),
24 :class => 'icon icon-edit') %>
24 :class => 'icon icon-edit') %>
25 <%= link_to(l(:button_delete), repository_path(repository),
25 <%= delete_link repository_path(repository) %>
26 :confirm => l(:text_are_you_sure),
27 :method => :delete,
28 :class => 'icon icon-del') %>
29 <% end %>
26 <% end %>
30 </td>
27 </td>
31 </tr>
28 </tr>
32 <% end %>
29 <% end %>
33 </tbody>
30 </tbody>
34 </table>
31 </table>
35 <% else %>
32 <% else %>
36 <p class="nodata"><%= l(:label_no_data) %></p>
33 <p class="nodata"><%= l(:label_no_data) %></p>
37 <% end %>
34 <% end %>
38
35
39 <% if User.current.allowed_to?(:manage_repository, @project) %>
36 <% if User.current.allowed_to?(:manage_repository, @project) %>
40 <p><%= link_to l(:label_repository_new), new_project_repository_path(@project), :class => 'icon icon-add' %></p>
37 <p><%= link_to l(:label_repository_new), new_project_repository_path(@project), :class => 'icon icon-add' %></p>
41 <% end %>
38 <% end %>
@@ -1,41 +1,41
1 <% if @project.shared_versions.any? %>
1 <% if @project.shared_versions.any? %>
2 <table class="list versions">
2 <table class="list versions">
3 <thead><tr>
3 <thead><tr>
4 <th><%= l(:label_version) %></th>
4 <th><%= l(:label_version) %></th>
5 <th><%= l(:field_effective_date) %></th>
5 <th><%= l(:field_effective_date) %></th>
6 <th><%= l(:field_description) %></th>
6 <th><%= l(:field_description) %></th>
7 <th><%= l(:field_status) %></th>
7 <th><%= l(:field_status) %></th>
8 <th><%= l(:field_sharing) %></th>
8 <th><%= l(:field_sharing) %></th>
9 <th><%= l(:label_wiki_page) %></th>
9 <th><%= l(:label_wiki_page) %></th>
10 <th style="width:15%"></th>
10 <th style="width:15%"></th>
11 </tr></thead>
11 </tr></thead>
12 <tbody>
12 <tbody>
13 <% for version in @project.shared_versions.sort %>
13 <% for version in @project.shared_versions.sort %>
14 <tr class="version <%= cycle 'odd', 'even' %> <%=h version.status %> <%= 'shared' if version.project != @project %>">
14 <tr class="version <%= cycle 'odd', 'even' %> <%=h version.status %> <%= 'shared' if version.project != @project %>">
15 <td class="name"><%= link_to_version version %></td>
15 <td class="name"><%= link_to_version version %></td>
16 <td class="date"><%= format_date(version.effective_date) %></td>
16 <td class="date"><%= format_date(version.effective_date) %></td>
17 <td class="description"><%=h version.description %></td>
17 <td class="description"><%=h version.description %></td>
18 <td class="status"><%= l("version_status_#{version.status}") %></td>
18 <td class="status"><%= l("version_status_#{version.status}") %></td>
19 <td class="sharing"><%=h format_version_sharing(version.sharing) %></td>
19 <td class="sharing"><%=h format_version_sharing(version.sharing) %></td>
20 <td><%= link_to_if_authorized(h(version.wiki_page_title), {:controller => 'wiki', :action => 'show', :project_id => version.project, :id => Wiki.titleize(version.wiki_page_title)}) || h(version.wiki_page_title) unless version.wiki_page_title.blank? || version.project.wiki.nil? %></td>
20 <td><%= link_to_if_authorized(h(version.wiki_page_title), {:controller => 'wiki', :action => 'show', :project_id => version.project, :id => Wiki.titleize(version.wiki_page_title)}) || h(version.wiki_page_title) unless version.wiki_page_title.blank? || version.project.wiki.nil? %></td>
21 <td class="buttons">
21 <td class="buttons">
22 <% if version.project == @project && User.current.allowed_to?(:manage_versions, @project) %>
22 <% if version.project == @project && User.current.allowed_to?(:manage_versions, @project) %>
23 <%= link_to l(:button_edit), edit_version_path(version), :class => 'icon icon-edit' %>
23 <%= link_to l(:button_edit), edit_version_path(version), :class => 'icon icon-edit' %>
24 <%= link_to l(:button_delete), version_path(version), :confirm => l(:text_are_you_sure), :method => :delete, :class => 'icon icon-del' %>
24 <%= delete_link version_path(version) %>
25 <% end %>
25 <% end %>
26 </td>
26 </td>
27 </tr>
27 </tr>
28 <% end; reset_cycle %>
28 <% end; reset_cycle %>
29 </tbody>
29 </tbody>
30 </table>
30 </table>
31 <% else %>
31 <% else %>
32 <p class="nodata"><%= l(:label_no_data) %></p>
32 <p class="nodata"><%= l(:label_no_data) %></p>
33 <% end %>
33 <% end %>
34
34
35 <div class="contextual">
35 <div class="contextual">
36 <% if @project.versions.any? %>
36 <% if @project.versions.any? %>
37 <%= link_to l(:label_close_versions), close_completed_project_versions_path(@project), :method => :put %>
37 <%= link_to l(:label_close_versions), close_completed_project_versions_path(@project), :method => :put %>
38 <% end %>
38 <% end %>
39 </div>
39 </div>
40
40
41 <p><%= link_to l(:label_version_new), new_project_version_path(@project, :back_url => ''), :class => 'icon icon-add' if User.current.allowed_to?(:manage_versions, @project) %></p>
41 <p><%= link_to l(:label_version_new), new_project_version_path(@project, :back_url => ''), :class => 'icon icon-add' if User.current.allowed_to?(:manage_versions, @project) %></p>
@@ -1,27 +1,27
1 <div class="contextual">
1 <div class="contextual">
2 <%= link_to_if_authorized l(:label_query_new), new_project_query_path(:project_id => @project), :class => 'icon icon-add' %>
2 <%= link_to_if_authorized l(:label_query_new), new_project_query_path(:project_id => @project), :class => 'icon icon-add' %>
3 </div>
3 </div>
4
4
5 <h2><%= l(:label_query_plural) %></h2>
5 <h2><%= l(:label_query_plural) %></h2>
6
6
7 <% if @queries.empty? %>
7 <% if @queries.empty? %>
8 <p><i><%=l(:label_no_data)%></i></p>
8 <p><i><%=l(:label_no_data)%></i></p>
9 <% else %>
9 <% else %>
10 <table class="list">
10 <table class="list">
11 <% @queries.each do |query| %>
11 <% @queries.each do |query| %>
12 <tr class="<%= cycle('odd', 'even') %>">
12 <tr class="<%= cycle('odd', 'even') %>">
13 <td>
13 <td>
14 <%= link_to h(query.name), :controller => 'issues', :action => 'index', :project_id => @project, :query_id => query %>
14 <%= link_to h(query.name), :controller => 'issues', :action => 'index', :project_id => @project, :query_id => query %>
15 </td>
15 </td>
16 <td align="right">
16 <td align="right">
17 <small>
17 <small>
18 <% if query.editable_by?(User.current) %>
18 <% if query.editable_by?(User.current) %>
19 <%= link_to l(:button_edit), edit_query_path(query), :class => 'icon icon-edit' %>
19 <%= link_to l(:button_edit), edit_query_path(query), :class => 'icon icon-edit' %>
20 <%= link_to l(:button_delete), query_path(query), :confirm => l(:text_are_you_sure), :method => :delete, :class => 'icon icon-del' %>
20 <%= delete_link query_path(query) %>
21 </small>
21 </small>
22 <% end %>
22 <% end %>
23 </td>
23 </td>
24 </tr>
24 </tr>
25 <% end %>
25 <% end %>
26 </table>
26 </table>
27 <% end %>
27 <% end %>
@@ -1,37 +1,34
1 <div class="contextual">
1 <div class="contextual">
2 <%= link_to l(:label_role_new), new_role_path, :class => 'icon icon-add' %>
2 <%= link_to l(:label_role_new), new_role_path, :class => 'icon icon-add' %>
3 </div>
3 </div>
4
4
5 <h2><%=l(:label_role_plural)%></h2>
5 <h2><%=l(:label_role_plural)%></h2>
6
6
7 <table class="list">
7 <table class="list">
8 <thead><tr>
8 <thead><tr>
9 <th><%=l(:label_role)%></th>
9 <th><%=l(:label_role)%></th>
10 <th><%=l(:button_sort)%></th>
10 <th><%=l(:button_sort)%></th>
11 <th></th>
11 <th></th>
12 </tr></thead>
12 </tr></thead>
13 <tbody>
13 <tbody>
14 <% for role in @roles %>
14 <% for role in @roles %>
15 <tr class="<%= cycle("odd", "even") %>">
15 <tr class="<%= cycle("odd", "even") %>">
16 <td><%= content_tag(role.builtin? ? 'em' : 'span', link_to(h(role.name), edit_role_path(role))) %></td>
16 <td><%= content_tag(role.builtin? ? 'em' : 'span', link_to(h(role.name), edit_role_path(role))) %></td>
17 <td align="center" style="width:15%;">
17 <td align="center" style="width:15%;">
18 <% unless role.builtin? %>
18 <% unless role.builtin? %>
19 <%= reorder_links('role', {:action => 'update', :id => role}, :put) %>
19 <%= reorder_links('role', {:action => 'update', :id => role}, :put) %>
20 <% end %>
20 <% end %>
21 </td>
21 </td>
22 <td class="buttons">
22 <td class="buttons">
23 <%= link_to(l(:button_delete), role_path(role),
23 <%= delete_link role_path(role) unless role.builtin? %>
24 :method => :delete,
25 :confirm => l(:text_are_you_sure),
26 :class => 'icon icon-del') unless role.builtin? %>
27 </td>
24 </td>
28 </tr>
25 </tr>
29 <% end %>
26 <% end %>
30 </tbody>
27 </tbody>
31 </table>
28 </table>
32
29
33 <p class="pagination"><%= pagination_links_full @role_pages %></p>
30 <p class="pagination"><%= pagination_links_full @role_pages %></p>
34
31
35 <p><%= link_to l(:label_permissions_report), :action => 'permissions' %></p>
32 <p><%= link_to l(:label_permissions_report), :action => 'permissions' %></p>
36
33
37 <% html_title(l(:label_role_plural)) -%>
34 <% html_title(l(:label_role_plural)) -%>
@@ -1,55 +1,55
1 <%= form_tag({}) do -%>
1 <%= form_tag({}) do -%>
2 <%= hidden_field_tag 'back_url', url_for(params) %>
2 <%= hidden_field_tag 'back_url', url_for(params) %>
3 <div class="autoscroll">
3 <div class="autoscroll">
4 <table class="list time-entries">
4 <table class="list time-entries">
5 <thead>
5 <thead>
6 <tr>
6 <tr>
7 <th class="checkbox hide-when-print">
7 <th class="checkbox hide-when-print">
8 <%= link_to image_tag('toggle_check.png'),
8 <%= link_to image_tag('toggle_check.png'),
9 {},
9 {},
10 :onclick => 'toggleIssuesSelection(Element.up(this, "form")); return false;',
10 :onclick => 'toggleIssuesSelection(Element.up(this, "form")); return false;',
11 :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %>
11 :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %>
12 </th>
12 </th>
13 <%= sort_header_tag('spent_on', :caption => l(:label_date), :default_order => 'desc') %>
13 <%= sort_header_tag('spent_on', :caption => l(:label_date), :default_order => 'desc') %>
14 <%= sort_header_tag('user', :caption => l(:label_member)) %>
14 <%= sort_header_tag('user', :caption => l(:label_member)) %>
15 <%= sort_header_tag('activity', :caption => l(:label_activity)) %>
15 <%= sort_header_tag('activity', :caption => l(:label_activity)) %>
16 <%= sort_header_tag('project', :caption => l(:label_project)) %>
16 <%= sort_header_tag('project', :caption => l(:label_project)) %>
17 <%= sort_header_tag('issue', :caption => l(:label_issue), :default_order => 'desc') %>
17 <%= sort_header_tag('issue', :caption => l(:label_issue), :default_order => 'desc') %>
18 <th><%= l(:field_comments) %></th>
18 <th><%= l(:field_comments) %></th>
19 <%= sort_header_tag('hours', :caption => l(:field_hours)) %>
19 <%= sort_header_tag('hours', :caption => l(:field_hours)) %>
20 <th></th>
20 <th></th>
21 </tr>
21 </tr>
22 </thead>
22 </thead>
23 <tbody>
23 <tbody>
24 <% entries.each do |entry| -%>
24 <% entries.each do |entry| -%>
25 <tr class="time-entry <%= cycle("odd", "even") %> hascontextmenu">
25 <tr class="time-entry <%= cycle("odd", "even") %> hascontextmenu">
26 <td class="checkbox hide-when-print"><%= check_box_tag("ids[]", entry.id, false, :id => nil) %></td>
26 <td class="checkbox hide-when-print"><%= check_box_tag("ids[]", entry.id, false, :id => nil) %></td>
27 <td class="spent_on"><%= format_date(entry.spent_on) %></td>
27 <td class="spent_on"><%= format_date(entry.spent_on) %></td>
28 <td class="user"><%= link_to_user(entry.user) %></td>
28 <td class="user"><%= link_to_user(entry.user) %></td>
29 <td class="activity"><%=h entry.activity %></td>
29 <td class="activity"><%=h entry.activity %></td>
30 <td class="project"><%= link_to_project(entry.project) %></td>
30 <td class="project"><%= link_to_project(entry.project) %></td>
31 <td class="subject">
31 <td class="subject">
32 <% if entry.issue -%>
32 <% if entry.issue -%>
33 <%= entry.issue.visible? ? link_to_issue(entry.issue, :truncate => 50) : "##{entry.issue.id}" -%>
33 <%= entry.issue.visible? ? link_to_issue(entry.issue, :truncate => 50) : "##{entry.issue.id}" -%>
34 <% end -%>
34 <% end -%>
35 </td>
35 </td>
36 <td class="comments"><%=h entry.comments %></td>
36 <td class="comments"><%=h entry.comments %></td>
37 <td class="hours"><%= html_hours("%.2f" % entry.hours) %></td>
37 <td class="hours"><%= html_hours("%.2f" % entry.hours) %></td>
38 <td align="center">
38 <td align="center">
39 <% if entry.editable_by?(User.current) -%>
39 <% if entry.editable_by?(User.current) -%>
40 <%= link_to image_tag('edit.png'), {:controller => 'timelog', :action => 'edit', :id => entry, :project_id => nil},
40 <%= link_to image_tag('edit.png'), {:controller => 'timelog', :action => 'edit', :id => entry, :project_id => nil},
41 :title => l(:button_edit) %>
41 :title => l(:button_edit) %>
42 <%= link_to image_tag('delete.png'), {:controller => 'timelog', :action => 'destroy', :id => entry, :project_id => nil},
42 <%= link_to image_tag('delete.png'), {:controller => 'timelog', :action => 'destroy', :id => entry, :project_id => nil},
43 :confirm => l(:text_are_you_sure),
43 :data => {:confirm => l(:text_are_you_sure)},
44 :method => :delete,
44 :method => :delete,
45 :title => l(:button_delete) %>
45 :title => l(:button_delete) %>
46 <% end -%>
46 <% end -%>
47 </td>
47 </td>
48 </tr>
48 </tr>
49 <% end -%>
49 <% end -%>
50 </tbody>
50 </tbody>
51 </table>
51 </table>
52 </div>
52 </div>
53 <% end -%>
53 <% end -%>
54
54
55 <%= context_menu time_entries_context_menu_path %>
55 <%= context_menu time_entries_context_menu_path %>
@@ -1,33 +1,30
1 <div class="contextual">
1 <div class="contextual">
2 <%= link_to l(:label_tracker_new), new_tracker_path, :class => 'icon icon-add' %>
2 <%= link_to l(:label_tracker_new), new_tracker_path, :class => 'icon icon-add' %>
3 </div>
3 </div>
4
4
5 <h2><%=l(:label_tracker_plural)%></h2>
5 <h2><%=l(:label_tracker_plural)%></h2>
6
6
7 <table class="list">
7 <table class="list">
8 <thead><tr>
8 <thead><tr>
9 <th><%=l(:label_tracker)%></th>
9 <th><%=l(:label_tracker)%></th>
10 <th></th>
10 <th></th>
11 <th><%=l(:button_sort)%></th>
11 <th><%=l(:button_sort)%></th>
12 <th></th>
12 <th></th>
13 </tr></thead>
13 </tr></thead>
14 <tbody>
14 <tbody>
15 <% for tracker in @trackers %>
15 <% for tracker in @trackers %>
16 <tr class="<%= cycle("odd", "even") %>">
16 <tr class="<%= cycle("odd", "even") %>">
17 <td><%= link_to h(tracker.name), edit_tracker_path(tracker) %></td>
17 <td><%= link_to h(tracker.name), edit_tracker_path(tracker) %></td>
18 <td align="center"><% unless tracker.workflows.count > 0 %><span class="icon icon-warning"><%= l(:text_tracker_no_workflow) %> (<%= link_to l(:button_edit), {:controller => 'workflows', :action => 'edit', :tracker_id => tracker} %>)</span><% end %></td>
18 <td align="center"><% unless tracker.workflows.count > 0 %><span class="icon icon-warning"><%= l(:text_tracker_no_workflow) %> (<%= link_to l(:button_edit), {:controller => 'workflows', :action => 'edit', :tracker_id => tracker} %>)</span><% end %></td>
19 <td align="center" style="width:15%;"><%= reorder_links('tracker', {:action => 'update', :id => tracker}, :put) %></td>
19 <td align="center" style="width:15%;"><%= reorder_links('tracker', {:action => 'update', :id => tracker}, :put) %></td>
20 <td class="buttons">
20 <td class="buttons">
21 <%= link_to(l(:button_delete), tracker_path(tracker),
21 <%= delete_link tracker_path(tracker) %>
22 :method => :delete,
23 :confirm => l(:text_are_you_sure),
24 :class => 'icon icon-del') %>
25 </td>
22 </td>
26 </tr>
23 </tr>
27 <% end %>
24 <% end %>
28 </tbody>
25 </tbody>
29 </table>
26 </table>
30
27
31 <p class="pagination"><%= pagination_links_full @tracker_pages %></p>
28 <p class="pagination"><%= pagination_links_full @tracker_pages %></p>
32
29
33 <% html_title(l(:label_tracker_plural)) -%>
30 <% html_title(l(:label_tracker_plural)) -%>
@@ -1,11 +1,11
1 <div class="contextual">
1 <div class="contextual">
2 <%= link_to l(:label_profile), user_path(@user), :class => 'icon icon-user' %>
2 <%= link_to l(:label_profile), user_path(@user), :class => 'icon icon-user' %>
3 <%= change_status_link(@user) %>
3 <%= change_status_link(@user) %>
4 <%= link_to(l(:button_delete), @user, :confirm => l(:text_are_you_sure), :method => :delete, :class => 'icon icon-del') if User.current != @user %>
4 <%= delete_link user_path(@user) if User.current != @user %>
5 </div>
5 </div>
6
6
7 <h2><%= link_to l(:label_user_plural), users_path %> &#187; <%=h @user.login %></h2>
7 <h2><%= link_to l(:label_user_plural), users_path %> &#187; <%=h @user.login %></h2>
8
8
9 <%= render_tabs user_settings_tabs %>
9 <%= render_tabs user_settings_tabs %>
10
10
11 <% html_title(l(:label_user), @user.login, l(:label_administration)) -%>
11 <% html_title(l(:label_user), @user.login, l(:label_administration)) -%>
@@ -1,58 +1,58
1 <div class="contextual">
1 <div class="contextual">
2 <%= link_to l(:label_user_new), new_user_path, :class => 'icon icon-add' %>
2 <%= link_to l(:label_user_new), new_user_path, :class => 'icon icon-add' %>
3 </div>
3 </div>
4
4
5 <h2><%=l(:label_user_plural)%></h2>
5 <h2><%=l(:label_user_plural)%></h2>
6
6
7 <%= form_tag({}, :method => :get) do %>
7 <%= form_tag({}, :method => :get) do %>
8 <fieldset><legend><%= l(:label_filter_plural) %></legend>
8 <fieldset><legend><%= l(:label_filter_plural) %></legend>
9 <label for='status'><%= l(:field_status) %>:</label>
9 <label for='status'><%= l(:field_status) %>:</label>
10 <%= select_tag 'status', users_status_options_for_select(@status), :class => "small", :onchange => "this.form.submit(); return false;" %>
10 <%= select_tag 'status', users_status_options_for_select(@status), :class => "small", :onchange => "this.form.submit(); return false;" %>
11
11
12 <% if @groups.present? %>
12 <% if @groups.present? %>
13 <label for='group_id'><%= l(:label_group) %>:</label>
13 <label for='group_id'><%= l(:label_group) %>:</label>
14 <%= select_tag 'group_id', content_tag('option') + options_from_collection_for_select(@groups, :id, :name, params[:group_id].to_i), :onchange => "this.form.submit(); return false;" %>
14 <%= select_tag 'group_id', content_tag('option') + options_from_collection_for_select(@groups, :id, :name, params[:group_id].to_i), :onchange => "this.form.submit(); return false;" %>
15 <% end %>
15 <% end %>
16
16
17 <label for='name'><%= l(:label_user) %>:</label>
17 <label for='name'><%= l(:label_user) %>:</label>
18 <%= text_field_tag 'name', params[:name], :size => 30 %>
18 <%= text_field_tag 'name', params[:name], :size => 30 %>
19 <%= submit_tag l(:button_apply), :class => "small", :name => nil %>
19 <%= submit_tag l(:button_apply), :class => "small", :name => nil %>
20 <%= link_to l(:button_clear), users_path, :class => 'icon icon-reload' %>
20 <%= link_to l(:button_clear), users_path, :class => 'icon icon-reload' %>
21 </fieldset>
21 </fieldset>
22 <% end %>
22 <% end %>
23 &nbsp;
23 &nbsp;
24
24
25 <div class="autoscroll">
25 <div class="autoscroll">
26 <table class="list">
26 <table class="list">
27 <thead><tr>
27 <thead><tr>
28 <%= sort_header_tag('login', :caption => l(:field_login)) %>
28 <%= sort_header_tag('login', :caption => l(:field_login)) %>
29 <%= sort_header_tag('firstname', :caption => l(:field_firstname)) %>
29 <%= sort_header_tag('firstname', :caption => l(:field_firstname)) %>
30 <%= sort_header_tag('lastname', :caption => l(:field_lastname)) %>
30 <%= sort_header_tag('lastname', :caption => l(:field_lastname)) %>
31 <%= sort_header_tag('mail', :caption => l(:field_mail)) %>
31 <%= sort_header_tag('mail', :caption => l(:field_mail)) %>
32 <%= sort_header_tag('admin', :caption => l(:field_admin), :default_order => 'desc') %>
32 <%= sort_header_tag('admin', :caption => l(:field_admin), :default_order => 'desc') %>
33 <%= sort_header_tag('created_on', :caption => l(:field_created_on), :default_order => 'desc') %>
33 <%= sort_header_tag('created_on', :caption => l(:field_created_on), :default_order => 'desc') %>
34 <%= sort_header_tag('last_login_on', :caption => l(:field_last_login_on), :default_order => 'desc') %>
34 <%= sort_header_tag('last_login_on', :caption => l(:field_last_login_on), :default_order => 'desc') %>
35 <th></th>
35 <th></th>
36 </tr></thead>
36 </tr></thead>
37 <tbody>
37 <tbody>
38 <% for user in @users -%>
38 <% for user in @users -%>
39 <tr class="user <%= cycle("odd", "even") %> <%= %w(anon active registered locked)[user.status] %>">
39 <tr class="user <%= cycle("odd", "even") %> <%= %w(anon active registered locked)[user.status] %>">
40 <td class="username"><%= avatar(user, :size => "14") %><%= link_to h(user.login), edit_user_path(user) %></td>
40 <td class="username"><%= avatar(user, :size => "14") %><%= link_to h(user.login), edit_user_path(user) %></td>
41 <td class="firstname"><%= h(user.firstname) %></td>
41 <td class="firstname"><%= h(user.firstname) %></td>
42 <td class="lastname"><%= h(user.lastname) %></td>
42 <td class="lastname"><%= h(user.lastname) %></td>
43 <td class="email"><%= mail_to(h(user.mail)) %></td>
43 <td class="email"><%= mail_to(h(user.mail)) %></td>
44 <td align="center"><%= checked_image user.admin? %></td>
44 <td align="center"><%= checked_image user.admin? %></td>
45 <td class="created_on" align="center"><%= format_time(user.created_on) %></td>
45 <td class="created_on" align="center"><%= format_time(user.created_on) %></td>
46 <td class="last_login_on" align="center"><%= format_time(user.last_login_on) unless user.last_login_on.nil? %></td>
46 <td class="last_login_on" align="center"><%= format_time(user.last_login_on) unless user.last_login_on.nil? %></td>
47 <td class="buttons">
47 <td class="buttons">
48 <%= change_status_link(user) %>
48 <%= change_status_link(user) %>
49 <%= link_to(l(:button_delete), user_path(user), :confirm => l(:text_are_you_sure), :method => :delete, :class => 'icon icon-del') unless User.current == user %>
49 <%= delete_link user_path(user) unless User.current == user %>
50 </td>
50 </td>
51 </tr>
51 </tr>
52 <% end -%>
52 <% end -%>
53 </tbody>
53 </tbody>
54 </table>
54 </table>
55 </div>
55 </div>
56 <p class="pagination"><%= pagination_links_full @user_pages, @user_count %></p>
56 <p class="pagination"><%= pagination_links_full @user_pages, @user_count %></p>
57
57
58 <% html_title(l(:label_user_plural)) -%>
58 <% html_title(l(:label_user_plural)) -%>
@@ -1,56 +1,55
1 <div class="contextual">
1 <div class="contextual">
2 <%= link_to(l(:button_edit), edit_version_path(@version), :class => 'icon icon-edit') if User.current.allowed_to?(:manage_versions, @version.project) %>
2 <%= link_to(l(:button_edit), edit_version_path(@version), :class => 'icon icon-edit') if User.current.allowed_to?(:manage_versions, @version.project) %>
3 <%= link_to_if_authorized(l(:button_edit_associated_wikipage, :page_title => @version.wiki_page_title), {:controller => 'wiki', :action => 'edit', :project_id => @version.project, :id => Wiki.titleize(@version.wiki_page_title)}, :class => 'icon icon-edit') unless @version.wiki_page_title.blank? || @version.project.wiki.nil? %>
3 <%= link_to_if_authorized(l(:button_edit_associated_wikipage, :page_title => @version.wiki_page_title), {:controller => 'wiki', :action => 'edit', :project_id => @version.project, :id => Wiki.titleize(@version.wiki_page_title)}, :class => 'icon icon-edit') unless @version.wiki_page_title.blank? || @version.project.wiki.nil? %>
4 <%= link_to(l(:button_delete), version_path(@version, :back_url => url_for(:controller => 'versions', :action => 'index', :project_id => @version.project)),
4 <%= delete_link version_path(@version, :back_url => url_for(:controller => 'versions', :action => 'index', :project_id => @version.project)) if User.current.allowed_to?(:manage_versions, @version.project) %>
5 :confirm => l(:text_are_you_sure), :method => :delete, :class => 'icon icon-del') if User.current.allowed_to?(:manage_versions, @version.project) %>
6 <%= call_hook(:view_versions_show_contextual, { :version => @version, :project => @project }) %>
5 <%= call_hook(:view_versions_show_contextual, { :version => @version, :project => @project }) %>
7 </div>
6 </div>
8
7
9 <h2><%= h(@version.name) %></h2>
8 <h2><%= h(@version.name) %></h2>
10
9
11 <div id="roadmap">
10 <div id="roadmap">
12 <%= render :partial => 'versions/overview', :locals => {:version => @version} %>
11 <%= render :partial => 'versions/overview', :locals => {:version => @version} %>
13 <%= render(:partial => "wiki/content", :locals => {:content => @version.wiki_page.content}) if @version.wiki_page %>
12 <%= render(:partial => "wiki/content", :locals => {:content => @version.wiki_page.content}) if @version.wiki_page %>
14
13
15 <div id="version-summary">
14 <div id="version-summary">
16 <% if @version.estimated_hours > 0 || User.current.allowed_to?(:view_time_entries, @project) %>
15 <% if @version.estimated_hours > 0 || User.current.allowed_to?(:view_time_entries, @project) %>
17 <fieldset class="time-tracking"><legend><%= l(:label_time_tracking) %></legend>
16 <fieldset class="time-tracking"><legend><%= l(:label_time_tracking) %></legend>
18 <table>
17 <table>
19 <tr>
18 <tr>
20 <th><%= l(:field_estimated_hours) %></th>
19 <th><%= l(:field_estimated_hours) %></th>
21 <td class="total-hours"><%= html_hours(l_hours(@version.estimated_hours)) %></td>
20 <td class="total-hours"><%= html_hours(l_hours(@version.estimated_hours)) %></td>
22 </tr>
21 </tr>
23 <% if User.current.allowed_to?(:view_time_entries, @project) %>
22 <% if User.current.allowed_to?(:view_time_entries, @project) %>
24 <tr>
23 <tr>
25 <th><%= l(:label_spent_time) %></th>
24 <th><%= l(:label_spent_time) %></th>
26 <td class="total-hours"><%= html_hours(l_hours(@version.spent_hours)) %></td>
25 <td class="total-hours"><%= html_hours(l_hours(@version.spent_hours)) %></td>
27 </tr>
26 </tr>
28 <% end %>
27 <% end %>
29 </table>
28 </table>
30 </fieldset>
29 </fieldset>
31 <% end %>
30 <% end %>
32
31
33 <div id="status_by">
32 <div id="status_by">
34 <%= render_issue_status_by(@version, params[:status_by]) if @version.fixed_issues.count > 0 %>
33 <%= render_issue_status_by(@version, params[:status_by]) if @version.fixed_issues.count > 0 %>
35 </div>
34 </div>
36 </div>
35 </div>
37
36
38 <% if @issues.present? %>
37 <% if @issues.present? %>
39 <%= form_tag({}) do -%>
38 <%= form_tag({}) do -%>
40 <table class="list related-issues">
39 <table class="list related-issues">
41 <caption><%= l(:label_related_issues) %></caption>
40 <caption><%= l(:label_related_issues) %></caption>
42 <%- @issues.each do |issue| -%>
41 <%- @issues.each do |issue| -%>
43 <tr class="hascontextmenu">
42 <tr class="hascontextmenu">
44 <td class="checkbox"><%= check_box_tag 'ids[]', issue.id, false, :id => nil %></td>
43 <td class="checkbox"><%= check_box_tag 'ids[]', issue.id, false, :id => nil %></td>
45 <td><%= link_to_issue(issue, :project => (@project != issue.project)) %></td>
44 <td><%= link_to_issue(issue, :project => (@project != issue.project)) %></td>
46 </tr>
45 </tr>
47 <% end %>
46 <% end %>
48 </table>
47 </table>
49 <% end %>
48 <% end %>
50 <%= context_menu issues_context_menu_path %>
49 <%= context_menu issues_context_menu_path %>
51 <% end %>
50 <% end %>
52 </div>
51 </div>
53
52
54 <%= call_hook :view_versions_show_bottom, :version => @version %>
53 <%= call_hook :view_versions_show_bottom, :version => @version %>
55
54
56 <% html_title @version.name %>
55 <% html_title @version.name %>
@@ -1,72 +1,72
1 <div class="contextual">
1 <div class="contextual">
2 <% if @editable %>
2 <% if @editable %>
3 <%= link_to_if_authorized(l(:button_edit), {:action => 'edit', :id => @page.title}, :class => 'icon icon-edit', :accesskey => accesskey(:edit)) if @content.current_version? %>
3 <%= link_to_if_authorized(l(:button_edit), {:action => 'edit', :id => @page.title}, :class => 'icon icon-edit', :accesskey => accesskey(:edit)) if @content.current_version? %>
4 <%= watcher_tag(@page, User.current) %>
4 <%= watcher_tag(@page, User.current) %>
5 <%= link_to_if_authorized(l(:button_lock), {:action => 'protect', :id => @page.title, :protected => 1}, :method => :post, :class => 'icon icon-lock') if !@page.protected? %>
5 <%= link_to_if_authorized(l(:button_lock), {:action => 'protect', :id => @page.title, :protected => 1}, :method => :post, :class => 'icon icon-lock') if !@page.protected? %>
6 <%= link_to_if_authorized(l(:button_unlock), {:action => 'protect', :id => @page.title, :protected => 0}, :method => :post, :class => 'icon icon-unlock') if @page.protected? %>
6 <%= link_to_if_authorized(l(:button_unlock), {:action => 'protect', :id => @page.title, :protected => 0}, :method => :post, :class => 'icon icon-unlock') if @page.protected? %>
7 <%= link_to_if_authorized(l(:button_rename), {:action => 'rename', :id => @page.title}, :class => 'icon icon-move') if @content.current_version? %>
7 <%= link_to_if_authorized(l(:button_rename), {:action => 'rename', :id => @page.title}, :class => 'icon icon-move') if @content.current_version? %>
8 <%= link_to_if_authorized(l(:button_delete), {:action => 'destroy', :id => @page.title}, :method => :delete, :confirm => l(:text_are_you_sure), :class => 'icon icon-del') %>
8 <%= link_to_if_authorized(l(:button_delete), {:action => 'destroy', :id => @page.title}, :method => :delete, :data => {:confirm => l(:text_are_you_sure)}, :class => 'icon icon-del') %>
9 <%= link_to_if_authorized(l(:button_rollback), {:action => 'edit', :id => @page.title, :version => @content.version }, :class => 'icon icon-cancel') unless @content.current_version? %>
9 <%= link_to_if_authorized(l(:button_rollback), {:action => 'edit', :id => @page.title, :version => @content.version }, :class => 'icon icon-cancel') unless @content.current_version? %>
10 <% end %>
10 <% end %>
11 <%= link_to_if_authorized(l(:label_history), {:action => 'history', :id => @page.title}, :class => 'icon icon-history') %>
11 <%= link_to_if_authorized(l(:label_history), {:action => 'history', :id => @page.title}, :class => 'icon icon-history') %>
12 </div>
12 </div>
13
13
14 <%= wiki_page_breadcrumb(@page) %>
14 <%= wiki_page_breadcrumb(@page) %>
15
15
16 <% unless @content.current_version? %>
16 <% unless @content.current_version? %>
17 <p>
17 <p>
18 <%= link_to(("\xc2\xab " + l(:label_previous)),
18 <%= link_to(("\xc2\xab " + l(:label_previous)),
19 :action => 'show', :id => @page.title, :project_id => @page.project,
19 :action => 'show', :id => @page.title, :project_id => @page.project,
20 :version => (@content.version - 1)) + " - " if @content.version > 1 %>
20 :version => (@content.version - 1)) + " - " if @content.version > 1 %>
21 <%= "#{l(:label_version)} #{@content.version}/#{@page.content.version}" %>
21 <%= "#{l(:label_version)} #{@content.version}/#{@page.content.version}" %>
22 <%= '('.html_safe + link_to(l(:label_diff), :controller => 'wiki', :action => 'diff',
22 <%= '('.html_safe + link_to(l(:label_diff), :controller => 'wiki', :action => 'diff',
23 :id => @page.title, :project_id => @page.project,
23 :id => @page.title, :project_id => @page.project,
24 :version => @content.version) + ')'.html_safe if @content.version > 1 %> -
24 :version => @content.version) + ')'.html_safe if @content.version > 1 %> -
25 <%= link_to((l(:label_next) + " \xc2\xbb"), :action => 'show',
25 <%= link_to((l(:label_next) + " \xc2\xbb"), :action => 'show',
26 :id => @page.title, :project_id => @page.project,
26 :id => @page.title, :project_id => @page.project,
27 :version => (@content.version + 1)) + " - " if @content.version < @page.content.version %>
27 :version => (@content.version + 1)) + " - " if @content.version < @page.content.version %>
28 <%= link_to(l(:label_current_version), :action => 'show', :id => @page.title, :project_id => @page.project) %>
28 <%= link_to(l(:label_current_version), :action => 'show', :id => @page.title, :project_id => @page.project) %>
29 <br />
29 <br />
30 <em><%= @content.author ? link_to_user(@content.author) : l(:label_user_anonymous)
30 <em><%= @content.author ? link_to_user(@content.author) : l(:label_user_anonymous)
31 %>, <%= format_time(@content.updated_on) %> </em><br />
31 %>, <%= format_time(@content.updated_on) %> </em><br />
32 <%=h @content.comments %>
32 <%=h @content.comments %>
33 </p>
33 </p>
34 <hr />
34 <hr />
35 <% end %>
35 <% end %>
36
36
37 <%= render(:partial => "wiki/content", :locals => {:content => @content}) %>
37 <%= render(:partial => "wiki/content", :locals => {:content => @content}) %>
38
38
39 <%= link_to_attachments @page %>
39 <%= link_to_attachments @page %>
40
40
41 <% if @editable && authorize_for('wiki', 'add_attachment') %>
41 <% if @editable && authorize_for('wiki', 'add_attachment') %>
42 <div id="wiki_add_attachment">
42 <div id="wiki_add_attachment">
43 <p><%= link_to l(:label_attachment_new), {}, :onclick => "Element.show('add_attachment_form'); Element.hide(this); Element.scrollTo('add_attachment_form'); return false;",
43 <p><%= link_to l(:label_attachment_new), {}, :onclick => "Element.show('add_attachment_form'); Element.hide(this); Element.scrollTo('add_attachment_form'); return false;",
44 :id => 'attach_files_link' %></p>
44 :id => 'attach_files_link' %></p>
45 <%= form_tag({:controller => 'wiki', :action => 'add_attachment',
45 <%= form_tag({:controller => 'wiki', :action => 'add_attachment',
46 :project_id => @project, :id => @page.title},
46 :project_id => @project, :id => @page.title},
47 :multipart => true, :id => "add_attachment_form",
47 :multipart => true, :id => "add_attachment_form",
48 :style => "display:none;") do %>
48 :style => "display:none;") do %>
49 <div class="box">
49 <div class="box">
50 <p><%= render :partial => 'attachments/form' %></p>
50 <p><%= render :partial => 'attachments/form' %></p>
51 </div>
51 </div>
52 <%= submit_tag l(:button_add) %>
52 <%= submit_tag l(:button_add) %>
53 <%= link_to l(:button_cancel), {}, :onclick => "Element.hide('add_attachment_form'); Element.show('attach_files_link'); return false;" %>
53 <%= link_to l(:button_cancel), {}, :onclick => "Element.hide('add_attachment_form'); Element.show('attach_files_link'); return false;" %>
54 <% end %>
54 <% end %>
55 </div>
55 </div>
56 <% end %>
56 <% end %>
57
57
58 <% other_formats_links do |f| %>
58 <% other_formats_links do |f| %>
59 <%= f.link_to 'PDF', :url => {:id => @page.title, :version => params[:version]} %>
59 <%= f.link_to 'PDF', :url => {:id => @page.title, :version => params[:version]} %>
60 <%= f.link_to 'HTML', :url => {:id => @page.title, :version => params[:version]} %>
60 <%= f.link_to 'HTML', :url => {:id => @page.title, :version => params[:version]} %>
61 <%= f.link_to 'TXT', :url => {:id => @page.title, :version => params[:version]} %>
61 <%= f.link_to 'TXT', :url => {:id => @page.title, :version => params[:version]} %>
62 <% end if User.current.allowed_to?(:export_wiki_pages, @project) %>
62 <% end if User.current.allowed_to?(:export_wiki_pages, @project) %>
63
63
64 <% content_for :header_tags do %>
64 <% content_for :header_tags do %>
65 <%= stylesheet_link_tag 'scm' %>
65 <%= stylesheet_link_tag 'scm' %>
66 <% end %>
66 <% end %>
67
67
68 <% content_for :sidebar do %>
68 <% content_for :sidebar do %>
69 <%= render :partial => 'sidebar' %>
69 <%= render :partial => 'sidebar' %>
70 <% end %>
70 <% end %>
71
71
72 <% html_title @page.pretty_title %>
72 <% html_title @page.pretty_title %>
General Comments 0
You need to be logged in to leave comments. Login now