Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

master merged

  • Loading branch information...
commit e6ce47291b3f08ebe18c2450fc4f21a2a3a2b8a9 2 parents 77bfc59 + 6104942
@AlexDenisov AlexDenisov authored
Showing with 4,220 additions and 2,126 deletions.
  1. +30 −0 CONTRIBUTING.md
  2. +22 −3 Gemfile
  3. +60 −19 Gemfile.lock
  4. +26 −0 Guardfile
  5. +4 −0 app/assets/javascripts/admin.js.coffee
  6. +1 −1  app/assets/javascripts/application.js
  7. +3 −0  app/assets/javascripts/main.js.coffee
  8. +0 −182 app/assets/javascripts/note.js
  9. +293 −0 app/assets/javascripts/notes.js
  10. +5 −1 app/assets/javascripts/projects.js.coffee
  11. +99 −10 app/assets/stylesheets/common.scss
  12. +8 −0 app/assets/stylesheets/gitlab_bootstrap/blocks.scss
  13. +33 −1 app/assets/stylesheets/gitlab_bootstrap/common.scss
  14. +5 −1 app/assets/stylesheets/main.scss
  15. +19 −9 app/assets/stylesheets/ref_select.scss
  16. +28 −27 app/assets/stylesheets/sections/issues.scss
  17. +27 −28 app/assets/stylesheets/sections/merge_requests.scss
  18. +0 −1  app/assets/stylesheets/sections/nav.scss
  19. +19 −10 app/assets/stylesheets/sections/notes.scss
  20. +8 −0 app/assets/stylesheets/sections/profile.scss
  21. +17 −16 app/contexts/notes/load_context.rb
  22. +1 −5 app/controllers/admin/dashboard_controller.rb
  23. +2 −6 app/controllers/admin/hooks_controller.rb
  24. +1 −5 app/controllers/admin/logs_controller.rb
  25. +3 −6 app/controllers/admin/projects_controller.rb
  26. +2 −3 app/controllers/admin/resque_controller.rb
  27. +1 −5 app/controllers/admin/team_members_controller.rb
  28. +6 −10 app/controllers/admin/users_controller.rb
  29. +11 −0 app/controllers/admin_controller.rb
  30. +0 −4 app/controllers/application_controller.rb
  31. +1 −1  app/controllers/commits_controller.rb
  32. +1 −3 app/controllers/issues_controller.rb
  33. +29 −1 app/controllers/omniauth_callbacks_controller.rb
  34. +6 −5 app/controllers/profile_controller.rb
  35. +7 −4 app/controllers/team_members_controller.rb
  36. +1 −1  app/decorators/commit_decorator.rb
  37. +9 −2 app/helpers/application_helper.rb
  38. +3 −1 app/helpers/gitlab_markdown_helper.rb
  39. +17 −0 app/helpers/notes_helper.rb
  40. +7 −0 app/helpers/profile_helper.rb
  41. +4 −0 app/helpers/projects_helper.rb
  42. +1 −1  app/helpers/tab_helper.rb
  43. +2 −1  app/helpers/tree_helper.rb
  44. +22 −14 app/models/event.rb
  45. +1 −1  app/models/issue.rb
  46. +1 −1  app/models/merge_request.rb
  47. +7 −1 app/models/note.rb
  48. +4 −0 app/models/project.rb
  49. +1 −1  app/models/tree.rb
  50. +14 −28 app/models/user.rb
  51. +0 −1  app/models/wiki.rb
  52. +12 −0 app/observers/project_observer.rb
  53. +12 −0 app/observers/user_observer.rb
  54. +2 −2 app/observers/users_project_observer.rb
  55. +0 −6 app/roles/upvote.rb
  56. +32 −0 app/roles/votes.rb
  57. +26 −9 app/views/admin/logs/show.html.haml
  58. +1 −2  app/views/admin/projects/_form.html.haml
  59. +2 −16 app/views/admin/projects/show.html.haml
  60. +4 −2 app/views/admin/resque/show.html.haml
  61. +1 −12 app/views/admin/team_members/_form.html.haml
  62. +2 −16 app/views/admin/users/show.html.haml
  63. +2 −2 app/views/commits/_commit_box.html.haml
  64. +1 −11 app/views/commits/_head.html.haml
  65. +3 −6 app/views/commits/_text_file.html.haml
  66. +1 −1  app/views/commits/show.html.haml
  67. +7 −1 app/views/dashboard/index.html.haml
  68. +1 −1  app/views/devise/sessions/_new_ldap.html.haml
  69. +3 −3 app/views/devise/sessions/new.html.haml
  70. +1 −1  app/views/events/_commit.html.haml
  71. +1 −1  app/views/events/_event_last_push.html.haml
  72. +1 −1  app/views/events/_event_membership_changed.html.haml
  73. +2 −2 app/views/issues/_form.html.haml
  74. +3 −3 app/views/issues/_show.html.haml
  75. +0 −7 app/views/issues/edit.html.haml
  76. +1 −1  app/views/issues/index.html.haml
  77. +0 −7 app/views/issues/new.html.haml
  78. +8 −8 app/views/issues/show.html.haml
  79. +7 −2 app/views/labels/_label.html.haml
  80. +5 −5 app/views/layouts/profile.html.haml
  81. +3 −10 app/views/merge_requests/_form.html.haml
  82. +3 −2 app/views/merge_requests/_merge_request.html.haml
  83. +2 −2 app/views/merge_requests/_show.html.haml
  84. +4 −0 app/views/merge_requests/diffs.html.haml
  85. +3 −0  app/views/merge_requests/diffs.js.haml
  86. +1 −1  app/views/merge_requests/show.js.haml
  87. +1 −1  app/views/merge_requests/show/_mr_box.html.haml
  88. +2 −4 app/views/merge_requests/show/_mr_title.html.haml
  89. +0 −6 app/views/milestones/edit.html.haml
  90. +1 −1  app/views/milestones/show.html.haml
  91. +1 −1  app/views/notes/{_form.html.haml → _common_form.html.haml}
  92. +3 −2 app/views/notes/{_create_common.js.haml → _create_common_note.js.haml}
  93. +0 −8 app/views/notes/_create_line.js.haml
  94. +19 −0 app/views/notes/_create_per_line_note.js.haml
  95. +0 −17 app/views/notes/_load.js.haml
  96. +10 −2 app/views/notes/{_show.html.haml → _note.html.haml}
  97. +3 −12 app/views/notes/_notes.html.haml
  98. +0 −4 app/views/notes/_notes_list.html.haml
  99. +11 −0 app/views/notes/_notes_with_form.html.haml
  100. +5 −0 app/views/notes/_per_line_note.html.haml
  101. +1 −0  app/views/notes/_per_line_note_link.html.haml
  102. +3 −0  app/views/notes/_per_line_notes_with_reply.html.haml
  103. +4 −0 app/views/notes/_per_line_reply_button.html.haml
  104. +0 −5 app/views/notes/_per_line_show.html.haml
  105. +0 −4 app/views/notes/_reply_button.html.haml
  106. +11 −0 app/views/notes/_reversed_notes_with_form.html.haml
  107. +2 −2 app/views/notes/create.js.haml
  108. +17 −1 app/views/notes/index.js.haml
  109. +57 −0 app/views/profile/account.html.haml
  110. +5 −0 app/views/profile/history.html.haml
  111. +0 −19 app/views/profile/password.html.haml
  112. +33 −21 app/views/profile/show.html.haml
  113. +0 −23 app/views/profile/token.html.haml
  114. +2 −2 app/views/projects/_project_head.html.haml
  115. +0 −8 app/views/projects/_refs.html.haml
  116. +3 −3 app/views/projects/edit.html.haml
  117. +1 −1  app/views/projects/wall.html.haml
  118. +1 −4 app/views/protected_branches/index.html.haml
  119. +1 −4 app/views/refs/_head.html.haml
  120. +6 −8 app/views/refs/_tree.html.haml
  121. +1 −1  app/views/refs/_tree_file.html.haml
  122. +0 −5 app/views/refs/blame.html.haml
  123. +1 −1  app/views/repositories/_branch.html.haml
  124. +1 −1  app/views/repositories/_feed.html.haml
  125. +1 −1  app/views/repositories/tags.html.haml
  126. +11 −8 app/views/search/show.html.haml
  127. +5 −0 app/views/shared/_ref_switcher.html.haml
  128. +1 −9 app/views/snippets/_form.html.haml
  129. +1 −1  app/views/snippets/show.html.haml
  130. +4 −11 app/views/team_members/_form.html.haml
  131. +13 −7 app/views/team_members/_show.html.haml
  132. 0  app/views/{projects → team_members}/_team.html.haml
  133. +2 −4 app/views/{projects/team.html.haml → team_members/index.html.haml}
  134. +1 −1  app/views/team_members/show.html.haml
  135. +6 −0 app/views/votes/_votes_block.html.haml
  136. +6 −0 app/views/votes/_votes_inline.html.haml
  137. +1 −1  app/views/wikis/show.html.haml
  138. +0 −8 config/cucumber.yml
  139. +36 −1 config/gitlab.yml.example
  140. +21 −5 config/initializers/1_settings.rb
  141. +17 −0 config/initializers/devise.rb
  142. +0 −15 config/initializers/omniauth.rb.sample
  143. +8 −0 config/initializers/resque.rb
  144. +3 −0  config/resque.yml.example
  145. +55 −53 config/routes.rb
  146. 0  config/{unicorn.rb.orig → unicorn.rb.example}
  147. +1 −0  doc/api/README.md
  148. +79 −0 doc/api/keys.md
  149. +44 −0 doc/api/projects.md
  150. +3 −3 doc/development.md
  151. +16 −2 doc/installation.md
  152. +3 −4 features/dashboard/dashboard.feature
  153. +3 −3 features/dashboard/issues.feature
  154. +4 −4 features/dashboard/merge_requests.feature
  155. +4 −6 features/dashboard/search.feature
  156. +4 −4 features/profile/profile.feature
  157. +5 −8 features/profile/ssh_keys.feature
  158. +9 −6 features/{projects → project}/commits/branches.feature
  159. +3 −3 features/{projects → project}/commits/commit_comments.feature
  160. +4 −5 features/{projects → project}/commits/commits.feature
  161. +5 −4 features/{projects → project}/commits/tags.feature
  162. +1 −1  features/{projects → project}/create_project.feature
  163. +2 −3 features/{projects → project}/issues/issues.feature
  164. +10 −0 features/project/issues/labels.feature
  165. +3 −3 features/{projects → project}/issues/milestones.feature
  166. +3 −3 features/{projects → project}/merge_requests.feature
  167. +2 −3 features/{projects → project}/network.feature
  168. +14 −0 features/project/project.feature
  169. +6 −8 features/{projects → project}/source/browse_files.feature
  170. +10 −0 features/project/source/git_blame.feature
  171. +7 −8 features/{projects → project}/team_management.feature
  172. +5 −6 features/{projects → project}/wall.feature
  173. +3 −3 features/{projects → project}/wiki.feature
  174. 0  features/projects/deploy_keys.feature
  175. +0 −13 features/projects/issues/labels.feature
  176. +0 −11 features/projects/project.feature
  177. 0  features/projects/snippets.feature
  178. +0 −10 features/projects/source/git_blame.feature
  179. 0  features/projects/web_hooks.feature
  180. +0 −21 features/step_definitions/common_steps.rb
  181. +0 −136 features/step_definitions/dashboard_steps.rb
  182. +0 −34 features/step_definitions/profile/profile_keys_steps.rb
  183. +0 −39 features/step_definitions/profile/profile_steps.rb
  184. +0 −38 features/step_definitions/project/browse_code_steps.rb
  185. +0 −64 features/step_definitions/project/project_commits_steps.rb
  186. +0 −81 features/step_definitions/project/project_issues_steps.rb
  187. +0 −38 features/step_definitions/project/project_merge_requests_steps.rb
  188. +0 −33 features/step_definitions/project/project_milestones_steps.rb
  189. +0 −55 features/step_definitions/project/project_team_steps.rb
  190. +0 −14 features/step_definitions/project/project_wiki_steps.rb
  191. +0 −77 features/step_definitions/project/projects_steps.rb
  192. +0 −91 features/step_definitions/visit_steps.rb
  193. +92 −0 features/steps/dashboard/dashboard.rb
  194. +19 −0 features/steps/dashboard/dashboard_issues.rb
  195. +23 −0 features/steps/dashboard/dashboard_merge_requests.rb
  196. +18 −0 features/steps/dashboard/dashboard_search.rb
  197. +44 −0 features/steps/profile/profile.rb
  198. +48 −0 features/steps/profile/profile_ssh_keys.rb
  199. +22 −0 features/steps/project/create_project.rb
  200. +5 −0 features/steps/project/project.rb
  201. +35 −0 features/steps/project/project_browse_branches.rb
  202. +47 −0 features/steps/project/project_browse_commits.rb
  203. +34 −0 features/steps/project/project_browse_files.rb
  204. +19 −0 features/steps/project/project_browse_git_repo.rb
  205. +10 −0 features/steps/project/project_browse_tags.rb
  206. +6 −0 features/steps/project/project_comment_commit.rb
  207. +134 −0 features/steps/project/project_issues.rb
  208. +24 −0 features/steps/project/project_labels.rb
  209. +80 −0 features/steps/project/project_merge_requests.rb
  210. +39 −0 features/steps/project/project_milestones.rb
  211. +22 −0 features/steps/project/project_network_graph.rb
  212. +89 −0 features/steps/project/project_team_management.rb
  213. +6 −0 features/steps/project/project_wall.rb
  214. +20 −0 features/steps/project/project_wiki.rb
  215. +10 −0 features/steps/shared/authentication.rb
  216. +21 −0 features/steps/shared/note.rb
  217. +112 −0 features/steps/shared/paths.rb
  218. +8 −0 features/steps/shared/project.rb
  219. +16 −48 features/support/env.rb
  220. +1 −0  lib/api.rb
  221. +10 −0 lib/api/entities.rb
  222. +36 −3 lib/api/helpers.rb
  223. +9 −21 lib/api/issues.rb
  224. +50 −0 lib/api/keys.rb
  225. +6 −16 lib/api/milestones.rb
  226. +66 −25 lib/api/projects.rb
  227. +11 −0 lib/gitlab/app_logger.rb
  228. +66 −0 lib/gitlab/auth.rb
  229. +8 −4 lib/gitlab/backend/gitolite_config.rb
  230. +8 −7 lib/gitlab/backend/grack_auth.rb
  231. +11 −0 lib/gitlab/git_logger.rb
  232. +3 −1 lib/gitlab/graph_commit.rb
  233. +2 −6 lib/gitlab/logger.rb
  234. +20 −8 lib/gitlab/markdown.rb
  235. +0 −65 lib/tasks/cucumber.rake
  236. +2 −3 lib/tasks/gitlab/test.rake
  237. +1 −1  lib/tasks/travis.rake
  238. +0 −10 script/cucumber
  239. +9 −1 spec/helpers/gitlab_markdown_helper_spec.rb
  240. +95 −0 spec/lib/auth_spec.rb
  241. +20 −21 spec/models/event_spec.rb
  242. +1 −1  spec/models/issue_spec.rb
  243. +1 −1  spec/models/merge_request_spec.rb
  244. +15 −8 spec/models/note_spec.rb
  245. +6 −1 spec/observers/user_observer_spec.rb
  246. +16 −12 spec/observers/users_project_observer_spec.rb
  247. +6 −4 spec/requests/api/issues_spec.rb
  248. +38 −5 spec/requests/api/projects_spec.rb
  249. +73 −0 spec/requests/api/ssh_keys_spec.rb
  250. +6 −4 spec/requests/api/users_spec.rb
  251. +13 −32 spec/requests/atom/dashboard_issues_spec.rb
  252. +12 −18 spec/requests/atom/dashboard_spec.rb
  253. +25 −31 spec/requests/atom/issues_spec.rb
  254. +1 −0  spec/requests/gitlab_flavored_markdown_spec.rb
  255. +2 −2 spec/requests/security/profile_access_spec.rb
  256. +1 −1  spec/requests/security/project_access_spec.rb
  257. +0 −27 spec/roles/upvote_spec.rb
  258. +132 −0 spec/roles/votes_spec.rb
  259. +166 −0 spec/routing/admin_routing_spec.rb
  260. +398 −0 spec/routing/project_routing_spec.rb
  261. +186 −0 spec/routing/routing_spec.rb
  262. +4 −30 spec/support/gitolite_stub.rb
  263. +1 −5 spec/support/matchers.rb
  264. BIN  vendor/assets/images/authbuttons/github_32.png
  265. BIN  vendor/assets/images/authbuttons/github_64.png
  266. BIN  vendor/assets/images/authbuttons/google_32.png
  267. BIN  vendor/assets/images/authbuttons/google_64.png
  268. BIN  vendor/assets/images/authbuttons/twitter_32.png
  269. BIN  vendor/assets/images/authbuttons/twitter_64.png
View
30 CONTRIBUTING.md
@@ -0,0 +1,30 @@
+## Contribute to GitLab
+
+If you want to contribute to GitLab, follow this process:
+
+1. Fork the project
+2. Create a feature branch
+3. Code
+4. Create a pull request
+
+We only accept pull requests if:
+
+* Your code has proper tests and all tests pass
+* Your code can be merged w/o problems
+* It wont broke existing functionality
+* Its a quality code
+* We like it :)
+
+## [You may need a developer VM](https://github.com/gitlabhq/developer-vm)
+
+## Running tests
+
+To run the specs for GitLab, you need to run seeds for test db.
+
+ cd gitlabhq
+ rake db:seed_fu RAILS_ENV=test
+
+Then you can run the test suite with rake:
+
+ rake gitlab:test
+
View
25 Gemfile
@@ -1,5 +1,13 @@
source "http://rubygems.org"
+def darwin_only(require_as)
+ RUBY_PLATFORM.include?('darwin') && require_as
+end
+
+def linux_only(require_as)
+ RUBY_PLATFORM.include?('linux') && require_as
+end
+
gem "rails", "3.2.8"
# Supported DBs
@@ -8,6 +16,10 @@ gem "mysql2"
# Auth
gem "devise", "~> 2.1.0"
+gem 'omniauth'
+gem 'omniauth-google-oauth2'
+gem 'omniauth-twitter'
+gem 'omniauth-github'
# GITLAB patched libs
gem "grit", :git => "https://github.com/gitlabhq/grit.git", :ref => "7f35cb98ff17d534a07e3ce6ec3d580f67402837"
@@ -98,21 +110,28 @@ group :development do
end
group :development, :test do
+ gem 'spinach-rails'
gem "rspec-rails"
gem "capybara"
gem "capybara-webkit"
gem "headless"
- gem "autotest"
- gem "autotest-rails"
gem "pry"
gem "awesome_print"
gem "database_cleaner"
gem "launchy"
gem 'factory_girl_rails'
+
+ # Guard
+ gem 'guard-rspec'
+ gem 'guard-spinach'
+
+ # Notification
+ gem 'rb-fsevent', :require => darwin_only('rb-fsevent')
+ gem 'growl', :require => darwin_only('growl')
+ gem 'rb-inotify', :require => linux_only('rb-inotify')
end
group :test do
- gem 'cucumber-rails', :require => false
gem "simplecov", :require => false
gem "shoulda-matchers"
gem 'email_spec'
View
79 Gemfile.lock
@@ -68,7 +68,6 @@ GIT
GEM
remote: http://rubygems.org/
specs:
- ZenTest (4.8.1)
actionmailer (3.2.8)
actionpack (= 3.2.8)
mail (~> 2.4.4)
@@ -100,10 +99,6 @@ GEM
rails (~> 3.0)
addressable (2.2.8)
arel (3.0.2)
- autotest (4.4.6)
- ZenTest (>= 4.4.1)
- autotest-rails (4.1.2)
- ZenTest (~> 4.5)
awesome_print (1.0.2)
bcrypt-ruby (3.0.1)
blankslate (2.1.2.4)
@@ -137,16 +132,8 @@ GEM
execjs
coffee-script-source (1.3.3)
colored (1.2)
+ colorize (0.5.8)
crack (0.3.1)
- cucumber (1.2.1)
- builder (>= 2.1.2)
- diff-lcs (>= 1.1.3)
- gherkin (~> 2.11.0)
- json (>= 1.4.6)
- cucumber-rails (1.3.0)
- capybara (>= 1.1.2)
- cucumber (>= 1.1.8)
- nokogiri (>= 1.5.0)
daemons (1.1.8)
database_cleaner (0.8.0)
devise (2.1.2)
@@ -171,12 +158,13 @@ GEM
factory_girl_rails (4.0.0)
factory_girl (~> 4.0.0)
railties (>= 3.0.0)
+ faraday (0.8.4)
+ multipart-post (~> 1.1)
ffaker (1.14.0)
ffi (1.0.11)
foreman (0.47.0)
thor (>= 0.13.6)
- gherkin (2.11.0)
- json (>= 1.4.6)
+ gherkin-ruby (0.2.1)
git (1.2.5)
github-markup (0.7.4)
gitlab_meta (2.9)
@@ -186,6 +174,15 @@ GEM
multi_xml
rack
rack-mount
+ growl (1.0.3)
+ guard (1.3.2)
+ listen (>= 0.4.2)
+ thor (>= 0.14.6)
+ guard-rspec (1.2.1)
+ guard (>= 1.1)
+ guard-spinach (0.0.2)
+ guard (>= 1.1)
+ spinach
haml (3.1.6)
haml-rails (0.3.4)
actionpack (~> 3.0)
@@ -199,6 +196,7 @@ GEM
httparty (0.8.3)
multi_json (~> 1.0)
multi_xml
+ httpauth (0.1)
i18n (0.6.1)
journey (1.0.4)
jquery-rails (2.0.2)
@@ -208,6 +206,8 @@ GEM
jquery-rails
railties (>= 3.1.0)
json (1.7.5)
+ jwt (0.1.5)
+ multi_json (>= 1.0)
kaminari (0.14.0)
actionpack (>= 3.0.0)
activesupport (>= 3.0.0)
@@ -219,6 +219,7 @@ GEM
libv8 (3.3.10.4)
libwebsocket (0.1.3)
addressable
+ listen (0.5.0)
mail (2.4.4)
i18n (>= 0.4.0)
mime-types (~> 1.16)
@@ -229,12 +230,35 @@ GEM
sprockets (~> 2.0)
multi_json (1.3.6)
multi_xml (0.5.1)
+ multipart-post (1.1.5)
mysql2 (0.3.11)
net-ldap (0.2.2)
nokogiri (1.5.3)
+ oauth (0.4.7)
+ oauth2 (0.8.0)
+ faraday (~> 0.8)
+ httpauth (~> 0.1)
+ jwt (~> 0.1.4)
+ multi_json (~> 1.0)
+ rack (~> 1.2)
omniauth (1.1.0)
hashie (~> 1.2)
rack
+ omniauth-github (1.0.3)
+ omniauth (~> 1.0)
+ omniauth-oauth2 (~> 1.1)
+ omniauth-google-oauth2 (0.1.13)
+ omniauth (~> 1.0)
+ omniauth-oauth2
+ omniauth-oauth (1.0.1)
+ oauth
+ omniauth (~> 1.0)
+ omniauth-oauth2 (1.1.0)
+ oauth2 (~> 0.8.0)
+ omniauth (~> 1.0)
+ omniauth-twitter (0.0.13)
+ multi_json (~> 1.3)
+ omniauth-oauth (~> 1.0)
orm_adapter (0.3.0)
polyglot (0.3.3)
posix-spawn (0.3.6)
@@ -274,6 +298,9 @@ GEM
raindrops (0.9.0)
rake (0.9.2.2)
raphael-rails (1.5.2)
+ rb-fsevent (0.9.1)
+ rb-inotify (0.8.8)
+ ffi (>= 0.5.0)
rdoc (3.12)
json (~> 1.4)
redcarpet (2.1.1)
@@ -336,6 +363,13 @@ GEM
tilt (~> 1.3, >= 1.3.3)
six (0.2.0)
slop (2.4.4)
+ spinach (0.5.2)
+ colorize
+ gherkin-ruby (~> 0.2.0)
+ spinach-rails (0.1.8)
+ capybara (~> 1)
+ railties (>= 3)
+ spinach (>= 0.4)
sprockets (2.1.3)
hike (~> 1.2)
rack (~> 1.0)
@@ -378,8 +412,6 @@ PLATFORMS
DEPENDENCIES
acts-as-taggable-on (= 2.3.1)
annotate!
- autotest
- autotest-rails
awesome_print
bootstrap-sass (= 2.0.4)
capybara
@@ -389,7 +421,6 @@ DEPENDENCIES
chosen-rails
coffee-rails (= 3.2.2)
colored
- cucumber-rails
database_cleaner
devise (~> 2.1.0)
draper
@@ -404,6 +435,9 @@ DEPENDENCIES
grack!
grape (~> 0.2.1)
grit!
+ growl
+ guard-rspec
+ guard-spinach
haml-rails
headless
httparty
@@ -415,12 +449,18 @@ DEPENDENCIES
linguist (~> 1.0.0)!
modernizr (= 2.5.3)
mysql2
+ omniauth
+ omniauth-github
+ omniauth-google-oauth2
omniauth-ldap!
+ omniauth-twitter
pry
pygments.rb!
rack-mini-profiler
rails (= 3.2.8)
raphael-rails (= 1.5.2)
+ rb-fsevent
+ rb-inotify
redcarpet (~> 2.1.1)
resque (~> 1.20.0)
resque_mailer
@@ -432,6 +472,7 @@ DEPENDENCIES
shoulda-matchers
simplecov
six
+ spinach-rails
sqlite3
stamp
test_after_commit
View
26 Guardfile
@@ -0,0 +1,26 @@
+# A sample Guardfile
+# More info at https://github.com/guard/guard#readme
+
+guard 'rspec', :version => 2, :all_on_start => false, :all_after_pass => false do
+ watch(%r{^spec/.+_spec\.rb$})
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
+ watch('spec/spec_helper.rb') { "spec" }
+
+ # Rails example
+ watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
+ watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
+ watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
+ watch('config/routes.rb') { "spec/routing" }
+ watch('app/controllers/application_controller.rb') { "spec/controllers" }
+
+ # Capybara request specs
+ watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
+end
+
+guard 'spinach' do
+ watch(%r|^features/(.*)\.feature|)
+ watch(%r|^features/steps/(.*)([^/]+)\.rb|) do |m|
+ "features/#{m[1]}#{m[2]}.feature"
+ end
+end
View
4 app/assets/javascripts/admin.js.coffee
@@ -6,3 +6,7 @@ $ ->
elems.val('').attr 'disabled', true
else
elems.removeAttr 'disabled'
+
+ $('.log-tabs a').click (e) ->
+ e.preventDefault()
+ $(this).tab('show')
View
2  app/assets/javascripts/application.js
@@ -11,7 +11,7 @@
//= require jquery.endless-scroll
//= require jquery.highlight
//= require jquery.waitforimages
-//= require bootstrap-modal
+//= require bootstrap
//= require modernizr
//= require chosen-jquery
//= require raphael
View
3  app/assets/javascripts/main.js.coffee
@@ -24,6 +24,9 @@ $ ->
# Click a .one_click_select field, select the contents
$(".one_click_select").live 'click', -> $(this).select()
+ # Initialize chosen selects
+ $('select.chosen').chosen()
+
# Disable form buttons while a form is submitting
$('body').on 'ajax:complete, ajax:beforeSend, submit', 'form', (e) ->
buttons = $('[type="submit"]', this)
View
182 app/assets/javascripts/note.js
@@ -1,182 +0,0 @@
-var NoteList = {
-
- notes_path: null,
- target_params: null,
- target_id: 0,
- target_type: null,
- first_id: 0,
- last_id: 0,
- disable:false,
-
- init:
- function(tid, tt, path) {
- this.notes_path = path + ".js";
- this.target_id = tid;
- this.target_type = tt;
- this.target_params = "&target_type=" + this.target_type + "&target_id=" + this.target_id;
-
- // get notes
- this.getContent();
-
- // get new notes every n seconds
- this.initRefresh();
-
- $('.delete-note').live('ajax:success', function() {
- $(this).closest('li').fadeOut(); });
-
- $(".note-form-holder").live("ajax:before", function(){
- $(".submit_note").disable()
- })
-
- $(".note-form-holder").live("ajax:complete", function(){
- $(".submit_note").enable()
- })
-
- disableButtonIfEmptyField(".note-text", ".submit_note");
-
- $(".note-text").live("focus", function(){
- $(this).css("height", "80px");
- $('.note_advanced_opts').show();
- });
-
- $("#note_attachment").change(function(e){
- var val = $('.input-file').val();
- var filename = val.replace(/^.*[\\\/]/, '');
- $(".file_name").text(filename);
- });
-
- },
-
-
- /**
- * Load new notes to fresh list called 'new_notes_list':
- * - Replace 'new_notes_list' with new list every n seconds
- * - Append new notes to this list after submit
- */
-
- initRefresh:
- function() {
- // init timer
- var intNew = setInterval("NoteList.getNew()", 10000);
- },
-
- replace:
- function(html) {
- $("#new_notes_list").html(html);
- },
-
- prepend:
- function(id, html) {
- if(id != this.last_id) {
- $("#new_notes_list").prepend(html);
- }
- },
-
- getNew:
- function() {
- // refersh notes list
- $.ajax({
- type: "GET",
- url: this.notes_path,
- data: "last_id=" + this.last_id + this.target_params,
- dataType: "script"});
- },
-
- refresh:
- function() {
- // refersh notes list
- $.ajax({
- type: "GET",
- url: this.notes_path,
- data: "first_id=" + this.first_id + "&last_id=" + this.last_id + this.target_params,
- dataType: "script"});
- },
-
-
- /**
- * Init load of notes:
- * 1. Get content with ajax call
- * 2. Set content of notes list with loaded one
- */
-
-
- getContent:
- function() {
- $.ajax({
- type: "GET",
- url: this.notes_path,
- data: "?" + this.target_params,
- complete: function(){ $('.status').removeClass("loading")},
- beforeSend: function() { $('.status').addClass("loading") },
- dataType: "script"});
- },
-
- setContent:
- function(fid, lid, html) {
- this.last_id = lid;
- this.first_id = fid;
- $("#notes-list").html(html);
-
- // Init infinite scrolling
- this.initLoadMore();
- },
-
-
- /**
- * Paging for old notes when scroll to bottom:
- * 1. Init scroll events with 'initLoadMore'
- * 2. Load onlder notes with 'getOld' method
- * 3. append old notes to bottom of list with 'append'
- *
- */
- getOld:
- function() {
- $('.loading').show();
- $.ajax({
- type: "GET",
- url: this.notes_path,
- data: "first_id=" + this.first_id + this.target_params,
- complete: function(){ $('.status').removeClass("loading")},
- beforeSend: function() { $('.status').addClass("loading") },
- dataType: "script"});
- },
-
- append:
- function(id, html) {
- if(this.first_id == id) {
- this.disable = true;
- } else {
- this.first_id = id;
- $("#notes-list").append(html);
- }
- },
-
- initLoadMore:
- function() {
- $(document).endlessScroll({
- bottomPixels: 400,
- fireDelay: 1000,
- fireOnce:true,
- ceaseFire: function() {
- return NoteList.disable;
- },
- callback: function(i) {
- NoteList.getOld();
- }
- });
- }
-};
-
-var PerLineNotes = {
- init:
- function() {
- $(".line_note_link, .line_note_reply_link").live("click", function(e) {
- var form = $(".per_line_form");
- $(this).closest("tr").after(form);
- form.find("#note_line_code").val($(this).attr("line_code"));
- form.show();
- return false;
- });
- disableButtonIfEmptyField(".line-note-text", ".submit_inline_note");
- }
-}
View
293 app/assets/javascripts/notes.js
@@ -0,0 +1,293 @@
+var NoteList = {
+
+ notes_path: null,
+ target_params: null,
+ target_id: 0,
+ target_type: null,
+ top_id: 0,
+ bottom_id: 0,
+ loading_more_disabled: false,
+ reversed: false,
+
+ init:
+ function(tid, tt, path) {
+ this.notes_path = path + ".js";
+ this.target_id = tid;
+ this.target_type = tt;
+ this.reversed = $("#notes-list").hasClass("reversed");
+ this.target_params = "&target_type=" + this.target_type + "&target_id=" + this.target_id;
+
+ // get initial set of notes
+ this.getContent();
+
+ $("#notes-list, #new-notes-list").on("ajax:success", ".delete-note", function() {
+ $(this).closest('li').fadeOut(function() {
+ $(this).remove();
+ NoteList.updateVotes();
+ });
+ });
+
+ $(".note-form-holder").on("ajax:before", function(){
+ $(".submit_note").disable();
+ })
+
+ $(".note-form-holder").on("ajax:complete", function(){
+ $(".submit_note").enable();
+ })
+
+ disableButtonIfEmptyField(".note-text", ".submit_note");
+
+ $("#note_attachment").change(function(e){
+ var val = $('.input-file').val();
+ var filename = val.replace(/^.*[\\\/]/, '');
+ $(".file_name").text(filename);
+ });
+
+ if(this.reversed) {
+ var textarea = $(".note-text");
+ $('.note_advanced_opts').hide();
+ textarea.css("height", "40px");
+ textarea.on("focus", function(){
+ $(this).css("height", "80px");
+ $('.note_advanced_opts').show();
+ });
+ }
+ },
+
+
+ /**
+ * Handle loading the initial set of notes.
+ * And set up loading more notes when scrolling to the bottom of the page.
+ */
+
+
+ /**
+ * Gets an inital set of notes.
+ */
+ getContent:
+ function() {
+ $.ajax({
+ type: "GET",
+ url: this.notes_path,
+ data: "?" + this.target_params,
+ complete: function(){ $('.notes-status').removeClass("loading")},
+ beforeSend: function() { $('.notes-status').addClass("loading") },
+ dataType: "script"});
+ },
+
+ /**
+ * Called in response to getContent().
+ * Replaces the content of #notes-list with the given html.
+ */
+ setContent:
+ function(first_id, last_id, html) {
+ this.top_id = first_id;
+ this.bottom_id = last_id;
+ $("#notes-list").html(html);
+
+ // init infinite scrolling
+ this.initLoadMore();
+
+ // init getting new notes
+ if (this.reversed) {
+ this.initRefreshNew();
+ }
+ },
+
+
+ /**
+ * Handle loading more notes when scrolling to the bottom of the page.
+ * The id of the last note in the list is in this.bottom_id.
+ *
+ * Set up refreshing only new notes after all notes have been loaded.
+ */
+
+
+ /**
+ * Initializes loading more notes when scrolling to the bottom of the page.
+ */
+ initLoadMore:
+ function() {
+ $(document).endlessScroll({
+ bottomPixels: 400,
+ fireDelay: 1000,
+ fireOnce:true,
+ ceaseFire: function() {
+ return NoteList.loading_more_disabled;
+ },
+ callback: function(i) {
+ NoteList.getMore();
+ }
+ });
+ },
+
+ /**
+ * Gets an additional set of notes.
+ */
+ getMore:
+ function() {
+ // only load more notes if there are no "new" notes
+ $('.loading').show();
+ $.ajax({
+ type: "GET",
+ url: this.notes_path,
+ data: "loading_more=1&" + (this.reversed ? "before_id" : "after_id") + "=" + this.bottom_id + this.target_params,
+ complete: function(){ $('.notes-status').removeClass("loading")},
+ beforeSend: function() { $('.notes-status').addClass("loading") },
+ dataType: "script"});
+ },
+
+ /**
+ * Called in response to getMore().
+ * Append notes to #notes-list.
+ */
+ appendMoreNotes:
+ function(id, html) {
+ if(id != this.bottom_id) {
+ this.bottom_id = id;
+ $("#notes-list").append(html);
+ }
+ },
+
+ /**
+ * Called in response to getMore().
+ * Disables loading more notes when scrolling to the bottom of the page.
+ * Initalizes refreshing new notes.
+ */
+ finishedLoadingMore:
+ function() {
+ this.loading_more_disabled = true;
+
+ // from now on only get new notes
+ if (!this.reversed) {
+ this.initRefreshNew();
+ }
+ // make sure we are up to date
+ this.updateVotes();
+ },
+
+
+ /**
+ * Handle refreshing and adding of new notes.
+ *
+ * New notes are all notes that are created after the site has been loaded.
+ * The "old" notes are in #notes-list the "new" ones will be in #new-notes-list.
+ * The id of the last "old" note is in this.bottom_id.
+ */
+
+
+ /**
+ * Initializes getting new notes every n seconds.
+ */
+ initRefreshNew:
+ function() {
+ setInterval("NoteList.getNew()", 10000);
+ },
+
+ /**
+ * Gets the new set of notes.
+ */
+ getNew:
+ function() {
+ $.ajax({
+ type: "GET",
+ url: this.notes_path,
+ data: "loading_new=1&after_id=" + (this.reversed ? this.top_id : this.bottom_id) + this.target_params,
+ dataType: "script"});
+ },
+
+ /**
+ * Called in response to getNew().
+ * Replaces the content of #new-notes-list with the given html.
+ */
+ replaceNewNotes:
+ function(html) {
+ $("#new-notes-list").html(html);
+ this.updateVotes();
+ },
+
+ /**
+ * Adds a single note to #new-notes-list.
+ */
+ appendNewNote:
+ function(id, html) {
+ if (this.reversed) {
+ $("#new-notes-list").prepend(html);
+ } else {
+ $("#new-notes-list").append(html);
+ }
+ this.updateVotes();
+ },
+
+ /**
+ * Recalculates the votes and updates them (if they are displayed at all).
+ *
+ * Assumes all relevant notes are displayed (i.e. there are no more notes to
+ * load via getMore()).
+ * Might produce inaccurate results when not all notes have been loaded and a
+ * recalculation is triggered (e.g. when deleting a note).
+ */
+ updateVotes:
+ function() {
+ var votes = $("#votes .votes");
+ var notes = $("#notes-list, #new-notes-list").find(".note.vote");
+
+ // only update if there is a vote display
+ if (votes.size()) {
+ var upvotes = notes.filter(".upvote").size();
+ var downvotes = notes.filter(".downvote").size();
+ var votesCount = upvotes + downvotes;
+ var upvotesPercent = votesCount ? (100.0 / votesCount * upvotes) : 0;
+ var downvotesPercent = votesCount ? (100.0 - upvotesPercent) : 0;
+
+ // change vote bar lengths
+ votes.find(".bar-success").css("width", upvotesPercent+"%");
+ votes.find(".bar-danger").css("width", downvotesPercent+"%");
+ // replace vote numbers
+ votes.find(".upvotes").text(votes.find(".upvotes").text().replace(/\d+/, upvotes));
+ votes.find(".downvotes").text(votes.find(".downvotes").text().replace(/\d+/, downvotes));
+ }
+ }
+};
+
+var PerLineNotes = {
+ init:
+ function() {
+ /**
+ * Called when clicking on the "add note" or "reply" button for a diff line.
+ *
+ * Shows the note form below the line.
+ * Sets some hidden fields in the form.
+ */
+ $(".diff_file_content").on("click", ".line_note_link, .line_note_reply_link", function(e) {
+ var form = $(".per_line_form");
+ $(this).closest("tr").after(form);
+ form.find("#note_line_code").val($(this).data("lineCode"));
+ form.show();
+ return false;
+ });
+
+ disableButtonIfEmptyField(".line-note-text", ".submit_inline_note");
+
+ /**
+ * Called in response to successfully deleting a note on a diff line.
+ *
+ * Removes the actual note from view.
+ * Removes the reply button if the last note for that line has been removed.
+ */
+ $(".diff_file_content").on("ajax:success", ".delete-note", function() {
+ var trNote = $(this).closest("tr");
+ trNote.fadeOut(function() {
+ $(this).remove();
+ });
+
+ // check if this is the last note for this line
+ // elements must really be removed for this to work reliably
+ var trLine = trNote.prev();
+ var trRpl = trNote.next();
+ if (trLine.hasClass("line_holder") && trRpl.hasClass("reply")) {
+ trRpl.fadeOut(function() { $(this).remove(); });
+ }
+ });
+ }
+}
View
6 app/assets/javascripts/projects.js.coffee
@@ -10,11 +10,15 @@ window.Projects = ->
$('form #project_default_branch').chosen()
disableButtonIfEmptyField '#project_name', '.project-submit'
-# Git clone panel switcher
$ ->
+ # Git clone panel switcher
scope = $ '.project_clone_holder'
if scope.length > 0
$('a, button', scope).click ->
$('a, button', scope).removeClass 'active'
$(@).addClass 'active'
$('#project_clone', scope).val $(@).data 'clone'
+
+ # Ref switcher
+ $('.project-refs-select').on 'change', ->
+ $(@).parents('form').submit()
View
109 app/assets/stylesheets/common.scss
@@ -145,6 +145,19 @@ span.update-author {
.label {
background-color: #474D57;
+ &.label-tag {
+ background: none;
+ border: none;
+ padding:4px 6px;
+ color:#444;
+ text-shadow:0 0 1px #fff;
+
+ &.grouped {
+ float: left;
+ margin-right: 6px;
+ padding: 6px;
+ }
+ }
&.label-issue {
background-color: #eee;
border: 1px solid #ccc;
@@ -158,6 +171,18 @@ span.update-author {
padding: 6px;
}
}
+
+ &.label-success {
+ background-color: #8D8;
+ color: #333;
+ text-shadow: 0 1px 1px white;
+ }
+
+ &.label-error {
+ background-color: #D88;
+ color: #333;
+ text-shadow: 0 1px 1px white;
+ }
}
.event_label {
@@ -181,11 +206,12 @@ span.update-author {
}
&.joined {
- background-color: #1cb9ff;
+ background-color: #1ca9dd;
}
&.left {
- background-color: #ff5057;
+ background-color: #888;
+ float:none;
}
}
@@ -414,13 +440,48 @@ p.time {
}
}
-.upvotes {
- font-size: 14px;
- font-weight: bold;
- color: #468847;
- text-align: right;
- padding: 4px;
- margin: 2px;
+.votes {
+ font-size: 13px;
+ line-height: 15px;
+ .progress {
+ height: 4px;
+ margin: 0;
+ .bar {
+ float: left;
+ height: 100%;
+ }
+ .bar-success {
+ background-color: #468847;
+ @include bg-gradient(#62C462, #51A351);
+ }
+ .bar-danger {
+ background-color: #B94A48;
+ @include bg-gradient(#EE5F5B, #BD362F);
+ }
+ }
+ .upvotes {
+ display: inline-block;
+ color: #468847;
+ }
+ .downvotes {
+ display: inline-block;
+ color: #B94A48;
+ }
+}
+.votes-block {
+ margin: 14px 6px 6px 0;
+ .downvotes {
+ float: right;
+ }
+}
+.votes-inline {
+ display: inline-block;
+ margin: 0 8px;
+ .progress {
+ display: inline-block;
+ padding: 0 0 2px;
+ width: 45px;
+ }
}
/* Fix for readme code (stopped it from being yellow) */
@@ -624,7 +685,7 @@ li.note {
margin-right:40px;
.prev {
- @extend .borders;
+ @extend .thumbnail;
height:120px;
width:175px;
margin-bottom:10px;
@@ -653,3 +714,31 @@ li.note {
text-align:center;
margin-bottom:10px;
}
+
+.oauth_select_holder {
+ padding:20px;
+ img {
+ padding:5px;
+ margin-right:10px;
+ }
+ .active {
+ img {
+ border:1px solid #ccc;
+ background:$hover;
+ @include border-radius(5px);
+ }
+ }
+}
+
+.btn-build-token {
+ float: left;
+ padding: 6px 20px;
+ margin-right: 12px;
+}
+
+.gitlab-promo {
+ a {
+ color:#aaa;
+ margin-right: 30px;
+ }
+}
View
8 app/assets/stylesheets/gitlab_bootstrap/blocks.scss
@@ -65,6 +65,10 @@
border-color: #CCC;
@include solid_shade;
+ &.white {
+ background:#fff;
+ }
+
ul {
margin:0;
}
@@ -142,4 +146,8 @@
border:none;
}
}
+
+ .ui-box-body {
+ padding:10px;
+ }
}
View
34 app/assets/stylesheets/gitlab_bootstrap/common.scss
@@ -33,7 +33,29 @@
.nav-pills a:hover { background-color:#888; }
.nav-pills .active a { background-color: $style_color; }
.nav-tabs > li > a, .nav-pills > li > a { color:$style_color; }
-.nav-tabs > .active > a { font-weight:bold; }
+.nav.nav-tabs {
+ li {
+ > a {
+ padding:8px 20px;
+ margin-right: 7px;
+ border-color: #EEE;
+ color:#888;
+ border-bottom: 1px solid #ddd;
+ .badge {
+ background-color: #eee;
+ color:#888;
+ text-shadow:0 1px 1px #fff;
+ }
+ }
+ &.active {
+ > a {
+ border-color: #CCC;
+ border-bottom: 1px solid #fff;
+ color:#333;
+ }
+ }
+ }
+}
/** ALERT MESSAGES **/
.alert-message { @extend .alert; }
@@ -50,3 +72,13 @@ img.lil_av { padding-left: 4px; padding-right:3px; }
/** HELPERS **/
.nothing_here_message { text-align:center; padding:20px; color:#777; }
p.slead { color:#456; font-size:16px; margin-bottom: 12px; font-weight: 200; line-height: 24px; }
+
+/** FORMS **/
+input[type='search'].search-text-input {
+ background-image: url("icon-search.png");
+ background-repeat: no-repeat;
+ background-position: 10px;
+ padding-left:25px;
+ @include border-radius(4px);
+ border:1px solid #ccc;
+}
View
6 app/assets/stylesheets/main.scss
@@ -135,7 +135,6 @@ $hover: #fdf5d9;
*/
@import "common.scss";
-
/**
* Styles related to specific part of app
*/
@@ -162,6 +161,11 @@ $hover: #fdf5d9;
@import "sections/notes.scss";
/**
+ * This file represent profile styles
+ */
+@import "sections/profile.scss";
+
+/**
* Devise styles
*/
@import "sections/login.scss";
View
28 app/assets/stylesheets/ref_select.scss
@@ -12,35 +12,45 @@
width:120px;
}
-.project-refs-form .chzn-container {
+.project-refs-form .chzn-container {
position: relative;
top: 0;
left: 0;
margin-right: 10px;
- .chzn-drop {
+ .chzn-drop {
margin:7px 0;
- border: 1px solid #CCC;
- min-width: 300px;
+ min-width: 400px;
+ border: 2px solid $blue_link;
+ @include border-radius(4px);
- .chzn-results {
+ .chzn-results {
max-height:300px;
+
+ .group-result {
+ color: $blue_link;
+ }
+ .active-result {
+ &.highlighted {
+ background: $blue_link;
+ }
+ }
}
.chzn-search input {
- min-width:200px;
+ min-width:365px;
}
}
- .chzn-single {
+ .chzn-single {
@include bg-gray-gradient;
- div {
+ div {
background:transparent;
border-left:none;
}
- span {
+ span {
font-weight: normal;
}
}
View
55 app/assets/stylesheets/sections/issues.scss
@@ -1,55 +1,55 @@
-.issue_form_box {
+.issue_form_box {
@extend .main_box;
- .issue_title {
+ .issue_title {
@extend .top_box_content;
- .clearfix {
- margin-bottom:0px;
- input {
+ .clearfix {
+ margin-bottom:0px;
+ input {
@extend .span8;
}
}
}
- .issue_middle_block {
+ .issue_middle_block {
@extend .middle_box_content;
height:30px;
- .issue_assignee {
+ .issue_assignee {
@extend .span6;
float:left;
}
- .issue_milestone {
+ .issue_milestone {
@extend .span4;
float:left;
}
}
- .issue_description {
+ .issue_description {
@extend .bottom_box_content;
}
}
-.issues_table {
- .issue {
+.issues_table {
+ .issue {
padding:7px 10px;
- .issue_check {
+ .issue_check {
float:left;
padding: 8px 0;
padding-right: 8px;
min-width: 15px;
}
- p {
+ p {
padding-top:0;
padding-bottom:2px;
}
- img.avatar {
+ img.avatar {
width:32px;
margin-top:4px;
}
}
}
-input.check_all_issues {
+input.check_all_issues {
float:left;
padding: 0;
margin:0;
@@ -59,8 +59,8 @@ input.check_all_issues {
height: 22px;
}
-.issues_content {
- .title {
+.issues_content {
+ .title {
height: 40px;
}
}
@@ -70,30 +70,30 @@ input.check_all_issues {
@media (min-width: 1200px) { .issues_filters select { width:220px; } }
-#issues-table-holder {
- .issues_filters {
- form {
+#issues-table-holder {
+ .issues_filters {
+ form {
padding:0;
margin:0;
margin-top:7px
}
- }
+ }
- .issues_bulk_update {
+ .issues_bulk_update {
margin: 0;
- form {
+ form {
padding:0;
margin:0;
margin-top:7px
}
- .update_selected_issues {
+ .update_selected_issues {
position:relative;
top:-2px;
margin-left:4px;
float:left;
}
-
- .update_issues_text {
+
+ .update_issues_text {
padding:3px;
line-height: 18px;
float:left;
@@ -101,10 +101,11 @@ input.check_all_issues {
}
}
-#update_status {
+#update_status {
width:100px;
}
+
/**
* Milestones list
*
View
55 app/assets/stylesheets/sections/merge_requests.scss
@@ -1,13 +1,13 @@
-/**
+/**
* MR form
*
*/
-.mr_branch_box {
+.mr_branch_box {
@extend .ui-box;
margin-bottom:20px;
- .body {
+ .body {
background:#f1f1f1;
}
@@ -17,19 +17,19 @@
* MR -> show: Automerge widget
*
*/
-.automerge_widget {
- &.can_be_merged {
+.automerge_widget {
+ &.can_be_merged {
background: #DFF0D8;
}
- form {
+ form {
margin-bottom:0;
- .clearfix {
+ .clearfix {
margin-bottom:0;
}
}
- .accept_group {
+ .accept_group {
float:left;
border: 1px solid #ADA;
padding: 2px;
@@ -37,29 +37,29 @@
border-radius: 5px;
background: #CEB;
- .accept_merge_request {
+ .accept_merge_request {
font-size:13px;
float:left;
}
- .remove_branch_holder {
+ .remove_branch_holder {
margin-left:20px;
margin-right:10px;
float:left;
}
- label {
+ label {
color:#444;
}
}
- .how_to_merge_link {
+ .how_to_merge_link {
@extend .primary;
}
}
-.mr_nav_tabs {
- li {
- a {
+.mr_nav_tabs {
+ li {
+ a {
font-weight:bold;
padding:8px 20px;
text-align:center;
@@ -67,19 +67,19 @@
}
}
-li.merge_request {
+li.merge_request {
padding:7px 10px;
- img.avatar {
+ img.avatar {
width: 32px;
margin-top: 4px;
}
- p {
+ p {
padding: 0px;
padding-bottom: 2px;
}
}
-.merge_in_progress {
+.merge_in_progress {
@extend .padded;
@extend .append-bottom-10;
}
@@ -88,22 +88,21 @@ li.merge_request {
@include round-borders-all(4px);
padding:2px 4px;
border:none;
- font-size:13px;
+ font-size:14px;
background: #474D57;
color:#fff;
- font-weight:bold;
- font-family: monospace;
+ font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
}
-.mr_source_commit,
-.mr_target_commit {
- .commit {
+.mr_source_commit,
+.mr_target_commit {
+ .commit {
margin:0;
padding:0;
padding: 5px;
margin-bottom: 5px;
.avatar { position:relative }
- .row_title {
+ .row_title {
color:#444;
}
.commit-author-name,
@@ -113,12 +112,12 @@ li.merge_request {
display:none;
}
list-style:none;
- &:hover {
+ &:hover {
background:none;
}
}
}
-.mr_direction_tip {
+.mr_direction_tip {
margin-top:40px
}
View
1  app/assets/stylesheets/sections/nav.scss
@@ -55,7 +55,6 @@ ul.main_menu {
&.current {
background-color:#D5D5D5;
- border-bottom: 1px solid #AAA;
border-right: 1px solid #BBB;
border-left: 1px solid #BBB;
border-radius: 0 0 1px 1px;
View
29 app/assets/stylesheets/sections/notes.scss
@@ -3,17 +3,13 @@
*
*/
#notes-list,
-#new_notes_list {
+#new-notes-list {
display:block;
list-style:none;
margin:0px;
padding:0px;
}
-#new_notes_list li:last-child{
- border-bottom:1px solid #aaa;
-}
-
.issue_notes,
.wiki_notes {
.note_content {
@@ -30,9 +26,6 @@
}
#new_note {
- .note-text {
- height:40px;
- }
.attach_holder {
display:none;
}
@@ -48,7 +41,6 @@
.note {
padding: 8px 0;
- border-bottom: 1px solid #eee;
overflow: hidden;
display: block;
img {float: left; margin-right: 10px;}
@@ -70,6 +62,23 @@
.delete-note { display:block; }
}
}
+#notes-list:not(.reversed) .note,
+#new-notes-list:not(.reversed) .note {
+ border-bottom: 1px solid #eee;
+}
+#notes-list.reversed .note,
+#new-notes-list.reversed .note {
+ border-top: 1px solid #eee;
+}
+
+/* mark vote notes */
+.voting_notes .note {
+ padding: 8px 0;
+}
+
+.notes-status {
+ margin: 18px;
+}
p.notify_controls input{
@@ -213,7 +222,7 @@ td .line_note_link {
}
}
-.note-text {
+.note-text {
border: 1px solid #aaa;
box-shadow:none;
}
View
8 app/assets/stylesheets/sections/profile.scss
@@ -0,0 +1,8 @@
+.profile_history {
+ .event_feed {
+ min-height:20px;
+ .avatar {
+ width:20px;
+ }
+ }
+}
View
33 app/contexts/notes/load_context.rb
@@ -3,30 +3,31 @@ class LoadContext < BaseContext
def execute
target_type = params[:target_type]
target_id = params[:target_id]
- first_id = params[:first_id]
- last_id = params[:last_id]
+ after_id = params[:after_id]
+ before_id = params[:before_id]
@notes = case target_type
- when "commit"
- then project.commit_notes(project.commit(target_id)).fresh.limit(20)
- when "snippet"
- then project.snippets.find(target_id).notes
- when "wall"
- then project.common_notes.order("created_at DESC").fresh.limit(50)
+ when "commit"
+ project.commit_notes(project.commit(target_id)).fresh.limit(20)
when "issue"
- then project.issues.find(target_id).notes.inc_author.order("created_at DESC").limit(20)
+ project.issues.find(target_id).notes.inc_author.fresh.limit(20)
when "merge_request"
- then project.merge_requests.find(target_id).notes.inc_author.order("created_at DESC").limit(20)
+ project.merge_requests.find(target_id).notes.inc_author.fresh.limit(20)
+ when "snippet"
+ project.snippets.find(target_id).notes.fresh
+ when "wall"
+ # this is the only case, where the order is DESC
+ project.common_notes.order("created_at DESC, id DESC").limit(50)
when "wiki"
- then project.wikis.reverse.map {|w| w.notes.fresh }.flatten[0..20]
+ project.wiki_notes.limit(20)
end
- @notes = if last_id
- @notes.where("id > ?", last_id)
- elsif first_id
- @notes.where("id < ?", first_id)
- else
+ @notes = if after_id
+ @notes.where("id > ?", after_id)
+ elsif before_id
+ @notes.where("id < ?", before_id)
+ else
@notes
end
end
View
6 app/controllers/admin/dashboard_controller.rb
@@ -1,8 +1,4 @@
-class Admin::DashboardController < ApplicationController
- layout "admin"
- before_filter :authenticate_user!
- before_filter :authenticate_admin!
-
+class Admin::DashboardController < AdminController
def index
@workers = Resque.workers
@pending_jobs = Resque.size(:post_receive)
View
8 app/controllers/admin/hooks_controller.rb
@@ -1,8 +1,4 @@
-class Admin::HooksController < ApplicationController
- layout "admin"
- before_filter :authenticate_user!
- before_filter :authenticate_admin!
-
+class Admin::HooksController < AdminController
def index
@hooks = SystemHook.all
@hook = SystemHook.new
@@ -15,7 +11,7 @@ def create
redirect_to admin_hooks_path, notice: 'Hook was successfully created.'
else
@hooks = SystemHook.all
- render :index
+ render :index
end
end
View
6 app/controllers/admin/logs_controller.rb
@@ -1,6 +1,2 @@
-class Admin::LogsController < ApplicationController
- layout "admin"
- before_filter :authenticate_user!
- before_filter :authenticate_admin!
+class Admin::LogsController < AdminController
end
-
View
9 app/controllers/admin/projects_controller.rb
@@ -1,7 +1,4 @@
-class Admin::ProjectsController < ApplicationController
- layout "admin"
- before_filter :authenticate_user!
- before_filter :authenticate_admin!
+class Admin::ProjectsController < AdminController
before_filter :admin_project, only: [:edit, :show, :update, :destroy, :team_update]
def index
@@ -43,7 +40,7 @@ def create
def update
owner_id = params[:project].delete(:owner_id)
- if owner_id
+ if owner_id
@admin_project.owner = User.find(owner_id)
end
@@ -60,7 +57,7 @@ def destroy
redirect_to admin_projects_url, notice: 'Project was successfully deleted.'
end
- private
+ private
def admin_project
@admin_project = Project.find_by_code(params[:id])
View
5 app/controllers/admin/resque_controller.rb
@@ -1,5 +1,4 @@
-class Admin::ResqueController < ApplicationController
- layout 'admin'
+class Admin::ResqueController < AdminController
def show
end
-end
+end
View
6 app/controllers/admin/team_members_controller.rb
@@ -1,8 +1,4 @@
-class Admin::TeamMembersController < ApplicationController
- layout "admin"
- before_filter :authenticate_user!
- before_filter :authenticate_admin!
-
+class Admin::TeamMembersController < AdminController
def edit
@admin_team_member = UsersProject.find(params[:id])
end
View
16 app/controllers/admin/users_controller.rb
@@ -1,8 +1,4 @@
-class Admin::UsersController < ApplicationController
- layout "admin"
- before_filter :authenticate_user!
- before_filter :authenticate_admin!
-
+class Admin::UsersController < AdminController
def index
@admin_users = User.scoped
@admin_users = @admin_users.filter(params[:filter])
@@ -24,7 +20,7 @@ def team_update
@admin_user = User.find(params[:id])
UsersProject.user_bulk_import(
- @admin_user,
+ @admin_user,
params[:project_ids],
params[:project_access]
)
@@ -41,22 +37,22 @@ def edit
@admin_user = User.find(params[:id])
end
- def block
+ def block
@admin_user = User.find(params[:id])
if @admin_user.block
redirect_to :back, alert: "Successfully blocked"
- else
+ else
redirect_to :back, alert: "Error occured. User was not blocked"
end
end
- def unblock
+ def unblock
@admin_user = User.find(params[:id])
if @admin_user.update_attribute(:blocked, false)
redirect_to :back, alert: "Successfully unblocked"
- else
+ else
redirect_to :back, alert: "Error occured. User was not unblocked"
end
end
View
11 app/controllers/admin_controller.rb
@@ -0,0 +1,11 @@
+# Provides a base class for Admin controllers to subclass
+#
+# Automatically sets the layout and ensures an administrator is logged in
+class AdminController < ApplicationController