##// END OF EJS Templates
Move repetitive calendar include code from views into helper (patch #966 by Peter Suschlik)....
Jean-Philippe Lang -
r1300:68fe7856c921
parent child
Show More
@@ -1,491 +1,504
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 module ApplicationHelper
19 19 include Redmine::WikiFormatting::Macros::Definitions
20 20
21 21 def current_role
22 22 @current_role ||= User.current.role_for_project(@project)
23 23 end
24 24
25 25 # Return true if user is authorized for controller/action, otherwise false
26 26 def authorize_for(controller, action)
27 27 User.current.allowed_to?({:controller => controller, :action => action}, @project)
28 28 end
29 29
30 30 # Display a link if user is authorized
31 31 def link_to_if_authorized(name, options = {}, html_options = nil, *parameters_for_method_reference)
32 32 link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for(options[:controller] || params[:controller], options[:action])
33 33 end
34 34
35 35 # Display a link to user's account page
36 36 def link_to_user(user)
37 37 user ? link_to(user, :controller => 'account', :action => 'show', :id => user) : 'Anonymous'
38 38 end
39 39
40 40 def link_to_issue(issue, options={})
41 41 link_to "#{issue.tracker.name} ##{issue.id}", {:controller => "issues", :action => "show", :id => issue}, options
42 42 end
43 43
44 44 def toggle_link(name, id, options={})
45 45 onclick = "Element.toggle('#{id}'); "
46 46 onclick << (options[:focus] ? "Form.Element.focus('#{options[:focus]}'); " : "this.blur(); ")
47 47 onclick << "return false;"
48 48 link_to(name, "#", :onclick => onclick)
49 49 end
50 50
51 51 def show_and_goto_link(name, id, options={})
52 52 onclick = "Element.show('#{id}'); "
53 53 onclick << (options[:focus] ? "Form.Element.focus('#{options[:focus]}'); " : "this.blur(); ")
54 54 onclick << "Element.scrollTo('#{id}'); "
55 55 onclick << "return false;"
56 56 link_to(name, "#", options.merge(:onclick => onclick))
57 57 end
58 58
59 59 def image_to_function(name, function, html_options = {})
60 60 html_options.symbolize_keys!
61 61 tag(:input, html_options.merge({
62 62 :type => "image", :src => image_path(name),
63 63 :onclick => (html_options[:onclick] ? "#{html_options[:onclick]}; " : "") + "#{function};"
64 64 }))
65 65 end
66 66
67 67 def prompt_to_remote(name, text, param, url, html_options = {})
68 68 html_options[:onclick] = "promptToRemote('#{text}', '#{param}', '#{url_for(url)}'); return false;"
69 69 link_to name, {}, html_options
70 70 end
71 71
72 72 def format_date(date)
73 73 return nil unless date
74 74 # "Setting.date_format.size < 2" is a temporary fix (content of date_format setting changed)
75 75 @date_format ||= (Setting.date_format.blank? || Setting.date_format.size < 2 ? l(:general_fmt_date) : Setting.date_format)
76 76 date.strftime(@date_format)
77 77 end
78 78
79 79 def format_time(time, include_date = true)
80 80 return nil unless time
81 81 time = time.to_time if time.is_a?(String)
82 82 zone = User.current.time_zone
83 83 if time.utc?
84 84 local = zone ? zone.adjust(time) : time.getlocal
85 85 else
86 86 local = zone ? zone.adjust(time.getutc) : time
87 87 end
88 88 @date_format ||= (Setting.date_format.blank? || Setting.date_format.size < 2 ? l(:general_fmt_date) : Setting.date_format)
89 89 @time_format ||= (Setting.time_format.blank? ? l(:general_fmt_time) : Setting.time_format)
90 90 include_date ? local.strftime("#{@date_format} #{@time_format}") : local.strftime(@time_format)
91 91 end
92 92
93 93 def html_hours(text)
94 94 text.gsub(%r{(\d+)\.(\d+)}, '<span class="hours hours-int">\1</span><span class="hours hours-dec">.\2</span>')
95 95 end
96 96
97 97 def authoring(created, author)
98 98 time_tag = content_tag('acronym', distance_of_time_in_words(Time.now, created), :title => format_time(created))
99 99 l(:label_added_time_by, author || 'Anonymous', time_tag)
100 100 end
101 101
102 102 def l_or_humanize(s)
103 103 l_has_string?("label_#{s}".to_sym) ? l("label_#{s}".to_sym) : s.to_s.humanize
104 104 end
105 105
106 106 def day_name(day)
107 107 l(:general_day_names).split(',')[day-1]
108 108 end
109 109
110 110 def month_name(month)
111 111 l(:actionview_datehelper_select_month_names).split(',')[month-1]
112 112 end
113 113
114 114 def pagination_links_full(paginator, count=nil, options={})
115 115 page_param = options.delete(:page_param) || :page
116 116 url_param = params.dup
117 117 # don't reuse params if filters are present
118 118 url_param.clear if url_param.has_key?(:set_filter)
119 119
120 120 html = ''
121 121 html << link_to_remote(('&#171; ' + l(:label_previous)),
122 122 {:update => 'content',
123 123 :url => url_param.merge(page_param => paginator.current.previous),
124 124 :complete => 'window.scrollTo(0,0)'},
125 125 {:href => url_for(:params => url_param.merge(page_param => paginator.current.previous))}) + ' ' if paginator.current.previous
126 126
127 127 html << (pagination_links_each(paginator, options) do |n|
128 128 link_to_remote(n.to_s,
129 129 {:url => {:params => url_param.merge(page_param => n)},
130 130 :update => 'content',
131 131 :complete => 'window.scrollTo(0,0)'},
132 132 {:href => url_for(:params => url_param.merge(page_param => n))})
133 133 end || '')
134 134
135 135 html << ' ' + link_to_remote((l(:label_next) + ' &#187;'),
136 136 {:update => 'content',
137 137 :url => url_param.merge(page_param => paginator.current.next),
138 138 :complete => 'window.scrollTo(0,0)'},
139 139 {:href => url_for(:params => url_param.merge(page_param => paginator.current.next))}) if paginator.current.next
140 140
141 141 unless count.nil?
142 142 html << [" (#{paginator.current.first_item}-#{paginator.current.last_item}/#{count})", per_page_links(paginator.items_per_page)].compact.join(' | ')
143 143 end
144 144
145 145 html
146 146 end
147 147
148 148 def per_page_links(selected=nil)
149 149 url_param = params.dup
150 150 url_param.clear if url_param.has_key?(:set_filter)
151 151
152 152 links = Setting.per_page_options_array.collect do |n|
153 153 n == selected ? n : link_to_remote(n, {:update => "content", :url => params.dup.merge(:per_page => n)},
154 154 {:href => url_for(url_param.merge(:per_page => n))})
155 155 end
156 156 links.size > 1 ? l(:label_display_per_page, links.join(', ')) : nil
157 157 end
158 158
159 159 def breadcrumb(*args)
160 160 content_tag('p', args.join(' &#187; ') + ' &#187; ', :class => 'breadcrumb')
161 161 end
162 162
163 163 def html_title(*args)
164 164 if args.empty?
165 165 title = []
166 166 title << @project.name if @project
167 167 title += @html_title if @html_title
168 168 title << Setting.app_title
169 169 title.compact.join(' - ')
170 170 else
171 171 @html_title ||= []
172 172 @html_title += args
173 173 end
174 174 end
175 175
176 176 def accesskey(s)
177 177 Redmine::AccessKeys.key_for s
178 178 end
179 179
180 180 # Formats text according to system settings.
181 181 # 2 ways to call this method:
182 182 # * with a String: textilizable(text, options)
183 183 # * with an object and one of its attribute: textilizable(issue, :description, options)
184 184 def textilizable(*args)
185 185 options = args.last.is_a?(Hash) ? args.pop : {}
186 186 case args.size
187 187 when 1
188 188 obj = nil
189 189 text = args.shift
190 190 when 2
191 191 obj = args.shift
192 192 text = obj.send(args.shift).to_s
193 193 else
194 194 raise ArgumentError, 'invalid arguments to textilizable'
195 195 end
196 196 return '' if text.blank?
197 197
198 198 only_path = options.delete(:only_path) == false ? false : true
199 199
200 200 # when using an image link, try to use an attachment, if possible
201 201 attachments = options[:attachments] || (obj && obj.respond_to?(:attachments) ? obj.attachments : nil)
202 202
203 203 if attachments
204 204 text = text.gsub(/!((\<|\=|\>)?(\([^\)]+\))?(\[[^\]]+\])?(\{[^\}]+\})?)(\S+\.(gif|jpg|jpeg|png))!/) do |m|
205 205 style = $1
206 206 filename = $6
207 207 rf = Regexp.new(filename, Regexp::IGNORECASE)
208 208 # search for the picture in attachments
209 209 if found = attachments.detect { |att| att.filename =~ rf }
210 210 image_url = url_for :only_path => only_path, :controller => 'attachments', :action => 'download', :id => found.id
211 211 "!#{style}#{image_url}!"
212 212 else
213 213 "!#{style}#{filename}!"
214 214 end
215 215 end
216 216 end
217 217
218 218 text = (Setting.text_formatting == 'textile') ?
219 219 Redmine::WikiFormatting.to_html(text) { |macro, args| exec_macro(macro, obj, args) } :
220 220 simple_format(auto_link(h(text)))
221 221
222 222 # different methods for formatting wiki links
223 223 case options[:wiki_links]
224 224 when :local
225 225 # used for local links to html files
226 226 format_wiki_link = Proc.new {|project, title| "#{title}.html" }
227 227 when :anchor
228 228 # used for single-file wiki export
229 229 format_wiki_link = Proc.new {|project, title| "##{title}" }
230 230 else
231 231 format_wiki_link = Proc.new {|project, title| url_for(:only_path => only_path, :controller => 'wiki', :action => 'index', :id => project, :page => title) }
232 232 end
233 233
234 234 project = options[:project] || @project || (obj && obj.respond_to?(:project) ? obj.project : nil)
235 235
236 236 # Wiki links
237 237 #
238 238 # Examples:
239 239 # [[mypage]]
240 240 # [[mypage|mytext]]
241 241 # wiki links can refer other project wikis, using project name or identifier:
242 242 # [[project:]] -> wiki starting page
243 243 # [[project:|mytext]]
244 244 # [[project:mypage]]
245 245 # [[project:mypage|mytext]]
246 246 text = text.gsub(/(!)?(\[\[([^\]\n\|]+)(\|([^\]\n\|]+))?\]\])/) do |m|
247 247 link_project = project
248 248 esc, all, page, title = $1, $2, $3, $5
249 249 if esc.nil?
250 250 if page =~ /^([^\:]+)\:(.*)$/
251 251 link_project = Project.find_by_name($1) || Project.find_by_identifier($1)
252 252 page = $2
253 253 title ||= $1 if page.blank?
254 254 end
255 255
256 256 if link_project && link_project.wiki
257 257 # check if page exists
258 258 wiki_page = link_project.wiki.find_page(page)
259 259 link_to((title || page), format_wiki_link.call(link_project, Wiki.titleize(page)),
260 260 :class => ('wiki-page' + (wiki_page ? '' : ' new')))
261 261 else
262 262 # project or wiki doesn't exist
263 263 title || page
264 264 end
265 265 else
266 266 all
267 267 end
268 268 end
269 269
270 270 # Redmine links
271 271 #
272 272 # Examples:
273 273 # Issues:
274 274 # #52 -> Link to issue #52
275 275 # Changesets:
276 276 # r52 -> Link to revision 52
277 277 # commit:a85130f -> Link to scmid starting with a85130f
278 278 # Documents:
279 279 # document#17 -> Link to document with id 17
280 280 # document:Greetings -> Link to the document with title "Greetings"
281 281 # document:"Some document" -> Link to the document with title "Some document"
282 282 # Versions:
283 283 # version#3 -> Link to version with id 3
284 284 # version:1.0.0 -> Link to version named "1.0.0"
285 285 # version:"1.0 beta 2" -> Link to version named "1.0 beta 2"
286 286 # Attachments:
287 287 # attachment:file.zip -> Link to the attachment of the current object named file.zip
288 288 # Source files:
289 289 # source:some/file -> Link to the file located at /some/file in the project's repository
290 290 # source:some/file@52 -> Link to the file's revision 52
291 291 # source:some/file#L120 -> Link to line 120 of the file
292 292 # source:some/file@52#L120 -> Link to line 120 of the file's revision 52
293 293 # export:some/file -> Force the download of the file
294 294 text = text.gsub(%r{([\s\(,-^])(!)?(attachment|document|version|commit|source|export)?((#|r)(\d+)|(:)([^"\s<>][^\s<>]*|"[^"]+"))(?=[[:punct:]]|\s|<|$)}) do |m|
295 295 leading, esc, prefix, sep, oid = $1, $2, $3, $5 || $7, $6 || $8
296 296 link = nil
297 297 if esc.nil?
298 298 if prefix.nil? && sep == 'r'
299 299 if project && (changeset = project.changesets.find_by_revision(oid))
300 300 link = link_to("r#{oid}", {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :rev => oid},
301 301 :class => 'changeset',
302 302 :title => truncate(changeset.comments, 100))
303 303 end
304 304 elsif sep == '#'
305 305 oid = oid.to_i
306 306 case prefix
307 307 when nil
308 308 if issue = Issue.find_by_id(oid, :include => [:project, :status], :conditions => Project.visible_by(User.current))
309 309 link = link_to("##{oid}", {:only_path => only_path, :controller => 'issues', :action => 'show', :id => oid},
310 310 :class => (issue.closed? ? 'issue closed' : 'issue'),
311 311 :title => "#{truncate(issue.subject, 100)} (#{issue.status.name})")
312 312 link = content_tag('del', link) if issue.closed?
313 313 end
314 314 when 'document'
315 315 if document = Document.find_by_id(oid, :include => [:project], :conditions => Project.visible_by(User.current))
316 316 link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document},
317 317 :class => 'document'
318 318 end
319 319 when 'version'
320 320 if version = Version.find_by_id(oid, :include => [:project], :conditions => Project.visible_by(User.current))
321 321 link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
322 322 :class => 'version'
323 323 end
324 324 end
325 325 elsif sep == ':'
326 326 # removes the double quotes if any
327 327 name = oid.gsub(%r{^"(.*)"$}, "\\1")
328 328 case prefix
329 329 when 'document'
330 330 if project && document = project.documents.find_by_title(name)
331 331 link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document},
332 332 :class => 'document'
333 333 end
334 334 when 'version'
335 335 if project && version = project.versions.find_by_name(name)
336 336 link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
337 337 :class => 'version'
338 338 end
339 339 when 'commit'
340 340 if project && (changeset = project.changesets.find(:first, :conditions => ["scmid LIKE ?", "#{name}%"]))
341 341 link = link_to h("#{name}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :rev => changeset.revision}, :class => 'changeset', :title => truncate(changeset.comments, 100)
342 342 end
343 343 when 'source', 'export'
344 344 if project && project.repository
345 345 name =~ %r{^[/\\]*(.*?)(@([0-9a-f]+))?(#(L\d+))?$}
346 346 path, rev, anchor = $1, $3, $5
347 347 link = link_to h("#{prefix}:#{name}"), {:controller => 'repositories', :action => 'entry', :id => project, :path => path,
348 348 :rev => rev,
349 349 :anchor => anchor,
350 350 :format => (prefix == 'export' ? 'raw' : nil)},
351 351 :class => (prefix == 'export' ? 'source download' : 'source')
352 352 end
353 353 when 'attachment'
354 354 if attachments && attachment = attachments.detect {|a| a.filename == name }
355 355 link = link_to h(attachment.filename), {:only_path => only_path, :controller => 'attachments', :action => 'download', :id => attachment},
356 356 :class => 'attachment'
357 357 end
358 358 end
359 359 end
360 360 end
361 361 leading + (link || "#{prefix}#{sep}#{oid}")
362 362 end
363 363
364 364 text
365 365 end
366 366
367 367 # Same as Rails' simple_format helper without using paragraphs
368 368 def simple_format_without_paragraph(text)
369 369 text.to_s.
370 370 gsub(/\r\n?/, "\n"). # \r\n and \r -> \n
371 371 gsub(/\n\n+/, "<br /><br />"). # 2+ newline -> 2 br
372 372 gsub(/([^\n]\n)(?=[^\n])/, '\1<br />') # 1 newline -> br
373 373 end
374 374
375 375 def error_messages_for(object_name, options = {})
376 376 options = options.symbolize_keys
377 377 object = instance_variable_get("@#{object_name}")
378 378 if object && !object.errors.empty?
379 379 # build full_messages here with controller current language
380 380 full_messages = []
381 381 object.errors.each do |attr, msg|
382 382 next if msg.nil?
383 383 msg = msg.first if msg.is_a? Array
384 384 if attr == "base"
385 385 full_messages << l(msg)
386 386 else
387 387 full_messages << "&#171; " + (l_has_string?("field_" + attr) ? l("field_" + attr) : object.class.human_attribute_name(attr)) + " &#187; " + l(msg) unless attr == "custom_values"
388 388 end
389 389 end
390 390 # retrieve custom values error messages
391 391 if object.errors[:custom_values]
392 392 object.custom_values.each do |v|
393 393 v.errors.each do |attr, msg|
394 394 next if msg.nil?
395 395 msg = msg.first if msg.is_a? Array
396 396 full_messages << "&#171; " + v.custom_field.name + " &#187; " + l(msg)
397 397 end
398 398 end
399 399 end
400 400 content_tag("div",
401 401 content_tag(
402 402 options[:header_tag] || "span", lwr(:gui_validation_error, full_messages.length) + ":"
403 403 ) +
404 404 content_tag("ul", full_messages.collect { |msg| content_tag("li", msg) }),
405 405 "id" => options[:id] || "errorExplanation", "class" => options[:class] || "errorExplanation"
406 406 )
407 407 else
408 408 ""
409 409 end
410 410 end
411 411
412 412 def lang_options_for_select(blank=true)
413 413 (blank ? [["(auto)", ""]] : []) +
414 414 GLoc.valid_languages.collect{|lang| [ ll(lang.to_s, :general_lang_name), lang.to_s]}.sort{|x,y| x.last <=> y.last }
415 415 end
416 416
417 417 def label_tag_for(name, option_tags = nil, options = {})
418 418 label_text = l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) + (options.delete(:required) ? @template.content_tag("span", " *", :class => "required"): "")
419 419 content_tag("label", label_text)
420 420 end
421 421
422 422 def labelled_tabular_form_for(name, object, options, &proc)
423 423 options[:html] ||= {}
424 424 options[:html][:class] = 'tabular' unless options[:html].has_key?(:class)
425 425 form_for(name, object, options.merge({ :builder => TabularFormBuilder, :lang => current_language}), &proc)
426 426 end
427 427
428 428 def check_all_links(form_name)
429 429 link_to_function(l(:button_check_all), "checkAll('#{form_name}', true)") +
430 430 " | " +
431 431 link_to_function(l(:button_uncheck_all), "checkAll('#{form_name}', false)")
432 432 end
433 433
434 434 def progress_bar(pcts, options={})
435 435 pcts = [pcts, pcts] unless pcts.is_a?(Array)
436 436 pcts[1] = pcts[1] - pcts[0]
437 437 pcts << (100 - pcts[1] - pcts[0])
438 438 width = options[:width] || '100px;'
439 439 legend = options[:legend] || ''
440 440 content_tag('table',
441 441 content_tag('tr',
442 442 (pcts[0] > 0 ? content_tag('td', '', :width => "#{pcts[0].floor}%;", :class => 'closed') : '') +
443 443 (pcts[1] > 0 ? content_tag('td', '', :width => "#{pcts[1].floor}%;", :class => 'done') : '') +
444 444 (pcts[2] > 0 ? content_tag('td', '', :width => "#{pcts[2].floor}%;", :class => 'todo') : '')
445 445 ), :class => 'progress', :style => "width: #{width};") +
446 446 content_tag('p', legend, :class => 'pourcent')
447 447 end
448 448
449 449 def context_menu_link(name, url, options={})
450 450 options[:class] ||= ''
451 451 if options.delete(:selected)
452 452 options[:class] << ' icon-checked disabled'
453 453 options[:disabled] = true
454 454 end
455 455 if options.delete(:disabled)
456 456 options.delete(:method)
457 457 options.delete(:confirm)
458 458 options.delete(:onclick)
459 459 options[:class] << ' disabled'
460 460 url = '#'
461 461 end
462 462 link_to name, url, options
463 463 end
464 464
465 465 def calendar_for(field_id)
466 include_calendar_headers_tags
466 467 image_tag("calendar.png", {:id => "#{field_id}_trigger",:class => "calendar-trigger"}) +
467 468 javascript_tag("Calendar.setup({inputField : '#{field_id}', ifFormat : '%Y-%m-%d', button : '#{field_id}_trigger' });")
468 469 end
470
471 def include_calendar_headers_tags
472 unless @calendar_headers_tags_included
473 @calendar_headers_tags_included = true
474 content_for :header_tags do
475 javascript_include_tag('calendar/calendar') +
476 javascript_include_tag("calendar/lang/calendar-#{current_language}.js") +
477 javascript_include_tag('calendar/calendar-setup') +
478 stylesheet_link_tag('calendar')
479 end
480 end
481 end
469 482
470 483 def wikitoolbar_for(field_id)
471 484 return '' unless Setting.text_formatting == 'textile'
472 485
473 486 help_link = l(:setting_text_formatting) + ': ' +
474 487 link_to(l(:label_help), compute_public_path('wiki_syntax', 'help', 'html'),
475 488 :onclick => "window.open(\"#{ compute_public_path('wiki_syntax', 'help', 'html') }\", \"\", \"resizable=yes, location=no, width=300, height=640, menubar=no, status=no, scrollbars=yes\"); return false;")
476 489
477 490 javascript_include_tag('jstoolbar/jstoolbar') +
478 491 javascript_include_tag("jstoolbar/lang/jstoolbar-#{current_language}") +
479 492 javascript_tag("var toolbar = new jsToolBar($('#{field_id}')); toolbar.setHelpLink('#{help_link}'); toolbar.draw();")
480 493 end
481 494
482 495 def content_for(name, content = nil, &block)
483 496 @has_content ||= {}
484 497 @has_content[name] = true
485 498 super(name, content, &block)
486 499 end
487 500
488 501 def has_content?(name)
489 502 (@has_content && @has_content[name]) || false
490 503 end
491 504 end
@@ -1,44 +1,37
1 1 <h2><%=l(:label_register)%></h2>
2 2
3 3 <% form_tag({:action => 'register'}, :class => "tabular") do %>
4 4 <%= error_messages_for 'user' %>
5 5
6 6 <div class="box">
7 7 <!--[form:user]-->
8 8 <p><label for="user_login"><%=l(:field_login)%> <span class="required">*</span></label>
9 9 <%= text_field 'user', 'login', :size => 25 %></p>
10 10
11 11 <p><label for="password"><%=l(:field_password)%> <span class="required">*</span></label>
12 12 <%= password_field_tag 'password', nil, :size => 25 %><br />
13 13 <em><%= l(:text_caracters_minimum, 4) %></em></p>
14 14
15 15 <p><label for="password_confirmation"><%=l(:field_password_confirmation)%> <span class="required">*</span></label>
16 16 <%= password_field_tag 'password_confirmation', nil, :size => 25 %></p>
17 17
18 18 <p><label for="user_firstname"><%=l(:field_firstname)%> <span class="required">*</span></label>
19 19 <%= text_field 'user', 'firstname' %></p>
20 20
21 21 <p><label for="user_lastname"><%=l(:field_lastname)%> <span class="required">*</span></label>
22 22 <%= text_field 'user', 'lastname' %></p>
23 23
24 24 <p><label for="user_mail"><%=l(:field_mail)%> <span class="required">*</span></label>
25 25 <%= text_field 'user', 'mail' %></p>
26 26
27 27 <p><label for="user_language"><%=l(:field_language)%></label>
28 28 <%= select("user", "language", lang_options_for_select) %></p>
29 29
30 30 <% for @custom_value in @custom_values %>
31 31 <p><%= custom_field_tag_with_label @custom_value %></p>
32 32 <% end %>
33 33 <!--[eoform:user]-->
34 34 </div>
35 35
36 36 <%= submit_tag l(:button_submit) %>
37 37 <% end %>
38
39 <% content_for :header_tags do %>
40 <%= javascript_include_tag 'calendar/calendar' %>
41 <%= javascript_include_tag "calendar/lang/calendar-#{current_language}.js" %>
42 <%= javascript_include_tag 'calendar/calendar-setup' %>
43 <%= stylesheet_link_tag 'calendar' %>
44 <% end %>
@@ -1,58 +1,51
1 1 <% if @issue.new_record? %>
2 2 <p><%= f.select :tracker_id, @project.trackers.collect {|t| [t.name, t.id]}, :required => true %></p>
3 3 <%= observe_field :issue_tracker_id, :url => { :action => :new },
4 4 :update => :content,
5 5 :with => "Form.serialize('issue-form')" %>
6 6 <hr />
7 7 <% end %>
8 8
9 9 <div id="issue_descr_fields" <%= 'style="display:none"' unless @issue.new_record? || @issue.errors.any? %>>
10 10 <p><%= f.text_field :subject, :size => 80, :required => true %></p>
11 11 <p><%= f.text_area :description, :required => true,
12 12 :cols => 60,
13 13 :rows => (@issue.description.blank? ? 10 : [[10, @issue.description.length / 50].max, 100].min),
14 14 :accesskey => accesskey(:edit),
15 15 :class => 'wiki-edit' %></p>
16 16 </div>
17 17
18 18 <div class="splitcontentleft">
19 19 <% if @issue.new_record? || @allowed_statuses.any? %>
20 20 <p><%= f.select :status_id, (@allowed_statuses.collect {|p| [p.name, p.id]}), :required => true %></p>
21 21 <% else %>
22 22 <p><label><%= l(:field_status) %></label> <%= @issue.status.name %></p>
23 23 <% end %>
24 24
25 25 <p><%= f.select :priority_id, (@priorities.collect {|p| [p.name, p.id]}), :required => true %></p>
26 26 <p><%= f.select :assigned_to_id, (@issue.assignable_users.collect {|m| [m.name, m.id]}), :include_blank => true %></p>
27 27 <p><%= f.select :category_id, (@project.issue_categories.collect {|c| [c.name, c.id]}), :include_blank => true %>
28 28 <%= prompt_to_remote(l(:label_issue_category_new),
29 29 l(:label_issue_category_new), 'category[name]',
30 30 {:controller => 'projects', :action => 'add_issue_category', :id => @project},
31 31 :class => 'small', :tabindex => 199) if authorize_for('projects', 'add_issue_category') %></p>
32 32 <%= content_tag('p', f.select(:fixed_version_id,
33 33 (@project.versions.sort.collect {|v| [v.name, v.id]}),
34 34 { :include_blank => true })) unless @project.versions.empty? %>
35 35 </div>
36 36
37 37 <div class="splitcontentright">
38 38 <p><%= f.text_field :start_date, :size => 10 %><%= calendar_for('issue_start_date') %></p>
39 39 <p><%= f.text_field :due_date, :size => 10 %><%= calendar_for('issue_due_date') %></p>
40 40 <p><%= f.text_field :estimated_hours, :size => 3 %> <%= l(:field_hours) %></p>
41 41 <p><%= f.select :done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %></p>
42 42 </div>
43 43
44 44 <div style="clear:both;"> </div>
45 45 <%= render :partial => 'form_custom_fields', :locals => {:values => @custom_values} %>
46 46
47 47 <% if @issue.new_record? %>
48 48 <p><label><%=l(:label_attachment_plural)%></label><%= render :partial => 'attachments/form' %></p>
49 49 <% end %>
50 50
51 51 <%= wikitoolbar_for 'issue_description' %>
52
53 <% content_for :header_tags do %>
54 <%= javascript_include_tag 'calendar/calendar' %>
55 <%= javascript_include_tag "calendar/lang/calendar-#{current_language}.js" %>
56 <%= javascript_include_tag 'calendar/calendar-setup' %>
57 <%= stylesheet_link_tag 'calendar' %>
58 <% end %>
@@ -1,56 +1,49
1 1 <h2><%= l(:label_bulk_edit_selected_issues) %></h2>
2 2
3 3 <ul><%= @issues.collect {|i| content_tag('li', link_to(h("#{i.tracker} ##{i.id}"), { :action => 'show', :id => i }) + h(": #{i.subject}")) }.join("\n") %></ul>
4 4
5 5 <% form_tag() do %>
6 6 <%= @issues.collect {|i| hidden_field_tag('ids[]', i.id)}.join %>
7 7 <div class="box">
8 8 <fieldset>
9 9 <legend><%= l(:label_change_properties) %></legend>
10 10 <p>
11 11 <% if @available_statuses.any? %>
12 12 <label><%= l(:field_status) %>:
13 13 <%= select_tag('status_id', "<option value=\"\">#{l(:label_no_change_option)}</option>" + options_from_collection_for_select(@available_statuses, :id, :name)) %></label>
14 14 <% end %>
15 15 <label><%= l(:field_priority) %>:
16 16 <%= select_tag('priority_id', "<option value=\"\">#{l(:label_no_change_option)}</option>" + options_from_collection_for_select(Enumeration.get_values('IPRI'), :id, :name)) %></label>
17 17 <label><%= l(:field_category) %>:
18 18 <%= select_tag('category_id', content_tag('option', l(:label_no_change_option), :value => '') +
19 19 content_tag('option', l(:label_none), :value => 'none') +
20 20 options_from_collection_for_select(@project.issue_categories, :id, :name)) %></label>
21 21 </p>
22 22 <p>
23 23 <label><%= l(:field_assigned_to) %>:
24 24 <%= select_tag('assigned_to_id', content_tag('option', l(:label_no_change_option), :value => '') +
25 25 content_tag('option', l(:label_nobody), :value => 'none') +
26 26 options_from_collection_for_select(@project.assignable_users, :id, :name)) %></label>
27 27 <label><%= l(:field_fixed_version) %>:
28 28 <%= select_tag('fixed_version_id', content_tag('option', l(:label_no_change_option), :value => '') +
29 29 content_tag('option', l(:label_none), :value => 'none') +
30 30 options_from_collection_for_select(@project.versions, :id, :name)) %></label>
31 31 </p>
32 32
33 33 <p>
34 34 <label><%= l(:field_start_date) %>:
35 35 <%= text_field_tag 'start_date', '', :size => 10 %><%= calendar_for('start_date') %></label>
36 36 <label><%= l(:field_due_date) %>:
37 37 <%= text_field_tag 'due_date', '', :size => 10 %><%= calendar_for('due_date') %></label>
38 38 <label><%= l(:field_done_ratio) %>:
39 39 <%= select_tag 'done_ratio', options_for_select([[l(:label_no_change_option), '']] + (0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %></label>
40 40 </p>
41 41 </fieldset>
42 42
43 43 <fieldset><legend><%= l(:field_notes) %></legend>
44 44 <%= text_area_tag 'notes', @notes, :cols => 60, :rows => 10, :class => 'wiki-edit' %>
45 45 <%= wikitoolbar_for 'notes' %>
46 46 </div>
47 47
48 48 <p><%= submit_tag l(:button_submit) %>
49 49 <% end %>
50
51 <% content_for :header_tags do %>
52 <%= javascript_include_tag 'calendar/calendar' %>
53 <%= javascript_include_tag "calendar/lang/calendar-#{current_language}.js" %>
54 <%= javascript_include_tag 'calendar/calendar-setup' %>
55 <%= stylesheet_link_tag 'calendar' %>
56 <% end %>
@@ -1,56 +1,48
1 1 <%= error_messages_for 'project' %>
2 2
3 3 <div class="box">
4 4 <!--[form:project]-->
5 5 <p><%= f.text_field :name, :required => true %><br /><em><%= l(:text_caracters_maximum, 30) %></em></p>
6 6
7 7 <% if User.current.admin? and !@root_projects.empty? %>
8 8 <p><%= f.select :parent_id, (@root_projects.collect {|p| [p.name, p.id]}), { :include_blank => true } %></p>
9 9 <% end %>
10 10
11 11 <p><%= f.text_area :description, :rows => 5, :class => 'wiki-edit' %></p>
12 12 <p><%= f.text_field :identifier, :required => true, :disabled => @project.identifier_frozen? %>
13 13 <% unless @project.identifier_frozen? %>
14 14 <br /><em><%= l(:text_length_between, 3, 20) %> <%= l(:text_project_identifier_info) %></em>
15 15 <% end %></p>
16 16 <p><%= f.text_field :homepage, :size => 40 %></p>
17 17 <p><%= f.check_box :is_public %></p>
18 18 <%= wikitoolbar_for 'project_description' %>
19 19
20 20 <% for @custom_value in @custom_values %>
21 21 <p><%= custom_field_tag_with_label @custom_value %></p>
22 22 <% end %>
23 23 </div>
24 24
25 25 <% unless @trackers.empty? %>
26 26 <fieldset class="box"><legend><%=l(:label_tracker_plural)%></legend>
27 27 <% @trackers.each do |tracker| %>
28 28 <label class="floating">
29 29 <%= check_box_tag 'project[tracker_ids][]', tracker.id, @project.trackers.include?(tracker) %>
30 30 <%= tracker %>
31 31 </label>
32 32 <% end %>
33 33 <%= hidden_field_tag 'project[tracker_ids][]', '' %>
34 34 </fieldset>
35 35 <% end %>
36 36
37 37 <% unless @custom_fields.empty? %>
38 38 <fieldset class="box"><legend><%=l(:label_custom_field_plural)%></legend>
39 39 <% for custom_field in @custom_fields %>
40 40 <label class="floating">
41 41 <%= check_box_tag 'project[custom_field_ids][]', custom_field.id, ((@project.custom_fields.include? custom_field) or custom_field.is_for_all?), (custom_field.is_for_all? ? {:disabled => "disabled"} : {}) %>
42 42 <%= custom_field.name %>
43 43 </label>
44 44 <% end %>
45 45 <%= hidden_field_tag 'project[custom_field_ids][]', '' %>
46 46 </fieldset>
47 47 <% end %>
48 48 <!--[eoform:project]-->
49
50
51 <% content_for :header_tags do %>
52 <%= javascript_include_tag 'calendar/calendar' %>
53 <%= javascript_include_tag "calendar/lang/calendar-#{current_language}.js" %>
54 <%= javascript_include_tag 'calendar/calendar-setup' %>
55 <%= stylesheet_link_tag 'calendar' %>
56 <% end %>
@@ -1,53 +1,46
1 1 <div class="contextual">
2 2 <%= link_to(l(:label_report), {:controller => 'timelog', :action => 'report', :project_id => @project}, :class => 'icon icon-report') %>
3 3 <%= link_to_if_authorized l(:button_log_time), {:controller => 'timelog', :action => 'edit', :project_id => @project, :issue_id => @issue}, :class => 'icon icon-time' %>
4 4 </div>
5 5
6 6 <h2><%= l(:label_spent_time) %></h2>
7 7
8 8 <% if @issue %>
9 9 <h3><%= link_to(@project.name, {:action => 'details', :project_id => @project}) %> / <%= link_to_issue(@issue) %></h3>
10 10 <% end %>
11 11
12 12 <% form_remote_tag( :url => {}, :method => :get, :update => 'content' ) do %>
13 13 <%= hidden_field_tag 'project_id', params[:project_id] %>
14 14 <%= hidden_field_tag 'issue_id', params[:issue_id] if @issue %>
15 15
16 16 <fieldset><legend><%= l(:label_date_range) %></legend>
17 17 <p>
18 18 <%= radio_button_tag 'period_type', '1', !@free_period %>
19 19 <%= select_tag 'period', options_for_period_select(params[:period]),
20 20 :onchange => 'this.form.onsubmit();',
21 21 :onfocus => '$("period_type_1").checked = true;' %>
22 22 </p>
23 23 <p>
24 24 <%= radio_button_tag 'period_type', '2', @free_period %>
25 25 <%= l(:label_date_from) %>
26 26 <%= text_field_tag 'from', @from, :size => 10, :onfocus => '$("period_type_2").checked = true;' %> <%= calendar_for('from') %>
27 27 <%= l(:label_date_to) %>
28 28 <%= text_field_tag 'to', @to, :size => 10, :onfocus => '$("period_type_2").checked = true;' %> <%= calendar_for('to') %>
29 29 <%= submit_tag l(:button_apply), :name => nil, :onclick => '$("period_type_2").checked = true;' %>
30 30 </p>
31 31 </fieldset>
32 32 <% end %>
33 33
34 34 <div class="total-hours">
35 35 <p><%= l(:label_total) %>: <%= html_hours(lwr(:label_f_hour, @total_hours)) %></p>
36 36 </div>
37 37
38 38 <% unless @entries.empty? %>
39 39 <%= render :partial => 'list', :locals => { :entries => @entries }%>
40 40 <p class="pagination"><%= pagination_links_full @entry_pages, @entry_count %></p>
41 41
42 42 <p class="other-formats">
43 43 <%= l(:label_export_to) %>
44 44 <span><%= link_to 'CSV', params.merge(:format => 'csv'), :class => 'csv' %></span>
45 45 </p>
46 46 <% end %>
47
48 <% content_for :header_tags do %>
49 <%= javascript_include_tag 'calendar/calendar' %>
50 <%= javascript_include_tag "calendar/lang/calendar-#{current_language}.js" %>
51 <%= javascript_include_tag 'calendar/calendar-setup' %>
52 <%= stylesheet_link_tag 'calendar' %>
53 <% end %>
@@ -1,23 +1,16
1 1 <h2><%= l(:label_spent_time) %></h2>
2 2
3 3 <% labelled_tabular_form_for :time_entry, @time_entry, :url => {:action => 'edit', :project_id => @time_entry.project} do |f| %>
4 4 <%= error_messages_for 'time_entry' %>
5 5
6 6 <div class="box">
7 7 <p><%= f.text_field :issue_id, :size => 6 %> <em><%= h("#{@time_entry.issue.tracker.name} ##{@time_entry.issue.id}: #{@time_entry.issue.subject}") if @time_entry.issue %></em></p>
8 8 <p><%= f.text_field :spent_on, :size => 10, :required => true %><%= calendar_for('time_entry_spent_on') %></p>
9 9 <p><%= f.text_field :hours, :size => 6, :required => true %></p>
10 10 <p><%= f.text_field :comments, :size => 100 %></p>
11 11 <p><%= f.select :activity_id, (@activities.collect {|p| [p.name, p.id]}), :required => true %></p>
12 12 </div>
13 13
14 14 <%= submit_tag l(:button_save) %>
15 15
16 16 <% end %>
17
18 <% content_for :header_tags do %>
19 <%= javascript_include_tag 'calendar/calendar' %>
20 <%= javascript_include_tag "calendar/lang/calendar-#{current_language}.js" %>
21 <%= javascript_include_tag 'calendar/calendar-setup' %>
22 <%= stylesheet_link_tag 'calendar' %>
23 <% end %> No newline at end of file
@@ -1,72 +1,65
1 1 <div class="contextual">
2 2 <%= link_to(l(:label_details), {:controller => 'timelog', :action => 'details', :project_id => @project}, :class => 'icon icon-details') %>
3 3 <%= link_to_if_authorized l(:button_log_time), {:controller => 'timelog', :action => 'edit', :project_id => @project, :issue_id => @issue}, :class => 'icon icon-time' %>
4 4 </div>
5 5
6 6 <h2><%= l(:label_spent_time) %></h2>
7 7
8 8 <% form_remote_tag(:url => {:project_id => @project}, :update => 'content') do %>
9 9 <% @criterias.each do |criteria| %>
10 10 <%= hidden_field_tag 'criterias[]', criteria %>
11 11 <% end %>
12 12 <fieldset><legend><%= l(:label_date_range) %></legend>
13 13 <p>
14 14 <%= l(:label_date_from) %>
15 15 <%= text_field_tag 'date_from', @date_from, :size => 10 %><%= calendar_for('date_from') %>
16 16 <%= l(:label_date_to) %>
17 17 <%= text_field_tag 'date_to', @date_to, :size => 10 %><%= calendar_for('date_to') %>
18 18 <%= l(:label_details) %>
19 19 <%= select_tag 'period', options_for_select([[l(:label_year), 'year'],
20 20 [l(:label_month), 'month'],
21 21 [l(:label_week), 'week']], @columns) %>
22 22 &nbsp;
23 23 <%= submit_tag l(:button_apply) %>
24 24 </p>
25 25 </fieldset>
26 26
27 27 <p><%= l(:button_add) %>: <%= select_tag('criterias[]', options_for_select([[]] + (@available_criterias.keys - @criterias).collect{|k| [l(@available_criterias[k][:label]), k]}),
28 28 :onchange => "this.form.onsubmit();",
29 29 :style => 'width: 200px',
30 30 :disabled => (@criterias.length >= 3)) %>
31 31 <%= link_to_remote l(:button_clear), {:url => {:project_id => @project, :date_from => @date_from, :date_to => @date_to, :period => @columns}, :update => 'content'},
32 32 :class => 'icon icon-reload' %></p>
33 33
34 34 <% unless @criterias.empty? %>
35 35 <div class="total-hours">
36 36 <p><%= l(:label_total) %>: <%= html_hours(lwr(:label_f_hour, @total_hours)) %></p>
37 37 </div>
38 38
39 39 <% unless @hours.empty? %>
40 40 <table class="list" id="time-report">
41 41 <thead>
42 42 <tr>
43 43 <% @criterias.each do |criteria| %>
44 44 <th width="15%"><%= l(@available_criterias[criteria][:label]) %></th>
45 45 <% end %>
46 46 <% @periods.each do |period| %>
47 47 <th width="<%= ((100 - @criterias.length * 15 - 15 ) / @periods.length).to_i %>%"><%= period %></th>
48 48 <% end %>
49 49 </tr>
50 50 </thead>
51 51 <tbody>
52 52 <%= render :partial => 'report_criteria', :locals => {:criterias => @criterias, :hours => @hours, :level => 0} %>
53 53 <tr class="total">
54 54 <td><%= l(:label_total) %></td>
55 55 <%= '<td></td>' * (@criterias.size - 1) %>
56 56 <% @periods.each do |period| -%>
57 57 <% sum = sum_hours(select_hours(@hours, @columns, period.to_s)) %>
58 58 <td class="hours"><%= html_hours("%.2f" % sum) if sum > 0 %></td>
59 59 <% end -%>
60 60 </tr>
61 61 </tbody>
62 62 </table>
63 63 <% end %>
64 64 <% end %>
65 65 <% end %>
66
67 <% content_for :header_tags do %>
68 <%= javascript_include_tag 'calendar/calendar' %>
69 <%= javascript_include_tag "calendar/lang/calendar-#{current_language}.js" %>
70 <%= javascript_include_tag 'calendar/calendar-setup' %>
71 <%= stylesheet_link_tag 'calendar' %>
72 <% end %>
@@ -1,39 +1,32
1 1 <%= error_messages_for 'user' %>
2 2
3 3 <!--[form:user]-->
4 4 <div class="box">
5 5 <h3><%=l(:label_information_plural)%></h3>
6 6 <p><%= f.text_field :login, :required => true, :size => 25 %></p>
7 7 <p><%= f.text_field :firstname, :required => true %></p>
8 8 <p><%= f.text_field :lastname, :required => true %></p>
9 9 <p><%= f.text_field :mail, :required => true %></p>
10 10 <p><%= f.select :language, lang_options_for_select %></p>
11 11
12 12 <% for @custom_value in @custom_values %>
13 13 <p><%= custom_field_tag_with_label @custom_value %></p>
14 14 <% end if @custom_values%>
15 15
16 16 <p><%= f.check_box :admin %></p>
17 17 </div>
18 18
19 19 <div class="box">
20 20 <h3><%=l(:label_authentication)%></h3>
21 21 <% unless @auth_sources.empty? %>
22 22 <p><%= f.select :auth_source_id, ([[l(:label_internal), ""]] + @auth_sources.collect { |a| [a.name, a.id] }), {}, :onchange => "if (this.value=='') {Element.show('password_fields');} else {Element.hide('password_fields');}" %></p>
23 23 <% end %>
24 24 <div id="password_fields" style="<%= 'display:none;' if @user.auth_source %>">
25 25 <p><label for="password"><%=l(:field_password)%><span class="required"> *</span></label>
26 26 <%= password_field_tag 'password', nil, :size => 25 %><br />
27 27 <em><%= l(:text_caracters_minimum, 4) %></em></p>
28 28 <p><label for="password_confirmation"><%=l(:field_password_confirmation)%><span class="required"> *</span></label>
29 29 <%= password_field_tag 'password_confirmation', nil, :size => 25 %></p>
30 30 </div>
31 31 </div>
32 32 <!--[eoform:user]-->
33
34 <% content_for :header_tags do %>
35 <%= javascript_include_tag 'calendar/calendar' %>
36 <%= javascript_include_tag "calendar/lang/calendar-#{current_language}.js" %>
37 <%= javascript_include_tag 'calendar/calendar-setup' %>
38 <%= stylesheet_link_tag 'calendar' %>
39 <% end %> No newline at end of file
@@ -1,15 +1,8
1 1 <%= error_messages_for 'version' %>
2 2
3 3 <div class="box">
4 4 <p><%= f.text_field :name, :size => 60, :required => true %></p>
5 5 <p><%= f.text_field :description, :size => 60 %></p>
6 6 <p><%= f.text_field :wiki_page_title, :label => :label_wiki_page, :size => 60, :disabled => @project.wiki.nil? %></p>
7 7 <p><%= f.text_field :effective_date, :size => 10 %><%= calendar_for('version_effective_date') %></p>
8 8 </div>
9
10 <% content_for :header_tags do %>
11 <%= javascript_include_tag 'calendar/calendar' %>
12 <%= javascript_include_tag "calendar/lang/calendar-#{current_language}.js" %>
13 <%= javascript_include_tag 'calendar/calendar-setup' %>
14 <%= stylesheet_link_tag 'calendar' %>
15 <% end %>
General Comments 0
You need to be logged in to leave comments. Login now