##// END OF EJS Templates
Use common function for generation of grid data...
marcink -
r3154:0226b6d6 beta
parent child Browse files
Show More
@@ -1,628 +1,626 b''
1 """
1 """
2 Routes configuration
2 Routes configuration
3
3
4 The more specific and detailed routes should be defined first so they
4 The more specific and detailed routes should be defined first so they
5 may take precedent over the more generic routes. For more information
5 may take precedent over the more generic routes. For more information
6 refer to the routes manual at http://routes.groovie.org/docs/
6 refer to the routes manual at http://routes.groovie.org/docs/
7 """
7 """
8 from __future__ import with_statement
8 from __future__ import with_statement
9 from routes import Mapper
9 from routes import Mapper
10
10
11 # prefix for non repository related links needs to be prefixed with `/`
11 # prefix for non repository related links needs to be prefixed with `/`
12 ADMIN_PREFIX = '/_admin'
12 ADMIN_PREFIX = '/_admin'
13
13
14
14
15 def make_map(config):
15 def make_map(config):
16 """Create, configure and return the routes Mapper"""
16 """Create, configure and return the routes Mapper"""
17 rmap = Mapper(directory=config['pylons.paths']['controllers'],
17 rmap = Mapper(directory=config['pylons.paths']['controllers'],
18 always_scan=config['debug'])
18 always_scan=config['debug'])
19 rmap.minimization = False
19 rmap.minimization = False
20 rmap.explicit = False
20 rmap.explicit = False
21
21
22 from rhodecode.lib.utils import is_valid_repo
22 from rhodecode.lib.utils import is_valid_repo
23 from rhodecode.lib.utils import is_valid_repos_group
23 from rhodecode.lib.utils import is_valid_repos_group
24
24
25 def check_repo(environ, match_dict):
25 def check_repo(environ, match_dict):
26 """
26 """
27 check for valid repository for proper 404 handling
27 check for valid repository for proper 404 handling
28
28
29 :param environ:
29 :param environ:
30 :param match_dict:
30 :param match_dict:
31 """
31 """
32 from rhodecode.model.db import Repository
32 from rhodecode.model.db import Repository
33 repo_name = match_dict.get('repo_name')
33 repo_name = match_dict.get('repo_name')
34
34
35 if match_dict.get('f_path'):
35 if match_dict.get('f_path'):
36 #fix for multiple initial slashes that causes errors
36 #fix for multiple initial slashes that causes errors
37 match_dict['f_path'] = match_dict['f_path'].lstrip('/')
37 match_dict['f_path'] = match_dict['f_path'].lstrip('/')
38
38
39 try:
39 try:
40 by_id = repo_name.split('_')
40 by_id = repo_name.split('_')
41 if len(by_id) == 2 and by_id[1].isdigit() and by_id[0] == '':
41 if len(by_id) == 2 and by_id[1].isdigit() and by_id[0] == '':
42 repo_name = Repository.get(by_id[1]).repo_name
42 repo_name = Repository.get(by_id[1]).repo_name
43 match_dict['repo_name'] = repo_name
43 match_dict['repo_name'] = repo_name
44 except:
44 except:
45 pass
45 pass
46
46
47 return is_valid_repo(repo_name, config['base_path'])
47 return is_valid_repo(repo_name, config['base_path'])
48
48
49 def check_group(environ, match_dict):
49 def check_group(environ, match_dict):
50 """
50 """
51 check for valid repositories group for proper 404 handling
51 check for valid repositories group for proper 404 handling
52
52
53 :param environ:
53 :param environ:
54 :param match_dict:
54 :param match_dict:
55 """
55 """
56 repos_group_name = match_dict.get('group_name')
56 repos_group_name = match_dict.get('group_name')
57
57
58 return is_valid_repos_group(repos_group_name, config['base_path'])
58 return is_valid_repos_group(repos_group_name, config['base_path'])
59
59
60 def check_int(environ, match_dict):
60 def check_int(environ, match_dict):
61 return match_dict.get('id').isdigit()
61 return match_dict.get('id').isdigit()
62
62
63 # The ErrorController route (handles 404/500 error pages); it should
63 # The ErrorController route (handles 404/500 error pages); it should
64 # likely stay at the top, ensuring it can always be resolved
64 # likely stay at the top, ensuring it can always be resolved
65 rmap.connect('/error/{action}', controller='error')
65 rmap.connect('/error/{action}', controller='error')
66 rmap.connect('/error/{action}/{id}', controller='error')
66 rmap.connect('/error/{action}/{id}', controller='error')
67
67
68 #==========================================================================
68 #==========================================================================
69 # CUSTOM ROUTES HERE
69 # CUSTOM ROUTES HERE
70 #==========================================================================
70 #==========================================================================
71
71
72 #MAIN PAGE
72 #MAIN PAGE
73 rmap.connect('home', '/', controller='home', action='index')
73 rmap.connect('home', '/', controller='home', action='index')
74 rmap.connect('repo_switcher', '/repos', controller='home',
74 rmap.connect('repo_switcher', '/repos', controller='home',
75 action='repo_switcher')
75 action='repo_switcher')
76 rmap.connect('branch_tag_switcher', '/branches-tags/{repo_name:.*?}',
76 rmap.connect('branch_tag_switcher', '/branches-tags/{repo_name:.*?}',
77 controller='home', action='branch_tag_switcher')
77 controller='home', action='branch_tag_switcher')
78 rmap.connect('bugtracker',
78 rmap.connect('bugtracker',
79 "http://bitbucket.org/marcinkuzminski/rhodecode/issues",
79 "http://bitbucket.org/marcinkuzminski/rhodecode/issues",
80 _static=True)
80 _static=True)
81 rmap.connect('rst_help',
81 rmap.connect('rst_help',
82 "http://docutils.sourceforge.net/docs/user/rst/quickref.html",
82 "http://docutils.sourceforge.net/docs/user/rst/quickref.html",
83 _static=True)
83 _static=True)
84 rmap.connect('rhodecode_official', "http://rhodecode.org", _static=True)
84 rmap.connect('rhodecode_official', "http://rhodecode.org", _static=True)
85
85
86 #ADMIN REPOSITORY REST ROUTES
86 #ADMIN REPOSITORY REST ROUTES
87 with rmap.submapper(path_prefix=ADMIN_PREFIX,
87 with rmap.submapper(path_prefix=ADMIN_PREFIX,
88 controller='admin/repos') as m:
88 controller='admin/repos') as m:
89 m.connect("repos", "/repos",
89 m.connect("repos", "/repos",
90 action="create", conditions=dict(method=["POST"]))
90 action="create", conditions=dict(method=["POST"]))
91 m.connect("repos", "/repos",
91 m.connect("repos", "/repos",
92 action="index", conditions=dict(method=["GET"]))
92 action="index", conditions=dict(method=["GET"]))
93 m.connect("formatted_repos", "/repos.{format}",
93 m.connect("formatted_repos", "/repos.{format}",
94 action="index",
94 action="index",
95 conditions=dict(method=["GET"]))
95 conditions=dict(method=["GET"]))
96 m.connect("new_repo", "/repos/new",
96 m.connect("new_repo", "/repos/new",
97 action="new", conditions=dict(method=["GET"]))
97 action="new", conditions=dict(method=["GET"]))
98 m.connect("formatted_new_repo", "/repos/new.{format}",
98 m.connect("formatted_new_repo", "/repos/new.{format}",
99 action="new", conditions=dict(method=["GET"]))
99 action="new", conditions=dict(method=["GET"]))
100 m.connect("/repos/{repo_name:.*?}",
100 m.connect("/repos/{repo_name:.*?}",
101 action="update", conditions=dict(method=["PUT"],
101 action="update", conditions=dict(method=["PUT"],
102 function=check_repo))
102 function=check_repo))
103 m.connect("/repos/{repo_name:.*?}",
103 m.connect("/repos/{repo_name:.*?}",
104 action="delete", conditions=dict(method=["DELETE"],
104 action="delete", conditions=dict(method=["DELETE"],
105 function=check_repo))
105 function=check_repo))
106 m.connect("edit_repo", "/repos/{repo_name:.*?}/edit",
106 m.connect("edit_repo", "/repos/{repo_name:.*?}/edit",
107 action="edit", conditions=dict(method=["GET"],
107 action="edit", conditions=dict(method=["GET"],
108 function=check_repo))
108 function=check_repo))
109 m.connect("formatted_edit_repo", "/repos/{repo_name:.*?}.{format}/edit",
109 m.connect("formatted_edit_repo", "/repos/{repo_name:.*?}.{format}/edit",
110 action="edit", conditions=dict(method=["GET"],
110 action="edit", conditions=dict(method=["GET"],
111 function=check_repo))
111 function=check_repo))
112 m.connect("repo", "/repos/{repo_name:.*?}",
112 m.connect("repo", "/repos/{repo_name:.*?}",
113 action="show", conditions=dict(method=["GET"],
113 action="show", conditions=dict(method=["GET"],
114 function=check_repo))
114 function=check_repo))
115 m.connect("formatted_repo", "/repos/{repo_name:.*?}.{format}",
115 m.connect("formatted_repo", "/repos/{repo_name:.*?}.{format}",
116 action="show", conditions=dict(method=["GET"],
116 action="show", conditions=dict(method=["GET"],
117 function=check_repo))
117 function=check_repo))
118 #ajax delete repo perm user
118 #ajax delete repo perm user
119 m.connect('delete_repo_user', "/repos_delete_user/{repo_name:.*?}",
119 m.connect('delete_repo_user', "/repos_delete_user/{repo_name:.*?}",
120 action="delete_perm_user",
120 action="delete_perm_user",
121 conditions=dict(method=["DELETE"], function=check_repo))
121 conditions=dict(method=["DELETE"], function=check_repo))
122
122
123 #ajax delete repo perm users_group
123 #ajax delete repo perm users_group
124 m.connect('delete_repo_users_group',
124 m.connect('delete_repo_users_group',
125 "/repos_delete_users_group/{repo_name:.*?}",
125 "/repos_delete_users_group/{repo_name:.*?}",
126 action="delete_perm_users_group",
126 action="delete_perm_users_group",
127 conditions=dict(method=["DELETE"], function=check_repo))
127 conditions=dict(method=["DELETE"], function=check_repo))
128
128
129 #settings actions
129 #settings actions
130 m.connect('repo_stats', "/repos_stats/{repo_name:.*?}",
130 m.connect('repo_stats', "/repos_stats/{repo_name:.*?}",
131 action="repo_stats", conditions=dict(method=["DELETE"],
131 action="repo_stats", conditions=dict(method=["DELETE"],
132 function=check_repo))
132 function=check_repo))
133 m.connect('repo_cache', "/repos_cache/{repo_name:.*?}",
133 m.connect('repo_cache', "/repos_cache/{repo_name:.*?}",
134 action="repo_cache", conditions=dict(method=["DELETE"],
134 action="repo_cache", conditions=dict(method=["DELETE"],
135 function=check_repo))
135 function=check_repo))
136 m.connect('repo_public_journal', "/repos_public_journal/{repo_name:.*?}",
136 m.connect('repo_public_journal', "/repos_public_journal/{repo_name:.*?}",
137 action="repo_public_journal", conditions=dict(method=["PUT"],
137 action="repo_public_journal", conditions=dict(method=["PUT"],
138 function=check_repo))
138 function=check_repo))
139 m.connect('repo_pull', "/repo_pull/{repo_name:.*?}",
139 m.connect('repo_pull', "/repo_pull/{repo_name:.*?}",
140 action="repo_pull", conditions=dict(method=["PUT"],
140 action="repo_pull", conditions=dict(method=["PUT"],
141 function=check_repo))
141 function=check_repo))
142 m.connect('repo_as_fork', "/repo_as_fork/{repo_name:.*?}",
142 m.connect('repo_as_fork', "/repo_as_fork/{repo_name:.*?}",
143 action="repo_as_fork", conditions=dict(method=["PUT"],
143 action="repo_as_fork", conditions=dict(method=["PUT"],
144 function=check_repo))
144 function=check_repo))
145 m.connect('repo_locking', "/repo_locking/{repo_name:.*?}",
145 m.connect('repo_locking', "/repo_locking/{repo_name:.*?}",
146 action="repo_locking", conditions=dict(method=["PUT"],
146 action="repo_locking", conditions=dict(method=["PUT"],
147 function=check_repo))
147 function=check_repo))
148
148
149 with rmap.submapper(path_prefix=ADMIN_PREFIX,
149 with rmap.submapper(path_prefix=ADMIN_PREFIX,
150 controller='admin/repos_groups') as m:
150 controller='admin/repos_groups') as m:
151 m.connect("repos_groups", "/repos_groups",
151 m.connect("repos_groups", "/repos_groups",
152 action="create", conditions=dict(method=["POST"]))
152 action="create", conditions=dict(method=["POST"]))
153 m.connect("repos_groups", "/repos_groups",
153 m.connect("repos_groups", "/repos_groups",
154 action="index", conditions=dict(method=["GET"]))
154 action="index", conditions=dict(method=["GET"]))
155 m.connect("formatted_repos_groups", "/repos_groups.{format}",
155 m.connect("formatted_repos_groups", "/repos_groups.{format}",
156 action="index", conditions=dict(method=["GET"]))
156 action="index", conditions=dict(method=["GET"]))
157 m.connect("new_repos_group", "/repos_groups/new",
157 m.connect("new_repos_group", "/repos_groups/new",
158 action="new", conditions=dict(method=["GET"]))
158 action="new", conditions=dict(method=["GET"]))
159 m.connect("formatted_new_repos_group", "/repos_groups/new.{format}",
159 m.connect("formatted_new_repos_group", "/repos_groups/new.{format}",
160 action="new", conditions=dict(method=["GET"]))
160 action="new", conditions=dict(method=["GET"]))
161 m.connect("update_repos_group", "/repos_groups/{id}",
161 m.connect("update_repos_group", "/repos_groups/{id}",
162 action="update", conditions=dict(method=["PUT"],
162 action="update", conditions=dict(method=["PUT"],
163 function=check_int))
163 function=check_int))
164 m.connect("delete_repos_group", "/repos_groups/{id}",
164 m.connect("delete_repos_group", "/repos_groups/{id}",
165 action="delete", conditions=dict(method=["DELETE"],
165 action="delete", conditions=dict(method=["DELETE"],
166 function=check_int))
166 function=check_int))
167 m.connect("edit_repos_group", "/repos_groups/{id:.*?}/edit",
167 m.connect("edit_repos_group", "/repos_groups/{id:.*?}/edit",
168 action="edit", conditions=dict(method=["GET"],))
168 action="edit", conditions=dict(method=["GET"],))
169 m.connect("formatted_edit_repos_group",
169 m.connect("formatted_edit_repos_group",
170 "/repos_groups/{id}.{format}/edit",
170 "/repos_groups/{id}.{format}/edit",
171 action="edit", conditions=dict(method=["GET"],
171 action="edit", conditions=dict(method=["GET"],
172 function=check_int))
172 function=check_int))
173 m.connect("repos_group", "/repos_groups/{id}",
173 m.connect("repos_group", "/repos_groups/{id}",
174 action="show", conditions=dict(method=["GET"],
174 action="show", conditions=dict(method=["GET"],
175 function=check_int))
175 function=check_int))
176 m.connect("formatted_repos_group", "/repos_groups/{id}.{format}",
176 m.connect("formatted_repos_group", "/repos_groups/{id}.{format}",
177 action="show", conditions=dict(method=["GET"],
177 action="show", conditions=dict(method=["GET"],
178 function=check_int))
178 function=check_int))
179 # ajax delete repos group perm user
179 # ajax delete repos group perm user
180 m.connect('delete_repos_group_user_perm',
180 m.connect('delete_repos_group_user_perm',
181 "/delete_repos_group_user_perm/{group_name:.*}",
181 "/delete_repos_group_user_perm/{group_name:.*}",
182 action="delete_repos_group_user_perm",
182 action="delete_repos_group_user_perm",
183 conditions=dict(method=["DELETE"], function=check_group))
183 conditions=dict(method=["DELETE"], function=check_group))
184
184
185 # ajax delete repos group perm users_group
185 # ajax delete repos group perm users_group
186 m.connect('delete_repos_group_users_group_perm',
186 m.connect('delete_repos_group_users_group_perm',
187 "/delete_repos_group_users_group_perm/{group_name:.*}",
187 "/delete_repos_group_users_group_perm/{group_name:.*}",
188 action="delete_repos_group_users_group_perm",
188 action="delete_repos_group_users_group_perm",
189 conditions=dict(method=["DELETE"], function=check_group))
189 conditions=dict(method=["DELETE"], function=check_group))
190
190
191 #ADMIN USER REST ROUTES
191 #ADMIN USER REST ROUTES
192 with rmap.submapper(path_prefix=ADMIN_PREFIX,
192 with rmap.submapper(path_prefix=ADMIN_PREFIX,
193 controller='admin/users') as m:
193 controller='admin/users') as m:
194 m.connect("users", "/users",
194 m.connect("users", "/users",
195 action="create", conditions=dict(method=["POST"]))
195 action="create", conditions=dict(method=["POST"]))
196 m.connect("users", "/users",
196 m.connect("users", "/users",
197 action="index", conditions=dict(method=["GET"]))
197 action="index", conditions=dict(method=["GET"]))
198 m.connect("formatted_users", "/users.{format}",
198 m.connect("formatted_users", "/users.{format}",
199 action="index", conditions=dict(method=["GET"]))
199 action="index", conditions=dict(method=["GET"]))
200 m.connect("new_user", "/users/new",
200 m.connect("new_user", "/users/new",
201 action="new", conditions=dict(method=["GET"]))
201 action="new", conditions=dict(method=["GET"]))
202 m.connect("formatted_new_user", "/users/new.{format}",
202 m.connect("formatted_new_user", "/users/new.{format}",
203 action="new", conditions=dict(method=["GET"]))
203 action="new", conditions=dict(method=["GET"]))
204 m.connect("update_user", "/users/{id}",
204 m.connect("update_user", "/users/{id}",
205 action="update", conditions=dict(method=["PUT"]))
205 action="update", conditions=dict(method=["PUT"]))
206 m.connect("delete_user", "/users/{id}",
206 m.connect("delete_user", "/users/{id}",
207 action="delete", conditions=dict(method=["DELETE"]))
207 action="delete", conditions=dict(method=["DELETE"]))
208 m.connect("edit_user", "/users/{id}/edit",
208 m.connect("edit_user", "/users/{id}/edit",
209 action="edit", conditions=dict(method=["GET"]))
209 action="edit", conditions=dict(method=["GET"]))
210 m.connect("formatted_edit_user",
210 m.connect("formatted_edit_user",
211 "/users/{id}.{format}/edit",
211 "/users/{id}.{format}/edit",
212 action="edit", conditions=dict(method=["GET"]))
212 action="edit", conditions=dict(method=["GET"]))
213 m.connect("user", "/users/{id}",
213 m.connect("user", "/users/{id}",
214 action="show", conditions=dict(method=["GET"]))
214 action="show", conditions=dict(method=["GET"]))
215 m.connect("formatted_user", "/users/{id}.{format}",
215 m.connect("formatted_user", "/users/{id}.{format}",
216 action="show", conditions=dict(method=["GET"]))
216 action="show", conditions=dict(method=["GET"]))
217
217
218 #EXTRAS USER ROUTES
218 #EXTRAS USER ROUTES
219 m.connect("user_perm", "/users_perm/{id}",
219 m.connect("user_perm", "/users_perm/{id}",
220 action="update_perm", conditions=dict(method=["PUT"]))
220 action="update_perm", conditions=dict(method=["PUT"]))
221 m.connect("user_emails", "/users_emails/{id}",
221 m.connect("user_emails", "/users_emails/{id}",
222 action="add_email", conditions=dict(method=["PUT"]))
222 action="add_email", conditions=dict(method=["PUT"]))
223 m.connect("user_emails_delete", "/users_emails/{id}",
223 m.connect("user_emails_delete", "/users_emails/{id}",
224 action="delete_email", conditions=dict(method=["DELETE"]))
224 action="delete_email", conditions=dict(method=["DELETE"]))
225 m.connect("user_ips", "/users_ips/{id}",
225 m.connect("user_ips", "/users_ips/{id}",
226 action="add_ip", conditions=dict(method=["PUT"]))
226 action="add_ip", conditions=dict(method=["PUT"]))
227 m.connect("user_ips_delete", "/users_ips/{id}",
227 m.connect("user_ips_delete", "/users_ips/{id}",
228 action="delete_ip", conditions=dict(method=["DELETE"]))
228 action="delete_ip", conditions=dict(method=["DELETE"]))
229
229
230 #ADMIN USERS GROUPS REST ROUTES
230 #ADMIN USERS GROUPS REST ROUTES
231 with rmap.submapper(path_prefix=ADMIN_PREFIX,
231 with rmap.submapper(path_prefix=ADMIN_PREFIX,
232 controller='admin/users_groups') as m:
232 controller='admin/users_groups') as m:
233 m.connect("users_groups", "/users_groups",
233 m.connect("users_groups", "/users_groups",
234 action="create", conditions=dict(method=["POST"]))
234 action="create", conditions=dict(method=["POST"]))
235 m.connect("users_groups", "/users_groups",
235 m.connect("users_groups", "/users_groups",
236 action="index", conditions=dict(method=["GET"]))
236 action="index", conditions=dict(method=["GET"]))
237 m.connect("formatted_users_groups", "/users_groups.{format}",
237 m.connect("formatted_users_groups", "/users_groups.{format}",
238 action="index", conditions=dict(method=["GET"]))
238 action="index", conditions=dict(method=["GET"]))
239 m.connect("new_users_group", "/users_groups/new",
239 m.connect("new_users_group", "/users_groups/new",
240 action="new", conditions=dict(method=["GET"]))
240 action="new", conditions=dict(method=["GET"]))
241 m.connect("formatted_new_users_group", "/users_groups/new.{format}",
241 m.connect("formatted_new_users_group", "/users_groups/new.{format}",
242 action="new", conditions=dict(method=["GET"]))
242 action="new", conditions=dict(method=["GET"]))
243 m.connect("update_users_group", "/users_groups/{id}",
243 m.connect("update_users_group", "/users_groups/{id}",
244 action="update", conditions=dict(method=["PUT"]))
244 action="update", conditions=dict(method=["PUT"]))
245 m.connect("delete_users_group", "/users_groups/{id}",
245 m.connect("delete_users_group", "/users_groups/{id}",
246 action="delete", conditions=dict(method=["DELETE"]))
246 action="delete", conditions=dict(method=["DELETE"]))
247 m.connect("edit_users_group", "/users_groups/{id}/edit",
247 m.connect("edit_users_group", "/users_groups/{id}/edit",
248 action="edit", conditions=dict(method=["GET"]))
248 action="edit", conditions=dict(method=["GET"]))
249 m.connect("formatted_edit_users_group",
249 m.connect("formatted_edit_users_group",
250 "/users_groups/{id}.{format}/edit",
250 "/users_groups/{id}.{format}/edit",
251 action="edit", conditions=dict(method=["GET"]))
251 action="edit", conditions=dict(method=["GET"]))
252 m.connect("users_group", "/users_groups/{id}",
252 m.connect("users_group", "/users_groups/{id}",
253 action="show", conditions=dict(method=["GET"]))
253 action="show", conditions=dict(method=["GET"]))
254 m.connect("formatted_users_group", "/users_groups/{id}.{format}",
254 m.connect("formatted_users_group", "/users_groups/{id}.{format}",
255 action="show", conditions=dict(method=["GET"]))
255 action="show", conditions=dict(method=["GET"]))
256
256
257 #EXTRAS USER ROUTES
257 #EXTRAS USER ROUTES
258 m.connect("users_group_perm", "/users_groups_perm/{id}",
258 m.connect("users_group_perm", "/users_groups_perm/{id}",
259 action="update_perm", conditions=dict(method=["PUT"]))
259 action="update_perm", conditions=dict(method=["PUT"]))
260
260
261 #ADMIN GROUP REST ROUTES
261 #ADMIN GROUP REST ROUTES
262 rmap.resource('group', 'groups',
262 rmap.resource('group', 'groups',
263 controller='admin/groups', path_prefix=ADMIN_PREFIX)
263 controller='admin/groups', path_prefix=ADMIN_PREFIX)
264
264
265 #ADMIN PERMISSIONS REST ROUTES
265 #ADMIN PERMISSIONS REST ROUTES
266 rmap.resource('permission', 'permissions',
266 rmap.resource('permission', 'permissions',
267 controller='admin/permissions', path_prefix=ADMIN_PREFIX)
267 controller='admin/permissions', path_prefix=ADMIN_PREFIX)
268
268
269 #ADMIN DEFAULTS REST ROUTES
269 #ADMIN DEFAULTS REST ROUTES
270 rmap.resource('default', 'defaults',
270 rmap.resource('default', 'defaults',
271 controller='admin/defaults', path_prefix=ADMIN_PREFIX)
271 controller='admin/defaults', path_prefix=ADMIN_PREFIX)
272
272
273 ##ADMIN LDAP SETTINGS
273 ##ADMIN LDAP SETTINGS
274 rmap.connect('ldap_settings', '%s/ldap' % ADMIN_PREFIX,
274 rmap.connect('ldap_settings', '%s/ldap' % ADMIN_PREFIX,
275 controller='admin/ldap_settings', action='ldap_settings',
275 controller='admin/ldap_settings', action='ldap_settings',
276 conditions=dict(method=["POST"]))
276 conditions=dict(method=["POST"]))
277
277
278 rmap.connect('ldap_home', '%s/ldap' % ADMIN_PREFIX,
278 rmap.connect('ldap_home', '%s/ldap' % ADMIN_PREFIX,
279 controller='admin/ldap_settings')
279 controller='admin/ldap_settings')
280
280
281 #ADMIN SETTINGS REST ROUTES
281 #ADMIN SETTINGS REST ROUTES
282 with rmap.submapper(path_prefix=ADMIN_PREFIX,
282 with rmap.submapper(path_prefix=ADMIN_PREFIX,
283 controller='admin/settings') as m:
283 controller='admin/settings') as m:
284 m.connect("admin_settings", "/settings",
284 m.connect("admin_settings", "/settings",
285 action="create", conditions=dict(method=["POST"]))
285 action="create", conditions=dict(method=["POST"]))
286 m.connect("admin_settings", "/settings",
286 m.connect("admin_settings", "/settings",
287 action="index", conditions=dict(method=["GET"]))
287 action="index", conditions=dict(method=["GET"]))
288 m.connect("formatted_admin_settings", "/settings.{format}",
288 m.connect("formatted_admin_settings", "/settings.{format}",
289 action="index", conditions=dict(method=["GET"]))
289 action="index", conditions=dict(method=["GET"]))
290 m.connect("admin_new_setting", "/settings/new",
290 m.connect("admin_new_setting", "/settings/new",
291 action="new", conditions=dict(method=["GET"]))
291 action="new", conditions=dict(method=["GET"]))
292 m.connect("formatted_admin_new_setting", "/settings/new.{format}",
292 m.connect("formatted_admin_new_setting", "/settings/new.{format}",
293 action="new", conditions=dict(method=["GET"]))
293 action="new", conditions=dict(method=["GET"]))
294 m.connect("/settings/{setting_id}",
294 m.connect("/settings/{setting_id}",
295 action="update", conditions=dict(method=["PUT"]))
295 action="update", conditions=dict(method=["PUT"]))
296 m.connect("/settings/{setting_id}",
296 m.connect("/settings/{setting_id}",
297 action="delete", conditions=dict(method=["DELETE"]))
297 action="delete", conditions=dict(method=["DELETE"]))
298 m.connect("admin_edit_setting", "/settings/{setting_id}/edit",
298 m.connect("admin_edit_setting", "/settings/{setting_id}/edit",
299 action="edit", conditions=dict(method=["GET"]))
299 action="edit", conditions=dict(method=["GET"]))
300 m.connect("formatted_admin_edit_setting",
300 m.connect("formatted_admin_edit_setting",
301 "/settings/{setting_id}.{format}/edit",
301 "/settings/{setting_id}.{format}/edit",
302 action="edit", conditions=dict(method=["GET"]))
302 action="edit", conditions=dict(method=["GET"]))
303 m.connect("admin_setting", "/settings/{setting_id}",
303 m.connect("admin_setting", "/settings/{setting_id}",
304 action="show", conditions=dict(method=["GET"]))
304 action="show", conditions=dict(method=["GET"]))
305 m.connect("formatted_admin_setting", "/settings/{setting_id}.{format}",
305 m.connect("formatted_admin_setting", "/settings/{setting_id}.{format}",
306 action="show", conditions=dict(method=["GET"]))
306 action="show", conditions=dict(method=["GET"]))
307 m.connect("admin_settings_my_account", "/my_account",
307 m.connect("admin_settings_my_account", "/my_account",
308 action="my_account", conditions=dict(method=["GET"]))
308 action="my_account", conditions=dict(method=["GET"]))
309 m.connect("admin_settings_my_account_update", "/my_account_update",
309 m.connect("admin_settings_my_account_update", "/my_account_update",
310 action="my_account_update", conditions=dict(method=["PUT"]))
310 action="my_account_update", conditions=dict(method=["PUT"]))
311 m.connect("admin_settings_create_repository", "/create_repository",
311 m.connect("admin_settings_create_repository", "/create_repository",
312 action="create_repository", conditions=dict(method=["GET"]))
312 action="create_repository", conditions=dict(method=["GET"]))
313 m.connect("admin_settings_my_repos", "/my_account/repos",
313 m.connect("admin_settings_my_repos", "/my_account/repos",
314 action="my_account_my_repos", conditions=dict(method=["GET"]))
314 action="my_account_my_repos", conditions=dict(method=["GET"]))
315 m.connect("admin_settings_my_pullrequests", "/my_account/pull_requests",
315 m.connect("admin_settings_my_pullrequests", "/my_account/pull_requests",
316 action="my_account_my_pullrequests", conditions=dict(method=["GET"]))
316 action="my_account_my_pullrequests", conditions=dict(method=["GET"]))
317
317
318 #NOTIFICATION REST ROUTES
318 #NOTIFICATION REST ROUTES
319 with rmap.submapper(path_prefix=ADMIN_PREFIX,
319 with rmap.submapper(path_prefix=ADMIN_PREFIX,
320 controller='admin/notifications') as m:
320 controller='admin/notifications') as m:
321 m.connect("notifications", "/notifications",
321 m.connect("notifications", "/notifications",
322 action="create", conditions=dict(method=["POST"]))
322 action="create", conditions=dict(method=["POST"]))
323 m.connect("notifications", "/notifications",
323 m.connect("notifications", "/notifications",
324 action="index", conditions=dict(method=["GET"]))
324 action="index", conditions=dict(method=["GET"]))
325 m.connect("notifications_mark_all_read", "/notifications/mark_all_read",
325 m.connect("notifications_mark_all_read", "/notifications/mark_all_read",
326 action="mark_all_read", conditions=dict(method=["GET"]))
326 action="mark_all_read", conditions=dict(method=["GET"]))
327 m.connect("formatted_notifications", "/notifications.{format}",
327 m.connect("formatted_notifications", "/notifications.{format}",
328 action="index", conditions=dict(method=["GET"]))
328 action="index", conditions=dict(method=["GET"]))
329 m.connect("new_notification", "/notifications/new",
329 m.connect("new_notification", "/notifications/new",
330 action="new", conditions=dict(method=["GET"]))
330 action="new", conditions=dict(method=["GET"]))
331 m.connect("formatted_new_notification", "/notifications/new.{format}",
331 m.connect("formatted_new_notification", "/notifications/new.{format}",
332 action="new", conditions=dict(method=["GET"]))
332 action="new", conditions=dict(method=["GET"]))
333 m.connect("/notification/{notification_id}",
333 m.connect("/notification/{notification_id}",
334 action="update", conditions=dict(method=["PUT"]))
334 action="update", conditions=dict(method=["PUT"]))
335 m.connect("/notification/{notification_id}",
335 m.connect("/notification/{notification_id}",
336 action="delete", conditions=dict(method=["DELETE"]))
336 action="delete", conditions=dict(method=["DELETE"]))
337 m.connect("edit_notification", "/notification/{notification_id}/edit",
337 m.connect("edit_notification", "/notification/{notification_id}/edit",
338 action="edit", conditions=dict(method=["GET"]))
338 action="edit", conditions=dict(method=["GET"]))
339 m.connect("formatted_edit_notification",
339 m.connect("formatted_edit_notification",
340 "/notification/{notification_id}.{format}/edit",
340 "/notification/{notification_id}.{format}/edit",
341 action="edit", conditions=dict(method=["GET"]))
341 action="edit", conditions=dict(method=["GET"]))
342 m.connect("notification", "/notification/{notification_id}",
342 m.connect("notification", "/notification/{notification_id}",
343 action="show", conditions=dict(method=["GET"]))
343 action="show", conditions=dict(method=["GET"]))
344 m.connect("formatted_notification", "/notifications/{notification_id}.{format}",
344 m.connect("formatted_notification", "/notifications/{notification_id}.{format}",
345 action="show", conditions=dict(method=["GET"]))
345 action="show", conditions=dict(method=["GET"]))
346
346
347 #ADMIN MAIN PAGES
347 #ADMIN MAIN PAGES
348 with rmap.submapper(path_prefix=ADMIN_PREFIX,
348 with rmap.submapper(path_prefix=ADMIN_PREFIX,
349 controller='admin/admin') as m:
349 controller='admin/admin') as m:
350 m.connect('admin_home', '', action='index')
350 m.connect('admin_home', '', action='index')
351 m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}',
351 m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}',
352 action='add_repo')
352 action='add_repo')
353
353
354 #==========================================================================
354 #==========================================================================
355 # API V2
355 # API V2
356 #==========================================================================
356 #==========================================================================
357 with rmap.submapper(path_prefix=ADMIN_PREFIX,
357 with rmap.submapper(path_prefix=ADMIN_PREFIX,
358 controller='api/api') as m:
358 controller='api/api') as m:
359 m.connect('api', '/api')
359 m.connect('api', '/api')
360
360
361 #USER JOURNAL
361 #USER JOURNAL
362 rmap.connect('journal_my_repos', '%s/journal_my_repos' % ADMIN_PREFIX,
363 controller='journal', action='index_my_repos')
364 rmap.connect('journal', '%s/journal' % ADMIN_PREFIX,
362 rmap.connect('journal', '%s/journal' % ADMIN_PREFIX,
365 controller='journal', action='index')
363 controller='journal', action='index')
366 rmap.connect('journal_rss', '%s/journal/rss' % ADMIN_PREFIX,
364 rmap.connect('journal_rss', '%s/journal/rss' % ADMIN_PREFIX,
367 controller='journal', action='journal_rss')
365 controller='journal', action='journal_rss')
368 rmap.connect('journal_atom', '%s/journal/atom' % ADMIN_PREFIX,
366 rmap.connect('journal_atom', '%s/journal/atom' % ADMIN_PREFIX,
369 controller='journal', action='journal_atom')
367 controller='journal', action='journal_atom')
370
368
371 rmap.connect('public_journal', '%s/public_journal' % ADMIN_PREFIX,
369 rmap.connect('public_journal', '%s/public_journal' % ADMIN_PREFIX,
372 controller='journal', action="public_journal")
370 controller='journal', action="public_journal")
373
371
374 rmap.connect('public_journal_rss', '%s/public_journal/rss' % ADMIN_PREFIX,
372 rmap.connect('public_journal_rss', '%s/public_journal/rss' % ADMIN_PREFIX,
375 controller='journal', action="public_journal_rss")
373 controller='journal', action="public_journal_rss")
376
374
377 rmap.connect('public_journal_rss_old', '%s/public_journal_rss' % ADMIN_PREFIX,
375 rmap.connect('public_journal_rss_old', '%s/public_journal_rss' % ADMIN_PREFIX,
378 controller='journal', action="public_journal_rss")
376 controller='journal', action="public_journal_rss")
379
377
380 rmap.connect('public_journal_atom',
378 rmap.connect('public_journal_atom',
381 '%s/public_journal/atom' % ADMIN_PREFIX, controller='journal',
379 '%s/public_journal/atom' % ADMIN_PREFIX, controller='journal',
382 action="public_journal_atom")
380 action="public_journal_atom")
383
381
384 rmap.connect('public_journal_atom_old',
382 rmap.connect('public_journal_atom_old',
385 '%s/public_journal_atom' % ADMIN_PREFIX, controller='journal',
383 '%s/public_journal_atom' % ADMIN_PREFIX, controller='journal',
386 action="public_journal_atom")
384 action="public_journal_atom")
387
385
388 rmap.connect('toggle_following', '%s/toggle_following' % ADMIN_PREFIX,
386 rmap.connect('toggle_following', '%s/toggle_following' % ADMIN_PREFIX,
389 controller='journal', action='toggle_following',
387 controller='journal', action='toggle_following',
390 conditions=dict(method=["POST"]))
388 conditions=dict(method=["POST"]))
391
389
392 #SEARCH
390 #SEARCH
393 rmap.connect('search', '%s/search' % ADMIN_PREFIX, controller='search',)
391 rmap.connect('search', '%s/search' % ADMIN_PREFIX, controller='search',)
394 rmap.connect('search_repo', '%s/search/{search_repo:.*}' % ADMIN_PREFIX,
392 rmap.connect('search_repo', '%s/search/{search_repo:.*}' % ADMIN_PREFIX,
395 controller='search')
393 controller='search')
396
394
397 #LOGIN/LOGOUT/REGISTER/SIGN IN
395 #LOGIN/LOGOUT/REGISTER/SIGN IN
398 rmap.connect('login_home', '%s/login' % ADMIN_PREFIX, controller='login')
396 rmap.connect('login_home', '%s/login' % ADMIN_PREFIX, controller='login')
399 rmap.connect('logout_home', '%s/logout' % ADMIN_PREFIX, controller='login',
397 rmap.connect('logout_home', '%s/logout' % ADMIN_PREFIX, controller='login',
400 action='logout')
398 action='logout')
401
399
402 rmap.connect('register', '%s/register' % ADMIN_PREFIX, controller='login',
400 rmap.connect('register', '%s/register' % ADMIN_PREFIX, controller='login',
403 action='register')
401 action='register')
404
402
405 rmap.connect('reset_password', '%s/password_reset' % ADMIN_PREFIX,
403 rmap.connect('reset_password', '%s/password_reset' % ADMIN_PREFIX,
406 controller='login', action='password_reset')
404 controller='login', action='password_reset')
407
405
408 rmap.connect('reset_password_confirmation',
406 rmap.connect('reset_password_confirmation',
409 '%s/password_reset_confirmation' % ADMIN_PREFIX,
407 '%s/password_reset_confirmation' % ADMIN_PREFIX,
410 controller='login', action='password_reset_confirmation')
408 controller='login', action='password_reset_confirmation')
411
409
412 #FEEDS
410 #FEEDS
413 rmap.connect('rss_feed_home', '/{repo_name:.*?}/feed/rss',
411 rmap.connect('rss_feed_home', '/{repo_name:.*?}/feed/rss',
414 controller='feed', action='rss',
412 controller='feed', action='rss',
415 conditions=dict(function=check_repo))
413 conditions=dict(function=check_repo))
416
414
417 rmap.connect('atom_feed_home', '/{repo_name:.*?}/feed/atom',
415 rmap.connect('atom_feed_home', '/{repo_name:.*?}/feed/atom',
418 controller='feed', action='atom',
416 controller='feed', action='atom',
419 conditions=dict(function=check_repo))
417 conditions=dict(function=check_repo))
420
418
421 #==========================================================================
419 #==========================================================================
422 # REPOSITORY ROUTES
420 # REPOSITORY ROUTES
423 #==========================================================================
421 #==========================================================================
424 rmap.connect('summary_home', '/{repo_name:.*?}',
422 rmap.connect('summary_home', '/{repo_name:.*?}',
425 controller='summary',
423 controller='summary',
426 conditions=dict(function=check_repo))
424 conditions=dict(function=check_repo))
427
425
428 rmap.connect('repos_group_home', '/{group_name:.*}',
426 rmap.connect('repos_group_home', '/{group_name:.*}',
429 controller='admin/repos_groups', action="show_by_name",
427 controller='admin/repos_groups', action="show_by_name",
430 conditions=dict(function=check_group))
428 conditions=dict(function=check_group))
431
429
432 rmap.connect('changeset_home', '/{repo_name:.*?}/changeset/{revision}',
430 rmap.connect('changeset_home', '/{repo_name:.*?}/changeset/{revision}',
433 controller='changeset', revision='tip',
431 controller='changeset', revision='tip',
434 conditions=dict(function=check_repo))
432 conditions=dict(function=check_repo))
435
433
436 #still working url for backward compat.
434 #still working url for backward compat.
437 rmap.connect('raw_changeset_home_depraced',
435 rmap.connect('raw_changeset_home_depraced',
438 '/{repo_name:.*?}/raw-changeset/{revision}',
436 '/{repo_name:.*?}/raw-changeset/{revision}',
439 controller='changeset', action='changeset_raw',
437 controller='changeset', action='changeset_raw',
440 revision='tip', conditions=dict(function=check_repo))
438 revision='tip', conditions=dict(function=check_repo))
441
439
442 ## new URLs
440 ## new URLs
443 rmap.connect('changeset_raw_home',
441 rmap.connect('changeset_raw_home',
444 '/{repo_name:.*?}/changeset-diff/{revision}',
442 '/{repo_name:.*?}/changeset-diff/{revision}',
445 controller='changeset', action='changeset_raw',
443 controller='changeset', action='changeset_raw',
446 revision='tip', conditions=dict(function=check_repo))
444 revision='tip', conditions=dict(function=check_repo))
447
445
448 rmap.connect('changeset_patch_home',
446 rmap.connect('changeset_patch_home',
449 '/{repo_name:.*?}/changeset-patch/{revision}',
447 '/{repo_name:.*?}/changeset-patch/{revision}',
450 controller='changeset', action='changeset_patch',
448 controller='changeset', action='changeset_patch',
451 revision='tip', conditions=dict(function=check_repo))
449 revision='tip', conditions=dict(function=check_repo))
452
450
453 rmap.connect('changeset_download_home',
451 rmap.connect('changeset_download_home',
454 '/{repo_name:.*?}/changeset-download/{revision}',
452 '/{repo_name:.*?}/changeset-download/{revision}',
455 controller='changeset', action='changeset_download',
453 controller='changeset', action='changeset_download',
456 revision='tip', conditions=dict(function=check_repo))
454 revision='tip', conditions=dict(function=check_repo))
457
455
458 rmap.connect('changeset_comment',
456 rmap.connect('changeset_comment',
459 '/{repo_name:.*?}/changeset/{revision}/comment',
457 '/{repo_name:.*?}/changeset/{revision}/comment',
460 controller='changeset', revision='tip', action='comment',
458 controller='changeset', revision='tip', action='comment',
461 conditions=dict(function=check_repo))
459 conditions=dict(function=check_repo))
462
460
463 rmap.connect('changeset_comment_delete',
461 rmap.connect('changeset_comment_delete',
464 '/{repo_name:.*?}/changeset/comment/{comment_id}/delete',
462 '/{repo_name:.*?}/changeset/comment/{comment_id}/delete',
465 controller='changeset', action='delete_comment',
463 controller='changeset', action='delete_comment',
466 conditions=dict(function=check_repo, method=["DELETE"]))
464 conditions=dict(function=check_repo, method=["DELETE"]))
467
465
468 rmap.connect('changeset_info', '/changeset_info/{repo_name:.*?}/{revision}',
466 rmap.connect('changeset_info', '/changeset_info/{repo_name:.*?}/{revision}',
469 controller='changeset', action='changeset_info')
467 controller='changeset', action='changeset_info')
470
468
471 rmap.connect('compare_url',
469 rmap.connect('compare_url',
472 '/{repo_name:.*?}/compare/{org_ref_type}@{org_ref:.*?}...{other_ref_type}@{other_ref:.*?}',
470 '/{repo_name:.*?}/compare/{org_ref_type}@{org_ref:.*?}...{other_ref_type}@{other_ref:.*?}',
473 controller='compare', action='index',
471 controller='compare', action='index',
474 conditions=dict(function=check_repo),
472 conditions=dict(function=check_repo),
475 requirements=dict(
473 requirements=dict(
476 org_ref_type='(branch|book|tag|rev|org_ref_type)',
474 org_ref_type='(branch|book|tag|rev|org_ref_type)',
477 other_ref_type='(branch|book|tag|rev|other_ref_type)')
475 other_ref_type='(branch|book|tag|rev|other_ref_type)')
478 )
476 )
479
477
480 rmap.connect('pullrequest_home',
478 rmap.connect('pullrequest_home',
481 '/{repo_name:.*?}/pull-request/new', controller='pullrequests',
479 '/{repo_name:.*?}/pull-request/new', controller='pullrequests',
482 action='index', conditions=dict(function=check_repo,
480 action='index', conditions=dict(function=check_repo,
483 method=["GET"]))
481 method=["GET"]))
484
482
485 rmap.connect('pullrequest',
483 rmap.connect('pullrequest',
486 '/{repo_name:.*?}/pull-request/new', controller='pullrequests',
484 '/{repo_name:.*?}/pull-request/new', controller='pullrequests',
487 action='create', conditions=dict(function=check_repo,
485 action='create', conditions=dict(function=check_repo,
488 method=["POST"]))
486 method=["POST"]))
489
487
490 rmap.connect('pullrequest_show',
488 rmap.connect('pullrequest_show',
491 '/{repo_name:.*?}/pull-request/{pull_request_id}',
489 '/{repo_name:.*?}/pull-request/{pull_request_id}',
492 controller='pullrequests',
490 controller='pullrequests',
493 action='show', conditions=dict(function=check_repo,
491 action='show', conditions=dict(function=check_repo,
494 method=["GET"]))
492 method=["GET"]))
495 rmap.connect('pullrequest_update',
493 rmap.connect('pullrequest_update',
496 '/{repo_name:.*?}/pull-request/{pull_request_id}',
494 '/{repo_name:.*?}/pull-request/{pull_request_id}',
497 controller='pullrequests',
495 controller='pullrequests',
498 action='update', conditions=dict(function=check_repo,
496 action='update', conditions=dict(function=check_repo,
499 method=["PUT"]))
497 method=["PUT"]))
500 rmap.connect('pullrequest_delete',
498 rmap.connect('pullrequest_delete',
501 '/{repo_name:.*?}/pull-request/{pull_request_id}',
499 '/{repo_name:.*?}/pull-request/{pull_request_id}',
502 controller='pullrequests',
500 controller='pullrequests',
503 action='delete', conditions=dict(function=check_repo,
501 action='delete', conditions=dict(function=check_repo,
504 method=["DELETE"]))
502 method=["DELETE"]))
505
503
506 rmap.connect('pullrequest_show_all',
504 rmap.connect('pullrequest_show_all',
507 '/{repo_name:.*?}/pull-request',
505 '/{repo_name:.*?}/pull-request',
508 controller='pullrequests',
506 controller='pullrequests',
509 action='show_all', conditions=dict(function=check_repo,
507 action='show_all', conditions=dict(function=check_repo,
510 method=["GET"]))
508 method=["GET"]))
511
509
512 rmap.connect('pullrequest_comment',
510 rmap.connect('pullrequest_comment',
513 '/{repo_name:.*?}/pull-request-comment/{pull_request_id}',
511 '/{repo_name:.*?}/pull-request-comment/{pull_request_id}',
514 controller='pullrequests',
512 controller='pullrequests',
515 action='comment', conditions=dict(function=check_repo,
513 action='comment', conditions=dict(function=check_repo,
516 method=["POST"]))
514 method=["POST"]))
517
515
518 rmap.connect('pullrequest_comment_delete',
516 rmap.connect('pullrequest_comment_delete',
519 '/{repo_name:.*?}/pull-request-comment/{comment_id}/delete',
517 '/{repo_name:.*?}/pull-request-comment/{comment_id}/delete',
520 controller='pullrequests', action='delete_comment',
518 controller='pullrequests', action='delete_comment',
521 conditions=dict(function=check_repo, method=["DELETE"]))
519 conditions=dict(function=check_repo, method=["DELETE"]))
522
520
523 rmap.connect('summary_home', '/{repo_name:.*?}/summary',
521 rmap.connect('summary_home', '/{repo_name:.*?}/summary',
524 controller='summary', conditions=dict(function=check_repo))
522 controller='summary', conditions=dict(function=check_repo))
525
523
526 rmap.connect('shortlog_home', '/{repo_name:.*?}/shortlog',
524 rmap.connect('shortlog_home', '/{repo_name:.*?}/shortlog',
527 controller='shortlog', conditions=dict(function=check_repo))
525 controller='shortlog', conditions=dict(function=check_repo))
528
526
529 rmap.connect('shortlog_file_home', '/{repo_name:.*?}/shortlog/{revision}/{f_path:.*}',
527 rmap.connect('shortlog_file_home', '/{repo_name:.*?}/shortlog/{revision}/{f_path:.*}',
530 controller='shortlog', f_path=None,
528 controller='shortlog', f_path=None,
531 conditions=dict(function=check_repo))
529 conditions=dict(function=check_repo))
532
530
533 rmap.connect('branches_home', '/{repo_name:.*?}/branches',
531 rmap.connect('branches_home', '/{repo_name:.*?}/branches',
534 controller='branches', conditions=dict(function=check_repo))
532 controller='branches', conditions=dict(function=check_repo))
535
533
536 rmap.connect('tags_home', '/{repo_name:.*?}/tags',
534 rmap.connect('tags_home', '/{repo_name:.*?}/tags',
537 controller='tags', conditions=dict(function=check_repo))
535 controller='tags', conditions=dict(function=check_repo))
538
536
539 rmap.connect('bookmarks_home', '/{repo_name:.*?}/bookmarks',
537 rmap.connect('bookmarks_home', '/{repo_name:.*?}/bookmarks',
540 controller='bookmarks', conditions=dict(function=check_repo))
538 controller='bookmarks', conditions=dict(function=check_repo))
541
539
542 rmap.connect('changelog_home', '/{repo_name:.*?}/changelog',
540 rmap.connect('changelog_home', '/{repo_name:.*?}/changelog',
543 controller='changelog', conditions=dict(function=check_repo))
541 controller='changelog', conditions=dict(function=check_repo))
544
542
545 rmap.connect('changelog_details', '/{repo_name:.*?}/changelog_details/{cs}',
543 rmap.connect('changelog_details', '/{repo_name:.*?}/changelog_details/{cs}',
546 controller='changelog', action='changelog_details',
544 controller='changelog', action='changelog_details',
547 conditions=dict(function=check_repo))
545 conditions=dict(function=check_repo))
548
546
549 rmap.connect('files_home', '/{repo_name:.*?}/files/{revision}/{f_path:.*}',
547 rmap.connect('files_home', '/{repo_name:.*?}/files/{revision}/{f_path:.*}',
550 controller='files', revision='tip', f_path='',
548 controller='files', revision='tip', f_path='',
551 conditions=dict(function=check_repo))
549 conditions=dict(function=check_repo))
552
550
553 rmap.connect('files_history_home',
551 rmap.connect('files_history_home',
554 '/{repo_name:.*?}/history/{revision}/{f_path:.*}',
552 '/{repo_name:.*?}/history/{revision}/{f_path:.*}',
555 controller='files', action='history', revision='tip', f_path='',
553 controller='files', action='history', revision='tip', f_path='',
556 conditions=dict(function=check_repo))
554 conditions=dict(function=check_repo))
557
555
558 rmap.connect('files_diff_home', '/{repo_name:.*?}/diff/{f_path:.*}',
556 rmap.connect('files_diff_home', '/{repo_name:.*?}/diff/{f_path:.*}',
559 controller='files', action='diff', revision='tip', f_path='',
557 controller='files', action='diff', revision='tip', f_path='',
560 conditions=dict(function=check_repo))
558 conditions=dict(function=check_repo))
561
559
562 rmap.connect('files_rawfile_home',
560 rmap.connect('files_rawfile_home',
563 '/{repo_name:.*?}/rawfile/{revision}/{f_path:.*}',
561 '/{repo_name:.*?}/rawfile/{revision}/{f_path:.*}',
564 controller='files', action='rawfile', revision='tip',
562 controller='files', action='rawfile', revision='tip',
565 f_path='', conditions=dict(function=check_repo))
563 f_path='', conditions=dict(function=check_repo))
566
564
567 rmap.connect('files_raw_home',
565 rmap.connect('files_raw_home',
568 '/{repo_name:.*?}/raw/{revision}/{f_path:.*}',
566 '/{repo_name:.*?}/raw/{revision}/{f_path:.*}',
569 controller='files', action='raw', revision='tip', f_path='',
567 controller='files', action='raw', revision='tip', f_path='',
570 conditions=dict(function=check_repo))
568 conditions=dict(function=check_repo))
571
569
572 rmap.connect('files_annotate_home',
570 rmap.connect('files_annotate_home',
573 '/{repo_name:.*?}/annotate/{revision}/{f_path:.*}',
571 '/{repo_name:.*?}/annotate/{revision}/{f_path:.*}',
574 controller='files', action='index', revision='tip',
572 controller='files', action='index', revision='tip',
575 f_path='', annotate=True, conditions=dict(function=check_repo))
573 f_path='', annotate=True, conditions=dict(function=check_repo))
576
574
577 rmap.connect('files_edit_home',
575 rmap.connect('files_edit_home',
578 '/{repo_name:.*?}/edit/{revision}/{f_path:.*}',
576 '/{repo_name:.*?}/edit/{revision}/{f_path:.*}',
579 controller='files', action='edit', revision='tip',
577 controller='files', action='edit', revision='tip',
580 f_path='', conditions=dict(function=check_repo))
578 f_path='', conditions=dict(function=check_repo))
581
579
582 rmap.connect('files_add_home',
580 rmap.connect('files_add_home',
583 '/{repo_name:.*?}/add/{revision}/{f_path:.*}',
581 '/{repo_name:.*?}/add/{revision}/{f_path:.*}',
584 controller='files', action='add', revision='tip',
582 controller='files', action='add', revision='tip',
585 f_path='', conditions=dict(function=check_repo))
583 f_path='', conditions=dict(function=check_repo))
586
584
587 rmap.connect('files_archive_home', '/{repo_name:.*?}/archive/{fname}',
585 rmap.connect('files_archive_home', '/{repo_name:.*?}/archive/{fname}',
588 controller='files', action='archivefile',
586 controller='files', action='archivefile',
589 conditions=dict(function=check_repo))
587 conditions=dict(function=check_repo))
590
588
591 rmap.connect('files_nodelist_home',
589 rmap.connect('files_nodelist_home',
592 '/{repo_name:.*?}/nodelist/{revision}/{f_path:.*}',
590 '/{repo_name:.*?}/nodelist/{revision}/{f_path:.*}',
593 controller='files', action='nodelist',
591 controller='files', action='nodelist',
594 conditions=dict(function=check_repo))
592 conditions=dict(function=check_repo))
595
593
596 rmap.connect('repo_settings_delete', '/{repo_name:.*?}/settings',
594 rmap.connect('repo_settings_delete', '/{repo_name:.*?}/settings',
597 controller='settings', action="delete",
595 controller='settings', action="delete",
598 conditions=dict(method=["DELETE"], function=check_repo))
596 conditions=dict(method=["DELETE"], function=check_repo))
599
597
600 rmap.connect('repo_settings_update', '/{repo_name:.*?}/settings',
598 rmap.connect('repo_settings_update', '/{repo_name:.*?}/settings',
601 controller='settings', action="update",
599 controller='settings', action="update",
602 conditions=dict(method=["PUT"], function=check_repo))
600 conditions=dict(method=["PUT"], function=check_repo))
603
601
604 rmap.connect('repo_settings_home', '/{repo_name:.*?}/settings',
602 rmap.connect('repo_settings_home', '/{repo_name:.*?}/settings',
605 controller='settings', action='index',
603 controller='settings', action='index',
606 conditions=dict(function=check_repo))
604 conditions=dict(function=check_repo))
607
605
608 rmap.connect('toggle_locking', "/{repo_name:.*?}/locking_toggle",
606 rmap.connect('toggle_locking', "/{repo_name:.*?}/locking_toggle",
609 controller='settings', action="toggle_locking",
607 controller='settings', action="toggle_locking",
610 conditions=dict(method=["GET"], function=check_repo))
608 conditions=dict(method=["GET"], function=check_repo))
611
609
612 rmap.connect('repo_fork_create_home', '/{repo_name:.*?}/fork',
610 rmap.connect('repo_fork_create_home', '/{repo_name:.*?}/fork',
613 controller='forks', action='fork_create',
611 controller='forks', action='fork_create',
614 conditions=dict(function=check_repo, method=["POST"]))
612 conditions=dict(function=check_repo, method=["POST"]))
615
613
616 rmap.connect('repo_fork_home', '/{repo_name:.*?}/fork',
614 rmap.connect('repo_fork_home', '/{repo_name:.*?}/fork',
617 controller='forks', action='fork',
615 controller='forks', action='fork',
618 conditions=dict(function=check_repo))
616 conditions=dict(function=check_repo))
619
617
620 rmap.connect('repo_forks_home', '/{repo_name:.*?}/forks',
618 rmap.connect('repo_forks_home', '/{repo_name:.*?}/forks',
621 controller='forks', action='forks',
619 controller='forks', action='forks',
622 conditions=dict(function=check_repo))
620 conditions=dict(function=check_repo))
623
621
624 rmap.connect('repo_followers_home', '/{repo_name:.*?}/followers',
622 rmap.connect('repo_followers_home', '/{repo_name:.*?}/followers',
625 controller='followers', action='followers',
623 controller='followers', action='followers',
626 conditions=dict(function=check_repo))
624 conditions=dict(function=check_repo))
627
625
628 return rmap
626 return rmap
@@ -1,510 +1,480 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.admin.repos
3 rhodecode.controllers.admin.repos
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 Repositories controller for RhodeCode
6 Repositories controller for RhodeCode
7
7
8 :created_on: Apr 7, 2010
8 :created_on: Apr 7, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26 import logging
26 import logging
27 import traceback
27 import traceback
28 import formencode
28 import formencode
29 from formencode import htmlfill
29 from formencode import htmlfill
30
30
31 from webob.exc import HTTPInternalServerError
31 from webob.exc import HTTPInternalServerError
32 from pylons import request, session, tmpl_context as c, url
32 from pylons import request, session, tmpl_context as c, url
33 from pylons.controllers.util import redirect
33 from pylons.controllers.util import redirect
34 from pylons.i18n.translation import _
34 from pylons.i18n.translation import _
35 from sqlalchemy.exc import IntegrityError
35 from sqlalchemy.exc import IntegrityError
36
36
37 import rhodecode
37 import rhodecode
38 from rhodecode.lib import helpers as h
38 from rhodecode.lib import helpers as h
39 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \
39 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \
40 HasPermissionAnyDecorator, HasRepoPermissionAllDecorator
40 HasPermissionAnyDecorator, HasRepoPermissionAllDecorator
41 from rhodecode.lib.base import BaseController, render
41 from rhodecode.lib.base import BaseController, render
42 from rhodecode.lib.utils import invalidate_cache, action_logger, repo_name_slug
42 from rhodecode.lib.utils import invalidate_cache, action_logger, repo_name_slug
43 from rhodecode.lib.helpers import get_token
43 from rhodecode.lib.helpers import get_token
44 from rhodecode.model.meta import Session
44 from rhodecode.model.meta import Session
45 from rhodecode.model.db import User, Repository, UserFollowing, RepoGroup,\
45 from rhodecode.model.db import User, Repository, UserFollowing, RepoGroup,\
46 RhodeCodeSetting
46 RhodeCodeSetting
47 from rhodecode.model.forms import RepoForm
47 from rhodecode.model.forms import RepoForm
48 from rhodecode.model.scm import ScmModel
48 from rhodecode.model.scm import ScmModel
49 from rhodecode.model.repo import RepoModel
49 from rhodecode.model.repo import RepoModel
50 from rhodecode.lib.compat import json
50 from rhodecode.lib.compat import json
51 from sqlalchemy.sql.expression import func
51 from sqlalchemy.sql.expression import func
52
52
53 log = logging.getLogger(__name__)
53 log = logging.getLogger(__name__)
54
54
55
55
56 class ReposController(BaseController):
56 class ReposController(BaseController):
57 """
57 """
58 REST Controller styled on the Atom Publishing Protocol"""
58 REST Controller styled on the Atom Publishing Protocol"""
59 # To properly map this controller, ensure your config/routing.py
59 # To properly map this controller, ensure your config/routing.py
60 # file has a resource setup:
60 # file has a resource setup:
61 # map.resource('repo', 'repos')
61 # map.resource('repo', 'repos')
62
62
63 @LoginRequired()
63 @LoginRequired()
64 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
64 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
65 def __before__(self):
65 def __before__(self):
66 c.admin_user = session.get('admin_user')
66 c.admin_user = session.get('admin_user')
67 c.admin_username = session.get('admin_username')
67 c.admin_username = session.get('admin_username')
68 super(ReposController, self).__before__()
68 super(ReposController, self).__before__()
69
69
70 def __load_defaults(self):
70 def __load_defaults(self):
71 c.repo_groups = RepoGroup.groups_choices(check_perms=True)
71 c.repo_groups = RepoGroup.groups_choices(check_perms=True)
72 c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups)
72 c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups)
73
73
74 repo_model = RepoModel()
74 repo_model = RepoModel()
75 c.users_array = repo_model.get_users_js()
75 c.users_array = repo_model.get_users_js()
76 c.users_groups_array = repo_model.get_users_groups_js()
76 c.users_groups_array = repo_model.get_users_groups_js()
77 choices, c.landing_revs = ScmModel().get_repo_landing_revs()
77 choices, c.landing_revs = ScmModel().get_repo_landing_revs()
78 c.landing_revs_choices = choices
78 c.landing_revs_choices = choices
79
79
80 def __load_data(self, repo_name=None):
80 def __load_data(self, repo_name=None):
81 """
81 """
82 Load defaults settings for edit, and update
82 Load defaults settings for edit, and update
83
83
84 :param repo_name:
84 :param repo_name:
85 """
85 """
86 self.__load_defaults()
86 self.__load_defaults()
87
87
88 c.repo_info = db_repo = Repository.get_by_repo_name(repo_name)
88 c.repo_info = db_repo = Repository.get_by_repo_name(repo_name)
89 repo = db_repo.scm_instance
89 repo = db_repo.scm_instance
90
90
91 if c.repo_info is None:
91 if c.repo_info is None:
92 h.not_mapped_error(repo_name)
92 h.not_mapped_error(repo_name)
93 return redirect(url('repos'))
93 return redirect(url('repos'))
94
94
95 ##override defaults for exact repo info here git/hg etc
95 ##override defaults for exact repo info here git/hg etc
96 choices, c.landing_revs = ScmModel().get_repo_landing_revs(c.repo_info)
96 choices, c.landing_revs = ScmModel().get_repo_landing_revs(c.repo_info)
97 c.landing_revs_choices = choices
97 c.landing_revs_choices = choices
98
98
99 c.default_user_id = User.get_by_username('default').user_id
99 c.default_user_id = User.get_by_username('default').user_id
100 c.in_public_journal = UserFollowing.query()\
100 c.in_public_journal = UserFollowing.query()\
101 .filter(UserFollowing.user_id == c.default_user_id)\
101 .filter(UserFollowing.user_id == c.default_user_id)\
102 .filter(UserFollowing.follows_repository == c.repo_info).scalar()
102 .filter(UserFollowing.follows_repository == c.repo_info).scalar()
103
103
104 if c.repo_info.stats:
104 if c.repo_info.stats:
105 # this is on what revision we ended up so we add +1 for count
105 # this is on what revision we ended up so we add +1 for count
106 last_rev = c.repo_info.stats.stat_on_revision + 1
106 last_rev = c.repo_info.stats.stat_on_revision + 1
107 else:
107 else:
108 last_rev = 0
108 last_rev = 0
109 c.stats_revision = last_rev
109 c.stats_revision = last_rev
110
110
111 c.repo_last_rev = repo.count() if repo.revisions else 0
111 c.repo_last_rev = repo.count() if repo.revisions else 0
112
112
113 if last_rev == 0 or c.repo_last_rev == 0:
113 if last_rev == 0 or c.repo_last_rev == 0:
114 c.stats_percentage = 0
114 c.stats_percentage = 0
115 else:
115 else:
116 c.stats_percentage = '%.2f' % ((float((last_rev)) /
116 c.stats_percentage = '%.2f' % ((float((last_rev)) /
117 c.repo_last_rev) * 100)
117 c.repo_last_rev) * 100)
118
118
119 defaults = RepoModel()._get_defaults(repo_name)
119 defaults = RepoModel()._get_defaults(repo_name)
120
120
121 c.repos_list = [('', _('--REMOVE FORK--'))]
121 c.repos_list = [('', _('--REMOVE FORK--'))]
122 c.repos_list += [(x.repo_id, x.repo_name) for x in
122 c.repos_list += [(x.repo_id, x.repo_name) for x in
123 Repository.query().order_by(Repository.repo_name).all()
123 Repository.query().order_by(Repository.repo_name).all()
124 if x.repo_id != c.repo_info.repo_id]
124 if x.repo_id != c.repo_info.repo_id]
125
125
126 defaults['id_fork_of'] = db_repo.fork.repo_id if db_repo.fork else ''
126 defaults['id_fork_of'] = db_repo.fork.repo_id if db_repo.fork else ''
127 return defaults
127 return defaults
128
128
129 @HasPermissionAllDecorator('hg.admin')
129 @HasPermissionAllDecorator('hg.admin')
130 def index(self, format='html'):
130 def index(self, format='html'):
131 """GET /repos: All items in the collection"""
131 """GET /repos: All items in the collection"""
132 # url('repos')
132 # url('repos')
133
133
134 c.repos_list = Repository.query()\
134 c.repos_list = Repository.query()\
135 .order_by(func.lower(Repository.repo_name))\
135 .order_by(func.lower(Repository.repo_name))\
136 .all()
136 .all()
137
137
138 repos_data = []
138 repos_data = RepoModel().get_repos_as_dict(repos_list=c.repos_list,
139 total_records = len(c.repos_list)
139 admin=True)
140
140 #json used to render the grid
141 _tmpl_lookup = rhodecode.CONFIG['pylons.app_globals'].mako_lookup
141 c.data = json.dumps(repos_data)
142 template = _tmpl_lookup.get_template('data_table/_dt_elements.html')
143
144 quick_menu = lambda repo_name: (template.get_def("quick_menu")
145 .render(repo_name, _=_, h=h, c=c))
146 repo_lnk = lambda name, rtype, private, fork_of: (
147 template.get_def("repo_name")
148 .render(name, rtype, private, fork_of, short_name=False,
149 admin=True, _=_, h=h, c=c))
150
151 repo_actions = lambda repo_name: (template.get_def("repo_actions")
152 .render(repo_name, _=_, h=h, c=c))
153
154 for repo in c.repos_list:
155 repos_data.append({
156 "menu": quick_menu(repo.repo_name),
157 "raw_name": repo.repo_name.lower(),
158 "name": repo_lnk(repo.repo_name, repo.repo_type,
159 repo.private, repo.fork),
160 "desc": repo.description,
161 "owner": repo.user.username,
162 "action": repo_actions(repo.repo_name),
163 })
164
165 c.data = json.dumps({
166 "totalRecords": total_records,
167 "startIndex": 0,
168 "sort": "name",
169 "dir": "asc",
170 "records": repos_data
171 })
172
142
173 return render('admin/repos/repos.html')
143 return render('admin/repos/repos.html')
174
144
175 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
145 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
176 def create(self):
146 def create(self):
177 """
147 """
178 POST /repos: Create a new item"""
148 POST /repos: Create a new item"""
179 # url('repos')
149 # url('repos')
180
150
181 self.__load_defaults()
151 self.__load_defaults()
182 form_result = {}
152 form_result = {}
183 try:
153 try:
184 form_result = RepoForm(repo_groups=c.repo_groups_choices,
154 form_result = RepoForm(repo_groups=c.repo_groups_choices,
185 landing_revs=c.landing_revs_choices)()\
155 landing_revs=c.landing_revs_choices)()\
186 .to_python(dict(request.POST))
156 .to_python(dict(request.POST))
187 new_repo = RepoModel().create(form_result,
157 new_repo = RepoModel().create(form_result,
188 self.rhodecode_user.user_id)
158 self.rhodecode_user.user_id)
189 if form_result['clone_uri']:
159 if form_result['clone_uri']:
190 h.flash(_('created repository %s from %s') \
160 h.flash(_('created repository %s from %s') \
191 % (form_result['repo_name'], form_result['clone_uri']),
161 % (form_result['repo_name'], form_result['clone_uri']),
192 category='success')
162 category='success')
193 else:
163 else:
194 h.flash(_('created repository %s') % form_result['repo_name'],
164 h.flash(_('created repository %s') % form_result['repo_name'],
195 category='success')
165 category='success')
196
166
197 if request.POST.get('user_created'):
167 if request.POST.get('user_created'):
198 # created by regular non admin user
168 # created by regular non admin user
199 action_logger(self.rhodecode_user, 'user_created_repo',
169 action_logger(self.rhodecode_user, 'user_created_repo',
200 form_result['repo_name_full'], self.ip_addr,
170 form_result['repo_name_full'], self.ip_addr,
201 self.sa)
171 self.sa)
202 else:
172 else:
203 action_logger(self.rhodecode_user, 'admin_created_repo',
173 action_logger(self.rhodecode_user, 'admin_created_repo',
204 form_result['repo_name_full'], self.ip_addr,
174 form_result['repo_name_full'], self.ip_addr,
205 self.sa)
175 self.sa)
206 Session().commit()
176 Session().commit()
207 except formencode.Invalid, errors:
177 except formencode.Invalid, errors:
208
178
209 c.new_repo = errors.value['repo_name']
179 c.new_repo = errors.value['repo_name']
210
180
211 if request.POST.get('user_created'):
181 if request.POST.get('user_created'):
212 r = render('admin/repos/repo_add_create_repository.html')
182 r = render('admin/repos/repo_add_create_repository.html')
213 else:
183 else:
214 r = render('admin/repos/repo_add.html')
184 r = render('admin/repos/repo_add.html')
215
185
216 return htmlfill.render(
186 return htmlfill.render(
217 r,
187 r,
218 defaults=errors.value,
188 defaults=errors.value,
219 errors=errors.error_dict or {},
189 errors=errors.error_dict or {},
220 prefix_error=False,
190 prefix_error=False,
221 encoding="UTF-8")
191 encoding="UTF-8")
222
192
223 except Exception:
193 except Exception:
224 log.error(traceback.format_exc())
194 log.error(traceback.format_exc())
225 msg = _('error occurred during creation of repository %s') \
195 msg = _('error occurred during creation of repository %s') \
226 % form_result.get('repo_name')
196 % form_result.get('repo_name')
227 h.flash(msg, category='error')
197 h.flash(msg, category='error')
228 return redirect(url('repos'))
198 return redirect(url('repos'))
229 #redirect to our new repo !
199 #redirect to our new repo !
230 return redirect(url('summary_home', repo_name=new_repo.repo_name))
200 return redirect(url('summary_home', repo_name=new_repo.repo_name))
231
201
232 @HasPermissionAllDecorator('hg.admin')
202 @HasPermissionAllDecorator('hg.admin')
233 def new(self, format='html'):
203 def new(self, format='html'):
234 """GET /repos/new: Form to create a new item"""
204 """GET /repos/new: Form to create a new item"""
235 new_repo = request.GET.get('repo', '')
205 new_repo = request.GET.get('repo', '')
236 c.new_repo = repo_name_slug(new_repo)
206 c.new_repo = repo_name_slug(new_repo)
237 self.__load_defaults()
207 self.__load_defaults()
238 ## apply the defaults from defaults page
208 ## apply the defaults from defaults page
239 defaults = RhodeCodeSetting.get_default_repo_settings(strip_prefix=True)
209 defaults = RhodeCodeSetting.get_default_repo_settings(strip_prefix=True)
240 return htmlfill.render(
210 return htmlfill.render(
241 render('admin/repos/repo_add.html'),
211 render('admin/repos/repo_add.html'),
242 defaults=defaults,
212 defaults=defaults,
243 errors={},
213 errors={},
244 prefix_error=False,
214 prefix_error=False,
245 encoding="UTF-8"
215 encoding="UTF-8"
246 )
216 )
247
217
248 @HasPermissionAllDecorator('hg.admin')
218 @HasPermissionAllDecorator('hg.admin')
249 def update(self, repo_name):
219 def update(self, repo_name):
250 """
220 """
251 PUT /repos/repo_name: Update an existing item"""
221 PUT /repos/repo_name: Update an existing item"""
252 # Forms posted to this method should contain a hidden field:
222 # Forms posted to this method should contain a hidden field:
253 # <input type="hidden" name="_method" value="PUT" />
223 # <input type="hidden" name="_method" value="PUT" />
254 # Or using helpers:
224 # Or using helpers:
255 # h.form(url('repo', repo_name=ID),
225 # h.form(url('repo', repo_name=ID),
256 # method='put')
226 # method='put')
257 # url('repo', repo_name=ID)
227 # url('repo', repo_name=ID)
258 self.__load_defaults()
228 self.__load_defaults()
259 repo_model = RepoModel()
229 repo_model = RepoModel()
260 changed_name = repo_name
230 changed_name = repo_name
261 #override the choices with extracted revisions !
231 #override the choices with extracted revisions !
262 choices, c.landing_revs = ScmModel().get_repo_landing_revs(repo_name)
232 choices, c.landing_revs = ScmModel().get_repo_landing_revs(repo_name)
263 c.landing_revs_choices = choices
233 c.landing_revs_choices = choices
264
234
265 _form = RepoForm(edit=True, old_data={'repo_name': repo_name},
235 _form = RepoForm(edit=True, old_data={'repo_name': repo_name},
266 repo_groups=c.repo_groups_choices,
236 repo_groups=c.repo_groups_choices,
267 landing_revs=c.landing_revs_choices)()
237 landing_revs=c.landing_revs_choices)()
268 try:
238 try:
269 form_result = _form.to_python(dict(request.POST))
239 form_result = _form.to_python(dict(request.POST))
270 repo = repo_model.update(repo_name, **form_result)
240 repo = repo_model.update(repo_name, **form_result)
271 invalidate_cache('get_repo_cached_%s' % repo_name)
241 invalidate_cache('get_repo_cached_%s' % repo_name)
272 h.flash(_('Repository %s updated successfully') % repo_name,
242 h.flash(_('Repository %s updated successfully') % repo_name,
273 category='success')
243 category='success')
274 changed_name = repo.repo_name
244 changed_name = repo.repo_name
275 action_logger(self.rhodecode_user, 'admin_updated_repo',
245 action_logger(self.rhodecode_user, 'admin_updated_repo',
276 changed_name, self.ip_addr, self.sa)
246 changed_name, self.ip_addr, self.sa)
277 Session().commit()
247 Session().commit()
278 except formencode.Invalid, errors:
248 except formencode.Invalid, errors:
279 defaults = self.__load_data(repo_name)
249 defaults = self.__load_data(repo_name)
280 defaults.update(errors.value)
250 defaults.update(errors.value)
281 return htmlfill.render(
251 return htmlfill.render(
282 render('admin/repos/repo_edit.html'),
252 render('admin/repos/repo_edit.html'),
283 defaults=defaults,
253 defaults=defaults,
284 errors=errors.error_dict or {},
254 errors=errors.error_dict or {},
285 prefix_error=False,
255 prefix_error=False,
286 encoding="UTF-8")
256 encoding="UTF-8")
287
257
288 except Exception:
258 except Exception:
289 log.error(traceback.format_exc())
259 log.error(traceback.format_exc())
290 h.flash(_('error occurred during update of repository %s') \
260 h.flash(_('error occurred during update of repository %s') \
291 % repo_name, category='error')
261 % repo_name, category='error')
292 return redirect(url('edit_repo', repo_name=changed_name))
262 return redirect(url('edit_repo', repo_name=changed_name))
293
263
294 @HasPermissionAllDecorator('hg.admin')
264 @HasPermissionAllDecorator('hg.admin')
295 def delete(self, repo_name):
265 def delete(self, repo_name):
296 """
266 """
297 DELETE /repos/repo_name: Delete an existing item"""
267 DELETE /repos/repo_name: Delete an existing item"""
298 # Forms posted to this method should contain a hidden field:
268 # Forms posted to this method should contain a hidden field:
299 # <input type="hidden" name="_method" value="DELETE" />
269 # <input type="hidden" name="_method" value="DELETE" />
300 # Or using helpers:
270 # Or using helpers:
301 # h.form(url('repo', repo_name=ID),
271 # h.form(url('repo', repo_name=ID),
302 # method='delete')
272 # method='delete')
303 # url('repo', repo_name=ID)
273 # url('repo', repo_name=ID)
304
274
305 repo_model = RepoModel()
275 repo_model = RepoModel()
306 repo = repo_model.get_by_repo_name(repo_name)
276 repo = repo_model.get_by_repo_name(repo_name)
307 if not repo:
277 if not repo:
308 h.not_mapped_error(repo_name)
278 h.not_mapped_error(repo_name)
309 return redirect(url('repos'))
279 return redirect(url('repos'))
310 try:
280 try:
311 action_logger(self.rhodecode_user, 'admin_deleted_repo',
281 action_logger(self.rhodecode_user, 'admin_deleted_repo',
312 repo_name, self.ip_addr, self.sa)
282 repo_name, self.ip_addr, self.sa)
313 repo_model.delete(repo)
283 repo_model.delete(repo)
314 invalidate_cache('get_repo_cached_%s' % repo_name)
284 invalidate_cache('get_repo_cached_%s' % repo_name)
315 h.flash(_('deleted repository %s') % repo_name, category='success')
285 h.flash(_('deleted repository %s') % repo_name, category='success')
316 Session().commit()
286 Session().commit()
317 except IntegrityError, e:
287 except IntegrityError, e:
318 if e.message.find('repositories_fork_id_fkey') != -1:
288 if e.message.find('repositories_fork_id_fkey') != -1:
319 log.error(traceback.format_exc())
289 log.error(traceback.format_exc())
320 h.flash(_('Cannot delete %s it still contains attached '
290 h.flash(_('Cannot delete %s it still contains attached '
321 'forks') % repo_name,
291 'forks') % repo_name,
322 category='warning')
292 category='warning')
323 else:
293 else:
324 log.error(traceback.format_exc())
294 log.error(traceback.format_exc())
325 h.flash(_('An error occurred during '
295 h.flash(_('An error occurred during '
326 'deletion of %s') % repo_name,
296 'deletion of %s') % repo_name,
327 category='error')
297 category='error')
328
298
329 except Exception, e:
299 except Exception, e:
330 log.error(traceback.format_exc())
300 log.error(traceback.format_exc())
331 h.flash(_('An error occurred during deletion of %s') % repo_name,
301 h.flash(_('An error occurred during deletion of %s') % repo_name,
332 category='error')
302 category='error')
333
303
334 return redirect(url('repos'))
304 return redirect(url('repos'))
335
305
336 @HasRepoPermissionAllDecorator('repository.admin')
306 @HasRepoPermissionAllDecorator('repository.admin')
337 def delete_perm_user(self, repo_name):
307 def delete_perm_user(self, repo_name):
338 """
308 """
339 DELETE an existing repository permission user
309 DELETE an existing repository permission user
340
310
341 :param repo_name:
311 :param repo_name:
342 """
312 """
343 try:
313 try:
344 RepoModel().revoke_user_permission(repo=repo_name,
314 RepoModel().revoke_user_permission(repo=repo_name,
345 user=request.POST['user_id'])
315 user=request.POST['user_id'])
346 Session().commit()
316 Session().commit()
347 except Exception:
317 except Exception:
348 log.error(traceback.format_exc())
318 log.error(traceback.format_exc())
349 h.flash(_('An error occurred during deletion of repository user'),
319 h.flash(_('An error occurred during deletion of repository user'),
350 category='error')
320 category='error')
351 raise HTTPInternalServerError()
321 raise HTTPInternalServerError()
352
322
353 @HasRepoPermissionAllDecorator('repository.admin')
323 @HasRepoPermissionAllDecorator('repository.admin')
354 def delete_perm_users_group(self, repo_name):
324 def delete_perm_users_group(self, repo_name):
355 """
325 """
356 DELETE an existing repository permission users group
326 DELETE an existing repository permission users group
357
327
358 :param repo_name:
328 :param repo_name:
359 """
329 """
360
330
361 try:
331 try:
362 RepoModel().revoke_users_group_permission(
332 RepoModel().revoke_users_group_permission(
363 repo=repo_name, group_name=request.POST['users_group_id']
333 repo=repo_name, group_name=request.POST['users_group_id']
364 )
334 )
365 Session().commit()
335 Session().commit()
366 except Exception:
336 except Exception:
367 log.error(traceback.format_exc())
337 log.error(traceback.format_exc())
368 h.flash(_('An error occurred during deletion of repository'
338 h.flash(_('An error occurred during deletion of repository'
369 ' users groups'),
339 ' users groups'),
370 category='error')
340 category='error')
371 raise HTTPInternalServerError()
341 raise HTTPInternalServerError()
372
342
373 @HasPermissionAllDecorator('hg.admin')
343 @HasPermissionAllDecorator('hg.admin')
374 def repo_stats(self, repo_name):
344 def repo_stats(self, repo_name):
375 """
345 """
376 DELETE an existing repository statistics
346 DELETE an existing repository statistics
377
347
378 :param repo_name:
348 :param repo_name:
379 """
349 """
380
350
381 try:
351 try:
382 RepoModel().delete_stats(repo_name)
352 RepoModel().delete_stats(repo_name)
383 Session().commit()
353 Session().commit()
384 except Exception, e:
354 except Exception, e:
385 log.error(traceback.format_exc())
355 log.error(traceback.format_exc())
386 h.flash(_('An error occurred during deletion of repository stats'),
356 h.flash(_('An error occurred during deletion of repository stats'),
387 category='error')
357 category='error')
388 return redirect(url('edit_repo', repo_name=repo_name))
358 return redirect(url('edit_repo', repo_name=repo_name))
389
359
390 @HasPermissionAllDecorator('hg.admin')
360 @HasPermissionAllDecorator('hg.admin')
391 def repo_cache(self, repo_name):
361 def repo_cache(self, repo_name):
392 """
362 """
393 INVALIDATE existing repository cache
363 INVALIDATE existing repository cache
394
364
395 :param repo_name:
365 :param repo_name:
396 """
366 """
397
367
398 try:
368 try:
399 ScmModel().mark_for_invalidation(repo_name)
369 ScmModel().mark_for_invalidation(repo_name)
400 Session().commit()
370 Session().commit()
401 except Exception, e:
371 except Exception, e:
402 log.error(traceback.format_exc())
372 log.error(traceback.format_exc())
403 h.flash(_('An error occurred during cache invalidation'),
373 h.flash(_('An error occurred during cache invalidation'),
404 category='error')
374 category='error')
405 return redirect(url('edit_repo', repo_name=repo_name))
375 return redirect(url('edit_repo', repo_name=repo_name))
406
376
407 @HasPermissionAllDecorator('hg.admin')
377 @HasPermissionAllDecorator('hg.admin')
408 def repo_locking(self, repo_name):
378 def repo_locking(self, repo_name):
409 """
379 """
410 Unlock repository when it is locked !
380 Unlock repository when it is locked !
411
381
412 :param repo_name:
382 :param repo_name:
413 """
383 """
414
384
415 try:
385 try:
416 repo = Repository.get_by_repo_name(repo_name)
386 repo = Repository.get_by_repo_name(repo_name)
417 if request.POST.get('set_lock'):
387 if request.POST.get('set_lock'):
418 Repository.lock(repo, c.rhodecode_user.user_id)
388 Repository.lock(repo, c.rhodecode_user.user_id)
419 elif request.POST.get('set_unlock'):
389 elif request.POST.get('set_unlock'):
420 Repository.unlock(repo)
390 Repository.unlock(repo)
421 except Exception, e:
391 except Exception, e:
422 log.error(traceback.format_exc())
392 log.error(traceback.format_exc())
423 h.flash(_('An error occurred during unlocking'),
393 h.flash(_('An error occurred during unlocking'),
424 category='error')
394 category='error')
425 return redirect(url('edit_repo', repo_name=repo_name))
395 return redirect(url('edit_repo', repo_name=repo_name))
426
396
427 @HasPermissionAllDecorator('hg.admin')
397 @HasPermissionAllDecorator('hg.admin')
428 def repo_public_journal(self, repo_name):
398 def repo_public_journal(self, repo_name):
429 """
399 """
430 Set's this repository to be visible in public journal,
400 Set's this repository to be visible in public journal,
431 in other words assing default user to follow this repo
401 in other words assing default user to follow this repo
432
402
433 :param repo_name:
403 :param repo_name:
434 """
404 """
435
405
436 cur_token = request.POST.get('auth_token')
406 cur_token = request.POST.get('auth_token')
437 token = get_token()
407 token = get_token()
438 if cur_token == token:
408 if cur_token == token:
439 try:
409 try:
440 repo_id = Repository.get_by_repo_name(repo_name).repo_id
410 repo_id = Repository.get_by_repo_name(repo_name).repo_id
441 user_id = User.get_by_username('default').user_id
411 user_id = User.get_by_username('default').user_id
442 self.scm_model.toggle_following_repo(repo_id, user_id)
412 self.scm_model.toggle_following_repo(repo_id, user_id)
443 h.flash(_('Updated repository visibility in public journal'),
413 h.flash(_('Updated repository visibility in public journal'),
444 category='success')
414 category='success')
445 Session().commit()
415 Session().commit()
446 except:
416 except:
447 h.flash(_('An error occurred during setting this'
417 h.flash(_('An error occurred during setting this'
448 ' repository in public journal'),
418 ' repository in public journal'),
449 category='error')
419 category='error')
450
420
451 else:
421 else:
452 h.flash(_('Token mismatch'), category='error')
422 h.flash(_('Token mismatch'), category='error')
453 return redirect(url('edit_repo', repo_name=repo_name))
423 return redirect(url('edit_repo', repo_name=repo_name))
454
424
455 @HasPermissionAllDecorator('hg.admin')
425 @HasPermissionAllDecorator('hg.admin')
456 def repo_pull(self, repo_name):
426 def repo_pull(self, repo_name):
457 """
427 """
458 Runs task to update given repository with remote changes,
428 Runs task to update given repository with remote changes,
459 ie. make pull on remote location
429 ie. make pull on remote location
460
430
461 :param repo_name:
431 :param repo_name:
462 """
432 """
463 try:
433 try:
464 ScmModel().pull_changes(repo_name, self.rhodecode_user.username)
434 ScmModel().pull_changes(repo_name, self.rhodecode_user.username)
465 h.flash(_('Pulled from remote location'), category='success')
435 h.flash(_('Pulled from remote location'), category='success')
466 except Exception, e:
436 except Exception, e:
467 h.flash(_('An error occurred during pull from remote location'),
437 h.flash(_('An error occurred during pull from remote location'),
468 category='error')
438 category='error')
469
439
470 return redirect(url('edit_repo', repo_name=repo_name))
440 return redirect(url('edit_repo', repo_name=repo_name))
471
441
472 @HasPermissionAllDecorator('hg.admin')
442 @HasPermissionAllDecorator('hg.admin')
473 def repo_as_fork(self, repo_name):
443 def repo_as_fork(self, repo_name):
474 """
444 """
475 Mark given repository as a fork of another
445 Mark given repository as a fork of another
476
446
477 :param repo_name:
447 :param repo_name:
478 """
448 """
479 try:
449 try:
480 fork_id = request.POST.get('id_fork_of')
450 fork_id = request.POST.get('id_fork_of')
481 repo = ScmModel().mark_as_fork(repo_name, fork_id,
451 repo = ScmModel().mark_as_fork(repo_name, fork_id,
482 self.rhodecode_user.username)
452 self.rhodecode_user.username)
483 fork = repo.fork.repo_name if repo.fork else _('Nothing')
453 fork = repo.fork.repo_name if repo.fork else _('Nothing')
484 Session().commit()
454 Session().commit()
485 h.flash(_('Marked repo %s as fork of %s') % (repo_name, fork),
455 h.flash(_('Marked repo %s as fork of %s') % (repo_name, fork),
486 category='success')
456 category='success')
487 except Exception, e:
457 except Exception, e:
488 log.error(traceback.format_exc())
458 log.error(traceback.format_exc())
489 h.flash(_('An error occurred during this operation'),
459 h.flash(_('An error occurred during this operation'),
490 category='error')
460 category='error')
491
461
492 return redirect(url('edit_repo', repo_name=repo_name))
462 return redirect(url('edit_repo', repo_name=repo_name))
493
463
494 @HasPermissionAllDecorator('hg.admin')
464 @HasPermissionAllDecorator('hg.admin')
495 def show(self, repo_name, format='html'):
465 def show(self, repo_name, format='html'):
496 """GET /repos/repo_name: Show a specific item"""
466 """GET /repos/repo_name: Show a specific item"""
497 # url('repo', repo_name=ID)
467 # url('repo', repo_name=ID)
498
468
499 @HasPermissionAllDecorator('hg.admin')
469 @HasPermissionAllDecorator('hg.admin')
500 def edit(self, repo_name, format='html'):
470 def edit(self, repo_name, format='html'):
501 """GET /repos/repo_name/edit: Form to edit an existing item"""
471 """GET /repos/repo_name/edit: Form to edit an existing item"""
502 # url('edit_repo', repo_name=ID)
472 # url('edit_repo', repo_name=ID)
503 defaults = self.__load_data(repo_name)
473 defaults = self.__load_data(repo_name)
504
474
505 return htmlfill.render(
475 return htmlfill.render(
506 render('admin/repos/repo_edit.html'),
476 render('admin/repos/repo_edit.html'),
507 defaults=defaults,
477 defaults=defaults,
508 encoding="UTF-8",
478 encoding="UTF-8",
509 force_defaults=False
479 force_defaults=False
510 )
480 )
@@ -1,366 +1,330 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.admin.repos_groups
3 rhodecode.controllers.admin.repos_groups
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 Repositories groups controller for RhodeCode
6 Repositories groups controller for RhodeCode
7
7
8 :created_on: Mar 23, 2010
8 :created_on: Mar 23, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26 import logging
26 import logging
27 import traceback
27 import traceback
28 import formencode
28 import formencode
29
29
30 from formencode import htmlfill
30 from formencode import htmlfill
31
31
32 from pylons import request, tmpl_context as c, url
32 from pylons import request, tmpl_context as c, url
33 from pylons.controllers.util import redirect
33 from pylons.controllers.util import redirect
34 from pylons.i18n.translation import _
34 from pylons.i18n.translation import _
35
35
36 from sqlalchemy.exc import IntegrityError
36 from sqlalchemy.exc import IntegrityError
37
37
38 import rhodecode
38 import rhodecode
39 from rhodecode.lib import helpers as h
39 from rhodecode.lib import helpers as h
40 from rhodecode.lib.ext_json import json
40 from rhodecode.lib.ext_json import json
41 from rhodecode.lib.auth import LoginRequired, HasPermissionAnyDecorator,\
41 from rhodecode.lib.auth import LoginRequired, HasPermissionAnyDecorator,\
42 HasReposGroupPermissionAnyDecorator
42 HasReposGroupPermissionAnyDecorator
43 from rhodecode.lib.base import BaseController, render
43 from rhodecode.lib.base import BaseController, render
44 from rhodecode.model.db import RepoGroup, Repository
44 from rhodecode.model.db import RepoGroup, Repository
45 from rhodecode.model.repos_group import ReposGroupModel
45 from rhodecode.model.repos_group import ReposGroupModel
46 from rhodecode.model.forms import ReposGroupForm
46 from rhodecode.model.forms import ReposGroupForm
47 from rhodecode.model.meta import Session
47 from rhodecode.model.meta import Session
48 from rhodecode.model.repo import RepoModel
48 from rhodecode.model.repo import RepoModel
49 from webob.exc import HTTPInternalServerError, HTTPNotFound
49 from webob.exc import HTTPInternalServerError, HTTPNotFound
50 from rhodecode.lib.utils2 import str2bool
50 from rhodecode.lib.utils2 import str2bool
51 from sqlalchemy.sql.expression import func
51 from sqlalchemy.sql.expression import func
52
52
53 log = logging.getLogger(__name__)
53 log = logging.getLogger(__name__)
54
54
55
55
56 class ReposGroupsController(BaseController):
56 class ReposGroupsController(BaseController):
57 """REST Controller styled on the Atom Publishing Protocol"""
57 """REST Controller styled on the Atom Publishing Protocol"""
58 # To properly map this controller, ensure your config/routing.py
58 # To properly map this controller, ensure your config/routing.py
59 # file has a resource setup:
59 # file has a resource setup:
60 # map.resource('repos_group', 'repos_groups')
60 # map.resource('repos_group', 'repos_groups')
61
61
62 @LoginRequired()
62 @LoginRequired()
63 def __before__(self):
63 def __before__(self):
64 super(ReposGroupsController, self).__before__()
64 super(ReposGroupsController, self).__before__()
65
65
66 def __load_defaults(self):
66 def __load_defaults(self):
67 c.repo_groups = RepoGroup.groups_choices()
67 c.repo_groups = RepoGroup.groups_choices()
68 c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups)
68 c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups)
69
69
70 repo_model = RepoModel()
70 repo_model = RepoModel()
71 c.users_array = repo_model.get_users_js()
71 c.users_array = repo_model.get_users_js()
72 c.users_groups_array = repo_model.get_users_groups_js()
72 c.users_groups_array = repo_model.get_users_groups_js()
73
73
74 def __load_data(self, group_id):
74 def __load_data(self, group_id):
75 """
75 """
76 Load defaults settings for edit, and update
76 Load defaults settings for edit, and update
77
77
78 :param group_id:
78 :param group_id:
79 """
79 """
80 self.__load_defaults()
80 self.__load_defaults()
81 repo_group = RepoGroup.get_or_404(group_id)
81 repo_group = RepoGroup.get_or_404(group_id)
82 data = repo_group.get_dict()
82 data = repo_group.get_dict()
83 data['group_name'] = repo_group.name
83 data['group_name'] = repo_group.name
84
84
85 # fill repository users
85 # fill repository users
86 for p in repo_group.repo_group_to_perm:
86 for p in repo_group.repo_group_to_perm:
87 data.update({'u_perm_%s' % p.user.username:
87 data.update({'u_perm_%s' % p.user.username:
88 p.permission.permission_name})
88 p.permission.permission_name})
89
89
90 # fill repository groups
90 # fill repository groups
91 for p in repo_group.users_group_to_perm:
91 for p in repo_group.users_group_to_perm:
92 data.update({'g_perm_%s' % p.users_group.users_group_name:
92 data.update({'g_perm_%s' % p.users_group.users_group_name:
93 p.permission.permission_name})
93 p.permission.permission_name})
94
94
95 return data
95 return data
96
96
97 @HasPermissionAnyDecorator('hg.admin')
97 @HasPermissionAnyDecorator('hg.admin')
98 def index(self, format='html'):
98 def index(self, format='html'):
99 """GET /repos_groups: All items in the collection"""
99 """GET /repos_groups: All items in the collection"""
100 # url('repos_groups')
100 # url('repos_groups')
101 sk = lambda g: g.parents[0].group_name if g.parents else g.group_name
101 sk = lambda g: g.parents[0].group_name if g.parents else g.group_name
102 c.groups = sorted(RepoGroup.query().all(), key=sk)
102 c.groups = sorted(RepoGroup.query().all(), key=sk)
103 return render('admin/repos_groups/repos_groups_show.html')
103 return render('admin/repos_groups/repos_groups_show.html')
104
104
105 @HasPermissionAnyDecorator('hg.admin')
105 @HasPermissionAnyDecorator('hg.admin')
106 def create(self):
106 def create(self):
107 """POST /repos_groups: Create a new item"""
107 """POST /repos_groups: Create a new item"""
108 # url('repos_groups')
108 # url('repos_groups')
109 self.__load_defaults()
109 self.__load_defaults()
110 repos_group_form = ReposGroupForm(available_groups =
110 repos_group_form = ReposGroupForm(available_groups =
111 c.repo_groups_choices)()
111 c.repo_groups_choices)()
112 try:
112 try:
113 form_result = repos_group_form.to_python(dict(request.POST))
113 form_result = repos_group_form.to_python(dict(request.POST))
114 ReposGroupModel().create(
114 ReposGroupModel().create(
115 group_name=form_result['group_name'],
115 group_name=form_result['group_name'],
116 group_description=form_result['group_description'],
116 group_description=form_result['group_description'],
117 parent=form_result['group_parent_id']
117 parent=form_result['group_parent_id']
118 )
118 )
119 Session().commit()
119 Session().commit()
120 h.flash(_('created repos group %s') \
120 h.flash(_('created repos group %s') \
121 % form_result['group_name'], category='success')
121 % form_result['group_name'], category='success')
122 #TODO: in futureaction_logger(, '', '', '', self.sa)
122 #TODO: in futureaction_logger(, '', '', '', self.sa)
123 except formencode.Invalid, errors:
123 except formencode.Invalid, errors:
124
124
125 return htmlfill.render(
125 return htmlfill.render(
126 render('admin/repos_groups/repos_groups_add.html'),
126 render('admin/repos_groups/repos_groups_add.html'),
127 defaults=errors.value,
127 defaults=errors.value,
128 errors=errors.error_dict or {},
128 errors=errors.error_dict or {},
129 prefix_error=False,
129 prefix_error=False,
130 encoding="UTF-8")
130 encoding="UTF-8")
131 except Exception:
131 except Exception:
132 log.error(traceback.format_exc())
132 log.error(traceback.format_exc())
133 h.flash(_('error occurred during creation of repos group %s') \
133 h.flash(_('error occurred during creation of repos group %s') \
134 % request.POST.get('group_name'), category='error')
134 % request.POST.get('group_name'), category='error')
135
135
136 return redirect(url('repos_groups'))
136 return redirect(url('repos_groups'))
137
137
138 @HasPermissionAnyDecorator('hg.admin')
138 @HasPermissionAnyDecorator('hg.admin')
139 def new(self, format='html'):
139 def new(self, format='html'):
140 """GET /repos_groups/new: Form to create a new item"""
140 """GET /repos_groups/new: Form to create a new item"""
141 # url('new_repos_group')
141 # url('new_repos_group')
142 self.__load_defaults()
142 self.__load_defaults()
143 return render('admin/repos_groups/repos_groups_add.html')
143 return render('admin/repos_groups/repos_groups_add.html')
144
144
145 @HasPermissionAnyDecorator('hg.admin')
145 @HasPermissionAnyDecorator('hg.admin')
146 def update(self, id):
146 def update(self, id):
147 """PUT /repos_groups/id: Update an existing item"""
147 """PUT /repos_groups/id: Update an existing item"""
148 # Forms posted to this method should contain a hidden field:
148 # Forms posted to this method should contain a hidden field:
149 # <input type="hidden" name="_method" value="PUT" />
149 # <input type="hidden" name="_method" value="PUT" />
150 # Or using helpers:
150 # Or using helpers:
151 # h.form(url('repos_group', id=ID),
151 # h.form(url('repos_group', id=ID),
152 # method='put')
152 # method='put')
153 # url('repos_group', id=ID)
153 # url('repos_group', id=ID)
154
154
155 self.__load_defaults()
155 self.__load_defaults()
156 c.repos_group = RepoGroup.get(id)
156 c.repos_group = RepoGroup.get(id)
157
157
158 repos_group_form = ReposGroupForm(
158 repos_group_form = ReposGroupForm(
159 edit=True,
159 edit=True,
160 old_data=c.repos_group.get_dict(),
160 old_data=c.repos_group.get_dict(),
161 available_groups=c.repo_groups_choices
161 available_groups=c.repo_groups_choices
162 )()
162 )()
163 try:
163 try:
164 form_result = repos_group_form.to_python(dict(request.POST))
164 form_result = repos_group_form.to_python(dict(request.POST))
165 ReposGroupModel().update(id, form_result)
165 ReposGroupModel().update(id, form_result)
166 Session().commit()
166 Session().commit()
167 h.flash(_('updated repos group %s') \
167 h.flash(_('updated repos group %s') \
168 % form_result['group_name'], category='success')
168 % form_result['group_name'], category='success')
169 #TODO: in future action_logger(, '', '', '', self.sa)
169 #TODO: in future action_logger(, '', '', '', self.sa)
170 except formencode.Invalid, errors:
170 except formencode.Invalid, errors:
171
171
172 return htmlfill.render(
172 return htmlfill.render(
173 render('admin/repos_groups/repos_groups_edit.html'),
173 render('admin/repos_groups/repos_groups_edit.html'),
174 defaults=errors.value,
174 defaults=errors.value,
175 errors=errors.error_dict or {},
175 errors=errors.error_dict or {},
176 prefix_error=False,
176 prefix_error=False,
177 encoding="UTF-8")
177 encoding="UTF-8")
178 except Exception:
178 except Exception:
179 log.error(traceback.format_exc())
179 log.error(traceback.format_exc())
180 h.flash(_('error occurred during update of repos group %s') \
180 h.flash(_('error occurred during update of repos group %s') \
181 % request.POST.get('group_name'), category='error')
181 % request.POST.get('group_name'), category='error')
182
182
183 return redirect(url('edit_repos_group', id=id))
183 return redirect(url('edit_repos_group', id=id))
184
184
185 @HasPermissionAnyDecorator('hg.admin')
185 @HasPermissionAnyDecorator('hg.admin')
186 def delete(self, id):
186 def delete(self, id):
187 """DELETE /repos_groups/id: Delete an existing item"""
187 """DELETE /repos_groups/id: Delete an existing item"""
188 # Forms posted to this method should contain a hidden field:
188 # Forms posted to this method should contain a hidden field:
189 # <input type="hidden" name="_method" value="DELETE" />
189 # <input type="hidden" name="_method" value="DELETE" />
190 # Or using helpers:
190 # Or using helpers:
191 # h.form(url('repos_group', id=ID),
191 # h.form(url('repos_group', id=ID),
192 # method='delete')
192 # method='delete')
193 # url('repos_group', id=ID)
193 # url('repos_group', id=ID)
194
194
195 gr = RepoGroup.get(id)
195 gr = RepoGroup.get(id)
196 repos = gr.repositories.all()
196 repos = gr.repositories.all()
197 if repos:
197 if repos:
198 h.flash(_('This group contains %s repositores and cannot be '
198 h.flash(_('This group contains %s repositores and cannot be '
199 'deleted') % len(repos),
199 'deleted') % len(repos),
200 category='error')
200 category='error')
201 return redirect(url('repos_groups'))
201 return redirect(url('repos_groups'))
202
202
203 try:
203 try:
204 ReposGroupModel().delete(id)
204 ReposGroupModel().delete(id)
205 Session().commit()
205 Session().commit()
206 h.flash(_('removed repos group %s') % gr.group_name,
206 h.flash(_('removed repos group %s') % gr.group_name,
207 category='success')
207 category='success')
208 #TODO: in future action_logger(, '', '', '', self.sa)
208 #TODO: in future action_logger(, '', '', '', self.sa)
209 except IntegrityError, e:
209 except IntegrityError, e:
210 if str(e.message).find('groups_group_parent_id_fkey') != -1:
210 if str(e.message).find('groups_group_parent_id_fkey') != -1:
211 log.error(traceback.format_exc())
211 log.error(traceback.format_exc())
212 h.flash(_('Cannot delete this group it still contains '
212 h.flash(_('Cannot delete this group it still contains '
213 'subgroups'),
213 'subgroups'),
214 category='warning')
214 category='warning')
215 else:
215 else:
216 log.error(traceback.format_exc())
216 log.error(traceback.format_exc())
217 h.flash(_('error occurred during deletion of repos '
217 h.flash(_('error occurred during deletion of repos '
218 'group %s') % gr.group_name, category='error')
218 'group %s') % gr.group_name, category='error')
219
219
220 except Exception:
220 except Exception:
221 log.error(traceback.format_exc())
221 log.error(traceback.format_exc())
222 h.flash(_('error occurred during deletion of repos '
222 h.flash(_('error occurred during deletion of repos '
223 'group %s') % gr.group_name, category='error')
223 'group %s') % gr.group_name, category='error')
224
224
225 return redirect(url('repos_groups'))
225 return redirect(url('repos_groups'))
226
226
227 @HasReposGroupPermissionAnyDecorator('group.admin')
227 @HasReposGroupPermissionAnyDecorator('group.admin')
228 def delete_repos_group_user_perm(self, group_name):
228 def delete_repos_group_user_perm(self, group_name):
229 """
229 """
230 DELETE an existing repositories group permission user
230 DELETE an existing repositories group permission user
231
231
232 :param group_name:
232 :param group_name:
233 """
233 """
234 try:
234 try:
235 recursive = str2bool(request.POST.get('recursive', False))
235 recursive = str2bool(request.POST.get('recursive', False))
236 ReposGroupModel().delete_permission(
236 ReposGroupModel().delete_permission(
237 repos_group=group_name, obj=request.POST['user_id'],
237 repos_group=group_name, obj=request.POST['user_id'],
238 obj_type='user', recursive=recursive
238 obj_type='user', recursive=recursive
239 )
239 )
240 Session().commit()
240 Session().commit()
241 except Exception:
241 except Exception:
242 log.error(traceback.format_exc())
242 log.error(traceback.format_exc())
243 h.flash(_('An error occurred during deletion of group user'),
243 h.flash(_('An error occurred during deletion of group user'),
244 category='error')
244 category='error')
245 raise HTTPInternalServerError()
245 raise HTTPInternalServerError()
246
246
247 @HasReposGroupPermissionAnyDecorator('group.admin')
247 @HasReposGroupPermissionAnyDecorator('group.admin')
248 def delete_repos_group_users_group_perm(self, group_name):
248 def delete_repos_group_users_group_perm(self, group_name):
249 """
249 """
250 DELETE an existing repositories group permission users group
250 DELETE an existing repositories group permission users group
251
251
252 :param group_name:
252 :param group_name:
253 """
253 """
254
254
255 try:
255 try:
256 recursive = str2bool(request.POST.get('recursive', False))
256 recursive = str2bool(request.POST.get('recursive', False))
257 ReposGroupModel().delete_permission(
257 ReposGroupModel().delete_permission(
258 repos_group=group_name, obj=request.POST['users_group_id'],
258 repos_group=group_name, obj=request.POST['users_group_id'],
259 obj_type='users_group', recursive=recursive
259 obj_type='users_group', recursive=recursive
260 )
260 )
261 Session().commit()
261 Session().commit()
262 except Exception:
262 except Exception:
263 log.error(traceback.format_exc())
263 log.error(traceback.format_exc())
264 h.flash(_('An error occurred during deletion of group'
264 h.flash(_('An error occurred during deletion of group'
265 ' users groups'),
265 ' users groups'),
266 category='error')
266 category='error')
267 raise HTTPInternalServerError()
267 raise HTTPInternalServerError()
268
268
269 def show_by_name(self, group_name):
269 def show_by_name(self, group_name):
270 """
270 """
271 This is a proxy that does a lookup group_name -> id, and shows
271 This is a proxy that does a lookup group_name -> id, and shows
272 the group by id view instead
272 the group by id view instead
273 """
273 """
274 group_name = group_name.rstrip('/')
274 group_name = group_name.rstrip('/')
275 id_ = RepoGroup.get_by_group_name(group_name)
275 id_ = RepoGroup.get_by_group_name(group_name)
276 if id_:
276 if id_:
277 return self.show(id_.group_id)
277 return self.show(id_.group_id)
278 raise HTTPNotFound
278 raise HTTPNotFound
279
279
280 @HasReposGroupPermissionAnyDecorator('group.read', 'group.write',
280 @HasReposGroupPermissionAnyDecorator('group.read', 'group.write',
281 'group.admin')
281 'group.admin')
282 def show(self, id, format='html'):
282 def show(self, id, format='html'):
283 """GET /repos_groups/id: Show a specific item"""
283 """GET /repos_groups/id: Show a specific item"""
284 # url('repos_group', id=ID)
284 # url('repos_group', id=ID)
285
285
286 c.group = RepoGroup.get_or_404(id)
286 c.group = RepoGroup.get_or_404(id)
287 c.group_repos = c.group.repositories.all()
287 c.group_repos = c.group.repositories.all()
288
288
289 #overwrite our cached list with current filter
289 #overwrite our cached list with current filter
290 gr_filter = c.group_repos
290 gr_filter = c.group_repos
291 c.repo_cnt = 0
291 c.repo_cnt = 0
292
292
293 groups = RepoGroup.query().order_by(RepoGroup.group_name)\
293 groups = RepoGroup.query().order_by(RepoGroup.group_name)\
294 .filter(RepoGroup.group_parent_id == id).all()
294 .filter(RepoGroup.group_parent_id == id).all()
295 c.groups = self.scm_model.get_repos_groups(groups)
295 c.groups = self.scm_model.get_repos_groups(groups)
296
296
297 if c.visual.lightweight_dashboard is False:
297 if c.visual.lightweight_dashboard is False:
298 c.cached_repo_list = self.scm_model.get_repos(all_repos=gr_filter)
298 c.repo_list = self.scm_model.get_repos(all_repos=gr_filter)
299
300 c.repos_list = c.cached_repo_list
301 ## lightweight version of dashboard
299 ## lightweight version of dashboard
302 else:
300 else:
303 c.repos_list = Repository.query()\
301 c.repos_list = Repository.query()\
304 .filter(Repository.group_id == id)\
302 .filter(Repository.group_id == id)\
305 .order_by(func.lower(Repository.repo_name))\
303 .order_by(func.lower(Repository.repo_name))\
306 .all()
304 .all()
307 repos_data = []
308 total_records = len(c.repos_list)
309
305
310 _tmpl_lookup = rhodecode.CONFIG['pylons.app_globals'].mako_lookup
306 repos_data = RepoModel().get_repos_as_dict(repos_list=c.repos_list,
311 template = _tmpl_lookup.get_template('data_table/_dt_elements.html')
307 admin=False)
312
308 #json used to render the grid
313 quick_menu = lambda repo_name: (template.get_def("quick_menu")
309 c.data = json.dumps(repos_data)
314 .render(repo_name, _=_, h=h, c=c))
315 repo_lnk = lambda name, rtype, private, fork_of: (
316 template.get_def("repo_name")
317 .render(name, rtype, private, fork_of, short_name=False,
318 admin=False, _=_, h=h, c=c))
319 last_change = lambda last_change: (template.get_def("last_change")
320 .render(last_change, _=_, h=h, c=c))
321 rss_lnk = lambda repo_name: (template.get_def("rss")
322 .render(repo_name, _=_, h=h, c=c))
323 atom_lnk = lambda repo_name: (template.get_def("atom")
324 .render(repo_name, _=_, h=h, c=c))
325
326 for repo in c.repos_list:
327 repos_data.append({
328 "menu": quick_menu(repo.repo_name),
329 "raw_name": repo.repo_name.lower(),
330 "name": repo_lnk(repo.repo_name, repo.repo_type,
331 repo.private, repo.fork),
332 "last_change": last_change(repo.last_db_change),
333 "desc": repo.description,
334 "owner": h.person(repo.user.username),
335 "rss": rss_lnk(repo.repo_name),
336 "atom": atom_lnk(repo.repo_name),
337 })
338
339 c.data = json.dumps({
340 "totalRecords": total_records,
341 "startIndex": 0,
342 "sort": "name",
343 "dir": "asc",
344 "records": repos_data
345 })
346
310
347 return render('admin/repos_groups/repos_groups.html')
311 return render('admin/repos_groups/repos_groups.html')
348
312
349 @HasPermissionAnyDecorator('hg.admin')
313 @HasPermissionAnyDecorator('hg.admin')
350 def edit(self, id, format='html'):
314 def edit(self, id, format='html'):
351 """GET /repos_groups/id/edit: Form to edit an existing item"""
315 """GET /repos_groups/id/edit: Form to edit an existing item"""
352 # url('edit_repos_group', id=ID)
316 # url('edit_repos_group', id=ID)
353
317
354 c.repos_group = ReposGroupModel()._get_repos_group(id)
318 c.repos_group = ReposGroupModel()._get_repos_group(id)
355 defaults = self.__load_data(c.repos_group.group_id)
319 defaults = self.__load_data(c.repos_group.group_id)
356
320
357 # we need to exclude this group from the group list for editing
321 # we need to exclude this group from the group list for editing
358 c.repo_groups = filter(lambda x: x[0] != c.repos_group.group_id,
322 c.repo_groups = filter(lambda x: x[0] != c.repos_group.group_id,
359 c.repo_groups)
323 c.repo_groups)
360
324
361 return htmlfill.render(
325 return htmlfill.render(
362 render('admin/repos_groups/repos_groups_edit.html'),
326 render('admin/repos_groups/repos_groups_edit.html'),
363 defaults=defaults,
327 defaults=defaults,
364 encoding="UTF-8",
328 encoding="UTF-8",
365 force_defaults=False
329 force_defaults=False
366 )
330 )
@@ -1,517 +1,514 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.admin.settings
3 rhodecode.controllers.admin.settings
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 settings controller for rhodecode admin
6 settings controller for rhodecode admin
7
7
8 :created_on: Jul 14, 2010
8 :created_on: Jul 14, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26 import logging
26 import logging
27 import traceback
27 import traceback
28 import formencode
28 import formencode
29 import pkg_resources
29 import pkg_resources
30 import platform
30 import platform
31
31
32 from sqlalchemy import func
32 from sqlalchemy import func
33 from formencode import htmlfill
33 from formencode import htmlfill
34 from pylons import request, session, tmpl_context as c, url, config
34 from pylons import request, session, tmpl_context as c, url, config
35 from pylons.controllers.util import abort, redirect
35 from pylons.controllers.util import abort, redirect
36 from pylons.i18n.translation import _
36 from pylons.i18n.translation import _
37
37
38 from rhodecode.lib import helpers as h
38 from rhodecode.lib import helpers as h
39 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \
39 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \
40 HasPermissionAnyDecorator, NotAnonymous
40 HasPermissionAnyDecorator, NotAnonymous
41 from rhodecode.lib.base import BaseController, render
41 from rhodecode.lib.base import BaseController, render
42 from rhodecode.lib.celerylib import tasks, run_task
42 from rhodecode.lib.celerylib import tasks, run_task
43 from rhodecode.lib.utils import repo2db_mapper, invalidate_cache, \
43 from rhodecode.lib.utils import repo2db_mapper, invalidate_cache, \
44 set_rhodecode_config, repo_name_slug, check_git_version
44 set_rhodecode_config, repo_name_slug, check_git_version
45 from rhodecode.model.db import RhodeCodeUi, Repository, RepoGroup, \
45 from rhodecode.model.db import RhodeCodeUi, Repository, RepoGroup, \
46 RhodeCodeSetting, PullRequest, PullRequestReviewers
46 RhodeCodeSetting, PullRequest, PullRequestReviewers
47 from rhodecode.model.forms import UserForm, ApplicationSettingsForm, \
47 from rhodecode.model.forms import UserForm, ApplicationSettingsForm, \
48 ApplicationUiSettingsForm, ApplicationVisualisationForm
48 ApplicationUiSettingsForm, ApplicationVisualisationForm
49 from rhodecode.model.scm import ScmModel
49 from rhodecode.model.scm import ScmModel
50 from rhodecode.model.user import UserModel
50 from rhodecode.model.user import UserModel
51 from rhodecode.model.repo import RepoModel
51 from rhodecode.model.db import User
52 from rhodecode.model.db import User
52 from rhodecode.model.notification import EmailNotificationModel
53 from rhodecode.model.notification import EmailNotificationModel
53 from rhodecode.model.meta import Session
54 from rhodecode.model.meta import Session
54 from rhodecode.lib.utils2 import str2bool, safe_unicode
55 from rhodecode.lib.utils2 import str2bool, safe_unicode
55
56 from rhodecode.lib.compat import json
56 log = logging.getLogger(__name__)
57 log = logging.getLogger(__name__)
57
58
58
59
59 class SettingsController(BaseController):
60 class SettingsController(BaseController):
60 """REST Controller styled on the Atom Publishing Protocol"""
61 """REST Controller styled on the Atom Publishing Protocol"""
61 # To properly map this controller, ensure your config/routing.py
62 # To properly map this controller, ensure your config/routing.py
62 # file has a resource setup:
63 # file has a resource setup:
63 # map.resource('setting', 'settings', controller='admin/settings',
64 # map.resource('setting', 'settings', controller='admin/settings',
64 # path_prefix='/admin', name_prefix='admin_')
65 # path_prefix='/admin', name_prefix='admin_')
65
66
66 @LoginRequired()
67 @LoginRequired()
67 def __before__(self):
68 def __before__(self):
68 c.admin_user = session.get('admin_user')
69 c.admin_user = session.get('admin_user')
69 c.admin_username = session.get('admin_username')
70 c.admin_username = session.get('admin_username')
70 c.modules = sorted([(p.project_name, p.version)
71 c.modules = sorted([(p.project_name, p.version)
71 for p in pkg_resources.working_set]
72 for p in pkg_resources.working_set]
72 + [('git', check_git_version())],
73 + [('git', check_git_version())],
73 key=lambda k: k[0].lower())
74 key=lambda k: k[0].lower())
74 c.py_version = platform.python_version()
75 c.py_version = platform.python_version()
75 c.platform = platform.platform()
76 c.platform = platform.platform()
76 super(SettingsController, self).__before__()
77 super(SettingsController, self).__before__()
77
78
78 @HasPermissionAllDecorator('hg.admin')
79 @HasPermissionAllDecorator('hg.admin')
79 def index(self, format='html'):
80 def index(self, format='html'):
80 """GET /admin/settings: All items in the collection"""
81 """GET /admin/settings: All items in the collection"""
81 # url('admin_settings')
82 # url('admin_settings')
82
83
83 defaults = RhodeCodeSetting.get_app_settings()
84 defaults = RhodeCodeSetting.get_app_settings()
84 defaults.update(self._get_hg_ui_settings())
85 defaults.update(self._get_hg_ui_settings())
85
86
86 return htmlfill.render(
87 return htmlfill.render(
87 render('admin/settings/settings.html'),
88 render('admin/settings/settings.html'),
88 defaults=defaults,
89 defaults=defaults,
89 encoding="UTF-8",
90 encoding="UTF-8",
90 force_defaults=False
91 force_defaults=False
91 )
92 )
92
93
93 @HasPermissionAllDecorator('hg.admin')
94 @HasPermissionAllDecorator('hg.admin')
94 def create(self):
95 def create(self):
95 """POST /admin/settings: Create a new item"""
96 """POST /admin/settings: Create a new item"""
96 # url('admin_settings')
97 # url('admin_settings')
97
98
98 @HasPermissionAllDecorator('hg.admin')
99 @HasPermissionAllDecorator('hg.admin')
99 def new(self, format='html'):
100 def new(self, format='html'):
100 """GET /admin/settings/new: Form to create a new item"""
101 """GET /admin/settings/new: Form to create a new item"""
101 # url('admin_new_setting')
102 # url('admin_new_setting')
102
103
103 @HasPermissionAllDecorator('hg.admin')
104 @HasPermissionAllDecorator('hg.admin')
104 def update(self, setting_id):
105 def update(self, setting_id):
105 """PUT /admin/settings/setting_id: Update an existing item"""
106 """PUT /admin/settings/setting_id: Update an existing item"""
106 # Forms posted to this method should contain a hidden field:
107 # Forms posted to this method should contain a hidden field:
107 # <input type="hidden" name="_method" value="PUT" />
108 # <input type="hidden" name="_method" value="PUT" />
108 # Or using helpers:
109 # Or using helpers:
109 # h.form(url('admin_setting', setting_id=ID),
110 # h.form(url('admin_setting', setting_id=ID),
110 # method='put')
111 # method='put')
111 # url('admin_setting', setting_id=ID)
112 # url('admin_setting', setting_id=ID)
112
113
113 if setting_id == 'mapping':
114 if setting_id == 'mapping':
114 rm_obsolete = request.POST.get('destroy', False)
115 rm_obsolete = request.POST.get('destroy', False)
115 log.debug('Rescanning directories with destroy=%s' % rm_obsolete)
116 log.debug('Rescanning directories with destroy=%s' % rm_obsolete)
116 initial = ScmModel().repo_scan()
117 initial = ScmModel().repo_scan()
117 log.debug('invalidating all repositories')
118 log.debug('invalidating all repositories')
118 for repo_name in initial.keys():
119 for repo_name in initial.keys():
119 invalidate_cache('get_repo_cached_%s' % repo_name)
120 invalidate_cache('get_repo_cached_%s' % repo_name)
120
121
121 added, removed = repo2db_mapper(initial, rm_obsolete)
122 added, removed = repo2db_mapper(initial, rm_obsolete)
122 _repr = lambda l: ', '.join(map(safe_unicode, l)) or '-'
123 _repr = lambda l: ', '.join(map(safe_unicode, l)) or '-'
123 h.flash(_('Repositories successfully '
124 h.flash(_('Repositories successfully '
124 'rescanned added: %s ; removed: %s') %
125 'rescanned added: %s ; removed: %s') %
125 (_repr(added), _repr(removed)),
126 (_repr(added), _repr(removed)),
126 category='success')
127 category='success')
127
128
128 if setting_id == 'whoosh':
129 if setting_id == 'whoosh':
129 repo_location = self._get_hg_ui_settings()['paths_root_path']
130 repo_location = self._get_hg_ui_settings()['paths_root_path']
130 full_index = request.POST.get('full_index', False)
131 full_index = request.POST.get('full_index', False)
131 run_task(tasks.whoosh_index, repo_location, full_index)
132 run_task(tasks.whoosh_index, repo_location, full_index)
132 h.flash(_('Whoosh reindex task scheduled'), category='success')
133 h.flash(_('Whoosh reindex task scheduled'), category='success')
133
134
134 if setting_id == 'global':
135 if setting_id == 'global':
135
136
136 application_form = ApplicationSettingsForm()()
137 application_form = ApplicationSettingsForm()()
137 try:
138 try:
138 form_result = application_form.to_python(dict(request.POST))
139 form_result = application_form.to_python(dict(request.POST))
139 except formencode.Invalid, errors:
140 except formencode.Invalid, errors:
140 return htmlfill.render(
141 return htmlfill.render(
141 render('admin/settings/settings.html'),
142 render('admin/settings/settings.html'),
142 defaults=errors.value,
143 defaults=errors.value,
143 errors=errors.error_dict or {},
144 errors=errors.error_dict or {},
144 prefix_error=False,
145 prefix_error=False,
145 encoding="UTF-8"
146 encoding="UTF-8"
146 )
147 )
147
148
148 try:
149 try:
149 sett1 = RhodeCodeSetting.get_by_name_or_create('title')
150 sett1 = RhodeCodeSetting.get_by_name_or_create('title')
150 sett1.app_settings_value = form_result['rhodecode_title']
151 sett1.app_settings_value = form_result['rhodecode_title']
151 Session().add(sett1)
152 Session().add(sett1)
152
153
153 sett2 = RhodeCodeSetting.get_by_name_or_create('realm')
154 sett2 = RhodeCodeSetting.get_by_name_or_create('realm')
154 sett2.app_settings_value = form_result['rhodecode_realm']
155 sett2.app_settings_value = form_result['rhodecode_realm']
155 Session().add(sett2)
156 Session().add(sett2)
156
157
157 sett3 = RhodeCodeSetting.get_by_name_or_create('ga_code')
158 sett3 = RhodeCodeSetting.get_by_name_or_create('ga_code')
158 sett3.app_settings_value = form_result['rhodecode_ga_code']
159 sett3.app_settings_value = form_result['rhodecode_ga_code']
159 Session().add(sett3)
160 Session().add(sett3)
160
161
161 Session().commit()
162 Session().commit()
162 set_rhodecode_config(config)
163 set_rhodecode_config(config)
163 h.flash(_('Updated application settings'), category='success')
164 h.flash(_('Updated application settings'), category='success')
164
165
165 except Exception:
166 except Exception:
166 log.error(traceback.format_exc())
167 log.error(traceback.format_exc())
167 h.flash(_('error occurred during updating '
168 h.flash(_('error occurred during updating '
168 'application settings'),
169 'application settings'),
169 category='error')
170 category='error')
170
171
171 if setting_id == 'visual':
172 if setting_id == 'visual':
172
173
173 application_form = ApplicationVisualisationForm()()
174 application_form = ApplicationVisualisationForm()()
174 try:
175 try:
175 form_result = application_form.to_python(dict(request.POST))
176 form_result = application_form.to_python(dict(request.POST))
176 except formencode.Invalid, errors:
177 except formencode.Invalid, errors:
177 return htmlfill.render(
178 return htmlfill.render(
178 render('admin/settings/settings.html'),
179 render('admin/settings/settings.html'),
179 defaults=errors.value,
180 defaults=errors.value,
180 errors=errors.error_dict or {},
181 errors=errors.error_dict or {},
181 prefix_error=False,
182 prefix_error=False,
182 encoding="UTF-8"
183 encoding="UTF-8"
183 )
184 )
184
185
185 try:
186 try:
186 sett1 = RhodeCodeSetting.get_by_name_or_create('show_public_icon')
187 sett1 = RhodeCodeSetting.get_by_name_or_create('show_public_icon')
187 sett1.app_settings_value = \
188 sett1.app_settings_value = \
188 form_result['rhodecode_show_public_icon']
189 form_result['rhodecode_show_public_icon']
189 Session().add(sett1)
190 Session().add(sett1)
190
191
191 sett2 = RhodeCodeSetting.get_by_name_or_create('show_private_icon')
192 sett2 = RhodeCodeSetting.get_by_name_or_create('show_private_icon')
192 sett2.app_settings_value = \
193 sett2.app_settings_value = \
193 form_result['rhodecode_show_private_icon']
194 form_result['rhodecode_show_private_icon']
194 Session().add(sett2)
195 Session().add(sett2)
195
196
196 sett3 = RhodeCodeSetting.get_by_name_or_create('stylify_metatags')
197 sett3 = RhodeCodeSetting.get_by_name_or_create('stylify_metatags')
197 sett3.app_settings_value = \
198 sett3.app_settings_value = \
198 form_result['rhodecode_stylify_metatags']
199 form_result['rhodecode_stylify_metatags']
199 Session().add(sett3)
200 Session().add(sett3)
200
201
201 sett4 = RhodeCodeSetting.get_by_name_or_create('lightweight_dashboard')
202 sett4 = RhodeCodeSetting.get_by_name_or_create('lightweight_dashboard')
202 sett4.app_settings_value = \
203 sett4.app_settings_value = \
203 form_result['rhodecode_lightweight_dashboard']
204 form_result['rhodecode_lightweight_dashboard']
204 Session().add(sett4)
205 Session().add(sett4)
205
206
206 Session().commit()
207 Session().commit()
207 set_rhodecode_config(config)
208 set_rhodecode_config(config)
208 h.flash(_('Updated visualisation settings'),
209 h.flash(_('Updated visualisation settings'),
209 category='success')
210 category='success')
210
211
211 except Exception:
212 except Exception:
212 log.error(traceback.format_exc())
213 log.error(traceback.format_exc())
213 h.flash(_('error occurred during updating '
214 h.flash(_('error occurred during updating '
214 'visualisation settings'),
215 'visualisation settings'),
215 category='error')
216 category='error')
216
217
217 if setting_id == 'vcs':
218 if setting_id == 'vcs':
218 application_form = ApplicationUiSettingsForm()()
219 application_form = ApplicationUiSettingsForm()()
219 try:
220 try:
220 form_result = application_form.to_python(dict(request.POST))
221 form_result = application_form.to_python(dict(request.POST))
221 except formencode.Invalid, errors:
222 except formencode.Invalid, errors:
222 return htmlfill.render(
223 return htmlfill.render(
223 render('admin/settings/settings.html'),
224 render('admin/settings/settings.html'),
224 defaults=errors.value,
225 defaults=errors.value,
225 errors=errors.error_dict or {},
226 errors=errors.error_dict or {},
226 prefix_error=False,
227 prefix_error=False,
227 encoding="UTF-8"
228 encoding="UTF-8"
228 )
229 )
229
230
230 try:
231 try:
231 # fix namespaces for hooks and extensions
232 # fix namespaces for hooks and extensions
232 _f = lambda s: s.replace('.', '_')
233 _f = lambda s: s.replace('.', '_')
233
234
234 sett = RhodeCodeUi.get_by_key('push_ssl')
235 sett = RhodeCodeUi.get_by_key('push_ssl')
235 sett.ui_value = form_result['web_push_ssl']
236 sett.ui_value = form_result['web_push_ssl']
236 Session().add(sett)
237 Session().add(sett)
237
238
238 sett = RhodeCodeUi.get_by_key('/')
239 sett = RhodeCodeUi.get_by_key('/')
239 sett.ui_value = form_result['paths_root_path']
240 sett.ui_value = form_result['paths_root_path']
240 Session().add(sett)
241 Session().add(sett)
241
242
242 #HOOKS
243 #HOOKS
243 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_UPDATE)
244 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_UPDATE)
244 sett.ui_active = form_result[_f('hooks_%s' %
245 sett.ui_active = form_result[_f('hooks_%s' %
245 RhodeCodeUi.HOOK_UPDATE)]
246 RhodeCodeUi.HOOK_UPDATE)]
246 Session().add(sett)
247 Session().add(sett)
247
248
248 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_REPO_SIZE)
249 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_REPO_SIZE)
249 sett.ui_active = form_result[_f('hooks_%s' %
250 sett.ui_active = form_result[_f('hooks_%s' %
250 RhodeCodeUi.HOOK_REPO_SIZE)]
251 RhodeCodeUi.HOOK_REPO_SIZE)]
251 Session().add(sett)
252 Session().add(sett)
252
253
253 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_PUSH)
254 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_PUSH)
254 sett.ui_active = form_result[_f('hooks_%s' %
255 sett.ui_active = form_result[_f('hooks_%s' %
255 RhodeCodeUi.HOOK_PUSH)]
256 RhodeCodeUi.HOOK_PUSH)]
256 Session().add(sett)
257 Session().add(sett)
257
258
258 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_PULL)
259 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_PULL)
259 sett.ui_active = form_result[_f('hooks_%s' %
260 sett.ui_active = form_result[_f('hooks_%s' %
260 RhodeCodeUi.HOOK_PULL)]
261 RhodeCodeUi.HOOK_PULL)]
261
262
262 Session().add(sett)
263 Session().add(sett)
263
264
264 ## EXTENSIONS
265 ## EXTENSIONS
265 sett = RhodeCodeUi.get_by_key('largefiles')
266 sett = RhodeCodeUi.get_by_key('largefiles')
266 if not sett:
267 if not sett:
267 #make one if it's not there !
268 #make one if it's not there !
268 sett = RhodeCodeUi()
269 sett = RhodeCodeUi()
269 sett.ui_key = 'largefiles'
270 sett.ui_key = 'largefiles'
270 sett.ui_section = 'extensions'
271 sett.ui_section = 'extensions'
271 sett.ui_active = form_result[_f('extensions_largefiles')]
272 sett.ui_active = form_result[_f('extensions_largefiles')]
272 Session().add(sett)
273 Session().add(sett)
273
274
274 sett = RhodeCodeUi.get_by_key('hgsubversion')
275 sett = RhodeCodeUi.get_by_key('hgsubversion')
275 if not sett:
276 if not sett:
276 #make one if it's not there !
277 #make one if it's not there !
277 sett = RhodeCodeUi()
278 sett = RhodeCodeUi()
278 sett.ui_key = 'hgsubversion'
279 sett.ui_key = 'hgsubversion'
279 sett.ui_section = 'extensions'
280 sett.ui_section = 'extensions'
280
281
281 sett.ui_active = form_result[_f('extensions_hgsubversion')]
282 sett.ui_active = form_result[_f('extensions_hgsubversion')]
282 Session().add(sett)
283 Session().add(sett)
283
284
284 # sett = RhodeCodeUi.get_by_key('hggit')
285 # sett = RhodeCodeUi.get_by_key('hggit')
285 # if not sett:
286 # if not sett:
286 # #make one if it's not there !
287 # #make one if it's not there !
287 # sett = RhodeCodeUi()
288 # sett = RhodeCodeUi()
288 # sett.ui_key = 'hggit'
289 # sett.ui_key = 'hggit'
289 # sett.ui_section = 'extensions'
290 # sett.ui_section = 'extensions'
290 #
291 #
291 # sett.ui_active = form_result[_f('extensions_hggit')]
292 # sett.ui_active = form_result[_f('extensions_hggit')]
292 # Session().add(sett)
293 # Session().add(sett)
293
294
294 Session().commit()
295 Session().commit()
295
296
296 h.flash(_('Updated VCS settings'), category='success')
297 h.flash(_('Updated VCS settings'), category='success')
297
298
298 except Exception:
299 except Exception:
299 log.error(traceback.format_exc())
300 log.error(traceback.format_exc())
300 h.flash(_('error occurred during updating '
301 h.flash(_('error occurred during updating '
301 'application settings'), category='error')
302 'application settings'), category='error')
302
303
303 if setting_id == 'hooks':
304 if setting_id == 'hooks':
304 ui_key = request.POST.get('new_hook_ui_key')
305 ui_key = request.POST.get('new_hook_ui_key')
305 ui_value = request.POST.get('new_hook_ui_value')
306 ui_value = request.POST.get('new_hook_ui_value')
306 try:
307 try:
307
308
308 if ui_value and ui_key:
309 if ui_value and ui_key:
309 RhodeCodeUi.create_or_update_hook(ui_key, ui_value)
310 RhodeCodeUi.create_or_update_hook(ui_key, ui_value)
310 h.flash(_('Added new hook'),
311 h.flash(_('Added new hook'),
311 category='success')
312 category='success')
312
313
313 # check for edits
314 # check for edits
314 update = False
315 update = False
315 _d = request.POST.dict_of_lists()
316 _d = request.POST.dict_of_lists()
316 for k, v in zip(_d.get('hook_ui_key', []),
317 for k, v in zip(_d.get('hook_ui_key', []),
317 _d.get('hook_ui_value_new', [])):
318 _d.get('hook_ui_value_new', [])):
318 RhodeCodeUi.create_or_update_hook(k, v)
319 RhodeCodeUi.create_or_update_hook(k, v)
319 update = True
320 update = True
320
321
321 if update:
322 if update:
322 h.flash(_('Updated hooks'), category='success')
323 h.flash(_('Updated hooks'), category='success')
323 Session().commit()
324 Session().commit()
324 except Exception:
325 except Exception:
325 log.error(traceback.format_exc())
326 log.error(traceback.format_exc())
326 h.flash(_('error occurred during hook creation'),
327 h.flash(_('error occurred during hook creation'),
327 category='error')
328 category='error')
328
329
329 return redirect(url('admin_edit_setting', setting_id='hooks'))
330 return redirect(url('admin_edit_setting', setting_id='hooks'))
330
331
331 if setting_id == 'email':
332 if setting_id == 'email':
332 test_email = request.POST.get('test_email')
333 test_email = request.POST.get('test_email')
333 test_email_subj = 'RhodeCode TestEmail'
334 test_email_subj = 'RhodeCode TestEmail'
334 test_email_body = 'RhodeCode Email test'
335 test_email_body = 'RhodeCode Email test'
335
336
336 test_email_html_body = EmailNotificationModel()\
337 test_email_html_body = EmailNotificationModel()\
337 .get_email_tmpl(EmailNotificationModel.TYPE_DEFAULT,
338 .get_email_tmpl(EmailNotificationModel.TYPE_DEFAULT,
338 body=test_email_body)
339 body=test_email_body)
339
340
340 recipients = [test_email] if test_email else None
341 recipients = [test_email] if test_email else None
341
342
342 run_task(tasks.send_email, recipients, test_email_subj,
343 run_task(tasks.send_email, recipients, test_email_subj,
343 test_email_body, test_email_html_body)
344 test_email_body, test_email_html_body)
344
345
345 h.flash(_('Email task created'), category='success')
346 h.flash(_('Email task created'), category='success')
346 return redirect(url('admin_settings'))
347 return redirect(url('admin_settings'))
347
348
348 @HasPermissionAllDecorator('hg.admin')
349 @HasPermissionAllDecorator('hg.admin')
349 def delete(self, setting_id):
350 def delete(self, setting_id):
350 """DELETE /admin/settings/setting_id: Delete an existing item"""
351 """DELETE /admin/settings/setting_id: Delete an existing item"""
351 # Forms posted to this method should contain a hidden field:
352 # Forms posted to this method should contain a hidden field:
352 # <input type="hidden" name="_method" value="DELETE" />
353 # <input type="hidden" name="_method" value="DELETE" />
353 # Or using helpers:
354 # Or using helpers:
354 # h.form(url('admin_setting', setting_id=ID),
355 # h.form(url('admin_setting', setting_id=ID),
355 # method='delete')
356 # method='delete')
356 # url('admin_setting', setting_id=ID)
357 # url('admin_setting', setting_id=ID)
357 if setting_id == 'hooks':
358 if setting_id == 'hooks':
358 hook_id = request.POST.get('hook_id')
359 hook_id = request.POST.get('hook_id')
359 RhodeCodeUi.delete(hook_id)
360 RhodeCodeUi.delete(hook_id)
360 Session().commit()
361 Session().commit()
361
362
362 @HasPermissionAllDecorator('hg.admin')
363 @HasPermissionAllDecorator('hg.admin')
363 def show(self, setting_id, format='html'):
364 def show(self, setting_id, format='html'):
364 """
365 """
365 GET /admin/settings/setting_id: Show a specific item"""
366 GET /admin/settings/setting_id: Show a specific item"""
366 # url('admin_setting', setting_id=ID)
367 # url('admin_setting', setting_id=ID)
367
368
368 @HasPermissionAllDecorator('hg.admin')
369 @HasPermissionAllDecorator('hg.admin')
369 def edit(self, setting_id, format='html'):
370 def edit(self, setting_id, format='html'):
370 """
371 """
371 GET /admin/settings/setting_id/edit: Form to
372 GET /admin/settings/setting_id/edit: Form to
372 edit an existing item"""
373 edit an existing item"""
373 # url('admin_edit_setting', setting_id=ID)
374 # url('admin_edit_setting', setting_id=ID)
374
375
375 c.hooks = RhodeCodeUi.get_builtin_hooks()
376 c.hooks = RhodeCodeUi.get_builtin_hooks()
376 c.custom_hooks = RhodeCodeUi.get_custom_hooks()
377 c.custom_hooks = RhodeCodeUi.get_custom_hooks()
377
378
378 return htmlfill.render(
379 return htmlfill.render(
379 render('admin/settings/hooks.html'),
380 render('admin/settings/hooks.html'),
380 defaults={},
381 defaults={},
381 encoding="UTF-8",
382 encoding="UTF-8",
382 force_defaults=False
383 force_defaults=False
383 )
384 )
384
385
385 @NotAnonymous()
386 @NotAnonymous()
386 def my_account(self):
387 def my_account(self):
387 """
388 """
388 GET /_admin/my_account Displays info about my account
389 GET /_admin/my_account Displays info about my account
389 """
390 """
390 # url('admin_settings_my_account')
391 # url('admin_settings_my_account')
391
392
392 c.user = User.get(self.rhodecode_user.user_id)
393 c.user = User.get(self.rhodecode_user.user_id)
393 all_repos = Session().query(Repository)\
394 .filter(Repository.user_id == c.user.user_id)\
395 .order_by(func.lower(Repository.repo_name)).all()
396
397 c.user_repos = ScmModel().get_repos(all_repos)
398
394
399 if c.user.username == 'default':
395 if c.user.username == 'default':
400 h.flash(_("You can't edit this user since it's"
396 h.flash(_("You can't edit this user since it's"
401 " crucial for entire application"), category='warning')
397 " crucial for entire application"), category='warning')
402 return redirect(url('users'))
398 return redirect(url('users'))
403
399
400 repos_list = Session().query(Repository)\
401 .filter(Repository.user_id ==
402 self.rhodecode_user.user_id)\
403 .order_by(func.lower(Repository.repo_name)).all()
404
405 repos_data = RepoModel().get_repos_as_dict(repos_list=repos_list,
406 admin=True)
407 #json used to render the grid
408 c.data = json.dumps(repos_data)
409
404 defaults = c.user.get_dict()
410 defaults = c.user.get_dict()
405
411
406 c.form = htmlfill.render(
412 c.form = htmlfill.render(
407 render('admin/users/user_edit_my_account_form.html'),
413 render('admin/users/user_edit_my_account_form.html'),
408 defaults=defaults,
414 defaults=defaults,
409 encoding="UTF-8",
415 encoding="UTF-8",
410 force_defaults=False
416 force_defaults=False
411 )
417 )
412 return render('admin/users/user_edit_my_account.html')
418 return render('admin/users/user_edit_my_account.html')
413
419
414 @NotAnonymous()
420 @NotAnonymous()
415 def my_account_update(self):
421 def my_account_update(self):
416 """PUT /_admin/my_account_update: Update an existing item"""
422 """PUT /_admin/my_account_update: Update an existing item"""
417 # Forms posted to this method should contain a hidden field:
423 # Forms posted to this method should contain a hidden field:
418 # <input type="hidden" name="_method" value="PUT" />
424 # <input type="hidden" name="_method" value="PUT" />
419 # Or using helpers:
425 # Or using helpers:
420 # h.form(url('admin_settings_my_account_update'),
426 # h.form(url('admin_settings_my_account_update'),
421 # method='put')
427 # method='put')
422 # url('admin_settings_my_account_update', id=ID)
428 # url('admin_settings_my_account_update', id=ID)
423 uid = self.rhodecode_user.user_id
429 uid = self.rhodecode_user.user_id
424 email = self.rhodecode_user.email
430 email = self.rhodecode_user.email
425 _form = UserForm(edit=True,
431 _form = UserForm(edit=True,
426 old_data={'user_id': uid, 'email': email})()
432 old_data={'user_id': uid, 'email': email})()
427 form_result = {}
433 form_result = {}
428 try:
434 try:
429 form_result = _form.to_python(dict(request.POST))
435 form_result = _form.to_python(dict(request.POST))
430 UserModel().update_my_account(uid, form_result)
436 UserModel().update_my_account(uid, form_result)
431 h.flash(_('Your account was updated successfully'),
437 h.flash(_('Your account was updated successfully'),
432 category='success')
438 category='success')
433 Session().commit()
439 Session().commit()
434 except formencode.Invalid, errors:
440 except formencode.Invalid, errors:
435 c.user = User.get(self.rhodecode_user.user_id)
441 c.user = User.get(self.rhodecode_user.user_id)
436
442
437 c.form = htmlfill.render(
443 c.form = htmlfill.render(
438 render('admin/users/user_edit_my_account_form.html'),
444 render('admin/users/user_edit_my_account_form.html'),
439 defaults=errors.value,
445 defaults=errors.value,
440 errors=errors.error_dict or {},
446 errors=errors.error_dict or {},
441 prefix_error=False,
447 prefix_error=False,
442 encoding="UTF-8")
448 encoding="UTF-8")
443 return render('admin/users/user_edit_my_account.html')
449 return render('admin/users/user_edit_my_account.html')
444 except Exception:
450 except Exception:
445 log.error(traceback.format_exc())
451 log.error(traceback.format_exc())
446 h.flash(_('error occurred during update of user %s') \
452 h.flash(_('error occurred during update of user %s') \
447 % form_result.get('username'), category='error')
453 % form_result.get('username'), category='error')
448
454
449 return redirect(url('my_account'))
455 return redirect(url('my_account'))
450
456
451 @NotAnonymous()
457 @NotAnonymous()
452 def my_account_my_repos(self):
453 all_repos = Session().query(Repository)\
454 .filter(Repository.user_id == self.rhodecode_user.user_id)\
455 .order_by(func.lower(Repository.repo_name))\
456 .all()
457 c.user_repos = ScmModel().get_repos(all_repos)
458 return render('admin/users/user_edit_my_account_repos.html')
459
460 @NotAnonymous()
461 def my_account_my_pullrequests(self):
458 def my_account_my_pullrequests(self):
462 c.my_pull_requests = PullRequest.query()\
459 c.my_pull_requests = PullRequest.query()\
463 .filter(PullRequest.user_id==
460 .filter(PullRequest.user_id ==
464 self.rhodecode_user.user_id)\
461 self.rhodecode_user.user_id)\
465 .all()
462 .all()
466 c.participate_in_pull_requests = \
463 c.participate_in_pull_requests = \
467 [x.pull_request for x in PullRequestReviewers.query()\
464 [x.pull_request for x in PullRequestReviewers.query()\
468 .filter(PullRequestReviewers.user_id==
465 .filter(PullRequestReviewers.user_id ==
469 self.rhodecode_user.user_id)\
466 self.rhodecode_user.user_id)\
470 .all()]
467 .all()]
471 return render('admin/users/user_edit_my_account_pullrequests.html')
468 return render('admin/users/user_edit_my_account_pullrequests.html')
472
469
473 @NotAnonymous()
470 @NotAnonymous()
474 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
471 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
475 def create_repository(self):
472 def create_repository(self):
476 """GET /_admin/create_repository: Form to create a new item"""
473 """GET /_admin/create_repository: Form to create a new item"""
477
474
478 c.repo_groups = RepoGroup.groups_choices(check_perms=True)
475 c.repo_groups = RepoGroup.groups_choices(check_perms=True)
479 c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups)
476 c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups)
480 choices, c.landing_revs = ScmModel().get_repo_landing_revs()
477 choices, c.landing_revs = ScmModel().get_repo_landing_revs()
481
478
482 new_repo = request.GET.get('repo', '')
479 new_repo = request.GET.get('repo', '')
483 c.new_repo = repo_name_slug(new_repo)
480 c.new_repo = repo_name_slug(new_repo)
484
481
485 ## apply the defaults from defaults page
482 ## apply the defaults from defaults page
486 defaults = RhodeCodeSetting.get_default_repo_settings(strip_prefix=True)
483 defaults = RhodeCodeSetting.get_default_repo_settings(strip_prefix=True)
487 return htmlfill.render(
484 return htmlfill.render(
488 render('admin/repos/repo_add_create_repository.html'),
485 render('admin/repos/repo_add_create_repository.html'),
489 defaults=defaults,
486 defaults=defaults,
490 errors={},
487 errors={},
491 prefix_error=False,
488 prefix_error=False,
492 encoding="UTF-8"
489 encoding="UTF-8"
493 )
490 )
494
491
495 def _get_hg_ui_settings(self):
492 def _get_hg_ui_settings(self):
496 ret = RhodeCodeUi.query().all()
493 ret = RhodeCodeUi.query().all()
497
494
498 if not ret:
495 if not ret:
499 raise Exception('Could not get application ui settings !')
496 raise Exception('Could not get application ui settings !')
500 settings = {}
497 settings = {}
501 for each in ret:
498 for each in ret:
502 k = each.ui_key
499 k = each.ui_key
503 v = each.ui_value
500 v = each.ui_value
504 if k == '/':
501 if k == '/':
505 k = 'root_path'
502 k = 'root_path'
506
503
507 if k == 'push_ssl':
504 if k == 'push_ssl':
508 v = str2bool(v)
505 v = str2bool(v)
509
506
510 if k.find('.') != -1:
507 if k.find('.') != -1:
511 k = k.replace('.', '_')
508 k = k.replace('.', '_')
512
509
513 if each.ui_section in ['hooks', 'extensions']:
510 if each.ui_section in ['hooks', 'extensions']:
514 v = each.ui_active
511 v = each.ui_active
515
512
516 settings[each.ui_section + '_' + k] = v
513 settings[each.ui_section + '_' + k] = v
517 return settings
514 return settings
@@ -1,133 +1,87 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.home
3 rhodecode.controllers.home
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 Home controller for Rhodecode
6 Home controller for Rhodecode
7
7
8 :created_on: Feb 18, 2010
8 :created_on: Feb 18, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26 import logging
26 import logging
27
27
28 from pylons import tmpl_context as c, request
28 from pylons import tmpl_context as c, request
29 from pylons.i18n.translation import _
29 from pylons.i18n.translation import _
30 from webob.exc import HTTPBadRequest
30 from webob.exc import HTTPBadRequest
31 from sqlalchemy.sql.expression import func
31
32
32 import rhodecode
33 import rhodecode
33 from rhodecode.lib import helpers as h
34 from rhodecode.lib import helpers as h
34 from rhodecode.lib.ext_json import json
35 from rhodecode.lib.ext_json import json
35 from rhodecode.lib.auth import LoginRequired
36 from rhodecode.lib.auth import LoginRequired
36 from rhodecode.lib.base import BaseController, render
37 from rhodecode.lib.base import BaseController, render
37 from rhodecode.model.db import Repository
38 from rhodecode.model.db import Repository
38 from sqlalchemy.sql.expression import func
39 from rhodecode.model.repo import RepoModel
40
39
41
40 log = logging.getLogger(__name__)
42 log = logging.getLogger(__name__)
41
43
42
44
43 class HomeController(BaseController):
45 class HomeController(BaseController):
44
46
45 @LoginRequired()
47 @LoginRequired()
46 def __before__(self):
48 def __before__(self):
47 super(HomeController, self).__before__()
49 super(HomeController, self).__before__()
48
50
49 def index(self):
51 def index(self):
50 c.groups = self.scm_model.get_repos_groups()
52 c.groups = self.scm_model.get_repos_groups()
51 c.group = None
53 c.group = None
52
54
53 if c.visual.lightweight_dashboard is False:
55 if c.visual.lightweight_dashboard is False:
54 c.repos_list = self.scm_model.get_repos()
56 c.repos_list = self.scm_model.get_repos()
55 ## lightweight version of dashboard
57 ## lightweight version of dashboard
56 else:
58 else:
57 c.repos_list = Repository.query()\
59 c.repos_list = Repository.query()\
58 .filter(Repository.group_id == None)\
60 .filter(Repository.group_id == None)\
59 .order_by(func.lower(Repository.repo_name))\
61 .order_by(func.lower(Repository.repo_name))\
60 .all()
62 .all()
61 repos_data = []
62 total_records = len(c.repos_list)
63
63
64 _tmpl_lookup = rhodecode.CONFIG['pylons.app_globals'].mako_lookup
64 repos_data = RepoModel().get_repos_as_dict(repos_list=c.repos_list,
65 template = _tmpl_lookup.get_template('data_table/_dt_elements.html')
65 admin=False)
66
66 #json used to render the grid
67 quick_menu = lambda repo_name: (template.get_def("quick_menu")
67 c.data = json.dumps(repos_data)
68 .render(repo_name, _=_, h=h, c=c))
69 repo_lnk = lambda name, rtype, private, fork_of: (
70 template.get_def("repo_name")
71 .render(name, rtype, private, fork_of, short_name=False,
72 admin=False, _=_, h=h, c=c))
73 last_change = lambda last_change: (template.get_def("last_change")
74 .render(last_change, _=_, h=h, c=c))
75 rss_lnk = lambda repo_name: (template.get_def("rss")
76 .render(repo_name, _=_, h=h, c=c))
77 atom_lnk = lambda repo_name: (template.get_def("atom")
78 .render(repo_name, _=_, h=h, c=c))
79 tip = lambda repo_name, cs_cache: (template.get_def("revision")
80 .render(repo_name,
81 cs_cache.get('revision'),
82 cs_cache.get('raw_id'),
83 cs_cache.get('author'),
84 cs_cache.get('message'), _=_, h=h,
85 c=c))
86
87 def desc(desc):
88 if c.visual.stylify_metatags:
89 return h.urlify_text(h.desc_stylize(h.truncate(desc, 60)))
90 else:
91 return h.urlify_text(h.truncate(desc, 60))
92
93 for repo in c.repos_list:
94 repos_data.append({
95 "menu": quick_menu(repo.repo_name),
96 "raw_name": repo.repo_name.lower(),
97 "name": repo_lnk(repo.repo_name, repo.repo_type,
98 repo.private, repo.fork),
99 "last_change": last_change(repo.last_db_change),
100 "tip": tip(repo.repo_name, repo.changeset_cache),
101 "desc": desc(repo.description),
102 "owner": h.person(repo.user.username),
103 "rss": rss_lnk(repo.repo_name),
104 "atom": atom_lnk(repo.repo_name),
105 })
106
107 c.data = json.dumps({
108 "totalRecords": total_records,
109 "startIndex": 0,
110 "sort": "name",
111 "dir": "asc",
112 "records": repos_data
113 })
114
68
115 return render('/index.html')
69 return render('/index.html')
116
70
117 def repo_switcher(self):
71 def repo_switcher(self):
118 if request.is_xhr:
72 if request.is_xhr:
119 all_repos = Repository.query().order_by(Repository.repo_name).all()
73 all_repos = Repository.query().order_by(Repository.repo_name).all()
120 c.repos_list = self.scm_model.get_repos(all_repos,
74 c.repos_list = self.scm_model.get_repos(all_repos,
121 sort_key='name_sort',
75 sort_key='name_sort',
122 simple=True)
76 simple=True)
123 return render('/repo_switcher_list.html')
77 return render('/repo_switcher_list.html')
124 else:
78 else:
125 raise HTTPBadRequest()
79 raise HTTPBadRequest()
126
80
127 def branch_tag_switcher(self, repo_name):
81 def branch_tag_switcher(self, repo_name):
128 if request.is_xhr:
82 if request.is_xhr:
129 c.rhodecode_db_repo = Repository.get_by_repo_name(c.repo_name)
83 c.rhodecode_db_repo = Repository.get_by_repo_name(c.repo_name)
130 c.rhodecode_repo = c.rhodecode_db_repo.scm_instance
84 c.rhodecode_repo = c.rhodecode_db_repo.scm_instance
131 return render('/switch_to_list.html')
85 return render('/switch_to_list.html')
132 else:
86 else:
133 raise HTTPBadRequest()
87 raise HTTPBadRequest()
@@ -1,322 +1,379 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.journal
3 rhodecode.controllers.journal
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 Journal controller for pylons
6 Journal controller for pylons
7
7
8 :created_on: Nov 21, 2010
8 :created_on: Nov 21, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 import logging
25 import logging
26 from itertools import groupby
26 from itertools import groupby
27
27
28 from sqlalchemy import or_
28 from sqlalchemy import or_
29 from sqlalchemy.orm import joinedload
29 from sqlalchemy.orm import joinedload
30 from sqlalchemy.sql.expression import func
31
30 from webhelpers.paginate import Page
32 from webhelpers.paginate import Page
31 from webhelpers.feedgenerator import Atom1Feed, Rss201rev2Feed
33 from webhelpers.feedgenerator import Atom1Feed, Rss201rev2Feed
32
34
33 from webob.exc import HTTPBadRequest
35 from webob.exc import HTTPBadRequest
34 from pylons import request, tmpl_context as c, response, url
36 from pylons import request, tmpl_context as c, response, url
35 from pylons.i18n.translation import _
37 from pylons.i18n.translation import _
36
38
37 import rhodecode.lib.helpers as h
39 import rhodecode.lib.helpers as h
38 from rhodecode.lib.auth import LoginRequired, NotAnonymous
40 from rhodecode.lib.auth import LoginRequired, NotAnonymous
39 from rhodecode.lib.base import BaseController, render
41 from rhodecode.lib.base import BaseController, render
40 from rhodecode.model.db import UserLog, UserFollowing, Repository, User
42 from rhodecode.model.db import UserLog, UserFollowing, Repository, User
41 from rhodecode.model.meta import Session
43 from rhodecode.model.meta import Session
42 from sqlalchemy.sql.expression import func
43 from rhodecode.model.scm import ScmModel
44 from rhodecode.lib.utils2 import safe_int, AttributeDict
44 from rhodecode.lib.utils2 import safe_int, AttributeDict
45 from rhodecode.controllers.admin.admin import _journal_filter
45 from rhodecode.controllers.admin.admin import _journal_filter
46 from rhodecode.model.repo import RepoModel
47 from rhodecode.lib.compat import json
46
48
47 log = logging.getLogger(__name__)
49 log = logging.getLogger(__name__)
48
50
49
51
50 class JournalController(BaseController):
52 class JournalController(BaseController):
51
53
52 def __before__(self):
54 def __before__(self):
53 super(JournalController, self).__before__()
55 super(JournalController, self).__before__()
54 self.language = 'en-us'
56 self.language = 'en-us'
55 self.ttl = "5"
57 self.ttl = "5"
56 self.feed_nr = 20
58 self.feed_nr = 20
57 c.search_term = request.GET.get('filter')
59 c.search_term = request.GET.get('filter')
58
60
59 @LoginRequired()
61 @LoginRequired()
60 @NotAnonymous()
62 @NotAnonymous()
61 def index(self):
63 def index(self):
62 # Return a rendered template
64 # Return a rendered template
63 p = safe_int(request.params.get('page', 1), 1)
65 p = safe_int(request.params.get('page', 1), 1)
64 c.user = User.get(self.rhodecode_user.user_id)
66 c.user = User.get(self.rhodecode_user.user_id)
65 c.following = self.sa.query(UserFollowing)\
67 c.following = self.sa.query(UserFollowing)\
66 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
68 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
67 .options(joinedload(UserFollowing.follows_repository))\
69 .options(joinedload(UserFollowing.follows_repository))\
68 .all()
70 .all()
69
71
70 journal = self._get_journal_data(c.following)
72 journal = self._get_journal_data(c.following)
71
73
72 def url_generator(**kw):
74 def url_generator(**kw):
73 return url.current(filter=c.search_term, **kw)
75 return url.current(filter=c.search_term, **kw)
74
76
75 c.journal_pager = Page(journal, page=p, items_per_page=20, url=url_generator)
77 c.journal_pager = Page(journal, page=p, items_per_page=20, url=url_generator)
76 c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager)
78 c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager)
77
79
78 c.journal_data = render('journal/journal_data.html')
80 c.journal_data = render('journal/journal_data.html')
79 if request.environ.get('HTTP_X_PARTIAL_XHR'):
81 if request.environ.get('HTTP_X_PARTIAL_XHR'):
80 return c.journal_data
82 return c.journal_data
81 return render('journal/journal.html')
83
84 repos_list = Session().query(Repository)\
85 .filter(Repository.user_id ==
86 self.rhodecode_user.user_id)\
87 .order_by(func.lower(Repository.repo_name)).all()
88
89 repos_data = RepoModel().get_repos_as_dict(repos_list=repos_list,
90 admin=True)
91 #json used to render the grid
92 c.data = json.dumps(repos_data)
93
94 watched_repos_data = []
95
96 ## watched repos
97 _render = RepoModel._render_datatable
98
99 def quick_menu(repo_name):
100 return _render('quick_menu', repo_name)
101
102 def repo_lnk(name, rtype, private, fork_of):
103 return _render('repo_name', name, rtype, private, fork_of,
104 short_name=False, admin=False)
105
106 def last_rev(repo_name, cs_cache):
107 return _render('revision', repo_name, cs_cache.get('revision'),
108 cs_cache.get('raw_id'), cs_cache.get('author'),
109 cs_cache.get('message'))
82
110
83 @LoginRequired()
111 def desc(desc):
84 @NotAnonymous()
112 from pylons import tmpl_context as c
85 def index_my_repos(self):
113 if c.visual.stylify_metatags:
86 c.user = User.get(self.rhodecode_user.user_id)
114 return h.urlify_text(h.desc_stylize(h.truncate(desc, 60)))
87 if request.environ.get('HTTP_X_PARTIAL_XHR'):
115 else:
88 all_repos = self.sa.query(Repository)\
116 return h.urlify_text(h.truncate(desc, 60))
89 .filter(Repository.user_id == c.user.user_id)\
117
90 .order_by(func.lower(Repository.repo_name)).all()
118 def repo_actions(repo_name):
91 c.user_repos = ScmModel().get_repos(all_repos)
119 return _render('repo_actions', repo_name)
92 return render('journal/journal_page_repos.html')
120
121 def owner_actions(user_id, username):
122 return _render('user_name', user_id, username)
123
124 def toogle_follow(repo_id):
125 return _render('toggle_follow', repo_id)
126
127 for entry in c.following:
128 repo = entry.follows_repository
129 cs_cache = repo.changeset_cache
130 row = {
131 "menu": quick_menu(repo.repo_name),
132 "raw_name": repo.repo_name.lower(),
133 "name": repo_lnk(repo.repo_name, repo.repo_type,
134 repo.private, repo.fork),
135 "last_changeset": last_rev(repo.repo_name, cs_cache),
136 "raw_tip": cs_cache.get('revision'),
137 "action": toogle_follow(repo.repo_id)
138 }
139
140 watched_repos_data.append(row)
141
142 c.watched_data = json.dumps({
143 "totalRecords": len(c.following),
144 "startIndex": 0,
145 "sort": "name",
146 "dir": "asc",
147 "records": watched_repos_data
148 })
149 return render('journal/journal.html')
93
150
94 @LoginRequired(api_access=True)
151 @LoginRequired(api_access=True)
95 @NotAnonymous()
152 @NotAnonymous()
96 def journal_atom(self):
153 def journal_atom(self):
97 """
154 """
98 Produce an atom-1.0 feed via feedgenerator module
155 Produce an atom-1.0 feed via feedgenerator module
99 """
156 """
100 following = self.sa.query(UserFollowing)\
157 following = self.sa.query(UserFollowing)\
101 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
158 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
102 .options(joinedload(UserFollowing.follows_repository))\
159 .options(joinedload(UserFollowing.follows_repository))\
103 .all()
160 .all()
104 return self._atom_feed(following, public=False)
161 return self._atom_feed(following, public=False)
105
162
106 @LoginRequired(api_access=True)
163 @LoginRequired(api_access=True)
107 @NotAnonymous()
164 @NotAnonymous()
108 def journal_rss(self):
165 def journal_rss(self):
109 """
166 """
110 Produce an rss feed via feedgenerator module
167 Produce an rss feed via feedgenerator module
111 """
168 """
112 following = self.sa.query(UserFollowing)\
169 following = self.sa.query(UserFollowing)\
113 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
170 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
114 .options(joinedload(UserFollowing.follows_repository))\
171 .options(joinedload(UserFollowing.follows_repository))\
115 .all()
172 .all()
116 return self._rss_feed(following, public=False)
173 return self._rss_feed(following, public=False)
117
174
118 def _get_daily_aggregate(self, journal):
175 def _get_daily_aggregate(self, journal):
119 groups = []
176 groups = []
120 for k, g in groupby(journal, lambda x: x.action_as_day):
177 for k, g in groupby(journal, lambda x: x.action_as_day):
121 user_group = []
178 user_group = []
122 #groupby username if it's a present value, else fallback to journal username
179 #groupby username if it's a present value, else fallback to journal username
123 for _, g2 in groupby(list(g), lambda x: x.user.username if x.user else x.username):
180 for _, g2 in groupby(list(g), lambda x: x.user.username if x.user else x.username):
124 l = list(g2)
181 l = list(g2)
125 user_group.append((l[0].user, l))
182 user_group.append((l[0].user, l))
126
183
127 groups.append((k, user_group,))
184 groups.append((k, user_group,))
128
185
129 return groups
186 return groups
130
187
131 def _get_journal_data(self, following_repos):
188 def _get_journal_data(self, following_repos):
132 repo_ids = [x.follows_repository.repo_id for x in following_repos
189 repo_ids = [x.follows_repository.repo_id for x in following_repos
133 if x.follows_repository is not None]
190 if x.follows_repository is not None]
134 user_ids = [x.follows_user.user_id for x in following_repos
191 user_ids = [x.follows_user.user_id for x in following_repos
135 if x.follows_user is not None]
192 if x.follows_user is not None]
136
193
137 filtering_criterion = None
194 filtering_criterion = None
138
195
139 if repo_ids and user_ids:
196 if repo_ids and user_ids:
140 filtering_criterion = or_(UserLog.repository_id.in_(repo_ids),
197 filtering_criterion = or_(UserLog.repository_id.in_(repo_ids),
141 UserLog.user_id.in_(user_ids))
198 UserLog.user_id.in_(user_ids))
142 if repo_ids and not user_ids:
199 if repo_ids and not user_ids:
143 filtering_criterion = UserLog.repository_id.in_(repo_ids)
200 filtering_criterion = UserLog.repository_id.in_(repo_ids)
144 if not repo_ids and user_ids:
201 if not repo_ids and user_ids:
145 filtering_criterion = UserLog.user_id.in_(user_ids)
202 filtering_criterion = UserLog.user_id.in_(user_ids)
146 if filtering_criterion is not None:
203 if filtering_criterion is not None:
147 journal = self.sa.query(UserLog)\
204 journal = self.sa.query(UserLog)\
148 .options(joinedload(UserLog.user))\
205 .options(joinedload(UserLog.user))\
149 .options(joinedload(UserLog.repository))
206 .options(joinedload(UserLog.repository))
150 #filter
207 #filter
151 try:
208 try:
152 journal = _journal_filter(journal, c.search_term)
209 journal = _journal_filter(journal, c.search_term)
153 except:
210 except:
154 # we want this to crash for now
211 # we want this to crash for now
155 raise
212 raise
156 journal = journal.filter(filtering_criterion)\
213 journal = journal.filter(filtering_criterion)\
157 .order_by(UserLog.action_date.desc())
214 .order_by(UserLog.action_date.desc())
158 else:
215 else:
159 journal = []
216 journal = []
160
217
161 return journal
218 return journal
162
219
163 @LoginRequired()
220 @LoginRequired()
164 @NotAnonymous()
221 @NotAnonymous()
165 def toggle_following(self):
222 def toggle_following(self):
166 cur_token = request.POST.get('auth_token')
223 cur_token = request.POST.get('auth_token')
167 token = h.get_token()
224 token = h.get_token()
168 if cur_token == token:
225 if cur_token == token:
169
226
170 user_id = request.POST.get('follows_user_id')
227 user_id = request.POST.get('follows_user_id')
171 if user_id:
228 if user_id:
172 try:
229 try:
173 self.scm_model.toggle_following_user(user_id,
230 self.scm_model.toggle_following_user(user_id,
174 self.rhodecode_user.user_id)
231 self.rhodecode_user.user_id)
175 Session.commit()
232 Session.commit()
176 return 'ok'
233 return 'ok'
177 except:
234 except:
178 raise HTTPBadRequest()
235 raise HTTPBadRequest()
179
236
180 repo_id = request.POST.get('follows_repo_id')
237 repo_id = request.POST.get('follows_repo_id')
181 if repo_id:
238 if repo_id:
182 try:
239 try:
183 self.scm_model.toggle_following_repo(repo_id,
240 self.scm_model.toggle_following_repo(repo_id,
184 self.rhodecode_user.user_id)
241 self.rhodecode_user.user_id)
185 Session.commit()
242 Session.commit()
186 return 'ok'
243 return 'ok'
187 except:
244 except:
188 raise HTTPBadRequest()
245 raise HTTPBadRequest()
189
246
190 log.debug('token mismatch %s vs %s' % (cur_token, token))
247 log.debug('token mismatch %s vs %s' % (cur_token, token))
191 raise HTTPBadRequest()
248 raise HTTPBadRequest()
192
249
193 @LoginRequired()
250 @LoginRequired()
194 def public_journal(self):
251 def public_journal(self):
195 # Return a rendered template
252 # Return a rendered template
196 p = safe_int(request.params.get('page', 1), 1)
253 p = safe_int(request.params.get('page', 1), 1)
197
254
198 c.following = self.sa.query(UserFollowing)\
255 c.following = self.sa.query(UserFollowing)\
199 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
256 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
200 .options(joinedload(UserFollowing.follows_repository))\
257 .options(joinedload(UserFollowing.follows_repository))\
201 .all()
258 .all()
202
259
203 journal = self._get_journal_data(c.following)
260 journal = self._get_journal_data(c.following)
204
261
205 c.journal_pager = Page(journal, page=p, items_per_page=20)
262 c.journal_pager = Page(journal, page=p, items_per_page=20)
206
263
207 c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager)
264 c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager)
208
265
209 c.journal_data = render('journal/journal_data.html')
266 c.journal_data = render('journal/journal_data.html')
210 if request.environ.get('HTTP_X_PARTIAL_XHR'):
267 if request.environ.get('HTTP_X_PARTIAL_XHR'):
211 return c.journal_data
268 return c.journal_data
212 return render('journal/public_journal.html')
269 return render('journal/public_journal.html')
213
270
214 def _atom_feed(self, repos, public=True):
271 def _atom_feed(self, repos, public=True):
215 journal = self._get_journal_data(repos)
272 journal = self._get_journal_data(repos)
216 if public:
273 if public:
217 _link = url('public_journal_atom', qualified=True)
274 _link = url('public_journal_atom', qualified=True)
218 _desc = '%s %s %s' % (c.rhodecode_name, _('public journal'),
275 _desc = '%s %s %s' % (c.rhodecode_name, _('public journal'),
219 'atom feed')
276 'atom feed')
220 else:
277 else:
221 _link = url('journal_atom', qualified=True)
278 _link = url('journal_atom', qualified=True)
222 _desc = '%s %s %s' % (c.rhodecode_name, _('journal'), 'atom feed')
279 _desc = '%s %s %s' % (c.rhodecode_name, _('journal'), 'atom feed')
223
280
224 feed = Atom1Feed(title=_desc,
281 feed = Atom1Feed(title=_desc,
225 link=_link,
282 link=_link,
226 description=_desc,
283 description=_desc,
227 language=self.language,
284 language=self.language,
228 ttl=self.ttl)
285 ttl=self.ttl)
229
286
230 for entry in journal[:self.feed_nr]:
287 for entry in journal[:self.feed_nr]:
231 user = entry.user
288 user = entry.user
232 if user is None:
289 if user is None:
233 #fix deleted users
290 #fix deleted users
234 user = AttributeDict({'short_contact': entry.username,
291 user = AttributeDict({'short_contact': entry.username,
235 'email': '',
292 'email': '',
236 'full_contact': ''})
293 'full_contact': ''})
237 action, action_extra, ico = h.action_parser(entry, feed=True)
294 action, action_extra, ico = h.action_parser(entry, feed=True)
238 title = "%s - %s %s" % (user.short_contact, action(),
295 title = "%s - %s %s" % (user.short_contact, action(),
239 entry.repository.repo_name)
296 entry.repository.repo_name)
240 desc = action_extra()
297 desc = action_extra()
241 _url = None
298 _url = None
242 if entry.repository is not None:
299 if entry.repository is not None:
243 _url = url('changelog_home',
300 _url = url('changelog_home',
244 repo_name=entry.repository.repo_name,
301 repo_name=entry.repository.repo_name,
245 qualified=True)
302 qualified=True)
246
303
247 feed.add_item(title=title,
304 feed.add_item(title=title,
248 pubdate=entry.action_date,
305 pubdate=entry.action_date,
249 link=_url or url('', qualified=True),
306 link=_url or url('', qualified=True),
250 author_email=user.email,
307 author_email=user.email,
251 author_name=user.full_contact,
308 author_name=user.full_contact,
252 description=desc)
309 description=desc)
253
310
254 response.content_type = feed.mime_type
311 response.content_type = feed.mime_type
255 return feed.writeString('utf-8')
312 return feed.writeString('utf-8')
256
313
257 def _rss_feed(self, repos, public=True):
314 def _rss_feed(self, repos, public=True):
258 journal = self._get_journal_data(repos)
315 journal = self._get_journal_data(repos)
259 if public:
316 if public:
260 _link = url('public_journal_atom', qualified=True)
317 _link = url('public_journal_atom', qualified=True)
261 _desc = '%s %s %s' % (c.rhodecode_name, _('public journal'),
318 _desc = '%s %s %s' % (c.rhodecode_name, _('public journal'),
262 'rss feed')
319 'rss feed')
263 else:
320 else:
264 _link = url('journal_atom', qualified=True)
321 _link = url('journal_atom', qualified=True)
265 _desc = '%s %s %s' % (c.rhodecode_name, _('journal'), 'rss feed')
322 _desc = '%s %s %s' % (c.rhodecode_name, _('journal'), 'rss feed')
266
323
267 feed = Rss201rev2Feed(title=_desc,
324 feed = Rss201rev2Feed(title=_desc,
268 link=_link,
325 link=_link,
269 description=_desc,
326 description=_desc,
270 language=self.language,
327 language=self.language,
271 ttl=self.ttl)
328 ttl=self.ttl)
272
329
273 for entry in journal[:self.feed_nr]:
330 for entry in journal[:self.feed_nr]:
274 user = entry.user
331 user = entry.user
275 if user is None:
332 if user is None:
276 #fix deleted users
333 #fix deleted users
277 user = AttributeDict({'short_contact': entry.username,
334 user = AttributeDict({'short_contact': entry.username,
278 'email': '',
335 'email': '',
279 'full_contact': ''})
336 'full_contact': ''})
280 action, action_extra, ico = h.action_parser(entry, feed=True)
337 action, action_extra, ico = h.action_parser(entry, feed=True)
281 title = "%s - %s %s" % (user.short_contact, action(),
338 title = "%s - %s %s" % (user.short_contact, action(),
282 entry.repository.repo_name)
339 entry.repository.repo_name)
283 desc = action_extra()
340 desc = action_extra()
284 _url = None
341 _url = None
285 if entry.repository is not None:
342 if entry.repository is not None:
286 _url = url('changelog_home',
343 _url = url('changelog_home',
287 repo_name=entry.repository.repo_name,
344 repo_name=entry.repository.repo_name,
288 qualified=True)
345 qualified=True)
289
346
290 feed.add_item(title=title,
347 feed.add_item(title=title,
291 pubdate=entry.action_date,
348 pubdate=entry.action_date,
292 link=_url or url('', qualified=True),
349 link=_url or url('', qualified=True),
293 author_email=user.email,
350 author_email=user.email,
294 author_name=user.full_contact,
351 author_name=user.full_contact,
295 description=desc)
352 description=desc)
296
353
297 response.content_type = feed.mime_type
354 response.content_type = feed.mime_type
298 return feed.writeString('utf-8')
355 return feed.writeString('utf-8')
299
356
300 @LoginRequired(api_access=True)
357 @LoginRequired(api_access=True)
301 def public_journal_atom(self):
358 def public_journal_atom(self):
302 """
359 """
303 Produce an atom-1.0 feed via feedgenerator module
360 Produce an atom-1.0 feed via feedgenerator module
304 """
361 """
305 c.following = self.sa.query(UserFollowing)\
362 c.following = self.sa.query(UserFollowing)\
306 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
363 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
307 .options(joinedload(UserFollowing.follows_repository))\
364 .options(joinedload(UserFollowing.follows_repository))\
308 .all()
365 .all()
309
366
310 return self._atom_feed(c.following)
367 return self._atom_feed(c.following)
311
368
312 @LoginRequired(api_access=True)
369 @LoginRequired(api_access=True)
313 def public_journal_rss(self):
370 def public_journal_rss(self):
314 """
371 """
315 Produce an rss2 feed via feedgenerator module
372 Produce an rss2 feed via feedgenerator module
316 """
373 """
317 c.following = self.sa.query(UserFollowing)\
374 c.following = self.sa.query(UserFollowing)\
318 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
375 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
319 .options(joinedload(UserFollowing.follows_repository))\
376 .options(joinedload(UserFollowing.follows_repository))\
320 .all()
377 .all()
321
378
322 return self._rss_feed(c.following)
379 return self._rss_feed(c.following)
@@ -1,579 +1,669 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.model.repo
3 rhodecode.model.repo
4 ~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~
5
5
6 Repository model for rhodecode
6 Repository model for rhodecode
7
7
8 :created_on: Jun 5, 2010
8 :created_on: Jun 5, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 from __future__ import with_statement
25 from __future__ import with_statement
26 import os
26 import os
27 import shutil
27 import shutil
28 import logging
28 import logging
29 import traceback
29 import traceback
30 from datetime import datetime
30 from datetime import datetime
31
31
32 from rhodecode.lib.vcs.backends import get_backend
32 from rhodecode.lib.vcs.backends import get_backend
33 from rhodecode.lib.compat import json
33 from rhodecode.lib.compat import json
34 from rhodecode.lib.utils2 import LazyProperty, safe_str, safe_unicode,\
34 from rhodecode.lib.utils2 import LazyProperty, safe_str, safe_unicode,\
35 remove_prefix
35 remove_prefix
36 from rhodecode.lib.caching_query import FromCache
36 from rhodecode.lib.caching_query import FromCache
37 from rhodecode.lib.hooks import log_create_repository, log_delete_repository
37 from rhodecode.lib.hooks import log_create_repository, log_delete_repository
38
38
39 from rhodecode.model import BaseModel
39 from rhodecode.model import BaseModel
40 from rhodecode.model.db import Repository, UserRepoToPerm, User, Permission, \
40 from rhodecode.model.db import Repository, UserRepoToPerm, User, Permission, \
41 Statistics, UsersGroup, UsersGroupRepoToPerm, RhodeCodeUi, RepoGroup,\
41 Statistics, UsersGroup, UsersGroupRepoToPerm, RhodeCodeUi, RepoGroup,\
42 RhodeCodeSetting
42 RhodeCodeSetting
43 from rhodecode.lib import helpers as h
43 from rhodecode.lib import helpers as h
44 from rhodecode.lib.auth import HasRepoPermissionAny
44
45
45
46
46 log = logging.getLogger(__name__)
47 log = logging.getLogger(__name__)
47
48
48
49
49 class RepoModel(BaseModel):
50 class RepoModel(BaseModel):
50
51
51 cls = Repository
52 cls = Repository
52 URL_SEPARATOR = Repository.url_sep()
53 URL_SEPARATOR = Repository.url_sep()
53
54
54 def __get_users_group(self, users_group):
55 def __get_users_group(self, users_group):
55 return self._get_instance(UsersGroup, users_group,
56 return self._get_instance(UsersGroup, users_group,
56 callback=UsersGroup.get_by_group_name)
57 callback=UsersGroup.get_by_group_name)
57
58
58 def _get_repos_group(self, repos_group):
59 def _get_repos_group(self, repos_group):
59 return self._get_instance(RepoGroup, repos_group,
60 return self._get_instance(RepoGroup, repos_group,
60 callback=RepoGroup.get_by_group_name)
61 callback=RepoGroup.get_by_group_name)
61
62
62 @LazyProperty
63 @LazyProperty
63 def repos_path(self):
64 def repos_path(self):
64 """
65 """
65 Get's the repositories root path from database
66 Get's the repositories root path from database
66 """
67 """
67
68
68 q = self.sa.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/').one()
69 q = self.sa.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/').one()
69 return q.ui_value
70 return q.ui_value
70
71
71 def get(self, repo_id, cache=False):
72 def get(self, repo_id, cache=False):
72 repo = self.sa.query(Repository)\
73 repo = self.sa.query(Repository)\
73 .filter(Repository.repo_id == repo_id)
74 .filter(Repository.repo_id == repo_id)
74
75
75 if cache:
76 if cache:
76 repo = repo.options(FromCache("sql_cache_short",
77 repo = repo.options(FromCache("sql_cache_short",
77 "get_repo_%s" % repo_id))
78 "get_repo_%s" % repo_id))
78 return repo.scalar()
79 return repo.scalar()
79
80
80 def get_repo(self, repository):
81 def get_repo(self, repository):
81 return self._get_repo(repository)
82 return self._get_repo(repository)
82
83
83 def get_by_repo_name(self, repo_name, cache=False):
84 def get_by_repo_name(self, repo_name, cache=False):
84 repo = self.sa.query(Repository)\
85 repo = self.sa.query(Repository)\
85 .filter(Repository.repo_name == repo_name)
86 .filter(Repository.repo_name == repo_name)
86
87
87 if cache:
88 if cache:
88 repo = repo.options(FromCache("sql_cache_short",
89 repo = repo.options(FromCache("sql_cache_short",
89 "get_repo_%s" % repo_name))
90 "get_repo_%s" % repo_name))
90 return repo.scalar()
91 return repo.scalar()
91
92
92 def get_users_js(self):
93 def get_users_js(self):
93 users = self.sa.query(User).filter(User.active == True).all()
94 users = self.sa.query(User).filter(User.active == True).all()
94 return json.dumps([
95 return json.dumps([
95 {
96 {
96 'id': u.user_id,
97 'id': u.user_id,
97 'fname': u.name,
98 'fname': u.name,
98 'lname': u.lastname,
99 'lname': u.lastname,
99 'nname': u.username,
100 'nname': u.username,
100 'gravatar_lnk': h.gravatar_url(u.email, 14)
101 'gravatar_lnk': h.gravatar_url(u.email, 14)
101 } for u in users]
102 } for u in users]
102 )
103 )
103
104
104 def get_users_groups_js(self):
105 def get_users_groups_js(self):
105 users_groups = self.sa.query(UsersGroup)\
106 users_groups = self.sa.query(UsersGroup)\
106 .filter(UsersGroup.users_group_active == True).all()
107 .filter(UsersGroup.users_group_active == True).all()
107
108
108 return json.dumps([
109 return json.dumps([
109 {
110 {
110 'id': gr.users_group_id,
111 'id': gr.users_group_id,
111 'grname': gr.users_group_name,
112 'grname': gr.users_group_name,
112 'grmembers': len(gr.members),
113 'grmembers': len(gr.members),
113 } for gr in users_groups]
114 } for gr in users_groups]
114 )
115 )
115
116
117 @classmethod
118 def _render_datatable(cls, tmpl, *args, **kwargs):
119 import rhodecode
120 from pylons import tmpl_context as c
121 from pylons.i18n.translation import _
122
123 _tmpl_lookup = rhodecode.CONFIG['pylons.app_globals'].mako_lookup
124 template = _tmpl_lookup.get_template('data_table/_dt_elements.html')
125
126 tmpl = template.get_def(tmpl)
127 kwargs.update(dict(_=_, h=h, c=c))
128 return tmpl.render(*args, **kwargs)
129
130 def get_repos_as_dict(self, repos_list=None, admin=False, perm_check=True):
131 _render = self._render_datatable
132
133 def quick_menu(repo_name):
134 return _render('quick_menu', repo_name)
135
136 def repo_lnk(name, rtype, private, fork_of):
137 return _render('repo_name', name, rtype, private, fork_of,
138 short_name=not admin, admin=False)
139
140 def last_change(last_change):
141 return _render("last_change", last_change)
142
143 def rss_lnk(repo_name):
144 return _render("rss", repo_name)
145
146 def atom_lnk(repo_name):
147 return _render("atom", repo_name)
148
149 def last_rev(repo_name, cs_cache):
150 return _render('revision', repo_name, cs_cache.get('revision'),
151 cs_cache.get('raw_id'), cs_cache.get('author'),
152 cs_cache.get('message'))
153
154 def desc(desc):
155 from pylons import tmpl_context as c
156 if c.visual.stylify_metatags:
157 return h.urlify_text(h.desc_stylize(h.truncate(desc, 60)))
158 else:
159 return h.urlify_text(h.truncate(desc, 60))
160
161 def repo_actions(repo_name):
162 return _render('repo_actions', repo_name)
163
164 def owner_actions(user_id, username):
165 return _render('user_name', user_id, username)
166
167 repos_data = []
168 for repo in repos_list:
169 if perm_check:
170 # check permission at this level
171 if not HasRepoPermissionAny(
172 'repository.read', 'repository.write', 'repository.admin'
173 )(repo.repo_name, 'get_repos_as_dict check'):
174 continue
175 cs_cache = repo.changeset_cache
176 row = {
177 "menu": quick_menu(repo.repo_name),
178 "raw_name": repo.repo_name.lower(),
179 "name": repo_lnk(repo.repo_name, repo.repo_type,
180 repo.private, repo.fork),
181 "last_change": last_change(repo.last_db_change),
182 "last_changeset": last_rev(repo.repo_name, cs_cache),
183 "raw_tip": cs_cache.get('revision'),
184 "desc": desc(repo.description),
185 "owner": h.person(repo.user.username),
186 "rss": rss_lnk(repo.repo_name),
187 "atom": atom_lnk(repo.repo_name),
188
189 }
190 if admin:
191 row.update({
192 "action": repo_actions(repo.repo_name),
193 "owner": owner_actions(repo.user.user_id,
194 h.person(repo.user.username))
195 })
196 repos_data.append(row)
197
198 return {
199 "totalRecords": len(repos_list),
200 "startIndex": 0,
201 "sort": "name",
202 "dir": "asc",
203 "records": repos_data
204 }
205
116 def _get_defaults(self, repo_name):
206 def _get_defaults(self, repo_name):
117 """
207 """
118 Get's information about repository, and returns a dict for
208 Get's information about repository, and returns a dict for
119 usage in forms
209 usage in forms
120
210
121 :param repo_name:
211 :param repo_name:
122 """
212 """
123
213
124 repo_info = Repository.get_by_repo_name(repo_name)
214 repo_info = Repository.get_by_repo_name(repo_name)
125
215
126 if repo_info is None:
216 if repo_info is None:
127 return None
217 return None
128
218
129 defaults = repo_info.get_dict()
219 defaults = repo_info.get_dict()
130 group, repo_name = repo_info.groups_and_repo
220 group, repo_name = repo_info.groups_and_repo
131 defaults['repo_name'] = repo_name
221 defaults['repo_name'] = repo_name
132 defaults['repo_group'] = getattr(group[-1] if group else None,
222 defaults['repo_group'] = getattr(group[-1] if group else None,
133 'group_id', None)
223 'group_id', None)
134
224
135 for strip, k in [(0, 'repo_type'), (1, 'repo_enable_downloads'),
225 for strip, k in [(0, 'repo_type'), (1, 'repo_enable_downloads'),
136 (1, 'repo_description'), (1, 'repo_enable_locking'),
226 (1, 'repo_description'), (1, 'repo_enable_locking'),
137 (1, 'repo_landing_rev'), (0, 'clone_uri'),
227 (1, 'repo_landing_rev'), (0, 'clone_uri'),
138 (1, 'repo_private'), (1, 'repo_enable_statistics')]:
228 (1, 'repo_private'), (1, 'repo_enable_statistics')]:
139 attr = k
229 attr = k
140 if strip:
230 if strip:
141 attr = remove_prefix(k, 'repo_')
231 attr = remove_prefix(k, 'repo_')
142
232
143 defaults[k] = defaults[attr]
233 defaults[k] = defaults[attr]
144
234
145 # fill owner
235 # fill owner
146 if repo_info.user:
236 if repo_info.user:
147 defaults.update({'user': repo_info.user.username})
237 defaults.update({'user': repo_info.user.username})
148 else:
238 else:
149 replacement_user = User.query().filter(User.admin ==
239 replacement_user = User.query().filter(User.admin ==
150 True).first().username
240 True).first().username
151 defaults.update({'user': replacement_user})
241 defaults.update({'user': replacement_user})
152
242
153 # fill repository users
243 # fill repository users
154 for p in repo_info.repo_to_perm:
244 for p in repo_info.repo_to_perm:
155 defaults.update({'u_perm_%s' % p.user.username:
245 defaults.update({'u_perm_%s' % p.user.username:
156 p.permission.permission_name})
246 p.permission.permission_name})
157
247
158 # fill repository groups
248 # fill repository groups
159 for p in repo_info.users_group_to_perm:
249 for p in repo_info.users_group_to_perm:
160 defaults.update({'g_perm_%s' % p.users_group.users_group_name:
250 defaults.update({'g_perm_%s' % p.users_group.users_group_name:
161 p.permission.permission_name})
251 p.permission.permission_name})
162
252
163 return defaults
253 return defaults
164
254
165 def update(self, org_repo_name, **kwargs):
255 def update(self, org_repo_name, **kwargs):
166 try:
256 try:
167 cur_repo = self.get_by_repo_name(org_repo_name, cache=False)
257 cur_repo = self.get_by_repo_name(org_repo_name, cache=False)
168
258
169 # update permissions
259 # update permissions
170 for member, perm, member_type in kwargs['perms_updates']:
260 for member, perm, member_type in kwargs['perms_updates']:
171 if member_type == 'user':
261 if member_type == 'user':
172 # this updates existing one
262 # this updates existing one
173 RepoModel().grant_user_permission(
263 RepoModel().grant_user_permission(
174 repo=cur_repo, user=member, perm=perm
264 repo=cur_repo, user=member, perm=perm
175 )
265 )
176 else:
266 else:
177 RepoModel().grant_users_group_permission(
267 RepoModel().grant_users_group_permission(
178 repo=cur_repo, group_name=member, perm=perm
268 repo=cur_repo, group_name=member, perm=perm
179 )
269 )
180 # set new permissions
270 # set new permissions
181 for member, perm, member_type in kwargs['perms_new']:
271 for member, perm, member_type in kwargs['perms_new']:
182 if member_type == 'user':
272 if member_type == 'user':
183 RepoModel().grant_user_permission(
273 RepoModel().grant_user_permission(
184 repo=cur_repo, user=member, perm=perm
274 repo=cur_repo, user=member, perm=perm
185 )
275 )
186 else:
276 else:
187 RepoModel().grant_users_group_permission(
277 RepoModel().grant_users_group_permission(
188 repo=cur_repo, group_name=member, perm=perm
278 repo=cur_repo, group_name=member, perm=perm
189 )
279 )
190
280
191 if 'user' in kwargs:
281 if 'user' in kwargs:
192 cur_repo.user = User.get_by_username(kwargs['user'])
282 cur_repo.user = User.get_by_username(kwargs['user'])
193
283
194 if 'repo_group' in kwargs:
284 if 'repo_group' in kwargs:
195 cur_repo.group = RepoGroup.get(kwargs['repo_group'])
285 cur_repo.group = RepoGroup.get(kwargs['repo_group'])
196
286
197 for strip, k in [(0, 'repo_type'), (1, 'repo_enable_downloads'),
287 for strip, k in [(0, 'repo_type'), (1, 'repo_enable_downloads'),
198 (1, 'repo_description'), (1, 'repo_enable_locking'),
288 (1, 'repo_description'), (1, 'repo_enable_locking'),
199 (1, 'repo_landing_rev'), (0, 'clone_uri'),
289 (1, 'repo_landing_rev'), (0, 'clone_uri'),
200 (1, 'repo_private'), (1, 'repo_enable_statistics')]:
290 (1, 'repo_private'), (1, 'repo_enable_statistics')]:
201 if k in kwargs:
291 if k in kwargs:
202 val = kwargs[k]
292 val = kwargs[k]
203 if strip:
293 if strip:
204 k = remove_prefix(k, 'repo_')
294 k = remove_prefix(k, 'repo_')
205 setattr(cur_repo, k, val)
295 setattr(cur_repo, k, val)
206
296
207 new_name = cur_repo.get_new_name(kwargs['repo_name'])
297 new_name = cur_repo.get_new_name(kwargs['repo_name'])
208 cur_repo.repo_name = new_name
298 cur_repo.repo_name = new_name
209
299
210 self.sa.add(cur_repo)
300 self.sa.add(cur_repo)
211
301
212 if org_repo_name != new_name:
302 if org_repo_name != new_name:
213 # rename repository
303 # rename repository
214 self.__rename_repo(old=org_repo_name, new=new_name)
304 self.__rename_repo(old=org_repo_name, new=new_name)
215
305
216 return cur_repo
306 return cur_repo
217 except:
307 except:
218 log.error(traceback.format_exc())
308 log.error(traceback.format_exc())
219 raise
309 raise
220
310
221 def create_repo(self, repo_name, repo_type, description, owner,
311 def create_repo(self, repo_name, repo_type, description, owner,
222 private=False, clone_uri=None, repos_group=None,
312 private=False, clone_uri=None, repos_group=None,
223 landing_rev='tip', just_db=False, fork_of=None,
313 landing_rev='tip', just_db=False, fork_of=None,
224 copy_fork_permissions=False, enable_statistics=False,
314 copy_fork_permissions=False, enable_statistics=False,
225 enable_locking=False, enable_downloads=False):
315 enable_locking=False, enable_downloads=False):
226 """
316 """
227 Create repository
317 Create repository
228
318
229 """
319 """
230 from rhodecode.model.scm import ScmModel
320 from rhodecode.model.scm import ScmModel
231
321
232 owner = self._get_user(owner)
322 owner = self._get_user(owner)
233 fork_of = self._get_repo(fork_of)
323 fork_of = self._get_repo(fork_of)
234 repos_group = self._get_repos_group(repos_group)
324 repos_group = self._get_repos_group(repos_group)
235 try:
325 try:
236
326
237 # repo name is just a name of repository
327 # repo name is just a name of repository
238 # while repo_name_full is a full qualified name that is combined
328 # while repo_name_full is a full qualified name that is combined
239 # with name and path of group
329 # with name and path of group
240 repo_name_full = repo_name
330 repo_name_full = repo_name
241 repo_name = repo_name.split(self.URL_SEPARATOR)[-1]
331 repo_name = repo_name.split(self.URL_SEPARATOR)[-1]
242
332
243 new_repo = Repository()
333 new_repo = Repository()
244 new_repo.enable_statistics = False
334 new_repo.enable_statistics = False
245 new_repo.repo_name = repo_name_full
335 new_repo.repo_name = repo_name_full
246 new_repo.repo_type = repo_type
336 new_repo.repo_type = repo_type
247 new_repo.user = owner
337 new_repo.user = owner
248 new_repo.group = repos_group
338 new_repo.group = repos_group
249 new_repo.description = description or repo_name
339 new_repo.description = description or repo_name
250 new_repo.private = private
340 new_repo.private = private
251 new_repo.clone_uri = clone_uri
341 new_repo.clone_uri = clone_uri
252 new_repo.landing_rev = landing_rev
342 new_repo.landing_rev = landing_rev
253
343
254 new_repo.enable_statistics = enable_statistics
344 new_repo.enable_statistics = enable_statistics
255 new_repo.enable_locking = enable_locking
345 new_repo.enable_locking = enable_locking
256 new_repo.enable_downloads = enable_downloads
346 new_repo.enable_downloads = enable_downloads
257
347
258 if repos_group:
348 if repos_group:
259 new_repo.enable_locking = repos_group.enable_locking
349 new_repo.enable_locking = repos_group.enable_locking
260
350
261 if fork_of:
351 if fork_of:
262 parent_repo = fork_of
352 parent_repo = fork_of
263 new_repo.fork = parent_repo
353 new_repo.fork = parent_repo
264
354
265 self.sa.add(new_repo)
355 self.sa.add(new_repo)
266
356
267 def _create_default_perms():
357 def _create_default_perms():
268 # create default permission
358 # create default permission
269 repo_to_perm = UserRepoToPerm()
359 repo_to_perm = UserRepoToPerm()
270 default = 'repository.read'
360 default = 'repository.read'
271 for p in User.get_by_username('default').user_perms:
361 for p in User.get_by_username('default').user_perms:
272 if p.permission.permission_name.startswith('repository.'):
362 if p.permission.permission_name.startswith('repository.'):
273 default = p.permission.permission_name
363 default = p.permission.permission_name
274 break
364 break
275
365
276 default_perm = 'repository.none' if private else default
366 default_perm = 'repository.none' if private else default
277
367
278 repo_to_perm.permission_id = self.sa.query(Permission)\
368 repo_to_perm.permission_id = self.sa.query(Permission)\
279 .filter(Permission.permission_name == default_perm)\
369 .filter(Permission.permission_name == default_perm)\
280 .one().permission_id
370 .one().permission_id
281
371
282 repo_to_perm.repository = new_repo
372 repo_to_perm.repository = new_repo
283 repo_to_perm.user_id = User.get_by_username('default').user_id
373 repo_to_perm.user_id = User.get_by_username('default').user_id
284
374
285 self.sa.add(repo_to_perm)
375 self.sa.add(repo_to_perm)
286
376
287 if fork_of:
377 if fork_of:
288 if copy_fork_permissions:
378 if copy_fork_permissions:
289 repo = fork_of
379 repo = fork_of
290 user_perms = UserRepoToPerm.query()\
380 user_perms = UserRepoToPerm.query()\
291 .filter(UserRepoToPerm.repository == repo).all()
381 .filter(UserRepoToPerm.repository == repo).all()
292 group_perms = UsersGroupRepoToPerm.query()\
382 group_perms = UsersGroupRepoToPerm.query()\
293 .filter(UsersGroupRepoToPerm.repository == repo).all()
383 .filter(UsersGroupRepoToPerm.repository == repo).all()
294
384
295 for perm in user_perms:
385 for perm in user_perms:
296 UserRepoToPerm.create(perm.user, new_repo,
386 UserRepoToPerm.create(perm.user, new_repo,
297 perm.permission)
387 perm.permission)
298
388
299 for perm in group_perms:
389 for perm in group_perms:
300 UsersGroupRepoToPerm.create(perm.users_group, new_repo,
390 UsersGroupRepoToPerm.create(perm.users_group, new_repo,
301 perm.permission)
391 perm.permission)
302 else:
392 else:
303 _create_default_perms()
393 _create_default_perms()
304 else:
394 else:
305 _create_default_perms()
395 _create_default_perms()
306
396
307 if not just_db:
397 if not just_db:
308 self.__create_repo(repo_name, repo_type,
398 self.__create_repo(repo_name, repo_type,
309 repos_group,
399 repos_group,
310 clone_uri)
400 clone_uri)
311 log_create_repository(new_repo.get_dict(),
401 log_create_repository(new_repo.get_dict(),
312 created_by=owner.username)
402 created_by=owner.username)
313
403
314 # now automatically start following this repository as owner
404 # now automatically start following this repository as owner
315 ScmModel(self.sa).toggle_following_repo(new_repo.repo_id,
405 ScmModel(self.sa).toggle_following_repo(new_repo.repo_id,
316 owner.user_id)
406 owner.user_id)
317 return new_repo
407 return new_repo
318 except:
408 except:
319 log.error(traceback.format_exc())
409 log.error(traceback.format_exc())
320 raise
410 raise
321
411
322 def create(self, form_data, cur_user, just_db=False, fork=None):
412 def create(self, form_data, cur_user, just_db=False, fork=None):
323 """
413 """
324 Backward compatibility function, just a wrapper on top of create_repo
414 Backward compatibility function, just a wrapper on top of create_repo
325
415
326 :param form_data:
416 :param form_data:
327 :param cur_user:
417 :param cur_user:
328 :param just_db:
418 :param just_db:
329 :param fork:
419 :param fork:
330 """
420 """
331 owner = cur_user
421 owner = cur_user
332 repo_name = form_data['repo_name_full']
422 repo_name = form_data['repo_name_full']
333 repo_type = form_data['repo_type']
423 repo_type = form_data['repo_type']
334 description = form_data['repo_description']
424 description = form_data['repo_description']
335 private = form_data['repo_private']
425 private = form_data['repo_private']
336 clone_uri = form_data.get('clone_uri')
426 clone_uri = form_data.get('clone_uri')
337 repos_group = form_data['repo_group']
427 repos_group = form_data['repo_group']
338 landing_rev = form_data['repo_landing_rev']
428 landing_rev = form_data['repo_landing_rev']
339 copy_fork_permissions = form_data.get('copy_permissions')
429 copy_fork_permissions = form_data.get('copy_permissions')
340 fork_of = form_data.get('fork_parent_id')
430 fork_of = form_data.get('fork_parent_id')
341
431
342 ## repo creation defaults, private and repo_type are filled in form
432 ## repo creation defaults, private and repo_type are filled in form
343 defs = RhodeCodeSetting.get_default_repo_settings(strip_prefix=True)
433 defs = RhodeCodeSetting.get_default_repo_settings(strip_prefix=True)
344 enable_statistics = defs.get('repo_enable_statistics')
434 enable_statistics = defs.get('repo_enable_statistics')
345 enable_locking = defs.get('repo_enable_locking')
435 enable_locking = defs.get('repo_enable_locking')
346 enable_downloads = defs.get('repo_enable_downloads')
436 enable_downloads = defs.get('repo_enable_downloads')
347
437
348 return self.create_repo(
438 return self.create_repo(
349 repo_name, repo_type, description, owner, private, clone_uri,
439 repo_name, repo_type, description, owner, private, clone_uri,
350 repos_group, landing_rev, just_db, fork_of, copy_fork_permissions,
440 repos_group, landing_rev, just_db, fork_of, copy_fork_permissions,
351 enable_statistics, enable_locking, enable_downloads
441 enable_statistics, enable_locking, enable_downloads
352 )
442 )
353
443
354 def create_fork(self, form_data, cur_user):
444 def create_fork(self, form_data, cur_user):
355 """
445 """
356 Simple wrapper into executing celery task for fork creation
446 Simple wrapper into executing celery task for fork creation
357
447
358 :param form_data:
448 :param form_data:
359 :param cur_user:
449 :param cur_user:
360 """
450 """
361 from rhodecode.lib.celerylib import tasks, run_task
451 from rhodecode.lib.celerylib import tasks, run_task
362 run_task(tasks.create_repo_fork, form_data, cur_user)
452 run_task(tasks.create_repo_fork, form_data, cur_user)
363
453
364 def delete(self, repo):
454 def delete(self, repo):
365 repo = self._get_repo(repo)
455 repo = self._get_repo(repo)
366 if repo:
456 if repo:
367 old_repo_dict = repo.get_dict()
457 old_repo_dict = repo.get_dict()
368 owner = repo.user
458 owner = repo.user
369 try:
459 try:
370 self.sa.delete(repo)
460 self.sa.delete(repo)
371 self.__delete_repo(repo)
461 self.__delete_repo(repo)
372 log_delete_repository(old_repo_dict,
462 log_delete_repository(old_repo_dict,
373 deleted_by=owner.username)
463 deleted_by=owner.username)
374 except:
464 except:
375 log.error(traceback.format_exc())
465 log.error(traceback.format_exc())
376 raise
466 raise
377
467
378 def grant_user_permission(self, repo, user, perm):
468 def grant_user_permission(self, repo, user, perm):
379 """
469 """
380 Grant permission for user on given repository, or update existing one
470 Grant permission for user on given repository, or update existing one
381 if found
471 if found
382
472
383 :param repo: Instance of Repository, repository_id, or repository name
473 :param repo: Instance of Repository, repository_id, or repository name
384 :param user: Instance of User, user_id or username
474 :param user: Instance of User, user_id or username
385 :param perm: Instance of Permission, or permission_name
475 :param perm: Instance of Permission, or permission_name
386 """
476 """
387 user = self._get_user(user)
477 user = self._get_user(user)
388 repo = self._get_repo(repo)
478 repo = self._get_repo(repo)
389 permission = self._get_perm(perm)
479 permission = self._get_perm(perm)
390
480
391 # check if we have that permission already
481 # check if we have that permission already
392 obj = self.sa.query(UserRepoToPerm)\
482 obj = self.sa.query(UserRepoToPerm)\
393 .filter(UserRepoToPerm.user == user)\
483 .filter(UserRepoToPerm.user == user)\
394 .filter(UserRepoToPerm.repository == repo)\
484 .filter(UserRepoToPerm.repository == repo)\
395 .scalar()
485 .scalar()
396 if obj is None:
486 if obj is None:
397 # create new !
487 # create new !
398 obj = UserRepoToPerm()
488 obj = UserRepoToPerm()
399 obj.repository = repo
489 obj.repository = repo
400 obj.user = user
490 obj.user = user
401 obj.permission = permission
491 obj.permission = permission
402 self.sa.add(obj)
492 self.sa.add(obj)
403 log.debug('Granted perm %s to %s on %s' % (perm, user, repo))
493 log.debug('Granted perm %s to %s on %s' % (perm, user, repo))
404
494
405 def revoke_user_permission(self, repo, user):
495 def revoke_user_permission(self, repo, user):
406 """
496 """
407 Revoke permission for user on given repository
497 Revoke permission for user on given repository
408
498
409 :param repo: Instance of Repository, repository_id, or repository name
499 :param repo: Instance of Repository, repository_id, or repository name
410 :param user: Instance of User, user_id or username
500 :param user: Instance of User, user_id or username
411 """
501 """
412
502
413 user = self._get_user(user)
503 user = self._get_user(user)
414 repo = self._get_repo(repo)
504 repo = self._get_repo(repo)
415
505
416 obj = self.sa.query(UserRepoToPerm)\
506 obj = self.sa.query(UserRepoToPerm)\
417 .filter(UserRepoToPerm.repository == repo)\
507 .filter(UserRepoToPerm.repository == repo)\
418 .filter(UserRepoToPerm.user == user)\
508 .filter(UserRepoToPerm.user == user)\
419 .scalar()
509 .scalar()
420 if obj:
510 if obj:
421 self.sa.delete(obj)
511 self.sa.delete(obj)
422 log.debug('Revoked perm on %s on %s' % (repo, user))
512 log.debug('Revoked perm on %s on %s' % (repo, user))
423
513
424 def grant_users_group_permission(self, repo, group_name, perm):
514 def grant_users_group_permission(self, repo, group_name, perm):
425 """
515 """
426 Grant permission for users group on given repository, or update
516 Grant permission for users group on given repository, or update
427 existing one if found
517 existing one if found
428
518
429 :param repo: Instance of Repository, repository_id, or repository name
519 :param repo: Instance of Repository, repository_id, or repository name
430 :param group_name: Instance of UserGroup, users_group_id,
520 :param group_name: Instance of UserGroup, users_group_id,
431 or users group name
521 or users group name
432 :param perm: Instance of Permission, or permission_name
522 :param perm: Instance of Permission, or permission_name
433 """
523 """
434 repo = self._get_repo(repo)
524 repo = self._get_repo(repo)
435 group_name = self.__get_users_group(group_name)
525 group_name = self.__get_users_group(group_name)
436 permission = self._get_perm(perm)
526 permission = self._get_perm(perm)
437
527
438 # check if we have that permission already
528 # check if we have that permission already
439 obj = self.sa.query(UsersGroupRepoToPerm)\
529 obj = self.sa.query(UsersGroupRepoToPerm)\
440 .filter(UsersGroupRepoToPerm.users_group == group_name)\
530 .filter(UsersGroupRepoToPerm.users_group == group_name)\
441 .filter(UsersGroupRepoToPerm.repository == repo)\
531 .filter(UsersGroupRepoToPerm.repository == repo)\
442 .scalar()
532 .scalar()
443
533
444 if obj is None:
534 if obj is None:
445 # create new
535 # create new
446 obj = UsersGroupRepoToPerm()
536 obj = UsersGroupRepoToPerm()
447
537
448 obj.repository = repo
538 obj.repository = repo
449 obj.users_group = group_name
539 obj.users_group = group_name
450 obj.permission = permission
540 obj.permission = permission
451 self.sa.add(obj)
541 self.sa.add(obj)
452 log.debug('Granted perm %s to %s on %s' % (perm, group_name, repo))
542 log.debug('Granted perm %s to %s on %s' % (perm, group_name, repo))
453
543
454 def revoke_users_group_permission(self, repo, group_name):
544 def revoke_users_group_permission(self, repo, group_name):
455 """
545 """
456 Revoke permission for users group on given repository
546 Revoke permission for users group on given repository
457
547
458 :param repo: Instance of Repository, repository_id, or repository name
548 :param repo: Instance of Repository, repository_id, or repository name
459 :param group_name: Instance of UserGroup, users_group_id,
549 :param group_name: Instance of UserGroup, users_group_id,
460 or users group name
550 or users group name
461 """
551 """
462 repo = self._get_repo(repo)
552 repo = self._get_repo(repo)
463 group_name = self.__get_users_group(group_name)
553 group_name = self.__get_users_group(group_name)
464
554
465 obj = self.sa.query(UsersGroupRepoToPerm)\
555 obj = self.sa.query(UsersGroupRepoToPerm)\
466 .filter(UsersGroupRepoToPerm.repository == repo)\
556 .filter(UsersGroupRepoToPerm.repository == repo)\
467 .filter(UsersGroupRepoToPerm.users_group == group_name)\
557 .filter(UsersGroupRepoToPerm.users_group == group_name)\
468 .scalar()
558 .scalar()
469 if obj:
559 if obj:
470 self.sa.delete(obj)
560 self.sa.delete(obj)
471 log.debug('Revoked perm to %s on %s' % (repo, group_name))
561 log.debug('Revoked perm to %s on %s' % (repo, group_name))
472
562
473 def delete_stats(self, repo_name):
563 def delete_stats(self, repo_name):
474 """
564 """
475 removes stats for given repo
565 removes stats for given repo
476
566
477 :param repo_name:
567 :param repo_name:
478 """
568 """
479 try:
569 try:
480 obj = self.sa.query(Statistics)\
570 obj = self.sa.query(Statistics)\
481 .filter(Statistics.repository ==
571 .filter(Statistics.repository ==
482 self.get_by_repo_name(repo_name))\
572 self.get_by_repo_name(repo_name))\
483 .one()
573 .one()
484 self.sa.delete(obj)
574 self.sa.delete(obj)
485 except:
575 except:
486 log.error(traceback.format_exc())
576 log.error(traceback.format_exc())
487 raise
577 raise
488
578
489 def __create_repo(self, repo_name, alias, parent, clone_uri=False):
579 def __create_repo(self, repo_name, alias, parent, clone_uri=False):
490 """
580 """
491 makes repository on filesystem. It's group aware means it'll create
581 makes repository on filesystem. It's group aware means it'll create
492 a repository within a group, and alter the paths accordingly of
582 a repository within a group, and alter the paths accordingly of
493 group location
583 group location
494
584
495 :param repo_name:
585 :param repo_name:
496 :param alias:
586 :param alias:
497 :param parent_id:
587 :param parent_id:
498 :param clone_uri:
588 :param clone_uri:
499 """
589 """
500 from rhodecode.lib.utils import is_valid_repo, is_valid_repos_group
590 from rhodecode.lib.utils import is_valid_repo, is_valid_repos_group
501 from rhodecode.model.scm import ScmModel
591 from rhodecode.model.scm import ScmModel
502
592
503 if parent:
593 if parent:
504 new_parent_path = os.sep.join(parent.full_path_splitted)
594 new_parent_path = os.sep.join(parent.full_path_splitted)
505 else:
595 else:
506 new_parent_path = ''
596 new_parent_path = ''
507
597
508 # we need to make it str for mercurial
598 # we need to make it str for mercurial
509 repo_path = os.path.join(*map(lambda x: safe_str(x),
599 repo_path = os.path.join(*map(lambda x: safe_str(x),
510 [self.repos_path, new_parent_path, repo_name]))
600 [self.repos_path, new_parent_path, repo_name]))
511
601
512 # check if this path is not a repository
602 # check if this path is not a repository
513 if is_valid_repo(repo_path, self.repos_path):
603 if is_valid_repo(repo_path, self.repos_path):
514 raise Exception('This path %s is a valid repository' % repo_path)
604 raise Exception('This path %s is a valid repository' % repo_path)
515
605
516 # check if this path is a group
606 # check if this path is a group
517 if is_valid_repos_group(repo_path, self.repos_path):
607 if is_valid_repos_group(repo_path, self.repos_path):
518 raise Exception('This path %s is a valid group' % repo_path)
608 raise Exception('This path %s is a valid group' % repo_path)
519
609
520 log.info('creating repo %s in %s @ %s' % (
610 log.info('creating repo %s in %s @ %s' % (
521 repo_name, safe_unicode(repo_path), clone_uri
611 repo_name, safe_unicode(repo_path), clone_uri
522 )
612 )
523 )
613 )
524 backend = get_backend(alias)
614 backend = get_backend(alias)
525 if alias == 'hg':
615 if alias == 'hg':
526 backend(repo_path, create=True, src_url=clone_uri)
616 backend(repo_path, create=True, src_url=clone_uri)
527 elif alias == 'git':
617 elif alias == 'git':
528 r = backend(repo_path, create=True, src_url=clone_uri, bare=True)
618 r = backend(repo_path, create=True, src_url=clone_uri, bare=True)
529 # add rhodecode hook into this repo
619 # add rhodecode hook into this repo
530 ScmModel().install_git_hook(repo=r)
620 ScmModel().install_git_hook(repo=r)
531 else:
621 else:
532 raise Exception('Undefined alias %s' % alias)
622 raise Exception('Undefined alias %s' % alias)
533
623
534 def __rename_repo(self, old, new):
624 def __rename_repo(self, old, new):
535 """
625 """
536 renames repository on filesystem
626 renames repository on filesystem
537
627
538 :param old: old name
628 :param old: old name
539 :param new: new name
629 :param new: new name
540 """
630 """
541 log.info('renaming repo from %s to %s' % (old, new))
631 log.info('renaming repo from %s to %s' % (old, new))
542
632
543 old_path = os.path.join(self.repos_path, old)
633 old_path = os.path.join(self.repos_path, old)
544 new_path = os.path.join(self.repos_path, new)
634 new_path = os.path.join(self.repos_path, new)
545 if os.path.isdir(new_path):
635 if os.path.isdir(new_path):
546 raise Exception(
636 raise Exception(
547 'Was trying to rename to already existing dir %s' % new_path
637 'Was trying to rename to already existing dir %s' % new_path
548 )
638 )
549 shutil.move(old_path, new_path)
639 shutil.move(old_path, new_path)
550
640
551 def __delete_repo(self, repo):
641 def __delete_repo(self, repo):
552 """
642 """
553 removes repo from filesystem, the removal is acctually made by
643 removes repo from filesystem, the removal is acctually made by
554 added rm__ prefix into dir, and rename internat .hg/.git dirs so this
644 added rm__ prefix into dir, and rename internat .hg/.git dirs so this
555 repository is no longer valid for rhodecode, can be undeleted later on
645 repository is no longer valid for rhodecode, can be undeleted later on
556 by reverting the renames on this repository
646 by reverting the renames on this repository
557
647
558 :param repo: repo object
648 :param repo: repo object
559 """
649 """
560 rm_path = os.path.join(self.repos_path, repo.repo_name)
650 rm_path = os.path.join(self.repos_path, repo.repo_name)
561 log.info("Removing %s" % (rm_path))
651 log.info("Removing %s" % (rm_path))
562 # disable hg/git internal that it doesn't get detected as repo
652 # disable hg/git internal that it doesn't get detected as repo
563 alias = repo.repo_type
653 alias = repo.repo_type
564
654
565 bare = getattr(repo.scm_instance, 'bare', False)
655 bare = getattr(repo.scm_instance, 'bare', False)
566
656
567 if not bare:
657 if not bare:
568 # skip this for bare git repos
658 # skip this for bare git repos
569 shutil.move(os.path.join(rm_path, '.%s' % alias),
659 shutil.move(os.path.join(rm_path, '.%s' % alias),
570 os.path.join(rm_path, 'rm__.%s' % alias))
660 os.path.join(rm_path, 'rm__.%s' % alias))
571 # disable repo
661 # disable repo
572 _now = datetime.now()
662 _now = datetime.now()
573 _ms = str(_now.microsecond).rjust(6, '0')
663 _ms = str(_now.microsecond).rjust(6, '0')
574 _d = 'rm__%s__%s' % (_now.strftime('%Y%m%d_%H%M%S_' + _ms),
664 _d = 'rm__%s__%s' % (_now.strftime('%Y%m%d_%H%M%S_' + _ms),
575 repo.just_name)
665 repo.just_name)
576 if repo.group:
666 if repo.group:
577 args = repo.group.full_path_splitted + [_d]
667 args = repo.group.full_path_splitted + [_d]
578 _d = os.path.join(*args)
668 _d = os.path.join(*args)
579 shutil.move(rm_path, os.path.join(self.repos_path, _d))
669 shutil.move(rm_path, os.path.join(self.repos_path, _d))
@@ -1,4847 +1,4847 b''
1 html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td
1 html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td
2 {
2 {
3 border: 0;
3 border: 0;
4 outline: 0;
4 outline: 0;
5 font-size: 100%;
5 font-size: 100%;
6 vertical-align: baseline;
6 vertical-align: baseline;
7 background: transparent;
7 background: transparent;
8 margin: 0;
8 margin: 0;
9 padding: 0;
9 padding: 0;
10 }
10 }
11
11
12 body {
12 body {
13 line-height: 1;
13 line-height: 1;
14 height: 100%;
14 height: 100%;
15 background: url("../images/background.png") repeat scroll 0 0 #B0B0B0;
15 background: url("../images/background.png") repeat scroll 0 0 #B0B0B0;
16 font-family: Lucida Grande, Verdana, Lucida Sans Regular,
16 font-family: Lucida Grande, Verdana, Lucida Sans Regular,
17 Lucida Sans Unicode, Arial, sans-serif; font-size : 12px;
17 Lucida Sans Unicode, Arial, sans-serif; font-size : 12px;
18 color: #000;
18 color: #000;
19 margin: 0;
19 margin: 0;
20 padding: 0;
20 padding: 0;
21 font-size: 12px;
21 font-size: 12px;
22 }
22 }
23
23
24 ol,ul {
24 ol,ul {
25 list-style: none;
25 list-style: none;
26 }
26 }
27
27
28 blockquote,q {
28 blockquote,q {
29 quotes: none;
29 quotes: none;
30 }
30 }
31
31
32 blockquote:before,blockquote:after,q:before,q:after {
32 blockquote:before,blockquote:after,q:before,q:after {
33 content: none;
33 content: none;
34 }
34 }
35
35
36 :focus {
36 :focus {
37 outline: 0;
37 outline: 0;
38 }
38 }
39
39
40 del {
40 del {
41 text-decoration: line-through;
41 text-decoration: line-through;
42 }
42 }
43
43
44 table {
44 table {
45 border-collapse: collapse;
45 border-collapse: collapse;
46 border-spacing: 0;
46 border-spacing: 0;
47 }
47 }
48
48
49 html {
49 html {
50 height: 100%;
50 height: 100%;
51 }
51 }
52
52
53 a {
53 a {
54 color: #003367;
54 color: #003367;
55 text-decoration: none;
55 text-decoration: none;
56 cursor: pointer;
56 cursor: pointer;
57 }
57 }
58
58
59 a:hover {
59 a:hover {
60 color: #316293;
60 color: #316293;
61 text-decoration: underline;
61 text-decoration: underline;
62 }
62 }
63
63
64 h1,h2,h3,h4,h5,h6,
64 h1,h2,h3,h4,h5,h6,
65 div.h1,div.h2,div.h3,div.h4,div.h5,div.h6 {
65 div.h1,div.h2,div.h3,div.h4,div.h5,div.h6 {
66 color: #292929;
66 color: #292929;
67 font-weight: 700;
67 font-weight: 700;
68 }
68 }
69
69
70 h1,div.h1 {
70 h1,div.h1 {
71 font-size: 22px;
71 font-size: 22px;
72 }
72 }
73
73
74 h2,div.h2 {
74 h2,div.h2 {
75 font-size: 20px;
75 font-size: 20px;
76 }
76 }
77
77
78 h3,div.h3 {
78 h3,div.h3 {
79 font-size: 18px;
79 font-size: 18px;
80 }
80 }
81
81
82 h4,div.h4 {
82 h4,div.h4 {
83 font-size: 16px;
83 font-size: 16px;
84 }
84 }
85
85
86 h5,div.h5 {
86 h5,div.h5 {
87 font-size: 14px;
87 font-size: 14px;
88 }
88 }
89
89
90 h6,div.h6 {
90 h6,div.h6 {
91 font-size: 11px;
91 font-size: 11px;
92 }
92 }
93
93
94 ul.circle {
94 ul.circle {
95 list-style-type: circle;
95 list-style-type: circle;
96 }
96 }
97
97
98 ul.disc {
98 ul.disc {
99 list-style-type: disc;
99 list-style-type: disc;
100 }
100 }
101
101
102 ul.square {
102 ul.square {
103 list-style-type: square;
103 list-style-type: square;
104 }
104 }
105
105
106 ol.lower-roman {
106 ol.lower-roman {
107 list-style-type: lower-roman;
107 list-style-type: lower-roman;
108 }
108 }
109
109
110 ol.upper-roman {
110 ol.upper-roman {
111 list-style-type: upper-roman;
111 list-style-type: upper-roman;
112 }
112 }
113
113
114 ol.lower-alpha {
114 ol.lower-alpha {
115 list-style-type: lower-alpha;
115 list-style-type: lower-alpha;
116 }
116 }
117
117
118 ol.upper-alpha {
118 ol.upper-alpha {
119 list-style-type: upper-alpha;
119 list-style-type: upper-alpha;
120 }
120 }
121
121
122 ol.decimal {
122 ol.decimal {
123 list-style-type: decimal;
123 list-style-type: decimal;
124 }
124 }
125
125
126 div.color {
126 div.color {
127 clear: both;
127 clear: both;
128 overflow: hidden;
128 overflow: hidden;
129 position: absolute;
129 position: absolute;
130 background: #FFF;
130 background: #FFF;
131 margin: 7px 0 0 60px;
131 margin: 7px 0 0 60px;
132 padding: 1px 1px 1px 0;
132 padding: 1px 1px 1px 0;
133 }
133 }
134
134
135 div.color a {
135 div.color a {
136 width: 15px;
136 width: 15px;
137 height: 15px;
137 height: 15px;
138 display: block;
138 display: block;
139 float: left;
139 float: left;
140 margin: 0 0 0 1px;
140 margin: 0 0 0 1px;
141 padding: 0;
141 padding: 0;
142 }
142 }
143
143
144 div.options {
144 div.options {
145 clear: both;
145 clear: both;
146 overflow: hidden;
146 overflow: hidden;
147 position: absolute;
147 position: absolute;
148 background: #FFF;
148 background: #FFF;
149 margin: 7px 0 0 162px;
149 margin: 7px 0 0 162px;
150 padding: 0;
150 padding: 0;
151 }
151 }
152
152
153 div.options a {
153 div.options a {
154 height: 1%;
154 height: 1%;
155 display: block;
155 display: block;
156 text-decoration: none;
156 text-decoration: none;
157 margin: 0;
157 margin: 0;
158 padding: 3px 8px;
158 padding: 3px 8px;
159 }
159 }
160
160
161 .top-left-rounded-corner {
161 .top-left-rounded-corner {
162 -webkit-border-top-left-radius: 8px;
162 -webkit-border-top-left-radius: 8px;
163 -khtml-border-radius-topleft: 8px;
163 -khtml-border-radius-topleft: 8px;
164 -moz-border-radius-topleft: 8px;
164 -moz-border-radius-topleft: 8px;
165 border-top-left-radius: 8px;
165 border-top-left-radius: 8px;
166 }
166 }
167
167
168 .top-right-rounded-corner {
168 .top-right-rounded-corner {
169 -webkit-border-top-right-radius: 8px;
169 -webkit-border-top-right-radius: 8px;
170 -khtml-border-radius-topright: 8px;
170 -khtml-border-radius-topright: 8px;
171 -moz-border-radius-topright: 8px;
171 -moz-border-radius-topright: 8px;
172 border-top-right-radius: 8px;
172 border-top-right-radius: 8px;
173 }
173 }
174
174
175 .bottom-left-rounded-corner {
175 .bottom-left-rounded-corner {
176 -webkit-border-bottom-left-radius: 8px;
176 -webkit-border-bottom-left-radius: 8px;
177 -khtml-border-radius-bottomleft: 8px;
177 -khtml-border-radius-bottomleft: 8px;
178 -moz-border-radius-bottomleft: 8px;
178 -moz-border-radius-bottomleft: 8px;
179 border-bottom-left-radius: 8px;
179 border-bottom-left-radius: 8px;
180 }
180 }
181
181
182 .bottom-right-rounded-corner {
182 .bottom-right-rounded-corner {
183 -webkit-border-bottom-right-radius: 8px;
183 -webkit-border-bottom-right-radius: 8px;
184 -khtml-border-radius-bottomright: 8px;
184 -khtml-border-radius-bottomright: 8px;
185 -moz-border-radius-bottomright: 8px;
185 -moz-border-radius-bottomright: 8px;
186 border-bottom-right-radius: 8px;
186 border-bottom-right-radius: 8px;
187 }
187 }
188
188
189 .top-left-rounded-corner-mid {
189 .top-left-rounded-corner-mid {
190 -webkit-border-top-left-radius: 4px;
190 -webkit-border-top-left-radius: 4px;
191 -khtml-border-radius-topleft: 4px;
191 -khtml-border-radius-topleft: 4px;
192 -moz-border-radius-topleft: 4px;
192 -moz-border-radius-topleft: 4px;
193 border-top-left-radius: 4px;
193 border-top-left-radius: 4px;
194 }
194 }
195
195
196 .top-right-rounded-corner-mid {
196 .top-right-rounded-corner-mid {
197 -webkit-border-top-right-radius: 4px;
197 -webkit-border-top-right-radius: 4px;
198 -khtml-border-radius-topright: 4px;
198 -khtml-border-radius-topright: 4px;
199 -moz-border-radius-topright: 4px;
199 -moz-border-radius-topright: 4px;
200 border-top-right-radius: 4px;
200 border-top-right-radius: 4px;
201 }
201 }
202
202
203 .bottom-left-rounded-corner-mid {
203 .bottom-left-rounded-corner-mid {
204 -webkit-border-bottom-left-radius: 4px;
204 -webkit-border-bottom-left-radius: 4px;
205 -khtml-border-radius-bottomleft: 4px;
205 -khtml-border-radius-bottomleft: 4px;
206 -moz-border-radius-bottomleft: 4px;
206 -moz-border-radius-bottomleft: 4px;
207 border-bottom-left-radius: 4px;
207 border-bottom-left-radius: 4px;
208 }
208 }
209
209
210 .bottom-right-rounded-corner-mid {
210 .bottom-right-rounded-corner-mid {
211 -webkit-border-bottom-right-radius: 4px;
211 -webkit-border-bottom-right-radius: 4px;
212 -khtml-border-radius-bottomright: 4px;
212 -khtml-border-radius-bottomright: 4px;
213 -moz-border-radius-bottomright: 4px;
213 -moz-border-radius-bottomright: 4px;
214 border-bottom-right-radius: 4px;
214 border-bottom-right-radius: 4px;
215 }
215 }
216
216
217 .help-block {
217 .help-block {
218 color: #999999;
218 color: #999999;
219 display: block;
219 display: block;
220 margin-bottom: 0;
220 margin-bottom: 0;
221 margin-top: 5px;
221 margin-top: 5px;
222 }
222 }
223
223
224 .empty_data{
224 .empty_data{
225 color:#B9B9B9;
225 color:#B9B9B9;
226 }
226 }
227
227
228 a.permalink{
228 a.permalink{
229 visibility: hidden;
229 visibility: hidden;
230 }
230 }
231
231
232 a.permalink:hover{
232 a.permalink:hover{
233 text-decoration: none;
233 text-decoration: none;
234 }
234 }
235
235
236 h1:hover > a.permalink,
236 h1:hover > a.permalink,
237 h2:hover > a.permalink,
237 h2:hover > a.permalink,
238 h3:hover > a.permalink,
238 h3:hover > a.permalink,
239 h4:hover > a.permalink,
239 h4:hover > a.permalink,
240 h5:hover > a.permalink,
240 h5:hover > a.permalink,
241 h6:hover > a.permalink,
241 h6:hover > a.permalink,
242 div:hover > a.permalink {
242 div:hover > a.permalink {
243 visibility: visible;
243 visibility: visible;
244 }
244 }
245
245
246 #header {
246 #header {
247 margin: 0;
247 margin: 0;
248 padding: 0 10px;
248 padding: 0 10px;
249 }
249 }
250
250
251 #header ul#logged-user {
251 #header ul#logged-user {
252 margin-bottom: 5px !important;
252 margin-bottom: 5px !important;
253 -webkit-border-radius: 0px 0px 8px 8px;
253 -webkit-border-radius: 0px 0px 8px 8px;
254 -khtml-border-radius: 0px 0px 8px 8px;
254 -khtml-border-radius: 0px 0px 8px 8px;
255 -moz-border-radius: 0px 0px 8px 8px;
255 -moz-border-radius: 0px 0px 8px 8px;
256 border-radius: 0px 0px 8px 8px;
256 border-radius: 0px 0px 8px 8px;
257 height: 37px;
257 height: 37px;
258 background-color: #003B76;
258 background-color: #003B76;
259 background-repeat: repeat-x;
259 background-repeat: repeat-x;
260 background-image: -khtml-gradient(linear, left top, left bottom, from(#003B76), to(#00376E) );
260 background-image: -khtml-gradient(linear, left top, left bottom, from(#003B76), to(#00376E) );
261 background-image: -moz-linear-gradient(top, #003b76, #00376e);
261 background-image: -moz-linear-gradient(top, #003b76, #00376e);
262 background-image: -ms-linear-gradient(top, #003b76, #00376e);
262 background-image: -ms-linear-gradient(top, #003b76, #00376e);
263 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76), color-stop(100%, #00376e) );
263 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76), color-stop(100%, #00376e) );
264 background-image: -webkit-linear-gradient(top, #003b76, #00376e);
264 background-image: -webkit-linear-gradient(top, #003b76, #00376e);
265 background-image: -o-linear-gradient(top, #003b76, #00376e);
265 background-image: -o-linear-gradient(top, #003b76, #00376e);
266 background-image: linear-gradient(top, #003b76, #00376e);
266 background-image: linear-gradient(top, #003b76, #00376e);
267 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76',endColorstr='#00376e', GradientType=0 );
267 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76',endColorstr='#00376e', GradientType=0 );
268 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
268 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
269 }
269 }
270
270
271 #header ul#logged-user li {
271 #header ul#logged-user li {
272 list-style: none;
272 list-style: none;
273 float: left;
273 float: left;
274 margin: 8px 0 0;
274 margin: 8px 0 0;
275 padding: 4px 12px;
275 padding: 4px 12px;
276 border-left: 1px solid #316293;
276 border-left: 1px solid #316293;
277 }
277 }
278
278
279 #header ul#logged-user li.first {
279 #header ul#logged-user li.first {
280 border-left: none;
280 border-left: none;
281 margin: 4px;
281 margin: 4px;
282 }
282 }
283
283
284 #header ul#logged-user li.first div.gravatar {
284 #header ul#logged-user li.first div.gravatar {
285 margin-top: -2px;
285 margin-top: -2px;
286 }
286 }
287
287
288 #header ul#logged-user li.first div.account {
288 #header ul#logged-user li.first div.account {
289 padding-top: 4px;
289 padding-top: 4px;
290 float: left;
290 float: left;
291 }
291 }
292
292
293 #header ul#logged-user li.last {
293 #header ul#logged-user li.last {
294 border-right: none;
294 border-right: none;
295 }
295 }
296
296
297 #header ul#logged-user li a {
297 #header ul#logged-user li a {
298 color: #fff;
298 color: #fff;
299 font-weight: 700;
299 font-weight: 700;
300 text-decoration: none;
300 text-decoration: none;
301 }
301 }
302
302
303 #header ul#logged-user li a:hover {
303 #header ul#logged-user li a:hover {
304 text-decoration: underline;
304 text-decoration: underline;
305 }
305 }
306
306
307 #header ul#logged-user li.highlight a {
307 #header ul#logged-user li.highlight a {
308 color: #fff;
308 color: #fff;
309 }
309 }
310
310
311 #header ul#logged-user li.highlight a:hover {
311 #header ul#logged-user li.highlight a:hover {
312 color: #FFF;
312 color: #FFF;
313 }
313 }
314
314
315 #header #header-inner {
315 #header #header-inner {
316 min-height: 44px;
316 min-height: 44px;
317 clear: both;
317 clear: both;
318 position: relative;
318 position: relative;
319 background-color: #003B76;
319 background-color: #003B76;
320 background-repeat: repeat-x;
320 background-repeat: repeat-x;
321 background-image: -khtml-gradient(linear, left top, left bottom, from(#003B76), to(#00376E) );
321 background-image: -khtml-gradient(linear, left top, left bottom, from(#003B76), to(#00376E) );
322 background-image: -moz-linear-gradient(top, #003b76, #00376e);
322 background-image: -moz-linear-gradient(top, #003b76, #00376e);
323 background-image: -ms-linear-gradient(top, #003b76, #00376e);
323 background-image: -ms-linear-gradient(top, #003b76, #00376e);
324 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76),color-stop(100%, #00376e) );
324 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76),color-stop(100%, #00376e) );
325 background-image: -webkit-linear-gradient(top, #003b76, #00376e);
325 background-image: -webkit-linear-gradient(top, #003b76, #00376e);
326 background-image: -o-linear-gradient(top, #003b76, #00376e);
326 background-image: -o-linear-gradient(top, #003b76, #00376e);
327 background-image: linear-gradient(top, #003b76, #00376e);
327 background-image: linear-gradient(top, #003b76, #00376e);
328 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76',endColorstr='#00376e', GradientType=0 );
328 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76',endColorstr='#00376e', GradientType=0 );
329 margin: 0;
329 margin: 0;
330 padding: 0;
330 padding: 0;
331 display: block;
331 display: block;
332 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
332 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
333 -webkit-border-radius: 4px 4px 4px 4px;
333 -webkit-border-radius: 4px 4px 4px 4px;
334 -khtml-border-radius: 4px 4px 4px 4px;
334 -khtml-border-radius: 4px 4px 4px 4px;
335 -moz-border-radius: 4px 4px 4px 4px;
335 -moz-border-radius: 4px 4px 4px 4px;
336 border-radius: 4px 4px 4px 4px;
336 border-radius: 4px 4px 4px 4px;
337 }
337 }
338 #header #header-inner.hover{
338 #header #header-inner.hover{
339 position: fixed !important;
339 position: fixed !important;
340 width: 100% !important;
340 width: 100% !important;
341 margin-left: -10px !important;
341 margin-left: -10px !important;
342 z-index: 10000;
342 z-index: 10000;
343 -webkit-border-radius: 0px 0px 0px 0px;
343 -webkit-border-radius: 0px 0px 0px 0px;
344 -khtml-border-radius: 0px 0px 0px 0px;
344 -khtml-border-radius: 0px 0px 0px 0px;
345 -moz-border-radius: 0px 0px 0px 0px;
345 -moz-border-radius: 0px 0px 0px 0px;
346 border-radius: 0px 0px 0px 0px;
346 border-radius: 0px 0px 0px 0px;
347 }
347 }
348
348
349 .ie7 #header #header-inner.hover,
349 .ie7 #header #header-inner.hover,
350 .ie8 #header #header-inner.hover,
350 .ie8 #header #header-inner.hover,
351 .ie9 #header #header-inner.hover
351 .ie9 #header #header-inner.hover
352 {
352 {
353 z-index: auto !important;
353 z-index: auto !important;
354 }
354 }
355
355
356 .header-pos-fix, .anchor{
356 .header-pos-fix, .anchor{
357 margin-top: -46px;
357 margin-top: -46px;
358 padding-top: 46px;
358 padding-top: 46px;
359 }
359 }
360
360
361 #header #header-inner #home a {
361 #header #header-inner #home a {
362 height: 40px;
362 height: 40px;
363 width: 46px;
363 width: 46px;
364 display: block;
364 display: block;
365 background: url("../images/button_home.png");
365 background: url("../images/button_home.png");
366 background-position: 0 0;
366 background-position: 0 0;
367 margin: 0;
367 margin: 0;
368 padding: 0;
368 padding: 0;
369 }
369 }
370
370
371 #header #header-inner #home a:hover {
371 #header #header-inner #home a:hover {
372 background-position: 0 -40px;
372 background-position: 0 -40px;
373 }
373 }
374
374
375 #header #header-inner #logo {
375 #header #header-inner #logo {
376 float: left;
376 float: left;
377 position: absolute;
377 position: absolute;
378 }
378 }
379
379
380 #header #header-inner #logo h1 {
380 #header #header-inner #logo h1 {
381 color: #FFF;
381 color: #FFF;
382 font-size: 20px;
382 font-size: 20px;
383 margin: 12px 0 0 13px;
383 margin: 12px 0 0 13px;
384 padding: 0;
384 padding: 0;
385 }
385 }
386
386
387 #header #header-inner #logo a {
387 #header #header-inner #logo a {
388 color: #fff;
388 color: #fff;
389 text-decoration: none;
389 text-decoration: none;
390 }
390 }
391
391
392 #header #header-inner #logo a:hover {
392 #header #header-inner #logo a:hover {
393 color: #bfe3ff;
393 color: #bfe3ff;
394 }
394 }
395
395
396 #header #header-inner #quick,#header #header-inner #quick ul {
396 #header #header-inner #quick,#header #header-inner #quick ul {
397 position: relative;
397 position: relative;
398 float: right;
398 float: right;
399 list-style-type: none;
399 list-style-type: none;
400 list-style-position: outside;
400 list-style-position: outside;
401 margin: 8px 8px 0 0;
401 margin: 8px 8px 0 0;
402 padding: 0;
402 padding: 0;
403 }
403 }
404
404
405 #header #header-inner #quick li {
405 #header #header-inner #quick li {
406 position: relative;
406 position: relative;
407 float: left;
407 float: left;
408 margin: 0 5px 0 0;
408 margin: 0 5px 0 0;
409 padding: 0;
409 padding: 0;
410 }
410 }
411
411
412 #header #header-inner #quick li a.menu_link {
412 #header #header-inner #quick li a.menu_link {
413 top: 0;
413 top: 0;
414 left: 0;
414 left: 0;
415 height: 1%;
415 height: 1%;
416 display: block;
416 display: block;
417 clear: both;
417 clear: both;
418 overflow: hidden;
418 overflow: hidden;
419 color: #FFF;
419 color: #FFF;
420 font-weight: 700;
420 font-weight: 700;
421 text-decoration: none;
421 text-decoration: none;
422 background: #369;
422 background: #369;
423 padding: 0;
423 padding: 0;
424 -webkit-border-radius: 4px 4px 4px 4px;
424 -webkit-border-radius: 4px 4px 4px 4px;
425 -khtml-border-radius: 4px 4px 4px 4px;
425 -khtml-border-radius: 4px 4px 4px 4px;
426 -moz-border-radius: 4px 4px 4px 4px;
426 -moz-border-radius: 4px 4px 4px 4px;
427 border-radius: 4px 4px 4px 4px;
427 border-radius: 4px 4px 4px 4px;
428 }
428 }
429
429
430 #header #header-inner #quick li span.short {
430 #header #header-inner #quick li span.short {
431 padding: 9px 6px 8px 6px;
431 padding: 9px 6px 8px 6px;
432 }
432 }
433
433
434 #header #header-inner #quick li span {
434 #header #header-inner #quick li span {
435 top: 0;
435 top: 0;
436 right: 0;
436 right: 0;
437 height: 1%;
437 height: 1%;
438 display: block;
438 display: block;
439 float: left;
439 float: left;
440 border-left: 1px solid #3f6f9f;
440 border-left: 1px solid #3f6f9f;
441 margin: 0;
441 margin: 0;
442 padding: 10px 12px 8px 10px;
442 padding: 10px 12px 8px 10px;
443 }
443 }
444
444
445 #header #header-inner #quick li span.normal {
445 #header #header-inner #quick li span.normal {
446 border: none;
446 border: none;
447 padding: 10px 12px 8px;
447 padding: 10px 12px 8px;
448 }
448 }
449
449
450 #header #header-inner #quick li span.icon {
450 #header #header-inner #quick li span.icon {
451 top: 0;
451 top: 0;
452 left: 0;
452 left: 0;
453 border-left: none;
453 border-left: none;
454 border-right: 1px solid #2e5c89;
454 border-right: 1px solid #2e5c89;
455 padding: 8px 6px 4px;
455 padding: 8px 6px 4px;
456 }
456 }
457
457
458 #header #header-inner #quick li span.icon_short {
458 #header #header-inner #quick li span.icon_short {
459 top: 0;
459 top: 0;
460 left: 0;
460 left: 0;
461 border-left: none;
461 border-left: none;
462 border-right: 1px solid #2e5c89;
462 border-right: 1px solid #2e5c89;
463 padding: 8px 6px 4px;
463 padding: 8px 6px 4px;
464 }
464 }
465
465
466 #header #header-inner #quick li span.icon img,#header #header-inner #quick li span.icon_short img
466 #header #header-inner #quick li span.icon img,#header #header-inner #quick li span.icon_short img
467 {
467 {
468 margin: 0px -2px 0px 0px;
468 margin: 0px -2px 0px 0px;
469 }
469 }
470
470
471 #header #header-inner #quick li a:hover {
471 #header #header-inner #quick li a:hover {
472 background: #4e4e4e no-repeat top left;
472 background: #4e4e4e no-repeat top left;
473 }
473 }
474
474
475 #header #header-inner #quick li a:hover span {
475 #header #header-inner #quick li a:hover span {
476 border-left: 1px solid #545454;
476 border-left: 1px solid #545454;
477 }
477 }
478
478
479 #header #header-inner #quick li a:hover span.icon,#header #header-inner #quick li a:hover span.icon_short
479 #header #header-inner #quick li a:hover span.icon,#header #header-inner #quick li a:hover span.icon_short
480 {
480 {
481 border-left: none;
481 border-left: none;
482 border-right: 1px solid #464646;
482 border-right: 1px solid #464646;
483 }
483 }
484
484
485 #header #header-inner #quick ul {
485 #header #header-inner #quick ul {
486 top: 29px;
486 top: 29px;
487 right: 0;
487 right: 0;
488 min-width: 200px;
488 min-width: 200px;
489 display: none;
489 display: none;
490 position: absolute;
490 position: absolute;
491 background: #FFF;
491 background: #FFF;
492 border: 1px solid #666;
492 border: 1px solid #666;
493 border-top: 1px solid #003367;
493 border-top: 1px solid #003367;
494 z-index: 100;
494 z-index: 100;
495 margin: 0px 0px 0px 0px;
495 margin: 0px 0px 0px 0px;
496 padding: 0;
496 padding: 0;
497 }
497 }
498
498
499 #header #header-inner #quick ul.repo_switcher {
499 #header #header-inner #quick ul.repo_switcher {
500 max-height: 275px;
500 max-height: 275px;
501 overflow-x: hidden;
501 overflow-x: hidden;
502 overflow-y: auto;
502 overflow-y: auto;
503 }
503 }
504
504
505 #header #header-inner #quick ul.repo_switcher li.qfilter_rs {
505 #header #header-inner #quick ul.repo_switcher li.qfilter_rs {
506 float: none;
506 float: none;
507 margin: 0;
507 margin: 0;
508 border-bottom: 2px solid #003367;
508 border-bottom: 2px solid #003367;
509 }
509 }
510
510
511 #header #header-inner #quick .repo_switcher_type {
511 #header #header-inner #quick .repo_switcher_type {
512 position: absolute;
512 position: absolute;
513 left: 0;
513 left: 0;
514 top: 9px;
514 top: 9px;
515 }
515 }
516
516
517 #header #header-inner #quick li ul li {
517 #header #header-inner #quick li ul li {
518 border-bottom: 1px solid #ddd;
518 border-bottom: 1px solid #ddd;
519 }
519 }
520
520
521 #header #header-inner #quick li ul li a {
521 #header #header-inner #quick li ul li a {
522 width: 182px;
522 width: 182px;
523 height: auto;
523 height: auto;
524 display: block;
524 display: block;
525 float: left;
525 float: left;
526 background: #FFF;
526 background: #FFF;
527 color: #003367;
527 color: #003367;
528 font-weight: 400;
528 font-weight: 400;
529 margin: 0;
529 margin: 0;
530 padding: 7px 9px;
530 padding: 7px 9px;
531 }
531 }
532
532
533 #header #header-inner #quick li ul li a:hover {
533 #header #header-inner #quick li ul li a:hover {
534 color: #000;
534 color: #000;
535 background: #FFF;
535 background: #FFF;
536 }
536 }
537
537
538 #header #header-inner #quick ul ul {
538 #header #header-inner #quick ul ul {
539 top: auto;
539 top: auto;
540 }
540 }
541
541
542 #header #header-inner #quick li ul ul {
542 #header #header-inner #quick li ul ul {
543 right: 200px;
543 right: 200px;
544 max-height: 290px;
544 max-height: 290px;
545 overflow: auto;
545 overflow: auto;
546 overflow-x: hidden;
546 overflow-x: hidden;
547 white-space: normal;
547 white-space: normal;
548 }
548 }
549
549
550 #header #header-inner #quick li ul li a.journal,#header #header-inner #quick li ul li a.journal:hover
550 #header #header-inner #quick li ul li a.journal,#header #header-inner #quick li ul li a.journal:hover
551 {
551 {
552 background: url("../images/icons/book.png") no-repeat scroll 4px 9px
552 background: url("../images/icons/book.png") no-repeat scroll 4px 9px
553 #FFF;
553 #FFF;
554 width: 167px;
554 width: 167px;
555 margin: 0;
555 margin: 0;
556 padding: 12px 9px 7px 24px;
556 padding: 12px 9px 7px 24px;
557 }
557 }
558
558
559 #header #header-inner #quick li ul li a.private_repo,#header #header-inner #quick li ul li a.private_repo:hover
559 #header #header-inner #quick li ul li a.private_repo,#header #header-inner #quick li ul li a.private_repo:hover
560 {
560 {
561 background: url("../images/icons/lock.png") no-repeat scroll 4px 9px
561 background: url("../images/icons/lock.png") no-repeat scroll 4px 9px
562 #FFF;
562 #FFF;
563 min-width: 167px;
563 min-width: 167px;
564 margin: 0;
564 margin: 0;
565 padding: 12px 9px 7px 24px;
565 padding: 12px 9px 7px 24px;
566 }
566 }
567
567
568 #header #header-inner #quick li ul li a.public_repo,#header #header-inner #quick li ul li a.public_repo:hover
568 #header #header-inner #quick li ul li a.public_repo,#header #header-inner #quick li ul li a.public_repo:hover
569 {
569 {
570 background: url("../images/icons/lock_open.png") no-repeat scroll 4px
570 background: url("../images/icons/lock_open.png") no-repeat scroll 4px
571 9px #FFF;
571 9px #FFF;
572 min-width: 167px;
572 min-width: 167px;
573 margin: 0;
573 margin: 0;
574 padding: 12px 9px 7px 24px;
574 padding: 12px 9px 7px 24px;
575 }
575 }
576
576
577 #header #header-inner #quick li ul li a.hg,#header #header-inner #quick li ul li a.hg:hover
577 #header #header-inner #quick li ul li a.hg,#header #header-inner #quick li ul li a.hg:hover
578 {
578 {
579 background: url("../images/icons/hgicon.png") no-repeat scroll 4px 9px
579 background: url("../images/icons/hgicon.png") no-repeat scroll 4px 9px
580 #FFF;
580 #FFF;
581 min-width: 167px;
581 min-width: 167px;
582 margin: 0 0 0 14px;
582 margin: 0 0 0 14px;
583 padding: 12px 9px 7px 24px;
583 padding: 12px 9px 7px 24px;
584 }
584 }
585
585
586 #header #header-inner #quick li ul li a.git,#header #header-inner #quick li ul li a.git:hover
586 #header #header-inner #quick li ul li a.git,#header #header-inner #quick li ul li a.git:hover
587 {
587 {
588 background: url("../images/icons/giticon.png") no-repeat scroll 4px 9px
588 background: url("../images/icons/giticon.png") no-repeat scroll 4px 9px
589 #FFF;
589 #FFF;
590 min-width: 167px;
590 min-width: 167px;
591 margin: 0 0 0 14px;
591 margin: 0 0 0 14px;
592 padding: 12px 9px 7px 24px;
592 padding: 12px 9px 7px 24px;
593 }
593 }
594
594
595 #header #header-inner #quick li ul li a.repos,#header #header-inner #quick li ul li a.repos:hover
595 #header #header-inner #quick li ul li a.repos,#header #header-inner #quick li ul li a.repos:hover
596 {
596 {
597 background: url("../images/icons/database_edit.png") no-repeat scroll
597 background: url("../images/icons/database_edit.png") no-repeat scroll
598 4px 9px #FFF;
598 4px 9px #FFF;
599 width: 167px;
599 width: 167px;
600 margin: 0;
600 margin: 0;
601 padding: 12px 9px 7px 24px;
601 padding: 12px 9px 7px 24px;
602 }
602 }
603
603
604 #header #header-inner #quick li ul li a.repos_groups,#header #header-inner #quick li ul li a.repos_groups:hover
604 #header #header-inner #quick li ul li a.repos_groups,#header #header-inner #quick li ul li a.repos_groups:hover
605 {
605 {
606 background: url("../images/icons/database_link.png") no-repeat scroll
606 background: url("../images/icons/database_link.png") no-repeat scroll
607 4px 9px #FFF;
607 4px 9px #FFF;
608 width: 167px;
608 width: 167px;
609 margin: 0;
609 margin: 0;
610 padding: 12px 9px 7px 24px;
610 padding: 12px 9px 7px 24px;
611 }
611 }
612
612
613 #header #header-inner #quick li ul li a.users,#header #header-inner #quick li ul li a.users:hover
613 #header #header-inner #quick li ul li a.users,#header #header-inner #quick li ul li a.users:hover
614 {
614 {
615 background: #FFF url("../images/icons/user_edit.png") no-repeat 4px 9px;
615 background: #FFF url("../images/icons/user_edit.png") no-repeat 4px 9px;
616 width: 167px;
616 width: 167px;
617 margin: 0;
617 margin: 0;
618 padding: 12px 9px 7px 24px;
618 padding: 12px 9px 7px 24px;
619 }
619 }
620
620
621 #header #header-inner #quick li ul li a.groups,#header #header-inner #quick li ul li a.groups:hover
621 #header #header-inner #quick li ul li a.groups,#header #header-inner #quick li ul li a.groups:hover
622 {
622 {
623 background: #FFF url("../images/icons/group_edit.png") no-repeat 4px 9px;
623 background: #FFF url("../images/icons/group_edit.png") no-repeat 4px 9px;
624 width: 167px;
624 width: 167px;
625 margin: 0;
625 margin: 0;
626 padding: 12px 9px 7px 24px;
626 padding: 12px 9px 7px 24px;
627 }
627 }
628
628
629 #header #header-inner #quick li ul li a.defaults,#header #header-inner #quick li ul li a.defaults:hover
629 #header #header-inner #quick li ul li a.defaults,#header #header-inner #quick li ul li a.defaults:hover
630 {
630 {
631 background: #FFF url("../images/icons/wrench.png") no-repeat 4px 9px;
631 background: #FFF url("../images/icons/wrench.png") no-repeat 4px 9px;
632 width: 167px;
632 width: 167px;
633 margin: 0;
633 margin: 0;
634 padding: 12px 9px 7px 24px;
634 padding: 12px 9px 7px 24px;
635 }
635 }
636
636
637 #header #header-inner #quick li ul li a.settings,#header #header-inner #quick li ul li a.settings:hover
637 #header #header-inner #quick li ul li a.settings,#header #header-inner #quick li ul li a.settings:hover
638 {
638 {
639 background: #FFF url("../images/icons/cog.png") no-repeat 4px 9px;
639 background: #FFF url("../images/icons/cog.png") no-repeat 4px 9px;
640 width: 167px;
640 width: 167px;
641 margin: 0;
641 margin: 0;
642 padding: 12px 9px 7px 24px;
642 padding: 12px 9px 7px 24px;
643 }
643 }
644
644
645 #header #header-inner #quick li ul li a.permissions,#header #header-inner #quick li ul li a.permissions:hover
645 #header #header-inner #quick li ul li a.permissions,#header #header-inner #quick li ul li a.permissions:hover
646 {
646 {
647 background: #FFF url("../images/icons/key.png") no-repeat 4px 9px;
647 background: #FFF url("../images/icons/key.png") no-repeat 4px 9px;
648 width: 167px;
648 width: 167px;
649 margin: 0;
649 margin: 0;
650 padding: 12px 9px 7px 24px;
650 padding: 12px 9px 7px 24px;
651 }
651 }
652
652
653 #header #header-inner #quick li ul li a.ldap,#header #header-inner #quick li ul li a.ldap:hover
653 #header #header-inner #quick li ul li a.ldap,#header #header-inner #quick li ul li a.ldap:hover
654 {
654 {
655 background: #FFF url("../images/icons/server_key.png") no-repeat 4px 9px;
655 background: #FFF url("../images/icons/server_key.png") no-repeat 4px 9px;
656 width: 167px;
656 width: 167px;
657 margin: 0;
657 margin: 0;
658 padding: 12px 9px 7px 24px;
658 padding: 12px 9px 7px 24px;
659 }
659 }
660
660
661 #header #header-inner #quick li ul li a.fork,#header #header-inner #quick li ul li a.fork:hover
661 #header #header-inner #quick li ul li a.fork,#header #header-inner #quick li ul li a.fork:hover
662 {
662 {
663 background: #FFF url("../images/icons/arrow_divide.png") no-repeat 4px
663 background: #FFF url("../images/icons/arrow_divide.png") no-repeat 4px
664 9px;
664 9px;
665 width: 167px;
665 width: 167px;
666 margin: 0;
666 margin: 0;
667 padding: 12px 9px 7px 24px;
667 padding: 12px 9px 7px 24px;
668 }
668 }
669
669
670 #header #header-inner #quick li ul li a.locking_add,#header #header-inner #quick li ul li a.locking_add:hover
670 #header #header-inner #quick li ul li a.locking_add,#header #header-inner #quick li ul li a.locking_add:hover
671 {
671 {
672 background: #FFF url("../images/icons/lock_add.png") no-repeat 4px
672 background: #FFF url("../images/icons/lock_add.png") no-repeat 4px
673 9px;
673 9px;
674 width: 167px;
674 width: 167px;
675 margin: 0;
675 margin: 0;
676 padding: 12px 9px 7px 24px;
676 padding: 12px 9px 7px 24px;
677 }
677 }
678
678
679 #header #header-inner #quick li ul li a.locking_del,#header #header-inner #quick li ul li a.locking_del:hover
679 #header #header-inner #quick li ul li a.locking_del,#header #header-inner #quick li ul li a.locking_del:hover
680 {
680 {
681 background: #FFF url("../images/icons/lock_delete.png") no-repeat 4px
681 background: #FFF url("../images/icons/lock_delete.png") no-repeat 4px
682 9px;
682 9px;
683 width: 167px;
683 width: 167px;
684 margin: 0;
684 margin: 0;
685 padding: 12px 9px 7px 24px;
685 padding: 12px 9px 7px 24px;
686 }
686 }
687
687
688 #header #header-inner #quick li ul li a.pull_request,#header #header-inner #quick li ul li a.pull_request:hover
688 #header #header-inner #quick li ul li a.pull_request,#header #header-inner #quick li ul li a.pull_request:hover
689 {
689 {
690 background: #FFF url("../images/icons/arrow_join.png") no-repeat 4px
690 background: #FFF url("../images/icons/arrow_join.png") no-repeat 4px
691 9px;
691 9px;
692 width: 167px;
692 width: 167px;
693 margin: 0;
693 margin: 0;
694 padding: 12px 9px 7px 24px;
694 padding: 12px 9px 7px 24px;
695 }
695 }
696
696
697 #header #header-inner #quick li ul li a.compare_request,#header #header-inner #quick li ul li a.compare_request:hover
697 #header #header-inner #quick li ul li a.compare_request,#header #header-inner #quick li ul li a.compare_request:hover
698 {
698 {
699 background: #FFF url("../images/icons/arrow_inout.png") no-repeat 4px
699 background: #FFF url("../images/icons/arrow_inout.png") no-repeat 4px
700 9px;
700 9px;
701 width: 167px;
701 width: 167px;
702 margin: 0;
702 margin: 0;
703 padding: 12px 9px 7px 24px;
703 padding: 12px 9px 7px 24px;
704 }
704 }
705
705
706 #header #header-inner #quick li ul li a.search,#header #header-inner #quick li ul li a.search:hover
706 #header #header-inner #quick li ul li a.search,#header #header-inner #quick li ul li a.search:hover
707 {
707 {
708 background: #FFF url("../images/icons/search_16.png") no-repeat 4px 9px;
708 background: #FFF url("../images/icons/search_16.png") no-repeat 4px 9px;
709 width: 167px;
709 width: 167px;
710 margin: 0;
710 margin: 0;
711 padding: 12px 9px 7px 24px;
711 padding: 12px 9px 7px 24px;
712 }
712 }
713
713
714 #header #header-inner #quick li ul li a.delete,#header #header-inner #quick li ul li a.delete:hover
714 #header #header-inner #quick li ul li a.delete,#header #header-inner #quick li ul li a.delete:hover
715 {
715 {
716 background: #FFF url("../images/icons/delete.png") no-repeat 4px 9px;
716 background: #FFF url("../images/icons/delete.png") no-repeat 4px 9px;
717 width: 167px;
717 width: 167px;
718 margin: 0;
718 margin: 0;
719 padding: 12px 9px 7px 24px;
719 padding: 12px 9px 7px 24px;
720 }
720 }
721
721
722 #header #header-inner #quick li ul li a.branches,#header #header-inner #quick li ul li a.branches:hover
722 #header #header-inner #quick li ul li a.branches,#header #header-inner #quick li ul li a.branches:hover
723 {
723 {
724 background: #FFF url("../images/icons/arrow_branch.png") no-repeat 4px
724 background: #FFF url("../images/icons/arrow_branch.png") no-repeat 4px
725 9px;
725 9px;
726 width: 167px;
726 width: 167px;
727 margin: 0;
727 margin: 0;
728 padding: 12px 9px 7px 24px;
728 padding: 12px 9px 7px 24px;
729 }
729 }
730
730
731 #header #header-inner #quick li ul li a.tags,
731 #header #header-inner #quick li ul li a.tags,
732 #header #header-inner #quick li ul li a.tags:hover{
732 #header #header-inner #quick li ul li a.tags:hover{
733 background: #FFF url("../images/icons/tag_blue.png") no-repeat 4px 9px;
733 background: #FFF url("../images/icons/tag_blue.png") no-repeat 4px 9px;
734 width: 167px;
734 width: 167px;
735 margin: 0;
735 margin: 0;
736 padding: 12px 9px 7px 24px;
736 padding: 12px 9px 7px 24px;
737 }
737 }
738
738
739 #header #header-inner #quick li ul li a.bookmarks,
739 #header #header-inner #quick li ul li a.bookmarks,
740 #header #header-inner #quick li ul li a.bookmarks:hover{
740 #header #header-inner #quick li ul li a.bookmarks:hover{
741 background: #FFF url("../images/icons/tag_green.png") no-repeat 4px 9px;
741 background: #FFF url("../images/icons/tag_green.png") no-repeat 4px 9px;
742 width: 167px;
742 width: 167px;
743 margin: 0;
743 margin: 0;
744 padding: 12px 9px 7px 24px;
744 padding: 12px 9px 7px 24px;
745 }
745 }
746
746
747 #header #header-inner #quick li ul li a.admin,
747 #header #header-inner #quick li ul li a.admin,
748 #header #header-inner #quick li ul li a.admin:hover{
748 #header #header-inner #quick li ul li a.admin:hover{
749 background: #FFF url("../images/icons/cog_edit.png") no-repeat 4px 9px;
749 background: #FFF url("../images/icons/cog_edit.png") no-repeat 4px 9px;
750 width: 167px;
750 width: 167px;
751 margin: 0;
751 margin: 0;
752 padding: 12px 9px 7px 24px;
752 padding: 12px 9px 7px 24px;
753 }
753 }
754
754
755 .groups_breadcrumbs a {
755 .groups_breadcrumbs a {
756 color: #fff;
756 color: #fff;
757 }
757 }
758
758
759 .groups_breadcrumbs a:hover {
759 .groups_breadcrumbs a:hover {
760 color: #bfe3ff;
760 color: #bfe3ff;
761 text-decoration: none;
761 text-decoration: none;
762 }
762 }
763
763
764 td.quick_repo_menu {
764 td.quick_repo_menu {
765 background: #FFF url("../images/vertical-indicator.png") 8px 50% no-repeat !important;
765 background: #FFF url("../images/vertical-indicator.png") 8px 50% no-repeat !important;
766 cursor: pointer;
766 cursor: pointer;
767 width: 8px;
767 width: 8px;
768 border: 1px solid transparent;
768 border: 1px solid transparent;
769 }
769 }
770
770
771 td.quick_repo_menu.active {
771 td.quick_repo_menu.active {
772 background: url("../images/dt-arrow-dn.png") no-repeat scroll 5px 50% #FFFFFF !important;
772 background: url("../images/dt-arrow-dn.png") no-repeat scroll 5px 50% #FFFFFF !important;
773 border: 1px solid #003367;
773 border: 1px solid #003367;
774 box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
774 box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
775 cursor: pointer;
775 cursor: pointer;
776 }
776 }
777
777
778 td.quick_repo_menu .menu_items {
778 td.quick_repo_menu .menu_items {
779 margin-top: 10px;
779 margin-top: 10px;
780 margin-left:-6px;
780 margin-left:-6px;
781 width: 150px;
781 width: 150px;
782 position: absolute;
782 position: absolute;
783 background-color: #FFF;
783 background-color: #FFF;
784 background: none repeat scroll 0 0 #FFFFFF;
784 background: none repeat scroll 0 0 #FFFFFF;
785 border-color: #003367 #666666 #666666;
785 border-color: #003367 #666666 #666666;
786 border-right: 1px solid #666666;
786 border-right: 1px solid #666666;
787 border-style: solid;
787 border-style: solid;
788 border-width: 1px;
788 border-width: 1px;
789 box-shadow: 2px 8px 4px rgba(0, 0, 0, 0.2);
789 box-shadow: 2px 8px 4px rgba(0, 0, 0, 0.2);
790 border-top-style: none;
790 border-top-style: none;
791 }
791 }
792
792
793 td.quick_repo_menu .menu_items li {
793 td.quick_repo_menu .menu_items li {
794 padding: 0 !important;
794 padding: 0 !important;
795 }
795 }
796
796
797 td.quick_repo_menu .menu_items a {
797 td.quick_repo_menu .menu_items a {
798 display: block;
798 display: block;
799 padding: 4px 12px 4px 8px;
799 padding: 4px 12px 4px 8px;
800 }
800 }
801
801
802 td.quick_repo_menu .menu_items a:hover {
802 td.quick_repo_menu .menu_items a:hover {
803 background-color: #EEE;
803 background-color: #EEE;
804 text-decoration: none;
804 text-decoration: none;
805 }
805 }
806
806
807 td.quick_repo_menu .menu_items .icon img {
807 td.quick_repo_menu .menu_items .icon img {
808 margin-bottom: -2px;
808 margin-bottom: -2px;
809 }
809 }
810
810
811 td.quick_repo_menu .menu_items.hidden {
811 td.quick_repo_menu .menu_items.hidden {
812 display: none;
812 display: none;
813 }
813 }
814
814
815 .yui-dt-first th {
815 .yui-dt-first th {
816 text-align: left;
816 text-align: left;
817 }
817 }
818
818
819 /*
819 /*
820 Copyright (c) 2011, Yahoo! Inc. All rights reserved.
820 Copyright (c) 2011, Yahoo! Inc. All rights reserved.
821 Code licensed under the BSD License:
821 Code licensed under the BSD License:
822 http://developer.yahoo.com/yui/license.html
822 http://developer.yahoo.com/yui/license.html
823 version: 2.9.0
823 version: 2.9.0
824 */
824 */
825 .yui-skin-sam .yui-dt-mask {
825 .yui-skin-sam .yui-dt-mask {
826 position: absolute;
826 position: absolute;
827 z-index: 9500;
827 z-index: 9500;
828 }
828 }
829 .yui-dt-tmp {
829 .yui-dt-tmp {
830 position: absolute;
830 position: absolute;
831 left: -9000px;
831 left: -9000px;
832 }
832 }
833 .yui-dt-scrollable .yui-dt-bd { overflow: auto }
833 .yui-dt-scrollable .yui-dt-bd { overflow: auto }
834 .yui-dt-scrollable .yui-dt-hd {
834 .yui-dt-scrollable .yui-dt-hd {
835 overflow: hidden;
835 overflow: hidden;
836 position: relative;
836 position: relative;
837 }
837 }
838 .yui-dt-scrollable .yui-dt-bd thead tr,
838 .yui-dt-scrollable .yui-dt-bd thead tr,
839 .yui-dt-scrollable .yui-dt-bd thead th {
839 .yui-dt-scrollable .yui-dt-bd thead th {
840 position: absolute;
840 position: absolute;
841 left: -1500px;
841 left: -1500px;
842 }
842 }
843 .yui-dt-scrollable tbody { -moz-outline: 0 }
843 .yui-dt-scrollable tbody { -moz-outline: 0 }
844 .yui-skin-sam thead .yui-dt-sortable { cursor: pointer }
844 .yui-skin-sam thead .yui-dt-sortable { cursor: pointer }
845 .yui-skin-sam thead .yui-dt-draggable { cursor: move }
845 .yui-skin-sam thead .yui-dt-draggable { cursor: move }
846 .yui-dt-coltarget {
846 .yui-dt-coltarget {
847 position: absolute;
847 position: absolute;
848 z-index: 999;
848 z-index: 999;
849 }
849 }
850 .yui-dt-hd { zoom: 1 }
850 .yui-dt-hd { zoom: 1 }
851 th.yui-dt-resizeable .yui-dt-resizerliner { position: relative }
851 th.yui-dt-resizeable .yui-dt-resizerliner { position: relative }
852 .yui-dt-resizer {
852 .yui-dt-resizer {
853 position: absolute;
853 position: absolute;
854 right: 0;
854 right: 0;
855 bottom: 0;
855 bottom: 0;
856 height: 100%;
856 height: 100%;
857 cursor: e-resize;
857 cursor: e-resize;
858 cursor: col-resize;
858 cursor: col-resize;
859 background-color: #CCC;
859 background-color: #CCC;
860 opacity: 0;
860 opacity: 0;
861 filter: alpha(opacity=0);
861 filter: alpha(opacity=0);
862 }
862 }
863 .yui-dt-resizerproxy {
863 .yui-dt-resizerproxy {
864 visibility: hidden;
864 visibility: hidden;
865 position: absolute;
865 position: absolute;
866 z-index: 9000;
866 z-index: 9000;
867 background-color: #CCC;
867 background-color: #CCC;
868 opacity: 0;
868 opacity: 0;
869 filter: alpha(opacity=0);
869 filter: alpha(opacity=0);
870 }
870 }
871 th.yui-dt-hidden .yui-dt-liner,
871 th.yui-dt-hidden .yui-dt-liner,
872 td.yui-dt-hidden .yui-dt-liner,
872 td.yui-dt-hidden .yui-dt-liner,
873 th.yui-dt-hidden .yui-dt-resizer { display: none }
873 th.yui-dt-hidden .yui-dt-resizer { display: none }
874 .yui-dt-editor,
874 .yui-dt-editor,
875 .yui-dt-editor-shim {
875 .yui-dt-editor-shim {
876 position: absolute;
876 position: absolute;
877 z-index: 9000;
877 z-index: 9000;
878 }
878 }
879 .yui-skin-sam .yui-dt table {
879 .yui-skin-sam .yui-dt table {
880 margin: 0;
880 margin: 0;
881 padding: 0;
881 padding: 0;
882 font-family: arial;
882 font-family: arial;
883 font-size: inherit;
883 font-size: inherit;
884 border-collapse: separate;
884 border-collapse: separate;
885 *border-collapse: collapse;
885 *border-collapse: collapse;
886 border-spacing: 0;
886 border-spacing: 0;
887 border: 1px solid #7f7f7f;
887 border: 1px solid #7f7f7f;
888 }
888 }
889 .yui-skin-sam .yui-dt thead { border-spacing: 0 }
889 .yui-skin-sam .yui-dt thead { border-spacing: 0 }
890 .yui-skin-sam .yui-dt caption {
890 .yui-skin-sam .yui-dt caption {
891 color: #000;
891 color: #000;
892 font-size: 85%;
892 font-size: 85%;
893 font-weight: normal;
893 font-weight: normal;
894 font-style: italic;
894 font-style: italic;
895 line-height: 1;
895 line-height: 1;
896 padding: 1em 0;
896 padding: 1em 0;
897 text-align: center;
897 text-align: center;
898 }
898 }
899 .yui-skin-sam .yui-dt th { background: #d8d8da url(../images/sprite.png) repeat-x 0 0 }
899 .yui-skin-sam .yui-dt th { background: #d8d8da url(../images/sprite.png) repeat-x 0 0 }
900 .yui-skin-sam .yui-dt th,
900 .yui-skin-sam .yui-dt th,
901 .yui-skin-sam .yui-dt th a {
901 .yui-skin-sam .yui-dt th a {
902 font-weight: normal;
902 font-weight: normal;
903 text-decoration: none;
903 text-decoration: none;
904 color: #000;
904 color: #000;
905 vertical-align: bottom;
905 vertical-align: bottom;
906 }
906 }
907 .yui-skin-sam .yui-dt th {
907 .yui-skin-sam .yui-dt th {
908 margin: 0;
908 margin: 0;
909 padding: 0;
909 padding: 0;
910 border: 0;
910 border: 0;
911 border-right: 1px solid #cbcbcb;
911 border-right: 1px solid #cbcbcb;
912 }
912 }
913 .yui-skin-sam .yui-dt tr.yui-dt-first td { border-top: 1px solid #7f7f7f }
913 .yui-skin-sam .yui-dt tr.yui-dt-first td { border-top: 1px solid #7f7f7f }
914 .yui-skin-sam .yui-dt th .yui-dt-liner { white-space: nowrap }
914 .yui-skin-sam .yui-dt th .yui-dt-liner { white-space: nowrap }
915 .yui-skin-sam .yui-dt-liner {
915 .yui-skin-sam .yui-dt-liner {
916 margin: 0;
916 margin: 0;
917 padding: 0;
917 padding: 0;
918 }
918 }
919 .yui-skin-sam .yui-dt-coltarget {
919 .yui-skin-sam .yui-dt-coltarget {
920 width: 5px;
920 width: 5px;
921 background-color: red;
921 background-color: red;
922 }
922 }
923 .yui-skin-sam .yui-dt td {
923 .yui-skin-sam .yui-dt td {
924 margin: 0;
924 margin: 0;
925 padding: 0;
925 padding: 0;
926 border: 0;
926 border: 0;
927 border-right: 1px solid #cbcbcb;
927 border-right: 1px solid #cbcbcb;
928 text-align: left;
928 text-align: left;
929 }
929 }
930 .yui-skin-sam .yui-dt-list td { border-right: 0 }
930 .yui-skin-sam .yui-dt-list td { border-right: 0 }
931 .yui-skin-sam .yui-dt-resizer { width: 6px }
931 .yui-skin-sam .yui-dt-resizer { width: 6px }
932 .yui-skin-sam .yui-dt-mask {
932 .yui-skin-sam .yui-dt-mask {
933 background-color: #000;
933 background-color: #000;
934 opacity: .25;
934 opacity: .25;
935 filter: alpha(opacity=25);
935 filter: alpha(opacity=25);
936 }
936 }
937 .yui-skin-sam .yui-dt-message { background-color: #FFF }
937 .yui-skin-sam .yui-dt-message { background-color: #FFF }
938 .yui-skin-sam .yui-dt-scrollable table { border: 0 }
938 .yui-skin-sam .yui-dt-scrollable table { border: 0 }
939 .yui-skin-sam .yui-dt-scrollable .yui-dt-hd {
939 .yui-skin-sam .yui-dt-scrollable .yui-dt-hd {
940 border-left: 1px solid #7f7f7f;
940 border-left: 1px solid #7f7f7f;
941 border-top: 1px solid #7f7f7f;
941 border-top: 1px solid #7f7f7f;
942 border-right: 1px solid #7f7f7f;
942 border-right: 1px solid #7f7f7f;
943 }
943 }
944 .yui-skin-sam .yui-dt-scrollable .yui-dt-bd {
944 .yui-skin-sam .yui-dt-scrollable .yui-dt-bd {
945 border-left: 1px solid #7f7f7f;
945 border-left: 1px solid #7f7f7f;
946 border-bottom: 1px solid #7f7f7f;
946 border-bottom: 1px solid #7f7f7f;
947 border-right: 1px solid #7f7f7f;
947 border-right: 1px solid #7f7f7f;
948 background-color: #FFF;
948 background-color: #FFF;
949 }
949 }
950 .yui-skin-sam .yui-dt-scrollable .yui-dt-data tr.yui-dt-last td { border-bottom: 1px solid #7f7f7f }
950 .yui-skin-sam .yui-dt-scrollable .yui-dt-data tr.yui-dt-last td { border-bottom: 1px solid #7f7f7f }
951 .yui-skin-sam th.yui-dt-asc,
951 .yui-skin-sam th.yui-dt-asc,
952 .yui-skin-sam th.yui-dt-desc { background: url(../images/sprite.png) repeat-x 0 -100px }
952 .yui-skin-sam th.yui-dt-desc { background: url(../images/sprite.png) repeat-x 0 -100px }
953 .yui-skin-sam th.yui-dt-sortable .yui-dt-label { margin-right: 10px }
953 .yui-skin-sam th.yui-dt-sortable .yui-dt-label { margin-right: 10px }
954 .yui-skin-sam th.yui-dt-asc .yui-dt-liner { background: url(../images/dt-arrow-up.png) no-repeat right }
954 .yui-skin-sam th.yui-dt-asc .yui-dt-liner { background: url(../images/dt-arrow-up.png) no-repeat right }
955 .yui-skin-sam th.yui-dt-desc .yui-dt-liner { background: url(../images/dt-arrow-dn.png) no-repeat right }
955 .yui-skin-sam th.yui-dt-desc .yui-dt-liner { background: url(../images/dt-arrow-dn.png) no-repeat right }
956 tbody .yui-dt-editable { cursor: pointer }
956 tbody .yui-dt-editable { cursor: pointer }
957 .yui-dt-editor {
957 .yui-dt-editor {
958 text-align: left;
958 text-align: left;
959 background-color: #f2f2f2;
959 background-color: #f2f2f2;
960 border: 1px solid #808080;
960 border: 1px solid #808080;
961 padding: 6px;
961 padding: 6px;
962 }
962 }
963 .yui-dt-editor label {
963 .yui-dt-editor label {
964 padding-left: 4px;
964 padding-left: 4px;
965 padding-right: 6px;
965 padding-right: 6px;
966 }
966 }
967 .yui-dt-editor .yui-dt-button {
967 .yui-dt-editor .yui-dt-button {
968 padding-top: 6px;
968 padding-top: 6px;
969 text-align: right;
969 text-align: right;
970 }
970 }
971 .yui-dt-editor .yui-dt-button button {
971 .yui-dt-editor .yui-dt-button button {
972 background: url(../images/sprite.png) repeat-x 0 0;
972 background: url(../images/sprite.png) repeat-x 0 0;
973 border: 1px solid #999;
973 border: 1px solid #999;
974 width: 4em;
974 width: 4em;
975 height: 1.8em;
975 height: 1.8em;
976 margin-left: 6px;
976 margin-left: 6px;
977 }
977 }
978 .yui-dt-editor .yui-dt-button button.yui-dt-default {
978 .yui-dt-editor .yui-dt-button button.yui-dt-default {
979 background: url(../images/sprite.png) repeat-x 0 -1400px;
979 background: url(../images/sprite.png) repeat-x 0 -1400px;
980 background-color: #5584e0;
980 background-color: #5584e0;
981 border: 1px solid #304369;
981 border: 1px solid #304369;
982 color: #FFF;
982 color: #FFF;
983 }
983 }
984 .yui-dt-editor .yui-dt-button button:hover {
984 .yui-dt-editor .yui-dt-button button:hover {
985 background: url(../images/sprite.png) repeat-x 0 -1300px;
985 background: url(../images/sprite.png) repeat-x 0 -1300px;
986 color: #000;
986 color: #000;
987 }
987 }
988 .yui-dt-editor .yui-dt-button button:active {
988 .yui-dt-editor .yui-dt-button button:active {
989 background: url(../images/sprite.png) repeat-x 0 -1700px;
989 background: url(../images/sprite.png) repeat-x 0 -1700px;
990 color: #000;
990 color: #000;
991 }
991 }
992 .yui-skin-sam tr.yui-dt-even { background-color: #FFF }
992 .yui-skin-sam tr.yui-dt-even { background-color: #FFF }
993 .yui-skin-sam tr.yui-dt-odd { background-color: #edf5ff }
993 .yui-skin-sam tr.yui-dt-odd { background-color: #edf5ff }
994 .yui-skin-sam tr.yui-dt-even td.yui-dt-asc,
994 .yui-skin-sam tr.yui-dt-even td.yui-dt-asc,
995 .yui-skin-sam tr.yui-dt-even td.yui-dt-desc { background-color: #edf5ff }
995 .yui-skin-sam tr.yui-dt-even td.yui-dt-desc { background-color: #edf5ff }
996 .yui-skin-sam tr.yui-dt-odd td.yui-dt-asc,
996 .yui-skin-sam tr.yui-dt-odd td.yui-dt-asc,
997 .yui-skin-sam tr.yui-dt-odd td.yui-dt-desc { background-color: #dbeaff }
997 .yui-skin-sam tr.yui-dt-odd td.yui-dt-desc { background-color: #dbeaff }
998 .yui-skin-sam .yui-dt-list tr.yui-dt-even { background-color: #FFF }
998 .yui-skin-sam .yui-dt-list tr.yui-dt-even { background-color: #FFF }
999 .yui-skin-sam .yui-dt-list tr.yui-dt-odd { background-color: #FFF }
999 .yui-skin-sam .yui-dt-list tr.yui-dt-odd { background-color: #FFF }
1000 .yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-asc,
1000 .yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-asc,
1001 .yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-desc { background-color: #edf5ff }
1001 .yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-desc { background-color: #edf5ff }
1002 .yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-asc,
1002 .yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-asc,
1003 .yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-desc { background-color: #edf5ff }
1003 .yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-desc { background-color: #edf5ff }
1004 .yui-skin-sam th.yui-dt-highlighted,
1004 .yui-skin-sam th.yui-dt-highlighted,
1005 .yui-skin-sam th.yui-dt-highlighted a { background-color: #b2d2ff }
1005 .yui-skin-sam th.yui-dt-highlighted a { background-color: #b2d2ff }
1006 .yui-skin-sam tr.yui-dt-highlighted,
1006 .yui-skin-sam tr.yui-dt-highlighted,
1007 .yui-skin-sam tr.yui-dt-highlighted td.yui-dt-asc,
1007 .yui-skin-sam tr.yui-dt-highlighted td.yui-dt-asc,
1008 .yui-skin-sam tr.yui-dt-highlighted td.yui-dt-desc,
1008 .yui-skin-sam tr.yui-dt-highlighted td.yui-dt-desc,
1009 .yui-skin-sam tr.yui-dt-even td.yui-dt-highlighted,
1009 .yui-skin-sam tr.yui-dt-even td.yui-dt-highlighted,
1010 .yui-skin-sam tr.yui-dt-odd td.yui-dt-highlighted {
1010 .yui-skin-sam tr.yui-dt-odd td.yui-dt-highlighted {
1011 cursor: pointer;
1011 cursor: pointer;
1012 background-color: #b2d2ff;
1012 background-color: #b2d2ff;
1013 }
1013 }
1014 .yui-skin-sam .yui-dt-list th.yui-dt-highlighted,
1014 .yui-skin-sam .yui-dt-list th.yui-dt-highlighted,
1015 .yui-skin-sam .yui-dt-list th.yui-dt-highlighted a { background-color: #b2d2ff }
1015 .yui-skin-sam .yui-dt-list th.yui-dt-highlighted a { background-color: #b2d2ff }
1016 .yui-skin-sam .yui-dt-list tr.yui-dt-highlighted,
1016 .yui-skin-sam .yui-dt-list tr.yui-dt-highlighted,
1017 .yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-asc,
1017 .yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-asc,
1018 .yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-desc,
1018 .yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-desc,
1019 .yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-highlighted,
1019 .yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-highlighted,
1020 .yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-highlighted {
1020 .yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-highlighted {
1021 cursor: pointer;
1021 cursor: pointer;
1022 background-color: #b2d2ff;
1022 background-color: #b2d2ff;
1023 }
1023 }
1024 .yui-skin-sam th.yui-dt-selected,
1024 .yui-skin-sam th.yui-dt-selected,
1025 .yui-skin-sam th.yui-dt-selected a { background-color: #446cd7 }
1025 .yui-skin-sam th.yui-dt-selected a { background-color: #446cd7 }
1026 .yui-skin-sam tr.yui-dt-selected td,
1026 .yui-skin-sam tr.yui-dt-selected td,
1027 .yui-skin-sam tr.yui-dt-selected td.yui-dt-asc,
1027 .yui-skin-sam tr.yui-dt-selected td.yui-dt-asc,
1028 .yui-skin-sam tr.yui-dt-selected td.yui-dt-desc {
1028 .yui-skin-sam tr.yui-dt-selected td.yui-dt-desc {
1029 background-color: #426fd9;
1029 background-color: #426fd9;
1030 color: #FFF;
1030 color: #FFF;
1031 }
1031 }
1032 .yui-skin-sam tr.yui-dt-even td.yui-dt-selected,
1032 .yui-skin-sam tr.yui-dt-even td.yui-dt-selected,
1033 .yui-skin-sam tr.yui-dt-odd td.yui-dt-selected {
1033 .yui-skin-sam tr.yui-dt-odd td.yui-dt-selected {
1034 background-color: #446cd7;
1034 background-color: #446cd7;
1035 color: #FFF;
1035 color: #FFF;
1036 }
1036 }
1037 .yui-skin-sam .yui-dt-list th.yui-dt-selected,
1037 .yui-skin-sam .yui-dt-list th.yui-dt-selected,
1038 .yui-skin-sam .yui-dt-list th.yui-dt-selected a { background-color: #446cd7 }
1038 .yui-skin-sam .yui-dt-list th.yui-dt-selected a { background-color: #446cd7 }
1039 .yui-skin-sam .yui-dt-list tr.yui-dt-selected td,
1039 .yui-skin-sam .yui-dt-list tr.yui-dt-selected td,
1040 .yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-asc,
1040 .yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-asc,
1041 .yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-desc {
1041 .yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-desc {
1042 background-color: #426fd9;
1042 background-color: #426fd9;
1043 color: #FFF;
1043 color: #FFF;
1044 }
1044 }
1045 .yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-selected,
1045 .yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-selected,
1046 .yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-selected {
1046 .yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-selected {
1047 background-color: #446cd7;
1047 background-color: #446cd7;
1048 color: #FFF;
1048 color: #FFF;
1049 }
1049 }
1050 .yui-skin-sam .yui-dt-paginator {
1050 .yui-skin-sam .yui-dt-paginator {
1051 display: block;
1051 display: block;
1052 margin: 6px 0;
1052 margin: 6px 0;
1053 white-space: nowrap;
1053 white-space: nowrap;
1054 }
1054 }
1055 .yui-skin-sam .yui-dt-paginator .yui-dt-first,
1055 .yui-skin-sam .yui-dt-paginator .yui-dt-first,
1056 .yui-skin-sam .yui-dt-paginator .yui-dt-last,
1056 .yui-skin-sam .yui-dt-paginator .yui-dt-last,
1057 .yui-skin-sam .yui-dt-paginator .yui-dt-selected { padding: 2px 6px }
1057 .yui-skin-sam .yui-dt-paginator .yui-dt-selected { padding: 2px 6px }
1058 .yui-skin-sam .yui-dt-paginator a.yui-dt-first,
1058 .yui-skin-sam .yui-dt-paginator a.yui-dt-first,
1059 .yui-skin-sam .yui-dt-paginator a.yui-dt-last { text-decoration: none }
1059 .yui-skin-sam .yui-dt-paginator a.yui-dt-last { text-decoration: none }
1060 .yui-skin-sam .yui-dt-paginator .yui-dt-previous,
1060 .yui-skin-sam .yui-dt-paginator .yui-dt-previous,
1061 .yui-skin-sam .yui-dt-paginator .yui-dt-next { display: none }
1061 .yui-skin-sam .yui-dt-paginator .yui-dt-next { display: none }
1062 .yui-skin-sam a.yui-dt-page {
1062 .yui-skin-sam a.yui-dt-page {
1063 border: 1px solid #cbcbcb;
1063 border: 1px solid #cbcbcb;
1064 padding: 2px 6px;
1064 padding: 2px 6px;
1065 text-decoration: none;
1065 text-decoration: none;
1066 background-color: #fff;
1066 background-color: #fff;
1067 }
1067 }
1068 .yui-skin-sam .yui-dt-selected {
1068 .yui-skin-sam .yui-dt-selected {
1069 border: 1px solid #fff;
1069 border: 1px solid #fff;
1070 background-color: #fff;
1070 background-color: #fff;
1071 }
1071 }
1072
1072
1073 #content #left {
1073 #content #left {
1074 left: 0;
1074 left: 0;
1075 width: 280px;
1075 width: 280px;
1076 position: absolute;
1076 position: absolute;
1077 }
1077 }
1078
1078
1079 #content #right {
1079 #content #right {
1080 margin: 0 60px 10px 290px;
1080 margin: 0 60px 10px 290px;
1081 }
1081 }
1082
1082
1083 #content div.box {
1083 #content div.box {
1084 clear: both;
1084 clear: both;
1085 overflow: hidden;
1085 overflow: hidden;
1086 background: #fff;
1086 background: #fff;
1087 margin: 0 0 10px;
1087 margin: 0 0 10px;
1088 padding: 0 0 10px;
1088 padding: 0 0 10px;
1089 -webkit-border-radius: 4px 4px 4px 4px;
1089 -webkit-border-radius: 4px 4px 4px 4px;
1090 -khtml-border-radius: 4px 4px 4px 4px;
1090 -khtml-border-radius: 4px 4px 4px 4px;
1091 -moz-border-radius: 4px 4px 4px 4px;
1091 -moz-border-radius: 4px 4px 4px 4px;
1092 border-radius: 4px 4px 4px 4px;
1092 border-radius: 4px 4px 4px 4px;
1093 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
1093 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
1094 }
1094 }
1095
1095
1096 #content div.box-left {
1096 #content div.box-left {
1097 width: 49%;
1097 width: 49%;
1098 clear: none;
1098 clear: none;
1099 float: left;
1099 float: left;
1100 margin: 0 0 10px;
1100 margin: 0 0 10px;
1101 }
1101 }
1102
1102
1103 #content div.box-right {
1103 #content div.box-right {
1104 width: 49%;
1104 width: 49%;
1105 clear: none;
1105 clear: none;
1106 float: right;
1106 float: right;
1107 margin: 0 0 10px;
1107 margin: 0 0 10px;
1108 }
1108 }
1109
1109
1110 #content div.box div.title {
1110 #content div.box div.title {
1111 clear: both;
1111 clear: both;
1112 overflow: hidden;
1112 overflow: hidden;
1113 background-color: #003B76;
1113 background-color: #003B76;
1114 background-repeat: repeat-x;
1114 background-repeat: repeat-x;
1115 background-image: -khtml-gradient(linear, left top, left bottom, from(#003B76), to(#00376E) );
1115 background-image: -khtml-gradient(linear, left top, left bottom, from(#003B76), to(#00376E) );
1116 background-image: -moz-linear-gradient(top, #003b76, #00376e);
1116 background-image: -moz-linear-gradient(top, #003b76, #00376e);
1117 background-image: -ms-linear-gradient(top, #003b76, #00376e);
1117 background-image: -ms-linear-gradient(top, #003b76, #00376e);
1118 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76), color-stop(100%, #00376e) );
1118 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76), color-stop(100%, #00376e) );
1119 background-image: -webkit-linear-gradient(top, #003b76, #00376e);
1119 background-image: -webkit-linear-gradient(top, #003b76, #00376e);
1120 background-image: -o-linear-gradient(top, #003b76, #00376e);
1120 background-image: -o-linear-gradient(top, #003b76, #00376e);
1121 background-image: linear-gradient(top, #003b76, #00376e);
1121 background-image: linear-gradient(top, #003b76, #00376e);
1122 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76', endColorstr='#00376e', GradientType=0 );
1122 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76', endColorstr='#00376e', GradientType=0 );
1123 margin: 0 0 20px;
1123 margin: 0 0 20px;
1124 padding: 0;
1124 padding: 0;
1125 }
1125 }
1126
1126
1127 #content div.box div.title h5 {
1127 #content div.box div.title h5 {
1128 float: left;
1128 float: left;
1129 border: none;
1129 border: none;
1130 color: #fff;
1130 color: #fff;
1131 text-transform: uppercase;
1131 text-transform: uppercase;
1132 margin: 0;
1132 margin: 0;
1133 padding: 11px 0 11px 10px;
1133 padding: 11px 0 11px 10px;
1134 }
1134 }
1135
1135
1136 #content div.box div.title .link-white{
1136 #content div.box div.title .link-white{
1137 color: #FFFFFF;
1137 color: #FFFFFF;
1138 }
1138 }
1139
1139
1140 #content div.box div.title .link-white.current{
1140 #content div.box div.title .link-white.current{
1141 color: #BFE3FF;
1141 color: #BFE3FF;
1142 }
1142 }
1143
1143
1144 #content div.box div.title ul.links li {
1144 #content div.box div.title ul.links li {
1145 list-style: none;
1145 list-style: none;
1146 float: left;
1146 float: left;
1147 margin: 0;
1147 margin: 0;
1148 padding: 0;
1148 padding: 0;
1149 }
1149 }
1150
1150
1151 #content div.box div.title ul.links li a {
1151 #content div.box div.title ul.links li a {
1152 border-left: 1px solid #316293;
1152 border-left: 1px solid #316293;
1153 color: #FFFFFF;
1153 color: #FFFFFF;
1154 display: block;
1154 display: block;
1155 float: left;
1155 float: left;
1156 font-size: 13px;
1156 font-size: 13px;
1157 font-weight: 700;
1157 font-weight: 700;
1158 height: 1%;
1158 height: 1%;
1159 margin: 0;
1159 margin: 0;
1160 padding: 11px 22px 12px;
1160 padding: 11px 22px 12px;
1161 text-decoration: none;
1161 text-decoration: none;
1162 }
1162 }
1163
1163
1164 #content div.box h1,#content div.box h2,#content div.box h3,#content div.box h4,#content div.box h5,#content div.box h6,
1164 #content div.box h1,#content div.box h2,#content div.box h3,#content div.box h4,#content div.box h5,#content div.box h6,
1165 #content div.box div.h1,#content div.box div.h2,#content div.box div.h3,#content div.box div.h4,#content div.box div.h5,#content div.box div.h6
1165 #content div.box div.h1,#content div.box div.h2,#content div.box div.h3,#content div.box div.h4,#content div.box div.h5,#content div.box div.h6
1166
1166
1167 {
1167 {
1168 clear: both;
1168 clear: both;
1169 overflow: hidden;
1169 overflow: hidden;
1170 border-bottom: 1px solid #DDD;
1170 border-bottom: 1px solid #DDD;
1171 margin: 10px 20px;
1171 margin: 10px 20px;
1172 padding: 0 0 15px;
1172 padding: 0 0 15px;
1173 }
1173 }
1174
1174
1175 #content div.box p {
1175 #content div.box p {
1176 color: #5f5f5f;
1176 color: #5f5f5f;
1177 font-size: 12px;
1177 font-size: 12px;
1178 line-height: 150%;
1178 line-height: 150%;
1179 margin: 0 24px 10px;
1179 margin: 0 24px 10px;
1180 padding: 0;
1180 padding: 0;
1181 }
1181 }
1182
1182
1183 #content div.box blockquote {
1183 #content div.box blockquote {
1184 border-left: 4px solid #DDD;
1184 border-left: 4px solid #DDD;
1185 color: #5f5f5f;
1185 color: #5f5f5f;
1186 font-size: 11px;
1186 font-size: 11px;
1187 line-height: 150%;
1187 line-height: 150%;
1188 margin: 0 34px;
1188 margin: 0 34px;
1189 padding: 0 0 0 14px;
1189 padding: 0 0 0 14px;
1190 }
1190 }
1191
1191
1192 #content div.box blockquote p {
1192 #content div.box blockquote p {
1193 margin: 10px 0;
1193 margin: 10px 0;
1194 padding: 0;
1194 padding: 0;
1195 }
1195 }
1196
1196
1197 #content div.box dl {
1197 #content div.box dl {
1198 margin: 10px 0px;
1198 margin: 10px 0px;
1199 }
1199 }
1200
1200
1201 #content div.box dt {
1201 #content div.box dt {
1202 font-size: 12px;
1202 font-size: 12px;
1203 margin: 0;
1203 margin: 0;
1204 }
1204 }
1205
1205
1206 #content div.box dd {
1206 #content div.box dd {
1207 font-size: 12px;
1207 font-size: 12px;
1208 margin: 0;
1208 margin: 0;
1209 padding: 8px 0 8px 15px;
1209 padding: 8px 0 8px 15px;
1210 }
1210 }
1211
1211
1212 #content div.box li {
1212 #content div.box li {
1213 font-size: 12px;
1213 font-size: 12px;
1214 padding: 4px 0;
1214 padding: 4px 0;
1215 }
1215 }
1216
1216
1217 #content div.box ul.disc,#content div.box ul.circle {
1217 #content div.box ul.disc,#content div.box ul.circle {
1218 margin: 10px 24px 10px 38px;
1218 margin: 10px 24px 10px 38px;
1219 }
1219 }
1220
1220
1221 #content div.box ul.square {
1221 #content div.box ul.square {
1222 margin: 10px 24px 10px 40px;
1222 margin: 10px 24px 10px 40px;
1223 }
1223 }
1224
1224
1225 #content div.box img.left {
1225 #content div.box img.left {
1226 border: none;
1226 border: none;
1227 float: left;
1227 float: left;
1228 margin: 10px 10px 10px 0;
1228 margin: 10px 10px 10px 0;
1229 }
1229 }
1230
1230
1231 #content div.box img.right {
1231 #content div.box img.right {
1232 border: none;
1232 border: none;
1233 float: right;
1233 float: right;
1234 margin: 10px 0 10px 10px;
1234 margin: 10px 0 10px 10px;
1235 }
1235 }
1236
1236
1237 #content div.box div.messages {
1237 #content div.box div.messages {
1238 clear: both;
1238 clear: both;
1239 overflow: hidden;
1239 overflow: hidden;
1240 margin: 0 20px;
1240 margin: 0 20px;
1241 padding: 0;
1241 padding: 0;
1242 }
1242 }
1243
1243
1244 #content div.box div.message {
1244 #content div.box div.message {
1245 clear: both;
1245 clear: both;
1246 overflow: hidden;
1246 overflow: hidden;
1247 margin: 0;
1247 margin: 0;
1248 padding: 5px 0;
1248 padding: 5px 0;
1249 white-space: pre-wrap;
1249 white-space: pre-wrap;
1250 }
1250 }
1251 #content div.box div.expand {
1251 #content div.box div.expand {
1252 width: 110%;
1252 width: 110%;
1253 height:14px;
1253 height:14px;
1254 font-size:10px;
1254 font-size:10px;
1255 text-align:center;
1255 text-align:center;
1256 cursor: pointer;
1256 cursor: pointer;
1257 color:#666;
1257 color:#666;
1258
1258
1259 background:-webkit-gradient(linear,0% 50%,100% 50%,color-stop(0%,rgba(255,255,255,0)),color-stop(100%,rgba(64,96,128,0.1)));
1259 background:-webkit-gradient(linear,0% 50%,100% 50%,color-stop(0%,rgba(255,255,255,0)),color-stop(100%,rgba(64,96,128,0.1)));
1260 background:-webkit-linear-gradient(top,rgba(255,255,255,0),rgba(64,96,128,0.1));
1260 background:-webkit-linear-gradient(top,rgba(255,255,255,0),rgba(64,96,128,0.1));
1261 background:-moz-linear-gradient(top,rgba(255,255,255,0),rgba(64,96,128,0.1));
1261 background:-moz-linear-gradient(top,rgba(255,255,255,0),rgba(64,96,128,0.1));
1262 background:-o-linear-gradient(top,rgba(255,255,255,0),rgba(64,96,128,0.1));
1262 background:-o-linear-gradient(top,rgba(255,255,255,0),rgba(64,96,128,0.1));
1263 background:-ms-linear-gradient(top,rgba(255,255,255,0),rgba(64,96,128,0.1));
1263 background:-ms-linear-gradient(top,rgba(255,255,255,0),rgba(64,96,128,0.1));
1264 background:linear-gradient(top,rgba(255,255,255,0),rgba(64,96,128,0.1));
1264 background:linear-gradient(top,rgba(255,255,255,0),rgba(64,96,128,0.1));
1265
1265
1266 display: none;
1266 display: none;
1267 }
1267 }
1268 #content div.box div.expand .expandtext {
1268 #content div.box div.expand .expandtext {
1269 background-color: #ffffff;
1269 background-color: #ffffff;
1270 padding: 2px;
1270 padding: 2px;
1271 border-radius: 2px;
1271 border-radius: 2px;
1272 }
1272 }
1273
1273
1274 #content div.box div.message a {
1274 #content div.box div.message a {
1275 font-weight: 400 !important;
1275 font-weight: 400 !important;
1276 }
1276 }
1277
1277
1278 #content div.box div.message div.image {
1278 #content div.box div.message div.image {
1279 float: left;
1279 float: left;
1280 margin: 9px 0 0 5px;
1280 margin: 9px 0 0 5px;
1281 padding: 6px;
1281 padding: 6px;
1282 }
1282 }
1283
1283
1284 #content div.box div.message div.image img {
1284 #content div.box div.message div.image img {
1285 vertical-align: middle;
1285 vertical-align: middle;
1286 margin: 0;
1286 margin: 0;
1287 }
1287 }
1288
1288
1289 #content div.box div.message div.text {
1289 #content div.box div.message div.text {
1290 float: left;
1290 float: left;
1291 margin: 0;
1291 margin: 0;
1292 padding: 9px 6px;
1292 padding: 9px 6px;
1293 }
1293 }
1294
1294
1295 #content div.box div.message div.dismiss a {
1295 #content div.box div.message div.dismiss a {
1296 height: 16px;
1296 height: 16px;
1297 width: 16px;
1297 width: 16px;
1298 display: block;
1298 display: block;
1299 background: url("../images/icons/cross.png") no-repeat;
1299 background: url("../images/icons/cross.png") no-repeat;
1300 margin: 15px 14px 0 0;
1300 margin: 15px 14px 0 0;
1301 padding: 0;
1301 padding: 0;
1302 }
1302 }
1303
1303
1304 #content div.box div.message div.text h1,#content div.box div.message div.text h2,#content div.box div.message div.text h3,#content div.box div.message div.text h4,#content div.box div.message div.text h5,#content div.box div.message div.text h6
1304 #content div.box div.message div.text h1,#content div.box div.message div.text h2,#content div.box div.message div.text h3,#content div.box div.message div.text h4,#content div.box div.message div.text h5,#content div.box div.message div.text h6
1305 {
1305 {
1306 border: none;
1306 border: none;
1307 margin: 0;
1307 margin: 0;
1308 padding: 0;
1308 padding: 0;
1309 }
1309 }
1310
1310
1311 #content div.box div.message div.text span {
1311 #content div.box div.message div.text span {
1312 height: 1%;
1312 height: 1%;
1313 display: block;
1313 display: block;
1314 margin: 0;
1314 margin: 0;
1315 padding: 5px 0 0;
1315 padding: 5px 0 0;
1316 }
1316 }
1317
1317
1318 #content div.box div.message-error {
1318 #content div.box div.message-error {
1319 height: 1%;
1319 height: 1%;
1320 clear: both;
1320 clear: both;
1321 overflow: hidden;
1321 overflow: hidden;
1322 background: #FBE3E4;
1322 background: #FBE3E4;
1323 border: 1px solid #FBC2C4;
1323 border: 1px solid #FBC2C4;
1324 color: #860006;
1324 color: #860006;
1325 }
1325 }
1326
1326
1327 #content div.box div.message-error h6 {
1327 #content div.box div.message-error h6 {
1328 color: #860006;
1328 color: #860006;
1329 }
1329 }
1330
1330
1331 #content div.box div.message-warning {
1331 #content div.box div.message-warning {
1332 height: 1%;
1332 height: 1%;
1333 clear: both;
1333 clear: both;
1334 overflow: hidden;
1334 overflow: hidden;
1335 background: #FFF6BF;
1335 background: #FFF6BF;
1336 border: 1px solid #FFD324;
1336 border: 1px solid #FFD324;
1337 color: #5f5200;
1337 color: #5f5200;
1338 }
1338 }
1339
1339
1340 #content div.box div.message-warning h6 {
1340 #content div.box div.message-warning h6 {
1341 color: #5f5200;
1341 color: #5f5200;
1342 }
1342 }
1343
1343
1344 #content div.box div.message-notice {
1344 #content div.box div.message-notice {
1345 height: 1%;
1345 height: 1%;
1346 clear: both;
1346 clear: both;
1347 overflow: hidden;
1347 overflow: hidden;
1348 background: #8FBDE0;
1348 background: #8FBDE0;
1349 border: 1px solid #6BACDE;
1349 border: 1px solid #6BACDE;
1350 color: #003863;
1350 color: #003863;
1351 }
1351 }
1352
1352
1353 #content div.box div.message-notice h6 {
1353 #content div.box div.message-notice h6 {
1354 color: #003863;
1354 color: #003863;
1355 }
1355 }
1356
1356
1357 #content div.box div.message-success {
1357 #content div.box div.message-success {
1358 height: 1%;
1358 height: 1%;
1359 clear: both;
1359 clear: both;
1360 overflow: hidden;
1360 overflow: hidden;
1361 background: #E6EFC2;
1361 background: #E6EFC2;
1362 border: 1px solid #C6D880;
1362 border: 1px solid #C6D880;
1363 color: #4e6100;
1363 color: #4e6100;
1364 }
1364 }
1365
1365
1366 #content div.box div.message-success h6 {
1366 #content div.box div.message-success h6 {
1367 color: #4e6100;
1367 color: #4e6100;
1368 }
1368 }
1369
1369
1370 #content div.box div.form div.fields div.field {
1370 #content div.box div.form div.fields div.field {
1371 height: 1%;
1371 height: 1%;
1372 border-bottom: 1px solid #DDD;
1372 border-bottom: 1px solid #DDD;
1373 clear: both;
1373 clear: both;
1374 margin: 0;
1374 margin: 0;
1375 padding: 10px 0;
1375 padding: 10px 0;
1376 }
1376 }
1377
1377
1378 #content div.box div.form div.fields div.field-first {
1378 #content div.box div.form div.fields div.field-first {
1379 padding: 0 0 10px;
1379 padding: 0 0 10px;
1380 }
1380 }
1381
1381
1382 #content div.box div.form div.fields div.field-noborder {
1382 #content div.box div.form div.fields div.field-noborder {
1383 border-bottom: 0 !important;
1383 border-bottom: 0 !important;
1384 }
1384 }
1385
1385
1386 #content div.box div.form div.fields div.field span.error-message {
1386 #content div.box div.form div.fields div.field span.error-message {
1387 height: 1%;
1387 height: 1%;
1388 display: inline-block;
1388 display: inline-block;
1389 color: red;
1389 color: red;
1390 margin: 8px 0 0 4px;
1390 margin: 8px 0 0 4px;
1391 padding: 0;
1391 padding: 0;
1392 }
1392 }
1393
1393
1394 #content div.box div.form div.fields div.field span.success {
1394 #content div.box div.form div.fields div.field span.success {
1395 height: 1%;
1395 height: 1%;
1396 display: block;
1396 display: block;
1397 color: #316309;
1397 color: #316309;
1398 margin: 8px 0 0;
1398 margin: 8px 0 0;
1399 padding: 0;
1399 padding: 0;
1400 }
1400 }
1401
1401
1402 #content div.box div.form div.fields div.field div.label {
1402 #content div.box div.form div.fields div.field div.label {
1403 left: 70px;
1403 left: 70px;
1404 width: 155px;
1404 width: 155px;
1405 position: absolute;
1405 position: absolute;
1406 margin: 0;
1406 margin: 0;
1407 padding: 5px 0 0 0px;
1407 padding: 5px 0 0 0px;
1408 }
1408 }
1409
1409
1410 #content div.box div.form div.fields div.field div.label-summary {
1410 #content div.box div.form div.fields div.field div.label-summary {
1411 left: 30px;
1411 left: 30px;
1412 width: 155px;
1412 width: 155px;
1413 position: absolute;
1413 position: absolute;
1414 margin: 0;
1414 margin: 0;
1415 padding: 0px 0 0 0px;
1415 padding: 0px 0 0 0px;
1416 }
1416 }
1417
1417
1418 #content div.box-left div.form div.fields div.field div.label,
1418 #content div.box-left div.form div.fields div.field div.label,
1419 #content div.box-right div.form div.fields div.field div.label,
1419 #content div.box-right div.form div.fields div.field div.label,
1420 #content div.box-left div.form div.fields div.field div.label,
1420 #content div.box-left div.form div.fields div.field div.label,
1421 #content div.box-left div.form div.fields div.field div.label-summary,
1421 #content div.box-left div.form div.fields div.field div.label-summary,
1422 #content div.box-right div.form div.fields div.field div.label-summary,
1422 #content div.box-right div.form div.fields div.field div.label-summary,
1423 #content div.box-left div.form div.fields div.field div.label-summary
1423 #content div.box-left div.form div.fields div.field div.label-summary
1424 {
1424 {
1425 clear: both;
1425 clear: both;
1426 overflow: hidden;
1426 overflow: hidden;
1427 left: 0;
1427 left: 0;
1428 width: auto;
1428 width: auto;
1429 position: relative;
1429 position: relative;
1430 margin: 0;
1430 margin: 0;
1431 padding: 0 0 8px;
1431 padding: 0 0 8px;
1432 }
1432 }
1433
1433
1434 #content div.box div.form div.fields div.field div.label-select {
1434 #content div.box div.form div.fields div.field div.label-select {
1435 padding: 5px 0 0 5px;
1435 padding: 5px 0 0 5px;
1436 }
1436 }
1437
1437
1438 #content div.box-left div.form div.fields div.field div.label-select,
1438 #content div.box-left div.form div.fields div.field div.label-select,
1439 #content div.box-right div.form div.fields div.field div.label-select
1439 #content div.box-right div.form div.fields div.field div.label-select
1440 {
1440 {
1441 padding: 0 0 8px;
1441 padding: 0 0 8px;
1442 }
1442 }
1443
1443
1444 #content div.box-left div.form div.fields div.field div.label-textarea,
1444 #content div.box-left div.form div.fields div.field div.label-textarea,
1445 #content div.box-right div.form div.fields div.field div.label-textarea
1445 #content div.box-right div.form div.fields div.field div.label-textarea
1446 {
1446 {
1447 padding: 0 0 8px !important;
1447 padding: 0 0 8px !important;
1448 }
1448 }
1449
1449
1450 #content div.box div.form div.fields div.field div.label label,div.label label
1450 #content div.box div.form div.fields div.field div.label label,div.label label
1451 {
1451 {
1452 color: #393939;
1452 color: #393939;
1453 font-weight: 700;
1453 font-weight: 700;
1454 }
1454 }
1455 #content div.box div.form div.fields div.field div.label label,div.label-summary label
1455 #content div.box div.form div.fields div.field div.label label,div.label-summary label
1456 {
1456 {
1457 color: #393939;
1457 color: #393939;
1458 font-weight: 700;
1458 font-weight: 700;
1459 }
1459 }
1460 #content div.box div.form div.fields div.field div.input {
1460 #content div.box div.form div.fields div.field div.input {
1461 margin: 0 0 0 200px;
1461 margin: 0 0 0 200px;
1462 }
1462 }
1463
1463
1464 #content div.box div.form div.fields div.field div.input.summary {
1464 #content div.box div.form div.fields div.field div.input.summary {
1465 margin: 0 0 0 110px;
1465 margin: 0 0 0 110px;
1466 }
1466 }
1467 #content div.box div.form div.fields div.field div.input.summary-short {
1467 #content div.box div.form div.fields div.field div.input.summary-short {
1468 margin: 0 0 0 110px;
1468 margin: 0 0 0 110px;
1469 }
1469 }
1470 #content div.box div.form div.fields div.field div.file {
1470 #content div.box div.form div.fields div.field div.file {
1471 margin: 0 0 0 200px;
1471 margin: 0 0 0 200px;
1472 }
1472 }
1473
1473
1474 #content div.box-left div.form div.fields div.field div.input,#content div.box-right div.form div.fields div.field div.input
1474 #content div.box-left div.form div.fields div.field div.input,#content div.box-right div.form div.fields div.field div.input
1475 {
1475 {
1476 margin: 0 0 0 0px;
1476 margin: 0 0 0 0px;
1477 }
1477 }
1478
1478
1479 #content div.box div.form div.fields div.field div.input input,
1479 #content div.box div.form div.fields div.field div.input input,
1480 .reviewer_ac input {
1480 .reviewer_ac input {
1481 background: #FFF;
1481 background: #FFF;
1482 border-top: 1px solid #b3b3b3;
1482 border-top: 1px solid #b3b3b3;
1483 border-left: 1px solid #b3b3b3;
1483 border-left: 1px solid #b3b3b3;
1484 border-right: 1px solid #eaeaea;
1484 border-right: 1px solid #eaeaea;
1485 border-bottom: 1px solid #eaeaea;
1485 border-bottom: 1px solid #eaeaea;
1486 color: #000;
1486 color: #000;
1487 font-size: 11px;
1487 font-size: 11px;
1488 margin: 0;
1488 margin: 0;
1489 padding: 7px 7px 6px;
1489 padding: 7px 7px 6px;
1490 }
1490 }
1491
1491
1492 #content div.box div.form div.fields div.field div.input input#clone_url,
1492 #content div.box div.form div.fields div.field div.input input#clone_url,
1493 #content div.box div.form div.fields div.field div.input input#clone_url_id
1493 #content div.box div.form div.fields div.field div.input input#clone_url_id
1494 {
1494 {
1495 font-size: 16px;
1495 font-size: 16px;
1496 padding: 2px;
1496 padding: 2px;
1497 }
1497 }
1498
1498
1499 #content div.box div.form div.fields div.field div.file input {
1499 #content div.box div.form div.fields div.field div.file input {
1500 background: none repeat scroll 0 0 #FFFFFF;
1500 background: none repeat scroll 0 0 #FFFFFF;
1501 border-color: #B3B3B3 #EAEAEA #EAEAEA #B3B3B3;
1501 border-color: #B3B3B3 #EAEAEA #EAEAEA #B3B3B3;
1502 border-style: solid;
1502 border-style: solid;
1503 border-width: 1px;
1503 border-width: 1px;
1504 color: #000000;
1504 color: #000000;
1505 font-size: 11px;
1505 font-size: 11px;
1506 margin: 0;
1506 margin: 0;
1507 padding: 7px 7px 6px;
1507 padding: 7px 7px 6px;
1508 }
1508 }
1509
1509
1510 input.disabled {
1510 input.disabled {
1511 background-color: #F5F5F5 !important;
1511 background-color: #F5F5F5 !important;
1512 }
1512 }
1513 #content div.box div.form div.fields div.field div.input input.small {
1513 #content div.box div.form div.fields div.field div.input input.small {
1514 width: 30%;
1514 width: 30%;
1515 }
1515 }
1516
1516
1517 #content div.box div.form div.fields div.field div.input input.medium {
1517 #content div.box div.form div.fields div.field div.input input.medium {
1518 width: 55%;
1518 width: 55%;
1519 }
1519 }
1520
1520
1521 #content div.box div.form div.fields div.field div.input input.large {
1521 #content div.box div.form div.fields div.field div.input input.large {
1522 width: 85%;
1522 width: 85%;
1523 }
1523 }
1524
1524
1525 #content div.box div.form div.fields div.field div.input input.date {
1525 #content div.box div.form div.fields div.field div.input input.date {
1526 width: 177px;
1526 width: 177px;
1527 }
1527 }
1528
1528
1529 #content div.box div.form div.fields div.field div.input input.button {
1529 #content div.box div.form div.fields div.field div.input input.button {
1530 background: #D4D0C8;
1530 background: #D4D0C8;
1531 border-top: 1px solid #FFF;
1531 border-top: 1px solid #FFF;
1532 border-left: 1px solid #FFF;
1532 border-left: 1px solid #FFF;
1533 border-right: 1px solid #404040;
1533 border-right: 1px solid #404040;
1534 border-bottom: 1px solid #404040;
1534 border-bottom: 1px solid #404040;
1535 color: #000;
1535 color: #000;
1536 margin: 0;
1536 margin: 0;
1537 padding: 4px 8px;
1537 padding: 4px 8px;
1538 }
1538 }
1539
1539
1540 #content div.box div.form div.fields div.field div.textarea {
1540 #content div.box div.form div.fields div.field div.textarea {
1541 border-top: 1px solid #b3b3b3;
1541 border-top: 1px solid #b3b3b3;
1542 border-left: 1px solid #b3b3b3;
1542 border-left: 1px solid #b3b3b3;
1543 border-right: 1px solid #eaeaea;
1543 border-right: 1px solid #eaeaea;
1544 border-bottom: 1px solid #eaeaea;
1544 border-bottom: 1px solid #eaeaea;
1545 margin: 0 0 0 200px;
1545 margin: 0 0 0 200px;
1546 padding: 10px;
1546 padding: 10px;
1547 }
1547 }
1548
1548
1549 #content div.box div.form div.fields div.field div.textarea-editor {
1549 #content div.box div.form div.fields div.field div.textarea-editor {
1550 border: 1px solid #ddd;
1550 border: 1px solid #ddd;
1551 padding: 0;
1551 padding: 0;
1552 }
1552 }
1553
1553
1554 #content div.box div.form div.fields div.field div.textarea textarea {
1554 #content div.box div.form div.fields div.field div.textarea textarea {
1555 width: 100%;
1555 width: 100%;
1556 height: 220px;
1556 height: 220px;
1557 overflow: hidden;
1557 overflow: hidden;
1558 background: #FFF;
1558 background: #FFF;
1559 color: #000;
1559 color: #000;
1560 font-size: 11px;
1560 font-size: 11px;
1561 outline: none;
1561 outline: none;
1562 border-width: 0;
1562 border-width: 0;
1563 margin: 0;
1563 margin: 0;
1564 padding: 0;
1564 padding: 0;
1565 }
1565 }
1566
1566
1567 #content div.box-left div.form div.fields div.field div.textarea textarea,#content div.box-right div.form div.fields div.field div.textarea textarea
1567 #content div.box-left div.form div.fields div.field div.textarea textarea,#content div.box-right div.form div.fields div.field div.textarea textarea
1568 {
1568 {
1569 width: 100%;
1569 width: 100%;
1570 height: 100px;
1570 height: 100px;
1571 }
1571 }
1572
1572
1573 #content div.box div.form div.fields div.field div.textarea table {
1573 #content div.box div.form div.fields div.field div.textarea table {
1574 width: 100%;
1574 width: 100%;
1575 border: none;
1575 border: none;
1576 margin: 0;
1576 margin: 0;
1577 padding: 0;
1577 padding: 0;
1578 }
1578 }
1579
1579
1580 #content div.box div.form div.fields div.field div.textarea table td {
1580 #content div.box div.form div.fields div.field div.textarea table td {
1581 background: #DDD;
1581 background: #DDD;
1582 border: none;
1582 border: none;
1583 padding: 0;
1583 padding: 0;
1584 }
1584 }
1585
1585
1586 #content div.box div.form div.fields div.field div.textarea table td table
1586 #content div.box div.form div.fields div.field div.textarea table td table
1587 {
1587 {
1588 width: auto;
1588 width: auto;
1589 border: none;
1589 border: none;
1590 margin: 0;
1590 margin: 0;
1591 padding: 0;
1591 padding: 0;
1592 }
1592 }
1593
1593
1594 #content div.box div.form div.fields div.field div.textarea table td table td
1594 #content div.box div.form div.fields div.field div.textarea table td table td
1595 {
1595 {
1596 font-size: 11px;
1596 font-size: 11px;
1597 padding: 5px 5px 5px 0;
1597 padding: 5px 5px 5px 0;
1598 }
1598 }
1599
1599
1600 #content div.box div.form div.fields div.field input[type=text]:focus,
1600 #content div.box div.form div.fields div.field input[type=text]:focus,
1601 #content div.box div.form div.fields div.field input[type=password]:focus,
1601 #content div.box div.form div.fields div.field input[type=password]:focus,
1602 #content div.box div.form div.fields div.field input[type=file]:focus,
1602 #content div.box div.form div.fields div.field input[type=file]:focus,
1603 #content div.box div.form div.fields div.field textarea:focus,
1603 #content div.box div.form div.fields div.field textarea:focus,
1604 #content div.box div.form div.fields div.field select:focus,
1604 #content div.box div.form div.fields div.field select:focus,
1605 .reviewer_ac input:focus
1605 .reviewer_ac input:focus
1606 {
1606 {
1607 background: #f6f6f6;
1607 background: #f6f6f6;
1608 border-color: #666;
1608 border-color: #666;
1609 }
1609 }
1610
1610
1611 .reviewer_ac {
1611 .reviewer_ac {
1612 padding:10px
1612 padding:10px
1613 }
1613 }
1614
1614
1615 div.form div.fields div.field div.button {
1615 div.form div.fields div.field div.button {
1616 margin: 0;
1616 margin: 0;
1617 padding: 0 0 0 8px;
1617 padding: 0 0 0 8px;
1618 }
1618 }
1619 #content div.box table.noborder {
1619 #content div.box table.noborder {
1620 border: 1px solid transparent;
1620 border: 1px solid transparent;
1621 }
1621 }
1622
1622
1623 #content div.box table {
1623 #content div.box table {
1624 width: 100%;
1624 width: 100%;
1625 border-collapse: separate;
1625 border-collapse: separate;
1626 margin: 0;
1626 margin: 0;
1627 padding: 0;
1627 padding: 0;
1628 border: 1px solid #eee;
1628 border: 1px solid #eee;
1629 -webkit-border-radius: 4px;
1629 -webkit-border-radius: 4px;
1630 -moz-border-radius: 4px;
1630 -moz-border-radius: 4px;
1631 border-radius: 4px;
1631 border-radius: 4px;
1632 }
1632 }
1633
1633
1634 #content div.box table th {
1634 #content div.box table th {
1635 background: #eee;
1635 background: #eee;
1636 border-bottom: 1px solid #ddd;
1636 border-bottom: 1px solid #ddd;
1637 padding: 5px 0px 5px 5px;
1637 padding: 5px 0px 5px 5px;
1638 text-align: left;
1638 text-align: left;
1639 }
1639 }
1640
1640
1641 #content div.box table th.left {
1641 #content div.box table th.left {
1642 text-align: left;
1642 text-align: left;
1643 }
1643 }
1644
1644
1645 #content div.box table th.right {
1645 #content div.box table th.right {
1646 text-align: right;
1646 text-align: right;
1647 }
1647 }
1648
1648
1649 #content div.box table th.center {
1649 #content div.box table th.center {
1650 text-align: center;
1650 text-align: center;
1651 }
1651 }
1652
1652
1653 #content div.box table th.selected {
1653 #content div.box table th.selected {
1654 vertical-align: middle;
1654 vertical-align: middle;
1655 padding: 0;
1655 padding: 0;
1656 }
1656 }
1657
1657
1658 #content div.box table td {
1658 #content div.box table td {
1659 background: #fff;
1659 background: #fff;
1660 border-bottom: 1px solid #cdcdcd;
1660 border-bottom: 1px solid #cdcdcd;
1661 vertical-align: middle;
1661 vertical-align: middle;
1662 padding: 5px;
1662 padding: 5px;
1663 }
1663 }
1664
1664
1665 #content div.box table tr.selected td {
1665 #content div.box table tr.selected td {
1666 background: #FFC;
1666 background: #FFC;
1667 }
1667 }
1668
1668
1669 #content div.box table td.selected {
1669 #content div.box table td.selected {
1670 width: 3%;
1670 width: 3%;
1671 text-align: center;
1671 text-align: center;
1672 vertical-align: middle;
1672 vertical-align: middle;
1673 padding: 0;
1673 padding: 0;
1674 }
1674 }
1675
1675
1676 #content div.box table td.action {
1676 #content div.box table td.action {
1677 width: 45%;
1677 width: 45%;
1678 text-align: left;
1678 text-align: left;
1679 }
1679 }
1680
1680
1681 #content div.box table td.date {
1681 #content div.box table td.date {
1682 width: 33%;
1682 width: 33%;
1683 text-align: center;
1683 text-align: center;
1684 }
1684 }
1685
1685
1686 #content div.box div.action {
1686 #content div.box div.action {
1687 float: right;
1687 float: right;
1688 background: #FFF;
1688 background: #FFF;
1689 text-align: right;
1689 text-align: right;
1690 margin: 10px 0 0;
1690 margin: 10px 0 0;
1691 padding: 0;
1691 padding: 0;
1692 }
1692 }
1693
1693
1694 #content div.box div.action select {
1694 #content div.box div.action select {
1695 font-size: 11px;
1695 font-size: 11px;
1696 margin: 0;
1696 margin: 0;
1697 }
1697 }
1698
1698
1699 #content div.box div.action .ui-selectmenu {
1699 #content div.box div.action .ui-selectmenu {
1700 margin: 0;
1700 margin: 0;
1701 padding: 0;
1701 padding: 0;
1702 }
1702 }
1703
1703
1704 #content div.box div.pagination {
1704 #content div.box div.pagination {
1705 height: 1%;
1705 height: 1%;
1706 clear: both;
1706 clear: both;
1707 overflow: hidden;
1707 overflow: hidden;
1708 margin: 10px 0 0;
1708 margin: 10px 0 0;
1709 padding: 0;
1709 padding: 0;
1710 }
1710 }
1711
1711
1712 #content div.box div.pagination ul.pager {
1712 #content div.box div.pagination ul.pager {
1713 float: right;
1713 float: right;
1714 text-align: right;
1714 text-align: right;
1715 margin: 0;
1715 margin: 0;
1716 padding: 0;
1716 padding: 0;
1717 }
1717 }
1718
1718
1719 #content div.box div.pagination ul.pager li {
1719 #content div.box div.pagination ul.pager li {
1720 height: 1%;
1720 height: 1%;
1721 float: left;
1721 float: left;
1722 list-style: none;
1722 list-style: none;
1723 background: #ebebeb url("../images/pager.png") repeat-x;
1723 background: #ebebeb url("../images/pager.png") repeat-x;
1724 border-top: 1px solid #dedede;
1724 border-top: 1px solid #dedede;
1725 border-left: 1px solid #cfcfcf;
1725 border-left: 1px solid #cfcfcf;
1726 border-right: 1px solid #c4c4c4;
1726 border-right: 1px solid #c4c4c4;
1727 border-bottom: 1px solid #c4c4c4;
1727 border-bottom: 1px solid #c4c4c4;
1728 color: #4A4A4A;
1728 color: #4A4A4A;
1729 font-weight: 700;
1729 font-weight: 700;
1730 margin: 0 0 0 4px;
1730 margin: 0 0 0 4px;
1731 padding: 0;
1731 padding: 0;
1732 }
1732 }
1733
1733
1734 #content div.box div.pagination ul.pager li.separator {
1734 #content div.box div.pagination ul.pager li.separator {
1735 padding: 6px;
1735 padding: 6px;
1736 }
1736 }
1737
1737
1738 #content div.box div.pagination ul.pager li.current {
1738 #content div.box div.pagination ul.pager li.current {
1739 background: #b4b4b4 url("../images/pager_selected.png") repeat-x;
1739 background: #b4b4b4 url("../images/pager_selected.png") repeat-x;
1740 border-top: 1px solid #ccc;
1740 border-top: 1px solid #ccc;
1741 border-left: 1px solid #bebebe;
1741 border-left: 1px solid #bebebe;
1742 border-right: 1px solid #b1b1b1;
1742 border-right: 1px solid #b1b1b1;
1743 border-bottom: 1px solid #afafaf;
1743 border-bottom: 1px solid #afafaf;
1744 color: #515151;
1744 color: #515151;
1745 padding: 6px;
1745 padding: 6px;
1746 }
1746 }
1747
1747
1748 #content div.box div.pagination ul.pager li a {
1748 #content div.box div.pagination ul.pager li a {
1749 height: 1%;
1749 height: 1%;
1750 display: block;
1750 display: block;
1751 float: left;
1751 float: left;
1752 color: #515151;
1752 color: #515151;
1753 text-decoration: none;
1753 text-decoration: none;
1754 margin: 0;
1754 margin: 0;
1755 padding: 6px;
1755 padding: 6px;
1756 }
1756 }
1757
1757
1758 #content div.box div.pagination ul.pager li a:hover,#content div.box div.pagination ul.pager li a:active
1758 #content div.box div.pagination ul.pager li a:hover,#content div.box div.pagination ul.pager li a:active
1759 {
1759 {
1760 background: #b4b4b4 url("../images/pager_selected.png") repeat-x;
1760 background: #b4b4b4 url("../images/pager_selected.png") repeat-x;
1761 border-top: 1px solid #ccc;
1761 border-top: 1px solid #ccc;
1762 border-left: 1px solid #bebebe;
1762 border-left: 1px solid #bebebe;
1763 border-right: 1px solid #b1b1b1;
1763 border-right: 1px solid #b1b1b1;
1764 border-bottom: 1px solid #afafaf;
1764 border-bottom: 1px solid #afafaf;
1765 margin: -1px;
1765 margin: -1px;
1766 }
1766 }
1767
1767
1768 #content div.box div.pagination-wh {
1768 #content div.box div.pagination-wh {
1769 height: 1%;
1769 height: 1%;
1770 clear: both;
1770 clear: both;
1771 overflow: hidden;
1771 overflow: hidden;
1772 text-align: right;
1772 text-align: right;
1773 margin: 10px 0 0;
1773 margin: 10px 0 0;
1774 padding: 0;
1774 padding: 0;
1775 }
1775 }
1776
1776
1777 #content div.box div.pagination-right {
1777 #content div.box div.pagination-right {
1778 float: right;
1778 float: right;
1779 }
1779 }
1780
1780
1781 #content div.box div.pagination-wh a,
1781 #content div.box div.pagination-wh a,
1782 #content div.box div.pagination-wh span.pager_dotdot,
1782 #content div.box div.pagination-wh span.pager_dotdot,
1783 #content div.box div.pagination-wh span.yui-pg-previous,
1783 #content div.box div.pagination-wh span.yui-pg-previous,
1784 #content div.box div.pagination-wh span.yui-pg-last,
1784 #content div.box div.pagination-wh span.yui-pg-last,
1785 #content div.box div.pagination-wh span.yui-pg-next,
1785 #content div.box div.pagination-wh span.yui-pg-next,
1786 #content div.box div.pagination-wh span.yui-pg-first
1786 #content div.box div.pagination-wh span.yui-pg-first
1787 {
1787 {
1788 height: 1%;
1788 height: 1%;
1789 float: left;
1789 float: left;
1790 background: #ebebeb url("../images/pager.png") repeat-x;
1790 background: #ebebeb url("../images/pager.png") repeat-x;
1791 border-top: 1px solid #dedede;
1791 border-top: 1px solid #dedede;
1792 border-left: 1px solid #cfcfcf;
1792 border-left: 1px solid #cfcfcf;
1793 border-right: 1px solid #c4c4c4;
1793 border-right: 1px solid #c4c4c4;
1794 border-bottom: 1px solid #c4c4c4;
1794 border-bottom: 1px solid #c4c4c4;
1795 color: #4A4A4A;
1795 color: #4A4A4A;
1796 font-weight: 700;
1796 font-weight: 700;
1797 margin: 0 0 0 4px;
1797 margin: 0 0 0 4px;
1798 padding: 6px;
1798 padding: 6px;
1799 }
1799 }
1800
1800
1801 #content div.box div.pagination-wh span.pager_curpage {
1801 #content div.box div.pagination-wh span.pager_curpage {
1802 height: 1%;
1802 height: 1%;
1803 float: left;
1803 float: left;
1804 background: #b4b4b4 url("../images/pager_selected.png") repeat-x;
1804 background: #b4b4b4 url("../images/pager_selected.png") repeat-x;
1805 border-top: 1px solid #ccc;
1805 border-top: 1px solid #ccc;
1806 border-left: 1px solid #bebebe;
1806 border-left: 1px solid #bebebe;
1807 border-right: 1px solid #b1b1b1;
1807 border-right: 1px solid #b1b1b1;
1808 border-bottom: 1px solid #afafaf;
1808 border-bottom: 1px solid #afafaf;
1809 color: #515151;
1809 color: #515151;
1810 font-weight: 700;
1810 font-weight: 700;
1811 margin: 0 0 0 4px;
1811 margin: 0 0 0 4px;
1812 padding: 6px;
1812 padding: 6px;
1813 }
1813 }
1814
1814
1815 #content div.box div.pagination-wh a:hover,#content div.box div.pagination-wh a:active
1815 #content div.box div.pagination-wh a:hover,#content div.box div.pagination-wh a:active
1816 {
1816 {
1817 background: #b4b4b4 url("../images/pager_selected.png") repeat-x;
1817 background: #b4b4b4 url("../images/pager_selected.png") repeat-x;
1818 border-top: 1px solid #ccc;
1818 border-top: 1px solid #ccc;
1819 border-left: 1px solid #bebebe;
1819 border-left: 1px solid #bebebe;
1820 border-right: 1px solid #b1b1b1;
1820 border-right: 1px solid #b1b1b1;
1821 border-bottom: 1px solid #afafaf;
1821 border-bottom: 1px solid #afafaf;
1822 text-decoration: none;
1822 text-decoration: none;
1823 }
1823 }
1824
1824
1825 #content div.box div.traffic div.legend {
1825 #content div.box div.traffic div.legend {
1826 clear: both;
1826 clear: both;
1827 overflow: hidden;
1827 overflow: hidden;
1828 border-bottom: 1px solid #ddd;
1828 border-bottom: 1px solid #ddd;
1829 margin: 0 0 10px;
1829 margin: 0 0 10px;
1830 padding: 0 0 10px;
1830 padding: 0 0 10px;
1831 }
1831 }
1832
1832
1833 #content div.box div.traffic div.legend h6 {
1833 #content div.box div.traffic div.legend h6 {
1834 float: left;
1834 float: left;
1835 border: none;
1835 border: none;
1836 margin: 0;
1836 margin: 0;
1837 padding: 0;
1837 padding: 0;
1838 }
1838 }
1839
1839
1840 #content div.box div.traffic div.legend li {
1840 #content div.box div.traffic div.legend li {
1841 list-style: none;
1841 list-style: none;
1842 float: left;
1842 float: left;
1843 font-size: 11px;
1843 font-size: 11px;
1844 margin: 0;
1844 margin: 0;
1845 padding: 0 8px 0 4px;
1845 padding: 0 8px 0 4px;
1846 }
1846 }
1847
1847
1848 #content div.box div.traffic div.legend li.visits {
1848 #content div.box div.traffic div.legend li.visits {
1849 border-left: 12px solid #edc240;
1849 border-left: 12px solid #edc240;
1850 }
1850 }
1851
1851
1852 #content div.box div.traffic div.legend li.pageviews {
1852 #content div.box div.traffic div.legend li.pageviews {
1853 border-left: 12px solid #afd8f8;
1853 border-left: 12px solid #afd8f8;
1854 }
1854 }
1855
1855
1856 #content div.box div.traffic table {
1856 #content div.box div.traffic table {
1857 width: auto;
1857 width: auto;
1858 }
1858 }
1859
1859
1860 #content div.box div.traffic table td {
1860 #content div.box div.traffic table td {
1861 background: transparent;
1861 background: transparent;
1862 border: none;
1862 border: none;
1863 padding: 2px 3px 3px;
1863 padding: 2px 3px 3px;
1864 }
1864 }
1865
1865
1866 #content div.box div.traffic table td.legendLabel {
1866 #content div.box div.traffic table td.legendLabel {
1867 padding: 0 3px 2px;
1867 padding: 0 3px 2px;
1868 }
1868 }
1869
1869
1870 #summary {
1870 #summary {
1871
1871
1872 }
1872 }
1873
1873
1874 #summary .metatag {
1874 #summary .metatag {
1875 display: inline-block;
1875 display: inline-block;
1876 padding: 3px 5px;
1876 padding: 3px 5px;
1877 margin-bottom: 3px;
1877 margin-bottom: 3px;
1878 margin-right: 1px;
1878 margin-right: 1px;
1879 border-radius: 5px;
1879 border-radius: 5px;
1880 }
1880 }
1881
1881
1882 #content div.box #summary p {
1882 #content div.box #summary p {
1883 margin-bottom: -5px;
1883 margin-bottom: -5px;
1884 width: 600px;
1884 width: 600px;
1885 white-space: pre-wrap;
1885 white-space: pre-wrap;
1886 }
1886 }
1887
1887
1888 #content div.box #summary p:last-child {
1888 #content div.box #summary p:last-child {
1889 margin-bottom: 9px;
1889 margin-bottom: 9px;
1890 }
1890 }
1891
1891
1892 #content div.box #summary p:first-of-type {
1892 #content div.box #summary p:first-of-type {
1893 margin-top: 9px;
1893 margin-top: 9px;
1894 }
1894 }
1895
1895
1896 .metatag {
1896 .metatag {
1897 display: inline-block;
1897 display: inline-block;
1898 margin-right: 1px;
1898 margin-right: 1px;
1899 -webkit-border-radius: 4px 4px 4px 4px;
1899 -webkit-border-radius: 4px 4px 4px 4px;
1900 -khtml-border-radius: 4px 4px 4px 4px;
1900 -khtml-border-radius: 4px 4px 4px 4px;
1901 -moz-border-radius: 4px 4px 4px 4px;
1901 -moz-border-radius: 4px 4px 4px 4px;
1902 border-radius: 4px 4px 4px 4px;
1902 border-radius: 4px 4px 4px 4px;
1903
1903
1904 border: solid 1px #9CF;
1904 border: solid 1px #9CF;
1905 padding: 2px 3px 2px 3px !important;
1905 padding: 2px 3px 2px 3px !important;
1906 background-color: #DEF;
1906 background-color: #DEF;
1907 }
1907 }
1908
1908
1909 .metatag[tag="dead"] {
1909 .metatag[tag="dead"] {
1910 background-color: #E44;
1910 background-color: #E44;
1911 }
1911 }
1912
1912
1913 .metatag[tag="stale"] {
1913 .metatag[tag="stale"] {
1914 background-color: #EA4;
1914 background-color: #EA4;
1915 }
1915 }
1916
1916
1917 .metatag[tag="featured"] {
1917 .metatag[tag="featured"] {
1918 background-color: #AEA;
1918 background-color: #AEA;
1919 }
1919 }
1920
1920
1921 .metatag[tag="requires"] {
1921 .metatag[tag="requires"] {
1922 background-color: #9CF;
1922 background-color: #9CF;
1923 }
1923 }
1924
1924
1925 .metatag[tag="recommends"] {
1925 .metatag[tag="recommends"] {
1926 background-color: #BDF;
1926 background-color: #BDF;
1927 }
1927 }
1928
1928
1929 .metatag[tag="lang"] {
1929 .metatag[tag="lang"] {
1930 background-color: #FAF474;
1930 background-color: #FAF474;
1931 }
1931 }
1932
1932
1933 .metatag[tag="license"] {
1933 .metatag[tag="license"] {
1934 border: solid 1px #9CF;
1934 border: solid 1px #9CF;
1935 background-color: #DEF;
1935 background-color: #DEF;
1936 target-new: tab !important;
1936 target-new: tab !important;
1937 }
1937 }
1938 .metatag[tag="see"] {
1938 .metatag[tag="see"] {
1939 border: solid 1px #CBD;
1939 border: solid 1px #CBD;
1940 background-color: #EDF;
1940 background-color: #EDF;
1941 }
1941 }
1942
1942
1943 a.metatag[tag="license"]:hover {
1943 a.metatag[tag="license"]:hover {
1944 background-color: #003367;
1944 background-color: #003367;
1945 color: #FFF;
1945 color: #FFF;
1946 text-decoration: none;
1946 text-decoration: none;
1947 }
1947 }
1948
1948
1949 #summary .desc {
1949 #summary .desc {
1950 white-space: pre;
1950 white-space: pre;
1951 width: 100%;
1951 width: 100%;
1952 }
1952 }
1953
1953
1954 #summary .repo_name {
1954 #summary .repo_name {
1955 font-size: 1.6em;
1955 font-size: 1.6em;
1956 font-weight: bold;
1956 font-weight: bold;
1957 vertical-align: baseline;
1957 vertical-align: baseline;
1958 clear: right
1958 clear: right
1959 }
1959 }
1960
1960
1961 #footer {
1961 #footer {
1962 clear: both;
1962 clear: both;
1963 overflow: hidden;
1963 overflow: hidden;
1964 text-align: right;
1964 text-align: right;
1965 margin: 0;
1965 margin: 0;
1966 padding: 0 10px 4px;
1966 padding: 0 10px 4px;
1967 margin: -10px 0 0;
1967 margin: -10px 0 0;
1968 }
1968 }
1969
1969
1970 #footer div#footer-inner {
1970 #footer div#footer-inner {
1971 background-color: #003B76;
1971 background-color: #003B76;
1972 background-repeat : repeat-x;
1972 background-repeat : repeat-x;
1973 background-image : -khtml-gradient( linear, left top, left bottom, from(#003B76), to(#00376E));
1973 background-image : -khtml-gradient( linear, left top, left bottom, from(#003B76), to(#00376E));
1974 background-image : -moz-linear-gradient(top, #003b76, #00376e);
1974 background-image : -moz-linear-gradient(top, #003b76, #00376e);
1975 background-image : -ms-linear-gradient( top, #003b76, #00376e);
1975 background-image : -ms-linear-gradient( top, #003b76, #00376e);
1976 background-image : -webkit-gradient( linear, left top, left bottom, color-stop( 0%, #003b76), color-stop( 100%, #00376e));
1976 background-image : -webkit-gradient( linear, left top, left bottom, color-stop( 0%, #003b76), color-stop( 100%, #00376e));
1977 background-image : -webkit-linear-gradient( top, #003b76, #00376e));
1977 background-image : -webkit-linear-gradient( top, #003b76, #00376e));
1978 background-image : -o-linear-gradient( top, #003b76, #00376e));
1978 background-image : -o-linear-gradient( top, #003b76, #00376e));
1979 background-image : linear-gradient( top, #003b76, #00376e);
1979 background-image : linear-gradient( top, #003b76, #00376e);
1980 filter :progid : DXImageTransform.Microsoft.gradient ( startColorstr = '#003b76', endColorstr = '#00376e', GradientType = 0);
1980 filter :progid : DXImageTransform.Microsoft.gradient ( startColorstr = '#003b76', endColorstr = '#00376e', GradientType = 0);
1981 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
1981 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
1982 -webkit-border-radius: 4px 4px 4px 4px;
1982 -webkit-border-radius: 4px 4px 4px 4px;
1983 -khtml-border-radius: 4px 4px 4px 4px;
1983 -khtml-border-radius: 4px 4px 4px 4px;
1984 -moz-border-radius: 4px 4px 4px 4px;
1984 -moz-border-radius: 4px 4px 4px 4px;
1985 border-radius: 4px 4px 4px 4px;
1985 border-radius: 4px 4px 4px 4px;
1986 }
1986 }
1987
1987
1988 #footer div#footer-inner p {
1988 #footer div#footer-inner p {
1989 padding: 15px 25px 15px 0;
1989 padding: 15px 25px 15px 0;
1990 color: #FFF;
1990 color: #FFF;
1991 font-weight: 700;
1991 font-weight: 700;
1992 }
1992 }
1993
1993
1994 #footer div#footer-inner .footer-link {
1994 #footer div#footer-inner .footer-link {
1995 float: left;
1995 float: left;
1996 padding-left: 10px;
1996 padding-left: 10px;
1997 }
1997 }
1998
1998
1999 #footer div#footer-inner .footer-link a,#footer div#footer-inner .footer-link-right a
1999 #footer div#footer-inner .footer-link a,#footer div#footer-inner .footer-link-right a
2000 {
2000 {
2001 color: #FFF;
2001 color: #FFF;
2002 }
2002 }
2003
2003
2004 #login div.title {
2004 #login div.title {
2005 clear: both;
2005 clear: both;
2006 overflow: hidden;
2006 overflow: hidden;
2007 position: relative;
2007 position: relative;
2008 background-color: #003B76;
2008 background-color: #003B76;
2009 background-repeat : repeat-x;
2009 background-repeat : repeat-x;
2010 background-image : -khtml-gradient( linear, left top, left bottom, from(#003B76), to(#00376E));
2010 background-image : -khtml-gradient( linear, left top, left bottom, from(#003B76), to(#00376E));
2011 background-image : -moz-linear-gradient( top, #003b76, #00376e);
2011 background-image : -moz-linear-gradient( top, #003b76, #00376e);
2012 background-image : -ms-linear-gradient( top, #003b76, #00376e);
2012 background-image : -ms-linear-gradient( top, #003b76, #00376e);
2013 background-image : -webkit-gradient( linear, left top, left bottom, color-stop( 0%, #003b76), color-stop( 100%, #00376e));
2013 background-image : -webkit-gradient( linear, left top, left bottom, color-stop( 0%, #003b76), color-stop( 100%, #00376e));
2014 background-image : -webkit-linear-gradient( top, #003b76, #00376e));
2014 background-image : -webkit-linear-gradient( top, #003b76, #00376e));
2015 background-image : -o-linear-gradient( top, #003b76, #00376e));
2015 background-image : -o-linear-gradient( top, #003b76, #00376e));
2016 background-image : linear-gradient( top, #003b76, #00376e);
2016 background-image : linear-gradient( top, #003b76, #00376e);
2017 filter : progid : DXImageTransform.Microsoft.gradient ( startColorstr = '#003b76', endColorstr = '#00376e', GradientType = 0);
2017 filter : progid : DXImageTransform.Microsoft.gradient ( startColorstr = '#003b76', endColorstr = '#00376e', GradientType = 0);
2018 margin: 0 auto;
2018 margin: 0 auto;
2019 padding: 0;
2019 padding: 0;
2020 }
2020 }
2021
2021
2022 #login div.inner {
2022 #login div.inner {
2023 background: #FFF url("../images/login.png") no-repeat top left;
2023 background: #FFF url("../images/login.png") no-repeat top left;
2024 border-top: none;
2024 border-top: none;
2025 border-bottom: none;
2025 border-bottom: none;
2026 margin: 0 auto;
2026 margin: 0 auto;
2027 padding: 20px;
2027 padding: 20px;
2028 }
2028 }
2029
2029
2030 #login div.form div.fields div.field div.label {
2030 #login div.form div.fields div.field div.label {
2031 width: 173px;
2031 width: 173px;
2032 float: left;
2032 float: left;
2033 text-align: right;
2033 text-align: right;
2034 margin: 2px 10px 0 0;
2034 margin: 2px 10px 0 0;
2035 padding: 5px 0 0 5px;
2035 padding: 5px 0 0 5px;
2036 }
2036 }
2037
2037
2038 #login div.form div.fields div.field div.input input {
2038 #login div.form div.fields div.field div.input input {
2039 background: #FFF;
2039 background: #FFF;
2040 border-top: 1px solid #b3b3b3;
2040 border-top: 1px solid #b3b3b3;
2041 border-left: 1px solid #b3b3b3;
2041 border-left: 1px solid #b3b3b3;
2042 border-right: 1px solid #eaeaea;
2042 border-right: 1px solid #eaeaea;
2043 border-bottom: 1px solid #eaeaea;
2043 border-bottom: 1px solid #eaeaea;
2044 color: #000;
2044 color: #000;
2045 font-size: 11px;
2045 font-size: 11px;
2046 margin: 0;
2046 margin: 0;
2047 padding: 7px 7px 6px;
2047 padding: 7px 7px 6px;
2048 }
2048 }
2049
2049
2050 #login div.form div.fields div.buttons {
2050 #login div.form div.fields div.buttons {
2051 clear: both;
2051 clear: both;
2052 overflow: hidden;
2052 overflow: hidden;
2053 border-top: 1px solid #DDD;
2053 border-top: 1px solid #DDD;
2054 text-align: right;
2054 text-align: right;
2055 margin: 0;
2055 margin: 0;
2056 padding: 10px 0 0;
2056 padding: 10px 0 0;
2057 }
2057 }
2058
2058
2059 #login div.form div.links {
2059 #login div.form div.links {
2060 clear: both;
2060 clear: both;
2061 overflow: hidden;
2061 overflow: hidden;
2062 margin: 10px 0 0;
2062 margin: 10px 0 0;
2063 padding: 0 0 2px;
2063 padding: 0 0 2px;
2064 }
2064 }
2065
2065
2066 .user-menu{
2066 .user-menu{
2067 margin: 0px !important;
2067 margin: 0px !important;
2068 float: left;
2068 float: left;
2069 }
2069 }
2070
2070
2071 .user-menu .container{
2071 .user-menu .container{
2072 padding:0px 4px 0px 4px;
2072 padding:0px 4px 0px 4px;
2073 margin: 0px 0px 0px 0px;
2073 margin: 0px 0px 0px 0px;
2074 }
2074 }
2075
2075
2076 .user-menu .gravatar{
2076 .user-menu .gravatar{
2077 margin: 0px 0px 0px 0px;
2077 margin: 0px 0px 0px 0px;
2078 cursor: pointer;
2078 cursor: pointer;
2079 }
2079 }
2080 .user-menu .gravatar.enabled{
2080 .user-menu .gravatar.enabled{
2081 background-color: #FDF784 !important;
2081 background-color: #FDF784 !important;
2082 }
2082 }
2083 .user-menu .gravatar:hover{
2083 .user-menu .gravatar:hover{
2084 background-color: #FDF784 !important;
2084 background-color: #FDF784 !important;
2085 }
2085 }
2086 #quick_login{
2086 #quick_login{
2087 min-height: 80px;
2087 min-height: 80px;
2088 margin: 37px 0 0 -251px;
2088 margin: 37px 0 0 -251px;
2089 padding: 4px;
2089 padding: 4px;
2090 position: absolute;
2090 position: absolute;
2091 width: 278px;
2091 width: 278px;
2092 background-color: #003B76;
2092 background-color: #003B76;
2093 background-repeat: repeat-x;
2093 background-repeat: repeat-x;
2094 background-image: -khtml-gradient(linear, left top, left bottom, from(#003B76), to(#00376E) );
2094 background-image: -khtml-gradient(linear, left top, left bottom, from(#003B76), to(#00376E) );
2095 background-image: -moz-linear-gradient(top, #003b76, #00376e);
2095 background-image: -moz-linear-gradient(top, #003b76, #00376e);
2096 background-image: -ms-linear-gradient(top, #003b76, #00376e);
2096 background-image: -ms-linear-gradient(top, #003b76, #00376e);
2097 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76), color-stop(100%, #00376e) );
2097 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76), color-stop(100%, #00376e) );
2098 background-image: -webkit-linear-gradient(top, #003b76, #00376e);
2098 background-image: -webkit-linear-gradient(top, #003b76, #00376e);
2099 background-image: -o-linear-gradient(top, #003b76, #00376e);
2099 background-image: -o-linear-gradient(top, #003b76, #00376e);
2100 background-image: linear-gradient(top, #003b76, #00376e);
2100 background-image: linear-gradient(top, #003b76, #00376e);
2101 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76', endColorstr='#00376e', GradientType=0 );
2101 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76', endColorstr='#00376e', GradientType=0 );
2102
2102
2103 z-index: 999;
2103 z-index: 999;
2104 -webkit-border-radius: 0px 0px 4px 4px;
2104 -webkit-border-radius: 0px 0px 4px 4px;
2105 -khtml-border-radius: 0px 0px 4px 4px;
2105 -khtml-border-radius: 0px 0px 4px 4px;
2106 -moz-border-radius: 0px 0px 4px 4px;
2106 -moz-border-radius: 0px 0px 4px 4px;
2107 border-radius: 0px 0px 4px 4px;
2107 border-radius: 0px 0px 4px 4px;
2108 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
2108 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
2109 }
2109 }
2110 #quick_login h4{
2110 #quick_login h4{
2111 color: #fff;
2111 color: #fff;
2112 padding: 5px 0px 5px 14px;
2112 padding: 5px 0px 5px 14px;
2113 }
2113 }
2114
2114
2115 #quick_login .password_forgoten {
2115 #quick_login .password_forgoten {
2116 padding-right: 10px;
2116 padding-right: 10px;
2117 padding-top: 0px;
2117 padding-top: 0px;
2118 text-align: left;
2118 text-align: left;
2119 }
2119 }
2120
2120
2121 #quick_login .password_forgoten a {
2121 #quick_login .password_forgoten a {
2122 font-size: 10px;
2122 font-size: 10px;
2123 color: #fff;
2123 color: #fff;
2124 }
2124 }
2125
2125
2126 #quick_login .register {
2126 #quick_login .register {
2127 padding-right: 10px;
2127 padding-right: 10px;
2128 padding-top: 5px;
2128 padding-top: 5px;
2129 text-align: left;
2129 text-align: left;
2130 }
2130 }
2131
2131
2132 #quick_login .register a {
2132 #quick_login .register a {
2133 font-size: 10px;
2133 font-size: 10px;
2134 color: #fff;
2134 color: #fff;
2135 }
2135 }
2136
2136
2137 #quick_login .submit {
2137 #quick_login .submit {
2138 margin: -20px 0 0 0px;
2138 margin: -20px 0 0 0px;
2139 position: absolute;
2139 position: absolute;
2140 right: 15px;
2140 right: 15px;
2141 }
2141 }
2142
2142
2143 #quick_login .links_left{
2143 #quick_login .links_left{
2144 float: left;
2144 float: left;
2145 }
2145 }
2146 #quick_login .links_right{
2146 #quick_login .links_right{
2147 float: right;
2147 float: right;
2148 }
2148 }
2149 #quick_login .full_name{
2149 #quick_login .full_name{
2150 color: #FFFFFF;
2150 color: #FFFFFF;
2151 font-weight: bold;
2151 font-weight: bold;
2152 padding: 3px;
2152 padding: 3px;
2153 }
2153 }
2154 #quick_login .big_gravatar{
2154 #quick_login .big_gravatar{
2155 padding:4px 0px 0px 6px;
2155 padding:4px 0px 0px 6px;
2156 }
2156 }
2157 #quick_login .inbox{
2157 #quick_login .inbox{
2158 padding:4px 0px 0px 6px;
2158 padding:4px 0px 0px 6px;
2159 color: #FFFFFF;
2159 color: #FFFFFF;
2160 font-weight: bold;
2160 font-weight: bold;
2161 }
2161 }
2162 #quick_login .inbox a{
2162 #quick_login .inbox a{
2163 color: #FFFFFF;
2163 color: #FFFFFF;
2164 }
2164 }
2165 #quick_login .email,#quick_login .email a{
2165 #quick_login .email,#quick_login .email a{
2166 color: #FFFFFF;
2166 color: #FFFFFF;
2167 padding: 3px;
2167 padding: 3px;
2168
2168
2169 }
2169 }
2170 #quick_login .links .logout{
2170 #quick_login .links .logout{
2171
2171
2172 }
2172 }
2173
2173
2174 #quick_login div.form div.fields {
2174 #quick_login div.form div.fields {
2175 padding-top: 2px;
2175 padding-top: 2px;
2176 padding-left: 10px;
2176 padding-left: 10px;
2177 }
2177 }
2178
2178
2179 #quick_login div.form div.fields div.field {
2179 #quick_login div.form div.fields div.field {
2180 padding: 5px;
2180 padding: 5px;
2181 }
2181 }
2182
2182
2183 #quick_login div.form div.fields div.field div.label label {
2183 #quick_login div.form div.fields div.field div.label label {
2184 color: #fff;
2184 color: #fff;
2185 padding-bottom: 3px;
2185 padding-bottom: 3px;
2186 }
2186 }
2187
2187
2188 #quick_login div.form div.fields div.field div.input input {
2188 #quick_login div.form div.fields div.field div.input input {
2189 width: 236px;
2189 width: 236px;
2190 background: #FFF;
2190 background: #FFF;
2191 border-top: 1px solid #b3b3b3;
2191 border-top: 1px solid #b3b3b3;
2192 border-left: 1px solid #b3b3b3;
2192 border-left: 1px solid #b3b3b3;
2193 border-right: 1px solid #eaeaea;
2193 border-right: 1px solid #eaeaea;
2194 border-bottom: 1px solid #eaeaea;
2194 border-bottom: 1px solid #eaeaea;
2195 color: #000;
2195 color: #000;
2196 font-size: 11px;
2196 font-size: 11px;
2197 margin: 0;
2197 margin: 0;
2198 padding: 5px 7px 4px;
2198 padding: 5px 7px 4px;
2199 }
2199 }
2200
2200
2201 #quick_login div.form div.fields div.buttons {
2201 #quick_login div.form div.fields div.buttons {
2202 clear: both;
2202 clear: both;
2203 overflow: hidden;
2203 overflow: hidden;
2204 text-align: right;
2204 text-align: right;
2205 margin: 0;
2205 margin: 0;
2206 padding: 5px 14px 0px 5px;
2206 padding: 5px 14px 0px 5px;
2207 }
2207 }
2208
2208
2209 #quick_login div.form div.links {
2209 #quick_login div.form div.links {
2210 clear: both;
2210 clear: both;
2211 overflow: hidden;
2211 overflow: hidden;
2212 margin: 10px 0 0;
2212 margin: 10px 0 0;
2213 padding: 0 0 2px;
2213 padding: 0 0 2px;
2214 }
2214 }
2215
2215
2216 #quick_login ol.links{
2216 #quick_login ol.links{
2217 display: block;
2217 display: block;
2218 font-weight: bold;
2218 font-weight: bold;
2219 list-style: none outside none;
2219 list-style: none outside none;
2220 text-align: right;
2220 text-align: right;
2221 }
2221 }
2222 #quick_login ol.links li{
2222 #quick_login ol.links li{
2223 line-height: 27px;
2223 line-height: 27px;
2224 margin: 0;
2224 margin: 0;
2225 padding: 0;
2225 padding: 0;
2226 color: #fff;
2226 color: #fff;
2227 display: block;
2227 display: block;
2228 float:none !important;
2228 float:none !important;
2229 }
2229 }
2230
2230
2231 #quick_login ol.links li a{
2231 #quick_login ol.links li a{
2232 color: #fff;
2232 color: #fff;
2233 display: block;
2233 display: block;
2234 padding: 2px;
2234 padding: 2px;
2235 }
2235 }
2236 #quick_login ol.links li a:HOVER{
2236 #quick_login ol.links li a:HOVER{
2237 background-color: inherit !important;
2237 background-color: inherit !important;
2238 }
2238 }
2239
2239
2240 #register div.title {
2240 #register div.title {
2241 clear: both;
2241 clear: both;
2242 overflow: hidden;
2242 overflow: hidden;
2243 position: relative;
2243 position: relative;
2244 background-color: #003B76;
2244 background-color: #003B76;
2245 background-repeat: repeat-x;
2245 background-repeat: repeat-x;
2246 background-image: -khtml-gradient(linear, left top, left bottom, from(#003B76), to(#00376E) );
2246 background-image: -khtml-gradient(linear, left top, left bottom, from(#003B76), to(#00376E) );
2247 background-image: -moz-linear-gradient(top, #003b76, #00376e);
2247 background-image: -moz-linear-gradient(top, #003b76, #00376e);
2248 background-image: -ms-linear-gradient(top, #003b76, #00376e);
2248 background-image: -ms-linear-gradient(top, #003b76, #00376e);
2249 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76), color-stop(100%, #00376e) );
2249 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #003b76), color-stop(100%, #00376e) );
2250 background-image: -webkit-linear-gradient(top, #003b76, #00376e);
2250 background-image: -webkit-linear-gradient(top, #003b76, #00376e);
2251 background-image: -o-linear-gradient(top, #003b76, #00376e);
2251 background-image: -o-linear-gradient(top, #003b76, #00376e);
2252 background-image: linear-gradient(top, #003b76, #00376e);
2252 background-image: linear-gradient(top, #003b76, #00376e);
2253 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76',
2253 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#003b76',
2254 endColorstr='#00376e', GradientType=0 );
2254 endColorstr='#00376e', GradientType=0 );
2255 margin: 0 auto;
2255 margin: 0 auto;
2256 padding: 0;
2256 padding: 0;
2257 }
2257 }
2258
2258
2259 #register div.inner {
2259 #register div.inner {
2260 background: #FFF;
2260 background: #FFF;
2261 border-top: none;
2261 border-top: none;
2262 border-bottom: none;
2262 border-bottom: none;
2263 margin: 0 auto;
2263 margin: 0 auto;
2264 padding: 20px;
2264 padding: 20px;
2265 }
2265 }
2266
2266
2267 #register div.form div.fields div.field div.label {
2267 #register div.form div.fields div.field div.label {
2268 width: 135px;
2268 width: 135px;
2269 float: left;
2269 float: left;
2270 text-align: right;
2270 text-align: right;
2271 margin: 2px 10px 0 0;
2271 margin: 2px 10px 0 0;
2272 padding: 5px 0 0 5px;
2272 padding: 5px 0 0 5px;
2273 }
2273 }
2274
2274
2275 #register div.form div.fields div.field div.input input {
2275 #register div.form div.fields div.field div.input input {
2276 width: 300px;
2276 width: 300px;
2277 background: #FFF;
2277 background: #FFF;
2278 border-top: 1px solid #b3b3b3;
2278 border-top: 1px solid #b3b3b3;
2279 border-left: 1px solid #b3b3b3;
2279 border-left: 1px solid #b3b3b3;
2280 border-right: 1px solid #eaeaea;
2280 border-right: 1px solid #eaeaea;
2281 border-bottom: 1px solid #eaeaea;
2281 border-bottom: 1px solid #eaeaea;
2282 color: #000;
2282 color: #000;
2283 font-size: 11px;
2283 font-size: 11px;
2284 margin: 0;
2284 margin: 0;
2285 padding: 7px 7px 6px;
2285 padding: 7px 7px 6px;
2286 }
2286 }
2287
2287
2288 #register div.form div.fields div.buttons {
2288 #register div.form div.fields div.buttons {
2289 clear: both;
2289 clear: both;
2290 overflow: hidden;
2290 overflow: hidden;
2291 border-top: 1px solid #DDD;
2291 border-top: 1px solid #DDD;
2292 text-align: left;
2292 text-align: left;
2293 margin: 0;
2293 margin: 0;
2294 padding: 10px 0 0 150px;
2294 padding: 10px 0 0 150px;
2295 }
2295 }
2296
2296
2297 #register div.form div.activation_msg {
2297 #register div.form div.activation_msg {
2298 padding-top: 4px;
2298 padding-top: 4px;
2299 padding-bottom: 4px;
2299 padding-bottom: 4px;
2300 }
2300 }
2301
2301
2302 #journal .journal_day {
2302 #journal .journal_day {
2303 font-size: 20px;
2303 font-size: 20px;
2304 padding: 10px 0px;
2304 padding: 10px 0px;
2305 border-bottom: 2px solid #DDD;
2305 border-bottom: 2px solid #DDD;
2306 margin-left: 10px;
2306 margin-left: 10px;
2307 margin-right: 10px;
2307 margin-right: 10px;
2308 }
2308 }
2309
2309
2310 #journal .journal_container {
2310 #journal .journal_container {
2311 padding: 5px;
2311 padding: 5px;
2312 clear: both;
2312 clear: both;
2313 margin: 0px 5px 0px 10px;
2313 margin: 0px 5px 0px 10px;
2314 }
2314 }
2315
2315
2316 #journal .journal_action_container {
2316 #journal .journal_action_container {
2317 padding-left: 38px;
2317 padding-left: 38px;
2318 }
2318 }
2319
2319
2320 #journal .journal_user {
2320 #journal .journal_user {
2321 color: #747474;
2321 color: #747474;
2322 font-size: 14px;
2322 font-size: 14px;
2323 font-weight: bold;
2323 font-weight: bold;
2324 height: 30px;
2324 height: 30px;
2325 }
2325 }
2326
2326
2327 #journal .journal_user.deleted {
2327 #journal .journal_user.deleted {
2328 color: #747474;
2328 color: #747474;
2329 font-size: 14px;
2329 font-size: 14px;
2330 font-weight: normal;
2330 font-weight: normal;
2331 height: 30px;
2331 height: 30px;
2332 font-style: italic;
2332 font-style: italic;
2333 }
2333 }
2334
2334
2335
2335
2336 #journal .journal_icon {
2336 #journal .journal_icon {
2337 clear: both;
2337 clear: both;
2338 float: left;
2338 float: left;
2339 padding-right: 4px;
2339 padding-right: 4px;
2340 padding-top: 3px;
2340 padding-top: 3px;
2341 }
2341 }
2342
2342
2343 #journal .journal_action {
2343 #journal .journal_action {
2344 padding-top: 4px;
2344 padding-top: 4px;
2345 min-height: 2px;
2345 min-height: 2px;
2346 float: left
2346 float: left
2347 }
2347 }
2348
2348
2349 #journal .journal_action_params {
2349 #journal .journal_action_params {
2350 clear: left;
2350 clear: left;
2351 padding-left: 22px;
2351 padding-left: 22px;
2352 }
2352 }
2353
2353
2354 #journal .journal_repo {
2354 #journal .journal_repo {
2355 float: left;
2355 float: left;
2356 margin-left: 6px;
2356 margin-left: 6px;
2357 padding-top: 3px;
2357 padding-top: 3px;
2358 }
2358 }
2359
2359
2360 #journal .date {
2360 #journal .date {
2361 clear: both;
2361 clear: both;
2362 color: #777777;
2362 color: #777777;
2363 font-size: 11px;
2363 font-size: 11px;
2364 padding-left: 22px;
2364 padding-left: 22px;
2365 }
2365 }
2366
2366
2367 #journal .journal_repo .journal_repo_name {
2367 #journal .journal_repo .journal_repo_name {
2368 font-weight: bold;
2368 font-weight: bold;
2369 font-size: 1.1em;
2369 font-size: 1.1em;
2370 }
2370 }
2371
2371
2372 #journal .compare_view {
2372 #journal .compare_view {
2373 padding: 5px 0px 5px 0px;
2373 padding: 5px 0px 5px 0px;
2374 width: 95px;
2374 width: 95px;
2375 }
2375 }
2376
2376
2377 .journal_highlight {
2377 .journal_highlight {
2378 font-weight: bold;
2378 font-weight: bold;
2379 padding: 0 2px;
2379 padding: 0 2px;
2380 vertical-align: bottom;
2380 vertical-align: bottom;
2381 }
2381 }
2382
2382
2383 .trending_language_tbl,.trending_language_tbl td {
2383 .trending_language_tbl,.trending_language_tbl td {
2384 border: 0 !important;
2384 border: 0 !important;
2385 margin: 0 !important;
2385 margin: 0 !important;
2386 padding: 0 !important;
2386 padding: 0 !important;
2387 }
2387 }
2388
2388
2389 .trending_language_tbl,.trending_language_tbl tr {
2389 .trending_language_tbl,.trending_language_tbl tr {
2390 border-spacing: 1px;
2390 border-spacing: 1px;
2391 }
2391 }
2392
2392
2393 .trending_language {
2393 .trending_language {
2394 background-color: #003367;
2394 background-color: #003367;
2395 color: #FFF;
2395 color: #FFF;
2396 display: block;
2396 display: block;
2397 min-width: 20px;
2397 min-width: 20px;
2398 text-decoration: none;
2398 text-decoration: none;
2399 height: 12px;
2399 height: 12px;
2400 margin-bottom: 0px;
2400 margin-bottom: 0px;
2401 margin-left: 5px;
2401 margin-left: 5px;
2402 white-space: pre;
2402 white-space: pre;
2403 padding: 3px;
2403 padding: 3px;
2404 }
2404 }
2405
2405
2406 h3.files_location {
2406 h3.files_location {
2407 font-size: 1.8em;
2407 font-size: 1.8em;
2408 font-weight: 700;
2408 font-weight: 700;
2409 border-bottom: none !important;
2409 border-bottom: none !important;
2410 margin: 10px 0 !important;
2410 margin: 10px 0 !important;
2411 }
2411 }
2412
2412
2413 #files_data dl dt {
2413 #files_data dl dt {
2414 float: left;
2414 float: left;
2415 width: 60px;
2415 width: 60px;
2416 margin: 0 !important;
2416 margin: 0 !important;
2417 padding: 5px;
2417 padding: 5px;
2418 }
2418 }
2419
2419
2420 #files_data dl dd {
2420 #files_data dl dd {
2421 margin: 0 !important;
2421 margin: 0 !important;
2422 padding: 5px !important;
2422 padding: 5px !important;
2423 }
2423 }
2424
2424
2425 .file_history{
2425 .file_history{
2426 padding-top:10px;
2426 padding-top:10px;
2427 font-size:16px;
2427 font-size:16px;
2428 }
2428 }
2429 .file_author{
2429 .file_author{
2430 float: left;
2430 float: left;
2431 }
2431 }
2432
2432
2433 .file_author .item{
2433 .file_author .item{
2434 float:left;
2434 float:left;
2435 padding:5px;
2435 padding:5px;
2436 color: #888;
2436 color: #888;
2437 }
2437 }
2438
2438
2439 .tablerow0 {
2439 .tablerow0 {
2440 background-color: #F8F8F8;
2440 background-color: #F8F8F8;
2441 }
2441 }
2442
2442
2443 .tablerow1 {
2443 .tablerow1 {
2444 background-color: #FFFFFF;
2444 background-color: #FFFFFF;
2445 }
2445 }
2446
2446
2447 .changeset_id {
2447 .changeset_id {
2448 font-family: monospace;
2448 font-family: monospace;
2449 color: #666666;
2449 color: #666666;
2450 }
2450 }
2451
2451
2452 .changeset_hash {
2452 .changeset_hash {
2453 color: #000000;
2453 color: #000000;
2454 }
2454 }
2455
2455
2456 #changeset_content {
2456 #changeset_content {
2457 border-left: 1px solid #CCC;
2457 border-left: 1px solid #CCC;
2458 border-right: 1px solid #CCC;
2458 border-right: 1px solid #CCC;
2459 border-bottom: 1px solid #CCC;
2459 border-bottom: 1px solid #CCC;
2460 padding: 5px;
2460 padding: 5px;
2461 }
2461 }
2462
2462
2463 #changeset_compare_view_content {
2463 #changeset_compare_view_content {
2464 border: 1px solid #CCC;
2464 border: 1px solid #CCC;
2465 padding: 5px;
2465 padding: 5px;
2466 }
2466 }
2467
2467
2468 #changeset_content .container {
2468 #changeset_content .container {
2469 min-height: 100px;
2469 min-height: 100px;
2470 font-size: 1.2em;
2470 font-size: 1.2em;
2471 overflow: hidden;
2471 overflow: hidden;
2472 }
2472 }
2473
2473
2474 #changeset_compare_view_content .compare_view_commits {
2474 #changeset_compare_view_content .compare_view_commits {
2475 width: auto !important;
2475 width: auto !important;
2476 }
2476 }
2477
2477
2478 #changeset_compare_view_content .compare_view_commits td {
2478 #changeset_compare_view_content .compare_view_commits td {
2479 padding: 0px 0px 0px 12px !important;
2479 padding: 0px 0px 0px 12px !important;
2480 }
2480 }
2481
2481
2482 #changeset_content .container .right {
2482 #changeset_content .container .right {
2483 float: right;
2483 float: right;
2484 width: 20%;
2484 width: 20%;
2485 text-align: right;
2485 text-align: right;
2486 }
2486 }
2487
2487
2488 #changeset_content .container .left .message {
2488 #changeset_content .container .left .message {
2489 white-space: pre-wrap;
2489 white-space: pre-wrap;
2490 }
2490 }
2491 #changeset_content .container .left .message a:hover {
2491 #changeset_content .container .left .message a:hover {
2492 text-decoration: none;
2492 text-decoration: none;
2493 }
2493 }
2494 .cs_files .cur_cs {
2494 .cs_files .cur_cs {
2495 margin: 10px 2px;
2495 margin: 10px 2px;
2496 font-weight: bold;
2496 font-weight: bold;
2497 }
2497 }
2498
2498
2499 .cs_files .node {
2499 .cs_files .node {
2500 float: left;
2500 float: left;
2501 }
2501 }
2502
2502
2503 .cs_files .changes {
2503 .cs_files .changes {
2504 float: right;
2504 float: right;
2505 color:#003367;
2505 color:#003367;
2506
2506
2507 }
2507 }
2508
2508
2509 .cs_files .changes .added {
2509 .cs_files .changes .added {
2510 background-color: #BBFFBB;
2510 background-color: #BBFFBB;
2511 float: left;
2511 float: left;
2512 text-align: center;
2512 text-align: center;
2513 font-size: 9px;
2513 font-size: 9px;
2514 padding: 2px 0px 2px 0px;
2514 padding: 2px 0px 2px 0px;
2515 }
2515 }
2516
2516
2517 .cs_files .changes .deleted {
2517 .cs_files .changes .deleted {
2518 background-color: #FF8888;
2518 background-color: #FF8888;
2519 float: left;
2519 float: left;
2520 text-align: center;
2520 text-align: center;
2521 font-size: 9px;
2521 font-size: 9px;
2522 padding: 2px 0px 2px 0px;
2522 padding: 2px 0px 2px 0px;
2523 }
2523 }
2524 /*new binary*/
2524 /*new binary*/
2525 .cs_files .changes .bin1 {
2525 .cs_files .changes .bin1 {
2526 background-color: #BBFFBB;
2526 background-color: #BBFFBB;
2527 float: left;
2527 float: left;
2528 text-align: center;
2528 text-align: center;
2529 font-size: 9px;
2529 font-size: 9px;
2530 padding: 2px 0px 2px 0px;
2530 padding: 2px 0px 2px 0px;
2531 }
2531 }
2532
2532
2533 /*deleted binary*/
2533 /*deleted binary*/
2534 .cs_files .changes .bin2 {
2534 .cs_files .changes .bin2 {
2535 background-color: #FF8888;
2535 background-color: #FF8888;
2536 float: left;
2536 float: left;
2537 text-align: center;
2537 text-align: center;
2538 font-size: 9px;
2538 font-size: 9px;
2539 padding: 2px 0px 2px 0px;
2539 padding: 2px 0px 2px 0px;
2540 }
2540 }
2541
2541
2542 /*mod binary*/
2542 /*mod binary*/
2543 .cs_files .changes .bin3 {
2543 .cs_files .changes .bin3 {
2544 background-color: #DDDDDD;
2544 background-color: #DDDDDD;
2545 float: left;
2545 float: left;
2546 text-align: center;
2546 text-align: center;
2547 font-size: 9px;
2547 font-size: 9px;
2548 padding: 2px 0px 2px 0px;
2548 padding: 2px 0px 2px 0px;
2549 }
2549 }
2550
2550
2551 /*rename file*/
2551 /*rename file*/
2552 .cs_files .changes .bin4 {
2552 .cs_files .changes .bin4 {
2553 background-color: #6D99FF;
2553 background-color: #6D99FF;
2554 float: left;
2554 float: left;
2555 text-align: center;
2555 text-align: center;
2556 font-size: 9px;
2556 font-size: 9px;
2557 padding: 2px 0px 2px 0px;
2557 padding: 2px 0px 2px 0px;
2558 }
2558 }
2559
2559
2560
2560
2561 .cs_files .cs_added,.cs_files .cs_A {
2561 .cs_files .cs_added,.cs_files .cs_A {
2562 background: url("../images/icons/page_white_add.png") no-repeat scroll
2562 background: url("../images/icons/page_white_add.png") no-repeat scroll
2563 3px;
2563 3px;
2564 height: 16px;
2564 height: 16px;
2565 padding-left: 20px;
2565 padding-left: 20px;
2566 margin-top: 7px;
2566 margin-top: 7px;
2567 text-align: left;
2567 text-align: left;
2568 }
2568 }
2569
2569
2570 .cs_files .cs_changed,.cs_files .cs_M {
2570 .cs_files .cs_changed,.cs_files .cs_M {
2571 background: url("../images/icons/page_white_edit.png") no-repeat scroll
2571 background: url("../images/icons/page_white_edit.png") no-repeat scroll
2572 3px;
2572 3px;
2573 height: 16px;
2573 height: 16px;
2574 padding-left: 20px;
2574 padding-left: 20px;
2575 margin-top: 7px;
2575 margin-top: 7px;
2576 text-align: left;
2576 text-align: left;
2577 }
2577 }
2578
2578
2579 .cs_files .cs_removed,.cs_files .cs_D {
2579 .cs_files .cs_removed,.cs_files .cs_D {
2580 background: url("../images/icons/page_white_delete.png") no-repeat
2580 background: url("../images/icons/page_white_delete.png") no-repeat
2581 scroll 3px;
2581 scroll 3px;
2582 height: 16px;
2582 height: 16px;
2583 padding-left: 20px;
2583 padding-left: 20px;
2584 margin-top: 7px;
2584 margin-top: 7px;
2585 text-align: left;
2585 text-align: left;
2586 }
2586 }
2587
2587
2588 #graph {
2588 #graph {
2589 overflow: hidden;
2589 overflow: hidden;
2590 }
2590 }
2591
2591
2592 #graph_nodes {
2592 #graph_nodes {
2593 float: left;
2593 float: left;
2594 margin-right: 0px;
2594 margin-right: 0px;
2595 margin-top: 0px;
2595 margin-top: 0px;
2596 }
2596 }
2597
2597
2598 #graph_content {
2598 #graph_content {
2599 width: 80%;
2599 width: 80%;
2600 float: left;
2600 float: left;
2601 }
2601 }
2602
2602
2603 #graph_content .container_header {
2603 #graph_content .container_header {
2604 border-bottom: 1px solid #DDD;
2604 border-bottom: 1px solid #DDD;
2605 padding: 10px;
2605 padding: 10px;
2606 height: 25px;
2606 height: 25px;
2607 }
2607 }
2608
2608
2609 #graph_content #rev_range_container {
2609 #graph_content #rev_range_container {
2610 float: left;
2610 float: left;
2611 margin: 0px 0px 0px 3px;
2611 margin: 0px 0px 0px 3px;
2612 }
2612 }
2613
2613
2614 #graph_content #rev_range_clear {
2614 #graph_content #rev_range_clear {
2615 float: left;
2615 float: left;
2616 margin: 0px 0px 0px 3px;
2616 margin: 0px 0px 0px 3px;
2617 }
2617 }
2618
2618
2619 #graph_content .container {
2619 #graph_content .container {
2620 border-bottom: 1px solid #DDD;
2620 border-bottom: 1px solid #DDD;
2621 height: 56px;
2621 height: 56px;
2622 overflow: hidden;
2622 overflow: hidden;
2623 }
2623 }
2624
2624
2625 #graph_content .container .right {
2625 #graph_content .container .right {
2626 float: right;
2626 float: right;
2627 width: 23%;
2627 width: 23%;
2628 text-align: right;
2628 text-align: right;
2629 }
2629 }
2630
2630
2631 #graph_content .container .left {
2631 #graph_content .container .left {
2632 float: left;
2632 float: left;
2633 width: 25%;
2633 width: 25%;
2634 padding-left: 5px;
2634 padding-left: 5px;
2635 }
2635 }
2636
2636
2637 #graph_content .container .mid {
2637 #graph_content .container .mid {
2638 float: left;
2638 float: left;
2639 width: 49%;
2639 width: 49%;
2640 }
2640 }
2641
2641
2642
2642
2643 #graph_content .container .left .date {
2643 #graph_content .container .left .date {
2644 color: #666;
2644 color: #666;
2645 padding-left: 22px;
2645 padding-left: 22px;
2646 font-size: 10px;
2646 font-size: 10px;
2647 }
2647 }
2648
2648
2649 #graph_content .container .left .author {
2649 #graph_content .container .left .author {
2650 height: 22px;
2650 height: 22px;
2651 }
2651 }
2652
2652
2653 #graph_content .container .left .author .user {
2653 #graph_content .container .left .author .user {
2654 color: #444444;
2654 color: #444444;
2655 float: left;
2655 float: left;
2656 margin-left: -4px;
2656 margin-left: -4px;
2657 margin-top: 4px;
2657 margin-top: 4px;
2658 }
2658 }
2659
2659
2660 #graph_content .container .mid .message {
2660 #graph_content .container .mid .message {
2661 white-space: pre-wrap;
2661 white-space: pre-wrap;
2662 }
2662 }
2663
2663
2664 #graph_content .container .mid .message a:hover{
2664 #graph_content .container .mid .message a:hover{
2665 text-decoration: none;
2665 text-decoration: none;
2666 }
2666 }
2667
2667
2668 .revision-link
2668 .revision-link
2669 {
2669 {
2670 color:#3F6F9F;
2670 color:#3F6F9F;
2671 font-weight: bold !important;
2671 font-weight: bold !important;
2672 }
2672 }
2673
2673
2674 .issue-tracker-link{
2674 .issue-tracker-link{
2675 color:#3F6F9F;
2675 color:#3F6F9F;
2676 font-weight: bold !important;
2676 font-weight: bold !important;
2677 }
2677 }
2678
2678
2679 .changeset-status-container{
2679 .changeset-status-container{
2680 padding-right: 5px;
2680 padding-right: 5px;
2681 margin-top:1px;
2681 margin-top:1px;
2682 float:right;
2682 float:right;
2683 height:14px;
2683 height:14px;
2684 }
2684 }
2685 .code-header .changeset-status-container{
2685 .code-header .changeset-status-container{
2686 float:left;
2686 float:left;
2687 padding:2px 0px 0px 2px;
2687 padding:2px 0px 0px 2px;
2688 }
2688 }
2689 .changeset-status-container .changeset-status-lbl{
2689 .changeset-status-container .changeset-status-lbl{
2690 color: rgb(136, 136, 136);
2690 color: rgb(136, 136, 136);
2691 float: left;
2691 float: left;
2692 padding: 3px 4px 0px 0px
2692 padding: 3px 4px 0px 0px
2693 }
2693 }
2694 .code-header .changeset-status-container .changeset-status-lbl{
2694 .code-header .changeset-status-container .changeset-status-lbl{
2695 float: left;
2695 float: left;
2696 padding: 0px 4px 0px 0px;
2696 padding: 0px 4px 0px 0px;
2697 }
2697 }
2698 .changeset-status-container .changeset-status-ico{
2698 .changeset-status-container .changeset-status-ico{
2699 float: left;
2699 float: left;
2700 }
2700 }
2701 .code-header .changeset-status-container .changeset-status-ico, .container .changeset-status-ico{
2701 .code-header .changeset-status-container .changeset-status-ico, .container .changeset-status-ico{
2702 float: left;
2702 float: left;
2703 }
2703 }
2704 .right .comments-container{
2704 .right .comments-container{
2705 padding-right: 5px;
2705 padding-right: 5px;
2706 margin-top:1px;
2706 margin-top:1px;
2707 float:right;
2707 float:right;
2708 height:14px;
2708 height:14px;
2709 }
2709 }
2710
2710
2711 .right .comments-cnt{
2711 .right .comments-cnt{
2712 float: left;
2712 float: left;
2713 color: rgb(136, 136, 136);
2713 color: rgb(136, 136, 136);
2714 padding-right: 2px;
2714 padding-right: 2px;
2715 }
2715 }
2716
2716
2717 .right .changes{
2717 .right .changes{
2718 clear: both;
2718 clear: both;
2719 }
2719 }
2720
2720
2721 .right .changes .changed_total {
2721 .right .changes .changed_total {
2722 display: block;
2722 display: block;
2723 float: right;
2723 float: right;
2724 text-align: center;
2724 text-align: center;
2725 min-width: 45px;
2725 min-width: 45px;
2726 cursor: pointer;
2726 cursor: pointer;
2727 color: #444444;
2727 color: #444444;
2728 background: #FEA;
2728 background: #FEA;
2729 -webkit-border-radius: 0px 0px 0px 6px;
2729 -webkit-border-radius: 0px 0px 0px 6px;
2730 -moz-border-radius: 0px 0px 0px 6px;
2730 -moz-border-radius: 0px 0px 0px 6px;
2731 border-radius: 0px 0px 0px 6px;
2731 border-radius: 0px 0px 0px 6px;
2732 padding: 1px;
2732 padding: 1px;
2733 }
2733 }
2734
2734
2735 .right .changes .added,.changed,.removed {
2735 .right .changes .added,.changed,.removed {
2736 display: block;
2736 display: block;
2737 padding: 1px;
2737 padding: 1px;
2738 color: #444444;
2738 color: #444444;
2739 float: right;
2739 float: right;
2740 text-align: center;
2740 text-align: center;
2741 min-width: 15px;
2741 min-width: 15px;
2742 }
2742 }
2743
2743
2744 .right .changes .added {
2744 .right .changes .added {
2745 background: #CFC;
2745 background: #CFC;
2746 }
2746 }
2747
2747
2748 .right .changes .changed {
2748 .right .changes .changed {
2749 background: #FEA;
2749 background: #FEA;
2750 }
2750 }
2751
2751
2752 .right .changes .removed {
2752 .right .changes .removed {
2753 background: #FAA;
2753 background: #FAA;
2754 }
2754 }
2755
2755
2756 .right .merge {
2756 .right .merge {
2757 padding: 1px 3px 1px 3px;
2757 padding: 1px 3px 1px 3px;
2758 background-color: #fca062;
2758 background-color: #fca062;
2759 font-size: 10px;
2759 font-size: 10px;
2760 font-weight: bold;
2760 font-weight: bold;
2761 color: #ffffff;
2761 color: #ffffff;
2762 text-transform: uppercase;
2762 text-transform: uppercase;
2763 white-space: nowrap;
2763 white-space: nowrap;
2764 -webkit-border-radius: 3px;
2764 -webkit-border-radius: 3px;
2765 -moz-border-radius: 3px;
2765 -moz-border-radius: 3px;
2766 border-radius: 3px;
2766 border-radius: 3px;
2767 margin-right: 2px;
2767 margin-right: 2px;
2768 }
2768 }
2769
2769
2770 .right .parent {
2770 .right .parent {
2771 color: #666666;
2771 color: #666666;
2772 clear:both;
2772 clear:both;
2773 }
2773 }
2774 .right .logtags{
2774 .right .logtags{
2775 padding: 2px 2px 2px 2px;
2775 padding: 2px 2px 2px 2px;
2776 }
2776 }
2777 .right .logtags .branchtag,.right .logtags .tagtag,.right .logtags .booktag{
2777 .right .logtags .branchtag,.right .logtags .tagtag,.right .logtags .booktag{
2778 margin: 0px 2px;
2778 margin: 0px 2px;
2779 }
2779 }
2780
2780
2781 .right .logtags .branchtag,.logtags .branchtag {
2781 .right .logtags .branchtag,.logtags .branchtag {
2782 padding: 1px 3px 1px 3px;
2782 padding: 1px 3px 1px 3px;
2783 background-color: #bfbfbf;
2783 background-color: #bfbfbf;
2784 font-size: 10px;
2784 font-size: 10px;
2785 font-weight: bold;
2785 font-weight: bold;
2786 color: #ffffff;
2786 color: #ffffff;
2787 text-transform: uppercase;
2787 text-transform: uppercase;
2788 white-space: nowrap;
2788 white-space: nowrap;
2789 -webkit-border-radius: 3px;
2789 -webkit-border-radius: 3px;
2790 -moz-border-radius: 3px;
2790 -moz-border-radius: 3px;
2791 border-radius: 3px;
2791 border-radius: 3px;
2792 }
2792 }
2793 .right .logtags .branchtag a:hover,.logtags .branchtag a{
2793 .right .logtags .branchtag a:hover,.logtags .branchtag a{
2794 color: #ffffff;
2794 color: #ffffff;
2795 }
2795 }
2796 .right .logtags .branchtag a:hover,.logtags .branchtag a:hover{
2796 .right .logtags .branchtag a:hover,.logtags .branchtag a:hover{
2797 text-decoration: none;
2797 text-decoration: none;
2798 color: #ffffff;
2798 color: #ffffff;
2799 }
2799 }
2800 .right .logtags .tagtag,.logtags .tagtag {
2800 .right .logtags .tagtag,.logtags .tagtag {
2801 padding: 1px 3px 1px 3px;
2801 padding: 1px 3px 1px 3px;
2802 background-color: #62cffc;
2802 background-color: #62cffc;
2803 font-size: 10px;
2803 font-size: 10px;
2804 font-weight: bold;
2804 font-weight: bold;
2805 color: #ffffff;
2805 color: #ffffff;
2806 text-transform: uppercase;
2806 text-transform: uppercase;
2807 white-space: nowrap;
2807 white-space: nowrap;
2808 -webkit-border-radius: 3px;
2808 -webkit-border-radius: 3px;
2809 -moz-border-radius: 3px;
2809 -moz-border-radius: 3px;
2810 border-radius: 3px;
2810 border-radius: 3px;
2811 }
2811 }
2812 .right .logtags .tagtag a:hover,.logtags .tagtag a{
2812 .right .logtags .tagtag a:hover,.logtags .tagtag a{
2813 color: #ffffff;
2813 color: #ffffff;
2814 }
2814 }
2815 .right .logtags .tagtag a:hover,.logtags .tagtag a:hover{
2815 .right .logtags .tagtag a:hover,.logtags .tagtag a:hover{
2816 text-decoration: none;
2816 text-decoration: none;
2817 color: #ffffff;
2817 color: #ffffff;
2818 }
2818 }
2819 .right .logbooks .bookbook,.logbooks .bookbook,.right .logtags .bookbook,.logtags .bookbook {
2819 .right .logbooks .bookbook,.logbooks .bookbook,.right .logtags .bookbook,.logtags .bookbook {
2820 padding: 1px 3px 1px 3px;
2820 padding: 1px 3px 1px 3px;
2821 background-color: #46A546;
2821 background-color: #46A546;
2822 font-size: 10px;
2822 font-size: 10px;
2823 font-weight: bold;
2823 font-weight: bold;
2824 color: #ffffff;
2824 color: #ffffff;
2825 text-transform: uppercase;
2825 text-transform: uppercase;
2826 white-space: nowrap;
2826 white-space: nowrap;
2827 -webkit-border-radius: 3px;
2827 -webkit-border-radius: 3px;
2828 -moz-border-radius: 3px;
2828 -moz-border-radius: 3px;
2829 border-radius: 3px;
2829 border-radius: 3px;
2830 }
2830 }
2831 .right .logbooks .bookbook,.logbooks .bookbook a,.right .logtags .bookbook,.logtags .bookbook a{
2831 .right .logbooks .bookbook,.logbooks .bookbook a,.right .logtags .bookbook,.logtags .bookbook a{
2832 color: #ffffff;
2832 color: #ffffff;
2833 }
2833 }
2834 .right .logbooks .bookbook,.logbooks .bookbook a:hover,.right .logtags .bookbook,.logtags .bookbook a:hover{
2834 .right .logbooks .bookbook,.logbooks .bookbook a:hover,.right .logtags .bookbook,.logtags .bookbook a:hover{
2835 text-decoration: none;
2835 text-decoration: none;
2836 color: #ffffff;
2836 color: #ffffff;
2837 }
2837 }
2838 div.browserblock {
2838 div.browserblock {
2839 overflow: hidden;
2839 overflow: hidden;
2840 border: 1px solid #ccc;
2840 border: 1px solid #ccc;
2841 background: #f8f8f8;
2841 background: #f8f8f8;
2842 font-size: 100%;
2842 font-size: 100%;
2843 line-height: 125%;
2843 line-height: 125%;
2844 padding: 0;
2844 padding: 0;
2845 -webkit-border-radius: 6px 6px 0px 0px;
2845 -webkit-border-radius: 6px 6px 0px 0px;
2846 -moz-border-radius: 6px 6px 0px 0px;
2846 -moz-border-radius: 6px 6px 0px 0px;
2847 border-radius: 6px 6px 0px 0px;
2847 border-radius: 6px 6px 0px 0px;
2848 }
2848 }
2849
2849
2850 div.browserblock .browser-header {
2850 div.browserblock .browser-header {
2851 background: #FFF;
2851 background: #FFF;
2852 padding: 10px 0px 15px 0px;
2852 padding: 10px 0px 15px 0px;
2853 width: 100%;
2853 width: 100%;
2854 }
2854 }
2855
2855
2856 div.browserblock .browser-nav {
2856 div.browserblock .browser-nav {
2857 float: left
2857 float: left
2858 }
2858 }
2859
2859
2860 div.browserblock .browser-branch {
2860 div.browserblock .browser-branch {
2861 float: left;
2861 float: left;
2862 }
2862 }
2863
2863
2864 div.browserblock .browser-branch label {
2864 div.browserblock .browser-branch label {
2865 color: #4A4A4A;
2865 color: #4A4A4A;
2866 vertical-align: text-top;
2866 vertical-align: text-top;
2867 }
2867 }
2868
2868
2869 div.browserblock .browser-header span {
2869 div.browserblock .browser-header span {
2870 margin-left: 5px;
2870 margin-left: 5px;
2871 font-weight: 700;
2871 font-weight: 700;
2872 }
2872 }
2873
2873
2874 div.browserblock .browser-search {
2874 div.browserblock .browser-search {
2875 clear: both;
2875 clear: both;
2876 padding: 8px 8px 0px 5px;
2876 padding: 8px 8px 0px 5px;
2877 height: 20px;
2877 height: 20px;
2878 }
2878 }
2879
2879
2880 div.browserblock #node_filter_box {
2880 div.browserblock #node_filter_box {
2881
2881
2882 }
2882 }
2883
2883
2884 div.browserblock .search_activate {
2884 div.browserblock .search_activate {
2885 float: left
2885 float: left
2886 }
2886 }
2887
2887
2888 div.browserblock .add_node {
2888 div.browserblock .add_node {
2889 float: left;
2889 float: left;
2890 padding-left: 5px;
2890 padding-left: 5px;
2891 }
2891 }
2892
2892
2893 div.browserblock .search_activate a:hover,div.browserblock .add_node a:hover
2893 div.browserblock .search_activate a:hover,div.browserblock .add_node a:hover
2894 {
2894 {
2895 text-decoration: none !important;
2895 text-decoration: none !important;
2896 }
2896 }
2897
2897
2898 div.browserblock .browser-body {
2898 div.browserblock .browser-body {
2899 background: #EEE;
2899 background: #EEE;
2900 border-top: 1px solid #CCC;
2900 border-top: 1px solid #CCC;
2901 }
2901 }
2902
2902
2903 table.code-browser {
2903 table.code-browser {
2904 border-collapse: collapse;
2904 border-collapse: collapse;
2905 width: 100%;
2905 width: 100%;
2906 }
2906 }
2907
2907
2908 table.code-browser tr {
2908 table.code-browser tr {
2909 margin: 3px;
2909 margin: 3px;
2910 }
2910 }
2911
2911
2912 table.code-browser thead th {
2912 table.code-browser thead th {
2913 background-color: #EEE;
2913 background-color: #EEE;
2914 height: 20px;
2914 height: 20px;
2915 font-size: 1.1em;
2915 font-size: 1.1em;
2916 font-weight: 700;
2916 font-weight: 700;
2917 text-align: left;
2917 text-align: left;
2918 padding-left: 10px;
2918 padding-left: 10px;
2919 }
2919 }
2920
2920
2921 table.code-browser tbody td {
2921 table.code-browser tbody td {
2922 padding-left: 10px;
2922 padding-left: 10px;
2923 height: 20px;
2923 height: 20px;
2924 }
2924 }
2925
2925
2926 table.code-browser .browser-file {
2926 table.code-browser .browser-file {
2927 background: url("../images/icons/document_16.png") no-repeat scroll 3px;
2927 background: url("../images/icons/document_16.png") no-repeat scroll 3px;
2928 height: 16px;
2928 height: 16px;
2929 padding-left: 20px;
2929 padding-left: 20px;
2930 text-align: left;
2930 text-align: left;
2931 }
2931 }
2932 .diffblock .changeset_header {
2932 .diffblock .changeset_header {
2933 height: 16px;
2933 height: 16px;
2934 }
2934 }
2935 .diffblock .changeset_file {
2935 .diffblock .changeset_file {
2936 background: url("../images/icons/file.png") no-repeat scroll 3px;
2936 background: url("../images/icons/file.png") no-repeat scroll 3px;
2937 text-align: left;
2937 text-align: left;
2938 float: left;
2938 float: left;
2939 padding: 2px 0px 2px 22px;
2939 padding: 2px 0px 2px 22px;
2940 }
2940 }
2941 .diffblock .diff-menu-wrapper{
2941 .diffblock .diff-menu-wrapper{
2942 float: left;
2942 float: left;
2943 }
2943 }
2944
2944
2945 .diffblock .diff-menu{
2945 .diffblock .diff-menu{
2946 position: absolute;
2946 position: absolute;
2947 background: none repeat scroll 0 0 #FFFFFF;
2947 background: none repeat scroll 0 0 #FFFFFF;
2948 border-color: #003367 #666666 #666666;
2948 border-color: #003367 #666666 #666666;
2949 border-right: 1px solid #666666;
2949 border-right: 1px solid #666666;
2950 border-style: solid solid solid;
2950 border-style: solid solid solid;
2951 border-width: 1px;
2951 border-width: 1px;
2952 box-shadow: 2px 8px 4px rgba(0, 0, 0, 0.2);
2952 box-shadow: 2px 8px 4px rgba(0, 0, 0, 0.2);
2953 margin-top:5px;
2953 margin-top:5px;
2954 margin-left:1px;
2954 margin-left:1px;
2955
2955
2956 }
2956 }
2957 .diffblock .diff-actions {
2957 .diffblock .diff-actions {
2958 padding: 2px 0px 0px 2px;
2958 padding: 2px 0px 0px 2px;
2959 float: left;
2959 float: left;
2960 }
2960 }
2961 .diffblock .diff-menu ul li {
2961 .diffblock .diff-menu ul li {
2962 padding: 0px 0px 0px 0px !important;
2962 padding: 0px 0px 0px 0px !important;
2963 }
2963 }
2964 .diffblock .diff-menu ul li a{
2964 .diffblock .diff-menu ul li a{
2965 display: block;
2965 display: block;
2966 padding: 3px 8px 3px 8px !important;
2966 padding: 3px 8px 3px 8px !important;
2967 }
2967 }
2968 .diffblock .diff-menu ul li a:hover{
2968 .diffblock .diff-menu ul li a:hover{
2969 text-decoration: none;
2969 text-decoration: none;
2970 background-color: #EEEEEE;
2970 background-color: #EEEEEE;
2971 }
2971 }
2972 table.code-browser .browser-dir {
2972 table.code-browser .browser-dir {
2973 background: url("../images/icons/folder_16.png") no-repeat scroll 3px;
2973 background: url("../images/icons/folder_16.png") no-repeat scroll 3px;
2974 height: 16px;
2974 height: 16px;
2975 padding-left: 20px;
2975 padding-left: 20px;
2976 text-align: left;
2976 text-align: left;
2977 }
2977 }
2978
2978
2979 table.code-browser .submodule-dir {
2979 table.code-browser .submodule-dir {
2980 background: url("../images/icons/disconnect.png") no-repeat scroll 3px;
2980 background: url("../images/icons/disconnect.png") no-repeat scroll 3px;
2981 height: 16px;
2981 height: 16px;
2982 padding-left: 20px;
2982 padding-left: 20px;
2983 text-align: left;
2983 text-align: left;
2984 }
2984 }
2985
2985
2986
2986
2987 .box .search {
2987 .box .search {
2988 clear: both;
2988 clear: both;
2989 overflow: hidden;
2989 overflow: hidden;
2990 margin: 0;
2990 margin: 0;
2991 padding: 0 20px 10px;
2991 padding: 0 20px 10px;
2992 }
2992 }
2993
2993
2994 .box .search div.search_path {
2994 .box .search div.search_path {
2995 background: none repeat scroll 0 0 #EEE;
2995 background: none repeat scroll 0 0 #EEE;
2996 border: 1px solid #CCC;
2996 border: 1px solid #CCC;
2997 color: blue;
2997 color: blue;
2998 margin-bottom: 10px;
2998 margin-bottom: 10px;
2999 padding: 10px 0;
2999 padding: 10px 0;
3000 }
3000 }
3001
3001
3002 .box .search div.search_path div.link {
3002 .box .search div.search_path div.link {
3003 font-weight: 700;
3003 font-weight: 700;
3004 margin-left: 25px;
3004 margin-left: 25px;
3005 }
3005 }
3006
3006
3007 .box .search div.search_path div.link a {
3007 .box .search div.search_path div.link a {
3008 color: #003367;
3008 color: #003367;
3009 cursor: pointer;
3009 cursor: pointer;
3010 text-decoration: none;
3010 text-decoration: none;
3011 }
3011 }
3012
3012
3013 #path_unlock {
3013 #path_unlock {
3014 color: red;
3014 color: red;
3015 font-size: 1.2em;
3015 font-size: 1.2em;
3016 padding-left: 4px;
3016 padding-left: 4px;
3017 }
3017 }
3018
3018
3019 .info_box span {
3019 .info_box span {
3020 margin-left: 3px;
3020 margin-left: 3px;
3021 margin-right: 3px;
3021 margin-right: 3px;
3022 }
3022 }
3023
3023
3024 .info_box .rev {
3024 .info_box .rev {
3025 color: #003367;
3025 color: #003367;
3026 font-size: 1.6em;
3026 font-size: 1.6em;
3027 font-weight: bold;
3027 font-weight: bold;
3028 vertical-align: sub;
3028 vertical-align: sub;
3029 }
3029 }
3030
3030
3031 .info_box input#at_rev,.info_box input#size {
3031 .info_box input#at_rev,.info_box input#size {
3032 background: #FFF;
3032 background: #FFF;
3033 border-top: 1px solid #b3b3b3;
3033 border-top: 1px solid #b3b3b3;
3034 border-left: 1px solid #b3b3b3;
3034 border-left: 1px solid #b3b3b3;
3035 border-right: 1px solid #eaeaea;
3035 border-right: 1px solid #eaeaea;
3036 border-bottom: 1px solid #eaeaea;
3036 border-bottom: 1px solid #eaeaea;
3037 color: #000;
3037 color: #000;
3038 font-size: 12px;
3038 font-size: 12px;
3039 margin: 0;
3039 margin: 0;
3040 padding: 1px 5px 1px;
3040 padding: 1px 5px 1px;
3041 }
3041 }
3042
3042
3043 .info_box input#view {
3043 .info_box input#view {
3044 text-align: center;
3044 text-align: center;
3045 padding: 4px 3px 2px 2px;
3045 padding: 4px 3px 2px 2px;
3046 }
3046 }
3047
3047
3048 .yui-overlay,.yui-panel-container {
3048 .yui-overlay,.yui-panel-container {
3049 visibility: hidden;
3049 visibility: hidden;
3050 position: absolute;
3050 position: absolute;
3051 z-index: 2;
3051 z-index: 2;
3052 }
3052 }
3053
3053
3054 #tip-box {
3054 #tip-box {
3055 position: absolute;
3055 position: absolute;
3056
3056
3057 background-color: #FFF;
3057 background-color: #FFF;
3058 border: 2px solid #003367;
3058 border: 2px solid #003367;
3059 font: 100% sans-serif;
3059 font: 100% sans-serif;
3060 width: auto;
3060 width: auto;
3061 opacity: 1px;
3061 opacity: 1px;
3062 padding: 8px;
3062 padding: 8px;
3063
3063
3064 white-space: pre-wrap;
3064 white-space: pre-wrap;
3065 -webkit-border-radius: 8px 8px 8px 8px;
3065 -webkit-border-radius: 8px 8px 8px 8px;
3066 -khtml-border-radius: 8px 8px 8px 8px;
3066 -khtml-border-radius: 8px 8px 8px 8px;
3067 -moz-border-radius: 8px 8px 8px 8px;
3067 -moz-border-radius: 8px 8px 8px 8px;
3068 border-radius: 8px 8px 8px 8px;
3068 border-radius: 8px 8px 8px 8px;
3069 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
3069 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
3070 -moz-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
3070 -moz-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
3071 -webkit-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
3071 -webkit-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
3072 }
3072 }
3073
3073
3074 .hl-tip-box {
3074 .hl-tip-box {
3075 visibility: hidden;
3075 visibility: hidden;
3076 position: absolute;
3076 position: absolute;
3077 color: #666;
3077 color: #666;
3078 background-color: #FFF;
3078 background-color: #FFF;
3079 border: 2px solid #003367;
3079 border: 2px solid #003367;
3080 font: 100% sans-serif;
3080 font: 100% sans-serif;
3081 width: auto;
3081 width: auto;
3082 opacity: 1px;
3082 opacity: 1px;
3083 padding: 8px;
3083 padding: 8px;
3084 white-space: pre-wrap;
3084 white-space: pre-wrap;
3085 -webkit-border-radius: 8px 8px 8px 8px;
3085 -webkit-border-radius: 8px 8px 8px 8px;
3086 -khtml-border-radius: 8px 8px 8px 8px;
3086 -khtml-border-radius: 8px 8px 8px 8px;
3087 -moz-border-radius: 8px 8px 8px 8px;
3087 -moz-border-radius: 8px 8px 8px 8px;
3088 border-radius: 8px 8px 8px 8px;
3088 border-radius: 8px 8px 8px 8px;
3089 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
3089 box-shadow: 0 2px 2px rgba(0, 0, 0, 0.6);
3090 }
3090 }
3091
3091
3092
3092
3093 .mentions-container{
3093 .mentions-container{
3094 width: 90% !important;
3094 width: 90% !important;
3095 }
3095 }
3096 .mentions-container .yui-ac-content{
3096 .mentions-container .yui-ac-content{
3097 width: 100% !important;
3097 width: 100% !important;
3098 }
3098 }
3099
3099
3100 .ac {
3100 .ac {
3101 vertical-align: top;
3101 vertical-align: top;
3102 }
3102 }
3103
3103
3104 .ac .yui-ac {
3104 .ac .yui-ac {
3105 position: inherit;
3105 position: inherit;
3106 font-size: 100%;
3106 font-size: 100%;
3107 }
3107 }
3108
3108
3109 .ac .perm_ac {
3109 .ac .perm_ac {
3110 width: 20em;
3110 width: 20em;
3111 }
3111 }
3112
3112
3113 .ac .yui-ac-input {
3113 .ac .yui-ac-input {
3114 width: 100%;
3114 width: 100%;
3115 }
3115 }
3116
3116
3117 .ac .yui-ac-container {
3117 .ac .yui-ac-container {
3118 position: absolute;
3118 position: absolute;
3119 top: 1.6em;
3119 top: 1.6em;
3120 width: auto;
3120 width: auto;
3121 }
3121 }
3122
3122
3123 .ac .yui-ac-content {
3123 .ac .yui-ac-content {
3124 position: absolute;
3124 position: absolute;
3125 border: 1px solid gray;
3125 border: 1px solid gray;
3126 background: #fff;
3126 background: #fff;
3127 z-index: 9050;
3127 z-index: 9050;
3128
3128
3129 }
3129 }
3130
3130
3131 .ac .yui-ac-shadow {
3131 .ac .yui-ac-shadow {
3132 position: absolute;
3132 position: absolute;
3133 width: 100%;
3133 width: 100%;
3134 background: #000;
3134 background: #000;
3135 -moz-opacity: 0.1px;
3135 -moz-opacity: 0.1px;
3136 opacity: .10;
3136 opacity: .10;
3137 filter: alpha(opacity = 10);
3137 filter: alpha(opacity = 10);
3138 z-index: 9049;
3138 z-index: 9049;
3139 margin: .3em;
3139 margin: .3em;
3140 }
3140 }
3141
3141
3142 .ac .yui-ac-content ul {
3142 .ac .yui-ac-content ul {
3143 width: 100%;
3143 width: 100%;
3144 margin: 0;
3144 margin: 0;
3145 padding: 0;
3145 padding: 0;
3146 z-index: 9050;
3146 z-index: 9050;
3147 }
3147 }
3148
3148
3149 .ac .yui-ac-content li {
3149 .ac .yui-ac-content li {
3150 cursor: default;
3150 cursor: default;
3151 white-space: nowrap;
3151 white-space: nowrap;
3152 margin: 0;
3152 margin: 0;
3153 padding: 2px 5px;
3153 padding: 2px 5px;
3154 height: 18px;
3154 height: 18px;
3155 z-index: 9050;
3155 z-index: 9050;
3156 display: block;
3156 display: block;
3157 width: auto !important;
3157 width: auto !important;
3158 }
3158 }
3159
3159
3160 .ac .yui-ac-content li .ac-container-wrap{
3160 .ac .yui-ac-content li .ac-container-wrap{
3161 width: auto;
3161 width: auto;
3162 }
3162 }
3163
3163
3164 .ac .yui-ac-content li.yui-ac-prehighlight {
3164 .ac .yui-ac-content li.yui-ac-prehighlight {
3165 background: #B3D4FF;
3165 background: #B3D4FF;
3166 z-index: 9050;
3166 z-index: 9050;
3167 }
3167 }
3168
3168
3169 .ac .yui-ac-content li.yui-ac-highlight {
3169 .ac .yui-ac-content li.yui-ac-highlight {
3170 background: #556CB5;
3170 background: #556CB5;
3171 color: #FFF;
3171 color: #FFF;
3172 z-index: 9050;
3172 z-index: 9050;
3173 }
3173 }
3174 .ac .yui-ac-bd{
3174 .ac .yui-ac-bd{
3175 z-index: 9050;
3175 z-index: 9050;
3176 }
3176 }
3177
3177
3178 .follow {
3178 .follow {
3179 background: url("../images/icons/heart_add.png") no-repeat scroll 3px;
3179 background: url("../images/icons/heart_add.png") no-repeat scroll 3px;
3180 height: 16px;
3180 height: 16px;
3181 width: 20px;
3181 width: 20px;
3182 cursor: pointer;
3182 cursor: pointer;
3183 display: block;
3183 display: block;
3184 float: right;
3184 float: right;
3185 margin-top: 2px;
3185 margin-top: 2px;
3186 }
3186 }
3187
3187
3188 .following {
3188 .following {
3189 background: url("../images/icons/heart_delete.png") no-repeat scroll 3px;
3189 background: url("../images/icons/heart_delete.png") no-repeat scroll 3px;
3190 height: 16px;
3190 height: 16px;
3191 width: 20px;
3191 width: 20px;
3192 cursor: pointer;
3192 cursor: pointer;
3193 display: block;
3193 display: block;
3194 float: right;
3194 float: right;
3195 margin-top: 2px;
3195 margin-top: 2px;
3196 }
3196 }
3197
3197
3198 .locking_locked{
3198 .locking_locked{
3199 background: #FFF url("../images/icons/block_16.png") no-repeat scroll 3px;
3199 background: #FFF url("../images/icons/block_16.png") no-repeat scroll 3px;
3200 height: 16px;
3200 height: 16px;
3201 width: 20px;
3201 width: 20px;
3202 cursor: pointer;
3202 cursor: pointer;
3203 display: block;
3203 display: block;
3204 float: right;
3204 float: right;
3205 margin-top: 2px;
3205 margin-top: 2px;
3206 }
3206 }
3207
3207
3208 .locking_unlocked{
3208 .locking_unlocked{
3209 background: #FFF url("../images/icons/accept.png") no-repeat scroll 3px;
3209 background: #FFF url("../images/icons/accept.png") no-repeat scroll 3px;
3210 height: 16px;
3210 height: 16px;
3211 width: 20px;
3211 width: 20px;
3212 cursor: pointer;
3212 cursor: pointer;
3213 display: block;
3213 display: block;
3214 float: right;
3214 float: right;
3215 margin-top: 2px;
3215 margin-top: 2px;
3216 }
3216 }
3217
3217
3218 .currently_following {
3218 .currently_following {
3219 padding-left: 10px;
3219 padding-left: 10px;
3220 padding-bottom: 5px;
3220 padding-bottom: 5px;
3221 }
3221 }
3222
3222
3223 .add_icon {
3223 .add_icon {
3224 background: url("../images/icons/add.png") no-repeat scroll 3px;
3224 background: url("../images/icons/add.png") no-repeat scroll 3px;
3225 padding-left: 20px;
3225 padding-left: 20px;
3226 padding-top: 0px;
3226 padding-top: 0px;
3227 text-align: left;
3227 text-align: left;
3228 }
3228 }
3229
3229
3230 .accept_icon {
3230 .accept_icon {
3231 background: url("../images/icons/accept.png") no-repeat scroll 3px;
3231 background: url("../images/icons/accept.png") no-repeat scroll 3px;
3232 padding-left: 20px;
3232 padding-left: 20px;
3233 padding-top: 0px;
3233 padding-top: 0px;
3234 text-align: left;
3234 text-align: left;
3235 }
3235 }
3236
3236
3237 .edit_icon {
3237 .edit_icon {
3238 background: url("../images/icons/folder_edit.png") no-repeat scroll 3px;
3238 background: url("../images/icons/application_form_edit.png") no-repeat scroll 3px;
3239 padding-left: 20px;
3239 padding-left: 20px;
3240 padding-top: 0px;
3240 padding-top: 0px;
3241 text-align: left;
3241 text-align: left;
3242 }
3242 }
3243
3243
3244 .delete_icon {
3244 .delete_icon {
3245 background: url("../images/icons/delete.png") no-repeat scroll 3px;
3245 background: url("../images/icons/delete.png") no-repeat scroll 3px;
3246 padding-left: 20px;
3246 padding-left: 20px;
3247 padding-top: 0px;
3247 padding-top: 0px;
3248 text-align: left;
3248 text-align: left;
3249 }
3249 }
3250
3250
3251 .refresh_icon {
3251 .refresh_icon {
3252 background: url("../images/icons/arrow_refresh.png") no-repeat scroll
3252 background: url("../images/icons/arrow_refresh.png") no-repeat scroll
3253 3px;
3253 3px;
3254 padding-left: 20px;
3254 padding-left: 20px;
3255 padding-top: 0px;
3255 padding-top: 0px;
3256 text-align: left;
3256 text-align: left;
3257 }
3257 }
3258
3258
3259 .pull_icon {
3259 .pull_icon {
3260 background: url("../images/icons/connect.png") no-repeat scroll 3px;
3260 background: url("../images/icons/connect.png") no-repeat scroll 3px;
3261 padding-left: 20px;
3261 padding-left: 20px;
3262 padding-top: 0px;
3262 padding-top: 0px;
3263 text-align: left;
3263 text-align: left;
3264 }
3264 }
3265
3265
3266 .rss_icon {
3266 .rss_icon {
3267 background: url("../images/icons/rss_16.png") no-repeat scroll 3px;
3267 background: url("../images/icons/rss_16.png") no-repeat scroll 3px;
3268 padding-left: 20px;
3268 padding-left: 20px;
3269 padding-top: 4px;
3269 padding-top: 4px;
3270 text-align: left;
3270 text-align: left;
3271 font-size: 8px
3271 font-size: 8px
3272 }
3272 }
3273
3273
3274 .atom_icon {
3274 .atom_icon {
3275 background: url("../images/icons/atom.png") no-repeat scroll 3px;
3275 background: url("../images/icons/atom.png") no-repeat scroll 3px;
3276 padding-left: 20px;
3276 padding-left: 20px;
3277 padding-top: 4px;
3277 padding-top: 4px;
3278 text-align: left;
3278 text-align: left;
3279 font-size: 8px
3279 font-size: 8px
3280 }
3280 }
3281
3281
3282 .archive_icon {
3282 .archive_icon {
3283 background: url("../images/icons/compress.png") no-repeat scroll 3px;
3283 background: url("../images/icons/compress.png") no-repeat scroll 3px;
3284 padding-left: 20px;
3284 padding-left: 20px;
3285 text-align: left;
3285 text-align: left;
3286 padding-top: 1px;
3286 padding-top: 1px;
3287 }
3287 }
3288
3288
3289 .start_following_icon {
3289 .start_following_icon {
3290 background: url("../images/icons/heart_add.png") no-repeat scroll 3px;
3290 background: url("../images/icons/heart_add.png") no-repeat scroll 3px;
3291 padding-left: 20px;
3291 padding-left: 20px;
3292 text-align: left;
3292 text-align: left;
3293 padding-top: 0px;
3293 padding-top: 0px;
3294 }
3294 }
3295
3295
3296 .stop_following_icon {
3296 .stop_following_icon {
3297 background: url("../images/icons/heart_delete.png") no-repeat scroll 3px;
3297 background: url("../images/icons/heart_delete.png") no-repeat scroll 3px;
3298 padding-left: 20px;
3298 padding-left: 20px;
3299 text-align: left;
3299 text-align: left;
3300 padding-top: 0px;
3300 padding-top: 0px;
3301 }
3301 }
3302
3302
3303 .action_button {
3303 .action_button {
3304 border: 0;
3304 border: 0;
3305 display: inline;
3305 display: inline;
3306 }
3306 }
3307
3307
3308 .action_button:hover {
3308 .action_button:hover {
3309 border: 0;
3309 border: 0;
3310 text-decoration: underline;
3310 text-decoration: underline;
3311 cursor: pointer;
3311 cursor: pointer;
3312 }
3312 }
3313
3313
3314 #switch_repos {
3314 #switch_repos {
3315 position: absolute;
3315 position: absolute;
3316 height: 25px;
3316 height: 25px;
3317 z-index: 1;
3317 z-index: 1;
3318 }
3318 }
3319
3319
3320 #switch_repos select {
3320 #switch_repos select {
3321 min-width: 150px;
3321 min-width: 150px;
3322 max-height: 250px;
3322 max-height: 250px;
3323 z-index: 1;
3323 z-index: 1;
3324 }
3324 }
3325
3325
3326 .breadcrumbs {
3326 .breadcrumbs {
3327 border: medium none;
3327 border: medium none;
3328 color: #FFF;
3328 color: #FFF;
3329 float: left;
3329 float: left;
3330 text-transform: uppercase;
3330 text-transform: uppercase;
3331 font-weight: 700;
3331 font-weight: 700;
3332 font-size: 14px;
3332 font-size: 14px;
3333 margin: 0;
3333 margin: 0;
3334 padding: 11px 0 11px 10px;
3334 padding: 11px 0 11px 10px;
3335 }
3335 }
3336
3336
3337 .breadcrumbs .hash {
3337 .breadcrumbs .hash {
3338 text-transform: none;
3338 text-transform: none;
3339 color: #fff;
3339 color: #fff;
3340 }
3340 }
3341
3341
3342 .breadcrumbs a {
3342 .breadcrumbs a {
3343 color: #FFF;
3343 color: #FFF;
3344 }
3344 }
3345
3345
3346 .flash_msg {
3346 .flash_msg {
3347
3347
3348 }
3348 }
3349
3349
3350 .flash_msg ul {
3350 .flash_msg ul {
3351
3351
3352 }
3352 }
3353
3353
3354 .error_red {
3354 .error_red {
3355 color:red;
3355 color:red;
3356 }
3356 }
3357
3357
3358 .error_msg {
3358 .error_msg {
3359 background-color: #c43c35;
3359 background-color: #c43c35;
3360 background-repeat: repeat-x;
3360 background-repeat: repeat-x;
3361 background-image: -khtml-gradient(linear, left top, left bottom, from(#ee5f5b), to(#c43c35) );
3361 background-image: -khtml-gradient(linear, left top, left bottom, from(#ee5f5b), to(#c43c35) );
3362 background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35);
3362 background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35);
3363 background-image: -ms-linear-gradient(top, #ee5f5b, #c43c35);
3363 background-image: -ms-linear-gradient(top, #ee5f5b, #c43c35);
3364 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ee5f5b), color-stop(100%, #c43c35) );
3364 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ee5f5b), color-stop(100%, #c43c35) );
3365 background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35);
3365 background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35);
3366 background-image: -o-linear-gradient(top, #ee5f5b, #c43c35);
3366 background-image: -o-linear-gradient(top, #ee5f5b, #c43c35);
3367 background-image: linear-gradient(top, #ee5f5b, #c43c35);
3367 background-image: linear-gradient(top, #ee5f5b, #c43c35);
3368 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b',endColorstr='#c43c35', GradientType=0 );
3368 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b',endColorstr='#c43c35', GradientType=0 );
3369 border-color: #c43c35 #c43c35 #882a25;
3369 border-color: #c43c35 #c43c35 #882a25;
3370 }
3370 }
3371
3371
3372 .warning_msg {
3372 .warning_msg {
3373 color: #404040 !important;
3373 color: #404040 !important;
3374 background-color: #eedc94;
3374 background-color: #eedc94;
3375 background-repeat: repeat-x;
3375 background-repeat: repeat-x;
3376 background-image: -khtml-gradient(linear, left top, left bottom, from(#fceec1), to(#eedc94) );
3376 background-image: -khtml-gradient(linear, left top, left bottom, from(#fceec1), to(#eedc94) );
3377 background-image: -moz-linear-gradient(top, #fceec1, #eedc94);
3377 background-image: -moz-linear-gradient(top, #fceec1, #eedc94);
3378 background-image: -ms-linear-gradient(top, #fceec1, #eedc94);
3378 background-image: -ms-linear-gradient(top, #fceec1, #eedc94);
3379 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fceec1), color-stop(100%, #eedc94) );
3379 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fceec1), color-stop(100%, #eedc94) );
3380 background-image: -webkit-linear-gradient(top, #fceec1, #eedc94);
3380 background-image: -webkit-linear-gradient(top, #fceec1, #eedc94);
3381 background-image: -o-linear-gradient(top, #fceec1, #eedc94);
3381 background-image: -o-linear-gradient(top, #fceec1, #eedc94);
3382 background-image: linear-gradient(top, #fceec1, #eedc94);
3382 background-image: linear-gradient(top, #fceec1, #eedc94);
3383 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fceec1', endColorstr='#eedc94', GradientType=0 );
3383 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fceec1', endColorstr='#eedc94', GradientType=0 );
3384 border-color: #eedc94 #eedc94 #e4c652;
3384 border-color: #eedc94 #eedc94 #e4c652;
3385 }
3385 }
3386
3386
3387 .success_msg {
3387 .success_msg {
3388 background-color: #57a957;
3388 background-color: #57a957;
3389 background-repeat: repeat-x !important;
3389 background-repeat: repeat-x !important;
3390 background-image: -khtml-gradient(linear, left top, left bottom, from(#62c462), to(#57a957) );
3390 background-image: -khtml-gradient(linear, left top, left bottom, from(#62c462), to(#57a957) );
3391 background-image: -moz-linear-gradient(top, #62c462, #57a957);
3391 background-image: -moz-linear-gradient(top, #62c462, #57a957);
3392 background-image: -ms-linear-gradient(top, #62c462, #57a957);
3392 background-image: -ms-linear-gradient(top, #62c462, #57a957);
3393 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #62c462), color-stop(100%, #57a957) );
3393 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #62c462), color-stop(100%, #57a957) );
3394 background-image: -webkit-linear-gradient(top, #62c462, #57a957);
3394 background-image: -webkit-linear-gradient(top, #62c462, #57a957);
3395 background-image: -o-linear-gradient(top, #62c462, #57a957);
3395 background-image: -o-linear-gradient(top, #62c462, #57a957);
3396 background-image: linear-gradient(top, #62c462, #57a957);
3396 background-image: linear-gradient(top, #62c462, #57a957);
3397 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0 );
3397 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0 );
3398 border-color: #57a957 #57a957 #3d773d;
3398 border-color: #57a957 #57a957 #3d773d;
3399 }
3399 }
3400
3400
3401 .notice_msg {
3401 .notice_msg {
3402 background-color: #339bb9;
3402 background-color: #339bb9;
3403 background-repeat: repeat-x;
3403 background-repeat: repeat-x;
3404 background-image: -khtml-gradient(linear, left top, left bottom, from(#5bc0de), to(#339bb9) );
3404 background-image: -khtml-gradient(linear, left top, left bottom, from(#5bc0de), to(#339bb9) );
3405 background-image: -moz-linear-gradient(top, #5bc0de, #339bb9);
3405 background-image: -moz-linear-gradient(top, #5bc0de, #339bb9);
3406 background-image: -ms-linear-gradient(top, #5bc0de, #339bb9);
3406 background-image: -ms-linear-gradient(top, #5bc0de, #339bb9);
3407 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5bc0de), color-stop(100%, #339bb9) );
3407 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5bc0de), color-stop(100%, #339bb9) );
3408 background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9);
3408 background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9);
3409 background-image: -o-linear-gradient(top, #5bc0de, #339bb9);
3409 background-image: -o-linear-gradient(top, #5bc0de, #339bb9);
3410 background-image: linear-gradient(top, #5bc0de, #339bb9);
3410 background-image: linear-gradient(top, #5bc0de, #339bb9);
3411 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0 );
3411 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0 );
3412 border-color: #339bb9 #339bb9 #22697d;
3412 border-color: #339bb9 #339bb9 #22697d;
3413 }
3413 }
3414
3414
3415 .success_msg,.error_msg,.notice_msg,.warning_msg {
3415 .success_msg,.error_msg,.notice_msg,.warning_msg {
3416 font-size: 12px;
3416 font-size: 12px;
3417 font-weight: 700;
3417 font-weight: 700;
3418 min-height: 14px;
3418 min-height: 14px;
3419 line-height: 14px;
3419 line-height: 14px;
3420 margin-bottom: 10px;
3420 margin-bottom: 10px;
3421 margin-top: 0;
3421 margin-top: 0;
3422 display: block;
3422 display: block;
3423 overflow: auto;
3423 overflow: auto;
3424 padding: 6px 10px 6px 10px;
3424 padding: 6px 10px 6px 10px;
3425 border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
3425 border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
3426 position: relative;
3426 position: relative;
3427 color: #FFF;
3427 color: #FFF;
3428 border-width: 1px;
3428 border-width: 1px;
3429 border-style: solid;
3429 border-style: solid;
3430 -webkit-border-radius: 4px;
3430 -webkit-border-radius: 4px;
3431 -moz-border-radius: 4px;
3431 -moz-border-radius: 4px;
3432 border-radius: 4px;
3432 border-radius: 4px;
3433 -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
3433 -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
3434 -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
3434 -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
3435 box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
3435 box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
3436 }
3436 }
3437
3437
3438 #msg_close {
3438 #msg_close {
3439 background: transparent url("../icons/cross_grey_small.png") no-repeat scroll 0 0;
3439 background: transparent url("../icons/cross_grey_small.png") no-repeat scroll 0 0;
3440 cursor: pointer;
3440 cursor: pointer;
3441 height: 16px;
3441 height: 16px;
3442 position: absolute;
3442 position: absolute;
3443 right: 5px;
3443 right: 5px;
3444 top: 5px;
3444 top: 5px;
3445 width: 16px;
3445 width: 16px;
3446 }
3446 }
3447 div#legend_data{
3447 div#legend_data{
3448 padding-left:10px;
3448 padding-left:10px;
3449 }
3449 }
3450 div#legend_container table{
3450 div#legend_container table{
3451 border: none !important;
3451 border: none !important;
3452 }
3452 }
3453 div#legend_container table,div#legend_choices table {
3453 div#legend_container table,div#legend_choices table {
3454 width: auto !important;
3454 width: auto !important;
3455 }
3455 }
3456
3456
3457 table#permissions_manage {
3457 table#permissions_manage {
3458 width: 0 !important;
3458 width: 0 !important;
3459 }
3459 }
3460
3460
3461 table#permissions_manage span.private_repo_msg {
3461 table#permissions_manage span.private_repo_msg {
3462 font-size: 0.8em;
3462 font-size: 0.8em;
3463 opacity: 0.6px;
3463 opacity: 0.6px;
3464 }
3464 }
3465
3465
3466 table#permissions_manage td.private_repo_msg {
3466 table#permissions_manage td.private_repo_msg {
3467 font-size: 0.8em;
3467 font-size: 0.8em;
3468 }
3468 }
3469
3469
3470 table#permissions_manage tr#add_perm_input td {
3470 table#permissions_manage tr#add_perm_input td {
3471 vertical-align: middle;
3471 vertical-align: middle;
3472 }
3472 }
3473
3473
3474 div.gravatar {
3474 div.gravatar {
3475 background-color: #FFF;
3475 background-color: #FFF;
3476 float: left;
3476 float: left;
3477 margin-right: 0.7em;
3477 margin-right: 0.7em;
3478 padding: 1px 1px 1px 1px;
3478 padding: 1px 1px 1px 1px;
3479 line-height:0;
3479 line-height:0;
3480 -webkit-border-radius: 3px;
3480 -webkit-border-radius: 3px;
3481 -khtml-border-radius: 3px;
3481 -khtml-border-radius: 3px;
3482 -moz-border-radius: 3px;
3482 -moz-border-radius: 3px;
3483 border-radius: 3px;
3483 border-radius: 3px;
3484 }
3484 }
3485
3485
3486 div.gravatar img {
3486 div.gravatar img {
3487 -webkit-border-radius: 2px;
3487 -webkit-border-radius: 2px;
3488 -khtml-border-radius: 2px;
3488 -khtml-border-radius: 2px;
3489 -moz-border-radius: 2px;
3489 -moz-border-radius: 2px;
3490 border-radius: 2px;
3490 border-radius: 2px;
3491 }
3491 }
3492
3492
3493 #header,#content,#footer {
3493 #header,#content,#footer {
3494 min-width: 978px;
3494 min-width: 978px;
3495 }
3495 }
3496
3496
3497 #content {
3497 #content {
3498 clear: both;
3498 clear: both;
3499 overflow: hidden;
3499 overflow: hidden;
3500 padding: 54px 10px 14px 10px;
3500 padding: 54px 10px 14px 10px;
3501 }
3501 }
3502
3502
3503 #content div.box div.title div.search {
3503 #content div.box div.title div.search {
3504
3504
3505 border-left: 1px solid #316293;
3505 border-left: 1px solid #316293;
3506 }
3506 }
3507
3507
3508 #content div.box div.title div.search div.input input {
3508 #content div.box div.title div.search div.input input {
3509 border: 1px solid #316293;
3509 border: 1px solid #316293;
3510 }
3510 }
3511
3511
3512 .ui-btn{
3512 .ui-btn{
3513 color: #515151;
3513 color: #515151;
3514 background-color: #DADADA;
3514 background-color: #DADADA;
3515 background-repeat: repeat-x;
3515 background-repeat: repeat-x;
3516 background-image: -khtml-gradient(linear, left top, left bottom, from(#F4F4F4),to(#DADADA) );
3516 background-image: -khtml-gradient(linear, left top, left bottom, from(#F4F4F4),to(#DADADA) );
3517 background-image: -moz-linear-gradient(top, #F4F4F4, #DADADA);
3517 background-image: -moz-linear-gradient(top, #F4F4F4, #DADADA);
3518 background-image: -ms-linear-gradient(top, #F4F4F4, #DADADA);
3518 background-image: -ms-linear-gradient(top, #F4F4F4, #DADADA);
3519 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4),color-stop(100%, #DADADA) );
3519 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4),color-stop(100%, #DADADA) );
3520 background-image: -webkit-linear-gradient(top, #F4F4F4, #DADADA) );
3520 background-image: -webkit-linear-gradient(top, #F4F4F4, #DADADA) );
3521 background-image: -o-linear-gradient(top, #F4F4F4, #DADADA) );
3521 background-image: -o-linear-gradient(top, #F4F4F4, #DADADA) );
3522 background-image: linear-gradient(top, #F4F4F4, #DADADA);
3522 background-image: linear-gradient(top, #F4F4F4, #DADADA);
3523 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#F4F4F4', endColorstr='#DADADA', GradientType=0);
3523 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#F4F4F4', endColorstr='#DADADA', GradientType=0);
3524
3524
3525 border-top: 1px solid #DDD;
3525 border-top: 1px solid #DDD;
3526 border-left: 1px solid #c6c6c6;
3526 border-left: 1px solid #c6c6c6;
3527 border-right: 1px solid #DDD;
3527 border-right: 1px solid #DDD;
3528 border-bottom: 1px solid #c6c6c6;
3528 border-bottom: 1px solid #c6c6c6;
3529 color: #515151;
3529 color: #515151;
3530 outline: none;
3530 outline: none;
3531 margin: 0px 3px 3px 0px;
3531 margin: 0px 3px 3px 0px;
3532 -webkit-border-radius: 4px 4px 4px 4px !important;
3532 -webkit-border-radius: 4px 4px 4px 4px !important;
3533 -khtml-border-radius: 4px 4px 4px 4px !important;
3533 -khtml-border-radius: 4px 4px 4px 4px !important;
3534 -moz-border-radius: 4px 4px 4px 4px !important;
3534 -moz-border-radius: 4px 4px 4px 4px !important;
3535 border-radius: 4px 4px 4px 4px !important;
3535 border-radius: 4px 4px 4px 4px !important;
3536 cursor: pointer !important;
3536 cursor: pointer !important;
3537 padding: 3px 3px 3px 3px;
3537 padding: 3px 3px 3px 3px;
3538 background-position: 0 -15px;
3538 background-position: 0 -15px;
3539
3539
3540 }
3540 }
3541 .ui-btn.xsmall{
3541 .ui-btn.xsmall{
3542 padding: 1px 2px 1px 1px;
3542 padding: 1px 2px 1px 1px;
3543 }
3543 }
3544
3544
3545 .ui-btn.large{
3545 .ui-btn.large{
3546 padding: 6px 12px;
3546 padding: 6px 12px;
3547 }
3547 }
3548
3548
3549 .ui-btn.clone{
3549 .ui-btn.clone{
3550 padding: 5px 2px 6px 1px;
3550 padding: 5px 2px 6px 1px;
3551 margin: 0px -4px 3px 0px;
3551 margin: 0px -4px 3px 0px;
3552 -webkit-border-radius: 4px 0px 0px 4px !important;
3552 -webkit-border-radius: 4px 0px 0px 4px !important;
3553 -khtml-border-radius: 4px 0px 0px 4px !important;
3553 -khtml-border-radius: 4px 0px 0px 4px !important;
3554 -moz-border-radius: 4px 0px 0px 4px !important;
3554 -moz-border-radius: 4px 0px 0px 4px !important;
3555 border-radius: 4px 0px 0px 4px !important;
3555 border-radius: 4px 0px 0px 4px !important;
3556 width: 100px;
3556 width: 100px;
3557 text-align: center;
3557 text-align: center;
3558 float: left;
3558 float: left;
3559 position: absolute;
3559 position: absolute;
3560 }
3560 }
3561 .ui-btn:focus {
3561 .ui-btn:focus {
3562 outline: none;
3562 outline: none;
3563 }
3563 }
3564 .ui-btn:hover{
3564 .ui-btn:hover{
3565 background-position: 0 0px;
3565 background-position: 0 0px;
3566 text-decoration: none;
3566 text-decoration: none;
3567 color: #515151;
3567 color: #515151;
3568 box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25), 0 0 3px #FFFFFF !important;
3568 box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25), 0 0 3px #FFFFFF !important;
3569 }
3569 }
3570
3570
3571 .ui-btn.red{
3571 .ui-btn.red{
3572 color:#fff;
3572 color:#fff;
3573 background-color: #c43c35;
3573 background-color: #c43c35;
3574 background-repeat: repeat-x;
3574 background-repeat: repeat-x;
3575 background-image: -khtml-gradient(linear, left top, left bottom, from(#ee5f5b), to(#c43c35));
3575 background-image: -khtml-gradient(linear, left top, left bottom, from(#ee5f5b), to(#c43c35));
3576 background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35);
3576 background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35);
3577 background-image: -ms-linear-gradient(top, #ee5f5b, #c43c35);
3577 background-image: -ms-linear-gradient(top, #ee5f5b, #c43c35);
3578 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ee5f5b), color-stop(100%, #c43c35));
3578 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ee5f5b), color-stop(100%, #c43c35));
3579 background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35);
3579 background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35);
3580 background-image: -o-linear-gradient(top, #ee5f5b, #c43c35);
3580 background-image: -o-linear-gradient(top, #ee5f5b, #c43c35);
3581 background-image: linear-gradient(top, #ee5f5b, #c43c35);
3581 background-image: linear-gradient(top, #ee5f5b, #c43c35);
3582 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0);
3582 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0);
3583 border-color: #c43c35 #c43c35 #882a25;
3583 border-color: #c43c35 #c43c35 #882a25;
3584 border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
3584 border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
3585 }
3585 }
3586
3586
3587
3587
3588 .ui-btn.blue{
3588 .ui-btn.blue{
3589 color:#fff;
3589 color:#fff;
3590 background-color: #339bb9;
3590 background-color: #339bb9;
3591 background-repeat: repeat-x;
3591 background-repeat: repeat-x;
3592 background-image: -khtml-gradient(linear, left top, left bottom, from(#5bc0de), to(#339bb9));
3592 background-image: -khtml-gradient(linear, left top, left bottom, from(#5bc0de), to(#339bb9));
3593 background-image: -moz-linear-gradient(top, #5bc0de, #339bb9);
3593 background-image: -moz-linear-gradient(top, #5bc0de, #339bb9);
3594 background-image: -ms-linear-gradient(top, #5bc0de, #339bb9);
3594 background-image: -ms-linear-gradient(top, #5bc0de, #339bb9);
3595 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5bc0de), color-stop(100%, #339bb9));
3595 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5bc0de), color-stop(100%, #339bb9));
3596 background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9);
3596 background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9);
3597 background-image: -o-linear-gradient(top, #5bc0de, #339bb9);
3597 background-image: -o-linear-gradient(top, #5bc0de, #339bb9);
3598 background-image: linear-gradient(top, #5bc0de, #339bb9);
3598 background-image: linear-gradient(top, #5bc0de, #339bb9);
3599 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0);
3599 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0);
3600 border-color: #339bb9 #339bb9 #22697d;
3600 border-color: #339bb9 #339bb9 #22697d;
3601 border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
3601 border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
3602 }
3602 }
3603
3603
3604 .ui-btn.green{
3604 .ui-btn.green{
3605 background-color: #57a957;
3605 background-color: #57a957;
3606 background-repeat: repeat-x;
3606 background-repeat: repeat-x;
3607 background-image: -khtml-gradient(linear, left top, left bottom, from(#62c462), to(#57a957));
3607 background-image: -khtml-gradient(linear, left top, left bottom, from(#62c462), to(#57a957));
3608 background-image: -moz-linear-gradient(top, #62c462, #57a957);
3608 background-image: -moz-linear-gradient(top, #62c462, #57a957);
3609 background-image: -ms-linear-gradient(top, #62c462, #57a957);
3609 background-image: -ms-linear-gradient(top, #62c462, #57a957);
3610 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #62c462), color-stop(100%, #57a957));
3610 background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #62c462), color-stop(100%, #57a957));
3611 background-image: -webkit-linear-gradient(top, #62c462, #57a957);
3611 background-image: -webkit-linear-gradient(top, #62c462, #57a957);
3612 background-image: -o-linear-gradient(top, #62c462, #57a957);
3612 background-image: -o-linear-gradient(top, #62c462, #57a957);
3613 background-image: linear-gradient(top, #62c462, #57a957);
3613 background-image: linear-gradient(top, #62c462, #57a957);
3614 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0);
3614 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0);
3615 border-color: #57a957 #57a957 #3d773d;
3615 border-color: #57a957 #57a957 #3d773d;
3616 border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
3616 border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
3617 }
3617 }
3618
3618
3619 .ui-btn.blue.hidden{
3619 .ui-btn.blue.hidden{
3620 display: none;
3620 display: none;
3621 }
3621 }
3622
3622
3623 .ui-btn.active{
3623 .ui-btn.active{
3624 font-weight: bold;
3624 font-weight: bold;
3625 }
3625 }
3626
3626
3627 ins,div.options a:hover {
3627 ins,div.options a:hover {
3628 text-decoration: none;
3628 text-decoration: none;
3629 }
3629 }
3630
3630
3631 img,
3631 img,
3632 #header #header-inner #quick li a:hover span.normal,
3632 #header #header-inner #quick li a:hover span.normal,
3633 #header #header-inner #quick li ul li.last,
3633 #header #header-inner #quick li ul li.last,
3634 #content div.box div.form div.fields div.field div.textarea table td table td a,
3634 #content div.box div.form div.fields div.field div.textarea table td table td a,
3635 #clone_url,
3635 #clone_url,
3636 #clone_url_id
3636 #clone_url_id
3637 {
3637 {
3638 border: none;
3638 border: none;
3639 }
3639 }
3640
3640
3641 img.icon,.right .merge img {
3641 img.icon,.right .merge img {
3642 vertical-align: bottom;
3642 vertical-align: bottom;
3643 }
3643 }
3644
3644
3645 #header ul#logged-user,#content div.box div.title ul.links,
3645 #header ul#logged-user,#content div.box div.title ul.links,
3646 #content div.box div.message div.dismiss,
3646 #content div.box div.message div.dismiss,
3647 #content div.box div.traffic div.legend ul
3647 #content div.box div.traffic div.legend ul
3648 {
3648 {
3649 float: right;
3649 float: right;
3650 margin: 0;
3650 margin: 0;
3651 padding: 0;
3651 padding: 0;
3652 }
3652 }
3653
3653
3654 #header #header-inner #home,#header #header-inner #logo,
3654 #header #header-inner #home,#header #header-inner #logo,
3655 #content div.box ul.left,#content div.box ol.left,
3655 #content div.box ul.left,#content div.box ol.left,
3656 #content div.box div.pagination-left,div#commit_history,
3656 #content div.box div.pagination-left,div#commit_history,
3657 div#legend_data,div#legend_container,div#legend_choices
3657 div#legend_data,div#legend_container,div#legend_choices
3658 {
3658 {
3659 float: left;
3659 float: left;
3660 }
3660 }
3661
3661
3662 #header #header-inner #quick li:hover ul ul,
3662 #header #header-inner #quick li:hover ul ul,
3663 #header #header-inner #quick li:hover ul ul ul,
3663 #header #header-inner #quick li:hover ul ul ul,
3664 #header #header-inner #quick li:hover ul ul ul ul,
3664 #header #header-inner #quick li:hover ul ul ul ul,
3665 #content #left #menu ul.closed,#content #left #menu li ul.collapsed,.yui-tt-shadow
3665 #content #left #menu ul.closed,#content #left #menu li ul.collapsed,.yui-tt-shadow
3666 {
3666 {
3667 display: none;
3667 display: none;
3668 }
3668 }
3669
3669
3670 #header #header-inner #quick li:hover ul,#header #header-inner #quick li li:hover ul,#header #header-inner #quick li li li:hover ul,#header #header-inner #quick li li li li:hover ul,#content #left #menu ul.opened,#content #left #menu li ul.expanded
3670 #header #header-inner #quick li:hover ul,#header #header-inner #quick li li:hover ul,#header #header-inner #quick li li li:hover ul,#header #header-inner #quick li li li li:hover ul,#content #left #menu ul.opened,#content #left #menu li ul.expanded
3671 {
3671 {
3672 display: block;
3672 display: block;
3673 }
3673 }
3674
3674
3675 #content div.graph {
3675 #content div.graph {
3676 padding: 0 10px 10px;
3676 padding: 0 10px 10px;
3677 }
3677 }
3678
3678
3679 #content div.box div.title ul.links li a:hover,#content div.box div.title ul.links li.ui-tabs-selected a
3679 #content div.box div.title ul.links li a:hover,#content div.box div.title ul.links li.ui-tabs-selected a
3680 {
3680 {
3681 color: #bfe3ff;
3681 color: #bfe3ff;
3682 }
3682 }
3683
3683
3684 #content div.box ol.lower-roman,#content div.box ol.upper-roman,#content div.box ol.lower-alpha,#content div.box ol.upper-alpha,#content div.box ol.decimal
3684 #content div.box ol.lower-roman,#content div.box ol.upper-roman,#content div.box ol.lower-alpha,#content div.box ol.upper-alpha,#content div.box ol.decimal
3685 {
3685 {
3686 margin: 10px 24px 10px 44px;
3686 margin: 10px 24px 10px 44px;
3687 }
3687 }
3688
3688
3689 #content div.box div.form,#content div.box div.table,#content div.box div.traffic
3689 #content div.box div.form,#content div.box div.table,#content div.box div.traffic
3690 {
3690 {
3691 clear: both;
3691 clear: both;
3692 overflow: hidden;
3692 overflow: hidden;
3693 margin: 0;
3693 margin: 0;
3694 padding: 0 20px 10px;
3694 padding: 0 20px 10px;
3695 }
3695 }
3696
3696
3697 #content div.box div.form div.fields,#login div.form,#login div.form div.fields,#register div.form,#register div.form div.fields
3697 #content div.box div.form div.fields,#login div.form,#login div.form div.fields,#register div.form,#register div.form div.fields
3698 {
3698 {
3699 clear: both;
3699 clear: both;
3700 overflow: hidden;
3700 overflow: hidden;
3701 margin: 0;
3701 margin: 0;
3702 padding: 0;
3702 padding: 0;
3703 }
3703 }
3704
3704
3705 #content div.box div.form div.fields div.field div.label span,#login div.form div.fields div.field div.label span,#register div.form div.fields div.field div.label span
3705 #content div.box div.form div.fields div.field div.label span,#login div.form div.fields div.field div.label span,#register div.form div.fields div.field div.label span
3706 {
3706 {
3707 height: 1%;
3707 height: 1%;
3708 display: block;
3708 display: block;
3709 color: #363636;
3709 color: #363636;
3710 margin: 0;
3710 margin: 0;
3711 padding: 2px 0 0;
3711 padding: 2px 0 0;
3712 }
3712 }
3713
3713
3714 #content div.box div.form div.fields div.field div.input input.error,#login div.form div.fields div.field div.input input.error,#register div.form div.fields div.field div.input input.error
3714 #content div.box div.form div.fields div.field div.input input.error,#login div.form div.fields div.field div.input input.error,#register div.form div.fields div.field div.input input.error
3715 {
3715 {
3716 background: #FBE3E4;
3716 background: #FBE3E4;
3717 border-top: 1px solid #e1b2b3;
3717 border-top: 1px solid #e1b2b3;
3718 border-left: 1px solid #e1b2b3;
3718 border-left: 1px solid #e1b2b3;
3719 border-right: 1px solid #FBC2C4;
3719 border-right: 1px solid #FBC2C4;
3720 border-bottom: 1px solid #FBC2C4;
3720 border-bottom: 1px solid #FBC2C4;
3721 }
3721 }
3722
3722
3723 #content div.box div.form div.fields div.field div.input input.success,#login div.form div.fields div.field div.input input.success,#register div.form div.fields div.field div.input input.success
3723 #content div.box div.form div.fields div.field div.input input.success,#login div.form div.fields div.field div.input input.success,#register div.form div.fields div.field div.input input.success
3724 {
3724 {
3725 background: #E6EFC2;
3725 background: #E6EFC2;
3726 border-top: 1px solid #cebb98;
3726 border-top: 1px solid #cebb98;
3727 border-left: 1px solid #cebb98;
3727 border-left: 1px solid #cebb98;
3728 border-right: 1px solid #c6d880;
3728 border-right: 1px solid #c6d880;
3729 border-bottom: 1px solid #c6d880;
3729 border-bottom: 1px solid #c6d880;
3730 }
3730 }
3731
3731
3732 #content div.box-left div.form div.fields div.field div.textarea,#content div.box-right div.form div.fields div.field div.textarea,#content div.box div.form div.fields div.field div.select select,#content div.box table th.selected input,#content div.box table td.selected input
3732 #content div.box-left div.form div.fields div.field div.textarea,#content div.box-right div.form div.fields div.field div.textarea,#content div.box div.form div.fields div.field div.select select,#content div.box table th.selected input,#content div.box table td.selected input
3733 {
3733 {
3734 margin: 0;
3734 margin: 0;
3735 }
3735 }
3736
3736
3737 #content div.box-left div.form div.fields div.field div.select,#content div.box-left div.form div.fields div.field div.checkboxes,#content div.box-left div.form div.fields div.field div.radios,#content div.box-right div.form div.fields div.field div.select,#content div.box-right div.form div.fields div.field div.checkboxes,#content div.box-right div.form div.fields div.field div.radios
3737 #content div.box-left div.form div.fields div.field div.select,#content div.box-left div.form div.fields div.field div.checkboxes,#content div.box-left div.form div.fields div.field div.radios,#content div.box-right div.form div.fields div.field div.select,#content div.box-right div.form div.fields div.field div.checkboxes,#content div.box-right div.form div.fields div.field div.radios
3738 {
3738 {
3739 margin: 0 0 0 0px !important;
3739 margin: 0 0 0 0px !important;
3740 padding: 0;
3740 padding: 0;
3741 }
3741 }
3742
3742
3743 #content div.box div.form div.fields div.field div.select,#content div.box div.form div.fields div.field div.checkboxes,#content div.box div.form div.fields div.field div.radios
3743 #content div.box div.form div.fields div.field div.select,#content div.box div.form div.fields div.field div.checkboxes,#content div.box div.form div.fields div.field div.radios
3744 {
3744 {
3745 margin: 0 0 0 200px;
3745 margin: 0 0 0 200px;
3746 padding: 0;
3746 padding: 0;
3747 }
3747 }
3748
3748
3749 #content div.box div.form div.fields div.field div.select a:hover,#content div.box div.form div.fields div.field div.select a.ui-selectmenu:hover,#content div.box div.action a:hover
3749 #content div.box div.form div.fields div.field div.select a:hover,#content div.box div.form div.fields div.field div.select a.ui-selectmenu:hover,#content div.box div.action a:hover
3750 {
3750 {
3751 color: #000;
3751 color: #000;
3752 text-decoration: none;
3752 text-decoration: none;
3753 }
3753 }
3754
3754
3755 #content div.box div.form div.fields div.field div.select a.ui-selectmenu-focus,#content div.box div.action a.ui-selectmenu-focus
3755 #content div.box div.form div.fields div.field div.select a.ui-selectmenu-focus,#content div.box div.action a.ui-selectmenu-focus
3756 {
3756 {
3757 border: 1px solid #666;
3757 border: 1px solid #666;
3758 }
3758 }
3759
3759
3760 #content div.box div.form div.fields div.field div.checkboxes div.checkbox,#content div.box div.form div.fields div.field div.radios div.radio
3760 #content div.box div.form div.fields div.field div.checkboxes div.checkbox,#content div.box div.form div.fields div.field div.radios div.radio
3761 {
3761 {
3762 clear: both;
3762 clear: both;
3763 overflow: hidden;
3763 overflow: hidden;
3764 margin: 0;
3764 margin: 0;
3765 padding: 8px 0 2px;
3765 padding: 8px 0 2px;
3766 }
3766 }
3767
3767
3768 #content div.box div.form div.fields div.field div.checkboxes div.checkbox input,#content div.box div.form div.fields div.field div.radios div.radio input
3768 #content div.box div.form div.fields div.field div.checkboxes div.checkbox input,#content div.box div.form div.fields div.field div.radios div.radio input
3769 {
3769 {
3770 float: left;
3770 float: left;
3771 margin: 0;
3771 margin: 0;
3772 }
3772 }
3773
3773
3774 #content div.box div.form div.fields div.field div.checkboxes div.checkbox label,#content div.box div.form div.fields div.field div.radios div.radio label
3774 #content div.box div.form div.fields div.field div.checkboxes div.checkbox label,#content div.box div.form div.fields div.field div.radios div.radio label
3775 {
3775 {
3776 height: 1%;
3776 height: 1%;
3777 display: block;
3777 display: block;
3778 float: left;
3778 float: left;
3779 margin: 2px 0 0 4px;
3779 margin: 2px 0 0 4px;
3780 }
3780 }
3781
3781
3782 div.form div.fields div.field div.button input,
3782 div.form div.fields div.field div.button input,
3783 #content div.box div.form div.fields div.buttons input
3783 #content div.box div.form div.fields div.buttons input
3784 div.form div.fields div.buttons input,
3784 div.form div.fields div.buttons input,
3785 #content div.box div.action div.button input {
3785 #content div.box div.action div.button input {
3786 /*color: #000;*/
3786 /*color: #000;*/
3787 font-size: 11px;
3787 font-size: 11px;
3788 font-weight: 700;
3788 font-weight: 700;
3789 margin: 0;
3789 margin: 0;
3790 }
3790 }
3791
3791
3792 input.ui-button {
3792 input.ui-button {
3793 background: #e5e3e3 url("../images/button.png") repeat-x;
3793 background: #e5e3e3 url("../images/button.png") repeat-x;
3794 border-top: 1px solid #DDD;
3794 border-top: 1px solid #DDD;
3795 border-left: 1px solid #c6c6c6;
3795 border-left: 1px solid #c6c6c6;
3796 border-right: 1px solid #DDD;
3796 border-right: 1px solid #DDD;
3797 border-bottom: 1px solid #c6c6c6;
3797 border-bottom: 1px solid #c6c6c6;
3798 color: #515151 !important;
3798 color: #515151 !important;
3799 outline: none;
3799 outline: none;
3800 margin: 0;
3800 margin: 0;
3801 padding: 6px 12px;
3801 padding: 6px 12px;
3802 -webkit-border-radius: 4px 4px 4px 4px;
3802 -webkit-border-radius: 4px 4px 4px 4px;
3803 -khtml-border-radius: 4px 4px 4px 4px;
3803 -khtml-border-radius: 4px 4px 4px 4px;
3804 -moz-border-radius: 4px 4px 4px 4px;
3804 -moz-border-radius: 4px 4px 4px 4px;
3805 border-radius: 4px 4px 4px 4px;
3805 border-radius: 4px 4px 4px 4px;
3806 box-shadow: 0 1px 0 #ececec;
3806 box-shadow: 0 1px 0 #ececec;
3807 cursor: pointer;
3807 cursor: pointer;
3808 }
3808 }
3809
3809
3810 input.ui-button:hover {
3810 input.ui-button:hover {
3811 background: #b4b4b4 url("../images/button_selected.png") repeat-x;
3811 background: #b4b4b4 url("../images/button_selected.png") repeat-x;
3812 border-top: 1px solid #ccc;
3812 border-top: 1px solid #ccc;
3813 border-left: 1px solid #bebebe;
3813 border-left: 1px solid #bebebe;
3814 border-right: 1px solid #b1b1b1;
3814 border-right: 1px solid #b1b1b1;
3815 border-bottom: 1px solid #afafaf;
3815 border-bottom: 1px solid #afafaf;
3816 }
3816 }
3817
3817
3818 div.form div.fields div.field div.highlight,#content div.box div.form div.fields div.buttons div.highlight
3818 div.form div.fields div.field div.highlight,#content div.box div.form div.fields div.buttons div.highlight
3819 {
3819 {
3820 display: inline;
3820 display: inline;
3821 }
3821 }
3822
3822
3823 #content div.box div.form div.fields div.buttons,div.form div.fields div.buttons
3823 #content div.box div.form div.fields div.buttons,div.form div.fields div.buttons
3824 {
3824 {
3825 margin: 10px 0 0 200px;
3825 margin: 10px 0 0 200px;
3826 padding: 0;
3826 padding: 0;
3827 }
3827 }
3828
3828
3829 #content div.box-left div.form div.fields div.buttons,#content div.box-right div.form div.fields div.buttons,div.box-left div.form div.fields div.buttons,div.box-right div.form div.fields div.buttons
3829 #content div.box-left div.form div.fields div.buttons,#content div.box-right div.form div.fields div.buttons,div.box-left div.form div.fields div.buttons,div.box-right div.form div.fields div.buttons
3830 {
3830 {
3831 margin: 10px 0 0;
3831 margin: 10px 0 0;
3832 }
3832 }
3833
3833
3834 #content div.box table td.user,#content div.box table td.address {
3834 #content div.box table td.user,#content div.box table td.address {
3835 width: 10%;
3835 width: 10%;
3836 text-align: center;
3836 text-align: center;
3837 }
3837 }
3838
3838
3839 #content div.box div.action div.button,#login div.form div.fields div.field div.input div.link,#register div.form div.fields div.field div.input div.link
3839 #content div.box div.action div.button,#login div.form div.fields div.field div.input div.link,#register div.form div.fields div.field div.input div.link
3840 {
3840 {
3841 text-align: right;
3841 text-align: right;
3842 margin: 6px 0 0;
3842 margin: 6px 0 0;
3843 padding: 0;
3843 padding: 0;
3844 }
3844 }
3845
3845
3846 #content div.box div.action div.button input.ui-state-hover,#login div.form div.fields div.buttons input.ui-state-hover,#register div.form div.fields div.buttons input.ui-state-hover
3846 #content div.box div.action div.button input.ui-state-hover,#login div.form div.fields div.buttons input.ui-state-hover,#register div.form div.fields div.buttons input.ui-state-hover
3847 {
3847 {
3848 background: #b4b4b4 url("../images/button_selected.png") repeat-x;
3848 background: #b4b4b4 url("../images/button_selected.png") repeat-x;
3849 border-top: 1px solid #ccc;
3849 border-top: 1px solid #ccc;
3850 border-left: 1px solid #bebebe;
3850 border-left: 1px solid #bebebe;
3851 border-right: 1px solid #b1b1b1;
3851 border-right: 1px solid #b1b1b1;
3852 border-bottom: 1px solid #afafaf;
3852 border-bottom: 1px solid #afafaf;
3853 color: #515151;
3853 color: #515151;
3854 margin: 0;
3854 margin: 0;
3855 padding: 6px 12px;
3855 padding: 6px 12px;
3856 }
3856 }
3857
3857
3858 #content div.box div.pagination div.results,#content div.box div.pagination-wh div.results
3858 #content div.box div.pagination div.results,#content div.box div.pagination-wh div.results
3859 {
3859 {
3860 text-align: left;
3860 text-align: left;
3861 float: left;
3861 float: left;
3862 margin: 0;
3862 margin: 0;
3863 padding: 0;
3863 padding: 0;
3864 }
3864 }
3865
3865
3866 #content div.box div.pagination div.results span,#content div.box div.pagination-wh div.results span
3866 #content div.box div.pagination div.results span,#content div.box div.pagination-wh div.results span
3867 {
3867 {
3868 height: 1%;
3868 height: 1%;
3869 display: block;
3869 display: block;
3870 float: left;
3870 float: left;
3871 background: #ebebeb url("../images/pager.png") repeat-x;
3871 background: #ebebeb url("../images/pager.png") repeat-x;
3872 border-top: 1px solid #dedede;
3872 border-top: 1px solid #dedede;
3873 border-left: 1px solid #cfcfcf;
3873 border-left: 1px solid #cfcfcf;
3874 border-right: 1px solid #c4c4c4;
3874 border-right: 1px solid #c4c4c4;
3875 border-bottom: 1px solid #c4c4c4;
3875 border-bottom: 1px solid #c4c4c4;
3876 color: #4A4A4A;
3876 color: #4A4A4A;
3877 font-weight: 700;
3877 font-weight: 700;
3878 margin: 0;
3878 margin: 0;
3879 padding: 6px 8px;
3879 padding: 6px 8px;
3880 }
3880 }
3881
3881
3882 #content div.box div.pagination ul.pager li.disabled,#content div.box div.pagination-wh a.disabled
3882 #content div.box div.pagination ul.pager li.disabled,#content div.box div.pagination-wh a.disabled
3883 {
3883 {
3884 color: #B4B4B4;
3884 color: #B4B4B4;
3885 padding: 6px;
3885 padding: 6px;
3886 }
3886 }
3887
3887
3888 #login,#register {
3888 #login,#register {
3889 width: 520px;
3889 width: 520px;
3890 margin: 10% auto 0;
3890 margin: 10% auto 0;
3891 padding: 0;
3891 padding: 0;
3892 }
3892 }
3893
3893
3894 #login div.color,#register div.color {
3894 #login div.color,#register div.color {
3895 clear: both;
3895 clear: both;
3896 overflow: hidden;
3896 overflow: hidden;
3897 background: #FFF;
3897 background: #FFF;
3898 margin: 10px auto 0;
3898 margin: 10px auto 0;
3899 padding: 3px 3px 3px 0;
3899 padding: 3px 3px 3px 0;
3900 }
3900 }
3901
3901
3902 #login div.color a,#register div.color a {
3902 #login div.color a,#register div.color a {
3903 width: 20px;
3903 width: 20px;
3904 height: 20px;
3904 height: 20px;
3905 display: block;
3905 display: block;
3906 float: left;
3906 float: left;
3907 margin: 0 0 0 3px;
3907 margin: 0 0 0 3px;
3908 padding: 0;
3908 padding: 0;
3909 }
3909 }
3910
3910
3911 #login div.title h5,#register div.title h5 {
3911 #login div.title h5,#register div.title h5 {
3912 color: #fff;
3912 color: #fff;
3913 margin: 10px;
3913 margin: 10px;
3914 padding: 0;
3914 padding: 0;
3915 }
3915 }
3916
3916
3917 #login div.form div.fields div.field,#register div.form div.fields div.field
3917 #login div.form div.fields div.field,#register div.form div.fields div.field
3918 {
3918 {
3919 clear: both;
3919 clear: both;
3920 overflow: hidden;
3920 overflow: hidden;
3921 margin: 0;
3921 margin: 0;
3922 padding: 0 0 10px;
3922 padding: 0 0 10px;
3923 }
3923 }
3924
3924
3925 #login div.form div.fields div.field span.error-message,#register div.form div.fields div.field span.error-message
3925 #login div.form div.fields div.field span.error-message,#register div.form div.fields div.field span.error-message
3926 {
3926 {
3927 height: 1%;
3927 height: 1%;
3928 display: block;
3928 display: block;
3929 color: red;
3929 color: red;
3930 margin: 8px 0 0;
3930 margin: 8px 0 0;
3931 padding: 0;
3931 padding: 0;
3932 max-width: 320px;
3932 max-width: 320px;
3933 }
3933 }
3934
3934
3935 #login div.form div.fields div.field div.label label,#register div.form div.fields div.field div.label label
3935 #login div.form div.fields div.field div.label label,#register div.form div.fields div.field div.label label
3936 {
3936 {
3937 color: #000;
3937 color: #000;
3938 font-weight: 700;
3938 font-weight: 700;
3939 }
3939 }
3940
3940
3941 #login div.form div.fields div.field div.input,#register div.form div.fields div.field div.input
3941 #login div.form div.fields div.field div.input,#register div.form div.fields div.field div.input
3942 {
3942 {
3943 float: left;
3943 float: left;
3944 margin: 0;
3944 margin: 0;
3945 padding: 0;
3945 padding: 0;
3946 }
3946 }
3947
3947
3948 #login div.form div.fields div.field div.checkbox,#register div.form div.fields div.field div.checkbox
3948 #login div.form div.fields div.field div.checkbox,#register div.form div.fields div.field div.checkbox
3949 {
3949 {
3950 margin: 0 0 0 184px;
3950 margin: 0 0 0 184px;
3951 padding: 0;
3951 padding: 0;
3952 }
3952 }
3953
3953
3954 #login div.form div.fields div.field div.checkbox label,#register div.form div.fields div.field div.checkbox label
3954 #login div.form div.fields div.field div.checkbox label,#register div.form div.fields div.field div.checkbox label
3955 {
3955 {
3956 color: #565656;
3956 color: #565656;
3957 font-weight: 700;
3957 font-weight: 700;
3958 }
3958 }
3959
3959
3960 #login div.form div.fields div.buttons input,#register div.form div.fields div.buttons input
3960 #login div.form div.fields div.buttons input,#register div.form div.fields div.buttons input
3961 {
3961 {
3962 color: #000;
3962 color: #000;
3963 font-size: 1em;
3963 font-size: 1em;
3964 font-weight: 700;
3964 font-weight: 700;
3965 margin: 0;
3965 margin: 0;
3966 }
3966 }
3967
3967
3968 #changeset_content .container .wrapper,#graph_content .container .wrapper
3968 #changeset_content .container .wrapper,#graph_content .container .wrapper
3969 {
3969 {
3970 width: 600px;
3970 width: 600px;
3971 }
3971 }
3972
3972
3973 #changeset_content .container .left {
3973 #changeset_content .container .left {
3974 float: left;
3974 float: left;
3975 width: 75%;
3975 width: 75%;
3976 padding-left: 5px;
3976 padding-left: 5px;
3977 }
3977 }
3978
3978
3979 #changeset_content .container .left .date,.ac .match {
3979 #changeset_content .container .left .date,.ac .match {
3980 font-weight: 700;
3980 font-weight: 700;
3981 padding-top: 5px;
3981 padding-top: 5px;
3982 padding-bottom: 5px;
3982 padding-bottom: 5px;
3983 }
3983 }
3984
3984
3985 div#legend_container table td,div#legend_choices table td {
3985 div#legend_container table td,div#legend_choices table td {
3986 border: none !important;
3986 border: none !important;
3987 height: 20px !important;
3987 height: 20px !important;
3988 padding: 0 !important;
3988 padding: 0 !important;
3989 }
3989 }
3990
3990
3991 .q_filter_box {
3991 .q_filter_box {
3992 -webkit-box-shadow: rgba(0,0,0,0.07) 0 1px 2px inset;
3992 -webkit-box-shadow: rgba(0,0,0,0.07) 0 1px 2px inset;
3993 -webkit-border-radius: 4px;
3993 -webkit-border-radius: 4px;
3994 -moz-border-radius: 4px;
3994 -moz-border-radius: 4px;
3995 border-radius: 4px;
3995 border-radius: 4px;
3996 border: 0 none;
3996 border: 0 none;
3997 color: #AAAAAA;
3997 color: #AAAAAA;
3998 margin-bottom: -4px;
3998 margin-bottom: -4px;
3999 margin-top: -4px;
3999 margin-top: -4px;
4000 padding-left: 3px;
4000 padding-left: 3px;
4001 }
4001 }
4002
4002
4003 #node_filter {
4003 #node_filter {
4004 border: 0px solid #545454;
4004 border: 0px solid #545454;
4005 color: #AAAAAA;
4005 color: #AAAAAA;
4006 padding-left: 3px;
4006 padding-left: 3px;
4007 }
4007 }
4008
4008
4009
4009
4010 .group_members_wrap{
4010 .group_members_wrap{
4011 min-height: 85px;
4011 min-height: 85px;
4012 padding-left: 20px;
4012 padding-left: 20px;
4013 }
4013 }
4014
4014
4015 .group_members .group_member{
4015 .group_members .group_member{
4016 height: 30px;
4016 height: 30px;
4017 padding:0px 0px 0px 0px;
4017 padding:0px 0px 0px 0px;
4018 }
4018 }
4019
4019
4020 .reviewers_member{
4020 .reviewers_member{
4021 height: 15px;
4021 height: 15px;
4022 padding:0px 0px 0px 10px;
4022 padding:0px 0px 0px 10px;
4023 }
4023 }
4024
4024
4025 .emails_wrap{
4025 .emails_wrap{
4026 padding: 0px 20px;
4026 padding: 0px 20px;
4027 }
4027 }
4028
4028
4029 .emails_wrap .email_entry{
4029 .emails_wrap .email_entry{
4030 height: 30px;
4030 height: 30px;
4031 padding:0px 0px 0px 10px;
4031 padding:0px 0px 0px 10px;
4032 }
4032 }
4033 .emails_wrap .email_entry .email{
4033 .emails_wrap .email_entry .email{
4034 float: left
4034 float: left
4035 }
4035 }
4036 .emails_wrap .email_entry .email_action{
4036 .emails_wrap .email_entry .email_action{
4037 float: left
4037 float: left
4038 }
4038 }
4039
4039
4040 .ips_wrap{
4040 .ips_wrap{
4041 padding: 0px 20px;
4041 padding: 0px 20px;
4042 }
4042 }
4043
4043
4044 .ips_wrap .ip_entry{
4044 .ips_wrap .ip_entry{
4045 height: 30px;
4045 height: 30px;
4046 padding:0px 0px 0px 10px;
4046 padding:0px 0px 0px 10px;
4047 }
4047 }
4048 .ips_wrap .ip_entry .ip{
4048 .ips_wrap .ip_entry .ip{
4049 float: left
4049 float: left
4050 }
4050 }
4051 .ips_wrap .ip_entry .ip_action{
4051 .ips_wrap .ip_entry .ip_action{
4052 float: left
4052 float: left
4053 }
4053 }
4054
4054
4055
4055
4056 /*README STYLE*/
4056 /*README STYLE*/
4057
4057
4058 div.readme {
4058 div.readme {
4059 padding:0px;
4059 padding:0px;
4060 }
4060 }
4061
4061
4062 div.readme h2 {
4062 div.readme h2 {
4063 font-weight: normal;
4063 font-weight: normal;
4064 }
4064 }
4065
4065
4066 div.readme .readme_box {
4066 div.readme .readme_box {
4067 background-color: #fafafa;
4067 background-color: #fafafa;
4068 }
4068 }
4069
4069
4070 div.readme .readme_box {
4070 div.readme .readme_box {
4071 clear:both;
4071 clear:both;
4072 overflow:hidden;
4072 overflow:hidden;
4073 margin:0;
4073 margin:0;
4074 padding:0 20px 10px;
4074 padding:0 20px 10px;
4075 }
4075 }
4076
4076
4077 div.readme .readme_box h1, div.readme .readme_box h2, div.readme .readme_box h3, div.readme .readme_box h4, div.readme .readme_box h5, div.readme .readme_box h6 {
4077 div.readme .readme_box h1, div.readme .readme_box h2, div.readme .readme_box h3, div.readme .readme_box h4, div.readme .readme_box h5, div.readme .readme_box h6 {
4078 border-bottom: 0 !important;
4078 border-bottom: 0 !important;
4079 margin: 0 !important;
4079 margin: 0 !important;
4080 padding: 0 !important;
4080 padding: 0 !important;
4081 line-height: 1.5em !important;
4081 line-height: 1.5em !important;
4082 }
4082 }
4083
4083
4084
4084
4085 div.readme .readme_box h1:first-child {
4085 div.readme .readme_box h1:first-child {
4086 padding-top: .25em !important;
4086 padding-top: .25em !important;
4087 }
4087 }
4088
4088
4089 div.readme .readme_box h2, div.readme .readme_box h3 {
4089 div.readme .readme_box h2, div.readme .readme_box h3 {
4090 margin: 1em 0 !important;
4090 margin: 1em 0 !important;
4091 }
4091 }
4092
4092
4093 div.readme .readme_box h2 {
4093 div.readme .readme_box h2 {
4094 margin-top: 1.5em !important;
4094 margin-top: 1.5em !important;
4095 border-top: 4px solid #e0e0e0 !important;
4095 border-top: 4px solid #e0e0e0 !important;
4096 padding-top: .5em !important;
4096 padding-top: .5em !important;
4097 }
4097 }
4098
4098
4099 div.readme .readme_box p {
4099 div.readme .readme_box p {
4100 color: black !important;
4100 color: black !important;
4101 margin: 1em 0 !important;
4101 margin: 1em 0 !important;
4102 line-height: 1.5em !important;
4102 line-height: 1.5em !important;
4103 }
4103 }
4104
4104
4105 div.readme .readme_box ul {
4105 div.readme .readme_box ul {
4106 list-style: disc !important;
4106 list-style: disc !important;
4107 margin: 1em 0 1em 2em !important;
4107 margin: 1em 0 1em 2em !important;
4108 }
4108 }
4109
4109
4110 div.readme .readme_box ol {
4110 div.readme .readme_box ol {
4111 list-style: decimal;
4111 list-style: decimal;
4112 margin: 1em 0 1em 2em !important;
4112 margin: 1em 0 1em 2em !important;
4113 }
4113 }
4114
4114
4115 div.readme .readme_box pre, code {
4115 div.readme .readme_box pre, code {
4116 font: 12px "Bitstream Vera Sans Mono","Courier",monospace;
4116 font: 12px "Bitstream Vera Sans Mono","Courier",monospace;
4117 }
4117 }
4118
4118
4119 div.readme .readme_box code {
4119 div.readme .readme_box code {
4120 font-size: 12px !important;
4120 font-size: 12px !important;
4121 background-color: ghostWhite !important;
4121 background-color: ghostWhite !important;
4122 color: #444 !important;
4122 color: #444 !important;
4123 padding: 0 .2em !important;
4123 padding: 0 .2em !important;
4124 border: 1px solid #dedede !important;
4124 border: 1px solid #dedede !important;
4125 }
4125 }
4126
4126
4127 div.readme .readme_box pre code {
4127 div.readme .readme_box pre code {
4128 padding: 0 !important;
4128 padding: 0 !important;
4129 font-size: 12px !important;
4129 font-size: 12px !important;
4130 background-color: #eee !important;
4130 background-color: #eee !important;
4131 border: none !important;
4131 border: none !important;
4132 }
4132 }
4133
4133
4134 div.readme .readme_box pre {
4134 div.readme .readme_box pre {
4135 margin: 1em 0;
4135 margin: 1em 0;
4136 font-size: 12px;
4136 font-size: 12px;
4137 background-color: #eee;
4137 background-color: #eee;
4138 border: 1px solid #ddd;
4138 border: 1px solid #ddd;
4139 padding: 5px;
4139 padding: 5px;
4140 color: #444;
4140 color: #444;
4141 overflow: auto;
4141 overflow: auto;
4142 -webkit-box-shadow: rgba(0,0,0,0.07) 0 1px 2px inset;
4142 -webkit-box-shadow: rgba(0,0,0,0.07) 0 1px 2px inset;
4143 -webkit-border-radius: 3px;
4143 -webkit-border-radius: 3px;
4144 -moz-border-radius: 3px;
4144 -moz-border-radius: 3px;
4145 border-radius: 3px;
4145 border-radius: 3px;
4146 }
4146 }
4147
4147
4148 div.readme .readme_box table {
4148 div.readme .readme_box table {
4149 display: table;
4149 display: table;
4150 border-collapse: separate;
4150 border-collapse: separate;
4151 border-spacing: 2px;
4151 border-spacing: 2px;
4152 border-color: gray;
4152 border-color: gray;
4153 width: auto !important;
4153 width: auto !important;
4154 }
4154 }
4155
4155
4156
4156
4157 /** RST STYLE **/
4157 /** RST STYLE **/
4158
4158
4159
4159
4160 div.rst-block {
4160 div.rst-block {
4161 padding:0px;
4161 padding:0px;
4162 }
4162 }
4163
4163
4164 div.rst-block h2 {
4164 div.rst-block h2 {
4165 font-weight: normal;
4165 font-weight: normal;
4166 }
4166 }
4167
4167
4168 div.rst-block {
4168 div.rst-block {
4169 background-color: #fafafa;
4169 background-color: #fafafa;
4170 }
4170 }
4171
4171
4172 div.rst-block {
4172 div.rst-block {
4173 clear:both;
4173 clear:both;
4174 overflow:hidden;
4174 overflow:hidden;
4175 margin:0;
4175 margin:0;
4176 padding:0 20px 10px;
4176 padding:0 20px 10px;
4177 }
4177 }
4178
4178
4179 div.rst-block h1, div.rst-block h2, div.rst-block h3, div.rst-block h4, div.rst-block h5, div.rst-block h6 {
4179 div.rst-block h1, div.rst-block h2, div.rst-block h3, div.rst-block h4, div.rst-block h5, div.rst-block h6 {
4180 border-bottom: 0 !important;
4180 border-bottom: 0 !important;
4181 margin: 0 !important;
4181 margin: 0 !important;
4182 padding: 0 !important;
4182 padding: 0 !important;
4183 line-height: 1.5em !important;
4183 line-height: 1.5em !important;
4184 }
4184 }
4185
4185
4186
4186
4187 div.rst-block h1:first-child {
4187 div.rst-block h1:first-child {
4188 padding-top: .25em !important;
4188 padding-top: .25em !important;
4189 }
4189 }
4190
4190
4191 div.rst-block h2, div.rst-block h3 {
4191 div.rst-block h2, div.rst-block h3 {
4192 margin: 1em 0 !important;
4192 margin: 1em 0 !important;
4193 }
4193 }
4194
4194
4195 div.rst-block h2 {
4195 div.rst-block h2 {
4196 margin-top: 1.5em !important;
4196 margin-top: 1.5em !important;
4197 border-top: 4px solid #e0e0e0 !important;
4197 border-top: 4px solid #e0e0e0 !important;
4198 padding-top: .5em !important;
4198 padding-top: .5em !important;
4199 }
4199 }
4200
4200
4201 div.rst-block p {
4201 div.rst-block p {
4202 color: black !important;
4202 color: black !important;
4203 margin: 1em 0 !important;
4203 margin: 1em 0 !important;
4204 line-height: 1.5em !important;
4204 line-height: 1.5em !important;
4205 }
4205 }
4206
4206
4207 div.rst-block ul {
4207 div.rst-block ul {
4208 list-style: disc !important;
4208 list-style: disc !important;
4209 margin: 1em 0 1em 2em !important;
4209 margin: 1em 0 1em 2em !important;
4210 }
4210 }
4211
4211
4212 div.rst-block ol {
4212 div.rst-block ol {
4213 list-style: decimal;
4213 list-style: decimal;
4214 margin: 1em 0 1em 2em !important;
4214 margin: 1em 0 1em 2em !important;
4215 }
4215 }
4216
4216
4217 div.rst-block pre, code {
4217 div.rst-block pre, code {
4218 font: 12px "Bitstream Vera Sans Mono","Courier",monospace;
4218 font: 12px "Bitstream Vera Sans Mono","Courier",monospace;
4219 }
4219 }
4220
4220
4221 div.rst-block code {
4221 div.rst-block code {
4222 font-size: 12px !important;
4222 font-size: 12px !important;
4223 background-color: ghostWhite !important;
4223 background-color: ghostWhite !important;
4224 color: #444 !important;
4224 color: #444 !important;
4225 padding: 0 .2em !important;
4225 padding: 0 .2em !important;
4226 border: 1px solid #dedede !important;
4226 border: 1px solid #dedede !important;
4227 }
4227 }
4228
4228
4229 div.rst-block pre code {
4229 div.rst-block pre code {
4230 padding: 0 !important;
4230 padding: 0 !important;
4231 font-size: 12px !important;
4231 font-size: 12px !important;
4232 background-color: #eee !important;
4232 background-color: #eee !important;
4233 border: none !important;
4233 border: none !important;
4234 }
4234 }
4235
4235
4236 div.rst-block pre {
4236 div.rst-block pre {
4237 margin: 1em 0;
4237 margin: 1em 0;
4238 font-size: 12px;
4238 font-size: 12px;
4239 background-color: #eee;
4239 background-color: #eee;
4240 border: 1px solid #ddd;
4240 border: 1px solid #ddd;
4241 padding: 5px;
4241 padding: 5px;
4242 color: #444;
4242 color: #444;
4243 overflow: auto;
4243 overflow: auto;
4244 -webkit-box-shadow: rgba(0,0,0,0.07) 0 1px 2px inset;
4244 -webkit-box-shadow: rgba(0,0,0,0.07) 0 1px 2px inset;
4245 -webkit-border-radius: 3px;
4245 -webkit-border-radius: 3px;
4246 -moz-border-radius: 3px;
4246 -moz-border-radius: 3px;
4247 border-radius: 3px;
4247 border-radius: 3px;
4248 }
4248 }
4249
4249
4250
4250
4251 /** comment main **/
4251 /** comment main **/
4252 .comments {
4252 .comments {
4253 padding:10px 20px;
4253 padding:10px 20px;
4254 }
4254 }
4255
4255
4256 .comments .comment {
4256 .comments .comment {
4257 border: 1px solid #ddd;
4257 border: 1px solid #ddd;
4258 margin-top: 10px;
4258 margin-top: 10px;
4259 -webkit-border-radius: 4px;
4259 -webkit-border-radius: 4px;
4260 -moz-border-radius: 4px;
4260 -moz-border-radius: 4px;
4261 border-radius: 4px;
4261 border-radius: 4px;
4262 }
4262 }
4263
4263
4264 .comments .comment .meta {
4264 .comments .comment .meta {
4265 background: #f8f8f8;
4265 background: #f8f8f8;
4266 padding: 4px;
4266 padding: 4px;
4267 border-bottom: 1px solid #ddd;
4267 border-bottom: 1px solid #ddd;
4268 height: 18px;
4268 height: 18px;
4269 }
4269 }
4270
4270
4271 .comments .comment .meta img {
4271 .comments .comment .meta img {
4272 vertical-align: middle;
4272 vertical-align: middle;
4273 }
4273 }
4274
4274
4275 .comments .comment .meta .user {
4275 .comments .comment .meta .user {
4276 font-weight: bold;
4276 font-weight: bold;
4277 float: left;
4277 float: left;
4278 padding: 4px 2px 2px 2px;
4278 padding: 4px 2px 2px 2px;
4279 }
4279 }
4280
4280
4281 .comments .comment .meta .date {
4281 .comments .comment .meta .date {
4282 float: left;
4282 float: left;
4283 padding:4px 4px 0px 4px;
4283 padding:4px 4px 0px 4px;
4284 }
4284 }
4285
4285
4286 .comments .comment .text {
4286 .comments .comment .text {
4287 background-color: #FAFAFA;
4287 background-color: #FAFAFA;
4288 }
4288 }
4289 .comment .text div.rst-block p {
4289 .comment .text div.rst-block p {
4290 margin: 0.5em 0px !important;
4290 margin: 0.5em 0px !important;
4291 }
4291 }
4292
4292
4293 .comments .comments-number{
4293 .comments .comments-number{
4294 padding:0px 0px 10px 0px;
4294 padding:0px 0px 10px 0px;
4295 font-weight: bold;
4295 font-weight: bold;
4296 color: #666;
4296 color: #666;
4297 font-size: 16px;
4297 font-size: 16px;
4298 }
4298 }
4299
4299
4300 /** comment form **/
4300 /** comment form **/
4301
4301
4302 .status-block{
4302 .status-block{
4303 height:80px;
4303 height:80px;
4304 clear:both
4304 clear:both
4305 }
4305 }
4306
4306
4307 .comment-form .clearfix{
4307 .comment-form .clearfix{
4308 background: #EEE;
4308 background: #EEE;
4309 -webkit-border-radius: 4px;
4309 -webkit-border-radius: 4px;
4310 -moz-border-radius: 4px;
4310 -moz-border-radius: 4px;
4311 border-radius: 4px;
4311 border-radius: 4px;
4312 padding: 10px;
4312 padding: 10px;
4313 }
4313 }
4314
4314
4315 div.comment-form {
4315 div.comment-form {
4316 margin-top: 20px;
4316 margin-top: 20px;
4317 }
4317 }
4318
4318
4319 .comment-form strong {
4319 .comment-form strong {
4320 display: block;
4320 display: block;
4321 margin-bottom: 15px;
4321 margin-bottom: 15px;
4322 }
4322 }
4323
4323
4324 .comment-form textarea {
4324 .comment-form textarea {
4325 width: 100%;
4325 width: 100%;
4326 height: 100px;
4326 height: 100px;
4327 font-family: 'Monaco', 'Courier', 'Courier New', monospace;
4327 font-family: 'Monaco', 'Courier', 'Courier New', monospace;
4328 }
4328 }
4329
4329
4330 form.comment-form {
4330 form.comment-form {
4331 margin-top: 10px;
4331 margin-top: 10px;
4332 margin-left: 10px;
4332 margin-left: 10px;
4333 }
4333 }
4334
4334
4335 .comment-form-submit {
4335 .comment-form-submit {
4336 margin-top: 5px;
4336 margin-top: 5px;
4337 margin-left: 525px;
4337 margin-left: 525px;
4338 }
4338 }
4339
4339
4340 .file-comments {
4340 .file-comments {
4341 display: none;
4341 display: none;
4342 }
4342 }
4343
4343
4344 .comment-form .comment {
4344 .comment-form .comment {
4345 margin-left: 10px;
4345 margin-left: 10px;
4346 }
4346 }
4347
4347
4348 .comment-form .comment-help{
4348 .comment-form .comment-help{
4349 padding: 0px 0px 5px 0px;
4349 padding: 0px 0px 5px 0px;
4350 color: #666;
4350 color: #666;
4351 }
4351 }
4352
4352
4353 .comment-form .comment-button{
4353 .comment-form .comment-button{
4354 padding-top:5px;
4354 padding-top:5px;
4355 }
4355 }
4356
4356
4357 .add-another-button {
4357 .add-another-button {
4358 margin-left: 10px;
4358 margin-left: 10px;
4359 margin-top: 10px;
4359 margin-top: 10px;
4360 margin-bottom: 10px;
4360 margin-bottom: 10px;
4361 }
4361 }
4362
4362
4363 .comment .buttons {
4363 .comment .buttons {
4364 float: right;
4364 float: right;
4365 padding:2px 2px 0px 0px;
4365 padding:2px 2px 0px 0px;
4366 }
4366 }
4367
4367
4368
4368
4369 .show-inline-comments{
4369 .show-inline-comments{
4370 position: relative;
4370 position: relative;
4371 top:1px
4371 top:1px
4372 }
4372 }
4373
4373
4374 /** comment inline form **/
4374 /** comment inline form **/
4375 .comment-inline-form .overlay{
4375 .comment-inline-form .overlay{
4376 display: none;
4376 display: none;
4377 }
4377 }
4378 .comment-inline-form .overlay.submitting{
4378 .comment-inline-form .overlay.submitting{
4379 display:block;
4379 display:block;
4380 background: none repeat scroll 0 0 white;
4380 background: none repeat scroll 0 0 white;
4381 font-size: 16px;
4381 font-size: 16px;
4382 opacity: 0.5;
4382 opacity: 0.5;
4383 position: absolute;
4383 position: absolute;
4384 text-align: center;
4384 text-align: center;
4385 vertical-align: top;
4385 vertical-align: top;
4386
4386
4387 }
4387 }
4388 .comment-inline-form .overlay.submitting .overlay-text{
4388 .comment-inline-form .overlay.submitting .overlay-text{
4389 width:100%;
4389 width:100%;
4390 margin-top:5%;
4390 margin-top:5%;
4391 }
4391 }
4392
4392
4393 .comment-inline-form .clearfix{
4393 .comment-inline-form .clearfix{
4394 background: #EEE;
4394 background: #EEE;
4395 -webkit-border-radius: 4px;
4395 -webkit-border-radius: 4px;
4396 -moz-border-radius: 4px;
4396 -moz-border-radius: 4px;
4397 border-radius: 4px;
4397 border-radius: 4px;
4398 padding: 5px;
4398 padding: 5px;
4399 }
4399 }
4400
4400
4401 div.comment-inline-form {
4401 div.comment-inline-form {
4402 padding:4px 0px 6px 0px;
4402 padding:4px 0px 6px 0px;
4403 }
4403 }
4404
4404
4405
4405
4406 tr.hl-comment{
4406 tr.hl-comment{
4407 /*
4407 /*
4408 background-color: #FFFFCC !important;
4408 background-color: #FFFFCC !important;
4409 */
4409 */
4410 }
4410 }
4411
4411
4412 /*
4412 /*
4413 tr.hl-comment pre {
4413 tr.hl-comment pre {
4414 border-top: 2px solid #FFEE33;
4414 border-top: 2px solid #FFEE33;
4415 border-left: 2px solid #FFEE33;
4415 border-left: 2px solid #FFEE33;
4416 border-right: 2px solid #FFEE33;
4416 border-right: 2px solid #FFEE33;
4417 }
4417 }
4418 */
4418 */
4419
4419
4420 .comment-inline-form strong {
4420 .comment-inline-form strong {
4421 display: block;
4421 display: block;
4422 margin-bottom: 15px;
4422 margin-bottom: 15px;
4423 }
4423 }
4424
4424
4425 .comment-inline-form textarea {
4425 .comment-inline-form textarea {
4426 width: 100%;
4426 width: 100%;
4427 height: 100px;
4427 height: 100px;
4428 font-family: 'Monaco', 'Courier', 'Courier New', monospace;
4428 font-family: 'Monaco', 'Courier', 'Courier New', monospace;
4429 }
4429 }
4430
4430
4431 form.comment-inline-form {
4431 form.comment-inline-form {
4432 margin-top: 10px;
4432 margin-top: 10px;
4433 margin-left: 10px;
4433 margin-left: 10px;
4434 }
4434 }
4435
4435
4436 .comment-inline-form-submit {
4436 .comment-inline-form-submit {
4437 margin-top: 5px;
4437 margin-top: 5px;
4438 margin-left: 525px;
4438 margin-left: 525px;
4439 }
4439 }
4440
4440
4441 .file-comments {
4441 .file-comments {
4442 display: none;
4442 display: none;
4443 }
4443 }
4444
4444
4445 .comment-inline-form .comment {
4445 .comment-inline-form .comment {
4446 margin-left: 10px;
4446 margin-left: 10px;
4447 }
4447 }
4448
4448
4449 .comment-inline-form .comment-help{
4449 .comment-inline-form .comment-help{
4450 padding: 0px 0px 2px 0px;
4450 padding: 0px 0px 2px 0px;
4451 color: #666666;
4451 color: #666666;
4452 font-size: 10px;
4452 font-size: 10px;
4453 }
4453 }
4454
4454
4455 .comment-inline-form .comment-button{
4455 .comment-inline-form .comment-button{
4456 padding-top:5px;
4456 padding-top:5px;
4457 }
4457 }
4458
4458
4459 /** comment inline **/
4459 /** comment inline **/
4460 .inline-comments {
4460 .inline-comments {
4461 padding:10px 20px;
4461 padding:10px 20px;
4462 }
4462 }
4463
4463
4464 .inline-comments div.rst-block {
4464 .inline-comments div.rst-block {
4465 clear:both;
4465 clear:both;
4466 overflow:hidden;
4466 overflow:hidden;
4467 margin:0;
4467 margin:0;
4468 padding:0 20px 0px;
4468 padding:0 20px 0px;
4469 }
4469 }
4470 .inline-comments .comment {
4470 .inline-comments .comment {
4471 border: 1px solid #ddd;
4471 border: 1px solid #ddd;
4472 -webkit-border-radius: 4px;
4472 -webkit-border-radius: 4px;
4473 -moz-border-radius: 4px;
4473 -moz-border-radius: 4px;
4474 border-radius: 4px;
4474 border-radius: 4px;
4475 margin: 3px 3px 5px 5px;
4475 margin: 3px 3px 5px 5px;
4476 background-color: #FAFAFA;
4476 background-color: #FAFAFA;
4477 }
4477 }
4478 .inline-comments .add-comment {
4478 .inline-comments .add-comment {
4479 padding: 2px 4px 8px 5px;
4479 padding: 2px 4px 8px 5px;
4480 }
4480 }
4481
4481
4482 .inline-comments .comment-wrapp{
4482 .inline-comments .comment-wrapp{
4483 padding:1px;
4483 padding:1px;
4484 }
4484 }
4485 .inline-comments .comment .meta {
4485 .inline-comments .comment .meta {
4486 background: #f8f8f8;
4486 background: #f8f8f8;
4487 padding: 4px;
4487 padding: 4px;
4488 border-bottom: 1px solid #ddd;
4488 border-bottom: 1px solid #ddd;
4489 height: 20px;
4489 height: 20px;
4490 }
4490 }
4491
4491
4492 .inline-comments .comment .meta img {
4492 .inline-comments .comment .meta img {
4493 vertical-align: middle;
4493 vertical-align: middle;
4494 }
4494 }
4495
4495
4496 .inline-comments .comment .meta .user {
4496 .inline-comments .comment .meta .user {
4497 font-weight: bold;
4497 font-weight: bold;
4498 float:left;
4498 float:left;
4499 padding: 3px;
4499 padding: 3px;
4500 }
4500 }
4501
4501
4502 .inline-comments .comment .meta .date {
4502 .inline-comments .comment .meta .date {
4503 float:left;
4503 float:left;
4504 padding: 3px;
4504 padding: 3px;
4505 }
4505 }
4506
4506
4507 .inline-comments .comment .text {
4507 .inline-comments .comment .text {
4508 background-color: #FAFAFA;
4508 background-color: #FAFAFA;
4509 }
4509 }
4510
4510
4511 .inline-comments .comments-number{
4511 .inline-comments .comments-number{
4512 padding:0px 0px 10px 0px;
4512 padding:0px 0px 10px 0px;
4513 font-weight: bold;
4513 font-weight: bold;
4514 color: #666;
4514 color: #666;
4515 font-size: 16px;
4515 font-size: 16px;
4516 }
4516 }
4517 .inline-comments-button .add-comment{
4517 .inline-comments-button .add-comment{
4518 margin:2px 0px 8px 5px !important
4518 margin:2px 0px 8px 5px !important
4519 }
4519 }
4520
4520
4521
4521
4522 .notification-paginator{
4522 .notification-paginator{
4523 padding: 0px 0px 4px 16px;
4523 padding: 0px 0px 4px 16px;
4524 float: left;
4524 float: left;
4525 }
4525 }
4526
4526
4527 .notifications{
4527 .notifications{
4528 border-radius: 4px 4px 4px 4px;
4528 border-radius: 4px 4px 4px 4px;
4529 -webkit-border-radius: 4px;
4529 -webkit-border-radius: 4px;
4530 -moz-border-radius: 4px;
4530 -moz-border-radius: 4px;
4531 float: right;
4531 float: right;
4532 margin: 20px 0px 0px 0px;
4532 margin: 20px 0px 0px 0px;
4533 position: absolute;
4533 position: absolute;
4534 text-align: center;
4534 text-align: center;
4535 width: 26px;
4535 width: 26px;
4536 z-index: 1000;
4536 z-index: 1000;
4537 }
4537 }
4538 .notifications a{
4538 .notifications a{
4539 color:#888 !important;
4539 color:#888 !important;
4540 display: block;
4540 display: block;
4541 font-size: 10px;
4541 font-size: 10px;
4542 background-color: #DEDEDE !important;
4542 background-color: #DEDEDE !important;
4543 border-radius: 2px !important;
4543 border-radius: 2px !important;
4544 -webkit-border-radius: 2px !important;
4544 -webkit-border-radius: 2px !important;
4545 -moz-border-radius: 2px !important;
4545 -moz-border-radius: 2px !important;
4546 }
4546 }
4547 .notifications a:hover{
4547 .notifications a:hover{
4548 text-decoration: none !important;
4548 text-decoration: none !important;
4549 background-color: #EEEFFF !important;
4549 background-color: #EEEFFF !important;
4550 }
4550 }
4551 .notification-header{
4551 .notification-header{
4552 padding-top:6px;
4552 padding-top:6px;
4553 }
4553 }
4554 .notification-header .desc{
4554 .notification-header .desc{
4555 font-size: 16px;
4555 font-size: 16px;
4556 height: 24px;
4556 height: 24px;
4557 float: left
4557 float: left
4558 }
4558 }
4559 .notification-list .container.unread{
4559 .notification-list .container.unread{
4560 background: none repeat scroll 0 0 rgba(255, 255, 180, 0.6);
4560 background: none repeat scroll 0 0 rgba(255, 255, 180, 0.6);
4561 }
4561 }
4562 .notification-header .gravatar{
4562 .notification-header .gravatar{
4563 background: none repeat scroll 0 0 transparent;
4563 background: none repeat scroll 0 0 transparent;
4564 padding: 0px 0px 0px 8px;
4564 padding: 0px 0px 0px 8px;
4565 }
4565 }
4566 .notification-list .container .notification-header .desc{
4566 .notification-list .container .notification-header .desc{
4567 font-weight: bold;
4567 font-weight: bold;
4568 font-size: 17px;
4568 font-size: 17px;
4569 }
4569 }
4570 .notification-table{
4570 .notification-table{
4571 border: 1px solid #ccc;
4571 border: 1px solid #ccc;
4572 -webkit-border-radius: 6px 6px 6px 6px;
4572 -webkit-border-radius: 6px 6px 6px 6px;
4573 -moz-border-radius: 6px 6px 6px 6px;
4573 -moz-border-radius: 6px 6px 6px 6px;
4574 border-radius: 6px 6px 6px 6px;
4574 border-radius: 6px 6px 6px 6px;
4575 clear: both;
4575 clear: both;
4576 margin: 0px 20px 0px 20px;
4576 margin: 0px 20px 0px 20px;
4577 }
4577 }
4578 .notification-header .delete-notifications{
4578 .notification-header .delete-notifications{
4579 float: right;
4579 float: right;
4580 padding-top: 8px;
4580 padding-top: 8px;
4581 cursor: pointer;
4581 cursor: pointer;
4582 }
4582 }
4583 .notification-header .read-notifications{
4583 .notification-header .read-notifications{
4584 float: right;
4584 float: right;
4585 padding-top: 8px;
4585 padding-top: 8px;
4586 cursor: pointer;
4586 cursor: pointer;
4587 }
4587 }
4588 .notification-subject{
4588 .notification-subject{
4589 clear:both;
4589 clear:both;
4590 border-bottom: 1px solid #eee;
4590 border-bottom: 1px solid #eee;
4591 padding:5px 0px 5px 38px;
4591 padding:5px 0px 5px 38px;
4592 }
4592 }
4593
4593
4594 .notification-body{
4594 .notification-body{
4595 clear:both;
4595 clear:both;
4596 margin: 34px 2px 2px 8px
4596 margin: 34px 2px 2px 8px
4597 }
4597 }
4598
4598
4599 /****
4599 /****
4600 PULL REQUESTS
4600 PULL REQUESTS
4601 *****/
4601 *****/
4602 .pullrequests_section_head {
4602 .pullrequests_section_head {
4603 padding:10px 10px 10px 0px;
4603 padding:10px 10px 10px 0px;
4604 font-size:16px;
4604 font-size:16px;
4605 font-weight: bold;
4605 font-weight: bold;
4606 }
4606 }
4607
4607
4608 /****
4608 /****
4609 PERMS
4609 PERMS
4610 *****/
4610 *****/
4611 #perms .perms_section_head {
4611 #perms .perms_section_head {
4612 padding:10px 10px 10px 0px;
4612 padding:10px 10px 10px 0px;
4613 font-size:16px;
4613 font-size:16px;
4614 font-weight: bold;
4614 font-weight: bold;
4615 }
4615 }
4616
4616
4617 #perms .perm_tag{
4617 #perms .perm_tag{
4618 padding: 1px 3px 1px 3px;
4618 padding: 1px 3px 1px 3px;
4619 font-size: 10px;
4619 font-size: 10px;
4620 font-weight: bold;
4620 font-weight: bold;
4621 text-transform: uppercase;
4621 text-transform: uppercase;
4622 white-space: nowrap;
4622 white-space: nowrap;
4623 -webkit-border-radius: 3px;
4623 -webkit-border-radius: 3px;
4624 -moz-border-radius: 3px;
4624 -moz-border-radius: 3px;
4625 border-radius: 3px;
4625 border-radius: 3px;
4626 }
4626 }
4627
4627
4628 #perms .perm_tag.admin{
4628 #perms .perm_tag.admin{
4629 background-color: #B94A48;
4629 background-color: #B94A48;
4630 color: #ffffff;
4630 color: #ffffff;
4631 }
4631 }
4632
4632
4633 #perms .perm_tag.write{
4633 #perms .perm_tag.write{
4634 background-color: #B94A48;
4634 background-color: #B94A48;
4635 color: #ffffff;
4635 color: #ffffff;
4636 }
4636 }
4637
4637
4638 #perms .perm_tag.read{
4638 #perms .perm_tag.read{
4639 background-color: #468847;
4639 background-color: #468847;
4640 color: #ffffff;
4640 color: #ffffff;
4641 }
4641 }
4642
4642
4643 #perms .perm_tag.none{
4643 #perms .perm_tag.none{
4644 background-color: #bfbfbf;
4644 background-color: #bfbfbf;
4645 color: #ffffff;
4645 color: #ffffff;
4646 }
4646 }
4647
4647
4648 .perm-gravatar{
4648 .perm-gravatar{
4649 vertical-align:middle;
4649 vertical-align:middle;
4650 padding:2px;
4650 padding:2px;
4651 }
4651 }
4652 .perm-gravatar-ac{
4652 .perm-gravatar-ac{
4653 vertical-align:middle;
4653 vertical-align:middle;
4654 padding:2px;
4654 padding:2px;
4655 width: 14px;
4655 width: 14px;
4656 height: 14px;
4656 height: 14px;
4657 }
4657 }
4658
4658
4659 /*****************************************************************************
4659 /*****************************************************************************
4660 DIFFS CSS
4660 DIFFS CSS
4661 ******************************************************************************/
4661 ******************************************************************************/
4662
4662
4663 div.diffblock {
4663 div.diffblock {
4664 overflow: auto;
4664 overflow: auto;
4665 padding: 0px;
4665 padding: 0px;
4666 border: 1px solid #ccc;
4666 border: 1px solid #ccc;
4667 background: #f8f8f8;
4667 background: #f8f8f8;
4668 font-size: 100%;
4668 font-size: 100%;
4669 line-height: 100%;
4669 line-height: 100%;
4670 /* new */
4670 /* new */
4671 line-height: 125%;
4671 line-height: 125%;
4672 -webkit-border-radius: 6px 6px 0px 0px;
4672 -webkit-border-radius: 6px 6px 0px 0px;
4673 -moz-border-radius: 6px 6px 0px 0px;
4673 -moz-border-radius: 6px 6px 0px 0px;
4674 border-radius: 6px 6px 0px 0px;
4674 border-radius: 6px 6px 0px 0px;
4675 }
4675 }
4676 div.diffblock.margined{
4676 div.diffblock.margined{
4677 margin: 0px 20px 0px 20px;
4677 margin: 0px 20px 0px 20px;
4678 }
4678 }
4679 div.diffblock .code-header{
4679 div.diffblock .code-header{
4680 border-bottom: 1px solid #CCCCCC;
4680 border-bottom: 1px solid #CCCCCC;
4681 background: #EEEEEE;
4681 background: #EEEEEE;
4682 padding:10px 0 10px 0;
4682 padding:10px 0 10px 0;
4683 height: 14px;
4683 height: 14px;
4684 }
4684 }
4685
4685
4686 div.diffblock .code-header.banner{
4686 div.diffblock .code-header.banner{
4687 border-bottom: 1px solid #CCCCCC;
4687 border-bottom: 1px solid #CCCCCC;
4688 background: #EEEEEE;
4688 background: #EEEEEE;
4689 height: 14px;
4689 height: 14px;
4690 margin: 0px 95px 0px 95px;
4690 margin: 0px 95px 0px 95px;
4691 padding: 3px 3px 11px 3px;
4691 padding: 3px 3px 11px 3px;
4692 }
4692 }
4693
4693
4694 div.diffblock .code-header.cv{
4694 div.diffblock .code-header.cv{
4695 height: 34px;
4695 height: 34px;
4696 }
4696 }
4697 div.diffblock .code-header-title{
4697 div.diffblock .code-header-title{
4698 padding: 0px 0px 10px 5px !important;
4698 padding: 0px 0px 10px 5px !important;
4699 margin: 0 !important;
4699 margin: 0 !important;
4700 }
4700 }
4701 div.diffblock .code-header .hash{
4701 div.diffblock .code-header .hash{
4702 float: left;
4702 float: left;
4703 padding: 2px 0 0 2px;
4703 padding: 2px 0 0 2px;
4704 }
4704 }
4705 div.diffblock .code-header .date{
4705 div.diffblock .code-header .date{
4706 float:left;
4706 float:left;
4707 text-transform: uppercase;
4707 text-transform: uppercase;
4708 padding: 2px 0px 0px 2px;
4708 padding: 2px 0px 0px 2px;
4709 }
4709 }
4710 div.diffblock .code-header div{
4710 div.diffblock .code-header div{
4711 margin-left:4px;
4711 margin-left:4px;
4712 font-weight: bold;
4712 font-weight: bold;
4713 font-size: 14px;
4713 font-size: 14px;
4714 }
4714 }
4715
4715
4716 div.diffblock .parents {
4716 div.diffblock .parents {
4717 float: left;
4717 float: left;
4718 height: 26px;
4718 height: 26px;
4719 width:100px;
4719 width:100px;
4720 font-size: 10px;
4720 font-size: 10px;
4721 font-weight: 400;
4721 font-weight: 400;
4722 vertical-align: middle;
4722 vertical-align: middle;
4723 padding: 0px 2px 2px 2px;
4723 padding: 0px 2px 2px 2px;
4724 background-color:#eeeeee;
4724 background-color:#eeeeee;
4725 border-bottom: 1px solid #CCCCCC;
4725 border-bottom: 1px solid #CCCCCC;
4726 }
4726 }
4727
4727
4728 div.diffblock .children {
4728 div.diffblock .children {
4729 float: right;
4729 float: right;
4730 height: 26px;
4730 height: 26px;
4731 width:100px;
4731 width:100px;
4732 font-size: 10px;
4732 font-size: 10px;
4733 font-weight: 400;
4733 font-weight: 400;
4734 vertical-align: middle;
4734 vertical-align: middle;
4735 text-align: right;
4735 text-align: right;
4736 padding: 0px 2px 2px 2px;
4736 padding: 0px 2px 2px 2px;
4737 background-color:#eeeeee;
4737 background-color:#eeeeee;
4738 border-bottom: 1px solid #CCCCCC;
4738 border-bottom: 1px solid #CCCCCC;
4739 }
4739 }
4740
4740
4741 div.diffblock .code-body{
4741 div.diffblock .code-body{
4742 background: #FFFFFF;
4742 background: #FFFFFF;
4743 }
4743 }
4744 div.diffblock pre.raw{
4744 div.diffblock pre.raw{
4745 background: #FFFFFF;
4745 background: #FFFFFF;
4746 color:#000000;
4746 color:#000000;
4747 }
4747 }
4748 table.code-difftable{
4748 table.code-difftable{
4749 border-collapse: collapse;
4749 border-collapse: collapse;
4750 width: 99%;
4750 width: 99%;
4751 }
4751 }
4752 table.code-difftable td {
4752 table.code-difftable td {
4753 padding: 0 !important;
4753 padding: 0 !important;
4754 background: none !important;
4754 background: none !important;
4755 border:0 !important;
4755 border:0 !important;
4756 vertical-align: none !important;
4756 vertical-align: none !important;
4757 }
4757 }
4758 table.code-difftable .context{
4758 table.code-difftable .context{
4759 background:none repeat scroll 0 0 #DDE7EF;
4759 background:none repeat scroll 0 0 #DDE7EF;
4760 }
4760 }
4761 table.code-difftable .add{
4761 table.code-difftable .add{
4762 background:none repeat scroll 0 0 #DDFFDD;
4762 background:none repeat scroll 0 0 #DDFFDD;
4763 }
4763 }
4764 table.code-difftable .add ins{
4764 table.code-difftable .add ins{
4765 background:none repeat scroll 0 0 #AAFFAA;
4765 background:none repeat scroll 0 0 #AAFFAA;
4766 text-decoration:none;
4766 text-decoration:none;
4767 }
4767 }
4768 table.code-difftable .del{
4768 table.code-difftable .del{
4769 background:none repeat scroll 0 0 #FFDDDD;
4769 background:none repeat scroll 0 0 #FFDDDD;
4770 }
4770 }
4771 table.code-difftable .del del{
4771 table.code-difftable .del del{
4772 background:none repeat scroll 0 0 #FFAAAA;
4772 background:none repeat scroll 0 0 #FFAAAA;
4773 text-decoration:none;
4773 text-decoration:none;
4774 }
4774 }
4775
4775
4776 /** LINE NUMBERS **/
4776 /** LINE NUMBERS **/
4777 table.code-difftable .lineno{
4777 table.code-difftable .lineno{
4778
4778
4779 padding-left:2px;
4779 padding-left:2px;
4780 padding-right:2px;
4780 padding-right:2px;
4781 text-align:right;
4781 text-align:right;
4782 width:32px;
4782 width:32px;
4783 -moz-user-select:none;
4783 -moz-user-select:none;
4784 -webkit-user-select: none;
4784 -webkit-user-select: none;
4785 border-right: 1px solid #CCC !important;
4785 border-right: 1px solid #CCC !important;
4786 border-left: 0px solid #CCC !important;
4786 border-left: 0px solid #CCC !important;
4787 border-top: 0px solid #CCC !important;
4787 border-top: 0px solid #CCC !important;
4788 border-bottom: none !important;
4788 border-bottom: none !important;
4789 vertical-align: middle !important;
4789 vertical-align: middle !important;
4790
4790
4791 }
4791 }
4792 table.code-difftable .lineno.new {
4792 table.code-difftable .lineno.new {
4793 }
4793 }
4794 table.code-difftable .lineno.old {
4794 table.code-difftable .lineno.old {
4795 }
4795 }
4796 table.code-difftable .lineno a{
4796 table.code-difftable .lineno a{
4797 color:#747474 !important;
4797 color:#747474 !important;
4798 font:11px "Bitstream Vera Sans Mono",Monaco,"Courier New",Courier,monospace !important;
4798 font:11px "Bitstream Vera Sans Mono",Monaco,"Courier New",Courier,monospace !important;
4799 letter-spacing:-1px;
4799 letter-spacing:-1px;
4800 text-align:right;
4800 text-align:right;
4801 padding-right: 2px;
4801 padding-right: 2px;
4802 cursor: pointer;
4802 cursor: pointer;
4803 display: block;
4803 display: block;
4804 width: 32px;
4804 width: 32px;
4805 }
4805 }
4806
4806
4807 table.code-difftable .lineno-inline{
4807 table.code-difftable .lineno-inline{
4808 background:none repeat scroll 0 0 #FFF !important;
4808 background:none repeat scroll 0 0 #FFF !important;
4809 padding-left:2px;
4809 padding-left:2px;
4810 padding-right:2px;
4810 padding-right:2px;
4811 text-align:right;
4811 text-align:right;
4812 width:30px;
4812 width:30px;
4813 -moz-user-select:none;
4813 -moz-user-select:none;
4814 -webkit-user-select: none;
4814 -webkit-user-select: none;
4815 }
4815 }
4816
4816
4817 /** CODE **/
4817 /** CODE **/
4818 table.code-difftable .code {
4818 table.code-difftable .code {
4819 display: block;
4819 display: block;
4820 width: 100%;
4820 width: 100%;
4821 }
4821 }
4822 table.code-difftable .code td{
4822 table.code-difftable .code td{
4823 margin:0;
4823 margin:0;
4824 padding:0;
4824 padding:0;
4825 }
4825 }
4826 table.code-difftable .code pre{
4826 table.code-difftable .code pre{
4827 margin:0;
4827 margin:0;
4828 padding:0;
4828 padding:0;
4829 height: 17px;
4829 height: 17px;
4830 line-height: 17px;
4830 line-height: 17px;
4831 }
4831 }
4832
4832
4833
4833
4834 .diffblock.margined.comm .line .code:hover{
4834 .diffblock.margined.comm .line .code:hover{
4835 background-color:#FFFFCC !important;
4835 background-color:#FFFFCC !important;
4836 cursor: pointer !important;
4836 cursor: pointer !important;
4837 background-image:url("../images/icons/comment_add.png") !important;
4837 background-image:url("../images/icons/comment_add.png") !important;
4838 background-repeat:no-repeat !important;
4838 background-repeat:no-repeat !important;
4839 background-position: right !important;
4839 background-position: right !important;
4840 background-position: 0% 50% !important;
4840 background-position: 0% 50% !important;
4841 }
4841 }
4842 .diffblock.margined.comm .line .code.no-comment:hover{
4842 .diffblock.margined.comm .line .code.no-comment:hover{
4843 background-image: none !important;
4843 background-image: none !important;
4844 cursor: auto !important;
4844 cursor: auto !important;
4845 background-color: inherit !important;
4845 background-color: inherit !important;
4846
4846
4847 }
4847 }
@@ -1,135 +1,142 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%inherit file="/base/base.html"/>
2 <%inherit file="/base/base.html"/>
3
3
4 <%def name="title()">
4 <%def name="title()">
5 ${_('Repositories administration')} - ${c.rhodecode_name}
5 ${_('Repositories administration')} - ${c.rhodecode_name}
6 </%def>
6 </%def>
7
7
8 <%def name="breadcrumbs_links()">
8 <%def name="breadcrumbs_links()">
9 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" value="${_('quick filter...')}"/> ${h.link_to(_('Admin'),h.url('admin_home'))} &raquo; <span id="repo_count">0</span> ${_('repositories')}
9 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" value="${_('quick filter...')}"/> ${h.link_to(_('Admin'),h.url('admin_home'))} &raquo; <span id="repo_count">0</span> ${_('repositories')}
10 </%def>
10 </%def>
11 <%def name="page_nav()">
11 <%def name="page_nav()">
12 ${self.menu('admin')}
12 ${self.menu('admin')}
13 </%def>
13 </%def>
14 <%def name="main()">
14 <%def name="main()">
15 <div class="box">
15 <div class="box">
16
16
17 <div class="title">
17 <div class="title">
18 ${self.breadcrumbs()}
18 ${self.breadcrumbs()}
19 <ul class="links">
19 <ul class="links">
20 <li>
20 <li>
21 <span>${h.link_to(_(u'ADD REPOSITORY'),h.url('new_repo'))}</span>
21 <span>${h.link_to(_(u'ADD REPOSITORY'),h.url('new_repo'))}</span>
22 </li>
22 </li>
23 </ul>
23 </ul>
24 </div>
24 </div>
25 <div class="table yui-skin-sam" id="repos_list_wrap"></div>
25 <div class="table yui-skin-sam" id="repos_list_wrap"></div>
26 <div id="user-paginator" style="padding: 0px 0px 0px 20px"></div>
26 <div id="user-paginator" style="padding: 0px 0px 0px 20px"></div>
27
27
28
28
29 </div>
29 </div>
30 <script>
30 <script>
31 var url = "${h.url('formatted_users', format='json')}";
31 var url = "${h.url('formatted_users', format='json')}";
32 var data = ${c.data|n};
32 var data = ${c.data|n};
33 var myDataSource = new YAHOO.util.DataSource(data);
33 var myDataSource = new YAHOO.util.DataSource(data);
34 myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
34 myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
35
35
36 myDataSource.responseSchema = {
36 myDataSource.responseSchema = {
37 resultsList: "records",
37 resultsList: "records",
38 fields: [
38 fields: [
39 {key:"menu"},
39 {key:"menu"},
40 {key:"raw_name"},
40 {key:"raw_name"},
41 {key:"name"},
41 {key:"name"},
42 {key:"desc"},
42 {key:"desc"},
43 {key:"last_changeset"},
43 {key:"owner"},
44 {key:"owner"},
44 {key:"action"},
45 {key:"action"},
45 ]
46 ]
46 };
47 };
47 myDataSource.doBeforeCallback = function(req,raw,res,cb) {
48 myDataSource.doBeforeCallback = function(req,raw,res,cb) {
48 // This is the filter function
49 // This is the filter function
49 var data = res.results || [],
50 var data = res.results || [],
50 filtered = [],
51 filtered = [],
51 i,l;
52 i,l;
52
53
53 if (req) {
54 if (req) {
54 req = req.toLowerCase();
55 req = req.toLowerCase();
55 for (i = 0; i<data.length; i++) {
56 for (i = 0; i<data.length; i++) {
56 var pos = data[i].raw_name.toLowerCase().indexOf(req)
57 var pos = data[i].raw_name.toLowerCase().indexOf(req)
57 if (pos != -1) {
58 if (pos != -1) {
58 filtered.push(data[i]);
59 filtered.push(data[i]);
59 }
60 }
60 }
61 }
61 res.results = filtered;
62 res.results = filtered;
62 }
63 }
63 YUD.get('repo_count').innerHTML = res.results.length;
64 YUD.get('repo_count').innerHTML = res.results.length;
64 return res;
65 return res;
65 }
66 }
66
67
67 // main table sorting
68 // main table sorting
68 var myColumnDefs = [
69 var myColumnDefs = [
69 {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"},
70 {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"},
70 {key:"name",label:"${_('Name')}",sortable:true,
71 {key:"name",label:"${_('Name')}",sortable:true,
71 sortOptions: { sortFunction: nameSort }},
72 sortOptions: { sortFunction: nameSort }},
72 {key:"desc",label:"${_('Description')}",sortable:true},
73 {key:"desc",label:"${_('Description')}",sortable:true},
74 {key:"last_changeset",label:"${_('Tip')}",sortable:true,
75 sortOptions: { sortFunction: revisionSort }},
73 {key:"owner",label:"${_('Owner')}",sortable:true},
76 {key:"owner",label:"${_('Owner')}",sortable:true},
74 {key:"action",label:"${_('Action')}",sortable:false},
77 {key:"action",label:"${_('Action')}",sortable:false},
75 ];
78 ];
76
79
77 var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource,{
80 var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource,{
78 sortedBy:{key:"name",dir:"asc"},
81 sortedBy:{key:"name",dir:"asc"},
79 paginator: new YAHOO.widget.Paginator({
82 paginator: new YAHOO.widget.Paginator({
80 rowsPerPage: 15,
83 rowsPerPage: 25,
81 alwaysVisible: false,
84 alwaysVisible: false,
82 template : "{PreviousPageLink} {FirstPageLink} {PageLinks} {LastPageLink} {NextPageLink}",
85 template : "{PreviousPageLink} {FirstPageLink} {PageLinks} {LastPageLink} {NextPageLink}",
83 pageLinks: 5,
86 pageLinks: 5,
84 containerClass: 'pagination-wh',
87 containerClass: 'pagination-wh',
85 currentPageClass: 'pager_curpage',
88 currentPageClass: 'pager_curpage',
86 pageLinkClass: 'pager_link',
89 pageLinkClass: 'pager_link',
87 nextPageLinkLabel: '&gt;',
90 nextPageLinkLabel: '&gt;',
88 previousPageLinkLabel: '&lt;',
91 previousPageLinkLabel: '&lt;',
89 firstPageLinkLabel: '&lt;&lt;',
92 firstPageLinkLabel: '&lt;&lt;',
90 lastPageLinkLabel: '&gt;&gt;',
93 lastPageLinkLabel: '&gt;&gt;',
91 containers:['user-paginator']
94 containers:['user-paginator']
92 }),
95 }),
93
96
94 MSG_SORTASC:"${_('Click to sort ascending')}",
97 MSG_SORTASC:"${_('Click to sort ascending')}",
95 MSG_SORTDESC:"${_('Click to sort descending')}",
98 MSG_SORTDESC:"${_('Click to sort descending')}",
96 MSG_EMPTY:"${_('No records found.')}",
99 MSG_EMPTY:"${_('No records found.')}",
97 MSG_ERROR:"${_('Data error.')}",
100 MSG_ERROR:"${_('Data error.')}",
98 MSG_LOADING:"${_('Loading...')}",
101 MSG_LOADING:"${_('Loading...')}",
99 }
102 }
100 );
103 );
101 myDataTable.subscribe('postRenderEvent',function(oArgs) {
104 myDataTable.subscribe('postRenderEvent',function(oArgs) {
102 tooltip_activate();
105 tooltip_activate();
103 quick_repo_menu();
106 quick_repo_menu();
104 });
107 });
105
108
106 var filterTimeout = null;
109 var filterTimeout = null;
107
110
108 updateFilter = function () {
111 updateFilter = function () {
109 // Reset timeout
112 // Reset timeout
110 filterTimeout = null;
113 filterTimeout = null;
111
114
112 // Reset sort
115 // Reset sort
113 var state = myDataTable.getState();
116 var state = myDataTable.getState();
114 state.sortedBy = {key:'name', dir:YAHOO.widget.DataTable.CLASS_ASC};
117 state.sortedBy = {key:'name', dir:YAHOO.widget.DataTable.CLASS_ASC};
115
118
116 // Get filtered data
119 // Get filtered data
117 myDataSource.sendRequest(YUD.get('q_filter').value,{
120 myDataSource.sendRequest(YUD.get('q_filter').value,{
118 success : myDataTable.onDataReturnInitializeTable,
121 success : myDataTable.onDataReturnInitializeTable,
119 failure : myDataTable.onDataReturnInitializeTable,
122 failure : myDataTable.onDataReturnInitializeTable,
120 scope : myDataTable,
123 scope : myDataTable,
121 argument: state
124 argument: state
122 });
125 });
123
126
124 };
127 };
125 YUE.on('q_filter','click',function(){
128 YUE.on('q_filter','click',function(){
129 if(!YUD.hasClass('q_filter', 'loaded')){
126 YUD.get('q_filter').value = '';
130 YUD.get('q_filter').value = '';
131 //TODO: load here full list later to do search within groups
132 YUD.addClass('q_filter', 'loaded');
133 }
127 });
134 });
128
135
129 YUE.on('q_filter','keyup',function (e) {
136 YUE.on('q_filter','keyup',function (e) {
130 clearTimeout(filterTimeout);
137 clearTimeout(filterTimeout);
131 filterTimeout = setTimeout(updateFilter,600);
138 filterTimeout = setTimeout(updateFilter,600);
132 });
139 });
133 </script>
140 </script>
134
141
135 </%def>
142 </%def>
@@ -1,248 +1,278 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%inherit file="/base/base.html"/>
2 <%inherit file="/base/base.html"/>
3
3
4 <%def name="title()">
4 <%def name="title()">
5 ${_('My account')} ${c.rhodecode_user.username} - ${c.rhodecode_name}
5 ${_('My account')} ${c.rhodecode_user.username} - ${c.rhodecode_name}
6 </%def>
6 </%def>
7
7
8 <%def name="breadcrumbs_links()">
8 <%def name="breadcrumbs_links()">
9 ${_('My Account')}
9 ${_('My Account')}
10 </%def>
10 </%def>
11
11
12 <%def name="page_nav()">
12 <%def name="page_nav()">
13 ${self.menu('admin')}
13 ${self.menu('admin')}
14 </%def>
14 </%def>
15
15
16 <%def name="main()">
16 <%def name="main()">
17
17
18 <div class="box box-left">
18 <div class="box box-left">
19 <!-- box / title -->
19 <!-- box / title -->
20 <div class="title">
20 <div class="title">
21 ${self.breadcrumbs()}
21 ${self.breadcrumbs()}
22 </div>
22 </div>
23 <!-- end box / title -->
23 <!-- end box / title -->
24 ${c.form|n}
24 ${c.form|n}
25 </div>
25 </div>
26
26
27 <div class="box box-right">
27 <div class="box box-right">
28 <!-- box / title -->
28 <!-- box / title -->
29 <div class="title">
29 <div class="title">
30 <h5>
30 <h5>
31 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" value="${_('quick filter...')}" style="display: none"/>
31 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" value="${_('quick filter...')}" style="display: none"/>
32 </h5>
32 </h5>
33 <ul class="links" style="color:#DADADA">
33 <ul class="links" style="color:#DADADA">
34 <li>
34 <li>
35 <span><a id="show_perms" class="link-white current" href="#perms">${_('My permissions')}</a> </span>
35 <span><a id="show_perms" class="link-white current" href="#perms">${_('My permissions')}</a> </span>
36 </li>
36 </li>
37 <li>
37 <li>
38 <span><a id="show_my" class="link-white" href="#my">${_('My repos')}</a> </span>
38 <span><a id="show_my" class="link-white" href="#my">${_('My repos')}</a> </span>
39 </li>
39 </li>
40 <li>
40 <li>
41 <span><a id="show_pullrequests" class="link-white" href="#pullrequests">${_('My pull requests')}</a> </span>
41 <span><a id="show_pullrequests" class="link-white" href="#pullrequests">${_('My pull requests')}</a> </span>
42 </li>
42 </li>
43 %if h.HasPermissionAny('hg.admin','hg.create.repository')():
43 %if h.HasPermissionAny('hg.admin','hg.create.repository')():
44 <li>
44 <li>
45 <span>${h.link_to(_('Add repo'),h.url('admin_settings_create_repository'))}</span>
45 <span>${h.link_to(_('Add repo'),h.url('admin_settings_create_repository'))}</span>
46 </li>
46 </li>
47 %endif
47 %endif
48 </ul>
48 </ul>
49 </div>
49 </div>
50 <!-- end box / title -->
50 <!-- end box / title -->
51 <div id="perms" class="table">
51 <div id="perms_container" class="table">
52 %for section in sorted(c.rhodecode_user.permissions.keys()):
52 %for section in sorted(c.rhodecode_user.permissions.keys()):
53 <div class="perms_section_head">${section.replace("_"," ").capitalize()}</div>
53 <div class="perms_section_head">${section.replace("_"," ").capitalize()}</div>
54
54
55 <div id='tbl_list_wrap_${section}' class="yui-skin-sam">
55 <div id='tbl_list_wrap_${section}' class="yui-skin-sam">
56 <table id="tbl_list_${section}">
56 <table id="tbl_list_${section}">
57 <thead>
57 <thead>
58 <tr>
58 <tr>
59 <th class="left">${_('Name')}</th>
59 <th class="left">${_('Name')}</th>
60 <th class="left">${_('Permission')}</th>
60 <th class="left">${_('Permission')}</th>
61 </thead>
61 </thead>
62 <tbody>
62 <tbody>
63 %for k in c.rhodecode_user.permissions[section]:
63 %for k in c.rhodecode_user.permissions[section]:
64 <%
64 <%
65 if section != 'global':
65 if section != 'global':
66 section_perm = c.rhodecode_user.permissions[section].get(k)
66 section_perm = c.rhodecode_user.permissions[section].get(k)
67 _perm = section_perm.split('.')[-1]
67 _perm = section_perm.split('.')[-1]
68 else:
68 else:
69 _perm = section_perm = None
69 _perm = section_perm = None
70 %>
70 %>
71 %if _perm not in ['none']:
71 %if _perm not in ['none']:
72 <tr>
72 <tr>
73 <td>
73 <td>
74 %if section == 'repositories':
74 %if section == 'repositories':
75 <a href="${h.url('summary_home',repo_name=k)}">${k}</a>
75 <a href="${h.url('summary_home',repo_name=k)}">${k}</a>
76 %elif section == 'repositories_groups':
76 %elif section == 'repositories_groups':
77 <a href="${h.url('repos_group_home',group_name=k)}">${k}</a>
77 <a href="${h.url('repos_group_home',group_name=k)}">${k}</a>
78 %else:
78 %else:
79 ${k}
79 ${k}
80 %endif
80 %endif
81 </td>
81 </td>
82 <td>
82 <td>
83 %if section == 'global':
83 %if section == 'global':
84 ${h.bool2icon(True)}
84 ${h.bool2icon(True)}
85 %else:
85 %else:
86 <span class="perm_tag ${_perm}">${section_perm}</span>
86 <span class="perm_tag ${_perm}">${section_perm}</span>
87 %endif
87 %endif
88 </td>
88 </td>
89 </tr>
89 </tr>
90 %endif
90 %endif
91 %endfor
91 %endfor
92 </tbody>
92 </tbody>
93 </table>
93 </table>
94 </div>
94 </div>
95 %endfor
95 %endfor
96 </div>
96 </div>
97 <div id="my" class="table" style="display:none">
97 <div id="my_container" style="display:none">
98 <div class="table yui-skin-sam" id="repos_list_wrap"></div>
99 <div id="user-paginator" style="padding: 0px 0px 0px 20px"></div>
98 </div>
100 </div>
99 <div id="pullrequests" class="table" style="display:none"></div>
101 <div id="pullrequests_container" class="table" style="display:none">
102 ## loaded via AJAX
103 ${_('Loading...')}
100 </div>
104 </div>
101
105 </div>
102
103
106
104 <script type="text/javascript">
107 <script type="text/javascript">
105 var filter_activate = function(){
106 var nodes = YUQ('#my tr td a.repo_name');
107 var func = function(node){
108 return node.parentNode.parentNode.parentNode.parentNode;
109 }
110 q_filter('q_filter',YUQ('#my tr td a.repo_name'),func);
111 }
112
108
113 var show_perms = function(e){
109 var show_perms = function(e){
114 YUD.addClass('show_perms', 'current');
110 YUD.addClass('show_perms', 'current');
115 YUD.removeClass('show_my','current');
111 YUD.removeClass('show_my','current');
116 YUD.removeClass('show_pullrequests','current');
112 YUD.removeClass('show_pullrequests','current');
117
113
118 YUD.setStyle('my','display','none');
114 YUD.setStyle('my_container','display','none');
119 YUD.setStyle('pullrequests','display','none');
115 YUD.setStyle('pullrequests_container','display','none');
120 YUD.setStyle('perms','display','');
116 YUD.setStyle('perms_container','display','');
121 YUD.setStyle('q_filter','display','none');
117 YUD.setStyle('q_filter','display','none');
122 }
118 }
123 YUE.on('show_perms','click',function(e){
119 YUE.on('show_perms','click',function(e){
124 show_perms();
120 show_perms();
125 })
121 })
126
122
127 var show_my = function(e){
123 var show_my = function(e){
128 YUD.addClass('show_my', 'current');
124 YUD.addClass('show_my', 'current');
129 YUD.removeClass('show_perms','current');
125 YUD.removeClass('show_perms','current');
130 YUD.removeClass('show_pullrequests','current');
126 YUD.removeClass('show_pullrequests','current');
131
127
132 YUD.setStyle('perms','display','none');
128 YUD.setStyle('perms_container','display','none');
133 YUD.setStyle('pullrequests','display','none');
129 YUD.setStyle('pullrequests_container','display','none');
134 YUD.setStyle('my','display','');
130 YUD.setStyle('my_container','display','');
135 YUD.setStyle('q_filter','display','');
131 YUD.setStyle('q_filter','display','');
136
132 if(!YUD.hasClass('show_my', 'loaded')){
137
133 table_renderer(${c.data |n});
138 var url = "${h.url('journal_my_repos')}";
134 YUD.addClass('show_my', 'loaded');
139 ypjax(url, 'my', function(){
135 }
140 table_sort();
141 filter_activate();
142 });
143 }
136 }
144 YUE.on('show_my','click',function(e){
137 YUE.on('show_my','click',function(e){
145 show_my(e);
138 show_my(e);
146 })
139 })
147
140
148 var show_pullrequests = function(e){
141 var show_pullrequests = function(e){
149 YUD.addClass('show_pullrequests', 'current');
142 YUD.addClass('show_pullrequests', 'current');
150 YUD.removeClass('show_my','current');
143 YUD.removeClass('show_my','current');
151 YUD.removeClass('show_perms','current');
144 YUD.removeClass('show_perms','current');
152
145
153 YUD.setStyle('my','display','none');
146 YUD.setStyle('my_container','display','none');
154 YUD.setStyle('perms','display','none');
147 YUD.setStyle('perms_container','display','none');
155 YUD.setStyle('pullrequests','display','');
148 YUD.setStyle('pullrequests_container','display','');
156 YUD.setStyle('q_filter','display','none');
149 YUD.setStyle('q_filter','display','none');
157
150
158 var url = "${h.url('admin_settings_my_pullrequests')}";
151 var url = "${h.url('admin_settings_my_pullrequests')}";
159 ypjax(url, 'pullrequests');
152 ypjax(url, 'pullrequests_container');
160 }
153 }
161 YUE.on('show_pullrequests','click',function(e){
154 YUE.on('show_pullrequests','click',function(e){
162 show_pullrequests(e)
155 show_pullrequests(e)
163 })
156 })
164
157
165 var tabs = {
158 var tabs = {
166 'perms': show_perms,
159 'perms': show_perms,
167 'my': show_my,
160 'my': show_my,
168 'pullrequests': show_pullrequests
161 'pullrequests': show_pullrequests
169 }
162 }
170 var url = location.href.split('#');
163 var url = location.href.split('#');
171 if (url[1]) {
164 if (url[1]) {
172 //We have a hash
165 //We have a hash
173 var tabHash = url[1];
166 var tabHash = url[1];
174 var func = tabs[tabHash]
167 var func = tabs[tabHash]
175 if (func){
168 if (func){
176 func();
169 func();
177 }
170 }
178 }
171 }
179
172
173 function table_renderer(data){
174 var myDataSource = new YAHOO.util.DataSource(data);
175 myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
176
177 myDataSource.responseSchema = {
178 resultsList: "records",
179 fields: [
180 {key:"menu"},
181 {key:"raw_name"},
182 {key:"name"},
183 {key:"last_changeset"},
184 {key:"action"},
185 ]
186 };
187 myDataSource.doBeforeCallback = function(req,raw,res,cb) {
188 // This is the filter function
189 var data = res.results || [],
190 filtered = [],
191 i,l;
192
193 if (req) {
194 req = req.toLowerCase();
195 for (i = 0; i<data.length; i++) {
196 var pos = data[i].raw_name.toLowerCase().indexOf(req)
197 if (pos != -1) {
198 filtered.push(data[i]);
199 }
200 }
201 res.results = filtered;
202 }
203 return res;
204 }
205
180 // main table sorting
206 // main table sorting
181 var myColumnDefs = [
207 var myColumnDefs = [
182 {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"},
208 {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"},
183 {key:"name",label:"${_('Name')}",sortable:true,
209 {key:"name",label:"${_('Name')}",sortable:true,
184 sortOptions: { sortFunction: nameSort }},
210 sortOptions: { sortFunction: nameSort }},
185 {key:"tip",label:"${_('Tip')}",sortable:true,
211 {key:"last_changeset",label:"${_('Tip')}",sortable:true,
186 sortOptions: { sortFunction: revisionSort }},
212 sortOptions: { sortFunction: revisionSort }},
187 {key:"action1",label:"",sortable:false},
213 {key:"action",label:"${_('Action')}",sortable:false},
188 {key:"action2",label:"",sortable:false},
189 ];
214 ];
190
215
191 function table_sort(){
216 var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource,{
192 var myDataSource = new YAHOO.util.DataSource(YUD.get("repos_list"));
193 myDataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
194 myDataSource.responseSchema = {
195 fields: [
196 {key:"menu"},
197 {key:"name"},
198 {key:"tip"},
199 {key:"action1"},
200 {key:"action2"},
201 ]
202 };
203 var trans_defs = {
204 sortedBy:{key:"name",dir:"asc"},
217 sortedBy:{key:"name",dir:"asc"},
218 paginator: new YAHOO.widget.Paginator({
219 rowsPerPage: 50,
220 alwaysVisible: false,
221 template : "{PreviousPageLink} {FirstPageLink} {PageLinks} {LastPageLink} {NextPageLink}",
222 pageLinks: 5,
223 containerClass: 'pagination-wh',
224 currentPageClass: 'pager_curpage',
225 pageLinkClass: 'pager_link',
226 nextPageLinkLabel: '&gt;',
227 previousPageLinkLabel: '&lt;',
228 firstPageLinkLabel: '&lt;&lt;',
229 lastPageLinkLabel: '&gt;&gt;',
230 containers:['user-paginator']
231 }),
232
205 MSG_SORTASC:"${_('Click to sort ascending')}",
233 MSG_SORTASC:"${_('Click to sort ascending')}",
206 MSG_SORTDESC:"${_('Click to sort descending')}",
234 MSG_SORTDESC:"${_('Click to sort descending')}",
207 MSG_EMPTY:"${_('No records found.')}",
235 MSG_EMPTY:"${_('No records found.')}",
208 MSG_ERROR:"${_('Data error.')}",
236 MSG_ERROR:"${_('Data error.')}",
209 MSG_LOADING:"${_('Loading...')}",
237 MSG_LOADING:"${_('Loading...')}",
210 }
238 }
211 var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource,trans_defs);
239 );
212 myDataTable.subscribe('postRenderEvent',function(oArgs) {
240 myDataTable.subscribe('postRenderEvent',function(oArgs) {
213 tooltip_activate();
241 tooltip_activate();
214 quick_repo_menu();
242 quick_repo_menu();
215 filter_activate();
216 });
243 });
217
244
218 var permsColumnDefs = [
245 var filterTimeout = null;
219 {key:"name",label:"${_('Name')}",sortable:true, sortOptions: { sortFunction: permNameSort }},
246
220 {key:"perm",label:"${_('Permission')}",sortable:false,},
247 updateFilter = function() {
221 ];
248 // Reset timeout
249 filterTimeout = null;
222
250
223 // perms repos table
251 // Reset sort
224 var myDataSource2 = new YAHOO.util.DataSource(YUD.get("tbl_list_repositories"));
252 var state = myDataTable.getState();
225 myDataSource2.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
253 state.sortedBy = {key:'name', dir:YAHOO.widget.DataTable.CLASS_ASC};
226 myDataSource2.responseSchema = {
254
227 fields: [
255 // Get filtered data
228 {key:"name"},
256 myDataSource.sendRequest(YUD.get('q_filter').value,{
229 {key:"perm"},
257 success : myDataTable.onDataReturnInitializeTable,
230 ]
258 failure : myDataTable.onDataReturnInitializeTable,
259 scope : myDataTable,
260 argument: state
261 });
262
231 };
263 };
232
264 YUE.on('q_filter','click',function(){
233 new YAHOO.widget.DataTable("tbl_list_wrap_repositories", permsColumnDefs, myDataSource2, trans_defs);
265 if(!YUD.hasClass('q_filter', 'loaded')){
266 YUD.get('q_filter').value = '';
267 //TODO: load here full list later to do search within groups
268 YUD.addClass('q_filter', 'loaded');
269 }
270 });
234
271
235 //perms groups table
272 YUE.on('q_filter','keyup',function (e) {
236 var myDataSource3 = new YAHOO.util.DataSource(YUD.get("tbl_list_repositories_groups"));
273 clearTimeout(filterTimeout);
237 myDataSource3.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
274 filterTimeout = setTimeout(updateFilter,600);
238 myDataSource3.responseSchema = {
275 });
239 fields: [
240 {key:"name"},
241 {key:"perm"},
242 ]
243 };
244
245 new YAHOO.widget.DataTable("tbl_list_wrap_repositories_groups", permsColumnDefs, myDataSource3, trans_defs);
246 }
276 }
247 </script>
277 </script>
248 </%def>
278 </%def>
@@ -1,46 +1,1 b''
1 <div id='repos_list_wrap' class="yui-skin-sam">
1
2 <table id="repos_list">
3 <thead>
4 <tr>
5 <th></th>
6 <th class="left">${_('Name')}</th>
7 <th class="left">${_('Revision')}</th>
8 <th class="left">${_('Action')}</th>
9 <th class="left">${_('Action')}</th>
10 </thead>
11 <tbody>
12 <%namespace name="dt" file="/data_table/_dt_elements.html"/>
13 %if c.user_repos:
14 %for repo in c.user_repos:
15 <tr>
16 ##QUICK MENU
17 <td class="quick_repo_menu">
18 ${dt.quick_menu(repo['name'])}
19 </td>
20 ##REPO NAME AND ICONS
21 <td class="reponame">
22 ${dt.repo_name(repo['name'],repo['dbrepo']['repo_type'],repo['dbrepo']['private'],h.AttributeDict(repo['dbrepo_fork']))}
23 </td>
24 ##LAST REVISION
25 <td>
26 ${dt.revision(repo['name'],repo['rev'],repo['tip'],repo['author'],repo['last_msg'])}
27 </td>
28 <td><a href="${h.url('repo_settings_home',repo_name=repo['name'])}" title="${_('edit')}"><img class="icon" alt="${_('private')}" src="${h.url('/images/icons/application_form_edit.png')}"/></a></td>
29 <td>
30 ${h.form(url('repo_settings_delete', repo_name=repo['name']),method='delete')}
31 ${h.submit('remove_%s' % repo['name'],'',class_="delete_icon action_button",onclick="return confirm('"+_('Confirm to delete this repository: %s') % repo['name']+"');")}
32 ${h.end_form()}
33 </td>
34 </tr>
35 %endfor
36 %else:
37 <div style="padding:5px 0px 10px 0px;">
38 ${_('No repositories yet')}
39 %if h.HasPermissionAny('hg.admin','hg.create.repository')():
40 ${h.link_to(_('create one now'),h.url('admin_settings_create_repository'),class_="ui-btn")}
41 %endif
42 </div>
43 %endif
44 </tbody>
45 </table>
46 </div>
@@ -1,128 +1,144 b''
1 ## DATA TABLE RE USABLE ELEMENTS
1 ## DATA TABLE RE USABLE ELEMENTS
2 ## usage:
2 ## usage:
3 ## <%namespace name="dt" file="/data_table/_dt_elements.html"/>
3 ## <%namespace name="dt" file="/data_table/_dt_elements.html"/>
4
4
5 <%def name="repo_actions(repo_name)">
6 ${h.form(h.url('repo', repo_name=repo_name),method='delete')}
7 ${h.submit('remove_%s' % repo_name,_('delete'),class_="delete_icon action_button",onclick="return confirm('"+_('Confirm to delete this repository: %s') % repo_name+"');")}
8 ${h.end_form()}
9 </%def>
10
11 <%def name="quick_menu(repo_name)">
5 <%def name="quick_menu(repo_name)">
12 <ul class="menu_items hidden">
6 <ul class="menu_items hidden">
13 <li style="border-top:1px solid #003367;margin-left:18px;padding-left:-99px"></li>
7 <li style="border-top:1px solid #003367;margin-left:18px;padding-left:-99px"></li>
14 <li>
8 <li>
15 <a title="${_('Summary')}" href="${h.url('summary_home',repo_name=repo_name)}">
9 <a title="${_('Summary')}" href="${h.url('summary_home',repo_name=repo_name)}">
16 <span class="icon">
10 <span class="icon">
17 <img src="${h.url('/images/icons/clipboard_16.png')}" alt="${_('Summary')}" />
11 <img src="${h.url('/images/icons/clipboard_16.png')}" alt="${_('Summary')}" />
18 </span>
12 </span>
19 <span>${_('Summary')}</span>
13 <span>${_('Summary')}</span>
20 </a>
14 </a>
21 </li>
15 </li>
22 <li>
16 <li>
23 <a title="${_('Changelog')}" href="${h.url('changelog_home',repo_name=repo_name)}">
17 <a title="${_('Changelog')}" href="${h.url('changelog_home',repo_name=repo_name)}">
24 <span class="icon">
18 <span class="icon">
25 <img src="${h.url('/images/icons/time.png')}" alt="${_('Changelog')}" />
19 <img src="${h.url('/images/icons/time.png')}" alt="${_('Changelog')}" />
26 </span>
20 </span>
27 <span>${_('Changelog')}</span>
21 <span>${_('Changelog')}</span>
28 </a>
22 </a>
29 </li>
23 </li>
30 <li>
24 <li>
31 <a title="${_('Files')}" href="${h.url('files_home',repo_name=repo_name)}">
25 <a title="${_('Files')}" href="${h.url('files_home',repo_name=repo_name)}">
32 <span class="icon">
26 <span class="icon">
33 <img src="${h.url('/images/icons/file.png')}" alt="${_('Files')}" />
27 <img src="${h.url('/images/icons/file.png')}" alt="${_('Files')}" />
34 </span>
28 </span>
35 <span>${_('Files')}</span>
29 <span>${_('Files')}</span>
36 </a>
30 </a>
37 </li>
31 </li>
38 <li>
32 <li>
39 <a title="${_('Fork')}" href="${h.url('repo_fork_home',repo_name=repo_name)}">
33 <a title="${_('Fork')}" href="${h.url('repo_fork_home',repo_name=repo_name)}">
40 <span class="icon">
34 <span class="icon">
41 <img src="${h.url('/images/icons/arrow_divide.png')}" alt="${_('Fork')}" />
35 <img src="${h.url('/images/icons/arrow_divide.png')}" alt="${_('Fork')}" />
42 </span>
36 </span>
43 <span>${_('Fork')}</span>
37 <span>${_('Fork')}</span>
44 </a>
38 </a>
45 </li>
39 </li>
46 </ul>
40 </ul>
47 </%def>
41 </%def>
48
42
49 <%def name="repo_name(name,rtype,private,fork_of,short_name=False, admin=False)">
43 <%def name="repo_name(name,rtype,private,fork_of,short_name=False,admin=False)">
50 <%
44 <%
51 def get_name(name,short_name=short_name):
45 def get_name(name,short_name=short_name):
52 if short_name:
46 if short_name:
53 return name.split('/')[-1]
47 return name.split('/')[-1]
54 else:
48 else:
55 return name
49 return name
56 %>
50 %>
57 <div style="white-space: nowrap">
51 <div style="white-space: nowrap">
58 ##TYPE OF REPO
52 ##TYPE OF REPO
59 %if h.is_hg(rtype):
53 %if h.is_hg(rtype):
60 <img class="icon" title="${_('Mercurial repository')}" alt="${_('Mercurial repository')}" src="${h.url('/images/icons/hgicon.png')}"/>
54 <img class="icon" title="${_('Mercurial repository')}" alt="${_('Mercurial repository')}" src="${h.url('/images/icons/hgicon.png')}"/>
61 %elif h.is_git(rtype):
55 %elif h.is_git(rtype):
62 <img class="icon" title="${_('Git repository')}" alt="${_('Git repository')}" src="${h.url('/images/icons/giticon.png')}"/>
56 <img class="icon" title="${_('Git repository')}" alt="${_('Git repository')}" src="${h.url('/images/icons/giticon.png')}"/>
63 %endif
57 %endif
64
58
65 ##PRIVATE/PUBLIC
59 ##PRIVATE/PUBLIC
66 %if private and c.visual.show_private_icon:
60 %if private and c.visual.show_private_icon:
67 <img class="icon" title="${_('private repository')}" alt="${_('private repository')}" src="${h.url('/images/icons/lock.png')}"/>
61 <img class="icon" title="${_('private repository')}" alt="${_('private repository')}" src="${h.url('/images/icons/lock.png')}"/>
68 %elif not private and c.visual.show_public_icon:
62 %elif not private and c.visual.show_public_icon:
69 <img class="icon" title="${_('public repository')}" alt="${_('public repository')}" src="${h.url('/images/icons/lock_open.png')}"/>
63 <img class="icon" title="${_('public repository')}" alt="${_('public repository')}" src="${h.url('/images/icons/lock_open.png')}"/>
70 %endif
64 %endif
71
65
72 ##NAME
66 ##NAME
73 %if admin:
67 %if admin:
74 ${h.link_to(get_name(name),h.url('edit_repo',repo_name=name),class_="repo_name")}
68 ${h.link_to(get_name(name),h.url('edit_repo',repo_name=name),class_="repo_name")}
75 %else:
69 %else:
76 ${h.link_to(get_name(name),h.url('summary_home',repo_name=name),class_="repo_name")}
70 ${h.link_to(get_name(name),h.url('summary_home',repo_name=name),class_="repo_name")}
77 %endif
71 %endif
78 %if fork_of:
72 %if fork_of:
79 <a href="${h.url('summary_home',repo_name=fork_of.repo_name)}">
73 <a href="${h.url('summary_home',repo_name=fork_of.repo_name)}">
80 <img class="icon" alt="${_('fork')}" title="${_('Fork of')} ${fork_of.repo_name}" src="${h.url('/images/icons/arrow_divide.png')}"/></a>
74 <img class="icon" alt="${_('fork')}" title="${_('Fork of')} ${fork_of.repo_name}" src="${h.url('/images/icons/arrow_divide.png')}"/></a>
81 %endif
75 %endif
82 </div>
76 </div>
83 </%def>
77 </%def>
84
78
85 <%def name="last_change(last_change)">
79 <%def name="last_change(last_change)">
86 <span class="tooltip" date="${last_change}" title="${h.tooltip(h.fmt_date(last_change))}">${h.age(last_change)}</span>
80 <span class="tooltip" date="${last_change}" title="${h.tooltip(h.fmt_date(last_change))}">${h.age(last_change)}</span>
87 </%def>
81 </%def>
88
82
89 <%def name="revision(name,rev,tip,author,last_msg)">
83 <%def name="revision(name,rev,tip,author,last_msg)">
90 <div>
84 <div>
91 %if rev >= 0:
85 %if rev >= 0:
92 <pre><a title="${h.tooltip('%s:\n\n%s' % (author,last_msg))}" class="tooltip" href="${h.url('changeset_home',repo_name=name,revision=tip)}">${'r%s:%s' % (rev,h.short_id(tip))}</a></pre>
86 <pre><a title="${h.tooltip('%s:\n\n%s' % (author,last_msg))}" class="tooltip" href="${h.url('changeset_home',repo_name=name,revision=tip)}">${'r%s:%s' % (rev,h.short_id(tip))}</a></pre>
93 %else:
87 %else:
94 ${_('No changesets yet')}
88 ${_('No changesets yet')}
95 %endif
89 %endif
96 </div>
90 </div>
97 </%def>
91 </%def>
98
92
99 <%def name="rss(name)">
93 <%def name="rss(name)">
100 %if c.rhodecode_user.username != 'default':
94 %if c.rhodecode_user.username != 'default':
101 <a title="${_('Subscribe to %s rss feed')% name}" class="rss_icon" href="${h.url('rss_feed_home',repo_name=name,api_key=c.rhodecode_user.api_key)}"></a>
95 <a title="${_('Subscribe to %s rss feed')% name}" class="rss_icon" href="${h.url('rss_feed_home',repo_name=name,api_key=c.rhodecode_user.api_key)}"></a>
102 %else:
96 %else:
103 <a title="${_('Subscribe to %s rss feed')% name}" class="rss_icon" href="${h.url('rss_feed_home',repo_name=name)}"></a>
97 <a title="${_('Subscribe to %s rss feed')% name}" class="rss_icon" href="${h.url('rss_feed_home',repo_name=name)}"></a>
104 %endif
98 %endif
105 </%def>
99 </%def>
106
100
107 <%def name="atom(name)">
101 <%def name="atom(name)">
108 %if c.rhodecode_user.username != 'default':
102 %if c.rhodecode_user.username != 'default':
109 <a title="${_('Subscribe to %s atom feed')% name}" class="atom_icon" href="${h.url('atom_feed_home',repo_name=name,api_key=c.rhodecode_user.api_key)}"></a>
103 <a title="${_('Subscribe to %s atom feed')% name}" class="atom_icon" href="${h.url('atom_feed_home',repo_name=name,api_key=c.rhodecode_user.api_key)}"></a>
110 %else:
104 %else:
111 <a title="${_('Subscribe to %s atom feed')% name}" class="atom_icon" href="${h.url('atom_feed_home',repo_name=name)}"></a>
105 <a title="${_('Subscribe to %s atom feed')% name}" class="atom_icon" href="${h.url('atom_feed_home',repo_name=name)}"></a>
112 %endif
106 %endif
113 </%def>
107 </%def>
114
108
115 <%def name="user_gravatar(email, size=24)">
109 <%def name="user_gravatar(email, size=24)">
116 <div class="gravatar"><img alt="gravatar" src="${h.gravatar_url(email, size)}"/> </div>
110 <div class="gravatar"><img alt="gravatar" src="${h.gravatar_url(email, size)}"/> </div>
117 </%def>
111 </%def>
118
112
113 <%def name="repo_actions(repo_name)">
114 <div>
115 <div style="float:left">
116 <a href="${h.url('repo_settings_home',repo_name=repo_name)}" title="${_('edit')}">
117 ${h.submit('edit_%s' % repo_name,_('edit'),class_="edit_icon action_button")}
118 </a>
119 </div>
120 <div style="float:left">
121 ${h.form(h.url('repo', repo_name=repo_name),method='delete')}
122 ${h.submit('remove_%s' % repo_name,_('delete'),class_="delete_icon action_button",onclick="return confirm('"+_('Confirm to delete this repository: %s') % repo_name+"');")}
123 ${h.end_form()}
124 </div>
125 </div>
126 </%def>
127
119 <%def name="user_actions(user_id, username)">
128 <%def name="user_actions(user_id, username)">
120 ${h.form(h.url('delete_user', id=user_id),method='delete')}
129 ${h.form(h.url('delete_user', id=user_id),method='delete')}
121 ${h.submit('remove_',_('delete'),id="remove_user_%s" % user_id,
130 ${h.submit('remove_',_('delete'),id="remove_user_%s" % user_id,
122 class_="delete_icon action_button",onclick="return confirm('"+_('Confirm to delete this user: %s') % username+"');")}
131 class_="delete_icon action_button",onclick="return confirm('"+_('Confirm to delete this user: %s') % username+"');")}
123 ${h.end_form()}
132 ${h.end_form()}
124 </%def>
133 </%def>
125
134
126 <%def name="user_name(user_id, username)">
135 <%def name="user_name(user_id, username)">
127 ${h.link_to(username,h.url('edit_user', id=user_id))}
136 ${h.link_to(username,h.url('edit_user', id=user_id))}
128 </%def>
137 </%def>
138
139 <%def name="toggle_follow(repo_id)">
140 <span id="follow_toggle_${repo_id}" class="following" title="${_('Stop following this repository')}"
141 onclick="javascript:toggleFollowingRepo(this, ${repo_id},'${str(h.get_token())}')">
142 </span>
143 </%def>
144
@@ -1,334 +1,337 b''
1 <%page args="parent" />
1 <%page args="parent" />
2 <div class="box">
2 <div class="box">
3 <!-- box / title -->
3 <!-- box / title -->
4 <div class="title">
4 <div class="title">
5 <h5>
5 <h5>
6 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" value="${_('quick filter...')}"/> ${parent.breadcrumbs()} <span id="repo_count">0</span> ${_('repositories')}
6 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" value="${_('quick filter...')}"/> ${parent.breadcrumbs()} <span id="repo_count">0</span> ${_('repositories')}
7 </h5>
7 </h5>
8 %if c.rhodecode_user.username != 'default':
8 %if c.rhodecode_user.username != 'default':
9 %if h.HasPermissionAny('hg.admin','hg.create.repository')():
9 %if h.HasPermissionAny('hg.admin','hg.create.repository')():
10 <ul class="links">
10 <ul class="links">
11 <li>
11 <li>
12 %if c.group:
12 %if c.group:
13 <span>${h.link_to(_('ADD REPOSITORY'),h.url('admin_settings_create_repository',parent_group=c.group.group_id))}</span>
13 <span>${h.link_to(_('ADD REPOSITORY'),h.url('admin_settings_create_repository',parent_group=c.group.group_id))}</span>
14 %else:
14 %else:
15 <span>${h.link_to(_('ADD REPOSITORY'),h.url('admin_settings_create_repository'))}</span>
15 <span>${h.link_to(_('ADD REPOSITORY'),h.url('admin_settings_create_repository'))}</span>
16 %endif
16 %endif
17 </li>
17 </li>
18 </ul>
18 </ul>
19 %endif
19 %endif
20 %endif
20 %endif
21 </div>
21 </div>
22 <!-- end box / title -->
22 <!-- end box / title -->
23 <div class="table">
23 <div class="table">
24 % if c.groups:
24 % if c.groups:
25 <div id='groups_list_wrap' class="yui-skin-sam">
25 <div id='groups_list_wrap' class="yui-skin-sam">
26 <table id="groups_list">
26 <table id="groups_list">
27 <thead>
27 <thead>
28 <tr>
28 <tr>
29 <th class="left"><a href="#">${_('Group name')}</a></th>
29 <th class="left"><a href="#">${_('Group name')}</a></th>
30 <th class="left"><a href="#">${_('Description')}</a></th>
30 <th class="left"><a href="#">${_('Description')}</a></th>
31 ##<th class="left"><a href="#">${_('Number of repositories')}</a></th>
31 ##<th class="left"><a href="#">${_('Number of repositories')}</a></th>
32 </tr>
32 </tr>
33 </thead>
33 </thead>
34
34
35 ## REPO GROUPS
35 ## REPO GROUPS
36 % for gr in c.groups:
36 % for gr in c.groups:
37 <tr>
37 <tr>
38 <td>
38 <td>
39 <div style="white-space: nowrap">
39 <div style="white-space: nowrap">
40 <img class="icon" alt="${_('Repositories group')}" src="${h.url('/images/icons/database_link.png')}"/>
40 <img class="icon" alt="${_('Repositories group')}" src="${h.url('/images/icons/database_link.png')}"/>
41 ${h.link_to(gr.name,url('repos_group_home',group_name=gr.group_name))}
41 ${h.link_to(gr.name,url('repos_group_home',group_name=gr.group_name))}
42 </div>
42 </div>
43 </td>
43 </td>
44 %if c.visual.stylify_metatags:
44 %if c.visual.stylify_metatags:
45 <td>${h.urlify_text(h.desc_stylize(gr.group_description))}</td>
45 <td>${h.urlify_text(h.desc_stylize(gr.group_description))}</td>
46 %else:
46 %else:
47 <td>${gr.group_description}</td>
47 <td>${gr.group_description}</td>
48 %endif
48 %endif
49 ## this is commented out since for multi nested repos can be HEAVY!
49 ## this is commented out since for multi nested repos can be HEAVY!
50 ## in number of executed queries during traversing uncomment at will
50 ## in number of executed queries during traversing uncomment at will
51 ##<td><b>${gr.repositories_recursive_count}</b></td>
51 ##<td><b>${gr.repositories_recursive_count}</b></td>
52 </tr>
52 </tr>
53 % endfor
53 % endfor
54
54
55 </table>
55 </table>
56 </div>
56 </div>
57 <div style="height: 20px"></div>
57 <div style="height: 20px"></div>
58 % endif
58 % endif
59 <div id="welcome" style="display:none;text-align:center">
59 <div id="welcome" style="display:none;text-align:center">
60 <h1><a href="${h.url('home')}">${c.rhodecode_name} ${c.rhodecode_version}</a></h1>
60 <h1><a href="${h.url('home')}">${c.rhodecode_name} ${c.rhodecode_version}</a></h1>
61 </div>
61 </div>
62 <%cnt=0%>
62 <%cnt=0%>
63 <%namespace name="dt" file="/data_table/_dt_elements.html"/>
63 <%namespace name="dt" file="/data_table/_dt_elements.html"/>
64 % if c.visual.lightweight_dashboard is False:
64 % if c.visual.lightweight_dashboard is False:
65 ## old full detailed version
65 ## old full detailed version
66 <div id='repos_list_wrap' class="yui-skin-sam">
66 <div id='repos_list_wrap' class="yui-skin-sam">
67 <table id="repos_list">
67 <table id="repos_list">
68 <thead>
68 <thead>
69 <tr>
69 <tr>
70 <th class="left"></th>
70 <th class="left"></th>
71 <th class="left">${_('Name')}</th>
71 <th class="left">${_('Name')}</th>
72 <th class="left">${_('Description')}</th>
72 <th class="left">${_('Description')}</th>
73 <th class="left">${_('Last change')}</th>
73 <th class="left">${_('Last change')}</th>
74 <th class="left">${_('Tip')}</th>
74 <th class="left">${_('Tip')}</th>
75 <th class="left">${_('Owner')}</th>
75 <th class="left">${_('Owner')}</th>
76 <th class="left">${_('RSS')}</th>
76 <th class="left">${_('RSS')}</th>
77 <th class="left">${_('Atom')}</th>
77 <th class="left">${_('Atom')}</th>
78 </tr>
78 </tr>
79 </thead>
79 </thead>
80 <tbody>
80 <tbody>
81 %for cnt,repo in enumerate(c.repos_list):
81 %for cnt,repo in enumerate(c.repos_list):
82 <tr class="parity${(cnt+1)%2}">
82 <tr class="parity${(cnt+1)%2}">
83 ##QUICK MENU
83 ##QUICK MENU
84 <td class="quick_repo_menu">
84 <td class="quick_repo_menu">
85 ${dt.quick_menu(repo['name'])}
85 ${dt.quick_menu(repo['name'])}
86 </td>
86 </td>
87 ##REPO NAME AND ICONS
87 ##REPO NAME AND ICONS
88 <td class="reponame">
88 <td class="reponame">
89 ${dt.repo_name(repo['name'],repo['dbrepo']['repo_type'],repo['dbrepo']['private'],h.AttributeDict(repo['dbrepo_fork']),pageargs.get('short_repo_names'))}
89 ${dt.repo_name(repo['name'],repo['dbrepo']['repo_type'],repo['dbrepo']['private'],h.AttributeDict(repo['dbrepo_fork']),pageargs.get('short_repo_names'))}
90 </td>
90 </td>
91 ##DESCRIPTION
91 ##DESCRIPTION
92 <td><span class="tooltip" title="${h.tooltip(repo['description'])}">
92 <td><span class="tooltip" title="${h.tooltip(repo['description'])}">
93 %if c.visual.stylify_metatags:
93 %if c.visual.stylify_metatags:
94 ${h.urlify_text(h.desc_stylize(h.truncate(repo['description'],60)))}</span>
94 ${h.urlify_text(h.desc_stylize(h.truncate(repo['description'],60)))}</span>
95 %else:
95 %else:
96 ${h.truncate(repo['description'],60)}</span>
96 ${h.truncate(repo['description'],60)}</span>
97 %endif
97 %endif
98 </td>
98 </td>
99 ##LAST CHANGE DATE
99 ##LAST CHANGE DATE
100 <td>
100 <td>
101 ${dt.last_change(repo['last_change'])}
101 ${dt.last_change(repo['last_change'])}
102 </td>
102 </td>
103 ##LAST REVISION
103 ##LAST REVISION
104 <td>
104 <td>
105 ${dt.revision(repo['name'],repo['rev'],repo['tip'],repo['author'],repo['last_msg'])}
105 ${dt.revision(repo['name'],repo['rev'],repo['tip'],repo['author'],repo['last_msg'])}
106 </td>
106 </td>
107 ##
107 ##
108 <td title="${repo['contact']}">${h.person(repo['contact'])}</td>
108 <td title="${repo['contact']}">${h.person(repo['contact'])}</td>
109 <td>
109 <td>
110 ${dt.rss(repo['name'])}
110 ${dt.rss(repo['name'])}
111 </td>
111 </td>
112 <td>
112 <td>
113 ${dt.atom(repo['name'])}
113 ${dt.atom(repo['name'])}
114 </td>
114 </td>
115 </tr>
115 </tr>
116 %endfor
116 %endfor
117 </tbody>
117 </tbody>
118 </table>
118 </table>
119 </div>
119 </div>
120 % else:
120 % else:
121 ## lightweight version
121 ## lightweight version
122 <div class="yui-skin-sam" id="repos_list_wrap"></div>
122 <div class="yui-skin-sam" id="repos_list_wrap"></div>
123 <div id="user-paginator" style="padding: 0px 0px 0px 0px"></div>
123 <div id="user-paginator" style="padding: 0px 0px 0px 0px"></div>
124 % endif
124 % endif
125 </div>
125 </div>
126 </div>
126 </div>
127 % if c.visual.lightweight_dashboard is False:
127 % if c.visual.lightweight_dashboard is False:
128 <script>
128 <script>
129 YUD.get('repo_count').innerHTML = ${cnt+1 if cnt else 0};
129 YUD.get('repo_count').innerHTML = ${cnt+1 if cnt else 0};
130 var func = function(node){
131 return node.parentNode.parentNode.parentNode.parentNode;
132 }
133
130
134 // groups table sorting
131 // groups table sorting
135 var myColumnDefs = [
132 var myColumnDefs = [
136 {key:"name",label:"${_('Group name')}",sortable:true,
133 {key:"name",label:"${_('Group name')}",sortable:true,
137 sortOptions: { sortFunction: groupNameSort }},
134 sortOptions: { sortFunction: groupNameSort }},
138 {key:"desc",label:"${_('Description')}",sortable:true},
135 {key:"desc",label:"${_('Description')}",sortable:true},
139 ];
136 ];
140
137
141 var myDataSource = new YAHOO.util.DataSource(YUD.get("groups_list"));
138 var myDataSource = new YAHOO.util.DataSource(YUD.get("groups_list"));
142
139
143 myDataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
140 myDataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
144 myDataSource.responseSchema = {
141 myDataSource.responseSchema = {
145 fields: [
142 fields: [
146 {key:"name"},
143 {key:"name"},
147 {key:"desc"},
144 {key:"desc"},
148 ]
145 ]
149 };
146 };
150
147
151 var myDataTable = new YAHOO.widget.DataTable("groups_list_wrap", myColumnDefs, myDataSource,{
148 var myDataTable = new YAHOO.widget.DataTable("groups_list_wrap", myColumnDefs, myDataSource,{
152 sortedBy:{key:"name",dir:"asc"},
149 sortedBy:{key:"name",dir:"asc"},
153 paginator: new YAHOO.widget.Paginator({
150 paginator: new YAHOO.widget.Paginator({
154 rowsPerPage: 5,
151 rowsPerPage: 5,
155 alwaysVisible: false,
152 alwaysVisible: false,
156 template : "{PreviousPageLink} {FirstPageLink} {PageLinks} {LastPageLink} {NextPageLink}",
153 template : "{PreviousPageLink} {FirstPageLink} {PageLinks} {LastPageLink} {NextPageLink}",
157 pageLinks: 5,
154 pageLinks: 5,
158 containerClass: 'pagination-wh',
155 containerClass: 'pagination-wh',
159 currentPageClass: 'pager_curpage',
156 currentPageClass: 'pager_curpage',
160 pageLinkClass: 'pager_link',
157 pageLinkClass: 'pager_link',
161 nextPageLinkLabel: '&gt;',
158 nextPageLinkLabel: '&gt;',
162 previousPageLinkLabel: '&lt;',
159 previousPageLinkLabel: '&lt;',
163 firstPageLinkLabel: '&lt;&lt;',
160 firstPageLinkLabel: '&lt;&lt;',
164 lastPageLinkLabel: '&gt;&gt;',
161 lastPageLinkLabel: '&gt;&gt;',
165 containers:['user-paginator']
162 containers:['user-paginator']
166 }),
163 }),
167 MSG_SORTASC:"${_('Click to sort ascending')}",
164 MSG_SORTASC:"${_('Click to sort ascending')}",
168 MSG_SORTDESC:"${_('Click to sort descending')}"
165 MSG_SORTDESC:"${_('Click to sort descending')}"
169 });
166 });
170
167
171 // main table sorting
168 // main table sorting
172 var myColumnDefs = [
169 var myColumnDefs = [
173 {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"},
170 {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"},
174 {key:"name",label:"${_('Name')}",sortable:true,
171 {key:"name",label:"${_('Name')}",sortable:true,
175 sortOptions: { sortFunction: nameSort }},
172 sortOptions: { sortFunction: nameSort }},
176 {key:"desc",label:"${_('Description')}",sortable:true},
173 {key:"desc",label:"${_('Description')}",sortable:true},
177 {key:"last_change",label:"${_('Last Change')}",sortable:true,
174 {key:"last_change",label:"${_('Last Change')}",sortable:true,
178 sortOptions: { sortFunction: ageSort }},
175 sortOptions: { sortFunction: ageSort }},
179 {key:"tip",label:"${_('Tip')}",sortable:true,
176 {key:"tip",label:"${_('Tip')}",sortable:true,
180 sortOptions: { sortFunction: revisionSort }},
177 sortOptions: { sortFunction: revisionSort }},
181 {key:"owner",label:"${_('Owner')}",sortable:true},
178 {key:"owner",label:"${_('Owner')}",sortable:true},
182 {key:"rss",label:"",sortable:false},
179 {key:"rss",label:"",sortable:false},
183 {key:"atom",label:"",sortable:false},
180 {key:"atom",label:"",sortable:false},
184 ];
181 ];
185
182
186 var myDataSource = new YAHOO.util.DataSource(YUD.get("repos_list"));
183 var myDataSource = new YAHOO.util.DataSource(YUD.get("repos_list"));
187
184
188 myDataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
185 myDataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
189
186
190 myDataSource.responseSchema = {
187 myDataSource.responseSchema = {
191 fields: [
188 fields: [
192 {key:"menu"},
189 {key:"menu"},
193 //{key:"raw_name"},
190 //{key:"raw_name"},
194 {key:"name"},
191 {key:"name"},
195 {key:"desc"},
192 {key:"desc"},
196 {key:"last_change"},
193 {key:"last_change"},
197 {key:"tip"},
194 {key:"tip"},
198 {key:"owner"},
195 {key:"owner"},
199 {key:"rss"},
196 {key:"rss"},
200 {key:"atom"},
197 {key:"atom"},
201 ]
198 ]
202 };
199 };
203
200
204 var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource,
201 var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource,
205 {
202 {
206 sortedBy:{key:"name",dir:"asc"},
203 sortedBy:{key:"name",dir:"asc"},
207 MSG_SORTASC:"${_('Click to sort ascending')}",
204 MSG_SORTASC:"${_('Click to sort ascending')}",
208 MSG_SORTDESC:"${_('Click to sort descending')}",
205 MSG_SORTDESC:"${_('Click to sort descending')}",
209 MSG_EMPTY:"${_('No records found.')}",
206 MSG_EMPTY:"${_('No records found.')}",
210 MSG_ERROR:"${_('Data error.')}",
207 MSG_ERROR:"${_('Data error.')}",
211 MSG_LOADING:"${_('Loading...')}",
208 MSG_LOADING:"${_('Loading...')}",
212 }
209 }
213 );
210 );
214 myDataTable.subscribe('postRenderEvent',function(oArgs) {
211 myDataTable.subscribe('postRenderEvent',function(oArgs) {
215 tooltip_activate();
212 tooltip_activate();
216 quick_repo_menu();
213 quick_repo_menu();
214 var func = function(node){
215 return node.parentNode.parentNode.parentNode.parentNode;
216 }
217 q_filter('q_filter',YUQ('div.table tr td a.repo_name'),func);
217 q_filter('q_filter',YUQ('div.table tr td a.repo_name'),func);
218 });
218 });
219
219
220 </script>
220 </script>
221 % else:
221 % else:
222 <script>
222 <script>
223 //var url = "${h.url('formatted_users', format='json')}";
224 var data = ${c.data|n};
223 var data = ${c.data|n};
225 var myDataSource = new YAHOO.util.DataSource(data);
224 var myDataSource = new YAHOO.util.DataSource(data);
226 myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
225 myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
227
226
228 myDataSource.responseSchema = {
227 myDataSource.responseSchema = {
229 resultsList: "records",
228 resultsList: "records",
230 fields: [
229 fields: [
231 {key:"menu"},
230 {key:"menu"},
232 {key:"raw_name"},
231 {key:"raw_name"},
233 {key:"name"},
232 {key:"name"},
234 {key:"desc"},
233 {key:"desc"},
235 {key:"last_change"},
234 {key:"last_change"},
236 {key: "tip"},
235 {key:"last_changeset"},
237 {key:"owner"},
236 {key:"owner"},
238 {key:"rss"},
237 {key:"rss"},
239 {key:"atom"},
238 {key:"atom"},
240 ]
239 ]
241 };
240 };
242 myDataSource.doBeforeCallback = function(req,raw,res,cb) {
241 myDataSource.doBeforeCallback = function(req,raw,res,cb) {
243 // This is the filter function
242 // This is the filter function
244 var data = res.results || [],
243 var data = res.results || [],
245 filtered = [],
244 filtered = [],
246 i,l;
245 i,l;
247
246
248 if (req) {
247 if (req) {
249 req = req.toLowerCase();
248 req = req.toLowerCase();
250 for (i = 0; i<data.length; i++) {
249 for (i = 0; i<data.length; i++) {
251 var pos = data[i].raw_name.toLowerCase().indexOf(req)
250 var pos = data[i].raw_name.toLowerCase().indexOf(req)
252 if (pos != -1) {
251 if (pos != -1) {
253 filtered.push(data[i]);
252 filtered.push(data[i]);
254 }
253 }
255 }
254 }
256 res.results = filtered;
255 res.results = filtered;
257 }
256 }
258 YUD.get('repo_count').innerHTML = res.results.length;
257 YUD.get('repo_count').innerHTML = res.results.length;
259 return res;
258 return res;
260 }
259 }
261
260
262 // main table sorting
261 // main table sorting
263 var myColumnDefs = [
262 var myColumnDefs = [
264 {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"},
263 {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"},
265 {key:"name",label:"${_('Name')}",sortable:true,
264 {key:"name",label:"${_('Name')}",sortable:true,
266 sortOptions: { sortFunction: nameSort }},
265 sortOptions: { sortFunction: nameSort }},
267 {key:"desc",label:"${_('Description')}",sortable:true},
266 {key:"desc",label:"${_('Description')}",sortable:true},
268 {key:"last_change",label:"${_('Last Change')}",sortable:true,
267 {key:"last_change",label:"${_('Last Change')}",sortable:true,
269 sortOptions: { sortFunction: ageSort }},
268 sortOptions: { sortFunction: ageSort }},
270 {key:"tip",label:"${_('Tip')}",sortable:true,
269 {key:"last_changeset",label:"${_('Tip')}",sortable:true,
271 sortOptions: { sortFunction: revisionSort }},
270 sortOptions: { sortFunction: revisionSort }},
272 {key:"owner",label:"${_('Owner')}",sortable:true},
271 {key:"owner",label:"${_('Owner')}",sortable:true},
273 {key:"rss",label:"",sortable:false},
272 {key:"rss",label:"",sortable:false},
274 {key:"atom",label:"",sortable:false},
273 {key:"atom",label:"",sortable:false},
275 ];
274 ];
276
275
277 var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource,{
276 var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource,{
278 sortedBy:{key:"name",dir:"asc"},
277 sortedBy:{key:"name",dir:"asc"},
279 paginator: new YAHOO.widget.Paginator({
278 paginator: new YAHOO.widget.Paginator({
280 rowsPerPage: ${c.visual.lightweight_dashboard_items},
279 rowsPerPage: ${c.visual.lightweight_dashboard_items},
281 alwaysVisible: false,
280 alwaysVisible: false,
282 template : "{PreviousPageLink} {FirstPageLink} {PageLinks} {LastPageLink} {NextPageLink}",
281 template : "{PreviousPageLink} {FirstPageLink} {PageLinks} {LastPageLink} {NextPageLink}",
283 pageLinks: 5,
282 pageLinks: 5,
284 containerClass: 'pagination-wh',
283 containerClass: 'pagination-wh',
285 currentPageClass: 'pager_curpage',
284 currentPageClass: 'pager_curpage',
286 pageLinkClass: 'pager_link',
285 pageLinkClass: 'pager_link',
287 nextPageLinkLabel: '&gt;',
286 nextPageLinkLabel: '&gt;',
288 previousPageLinkLabel: '&lt;',
287 previousPageLinkLabel: '&lt;',
289 firstPageLinkLabel: '&lt;&lt;',
288 firstPageLinkLabel: '&lt;&lt;',
290 lastPageLinkLabel: '&gt;&gt;',
289 lastPageLinkLabel: '&gt;&gt;',
291 containers:['user-paginator']
290 containers:['user-paginator']
292 }),
291 }),
293
292
294 MSG_SORTASC:"${_('Click to sort ascending')}",
293 MSG_SORTASC:"${_('Click to sort ascending')}",
295 MSG_SORTDESC:"${_('Click to sort descending')}",
294 MSG_SORTDESC:"${_('Click to sort descending')}",
296 MSG_EMPTY:"${_('No records found.')}",
295 MSG_EMPTY:"${_('No records found.')}",
297 MSG_ERROR:"${_('Data error.')}",
296 MSG_ERROR:"${_('Data error.')}",
298 MSG_LOADING:"${_('Loading...')}",
297 MSG_LOADING:"${_('Loading...')}",
299 }
298 }
300 );
299 );
301 myDataTable.subscribe('postRenderEvent',function(oArgs) {
300 myDataTable.subscribe('postRenderEvent',function(oArgs) {
302 tooltip_activate();
301 tooltip_activate();
303 quick_repo_menu();
302 quick_repo_menu();
304 });
303 });
305
304
306 var filterTimeout = null;
305 var filterTimeout = null;
307
306
308 updateFilter = function () {
307 updateFilter = function () {
309 // Reset timeout
308 // Reset timeout
310 filterTimeout = null;
309 filterTimeout = null;
311
310
312 // Reset sort
311 // Reset sort
313 var state = myDataTable.getState();
312 var state = myDataTable.getState();
314 state.sortedBy = {key:'name', dir:YAHOO.widget.DataTable.CLASS_ASC};
313 state.sortedBy = {key:'name', dir:YAHOO.widget.DataTable.CLASS_ASC};
315
314
316 // Get filtered data
315 // Get filtered data
317 myDataSource.sendRequest(YUD.get('q_filter').value,{
316 myDataSource.sendRequest(YUD.get('q_filter').value,{
318 success : myDataTable.onDataReturnInitializeTable,
317 success : myDataTable.onDataReturnInitializeTable,
319 failure : myDataTable.onDataReturnInitializeTable,
318 failure : myDataTable.onDataReturnInitializeTable,
320 scope : myDataTable,
319 scope : myDataTable,
321 argument: state
320 argument: state
322 });
321 });
323
322
324 };
323 };
325 YUE.on('q_filter','click',function(){
324 YUE.on('q_filter','click',function(){
325 if(!YUD.hasClass('q_filter', 'loaded')){
326 YUD.get('q_filter').value = '';
326 YUD.get('q_filter').value = '';
327 //TODO: load here full list later to do search within groups
328 YUD.addClass('q_filter', 'loaded');
329 }
327 });
330 });
328
331
329 YUE.on('q_filter','keyup',function (e) {
332 YUE.on('q_filter','keyup',function (e) {
330 clearTimeout(filterTimeout);
333 clearTimeout(filterTimeout);
331 filterTimeout = setTimeout(updateFilter,600);
334 filterTimeout = setTimeout(updateFilter,600);
332 });
335 });
333 </script>
336 </script>
334 % endif
337 % endif
@@ -1,241 +1,375 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%inherit file="/base/base.html"/>
2 <%inherit file="/base/base.html"/>
3 <%def name="title()">
3 <%def name="title()">
4 ${_('Journal')} - ${c.rhodecode_name}
4 ${_('Journal')} - ${c.rhodecode_name}
5 </%def>
5 </%def>
6 <%def name="breadcrumbs()">
6 <%def name="breadcrumbs()">
7 <h5>
7 <h5>
8 <form id="filter_form">
8 <form id="filter_form">
9 <input class="q_filter_box ${'' if c.search_term else 'initial'}" id="j_filter" size="15" type="text" name="filter" value="${c.search_term or _('quick filter...')}"/>
9 <input class="q_filter_box ${'' if c.search_term else 'initial'}" id="j_filter" size="15" type="text" name="filter" value="${c.search_term or _('quick filter...')}"/>
10 <span class="tooltip" title="${h.tooltip(h.journal_filter_help())}">?</span>
10 <span class="tooltip" title="${h.tooltip(h.journal_filter_help())}">?</span>
11 <input type='submit' value="${_('filter')}" class="ui-btn" style="padding:0px 2px 0px 2px;margin:0px"/>
11 <input type='submit' value="${_('filter')}" class="ui-btn" style="padding:0px 2px 0px 2px;margin:0px"/>
12 ${_('journal')} - ${ungettext('%s entry', '%s entries', c.journal_pager.item_count) % (c.journal_pager.item_count)}
12 ${_('journal')} - ${ungettext('%s entry', '%s entries', c.journal_pager.item_count) % (c.journal_pager.item_count)}
13 </form>
13 </form>
14 ${h.end_form()}
14 ${h.end_form()}
15 </h5>
15 </h5>
16 </%def>
16 </%def>
17 <%def name="page_nav()">
17 <%def name="page_nav()">
18 ${self.menu('home')}
18 ${self.menu('home')}
19 </%def>
19 </%def>
20 <%def name="head_extra()">
20 <%def name="head_extra()">
21 <link href="${h.url('journal_atom', api_key=c.rhodecode_user.api_key)}" rel="alternate" title="${_('ATOM journal feed')}" type="application/atom+xml" />
21 <link href="${h.url('journal_atom', api_key=c.rhodecode_user.api_key)}" rel="alternate" title="${_('ATOM journal feed')}" type="application/atom+xml" />
22 <link href="${h.url('journal_rss', api_key=c.rhodecode_user.api_key)}" rel="alternate" title="${_('RSS journal feed')}" type="application/rss+xml" />
22 <link href="${h.url('journal_rss', api_key=c.rhodecode_user.api_key)}" rel="alternate" title="${_('RSS journal feed')}" type="application/rss+xml" />
23 </%def>
23 </%def>
24 <%def name="main()">
24 <%def name="main()">
25
25
26 <div class="box box-left">
26 <div class="box box-left">
27 <!-- box / title -->
27 <!-- box / title -->
28 <div class="title">
28 <div class="title">
29 ${self.breadcrumbs()}
29 ${self.breadcrumbs()}
30 <ul class="links">
30 <ul class="links">
31 <li>
31 <li>
32 <span><a id="refresh" href="${h.url('journal')}"><img class="icon" title="${_('Refresh')}" alt="${_('Refresh')}" src="${h.url('/images/icons/arrow_refresh.png')}"/></a></span>
32 <span><a id="refresh" href="${h.url('journal')}"><img class="icon" title="${_('Refresh')}" alt="${_('Refresh')}" src="${h.url('/images/icons/arrow_refresh.png')}"/></a></span>
33 </li>
33 </li>
34 <li>
34 <li>
35 <span><a href="${h.url('journal_rss', api_key=c.rhodecode_user.api_key)}"><img class="icon" title="${_('RSS feed')}" alt="${_('RSS feed')}" src="${h.url('/images/icons/rss_16.png')}"/></a></span>
35 <span><a href="${h.url('journal_rss', api_key=c.rhodecode_user.api_key)}"><img class="icon" title="${_('RSS feed')}" alt="${_('RSS feed')}" src="${h.url('/images/icons/rss_16.png')}"/></a></span>
36 </li>
36 </li>
37 <li>
37 <li>
38 <span><a href="${h.url('journal_atom', api_key=c.rhodecode_user.api_key)}"><img class="icon" title="${_('ATOM feed')}" alt="${_('ATOM feed')}" src="${h.url('/images/icons/atom.png')}"/></a></span>
38 <span><a href="${h.url('journal_atom', api_key=c.rhodecode_user.api_key)}"><img class="icon" title="${_('ATOM feed')}" alt="${_('ATOM feed')}" src="${h.url('/images/icons/atom.png')}"/></a></span>
39 </li>
39 </li>
40 </ul>
40 </ul>
41 </div>
41 </div>
42 <div id="journal">${c.journal_data}</div>
42 <div id="journal">${c.journal_data}</div>
43 </div>
43 </div>
44 <div class="box box-right">
44 <div class="box box-right">
45 <!-- box / title -->
45 <!-- box / title -->
46
46 <div class="title">
47 <div class="title">
47 <h5>
48 <h5>
48 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" value="${_('quick filter...')}"/>
49 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" value="${_('quick filter...')}" style="display: none"/>
49 <a id="show_watched" class="link-white" href="#watched">${_('Watched')}</a> / <a id="show_my" class="link-white" href="#my">${_('My repos')}</a>
50 <input class="q_filter_box" id="q_filter_watched" size="15" type="text" name="filter" value="${_('quick filter...')}" style="display: none"/>
50 </h5>
51 </h5>
51 %if h.HasPermissionAny('hg.admin','hg.create.repository')():
52 <ul class="links" style="color:#DADADA">
52 <ul class="links">
53 <li>
53 <li>
54 <span>${h.link_to(_('ADD'),h.url('admin_settings_create_repository'))}</span>
54 <span><a id="show_watched" class="link-white current" href="#watched">${_('Watched')}</a> </span>
55 </li>
55 </li>
56 </ul>
56 <li>
57 <span><a id="show_my" class="link-white" href="#my">${_('My repos')}</a> </span>
58 </li>
59 %if h.HasPermissionAny('hg.admin','hg.create.repository')():
60 <li>
61 <span>${h.link_to(_('Add repo'),h.url('admin_settings_create_repository'))}</span>
62 </li>
57 %endif
63 %endif
58 </div>
64 </ul>
59 <!-- end box / title -->
60 <div id="my" class="table" style="display:none">
61 ## loaded via AJAX
62 ${_('Loading...')}
63 </div>
65 </div>
64
66
65 <div id="watched" class="table">
67 <!-- end box / title -->
66 %if c.following:
68 <div id="my_container" style="display:none">
67 <table>
69 <div class="table yui-skin-sam" id="repos_list_wrap"></div>
68 <thead>
70 <div id="user-paginator" style="padding: 0px 0px 0px 20px"></div>
69 <tr>
70 <th class="left">${_('Name')}</th>
71 </thead>
72 <tbody>
73 %for entry in c.following:
74 <tr>
75 <td>
76 %if entry.follows_user_id:
77 <img title="${_('following user')}" alt="${_('user')}" src="${h.url('/images/icons/user.png')}"/>
78 ${entry.follows_user.full_contact}
79 %endif
80
81 %if entry.follows_repo_id:
82 <div style="float:right;padding-right:5px">
83 <span id="follow_toggle_${entry.follows_repository.repo_id}" class="following" title="${_('Stop following this repository')}"
84 onclick="javascript:toggleFollowingRepo(this,${entry.follows_repository.repo_id},'${str(h.get_token())}')">
85 </span>
86 </div>
71 </div>
87
72
88 %if h.is_hg(entry.follows_repository):
73 <div id="watched_container">
89 <img class="icon" title="${_('Mercurial repository')}" alt="${_('Mercurial repository')}" src="${h.url('/images/icons/hgicon.png')}"/>
74 <div class="table yui-skin-sam" id="watched_repos_list_wrap"></div>
90 %elif h.is_git(entry.follows_repository):
75 <div id="watched-user-paginator" style="padding: 0px 0px 0px 20px"></div>
91 <img class="icon" title="${_('Git repository')}" alt="${_('Git repository')}" src="${h.url('/images/icons/giticon.png')}"/>
92 %endif
93
94 %if entry.follows_repository.private and c.visual.show_private_icon:
95 <img class="icon" title="${_('private repository')}" alt="${_('private repository')}" src="${h.url('/images/icons/lock.png')}"/>
96 %elif not entry.follows_repository.private and c.visual.show_public_icon:
97 <img class="icon" title="${_('public repository')}" alt="${_('public repository')}" src="${h.url('/images/icons/lock_open.png')}"/>
98 %endif
99 <span class="watched_repo">
100 ${h.link_to(entry.follows_repository.repo_name,h.url('summary_home',repo_name=entry.follows_repository.repo_name))}
101 </span>
102 %endif
103 </td>
104 </tr>
105 %endfor
106 </tbody>
107 </table>
108 %else:
109 <div style="padding:5px 0px 10px 0px;">
110 ${_('You are not following any users or repositories')}
111 </div>
112 %endif
113 </div>
76 </div>
114 </div>
77 </div>
115
78
116 <script type="text/javascript">
79 <script type="text/javascript">
117
80
118 YUE.on('j_filter','click',function(){
81 YUE.on('j_filter','click',function(){
119 var jfilter = YUD.get('j_filter');
82 var jfilter = YUD.get('j_filter');
120 if(YUD.hasClass(jfilter, 'initial')){
83 if(YUD.hasClass(jfilter, 'initial')){
121 jfilter.value = '';
84 jfilter.value = '';
122 }
85 }
123 });
86 });
124 var fix_j_filter_width = function(len){
87 var fix_j_filter_width = function(len){
125 YUD.setStyle(YUD.get('j_filter'),'width',Math.max(80, len*6.50)+'px');
88 YUD.setStyle(YUD.get('j_filter'),'width',Math.max(80, len*6.50)+'px');
126 }
89 }
127 YUE.on('j_filter','keyup',function(){
90 YUE.on('j_filter','keyup',function(){
128 fix_j_filter_width(YUD.get('j_filter').value.length);
91 fix_j_filter_width(YUD.get('j_filter').value.length);
129 });
92 });
130 YUE.on('filter_form','submit',function(e){
93 YUE.on('filter_form','submit',function(e){
131 YUE.preventDefault(e)
94 YUE.preventDefault(e)
132 var val = YUD.get('j_filter').value;
95 var val = YUD.get('j_filter').value;
133 window.location = "${url.current(filter='__FILTER__')}".replace('__FILTER__',val);
96 window.location = "${url.current(filter='__FILTER__')}".replace('__FILTER__',val);
134 });
97 });
135 fix_j_filter_width(YUD.get('j_filter').value.length);
98 fix_j_filter_width(YUD.get('j_filter').value.length);
136
99
137 var show_my = function(e){
100 YUE.on('refresh','click',function(e){
138 YUD.setStyle('watched','display','none');
101 ypjax("${h.url.current(filter=c.search_term)}","journal",function(){
139 YUD.setStyle('my','display','');
102 show_more_event();
140
141 var url = "${h.url('admin_settings_my_repos')}";
142 ypjax(url, 'my', function(){
143 tooltip_activate();
103 tooltip_activate();
144 quick_repo_menu();
104 show_changeset_tooltip();
145 var nodes = YUQ('#my tr td a.repo_name');
105 });
146 var func = function(node){
106 YUE.preventDefault(e);
147 return node.parentNode.parentNode.parentNode;
148 }
149 q_filter('q_filter',nodes,func);
150 });
107 });
151
108
109 var show_my = function(e){
110 YUD.setStyle('watched_container','display','none');
111 YUD.setStyle('my_container','display','');
112 YUD.setStyle('q_filter','display','');
113 YUD.setStyle('q_filter_watched','display','none');
114
115 YUD.addClass('show_my', 'current');
116 YUD.removeClass('show_watched','current');
117
118 if(!YUD.hasClass('show_my', 'loaded')){
119 table_renderer(${c.data |n});
120 YUD.addClass('show_my', 'loaded');
121 }
152 }
122 }
153 YUE.on('show_my','click',function(e){
123 YUE.on('show_my','click',function(e){
154 show_my(e);
124 show_my(e);
155 })
125 })
156 var show_watched = function(e){
126 var show_watched = function(e){
157 YUD.setStyle('my','display','none');
127 YUD.setStyle('my_container','display','none');
158 YUD.setStyle('watched','display','');
128 YUD.setStyle('watched_container','display','');
159 var nodes = YUQ('#watched .watched_repo a');
129 YUD.setStyle('q_filter_watched','display','');
130 YUD.setStyle('q_filter','display','none');
131
132 YUD.addClass('show_watched', 'current');
133 YUD.removeClass('show_my','current');
134 if(!YUD.hasClass('show_watched', 'loaded')){
135 watched_renderer(${c.watched_data |n});
136 YUD.addClass('show_watched', 'loaded');
137 }
138
139 return
140 var nodes = YUQ('#watched_container .watched_repo a');
160 var target = 'q_filter';
141 var target = 'q_filter';
161 var func = function(node){
142 var func = function(node){
162 return node.parentNode.parentNode;
143 return node.parentNode.parentNode;
163 }
144 }
164 q_filter(target,nodes,func);
145 q_filter(target,nodes,func);
165 }
146 }
166 YUE.on('show_watched','click',function(e){
147 YUE.on('show_watched','click',function(e){
167 show_watched(e);
148 show_watched(e);
168 })
149 })
169 //init watched
150 //init watched
170 show_watched();
151 show_watched();
171
152
172 var tabs = {
153 var tabs = {
173 'watched': show_watched,
154 'watched': show_watched,
174 'my': show_my,
155 'my': show_my,
175 }
156 }
176 var url = location.href.split('#');
157 var url = location.href.split('#');
177 if (url[1]) {
158 if (url[1]) {
178 //We have a hash
159 //We have a hash
179 var tabHash = url[1];
160 var tabHash = url[1];
180 var func = tabs[tabHash]
161 var func = tabs[tabHash]
181 if (func){
162 if (func){
182 func();
163 func();
183 }
164 }
184 }
165 }
166 function watched_renderer(data){
167 var myDataSource = new YAHOO.util.DataSource(data);
168 myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
185
169
186 YUE.on('refresh','click',function(e){
170 myDataSource.responseSchema = {
187 ypjax("${h.url.current(filter=c.search_term)}","journal",function(){
171 resultsList: "records",
188 show_more_event();
172 fields: [
189 tooltip_activate();
173 {key:"menu"},
190 show_changeset_tooltip();
174 {key:"raw_name"},
191 });
175 {key:"name"},
192 YUE.preventDefault(e);
176 {key:"last_changeset"},
193 });
177 {key:"action"},
178 ]
179 };
180 myDataSource.doBeforeCallback = function(req,raw,res,cb) {
181 // This is the filter function
182 var data = res.results || [],
183 filtered = [],
184 i,l;
194
185
195
186 if (req) {
187 req = req.toLowerCase();
188 for (i = 0; i<data.length; i++) {
189 var pos = data[i].raw_name.toLowerCase().indexOf(req)
190 if (pos != -1) {
191 filtered.push(data[i]);
192 }
193 }
194 res.results = filtered;
195 }
196 return res;
197 }
196 // main table sorting
198 // main table sorting
197 var myColumnDefs = [
199 var myColumnDefs = [
198 {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"},
200 {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"},
199 {key:"name",label:"${_('Name')}",sortable:true,
201 {key:"name",label:"${_('Name')}",sortable:true,
200 sortOptions: { sortFunction: nameSort }},
202 sortOptions: { sortFunction: nameSort }},
201 {key:"tip",label:"${_('Tip')}",sortable:true,
203 {key:"last_changeset",label:"${_('Tip')}",sortable:true,
202 sortOptions: { sortFunction: revisionSort }},
204 sortOptions: { sortFunction: revisionSort }},
203 {key:"action1",label:"",sortable:false},
205 {key:"action",label:"${_('Action')}",sortable:false},
204 {key:"action2",label:"",sortable:false},
205 ];
206 ];
206
207
207 var myDataSource = new YAHOO.util.DataSource(YUD.get("repos_list"));
208 var myDataTable = new YAHOO.widget.DataTable("watched_repos_list_wrap", myColumnDefs, myDataSource,{
208
209 sortedBy:{key:"name",dir:"asc"},
209 myDataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
210 paginator: new YAHOO.widget.Paginator({
211 rowsPerPage: 25,
212 alwaysVisible: false,
213 template : "{PreviousPageLink} {FirstPageLink} {PageLinks} {LastPageLink} {NextPageLink}",
214 pageLinks: 5,
215 containerClass: 'pagination-wh',
216 currentPageClass: 'pager_curpage',
217 pageLinkClass: 'pager_link',
218 nextPageLinkLabel: '&gt;',
219 previousPageLinkLabel: '&lt;',
220 firstPageLinkLabel: '&lt;&lt;',
221 lastPageLinkLabel: '&gt;&gt;',
222 containers:['watched-user-paginator']
223 }),
210
224
211 myDataSource.responseSchema = {
212 fields: [
213 {key:"menu"},
214 {key:"name"},
215 {key:"tip"},
216 {key:"action1"},
217 {key:"action2"}
218 ]
219 };
220
221 var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource,
222 {
223 sortedBy:{key:"name",dir:"asc"},
224 MSG_SORTASC:"${_('Click to sort ascending')}",
225 MSG_SORTASC:"${_('Click to sort ascending')}",
225 MSG_SORTDESC:"${_('Click to sort descending')}",
226 MSG_SORTDESC:"${_('Click to sort descending')}",
226 MSG_EMPTY:"${_('No records found.')}",
227 MSG_EMPTY:"${_('No records found.')}",
227 MSG_ERROR:"${_('Data error.')}",
228 MSG_ERROR:"${_('Data error.')}",
228 MSG_LOADING:"${_('Loading...')}",
229 MSG_LOADING:"${_('Loading...')}",
229 }
230 }
230 );
231 );
231 myDataTable.subscribe('postRenderEvent',function(oArgs) {
232 myDataTable.subscribe('postRenderEvent',function(oArgs) {
232 tooltip_activate();
233 tooltip_activate();
233 quick_repo_menu();
234 quick_repo_menu();
234 var func = function(node){
235 });
235 return node.parentNode.parentNode.parentNode.parentNode;
236
237 var filterTimeout = null;
238
239 updateFilter = function () {
240 // Reset timeout
241 filterTimeout = null;
242
243 // Reset sort
244 var state = myDataTable.getState();
245 state.sortedBy = {key:'name', dir:YAHOO.widget.DataTable.CLASS_ASC};
246
247 // Get filtered data
248 myDataSource.sendRequest(YUD.get('q_filter_watched').value,{
249 success : myDataTable.onDataReturnInitializeTable,
250 failure : myDataTable.onDataReturnInitializeTable,
251 scope : myDataTable,
252 argument: state
253 });
254
255 };
256 YUE.on('q_filter_watched','click',function(){
257 if(!YUD.hasClass('q_filter_watched', 'loaded')){
258 YUD.get('q_filter_watched').value = '';
259 //TODO: load here full list later to do search within groups
260 YUD.addClass('q_filter_watched', 'loaded');
261 }
262 });
263
264 YUE.on('q_filter_watched','keyup',function (e) {
265 clearTimeout(filterTimeout);
266 filterTimeout = setTimeout(updateFilter,600);
267 });
268 }
269
270 function table_renderer(data){
271 var myDataSource = new YAHOO.util.DataSource(data);
272 myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
273
274 myDataSource.responseSchema = {
275 resultsList: "records",
276 fields: [
277 {key:"menu"},
278 {key:"raw_name"},
279 {key:"name"},
280 {key:"last_changeset"},
281 {key:"action"},
282 ]
283 };
284 myDataSource.doBeforeCallback = function(req,raw,res,cb) {
285 // This is the filter function
286 var data = res.results || [],
287 filtered = [],
288 i,l;
289
290 if (req) {
291 req = req.toLowerCase();
292 for (i = 0; i<data.length; i++) {
293 var pos = data[i].raw_name.toLowerCase().indexOf(req)
294 if (pos != -1) {
295 filtered.push(data[i]);
296 }
297 }
298 res.results = filtered;
299 }
300 return res;
236 }
301 }
237 q_filter('q_filter',YUQ('#my tr td a.repo_name'),func);
302 // main table sorting
303 var myColumnDefs = [
304 {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"},
305 {key:"name",label:"${_('Name')}",sortable:true,
306 sortOptions: { sortFunction: nameSort }},
307 {key:"last_changeset",label:"${_('Tip')}",sortable:true,
308 sortOptions: { sortFunction: revisionSort }},
309 {key:"action",label:"${_('Action')}",sortable:false},
310 ];
311
312 var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource,{
313 sortedBy:{key:"name",dir:"asc"},
314 paginator: new YAHOO.widget.Paginator({
315 rowsPerPage: 25,
316 alwaysVisible: false,
317 template : "{PreviousPageLink} {FirstPageLink} {PageLinks} {LastPageLink} {NextPageLink}",
318 pageLinks: 5,
319 containerClass: 'pagination-wh',
320 currentPageClass: 'pager_curpage',
321 pageLinkClass: 'pager_link',
322 nextPageLinkLabel: '&gt;',
323 previousPageLinkLabel: '&lt;',
324 firstPageLinkLabel: '&lt;&lt;',
325 lastPageLinkLabel: '&gt;&gt;',
326 containers:['user-paginator']
327 }),
328
329 MSG_SORTASC:"${_('Click to sort ascending')}",
330 MSG_SORTDESC:"${_('Click to sort descending')}",
331 MSG_EMPTY:"${_('No records found.')}",
332 MSG_ERROR:"${_('Data error.')}",
333 MSG_LOADING:"${_('Loading...')}",
334 }
335 );
336 myDataTable.subscribe('postRenderEvent',function(oArgs) {
337 tooltip_activate();
338 quick_repo_menu();
238 });
339 });
239
340
341 var filterTimeout = null;
342
343 updateFilter = function () {
344 // Reset timeout
345 filterTimeout = null;
346
347 // Reset sort
348 var state = myDataTable.getState();
349 state.sortedBy = {key:'name', dir:YAHOO.widget.DataTable.CLASS_ASC};
350
351 // Get filtered data
352 myDataSource.sendRequest(YUD.get('q_filter').value,{
353 success : myDataTable.onDataReturnInitializeTable,
354 failure : myDataTable.onDataReturnInitializeTable,
355 scope : myDataTable,
356 argument: state
357 });
358
359 };
360 YUE.on('q_filter','click',function(){
361 if(!YUD.hasClass('q_filter', 'loaded')){
362 YUD.get('q_filter').value = '';
363 //TODO: load here full list later to do search within groups
364 YUD.addClass('q_filter', 'loaded');
365 }
366 });
367
368 YUE.on('q_filter','keyup',function (e) {
369 clearTimeout(filterTimeout);
370 filterTimeout = setTimeout(updateFilter,600);
371 });
372 }
373
240 </script>
374 </script>
241 </%def>
375 </%def>
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now