##// END OF EJS Templates
Forum list can be reordered with drag and drop (#12909)....
Jean-Philippe Lang -
r14955:fb6b565a1ec9
parent child
Show More
@@ -1,111 +1,120
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2016 Jean-Philippe Lang
2 # Copyright (C) 2006-2016 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 class BoardsController < ApplicationController
18 class BoardsController < ApplicationController
19 default_search_scope :messages
19 default_search_scope :messages
20 before_filter :find_project_by_project_id, :find_board_if_available, :authorize
20 before_filter :find_project_by_project_id, :find_board_if_available, :authorize
21 accept_rss_auth :index, :show
21 accept_rss_auth :index, :show
22
22
23 helper :sort
23 helper :sort
24 include SortHelper
24 include SortHelper
25 helper :watchers
25 helper :watchers
26
26
27 def index
27 def index
28 @boards = @project.boards.preload(:project, :last_message => :author).to_a
28 @boards = @project.boards.preload(:project, :last_message => :author).to_a
29 # show the board if there is only one
29 # show the board if there is only one
30 if @boards.size == 1
30 if @boards.size == 1
31 @board = @boards.first
31 @board = @boards.first
32 show
32 show
33 end
33 end
34 end
34 end
35
35
36 def show
36 def show
37 respond_to do |format|
37 respond_to do |format|
38 format.html {
38 format.html {
39 sort_init 'updated_on', 'desc'
39 sort_init 'updated_on', 'desc'
40 sort_update 'created_on' => "#{Message.table_name}.created_on",
40 sort_update 'created_on' => "#{Message.table_name}.created_on",
41 'replies' => "#{Message.table_name}.replies_count",
41 'replies' => "#{Message.table_name}.replies_count",
42 'updated_on' => "COALESCE(last_replies_messages.created_on, #{Message.table_name}.created_on)"
42 'updated_on' => "COALESCE(last_replies_messages.created_on, #{Message.table_name}.created_on)"
43
43
44 @topic_count = @board.topics.count
44 @topic_count = @board.topics.count
45 @topic_pages = Paginator.new @topic_count, per_page_option, params['page']
45 @topic_pages = Paginator.new @topic_count, per_page_option, params['page']
46 @topics = @board.topics.
46 @topics = @board.topics.
47 reorder("#{Message.table_name}.sticky DESC").
47 reorder("#{Message.table_name}.sticky DESC").
48 joins("LEFT OUTER JOIN #{Message.table_name} last_replies_messages ON last_replies_messages.id = #{Message.table_name}.last_reply_id").
48 joins("LEFT OUTER JOIN #{Message.table_name} last_replies_messages ON last_replies_messages.id = #{Message.table_name}.last_reply_id").
49 limit(@topic_pages.per_page).
49 limit(@topic_pages.per_page).
50 offset(@topic_pages.offset).
50 offset(@topic_pages.offset).
51 order(sort_clause).
51 order(sort_clause).
52 preload(:author, {:last_reply => :author}).
52 preload(:author, {:last_reply => :author}).
53 to_a
53 to_a
54 @message = Message.new(:board => @board)
54 @message = Message.new(:board => @board)
55 render :action => 'show', :layout => !request.xhr?
55 render :action => 'show', :layout => !request.xhr?
56 }
56 }
57 format.atom {
57 format.atom {
58 @messages = @board.messages.
58 @messages = @board.messages.
59 reorder('created_on DESC').
59 reorder('created_on DESC').
60 includes(:author, :board).
60 includes(:author, :board).
61 limit(Setting.feeds_limit.to_i).
61 limit(Setting.feeds_limit.to_i).
62 to_a
62 to_a
63 render_feed(@messages, :title => "#{@project}: #{@board}")
63 render_feed(@messages, :title => "#{@project}: #{@board}")
64 }
64 }
65 end
65 end
66 end
66 end
67
67
68 def new
68 def new
69 @board = @project.boards.build
69 @board = @project.boards.build
70 @board.safe_attributes = params[:board]
70 @board.safe_attributes = params[:board]
71 end
71 end
72
72
73 def create
73 def create
74 @board = @project.boards.build
74 @board = @project.boards.build
75 @board.safe_attributes = params[:board]
75 @board.safe_attributes = params[:board]
76 if @board.save
76 if @board.save
77 flash[:notice] = l(:notice_successful_create)
77 flash[:notice] = l(:notice_successful_create)
78 redirect_to_settings_in_projects
78 redirect_to_settings_in_projects
79 else
79 else
80 render :action => 'new'
80 render :action => 'new'
81 end
81 end
82 end
82 end
83
83
84 def edit
84 def edit
85 end
85 end
86
86
87 def update
87 def update
88 @board.safe_attributes = params[:board]
88 @board.safe_attributes = params[:board]
89 if @board.save
89 if @board.save
90 redirect_to_settings_in_projects
90 respond_to do |format|
91 format.html {
92 flash[:notice] = l(:notice_successful_update)
93 redirect_to_settings_in_projects
94 }
95 format.js { render :nothing => true }
96 end
91 else
97 else
92 render :action => 'edit'
98 respond_to do |format|
99 format.html { render :action => 'edit' }
100 format.js { render :nothing => true, :status => 422 }
101 end
93 end
102 end
94 end
103 end
95
104
96 def destroy
105 def destroy
97 @board.destroy
106 @board.destroy
98 redirect_to_settings_in_projects
107 redirect_to_settings_in_projects
99 end
108 end
100
109
101 private
110 private
102 def redirect_to_settings_in_projects
111 def redirect_to_settings_in_projects
103 redirect_to settings_project_path(@project, :tab => 'boards')
112 redirect_to settings_project_path(@project, :tab => 'boards')
104 end
113 end
105
114
106 def find_board_if_available
115 def find_board_if_available
107 @board = @project.boards.find(params[:id]) if params[:id]
116 @board = @project.boards.find(params[:id]) if params[:id]
108 rescue ActiveRecord::RecordNotFound
117 rescue ActiveRecord::RecordNotFound
109 render_404
118 render_404
110 end
119 end
111 end
120 end
@@ -1,123 +1,136
1 # encoding: utf-8
1 # encoding: utf-8
2 #
2 #
3 # Redmine - project management software
3 # Redmine - project management software
4 # Copyright (C) 2006-2016 Jean-Philippe Lang
4 # Copyright (C) 2006-2016 Jean-Philippe Lang
5 #
5 #
6 # This program is free software; you can redistribute it and/or
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
9 # of the License, or (at your option) any later version.
10 #
10 #
11 # This program is distributed in the hope that it will be useful,
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
14 # GNU General Public License for more details.
15 #
15 #
16 # You should have received a copy of the GNU General Public License
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
19
20 module ProjectsHelper
20 module ProjectsHelper
21 def project_settings_tabs
21 def project_settings_tabs
22 tabs = [{:name => 'info', :action => :edit_project, :partial => 'projects/edit', :label => :label_information_plural},
22 tabs = [{:name => 'info', :action => :edit_project, :partial => 'projects/edit', :label => :label_information_plural},
23 {:name => 'modules', :action => :select_project_modules, :partial => 'projects/settings/modules', :label => :label_module_plural},
23 {:name => 'modules', :action => :select_project_modules, :partial => 'projects/settings/modules', :label => :label_module_plural},
24 {:name => 'members', :action => :manage_members, :partial => 'projects/settings/members', :label => :label_member_plural},
24 {:name => 'members', :action => :manage_members, :partial => 'projects/settings/members', :label => :label_member_plural},
25 {:name => 'versions', :action => :manage_versions, :partial => 'projects/settings/versions', :label => :label_version_plural},
25 {:name => 'versions', :action => :manage_versions, :partial => 'projects/settings/versions', :label => :label_version_plural},
26 {:name => 'categories', :action => :manage_categories, :partial => 'projects/settings/issue_categories', :label => :label_issue_category_plural},
26 {:name => 'categories', :action => :manage_categories, :partial => 'projects/settings/issue_categories', :label => :label_issue_category_plural},
27 {:name => 'wiki', :action => :manage_wiki, :partial => 'projects/settings/wiki', :label => :label_wiki},
27 {:name => 'wiki', :action => :manage_wiki, :partial => 'projects/settings/wiki', :label => :label_wiki},
28 {:name => 'repositories', :action => :manage_repository, :partial => 'projects/settings/repositories', :label => :label_repository_plural},
28 {:name => 'repositories', :action => :manage_repository, :partial => 'projects/settings/repositories', :label => :label_repository_plural},
29 {:name => 'boards', :action => :manage_boards, :partial => 'projects/settings/boards', :label => :label_board_plural},
29 {:name => 'boards', :action => :manage_boards, :partial => 'projects/settings/boards', :label => :label_board_plural},
30 {:name => 'activities', :action => :manage_project_activities, :partial => 'projects/settings/activities', :label => :enumeration_activities}
30 {:name => 'activities', :action => :manage_project_activities, :partial => 'projects/settings/activities', :label => :enumeration_activities}
31 ]
31 ]
32 tabs.select {|tab| User.current.allowed_to?(tab[:action], @project)}
32 tabs.select {|tab| User.current.allowed_to?(tab[:action], @project)}
33 end
33 end
34
34
35 def parent_project_select_tag(project)
35 def parent_project_select_tag(project)
36 selected = project.parent
36 selected = project.parent
37 # retrieve the requested parent project
37 # retrieve the requested parent project
38 parent_id = (params[:project] && params[:project][:parent_id]) || params[:parent_id]
38 parent_id = (params[:project] && params[:project][:parent_id]) || params[:parent_id]
39 if parent_id
39 if parent_id
40 selected = (parent_id.blank? ? nil : Project.find(parent_id))
40 selected = (parent_id.blank? ? nil : Project.find(parent_id))
41 end
41 end
42
42
43 options = ''
43 options = ''
44 options << "<option value=''>&nbsp;</option>" if project.allowed_parents.include?(nil)
44 options << "<option value=''>&nbsp;</option>" if project.allowed_parents.include?(nil)
45 options << project_tree_options_for_select(project.allowed_parents.compact, :selected => selected)
45 options << project_tree_options_for_select(project.allowed_parents.compact, :selected => selected)
46 content_tag('select', options.html_safe, :name => 'project[parent_id]', :id => 'project_parent_id')
46 content_tag('select', options.html_safe, :name => 'project[parent_id]', :id => 'project_parent_id')
47 end
47 end
48
48
49 def render_project_action_links
49 def render_project_action_links
50 links = []
50 links = []
51 if User.current.allowed_to?(:add_project, nil, :global => true)
51 if User.current.allowed_to?(:add_project, nil, :global => true)
52 links << link_to(l(:label_project_new), new_project_path, :class => 'icon icon-add')
52 links << link_to(l(:label_project_new), new_project_path, :class => 'icon icon-add')
53 end
53 end
54 if User.current.allowed_to?(:view_issues, nil, :global => true)
54 if User.current.allowed_to?(:view_issues, nil, :global => true)
55 links << link_to(l(:label_issue_view_all), issues_path)
55 links << link_to(l(:label_issue_view_all), issues_path)
56 end
56 end
57 if User.current.allowed_to?(:view_time_entries, nil, :global => true)
57 if User.current.allowed_to?(:view_time_entries, nil, :global => true)
58 links << link_to(l(:label_overall_spent_time), time_entries_path)
58 links << link_to(l(:label_overall_spent_time), time_entries_path)
59 end
59 end
60 links << link_to(l(:label_overall_activity), activity_path)
60 links << link_to(l(:label_overall_activity), activity_path)
61 links.join(" | ").html_safe
61 links.join(" | ").html_safe
62 end
62 end
63
63
64 # Renders the projects index
64 # Renders the projects index
65 def render_project_hierarchy(projects)
65 def render_project_hierarchy(projects)
66 render_project_nested_lists(projects) do |project|
66 render_project_nested_lists(projects) do |project|
67 s = link_to_project(project, {}, :class => "#{project.css_classes} #{User.current.member_of?(project) ? 'my-project' : nil}")
67 s = link_to_project(project, {}, :class => "#{project.css_classes} #{User.current.member_of?(project) ? 'my-project' : nil}")
68 if project.description.present?
68 if project.description.present?
69 s << content_tag('div', textilizable(project.short_description, :project => project), :class => 'wiki description')
69 s << content_tag('div', textilizable(project.short_description, :project => project), :class => 'wiki description')
70 end
70 end
71 s
71 s
72 end
72 end
73 end
73 end
74
74
75 # Returns a set of options for a select field, grouped by project.
75 # Returns a set of options for a select field, grouped by project.
76 def version_options_for_select(versions, selected=nil)
76 def version_options_for_select(versions, selected=nil)
77 grouped = Hash.new {|h,k| h[k] = []}
77 grouped = Hash.new {|h,k| h[k] = []}
78 versions.each do |version|
78 versions.each do |version|
79 grouped[version.project.name] << [version.name, version.id]
79 grouped[version.project.name] << [version.name, version.id]
80 end
80 end
81
81
82 selected = selected.is_a?(Version) ? selected.id : selected
82 selected = selected.is_a?(Version) ? selected.id : selected
83 if grouped.keys.size > 1
83 if grouped.keys.size > 1
84 grouped_options_for_select(grouped, selected)
84 grouped_options_for_select(grouped, selected)
85 else
85 else
86 options_for_select((grouped.values.first || []), selected)
86 options_for_select((grouped.values.first || []), selected)
87 end
87 end
88 end
88 end
89
89
90 def project_default_version_options(project)
90 def project_default_version_options(project)
91 versions = project.shared_versions.open.to_a
91 versions = project.shared_versions.open.to_a
92 if project.default_version && !versions.include?(project.default_version)
92 if project.default_version && !versions.include?(project.default_version)
93 versions << project.default_version
93 versions << project.default_version
94 end
94 end
95 version_options_for_select(versions, project.default_version)
95 version_options_for_select(versions, project.default_version)
96 end
96 end
97
97
98 def format_version_sharing(sharing)
98 def format_version_sharing(sharing)
99 sharing = 'none' unless Version::VERSION_SHARINGS.include?(sharing)
99 sharing = 'none' unless Version::VERSION_SHARINGS.include?(sharing)
100 l("label_version_sharing_#{sharing}")
100 l("label_version_sharing_#{sharing}")
101 end
101 end
102
102
103 def render_boards_tree(boards, parent=nil, level=0, &block)
104 selection = boards.select {|b| b.parent == parent}
105 return '' if selection.empty?
106
107 s = ''.html_safe
108 selection.each do |board|
109 node = capture(board, level, &block)
110 node << render_boards_tree(boards, board, level+1, &block)
111 s << content_tag('div', node)
112 end
113 content_tag('div', s, :class => 'sort-level')
114 end
115
103 def render_api_includes(project, api)
116 def render_api_includes(project, api)
104 api.array :trackers do
117 api.array :trackers do
105 project.trackers.each do |tracker|
118 project.trackers.each do |tracker|
106 api.tracker(:id => tracker.id, :name => tracker.name)
119 api.tracker(:id => tracker.id, :name => tracker.name)
107 end
120 end
108 end if include_in_api_response?('trackers')
121 end if include_in_api_response?('trackers')
109
122
110 api.array :issue_categories do
123 api.array :issue_categories do
111 project.issue_categories.each do |category|
124 project.issue_categories.each do |category|
112 api.issue_category(:id => category.id, :name => category.name)
125 api.issue_category(:id => category.id, :name => category.name)
113 end
126 end
114 end if include_in_api_response?('issue_categories')
127 end if include_in_api_response?('issue_categories')
115
128
116 api.array :enabled_modules do
129 api.array :enabled_modules do
117 project.enabled_modules.each do |enabled_module|
130 project.enabled_modules.each do |enabled_module|
118 api.enabled_module(:id => enabled_module.id, :name => enabled_module.name)
131 api.enabled_module(:id => enabled_module.id, :name => enabled_module.name)
119 end
132 end
120 end if include_in_api_response?('enabled_modules')
133 end if include_in_api_response?('enabled_modules')
121
134
122 end
135 end
123 end
136 end
@@ -1,69 +1,73
1 # encoding: utf-8
1 # encoding: utf-8
2 #
2 #
3 # Redmine - project management software
3 # Redmine - project management software
4 # Copyright (C) 2006-2016 Jean-Philippe Lang
4 # Copyright (C) 2006-2016 Jean-Philippe Lang
5 #
5 #
6 # This program is free software; you can redistribute it and/or
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
9 # of the License, or (at your option) any later version.
10 #
10 #
11 # This program is distributed in the hope that it will be useful,
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
14 # GNU General Public License for more details.
15 #
15 #
16 # You should have received a copy of the GNU General Public License
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
19
20 module RoutesHelper
20 module RoutesHelper
21
21
22 # Returns the path to project issues or to the cross-project
22 # Returns the path to project issues or to the cross-project
23 # issue list if project is nil
23 # issue list if project is nil
24 def _project_issues_path(project, *args)
24 def _project_issues_path(project, *args)
25 if project
25 if project
26 project_issues_path(project, *args)
26 project_issues_path(project, *args)
27 else
27 else
28 issues_path(*args)
28 issues_path(*args)
29 end
29 end
30 end
30 end
31
31
32 def _project_calendar_path(project, *args)
32 def _project_calendar_path(project, *args)
33 project ? project_calendar_path(project, *args) : issues_calendar_path(*args)
33 project ? project_calendar_path(project, *args) : issues_calendar_path(*args)
34 end
34 end
35
35
36 def _project_gantt_path(project, *args)
36 def _project_gantt_path(project, *args)
37 project ? project_gantt_path(project, *args) : issues_gantt_path(*args)
37 project ? project_gantt_path(project, *args) : issues_gantt_path(*args)
38 end
38 end
39
39
40 def _time_entries_path(project, issue, *args)
40 def _time_entries_path(project, issue, *args)
41 if issue
41 if issue
42 issue_time_entries_path(issue, *args)
42 issue_time_entries_path(issue, *args)
43 elsif project
43 elsif project
44 project_time_entries_path(project, *args)
44 project_time_entries_path(project, *args)
45 else
45 else
46 time_entries_path(*args)
46 time_entries_path(*args)
47 end
47 end
48 end
48 end
49
49
50 def _report_time_entries_path(project, issue, *args)
50 def _report_time_entries_path(project, issue, *args)
51 if issue
51 if issue
52 report_issue_time_entries_path(issue, *args)
52 report_issue_time_entries_path(issue, *args)
53 elsif project
53 elsif project
54 report_project_time_entries_path(project, *args)
54 report_project_time_entries_path(project, *args)
55 else
55 else
56 report_time_entries_path(*args)
56 report_time_entries_path(*args)
57 end
57 end
58 end
58 end
59
59
60 def _new_time_entry_path(project, issue, *args)
60 def _new_time_entry_path(project, issue, *args)
61 if issue
61 if issue
62 new_issue_time_entry_path(issue, *args)
62 new_issue_time_entry_path(issue, *args)
63 elsif project
63 elsif project
64 new_project_time_entry_path(project, *args)
64 new_project_time_entry_path(project, *args)
65 else
65 else
66 new_time_entry_path(*args)
66 new_time_entry_path(*args)
67 end
67 end
68 end
68 end
69
70 def board_path(board, *args)
71 project_board_path(board.project, board, *args)
72 end
69 end
73 end
@@ -1,96 +1,96
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2016 Jean-Philippe Lang
2 # Copyright (C) 2006-2016 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 class Board < ActiveRecord::Base
18 class Board < ActiveRecord::Base
19 include Redmine::SafeAttributes
19 include Redmine::SafeAttributes
20 belongs_to :project
20 belongs_to :project
21 has_many :messages, lambda {order("#{Message.table_name}.created_on DESC")}, :dependent => :destroy
21 has_many :messages, lambda {order("#{Message.table_name}.created_on DESC")}, :dependent => :destroy
22 belongs_to :last_message, :class_name => 'Message'
22 belongs_to :last_message, :class_name => 'Message'
23 acts_as_tree :dependent => :nullify
23 acts_as_tree :dependent => :nullify
24 acts_as_positioned :scope => [:project_id, :parent_id]
24 acts_as_positioned :scope => [:project_id, :parent_id]
25 acts_as_watchable
25 acts_as_watchable
26
26
27 validates_presence_of :name, :description
27 validates_presence_of :name, :description
28 validates_length_of :name, :maximum => 30
28 validates_length_of :name, :maximum => 30
29 validates_length_of :description, :maximum => 255
29 validates_length_of :description, :maximum => 255
30 validate :validate_board
30 validate :validate_board
31 attr_protected :id
31 attr_protected :id
32
32
33 scope :visible, lambda {|*args|
33 scope :visible, lambda {|*args|
34 joins(:project).
34 joins(:project).
35 where(Project.allowed_to_condition(args.shift || User.current, :view_messages, *args))
35 where(Project.allowed_to_condition(args.shift || User.current, :view_messages, *args))
36 }
36 }
37
37
38 safe_attributes 'name', 'description', 'parent_id', 'move_to'
38 safe_attributes 'name', 'description', 'parent_id', 'position'
39
39
40 def visible?(user=User.current)
40 def visible?(user=User.current)
41 !user.nil? && user.allowed_to?(:view_messages, project)
41 !user.nil? && user.allowed_to?(:view_messages, project)
42 end
42 end
43
43
44 def reload(*args)
44 def reload(*args)
45 @valid_parents = nil
45 @valid_parents = nil
46 super
46 super
47 end
47 end
48
48
49 def to_s
49 def to_s
50 name
50 name
51 end
51 end
52
52
53 # Returns a scope for the board topics (messages without parent)
53 # Returns a scope for the board topics (messages without parent)
54 def topics
54 def topics
55 messages.where(:parent_id => nil)
55 messages.where(:parent_id => nil)
56 end
56 end
57
57
58 def valid_parents
58 def valid_parents
59 @valid_parents ||= project.boards - self_and_descendants
59 @valid_parents ||= project.boards - self_and_descendants
60 end
60 end
61
61
62 def reset_counters!
62 def reset_counters!
63 self.class.reset_counters!(id)
63 self.class.reset_counters!(id)
64 end
64 end
65
65
66 # Updates topics_count, messages_count and last_message_id attributes for +board_id+
66 # Updates topics_count, messages_count and last_message_id attributes for +board_id+
67 def self.reset_counters!(board_id)
67 def self.reset_counters!(board_id)
68 board_id = board_id.to_i
68 board_id = board_id.to_i
69 Board.where(:id => board_id).
69 Board.where(:id => board_id).
70 update_all(["topics_count = (SELECT COUNT(*) FROM #{Message.table_name} WHERE board_id=:id AND parent_id IS NULL)," +
70 update_all(["topics_count = (SELECT COUNT(*) FROM #{Message.table_name} WHERE board_id=:id AND parent_id IS NULL)," +
71 " messages_count = (SELECT COUNT(*) FROM #{Message.table_name} WHERE board_id=:id)," +
71 " messages_count = (SELECT COUNT(*) FROM #{Message.table_name} WHERE board_id=:id)," +
72 " last_message_id = (SELECT MAX(id) FROM #{Message.table_name} WHERE board_id=:id)", :id => board_id])
72 " last_message_id = (SELECT MAX(id) FROM #{Message.table_name} WHERE board_id=:id)", :id => board_id])
73 end
73 end
74
74
75 def self.board_tree(boards, parent_id=nil, level=0)
75 def self.board_tree(boards, parent_id=nil, level=0)
76 tree = []
76 tree = []
77 boards.select {|board| board.parent_id == parent_id}.sort_by(&:position).each do |board|
77 boards.select {|board| board.parent_id == parent_id}.sort_by(&:position).each do |board|
78 tree << [board, level]
78 tree << [board, level]
79 tree += board_tree(boards, board.id, level+1)
79 tree += board_tree(boards, board.id, level+1)
80 end
80 end
81 if block_given?
81 if block_given?
82 tree.each do |board, level|
82 tree.each do |board, level|
83 yield board, level
83 yield board, level
84 end
84 end
85 end
85 end
86 tree
86 tree
87 end
87 end
88
88
89 protected
89 protected
90
90
91 def validate_board
91 def validate_board
92 if parent_id && parent_id_changed?
92 if parent_id && parent_id_changed?
93 errors.add(:parent_id, :invalid) unless valid_parents.include?(parent)
93 errors.add(:parent_id, :invalid) unless valid_parents.include?(parent)
94 end
94 end
95 end
95 end
96 end
96 end
@@ -1,36 +1,33
1 <% if @project.boards.any? %>
1 <% if @project.boards.any? %>
2 <table class="list">
2 <div class="table-list boards">
3 <thead><tr>
3 <div class="table-list-header">
4 <th><%= l(:label_board) %></th>
4 <div class="table-list-cell"><%= l(:label_board) %></div>
5 <th><%= l(:field_description) %></th>
5 </div>
6 <th></th>
6 <%= render_boards_tree(@project.boards) do |board, level| %>
7 <th></th>
7 <div class="table-list-row <%= cycle 'odd', 'even' %>">
8 </tr></thead>
8 <div class="table-list-cell name" style="padding-left: <%= 2 + level * 16 %>px">
9 <tbody>
9 <%= link_to board.name, project_board_path(@project, board) %>
10 <% Board.board_tree(@project.boards) do |board, level|
10 </div>
11 next if board.new_record? %>
11 <div class="table-list-cell description"><%= board.description %></div>
12 <tr class="<%= cycle 'odd', 'even' %>">
12 <div class="table-list-cell buttons">
13 <td class="name" style="padding-left: <%= level * 18 %>px;"><%= link_to board.name, project_board_path(@project, board) %></td>
14 <td class="description"><%= board.description %></td>
15 <td class="reorder">
16 <% if authorize_for("boards", "edit") %>
17 <%= reorder_links('board', {:controller => 'boards', :action => 'update', :project_id => @project, :id => board}, :put) %>
18 <% end %>
19 </td>
20 <td class="buttons">
21 <% if User.current.allowed_to?(:manage_boards, @project) %>
13 <% if User.current.allowed_to?(:manage_boards, @project) %>
14 <%= reorder_handle(board) %>
22 <%= link_to l(:button_edit), edit_project_board_path(@project, board), :class => 'icon icon-edit' %>
15 <%= link_to l(:button_edit), edit_project_board_path(@project, board), :class => 'icon icon-edit' %>
23 <%= delete_link project_board_path(@project, board) %>
16 <%= delete_link project_board_path(@project, board) %>
24 <% end %>
17 <% end %>
25 </td>
18 </div>
26 </tr>
19 </div>
20 <% end %>
21 </div>
22
23 <%= javascript_tag do %>
24 $(function() { $("div.sort-level").positionedItems(); });
27 <% end %>
25 <% end %>
28 </tbody>
26
29 </table>
30 <% else %>
27 <% else %>
31 <p class="nodata"><%= l(:label_no_data) %></p>
28 <p class="nodata"><%= l(:label_no_data) %></p>
32 <% end %>
29 <% end %>
33
30
34 <% if User.current.allowed_to?(:manage_boards, @project) %>
31 <% if User.current.allowed_to?(:manage_boards, @project) %>
35 <p><%= link_to l(:label_board_new), new_project_board_path(@project), :class => 'icon icon-add' %></p>
32 <p><%= link_to l(:label_board_new), new_project_board_path(@project), :class => 'icon icon-add' %></p>
36 <% end %>
33 <% end %>
@@ -1,742 +1,742
1 /* Redmine - project management software
1 /* Redmine - project management software
2 Copyright (C) 2006-2016 Jean-Philippe Lang */
2 Copyright (C) 2006-2016 Jean-Philippe Lang */
3
3
4 function checkAll(id, checked) {
4 function checkAll(id, checked) {
5 $('#'+id).find('input[type=checkbox]:enabled').prop('checked', checked);
5 $('#'+id).find('input[type=checkbox]:enabled').prop('checked', checked);
6 }
6 }
7
7
8 function toggleCheckboxesBySelector(selector) {
8 function toggleCheckboxesBySelector(selector) {
9 var all_checked = true;
9 var all_checked = true;
10 $(selector).each(function(index) {
10 $(selector).each(function(index) {
11 if (!$(this).is(':checked')) { all_checked = false; }
11 if (!$(this).is(':checked')) { all_checked = false; }
12 });
12 });
13 $(selector).prop('checked', !all_checked);
13 $(selector).prop('checked', !all_checked);
14 }
14 }
15
15
16 function showAndScrollTo(id, focus) {
16 function showAndScrollTo(id, focus) {
17 $('#'+id).show();
17 $('#'+id).show();
18 if (focus !== null) {
18 if (focus !== null) {
19 $('#'+focus).focus();
19 $('#'+focus).focus();
20 }
20 }
21 $('html, body').animate({scrollTop: $('#'+id).offset().top}, 100);
21 $('html, body').animate({scrollTop: $('#'+id).offset().top}, 100);
22 }
22 }
23
23
24 function toggleRowGroup(el) {
24 function toggleRowGroup(el) {
25 var tr = $(el).parents('tr').first();
25 var tr = $(el).parents('tr').first();
26 var n = tr.next();
26 var n = tr.next();
27 tr.toggleClass('open');
27 tr.toggleClass('open');
28 while (n.length && !n.hasClass('group')) {
28 while (n.length && !n.hasClass('group')) {
29 n.toggle();
29 n.toggle();
30 n = n.next('tr');
30 n = n.next('tr');
31 }
31 }
32 }
32 }
33
33
34 function collapseAllRowGroups(el) {
34 function collapseAllRowGroups(el) {
35 var tbody = $(el).parents('tbody').first();
35 var tbody = $(el).parents('tbody').first();
36 tbody.children('tr').each(function(index) {
36 tbody.children('tr').each(function(index) {
37 if ($(this).hasClass('group')) {
37 if ($(this).hasClass('group')) {
38 $(this).removeClass('open');
38 $(this).removeClass('open');
39 } else {
39 } else {
40 $(this).hide();
40 $(this).hide();
41 }
41 }
42 });
42 });
43 }
43 }
44
44
45 function expandAllRowGroups(el) {
45 function expandAllRowGroups(el) {
46 var tbody = $(el).parents('tbody').first();
46 var tbody = $(el).parents('tbody').first();
47 tbody.children('tr').each(function(index) {
47 tbody.children('tr').each(function(index) {
48 if ($(this).hasClass('group')) {
48 if ($(this).hasClass('group')) {
49 $(this).addClass('open');
49 $(this).addClass('open');
50 } else {
50 } else {
51 $(this).show();
51 $(this).show();
52 }
52 }
53 });
53 });
54 }
54 }
55
55
56 function toggleAllRowGroups(el) {
56 function toggleAllRowGroups(el) {
57 var tr = $(el).parents('tr').first();
57 var tr = $(el).parents('tr').first();
58 if (tr.hasClass('open')) {
58 if (tr.hasClass('open')) {
59 collapseAllRowGroups(el);
59 collapseAllRowGroups(el);
60 } else {
60 } else {
61 expandAllRowGroups(el);
61 expandAllRowGroups(el);
62 }
62 }
63 }
63 }
64
64
65 function toggleFieldset(el) {
65 function toggleFieldset(el) {
66 var fieldset = $(el).parents('fieldset').first();
66 var fieldset = $(el).parents('fieldset').first();
67 fieldset.toggleClass('collapsed');
67 fieldset.toggleClass('collapsed');
68 fieldset.children('div').toggle();
68 fieldset.children('div').toggle();
69 }
69 }
70
70
71 function hideFieldset(el) {
71 function hideFieldset(el) {
72 var fieldset = $(el).parents('fieldset').first();
72 var fieldset = $(el).parents('fieldset').first();
73 fieldset.toggleClass('collapsed');
73 fieldset.toggleClass('collapsed');
74 fieldset.children('div').hide();
74 fieldset.children('div').hide();
75 }
75 }
76
76
77 // columns selection
77 // columns selection
78 function moveOptions(theSelFrom, theSelTo) {
78 function moveOptions(theSelFrom, theSelTo) {
79 $(theSelFrom).find('option:selected').detach().prop("selected", false).appendTo($(theSelTo));
79 $(theSelFrom).find('option:selected').detach().prop("selected", false).appendTo($(theSelTo));
80 }
80 }
81
81
82 function moveOptionUp(theSel) {
82 function moveOptionUp(theSel) {
83 $(theSel).find('option:selected').each(function(){
83 $(theSel).find('option:selected').each(function(){
84 $(this).prev(':not(:selected)').detach().insertAfter($(this));
84 $(this).prev(':not(:selected)').detach().insertAfter($(this));
85 });
85 });
86 }
86 }
87
87
88 function moveOptionTop(theSel) {
88 function moveOptionTop(theSel) {
89 $(theSel).find('option:selected').detach().prependTo($(theSel));
89 $(theSel).find('option:selected').detach().prependTo($(theSel));
90 }
90 }
91
91
92 function moveOptionDown(theSel) {
92 function moveOptionDown(theSel) {
93 $($(theSel).find('option:selected').get().reverse()).each(function(){
93 $($(theSel).find('option:selected').get().reverse()).each(function(){
94 $(this).next(':not(:selected)').detach().insertBefore($(this));
94 $(this).next(':not(:selected)').detach().insertBefore($(this));
95 });
95 });
96 }
96 }
97
97
98 function moveOptionBottom(theSel) {
98 function moveOptionBottom(theSel) {
99 $(theSel).find('option:selected').detach().appendTo($(theSel));
99 $(theSel).find('option:selected').detach().appendTo($(theSel));
100 }
100 }
101
101
102 function initFilters() {
102 function initFilters() {
103 $('#add_filter_select').change(function() {
103 $('#add_filter_select').change(function() {
104 addFilter($(this).val(), '', []);
104 addFilter($(this).val(), '', []);
105 });
105 });
106 $('#filters-table td.field input[type=checkbox]').each(function() {
106 $('#filters-table td.field input[type=checkbox]').each(function() {
107 toggleFilter($(this).val());
107 toggleFilter($(this).val());
108 });
108 });
109 $('#filters-table').on('click', 'td.field input[type=checkbox]', function() {
109 $('#filters-table').on('click', 'td.field input[type=checkbox]', function() {
110 toggleFilter($(this).val());
110 toggleFilter($(this).val());
111 });
111 });
112 $('#filters-table').on('click', '.toggle-multiselect', function() {
112 $('#filters-table').on('click', '.toggle-multiselect', function() {
113 toggleMultiSelect($(this).siblings('select'));
113 toggleMultiSelect($(this).siblings('select'));
114 });
114 });
115 $('#filters-table').on('keypress', 'input[type=text]', function(e) {
115 $('#filters-table').on('keypress', 'input[type=text]', function(e) {
116 if (e.keyCode == 13) $(this).closest('form').submit();
116 if (e.keyCode == 13) $(this).closest('form').submit();
117 });
117 });
118 }
118 }
119
119
120 function addFilter(field, operator, values) {
120 function addFilter(field, operator, values) {
121 var fieldId = field.replace('.', '_');
121 var fieldId = field.replace('.', '_');
122 var tr = $('#tr_'+fieldId);
122 var tr = $('#tr_'+fieldId);
123 if (tr.length > 0) {
123 if (tr.length > 0) {
124 tr.show();
124 tr.show();
125 } else {
125 } else {
126 buildFilterRow(field, operator, values);
126 buildFilterRow(field, operator, values);
127 }
127 }
128 $('#cb_'+fieldId).prop('checked', true);
128 $('#cb_'+fieldId).prop('checked', true);
129 toggleFilter(field);
129 toggleFilter(field);
130 $('#add_filter_select').val('').find('option').each(function() {
130 $('#add_filter_select').val('').find('option').each(function() {
131 if ($(this).attr('value') == field) {
131 if ($(this).attr('value') == field) {
132 $(this).attr('disabled', true);
132 $(this).attr('disabled', true);
133 }
133 }
134 });
134 });
135 }
135 }
136
136
137 function buildFilterRow(field, operator, values) {
137 function buildFilterRow(field, operator, values) {
138 var fieldId = field.replace('.', '_');
138 var fieldId = field.replace('.', '_');
139 var filterTable = $("#filters-table");
139 var filterTable = $("#filters-table");
140 var filterOptions = availableFilters[field];
140 var filterOptions = availableFilters[field];
141 if (!filterOptions) return;
141 if (!filterOptions) return;
142 var operators = operatorByType[filterOptions['type']];
142 var operators = operatorByType[filterOptions['type']];
143 var filterValues = filterOptions['values'];
143 var filterValues = filterOptions['values'];
144 var i, select;
144 var i, select;
145
145
146 var tr = $('<tr class="filter">').attr('id', 'tr_'+fieldId).html(
146 var tr = $('<tr class="filter">').attr('id', 'tr_'+fieldId).html(
147 '<td class="field"><input checked="checked" id="cb_'+fieldId+'" name="f[]" value="'+field+'" type="checkbox"><label for="cb_'+fieldId+'"> '+filterOptions['name']+'</label></td>' +
147 '<td class="field"><input checked="checked" id="cb_'+fieldId+'" name="f[]" value="'+field+'" type="checkbox"><label for="cb_'+fieldId+'"> '+filterOptions['name']+'</label></td>' +
148 '<td class="operator"><select id="operators_'+fieldId+'" name="op['+field+']"></td>' +
148 '<td class="operator"><select id="operators_'+fieldId+'" name="op['+field+']"></td>' +
149 '<td class="values"></td>'
149 '<td class="values"></td>'
150 );
150 );
151 filterTable.append(tr);
151 filterTable.append(tr);
152
152
153 select = tr.find('td.operator select');
153 select = tr.find('td.operator select');
154 for (i = 0; i < operators.length; i++) {
154 for (i = 0; i < operators.length; i++) {
155 var option = $('<option>').val(operators[i]).text(operatorLabels[operators[i]]);
155 var option = $('<option>').val(operators[i]).text(operatorLabels[operators[i]]);
156 if (operators[i] == operator) { option.attr('selected', true); }
156 if (operators[i] == operator) { option.attr('selected', true); }
157 select.append(option);
157 select.append(option);
158 }
158 }
159 select.change(function(){ toggleOperator(field); });
159 select.change(function(){ toggleOperator(field); });
160
160
161 switch (filterOptions['type']) {
161 switch (filterOptions['type']) {
162 case "list":
162 case "list":
163 case "list_optional":
163 case "list_optional":
164 case "list_status":
164 case "list_status":
165 case "list_subprojects":
165 case "list_subprojects":
166 tr.find('td.values').append(
166 tr.find('td.values').append(
167 '<span style="display:none;"><select class="value" id="values_'+fieldId+'_1" name="v['+field+'][]"></select>' +
167 '<span style="display:none;"><select class="value" id="values_'+fieldId+'_1" name="v['+field+'][]"></select>' +
168 ' <span class="toggle-multiselect">&nbsp;</span></span>'
168 ' <span class="toggle-multiselect">&nbsp;</span></span>'
169 );
169 );
170 select = tr.find('td.values select');
170 select = tr.find('td.values select');
171 if (values.length > 1) { select.attr('multiple', true); }
171 if (values.length > 1) { select.attr('multiple', true); }
172 for (i = 0; i < filterValues.length; i++) {
172 for (i = 0; i < filterValues.length; i++) {
173 var filterValue = filterValues[i];
173 var filterValue = filterValues[i];
174 var option = $('<option>');
174 var option = $('<option>');
175 if ($.isArray(filterValue)) {
175 if ($.isArray(filterValue)) {
176 option.val(filterValue[1]).text(filterValue[0]);
176 option.val(filterValue[1]).text(filterValue[0]);
177 if ($.inArray(filterValue[1], values) > -1) {option.attr('selected', true);}
177 if ($.inArray(filterValue[1], values) > -1) {option.attr('selected', true);}
178 } else {
178 } else {
179 option.val(filterValue).text(filterValue);
179 option.val(filterValue).text(filterValue);
180 if ($.inArray(filterValue, values) > -1) {option.attr('selected', true);}
180 if ($.inArray(filterValue, values) > -1) {option.attr('selected', true);}
181 }
181 }
182 select.append(option);
182 select.append(option);
183 }
183 }
184 break;
184 break;
185 case "date":
185 case "date":
186 case "date_past":
186 case "date_past":
187 tr.find('td.values').append(
187 tr.find('td.values').append(
188 '<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_1" size="10" class="value date_value" /></span>' +
188 '<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_1" size="10" class="value date_value" /></span>' +
189 ' <span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_2" size="10" class="value date_value" /></span>' +
189 ' <span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_2" size="10" class="value date_value" /></span>' +
190 ' <span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'" size="3" class="value" /> '+labelDayPlural+'</span>'
190 ' <span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'" size="3" class="value" /> '+labelDayPlural+'</span>'
191 );
191 );
192 $('#values_'+fieldId+'_1').val(values[0]).datepicker(datepickerOptions);
192 $('#values_'+fieldId+'_1').val(values[0]).datepicker(datepickerOptions);
193 $('#values_'+fieldId+'_2').val(values[1]).datepicker(datepickerOptions);
193 $('#values_'+fieldId+'_2').val(values[1]).datepicker(datepickerOptions);
194 $('#values_'+fieldId).val(values[0]);
194 $('#values_'+fieldId).val(values[0]);
195 break;
195 break;
196 case "string":
196 case "string":
197 case "text":
197 case "text":
198 tr.find('td.values').append(
198 tr.find('td.values').append(
199 '<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'" size="30" class="value" /></span>'
199 '<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'" size="30" class="value" /></span>'
200 );
200 );
201 $('#values_'+fieldId).val(values[0]);
201 $('#values_'+fieldId).val(values[0]);
202 break;
202 break;
203 case "relation":
203 case "relation":
204 tr.find('td.values').append(
204 tr.find('td.values').append(
205 '<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'" size="6" class="value" /></span>' +
205 '<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'" size="6" class="value" /></span>' +
206 '<span style="display:none;"><select class="value" name="v['+field+'][]" id="values_'+fieldId+'_1"></select></span>'
206 '<span style="display:none;"><select class="value" name="v['+field+'][]" id="values_'+fieldId+'_1"></select></span>'
207 );
207 );
208 $('#values_'+fieldId).val(values[0]);
208 $('#values_'+fieldId).val(values[0]);
209 select = tr.find('td.values select');
209 select = tr.find('td.values select');
210 for (i = 0; i < allProjects.length; i++) {
210 for (i = 0; i < allProjects.length; i++) {
211 var filterValue = allProjects[i];
211 var filterValue = allProjects[i];
212 var option = $('<option>');
212 var option = $('<option>');
213 option.val(filterValue[1]).text(filterValue[0]);
213 option.val(filterValue[1]).text(filterValue[0]);
214 if (values[0] == filterValue[1]) { option.attr('selected', true); }
214 if (values[0] == filterValue[1]) { option.attr('selected', true); }
215 select.append(option);
215 select.append(option);
216 }
216 }
217 break;
217 break;
218 case "integer":
218 case "integer":
219 case "float":
219 case "float":
220 case "tree":
220 case "tree":
221 tr.find('td.values').append(
221 tr.find('td.values').append(
222 '<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_1" size="6" class="value" /></span>' +
222 '<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_1" size="6" class="value" /></span>' +
223 ' <span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_2" size="6" class="value" /></span>'
223 ' <span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_2" size="6" class="value" /></span>'
224 );
224 );
225 $('#values_'+fieldId+'_1').val(values[0]);
225 $('#values_'+fieldId+'_1').val(values[0]);
226 $('#values_'+fieldId+'_2').val(values[1]);
226 $('#values_'+fieldId+'_2').val(values[1]);
227 break;
227 break;
228 }
228 }
229 }
229 }
230
230
231 function toggleFilter(field) {
231 function toggleFilter(field) {
232 var fieldId = field.replace('.', '_');
232 var fieldId = field.replace('.', '_');
233 if ($('#cb_' + fieldId).is(':checked')) {
233 if ($('#cb_' + fieldId).is(':checked')) {
234 $("#operators_" + fieldId).show().removeAttr('disabled');
234 $("#operators_" + fieldId).show().removeAttr('disabled');
235 toggleOperator(field);
235 toggleOperator(field);
236 } else {
236 } else {
237 $("#operators_" + fieldId).hide().attr('disabled', true);
237 $("#operators_" + fieldId).hide().attr('disabled', true);
238 enableValues(field, []);
238 enableValues(field, []);
239 }
239 }
240 }
240 }
241
241
242 function enableValues(field, indexes) {
242 function enableValues(field, indexes) {
243 var fieldId = field.replace('.', '_');
243 var fieldId = field.replace('.', '_');
244 $('#tr_'+fieldId+' td.values .value').each(function(index) {
244 $('#tr_'+fieldId+' td.values .value').each(function(index) {
245 if ($.inArray(index, indexes) >= 0) {
245 if ($.inArray(index, indexes) >= 0) {
246 $(this).removeAttr('disabled');
246 $(this).removeAttr('disabled');
247 $(this).parents('span').first().show();
247 $(this).parents('span').first().show();
248 } else {
248 } else {
249 $(this).val('');
249 $(this).val('');
250 $(this).attr('disabled', true);
250 $(this).attr('disabled', true);
251 $(this).parents('span').first().hide();
251 $(this).parents('span').first().hide();
252 }
252 }
253
253
254 if ($(this).hasClass('group')) {
254 if ($(this).hasClass('group')) {
255 $(this).addClass('open');
255 $(this).addClass('open');
256 } else {
256 } else {
257 $(this).show();
257 $(this).show();
258 }
258 }
259 });
259 });
260 }
260 }
261
261
262 function toggleOperator(field) {
262 function toggleOperator(field) {
263 var fieldId = field.replace('.', '_');
263 var fieldId = field.replace('.', '_');
264 var operator = $("#operators_" + fieldId);
264 var operator = $("#operators_" + fieldId);
265 switch (operator.val()) {
265 switch (operator.val()) {
266 case "!*":
266 case "!*":
267 case "*":
267 case "*":
268 case "t":
268 case "t":
269 case "ld":
269 case "ld":
270 case "w":
270 case "w":
271 case "lw":
271 case "lw":
272 case "l2w":
272 case "l2w":
273 case "m":
273 case "m":
274 case "lm":
274 case "lm":
275 case "y":
275 case "y":
276 case "o":
276 case "o":
277 case "c":
277 case "c":
278 case "*o":
278 case "*o":
279 case "!o":
279 case "!o":
280 enableValues(field, []);
280 enableValues(field, []);
281 break;
281 break;
282 case "><":
282 case "><":
283 enableValues(field, [0,1]);
283 enableValues(field, [0,1]);
284 break;
284 break;
285 case "<t+":
285 case "<t+":
286 case ">t+":
286 case ">t+":
287 case "><t+":
287 case "><t+":
288 case "t+":
288 case "t+":
289 case ">t-":
289 case ">t-":
290 case "<t-":
290 case "<t-":
291 case "><t-":
291 case "><t-":
292 case "t-":
292 case "t-":
293 enableValues(field, [2]);
293 enableValues(field, [2]);
294 break;
294 break;
295 case "=p":
295 case "=p":
296 case "=!p":
296 case "=!p":
297 case "!p":
297 case "!p":
298 enableValues(field, [1]);
298 enableValues(field, [1]);
299 break;
299 break;
300 default:
300 default:
301 enableValues(field, [0]);
301 enableValues(field, [0]);
302 break;
302 break;
303 }
303 }
304 }
304 }
305
305
306 function toggleMultiSelect(el) {
306 function toggleMultiSelect(el) {
307 if (el.attr('multiple')) {
307 if (el.attr('multiple')) {
308 el.removeAttr('multiple');
308 el.removeAttr('multiple');
309 el.attr('size', 1);
309 el.attr('size', 1);
310 } else {
310 } else {
311 el.attr('multiple', true);
311 el.attr('multiple', true);
312 if (el.children().length > 10)
312 if (el.children().length > 10)
313 el.attr('size', 10);
313 el.attr('size', 10);
314 else
314 else
315 el.attr('size', 4);
315 el.attr('size', 4);
316 }
316 }
317 }
317 }
318
318
319 function showTab(name, url) {
319 function showTab(name, url) {
320 $('#tab-content-' + name).parent().find('.tab-content').hide();
320 $('#tab-content-' + name).parent().find('.tab-content').hide();
321 $('#tab-content-' + name).parent().find('div.tabs a').removeClass('selected');
321 $('#tab-content-' + name).parent().find('div.tabs a').removeClass('selected');
322 $('#tab-content-' + name).show();
322 $('#tab-content-' + name).show();
323 $('#tab-' + name).addClass('selected');
323 $('#tab-' + name).addClass('selected');
324 //replaces current URL with the "href" attribute of the current link
324 //replaces current URL with the "href" attribute of the current link
325 //(only triggered if supported by browser)
325 //(only triggered if supported by browser)
326 if ("replaceState" in window.history) {
326 if ("replaceState" in window.history) {
327 window.history.replaceState(null, document.title, url);
327 window.history.replaceState(null, document.title, url);
328 }
328 }
329 return false;
329 return false;
330 }
330 }
331
331
332 function moveTabRight(el) {
332 function moveTabRight(el) {
333 var lis = $(el).parents('div.tabs').first().find('ul').children();
333 var lis = $(el).parents('div.tabs').first().find('ul').children();
334 var bw = $(el).parents('div.tabs-buttons').outerWidth(true);
334 var bw = $(el).parents('div.tabs-buttons').outerWidth(true);
335 var tabsWidth = 0;
335 var tabsWidth = 0;
336 var i = 0;
336 var i = 0;
337 lis.each(function() {
337 lis.each(function() {
338 if ($(this).is(':visible')) {
338 if ($(this).is(':visible')) {
339 tabsWidth += $(this).outerWidth(true);
339 tabsWidth += $(this).outerWidth(true);
340 }
340 }
341 });
341 });
342 if (tabsWidth < $(el).parents('div.tabs').first().width() - bw) { return; }
342 if (tabsWidth < $(el).parents('div.tabs').first().width() - bw) { return; }
343 $(el).siblings('.tab-left').removeClass('disabled');
343 $(el).siblings('.tab-left').removeClass('disabled');
344 while (i<lis.length && !lis.eq(i).is(':visible')) { i++; }
344 while (i<lis.length && !lis.eq(i).is(':visible')) { i++; }
345 var w = lis.eq(i).width();
345 var w = lis.eq(i).width();
346 lis.eq(i).hide();
346 lis.eq(i).hide();
347 if (tabsWidth - w < $(el).parents('div.tabs').first().width() - bw) {
347 if (tabsWidth - w < $(el).parents('div.tabs').first().width() - bw) {
348 $(el).addClass('disabled');
348 $(el).addClass('disabled');
349 }
349 }
350 }
350 }
351
351
352 function moveTabLeft(el) {
352 function moveTabLeft(el) {
353 var lis = $(el).parents('div.tabs').first().find('ul').children();
353 var lis = $(el).parents('div.tabs').first().find('ul').children();
354 var i = 0;
354 var i = 0;
355 while (i < lis.length && !lis.eq(i).is(':visible')) { i++; }
355 while (i < lis.length && !lis.eq(i).is(':visible')) { i++; }
356 if (i > 0) {
356 if (i > 0) {
357 lis.eq(i-1).show();
357 lis.eq(i-1).show();
358 $(el).siblings('.tab-right').removeClass('disabled');
358 $(el).siblings('.tab-right').removeClass('disabled');
359 }
359 }
360 if (i <= 1) {
360 if (i <= 1) {
361 $(el).addClass('disabled');
361 $(el).addClass('disabled');
362 }
362 }
363 }
363 }
364
364
365 function displayTabsButtons() {
365 function displayTabsButtons() {
366 var lis;
366 var lis;
367 var tabsWidth;
367 var tabsWidth;
368 var el;
368 var el;
369 var numHidden;
369 var numHidden;
370 $('div.tabs').each(function() {
370 $('div.tabs').each(function() {
371 el = $(this);
371 el = $(this);
372 lis = el.find('ul').children();
372 lis = el.find('ul').children();
373 tabsWidth = 0;
373 tabsWidth = 0;
374 numHidden = 0;
374 numHidden = 0;
375 lis.each(function(){
375 lis.each(function(){
376 if ($(this).is(':visible')) {
376 if ($(this).is(':visible')) {
377 tabsWidth += $(this).outerWidth(true);
377 tabsWidth += $(this).outerWidth(true);
378 } else {
378 } else {
379 numHidden++;
379 numHidden++;
380 }
380 }
381 });
381 });
382 var bw = $(el).parents('div.tabs-buttons').outerWidth(true);
382 var bw = $(el).parents('div.tabs-buttons').outerWidth(true);
383 if ((tabsWidth < el.width() - bw) && (lis.first().is(':visible'))) {
383 if ((tabsWidth < el.width() - bw) && (lis.first().is(':visible'))) {
384 el.find('div.tabs-buttons').hide();
384 el.find('div.tabs-buttons').hide();
385 } else {
385 } else {
386 el.find('div.tabs-buttons').show().children('button.tab-left').toggleClass('disabled', numHidden == 0);
386 el.find('div.tabs-buttons').show().children('button.tab-left').toggleClass('disabled', numHidden == 0);
387 }
387 }
388 });
388 });
389 }
389 }
390
390
391 function setPredecessorFieldsVisibility() {
391 function setPredecessorFieldsVisibility() {
392 var relationType = $('#relation_relation_type');
392 var relationType = $('#relation_relation_type');
393 if (relationType.val() == "precedes" || relationType.val() == "follows") {
393 if (relationType.val() == "precedes" || relationType.val() == "follows") {
394 $('#predecessor_fields').show();
394 $('#predecessor_fields').show();
395 } else {
395 } else {
396 $('#predecessor_fields').hide();
396 $('#predecessor_fields').hide();
397 }
397 }
398 }
398 }
399
399
400 function showModal(id, width, title) {
400 function showModal(id, width, title) {
401 var el = $('#'+id).first();
401 var el = $('#'+id).first();
402 if (el.length === 0 || el.is(':visible')) {return;}
402 if (el.length === 0 || el.is(':visible')) {return;}
403 if (!title) title = el.find('h3.title').text();
403 if (!title) title = el.find('h3.title').text();
404 // moves existing modals behind the transparent background
404 // moves existing modals behind the transparent background
405 $(".modal").zIndex(99);
405 $(".modal").zIndex(99);
406 el.dialog({
406 el.dialog({
407 width: width,
407 width: width,
408 modal: true,
408 modal: true,
409 resizable: false,
409 resizable: false,
410 dialogClass: 'modal',
410 dialogClass: 'modal',
411 title: title
411 title: title
412 }).on('dialogclose', function(){
412 }).on('dialogclose', function(){
413 $(".modal").zIndex(101);
413 $(".modal").zIndex(101);
414 });
414 });
415 el.find("input[type=text], input[type=submit]").first().focus();
415 el.find("input[type=text], input[type=submit]").first().focus();
416 }
416 }
417
417
418 function hideModal(el) {
418 function hideModal(el) {
419 var modal;
419 var modal;
420 if (el) {
420 if (el) {
421 modal = $(el).parents('.ui-dialog-content');
421 modal = $(el).parents('.ui-dialog-content');
422 } else {
422 } else {
423 modal = $('#ajax-modal');
423 modal = $('#ajax-modal');
424 }
424 }
425 modal.dialog("close");
425 modal.dialog("close");
426 }
426 }
427
427
428 function submitPreview(url, form, target) {
428 function submitPreview(url, form, target) {
429 $.ajax({
429 $.ajax({
430 url: url,
430 url: url,
431 type: 'post',
431 type: 'post',
432 data: $('#'+form).serialize(),
432 data: $('#'+form).serialize(),
433 success: function(data){
433 success: function(data){
434 $('#'+target).html(data);
434 $('#'+target).html(data);
435 }
435 }
436 });
436 });
437 }
437 }
438
438
439 function collapseScmEntry(id) {
439 function collapseScmEntry(id) {
440 $('.'+id).each(function() {
440 $('.'+id).each(function() {
441 if ($(this).hasClass('open')) {
441 if ($(this).hasClass('open')) {
442 collapseScmEntry($(this).attr('id'));
442 collapseScmEntry($(this).attr('id'));
443 }
443 }
444 $(this).hide();
444 $(this).hide();
445 });
445 });
446 $('#'+id).removeClass('open');
446 $('#'+id).removeClass('open');
447 }
447 }
448
448
449 function expandScmEntry(id) {
449 function expandScmEntry(id) {
450 $('.'+id).each(function() {
450 $('.'+id).each(function() {
451 $(this).show();
451 $(this).show();
452 if ($(this).hasClass('loaded') && !$(this).hasClass('collapsed')) {
452 if ($(this).hasClass('loaded') && !$(this).hasClass('collapsed')) {
453 expandScmEntry($(this).attr('id'));
453 expandScmEntry($(this).attr('id'));
454 }
454 }
455 });
455 });
456 $('#'+id).addClass('open');
456 $('#'+id).addClass('open');
457 }
457 }
458
458
459 function scmEntryClick(id, url) {
459 function scmEntryClick(id, url) {
460 var el = $('#'+id);
460 var el = $('#'+id);
461 if (el.hasClass('open')) {
461 if (el.hasClass('open')) {
462 collapseScmEntry(id);
462 collapseScmEntry(id);
463 el.addClass('collapsed');
463 el.addClass('collapsed');
464 return false;
464 return false;
465 } else if (el.hasClass('loaded')) {
465 } else if (el.hasClass('loaded')) {
466 expandScmEntry(id);
466 expandScmEntry(id);
467 el.removeClass('collapsed');
467 el.removeClass('collapsed');
468 return false;
468 return false;
469 }
469 }
470 if (el.hasClass('loading')) {
470 if (el.hasClass('loading')) {
471 return false;
471 return false;
472 }
472 }
473 el.addClass('loading');
473 el.addClass('loading');
474 $.ajax({
474 $.ajax({
475 url: url,
475 url: url,
476 success: function(data) {
476 success: function(data) {
477 el.after(data);
477 el.after(data);
478 el.addClass('open').addClass('loaded').removeClass('loading');
478 el.addClass('open').addClass('loaded').removeClass('loading');
479 }
479 }
480 });
480 });
481 return true;
481 return true;
482 }
482 }
483
483
484 function randomKey(size) {
484 function randomKey(size) {
485 var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
485 var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
486 var key = '';
486 var key = '';
487 for (var i = 0; i < size; i++) {
487 for (var i = 0; i < size; i++) {
488 key += chars.charAt(Math.floor(Math.random() * chars.length));
488 key += chars.charAt(Math.floor(Math.random() * chars.length));
489 }
489 }
490 return key;
490 return key;
491 }
491 }
492
492
493 function updateIssueFrom(url, el) {
493 function updateIssueFrom(url, el) {
494 $('#all_attributes input, #all_attributes textarea, #all_attributes select').each(function(){
494 $('#all_attributes input, #all_attributes textarea, #all_attributes select').each(function(){
495 $(this).data('valuebeforeupdate', $(this).val());
495 $(this).data('valuebeforeupdate', $(this).val());
496 });
496 });
497 if (el) {
497 if (el) {
498 $("#form_update_triggered_by").val($(el).attr('id'));
498 $("#form_update_triggered_by").val($(el).attr('id'));
499 }
499 }
500 return $.ajax({
500 return $.ajax({
501 url: url,
501 url: url,
502 type: 'post',
502 type: 'post',
503 data: $('#issue-form').serialize()
503 data: $('#issue-form').serialize()
504 });
504 });
505 }
505 }
506
506
507 function replaceIssueFormWith(html){
507 function replaceIssueFormWith(html){
508 var replacement = $(html);
508 var replacement = $(html);
509 $('#all_attributes input, #all_attributes textarea, #all_attributes select').each(function(){
509 $('#all_attributes input, #all_attributes textarea, #all_attributes select').each(function(){
510 var object_id = $(this).attr('id');
510 var object_id = $(this).attr('id');
511 if (object_id && $(this).data('valuebeforeupdate')!=$(this).val()) {
511 if (object_id && $(this).data('valuebeforeupdate')!=$(this).val()) {
512 replacement.find('#'+object_id).val($(this).val());
512 replacement.find('#'+object_id).val($(this).val());
513 }
513 }
514 });
514 });
515 $('#all_attributes').empty();
515 $('#all_attributes').empty();
516 $('#all_attributes').prepend(replacement);
516 $('#all_attributes').prepend(replacement);
517 }
517 }
518
518
519 function updateBulkEditFrom(url) {
519 function updateBulkEditFrom(url) {
520 $.ajax({
520 $.ajax({
521 url: url,
521 url: url,
522 type: 'post',
522 type: 'post',
523 data: $('#bulk_edit_form').serialize()
523 data: $('#bulk_edit_form').serialize()
524 });
524 });
525 }
525 }
526
526
527 function observeAutocompleteField(fieldId, url, options) {
527 function observeAutocompleteField(fieldId, url, options) {
528 $(document).ready(function() {
528 $(document).ready(function() {
529 $('#'+fieldId).autocomplete($.extend({
529 $('#'+fieldId).autocomplete($.extend({
530 source: url,
530 source: url,
531 minLength: 2,
531 minLength: 2,
532 position: {collision: "flipfit"},
532 position: {collision: "flipfit"},
533 search: function(){$('#'+fieldId).addClass('ajax-loading');},
533 search: function(){$('#'+fieldId).addClass('ajax-loading');},
534 response: function(){$('#'+fieldId).removeClass('ajax-loading');}
534 response: function(){$('#'+fieldId).removeClass('ajax-loading');}
535 }, options));
535 }, options));
536 $('#'+fieldId).addClass('autocomplete');
536 $('#'+fieldId).addClass('autocomplete');
537 });
537 });
538 }
538 }
539
539
540 function observeSearchfield(fieldId, targetId, url) {
540 function observeSearchfield(fieldId, targetId, url) {
541 $('#'+fieldId).each(function() {
541 $('#'+fieldId).each(function() {
542 var $this = $(this);
542 var $this = $(this);
543 $this.addClass('autocomplete');
543 $this.addClass('autocomplete');
544 $this.attr('data-value-was', $this.val());
544 $this.attr('data-value-was', $this.val());
545 var check = function() {
545 var check = function() {
546 var val = $this.val();
546 var val = $this.val();
547 if ($this.attr('data-value-was') != val){
547 if ($this.attr('data-value-was') != val){
548 $this.attr('data-value-was', val);
548 $this.attr('data-value-was', val);
549 $.ajax({
549 $.ajax({
550 url: url,
550 url: url,
551 type: 'get',
551 type: 'get',
552 data: {q: $this.val()},
552 data: {q: $this.val()},
553 success: function(data){ if(targetId) $('#'+targetId).html(data); },
553 success: function(data){ if(targetId) $('#'+targetId).html(data); },
554 beforeSend: function(){ $this.addClass('ajax-loading'); },
554 beforeSend: function(){ $this.addClass('ajax-loading'); },
555 complete: function(){ $this.removeClass('ajax-loading'); }
555 complete: function(){ $this.removeClass('ajax-loading'); }
556 });
556 });
557 }
557 }
558 };
558 };
559 var reset = function() {
559 var reset = function() {
560 if (timer) {
560 if (timer) {
561 clearInterval(timer);
561 clearInterval(timer);
562 timer = setInterval(check, 300);
562 timer = setInterval(check, 300);
563 }
563 }
564 };
564 };
565 var timer = setInterval(check, 300);
565 var timer = setInterval(check, 300);
566 $this.bind('keyup click mousemove', reset);
566 $this.bind('keyup click mousemove', reset);
567 });
567 });
568 }
568 }
569
569
570 function beforeShowDatePicker(input, inst) {
570 function beforeShowDatePicker(input, inst) {
571 var default_date = null;
571 var default_date = null;
572 switch ($(input).attr("id")) {
572 switch ($(input).attr("id")) {
573 case "issue_start_date" :
573 case "issue_start_date" :
574 if ($("#issue_due_date").size() > 0) {
574 if ($("#issue_due_date").size() > 0) {
575 default_date = $("#issue_due_date").val();
575 default_date = $("#issue_due_date").val();
576 }
576 }
577 break;
577 break;
578 case "issue_due_date" :
578 case "issue_due_date" :
579 if ($("#issue_start_date").size() > 0) {
579 if ($("#issue_start_date").size() > 0) {
580 var start_date = $("#issue_start_date").val();
580 var start_date = $("#issue_start_date").val();
581 if (start_date != "") {
581 if (start_date != "") {
582 start_date = new Date(Date.parse(start_date));
582 start_date = new Date(Date.parse(start_date));
583 if (start_date > new Date()) {
583 if (start_date > new Date()) {
584 default_date = $("#issue_start_date").val();
584 default_date = $("#issue_start_date").val();
585 }
585 }
586 }
586 }
587 }
587 }
588 break;
588 break;
589 }
589 }
590 $(input).datepicker("option", "defaultDate", default_date);
590 $(input).datepicker("option", "defaultDate", default_date);
591 }
591 }
592
592
593 (function($){
593 (function($){
594 $.fn.positionedItems = function(sortableOptions, options){
594 $.fn.positionedItems = function(sortableOptions, options){
595 var settings = $.extend({
595 var settings = $.extend({
596 firstPosition: 1
596 firstPosition: 1
597 }, options );
597 }, options );
598
598
599 return this.sortable($.extend({
599 return this.sortable($.extend({
600 handle: ".sort-handle",
600 handle: ".sort-handle",
601 helper: function(event, ui){
601 helper: function(event, ui){
602 ui.children().each(function(){
602 ui.children('td').each(function(){
603 $(this).width($(this).width());
603 $(this).width($(this).width());
604 });
604 });
605 return ui;
605 return ui;
606 },
606 },
607 update: function(event, ui) {
607 update: function(event, ui) {
608 var sortable = $(this);
608 var sortable = $(this);
609 var url = ui.item.find(".sort-handle").data("reorder-url");
609 var url = ui.item.find(".sort-handle").data("reorder-url");
610 var param = ui.item.find(".sort-handle").data("reorder-param");
610 var param = ui.item.find(".sort-handle").data("reorder-param");
611 var data = {};
611 var data = {};
612 data[param] = {position: ui.item.index() + settings['firstPosition']};
612 data[param] = {position: ui.item.index() + settings['firstPosition']};
613 $.ajax({
613 $.ajax({
614 url: url,
614 url: url,
615 type: 'put',
615 type: 'put',
616 dataType: 'script',
616 dataType: 'script',
617 data: data,
617 data: data,
618 success: function(data){
618 success: function(data){
619 sortable.children(":even").removeClass("even").addClass("odd");
619 sortable.children(":even").removeClass("even").addClass("odd");
620 sortable.children(":odd").removeClass("odd").addClass("even");
620 sortable.children(":odd").removeClass("odd").addClass("even");
621 },
621 },
622 error: function(jqXHR, textStatus, errorThrown){
622 error: function(jqXHR, textStatus, errorThrown){
623 alert(jqXHR.status);
623 alert(jqXHR.status);
624 sortable.sortable("cancel");
624 sortable.sortable("cancel");
625 }
625 }
626 });
626 });
627 },
627 },
628 }, sortableOptions));
628 }, sortableOptions));
629 }
629 }
630 }( jQuery ));
630 }( jQuery ));
631
631
632 function initMyPageSortable(list, url) {
632 function initMyPageSortable(list, url) {
633 $('#list-'+list).sortable({
633 $('#list-'+list).sortable({
634 connectWith: '.block-receiver',
634 connectWith: '.block-receiver',
635 tolerance: 'pointer',
635 tolerance: 'pointer',
636 update: function(){
636 update: function(){
637 $.ajax({
637 $.ajax({
638 url: url,
638 url: url,
639 type: 'post',
639 type: 'post',
640 data: {'blocks': $.map($('#list-'+list).children(), function(el){return $(el).attr('id');})}
640 data: {'blocks': $.map($('#list-'+list).children(), function(el){return $(el).attr('id');})}
641 });
641 });
642 }
642 }
643 });
643 });
644 $("#list-top, #list-left, #list-right").disableSelection();
644 $("#list-top, #list-left, #list-right").disableSelection();
645 }
645 }
646
646
647 var warnLeavingUnsavedMessage;
647 var warnLeavingUnsavedMessage;
648 function warnLeavingUnsaved(message) {
648 function warnLeavingUnsaved(message) {
649 warnLeavingUnsavedMessage = message;
649 warnLeavingUnsavedMessage = message;
650 $(document).on('submit', 'form', function(){
650 $(document).on('submit', 'form', function(){
651 $('textarea').removeData('changed');
651 $('textarea').removeData('changed');
652 });
652 });
653 $(document).on('change', 'textarea', function(){
653 $(document).on('change', 'textarea', function(){
654 $(this).data('changed', 'changed');
654 $(this).data('changed', 'changed');
655 });
655 });
656 window.onbeforeunload = function(){
656 window.onbeforeunload = function(){
657 var warn = false;
657 var warn = false;
658 $('textarea').blur().each(function(){
658 $('textarea').blur().each(function(){
659 if ($(this).data('changed')) {
659 if ($(this).data('changed')) {
660 warn = true;
660 warn = true;
661 }
661 }
662 });
662 });
663 if (warn) {return warnLeavingUnsavedMessage;}
663 if (warn) {return warnLeavingUnsavedMessage;}
664 };
664 };
665 }
665 }
666
666
667 function setupAjaxIndicator() {
667 function setupAjaxIndicator() {
668 $(document).bind('ajaxSend', function(event, xhr, settings) {
668 $(document).bind('ajaxSend', function(event, xhr, settings) {
669 if ($('.ajax-loading').length === 0 && settings.contentType != 'application/octet-stream') {
669 if ($('.ajax-loading').length === 0 && settings.contentType != 'application/octet-stream') {
670 $('#ajax-indicator').show();
670 $('#ajax-indicator').show();
671 }
671 }
672 });
672 });
673 $(document).bind('ajaxStop', function() {
673 $(document).bind('ajaxStop', function() {
674 $('#ajax-indicator').hide();
674 $('#ajax-indicator').hide();
675 });
675 });
676 }
676 }
677
677
678 function setupTabs() {
678 function setupTabs() {
679 if($('.tabs').length > 0) {
679 if($('.tabs').length > 0) {
680 displayTabsButtons();
680 displayTabsButtons();
681 $(window).resize(displayTabsButtons);
681 $(window).resize(displayTabsButtons);
682 }
682 }
683 }
683 }
684
684
685 function hideOnLoad() {
685 function hideOnLoad() {
686 $('.hol').hide();
686 $('.hol').hide();
687 }
687 }
688
688
689 function addFormObserversForDoubleSubmit() {
689 function addFormObserversForDoubleSubmit() {
690 $('form[method=post]').each(function() {
690 $('form[method=post]').each(function() {
691 if (!$(this).hasClass('multiple-submit')) {
691 if (!$(this).hasClass('multiple-submit')) {
692 $(this).submit(function(form_submission) {
692 $(this).submit(function(form_submission) {
693 if ($(form_submission.target).attr('data-submitted')) {
693 if ($(form_submission.target).attr('data-submitted')) {
694 form_submission.preventDefault();
694 form_submission.preventDefault();
695 } else {
695 } else {
696 $(form_submission.target).attr('data-submitted', true);
696 $(form_submission.target).attr('data-submitted', true);
697 }
697 }
698 });
698 });
699 }
699 }
700 });
700 });
701 }
701 }
702
702
703 function defaultFocus(){
703 function defaultFocus(){
704 if (($('#content :focus').length == 0) && (window.location.hash == '')) {
704 if (($('#content :focus').length == 0) && (window.location.hash == '')) {
705 $('#content input[type=text], #content textarea').first().focus();
705 $('#content input[type=text], #content textarea').first().focus();
706 }
706 }
707 }
707 }
708
708
709 function blockEventPropagation(event) {
709 function blockEventPropagation(event) {
710 event.stopPropagation();
710 event.stopPropagation();
711 event.preventDefault();
711 event.preventDefault();
712 }
712 }
713
713
714 function toggleDisabledOnChange() {
714 function toggleDisabledOnChange() {
715 var checked = $(this).is(':checked');
715 var checked = $(this).is(':checked');
716 $($(this).data('disables')).attr('disabled', checked);
716 $($(this).data('disables')).attr('disabled', checked);
717 $($(this).data('enables')).attr('disabled', !checked);
717 $($(this).data('enables')).attr('disabled', !checked);
718 }
718 }
719 function toggleDisabledInit() {
719 function toggleDisabledInit() {
720 $('input[data-disables], input[data-enables]').each(toggleDisabledOnChange);
720 $('input[data-disables], input[data-enables]').each(toggleDisabledOnChange);
721 }
721 }
722 $(document).ready(function(){
722 $(document).ready(function(){
723 $('#content').on('change', 'input[data-disables], input[data-enables]', toggleDisabledOnChange);
723 $('#content').on('change', 'input[data-disables], input[data-enables]', toggleDisabledOnChange);
724 toggleDisabledInit();
724 toggleDisabledInit();
725 });
725 });
726
726
727 function keepAnchorOnSignIn(form){
727 function keepAnchorOnSignIn(form){
728 var hash = decodeURIComponent(self.document.location.hash);
728 var hash = decodeURIComponent(self.document.location.hash);
729 if (hash) {
729 if (hash) {
730 if (hash.indexOf("#") === -1) {
730 if (hash.indexOf("#") === -1) {
731 hash = "#" + hash;
731 hash = "#" + hash;
732 }
732 }
733 form.action = form.action + hash;
733 form.action = form.action + hash;
734 }
734 }
735 return true;
735 return true;
736 }
736 }
737
737
738 $(document).ready(setupAjaxIndicator);
738 $(document).ready(setupAjaxIndicator);
739 $(document).ready(hideOnLoad);
739 $(document).ready(hideOnLoad);
740 $(document).ready(addFormObserversForDoubleSubmit);
740 $(document).ready(addFormObserversForDoubleSubmit);
741 $(document).ready(defaultFocus);
741 $(document).ready(defaultFocus);
742 $(document).ready(setupTabs);
742 $(document).ready(setupTabs);
@@ -1,1369 +1,1373
1 html {overflow-y:scroll;}
1 html {overflow-y:scroll;}
2 body { font-family: Verdana, sans-serif; font-size: 12px; color:#333; margin: 0; padding: 0; min-width: 900px; }
2 body { font-family: Verdana, sans-serif; font-size: 12px; color:#333; margin: 0; padding: 0; min-width: 900px; }
3
3
4 h1, h2, h3, h4 {font-family: "Trebuchet MS", Verdana, sans-serif;padding: 2px 10px 1px 0px;margin: 0 0 10px 0;}
4 h1, h2, h3, h4 {font-family: "Trebuchet MS", Verdana, sans-serif;padding: 2px 10px 1px 0px;margin: 0 0 10px 0;}
5 #content h1, h2, h3, h4 {color: #555;}
5 #content h1, h2, h3, h4 {color: #555;}
6 h2, .wiki h1 {font-size: 20px;}
6 h2, .wiki h1 {font-size: 20px;}
7 h3, .wiki h2 {font-size: 16px;}
7 h3, .wiki h2 {font-size: 16px;}
8 h4, .wiki h3 {font-size: 13px;}
8 h4, .wiki h3 {font-size: 13px;}
9 h4 {border-bottom: 1px dotted #bbb;}
9 h4 {border-bottom: 1px dotted #bbb;}
10 pre, code {font-family: Consolas, Menlo, "Liberation Mono", Courier, monospace;}
10 pre, code {font-family: Consolas, Menlo, "Liberation Mono", Courier, monospace;}
11
11
12 /***** Layout *****/
12 /***** Layout *****/
13 #wrapper {background: white;overflow: hidden;}
13 #wrapper {background: white;overflow: hidden;}
14
14
15 #top-menu {background: #3E5B76; color: #fff; height:1.8em; font-size: 0.8em; padding: 2px 2px 0px 6px;}
15 #top-menu {background: #3E5B76; color: #fff; height:1.8em; font-size: 0.8em; padding: 2px 2px 0px 6px;}
16 #top-menu ul {margin: 0; padding: 0;}
16 #top-menu ul {margin: 0; padding: 0;}
17 #top-menu li {
17 #top-menu li {
18 float:left;
18 float:left;
19 list-style-type:none;
19 list-style-type:none;
20 margin: 0px 0px 0px 0px;
20 margin: 0px 0px 0px 0px;
21 padding: 0px 0px 0px 0px;
21 padding: 0px 0px 0px 0px;
22 white-space:nowrap;
22 white-space:nowrap;
23 }
23 }
24 #top-menu a {color: #fff; margin-right: 8px; font-weight: bold;}
24 #top-menu a {color: #fff; margin-right: 8px; font-weight: bold;}
25 #top-menu #loggedas { float: right; margin-right: 0.5em; color: #fff; }
25 #top-menu #loggedas { float: right; margin-right: 0.5em; color: #fff; }
26
26
27 #account {float:right;}
27 #account {float:right;}
28
28
29 #header {min-height:5.3em;margin:0;background-color:#628DB6;color:#f8f8f8; padding: 4px 8px 20px 6px; position:relative;}
29 #header {min-height:5.3em;margin:0;background-color:#628DB6;color:#f8f8f8; padding: 4px 8px 20px 6px; position:relative;}
30 #header a {color:#f8f8f8;}
30 #header a {color:#f8f8f8;}
31 #header h1 { overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
31 #header h1 { overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
32 #header h1 .breadcrumbs { display:block; font-size: .6em; font-weight: normal; }
32 #header h1 .breadcrumbs { display:block; font-size: .6em; font-weight: normal; }
33 #quick-search {float:right;}
33 #quick-search {float:right;}
34
34
35 #main-menu {position: absolute; bottom: 0px; left:6px; margin-right: -500px; width: 100%;}
35 #main-menu {position: absolute; bottom: 0px; left:6px; margin-right: -500px; width: 100%;}
36 #main-menu ul {margin: 0; padding: 0; width: 100%; white-space: nowrap;}
36 #main-menu ul {margin: 0; padding: 0; width: 100%; white-space: nowrap;}
37 #main-menu li {
37 #main-menu li {
38 float:none;
38 float:none;
39 list-style-type:none;
39 list-style-type:none;
40 margin: 0px 2px 0px 0px;
40 margin: 0px 2px 0px 0px;
41 padding: 0px 0px 0px 0px;
41 padding: 0px 0px 0px 0px;
42 white-space:nowrap;
42 white-space:nowrap;
43 display:inline-block;
43 display:inline-block;
44 }
44 }
45 #main-menu li a {
45 #main-menu li a {
46 display: block;
46 display: block;
47 color: #fff;
47 color: #fff;
48 text-decoration: none;
48 text-decoration: none;
49 font-weight: bold;
49 font-weight: bold;
50 margin: 0;
50 margin: 0;
51 padding: 4px 10px 4px 10px;
51 padding: 4px 10px 4px 10px;
52 }
52 }
53 #main-menu li a:hover {background:#759FCF; color:#fff;}
53 #main-menu li a:hover {background:#759FCF; color:#fff;}
54 #main-menu li a.selected, #main-menu li a.selected:hover {background:#fff; color:#555;}
54 #main-menu li a.selected, #main-menu li a.selected:hover {background:#fff; color:#555;}
55 #main-menu .tabs-buttons {
55 #main-menu .tabs-buttons {
56 right: 6px;
56 right: 6px;
57 background-color: transparent;
57 background-color: transparent;
58 border-bottom-color: transparent;
58 border-bottom-color: transparent;
59 }
59 }
60
60
61 #admin-menu ul {margin: 0; padding: 0;}
61 #admin-menu ul {margin: 0; padding: 0;}
62 #admin-menu li {margin: 0; padding: 0 0 6px 0; list-style-type:none;}
62 #admin-menu li {margin: 0; padding: 0 0 6px 0; list-style-type:none;}
63
63
64 #admin-menu a { background-position: 0% 40%; background-repeat: no-repeat; padding-left: 20px; padding-top: 2px; padding-bottom: 3px;}
64 #admin-menu a { background-position: 0% 40%; background-repeat: no-repeat; padding-left: 20px; padding-top: 2px; padding-bottom: 3px;}
65 #admin-menu a.projects { background-image: url(../images/projects.png); }
65 #admin-menu a.projects { background-image: url(../images/projects.png); }
66 #admin-menu a.users { background-image: url(../images/user.png); }
66 #admin-menu a.users { background-image: url(../images/user.png); }
67 #admin-menu a.groups { background-image: url(../images/group.png); }
67 #admin-menu a.groups { background-image: url(../images/group.png); }
68 #admin-menu a.roles { background-image: url(../images/database_key.png); }
68 #admin-menu a.roles { background-image: url(../images/database_key.png); }
69 #admin-menu a.trackers { background-image: url(../images/ticket.png); }
69 #admin-menu a.trackers { background-image: url(../images/ticket.png); }
70 #admin-menu a.issue_statuses { background-image: url(../images/ticket_edit.png); }
70 #admin-menu a.issue_statuses { background-image: url(../images/ticket_edit.png); }
71 #admin-menu a.workflows { background-image: url(../images/ticket_go.png); }
71 #admin-menu a.workflows { background-image: url(../images/ticket_go.png); }
72 #admin-menu a.custom_fields { background-image: url(../images/textfield.png); }
72 #admin-menu a.custom_fields { background-image: url(../images/textfield.png); }
73 #admin-menu a.enumerations { background-image: url(../images/text_list_bullets.png); }
73 #admin-menu a.enumerations { background-image: url(../images/text_list_bullets.png); }
74 #admin-menu a.settings { background-image: url(../images/changeset.png); }
74 #admin-menu a.settings { background-image: url(../images/changeset.png); }
75 #admin-menu a.plugins { background-image: url(../images/plugin.png); }
75 #admin-menu a.plugins { background-image: url(../images/plugin.png); }
76 #admin-menu a.info { background-image: url(../images/help.png); }
76 #admin-menu a.info { background-image: url(../images/help.png); }
77 #admin-menu a.server_authentication { background-image: url(../images/server_key.png); }
77 #admin-menu a.server_authentication { background-image: url(../images/server_key.png); }
78
78
79 #main {background-color:#EEEEEE;}
79 #main {background-color:#EEEEEE;}
80
80
81 #sidebar{ float: right; width: 22%; position: relative; z-index: 9; padding: 0; margin: 0;}
81 #sidebar{ float: right; width: 22%; position: relative; z-index: 9; padding: 0; margin: 0;}
82 * html #sidebar{ width: 22%; }
82 * html #sidebar{ width: 22%; }
83 #sidebar h3{ font-size: 14px; margin-top:14px; color: #666; }
83 #sidebar h3{ font-size: 14px; margin-top:14px; color: #666; }
84 #sidebar hr{ width: 100%; margin: 0 auto; height: 1px; background: #ccc; border: 0; }
84 #sidebar hr{ width: 100%; margin: 0 auto; height: 1px; background: #ccc; border: 0; }
85 * html #sidebar hr{ width: 95%; position: relative; left: -6px; color: #ccc; }
85 * html #sidebar hr{ width: 95%; position: relative; left: -6px; color: #ccc; }
86 #sidebar .contextual { margin-right: 1em; }
86 #sidebar .contextual { margin-right: 1em; }
87 #sidebar ul, ul.flat {margin: 0; padding: 0;}
87 #sidebar ul, ul.flat {margin: 0; padding: 0;}
88 #sidebar ul li, ul.flat li {list-style-type:none;margin: 0px 2px 0px 0px; padding: 0px 0px 0px 0px;}
88 #sidebar ul li, ul.flat li {list-style-type:none;margin: 0px 2px 0px 0px; padding: 0px 0px 0px 0px;}
89 #sidebar div.wiki h3 {font-size:13px; margin-top:0; color:#555;}
89 #sidebar div.wiki h3 {font-size:13px; margin-top:0; color:#555;}
90 #sidebar div.wiki ul {margin:inherit; padding-left:40px;}
90 #sidebar div.wiki ul {margin:inherit; padding-left:40px;}
91 #sidebar div.wiki ul li {list-style-type:inherit;}
91 #sidebar div.wiki ul li {list-style-type:inherit;}
92
92
93 #content { width: 75%; background-color: #fff; margin: 0px; border-right: 1px solid #ddd; padding: 6px 10px 10px 10px; z-index: 10; }
93 #content { width: 75%; background-color: #fff; margin: 0px; border-right: 1px solid #ddd; padding: 6px 10px 10px 10px; z-index: 10; }
94 * html #content{ width: 75%; padding-left: 0; margin-top: 0px; padding: 6px 10px 10px 10px;}
94 * html #content{ width: 75%; padding-left: 0; margin-top: 0px; padding: 6px 10px 10px 10px;}
95 html>body #content { min-height: 600px; }
95 html>body #content { min-height: 600px; }
96 * html body #content { height: 600px; } /* IE */
96 * html body #content { height: 600px; } /* IE */
97
97
98 #main.nosidebar #sidebar{ display: none; }
98 #main.nosidebar #sidebar{ display: none; }
99 #main.nosidebar #content{ width: auto; border-right: 0; }
99 #main.nosidebar #content{ width: auto; border-right: 0; }
100
100
101 #footer {clear: both; border-top: 1px solid #bbb; font-size: 0.9em; color: #aaa; padding: 5px; text-align:center; background:#fff;}
101 #footer {clear: both; border-top: 1px solid #bbb; font-size: 0.9em; color: #aaa; padding: 5px; text-align:center; background:#fff;}
102
102
103 #login-form table {margin-top:5em; padding:1em; margin-left: auto; margin-right: auto; border: 2px solid #FDBF3B; background-color:#FFEBC1; }
103 #login-form table {margin-top:5em; padding:1em; margin-left: auto; margin-right: auto; border: 2px solid #FDBF3B; background-color:#FFEBC1; }
104 #login-form table td {padding: 6px;}
104 #login-form table td {padding: 6px;}
105 #login-form label {font-weight: bold;}
105 #login-form label {font-weight: bold;}
106 #login-form input#username, #login-form input#password { width: 300px; }
106 #login-form input#username, #login-form input#password { width: 300px; }
107
107
108 div.modal { border-radius:5px; background:#fff; z-index:50; padding:4px;}
108 div.modal { border-radius:5px; background:#fff; z-index:50; padding:4px;}
109 div.modal h3.title {display:none;}
109 div.modal h3.title {display:none;}
110 div.modal p.buttons {text-align:right; margin-bottom:0;}
110 div.modal p.buttons {text-align:right; margin-bottom:0;}
111 div.modal .box p {margin: 0.3em 0;}
111 div.modal .box p {margin: 0.3em 0;}
112
112
113 input#openid_url { background: url(../images/openid-bg.gif) no-repeat; background-color: #fff; background-position: 0 50%; padding-left: 18px; }
113 input#openid_url { background: url(../images/openid-bg.gif) no-repeat; background-color: #fff; background-position: 0 50%; padding-left: 18px; }
114
114
115 .clear:after{ content: "."; display: block; height: 0; clear: both; visibility: hidden; }
115 .clear:after{ content: "."; display: block; height: 0; clear: both; visibility: hidden; }
116
116
117 .mobile-show {display: none;}
117 .mobile-show {display: none;}
118
118
119 /***** Links *****/
119 /***** Links *****/
120 a, a:link, a:visited{ color: #169; text-decoration: none; }
120 a, a:link, a:visited{ color: #169; text-decoration: none; }
121 a:hover, a:active{ color: #c61a1a; text-decoration: underline;}
121 a:hover, a:active{ color: #c61a1a; text-decoration: underline;}
122 a img{ border: 0; }
122 a img{ border: 0; }
123
123
124 a.issue.closed, a.issue.closed:link, a.issue.closed:visited { color: #999; text-decoration: line-through; }
124 a.issue.closed, a.issue.closed:link, a.issue.closed:visited { color: #999; text-decoration: line-through; }
125 a.project.closed, a.project.closed:link, a.project.closed:visited { color: #999; }
125 a.project.closed, a.project.closed:link, a.project.closed:visited { color: #999; }
126 a.user.locked, a.user.locked:link, a.user.locked:visited {color: #999;}
126 a.user.locked, a.user.locked:link, a.user.locked:visited {color: #999;}
127
127
128 #sidebar a.selected {line-height:1.7em; padding:1px 3px 2px 2px; margin-left:-2px; background-color:#9DB9D5; color:#fff; border-radius:2px;}
128 #sidebar a.selected {line-height:1.7em; padding:1px 3px 2px 2px; margin-left:-2px; background-color:#9DB9D5; color:#fff; border-radius:2px;}
129 #sidebar a.selected:hover {text-decoration:none;}
129 #sidebar a.selected:hover {text-decoration:none;}
130 #admin-menu a {line-height:1.7em;}
130 #admin-menu a {line-height:1.7em;}
131 #admin-menu a.selected {padding-left: 20px !important; background-position: 2px 40%;}
131 #admin-menu a.selected {padding-left: 20px !important; background-position: 2px 40%;}
132
132
133 a.collapsible {padding-left: 12px; background: url(../images/arrow_expanded.png) no-repeat -3px 40%;}
133 a.collapsible {padding-left: 12px; background: url(../images/arrow_expanded.png) no-repeat -3px 40%;}
134 a.collapsible.collapsed {background: url(../images/arrow_collapsed.png) no-repeat -5px 40%;}
134 a.collapsible.collapsed {background: url(../images/arrow_collapsed.png) no-repeat -5px 40%;}
135
135
136 a#toggle-completed-versions {color:#999;}
136 a#toggle-completed-versions {color:#999;}
137
137
138 a.toggle-checkboxes { margin-left: 5px; padding-left: 12px; background: url(../images/toggle_check.png) no-repeat 0% 50%; }
138 a.toggle-checkboxes { margin-left: 5px; padding-left: 12px; background: url(../images/toggle_check.png) no-repeat 0% 50%; }
139
139
140 /***** Tables *****/
140 /***** Tables *****/
141 table.list { border: 1px solid #e4e4e4; border-collapse: collapse; width: 100%; margin-bottom: 4px; }
141 table.list, .table-list { border: 1px solid #e4e4e4; border-collapse: collapse; width: 100%; margin-bottom: 4px; }
142 table.list th { background-color:#EEEEEE; padding: 4px; white-space:nowrap; }
142 table.list th, .table-list-header { background-color:#EEEEEE; padding: 4px; white-space:nowrap; font-weight:bold; }
143 table.list td {text-align:center; vertical-align:top; padding-right:10px;}
143 table.list td {text-align:center; vertical-align:top; padding-right:10px;}
144 table.list td.id { width: 2%; text-align: center;}
144 table.list td.id { width: 2%; text-align: center;}
145 table.list td.name, table.list td.description, table.list td.subject, table.list td.comments, table.list td.roles {text-align: left;}
145 table.list td.name, table.list td.description, table.list td.subject, table.list td.comments, table.list td.roles {text-align: left;}
146 table.list td.tick {width:15%}
146 table.list td.tick {width:15%}
147 table.list td.checkbox { width: 15px; padding: 2px 0 0 0; }
147 table.list td.checkbox { width: 15px; padding: 2px 0 0 0; }
148 table.list td.checkbox input {padding:0px;}
148 table.list td.checkbox input {padding:0px;}
149 table.list td.buttons { width: 15%; white-space:nowrap; text-align: right; }
149 table.list td.buttons, div.buttons { width: 15%; white-space:nowrap; text-align: right; }
150 table.list td.buttons a { margin-right: 0.6em; }
150 table.list td.buttons a, div.buttons a { margin-right: 0.6em; }
151 table.list td.buttons img {vertical-align:middle;}
151 table.list td.buttons img, div.buttons img {vertical-align:middle;}
152 table.list td.reorder {width:15%; white-space:nowrap; text-align:center; }
152 table.list td.reorder {width:15%; white-space:nowrap; text-align:center; }
153 table.list table.progress td {padding-right:0px;}
153 table.list table.progress td {padding-right:0px;}
154 table.list caption { text-align: left; padding: 0.5em 0.5em 0.5em 0; }
154 table.list caption { text-align: left; padding: 0.5em 0.5em 0.5em 0; }
155
155
156 .table-list-cell {display: table-cell; vertical-align: top; padding:2px; }
157
156 tr.project td.name a { white-space:nowrap; }
158 tr.project td.name a { white-space:nowrap; }
157 tr.project.closed, tr.project.archived { color: #aaa; }
159 tr.project.closed, tr.project.archived { color: #aaa; }
158 tr.project.closed a, tr.project.archived a { color: #aaa; }
160 tr.project.closed a, tr.project.archived a { color: #aaa; }
159
161
160 tr.project.idnt td.name span {background: url(../images/bullet_arrow_right.png) no-repeat 0 50%; padding-left: 16px;}
162 tr.project.idnt td.name span {background: url(../images/bullet_arrow_right.png) no-repeat 0 50%; padding-left: 16px;}
161 tr.project.idnt-1 td.name {padding-left: 0.5em;}
163 tr.project.idnt-1 td.name {padding-left: 0.5em;}
162 tr.project.idnt-2 td.name {padding-left: 2em;}
164 tr.project.idnt-2 td.name {padding-left: 2em;}
163 tr.project.idnt-3 td.name {padding-left: 3.5em;}
165 tr.project.idnt-3 td.name {padding-left: 3.5em;}
164 tr.project.idnt-4 td.name {padding-left: 5em;}
166 tr.project.idnt-4 td.name {padding-left: 5em;}
165 tr.project.idnt-5 td.name {padding-left: 6.5em;}
167 tr.project.idnt-5 td.name {padding-left: 6.5em;}
166 tr.project.idnt-6 td.name {padding-left: 8em;}
168 tr.project.idnt-6 td.name {padding-left: 8em;}
167 tr.project.idnt-7 td.name {padding-left: 9.5em;}
169 tr.project.idnt-7 td.name {padding-left: 9.5em;}
168 tr.project.idnt-8 td.name {padding-left: 11em;}
170 tr.project.idnt-8 td.name {padding-left: 11em;}
169 tr.project.idnt-9 td.name {padding-left: 12.5em;}
171 tr.project.idnt-9 td.name {padding-left: 12.5em;}
170
172
171 tr.issue { text-align: center; white-space: nowrap; }
173 tr.issue { text-align: center; white-space: nowrap; }
172 tr.issue td.subject, tr.issue td.category, td.assigned_to, tr.issue td.string, tr.issue td.text, tr.issue td.relations, tr.issue td.parent { white-space: normal; }
174 tr.issue td.subject, tr.issue td.category, td.assigned_to, tr.issue td.string, tr.issue td.text, tr.issue td.relations, tr.issue td.parent { white-space: normal; }
173 tr.issue td.relations { text-align: left; }
175 tr.issue td.relations { text-align: left; }
174 tr.issue td.done_ratio table.progress { margin-left:auto; margin-right: auto;}
176 tr.issue td.done_ratio table.progress { margin-left:auto; margin-right: auto;}
175 tr.issue td.relations span {white-space: nowrap;}
177 tr.issue td.relations span {white-space: nowrap;}
176 table.issues td.description {color:#777; font-size:90%; padding:4px 4px 4px 24px; text-align:left; white-space:normal;}
178 table.issues td.description {color:#777; font-size:90%; padding:4px 4px 4px 24px; text-align:left; white-space:normal;}
177 table.issues td.description pre {white-space:normal;}
179 table.issues td.description pre {white-space:normal;}
178
180
179 tr.issue.idnt td.subject a {background: url(../images/bullet_arrow_right.png) no-repeat 0 50%; padding-left: 16px;}
181 tr.issue.idnt td.subject a {background: url(../images/bullet_arrow_right.png) no-repeat 0 50%; padding-left: 16px;}
180 tr.issue.idnt-1 td.subject {padding-left: 0.5em;}
182 tr.issue.idnt-1 td.subject {padding-left: 0.5em;}
181 tr.issue.idnt-2 td.subject {padding-left: 2em;}
183 tr.issue.idnt-2 td.subject {padding-left: 2em;}
182 tr.issue.idnt-3 td.subject {padding-left: 3.5em;}
184 tr.issue.idnt-3 td.subject {padding-left: 3.5em;}
183 tr.issue.idnt-4 td.subject {padding-left: 5em;}
185 tr.issue.idnt-4 td.subject {padding-left: 5em;}
184 tr.issue.idnt-5 td.subject {padding-left: 6.5em;}
186 tr.issue.idnt-5 td.subject {padding-left: 6.5em;}
185 tr.issue.idnt-6 td.subject {padding-left: 8em;}
187 tr.issue.idnt-6 td.subject {padding-left: 8em;}
186 tr.issue.idnt-7 td.subject {padding-left: 9.5em;}
188 tr.issue.idnt-7 td.subject {padding-left: 9.5em;}
187 tr.issue.idnt-8 td.subject {padding-left: 11em;}
189 tr.issue.idnt-8 td.subject {padding-left: 11em;}
188 tr.issue.idnt-9 td.subject {padding-left: 12.5em;}
190 tr.issue.idnt-9 td.subject {padding-left: 12.5em;}
189
191
190 table.issue-report {table-layout:fixed;}
192 table.issue-report {table-layout:fixed;}
191
193
192 tr.entry { border: 1px solid #f8f8f8; }
194 tr.entry { border: 1px solid #f8f8f8; }
193 tr.entry td { white-space: nowrap; }
195 tr.entry td { white-space: nowrap; }
194 tr.entry td.filename {width:30%; text-align:left;}
196 tr.entry td.filename {width:30%; text-align:left;}
195 tr.entry td.filename_no_report {width:70%; text-align:left;}
197 tr.entry td.filename_no_report {width:70%; text-align:left;}
196 tr.entry td.size { text-align: right; font-size: 90%; }
198 tr.entry td.size { text-align: right; font-size: 90%; }
197 tr.entry td.revision, tr.entry td.author { text-align: center; }
199 tr.entry td.revision, tr.entry td.author { text-align: center; }
198 tr.entry td.age { text-align: right; }
200 tr.entry td.age { text-align: right; }
199 tr.entry.file td.filename a { margin-left: 16px; }
201 tr.entry.file td.filename a { margin-left: 16px; }
200 tr.entry.file td.filename_no_report a { margin-left: 16px; }
202 tr.entry.file td.filename_no_report a { margin-left: 16px; }
201
203
202 tr span.expander {background-image: url(../images/bullet_toggle_plus.png); padding-left: 8px; margin-left: 0; cursor: pointer;}
204 tr span.expander {background-image: url(../images/bullet_toggle_plus.png); padding-left: 8px; margin-left: 0; cursor: pointer;}
203 tr.open span.expander {background-image: url(../images/bullet_toggle_minus.png);}
205 tr.open span.expander {background-image: url(../images/bullet_toggle_minus.png);}
204
206
205 tr.changeset { height: 20px }
207 tr.changeset { height: 20px }
206 tr.changeset ul, ol { margin-top: 0px; margin-bottom: 0px; }
208 tr.changeset ul, ol { margin-top: 0px; margin-bottom: 0px; }
207 tr.changeset td.revision_graph { width: 15%; background-color: #fffffb; }
209 tr.changeset td.revision_graph { width: 15%; background-color: #fffffb; }
208 tr.changeset td.author { text-align: center; width: 15%; white-space:nowrap;}
210 tr.changeset td.author { text-align: center; width: 15%; white-space:nowrap;}
209 tr.changeset td.committed_on { text-align: center; width: 15%; white-space:nowrap;}
211 tr.changeset td.committed_on { text-align: center; width: 15%; white-space:nowrap;}
210
212
211 table.files tbody th {text-align:left;}
213 table.files tbody th {text-align:left;}
212 table.files tr.file td.filename { text-align: left; padding-left: 24px; }
214 table.files tr.file td.filename { text-align: left; padding-left: 24px; }
213 table.files tr.file td.digest { font-size: 80%; }
215 table.files tr.file td.digest { font-size: 80%; }
214
216
215 table.members td.roles, table.memberships td.roles { width: 45%; }
217 table.members td.roles, table.memberships td.roles { width: 45%; }
216
218
217 tr.message { height: 2.6em; }
219 tr.message { height: 2.6em; }
218 tr.message td.subject { padding-left: 20px; }
220 tr.message td.subject { padding-left: 20px; }
219 tr.message td.created_on { white-space: nowrap; }
221 tr.message td.created_on { white-space: nowrap; }
220 tr.message td.last_message { font-size: 80%; white-space: nowrap; }
222 tr.message td.last_message { font-size: 80%; white-space: nowrap; }
221 tr.message.locked td.subject { background: url(../images/locked.png) no-repeat 0 1px; }
223 tr.message.locked td.subject { background: url(../images/locked.png) no-repeat 0 1px; }
222 tr.message.sticky td.subject { background: url(../images/bullet_go.png) no-repeat 0 1px; font-weight: bold; }
224 tr.message.sticky td.subject { background: url(../images/bullet_go.png) no-repeat 0 1px; font-weight: bold; }
223
225
224 tr.version.closed, tr.version.closed a { color: #999; }
226 tr.version.closed, tr.version.closed a { color: #999; }
225 tr.version td.name { padding-left: 20px; }
227 tr.version td.name { padding-left: 20px; }
226 tr.version.shared td.name { background: url(../images/link.png) no-repeat 0% 70%; }
228 tr.version.shared td.name { background: url(../images/link.png) no-repeat 0% 70%; }
227 tr.version td.date, tr.version td.status, tr.version td.sharing { text-align: center; white-space:nowrap; }
229 tr.version td.date, tr.version td.status, tr.version td.sharing { text-align: center; white-space:nowrap; }
228
230
229 tr.user td {width:13%;white-space: nowrap;}
231 tr.user td {width:13%;white-space: nowrap;}
230 td.username, td.firstname, td.lastname, td.email {text-align:left !important;}
232 td.username, td.firstname, td.lastname, td.email {text-align:left !important;}
231 tr.user td.email { width:18%; }
233 tr.user td.email { width:18%; }
232 tr.user.locked, tr.user.registered { color: #aaa; }
234 tr.user.locked, tr.user.registered { color: #aaa; }
233 tr.user.locked a, tr.user.registered a { color: #aaa; }
235 tr.user.locked a, tr.user.registered a { color: #aaa; }
234
236
235 table.permissions td.role {color:#999;font-size:90%;font-weight:normal !important;text-align:center;vertical-align:bottom;}
237 table.permissions td.role {color:#999;font-size:90%;font-weight:normal !important;text-align:center;vertical-align:bottom;}
236
238
237 tr.wiki-page-version td.updated_on, tr.wiki-page-version td.author {text-align:center;}
239 tr.wiki-page-version td.updated_on, tr.wiki-page-version td.author {text-align:center;}
238
240
239 tr.time-entry { text-align: center; white-space: nowrap; }
241 tr.time-entry { text-align: center; white-space: nowrap; }
240 tr.time-entry td.issue, tr.time-entry td.comments, tr.time-entry td.subject, tr.time-entry td.activity { text-align: left; white-space: normal; }
242 tr.time-entry td.issue, tr.time-entry td.comments, tr.time-entry td.subject, tr.time-entry td.activity { text-align: left; white-space: normal; }
241 td.hours { text-align: right; font-weight: bold; padding-right: 0.5em; }
243 td.hours { text-align: right; font-weight: bold; padding-right: 0.5em; }
242 td.hours .hours-dec { font-size: 0.9em; }
244 td.hours .hours-dec { font-size: 0.9em; }
243
245
244 table.plugins td { vertical-align: middle; }
246 table.plugins td { vertical-align: middle; }
245 table.plugins td.configure { text-align: right; padding-right: 1em; }
247 table.plugins td.configure { text-align: right; padding-right: 1em; }
246 table.plugins span.name { font-weight: bold; display: block; margin-bottom: 6px; }
248 table.plugins span.name { font-weight: bold; display: block; margin-bottom: 6px; }
247 table.plugins span.description { display: block; font-size: 0.9em; }
249 table.plugins span.description { display: block; font-size: 0.9em; }
248 table.plugins span.url { display: block; font-size: 0.9em; }
250 table.plugins span.url { display: block; font-size: 0.9em; }
249
251
250 tr.group td { padding: 0.8em 0 0.5em 0.3em; border-bottom: 1px solid #ccc; text-align:left; }
252 tr.group td { padding: 0.8em 0 0.5em 0.3em; border-bottom: 1px solid #ccc; text-align:left; }
251 tr.group span.name {font-weight:bold;}
253 tr.group span.name {font-weight:bold;}
252 tr.group span.count {font-weight:bold; position:relative; top:-1px; color:#fff; font-size:10px; background:#9DB9D5; padding:0px 6px 1px 6px; border-radius:3px; margin-left:4px;}
254 tr.group span.count {font-weight:bold; position:relative; top:-1px; color:#fff; font-size:10px; background:#9DB9D5; padding:0px 6px 1px 6px; border-radius:3px; margin-left:4px;}
253 tr.group span.totals {color: #aaa; font-size: 80%;}
255 tr.group span.totals {color: #aaa; font-size: 80%;}
254 tr.group span.totals .value {font-weight:bold; color:#777;}
256 tr.group span.totals .value {font-weight:bold; color:#777;}
255 tr.group a.toggle-all { color: #aaa; font-size: 80%; display:none; float:right; margin-right:4px;}
257 tr.group a.toggle-all { color: #aaa; font-size: 80%; display:none; float:right; margin-right:4px;}
256 tr.group:hover a.toggle-all { display:inline;}
258 tr.group:hover a.toggle-all { display:inline;}
257 a.toggle-all:hover {text-decoration:none;}
259 a.toggle-all:hover {text-decoration:none;}
258
260
259 table.list tbody tr:hover { background-color:#ffffdd; }
261 table.list tbody tr:hover { background-color:#ffffdd; }
260 table.list tbody tr.group:hover { background-color:inherit; }
262 table.list tbody tr.group:hover { background-color:inherit; }
261 table td {padding:2px;}
263 table td {padding:2px;}
262 table p {margin:0;}
264 table p {margin:0;}
263 .odd {background-color:#f6f7f8;}
265 .odd {background-color:#f6f7f8;}
264 .even {background-color: #fff;}
266 .even {background-color: #fff;}
265
267
266 tr.builtin td.name {font-style:italic;}
268 tr.builtin td.name {font-style:italic;}
267
269
268 a.sort { padding-right: 16px; background-position: 100% 50%; background-repeat: no-repeat; }
270 a.sort { padding-right: 16px; background-position: 100% 50%; background-repeat: no-repeat; }
269 a.sort.asc { background-image: url(../images/sort_asc.png); }
271 a.sort.asc { background-image: url(../images/sort_asc.png); }
270 a.sort.desc { background-image: url(../images/sort_desc.png); }
272 a.sort.desc { background-image: url(../images/sort_desc.png); }
271
273
272 table.boards a.board, h3.comments { background: url(../images/comment.png) no-repeat 0% 50%; padding-left: 20px; }
274 table.boards a.board, h3.comments { background: url(../images/comment.png) no-repeat 0% 50%; padding-left: 20px; }
273 table.boards td.last-message {text-align:left;font-size:80%;}
275 table.boards td.last-message {text-align:left;font-size:80%;}
274
276
277 div.table-list.boards .table-list-cell.name {width: 30%;}
278
275 table.messages td.last_message {text-align:left;}
279 table.messages td.last_message {text-align:left;}
276
280
277 #query_form_content {font-size:90%;}
281 #query_form_content {font-size:90%;}
278
282
279 .query_sort_criteria_count {
283 .query_sort_criteria_count {
280 display: inline-block;
284 display: inline-block;
281 min-width: 1em;
285 min-width: 1em;
282 }
286 }
283
287
284 table.query-columns {
288 table.query-columns {
285 border-collapse: collapse;
289 border-collapse: collapse;
286 border: 0;
290 border: 0;
287 }
291 }
288
292
289 table.query-columns td.buttons {
293 table.query-columns td.buttons {
290 vertical-align: middle;
294 vertical-align: middle;
291 text-align: center;
295 text-align: center;
292 }
296 }
293 table.query-columns td.buttons input[type=button] {width:35px;}
297 table.query-columns td.buttons input[type=button] {width:35px;}
294 .query-totals {text-align:right; margin-top:-2.3em;}
298 .query-totals {text-align:right; margin-top:-2.3em;}
295 .query-totals>span {margin-left:0.6em;}
299 .query-totals>span {margin-left:0.6em;}
296 .query-totals .value {font-weight:bold;}
300 .query-totals .value {font-weight:bold;}
297
301
298 td.center {text-align:center;}
302 td.center {text-align:center;}
299
303
300 h3.version { background: url(../images/package.png) no-repeat 0% 50%; padding-left: 20px; }
304 h3.version { background: url(../images/package.png) no-repeat 0% 50%; padding-left: 20px; }
301
305
302 div.issues h3 { background: url(../images/ticket.png) no-repeat 0% 50%; padding-left: 20px; }
306 div.issues h3 { background: url(../images/ticket.png) no-repeat 0% 50%; padding-left: 20px; }
303 div.members h3 { background: url(../images/group.png) no-repeat 0% 50%; padding-left: 20px; }
307 div.members h3 { background: url(../images/group.png) no-repeat 0% 50%; padding-left: 20px; }
304 div.news h3 { background: url(../images/news.png) no-repeat 0% 50%; padding-left: 20px; }
308 div.news h3 { background: url(../images/news.png) no-repeat 0% 50%; padding-left: 20px; }
305 div.projects h3 { background: url(../images/projects.png) no-repeat 0% 50%; padding-left: 20px; }
309 div.projects h3 { background: url(../images/projects.png) no-repeat 0% 50%; padding-left: 20px; }
306
310
307 #watchers select {width: 95%; display: block;}
311 #watchers select {width: 95%; display: block;}
308 #watchers a.delete {opacity: 0.4; margin-left: 5px;}
312 #watchers a.delete {opacity: 0.4; margin-left: 5px;}
309 #watchers a.delete:hover {opacity: 1;}
313 #watchers a.delete:hover {opacity: 1;}
310 #watchers img.gravatar {margin: 0 4px 2px 0;}
314 #watchers img.gravatar {margin: 0 4px 2px 0;}
311
315
312 span#watchers_inputs {overflow:auto; display:block;}
316 span#watchers_inputs {overflow:auto; display:block;}
313 span.search_for_watchers {display:block;}
317 span.search_for_watchers {display:block;}
314 span.search_for_watchers, span.add_attachment {font-size:80%; line-height:2.5em;}
318 span.search_for_watchers, span.add_attachment {font-size:80%; line-height:2.5em;}
315 span.search_for_watchers a, span.add_attachment a {padding-left:16px; background: url(../images/bullet_add.png) no-repeat 0 50%; }
319 span.search_for_watchers a, span.add_attachment a {padding-left:16px; background: url(../images/bullet_add.png) no-repeat 0 50%; }
316
320
317
321
318 .highlight { background-color: #FCFD8D;}
322 .highlight { background-color: #FCFD8D;}
319 .highlight.token-1 { background-color: #faa;}
323 .highlight.token-1 { background-color: #faa;}
320 .highlight.token-2 { background-color: #afa;}
324 .highlight.token-2 { background-color: #afa;}
321 .highlight.token-3 { background-color: #aaf;}
325 .highlight.token-3 { background-color: #aaf;}
322
326
323 .box{
327 .box{
324 padding:6px;
328 padding:6px;
325 margin-bottom: 10px;
329 margin-bottom: 10px;
326 background-color:#f6f6f6;
330 background-color:#f6f6f6;
327 color:#505050;
331 color:#505050;
328 line-height:1.5em;
332 line-height:1.5em;
329 border: 1px solid #e4e4e4;
333 border: 1px solid #e4e4e4;
330 word-wrap: break-word;
334 word-wrap: break-word;
331 border-radius: 3px;
335 border-radius: 3px;
332 }
336 }
333 .pagination .per-page span.selected {
337 .pagination .per-page span.selected {
334 font-weight: bold;
338 font-weight: bold;
335 }
339 }
336
340
337 div.square {
341 div.square {
338 border: 1px solid #999;
342 border: 1px solid #999;
339 float: left;
343 float: left;
340 margin: .3em .4em 0 .4em;
344 margin: .3em .4em 0 .4em;
341 overflow: hidden;
345 overflow: hidden;
342 width: .6em; height: .6em;
346 width: .6em; height: .6em;
343 }
347 }
344 .contextual {float:right; white-space: nowrap; line-height:1.4em;margin-top:5px; padding-left: 10px; font-size:0.9em;}
348 .contextual {float:right; white-space: nowrap; line-height:1.4em;margin-top:5px; padding-left: 10px; font-size:0.9em;}
345 .contextual input, .contextual select {font-size:0.9em;}
349 .contextual input, .contextual select {font-size:0.9em;}
346 .message .contextual { margin-top: 0; }
350 .message .contextual { margin-top: 0; }
347
351
348 .splitcontent {overflow:auto;}
352 .splitcontent {overflow:auto;}
349 .splitcontentleft{float:left; width:49%;}
353 .splitcontentleft{float:left; width:49%;}
350 .splitcontentright{float:right; width:49%;}
354 .splitcontentright{float:right; width:49%;}
351 form {display: inline;}
355 form {display: inline;}
352 input, select {vertical-align: middle; margin-top: 1px; margin-bottom: 1px;}
356 input, select {vertical-align: middle; margin-top: 1px; margin-bottom: 1px;}
353 fieldset {border: 1px solid #e4e4e4; margin:0;}
357 fieldset {border: 1px solid #e4e4e4; margin:0;}
354 legend {color: #333;}
358 legend {color: #333;}
355 hr { width: 100%; height: 1px; background: #ccc; border: 0;}
359 hr { width: 100%; height: 1px; background: #ccc; border: 0;}
356 blockquote { font-style: italic; border-left: 3px solid #e0e0e0; padding-left: 0.6em; margin-left: 2.4em;}
360 blockquote { font-style: italic; border-left: 3px solid #e0e0e0; padding-left: 0.6em; margin-left: 2.4em;}
357 blockquote blockquote { margin-left: 0;}
361 blockquote blockquote { margin-left: 0;}
358 abbr, span.field-description[title] { border-bottom: 1px dotted #aaa; cursor: help; }
362 abbr, span.field-description[title] { border-bottom: 1px dotted #aaa; cursor: help; }
359 textarea.wiki-edit {width:99%; resize:vertical;}
363 textarea.wiki-edit {width:99%; resize:vertical;}
360 li p {margin-top: 0;}
364 li p {margin-top: 0;}
361 div.issue {background:#ffffdd; padding:6px; margin-bottom:6px; border: 1px solid #d7d7d7; border-radius:3px;}
365 div.issue {background:#ffffdd; padding:6px; margin-bottom:6px; border: 1px solid #d7d7d7; border-radius:3px;}
362 p.breadcrumb { font-size: 0.9em; margin: 4px 0 4px 0;}
366 p.breadcrumb { font-size: 0.9em; margin: 4px 0 4px 0;}
363 p.subtitle { font-size: 0.9em; margin: -6px 0 12px 0; font-style: italic; }
367 p.subtitle { font-size: 0.9em; margin: -6px 0 12px 0; font-style: italic; }
364 p.footnote { font-size: 0.9em; margin-top: 0px; margin-bottom: 0px; }
368 p.footnote { font-size: 0.9em; margin-top: 0px; margin-bottom: 0px; }
365 .ltr {direction:ltr !important; unicode-bidi:bidi-override;}
369 .ltr {direction:ltr !important; unicode-bidi:bidi-override;}
366 .rtl {direction:rtl !important; unicode-bidi:bidi-override;}
370 .rtl {direction:rtl !important; unicode-bidi:bidi-override;}
367
371
368 div.issue div.subject div div { padding-left: 16px; }
372 div.issue div.subject div div { padding-left: 16px; }
369 div.issue div.subject p {margin: 0; margin-bottom: 0.1em; font-size: 90%; color: #999;}
373 div.issue div.subject p {margin: 0; margin-bottom: 0.1em; font-size: 90%; color: #999;}
370 div.issue div.subject>div>p { margin-top: 0.5em; }
374 div.issue div.subject>div>p { margin-top: 0.5em; }
371 div.issue div.subject h3 {margin: 0; margin-bottom: 0.1em;}
375 div.issue div.subject h3 {margin: 0; margin-bottom: 0.1em;}
372 div.issue span.private, div.journal span.private { position:relative; bottom: 2px; text-transform: uppercase; background: #d22; color: #fff; font-weight:bold; padding: 0px 2px 0px 2px; font-size: 60%; margin-right: 2px; border-radius: 2px;}
376 div.issue span.private, div.journal span.private { position:relative; bottom: 2px; text-transform: uppercase; background: #d22; color: #fff; font-weight:bold; padding: 0px 2px 0px 2px; font-size: 60%; margin-right: 2px; border-radius: 2px;}
373 div.issue .next-prev-links {color:#999;}
377 div.issue .next-prev-links {color:#999;}
374 div.issue .attributes {margin-top: 2em;}
378 div.issue .attributes {margin-top: 2em;}
375 div.issue .attribute {padding-left:180px; clear:left; min-height: 1.8em;}
379 div.issue .attribute {padding-left:180px; clear:left; min-height: 1.8em;}
376 div.issue .attribute .label {width: 170px; margin-left:-180px; font-weight:bold; float:left;}
380 div.issue .attribute .label {width: 170px; margin-left:-180px; font-weight:bold; float:left;}
377 div.issue.overdue .due-date .value { color: #c22; }
381 div.issue.overdue .due-date .value { color: #c22; }
378
382
379 #issue_tree table.issues, #relations table.issues { border: 0; }
383 #issue_tree table.issues, #relations table.issues { border: 0; }
380 #issue_tree td.checkbox, #relations td.checkbox {display:none;}
384 #issue_tree td.checkbox, #relations td.checkbox {display:none;}
381 #relations td.buttons {padding:0;}
385 #relations td.buttons {padding:0;}
382
386
383 fieldset.collapsible {border-width: 1px 0 0 0;}
387 fieldset.collapsible {border-width: 1px 0 0 0;}
384 fieldset.collapsible>legend { padding-left: 16px; background: url(../images/arrow_expanded.png) no-repeat 0% 40%; cursor:pointer; }
388 fieldset.collapsible>legend { padding-left: 16px; background: url(../images/arrow_expanded.png) no-repeat 0% 40%; cursor:pointer; }
385 fieldset.collapsible.collapsed>legend { background-image: url(../images/arrow_collapsed.png); }
389 fieldset.collapsible.collapsed>legend { background-image: url(../images/arrow_collapsed.png); }
386
390
387 fieldset#date-range p { margin: 2px 0 2px 0; }
391 fieldset#date-range p { margin: 2px 0 2px 0; }
388 fieldset#filters table { border-collapse: collapse; }
392 fieldset#filters table { border-collapse: collapse; }
389 fieldset#filters table td { padding: 0; vertical-align: middle; }
393 fieldset#filters table td { padding: 0; vertical-align: middle; }
390 fieldset#filters tr.filter { height: 2.1em; }
394 fieldset#filters tr.filter { height: 2.1em; }
391 fieldset#filters td.field { width:230px; }
395 fieldset#filters td.field { width:230px; }
392 fieldset#filters td.operator { width:180px; }
396 fieldset#filters td.operator { width:180px; }
393 fieldset#filters td.operator select {max-width:170px;}
397 fieldset#filters td.operator select {max-width:170px;}
394 fieldset#filters td.values { white-space:nowrap; }
398 fieldset#filters td.values { white-space:nowrap; }
395 fieldset#filters td.values select {min-width:130px;}
399 fieldset#filters td.values select {min-width:130px;}
396 fieldset#filters td.values input {height:1em;}
400 fieldset#filters td.values input {height:1em;}
397
401
398 #filters-table {width:60%; float:left;}
402 #filters-table {width:60%; float:left;}
399 .add-filter {width:35%; float:right; text-align: right; vertical-align: top;}
403 .add-filter {width:35%; float:right; text-align: right; vertical-align: top;}
400
404
401 #issue_is_private_wrap {float:right; margin-right:1em;}
405 #issue_is_private_wrap {float:right; margin-right:1em;}
402 .toggle-multiselect {background: url(../images/bullet_toggle_plus.png) no-repeat 0% 40%; padding-left:16px; margin-left:0; margin-right:5px; cursor:pointer;}
406 .toggle-multiselect {background: url(../images/bullet_toggle_plus.png) no-repeat 0% 40%; padding-left:16px; margin-left:0; margin-right:5px; cursor:pointer;}
403 .buttons { font-size: 0.9em; margin-bottom: 1.4em; margin-top: 1em; }
407 .buttons { font-size: 0.9em; margin-bottom: 1.4em; margin-top: 1em; }
404
408
405 div#issue-changesets {float:right; width:45%; margin-left: 1em; margin-bottom: 1em; background: #fff; padding-left: 1em; font-size: 90%;}
409 div#issue-changesets {float:right; width:45%; margin-left: 1em; margin-bottom: 1em; background: #fff; padding-left: 1em; font-size: 90%;}
406 div#issue-changesets div.changeset { padding: 4px;}
410 div#issue-changesets div.changeset { padding: 4px;}
407 div#issue-changesets div.changeset { border-bottom: 1px solid #ddd; }
411 div#issue-changesets div.changeset { border-bottom: 1px solid #ddd; }
408 div#issue-changesets p { margin-top: 0; margin-bottom: 1em;}
412 div#issue-changesets p { margin-top: 0; margin-bottom: 1em;}
409
413
410 .journal ul.details img {margin:0 0 -3px 4px;}
414 .journal ul.details img {margin:0 0 -3px 4px;}
411 div.journal {overflow:auto;}
415 div.journal {overflow:auto;}
412 div.journal.private-notes {border-left:2px solid #d22; padding-left:4px; margin-left:-6px;}
416 div.journal.private-notes {border-left:2px solid #d22; padding-left:4px; margin-left:-6px;}
413 div.journal ul.details {color:#959595; margin-bottom: 1.5em;}
417 div.journal ul.details {color:#959595; margin-bottom: 1.5em;}
414 div.journal ul.details a {color:#70A7CD;}
418 div.journal ul.details a {color:#70A7CD;}
415 div.journal ul.details a:hover {color:#D14848;}
419 div.journal ul.details a:hover {color:#D14848;}
416
420
417 div#activity dl, #search-results { margin-left: 2em; }
421 div#activity dl, #search-results { margin-left: 2em; }
418 div#activity dd, #search-results dd { margin-bottom: 1em; padding-left: 18px; font-size: 0.9em; }
422 div#activity dd, #search-results dd { margin-bottom: 1em; padding-left: 18px; font-size: 0.9em; }
419 div#activity dt, #search-results dt { margin-bottom: 0px; padding-left: 20px; line-height: 18px; background-position: 0 50%; background-repeat: no-repeat; }
423 div#activity dt, #search-results dt { margin-bottom: 0px; padding-left: 20px; line-height: 18px; background-position: 0 50%; background-repeat: no-repeat; }
420 div#activity dt.me .time { border-bottom: 1px solid #999; }
424 div#activity dt.me .time { border-bottom: 1px solid #999; }
421 div#activity dt .time { color: #777; font-size: 80%; }
425 div#activity dt .time { color: #777; font-size: 80%; }
422 div#activity dd .description, #search-results dd .description { font-style: italic; }
426 div#activity dd .description, #search-results dd .description { font-style: italic; }
423 div#activity span.project:after, #search-results span.project:after { content: " -"; }
427 div#activity span.project:after, #search-results span.project:after { content: " -"; }
424 div#activity dd span.description, #search-results dd span.description { display:block; color: #808080; }
428 div#activity dd span.description, #search-results dd span.description { display:block; color: #808080; }
425 div#activity dt.grouped {margin-left:5em;}
429 div#activity dt.grouped {margin-left:5em;}
426 div#activity dd.grouped {margin-left:9em;}
430 div#activity dd.grouped {margin-left:9em;}
427
431
428 #search-results dd { margin-bottom: 1em; padding-left: 20px; margin-left:0px; }
432 #search-results dd { margin-bottom: 1em; padding-left: 20px; margin-left:0px; }
429
433
430 div#search-results-counts {float:right;}
434 div#search-results-counts {float:right;}
431 div#search-results-counts ul { margin-top: 0.5em; }
435 div#search-results-counts ul { margin-top: 0.5em; }
432 div#search-results-counts li { list-style-type:none; float: left; margin-left: 1em; }
436 div#search-results-counts li { list-style-type:none; float: left; margin-left: 1em; }
433
437
434 dt.issue { background-image: url(../images/ticket.png); }
438 dt.issue { background-image: url(../images/ticket.png); }
435 dt.issue-edit { background-image: url(../images/ticket_edit.png); }
439 dt.issue-edit { background-image: url(../images/ticket_edit.png); }
436 dt.issue-closed { background-image: url(../images/ticket_checked.png); }
440 dt.issue-closed { background-image: url(../images/ticket_checked.png); }
437 dt.issue-note { background-image: url(../images/ticket_note.png); }
441 dt.issue-note { background-image: url(../images/ticket_note.png); }
438 dt.changeset { background-image: url(../images/changeset.png); }
442 dt.changeset { background-image: url(../images/changeset.png); }
439 dt.news { background-image: url(../images/news.png); }
443 dt.news { background-image: url(../images/news.png); }
440 dt.message { background-image: url(../images/message.png); }
444 dt.message { background-image: url(../images/message.png); }
441 dt.reply { background-image: url(../images/comments.png); }
445 dt.reply { background-image: url(../images/comments.png); }
442 dt.wiki-page { background-image: url(../images/wiki_edit.png); }
446 dt.wiki-page { background-image: url(../images/wiki_edit.png); }
443 dt.attachment { background-image: url(../images/attachment.png); }
447 dt.attachment { background-image: url(../images/attachment.png); }
444 dt.document { background-image: url(../images/document.png); }
448 dt.document { background-image: url(../images/document.png); }
445 dt.project { background-image: url(../images/projects.png); }
449 dt.project { background-image: url(../images/projects.png); }
446 dt.time-entry { background-image: url(../images/time.png); }
450 dt.time-entry { background-image: url(../images/time.png); }
447
451
448 #search-results dt.issue.closed { background-image: url(../images/ticket_checked.png); }
452 #search-results dt.issue.closed { background-image: url(../images/ticket_checked.png); }
449
453
450 div#roadmap .related-issues { margin-bottom: 1em; }
454 div#roadmap .related-issues { margin-bottom: 1em; }
451 div#roadmap .related-issues td.checkbox { display: none; }
455 div#roadmap .related-issues td.checkbox { display: none; }
452 div#roadmap .wiki h1:first-child { display: none; }
456 div#roadmap .wiki h1:first-child { display: none; }
453 div#roadmap .wiki h1 { font-size: 120%; }
457 div#roadmap .wiki h1 { font-size: 120%; }
454 div#roadmap .wiki h2 { font-size: 110%; }
458 div#roadmap .wiki h2 { font-size: 110%; }
455 body.controller-versions.action-show div#roadmap .related-issues {width:70%;}
459 body.controller-versions.action-show div#roadmap .related-issues {width:70%;}
456
460
457 div#version-summary { float:right; width:28%; margin-left: 16px; margin-bottom: 16px; background-color: #fff; }
461 div#version-summary { float:right; width:28%; margin-left: 16px; margin-bottom: 16px; background-color: #fff; }
458 div#version-summary fieldset { margin-bottom: 1em; }
462 div#version-summary fieldset { margin-bottom: 1em; }
459 div#version-summary fieldset.time-tracking table { width:100%; }
463 div#version-summary fieldset.time-tracking table { width:100%; }
460 div#version-summary th, div#version-summary td.total-hours { text-align: right; }
464 div#version-summary th, div#version-summary td.total-hours { text-align: right; }
461
465
462 table#time-report td.hours, table#time-report th.period, table#time-report th.total { text-align: right; padding-right: 0.5em; }
466 table#time-report td.hours, table#time-report th.period, table#time-report th.total { text-align: right; padding-right: 0.5em; }
463 table#time-report tbody tr.subtotal { font-style: italic; color:#777;}
467 table#time-report tbody tr.subtotal { font-style: italic; color:#777;}
464 table#time-report tbody tr.subtotal td.hours { color:#b0b0b0; }
468 table#time-report tbody tr.subtotal td.hours { color:#b0b0b0; }
465 table#time-report tbody tr.total { font-weight: bold; background-color:#EEEEEE; border-top:1px solid #e4e4e4;}
469 table#time-report tbody tr.total { font-weight: bold; background-color:#EEEEEE; border-top:1px solid #e4e4e4;}
466 table#time-report .hours-dec { font-size: 0.9em; }
470 table#time-report .hours-dec { font-size: 0.9em; }
467
471
468 div.wiki-page .contextual a {opacity: 0.4}
472 div.wiki-page .contextual a {opacity: 0.4}
469 div.wiki-page .contextual a:hover {opacity: 1}
473 div.wiki-page .contextual a:hover {opacity: 1}
470
474
471 form .attributes select { width: 60%; }
475 form .attributes select { width: 60%; }
472 form .attributes select + a.icon-only { vertical-align: middle; margin-left: 4px; }
476 form .attributes select + a.icon-only { vertical-align: middle; margin-left: 4px; }
473 input#issue_subject, input#document_title { width: 99%; }
477 input#issue_subject, input#document_title { width: 99%; }
474 select#issue_done_ratio { width: 95px; }
478 select#issue_done_ratio { width: 95px; }
475
479
476 ul.projects {margin:0; padding-left:1em;}
480 ul.projects {margin:0; padding-left:1em;}
477 ul.projects ul {padding-left:1.6em;}
481 ul.projects ul {padding-left:1.6em;}
478 ul.projects.root {margin:0; padding:0;}
482 ul.projects.root {margin:0; padding:0;}
479 ul.projects li {list-style-type:none;}
483 ul.projects li {list-style-type:none;}
480
484
481 #projects-index ul.projects ul.projects { border-left: 3px solid #e0e0e0; padding-left:1em;}
485 #projects-index ul.projects ul.projects { border-left: 3px solid #e0e0e0; padding-left:1em;}
482 #projects-index ul.projects li.root {margin-bottom: 1em;}
486 #projects-index ul.projects li.root {margin-bottom: 1em;}
483 #projects-index ul.projects li.child {margin-top: 1em;}
487 #projects-index ul.projects li.child {margin-top: 1em;}
484 #projects-index ul.projects div.root a.project { font-family: "Trebuchet MS", Verdana, sans-serif; font-weight: bold; font-size: 16px; margin: 0 0 10px 0; }
488 #projects-index ul.projects div.root a.project { font-family: "Trebuchet MS", Verdana, sans-serif; font-weight: bold; font-size: 16px; margin: 0 0 10px 0; }
485 .my-project { padding-left: 18px; background: url(../images/fav.png) no-repeat 0 50%; }
489 .my-project { padding-left: 18px; background: url(../images/fav.png) no-repeat 0 50%; }
486
490
487 #notified-projects>ul, #tracker_project_ids>ul, #custom_field_project_ids>ul {max-height:250px; overflow-y:auto;}
491 #notified-projects>ul, #tracker_project_ids>ul, #custom_field_project_ids>ul {max-height:250px; overflow-y:auto;}
488
492
489 #related-issues li img {vertical-align:middle;}
493 #related-issues li img {vertical-align:middle;}
490
494
491 ul.properties {padding:0; font-size: 0.9em; color: #777;}
495 ul.properties {padding:0; font-size: 0.9em; color: #777;}
492 ul.properties li {list-style-type:none;}
496 ul.properties li {list-style-type:none;}
493 ul.properties li span {font-style:italic;}
497 ul.properties li span {font-style:italic;}
494
498
495 .total-hours { font-size: 110%; font-weight: bold; }
499 .total-hours { font-size: 110%; font-weight: bold; }
496 .total-hours span.hours-int { font-size: 120%; }
500 .total-hours span.hours-int { font-size: 120%; }
497
501
498 .autoscroll {overflow-x: auto; padding:1px; margin-bottom: 1.2em; position: relative;}
502 .autoscroll {overflow-x: auto; padding:1px; margin-bottom: 1.2em; position: relative;}
499 #user_login, #user_firstname, #user_lastname, #user_mail, #my_account_form select, #user_form select, #user_identity_url { width: 90%; }
503 #user_login, #user_firstname, #user_lastname, #user_mail, #my_account_form select, #user_form select, #user_identity_url { width: 90%; }
500
504
501 #workflow_copy_form select { width: 200px; }
505 #workflow_copy_form select { width: 200px; }
502 table.transitions td.enabled {background: #bfb;}
506 table.transitions td.enabled {background: #bfb;}
503 #workflow_form table select {font-size:90%; max-width:100px;}
507 #workflow_form table select {font-size:90%; max-width:100px;}
504 table.fields_permissions td.readonly {background:#ddd;}
508 table.fields_permissions td.readonly {background:#ddd;}
505 table.fields_permissions td.required {background:#d88;}
509 table.fields_permissions td.required {background:#d88;}
506
510
507 select.expandable {vertical-align:top;}
511 select.expandable {vertical-align:top;}
508
512
509 textarea#custom_field_possible_values {width: 95%; resize:vertical}
513 textarea#custom_field_possible_values {width: 95%; resize:vertical}
510 textarea#custom_field_default_value {width: 95%; resize:vertical}
514 textarea#custom_field_default_value {width: 95%; resize:vertical}
511 .sort-handle {display:inline-block; vertical-align:middle;}
515 .sort-handle {display:inline-block; vertical-align:middle;}
512
516
513 input#content_comments {width: 99%}
517 input#content_comments {width: 99%}
514
518
515 span.pagination {margin-left:3px; color:#888;}
519 span.pagination {margin-left:3px; color:#888;}
516 .pagination ul.pages {
520 .pagination ul.pages {
517 margin: 0 5px 0 0;
521 margin: 0 5px 0 0;
518 padding: 0;
522 padding: 0;
519 display: inline;
523 display: inline;
520 }
524 }
521 .pagination ul.pages li {
525 .pagination ul.pages li {
522 display: inline-block;
526 display: inline-block;
523 padding: 0;
527 padding: 0;
524 border: 1px solid #ccc;
528 border: 1px solid #ccc;
525 margin-left: -1px;
529 margin-left: -1px;
526 line-height: 2em;
530 line-height: 2em;
527 margin-bottom: 1em;
531 margin-bottom: 1em;
528 white-space: nowrap;
532 white-space: nowrap;
529 text-align: center;
533 text-align: center;
530 }
534 }
531 .pagination ul.pages li a,
535 .pagination ul.pages li a,
532 .pagination ul.pages li span {
536 .pagination ul.pages li span {
533 padding: 3px 8px;
537 padding: 3px 8px;
534 }
538 }
535 .pagination ul.pages li:first-child {
539 .pagination ul.pages li:first-child {
536 border-top-left-radius: 4px;
540 border-top-left-radius: 4px;
537 border-bottom-left-radius: 4px;
541 border-bottom-left-radius: 4px;
538 }
542 }
539 .pagination ul.pages li:last-child {
543 .pagination ul.pages li:last-child {
540 border-top-right-radius: 4px;
544 border-top-right-radius: 4px;
541 border-bottom-right-radius: 4px;
545 border-bottom-right-radius: 4px;
542 }
546 }
543 .pagination ul.pages li.current {
547 .pagination ul.pages li.current {
544 color: white;
548 color: white;
545 background-color: #628DB6;
549 background-color: #628DB6;
546 border-color: #628DB6;
550 border-color: #628DB6;
547 }
551 }
548 .pagination ul.pages li.page:hover {
552 .pagination ul.pages li.page:hover {
549 background-color: #EEE;
553 background-color: #EEE;
550 }
554 }
551 .pagination ul.pages li.page a:hover,
555 .pagination ul.pages li.page a:hover,
552 .pagination ul.pages li.page a:active {
556 .pagination ul.pages li.page a:active {
553 color: inherit;
557 color: inherit;
554 text-decoration: inherit;
558 text-decoration: inherit;
555 }
559 }
556 span.pagination>span {white-space:nowrap;}
560 span.pagination>span {white-space:nowrap;}
557
561
558 #search-form fieldset p {margin:0.2em 0;}
562 #search-form fieldset p {margin:0.2em 0;}
559
563
560 /***** Tabular forms ******/
564 /***** Tabular forms ******/
561 .tabular p{
565 .tabular p{
562 margin: 0;
566 margin: 0;
563 padding: 3px 0 3px 0;
567 padding: 3px 0 3px 0;
564 padding-left: 180px; /* width of left column containing the label elements */
568 padding-left: 180px; /* width of left column containing the label elements */
565 min-height: 1.8em;
569 min-height: 1.8em;
566 clear:left;
570 clear:left;
567 }
571 }
568
572
569 html>body .tabular p {overflow:hidden;}
573 html>body .tabular p {overflow:hidden;}
570
574
571 .tabular input, .tabular select {max-width:95%}
575 .tabular input, .tabular select {max-width:95%}
572 .tabular textarea {width:95%; resize:vertical;}
576 .tabular textarea {width:95%; resize:vertical;}
573
577
574 .tabular label{
578 .tabular label{
575 font-weight: bold;
579 font-weight: bold;
576 float: left;
580 float: left;
577 text-align: right;
581 text-align: right;
578 /* width of left column */
582 /* width of left column */
579 margin-left: -180px;
583 margin-left: -180px;
580 /* width of labels. Should be smaller than left column to create some right margin */
584 /* width of labels. Should be smaller than left column to create some right margin */
581 width: 175px;
585 width: 175px;
582 }
586 }
583
587
584 .tabular label.floating{
588 .tabular label.floating{
585 font-weight: normal;
589 font-weight: normal;
586 margin-left: 0px;
590 margin-left: 0px;
587 text-align: left;
591 text-align: left;
588 width: 270px;
592 width: 270px;
589 }
593 }
590
594
591 .tabular label.block{
595 .tabular label.block{
592 font-weight: normal;
596 font-weight: normal;
593 margin-left: 0px !important;
597 margin-left: 0px !important;
594 text-align: left;
598 text-align: left;
595 float: none;
599 float: none;
596 display: block;
600 display: block;
597 width: auto !important;
601 width: auto !important;
598 }
602 }
599
603
600 .tabular label.inline{
604 .tabular label.inline{
601 font-weight: normal;
605 font-weight: normal;
602 float:none;
606 float:none;
603 margin-left: 5px !important;
607 margin-left: 5px !important;
604 width: auto;
608 width: auto;
605 }
609 }
606
610
607 label.no-css {
611 label.no-css {
608 font-weight: inherit;
612 font-weight: inherit;
609 float:none;
613 float:none;
610 text-align:left;
614 text-align:left;
611 margin-left:0px;
615 margin-left:0px;
612 width:auto;
616 width:auto;
613 }
617 }
614 input#time_entry_comments { width: 90%;}
618 input#time_entry_comments { width: 90%;}
615
619
616 #preview fieldset {margin-top: 1em; background: url(../images/draft.png)}
620 #preview fieldset {margin-top: 1em; background: url(../images/draft.png)}
617
621
618 .tabular.settings p{ padding-left: 300px; }
622 .tabular.settings p{ padding-left: 300px; }
619 .tabular.settings label{ margin-left: -300px; width: 295px; }
623 .tabular.settings label{ margin-left: -300px; width: 295px; }
620 .tabular.settings textarea { width: 99%; }
624 .tabular.settings textarea { width: 99%; }
621
625
622 .settings.enabled_scm table {width:100%}
626 .settings.enabled_scm table {width:100%}
623 .settings.enabled_scm td.scm_name{ font-weight: bold; }
627 .settings.enabled_scm td.scm_name{ font-weight: bold; }
624
628
625 fieldset.settings label { display: block; }
629 fieldset.settings label { display: block; }
626 fieldset#notified_events .parent { padding-left: 20px; }
630 fieldset#notified_events .parent { padding-left: 20px; }
627
631
628 span.required {color: #bb0000;}
632 span.required {color: #bb0000;}
629 .summary {font-style: italic;}
633 .summary {font-style: italic;}
630
634
631 .check_box_group {
635 .check_box_group {
632 display:block;
636 display:block;
633 width:95%;
637 width:95%;
634 max-height:300px;
638 max-height:300px;
635 overflow-y:auto;
639 overflow-y:auto;
636 padding:2px 4px 4px 2px;
640 padding:2px 4px 4px 2px;
637 background:#fff;
641 background:#fff;
638 border:1px solid #9EB1C2;
642 border:1px solid #9EB1C2;
639 border-radius:2px
643 border-radius:2px
640 }
644 }
641 .check_box_group label {
645 .check_box_group label {
642 font-weight: normal;
646 font-weight: normal;
643 margin-left: 0px !important;
647 margin-left: 0px !important;
644 text-align: left;
648 text-align: left;
645 float: none;
649 float: none;
646 display: block;
650 display: block;
647 width: auto;
651 width: auto;
648 }
652 }
649 .check_box_group.bool_cf {border:0; background:inherit;}
653 .check_box_group.bool_cf {border:0; background:inherit;}
650 .check_box_group.bool_cf label {display: inline;}
654 .check_box_group.bool_cf label {display: inline;}
651
655
652 #attachments_fields input.description {margin-left:4px; width:340px;}
656 #attachments_fields input.description {margin-left:4px; width:340px;}
653 #attachments_fields span {display:block; white-space:nowrap;}
657 #attachments_fields span {display:block; white-space:nowrap;}
654 #attachments_fields input.filename {border:0; height:1.8em; width:250px; color:#555; background-color:inherit; background:url(../images/attachment.png) no-repeat 1px 50%; padding-left:18px;}
658 #attachments_fields input.filename {border:0; height:1.8em; width:250px; color:#555; background-color:inherit; background:url(../images/attachment.png) no-repeat 1px 50%; padding-left:18px;}
655 #attachments_fields .ajax-waiting input.filename {background:url(../images/hourglass.png) no-repeat 0px 50%;}
659 #attachments_fields .ajax-waiting input.filename {background:url(../images/hourglass.png) no-repeat 0px 50%;}
656 #attachments_fields .ajax-loading input.filename {background:url(../images/loading.gif) no-repeat 0px 50%;}
660 #attachments_fields .ajax-loading input.filename {background:url(../images/loading.gif) no-repeat 0px 50%;}
657 #attachments_fields div.ui-progressbar { width: 100px; height:14px; margin: 2px 0 -5px 8px; display: inline-block; }
661 #attachments_fields div.ui-progressbar { width: 100px; height:14px; margin: 2px 0 -5px 8px; display: inline-block; }
658 a.remove-upload {background: url(../images/delete.png) no-repeat 1px 50%; width:1px; display:inline-block; padding-left:16px;}
662 a.remove-upload {background: url(../images/delete.png) no-repeat 1px 50%; width:1px; display:inline-block; padding-left:16px;}
659 a.remove-upload:hover {text-decoration:none !important;}
663 a.remove-upload:hover {text-decoration:none !important;}
660
664
661 div.fileover { background-color: lavender; }
665 div.fileover { background-color: lavender; }
662
666
663 div.attachments { margin-top: 12px; }
667 div.attachments { margin-top: 12px; }
664 div.attachments p { margin:4px 0 2px 0; }
668 div.attachments p { margin:4px 0 2px 0; }
665 div.attachments img { vertical-align: middle; }
669 div.attachments img { vertical-align: middle; }
666 div.attachments span.author { font-size: 0.9em; color: #888; }
670 div.attachments span.author { font-size: 0.9em; color: #888; }
667
671
668 div.thumbnails {margin-top:0.6em;}
672 div.thumbnails {margin-top:0.6em;}
669 div.thumbnails div {background:#fff;border:2px solid #ddd;display:inline-block;margin-right:2px;}
673 div.thumbnails div {background:#fff;border:2px solid #ddd;display:inline-block;margin-right:2px;}
670 div.thumbnails img {margin: 3px; vertical-align: middle;}
674 div.thumbnails img {margin: 3px; vertical-align: middle;}
671 #history div.thumbnails {margin-left: 2em;}
675 #history div.thumbnails {margin-left: 2em;}
672
676
673 p.other-formats { text-align: right; font-size:0.9em; color: #666; }
677 p.other-formats { text-align: right; font-size:0.9em; color: #666; }
674 .other-formats span + span:before { content: "| "; }
678 .other-formats span + span:before { content: "| "; }
675
679
676 a.atom { background: url(../images/feed.png) no-repeat 1px 50%; padding: 2px 0px 3px 16px; }
680 a.atom { background: url(../images/feed.png) no-repeat 1px 50%; padding: 2px 0px 3px 16px; }
677
681
678 em.info {font-style:normal;font-size:90%;color:#888;display:block;}
682 em.info {font-style:normal;font-size:90%;color:#888;display:block;}
679 em.info.error {padding-left:20px; background:url(../images/exclamation.png) no-repeat 0 50%;}
683 em.info.error {padding-left:20px; background:url(../images/exclamation.png) no-repeat 0 50%;}
680
684
681 textarea.text_cf {width:95%; resize:vertical;}
685 textarea.text_cf {width:95%; resize:vertical;}
682 input.string_cf, input.link_cf {width:95%;}
686 input.string_cf, input.link_cf {width:95%;}
683 select.bool_cf {width:auto !important;}
687 select.bool_cf {width:auto !important;}
684
688
685 #tab-content-modules fieldset p {margin:3px 0 4px 0;}
689 #tab-content-modules fieldset p {margin:3px 0 4px 0;}
686
690
687 #tab-content-users .splitcontentleft {width: 64%;}
691 #tab-content-users .splitcontentleft {width: 64%;}
688 #tab-content-users .splitcontentright {width: 34%;}
692 #tab-content-users .splitcontentright {width: 34%;}
689 #tab-content-users fieldset {padding:1em; margin-bottom: 1em;}
693 #tab-content-users fieldset {padding:1em; margin-bottom: 1em;}
690 #tab-content-users fieldset legend {font-weight: bold;}
694 #tab-content-users fieldset legend {font-weight: bold;}
691 #tab-content-users fieldset label {display: block;}
695 #tab-content-users fieldset label {display: block;}
692 #tab-content-users #principals {max-height: 400px; overflow: auto;}
696 #tab-content-users #principals {max-height: 400px; overflow: auto;}
693
697
694 #users_for_watcher {height: 200px; overflow:auto;}
698 #users_for_watcher {height: 200px; overflow:auto;}
695 #users_for_watcher label {display: block;}
699 #users_for_watcher label {display: block;}
696
700
697 table.members td.name {padding-left: 20px;}
701 table.members td.name {padding-left: 20px;}
698 table.members td.group, table.members td.groupnonmember, table.members td.groupanonymous {background: url(../images/group.png) no-repeat 0% 1px;}
702 table.members td.group, table.members td.groupnonmember, table.members td.groupanonymous {background: url(../images/group.png) no-repeat 0% 1px;}
699
703
700 input#principal_search, input#user_search {width:90%}
704 input#principal_search, input#user_search {width:90%}
701 .roles-selection label {display:inline-block; width:210px;}
705 .roles-selection label {display:inline-block; width:210px;}
702
706
703 input.autocomplete {
707 input.autocomplete {
704 background: #fff url(../images/magnifier.png) no-repeat 2px 50%; padding-left:20px !important;
708 background: #fff url(../images/magnifier.png) no-repeat 2px 50%; padding-left:20px !important;
705 border:1px solid #9EB1C2; border-radius:2px; height:1.5em;
709 border:1px solid #9EB1C2; border-radius:2px; height:1.5em;
706 }
710 }
707 input.autocomplete.ajax-loading {
711 input.autocomplete.ajax-loading {
708 background-image: url(../images/loading.gif);
712 background-image: url(../images/loading.gif);
709 }
713 }
710
714
711 .role-visibility {padding-left:2em;}
715 .role-visibility {padding-left:2em;}
712
716
713 .objects-selection {
717 .objects-selection {
714 height: 300px;
718 height: 300px;
715 overflow: auto;
719 overflow: auto;
716 margin-bottom: 1em;
720 margin-bottom: 1em;
717 }
721 }
718
722
719 .objects-selection label {
723 .objects-selection label {
720 display: block;
724 display: block;
721 }
725 }
722
726
723 .objects-selection>div {
727 .objects-selection>div {
724 column-count: auto;
728 column-count: auto;
725 column-width: 200px;
729 column-width: 200px;
726 -webkit-column-count: auto;
730 -webkit-column-count: auto;
727 -webkit-column-width: 200px;
731 -webkit-column-width: 200px;
728 -webkit-column-gap : 0.5rem;
732 -webkit-column-gap : 0.5rem;
729 -webkit-column-rule: 1px solid #ccc;
733 -webkit-column-rule: 1px solid #ccc;
730 -moz-column-count: auto;
734 -moz-column-count: auto;
731 -moz-column-width: 200px;
735 -moz-column-width: 200px;
732 -moz-column-gap : 0.5rem;
736 -moz-column-gap : 0.5rem;
733 -moz-column-rule: 1px solid #ccc;
737 -moz-column-rule: 1px solid #ccc;
734 }
738 }
735
739
736 /***** Flash & error messages ****/
740 /***** Flash & error messages ****/
737 #errorExplanation, div.flash, .nodata, .warning, .conflict {
741 #errorExplanation, div.flash, .nodata, .warning, .conflict {
738 padding: 4px 4px 4px 30px;
742 padding: 4px 4px 4px 30px;
739 margin-bottom: 12px;
743 margin-bottom: 12px;
740 font-size: 1.1em;
744 font-size: 1.1em;
741 border: 2px solid;
745 border: 2px solid;
742 border-radius: 3px;
746 border-radius: 3px;
743 }
747 }
744
748
745 div.flash {margin-top: 8px;}
749 div.flash {margin-top: 8px;}
746
750
747 div.flash.error, #errorExplanation {
751 div.flash.error, #errorExplanation {
748 background: url(../images/exclamation.png) 8px 50% no-repeat;
752 background: url(../images/exclamation.png) 8px 50% no-repeat;
749 background-color: #ffe3e3;
753 background-color: #ffe3e3;
750 border-color: #dd0000;
754 border-color: #dd0000;
751 color: #880000;
755 color: #880000;
752 }
756 }
753
757
754 div.flash.notice {
758 div.flash.notice {
755 background: url(../images/true.png) 8px 5px no-repeat;
759 background: url(../images/true.png) 8px 5px no-repeat;
756 background-color: #dfffdf;
760 background-color: #dfffdf;
757 border-color: #9fcf9f;
761 border-color: #9fcf9f;
758 color: #005f00;
762 color: #005f00;
759 }
763 }
760
764
761 div.flash.warning, .conflict {
765 div.flash.warning, .conflict {
762 background: url(../images/warning.png) 8px 5px no-repeat;
766 background: url(../images/warning.png) 8px 5px no-repeat;
763 background-color: #FFEBC1;
767 background-color: #FFEBC1;
764 border-color: #FDBF3B;
768 border-color: #FDBF3B;
765 color: #A6750C;
769 color: #A6750C;
766 text-align: left;
770 text-align: left;
767 }
771 }
768
772
769 .nodata, .warning {
773 .nodata, .warning {
770 text-align: center;
774 text-align: center;
771 background-color: #FFEBC1;
775 background-color: #FFEBC1;
772 border-color: #FDBF3B;
776 border-color: #FDBF3B;
773 color: #A6750C;
777 color: #A6750C;
774 }
778 }
775
779
776 #errorExplanation ul { font-size: 0.9em;}
780 #errorExplanation ul { font-size: 0.9em;}
777 #errorExplanation h2, #errorExplanation p { display: none; }
781 #errorExplanation h2, #errorExplanation p { display: none; }
778
782
779 .conflict-details {font-size:80%;}
783 .conflict-details {font-size:80%;}
780
784
781 /***** Ajax indicator ******/
785 /***** Ajax indicator ******/
782 #ajax-indicator {
786 #ajax-indicator {
783 position: absolute; /* fixed not supported by IE */
787 position: absolute; /* fixed not supported by IE */
784 background-color:#eee;
788 background-color:#eee;
785 border: 1px solid #bbb;
789 border: 1px solid #bbb;
786 top:35%;
790 top:35%;
787 left:40%;
791 left:40%;
788 width:20%;
792 width:20%;
789 font-weight:bold;
793 font-weight:bold;
790 text-align:center;
794 text-align:center;
791 padding:0.6em;
795 padding:0.6em;
792 z-index:100;
796 z-index:100;
793 opacity: 0.5;
797 opacity: 0.5;
794 }
798 }
795
799
796 html>body #ajax-indicator { position: fixed; }
800 html>body #ajax-indicator { position: fixed; }
797
801
798 #ajax-indicator span {
802 #ajax-indicator span {
799 background-position: 0% 40%;
803 background-position: 0% 40%;
800 background-repeat: no-repeat;
804 background-repeat: no-repeat;
801 background-image: url(../images/loading.gif);
805 background-image: url(../images/loading.gif);
802 padding-left: 26px;
806 padding-left: 26px;
803 vertical-align: bottom;
807 vertical-align: bottom;
804 }
808 }
805
809
806 /***** Calendar *****/
810 /***** Calendar *****/
807 table.cal {border-collapse: collapse; width: 100%; margin: 0px 0 6px 0;border: 1px solid #d7d7d7;}
811 table.cal {border-collapse: collapse; width: 100%; margin: 0px 0 6px 0;border: 1px solid #d7d7d7;}
808 table.cal thead th {width: 14%; background-color:#EEEEEE; padding: 4px; }
812 table.cal thead th {width: 14%; background-color:#EEEEEE; padding: 4px; }
809 table.cal thead th.week-number {width: auto;}
813 table.cal thead th.week-number {width: auto;}
810 table.cal tbody tr {height: 100px;}
814 table.cal tbody tr {height: 100px;}
811 table.cal td {border: 1px solid #d7d7d7; vertical-align: top; font-size: 0.9em;}
815 table.cal td {border: 1px solid #d7d7d7; vertical-align: top; font-size: 0.9em;}
812 table.cal td.week-number { background-color:#EEEEEE; padding: 4px; border:none; font-size: 1em;}
816 table.cal td.week-number { background-color:#EEEEEE; padding: 4px; border:none; font-size: 1em;}
813 table.cal td p.day-num {font-size: 1.1em; text-align:right;}
817 table.cal td p.day-num {font-size: 1.1em; text-align:right;}
814 table.cal td.odd p.day-num {color: #bbb;}
818 table.cal td.odd p.day-num {color: #bbb;}
815 table.cal td.today {background:#ffffdd;}
819 table.cal td.today {background:#ffffdd;}
816 table.cal td.today p.day-num {font-weight: bold;}
820 table.cal td.today p.day-num {font-weight: bold;}
817 table.cal .starting a, p.cal.legend .starting {background: url(../images/bullet_go.png) no-repeat -1px -2px; padding-left:16px;}
821 table.cal .starting a, p.cal.legend .starting {background: url(../images/bullet_go.png) no-repeat -1px -2px; padding-left:16px;}
818 table.cal .ending a, p.cal.legend .ending {background: url(../images/bullet_end.png) no-repeat -1px -2px; padding-left:16px;}
822 table.cal .ending a, p.cal.legend .ending {background: url(../images/bullet_end.png) no-repeat -1px -2px; padding-left:16px;}
819 table.cal .starting.ending a, p.cal.legend .starting.ending {background: url(../images/bullet_diamond.png) no-repeat -1px -2px; padding-left:16px;}
823 table.cal .starting.ending a, p.cal.legend .starting.ending {background: url(../images/bullet_diamond.png) no-repeat -1px -2px; padding-left:16px;}
820 p.cal.legend span {display:block;}
824 p.cal.legend span {display:block;}
821
825
822 /***** Tooltips ******/
826 /***** Tooltips ******/
823 .tooltip{position:relative;z-index:24;}
827 .tooltip{position:relative;z-index:24;}
824 .tooltip:hover{z-index:25;color:#000;}
828 .tooltip:hover{z-index:25;color:#000;}
825 .tooltip span.tip{display: none; text-align:left;}
829 .tooltip span.tip{display: none; text-align:left;}
826
830
827 div.tooltip:hover span.tip{
831 div.tooltip:hover span.tip{
828 display:block;
832 display:block;
829 position:absolute;
833 position:absolute;
830 top:12px; width:270px;
834 top:12px; width:270px;
831 border:1px solid #555;
835 border:1px solid #555;
832 background-color:#fff;
836 background-color:#fff;
833 padding: 4px;
837 padding: 4px;
834 font-size: 0.8em;
838 font-size: 0.8em;
835 color:#505050;
839 color:#505050;
836 }
840 }
837
841
838 img.ui-datepicker-trigger {
842 img.ui-datepicker-trigger {
839 cursor: pointer;
843 cursor: pointer;
840 vertical-align: middle;
844 vertical-align: middle;
841 margin-left: 4px;
845 margin-left: 4px;
842 }
846 }
843
847
844 /***** Progress bar *****/
848 /***** Progress bar *****/
845 table.progress {
849 table.progress {
846 border-collapse: collapse;
850 border-collapse: collapse;
847 border-spacing: 0pt;
851 border-spacing: 0pt;
848 empty-cells: show;
852 empty-cells: show;
849 text-align: center;
853 text-align: center;
850 float:left;
854 float:left;
851 margin: 1px 6px 1px 0px;
855 margin: 1px 6px 1px 0px;
852 }
856 }
853
857
854 table.progress {width:80px;}
858 table.progress {width:80px;}
855 table.progress td { height: 1em; }
859 table.progress td { height: 1em; }
856 table.progress td.closed { background: #BAE0BA none repeat scroll 0%; }
860 table.progress td.closed { background: #BAE0BA none repeat scroll 0%; }
857 table.progress td.done { background: #D3EDD3 none repeat scroll 0%; }
861 table.progress td.done { background: #D3EDD3 none repeat scroll 0%; }
858 table.progress td.todo { background: #eee none repeat scroll 0%; }
862 table.progress td.todo { background: #eee none repeat scroll 0%; }
859 p.percent {font-size: 80%; margin:0;}
863 p.percent {font-size: 80%; margin:0;}
860 p.progress-info {clear: left; font-size: 80%; margin-top:-4px; color:#777;}
864 p.progress-info {clear: left; font-size: 80%; margin-top:-4px; color:#777;}
861
865
862 .version-overview table.progress {width:40em;}
866 .version-overview table.progress {width:40em;}
863 .version-overview table.progress td { height: 1.2em; }
867 .version-overview table.progress td { height: 1.2em; }
864
868
865 /***** Tabs *****/
869 /***** Tabs *****/
866 #content .tabs {height: 2.6em; margin-bottom:1.2em; position:relative; overflow:hidden;}
870 #content .tabs {height: 2.6em; margin-bottom:1.2em; position:relative; overflow:hidden;}
867 #content .tabs ul {margin:0; position:absolute; bottom:0; padding-left:0.5em; width: 2000px; border-bottom: 1px solid #bbbbbb;}
871 #content .tabs ul {margin:0; position:absolute; bottom:0; padding-left:0.5em; width: 2000px; border-bottom: 1px solid #bbbbbb;}
868 #content .tabs ul li {
872 #content .tabs ul li {
869 float:left;
873 float:left;
870 list-style-type:none;
874 list-style-type:none;
871 white-space:nowrap;
875 white-space:nowrap;
872 margin-right:4px;
876 margin-right:4px;
873 background:#fff;
877 background:#fff;
874 position:relative;
878 position:relative;
875 margin-bottom:-1px;
879 margin-bottom:-1px;
876 }
880 }
877 #content .tabs ul li a{
881 #content .tabs ul li a{
878 display:block;
882 display:block;
879 font-size: 0.9em;
883 font-size: 0.9em;
880 text-decoration:none;
884 text-decoration:none;
881 line-height:1.3em;
885 line-height:1.3em;
882 padding:4px 6px 4px 6px;
886 padding:4px 6px 4px 6px;
883 border: 1px solid #ccc;
887 border: 1px solid #ccc;
884 border-bottom: 1px solid #bbbbbb;
888 border-bottom: 1px solid #bbbbbb;
885 background-color: #f6f6f6;
889 background-color: #f6f6f6;
886 color:#999;
890 color:#999;
887 font-weight:bold;
891 font-weight:bold;
888 border-top-left-radius:3px;
892 border-top-left-radius:3px;
889 border-top-right-radius:3px;
893 border-top-right-radius:3px;
890 }
894 }
891
895
892 #content .tabs ul li a:hover {
896 #content .tabs ul li a:hover {
893 background-color: #ffffdd;
897 background-color: #ffffdd;
894 text-decoration:none;
898 text-decoration:none;
895 }
899 }
896
900
897 #content .tabs ul li a.selected {
901 #content .tabs ul li a.selected {
898 background-color: #fff;
902 background-color: #fff;
899 border: 1px solid #bbbbbb;
903 border: 1px solid #bbbbbb;
900 border-bottom: 1px solid #fff;
904 border-bottom: 1px solid #fff;
901 color:#444;
905 color:#444;
902 }
906 }
903
907
904 #content .tabs ul li a.selected:hover {background-color: #fff;}
908 #content .tabs ul li a.selected:hover {background-color: #fff;}
905
909
906 div.tabs-buttons { position:absolute; right: 0; width: 54px; height: 24px; background: white; bottom: 0; border-bottom: 1px solid #bbbbbb; }
910 div.tabs-buttons { position:absolute; right: 0; width: 54px; height: 24px; background: white; bottom: 0; border-bottom: 1px solid #bbbbbb; }
907
911
908 button.tab-left, button.tab-right {
912 button.tab-left, button.tab-right {
909 font-size: 0.9em;
913 font-size: 0.9em;
910 cursor: pointer;
914 cursor: pointer;
911 height:24px;
915 height:24px;
912 border: 1px solid #ccc;
916 border: 1px solid #ccc;
913 border-bottom: 1px solid #bbbbbb;
917 border-bottom: 1px solid #bbbbbb;
914 position:absolute;
918 position:absolute;
915 padding:4px;
919 padding:4px;
916 width: 20px;
920 width: 20px;
917 bottom: -1px;
921 bottom: -1px;
918 }
922 }
919 button.tab-left:hover, button.tab-right:hover {
923 button.tab-left:hover, button.tab-right:hover {
920 background-color: #f5f5f5;
924 background-color: #f5f5f5;
921 }
925 }
922 button.tab-left:focus, button.tab-right:focus {
926 button.tab-left:focus, button.tab-right:focus {
923 outline: 0;
927 outline: 0;
924 }
928 }
925
929
926 button.tab-left {
930 button.tab-left {
927 right: 20px;
931 right: 20px;
928 background: #eeeeee url(../images/bullet_arrow_left.png) no-repeat 50% 50%;
932 background: #eeeeee url(../images/bullet_arrow_left.png) no-repeat 50% 50%;
929 border-top-left-radius:3px;
933 border-top-left-radius:3px;
930 }
934 }
931
935
932 button.tab-right {
936 button.tab-right {
933 right: 0;
937 right: 0;
934 background: #eeeeee url(../images/bullet_arrow_right.png) no-repeat 50% 50%;
938 background: #eeeeee url(../images/bullet_arrow_right.png) no-repeat 50% 50%;
935 border-top-right-radius:3px;
939 border-top-right-radius:3px;
936 }
940 }
937
941
938 button.tab-left.disabled, button.tab-right.disabled {
942 button.tab-left.disabled, button.tab-right.disabled {
939 background-color: #ccc;
943 background-color: #ccc;
940 cursor: unset;
944 cursor: unset;
941 }
945 }
942
946
943 /***** Diff *****/
947 /***** Diff *****/
944 .diff_out { background: #fcc; }
948 .diff_out { background: #fcc; }
945 .diff_out span { background: #faa; }
949 .diff_out span { background: #faa; }
946 .diff_in { background: #cfc; }
950 .diff_in { background: #cfc; }
947 .diff_in span { background: #afa; }
951 .diff_in span { background: #afa; }
948
952
949 .text-diff {
953 .text-diff {
950 padding: 1em;
954 padding: 1em;
951 background-color:#f6f6f6;
955 background-color:#f6f6f6;
952 color:#505050;
956 color:#505050;
953 border: 1px solid #e4e4e4;
957 border: 1px solid #e4e4e4;
954 }
958 }
955
959
956 /***** Wiki *****/
960 /***** Wiki *****/
957 div.wiki table {
961 div.wiki table {
958 border-collapse: collapse;
962 border-collapse: collapse;
959 margin-bottom: 1em;
963 margin-bottom: 1em;
960 }
964 }
961
965
962 div.wiki table, div.wiki td, div.wiki th {
966 div.wiki table, div.wiki td, div.wiki th {
963 border: 1px solid #bbb;
967 border: 1px solid #bbb;
964 padding: 4px;
968 padding: 4px;
965 }
969 }
966
970
967 div.wiki .noborder, div.wiki .noborder td, div.wiki .noborder th {border:0;}
971 div.wiki .noborder, div.wiki .noborder td, div.wiki .noborder th {border:0;}
968
972
969 div.wiki .external {
973 div.wiki .external {
970 background-position: 0% 60%;
974 background-position: 0% 60%;
971 background-repeat: no-repeat;
975 background-repeat: no-repeat;
972 padding-left: 12px;
976 padding-left: 12px;
973 background-image: url(../images/external.png);
977 background-image: url(../images/external.png);
974 }
978 }
975
979
976 div.wiki a {word-wrap: break-word;}
980 div.wiki a {word-wrap: break-word;}
977 div.wiki a.new {color: #b73535;}
981 div.wiki a.new {color: #b73535;}
978
982
979 div.wiki ul, div.wiki ol {margin-bottom:1em;}
983 div.wiki ul, div.wiki ol {margin-bottom:1em;}
980 div.wiki li>ul, div.wiki li>ol {margin-bottom: 0;}
984 div.wiki li>ul, div.wiki li>ol {margin-bottom: 0;}
981
985
982 div.wiki pre {
986 div.wiki pre {
983 margin: 1em 1em 1em 1.6em;
987 margin: 1em 1em 1em 1.6em;
984 padding: 8px;
988 padding: 8px;
985 background-color: #fafafa;
989 background-color: #fafafa;
986 border: 1px solid #e2e2e2;
990 border: 1px solid #e2e2e2;
987 border-radius: 3px;
991 border-radius: 3px;
988 width:auto;
992 width:auto;
989 overflow-x: auto;
993 overflow-x: auto;
990 overflow-y: hidden;
994 overflow-y: hidden;
991 }
995 }
992
996
993 div.wiki ul.toc {
997 div.wiki ul.toc {
994 background-color: #ffffdd;
998 background-color: #ffffdd;
995 border: 1px solid #e4e4e4;
999 border: 1px solid #e4e4e4;
996 padding: 4px;
1000 padding: 4px;
997 line-height: 1.2em;
1001 line-height: 1.2em;
998 margin-bottom: 12px;
1002 margin-bottom: 12px;
999 margin-right: 12px;
1003 margin-right: 12px;
1000 margin-left: 0;
1004 margin-left: 0;
1001 display: table
1005 display: table
1002 }
1006 }
1003 * html div.wiki ul.toc { width: 50%; } /* IE6 doesn't autosize div */
1007 * html div.wiki ul.toc { width: 50%; } /* IE6 doesn't autosize div */
1004
1008
1005 div.wiki ul.toc.right { float: right; margin-left: 12px; margin-right: 0; width: auto; }
1009 div.wiki ul.toc.right { float: right; margin-left: 12px; margin-right: 0; width: auto; }
1006 div.wiki ul.toc.left { float: left; margin-right: 12px; margin-left: 0; width: auto; }
1010 div.wiki ul.toc.left { float: left; margin-right: 12px; margin-left: 0; width: auto; }
1007 div.wiki ul.toc ul { margin: 0; padding: 0; }
1011 div.wiki ul.toc ul { margin: 0; padding: 0; }
1008 div.wiki ul.toc li {list-style-type:none; margin: 0; font-size:12px;}
1012 div.wiki ul.toc li {list-style-type:none; margin: 0; font-size:12px;}
1009 div.wiki ul.toc li li {margin-left: 1.5em; font-size:10px;}
1013 div.wiki ul.toc li li {margin-left: 1.5em; font-size:10px;}
1010 div.wiki ul.toc a {
1014 div.wiki ul.toc a {
1011 font-size: 0.9em;
1015 font-size: 0.9em;
1012 font-weight: normal;
1016 font-weight: normal;
1013 text-decoration: none;
1017 text-decoration: none;
1014 color: #606060;
1018 color: #606060;
1015 }
1019 }
1016 div.wiki ul.toc a:hover { color: #c61a1a; text-decoration: underline;}
1020 div.wiki ul.toc a:hover { color: #c61a1a; text-decoration: underline;}
1017
1021
1018 a.wiki-anchor { display: none; margin-left: 6px; text-decoration: none; }
1022 a.wiki-anchor { display: none; margin-left: 6px; text-decoration: none; }
1019 a.wiki-anchor:hover { color: #aaa !important; text-decoration: none; }
1023 a.wiki-anchor:hover { color: #aaa !important; text-decoration: none; }
1020 h1:hover a.wiki-anchor, h2:hover a.wiki-anchor, h3:hover a.wiki-anchor { display: inline; color: #ddd; }
1024 h1:hover a.wiki-anchor, h2:hover a.wiki-anchor, h3:hover a.wiki-anchor { display: inline; color: #ddd; }
1021
1025
1022 div.wiki img {vertical-align:middle; max-width:100%;}
1026 div.wiki img {vertical-align:middle; max-width:100%;}
1023
1027
1024 /***** My page layout *****/
1028 /***** My page layout *****/
1025 .block-receiver {
1029 .block-receiver {
1026 border:1px dashed #c0c0c0;
1030 border:1px dashed #c0c0c0;
1027 margin-bottom: 20px;
1031 margin-bottom: 20px;
1028 padding: 15px 0 15px 0;
1032 padding: 15px 0 15px 0;
1029 }
1033 }
1030
1034
1031 .mypage-box {
1035 .mypage-box {
1032 margin:0 0 20px 0;
1036 margin:0 0 20px 0;
1033 color:#505050;
1037 color:#505050;
1034 line-height:1.5em;
1038 line-height:1.5em;
1035 }
1039 }
1036
1040
1037 .handle {cursor: move;}
1041 .handle {cursor: move;}
1038
1042
1039 a.close-icon {
1043 a.close-icon {
1040 display:block;
1044 display:block;
1041 margin-top:3px;
1045 margin-top:3px;
1042 overflow:hidden;
1046 overflow:hidden;
1043 width:12px;
1047 width:12px;
1044 height:12px;
1048 height:12px;
1045 background-repeat: no-repeat;
1049 background-repeat: no-repeat;
1046 cursor:pointer;
1050 cursor:pointer;
1047 background-image:url('../images/close.png');
1051 background-image:url('../images/close.png');
1048 }
1052 }
1049 a.close-icon:hover {background-image:url('../images/close_hl.png');}
1053 a.close-icon:hover {background-image:url('../images/close_hl.png');}
1050
1054
1051 /***** Gantt chart *****/
1055 /***** Gantt chart *****/
1052 .gantt_hdr {
1056 .gantt_hdr {
1053 position:absolute;
1057 position:absolute;
1054 top:0;
1058 top:0;
1055 height:16px;
1059 height:16px;
1056 border-top: 1px solid #c0c0c0;
1060 border-top: 1px solid #c0c0c0;
1057 border-bottom: 1px solid #c0c0c0;
1061 border-bottom: 1px solid #c0c0c0;
1058 border-right: 1px solid #c0c0c0;
1062 border-right: 1px solid #c0c0c0;
1059 text-align: center;
1063 text-align: center;
1060 overflow: hidden;
1064 overflow: hidden;
1061 }
1065 }
1062
1066
1063 .gantt_hdr.nwday {background-color:#f1f1f1; color:#999;}
1067 .gantt_hdr.nwday {background-color:#f1f1f1; color:#999;}
1064
1068
1065 .gantt_subjects { font-size: 0.8em; }
1069 .gantt_subjects { font-size: 0.8em; }
1066 .gantt_subjects div { line-height:16px;height:16px;overflow:hidden;white-space:nowrap;text-overflow: ellipsis; }
1070 .gantt_subjects div { line-height:16px;height:16px;overflow:hidden;white-space:nowrap;text-overflow: ellipsis; }
1067
1071
1068 .task {
1072 .task {
1069 position: absolute;
1073 position: absolute;
1070 height:8px;
1074 height:8px;
1071 font-size:0.8em;
1075 font-size:0.8em;
1072 color:#888;
1076 color:#888;
1073 padding:0;
1077 padding:0;
1074 margin:0;
1078 margin:0;
1075 line-height:16px;
1079 line-height:16px;
1076 white-space:nowrap;
1080 white-space:nowrap;
1077 }
1081 }
1078
1082
1079 .task.label {width:100%;}
1083 .task.label {width:100%;}
1080 .task.label.project, .task.label.version { font-weight: bold; }
1084 .task.label.project, .task.label.version { font-weight: bold; }
1081
1085
1082 .task_late { background:#f66 url(../images/task_late.png); border: 1px solid #f66; }
1086 .task_late { background:#f66 url(../images/task_late.png); border: 1px solid #f66; }
1083 .task_done { background:#00c600 url(../images/task_done.png); border: 1px solid #00c600; }
1087 .task_done { background:#00c600 url(../images/task_done.png); border: 1px solid #00c600; }
1084 .task_todo { background:#aaa url(../images/task_todo.png); border: 1px solid #aaa; }
1088 .task_todo { background:#aaa url(../images/task_todo.png); border: 1px solid #aaa; }
1085
1089
1086 .task_todo.parent { background: #888; border: 1px solid #888; height: 3px;}
1090 .task_todo.parent { background: #888; border: 1px solid #888; height: 3px;}
1087 .task_late.parent, .task_done.parent { height: 3px;}
1091 .task_late.parent, .task_done.parent { height: 3px;}
1088 .task.parent.marker.starting { position: absolute; background: url(../images/task_parent_end.png) no-repeat 0 0; width: 8px; height: 16px; margin-left: -4px; left: 0px; top: -1px;}
1092 .task.parent.marker.starting { position: absolute; background: url(../images/task_parent_end.png) no-repeat 0 0; width: 8px; height: 16px; margin-left: -4px; left: 0px; top: -1px;}
1089 .task.parent.marker.ending { position: absolute; background: url(../images/task_parent_end.png) no-repeat 0 0; width: 8px; height: 16px; margin-left: -4px; right: 0px; top: -1px;}
1093 .task.parent.marker.ending { position: absolute; background: url(../images/task_parent_end.png) no-repeat 0 0; width: 8px; height: 16px; margin-left: -4px; right: 0px; top: -1px;}
1090
1094
1091 .version.task_late { background:#f66 url(../images/milestone_late.png); border: 1px solid #f66; height: 2px; margin-top: 3px;}
1095 .version.task_late { background:#f66 url(../images/milestone_late.png); border: 1px solid #f66; height: 2px; margin-top: 3px;}
1092 .version.task_done { background:#00c600 url(../images/milestone_done.png); border: 1px solid #00c600; height: 2px; margin-top: 3px;}
1096 .version.task_done { background:#00c600 url(../images/milestone_done.png); border: 1px solid #00c600; height: 2px; margin-top: 3px;}
1093 .version.task_todo { background:#fff url(../images/milestone_todo.png); border: 1px solid #fff; height: 2px; margin-top: 3px;}
1097 .version.task_todo { background:#fff url(../images/milestone_todo.png); border: 1px solid #fff; height: 2px; margin-top: 3px;}
1094 .version.marker { background-image:url(../images/version_marker.png); background-repeat: no-repeat; border: 0; margin-left: -4px; margin-top: 1px; }
1098 .version.marker { background-image:url(../images/version_marker.png); background-repeat: no-repeat; border: 0; margin-left: -4px; margin-top: 1px; }
1095
1099
1096 .project.task_late { background:#f66 url(../images/milestone_late.png); border: 1px solid #f66; height: 2px; margin-top: 3px;}
1100 .project.task_late { background:#f66 url(../images/milestone_late.png); border: 1px solid #f66; height: 2px; margin-top: 3px;}
1097 .project.task_done { background:#00c600 url(../images/milestone_done.png); border: 1px solid #00c600; height: 2px; margin-top: 3px;}
1101 .project.task_done { background:#00c600 url(../images/milestone_done.png); border: 1px solid #00c600; height: 2px; margin-top: 3px;}
1098 .project.task_todo { background:#fff url(../images/milestone_todo.png); border: 1px solid #fff; height: 2px; margin-top: 3px;}
1102 .project.task_todo { background:#fff url(../images/milestone_todo.png); border: 1px solid #fff; height: 2px; margin-top: 3px;}
1099 .project.marker { background-image:url(../images/project_marker.png); background-repeat: no-repeat; border: 0; margin-left: -4px; margin-top: 1px; }
1103 .project.marker { background-image:url(../images/project_marker.png); background-repeat: no-repeat; border: 0; margin-left: -4px; margin-top: 1px; }
1100
1104
1101 .version-behind-schedule a, .issue-behind-schedule a {color: #f66914;}
1105 .version-behind-schedule a, .issue-behind-schedule a {color: #f66914;}
1102 .version-overdue a, .issue-overdue a, .project-overdue a {color: #f00;}
1106 .version-overdue a, .issue-overdue a, .project-overdue a {color: #f00;}
1103
1107
1104 /***** Icons *****/
1108 /***** Icons *****/
1105 .icon {
1109 .icon {
1106 background-position: 0% 50%;
1110 background-position: 0% 50%;
1107 background-repeat: no-repeat;
1111 background-repeat: no-repeat;
1108 padding-left: 20px;
1112 padding-left: 20px;
1109 padding-top: 2px;
1113 padding-top: 2px;
1110 padding-bottom: 3px;
1114 padding-bottom: 3px;
1111 }
1115 }
1112 .icon-only {
1116 .icon-only {
1113 background-position: 0% 50%;
1117 background-position: 0% 50%;
1114 background-repeat: no-repeat;
1118 background-repeat: no-repeat;
1115 padding-left: 16px;
1119 padding-left: 16px;
1116 }
1120 }
1117 a.icon-only {
1121 a.icon-only {
1118 display: inline-block;
1122 display: inline-block;
1119 width: 0;
1123 width: 0;
1120 height: 16px;
1124 height: 16px;
1121 overflow: hidden;
1125 overflow: hidden;
1122 padding-top: 0;
1126 padding-top: 0;
1123 padding-bottom: 0;
1127 padding-bottom: 0;
1124 font-size: 8px;
1128 font-size: 8px;
1125 vertical-align: text-bottom;
1129 vertical-align: text-bottom;
1126 }
1130 }
1127 a.icon-only::after {
1131 a.icon-only::after {
1128 content: "&nbsp;";
1132 content: "&nbsp;";
1129 }
1133 }
1130
1134
1131 .icon-add { background-image: url(../images/add.png); }
1135 .icon-add { background-image: url(../images/add.png); }
1132 .icon-edit { background-image: url(../images/edit.png); }
1136 .icon-edit { background-image: url(../images/edit.png); }
1133 .icon-copy { background-image: url(../images/copy.png); }
1137 .icon-copy { background-image: url(../images/copy.png); }
1134 .icon-duplicate { background-image: url(../images/duplicate.png); }
1138 .icon-duplicate { background-image: url(../images/duplicate.png); }
1135 .icon-del { background-image: url(../images/delete.png); }
1139 .icon-del { background-image: url(../images/delete.png); }
1136 .icon-move { background-image: url(../images/move.png); }
1140 .icon-move { background-image: url(../images/move.png); }
1137 .icon-save { background-image: url(../images/save.png); }
1141 .icon-save { background-image: url(../images/save.png); }
1138 .icon-cancel { background-image: url(../images/cancel.png); }
1142 .icon-cancel { background-image: url(../images/cancel.png); }
1139 .icon-multiple { background-image: url(../images/table_multiple.png); }
1143 .icon-multiple { background-image: url(../images/table_multiple.png); }
1140 .icon-folder { background-image: url(../images/folder.png); }
1144 .icon-folder { background-image: url(../images/folder.png); }
1141 .open .icon-folder { background-image: url(../images/folder_open.png); }
1145 .open .icon-folder { background-image: url(../images/folder_open.png); }
1142 .icon-package { background-image: url(../images/package.png); }
1146 .icon-package { background-image: url(../images/package.png); }
1143 .icon-user { background-image: url(../images/user.png); }
1147 .icon-user { background-image: url(../images/user.png); }
1144 .icon-projects { background-image: url(../images/projects.png); }
1148 .icon-projects { background-image: url(../images/projects.png); }
1145 .icon-help { background-image: url(../images/help.png); }
1149 .icon-help { background-image: url(../images/help.png); }
1146 .icon-attachment { background-image: url(../images/attachment.png); }
1150 .icon-attachment { background-image: url(../images/attachment.png); }
1147 .icon-history { background-image: url(../images/history.png); }
1151 .icon-history { background-image: url(../images/history.png); }
1148 .icon-time { background-image: url(../images/time.png); }
1152 .icon-time { background-image: url(../images/time.png); }
1149 .icon-time-add { background-image: url(../images/time_add.png); }
1153 .icon-time-add { background-image: url(../images/time_add.png); }
1150 .icon-stats { background-image: url(../images/stats.png); }
1154 .icon-stats { background-image: url(../images/stats.png); }
1151 .icon-warning { background-image: url(../images/warning.png); }
1155 .icon-warning { background-image: url(../images/warning.png); }
1152 .icon-error { background-image: url(../images/exclamation.png); }
1156 .icon-error { background-image: url(../images/exclamation.png); }
1153 .icon-fav { background-image: url(../images/fav.png); }
1157 .icon-fav { background-image: url(../images/fav.png); }
1154 .icon-fav-off { background-image: url(../images/fav_off.png); }
1158 .icon-fav-off { background-image: url(../images/fav_off.png); }
1155 .icon-reload { background-image: url(../images/reload.png); }
1159 .icon-reload { background-image: url(../images/reload.png); }
1156 .icon-lock { background-image: url(../images/locked.png); }
1160 .icon-lock { background-image: url(../images/locked.png); }
1157 .icon-unlock { background-image: url(../images/unlock.png); }
1161 .icon-unlock { background-image: url(../images/unlock.png); }
1158 .icon-checked { background-image: url(../images/toggle_check.png); }
1162 .icon-checked { background-image: url(../images/toggle_check.png); }
1159 .icon-details { background-image: url(../images/zoom_in.png); }
1163 .icon-details { background-image: url(../images/zoom_in.png); }
1160 .icon-report { background-image: url(../images/report.png); }
1164 .icon-report { background-image: url(../images/report.png); }
1161 .icon-comment { background-image: url(../images/comment.png); }
1165 .icon-comment { background-image: url(../images/comment.png); }
1162 .icon-summary { background-image: url(../images/lightning.png); }
1166 .icon-summary { background-image: url(../images/lightning.png); }
1163 .icon-server-authentication { background-image: url(../images/server_key.png); }
1167 .icon-server-authentication { background-image: url(../images/server_key.png); }
1164 .icon-issue { background-image: url(../images/ticket.png); }
1168 .icon-issue { background-image: url(../images/ticket.png); }
1165 .icon-zoom-in { background-image: url(../images/zoom_in.png); }
1169 .icon-zoom-in { background-image: url(../images/zoom_in.png); }
1166 .icon-zoom-out { background-image: url(../images/zoom_out.png); }
1170 .icon-zoom-out { background-image: url(../images/zoom_out.png); }
1167 .icon-magnifier { background-image: url(../images/magnifier.png); }
1171 .icon-magnifier { background-image: url(../images/magnifier.png); }
1168 .icon-passwd { background-image: url(../images/textfield_key.png); }
1172 .icon-passwd { background-image: url(../images/textfield_key.png); }
1169 .icon-test { background-image: url(../images/bullet_go.png); }
1173 .icon-test { background-image: url(../images/bullet_go.png); }
1170 .icon-email { background-image: url(../images/email.png); }
1174 .icon-email { background-image: url(../images/email.png); }
1171 .icon-email-disabled { background-image: url(../images/email_disabled.png); }
1175 .icon-email-disabled { background-image: url(../images/email_disabled.png); }
1172 .icon-email-add { background-image: url(../images/email_add.png); }
1176 .icon-email-add { background-image: url(../images/email_add.png); }
1173 .icon-move-up { background-image: url(../images/1uparrow.png); }
1177 .icon-move-up { background-image: url(../images/1uparrow.png); }
1174 .icon-move-top { background-image: url(../images/2uparrow.png); }
1178 .icon-move-top { background-image: url(../images/2uparrow.png); }
1175 .icon-move-down { background-image: url(../images/1downarrow.png); }
1179 .icon-move-down { background-image: url(../images/1downarrow.png); }
1176 .icon-move-bottom { background-image: url(../images/2downarrow.png); }
1180 .icon-move-bottom { background-image: url(../images/2downarrow.png); }
1177 .icon-ok { background-image: url(../images/true.png); }
1181 .icon-ok { background-image: url(../images/true.png); }
1178 .icon-not-ok { background-image: url(../images/false.png); }
1182 .icon-not-ok { background-image: url(../images/false.png); }
1179 .icon-link-break { background-image: url(../images/link_break.png); }
1183 .icon-link-break { background-image: url(../images/link_break.png); }
1180
1184
1181 .icon-file { background-image: url(../images/files/default.png); }
1185 .icon-file { background-image: url(../images/files/default.png); }
1182 .icon-file.text-plain { background-image: url(../images/files/text.png); }
1186 .icon-file.text-plain { background-image: url(../images/files/text.png); }
1183 .icon-file.text-x-c { background-image: url(../images/files/c.png); }
1187 .icon-file.text-x-c { background-image: url(../images/files/c.png); }
1184 .icon-file.text-x-csharp { background-image: url(../images/files/csharp.png); }
1188 .icon-file.text-x-csharp { background-image: url(../images/files/csharp.png); }
1185 .icon-file.text-x-java { background-image: url(../images/files/java.png); }
1189 .icon-file.text-x-java { background-image: url(../images/files/java.png); }
1186 .icon-file.text-x-javascript { background-image: url(../images/files/js.png); }
1190 .icon-file.text-x-javascript { background-image: url(../images/files/js.png); }
1187 .icon-file.text-x-php { background-image: url(../images/files/php.png); }
1191 .icon-file.text-x-php { background-image: url(../images/files/php.png); }
1188 .icon-file.text-x-ruby { background-image: url(../images/files/ruby.png); }
1192 .icon-file.text-x-ruby { background-image: url(../images/files/ruby.png); }
1189 .icon-file.text-xml { background-image: url(../images/files/xml.png); }
1193 .icon-file.text-xml { background-image: url(../images/files/xml.png); }
1190 .icon-file.text-css { background-image: url(../images/files/css.png); }
1194 .icon-file.text-css { background-image: url(../images/files/css.png); }
1191 .icon-file.text-html { background-image: url(../images/files/html.png); }
1195 .icon-file.text-html { background-image: url(../images/files/html.png); }
1192 .icon-file.image-gif { background-image: url(../images/files/image.png); }
1196 .icon-file.image-gif { background-image: url(../images/files/image.png); }
1193 .icon-file.image-jpeg { background-image: url(../images/files/image.png); }
1197 .icon-file.image-jpeg { background-image: url(../images/files/image.png); }
1194 .icon-file.image-png { background-image: url(../images/files/image.png); }
1198 .icon-file.image-png { background-image: url(../images/files/image.png); }
1195 .icon-file.image-tiff { background-image: url(../images/files/image.png); }
1199 .icon-file.image-tiff { background-image: url(../images/files/image.png); }
1196 .icon-file.application-pdf { background-image: url(../images/files/pdf.png); }
1200 .icon-file.application-pdf { background-image: url(../images/files/pdf.png); }
1197 .icon-file.application-zip { background-image: url(../images/files/zip.png); }
1201 .icon-file.application-zip { background-image: url(../images/files/zip.png); }
1198 .icon-file.application-x-gzip { background-image: url(../images/files/zip.png); }
1202 .icon-file.application-x-gzip { background-image: url(../images/files/zip.png); }
1199
1203
1200 .contextual>.icon:not(:first-child), .buttons>.icon:not(:first-child) { margin-left: 5px; }
1204 .contextual>.icon:not(:first-child), .buttons>.icon:not(:first-child) { margin-left: 5px; }
1201
1205
1202 img.gravatar {
1206 img.gravatar {
1203 padding: 2px;
1207 padding: 2px;
1204 border: solid 1px #d5d5d5;
1208 border: solid 1px #d5d5d5;
1205 background: #fff;
1209 background: #fff;
1206 vertical-align: middle;
1210 vertical-align: middle;
1207 }
1211 }
1208
1212
1209 div.issue img.gravatar {
1213 div.issue img.gravatar {
1210 float: left;
1214 float: left;
1211 margin: 0 6px 0 0;
1215 margin: 0 6px 0 0;
1212 padding: 5px;
1216 padding: 5px;
1213 }
1217 }
1214
1218
1215 div.issue .attributes img.gravatar {
1219 div.issue .attributes img.gravatar {
1216 height: 14px;
1220 height: 14px;
1217 width: 14px;
1221 width: 14px;
1218 padding: 2px;
1222 padding: 2px;
1219 float: left;
1223 float: left;
1220 margin: 0 0.5em 0 0;
1224 margin: 0 0.5em 0 0;
1221 }
1225 }
1222
1226
1223 h2 img.gravatar {margin: -2px 4px -4px 0;}
1227 h2 img.gravatar {margin: -2px 4px -4px 0;}
1224 h3 img.gravatar {margin: -4px 4px -4px 0;}
1228 h3 img.gravatar {margin: -4px 4px -4px 0;}
1225 h4 img.gravatar {margin: -6px 4px -4px 0;}
1229 h4 img.gravatar {margin: -6px 4px -4px 0;}
1226 td.username img.gravatar {margin: 0 0.5em 0 0; vertical-align: top;}
1230 td.username img.gravatar {margin: 0 0.5em 0 0; vertical-align: top;}
1227 #activity dt img.gravatar {float: left; margin: 0 1em 1em 0;}
1231 #activity dt img.gravatar {float: left; margin: 0 1em 1em 0;}
1228 /* Used on 12px Gravatar img tags without the icon background */
1232 /* Used on 12px Gravatar img tags without the icon background */
1229 .icon-gravatar {float: left; margin-right: 4px;}
1233 .icon-gravatar {float: left; margin-right: 4px;}
1230
1234
1231 #activity dt, .journal {clear: left;}
1235 #activity dt, .journal {clear: left;}
1232
1236
1233 .journal-link {float: right;}
1237 .journal-link {float: right;}
1234
1238
1235 h2 img { vertical-align:middle; }
1239 h2 img { vertical-align:middle; }
1236
1240
1237 .hascontextmenu { cursor: context-menu; }
1241 .hascontextmenu { cursor: context-menu; }
1238
1242
1239 .sample-data {border:1px solid #ccc; border-collapse:collapse; background-color:#fff; margin:0.5em;}
1243 .sample-data {border:1px solid #ccc; border-collapse:collapse; background-color:#fff; margin:0.5em;}
1240 .sample-data td {border:1px solid #ccc; padding: 2px 4px; font-family: Consolas, Menlo, "Liberation Mono", Courier, monospace;}
1244 .sample-data td {border:1px solid #ccc; padding: 2px 4px; font-family: Consolas, Menlo, "Liberation Mono", Courier, monospace;}
1241 .sample-data tr:first-child td {font-weight:bold; text-align:center;}
1245 .sample-data tr:first-child td {font-weight:bold; text-align:center;}
1242
1246
1243 .ui-progressbar {position: relative;}
1247 .ui-progressbar {position: relative;}
1244 #progress-label {
1248 #progress-label {
1245 position: absolute; left: 50%; top: 4px;
1249 position: absolute; left: 50%; top: 4px;
1246 font-weight: bold;
1250 font-weight: bold;
1247 color: #555; text-shadow: 1px 1px 0 #fff;
1251 color: #555; text-shadow: 1px 1px 0 #fff;
1248 }
1252 }
1249
1253
1250 /* Custom JQuery styles */
1254 /* Custom JQuery styles */
1251 .ui-datepicker-title select {width:70px !important; margin-top:-2px !important; margin-right:4px !important;}
1255 .ui-datepicker-title select {width:70px !important; margin-top:-2px !important; margin-right:4px !important;}
1252
1256
1253
1257
1254 /************* CodeRay styles *************/
1258 /************* CodeRay styles *************/
1255 .syntaxhl div {display: inline;}
1259 .syntaxhl div {display: inline;}
1256 .syntaxhl .code pre { overflow: auto }
1260 .syntaxhl .code pre { overflow: auto }
1257
1261
1258 .syntaxhl .annotation { color:#007 }
1262 .syntaxhl .annotation { color:#007 }
1259 .syntaxhl .attribute-name { color:#b48 }
1263 .syntaxhl .attribute-name { color:#b48 }
1260 .syntaxhl .attribute-value { color:#700 }
1264 .syntaxhl .attribute-value { color:#700 }
1261 .syntaxhl .binary { color:#549 }
1265 .syntaxhl .binary { color:#549 }
1262 .syntaxhl .binary .char { color:#325 }
1266 .syntaxhl .binary .char { color:#325 }
1263 .syntaxhl .binary .delimiter { color:#325 }
1267 .syntaxhl .binary .delimiter { color:#325 }
1264 .syntaxhl .char { color:#D20 }
1268 .syntaxhl .char { color:#D20 }
1265 .syntaxhl .char .content { color:#D20 }
1269 .syntaxhl .char .content { color:#D20 }
1266 .syntaxhl .char .delimiter { color:#710 }
1270 .syntaxhl .char .delimiter { color:#710 }
1267 .syntaxhl .class { color:#258; font-weight:bold }
1271 .syntaxhl .class { color:#258; font-weight:bold }
1268 .syntaxhl .class-variable { color:#369 }
1272 .syntaxhl .class-variable { color:#369 }
1269 .syntaxhl .color { color:#0A0 }
1273 .syntaxhl .color { color:#0A0 }
1270 .syntaxhl .comment { color:#385 }
1274 .syntaxhl .comment { color:#385 }
1271 .syntaxhl .comment .char { color:#385 }
1275 .syntaxhl .comment .char { color:#385 }
1272 .syntaxhl .comment .delimiter { color:#385 }
1276 .syntaxhl .comment .delimiter { color:#385 }
1273 .syntaxhl .constant { color:#258; font-weight:bold }
1277 .syntaxhl .constant { color:#258; font-weight:bold }
1274 .syntaxhl .decorator { color:#B0B }
1278 .syntaxhl .decorator { color:#B0B }
1275 .syntaxhl .definition { color:#099; font-weight:bold }
1279 .syntaxhl .definition { color:#099; font-weight:bold }
1276 .syntaxhl .delimiter { color:black }
1280 .syntaxhl .delimiter { color:black }
1277 .syntaxhl .directive { color:#088; font-weight:bold }
1281 .syntaxhl .directive { color:#088; font-weight:bold }
1278 .syntaxhl .docstring { color:#D42; }
1282 .syntaxhl .docstring { color:#D42; }
1279 .syntaxhl .doctype { color:#34b }
1283 .syntaxhl .doctype { color:#34b }
1280 .syntaxhl .done { text-decoration: line-through; color: gray }
1284 .syntaxhl .done { text-decoration: line-through; color: gray }
1281 .syntaxhl .entity { color:#800; font-weight:bold }
1285 .syntaxhl .entity { color:#800; font-weight:bold }
1282 .syntaxhl .error { color:#F00; background-color:#FAA }
1286 .syntaxhl .error { color:#F00; background-color:#FAA }
1283 .syntaxhl .escape { color:#666 }
1287 .syntaxhl .escape { color:#666 }
1284 .syntaxhl .exception { color:#C00; font-weight:bold }
1288 .syntaxhl .exception { color:#C00; font-weight:bold }
1285 .syntaxhl .float { color:#06D }
1289 .syntaxhl .float { color:#06D }
1286 .syntaxhl .function { color:#06B; font-weight:bold }
1290 .syntaxhl .function { color:#06B; font-weight:bold }
1287 .syntaxhl .function .delimiter { color:#024; font-weight:bold }
1291 .syntaxhl .function .delimiter { color:#024; font-weight:bold }
1288 .syntaxhl .global-variable { color:#d70 }
1292 .syntaxhl .global-variable { color:#d70 }
1289 .syntaxhl .hex { color:#02b }
1293 .syntaxhl .hex { color:#02b }
1290 .syntaxhl .id { color:#33D; font-weight:bold }
1294 .syntaxhl .id { color:#33D; font-weight:bold }
1291 .syntaxhl .include { color:#B44; font-weight:bold }
1295 .syntaxhl .include { color:#B44; font-weight:bold }
1292 .syntaxhl .inline { background-color: hsla(0,0%,0%,0.07); color: black }
1296 .syntaxhl .inline { background-color: hsla(0,0%,0%,0.07); color: black }
1293 .syntaxhl .inline-delimiter { font-weight: bold; color: #666 }
1297 .syntaxhl .inline-delimiter { font-weight: bold; color: #666 }
1294 .syntaxhl .instance-variable { color:#33B }
1298 .syntaxhl .instance-variable { color:#33B }
1295 .syntaxhl .integer { color:#06D }
1299 .syntaxhl .integer { color:#06D }
1296 .syntaxhl .imaginary { color:#f00 }
1300 .syntaxhl .imaginary { color:#f00 }
1297 .syntaxhl .important { color:#D00 }
1301 .syntaxhl .important { color:#D00 }
1298 .syntaxhl .key { color: #606 }
1302 .syntaxhl .key { color: #606 }
1299 .syntaxhl .key .char { color: #60f }
1303 .syntaxhl .key .char { color: #60f }
1300 .syntaxhl .key .delimiter { color: #404 }
1304 .syntaxhl .key .delimiter { color: #404 }
1301 .syntaxhl .keyword { color:#939; font-weight:bold }
1305 .syntaxhl .keyword { color:#939; font-weight:bold }
1302 .syntaxhl .label { color:#970; font-weight:bold }
1306 .syntaxhl .label { color:#970; font-weight:bold }
1303 .syntaxhl .local-variable { color:#950 }
1307 .syntaxhl .local-variable { color:#950 }
1304 .syntaxhl .map .content { color:#808 }
1308 .syntaxhl .map .content { color:#808 }
1305 .syntaxhl .map .delimiter { color:#40A}
1309 .syntaxhl .map .delimiter { color:#40A}
1306 .syntaxhl .map { background-color:hsla(200,100%,50%,0.06); }
1310 .syntaxhl .map { background-color:hsla(200,100%,50%,0.06); }
1307 .syntaxhl .namespace { color:#707; font-weight:bold }
1311 .syntaxhl .namespace { color:#707; font-weight:bold }
1308 .syntaxhl .octal { color:#40E }
1312 .syntaxhl .octal { color:#40E }
1309 .syntaxhl .operator { }
1313 .syntaxhl .operator { }
1310 .syntaxhl .predefined { color:#369; font-weight:bold }
1314 .syntaxhl .predefined { color:#369; font-weight:bold }
1311 .syntaxhl .predefined-constant { color:#069 }
1315 .syntaxhl .predefined-constant { color:#069 }
1312 .syntaxhl .predefined-type { color:#0a8; font-weight:bold }
1316 .syntaxhl .predefined-type { color:#0a8; font-weight:bold }
1313 .syntaxhl .preprocessor { color:#579 }
1317 .syntaxhl .preprocessor { color:#579 }
1314 .syntaxhl .pseudo-class { color:#00C; font-weight:bold }
1318 .syntaxhl .pseudo-class { color:#00C; font-weight:bold }
1315 .syntaxhl .regexp { background-color:hsla(300,100%,50%,0.06); }
1319 .syntaxhl .regexp { background-color:hsla(300,100%,50%,0.06); }
1316 .syntaxhl .regexp .content { color:#808 }
1320 .syntaxhl .regexp .content { color:#808 }
1317 .syntaxhl .regexp .delimiter { color:#404 }
1321 .syntaxhl .regexp .delimiter { color:#404 }
1318 .syntaxhl .regexp .modifier { color:#C2C }
1322 .syntaxhl .regexp .modifier { color:#C2C }
1319 .syntaxhl .reserved { color:#080; font-weight:bold }
1323 .syntaxhl .reserved { color:#080; font-weight:bold }
1320 .syntaxhl .shell { background-color:hsla(120,100%,50%,0.06); }
1324 .syntaxhl .shell { background-color:hsla(120,100%,50%,0.06); }
1321 .syntaxhl .shell .content { color:#2B2 }
1325 .syntaxhl .shell .content { color:#2B2 }
1322 .syntaxhl .shell .delimiter { color:#161 }
1326 .syntaxhl .shell .delimiter { color:#161 }
1323 .syntaxhl .string .char { color: #46a }
1327 .syntaxhl .string .char { color: #46a }
1324 .syntaxhl .string .content { color: #46a }
1328 .syntaxhl .string .content { color: #46a }
1325 .syntaxhl .string .delimiter { color: #46a }
1329 .syntaxhl .string .delimiter { color: #46a }
1326 .syntaxhl .string .modifier { color: #46a }
1330 .syntaxhl .string .modifier { color: #46a }
1327 .syntaxhl .symbol { color:#d33 }
1331 .syntaxhl .symbol { color:#d33 }
1328 .syntaxhl .symbol .content { color:#d33 }
1332 .syntaxhl .symbol .content { color:#d33 }
1329 .syntaxhl .symbol .delimiter { color:#d33 }
1333 .syntaxhl .symbol .delimiter { color:#d33 }
1330 .syntaxhl .tag { color:#070; font-weight:bold }
1334 .syntaxhl .tag { color:#070; font-weight:bold }
1331 .syntaxhl .type { color:#339; font-weight:bold }
1335 .syntaxhl .type { color:#339; font-weight:bold }
1332 .syntaxhl .value { color: #088 }
1336 .syntaxhl .value { color: #088 }
1333 .syntaxhl .variable { color:#037 }
1337 .syntaxhl .variable { color:#037 }
1334
1338
1335 .syntaxhl .insert { background: hsla(120,100%,50%,0.12) }
1339 .syntaxhl .insert { background: hsla(120,100%,50%,0.12) }
1336 .syntaxhl .delete { background: hsla(0,100%,50%,0.12) }
1340 .syntaxhl .delete { background: hsla(0,100%,50%,0.12) }
1337 .syntaxhl .change { color: #bbf; background: #007 }
1341 .syntaxhl .change { color: #bbf; background: #007 }
1338 .syntaxhl .head { color: #f8f; background: #505 }
1342 .syntaxhl .head { color: #f8f; background: #505 }
1339 .syntaxhl .head .filename { color: white; }
1343 .syntaxhl .head .filename { color: white; }
1340
1344
1341 .syntaxhl .delete .eyecatcher { background-color: hsla(0,100%,50%,0.2); border: 1px solid hsla(0,100%,45%,0.5); margin: -1px; border-bottom: none; border-top-left-radius: 5px; border-top-right-radius: 5px; }
1345 .syntaxhl .delete .eyecatcher { background-color: hsla(0,100%,50%,0.2); border: 1px solid hsla(0,100%,45%,0.5); margin: -1px; border-bottom: none; border-top-left-radius: 5px; border-top-right-radius: 5px; }
1342 .syntaxhl .insert .eyecatcher { background-color: hsla(120,100%,50%,0.2); border: 1px solid hsla(120,100%,25%,0.5); margin: -1px; border-top: none; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; }
1346 .syntaxhl .insert .eyecatcher { background-color: hsla(120,100%,50%,0.2); border: 1px solid hsla(120,100%,25%,0.5); margin: -1px; border-top: none; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; }
1343
1347
1344 .syntaxhl .insert .insert { color: #0c0; background:transparent; font-weight:bold }
1348 .syntaxhl .insert .insert { color: #0c0; background:transparent; font-weight:bold }
1345 .syntaxhl .delete .delete { color: #c00; background:transparent; font-weight:bold }
1349 .syntaxhl .delete .delete { color: #c00; background:transparent; font-weight:bold }
1346 .syntaxhl .change .change { color: #88f }
1350 .syntaxhl .change .change { color: #88f }
1347 .syntaxhl .head .head { color: #f4f }
1351 .syntaxhl .head .head { color: #f4f }
1348
1352
1349 /***** Media print specific styles *****/
1353 /***** Media print specific styles *****/
1350 @media print {
1354 @media print {
1351 #top-menu, #header, #main-menu, #sidebar, #footer, .contextual, .other-formats { display:none; }
1355 #top-menu, #header, #main-menu, #sidebar, #footer, .contextual, .other-formats { display:none; }
1352 #main { background: #fff; }
1356 #main { background: #fff; }
1353 #content { width: 99%; margin: 0; padding: 0; border: 0; background: #fff; overflow: visible !important;}
1357 #content { width: 99%; margin: 0; padding: 0; border: 0; background: #fff; overflow: visible !important;}
1354 #wiki_add_attachment { display:none; }
1358 #wiki_add_attachment { display:none; }
1355 .hide-when-print { display: none; }
1359 .hide-when-print { display: none; }
1356 .autoscroll {overflow-x: visible;}
1360 .autoscroll {overflow-x: visible;}
1357 table.list {margin-top:0.5em;}
1361 table.list {margin-top:0.5em;}
1358 table.list th, table.list td {border: 1px solid #aaa;}
1362 table.list th, table.list td {border: 1px solid #aaa;}
1359 }
1363 }
1360
1364
1361 /* Accessibility specific styles */
1365 /* Accessibility specific styles */
1362 .hidden-for-sighted {
1366 .hidden-for-sighted {
1363 position:absolute;
1367 position:absolute;
1364 left:-10000px;
1368 left:-10000px;
1365 top:auto;
1369 top:auto;
1366 width:1px;
1370 width:1px;
1367 height:1px;
1371 height:1px;
1368 overflow:hidden;
1372 overflow:hidden;
1369 }
1373 }
@@ -1,221 +1,221
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2016 Jean-Philippe Lang
2 # Copyright (C) 2006-2016 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 File.expand_path('../../test_helper', __FILE__)
18 require File.expand_path('../../test_helper', __FILE__)
19
19
20 class BoardsControllerTest < ActionController::TestCase
20 class BoardsControllerTest < ActionController::TestCase
21 fixtures :projects, :users, :members, :member_roles, :roles, :boards, :messages, :enabled_modules
21 fixtures :projects, :users, :members, :member_roles, :roles, :boards, :messages, :enabled_modules
22
22
23 def setup
23 def setup
24 User.current = nil
24 User.current = nil
25 end
25 end
26
26
27 def test_index
27 def test_index
28 get :index, :project_id => 1
28 get :index, :project_id => 1
29 assert_response :success
29 assert_response :success
30 assert_template 'index'
30 assert_template 'index'
31 assert_not_nil assigns(:boards)
31 assert_not_nil assigns(:boards)
32 assert_not_nil assigns(:project)
32 assert_not_nil assigns(:project)
33 end
33 end
34
34
35 def test_index_not_found
35 def test_index_not_found
36 get :index, :project_id => 97
36 get :index, :project_id => 97
37 assert_response 404
37 assert_response 404
38 end
38 end
39
39
40 def test_index_should_show_messages_if_only_one_board
40 def test_index_should_show_messages_if_only_one_board
41 Project.find(1).boards.slice(1..-1).each(&:destroy)
41 Project.find(1).boards.slice(1..-1).each(&:destroy)
42
42
43 get :index, :project_id => 1
43 get :index, :project_id => 1
44 assert_response :success
44 assert_response :success
45 assert_template 'show'
45 assert_template 'show'
46 assert_not_nil assigns(:topics)
46 assert_not_nil assigns(:topics)
47 end
47 end
48
48
49 def test_show
49 def test_show
50 get :show, :project_id => 1, :id => 1
50 get :show, :project_id => 1, :id => 1
51 assert_response :success
51 assert_response :success
52 assert_template 'show'
52 assert_template 'show'
53 assert_not_nil assigns(:board)
53 assert_not_nil assigns(:board)
54 assert_not_nil assigns(:project)
54 assert_not_nil assigns(:project)
55 assert_not_nil assigns(:topics)
55 assert_not_nil assigns(:topics)
56 end
56 end
57
57
58 def test_show_should_display_sticky_messages_first
58 def test_show_should_display_sticky_messages_first
59 Message.update_all(:sticky => 0)
59 Message.update_all(:sticky => 0)
60 Message.where({:id => 1}).update_all({:sticky => 1})
60 Message.where({:id => 1}).update_all({:sticky => 1})
61
61
62 get :show, :project_id => 1, :id => 1
62 get :show, :project_id => 1, :id => 1
63 assert_response :success
63 assert_response :success
64
64
65 topics = assigns(:topics)
65 topics = assigns(:topics)
66 assert_not_nil topics
66 assert_not_nil topics
67 assert topics.size > 1, "topics size was #{topics.size}"
67 assert topics.size > 1, "topics size was #{topics.size}"
68 assert topics.first.sticky?
68 assert topics.first.sticky?
69 assert topics.first.updated_on < topics.second.updated_on
69 assert topics.first.updated_on < topics.second.updated_on
70 end
70 end
71
71
72 def test_show_should_display_message_with_last_reply_first
72 def test_show_should_display_message_with_last_reply_first
73 Message.update_all(:sticky => 0)
73 Message.update_all(:sticky => 0)
74
74
75 # Reply to an old topic
75 # Reply to an old topic
76 old_topic = Message.where(:board_id => 1, :parent_id => nil).order('created_on ASC').first
76 old_topic = Message.where(:board_id => 1, :parent_id => nil).order('created_on ASC').first
77 reply = Message.new(:board_id => 1, :subject => 'New reply', :content => 'New reply', :author_id => 2)
77 reply = Message.new(:board_id => 1, :subject => 'New reply', :content => 'New reply', :author_id => 2)
78 old_topic.children << reply
78 old_topic.children << reply
79
79
80 get :show, :project_id => 1, :id => 1
80 get :show, :project_id => 1, :id => 1
81 assert_response :success
81 assert_response :success
82 topics = assigns(:topics)
82 topics = assigns(:topics)
83 assert_not_nil topics
83 assert_not_nil topics
84 assert_equal old_topic, topics.first
84 assert_equal old_topic, topics.first
85 end
85 end
86
86
87 def test_show_with_permission_should_display_the_new_message_form
87 def test_show_with_permission_should_display_the_new_message_form
88 @request.session[:user_id] = 2
88 @request.session[:user_id] = 2
89 get :show, :project_id => 1, :id => 1
89 get :show, :project_id => 1, :id => 1
90 assert_response :success
90 assert_response :success
91 assert_template 'show'
91 assert_template 'show'
92
92
93 assert_select 'form#message-form' do
93 assert_select 'form#message-form' do
94 assert_select 'input[name=?]', 'message[subject]'
94 assert_select 'input[name=?]', 'message[subject]'
95 end
95 end
96 end
96 end
97
97
98 def test_show_atom
98 def test_show_atom
99 get :show, :project_id => 1, :id => 1, :format => 'atom'
99 get :show, :project_id => 1, :id => 1, :format => 'atom'
100 assert_response :success
100 assert_response :success
101 assert_template 'common/feed'
101 assert_template 'common/feed'
102 assert_not_nil assigns(:board)
102 assert_not_nil assigns(:board)
103 assert_not_nil assigns(:project)
103 assert_not_nil assigns(:project)
104 assert_not_nil assigns(:messages)
104 assert_not_nil assigns(:messages)
105 end
105 end
106
106
107 def test_show_not_found
107 def test_show_not_found
108 get :index, :project_id => 1, :id => 97
108 get :index, :project_id => 1, :id => 97
109 assert_response 404
109 assert_response 404
110 end
110 end
111
111
112 def test_new
112 def test_new
113 @request.session[:user_id] = 2
113 @request.session[:user_id] = 2
114 get :new, :project_id => 1
114 get :new, :project_id => 1
115 assert_response :success
115 assert_response :success
116 assert_template 'new'
116 assert_template 'new'
117
117
118 assert_select 'select[name=?]', 'board[parent_id]' do
118 assert_select 'select[name=?]', 'board[parent_id]' do
119 assert_select 'option', (Project.find(1).boards.size + 1)
119 assert_select 'option', (Project.find(1).boards.size + 1)
120 assert_select 'option[value=""]'
120 assert_select 'option[value=""]'
121 assert_select 'option[value="1"]', :text => 'Help'
121 assert_select 'option[value="1"]', :text => 'Help'
122 end
122 end
123
123
124 # &nbsp; replaced by nokogiri, not easy to test in DOM assertions
124 # &nbsp; replaced by nokogiri, not easy to test in DOM assertions
125 assert_not_include '<option value=""></option>', response.body
125 assert_not_include '<option value=""></option>', response.body
126 assert_include '<option value="">&nbsp;</option>', response.body
126 assert_include '<option value="">&nbsp;</option>', response.body
127 end
127 end
128
128
129 def test_new_without_project_boards
129 def test_new_without_project_boards
130 Project.find(1).boards.delete_all
130 Project.find(1).boards.delete_all
131 @request.session[:user_id] = 2
131 @request.session[:user_id] = 2
132
132
133 get :new, :project_id => 1
133 get :new, :project_id => 1
134 assert_response :success
134 assert_response :success
135 assert_template 'new'
135 assert_template 'new'
136
136
137 assert_select 'select[name=?]', 'board[parent_id]', 0
137 assert_select 'select[name=?]', 'board[parent_id]', 0
138 end
138 end
139
139
140 def test_create
140 def test_create
141 @request.session[:user_id] = 2
141 @request.session[:user_id] = 2
142 assert_difference 'Board.count' do
142 assert_difference 'Board.count' do
143 post :create, :project_id => 1, :board => { :name => 'Testing', :description => 'Testing board creation'}
143 post :create, :project_id => 1, :board => { :name => 'Testing', :description => 'Testing board creation'}
144 end
144 end
145 assert_redirected_to '/projects/ecookbook/settings/boards'
145 assert_redirected_to '/projects/ecookbook/settings/boards'
146 board = Board.order('id DESC').first
146 board = Board.order('id DESC').first
147 assert_equal 'Testing', board.name
147 assert_equal 'Testing', board.name
148 assert_equal 'Testing board creation', board.description
148 assert_equal 'Testing board creation', board.description
149 end
149 end
150
150
151 def test_create_with_parent
151 def test_create_with_parent
152 @request.session[:user_id] = 2
152 @request.session[:user_id] = 2
153 assert_difference 'Board.count' do
153 assert_difference 'Board.count' do
154 post :create, :project_id => 1, :board => { :name => 'Testing', :description => 'Testing', :parent_id => 2}
154 post :create, :project_id => 1, :board => { :name => 'Testing', :description => 'Testing', :parent_id => 2}
155 end
155 end
156 assert_redirected_to '/projects/ecookbook/settings/boards'
156 assert_redirected_to '/projects/ecookbook/settings/boards'
157 board = Board.order('id DESC').first
157 board = Board.order('id DESC').first
158 assert_equal Board.find(2), board.parent
158 assert_equal Board.find(2), board.parent
159 end
159 end
160
160
161 def test_create_with_failure
161 def test_create_with_failure
162 @request.session[:user_id] = 2
162 @request.session[:user_id] = 2
163 assert_no_difference 'Board.count' do
163 assert_no_difference 'Board.count' do
164 post :create, :project_id => 1, :board => { :name => '', :description => 'Testing board creation'}
164 post :create, :project_id => 1, :board => { :name => '', :description => 'Testing board creation'}
165 end
165 end
166 assert_response :success
166 assert_response :success
167 assert_template 'new'
167 assert_template 'new'
168 end
168 end
169
169
170 def test_edit
170 def test_edit
171 @request.session[:user_id] = 2
171 @request.session[:user_id] = 2
172 get :edit, :project_id => 1, :id => 2
172 get :edit, :project_id => 1, :id => 2
173 assert_response :success
173 assert_response :success
174 assert_template 'edit'
174 assert_template 'edit'
175 end
175 end
176
176
177 def test_edit_with_parent
177 def test_edit_with_parent
178 board = Board.generate!(:project_id => 1, :parent_id => 2)
178 board = Board.generate!(:project_id => 1, :parent_id => 2)
179 @request.session[:user_id] = 2
179 @request.session[:user_id] = 2
180 get :edit, :project_id => 1, :id => board.id
180 get :edit, :project_id => 1, :id => board.id
181 assert_response :success
181 assert_response :success
182 assert_template 'edit'
182 assert_template 'edit'
183
183
184 assert_select 'select[name=?]', 'board[parent_id]' do
184 assert_select 'select[name=?]', 'board[parent_id]' do
185 assert_select 'option[value="2"][selected=selected]'
185 assert_select 'option[value="2"][selected=selected]'
186 end
186 end
187 end
187 end
188
188
189 def test_update
189 def test_update
190 @request.session[:user_id] = 2
190 @request.session[:user_id] = 2
191 assert_no_difference 'Board.count' do
191 assert_no_difference 'Board.count' do
192 put :update, :project_id => 1, :id => 2, :board => { :name => 'Testing', :description => 'Testing board update'}
192 put :update, :project_id => 1, :id => 2, :board => { :name => 'Testing', :description => 'Testing board update'}
193 end
193 end
194 assert_redirected_to '/projects/ecookbook/settings/boards'
194 assert_redirected_to '/projects/ecookbook/settings/boards'
195 assert_equal 'Testing', Board.find(2).name
195 assert_equal 'Testing', Board.find(2).name
196 end
196 end
197
197
198 def test_update_position
198 def test_update_position
199 @request.session[:user_id] = 2
199 @request.session[:user_id] = 2
200 put :update, :project_id => 1, :id => 2, :board => { :move_to => 'highest'}
200 put :update, :project_id => 1, :id => 2, :board => { :position => 1}
201 assert_redirected_to '/projects/ecookbook/settings/boards'
201 assert_redirected_to '/projects/ecookbook/settings/boards'
202 board = Board.find(2)
202 board = Board.find(2)
203 assert_equal 1, board.position
203 assert_equal 1, board.position
204 end
204 end
205
205
206 def test_update_with_failure
206 def test_update_with_failure
207 @request.session[:user_id] = 2
207 @request.session[:user_id] = 2
208 put :update, :project_id => 1, :id => 2, :board => { :name => '', :description => 'Testing board update'}
208 put :update, :project_id => 1, :id => 2, :board => { :name => '', :description => 'Testing board update'}
209 assert_response :success
209 assert_response :success
210 assert_template 'edit'
210 assert_template 'edit'
211 end
211 end
212
212
213 def test_destroy
213 def test_destroy
214 @request.session[:user_id] = 2
214 @request.session[:user_id] = 2
215 assert_difference 'Board.count', -1 do
215 assert_difference 'Board.count', -1 do
216 delete :destroy, :project_id => 1, :id => 2
216 delete :destroy, :project_id => 1, :id => 2
217 end
217 end
218 assert_redirected_to '/projects/ecookbook/settings/boards'
218 assert_redirected_to '/projects/ecookbook/settings/boards'
219 assert_nil Board.find_by_id(2)
219 assert_nil Board.find_by_id(2)
220 end
220 end
221 end
221 end
General Comments 0
You need to be logged in to leave comments. Login now