##// END OF EJS Templates
Added preview on add/edit issue form....
Jean-Philippe Lang -
r801:5259dec0611a
parent child
Show More
@@ -1,197 +1,204
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class IssuesController < ApplicationController
19 19 layout 'base', :except => :export_pdf
20 before_filter :find_project, :authorize, :except => :index
20 before_filter :find_project, :authorize, :except => [:index, :preview]
21 21 accept_key_auth :index
22 22
23 23 cache_sweeper :issue_sweeper, :only => [ :edit, :change_status, :destroy ]
24 24
25 25 helper :projects
26 26 include ProjectsHelper
27 27 helper :custom_fields
28 28 include CustomFieldsHelper
29 29 helper :ifpdf
30 30 include IfpdfHelper
31 31 helper :issue_relations
32 32 include IssueRelationsHelper
33 33 helper :watchers
34 34 include WatchersHelper
35 35 helper :attachments
36 36 include AttachmentsHelper
37 37 helper :queries
38 38 helper :sort
39 39 include SortHelper
40 40
41 41 def index
42 42 sort_init "#{Issue.table_name}.id", "desc"
43 43 sort_update
44 44 retrieve_query
45 45 if @query.valid?
46 46 @issue_count = Issue.count(:include => [:status, :project], :conditions => @query.statement)
47 47 @issue_pages = Paginator.new self, @issue_count, 25, params['page']
48 48 @issues = Issue.find :all, :order => sort_clause,
49 49 :include => [ :assigned_to, :status, :tracker, :project, :priority, :category ],
50 50 :conditions => @query.statement,
51 51 :limit => @issue_pages.items_per_page,
52 52 :offset => @issue_pages.current.offset
53 53 end
54 54 respond_to do |format|
55 55 format.html { render :layout => false if request.xhr? }
56 56 format.atom { render_feed(@issues, :title => l(:label_issue_plural)) }
57 57 end
58 58 end
59 59
60 60 def show
61 61 @custom_values = @issue.custom_values.find(:all, :include => :custom_field)
62 62 @journals = @issue.journals.find(:all, :include => [:user, :details], :order => "#{Journal.table_name}.created_on ASC")
63 63
64 64 if params[:format]=='pdf'
65 65 @options_for_rfpdf ||= {}
66 66 @options_for_rfpdf[:file_name] = "#{@project.identifier}-#{@issue.id}.pdf"
67 67 render :template => 'issues/show.rfpdf', :layout => false
68 68 else
69 69 @status_options = @issue.status.find_new_statuses_allowed_to(logged_in_user.role_for_project(@project), @issue.tracker) if logged_in_user
70 70 render :template => 'issues/show.rhtml'
71 71 end
72 72 end
73 73
74 74 def edit
75 75 @priorities = Enumeration::get_values('IPRI')
76 76 if request.get?
77 77 @custom_values = @project.custom_fields_for_issues(@issue.tracker).collect { |x| @issue.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x, :customized => @issue) }
78 78 else
79 79 begin
80 80 @issue.init_journal(self.logged_in_user)
81 81 # Retrieve custom fields and values
82 82 @custom_values = @project.custom_fields_for_issues(@issue.tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue, :value => params["custom_fields"][x.id.to_s]) }
83 83 @issue.custom_values = @custom_values
84 84 @issue.attributes = params[:issue]
85 85 if @issue.save
86 86 flash[:notice] = l(:notice_successful_update)
87 87 redirect_to :action => 'show', :id => @issue
88 88 end
89 89 rescue ActiveRecord::StaleObjectError
90 90 # Optimistic locking exception
91 91 flash[:error] = l(:notice_locking_conflict)
92 92 end
93 93 end
94 94 end
95 95
96 96 def add_note
97 97 unless params[:notes].empty?
98 98 journal = @issue.init_journal(self.logged_in_user, params[:notes])
99 99 if @issue.save
100 100 params[:attachments].each { |file|
101 101 next unless file.size > 0
102 102 a = Attachment.create(:container => @issue, :file => file, :author => logged_in_user)
103 103 journal.details << JournalDetail.new(:property => 'attachment',
104 104 :prop_key => a.id,
105 105 :value => a.filename) unless a.new_record?
106 106 } if params[:attachments] and params[:attachments].is_a? Array
107 107 flash[:notice] = l(:notice_successful_update)
108 108 Mailer.deliver_issue_edit(journal) if Setting.notified_events.include?('issue_updated')
109 109 redirect_to :action => 'show', :id => @issue
110 110 return
111 111 end
112 112 end
113 113 show
114 114 render :action => 'show'
115 115 end
116 116
117 117 def change_status
118 118 @status_options = @issue.status.find_new_statuses_allowed_to(logged_in_user.role_for_project(@project), @issue.tracker) if logged_in_user
119 119 @new_status = IssueStatus.find(params[:new_status_id])
120 120 if params[:confirm]
121 121 begin
122 122 journal = @issue.init_journal(self.logged_in_user, params[:notes])
123 123 @issue.status = @new_status
124 124 if @issue.update_attributes(params[:issue])
125 125 # Save attachments
126 126 params[:attachments].each { |file|
127 127 next unless file.size > 0
128 128 a = Attachment.create(:container => @issue, :file => file, :author => logged_in_user)
129 129 journal.details << JournalDetail.new(:property => 'attachment',
130 130 :prop_key => a.id,
131 131 :value => a.filename) unless a.new_record?
132 132 } if params[:attachments] and params[:attachments].is_a? Array
133 133
134 134 # Log time
135 135 if current_role.allowed_to?(:log_time)
136 136 @time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => logged_in_user, :spent_on => Date.today)
137 137 @time_entry.attributes = params[:time_entry]
138 138 @time_entry.save
139 139 end
140 140
141 141 flash[:notice] = l(:notice_successful_update)
142 142 Mailer.deliver_issue_edit(journal) if Setting.notified_events.include?('issue_updated')
143 143 redirect_to :action => 'show', :id => @issue
144 144 end
145 145 rescue ActiveRecord::StaleObjectError
146 146 # Optimistic locking exception
147 147 flash[:error] = l(:notice_locking_conflict)
148 148 end
149 149 end
150 150 @assignable_to = @project.members.find(:all, :include => :user).collect{ |m| m.user }
151 151 @activities = Enumeration::get_values('ACTI')
152 152 end
153 153
154 154 def destroy
155 155 @issue.destroy
156 156 redirect_to :controller => 'projects', :action => 'list_issues', :id => @project
157 157 end
158 158
159 159 def destroy_attachment
160 160 a = @issue.attachments.find(params[:attachment_id])
161 161 a.destroy
162 162 journal = @issue.init_journal(self.logged_in_user)
163 163 journal.details << JournalDetail.new(:property => 'attachment',
164 164 :prop_key => a.id,
165 165 :old_value => a.filename)
166 166 journal.save
167 167 redirect_to :action => 'show', :id => @issue
168 168 end
169 169
170 def preview
171 issue = Issue.find_by_id(params[:id])
172 @attachements = issue.attachments if issue
173 @text = params[:issue][:description]
174 render :partial => 'common/preview'
175 end
176
170 177 private
171 178 def find_project
172 179 @issue = Issue.find(params[:id], :include => [:project, :tracker, :status, :author, :priority, :category])
173 180 @project = @issue.project
174 181 rescue ActiveRecord::RecordNotFound
175 182 render_404
176 183 end
177 184
178 185 # Retrieve query from session or build a new query
179 186 def retrieve_query
180 187 if params[:set_filter] or !session[:query] or session[:query].project_id
181 188 # Give it a name, required to be valid
182 189 @query = Query.new(:name => "_", :executed_by => logged_in_user)
183 190 if params[:fields] and params[:fields].is_a? Array
184 191 params[:fields].each do |field|
185 192 @query.add_filter(field, params[:operators][field], params[:values][field])
186 193 end
187 194 else
188 195 @query.available_filters.keys.each do |field|
189 196 @query.add_short_filter(field, params[field]) if params[field]
190 197 end
191 198 end
192 199 session[:query] = @query
193 200 else
194 201 @query = session[:query]
195 202 end
196 203 end
197 204 end
@@ -1,175 +1,175
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require 'diff'
19 19
20 20 class WikiController < ApplicationController
21 21 layout 'base'
22 22 before_filter :find_wiki, :authorize
23 23
24 24 verify :method => :post, :only => [:destroy, :destroy_attachment], :redirect_to => { :action => :index }
25 25
26 26 helper :attachments
27 27 include AttachmentsHelper
28 28
29 29 # display a page (in editing mode if it doesn't exist)
30 30 def index
31 31 page_title = params[:page]
32 32 @page = @wiki.find_or_new_page(page_title)
33 33 if @page.new_record?
34 34 edit
35 35 render :action => 'edit' and return
36 36 end
37 37 @content = @page.content_for_version(params[:version])
38 38 if params[:export] == 'html'
39 39 export = render_to_string :action => 'export', :layout => false
40 40 send_data(export, :type => 'text/html', :filename => "#{@page.title}.html")
41 41 return
42 42 elsif params[:export] == 'txt'
43 43 send_data(@content.text, :type => 'text/plain', :filename => "#{@page.title}.txt")
44 44 return
45 45 end
46 46 render :action => 'show'
47 47 end
48 48
49 49 # edit an existing page or a new one
50 50 def edit
51 51 @page = @wiki.find_or_new_page(params[:page])
52 52 @page.content = WikiContent.new(:page => @page) if @page.new_record?
53 53
54 54 @content = @page.content_for_version(params[:version])
55 55 @content.text = "h1. #{@page.pretty_title}" if @content.text.blank?
56 56 # don't keep previous comment
57 57 @content.comments = nil
58 58 if request.post?
59 59 if !@page.new_record? && @content.text == params[:content][:text]
60 60 # don't save if text wasn't changed
61 61 redirect_to :action => 'index', :id => @project, :page => @page.title
62 62 return
63 63 end
64 64 #@content.text = params[:content][:text]
65 65 #@content.comments = params[:content][:comments]
66 66 @content.attributes = params[:content]
67 67 @content.author = logged_in_user
68 68 # if page is new @page.save will also save content, but not if page isn't a new record
69 69 if (@page.new_record? ? @page.save : @content.save)
70 70 redirect_to :action => 'index', :id => @project, :page => @page.title
71 71 end
72 72 end
73 73 rescue ActiveRecord::StaleObjectError
74 74 # Optimistic locking exception
75 75 flash[:error] = l(:notice_locking_conflict)
76 76 end
77 77
78 78 # rename a page
79 79 def rename
80 80 @page = @wiki.find_page(params[:page])
81 81 @page.redirect_existing_links = true
82 82 # used to display the *original* title if some AR validation errors occur
83 83 @original_title = @page.pretty_title
84 84 if request.post? && @page.update_attributes(params[:wiki_page])
85 85 flash[:notice] = l(:notice_successful_update)
86 86 redirect_to :action => 'index', :id => @project, :page => @page.title
87 87 end
88 88 end
89 89
90 90 # show page history
91 91 def history
92 92 @page = @wiki.find_page(params[:page])
93 93
94 94 @version_count = @page.content.versions.count
95 95 @version_pages = Paginator.new self, @version_count, 25, params['p']
96 96 # don't load text
97 97 @versions = @page.content.versions.find :all,
98 98 :select => "id, author_id, comments, updated_on, version",
99 99 :order => 'version DESC',
100 100 :limit => @version_pages.items_per_page + 1,
101 101 :offset => @version_pages.current.offset
102 102
103 103 render :layout => false if request.xhr?
104 104 end
105 105
106 106 def diff
107 107 @page = @wiki.find_page(params[:page])
108 108 @diff = @page.diff(params[:version], params[:version_from])
109 109 render_404 unless @diff
110 110 end
111 111
112 112 # remove a wiki page and its history
113 113 def destroy
114 114 @page = @wiki.find_page(params[:page])
115 115 @page.destroy if @page
116 116 redirect_to :action => 'special', :id => @project, :page => 'Page_index'
117 117 end
118 118
119 119 # display special pages
120 120 def special
121 121 page_title = params[:page].downcase
122 122 case page_title
123 123 # show pages index, sorted by title
124 124 when 'page_index', 'date_index'
125 125 # eager load information about last updates, without loading text
126 126 @pages = @wiki.pages.find :all, :select => "#{WikiPage.table_name}.*, #{WikiContent.table_name}.updated_on",
127 127 :joins => "LEFT JOIN #{WikiContent.table_name} ON #{WikiContent.table_name}.page_id = #{WikiPage.table_name}.id",
128 128 :order => 'title'
129 129 @pages_by_date = @pages.group_by {|p| p.updated_on.to_date}
130 130 # export wiki to a single html file
131 131 when 'export'
132 132 @pages = @wiki.pages.find :all, :order => 'title'
133 133 export = render_to_string :action => 'export_multiple', :layout => false
134 134 send_data(export, :type => 'text/html', :filename => "wiki.html")
135 135 return
136 136 else
137 137 # requested special page doesn't exist, redirect to default page
138 138 redirect_to :action => 'index', :id => @project, :page => nil and return
139 139 end
140 140 render :action => "special_#{page_title}"
141 141 end
142 142
143 143 def preview
144 144 page = @wiki.find_page(params[:page])
145 145 @attachements = page.attachments if page
146 146 @text = params[:content][:text]
147 render :partial => 'preview'
147 render :partial => 'common/preview'
148 148 end
149 149
150 150 def add_attachment
151 151 @page = @wiki.find_page(params[:page])
152 152 # Save the attachments
153 153 params[:attachments].each { |file|
154 154 next unless file.size > 0
155 155 a = Attachment.create(:container => @page, :file => file, :author => logged_in_user)
156 156 } if params[:attachments] and params[:attachments].is_a? Array
157 157 redirect_to :action => 'index', :page => @page.title
158 158 end
159 159
160 160 def destroy_attachment
161 161 @page = @wiki.find_page(params[:page])
162 162 @page.attachments.find(params[:attachment_id]).destroy
163 163 redirect_to :action => 'index', :page => @page.title
164 164 end
165 165
166 166 private
167 167
168 168 def find_wiki
169 169 @project = Project.find(params[:id])
170 170 @wiki = @project.wiki
171 171 render_404 unless @wiki
172 172 rescue ActiveRecord::RecordNotFound
173 173 render_404
174 174 end
175 175 end
1 NO CONTENT: file renamed from app/views/wiki/_preview.rhtml to app/views/common/_preview.rhtml
@@ -1,48 +1,52
1 1 <%= error_messages_for 'issue' %>
2 2 <div class="box">
3 3
4 4 <div class="splitcontentleft">
5 5 <% if @issue.new_record? %>
6 6 <p><%= f.select :status_id, (@allowed_statuses.collect {|p| [p.name, p.id]}), :required => true %></p>
7 7 <% else %>
8 8 <p><label><%= l(:field_status) %></label> <%= @issue.status.name %></p>
9 9 <% end %>
10 10
11 11 <p><%= f.select :priority_id, (@priorities.collect {|p| [p.name, p.id]}), :required => true %></p>
12 12 <p><%= f.select :assigned_to_id, (@issue.assignable_users.collect {|m| [m.name, m.id]}), :include_blank => true %></p>
13 13 <p><%= f.select :category_id, (@project.issue_categories.collect {|c| [c.name, c.id]}), :include_blank => true %>
14 14 <%= prompt_to_remote(l(:label_issue_category_new),
15 15 l(:label_issue_category_new), 'category[name]',
16 16 {:controller => 'projects', :action => 'add_issue_category', :id => @project},
17 17 :class => 'small') if authorize_for('projects', 'add_issue_category') %></p>
18 18 </div>
19 19
20 20 <div class="splitcontentright">
21 21 <p><%= f.text_field :start_date, :size => 10 %><%= calendar_for('issue_start_date') %></p>
22 22 <p><%= f.text_field :due_date, :size => 10 %><%= calendar_for('issue_due_date') %></p>
23 23 <p><%= f.text_field :estimated_hours, :size => 3 %> <%= l(:field_hours) %></p>
24 24 <p><%= f.select :done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %></p>
25 25 </div>
26 26
27 27 <p><%= f.text_field :subject, :size => 80, :required => true %></p>
28 <p><%= f.text_area :description, :required => true, :cols => 60, :rows => (@issue.description.blank? ? 10 : [[10, @issue.description.length / 50].max, 100].min), :class => 'wiki-edit' %></p>
28 <p><%= f.text_area :description, :required => true,
29 :cols => 60,
30 :rows => (@issue.description.blank? ? 10 : [[10, @issue.description.length / 50].max, 100].min),
31 :accesskey => accesskey(:edit),
32 :class => 'wiki-edit' %></p>
29 33 <p><%= f.select :fixed_version_id, (@project.versions.sort.collect {|v| [v.name, v.id]}), { :include_blank => true } %></p>
30 34 <% for @custom_value in @custom_values %>
31 35 <p><%= custom_field_tag_with_label @custom_value %></p>
32 36 <% end %>
33 37
34 38 <% if @issue.new_record? %>
35 39 <p id="attachments_p"><label for="attachment_file"><%=l(:label_attachment)%>
36 40 <%= image_to_function "add.png", "addFileField();return false" %></label>
37 41 <%= file_field_tag 'attachments[]', :size => 30 %> <em>(<%= l(:label_max_size) %>: <%= number_to_human_size(Setting.attachment_max_size.to_i.kilobytes) %>)</em></p>
38 42 <% end %>
39 43 </div>
40 44
41 45 <%= wikitoolbar_for 'issue_description' %>
42 46
43 47 <% content_for :header_tags do %>
44 48 <%= javascript_include_tag 'calendar/calendar' %>
45 49 <%= javascript_include_tag "calendar/lang/calendar-#{current_language}.js" %>
46 50 <%= javascript_include_tag 'calendar/calendar-setup' %>
47 51 <%= stylesheet_link_tag 'calendar' %>
48 52 <% end %>
@@ -1,7 +1,19
1 1 <h2><%=h "#{@issue.tracker.name} ##{@issue.id}" %></h2>
2 2
3 <% labelled_tabular_form_for :issue, @issue, :url => {:action => 'edit'} do |f| %>
3 <% labelled_tabular_form_for :issue, @issue,
4 :url => {:action => 'edit'},
5 :html => {:id => 'issue-form'} do |f| %>
4 6 <%= render :partial => 'form', :locals => {:f => f} %>
5 7 <%= f.hidden_field :lock_version %>
6 8 <%= submit_tag l(:button_save) %>
9 <%= link_to_remote l(:label_preview),
10 { :url => { :controller => 'issues', :action => 'preview', :id => @issue },
11 :method => 'post',
12 :update => 'preview',
13 :with => "Form.serialize('issue-form')",
14 :complete => "location.href='#preview-top'"
15 }, :accesskey => accesskey(:preview) %>
7 16 <% end %>
17
18 <a name="preview-top"></a>
19 <div id="preview" class="wiki"></div>
@@ -1,7 +1,19
1 1 <h2><%=l(:label_issue_new)%>: <%= @tracker.name %></h2>
2 2
3 <% labelled_tabular_form_for :issue, @issue, :url => {:action => 'add_issue'}, :html => {:multipart => true} do |f| %>
3 <% labelled_tabular_form_for :issue, @issue,
4 :url => {:action => 'add_issue'},
5 :html => {:multipart => true, :id => 'issue-form'} do |f| %>
4 6 <%= hidden_field_tag 'tracker_id', @tracker.id %>
5 7 <%= render :partial => 'issues/form', :locals => {:f => f} %>
6 8 <%= submit_tag l(:button_create) %>
9 <%= link_to_remote l(:label_preview),
10 { :url => { :controller => 'issues', :action => 'preview', :id => @issue },
11 :method => 'post',
12 :update => 'preview',
13 :with => "Form.serialize('issue-form')",
14 :complete => "location.href='#preview-top'"
15 }, :accesskey => accesskey(:preview) %>
7 16 <% end %>
17
18 <a name="preview-top"></a>
19 <div id="preview" class="wiki"></div>
@@ -1,465 +1,467
1 1 body { font-family: Verdana, sans-serif; font-size: 12px; color:#484848; margin: 0; padding: 0; min-width: 900px; }
2 2
3 3 h1, h2, h3, h4 { font-family: "Trebuchet MS", Verdana, sans-serif;}
4 4 h1 {margin:0; padding:0; font-size: 24px;}
5 5 h2, .wiki h1 {font-size: 20px;padding: 2px 10px 1px 0px;margin: 0 0 10px 0; border-bottom: 1px solid #bbbbbb; color: #444;}
6 6 h3, .wiki h2 {font-size: 16px;padding: 2px 10px 1px 0px;margin: 0 0 10px 0; border-bottom: 1px solid #bbbbbb; color: #444;}
7 7 h4, .wiki h3 {font-size: 12px;padding: 2px 10px 1px 0px;margin-bottom: 5px; border-bottom: 1px dotted #bbbbbb; color: #444;}
8 8
9 9 /***** Layout *****/
10 10 #top-menu {background: #2C4056;color: #fff;height:1.5em; padding: 2px 6px 0px 6px;}
11 11 #top-menu a {color: #fff; padding-right: 4px;}
12 12 #account {float:right;}
13 13
14 14 #header {height:5.3em;margin:0;background-color:#507AAA;color:#f8f8f8; padding: 4px 8px 0px 6px;}
15 15 #header a {color:#f8f8f8;}
16 16 #quick-search {float:right;}
17 17
18 18 #main-menu {position: absolute; top: 5.5em; left:6px;}
19 19 #main-menu ul {margin: 0; padding: 0;}
20 20 #main-menu li {
21 21 float:left;
22 22 list-style-type:none;
23 23 margin: 0px 10px 0px 0px;
24 24 padding: 0px 0px 0px 0px;
25 25 white-space:nowrap;
26 26 }
27 27 #main-menu li a {
28 28 display: block;
29 29 color: #fff;
30 30 text-decoration: none;
31 31 margin: 0;
32 32 padding: 4px 4px 4px 4px;
33 33 background: #2C4056;
34 34 }
35 35 #main-menu li a:hover {background:#759FCF;}
36 36
37 37 #main {background: url(../images/mainbg.png) repeat-x; background-color:#EEEEEE;}
38 38
39 39 #sidebar{ float: right; width: 17%; position: relative; z-index: 9; min-height: 600px; padding: 0; margin: 0;}
40 40 * html #sidebar{ width: 17%; }
41 41 #sidebar h3{ font-size: 14px; margin-top:14px; color: #666; }
42 42 #sidebar hr{ width: 100%; margin: 0 auto; height: 1px; background: #ccc; border: 0; }
43 43 * html #sidebar hr{ width: 95%; position: relative; left: -6px; color: #ccc; }
44 44
45 45 #content { width: 80%; background: url(../images/contentbg.png) repeat-x; background-color: #fff; margin: 0px; border-right: 1px solid #ddd; padding: 6px 10px 10px 10px; position: relative; z-index: 10; height:600px; min-height: 600px;}
46 46 * html #content{ width: 80%; padding-left: 0; margin-top: 0px; padding: 6px 10px 10px 10px;}
47 47 html>body #content {
48 48 height: auto;
49 49 min-height: 600px;
50 50 }
51 51
52 52 #main.nosidebar #sidebar{ display: none; }
53 53 #main.nosidebar #content{ width: auto; border-right: 0; }
54 54
55 55 #footer {clear: both; border-top: 1px solid #bbb; font-size: 0.9em; color: #aaa; padding: 5px; text-align:center; background:#fff;}
56 56
57 57 #login-form table {margin-top:5em; padding:1em; margin-left: auto; margin-right: auto; border: 2px solid #FDBF3B; background-color:#FFEBC1; }
58 58 #login-form table td {padding: 6px;}
59 59 #login-form label {font-weight: bold;}
60 60
61 61 .clear:after{ content: "."; display: block; height: 0; clear: both; visibility: hidden; }
62 62
63 63 /***** Links *****/
64 64 a, a:link, a:visited{ color: #2A5685; text-decoration: none; }
65 65 a:hover, a:active{ color: #c61a1a; text-decoration: underline;}
66 66 a img{ border: 0; }
67 67
68 68 /***** Tables *****/
69 69 table.list { border: 1px solid #e4e4e4; border-collapse: collapse; width: 100%; margin-bottom: 4px; }
70 70 table.list th { background-color:#EEEEEE; padding: 4px; white-space:nowrap; }
71 71 table.list td { overflow: hidden; text-overflow: ellipsis; vertical-align: top;}
72 72 table.list td.id { width: 2%; text-align: center;}
73 73 table.list td.checkbox { width: 15px; padding: 0px;}
74 74
75 75 tr.issue { text-align: center; white-space: nowrap; }
76 76 tr.issue td.subject, tr.issue td.category { white-space: normal; }
77 77 tr.issue td.subject { text-align: left; }
78 78
79 79 table.list tbody tr:hover { background-color:#ffffdd; }
80 80 table td {padding:2px;}
81 81 table p {margin:0;}
82 82 .odd {background-color:#f6f7f8;}
83 83 .even {background-color: #fff;}
84 84
85 85 .highlight { background-color: #FCFD8D;}
86 86
87 87 .box{
88 88 padding:6px;
89 89 margin-bottom: 10px;
90 90 background-color:#f6f6f6;
91 91 color:#505050;
92 92 line-height:1.5em;
93 93 border: 1px solid #e4e4e4;
94 94 }
95 95
96 96 div.square {
97 97 border: 1px solid #999;
98 98 float: left;
99 99 margin: .3em .4em 0 .4em;
100 100 overflow: hidden;
101 101 width: .6em; height: .6em;
102 102 }
103 103
104 104 .contextual {float:right; white-space: nowrap; line-height:1.4em;margin-top:5px;font-size:0.9em;}
105 105 .splitcontentleft{float:left; width:49%;}
106 106 .splitcontentright{float:right; width:49%;}
107 107 form {display: inline;}
108 108 input, select {vertical-align: middle; margin-top: 1px; margin-bottom: 1px;}
109 109 fieldset {border: 1px solid #e4e4e4; margin:0;}
110 110 legend {color: #484848;}
111 111 hr { width: 100%; height: 1px; background: #ccc; border: 0;}
112 112 textarea.wiki-edit { width: 99%; }
113 113 li p {margin-top: 0;}
114 114 div.issue {background:#ffffdd; padding:6px; margin-bottom:6px;border: 1px solid #d7d7d7;}
115 115 .autoscroll {overflow-x: auto; padding:1px; width:100%;}
116 116
117 117 /***** Tabular forms ******/
118 118 .tabular p{
119 119 margin: 0;
120 120 padding: 5px 0 8px 0;
121 121 padding-left: 180px; /*width of left column containing the label elements*/
122 122 height: 1%;
123 123 clear:left;
124 124 }
125 125
126 126 .tabular label{
127 127 font-weight: bold;
128 128 float: left;
129 129 text-align: right;
130 130 margin-left: -180px; /*width of left column*/
131 131 width: 175px; /*width of labels. Should be smaller than left column to create some right
132 132 margin*/
133 133 }
134 134
135 135 .tabular label.floating{
136 136 font-weight: normal;
137 137 margin-left: 0px;
138 138 text-align: left;
139 139 width: 200px;
140 140 }
141 141
142 #preview fieldset {margin-top: 1em; background: url(../images/draft.png)}
143
142 144 #settings .tabular p{ padding-left: 300px; }
143 145 #settings .tabular label{ margin-left: -300px; width: 295px; }
144 146
145 147 .required {color: #bb0000;}
146 148 .summary {font-style: italic;}
147 149
148 150 div.attachments p { margin:4px 0 2px 0; }
149 151
150 152 /***** Flash & error messages ****/
151 153 #flash div, #errorExplanation, .nodata {
152 154 padding: 4px 4px 4px 30px;
153 155 margin-bottom: 12px;
154 156 font-size: 1.1em;
155 157 border: 2px solid;
156 158 }
157 159
158 160 #flash div {margin-top: 6px;}
159 161
160 162 #flash div.error, #errorExplanation {
161 163 background: url(../images/false.png) 8px 5px no-repeat;
162 164 background-color: #ffe3e3;
163 165 border-color: #dd0000;
164 166 color: #550000;
165 167 }
166 168
167 169 #flash div.notice {
168 170 background: url(../images/true.png) 8px 5px no-repeat;
169 171 background-color: #dfffdf;
170 172 border-color: #9fcf9f;
171 173 color: #005f00;
172 174 }
173 175
174 176 .nodata {
175 177 text-align: center;
176 178 background-color: #FFEBC1;
177 179 border-color: #FDBF3B;
178 180 color: #A6750C;
179 181 }
180 182
181 183 #errorExplanation ul { font-size: 0.9em;}
182 184
183 185 /***** Ajax indicator ******/
184 186 #ajax-indicator {
185 187 position: absolute; /* fixed not supported by IE */
186 188 background-color:#eee;
187 189 border: 1px solid #bbb;
188 190 top:35%;
189 191 left:40%;
190 192 width:20%;
191 193 font-weight:bold;
192 194 text-align:center;
193 195 padding:0.6em;
194 196 z-index:100;
195 197 filter:alpha(opacity=50);
196 198 -moz-opacity:0.5;
197 199 opacity: 0.5;
198 200 -khtml-opacity: 0.5;
199 201 }
200 202
201 203 html>body #ajax-indicator { position: fixed; }
202 204
203 205 #ajax-indicator span {
204 206 background-position: 0% 40%;
205 207 background-repeat: no-repeat;
206 208 background-image: url(../images/loading.gif);
207 209 padding-left: 26px;
208 210 vertical-align: bottom;
209 211 }
210 212
211 213 /***** Calendar *****/
212 214 table.cal {border-collapse: collapse; width: 100%; margin: 8px 0 6px 0;border: 1px solid #d7d7d7;}
213 215 table.cal th { background-color:#EEEEEE; padding: 4px; }
214 216 table.cal td {border: 1px solid #d7d7d7;}
215 217 table.cal td.today {background:#ffffdd;}
216 218
217 219 /***** Tooltips ******/
218 220 .tooltip{position:relative;z-index:24;}
219 221 .tooltip:hover{z-index:25;color:#000;}
220 222 .tooltip span.tip{display: none; text-align:left;}
221 223
222 224 div.tooltip:hover span.tip{
223 225 display:block;
224 226 position:absolute;
225 227 top:12px; left:24px; width:270px;
226 228 border:1px solid #555;
227 229 background-color:#fff;
228 230 padding: 4px;
229 231 font-size: 0.8em;
230 232 color:#505050;
231 233 }
232 234
233 235 /***** Progress bar *****/
234 236 .progress {
235 237 border: 1px solid #D7D7D7;
236 238 border-collapse: collapse;
237 239 border-spacing: 0pt;
238 240 empty-cells: show;
239 241 padding: 3px;
240 242 width: 40em;
241 243 text-align: center;
242 244 }
243 245
244 246 .progress td { height: 1em; }
245 247 .progress .closed { background: #BAE0BA none repeat scroll 0%; }
246 248 .progress .open { background: #FFF none repeat scroll 0%; }
247 249
248 250 /***** Tabs *****/
249 251 #content .tabs{height: 2.6em;}
250 252 #content .tabs ul{margin:0;}
251 253 #content .tabs ul li{
252 254 float:left;
253 255 list-style-type:none;
254 256 white-space:nowrap;
255 257 margin-right:8px;
256 258 background:#fff;
257 259 }
258 260 #content .tabs ul li a{
259 261 display:block;
260 262 font-size: 0.9em;
261 263 text-decoration:none;
262 264 line-height:1em;
263 265 padding:4px;
264 266 border: 1px solid #c0c0c0;
265 267 }
266 268
267 269 #content .tabs ul li a.selected, #content .tabs ul li a:hover{
268 270 background-color: #507AAA;
269 271 border: 1px solid #507AAA;
270 272 color: #fff;
271 273 text-decoration:none;
272 274 }
273 275
274 276 /***** Diff *****/
275 277 .diff_out { background: #fcc; }
276 278 .diff_in { background: #cfc; }
277 279
278 280 /***** Wiki *****/
279 281 div.wiki table {
280 282 border: 1px solid #505050;
281 283 border-collapse: collapse;
282 284 }
283 285
284 286 div.wiki table, div.wiki td, div.wiki th {
285 287 border: 1px solid #bbb;
286 288 padding: 4px;
287 289 }
288 290
289 291 div.wiki .external {
290 292 background-position: 0% 60%;
291 293 background-repeat: no-repeat;
292 294 padding-left: 12px;
293 295 background-image: url(../images/external.png);
294 296 }
295 297
296 298 div.wiki a.new {
297 299 color: #b73535;
298 300 }
299 301
300 302 div.wiki pre {
301 303 margin: 1em 1em 1em 1.6em;
302 304 padding: 2px;
303 305 background-color: #fafafa;
304 306 border: 1px solid #dadada;
305 307 width:95%;
306 308 overflow-x: auto;
307 309 }
308 310
309 311 div.wiki div.toc {
310 312 background-color: #ffffdd;
311 313 border: 1px solid #e4e4e4;
312 314 padding: 4px;
313 315 line-height: 1.2em;
314 316 margin-bottom: 12px;
315 317 margin-right: 12px;
316 318 display: table
317 319 }
318 320 * html div.wiki div.toc { width: 50%; } /* IE6 doesn't autosize div */
319 321
320 322 div.wiki div.toc.right { float: right; margin-left: 12px; margin-right: 0; width: auto; }
321 323 div.wiki div.toc.left { float: left; margin-right: 12px; margin-left: 0; width: auto; }
322 324
323 325 div.wiki div.toc a {
324 326 display: block;
325 327 font-size: 0.9em;
326 328 font-weight: normal;
327 329 text-decoration: none;
328 330 color: #606060;
329 331 }
330 332 div.wiki div.toc a:hover { color: #c61a1a; text-decoration: underline;}
331 333
332 334 div.wiki div.toc a.heading2 { margin-left: 6px; }
333 335 div.wiki div.toc a.heading3 { margin-left: 12px; font-size: 0.8em; }
334 336
335 337 /***** My page layout *****/
336 338 .block-receiver {
337 339 border:1px dashed #c0c0c0;
338 340 margin-bottom: 20px;
339 341 padding: 15px 0 15px 0;
340 342 }
341 343
342 344 .mypage-box {
343 345 margin:0 0 20px 0;
344 346 color:#505050;
345 347 line-height:1.5em;
346 348 }
347 349
348 350 .handle {
349 351 cursor: move;
350 352 }
351 353
352 354 a.close-icon {
353 355 display:block;
354 356 margin-top:3px;
355 357 overflow:hidden;
356 358 width:12px;
357 359 height:12px;
358 360 background-repeat: no-repeat;
359 361 cursor:pointer;
360 362 background-image:url('../images/close.png');
361 363 }
362 364
363 365 a.close-icon:hover {
364 366 background-image:url('../images/close_hl.png');
365 367 }
366 368
367 369 /***** Gantt chart *****/
368 370 .gantt_hdr {
369 371 position:absolute;
370 372 top:0;
371 373 height:16px;
372 374 border-top: 1px solid #c0c0c0;
373 375 border-bottom: 1px solid #c0c0c0;
374 376 border-right: 1px solid #c0c0c0;
375 377 text-align: center;
376 378 overflow: hidden;
377 379 }
378 380
379 381 .task {
380 382 position: absolute;
381 383 height:8px;
382 384 font-size:0.8em;
383 385 color:#888;
384 386 padding:0;
385 387 margin:0;
386 388 line-height:0.8em;
387 389 }
388 390
389 391 .task_late { background:#f66 url(../images/task_late.png); border: 1px solid #f66; }
390 392 .task_done { background:#66f url(../images/task_done.png); border: 1px solid #66f; }
391 393 .task_todo { background:#aaa url(../images/task_todo.png); border: 1px solid #aaa; }
392 394 .milestone { background-image:url(../images/milestone.png); background-repeat: no-repeat; border: 0; }
393 395
394 396 /***** Icons *****/
395 397 .icon {
396 398 background-position: 0% 40%;
397 399 background-repeat: no-repeat;
398 400 padding-left: 20px;
399 401 padding-top: 2px;
400 402 padding-bottom: 3px;
401 403 }
402 404
403 405 .icon22 {
404 406 background-position: 0% 40%;
405 407 background-repeat: no-repeat;
406 408 padding-left: 26px;
407 409 line-height: 22px;
408 410 vertical-align: middle;
409 411 }
410 412
411 413 .icon-add { background-image: url(../images/add.png); }
412 414 .icon-edit { background-image: url(../images/edit.png); }
413 415 .icon-del { background-image: url(../images/delete.png); }
414 416 .icon-move { background-image: url(../images/move.png); }
415 417 .icon-save { background-image: url(../images/save.png); }
416 418 .icon-cancel { background-image: url(../images/cancel.png); }
417 419 .icon-pdf { background-image: url(../images/pdf.png); }
418 420 .icon-csv { background-image: url(../images/csv.png); }
419 421 .icon-html { background-image: url(../images/html.png); }
420 422 .icon-image { background-image: url(../images/image.png); }
421 423 .icon-txt { background-image: url(../images/txt.png); }
422 424 .icon-file { background-image: url(../images/file.png); }
423 425 .icon-folder { background-image: url(../images/folder.png); }
424 426 .icon-package { background-image: url(../images/package.png); }
425 427 .icon-home { background-image: url(../images/home.png); }
426 428 .icon-user { background-image: url(../images/user.png); }
427 429 .icon-mypage { background-image: url(../images/user_page.png); }
428 430 .icon-admin { background-image: url(../images/admin.png); }
429 431 .icon-projects { background-image: url(../images/projects.png); }
430 432 .icon-logout { background-image: url(../images/logout.png); }
431 433 .icon-help { background-image: url(../images/help.png); }
432 434 .icon-attachment { background-image: url(../images/attachment.png); }
433 435 .icon-index { background-image: url(../images/index.png); }
434 436 .icon-history { background-image: url(../images/history.png); }
435 437 .icon-feed { background-image: url(../images/feed.png); }
436 438 .icon-time { background-image: url(../images/time.png); }
437 439 .icon-stats { background-image: url(../images/stats.png); }
438 440 .icon-warning { background-image: url(../images/warning.png); }
439 441 .icon-fav { background-image: url(../images/fav.png); }
440 442 .icon-fav-off { background-image: url(../images/fav_off.png); }
441 443 .icon-reload { background-image: url(../images/reload.png); }
442 444 .icon-lock { background-image: url(../images/locked.png); }
443 445 .icon-unlock { background-image: url(../images/unlock.png); }
444 446 .icon-note { background-image: url(../images/note.png); }
445 447
446 448 .icon22-projects { background-image: url(../images/22x22/projects.png); }
447 449 .icon22-users { background-image: url(../images/22x22/users.png); }
448 450 .icon22-tracker { background-image: url(../images/22x22/tracker.png); }
449 451 .icon22-role { background-image: url(../images/22x22/role.png); }
450 452 .icon22-workflow { background-image: url(../images/22x22/workflow.png); }
451 453 .icon22-options { background-image: url(../images/22x22/options.png); }
452 454 .icon22-notifications { background-image: url(../images/22x22/notifications.png); }
453 455 .icon22-authent { background-image: url(../images/22x22/authent.png); }
454 456 .icon22-info { background-image: url(../images/22x22/info.png); }
455 457 .icon22-comment { background-image: url(../images/22x22/comment.png); }
456 458 .icon22-package { background-image: url(../images/22x22/package.png); }
457 459 .icon22-settings { background-image: url(../images/22x22/settings.png); }
458 460 .icon22-plugin { background-image: url(../images/22x22/plugin.png); }
459 461
460 462 /***** Media print specific styles *****/
461 463 @media print {
462 464 #top-menu, #header, #main-menu, #sidebar, #footer, .contextual { display:none; }
463 465 #main { background: #fff; }
464 466 #content { width: 99%; margin: 0; padding: 0; border: 0; background: #fff; }
465 467 }
General Comments 0
You need to be logged in to leave comments. Login now