##// END OF EJS Templates
Add breadcrumb nav for the forums (#892)....
Jean-Philippe Lang -
r1284:b9e380c9febe
parent child
Show More
@@ -1,487 +1,491
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 def breadcrumb(*args)
160 content_tag('p', args.join(' &#187; ') + ' &#187; ', :class => 'breadcrumb')
161 end
162
159 163 def html_title(*args)
160 164 if args.empty?
161 165 title = []
162 166 title << @project.name if @project
163 167 title += @html_title if @html_title
164 168 title << Setting.app_title
165 169 title.compact.join(' - ')
166 170 else
167 171 @html_title ||= []
168 172 @html_title += args
169 173 end
170 174 end
171 175
172 176 def accesskey(s)
173 177 Redmine::AccessKeys.key_for s
174 178 end
175 179
176 180 # Formats text according to system settings.
177 181 # 2 ways to call this method:
178 182 # * with a String: textilizable(text, options)
179 183 # * with an object and one of its attribute: textilizable(issue, :description, options)
180 184 def textilizable(*args)
181 185 options = args.last.is_a?(Hash) ? args.pop : {}
182 186 case args.size
183 187 when 1
184 188 obj = nil
185 189 text = args.shift
186 190 when 2
187 191 obj = args.shift
188 192 text = obj.send(args.shift).to_s
189 193 else
190 194 raise ArgumentError, 'invalid arguments to textilizable'
191 195 end
192 196 return '' if text.blank?
193 197
194 198 only_path = options.delete(:only_path) == false ? false : true
195 199
196 200 # when using an image link, try to use an attachment, if possible
197 201 attachments = options[:attachments] || (obj && obj.respond_to?(:attachments) ? obj.attachments : nil)
198 202
199 203 if attachments
200 204 text = text.gsub(/!((\<|\=|\>)?(\([^\)]+\))?(\[[^\]]+\])?(\{[^\}]+\})?)(\S+\.(gif|jpg|jpeg|png))!/) do |m|
201 205 style = $1
202 206 filename = $6
203 207 rf = Regexp.new(filename, Regexp::IGNORECASE)
204 208 # search for the picture in attachments
205 209 if found = attachments.detect { |att| att.filename =~ rf }
206 210 image_url = url_for :only_path => only_path, :controller => 'attachments', :action => 'download', :id => found.id
207 211 "!#{style}#{image_url}!"
208 212 else
209 213 "!#{style}#{filename}!"
210 214 end
211 215 end
212 216 end
213 217
214 218 text = (Setting.text_formatting == 'textile') ?
215 219 Redmine::WikiFormatting.to_html(text) { |macro, args| exec_macro(macro, obj, args) } :
216 220 simple_format(auto_link(h(text)))
217 221
218 222 # different methods for formatting wiki links
219 223 case options[:wiki_links]
220 224 when :local
221 225 # used for local links to html files
222 226 format_wiki_link = Proc.new {|project, title| "#{title}.html" }
223 227 when :anchor
224 228 # used for single-file wiki export
225 229 format_wiki_link = Proc.new {|project, title| "##{title}" }
226 230 else
227 231 format_wiki_link = Proc.new {|project, title| url_for(:only_path => only_path, :controller => 'wiki', :action => 'index', :id => project, :page => title) }
228 232 end
229 233
230 234 project = options[:project] || @project || (obj && obj.respond_to?(:project) ? obj.project : nil)
231 235
232 236 # Wiki links
233 237 #
234 238 # Examples:
235 239 # [[mypage]]
236 240 # [[mypage|mytext]]
237 241 # wiki links can refer other project wikis, using project name or identifier:
238 242 # [[project:]] -> wiki starting page
239 243 # [[project:|mytext]]
240 244 # [[project:mypage]]
241 245 # [[project:mypage|mytext]]
242 246 text = text.gsub(/(!)?(\[\[([^\]\n\|]+)(\|([^\]\n\|]+))?\]\])/) do |m|
243 247 link_project = project
244 248 esc, all, page, title = $1, $2, $3, $5
245 249 if esc.nil?
246 250 if page =~ /^([^\:]+)\:(.*)$/
247 251 link_project = Project.find_by_name($1) || Project.find_by_identifier($1)
248 252 page = $2
249 253 title ||= $1 if page.blank?
250 254 end
251 255
252 256 if link_project && link_project.wiki
253 257 # check if page exists
254 258 wiki_page = link_project.wiki.find_page(page)
255 259 link_to((title || page), format_wiki_link.call(link_project, Wiki.titleize(page)),
256 260 :class => ('wiki-page' + (wiki_page ? '' : ' new')))
257 261 else
258 262 # project or wiki doesn't exist
259 263 title || page
260 264 end
261 265 else
262 266 all
263 267 end
264 268 end
265 269
266 270 # Redmine links
267 271 #
268 272 # Examples:
269 273 # Issues:
270 274 # #52 -> Link to issue #52
271 275 # Changesets:
272 276 # r52 -> Link to revision 52
273 277 # commit:a85130f -> Link to scmid starting with a85130f
274 278 # Documents:
275 279 # document#17 -> Link to document with id 17
276 280 # document:Greetings -> Link to the document with title "Greetings"
277 281 # document:"Some document" -> Link to the document with title "Some document"
278 282 # Versions:
279 283 # version#3 -> Link to version with id 3
280 284 # version:1.0.0 -> Link to version named "1.0.0"
281 285 # version:"1.0 beta 2" -> Link to version named "1.0 beta 2"
282 286 # Attachments:
283 287 # attachment:file.zip -> Link to the attachment of the current object named file.zip
284 288 # Source files:
285 289 # source:some/file -> Link to the file located at /some/file in the project's repository
286 290 # source:some/file@52 -> Link to the file's revision 52
287 291 # source:some/file#L120 -> Link to line 120 of the file
288 292 # source:some/file@52#L120 -> Link to line 120 of the file's revision 52
289 293 # export:some/file -> Force the download of the file
290 294 text = text.gsub(%r{([\s\(,-^])(!)?(attachment|document|version|commit|source|export)?((#|r)(\d+)|(:)([^"\s<>][^\s<>]*|"[^"]+"))(?=[[:punct:]]|\s|<|$)}) do |m|
291 295 leading, esc, prefix, sep, oid = $1, $2, $3, $5 || $7, $6 || $8
292 296 link = nil
293 297 if esc.nil?
294 298 if prefix.nil? && sep == 'r'
295 299 if project && (changeset = project.changesets.find_by_revision(oid))
296 300 link = link_to("r#{oid}", {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :rev => oid},
297 301 :class => 'changeset',
298 302 :title => truncate(changeset.comments, 100))
299 303 end
300 304 elsif sep == '#'
301 305 oid = oid.to_i
302 306 case prefix
303 307 when nil
304 308 if issue = Issue.find_by_id(oid, :include => [:project, :status], :conditions => Project.visible_by(User.current))
305 309 link = link_to("##{oid}", {:only_path => only_path, :controller => 'issues', :action => 'show', :id => oid},
306 310 :class => (issue.closed? ? 'issue closed' : 'issue'),
307 311 :title => "#{truncate(issue.subject, 100)} (#{issue.status.name})")
308 312 link = content_tag('del', link) if issue.closed?
309 313 end
310 314 when 'document'
311 315 if document = Document.find_by_id(oid, :include => [:project], :conditions => Project.visible_by(User.current))
312 316 link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document},
313 317 :class => 'document'
314 318 end
315 319 when 'version'
316 320 if version = Version.find_by_id(oid, :include => [:project], :conditions => Project.visible_by(User.current))
317 321 link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
318 322 :class => 'version'
319 323 end
320 324 end
321 325 elsif sep == ':'
322 326 # removes the double quotes if any
323 327 name = oid.gsub(%r{^"(.*)"$}, "\\1")
324 328 case prefix
325 329 when 'document'
326 330 if project && document = project.documents.find_by_title(name)
327 331 link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document},
328 332 :class => 'document'
329 333 end
330 334 when 'version'
331 335 if project && version = project.versions.find_by_name(name)
332 336 link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
333 337 :class => 'version'
334 338 end
335 339 when 'commit'
336 340 if project && (changeset = project.changesets.find(:first, :conditions => ["scmid LIKE ?", "#{name}%"]))
337 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)
338 342 end
339 343 when 'source', 'export'
340 344 if project && project.repository
341 345 name =~ %r{^[/\\]*(.*?)(@([0-9a-f]+))?(#(L\d+))?$}
342 346 path, rev, anchor = $1, $3, $5
343 347 link = link_to h("#{prefix}:#{name}"), {:controller => 'repositories', :action => 'entry', :id => project, :path => path,
344 348 :rev => rev,
345 349 :anchor => anchor,
346 350 :format => (prefix == 'export' ? 'raw' : nil)},
347 351 :class => (prefix == 'export' ? 'source download' : 'source')
348 352 end
349 353 when 'attachment'
350 354 if attachments && attachment = attachments.detect {|a| a.filename == name }
351 355 link = link_to h(attachment.filename), {:only_path => only_path, :controller => 'attachments', :action => 'download', :id => attachment},
352 356 :class => 'attachment'
353 357 end
354 358 end
355 359 end
356 360 end
357 361 leading + (link || "#{prefix}#{sep}#{oid}")
358 362 end
359 363
360 364 text
361 365 end
362 366
363 367 # Same as Rails' simple_format helper without using paragraphs
364 368 def simple_format_without_paragraph(text)
365 369 text.to_s.
366 370 gsub(/\r\n?/, "\n"). # \r\n and \r -> \n
367 371 gsub(/\n\n+/, "<br /><br />"). # 2+ newline -> 2 br
368 372 gsub(/([^\n]\n)(?=[^\n])/, '\1<br />') # 1 newline -> br
369 373 end
370 374
371 375 def error_messages_for(object_name, options = {})
372 376 options = options.symbolize_keys
373 377 object = instance_variable_get("@#{object_name}")
374 378 if object && !object.errors.empty?
375 379 # build full_messages here with controller current language
376 380 full_messages = []
377 381 object.errors.each do |attr, msg|
378 382 next if msg.nil?
379 383 msg = msg.first if msg.is_a? Array
380 384 if attr == "base"
381 385 full_messages << l(msg)
382 386 else
383 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"
384 388 end
385 389 end
386 390 # retrieve custom values error messages
387 391 if object.errors[:custom_values]
388 392 object.custom_values.each do |v|
389 393 v.errors.each do |attr, msg|
390 394 next if msg.nil?
391 395 msg = msg.first if msg.is_a? Array
392 396 full_messages << "&#171; " + v.custom_field.name + " &#187; " + l(msg)
393 397 end
394 398 end
395 399 end
396 400 content_tag("div",
397 401 content_tag(
398 402 options[:header_tag] || "span", lwr(:gui_validation_error, full_messages.length) + ":"
399 403 ) +
400 404 content_tag("ul", full_messages.collect { |msg| content_tag("li", msg) }),
401 405 "id" => options[:id] || "errorExplanation", "class" => options[:class] || "errorExplanation"
402 406 )
403 407 else
404 408 ""
405 409 end
406 410 end
407 411
408 412 def lang_options_for_select(blank=true)
409 413 (blank ? [["(auto)", ""]] : []) +
410 414 GLoc.valid_languages.collect{|lang| [ ll(lang.to_s, :general_lang_name), lang.to_s]}.sort{|x,y| x.last <=> y.last }
411 415 end
412 416
413 417 def label_tag_for(name, option_tags = nil, options = {})
414 418 label_text = l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) + (options.delete(:required) ? @template.content_tag("span", " *", :class => "required"): "")
415 419 content_tag("label", label_text)
416 420 end
417 421
418 422 def labelled_tabular_form_for(name, object, options, &proc)
419 423 options[:html] ||= {}
420 424 options[:html][:class] = 'tabular' unless options[:html].has_key?(:class)
421 425 form_for(name, object, options.merge({ :builder => TabularFormBuilder, :lang => current_language}), &proc)
422 426 end
423 427
424 428 def check_all_links(form_name)
425 429 link_to_function(l(:button_check_all), "checkAll('#{form_name}', true)") +
426 430 " | " +
427 431 link_to_function(l(:button_uncheck_all), "checkAll('#{form_name}', false)")
428 432 end
429 433
430 434 def progress_bar(pcts, options={})
431 435 pcts = [pcts, pcts] unless pcts.is_a?(Array)
432 436 pcts[1] = pcts[1] - pcts[0]
433 437 pcts << (100 - pcts[1] - pcts[0])
434 438 width = options[:width] || '100px;'
435 439 legend = options[:legend] || ''
436 440 content_tag('table',
437 441 content_tag('tr',
438 442 (pcts[0] > 0 ? content_tag('td', '', :width => "#{pcts[0].floor}%;", :class => 'closed') : '') +
439 443 (pcts[1] > 0 ? content_tag('td', '', :width => "#{pcts[1].floor}%;", :class => 'done') : '') +
440 444 (pcts[2] > 0 ? content_tag('td', '', :width => "#{pcts[2].floor}%;", :class => 'todo') : '')
441 445 ), :class => 'progress', :style => "width: #{width};") +
442 446 content_tag('p', legend, :class => 'pourcent')
443 447 end
444 448
445 449 def context_menu_link(name, url, options={})
446 450 options[:class] ||= ''
447 451 if options.delete(:selected)
448 452 options[:class] << ' icon-checked disabled'
449 453 options[:disabled] = true
450 454 end
451 455 if options.delete(:disabled)
452 456 options.delete(:method)
453 457 options.delete(:confirm)
454 458 options.delete(:onclick)
455 459 options[:class] << ' disabled'
456 460 url = '#'
457 461 end
458 462 link_to name, url, options
459 463 end
460 464
461 465 def calendar_for(field_id)
462 466 image_tag("calendar.png", {:id => "#{field_id}_trigger",:class => "calendar-trigger"}) +
463 467 javascript_tag("Calendar.setup({inputField : '#{field_id}', ifFormat : '%Y-%m-%d', button : '#{field_id}_trigger' });")
464 468 end
465 469
466 470 def wikitoolbar_for(field_id)
467 471 return '' unless Setting.text_formatting == 'textile'
468 472
469 473 help_link = l(:setting_text_formatting) + ': ' +
470 474 link_to(l(:label_help), compute_public_path('wiki_syntax', 'help', 'html'),
471 475 :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;")
472 476
473 477 javascript_include_tag('jstoolbar/jstoolbar') +
474 478 javascript_include_tag("jstoolbar/lang/jstoolbar-#{current_language}") +
475 479 javascript_tag("var toolbar = new jsToolBar($('#{field_id}')); toolbar.setHelpLink('#{help_link}'); toolbar.draw();")
476 480 end
477 481
478 482 def content_for(name, content = nil, &block)
479 483 @has_content ||= {}
480 484 @has_content[name] = true
481 485 super(name, content, &block)
482 486 end
483 487
484 488 def has_content?(name)
485 489 (@has_content && @has_content[name]) || false
486 490 end
487 491 end
@@ -1,57 +1,59
1 <%= breadcrumb link_to(l(:label_board_plural), {:controller => 'boards', :action => 'index', :project_id => @project}) %>
2
1 3 <div class="contextual">
2 4 <%= link_to_if_authorized l(:label_message_new),
3 5 {:controller => 'messages', :action => 'new', :board_id => @board},
4 6 :class => 'icon icon-add',
5 7 :onclick => 'Element.show("add-message"); return false;' %>
6 8 <%= watcher_tag(@board, User.current) %>
7 9 </div>
8 10
9 11 <div id="add-message" style="display:none;">
10 12 <h2><%= link_to h(@board.name), :controller => 'boards', :action => 'show', :project_id => @project, :id => @board %> &#187; <%= l(:label_message_new) %></h2>
11 13 <% form_for :message, @message, :url => {:controller => 'messages', :action => 'new', :board_id => @board}, :html => {:multipart => true, :id => 'message-form'} do |f| %>
12 14 <%= render :partial => 'messages/form', :locals => {:f => f} %>
13 15 <p><%= submit_tag l(:button_create) %>
14 16 <%= link_to_remote l(:label_preview),
15 17 { :url => { :controller => 'messages', :action => 'preview', :board_id => @board },
16 18 :method => 'post',
17 19 :update => 'preview',
18 20 :with => "Form.serialize('message-form')",
19 21 :complete => "Element.scrollTo('preview')"
20 22 }, :accesskey => accesskey(:preview) %> |
21 23 <%= link_to l(:button_cancel), "#", :onclick => 'Element.hide("add-message")' %></p>
22 24 <% end %>
23 25 <div id="preview" class="wiki"></div>
24 26 </div>
25 27
26 28 <h2><%=h @board.name %></h2>
27 29
28 30 <% if @topics.any? %>
29 31 <table class="list messages">
30 32 <thead><tr>
31 33 <th><%= l(:field_subject) %></th>
32 34 <th><%= l(:field_author) %></th>
33 35 <%= sort_header_tag("#{Message.table_name}.created_on", :caption => l(:field_created_on)) %>
34 36 <th><%= l(:label_reply_plural) %></th>
35 37 <%= sort_header_tag("#{Message.table_name}.updated_on", :caption => l(:label_message_last)) %>
36 38 </tr></thead>
37 39 <tbody>
38 40 <% @topics.each do |topic| %>
39 41 <tr class="message <%= cycle 'odd', 'even' %> <%= topic.sticky? ? 'sticky' : '' %> <%= topic.locked? ? 'locked' : '' %>">
40 42 <td class="subject"><%= link_to h(topic.subject), { :controller => 'messages', :action => 'show', :board_id => @board, :id => topic }, :class => 'icon' %></td>
41 43 <td class="author" align="center"><%= topic.author %></td>
42 44 <td class="created_on" align="center"><%= format_time(topic.created_on) %></td>
43 45 <td class="replies" align="center"><%= topic.replies_count %></td>
44 46 <td class="last_message">
45 47 <% if topic.last_reply %>
46 48 <%= authoring topic.last_reply.created_on, topic.last_reply.author %><br />
47 49 <%= link_to_message topic.last_reply %>
48 50 <% end %>
49 51 </td>
50 52 </tr>
51 53 <% end %>
52 54 </tbody>
53 55 </table>
54 56 <p class="pagination"><%= pagination_links_full @topic_pages, @topic_count %></p>
55 57 <% else %>
56 58 <p class="nodata"><%= l(:label_no_data) %></p>
57 59 <% end %>
@@ -1,47 +1,50
1 <%= breadcrumb link_to(l(:label_board_plural), {:controller => 'boards', :action => 'index', :project_id => @project}),
2 link_to(h(@board.name), {:controller => 'boards', :action => 'show', :project_id => @project, :id => @board}) %>
3
1 4 <div class="contextual">
2 5 <%= link_to_if_authorized l(:button_edit), {:action => 'edit', :id => @topic}, :class => 'icon icon-edit' %>
3 6 <%= link_to_if_authorized l(:button_delete), {:action => 'destroy', :id => @topic}, :method => :post, :confirm => l(:text_are_you_sure), :class => 'icon icon-del' %>
4 7 </div>
5 8
6 <h2><%= link_to h(@board.name), :controller => 'boards', :action => 'show', :project_id => @project, :id => @board %> &#187; <%=h @topic.subject %></h2>
9 <h2><%=h @topic.subject %></h2>
7 10
8 11 <div class="message">
9 12 <p><span class="author"><%= authoring @topic.created_on, @topic.author %></span></p>
10 13 <div class="wiki">
11 14 <%= textilizable(@topic.content, :attachments => @topic.attachments) %>
12 15 </div>
13 16 <%= link_to_attachments @topic.attachments, :no_author => true %>
14 17 </div>
15 18 <br />
16 19
17 20 <h3 class="icon22 icon22-comment"><%= l(:label_reply_plural) %></h3>
18 21 <% @replies.each do |message| %>
19 22 <a name="<%= "message-#{message.id}" %>"></a>
20 23 <div class="contextual">
21 24 <%= link_to_if_authorized image_tag('edit.png'), {:action => 'edit', :id => message}, :title => l(:button_edit) %>
22 25 <%= link_to_if_authorized image_tag('delete.png'), {:action => 'destroy', :id => message}, :method => :post, :confirm => l(:text_are_you_sure), :title => l(:button_delete) %>
23 26 </div>
24 27 <div class="message reply">
25 28 <h4><%=h message.subject %> - <%= authoring message.created_on, message.author %></h4>
26 29 <div class="wiki"><%= textilizable message.content %></div>
27 30 <%= link_to_attachments message.attachments, :no_author => true %>
28 31 </div>
29 32 <% end %>
30 33
31 34 <% if !@topic.locked? && authorize_for('messages', 'reply') %>
32 35 <p><%= toggle_link l(:button_reply), "reply", :focus => 'message_content' %></p>
33 36 <div id="reply" style="display:none;">
34 37 <% form_for :reply, @reply, :url => {:action => 'reply', :id => @topic}, :html => {:multipart => true, :id => 'message-form'} do |f| %>
35 38 <%= render :partial => 'form', :locals => {:f => f, :replying => true} %>
36 39 <%= submit_tag l(:button_submit) %>
37 40 <%= link_to_remote l(:label_preview),
38 41 { :url => { :controller => 'messages', :action => 'preview', :board_id => @board },
39 42 :method => 'post',
40 43 :update => 'preview',
41 44 :with => "Form.serialize('message-form')",
42 45 :complete => "Element.scrollTo('preview')"
43 46 }, :accesskey => accesskey(:preview) %>
44 47 <% end %>
45 48 <div id="preview" class="wiki"></div>
46 49 </div>
47 50 <% end %>
@@ -1,579 +1,580
1 1 body { font-family: Verdana, sans-serif; font-size: 12px; color:#484848; margin: 0; padding: 0; min-width: 900px; }
2 2
3 3 h1, h2, h3, h4 { font-family: "Trebuchet MS", Verdana, sans-serif;}
4 4 h1 {margin:0; padding:0; font-size: 24px;}
5 5 h2, .wiki h1 {font-size: 20px;padding: 2px 10px 1px 0px;margin: 0 0 10px 0; border-bottom: 1px solid #bbbbbb; color: #444;}
6 6 h3, .wiki h2 {font-size: 16px;padding: 2px 10px 1px 0px;margin: 0 0 10px 0; border-bottom: 1px solid #bbbbbb; color: #444;}
7 7 h4, .wiki h3 {font-size: 13px;padding: 2px 10px 1px 0px;margin-bottom: 5px; border-bottom: 1px dotted #bbbbbb; color: #444;}
8 8
9 9 /***** Layout *****/
10 10 #wrapper {background: white;}
11 11
12 12 #top-menu {background: #2C4056; color: #fff; height:1.8em; font-size: 0.8em; padding: 2px 2px 0px 6px;}
13 13 #top-menu ul {margin: 0; padding: 0;}
14 14 #top-menu li {
15 15 float:left;
16 16 list-style-type:none;
17 17 margin: 0px 0px 0px 0px;
18 18 padding: 0px 0px 0px 0px;
19 19 white-space:nowrap;
20 20 }
21 21 #top-menu a {color: #fff; padding-right: 8px; font-weight: bold;}
22 22 #top-menu #loggedas { float: right; margin-right: 0.5em; color: #fff; }
23 23
24 24 #account {float:right;}
25 25
26 26 #header {height:5.3em;margin:0;background-color:#507AAA;color:#f8f8f8; padding: 4px 8px 0px 6px; position:relative;}
27 27 #header a {color:#f8f8f8;}
28 28 #quick-search {float:right;}
29 29
30 30 #main-menu {position: absolute; bottom: 0px; left:6px; margin-right: -500px;}
31 31 #main-menu ul {margin: 0; padding: 0;}
32 32 #main-menu li {
33 33 float:left;
34 34 list-style-type:none;
35 35 margin: 0px 2px 0px 0px;
36 36 padding: 0px 0px 0px 0px;
37 37 white-space:nowrap;
38 38 }
39 39 #main-menu li a {
40 40 display: block;
41 41 color: #fff;
42 42 text-decoration: none;
43 43 font-weight: bold;
44 44 margin: 0;
45 45 padding: 4px 10px 4px 10px;
46 46 }
47 47 #main-menu li a:hover {background:#759FCF; color:#fff;}
48 48 #main-menu li a.selected, #main-menu li a.selected:hover {background:#fff; color:#555;}
49 49
50 50 #main {background-color:#EEEEEE;}
51 51
52 52 #sidebar{ float: right; width: 17%; position: relative; z-index: 9; min-height: 600px; padding: 0; margin: 0;}
53 53 * html #sidebar{ width: 17%; }
54 54 #sidebar h3{ font-size: 14px; margin-top:14px; color: #666; }
55 55 #sidebar hr{ width: 100%; margin: 0 auto; height: 1px; background: #ccc; border: 0; }
56 56 * html #sidebar hr{ width: 95%; position: relative; left: -6px; color: #ccc; }
57 57
58 58 #content { width: 80%; background-color: #fff; margin: 0px; border-right: 1px solid #ddd; padding: 6px 10px 10px 10px; z-index: 10; height:600px; min-height: 600px;}
59 59 * html #content{ width: 80%; padding-left: 0; margin-top: 0px; padding: 6px 10px 10px 10px;}
60 60 html>body #content {
61 61 height: auto;
62 62 min-height: 600px;
63 63 }
64 64
65 65 #main.nosidebar #sidebar{ display: none; }
66 66 #main.nosidebar #content{ width: auto; border-right: 0; }
67 67
68 68 #footer {clear: both; border-top: 1px solid #bbb; font-size: 0.9em; color: #aaa; padding: 5px; text-align:center; background:#fff;}
69 69
70 70 #login-form table {margin-top:5em; padding:1em; margin-left: auto; margin-right: auto; border: 2px solid #FDBF3B; background-color:#FFEBC1; }
71 71 #login-form table td {padding: 6px;}
72 72 #login-form label {font-weight: bold;}
73 73
74 74 .clear:after{ content: "."; display: block; height: 0; clear: both; visibility: hidden; }
75 75
76 76 /***** Links *****/
77 77 a, a:link, a:visited{ color: #2A5685; text-decoration: none; }
78 78 a:hover, a:active{ color: #c61a1a; text-decoration: underline;}
79 79 a img{ border: 0; }
80 80
81 81 a.issue.closed, .issue.closed a { text-decoration: line-through; }
82 82
83 83 /***** Tables *****/
84 84 table.list { border: 1px solid #e4e4e4; border-collapse: collapse; width: 100%; margin-bottom: 4px; }
85 85 table.list th { background-color:#EEEEEE; padding: 4px; white-space:nowrap; }
86 86 table.list td { overflow: hidden; vertical-align: top;}
87 87 table.list td.id { width: 2%; text-align: center;}
88 88 table.list td.checkbox { width: 15px; padding: 0px;}
89 89
90 90 table.list.issues { margin-top: 10px; }
91 91 tr.issue { text-align: center; white-space: nowrap; }
92 92 tr.issue td.subject, tr.issue td.category { white-space: normal; }
93 93 tr.issue td.subject { text-align: left; }
94 94 tr.issue td.done_ratio table.progress { margin-left:auto; margin-right: auto;}
95 95
96 96 tr.entry { border: 1px solid #f8f8f8; }
97 97 tr.entry td { white-space: nowrap; }
98 98 tr.entry td.filename { width: 30%; }
99 99 tr.entry td.size { text-align: right; font-size: 90%; }
100 100 tr.entry td.revision, tr.entry td.author { text-align: center; }
101 101 tr.entry td.age { text-align: right; }
102 102
103 103 tr.changeset td.author { text-align: center; width: 15%; }
104 104 tr.changeset td.committed_on { text-align: center; width: 15%; }
105 105
106 106 tr.message { height: 2.6em; }
107 107 tr.message td.last_message { font-size: 80%; }
108 108 tr.message.locked td.subject a { background-image: url(../images/locked.png); }
109 109 tr.message.sticky td.subject a { background-image: url(../images/sticky.png); font-weight: bold; }
110 110
111 111 tr.user td { width:13%; }
112 112 tr.user td.email { width:18%; }
113 113 tr.user td { white-space: nowrap; }
114 114 tr.user.locked, tr.user.registered { color: #aaa; }
115 115 tr.user.locked a, tr.user.registered a { color: #aaa; }
116 116
117 117 tr.time-entry { text-align: center; white-space: nowrap; }
118 118 tr.time-entry td.subject, tr.time-entry td.comments { text-align: left; white-space: normal; }
119 119 td.hours { text-align: right; font-weight: bold; padding-right: 0.5em; }
120 120 td.hours .hours-dec { font-size: 0.9em; }
121 121
122 122 table.list tbody tr:hover { background-color:#ffffdd; }
123 123 table td {padding:2px;}
124 124 table p {margin:0;}
125 125 .odd {background-color:#f6f7f8;}
126 126 .even {background-color: #fff;}
127 127
128 128 .highlight { background-color: #FCFD8D;}
129 129 .highlight.token-1 { background-color: #faa;}
130 130 .highlight.token-2 { background-color: #afa;}
131 131 .highlight.token-3 { background-color: #aaf;}
132 132
133 133 .box{
134 134 padding:6px;
135 135 margin-bottom: 10px;
136 136 background-color:#f6f6f6;
137 137 color:#505050;
138 138 line-height:1.5em;
139 139 border: 1px solid #e4e4e4;
140 140 }
141 141
142 142 div.square {
143 143 border: 1px solid #999;
144 144 float: left;
145 145 margin: .3em .4em 0 .4em;
146 146 overflow: hidden;
147 147 width: .6em; height: .6em;
148 148 }
149 149 .contextual {float:right; white-space: nowrap; line-height:1.4em;margin-top:5px; padding-left: 10px; font-size:0.9em;}
150 150 .contextual input {font-size:0.9em;}
151 151
152 152 .splitcontentleft{float:left; width:49%;}
153 153 .splitcontentright{float:right; width:49%;}
154 154 form {display: inline;}
155 155 input, select {vertical-align: middle; margin-top: 1px; margin-bottom: 1px;}
156 156 fieldset {border: 1px solid #e4e4e4; margin:0;}
157 157 legend {color: #484848;}
158 158 hr { width: 100%; height: 1px; background: #ccc; border: 0;}
159 159 textarea.wiki-edit { width: 99%; }
160 160 li p {margin-top: 0;}
161 161 div.issue {background:#ffffdd; padding:6px; margin-bottom:6px;border: 1px solid #d7d7d7;}
162 p.breadcrumb { font-size: 0.9em; margin: 4px 0 4px 0;}
162 163
163 164 fieldset#filters .buttons { text-align: right; font-size: 0.9em; margin: 0 4px 0px 0; }
164 165
165 166 div#issue-changesets {float:right; width:45%; margin-left: 1em; margin-bottom: 1em; background: #fff; padding-left: 1em; font-size: 90%;}
166 167 div#issue-changesets .changeset { padding: 4px;}
167 168 div#issue-changesets .changeset { border-bottom: 1px solid #ddd; }
168 169 div#issue-changesets p { margin-top: 0; margin-bottom: 1em;}
169 170
170 171 div#activity dl { margin-left: 2em; }
171 172 div#activity dd { margin-bottom: 1em; }
172 173 div#activity dt { margin-bottom: 1px; }
173 174 div#activity dt .time { color: #777; font-size: 80%; }
174 175 div#activity dd .description { font-style: italic; }
175 176 div#activity span.project:after { content: " -"; }
176 177
177 178 div#roadmap fieldset.related-issues { margin-bottom: 1em; }
178 179 div#roadmap fieldset.related-issues ul { margin-top: 0.3em; margin-bottom: 0.3em; }
179 180 div#roadmap .wiki h1:first-child { display: none; }
180 181 div#roadmap .wiki h1 { font-size: 120%; }
181 182 div#roadmap .wiki h2 { font-size: 110%; }
182 183
183 184 div#version-summary { float:right; width:380px; margin-left: 16px; margin-bottom: 16px; background-color: #fff; }
184 185 div#version-summary fieldset { margin-bottom: 1em; }
185 186 div#version-summary .total-hours { text-align: right; }
186 187
187 188 table#time-report td.hours { text-align: right; padding-right: 0.5em; }
188 189 table#time-report tbody tr { font-style: italic; color: #777; }
189 190 table#time-report tbody tr.last-level { font-style: normal; color: #555; }
190 191 table#time-report tbody tr.total { font-style: normal; font-weight: bold; color: #555; background-color:#EEEEEE; }
191 192 table#time-report .hours-dec { font-size: 0.9em; }
192 193
193 194 .total-hours { font-size: 110%; font-weight: bold; }
194 195 .total-hours span.hours-int { font-size: 120%; }
195 196
196 197 .autoscroll {overflow-x: auto; padding:1px; width:100%; margin-bottom: 1.2em;}
197 198 #user_firstname, #user_lastname, #user_mail, #my_account_form select { width: 90%; }
198 199
199 200 .pagination {font-size: 90%}
200 201 p.pagination {margin-top:8px;}
201 202
202 203 /***** Tabular forms ******/
203 204 .tabular p{
204 205 margin: 0;
205 206 padding: 5px 0 8px 0;
206 207 padding-left: 180px; /*width of left column containing the label elements*/
207 208 height: 1%;
208 209 clear:left;
209 210 }
210 211
211 212 .tabular label{
212 213 font-weight: bold;
213 214 float: left;
214 215 text-align: right;
215 216 margin-left: -180px; /*width of left column*/
216 217 width: 175px; /*width of labels. Should be smaller than left column to create some right
217 218 margin*/
218 219 }
219 220
220 221 .tabular label.floating{
221 222 font-weight: normal;
222 223 margin-left: 0px;
223 224 text-align: left;
224 225 width: 200px;
225 226 }
226 227
227 228 #preview fieldset {margin-top: 1em; background: url(../images/draft.png)}
228 229
229 230 .tabular.settings p{ padding-left: 300px; }
230 231 .tabular.settings label{ margin-left: -300px; width: 295px; }
231 232
232 233 .required {color: #bb0000;}
233 234 .summary {font-style: italic;}
234 235
235 236 #attachments_fields input[type=text] {margin-left: 8px; }
236 237
237 238 div.attachments p { margin:4px 0 2px 0; }
238 239 div.attachments img { vertical-align: middle; }
239 240 div.attachments span.author { font-size: 0.9em; color: #888; }
240 241
241 242 p.other-formats { text-align: right; font-size:0.9em; color: #666; }
242 243 .other-formats span + span:before { content: "| "; }
243 244
244 245 a.feed { background: url(../images/feed.png) no-repeat 1px 50%; padding: 2px 0px 3px 16px; }
245 246
246 247 /***** Flash & error messages ****/
247 248 #errorExplanation, div.flash, .nodata {
248 249 padding: 4px 4px 4px 30px;
249 250 margin-bottom: 12px;
250 251 font-size: 1.1em;
251 252 border: 2px solid;
252 253 }
253 254
254 255 div.flash {margin-top: 8px;}
255 256
256 257 div.flash.error, #errorExplanation {
257 258 background: url(../images/false.png) 8px 5px no-repeat;
258 259 background-color: #ffe3e3;
259 260 border-color: #dd0000;
260 261 color: #550000;
261 262 }
262 263
263 264 div.flash.notice {
264 265 background: url(../images/true.png) 8px 5px no-repeat;
265 266 background-color: #dfffdf;
266 267 border-color: #9fcf9f;
267 268 color: #005f00;
268 269 }
269 270
270 271 .nodata {
271 272 text-align: center;
272 273 background-color: #FFEBC1;
273 274 border-color: #FDBF3B;
274 275 color: #A6750C;
275 276 }
276 277
277 278 #errorExplanation ul { font-size: 0.9em;}
278 279
279 280 /***** Ajax indicator ******/
280 281 #ajax-indicator {
281 282 position: absolute; /* fixed not supported by IE */
282 283 background-color:#eee;
283 284 border: 1px solid #bbb;
284 285 top:35%;
285 286 left:40%;
286 287 width:20%;
287 288 font-weight:bold;
288 289 text-align:center;
289 290 padding:0.6em;
290 291 z-index:100;
291 292 filter:alpha(opacity=50);
292 293 opacity: 0.5;
293 294 }
294 295
295 296 html>body #ajax-indicator { position: fixed; }
296 297
297 298 #ajax-indicator span {
298 299 background-position: 0% 40%;
299 300 background-repeat: no-repeat;
300 301 background-image: url(../images/loading.gif);
301 302 padding-left: 26px;
302 303 vertical-align: bottom;
303 304 }
304 305
305 306 /***** Calendar *****/
306 307 table.cal {border-collapse: collapse; width: 100%; margin: 8px 0 6px 0;border: 1px solid #d7d7d7;}
307 308 table.cal thead th {width: 14%;}
308 309 table.cal tbody tr {height: 100px;}
309 310 table.cal th { background-color:#EEEEEE; padding: 4px; }
310 311 table.cal td {border: 1px solid #d7d7d7; vertical-align: top; font-size: 0.9em;}
311 312 table.cal td p.day-num {font-size: 1.1em; text-align:right;}
312 313 table.cal td.odd p.day-num {color: #bbb;}
313 314 table.cal td.today {background:#ffffdd;}
314 315 table.cal td.today p.day-num {font-weight: bold;}
315 316
316 317 /***** Tooltips ******/
317 318 .tooltip{position:relative;z-index:24;}
318 319 .tooltip:hover{z-index:25;color:#000;}
319 320 .tooltip span.tip{display: none; text-align:left;}
320 321
321 322 div.tooltip:hover span.tip{
322 323 display:block;
323 324 position:absolute;
324 325 top:12px; left:24px; width:270px;
325 326 border:1px solid #555;
326 327 background-color:#fff;
327 328 padding: 4px;
328 329 font-size: 0.8em;
329 330 color:#505050;
330 331 }
331 332
332 333 /***** Progress bar *****/
333 334 table.progress {
334 335 border: 1px solid #D7D7D7;
335 336 border-collapse: collapse;
336 337 border-spacing: 0pt;
337 338 empty-cells: show;
338 339 text-align: center;
339 340 float:left;
340 341 margin: 1px 6px 1px 0px;
341 342 }
342 343
343 344 table.progress td { height: 0.9em; }
344 345 table.progress td.closed { background: #BAE0BA none repeat scroll 0%; }
345 346 table.progress td.done { background: #DEF0DE none repeat scroll 0%; }
346 347 table.progress td.open { background: #FFF none repeat scroll 0%; }
347 348 p.pourcent {font-size: 80%;}
348 349 p.progress-info {clear: left; font-style: italic; font-size: 80%;}
349 350
350 351 /***** Tabs *****/
351 352 #content .tabs {height: 2.6em; border-bottom: 1px solid #bbbbbb; margin-bottom:1.2em; position:relative;}
352 353 #content .tabs ul {margin:0; position:absolute; bottom:-2px; padding-left:1em;}
353 354 #content .tabs>ul { bottom:-1px; } /* others */
354 355 #content .tabs ul li {
355 356 float:left;
356 357 list-style-type:none;
357 358 white-space:nowrap;
358 359 margin-right:8px;
359 360 background:#fff;
360 361 }
361 362 #content .tabs ul li a{
362 363 display:block;
363 364 font-size: 0.9em;
364 365 text-decoration:none;
365 366 line-height:1.3em;
366 367 padding:4px 6px 4px 6px;
367 368 border: 1px solid #ccc;
368 369 border-bottom: 1px solid #bbbbbb;
369 370 background-color: #eeeeee;
370 371 color:#777;
371 372 font-weight:bold;
372 373 }
373 374
374 375 #content .tabs ul li a:hover {
375 376 background-color: #ffffdd;
376 377 text-decoration:none;
377 378 }
378 379
379 380 #content .tabs ul li a.selected {
380 381 background-color: #fff;
381 382 border: 1px solid #bbbbbb;
382 383 border-bottom: 1px solid #fff;
383 384 }
384 385
385 386 #content .tabs ul li a.selected:hover {
386 387 background-color: #fff;
387 388 }
388 389
389 390 /***** Diff *****/
390 391 .diff_out { background: #fcc; }
391 392 .diff_in { background: #cfc; }
392 393
393 394 /***** Wiki *****/
394 395 div.wiki table {
395 396 border: 1px solid #505050;
396 397 border-collapse: collapse;
397 398 margin-bottom: 1em;
398 399 }
399 400
400 401 div.wiki table, div.wiki td, div.wiki th {
401 402 border: 1px solid #bbb;
402 403 padding: 4px;
403 404 }
404 405
405 406 div.wiki .external {
406 407 background-position: 0% 60%;
407 408 background-repeat: no-repeat;
408 409 padding-left: 12px;
409 410 background-image: url(../images/external.png);
410 411 }
411 412
412 413 div.wiki a.new {
413 414 color: #b73535;
414 415 }
415 416
416 417 div.wiki pre {
417 418 margin: 1em 1em 1em 1.6em;
418 419 padding: 2px;
419 420 background-color: #fafafa;
420 421 border: 1px solid #dadada;
421 422 width:95%;
422 423 overflow-x: auto;
423 424 }
424 425
425 426 div.wiki div.toc {
426 427 background-color: #ffffdd;
427 428 border: 1px solid #e4e4e4;
428 429 padding: 4px;
429 430 line-height: 1.2em;
430 431 margin-bottom: 12px;
431 432 margin-right: 12px;
432 433 display: table
433 434 }
434 435 * html div.wiki div.toc { width: 50%; } /* IE6 doesn't autosize div */
435 436
436 437 div.wiki div.toc.right { float: right; margin-left: 12px; margin-right: 0; width: auto; }
437 438 div.wiki div.toc.left { float: left; margin-right: 12px; margin-left: 0; width: auto; }
438 439
439 440 div.wiki div.toc a {
440 441 display: block;
441 442 font-size: 0.9em;
442 443 font-weight: normal;
443 444 text-decoration: none;
444 445 color: #606060;
445 446 }
446 447 div.wiki div.toc a:hover { color: #c61a1a; text-decoration: underline;}
447 448
448 449 div.wiki div.toc a.heading2 { margin-left: 6px; }
449 450 div.wiki div.toc a.heading3 { margin-left: 12px; font-size: 0.8em; }
450 451
451 452 /***** My page layout *****/
452 453 .block-receiver {
453 454 border:1px dashed #c0c0c0;
454 455 margin-bottom: 20px;
455 456 padding: 15px 0 15px 0;
456 457 }
457 458
458 459 .mypage-box {
459 460 margin:0 0 20px 0;
460 461 color:#505050;
461 462 line-height:1.5em;
462 463 }
463 464
464 465 .handle {
465 466 cursor: move;
466 467 }
467 468
468 469 a.close-icon {
469 470 display:block;
470 471 margin-top:3px;
471 472 overflow:hidden;
472 473 width:12px;
473 474 height:12px;
474 475 background-repeat: no-repeat;
475 476 cursor:pointer;
476 477 background-image:url('../images/close.png');
477 478 }
478 479
479 480 a.close-icon:hover {
480 481 background-image:url('../images/close_hl.png');
481 482 }
482 483
483 484 /***** Gantt chart *****/
484 485 .gantt_hdr {
485 486 position:absolute;
486 487 top:0;
487 488 height:16px;
488 489 border-top: 1px solid #c0c0c0;
489 490 border-bottom: 1px solid #c0c0c0;
490 491 border-right: 1px solid #c0c0c0;
491 492 text-align: center;
492 493 overflow: hidden;
493 494 }
494 495
495 496 .task {
496 497 position: absolute;
497 498 height:8px;
498 499 font-size:0.8em;
499 500 color:#888;
500 501 padding:0;
501 502 margin:0;
502 503 line-height:0.8em;
503 504 }
504 505
505 506 .task_late { background:#f66 url(../images/task_late.png); border: 1px solid #f66; }
506 507 .task_done { background:#66f url(../images/task_done.png); border: 1px solid #66f; }
507 508 .task_todo { background:#aaa url(../images/task_todo.png); border: 1px solid #aaa; }
508 509 .milestone { background-image:url(../images/milestone.png); background-repeat: no-repeat; border: 0; }
509 510
510 511 /***** Icons *****/
511 512 .icon {
512 513 background-position: 0% 40%;
513 514 background-repeat: no-repeat;
514 515 padding-left: 20px;
515 516 padding-top: 2px;
516 517 padding-bottom: 3px;
517 518 }
518 519
519 520 .icon22 {
520 521 background-position: 0% 40%;
521 522 background-repeat: no-repeat;
522 523 padding-left: 26px;
523 524 line-height: 22px;
524 525 vertical-align: middle;
525 526 }
526 527
527 528 .icon-add { background-image: url(../images/add.png); }
528 529 .icon-edit { background-image: url(../images/edit.png); }
529 530 .icon-copy { background-image: url(../images/copy.png); }
530 531 .icon-del { background-image: url(../images/delete.png); }
531 532 .icon-move { background-image: url(../images/move.png); }
532 533 .icon-save { background-image: url(../images/save.png); }
533 534 .icon-cancel { background-image: url(../images/cancel.png); }
534 535 .icon-file { background-image: url(../images/file.png); }
535 536 .icon-folder { background-image: url(../images/folder.png); }
536 537 .open .icon-folder { background-image: url(../images/folder_open.png); }
537 538 .icon-package { background-image: url(../images/package.png); }
538 539 .icon-home { background-image: url(../images/home.png); }
539 540 .icon-user { background-image: url(../images/user.png); }
540 541 .icon-mypage { background-image: url(../images/user_page.png); }
541 542 .icon-admin { background-image: url(../images/admin.png); }
542 543 .icon-projects { background-image: url(../images/projects.png); }
543 544 .icon-logout { background-image: url(../images/logout.png); }
544 545 .icon-help { background-image: url(../images/help.png); }
545 546 .icon-attachment { background-image: url(../images/attachment.png); }
546 547 .icon-index { background-image: url(../images/index.png); }
547 548 .icon-history { background-image: url(../images/history.png); }
548 549 .icon-time { background-image: url(../images/time.png); }
549 550 .icon-stats { background-image: url(../images/stats.png); }
550 551 .icon-warning { background-image: url(../images/warning.png); }
551 552 .icon-fav { background-image: url(../images/fav.png); }
552 553 .icon-fav-off { background-image: url(../images/fav_off.png); }
553 554 .icon-reload { background-image: url(../images/reload.png); }
554 555 .icon-lock { background-image: url(../images/locked.png); }
555 556 .icon-unlock { background-image: url(../images/unlock.png); }
556 557 .icon-checked { background-image: url(../images/true.png); }
557 558 .icon-details { background-image: url(../images/zoom_in.png); }
558 559 .icon-report { background-image: url(../images/report.png); }
559 560
560 561 .icon22-projects { background-image: url(../images/22x22/projects.png); }
561 562 .icon22-users { background-image: url(../images/22x22/users.png); }
562 563 .icon22-tracker { background-image: url(../images/22x22/tracker.png); }
563 564 .icon22-role { background-image: url(../images/22x22/role.png); }
564 565 .icon22-workflow { background-image: url(../images/22x22/workflow.png); }
565 566 .icon22-options { background-image: url(../images/22x22/options.png); }
566 567 .icon22-notifications { background-image: url(../images/22x22/notifications.png); }
567 568 .icon22-authent { background-image: url(../images/22x22/authent.png); }
568 569 .icon22-info { background-image: url(../images/22x22/info.png); }
569 570 .icon22-comment { background-image: url(../images/22x22/comment.png); }
570 571 .icon22-package { background-image: url(../images/22x22/package.png); }
571 572 .icon22-settings { background-image: url(../images/22x22/settings.png); }
572 573 .icon22-plugin { background-image: url(../images/22x22/plugin.png); }
573 574
574 575 /***** Media print specific styles *****/
575 576 @media print {
576 577 #top-menu, #header, #main-menu, #sidebar, #footer, .contextual { display:none; }
577 578 #main { background: #fff; }
578 579 #content { width: 99%; margin: 0; padding: 0; border: 0; background: #fff; }
579 580 }
General Comments 0
You need to be logged in to leave comments. Login now