##// END OF EJS Templates
Adds an helper to render other formats download links....
Jean-Philippe Lang -
r2331:f1aa0df32666
parent child
Show More
@@ -0,0 +1,33
1 # Redmine - project management software
2 # Copyright (C) 2006-2009 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 module Redmine
19 module Views
20 class OtherFormatsBuilder
21 def initialize(view)
22 @view = view
23 end
24
25 def link_to(name, options={})
26 url = { :format => name.to_s.downcase }.merge(options.delete(:url) || {})
27 caption = options.delete(:caption) || name
28 html_options = { :class => name.to_s.downcase }.merge(options)
29 @view.content_tag('span', @view.link_to(caption, url, html_options))
30 end
31 end
32 end
33 end
@@ -1,211 +1,211
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require 'diff'
18 require 'diff'
19
19
20 class WikiController < ApplicationController
20 class WikiController < ApplicationController
21 before_filter :find_wiki, :authorize
21 before_filter :find_wiki, :authorize
22 before_filter :find_existing_page, :only => [:rename, :protect, :history, :diff, :annotate, :add_attachment, :destroy]
22 before_filter :find_existing_page, :only => [:rename, :protect, :history, :diff, :annotate, :add_attachment, :destroy]
23
23
24 verify :method => :post, :only => [:destroy, :protect], :redirect_to => { :action => :index }
24 verify :method => :post, :only => [:destroy, :protect], :redirect_to => { :action => :index }
25
25
26 helper :attachments
26 helper :attachments
27 include AttachmentsHelper
27 include AttachmentsHelper
28
28
29 # display a page (in editing mode if it doesn't exist)
29 # display a page (in editing mode if it doesn't exist)
30 def index
30 def index
31 page_title = params[:page]
31 page_title = params[:page]
32 @page = @wiki.find_or_new_page(page_title)
32 @page = @wiki.find_or_new_page(page_title)
33 if @page.new_record?
33 if @page.new_record?
34 if User.current.allowed_to?(:edit_wiki_pages, @project)
34 if User.current.allowed_to?(:edit_wiki_pages, @project)
35 edit
35 edit
36 render :action => 'edit'
36 render :action => 'edit'
37 else
37 else
38 render_404
38 render_404
39 end
39 end
40 return
40 return
41 end
41 end
42 if params[:version] && !User.current.allowed_to?(:view_wiki_edits, @project)
42 if params[:version] && !User.current.allowed_to?(:view_wiki_edits, @project)
43 # Redirects user to the current version if he's not allowed to view previous versions
43 # Redirects user to the current version if he's not allowed to view previous versions
44 redirect_to :version => nil
44 redirect_to :version => nil
45 return
45 return
46 end
46 end
47 @content = @page.content_for_version(params[:version])
47 @content = @page.content_for_version(params[:version])
48 if params[:export] == 'html'
48 if params[:format] == 'html'
49 export = render_to_string :action => 'export', :layout => false
49 export = render_to_string :action => 'export', :layout => false
50 send_data(export, :type => 'text/html', :filename => "#{@page.title}.html")
50 send_data(export, :type => 'text/html', :filename => "#{@page.title}.html")
51 return
51 return
52 elsif params[:export] == 'txt'
52 elsif params[:format] == 'txt'
53 send_data(@content.text, :type => 'text/plain', :filename => "#{@page.title}.txt")
53 send_data(@content.text, :type => 'text/plain', :filename => "#{@page.title}.txt")
54 return
54 return
55 end
55 end
56 @editable = editable?
56 @editable = editable?
57 render :action => 'show'
57 render :action => 'show'
58 end
58 end
59
59
60 # edit an existing page or a new one
60 # edit an existing page or a new one
61 def edit
61 def edit
62 @page = @wiki.find_or_new_page(params[:page])
62 @page = @wiki.find_or_new_page(params[:page])
63 return render_403 unless editable?
63 return render_403 unless editable?
64 @page.content = WikiContent.new(:page => @page) if @page.new_record?
64 @page.content = WikiContent.new(:page => @page) if @page.new_record?
65
65
66 @content = @page.content_for_version(params[:version])
66 @content = @page.content_for_version(params[:version])
67 @content.text = initial_page_content(@page) if @content.text.blank?
67 @content.text = initial_page_content(@page) if @content.text.blank?
68 # don't keep previous comment
68 # don't keep previous comment
69 @content.comments = nil
69 @content.comments = nil
70 if request.get?
70 if request.get?
71 # To prevent StaleObjectError exception when reverting to a previous version
71 # To prevent StaleObjectError exception when reverting to a previous version
72 @content.version = @page.content.version
72 @content.version = @page.content.version
73 else
73 else
74 if !@page.new_record? && @content.text == params[:content][:text]
74 if !@page.new_record? && @content.text == params[:content][:text]
75 # don't save if text wasn't changed
75 # don't save if text wasn't changed
76 redirect_to :action => 'index', :id => @project, :page => @page.title
76 redirect_to :action => 'index', :id => @project, :page => @page.title
77 return
77 return
78 end
78 end
79 #@content.text = params[:content][:text]
79 #@content.text = params[:content][:text]
80 #@content.comments = params[:content][:comments]
80 #@content.comments = params[:content][:comments]
81 @content.attributes = params[:content]
81 @content.attributes = params[:content]
82 @content.author = User.current
82 @content.author = User.current
83 # if page is new @page.save will also save content, but not if page isn't a new record
83 # if page is new @page.save will also save content, but not if page isn't a new record
84 if (@page.new_record? ? @page.save : @content.save)
84 if (@page.new_record? ? @page.save : @content.save)
85 redirect_to :action => 'index', :id => @project, :page => @page.title
85 redirect_to :action => 'index', :id => @project, :page => @page.title
86 end
86 end
87 end
87 end
88 rescue ActiveRecord::StaleObjectError
88 rescue ActiveRecord::StaleObjectError
89 # Optimistic locking exception
89 # Optimistic locking exception
90 flash[:error] = l(:notice_locking_conflict)
90 flash[:error] = l(:notice_locking_conflict)
91 end
91 end
92
92
93 # rename a page
93 # rename a page
94 def rename
94 def rename
95 return render_403 unless editable?
95 return render_403 unless editable?
96 @page.redirect_existing_links = true
96 @page.redirect_existing_links = true
97 # used to display the *original* title if some AR validation errors occur
97 # used to display the *original* title if some AR validation errors occur
98 @original_title = @page.pretty_title
98 @original_title = @page.pretty_title
99 if request.post? && @page.update_attributes(params[:wiki_page])
99 if request.post? && @page.update_attributes(params[:wiki_page])
100 flash[:notice] = l(:notice_successful_update)
100 flash[:notice] = l(:notice_successful_update)
101 redirect_to :action => 'index', :id => @project, :page => @page.title
101 redirect_to :action => 'index', :id => @project, :page => @page.title
102 end
102 end
103 end
103 end
104
104
105 def protect
105 def protect
106 @page.update_attribute :protected, params[:protected]
106 @page.update_attribute :protected, params[:protected]
107 redirect_to :action => 'index', :id => @project, :page => @page.title
107 redirect_to :action => 'index', :id => @project, :page => @page.title
108 end
108 end
109
109
110 # show page history
110 # show page history
111 def history
111 def history
112 @version_count = @page.content.versions.count
112 @version_count = @page.content.versions.count
113 @version_pages = Paginator.new self, @version_count, per_page_option, params['p']
113 @version_pages = Paginator.new self, @version_count, per_page_option, params['p']
114 # don't load text
114 # don't load text
115 @versions = @page.content.versions.find :all,
115 @versions = @page.content.versions.find :all,
116 :select => "id, author_id, comments, updated_on, version",
116 :select => "id, author_id, comments, updated_on, version",
117 :order => 'version DESC',
117 :order => 'version DESC',
118 :limit => @version_pages.items_per_page + 1,
118 :limit => @version_pages.items_per_page + 1,
119 :offset => @version_pages.current.offset
119 :offset => @version_pages.current.offset
120
120
121 render :layout => false if request.xhr?
121 render :layout => false if request.xhr?
122 end
122 end
123
123
124 def diff
124 def diff
125 @diff = @page.diff(params[:version], params[:version_from])
125 @diff = @page.diff(params[:version], params[:version_from])
126 render_404 unless @diff
126 render_404 unless @diff
127 end
127 end
128
128
129 def annotate
129 def annotate
130 @annotate = @page.annotate(params[:version])
130 @annotate = @page.annotate(params[:version])
131 render_404 unless @annotate
131 render_404 unless @annotate
132 end
132 end
133
133
134 # remove a wiki page and its history
134 # remove a wiki page and its history
135 def destroy
135 def destroy
136 return render_403 unless editable?
136 return render_403 unless editable?
137 @page.destroy
137 @page.destroy
138 redirect_to :action => 'special', :id => @project, :page => 'Page_index'
138 redirect_to :action => 'special', :id => @project, :page => 'Page_index'
139 end
139 end
140
140
141 # display special pages
141 # display special pages
142 def special
142 def special
143 page_title = params[:page].downcase
143 page_title = params[:page].downcase
144 case page_title
144 case page_title
145 # show pages index, sorted by title
145 # show pages index, sorted by title
146 when 'page_index', 'date_index'
146 when 'page_index', 'date_index'
147 # eager load information about last updates, without loading text
147 # eager load information about last updates, without loading text
148 @pages = @wiki.pages.find :all, :select => "#{WikiPage.table_name}.*, #{WikiContent.table_name}.updated_on",
148 @pages = @wiki.pages.find :all, :select => "#{WikiPage.table_name}.*, #{WikiContent.table_name}.updated_on",
149 :joins => "LEFT JOIN #{WikiContent.table_name} ON #{WikiContent.table_name}.page_id = #{WikiPage.table_name}.id",
149 :joins => "LEFT JOIN #{WikiContent.table_name} ON #{WikiContent.table_name}.page_id = #{WikiPage.table_name}.id",
150 :order => 'title'
150 :order => 'title'
151 @pages_by_date = @pages.group_by {|p| p.updated_on.to_date}
151 @pages_by_date = @pages.group_by {|p| p.updated_on.to_date}
152 @pages_by_parent_id = @pages.group_by(&:parent_id)
152 @pages_by_parent_id = @pages.group_by(&:parent_id)
153 # export wiki to a single html file
153 # export wiki to a single html file
154 when 'export'
154 when 'export'
155 @pages = @wiki.pages.find :all, :order => 'title'
155 @pages = @wiki.pages.find :all, :order => 'title'
156 export = render_to_string :action => 'export_multiple', :layout => false
156 export = render_to_string :action => 'export_multiple', :layout => false
157 send_data(export, :type => 'text/html', :filename => "wiki.html")
157 send_data(export, :type => 'text/html', :filename => "wiki.html")
158 return
158 return
159 else
159 else
160 # requested special page doesn't exist, redirect to default page
160 # requested special page doesn't exist, redirect to default page
161 redirect_to :action => 'index', :id => @project, :page => nil and return
161 redirect_to :action => 'index', :id => @project, :page => nil and return
162 end
162 end
163 render :action => "special_#{page_title}"
163 render :action => "special_#{page_title}"
164 end
164 end
165
165
166 def preview
166 def preview
167 page = @wiki.find_page(params[:page])
167 page = @wiki.find_page(params[:page])
168 # page is nil when previewing a new page
168 # page is nil when previewing a new page
169 return render_403 unless page.nil? || editable?(page)
169 return render_403 unless page.nil? || editable?(page)
170 if page
170 if page
171 @attachements = page.attachments
171 @attachements = page.attachments
172 @previewed = page.content
172 @previewed = page.content
173 end
173 end
174 @text = params[:content][:text]
174 @text = params[:content][:text]
175 render :partial => 'common/preview'
175 render :partial => 'common/preview'
176 end
176 end
177
177
178 def add_attachment
178 def add_attachment
179 return render_403 unless editable?
179 return render_403 unless editable?
180 attach_files(@page, params[:attachments])
180 attach_files(@page, params[:attachments])
181 redirect_to :action => 'index', :page => @page.title
181 redirect_to :action => 'index', :page => @page.title
182 end
182 end
183
183
184 private
184 private
185
185
186 def find_wiki
186 def find_wiki
187 @project = Project.find(params[:id])
187 @project = Project.find(params[:id])
188 @wiki = @project.wiki
188 @wiki = @project.wiki
189 render_404 unless @wiki
189 render_404 unless @wiki
190 rescue ActiveRecord::RecordNotFound
190 rescue ActiveRecord::RecordNotFound
191 render_404
191 render_404
192 end
192 end
193
193
194 # Finds the requested page and returns a 404 error if it doesn't exist
194 # Finds the requested page and returns a 404 error if it doesn't exist
195 def find_existing_page
195 def find_existing_page
196 @page = @wiki.find_page(params[:page])
196 @page = @wiki.find_page(params[:page])
197 render_404 if @page.nil?
197 render_404 if @page.nil?
198 end
198 end
199
199
200 # Returns true if the current user is allowed to edit the page, otherwise false
200 # Returns true if the current user is allowed to edit the page, otherwise false
201 def editable?(page = @page)
201 def editable?(page = @page)
202 page.editable_by?(User.current)
202 page.editable_by?(User.current)
203 end
203 end
204
204
205 # Returns the default content of a new wiki page
205 # Returns the default content of a new wiki page
206 def initial_page_content(page)
206 def initial_page_content(page)
207 helper = Redmine::WikiFormatting.helper_for(Setting.text_formatting)
207 helper = Redmine::WikiFormatting.helper_for(Setting.text_formatting)
208 extend helper unless self.instance_of?(helper)
208 extend helper unless self.instance_of?(helper)
209 helper.instance_method(:initial_page_content).bind(self).call(page)
209 helper.instance_method(:initial_page_content).bind(self).call(page)
210 end
210 end
211 end
211 end
@@ -1,672 +1,678
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require 'coderay'
18 require 'coderay'
19 require 'coderay/helpers/file_type'
19 require 'coderay/helpers/file_type'
20 require 'forwardable'
20 require 'forwardable'
21 require 'cgi'
21 require 'cgi'
22
22
23 module ApplicationHelper
23 module ApplicationHelper
24 include Redmine::WikiFormatting::Macros::Definitions
24 include Redmine::WikiFormatting::Macros::Definitions
25 include GravatarHelper::PublicMethods
25 include GravatarHelper::PublicMethods
26
26
27 extend Forwardable
27 extend Forwardable
28 def_delegators :wiki_helper, :wikitoolbar_for, :heads_for_wiki_formatter
28 def_delegators :wiki_helper, :wikitoolbar_for, :heads_for_wiki_formatter
29
29
30 def current_role
30 def current_role
31 @current_role ||= User.current.role_for_project(@project)
31 @current_role ||= User.current.role_for_project(@project)
32 end
32 end
33
33
34 # Return true if user is authorized for controller/action, otherwise false
34 # Return true if user is authorized for controller/action, otherwise false
35 def authorize_for(controller, action)
35 def authorize_for(controller, action)
36 User.current.allowed_to?({:controller => controller, :action => action}, @project)
36 User.current.allowed_to?({:controller => controller, :action => action}, @project)
37 end
37 end
38
38
39 # Display a link if user is authorized
39 # Display a link if user is authorized
40 def link_to_if_authorized(name, options = {}, html_options = nil, *parameters_for_method_reference)
40 def link_to_if_authorized(name, options = {}, html_options = nil, *parameters_for_method_reference)
41 link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for(options[:controller] || params[:controller], options[:action])
41 link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for(options[:controller] || params[:controller], options[:action])
42 end
42 end
43
43
44 # Display a link to remote if user is authorized
44 # Display a link to remote if user is authorized
45 def link_to_remote_if_authorized(name, options = {}, html_options = nil)
45 def link_to_remote_if_authorized(name, options = {}, html_options = nil)
46 url = options[:url] || {}
46 url = options[:url] || {}
47 link_to_remote(name, options, html_options) if authorize_for(url[:controller] || params[:controller], url[:action])
47 link_to_remote(name, options, html_options) if authorize_for(url[:controller] || params[:controller], url[:action])
48 end
48 end
49
49
50 # Display a link to user's account page
50 # Display a link to user's account page
51 def link_to_user(user, options={})
51 def link_to_user(user, options={})
52 (user && !user.anonymous?) ? link_to(user.name(options[:format]), :controller => 'account', :action => 'show', :id => user) : 'Anonymous'
52 (user && !user.anonymous?) ? link_to(user.name(options[:format]), :controller => 'account', :action => 'show', :id => user) : 'Anonymous'
53 end
53 end
54
54
55 def link_to_issue(issue, options={})
55 def link_to_issue(issue, options={})
56 options[:class] ||= ''
56 options[:class] ||= ''
57 options[:class] << ' issue'
57 options[:class] << ' issue'
58 options[:class] << ' closed' if issue.closed?
58 options[:class] << ' closed' if issue.closed?
59 link_to "#{issue.tracker.name} ##{issue.id}", {:controller => "issues", :action => "show", :id => issue}, options
59 link_to "#{issue.tracker.name} ##{issue.id}", {:controller => "issues", :action => "show", :id => issue}, options
60 end
60 end
61
61
62 # Generates a link to an attachment.
62 # Generates a link to an attachment.
63 # Options:
63 # Options:
64 # * :text - Link text (default to attachment filename)
64 # * :text - Link text (default to attachment filename)
65 # * :download - Force download (default: false)
65 # * :download - Force download (default: false)
66 def link_to_attachment(attachment, options={})
66 def link_to_attachment(attachment, options={})
67 text = options.delete(:text) || attachment.filename
67 text = options.delete(:text) || attachment.filename
68 action = options.delete(:download) ? 'download' : 'show'
68 action = options.delete(:download) ? 'download' : 'show'
69
69
70 link_to(h(text), {:controller => 'attachments', :action => action, :id => attachment, :filename => attachment.filename }, options)
70 link_to(h(text), {:controller => 'attachments', :action => action, :id => attachment, :filename => attachment.filename }, options)
71 end
71 end
72
72
73 def toggle_link(name, id, options={})
73 def toggle_link(name, id, options={})
74 onclick = "Element.toggle('#{id}'); "
74 onclick = "Element.toggle('#{id}'); "
75 onclick << (options[:focus] ? "Form.Element.focus('#{options[:focus]}'); " : "this.blur(); ")
75 onclick << (options[:focus] ? "Form.Element.focus('#{options[:focus]}'); " : "this.blur(); ")
76 onclick << "return false;"
76 onclick << "return false;"
77 link_to(name, "#", :onclick => onclick)
77 link_to(name, "#", :onclick => onclick)
78 end
78 end
79
79
80 def image_to_function(name, function, html_options = {})
80 def image_to_function(name, function, html_options = {})
81 html_options.symbolize_keys!
81 html_options.symbolize_keys!
82 tag(:input, html_options.merge({
82 tag(:input, html_options.merge({
83 :type => "image", :src => image_path(name),
83 :type => "image", :src => image_path(name),
84 :onclick => (html_options[:onclick] ? "#{html_options[:onclick]}; " : "") + "#{function};"
84 :onclick => (html_options[:onclick] ? "#{html_options[:onclick]}; " : "") + "#{function};"
85 }))
85 }))
86 end
86 end
87
87
88 def prompt_to_remote(name, text, param, url, html_options = {})
88 def prompt_to_remote(name, text, param, url, html_options = {})
89 html_options[:onclick] = "promptToRemote('#{text}', '#{param}', '#{url_for(url)}'); return false;"
89 html_options[:onclick] = "promptToRemote('#{text}', '#{param}', '#{url_for(url)}'); return false;"
90 link_to name, {}, html_options
90 link_to name, {}, html_options
91 end
91 end
92
92
93 def format_date(date)
93 def format_date(date)
94 return nil unless date
94 return nil unless date
95 # "Setting.date_format.size < 2" is a temporary fix (content of date_format setting changed)
95 # "Setting.date_format.size < 2" is a temporary fix (content of date_format setting changed)
96 @date_format ||= (Setting.date_format.blank? || Setting.date_format.size < 2 ? l(:general_fmt_date) : Setting.date_format)
96 @date_format ||= (Setting.date_format.blank? || Setting.date_format.size < 2 ? l(:general_fmt_date) : Setting.date_format)
97 date.strftime(@date_format)
97 date.strftime(@date_format)
98 end
98 end
99
99
100 def format_time(time, include_date = true)
100 def format_time(time, include_date = true)
101 return nil unless time
101 return nil unless time
102 time = time.to_time if time.is_a?(String)
102 time = time.to_time if time.is_a?(String)
103 zone = User.current.time_zone
103 zone = User.current.time_zone
104 local = zone ? time.in_time_zone(zone) : (time.utc? ? time.localtime : time)
104 local = zone ? time.in_time_zone(zone) : (time.utc? ? time.localtime : time)
105 @date_format ||= (Setting.date_format.blank? || Setting.date_format.size < 2 ? l(:general_fmt_date) : Setting.date_format)
105 @date_format ||= (Setting.date_format.blank? || Setting.date_format.size < 2 ? l(:general_fmt_date) : Setting.date_format)
106 @time_format ||= (Setting.time_format.blank? ? l(:general_fmt_time) : Setting.time_format)
106 @time_format ||= (Setting.time_format.blank? ? l(:general_fmt_time) : Setting.time_format)
107 include_date ? local.strftime("#{@date_format} #{@time_format}") : local.strftime(@time_format)
107 include_date ? local.strftime("#{@date_format} #{@time_format}") : local.strftime(@time_format)
108 end
108 end
109
109
110 def format_activity_title(text)
110 def format_activity_title(text)
111 h(truncate_single_line(text, 100))
111 h(truncate_single_line(text, 100))
112 end
112 end
113
113
114 def format_activity_day(date)
114 def format_activity_day(date)
115 date == Date.today ? l(:label_today).titleize : format_date(date)
115 date == Date.today ? l(:label_today).titleize : format_date(date)
116 end
116 end
117
117
118 def format_activity_description(text)
118 def format_activity_description(text)
119 h(truncate(text.to_s, 250).gsub(%r{<(pre|code)>.*$}m, '...'))
119 h(truncate(text.to_s, 250).gsub(%r{<(pre|code)>.*$}m, '...'))
120 end
120 end
121
121
122 def distance_of_date_in_words(from_date, to_date = 0)
122 def distance_of_date_in_words(from_date, to_date = 0)
123 from_date = from_date.to_date if from_date.respond_to?(:to_date)
123 from_date = from_date.to_date if from_date.respond_to?(:to_date)
124 to_date = to_date.to_date if to_date.respond_to?(:to_date)
124 to_date = to_date.to_date if to_date.respond_to?(:to_date)
125 distance_in_days = (to_date - from_date).abs
125 distance_in_days = (to_date - from_date).abs
126 lwr(:actionview_datehelper_time_in_words_day, distance_in_days)
126 lwr(:actionview_datehelper_time_in_words_day, distance_in_days)
127 end
127 end
128
128
129 def due_date_distance_in_words(date)
129 def due_date_distance_in_words(date)
130 if date
130 if date
131 l((date < Date.today ? :label_roadmap_overdue : :label_roadmap_due_in), distance_of_date_in_words(Date.today, date))
131 l((date < Date.today ? :label_roadmap_overdue : :label_roadmap_due_in), distance_of_date_in_words(Date.today, date))
132 end
132 end
133 end
133 end
134
134
135 def render_page_hierarchy(pages, node=nil)
135 def render_page_hierarchy(pages, node=nil)
136 content = ''
136 content = ''
137 if pages[node]
137 if pages[node]
138 content << "<ul class=\"pages-hierarchy\">\n"
138 content << "<ul class=\"pages-hierarchy\">\n"
139 pages[node].each do |page|
139 pages[node].each do |page|
140 content << "<li>"
140 content << "<li>"
141 content << link_to(h(page.pretty_title), {:controller => 'wiki', :action => 'index', :id => page.project, :page => page.title},
141 content << link_to(h(page.pretty_title), {:controller => 'wiki', :action => 'index', :id => page.project, :page => page.title},
142 :title => (page.respond_to?(:updated_on) ? l(:label_updated_time, distance_of_time_in_words(Time.now, page.updated_on)) : nil))
142 :title => (page.respond_to?(:updated_on) ? l(:label_updated_time, distance_of_time_in_words(Time.now, page.updated_on)) : nil))
143 content << "\n" + render_page_hierarchy(pages, page.id) if pages[page.id]
143 content << "\n" + render_page_hierarchy(pages, page.id) if pages[page.id]
144 content << "</li>\n"
144 content << "</li>\n"
145 end
145 end
146 content << "</ul>\n"
146 content << "</ul>\n"
147 end
147 end
148 content
148 content
149 end
149 end
150
150
151 # Renders flash messages
151 # Renders flash messages
152 def render_flash_messages
152 def render_flash_messages
153 s = ''
153 s = ''
154 flash.each do |k,v|
154 flash.each do |k,v|
155 s << content_tag('div', v, :class => "flash #{k}")
155 s << content_tag('div', v, :class => "flash #{k}")
156 end
156 end
157 s
157 s
158 end
158 end
159
159
160 # Renders the project quick-jump box
160 # Renders the project quick-jump box
161 def render_project_jump_box
161 def render_project_jump_box
162 # Retrieve them now to avoid a COUNT query
162 # Retrieve them now to avoid a COUNT query
163 projects = User.current.projects.all
163 projects = User.current.projects.all
164 if projects.any?
164 if projects.any?
165 s = '<select onchange="if (this.value != \'\') { window.location = this.value; }">' +
165 s = '<select onchange="if (this.value != \'\') { window.location = this.value; }">' +
166 "<option selected='selected'>#{ l(:label_jump_to_a_project) }</option>" +
166 "<option selected='selected'>#{ l(:label_jump_to_a_project) }</option>" +
167 '<option disabled="disabled">---</option>'
167 '<option disabled="disabled">---</option>'
168 s << project_tree_options_for_select(projects) do |p|
168 s << project_tree_options_for_select(projects) do |p|
169 { :value => url_for(:controller => 'projects', :action => 'show', :id => p, :jump => current_menu_item) }
169 { :value => url_for(:controller => 'projects', :action => 'show', :id => p, :jump => current_menu_item) }
170 end
170 end
171 s << '</select>'
171 s << '</select>'
172 s
172 s
173 end
173 end
174 end
174 end
175
175
176 def project_tree_options_for_select(projects, options = {})
176 def project_tree_options_for_select(projects, options = {})
177 s = ''
177 s = ''
178 project_tree(projects) do |project, level|
178 project_tree(projects) do |project, level|
179 name_prefix = (level > 0 ? ('&nbsp;' * 2 * level + '&#187; ') : '')
179 name_prefix = (level > 0 ? ('&nbsp;' * 2 * level + '&#187; ') : '')
180 tag_options = {:value => project.id, :selected => ((project == options[:selected]) ? 'selected' : nil)}
180 tag_options = {:value => project.id, :selected => ((project == options[:selected]) ? 'selected' : nil)}
181 tag_options.merge!(yield(project)) if block_given?
181 tag_options.merge!(yield(project)) if block_given?
182 s << content_tag('option', name_prefix + h(project), tag_options)
182 s << content_tag('option', name_prefix + h(project), tag_options)
183 end
183 end
184 s
184 s
185 end
185 end
186
186
187 # Yields the given block for each project with its level in the tree
187 # Yields the given block for each project with its level in the tree
188 def project_tree(projects, &block)
188 def project_tree(projects, &block)
189 ancestors = []
189 ancestors = []
190 projects.sort_by(&:lft).each do |project|
190 projects.sort_by(&:lft).each do |project|
191 while (ancestors.any? && !project.is_descendant_of?(ancestors.last))
191 while (ancestors.any? && !project.is_descendant_of?(ancestors.last))
192 ancestors.pop
192 ancestors.pop
193 end
193 end
194 yield project, ancestors.size
194 yield project, ancestors.size
195 ancestors << project
195 ancestors << project
196 end
196 end
197 end
197 end
198
198
199 # Truncates and returns the string as a single line
199 # Truncates and returns the string as a single line
200 def truncate_single_line(string, *args)
200 def truncate_single_line(string, *args)
201 truncate(string, *args).gsub(%r{[\r\n]+}m, ' ')
201 truncate(string, *args).gsub(%r{[\r\n]+}m, ' ')
202 end
202 end
203
203
204 def html_hours(text)
204 def html_hours(text)
205 text.gsub(%r{(\d+)\.(\d+)}, '<span class="hours hours-int">\1</span><span class="hours hours-dec">.\2</span>')
205 text.gsub(%r{(\d+)\.(\d+)}, '<span class="hours hours-int">\1</span><span class="hours hours-dec">.\2</span>')
206 end
206 end
207
207
208 def authoring(created, author, options={})
208 def authoring(created, author, options={})
209 time_tag = @project.nil? ? content_tag('acronym', distance_of_time_in_words(Time.now, created), :title => format_time(created)) :
209 time_tag = @project.nil? ? content_tag('acronym', distance_of_time_in_words(Time.now, created), :title => format_time(created)) :
210 link_to(distance_of_time_in_words(Time.now, created),
210 link_to(distance_of_time_in_words(Time.now, created),
211 {:controller => 'projects', :action => 'activity', :id => @project, :from => created.to_date},
211 {:controller => 'projects', :action => 'activity', :id => @project, :from => created.to_date},
212 :title => format_time(created))
212 :title => format_time(created))
213 author_tag = (author.is_a?(User) && !author.anonymous?) ? link_to(h(author), :controller => 'account', :action => 'show', :id => author) : h(author || 'Anonymous')
213 author_tag = (author.is_a?(User) && !author.anonymous?) ? link_to(h(author), :controller => 'account', :action => 'show', :id => author) : h(author || 'Anonymous')
214 l(options[:label] || :label_added_time_by, author_tag, time_tag)
214 l(options[:label] || :label_added_time_by, author_tag, time_tag)
215 end
215 end
216
216
217 def l_or_humanize(s, options={})
217 def l_or_humanize(s, options={})
218 k = "#{options[:prefix]}#{s}".to_sym
218 k = "#{options[:prefix]}#{s}".to_sym
219 l_has_string?(k) ? l(k) : s.to_s.humanize
219 l_has_string?(k) ? l(k) : s.to_s.humanize
220 end
220 end
221
221
222 def day_name(day)
222 def day_name(day)
223 l(:general_day_names).split(',')[day-1]
223 l(:general_day_names).split(',')[day-1]
224 end
224 end
225
225
226 def month_name(month)
226 def month_name(month)
227 l(:actionview_datehelper_select_month_names).split(',')[month-1]
227 l(:actionview_datehelper_select_month_names).split(',')[month-1]
228 end
228 end
229
229
230 def syntax_highlight(name, content)
230 def syntax_highlight(name, content)
231 type = CodeRay::FileType[name]
231 type = CodeRay::FileType[name]
232 type ? CodeRay.scan(content, type).html : h(content)
232 type ? CodeRay.scan(content, type).html : h(content)
233 end
233 end
234
234
235 def to_path_param(path)
235 def to_path_param(path)
236 path.to_s.split(%r{[/\\]}).select {|p| !p.blank?}
236 path.to_s.split(%r{[/\\]}).select {|p| !p.blank?}
237 end
237 end
238
238
239 def pagination_links_full(paginator, count=nil, options={})
239 def pagination_links_full(paginator, count=nil, options={})
240 page_param = options.delete(:page_param) || :page
240 page_param = options.delete(:page_param) || :page
241 url_param = params.dup
241 url_param = params.dup
242 # don't reuse params if filters are present
242 # don't reuse params if filters are present
243 url_param.clear if url_param.has_key?(:set_filter)
243 url_param.clear if url_param.has_key?(:set_filter)
244
244
245 html = ''
245 html = ''
246 if paginator.current.previous
246 if paginator.current.previous
247 html << link_to_remote_content_update('&#171; ' + l(:label_previous), url_param.merge(page_param => paginator.current.previous)) + ' '
247 html << link_to_remote_content_update('&#171; ' + l(:label_previous), url_param.merge(page_param => paginator.current.previous)) + ' '
248 end
248 end
249
249
250 html << (pagination_links_each(paginator, options) do |n|
250 html << (pagination_links_each(paginator, options) do |n|
251 link_to_remote_content_update(n.to_s, url_param.merge(page_param => n))
251 link_to_remote_content_update(n.to_s, url_param.merge(page_param => n))
252 end || '')
252 end || '')
253
253
254 if paginator.current.next
254 if paginator.current.next
255 html << ' ' + link_to_remote_content_update((l(:label_next) + ' &#187;'), url_param.merge(page_param => paginator.current.next))
255 html << ' ' + link_to_remote_content_update((l(:label_next) + ' &#187;'), url_param.merge(page_param => paginator.current.next))
256 end
256 end
257
257
258 unless count.nil?
258 unless count.nil?
259 html << [
259 html << [
260 " (#{paginator.current.first_item}-#{paginator.current.last_item}/#{count})",
260 " (#{paginator.current.first_item}-#{paginator.current.last_item}/#{count})",
261 per_page_links(paginator.items_per_page)
261 per_page_links(paginator.items_per_page)
262 ].compact.join(' | ')
262 ].compact.join(' | ')
263 end
263 end
264
264
265 html
265 html
266 end
266 end
267
267
268 def per_page_links(selected=nil)
268 def per_page_links(selected=nil)
269 url_param = params.dup
269 url_param = params.dup
270 url_param.clear if url_param.has_key?(:set_filter)
270 url_param.clear if url_param.has_key?(:set_filter)
271
271
272 links = Setting.per_page_options_array.collect do |n|
272 links = Setting.per_page_options_array.collect do |n|
273 n == selected ? n : link_to_remote(n, {:update => "content",
273 n == selected ? n : link_to_remote(n, {:update => "content",
274 :url => params.dup.merge(:per_page => n),
274 :url => params.dup.merge(:per_page => n),
275 :method => :get},
275 :method => :get},
276 {:href => url_for(url_param.merge(:per_page => n))})
276 {:href => url_for(url_param.merge(:per_page => n))})
277 end
277 end
278 links.size > 1 ? l(:label_display_per_page, links.join(', ')) : nil
278 links.size > 1 ? l(:label_display_per_page, links.join(', ')) : nil
279 end
279 end
280
280
281 def breadcrumb(*args)
281 def breadcrumb(*args)
282 elements = args.flatten
282 elements = args.flatten
283 elements.any? ? content_tag('p', args.join(' &#187; ') + ' &#187; ', :class => 'breadcrumb') : nil
283 elements.any? ? content_tag('p', args.join(' &#187; ') + ' &#187; ', :class => 'breadcrumb') : nil
284 end
284 end
285
286 def other_formats_links(&block)
287 concat('<p class="other-formats">' + l(:label_export_to), block.binding)
288 yield Redmine::Views::OtherFormatsBuilder.new(self)
289 concat('</p>', block.binding)
290 end
285
291
286 def html_title(*args)
292 def html_title(*args)
287 if args.empty?
293 if args.empty?
288 title = []
294 title = []
289 title << @project.name if @project
295 title << @project.name if @project
290 title += @html_title if @html_title
296 title += @html_title if @html_title
291 title << Setting.app_title
297 title << Setting.app_title
292 title.compact.join(' - ')
298 title.compact.join(' - ')
293 else
299 else
294 @html_title ||= []
300 @html_title ||= []
295 @html_title += args
301 @html_title += args
296 end
302 end
297 end
303 end
298
304
299 def accesskey(s)
305 def accesskey(s)
300 Redmine::AccessKeys.key_for s
306 Redmine::AccessKeys.key_for s
301 end
307 end
302
308
303 # Formats text according to system settings.
309 # Formats text according to system settings.
304 # 2 ways to call this method:
310 # 2 ways to call this method:
305 # * with a String: textilizable(text, options)
311 # * with a String: textilizable(text, options)
306 # * with an object and one of its attribute: textilizable(issue, :description, options)
312 # * with an object and one of its attribute: textilizable(issue, :description, options)
307 def textilizable(*args)
313 def textilizable(*args)
308 options = args.last.is_a?(Hash) ? args.pop : {}
314 options = args.last.is_a?(Hash) ? args.pop : {}
309 case args.size
315 case args.size
310 when 1
316 when 1
311 obj = options[:object]
317 obj = options[:object]
312 text = args.shift
318 text = args.shift
313 when 2
319 when 2
314 obj = args.shift
320 obj = args.shift
315 text = obj.send(args.shift).to_s
321 text = obj.send(args.shift).to_s
316 else
322 else
317 raise ArgumentError, 'invalid arguments to textilizable'
323 raise ArgumentError, 'invalid arguments to textilizable'
318 end
324 end
319 return '' if text.blank?
325 return '' if text.blank?
320
326
321 only_path = options.delete(:only_path) == false ? false : true
327 only_path = options.delete(:only_path) == false ? false : true
322
328
323 # when using an image link, try to use an attachment, if possible
329 # when using an image link, try to use an attachment, if possible
324 attachments = options[:attachments] || (obj && obj.respond_to?(:attachments) ? obj.attachments : nil)
330 attachments = options[:attachments] || (obj && obj.respond_to?(:attachments) ? obj.attachments : nil)
325
331
326 if attachments
332 if attachments
327 attachments = attachments.sort_by(&:created_on).reverse
333 attachments = attachments.sort_by(&:created_on).reverse
328 text = text.gsub(/!((\<|\=|\>)?(\([^\)]+\))?(\[[^\]]+\])?(\{[^\}]+\})?)(\S+\.(bmp|gif|jpg|jpeg|png))!/i) do |m|
334 text = text.gsub(/!((\<|\=|\>)?(\([^\)]+\))?(\[[^\]]+\])?(\{[^\}]+\})?)(\S+\.(bmp|gif|jpg|jpeg|png))!/i) do |m|
329 style = $1
335 style = $1
330 filename = $6
336 filename = $6
331 rf = Regexp.new(Regexp.escape(filename), Regexp::IGNORECASE)
337 rf = Regexp.new(Regexp.escape(filename), Regexp::IGNORECASE)
332 # search for the picture in attachments
338 # search for the picture in attachments
333 if found = attachments.detect { |att| att.filename =~ rf }
339 if found = attachments.detect { |att| att.filename =~ rf }
334 image_url = url_for :only_path => only_path, :controller => 'attachments', :action => 'download', :id => found
340 image_url = url_for :only_path => only_path, :controller => 'attachments', :action => 'download', :id => found
335 desc = found.description.to_s.gsub(/^([^\(\)]*).*$/, "\\1")
341 desc = found.description.to_s.gsub(/^([^\(\)]*).*$/, "\\1")
336 alt = desc.blank? ? nil : "(#{desc})"
342 alt = desc.blank? ? nil : "(#{desc})"
337 "!#{style}#{image_url}#{alt}!"
343 "!#{style}#{image_url}#{alt}!"
338 else
344 else
339 "!#{style}#{filename}!"
345 "!#{style}#{filename}!"
340 end
346 end
341 end
347 end
342 end
348 end
343
349
344 text = Redmine::WikiFormatting.to_html(Setting.text_formatting, text) { |macro, args| exec_macro(macro, obj, args) }
350 text = Redmine::WikiFormatting.to_html(Setting.text_formatting, text) { |macro, args| exec_macro(macro, obj, args) }
345
351
346 # different methods for formatting wiki links
352 # different methods for formatting wiki links
347 case options[:wiki_links]
353 case options[:wiki_links]
348 when :local
354 when :local
349 # used for local links to html files
355 # used for local links to html files
350 format_wiki_link = Proc.new {|project, title, anchor| "#{title}.html" }
356 format_wiki_link = Proc.new {|project, title, anchor| "#{title}.html" }
351 when :anchor
357 when :anchor
352 # used for single-file wiki export
358 # used for single-file wiki export
353 format_wiki_link = Proc.new {|project, title, anchor| "##{title}" }
359 format_wiki_link = Proc.new {|project, title, anchor| "##{title}" }
354 else
360 else
355 format_wiki_link = Proc.new {|project, title, anchor| url_for(:only_path => only_path, :controller => 'wiki', :action => 'index', :id => project, :page => title, :anchor => anchor) }
361 format_wiki_link = Proc.new {|project, title, anchor| url_for(:only_path => only_path, :controller => 'wiki', :action => 'index', :id => project, :page => title, :anchor => anchor) }
356 end
362 end
357
363
358 project = options[:project] || @project || (obj && obj.respond_to?(:project) ? obj.project : nil)
364 project = options[:project] || @project || (obj && obj.respond_to?(:project) ? obj.project : nil)
359
365
360 # Wiki links
366 # Wiki links
361 #
367 #
362 # Examples:
368 # Examples:
363 # [[mypage]]
369 # [[mypage]]
364 # [[mypage|mytext]]
370 # [[mypage|mytext]]
365 # wiki links can refer other project wikis, using project name or identifier:
371 # wiki links can refer other project wikis, using project name or identifier:
366 # [[project:]] -> wiki starting page
372 # [[project:]] -> wiki starting page
367 # [[project:|mytext]]
373 # [[project:|mytext]]
368 # [[project:mypage]]
374 # [[project:mypage]]
369 # [[project:mypage|mytext]]
375 # [[project:mypage|mytext]]
370 text = text.gsub(/(!)?(\[\[([^\]\n\|]+)(\|([^\]\n\|]+))?\]\])/) do |m|
376 text = text.gsub(/(!)?(\[\[([^\]\n\|]+)(\|([^\]\n\|]+))?\]\])/) do |m|
371 link_project = project
377 link_project = project
372 esc, all, page, title = $1, $2, $3, $5
378 esc, all, page, title = $1, $2, $3, $5
373 if esc.nil?
379 if esc.nil?
374 if page =~ /^([^\:]+)\:(.*)$/
380 if page =~ /^([^\:]+)\:(.*)$/
375 link_project = Project.find_by_name($1) || Project.find_by_identifier($1)
381 link_project = Project.find_by_name($1) || Project.find_by_identifier($1)
376 page = $2
382 page = $2
377 title ||= $1 if page.blank?
383 title ||= $1 if page.blank?
378 end
384 end
379
385
380 if link_project && link_project.wiki
386 if link_project && link_project.wiki
381 # extract anchor
387 # extract anchor
382 anchor = nil
388 anchor = nil
383 if page =~ /^(.+?)\#(.+)$/
389 if page =~ /^(.+?)\#(.+)$/
384 page, anchor = $1, $2
390 page, anchor = $1, $2
385 end
391 end
386 # check if page exists
392 # check if page exists
387 wiki_page = link_project.wiki.find_page(page)
393 wiki_page = link_project.wiki.find_page(page)
388 link_to((title || page), format_wiki_link.call(link_project, Wiki.titleize(page), anchor),
394 link_to((title || page), format_wiki_link.call(link_project, Wiki.titleize(page), anchor),
389 :class => ('wiki-page' + (wiki_page ? '' : ' new')))
395 :class => ('wiki-page' + (wiki_page ? '' : ' new')))
390 else
396 else
391 # project or wiki doesn't exist
397 # project or wiki doesn't exist
392 title || page
398 title || page
393 end
399 end
394 else
400 else
395 all
401 all
396 end
402 end
397 end
403 end
398
404
399 # Redmine links
405 # Redmine links
400 #
406 #
401 # Examples:
407 # Examples:
402 # Issues:
408 # Issues:
403 # #52 -> Link to issue #52
409 # #52 -> Link to issue #52
404 # Changesets:
410 # Changesets:
405 # r52 -> Link to revision 52
411 # r52 -> Link to revision 52
406 # commit:a85130f -> Link to scmid starting with a85130f
412 # commit:a85130f -> Link to scmid starting with a85130f
407 # Documents:
413 # Documents:
408 # document#17 -> Link to document with id 17
414 # document#17 -> Link to document with id 17
409 # document:Greetings -> Link to the document with title "Greetings"
415 # document:Greetings -> Link to the document with title "Greetings"
410 # document:"Some document" -> Link to the document with title "Some document"
416 # document:"Some document" -> Link to the document with title "Some document"
411 # Versions:
417 # Versions:
412 # version#3 -> Link to version with id 3
418 # version#3 -> Link to version with id 3
413 # version:1.0.0 -> Link to version named "1.0.0"
419 # version:1.0.0 -> Link to version named "1.0.0"
414 # version:"1.0 beta 2" -> Link to version named "1.0 beta 2"
420 # version:"1.0 beta 2" -> Link to version named "1.0 beta 2"
415 # Attachments:
421 # Attachments:
416 # attachment:file.zip -> Link to the attachment of the current object named file.zip
422 # attachment:file.zip -> Link to the attachment of the current object named file.zip
417 # Source files:
423 # Source files:
418 # source:some/file -> Link to the file located at /some/file in the project's repository
424 # source:some/file -> Link to the file located at /some/file in the project's repository
419 # source:some/file@52 -> Link to the file's revision 52
425 # source:some/file@52 -> Link to the file's revision 52
420 # source:some/file#L120 -> Link to line 120 of the file
426 # source:some/file#L120 -> Link to line 120 of the file
421 # source:some/file@52#L120 -> Link to line 120 of the file's revision 52
427 # source:some/file@52#L120 -> Link to line 120 of the file's revision 52
422 # export:some/file -> Force the download of the file
428 # export:some/file -> Force the download of the file
423 # Forum messages:
429 # Forum messages:
424 # message#1218 -> Link to message with id 1218
430 # message#1218 -> Link to message with id 1218
425 text = text.gsub(%r{([\s\(,\-\>]|^)(!)?(attachment|document|version|commit|source|export|message)?((#|r)(\d+)|(:)([^"\s<>][^\s<>]*?|"[^"]+?"))(?=(?=[[:punct:]]\W)|\s|<|$)}) do |m|
431 text = text.gsub(%r{([\s\(,\-\>]|^)(!)?(attachment|document|version|commit|source|export|message)?((#|r)(\d+)|(:)([^"\s<>][^\s<>]*?|"[^"]+?"))(?=(?=[[:punct:]]\W)|\s|<|$)}) do |m|
426 leading, esc, prefix, sep, oid = $1, $2, $3, $5 || $7, $6 || $8
432 leading, esc, prefix, sep, oid = $1, $2, $3, $5 || $7, $6 || $8
427 link = nil
433 link = nil
428 if esc.nil?
434 if esc.nil?
429 if prefix.nil? && sep == 'r'
435 if prefix.nil? && sep == 'r'
430 if project && (changeset = project.changesets.find_by_revision(oid))
436 if project && (changeset = project.changesets.find_by_revision(oid))
431 link = link_to("r#{oid}", {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :rev => oid},
437 link = link_to("r#{oid}", {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :rev => oid},
432 :class => 'changeset',
438 :class => 'changeset',
433 :title => truncate_single_line(changeset.comments, 100))
439 :title => truncate_single_line(changeset.comments, 100))
434 end
440 end
435 elsif sep == '#'
441 elsif sep == '#'
436 oid = oid.to_i
442 oid = oid.to_i
437 case prefix
443 case prefix
438 when nil
444 when nil
439 if issue = Issue.find_by_id(oid, :include => [:project, :status], :conditions => Project.visible_by(User.current))
445 if issue = Issue.find_by_id(oid, :include => [:project, :status], :conditions => Project.visible_by(User.current))
440 link = link_to("##{oid}", {:only_path => only_path, :controller => 'issues', :action => 'show', :id => oid},
446 link = link_to("##{oid}", {:only_path => only_path, :controller => 'issues', :action => 'show', :id => oid},
441 :class => (issue.closed? ? 'issue closed' : 'issue'),
447 :class => (issue.closed? ? 'issue closed' : 'issue'),
442 :title => "#{truncate(issue.subject, 100)} (#{issue.status.name})")
448 :title => "#{truncate(issue.subject, 100)} (#{issue.status.name})")
443 link = content_tag('del', link) if issue.closed?
449 link = content_tag('del', link) if issue.closed?
444 end
450 end
445 when 'document'
451 when 'document'
446 if document = Document.find_by_id(oid, :include => [:project], :conditions => Project.visible_by(User.current))
452 if document = Document.find_by_id(oid, :include => [:project], :conditions => Project.visible_by(User.current))
447 link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document},
453 link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document},
448 :class => 'document'
454 :class => 'document'
449 end
455 end
450 when 'version'
456 when 'version'
451 if version = Version.find_by_id(oid, :include => [:project], :conditions => Project.visible_by(User.current))
457 if version = Version.find_by_id(oid, :include => [:project], :conditions => Project.visible_by(User.current))
452 link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
458 link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
453 :class => 'version'
459 :class => 'version'
454 end
460 end
455 when 'message'
461 when 'message'
456 if message = Message.find_by_id(oid, :include => [:parent, {:board => :project}], :conditions => Project.visible_by(User.current))
462 if message = Message.find_by_id(oid, :include => [:parent, {:board => :project}], :conditions => Project.visible_by(User.current))
457 link = link_to h(truncate(message.subject, 60)), {:only_path => only_path,
463 link = link_to h(truncate(message.subject, 60)), {:only_path => only_path,
458 :controller => 'messages',
464 :controller => 'messages',
459 :action => 'show',
465 :action => 'show',
460 :board_id => message.board,
466 :board_id => message.board,
461 :id => message.root,
467 :id => message.root,
462 :anchor => (message.parent ? "message-#{message.id}" : nil)},
468 :anchor => (message.parent ? "message-#{message.id}" : nil)},
463 :class => 'message'
469 :class => 'message'
464 end
470 end
465 end
471 end
466 elsif sep == ':'
472 elsif sep == ':'
467 # removes the double quotes if any
473 # removes the double quotes if any
468 name = oid.gsub(%r{^"(.*)"$}, "\\1")
474 name = oid.gsub(%r{^"(.*)"$}, "\\1")
469 case prefix
475 case prefix
470 when 'document'
476 when 'document'
471 if project && document = project.documents.find_by_title(name)
477 if project && document = project.documents.find_by_title(name)
472 link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document},
478 link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document},
473 :class => 'document'
479 :class => 'document'
474 end
480 end
475 when 'version'
481 when 'version'
476 if project && version = project.versions.find_by_name(name)
482 if project && version = project.versions.find_by_name(name)
477 link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
483 link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
478 :class => 'version'
484 :class => 'version'
479 end
485 end
480 when 'commit'
486 when 'commit'
481 if project && (changeset = project.changesets.find(:first, :conditions => ["scmid LIKE ?", "#{name}%"]))
487 if project && (changeset = project.changesets.find(:first, :conditions => ["scmid LIKE ?", "#{name}%"]))
482 link = link_to h("#{name}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :rev => changeset.revision},
488 link = link_to h("#{name}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :rev => changeset.revision},
483 :class => 'changeset',
489 :class => 'changeset',
484 :title => truncate_single_line(changeset.comments, 100)
490 :title => truncate_single_line(changeset.comments, 100)
485 end
491 end
486 when 'source', 'export'
492 when 'source', 'export'
487 if project && project.repository
493 if project && project.repository
488 name =~ %r{^[/\\]*(.*?)(@([0-9a-f]+))?(#(L\d+))?$}
494 name =~ %r{^[/\\]*(.*?)(@([0-9a-f]+))?(#(L\d+))?$}
489 path, rev, anchor = $1, $3, $5
495 path, rev, anchor = $1, $3, $5
490 link = link_to h("#{prefix}:#{name}"), {:controller => 'repositories', :action => 'entry', :id => project,
496 link = link_to h("#{prefix}:#{name}"), {:controller => 'repositories', :action => 'entry', :id => project,
491 :path => to_path_param(path),
497 :path => to_path_param(path),
492 :rev => rev,
498 :rev => rev,
493 :anchor => anchor,
499 :anchor => anchor,
494 :format => (prefix == 'export' ? 'raw' : nil)},
500 :format => (prefix == 'export' ? 'raw' : nil)},
495 :class => (prefix == 'export' ? 'source download' : 'source')
501 :class => (prefix == 'export' ? 'source download' : 'source')
496 end
502 end
497 when 'attachment'
503 when 'attachment'
498 if attachments && attachment = attachments.detect {|a| a.filename == name }
504 if attachments && attachment = attachments.detect {|a| a.filename == name }
499 link = link_to h(attachment.filename), {:only_path => only_path, :controller => 'attachments', :action => 'download', :id => attachment},
505 link = link_to h(attachment.filename), {:only_path => only_path, :controller => 'attachments', :action => 'download', :id => attachment},
500 :class => 'attachment'
506 :class => 'attachment'
501 end
507 end
502 end
508 end
503 end
509 end
504 end
510 end
505 leading + (link || "#{prefix}#{sep}#{oid}")
511 leading + (link || "#{prefix}#{sep}#{oid}")
506 end
512 end
507
513
508 text
514 text
509 end
515 end
510
516
511 # Same as Rails' simple_format helper without using paragraphs
517 # Same as Rails' simple_format helper without using paragraphs
512 def simple_format_without_paragraph(text)
518 def simple_format_without_paragraph(text)
513 text.to_s.
519 text.to_s.
514 gsub(/\r\n?/, "\n"). # \r\n and \r -> \n
520 gsub(/\r\n?/, "\n"). # \r\n and \r -> \n
515 gsub(/\n\n+/, "<br /><br />"). # 2+ newline -> 2 br
521 gsub(/\n\n+/, "<br /><br />"). # 2+ newline -> 2 br
516 gsub(/([^\n]\n)(?=[^\n])/, '\1<br />') # 1 newline -> br
522 gsub(/([^\n]\n)(?=[^\n])/, '\1<br />') # 1 newline -> br
517 end
523 end
518
524
519 def error_messages_for(object_name, options = {})
525 def error_messages_for(object_name, options = {})
520 options = options.symbolize_keys
526 options = options.symbolize_keys
521 object = instance_variable_get("@#{object_name}")
527 object = instance_variable_get("@#{object_name}")
522 if object && !object.errors.empty?
528 if object && !object.errors.empty?
523 # build full_messages here with controller current language
529 # build full_messages here with controller current language
524 full_messages = []
530 full_messages = []
525 object.errors.each do |attr, msg|
531 object.errors.each do |attr, msg|
526 next if msg.nil?
532 next if msg.nil?
527 msg = msg.first if msg.is_a? Array
533 msg = msg.first if msg.is_a? Array
528 if attr == "base"
534 if attr == "base"
529 full_messages << l(msg)
535 full_messages << l(msg)
530 else
536 else
531 full_messages << "&#171; " + (l_has_string?("field_" + attr) ? l("field_" + attr) : object.class.human_attribute_name(attr)) + " &#187; " + l(msg) unless attr == "custom_values"
537 full_messages << "&#171; " + (l_has_string?("field_" + attr) ? l("field_" + attr) : object.class.human_attribute_name(attr)) + " &#187; " + l(msg) unless attr == "custom_values"
532 end
538 end
533 end
539 end
534 # retrieve custom values error messages
540 # retrieve custom values error messages
535 if object.errors[:custom_values]
541 if object.errors[:custom_values]
536 object.custom_values.each do |v|
542 object.custom_values.each do |v|
537 v.errors.each do |attr, msg|
543 v.errors.each do |attr, msg|
538 next if msg.nil?
544 next if msg.nil?
539 msg = msg.first if msg.is_a? Array
545 msg = msg.first if msg.is_a? Array
540 full_messages << "&#171; " + v.custom_field.name + " &#187; " + l(msg)
546 full_messages << "&#171; " + v.custom_field.name + " &#187; " + l(msg)
541 end
547 end
542 end
548 end
543 end
549 end
544 content_tag("div",
550 content_tag("div",
545 content_tag(
551 content_tag(
546 options[:header_tag] || "span", lwr(:gui_validation_error, full_messages.length) + ":"
552 options[:header_tag] || "span", lwr(:gui_validation_error, full_messages.length) + ":"
547 ) +
553 ) +
548 content_tag("ul", full_messages.collect { |msg| content_tag("li", msg) }),
554 content_tag("ul", full_messages.collect { |msg| content_tag("li", msg) }),
549 "id" => options[:id] || "errorExplanation", "class" => options[:class] || "errorExplanation"
555 "id" => options[:id] || "errorExplanation", "class" => options[:class] || "errorExplanation"
550 )
556 )
551 else
557 else
552 ""
558 ""
553 end
559 end
554 end
560 end
555
561
556 def lang_options_for_select(blank=true)
562 def lang_options_for_select(blank=true)
557 (blank ? [["(auto)", ""]] : []) +
563 (blank ? [["(auto)", ""]] : []) +
558 GLoc.valid_languages.collect{|lang| [ ll(lang.to_s, :general_lang_name), lang.to_s]}.sort{|x,y| x.last <=> y.last }
564 GLoc.valid_languages.collect{|lang| [ ll(lang.to_s, :general_lang_name), lang.to_s]}.sort{|x,y| x.last <=> y.last }
559 end
565 end
560
566
561 def label_tag_for(name, option_tags = nil, options = {})
567 def label_tag_for(name, option_tags = nil, options = {})
562 label_text = l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) + (options.delete(:required) ? @template.content_tag("span", " *", :class => "required"): "")
568 label_text = l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) + (options.delete(:required) ? @template.content_tag("span", " *", :class => "required"): "")
563 content_tag("label", label_text)
569 content_tag("label", label_text)
564 end
570 end
565
571
566 def labelled_tabular_form_for(name, object, options, &proc)
572 def labelled_tabular_form_for(name, object, options, &proc)
567 options[:html] ||= {}
573 options[:html] ||= {}
568 options[:html][:class] = 'tabular' unless options[:html].has_key?(:class)
574 options[:html][:class] = 'tabular' unless options[:html].has_key?(:class)
569 form_for(name, object, options.merge({ :builder => TabularFormBuilder, :lang => current_language}), &proc)
575 form_for(name, object, options.merge({ :builder => TabularFormBuilder, :lang => current_language}), &proc)
570 end
576 end
571
577
572 def back_url_hidden_field_tag
578 def back_url_hidden_field_tag
573 back_url = params[:back_url] || request.env['HTTP_REFERER']
579 back_url = params[:back_url] || request.env['HTTP_REFERER']
574 back_url = CGI.unescape(back_url.to_s)
580 back_url = CGI.unescape(back_url.to_s)
575 hidden_field_tag('back_url', CGI.escape(back_url)) unless back_url.blank?
581 hidden_field_tag('back_url', CGI.escape(back_url)) unless back_url.blank?
576 end
582 end
577
583
578 def check_all_links(form_name)
584 def check_all_links(form_name)
579 link_to_function(l(:button_check_all), "checkAll('#{form_name}', true)") +
585 link_to_function(l(:button_check_all), "checkAll('#{form_name}', true)") +
580 " | " +
586 " | " +
581 link_to_function(l(:button_uncheck_all), "checkAll('#{form_name}', false)")
587 link_to_function(l(:button_uncheck_all), "checkAll('#{form_name}', false)")
582 end
588 end
583
589
584 def progress_bar(pcts, options={})
590 def progress_bar(pcts, options={})
585 pcts = [pcts, pcts] unless pcts.is_a?(Array)
591 pcts = [pcts, pcts] unless pcts.is_a?(Array)
586 pcts[1] = pcts[1] - pcts[0]
592 pcts[1] = pcts[1] - pcts[0]
587 pcts << (100 - pcts[1] - pcts[0])
593 pcts << (100 - pcts[1] - pcts[0])
588 width = options[:width] || '100px;'
594 width = options[:width] || '100px;'
589 legend = options[:legend] || ''
595 legend = options[:legend] || ''
590 content_tag('table',
596 content_tag('table',
591 content_tag('tr',
597 content_tag('tr',
592 (pcts[0] > 0 ? content_tag('td', '', :style => "width: #{pcts[0].floor}%;", :class => 'closed') : '') +
598 (pcts[0] > 0 ? content_tag('td', '', :style => "width: #{pcts[0].floor}%;", :class => 'closed') : '') +
593 (pcts[1] > 0 ? content_tag('td', '', :style => "width: #{pcts[1].floor}%;", :class => 'done') : '') +
599 (pcts[1] > 0 ? content_tag('td', '', :style => "width: #{pcts[1].floor}%;", :class => 'done') : '') +
594 (pcts[2] > 0 ? content_tag('td', '', :style => "width: #{pcts[2].floor}%;", :class => 'todo') : '')
600 (pcts[2] > 0 ? content_tag('td', '', :style => "width: #{pcts[2].floor}%;", :class => 'todo') : '')
595 ), :class => 'progress', :style => "width: #{width};") +
601 ), :class => 'progress', :style => "width: #{width};") +
596 content_tag('p', legend, :class => 'pourcent')
602 content_tag('p', legend, :class => 'pourcent')
597 end
603 end
598
604
599 def context_menu_link(name, url, options={})
605 def context_menu_link(name, url, options={})
600 options[:class] ||= ''
606 options[:class] ||= ''
601 if options.delete(:selected)
607 if options.delete(:selected)
602 options[:class] << ' icon-checked disabled'
608 options[:class] << ' icon-checked disabled'
603 options[:disabled] = true
609 options[:disabled] = true
604 end
610 end
605 if options.delete(:disabled)
611 if options.delete(:disabled)
606 options.delete(:method)
612 options.delete(:method)
607 options.delete(:confirm)
613 options.delete(:confirm)
608 options.delete(:onclick)
614 options.delete(:onclick)
609 options[:class] << ' disabled'
615 options[:class] << ' disabled'
610 url = '#'
616 url = '#'
611 end
617 end
612 link_to name, url, options
618 link_to name, url, options
613 end
619 end
614
620
615 def calendar_for(field_id)
621 def calendar_for(field_id)
616 include_calendar_headers_tags
622 include_calendar_headers_tags
617 image_tag("calendar.png", {:id => "#{field_id}_trigger",:class => "calendar-trigger"}) +
623 image_tag("calendar.png", {:id => "#{field_id}_trigger",:class => "calendar-trigger"}) +
618 javascript_tag("Calendar.setup({inputField : '#{field_id}', ifFormat : '%Y-%m-%d', button : '#{field_id}_trigger' });")
624 javascript_tag("Calendar.setup({inputField : '#{field_id}', ifFormat : '%Y-%m-%d', button : '#{field_id}_trigger' });")
619 end
625 end
620
626
621 def include_calendar_headers_tags
627 def include_calendar_headers_tags
622 unless @calendar_headers_tags_included
628 unless @calendar_headers_tags_included
623 @calendar_headers_tags_included = true
629 @calendar_headers_tags_included = true
624 content_for :header_tags do
630 content_for :header_tags do
625 javascript_include_tag('calendar/calendar') +
631 javascript_include_tag('calendar/calendar') +
626 javascript_include_tag("calendar/lang/calendar-#{current_language}.js") +
632 javascript_include_tag("calendar/lang/calendar-#{current_language}.js") +
627 javascript_include_tag('calendar/calendar-setup') +
633 javascript_include_tag('calendar/calendar-setup') +
628 stylesheet_link_tag('calendar')
634 stylesheet_link_tag('calendar')
629 end
635 end
630 end
636 end
631 end
637 end
632
638
633 def content_for(name, content = nil, &block)
639 def content_for(name, content = nil, &block)
634 @has_content ||= {}
640 @has_content ||= {}
635 @has_content[name] = true
641 @has_content[name] = true
636 super(name, content, &block)
642 super(name, content, &block)
637 end
643 end
638
644
639 def has_content?(name)
645 def has_content?(name)
640 (@has_content && @has_content[name]) || false
646 (@has_content && @has_content[name]) || false
641 end
647 end
642
648
643 # Returns the avatar image tag for the given +user+ if avatars are enabled
649 # Returns the avatar image tag for the given +user+ if avatars are enabled
644 # +user+ can be a User or a string that will be scanned for an email address (eg. 'joe <joe@foo.bar>')
650 # +user+ can be a User or a string that will be scanned for an email address (eg. 'joe <joe@foo.bar>')
645 def avatar(user, options = { })
651 def avatar(user, options = { })
646 if Setting.gravatar_enabled?
652 if Setting.gravatar_enabled?
647 email = nil
653 email = nil
648 if user.respond_to?(:mail)
654 if user.respond_to?(:mail)
649 email = user.mail
655 email = user.mail
650 elsif user.to_s =~ %r{<(.+?)>}
656 elsif user.to_s =~ %r{<(.+?)>}
651 email = $1
657 email = $1
652 end
658 end
653 return gravatar(email.to_s.downcase, options) unless email.blank? rescue nil
659 return gravatar(email.to_s.downcase, options) unless email.blank? rescue nil
654 end
660 end
655 end
661 end
656
662
657 private
663 private
658
664
659 def wiki_helper
665 def wiki_helper
660 helper = Redmine::WikiFormatting.helper_for(Setting.text_formatting)
666 helper = Redmine::WikiFormatting.helper_for(Setting.text_formatting)
661 extend helper
667 extend helper
662 return self
668 return self
663 end
669 end
664
670
665 def link_to_remote_content_update(text, url_params)
671 def link_to_remote_content_update(text, url_params)
666 link_to_remote(text,
672 link_to_remote(text,
667 {:url => url_params, :method => :get, :update => 'content', :complete => 'window.scrollTo(0,0)'},
673 {:url => url_params, :method => :get, :update => 'content', :complete => 'window.scrollTo(0,0)'},
668 {:href => url_for(:params => url_params)}
674 {:href => url_for(:params => url_params)}
669 )
675 )
670 end
676 end
671
677
672 end
678 end
@@ -1,69 +1,68
1 <div class="contextual">
1 <div class="contextual">
2 <%= link_to(l(:button_edit), {:controller => 'users', :action => 'edit', :id => @user}, :class => 'icon icon-edit') if User.current.admin? %>
2 <%= link_to(l(:button_edit), {:controller => 'users', :action => 'edit', :id => @user}, :class => 'icon icon-edit') if User.current.admin? %>
3 </div>
3 </div>
4
4
5 <h2><%= avatar @user %> <%=h @user.name %></h2>
5 <h2><%= avatar @user %> <%=h @user.name %></h2>
6
6
7 <div class="splitcontentleft">
7 <div class="splitcontentleft">
8 <ul>
8 <ul>
9 <% unless @user.pref.hide_mail %>
9 <% unless @user.pref.hide_mail %>
10 <li><%=l(:field_mail)%>: <%= mail_to(h(@user.mail), nil, :encode => 'javascript') %></li>
10 <li><%=l(:field_mail)%>: <%= mail_to(h(@user.mail), nil, :encode => 'javascript') %></li>
11 <% end %>
11 <% end %>
12 <% for custom_value in @custom_values %>
12 <% for custom_value in @custom_values %>
13 <% if !custom_value.value.empty? %>
13 <% if !custom_value.value.empty? %>
14 <li><%= custom_value.custom_field.name%>: <%=h show_value(custom_value) %></li>
14 <li><%= custom_value.custom_field.name%>: <%=h show_value(custom_value) %></li>
15 <% end %>
15 <% end %>
16 <% end %>
16 <% end %>
17 <li><%=l(:label_registered_on)%>: <%= format_date(@user.created_on) %></li>
17 <li><%=l(:label_registered_on)%>: <%= format_date(@user.created_on) %></li>
18 <% unless @user.last_login_on.nil? %>
18 <% unless @user.last_login_on.nil? %>
19 <li><%=l(:field_last_login_on)%>: <%= format_date(@user.last_login_on) %></li>
19 <li><%=l(:field_last_login_on)%>: <%= format_date(@user.last_login_on) %></li>
20 <% end %>
20 <% end %>
21 </ul>
21 </ul>
22
22
23 <% unless @memberships.empty? %>
23 <% unless @memberships.empty? %>
24 <h3><%=l(:label_project_plural)%></h3>
24 <h3><%=l(:label_project_plural)%></h3>
25 <ul>
25 <ul>
26 <% for membership in @memberships %>
26 <% for membership in @memberships %>
27 <li><%= link_to(h(membership.project.name), :controller => 'projects', :action => 'show', :id => membership.project) %>
27 <li><%= link_to(h(membership.project.name), :controller => 'projects', :action => 'show', :id => membership.project) %>
28 (<%=h membership.role.name %>, <%= format_date(membership.created_on) %>)</li>
28 (<%=h membership.role.name %>, <%= format_date(membership.created_on) %>)</li>
29 <% end %>
29 <% end %>
30 </ul>
30 </ul>
31 <% end %>
31 <% end %>
32 </div>
32 </div>
33
33
34 <div class="splitcontentright">
34 <div class="splitcontentright">
35
35
36 <% unless @events_by_day.empty? %>
36 <% unless @events_by_day.empty? %>
37 <h3><%= link_to l(:label_activity), :controller => 'projects', :action => 'activity', :user_id => @user, :from => @events_by_day.keys.first %></h3>
37 <h3><%= link_to l(:label_activity), :controller => 'projects', :action => 'activity', :user_id => @user, :from => @events_by_day.keys.first %></h3>
38
38
39 <p>
39 <p>
40 <%=l(:label_reported_issues)%>: <%= Issue.count(:conditions => ["author_id=?", @user.id]) %>
40 <%=l(:label_reported_issues)%>: <%= Issue.count(:conditions => ["author_id=?", @user.id]) %>
41 </p>
41 </p>
42
42
43 <div id="activity">
43 <div id="activity">
44 <% @events_by_day.keys.sort.reverse.each do |day| %>
44 <% @events_by_day.keys.sort.reverse.each do |day| %>
45 <h4><%= format_activity_day(day) %></h4>
45 <h4><%= format_activity_day(day) %></h4>
46 <dl>
46 <dl>
47 <% @events_by_day[day].sort {|x,y| y.event_datetime <=> x.event_datetime }.each do |e| -%>
47 <% @events_by_day[day].sort {|x,y| y.event_datetime <=> x.event_datetime }.each do |e| -%>
48 <dt class="<%= e.event_type %>">
48 <dt class="<%= e.event_type %>">
49 <span class="time"><%= format_time(e.event_datetime, false) %></span>
49 <span class="time"><%= format_time(e.event_datetime, false) %></span>
50 <%= content_tag('span', h(e.project), :class => 'project') %>
50 <%= content_tag('span', h(e.project), :class => 'project') %>
51 <%= link_to format_activity_title(e.event_title), e.event_url %></dt>
51 <%= link_to format_activity_title(e.event_title), e.event_url %></dt>
52 <dd><span class="description"><%= format_activity_description(e.event_description) %></span></dd>
52 <dd><span class="description"><%= format_activity_description(e.event_description) %></span></dd>
53 <% end -%>
53 <% end -%>
54 </dl>
54 </dl>
55 <% end -%>
55 <% end -%>
56 </div>
56 </div>
57
57
58 <p class="other-formats">
58 <% other_formats_links do |f| %>
59 <%= l(:label_export_to) %>
59 <%= f.link_to 'Atom', :url => {:controller => 'projects', :action => 'activity', :id => nil, :user_id => @user, :key => User.current.rss_key} %>
60 <%= link_to 'Atom', {:controller => 'projects', :action => 'activity', :id => nil, :user_id => @user, :format => :atom, :key => User.current.rss_key}, :class => 'feed' %>
60 <% end %>
61 </p>
62
61
63 <% content_for :header_tags do %>
62 <% content_for :header_tags do %>
64 <%= auto_discovery_link_tag(:atom, :controller => 'projects', :action => 'activity', :user_id => @user, :format => :atom, :key => User.current.rss_key) %>
63 <%= auto_discovery_link_tag(:atom, :controller => 'projects', :action => 'activity', :user_id => @user, :format => :atom, :key => User.current.rss_key) %>
65 <% end %>
64 <% end %>
66 <% end %>
65 <% end %>
67 </div>
66 </div>
68
67
69 <% html_title @user.name %>
68 <% html_title @user.name %>
@@ -1,42 +1,40
1 <h2><%= l(:label_board_plural) %></h2>
1 <h2><%= l(:label_board_plural) %></h2>
2
2
3 <table class="list boards">
3 <table class="list boards">
4 <thead><tr>
4 <thead><tr>
5 <th><%= l(:label_board) %></th>
5 <th><%= l(:label_board) %></th>
6 <th><%= l(:label_topic_plural) %></th>
6 <th><%= l(:label_topic_plural) %></th>
7 <th><%= l(:label_message_plural) %></th>
7 <th><%= l(:label_message_plural) %></th>
8 <th><%= l(:label_message_last) %></th>
8 <th><%= l(:label_message_last) %></th>
9 </tr></thead>
9 </tr></thead>
10 <tbody>
10 <tbody>
11 <% for board in @boards %>
11 <% for board in @boards %>
12 <tr class="<%= cycle 'odd', 'even' %>">
12 <tr class="<%= cycle 'odd', 'even' %>">
13 <td>
13 <td>
14 <%= link_to h(board.name), {:action => 'show', :id => board}, :class => "icon22 icon22-comment" %><br />
14 <%= link_to h(board.name), {:action => 'show', :id => board}, :class => "icon22 icon22-comment" %><br />
15 <%=h board.description %>
15 <%=h board.description %>
16 </td>
16 </td>
17 <td align="center"><%= board.topics_count %></td>
17 <td align="center"><%= board.topics_count %></td>
18 <td align="center"><%= board.messages_count %></td>
18 <td align="center"><%= board.messages_count %></td>
19 <td>
19 <td>
20 <small>
20 <small>
21 <% if board.last_message %>
21 <% if board.last_message %>
22 <%= authoring board.last_message.created_on, board.last_message.author %><br />
22 <%= authoring board.last_message.created_on, board.last_message.author %><br />
23 <%= link_to_message board.last_message %>
23 <%= link_to_message board.last_message %>
24 <% end %>
24 <% end %>
25 </small>
25 </small>
26 </td>
26 </td>
27 </tr>
27 </tr>
28 <% end %>
28 <% end %>
29 </tbody>
29 </tbody>
30 </table>
30 </table>
31
31
32 <p class="other-formats">
32 <% other_formats_links do |f| %>
33 <%= l(:label_export_to) %>
33 <%= f.link_to 'Atom', :url => {:controller => 'projects', :action => 'activity', :id => @project, :show_messages => 1, :key => User.current.rss_key} %>
34 <span><%= link_to 'Atom', {:controller => 'projects', :action => 'activity', :id => @project, :format => 'atom', :show_messages => 1, :key => User.current.rss_key},
34 <% end %>
35 :class => 'feed' %></span>
36 </p>
37
35
38 <% content_for :header_tags do %>
36 <% content_for :header_tags do %>
39 <%= auto_discovery_link_tag(:atom, {:controller => 'projects', :action => 'activity', :id => @project, :format => 'atom', :show_messages => 1, :key => User.current.rss_key}) %>
37 <%= auto_discovery_link_tag(:atom, {:controller => 'projects', :action => 'activity', :id => @project, :format => 'atom', :show_messages => 1, :key => User.current.rss_key}) %>
40 <% end %>
38 <% end %>
41
39
42 <% html_title l(:label_board_plural) %>
40 <% html_title l(:label_board_plural) %>
@@ -1,257 +1,254
1 <% form_tag(params.merge(:month => nil, :year => nil, :months => nil), :id => 'query_form') do %>
1 <% form_tag(params.merge(:month => nil, :year => nil, :months => nil), :id => 'query_form') do %>
2 <% if @query.new_record? %>
2 <% if @query.new_record? %>
3 <h2><%=l(:label_gantt)%></h2>
3 <h2><%=l(:label_gantt)%></h2>
4 <fieldset id="filters"><legend><%= l(:label_filter_plural) %></legend>
4 <fieldset id="filters"><legend><%= l(:label_filter_plural) %></legend>
5 <%= render :partial => 'queries/filters', :locals => {:query => @query} %>
5 <%= render :partial => 'queries/filters', :locals => {:query => @query} %>
6 </fieldset>
6 </fieldset>
7 <% else %>
7 <% else %>
8 <h2><%=h @query.name %></h2>
8 <h2><%=h @query.name %></h2>
9 <% html_title @query.name %>
9 <% html_title @query.name %>
10 <% end %>
10 <% end %>
11
11
12 <fieldset id="date-range"><legend><%= l(:label_date_range) %></legend>
12 <fieldset id="date-range"><legend><%= l(:label_date_range) %></legend>
13 <%= text_field_tag 'months', @gantt.months, :size => 2 %>
13 <%= text_field_tag 'months', @gantt.months, :size => 2 %>
14 <%= l(:label_months_from) %>
14 <%= l(:label_months_from) %>
15 <%= select_month(@gantt.month_from, :prefix => "month", :discard_type => true) %>
15 <%= select_month(@gantt.month_from, :prefix => "month", :discard_type => true) %>
16 <%= select_year(@gantt.year_from, :prefix => "year", :discard_type => true) %>
16 <%= select_year(@gantt.year_from, :prefix => "year", :discard_type => true) %>
17 <%= hidden_field_tag 'zoom', @gantt.zoom %>
17 <%= hidden_field_tag 'zoom', @gantt.zoom %>
18 </fieldset>
18 </fieldset>
19
19
20 <p style="float:right; margin:0px;">
20 <p style="float:right; margin:0px;">
21 <%= if @gantt.zoom < 4
21 <%= if @gantt.zoom < 4
22 link_to_remote image_tag('zoom_in.png'), {:url => @gantt.params.merge(:zoom => (@gantt.zoom+1)), :update => 'content'}, {:href => url_for(@gantt.params.merge(:zoom => (@gantt.zoom+1)))}
22 link_to_remote image_tag('zoom_in.png'), {:url => @gantt.params.merge(:zoom => (@gantt.zoom+1)), :update => 'content'}, {:href => url_for(@gantt.params.merge(:zoom => (@gantt.zoom+1)))}
23 else
23 else
24 image_tag 'zoom_in_g.png'
24 image_tag 'zoom_in_g.png'
25 end %>
25 end %>
26 <%= if @gantt.zoom > 1
26 <%= if @gantt.zoom > 1
27 link_to_remote image_tag('zoom_out.png'), {:url => @gantt.params.merge(:zoom => (@gantt.zoom-1)), :update => 'content'}, {:href => url_for(@gantt.params.merge(:zoom => (@gantt.zoom-1)))}
27 link_to_remote image_tag('zoom_out.png'), {:url => @gantt.params.merge(:zoom => (@gantt.zoom-1)), :update => 'content'}, {:href => url_for(@gantt.params.merge(:zoom => (@gantt.zoom-1)))}
28 else
28 else
29 image_tag 'zoom_out_g.png'
29 image_tag 'zoom_out_g.png'
30 end %>
30 end %>
31 </p>
31 </p>
32
32
33 <p class="buttons">
33 <p class="buttons">
34 <%= link_to_remote l(:button_apply),
34 <%= link_to_remote l(:button_apply),
35 { :url => { :set_filter => (@query.new_record? ? 1 : nil) },
35 { :url => { :set_filter => (@query.new_record? ? 1 : nil) },
36 :update => "content",
36 :update => "content",
37 :with => "Form.serialize('query_form')"
37 :with => "Form.serialize('query_form')"
38 }, :class => 'icon icon-checked' %>
38 }, :class => 'icon icon-checked' %>
39
39
40 <%= link_to_remote l(:button_clear),
40 <%= link_to_remote l(:button_clear),
41 { :url => { :set_filter => (@query.new_record? ? 1 : nil) },
41 { :url => { :set_filter => (@query.new_record? ? 1 : nil) },
42 :update => "content",
42 :update => "content",
43 }, :class => 'icon icon-reload' if @query.new_record? %>
43 }, :class => 'icon icon-reload' if @query.new_record? %>
44 </p>
44 </p>
45 <% end %>
45 <% end %>
46
46
47 <%= error_messages_for 'query' %>
47 <%= error_messages_for 'query' %>
48 <% if @query.valid? %>
48 <% if @query.valid? %>
49 <% zoom = 1
49 <% zoom = 1
50 @gantt.zoom.times { zoom = zoom * 2 }
50 @gantt.zoom.times { zoom = zoom * 2 }
51
51
52 subject_width = 330
52 subject_width = 330
53 header_heigth = 18
53 header_heigth = 18
54
54
55 headers_height = header_heigth
55 headers_height = header_heigth
56 show_weeks = false
56 show_weeks = false
57 show_days = false
57 show_days = false
58
58
59 if @gantt.zoom >1
59 if @gantt.zoom >1
60 show_weeks = true
60 show_weeks = true
61 headers_height = 2*header_heigth
61 headers_height = 2*header_heigth
62 if @gantt.zoom > 2
62 if @gantt.zoom > 2
63 show_days = true
63 show_days = true
64 headers_height = 3*header_heigth
64 headers_height = 3*header_heigth
65 end
65 end
66 end
66 end
67
67
68 g_width = (@gantt.date_to - @gantt.date_from + 1)*zoom
68 g_width = (@gantt.date_to - @gantt.date_from + 1)*zoom
69 g_height = [(20 * @gantt.events.length + 6)+150, 206].max
69 g_height = [(20 * @gantt.events.length + 6)+150, 206].max
70 t_height = g_height + headers_height
70 t_height = g_height + headers_height
71 %>
71 %>
72
72
73 <table width="100%" style="border:0; border-collapse: collapse;">
73 <table width="100%" style="border:0; border-collapse: collapse;">
74 <tr>
74 <tr>
75 <td style="width:<%= subject_width %>px; padding:0px;">
75 <td style="width:<%= subject_width %>px; padding:0px;">
76
76
77 <div style="position:relative;height:<%= t_height + 24 %>px;width:<%= subject_width + 1 %>px;">
77 <div style="position:relative;height:<%= t_height + 24 %>px;width:<%= subject_width + 1 %>px;">
78 <div style="right:-2px;width:<%= subject_width %>px;height:<%= headers_height %>px;background: #eee;" class="gantt_hdr"></div>
78 <div style="right:-2px;width:<%= subject_width %>px;height:<%= headers_height %>px;background: #eee;" class="gantt_hdr"></div>
79 <div style="right:-2px;width:<%= subject_width %>px;height:<%= t_height %>px;border-left: 1px solid #c0c0c0;overflow:hidden;" class="gantt_hdr"></div>
79 <div style="right:-2px;width:<%= subject_width %>px;height:<%= t_height %>px;border-left: 1px solid #c0c0c0;overflow:hidden;" class="gantt_hdr"></div>
80 <%
80 <%
81 #
81 #
82 # Tasks subjects
82 # Tasks subjects
83 #
83 #
84 top = headers_height + 8
84 top = headers_height + 8
85 @gantt.events.each do |i| %>
85 @gantt.events.each do |i| %>
86 <div style="position: absolute;line-height:1.2em;height:16px;top:<%= top %>px;left:4px;overflow:hidden;"><small>
86 <div style="position: absolute;line-height:1.2em;height:16px;top:<%= top %>px;left:4px;overflow:hidden;"><small>
87 <% if i.is_a? Issue %>
87 <% if i.is_a? Issue %>
88 <%= h("#{i.project} -") unless @project && @project == i.project %>
88 <%= h("#{i.project} -") unless @project && @project == i.project %>
89 <%= link_to_issue i %>: <%=h i.subject %>
89 <%= link_to_issue i %>: <%=h i.subject %>
90 <% else %>
90 <% else %>
91 <span class="icon icon-package">
91 <span class="icon icon-package">
92 <%= h("#{i.project} -") unless @project && @project == i.project %>
92 <%= h("#{i.project} -") unless @project && @project == i.project %>
93 <%= link_to_version i %>
93 <%= link_to_version i %>
94 </span>
94 </span>
95 <% end %>
95 <% end %>
96 </small></div>
96 </small></div>
97 <% top = top + 20
97 <% top = top + 20
98 end %>
98 end %>
99 </div>
99 </div>
100 </td>
100 </td>
101 <td>
101 <td>
102
102
103 <div style="position:relative;height:<%= t_height + 24 %>px;overflow:auto;">
103 <div style="position:relative;height:<%= t_height + 24 %>px;overflow:auto;">
104 <div style="width:<%= g_width-1 %>px;height:<%= headers_height %>px;background: #eee;" class="gantt_hdr">&nbsp;</div>
104 <div style="width:<%= g_width-1 %>px;height:<%= headers_height %>px;background: #eee;" class="gantt_hdr">&nbsp;</div>
105 <%
105 <%
106 #
106 #
107 # Months headers
107 # Months headers
108 #
108 #
109 month_f = @gantt.date_from
109 month_f = @gantt.date_from
110 left = 0
110 left = 0
111 height = (show_weeks ? header_heigth : header_heigth + g_height)
111 height = (show_weeks ? header_heigth : header_heigth + g_height)
112 @gantt.months.times do
112 @gantt.months.times do
113 width = ((month_f >> 1) - month_f) * zoom - 1
113 width = ((month_f >> 1) - month_f) * zoom - 1
114 %>
114 %>
115 <div style="left:<%= left %>px;width:<%= width %>px;height:<%= height %>px;" class="gantt_hdr">
115 <div style="left:<%= left %>px;width:<%= width %>px;height:<%= height %>px;" class="gantt_hdr">
116 <%= link_to "#{month_f.year}-#{month_f.month}", @gantt.params.merge(:year => month_f.year, :month => month_f.month), :title => "#{month_name(month_f.month)} #{month_f.year}"%>
116 <%= link_to "#{month_f.year}-#{month_f.month}", @gantt.params.merge(:year => month_f.year, :month => month_f.month), :title => "#{month_name(month_f.month)} #{month_f.year}"%>
117 </div>
117 </div>
118 <%
118 <%
119 left = left + width + 1
119 left = left + width + 1
120 month_f = month_f >> 1
120 month_f = month_f >> 1
121 end %>
121 end %>
122
122
123 <%
123 <%
124 #
124 #
125 # Weeks headers
125 # Weeks headers
126 #
126 #
127 if show_weeks
127 if show_weeks
128 left = 0
128 left = 0
129 height = (show_days ? header_heigth-1 : header_heigth-1 + g_height)
129 height = (show_days ? header_heigth-1 : header_heigth-1 + g_height)
130 if @gantt.date_from.cwday == 1
130 if @gantt.date_from.cwday == 1
131 # @date_from is monday
131 # @date_from is monday
132 week_f = @gantt.date_from
132 week_f = @gantt.date_from
133 else
133 else
134 # find next monday after @date_from
134 # find next monday after @date_from
135 week_f = @gantt.date_from + (7 - @gantt.date_from.cwday + 1)
135 week_f = @gantt.date_from + (7 - @gantt.date_from.cwday + 1)
136 width = (7 - @gantt.date_from.cwday + 1) * zoom-1
136 width = (7 - @gantt.date_from.cwday + 1) * zoom-1
137 %>
137 %>
138 <div style="left:<%= left %>px;top:19px;width:<%= width %>px;height:<%= height %>px;" class="gantt_hdr">&nbsp;</div>
138 <div style="left:<%= left %>px;top:19px;width:<%= width %>px;height:<%= height %>px;" class="gantt_hdr">&nbsp;</div>
139 <%
139 <%
140 left = left + width+1
140 left = left + width+1
141 end %>
141 end %>
142 <%
142 <%
143 while week_f <= @gantt.date_to
143 while week_f <= @gantt.date_to
144 width = (week_f + 6 <= @gantt.date_to) ? 7 * zoom -1 : (@gantt.date_to - week_f + 1) * zoom-1
144 width = (week_f + 6 <= @gantt.date_to) ? 7 * zoom -1 : (@gantt.date_to - week_f + 1) * zoom-1
145 %>
145 %>
146 <div style="left:<%= left %>px;top:19px;width:<%= width %>px;height:<%= height %>px;" class="gantt_hdr">
146 <div style="left:<%= left %>px;top:19px;width:<%= width %>px;height:<%= height %>px;" class="gantt_hdr">
147 <small><%= week_f.cweek if width >= 16 %></small>
147 <small><%= week_f.cweek if width >= 16 %></small>
148 </div>
148 </div>
149 <%
149 <%
150 left = left + width+1
150 left = left + width+1
151 week_f = week_f+7
151 week_f = week_f+7
152 end
152 end
153 end %>
153 end %>
154
154
155 <%
155 <%
156 #
156 #
157 # Days headers
157 # Days headers
158 #
158 #
159 if show_days
159 if show_days
160 left = 0
160 left = 0
161 height = g_height + header_heigth - 1
161 height = g_height + header_heigth - 1
162 wday = @gantt.date_from.cwday
162 wday = @gantt.date_from.cwday
163 (@gantt.date_to - @gantt.date_from + 1).to_i.times do
163 (@gantt.date_to - @gantt.date_from + 1).to_i.times do
164 width = zoom - 1
164 width = zoom - 1
165 %>
165 %>
166 <div style="left:<%= left %>px;top:37px;width:<%= width %>px;height:<%= height %>px;font-size:0.7em;<%= "background:#f1f1f1;" if wday > 5 %>" class="gantt_hdr">
166 <div style="left:<%= left %>px;top:37px;width:<%= width %>px;height:<%= height %>px;font-size:0.7em;<%= "background:#f1f1f1;" if wday > 5 %>" class="gantt_hdr">
167 <%= day_name(wday).first %>
167 <%= day_name(wday).first %>
168 </div>
168 </div>
169 <%
169 <%
170 left = left + width+1
170 left = left + width+1
171 wday = wday + 1
171 wday = wday + 1
172 wday = 1 if wday > 7
172 wday = 1 if wday > 7
173 end
173 end
174 end %>
174 end %>
175
175
176 <%
176 <%
177 #
177 #
178 # Tasks
178 # Tasks
179 #
179 #
180 top = headers_height + 10
180 top = headers_height + 10
181 @gantt.events.each do |i|
181 @gantt.events.each do |i|
182 if i.is_a? Issue
182 if i.is_a? Issue
183 i_start_date = (i.start_date >= @gantt.date_from ? i.start_date : @gantt.date_from )
183 i_start_date = (i.start_date >= @gantt.date_from ? i.start_date : @gantt.date_from )
184 i_end_date = (i.due_before <= @gantt.date_to ? i.due_before : @gantt.date_to )
184 i_end_date = (i.due_before <= @gantt.date_to ? i.due_before : @gantt.date_to )
185
185
186 i_done_date = i.start_date + ((i.due_before - i.start_date+1)*i.done_ratio/100).floor
186 i_done_date = i.start_date + ((i.due_before - i.start_date+1)*i.done_ratio/100).floor
187 i_done_date = (i_done_date <= @gantt.date_from ? @gantt.date_from : i_done_date )
187 i_done_date = (i_done_date <= @gantt.date_from ? @gantt.date_from : i_done_date )
188 i_done_date = (i_done_date >= @gantt.date_to ? @gantt.date_to : i_done_date )
188 i_done_date = (i_done_date >= @gantt.date_to ? @gantt.date_to : i_done_date )
189
189
190 i_late_date = [i_end_date, Date.today].min if i_start_date < Date.today
190 i_late_date = [i_end_date, Date.today].min if i_start_date < Date.today
191
191
192 i_left = ((i_start_date - @gantt.date_from)*zoom).floor
192 i_left = ((i_start_date - @gantt.date_from)*zoom).floor
193 i_width = ((i_end_date - i_start_date + 1)*zoom).floor - 2 # total width of the issue (- 2 for left and right borders)
193 i_width = ((i_end_date - i_start_date + 1)*zoom).floor - 2 # total width of the issue (- 2 for left and right borders)
194 d_width = ((i_done_date - i_start_date)*zoom).floor - 2 # done width
194 d_width = ((i_done_date - i_start_date)*zoom).floor - 2 # done width
195 l_width = i_late_date ? ((i_late_date - i_start_date+1)*zoom).floor - 2 : 0 # delay width
195 l_width = i_late_date ? ((i_late_date - i_start_date+1)*zoom).floor - 2 : 0 # delay width
196 %>
196 %>
197 <div style="top:<%= top %>px;left:<%= i_left %>px;width:<%= i_width %>px;" class="task task_todo">&nbsp;</div>
197 <div style="top:<%= top %>px;left:<%= i_left %>px;width:<%= i_width %>px;" class="task task_todo">&nbsp;</div>
198 <% if l_width > 0 %>
198 <% if l_width > 0 %>
199 <div style="top:<%= top %>px;left:<%= i_left %>px;width:<%= l_width %>px;" class="task task_late">&nbsp;</div>
199 <div style="top:<%= top %>px;left:<%= i_left %>px;width:<%= l_width %>px;" class="task task_late">&nbsp;</div>
200 <% end %>
200 <% end %>
201 <% if d_width > 0 %>
201 <% if d_width > 0 %>
202 <div style="top:<%= top %>px;left:<%= i_left %>px;width:<%= d_width %>px;" class="task task_done">&nbsp;</div>
202 <div style="top:<%= top %>px;left:<%= i_left %>px;width:<%= d_width %>px;" class="task task_done">&nbsp;</div>
203 <% end %>
203 <% end %>
204 <div style="top:<%= top %>px;left:<%= i_left + i_width + 5 %>px;background:#fff;" class="task">
204 <div style="top:<%= top %>px;left:<%= i_left + i_width + 5 %>px;background:#fff;" class="task">
205 <%= i.status.name %>
205 <%= i.status.name %>
206 <%= (i.done_ratio).to_i %>%
206 <%= (i.done_ratio).to_i %>%
207 </div>
207 </div>
208 <div class="tooltip" style="position: absolute;top:<%= top %>px;left:<%= i_left %>px;width:<%= i_width %>px;height:12px;">
208 <div class="tooltip" style="position: absolute;top:<%= top %>px;left:<%= i_left %>px;width:<%= i_width %>px;height:12px;">
209 <span class="tip">
209 <span class="tip">
210 <%= render_issue_tooltip i %>
210 <%= render_issue_tooltip i %>
211 </span></div>
211 </span></div>
212 <% else
212 <% else
213 i_left = ((i.start_date - @gantt.date_from)*zoom).floor
213 i_left = ((i.start_date - @gantt.date_from)*zoom).floor
214 %>
214 %>
215 <div style="top:<%= top %>px;left:<%= i_left %>px;width:15px;" class="task milestone">&nbsp;</div>
215 <div style="top:<%= top %>px;left:<%= i_left %>px;width:15px;" class="task milestone">&nbsp;</div>
216 <div style="top:<%= top %>px;left:<%= i_left + 12 %>px;background:#fff;" class="task">
216 <div style="top:<%= top %>px;left:<%= i_left + 12 %>px;background:#fff;" class="task">
217 <%= h("#{i.project} -") unless @project && @project == i.project %>
217 <%= h("#{i.project} -") unless @project && @project == i.project %>
218 <strong><%=h i %></strong>
218 <strong><%=h i %></strong>
219 </div>
219 </div>
220 <% end %>
220 <% end %>
221 <% top = top + 20
221 <% top = top + 20
222 end %>
222 end %>
223
223
224 <%
224 <%
225 #
225 #
226 # Today red line (excluded from cache)
226 # Today red line (excluded from cache)
227 #
227 #
228 if Date.today >= @gantt.date_from and Date.today <= @gantt.date_to %>
228 if Date.today >= @gantt.date_from and Date.today <= @gantt.date_to %>
229 <div style="position: absolute;height:<%= g_height %>px;top:<%= headers_height + 1 %>px;left:<%= ((Date.today-@gantt.date_from+1)*zoom).floor()-1 %>px;width:10px;border-left: 1px dashed red;">&nbsp;</div>
229 <div style="position: absolute;height:<%= g_height %>px;top:<%= headers_height + 1 %>px;left:<%= ((Date.today-@gantt.date_from+1)*zoom).floor()-1 %>px;width:10px;border-left: 1px dashed red;">&nbsp;</div>
230 <% end %>
230 <% end %>
231
231
232 </div>
232 </div>
233 </td>
233 </td>
234 </tr>
234 </tr>
235 </table>
235 </table>
236
236
237 <table width="100%">
237 <table width="100%">
238 <tr>
238 <tr>
239 <td align="left"><%= link_to_remote ('&#171; ' + l(:label_previous)), {:url => @gantt.params_previous, :update => 'content', :complete => 'window.scrollTo(0,0)'}, {:href => url_for(@gantt.params_previous)} %></td>
239 <td align="left"><%= link_to_remote ('&#171; ' + l(:label_previous)), {:url => @gantt.params_previous, :update => 'content', :complete => 'window.scrollTo(0,0)'}, {:href => url_for(@gantt.params_previous)} %></td>
240 <td align="right"><%= link_to_remote (l(:label_next) + ' &#187;'), {:url => @gantt.params_next, :update => 'content', :complete => 'window.scrollTo(0,0)'}, {:href => url_for(@gantt.params_next)} %></td>
240 <td align="right"><%= link_to_remote (l(:label_next) + ' &#187;'), {:url => @gantt.params_next, :update => 'content', :complete => 'window.scrollTo(0,0)'}, {:href => url_for(@gantt.params_next)} %></td>
241 </tr>
241 </tr>
242 </table>
242 </table>
243
243
244 <p class="other-formats">
244 <% other_formats_links do |f| %>
245 <%= l(:label_export_to) %>
245 <%= f.link_to 'PDF', :url => @gantt.params %>
246 <span><%= link_to 'PDF', @gantt.params.merge(:format => 'pdf'), :class => 'pdf' %></span>
246 <%= f.link_to('PNG', :url => @gantt.params) if @gantt.respond_to?('to_image') %>
247 <% if @gantt.respond_to?('to_image') %>
248 <span><%= link_to 'PNG', @gantt.params.merge(:format => 'png'), :class => 'image' %></span>
249 <% end %>
247 <% end %>
250 </p>
251 <% end # query.valid? %>
248 <% end # query.valid? %>
252
249
253 <% content_for :sidebar do %>
250 <% content_for :sidebar do %>
254 <%= render :partial => 'issues/sidebar' %>
251 <%= render :partial => 'issues/sidebar' %>
255 <% end %>
252 <% end %>
256
253
257 <% html_title(l(:label_gantt)) -%>
254 <% html_title(l(:label_gantt)) -%>
@@ -1,68 +1,68
1 <% if @query.new_record? %>
1 <% if @query.new_record? %>
2 <h2><%=l(:label_issue_plural)%></h2>
2 <h2><%=l(:label_issue_plural)%></h2>
3 <% html_title(l(:label_issue_plural)) %>
3 <% html_title(l(:label_issue_plural)) %>
4
4
5 <% form_tag({ :controller => 'queries', :action => 'new' }, :id => 'query_form') do %>
5 <% form_tag({ :controller => 'queries', :action => 'new' }, :id => 'query_form') do %>
6 <%= hidden_field_tag('project_id', @project.id) if @project %>
6 <%= hidden_field_tag('project_id', @project.id) if @project %>
7 <fieldset id="filters"><legend><%= l(:label_filter_plural) %></legend>
7 <fieldset id="filters"><legend><%= l(:label_filter_plural) %></legend>
8 <%= render :partial => 'queries/filters', :locals => {:query => @query} %>
8 <%= render :partial => 'queries/filters', :locals => {:query => @query} %>
9 <p class="buttons">
9 <p class="buttons">
10 <%= link_to_remote l(:button_apply),
10 <%= link_to_remote l(:button_apply),
11 { :url => { :set_filter => 1 },
11 { :url => { :set_filter => 1 },
12 :update => "content",
12 :update => "content",
13 :with => "Form.serialize('query_form')"
13 :with => "Form.serialize('query_form')"
14 }, :class => 'icon icon-checked' %>
14 }, :class => 'icon icon-checked' %>
15
15
16 <%= link_to_remote l(:button_clear),
16 <%= link_to_remote l(:button_clear),
17 { :url => { :set_filter => 1, :project_id => (@project.nil? ? nil : @project.id) },
17 { :url => { :set_filter => 1, :project_id => (@project.nil? ? nil : @project.id) },
18 :method => :get,
18 :method => :get,
19 :update => "content",
19 :update => "content",
20 }, :class => 'icon icon-reload' %>
20 }, :class => 'icon icon-reload' %>
21
21
22 <% if User.current.allowed_to?(:save_queries, @project, :global => true) %>
22 <% if User.current.allowed_to?(:save_queries, @project, :global => true) %>
23 <%= link_to l(:button_save), {}, :onclick => "$('query_form').submit(); return false;", :class => 'icon icon-save' %>
23 <%= link_to l(:button_save), {}, :onclick => "$('query_form').submit(); return false;", :class => 'icon icon-save' %>
24 <% end %>
24 <% end %>
25 </p>
25 </p>
26 </fieldset>
26 </fieldset>
27 <% end %>
27 <% end %>
28 <% else %>
28 <% else %>
29 <div class="contextual">
29 <div class="contextual">
30 <% if @query.editable_by?(User.current) %>
30 <% if @query.editable_by?(User.current) %>
31 <%= link_to l(:button_edit), {:controller => 'queries', :action => 'edit', :id => @query}, :class => 'icon icon-edit' %>
31 <%= link_to l(:button_edit), {:controller => 'queries', :action => 'edit', :id => @query}, :class => 'icon icon-edit' %>
32 <%= link_to l(:button_delete), {:controller => 'queries', :action => 'destroy', :id => @query}, :confirm => l(:text_are_you_sure), :method => :post, :class => 'icon icon-del' %>
32 <%= link_to l(:button_delete), {:controller => 'queries', :action => 'destroy', :id => @query}, :confirm => l(:text_are_you_sure), :method => :post, :class => 'icon icon-del' %>
33 <% end %>
33 <% end %>
34 </div>
34 </div>
35 <h2><%=h @query.name %></h2>
35 <h2><%=h @query.name %></h2>
36 <div id="query_form"></div>
36 <div id="query_form"></div>
37 <% html_title @query.name %>
37 <% html_title @query.name %>
38 <% end %>
38 <% end %>
39 <%= error_messages_for 'query' %>
39 <%= error_messages_for 'query' %>
40 <% if @query.valid? %>
40 <% if @query.valid? %>
41 <% if @issues.empty? %>
41 <% if @issues.empty? %>
42 <p class="nodata"><%= l(:label_no_data) %></p>
42 <p class="nodata"><%= l(:label_no_data) %></p>
43 <% else %>
43 <% else %>
44 <%= render :partial => 'issues/list', :locals => {:issues => @issues, :query => @query} %>
44 <%= render :partial => 'issues/list', :locals => {:issues => @issues, :query => @query} %>
45 <p class="pagination"><%= pagination_links_full @issue_pages, @issue_count %></p>
45 <p class="pagination"><%= pagination_links_full @issue_pages, @issue_count %></p>
46
46
47 <p class="other-formats">
47 <% other_formats_links do |f| %>
48 <%= l(:label_export_to) %>
48 <%= f.link_to 'Atom', :url => {:query_id => (@query.new_record? ? nil : @query), :key => User.current.rss_key} %>
49 <span><%= link_to 'Atom', {:query_id => @query, :format => 'atom', :key => User.current.rss_key}, :class => 'feed' %></span>
49 <%= f.link_to 'CSV' %>
50 <span><%= link_to 'CSV', {:format => 'csv'}, :class => 'csv' %></span>
50 <%= f.link_to 'PDF' %>
51 <span><%= link_to 'PDF', {:format => 'pdf'}, :class => 'pdf' %></span>
51 <% end %>
52 </p>
52
53 <% end %>
53 <% end %>
54 <% end %>
54 <% end %>
55
55
56 <% content_for :sidebar do %>
56 <% content_for :sidebar do %>
57 <%= render :partial => 'issues/sidebar' %>
57 <%= render :partial => 'issues/sidebar' %>
58 <% end %>
58 <% end %>
59
59
60 <% content_for :header_tags do %>
60 <% content_for :header_tags do %>
61 <%= auto_discovery_link_tag(:atom, {:query_id => @query, :format => 'atom', :page => nil, :key => User.current.rss_key}, :title => l(:label_issue_plural)) %>
61 <%= auto_discovery_link_tag(:atom, {:query_id => @query, :format => 'atom', :page => nil, :key => User.current.rss_key}, :title => l(:label_issue_plural)) %>
62 <%= auto_discovery_link_tag(:atom, {:action => 'changes', :query_id => @query, :format => 'atom', :page => nil, :key => User.current.rss_key}, :title => l(:label_changes_details)) %>
62 <%= auto_discovery_link_tag(:atom, {:action => 'changes', :query_id => @query, :format => 'atom', :page => nil, :key => User.current.rss_key}, :title => l(:label_changes_details)) %>
63 <%= javascript_include_tag 'context_menu' %>
63 <%= javascript_include_tag 'context_menu' %>
64 <%= stylesheet_link_tag 'context_menu' %>
64 <%= stylesheet_link_tag 'context_menu' %>
65 <% end %>
65 <% end %>
66
66
67 <div id="context-menu" style="display: none;"></div>
67 <div id="context-menu" style="display: none;"></div>
68 <%= javascript_tag "new ContextMenu('#{url_for(:controller => 'issues', :action => 'context_menu')}')" %>
68 <%= javascript_tag "new ContextMenu('#{url_for(:controller => 'issues', :action => 'context_menu')}')" %>
@@ -1,126 +1,125
1 <div class="contextual">
1 <div class="contextual">
2 <%= link_to_if_authorized(l(:button_update), {:controller => 'issues', :action => 'edit', :id => @issue }, :onclick => 'showAndScrollTo("update", "notes"); return false;', :class => 'icon icon-edit', :accesskey => accesskey(:edit)) %>
2 <%= link_to_if_authorized(l(:button_update), {:controller => 'issues', :action => 'edit', :id => @issue }, :onclick => 'showAndScrollTo("update", "notes"); return false;', :class => 'icon icon-edit', :accesskey => accesskey(:edit)) %>
3 <%= link_to_if_authorized l(:button_log_time), {:controller => 'timelog', :action => 'edit', :issue_id => @issue}, :class => 'icon icon-time' %>
3 <%= link_to_if_authorized l(:button_log_time), {:controller => 'timelog', :action => 'edit', :issue_id => @issue}, :class => 'icon icon-time' %>
4 <%= watcher_tag(@issue, User.current) %>
4 <%= watcher_tag(@issue, User.current) %>
5 <%= link_to_if_authorized l(:button_copy), {:controller => 'issues', :action => 'new', :project_id => @project, :copy_from => @issue }, :class => 'icon icon-copy' %>
5 <%= link_to_if_authorized l(:button_copy), {:controller => 'issues', :action => 'new', :project_id => @project, :copy_from => @issue }, :class => 'icon icon-copy' %>
6 <%= link_to_if_authorized l(:button_move), {:controller => 'issues', :action => 'move', :id => @issue }, :class => 'icon icon-move' %>
6 <%= link_to_if_authorized l(:button_move), {:controller => 'issues', :action => 'move', :id => @issue }, :class => 'icon icon-move' %>
7 <%= link_to_if_authorized l(:button_delete), {:controller => 'issues', :action => 'destroy', :id => @issue}, :confirm => l(:text_are_you_sure), :method => :post, :class => 'icon icon-del' %>
7 <%= link_to_if_authorized l(:button_delete), {:controller => 'issues', :action => 'destroy', :id => @issue}, :confirm => l(:text_are_you_sure), :method => :post, :class => 'icon icon-del' %>
8 </div>
8 </div>
9
9
10 <h2><%= @issue.tracker.name %> #<%= @issue.id %></h2>
10 <h2><%= @issue.tracker.name %> #<%= @issue.id %></h2>
11
11
12 <div class="<%= css_issue_classes(@issue) %>">
12 <div class="<%= css_issue_classes(@issue) %>">
13 <%= avatar(@issue.author, :size => "64") %>
13 <%= avatar(@issue.author, :size => "64") %>
14 <h3><%=h @issue.subject %></h3>
14 <h3><%=h @issue.subject %></h3>
15 <p class="author">
15 <p class="author">
16 <%= authoring @issue.created_on, @issue.author %>.
16 <%= authoring @issue.created_on, @issue.author %>.
17 <%= l(:label_updated_time, distance_of_time_in_words(Time.now, @issue.updated_on)) + '.' if @issue.created_on != @issue.updated_on %>
17 <%= l(:label_updated_time, distance_of_time_in_words(Time.now, @issue.updated_on)) + '.' if @issue.created_on != @issue.updated_on %>
18 </p>
18 </p>
19
19
20 <table width="100%">
20 <table width="100%">
21 <tr>
21 <tr>
22 <td style="width:15%" class="status"><b><%=l(:field_status)%>:</b></td><td style="width:35%" class="status status-<%= @issue.status.name %>"><%= @issue.status.name %></td>
22 <td style="width:15%" class="status"><b><%=l(:field_status)%>:</b></td><td style="width:35%" class="status status-<%= @issue.status.name %>"><%= @issue.status.name %></td>
23 <td style="width:15%" class="start-date"><b><%=l(:field_start_date)%>:</b></td><td style="width:35%"><%= format_date(@issue.start_date) %></td>
23 <td style="width:15%" class="start-date"><b><%=l(:field_start_date)%>:</b></td><td style="width:35%"><%= format_date(@issue.start_date) %></td>
24 </tr>
24 </tr>
25 <tr>
25 <tr>
26 <td class="priority"><b><%=l(:field_priority)%>:</b></td><td class="priority priority-<%= @issue.priority.name %>"><%= @issue.priority.name %></td>
26 <td class="priority"><b><%=l(:field_priority)%>:</b></td><td class="priority priority-<%= @issue.priority.name %>"><%= @issue.priority.name %></td>
27 <td class="due-date"><b><%=l(:field_due_date)%>:</b></td><td class="due-date"><%= format_date(@issue.due_date) %></td>
27 <td class="due-date"><b><%=l(:field_due_date)%>:</b></td><td class="due-date"><%= format_date(@issue.due_date) %></td>
28 </tr>
28 </tr>
29 <tr>
29 <tr>
30 <td class="assigned-to"><b><%=l(:field_assigned_to)%>:</b></td><td><%= avatar(@issue.assigned_to, :size => "14") %><%= @issue.assigned_to ? link_to_user(@issue.assigned_to) : "-" %></td>
30 <td class="assigned-to"><b><%=l(:field_assigned_to)%>:</b></td><td><%= avatar(@issue.assigned_to, :size => "14") %><%= @issue.assigned_to ? link_to_user(@issue.assigned_to) : "-" %></td>
31 <td class="progress"><b><%=l(:field_done_ratio)%>:</b></td><td class="progress"><%= progress_bar @issue.done_ratio, :width => '80px', :legend => "#{@issue.done_ratio}%" %></td>
31 <td class="progress"><b><%=l(:field_done_ratio)%>:</b></td><td class="progress"><%= progress_bar @issue.done_ratio, :width => '80px', :legend => "#{@issue.done_ratio}%" %></td>
32 </tr>
32 </tr>
33 <tr>
33 <tr>
34 <td class="category"><b><%=l(:field_category)%>:</b></td><td><%=h @issue.category ? @issue.category.name : "-" %></td>
34 <td class="category"><b><%=l(:field_category)%>:</b></td><td><%=h @issue.category ? @issue.category.name : "-" %></td>
35 <% if User.current.allowed_to?(:view_time_entries, @project) %>
35 <% if User.current.allowed_to?(:view_time_entries, @project) %>
36 <td class="spent-time"><b><%=l(:label_spent_time)%>:</b></td>
36 <td class="spent-time"><b><%=l(:label_spent_time)%>:</b></td>
37 <td class="spent-hours"><%= @issue.spent_hours > 0 ? (link_to lwr(:label_f_hour, @issue.spent_hours), {:controller => 'timelog', :action => 'details', :project_id => @project, :issue_id => @issue}, :class => 'icon icon-time') : "-" %></td>
37 <td class="spent-hours"><%= @issue.spent_hours > 0 ? (link_to lwr(:label_f_hour, @issue.spent_hours), {:controller => 'timelog', :action => 'details', :project_id => @project, :issue_id => @issue}, :class => 'icon icon-time') : "-" %></td>
38 <% end %>
38 <% end %>
39 </tr>
39 </tr>
40 <tr>
40 <tr>
41 <td class="fixed-version"><b><%=l(:field_fixed_version)%>:</b></td><td><%= @issue.fixed_version ? link_to_version(@issue.fixed_version) : "-" %></td>
41 <td class="fixed-version"><b><%=l(:field_fixed_version)%>:</b></td><td><%= @issue.fixed_version ? link_to_version(@issue.fixed_version) : "-" %></td>
42 <% if @issue.estimated_hours %>
42 <% if @issue.estimated_hours %>
43 <td class="estimated-hours"><b><%=l(:field_estimated_hours)%>:</b></td><td><%= lwr(:label_f_hour, @issue.estimated_hours) %></td>
43 <td class="estimated-hours"><b><%=l(:field_estimated_hours)%>:</b></td><td><%= lwr(:label_f_hour, @issue.estimated_hours) %></td>
44 <% end %>
44 <% end %>
45 </tr>
45 </tr>
46 <tr>
46 <tr>
47 <% n = 0 -%>
47 <% n = 0 -%>
48 <% @issue.custom_values.each do |value| -%>
48 <% @issue.custom_values.each do |value| -%>
49 <td valign="top"><b><%=h value.custom_field.name %>:</b></td><td valign="top"><%= simple_format(h(show_value(value))) %></td>
49 <td valign="top"><b><%=h value.custom_field.name %>:</b></td><td valign="top"><%= simple_format(h(show_value(value))) %></td>
50 <% n = n + 1
50 <% n = n + 1
51 if (n > 1)
51 if (n > 1)
52 n = 0 %>
52 n = 0 %>
53 </tr><tr>
53 </tr><tr>
54 <%end
54 <%end
55 end %>
55 end %>
56 </tr>
56 </tr>
57 <%= call_hook(:view_issues_show_details_bottom, :issue => @issue) %>
57 <%= call_hook(:view_issues_show_details_bottom, :issue => @issue) %>
58 </table>
58 </table>
59 <hr />
59 <hr />
60
60
61 <div class="contextual">
61 <div class="contextual">
62 <%= link_to_remote_if_authorized(l(:button_quote), { :url => {:action => 'reply', :id => @issue} }, :class => 'icon icon-comment') unless @issue.description.blank? %>
62 <%= link_to_remote_if_authorized(l(:button_quote), { :url => {:action => 'reply', :id => @issue} }, :class => 'icon icon-comment') unless @issue.description.blank? %>
63 </div>
63 </div>
64
64
65 <p><strong><%=l(:field_description)%></strong></p>
65 <p><strong><%=l(:field_description)%></strong></p>
66 <div class="wiki">
66 <div class="wiki">
67 <%= textilizable @issue, :description, :attachments => @issue.attachments %>
67 <%= textilizable @issue, :description, :attachments => @issue.attachments %>
68 </div>
68 </div>
69
69
70 <%= link_to_attachments @issue %>
70 <%= link_to_attachments @issue %>
71
71
72 <% if authorize_for('issue_relations', 'new') || @issue.relations.any? %>
72 <% if authorize_for('issue_relations', 'new') || @issue.relations.any? %>
73 <hr />
73 <hr />
74 <div id="relations">
74 <div id="relations">
75 <%= render :partial => 'relations' %>
75 <%= render :partial => 'relations' %>
76 </div>
76 </div>
77 <% end %>
77 <% end %>
78
78
79 <% if User.current.allowed_to?(:add_issue_watchers, @project) ||
79 <% if User.current.allowed_to?(:add_issue_watchers, @project) ||
80 (@issue.watchers.any? && User.current.allowed_to?(:view_issue_watchers, @project)) %>
80 (@issue.watchers.any? && User.current.allowed_to?(:view_issue_watchers, @project)) %>
81 <hr />
81 <hr />
82 <div id="watchers">
82 <div id="watchers">
83 <%= render :partial => 'watchers/watchers', :locals => {:watched => @issue} %>
83 <%= render :partial => 'watchers/watchers', :locals => {:watched => @issue} %>
84 </div>
84 </div>
85 <% end %>
85 <% end %>
86
86
87 </div>
87 </div>
88
88
89 <% if @issue.changesets.any? && User.current.allowed_to?(:view_changesets, @project) %>
89 <% if @issue.changesets.any? && User.current.allowed_to?(:view_changesets, @project) %>
90 <div id="issue-changesets">
90 <div id="issue-changesets">
91 <h3><%=l(:label_associated_revisions)%></h3>
91 <h3><%=l(:label_associated_revisions)%></h3>
92 <%= render :partial => 'changesets', :locals => { :changesets => @issue.changesets} %>
92 <%= render :partial => 'changesets', :locals => { :changesets => @issue.changesets} %>
93 </div>
93 </div>
94 <% end %>
94 <% end %>
95
95
96 <% if @journals.any? %>
96 <% if @journals.any? %>
97 <div id="history">
97 <div id="history">
98 <h3><%=l(:label_history)%></h3>
98 <h3><%=l(:label_history)%></h3>
99 <%= render :partial => 'history', :locals => { :journals => @journals } %>
99 <%= render :partial => 'history', :locals => { :journals => @journals } %>
100 </div>
100 </div>
101 <% end %>
101 <% end %>
102 <div style="clear: both;"></div>
102 <div style="clear: both;"></div>
103
103
104 <% if authorize_for('issues', 'edit') %>
104 <% if authorize_for('issues', 'edit') %>
105 <div id="update" style="display:none;">
105 <div id="update" style="display:none;">
106 <h3><%= l(:button_update) %></h3>
106 <h3><%= l(:button_update) %></h3>
107 <%= render :partial => 'edit' %>
107 <%= render :partial => 'edit' %>
108 </div>
108 </div>
109 <% end %>
109 <% end %>
110
110
111 <p class="other-formats">
111 <% other_formats_links do |f| %>
112 <%= l(:label_export_to) %>
112 <%= f.link_to 'Atom', :url => {:key => User.current.rss_key} %>
113 <span><%= link_to 'Atom', {:format => 'atom', :key => User.current.rss_key}, :class => 'feed' %></span>
113 <%= f.link_to 'PDF' %>
114 <span><%= link_to 'PDF', {:format => 'pdf'}, :class => 'pdf' %></span>
114 <% end %>
115 </p>
116
115
117 <% html_title "#{@issue.tracker.name} ##{@issue.id}: #{@issue.subject}" %>
116 <% html_title "#{@issue.tracker.name} ##{@issue.id}: #{@issue.subject}" %>
118
117
119 <% content_for :sidebar do %>
118 <% content_for :sidebar do %>
120 <%= render :partial => 'issues/sidebar' %>
119 <%= render :partial => 'issues/sidebar' %>
121 <% end %>
120 <% end %>
122
121
123 <% content_for :header_tags do %>
122 <% content_for :header_tags do %>
124 <%= auto_discovery_link_tag(:atom, {:format => 'atom', :key => User.current.rss_key}, :title => "#{@issue.project} - #{@issue.tracker} ##{@issue.id}: #{@issue.subject}") %>
123 <%= auto_discovery_link_tag(:atom, {:format => 'atom', :key => User.current.rss_key}, :title => "#{@issue.project} - #{@issue.tracker} ##{@issue.id}: #{@issue.subject}") %>
125 <%= stylesheet_link_tag 'scm' %>
124 <%= stylesheet_link_tag 'scm' %>
126 <% end %>
125 <% end %>
@@ -1,51 +1,50
1 <div class="contextual">
1 <div class="contextual">
2 <%= link_to_if_authorized(l(:label_news_new),
2 <%= link_to_if_authorized(l(:label_news_new),
3 {:controller => 'news', :action => 'new', :project_id => @project},
3 {:controller => 'news', :action => 'new', :project_id => @project},
4 :class => 'icon icon-add',
4 :class => 'icon icon-add',
5 :onclick => 'Element.show("add-news"); Form.Element.focus("news_title"); return false;') if @project %>
5 :onclick => 'Element.show("add-news"); Form.Element.focus("news_title"); return false;') if @project %>
6 </div>
6 </div>
7
7
8 <div id="add-news" style="display:none;">
8 <div id="add-news" style="display:none;">
9 <h2><%=l(:label_news_new)%></h2>
9 <h2><%=l(:label_news_new)%></h2>
10 <% labelled_tabular_form_for :news, @news, :url => { :controller => 'news', :action => 'new', :project_id => @project },
10 <% labelled_tabular_form_for :news, @news, :url => { :controller => 'news', :action => 'new', :project_id => @project },
11 :html => { :id => 'news-form' } do |f| %>
11 :html => { :id => 'news-form' } do |f| %>
12 <%= render :partial => 'news/form', :locals => { :f => f } %>
12 <%= render :partial => 'news/form', :locals => { :f => f } %>
13 <%= submit_tag l(:button_create) %>
13 <%= submit_tag l(:button_create) %>
14 <%= link_to_remote l(:label_preview),
14 <%= link_to_remote l(:label_preview),
15 { :url => { :controller => 'news', :action => 'preview', :project_id => @project },
15 { :url => { :controller => 'news', :action => 'preview', :project_id => @project },
16 :method => 'post',
16 :method => 'post',
17 :update => 'preview',
17 :update => 'preview',
18 :with => "Form.serialize('news-form')"
18 :with => "Form.serialize('news-form')"
19 }, :accesskey => accesskey(:preview) %> |
19 }, :accesskey => accesskey(:preview) %> |
20 <%= link_to l(:button_cancel), "#", :onclick => 'Element.hide("add-news")' %>
20 <%= link_to l(:button_cancel), "#", :onclick => 'Element.hide("add-news")' %>
21 <% end if @project %>
21 <% end if @project %>
22 <div id="preview" class="wiki"></div>
22 <div id="preview" class="wiki"></div>
23 </div>
23 </div>
24
24
25 <h2><%=l(:label_news_plural)%></h2>
25 <h2><%=l(:label_news_plural)%></h2>
26
26
27 <% if @newss.empty? %>
27 <% if @newss.empty? %>
28 <p class="nodata"><%= l(:label_no_data) %></p>
28 <p class="nodata"><%= l(:label_no_data) %></p>
29 <% else %>
29 <% else %>
30 <% @newss.each do |news| %>
30 <% @newss.each do |news| %>
31 <h3><%= link_to(h(news.project.name), :controller => 'projects', :action => 'show', :id => news.project) + ': ' unless news.project == @project %>
31 <h3><%= link_to(h(news.project.name), :controller => 'projects', :action => 'show', :id => news.project) + ': ' unless news.project == @project %>
32 <%= link_to h(news.title), :controller => 'news', :action => 'show', :id => news %>
32 <%= link_to h(news.title), :controller => 'news', :action => 'show', :id => news %>
33 <%= "(#{news.comments_count} #{lwr(:label_comment, news.comments_count).downcase})" if news.comments_count > 0 %></h3>
33 <%= "(#{news.comments_count} #{lwr(:label_comment, news.comments_count).downcase})" if news.comments_count > 0 %></h3>
34 <p class="author"><%= authoring news.created_on, news.author %></p>
34 <p class="author"><%= authoring news.created_on, news.author %></p>
35 <div class="wiki">
35 <div class="wiki">
36 <%= textilizable(news.description) %>
36 <%= textilizable(news.description) %>
37 </div>
37 </div>
38 <% end %>
38 <% end %>
39 <% end %>
39 <% end %>
40 <p class="pagination"><%= pagination_links_full @news_pages %></p>
40 <p class="pagination"><%= pagination_links_full @news_pages %></p>
41
41
42 <p class="other-formats">
42 <% other_formats_links do |f| %>
43 <%= l(:label_export_to) %>
43 <%= f.link_to 'Atom', :url => {:project_id => @project, :key => User.current.rss_key} %>
44 <span><%= link_to 'Atom', {:project_id => @project, :format => 'atom', :key => User.current.rss_key}, :class => 'feed' %></span>
44 <% end %>
45 </p>
46
45
47 <% content_for :header_tags do %>
46 <% content_for :header_tags do %>
48 <%= auto_discovery_link_tag(:atom, params.merge({:format => 'atom', :page => nil, :key => User.current.rss_key})) %>
47 <%= auto_discovery_link_tag(:atom, params.merge({:format => 'atom', :page => nil, :key => User.current.rss_key})) %>
49 <% end %>
48 <% end %>
50
49
51 <% html_title(l(:label_news_plural)) -%>
50 <% html_title(l(:label_news_plural)) -%>
@@ -1,60 +1,59
1 <h2><%= @author.nil? ? l(:label_activity) : l(:label_user_activity, link_to_user(@author)) %></h2>
1 <h2><%= @author.nil? ? l(:label_activity) : l(:label_user_activity, link_to_user(@author)) %></h2>
2 <p class="subtitle"><%= "#{l(:label_date_from)} #{format_date(@date_to - @days)} #{l(:label_date_to).downcase} #{format_date(@date_to-1)}" %></p>
2 <p class="subtitle"><%= "#{l(:label_date_from)} #{format_date(@date_to - @days)} #{l(:label_date_to).downcase} #{format_date(@date_to-1)}" %></p>
3
3
4 <div id="activity">
4 <div id="activity">
5 <% @events_by_day.keys.sort.reverse.each do |day| %>
5 <% @events_by_day.keys.sort.reverse.each do |day| %>
6 <h3><%= format_activity_day(day) %></h3>
6 <h3><%= format_activity_day(day) %></h3>
7 <dl>
7 <dl>
8 <% @events_by_day[day].sort {|x,y| y.event_datetime <=> x.event_datetime }.each do |e| -%>
8 <% @events_by_day[day].sort {|x,y| y.event_datetime <=> x.event_datetime }.each do |e| -%>
9 <dt class="<%= e.event_type %> <%= User.current.logged? && e.respond_to?(:event_author) && User.current == e.event_author ? 'me' : nil %>">
9 <dt class="<%= e.event_type %> <%= User.current.logged? && e.respond_to?(:event_author) && User.current == e.event_author ? 'me' : nil %>">
10 <%= avatar(e.event_author, :size => "24") if e.respond_to?(:event_author) %>
10 <%= avatar(e.event_author, :size => "24") if e.respond_to?(:event_author) %>
11 <span class="time"><%= format_time(e.event_datetime, false) %></span>
11 <span class="time"><%= format_time(e.event_datetime, false) %></span>
12 <%= content_tag('span', h(e.project), :class => 'project') if @project.nil? || @project != e.project %>
12 <%= content_tag('span', h(e.project), :class => 'project') if @project.nil? || @project != e.project %>
13 <%= link_to format_activity_title(e.event_title), e.event_url %></dt>
13 <%= link_to format_activity_title(e.event_title), e.event_url %></dt>
14 <dd><span class="description"><%= format_activity_description(e.event_description) %></span>
14 <dd><span class="description"><%= format_activity_description(e.event_description) %></span>
15 <span class="author"><%= e.event_author if e.respond_to?(:event_author) %></span></dd>
15 <span class="author"><%= e.event_author if e.respond_to?(:event_author) %></span></dd>
16 <% end -%>
16 <% end -%>
17 </dl>
17 </dl>
18 <% end -%>
18 <% end -%>
19 </div>
19 </div>
20
20
21 <%= content_tag('p', l(:label_no_data), :class => 'nodata') if @events_by_day.empty? %>
21 <%= content_tag('p', l(:label_no_data), :class => 'nodata') if @events_by_day.empty? %>
22
22
23 <div style="float:left;">
23 <div style="float:left;">
24 <%= link_to_remote(('&#171; ' + l(:label_previous)),
24 <%= link_to_remote(('&#171; ' + l(:label_previous)),
25 {:update => "content", :url => params.merge(:from => @date_to - @days - 1), :method => :get, :complete => 'window.scrollTo(0,0)'},
25 {:update => "content", :url => params.merge(:from => @date_to - @days - 1), :method => :get, :complete => 'window.scrollTo(0,0)'},
26 {:href => url_for(params.merge(:from => @date_to - @days - 1)),
26 {:href => url_for(params.merge(:from => @date_to - @days - 1)),
27 :title => "#{l(:label_date_from)} #{format_date(@date_to - 2*@days)} #{l(:label_date_to).downcase} #{format_date(@date_to - @days - 1)}"}) %>
27 :title => "#{l(:label_date_from)} #{format_date(@date_to - 2*@days)} #{l(:label_date_to).downcase} #{format_date(@date_to - @days - 1)}"}) %>
28 </div>
28 </div>
29 <div style="float:right;">
29 <div style="float:right;">
30 <%= link_to_remote((l(:label_next) + ' &#187;'),
30 <%= link_to_remote((l(:label_next) + ' &#187;'),
31 {:update => "content", :url => params.merge(:from => @date_to + @days - 1), :method => :get, :complete => 'window.scrollTo(0,0)'},
31 {:update => "content", :url => params.merge(:from => @date_to + @days - 1), :method => :get, :complete => 'window.scrollTo(0,0)'},
32 {:href => url_for(params.merge(:from => @date_to + @days - 1)),
32 {:href => url_for(params.merge(:from => @date_to + @days - 1)),
33 :title => "#{l(:label_date_from)} #{format_date(@date_to)} #{l(:label_date_to).downcase} #{format_date(@date_to + @days - 1)}"}) unless @date_to >= Date.today %>
33 :title => "#{l(:label_date_from)} #{format_date(@date_to)} #{l(:label_date_to).downcase} #{format_date(@date_to + @days - 1)}"}) unless @date_to >= Date.today %>
34 </div>
34 </div>
35 &nbsp;
35 &nbsp;
36 <p class="other-formats">
36 <% other_formats_links do |f| %>
37 <%= l(:label_export_to) %>
37 <%= f.link_to 'Atom', :url => params.merge(:from => nil, :key => User.current.rss_key) %>
38 <%= link_to 'Atom', params.merge(:format => :atom, :from => nil, :key => User.current.rss_key), :class => 'feed' %>
38 <% end %>
39 </p>
40
39
41 <% content_for :header_tags do %>
40 <% content_for :header_tags do %>
42 <%= auto_discovery_link_tag(:atom, params.merge(:format => 'atom', :from => nil, :key => User.current.rss_key)) %>
41 <%= auto_discovery_link_tag(:atom, params.merge(:format => 'atom', :from => nil, :key => User.current.rss_key)) %>
43 <% end %>
42 <% end %>
44
43
45 <% content_for :sidebar do %>
44 <% content_for :sidebar do %>
46 <% form_tag({}, :method => :get) do %>
45 <% form_tag({}, :method => :get) do %>
47 <h3><%= l(:label_activity) %></h3>
46 <h3><%= l(:label_activity) %></h3>
48 <p><% @activity.event_types.each do |t| %>
47 <p><% @activity.event_types.each do |t| %>
49 <label><%= check_box_tag "show_#{t}", 1, @activity.scope.include?(t) %> <%= l("label_#{t.singularize}_plural")%></label><br />
48 <label><%= check_box_tag "show_#{t}", 1, @activity.scope.include?(t) %> <%= l("label_#{t.singularize}_plural")%></label><br />
50 <% end %></p>
49 <% end %></p>
51 <% if @project && @project.descendants.active.any? %>
50 <% if @project && @project.descendants.active.any? %>
52 <p><label><%= check_box_tag 'with_subprojects', 1, @with_subprojects %> <%=l(:label_subproject_plural)%></label></p>
51 <p><label><%= check_box_tag 'with_subprojects', 1, @with_subprojects %> <%=l(:label_subproject_plural)%></label></p>
53 <%= hidden_field_tag 'with_subprojects', 0 %>
52 <%= hidden_field_tag 'with_subprojects', 0 %>
54 <% end %>
53 <% end %>
55 <%= hidden_field_tag('user_id', params[:user_id]) unless params[:user_id].blank? %>
54 <%= hidden_field_tag('user_id', params[:user_id]) unless params[:user_id].blank? %>
56 <p><%= submit_tag l(:button_apply), :class => 'button-small', :name => nil %></p>
55 <p><%= submit_tag l(:button_apply), :class => 'button-small', :name => nil %></p>
57 <% end %>
56 <% end %>
58 <% end %>
57 <% end %>
59
58
60 <% html_title(l(:label_activity), @author) -%>
59 <% html_title(l(:label_activity), @author) -%>
@@ -1,22 +1,21
1 <div class="contextual">
1 <div class="contextual">
2 <%= link_to(l(:label_project_new), {:controller => 'projects', :action => 'add'}, :class => 'icon icon-add') + ' |' if User.current.admin? %>
2 <%= link_to(l(:label_project_new), {:controller => 'projects', :action => 'add'}, :class => 'icon icon-add') + ' |' if User.current.admin? %>
3 <%= link_to l(:label_issue_view_all), { :controller => 'issues' } %> |
3 <%= link_to l(:label_issue_view_all), { :controller => 'issues' } %> |
4 <%= link_to l(:label_overall_activity), { :controller => 'projects', :action => 'activity' }%>
4 <%= link_to l(:label_overall_activity), { :controller => 'projects', :action => 'activity' }%>
5 </div>
5 </div>
6
6
7 <h2><%=l(:label_project_plural)%></h2>
7 <h2><%=l(:label_project_plural)%></h2>
8
8
9 <%= render_project_hierarchy(@projects)%>
9 <%= render_project_hierarchy(@projects)%>
10
10
11 <% if User.current.logged? %>
11 <% if User.current.logged? %>
12 <p style="text-align:right;">
12 <p style="text-align:right;">
13 <span class="my-project"><%= l(:label_my_projects) %></span>
13 <span class="my-project"><%= l(:label_my_projects) %></span>
14 </p>
14 </p>
15 <% end %>
15 <% end %>
16
16
17 <p class="other-formats">
17 <% other_formats_links do |f| %>
18 <%= l(:label_export_to) %>
18 <%= f.link_to 'Atom', :url => {:key => User.current.rss_key} %>
19 <span><%= link_to 'Atom', {:format => 'atom', :key => User.current.rss_key}, :class => 'feed' %></span>
19 <% end %>
20 </p>
21
20
22 <% html_title(l(:label_project_plural)) -%>
21 <% html_title(l(:label_project_plural)) -%>
@@ -1,27 +1,26
1 <h2><%= l(:label_revision) %> <%= format_revision(@rev) %> <%= @path.gsub(/^.*\//, '') %></h2>
1 <h2><%= l(:label_revision) %> <%= format_revision(@rev) %> <%= @path.gsub(/^.*\//, '') %></h2>
2
2
3 <!-- Choose view type -->
3 <!-- Choose view type -->
4 <% form_tag({ :controller => 'repositories', :action => 'diff'}, :method => 'get') do %>
4 <% form_tag({ :controller => 'repositories', :action => 'diff'}, :method => 'get') do %>
5 <% params.each do |k, p| %>
5 <% params.each do |k, p| %>
6 <% if k != "type" %>
6 <% if k != "type" %>
7 <%= hidden_field_tag(k,p) %>
7 <%= hidden_field_tag(k,p) %>
8 <% end %>
8 <% end %>
9 <% end %>
9 <% end %>
10 <p><label><%= l(:label_view_diff) %></label>
10 <p><label><%= l(:label_view_diff) %></label>
11 <%= select_tag 'type', options_for_select([[l(:label_diff_inline), "inline"], [l(:label_diff_side_by_side), "sbs"]], @diff_type), :onchange => "if (this.value != '') {this.form.submit()}" %></p>
11 <%= select_tag 'type', options_for_select([[l(:label_diff_inline), "inline"], [l(:label_diff_side_by_side), "sbs"]], @diff_type), :onchange => "if (this.value != '') {this.form.submit()}" %></p>
12 <% end %>
12 <% end %>
13
13
14 <% cache(@cache_key) do -%>
14 <% cache(@cache_key) do -%>
15 <%= render :partial => 'common/diff', :locals => {:diff => @diff, :diff_type => @diff_type} %>
15 <%= render :partial => 'common/diff', :locals => {:diff => @diff, :diff_type => @diff_type} %>
16 <% end -%>
16 <% end -%>
17
17
18 <p class="other-formats">
18 <% other_formats_links do |f| %>
19 <%= l(:label_export_to) %>
19 <%= f.link_to 'Diff', :url => params, :caption => 'Unified diff' %>
20 <span><%= link_to 'Unified diff', params.merge(:format => 'diff') %></span>
20 <% end %>
21 </p>
22
21
23 <% html_title(with_leading_slash(@path), 'Diff') -%>
22 <% html_title(with_leading_slash(@path), 'Diff') -%>
24
23
25 <% content_for :header_tags do %>
24 <% content_for :header_tags do %>
26 <%= stylesheet_link_tag "scm" %>
25 <%= stylesheet_link_tag "scm" %>
27 <% end %>
26 <% end %>
@@ -1,24 +1,23
1 <div class="contextual">
1 <div class="contextual">
2 <% form_tag({:action => 'revision', :id => @project}) do %>
2 <% form_tag({:action => 'revision', :id => @project}) do %>
3 <%= l(:label_revision) %>: <%= text_field_tag 'rev', @rev, :size => 5 %>
3 <%= l(:label_revision) %>: <%= text_field_tag 'rev', @rev, :size => 5 %>
4 <%= submit_tag 'OK' %>
4 <%= submit_tag 'OK' %>
5 <% end %>
5 <% end %>
6 </div>
6 </div>
7
7
8 <h2><%= l(:label_revision_plural) %></h2>
8 <h2><%= l(:label_revision_plural) %></h2>
9
9
10 <%= render :partial => 'revisions', :locals => {:project => @project, :path => '', :revisions => @changesets, :entry => nil }%>
10 <%= render :partial => 'revisions', :locals => {:project => @project, :path => '', :revisions => @changesets, :entry => nil }%>
11
11
12 <p class="pagination"><%= pagination_links_full @changeset_pages,@changeset_count %></p>
12 <p class="pagination"><%= pagination_links_full @changeset_pages,@changeset_count %></p>
13
13
14 <% content_for :header_tags do %>
14 <% content_for :header_tags do %>
15 <%= stylesheet_link_tag "scm" %>
15 <%= stylesheet_link_tag "scm" %>
16 <%= auto_discovery_link_tag(:atom, params.merge({:format => 'atom', :page => nil, :key => User.current.rss_key})) %>
16 <%= auto_discovery_link_tag(:atom, params.merge({:format => 'atom', :page => nil, :key => User.current.rss_key})) %>
17 <% end %>
17 <% end %>
18
18
19 <p class="other-formats">
19 <% other_formats_links do |f| %>
20 <%= l(:label_export_to) %>
20 <%= f.link_to 'Atom', :url => {:key => User.current.rss_key} %>
21 <span><%= link_to 'Atom', {:format => 'atom', :key => User.current.rss_key}, :class => 'feed' %></span>
21 <% end %>
22 </p>
23
22
24 <% html_title(l(:label_revision_plural)) -%>
23 <% html_title(l(:label_revision_plural)) -%>
@@ -1,35 +1,35
1 <div class="contextual">
1 <div class="contextual">
2 <%= call_hook(:view_repositories_show_contextual, { :repository => @repository, :project => @project }) %>
2 <%= call_hook(:view_repositories_show_contextual, { :repository => @repository, :project => @project }) %>
3 <%= link_to l(:label_statistics), {:action => 'stats', :id => @project}, :class => 'icon icon-stats' %>
3 <%= link_to l(:label_statistics), {:action => 'stats', :id => @project}, :class => 'icon icon-stats' %>
4
4
5 <% if !@entries.nil? && authorize_for('repositories', 'browse') -%>
5 <% if !@entries.nil? && authorize_for('repositories', 'browse') -%>
6 <% form_tag(:action => 'browse', :id => @project) do -%>
6 <% form_tag(:action => 'browse', :id => @project) do -%>
7 | <%= l(:label_revision) %>: <%= text_field_tag 'rev', @rev, :size => 5 %>
7 | <%= l(:label_revision) %>: <%= text_field_tag 'rev', @rev, :size => 5 %>
8 <% end -%>
8 <% end -%>
9 <% end -%>
9 <% end -%>
10 </div>
10 </div>
11
11
12 <h2><%= l(:label_repository) %> (<%= @repository.scm_name %>)</h2>
12 <h2><%= l(:label_repository) %> (<%= @repository.scm_name %>)</h2>
13
13
14 <% if !@entries.nil? && authorize_for('repositories', 'browse') %>
14 <% if !@entries.nil? && authorize_for('repositories', 'browse') %>
15 <%= render :partial => 'dir_list' %>
15 <%= render :partial => 'dir_list' %>
16 <% end %>
16 <% end %>
17
17
18 <% if !@changesets.empty? && authorize_for('repositories', 'revisions') %>
18 <% if !@changesets.empty? && authorize_for('repositories', 'revisions') %>
19 <h3><%= l(:label_latest_revision_plural) %></h3>
19 <h3><%= l(:label_latest_revision_plural) %></h3>
20 <%= render :partial => 'revisions', :locals => {:project => @project, :path => '', :revisions => @changesets, :entry => nil }%>
20 <%= render :partial => 'revisions', :locals => {:project => @project, :path => '', :revisions => @changesets, :entry => nil }%>
21 <p><%= link_to l(:label_view_revisions), :action => 'revisions', :id => @project %></p>
21 <p><%= link_to l(:label_view_revisions), :action => 'revisions', :id => @project %></p>
22 <% content_for :header_tags do %>
22 <% content_for :header_tags do %>
23 <%= auto_discovery_link_tag(:atom, params.merge({:format => 'atom', :action => 'revisions', :id => @project, :page => nil, :key => User.current.rss_key})) %>
23 <%= auto_discovery_link_tag(:atom, params.merge({:format => 'atom', :action => 'revisions', :id => @project, :page => nil, :key => User.current.rss_key})) %>
24 <% end %>
24 <% end %>
25 <p class="other-formats">
25
26 <%= l(:label_export_to) %>
26 <% other_formats_links do |f| %>
27 <span><%= link_to 'Atom', {:action => 'revisions', :id => @project, :format => 'atom', :key => User.current.rss_key}, :class => 'feed' %></span>
27 <%= f.link_to 'Atom', :url => {:action => 'revisions', :id => @project, :key => User.current.rss_key} %>
28 </p>
28 <% end %>
29 <% end %>
29 <% end %>
30
30
31 <% content_for :header_tags do %>
31 <% content_for :header_tags do %>
32 <%= stylesheet_link_tag "scm" %>
32 <%= stylesheet_link_tag "scm" %>
33 <% end %>
33 <% end %>
34
34
35 <% html_title(l(:label_repository)) -%>
35 <% html_title(l(:label_repository)) -%>
@@ -1,36 +1,35
1 <div class="contextual">
1 <div class="contextual">
2 <%= link_to_if_authorized l(:button_log_time), {:controller => 'timelog', :action => 'edit', :project_id => @project, :issue_id => @issue}, :class => 'icon icon-time' %>
2 <%= link_to_if_authorized l(:button_log_time), {:controller => 'timelog', :action => 'edit', :project_id => @project, :issue_id => @issue}, :class => 'icon icon-time' %>
3 </div>
3 </div>
4
4
5 <%= render_timelog_breadcrumb %>
5 <%= render_timelog_breadcrumb %>
6
6
7 <h2><%= l(:label_spent_time) %></h2>
7 <h2><%= l(:label_spent_time) %></h2>
8
8
9 <% form_remote_tag( :url => {}, :html => {:method => :get}, :method => :get, :update => 'content' ) do %>
9 <% form_remote_tag( :url => {}, :html => {:method => :get}, :method => :get, :update => 'content' ) do %>
10 <%# TOOD: remove the project_id and issue_id hidden fields, that information is
10 <%# TOOD: remove the project_id and issue_id hidden fields, that information is
11 already in the URI %>
11 already in the URI %>
12 <%= hidden_field_tag 'project_id', params[:project_id] %>
12 <%= hidden_field_tag 'project_id', params[:project_id] %>
13 <%= hidden_field_tag 'issue_id', params[:issue_id] if @issue %>
13 <%= hidden_field_tag 'issue_id', params[:issue_id] if @issue %>
14 <%= render :partial => 'date_range' %>
14 <%= render :partial => 'date_range' %>
15 <% end %>
15 <% end %>
16
16
17 <div class="total-hours">
17 <div class="total-hours">
18 <p><%= l(:label_total) %>: <%= html_hours(lwr(:label_f_hour, @total_hours)) %></p>
18 <p><%= l(:label_total) %>: <%= html_hours(lwr(:label_f_hour, @total_hours)) %></p>
19 </div>
19 </div>
20
20
21 <% unless @entries.empty? %>
21 <% unless @entries.empty? %>
22 <%= render :partial => 'list', :locals => { :entries => @entries }%>
22 <%= render :partial => 'list', :locals => { :entries => @entries }%>
23 <p class="pagination"><%= pagination_links_full @entry_pages, @entry_count %></p>
23 <p class="pagination"><%= pagination_links_full @entry_pages, @entry_count %></p>
24
24
25 <p class="other-formats">
25 <% other_formats_links do |f| %>
26 <%= l(:label_export_to) %>
26 <%= f.link_to 'Atom', :url => params.merge({:issue_id => @issue, :key => User.current.rss_key}) %>
27 <span><%= link_to 'Atom', {:issue_id => @issue, :format => 'atom', :key => User.current.rss_key}, :class => 'feed' %></span>
27 <%= f.link_to 'CSV', :url => params %>
28 <span><%= link_to 'CSV', params.merge(:format => 'csv'), :class => 'csv' %></span>
28 <% end %>
29 </p>
30 <% end %>
29 <% end %>
31
30
32 <% html_title l(:label_spent_time), l(:label_details) %>
31 <% html_title l(:label_spent_time), l(:label_details) %>
33
32
34 <% content_for :header_tags do %>
33 <% content_for :header_tags do %>
35 <%= auto_discovery_link_tag(:atom, {:issue_id => @issue, :format => 'atom', :key => User.current.rss_key}, :title => l(:label_spent_time)) %>
34 <%= auto_discovery_link_tag(:atom, {:issue_id => @issue, :format => 'atom', :key => User.current.rss_key}, :title => l(:label_spent_time)) %>
36 <% end %>
35 <% end %>
@@ -1,76 +1,75
1 <div class="contextual">
1 <div class="contextual">
2 <%= link_to_if_authorized l(:button_log_time), {:controller => 'timelog', :action => 'edit', :project_id => @project, :issue_id => @issue}, :class => 'icon icon-time' %>
2 <%= link_to_if_authorized l(:button_log_time), {:controller => 'timelog', :action => 'edit', :project_id => @project, :issue_id => @issue}, :class => 'icon icon-time' %>
3 </div>
3 </div>
4
4
5 <%= render_timelog_breadcrumb %>
5 <%= render_timelog_breadcrumb %>
6
6
7 <h2><%= l(:label_spent_time) %></h2>
7 <h2><%= l(:label_spent_time) %></h2>
8
8
9 <% form_remote_tag(:url => {}, :html => {:method => :get}, :method => :get, :update => 'content') do %>
9 <% form_remote_tag(:url => {}, :html => {:method => :get}, :method => :get, :update => 'content') do %>
10 <% @criterias.each do |criteria| %>
10 <% @criterias.each do |criteria| %>
11 <%= hidden_field_tag 'criterias[]', criteria, :id => nil %>
11 <%= hidden_field_tag 'criterias[]', criteria, :id => nil %>
12 <% end %>
12 <% end %>
13 <%# TODO: get rid of the project_id field, that should already be in the URL %>
13 <%# TODO: get rid of the project_id field, that should already be in the URL %>
14 <%= hidden_field_tag 'project_id', params[:project_id] %>
14 <%= hidden_field_tag 'project_id', params[:project_id] %>
15 <%= render :partial => 'date_range' %>
15 <%= render :partial => 'date_range' %>
16
16
17 <p><%= l(:label_details) %>: <%= select_tag 'columns', options_for_select([[l(:label_year), 'year'],
17 <p><%= l(:label_details) %>: <%= select_tag 'columns', options_for_select([[l(:label_year), 'year'],
18 [l(:label_month), 'month'],
18 [l(:label_month), 'month'],
19 [l(:label_week), 'week'],
19 [l(:label_week), 'week'],
20 [l(:label_day_plural).titleize, 'day']], @columns),
20 [l(:label_day_plural).titleize, 'day']], @columns),
21 :onchange => "this.form.onsubmit();" %>
21 :onchange => "this.form.onsubmit();" %>
22
22
23 <%= l(:button_add) %>: <%= select_tag('criterias[]', options_for_select([[]] + (@available_criterias.keys - @criterias).collect{|k| [l(@available_criterias[k][:label]), k]}),
23 <%= l(:button_add) %>: <%= select_tag('criterias[]', options_for_select([[]] + (@available_criterias.keys - @criterias).collect{|k| [l(@available_criterias[k][:label]), k]}),
24 :onchange => "this.form.onsubmit();",
24 :onchange => "this.form.onsubmit();",
25 :style => 'width: 200px',
25 :style => 'width: 200px',
26 :id => nil,
26 :id => nil,
27 :disabled => (@criterias.length >= 3)) %>
27 :disabled => (@criterias.length >= 3)) %>
28 <%= link_to_remote l(:button_clear), {:url => {:project_id => @project, :period_type => params[:period_type], :period => params[:period], :from => @from, :to => @to, :columns => @columns},
28 <%= link_to_remote l(:button_clear), {:url => {:project_id => @project, :period_type => params[:period_type], :period => params[:period], :from => @from, :to => @to, :columns => @columns},
29 :method => :get,
29 :method => :get,
30 :update => 'content'
30 :update => 'content'
31 }, :class => 'icon icon-reload' %></p>
31 }, :class => 'icon icon-reload' %></p>
32 <% end %>
32 <% end %>
33
33
34 <% unless @criterias.empty? %>
34 <% unless @criterias.empty? %>
35 <div class="total-hours">
35 <div class="total-hours">
36 <p><%= l(:label_total) %>: <%= html_hours(lwr(:label_f_hour, @total_hours)) %></p>
36 <p><%= l(:label_total) %>: <%= html_hours(lwr(:label_f_hour, @total_hours)) %></p>
37 </div>
37 </div>
38
38
39 <% unless @hours.empty? %>
39 <% unless @hours.empty? %>
40 <table class="list" id="time-report">
40 <table class="list" id="time-report">
41 <thead>
41 <thead>
42 <tr>
42 <tr>
43 <% @criterias.each do |criteria| %>
43 <% @criterias.each do |criteria| %>
44 <th><%= l(@available_criterias[criteria][:label]) %></th>
44 <th><%= l(@available_criterias[criteria][:label]) %></th>
45 <% end %>
45 <% end %>
46 <% columns_width = (40 / (@periods.length+1)).to_i %>
46 <% columns_width = (40 / (@periods.length+1)).to_i %>
47 <% @periods.each do |period| %>
47 <% @periods.each do |period| %>
48 <th class="period" width="<%= columns_width %>%"><%= period %></th>
48 <th class="period" width="<%= columns_width %>%"><%= period %></th>
49 <% end %>
49 <% end %>
50 <th class="total" width="<%= columns_width %>%"><%= l(:label_total) %></th>
50 <th class="total" width="<%= columns_width %>%"><%= l(:label_total) %></th>
51 </tr>
51 </tr>
52 </thead>
52 </thead>
53 <tbody>
53 <tbody>
54 <%= render :partial => 'report_criteria', :locals => {:criterias => @criterias, :hours => @hours, :level => 0} %>
54 <%= render :partial => 'report_criteria', :locals => {:criterias => @criterias, :hours => @hours, :level => 0} %>
55 <tr class="total">
55 <tr class="total">
56 <td><%= l(:label_total) %></td>
56 <td><%= l(:label_total) %></td>
57 <%= '<td></td>' * (@criterias.size - 1) %>
57 <%= '<td></td>' * (@criterias.size - 1) %>
58 <% total = 0 -%>
58 <% total = 0 -%>
59 <% @periods.each do |period| -%>
59 <% @periods.each do |period| -%>
60 <% sum = sum_hours(select_hours(@hours, @columns, period.to_s)); total += sum -%>
60 <% sum = sum_hours(select_hours(@hours, @columns, period.to_s)); total += sum -%>
61 <td class="hours"><%= html_hours("%.2f" % sum) if sum > 0 %></td>
61 <td class="hours"><%= html_hours("%.2f" % sum) if sum > 0 %></td>
62 <% end -%>
62 <% end -%>
63 <td class="hours"><%= html_hours("%.2f" % total) if total > 0 %></td>
63 <td class="hours"><%= html_hours("%.2f" % total) if total > 0 %></td>
64 </tr>
64 </tr>
65 </tbody>
65 </tbody>
66 </table>
66 </table>
67
67
68 <p class="other-formats">
68 <% other_formats_links do |f| %>
69 <%= l(:label_export_to) %>
69 <%= f.link_to 'CSV', :url => params %>
70 <span><%= link_to 'CSV', params.merge({:format => 'csv'}), :class => 'csv' %></span>
70 <% end %>
71 </p>
72 <% end %>
71 <% end %>
73 <% end %>
72 <% end %>
74
73
75 <% html_title l(:label_spent_time), l(:label_report) %>
74 <% html_title l(:label_spent_time), l(:label_report) %>
76
75
@@ -1,59 +1,58
1 <div class="contextual">
1 <div class="contextual">
2 <% if @editable %>
2 <% if @editable %>
3 <%= link_to_if_authorized(l(:button_edit), {:action => 'edit', :page => @page.title}, :class => 'icon icon-edit', :accesskey => accesskey(:edit)) if @content.version == @page.content.version %>
3 <%= link_to_if_authorized(l(:button_edit), {:action => 'edit', :page => @page.title}, :class => 'icon icon-edit', :accesskey => accesskey(:edit)) if @content.version == @page.content.version %>
4 <%= link_to_if_authorized(l(:button_lock), {:action => 'protect', :page => @page.title, :protected => 1}, :method => :post, :class => 'icon icon-lock') if !@page.protected? %>
4 <%= link_to_if_authorized(l(:button_lock), {:action => 'protect', :page => @page.title, :protected => 1}, :method => :post, :class => 'icon icon-lock') if !@page.protected? %>
5 <%= link_to_if_authorized(l(:button_unlock), {:action => 'protect', :page => @page.title, :protected => 0}, :method => :post, :class => 'icon icon-unlock') if @page.protected? %>
5 <%= link_to_if_authorized(l(:button_unlock), {:action => 'protect', :page => @page.title, :protected => 0}, :method => :post, :class => 'icon icon-unlock') if @page.protected? %>
6 <%= link_to_if_authorized(l(:button_rename), {:action => 'rename', :page => @page.title}, :class => 'icon icon-move') if @content.version == @page.content.version %>
6 <%= link_to_if_authorized(l(:button_rename), {:action => 'rename', :page => @page.title}, :class => 'icon icon-move') if @content.version == @page.content.version %>
7 <%= link_to_if_authorized(l(:button_delete), {:action => 'destroy', :page => @page.title}, :method => :post, :confirm => l(:text_are_you_sure), :class => 'icon icon-del') %>
7 <%= link_to_if_authorized(l(:button_delete), {:action => 'destroy', :page => @page.title}, :method => :post, :confirm => l(:text_are_you_sure), :class => 'icon icon-del') %>
8 <%= link_to_if_authorized(l(:button_rollback), {:action => 'edit', :page => @page.title, :version => @content.version }, :class => 'icon icon-cancel') if @content.version < @page.content.version %>
8 <%= link_to_if_authorized(l(:button_rollback), {:action => 'edit', :page => @page.title, :version => @content.version }, :class => 'icon icon-cancel') if @content.version < @page.content.version %>
9 <% end %>
9 <% end %>
10 <%= link_to_if_authorized(l(:label_history), {:action => 'history', :page => @page.title}, :class => 'icon icon-history') %>
10 <%= link_to_if_authorized(l(:label_history), {:action => 'history', :page => @page.title}, :class => 'icon icon-history') %>
11 </div>
11 </div>
12
12
13 <%= breadcrumb(@page.ancestors.reverse.collect {|parent| link_to h(parent.pretty_title), {:page => parent.title}}) %>
13 <%= breadcrumb(@page.ancestors.reverse.collect {|parent| link_to h(parent.pretty_title), {:page => parent.title}}) %>
14
14
15 <% if @content.version != @page.content.version %>
15 <% if @content.version != @page.content.version %>
16 <p>
16 <p>
17 <%= link_to(('&#171; ' + l(:label_previous)), :action => 'index', :page => @page.title, :version => (@content.version - 1)) + " - " if @content.version > 1 %>
17 <%= link_to(('&#171; ' + l(:label_previous)), :action => 'index', :page => @page.title, :version => (@content.version - 1)) + " - " if @content.version > 1 %>
18 <%= "#{l(:label_version)} #{@content.version}/#{@page.content.version}" %>
18 <%= "#{l(:label_version)} #{@content.version}/#{@page.content.version}" %>
19 <%= '(' + link_to('diff', :controller => 'wiki', :action => 'diff', :page => @page.title, :version => @content.version) + ')' if @content.version > 1 %> -
19 <%= '(' + link_to('diff', :controller => 'wiki', :action => 'diff', :page => @page.title, :version => @content.version) + ')' if @content.version > 1 %> -
20 <%= link_to((l(:label_next) + ' &#187;'), :action => 'index', :page => @page.title, :version => (@content.version + 1)) + " - " if @content.version < @page.content.version %>
20 <%= link_to((l(:label_next) + ' &#187;'), :action => 'index', :page => @page.title, :version => (@content.version + 1)) + " - " if @content.version < @page.content.version %>
21 <%= link_to(l(:label_current_version), :action => 'index', :page => @page.title) %>
21 <%= link_to(l(:label_current_version), :action => 'index', :page => @page.title) %>
22 <br />
22 <br />
23 <em><%= @content.author ? @content.author.name : "anonyme" %>, <%= format_time(@content.updated_on) %> </em><br />
23 <em><%= @content.author ? @content.author.name : "anonyme" %>, <%= format_time(@content.updated_on) %> </em><br />
24 <%=h @content.comments %>
24 <%=h @content.comments %>
25 </p>
25 </p>
26 <hr />
26 <hr />
27 <% end %>
27 <% end %>
28
28
29 <%= render(:partial => "wiki/content", :locals => {:content => @content}) %>
29 <%= render(:partial => "wiki/content", :locals => {:content => @content}) %>
30
30
31 <%= link_to_attachments @page %>
31 <%= link_to_attachments @page %>
32
32
33 <% if @editable && authorize_for('wiki', 'add_attachment') %>
33 <% if @editable && authorize_for('wiki', 'add_attachment') %>
34 <p><%= link_to l(:label_attachment_new), {}, :onclick => "Element.show('add_attachment_form'); Element.hide(this); Element.scrollTo('add_attachment_form'); return false;",
34 <p><%= link_to l(:label_attachment_new), {}, :onclick => "Element.show('add_attachment_form'); Element.hide(this); Element.scrollTo('add_attachment_form'); return false;",
35 :id => 'attach_files_link' %></p>
35 :id => 'attach_files_link' %></p>
36 <% form_tag({ :controller => 'wiki', :action => 'add_attachment', :page => @page.title }, :multipart => true, :id => "add_attachment_form", :style => "display:none;") do %>
36 <% form_tag({ :controller => 'wiki', :action => 'add_attachment', :page => @page.title }, :multipart => true, :id => "add_attachment_form", :style => "display:none;") do %>
37 <div class="box">
37 <div class="box">
38 <p><%= render :partial => 'attachments/form' %></p>
38 <p><%= render :partial => 'attachments/form' %></p>
39 </div>
39 </div>
40 <%= submit_tag l(:button_add) %>
40 <%= submit_tag l(:button_add) %>
41 <%= link_to l(:button_cancel), {}, :onclick => "Element.hide('add_attachment_form'); Element.show('attach_files_link'); return false;" %>
41 <%= link_to l(:button_cancel), {}, :onclick => "Element.hide('add_attachment_form'); Element.show('attach_files_link'); return false;" %>
42 <% end %>
42 <% end %>
43 <% end %>
43 <% end %>
44
44
45 <p class="other-formats">
45 <% other_formats_links do |f| %>
46 <%= l(:label_export_to) %>
46 <%= f.link_to 'HTML', :url => {:page => @page.title, :version => @content.version} %>
47 <span><%= link_to 'HTML', {:page => @page.title, :export => 'html', :version => @content.version}, :class => 'html' %></span>
47 <%= f.link_to 'TXT', :url => {:page => @page.title, :version => @content.version} %>
48 <span><%= link_to 'TXT', {:page => @page.title, :export => 'txt', :version => @content.version}, :class => 'text' %></span>
48 <% end %>
49 </p>
50
49
51 <% content_for :header_tags do %>
50 <% content_for :header_tags do %>
52 <%= stylesheet_link_tag 'scm' %>
51 <%= stylesheet_link_tag 'scm' %>
53 <% end %>
52 <% end %>
54
53
55 <% content_for :sidebar do %>
54 <% content_for :sidebar do %>
56 <%= render :partial => 'sidebar' %>
55 <%= render :partial => 'sidebar' %>
57 <% end %>
56 <% end %>
58
57
59 <% html_title @page.pretty_title %>
58 <% html_title @page.pretty_title %>
@@ -1,30 +1,29
1 <h2><%= l(:label_index_by_date) %></h2>
1 <h2><%= l(:label_index_by_date) %></h2>
2
2
3 <% if @pages.empty? %>
3 <% if @pages.empty? %>
4 <p class="nodata"><%= l(:label_no_data) %></p>
4 <p class="nodata"><%= l(:label_no_data) %></p>
5 <% end %>
5 <% end %>
6
6
7 <% @pages_by_date.keys.sort.reverse.each do |date| %>
7 <% @pages_by_date.keys.sort.reverse.each do |date| %>
8 <h3><%= format_date(date) %></h3>
8 <h3><%= format_date(date) %></h3>
9 <ul>
9 <ul>
10 <% @pages_by_date[date].each do |page| %>
10 <% @pages_by_date[date].each do |page| %>
11 <li><%= link_to page.pretty_title, :action => 'index', :page => page.title %></li>
11 <li><%= link_to page.pretty_title, :action => 'index', :page => page.title %></li>
12 <% end %>
12 <% end %>
13 </ul>
13 </ul>
14 <% end %>
14 <% end %>
15
15
16 <% content_for :sidebar do %>
16 <% content_for :sidebar do %>
17 <%= render :partial => 'sidebar' %>
17 <%= render :partial => 'sidebar' %>
18 <% end %>
18 <% end %>
19
19
20 <% unless @pages.empty? %>
20 <% unless @pages.empty? %>
21 <p class="other-formats">
21 <% other_formats_links do |f| %>
22 <%= l(:label_export_to) %>
22 <%= f.link_to 'Atom', :url => {:controller => 'projects', :action => 'activity', :id => @project, :show_wiki_pages => 1, :key => User.current.rss_key} %>
23 <span><%= link_to 'Atom', {:controller => 'projects', :action => 'activity', :id => @project, :show_wiki_pages => 1, :format => 'atom', :key => User.current.rss_key}, :class => 'feed' %></span>
23 <%= f.link_to 'HTML', :url => {:action => 'special', :page => 'export'} %>
24 <span><%= link_to 'HTML', {:action => 'special', :page => 'export'}, :class => 'html' %></span>
24 <% end %>
25 </p>
26 <% end %>
25 <% end %>
27
26
28 <% content_for :header_tags do %>
27 <% content_for :header_tags do %>
29 <%= auto_discovery_link_tag(:atom, :controller => 'projects', :action => 'activity', :id => @project, :show_wiki_pages => 1, :format => 'atom', :key => User.current.rss_key) %>
28 <%= auto_discovery_link_tag(:atom, :controller => 'projects', :action => 'activity', :id => @project, :show_wiki_pages => 1, :format => 'atom', :key => User.current.rss_key) %>
30 <% end %>
29 <% end %>
@@ -1,23 +1,22
1 <h2><%= l(:label_index_by_title) %></h2>
1 <h2><%= l(:label_index_by_title) %></h2>
2
2
3 <% if @pages.empty? %>
3 <% if @pages.empty? %>
4 <p class="nodata"><%= l(:label_no_data) %></p>
4 <p class="nodata"><%= l(:label_no_data) %></p>
5 <% end %>
5 <% end %>
6
6
7 <%= render_page_hierarchy(@pages_by_parent_id) %>
7 <%= render_page_hierarchy(@pages_by_parent_id) %>
8
8
9 <% content_for :sidebar do %>
9 <% content_for :sidebar do %>
10 <%= render :partial => 'sidebar' %>
10 <%= render :partial => 'sidebar' %>
11 <% end %>
11 <% end %>
12
12
13 <% unless @pages.empty? %>
13 <% unless @pages.empty? %>
14 <p class="other-formats">
14 <% other_formats_links do |f| %>
15 <%= l(:label_export_to) %>
15 <%= f.link_to 'Atom', :url => {:controller => 'projects', :action => 'activity', :id => @project, :show_wiki_pages => 1, :key => User.current.rss_key} %>
16 <span><%= link_to 'Atom', {:controller => 'projects', :action => 'activity', :id => @project, :show_wiki_pages => 1, :format => 'atom', :key => User.current.rss_key}, :class => 'feed' %></span>
16 <%= f.link_to 'HTML', :url => {:action => 'special', :page => 'export'} %>
17 <span><%= link_to 'HTML', {:action => 'special', :page => 'export'} %></span>
17 <% end %>
18 </p>
19 <% end %>
18 <% end %>
20
19
21 <% content_for :header_tags do %>
20 <% content_for :header_tags do %>
22 <%= auto_discovery_link_tag(:atom, :controller => 'projects', :action => 'activity', :id => @project, :show_wiki_pages => 1, :format => 'atom', :key => User.current.rss_key) %>
21 <%= auto_discovery_link_tag(:atom, :controller => 'projects', :action => 'activity', :id => @project, :show_wiki_pages => 1, :format => 'atom', :key => User.current.rss_key) %>
23 <% end %>
22 <% end %>
@@ -1,701 +1,701
1 body { font-family: Verdana, sans-serif; font-size: 12px; color:#484848; margin: 0; padding: 0; min-width: 900px; }
1 body { font-family: Verdana, sans-serif; font-size: 12px; color:#484848; margin: 0; padding: 0; min-width: 900px; }
2
2
3 h1, h2, h3, h4 { font-family: "Trebuchet MS", Verdana, sans-serif;}
3 h1, h2, h3, h4 { font-family: "Trebuchet MS", Verdana, sans-serif;}
4 h1 {margin:0; padding:0; font-size: 24px;}
4 h1 {margin:0; padding:0; font-size: 24px;}
5 h2, .wiki h1 {font-size: 20px;padding: 2px 10px 1px 0px;margin: 0 0 10px 0; border-bottom: 1px solid #bbbbbb; color: #444;}
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 h3, .wiki h2 {font-size: 16px;padding: 2px 10px 1px 0px;margin: 0 0 10px 0; border-bottom: 1px solid #bbbbbb; color: #444;}
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 h4, .wiki h3 {font-size: 13px;padding: 2px 10px 1px 0px;margin-bottom: 5px; border-bottom: 1px dotted #bbbbbb; color: #444;}
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 /***** Layout *****/
9 /***** Layout *****/
10 #wrapper {background: white;}
10 #wrapper {background: white;}
11
11
12 #top-menu {background: #2C4056; color: #fff; height:1.8em; font-size: 0.8em; padding: 2px 2px 0px 6px;}
12 #top-menu {background: #2C4056; color: #fff; height:1.8em; font-size: 0.8em; padding: 2px 2px 0px 6px;}
13 #top-menu ul {margin: 0; padding: 0;}
13 #top-menu ul {margin: 0; padding: 0;}
14 #top-menu li {
14 #top-menu li {
15 float:left;
15 float:left;
16 list-style-type:none;
16 list-style-type:none;
17 margin: 0px 0px 0px 0px;
17 margin: 0px 0px 0px 0px;
18 padding: 0px 0px 0px 0px;
18 padding: 0px 0px 0px 0px;
19 white-space:nowrap;
19 white-space:nowrap;
20 }
20 }
21 #top-menu a {color: #fff; margin-right: 8px; font-weight: bold;}
21 #top-menu a {color: #fff; margin-right: 8px; font-weight: bold;}
22 #top-menu #loggedas { float: right; margin-right: 0.5em; color: #fff; }
22 #top-menu #loggedas { float: right; margin-right: 0.5em; color: #fff; }
23
23
24 #account {float:right;}
24 #account {float:right;}
25
25
26 #header {height:5.3em;margin:0;background-color:#507AAA;color:#f8f8f8; padding: 4px 8px 0px 6px; position:relative;}
26 #header {height:5.3em;margin:0;background-color:#507AAA;color:#f8f8f8; padding: 4px 8px 0px 6px; position:relative;}
27 #header a {color:#f8f8f8;}
27 #header a {color:#f8f8f8;}
28 #quick-search {float:right;}
28 #quick-search {float:right;}
29
29
30 #main-menu {position: absolute; bottom: 0px; left:6px; margin-right: -500px;}
30 #main-menu {position: absolute; bottom: 0px; left:6px; margin-right: -500px;}
31 #main-menu ul {margin: 0; padding: 0;}
31 #main-menu ul {margin: 0; padding: 0;}
32 #main-menu li {
32 #main-menu li {
33 float:left;
33 float:left;
34 list-style-type:none;
34 list-style-type:none;
35 margin: 0px 2px 0px 0px;
35 margin: 0px 2px 0px 0px;
36 padding: 0px 0px 0px 0px;
36 padding: 0px 0px 0px 0px;
37 white-space:nowrap;
37 white-space:nowrap;
38 }
38 }
39 #main-menu li a {
39 #main-menu li a {
40 display: block;
40 display: block;
41 color: #fff;
41 color: #fff;
42 text-decoration: none;
42 text-decoration: none;
43 font-weight: bold;
43 font-weight: bold;
44 margin: 0;
44 margin: 0;
45 padding: 4px 10px 4px 10px;
45 padding: 4px 10px 4px 10px;
46 }
46 }
47 #main-menu li a:hover {background:#759FCF; color:#fff;}
47 #main-menu li a:hover {background:#759FCF; color:#fff;}
48 #main-menu li a.selected, #main-menu li a.selected:hover {background:#fff; color:#555;}
48 #main-menu li a.selected, #main-menu li a.selected:hover {background:#fff; color:#555;}
49
49
50 #main {background-color:#EEEEEE;}
50 #main {background-color:#EEEEEE;}
51
51
52 #sidebar{ float: right; width: 17%; position: relative; z-index: 9; min-height: 600px; padding: 0; margin: 0;}
52 #sidebar{ float: right; width: 17%; position: relative; z-index: 9; min-height: 600px; padding: 0; margin: 0;}
53 * html #sidebar{ width: 17%; }
53 * html #sidebar{ width: 17%; }
54 #sidebar h3{ font-size: 14px; margin-top:14px; color: #666; }
54 #sidebar h3{ font-size: 14px; margin-top:14px; color: #666; }
55 #sidebar hr{ width: 100%; margin: 0 auto; height: 1px; background: #ccc; border: 0; }
55 #sidebar hr{ width: 100%; margin: 0 auto; height: 1px; background: #ccc; border: 0; }
56 * html #sidebar hr{ width: 95%; position: relative; left: -6px; color: #ccc; }
56 * html #sidebar hr{ width: 95%; position: relative; left: -6px; color: #ccc; }
57
57
58 #content { width: 80%; background-color: #fff; margin: 0px; border-right: 1px solid #ddd; padding: 6px 10px 10px 10px; z-index: 10; }
58 #content { width: 80%; background-color: #fff; margin: 0px; border-right: 1px solid #ddd; padding: 6px 10px 10px 10px; z-index: 10; }
59 * html #content{ width: 80%; padding-left: 0; margin-top: 0px; padding: 6px 10px 10px 10px;}
59 * html #content{ width: 80%; padding-left: 0; margin-top: 0px; padding: 6px 10px 10px 10px;}
60 html>body #content { min-height: 600px; }
60 html>body #content { min-height: 600px; }
61 * html body #content { height: 600px; } /* IE */
61 * html body #content { height: 600px; } /* IE */
62
62
63 #main.nosidebar #sidebar{ display: none; }
63 #main.nosidebar #sidebar{ display: none; }
64 #main.nosidebar #content{ width: auto; border-right: 0; }
64 #main.nosidebar #content{ width: auto; border-right: 0; }
65
65
66 #footer {clear: both; border-top: 1px solid #bbb; font-size: 0.9em; color: #aaa; padding: 5px; text-align:center; background:#fff;}
66 #footer {clear: both; border-top: 1px solid #bbb; font-size: 0.9em; color: #aaa; padding: 5px; text-align:center; background:#fff;}
67
67
68 #login-form table {margin-top:5em; padding:1em; margin-left: auto; margin-right: auto; border: 2px solid #FDBF3B; background-color:#FFEBC1; }
68 #login-form table {margin-top:5em; padding:1em; margin-left: auto; margin-right: auto; border: 2px solid #FDBF3B; background-color:#FFEBC1; }
69 #login-form table td {padding: 6px;}
69 #login-form table td {padding: 6px;}
70 #login-form label {font-weight: bold;}
70 #login-form label {font-weight: bold;}
71
71
72 .clear:after{ content: "."; display: block; height: 0; clear: both; visibility: hidden; }
72 .clear:after{ content: "."; display: block; height: 0; clear: both; visibility: hidden; }
73
73
74 /***** Links *****/
74 /***** Links *****/
75 a, a:link, a:visited{ color: #2A5685; text-decoration: none; }
75 a, a:link, a:visited{ color: #2A5685; text-decoration: none; }
76 a:hover, a:active{ color: #c61a1a; text-decoration: underline;}
76 a:hover, a:active{ color: #c61a1a; text-decoration: underline;}
77 a img{ border: 0; }
77 a img{ border: 0; }
78
78
79 a.issue.closed { text-decoration: line-through; }
79 a.issue.closed { text-decoration: line-through; }
80
80
81 /***** Tables *****/
81 /***** Tables *****/
82 table.list { border: 1px solid #e4e4e4; border-collapse: collapse; width: 100%; margin-bottom: 4px; }
82 table.list { border: 1px solid #e4e4e4; border-collapse: collapse; width: 100%; margin-bottom: 4px; }
83 table.list th { background-color:#EEEEEE; padding: 4px; white-space:nowrap; }
83 table.list th { background-color:#EEEEEE; padding: 4px; white-space:nowrap; }
84 table.list td { vertical-align: top; }
84 table.list td { vertical-align: top; }
85 table.list td.id { width: 2%; text-align: center;}
85 table.list td.id { width: 2%; text-align: center;}
86 table.list td.checkbox { width: 15px; padding: 0px;}
86 table.list td.checkbox { width: 15px; padding: 0px;}
87
87
88 tr.project td.name a { padding-left: 16px; white-space:nowrap; }
88 tr.project td.name a { padding-left: 16px; white-space:nowrap; }
89 tr.project.parent td.name a { background: url('../images/bullet_toggle_minus.png') no-repeat; }
89 tr.project.parent td.name a { background: url('../images/bullet_toggle_minus.png') no-repeat; }
90
90
91 tr.issue { text-align: center; white-space: nowrap; }
91 tr.issue { text-align: center; white-space: nowrap; }
92 tr.issue td.subject, tr.issue td.category, td.assigned_to { white-space: normal; }
92 tr.issue td.subject, tr.issue td.category, td.assigned_to { white-space: normal; }
93 tr.issue td.subject { text-align: left; }
93 tr.issue td.subject { text-align: left; }
94 tr.issue td.done_ratio table.progress { margin-left:auto; margin-right: auto;}
94 tr.issue td.done_ratio table.progress { margin-left:auto; margin-right: auto;}
95
95
96 tr.entry { border: 1px solid #f8f8f8; }
96 tr.entry { border: 1px solid #f8f8f8; }
97 tr.entry td { white-space: nowrap; }
97 tr.entry td { white-space: nowrap; }
98 tr.entry td.filename { width: 30%; }
98 tr.entry td.filename { width: 30%; }
99 tr.entry td.size { text-align: right; font-size: 90%; }
99 tr.entry td.size { text-align: right; font-size: 90%; }
100 tr.entry td.revision, tr.entry td.author { text-align: center; }
100 tr.entry td.revision, tr.entry td.author { text-align: center; }
101 tr.entry td.age { text-align: right; }
101 tr.entry td.age { text-align: right; }
102
102
103 tr.entry span.expander {background-image: url(../images/bullet_toggle_plus.png); padding-left: 8px; margin-left: 0; cursor: pointer;}
103 tr.entry span.expander {background-image: url(../images/bullet_toggle_plus.png); padding-left: 8px; margin-left: 0; cursor: pointer;}
104 tr.entry.open span.expander {background-image: url(../images/bullet_toggle_minus.png);}
104 tr.entry.open span.expander {background-image: url(../images/bullet_toggle_minus.png);}
105 tr.entry.file td.filename a { margin-left: 16px; }
105 tr.entry.file td.filename a { margin-left: 16px; }
106
106
107 tr.changeset td.author { text-align: center; width: 15%; }
107 tr.changeset td.author { text-align: center; width: 15%; }
108 tr.changeset td.committed_on { text-align: center; width: 15%; }
108 tr.changeset td.committed_on { text-align: center; width: 15%; }
109
109
110 tr.message { height: 2.6em; }
110 tr.message { height: 2.6em; }
111 tr.message td.last_message { font-size: 80%; }
111 tr.message td.last_message { font-size: 80%; }
112 tr.message.locked td.subject a { background-image: url(../images/locked.png); }
112 tr.message.locked td.subject a { background-image: url(../images/locked.png); }
113 tr.message.sticky td.subject a { background-image: url(../images/sticky.png); font-weight: bold; }
113 tr.message.sticky td.subject a { background-image: url(../images/sticky.png); font-weight: bold; }
114
114
115 tr.user td { width:13%; }
115 tr.user td { width:13%; }
116 tr.user td.email { width:18%; }
116 tr.user td.email { width:18%; }
117 tr.user td { white-space: nowrap; }
117 tr.user td { white-space: nowrap; }
118 tr.user.locked, tr.user.registered { color: #aaa; }
118 tr.user.locked, tr.user.registered { color: #aaa; }
119 tr.user.locked a, tr.user.registered a { color: #aaa; }
119 tr.user.locked a, tr.user.registered a { color: #aaa; }
120
120
121 tr.time-entry { text-align: center; white-space: nowrap; }
121 tr.time-entry { text-align: center; white-space: nowrap; }
122 tr.time-entry td.subject, tr.time-entry td.comments { text-align: left; white-space: normal; }
122 tr.time-entry td.subject, tr.time-entry td.comments { text-align: left; white-space: normal; }
123 td.hours { text-align: right; font-weight: bold; padding-right: 0.5em; }
123 td.hours { text-align: right; font-weight: bold; padding-right: 0.5em; }
124 td.hours .hours-dec { font-size: 0.9em; }
124 td.hours .hours-dec { font-size: 0.9em; }
125
125
126 table.plugins td { vertical-align: middle; }
126 table.plugins td { vertical-align: middle; }
127 table.plugins td.configure { text-align: right; padding-right: 1em; }
127 table.plugins td.configure { text-align: right; padding-right: 1em; }
128 table.plugins span.name { font-weight: bold; display: block; margin-bottom: 6px; }
128 table.plugins span.name { font-weight: bold; display: block; margin-bottom: 6px; }
129 table.plugins span.description { display: block; font-size: 0.9em; }
129 table.plugins span.description { display: block; font-size: 0.9em; }
130 table.plugins span.url { display: block; font-size: 0.9em; }
130 table.plugins span.url { display: block; font-size: 0.9em; }
131
131
132 table.list tbody tr:hover { background-color:#ffffdd; }
132 table.list tbody tr:hover { background-color:#ffffdd; }
133 table td {padding:2px;}
133 table td {padding:2px;}
134 table p {margin:0;}
134 table p {margin:0;}
135 .odd {background-color:#f6f7f8;}
135 .odd {background-color:#f6f7f8;}
136 .even {background-color: #fff;}
136 .even {background-color: #fff;}
137
137
138 .highlight { background-color: #FCFD8D;}
138 .highlight { background-color: #FCFD8D;}
139 .highlight.token-1 { background-color: #faa;}
139 .highlight.token-1 { background-color: #faa;}
140 .highlight.token-2 { background-color: #afa;}
140 .highlight.token-2 { background-color: #afa;}
141 .highlight.token-3 { background-color: #aaf;}
141 .highlight.token-3 { background-color: #aaf;}
142
142
143 .box{
143 .box{
144 padding:6px;
144 padding:6px;
145 margin-bottom: 10px;
145 margin-bottom: 10px;
146 background-color:#f6f6f6;
146 background-color:#f6f6f6;
147 color:#505050;
147 color:#505050;
148 line-height:1.5em;
148 line-height:1.5em;
149 border: 1px solid #e4e4e4;
149 border: 1px solid #e4e4e4;
150 }
150 }
151
151
152 div.square {
152 div.square {
153 border: 1px solid #999;
153 border: 1px solid #999;
154 float: left;
154 float: left;
155 margin: .3em .4em 0 .4em;
155 margin: .3em .4em 0 .4em;
156 overflow: hidden;
156 overflow: hidden;
157 width: .6em; height: .6em;
157 width: .6em; height: .6em;
158 }
158 }
159 .contextual {float:right; white-space: nowrap; line-height:1.4em;margin-top:5px; padding-left: 10px; font-size:0.9em;}
159 .contextual {float:right; white-space: nowrap; line-height:1.4em;margin-top:5px; padding-left: 10px; font-size:0.9em;}
160 .contextual input {font-size:0.9em;}
160 .contextual input {font-size:0.9em;}
161
161
162 .splitcontentleft{float:left; width:49%;}
162 .splitcontentleft{float:left; width:49%;}
163 .splitcontentright{float:right; width:49%;}
163 .splitcontentright{float:right; width:49%;}
164 form {display: inline;}
164 form {display: inline;}
165 input, select {vertical-align: middle; margin-top: 1px; margin-bottom: 1px;}
165 input, select {vertical-align: middle; margin-top: 1px; margin-bottom: 1px;}
166 fieldset {border: 1px solid #e4e4e4; margin:0;}
166 fieldset {border: 1px solid #e4e4e4; margin:0;}
167 legend {color: #484848;}
167 legend {color: #484848;}
168 hr { width: 100%; height: 1px; background: #ccc; border: 0;}
168 hr { width: 100%; height: 1px; background: #ccc; border: 0;}
169 blockquote { font-style: italic; border-left: 3px solid #e0e0e0; padding-left: 0.6em; margin-left: 2.4em;}
169 blockquote { font-style: italic; border-left: 3px solid #e0e0e0; padding-left: 0.6em; margin-left: 2.4em;}
170 blockquote blockquote { margin-left: 0;}
170 blockquote blockquote { margin-left: 0;}
171 textarea.wiki-edit { width: 99%; }
171 textarea.wiki-edit { width: 99%; }
172 li p {margin-top: 0;}
172 li p {margin-top: 0;}
173 div.issue {background:#ffffdd; padding:6px; margin-bottom:6px;border: 1px solid #d7d7d7;}
173 div.issue {background:#ffffdd; padding:6px; margin-bottom:6px;border: 1px solid #d7d7d7;}
174 p.breadcrumb { font-size: 0.9em; margin: 4px 0 4px 0;}
174 p.breadcrumb { font-size: 0.9em; margin: 4px 0 4px 0;}
175 p.subtitle { font-size: 0.9em; margin: -6px 0 12px 0; font-style: italic; }
175 p.subtitle { font-size: 0.9em; margin: -6px 0 12px 0; font-style: italic; }
176 p.footnote { font-size: 0.9em; margin-top: 0px; margin-bottom: 0px; }
176 p.footnote { font-size: 0.9em; margin-top: 0px; margin-bottom: 0px; }
177
177
178 fieldset#filters, fieldset#date-range { padding: 0.7em; margin-bottom: 8px; }
178 fieldset#filters, fieldset#date-range { padding: 0.7em; margin-bottom: 8px; }
179 fieldset#filters p { margin: 1.2em 0 0.8em 2px; }
179 fieldset#filters p { margin: 1.2em 0 0.8em 2px; }
180 fieldset#filters table { border-collapse: collapse; }
180 fieldset#filters table { border-collapse: collapse; }
181 fieldset#filters table td { padding: 0; vertical-align: middle; }
181 fieldset#filters table td { padding: 0; vertical-align: middle; }
182 fieldset#filters tr.filter { height: 2em; }
182 fieldset#filters tr.filter { height: 2em; }
183 fieldset#filters td.add-filter { text-align: right; vertical-align: top; }
183 fieldset#filters td.add-filter { text-align: right; vertical-align: top; }
184 .buttons { font-size: 0.9em; }
184 .buttons { font-size: 0.9em; }
185
185
186 div#issue-changesets {float:right; width:45%; margin-left: 1em; margin-bottom: 1em; background: #fff; padding-left: 1em; font-size: 90%;}
186 div#issue-changesets {float:right; width:45%; margin-left: 1em; margin-bottom: 1em; background: #fff; padding-left: 1em; font-size: 90%;}
187 div#issue-changesets .changeset { padding: 4px;}
187 div#issue-changesets .changeset { padding: 4px;}
188 div#issue-changesets .changeset { border-bottom: 1px solid #ddd; }
188 div#issue-changesets .changeset { border-bottom: 1px solid #ddd; }
189 div#issue-changesets p { margin-top: 0; margin-bottom: 1em;}
189 div#issue-changesets p { margin-top: 0; margin-bottom: 1em;}
190
190
191 div#activity dl, #search-results { margin-left: 2em; }
191 div#activity dl, #search-results { margin-left: 2em; }
192 div#activity dd, #search-results dd { margin-bottom: 1em; padding-left: 18px; font-size: 0.9em; }
192 div#activity dd, #search-results dd { margin-bottom: 1em; padding-left: 18px; font-size: 0.9em; }
193 div#activity dt, #search-results dt { margin-bottom: 0px; padding-left: 20px; line-height: 18px; background-position: 0 50%; background-repeat: no-repeat; }
193 div#activity dt, #search-results dt { margin-bottom: 0px; padding-left: 20px; line-height: 18px; background-position: 0 50%; background-repeat: no-repeat; }
194 div#activity dt.me .time { border-bottom: 1px solid #999; }
194 div#activity dt.me .time { border-bottom: 1px solid #999; }
195 div#activity dt .time { color: #777; font-size: 80%; }
195 div#activity dt .time { color: #777; font-size: 80%; }
196 div#activity dd .description, #search-results dd .description { font-style: italic; }
196 div#activity dd .description, #search-results dd .description { font-style: italic; }
197 div#activity span.project:after, #search-results span.project:after { content: " -"; }
197 div#activity span.project:after, #search-results span.project:after { content: " -"; }
198 div#activity dd span.description, #search-results dd span.description { display:block; }
198 div#activity dd span.description, #search-results dd span.description { display:block; }
199
199
200 #search-results dd { margin-bottom: 1em; padding-left: 20px; margin-left:0px; }
200 #search-results dd { margin-bottom: 1em; padding-left: 20px; margin-left:0px; }
201
201
202 div#search-results-counts {float:right;}
202 div#search-results-counts {float:right;}
203 div#search-results-counts ul { margin-top: 0.5em; }
203 div#search-results-counts ul { margin-top: 0.5em; }
204 div#search-results-counts li { list-style-type:none; float: left; margin-left: 1em; }
204 div#search-results-counts li { list-style-type:none; float: left; margin-left: 1em; }
205
205
206 dt.issue { background-image: url(../images/ticket.png); }
206 dt.issue { background-image: url(../images/ticket.png); }
207 dt.issue-edit { background-image: url(../images/ticket_edit.png); }
207 dt.issue-edit { background-image: url(../images/ticket_edit.png); }
208 dt.issue-closed { background-image: url(../images/ticket_checked.png); }
208 dt.issue-closed { background-image: url(../images/ticket_checked.png); }
209 dt.issue-note { background-image: url(../images/ticket_note.png); }
209 dt.issue-note { background-image: url(../images/ticket_note.png); }
210 dt.changeset { background-image: url(../images/changeset.png); }
210 dt.changeset { background-image: url(../images/changeset.png); }
211 dt.news { background-image: url(../images/news.png); }
211 dt.news { background-image: url(../images/news.png); }
212 dt.message { background-image: url(../images/message.png); }
212 dt.message { background-image: url(../images/message.png); }
213 dt.reply { background-image: url(../images/comments.png); }
213 dt.reply { background-image: url(../images/comments.png); }
214 dt.wiki-page { background-image: url(../images/wiki_edit.png); }
214 dt.wiki-page { background-image: url(../images/wiki_edit.png); }
215 dt.attachment { background-image: url(../images/attachment.png); }
215 dt.attachment { background-image: url(../images/attachment.png); }
216 dt.document { background-image: url(../images/document.png); }
216 dt.document { background-image: url(../images/document.png); }
217 dt.project { background-image: url(../images/projects.png); }
217 dt.project { background-image: url(../images/projects.png); }
218
218
219 #search-results dt.issue.closed { background-image: url(../images/ticket_checked.png); }
219 #search-results dt.issue.closed { background-image: url(../images/ticket_checked.png); }
220
220
221 div#roadmap fieldset.related-issues { margin-bottom: 1em; }
221 div#roadmap fieldset.related-issues { margin-bottom: 1em; }
222 div#roadmap fieldset.related-issues ul { margin-top: 0.3em; margin-bottom: 0.3em; }
222 div#roadmap fieldset.related-issues ul { margin-top: 0.3em; margin-bottom: 0.3em; }
223 div#roadmap .wiki h1:first-child { display: none; }
223 div#roadmap .wiki h1:first-child { display: none; }
224 div#roadmap .wiki h1 { font-size: 120%; }
224 div#roadmap .wiki h1 { font-size: 120%; }
225 div#roadmap .wiki h2 { font-size: 110%; }
225 div#roadmap .wiki h2 { font-size: 110%; }
226
226
227 div#version-summary { float:right; width:380px; margin-left: 16px; margin-bottom: 16px; background-color: #fff; }
227 div#version-summary { float:right; width:380px; margin-left: 16px; margin-bottom: 16px; background-color: #fff; }
228 div#version-summary fieldset { margin-bottom: 1em; }
228 div#version-summary fieldset { margin-bottom: 1em; }
229 div#version-summary .total-hours { text-align: right; }
229 div#version-summary .total-hours { text-align: right; }
230
230
231 table#time-report td.hours, table#time-report th.period, table#time-report th.total { text-align: right; padding-right: 0.5em; }
231 table#time-report td.hours, table#time-report th.period, table#time-report th.total { text-align: right; padding-right: 0.5em; }
232 table#time-report tbody tr { font-style: italic; color: #777; }
232 table#time-report tbody tr { font-style: italic; color: #777; }
233 table#time-report tbody tr.last-level { font-style: normal; color: #555; }
233 table#time-report tbody tr.last-level { font-style: normal; color: #555; }
234 table#time-report tbody tr.total { font-style: normal; font-weight: bold; color: #555; background-color:#EEEEEE; }
234 table#time-report tbody tr.total { font-style: normal; font-weight: bold; color: #555; background-color:#EEEEEE; }
235 table#time-report .hours-dec { font-size: 0.9em; }
235 table#time-report .hours-dec { font-size: 0.9em; }
236
236
237 form#issue-form .attributes { margin-bottom: 8px; }
237 form#issue-form .attributes { margin-bottom: 8px; }
238 form#issue-form .attributes p { padding-top: 1px; padding-bottom: 2px; }
238 form#issue-form .attributes p { padding-top: 1px; padding-bottom: 2px; }
239 form#issue-form .attributes select { min-width: 30%; }
239 form#issue-form .attributes select { min-width: 30%; }
240
240
241 ul.projects { margin: 0; padding-left: 1em; }
241 ul.projects { margin: 0; padding-left: 1em; }
242 ul.projects.root { margin: 0; padding: 0; }
242 ul.projects.root { margin: 0; padding: 0; }
243 ul.projects ul { border-left: 3px solid #e0e0e0; }
243 ul.projects ul { border-left: 3px solid #e0e0e0; }
244 ul.projects li { list-style-type:none; }
244 ul.projects li { list-style-type:none; }
245 ul.projects li.root { margin-bottom: 1em; }
245 ul.projects li.root { margin-bottom: 1em; }
246 ul.projects li.child { margin-top: 1em;}
246 ul.projects li.child { margin-top: 1em;}
247 ul.projects div.root a.project { font-family: "Trebuchet MS", Verdana, sans-serif; font-weight: bold; font-size: 16px; margin: 0 0 10px 0; }
247 ul.projects div.root a.project { font-family: "Trebuchet MS", Verdana, sans-serif; font-weight: bold; font-size: 16px; margin: 0 0 10px 0; }
248 .my-project { padding-left: 18px; background: url(../images/fav.png) no-repeat 0 50%; }
248 .my-project { padding-left: 18px; background: url(../images/fav.png) no-repeat 0 50%; }
249
249
250 ul.properties {padding:0; font-size: 0.9em; color: #777;}
250 ul.properties {padding:0; font-size: 0.9em; color: #777;}
251 ul.properties li {list-style-type:none;}
251 ul.properties li {list-style-type:none;}
252 ul.properties li span {font-style:italic;}
252 ul.properties li span {font-style:italic;}
253
253
254 .total-hours { font-size: 110%; font-weight: bold; }
254 .total-hours { font-size: 110%; font-weight: bold; }
255 .total-hours span.hours-int { font-size: 120%; }
255 .total-hours span.hours-int { font-size: 120%; }
256
256
257 .autoscroll {overflow-x: auto; padding:1px; margin-bottom: 1.2em;}
257 .autoscroll {overflow-x: auto; padding:1px; margin-bottom: 1.2em;}
258 #user_firstname, #user_lastname, #user_mail, #my_account_form select { width: 90%; }
258 #user_firstname, #user_lastname, #user_mail, #my_account_form select { width: 90%; }
259
259
260 .pagination {font-size: 90%}
260 .pagination {font-size: 90%}
261 p.pagination {margin-top:8px;}
261 p.pagination {margin-top:8px;}
262
262
263 /***** Tabular forms ******/
263 /***** Tabular forms ******/
264 .tabular p{
264 .tabular p{
265 margin: 0;
265 margin: 0;
266 padding: 5px 0 8px 0;
266 padding: 5px 0 8px 0;
267 padding-left: 180px; /*width of left column containing the label elements*/
267 padding-left: 180px; /*width of left column containing the label elements*/
268 height: 1%;
268 height: 1%;
269 clear:left;
269 clear:left;
270 }
270 }
271
271
272 html>body .tabular p {overflow:hidden;}
272 html>body .tabular p {overflow:hidden;}
273
273
274 .tabular label{
274 .tabular label{
275 font-weight: bold;
275 font-weight: bold;
276 float: left;
276 float: left;
277 text-align: right;
277 text-align: right;
278 margin-left: -180px; /*width of left column*/
278 margin-left: -180px; /*width of left column*/
279 width: 175px; /*width of labels. Should be smaller than left column to create some right
279 width: 175px; /*width of labels. Should be smaller than left column to create some right
280 margin*/
280 margin*/
281 }
281 }
282
282
283 .tabular label.floating{
283 .tabular label.floating{
284 font-weight: normal;
284 font-weight: normal;
285 margin-left: 0px;
285 margin-left: 0px;
286 text-align: left;
286 text-align: left;
287 width: 270px;
287 width: 270px;
288 }
288 }
289
289
290 input#time_entry_comments { width: 90%;}
290 input#time_entry_comments { width: 90%;}
291
291
292 #preview fieldset {margin-top: 1em; background: url(../images/draft.png)}
292 #preview fieldset {margin-top: 1em; background: url(../images/draft.png)}
293
293
294 .tabular.settings p{ padding-left: 300px; }
294 .tabular.settings p{ padding-left: 300px; }
295 .tabular.settings label{ margin-left: -300px; width: 295px; }
295 .tabular.settings label{ margin-left: -300px; width: 295px; }
296
296
297 .required {color: #bb0000;}
297 .required {color: #bb0000;}
298 .summary {font-style: italic;}
298 .summary {font-style: italic;}
299
299
300 #attachments_fields input[type=text] {margin-left: 8px; }
300 #attachments_fields input[type=text] {margin-left: 8px; }
301
301
302 div.attachments { margin-top: 12px; }
302 div.attachments { margin-top: 12px; }
303 div.attachments p { margin:4px 0 2px 0; }
303 div.attachments p { margin:4px 0 2px 0; }
304 div.attachments img { vertical-align: middle; }
304 div.attachments img { vertical-align: middle; }
305 div.attachments span.author { font-size: 0.9em; color: #888; }
305 div.attachments span.author { font-size: 0.9em; color: #888; }
306
306
307 p.other-formats { text-align: right; font-size:0.9em; color: #666; }
307 p.other-formats { text-align: right; font-size:0.9em; color: #666; }
308 .other-formats span + span:before { content: "| "; }
308 .other-formats span + span:before { content: "| "; }
309
309
310 a.feed { background: url(../images/feed.png) no-repeat 1px 50%; padding: 2px 0px 3px 16px; }
310 a.atom { background: url(../images/feed.png) no-repeat 1px 50%; padding: 2px 0px 3px 16px; }
311
311
312 /***** Flash & error messages ****/
312 /***** Flash & error messages ****/
313 #errorExplanation, div.flash, .nodata, .warning {
313 #errorExplanation, div.flash, .nodata, .warning {
314 padding: 4px 4px 4px 30px;
314 padding: 4px 4px 4px 30px;
315 margin-bottom: 12px;
315 margin-bottom: 12px;
316 font-size: 1.1em;
316 font-size: 1.1em;
317 border: 2px solid;
317 border: 2px solid;
318 }
318 }
319
319
320 div.flash {margin-top: 8px;}
320 div.flash {margin-top: 8px;}
321
321
322 div.flash.error, #errorExplanation {
322 div.flash.error, #errorExplanation {
323 background: url(../images/false.png) 8px 5px no-repeat;
323 background: url(../images/false.png) 8px 5px no-repeat;
324 background-color: #ffe3e3;
324 background-color: #ffe3e3;
325 border-color: #dd0000;
325 border-color: #dd0000;
326 color: #550000;
326 color: #550000;
327 }
327 }
328
328
329 div.flash.notice {
329 div.flash.notice {
330 background: url(../images/true.png) 8px 5px no-repeat;
330 background: url(../images/true.png) 8px 5px no-repeat;
331 background-color: #dfffdf;
331 background-color: #dfffdf;
332 border-color: #9fcf9f;
332 border-color: #9fcf9f;
333 color: #005f00;
333 color: #005f00;
334 }
334 }
335
335
336 div.flash.warning {
336 div.flash.warning {
337 background: url(../images/warning.png) 8px 5px no-repeat;
337 background: url(../images/warning.png) 8px 5px no-repeat;
338 background-color: #FFEBC1;
338 background-color: #FFEBC1;
339 border-color: #FDBF3B;
339 border-color: #FDBF3B;
340 color: #A6750C;
340 color: #A6750C;
341 text-align: left;
341 text-align: left;
342 }
342 }
343
343
344 .nodata, .warning {
344 .nodata, .warning {
345 text-align: center;
345 text-align: center;
346 background-color: #FFEBC1;
346 background-color: #FFEBC1;
347 border-color: #FDBF3B;
347 border-color: #FDBF3B;
348 color: #A6750C;
348 color: #A6750C;
349 }
349 }
350
350
351 #errorExplanation ul { font-size: 0.9em;}
351 #errorExplanation ul { font-size: 0.9em;}
352
352
353 /***** Ajax indicator ******/
353 /***** Ajax indicator ******/
354 #ajax-indicator {
354 #ajax-indicator {
355 position: absolute; /* fixed not supported by IE */
355 position: absolute; /* fixed not supported by IE */
356 background-color:#eee;
356 background-color:#eee;
357 border: 1px solid #bbb;
357 border: 1px solid #bbb;
358 top:35%;
358 top:35%;
359 left:40%;
359 left:40%;
360 width:20%;
360 width:20%;
361 font-weight:bold;
361 font-weight:bold;
362 text-align:center;
362 text-align:center;
363 padding:0.6em;
363 padding:0.6em;
364 z-index:100;
364 z-index:100;
365 filter:alpha(opacity=50);
365 filter:alpha(opacity=50);
366 opacity: 0.5;
366 opacity: 0.5;
367 }
367 }
368
368
369 html>body #ajax-indicator { position: fixed; }
369 html>body #ajax-indicator { position: fixed; }
370
370
371 #ajax-indicator span {
371 #ajax-indicator span {
372 background-position: 0% 40%;
372 background-position: 0% 40%;
373 background-repeat: no-repeat;
373 background-repeat: no-repeat;
374 background-image: url(../images/loading.gif);
374 background-image: url(../images/loading.gif);
375 padding-left: 26px;
375 padding-left: 26px;
376 vertical-align: bottom;
376 vertical-align: bottom;
377 }
377 }
378
378
379 /***** Calendar *****/
379 /***** Calendar *****/
380 table.cal {border-collapse: collapse; width: 100%; margin: 0px 0 6px 0;border: 1px solid #d7d7d7;}
380 table.cal {border-collapse: collapse; width: 100%; margin: 0px 0 6px 0;border: 1px solid #d7d7d7;}
381 table.cal thead th {width: 14%;}
381 table.cal thead th {width: 14%;}
382 table.cal tbody tr {height: 100px;}
382 table.cal tbody tr {height: 100px;}
383 table.cal th { background-color:#EEEEEE; padding: 4px; }
383 table.cal th { background-color:#EEEEEE; padding: 4px; }
384 table.cal td {border: 1px solid #d7d7d7; vertical-align: top; font-size: 0.9em;}
384 table.cal td {border: 1px solid #d7d7d7; vertical-align: top; font-size: 0.9em;}
385 table.cal td p.day-num {font-size: 1.1em; text-align:right;}
385 table.cal td p.day-num {font-size: 1.1em; text-align:right;}
386 table.cal td.odd p.day-num {color: #bbb;}
386 table.cal td.odd p.day-num {color: #bbb;}
387 table.cal td.today {background:#ffffdd;}
387 table.cal td.today {background:#ffffdd;}
388 table.cal td.today p.day-num {font-weight: bold;}
388 table.cal td.today p.day-num {font-weight: bold;}
389
389
390 /***** Tooltips ******/
390 /***** Tooltips ******/
391 .tooltip{position:relative;z-index:24;}
391 .tooltip{position:relative;z-index:24;}
392 .tooltip:hover{z-index:25;color:#000;}
392 .tooltip:hover{z-index:25;color:#000;}
393 .tooltip span.tip{display: none; text-align:left;}
393 .tooltip span.tip{display: none; text-align:left;}
394
394
395 div.tooltip:hover span.tip{
395 div.tooltip:hover span.tip{
396 display:block;
396 display:block;
397 position:absolute;
397 position:absolute;
398 top:12px; left:24px; width:270px;
398 top:12px; left:24px; width:270px;
399 border:1px solid #555;
399 border:1px solid #555;
400 background-color:#fff;
400 background-color:#fff;
401 padding: 4px;
401 padding: 4px;
402 font-size: 0.8em;
402 font-size: 0.8em;
403 color:#505050;
403 color:#505050;
404 }
404 }
405
405
406 /***** Progress bar *****/
406 /***** Progress bar *****/
407 table.progress {
407 table.progress {
408 border: 1px solid #D7D7D7;
408 border: 1px solid #D7D7D7;
409 border-collapse: collapse;
409 border-collapse: collapse;
410 border-spacing: 0pt;
410 border-spacing: 0pt;
411 empty-cells: show;
411 empty-cells: show;
412 text-align: center;
412 text-align: center;
413 float:left;
413 float:left;
414 margin: 1px 6px 1px 0px;
414 margin: 1px 6px 1px 0px;
415 }
415 }
416
416
417 table.progress td { height: 0.9em; }
417 table.progress td { height: 0.9em; }
418 table.progress td.closed { background: #BAE0BA none repeat scroll 0%; }
418 table.progress td.closed { background: #BAE0BA none repeat scroll 0%; }
419 table.progress td.done { background: #DEF0DE none repeat scroll 0%; }
419 table.progress td.done { background: #DEF0DE none repeat scroll 0%; }
420 table.progress td.open { background: #FFF none repeat scroll 0%; }
420 table.progress td.open { background: #FFF none repeat scroll 0%; }
421 p.pourcent {font-size: 80%;}
421 p.pourcent {font-size: 80%;}
422 p.progress-info {clear: left; font-style: italic; font-size: 80%;}
422 p.progress-info {clear: left; font-style: italic; font-size: 80%;}
423
423
424 /***** Tabs *****/
424 /***** Tabs *****/
425 #content .tabs {height: 2.6em; border-bottom: 1px solid #bbbbbb; margin-bottom:1.2em; position:relative;}
425 #content .tabs {height: 2.6em; border-bottom: 1px solid #bbbbbb; margin-bottom:1.2em; position:relative;}
426 #content .tabs ul {margin:0; position:absolute; bottom:-2px; padding-left:1em;}
426 #content .tabs ul {margin:0; position:absolute; bottom:-2px; padding-left:1em;}
427 #content .tabs>ul { bottom:-1px; } /* others */
427 #content .tabs>ul { bottom:-1px; } /* others */
428 #content .tabs ul li {
428 #content .tabs ul li {
429 float:left;
429 float:left;
430 list-style-type:none;
430 list-style-type:none;
431 white-space:nowrap;
431 white-space:nowrap;
432 margin-right:8px;
432 margin-right:8px;
433 background:#fff;
433 background:#fff;
434 }
434 }
435 #content .tabs ul li a{
435 #content .tabs ul li a{
436 display:block;
436 display:block;
437 font-size: 0.9em;
437 font-size: 0.9em;
438 text-decoration:none;
438 text-decoration:none;
439 line-height:1.3em;
439 line-height:1.3em;
440 padding:4px 6px 4px 6px;
440 padding:4px 6px 4px 6px;
441 border: 1px solid #ccc;
441 border: 1px solid #ccc;
442 border-bottom: 1px solid #bbbbbb;
442 border-bottom: 1px solid #bbbbbb;
443 background-color: #eeeeee;
443 background-color: #eeeeee;
444 color:#777;
444 color:#777;
445 font-weight:bold;
445 font-weight:bold;
446 }
446 }
447
447
448 #content .tabs ul li a:hover {
448 #content .tabs ul li a:hover {
449 background-color: #ffffdd;
449 background-color: #ffffdd;
450 text-decoration:none;
450 text-decoration:none;
451 }
451 }
452
452
453 #content .tabs ul li a.selected {
453 #content .tabs ul li a.selected {
454 background-color: #fff;
454 background-color: #fff;
455 border: 1px solid #bbbbbb;
455 border: 1px solid #bbbbbb;
456 border-bottom: 1px solid #fff;
456 border-bottom: 1px solid #fff;
457 }
457 }
458
458
459 #content .tabs ul li a.selected:hover {
459 #content .tabs ul li a.selected:hover {
460 background-color: #fff;
460 background-color: #fff;
461 }
461 }
462
462
463 /***** Diff *****/
463 /***** Diff *****/
464 .diff_out { background: #fcc; }
464 .diff_out { background: #fcc; }
465 .diff_in { background: #cfc; }
465 .diff_in { background: #cfc; }
466
466
467 /***** Wiki *****/
467 /***** Wiki *****/
468 div.wiki table {
468 div.wiki table {
469 border: 1px solid #505050;
469 border: 1px solid #505050;
470 border-collapse: collapse;
470 border-collapse: collapse;
471 margin-bottom: 1em;
471 margin-bottom: 1em;
472 }
472 }
473
473
474 div.wiki table, div.wiki td, div.wiki th {
474 div.wiki table, div.wiki td, div.wiki th {
475 border: 1px solid #bbb;
475 border: 1px solid #bbb;
476 padding: 4px;
476 padding: 4px;
477 }
477 }
478
478
479 div.wiki .external {
479 div.wiki .external {
480 background-position: 0% 60%;
480 background-position: 0% 60%;
481 background-repeat: no-repeat;
481 background-repeat: no-repeat;
482 padding-left: 12px;
482 padding-left: 12px;
483 background-image: url(../images/external.png);
483 background-image: url(../images/external.png);
484 }
484 }
485
485
486 div.wiki a.new {
486 div.wiki a.new {
487 color: #b73535;
487 color: #b73535;
488 }
488 }
489
489
490 div.wiki pre {
490 div.wiki pre {
491 margin: 1em 1em 1em 1.6em;
491 margin: 1em 1em 1em 1.6em;
492 padding: 2px;
492 padding: 2px;
493 background-color: #fafafa;
493 background-color: #fafafa;
494 border: 1px solid #dadada;
494 border: 1px solid #dadada;
495 width:95%;
495 width:95%;
496 overflow-x: auto;
496 overflow-x: auto;
497 }
497 }
498
498
499 div.wiki ul.toc {
499 div.wiki ul.toc {
500 background-color: #ffffdd;
500 background-color: #ffffdd;
501 border: 1px solid #e4e4e4;
501 border: 1px solid #e4e4e4;
502 padding: 4px;
502 padding: 4px;
503 line-height: 1.2em;
503 line-height: 1.2em;
504 margin-bottom: 12px;
504 margin-bottom: 12px;
505 margin-right: 12px;
505 margin-right: 12px;
506 margin-left: 0;
506 margin-left: 0;
507 display: table
507 display: table
508 }
508 }
509 * html div.wiki ul.toc { width: 50%; } /* IE6 doesn't autosize div */
509 * html div.wiki ul.toc { width: 50%; } /* IE6 doesn't autosize div */
510
510
511 div.wiki ul.toc.right { float: right; margin-left: 12px; margin-right: 0; width: auto; }
511 div.wiki ul.toc.right { float: right; margin-left: 12px; margin-right: 0; width: auto; }
512 div.wiki ul.toc.left { float: left; margin-right: 12px; margin-left: 0; width: auto; }
512 div.wiki ul.toc.left { float: left; margin-right: 12px; margin-left: 0; width: auto; }
513 div.wiki ul.toc li { list-style-type:none;}
513 div.wiki ul.toc li { list-style-type:none;}
514 div.wiki ul.toc li.heading2 { margin-left: 6px; }
514 div.wiki ul.toc li.heading2 { margin-left: 6px; }
515 div.wiki ul.toc li.heading3 { margin-left: 12px; font-size: 0.8em; }
515 div.wiki ul.toc li.heading3 { margin-left: 12px; font-size: 0.8em; }
516
516
517 div.wiki ul.toc a {
517 div.wiki ul.toc a {
518 font-size: 0.9em;
518 font-size: 0.9em;
519 font-weight: normal;
519 font-weight: normal;
520 text-decoration: none;
520 text-decoration: none;
521 color: #606060;
521 color: #606060;
522 }
522 }
523 div.wiki ul.toc a:hover { color: #c61a1a; text-decoration: underline;}
523 div.wiki ul.toc a:hover { color: #c61a1a; text-decoration: underline;}
524
524
525 a.wiki-anchor { display: none; margin-left: 6px; text-decoration: none; }
525 a.wiki-anchor { display: none; margin-left: 6px; text-decoration: none; }
526 a.wiki-anchor:hover { color: #aaa !important; text-decoration: none; }
526 a.wiki-anchor:hover { color: #aaa !important; text-decoration: none; }
527 h1:hover a.wiki-anchor, h2:hover a.wiki-anchor, h3:hover a.wiki-anchor { display: inline; color: #ddd; }
527 h1:hover a.wiki-anchor, h2:hover a.wiki-anchor, h3:hover a.wiki-anchor { display: inline; color: #ddd; }
528
528
529 /***** My page layout *****/
529 /***** My page layout *****/
530 .block-receiver {
530 .block-receiver {
531 border:1px dashed #c0c0c0;
531 border:1px dashed #c0c0c0;
532 margin-bottom: 20px;
532 margin-bottom: 20px;
533 padding: 15px 0 15px 0;
533 padding: 15px 0 15px 0;
534 }
534 }
535
535
536 .mypage-box {
536 .mypage-box {
537 margin:0 0 20px 0;
537 margin:0 0 20px 0;
538 color:#505050;
538 color:#505050;
539 line-height:1.5em;
539 line-height:1.5em;
540 }
540 }
541
541
542 .handle {
542 .handle {
543 cursor: move;
543 cursor: move;
544 }
544 }
545
545
546 a.close-icon {
546 a.close-icon {
547 display:block;
547 display:block;
548 margin-top:3px;
548 margin-top:3px;
549 overflow:hidden;
549 overflow:hidden;
550 width:12px;
550 width:12px;
551 height:12px;
551 height:12px;
552 background-repeat: no-repeat;
552 background-repeat: no-repeat;
553 cursor:pointer;
553 cursor:pointer;
554 background-image:url('../images/close.png');
554 background-image:url('../images/close.png');
555 }
555 }
556
556
557 a.close-icon:hover {
557 a.close-icon:hover {
558 background-image:url('../images/close_hl.png');
558 background-image:url('../images/close_hl.png');
559 }
559 }
560
560
561 /***** Gantt chart *****/
561 /***** Gantt chart *****/
562 .gantt_hdr {
562 .gantt_hdr {
563 position:absolute;
563 position:absolute;
564 top:0;
564 top:0;
565 height:16px;
565 height:16px;
566 border-top: 1px solid #c0c0c0;
566 border-top: 1px solid #c0c0c0;
567 border-bottom: 1px solid #c0c0c0;
567 border-bottom: 1px solid #c0c0c0;
568 border-right: 1px solid #c0c0c0;
568 border-right: 1px solid #c0c0c0;
569 text-align: center;
569 text-align: center;
570 overflow: hidden;
570 overflow: hidden;
571 }
571 }
572
572
573 .task {
573 .task {
574 position: absolute;
574 position: absolute;
575 height:8px;
575 height:8px;
576 font-size:0.8em;
576 font-size:0.8em;
577 color:#888;
577 color:#888;
578 padding:0;
578 padding:0;
579 margin:0;
579 margin:0;
580 line-height:0.8em;
580 line-height:0.8em;
581 }
581 }
582
582
583 .task_late { background:#f66 url(../images/task_late.png); border: 1px solid #f66; }
583 .task_late { background:#f66 url(../images/task_late.png); border: 1px solid #f66; }
584 .task_done { background:#66f url(../images/task_done.png); border: 1px solid #66f; }
584 .task_done { background:#66f url(../images/task_done.png); border: 1px solid #66f; }
585 .task_todo { background:#aaa url(../images/task_todo.png); border: 1px solid #aaa; }
585 .task_todo { background:#aaa url(../images/task_todo.png); border: 1px solid #aaa; }
586 .milestone { background-image:url(../images/milestone.png); background-repeat: no-repeat; border: 0; }
586 .milestone { background-image:url(../images/milestone.png); background-repeat: no-repeat; border: 0; }
587
587
588 /***** Icons *****/
588 /***** Icons *****/
589 .icon {
589 .icon {
590 background-position: 0% 40%;
590 background-position: 0% 40%;
591 background-repeat: no-repeat;
591 background-repeat: no-repeat;
592 padding-left: 20px;
592 padding-left: 20px;
593 padding-top: 2px;
593 padding-top: 2px;
594 padding-bottom: 3px;
594 padding-bottom: 3px;
595 }
595 }
596
596
597 .icon22 {
597 .icon22 {
598 background-position: 0% 40%;
598 background-position: 0% 40%;
599 background-repeat: no-repeat;
599 background-repeat: no-repeat;
600 padding-left: 26px;
600 padding-left: 26px;
601 line-height: 22px;
601 line-height: 22px;
602 vertical-align: middle;
602 vertical-align: middle;
603 }
603 }
604
604
605 .icon-add { background-image: url(../images/add.png); }
605 .icon-add { background-image: url(../images/add.png); }
606 .icon-edit { background-image: url(../images/edit.png); }
606 .icon-edit { background-image: url(../images/edit.png); }
607 .icon-copy { background-image: url(../images/copy.png); }
607 .icon-copy { background-image: url(../images/copy.png); }
608 .icon-del { background-image: url(../images/delete.png); }
608 .icon-del { background-image: url(../images/delete.png); }
609 .icon-move { background-image: url(../images/move.png); }
609 .icon-move { background-image: url(../images/move.png); }
610 .icon-save { background-image: url(../images/save.png); }
610 .icon-save { background-image: url(../images/save.png); }
611 .icon-cancel { background-image: url(../images/cancel.png); }
611 .icon-cancel { background-image: url(../images/cancel.png); }
612 .icon-file { background-image: url(../images/file.png); }
612 .icon-file { background-image: url(../images/file.png); }
613 .icon-folder { background-image: url(../images/folder.png); }
613 .icon-folder { background-image: url(../images/folder.png); }
614 .open .icon-folder { background-image: url(../images/folder_open.png); }
614 .open .icon-folder { background-image: url(../images/folder_open.png); }
615 .icon-package { background-image: url(../images/package.png); }
615 .icon-package { background-image: url(../images/package.png); }
616 .icon-home { background-image: url(../images/home.png); }
616 .icon-home { background-image: url(../images/home.png); }
617 .icon-user { background-image: url(../images/user.png); }
617 .icon-user { background-image: url(../images/user.png); }
618 .icon-mypage { background-image: url(../images/user_page.png); }
618 .icon-mypage { background-image: url(../images/user_page.png); }
619 .icon-admin { background-image: url(../images/admin.png); }
619 .icon-admin { background-image: url(../images/admin.png); }
620 .icon-projects { background-image: url(../images/projects.png); }
620 .icon-projects { background-image: url(../images/projects.png); }
621 .icon-help { background-image: url(../images/help.png); }
621 .icon-help { background-image: url(../images/help.png); }
622 .icon-attachment { background-image: url(../images/attachment.png); }
622 .icon-attachment { background-image: url(../images/attachment.png); }
623 .icon-index { background-image: url(../images/index.png); }
623 .icon-index { background-image: url(../images/index.png); }
624 .icon-history { background-image: url(../images/history.png); }
624 .icon-history { background-image: url(../images/history.png); }
625 .icon-time { background-image: url(../images/time.png); }
625 .icon-time { background-image: url(../images/time.png); }
626 .icon-stats { background-image: url(../images/stats.png); }
626 .icon-stats { background-image: url(../images/stats.png); }
627 .icon-warning { background-image: url(../images/warning.png); }
627 .icon-warning { background-image: url(../images/warning.png); }
628 .icon-fav { background-image: url(../images/fav.png); }
628 .icon-fav { background-image: url(../images/fav.png); }
629 .icon-fav-off { background-image: url(../images/fav_off.png); }
629 .icon-fav-off { background-image: url(../images/fav_off.png); }
630 .icon-reload { background-image: url(../images/reload.png); }
630 .icon-reload { background-image: url(../images/reload.png); }
631 .icon-lock { background-image: url(../images/locked.png); }
631 .icon-lock { background-image: url(../images/locked.png); }
632 .icon-unlock { background-image: url(../images/unlock.png); }
632 .icon-unlock { background-image: url(../images/unlock.png); }
633 .icon-checked { background-image: url(../images/true.png); }
633 .icon-checked { background-image: url(../images/true.png); }
634 .icon-details { background-image: url(../images/zoom_in.png); }
634 .icon-details { background-image: url(../images/zoom_in.png); }
635 .icon-report { background-image: url(../images/report.png); }
635 .icon-report { background-image: url(../images/report.png); }
636 .icon-comment { background-image: url(../images/comment.png); }
636 .icon-comment { background-image: url(../images/comment.png); }
637
637
638 .icon22-projects { background-image: url(../images/22x22/projects.png); }
638 .icon22-projects { background-image: url(../images/22x22/projects.png); }
639 .icon22-users { background-image: url(../images/22x22/users.png); }
639 .icon22-users { background-image: url(../images/22x22/users.png); }
640 .icon22-tracker { background-image: url(../images/22x22/tracker.png); }
640 .icon22-tracker { background-image: url(../images/22x22/tracker.png); }
641 .icon22-role { background-image: url(../images/22x22/role.png); }
641 .icon22-role { background-image: url(../images/22x22/role.png); }
642 .icon22-workflow { background-image: url(../images/22x22/workflow.png); }
642 .icon22-workflow { background-image: url(../images/22x22/workflow.png); }
643 .icon22-options { background-image: url(../images/22x22/options.png); }
643 .icon22-options { background-image: url(../images/22x22/options.png); }
644 .icon22-notifications { background-image: url(../images/22x22/notifications.png); }
644 .icon22-notifications { background-image: url(../images/22x22/notifications.png); }
645 .icon22-authent { background-image: url(../images/22x22/authent.png); }
645 .icon22-authent { background-image: url(../images/22x22/authent.png); }
646 .icon22-info { background-image: url(../images/22x22/info.png); }
646 .icon22-info { background-image: url(../images/22x22/info.png); }
647 .icon22-comment { background-image: url(../images/22x22/comment.png); }
647 .icon22-comment { background-image: url(../images/22x22/comment.png); }
648 .icon22-package { background-image: url(../images/22x22/package.png); }
648 .icon22-package { background-image: url(../images/22x22/package.png); }
649 .icon22-settings { background-image: url(../images/22x22/settings.png); }
649 .icon22-settings { background-image: url(../images/22x22/settings.png); }
650 .icon22-plugin { background-image: url(../images/22x22/plugin.png); }
650 .icon22-plugin { background-image: url(../images/22x22/plugin.png); }
651
651
652 img.gravatar {
652 img.gravatar {
653 padding: 2px;
653 padding: 2px;
654 border: solid 1px #d5d5d5;
654 border: solid 1px #d5d5d5;
655 background: #fff;
655 background: #fff;
656 }
656 }
657
657
658 div.issue img.gravatar {
658 div.issue img.gravatar {
659 float: right;
659 float: right;
660 margin: 0 0 0 1em;
660 margin: 0 0 0 1em;
661 padding: 5px;
661 padding: 5px;
662 }
662 }
663
663
664 div.issue table img.gravatar {
664 div.issue table img.gravatar {
665 height: 14px;
665 height: 14px;
666 width: 14px;
666 width: 14px;
667 padding: 2px;
667 padding: 2px;
668 float: left;
668 float: left;
669 margin: 0 0.5em 0 0;
669 margin: 0 0.5em 0 0;
670 }
670 }
671
671
672 #history img.gravatar {
672 #history img.gravatar {
673 padding: 3px;
673 padding: 3px;
674 margin: 0 1.5em 1em 0;
674 margin: 0 1.5em 1em 0;
675 float: left;
675 float: left;
676 }
676 }
677
677
678 td.username img.gravatar {
678 td.username img.gravatar {
679 float: left;
679 float: left;
680 margin: 0 1em 0 0;
680 margin: 0 1em 0 0;
681 }
681 }
682
682
683 #activity dt img.gravatar {
683 #activity dt img.gravatar {
684 float: left;
684 float: left;
685 margin: 0 1em 1em 0;
685 margin: 0 1em 1em 0;
686 }
686 }
687
687
688 #activity dt,
688 #activity dt,
689 .journal {
689 .journal {
690 clear: left;
690 clear: left;
691 }
691 }
692
692
693 h2 img { vertical-align:middle; }
693 h2 img { vertical-align:middle; }
694
694
695
695
696 /***** Media print specific styles *****/
696 /***** Media print specific styles *****/
697 @media print {
697 @media print {
698 #top-menu, #header, #main-menu, #sidebar, #footer, .contextual, .other-formats { display:none; }
698 #top-menu, #header, #main-menu, #sidebar, #footer, .contextual, .other-formats { display:none; }
699 #main { background: #fff; }
699 #main { background: #fff; }
700 #content { width: 99%; margin: 0; padding: 0; border: 0; background: #fff; overflow: visible !important;}
700 #content { width: 99%; margin: 0; padding: 0; border: 0; background: #fff; overflow: visible !important;}
701 }
701 }
General Comments 0
You need to be logged in to leave comments. Login now